20 #include "kxmlcommand.h"
22 #include "kmfactory.h"
23 #include "tdeprintcheck.h"
24 #include "driverview.h"
29 #include <tqinputdialog.h>
31 #include <tqvaluelist.h>
32 #include <kstandarddirs.h>
33 #include <tdelocale.h>
34 #include <ksimpleconfig.h>
35 #include <kdialogbase.h>
37 #include <tdeprocess.h>
38 #include <klibloader.h>
39 #include <tdemessagebox.h>
41 static void setOptionText(DrBase *opt,
const TQString& s)
44 opt->set(
"text", opt->name());
46 opt->set(
"text", i18n(s.utf8()));
49 class KXmlCommand::KXmlCommandPrivate
59 TQString m_description;
60 TQString m_outputMime;
61 TQStringList m_inputMime;
62 TQStringList m_requirements;
67 KXmlCommand::KXmlCommand(
const TQString& xmlId)
68 : TQObject(KXmlCommandManager::self(),
"XmlCommand")
74 KXmlCommand::~KXmlCommand()
83 void KXmlCommand::init()
85 d =
new KXmlCommandPrivate;
87 d->m_loaded[0] = d->m_loaded[1] =
false;
90 TQString KXmlCommand::name()
const
93 void KXmlCommand::setName(
const TQString& s)
96 TQString KXmlCommand::command()
102 void KXmlCommand::setCommand(
const TQString& s)
107 DrMain* KXmlCommand::driver()
113 DrMain* KXmlCommand::takeDriver()
116 DrMain *dr = d->m_driver;
118 d->m_loaded[1] =
false;
122 void KXmlCommand::setDriver(DrMain *driver)
125 d->m_driver = driver;
128 TQString KXmlCommand::io(
bool io_input,
bool io_pipe)
131 return d->m_io[(io_input?0:1)].m_format[(io_pipe?1:0)];
134 void KXmlCommand::setIo(
const TQString& s,
bool io_input,
bool io_pipe)
136 d->m_io[(io_input?0:1)].m_format[(io_pipe?1:0)] = s;
139 TQString KXmlCommand::description()
142 return d->m_description;
145 void KXmlCommand::setDescription(
const TQString& s)
147 d->m_description = s;
150 TQString KXmlCommand::mimeType()
153 return d->m_outputMime;
156 void KXmlCommand::setMimeType(
const TQString& s)
161 bool KXmlCommand::acceptMimeType(
const TQString& s)
164 return (d->m_inputMime.find(s) != d->m_inputMime.end());
167 TQStringList KXmlCommand::inputMimeTypes()
170 return d->m_inputMime;
173 void KXmlCommand::setInputMimeTypes(
const TQStringList& l)
178 TQStringList KXmlCommand::requirements()
181 return d->m_requirements;
184 void KXmlCommand::setRequirements(
const TQStringList& l)
186 d->m_requirements = l;
189 TQString KXmlCommand::comment()
195 void KXmlCommand::setComment(
const TQString& s )
200 bool KXmlCommand::isValid()
202 return (!locate(
"data",
"tdeprint/filters/"+name()+
".desktop").isEmpty());
205 void KXmlCommand::check(
bool use_xml)
210 d->m_loaded[0] =
true;
212 if (use_xml && !d->m_loaded[1])
215 d->m_loaded[1] =
true;
219 void KXmlCommand::loadDesktop()
221 KSimpleConfig conf(locate(
"data",
"tdeprint/filters/"+name()+
".desktop"));
222 conf.setGroup(
"TDE Print Filter Entry");
223 d->m_description = conf.readEntry(
"Comment");
224 d->m_outputMime = conf.readEntry(
"MimeTypeOut");
225 d->m_inputMime = conf.readListEntry(
"MimeTypeIn");
226 d->m_requirements = conf.readListEntry(
"Require");
227 d->m_comment = conf.readEntry(
"Description" );
230 void KXmlCommand::saveDesktop()
232 KSimpleConfig conf(locateLocal(
"data",
"tdeprint/filters/"+name()+
".desktop"));
233 conf.setGroup(
"TDE Print Filter Entry");
234 conf.writeEntry(
"Comment", d->m_description);
235 conf.writeEntry(
"MimeTypeIn", d->m_inputMime);
236 conf.writeEntry(
"MimeTypeOut", d->m_outputMime);
237 conf.writeEntry(
"Require", d->m_requirements);
238 conf.writeEntry(
"Description", d->m_comment );
241 void KXmlCommand::loadXml()
243 TQFile f(locate(
"data",
"tdeprint/filters/"+name()+
".xml"));
245 if (f.open(IO_ReadOnly) && doc.setContent(&f) && doc.documentElement().tagName() ==
"kprintfilter")
247 TQDomElement e, docElem = doc.documentElement();
248 d->m_name = docElem.attribute(
"name");
251 e = docElem.namedItem(
"filtercommand").toElement();
253 d->m_command = e.attribute(
"data");
256 e = docElem.namedItem(
"filterargs").toElement();
259 d->m_driver =
new DrMain;
260 d->m_driver->setName(d->m_name);
261 parseGroup(e, d->m_driver);
262 setOptionText(d->m_driver, d->m_description);
266 e = docElem.namedItem(
"filterinput").toElement();
269 e = docElem.namedItem(
"filteroutput").toElement();
275 void KXmlCommand::parseIO(
const TQDomElement& e,
int n)
277 TQDomElement elem = e.firstChild().toElement();
278 while (!elem.isNull())
280 if (elem.tagName() ==
"filterarg")
282 int format = (elem.attribute(
"name") ==
"file" ? 0 : 1);
283 d->m_io[n].m_format[format] = elem.attribute(
"format");
285 elem = elem.nextSibling().toElement();
289 DrGroup* KXmlCommand::parseGroup(
const TQDomElement& e, DrGroup *grp)
293 grp->setName(e.attribute(
"name"));
294 setOptionText(grp, e.attribute(
"description"));
296 TQDomElement elem = e.firstChild().toElement();
297 while (!elem.isNull())
299 if (elem.tagName() ==
"filterarg")
301 DrBase *opt = parseArgument(elem);
305 else if (elem.tagName() ==
"filtergroup")
307 DrGroup *group = parseGroup(elem, 0);
309 grp->addGroup(group);
311 elem = elem.nextSibling().toElement();
317 DrBase* KXmlCommand::parseArgument(
const TQDomElement& e)
320 TQString type = e.attribute(
"type");
322 if (type ==
"int" || type ==
"float")
325 opt =
new DrIntegerOption;
327 opt =
new DrFloatOption;
328 opt->set(
"minval", e.attribute(
"min"));
329 opt->set(
"maxval", e.attribute(
"max"));
331 else if (type ==
"string")
332 opt =
new DrStringOption;
333 else if (type ==
"list" || type ==
"bool")
336 opt =
new DrListOption;
338 opt =
new DrBooleanOption;
339 DrListOption *lopt =
static_cast<DrListOption*
>(opt);
340 TQDomElement elem = e.firstChild().toElement();
341 while (!elem.isNull())
343 if (elem.tagName() ==
"value")
345 DrBase *choice =
new DrBase;
346 choice->setName(elem.attribute(
"name"));
347 setOptionText(choice, elem.attribute(
"description"));
348 lopt->addChoice(choice);
350 elem = elem.nextSibling().toElement();
356 opt->setName(
"_kde-" + d->m_name +
"-" + e.attribute(
"name"));
357 setOptionText(opt, e.attribute(
"description"));
358 opt->set(
"format", e.attribute(
"format"));
359 opt->set(
"default", e.attribute(
"default"));
360 opt->set(
"persistent", e.attribute(
"persistent" ) );
361 opt->setValueText(opt->get(
"default"));
366 TQString KXmlCommand::buildCommand(
const TQMap<TQString,TQString>& opts,
bool pipein,
bool pipeout)
370 TQString str, cmd = d->m_command;
371 TQString re(
"%value" ), quotedRe(
"'%value'" );
375 TQMap<TQString,TQString> fopts;
377 d->m_driver->setOptions(opts);
378 d->m_driver->getOptions(fopts,
false);
379 for (TQMap<TQString,TQString>::ConstIterator it=fopts.begin(); it!=fopts.end(); ++it)
381 DrBase *dopt = d->m_driver->findOption(it.key());
384 TQString format = dopt->get(
"format");
385 TQString value = dopt->valueText();
386 if ( format.find( quotedRe ) != -1 )
388 if ( ( value.right( 1 ) ==
"'" && value.left( 1 ) ==
"'" ) ||
389 ( value.right( 1 ) ==
"\"" && value.left( 1 ) ==
"\"" ) )
390 format.replace( quotedRe, value );
392 format.replace( re, value );
396 format.replace( re, TDEProcess::quote( dopt->valueText() ) );
398 str.append(format).append(
" ");
401 cmd.replace(
"%filterargs", str);
404 cmd.replace(
"%filterinput", d->m_io[0].m_format[(pipein?1:0)]);
405 cmd.replace(
"%filteroutput", d->m_io[1].m_format[(pipeout?1:0)]);
410 void KXmlCommand::setOptions(
const TQMap<TQString,TQString>& opts)
412 if (opts.count() == 0)
416 d->m_driver->setOptions(opts);
419 void KXmlCommand::getOptions(TQMap<TQString,TQString>& opts,
bool incldef)
423 d->m_driver->getOptions(opts, incldef);
426 void KXmlCommand::saveXml()
428 TQFile f(locateLocal(
"data",
"tdeprint/filters/"+name()+
".xml"));
429 if (!f.open(IO_WriteOnly))
432 TQDomDocument doc(
"kprintfilter");
433 TQDomElement root = doc.createElement(
"kprintfilter"), elem;
435 root.setAttribute(
"name", d->m_name);
436 doc.appendChild(root);
439 elem = doc.createElement(
"filtercommand");
440 elem.setAttribute(
"data", d->m_command);
441 root.appendChild(elem);
446 elem = createGroup(doc, d->m_driver);
447 elem.setTagName(
"filterargs");
448 root.appendChild(elem);
452 if (!(elem=createIO(doc, 0,
"filterinput")).isNull())
453 root.appendChild(elem);
454 if (!(elem=createIO(doc, 1,
"filteroutput")).isNull())
455 root.appendChild(elem);
463 TQDomElement KXmlCommand::createIO(TQDomDocument& doc,
int n,
const TQString& tag)
465 TQDomElement elem = doc.createElement(tag);
466 if (d->m_command.find(
"%"+tag) != -1)
468 for (
int i=0; i<2; i++)
470 TQDomElement io = doc.createElement(
"filterarg");
471 io.setAttribute(
"name", (i ?
"pipe" :
"file"));
472 io.setAttribute(
"format", d->m_io[n].m_format[i]);
473 elem.appendChild(io);
480 TQDomElement KXmlCommand::createGroup(TQDomDocument& doc, DrGroup *group)
482 TQDomElement elem = doc.createElement(
"filtergroup");
483 elem.setAttribute(
"name", group->name());
484 elem.setAttribute(
"description", group->get(
"text"));
486 TQPtrListIterator<DrGroup> git(group->groups());
487 for (; git.current(); ++git)
488 elem.appendChild(createGroup(doc, git.current()));
490 TQPtrListIterator<DrBase> oit(group->options());
491 for (; oit.current(); ++oit)
492 elem.appendChild(createElement(doc, oit.current()));
497 TQDomElement KXmlCommand::createElement(TQDomDocument& doc, DrBase *opt)
499 TQDomElement elem = doc.createElement(
"filterarg");
500 TQString elemName = opt->name();
501 if (elemName.startsWith(
"_kde-"))
502 elemName.replace(0, name().length()+6,
"");
503 elem.setAttribute(
"name", elemName);
504 elem.setAttribute(
"format", opt->get(
"format"));
505 elem.setAttribute(
"description", opt->get(
"text"));
506 elem.setAttribute(
"default", opt->get(
"default"));
507 elem.setAttribute(
"persistent", opt->get(
"persistent" ) ==
"1" ?
"1" :
"0");
512 elem.setAttribute(
"type",
"string");
514 case DrBase::Integer:
516 elem.setAttribute(
"type", (opt->type() == DrBase::Integer ?
"int" :
"float"));
517 elem.setAttribute(
"min", opt->get(
"minval"));
518 elem.setAttribute(
"max", opt->get(
"maxval"));
520 case DrBase::Boolean:
522 elem.setAttribute(
"type", (opt->type() == DrBase::List ?
"list" :
"bool"));
524 TQPtrListIterator<DrBase> it(*(
static_cast<DrListOption*
>(opt)->choices()));
525 for (; it.current(); ++it)
527 TQDomElement chElem = doc.createElement(
"value");
528 chElem.setAttribute(
"name", it.current()->name());
529 chElem.setAttribute(
"description", it.current()->get(
"text"));
530 elem.appendChild(chElem);
543 class KXmlCommandManager::KXmlCommandManagerPrivate
546 TQStringList m_cmdlist;
547 TQMap<TQString, TQValueList<KXmlCommand*> > m_mimemap;
548 TQMap<TQString, KXmlCommand*> m_cmdmap;
551 KXmlCommandManager* KXmlCommandManager::m_self = 0;
553 KXmlCommandManager* KXmlCommandManager::self()
557 m_self =
new KXmlCommandManager;
558 TQ_CHECK_PTR(m_self);
563 KXmlCommandManager::KXmlCommandManager()
564 : TQObject(KMFactory::self(),
"XmlCommandManager")
566 d =
new KXmlCommandManagerPrivate;
569 KXmlCommandManager::~KXmlCommandManager()
575 KXmlCommand* KXmlCommandManager::loadCommand(
const TQString& xmlId,
bool check)
579 TQString desktopFile = locate(
"data",
"tdeprint/filters/"+xmlId+
".desktop");
580 if (desktopFile.isEmpty())
583 return new KXmlCommand(xmlId);
586 void KXmlCommandManager::saveCommand(KXmlCommand *xmlCmd)
588 xmlCmd->saveDesktop();
594 void KXmlCommandManager::cleanUp()
596 for (TQMap<TQString, KXmlCommand*>::ConstIterator it=d->m_cmdmap.begin(); it!=d->m_cmdmap.end(); ++it)
599 d->m_mimemap.clear();
600 d->m_cmdlist.clear();
603 void KXmlCommandManager::preload()
605 if (d->m_cmdmap.count() == 0)
608 for (TQStringList::Iterator it=d->m_cmdlist.begin(); it!=d->m_cmdlist.end(); ++it)
610 KXmlCommand *xmlCmd = loadCommand(*it);
611 if (!xmlCmd)
continue;
613 TQStringList inputMime = xmlCmd->inputMimeTypes();
614 for (TQStringList::ConstIterator mime=inputMime.begin(); mime!=inputMime.end(); ++mime)
616 d->m_mimemap[*mime].append(xmlCmd);
617 d->m_cmdmap[*it] = xmlCmd;
623 TQStringList KXmlCommandManager::commandList()
625 if (d->m_cmdlist.isEmpty())
627 TQStringList dirs = TDEGlobal::dirs()->findDirs(
"data",
"tdeprint/filters/");
629 for (TQStringList::ConstIterator it=dirs.begin(); it!=dirs.end(); ++it)
631 TQStringList list = TQDir(*it).entryList(
"*.desktop", TQDir::Files, TQDir::Unsorted);
632 for (TQStringList::ConstIterator it2=list.begin(); it2!=list.end(); ++it2)
634 TQString cmdName = (*it2).left((*it2).length()-8);
635 if (d->m_cmdlist.find(cmdName) == d->m_cmdlist.end())
636 d->m_cmdlist.append(cmdName);
646 TQStringList KXmlCommandManager::commandListWithDescription()
650 for (TQMap<TQString,KXmlCommand*>::ConstIterator it=d->m_cmdmap.begin(); it!=d->m_cmdmap.end(); ++it)
651 l << (*it)->name() << (*it)->description();
656 TQString KXmlCommandManager::selectCommand(TQWidget *parent)
658 KLibrary *lib = KLibLoader::self()->library(
"libtdeprint_management_module" );
661 KMessageBox::error( parent, i18n(
"Unable to load TDE print management library: %1" ).arg( KLibLoader::self()->lastErrorMessage() ) );
662 return TQString::null;
666 TQString ( *func )( TQWidget* ) = ( TQString( * )( TQWidget* ) )lib->symbol(
"select_command" );
669 KMessageBox::error( parent, i18n(
"Unable to find wizard object in management library." ) );
670 return TQString::null;
673 return func( parent );
677 KXmlCommand* KXmlCommandManager::command(
const TQString& xmlId)
const
679 return (d->m_cmdmap.contains(xmlId) ? d->m_cmdmap[xmlId] : 0);
682 int KXmlCommandManager::insertCommand(TQStringList& list,
const TQString& filtername,
bool defaultToStart)
687 KXmlCommand *f1 = command(filtername), *f2 = 0;
688 if (f1 && f1->inputMimeTypes().count() > 0)
690 TQString mimetype = f1->inputMimeTypes()[0];
691 for (TQStringList::Iterator it=list.begin(); it!=list.end(); ++it, pos++)
697 if (f2->acceptMimeType(f1->mimeType()) && f1->acceptMimeType(mimetype))
699 list.insert(it, filtername);
704 mimetype = f2->mimeType();
708 if (pos == (
int)(list.count()))
710 if (list.count() == 0 || f1->acceptMimeType(mimetype))
711 list.append(filtername);
712 else if (defaultToStart)
715 list.prepend(filtername);
724 TQStringList KXmlCommandManager::autoConvert(
const TQString& mimesrc,
const TQString& mimedest)
731 if (d->m_mimemap.contains(mimesrc))
733 const TQValueList<KXmlCommand*> l = d->m_mimemap[mimesrc];
734 for (TQValueList<KXmlCommand*>::ConstIterator it=l.begin(); it!=l.end(); ++it)
737 if (!KdeprintChecker::check((*it)->requirements()))
741 if ((*it)->mimeType() == mimedest)
743 chain = TQStringList((*it)->name());
748 else if ((*it)->mimeType() != mimesrc)
750 TQStringList subchain = autoConvert((*it)->mimeType(), mimedest);
755 if (subchain.count() > 0 && subchain.findIndex((*it)->name()) == -1)
757 subchain.prepend((*it)->name());
758 if (subchain.count() < score || score == 0)
761 score = subchain.count();
772 bool KXmlCommandManager::checkCommand(
const TQString& xmlId,
int inputCheck,
int outputCheck, TQString *msg)
774 KXmlCommand *xmlCmd = command(xmlId);
776 bool needDestroy(
false);
780 xmlCmd = loadCommand(xmlId,
true);
781 needDestroy = (xmlCmd != 0);
787 status = (xmlCmd->isValid() && KdeprintChecker::check(xmlCmd->requirements()));
789 errmsg = i18n(
"One of the command object's requirements is not met.");
791 TQString cmd = (xmlCmd ? xmlCmd->command() : xmlId);
792 if (status && !cmd.isEmpty() && (inputCheck > None || outputCheck > None))
794 if (inputCheck > None && (cmd.find(
"%in") == -1 || inputCheck == Advanced) && cmd.find(
"%filterinput") == -1)
797 errmsg = i18n(
"The command does not contain the required tag %1.").arg(inputCheck == Advanced ?
"%filterinput" :
"{%in,%filterinput}");
799 if (status && outputCheck > None && (cmd.find(
"%out") == -1 || outputCheck == Advanced) && cmd.find(
"filteroutput") == -1)
802 errmsg = i18n(
"The command does not contain the required tag %1.").arg(outputCheck == Advanced ?
"%filteroutput" :
"{%out,%filteroutput}");
815 bool KXmlCommandManager::configure(KXmlCommand *xmlCmd, TQWidget *parent)
817 if (xmlCmd->driver())
819 KDialogBase dlg(parent, 0,
true, xmlCmd->description(), KDialogBase::Ok);
820 DriverView view(&dlg);
822 dlg.setMainWidget(&view);
823 view.setDriver(xmlCmd->driver());