00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
#include <config.h>
00021
00022
#include "kmcupsmanager.h"
00023
#include "kmprinter.h"
00024
#include "ipprequest.h"
00025
#include "cupsinfos.h"
00026
#include "driver.h"
00027
#include "kmfactory.h"
00028
#include "kmdbentry.h"
00029
#include "cupsaddsmb2.h"
00030
#include "ippreportdlg.h"
00031
#include "kpipeprocess.h"
00032
#include "util.h"
00033
#include "foomatic2loader.h"
00034
#include "ppdloader.h"
00035
00036
#include <qfile.h>
00037
#include <qtextstream.h>
00038
#include <qregexp.h>
00039
#include <qtimer.h>
00040
#include <qsocket.h>
00041
#include <qdatetime.h>
00042
00043
#include <kdebug.h>
00044
#include <kapplication.h>
00045
#include <klocale.h>
00046
#include <kconfig.h>
00047
#include <kstandarddirs.h>
00048
#include <klibloader.h>
00049
#include <kmessagebox.h>
00050
#include <kaction.h>
00051
#include <kdialogbase.h>
00052
#include <kextendedsocket.h>
00053
#include <kprocess.h>
00054
#include <kfilterdev.h>
00055
#include <cups/cups.h>
00056
#include <cups/ppd.h>
00057
#include <math.h>
00058
00059
#define ppdi18n(s) i18n(QString::fromLocal8Bit(s).utf8())
00060
00061
void extractMaticData(
QString& buf,
const QString& filename);
00062
QString printerURI(KMPrinter *p,
bool useExistingURI =
false);
00063
QString downloadDriver(KMPrinter *p);
00064
00065
static int trials = 5;
00066
00067
00068
00069 KMCupsManager::KMCupsManager(
QObject *parent,
const char *name,
const QStringList & )
00070 : KMManager(parent,name)
00071 {
00072
00073
00074 CupsInfos::self();
00075 m_cupsdconf = 0;
00076 m_currentprinter = 0;
00077 m_socket = 0;
00078
00079 setHasManagement(
true);
00080 setPrinterOperationMask(KMManager::PrinterAll);
00081 setServerOperationMask(KMManager::ServerAll);
00082
00083
00084
00085
00086 setenv(
"LANG",
"en", 1);
00087 }
00088
00089 KMCupsManager::~KMCupsManager()
00090 {
00091
00092 }
00093
00094
QString KMCupsManager::driverDbCreationProgram()
00095 {
00096
return QString::fromLatin1(
"make_driver_db_cups");
00097 }
00098
00099
QString KMCupsManager::driverDirectory()
00100 {
00101
QString d = cupsInstallDir();
00102
if (d.
isEmpty())
00103 d =
"/usr";
00104 d.
append(
"/share/cups/model");
00105
00106 d.
append(
":/usr/share/foomatic/db/source");
00107
return d;
00108 }
00109
00110
QString KMCupsManager::cupsInstallDir()
00111 {
00112 KConfig *conf= KMFactory::self()->printConfig();
00113 conf->setGroup(
"CUPS");
00114
QString dir = conf->readPathEntry(
"InstallDir");
00115
return dir;
00116 }
00117
00118
void KMCupsManager::reportIppError(IppRequest *req)
00119 {
00120 setErrorMsg(req->statusMessage());
00121 }
00122
00123
bool KMCupsManager::createPrinter(KMPrinter *p)
00124 {
00125
bool isclass = p->isClass(
false), result(
false);
00126 IppRequest req;
00127
QString uri;
00128
00129 uri = printerURI(p,
false);
00130 req.addURI(IPP_TAG_OPERATION,
"printer-uri",uri);
00131
00132 p->setUri(KURL(uri));
00133
00134
if (isclass)
00135 {
00136 req.setOperation(CUPS_ADD_CLASS);
00137
QStringList members = p->members(), uris;
00138
QString s =
QString::fromLocal8Bit(
"ipp://%1:%2/printers/").arg(CupsInfos::self()->host()).arg(CupsInfos::self()->port());
00139
for (QStringList::ConstIterator it=members.begin(); it!=members.end(); ++it)
00140 uris.append(s+(*it));
00141 req.addURI(IPP_TAG_PRINTER,
"member-uris",uris);
00142 }
00143
else
00144 {
00145 req.setOperation(CUPS_ADD_PRINTER);
00146
00147
00148 KMPrinter *otherP = findPrinter(p->printerName());
00149
if (!otherP || otherP->device() != p->device())
00150 {
00156 req.addURI(IPP_TAG_PRINTER,
"device-uri",p->device());
00157 }
00158
if (!p->option(
"kde-banners").isEmpty())
00159 {
00160
QStringList bans =
QStringList::split(
',',p->option(
"kde-banners"),
false);
00161
while (bans.count() < 2)
00162 bans.append(
"none");
00163 req.addName(IPP_TAG_PRINTER,
"job-sheets-default",bans);
00164 }
00165 req.addInteger(IPP_TAG_PRINTER,
"job-quota-period",p->option(
"job-quota-period").toInt());
00166 req.addInteger(IPP_TAG_PRINTER,
"job-k-limit",p->option(
"job-k-limit").toInt());
00167 req.addInteger(IPP_TAG_PRINTER,
"job-page-limit",p->option(
"job-page-limit").toInt());
00168
if (!p->option(
"requesting-user-name-denied").isEmpty())
00169 req.addName(IPP_TAG_PRINTER,
"requesting-user-name-denied",QStringList::split(
",",p->option(
"requesting-user-name-denied"),
false));
00170
else if (!p->option(
"requesting-user-name-allowed").isEmpty())
00171 req.addName(IPP_TAG_PRINTER,
"requesting-user-name-allowed",QStringList::split(
",",p->option(
"requesting-user-name-allowed"),
false));
00172
else
00173 req.addName(IPP_TAG_PRINTER,
"requesting-user-name-allowed",QString::fromLatin1(
"all"));
00174 }
00175 req.addText(IPP_TAG_PRINTER,
"printer-info",p->description());
00176 req.addText(IPP_TAG_PRINTER,
"printer-location",p->location());
00177
00178
if (req.doRequest(
"/admin/"))
00179 {
00180 result =
true;
00181
if (p->driver())
00182 result = savePrinterDriver(p,p->driver());
00183
if (result)
00184 upPrinter(p,
true);
00185 }
00186
else reportIppError(&req);
00187
00188
return result;
00189 }
00190
00191
bool KMCupsManager::removePrinter(KMPrinter *p)
00192 {
00193
bool result = setPrinterState(p,CUPS_DELETE_PRINTER);
00194
return result;
00195 }
00196
00197
bool KMCupsManager::enablePrinter(KMPrinter *p,
bool state)
00198 {
00199
return setPrinterState(p, (state ? CUPS_ACCEPT_JOBS : CUPS_REJECT_JOBS));
00200 }
00201
00202
bool KMCupsManager::startPrinter(KMPrinter *p,
bool state)
00203 {
00204
return setPrinterState(p, (state ? IPP_RESUME_PRINTER : IPP_PAUSE_PRINTER));
00205 }
00206
00207
bool KMCupsManager::setDefaultPrinter(KMPrinter *p)
00208 {
00209
return setPrinterState(p,CUPS_SET_DEFAULT);
00210 }
00211
00212
bool KMCupsManager::setPrinterState(KMPrinter *p,
int state)
00213 {
00214 IppRequest req;
00215
QString uri;
00216
00217 req.setOperation(state);
00218 uri = printerURI(p);
00219 req.addURI(IPP_TAG_OPERATION,
"printer-uri",uri);
00220
if (req.doRequest(
"/admin/"))
00221
return true;
00222 reportIppError(&req);
00223
return false;
00224 }
00225
00226
bool KMCupsManager::completePrinter(KMPrinter *p)
00227 {
00228
if (completePrinterShort(p))
00229 {
00230
00231
QString ppdname = downloadDriver(p);
00232 ppd_file_t *ppd = (ppdname.
isEmpty() ? NULL : ppdOpenFile(ppdname.
local8Bit()));
00233
if (ppd)
00234 {
00235 KMDBEntry entry;
00236
00237
00238
00239 entry.manufacturer = ppd->manufacturer;
00240 entry.model = ppd->shortnickname;
00241 entry.modelname = ppd->modelname;
00242
00243 entry.validate(
false);
00244
00245 p->setManufacturer(entry.manufacturer);
00246 p->setModel(entry.model);
00247 p->setDriverInfo(QString::fromLocal8Bit(ppd->nickname));
00248 ppdClose(ppd);
00249 }
00250
if (!ppdname.
isEmpty())
00251
QFile::remove(ppdname);
00252
00253
return true;
00254 }
00255
return false;
00256 }
00257
00258
bool KMCupsManager::completePrinterShort(KMPrinter *p)
00259 {
00260 IppRequest req;
00261
QStringList keys;
00262
QString uri;
00263
00264 req.setOperation(IPP_GET_PRINTER_ATTRIBUTES);
00265 uri = printerURI(p,
true);
00266 req.addURI(IPP_TAG_OPERATION,
"printer-uri",uri);
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308 keys.append(
"printer-info");
00309 keys.append(
"printer-make-and-model");
00310 keys.append(
"job-sheets-default");
00311 keys.append(
"job-sheets-supported");
00312 keys.append(
"job-quota-period");
00313 keys.append(
"job-k-limit");
00314 keys.append(
"job-page-limit");
00315 keys.append(
"requesting-user-name-allowed");
00316 keys.append(
"requesting-user-name-denied");
00317
if (p->isClass(
true))
00318 {
00319 keys.append(
"member-uris");
00320 keys.append(
"member-names");
00321 }
00322
else
00323 keys.append(
"device-uri");
00324 req.addKeyword(IPP_TAG_OPERATION,
"requested-attributes",keys);
00325
00326
if (req.doRequest(
"/printers/"))
00327 {
00328
QString value;
00329
if (req.text(
"printer-info",value)) p->setDescription(value);
00330
00331
00332
if (req.text(
"printer-make-and-model",value)) p->setDriverInfo(value);
00333
if (req.uri(
"device-uri",value))
00334 {
00339 p->setDevice( value );
00340 }
00341
QStringList values;
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
if (req.name(
"member-names",values))
00354 p->setMembers(values);
00355
00356 req.name(
"job-sheets-default",values);
00357
while (values.count() < 2) values.append(
"none");
00358 p->setOption(
"kde-banners",values.
join(QString::fromLatin1(
",")));
00359
if (req.name(
"job-sheets-supported",values)) p->setOption(
"kde-banners-supported",values.
join(QString::fromLatin1(
",")));
00360
00361
00362
int ival;
00363
if (req.integer(
"job-quota-period",ival)) p->setOption(
"job-quota-period",QString::number(ival));
00364
if (req.integer(
"job-k-limit",ival)) p->setOption(
"job-k-limit",QString::number(ival));
00365
if (req.integer(
"job-page-limit",ival)) p->setOption(
"job-page-limit",QString::number(ival));
00366
00367
00368
if (req.name(
"requesting-user-name-allowed",values) && values.count() > 0)
00369 {
00370 p->removeOption(
"requesting-user-name-denied");
00371 p->setOption(
"requesting-user-name-allowed",values.
join(
","));
00372 }
00373
if (req.name(
"requesting-user-name-denied",values) && values.count() > 0)
00374 {
00375 p->removeOption(
"requesting-user-name-allowed");
00376 p->setOption(
"requesting-user-name-denied",values.
join(
","));
00377 }
00378
00379
return true;
00380 }
00381
00382 reportIppError(&req);
00383
return false;
00384 }
00385
00386
bool KMCupsManager::testPrinter(KMPrinter *p)
00387 {
00388
return KMManager::testPrinter(p);
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411 }
00412
00413
void KMCupsManager::listPrinters()
00414 {
00415 loadServerPrinters();
00416 }
00417
00418
void KMCupsManager::loadServerPrinters()
00419 {
00420 IppRequest req;
00421
QStringList keys;
00422
00423
00424 req.setOperation(CUPS_GET_PRINTERS);
00425 keys.append(
"printer-name");
00426 keys.append(
"printer-type");
00427 keys.append(
"printer-state");
00428
00429 keys.append(
"printer-location");
00430 keys.append(
"printer-uri-supported");
00431 keys.append(
"printer-is-accepting-jobs");
00432 req.addKeyword(IPP_TAG_OPERATION,
"requested-attributes",keys);
00433
00434
if (req.doRequest(
"/printers/"))
00435 {
00436 processRequest(&req);
00437
00438
00439 req.init();
00440 req.setOperation(CUPS_GET_CLASSES);
00441 req.addKeyword(IPP_TAG_OPERATION,
"requested-attributes",keys);
00442
00443
if (req.doRequest(
"/classes/"))
00444 {
00445 processRequest(&req);
00446
00447
00448 req.init();
00449 req.setOperation(CUPS_GET_DEFAULT);
00450 req.addKeyword(IPP_TAG_OPERATION,
"requested-attributes",QString::fromLatin1(
"printer-name"));
00451
if (req.doRequest(
"/printers/"))
00452 {
00453
QString s = QString::null;
00454 req.name(
"printer-name",s);
00455 setHardDefault(findPrinter(s));
00456 }
00457
00458
00459
00460
00461
00462
return;
00463 }
00464 }
00465
00466
00467 reportIppError(&req);
00468 }
00469
00470
void KMCupsManager::processRequest(IppRequest* req)
00471 {
00472 ipp_attribute_t *attr = req->first();
00473 KMPrinter *printer =
new KMPrinter();
00474
while (attr)
00475 {
00476
QString attrname(attr->name);
00477
if (attrname ==
"printer-name")
00478 {
00479
QString value =
QString::fromLocal8Bit(attr->values[0].string.text);
00480 printer->setName(value);
00481 printer->setPrinterName(value);
00482 }
00483
else if (attrname ==
"printer-type")
00484 {
00485
int value = attr->values[0].integer;
00486 printer->setType(0);
00487 printer->addType(((value & CUPS_PRINTER_CLASS) || (value & CUPS_PRINTER_IMPLICIT) ? KMPrinter::Class : KMPrinter::Printer));
00488
if ((value & CUPS_PRINTER_REMOTE)) printer->addType(KMPrinter::Remote);
00489
if ((value & CUPS_PRINTER_IMPLICIT)) printer->addType(KMPrinter::Implicit);
00490
00491
00492 printer->setPrinterCap( ( value & CUPS_PRINTER_OPTIONS ) >> 2 );
00493 }
00494
else if (attrname ==
"printer-state")
00495 {
00496
switch (attr->values[0].integer)
00497 {
00498
case IPP_PRINTER_IDLE: printer->setState(KMPrinter::Idle);
break;
00499
case IPP_PRINTER_PROCESSING: printer->setState(KMPrinter::Processing);
break;
00500
case IPP_PRINTER_STOPPED: printer->setState(KMPrinter::Stopped);
break;
00501 }
00502 }
00503
else if (attrname ==
"printer-uri-supported")
00504 {
00505 printer->setUri(KURL(attr->values[0].string.text));
00506 }
00507
else if (attrname ==
"printer-location")
00508 {
00509 printer->setLocation(QString::fromLocal8Bit(attr->values[0].string.text));
00510 }
00511
else if (attrname ==
"printer-is-accepting-jobs")
00512 {
00513 printer->setAcceptJobs(attr->values[0].boolean);
00514 }
00515
if (attrname.isEmpty() || attr == req->last())
00516 {
00517 addPrinter(printer);
00518 printer =
new KMPrinter();
00519 }
00520 attr = attr->next;
00521 }
00522
delete printer;
00523 }
00524
00525 DrMain* KMCupsManager::loadPrinterDriver(KMPrinter *p,
bool)
00526 {
00527
if (!p || p->isClass(
true))
00528
return NULL;
00529
00530
QString fname = downloadDriver(p);
00531 DrMain *driver(0);
00532
if (!fname.
isEmpty())
00533 {
00534 driver = loadDriverFile(fname);
00535
if (driver)
00536 driver->set(
"temporary",fname);
00537 }
00538
00539
return driver;
00540 }
00541
00542 DrMain* KMCupsManager::loadFileDriver(
const QString& filename)
00543 {
00544
if (filename.
startsWith(
"ppd:"))
00545
return loadDriverFile(filename.
mid(4));
00546
else if (filename.
startsWith(
"foomatic/"))
00547
return loadMaticDriver(filename);
00548
else
00549
return loadDriverFile(filename);
00550 }
00551
00552 DrMain* KMCupsManager::loadMaticDriver(
const QString& drname)
00553 {
00554
QStringList comps =
QStringList::split(
'/', drname,
false);
00555
QString tmpFile = locateLocal(
"tmp",
"foomatic_" + kapp->randomString(8));
00556
QString PATH = getenv(
"PATH") +
QString::fromLatin1(
":/usr/sbin:/usr/local/sbin:/opt/sbin:/opt/local/sbin");
00557
QString exe = KStandardDirs::findExe(
"foomatic-datafile", PATH);
00558
if (exe.
isEmpty())
00559 {
00560 setErrorMsg(i18n(
"Unable to find the executable foomatic-datafile "
00561
"in your PATH. Check that Foomatic is correctly installed."));
00562
return NULL;
00563 }
00564
00565 KPipeProcess in;
00566
QFile out(tmpFile);
00567
QString cmd = KProcess::quote(exe);
00568 cmd +=
" -t cups -d ";
00569 cmd += KProcess::quote(comps[2]);
00570 cmd +=
" -p ";
00571 cmd += KProcess::quote(comps[1]);
00572
if (in.open(cmd) && out.open(IO_WriteOnly))
00573 {
00574
QTextStream tin(&in), tout(&out);
00575
QString line;
00576
while (!tin.atEnd())
00577 {
00578 line = tin.readLine();
00579 tout << line << endl;
00580 }
00581 in.close();
00582 out.close();
00583
00584 DrMain *driver = loadDriverFile(tmpFile);
00585
if (driver)
00586 {
00587 driver->set(
"template", tmpFile);
00588 driver->set(
"temporary", tmpFile);
00589
return driver;
00590 }
00591 }
00592 setErrorMsg(i18n(
"Unable to create the Foomatic driver [%1,%2]. "
00593
"Either that driver does not exist, or you don't have "
00594
"the required permissions to perform that operation.").arg(comps[1]).arg(comps[2]));
00595
QFile::remove(tmpFile);
00596
return NULL;
00597 }
00598
00599 DrMain* KMCupsManager::loadDriverFile(
const QString& fname)
00600 {
00601
if (
QFile::exists(fname))
00602 {
00603 DrMain *driver = PPDLoader::loadDriver( fname );
00604
if ( driver )
00605 {
00606 driver->set(
"template", fname );
00607
00608 }
00609
return driver;
00610 }
00611
return NULL;
00612 }
00613
00614
void KMCupsManager::saveDriverFile(DrMain *driver,
const QString& filename)
00615 {
00616 kdDebug( 500 ) <<
"Saving PPD file with template=" << driver->get(
"template" ) << endl;
00617
QIODevice *in = KFilterDev::deviceForFile( driver->get(
"template" ) );
00618
QFile out(filename);
00619
if (in && in->
open(IO_ReadOnly) && out.open(IO_WriteOnly))
00620 {
00621
QTextStream tin(in), tout(&out);
00622
QString line, keyword;
00623
bool isnumeric(
false);
00624 DrBase *opt(0);
00625
00626
while (!tin.eof())
00627 {
00628 line = tin.readLine();
00629
if (line.
startsWith(
"*% COMDATA #"))
00630 {
00631
int p(-1), q(-1);
00632
if ((p=line.
find(
"'name'")) != -1)
00633 {
00634 p = line.
find(
'\'',p+6)+1;
00635 q = line.
find(
'\'',p);
00636 keyword = line.
mid(p,q-p);
00637 opt = driver->findOption(keyword);
00638
if (opt && (opt->type() == DrBase::Integer || opt->type() == DrBase::Float))
00639 isnumeric =
true;
00640
else
00641 isnumeric =
false;
00642 }
00643
00644
00645
00646
00647
00648
00649
00650
00651
else if ((p=line.
find(
"'default'")) != -1 && !keyword.
isEmpty() && opt && isnumeric)
00652 {
00653
QString prefix = line.
left(p+9);
00654 tout << prefix <<
" => '" << opt->valueText() <<
'\'';
00655
if (line.
find(
',',p) != -1)
00656 tout <<
',';
00657 tout << endl;
00658
continue;
00659 }
00660 tout << line << endl;
00661 }
00662
else if (line.
startsWith(
"*Default"))
00663 {
00664
int p = line.
find(
':',8);
00665 keyword = line.
mid(8,p-8);
00666 DrBase *bopt = 0;
00667
if ( keyword ==
"PageRegion" || keyword ==
"ImageableArea" || keyword ==
"PaperDimension" )
00668 bopt = driver->findOption( QString::fromLatin1(
"PageSize" ) );
00669
else
00670 bopt = driver->findOption( keyword );
00671
if (bopt)
00672
switch (bopt->type())
00673 {
00674
case DrBase::List:
00675
case DrBase::Boolean:
00676 {
00677 DrListOption *opt = static_cast<DrListOption*>(bopt);
00678
if (opt && opt->currentChoice())
00679 tout <<
"*Default" << keyword <<
": " << opt->currentChoice()->name() << endl;
00680
else
00681 tout << line << endl;
00682 }
00683
break;
00684
case DrBase::Integer:
00685 {
00686 DrIntegerOption *opt = static_cast<DrIntegerOption*>(bopt);
00687 tout <<
"*Default" << keyword <<
": " << opt->fixedVal() << endl;
00688 }
00689
break;
00690
case DrBase::Float:
00691 {
00692 DrFloatOption *opt = static_cast<DrFloatOption*>(bopt);
00693 tout <<
"*Default" << keyword <<
": " << opt->fixedVal() << endl;
00694 }
00695
break;
00696
default:
00697 tout << line << endl;
00698
break;
00699 }
00700
else
00701 tout << line << endl;
00702 }
00703
else
00704 tout << line << endl;
00705 }
00706 }
00707
delete in;
00708 }
00709
00710
bool KMCupsManager::savePrinterDriver(KMPrinter *p, DrMain *d)
00711 {
00712
QString tmpfilename = locateLocal(
"tmp",
"print_") + kapp->randomString(8);
00713
00714
00715 saveDriverFile(d,tmpfilename);
00716
00717
00718 IppRequest req;
00719
QString uri;
00720
bool result(
false);
00721
00722 req.setOperation(CUPS_ADD_PRINTER);
00723 uri = printerURI(p,
true);
00724 req.addURI(IPP_TAG_OPERATION,
"printer-uri",uri);
00725 result = req.doFileRequest(
"/admin/",tmpfilename);
00726
00727
00728
QFile::remove(tmpfilename);
00729
00730
if (!result)
00731 reportIppError(&req);
00732
return result;
00733 }
00734
00735
void* KMCupsManager::loadCupsdConfFunction(
const char *name)
00736 {
00737
if (!m_cupsdconf)
00738 {
00739 m_cupsdconf = KLibLoader::self()->library(
"cupsdconf");
00740
if (!m_cupsdconf)
00741 {
00742 setErrorMsg(i18n(
"Library cupsdconf not found. Check your installation."));
00743
return NULL;
00744 }
00745 }
00746
void* func = m_cupsdconf->symbol(name);
00747
if (!func)
00748 setErrorMsg(i18n(
"Symbol %1 not found in cupsdconf library.").arg(name));
00749
return func;
00750 }
00751
00752
void KMCupsManager::unloadCupsdConf()
00753 {
00754
if (m_cupsdconf)
00755 {
00756 KLibLoader::self()->unloadLibrary(
"libcupsdconf");
00757 m_cupsdconf = 0;
00758 }
00759 }
00760
00761
bool KMCupsManager::restartServer()
00762 {
00763
QString msg;
00764 bool (*f1)(
QString&) = (bool(*)(
QString&))loadCupsdConfFunction(
"restartServer");
00765
bool result(
false);
00766
if (f1)
00767 {
00768 result = f1(msg);
00769
if (!result) setErrorMsg(msg);
00770 }
00771 unloadCupsdConf();
00772
return result;
00773 }
00774
00775
bool KMCupsManager::configureServer(
QWidget *parent)
00776 {
00777
QString msg;
00778 bool (*f2)(
QWidget*,
QString&) = (bool(*)(
QWidget*,
QString&))loadCupsdConfFunction(
"configureServer");
00779
bool result(
false);
00780
if (f2)
00781 {
00782 result = f2(parent, msg);
00783
if ( !result )
00784 setErrorMsg( msg );
00785 }
00786 unloadCupsdConf();
00787
return result;
00788 }
00789
00790
QStringList KMCupsManager::detectLocalPrinters()
00791 {
00792
QStringList list;
00793 IppRequest req;
00794 req.setOperation(CUPS_GET_DEVICES);
00795
if (req.doRequest(
"/"))
00796 {
00797
QString desc, uri, printer, cl;
00798 ipp_attribute_t *attr = req.first();
00799
while (attr)
00800 {
00801
QString attrname(attr->name);
00802
if (attrname ==
"device-info") desc = attr->values[0].string.text;
00803
else if (attrname ==
"device-make-and-model") printer = attr->values[0].string.text;
00804
else if (attrname ==
"device-uri") uri = attr->values[0].string.text;
00805
else if ( attrname ==
"device-class" ) cl = attr->values[ 0 ].string.text;
00806
if (attrname.isEmpty() || attr == req.last())
00807 {
00808
if (!uri.
isEmpty())
00809 {
00810
if (printer ==
"Unknown") printer = QString::null;
00811 list << cl << uri << desc << printer;
00812 }
00813 uri = desc = printer = cl = QString::null;
00814 }
00815 attr = attr->next;
00816 }
00817 }
00818
return list;
00819 }
00820
00821
void KMCupsManager::createPluginActions(KActionCollection *coll)
00822 {
00823 KAction *act =
new KAction(i18n(
"&Export Driver..."),
"kdeprint_uploadsmb", 0,
this, SLOT(exportDriver()), coll,
"plugin_export_driver");
00824 act->setGroup(
"plugin");
00825 act =
new KAction(i18n(
"&Printer IPP Report..."),
"kdeprint_report", 0,
this, SLOT(printerIppReport()), coll,
"plugin_printer_ipp_report");
00826 act->setGroup(
"plugin");
00827 }
00828
00829
void KMCupsManager::validatePluginActions(KActionCollection *coll, KMPrinter *pr)
00830 {
00831
00832 m_currentprinter = pr;
00833 coll->action(
"plugin_export_driver")->setEnabled(pr && pr->isLocal() && !pr->isClass(
true) && !pr->isSpecial());
00834 coll->action(
"plugin_printer_ipp_report")->setEnabled(pr && !pr->isSpecial());
00835 }
00836
00837
void KMCupsManager::exportDriver()
00838 {
00839
if (m_currentprinter && m_currentprinter->isLocal() &&
00840 !m_currentprinter->isClass(
true) && !m_currentprinter->isSpecial())
00841 {
00842
QString path = cupsInstallDir();
00843
if (path.
isEmpty())
00844 path =
"/usr/share/cups";
00845
else
00846 path +=
"/share/cups";
00847 CupsAddSmb::exportDest(m_currentprinter->printerName(), path);
00848 }
00849 }
00850
00851
void KMCupsManager::printerIppReport()
00852 {
00853
if (m_currentprinter && !m_currentprinter->isSpecial())
00854 {
00855 IppRequest req;
00856
QString uri;
00857
00858 req.setOperation(IPP_GET_PRINTER_ATTRIBUTES);
00859 uri = printerURI(m_currentprinter,
true);
00860 req.addURI(IPP_TAG_OPERATION,
"printer-uri",uri);
00861
00862
00863
00864
00865
00866
00867
00868 req.dump(2);
00869
if (req.doRequest(
"/printers/"))
00870 {
00871 ippReport(req, IPP_TAG_PRINTER, i18n(
"IPP report for %1").arg(m_currentprinter->printerName()));
00872 }
00873
else
00874 {
00875 KMessageBox::error(0,
"<p>"+i18n(
"Unable to retrieve printer information. Error received:")+
"</p>"+req.statusMessage());
00876 }
00877 }
00878 }
00879
00880
void KMCupsManager::ippReport(IppRequest& req,
int group,
const QString& caption)
00881 {
00882 IppReportDlg::report(&req, group, caption);
00883 }
00884
00885
QString KMCupsManager::stateInformation()
00886 {
00887
return i18n(
"Connected to %1:%2").arg(CupsInfos::self()->host()).arg(CupsInfos::self()->port());
00888 }
00889
00890
void KMCupsManager::checkUpdatePossibleInternal()
00891 {
00892 kdDebug(500) <<
"Checking for update possible" << endl;
00893
delete m_socket;
00894
00895
00896
00897
00898 m_socket =
new QSocket(
this );
00899 connect( m_socket, SIGNAL( connected() ), SLOT( slotConnectionSuccess() ) );
00900 connect( m_socket, SIGNAL( error(
int ) ), SLOT( slotConnectionFailed(
int ) ) );
00901 trials = 5;
00902
QTimer::singleShot( 1,
this, SLOT( slotAsyncConnect() ) );
00903 }
00904
00905
void KMCupsManager::slotConnectionSuccess()
00906 {
00907 kdDebug(500) <<
"Connection success, trying to send a request..." << endl;
00908 m_socket->close();
00909
00910 IppRequest req;
00911 req.setOperation( CUPS_GET_PRINTERS );
00912 req.addKeyword( IPP_TAG_OPERATION,
"requested-attributes", QString::fromLatin1(
"printer-name" ) );
00913
if ( req.doRequest(
"/printers/" ) )
00914 setUpdatePossible(
true );
00915
else
00916 {
00917 kdDebug(500) <<
"Unable to get printer list" << endl;
00918
if ( trials > 0 )
00919 {
00920 trials--;
00921
QTimer::singleShot( 1000,
this, SLOT( slotAsyncConnect() ) );
00922 }
00923
else
00924 {
00925 setErrorMsg( i18n(
"Connection to CUPS server failed. Check that the CUPS server is correctly installed and running. "
00926
"Error: %1." ).arg( i18n(
"the IPP request failed for an unknown reason" ) ) );
00927 setUpdatePossible(
false );
00928 }
00929 }
00930 }
00931
00932
void KMCupsManager::slotAsyncConnect()
00933 {
00934 kdDebug(500) <<
"Starting async connect" << endl;
00935
00936 m_socket->connectToHost( CupsInfos::self()->host(), CupsInfos::self()->port() );
00937 }
00938
00939
void KMCupsManager::slotConnectionFailed(
int errcode )
00940 {
00941 kdDebug(500) <<
"Connection failed trials=" << trials << endl;
00942
if ( trials > 0 )
00943 {
00944
00945
00946 trials--;
00947 m_socket->close();
00948
QTimer::singleShot( 1000,
this, SLOT( slotAsyncConnect() ) );
00949
return;
00950 }
00951
00952 setErrorMsg( i18n(
"Connection to CUPS server failed. Check that the CUPS server is correctly installed and running. "
00953
"Error: %1." ).arg( errcode == QSocket::ErrConnectionRefused ? i18n(
"connection refused" ) : i18n(
"host not found" ) ) );
00954 setUpdatePossible(
false );
00955 }
00956
00957
void KMCupsManager::hostPingSlot() {
00958 m_hostSuccess =
true;
00959 m_lookupDone =
true;
00960 }
00961
00962
void KMCupsManager::hostPingFailedSlot() {
00963 m_hostSuccess =
false;
00964 m_lookupDone =
true;
00965 }
00966
00967
00968
00969
void extractMaticData(
QString& buf,
const QString& filename)
00970 {
00971
QFile f(filename);
00972
if (f.exists() && f.open(IO_ReadOnly))
00973 {
00974
QTextStream t(&f);
00975
QString line;
00976
while (!t.eof())
00977 {
00978 line = t.readLine();
00979
if (line.
startsWith(
"*% COMDATA #"))
00980 buf.
append(line.
right(line.
length()-12)).append(
'\n');
00981 }
00982 }
00983 }
00984
00985
QString printerURI(KMPrinter *p,
bool use)
00986 {
00987
QString uri;
00988
if (use && !p->uri().isEmpty())
00989 uri = p->uri().prettyURL();
00990
else
00991 uri =
QString(
"ipp://%1:%2/%4/%3").
arg(CupsInfos::self()->host()).arg(CupsInfos::self()->port()).arg(p->printerName()).arg((p->isClass(
false) ?
"classes" :
"printers"));
00992
return uri;
00993 }
00994
00995
QString downloadDriver(KMPrinter *p)
00996 {
00997
QString driverfile, prname = p->printerName();
00998
bool changed(
false);
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017 driverfile = cupsGetPPD(prname.
local8Bit());
01018
01019
01020
if (changed)
01021 {
01022 cupsSetServer(CupsInfos::self()->host().local8Bit());
01023 ippSetPort(CupsInfos::self()->port());
01024 }
01025
01026
return driverfile;
01027 }
01028
01029
#include "kmcupsmanager.moc"