00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
#include "kmcupsjobmanager.h"
00021
#include "kmcupsmanager.h"
00022
#include "kmjob.h"
00023
#include "cupsinfos.h"
00024
#include "ipprequest.h"
00025
#include "pluginaction.h"
00026
#include "kprinter.h"
00027
#include "kprinterpropertydialog.h"
00028
#include "kmuimanager.h"
00029
#include "kmfactory.h"
00030
#include "kpdriverpage.h"
00031
#include "kpschedulepage.h"
00032
#include "kpcopiespage.h"
00033
#include "kptagspage.h"
00034
00035
#include <klocale.h>
00036
#include <kdebug.h>
00037
#include <kurl.h>
00038
00039 KMCupsJobManager::KMCupsJobManager(
QObject *parent,
const char *name,
const QStringList & )
00040 : KMJobManager(parent,name)
00041 {
00042 }
00043
00044 KMCupsJobManager::~KMCupsJobManager()
00045 {
00046 }
00047
00048
int KMCupsJobManager::actions()
00049 {
00050
return KMJob::All;
00051 }
00052
00053
bool KMCupsJobManager::sendCommandSystemJob(
const QPtrList<KMJob>& jobs,
int action,
const QString& argstr)
00054 {
00055 IppRequest req;
00056
QString uri;
00057
bool value(
true);
00058
00059
QPtrListIterator<KMJob> it(jobs);
00060
for (;it.
current() && value;++it)
00061 {
00062
00063
00064
00065 req.addURI(IPP_TAG_OPERATION,
"job-uri",it.
current()->uri());
00066 req.addName(IPP_TAG_OPERATION,
"requesting-user-name",CupsInfos::self()->login());
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
switch (action)
00079 {
00080
case KMJob::Remove:
00081 req.setOperation(IPP_CANCEL_JOB);
00082
break;
00083
case KMJob::Hold:
00084 req.setOperation(IPP_HOLD_JOB);
00085
break;
00086
case KMJob::Resume:
00087 req.setOperation(IPP_RELEASE_JOB);
00088
break;
00089
case KMJob::Restart:
00090 req.setOperation(IPP_RESTART_JOB);
00091
break;
00092
case KMJob::Move:
00093
if (argstr.
isEmpty())
return false;
00094 req.setOperation(CUPS_MOVE_JOB);
00095 uri =
QString::fromLatin1(
"ipp://%1:%2/printers/%3").arg(CupsInfos::self()->host()).arg(CupsInfos::self()->port()).arg(argstr);
00096 req.addURI(IPP_TAG_OPERATION,
"job-printer-uri", uri);
00097
break;
00098
default:
00099
return false;
00100 }
00101
00102
if (!(value = req.doRequest(
"/jobs/")))
00103 KMManager::self()->setErrorMsg(req.statusMessage());
00104 }
00105
00106
return value;
00107 }
00108
00109
bool KMCupsJobManager::listJobs(
const QString& prname, KMJobManager::JobType type,
int limit)
00110 {
00111 IppRequest req;
00112
QString uri(
"ipp://%1:%2/%3/%4");
00113
QStringList keys;
00114 CupsInfos *infos = CupsInfos::self();
00115
00116
00117 keys.append(
"job-id");
00118 keys.append(
"job-uri");
00119 keys.append(
"job-name");
00120 keys.append(
"job-state");
00121 keys.append(
"job-printer-uri");
00122 keys.append(
"job-k-octets");
00123 keys.append(
"job-originating-user-name");
00124 keys.append(
"job-k-octets-completed");
00125 keys.append(
"job-media-sheets");
00126 keys.append(
"job-media-sheets-completed");
00127 keys.append(
"job-priority");
00128 keys.append(
"job-billing");
00129
00130 req.setOperation(IPP_GET_JOBS);
00131
00132
00133 KMPrinter *mp = KMManager::self()->findPrinter(prname);
00134
if (!mp)
00135
return false;
00136
00137
if (!mp->uri().isEmpty())
00138 {
00139 req.addURI(IPP_TAG_OPERATION,
"printer-uri", mp->uri().prettyURL());
00140
00141
00142
00143
00144 }
00145
else
00146 req.addURI(IPP_TAG_OPERATION,
"printer-uri", uri.
arg(infos->host()).arg(infos->port()).arg(((mp&&mp->isClass())?
"classes":
"printers")).arg(prname));
00147
00148
00149 req.addKeyword(IPP_TAG_OPERATION,
"requested-attributes", keys);
00150
if (type == KMJobManager::CompletedJobs)
00151 req.addKeyword(IPP_TAG_OPERATION,
"which-jobs",QString::fromLatin1(
"completed"));
00152
if (limit > 0)
00153 req.addInteger(IPP_TAG_OPERATION,
"limit",limit);
00154
00155
00156
if (req.doRequest(
"/"))
00157 parseListAnswer(req, mp);
00158
else
00159
return false;
00160
00161
return true;
00162 }
00163
00164
void KMCupsJobManager::parseListAnswer(IppRequest& req, KMPrinter *pr)
00165 {
00166 ipp_attribute_t *attr = req.first();
00167 KMJob *job =
new KMJob();
00168
QString uri;
00169
while (attr)
00170 {
00171
QString name(attr->name);
00172
if (name ==
"job-id") job->setId(attr->values[0].integer);
00173
else if (name ==
"job-uri") job->setUri(QString::fromLocal8Bit(attr->values[0].string.text));
00174
else if (name ==
"job-name") job->setName(QString::fromLocal8Bit(attr->values[0].string.text));
00175
else if (name ==
"job-state")
00176 {
00177
switch (attr->values[0].integer)
00178 {
00179
case IPP_JOB_PENDING:
00180 job->setState(KMJob::Queued);
00181
break;
00182
case IPP_JOB_HELD:
00183 job->setState(KMJob::Held);
00184
break;
00185
case IPP_JOB_PROCESSING:
00186 job->setState(KMJob::Printing);
00187
break;
00188
case IPP_JOB_STOPPED:
00189 job->setState(KMJob::Error);
00190
break;
00191
case IPP_JOB_CANCELLED:
00192 job->setState(KMJob::Cancelled);
00193
break;
00194
case IPP_JOB_ABORTED:
00195 job->setState(KMJob::Aborted);
00196
break;
00197
case IPP_JOB_COMPLETED:
00198 job->setState(KMJob::Completed);
00199
break;
00200
default:
00201 job->setState(KMJob::Unknown);
00202
break;
00203 }
00204 }
00205
else if (name ==
"job-k-octets") job->setSize(attr->values[0].integer);
00206
else if (name ==
"job-originating-user-name") job->setOwner(QString::fromLocal8Bit(attr->values[0].string.text));
00207
else if (name ==
"job-k-octets-completed") job->setProcessedSize(attr->values[0].integer);
00208
else if (name ==
"job-media-sheets") job->setPages(attr->values[0].integer);
00209
else if (name ==
"job-media-sheets-completed") job->setProcessedPages(attr->values[0].integer);
00210
else if (name ==
"job-printer-uri" && !pr->isRemote())
00211 {
00212
QString str(attr->values[0].string.text);
00213
int p = str.
findRev(
'/');
00214
if (p != -1)
00215 job->setPrinter(str.
mid(p+1));
00216 }
00217
else if (name ==
"job-priority")
00218 {
00219 job->setAttribute(0, QString::fromLatin1(
"%1").arg(attr->values[0].integer, 3));
00220 }
00221
else if (name ==
"job-billing")
00222 {
00223 job->setAttributeCount(2);
00224 job->setAttribute(1, QString::fromLocal8Bit(attr->values[0].string.text));
00225 }
00226
00227
if (name.isEmpty() || attr == req.last())
00228 {
00229
if (job->printer().isEmpty())
00230 job->setPrinter(pr->printerName());
00231 job->setRemote(pr->isRemote());
00232 addJob(job);
00233 job =
new KMJob();
00234 }
00235
00236 attr = attr->next;
00237 }
00238
delete job;
00239 }
00240
00241
bool KMCupsJobManager::doPluginAction(
int ID,
const QPtrList<KMJob>& jobs)
00242 {
00243
switch (ID)
00244 {
00245
case 0:
00246
if (jobs.
count() == 1)
00247
return jobIppReport(jobs.
getFirst());
00248
break;
00249
case 1:
00250
return changePriority(jobs,
true);
00251
case 2:
00252
return changePriority(jobs,
false);
00253
case 3:
00254
return editJobAttributes(jobs.
getFirst());
00255 }
00256
return false;
00257 }
00258
00259
bool KMCupsJobManager::jobIppReport(KMJob *j)
00260 {
00261 IppRequest req;
00262
00263 req.setOperation(IPP_GET_JOB_ATTRIBUTES);
00264 req.addURI(IPP_TAG_OPERATION,
"job-uri", j->uri());
00265
bool result(
true);
00266
00267
00268
00269
00270
00271
00272
00273
00274
if ((result=req.doRequest(
"/")))
00275 static_cast<KMCupsManager*>(KMManager::self())->ippReport(req, IPP_TAG_JOB, i18n(
"Job Report"));
00276
else
00277 KMManager::self()->setErrorMsg(i18n(
"Unable to retrieve job information: ")+req.statusMessage());
00278
return result;
00279 }
00280
00281
QValueList<KAction*> KMCupsJobManager::createPluginActions(KActionCollection *coll)
00282 {
00283
QValueList<KAction*> list;
00284 KAction *act(0);
00285
00286 list << (act =
new PluginAction(0, i18n(
"&Job IPP Report..."),
"kdeprint_report", 0, coll,
"plugin_ipp"));
00287 act->setGroup(
"plugin");
00288 list << (act =
new PluginAction(1, i18n(
"&Increase Priority"),
"up", 0, coll,
"plugin_prioup"));
00289 act->setGroup(
"plugin");
00290 list << (act =
new PluginAction(2, i18n(
"&Decrease Priority"),
"down", 0, coll,
"plugin_priodown"));
00291 act->setGroup(
"plugin");
00292 list << (act =
new PluginAction(3, i18n(
"&Edit Attributes..."),
"edit", 0, coll,
"plugin_editjob"));
00293 act->setGroup(
"plugin");
00294
00295
return list;
00296 }
00297
00298
void KMCupsJobManager::validatePluginActions(KActionCollection *coll,
const QPtrList<KMJob>& joblist)
00299 {
00300
QPtrListIterator<KMJob> it(joblist);
00301
bool flag(
true);
00302
for (; it.
current(); ++it)
00303 {
00304 flag = (flag && it.
current()->type() == KMJob::System
00305 && (it.
current()->state() == KMJob::Queued || it.
current()->state() == KMJob::Held)
00306 );
00307 }
00308 flag = (flag && joblist.
count() > 0);
00309 KAction *a;
00310
if ( ( a = coll->action(
"plugin_ipp" ) ) )
00311 a->setEnabled( joblist.
count() == 1 );
00312
if ( ( a = coll->action(
"plugin_prioup" ) ) )
00313 a->setEnabled( flag );
00314
if ( ( a = coll->action(
"plugin_priodown" ) ) )
00315 a->setEnabled( flag );
00316
if ( ( a = coll->action(
"plugin_editjob" ) ) )
00317 a->setEnabled( flag && ( joblist.
count() == 1 ) );
00318 }
00319
00320
bool KMCupsJobManager::changePriority(
const QPtrList<KMJob>& jobs,
bool up)
00321 {
00322
QPtrListIterator<KMJob> it(jobs);
00323
bool result(
true);
00324
for (; it.
current() && result; ++it)
00325 {
00326
int value = it.
current()->attribute(0).toInt();
00327
if (up) value = QMIN(value+10, 100);
00328
else value = QMAX(value-10, 1);
00329
00330 IppRequest req;
00331
00332
00333
00334
00335
00336
00337
00338
00339 req.setOperation(IPP_SET_JOB_ATTRIBUTES);
00340 req.addURI(IPP_TAG_OPERATION,
"job-uri", it.
current()->uri());
00341 req.addName(IPP_TAG_OPERATION,
"requesting-user-name", CupsInfos::self()->login());
00342 req.addInteger(IPP_TAG_JOB,
"job-priority", value);
00343
00344
if (!(result = req.doRequest(
"/jobs/")))
00345 KMManager::self()->setErrorMsg(i18n(
"Unable to change job priority: ")+req.statusMessage());
00346 }
00347
return result;
00348 }
00349
00350
static QString processRange(
const QString& range)
00351 {
00352
QStringList l =
QStringList::split(
',', range,
false);
00353
QString s;
00354
for (QStringList::ConstIterator it=l.begin(); it!=l.end(); ++it)
00355 {
00356 s.
append(*it);
00357
if ((*it).find(
'-') == -1)
00358 s.
append(
"-").append(*it);
00359 s.
append(
",");
00360 }
00361
if (!s.
isEmpty())
00362 s.
truncate(s.
length()-1);
00363
return s;
00364 }
00365
00366
bool KMCupsJobManager::editJobAttributes(KMJob *j)
00367 {
00368 IppRequest req;
00369
00370 req.setOperation(IPP_GET_JOB_ATTRIBUTES);
00371 req.addURI(IPP_TAG_OPERATION,
"job-uri", j->uri());
00372
00373
00374
00375
00376
00377
00378
00379
00380
if (!req.doRequest(
"/"))
00381 {
00382 KMManager::self()->setErrorMsg(i18n(
"Unable to retrieve job information: ")+req.statusMessage());
00383
return false;
00384 }
00385
00386
QMap<QString,QString> opts = req.toMap(IPP_TAG_JOB);
00387
00388
if (opts.
contains(
"copies"))
00389 opts[
"kde-copies"] = opts[
"copies"];
00390
if (opts.contains(
"page-set"))
00391 opts[
"kde-pageset"] = (opts[
"page-set"] ==
"even" ?
"2" : (opts[
"page-set"] ==
"odd" ?
"1" :
"0"));
00392
if (opts.contains(
"OutputOrder"))
00393 opts[
"kde-pageorder"] = opts[
"OutputOrder"];
00394
if (opts.contains(
"multiple-document-handling"))
00395 opts[
"kde-collate"] = (opts[
"multiple-document-handling"] ==
"separate-documents-collated-copies" ?
"Collate" :
"Uncollate");
00396
if (opts.contains(
"page-ranges"))
00397 opts[
"kde-range"] = opts[
"page-ranges"];
00398
00399
00400 KMPrinter *prt = KMManager::self()->findPrinter(j->printer());
00401
if (!prt)
00402 {
00403 KMManager::self()->setErrorMsg(i18n(
"Unable to find printer %1.").arg(j->printer()));
00404
return false;
00405 }
00406 KMManager::self()->completePrinterShort(prt);
00407
KPrinter::ApplicationType oldAppType =
KPrinter::applicationType();
00408
KPrinter::setApplicationType(KPrinter::StandAlone);
00409 KPrinterPropertyDialog dlg(prt);
00410 dlg.setDriver(KMManager::self()->loadPrinterDriver(prt));
00411 KMFactory::self()->uiManager()->setupPrinterPropertyDialog(&dlg);
00412
KPrinter::setApplicationType( oldAppType );
00413
if (dlg.driver())
00414 dlg.addPage(
new KPDriverPage(prt, dlg.driver(), &dlg));
00415 dlg.addPage(
new KPCopiesPage(0, &dlg));
00416 dlg.addPage(
new KPSchedulePage(&dlg));
00417 dlg.addPage(
new KPTagsPage(
true, &dlg));
00418 dlg.setOptions(opts);
00419 dlg.enableSaveButton(
false);
00420 dlg.setCaption(i18n(
"Attributes of Job %1@%2 (%3)").arg(j->id()).arg(j->printer()).arg(j->name()));
00421
if (dlg.exec())
00422 {
00423 opts.clear();
00424
00425 dlg.getOptions(opts,
true);
00426
00427 opts[
"copies"] = opts[
"kde-copies"];
00428 opts[
"OutputOrder"] = opts[
"kde-pageorder"];
00429 opts[
"multiple-document-handling"] = (opts[
"kde-collate"] ==
"Collate" ?
"separate-documents-collated-copies" :
"separate-documents-uncollated-copies");
00430 opts[
"page-set"] = (opts[
"kde-pageset"] ==
"1" ?
"odd" : (opts[
"kde-pageset"] ==
"2" ?
"even" :
"all"));
00431
00432 opts[
"page-ranges"] = processRange(opts[
"kde-range"]);
00433
00434 req.init();
00435 req.setOperation(IPP_SET_JOB_ATTRIBUTES);
00436 req.addURI(IPP_TAG_OPERATION,
"job-uri", j->uri());
00437 req.addName(IPP_TAG_OPERATION,
"requesting-user-name", CupsInfos::self()->login());
00438 req.setMap(opts);
00439
00440
if (!req.doRequest(
"/jobs/"))
00441 {
00442 KMManager::self()->setErrorMsg(i18n(
"Unable to set job attributes: ")+req.statusMessage());
00443
return false;
00444 }
00445 }
00446
00447
return true;
00448 }
00449
00450
#include "kmcupsjobmanager.moc"