kprinter.cpp
00001 /* 00002 * This file is part of the KDE libraries 00003 * Copyright (c) 2001 Michael Goffioul <kdeprint@swing.be> 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Library General Public 00007 * License version 2 as published by the Free Software Foundation. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Library General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Library General Public License 00015 * along with this library; see the file COPYING.LIB. If not, write to 00016 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00017 * Boston, MA 02110-1301, USA. 00018 **/ 00019 00020 #include <config.h> 00021 00022 #include "kprinter.h" 00023 #include "kprinterimpl.h" 00024 #include "kprintdialog.h" 00025 #include "kprintpreview.h" 00026 #include "kmfactory.h" 00027 #include "kmuimanager.h" 00028 #include "kmmanager.h" 00029 #include "driver.h" 00030 00031 #include <qpaintdevicemetrics.h> 00032 #include <qfile.h> 00033 #include <qtl.h> 00034 #include <qdir.h> 00035 #include <qguardedptr.h> 00036 #include <kapplication.h> 00037 #include <kstandarddirs.h> 00038 #include <kglobal.h> 00039 #include <kconfig.h> 00040 #include <krun.h> 00041 #include <knotifyclient.h> 00042 #include <kdebug.h> 00043 #include <klocale.h> 00044 #include <kprocess.h> 00045 #include <klibloader.h> 00046 #include <kmessagebox.h> 00047 00048 static void dumpOptions(const QMap<QString,QString>& opts); 00049 static void reportError(KPrinter*); 00050 00051 //************************************************************************************** 00052 // KPrinterWrapper class 00053 //************************************************************************************** 00054 00055 class KPrinterWrapper : public QPrinter 00056 { 00057 friend class KPrinter; 00058 public: 00059 KPrinterWrapper(KPrinter*, PrinterMode m = ScreenResolution); 00060 ~KPrinterWrapper(); 00061 protected: 00062 virtual bool cmd(int, QPainter*, QPDevCmdParam*); 00063 virtual int metric(int) const; 00064 int qprinterMetric(int) const; 00065 private: 00066 KPrinter *m_printer; 00067 }; 00068 00069 KPrinterWrapper::KPrinterWrapper(KPrinter *prt, QPrinter::PrinterMode m) 00070 : QPrinter(m), m_printer(prt) 00071 { 00072 } 00073 00074 KPrinterWrapper::~KPrinterWrapper() 00075 { 00076 } 00077 00078 bool KPrinterWrapper::cmd(int c, QPainter *painter, QPDevCmdParam *p) 00079 { 00080 return QPrinter::cmd(c,painter,p); 00081 } 00082 00083 int KPrinterWrapper::metric(int m) const 00084 { 00085 return m_printer->metric(m); 00086 } 00087 00088 int KPrinterWrapper::qprinterMetric(int m) const 00089 { 00090 return QPrinter::metric(m); 00091 } 00092 00093 //************************************************************************************** 00094 // KPrinterPrivate class 00095 //************************************************************************************** 00096 00097 class KPrinterPrivate 00098 { 00099 public: 00100 QGuardedPtr<KPrinterImpl> m_impl; 00101 bool m_restore; 00102 bool m_previewonly; 00103 WId m_parentId; 00104 QString m_docfilename; 00105 QString m_docdirectory; 00106 KPrinterWrapper *m_wrapper; 00107 QMap<QString,QString> m_options; 00108 QString m_tmpbuffer; 00109 QString m_printername; 00110 QString m_searchname; 00111 QString m_errormsg; 00112 bool m_ready; 00113 int m_pagenumber; 00114 DrPageSize *m_pagesize; 00115 bool m_useprinterres; 00116 int m_defaultres; 00117 }; 00118 00119 //************************************************************************************** 00120 // KPrinter class 00121 //************************************************************************************** 00122 00123 KPrinter::KPrinter(bool restore, QPrinter::PrinterMode m) 00124 : QPaintDevice(QInternal::Printer|QInternal::ExternalDevice) 00125 { 00126 init(restore, m); 00127 } 00128 00129 KPrinter::~KPrinter() 00130 { 00131 // delete Wrapper object 00132 delete d->m_wrapper; 00133 00134 // save current options 00135 if (d->m_restore) 00136 saveSettings(); 00137 00138 // delete private data (along any data allocated internally) 00139 delete d->m_pagesize; 00140 delete d; 00141 } 00142 00143 void KPrinter::init(bool restore, QPrinter::PrinterMode m) 00144 { 00145 // Private data initialization 00146 d = new KPrinterPrivate; 00147 d->m_impl = KMFactory::self()->printerImplementation(); 00148 d->m_restore = restore; 00149 d->m_previewonly = false; 00150 d->m_parentId = 0; 00151 d->m_pagesize = 0; 00152 00153 // initialize QPrinter wrapper 00154 d->m_wrapper = new KPrinterWrapper(this, m); 00155 00156 // other initialization 00157 d->m_tmpbuffer = d->m_impl->tempFile(); 00158 d->m_ready = false; 00159 d->m_defaultres = d->m_wrapper->resolution(); 00160 d->m_useprinterres = false; 00161 00162 // reload options from implementation (static object) 00163 if (d->m_restore) 00164 loadSettings(); 00165 } 00166 00167 void KPrinter::loadSettings() 00168 { 00169 d->m_options = d->m_impl->loadOptions(); 00170 00171 // load the last printer used in the current process (if any) 00172 // and remove the corresponding entry in the option map, as it 00173 // is not needed anymore 00174 setSearchName(option("kde-searchname")); 00175 d->m_options.remove("kde-searchname"); 00176 00177 KConfig *conf = KGlobal::config(), *pconf = KMFactory::self()->printConfig(); 00178 conf->setGroup("KPrinter Settings"); 00179 pconf->setGroup("General"); 00180 00181 // load latest used printer from config file, if required in the options 00182 if (searchName().isEmpty() && pconf->readBoolEntry("UseLast", true)) 00183 setSearchName(conf->readEntry("Printer")); 00184 00185 // latest used print command 00186 setOption("kde-printcommand",conf->readPathEntry("PrintCommand")); 00187 00188 // latest used document directory 00189 setDocDirectory( conf->readPathEntry( "DocDirectory" ) ); 00190 setDocFileName( "print" ); 00191 } 00192 00193 void KPrinter::saveSettings() 00194 { 00195 if (d->m_impl) 00196 { 00197 setOption("kde-searchname", searchName()); 00198 d->m_impl->saveOptions(d->m_options); 00199 } 00200 00201 // save latest used printer to config file 00202 KConfig *conf = KGlobal::config(); 00203 conf->setGroup("KPrinter Settings"); 00204 conf->writeEntry("Printer",searchName()); 00205 // latest used print command 00206 conf->writePathEntry("PrintCommand",option("kde-printcommand")); 00207 00208 // latest used document directory 00209 if ( d->m_docdirectory.isEmpty() ) 00210 { 00211 KURL url( outputFileName() ); 00212 if ( url.isValid() ) 00213 conf->writePathEntry( "DocDirectory", url.directory() ); 00214 } 00215 else 00216 conf->writePathEntry( "DocDirectory", d->m_docdirectory ); 00217 } 00218 00219 bool KPrinter::setup(QWidget *parent, const QString& caption, bool forceExpand) 00220 { 00221 if (!kapp->authorize("print/dialog")) 00222 { 00223 autoConfigure(QString::null, parent); 00224 return true; // Just print it 00225 } 00226 00227 if (parent) 00228 d->m_parentId = parent->winId(); 00229 00230 KPrintDialog *dlg = KPrintDialog::printerDialog(this, parent, caption, forceExpand); 00231 bool state = false; 00232 if (dlg) 00233 { 00234 state = dlg->exec(); 00235 delete dlg; 00236 } 00237 return state; 00238 } 00239 00240 void KPrinter::addStandardPage(int p) 00241 { 00242 KMFactory::self()->settings()->standardDialogPages |= p; 00243 } 00244 00245 void KPrinter::removeStandardPage(int p) 00246 { 00247 KMFactory::self()->settings()->standardDialogPages &= (~p); 00248 } 00249 00250 void KPrinter::addDialogPage(KPrintDialogPage *page) 00251 { 00252 KMFactory::self()->uiManager()->addPrintDialogPage(page); 00253 } 00254 00255 void KPrinter::setPageSelection(PageSelectionType t) 00256 { 00257 KMFactory::self()->settings()->pageSelection = t; 00258 } 00259 00260 KPrinter::PageSelectionType KPrinter::pageSelection() 00261 { 00262 return (PageSelectionType)KMFactory::self()->settings()->pageSelection; 00263 } 00264 00265 void KPrinter::setApplicationType(ApplicationType t) 00266 { 00267 KMFactory::self()->settings()->application = t; 00268 } 00269 00270 KPrinter::ApplicationType KPrinter::applicationType() 00271 { 00272 return (ApplicationType)KMFactory::self()->settings()->application; 00273 } 00274 00275 bool KPrinter::cmd(int c, QPainter *painter, QPDevCmdParam *p) 00276 { 00277 bool value(true); 00278 if (c == QPaintDevice::PdcBegin) 00279 { 00280 d->m_impl->statusMessage(i18n("Initialization..."), this); 00281 d->m_pagenumber = 1; 00282 preparePrinting(); 00283 d->m_impl->statusMessage(i18n("Generating print data: page %1").arg(d->m_pagenumber), this); 00284 } 00285 value = d->m_wrapper->cmd(c,painter,p); 00286 if (c == QPaintDevice::PdcEnd) 00287 { 00288 // this call should take care of everything (preview, output-to-file, filtering, ...) 00289 value = value && printFiles(QStringList(d->m_wrapper->outputFileName()),true); 00290 // reset "ready" state 00291 finishPrinting(); 00292 } 00293 return value; 00294 } 00295 00296 void KPrinter::translateQtOptions() 00297 { 00298 d->m_wrapper->setCreator(creator()); 00299 d->m_wrapper->setDocName(docName()); 00300 d->m_wrapper->setFullPage(fullPage()); 00301 d->m_wrapper->setColorMode((QPrinter::ColorMode)colorMode()); 00302 d->m_wrapper->setOrientation((QPrinter::Orientation)orientation()); 00303 if ( !option( "kde-printsize" ).isEmpty() ) 00304 d->m_wrapper->setPageSize( ( QPrinter::PageSize )option( "kde-printsize" ).toInt() ); 00305 else 00306 d->m_wrapper->setPageSize((QPrinter::PageSize)pageSize()); 00307 d->m_wrapper->setOutputToFile(true); 00308 d->m_wrapper->setOutputFileName(d->m_tmpbuffer); 00309 d->m_wrapper->setNumCopies(option("kde-qtcopies").isEmpty() ? 1 : option("kde-qtcopies").toInt()); 00310 if (!option("kde-margin-top").isEmpty()) 00311 { 00318 int res = resolution(); 00319 d->m_wrapper->setMargins( 00320 ( int )( ( option("kde-margin-top").toFloat() * res + 71 ) / 72 ), 00321 ( int )( ( option("kde-margin-left").toFloat() * res + 71 ) / 72 ), 00322 ( int )( ( option("kde-margin-bottom").toFloat() * res + 71 ) / 72 ), 00323 ( int )( ( option("kde-margin-right").toFloat() * res + 71 ) / 72 ) ); 00324 } 00325 else if ( d->m_pagesize != NULL ) 00326 { 00327 int res = resolution(); 00328 DrPageSize *ps = d->m_pagesize; 00329 int top = ( int )( ps->topMargin() * res + 71 ) / 72; 00330 int left = ( int )( ps->leftMargin() * res + 71 ) / 72; 00331 int bottom = ( int )( ps->bottomMargin() * res + 71 ) / 72; 00332 int right = ( int )( ps->rightMargin() * res + 71 ) / 72; 00333 if ( !fullPage() ) 00334 { 00335 // Printers can often print very close to the edges (PPD files say ImageArea==PaperDimension). 00336 // But that doesn't mean it looks good. Apps which use setFullPage(false) assume that 00337 // KPrinter will give them reasonable margins, so let's QMAX with defaults from Qt in that case. 00338 // Keep this in sync with KPMarginPage::initPageSize 00339 unsigned int it, il, ib, ir; 00340 d->m_wrapper->margins( &it, &il, &ib, &ir ); 00341 top = QMAX( top, (int)it ); 00342 left = QMAX( left, (int)il ); 00343 bottom = QMAX( bottom, (int)ib ); 00344 right = QMAX( right, (int)ir ); 00345 } 00346 d->m_wrapper->setMargins( top, left, bottom, right ); 00347 } 00348 /*else 00349 { 00350 int res = d->m_wrapper->resolution(); 00351 d->m_wrapper->setMargins( res/3, res/2, res/3, res/2 ); 00352 }*/ 00353 // for special printers, copies are handled by Qt 00354 if (option("kde-isspecial") == "1") 00355 d->m_wrapper->setNumCopies(numCopies()); 00356 } 00357 00358 bool KPrinter::printFiles(const QStringList& l, bool flag, bool startviewer) 00359 { 00360 QStringList files(l); 00361 bool status(true); 00362 00363 // First apply possible filters, and update "remove" flag if filters has 00364 // been applied (result == 0, means nothing happened). 00365 int fresult = d->m_impl->filterFiles(this, files, flag); 00366 if (fresult == -1) 00367 { 00368 reportError(this); 00369 status = false; 00370 } 00371 else if (fresult == 1) 00372 flag = true; 00373 00374 if (status) 00375 { 00376 // Automatic conversion to format supported by print system 00377 fresult = d->m_impl->autoConvertFiles(this, files, flag); 00378 if (fresult == -1) 00379 { 00380 reportError(this); 00381 status = false; 00382 } 00383 else if (fresult == 1) 00384 flag = true; 00385 } 00386 00387 // Continue if status is OK (filtering succeeded) and no output-to-file 00388 if (status && files.count() > 0) 00389 { 00390 // Show preview if needed (only possible for a single file !), and stop 00391 // if the user requested it. Force preview if preview-only mode has been set: it 00392 // then use by default the first file in the list. 00393 if (((files.count() != 1 || option("kde-preview") != "1") && !d->m_previewonly) || doPreview(files[0])) 00394 { 00395 // check if printing has been prepared (it may be not prepared if the KPrinter object is not 00396 // use as a QPaintDevice object) 00397 preparePrinting(); 00398 00399 if (!d->m_impl->printFiles(this, files, flag)) 00400 { 00401 reportError(this); 00402 status = false; 00403 } 00404 else 00405 { 00406 if (/* !outputToFile() && */ startviewer) 00407 { 00408 QStringList args; 00409 args << "-d"; 00410 args << printerName(); 00411 args << "--noshow"; 00412 kapp->kdeinitExec("kjobviewer", args); 00413 } 00414 } 00415 } 00416 else if (flag) 00417 // situation: only one file, it has been previewed and printing has been canceled, then 00418 // we should remove the file ourself 00419 { 00420 QFile::remove(files[0]); 00421 } 00422 } 00423 finishPrinting(); 00424 return status; 00425 } 00426 00427 bool KPrinter::doPreview(const QString& file) 00428 { 00429 d->m_impl->statusMessage(i18n("Previewing..."), this); 00430 d->m_impl->statusMessage(QString::null, this); 00431 return KPrintPreview::preview(file, d->m_previewonly, d->m_parentId); 00432 } 00433 00434 void KPrinter::preparePrinting() 00435 { 00436 // check if already prepared (-> do nothing) 00437 if (d->m_ready) return; 00438 00439 // re-initialize error 00440 setErrorMessage(QString::null); 00441 00442 // re-initialize margins and page size (by default, use Qt mechanism) 00443 setRealPageSize(NULL); 00444 00445 // print-system-specific setup, only if not printing to file 00446 if (option("kde-isspecial") != "1") 00447 d->m_impl->preparePrinting(this); 00448 00449 // set the correct resolution, if needed (or reset it) 00450 int res = option( "kde-resolution" ).toInt(); 00451 if ( d->m_useprinterres && res > 0 ) 00452 d->m_wrapper->setResolution( res ); 00453 else 00454 d->m_wrapper->setResolution( d->m_defaultres ); 00455 00456 // standard Qt settings 00457 translateQtOptions(); 00458 00459 d->m_ready = true; 00460 dumpOptions(d->m_options); 00461 } 00462 00463 void KPrinter::finishPrinting() 00464 { 00465 d->m_ready = false; 00466 // close the status window 00467 d->m_impl->statusMessage(QString::null, this); 00468 } 00469 00470 QValueList<int> KPrinter::pageList() const 00471 { 00472 QValueList<int> list; 00473 int mp(minPage()), MP(maxPage()); 00474 if (mp > 0 && MP > 0 && MP >= mp) 00475 { // do something only if bounds specified 00476 if (option("kde-current") == "1") 00477 { // print only current page 00478 int pp = currentPage(); 00479 if (pp >= mp && pp <= MP) list.append(pp); 00480 } 00481 else 00482 { 00483 // process range specification 00484 if (!option("kde-range").isEmpty()) 00485 { 00486 QStringList ranges = QStringList::split(',',option("kde-range"),false); 00487 for (QStringList::ConstIterator it=ranges.begin();it!=ranges.end();++it) 00488 { 00489 int p = (*it).find('-'); 00490 bool ok; 00491 if (p == -1) 00492 { 00493 int pp = (*it).toInt(&ok); 00494 if (ok && pp >= mp && pp <= MP) 00495 list.append(pp); 00496 } 00497 else 00498 { 00499 int p1(0), p2(0); 00500 p1 = (*it).left(p).toInt(&ok); 00501 if (ok) p2 = (*it).right((*it).length()-p-1).toInt(&ok); 00502 if (ok && p1 <= p2) 00503 { 00504 // clip to min/max 00505 p1 = QMAX(mp,p1); 00506 p2 = QMIN(MP,p2); 00507 for (int i=p1;i<=p2;i++) 00508 list.append(i); 00509 } 00510 } 00511 } 00512 } 00513 else 00514 { // add all pages between min and max 00515 for (int i=mp;i<=MP;i++) list.append(i); 00516 } 00517 00518 // revert the list if needed 00519 if (pageOrder() == LastPageFirst) 00520 { 00521 for (uint i=0;i<(list.count()/2);i++) 00522 qSwap(list[i],list[list.count()-1-i]); 00523 } 00524 00525 // select page set if needed 00526 if (pageSet() != AllPages) 00527 { 00528 bool keepEven = (pageSet() == EvenPages); 00529 for (QValueList<int>::Iterator it=list.begin();it!=list.end();) 00530 if ((((*it) % 2) != 0 && keepEven) || 00531 (((*it) % 2) == 0 && !keepEven)) it = list.remove(it); 00532 else ++it; 00533 } 00534 } 00535 } 00536 return list; 00537 } 00538 00539 //************************************************************************************** 00540 // QPrinter interface 00541 //************************************************************************************** 00542 00543 int KPrinter::numCopies() const 00544 { 00545 bool ok; 00546 int p = option("kde-copies").toInt(&ok); 00547 return (ok ? p : 1); 00548 } 00549 00550 QSize KPrinter::margins() const 00551 { 00552 return d->m_wrapper->margins(); 00553 } 00554 00555 void KPrinter::margins( uint *top, uint *left, uint *bottom, uint *right ) const 00556 { 00557 d->m_wrapper->margins( top, left, bottom, right ); 00558 } 00559 00560 int KPrinter::metric(int m) const 00561 { 00562 if (d->m_pagesize == NULL || !option( "kde-printsize" ).isEmpty()) 00563 return d->m_wrapper->qprinterMetric(m); 00564 00565 int val(0); 00566 bool land = (orientation() == KPrinter::Landscape); 00567 uint res(d->m_wrapper->resolution()), top = res/2, left = res/2, bottom = res/3, right = res/2; 00568 margins( &top, &left, &bottom, &right ); 00569 switch ( m ) 00570 { 00571 case QPaintDeviceMetrics::PdmWidth: 00572 val = (land ? ( int )d->m_pagesize->pageHeight() : ( int )d->m_pagesize->pageWidth()); 00573 if ( res != 72 ) 00574 val = (val * res + 36) / 72; 00575 if ( !fullPage() ) 00576 val -= ( left + right ); 00577 break; 00578 case QPaintDeviceMetrics::PdmHeight: 00579 val = (land ? ( int )d->m_pagesize->pageWidth() : ( int )d->m_pagesize->pageHeight()); 00580 if ( res != 72 ) 00581 val = (val * res + 36) / 72; 00582 if ( !fullPage() ) 00583 val -= ( top + bottom ); 00584 break; 00585 case QPaintDeviceMetrics::PdmWidthMM: 00586 val = metric( QPaintDeviceMetrics::PdmWidth ); 00587 val = (val * 254 + 5*res) / (10*res); // +360 to get the right rounding 00588 break; 00589 case QPaintDeviceMetrics::PdmHeightMM: 00590 val = metric( QPaintDeviceMetrics::PdmHeight ); 00591 val = (val * 254 + 5*res) / (10*res); 00592 break; 00593 default: 00594 val = d->m_wrapper->qprinterMetric(m); 00595 break; 00596 } 00597 return val; 00598 } 00599 00600 void KPrinter::setOrientation(Orientation o) 00601 { 00602 KMFactory::self()->settings()->orientation = o; 00603 setOption("kde-orientation",(o == Landscape ? "Landscape" : "Portrait")); 00604 d->m_impl->broadcastOption("kde-orientation",(o == Landscape ? "Landscape" : "Portrait")); 00605 d->m_impl->broadcastOption( "kde-orientation-fixed", "1" ); 00606 } 00607 00608 void KPrinter::setOption( const QString& key, const QString& value, bool broadcast ) 00609 { 00610 setOption( key, value ); 00611 if ( broadcast ) 00612 d->m_impl->broadcastOption( key, value ); 00613 } 00614 00615 void KPrinter::setPageSize(PageSize s) 00616 { 00617 KMFactory::self()->settings()->pageSize = s; 00618 setOption("kde-pagesize",QString::number((int)s),true); 00619 d->m_impl->broadcastOption( "kde-pagesize-fixed", "1" ); 00620 } 00621 00622 void KPrinter::setOptions(const QMap<QString,QString>& opts) 00623 { // This functions remove all options except those with "kde-..." 00624 // which correspond to externally-sets options (use the value 00625 // from "opts" if specified 00626 QMap<QString,QString> tmpset = d->m_options; 00627 d->m_options = opts; 00628 // remove some problematic options that may not be overwritten (ugly hack). 00629 // Default values will be used instead, except if the dialog has set new ones. 00630 tmpset.remove("kde-pagesize"); 00631 tmpset.remove( "kde-printsize" ); 00632 tmpset.remove("kde-orientation"); 00633 tmpset.remove("kde-colormode"); 00634 tmpset.remove("kde-margin-top"); 00635 tmpset.remove("kde-margin-left"); 00636 tmpset.remove("kde-margin-bottom"); 00637 tmpset.remove("kde-margin-right"); 00638 tmpset.remove( "kde-resolution" ); 00639 tmpset.remove( "kde-fonts" ); 00640 for (QMap<QString,QString>::ConstIterator it=tmpset.begin();it!=tmpset.end();++it) 00641 if (it.key().left(4) == "kde-" && !(d->m_options.contains(it.key()))) 00642 d->m_options[it.key()] = it.data(); 00643 } 00644 00645 void KPrinter::initOptions(const QMap<QString,QString>& opts) 00646 { // This function can be used to initialize the KPrinter object just after 00647 // creation to set some options. Non global options will be propagated to 00648 // all listed printers (non-global => start with "kde-...") 00649 for (QMap<QString,QString>::ConstIterator it=opts.begin(); it!=opts.end(); ++it) 00650 { 00651 setOption(it.key(), it.data()); 00652 if (it.key().left(4) != "kde-") 00653 d->m_impl->broadcastOption(it.key(),it.data()); 00654 } 00655 } 00656 00657 void KPrinter::reload() 00658 { 00659 d->m_impl = KMFactory::self()->printerImplementation(); 00660 int global = KMFactory::self()->settings()->orientation; 00661 if (global != -1) setOrientation((KPrinter::Orientation)global); 00662 global = KMFactory::self()->settings()->pageSize; 00663 if (global != -1) setPageSize((KPrinter::PageSize)global); 00664 //initOptions(d->m_options); 00665 } 00666 00667 bool KPrinter::autoConfigure(const QString& prname, QWidget *parent) 00668 { 00669 KMManager *mgr = KMManager::self(); 00670 KMPrinter *mprt(0); 00671 00672 mgr->printerList(false); 00673 if (prname.isEmpty()) 00674 mprt = mgr->defaultPrinter(); 00675 else 00676 mprt = mgr->findPrinter(prname); 00677 00678 if (mprt) 00679 return mprt->autoConfigure(this, parent); 00680 else 00681 return false; 00682 } 00683 00684 //************************************************************************************** 00685 // Util functions 00686 //************************************************************************************** 00687 00688 void reportError(KPrinter *p) 00689 { 00690 if (!KNotifyClient::event(0,"printerror",i18n("<p><nobr>A print error occurred. Error message received from system:</nobr></p><br>%1").arg(p->errorMessage()))) 00691 kdDebug(500) << "could not send notify event" << endl; 00692 } 00693 00694 KPrinter::PageSize pageNameToPageSize(const QString& _name) 00695 { 00696 QString name = _name.upper(); 00697 if (name == "LETTER") return KPrinter::Letter; 00698 else if (name == "LEGAL") return KPrinter::Legal; 00699 else if (name == "A4") return KPrinter::A4; 00700 else if (name == "A3") return KPrinter::A3; 00701 else if (name == "EXECUTIVE") return KPrinter::Executive; 00702 else if (name == "LEDGER") return KPrinter::Ledger; 00703 else if (name == "TABLOID") return KPrinter::Tabloid; 00704 else if (name == "FOLIO") return KPrinter::Folio; 00705 else if (name == "A5") return KPrinter::A5; 00706 else if (name == "A6") return KPrinter::A6; 00707 else if (name == "A7") return KPrinter::A7; 00708 else if (name == "A8") return KPrinter::A8; 00709 else if (name == "A9") return KPrinter::A9; 00710 else if (name == "A2") return KPrinter::A2; 00711 else if (name == "A1") return KPrinter::A1; 00712 else if (name == "A0") return KPrinter::A0; 00713 else if (name == "B0" || name == "B0ISO") return KPrinter::B0; 00714 else if (name == "B1" || name == "B1ISO") return KPrinter::B1; 00715 else if (name == "B2" || name == "B2ISO") return KPrinter::B2; 00716 else if (name == "B3" || name == "B3ISO") return KPrinter::B3; 00717 else if (name == "B4" || name == "B4ISO") return KPrinter::B4; 00718 else if (name == "B5" || name == "B5ISO") return KPrinter::B5; 00719 else if (name == "B6" || name == "B6ISO") return KPrinter::B6; 00720 else if (name == "B7" || name == "B7ISO") return KPrinter::B7; 00721 else if (name == "B8" || name == "B8ISO") return KPrinter::B8; 00722 else if (name == "B9" || name == "B9ISO") return KPrinter::B9; 00723 else if (name == "B10" || name == "B10ISO") return KPrinter::B10; 00724 else if (name == "C5" || name == "C5E" || name == "ENVC5") return KPrinter::C5E; 00725 else if (name == "DL" || name == "DLE" || name == "ENVDL") return KPrinter::DLE; 00726 else if (name == "COMM10" || name == "COM10" || name == "ENV10") return KPrinter::Comm10E; 00727 else return KPrinter::A4; 00728 } 00729 00730 const char* pageSizeToPageName(KPrinter::PageSize s) 00731 { 00732 switch(s) 00733 { 00734 case KPrinter::Letter: return "Letter"; 00735 case KPrinter::Legal: return "Legal"; 00736 case KPrinter::A4: return "A4"; 00737 case KPrinter::A3: return "A3"; 00738 case KPrinter::Executive: return "Executive"; 00739 case KPrinter::Ledger: return "Ledger"; 00740 case KPrinter::Tabloid: return "Tabloid"; 00741 case KPrinter::Folio: return "Folio"; 00742 case KPrinter::A5: return "A5"; 00743 case KPrinter::A6: return "A6"; 00744 case KPrinter::A7: return "A7"; 00745 case KPrinter::A8: return "A8"; 00746 case KPrinter::A9: return "A9"; 00747 case KPrinter::A2: return "A2"; 00748 case KPrinter::A1: return "A1"; 00749 case KPrinter::A0: return "A0"; 00750 case KPrinter::B0: return "B0"; 00751 case KPrinter::B1: return "B1"; 00752 case KPrinter::B2: return "B2"; 00753 case KPrinter::B3: return "B3"; 00754 case KPrinter::B4: return "B4"; 00755 case KPrinter::B5: return "B5"; 00756 case KPrinter::B6: return "B6"; 00757 case KPrinter::B7: return "B7"; 00758 case KPrinter::B8: return "B8"; 00759 case KPrinter::B9: return "B9"; 00760 case KPrinter::B10: return "B10"; 00761 case KPrinter::C5E: return "C5"; 00762 case KPrinter::DLE: return "DL"; 00763 case KPrinter::Comm10E: return "Comm10"; 00764 default: return "A4"; 00765 } 00766 } 00767 00768 // FIXME: remove for 4.0 00769 QSize rangeToSize( const QString& ) 00770 { 00771 kdWarning( 500 ) << "rangeToSize(QString) is obsolete, do not use (no effect)" << endl; 00772 return QSize(); 00773 } 00774 00775 static void dumpOptions(const QMap<QString,QString>& opts) 00776 { 00777 kdDebug(500) << "********************" << endl; 00778 for (QMap<QString,QString>::ConstIterator it=opts.begin(); it!=opts.end(); ++it) 00779 kdDebug(500) << it.key() << " = " << it.data() << endl; 00780 } 00781 00782 KPrinterImpl* KPrinter::implementation() const 00783 { return d->m_impl; } 00784 00785 const QString& KPrinter::option(const QString& key) const 00786 { return ((const KPrinterPrivate*)(d))->m_options[key]; } 00787 00788 void KPrinter::setOption(const QString& key, const QString& value) 00789 { d->m_options[key] = value; } 00790 00791 QString KPrinter::docName() const 00792 { return option("kde-docname"); } 00793 00794 void KPrinter::setDocName(const QString& d) 00795 { setOption("kde-docname",d); } 00796 00797 QString KPrinter::creator() const 00798 { return option("kde-creator"); } 00799 00800 void KPrinter::setCreator(const QString& d) 00801 { setOption("kde-creator",d); } 00802 00803 bool KPrinter::fullPage() const 00804 { return (option("kde-fullpage") == "1"); } 00805 00806 void KPrinter::setFullPage(bool on) 00807 { setOption("kde-fullpage",(on ? "1" : "0")); } 00808 00809 KPrinter::ColorMode KPrinter::colorMode() const 00810 { return (KPrinter::ColorMode)(option("kde-colormode") == "GrayScale" ? GrayScale : Color); } 00811 00812 void KPrinter::setColorMode(ColorMode m) 00813 { setOption("kde-colormode",(m == Color ? "Color" : "GrayScale")); } 00814 00815 void KPrinter::setNumCopies(int n) 00816 { setOption("kde-copies",QString::number(n)); } 00817 00818 KPrinter::Orientation KPrinter::orientation() const 00819 { return (option("kde-orientation") == "Landscape" ? Landscape : Portrait); } 00820 00821 KPrinter::PageOrder KPrinter::pageOrder() const 00822 { return (option("kde-pageorder") == "Reverse" ? LastPageFirst : FirstPageFirst); } 00823 00824 void KPrinter::setPageOrder(PageOrder o) 00825 { setOption("kde-pageorder",(o == LastPageFirst ? "Reverse" : "Forward")); } 00826 00827 KPrinter::CollateType KPrinter::collate() const 00828 { return (option("kde-collate") == "Collate" ? Collate : Uncollate); } 00829 00830 void KPrinter::setCollate(CollateType c) 00831 { setOption("kde-collate",(c == Collate ? "Collate" : "Uncollate")); } 00832 00833 int KPrinter::minPage() const 00834 { return (option("kde-minpage").isEmpty() ? 0 : option("kde-minpage").toInt()); } 00835 00836 int KPrinter::maxPage() const 00837 { return (option("kde-maxpage").isEmpty() ? 0 : option("kde-maxpage").toInt()); } 00838 00839 void KPrinter::setMinMax(int m, int M) 00840 { setOption("kde-minpage",QString::number(m)); setOption("kde-maxpage",QString::number(M)); } 00841 00842 int KPrinter::fromPage() const 00843 { return (option("kde-frompage").isEmpty() ? 0 : option("kde-frompage").toInt()); } 00844 00845 int KPrinter::toPage() const 00846 { return (option("kde-topage").isEmpty() ? 0 : option("kde-topage").toInt()); } 00847 00848 void KPrinter::setFromTo(int m, int M) 00849 { setOption("kde-frompage",QString::number(m)); setOption("kde-topage",QString::number(M)); setOption("kde-range",(m>0 && M>0 ? QString("%1-%2").arg(m).arg(M) : QString::fromLatin1(""))); } 00850 00851 // if no page size defined, use the localized one 00852 KPrinter::PageSize KPrinter::pageSize() const 00853 { return (option("kde-pagesize").isEmpty() ? (PageSize)KGlobal::locale()->pageSize() : (PageSize)option("kde-pagesize").toInt()); } 00854 00855 KPrinter::PageSetType KPrinter::pageSet() const 00856 { return (option("kde-pageset").isEmpty() ? AllPages : (PageSetType)(option("kde-pageset").toInt())); } 00857 00858 int KPrinter::currentPage() const 00859 { return (option("kde-currentpage").isEmpty() ? 0 : option("kde-currentpage").toInt()); } 00860 00861 void KPrinter::setCurrentPage(int p) 00862 { setOption("kde-currentpage",QString::number(p)); } 00863 00864 QString KPrinter::printerName() const 00865 { return d->m_printername; } 00866 00867 void KPrinter::setPrinterName(const QString& s) 00868 { d->m_printername = s; } 00869 00870 QString KPrinter::printProgram() const 00871 { return (option("kde-isspecial") == "1" ? option("kde-special-command") : QString::null); } 00872 00873 void KPrinter::setPrintProgram(const QString& prg) 00874 { 00875 if (prg.isNull()) 00876 { 00877 setOption("kde-isspecial", "0"); 00878 d->m_options.remove("kde-special-command"); 00879 } 00880 else 00881 { 00882 QString s(prg); 00883 if (s.find("%in") == -1) 00884 s.append(" %in"); 00885 setOutputToFile( s.find( "%out" ) != -1 ); 00886 setOption("kde-isspecial", "1"); 00887 setOption("kde-special-command", s); 00888 } 00889 } 00890 00891 QString KPrinter::printerSelectionOption() const 00892 { return QString::fromLatin1(""); } 00893 00894 void KPrinter::setPrinterSelectionOption(const QString&) 00895 {} 00896 00897 const QMap<QString,QString>& KPrinter::options() const 00898 { return d->m_options; } 00899 00900 QString KPrinter::searchName() const 00901 { return d->m_searchname; } 00902 00903 void KPrinter::setSearchName(const QString& s) 00904 { d->m_searchname = s; } 00905 00906 bool KPrinter::newPage() 00907 { 00908 d->m_pagenumber++; 00909 d->m_impl->statusMessage(i18n("Generating print data: page %1").arg(d->m_pagenumber), this); 00910 return d->m_wrapper->newPage(); 00911 } 00912 00913 QString KPrinter::outputFileName() const 00914 { return option("kde-outputfilename"); } 00915 00916 void KPrinter::setOutputFileName(const QString& f) 00917 { setOption("kde-outputfilename",f); setOutputToFile(!f.isEmpty()); } 00918 00919 bool KPrinter::outputToFile() const 00920 { return (option("kde-outputtofile") == "1" || (option("kde-isspecial") == "1" && option("kde-special-command").isEmpty())); } 00921 00922 void KPrinter::setOutputToFile(bool on) 00923 { 00924 setOption("kde-outputtofile",(on ? "1" : "0")); 00925 if (on) 00926 { 00927 setOption("kde-special-command",QString::null); 00928 setOption("kde-isspecial","1"); 00929 } 00930 } 00931 00932 bool KPrinter::abort() 00933 { return d->m_wrapper->abort(); } 00934 00935 bool KPrinter::aborted() const 00936 { return d->m_wrapper->aborted(); } 00937 00938 void KPrinter::setMargins(QSize m) 00939 { 00940 setMargins( m.height(), m.width(), m.height(), m.width() ); 00941 } 00942 00943 void KPrinter::setMargins( uint top, uint left, uint bottom, uint right ) 00944 { 00945 d->m_wrapper->setMargins( top, left, bottom, right ); 00946 setOption( "kde-margin-top", QString::number( top ), true ); 00947 setOption( "kde-margin-left", QString::number( left ), true ); 00948 setOption( "kde-margin-bottom", QString::number( bottom ), true ); 00949 setOption( "kde-margin-right", QString::number( right ), true ); 00950 } 00951 00952 // FIXME: remove for 4.0 00953 QSize KPrinter::realPageSize() const 00954 { 00955 kdWarning( 500 ) << "KPrinter::realPageSize() is obsolete, do not use" << endl; 00956 if ( d->m_pagesize ) 00957 return d->m_pagesize->pageSize(); 00958 else 00959 return QSize(); 00960 } 00961 00962 void KPrinter::setRealPageSize(DrPageSize *p) 00963 { 00964 if ( p ) 00965 { 00966 kdDebug( 500 ) << "Page size: width =" << p->pageWidth() << endl; 00967 kdDebug( 500 ) << "Page size: height =" << p->pageHeight() << endl; 00968 kdDebug( 500 ) << "Page size: left =" << p->leftMargin() << endl; 00969 kdDebug( 500 ) << "Page size: top =" << p->topMargin() << endl; 00970 kdDebug( 500 ) << "Page size: right =" << p->rightMargin() << endl; 00971 kdDebug( 500 ) << "Page size: bottom =" << p->bottomMargin() << endl; 00972 } 00973 else 00974 kdDebug( 500 ) << "Resetting page size" << endl; 00975 00976 /* we copy the page size structure internally 00977 * as the original object is owned by the driver 00978 * that control its destrution */ 00979 delete d->m_pagesize; 00980 d->m_pagesize = 0; 00981 if ( p ) 00982 d->m_pagesize = new DrPageSize( *p ); 00983 } 00984 00985 // FIXME: remove for 4.0 00986 void KPrinter::setRealPageSize( QSize ) 00987 { 00988 kdWarning( 500 ) << "KPrinter::setRealPageSize(QSize) is obsolete, do not use (no effect)" << endl; 00989 } 00990 00991 // FIXME: remove for 4.0 00992 void KPrinter::setRealDrawableArea( const QRect& ) 00993 { 00994 kdWarning( 500 ) << "KPrinter::setRealDrawableArea(QRect) is obsolete, do not use (no effect)" << endl; 00995 } 00996 00997 // FIXME: remove for 4.0 00998 QRect KPrinter::realDrawableArea() const 00999 { 01000 kdWarning( 500 ) << "KPrinter::realDrawableArea() is obsolete, do not use" << endl; 01001 if ( d->m_pagesize ) 01002 return d->m_pagesize->pageRect(); 01003 else 01004 return QRect(); 01005 } 01006 01007 QString KPrinter::errorMessage() const 01008 { return d->m_errormsg; } 01009 01010 void KPrinter::setErrorMessage(const QString& msg) 01011 { d->m_errormsg = msg; } 01012 01013 /* we're using a builtin member to store this state because we don't 01014 * want to keep it from object to object. So there's no need to use 01015 * the QMap structure to store this 01016 */ 01017 void KPrinter::setPreviewOnly(bool on) 01018 { d->m_previewonly = on; } 01019 01020 bool KPrinter::previewOnly() const 01021 { return d->m_previewonly; } 01022 01023 void KPrinter::setDocFileName(const QString& s) 01024 { d->m_docfilename = s; } 01025 01026 QString KPrinter::docFileName() const 01027 { return d->m_docfilename; } 01028 01029 void KPrinter::setDocDirectory( const QString& s ) 01030 { d->m_docdirectory = s; } 01031 01032 QString KPrinter::docDirectory() const 01033 { return ( d->m_docdirectory.isEmpty() ? QDir::homeDirPath() : d->m_docdirectory ); } 01034 01035 void KPrinter::setResolution(int dpi) 01036 { 01037 d->m_wrapper->setResolution(dpi); 01038 d->m_defaultres = dpi; 01039 } 01040 01041 int KPrinter::resolution() const 01042 { return d->m_wrapper->resolution(); } 01043 01044 void KPrinter::setUsePrinterResolution( bool on ) 01045 { d->m_useprinterres = on; }