00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
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
00100
00101
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 {
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() );
00187 }
00188
00189 bool FilePrinter::detectCupsService()
00190 {
00191
00192
00193
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
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();
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";
00463 case QPrinter::Comm10E: return "Comm10";
00464 case QPrinter::DLE: return "DL";
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
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"