00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
#include "kmlprmanager.h"
00021
#include "printcapreader.h"
00022
#include "printcapentry.h"
00023
#include "lpchelper.h"
00024
#include "matichandler.h"
00025
#include "apshandler.h"
00026
#include "lprngtoolhandler.h"
00027
#include "lprsettings.h"
00028
#include "driver.h"
00029
#include "editentrydialog.h"
00030
00031
#include <qfileinfo.h>
00032
#include <qptrlist.h>
00033
#include <klocale.h>
00034
#include <kstandarddirs.h>
00035
#include <kdebug.h>
00036
#include <kprinter.h>
00037
#include <kprocess.h>
00038
#include <kaction.h>
00039
#include <kmessagebox.h>
00040
#include <klibloader.h>
00041
00042
#include <stdlib.h>
00043
#include <unistd.h>
00044
00045 KMLprManager::KMLprManager(
QObject *parent,
const char *name,
const QStringList & )
00046 : KMManager(parent,name)
00047 {
00048 m_handlers.setAutoDelete(
true);
00049 m_handlerlist.setAutoDelete(
false);
00050 m_entries.setAutoDelete(
true);
00051
00052 m_lpchelper =
new LpcHelper(
this);
00053 m_currentprinter = 0;
00054
00055 setHasManagement(getuid() == 0);
00056 setPrinterOperationMask(
00057 KMManager::PrinterEnabling |
00058 KMManager::PrinterConfigure |
00059 KMManager::PrinterTesting |
00060 KMManager::PrinterCreation |
00061 KMManager::PrinterRemoval |
00062 KMManager::PrinterTesting
00063 );
00064
00065 initHandlers();
00066 }
00067
00068
void KMLprManager::listPrinters()
00069 {
00070
QFileInfo fi(LprSettings::self()->printcapFile());
00071
00072
if (m_lpchelper)
00073 m_lpchelper->updateStates();
00074
00075
00076
if (!m_updtime.isValid() || m_updtime < fi.lastModified())
00077 {
00078
00079 m_entries.clear();
00080
00081
QPtrListIterator<LprHandler> hit(m_handlerlist);
00082
for (; hit.current(); ++hit)
00083 hit.current()->reset();
00084
00085
00086 PrintcapReader reader;
00087
QFile f(fi.absFilePath());
00088 PrintcapEntry *entry;
00089
if (f.exists() && f.open(IO_ReadOnly))
00090 {
00091 reader.setPrintcapFile(&f);
00092
while ((entry = reader.nextEntry()) != NULL)
00093 {
00094
QPtrListIterator<LprHandler> it(m_handlerlist);
00095
for (; it.current(); ++it)
00096
if (it.current()->validate(entry))
00097 {
00098 KMPrinter *prt = it.current()->createPrinter(entry);
00099 checkPrinterState(prt);
00100 prt->setOption(
"kde-lpr-handler", it.current()->name());
00101 addPrinter(prt);
00102
break;
00103 }
00104 m_entries.insert(entry->name, entry);
00105 }
00106 }
00107
00108
00109 m_updtime = fi.lastModified();
00110 }
00111
else
00112 {
00113
QPtrListIterator<KMPrinter> it(m_printers);
00114
for (; it.current(); ++it)
00115
if (!it.current()->isSpecial())
00116 {
00117 it.current()->setDiscarded(
false);
00118 checkPrinterState(it.current());
00119 }
00120 }
00121 }
00122
00123
void KMLprManager::insertHandler(LprHandler *handler)
00124 {
00125 m_handlers.insert(handler->name(), handler);
00126 m_handlerlist.append(handler);
00127 kdDebug() <<
"Handler: " << handler->name() << endl;
00128 }
00129
00130
void KMLprManager::initHandlers()
00131 {
00132 m_handlers.clear();
00133 m_handlerlist.clear();
00134
00135 insertHandler(
new MaticHandler(
this));
00136 insertHandler(
new ApsHandler(
this));
00137 insertHandler(
new LPRngToolHandler(
this));
00138
00139
00140
QStringList l = KGlobal::dirs()->findAllResources(
"data",
"kdeprint/lpr/*.la");
00141
for (QStringList::ConstIterator it=l.begin(); it!=l.end(); ++it)
00142 {
00143 KLibrary *library = KLibLoader::self()->library(QFile::encodeName(*it));
00144
if (library)
00145 {
00146 kdDebug() <<
"loading external handler from " << *it << endl;
00147 LprHandler*(*func)(KMManager*) = (LprHandler*(*)(KMManager*))(library->symbol(
"create_handler"));
00148
if (func)
00149 insertHandler(func(
this));
00150
else
00151 kdDebug() <<
"couldn't find the symbol 'create_handler'" << endl;
00152 }
00153 }
00154
00155
00156 insertHandler(
new LprHandler(
"default",
this));
00157 }
00158
00159 LprHandler* KMLprManager::findHandler(KMPrinter *prt)
00160 {
00161
QString handlerstr(prt->option(
"kde-lpr-handler"));
00162 LprHandler *handler(0);
00163
if (handlerstr.isEmpty() || (handler = m_handlers.find(handlerstr)) == NULL)
00164 {
00165
return NULL;
00166 }
00167
return handler;
00168 }
00169
00170 PrintcapEntry* KMLprManager::findEntry(KMPrinter *prt)
00171 {
00172 PrintcapEntry *entry = m_entries.find(prt->printerName());
00173
if (!entry)
00174 {
00175
return NULL;
00176 }
00177
return entry;
00178 }
00179
00180
bool KMLprManager::completePrinter(KMPrinter *prt)
00181 {
00182 LprHandler *handler = findHandler(prt);
00183 PrintcapEntry *entry = findEntry(prt);
00184
if (handler && entry)
00185
return handler->completePrinter(prt, entry,
false);
00186
return false;
00187 }
00188
00189
bool KMLprManager::completePrinterShort(KMPrinter *prt)
00190 {
00191 LprHandler *handler = findHandler(prt);
00192 PrintcapEntry *entry = findEntry(prt);
00193
if (!handler || !entry)
00194
return false;
00195
00196
return handler->completePrinter(prt, entry,
true);
00197 }
00198
00199
void KMLprManager::checkPrinterState(KMPrinter *prt)
00200 {
00201
if (m_lpchelper)
00202 {
00203 KMPrinter::PrinterState st = m_lpchelper->state(prt);
00204 prt->setState(st);
00205 prt->setAcceptJobs(!(st & KMPrinter::Rejecting));
00206 }
00207
else
00208 {
00209 prt->setState(KMPrinter::Idle);
00210 prt->setAcceptJobs(
true);
00211 }
00212 }
00213
00214 DrMain* KMLprManager::loadPrinterDriver(KMPrinter *prt,
bool config)
00215 {
00216
if (!prt)
00217
return NULL;
00218
00219 LprHandler *handler = findHandler(prt);
00220 PrintcapEntry *entry = findEntry(prt);
00221
if (handler && entry)
00222 {
00223 DrMain *driver = handler->loadDriver(prt, entry, config);
00224
if (driver)
00225 driver->set(
"handler", handler->name());
00226
return driver;
00227 }
00228
return NULL;
00229 }
00230
00231 DrMain* KMLprManager::loadFileDriver(
const QString& filename)
00232 {
00233
int p = filename.find(
'/');
00234
QString handler_str = (p != -1 ? filename.left(p) :
QString::fromLatin1("default"));
00235 LprHandler *handler = m_handlers.find(handler_str);
00236
if (handler)
00237 {
00238 DrMain *driver = handler->loadDbDriver(filename);
00239
if (driver)
00240 driver->set(
"handler", handler->name());
00241
return driver;
00242 }
00243
return NULL;
00244 }
00245
00246
bool KMLprManager::enablePrinter(KMPrinter *prt,
bool state)
00247 {
00248
QString msg;
00249
if (!m_lpchelper->enable(prt, state, msg))
00250 {
00251 setErrorMsg(msg);
00252
return false;
00253 }
00254
return true;
00255 }
00256
00257
bool KMLprManager::startPrinter(KMPrinter *prt,
bool state)
00258 {
00259
QString msg;
00260
if (!m_lpchelper->start(prt, state, msg))
00261 {
00262 setErrorMsg(msg);
00263
return false;
00264 }
00265
return true;
00266 }
00267
00268
bool KMLprManager::savePrinterDriver(KMPrinter *prt, DrMain *driver)
00269 {
00270 LprHandler *handler = findHandler(prt);
00271 PrintcapEntry *entry = findEntry(prt);
00272
if (handler && entry)
00273 {
00274
bool mustSave(
false);
00275
if (handler->savePrinterDriver(prt, entry, driver, &mustSave))
00276 {
00277
if (mustSave)
00278
return savePrintcapFile();
00279
return true;
00280 }
00281 }
00282
return false;
00283 }
00284
00285
bool KMLprManager::savePrintcapFile()
00286 {
00287
if (!LprSettings::self()->isLocalPrintcap())
00288 {
00289 setErrorMsg(i18n(
"The printcap file is a remote file (NIS). It cannot be written."));
00290
return false;
00291 }
00292
QFile f(LprSettings::self()->printcapFile());
00293
if (f.open(IO_WriteOnly))
00294 {
00295
QTextStream t(&f);
00296
QDictIterator<PrintcapEntry> it(m_entries);
00297
for (; it.current(); ++it)
00298 {
00299 it.current()->writeEntry(t);
00300 }
00301
return true;
00302 }
00303
else
00304 {
00305 setErrorMsg(i18n(
"Unable to save printcap file. Check that "
00306
"you have write permissions for that file."));
00307
return false;
00308 }
00309 }
00310
00311
bool KMLprManager::createPrinter(KMPrinter *prt)
00312 {
00313
00314 PrintcapEntry *oldEntry = m_entries.find(prt->printerName());
00315
00316
00317 LprHandler *handler(0);
00318
00319
00320
00321
00322
if (prt->driver())
00323 handler = m_handlers.find(prt->driver()->get(
"handler"));
00324
else if (oldEntry)
00325 handler = findHandler(prt);
00326
else
00327 handler = m_handlers.find(
"default");
00328
if (!handler)
00329 {
00330 setErrorMsg(i18n(
"Internal error: no handler defined."));
00331
return false;
00332 }
00333 prt->setOption(
"kde-lpr-handler", handler->name());
00334
00335
00336
00337
00338
if (!prt->driver() && oldEntry)
00339 prt->setDriver(handler->loadDriver(prt, oldEntry,
true));
00340
00341
QString sd = LprSettings::self()->baseSpoolDir();
00342
if (sd.isEmpty())
00343 {
00344 setErrorMsg(i18n(
"Couldn't determine spool directory. See options dialog."));
00345
return false;
00346 }
00347 sd.append(
"/").append(prt->printerName());
00348
if (!KStandardDirs::makeDir(sd, 0755))
00349 {
00350 setErrorMsg(i18n(
"Unable to create the spool directory %1. Check that you "
00351
"have the required permissions for that operation.").arg(sd));
00352
return false;
00353 }
00354 PrintcapEntry *entry = handler->createEntry(prt);
00355
if (!entry)
00356
return false;
00357
00358 m_entries.remove(prt->printerName());
00359 entry->name = prt->printerName();
00360 entry->addField(
"sh", Field::Boolean);
00361 entry->addField(
"mx", Field::Integer,
"0");
00362 entry->addField(
"sd", Field::String, sd);
00363
if (!prt->option(
"kde-aliases").isEmpty())
00364 entry->aliases += QStringList::split(
"|", prt->option(
"kde-aliases"),
false);
00365
00366
00367 m_entries.insert(prt->printerName(), entry);
00368
bool result = savePrintcapFile();
00369
if (result)
00370 {
00371
if (prt->driver())
00372 {
00373 result = handler->savePrinterDriver(prt, entry, prt->driver());
00374 }
00375
00376
00377
if (LprSettings::self()->mode() == LprSettings::LPRng)
00378 {
00379
QString msg;
00380
if (!m_lpchelper->restart(msg))
00381 {
00382 setErrorMsg(i18n(
"The printer has been created but the print daemon "
00383
"could not be restarted. %1").arg(msg));
00384
return false;
00385 }
00386 }
00387 }
00388
return result;
00389 }
00390
00391
bool KMLprManager::removePrinter(KMPrinter *prt)
00392 {
00393 LprHandler *handler = findHandler(prt);
00394 PrintcapEntry *entry = findEntry(prt);
00395
if (handler && entry)
00396 {
00397
if (handler->removePrinter(prt, entry))
00398 {
00399
QString sd = entry->field(
"sd");
00400
00401
00402 m_entries.take(prt->printerName());
00403
bool status = savePrintcapFile();
00404
if (status)
00405 {
00406
00407
delete entry;
00408 status = (::system(QFile::encodeName(
"rm -rf " + KProcess::quote(sd))) == 0);
00409
if (!status)
00410 setErrorMsg(i18n(
"Unable to remove spool directory %1. "
00411
"Check that you have write permissions "
00412
"for that directory.").arg(sd));
00413
return status;
00414 }
00415
else
00416
00417 m_entries.insert(prt->printerName(), entry);
00418 }
00419 }
00420
return false;
00421 }
00422
00423
QString KMLprManager::driverDbCreationProgram()
00424 {
00425
return QString::fromLatin1(
"make_driver_db_lpr");
00426 }
00427
00428
QString KMLprManager::driverDirectory()
00429 {
00430
QPtrListIterator<LprHandler> it(m_handlerlist);
00431
QString dbDirs;
00432
for (; it.current(); ++it)
00433 {
00434
QString dir = it.current()->driverDirectory();
00435
if (!dir.isEmpty())
00436 dbDirs.append(dir).append(
":");
00437 }
00438
if (!dbDirs.isEmpty())
00439 dbDirs.truncate(dbDirs.length()-1);
00440
return dbDirs;
00441 }
00442
00443
QString KMLprManager::printOptions(
KPrinter *prt)
00444 {
00445 KMPrinter *mprt = findPrinter(prt->
printerName());
00446
QString opts;
00447
if (mprt)
00448 {
00449 LprHandler *handler = findHandler(mprt);
00450
if (handler)
00451
return handler->printOptions(prt);
00452 }
00453
return QString::null;
00454 }
00455
00456
void KMLprManager::createPluginActions(KActionCollection *coll)
00457 {
00458 KAction *act =
new KAction(i18n(
"&Edit printcap Entry..."),
"kdeprint_report", 0,
this, SLOT(slotEditPrintcap()), coll,
"plugin_editprintcap");
00459 act->setGroup(
"plugin");
00460 }
00461
00462
void KMLprManager::validatePluginActions(KActionCollection *coll, KMPrinter *prt)
00463 {
00464 m_currentprinter = prt;
00465
00466 coll->action(
"plugin_editprintcap")->setEnabled(0 && hasManagement() && prt && !prt->isSpecial());
00467 }
00468
00469
void KMLprManager::slotEditPrintcap()
00470 {
00471
if (!m_currentprinter ||
00472 KMessageBox::warningYesNo(NULL,
00473 i18n(
"Editing a printcap entry manually should only be "
00474
"done by confirmed system administrator. This may "
00475
"prevent your printer from working. Do you want to "
00476
"continue?"), QString::null, QString::null, QString::null,
00477
"editPrintcap") == KMessageBox::No)
00478
return;
00479
00480 PrintcapEntry *entry = findEntry(m_currentprinter);
00481 EditEntryDialog dlg(entry, NULL);
00482
if (dlg.exec())
00483 {
00484 }
00485 }
00486
00487
QString KMLprManager::stateInformation()
00488 {
00489
return i18n(
"Spooler type: %1").arg(LprSettings::self()->mode() == LprSettings::LPR ?
"LPR (BSD compatible)" :
"LPRng");
00490 }
00491
00492
#include "kmlprmanager.moc"