Commit 1b1ed945 authored by John Layt's avatar John Layt

Enable Okular printing features:

* Add FilePrinter class to enable printing via postscript files
* DJVU, PDF, and PS backends print FilePrinter
* All backends enable printing of bookmarked pages
* Print and Print Preview actions enabled/disabled depending on backends
  printing ability

Note that FilePrinter only works on *NIX platforms with Cups, lpr, or lp.



svn path=/trunk/KDE/kdegraphics/okular/; revision=741990
parent 2153ec5e
...@@ -43,6 +43,7 @@ set(okularcore_SRCS ...@@ -43,6 +43,7 @@ set(okularcore_SRCS
core/textdocumentgenerator.cpp core/textdocumentgenerator.cpp
core/textpage.cpp core/textpage.cpp
core/utils.cpp core/utils.cpp
core/fileprinter.cpp
) )
install( FILES install( FILES
...@@ -64,6 +65,7 @@ install( FILES ...@@ -64,6 +65,7 @@ install( FILES
core/textdocumentgenerator.h core/textdocumentgenerator.h
core/textpage.h core/textpage.h
core/utils.h core/utils.h
core/fileprinter.h
DESTINATION ${INCLUDE_INSTALL_DIR}/okular/core ) DESTINATION ${INCLUDE_INSTALL_DIR}/okular/core )
install( FILES install( FILES
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <QtGui/QApplication> #include <QtGui/QApplication>
#include <QtGui/QLabel> #include <QtGui/QLabel>
#include <QtGui/QPrinter> #include <QtGui/QPrinter>
#include <QtGui/QPrintDialog>
#include <kaboutdata.h> #include <kaboutdata.h>
#include <kauthorized.h> #include <kauthorized.h>
...@@ -2186,6 +2187,68 @@ BookmarkManager * Document::bookmarkManager() const ...@@ -2186,6 +2187,68 @@ BookmarkManager * Document::bookmarkManager() const
return d->m_bookmarkManager; return d->m_bookmarkManager;
} }
QList<int> Document::bookmarkedPageList() const
{
QList<int> list;
uint docPages = pages();
//pages are 0-indexed internally, but 1-indexed externally
for ( uint i = 0; i < docPages; i++ )
{
if ( bookmarkManager()->isBookmarked( i ) )
{
list << i + 1;
}
}
return list;
}
QString Document::bookmarkedPageRange() const
{
// Code formerly in Part::slotPrint()
// range detecting
QString range;
uint docPages = pages();
int startId = -1;
int endId = -1;
for ( uint i = 0; i < docPages; ++i )
{
if ( bookmarkManager()->isBookmarked( i ) )
{
if ( startId < 0 )
startId = i;
if ( endId < 0 )
endId = startId;
else
++endId;
}
else if ( startId >= 0 && endId >= 0 )
{
if ( !range.isEmpty() )
range += ',';
if ( endId - startId > 0 )
range += QString( "%1-%2" ).arg( startId + 1 ).arg( endId + 1 );
else
range += QString::number( startId + 1 );
startId = -1;
endId = -1;
}
}
if ( startId >= 0 && endId >= 0 )
{
if ( !range.isEmpty() )
range += ',';
if ( endId - startId > 0 )
range += QString( "%1-%2" ).arg( startId + 1 ).arg( endId + 1 );
else
range += QString::number( startId + 1 );
}
return range;
}
void Document::processAction( const Action * action ) void Document::processAction( const Action * action )
{ {
if ( !action ) if ( !action )
...@@ -2396,6 +2459,33 @@ void Document::processSourceReference( const SourceReference * ref ) ...@@ -2396,6 +2459,33 @@ void Document::processSourceReference( const SourceReference * ref )
QProcess::startDetached( p ); QProcess::startDetached( p );
} }
Document::PrintingType Document::printingSupport() const
{
if ( d->m_generator )
{
if ( d->m_generator->hasFeature( Generator::PrintNative ) )
{
return NativePrinting;
}
#ifndef Q_OS_WIN
if ( d->m_generator->hasFeature( Generator::PrintPostscript ) )
{
return PostscriptPrinting;
}
#endif
}
return NoPrinting;
}
bool Document::supportsPrintToFile() const
{
return d->m_generator ? d->m_generator->hasFeature( Generator::PrintToFile ) : false;
}
bool Document::print( QPrinter &printer ) bool Document::print( QPrinter &printer )
{ {
return d->m_generator ? d->m_generator->print( printer ) : false; return d->m_generator ? d->m_generator->print( printer ) : false;
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <kmimetype.h> #include <kmimetype.h>
class QPrinter; class QPrinter;
class QPrintDialog;
class KComponentData; class KComponentData;
class KBookmark; class KBookmark;
class KConfigDialog; class KConfigDialog;
...@@ -415,6 +416,16 @@ class OKULAR_EXPORT Document : public QObject ...@@ -415,6 +416,16 @@ class OKULAR_EXPORT Document : public QObject
*/ */
void processAction( const Action *action ); void processAction( const Action *action );
/**
* Returns a list of the bookmarked.pages
*/
QList<int> bookmarkedPageList() const;
/**
* Returns the range of the bookmarked.pages
*/
QString bookmarkedPageRange() const;
/** /**
* Processes/Executes the given source @p reference. * Processes/Executes the given source @p reference.
*/ */
...@@ -425,6 +436,27 @@ class OKULAR_EXPORT Document : public QObject ...@@ -425,6 +436,27 @@ class OKULAR_EXPORT Document : public QObject
*/ */
bool canConfigurePrinter() const; bool canConfigurePrinter() const;
/**
* What type of printing a document supports
*/
enum PrintingType
{
NoPrinting, ///< Printing Not Supported
NativePrinting, ///< Native Cross-Platform Printing
PostscriptPrinting ///< Postscript file printing
};
/**
* Returns what sort of printing the document supports:
* Native, Postscript, None
*/
PrintingType printingSupport() const;
/**
* Returns whether the document supports printing to both PDF and PS files.
*/
bool supportsPrintToFile() const;
/** /**
* Prints the document to the given @p printer. * Prints the document to the given @p printer.
*/ */
......
This diff is collapsed.
/***************************************************************************
* Copyright (C) 2007 by John Layt <john@layt.net> *
* *
* FilePrinterPreview based on KPrintPreview (originally LGPL) *
* Copyright (c) 2007 Alex Merry <huntedhacker@tiscali.co.uk> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
***************************************************************************/
// This Class is a temporary addition to Okular for the duration of KDE 4.0.
// In KDE 4.1 this class will either be moved to kdelibs if still required,
// or replaced with a Qt 4.4 based solution.
#ifndef FILEPRINTER_H
#define FILEPRINTER_H
#include <QList>
#include <QString>
#include <kdialog.h>
#include <okular/core/okular_export.h>
class QPrinter;
class QSize;
namespace Okular {
class OKULAR_EXPORT FilePrinter
{
public:
/** Whether file(s) get deleted by the application or by the print system.
*
* You may need to chose system deletion if your temp file clean-up
* deletes the file before the print system is finished with it.
*/
enum FileDeletePolicy { ApplicationDeletesFiles, SystemDeletesFiles };
/** Whether pages to be printed are selected by the application or the print system.
*
* If application side, then the generated file will only contain those pages
* selected by the user, so FilePrinter will print all the pages in the file.
*
* If system side, then the file will contain all the pages in the document, and
* the print system will print the users selected print range from out of the file.
*
* Note system side only works in CUPS, not LPR.
*/
enum PageSelectPolicy { ApplicationSelectsPages, SystemSelectsPages };
/** Print a file using the settings in QPrinter
*
* Only supports CUPS and LPR on *NIX. Page Range only supported in CUPS.
* Most settings unsupported by LPR, some settings unsupported by CUPS.
*
* @param printer the print settings to use
* @param file the file to print
* @param fileDeletePolicy if the application or system deletes the file
* @param pageSelectPolicy if the application or system selects the pages to print
* @param pageRange page range to print if SystemSlectsPages and user chooses Selection in Print Dialog
*
* @returns Returns exit code:
* -9 if lpr not found
* -8 if empty file name
* -7 if unable to find file
* -6 if invalid printer state
* -2 if the KProcess could not be started
* -1 if the KProcess crashed
* otherwise the KProcess exit code
*/
static int printFile( QPrinter &printer, const QString file,
FileDeletePolicy fileDeletePolicy = FilePrinter::ApplicationDeletesFiles,
PageSelectPolicy pageSelectPolicy = FilePrinter::ApplicationSelectsPages,
const QString &pageRange = QString() );
/** Print a list of files using the settings in QPrinter
*
* Only supports CUPS and LPR on *NIX.
* Most settings unsupported by LPR, some settings unsupported by CUPS.
*
* @param printer the print settings to use
* @param fileList the files to print
* @param fileDeletePolicy if the application or system deletes the file
*
* @returns Returns exit code:
* -9 if lpr not found
* -8 if empty file list
* -7 if unable to find a file
* -6 if invalid printer state
* -2 if the KProcess could not be started
* -1 if the KProcess crashed
* otherwise the KProcess exit code
*/
static int printFiles( QPrinter &printer, const QStringList &fileList,
FileDeletePolicy fileDeletePolicy = FilePrinter::ApplicationDeletesFiles );
/** Return the list of pages selected by the user in the Print Dialog
*
* @param printer the print settings to use
* @param lastPage the last page number, needed if AllPages option is selected
* @param selectedPageList list of pages to use if Selection option is selected
* @returns Returns list of pages to print
*/
static QList<int> pageList( QPrinter &printer, int lastPage, const QList<int> &selectedPageList );
/** Return the range of pages selected by the user in the Print Dialog
*
* @param printer the print settings to use
* @param lastPage the last page number, needed if AllPages option is selected
* @param selectedPageList list of pages to use if Selection option is selected
* @returns Returns range of pages to print
*/
static QString pageRange( QPrinter &printer, int lastPage, const QList<int> &selectedPageList );
/** convert a Page List into a Page Range
*
* @param pageList list of pages to convert
* @returns Returns equivalent page range
*/
static QString pageListToPageRange( const QList<int> &pageList );
/** Return if CUPS Print System is available on this system
*
* @returns Returns true if CUPS available
*/
static bool cupsAvailable();
/** Returns the postscript standard page size
*
* @returns Returns paper size in ps points
*/
static QSize psPaperSize( QPrinter &printer );
protected:
bool detectCupsService();
bool detectCupsConfig();
int doPrintFiles( QPrinter &printer, const QStringList fileList,
FileDeletePolicy fileDeletePolicy, PageSelectPolicy pageSelectPolicy,
const QString &pageRange );
QStringList printArguments( QPrinter &printer,
FileDeletePolicy fileDeletePolicy, PageSelectPolicy pageSelectPolicy,
bool useCupsOptions, const QString &pageRange, const QString &version );
QStringList destination( QPrinter &printer, const QString &version );
QStringList copies( QPrinter &printer, const QString &version );
QStringList jobname( QPrinter &printer, const QString &version );
QStringList deleteFile( QPrinter &printer, FileDeletePolicy fileDeletePolicy,
const QString &version );
QStringList pages( QPrinter &printer, PageSelectPolicy pageSelectPolicy,
const QString &pageRange, bool useCupsOptions, const QString &version );
QStringList cupsOptions( QPrinter &printer );
QStringList optionMedia( QPrinter &printer );
QString mediaPageSize( QPrinter &printer );
QString mediaPaperSource( QPrinter &printer );
QStringList optionOrientation( QPrinter &printer );
QStringList optionDoubleSidedPrinting( QPrinter &printer );
QStringList optionPageOrder( QPrinter &printer );
QStringList optionCollateCopies( QPrinter &printer );
};
// This code copied from KPrintPreview by Alex Merry, adapted to do PS files instead of PDF
class FilePrinterPreviewPrivate;
class OKULAR_EXPORT FilePrinterPreview : public KDialog
{
Q_OBJECT
public:
/**
* Create a Print Preview dialog for a given file.
*
* @param printer file to print preview
* @param parent pointer to the parent widget for the dialog
*/
explicit FilePrinterPreview( const QString &filename, QWidget *parent = 0 );
virtual ~FilePrinterPreview();
protected:
void showEvent( QShowEvent *event );
private:
FilePrinterPreviewPrivate * const d;
};
}
#endif // FILEPRINTER_H
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
class QMutex; class QMutex;
class QPrinter; class QPrinter;
class QPrintDialog;
class KAboutData; class KAboutData;
class KComponentData; class KComponentData;
class KIcon; class KIcon;
...@@ -196,7 +197,10 @@ class OKULAR_EXPORT Generator : public QObject ...@@ -196,7 +197,10 @@ class OKULAR_EXPORT Generator : public QObject
TextExtraction, ///< Whether the Generator can extract text from the document in the form of TextPage's TextExtraction, ///< Whether the Generator can extract text from the document in the form of TextPage's
ReadRawData, ///< Whether the Generator can read a document directly from its raw data. ReadRawData, ///< Whether the Generator can read a document directly from its raw data.
FontInfo, ///< Whether the Generator can provide information about the fonts used in the document FontInfo, ///< Whether the Generator can provide information about the fonts used in the document
PageSizes ///< Whether the Generator can change the size of the document pages. PageSizes, ///< Whether the Generator can change the size of the document pages.
PrintNative, ///< Whether the Generator supports native cross-platform printing (QPainter-based).
PrintPostscript, ///< Whether the Generator supports postscript-based file printing.
PrintToFile ///< Whether the Generator supports export to PDF & PS through the Print Dialog
}; };
/** /**
......
...@@ -12,7 +12,9 @@ ...@@ -12,7 +12,9 @@
#include <QtGui/QPainter> #include <QtGui/QPainter>
#include <QtGui/QPrinter> #include <QtGui/QPrinter>
#include <okular/core/document.h>
#include <okular/core/page.h> #include <okular/core/page.h>
#include <okular/core/fileprinter.h>
OKULAR_EXPORT_PLUGIN(ComicBookGenerator) OKULAR_EXPORT_PLUGIN(ComicBookGenerator)
...@@ -20,6 +22,8 @@ ComicBookGenerator::ComicBookGenerator() ...@@ -20,6 +22,8 @@ ComicBookGenerator::ComicBookGenerator()
: Generator() : Generator()
{ {
setFeature( Threaded ); setFeature( Threaded );
setFeature( PrintNative );
setFeature( PrintToFile );
} }
ComicBookGenerator::~ComicBookGenerator() ComicBookGenerator::~ComicBookGenerator()
...@@ -70,19 +74,17 @@ bool ComicBookGenerator::print( QPrinter& printer ) ...@@ -70,19 +74,17 @@ bool ComicBookGenerator::print( QPrinter& printer )
{ {
QPainter p( &printer ); QPainter p( &printer );
for ( int i = 0; i < mDocument.pages(); ++i ) { QList<int> pageList = Okular::FilePrinter::pageList( printer, document()->pages(),
QImage image = mDocument.pageImage( i ); document()->bookmarkedPageList() );
uint left, top, right, bottom;
left = printer.paperRect().left() - printer.pageRect().left();
top = printer.paperRect().top() - printer.pageRect().top();
right = printer.paperRect().right() - printer.pageRect().right();
bottom = printer.paperRect().bottom() - printer.pageRect().bottom();
int pageWidth = printer.width() - right; for ( int i = 0; i < pageList.count(); ++i ) {
int pageHeight = printer.height() - bottom;
if ( (image.width() > pageWidth) || (image.height() > pageHeight) ) QImage image = mDocument.pageImage( pageList[i] - 1 );
image = image.scaled( pageWidth, pageHeight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
if ( ( image.width() > printer.width() ) || ( image.height() > printer.height() ) )
image = image.scaled( printer.width(), printer.height(),
Qt::KeepAspectRatio, Qt::SmoothTransformation );
if ( i != 0 ) if ( i != 0 )
printer.newPage(); printer.newPage();
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <okular/core/page.h> #include <okular/core/page.h>
#include <okular/core/textpage.h> #include <okular/core/textpage.h>
#include <okular/core/utils.h> #include <okular/core/utils.h>
#include <okular/core/fileprinter.h>
#include <qdom.h> #include <qdom.h>
#include <qmutex.h> #include <qmutex.h>
...@@ -66,6 +67,7 @@ DjVuGenerator::DjVuGenerator() ...@@ -66,6 +67,7 @@ DjVuGenerator::DjVuGenerator()
{ {
setFeature( TextExtraction ); setFeature( TextExtraction );
setFeature( Threaded ); setFeature( Threaded );
setFeature( PrintPostscript );
m_djvu = new KDjVu(); m_djvu = new KDjVu();
...@@ -185,30 +187,31 @@ const Okular::DocumentSynopsis * DjVuGenerator::generateDocumentSynopsis() ...@@ -185,30 +187,31 @@ const Okular::DocumentSynopsis * DjVuGenerator::generateDocumentSynopsis()
bool DjVuGenerator::print( QPrinter& printer ) bool DjVuGenerator::print( QPrinter& printer )
{ {
/* This printing method unsupported in QPrinter, looking for alternative. bool result = false;
QList<int> pageList;
if ( !printer.previewOnly() )
pageList = printer.pageList();
else
{
int pages = m_djvu->pages().count();
for( int i = 1; i <= pages; ++i )
pageList.push_back(i);
}
// Create tempfile to write to
KTemporaryFile tf; KTemporaryFile tf;
tf.setSuffix( ".ps" ); tf.setSuffix( ".ps" );
if ( !tf.open() ) if ( !tf.open() )
return false; return false;
QMutexLocker locker( userMutex() ); QMutexLocker locker( userMutex() );
QList<int> pageList = Okular::FilePrinter::pageList( printer, m_djvu->pages().count(),
document()->bookmarkedPageList() );
if ( m_djvu->exportAsPostScript( &tf, pageList ) ) if ( m_djvu->exportAsPostScript( &tf, pageList ) )
{ {
return printer.printFiles( QStringList( tf.fileName() ), false ); tf.setAutoRemove( false );
int ret = Okular::FilePrinter::printFile( printer, tf.fileName(),
Okular::FilePrinter::SystemDeletesFiles,
Okular::FilePrinter::ApplicationSelectsPages,
document()->bookmarkedPageRange() );
result = ( ret >=0 );
} }
*/
return false; tf.close();
return result;
} }
QVariant DjVuGenerator::metaData( const QString &key, const QVariant &option ) const QVariant DjVuGenerator::metaData( const QString &key, const QVariant &option ) const
......
...@@ -478,9 +478,13 @@ void DVIExportToPS::finished_impl(int exit_code) ...@@ -478,9 +478,13 @@ void DVIExportToPS::finished_impl(int exit_code)
{ {
if (printer_ && !output_name_.isEmpty()) { if (printer_ && !output_name_.isEmpty()) {
const QFileInfo output(output_name_); const QFileInfo output(output_name_);
if (output.exists() && output.isReadable()) if (output.exists() && output.isReadable()) {
//Unsupported in Qt // I'm not 100% sure on this, think we still need to select pages in export to ps above
//printer_->printFiles(QStringList(output_name_), true); FilePrinter::printFile( printer_, output_name_,
FilePrinter::ApplicationDeletesFiles,
FilePrinter::ApplicationSelectsPages,
QString() );
}
} }
#ifndef DVIEXPORT_USE_QPROCESS #ifndef DVIEXPORT_USE_QPROCESS
......
...@@ -31,6 +31,8 @@ KIMGIOGenerator::KIMGIOGenerator() ...@@ -31,6 +31,8 @@ KIMGIOGenerator::KIMGIOGenerator()
{ {
setFeature( ReadRawData ); setFeature( ReadRawData );
setFeature( Threaded ); setFeature( Threaded );
setFeature( PrintNative );
setFeature( PrintToFile );
KAboutData *about = new KAboutData( KAboutData *about = new KAboutData(
"okular_kimgio", "okular_kimgio",
...@@ -122,18 +124,12 @@ bool KIMGIOGenerator::print( QPrinter& printer ) ...@@ -122,18 +124,12 @@ bool KIMGIOGenerator::print( QPrinter& printer )
{ {
QPainter p( &printer ); QPainter p( &printer );
uint left, top, right, bottom; QImage image( m_img );
left = printer.paperRect().left() - printer.pageRect().left();
top = printer.paperRect().top() - printer.pageRect().top();
right = printer.paperRect().right() - printer.pageRect().right();
bottom = printer.paperRect().bottom() - printer.pageRect().bottom();
int pageWidth = printer.width() - right; if ( ( image.width() > printer.width() ) || ( image.height() > printer.height() ) )
int pageHeight = printer.height() - bottom;
QImage image( m_img );