00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "driver.h"
00021 #include "driveritem.h"
00022
00023 #include <qfile.h>
00024 #include <qstringlist.h>
00025 #include <kdebug.h>
00026 #include <klocale.h>
00027 #include <stdlib.h>
00028 #include <math.h>
00029
00030
00031
00032
00033
00034 DrBase::DrBase()
00035 : m_type(DrBase::Base), m_conflict(false)
00036 {
00037 }
00038
00039 DrBase::~DrBase()
00040 {
00041 }
00042
00043 QString DrBase::valueText()
00044 {
00045 return QString::null;
00046 }
00047
00048 QString DrBase::prettyText()
00049 {
00050 return valueText();
00051 }
00052
00053 void DrBase::setValueText(const QString&)
00054 {
00055 }
00056
00057 DriverItem* DrBase::createItem(DriverItem *parent, DriverItem *after)
00058 {
00059 return new DriverItem(parent, after, this);
00060 }
00061
00062 void DrBase::setOptions(const QMap<QString,QString>& opts)
00063 {
00064 if (opts.contains(name())) setValueText(opts[name()]);
00065 }
00066
00067 void DrBase::getOptions(QMap<QString,QString>& opts, bool incldef)
00068 {
00069 QString val = valueText();
00070 if ( incldef || get( "persistent" ) == "1" || get("default") != val )
00071 opts[name()] = val;
00072 }
00073
00074 DrBase* DrBase::clone()
00075 {
00076 DrBase *opt(0);
00077 switch (type())
00078 {
00079 case Main: opt = new DrMain; break;
00080 case Group: opt = new DrGroup; break;
00081 case String: opt = new DrStringOption; break;
00082 case Integer: opt = new DrIntegerOption; break;
00083 case Float: opt = new DrFloatOption; break;
00084 case List: opt = new DrListOption; break;
00085 case Boolean: opt = new DrBooleanOption; break;
00086 default: opt = new DrBase; break;
00087 }
00088 opt->m_map = m_map;
00089 opt->m_name = m_name;
00090 opt->m_conflict = m_conflict;
00091 opt->setValueText(valueText());
00092
00093 return opt;
00094 }
00095
00096
00097
00098
00099
00100 DrMain::DrMain()
00101 : DrGroup()
00102 {
00103 m_type = DrBase::Main;
00104 m_constraints.setAutoDelete(true);
00105 m_pagesizes.setAutoDelete(true);
00106 }
00107
00108 DrMain::~DrMain()
00109 {
00110
00111 if (has("temporary"))
00112 QFile::remove(get("temporary"));
00113 }
00114
00115 DriverItem* DrMain::createTreeView(QListView *parent)
00116 {
00117 DriverItem *root = new DriverItem(parent, this);
00118 createTree(root);
00119 return root;
00120 }
00121
00122 int DrMain::checkConstraints()
00123 {
00124 int result(0);
00125 clearConflict();
00126 QPtrListIterator<DrConstraint> it(m_constraints);
00127 for (;it.current();++it)
00128 if (it.current()->check(this))
00129 result++;
00130 return result;
00131 }
00132
00133 void DrMain::addPageSize(DrPageSize *ps)
00134 {
00135 m_pagesizes.insert(ps->pageName(),ps);
00136 }
00137
00138 void DrMain::removeOptionGlobally(const QString& name)
00139 {
00140 DrGroup *grp(0);
00141 DrBase *opt = findOption(name, &grp);
00142
00143 if (opt && grp)
00144 {
00145 grp->removeOption(name);
00146 if (grp->isEmpty())
00147 removeGroup(grp);
00148 }
00149 }
00150
00151 void DrMain::removeGroupGlobally(DrGroup *grp)
00152 {
00153 DrGroup *parent(0);
00154 if (findGroup(grp, &parent) && parent)
00155 {
00156 parent->removeGroup(grp);
00157 if (parent->isEmpty() && parent != this)
00158 removeGroupGlobally(parent);
00159 }
00160 }
00161
00162 QMap<QString, DrBase*> DrMain::flatten()
00163 {
00164 QMap<QString, DrBase*> optmap;
00165 int index(0);
00166 flattenGroup(optmap, index);
00167 return optmap;
00168 }
00169
00170 DrMain* DrMain::cloneDriver()
00171 {
00172 DrMain *driver = static_cast<DrMain*>(clone());
00173
00174 QPtrListIterator<DrConstraint> cit(m_constraints);
00175 for (; cit.current(); ++cit)
00176 driver->addConstraint(new DrConstraint(*(cit.current())));
00177
00178 QDictIterator<DrPageSize> pit(m_pagesizes);
00179 for (; pit.current(); ++pit)
00180 driver->addPageSize(new DrPageSize(*(pit.current())));
00181
00182 return driver;
00183 }
00184
00185
00186
00187
00188
00189 DrGroup::DrGroup()
00190 : DrBase()
00191 {
00192 m_type = DrBase::Group;
00193
00194 m_subgroups.setAutoDelete(true);
00195 m_options.setAutoDelete(true);
00196 m_listoptions.setAutoDelete(false);
00197 }
00198
00199 DrGroup::~DrGroup()
00200 {
00201 }
00202
00203 void DrGroup::addOption(DrBase *opt)
00204 {
00205 if (!opt->name().isEmpty())
00206 {
00207 m_options.insert(opt->name(),opt);
00208 m_listoptions.append(opt);
00209 }
00210 }
00211
00212 void DrGroup::addGroup(DrGroup *grp)
00213 {
00214 m_subgroups.append(grp);
00215 }
00216
00217 void DrGroup::addObject(DrBase *optgrp)
00218 {
00219 if (optgrp->isOption())
00220 addOption(optgrp);
00221 else if (optgrp->type() == DrBase::Group)
00222 addGroup(static_cast<DrGroup*>(optgrp));
00223 }
00224
00225 void DrGroup::removeOption(const QString& name)
00226 {
00227 DrBase *opt = m_options.find(name);
00228 if (opt)
00229 {
00230 m_listoptions.removeRef(opt);
00231 m_options.remove(name);
00232 }
00233 }
00234
00235 void DrGroup::removeGroup(DrGroup *grp)
00236 {
00237 m_subgroups.removeRef(grp);
00238 }
00239
00240 bool DrGroup::isEmpty()
00241 {
00242 return (m_options.count()+m_subgroups.count() == 0);
00243 }
00244
00245 DriverItem* DrGroup::createItem(DriverItem *parent, DriverItem *after)
00246 {
00247 DriverItem *item = DrBase::createItem(parent, after);
00248 createTree(item);
00249 return item;
00250 }
00251
00252 void DrGroup::createTree(DriverItem *parent)
00253 {
00254 DriverItem *item(0);
00255
00256 QPtrListIterator<DrGroup> lit(m_subgroups);
00257 for (;lit.current();++lit)
00258 item = lit.current()->createItem(parent, item);
00259
00260 QPtrListIterator<DrBase> dit(m_listoptions);
00261 for (;dit.current();++dit)
00262 item = dit.current()->createItem(parent, item);
00263 }
00264
00265 DrBase* DrGroup::findOption(const QString& name, DrGroup **parentGroup)
00266 {
00267 DrBase *opt = m_options.find(name);
00268 if (!opt)
00269 {
00270 QPtrListIterator<DrGroup> it(m_subgroups);
00271 for (;it.current() && !opt; ++it)
00272 opt = it.current()->findOption(name, parentGroup);
00273 }
00274 else if (parentGroup)
00275 *parentGroup = this;
00276 return opt;
00277 }
00278
00279 DrGroup* DrGroup::findGroup(DrGroup *grp, DrGroup ** parentGroup)
00280 {
00281 DrGroup *group = (m_subgroups.findRef(grp) == -1 ? 0 : grp);
00282 if (!group)
00283 {
00284 QPtrListIterator<DrGroup> it(m_subgroups);
00285 for (;it.current() && !group; ++it)
00286 group = it.current()->findGroup(grp, parentGroup);
00287 }
00288 else if (parentGroup)
00289 *parentGroup = this;
00290 return group;
00291 }
00292
00293 void DrGroup::clearConflict()
00294 {
00295 QDictIterator<DrBase> dit(m_options);
00296 for (;dit.current();++dit)
00297 dit.current()->setConflict(false);
00298
00299 QPtrListIterator<DrGroup> lit(m_subgroups);
00300 for (;lit.current();++lit)
00301 lit.current()->clearConflict();
00302 }
00303
00304 void DrGroup::setOptions(const QMap<QString,QString>& opts)
00305 {
00306 QDictIterator<DrBase> dit(m_options);
00307 for (;dit.current();++dit)
00308 dit.current()->setOptions(opts);
00309
00310 QPtrListIterator<DrGroup> lit(m_subgroups);
00311 for (;lit.current();++lit)
00312 lit.current()->setOptions(opts);
00313 }
00314
00315 void DrGroup::getOptions(QMap<QString,QString>& opts, bool incldef)
00316 {
00317 QDictIterator<DrBase> dit(m_options);
00318 for (;dit.current();++dit)
00319 dit.current()->getOptions(opts,incldef);
00320
00321 QPtrListIterator<DrGroup> lit(m_subgroups);
00322 for (;lit.current();++lit)
00323 lit.current()->getOptions(opts,incldef);
00324 }
00325
00326 void DrGroup::flattenGroup(QMap<QString, DrBase*>& optmap, int& index)
00327 {
00328 QPtrListIterator<DrGroup> git(m_subgroups);
00329 for (; git.current(); ++git)
00330 git.current()->flattenGroup(optmap, index);
00331
00332 QDictIterator<DrBase> oit(m_options);
00333 for (; oit.current(); ++oit)
00334 optmap[oit.current()->name()] = oit.current();
00335
00336 if (name().isEmpty())
00337 optmap[QString::fromLatin1("group%1").arg(index++)] = this;
00338 else
00339 optmap[name()] = this;
00340
00341 m_subgroups.setAutoDelete(false);
00342 m_options.setAutoDelete(false);
00343 m_subgroups.clear();
00344 m_options.clear();
00345 m_listoptions.clear();
00346 m_subgroups.setAutoDelete(true);
00347 m_options.setAutoDelete(true);
00348 }
00349
00350 DrBase* DrGroup::clone()
00351 {
00352 DrGroup *grp = static_cast<DrGroup*>(DrBase::clone());
00353
00354 QPtrListIterator<DrGroup> git(m_subgroups);
00355 for (; git.current(); ++git)
00356 grp->addGroup(static_cast<DrGroup*>(git.current()->clone()));
00357
00358 QPtrListIterator<DrBase> oit(m_listoptions);
00359 for (; oit.current(); ++oit)
00360 grp->addOption(oit.current()->clone());
00361
00362 return static_cast<DrBase*>(grp);
00363 }
00364
00365 QString DrGroup::groupForOption( const QString& optname )
00366 {
00367 QString grpname;
00368 if ( optname == "PageSize" ||
00369 optname == "InputSlot" ||
00370 optname == "ManualFeed" ||
00371 optname == "MediaType" ||
00372 optname == "MediaColor" ||
00373 optname == "MediaWeight" ||
00374 optname == "Duplex" ||
00375 optname == "DoubleSided" ||
00376 optname == "Copies" )
00377 grpname = i18n( "General" );
00378 else if ( optname.startsWith( "stp" ) ||
00379 optname == "Cyan" ||
00380 optname == "Yellow" ||
00381 optname == "Magenta" ||
00382 optname == "Black" ||
00383 optname == "Density" ||
00384 optname == "Contrast" )
00385 grpname = i18n( "Adjustments" );
00386 else if ( optname.startsWith( "JCL" ) )
00387 grpname = i18n( "JCL" );
00388 else
00389 grpname = i18n( "Others" );
00390 return grpname;
00391 }
00392
00393
00394
00395
00396
00397 DrChoiceGroup::DrChoiceGroup()
00398 : DrGroup()
00399 {
00400 m_type = DrBase::ChoiceGroup;
00401 }
00402
00403 DrChoiceGroup::~DrChoiceGroup()
00404 {
00405 }
00406
00407 DriverItem* DrChoiceGroup::createItem(DriverItem *parent, DriverItem*)
00408 {
00409 createTree(parent);
00410 return NULL;
00411 }
00412
00413
00414
00415
00416
00417 DrStringOption::DrStringOption()
00418 : DrBase()
00419 {
00420 m_type = DrBase::String;
00421 }
00422
00423 DrStringOption::~DrStringOption()
00424 {
00425 }
00426
00427 QString DrStringOption::valueText()
00428 {
00429 return m_value;
00430 }
00431
00432 void DrStringOption::setValueText(const QString& s)
00433 {
00434 m_value = s;
00435 }
00436
00437
00438
00439
00440
00441 DrIntegerOption::DrIntegerOption()
00442 : DrBase()
00443 {
00444 m_type = DrBase::Integer;
00445 m_value = 0;
00446 set("minval","0");
00447 set("maxval","10");
00448 }
00449
00450 DrIntegerOption::~DrIntegerOption()
00451 {
00452 }
00453
00454 QString DrIntegerOption::valueText()
00455 {
00456 QString s = QString::number(m_value);
00457 return s;
00458 }
00459
00460 void DrIntegerOption::setValueText(const QString& s)
00461 {
00462 m_value = s.toInt();
00463 }
00464
00465 QString DrIntegerOption::fixedVal()
00466 {
00467 QStringList vals = QStringList::split("|", get("fixedvals"), false);
00468 if (vals.count() == 0)
00469 return valueText();
00470 int d(0);
00471 QString val;
00472 for (QStringList::Iterator it=vals.begin(); it!=vals.end(); ++it)
00473 {
00474 int thisVal = (*it).toInt();
00475 if (val.isEmpty() || abs(thisVal - m_value) < d)
00476 {
00477 d = abs(thisVal - m_value);
00478 val = *it;
00479 }
00480 }
00481 if (val.isEmpty())
00482 return valueText();
00483 else
00484 return val;
00485 }
00486
00487
00488
00489
00490
00491 DrFloatOption::DrFloatOption()
00492 : DrBase()
00493 {
00494 m_type = DrBase::Float;
00495 m_value = 0.0;
00496 set("minval","0.0");
00497 set("maxval","1.0");
00498 }
00499
00500 DrFloatOption::~DrFloatOption()
00501 {
00502 }
00503
00504 QString DrFloatOption::valueText()
00505 {
00506 QString s = QString::number(m_value,'f',3);
00507 return s;
00508 }
00509
00510 void DrFloatOption::setValueText(const QString& s)
00511 {
00512 m_value = s.toFloat();
00513 }
00514
00515 QString DrFloatOption::fixedVal()
00516 {
00517 QStringList vals = QStringList::split("|", get("fixedvals"), false);
00518 if (vals.count() == 0)
00519 return valueText();
00520 float d(0);
00521 QString val;
00522 for (QStringList::Iterator it=vals.begin(); it!=vals.end(); ++it)
00523 {
00524 float thisVal = (*it).toFloat();
00525 if (val.isEmpty() || fabs(thisVal - m_value) < d)
00526 {
00527 d = fabs(thisVal - m_value);
00528 val = *it;
00529 }
00530 }
00531 if (val.isEmpty())
00532 return valueText();
00533 else
00534 return val;
00535 }
00536
00537
00538
00539
00540
00541 DrListOption::DrListOption()
00542 : DrBase()
00543 {
00544 m_type = DrBase::List;
00545
00546 m_choices.setAutoDelete(true);
00547 m_current = 0;
00548 }
00549
00550 DrListOption::~DrListOption()
00551 {
00552 }
00553
00554 QString DrListOption::valueText()
00555 {
00556 QString s = (m_current ? m_current->name() : QString::null);
00557 return s;
00558 }
00559
00560 QString DrListOption::prettyText()
00561 {
00562 if (m_current)
00563 return m_current->get("text");
00564 else
00565 return QString::null;
00566 }
00567
00568 void DrListOption::setValueText(const QString& s)
00569 {
00570 m_current = findChoice(s);
00571 if (!m_current)
00572 {
00573 bool ok;
00574 int index = s.toInt(&ok);
00575 if (ok)
00576 setChoice(index);
00577 }
00578 }
00579
00580 DrBase* DrListOption::findChoice(const QString& txt)
00581 {
00582 QPtrListIterator<DrBase> it(m_choices);
00583 for (;it.current();++it)
00584 if (it.current()->name() == txt)
00585 return it.current();
00586 return NULL;
00587 }
00588
00589 DrBase* DrListOption::clone()
00590 {
00591 DrListOption *opt = static_cast<DrListOption*>(DrBase::clone());
00592
00593 QPtrListIterator<DrBase> it(m_choices);
00594 for (; it.current(); ++it)
00595 opt->addChoice(it.current()->clone());
00596
00597 opt->setValueText(valueText());
00598
00599 return static_cast<DrBase*>(opt);
00600 }
00601
00602 void DrListOption::getOptions(QMap<QString,QString>& opts, bool incldef)
00603 {
00604 DrBase::getOptions(opts, incldef);
00605 if (currentChoice() && currentChoice()->type() == DrBase::ChoiceGroup)
00606 currentChoice()->getOptions(opts, incldef);
00607 }
00608
00609 void DrListOption::setOptions(const QMap<QString,QString>& opts)
00610 {
00611 DrBase::setOptions(opts);
00612 if (currentChoice() && currentChoice()->type() == DrBase::ChoiceGroup)
00613 currentChoice()->setOptions(opts);
00614 }
00615
00616 DriverItem* DrListOption::createItem(DriverItem *parent, DriverItem *after)
00617 {
00618 DriverItem *item = DrBase::createItem(parent, after);
00619
00620
00621
00622
00623 return item;
00624 }
00625
00626 void DrListOption::setChoice(int choicenum)
00627 {
00628 if (choicenum >= 0 && choicenum < (int)m_choices.count())
00629 {
00630 setValueText(m_choices.at(choicenum)->name());
00631 }
00632 }
00633
00634
00635
00636
00637
00638 DrConstraint::DrConstraint(const QString& o1, const QString& o2, const QString& c1, const QString& c2)
00639 : m_opt1(o1), m_opt2(o2), m_choice1(c1), m_choice2(c2), m_option1(0), m_option2(0)
00640 {
00641 }
00642
00643 DrConstraint::DrConstraint(const DrConstraint& d)
00644 : m_opt1(d.m_opt1), m_opt2(d.m_opt2), m_choice1(d.m_choice1), m_choice2(d.m_choice2), m_option1(0), m_option2(0)
00645 {
00646 }
00647
00648 bool DrConstraint::check(DrMain *driver)
00649 {
00650 if (!m_option1) m_option1 = (DrListOption*)driver->findOption(m_opt1);
00651 if (!m_option2) m_option2 = (DrListOption*)driver->findOption(m_opt2);
00652 if (m_option1 && m_option2 && m_option1->currentChoice() && m_option2->currentChoice())
00653 {
00654 bool f1(false), f2(false);
00655 QString c1(m_option1->currentChoice()->name()), c2(m_option2->currentChoice()->name());
00656
00657 if (m_choice1.isEmpty())
00658 f1 = (c1 != "None" && c1 != "Off" && c1 != "False");
00659 else
00660 f1 = (c1 == m_choice1);
00661 if (m_choice2.isEmpty())
00662 f2 = (c2 != "None" && c2 != "Off" && c2 != "False");
00663 else
00664 f2 = (c2 == m_choice2);
00665
00666 QString s((f1 && f2 ? "1" : "0"));
00667 if (!m_option1->conflict()) m_option1->setConflict(f1 && f2);
00668 if (!m_option2->conflict()) m_option2->setConflict(f1 && f2);
00669
00670 return (f1 && f2);
00671 }
00672 return false;
00673 }
00674
00675
00676
00677
00678
00679 DrPageSize::DrPageSize(const QString& s, float width, float height, float left, float bottom, float right, float top)
00680 : m_name(s),
00681 m_width( width ),
00682 m_height( height ),
00683 m_left( left ),
00684 m_bottom( bottom ),
00685 m_right( right ),
00686 m_top( top )
00687 {
00688 }
00689
00690 DrPageSize::DrPageSize(const DrPageSize& d)
00691 : m_name(d.m_name),
00692 m_width( d.m_width ),
00693 m_height( d.m_height ),
00694 m_left( d.m_left ),
00695 m_bottom( d.m_bottom ),
00696 m_right( d.m_right ),
00697 m_top( d.m_top )
00698 {
00699 }
00700
00701 QSize DrPageSize::pageSize() const
00702 {
00703 return QSize( ( int )m_width, ( int )m_height );
00704 }
00705
00706 QRect DrPageSize::pageRect() const
00707 {
00708 return QRect( ( int )( m_left+0.5 ), ( int )( m_top+0.5 ), ( int )( m_width-m_left-m_right ), ( int )( m_height-m_top-m_bottom ) );
00709 }
00710
00711 QSize DrPageSize::margins() const
00712 {
00713 return QSize( ( int )( m_left+0.5 ), ( int )( m_top+0.5 ) );
00714 }