lpdtools.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., 51 Franklin Street, Fifth Floor,
00017  *  Boston, MA 02110-1301, USA.
00018  **/
00019 
00020 #include "lpdtools.h"
00021 #include "driver.h"
00022 #include "kmprinter.h"
00023 
00024 #include <qfile.h>
00025 #include <klocale.h>
00026 
00027 static const char *pt_pagesize[] = {
00028     "ledger", I18N_NOOP("Ledger"),
00029     "legal", I18N_NOOP("US Legal"),
00030     "letter", I18N_NOOP("US Letter"),
00031     "a4", I18N_NOOP("A4"),
00032     "a3", I18N_NOOP("A3"),
00033     "b4", I18N_NOOP("B4"),
00034     "b5", I18N_NOOP("B5"),
00035     0
00036 };
00037 static int pt_nup[] = { 1, 2, 4, 8, -1 };
00038 static const char *pt_bool[] = {
00039     "YES", I18N_NOOP("Enabled"),
00040     "NO", I18N_NOOP("Disabled"),
00041     0
00042 };
00043 
00044 void setupBooleanOption(DrBooleanOption *opt)
00045 {
00046     int     i(0);
00047     while (pt_bool[i])
00048     {
00049         DrBase  *ch = new DrBase();
00050         ch->setName(pt_bool[i++]);
00051         ch->set("text",pt_bool[i++]);
00052         opt->addChoice(ch);
00053     }
00054 }
00055 
00056 QString nextWord(const QString& s, int& pos)
00057 {
00058     int p1(pos), p2(0);
00059     while (s[p1].isSpace() && p1 < (int)s.length()) p1++;
00060     if (s[p1] == '{')
00061     {
00062         p1++;
00063         p2 = s.find('}',p1);
00064     }
00065     else
00066     {
00067         p2 = p1;
00068         while (!s[p2].isSpace() && p2 < (int)s.length()) p2++;
00069     }
00070     pos = (p2+1);
00071     return s.mid(p1,p2-p1);
00072 }
00073 
00074 //************************************************************************************************
00075 
00076 bool PrintcapEntry::readLine(const QString& line)
00077 {
00078     QStringList l = QStringList::split(':',line,false);
00079     if (l.count() > 0)
00080     {
00081         m_name = l[0];
00082         int p(-1);
00083         // discard aliases
00084         if ((p=m_name.find('|')) != -1)
00085             m_name = m_name.left(p);
00086         m_args.clear();
00087         for (uint i=1; i<l.count(); i++)
00088         {
00089             int p = l[i].find('=');
00090             if (p == -1) p = 2;
00091             QString key = l[i].left(p);
00092             QString value = l[i].right(l[i].length()-(l[i][p] == '=' ? p+1 : p));
00093             m_args[key] = value;
00094         }
00095         return true;
00096     }
00097     return false;
00098 }
00099 
00100 void PrintcapEntry::writeEntry(QTextStream& t)
00101 {
00102     if (m_comment.isEmpty()) t << "# Entry for printer " << m_name << endl;
00103     else t << m_comment << endl;
00104     t << m_name << ":";
00105     for (QMap<QString,QString>::ConstIterator it=m_args.begin(); it!=m_args.end(); ++it)
00106     {
00107         t << "\\\n\t:" << it.key();
00108         if (!it.data().isEmpty())
00109             t << ((*it)[0] == '#' ? "" : "=") << *it;
00110         t << ":";
00111     }
00112     t << endl << endl;
00113 }
00114 
00115 QString PrintcapEntry::comment(int index)
00116 {
00117     QString w;
00118     if (m_comment.startsWith("##PRINTTOOL3##"))
00119     {
00120         int p(0);
00121         for (int i=0;i<index;i++)
00122             w = nextWord(m_comment,p);
00123     }
00124     return w;
00125 }
00126 
00127 KMPrinter* PrintcapEntry::createPrinter()
00128 {
00129     KMPrinter   *printer = new KMPrinter();
00130     printer->setName(m_name);
00131     printer->setPrinterName(m_name);
00132     printer->setInstanceName(QString::null);
00133     printer->setState(KMPrinter::Idle);
00134     printer->setType(KMPrinter::Printer);
00135     return printer;
00136 }
00137 
00138 //************************************************************************************************
00139 
00140 QStringList splitPrinttoolLine(const QString& line)
00141 {
00142     QStringList l;
00143     int         p = line.find(':');
00144     if (p != -1)
00145     {
00146         l.append(line.left(p));
00147         p = line.find('{',p);
00148         if (p == -1)
00149             l.append(line.right(line.length()-l[0].length()-1).stripWhiteSpace());
00150         else
00151         {
00152             while (p != -1)
00153             {
00154                 int     q = line.find('}',p);
00155                 if (q != -1)
00156                 {
00157                     l.append(line.mid(p+1,q-p-1));
00158                     p = line.find('{',q);
00159                 }
00160                 else break;
00161             }
00162         }
00163     }
00164     return l;
00165 }
00166 
00167 bool PrinttoolEntry::readEntry(QTextStream& t)
00168 {
00169     QString line;
00170     QStringList args;
00171 
00172     m_resolutions.setAutoDelete(true);
00173     m_depths.setAutoDelete(true);
00174     m_resolutions.clear();
00175     m_depths.clear();
00176     while (!t.eof())
00177     {
00178         line = getPrintcapLine(t);
00179         if (line.isEmpty())
00180             break;
00181         if (line == "EndEntry")
00182             return !m_name.isEmpty();
00183         QStringList l = splitPrinttoolLine(line);
00184         if (l.count() > 1)
00185         {
00186             if (l[0] == "StartEntry") m_name = l[1];
00187             else if (l[0] == "GSDriver") m_gsdriver = l[1];
00188             else if (l[0] == "About") m_about = l[1];
00189             else if (l[0] == "Description") m_description = l[1];
00190             else if (l[0] == "Resolution" && l.count() > 2)
00191             {
00192                 Resolution  *resol = new Resolution;
00193                 bool        ok(false);
00194                 resol->xdpi = l[1].toInt(&ok);
00195                 if (ok) resol->ydpi = l[2].toInt(&ok);
00196                 if (l.count() > 3)
00197                     resol->comment = l[3];
00198                 if (ok) m_resolutions.append(resol);
00199                 else delete resol;
00200             }
00201             else if (l[0] == "BitsPerPixel" && l.count() > 1)
00202             {
00203                 BitsPerPixel    *dpth = new BitsPerPixel;
00204                 dpth->bpp = l[1];
00205                 if (l.count() > 2)
00206                     dpth->comment = l[2];
00207                 m_depths.append(dpth);
00208             }
00209         }
00210     }
00211     return false;
00212 }
00213 
00214 DrMain* PrinttoolEntry::createDriver()
00215 {
00216     // create driver
00217     DrMain  *dr = new DrMain();
00218     dr->setName(m_name);
00219     dr->set("description",m_description);
00220     dr->set("text",m_description);
00221     dr->set("drtype","printtool");
00222 
00223     DrGroup     *gr(0);
00224     DrListOption    *lopt(0);
00225     DrStringOption  *sopt(0);
00226     DrBooleanOption *bopt(0);
00227     DrBase      *ch(0);
00228 
00229     if (m_gsdriver != "TEXT")
00230     {
00231         // create GS group
00232         gr = new DrGroup();
00233         gr->set("text",i18n("GhostScript settings"));
00234         dr->addGroup(gr);
00235 
00236         // Pseudo option to have access to GS driver
00237         lopt = new DrListOption();
00238         lopt->setName("GSDEVICE");
00239         lopt->set("text",i18n("Driver"));
00240         lopt->set("default",m_gsdriver);
00241         gr->addOption(lopt);
00242         ch = new DrBase();
00243         ch->setName(m_gsdriver);
00244         ch->set("text",m_gsdriver);
00245         lopt->addChoice(ch);
00246         lopt->setValueText(m_gsdriver);
00247 
00248 
00249         // Resolutions
00250         if (m_resolutions.count() > 0)
00251         {
00252             lopt = new DrListOption();
00253             lopt->setName("RESOLUTION");
00254             lopt->set("text",i18n("Resolution"));
00255             gr->addOption(lopt);
00256             QPtrListIterator<Resolution>    it(m_resolutions);
00257             for (int i=0;it.current();++it,i++)
00258             {
00259                 ch = new DrBase;
00260                 ch->setName(QString::fromLatin1("%1x%2").arg(it.current()->xdpi).arg(it.current()->ydpi));
00261                 if (it.current()->comment.isEmpty())
00262                     ch->set("text",QString::fromLatin1("%1x%2 DPI").arg(it.current()->xdpi).arg(it.current()->ydpi));
00263                 else
00264                     ch->set("text",QString::fromLatin1("%2x%3 DPI (%1)").arg(it.current()->comment).arg(it.current()->xdpi).arg(it.current()->ydpi));
00265                 lopt->addChoice(ch);
00266             }
00267             QString defval = lopt->choices()->first()->name();
00268             lopt->set("default",defval);
00269             lopt->setValueText(defval);
00270         }
00271 
00272         // BitsPerPixels
00273         if (m_depths.count() > 0)
00274         {
00275             lopt = new DrListOption();
00276             lopt->setName("COLOR");
00277             lopt->set("text",i18n("Color depth"));
00278             gr->addOption(lopt);
00279             QPtrListIterator<BitsPerPixel>  it(m_depths);
00280             for (int i=0;it.current();++it,i++)
00281             {
00282                 ch = new DrBase;
00283                 if (m_gsdriver != "uniprint")
00284                     ch->setName(QString::fromLatin1("-dBitsPerPixel=%1").arg(it.current()->bpp));
00285                 else
00286                     ch->setName(it.current()->bpp);
00287                 if (it.current()->comment.isEmpty())
00288                     ch->set("text",it.current()->bpp);
00289                 else
00290                     ch->set("text",QString::fromLatin1("%1 - %2").arg(it.current()->bpp).arg(it.current()->comment));
00291                 lopt->addChoice(ch);
00292             }
00293             QString defval = lopt->choices()->first()->name();
00294             lopt->set("default",defval);
00295             lopt->setValueText(defval);
00296         }
00297 
00298         // additional GS options
00299         sopt = new DrStringOption;
00300         sopt->setName("EXTRA_GS_OPTIONS");
00301         sopt->set("text",i18n("Additional GS options"));
00302         gr->addOption(sopt);
00303     }
00304 
00305     // General group
00306     gr = new DrGroup();
00307     gr->set("text",i18n("General"));
00308     dr->addGroup(gr);
00309 
00310     // Page size
00311     lopt = new DrListOption();
00312     lopt->setName("PAPERSIZE");
00313     lopt->set("text",i18n("Page size"));
00314     lopt->set("default","letter");
00315     gr->addOption(lopt);
00316     int     i(0);
00317     while (pt_pagesize[i])
00318     {
00319         ch = new DrBase();
00320         ch->setName(pt_pagesize[i++]);
00321         ch->set("text",i18n(pt_pagesize[i++]));
00322         lopt->addChoice(ch);
00323     }
00324     lopt->setValueText("letter");
00325 
00326     // Nup
00327     lopt = new DrListOption();
00328     lopt->setName("NUP");
00329     lopt->set("text",i18n("Pages per sheet"));
00330     lopt->set("default","1");
00331     gr->addOption(lopt);
00332     i = 0;
00333     while (pt_nup[i] != -1)
00334     {
00335         ch = new DrBase();
00336         ch->setName(QString::number(pt_nup[i++]));
00337         ch->set("text",ch->name());
00338         lopt->addChoice(ch);
00339     }
00340     lopt->setValueText("1");
00341 
00342     // Margins
00343     sopt = new DrStringOption();
00344     sopt->setName("RTLFTMAR");
00345     sopt->set("text",i18n("Left/right margin (1/72 in)"));
00346     sopt->setValueText("18");
00347     gr->addOption(sopt);
00348     sopt = new DrStringOption();
00349     sopt->setName("TOPBOTMAR");
00350     sopt->set("text",i18n("Top/bottom margin (1/72 in)"));
00351     sopt->setValueText("18");
00352     gr->addOption(sopt);
00353 
00354     // Text group
00355     gr = new DrGroup();
00356     gr->set("text",i18n("Text options"));
00357     dr->addGroup(gr);
00358 
00359     // Send EOF
00360     bopt = new DrBooleanOption();
00361     bopt->setName("TEXT_SEND_EOF");
00362     bopt->set("text",i18n("Send EOF after job to eject page"));
00363     gr->addOption(bopt);
00364     setupBooleanOption(bopt);
00365     bopt->setValueText("NO");
00366 
00367     // Fix stair-stepping
00368     bopt = new DrBooleanOption();
00369     bopt->setName("CRLFTRANS");
00370     bopt->set("text",i18n("Fix stair-stepping text"));
00371     gr->addOption(bopt);
00372     setupBooleanOption(bopt);
00373     bopt->choices()->first()->setName("1");
00374     bopt->choices()->last()->setName("0");
00375     bopt->setValueText("0");
00376 
00377     if (m_gsdriver != "POSTSCRIPT")
00378     {
00379         // Fast text printing
00380         bopt = new DrBooleanOption();
00381         bopt->setName("ASCII_TO_PS");
00382         bopt->set("text",i18n("Fast text printing (non-PS printers only)"));
00383         gr->addOption(bopt);
00384         setupBooleanOption(bopt);
00385         bopt->choices()->first()->setName("NO");
00386         bopt->choices()->last()->setName("YES");
00387         bopt->setValueText("NO");
00388     }
00389 
00390     return dr;
00391 }
00392 
00393 //************************************************************************************************
00394 
00395 QString getPrintcapLine(QTextStream& t, QString *lastcomment)
00396 {
00397     QString line, buffer, comm;
00398     while (!t.eof())
00399     {
00400         buffer = t.readLine().stripWhiteSpace();
00401         if (buffer.isEmpty() || buffer[0] == '#')
00402         {
00403             comm = buffer;
00404             continue;
00405         }
00406         line.append(buffer);
00407         if (line.right(1) == "\\")
00408         {
00409             line.truncate(line.length()-1);
00410             line = line.stripWhiteSpace();
00411         }
00412         else break;
00413     }
00414     if (lastcomment)
00415         *lastcomment = comm;
00416     return line;
00417 }
KDE Home | KDE Accessibility Home | Description of Access Keys