Main Page · Namespace List · Alphabetical List · Class List · File List · Namespace Members · Class Members · File Members · Related Pages

guiprinterautosetup.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2005-2006 by Konrad Wilhelm Kleine
00003  *   konrad@plothe-kleine.de
00004  *
00005  *   This file contains the automatic printer setup implementation.
00006  *
00007  *   PLEASE NOTICE: If not stated otherwise, whenever we speak of 'printer
00008  *                  drivers' or simply 'drivers', we mean the PPD files
00009  *                  and not the actual drivers.
00010  *
00011  *   STATUS: File has been reviewed and commented
00012  *
00013  *   $Id: guiprinterautosetup.cpp,v 1.12 2006/04/23 16:06:22 hbci Exp $
00014  *
00015  *   This program is free software; you can redistribute it and/or modify
00016  *   it under the terms of the GNU General Public License as published by
00017  *   the Free Software Foundation; either version 2 of the License, or
00018  *   (at your option) any later version.
00019  *
00020  *   This program is distributed in the hope that it will be useful,
00021  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00022  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023  *   GNU General Public License for more details.
00024  *
00025  *   You should have received a copy of the GNU General Public License
00026  *   along with this program; if not, write to the Free Software Foundation,
00027  *   Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00028  ***************************************************************************/
00029 
00030 // App includes
00031 #include "guiprinterautosetup.h"
00032 #include "printersetupdb.h"
00033 #include "globals.h"
00034 #include "globalsprintersetup.h"
00035 using namespace LinuxPrinterSetup;
00036 
00037 // Qt includes
00038 #include <qfile.h>
00039 #include <qdir.h>
00040 #include <qlistbox.h>
00041 #include <qtextstream.h>
00042 #include <qmessagebox.h>
00043 #include <qregexp.h>
00044 #include <qdom.h>
00045 #include <qapplication.h>
00046 #include <qcheckbox.h>
00047 #include <qlabel.h>
00048 #include <qpushbutton.h>
00049 #include <qcursor.h>
00050 #include <qdialog.h>
00051 #include <qpixmap.h>
00052 
00053 // Other includes
00054 #include <stdlib.h>
00055 using namespace std;
00056 
00057 
00063 GuiPrinterAutoSetup::GuiPrinterAutoSetup( QWidget * parent, const char * name )
00064     : GuiPrinterAutoSetupBase(parent,name)
00065 {
00066   qDebug("Constructor GuiPrinterAutoSetup");
00067 
00068   m_domDoc                  = new PrinterSetupDb( LPS_DB_DOCUMENT_NAME );
00069   m_translationRecommended  = tr("recommended", "This will be a appended to any recommended printer");
00070 
00071   connect(pushButton_back, SIGNAL(clicked()), this, SIGNAL(back()));
00072 }
00073 
00074 
00078 GuiPrinterAutoSetup::~GuiPrinterAutoSetup()
00079 {
00080   if ( m_domDoc )
00081     delete m_domDoc;
00082 
00083   qDebug("Destructor GuiPrinterAutoSetup finished");
00084 }
00085 
00086 
00093 void GuiPrinterAutoSetup::show()
00094 {
00095   GuiPrinterAutoSetupBase::show();
00096 
00097   emit showSmallHelp("smallPrinterAutoSetup.html");
00098   QString errMsg;
00099 
00100   label_status->setPaletteBackgroundColor(Qt::yellow);
00101   label_status->setText(tr("Loading database..."));
00102 
00103   setCursor(Qt::WaitCursor);
00104 
00105   setCaption(tr("Automatic Printer Setup"));
00106   qApp->processEvents();
00107 
00108   listBox_printers->clear();
00109   listBox_drivers->clear();
00110   QString fileName = MP_DIR() + MONEYPENNY_DATA_DIR + LPS_DB_FILE;
00111   qDebug(QString("Now loading: ") + fileName);
00112 
00113   try
00114   {
00115     // Load the XML database
00116     QFile file( fileName );
00117 
00118     if ( !file.exists() || !file.open( IO_ReadOnly ) )
00119       throw QString("Could not open file for reading:") + " " + fileName;
00120 
00121     QString errMsg;
00122     int     errLine;
00123     int     errCol;
00124     bool    ok      = m_domDoc->setContent(&file, false, &errMsg, &errLine, &errCol);
00125 
00126     file.close();
00127 
00128     if ( !ok )
00129       throw LpsError(QString("An internal error in the XML file %1 at line %2 in column %3 occured."
00130                              "<br />The error message from the system was: %4").arg(
00131                        LPS_DB_FILE, QString::number(errLine),QString::number(errCol),errMsg));
00132 
00133     // Initiate the autodetection process
00134     on_pushButton_restart_clicked();
00135   }
00136   catch ( LpsError e )
00137   {
00138     label_status->setPaletteBackgroundColor( Qt::red );
00139     label_status->setText(e);
00140     enableWidgets(NoneFlag ^ HelpButtonFlag ^ BackButtonFlag);
00141   }
00142   unsetCursor();
00143 }
00144 
00145 
00154 void GuiPrinterAutoSetup::on_pushButton_saveSettings_clicked()
00155 {
00156   try
00157   {
00158     //----------------------------------------------------------------------
00159     // Try to get all information about the selected printer.
00160     //----------------------------------------------------------------------
00161     QString       manufacturer  = listBox_printers->selectedItem()->text().section(" / ", 0, 0);
00162     QString       product       = listBox_printers->selectedItem()->text().section(" / ", 1, 1);
00163     QString       driver        = listBox_drivers->selectedItem()->text().replace(m_translationRecommended, "recommended");
00164     QString       printer       = listBox_printers->selectedItem()->text();
00165     QDomNodeList  drivers       = m_printerMap[printer].drivers;
00166     QDomElement   driverElement;
00167 
00168     uint i = 0;
00169     while ( driverElement.isNull()   &&   (i < drivers.length()) )
00170     {
00171       QDomElement element = drivers.item(i).toElement();
00172 
00173       if ( element.attribute("nickName") == driver ) //we have found it
00174         driverElement = element;
00175 
00176       i++;
00177     }
00178 
00179     if ( driverElement.isNull() )
00180       throw LpsError(QString("The driver element was NULL."));
00181 
00182     QString nickName        = driverElement.attribute("nickName");
00183     QString pcFileName      = driverElement.attribute("pcFileName");
00184     QString languageVersion = driverElement.attribute("languageVersion");
00185     QString ppdFilePath     = driverElement.attribute("ppdFilePath");
00186     QString deviceUri;
00187 
00188     if ( m_printerMap[ listBox_printers->selectedItem()->text() ].connectionType == ParPortConnection )
00189       deviceUri = "parallel:/dev/lp0";
00190     else
00191       deviceUri = "usb:/dev/usb/lp0";
00192 
00193     //----------------------------------------------------------------------
00194     // Next: Setup the printer using a CUPS CLI-command
00195     //----------------------------------------------------------------------
00196     QDomElement modelEle = m_domDoc->getModel(manufacturer, "", product);
00197 
00198     QString printerName = "";
00199 
00200     if ( !modelEle.isNull() )
00201       printerName = modelEle.attribute("name");
00202     else
00203       printerName = LPS_PRINTER_NAME;
00204 
00205     installPrinter(this, printerName, deviceUri, ppdFilePath);
00206 
00207     //----------------------------------------------------------------------
00208     // Ask the user whether a testpage shall be printed
00209     //----------------------------------------------------------------------
00210     testPrintRequest(this, printerName);
00211 
00212     label_status->setText("<p>" + tr("Your printer has been set up successfully.") + "</p>");
00213     label_status->setPaletteBackgroundColor(Qt::green);
00214 
00215   }
00216   catch ( LpsNotice e )
00217   {
00218     label_status->setPaletteBackgroundColor(Qt::yellow);
00219     label_status->setText(e);
00220     qDebug(e.latin1());
00221   }
00222   catch ( LpsError e )
00223   {
00224     label_status->setPaletteBackgroundColor(Qt::red);
00225     label_status->setText(e);
00226     qDebug(e.latin1());
00227   }
00228   unsetCursor();
00229 }
00230 
00231 
00236 void GuiPrinterAutoSetup::on_pushButton_help_clicked()
00237 {
00238   emit helpRequest("printerAutoSetup.html");
00239 }
00240 
00241 
00249 void GuiPrinterAutoSetup::on_listBox_drivers_highlighted(QListBoxItem * item)
00250 {
00251   QListBoxItem * printerItem = listBox_printers->selectedItem();
00252 
00253   if ( !item || !printerItem )
00254     return;
00255 
00256   label_status->setText(  tr("Driver:") + " <b>" + item->text()+"</b><br>" +
00257                           tr("Printer:")+ " <b>" + printerItem->text()+"</b><br>" +
00258                           tr("Click \"Save Settings\", if you want to use these settings.")
00259                        );
00260 
00261   label_status->setPaletteBackgroundColor(Qt::yellow);
00262 }
00263 
00264 
00273 void GuiPrinterAutoSetup::on_listBox_printers_highlighted(QListBoxItem * item)
00274 {
00275   if( !item ) // clicking into nirvana
00276     return;
00277 
00278   enableWidgets(AllFlags^DriversFlag);
00279   listBox_drivers->clear();
00280 
00281   QString manufacturer  = item->text().section(" / ", 0, 0);
00282   QString product       = item->text().section(" / ", 1, 1);
00283 
00284   qDebug("GuiPrinterAutoSetup::on_listBox_printers_highlighted:Searching drivers for: %s", product.latin1());
00285 
00286 
00287   //
00288   // Why did I use a reference below? -> To avoid doing the same thing more than one.
00289   //
00290   // If the user already clicked on the printer that is currently focused in the printer
00291   // list box, we've already queried the database to find associated printer drivers.
00292   // If this is the first time, the user clicked on the printer in the printer driver
00293   // list box, we have to query the database for the first time for the selected printer.
00294   // And we have to make sure that the returned information is stored for upcoming
00295   // selections of the same printer.
00296   //
00297   QDomNodeList & drivers = m_printerMap[ item->text() ].drivers;
00298 
00299   if ( drivers.length() <= 0 )
00300     drivers = m_domDoc->getDrivers(product); // matches products OR models
00301 
00302   for ( uint i=0; i<drivers.length(); i++ )
00303   {
00304     QDomElement driverElement = drivers.item(i).toElement();
00305 
00306     if ( !driverElement.isNull() )
00307     {
00308       //
00309       // Insert driver into driver list box and replace the "recommended" string
00310       // with a localized translation.
00311       //
00312       QString driverName = driverElement.attribute("nickName");
00313 
00314       qDebug ("GuiPrinterAutoSetup::on_listBox_printers_highlighted: Found driver %s", driverName.latin1());
00315 
00316       listBox_drivers->insertItem(driverName.replace("recommended",m_translationRecommended));
00317 
00318       //
00319       // If the last inserted item contained the "recommended" string, pre-select it.
00320       //
00321       uint count = listBox_drivers->count();
00322       if ( listBox_drivers->text(count - 1).contains(m_translationRecommended) )
00323       {
00324         listBox_drivers->setCurrentItem(count - 1);
00325         enableWidgets(AllFlags);
00326       }
00327     }
00328   }
00329 
00330   uint count = drivers.length();
00331   if ( count <= 0 )
00332   {
00333     label_status->setPaletteBackgroundColor( Qt::yellow );
00334     label_status->setText(  tr("No appropriate driver found for this device:") +
00335                             " <b>" + item->text() + "</b> <br>" +
00336                             tr("Please choose a different device!")
00337                          );
00338     enableWidgets(AllFlags ^ SaveSettingsButtonFlag ^ DriversFlag);
00339   }
00340 
00341   if( !listBox_drivers->selectedItem() && count > 0 )
00342   {
00343     listBox_drivers->setCurrentItem(0);
00344     enableWidgets(AllFlags);
00345   }
00346 }
00347 
00348 
00354 void GuiPrinterAutoSetup::on_pushButton_restart_clicked()
00355 {
00356   enableWidgets(NoneFlag);
00357 
00358   listBox_printers->clear();
00359   listBox_drivers->clear();
00360   m_printerMap.clear();
00361   int nPrinters = 0;
00362 
00363   try
00364   {
00365     //
00366     // Never change the order of this function calls.
00367     // If you connected the same printer via usb AND parallel port, it's safer
00368     // to use the usb rather than the parallel port. The parallel port printer
00369     // is shown in the list, although it might have been disconnected unlike
00370     // the usb printer which will disappear from the list, the next time you
00371     // enter a new autodetection cycle.
00372     //
00373     nPrinters += findParPortPrinters();
00374     nPrinters += findUsbPrinters();
00375   }
00376   catch ( LpsError e )
00377   {
00378     label_status->setPaletteBackgroundColor(Qt::red);
00379     label_status->setText(e);
00380     enableWidgets(AllFlags ^ DriversFlag ^ SaveSettingsButtonFlag);
00381     return;
00382   }
00383 
00384   if ( nPrinters > 0 )
00385   {
00386     PrinterMap::Iterator it;
00387 
00388     for ( it = m_printerMap.begin(); it != m_printerMap.end(); ++it )
00389     {
00390       listBox_printers->insertItem( QString(it.key().latin1()) );
00391       qDebug(QString(it.key().latin1()));
00392     }
00393 
00394     //
00395     // If we found more than one printer/device, select the first from the list.
00396     //
00397     listBox_printers->setCurrentItem(0);
00398   }
00399   else
00400   {
00401     label_status->setPaletteBackgroundColor(Qt::yellow);
00402 
00403     label_status->setText(  "<p>"+
00404                             tr("No printers found! Make sure your printer is connected and switched on.") + "<br>" +
00405                             tr("If you use a parallel port printer, connect it to your computer before booting.") +
00406                             "<br>" +
00407                             tr("You can also try the <i>Show all devices</i>-checkbox. ") +
00408                             "</p>"
00409                          );
00410 
00411     enableWidgets(AllFlags ^ PrintersFlag ^ DriversFlag ^ SaveSettingsButtonFlag);
00412   }
00413 }
00414 
00415 
00423 void GuiPrinterAutoSetup::on_checkBox_showAllDevices_stateChanged( int state )
00424 {
00425   if ( state == QButton::On )
00426   {
00427     QMessageBox::information( this,
00428                               LPS_APP_NAME,
00429                               tr("Please find out yourself, which of the devices in the list could be your printer.")  +
00430                               "<br>" +
00431                               tr("You should then switch to Manual Printer Setup.")
00432                             );
00433   }
00434 
00435   on_pushButton_restart_clicked();
00436 }
00437 
00438 
00446 void GuiPrinterAutoSetup::on_pushButton_driverDetails_clicked()
00447 {
00448   try
00449   {
00450     showPrinterDriverDetails(  listBox_drivers->selectedItem()->text().replace(m_translationRecommended, "recommended")  );
00451   }
00452   catch (LpsError e)
00453   {
00454     label_status->setText(e);
00455     label_status->setPaletteBackgroundColor(Qt::yellow);
00456   }
00457 }
00458 
00459 
00464 void GuiPrinterAutoSetup::on_pushButton_manualSetup_clicked()
00465 {
00466   emit raiseWidget(PRINTER_MANUALSETUP_WIDGET);
00467 }
00468 
00469 
00477 int GuiPrinterAutoSetup::findUsbPrinters()
00478 {
00479   //
00482   //
00483   QFile usbDevicesFile( LPS_USB_DEVICE_PATH );
00484 
00485   if ( !usbDevicesFile.exists() || !usbDevicesFile.open(IO_ReadOnly) )
00486   {
00487     throw LpsError(tr( "Could not open device file for reading. Filename: ") + usbDevicesFile.name());
00488   }
00489 
00490   QTextStream stream( &usbDevicesFile );
00491   int         nPrintersFound          = 0;
00492   int         status                  = 0; 
00493   int         statusManufacturerDone  = 1; 
00494   int         statusProductDone       = 2; 
00495   int         statusAllDone           = 3; 
00496   QString     manufacturerName        = QString::null;
00497   QString     product                 = QString::null;
00498 
00499   //
00500   // Read until we have reached the end of the file
00501   //
00502   while ( !stream.atEnd() )
00503   {
00504     //
00505     // Extract the file line by line and parse each, until
00506     // we have found all needed information (status==statusAllDone).
00507     //
00508     QString line = stream.readLine();
00509 
00510     //
00511     // a new printer device is expected soon
00512     //
00513     if ( line == "" )
00514     {
00515       status = 0;
00516     }
00517     else if ( line.startsWith("S:  Manufacturer=") )
00518     {
00519       manufacturerName = line.remove("S:  Manufacturer=");
00520       status          |= statusManufacturerDone;
00521     }
00522     else if ( line.startsWith("S:  Product=") )
00523     {
00524       product = line.remove("S:  Product=");
00525       status |= statusProductDone;
00526     }
00527 
00528     if ( status == statusAllDone )
00529     {
00530       fixManufacturer(manufacturerName);
00531 
00532       qDebug("GuiPrinterAutoSetup::findUsbPrinters: Found printer: %s %s", manufacturerName.latin1(), product.latin1());
00533 
00534       QDomNodeList drivers;
00535 
00536       //
00537       // A device has to meet at least one of the following three criteria
00538       // before it is inserted into the printers list box:
00539       //
00540       // 1. The user wants to see all connected devices (checkBox_showAllDevices is checked)
00541       // 2. We found the manufacturer of the device in our printer driver DB
00542       // 3. We found the product of the device somewhere in the DB
00543       //
00544       if (  checkBox_showAllDevices->isChecked() ||
00545             m_domDoc->manufacturerExists(manufacturerName) ||
00546             (drivers=m_domDoc->getDrivers(product)).length()
00547          )
00548       {
00549         status = 0;
00550 
00551         PrinterDevice device;
00552 
00553         device.nativeManufacturer = manufacturerName;
00554         device.connectionType     = UsbConnection;
00555         device.drivers            = drivers;
00556         device.nativeProduct      = product;
00557 
00558         m_printerMap[ manufacturerName +" / "+ product ] = device;
00559 
00560         nPrintersFound++;
00561       }//end if checkBox....
00562     } //end if status == statusAllDone
00563   }// end while
00564 
00565   return nPrintersFound;
00566 }
00567 
00568 
00576 int GuiPrinterAutoSetup::findParPortPrinters()
00577 {
00578   int nPrintersFound = 0;
00579 
00580   QDir deviceDir(LPS_PARPORT_DEVICE_DIR); // typically, this point to /proc/sys/dev/parport/
00581 
00582   if ( !deviceDir.exists() || !deviceDir.isReadable() )
00583     throw LpsError(QString("The following directory could not be found or is not readable: ") + deviceDir.absPath());
00584 
00585   deviceDir.setFilter( QDir::Dirs );
00586   QStringList subdirs = deviceDir.entryList();
00587 
00588   // Run through all directories that are in /proc/sys/dev/parport/ and search for parportX directories
00589   for ( QStringList::Iterator subDirIt = subdirs.begin();
00590         subDirIt != subdirs.end();
00591         ++subDirIt
00592       )
00593   {
00594     if ( subDirIt!=NULL )
00595     {
00596       QString dirName = *subDirIt;
00597 
00598       // Filter parport dirs
00599       if ( dirName!="." && dirName!=".." && dirName.contains("parport") ) //this is a parportX dir,
00600                                                                           //enter it and search for an autoprobe file
00601       {
00602         QString absPath = deviceDir.absPath() + "/" + dirName;
00603 
00604         QDir dirEntry( absPath );
00605 
00606         if ( !dirEntry.exists() || !dirEntry.isReadable() )
00607           throw LpsError(QString("The following directory could not be found or is not readable: ") + dirEntry.absPath());
00608 
00609         dirEntry.setFilter( QDir::Files );
00610         QStringList files = dirEntry.entryList();
00611 
00612         QFile deviceFile(absPath + "/autoprobe");
00613 
00614         if ( !deviceFile.exists() || !deviceFile.open(IO_ReadOnly) )
00615           throw  LpsError(QString("Could not open device file for reading: ") + deviceFile.name());
00616 
00617         QTextStream stream( &deviceFile );
00618 
00619         int     status                  = 0; 
00620         int     statusManufacturerDone  = 1; 
00621         int     statusModelDone         = 2; 
00622         int     statusAllDone           = 3; 
00623 
00624         QString manufacturer            = "";
00625         QString model                   = "";
00626 
00627         //
00628         // Read the autoprobe file from the beginning to the end
00629         //
00630         while ( !stream.atEnd() )
00631         {
00632           //
00633           // Extract the file line by line and parse each, until
00634           // we have found all needed information (status==statusAllDone).
00635           //
00636           QString line = stream.readLine();
00637 
00638           if ( line.startsWith("MANUFACTURER:") )
00639           {
00640             manufacturer = line.remove("MANUFACTURER:").remove(";");
00641             status      |= statusManufacturerDone;
00642           }
00643           else if ( line.startsWith("MODEL:") )
00644           {
00645             model   = line.remove("MODEL:").remove(";");
00646             status |= statusModelDone;
00647           }
00648           if ( status == statusAllDone )
00649           {
00650             fixManufacturer(manufacturer);
00651 
00652             qDebug("GuiPrinterAutoSetup::findParPortPrinters: Found printer: %s %s", manufacturer.latin1(), model.latin1());
00653 
00654             QDomNodeList drivers;
00655 
00656             //
00657             // A device has to meet at least one of the following three criteria
00658             // before it is inserted into the printers list box:
00659             //
00660             // 1. The user wants to see all connected devices (checkBox_showAllDevices is checked)
00661             // 2. We found the manufacturer of the device in our printer driver DB
00662             // 3. We found the product of the device somewhere in the DB
00663             //
00664             if (  checkBox_showAllDevices->isChecked() ||
00665                   m_domDoc->manufacturerExists(manufacturer) ||
00666                   (drivers=m_domDoc->getDrivers(model)).length()
00667                )
00668             {
00669                 status                    = 0;
00670 
00671                 PrinterDevice device;
00672 
00673                 device.nativeManufacturer = manufacturer;
00674                 device.connectionType     = ParPortConnection;
00675                 device.nativeProduct      = model;
00676                 device.drivers            = drivers;
00677 
00678                 m_printerMap[manufacturer +" / "+ model] = device;
00679 
00680                 nPrintersFound++;
00681             }
00682           }//end if status == allDone
00683         }//end while !stream atEnd
00684 
00685         deviceFile.close();
00686       } //end if dirname contains parport
00687     }//end if subir != Null
00688   }//end for
00689 
00690   return nPrintersFound;
00691 }
00692 
00693 
00700 void GuiPrinterAutoSetup::enableWidgets( int wf )
00701 {
00702   // list boxes
00703   listBox_drivers->setEnabled(          wf & DriversFlag            );
00704   listBox_printers->setEnabled(         wf & PrintersFlag           );
00705 
00706   // labels
00707   label_drivers->setEnabled(            wf & DriversFlag            );
00708   label_printers->setEnabled(           wf & PrintersFlag           );
00709 
00710   // push buttons
00711   pushButton_driverDetails->setEnabled( wf & DriversFlag            );
00712   pushButton_help->setEnabled(          wf & HelpButtonFlag         );
00713   pushButton_back->setEnabled(          wf & BackButtonFlag         );
00714   pushButton_restart->setEnabled(       wf & RestartButtonFlag      );
00715   pushButton_manualSetup->setEnabled(   wf & ManualSetupButtonFlag  );
00716   pushButton_saveSettings->setEnabled(  wf & SaveSettingsButtonFlag );
00717 }
00718 
00719 
00728 void GuiPrinterAutoSetup::fixManufacturer( QString & manufacturer )
00729 {
00730   if ( manufacturer == "Hewlett-Packard" )
00731     manufacturer = "HP";
00732 }


To get more information, please visit our project site hosted at SourceForge.net Logo
To support this project, please click on this image: Support This Project

Copyright © 2005-2006 Linux Printer Setup Documentation generated by Doxygen 1.4.4 LPS 1.0 (Disclaimer)