driver.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 "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  * DrBase members *
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  * DrMain members *
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     // remove a possible temporary file
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  * DrGroup members *
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  * DrChoiceGroup members *
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  * DrStringOption members *
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  * DrIntegerOption members *
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  * DrFloatOption members *
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  * DrListOption members *
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     /*if (currentChoice() && currentChoice()->type() == DrBase::ChoiceGroup)
00620     {
00621         currentChoice()->createItem(item);
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  * DrConstraint members *
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         // check choices
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         // tag options
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         // return value
00670         return (f1 && f2);
00671     }
00672     return false;
00673 }
00674 
00675 /**********************
00676  * DrPageSize members *
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 }
KDE Home | KDE Accessibility Home | Description of Access Keys