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