kpilot/kpilot

kpilot.cc

00001 /* KPilot
00002 **
00003 ** Copyright (C) 1998-2001 by Dan Pilone
00004 ** Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
00005 **
00006 ** This is the main program in KPilot.
00007 **
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 
00032 #include <config.h>
00033 #include "options.h"
00034 #include "fakes.h"
00035 
00036 #include <qfile.h>
00037 #include <qptrlist.h>
00038 #include <qstring.h>
00039 #include <qvbox.h>
00040 #include <qtimer.h>
00041 
00042 #include <kjanuswidget.h>
00043 #include <kurl.h>
00044 #include <kmessagebox.h>
00045 #include <kstatusbar.h>
00046 #include <kconfig.h>
00047 #include <kwin.h>
00048 #include <kcombobox.h>
00049 #include <kmenubar.h>
00050 #include <kstandarddirs.h>
00051 #include <kaboutdata.h>
00052 #include <kcmdlineargs.h>
00053 #include <kiconloader.h>
00054 #include <kdebug.h>
00055 #include <kaction.h>
00056 #include <kactionclasses.h>
00057 #include <kstdaction.h>
00058 #include <kuniqueapplication.h>
00059 #include <kkeydialog.h>
00060 #include <kedittoolbar.h>
00061 #include <kcmultidialog.h>
00062 #include <kprogress.h>
00063 #include <klibloader.h>
00064 
00065 
00066 #include "kpilotConfigDialog.h"
00067 #include "kpilotConfig.h"
00068 #include "kpilotConfigWizard.h"
00069 
00070 #include "pilotComponent.h"
00071 #include "pilotDatabase.h"
00072 
00073 #include "addressWidget.h"
00074 #include "memoWidget.h"
00075 #include "fileInstallWidget.h"
00076 #include "logWidget.h"
00077 #include "dbviewerWidget.h"
00078 #include "datebookWidget.h"
00079 #include "todoWidget.h"
00080 
00081 #include "conduitConfigDialog.h"
00082 
00083 #ifndef _KPILOT_PILOTDAEMON_H
00084 #include "pilotDaemonDCOP.h"
00085 #endif
00086 
00087 #ifndef __PILOTDAEMONDCOP_STUB__
00088 #include "pilotDaemonDCOP_stub.h"
00089 #endif
00090 
00091 #include "kpilot.moc"
00092 
00093 class KPilotInstaller::KPilotPrivate
00094 {
00095 public:
00096     typedef QPtrList<PilotComponent> ComponentList;
00097 
00098 private:
00099     ComponentList  fPilotComponentList;
00100 
00101 public:
00102     ComponentList &list() { return fPilotComponentList; } ;
00103 } ;
00104 
00105 KPilotInstaller::KPilotInstaller() :
00106     DCOPObject("KPilotIface"),
00107     KMainWindow(0),
00108     fDaemonStub(new PilotDaemonDCOP_stub("kpilotDaemon",
00109         "KPilotDaemonIface")),
00110     fP(new KPilotPrivate),
00111     fQuitAfterCopyComplete(false),
00112     fManagingWidget(0L),
00113     fDaemonWasRunning(true),
00114     fAppStatus(Startup),
00115     fFileInstallWidget(0L),
00116     fLogWidget(0L)
00117 {
00118     FUNCTIONSETUP;
00119 
00120     readConfig();
00121     setupWidget();
00122 
00123 #ifdef DEBUG
00124     PilotRecord::allocationInfo();
00125 #endif
00126     fConfigureKPilotDialogInUse = false;
00127 
00128 }
00129 
00130 KPilotInstaller::~KPilotInstaller()
00131 {
00132     FUNCTIONSETUP;
00133     killDaemonIfNeeded();
00134     delete fDaemonStub;
00135 #ifdef DEBUG
00136     PilotRecord::allocationInfo();
00137     (void) PilotDatabase::count();
00138 #endif
00139 }
00140 
00141 void KPilotInstaller::killDaemonIfNeeded()
00142 {
00143     FUNCTIONSETUP;
00144     if (KPilotSettings::killDaemonAtExit())
00145     {
00146         if (!fDaemonWasRunning)
00147         {
00148 #ifdef DEBUG
00149             DEBUGKPILOT << fname << ": Killing daemon." << endl;
00150 #endif
00151 
00152             getDaemon().quitNow();
00153         }
00154     }
00155 }
00156 
00157 void KPilotInstaller::startDaemonIfNeeded()
00158 {
00159     FUNCTIONSETUP;
00160 
00161     fAppStatus=WaitingForDaemon;
00162 
00163     QString daemonError;
00164     QCString daemonDCOP;
00165     int daemonPID;
00166 
00167     QString s = getDaemon().statusString();
00168 
00169 #ifdef DEBUG
00170     DEBUGKPILOT << fname << ": Daemon status is "
00171         << ( s.isEmpty() ? CSL1("<none>") : s ) << endl;
00172 #endif
00173 
00174     if ((s.isEmpty()) || (!getDaemon().ok()))
00175     {
00176 #ifdef DEBUG
00177         DEBUGKPILOT << fname
00178             << ": Daemon not responding, trying to start it."
00179             << endl;
00180 #endif
00181         fLogWidget->addMessage(i18n("Starting the KPilot daemon ..."));
00182         fDaemonWasRunning = false;
00183     }
00184     else
00185     {
00186         fDaemonWasRunning = true;
00187     }
00188 
00189     if (!fDaemonWasRunning && KApplication::startServiceByDesktopName(
00190         CSL1("kpilotdaemon"),
00191         QString::null, &daemonError, &daemonDCOP, &daemonPID
00192             , "0" /* no notify */
00193         ))
00194     {
00195         kdError() << k_funcinfo
00196             << ": Can't start daemon : " << daemonError << endl;
00197         if (fLogWidget)
00198         {
00199             fLogWidget->addMessage(i18n("Could not start the "
00200                 "KPilot daemon. The system error message "
00201                 "was: &quot;%1&quot;").arg(daemonError));
00202         }
00203         fAppStatus=Error;
00204     }
00205     else
00206     {
00207 #ifdef DEBUG
00208         s = getDaemon().statusString();
00209         DEBUGKPILOT << fname << ": Daemon status is " << s << endl;
00210 #endif
00211         if (fLogWidget)
00212         {
00213             int wordoffset;
00214             s.remove(0,12);
00215             wordoffset=s.find(';');
00216             if (wordoffset>0) s.truncate(wordoffset);
00217 
00218             fLogWidget->addMessage(
00219                 i18n("Daemon status is `%1'")
00220                 .arg(s.isEmpty() ? i18n("not running") : s ));
00221         }
00222         fAppStatus=Normal;
00223     }
00224 }
00225 
00226 void KPilotInstaller::readConfig()
00227 {
00228     FUNCTIONSETUP;
00229 
00230     KPilotSettings::self()->readConfig();
00231 
00232     (void) Pilot::setupPilotCodec(KPilotSettings::encoding());
00233     (void) Pilot::setupPilotCodec(KPilotSettings::encoding());
00234 
00235     if (fLogWidget)
00236     {
00237         fLogWidget->addMessage(i18n("Using character set %1 on "
00238             "the handheld.")
00239             .arg(Pilot::codecName()));
00240     }
00241 }
00242 
00243 
00244 void KPilotInstaller::setupWidget()
00245 {
00246     FUNCTIONSETUP;
00247 
00248 #ifdef DEBUG
00249     DEBUGKPILOT << fname << ": Creating central widget." << endl;
00250 #endif
00251 
00252     setCaption(CSL1("KPilot"));
00253     setMinimumSize(500, 405);
00254 
00255 
00256     fManagingWidget = new KJanusWidget(this,"mainWidget",
00257         KJanusWidget::IconList);
00258     fManagingWidget->setMinimumSize(fManagingWidget->sizeHint());
00259     fManagingWidget->show();
00260     setCentralWidget(fManagingWidget);
00261     connect( fManagingWidget, SIGNAL( aboutToShowPage ( QWidget* ) ),
00262             this, SLOT( slotAboutToShowComponent( QWidget* ) ) );
00263 
00264     initIcons();
00265     initMenu();
00266     initComponents();
00267 
00268     setMinimumSize(sizeHint() + QSize(10,60));
00269 
00270     createGUI(CSL1("kpilotui.rc"), false);
00271 #ifdef DEBUG
00272     DEBUGKPILOT << fname
00273         << ": Got XML from "
00274         << xmlFile() << " and " << localXMLFile() << endl;
00275 #endif
00276     setAutoSaveSettings();
00277 }
00278 
00279 void KPilotInstaller::initComponents()
00280 {
00281     FUNCTIONSETUP;
00282 
00283     QString defaultDBPath = KPilotConfig::getDefaultDBPath();
00284 
00285 #ifdef DEBUG
00286     DEBUGKPILOT << fname << ": Creating component pages." << endl;
00287 #endif
00288 
00289     QPixmap pixmap;
00290     QString pixfile;
00291     QWidget *w;
00292 
00293 #define ADDICONPAGE(a,b) \
00294     pixmap = KGlobal::iconLoader()->loadIcon(b, KIcon::Desktop, 64); \
00295     w = getManagingWidget()->addVBoxPage(a,QString::null, pixmap) ;
00296 
00297     ADDICONPAGE(i18n("HotSync"),CSL1("kpilotbhotsync"));
00298     fLogWidget = new LogWidget(w);
00299     addComponentPage(fLogWidget, i18n("HotSync"));
00300     fLogWidget->setShowTime(true);
00301 
00302     ADDICONPAGE(i18n("To-do Viewer"),CSL1("kpilottodo"));
00303     addComponentPage(new TodoWidget(w,defaultDBPath),
00304         i18n("To-do Viewer"));
00305 
00306     ADDICONPAGE(i18n("Address Viewer"),CSL1("kpilotaddress"));
00307     addComponentPage(new AddressWidget(w,defaultDBPath),
00308         i18n("Address Viewer"));
00309 
00310     ADDICONPAGE(i18n("Memo Viewer"),CSL1("kpilotknotes"));
00311     addComponentPage(new MemoWidget(w, defaultDBPath),
00312         i18n("Memo Viewer"));
00313 
00314     ADDICONPAGE(i18n("File Installer"),CSL1("kpilotfileinstaller"));
00315     fFileInstallWidget = new FileInstallWidget(
00316         w,defaultDBPath);
00317     addComponentPage(fFileInstallWidget, i18n("File Installer"));
00318 
00319     ADDICONPAGE(i18n("Generic DB Viewer"),CSL1("kpilotdb"));
00320     addComponentPage(new GenericDBWidget(w,defaultDBPath),
00321         i18n("Generic DB Viewer"));
00322 
00323 #undef ADDICONPAGE
00324 
00325     QTimer::singleShot(500,this,SLOT(initializeComponents()));
00326 }
00327 
00328 
00329 
00330 void KPilotInstaller::initIcons()
00331 {
00332     FUNCTIONSETUP;
00333 
00334 }
00335 
00336 
00337 
00338 void KPilotInstaller::slotAboutToShowComponent( QWidget *c )
00339 {
00340     FUNCTIONSETUP;
00341     int ix = fManagingWidget->pageIndex( c );
00342     PilotComponent*compToShow = fP->list().at(ix);
00343 #ifdef DEBUG
00344     DEBUGKPILOT << fname
00345         << ": Index: " << ix
00346         << ", Widget=" << c
00347         << ", ComToShow=" << compToShow << endl;
00348 #endif
00349     for ( PilotComponent *comp = fP->list().first(); comp; comp = fP->list().next() )
00350     {
00351         // Load/Unload the data needed
00352         comp->showKPilotComponent( comp == compToShow );
00353     }
00354 }
00355 
00356 void KPilotInstaller::slotSelectComponent(PilotComponent * c)
00357 {
00358     FUNCTIONSETUP;
00359     if (!c)
00360     {
00361         kdWarning() << k_funcinfo << ": Not a widget." << endl;
00362         return;
00363     }
00364 
00365     QObject *o = c->parent();
00366     if (!o)
00367     {
00368         kdWarning() << k_funcinfo << ": No parent." << endl;
00369         return;
00370     }
00371 
00372     QWidget *parent = dynamic_cast<QWidget *>(o);
00373     if (!parent)
00374     {
00375         kdWarning() << k_funcinfo << ": No widget parent." << endl;
00376         return;
00377     }
00378 
00379     int index = fManagingWidget->pageIndex(parent);
00380 
00381     if (index < 0)
00382     {
00383         kdWarning() << k_funcinfo << ": Index " << index << endl;
00384         return;
00385     }
00386 
00387     for ( PilotComponent *comp = fP->list().first(); comp; comp = fP->list().next() )
00388     {
00389         // Load/Unload the data needed
00390         comp->showKPilotComponent( comp == c );
00391     }
00392     fManagingWidget->showPage(index);
00393 }
00394 
00395 
00396 
00397 
00398 void KPilotInstaller::slotBackupRequested()
00399 {
00400     FUNCTIONSETUP;
00401     setupSync(SyncAction::SyncMode::eBackup,
00402         i18n("Next sync will be a backup. ") +
00403         i18n("Please press the HotSync button."));
00404 }
00405 
00406 void KPilotInstaller::slotRestoreRequested()
00407 {
00408     FUNCTIONSETUP;
00409     setupSync(SyncAction::SyncMode::eRestore,
00410         i18n("Next sync will restore the Pilot from backup. ") +
00411         i18n("Please press the HotSync button."));
00412 }
00413 
00414 void KPilotInstaller::slotHotSyncRequested()
00415 {
00416     FUNCTIONSETUP;
00417     setupSync(SyncAction::SyncMode::eHotSync,
00418         i18n("Next sync will be a regular HotSync. ") +
00419         i18n("Please press the HotSync button."));
00420 }
00421 
00422 void KPilotInstaller::slotFullSyncRequested()
00423 {
00424     FUNCTIONSETUP;
00425     setupSync(SyncAction::SyncMode::eFullSync,
00426         i18n("Next sync will be a Full Sync. ") +
00427         i18n("Please press the HotSync button."));
00428 }
00429 
00430 void KPilotInstaller::slotHHtoPCRequested()
00431 {
00432     FUNCTIONSETUP;
00433     setupSync(SyncAction::SyncMode::eCopyHHToPC,
00434         i18n("Next sync will copy Handheld data to PC. ") +
00435         i18n("Please press the HotSync button."));
00436 }
00437 
00438 void KPilotInstaller::slotPCtoHHRequested()
00439 {
00440     FUNCTIONSETUP;
00441     setupSync(SyncAction::SyncMode::eCopyPCToHH,
00442         i18n("Next sync will copy PC data to Handheld. ") +
00443         i18n("Please press the HotSync button."));
00444 }
00445 
00446 /* virtual DCOP */ ASYNC KPilotInstaller::daemonStatus(int i)
00447 {
00448     FUNCTIONSETUP;
00449 #ifdef DEBUG
00450     DEBUGKPILOT << fname << ": Received daemon message " << i << endl;
00451 #endif
00452 
00453     switch(i)
00454     {
00455     case KPilotDCOP::StartOfHotSync :
00456         if (fAppStatus==Normal)
00457         {
00458             fAppStatus=WaitingForDaemon;
00459             componentPreSync();
00460         }
00461         break;
00462     case KPilotDCOP::EndOfHotSync :
00463         if (fAppStatus==WaitingForDaemon)
00464         {
00465             componentPostSync();
00466             fAppStatus=Normal;
00467         }
00468         break;
00469     case KPilotDCOP::DaemonQuit :
00470         if (fLogWidget)
00471         {
00472             fLogWidget->logMessage(i18n("The daemon has exited."));
00473             fLogWidget->logMessage(i18n("No further HotSyncs are possible."));
00474             fLogWidget->logMessage(i18n("Restart the daemon to HotSync again."));
00475         }
00476         fAppStatus=WaitingForDaemon;
00477         break;
00478     case KPilotDCOP::None :
00479         kdWarning() << k_funcinfo << ": Unhandled status message " << i << endl;
00480         break;
00481     }
00482 }
00483 
00484 /* virtual DCOP*/ int KPilotInstaller::kpilotStatus()
00485 {
00486     return status();
00487 }
00488 
00489 bool KPilotInstaller::componentPreSync()
00490 {
00491     FUNCTIONSETUP;
00492 
00493     QString reason;
00494     QString rprefix(i18n("Cannot start a Sync now. %1"));
00495 
00496     for (fP->list().first();
00497         fP->list().current(); fP->list().next())
00498     {
00499 #ifdef DEBUG
00500         DEBUGKPILOT << fname
00501             << ": Pre-sync for builtin "
00502             << fP->list().current()->name() << endl;
00503 #endif
00504         if (!fP->list().current()->preHotSync(reason))
00505             break;
00506     }
00507 
00508     if (!reason.isNull())
00509     {
00510         KMessageBox::sorry(this,
00511             rprefix.arg(reason),
00512             i18n("Cannot start Sync"));
00513         return false;
00514     }
00515     return true;
00516 }
00517 
00518 void KPilotInstaller::componentPostSync()
00519 {
00520     FUNCTIONSETUP;
00521 
00522     for (fP->list().first();
00523         fP->list().current(); fP->list().next())
00524     {
00525 #ifdef DEBUG
00526         DEBUGKPILOT << fname
00527             << ": Post-sync for builtin "
00528             << fP->list().current()->name() << endl;
00529 #endif
00530         fP->list().current()->postHotSync();
00531     }
00532 }
00533 
00534 void KPilotInstaller::setupSync(int kind, const QString & message)
00535 {
00536     FUNCTIONSETUP;
00537 
00538     if (!componentPreSync())
00539     {
00540         return;
00541     }
00542     if (!message.isEmpty())
00543     {
00544         QString m(message);
00545         if (fLogWidget)
00546         {
00547             fLogWidget->logMessage(m);
00548         }
00549     }
00550     getDaemon().requestSync(kind);
00551 }
00552 
00553 void KPilotInstaller::closeEvent(QCloseEvent * e)
00554 {
00555     FUNCTIONSETUP;
00556 
00557     quit();
00558     e->accept();
00559 }
00560 
00561 void KPilotInstaller::initMenu()
00562 {
00563     FUNCTIONSETUP;
00564 
00565     KAction *a;
00566 
00567     KActionMenu *syncPopup;
00568 
00569     syncPopup = new KActionMenu(i18n("HotSync"), CSL1("kpilot"),
00570         actionCollection(), "popup_hotsync");
00571     syncPopup->setToolTip(i18n("Select the kind of HotSync to perform next."));
00572     syncPopup->setWhatsThis(i18n("Select the kind of HotSync to perform next. "
00573         "This applies only to the next HotSync; to change the default, use "
00574         "the configuration dialog."));
00575     connect(syncPopup, SIGNAL(activated()),
00576         this, SLOT(slotHotSyncRequested()));
00577 
00578     // File actions, keep this list synced with kpilotui.rc and pilotDaemon.cc
00579     a = new KAction(i18n("&HotSync"), CSL1("hotsync"), 0,
00580         this, SLOT(slotHotSyncRequested()),
00581         actionCollection(), "file_hotsync");
00582     a->setToolTip(i18n("Next HotSync will be normal HotSync."));
00583     a->setWhatsThis(i18n("Tell the daemon that the next HotSync "
00584         "should be a normal HotSync."));
00585     syncPopup->insert(a);
00586 
00587     a = new KAction(i18n("Full&Sync"), CSL1("fullsync"), 0,
00588         this, SLOT(slotFullSyncRequested()),
00589         actionCollection(), "file_fullsync");
00590     a->setToolTip(i18n("Next HotSync will be a FullSync."));
00591     a->setWhatsThis(i18n("Tell the daemon that the next HotSync "
00592         "should be a FullSync (check data on both sides)."));
00593     syncPopup->insert(a);
00594 
00595     a = new KAction(i18n("&Backup"), CSL1("backup"), 0,
00596         this, SLOT(slotBackupRequested()),
00597         actionCollection(), "file_backup");
00598     a->setToolTip(i18n("Next HotSync will be backup."));
00599     a->setWhatsThis(i18n("Tell the daemon that the next HotSync "
00600         "should back up the Handheld to the PC."));
00601     syncPopup->insert(a);
00602 
00603     a = new KAction(i18n("&Restore"), CSL1("restore"), 0,
00604         this, SLOT(slotRestoreRequested()),
00605         actionCollection(), "file_restore");
00606     a->setToolTip(i18n("Next HotSync will be restore."));
00607     a->setWhatsThis(i18n("Tell the daemon that the next HotSync "
00608         "should restore the Handheld from data on the PC."));
00609     syncPopup->insert(a);
00610 
00611     a = new KAction(i18n("Copy Handheld to PC"), QString::null, 0,
00612         this, SLOT(slotHHtoPCRequested()),
00613         actionCollection(), "file_HHtoPC");
00614     a->setToolTip(i18n("Next HotSync will be backup."));
00615     a->setWhatsThis(i18n("Tell the daemon that the next HotSync "
00616         "should copy all data from the Handheld to the PC, "
00617         "overwriting entries on the PC."));
00618     syncPopup->insert(a);
00619 
00620     a = new KAction(i18n("Copy PC to Handheld"), QString::null, 0,
00621         this, SLOT(slotPCtoHHRequested()),
00622         actionCollection(), "file_PCtoHH");
00623     a->setToolTip(i18n("Next HotSync will copy PC to Handheld."));
00624     a->setWhatsThis(i18n("Tell the daemon that the next HotSync "
00625         "should copy all data from the PC to the Handheld, "
00626         "overwriting entries on the Handheld."));
00627     syncPopup->insert(a);
00628 
00629 
00630 #if 0
00631     a = new KAction(i18n("&List Only"),CSL1("listsync"),0,
00632         this,SLOT(slotTestSyncRequested()),
00633         actionCollection(), "file_list");
00634     a->setToolTip(i18n("Next HotSync will list databases."));
00635     a->setWhatsThis(i18n("Tell the daemon that the next HotSync "
00636         "should just list the files on the Handheld and do nothing "
00637         "else."));
00638     syncPopup->insert(a);
00639 #endif
00640 
00641 
00642     a = new KAction(i18n("Rese&t Link"),CSL1("reload"), 0,
00643         this, SLOT(slotResetLink()),
00644         actionCollection(),"file_reload");
00645     a->setToolTip(i18n("Reset the device connection."));
00646     a->setWhatsThis(i18n("Try to reset the daemon and its connection "
00647         "to the Handheld."));
00648 
00649 
00650     a = KStdAction::quit(this, SLOT(quit()), actionCollection());
00651     a->setWhatsThis(i18n("Quit KPilot, (and stop the daemon "
00652         "if configured that way)."));
00653 
00654     // View actions
00655 
00656     // Options actions
00657     createStandardStatusBarAction();
00658     setStandardToolBarMenuEnabled(true);
00659 
00660     (void) KStdAction::keyBindings(this, SLOT(optionsConfigureKeys()),
00661         actionCollection());
00662     (void) KStdAction::configureToolbars(this, SLOT(optionsConfigureToolbars()),
00663         actionCollection());
00664     (void) KStdAction::preferences(this, SLOT(configure()),
00665         actionCollection());
00666 
00667     a = new KAction(i18n("Configuration &Wizard..."), CSL1("wizard"), 0,
00668         this, SLOT(configureWizard()),
00669         actionCollection(), "options_configure_wizard");
00670     a->setWhatsThis(i18n("Configure KPilot using the configuration wizard."));
00671 
00672 }
00673 
00674 void KPilotInstaller::fileInstalled(int)
00675 {
00676     FUNCTIONSETUP;
00677 }
00678 
00679 void KPilotInstaller::quit()
00680 {
00681     FUNCTIONSETUP;
00682 
00683     for (fP->list().first();
00684         fP->list().current(); fP->list().next())
00685     {
00686         QString reason;
00687         if (!fP->list().current()->preHotSync(reason))
00688         {
00689             kdWarning() << k_funcinfo
00690                 << ": Couldn't save "
00691                 << fP->list().current()->name()
00692                 << endl;
00693         }
00694     }
00695 
00696     killDaemonIfNeeded();
00697     kapp->quit();
00698 }
00699 
00700 void KPilotInstaller::addComponentPage(PilotComponent * p,
00701     const QString & name)
00702 {
00703     FUNCTIONSETUP;
00704 
00705     if (!p)
00706     {
00707         kdWarning() << k_funcinfo
00708             << ": Adding NULL component?" << endl;
00709         return;
00710     }
00711 
00712 #ifdef DEBUG
00713     DEBUGKPILOT << fname
00714         << ": Adding component @"
00715         << (unsigned long) p << " called " << p->name("(none)") << endl;
00716 #endif
00717 
00718     fP->list().append(p);
00719 
00720     // The first component added gets id 1, while the title
00721     // screen -- added elsewhere -- has id 0.
00722     //
00723     // fManagingWidget->addWidget(p, fP->list().count());
00724 
00725 
00726     const char *componentname = p->name("(none)");
00727     char *actionname = 0L;
00728     int actionnameLength = 0;
00729 
00730     if (strncmp(componentname, "component_", 10) == 0)
00731     {
00732         actionnameLength = strlen(componentname) - 10 + 8;
00733         actionname = new char[actionnameLength];
00734 
00735         strlcpy(actionname, "view_", actionnameLength);
00736         strlcat(actionname, componentname + 10, actionnameLength);
00737     }
00738     else
00739     {
00740         actionnameLength = strlen(componentname) + 8;
00741         actionname = new char[actionnameLength];
00742 
00743         strlcpy(actionname, "view_", actionnameLength);
00744         strlcat(actionname, componentname, actionnameLength);
00745     }
00746 
00747 #ifdef DEBUG
00748     DEBUGKPILOT << fname
00749         << ": Using component action name "
00750         << name << " for " << actionname << endl;
00751 #endif
00752 
00753     KToggleAction *pt =
00754         new KToggleAction(name, /* "kpilot" -- component icon, */ 0,
00755         p, SLOT(slotShowComponent()),
00756         actionCollection(), actionname);
00757 
00758     pt->setExclusiveGroup(CSL1("view_menu"));
00759 
00760     connect(p, SIGNAL(showComponent(PilotComponent *)),
00761         this, SLOT(slotSelectComponent(PilotComponent *)));
00762 }
00763 
00764 /* slot */ void KPilotInstaller::initializeComponents()
00765 {
00766     FUNCTIONSETUP;
00767 
00768 /*  for (PilotComponent *p = fP->list().first();
00769         p ; p = fP->list().next())
00770     {
00771         p->initialize();
00772     }*/
00773 }
00774 
00775 
00776 void KPilotInstaller::optionsConfigureKeys()
00777 {
00778     FUNCTIONSETUP;
00779     KKeyDialog::configure( actionCollection() );
00780 }
00781 
00782 void KPilotInstaller::optionsConfigureToolbars()
00783 {
00784     FUNCTIONSETUP;
00785     // use the standard toolbar editor
00786     // This was added in KDE 3.1
00787     saveMainWindowSettings( KGlobal::config(), autoSaveGroup() );
00788     KEditToolbar dlg(actionCollection());
00789     connect(&dlg, SIGNAL(newToolbarConfig()), this, SLOT(slotNewToolbarConfig()));
00790     dlg.exec();
00791 }
00792 
00793 
00794 void KPilotInstaller::slotNewToolbarConfig()
00795 {
00796     FUNCTIONSETUP;
00797     // recreate our GUI
00798     createGUI();
00799     applyMainWindowSettings( KGlobal::config(), autoSaveGroup() );
00800 }
00801 
00802 void KPilotInstaller::slotResetLink()
00803 {
00804     FUNCTIONSETUP;
00805     getDaemon().reloadSettings();
00806 }
00807 
00808 /*
00809 ** Can't be a member function because it needs to be called even with no KPilotInstaller.
00810 */
00811 static bool runConfigure(PilotDaemonDCOP_stub &daemon,QWidget *parent)
00812 {
00813     FUNCTIONSETUP;
00814     bool ret = false;
00815 
00816     // Display the (modal) options page.
00817     //
00818     //
00819     int rememberedSync = daemon.nextSyncType();
00820     daemon.requestSync(0);
00821 
00822     KPilotSettings::self()->readConfig();
00823 
00824     KCMultiDialog *options = new KCMultiDialog( KDialogBase::Plain, i18n("Configuration"), parent, "KPilotPreferences", true );
00825     options->addModule( CSL1("kpilot_config.desktop") );
00826 
00827     if (!options)
00828     {
00829         kdError() << k_funcinfo
00830             << ": Can't allocate KPilotOptions object" << endl;
00831         daemon.requestSync(rememberedSync);
00832         return false;
00833     }
00834 
00835     int r = options->exec();
00836 
00837     if ( r && options->result() )
00838     {
00839 #ifdef DEBUG
00840         DEBUGKPILOT << fname << ": Updating link." << endl;
00841 #endif
00842 
00843         // The settings are changed in the external module!!!
00844         KPilotSettings::self()->config()->sync();
00845         KPilotSettings::self()->readConfig();
00846 
00847         // Update the daemon to reflect new settings.
00848         // @TODO: This should also be done when pressing apply without
00849         // closing the dialog.
00850         //
00851         daemon.reloadSettings();
00852         ret = true;
00853     }
00854 
00855     KPILOT_DELETE(options);
00856     daemon.requestSync(rememberedSync);
00857 
00858 #ifdef DEBUG
00859     DEBUGKPILOT << fname << ": Done with options." << endl;
00860 #endif
00861 
00862     KPilotConfig::sync();
00863     return ret;
00864 }
00865 
00866 /*
00867  * Run the config wizard -- this takes a little library magic, and
00868  * it might fail entirely; returns false if no wizard could be run,
00869  * or true if the wizard runs (says nothing about it being OK'ed or
00870  * canceled, though).
00871  */
00872 typedef enum { Failed, OK, Cancel } WizardResult;
00873 static WizardResult runWizard(PilotDaemonDCOP_stub &daemon,QWidget *parent)
00874 {
00875     FUNCTIONSETUP;
00876     WizardResult ret = Failed ;
00877     int rememberedSync = daemon.nextSyncType();
00878     daemon.requestSync(0);
00879 
00880     KPilotSettings::self()->readConfig();
00881     // Declarations at top because of goto's in this function
00882     ConfigWizard *(* f) (QWidget *, int) = 0L ;
00883     ConfigWizard *w = 0L;
00884     KLibrary *l = KLibLoader::self()->library("kcm_kpilot");
00885 
00886     if (!l)
00887     {
00888         kdWarning() << k_funcinfo << ": Couldn't load library!" << endl;
00889         goto sorry;
00890     }
00891 
00892     if (l->hasSymbol("create_wizard"))
00893     {
00894         f = ( ConfigWizard * (*) (QWidget *, int) ) (l->symbol("create_wizard")) ;
00895     }
00896 
00897     if (!f)
00898     {
00899         kdWarning() << k_funcinfo << ": No create_wizard() in library." << endl;
00900         goto sorry;
00901     }
00902 
00903     w = f(parent,ConfigWizard::Standalone);
00904     if (!w)
00905     {
00906         kdWarning() << k_funcinfo << ": Can't create wizard." << endl;
00907         goto sorry;
00908     }
00909 
00910     if (w->exec())
00911     {
00912         KPilotSettings::self()->readConfig();
00913         ret = OK;
00914     }
00915     else
00916     {
00917         ret = Cancel;
00918     }
00919     KPILOT_DELETE(w);
00920 
00921 sorry:
00922     if (Failed == ret)
00923     {
00924         KMessageBox::sorry(parent,
00925             i18n("The library containing the configuration wizard for KPilot "
00926                 "could not be loaded, and the wizard is not available. "
00927                 "Please try to use the regular configuration dialog."),
00928                 i18n("Wizard Not Available"));
00929     }
00930 
00931     if (OK == ret)
00932     {
00933         KPilotConfig::updateConfigVersion();
00934         KPilotSettings::writeConfig();
00935         KPilotConfig::sync();
00936     }
00937 
00938     daemon.requestSync(rememberedSync);
00939     return ret;
00940 }
00941 
00942 void KPilotInstaller::componentUpdate()
00943 {
00944     FUNCTIONSETUP;
00945 
00946     QString defaultDBPath = KPilotConfig::getDefaultDBPath();
00947     bool dbPathChanged = false;
00948 
00949     for (fP->list().first();
00950         fP->list().current();
00951         fP->list().next())
00952     {
00953 // TODO_RK: update the current component to use the new settings
00954 //          fP->list().current()->initialize();
00955         PilotComponent *p = fP->list().current();
00956         if (p && (p->dbPath() != defaultDBPath))
00957         {
00958             dbPathChanged = true;
00959             p->setDBPath(defaultDBPath);
00960         }
00961     }
00962 
00963     if (!dbPathChanged) // done if the username didn't change
00964     {
00965         return;
00966     }
00967 
00968     // Otherwise, need to re-load the databases
00969     //
00970     if (fLogWidget)
00971     {
00972         fLogWidget->logMessage(i18n("Changed username to `%1'.")
00973             .arg(KPilotSettings::userName()));
00974         fManagingWidget->showPage(0);
00975         slotAboutToShowComponent(fLogWidget);
00976     }
00977     else
00978     {
00979         int ix = fManagingWidget->activePageIndex();
00980         PilotComponent *component = 0L;
00981         if (ix>=0)
00982         {
00983             component = fP->list().at(ix);
00984         }
00985         if (component)
00986         {
00987             component->hideComponent(); // Throw away current data
00988             component->showComponent(); // Reload
00989         }
00990     }
00991 }
00992 
00993 /* virtual DCOP */ ASYNC KPilotInstaller::configureWizard()
00994 {
00995     FUNCTIONSETUP;
00996 
00997     if ( fAppStatus!=Normal || fConfigureKPilotDialogInUse )
00998     {
00999         if (fLogWidget)
01000         {
01001             fLogWidget->addMessage(i18n("Cannot run KPilot's configuration wizard right now (KPilot's UI is already busy)."));
01002         }
01003         return;
01004     }
01005     fAppStatus=UIBusy;
01006     fConfigureKPilotDialogInUse = true;
01007 
01008     if (runWizard(getDaemon(),this) == OK)
01009     {
01010         componentUpdate();
01011     }
01012 
01013     fConfigureKPilotDialogInUse = false;
01014     fAppStatus=Normal;
01015 }
01016 
01017 /* virtual DCOP */ ASYNC KPilotInstaller::configure()
01018 {
01019     FUNCTIONSETUP;
01020 
01021     if ( fAppStatus!=Normal || fConfigureKPilotDialogInUse )
01022     {
01023         if (fLogWidget)
01024         {
01025             fLogWidget->addMessage(i18n("Cannot configure KPilot right now (KPilot's UI is already busy)."));
01026         }
01027         return;
01028     }
01029     fAppStatus=UIBusy;
01030     fConfigureKPilotDialogInUse = true;
01031     if (runConfigure(getDaemon(),this))
01032     {
01033         componentUpdate();
01034     }
01035 
01036     fConfigureKPilotDialogInUse = false;
01037     fAppStatus=Normal;
01038 }
01039 
01040 
01041 /* static */ const char *KPilotInstaller::version(int kind)
01042 {
01043     FUNCTIONSETUP;
01044     // I don't think the program title needs to be translated. (ADE)
01045     //
01046     //
01047     if (kind)
01048     {
01049         return "kpilot.cc";
01050     }
01051     else
01052     {
01053         return "KPilot v" KPILOT_VERSION;
01054     }
01055 }
01056 
01057 // Command line options descriptions.
01058 //
01059 //
01060 //
01061 //
01062 static KCmdLineOptions kpilotoptions[] = {
01063     {"s", 0, 0},
01064     {"setup",
01065         I18N_NOOP("Setup the Pilot device, conduits and other parameters"),
01066         0L},
01067 #ifdef DEBUG
01068     {"debug <level>", I18N_NOOP("Set debugging level"), "0"},
01069 #endif
01070     KCmdLineLastOption
01071 };
01072 
01073 
01074 
01075 
01076 // "Regular" mode == 0
01077 // setup mode == 's'
01078 //
01079 // This is only changed by the --setup flag --
01080 // kpilot still does a setup the first time it is run.
01081 //
01082 //
01083 KPilotConfig::RunMode run_mode = KPilotConfig::Normal;
01084 
01085 
01086 
01087 int main(int argc, char **argv)
01088 {
01089     FUNCTIONSETUP;
01090 
01091     KAboutData about("kpilot", I18N_NOOP("KPilot"),
01092         KPILOT_VERSION,
01093         "KPilot - HotSync software for KDE\n\n",
01094         KAboutData::License_GPL,
01095         "(c) 1998-2000,2001, Dan Pilone (c) 2000-2006, Adriaan de Groot",
01096         0L,
01097         "http://www.kpilot.org/"
01098         );
01099     about.addAuthor("Dan Pilone",
01100         I18N_NOOP("Project Leader"),
01101         "pilone@slac.com" );
01102     about.addAuthor("Adriaan de Groot",
01103         I18N_NOOP("Maintainer"),
01104         "groot@kde.org", "http://www.kpilot.org/");
01105     about.addAuthor("Reinhold Kainhofer",
01106         I18N_NOOP("Core and conduits developer"), "reinhold@kainhofer.com", "http://reinhold.kainhofer.com/Linux/");
01107     about.addAuthor("Jason 'vanRijn' Kasper",
01108         I18N_NOOP("Core and conduits developer"),
01109         "vR@movingparts.net", "http://movingparts.net/");
01110     about.addCredit("Preston Brown", I18N_NOOP("VCal conduit"));
01111     about.addCredit("Greg Stern", I18N_NOOP("Abbrowser conduit"));
01112     about.addCredit("Chris Molnar", I18N_NOOP("Expenses conduit"));
01113     about.addCredit("Jörn Ahrens", I18N_NOOP("Notepad conduit, Bugfixer"));
01114     about.addCredit("Heiko Purnhagen", I18N_NOOP("Bugfixer"));
01115     about.addCredit("Jörg Habenicht", I18N_NOOP("Bugfixer"));
01116     about.addCredit("Martin Junius",
01117         I18N_NOOP("XML GUI"),
01118         "mj@m-j-s.net", "http://www.m-j-s.net/kde/");
01119     about.addCredit("David Bishop",
01120         I18N_NOOP(".ui files"));
01121     about.addCredit("Aaron J. Seigo",
01122         I18N_NOOP("Bugfixer, coolness"));
01123     about.addCredit("Bertjan Broeksema", 
01124         I18N_NOOP("VCalconduit state machine, CMake"));
01125 
01126     KCmdLineArgs::init(argc, argv, &about);
01127     KCmdLineArgs::addCmdLineOptions(kpilotoptions, "kpilot");
01128     KUniqueApplication::addCmdLineOptions();
01129     KCmdLineArgs *p = KCmdLineArgs::parsedArgs();
01130 
01131 #ifdef DEBUG
01132     KPilotConfig::getDebugLevel(p);
01133 #endif
01134 
01135 
01136     if (!KUniqueApplication::start())
01137     {
01138         return 0;
01139     }
01140     KUniqueApplication a(true, true);
01141 
01142 
01143     if (p->isSet("setup"))
01144     {
01145         run_mode = KPilotConfig::ConfigureKPilot;
01146     }
01147     else if (KPilotSettings::configVersion() < KPilotConfig::ConfigurationVersion)
01148     {
01149         kdWarning() << ": KPilot configuration version "
01150             << KPilotConfig::ConfigurationVersion
01151             << " newer than stored version "
01152             << KPilotSettings::configVersion() << endl;
01153         // Only force a reconfigure and continue if the
01154         // user is expecting normal startup. Otherwise,
01155         // do the configuration they're explicitly asking for.
01156         run_mode = KPilotConfig::interactiveUpdate();
01157         if (run_mode == KPilotConfig::Cancel) return 1;
01158     }
01159 
01160 
01161     if ( (run_mode == KPilotConfig::ConfigureKPilot) ||
01162         (run_mode == KPilotConfig::ConfigureAndContinue) ||
01163         (run_mode == KPilotConfig::WizardAndContinue) )
01164     {
01165 #ifdef DEBUG
01166         DEBUGKPILOT << fname
01167             << ": Running setup first."
01168             << " (mode " << run_mode << ")" << endl;
01169 #endif
01170         PilotDaemonDCOP_stub *daemon = new PilotDaemonDCOP_stub("kpilotDaemon","KPilotDaemonIface");
01171         bool r = false;
01172         if (run_mode == KPilotConfig::WizardAndContinue)
01173         {
01174             r = ( runWizard(*daemon,0L) == OK );
01175         }
01176         else
01177         {
01178             r = runConfigure(*daemon,0L);
01179         }
01180         delete daemon;
01181         if (!r) return 1;
01182         // User expected configure only.
01183         if (run_mode == KPilotConfig::ConfigureKPilot)
01184         {
01185             return 0;
01186         }
01187     }
01188 
01189     if (KPilotSettings::configVersion() < KPilotConfig::ConfigurationVersion)
01190     {
01191         kdWarning() << k_funcinfo <<
01192             ": Is still not configured for use." << endl;
01193         KPilotConfig::sorryVersionOutdated( KPilotSettings::configVersion());
01194         return 1;
01195     }
01196 
01197 
01198     KPilotInstaller *tp = new KPilotInstaller();
01199 
01200     if (tp->status() == KPilotInstaller::Error)
01201     {
01202         KPILOT_DELETE(tp);
01203         return 1;
01204     }
01205 
01206     QTimer::singleShot(0,tp,SLOT(startDaemonIfNeeded()));
01207 
01208     KGlobal::dirs()->addResourceType("pilotdbs",
01209         CSL1("share/apps/kpilot/DBBackup"));
01210     tp->show();
01211     a.setMainWidget(tp);
01212     DEBUGKPILOT << fname << ": MINIICON = " << a.miniIconName() << endl;
01213     return a.exec();
01214 }
01215 
01216 
KDE Home | KDE Accessibility Home | Description of Access Keys