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

tdeprint

  • tdeprint
  • cups
kmcupsjobmanager.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 "kmcupsjobmanager.h"
21 #include "kmcupsmanager.h"
22 #include "kmjob.h"
23 #include "cupsinfos.h"
24 #include "ipprequest.h"
25 #include "pluginaction.h"
26 #include "kprinter.h"
27 #include "kprinterpropertydialog.h"
28 #include "kmuimanager.h"
29 #include "kmfactory.h"
30 #include "kpdriverpage.h"
31 #include "kpschedulepage.h"
32 #include "kpcopiespage.h"
33 #include "kptagspage.h"
34 
35 #include <tdelocale.h>
36 #include <kdebug.h>
37 #include <kurl.h>
38 
39 #include "config.h"
40 
41 KMCupsJobManager::KMCupsJobManager(TQObject *parent, const char *name, const TQStringList & /*args*/)
42 : KMJobManager(parent,name)
43 {
44 }
45 
46 KMCupsJobManager::~KMCupsJobManager()
47 {
48 }
49 
50 int KMCupsJobManager::actions()
51 {
52  return KMJob::All;
53 }
54 
55 bool KMCupsJobManager::sendCommandSystemJob(const TQPtrList<KMJob>& jobs, int action, const TQString& argstr)
56 {
57  IppRequest req;
58  TQString uri;
59  bool value(true);
60 
61  TQPtrListIterator<KMJob> it(jobs);
62  for (;it.current() && value;++it)
63  {
64  // hypothesis: job operation are always done on local jobs. The only operation
65  // allowed on remote jobs is listing (done elsewhere).
66 
67  req.addURI(IPP_TAG_OPERATION,"job-uri",it.current()->uri());
68  req.addName(IPP_TAG_OPERATION,"requesting-user-name",CupsInfos::self()->login());
69  /*
70  TQString jobHost;
71  if (!it.current()->uri().isEmpty())
72  {
73  KURL url(it.current()->uri());
74  req.setHost(url.host());
75  req.setPort(url.port());
76  jobHost = url.host();
77  }
78  */
79 
80  switch (action)
81  {
82  case KMJob::Remove:
83  req.setOperation(IPP_CANCEL_JOB);
84  break;
85  case KMJob::Hold:
86  req.setOperation(IPP_HOLD_JOB);
87  break;
88  case KMJob::Resume:
89  req.setOperation(IPP_RELEASE_JOB);
90  break;
91  case KMJob::Restart:
92  req.setOperation(IPP_RESTART_JOB);
93  break;
94  case KMJob::Move:
95  if (argstr.isEmpty()) return false;
96  req.setOperation(CUPS_MOVE_JOB);
97  uri =
98  TQString::fromLatin1("ipp://%1/printers/%2").arg(CupsInfos::self()->hostaddr(),
99  argstr);
100  req.addURI(IPP_TAG_OPERATION, "job-printer-uri", uri);
101  break;
102  default:
103  return false;
104  }
105 
106  if (!(value = req.doRequest("/jobs/")))
107  KMManager::self()->setErrorMsg(req.statusMessage());
108  }
109 
110  return value;
111 }
112 
113 bool KMCupsJobManager::listJobs(const TQString& prname, KMJobManager::JobType type, int limit)
114 {
115  IppRequest req;
116  TQStringList keys;
117  CupsInfos *infos = CupsInfos::self();
118 
119  // wanted attributes
120  keys.append("job-id");
121  keys.append("job-uri");
122  keys.append("job-name");
123  keys.append("job-state");
124  keys.append("job-printer-uri");
125  keys.append("job-k-octets");
126  keys.append("job-originating-user-name");
127  keys.append("job-k-octets-completed");
128  keys.append("job-media-sheets");
129  keys.append("job-media-sheets-completed");
130  keys.append("job-priority");
131  keys.append("job-billing");
132 
133  req.setOperation(IPP_GET_JOBS);
134 
135  // add printer-uri
136  KMPrinter *mp = KMManager::self()->findPrinter(prname);
137  if (!mp)
138  return false;
139 
140  if (!mp->uri().isEmpty())
141  {
142  req.addURI(IPP_TAG_OPERATION, "printer-uri", mp->uri().prettyURL());
143  /*
144  req.setHost(mp->uri().host());
145  req.setPort(mp->uri().port());
146  */
147  }
148  else
149  req.addURI(IPP_TAG_OPERATION, "printer-uri", TQString("ipp://%1/%2/%3").arg(infos->hostaddr(),
150  (mp&&mp->isClass())?"classes":"printers", prname));
151 
152  // other attributes
153  req.addKeyword(IPP_TAG_OPERATION, "requested-attributes", keys);
154  if (type == KMJobManager::CompletedJobs)
155  req.addKeyword(IPP_TAG_OPERATION,"which-jobs",TQString::fromLatin1("completed"));
156  if (limit > 0)
157  req.addInteger(IPP_TAG_OPERATION,"limit",limit);
158 
159  // send request
160  if (req.doRequest("/"))
161  parseListAnswer(req, mp);
162  else
163  return false;
164 
165  return true;
166 }
167 
168 void KMCupsJobManager::parseListAnswer(IppRequest& req, KMPrinter *pr)
169 {
170  ipp_attribute_t *attr = req.first();
171  ipp_attribute_t *nextAttr;
172  KMJob *job = new KMJob();
173  TQString uri;
174  while (attr)
175  {
176 #ifdef HAVE_CUPS_1_6
177  TQString name(ippGetName(attr));
178  if (name == "job-id") job->setId(ippGetInteger(attr, 0));
179  else if (name == "job-uri") job->setUri(TQString::fromLocal8Bit(ippGetString(attr, 0, NULL)));
180  else if (name == "job-name") job->setName(TQString::fromLocal8Bit(ippGetString(attr, 0, NULL)));
181  else if (name == "job-state")
182  {
183  switch (ippGetInteger(attr, 0))
184  {
185  case IPP_JOB_PENDING:
186  job->setState(KMJob::Queued);
187  break;
188  case IPP_JOB_HELD:
189  job->setState(KMJob::Held);
190  break;
191  case IPP_JOB_PROCESSING:
192  job->setState(KMJob::Printing);
193  break;
194  case IPP_JOB_STOPPED:
195  job->setState(KMJob::Error);
196  break;
197  case IPP_JOB_CANCELLED:
198  job->setState(KMJob::Cancelled);
199  break;
200  case IPP_JOB_ABORTED:
201  job->setState(KMJob::Aborted);
202  break;
203  case IPP_JOB_COMPLETED:
204  job->setState(KMJob::Completed);
205  break;
206  default:
207  job->setState(KMJob::Unknown);
208  break;
209  }
210  }
211  else if (name == "job-k-octets") job->setSize(ippGetInteger(attr, 0));
212  else if (name == "job-originating-user-name") job->setOwner(TQString::fromLocal8Bit(ippGetString(attr, 0, NULL)));
213  else if (name == "job-k-octets-completed") job->setProcessedSize(ippGetInteger(attr, 0));
214  else if (name == "job-media-sheets") job->setPages(ippGetInteger(attr, 0));
215  else if (name == "job-media-sheets-completed") job->setProcessedPages(ippGetInteger(attr, 0));
216  else if (name == "job-printer-uri" && !pr->isRemote())
217  {
218  TQString str(ippGetString(attr, 0, NULL));
219  int p = str.findRev('/');
220  if (p != -1)
221  job->setPrinter(str.mid(p+1));
222  }
223  else if (name == "job-priority")
224  {
225  job->setAttribute(0, TQString::fromLatin1("%1").arg(ippGetInteger(attr, 0), 3));
226  }
227  else if (name == "job-billing")
228  {
229  job->setAttributeCount(2);
230  job->setAttribute(1, TQString::fromLocal8Bit(ippGetString(attr, 0, NULL)));
231  }
232 
233  nextAttr = ippNextAttribute(req.request());
234  if (name.isEmpty() || (!nextAttr))
235  {
236  if (job->printer().isEmpty())
237  job->setPrinter(pr->printerName());
238  job->setRemote(pr->isRemote());
239  addJob(job); // don't use job after this call !!!
240  job = new KMJob();
241  }
242  attr = nextAttr;
243 #else // HAVE_CUPS_1_6
244  TQString name(attr->name);
245  if (name == "job-id") job->setId(attr->values[0].integer);
246  else if (name == "job-uri") job->setUri(TQString::fromLocal8Bit(attr->values[0].string.text));
247  else if (name == "job-name") job->setName(TQString::fromLocal8Bit(attr->values[0].string.text));
248  else if (name == "job-state")
249  {
250  switch (attr->values[0].integer)
251  {
252  case IPP_JOB_PENDING:
253  job->setState(KMJob::Queued);
254  break;
255  case IPP_JOB_HELD:
256  job->setState(KMJob::Held);
257  break;
258  case IPP_JOB_PROCESSING:
259  job->setState(KMJob::Printing);
260  break;
261  case IPP_JOB_STOPPED:
262  job->setState(KMJob::Error);
263  break;
264  case IPP_JOB_CANCELLED:
265  job->setState(KMJob::Cancelled);
266  break;
267  case IPP_JOB_ABORTED:
268  job->setState(KMJob::Aborted);
269  break;
270  case IPP_JOB_COMPLETED:
271  job->setState(KMJob::Completed);
272  break;
273  default:
274  job->setState(KMJob::Unknown);
275  break;
276  }
277  }
278  else if (name == "job-k-octets") job->setSize(attr->values[0].integer);
279  else if (name == "job-originating-user-name") job->setOwner(TQString::fromLocal8Bit(attr->values[0].string.text));
280  else if (name == "job-k-octets-completed") job->setProcessedSize(attr->values[0].integer);
281  else if (name == "job-media-sheets") job->setPages(attr->values[0].integer);
282  else if (name == "job-media-sheets-completed") job->setProcessedPages(attr->values[0].integer);
283  else if (name == "job-printer-uri" && !pr->isRemote())
284  {
285  TQString str(attr->values[0].string.text);
286  int p = str.findRev('/');
287  if (p != -1)
288  job->setPrinter(str.mid(p+1));
289  }
290  else if (name == "job-priority")
291  {
292  job->setAttribute(0, TQString::fromLatin1("%1").arg(attr->values[0].integer, 3));
293  }
294  else if (name == "job-billing")
295  {
296  job->setAttributeCount(2);
297  job->setAttribute(1, TQString::fromLocal8Bit(attr->values[0].string.text));
298  }
299 
300  if (name.isEmpty() || attr == req.last())
301  {
302  if (job->printer().isEmpty())
303  job->setPrinter(pr->printerName());
304  job->setRemote(pr->isRemote());
305  addJob(job); // don't use job after this call !!!
306  job = new KMJob();
307  }
308 
309  attr = attr->next;
310 #endif // HAVE_CUPS_1_6
311  }
312  delete job;
313 }
314 
315 bool KMCupsJobManager::doPluginAction(int ID, const TQPtrList<KMJob>& jobs)
316 {
317  switch (ID)
318  {
319  case 0:
320  if (jobs.count() == 1)
321  return jobIppReport(jobs.getFirst());
322  break;
323  case 1:
324  return changePriority(jobs, true);
325  case 2:
326  return changePriority(jobs, false);
327  case 3:
328  return editJobAttributes(jobs.getFirst());
329  }
330  return false;
331 }
332 
333 bool KMCupsJobManager::jobIppReport(KMJob *j)
334 {
335  IppRequest req;
336 
337  req.setOperation(IPP_GET_JOB_ATTRIBUTES);
338  req.addURI(IPP_TAG_OPERATION, "job-uri", j->uri());
339  bool result(true);
340  /*
341  if (!j->uri().isEmpty())
342  {
343  KURL url(j->uri());
344  req.setHost(url.host());
345  req.setPort(url.port());
346  }
347  */
348  if ((result=req.doRequest("/")))
349  static_cast<KMCupsManager*>(KMManager::self())->ippReport(req, IPP_TAG_JOB, i18n("Job Report"));
350  else
351  KMManager::self()->setErrorMsg(i18n("Unable to retrieve job information: ")+req.statusMessage());
352  return result;
353 }
354 
355 TQValueList<TDEAction*> KMCupsJobManager::createPluginActions(TDEActionCollection *coll)
356 {
357  TQValueList<TDEAction*> list;
358  TDEAction *act(0);
359 
360  list << (act = new PluginAction(0, i18n("&Job IPP Report"), "tdeprint_report", 0, coll, "plugin_ipp"));
361  act->setGroup("plugin");
362  list << (act = new PluginAction(1, i18n("&Increase Priority"), "go-up", 0, coll, "plugin_prioup"));
363  act->setGroup("plugin");
364  list << (act = new PluginAction(2, i18n("&Decrease Priority"), "go-down", 0, coll, "plugin_priodown"));
365  act->setGroup("plugin");
366  list << (act = new PluginAction(3, i18n("&Edit Attributes..."), "edit", 0, coll, "plugin_editjob"));
367  act->setGroup("plugin");
368 
369  return list;
370 }
371 
372 void KMCupsJobManager::validatePluginActions(TDEActionCollection *coll, const TQPtrList<KMJob>& joblist)
373 {
374  TQPtrListIterator<KMJob> it(joblist);
375  bool flag(true);
376  for (; it.current(); ++it)
377  {
378  flag = (flag && it.current()->type() == KMJob::System
379  && (it.current()->state() == KMJob::Queued || it.current()->state() == KMJob::Held)
380  /*&& !it.current()->isRemote()*/);
381  }
382  flag = (flag && joblist.count() > 0);
383  TDEAction *a;
384  if ( ( a = coll->action( "plugin_ipp" ) ) )
385  a->setEnabled( joblist.count() == 1 );
386  if ( ( a = coll->action( "plugin_prioup" ) ) )
387  a->setEnabled( flag );
388  if ( ( a = coll->action( "plugin_priodown" ) ) )
389  a->setEnabled( flag );
390  if ( ( a = coll->action( "plugin_editjob" ) ) )
391  a->setEnabled( flag && ( joblist.count() == 1 ) );
392 }
393 
394 bool KMCupsJobManager::changePriority(const TQPtrList<KMJob>& jobs, bool up)
395 {
396  TQPtrListIterator<KMJob> it(jobs);
397  bool result(true);
398  for (; it.current() && result; ++it)
399  {
400  int value = it.current()->attribute(0).toInt();
401  if (up) value = TQMIN(value+10, 100);
402  else value = TQMAX(value-10, 1);
403 
404  IppRequest req;
405  /*
406  if (!it.current()->uri().isEmpty())
407  {
408  KURL url(it.current()->uri());
409  req.setHost(url.host());
410  req.setPort(url.port());
411  }
412  */
413  req.setOperation(IPP_SET_JOB_ATTRIBUTES);
414  req.addURI(IPP_TAG_OPERATION, "job-uri", it.current()->uri());
415  req.addName(IPP_TAG_OPERATION, "requesting-user-name", CupsInfos::self()->login());
416  req.addInteger(IPP_TAG_JOB, "job-priority", value);
417 
418  if (!(result = req.doRequest("/jobs/")))
419  KMManager::self()->setErrorMsg(i18n("Unable to change job priority: ")+req.statusMessage());
420  }
421  return result;
422 }
423 
424 static TQString processRange(const TQString& range)
425 {
426  TQStringList l = TQStringList::split(',', range, false);
427  TQString s;
428  for (TQStringList::ConstIterator it=l.begin(); it!=l.end(); ++it)
429  {
430  s.append(*it);
431  if ((*it).find('-') == -1)
432  s.append("-").append(*it);
433  s.append(",");
434  }
435  if (!s.isEmpty())
436  s.truncate(s.length()-1);
437  return s;
438 }
439 
440 bool KMCupsJobManager::editJobAttributes(KMJob *j)
441 {
442  IppRequest req;
443 
444  req.setOperation(IPP_GET_JOB_ATTRIBUTES);
445  req.addURI(IPP_TAG_OPERATION, "job-uri", j->uri());
446  /*
447  if (!j->uri().isEmpty())
448  {
449  KURL url(j->uri());
450  req.setHost(url.host());
451  req.setPort(url.port());
452  }
453  */
454  if (!req.doRequest("/"))
455  {
456  KMManager::self()->setErrorMsg(i18n("Unable to retrieve job information: ")+req.statusMessage());
457  return false;
458  }
459 
460  TQMap<TQString,TQString> opts = req.toMap(IPP_TAG_JOB);
461  // translate the "Copies" option to non-CUPS syntax
462  if (opts.contains("copies"))
463  opts["kde-copies"] = opts["copies"];
464  if (opts.contains("page-set"))
465  opts["kde-pageset"] = (opts["page-set"] == "even" ? "2" : (opts["page-set"] == "odd" ? "1" : "0"));
466  if (opts.contains("OutputOrder"))
467  opts["kde-pageorder"] = opts["OutputOrder"];
468  if (opts.contains("multiple-document-handling"))
469  opts["kde-collate"] = (opts["multiple-document-handling"] == "separate-documents-collated-copies" ? "Collate" : "Uncollate");
470  if (opts.contains("page-ranges"))
471  opts["kde-range"] = opts["page-ranges"];
472 
473  // find printer and construct dialog
474  KMPrinter *prt = KMManager::self()->findPrinter(j->printer());
475  if (!prt)
476  {
477  KMManager::self()->setErrorMsg(i18n("Unable to find printer %1.").arg(j->printer()));
478  return false;
479  }
480  KMManager::self()->completePrinterShort(prt);
481  KPrinter::ApplicationType oldAppType = KPrinter::applicationType();
482  KPrinter::setApplicationType(KPrinter::StandAlone);
483  KPrinterPropertyDialog dlg(prt);
484  dlg.setDriver(KMManager::self()->loadPrinterDriver(prt));
485  KMFactory::self()->uiManager()->setupPrinterPropertyDialog(&dlg);
486  KPrinter::setApplicationType( oldAppType );
487  if (dlg.driver())
488  dlg.addPage(new KPDriverPage(prt, dlg.driver(), &dlg));
489  dlg.addPage(new KPCopiesPage(0, &dlg));
490  dlg.addPage(new KPSchedulePage(&dlg));
491  dlg.addPage(new KPTagsPage(true, &dlg));
492  dlg.setOptions(opts);
493  dlg.enableSaveButton(false);
494  dlg.setCaption(i18n("Attributes of Job %1@%2 (%3)").arg(j->id()).arg(j->printer()).arg(j->name()));
495  if (dlg.exec())
496  {
497  opts.clear();
498  // include default values to override non-default values
499  dlg.getOptions(opts, true);
500  // translate the "Copies" options from non-CUPS syntax
501  opts["copies"] = opts["kde-copies"];
502  opts["OutputOrder"] = opts["kde-pageorder"];
503  opts["multiple-document-handling"] = (opts["kde-collate"] == "Collate" ? "separate-documents-collated-copies" : "separate-documents-uncollated-copies");
504  opts["page-set"] = (opts["kde-pageset"] == "1" ? "odd" : (opts["kde-pageset"] == "2" ? "even" : "all"));
505  // it seems CUPS is buggy. Disable page-ranges modification, otherwise nothing gets printed
506  opts["page-ranges"] = processRange(opts["kde-range"]);
507 
508  req.init();
509  req.setOperation(IPP_SET_JOB_ATTRIBUTES);
510  req.addURI(IPP_TAG_OPERATION, "job-uri", j->uri());
511  req.addName(IPP_TAG_OPERATION, "requesting-user-name", CupsInfos::self()->login());
512  req.setMap(opts);
513  //req.dump(1);
514  if (!req.doRequest("/jobs/"))
515  {
516  KMManager::self()->setErrorMsg(i18n("Unable to set job attributes: ")+req.statusMessage());
517  return false;
518  }
519  }
520 
521  return true;
522 }
523 
524 #include "kmcupsjobmanager.moc"
KPrinter::ApplicationType
ApplicationType
Defines the type of the application, this affects the GUI of the print dialog:
Definition: kprinter.h:126
KPrinter::setApplicationType
static void setApplicationType(ApplicationType type)
Sets the application type concerning the print dialog.
Definition: kprinter.cpp:265
KPrinter::applicationType
static ApplicationType applicationType()
Returns the application type concerning the print dialog.
Definition: kprinter.cpp:270

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.