00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
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 void ConduitTip::maybeTip(const QPoint &p)
00090 {
00091 FUNCTIONSETUP;
00092
00093 QListViewItem *l = fListView->itemAt(p);
00094
00095 if (!l) return;
00096
00097
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
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;
00134 QLabel *l = 0L;
00135 QVBox *v = 0L;
00136
00137
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);
00144 l->resize(30,30);
00145 v->setStretchFactor(l,100);
00146
00147
00148 fStack = new QWidgetStack(p,"RightPart");
00149
00150
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
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
00167 v = new QVBox(fStack,"OldStyle");
00168 w = new QWidget(v);
00169 v->setStretchFactor(w,50);
00170 fOldStyleLabel = new QLabel(v);
00171
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
00180 w = new QWidget(v);
00181 v->setStretchFactor(w,50);
00182 fStack->addWidget(v,OLD_CONDUIT);
00183
00184
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
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 bool ConduitConfigDialog::validate()
00224 {
00225 return fConfigWidget->release();
00226 }
00227
00228 void ConduitConfigDialog::commitChanges()
00229 {
00230 fConfigWidget->commitChanges();
00231 }
00232
00233 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
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
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
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)
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
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
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 void ConduitConfigWidget::commitChanges()
00608 {
00609 FUNCTIONSETUP;
00610
00611
00612
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