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

tdeprint

kmcupsjobmanager.cpp

00001 /*
00002  *  This file is part of the KDE libraries
00003  *  Copyright (c) 2001 Michael Goffioul <tdeprint@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., 51 Franklin Street, Fifth Floor,
00017  *  Boston, MA 02110-1301, 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 <tdelocale.h>
00036 #include <kdebug.h>
00037 #include <kurl.h>
00038 
00039 #include "config.h"
00040 
00041 KMCupsJobManager::KMCupsJobManager(TQObject *parent, const char *name, const TQStringList & /*args*/)
00042 : KMJobManager(parent,name)
00043 {
00044 }
00045 
00046 KMCupsJobManager::~KMCupsJobManager()
00047 {
00048 }
00049 
00050 int KMCupsJobManager::actions()
00051 {
00052     return KMJob::All;
00053 }
00054 
00055 bool KMCupsJobManager::sendCommandSystemJob(const TQPtrList<KMJob>& jobs, int action, const TQString& argstr)
00056 {
00057     IppRequest  req;
00058     TQString        uri;
00059     bool        value(true);
00060 
00061     TQPtrListIterator<KMJob>    it(jobs);
00062     for (;it.current() && value;++it)
00063     {
00064         // hypothesis: job operation are always done on local jobs. The only operation
00065         // allowed on remote jobs is listing (done elsewhere).
00066 
00067         req.addURI(IPP_TAG_OPERATION,"job-uri",it.current()->uri());
00068         req.addName(IPP_TAG_OPERATION,"requesting-user-name",CupsInfos::self()->login());
00069         /*
00070         TQString    jobHost;
00071         if (!it.current()->uri().isEmpty())
00072         {
00073             KURL    url(it.current()->uri());
00074             req.setHost(url.host());
00075             req.setPort(url.port());
00076             jobHost = url.host();
00077         }
00078         */
00079 
00080         switch (action)
00081         {
00082             case KMJob::Remove:
00083                 req.setOperation(IPP_CANCEL_JOB);
00084                 break;
00085             case KMJob::Hold:
00086                 req.setOperation(IPP_HOLD_JOB);
00087                 break;
00088             case KMJob::Resume:
00089                 req.setOperation(IPP_RELEASE_JOB);
00090                 break;
00091             case KMJob::Restart:
00092                 req.setOperation(IPP_RESTART_JOB);
00093                 break;
00094             case KMJob::Move:
00095                 if (argstr.isEmpty()) return false;
00096                 req.setOperation(CUPS_MOVE_JOB);
00097                 uri =
00098                     TQString::fromLatin1("ipp://%1/printers/%2").arg(CupsInfos::self()->hostaddr(),
00099                         argstr);
00100                 req.addURI(IPP_TAG_OPERATION, "job-printer-uri", uri);
00101                 break;
00102             default:
00103                 return false;
00104         }
00105 
00106         if (!(value = req.doRequest("/jobs/")))
00107             KMManager::self()->setErrorMsg(req.statusMessage());
00108     }
00109 
00110     return value;
00111 }
00112 
00113 bool KMCupsJobManager::listJobs(const TQString& prname, KMJobManager::JobType type, int limit)
00114 {
00115     IppRequest  req;
00116     TQStringList    keys;
00117     CupsInfos   *infos = CupsInfos::self();
00118 
00119     // wanted attributes
00120     keys.append("job-id");
00121     keys.append("job-uri");
00122     keys.append("job-name");
00123     keys.append("job-state");
00124     keys.append("job-printer-uri");
00125     keys.append("job-k-octets");
00126     keys.append("job-originating-user-name");
00127     keys.append("job-k-octets-completed");
00128     keys.append("job-media-sheets");
00129     keys.append("job-media-sheets-completed");
00130     keys.append("job-priority");
00131     keys.append("job-billing");
00132 
00133     req.setOperation(IPP_GET_JOBS);
00134 
00135     // add printer-uri
00136     KMPrinter *mp = KMManager::self()->findPrinter(prname);
00137     if (!mp)
00138         return false;
00139 
00140     if (!mp->uri().isEmpty())
00141     {
00142         req.addURI(IPP_TAG_OPERATION, "printer-uri", mp->uri().prettyURL());
00143         /*
00144         req.setHost(mp->uri().host());
00145         req.setPort(mp->uri().port());
00146         */
00147     }
00148     else
00149         req.addURI(IPP_TAG_OPERATION, "printer-uri", TQString("ipp://%1/%2/%3").arg(infos->hostaddr(),
00150                             (mp&&mp->isClass())?"classes":"printers", prname));
00151 
00152     // other attributes
00153     req.addKeyword(IPP_TAG_OPERATION, "requested-attributes", keys);
00154     if (type == KMJobManager::CompletedJobs)
00155         req.addKeyword(IPP_TAG_OPERATION,"which-jobs",TQString::fromLatin1("completed"));
00156     if (limit > 0)
00157         req.addInteger(IPP_TAG_OPERATION,"limit",limit);
00158 
00159     // send request
00160     if (req.doRequest("/"))
00161         parseListAnswer(req, mp);
00162     else
00163         return false;
00164 
00165     return true;
00166 }
00167 
00168 void KMCupsJobManager::parseListAnswer(IppRequest& req, KMPrinter *pr)
00169 {
00170     ipp_attribute_t *attr = req.first();
00171     ipp_attribute_t *nextAttr;
00172     KMJob       *job = new KMJob();
00173     TQString        uri;
00174     while (attr)
00175     {
00176 #ifdef HAVE_CUPS_1_6
00177         TQString    name(ippGetName(attr));
00178         if (name == "job-id") job->setId(ippGetInteger(attr, 0));
00179         else if (name == "job-uri") job->setUri(TQString::fromLocal8Bit(ippGetString(attr, 0, NULL)));
00180         else if (name == "job-name") job->setName(TQString::fromLocal8Bit(ippGetString(attr, 0, NULL)));
00181         else if (name == "job-state")
00182         {
00183             switch (ippGetInteger(attr, 0))
00184             {
00185                 case IPP_JOB_PENDING:
00186                     job->setState(KMJob::Queued);
00187                     break;
00188                 case IPP_JOB_HELD:
00189                     job->setState(KMJob::Held);
00190                     break;
00191                 case IPP_JOB_PROCESSING:
00192                     job->setState(KMJob::Printing);
00193                     break;
00194                 case IPP_JOB_STOPPED:
00195                     job->setState(KMJob::Error);
00196                     break;
00197                 case IPP_JOB_CANCELLED:
00198                     job->setState(KMJob::Cancelled);
00199                     break;
00200                 case IPP_JOB_ABORTED:
00201                     job->setState(KMJob::Aborted);
00202                     break;
00203                 case IPP_JOB_COMPLETED:
00204                     job->setState(KMJob::Completed);
00205                     break;
00206                 default:
00207                     job->setState(KMJob::Unknown);
00208                     break;
00209             }
00210         }
00211         else if (name == "job-k-octets") job->setSize(ippGetInteger(attr, 0));
00212         else if (name == "job-originating-user-name") job->setOwner(TQString::fromLocal8Bit(ippGetString(attr, 0, NULL)));
00213         else if (name == "job-k-octets-completed") job->setProcessedSize(ippGetInteger(attr, 0));
00214         else if (name == "job-media-sheets") job->setPages(ippGetInteger(attr, 0));
00215         else if (name == "job-media-sheets-completed") job->setProcessedPages(ippGetInteger(attr, 0));
00216         else if (name == "job-printer-uri" && !pr->isRemote())
00217         {
00218             TQString    str(ippGetString(attr, 0, NULL));
00219             int p = str.findRev('/');
00220             if (p != -1)
00221                 job->setPrinter(str.mid(p+1));
00222         }
00223         else if (name == "job-priority")
00224         {
00225             job->setAttribute(0, TQString::fromLatin1("%1").arg(ippGetInteger(attr, 0), 3));
00226         }
00227         else if (name == "job-billing")
00228         {
00229             job->setAttributeCount(2);
00230             job->setAttribute(1, TQString::fromLocal8Bit(ippGetString(attr, 0, NULL)));
00231         }
00232 
00233         nextAttr = ippNextAttribute(req.request());
00234         if (name.isEmpty() || (!nextAttr))
00235         {
00236             if (job->printer().isEmpty())
00237                 job->setPrinter(pr->printerName());
00238             job->setRemote(pr->isRemote());
00239             addJob(job);    // don't use job after this call !!!
00240             job = new KMJob();
00241         }
00242         attr = nextAttr;
00243 #else // HAVE_CUPS_1_6
00244         TQString    name(attr->name);
00245         if (name == "job-id") job->setId(attr->values[0].integer);
00246         else if (name == "job-uri") job->setUri(TQString::fromLocal8Bit(attr->values[0].string.text));
00247         else if (name == "job-name") job->setName(TQString::fromLocal8Bit(attr->values[0].string.text));
00248         else if (name == "job-state")
00249         {
00250             switch (attr->values[0].integer)
00251             {
00252                 case IPP_JOB_PENDING:
00253                     job->setState(KMJob::Queued);
00254                     break;
00255                 case IPP_JOB_HELD:
00256                     job->setState(KMJob::Held);
00257                     break;
00258                 case IPP_JOB_PROCESSING:
00259                     job->setState(KMJob::Printing);
00260                     break;
00261                 case IPP_JOB_STOPPED:
00262                     job->setState(KMJob::Error);
00263                     break;
00264                 case IPP_JOB_CANCELLED:
00265                     job->setState(KMJob::Cancelled);
00266                     break;
00267                 case IPP_JOB_ABORTED:
00268                     job->setState(KMJob::Aborted);
00269                     break;
00270                 case IPP_JOB_COMPLETED:
00271                     job->setState(KMJob::Completed);
00272                     break;
00273                 default:
00274                     job->setState(KMJob::Unknown);
00275                     break;
00276             }
00277         }
00278         else if (name == "job-k-octets") job->setSize(attr->values[0].integer);
00279         else if (name == "job-originating-user-name") job->setOwner(TQString::fromLocal8Bit(attr->values[0].string.text));
00280         else if (name == "job-k-octets-completed") job->setProcessedSize(attr->values[0].integer);
00281         else if (name == "job-media-sheets") job->setPages(attr->values[0].integer);
00282         else if (name == "job-media-sheets-completed") job->setProcessedPages(attr->values[0].integer);
00283         else if (name == "job-printer-uri" && !pr->isRemote())
00284         {
00285             TQString    str(attr->values[0].string.text);
00286             int p = str.findRev('/');
00287             if (p != -1)
00288                 job->setPrinter(str.mid(p+1));
00289         }
00290         else if (name == "job-priority")
00291         {
00292             job->setAttribute(0, TQString::fromLatin1("%1").arg(attr->values[0].integer, 3));
00293         }
00294         else if (name == "job-billing")
00295         {
00296             job->setAttributeCount(2);
00297             job->setAttribute(1, TQString::fromLocal8Bit(attr->values[0].string.text));
00298         }
00299 
00300         if (name.isEmpty() || attr == req.last())
00301         {
00302             if (job->printer().isEmpty())
00303                 job->setPrinter(pr->printerName());
00304             job->setRemote(pr->isRemote());
00305             addJob(job);    // don't use job after this call !!!
00306             job = new KMJob();
00307         }
00308 
00309         attr = attr->next;
00310 #endif // HAVE_CUPS_1_6
00311     }
00312     delete job;
00313 }
00314 
00315 bool KMCupsJobManager::doPluginAction(int ID, const TQPtrList<KMJob>& jobs)
00316 {
00317     switch (ID)
00318     {
00319         case 0:
00320             if (jobs.count() == 1)
00321                 return jobIppReport(jobs.getFirst());
00322             break;
00323         case 1:
00324             return changePriority(jobs, true);
00325         case 2:
00326             return changePriority(jobs, false);
00327         case 3:
00328             return editJobAttributes(jobs.getFirst());
00329     }
00330     return false;
00331 }
00332 
00333 bool KMCupsJobManager::jobIppReport(KMJob *j)
00334 {
00335     IppRequest  req;
00336 
00337     req.setOperation(IPP_GET_JOB_ATTRIBUTES);
00338     req.addURI(IPP_TAG_OPERATION, "job-uri", j->uri());
00339     bool    result(true);
00340     /*
00341     if (!j->uri().isEmpty())
00342     {
00343         KURL    url(j->uri());
00344         req.setHost(url.host());
00345         req.setPort(url.port());
00346     }
00347     */
00348     if ((result=req.doRequest("/")))
00349         static_cast<KMCupsManager*>(KMManager::self())->ippReport(req, IPP_TAG_JOB, i18n("Job Report"));
00350     else
00351         KMManager::self()->setErrorMsg(i18n("Unable to retrieve job information: ")+req.statusMessage());
00352     return result;
00353 }
00354 
00355 TQValueList<TDEAction*> KMCupsJobManager::createPluginActions(TDEActionCollection *coll)
00356 {
00357     TQValueList<TDEAction*> list;
00358     TDEAction   *act(0);
00359 
00360     list <<  (act = new PluginAction(0, i18n("&Job IPP Report"), "tdeprint_report", 0, coll, "plugin_ipp"));
00361     act->setGroup("plugin");
00362     list << (act = new PluginAction(1, i18n("&Increase Priority"), "go-up", 0, coll, "plugin_prioup"));
00363     act->setGroup("plugin");
00364     list << (act = new PluginAction(2, i18n("&Decrease Priority"), "go-down", 0, coll, "plugin_priodown"));
00365     act->setGroup("plugin");
00366     list << (act = new PluginAction(3, i18n("&Edit Attributes..."), "edit", 0, coll, "plugin_editjob"));
00367     act->setGroup("plugin");
00368 
00369     return list;
00370 }
00371 
00372 void KMCupsJobManager::validatePluginActions(TDEActionCollection *coll, const TQPtrList<KMJob>& joblist)
00373 {
00374     TQPtrListIterator<KMJob>    it(joblist);
00375     bool    flag(true);
00376     for (; it.current(); ++it)
00377     {
00378         flag = (flag && it.current()->type() == KMJob::System
00379                 && (it.current()->state() == KMJob::Queued || it.current()->state() == KMJob::Held)
00380             /*&& !it.current()->isRemote()*/);
00381     }
00382     flag = (flag && joblist.count() > 0);
00383     TDEAction *a;
00384     if ( ( a = coll->action( "plugin_ipp" ) ) )
00385         a->setEnabled( joblist.count() == 1 );
00386     if ( ( a = coll->action( "plugin_prioup" ) ) )
00387         a->setEnabled( flag );
00388     if ( ( a = coll->action( "plugin_priodown" ) ) )
00389         a->setEnabled( flag );
00390     if ( ( a = coll->action( "plugin_editjob" ) ) )
00391         a->setEnabled( flag && ( joblist.count() == 1 ) );
00392 }
00393 
00394 bool KMCupsJobManager::changePriority(const TQPtrList<KMJob>& jobs, bool up)
00395 {
00396     TQPtrListIterator<KMJob>    it(jobs);
00397     bool    result(true);
00398     for (; it.current() && result; ++it)
00399     {
00400         int value = it.current()->attribute(0).toInt();
00401         if (up) value = TQMIN(value+10, 100);
00402         else value = TQMAX(value-10, 1);
00403 
00404         IppRequest  req;
00405         /*
00406         if (!it.current()->uri().isEmpty())
00407         {
00408             KURL    url(it.current()->uri());
00409             req.setHost(url.host());
00410             req.setPort(url.port());
00411         }
00412         */
00413         req.setOperation(IPP_SET_JOB_ATTRIBUTES);
00414         req.addURI(IPP_TAG_OPERATION, "job-uri", it.current()->uri());
00415         req.addName(IPP_TAG_OPERATION, "requesting-user-name", CupsInfos::self()->login());
00416         req.addInteger(IPP_TAG_JOB, "job-priority", value);
00417 
00418         if (!(result = req.doRequest("/jobs/")))
00419             KMManager::self()->setErrorMsg(i18n("Unable to change job priority: ")+req.statusMessage());
00420     }
00421     return result;
00422 }
00423 
00424 static TQString processRange(const TQString& range)
00425 {
00426     TQStringList    l = TQStringList::split(',', range, false);
00427     TQString    s;
00428     for (TQStringList::ConstIterator it=l.begin(); it!=l.end(); ++it)
00429     {
00430         s.append(*it);
00431         if ((*it).find('-') == -1)
00432             s.append("-").append(*it);
00433         s.append(",");
00434     }
00435     if (!s.isEmpty())
00436         s.truncate(s.length()-1);
00437     return s;
00438 }
00439 
00440 bool KMCupsJobManager::editJobAttributes(KMJob *j)
00441 {
00442     IppRequest  req;
00443 
00444     req.setOperation(IPP_GET_JOB_ATTRIBUTES);
00445     req.addURI(IPP_TAG_OPERATION, "job-uri", j->uri());
00446     /*
00447     if (!j->uri().isEmpty())
00448     {
00449         KURL    url(j->uri());
00450         req.setHost(url.host());
00451         req.setPort(url.port());
00452     }
00453     */
00454     if (!req.doRequest("/"))
00455     {
00456         KMManager::self()->setErrorMsg(i18n("Unable to retrieve job information: ")+req.statusMessage());
00457         return false;
00458     }
00459 
00460     TQMap<TQString,TQString>    opts = req.toMap(IPP_TAG_JOB);
00461     // translate the "Copies" option to non-CUPS syntax
00462     if (opts.contains("copies"))
00463         opts["kde-copies"] = opts["copies"];
00464     if (opts.contains("page-set"))
00465         opts["kde-pageset"] = (opts["page-set"] == "even" ? "2" : (opts["page-set"] == "odd" ? "1" : "0"));
00466     if (opts.contains("OutputOrder"))
00467         opts["kde-pageorder"] = opts["OutputOrder"];
00468     if (opts.contains("multiple-document-handling"))
00469         opts["kde-collate"] = (opts["multiple-document-handling"] == "separate-documents-collated-copies" ? "Collate" : "Uncollate");
00470     if (opts.contains("page-ranges"))
00471         opts["kde-range"] = opts["page-ranges"];
00472 
00473     // find printer and construct dialog
00474     KMPrinter   *prt = KMManager::self()->findPrinter(j->printer());
00475     if (!prt)
00476     {
00477         KMManager::self()->setErrorMsg(i18n("Unable to find printer %1.").arg(j->printer()));
00478         return false;
00479     }
00480     KMManager::self()->completePrinterShort(prt);
00481     KPrinter::ApplicationType oldAppType = KPrinter::applicationType();
00482     KPrinter::setApplicationType(KPrinter::StandAlone);
00483     KPrinterPropertyDialog  dlg(prt);
00484     dlg.setDriver(KMManager::self()->loadPrinterDriver(prt));
00485     KMFactory::self()->uiManager()->setupPrinterPropertyDialog(&dlg);
00486     KPrinter::setApplicationType( oldAppType );
00487     if (dlg.driver())
00488         dlg.addPage(new KPDriverPage(prt, dlg.driver(), &dlg));
00489     dlg.addPage(new KPCopiesPage(0, &dlg));
00490     dlg.addPage(new KPSchedulePage(&dlg));
00491     dlg.addPage(new KPTagsPage(true, &dlg));
00492     dlg.setOptions(opts);
00493     dlg.enableSaveButton(false);
00494     dlg.setCaption(i18n("Attributes of Job %1@%2 (%3)").arg(j->id()).arg(j->printer()).arg(j->name()));
00495     if (dlg.exec())
00496     {
00497         opts.clear();
00498         // include default values to override non-default values
00499         dlg.getOptions(opts, true);
00500         // translate the "Copies" options from non-CUPS syntax
00501         opts["copies"] = opts["kde-copies"];
00502         opts["OutputOrder"] = opts["kde-pageorder"];
00503         opts["multiple-document-handling"] = (opts["kde-collate"] == "Collate" ? "separate-documents-collated-copies" : "separate-documents-uncollated-copies");
00504         opts["page-set"] = (opts["kde-pageset"] == "1" ? "odd" : (opts["kde-pageset"] == "2" ? "even" : "all"));
00505         // it seems CUPS is buggy. Disable page-ranges modification, otherwise nothing gets printed
00506         opts["page-ranges"] = processRange(opts["kde-range"]);
00507 
00508         req.init();
00509         req.setOperation(IPP_SET_JOB_ATTRIBUTES);
00510         req.addURI(IPP_TAG_OPERATION, "job-uri", j->uri());
00511         req.addName(IPP_TAG_OPERATION, "requesting-user-name", CupsInfos::self()->login());
00512         req.setMap(opts);
00513         //req.dump(1);
00514         if (!req.doRequest("/jobs/"))
00515         {
00516             KMManager::self()->setErrorMsg(i18n("Unable to set job attributes: ")+req.statusMessage());
00517             return false;
00518         }
00519     }
00520 
00521     return true;
00522 }
00523 
00524 #include "kmcupsjobmanager.moc"

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.6.3
This website is maintained by Timothy Pearson.