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

tdeprint

  • tdeprint
kprinterimpl.cpp
1 /*
2  * This file is part of the KDE libraries
3  * Copyright (c) 2001 Michael Goffioul <tdeprint@swing.be>
4  *
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License version 2 as published by the Free Software Foundation.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB. If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  **/
20 
21 #include "kprinterimpl.h"
22 #include "kprinter.h"
23 #include "kmfactory.h"
24 #include "kmmanager.h"
25 #include "kmuimanager.h"
26 #include "kxmlcommand.h"
27 #include "kmspecialmanager.h"
28 #include "kmthreadjob.h"
29 #include "kmprinter.h"
30 #include "driver.h"
31 
32 #include <tqfile.h>
33 #include <tqregexp.h>
34 #include <kinputdialog.h>
35 #include <tdelocale.h>
36 #include <dcopclient.h>
37 #include <tdeapplication.h>
38 #include <kstandarddirs.h>
39 #include <kdatastream.h>
40 #include <kdebug.h>
41 #include <kmimemagic.h>
42 #include <tdemessagebox.h>
43 #include <tdeprocess.h>
44 #include <tdeconfig.h>
45 
46 #include <stdlib.h>
47 
48 void dumpOptions(const TQMap<TQString,TQString>&);
49 void initEditPrinter(KMPrinter *p)
50 {
51  if (!p->isEdited())
52  {
53  p->setEditedOptions(p->defaultOptions());
54  p->setEdited(true);
55  }
56 }
57 
58 //****************************************************************************************
59 
60 KPrinterImpl::KPrinterImpl(TQObject *parent, const char *name)
61 : TQObject(parent,name)
62 {
63  loadAppOptions();
64 }
65 
66 KPrinterImpl::~KPrinterImpl()
67 {
68 }
69 
70 void KPrinterImpl::preparePrinting(KPrinter *printer)
71 {
72  // page size -> try to find page size and margins from driver file
73  // use "PageSize" as option name to find the wanted page size. It's
74  // up to the driver loader to use that option name.
75  KMManager *mgr = KMFactory::self()->manager();
76  DrMain *driver = mgr->loadPrinterDriver(mgr->findPrinter(printer->printerName()), false);
77  if (driver)
78  {
79  // Find the page size:
80  // 1) print option
81  // 2) default driver option
82  TQString psname = printer->option("PageSize");
83  if (psname.isEmpty())
84  {
85  DrListOption *opt = (DrListOption*)driver->findOption("PageSize");
86  if (opt) psname = opt->get("default");
87  }
88  if (!psname.isEmpty())
89  {
90  printer->setOption("kde-pagesize",TQString::number((int)pageNameToPageSize(psname)));
91  DrPageSize *ps = driver->findPageSize(psname);
92  if (ps)
93  {
94  printer->setRealPageSize( ps );
95  }
96  }
97 
98  // Find the numerical resolution
99  // 1) print option (Resolution)
100  // 2) default driver option (Resolution)
101  // 3) default printer resolution
102  // The resolution must have the format: XXXdpi or XXXxYYYdpi. In the second
103  // case the YYY value is used as resolution.
104  TQString res = printer->option( "Resolution" );
105  if ( res.isEmpty() )
106  {
107  DrBase *opt = driver->findOption( "Resolution" );
108  if ( opt )
109  res = opt->get( "default" );
110  if ( res.isEmpty() )
111  res = driver->get( "resolution" );
112  }
113  if ( !res.isEmpty() )
114  {
115  TQRegExp re( "(\\d+)(?:x(\\d+))?dpi" );
116  if ( re.search( res ) != -1 )
117  {
118  if ( !re.cap( 2 ).isEmpty() )
119  printer->setOption( "kde-resolution", re.cap( 2 ) );
120  else
121  printer->setOption( "kde-resolution", re.cap( 1 ) );
122  }
123  }
124 
125  // Find the supported fonts
126  TQString fonts = driver->get( "fonts" );
127  if ( !fonts.isEmpty() )
128  printer->setOption( "kde-fonts", fonts );
129 
130  delete driver;
131  }
132 
133 }
134 
135 bool KPrinterImpl::setupCommand(TQString&, KPrinter*)
136 {
137  return false;
138 }
139 
140 bool KPrinterImpl::printFiles(KPrinter *p, const TQStringList& f, bool flag)
141 {
142  TQString cmd;
143  if (p->option("kde-isspecial") == "1")
144  {
145  if (p->option("kde-special-command").isEmpty() && p->outputToFile())
146  {
147  KURL url( p->outputFileName() );
148  if ( !url.isLocalFile() )
149  {
150  cmd = ( flag ? "mv" : "cp" ) + ( " %in $out{" + p->outputFileName() + "}" );
151  }
152  else
153  {
154  if (f.count() > 1)
155  {
156  p->setErrorMessage(i18n("Cannot copy multiple files into one file."));
157  return false;
158  }
159  else
160  {
161  TDEProcess proc;
162  proc << (flag?"mv":"cp") << f[0] << p->outputFileName();
163  if (!proc.start(TDEProcess::Block) || !proc.normalExit() || proc.exitStatus() != 0)
164  {
165  p->setErrorMessage(i18n("Cannot save print file to %1. Check that you have write access to it.").arg(p->outputFileName()));
166  return false;
167  }
168  }
169  return true;
170  }
171  }
172  else if (!setupSpecialCommand(cmd,p,f))
173  return false;
174  }
175  else if (!setupCommand(cmd,p))
176  return false;
177  return startPrinting(cmd,p,f,flag);
178 }
179 
180 void KPrinterImpl::broadcastOption(const TQString& key, const TQString& value)
181 {
182  // force printer listing if not done yet (or reload needed)
183  TQPtrList<KMPrinter> *printers = KMFactory::self()->manager()->printerListComplete(false);
184  if (printers)
185  {
186  TQPtrListIterator<KMPrinter> it(*printers);
187  for (;it.current();++it)
188  {
189  initEditPrinter(it.current());
190  it.current()->setEditedOption(key,value);
191  }
192  }
193 }
194 
195 int KPrinterImpl::dcopPrint(const TQString& cmd, const TQStringList& files, bool removeflag)
196 {
197  kdDebug(500) << "tdeprint: print command: " << cmd << endl;
198 
199  int result = 0;
200  DCOPClient *dclient = kapp->dcopClient();
201  if (!dclient || (!dclient->isAttached() && !dclient->attach()))
202  {
203  return result;
204  }
205 
206  TQByteArray data, replyData;
207  TQCString replyType;
208  TQDataStream arg( data, IO_WriteOnly );
209  arg << cmd;
210  arg << files;
211  arg << removeflag;
212  if (dclient->call( "kded", "tdeprintd", "print(TQString,TQStringList,bool)", data, replyType, replyData ))
213  {
214  if (replyType == "int")
215  {
216  TQDataStream _reply_stream( replyData, IO_ReadOnly );
217  _reply_stream >> result;
218  }
219  }
220  return result;
221 }
222 
223 void KPrinterImpl::statusMessage(const TQString& msg, KPrinter *printer)
224 {
225  kdDebug(500) << "tdeprint: status message: " << msg << endl;
226  TDEConfig *conf = KMFactory::self()->printConfig();
227  conf->setGroup("General");
228  if (!conf->readBoolEntry("ShowStatusMsg", true))
229  return;
230 
231  TQString message(msg);
232  if (printer && !msg.isEmpty())
233  message.prepend(i18n("Printing document: %1").arg(printer->docName())+"\n");
234 
235  DCOPClient *dclient = kapp->dcopClient();
236  if (!dclient || (!dclient->isAttached() && !dclient->attach()))
237  {
238  return;
239  }
240 
241  TQByteArray data;
242  TQDataStream arg( data, IO_WriteOnly );
243  arg << message;
244  arg << (int)getpid();
245  arg << kapp->caption();
246  dclient->send( "kded", "tdeprintd", "statusMessage(TQString,int,TQString)", data );
247 }
248 
249 bool KPrinterImpl::startPrinting(const TQString& cmd, KPrinter *printer, const TQStringList& files, bool flag)
250 {
251  statusMessage(i18n("Sending print data to printer: %1").arg(printer->printerName()), printer);
252 
253  TQString command(cmd), filestr;
254  TQStringList printfiles;
255  if (command.find("%in") == -1) command.append(" %in");
256 
257  for (TQStringList::ConstIterator it=files.begin(); it!=files.end(); ++it)
258  if (TQFile::exists(*it))
259  {
260  // quote filenames
261  filestr.append(quote(*it)).append(" ");
262  printfiles.append(*it);
263  }
264  else
265  kdDebug(500) << "File not found: " << (*it) << endl;
266 
267  if (printfiles.count() > 0)
268  {
269  command.replace("%in",filestr);
270  int pid = dcopPrint(command,files,flag);
271  if (pid > 0)
272  {
273  if (printer)
274  KMThreadJob::createJob(pid,printer->printerName(),printer->docName(),getenv("USER"),0);
275  return true;
276  }
277  else
278  {
279  TQString msg = i18n("Unable to start child print process. ");
280  if (pid == 0)
281  msg += i18n("The TDE print server (<b>tdeprintd</b>) could not be contacted. Check that this server is running.");
282  else
283  msg += i18n("1 is the command that <files> is given to", "Check the command syntax:\n%1 <files>").arg(cmd);
284  printer->setErrorMessage(msg);
285  return false;
286  }
287  }
288  //else
289  //{
290  printer->setErrorMessage(i18n("No valid file was found for printing. Operation aborted."));
291  return false;
292  //}
293 }
294 
295 TQString KPrinterImpl::tempFile()
296 {
297  TQString f;
298  // be sure the file doesn't exist
299  do f = locateLocal("tmp","tdeprint_") + TDEApplication::randomString(8); while (TQFile::exists(f));
300  return f;
301 }
302 
303 int KPrinterImpl::filterFiles(KPrinter *printer, TQStringList& files, bool flag)
304 {
305  TQStringList flist = TQStringList::split(',',printer->option("_kde-filters"),false);
306  TQMap<TQString,TQString> opts = printer->options();
307 
308  // generic page selection mechanism (using psselect filter)
309  // do it only if:
310  // - using system-side page selection
311  // - special printer or regular printer without page selection support in current plugin
312  // - one of the page selection option has been selected to non default value
313  // Action -> add the psselect filter to the filter chain.
314  if (printer->pageSelection() == KPrinter::SystemSide &&
315  (printer->option("kde-isspecial") == "1" || !(KMFactory::self()->uiManager()->pluginPageCap() & KMUiManager::PSSelect)) &&
316  (printer->pageOrder() == KPrinter::LastPageFirst ||
317  !printer->option("kde-range").isEmpty() ||
318  printer->pageSet() != KPrinter::AllPages))
319  {
320  if (flist.findIndex("psselect") == -1)
321  {
322  int index = KXmlCommandManager::self()->insertCommand(flist, "psselect", false);
323  if (index == -1 || !KXmlCommandManager::self()->checkCommand("psselect"))
324  {
325  printer->setErrorMessage(i18n("<p>Unable to perform the requested page selection. The filter <b>psselect</b> "
326  "cannot be inserted in the current filter chain. See <b>Filter</b> tab in the "
327  "printer properties dialog for further information.</p>"));
328  return -1;
329  }
330  }
331  if (printer->pageOrder() == KPrinter::LastPageFirst)
332  opts["_kde-psselect-order"] = "r";
333  if (!printer->option("kde-range").isEmpty())
334  opts["_kde-psselect-range"] = printer->option("kde-range");
335  if (printer->pageSet() != KPrinter::AllPages)
336  opts["_kde-psselect-set"] = (printer->pageSet() == KPrinter::OddPages ? "-o" : "-e");
337  }
338 
339  return doFilterFiles(printer, files, flist, opts, flag);
340 }
341 
342 int KPrinterImpl::doFilterFiles(KPrinter *printer, TQStringList& files, const TQStringList& flist, const TQMap<TQString,TQString>& opts, bool flag)
343 {
344  // nothing to do
345  if (flist.count() == 0)
346  return 0;
347 
348  TQString filtercmd;
349  TQStringList inputMimeTypes;
350  for (uint i=0;i<flist.count();i++)
351  {
352  KXmlCommand *filter = KXmlCommandManager::self()->loadCommand(flist[i]);
353  if (!filter)
354  {
355  printer->setErrorMessage(i18n("<p>Could not load filter description for <b>%1</b>.</p>").arg(flist[i]));
356  return -1; // Error
357  }
358  if (i == 0)
359  inputMimeTypes = filter->inputMimeTypes();
360 
361  TQString subcmd = filter->buildCommand(opts,(i>0),(i<(flist.count()-1)));
362  delete filter;
363  if (!subcmd.isEmpty())
364  {
365  filtercmd.append(subcmd);
366  if (i < flist.count()-1)
367  filtercmd.append("| ");
368  }
369  else
370  {
371  printer->setErrorMessage(i18n("<p>Error while reading filter description for <b>%1</b>. Empty command line received.</p>").arg(flist[i]));
372  return -1;
373  }
374  }
375  kdDebug(500) << "tdeprint: filter command: " << filtercmd << endl;
376 
377  TQString rin("%in"), rout("%out"), rpsl("%psl"), rpsu("%psu");
378  TQString ps = pageSizeToPageName( printer->option( "kde-printsize" ).isEmpty() ? printer->pageSize() : ( KPrinter::PageSize )printer->option( "kde-printsize" ).toInt() );
379  for (TQStringList::Iterator it=files.begin(); it!=files.end(); ++it)
380  {
381  TQString mime = KMimeMagic::self()->findFileType(*it)->mimeType();
382  if (inputMimeTypes.find(mime) == inputMimeTypes.end())
383  {
384  if (KMessageBox::warningContinueCancel(0,
385  "<p>" + i18n("The MIME type %1 is not supported as input of the filter chain "
386  "(this may happen with non-CUPS spoolers when performing page selection "
387  "on a non-PostScript file). Do you want TDE to convert the file to a supported "
388  "format?</p>").arg(mime),
389  TQString::null, i18n("Convert")) == KMessageBox::Continue)
390  {
391  TQStringList ff;
392  int done(0);
393 
394  ff << *it;
395  while (done == 0)
396  {
397  bool ok(false);
398  TQString targetMime = KInputDialog::getItem(
399  i18n("Select MIME Type"),
400  i18n("Select the target format for the conversion:"),
401  inputMimeTypes, 0, false, &ok);
402  if (!ok)
403  {
404  printer->setErrorMessage(i18n("Operation aborted."));
405  return -1;
406  }
407  TQStringList filters = KXmlCommandManager::self()->autoConvert(mime, targetMime);
408  if (filters.count() == 0)
409  {
410  KMessageBox::error(0, i18n("No appropriate filter found. Select another target format."));
411  }
412  else
413  {
414  int result = doFilterFiles(printer, ff, filters, TQMap<TQString,TQString>(), flag);
415  if (result == 1)
416  {
417  *it = ff[0];
418  done = 1;
419  }
420  else
421  {
422  KMessageBox::error(0,
423  i18n("<qt>Operation failed with message:<br>%1<br>Select another target format.</qt>").arg(printer->errorMessage()));
424  }
425  }
426  }
427  }
428  else
429  {
430  printer->setErrorMessage(i18n("Operation aborted."));
431  return -1;
432  }
433  }
434 
435  TQString tmpfile = tempFile();
436  TQString cmd(filtercmd);
437  cmd.replace(rout,quote(tmpfile));
438  cmd.replace(rpsl,ps.lower());
439  cmd.replace(rpsu,ps);
440  cmd.replace(rin,quote(*it)); // Replace as last, filename could contain "%psl"
441  statusMessage(i18n("Filtering print data"), printer);
442  int status = system(TQFile::encodeName(cmd));
443  if (status < 0 || WEXITSTATUS(status) == 127)
444  {
445  printer->setErrorMessage(i18n("Error while filtering. Command was: <b>%1</b>.").arg(filtercmd));
446  return -1;
447  }
448  if (flag) TQFile::remove(*it);
449  *it = tmpfile;
450  }
451  return 1;
452 }
453 
454 int KPrinterImpl::autoConvertFiles(KPrinter *printer, TQStringList& files, bool flag)
455 {
456  TQString primaryMimeType = "application/postscript";
457  TQStringList mimeTypes( primaryMimeType );
458  if ( printer->option( "kde-isspecial" ) == "1" )
459  {
460  if ( !printer->option( "kde-special-command" ).isEmpty() )
461  {
462  KXmlCommand *cmd = KXmlCommandManager::self()->loadCommand( printer->option( "kde-special-command" ), true );
463  if ( cmd )
464  {
465  mimeTypes = cmd->inputMimeTypes();
466  // FIXME: the XML command description should now contain a primiary
467  // mime type as well. This is a temporary-only solution.
468  primaryMimeType = mimeTypes[ 0 ];
469  }
470  }
471  }
472  else
473  {
474  KMFactory::PluginInfo info = KMFactory::self()->pluginInfo(KMFactory::self()->printSystem());
475  mimeTypes = info.mimeTypes;
476  primaryMimeType = info.primaryMimeType;
477  }
478  KMFactory::PluginInfo info = KMFactory::self()->pluginInfo(KMFactory::self()->printSystem());
479  int status(0), result;
480  for (TQStringList::Iterator it=files.begin(); it!=files.end(); )
481  {
482  TQString mime = KMimeMagic::self()->findFileType(*it)->mimeType();
483  if ( mime == "application/x-zerosize" )
484  {
485  // special case of empty file
486  KMessageBox::information( NULL,
487  i18n( "<qt>The print file is empty and will be ignored:<p>%1</p></qt>" ).arg( *it ),
488  TQString::null, "emptyFileNotPrinted" );
489  if ( flag )
490  TQFile::remove( *it );
491  it = files.remove( it );
492  continue;
493  }
494  else if (mimeTypes.findIndex(mime) == -1)
495  {
496  if ((result=KMessageBox::warningYesNoCancel(NULL,
497  i18n("<qt>The file format <em> %1 </em> is not directly supported by the current print system. You "
498  "now have 3 options: "
499  "<ul> "
500  "<li> TDE can attempt to convert this file automatically to a supported format. "
501  "(Select <em>Convert</em>) </li>"
502  "<li> You can try to send the file to the printer without any conversion. "
503  "(Select <em>Keep</em>) </li>"
504  "<li> You can cancel the printjob. "
505  "(Select <em>Cancel</em>) </li>"
506  "</ul> "
507  "Do you want TDE to attempt and convert this file to %2?</qt>").arg(mime).arg(primaryMimeType),
508  TQString::null,
509  i18n("Convert"),
510  i18n("Keep"),
511  TQString::fromLatin1("tdeprintAutoConvert"))) == KMessageBox::Yes)
512  {
513  // find the filter chain
514  TQStringList flist = KXmlCommandManager::self()->autoConvert(mime, primaryMimeType);
515  if (flist.count() == 0)
516  {
517  KMessageBox::error(NULL,
518  i18n("<qt>No appropriate filter was found to convert the file format %1 into %2.<br>"
519  "<ul>"
520  "<li>Go to <i>System Options -> Commands</i> to look through the list of "
521  "possible filters. Each filter executes an external program.</li>"
522  "<li> See if the required external program is available.on your "
523  "system.</li>"
524  "</ul>"
525  "</qt>").arg(mime).arg(primaryMimeType),
526  i18n("Print"));
527  if (flag)
528  TQFile::remove(*it);
529  it = files.remove(it);
530  continue;
531  }
532  TQStringList l(*it);
533  switch (doFilterFiles(printer, l, flist, TQMap<TQString,TQString>(), flag))
534  {
535  case -1:
536  return -1;
537  case 0:
538  break;
539  case 1:
540  status = 1;
541  *it = l[0];
542  break;
543  }
544  }
545  else if (result == KMessageBox::Cancel)
546  {
547  files.clear();
548  return 0;
549  }
550  }
551  ++it;
552  }
553  return status;
554 }
555 
556 bool KPrinterImpl::setupSpecialCommand(TQString& cmd, KPrinter *p, const TQStringList&)
557 {
558  TQString s(p->option("kde-special-command"));
559  if (s.isEmpty())
560  {
561  p->setErrorMessage("Empty command.");
562  return false;
563  }
564 
565  s = KMFactory::self()->specialManager()->setupCommand(s, p->options());
566 
567  TQString ps = pageSizeToPageName( p->option( "kde-printsize" ).isEmpty() ? p->pageSize() : ( KPrinter::PageSize )p->option( "kde-printsize" ).toInt() );
568  s.replace("%psl", ps.lower());
569  s.replace("%psu", ps);
570  s.replace("%out", "$out{" + p->outputFileName() + "}"); // Replace as last
571  cmd = s;
572  return true;
573 }
574 
575 TQString KPrinterImpl::quote(const TQString& s)
576 { return TDEProcess::quote(s); }
577 
578 void KPrinterImpl::saveOptions(const TQMap<TQString,TQString>& opts)
579 {
580  m_options = opts;
581  saveAppOptions();
582 }
583 
584 void KPrinterImpl::loadAppOptions()
585 {
586  TDEConfig *conf = TDEGlobal::config();
587  conf->setGroup("KPrinter Settings");
588  TQStringList opts = conf->readListEntry("ApplicationOptions");
589  for (uint i=0; i<opts.count(); i+=2)
590  if (opts[i].startsWith("app-"))
591  m_options[opts[i]] = opts[i+1];
592 }
593 
594 void KPrinterImpl::saveAppOptions()
595 {
596  TQStringList optlist;
597  for (TQMap<TQString,TQString>::ConstIterator it=m_options.begin(); it!=m_options.end(); ++it)
598  if (it.key().startsWith("app-"))
599  optlist << it.key() << it.data();
600 
601  TDEConfig *conf = TDEGlobal::config();
602  conf->setGroup("KPrinter Settings");
603  conf->writeEntry("ApplicationOptions", optlist);
604 }
605 
606 #include "kprinterimpl.moc"
KPrinter
This class is the main interface to access the TDE print framework.
Definition: kprinter.h:89
KPrinter::docName
TQString docName() const
See TQPrinter::docName().
Definition: kprinter.cpp:797
KPrinter::PageSize
PageSize
Defines the paper size to use.
Definition: kprinter.h:168
KPrinter::option
const TQString & option(const TQString &key) const
Starts the add printer wizard.
Definition: kprinter.cpp:791
KPrinter::outputToFile
bool outputToFile() const
See TQPrinter::outputToFile().
Definition: kprinter.cpp:925
KPrinter::setRealPageSize
void setRealPageSize(TQSize p)
DO NOT USE, WILL BE REMOVED.
Definition: kprinter.cpp:992
KPrinter::setErrorMessage
void setErrorMessage(const TQString &msg)
Sets the last error message.
Definition: kprinter.cpp:1016
KPrinter::printerName
TQString printerName() const
See TQPrinter::printerName().
Definition: kprinter.cpp:870
KPrinter::outputFileName
TQString outputFileName() const
See TQPrinter::outputFileName().
Definition: kprinter.cpp:919
KPrinter::setOption
void setOption(const TQString &key, const TQString &value)
Adds or modifies an option in the KPrinter object.
Definition: kprinter.cpp:794
KPrinter::pageSize
PageSize pageSize() const
See TQPrinter::pageSize().
Definition: kprinter.cpp:858
KPrinter::options
const TQMap< TQString, TQString > & options() const
Returns the complete set of print options from the KPrinter object.
Definition: kprinter.cpp:903
KPrinter::pageSet
PageSetType pageSet() const
Returns the page set of the current KPrinter object.
Definition: kprinter.cpp:861
KPrinter::pageOrder
PageOrder pageOrder() const
See TQPrinter::pageOrder().
Definition: kprinter.cpp:827
KPrinter::pageSelection
static PageSelectionType pageSelection()
Returns the page selection mode of the current application.
Definition: kprinter.cpp:260
KPrinter::errorMessage
TQString errorMessage() const
Returns the last error message issued by the print system.
Definition: kprinter.cpp:1013

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