kpilot/kpilot

conduitConfigDialog.cc

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