• 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 <tdestandarddirs.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
48void dumpOptions(const TQMap<TQString,TQString>&);
49void initEditPrinter(KMPrinter *p)
50{
51 if (!p->isEdited())
52 {
53 p->setEditedOptions(p->defaultOptions());
54 p->setEdited(true);
55 }
56}
57
58//****************************************************************************************
59
60KPrinterImpl::KPrinterImpl(TQObject *parent, const char *name)
61: TQObject(parent,name)
62{
63 loadAppOptions();
64}
65
66KPrinterImpl::~KPrinterImpl()
67{
68}
69
70void 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
135bool KPrinterImpl::setupCommand(TQString&, KPrinter*)
136{
137 return false;
138}
139
140bool 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
180void 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
195int 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 = tdeApp->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
223void 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 = tdeApp->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 << tdeApp->caption();
246 dclient->send( "kded", "tdeprintd", "statusMessage(TQString,int,TQString)", data );
247}
248
249bool 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
295TQString 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
303int 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
342int 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
454int 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
556bool 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
575TQString KPrinterImpl::quote(const TQString& s)
576{ return TDEProcess::quote(s); }
577
578void KPrinterImpl::saveOptions(const TQMap<TQString,TQString>& opts)
579{
580 m_options = opts;
581 saveAppOptions();
582}
583
584void 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
594void 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.4
This website is maintained by Timothy Pearson.