# kdeprint Library API Documentation

Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# kmcupsjobmanager.cpp

    00001 /*
    00002  *  This file is part of the KDE libraries
    00003  *  Copyright (c) 2001 Michael Goffioul <kdeprint@swing.be>
    00004  *
    00005  *  This library is free software; you can redistribute it and/or
    00006  *  modify it under the terms of the GNU Library General Public
    00007  *  License version 2 as published by the Free Software Foundation.
    00008  *
    00009  *  This library is distributed in the hope that it will be useful,
    00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00012  *  Library General Public License for more details.
    00013  *
    00014  *  You should have received a copy of the GNU Library General Public License
    00015  *  along with this library; see the file COPYING.LIB.  If not, write to
    00016  *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    00017  *  Boston, MA 02111-1307, USA.
    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 & /*args*/)
    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         // hypothesis: job operation are always done on local jobs. The only operation
    00063         // allowed on remote jobs is listing (done elsewhere).
    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         QString jobHost;
    00069         if (!it.current()->uri().isEmpty())
    00070         {
    00071             KURL    url(it.current()->uri());
    00072             req.setHost(url.host());
    00073             req.setPort(url.port());
    00074             jobHost = url.host();
    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     // wanted attributes
    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     // add printer-uri
    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         req.setHost(mp->uri().host());
    00142         req.setPort(mp->uri().port());
    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     // other attributes
    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     // send request
    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);    // don't use job after this call !!!
    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     if (!j->uri().isEmpty())
    00268     {
    00269         KURL    url(j->uri());
    00270         req.setHost(url.host());
    00271         req.setPort(url.port());
    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             /*&& !it.current()->isRemote()*/);
    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         if (!it.current()->uri().isEmpty())
    00333         {
    00334             KURL    url(it.current()->uri());
    00335             req.setHost(url.host());
    00336             req.setPort(url.port());
    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     if (!j->uri().isEmpty())
    00374     {
    00375         KURL    url(j->uri());
    00376         req.setHost(url.host());
    00377         req.setPort(url.port());
    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     // translate the "Copies" option to non-CUPS syntax
    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     // find printer and construct dialog
    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         // include default values to override non-default values
    00425         dlg.getOptions(opts, true);
    00426         // translate the "Copies" options from non-CUPS syntax
    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         // it seems CUPS is buggy. Disable page-ranges modification, otherwise nothing gets printed
    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         //req.dump(1);
    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"

This file is part of the documentation for kdeprint Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:31:02 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003