00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
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
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
00232 gr = new DrGroup();
00233 gr->set("text",i18n("GhostScript settings"));
00234 dr->addGroup(gr);
00235
00236
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
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
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
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
00306 gr = new DrGroup();
00307 gr->set("text",i18n("General"));
00308 dr->addGroup(gr);
00309
00310
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
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
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
00355 gr = new DrGroup();
00356 gr->set("text",i18n("Text options"));
00357 dr->addGroup(gr);
00358
00359
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
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
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 }