• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdeprint
 

tdeprint

  • tdeprint
  • lpr
kmlprmanager.cpp
1 /*
2  * This file is part of the KDE libraries
3  * Copyright (c) 2001 Michael Goffioul <tdeprint@swing.be>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License version 2 as published by the Free Software Foundation.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this library; see the file COPYING.LIB. If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  **/
19 
20 #include "kmlprmanager.h"
21 #include "printcapreader.h"
22 #include "printcapentry.h"
23 #include "lpchelper.h"
24 #include "matichandler.h"
25 #include "apshandler.h"
26 #include "lprngtoolhandler.h"
27 #include "lprsettings.h"
28 #include "driver.h"
29 #include "editentrydialog.h"
30 
31 #include <tqfileinfo.h>
32 #include <tqptrlist.h>
33 #include <tdelocale.h>
34 #include <kstandarddirs.h>
35 #include <kdebug.h>
36 #include <kprinter.h>
37 #include <kprocess.h>
38 #include <tdeaction.h>
39 #include <tdemessagebox.h>
40 #include <klibloader.h>
41 
42 #include <stdlib.h>
43 #include <unistd.h>
44 
45 KMLprManager::KMLprManager(TQObject *parent, const char *name, const TQStringList & /*args*/)
46 : KMManager(parent,name)
47 {
48  m_handlers.setAutoDelete(true);
49  m_handlerlist.setAutoDelete(false);
50  m_entries.setAutoDelete(true);
51 
52  m_lpchelper = new LpcHelper(this);
53  m_currentprinter = 0;
54 
55  setHasManagement(getuid() == 0);
56  setPrinterOperationMask(
57  KMManager::PrinterEnabling |
58  KMManager::PrinterConfigure |
59  KMManager::PrinterTesting |
60  KMManager::PrinterCreation |
61  KMManager::PrinterRemoval |
62  KMManager::PrinterTesting
63  );
64 
65  initHandlers();
66 }
67 
68 void KMLprManager::listPrinters()
69 {
70  TQFileInfo fi(LprSettings::self()->printcapFile());
71 
72  if (m_lpchelper)
73  m_lpchelper->updateStates();
74 
75  // update only if needed
76  if (!m_updtime.isValid() || m_updtime < fi.lastModified())
77  {
78  // cleanup previous entries
79  m_entries.clear();
80  // notify handlers
81  TQPtrListIterator<LprHandler> hit(m_handlerlist);
82  for (; hit.current(); ++hit)
83  hit.current()->reset();
84 
85  // try to open the printcap file and parse it
86  PrintcapReader reader;
87  TQFile f(fi.absFilePath());
88  PrintcapEntry *entry;
89  if (f.exists() && f.open(IO_ReadOnly))
90  {
91  reader.setPrintcapFile(&f);
92  while ((entry = reader.nextEntry()) != NULL)
93  {
94  TQPtrListIterator<LprHandler> it(m_handlerlist);
95  for (; it.current(); ++it)
96  if (it.current()->validate(entry))
97  {
98  KMPrinter *prt = it.current()->createPrinter(entry);
99  checkPrinterState(prt);
100  prt->setOption("kde-lpr-handler", it.current()->name());
101  addPrinter(prt);
102  break;
103  }
104  m_entries.insert(entry->name, entry);
105  }
106  }
107 
108  // save update time
109  m_updtime = fi.lastModified();
110  }
111  else
112  {
113  TQPtrListIterator<KMPrinter> it(m_printers);
114  for (; it.current(); ++it)
115  if (!it.current()->isSpecial())
116  {
117  it.current()->setDiscarded(false);
118  checkPrinterState(it.current());
119  }
120  }
121 }
122 
123 void KMLprManager::insertHandler(LprHandler *handler)
124 {
125  m_handlers.insert(handler->name(), handler);
126  m_handlerlist.append(handler);
127  kdDebug() << "Handler: " << handler->name() << endl;
128 }
129 
130 void KMLprManager::initHandlers()
131 {
132  m_handlers.clear();
133  m_handlerlist.clear();
134 
135  insertHandler(new MaticHandler(this));
136  insertHandler(new ApsHandler(this));
137  insertHandler(new LPRngToolHandler(this));
138 
139  // now load external handlers
140  TQStringList l = TDEGlobal::dirs()->findAllResources("data", "tdeprint/lpr/*.la");
141  for (TQStringList::ConstIterator it=l.begin(); it!=l.end(); ++it)
142  {
143  KLibrary *library = KLibLoader::self()->library(TQFile::encodeName(*it));
144  if (library)
145  {
146  kdDebug() << "loading external handler from " << *it << endl;
147  LprHandler*(*func)(KMManager*) = (LprHandler*(*)(KMManager*))(library->symbol("create_handler"));
148  if (func)
149  insertHandler(func(this));
150  else
151  kdDebug() << "couldn't find the symbol 'create_handler'" << endl;
152  }
153  }
154 
155  // default handler
156  insertHandler(new LprHandler("default", this));
157 }
158 
159 LprHandler* KMLprManager::findHandler(KMPrinter *prt)
160 {
161  TQString handlerstr(prt->option("kde-lpr-handler"));
162  LprHandler *handler(0);
163  if (handlerstr.isEmpty() || (handler = m_handlers.find(handlerstr)) == NULL)
164  {
165  return NULL;
166  }
167  return handler;
168 }
169 
170 PrintcapEntry* KMLprManager::findEntry(KMPrinter *prt)
171 {
172  PrintcapEntry *entry = m_entries.find(prt->printerName());
173  if (!entry)
174  {
175  return NULL;
176  }
177  return entry;
178 }
179 
180 bool KMLprManager::completePrinter(KMPrinter *prt)
181 {
182  LprHandler *handler = findHandler(prt);
183  PrintcapEntry *entry = findEntry(prt);
184  if (handler && entry)
185  return handler->completePrinter(prt, entry, false);
186  return false;
187 }
188 
189 bool KMLprManager::completePrinterShort(KMPrinter *prt)
190 {
191  LprHandler *handler = findHandler(prt);
192  PrintcapEntry *entry = findEntry(prt);
193  if (!handler || !entry)
194  return false;
195 
196  return handler->completePrinter(prt, entry, true);
197 }
198 
199 void KMLprManager::checkPrinterState(KMPrinter *prt)
200 {
201  if (m_lpchelper)
202  {
203  KMPrinter::PrinterState st = m_lpchelper->state(prt);
204  prt->setState(st);
205  prt->setAcceptJobs(!(st & KMPrinter::Rejecting));
206  }
207  else
208  {
209  prt->setState(KMPrinter::Idle);
210  prt->setAcceptJobs(true);
211  }
212 }
213 
214 DrMain* KMLprManager::loadPrinterDriver(KMPrinter *prt, bool config)
215 {
216  if (!prt)
217  return NULL;
218 
219  LprHandler *handler = findHandler(prt);
220  PrintcapEntry *entry = findEntry(prt);
221  if (handler && entry)
222  {
223  DrMain *driver = handler->loadDriver(prt, entry, config);
224  if (driver)
225  driver->set("handler", handler->name());
226  return driver;
227  }
228  return NULL;
229 }
230 
231 DrMain* KMLprManager::loadFileDriver(const TQString& filename)
232 {
233  int p = filename.find('/');
234  TQString handler_str = (p != -1 ? filename.left(p) : TQString::fromLatin1("default"));
235  LprHandler *handler = m_handlers.find(handler_str);
236  if (handler)
237  {
238  DrMain *driver = handler->loadDbDriver(filename);
239  if (driver)
240  driver->set("handler", handler->name());
241  return driver;
242  }
243  return NULL;
244 }
245 
246 bool KMLprManager::enablePrinter(KMPrinter *prt, bool state)
247 {
248  TQString msg;
249  if (!m_lpchelper->enable(prt, state, msg))
250  {
251  setErrorMsg(msg);
252  return false;
253  }
254  return true;
255 }
256 
257 bool KMLprManager::startPrinter(KMPrinter *prt, bool state)
258 {
259  TQString msg;
260  if (!m_lpchelper->start(prt, state, msg))
261  {
262  setErrorMsg(msg);
263  return false;
264  }
265  return true;
266 }
267 
268 bool KMLprManager::savePrinterDriver(KMPrinter *prt, DrMain *driver)
269 {
270  LprHandler *handler = findHandler(prt);
271  PrintcapEntry *entry = findEntry(prt);
272  if (handler && entry)
273  {
274  bool mustSave(false);
275  if (handler->savePrinterDriver(prt, entry, driver, &mustSave))
276  {
277  if (mustSave)
278  return savePrintcapFile();
279  return true;
280  }
281  }
282  return false;
283 }
284 
285 bool KMLprManager::savePrintcapFile()
286 {
287  if (!LprSettings::self()->isLocalPrintcap())
288  {
289  setErrorMsg(i18n("The printcap file is a remote file (NIS). It cannot be written."));
290  return false;
291  }
292  TQFile f(LprSettings::self()->printcapFile());
293  if (f.open(IO_WriteOnly))
294  {
295  TQTextStream t(&f);
296  TQDictIterator<PrintcapEntry> it(m_entries);
297  for (; it.current(); ++it)
298  {
299  it.current()->writeEntry(t);
300  }
301  return true;
302  }
303  else
304  {
305  setErrorMsg(i18n("Unable to save printcap file. Check that "
306  "you have write permissions for that file."));
307  return false;
308  }
309 }
310 
311 bool KMLprManager::createPrinter(KMPrinter *prt)
312 {
313  // remove existing printcap entry
314  PrintcapEntry *oldEntry = m_entries.find(prt->printerName());
315 
316  // look for the handler and re-create entry
317  LprHandler *handler(0);
318  // To look for the handler, either we base ourselves
319  // on the driver (1: new printer, 2: modifying driver)
320  // or we use the handler of the existing printer
321  // (modifying something else, handler stays the same)
322  if (prt->driver())
323  handler = m_handlers.find(prt->driver()->get("handler"));
324  else if (oldEntry)
325  handler = findHandler(prt);
326  else
327  handler = m_handlers.find("default");
328  if (!handler)
329  {
330  setErrorMsg(i18n("Internal error: no handler defined."));
331  return false;
332  }
333  prt->setOption("kde-lpr-handler", handler->name());
334 
335  // we reload the driver if the printer object doesn't have one
336  // and there's an old entry (sometimes needed to keep the backend
337  // like in Foomatic)
338  if (!prt->driver() && oldEntry)
339  prt->setDriver(handler->loadDriver(prt, oldEntry, true));
340 
341  TQString sd = LprSettings::self()->baseSpoolDir();
342  if (sd.isEmpty())
343  {
344  setErrorMsg(i18n("Couldn't determine spool directory. See options dialog."));
345  return false;
346  }
347  sd.append("/").append(prt->printerName());
348  if (!TDEStandardDirs::makeDir(sd, 0755))
349  {
350  setErrorMsg(i18n("Unable to create the spool directory %1. Check that you "
351  "have the required permissions for that operation.").arg(sd));
352  return false;
353  }
354  PrintcapEntry *entry = handler->createEntry(prt);
355  if (!entry)
356  return false; // error should be set in the handler
357  // old entry can be removed now
358  m_entries.remove(prt->printerName());
359  entry->name = prt->printerName();
360  entry->addField("sh", Field::Boolean);
361  entry->addField("mx", Field::Integer, "0");
362  entry->addField("sd", Field::String, sd);
363  if (!prt->option("kde-aliases").isEmpty())
364  entry->aliases += TQStringList::split("|", prt->option("kde-aliases"), false);
365 
366  // insert the new entry and save printcap file
367  m_entries.insert(prt->printerName(), entry);
368  bool result = savePrintcapFile();
369  if (result)
370  {
371  if (prt->driver())
372  {
373  result = handler->savePrinterDriver(prt, entry, prt->driver());
374  }
375 
376  // in case of LPRng, we need to tell the daemon about new printer
377  if (LprSettings::self()->mode() == LprSettings::LPRng)
378  {
379  TQString msg;
380  if (!m_lpchelper->restart(msg))
381  {
382  setErrorMsg(i18n("The printer has been created but the print daemon "
383  "could not be restarted. %1").arg(msg));
384  return false;
385  }
386  }
387  }
388  return result;
389 }
390 
391 bool KMLprManager::removePrinter(KMPrinter *prt)
392 {
393  LprHandler *handler = findHandler(prt);
394  PrintcapEntry *entry = findEntry(prt);
395  if (handler && entry)
396  {
397  if (handler->removePrinter(prt, entry))
398  {
399  TQString sd = entry->field("sd");
400  // first try to save the printcap file, and if
401  // successful, remove the spool directory
402  m_entries.take(prt->printerName());
403  bool status = savePrintcapFile();
404  if (status)
405  {
406  // printcap file saved, entry can be deleted now
407  delete entry;
408  status = (::system(TQFile::encodeName("rm -rf " + TDEProcess::quote(sd))) == 0);
409  if (!status)
410  setErrorMsg(i18n("Unable to remove spool directory %1. "
411  "Check that you have write permissions "
412  "for that directory.").arg(sd));
413  return status;
414  }
415  else
416  // push back the non-removed entry
417  m_entries.insert(prt->printerName(), entry);
418  }
419  }
420  return false;
421 }
422 
423 TQString KMLprManager::driverDbCreationProgram()
424 {
425  return TQString::fromLatin1("make_driver_db_lpr");
426 }
427 
428 TQString KMLprManager::driverDirectory()
429 {
430  TQPtrListIterator<LprHandler> it(m_handlerlist);
431  TQString dbDirs;
432  for (; it.current(); ++it)
433  {
434  TQString dir = it.current()->driverDirectory();
435  if (!dir.isEmpty())
436  dbDirs.append(dir).append(":");
437  }
438  if (!dbDirs.isEmpty())
439  dbDirs.truncate(dbDirs.length()-1);
440  return dbDirs;
441 }
442 
443 TQString KMLprManager::printOptions(KPrinter *prt)
444 {
445  KMPrinter *mprt = findPrinter(prt->printerName());
446  TQString opts;
447  if (mprt)
448  {
449  LprHandler *handler = findHandler(mprt);
450  if (handler)
451  return handler->printOptions(prt);
452  }
453  return TQString::null;
454 }
455 
456 void KMLprManager::createPluginActions(TDEActionCollection *coll)
457 {
458  TDEAction *act = new TDEAction(i18n("&Edit printcap Entry..."), "tdeprint_report", 0, this, TQT_SLOT(slotEditPrintcap()), coll, "plugin_editprintcap");
459  act->setGroup("plugin");
460 }
461 
462 void KMLprManager::validatePluginActions(TDEActionCollection *coll, KMPrinter *prt)
463 {
464  m_currentprinter = prt;
465  // FIXME: disabled until completion
466  coll->action("plugin_editprintcap")->setEnabled(0 && hasManagement() && prt && !prt->isSpecial());
467 }
468 
469 void KMLprManager::slotEditPrintcap()
470 {
471  if (!m_currentprinter ||
472  KMessageBox::warningContinueCancel(NULL,
473  i18n("Editing a printcap entry manually should only be "
474  "done by confirmed system administrator. This may "
475  "prevent your printer from working. Do you want to "
476  "continue?"), TQString::null, KStdGuiItem::cont(),
477  "editPrintcap") == KMessageBox::Cancel)
478  return;
479 
480  PrintcapEntry *entry = findEntry(m_currentprinter);
481  EditEntryDialog dlg(entry, NULL);
482  if (dlg.exec())
483  {
484  }
485 }
486 
487 TQString KMLprManager::stateInformation()
488 {
489  return i18n("Spooler type: %1").arg(LprSettings::self()->mode() == LprSettings::LPR ? "LPR (BSD compatible)" : "LPRng");
490 }
491 
492 #include "kmlprmanager.moc"
KPrinter
This class is the main interface to access the TDE print framework.
Definition: kprinter.h:88
KPrinter::printerName
TQString printerName() const
See TQPrinter::printerName().
Definition: kprinter.cpp:864

tdeprint

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

tdeprint

Skip menu "tdeprint"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  •     tdecore
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  • tdeioslave
  •   http
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdeprint by doxygen 1.8.8
This website is maintained by Timothy Pearson.