• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

KDEPrint

apshandler.cpp

Go to the documentation of this file.
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., 51 Franklin Street, Fifth Floor,
00017  *  Boston, MA 02110-1301, USA.
00018  **/
00019 
00020 #include "apshandler.h"
00021 #include "driver.h"
00022 #include "printcapentry.h"
00023 #include "kmprinter.h"
00024 #include "lprsettings.h"
00025 #include "kmmanager.h"
00026 #include "util.h"
00027 #include "kprinter.h"
00028 
00029 #include <QtCore/QFile>
00030 #include <QtCore/QDir>
00031 #include <QtCore/QTextStream>
00032 #include <QtCore/QStack>
00033 #include <kstandarddirs.h>
00034 #include <klocale.h>
00035 #include <kdebug.h>
00036 
00037 #include <sys/types.h>
00038 #include <sys/stat.h>
00039 
00040 ApsHandler::ApsHandler(KMManager *mgr)
00041         : LprHandler("apsfilter", mgr)
00042 {
00043     m_counter = 1;
00044 }
00045 
00046 bool ApsHandler::validate(PrintcapEntry *entry)
00047 {
00048     return (entry->field("if").endsWith("apsfilter"));
00049 }
00050 
00051 KMPrinter* ApsHandler::createPrinter(PrintcapEntry *entry)
00052 {
00053     entry->comment = QString::fromLatin1("# APS%1_BEGIN:printer%2").arg(m_counter).arg(m_counter);
00054     entry->postcomment = QString::fromLatin1("# APS%1_END - don't delete this").arg(m_counter);
00055     m_counter++;
00056     return LprHandler::createPrinter(entry);
00057 }
00058 
00059 bool ApsHandler::completePrinter(KMPrinter *prt, PrintcapEntry *entry, bool shortmode)
00060 {
00061     if (LprHandler::completePrinter(prt, entry, shortmode)) {
00062         if (!shortmode) {
00063             QMap<QString, QString> opts = loadResources(entry);
00064             if (opts.contains("PRINTER")) {
00065                 prt->setDescription(i18n("APS Driver (%1)", opts["PRINTER"]));
00066                 prt->setDriverInfo(prt->description());
00067             }
00068         }
00069         if (prt->device().isEmpty()) {
00070             QString prot;
00071             QString smbname(sysconfDir() + '/' + prt->printerName() + "/smbclient.conf");
00072             QString ncpname(sysconfDir() + '/' + prt->printerName() + "/netware.conf");
00073             if (QFile::exists(smbname)) {
00074                 QMap<QString, QString> opts = loadVarFile(smbname);
00075                 if (opts.count() == 0)
00076                     prt->setDevice("smb://<unknown>/<unknown>");
00077                 else {
00078                     prt->setDevice(buildSmbURI(
00079                                        opts[ "SMB_WORKGROUP" ],
00080                                        opts[ "SMB_SERVER" ],
00081                                        opts[ "SMB_PRINTER" ],
00082                                        opts[ "SMB_USER" ],
00083                                        opts[ "SMB_PASSWD" ]));
00084                 }
00085                 prot = "smb";
00086             } else if (QFile::exists(ncpname)) {
00087                 QMap<QString, QString> opts = loadVarFile(ncpname);
00088                 if (opts.count() == 0)
00089                     prt->setDevice("ncp://<unknown>/<unknown>");
00090                 else {
00091                     QString uri = buildSmbURI(
00092                                       QString(),
00093                                       opts[ "NCP_SERVER" ],
00094                                       opts[ "NCP_PRINTER" ],
00095                                       opts[ "NCP_USER" ],
00096                                       opts[ "NCP_PASSWD" ]);
00097                     uri.replace(0, 3, "ncp");
00098                     prt->setDevice(uri);
00099                 }
00100                 prot = "ncp";
00101             }
00102             if (!prt->device().isEmpty())
00103                 prt->setLocation(i18n("Network printer (%1)", prot));
00104         }
00105         return true;
00106     }
00107     return false;
00108 }
00109 
00110 QString ApsHandler::sysconfDir()
00111 {
00112     return QFile::encodeName("/etc/apsfilter");
00113 }
00114 
00115 QString ApsHandler::shareDir()
00116 {
00117     return driverDirectory();
00118 }
00119 
00120 QString ApsHandler::driverDirInternal()
00121 {
00122     return locateDir("apsfilter/setup", "/usr/share:/usr/local/share:/opt/share");
00123 }
00124 
00125 QMap<QString, QString> ApsHandler::loadResources(PrintcapEntry *entry)
00126 {
00127     return loadVarFile(sysconfDir() + '/' + (entry ? entry->name : QString()) + "/apsfilterrc");
00128 }
00129 
00130 QMap<QString, QString> ApsHandler::loadVarFile(const QString& filename)
00131 {
00132     QMap<QString, QString> opts;
00133     QFile f(filename);
00134     if (f.open(QIODevice::ReadOnly)) {
00135         QTextStream t(&f);
00136         QString line;
00137         int p(-1);
00138         while (!t.atEnd()) {
00139             line = t.readLine().trimmed();
00140             if (line.isEmpty() || line[0] == '#' || (p = line.indexOf('=')) == -1)
00141                 continue;
00142             QString variable = line.left(p).trimmed();
00143             QString value = line.mid(p + 1).trimmed();
00144             if (!value.isEmpty() && value[0] == '\'')
00145                 value = value.mid(1, value.length() - 2);
00146             opts[variable] = value;
00147         }
00148     }
00149     return opts;
00150 }
00151 
00152 DrMain* ApsHandler::loadDriver(KMPrinter*, PrintcapEntry *entry, bool config)
00153 {
00154     DrMain *driver = loadApsDriver(config);
00155     if (driver /* && config */) {   // Load resources in all case, to get the correct page size
00156         QMap<QString, QString> opts = loadResources(entry);
00157         if (!config && opts.contains("PAPERSIZE")) {
00158             // this is needed to keep applications informed
00159             // about the current selected page size
00160             opts[ "PageSize" ] = opts[ "PAPERSIZE" ];
00161 
00162             // default page size needs to be set to the actual
00163             // value of the printer driver, otherwise it's blocked
00164             // to A4
00165             DrBase *opt = driver->findOption("PageSize");
00166             if (opt)
00167                 opt->set("default", opts[ "PageSize" ]);
00168         }
00169         driver->setOptions(opts);
00170         driver->set("gsdriver", opts["PRINTER"]);
00171     }
00172     return driver;
00173 }
00174 
00175 DrMain* ApsHandler::loadDbDriver(const QString& s)
00176 {
00177     int p = s.indexOf('/');
00178     DrMain *driver = loadApsDriver(true);
00179     if (driver)
00180         driver->set("gsdriver", s.mid(p + 1));
00181     return driver;
00182 }
00183 
00184 DrMain* ApsHandler::loadApsDriver(bool config)
00185 {
00186     DrMain *driver = loadToolDriver(KStandardDirs::locate("data", (config ? "kdeprint/apsdriver1" : "kdeprint/apsdriver2")));
00187     if (driver)
00188         driver->set("text", "APS Common Driver");
00189     return driver;
00190 }
00191 
00192 void ApsHandler::reset()
00193 {
00194     m_counter = 1;
00195 }
00196 
00197 PrintcapEntry* ApsHandler::createEntry(KMPrinter *prt)
00198 {
00199     QString prot = prt->deviceProtocol();
00200     if (prot != "parallel" && prot != "lpd" && prot != "smb" && prot != "ncp") {
00201         manager()->setErrorMsg(i18n("Unsupported backend: %1.", prot));
00202         return NULL;
00203     }
00204     QString path = sysconfDir() + '/' + prt->printerName();
00205     if (!KStandardDirs::makeDir(path, 0755)) {
00206         manager()->setErrorMsg(i18n("Unable to create directory %1.", path));
00207         return NULL;
00208     }
00209     if (prot == "smb" || prot == "ncp") {
00210         // either "smb" or "ncp"
00211         QFile::remove(path + "/smbclient.conf");
00212         QFile::remove(path + "/netware.conf");
00213         QFile f;
00214         if (prot == "smb") {
00215             f.setFileName(path + "/smbclient.conf");
00216             if (f.open(QIODevice::WriteOnly)) {
00217                 QTextStream t(&f);
00218                 QString work, server, printer, user, passwd;
00219                 if (splitSmbURI(prt->device(), work, server, printer, user, passwd)) {
00220                     if (work.isEmpty()) {
00221                         manager()->setErrorMsg(i18n("Missing element: %1.", QString("Workgroup")));
00222                         return NULL;
00223                     }
00224                     t << "SMB_SERVER='" << server << "'" << endl;
00225                     t << "SMB_PRINTER='" << printer << "'" << endl;
00226                     t << "SMB_IP=''" << endl;
00227                     t << "SMB_WORKGROUP='" << work << "'" << endl;
00228                     t << "SMB_BUFFER=1400" << endl;
00229                     t << "SMB_FLAGS='-N'" << endl;
00230                     if (!user.isEmpty()) {
00231                         t << "SMB_USER='" << user << "'" << endl;
00232                         t << "SMB_PASSWD='" << passwd << "'" << endl;
00233                     }
00234                 } else {
00235                     manager()->setErrorMsg(i18n("Invalid printer backend specification: %1" ,  prt->device()));
00236                     return NULL;
00237                 }
00238             } else {
00239                 manager()->setErrorMsg(i18n("Unable to create the file %1.", f.fileName()));
00240                 return NULL;
00241             }
00242         } else {
00243             f.setFileName(path + "/netware.conf");
00244             if (f.open(QIODevice::WriteOnly)) {
00245                 QString work, server, printer, user, passwd;
00246                 QString uri = prt->device();
00247                 uri.replace(0, 3, "smb");
00248                 if (splitSmbURI(uri, work, server, printer, user, passwd)) {
00249                     QTextStream t(&f);
00250                     t << "NCP_SERVER='" << server << "'" << endl;
00251                     t << "NCP_PRINTER='" << printer << "'" << endl;
00252                     if (!user.isEmpty()) {
00253                         t << "NCP_USER='" << user << "'" << endl;
00254                         t << "NCP_PASSWD='" << passwd << "'" << endl;
00255                     }
00256                 } else {
00257                     manager()->setErrorMsg(i18n("Invalid printer backend specification: %1" ,  prt->device()));
00258                     return NULL;
00259                 }
00260             } else {
00261                 manager()->setErrorMsg(i18n("Unable to create the file %1.", f.fileName()));
00262                 return NULL;
00263             }
00264         }
00265         // change file permissions
00266         ::chmod(QFile::encodeName(f.fileName()).data(), S_IRUSR | S_IWUSR);
00267     }
00268     PrintcapEntry *entry = LprHandler::createEntry(prt);
00269     if (!entry) {
00270         entry = new PrintcapEntry;
00271         entry->addField("lp", Field::String, "/dev/null");
00272     }
00273     QString sd = LprSettings::self()->baseSpoolDir() + '/' + prt->printerName();
00274     entry->addField("af", Field::String, sd + "/acct");
00275     entry->addField("lf", Field::String, sd + "/log");
00276     entry->addField("if", Field::String, sysconfDir() + "/basedir/bin/apsfilter");
00277     entry->comment = QString::fromLatin1("# APS%1_BEGIN:printer%2").arg(m_counter).arg(m_counter);
00278     entry->postcomment = QString::fromLatin1("# APS%1_END").arg(m_counter);
00279     m_counter++;
00280     return entry;
00281 }
00282 
00283 bool ApsHandler::savePrinterDriver(KMPrinter *prt, PrintcapEntry*, DrMain *driver, bool*)
00284 {
00285     if (driver->get("gsdriver").isEmpty()) {
00286         manager()->setErrorMsg(i18n("The APS driver is not defined."));
00287         return false;
00288     }
00289     QFile f(sysconfDir() + '/' + prt->printerName() + "/apsfilterrc");
00290     if (f.open(QIODevice::WriteOnly)) {
00291         QTextStream t(&f);
00292         t << "# File generated by KDEPrint" << endl;
00293         t << "PRINTER='" << driver->get("gsdriver") << "'" << endl;
00294         QStack<DrGroup*> stack;
00295         stack.push(driver);
00296         while (stack.count() > 0) {
00297             DrGroup *grp = stack.pop();
00298             foreach(DrGroup* subgroup, grp->groups())
00299             stack.push(subgroup);
00300             QString value;
00301             foreach(DrBase* option, grp->options()) {
00302                 value = option->valueText();
00303                 switch (option->type()) {
00304                 case DrBase::Boolean:
00305                     if (value == "true")
00306                         t << option->name() << "='" << value << "'" << endl;
00307                     break;
00308                 case DrBase::List:
00309                     if (value != "(empty)")
00310                         t << option->name() << "='" << value << "'" << endl;
00311                     break;
00312                 case DrBase::String:
00313                     if (!value.isEmpty())
00314                         t << option->name() << "='" << value << "'" << endl;
00315                     break;
00316                 default:
00317                     break;
00318                 }
00319             }
00320         }
00321         return true;
00322     } else {
00323         manager()->setErrorMsg(i18n("Unable to create the file %1.", f.fileName()));
00324         return false;
00325     }
00326 }
00327 
00328 bool ApsHandler::removePrinter(KMPrinter*, PrintcapEntry *entry)
00329 {
00330     QString path(sysconfDir() + '/' + entry->name);
00331     QFile::remove(path + "/smbclient.conf");
00332     QFile::remove(path + "/netware.conf");
00333     QFile::remove(path + "/apsfilterrc");
00334     if (!QDir(path).rmdir(path)) {
00335         manager()->setErrorMsg(i18n("Unable to remove directory %1.", path));
00336         return false;
00337     }
00338     return true;
00339 }
00340 
00341 QString ApsHandler::printOptions(KPrinter *printer)
00342 {
00343     QString optstr;
00344     QMap<QString, QString> opts = printer->options();
00345     for (QMap<QString, QString>::ConstIterator it = opts.begin(); it != opts.end(); ++it) {
00346         if (it.key().startsWith("kde-") || it.key().startsWith("_kde-") || it.key().startsWith("app-"))
00347             continue;
00348         optstr.append((*it)).append(":");
00349     }
00350     if (!optstr.isEmpty()) {
00351         optstr = optstr.left(optstr.length() - 1);
00352         if (LprSettings::self()->mode() == LprSettings::LPR)
00353             optstr.prepend("-C '").append("'");
00354         else
00355             optstr.prepend("-Z '").append("'");
00356     }
00357     return optstr;
00358 }

KDEPrint

Skip menu "KDEPrint"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  •   KDEPrint
Generated for API Reference by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal