kpilot Library API Documentation

conduitConfigDialog.cc

00001 /* conduitConfigDialog.cc KPilot 00002 ** 00003 ** Copyright (C) 2001 by Dan Pilone 00004 ** 00005 ** This file defines a .ui-based configuration dialog for conduits. 00006 */ 00007 00008 /* 00009 ** This program is free software; you can redistribute it and/or modify 00010 ** it under the terms of the GNU General Public License as published by 00011 ** the Free Software Foundation; either version 2 of the License, or 00012 ** (at your option) any later version. 00013 ** 00014 ** This program is distributed in the hope that it will be useful, 00015 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 ** GNU General Public License for more details. 00018 ** 00019 ** You should have received a copy of the GNU General Public License 00020 ** along with this program in a file called COPYING; if not, write to 00021 ** the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 00022 ** MA 02111-1307, USA. 00023 */ 00024 00025 /* 00026 ** Bug reports and questions can be sent to kde-pim@kde.org 00027 */ 00028 00029 static const char *conduitconfigdialog_id = 00030 "$Id: conduitConfigDialog.cc,v 1.30 2003/11/22 12:20:12 kainhofe Exp $"; 00031 00032 #include "options.h" 00033 00034 #include <qlistview.h> 00035 #include <qlabel.h> 00036 #include <qtooltip.h> 00037 #include <qfile.h> 00038 #include <qpushbutton.h> 00039 #include <qhbox.h> 00040 #include <qlayout.h> 00041 #include <qwidgetstack.h> 00042 #include <qvbox.h> 00043 00044 #include <kservice.h> 00045 #include <kservicetype.h> 00046 #include <kuserprofile.h> 00047 #include <kprocess.h> 00048 #include <kmessagebox.h> 00049 #include <kglobal.h> 00050 #include <kstandarddirs.h> 00051 #include <klibloader.h> 00052 #include <kseparator.h> 00053 00054 #include "plugin.h" 00055 #include "kpilotConfig.h" 00056 00057 #include "conduitConfigDialog.moc" 00058 00059 #define CONDUIT_NAME (0) 00060 #define CONDUIT_COMMENT (1) 00061 #define CONDUIT_DESKTOP (2) 00062 #define CONDUIT_LIBRARY (3) 00063 00064 class ConduitTip : public QToolTip 00065 { 00066 public: 00067 ConduitTip(QListView *parent); 00068 virtual ~ConduitTip(); 00069 00070 protected: 00071 virtual void maybeTip(const QPoint &); 00072 00073 QListView *fListView; 00074 } ; 00075 00076 00077 ConduitTip::ConduitTip(QListView *p) : 00078 QToolTip(p->viewport(),0L), 00079 fListView(p) 00080 { 00081 FUNCTIONSETUP; 00082 } 00083 00084 ConduitTip::~ConduitTip() 00085 { 00086 FUNCTIONSETUP; 00087 } 00088 00089 /* virtual */ void ConduitTip::maybeTip(const QPoint &p) 00090 { 00091 FUNCTIONSETUP; 00092 00093 QListViewItem *l = fListView->itemAt(p); 00094 00095 if (!l) return; 00096 00097 // ConduitListItem *q = static_cast<ConduitListItem *>(l); 00098 00099 #ifdef DEBUG 00100 DEBUGKPILOT << fname 00101 << ": Tip over " 00102 << l->text(CONDUIT_NAME) 00103 << " with text " 00104 << l->text(CONDUIT_COMMENT) 00105 << endl; 00106 #endif 00107 00108 QString s = l->text(CONDUIT_COMMENT); 00109 00110 if (s.isEmpty()) return; 00111 if (s.find(CSL1("<qt>"),0,false) == -1) 00112 { 00113 s.prepend(CSL1("<qt>")); 00114 s.append(CSL1("</qt>")); 00115 } 00116 00117 tip(fListView->itemRect(l),s); 00118 } 00119 00120 // Page numbers in the widget stack 00121 #define INTRO (0) 00122 #define OLD_CONDUIT (1) 00123 #define BROKEN_CONDUIT (2) 00124 #define INTERNAL_CONDUIT (3) 00125 #define NEW_CONDUIT (4) 00126 00127 00128 ConduitConfigWidgetBase::ConduitConfigWidgetBase(QHBox *p,const char *n) : 00129 QObject(p,n) 00130 { 00131 p->setSpacing(10); 00132 00133 QWidget *w = 0L; // For spacing purposes only. 00134 QLabel *l = 0L; 00135 QVBox *v = 0L; 00136 00137 // Create the left hand column 00138 v = new QVBox(p); 00139 fConduitList = new QListView(v,"ConduitList"); 00140 fConduitList->addColumn(i18n("Conduit")); 00141 v->setStretchFactor(fConduitList,0); 00142 v->setSpacing(50); 00143 l = new QLabel(v); // Just a placekeeper, to fix redraw problems. 00144 l->resize(30,30); 00145 v->setStretchFactor(l,100); 00146 00147 // Right hand column 00148 fStack = new QWidgetStack(p,"RightPart"); 00149 00150 // Zero'th page in stack 00151 l = new QLabel(fStack); 00152 l->setFrameShape(QLabel::Box); 00153 l->setText(i18n("<qt>Select a conduit in the list to configure it. " 00154 "Checked conduits will be run during a HotSync.</qt>")); 00155 l->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter | Qt::ExpandTabs | Qt::WordBreak); 00156 fStack->addWidget(l,INTRO); 00157 00158 // First page in stack (right hand column) 00159 l = new QLabel(fStack); 00160 l->setFrameShape(QLabel::Box); 00161 l->setText(i18n("<qt>This conduit appears to be broken and cannot " 00162 "be configured.</qt>")); 00163 l->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter | Qt::ExpandTabs | Qt::WordBreak); 00164 fStack->addWidget(l,BROKEN_CONDUIT); 00165 00166 // Second page, now with layout in a single column 00167 v = new QVBox(fStack,"OldStyle"); 00168 w = new QWidget(v); 00169 v->setStretchFactor(w,50); 00170 fOldStyleLabel = new QLabel(v); 00171 // Within this column, center the button box 00172 QHBox *h = new QHBox(v,"ButtonBox"); 00173 w = new QWidget(h); 00174 h->setStretchFactor(w,50); 00175 fConfigureButton = new QPushButton(h); 00176 fConfigureButton->setText(i18n("Configure...")); 00177 w = new QWidget(h); 00178 h->setStretchFactor(w,50); 00179 // Add stretch beneath the button box 00180 w = new QWidget(v); 00181 v->setStretchFactor(w,50); 00182 fStack->addWidget(v,OLD_CONDUIT); 00183 00184 // Page 3 00185 l = new QLabel(fStack); 00186 l->setFrameShape(QLabel::Box); 00187 l->setText(i18n("<qt>This is an internal conduit which has no " 00188 "configuration options.</qt>")); 00189 l->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter | Qt::ExpandTabs | Qt::WordBreak); 00190 fStack->addWidget(l,INTERNAL_CONDUIT); 00191 } 00192 00193 00194 ConduitConfigDialog::ConduitConfigDialog(QWidget * _w, const char *n, 00195 bool m) : UIDialog(_w, n, Ok|Apply|Cancel,m) 00196 { 00197 FUNCTIONSETUP; 00198 00199 enableButtonSeparator(true); 00200 // selected(0L); 00201 00202 QHBox *h = dynamic_cast<QHBox *>(widget()); 00203 if (!h) 00204 { 00205 h = new QHBox(widget()); 00206 } 00207 00208 fConfigWidget = new ConduitConfigWidget(h,0L); 00209 00210 QObject::connect(fConfigWidget,SIGNAL(sizeChanged()), 00211 h,SLOT(adjustSize())); 00212 QObject::connect(fConfigWidget,SIGNAL(sizeChanged()), 00213 this,SLOT(adjustSize())); 00214 00215 (void) conduitconfigdialog_id; 00216 } 00217 00218 ConduitConfigDialog::~ConduitConfigDialog() 00219 { 00220 FUNCTIONSETUP; 00221 } 00222 00223 /* virtual */ bool ConduitConfigDialog::validate() 00224 { 00225 return fConfigWidget->release(); 00226 } 00227 00228 /* virtual */ void ConduitConfigDialog::commitChanges() 00229 { 00230 fConfigWidget->commitChanges(); 00231 } 00232 00233 /* virtual */ void ConduitConfigDialog::slotApply() 00234 { 00235 commitChanges(); 00236 } 00237 00238 #define PAGE_SIZE QSize(440,300) 00239 00240 ConduitConfigWidget::ConduitConfigWidget(QHBox *p, const char *n, 00241 bool) : 00242 ConduitConfigWidgetBase(p,n), 00243 fConfigure(0L), 00244 fCurrentConduit(0L), 00245 fCurrentConfig(0L), 00246 fCurrentOldStyle(0L), 00247 fParentWidget(p) 00248 { 00249 FUNCTIONSETUP; 00250 00251 // fConduitList->removeColumn(CONDUIT_COMMENT); 00252 fillLists(); 00253 fConduitList->adjustSize(); 00254 fConduitList->show(); 00255 00256 fStack->resize(PAGE_SIZE); 00257 fStack->setMinimumSize(PAGE_SIZE); 00258 00259 QObject::connect(fConduitList, 00260 SIGNAL(selectionChanged(QListViewItem *)), 00261 this,SLOT(selected(QListViewItem *))); 00262 QObject::connect(fConfigureButton, 00263 SIGNAL(clicked()), 00264 this,SLOT(configure())); 00265 00266 selected(0L); 00267 // adjustSize(); 00268 fStack->raiseWidget(INTRO); 00269 00270 (void) new ConduitTip(fConduitList); 00271 } 00272 00273 ConduitConfigWidget::~ConduitConfigWidget() 00274 { 00275 FUNCTIONSETUP; 00276 release(); 00277 } 00278 00279 void ConduitConfigWidget::fillLists() 00280 { 00281 FUNCTIONSETUP; 00282 00283 QStringList potentiallyInstalled = 00284 KPilotConfig::getConfig().setConduitGroup(). 00285 getInstalledConduits(); 00286 KServiceTypeProfile::OfferList offers = 00287 KServiceTypeProfile::offers(CSL1("KPilotConduit")); 00288 00289 QValueListIterator < KServiceOffer > availList(offers.begin()); 00290 while (availList != offers.end()) 00291 { 00292 KSharedPtr < KService > o = (*availList).service(); 00293 00294 #ifdef DEBUG 00295 DEBUGKPILOT << fname << ": " 00296 << o->desktopEntryName() 00297 << " = " << o->name() << endl; 00298 #endif 00299 00300 QCheckListItem *p = 0L; 00301 00302 if (!o->exec().isEmpty()) 00303 { 00304 kdWarning() << k_funcinfo 00305 << ": Old-style conduit found " 00306 << o->name() 00307 << endl; 00308 } 00309 00310 p = new QCheckListItem(fConduitList, 00311 o->name(), 00312 QCheckListItem::CheckBox); 00313 p->setMultiLinesEnabled(true); 00314 p->setText(CONDUIT_COMMENT,o->comment()); 00315 p->setText(CONDUIT_DESKTOP,o->desktopEntryName()); 00316 p->setText(CONDUIT_LIBRARY,o->library()); 00317 00318 if (potentiallyInstalled.findIndex(o->desktopEntryName()) < 0) 00319 { 00320 p->setOn(false); 00321 } 00322 else 00323 { 00324 p->setOn(true); 00325 } 00326 00327 ++availList; 00328 } 00329 00330 // Now the (statically compiled) internal conduits 00331 QCheckListItem *p = 0L; 00332 #define IC(a,b,c) p = new QCheckListItem(fConduitList,i18n(a),QCheckListItem::CheckBox); \ 00333 p->setText(CONDUIT_COMMENT,i18n(c)); \ 00334 p->setText(CONDUIT_LIBRARY,"internal_" b); \ 00335 p->setText(CONDUIT_DESKTOP,"internal_" b); \ 00336 if (potentiallyInstalled.findIndex(p->text(CONDUIT_DESKTOP))>=0) \ 00337 p->setOn(true); 00338 00339 IC("Kroupware","kroupware", 00340 "Sync the handheld with a Kroupware client (for example, KMail)."); 00341 IC("Install Files","fileinstall", 00342 "Install files that are dragged to KPilot onto the handheld."); 00343 00344 #undef IC 00345 } 00346 00347 void ConduitConfigWidget::loadAndConfigure(QListViewItem *p) // ,bool exec) 00348 { 00349 FUNCTIONSETUP; 00350 00351 if (!p) 00352 { 00353 #ifdef DEBUG 00354 DEBUGKPILOT << fname 00355 << ": Executed NULL conduit?" 00356 << endl; 00357 #endif 00358 fStack->raiseWidget(INTRO); 00359 return; 00360 } 00361 00362 #ifdef DEBUG 00363 DEBUGKPILOT << fname 00364 << ": Executing conduit " 00365 << p->text(CONDUIT_NAME) 00366 << endl; 00367 #endif 00368 00369 if (p->text(CONDUIT_LIBRARY).isEmpty()) 00370 { 00371 fStack->raiseWidget(BROKEN_CONDUIT); 00372 warnNoExec(p); 00373 return; 00374 } 00375 00376 if (p->text(CONDUIT_LIBRARY).startsWith(CSL1("internal_"))) 00377 { 00378 fStack->raiseWidget(INTERNAL_CONDUIT); 00379 return; 00380 } 00381 00382 QCString library = QFile::encodeName(p->text(CONDUIT_LIBRARY)); 00383 00384 KLibFactory *f = KLibLoader::self()-> 00385 factory(library); 00386 if (!f) 00387 { 00388 #ifdef DEBUG 00389 DEBUGKPILOT << fname 00390 << ": No conduit library " 00391 << library 00392 << " found." 00393 << endl; 00394 #endif 00395 fStack->raiseWidget(BROKEN_CONDUIT); 00396 warnNoLibrary(p); 00397 return; 00398 } 00399 00400 QStringList a; 00401 a.append(CSL1("modal")); 00402 00403 // QObject *o = f->create(this, 0L, "ConduitConfig",a); 00404 QObject *o = f->create(fStack, 0L, "ConduitConfigBase", a); 00405 bool oldstyle=false; 00406 00407 if (!o) 00408 { 00409 #ifdef DEBUG 00410 DEBUGKPILOT << fname 00411 << ": Can't create ConduitConfigBase - must be old conduit." 00412 << endl; 00413 #endif 00414 00415 o = f->create(fParentWidget,0L,"ConduitConfig",a); 00416 oldstyle=true; 00417 00418 if (!o) 00419 { 00420 #ifdef DEBUG 00421 DEBUGKPILOT << fname 00422 << ": No ConduitConfig either." 00423 << endl; 00424 #endif 00425 KLibLoader::self()->unloadLibrary( 00426 library); 00427 fStack->raiseWidget(BROKEN_CONDUIT); 00428 warnNoLibrary(p); 00429 return; 00430 } 00431 } 00432 00433 if (oldstyle) 00434 { 00435 ConduitConfig *d = dynamic_cast<ConduitConfig *>(o); 00436 00437 if (!d) 00438 { 00439 #ifdef DEBUG 00440 DEBUGKPILOT << fname 00441 << ": Can't cast to config dialog." 00442 << endl; 00443 #endif 00444 fStack->raiseWidget(BROKEN_CONDUIT); 00445 warnNoLibrary(p); 00446 return; 00447 } 00448 fStack->raiseWidget(OLD_CONDUIT); 00449 fOldStyleLabel->setText(i18n("<qt>The conduit <i>%1</i> " 00450 "is an old-style conduit. To configure it, " 00451 "click the configure button below.</qt>") 00452 .arg(p->text(CONDUIT_NAME))); 00453 00454 fCurrentOldStyle=d; 00455 d->setConfig(&KPilotConfig::getConfig()); 00456 d->readSettings(); 00457 } 00458 else 00459 { 00460 ConduitConfigBase *d = dynamic_cast<ConduitConfigBase *>(o); 00461 00462 if (!d) 00463 { 00464 #ifdef DEBUG 00465 DEBUGKPILOT << fname 00466 << ": Can't cast to config base object." 00467 << endl; 00468 #endif 00469 fStack->raiseWidget(BROKEN_CONDUIT); 00470 warnNoLibrary(p); 00471 return; 00472 } 00473 00474 // Remove the config widget from the stack before we can add the new one 00475 QWidget *oldConfigWidget = fStack->widget( NEW_CONDUIT ); 00476 if ( oldConfigWidget ) 00477 { 00478 fStack->removeWidget( oldConfigWidget ); 00479 KPILOT_DELETE( oldConfigWidget ); 00480 } 00481 if (fStack->addWidget(d->widget(),NEW_CONDUIT)<0) 00482 { 00483 #ifdef DEBUG 00484 DEBUGKPILOT << fname 00485 << ": Can't add config widget to stack." 00486 << endl; 00487 #endif 00488 } 00489 else 00490 { 00491 d->load(&KPilotConfig::getConfig()); 00492 fStack->raiseWidget(NEW_CONDUIT); 00493 d->widget()->show(); 00494 fCurrentConfig=d; 00495 } 00496 } 00497 } 00498 00499 bool ConduitConfigWidget::release() 00500 { 00501 FUNCTIONSETUP; 00502 if (fCurrentConfig) 00503 { 00504 if (!fCurrentConfig->maybeSave(&KPilotConfig::getConfig())) 00505 return false; 00506 fStack->raiseWidget(0); 00507 delete fCurrentConfig; 00508 } 00509 if (fCurrentOldStyle) 00510 { 00511 fStack->raiseWidget(0); 00512 delete fCurrentOldStyle; 00513 } 00514 if (fCurrentConduit) 00515 { 00516 KLibLoader::self()->unloadLibrary( 00517 QFile::encodeName(fCurrentConduit->text(CONDUIT_LIBRARY))); 00518 } 00519 fCurrentConduit=0L; 00520 fCurrentConfig=0L; 00521 fCurrentOldStyle=0L; 00522 return true; 00523 } 00524 00525 void ConduitConfigWidget::selected(QListViewItem *p) 00526 { 00527 FUNCTIONSETUP; 00528 #ifdef DEBUG 00529 DEBUGKPILOT << fname << ": " 00530 << ( p ? p->text(CONDUIT_NAME) : CSL1("None") ) 00531 << endl; 00532 #endif 00533 if (p!=fCurrentConduit) 00534 { 00535 if (!release()) 00536 { 00537 p->setSelected(false); 00538 fCurrentConduit->setSelected(true); 00539 return; 00540 } 00541 } 00542 fCurrentConduit=p; 00543 loadAndConfigure(p); 00544 fStack->adjustSize(); 00545 #ifdef DEBUG 00546 DEBUGKPILOT << fname << ": New widget size " 00547 << fStack->size().width() << "x" << fStack->size().height() << endl; 00548 DEBUGKPILOT << fname << ": Parent current size " 00549 << fParentWidget->size().width() << "x" 00550 << fParentWidget->size().height() << endl; 00551 #endif 00552 emit sizeChanged(); 00553 #ifdef DEBUG 00554 DEBUGKPILOT << fname << ": Parent new size " 00555 << fParentWidget->size().width() << "x" 00556 << fParentWidget->size().height() << endl; 00557 #endif 00558 00559 } 00560 00561 void ConduitConfigWidget::configure() 00562 { 00563 if (!fCurrentOldStyle) 00564 { 00565 loadAndConfigure(fConduitList->selectedItem()); 00566 } 00567 if (fCurrentOldStyle) 00568 { 00569 fCurrentOldStyle->exec(); 00570 } 00571 } 00572 00573 void ConduitConfigWidget::warnNoExec(const QListViewItem * p) 00574 { 00575 FUNCTIONSETUP; 00576 00577 QString msg = i18n("<qt>No library could be " 00578 "found for the conduit %1. This means that the " 00579 "conduit was not installed properly.</qt>") 00580 .arg(p->text(CONDUIT_NAME)); 00581 00582 #ifdef DEBUG 00583 DEBUGKPILOT << fname << ": No library for " 00584 << p->text(CONDUIT_NAME) << endl; 00585 #endif 00586 00587 KMessageBox::error(fParentWidget, msg, i18n("Conduit Error")); 00588 } 00589 00590 void ConduitConfigWidget::warnNoLibrary(const QListViewItem *p) 00591 { 00592 FUNCTIONSETUP; 00593 00594 QString msg = i18n("<qt>There was a problem loading the library " 00595 "for the conduit %1. This means that the " 00596 "conduit was not installed properly.</qt>") 00597 .arg(p->text(CONDUIT_NAME)); 00598 00599 #ifdef DEBUG 00600 DEBUGKPILOT << fname << ": Can't load library for " 00601 << p->text(CONDUIT_NAME) << endl; 00602 #endif 00603 00604 KMessageBox::error(fParentWidget, msg, i18n("Conduit Error")); 00605 } 00606 00607 /* virtual */ void ConduitConfigWidget::commitChanges() 00608 { 00609 FUNCTIONSETUP; 00610 00611 // Only new-style conduits have changes that need to be commited 00612 // old-style conduits have their own config dlg which commits them itself 00613 if ( fStack->id( fStack->visibleWidget())==NEW_CONDUIT ) 00614 { 00615 fCurrentConfig->commit(&KPilotConfig::getConfig()); 00616 } 00617 00618 QStringList activeConduits; 00619 const QCheckListItem *p = 00620 dynamic_cast<QCheckListItem *>(fConduitList->firstChild()); 00621 KPilotConfigSettings & config = KPilotConfig::getConfig(); 00622 00623 00624 00625 while (p) 00626 { 00627 if (p->isOn()) 00628 { 00629 activeConduits.append(p->text(CONDUIT_DESKTOP)); 00630 } 00631 p = dynamic_cast<QCheckListItem *>(p->nextSibling()); 00632 } 00633 config.setConduitGroup().setInstalledConduits(activeConduits); 00634 config.sync(); 00635 } 00636 00637 00638 00639
KDE Logo
This file is part of the documentation for kpilot Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Jul 28 23:57:48 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003