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 static const char *conduitconfigdialog_id =
00032     "$Id: conduitConfigDialog.cc 437980 2005-07-23 19:53:57Z kainhofe $";
00033 
00034 #include "options.h"
00035 
00036 #include <qlistview.h>
00037 #include <qlabel.h>
00038 #include <qtooltip.h>
00039 #include <qfile.h>
00040 #include <qpushbutton.h>
00041 #include <qhbox.h>
00042 #include <qlayout.h>
00043 #include <qwidgetstack.h>
00044 #include <qvbox.h>
00045 #include <qsplitter.h>
00046 #include <qheader.h>
00047 #include <qtimer.h>
00048 
00049 #include <kservice.h>
00050 #include <kservicetype.h>
00051 #include <kuserprofile.h>
00052 #include <kprocess.h>
00053 #include <kmessagebox.h>
00054 #include <kglobal.h>
00055 #include <kstandarddirs.h>
00056 #include <klibloader.h>
00057 #include <kseparator.h>
00058 #include <kconfigskeleton.h>
00059 #include <kdialogbase.h>
00060 
00061 #include "uiDialog.h"
00062 #include "plugin.h"
00063 #include "kpilotConfig.h"
00064 #include "kpilotConfigDialog.h"
00065 
00066 #include "kpilotConfigWizard.h"
00067 
00068 #include "conduitConfigDialog.moc"
00069 
00070 #define CONDUIT_NAME    (0)
00071 #define CONDUIT_COMMENT (1)
00072 #define CONDUIT_DESKTOP (2)
00073 #define CONDUIT_LIBRARY (3)
00074 #define CONDUIT_ORDER   (4)
00075 
00076 
00077 extern "C"
00078 {
00079     KDE_EXPORT KCModule *create_kpilotconfig( QWidget *parent, const char * )
00080     {
00081         return new ConduitConfigWidget( parent, "kcmkpilotconfig" );
00082     }
00083 
00084     KDE_EXPORT ConfigWizard *create_wizard(QWidget *parent, int m)
00085     {
00086         return new ConfigWizard(parent,"Wizard", m);
00087     }
00088 }
00089 
00090 
00091 class ConduitTip : public QToolTip
00092 {
00093 public:
00094     ConduitTip(QListView *parent);
00095     virtual ~ConduitTip();
00096 
00097 protected:
00098     virtual void maybeTip(const QPoint &);
00099 
00100     QListView *fListView;
00101 } ;
00102 
00103 
00104 ConduitTip::ConduitTip(QListView *p) :
00105     QToolTip(p->viewport(),0L),
00106     fListView(p)
00107 {
00108     FUNCTIONSETUP;
00109 }
00110 
00111 ConduitTip::~ConduitTip()
00112 {
00113     FUNCTIONSETUP;
00114 }
00115 
00116 /* virtual */ void ConduitTip::maybeTip(const QPoint &p)
00117 {
00118     FUNCTIONSETUP;
00119 
00120     QListViewItem *l = fListView->itemAt(p);
00121 
00122     if (!l) return;
00123 
00124     // ConduitListItem *q = static_cast<ConduitListItem *>(l);
00125 
00126 #ifdef DEBUG
00127     DEBUGKPILOT << fname
00128         << ": Tip over "
00129         << l->text(CONDUIT_NAME)
00130         << " with text "
00131         << l->text(CONDUIT_COMMENT)
00132         << endl;
00133 #endif
00134 
00135     QString s = l->text(CONDUIT_COMMENT);
00136 
00137     if (s.isEmpty()) return;
00138     if (s.find(CSL1("<qt>"),0,false) == -1)
00139     {
00140         s.prepend(CSL1("<qt>"));
00141         s.append(CSL1("</qt>"));
00142     }
00143 
00144     tip(fListView->itemRect(l),s);
00145 }
00146 
00147 // implement our own check list items so we can detect if a given item was checked/unchecked. We need
00148 // this to prevent the modified signal if one only wants to display a conduit's config widget. Currently,
00149 // KListView doesn't provide any signal that indicates that the checked state of a checklist item was changed.
00150 class KPilotCheckListItem : public QCheckListItem
00151 {
00152 public:
00153     KPilotCheckListItem ( QListViewItem * parent, const QString & text, Type tt = RadioButtonController ) : QCheckListItem(parent, text, tt),mOriginalState(false) {}
00154     ~KPilotCheckListItem() {}
00155 
00156     void setOriginalState(bool state) { mOriginalState=state; setOn(state);}
00157     bool isOriginalState() { return isOn() == mOriginalState; }
00158 
00159 protected:
00160     bool mOriginalState;
00161 };
00162 
00163 
00164 // Page numbers in the widget stack
00165 #define OLD_CONDUIT      (1)
00166 #define BROKEN_CONDUIT   (2)
00167 #define INTERNAL_CONDUIT (3)
00168 #define INTERNAL_EXPLN   (4)
00169 #define CONDUIT_EXPLN    (5)
00170 #define GENERAL_EXPLN    (6)
00171 #define GENERAL_ABOUT    (7)
00172 #define NEW_CONDUIT      (8)
00173 
00174 
00175 /*
00176 ** Create a page in the widget stack @p parent on page @p pageno,
00177 ** bearing the given @p text. The remainder of the parameters are
00178 ** for esoteric things like:
00179 **  @p buttons set to non-null to include (and return) a QHBox suitable
00180 **     for displaying a row of buttons in on the page.
00181 **  @p label set to non-null to return the QLabel used to display @p text.
00182 */
00183 static void addDescriptionPage(QWidgetStack *parent,
00184     int pageno,
00185     const QString &text,
00186     QHBox **buttons = 0L,
00187     QLabel **label = 0L)
00188 {
00189     QVBox *v = new QVBox(parent);
00190     QLabel *l = 0L;
00191 
00192     v->setFrameShape(QLabel::NoFrame);
00193     v->setMargin(SPACING);
00194 
00195     l = new QLabel(v);
00196     l->setText(text);
00197     l->setAlignment(Qt::AlignLeft | Qt::AlignVCenter | Qt::ExpandTabs | Qt::WordBreak);
00198 
00199     if (label) { *label = l; }
00200 
00201     if (buttons)
00202     {
00203         *buttons = new QHBox(v);
00204         l = new QLabel(v);
00205     }
00206 
00207     parent->addWidget(v,pageno);
00208 }
00209 
00210 
00211 ConduitConfigWidgetBase::ConduitConfigWidgetBase(QWidget *parent, const char *n) :
00212     KCModule(parent, n),
00213     fConduitList(0L),
00214     fStack(0L),
00215     fConfigureButton(0L),
00216     fConfigureWizard(0L),
00217     fConfigureKontact(0L),
00218     fActionDescription(0L)
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(UIDialog::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     (void) conduitconfigdialog_id;
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 #ifdef DEBUG
00523     DEBUGKPILOT << fname
00524         << ": Executing conduit "
00525         << p->text(CONDUIT_NAME)
00526         << endl;
00527 #endif
00528 
00529     if (p->text(CONDUIT_LIBRARY).isEmpty())
00530     {
00531         fStack->raiseWidget(BROKEN_CONDUIT);
00532         warnNoExec(p);
00533         return;
00534     }
00535 
00536     if (p->text(CONDUIT_LIBRARY).startsWith(CSL1("internal_")))
00537     {
00538         fStack->raiseWidget(INTERNAL_CONDUIT);
00539         fActionDescription->setText(
00540             i18n("<qt>This is an internal action which has no "
00541             "configuration options. "
00542             "The action's description is: <i>%1</i> "
00543             "</qt>").arg(p->text(CONDUIT_COMMENT)));
00544         return;
00545     }
00546 
00547     if (p->text(CONDUIT_LIBRARY) == CSL1("expln_conduits"))
00548     {
00549         fStack->raiseWidget(CONDUIT_EXPLN);
00550         return;
00551     }
00552     if (p->text(CONDUIT_LIBRARY) == CSL1("expln_general"))
00553     {
00554         fStack->raiseWidget(GENERAL_EXPLN);
00555         return;
00556     }
00557 
00558     if (p->text(CONDUIT_LIBRARY) == CSL1("general_about"))
00559     {
00560         fStack->raiseWidget(GENERAL_ABOUT);
00561         return;
00562     }
00563 
00564     QObject *o = 0L;
00565 
00566     // Page 4: General setup
00567     if (p->text(CONDUIT_LIBRARY).startsWith(CSL1("general_")))
00568     {
00569         o = handleGeneralPages(fStack,p);
00570     }
00571     else
00572     {
00573         QCString library = QFile::encodeName(p->text(CONDUIT_LIBRARY));
00574 
00575         KLibFactory *f = KLibLoader::self()->factory(library);
00576         if (!f)
00577         {
00578 #ifdef DEBUG
00579             DEBUGKPILOT << fname
00580                 << ": No conduit library "
00581                 << library
00582                 << " found."
00583                 << endl;
00584 #endif
00585             fStack->raiseWidget(BROKEN_CONDUIT);
00586             warnNoLibrary(p);
00587             return;
00588         }
00589 
00590         dumpConduitInfo(KLibLoader::self()->library(library));
00591 
00592         QStringList a;
00593         a.append(CSL1("modal"));
00594 
00595         o = f->create(fStack, 0L, "ConduitConfigBase", a);
00596 
00597         if (!o)
00598         {
00599 #ifdef DEBUG
00600             DEBUGKPILOT << fname
00601                 << ": Can't create ConduitConfigBase - must be old conduit."
00602                 << endl;
00603 #endif
00604 
00605             KLibLoader::self()->unloadLibrary(
00606                 library);
00607             fStack->raiseWidget(BROKEN_CONDUIT);
00608             warnNoLibrary(p);
00609             return;
00610         }
00611     }
00612 
00613     ConduitConfigBase *d = dynamic_cast<ConduitConfigBase *>(o);
00614 
00615     if (!d)
00616     {
00617 #ifdef DEBUG
00618         DEBUGKPILOT << fname
00619             << ": Can't cast to config base object."
00620             << endl;
00621 #endif
00622         fStack->raiseWidget(BROKEN_CONDUIT);
00623         warnNoLibrary(p);
00624         return;
00625     }
00626 
00627     // Remove the config widget from the stack before we can add the new one
00628     QWidget *oldConfigWidget = fStack->widget( NEW_CONDUIT );
00629     if ( oldConfigWidget )
00630     {
00631         fStack->removeWidget( oldConfigWidget );
00632         KPILOT_DELETE( oldConfigWidget );
00633     }
00634     if (fStack->addWidget(d->widget(),NEW_CONDUIT)<0)
00635     {
00636 #ifdef DEBUG
00637         DEBUGKPILOT << fname
00638             << ": Can't add config widget to stack."
00639             << endl;
00640 #endif
00641     }
00642     else
00643     {
00644         d->load();
00645         fStack->raiseWidget(NEW_CONDUIT);
00646         d->widget()->show();
00647         fCurrentConfig=d;
00648         // make sure the changed signal is propagated to the KCM*Dialog
00649         // and the apply button is enabled correspondingly.
00650         connect(d, SIGNAL(changed(bool)), this, SIGNAL(changed(bool)));
00651     }
00652 }
00653 
00654 bool ConduitConfigWidget::release()
00655 {
00656     FUNCTIONSETUP;
00657     if (fCurrentConfig)
00658     {
00659         if (!fCurrentConfig->maybeSave())
00660             return false;
00661         fStack->raiseWidget(0);
00662         delete fCurrentConfig;
00663     }
00664     if (fCurrentConduit)
00665     {
00666         KLibLoader::self()->unloadLibrary(
00667             QFile::encodeName(fCurrentConduit->text(CONDUIT_LIBRARY)));
00668     }
00669     fCurrentConduit=0L;
00670     fCurrentConfig=0L;
00671     return true;
00672 }
00673 
00674 void ConduitConfigWidget::unselect()
00675 {
00676     fConduitList->setSelected( fCurrentConduit, true );
00677     fConduitList->setCurrentItem( fCurrentConduit );
00678 }
00679 
00680 void ConduitConfigWidget::selected(QListViewItem *p)
00681 {
00682     FUNCTIONSETUP;
00683 #ifdef DEBUG
00684     DEBUGKPILOT << fname << ": "
00685         << ( p ? p->text(CONDUIT_NAME) : CSL1("None") )
00686         << endl;
00687 #endif
00688     if (p!=fCurrentConduit)
00689     {
00690         if (!release())
00691         {
00692             fConduitList->blockSignals(true);
00693             QTimer::singleShot(1,this,SLOT(unselect()));
00694             return;
00695         }
00696     }
00697     fCurrentConduit=p;
00698     loadAndConfigure(p);
00699 //  fStack->adjustSize();
00700 #ifdef DEBUG
00701     DEBUGKPILOT << fname << ": New widget size "
00702         << fStack->size().width() << "x" << fStack->size().height() << endl;
00703     DEBUGKPILOT << fname << ": Current size "
00704         << size().width() << "x"
00705         << size().height() << endl;
00706 #endif
00707     emit sizeChanged();
00708 #ifdef DEBUG
00709     DEBUGKPILOT << fname << ": New size "
00710         << size().width() << "x"
00711         << size().height() << endl;
00712 #endif
00713 
00714     // set the dialog title to the selected item
00715     QListViewItem *pParent = p->parent();
00716     QString title;
00717     title = pParent ? pParent->text(CONDUIT_NAME) + CSL1(" - ") : QString() ;
00718     title += p ? p->text(CONDUIT_NAME) : i18n("KPilot Setup");
00719     fTitleText->setText(title);
00720 }
00721 
00722 void ConduitConfigWidget::configure()
00723 {
00724     loadAndConfigure(fConduitList->selectedItem());
00725 }
00726 
00727 void ConduitConfigWidget::warnNoExec(const QListViewItem * p)
00728 {
00729     FUNCTIONSETUP;
00730 
00731     QString msg = i18n("<qt>No library could be "
00732         "found for the conduit %1. This means that the "
00733         "conduit was not installed properly.</qt>")
00734         .arg(p->text(CONDUIT_NAME));
00735 
00736 #ifdef DEBUG
00737     DEBUGKPILOT << fname << ": No library for "
00738         << p->text(CONDUIT_NAME) << endl;
00739 #endif
00740 
00741     KMessageBox::error(this, msg, i18n("Conduit Error"));
00742 }
00743 
00744 void ConduitConfigWidget::warnNoLibrary(const QListViewItem *p)
00745 {
00746     FUNCTIONSETUP;
00747 
00748     QString msg = i18n("<qt>There was a problem loading the library "
00749         "for the conduit %1. This means that the "
00750         "conduit was not installed properly.</qt>")
00751         .arg(p->text(CONDUIT_NAME));
00752 
00753 #ifdef DEBUG
00754     DEBUGKPILOT << fname << ": Can't load library for "
00755         << p->text(CONDUIT_NAME) << endl;
00756 #endif
00757 
00758     KMessageBox::error(this, msg, i18n("Conduit Error"));
00759 }
00760 
00761 void ConduitConfigWidget::save()
00762 {
00763     FUNCTIONSETUP;
00764 
00765     // Only new-style conduits and the general setup have changes that need to be commited
00766     // old-style conduits have their own config dlg which commits them itself
00767     if ( fStack->id( fStack->visibleWidget())==NEW_CONDUIT )
00768     {
00769         if (fCurrentConfig) fCurrentConfig->commit();
00770     }
00771 
00772     QStringList activeConduits;
00773     QListViewItemIterator it( fConduitList );
00774     while ( it.current() ) {
00775         KPilotCheckListItem*p = dynamic_cast<KPilotCheckListItem*>(it.current());
00776         if ( p )
00777         {
00778             p->setOriginalState( p->isOn() );
00779             if ( p->isOn() )
00780             activeConduits.append(p->text(CONDUIT_DESKTOP));
00781         }
00782         ++it;
00783     }
00784     KPilotSettings::setInstalledConduits(activeConduits);
00785     KPilotSettings::self()->writeConfig();
00786 }
00787 
00788 
00789 void ConduitConfigWidget::load()
00790 {
00791     FUNCTIONSETUP;
00792     KPilotSettings::self()->readConfig();
00793 
00794     QStringList potentiallyInstalled = KPilotSettings::installedConduits();
00795     QListViewItem*p = fConduitList->firstChild();
00796     while (p)
00797     {
00798         QListViewItem*q = p->firstChild();
00799         while (q)
00800         {
00801             QCheckListItem*qq=dynamic_cast<QCheckListItem*>(q);
00802             if (qq)
00803             {
00804                 qq->setOn(! (potentiallyInstalled.findIndex(qq->text(CONDUIT_DESKTOP))<0) );
00805             }
00806             q = q->nextSibling();
00807         }
00808         p=p->nextSibling();
00809     }
00810 
00811 
00812     // Only new-style conduits and the general setup have changes that need to be commited
00813     // old-style conduits have their own config dlg which commits them itself
00814     if ( fStack->id( fStack->visibleWidget())==NEW_CONDUIT )
00815     {
00816         if (fCurrentConfig) fCurrentConfig->load();
00817     }
00818 }
00819 
00820 
00821 void ConduitConfigWidget::conduitsChanged(QListViewItem*item)
00822 {
00823     KPilotCheckListItem*i=dynamic_cast<KPilotCheckListItem*>(item);
00824     if (i)
00825     {
00826         if (!i->isOriginalState()) emit changed(true);
00827     }
00828 }
00829 
00830 void ConduitConfigWidget::reopenItem(QListViewItem *i)
00831 {
00832     i->setOpen(true);
00833 }
00834 
00835 void ConduitConfigWidget::configureWizard()
00836 {
00837     FUNCTIONSETUP;
00838     ConfigWizard wiz(this, "Wizard");
00839     if (wiz.exec()) {
00840         KPilotSettings::self()->readConfig();
00841         load();
00842     }
00843 }
00844 
00845 
KDE Home | KDE Accessibility Home | Description of Access Keys