• 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
41KMCupsJobManager::KMCupsJobManager(TQObject *parent, const char *name, const TQStringList & /*args*/)
42: KMJobManager(parent,name)
43{
44}
45
46KMCupsJobManager::~KMCupsJobManager()
47{
48}
49
50int KMCupsJobManager::actions()
51{
52 return KMJob::All;
53}
54
55bool 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
113bool 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
168void 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
315bool 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
333bool 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
355TQValueList<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
372void 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
394bool 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
424static 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
440bool 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
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdeprint by doxygen 1.9.4
This website is maintained by Timothy Pearson.