• Skip to content
  • Skip to link menu
KDE 4.0 API Reference
  • KDE API Reference
  • kdegraphics
  • Sitemap
  • Contact Us
 

okular

fileprinter.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2007 by John Layt <john@layt.net>                       *
00003  *                                                                         *
00004  *   FilePrinterPreview based on KPrintPreview (originally LGPL)           *
00005  *   Copyright (c) 2007 Alex Merry <huntedhacker@tiscali.co.uk>            *
00006  *                                                                         *
00007  *   This program is free software; you can redistribute it and/or modify  *
00008  *   it under the terms of the GNU General Public License as published by  *
00009  *   the Free Software Foundation; either version 2 of the License, or     *
00010  *   (at your option) any later version.                                   *
00011  ***************************************************************************/
00012 
00013 #include "fileprinter.h"
00014 
00015 #include <QtGui/QPrinter>
00016 #include <QPrintEngine>
00017 #include <QStringList>
00018 #include <QFile>
00019 #include <QSize>
00020 #include <QtCore/QFile>
00021 #include <QtGui/QLabel>
00022 #include <QtGui/QShowEvent>
00023 
00024 #include <KProcess>
00025 #include <KShell>
00026 #include <klocalsocket.h>
00027 #include <kstandarddirs.h>
00028 #include <ktempdir.h>
00029 #include <kdebug.h>
00030 
00031 #include "debug_p.h"
00032 
00033 using namespace Okular;
00034 
00035 int FilePrinter::printFile( QPrinter &printer, QString file, FileDeletePolicy fileDeletePolicy,
00036                             PageSelectPolicy pageSelectPolicy, const QString &pageRange )
00037 {
00038     FilePrinter fp;
00039     return fp.doPrintFiles( printer, QStringList( file ), fileDeletePolicy, pageSelectPolicy, pageRange );
00040 }
00041 
00042 int FilePrinter::printFiles( QPrinter &printer, const QStringList &fileList, FileDeletePolicy fileDeletePolicy )
00043 {
00044     FilePrinter fp;
00045     return fp.doPrintFiles( printer, fileList, fileDeletePolicy, FilePrinter::ApplicationSelectsPages, QString() );
00046 }
00047 
00048 int FilePrinter::doPrintFiles( QPrinter &printer, QStringList fileList, FileDeletePolicy fileDeletePolicy,
00049                                PageSelectPolicy pageSelectPolicy, const QString &pageRange )
00050 {
00051     QString exe("lpr");
00052 
00053     if ( KStandardDirs::findExe(exe).isEmpty() ) {
00054         exe = "lp";
00055     }
00056 
00057     if ( KStandardDirs::findExe(exe).isEmpty() ) {
00058         return -9;
00059     }
00060 
00061     if ( fileList.size() < 1 ) {
00062         return -8;
00063     }
00064 
00065     for (QStringList::ConstIterator it = fileList.begin(); it != fileList.end(); ++it) {
00066         if (!QFile::exists(*it)) {
00067             return -7;
00068         }
00069     }
00070 
00071     if ( printer.printerState() == QPrinter::Aborted || printer.printerState() == QPrinter::Error ) {
00072         return -6;
00073     }
00074 
00075     // Print to File if a filename set, assumes there must be only 1 file
00076     if ( !printer.outputFileName().isEmpty() ) {
00077 
00078         if ( QFile::exists( printer.outputFileName() ) ) {
00079             QFile::remove( printer.outputFileName() );
00080         }
00081 
00082         int res = QFile::copy( fileList[0], printer.outputFileName() );
00083 
00084         if ( fileDeletePolicy == FilePrinter::SystemDeletesFiles ) {
00085             QFile::remove( fileList[0] );
00086         }
00087 
00088         if ( res ) return 0;
00089 
00090     }
00091 
00092     bool useCupsOptions = cupsAvailable();
00093     QStringList argList = printArguments( printer, fileDeletePolicy, pageSelectPolicy, useCupsOptions, pageRange, exe )
00094                           << fileList;
00095     kDebug(OkularDebug) << "Executing" << exe << "with arguments" << argList;
00096 
00097     int ret = KProcess::execute( exe, argList );
00098 
00099     // If we used the Cups options and the command failed, try again without them in case Cups lpr/lp not installed.
00100     // I'm not convinced this will work, I don't think KProcess returns the result of the command, but rather
00101     // that it was able to be executed?
00102     if ( useCupsOptions && ret < 0 ) {
00103 
00104         argList = printArguments( printer, fileDeletePolicy, pageSelectPolicy, useCupsOptions, pageRange, exe )
00105                   << fileList;
00106         kDebug(OkularDebug) << "Retrying" << exe << "without CUPS arguments" << argList;
00107 
00108         ret = KProcess::execute( exe, argList );
00109     }
00110 
00111     return ret;
00112 }
00113 
00114 QList<int> FilePrinter::pageList( QPrinter &printer, int lastPage, const QList<int> &selectedPageList )
00115 {
00116     if ( printer.printRange() == QPrinter::Selection) {
00117         return selectedPageList;
00118     }
00119 
00120     int startPage, endPage;
00121     QList<int> list;
00122 
00123     if ( printer.printRange() == QPrinter::PageRange ) {
00124         startPage = printer.fromPage();
00125         endPage = printer.toPage();
00126     } else { //AllPages
00127         startPage = 1;
00128         endPage = lastPage;
00129     }
00130 
00131     for (int i = startPage; i <= endPage; i++ ) {
00132         list << i;
00133     }
00134     return list;
00135 }
00136 
00137 QString FilePrinter::pageRange( QPrinter &printer, int lastPage, const QList<int> &selectedPageList )
00138 {
00139     if ( printer.printRange() == QPrinter::Selection) {
00140         return pageListToPageRange( selectedPageList );
00141     }
00142 
00143     if ( printer.printRange() == QPrinter::PageRange ) {
00144         return QString("%1-%2").arg(printer.fromPage()).arg(printer.toPage());
00145     }
00146 
00147     return QString("1-%2").arg( lastPage );
00148 }
00149 
00150 QString FilePrinter::pageListToPageRange( const QList<int> &pageList )
00151 {
00152     QString pageRange;
00153     int count = pageList.count();
00154     int i = 0;
00155     int seqStart = i;
00156     int seqEnd;
00157 
00158     while ( i != count ) {
00159 
00160         if ( i + 1 == count || pageList[i] + 1 != pageList[i+1] ) {
00161 
00162             seqEnd = i;
00163 
00164             if ( !pageRange.isEmpty() ) {
00165                 pageRange.append(",");
00166             }
00167 
00168             if ( seqStart == seqEnd ) {
00169                 pageRange.append(pageList[i]);
00170             } else {
00171                 pageRange.append("%1-%2").arg(seqStart).arg(seqEnd);
00172             }
00173 
00174             seqStart = i + 1;
00175         }
00176 
00177         i++;
00178     }
00179 
00180     return pageRange;
00181 }
00182 
00183 bool FilePrinter::cupsAvailable()
00184 {
00185     FilePrinter fp;
00186     return ( fp.detectCupsConfig() /*&& fp.detectCupsService()*/ );
00187 }
00188 
00189 bool FilePrinter::detectCupsService()
00190 {
00191     // copied from KdeprintChecker::checkService()
00192     // Copyright (c) 2001 Michael Goffioul <kdeprint@swing.be>
00193     // original license LGPL
00194     KLocalSocket sock;
00195     sock.connectToPath("/ipp");
00196     kDebug(OkularDebug) << "socket wait =" << sock.waitForConnected();
00197     kDebug(OkularDebug) << "socket error =" << sock.error();
00198     kDebug(OkularDebug) << "socket isOpen() =" << sock.isOpen();
00199     return sock.isOpen();
00200 }
00201 
00202 bool FilePrinter::detectCupsConfig()
00203 {
00204     if ( QFile::exists("/etc/cups/cupsd.conf") ) return true;
00205     if ( QFile::exists("/usr/etc/cups/cupsd.conf") ) return true;
00206     if ( QFile::exists("/usr/local/etc/cups/cupsd.conf") ) return true;
00207     if ( QFile::exists("/opt/etc/cups/cupsd.conf") ) return true;
00208     if ( QFile::exists("/opt/local/etc/cups/cupsd.conf") ) return true;
00209     return false;
00210 }
00211 
00212 QSize FilePrinter::psPaperSize( QPrinter &printer )
00213 {
00214     QSize size;
00215 
00216     switch ( printer.pageSize() ) {
00217     case QPrinter::A0:        size = QSize( 2384, 3370 ); break;
00218     case QPrinter::A1:        size = QSize( 1684, 2384 ); break;
00219     case QPrinter::A2:        size = QSize( 1191, 1684 ); break;
00220     case QPrinter::A3:        size = QSize(  842, 1191 ); break;
00221     case QPrinter::A4:        size = QSize(  595,  842 ); break;
00222     case QPrinter::A5:        size = QSize(  420,  595 ); break;
00223     case QPrinter::A6:        size = QSize(  298,  420 ); break;
00224     case QPrinter::A7:        size = QSize(  210,  298 ); break;
00225     case QPrinter::A8:        size = QSize(  147,  210 ); break;
00226     case QPrinter::A9:        size = QSize(  105,  147 ); break;
00227     case QPrinter::B0:        size = QSize( 2835, 4008 ); break;
00228     case QPrinter::B1:        size = QSize( 2004, 2835 ); break;
00229     case QPrinter::B2:        size = QSize( 1417, 2004 ); break;
00230     case QPrinter::B3:        size = QSize( 1001, 1417 ); break;
00231     case QPrinter::B4:        size = QSize(  709, 1001 ); break;
00232     case QPrinter::B5:        size = QSize(  499,  709 ); break;
00233     case QPrinter::B6:        size = QSize(  354,  499 ); break;
00234     case QPrinter::B7:        size = QSize(  249,  354 ); break;
00235     case QPrinter::B8:        size = QSize(  176,  249 ); break;
00236     case QPrinter::B9:        size = QSize(  125,  176 ); break;
00237     case QPrinter::B10:       size = QSize(   88,  125 ); break;
00238     case QPrinter::C5E:       size = QSize(  459,  649 ); break;
00239     case QPrinter::Comm10E:   size = QSize(  297,  684 ); break;
00240     case QPrinter::DLE:       size = QSize(  312,  624 ); break;
00241     case QPrinter::Executive: size = QSize(  522,  756 ); break;
00242     case QPrinter::Folio:     size = QSize(  595,  935 ); break;
00243     case QPrinter::Ledger:    size = QSize( 1224,  792 ); break;
00244     case QPrinter::Legal:     size = QSize(  612, 1008 ); break;
00245     case QPrinter::Letter:    size = QSize(  612,  792 ); break;
00246     case QPrinter::Tabloid:   size = QSize(  792, 1224 ); break;
00247     case QPrinter::Custom:    return QSize( (int) printer.widthMM() * ( 25.4 / 72 ),
00248                                             (int) printer.heightMM() * ( 25.4 / 72 ) );
00249     default:                  return QSize();
00250     }
00251 
00252     if ( printer.orientation() == QPrinter::Landscape ) {
00253         size.transpose();
00254     }
00255 
00256     return size;
00257 }
00258 
00259 
00260 
00261 
00262 QStringList FilePrinter::printArguments( QPrinter &printer, FileDeletePolicy fileDeletePolicy,
00263                                          PageSelectPolicy pageSelectPolicy, bool useCupsOptions,
00264                                          const QString &pageRange, const QString &version )
00265 {
00266     QStringList argList;
00267 
00268     if ( ! destination( printer, version ).isEmpty() ) {
00269         argList << destination( printer, version );
00270     }
00271 
00272     if ( ! copies( printer, version ).isEmpty() ) {
00273         argList << copies( printer, version );
00274     }
00275 
00276     if ( ! jobname( printer, version ).isEmpty() ) {
00277         argList << jobname( printer, version );
00278     }
00279 
00280     if ( ! pages( printer, pageSelectPolicy, pageRange, useCupsOptions, version ).isEmpty() ) {
00281         argList << pages( printer, pageSelectPolicy, pageRange, useCupsOptions, version );
00282     }
00283 
00284     if ( useCupsOptions && ! cupsOptions( printer ).isEmpty() ) {
00285         argList << cupsOptions( printer );
00286     }
00287 
00288     if ( ! deleteFile( printer, fileDeletePolicy, version ).isEmpty() ) {
00289         argList << deleteFile( printer, fileDeletePolicy, version );
00290     }
00291 
00292     if ( version == "lp" ) {
00293         argList << "--";
00294     }
00295 
00296     return argList;
00297 }
00298 
00299 QStringList FilePrinter::destination( QPrinter &printer, const QString &version )
00300 {
00301     if ( version == "lp" ) {
00302         return QStringList("-d") << printer.printerName();
00303     }
00304 
00305     if ( version == "lpr" ) {
00306         return QStringList("-P") << printer.printerName();
00307     }
00308 
00309     return QStringList();
00310 }
00311 
00312 QStringList FilePrinter::copies( QPrinter &printer, const QString &version )
00313 {
00314     // Can't use QPrinter::numCopies(), as if CUPS will always return 1, not sure if this behaves same way as well?
00315     int cp = printer.printEngine()->property( QPrintEngine::PPK_NumberOfCopies ).toInt();
00316 
00317     if ( version == "lp" ) {
00318         return QStringList("-n") << QString("%1").arg( cp );
00319     }
00320 
00321     if ( version == "lpr" ) {
00322         return QStringList() << QString("-#%1").arg( cp );
00323     }
00324 
00325     return QStringList();
00326 }
00327 
00328 QStringList FilePrinter::jobname( QPrinter &printer, const QString &version )
00329 {
00330     if ( ! printer.docName().isEmpty() ) {
00331 
00332         if ( version == "lp" ) {
00333             return QStringList("-t") << printer.docName();
00334         }
00335 
00336         if ( version == "lpr" ) {
00337             return QStringList("-J") << printer.docName();
00338         }
00339     }
00340 
00341     return QStringList();
00342 }
00343 
00344 QStringList FilePrinter::deleteFile( QPrinter &printer, FileDeletePolicy fileDeletePolicy, const QString &version )
00345 {
00346     if ( fileDeletePolicy == FilePrinter::SystemDeletesFiles && version == "lpr" ) {
00347         return QStringList("-r");
00348     }
00349 
00350     return QStringList();
00351 }
00352 
00353 QStringList FilePrinter::pages( QPrinter &printer, PageSelectPolicy pageSelectPolicy, const QString &pageRange,
00354                                     bool useCupsOptions, const QString &version )
00355 {
00356     if ( pageSelectPolicy == FilePrinter::SystemSelectsPages ) {
00357 
00358         if ( printer.printRange() == QPrinter::Selection && ! pageRange.isEmpty() ) {
00359 
00360             if ( version == "lp" ) {
00361                 return QStringList("-P") << pageRange ;
00362             }
00363 
00364             if ( version == "lpr" && useCupsOptions ) {
00365                 return QStringList("-o") << QString("page-ranges=%1").arg( pageRange );
00366             }
00367 
00368         }
00369 
00370         if ( printer.printRange() == QPrinter::PageRange ) {
00371 
00372             if ( version == "lp" ) {
00373                 return QStringList("-P") << QString("%1-%2").arg( printer.fromPage() )
00374                                                             .arg( printer.toPage() );
00375             }
00376 
00377             if ( version == "lpr" && useCupsOptions ) {
00378                 return QStringList("-o") << QString("page-ranges=%1-%2").arg( printer.fromPage() )
00379                                                                         .arg( printer.toPage() );
00380             }
00381 
00382         }
00383 
00384     }
00385 
00386     return QStringList(); // AllPages
00387 }
00388 
00389 QStringList FilePrinter::cupsOptions( QPrinter &printer )
00390 {
00391     QStringList optionList;
00392 
00393     if ( ! optionMedia( printer ).isEmpty() ) {
00394         optionList << optionMedia( printer );
00395     }
00396 
00397     if ( ! optionOrientation( printer ).isEmpty() ) {
00398         optionList << optionOrientation( printer );
00399     }
00400 
00401     if ( ! optionDoubleSidedPrinting( printer ).isEmpty() ) {
00402         optionList << optionDoubleSidedPrinting( printer );
00403     }
00404 
00405     if ( ! optionPageOrder( printer ).isEmpty() ) {
00406         optionList << optionPageOrder( printer );
00407     }
00408 
00409     if ( ! optionCollateCopies( printer ).isEmpty() ) {
00410         optionList << optionCollateCopies( printer );
00411     }
00412 
00413     return optionList;
00414 }
00415 
00416 QStringList FilePrinter::optionMedia( QPrinter &printer )
00417 {
00418     if ( ! mediaPageSize( printer ).isEmpty() && 
00419          ! mediaPaperSource( printer ).isEmpty() ) {
00420         return QStringList("-o") <<
00421                 QString("media=%1,%2").arg( mediaPageSize( printer ) )
00422                                       .arg( mediaPaperSource( printer ) );
00423     }
00424 
00425     if ( ! mediaPageSize( printer ).isEmpty() ) {
00426         return QStringList("-o") <<
00427                 QString("media=%1").arg( mediaPageSize( printer ) );
00428     }
00429 
00430     if ( ! mediaPaperSource( printer ).isEmpty() ) {
00431         return QStringList("-o") <<
00432                 QString("media=%1").arg( mediaPaperSource( printer ) );
00433     }
00434 
00435     return QStringList();
00436 }
00437 
00438 QString FilePrinter::mediaPageSize( QPrinter &printer )
00439 {
00440     switch ( printer.pageSize() ) {
00441     case QPrinter::A0:         return "A0";
00442     case QPrinter::A1:         return "A1";
00443     case QPrinter::A2:         return "A2";
00444     case QPrinter::A3:         return "A3";
00445     case QPrinter::A4:         return "A4";
00446     case QPrinter::A5:         return "A5";
00447     case QPrinter::A6:         return "A6";
00448     case QPrinter::A7:         return "A7";
00449     case QPrinter::A8:         return "A8";
00450     case QPrinter::A9:         return "A9";
00451     case QPrinter::B0:         return "B0";
00452     case QPrinter::B1:         return "B1";
00453     case QPrinter::B10:        return "B10";
00454     case QPrinter::B2:         return "B2";
00455     case QPrinter::B3:         return "B3";
00456     case QPrinter::B4:         return "B4";
00457     case QPrinter::B5:         return "B5";
00458     case QPrinter::B6:         return "B6";
00459     case QPrinter::B7:         return "B7";
00460     case QPrinter::B8:         return "B8";
00461     case QPrinter::B9:         return "B9";
00462     case QPrinter::C5E:        return "C5";     //Correct Translation?
00463     case QPrinter::Comm10E:    return "Comm10"; //Correct Translation?
00464     case QPrinter::DLE:        return "DL";     //Correct Translation?
00465     case QPrinter::Executive:  return "Executive";
00466     case QPrinter::Folio:      return "Folio";
00467     case QPrinter::Ledger:     return "Ledger";
00468     case QPrinter::Legal:      return "Legal";
00469     case QPrinter::Letter:     return "Letter";
00470     case QPrinter::Tabloid:    return "Tabloid";
00471     case QPrinter::Custom:     return QString("Custom.%1x%2mm")
00472                                             .arg( printer.heightMM() )
00473                                             .arg( printer.widthMM() );
00474     default:                   return QString();
00475     }
00476 }
00477 
00478 // What about Upper and MultiPurpose?  And others in PPD???
00479 QString FilePrinter::mediaPaperSource( QPrinter &printer )
00480 {
00481     switch ( printer.paperSource() ) {
00482     case QPrinter::Auto:            return QString();
00483     case QPrinter::Cassette:        return "Cassette";
00484     case QPrinter::Envelope:        return "Envelope";
00485     case QPrinter::EnvelopeManual:  return "EnvelopeManual";
00486     case QPrinter::FormSource:      return "FormSource";
00487     case QPrinter::LargeCapacity:   return "LargeCapacity";
00488     case QPrinter::LargeFormat:     return "LargeFormat";
00489     case QPrinter::Lower:           return "Lower";
00490     case QPrinter::MaxPageSource:   return "MaxPageSource";
00491     case QPrinter::Middle:          return "Middle";
00492     case QPrinter::Manual:          return "Manual";
00493     case QPrinter::OnlyOne:         return "OnlyOne";
00494     case QPrinter::Tractor:         return "Tractor";
00495     case QPrinter::SmallFormat:     return "SmallFormat";
00496     default:                        return QString();
00497     }
00498 }
00499 
00500 QStringList FilePrinter::optionOrientation( QPrinter &printer )
00501 {
00502     switch ( printer.orientation() ) {
00503     case QPrinter::Portrait:   return QStringList("-o") << "portrait";
00504     case QPrinter::Landscape:  return QStringList("-o") << "landscape";
00505     default:                   return QStringList();
00506     }
00507 }
00508 
00509 QStringList FilePrinter::optionDoubleSidedPrinting( QPrinter &printer )
00510 {
00511     if ( printer.doubleSidedPrinting() ) {
00512         if ( printer.orientation() == QPrinter::Landscape ) {
00513             return QStringList("-o") << "sides=two-sided-short-edge";
00514         } else {
00515             return QStringList("-o") << "sides=two-sided-long-edge";
00516         }
00517     }
00518     return QStringList("-o") << "sides=one-sided";
00519 }
00520 
00521 QStringList FilePrinter::optionPageOrder( QPrinter &printer )
00522 {
00523     if ( printer.pageOrder() == QPrinter::LastPageFirst ) {
00524         return QStringList("-o") << "outputorder=reverse";
00525     }
00526     return QStringList("-o") << "outputorder=normal";
00527 }
00528 
00529 QStringList FilePrinter::optionCollateCopies( QPrinter &printer )
00530 {
00531     if ( printer.collateCopies() ) {
00532         return QStringList("-o") << "Collate=True";
00533     }
00534     return QStringList("-o") << "Collate=False";
00535 }
00536 
00537 #include "fileprinter.moc"

okular

Skip menu "okular"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdegraphics

Skip menu "kdegraphics"
  • okular
Generated for kdegraphics by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal