kpilot

conduitConfigDialog.cc

Go to the documentation of this file.
00001 /* KPilot
00002 **
00003 ** Copyright (C) 2001 by Dan Pilone
00004 ** Copyright (C) 2002-2004 by Adriaan de Groot
00005 ** Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
00006 **
00007 ** This file defines a .ui-based configuration dialog for conduits.
00008 */
00009 
00010 /*
00011 ** This program is free software; you can redistribute it and/or modify
00012 ** it under the terms of the GNU General Public License as published by
00013 ** the Free Software Foundation; either version 2 of the License, or
00014 ** (at your option) any later version.
00015 **
00016 ** This program is distributed in the hope that it will be useful,
00017 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00018 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00019 ** GNU General Public License for more details.
00020 **
00021 ** You should have received a copy of the GNU General Public License
00022 ** along with this program in a file called COPYING; if not, write to
00023 ** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00024 ** MA 02110-1301, USA.
00025 */
00026 
00027 /*
00028 ** Bug reports and questions can be sent to kde-pim@kde.org
00029 */
00030 
00031 #include "options.h"
00032 
00033 #include <qlistview.h>
00034 #include <qlabel.h>
00035 #include <qtooltip.h>
00036 #include <qfile.h>
00037 #include <qpushbutton.h>
00038 #include <qhbox.h>
00039 #include <qlayout.h>
00040 #include <qwidgetstack.h>
00041 #include <qvbox.h>
00042 #include <qsplitter.h>
00043 #include <qheader.h>
00044 #include <qtimer.h>
00045 
00046 #include <kservice.h>
00047 #include <kservicetype.h>
00048 #include <kuserprofile.h>
00049 #include <kprocess.h>
00050 #include <kmessagebox.h>
00051 #include <kglobal.h>
00052 #include <kstandarddirs.h>
00053 #include <klibloader.h>
00054 #include <kseparator.h>
00055 #include <kconfigskeleton.h>
00056 #include <kdialogbase.h>
00057 
00058 #include "plugin.h"
00059 #include "kpilotConfig.h"
00060 #include "kpilotConfigDialog.h"
00061 
00062 #include "kpilotConfigWizard.h"
00063 
00064 #include "conduitConfigDialog.moc"
00065 
00066 #define CONDUIT_NAME    (0)
00067 #define CONDUIT_COMMENT (1)
00068 #define CONDUIT_DESKTOP (2)
00069 #define CONDUIT_LIBRARY (3)
00070 #define CONDUIT_ORDER   (4)
00071 
00072 
00073 extern "C"
00074 {
00075     KDE_EXPORT KCModule *create_kpilotconfig( QWidget *parent, const char * )
00076     {
00077         FUNCTIONSETUP;
00078         return new ConduitConfigWidget( parent, "kcmkpilotconfig" );
00079     }
00080 
00081     KDE_EXPORT ConfigWizard *create_wizard(QWidget *parent, int m)
00082     {
00083         FUNCTIONSETUP;
00084         return new ConfigWizard(parent,"Wizard", m);
00085     }
00086 }
00087 
00088 
00089 class ConduitTip : public QToolTip
00090 {
00091 public:
00092     ConduitTip(QListView *parent);
00093     virtual ~ConduitTip();
00094 
00095 protected:
00096     virtual void maybeTip(const QPoint &);
00097 
00098     QListView *fListView;
00099 } ;
00100 
00101 
00102 ConduitTip::ConduitTip(QListView *p) :
00103     QToolTip(p->viewport(),0L),
00104     fListView(p)
00105 {
00106     FUNCTIONSETUP;
00107 }
00108 
00109 ConduitTip::~ConduitTip()
00110 {
00111     FUNCTIONSETUP;
00112 }
00113 
00114 /* virtual */ void ConduitTip::maybeTip(const QPoint &p)
00115 {
00116     FUNCTIONSETUP;
00117 
00118     QListViewItem *l = fListView->itemAt(p);
00119 
00120     if (!l) return;
00121 
00122     // ConduitListItem *q = static_cast<ConduitListItem *>(l);
00123 
00124 #ifdef DEBUG
00125     DEBUGKPILOT << fname
00126         << ": Tip over "
00127         << l->text(CONDUIT_NAME)
00128         << " with text "
00129         << l->text(CONDUIT_COMMENT)
00130         << endl;
00131 #endif
00132 
00133     QString s = l->text(CONDUIT_COMMENT);
00134 
00135     if (s.isEmpty()) return;
00136     if (s.find(CSL1("<qt>"),0,false) == -1)
00137     {
00138         s.prepend(CSL1("<qt>"));
00139         s.append(CSL1("</qt>"));
00140     }
00141 
00142     tip(fListView->itemRect(l),s);
00143 }
00144 
00145 // implement our own check list items so we can detect if a given item was checked/unchecked. We need
00146 // this to prevent the modified signal if one only wants to display a conduit's config widget. Currently,
00147 // KListView doesn't provide any signal that indicates that the checked state of a checklist item was changed.
00148 class KPilotCheckListItem : public QCheckListItem
00149 {
00150 public:
00151     KPilotCheckListItem ( QListViewItem * parent, const QString & text, Type tt = RadioButtonController ) : QCheckListItem(parent, text, tt),mOriginalState(false) {}
00152     ~KPilotCheckListItem() {}
00153 
00154     void setOriginalState(bool state) { mOriginalState=state; setOn(state);}
00155     bool isOriginalState() { return isOn() == mOriginalState; }
00156 
00157 protected:
00158     bool mOriginalState;
00159 };
00160 
00161 
00162 // Page numbers in the widget stack
00163 #define OLD_CONDUIT      (1)
00164 #define BROKEN_CONDUIT   (2)
00165 #define INTERNAL_CONDUIT (3)
00166 #define INTERNAL_EXPLN   (4)
00167 #define CONDUIT_EXPLN    (5)
00168 #define GENERAL_EXPLN    (6)
00169 #define GENERAL_ABOUT    (7)
00170 #define NEW_CONDUIT      (8)
00171 
00172 
00173 /*
00174 ** Create a page in the widget stack @p parent on page @p pageno,
00175 ** bearing the given @p text. The remainder of the parameters are
00176 ** for esoteric things like:
00177 **  @p buttons set to non-null to include (and return) a QHBox suitable
00178 **     for displaying a row of buttons in on the page.
00179 **  @p label set to non-null to return the QLabel used to display @p text.
00180 */
00181 static void addDescriptionPage(QWidgetStack *parent,
00182     int pageno,
00183     const QString &text,
00184     QHBox **buttons = 0L,
00185     QLabel **label = 0L)
00186 {
00187     QVBox *v = new QVBox(parent);
00188     QLabel *l = 0L;
00189 
00190     v->setFrameShape(QLabel::NoFrame);
00191     v->setMargin(SPACING);
00192 
00193     l = new QLabel(v);
00194     l->setText(text);
00195     l->setAlignment(Qt::AlignLeft | Qt::AlignVCenter | Qt::ExpandTabs | Qt::WordBreak);
00196 
00197     if (label) { *label = l; }
00198 
00199     if (buttons)
00200     {
00201         *buttons = new QHBox(v);
00202         l = new QLabel(v);
00203     }
00204 
00205     parent->addWidget(v,pageno);
00206 }
00207 
00208 
00209 ConduitConfigWidgetBase::ConduitConfigWidgetBase(QWidget *parent, const char *n) :
00210     KCModule(parent, n),
00211     fConduitList(0L),
00212     fStack(0L),
00213     fConfigureButton(0L),
00214     fConfigureWizard(0L),
00215     fConfigureKontact(0L),
00216     fActionDescription(0L)
00217 {
00218     FUNCTIONSETUP;
00219 
00220     QWidget *w = 0L; // For spacing purposes only.
00221     QHBox *btns = 0L;
00222 
00223     QHBoxLayout *mainLayout = new QHBoxLayout(this);
00224     mainLayout->setSpacing(10);
00225 
00226     // Create the left hand column
00227     fConduitList = new QListView(this ,"ConduitList");
00228     fConduitList->addColumn(QString::null);
00229     fConduitList->header()->hide();
00230     fConduitList->setSizePolicy(
00231         QSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred));
00232     mainLayout->addWidget(fConduitList);
00233 
00234     // Create the title
00235     QVBoxLayout *vbox = new QVBoxLayout(this, 0, KDialog::spacingHint());
00236     // String below is just to make space; no need to translate.
00237     fTitleText = new QLabel(CSL1("Conduit Setup - Addressbook"), this);
00238     QFont titleFont(fTitleText->font());
00239     titleFont.setBold(true);
00240     fTitleText->setFont(titleFont);
00241     vbox->addWidget(fTitleText, 0, AlignLeft);
00242     vbox->addWidget(new KSeparator(QFrame::HLine|QFrame::Plain, this));
00243 
00244     // Right hand column
00245     fStack = new QWidgetStack(this, "RightPart");
00246     vbox->addWidget(fStack, 10);
00247 
00248     mainLayout->addLayout(vbox);
00249 
00250     // First page in stack (right hand column)
00251     addDescriptionPage(fStack,BROKEN_CONDUIT,
00252         i18n("<qt>This conduit appears to be broken and cannot "
00253         "be configured.</qt>"));
00254 
00255     // Second page, now with layout in a single column
00256     //
00257     // Probably deprecated.
00258     //
00259     addDescriptionPage(fStack,OLD_CONDUIT,
00260         i18n("<qt>This is an old-style conduit.</qt>"),&btns);
00261     w = new QWidget(btns);
00262     btns->setStretchFactor(w,50);
00263     fConfigureButton = new QPushButton(btns);
00264     fConfigureButton->setText(i18n("Configure..."));
00265     w = new QWidget(btns);
00266     btns->setStretchFactor(w,50);
00267 
00268     // Page 3
00269     addDescriptionPage(fStack,INTERNAL_CONDUIT,
00270         QString::null,0L,&fActionDescription);
00271 
00272     // Page 5 - explanation about conduits
00273     addDescriptionPage(fStack,CONDUIT_EXPLN,
00274         i18n("<qt><i>Conduits</i> are external (possibly third-party) "
00275         "programs that perform synchronization actions. They may "
00276         "have individual configurations. Select a conduit to configure it, "
00277         "and enable it by clicking on its checkbox. "
00278         "</qt>"));
00279 
00280     // Page 6 - explanation about general setup
00281     addDescriptionPage(fStack,GENERAL_EXPLN,
00282         i18n("<qt><p>The <i>general</i> portion of KPilot's setup "
00283         "contains settings for your hardware and the way KPilot "
00284         "should display your data. For the basic setup, which should fulfill "
00285         "the need of most users, just use the setup wizard below.</p>"
00286         "If you need some special settings, this dialog provides all the options "
00287         "for fine-tuning KPilot. But be warned: The HotSync settings are "
00288         "various esoteric things.</p>"
00289         "<p>You can enable an action or conduit by clicking on its checkbox. "
00290         "Checked conduits will be run during a HotSync. "
00291         "Select a conduit to configure it.</p>"
00292         "</qt>"),&btns);
00293     w = new QWidget(btns);
00294     btns->setStretchFactor(w,50);
00295     fConfigureWizard = new QPushButton(i18n("Configuration Wizard"),btns);
00296     w = new QWidget(btns);
00297     btns->setStretchFactor(w,50);
00298 
00299 
00300     fStack->addWidget(ConduitConfigBase::aboutPage(fStack,0L),GENERAL_ABOUT);
00301 }
00302 
00303 ConduitConfigWidget::ConduitConfigWidget(QWidget *parent, const char *n,
00304     bool) :
00305     ConduitConfigWidgetBase(parent,n),
00306     fConfigure(0L),
00307     fCurrentConduit(0L),
00308     fGeneralPage(0L),
00309     fCurrentConfig(0L)
00310 {
00311     FUNCTIONSETUP;
00312 
00313     fConduitList->setSorting(-1);
00314     fConduitList->setRootIsDecorated(true);
00315     fConduitList->setTreeStepSize(10);
00316     // fConduitList->removeColumn(CONDUIT_COMMENT);
00317     fillLists();
00318 
00319     fConduitList->resize(fConduitList->sizeHint());
00320     fConduitList->setMinimumSize(fConduitList->sizeHint());
00321     fConduitList->setColumnWidth(0, fConduitList->sizeHint().width());
00322     fConduitList->setResizeMode(QListView::AllColumns);
00323 
00324     fStack->resize(fStack->sizeHint()+QSize(10,40));
00325     fStack->setMinimumSize(fStack->sizeHint()+QSize(10,40));
00326 
00327     QObject::connect(fConduitList,
00328         SIGNAL(selectionChanged(QListViewItem *)),
00329         this,SLOT(selected(QListViewItem *)));
00330     QObject::connect(fConduitList,
00331         SIGNAL(clicked(QListViewItem*)),
00332         this, SLOT(conduitsChanged(QListViewItem*)));
00333 
00334     // Deprecated?
00335     QObject::connect(fConfigureButton,
00336         SIGNAL(clicked()),
00337         this,SLOT(configure()));
00338 
00339     QObject::connect(fConfigureWizard,SIGNAL(clicked()),
00340         this,SLOT(configureWizard()));
00341 
00342     fGeneralPage->setSelected(true);
00343     fConduitList->setCurrentItem(fGeneralPage);
00344     selected(fGeneralPage);
00345 
00346     (void) new ConduitTip(fConduitList);
00347     setButtons(Apply);
00348 
00349 }
00350 
00351 ConduitConfigWidget::~ConduitConfigWidget()
00352 {
00353     FUNCTIONSETUP;
00354     release();
00355 }
00356 
00357 void ConduitConfigWidget::fillLists()
00358 {
00359     FUNCTIONSETUP;
00360 
00361     // 3 QListViewItems for the three headings in the list
00362     QListViewItem *general,*conduits;
00363 
00364     // And two generic pointers for the rest.
00365     QListViewItem *q = 0L;
00366     KPilotCheckListItem *p = 0L;
00367 
00368     q = new QListViewItem(fConduitList, i18n("About"));
00369     q->setText(CONDUIT_COMMENT, i18n("About KPilot. Credits."));
00370     q->setText(CONDUIT_LIBRARY, CSL1("general_about"));
00371 
00372     conduits = new QListViewItem(fConduitList, i18n("Conduits"));
00373 
00374     general = new QListViewItem( fConduitList, i18n("General Setup" ) );
00375     fGeneralPage = general;
00376 
00377     // Give them identifiers so they can be handled specially when selected.
00378     conduits->setText(CONDUIT_LIBRARY,CSL1("expln_conduits"));
00379     general->setText( CONDUIT_LIBRARY, CSL1("expln_general") );
00380 
00381     general->setText( CONDUIT_COMMENT,
00382         i18n("General setup of KPilot (User name, port, general sync settings)") );
00383     conduits->setText( CONDUIT_COMMENT,
00384         i18n("Actions for HotSync with individual configuration."));
00385 
00386     conduits->setOpen(true);
00387     general->setOpen(true);
00388 
00389 
00390     // Create entries under general.
00391 #define CE(a,b,c) q = new QListViewItem(general,a) ; \
00392     q->setText(CONDUIT_COMMENT,b) ; \
00393     q->setText(CONDUIT_LIBRARY,c) ;
00394 
00395     CE(i18n("Startup and Exit"), i18n("Behavior at startup and exit."), CSL1("general_startexit") );
00396     CE(i18n("Viewers"), i18n("Viewer settings."), CSL1("general_view") );
00397     CE(i18n("Backup"),i18n("Special settings for backup."),CSL1("general_backup"));
00398     CE(i18n("HotSync"),i18n("Special behavior during HotSync."),CSL1("general_sync"));
00399     CE(i18n("Device"),i18n("Hardware settings and startup and exit options."),CSL1("general_setup"));
00400 
00401 #undef CE
00402 
00403 
00404     // List of installed (enabled) actions and conduits.
00405     QStringList potentiallyInstalled = KPilotSettings::installedConduits();
00406 
00407     //  Create internal conduits.
00408     //
00409     //
00410 
00411 #define IC(a,b,c) p = new KPilotCheckListItem(conduits,i18n(a),QCheckListItem::CheckBox); \
00412     p->setText(CONDUIT_COMMENT,i18n(c)); \
00413     p->setText(CONDUIT_LIBRARY,CSL1("internal_" b)); \
00414     p->setText(CONDUIT_DESKTOP,CSL1("internal_" b)); \
00415     if (potentiallyInstalled.findIndex(p->text(CONDUIT_DESKTOP))>=0) \
00416         p->setOriginalState(true);
00417 
00418     IC("Install Files","fileinstall",
00419         "Install files that are dragged to KPilot onto the handheld.");
00420 #undef IC
00421 
00422 
00423 
00424     KServiceTypeProfile::OfferList offers =
00425         KServiceTypeProfile::offers(CSL1("KPilotConduit"));
00426 
00427     QValueListIterator < KServiceOffer > availList(offers.begin());
00428     while (availList != offers.end())
00429     {
00430         KSharedPtr < KService > o = (*availList).service();
00431 
00432 #ifdef DEBUG
00433         DEBUGKPILOT << fname << ": "
00434             << o->desktopEntryName()
00435             << " = " << o->name() << endl;
00436 #endif
00437 
00438         if (!o->exec().isEmpty())
00439         {
00440             WARNINGKPILOT << "Old-style conduit found "
00441                 << o->name()
00442                 << endl;
00443         }
00444 
00445         p = new KPilotCheckListItem(conduits,
00446             o->name(),
00447             QCheckListItem::CheckBox);
00448         p->setMultiLinesEnabled(true);
00449         p->setText(CONDUIT_COMMENT,o->comment());
00450         p->setText(CONDUIT_DESKTOP,o->desktopEntryName());
00451         p->setText(CONDUIT_LIBRARY,o->library());
00452 
00453         if (potentiallyInstalled.findIndex(o->desktopEntryName()) < 0)
00454         {
00455             p->setOriginalState(false);
00456         }
00457         else
00458         {
00459             p->setOriginalState(true);
00460         }
00461 
00462         ++availList;
00463     }
00464 }
00465 
00466 static void dumpConduitInfo(const KLibrary *lib)
00467 {
00468 #ifdef DEBUG
00469     FUNCTIONSETUP;
00470     DEBUGKPILOT << "Plugin version = " << PluginUtility::pluginVersion(lib) << endl;
00471     DEBUGKPILOT << "Plugin id      = " << PluginUtility::pluginVersionString(lib) << endl;
00472 #endif
00473 }
00474 
00475 static ConduitConfigBase *handleGeneralPages(QWidget *w, QListViewItem *p)
00476 {
00477     ConduitConfigBase *o = 0L;
00478 
00479     QString s = p->text(CONDUIT_LIBRARY) ;
00480 
00481     if (s.startsWith(CSL1("general_setup")))
00482     {
00483         o = new DeviceConfigPage( w, "generalSetup" );
00484     }
00485     else if (s.startsWith(CSL1("general_sync")))
00486     {
00487         o = new SyncConfigPage( w, "syncSetup" );
00488     }
00489     else if (s.startsWith(CSL1("general_view")))
00490     {
00491         o = new ViewersConfigPage( w, "viewSetup" );
00492     }
00493     else if (s.startsWith(CSL1("general_startexit")))
00494     {
00495         o = new StartExitConfigPage(w,"startSetup");
00496     }
00497     else if (s.startsWith(CSL1("general_backup")))
00498     {
00499         o = new BackupConfigPage(w,"backupSetup");
00500     }
00501 
00502     return o;
00503 }
00504 
00505 void ConduitConfigWidget::loadAndConfigure(QListViewItem *p) // ,bool exec)
00506 {
00507     FUNCTIONSETUP;
00508 
00509     if (!p)
00510     {
00511 #ifdef DEBUG
00512         DEBUGKPILOT << fname
00513             << ": Executed NULL conduit?"
00514             << endl;
00515 #endif
00516         fStack->raiseWidget(GENERAL_EXPLN);
00517         return;
00518     }
00519 
00520     QString libraryName = p->text(CONDUIT_LIBRARY);
00521 
00522 #ifdef DEBUG
00523     DEBUGKPILOT << fname
00524         << ": Executing conduit "
00525         << p->text(CONDUIT_NAME)
00526         << " (library " << libraryName << ")"
00527         << endl;
00528 #endif
00529 
00530 
00531     if (libraryName.isEmpty())
00532     {
00533         fStack->raiseWidget(BROKEN_CONDUIT);
00534         warnNoExec(p);
00535         return;
00536     }
00537 
00538     if (libraryName.startsWith(CSL1("internal_")))
00539     {
00540         fStack->raiseWidget(INTERNAL_CONDUIT);
00541         fActionDescription->setText(
00542             i18n("<qt>This is an internal action which has no "
00543             "configuration options. "
00544             "The action's description is: <i>%1</i> "
00545             "</qt>").arg(p->text(CONDUIT_COMMENT)));
00546         return;
00547     }
00548 
00549     if (libraryName == CSL1("expln_conduits"))
00550     {
00551         fStack->raiseWidget(CONDUIT_EXPLN);
00552         return;
00553     }
00554     if (libraryName == CSL1("expln_general"))
00555     {
00556         fStack->raiseWidget(GENERAL_EXPLN);
00557         return;
00558     }
00559 
00560     if (libraryName == CSL1("general_about"))
00561     {
00562         fStack->raiseWidget(GENERAL_ABOUT);
00563         return;
00564     }
00565 
00566     QObject *o = 0L;
00567 
00568     // Page 4: General setup
00569     if (libraryName.startsWith(CSL1("general_")))
00570     {
00571         o = handleGeneralPages(fStack,p);
00572     }
00573     else
00574     {
00575         QCString library = QFile::encodeName(libraryName);
00576 
00577         KLibFactory *f = KLibLoader::self()->factory(library);
00578         if (!f)
00579         {
00580 #ifdef DEBUG
00581             DEBUGKPILOT << fname
00582                 << ": No conduit library "
00583                 << library.data()
00584                 << " [" << library.size() << "]"
00585                 << " (" << libraryName << ")"
00586                 << " found."
00587                 << endl;
00588 #endif
00589             fStack->raiseWidget(BROKEN_CONDUIT);
00590             warnNoLibrary(p);
00591             return;
00592         }
00593 
00594         dumpConduitInfo(KLibLoader::self()->library(library));
00595 
00596         QStringList a;
00597         a.append(CSL1("modal"));
00598 
00599         o = f->create(fStack, 0L, "ConduitConfigBase", a);
00600 
00601         if (!o)
00602         {
00603 #ifdef DEBUG
00604             DEBUGKPILOT << fname
00605                 << ": Can't create ConduitConfigBase - must be old conduit."
00606                 << endl;
00607 #endif
00608 
00609             KLibLoader::self()->unloadLibrary(
00610                 library);
00611             fStack->raiseWidget(BROKEN_CONDUIT);
00612             warnNoLibrary(p);
00613             return;
00614         }
00615     }
00616 
00617     ConduitConfigBase *d = dynamic_cast<ConduitConfigBase *>(o);
00618 
00619     if (!d)
00620     {
00621 #ifdef DEBUG
00622         DEBUGKPILOT << fname
00623             << ": Can't cast to config base object."
00624             << endl;
00625 #endif
00626         fStack->raiseWidget(BROKEN_CONDUIT);
00627         warnNoLibrary(p);
00628         return;
00629     }
00630 
00631     // Remove the config widget from the stack before we can add the new one
00632     QWidget *oldConfigWidget = fStack->widget( NEW_CONDUIT );
00633     if ( oldConfigWidget )
00634     {
00635         fStack->removeWidget( oldConfigWidget );
00636         KPILOT_DELETE( oldConfigWidget );
00637     }
00638     if (fStack->addWidget(d->widget(),NEW_CONDUIT)<0)
00639     {
00640 #ifdef DEBUG
00641         DEBUGKPILOT << fname
00642             << ": Can't add config widget to stack."
00643             << endl;
00644 #endif
00645     }
00646     else
00647     {
00648         d->load();
00649         fStack->raiseWidget(NEW_CONDUIT);
00650         d->widget()->show();
00651         fCurrentConfig=d;
00652         // make sure the changed signal is propagated to the KCM*Dialog
00653         // and the apply button is enabled correspondingly.
00654         connect(d, SIGNAL(changed(bool)), this, SIGNAL(changed(bool)));
00655     }
00656 }
00657 
00658 bool ConduitConfigWidget::release()
00659 {
00660     FUNCTIONSETUP;
00661     if (fCurrentConfig)
00662     {
00663         if (!fCurrentConfig->maybeSave())
00664             return false;
00665         fStack->raiseWidget(0);
00666         delete fCurrentConfig;
00667     }
00668     if (fCurrentConduit)
00669     {
00670         KLibLoader::self()->unloadLibrary(
00671             QFile::encodeName(fCurrentConduit->text(CONDUIT_LIBRARY)));
00672     }
00673     fCurrentConduit=0L;
00674     fCurrentConfig=0L;
00675     return true;
00676 }
00677 
00678 void ConduitConfigWidget::unselect()
00679 {
00680     fConduitList->setSelected( fCurrentConduit, true );
00681     fConduitList->setCurrentItem( fCurrentConduit );
00682 }
00683 
00684 void ConduitConfigWidget::selected(QListViewItem *p)
00685 {
00686     FUNCTIONSETUP;
00687 #ifdef DEBUG
00688     DEBUGKPILOT << fname << ": "
00689         << ( p ? p->text(CONDUIT_NAME) : CSL1("None") )
00690         << endl;
00691 #endif
00692     if (p!=fCurrentConduit)
00693     {
00694         if (!release())
00695         {
00696             fConduitList->blockSignals(true);
00697             QTimer::singleShot(1,this,SLOT(unselect()));
00698             return;
00699         }
00700     }
00701     fCurrentConduit=p;
00702     loadAndConfigure(p);
00703 //  fStack->adjustSize();
00704 #ifdef DEBUG
00705     DEBUGKPILOT << fname << ": New widget size "
00706         << fStack->size().width() << "x" << fStack->size().height() << endl;
00707     DEBUGKPILOT << fname << ": Current size "
00708         << size().width() << "x"
00709         << size().height() << endl;
00710 #endif
00711     emit sizeChanged();
00712 #ifdef DEBUG
00713     DEBUGKPILOT << fname << ": New size "
00714         << size().width() << "x"
00715         << size().height() << endl;
00716 #endif
00717 
00718     // set the dialog title to the selected item
00719     QListViewItem *pParent = p->parent();
00720     QString title;
00721     title = pParent ? pParent->text(CONDUIT_NAME) + CSL1(" - ") : QString() ;
00722     title += p ? p->text(CONDUIT_NAME) : i18n("KPilot Setup");
00723     fTitleText->setText(title);
00724 }
00725 
00726 void ConduitConfigWidget::configure()
00727 {
00728     loadAndConfigure(fConduitList->selectedItem());
00729 }
00730 
00731 void ConduitConfigWidget::warnNoExec(const QListViewItem * p)
00732 {
00733     FUNCTIONSETUP;
00734 
00735     QString msg = i18n("<qt>No library could be "
00736         "found for the conduit %1. This means that the "
00737         "conduit was not installed properly.</qt>")
00738         .arg(p->text(CONDUIT_NAME));
00739 
00740 #ifdef DEBUG
00741     DEBUGKPILOT << fname << ": No library for "
00742         << p->text(CONDUIT_NAME) << endl;
00743 #endif
00744 
00745     KMessageBox::error(this, msg, i18n("Conduit Error"));
00746 }
00747 
00748 void ConduitConfigWidget::warnNoLibrary(const QListViewItem *p)
00749 {
00750     FUNCTIONSETUP;
00751 
00752     QString msg = i18n("<qt>There was a problem loading the library "
00753         "for the conduit %1. This means that the "
00754         "conduit was not installed properly.</qt>")
00755         .arg(p->text(CONDUIT_NAME));
00756 
00757 #ifdef DEBUG
00758     DEBUGKPILOT << fname << ": Can't load library for "
00759         << p->text(CONDUIT_NAME) << endl;
00760 #endif
00761 
00762     KMessageBox::error(this, msg, i18n("Conduit Error"));
00763 }
00764 
00765 void ConduitConfigWidget::save()
00766 {
00767     FUNCTIONSETUP;
00768 
00769     // Only new-style conduits and the general setup have changes that need to be commited
00770     // old-style conduits have their own config dlg which commits them itself
00771     if ( fStack->id( fStack->visibleWidget())==NEW_CONDUIT )
00772     {
00773         if (fCurrentConfig) fCurrentConfig->commit();
00774     }
00775 
00776     QStringList activeConduits;
00777     QListViewItemIterator it( fConduitList );
00778     while ( it.current() ) {
00779         KPilotCheckListItem*p = dynamic_cast<KPilotCheckListItem*>(it.current());
00780         if ( p )
00781         {
00782             p->setOriginalState( p->isOn() );
00783             if ( p->isOn() )
00784             activeConduits.append(p->text(CONDUIT_DESKTOP));
00785         }
00786         ++it;
00787     }
00788     KPilotSettings::setInstalledConduits(activeConduits);
00789     KPilotSettings::self()->writeConfig();
00790 }
00791 
00792 
00793 void ConduitConfigWidget::load()
00794 {
00795     FUNCTIONSETUP;
00796     KPilotSettings::self()->readConfig();
00797 
00798     QStringList potentiallyInstalled = KPilotSettings::installedConduits();
00799     QListViewItem*p = fConduitList->firstChild();
00800     while (p)
00801     {
00802         QListViewItem*q = p->firstChild();
00803         while (q)
00804         {
00805             QCheckListItem*qq=dynamic_cast<QCheckListItem*>(q);
00806             if (qq)
00807             {
00808                 qq->setOn(! (potentiallyInstalled.findIndex(qq->text(CONDUIT_DESKTOP))<0) );
00809             }
00810             q = q->nextSibling();
00811         }
00812         p=p->nextSibling();
00813     }
00814 
00815 
00816     // Only new-style conduits and the general setup have changes that need to be commited
00817     // old-style conduits have their own config dlg which commits them itself
00818     if ( fStack->id( fStack->visibleWidget())==NEW_CONDUIT )
00819     {
00820         if (fCurrentConfig) fCurrentConfig->load();
00821     }
00822 }
00823 
00824 
00825 void ConduitConfigWidget::conduitsChanged(QListViewItem*item)
00826 {
00827     KPilotCheckListItem*i=dynamic_cast<KPilotCheckListItem*>(item);
00828     if (i)
00829     {
00830         if (!i->isOriginalState()) emit changed(true);
00831     }
00832 }
00833 
00834 void ConduitConfigWidget::reopenItem(QListViewItem *i)
00835 {
00836     i->setOpen(true);
00837 }
00838 
00839 void ConduitConfigWidget::configureWizard()
00840 {
00841     FUNCTIONSETUP;
00842     ConfigWizard wiz(this, "Wizard");
00843     if (wiz.exec()) {
00844         KPilotSettings::self()->readConfig();
00845         load();
00846     }
00847 }
00848 
00849