| # kdeprint Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# kprintdialog.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 /*
    00021  *  "WhatsThis" help items added by Kurt Pfeifle, August 2003,
    00022  *  same copyright as above.
    00023  **/
    00024
    00025 #include "kprintdialog.h"
    00026 #include "kprinter.h"
    00027 #include "kprinterimpl.h"
    00028 #include "kmfactory.h"
    00029 #include "kmuimanager.h"
    00030 #include "kmmanager.h"
    00031 #include "kmprinter.h"
    00032 #include "kmvirtualmanager.h"
    00033 #include "kprintdialogpage.h"
    00034 #include "kprinterpropertydialog.h"
    00035 #include "plugincombobox.h"
    00036 #include "kpcopiespage.h"
    00037 #include "treecombobox.h"
    00038 #include "messagewindow.h"
    00039
    00040 #include <qgroupbox.h>
    00041 #include <qcheckbox.h>
    00042 #include <kpushbutton.h>
    00043 #include <qlabel.h>
    00044 #include <qcombobox.h>
    00045 #include <qtabwidget.h>
    00046 #include <qvbox.h>
    00047 #include <qlayout.h>
    00048 #include <qregexp.h>
    00049 #include <kmessagebox.h>
    00050 #include <qdir.h>
    00051 #include <qtooltip.h>
    00052 #include <qwhatsthis.h>
    00053
    00054 #include <klocale.h>
    00055 #include <kiconloader.h>
    00056 #include <kfiledialog.h>
    00057 #include <kurlrequester.h>
    00058 #include <klineedit.h>
    00059 #include <kdebug.h>
    00060 #include <kglobal.h>
    00061 #include <kconfig.h>
    00062 #include <kguiitem.h>
    00063 #include <kstdguiitem.h>
    00064 #include <kapplication.h>
    00065 #include <kio/renamedlg.h>
    00066
    00067 #include <time.h>
    00068
    00069 #define SHOWHIDE(widget,on) if (on) widget->show(); else widget->hide();
    00070
    00071 class KPrintDialog::KPrintDialogPrivate
    00072 {
    00073 public:
    00074     QLabel  *m_type, *m_state, *m_comment, *m_location, *m_cmdlabel, *m_filelabel;
    00075     KPushButton *m_properties, *m_default, *m_options, *m_ok, *m_extbtn;
    00076     QPushButton *m_wizard, *m_filter;
    00077     QCheckBox   *m_preview;
    00078     QLineEdit   *m_cmd;
    00079     TreeComboBox    *m_printers;
    00080     QVBox       *m_dummy;
    00081     PluginComboBox  *m_plugin;
    00082     KURLRequester   *m_file;
    00083     QCheckBox   *m_persistent;
    00084     bool    m_reduced;
    00085
    00086     QPtrList<KPrintDialogPage>  m_pages;
    00087     KPrinter        *m_printer;
    00088     bool b_optionsEnabled;
    00089     bool b_propertiesEnabled;
    00090     bool b_systemEnabled;
    00091 };
    00092
    00093 KPrintDialog::KPrintDialog(QWidget *parent, const char *name)
    00094 : KDialog(parent,name,true)
    00095 {
    00096     //WhatsThis strings.... (added by pfeifle@kde.org)
    00097     QString whatsThisLocationLabel = i18n(  " <qt><b>Printer Location:</b> The <em>Location</em> may describe where the"
    00098                         " selected printer is located. The Location description is created"
    00099                         " by the administrator of the print system (or may be"
    00100                         " left empty)."
    00101                         " </qt>" );
    00102     QString whatsThisPrinterType = i18n(    " <qt><b>Printer Type:</b>  The <em>Type</em> indicates your printer type."
    00103                         " </qt>" );
    00104     QString whatsThisPrinterState = i18n(   " <qt><b>Printer State:</b>  The <em>State</em> indicates the state of the"
    00105                         " print queue on the print server (which could be your localhost). The"
    00106                         " state may be 'Idle', 'Processing', 'Stopped', 'Paused' or similar."
    00107                         " </qt>" );
    00108     QString whatsThisPrinterComment = i18n( " <qt><b>Printer Comment:</b>  The <em>Comment</em> may describe the selected"
    00109                         " printer. This comment is created by the administrator"
    00110                         " of the print system (or may be left empty)."
    00111                         " </qt>" );
    00112     QString whatsThisPrinterSelect = i18n(  " <qt><b>Printer Selection Menu:</b> "
    00113                         " <p>Use this combo box to select the printer to which you want to print."
    00114                         " Initially (if you run KDEPrint for the first time), you may only find the "
    00115                         "  <em>KDE special printers</em> (which save"
    00116                         " jobs to disk [as PostScript- or PDF-files], or deliver jobs via"
    00117                         " email (as a PDF"
    00118                         " attachment). If you are missing a real printer, you need to..."
    00119                         " <ul>"
    00120                         " <li>...either create a local printer with the help of the <em>KDE Add"
    00121                         " Printer Wizard</em>. The Wizard is available for the CUPS and RLPR printing"
    00122                         " systems (click button to the left of the <em>'Properties'</em> button),</li>"
    00123                         " <li>...or try to connect to an existing remote"
    00124                         " CUPS print server. You can connect by clicking the <em>'System Options'</em> button"
    00125                         " below. A new dialog opens: click on the <em>'CUPS server'</em>"
    00126                         " icon: Fill in the information required to use the remote"
    00127                         " server. </li> "
    00128                         " </ul>"
    00129                         " <p><b>Note:</b> It may happen that you successfully connected to a remote CUPS "
    00130                         " server and still do not get a printer list. If this happens: force KDEPrint to "
    00131                         " re-load its configuration files."
    00132                         " To reload the configuration files, either start kprinter again, or use the "
    00133                         " switch the print system away from CUPS and back again once. The print system switch "
    00134                         " can be made through a selection in the drop-down menu at bottom of this dialog when "
    00135                         " fully expanded). </p> "
    00136                         " </qt>" );
    00137     QString whatsThisPrintJobProperties = i18n( " <qt><b>Print Job Properties:</b> "
    00138                         " <p>This button opens a dialog where you can make decisions"
    00139                         " regarding all supported print job options."
    00140                         " </qt>" );
    00141     QString whatsThisPrinterFilter = i18n(  " <qt><b>Selective View on List of Printers:</b>"
    00142                         " <p> This button reduces the list of visible printers"
    00143                         " to a shorter, more convenient, pre-defined list.</p>"
    00144                         " <p>This is particularly useful in enterprise environments"
    00145                         " with lots of printers. The default is to show <b>all</b> printers.</p>"
    00146                         " <p>To create a personal <em>'selective view list'</em>, click on the"
    00147                         " <em>'System Options'</em> button at the bottom of this dialog."
    00148                         " Then, in the new dialog, select <em>'Filter'</em> (left column in the"
    00149                         " <em>KDE Print Configuration</em> dialog) and setup your selection..</p>"
    00150                         " <p><b>Warning:</b> Clicking this button without prior creation of a personal "
    00151                         " <em>'selective view list'</em> will make all printers dissappear from the "
    00152                         " view. (To re-enable all printers, just click this button again.) </p> "
    00153                         " </qt>" );
    00154     QString whatsThisAddPrinterWizard = i18n( "<qt><b>KDE Add Printer Wizard</b>"
    00155                         " <p>This button starts the <em>KDE Add Printer Wizard</em>.</p>"
    00156                         " <p>Use the Wizard (with <em>\"CUPS\"</em> or <em>\"RLPR\"</em>) to add locally"
    00157                         " defined printers to your system. </p>"
    00158                         " <p><b>Note:</b> The <em>KDE Add Printer Wizard</em> does <b>not</b> work, "
    00159                         " and this button is disabled if you use "
    00160                         " <em>\"Generic LPD</em>\", <em>\"LPRng\"</em>, or <em>\"Print Through "
    00161                         " an External Program</em>\".) </p> "
    00162                         " </qt>" );
    00163     QString whatsThisExternalPrintCommand = i18n( " <qt><b>External Print Command</b>"
    00164                         " <p>Here you can enter any command that would also print for you in "
    00165                         " a <em>konsole</em> window. </p>"
    00166                         " <b>Example:</b> <pre>a2ps -P &lt;printername&gt; --medium=A3</pre>."
    00167                         " </qt>" );
    00168     QString whatsThisOptions = i18n( " <qt><b>Additional Print Job Options</b>"
    00169                         " <p>This button shows or hides additional printing options.</qt>" );
    00170     QString whatsThisSystemOptions = i18n(  " <qt><b>System Options:</b> "
    00171                         " <p>This button starts a new dialog where you can adjust various"
    00172                         " settings of your printing system. Amongst them:"
    00173                         " <ul><li> Should KDE"
    00174                         " applications embed all fonts into the PostScript they"
    00175                         " generate for printing?"
    00176                         " <li> Should KDE use an external PostScript viewer"
    00177                         " like <em>gv</em> for print page previews?"
    00178                         " <li> Should KDEPrint use a local or a remote CUPS server?,"
    00179                         " </ul> and many more.... "
    00180                             " </qt>" );
    00181
    00182     QString whatsThisHelpButton = i18n(     " <qt><b>Help:</b> This button takes you to the complete <em>KDEPrint"
    00183                         " Manual</em>."
    00184                             " </qt>" );
    00185
    00186     QString whatsThisCancelButton = i18n(   " <qt><b>Cancel:</b> This button cancels your print job and quits the"
    00187                         " kprinter dialog."
    00188                             " </qt>" );
    00189
    00190     QString whatsThisPrintButton = i18n(    " <qt><b>Print:</b> This button sends the job to the printing process."
    00191                         " If you are sending non-PostScript files, you may be"
    00192                         " asked if you want KDE to convert the files into PostScript,"
    00193                         " or if you want your print subsystem (like CUPS) to do this."
    00194                             " </qt>" );
    00195
    00196     QString whatsThisKeepDialogOpenCheckbox = i18n( " <qt><b>Keep Printing Dialog Open</b>"
    00197                         "<p>If you enable this checkbox, the printing dialog"
    00198                         " stays open after you hit the <em>Print</em> button.</p>"
    00199                         " <p> This is"
    00200                         " especially useful, if you need to test various"
    00201                         " print settings (like color matching for an inkjet printer)"
    00202                         " or if you want to send your job to multiple printers (one after"
    00203                         " the other) to have it finished more quickly.</p>"
    00204                             " </qt>" );
    00205
    00206     QString whatsThisOutputFileLabel = i18n(" <qt><b>Output File Name and Path:</b> The \"Output file:\" shows "
    00207                         " you where your file will be"
    00208                         " saved if you decide to \"Print to File\" your job, using one of the"
    00209                         " KDE <em>Special Printers</em> named \"Print to File (PostScript)\""
    00210                         " or \"Print to File (PDF)\". Choose a name and location that suits"
    00211                         " your need by using the button and/or editing the line on the right."
    00212                             " </qt>" );
    00213
    00214     QString whatsThisOutputFileLineedit = i18n(" <qt><b>Output File Name and Path:</b> Edit this line to create a "
    00215                         " path and filename that suits your needs."
    00216                         " (Button and Lineedit field are only available if you \"Print to File\")"
    00217                             " </qt>" );
    00218
    00219     QString whatsThisOutputFileButton = i18n(" <qt><b>Browse Directories button:<b> This button calls "
    00220                         " the \"File Open / Browsed Directories\" dialog to let you"
    00221                         " choose a directory and file name where your \"Print-to-File\""
    00222                         " job should be saved."
    00223                             " </qt>" );
    00224
    00225     QString whatsThisAddFileButton = i18n(  " <qt><b>Add File to Job</b>"
    00226                         " <p>This button calls the \"File Open / Browse Directories\" dialog to allow you"
    00227                         " to select a file for printing. Note, that "
    00228                         " <ul><li>you can select ASCII or International Text, PDF,"
    00229                         " PostScript, JPEG, TIFF, PNG, GIF and many other graphical"
    00230                         " formats."
    00231                         " <li>you can select various files from different paths"
    00232                         " and send them as one \"multi-file job\" to the printing"
    00233                         " system."
    00234                         " </ul>"
    00235                             " </qt>" );
    00236
    00237     QString whatsThisPreviewCheckBox = i18n(" <qt><b>Print Preview</b>"
    00238                         " Enable this checkbox if you want to see a preview of"
    00239                         " your printout. A preview lets you check if, for instance,"
    00240                         " your intended \"poster\" or \"pamphlet\" layout"
    00241                         " looks like you expected, without wasting paper first. It"
    00242                         " also lets you cancel the job if something looks wrong. "
    00243                         " <p><b>Note:</b> The preview feature (and therefore this checkbox) "
    00244                         " is only visible for printjobs created from inside KDE applications. "
    00245                         " If you start kprinter from the commandline, or if you use kprinter "
    00246                         " as a print command for non-KDE applications (like Acrobat Reader, "
    00247                                                 " Firefox or OpenOffice), print preview is not available here. "
    00248                             " </qt>" );
    00249
    00250     QString whatsThisSetDefaultPrinter = i18n(" <qt><b>Set as Default Printer</b>"
    00251                         " This button sets the current printer as the user's"
    00252                         " default. "
    00253                         " <p><b>Note:</b> (Button is only visible if the checkbox for "
    00254                         " <em>System Options</em>"
    00255                         " --> <em>General</em> --> <em>Miscellaneous</em>: <em>\"Defaults"
    00256                         " to the last printer used in the application\"</em> is disabled.)"
    00257                             " </qt>" );
    00258     d = new KPrintDialogPrivate;
    00259
    00260     d->m_pages.setAutoDelete(false);
    00261     d->m_printer = 0;
    00262     setCaption(i18n("Print"));
    00263
    00264     // widget creation
    00265     QGroupBox   *m_pbox = new QGroupBox(0,Qt::Vertical,i18n("Printer"), this);
    00266     d->m_type = new QLabel(m_pbox);
    00267     QWhatsThis::add(d->m_type, whatsThisPrinterType);
    00268     d->m_state = new QLabel(m_pbox);
    00269     QWhatsThis::add(d->m_state, whatsThisPrinterState);
    00270     d->m_comment = new QLabel(m_pbox);
    00271     QWhatsThis::add(d->m_comment, whatsThisPrinterComment);
    00272     d->m_location = new QLabel(m_pbox);
    00273     QWhatsThis::add(d->m_location, whatsThisLocationLabel);
    00274
    00275     d->m_printers = new TreeComboBox(m_pbox);
    00276     QWhatsThis::add(d->m_printers, whatsThisPrinterSelect);
    00277     d->m_printers->setMinimumHeight(25);
    00278     QLabel  *m_printerlabel = new QLabel(i18n("&Name:"), m_pbox);
    00279     QWhatsThis::add(m_printerlabel, whatsThisPrinterSelect);
    00280     QLabel  *m_statelabel = new QLabel(i18n("Status", "State:"), m_pbox);
    00281     QWhatsThis::add(m_statelabel, whatsThisPrinterState);
    00282     QLabel  *m_typelabel = new QLabel(i18n("Type:"), m_pbox);
    00283     QWhatsThis::add(m_typelabel, whatsThisPrinterType);
    00284     QLabel  *m_locationlabel = new QLabel(i18n("Location:"), m_pbox);
    00285     QWhatsThis::add(m_locationlabel, whatsThisLocationLabel);
    00286     QLabel  *m_commentlabel = new QLabel(i18n("Comment:"), m_pbox);
    00287     QWhatsThis::add(m_commentlabel, whatsThisPrinterComment);
    00288     m_printerlabel->setBuddy(d->m_printers);
    00289     d->m_properties = new KPushButton(KGuiItem(i18n("P&roperties"), "edit"), m_pbox);
    00290     QWhatsThis::add( d->m_properties, whatsThisPrintJobProperties);
    00291     d->m_options = new KPushButton(KGuiItem(i18n("System Op&tions"), "kdeprint_configmgr"), this);
    00292     QWhatsThis::add(d->m_options,whatsThisSystemOptions);
    00293     d->m_default = new KPushButton(KGuiItem(i18n("Set as &Default"), "kdeprint_defaultsoft"), m_pbox);
    00294     QWhatsThis::add(d->m_default,whatsThisSetDefaultPrinter);
    00295     d->m_filter = new QPushButton(m_pbox);
    00296     d->m_filter->setPixmap(SmallIcon("filter"));
    00297     d->m_filter->setMinimumSize(QSize(d->m_printers->minimumHeight(),d->m_printers->minimumHeight()));
    00298     d->m_filter->setToggleButton(true);
    00299     d->m_filter->setOn(KMManager::self()->isFilterEnabled());
    00300     QToolTip::add(d->m_filter, i18n("Toggle selective view on printer list"));
    00301     QWhatsThis::add(d->m_filter, whatsThisPrinterFilter);
    00302     d->m_wizard = new QPushButton(m_pbox);
    00303     d->m_wizard->setPixmap(SmallIcon("wizard"));
    00304     d->m_wizard->setMinimumSize(QSize(d->m_printers->minimumHeight(),d->m_printers->minimumHeight()));
    00305     QToolTip::add(d->m_wizard, i18n("Add printer..."));
    00306     QWhatsThis::add(d->m_wizard, whatsThisAddPrinterWizard);
    00307     d->m_ok = new KPushButton(KGuiItem(i18n("&Print"), "fileprint"), this);
    00308         QWhatsThis::add( d->m_ok, whatsThisPrintButton);
    00309     d->m_ok->setDefault(true);
    00310     d->m_ok->setEnabled( false );
    00311     QPushButton *m_cancel = new KPushButton(KStdGuiItem::cancel(), this);
    00312         QWhatsThis::add(m_cancel, whatsThisCancelButton);
    00313     d->m_preview = new QCheckBox(i18n("Previe&w"), m_pbox);
    00314     QWhatsThis::add(d->m_preview, whatsThisPreviewCheckBox);
    00315     d->m_filelabel = new QLabel(i18n("O&utput file:"), m_pbox);
    00316     QWhatsThis::add(d->m_filelabel,whatsThisOutputFileLabel);
    00317     d->m_file = new KURLRequester(QDir::homeDirPath()+"/print.ps", m_pbox);
    00318     QWhatsThis::add(d->m_file,whatsThisOutputFileLineedit);
    00319     d->m_file->setEnabled(false);
    00320     d->m_filelabel->setBuddy(d->m_file);
    00321     d->m_cmdlabel = new QLabel(i18n("Print co&mmand:"), m_pbox);
    00322         QWhatsThis::add( d->m_cmdlabel, whatsThisExternalPrintCommand);
    00323
    00324     d->m_cmd = new QLineEdit(m_pbox);
    00325         QWhatsThis::add( d->m_cmd, whatsThisExternalPrintCommand);
    00326     d->m_cmdlabel->setBuddy(d->m_cmd);
    00327     d->m_dummy = new QVBox(this);
    00328     d->m_plugin = new PluginComboBox(this);
    00329     d->m_extbtn = new KPushButton(this);
    00330     QToolTip::add(d->m_extbtn, i18n("Show/hide advanced options"));
    00331     QWhatsThis::add(d->m_extbtn, whatsThisOptions);
    00332     d->m_persistent = new QCheckBox(i18n("&Keep this dialog open after printing"), this);
    00333         QWhatsThis::add( d->m_persistent, whatsThisKeepDialogOpenCheckbox);
    00334     QPushButton *m_help = new KPushButton(KStdGuiItem::help(), this);
    00335         QWhatsThis::add( m_help, whatsThisHelpButton);
    00336
    00337     QWidget::setTabOrder( d->m_printers, d->m_filter );
    00338     QWidget::setTabOrder( d->m_filter, d->m_wizard );
    00339     QWidget::setTabOrder( d->m_wizard, d->m_properties );
    00340     QWidget::setTabOrder( d->m_properties, d->m_preview );
    00341     QWidget::setTabOrder( d->m_preview, d->m_file );
    00342     QWidget::setTabOrder( d->m_file, d->m_cmd );
    00343     QWidget::setTabOrder( d->m_plugin, d->m_persistent );
    00344     QWidget::setTabOrder( d->m_persistent, d->m_extbtn );
    00345     QWidget::setTabOrder( d->m_extbtn, d->m_options );
    00346     QWidget::setTabOrder( d->m_options, m_help );
    00347     QWidget::setTabOrder( m_help, d->m_ok );
    00348     QWidget::setTabOrder( d->m_ok, m_cancel );
    00349
    00350     // layout creation
    00351     QVBoxLayout *l1 = new QVBoxLayout(this, 10, 10);
    00352     l1->addWidget(m_pbox,0);
    00353     l1->addWidget(d->m_dummy,1);
    00354     l1->addWidget(d->m_plugin,0);
    00355     l1->addWidget(d->m_persistent);
    00356     QHBoxLayout *l2 = new QHBoxLayout(0, 0, 10);
    00357     l1->addLayout(l2);
    00358     l2->addWidget(d->m_extbtn,0);
    00359     l2->addWidget(d->m_options,0);
    00360     l2->addWidget(m_help,0);
    00361     l2->addStretch(1);
    00362     l2->addWidget(d->m_ok,0);
    00363     l2->addWidget(m_cancel,0);
    00364     QGridLayout *l3 = new QGridLayout(m_pbox->layout(),3,3,7);
    00365     l3->setColStretch(1,1);
    00366     l3->setRowStretch(0,1);
    00367     QGridLayout *l4 = new QGridLayout(0, 5, 2, 0, 5);
    00368     l3->addMultiCellLayout(l4,0,0,0,1);
    00369     l4->addWidget(m_printerlabel,0,0);
    00370     l4->addWidget(m_statelabel,1,0);
    00371     l4->addWidget(m_typelabel,2,0);
    00372     l4->addWidget(m_locationlabel,3,0);
    00373     l4->addWidget(m_commentlabel,4,0);
    00374     QHBoxLayout *ll4 = new QHBoxLayout(0, 0, 3);
    00375     l4->addLayout(ll4,0,1);
    00376     ll4->addWidget(d->m_printers,1);
    00377     ll4->addWidget(d->m_filter,0);
    00378     ll4->addWidget(d->m_wizard,0);
    00379     //l4->addWidget(d->m_printers,0,1);
    00380     l4->addWidget(d->m_state,1,1);
    00381     l4->addWidget(d->m_type,2,1);
    00382     l4->addWidget(d->m_location,3,1);
    00383     l4->addWidget(d->m_comment,4,1);
    00384     l4->setColStretch(1,1);
    00385     QVBoxLayout *l5 = new QVBoxLayout(0, 0, 10);
    00386     l3->addLayout(l5,0,2);
    00387     l5->addWidget(d->m_properties,0);
    00388     l5->addWidget(d->m_default,0);
    00389     l5->addWidget(d->m_preview,0);
    00390     l5->addStretch(1);
    00391     //***
    00392     l3->addWidget(d->m_filelabel,1,0);
    00393     l3->addWidget(d->m_file,1,1);
    00394     //***
    00395     l3->addWidget(d->m_cmdlabel,2,0);
    00396     l3->addMultiCellWidget(d->m_cmd,2,2,1,2);
    00397
    00398     // connections
    00399     connect(d->m_ok,SIGNAL(clicked()),SLOT(accept()));
    00400     connect(m_cancel,SIGNAL(clicked()),SLOT(reject()));
    00401     connect(d->m_properties,SIGNAL(clicked()),SLOT(slotProperties()));
    00402     connect(d->m_default,SIGNAL(clicked()),SLOT(slotSetDefault()));
    00403     connect(d->m_printers,SIGNAL(activated(int)),SLOT(slotPrinterSelected(int)));
    00404     connect(d->m_options,SIGNAL(clicked()),SLOT(slotOptions()));
    00405     connect(d->m_wizard,SIGNAL(clicked()),SLOT(slotWizard()));
    00406     connect(d->m_extbtn, SIGNAL(clicked()), SLOT(slotExtensionClicked()));
    00407     connect(d->m_filter, SIGNAL(toggled(bool)), SLOT(slotToggleFilter(bool)));
    00408     connect(m_help, SIGNAL(clicked()), SLOT(slotHelp()));
    00409     connect(d->m_file, SIGNAL(urlSelected(const QString&)), SLOT(slotOutputFileSelected(const QString&)));
    00410     connect( d->m_file, SIGNAL( openFileDialog( KURLRequester* ) ), SLOT( slotOpenFileDialog() ) );
    00411     connect( KMFactory::self()->manager(), SIGNAL( updatePossible( bool ) ), SLOT( slotUpdatePossible( bool ) ) );
    00412
    00413     d->b_optionsEnabled = kapp->authorize("print/options") && kapp->authorize("print/selection");
    00414     d->b_propertiesEnabled = kapp->authorize("print/properties") && kapp->authorize("print/selection");
    00415     d->b_systemEnabled = kapp->authorize("print/system") && kapp->authorize("print/selection");
    00416
    00417     if (!d->b_systemEnabled)
    00418     {
    00419         d->m_plugin->hide();
    00420     }
    00421
    00422     if (!d->b_optionsEnabled)
    00423     {
    00424         d->m_options->hide();
    00425     }
    00426
    00427     if (!d->b_propertiesEnabled)
    00428     {
    00429         d->m_properties->hide();
    00430         d->m_wizard->hide();
    00431     }
    00432
    00433     if (!kapp->authorize("print/selection"))
    00434     {
    00435         d->m_extbtn->hide();
    00436         m_pbox->hide();
    00437
    00438         expandDialog(true);
    00439     }
    00440     else
    00441     {
    00442         KConfig *config = KGlobal::config();
    00443         config->setGroup("KPrinter Settings");
    00444         expandDialog(!config->readBoolEntry("DialogReduced", (KMFactory::self()->settings()->application != KPrinter::StandAlone)));
    00445     }
    00446 }
    00447
    00448 KPrintDialog::~KPrintDialog()
    00449 {
    00450     KConfig *config = KGlobal::config();
    00451     config->setGroup("KPrinter Settings");
    00452     config->writeEntry("DialogReduced", d->m_reduced);
    00453
    00454     delete d;
    00455 }
    00456
    00457 void KPrintDialog::setFlags(int f)
    00458 {
    00459     SHOWHIDE(d->m_properties, (f & KMUiManager::Properties) && d->b_propertiesEnabled)
    00460     d->m_default->hide();
    00461     SHOWHIDE(d->m_default, ((f & KMUiManager::Default) && !KMFactory::self()->printConfig("General")->readBoolEntry("UseLast", true)))
    00462     SHOWHIDE(d->m_preview, (f & KMUiManager::Preview))
    00463     bool    on = (f & KMUiManager::OutputToFile);
    00464     SHOWHIDE(d->m_filelabel, on)
    00465     SHOWHIDE(d->m_file, on)
    00466     on = (f & KMUiManager::PrintCommand);
    00467     SHOWHIDE(d->m_cmdlabel, on)
    00468     SHOWHIDE(d->m_cmd, on)
    00469     SHOWHIDE(d->m_persistent, (f & KMUiManager::Persistent))
    00470
    00471     // also update "wizard" button
    00472     KMManager   *mgr = KMFactory::self()->manager();
    00473     d->m_wizard->setEnabled((mgr->hasManagement() && (mgr->printerOperationMask() & KMManager::PrinterCreation)));
    00474 }
    00475
    00476 void KPrintDialog::setDialogPages(QPtrList<KPrintDialogPage> *pages)
    00477 {
    00478     if (!pages) return;
    00479     if (pages->count() + d->m_pages.count() == 1)
    00480     {
    00481         // only one page, reparent the page to d->m_dummy and remove any
    00482         // QTabWidget child if any.
    00483         if (pages->count() > 0)
    00484             d->m_pages.append(pages->take(0));
    00485         d->m_pages.first()->reparent(d->m_dummy, QPoint(0,0));
    00486         d->m_pages.first()->show();
    00487         delete d->m_dummy->child("TabWidget", "QTabWidget");
    00488     }
    00489     else
    00490     {
    00491         // more than one page.
    00492         QTabWidget  *tabs = static_cast<QTabWidget*>(d->m_dummy->child("TabWidget", "QTabWidget"));
    00493         if (!tabs)
    00494         {
    00495             // QTabWidget doesn't exist. Create it and reparent all
    00496             // already existing pages.
    00497             tabs = new QTabWidget(d->m_dummy, "TabWidget");
    00498             tabs->setMargin(10);
    00499             for (d->m_pages.first(); d->m_pages.current(); d->m_pages.next())
    00500             {
    00501                 tabs->addTab(d->m_pages.current(), d->m_pages.current()->title());
    00502             }
    00503         }
    00504         while (pages->count() > 0)
    00505         {
    00506             KPrintDialogPage    *page = pages->take(0);
    00507             d->m_pages.append(page);
    00508             tabs->addTab(page, page->title());
    00509         }
    00510         tabs->show();
    00511     }
    00512     d->m_extbtn->setEnabled(d->m_pages.count() > 0);
    00513 }
    00514
    00515 KPrintDialog* KPrintDialog::printerDialog(KPrinter *printer, QWidget *parent, const QString& caption, bool forceExpand)
    00516 {
    00517     if (printer)
    00518     {
    00519         KPrintDialog    *dlg = new KPrintDialog(parent);
    00520         // needs to set the printer before setting up the
    00521         // print dialog as some additional pages may need it.
    00522         // Real initialization comes after.
    00523         dlg->d->m_printer = printer;
    00524         KMFactory::self()->uiManager()->setupPrintDialog(dlg);
    00525         dlg->init();
    00526         if (!caption.isEmpty())
    00527             dlg->setCaption(caption);
    00528         if (forceExpand)
    00529         {
    00530             // we force the dialog to be expanded:
    00531             //  - expand the dialog
    00532             //  - hide the show/hide button
    00533             dlg->expandDialog(true);
    00534             dlg->d->m_extbtn->hide();
    00535         }
    00536         return dlg;
    00537     }
    00538     return NULL;
    00539 }
    00540
    00541 void KPrintDialog::initialize(KPrinter *printer)
    00542 {
    00543     d->m_printer = printer;
    00544
    00545     // first retrieve printer list and update combo box (get default or last used printer also)
    00546     QPtrList<KMPrinter> *plist = KMFactory::self()->manager()->printerList();
    00547     if (!KMManager::self()->errorMsg().isEmpty())
    00548     {
    00549         KMessageBox::error(parentWidget(),
    00550             "<qt><nobr>"+
    00551             i18n("An error occurred while retrieving the printer list:")
    00552             +"</nobr><br><br>"+KMManager::self()->errorMsg()+"</qt>");
    00553     }
    00554
    00555     if (plist)
    00556     {
    00557         QString oldP = d->m_printers->currentText();
    00558         d->m_printers->clear();
    00559         QPtrListIterator<KMPrinter> it(*plist);
    00560         int     defsoft(-1), defhard(-1), defsearch(-1);
    00561         bool    sep(false);
    00562         for (;it.current();++it)
    00563         {
    00564             // skip invalid printers
    00565             if ( !it.current()->isValid() )
    00566                 continue;
    00567
    00568             if (!sep && it.current()->isSpecial())
    00569             {
    00570                 sep = true;
    00571                 d->m_printers->insertItem(QPixmap(), QString::fromLatin1("--------"));
    00572             }
    00573             d->m_printers->insertItem(SmallIcon(it.current()->pixmap(),0,(it.current()->isValid() ? (int)KIcon::DefaultState : (int)KIcon::LockOverlay)),it.current()->name(),false/*sep*/);
    00574             if (it.current()->isSoftDefault())
    00575                 defsoft = d->m_printers->count()-1;
    00576             if (it.current()->isHardDefault())
    00577                 defhard = d->m_printers->count()-1;
    00578             if (!oldP.isEmpty() && oldP == it.current()->name())
    00579                 defsearch = d->m_printers->count()-1;
    00580             else if (defsearch == -1 && it.current()->name() == printer->searchName())
    00581                 defsearch = d->m_printers->count()-1;
    00582         }
    00583         int defindex = (defsearch != -1 ? defsearch : (defsoft != -1 ? defsoft : QMAX(defhard,0)));
    00584         d->m_printers->setCurrentItem(defindex);
    00585         //slotPrinterSelected(defindex);
    00586     }
    00587
    00588     // Initialize output filename
    00589     if (!d->m_printer->outputFileName().isEmpty())
    00590         d->m_file->setURL( d->m_printer->outputFileName() );
    00591     else if (!d->m_printer->docFileName().isEmpty())
    00592         d->m_file->setURL( d->m_printer->docDirectory()+"/"+d->m_printer->docFileName()+".ps" );
    00593
    00594     if ( d->m_printers->count() > 0 )
    00595         slotPrinterSelected( d->m_printers->currentItem() );
    00596
    00597     // update with KPrinter options
    00598     if (d->m_printer->option("kde-preview") == "1" || d->m_printer->previewOnly())
    00599         d->m_preview->setChecked(true);
    00600     d->m_preview->setEnabled(!d->m_printer->previewOnly());
    00601     d->m_cmd->setText(d->m_printer->option("kde-printcommand"));
    00602     QPtrListIterator<KPrintDialogPage>  it(d->m_pages);
    00603     for (;it.current();++it)
    00604         it.current()->setOptions(d->m_printer->options());
    00605 }
    00606
    00607 void KPrintDialog::slotPrinterSelected(int index)
    00608 {
    00609     bool    ok(false);
    00610     d->m_location->setText(QString::null);
    00611     d->m_state->setText(QString::null);
    00612     d->m_comment->setText(QString::null);
    00613     d->m_type->setText(QString::null);
    00614     if (index >= 0 && index < d->m_printers->count())
    00615     {
    00616         KMManager   *mgr = KMFactory::self()->manager();
    00617         KMPrinter   *p = mgr->findPrinter(d->m_printers->text(index));
    00618         if (p)
    00619         {
    00620             if (!p->isSpecial()) mgr->completePrinterShort(p);
    00621             d->m_location->setText(p->location());
    00622             d->m_comment->setText(p->driverInfo());
    00623             d->m_type->setText(p->description());
    00624             d->m_state->setText(p->stateString());
    00625             ok = p->isValid();
    00626             enableSpecial(p->isSpecial());
    00627             enableOutputFile(p->option("kde-special-file") == "1");
    00628             setOutputFileExtension(p->option("kde-special-extension"));
    00629         }
    00630                 else
    00631                     enableOutputFile( ok );
    00632     }
    00633     d->m_properties->setEnabled(ok);
    00634     d->m_ok->setEnabled(ok);
    00635 }
    00636
    00637 void KPrintDialog::slotProperties()
    00638 {
    00639     if (!d->m_printer) return;
    00640
    00641     KMPrinter   *prt = KMFactory::self()->manager()->findPrinter(d->m_printers->currentText());
    00642     if (prt)
    00643         KPrinterPropertyDialog::setupPrinter(prt, this);
    00644 }
    00645
    00646 void KPrintDialog::slotSetDefault()
    00647 {
    00648     KMPrinter   *p = KMFactory::self()->manager()->findPrinter(d->m_printers->currentText());
    00649     if (p)
    00650         KMFactory::self()->virtualManager()->setDefault(p);
    00651 }
    00652
    00653 void KPrintDialog::done(int result)
    00654 {
    00655     if (result == Accepted && d->m_printer)
    00656     {
    00657         QMap<QString,QString>   opts;
    00658         KMPrinter       *prt(0);
    00659
    00660         // get options from global pages
    00661         QString msg;
    00662         QPtrListIterator<KPrintDialogPage>  it(d->m_pages);
    00663         for (;it.current();++it)
    00664             if (it.current()->isEnabled())
    00665             {
    00666                 if (it.current()->isValid(msg))
    00667                     it.current()->getOptions(opts);
    00668                 else
    00669                 {
    00670                     KMessageBox::error(this, msg.prepend("<qt>").append("</qt>"));
    00671                     return;
    00672                 }
    00673             }
    00674
    00675         // add options from the dialog itself
    00676         // TODO: ADD PRINTER CHECK MECHANISM !!!
    00677         prt = KMFactory::self()->manager()->findPrinter(d->m_printers->currentText());
    00678         if (prt->isSpecial() && prt->option("kde-special-file") == "1")
    00679         {
    00680             if (!checkOutputFile()) return;
    00681             d->m_printer->setOutputToFile(true);
    00682             /* be sure to decode the output filename */
    00683             d->m_printer->setOutputFileName( KURL::decode_string( d->m_file->url() ) );
    00684         }
    00685         else
    00686             d->m_printer->setOutputToFile(false);
    00687         d->m_printer->setPrinterName(prt->printerName());
    00688         d->m_printer->setSearchName(prt->name());
    00689         opts["kde-printcommand"] = d->m_cmd->text();
    00690         opts["kde-preview"] = (d->m_preview->isChecked() ? "1" : "0");
    00691         opts["kde-isspecial"] = (prt->isSpecial() ? "1" : "0");
    00692         opts["kde-special-command"] = prt->option("kde-special-command");
    00693
    00694         // merge options with KMPrinter object options
    00695         QMap<QString,QString>   popts = (prt->isEdited() ? prt->editedOptions() : prt->defaultOptions());
    00696         for (QMap<QString,QString>::ConstIterator it=popts.begin(); it!=popts.end(); ++it)
    00697             opts[it.key()] = it.data();
    00698
    00699         // update KPrinter object
    00700         d->m_printer->setOptions(opts);
    00701
    00702         emit printRequested(d->m_printer);
    00703         // close dialog if not persistent
    00704         if (!d->m_persistent->isChecked() || !d->m_persistent->isVisible())
    00705             KDialog::done(result);
    00706     }
    00707     else
    00708         KDialog::done(result);
    00709 }
    00710
    00711 bool KPrintDialog::checkOutputFile()
    00712 {
    00713     bool    value(false);
    00714     if (d->m_file->url().isEmpty())
    00715         KMessageBox::error(this,i18n("The output filename is empty."));
    00716     else
    00717     {
    00718         KURL url( d->m_file->url() );
    00719         if ( !url.isLocalFile() )
    00720             return true;
    00721
    00722         bool    anotherCheck;
    00723         do
    00724         {
    00725         anotherCheck = false;
    00726         QFileInfo   f(url.path());
    00727         if (f.exists())
    00728         {
    00729             if (f.isWritable())
    00730             {
    00731                 //value = (KMessageBox::warningYesNo(this,i18n("File \"%1\" already exists. Overwrite?").arg(f.absFilePath())) == KMessageBox::Yes);
    00732                 time_t mtimeDest = f.lastModified().toTime_t();
    00733                 KIO::RenameDlg dlg( this, i18n( "Print" ), QString::null, d->m_file->url(),
    00734                         KIO::M_OVERWRITE, ( time_t ) -1, f.size(), ( time_t ) -1, f.created().toTime_t() , mtimeDest+1, mtimeDest, true );
    00735                 int result = dlg.exec();
    00736                 switch ( result )
    00737                 {
    00738                     case KIO::R_OVERWRITE:
    00739                         value = true;
    00740                         break;
    00741                     default:
    00742                     case KIO::R_CANCEL:
    00743                         value = false;
    00744                         break;
    00745                     case KIO::R_RENAME:
    00746                         url = dlg.newDestURL();
    00747                         d->m_file->setURL( url.path() );
    00748                         value = true;
    00749                         anotherCheck = true;
    00750                         break;
    00751                 }
    00752             }
    00753             else
    00754                 KMessageBox::error(this,i18n("You don't have write permissions to this file."));
    00755         }
    00756         else
    00757         {
    00758             QFileInfo d( f.dirPath( true ) );
    00759             if ( !d.exists() )
    00760                 KMessageBox::error( this, i18n( "The output directory does not exist." ) );
    00761             else if ( !d.isWritable() )
    00762                 KMessageBox::error(this,i18n("You don't have write permissions in that directory."));
    00763             else
    00764                 value = true;
    00765         }
    00766         } while( anotherCheck );
    00767     }
    00768     return value;
    00769 }
    00770
    00771 void KPrintDialog::slotOptions()
    00772 {
    00773     if (KMManager::self()->invokeOptionsDialog(this))
    00774         init();
    00775 }
    00776
    00777 void KPrintDialog::enableOutputFile(bool on)
    00778 {
    00779     d->m_filelabel->setEnabled(on);
    00780     d->m_file->setEnabled(on);
    00781 }
    00782
    00783 void KPrintDialog::enableSpecial(bool on)
    00784 {
    00785     d->m_default->setDisabled(on);
    00786     d->m_cmdlabel->setDisabled(on);
    00787     d->m_cmd->setDisabled(on);
    00788     KPCopiesPage    *copypage = (KPCopiesPage*)child("CopiesPage","KPCopiesPage");
    00789     if (copypage)
    00790         copypage->initialize(!on);
    00791     // disable/enable all other pages (if needed)
    00792     for (d->m_pages.first(); d->m_pages.current(); d->m_pages.next())
    00793         if (d->m_pages.current()->onlyRealPrinters())
    00794             d->m_pages.current()->setEnabled(!on);
    00795 }
    00796
    00797 void KPrintDialog::setOutputFileExtension(const QString& ext)
    00798 {
    00799     if (!ext.isEmpty())
    00800     {
    00801         KURL url( d->m_file->url() );
    00802         QString f( url.fileName() );
    00803         int p = f.findRev( '.' );
    00804         // change "file.ext"; don't change "file", "file." or ".file" but do change ".file.ext"
    00805         if ( p > 0 && p != int (f.length () - 1) )
    00806         {
    00807             url.setFileName( f.left( p ) + "." + ext );
    00808             d->m_file->setURL( KURL::decode_string( url.url() ) );
    00809         }
    00810     }
    00811 }
    00812
    00813 void KPrintDialog::slotWizard()
    00814 {
    00815     int result = KMFactory::self()->manager()->addPrinterWizard(this);
    00816     if (result == -1)
    00817         KMessageBox::error(this, KMFactory::self()->manager()->errorMsg().prepend("<qt>").append("</qt>"));
    00818     else if (result == 1)
    00819         initialize(d->m_printer);
    00820 }
    00821
    00822 void KPrintDialog::reload()
    00823 {
    00824     // remove printer dependent pages (usually from plugin)
    00825     QTabWidget  *tabs = static_cast<QTabWidget*>(d->m_dummy->child("TabWidget", "QTabWidget"));
    00826     for (uint i=0; i<d->m_pages.count(); i++)
    00827         if (d->m_pages.at(i)->onlyRealPrinters())
    00828         {
    00829             KPrintDialogPage    *page = d->m_pages.take(i--);
    00830             if (tabs)
    00831                 tabs->removePage(page);
    00832             delete page;
    00833         }
    00834     // reload printer dependent pages from plugin
    00835     QPtrList<KPrintDialogPage>  pages;
    00836     pages.setAutoDelete(false);
    00837     KMFactory::self()->uiManager()->setupPrintDialogPages(&pages);
    00838     // add those pages to the dialog
    00839     setDialogPages(&pages);
    00840     if (!d->m_reduced)
    00841         d->m_dummy->show();
    00842     // other initializations
    00843     setFlags(KMFactory::self()->uiManager()->dialogFlags());
    00844     connect( KMFactory::self()->manager(), SIGNAL( updatePossible( bool ) ), SLOT( slotUpdatePossible( bool ) ) );
    00845     init();
    00846 }
    00847
    00848 void KPrintDialog::configChanged()
    00849 {
    00850     // simply update the printer list: do it all the time
    00851     // as changing settings may influence the way printer
    00852     // are listed.
    00853     init();
    00854
    00855     // update the GUI
    00856     setFlags(KMFactory::self()->uiManager()->dialogFlags());
    00857 }
    00858
    00859 void KPrintDialog::expandDialog(bool on)
    00860 {
    00861     QSize   sz(size());
    00862     bool    needResize(isVisible());
    00863
    00864     if (on)
    00865     {
    00866         sz.setHeight(sz.height()+d->m_dummy->minimumSize().height()+d->m_plugin->minimumSize().height()+2*layout()->spacing());
    00867         if (isVisible() || !d->m_dummy->isVisible() || !d->m_plugin->isVisible())
    00868         {
    00869             d->m_dummy->show();
    00870             if (d->b_systemEnabled)
    00871                 d->m_plugin->show();
    00872         }
    00873         d->m_extbtn->setIconSet(SmallIconSet("up"));
    00874         d->m_extbtn->setText(i18n("&Options <<"));
    00875         d->m_reduced = false;
    00876     }
    00877     else
    00878     {
    00879         sz.setHeight(sz.height()-d->m_dummy->height()-d->m_plugin->height()-2*layout()->spacing());
    00880         if (!isVisible() || d->m_dummy->isVisible() || d->m_plugin->isVisible())
    00881         {
    00882             d->m_dummy->hide();
    00883             if (d->b_systemEnabled)
    00884                 d->m_plugin->hide();
    00885         }
    00886         d->m_extbtn->setIconSet(SmallIconSet("down"));
    00887         d->m_extbtn->setText(i18n("&Options >>"));
    00888         d->m_reduced = true;
    00889     }
    00890
    00891     if (needResize)
    00892     {
    00893         layout()->activate();
    00894         resize(sz);
    00895     }
    00896 }
    00897
    00898 void KPrintDialog::slotExtensionClicked()
    00899 {
    00900     // As all pages are children of d->m_dummy, I simply have to hide/show it
    00901     expandDialog(!(d->m_dummy->isVisible()));
    00902 }
    00903
    00904 KPrinter* KPrintDialog::printer() const
    00905 {
    00906     return d->m_printer;
    00907 }
    00908
    00909 void KPrintDialog::slotToggleFilter(bool on)
    00910 {
    00911     KMManager::self()->enableFilter(on);
    00912     initialize(d->m_printer);
    00913 }
    00914
    00915 void KPrintDialog::slotHelp()
    00916 {
    00917     kapp->invokeHelp(QString::null, "kdeprint");
    00918 }
    00919
    00920 void KPrintDialog::slotOutputFileSelected(const QString& txt)
    00921 {
    00922     d->m_file->setURL( txt );
    00923 }
    00924
    00925 void KPrintDialog::init()
    00926 {
    00927     d->m_ok->setEnabled( false );
    00928     MessageWindow::remove( this );
    00929     MessageWindow::add( this, i18n( "Initializing printing system..." ), 500 );
    00930     KMFactory::self()->manager()->checkUpdatePossible();
    00931 }
    00932
    00933 void KPrintDialog::slotUpdatePossible( bool flag )
    00934 {
    00935     MessageWindow::remove( this );
    00936     if ( !flag )
    00937         KMessageBox::error(parentWidget(),
    00938             "<qt><nobr>"+
    00939             i18n("An error occurred while retrieving the printer list:")
    00940             +"</nobr><br><br>"+KMManager::self()->errorMsg()+"</qt>");
    00941     initialize( d->m_printer );
    00942 }
    00943
    00944 void KPrintDialog::enableDialogPage( int index, bool flag )
    00945 {
    00946     if ( index < 0 || index >= ( int )d->m_pages.count() )
    00947     {
    00948         kdWarning() << "KPrintDialog: page index out of bound" << endl;
    00949         return;
    00950     }
    00951
    00952     if ( d->m_pages.count() > 1 )
    00953     {
    00954         QTabWidget  *tabs = static_cast<QTabWidget*>(d->m_dummy->child("TabWidget", "QTabWidget"));
    00955         tabs->setTabEnabled( d->m_pages.at( index ), flag );
    00956     }
    00957     else
    00958         d->m_pages.at( 0 )->setEnabled( flag );
    00959 }
    00960
    00961 void KPrintDialog::slotOpenFileDialog()
    00962 {
    00963     KFileDialog *dialog = d->m_file->fileDialog();
    00964
    00965     dialog->setCaption(i18n("Print to File"));
    00966     dialog->setMode(d->m_file->fileDialog()->mode() & ~KFile::LocalOnly);
    00967     dialog->setOperationMode( KFileDialog::Saving );
    00968
    00969     KMPrinter *prt = KMFactory::self()->manager()->findPrinter(d->m_printers->currentText());
    00970     if (prt)
    00971     {
    00972         QString mimetype(prt->option("kde-special-mimetype"));
    00973         QString ext(prt->option("kde-special-extension"));
    00974
    00975         if (!mimetype.isEmpty())
    00976         {
    00977             QStringList filter;
    00978             filter << mimetype;
    00979             filter << "all/allfiles";
    00980             dialog->setMimeFilter (filter, mimetype);
    00981         }
    00982         else if (!ext.isEmpty())
    00983             dialog->setFilter ("*." + ext + "\n*|" + i18n ("All Files"));
    00984     }
    00985 }
    00986
    00987 #include "kprintdialog.moc"

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