# kdeprint Library API Documentation

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

# kxmlcommand.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 "kxmlcommand.h"
    00021 #include "driver.h"
    00022 #include "kmfactory.h"
    00023 #include "kdeprintcheck.h"
    00024 #include "driverview.h"
    00025
    00026 #include <qfile.h>
    00027 #include <qregexp.h>
    00028 #include <qdir.h>
    00029 #include <qinputdialog.h>
    00030 #include <qmap.h>
    00031 #include <qvaluelist.h>
    00032 #include <kstandarddirs.h>
    00033 #include <klocale.h>
    00034 #include <ksimpleconfig.h>
    00035 #include <kdialogbase.h>
    00036 #include <kdebug.h>
    00037 #include <kprocess.h>
    00038 #include <klibloader.h>
    00039 #include <kmessagebox.h>
    00040
    00041 static void setOptionText(DrBase *opt, const QString& s)
    00042 {
    00043     if (s.isEmpty())
    00044         opt->set("text", opt->name());
    00045     else
    00046         opt->set("text", i18n(s.utf8()));
    00047 }
    00048
    00049 class KXmlCommand::KXmlCommandPrivate
    00050 {
    00051 public:
    00052     QString m_name;
    00053     QString m_command;
    00054     DrMain  *m_driver;
    00055     struct
    00056     {
    00057         QString m_format[2];    // 0 -> file, 1 -> pipe
    00058     }   m_io[2];                // 0 -> input, 1 -> output
    00059     QString m_description;
    00060     QString m_outputMime;
    00061     QStringList m_inputMime;
    00062     QStringList m_requirements;
    00063     bool    m_loaded[2];    // 0 -> Desktop, 1 -> XML
    00064     QString m_comment;
    00065 };
    00066
    00067 KXmlCommand::KXmlCommand(const QString& xmlId)
    00068 : QObject(KXmlCommandManager::self(), "XmlCommand")
    00069 {
    00070     init();
    00071     d->m_name = xmlId;
    00072 }
    00073
    00074 KXmlCommand::~KXmlCommand()
    00075 {
    00076     //kdDebug(500) << "deleting driver" << endl;
    00077     delete d->m_driver;
    00078     //kdDebug(500) << "deleting private data" << endl;
    00079     delete d;
    00080     //kdDebug(500) << "finished" << endl;
    00081 }
    00082
    00083 void KXmlCommand::init()
    00084 {
    00085     d = new KXmlCommandPrivate;
    00086     d->m_driver = 0;
    00087     d->m_loaded[0] = d->m_loaded[1] = false;
    00088 }
    00089
    00090 QString KXmlCommand::name() const
    00091 { return d->m_name; }
    00092
    00093 void KXmlCommand::setName(const QString& s)
    00094 { d->m_name = s; }
    00095
    00096 QString KXmlCommand::command()
    00097 {
    00098     check(true);
    00099     return d->m_command;
    00100 }
    00101
    00102 void KXmlCommand::setCommand(const QString& s)
    00103 {
    00104     d->m_command = s;
    00105 }
    00106
    00107 DrMain* KXmlCommand::driver()
    00108 {
    00109     check(true);
    00110     return d->m_driver;
    00111 }
    00112
    00113 DrMain* KXmlCommand::takeDriver()
    00114 {
    00115     check(true);
    00116     DrMain  *dr = d->m_driver;
    00117     d->m_driver = 0;
    00118     d->m_loaded[1] = false;
    00119     return dr;
    00120 }
    00121
    00122 void KXmlCommand::setDriver(DrMain *driver)
    00123 {
    00124     delete d->m_driver;
    00125     d->m_driver = driver;
    00126 }
    00127
    00128 QString KXmlCommand::io(bool io_input, bool io_pipe)
    00129 {
    00130     check(true);
    00131     return d->m_io[(io_input?0:1)].m_format[(io_pipe?1:0)];
    00132 }
    00133
    00134 void KXmlCommand::setIo(const QString& s, bool io_input, bool io_pipe)
    00135 {
    00136     d->m_io[(io_input?0:1)].m_format[(io_pipe?1:0)] = s;
    00137 }
    00138
    00139 QString KXmlCommand::description()
    00140 {
    00141     check();
    00142     return d->m_description;
    00143 }
    00144
    00145 void KXmlCommand::setDescription(const QString& s)
    00146 {
    00147     d->m_description = s;
    00148 }
    00149
    00150 QString KXmlCommand::mimeType()
    00151 {
    00152     check();
    00153     return d->m_outputMime;
    00154 }
    00155
    00156 void KXmlCommand::setMimeType(const QString& s)
    00157 {
    00158     d->m_outputMime = s;
    00159 }
    00160
    00161 bool KXmlCommand::acceptMimeType(const QString& s)
    00162 {
    00163     check();
    00164     return (d->m_inputMime.find(s) != d->m_inputMime.end());
    00165 }
    00166
    00167 QStringList KXmlCommand::inputMimeTypes()
    00168 {
    00169     check();
    00170     return d->m_inputMime;
    00171 }
    00172
    00173 void KXmlCommand::setInputMimeTypes(const QStringList& l)
    00174 {
    00175     d->m_inputMime = l;
    00176 }
    00177
    00178 QStringList KXmlCommand::requirements()
    00179 {
    00180     check();
    00181     return d->m_requirements;
    00182 }
    00183
    00184 void KXmlCommand::setRequirements(const QStringList& l)
    00185 {
    00186     d->m_requirements = l;
    00187 }
    00188
    00189 QString KXmlCommand::comment()
    00190 {
    00191     check();
    00192     return d->m_comment;
    00193 }
    00194
    00195 void KXmlCommand::setComment( const QString& s )
    00196 {
    00197     d->m_comment = s;
    00198 }
    00199
    00200 bool KXmlCommand::isValid()
    00201 {
    00202     return (!locate("data", "kdeprint/filters/"+name()+".desktop").isEmpty());
    00203 }
    00204
    00205 void KXmlCommand::check(bool use_xml)
    00206 {
    00207     if (!d->m_loaded[0])
    00208     {
    00209         loadDesktop();
    00210         d->m_loaded[0] = true;
    00211     }
    00212     if (use_xml && !d->m_loaded[1])
    00213     {
    00214         loadXml();
    00215         d->m_loaded[1] = true;
    00216     }
    00217 }
    00218
    00219 void KXmlCommand::loadDesktop()
    00220 {
    00221     KSimpleConfig   conf(locate("data", "kdeprint/filters/"+name()+".desktop"));
    00222     conf.setGroup("KDE Print Filter Entry");
    00223     d->m_description = conf.readEntry("Comment");
    00224     d->m_outputMime = conf.readEntry("MimeTypeOut");
    00225     d->m_inputMime = conf.readListEntry("MimeTypeIn");
    00226     d->m_requirements = conf.readListEntry("Require");
    00227     d->m_comment = conf.readEntry( "Description" );
    00228 }
    00229
    00230 void KXmlCommand::saveDesktop()
    00231 {
    00232     KSimpleConfig   conf(locateLocal("data", "kdeprint/filters/"+name()+".desktop"));
    00233     conf.setGroup("KDE Print Filter Entry");
    00234     conf.writeEntry("Comment", d->m_description);
    00235     conf.writeEntry("MimeTypeIn", d->m_inputMime);
    00236     conf.writeEntry("MimeTypeOut", d->m_outputMime);
    00237     conf.writeEntry("Require", d->m_requirements);
    00238     conf.writeEntry( "Description", d->m_comment );
    00239 }
    00240
    00241 void KXmlCommand::loadXml()
    00242 {
    00243     QFile   f(locate("data", "kdeprint/filters/"+name()+".xml"));
    00244     QDomDocument    doc;
    00245     if (f.open(IO_ReadOnly) && doc.setContent(&f) && doc.documentElement().tagName() == "kprintfilter")
    00246     {
    00247         QDomElement e, docElem = doc.documentElement();
    00248         d->m_name = docElem.attribute("name");
    00249
    00250         // command
    00251         e = docElem.namedItem("filtercommand").toElement();
    00252         if (!e.isNull())
    00253             d->m_command = e.attribute("data");
    00254
    00255         // arguments
    00256         e = docElem.namedItem("filterargs").toElement();
    00257         if (!e.isNull())
    00258         {
    00259             d->m_driver = new DrMain;
    00260             d->m_driver->setName(d->m_name);
    00261             parseGroup(e, d->m_driver);
    00262             setOptionText(d->m_driver, d->m_description);
    00263         }
    00264
    00265         // input/output
    00266         e = docElem.namedItem("filterinput").toElement();
    00267         if (!e.isNull())
    00268             parseIO(e, 0);
    00269         e = docElem.namedItem("filteroutput").toElement();
    00270         if (!e.isNull())
    00271             parseIO(e, 1);
    00272     }
    00273 }
    00274
    00275 void KXmlCommand::parseIO(const QDomElement& e, int n)
    00276 {
    00277     QDomElement elem = e.firstChild().toElement();
    00278     while (!elem.isNull())
    00279     {
    00280         if (elem.tagName() == "filterarg")
    00281         {
    00282             int format = (elem.attribute("name") == "file" ? 0 : 1);
    00283             d->m_io[n].m_format[format] = elem.attribute("format");
    00284         }
    00285         elem = elem.nextSibling().toElement();
    00286     }
    00287 }
    00288
    00289 DrGroup* KXmlCommand::parseGroup(const QDomElement& e, DrGroup *grp)
    00290 {
    00291     if (!grp)
    00292         grp = new DrGroup;
    00293     grp->setName(e.attribute("name"));
    00294     setOptionText(grp, e.attribute("description"));
    00295
    00296     QDomElement elem = e.firstChild().toElement();
    00297     while (!elem.isNull())
    00298     {
    00299         if (elem.tagName() == "filterarg")
    00300         {
    00301             DrBase  *opt = parseArgument(elem);
    00302             if (opt)
    00303                 grp->addOption(opt);
    00304         }
    00305         else if (elem.tagName() == "filtergroup")
    00306         {
    00307             DrGroup *group = parseGroup(elem, 0);
    00308             if (group)
    00309                 grp->addGroup(group);
    00310         }
    00311         elem = elem.nextSibling().toElement();
    00312     }
    00313
    00314     return grp;
    00315 }
    00316
    00317 DrBase* KXmlCommand::parseArgument(const QDomElement& e)
    00318 {
    00319     DrBase  *opt(0);
    00320     QString type = e.attribute("type");
    00321
    00322     if (type == "int" || type == "float")
    00323     {
    00324         if (type == "int")
    00325             opt = new DrIntegerOption;
    00326         else
    00327             opt = new DrFloatOption;
    00328         opt->set("minval", e.attribute("min"));
    00329         opt->set("maxval", e.attribute("max"));
    00330     }
    00331     else if (type == "string")
    00332         opt = new DrStringOption;
    00333     else if (type == "list" || type == "bool")
    00334     {
    00335         if (type == "list")
    00336             opt = new DrListOption;
    00337         else
    00338             opt = new DrBooleanOption;
    00339         DrListOption    *lopt = static_cast<DrListOption*>(opt);
    00340         QDomElement elem = e.firstChild().toElement();
    00341         while (!elem.isNull())
    00342         {
    00343             if (elem.tagName() == "value")
    00344             {
    00345                 DrBase  *choice = new DrBase;
    00346                 choice->setName(elem.attribute("name"));
    00347                 setOptionText(choice, elem.attribute("description"));
    00348                 lopt->addChoice(choice);
    00349             }
    00350             elem = elem.nextSibling().toElement();
    00351         }
    00352     }
    00353     else
    00354         return 0;
    00355
    00356     opt->setName("_kde-" + d->m_name + "-" + e.attribute("name"));
    00357     setOptionText(opt, e.attribute("description"));
    00358     opt->set("format", e.attribute("format"));
    00359     opt->set("default", e.attribute("default"));
    00360     opt->set( "persistent", e.attribute( "persistent" ) );
    00361     opt->setValueText(opt->get("default"));
    00362
    00363     return opt;
    00364 }
    00365
    00366 QString KXmlCommand::buildCommand(const QMap<QString,QString>& opts, bool pipein, bool pipeout)
    00367 {
    00368     check(true);
    00369
    00370     QString     str, cmd = d->m_command;
    00371     QString re( "%value" ), quotedRe( "'%value'" );
    00372
    00373     if (d->m_driver)
    00374     {
    00375         QMap<QString,QString>   fopts;
    00376
    00377         d->m_driver->setOptions(opts);
    00378         d->m_driver->getOptions(fopts, false);
    00379         for (QMap<QString,QString>::ConstIterator it=fopts.begin(); it!=fopts.end(); ++it)
    00380         {
    00381             DrBase  *dopt = d->m_driver->findOption(it.key());
    00382             if (dopt)
    00383             {
    00384                 QString format = dopt->get("format");
    00385                 QString value = dopt->valueText();
    00386                 if ( format.find( quotedRe ) != -1 )
    00387                 {
    00388                     if ( ( value.right( 1 ) == "'" && value.left( 1 ) == "'" )  ||
    00389                          ( value.right( 1 ) == "\"" && value.left( 1 ) == "\"" ) )
    00390                         format.replace( quotedRe, value );
    00391                     else
    00392                         format.replace( re, value );
    00393                 }
    00394                 else
    00395                 {
    00396                     format.replace( re, KProcess::quote( dopt->valueText() ) );
    00397                 }
    00398                 str.append(format).append(" ");
    00399             }
    00400         }
    00401         cmd.replace("%filterargs", str);
    00402     }
    00403
    00404     cmd.replace("%filterinput", d->m_io[0].m_format[(pipein?1:0)]);
    00405     cmd.replace("%filteroutput", d->m_io[1].m_format[(pipeout?1:0)]);
    00406
    00407     return cmd;
    00408 }
    00409
    00410 void KXmlCommand::setOptions(const QMap<QString,QString>& opts)
    00411 {
    00412     if (opts.count() == 0)
    00413         return;
    00414     // force loading the driver if needed
    00415     if (driver())
    00416         d->m_driver->setOptions(opts);
    00417 }
    00418
    00419 void KXmlCommand::getOptions(QMap<QString,QString>& opts, bool incldef)
    00420 {
    00421     // force loading the driver
    00422     if (driver())
    00423         d->m_driver->getOptions(opts, incldef);
    00424 }
    00425
    00426 void KXmlCommand::saveXml()
    00427 {
    00428     QFile   f(locateLocal("data", "kdeprint/filters/"+name()+".xml"));
    00429     if (!f.open(IO_WriteOnly))
    00430         return;
    00431
    00432     QDomDocument    doc("kprintfilter");
    00433     QDomElement root = doc.createElement("kprintfilter"), elem;
    00434
    00435     root.setAttribute("name", d->m_name);
    00436     doc.appendChild(root);
    00437
    00438     // command
    00439     elem = doc.createElement("filtercommand");
    00440     elem.setAttribute("data", d->m_command);
    00441     root.appendChild(elem);
    00442
    00443     // options
    00444     if (d->m_driver)
    00445     {
    00446         elem = createGroup(doc, d->m_driver);
    00447         elem.setTagName("filterargs");
    00448         root.appendChild(elem);
    00449     }
    00450
    00451     // IO
    00452     if (!(elem=createIO(doc, 0, "filterinput")).isNull())
    00453         root.appendChild(elem);
    00454     if (!(elem=createIO(doc, 1, "filteroutput")).isNull())
    00455         root.appendChild(elem);
    00456
    00457     // save to file (and close it)
    00458     QTextStream t(&f);
    00459     t << doc.toString();
    00460     f.close();
    00461 }
    00462
    00463 QDomElement KXmlCommand::createIO(QDomDocument& doc, int n, const QString& tag)
    00464 {
    00465     QDomElement elem = doc.createElement(tag);
    00466     if (d->m_command.find("%"+tag) != -1)
    00467     {
    00468         for (int i=0; i<2; i++)
    00469         {
    00470             QDomElement io = doc.createElement("filterarg");
    00471             io.setAttribute("name", (i ? "pipe" : "file"));
    00472             io.setAttribute("format", d->m_io[n].m_format[i]);
    00473             elem.appendChild(io);
    00474         }
    00475     }
    00476
    00477     return elem;
    00478 }
    00479
    00480 QDomElement KXmlCommand::createGroup(QDomDocument& doc, DrGroup *group)
    00481 {
    00482     QDomElement elem = doc.createElement("filtergroup");
    00483     elem.setAttribute("name", group->name());
    00484     elem.setAttribute("description", group->get("text"));
    00485
    00486     QPtrListIterator<DrGroup>   git(group->groups());
    00487     for (; git.current(); ++git)
    00488         elem.appendChild(createGroup(doc, git.current()));
    00489
    00490     QPtrListIterator<DrBase>    oit(group->options());
    00491     for (; oit.current(); ++oit)
    00492         elem.appendChild(createElement(doc, oit.current()));
    00493
    00494     return elem;
    00495 }
    00496
    00497 QDomElement KXmlCommand::createElement(QDomDocument& doc, DrBase *opt)
    00498 {
    00499     QDomElement elem = doc.createElement("filterarg");
    00500     QString elemName = opt->name();
    00501     if (elemName.startsWith("_kde-"))
    00502         elemName.replace(0, name().length()+6, "");
    00503     elem.setAttribute("name", elemName);
    00504     elem.setAttribute("format", opt->get("format"));
    00505     elem.setAttribute("description", opt->get("text"));
    00506     elem.setAttribute("default", opt->get("default"));
    00507     elem.setAttribute( "persistent", opt->get( "persistent" ) == "1" ? "1" : "0");
    00508
    00509     switch (opt->type())
    00510     {
    00511         case DrBase::String:
    00512             elem.setAttribute("type", "string");
    00513             break;
    00514         case DrBase::Integer:
    00515         case DrBase::Float:
    00516             elem.setAttribute("type", (opt->type() == DrBase::Integer ? "int" : "float"));
    00517             elem.setAttribute("min", opt->get("minval"));
    00518             elem.setAttribute("max", opt->get("maxval"));
    00519             break;
    00520         case DrBase::Boolean:
    00521         case DrBase::List:
    00522             elem.setAttribute("type", (opt->type() == DrBase::List ? "list" : "bool"));
    00523             {
    00524                 QPtrListIterator<DrBase>    it(*(static_cast<DrListOption*>(opt)->choices()));
    00525                 for (; it.current(); ++it)
    00526                 {
    00527                     QDomElement chElem = doc.createElement("value");
    00528                     chElem.setAttribute("name", it.current()->name());
    00529                     chElem.setAttribute("description", it.current()->get("text"));
    00530                     elem.appendChild(chElem);
    00531                 }
    00532             }
    00533             break;
    00534         default:
    00535             break;
    00536     }
    00537
    00538     return elem;
    00539 }
    00540
    00541 //---------------------------------------------------------------------------------------------------
    00542
    00543 class KXmlCommandManager::KXmlCommandManagerPrivate
    00544 {
    00545 public:
    00546     QStringList m_cmdlist;
    00547     QMap<QString, QValueList<KXmlCommand*> >    m_mimemap;
    00548     QMap<QString, KXmlCommand*> m_cmdmap;
    00549 };
    00550
    00551 KXmlCommandManager* KXmlCommandManager::m_self = 0;
    00552
    00553 KXmlCommandManager* KXmlCommandManager::self()
    00554 {
    00555     if (!m_self)
    00556     {
    00557         m_self = new KXmlCommandManager;
    00558         Q_CHECK_PTR(m_self);
    00559     }
    00560     return m_self;
    00561 }
    00562
    00563 KXmlCommandManager::KXmlCommandManager()
    00564 : QObject(KMFactory::self(), "XmlCommandManager")
    00565 {
    00566     d = new KXmlCommandManagerPrivate;
    00567 }
    00568
    00569 KXmlCommandManager::~KXmlCommandManager()
    00570 {
    00571     cleanUp();
    00572     delete d;
    00573 }
    00574
    00575 KXmlCommand* KXmlCommandManager::loadCommand(const QString& xmlId, bool check)
    00576 {
    00577     if (check)
    00578     {
    00579         QString desktopFile = locate("data", "kdeprint/filters/"+xmlId+".desktop");
    00580         if (desktopFile.isEmpty())
    00581             return 0;
    00582     }
    00583     return new KXmlCommand(xmlId);
    00584 }
    00585
    00586 void KXmlCommandManager::saveCommand(KXmlCommand *xmlCmd)
    00587 {
    00588     xmlCmd->saveDesktop();
    00589     xmlCmd->saveXml();
    00590
    00591     cleanUp();
    00592 }
    00593
    00594 void KXmlCommandManager::cleanUp()
    00595 {
    00596     for (QMap<QString, KXmlCommand*>::ConstIterator it=d->m_cmdmap.begin(); it!=d->m_cmdmap.end(); ++it)
    00597         delete (*it);
    00598     d->m_cmdmap.clear();
    00599     d->m_mimemap.clear();
    00600     d->m_cmdlist.clear();
    00601 }
    00602
    00603 void KXmlCommandManager::preload()
    00604 {
    00605     if (d->m_cmdmap.count() == 0)
    00606     {
    00607         commandList();
    00608         for (QStringList::Iterator it=d->m_cmdlist.begin(); it!=d->m_cmdlist.end(); ++it)
    00609         {
    00610             KXmlCommand *xmlCmd = loadCommand(*it);
    00611             if (!xmlCmd) continue; // Error!
    00612
    00613             QStringList inputMime = xmlCmd->inputMimeTypes();
    00614             for (QStringList::ConstIterator mime=inputMime.begin(); mime!=inputMime.end(); ++mime)
    00615             {
    00616                 d->m_mimemap[*mime].append(xmlCmd);
    00617                 d->m_cmdmap[*it] = xmlCmd;
    00618             }
    00619         }
    00620     }
    00621 }
    00622
    00623 QStringList KXmlCommandManager::commandList()
    00624 {
    00625     if (d->m_cmdlist.isEmpty())
    00626     {
    00627         QStringList dirs = KGlobal::dirs()->findDirs("data", "kdeprint/filters/");
    00628
    00629         for (QStringList::ConstIterator it=dirs.begin(); it!=dirs.end(); ++it)
    00630         {
    00631             QStringList list = QDir(*it).entryList("*.desktop", QDir::Files, QDir::Unsorted);
    00632             for (QStringList::ConstIterator it2=list.begin(); it2!=list.end(); ++it2)
    00633             {
    00634                 QString cmdName = (*it2).left((*it2).length()-8);
    00635                 if (d->m_cmdlist.find(cmdName) == d->m_cmdlist.end())
    00636                     d->m_cmdlist.append(cmdName);
    00637             }
    00638         }
    00639
    00640         d->m_cmdlist.sort();
    00641     }
    00642
    00643     return d->m_cmdlist;
    00644 }
    00645
    00646 QStringList KXmlCommandManager::commandListWithDescription()
    00647 {
    00648     preload();
    00649     QStringList l;
    00650     for (QMap<QString,KXmlCommand*>::ConstIterator it=d->m_cmdmap.begin(); it!=d->m_cmdmap.end(); ++it)
    00651         l << (*it)->name() << (*it)->description();
    00652
    00653     return l;
    00654 }
    00655
    00656 QString KXmlCommandManager::selectCommand(QWidget *parent)
    00657 {
    00658     KLibrary *lib = KLibLoader::self()->library( "libkdeprint_management_module" );
    00659     if ( !lib )
    00660     {
    00661         KMessageBox::error( parent, i18n( "Unable to load KDE print management library: %1" ).arg( KLibLoader::self()->lastErrorMessage() ) );
    00662         return QString::null;
    00663     }
    00664     else
    00665     {
    00666         QString ( *func )( QWidget* ) = ( QString( * )( QWidget* ) )lib->symbol( "select_command" );
    00667         if ( !func )
    00668         {
    00669             KMessageBox::error( parent, i18n( "Unable to find wizard object in management library." ) );
    00670             return QString::null;
    00671         }
    00672         else
    00673             return func( parent );
    00674     }
    00675 }
    00676
    00677 KXmlCommand* KXmlCommandManager::command(const QString& xmlId) const
    00678 {
    00679     return (d->m_cmdmap.contains(xmlId) ? d->m_cmdmap[xmlId] : 0);
    00680 }
    00681
    00682 int KXmlCommandManager::insertCommand(QStringList& list, const QString& filtername, bool defaultToStart)
    00683 {
    00684     preload();
    00685
    00686     int pos(0);
    00687     KXmlCommand *f1 = command(filtername), *f2 = 0;
    00688     if (f1 && f1->inputMimeTypes().count() > 0)
    00689     {
    00690         QString mimetype = f1->inputMimeTypes()[0];
    00691         for (QStringList::Iterator it=list.begin(); it!=list.end(); ++it, pos++)
    00692         {
    00693             f2 = command(*it);
    00694             if (!f2)
    00695                 return -1; // Shouldn't happen
    00696
    00697             if (f2->acceptMimeType(f1->mimeType()) && f1->acceptMimeType(mimetype))
    00698             {
    00699                 list.insert(it, filtername);
    00700                 break;
    00701             }
    00702             else
    00703             {
    00704                 mimetype = f2->mimeType();
    00705                 f2 = 0;
    00706             }
    00707         }
    00708         if (pos == (int)(list.count()))
    00709         {
    00710             if (list.count() == 0 || f1->acceptMimeType(mimetype))
    00711                 list.append(filtername);
    00712             else if (defaultToStart)
    00713             {
    00714                 pos = 0;
    00715                 list.prepend(filtername);
    00716             }
    00717             else
    00718                 pos = -1;
    00719         }
    00720     }
    00721     return pos;
    00722 }
    00723
    00724 QStringList KXmlCommandManager::autoConvert(const QString& mimesrc, const QString& mimedest)
    00725 {
    00726     QStringList chain;
    00727     uint        score(0);
    00728
    00729     preload();
    00730
    00731     if (d->m_mimemap.contains(mimesrc))
    00732     {
    00733         const QValueList<KXmlCommand*>  l = d->m_mimemap[mimesrc];
    00734         for (QValueList<KXmlCommand*>::ConstIterator it=l.begin(); it!=l.end(); ++it)
    00735         {
    00736             // check filter availability
    00737             if (!KdeprintChecker::check((*it)->requirements()))
    00738                 continue;
    00739
    00740             // direct filter: shortest path => return immediately
    00741             if ((*it)->mimeType() == mimedest)
    00742             {
    00743                 chain = QStringList((*it)->name());
    00744                 break;
    00745             }
    00746             // non direct filter: find the shortest way between
    00747             // its output and mimedest (do not consider cyling filters)
    00748             else if ((*it)->mimeType() != mimesrc)
    00749             {
    00750                 QStringList subchain = autoConvert((*it)->mimeType(), mimedest);
    00751                 // If chain length is 0, then there's no possible filter between those 2
    00752                 // mime types. Just discard it. If the subchain contains also the current
    00753                 // considered filter, then discard it: it denotes of a cycle in filter
    00754                 // chain.
    00755                 if (subchain.count() > 0 && subchain.findIndex((*it)->name()) == -1)
    00756                 {
    00757                     subchain.prepend((*it)->name());
    00758                     if (subchain.count() < score || score == 0)
    00759                     {
    00760                         chain = subchain;
    00761                         score = subchain.count();
    00762                     }
    00763                 }
    00764             }
    00765         }
    00766     }
    00767     // At this point, either we have the shortest path, or empty
    00768     // list if nothing could be found
    00769     return chain;
    00770 }
    00771
    00772 bool KXmlCommandManager::checkCommand(const QString& xmlId, int inputCheck, int outputCheck, QString *msg)
    00773 {
    00774     KXmlCommand *xmlCmd = command(xmlId);
    00775     QString errmsg;
    00776     bool    needDestroy(false);
    00777     //kdDebug(500) << "checking command: " << xmlId << " (" << (xmlCmd != NULL) << ")" << endl;
    00778     if (!xmlCmd)
    00779     {
    00780         xmlCmd = loadCommand(xmlId, true);
    00781         needDestroy = (xmlCmd != 0);
    00782     }
    00783
    00784     bool    status(true);
    00785     if (xmlCmd)
    00786     {
    00787         status = (xmlCmd->isValid() && KdeprintChecker::check(xmlCmd->requirements()));
    00788         if (!status)
    00789             errmsg = i18n("One of the command object's requirements is not met.");
    00790     }
    00791     QString cmd = (xmlCmd ? xmlCmd->command() : xmlId);
    00792     if (status && !cmd.isEmpty() && (inputCheck > None || outputCheck > None))
    00793     {
    00794         if (inputCheck > None && (cmd.find("%in") == -1 || inputCheck == Advanced) && cmd.find("%filterinput") == -1)
    00795         {
    00796             status = false;
    00797             errmsg = i18n("The command does not contain the required tag %1.").arg(inputCheck == Advanced ? "%filterinput" : "{%in,%filterinput}");
    00798         }
    00799         if (status && outputCheck > None && (cmd.find("%out") == -1 || outputCheck == Advanced) && cmd.find("filteroutput") == -1)
    00800         {
    00801             status = false;
    00802             errmsg = i18n("The command does not contain the required tag %1.").arg(outputCheck == Advanced ? "%filteroutput" : "{%out,%filteroutput}");
    00803         }
    00804     }
    00805
    00806     if (needDestroy)
    00807         delete xmlCmd;
    00808
    00809     if (msg)
    00810         *msg = errmsg;
    00811
    00812     return status;
    00813 }
    00814
    00815 bool KXmlCommandManager::configure(KXmlCommand *xmlCmd, QWidget *parent)
    00816 {
    00817     if (xmlCmd->driver())
    00818     {
    00819         KDialogBase dlg(parent, 0, true, xmlCmd->description(), KDialogBase::Ok);
    00820         DriverView  view(&dlg);
    00821
    00822         dlg.setMainWidget(&view);
    00823         view.setDriver(xmlCmd->driver());
    00824         dlg.resize(350,400);
    00825         dlg.exec();
    00826
    00827         return true;
    00828     }
    00829     return false;
    00830 }

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:04 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003