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