kpilot Library API Documentation

pilotDaemon.cc

00001 /* pilotDaemon.cc KPilot 00002 ** 00003 ** Copyright (C) 1998-2001 by Dan Pilone 00004 ** 00005 ** This is the KPilot Daemon, which does the actual communication with 00006 ** the Pilot and with the conduits. 00007 */ 00008 00009 /* 00010 ** This program is free software; you can redistribute it and/or modify 00011 ** it under the terms of the GNU General Public License as published by 00012 ** the Free Software Foundation; either version 2 of the License, or 00013 ** (at your option) any later version. 00014 ** 00015 ** This program is distributed in the hope that it will be useful, 00016 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 ** GNU General Public License for more details. 00019 ** 00020 ** You should have received a copy of the GNU General Public License 00021 ** along with this program in a file called COPYING; if not, write to 00022 ** the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 00023 ** MA 02111-1307, USA. 00024 */ 00025 00026 /* 00027 ** Bug reports and questions can be sent to kde-pim@kde.org 00028 */ 00029 static const char *pilotdaemon_id = 00030 "$Id: pilotDaemon.cc,v 1.94 2003/10/13 21:33:27 goossens Exp $"; 00031 00032 // Heck yeah. 00033 #define ENABLE_KROUPWARE 00034 00035 #ifndef _KPILOT_OPTIONS_H 00036 #include "options.h" 00037 #endif 00038 00039 #include <time.h> 00040 00041 #ifdef TIME_WITH_SYS_TIME 00042 #include <sys/time.h> 00043 #endif 00044 00045 #include <sys/types.h> 00046 #include <sys/stat.h> 00047 #include <dirent.h> 00048 #include <fcntl.h> 00049 #include <unistd.h> 00050 #include <stdio.h> 00051 #include <stdlib.h> 00052 #include <signal.h> 00053 #include <errno.h> 00054 00055 #include <qdir.h> 00056 #include <qptrlist.h> 00057 #include <qcursor.h> 00058 #include <qptrstack.h> 00059 #include <qtimer.h> 00060 #include <qtooltip.h> 00061 00062 #include <kuniqueapplication.h> 00063 #include <kaboutdata.h> 00064 #include <kaboutapplication.h> 00065 #include <kcmdlineargs.h> 00066 #include <kwin.h> 00067 #include <ksimpleconfig.h> 00068 #include <kurl.h> 00069 #include <ksock.h> 00070 #include <kmessagebox.h> 00071 #include <kstandarddirs.h> 00072 #include <kpopupmenu.h> 00073 #include <kiconloader.h> 00074 #include <kio/netaccess.h> 00075 #include <kdebug.h> 00076 #include <ktempfile.h> 00077 #include <kprocess.h> 00078 #include <dcopclient.h> 00079 #include <kurldrag.h> 00080 00081 #include "pilotAppCategory.h" 00082 00083 #include "fileInstaller.h" 00084 #include "kpilotConfig.h" 00085 #include "pilotUser.h" 00086 00087 #include "hotSync.h" 00088 #include "interactiveSync.h" 00089 #include "syncStack.h" 00090 #include "internalEditorAction.h" 00091 00092 #ifdef ENABLE_KROUPWARE 00093 #include "kroupware.h" 00094 #endif 00095 00096 #include "kpilotDCOP_stub.h" 00097 #include "kpilotDCOP.h" 00098 #include "logWidgetDCOP_stub.h" 00099 00100 #include "pilotDaemon.moc" 00101 00102 00103 PilotDaemonTray::PilotDaemonTray(PilotDaemon * p) : 00104 KSystemTray(0, "pilotDaemon"), 00105 daemon(p), 00106 kap(0L) 00107 { 00108 FUNCTIONSETUP; 00109 setupWidget(); 00110 setAcceptDrops(true); 00111 00112 00113 /* NOTREACHED */ 00114 (void) pilotdaemon_id; 00115 } 00116 00117 /* virtual */ void PilotDaemonTray::dragEnterEvent(QDragEnterEvent * e) 00118 { 00119 FUNCTIONSETUP; 00120 e->accept(KURLDrag::canDecode(e)); 00121 } 00122 00123 /* virtual */ void PilotDaemonTray::dropEvent(QDropEvent * e) 00124 { 00125 FUNCTIONSETUP; 00126 00127 KURL::List list; 00128 00129 KURLDrag::decode(e, list); 00130 00131 QStringList files; 00132 for(KURL::List::ConstIterator it = list.begin(); it != list.end(); ++it) 00133 { 00134 if ((*it).isLocalFile()) 00135 files << (*it).path(); 00136 } 00137 00138 daemon->addInstallFiles(files); 00139 } 00140 00141 /* virtual */ void PilotDaemonTray::mousePressEvent(QMouseEvent * e) 00142 { 00143 FUNCTIONSETUP; 00144 00145 switch (e->button()) 00146 { 00147 case RightButton: 00148 { 00149 KPopupMenu *menu = contextMenu(); 00150 contextMenuAboutToShow(menu); 00151 menu->popup(e->globalPos()); 00152 } 00153 break; 00154 case LeftButton: 00155 if (daemon) daemon->slotRunKPilot(); 00156 break; 00157 default: 00158 KSystemTray::mousePressEvent(e); 00159 } 00160 } 00161 00162 /* virtual */ void PilotDaemonTray::closeEvent(QCloseEvent *) 00163 { 00164 FUNCTIONSETUP; 00165 daemon->quitNow(); 00166 } 00167 00168 void PilotDaemonTray::setupWidget() 00169 { 00170 FUNCTIONSETUP; 00171 00172 KGlobal::iconLoader()->addAppDir(CSL1("kpilot")); 00173 icon = SmallIcon(CSL1("hotsync")); 00174 busyicon = SmallIcon(CSL1("busysync")); 00175 00176 slotShowBusy(); 00177 QTimer::singleShot(2000,this,SLOT(slotShowNormal())); 00178 00179 KPopupMenu *menu = contextMenu(); 00180 00181 menu->insertItem(i18n("&About"), this, SLOT(slotShowAbout())); 00182 menuKPilotItem = menu->insertItem(i18n("Start &KPilot"), daemon, 00183 SLOT(slotRunKPilot())); 00184 00185 menuConfigureConduitsItem = menu->insertItem(i18n("&Configure Conduits..."), 00186 daemon, SLOT(slotRunConduitConfig())); 00187 00188 #ifdef DEBUG 00189 DEBUGDAEMON << fname << ": Finished getting icons" << endl; 00190 #endif 00191 } 00192 00193 void PilotDaemonTray::slotShowAbout() 00194 { 00195 FUNCTIONSETUP; 00196 00197 if (!kap) 00198 { 00199 kap = new KAboutApplication(0, "kpdab", false); 00200 } 00201 00202 kap->show(); 00203 } 00204 00205 00206 void PilotDaemonTray::enableRunKPilot(bool b) 00207 { 00208 FUNCTIONSETUP; 00209 contextMenu()->setItemEnabled(menuKPilotItem, b); 00210 contextMenu()->setItemEnabled(menuConfigureConduitsItem, b); 00211 } 00212 00213 00214 void PilotDaemonTray::changeIcon(IconShape i) 00215 { 00216 FUNCTIONSETUP; 00217 00218 switch (i) 00219 { 00220 case Normal: 00221 if (icon.isNull()) 00222 { 00223 kdWarning() << k_funcinfo 00224 << ": Regular icon is NULL!" << endl; 00225 } 00226 setPixmap(icon); 00227 break; 00228 case Busy: 00229 if (busyicon.isNull()) 00230 { 00231 kdWarning() << k_funcinfo 00232 << ": Busy icon is NULL!" << endl; 00233 } 00234 setPixmap(busyicon); 00235 break; 00236 default: 00237 kdWarning() << k_funcinfo 00238 << ": Bad icon number " << (int) i << endl; 00239 } 00240 } 00241 00242 void PilotDaemonTray::slotShowNormal() 00243 { 00244 FUNCTIONSETUP; 00245 changeIcon(Normal); 00246 } 00247 00248 void PilotDaemonTray::slotShowBusy() 00249 { 00250 FUNCTIONSETUP; 00251 changeIcon(Busy); 00252 } 00253 00254 00255 00256 PilotDaemon::PilotDaemon() : 00257 DCOPObject("KPilotDaemonIface"), 00258 fStatus(INIT), 00259 fPostSyncAction(None), 00260 fPilotLink(0L), 00261 fPilotDevice(QString::null), 00262 fNextSyncType(PilotDaemonDCOP::HotSync), 00263 fSyncStack(0L), 00264 fTray(0L), 00265 fInstaller(0L), 00266 fLogStub(new LoggerDCOP_stub("kpilot", "LogIface")), 00267 fKPilotStub(new KPilotDCOP_stub("kpilot", "KPilotIface")) 00268 { 00269 FUNCTIONSETUP; 00270 00271 setupPilotLink(); 00272 reloadSettings(); 00273 00274 if (fStatus == ERROR) 00275 { 00276 kdWarning() << k_funcinfo 00277 << ": Connecting to device failed." << endl; 00278 return; 00279 } 00280 00281 fInstaller = new FileInstaller; 00282 connect(fInstaller, SIGNAL(filesChanged()), 00283 this, SLOT(slotFilesChanged())); 00284 00285 00286 #ifdef DEBUG 00287 DEBUGDAEMON << fname 00288 << ": The daemon is ready with status " 00289 << statusString() << " (" << (int) fStatus << ")" << endl; 00290 #endif 00291 } 00292 00293 PilotDaemon::~PilotDaemon() 00294 { 00295 FUNCTIONSETUP; 00296 00297 KPILOT_DELETE(fPilotLink); 00298 KPILOT_DELETE(fSyncStack); 00299 KPILOT_DELETE(fInstaller); 00300 } 00301 00302 void PilotDaemon::addInstallFiles(const QStringList &l) 00303 { 00304 FUNCTIONSETUP; 00305 00306 fInstaller->addFiles( l, fTray ); 00307 } 00308 00309 int PilotDaemon::getPilotSpeed(KPilotConfigSettings & config) 00310 { 00311 FUNCTIONSETUP; 00312 00313 int speed = config.getPilotSpeed(); 00314 00315 // Translate the speed entry in the 00316 // config file to something we can 00317 // put in the environment (for who?) 00318 // 00319 // 00320 const char *speedname = 0L; 00321 00322 switch (speed) 00323 { 00324 case 0: 00325 speedname = "PILOTRATE=9600"; 00326 break; 00327 case 1: 00328 speedname = "PILOTRATE=19200"; 00329 break; 00330 case 2: 00331 speedname = "PILOTRATE=38400"; 00332 break; 00333 case 3: 00334 speedname = "PILOTRATE=57600"; 00335 break; 00336 case 4: 00337 speedname = "PILOTRATE=115200"; 00338 break; 00339 default: 00340 speedname = "PILOTRATE=9600"; 00341 } 00342 00343 #ifdef DEBUG 00344 DEBUGDAEMON << fname 00345 << ": Speed set to " 00346 << speedname << " (" << speed << ")" << endl; 00347 #endif 00348 00349 putenv((char *) speedname); 00350 00351 return speed; 00352 } 00353 00354 00355 void PilotDaemon::showTray() 00356 { 00357 FUNCTIONSETUP; 00358 00359 if (!fTray) 00360 { 00361 #ifdef DEBUG 00362 DEBUGDAEMON << fname << ": No tray icon to display!" << endl; 00363 #endif 00364 00365 return; 00366 } 00367 00368 // Copied from Klipper 00369 KWin::setSystemTrayWindowFor(fTray->winId(), 0); 00370 fTray->setGeometry(-100, -100, 42, 42); 00371 fTray->show(); 00372 00373 #ifdef DEBUG 00374 DEBUGDAEMON << fname << ": Tray icon displayed." << endl; 00375 #endif 00376 00377 updateTrayStatus(); 00378 } 00379 00380 /* DCOP ASYNC */ void PilotDaemon::reloadSettings() 00381 { 00382 FUNCTIONSETUP; 00383 00384 switch (fStatus) 00385 { 00386 case INIT: 00387 case HOTSYNC_END: 00388 case ERROR: 00389 case READY: 00390 // It's OK to reload settings in these states. 00391 break; 00392 case HOTSYNC_START: 00393 case FILE_INSTALL_REQ: 00394 // Postpone the reload till the sync finishes. 00395 fPostSyncAction |= ReloadSettings; 00396 return; 00397 break; 00398 } 00399 00400 KPilotConfigSettings & config = KPilotConfig::getConfig(); 00401 config.reparseConfiguration(); 00402 00403 getPilotSpeed(config); 00404 00405 fPilotDevice = config.getPilotDevice(); 00406 fPilotType = KPilotDeviceLink::None; 00407 00408 (void) PilotAppCategory::setupPilotCodec(config.getEncoding()); 00409 00410 #ifdef DEBUG 00411 DEBUGDAEMON << fname 00412 << ": Got configuration " 00413 << fPilotDevice 00414 << " (" 00415 << fPilotType 00416 << ")" 00417 << endl; 00418 #endif 00419 00420 00421 /* 00422 ** Override the kind of device, since OldStyleUSB 00423 ** works with everything and it saves the user from 00424 ** havind to choose the right kind. 00425 */ 00426 fPilotType = KPilotDeviceLink::OldStyleUSB; 00427 00428 if (fPilotLink) 00429 { 00430 #ifdef DEBUG 00431 DEBUGDAEMON << fname 00432 << ": Resetting with device " 00433 << fPilotDevice 00434 << " and type " 00435 << fPilotLink->deviceTypeString(fPilotType) << endl; 00436 #endif 00437 00438 fPilotLink->reset(fPilotType, fPilotDevice); 00439 } 00440 00441 if (config.getDockDaemon()) 00442 { 00443 if (!fTray) 00444 { 00445 fTray = new PilotDaemonTray(this); 00446 fTray->show(); 00447 } 00448 else 00449 { 00450 fTray->show(); 00451 } 00452 } 00453 else 00454 { 00455 if (fTray) 00456 { 00457 fTray->hide(); 00458 delete fTray; 00459 00460 fTray = 0L; 00461 } 00462 } 00463 00464 updateTrayStatus(); 00465 } 00466 00467 /* DCOP */ QString PilotDaemon::statusString() 00468 { 00469 FUNCTIONSETUP; 00470 00471 QString s = CSL1("PilotDaemon="); 00472 00473 switch (status()) 00474 { 00475 case INIT: 00476 s.append(QString(CSL1("Initializing"))); 00477 break; 00478 case READY: 00479 s.append(QString(CSL1("Found device"))); 00480 break; 00481 case ERROR: 00482 s.append(QString(CSL1("Error"))); 00483 break; 00484 case FILE_INSTALL_REQ: 00485 s.append(QString(CSL1("Installing File"))); 00486 break; 00487 case HOTSYNC_END: 00488 s.append(QString(CSL1("End of Hotsync"))); 00489 break; 00490 case HOTSYNC_START: 00491 s.append(QString(CSL1("Syncing"))); 00492 break; 00493 } 00494 00495 s.append(CSL1(" NextSync=")); 00496 s.append(syncTypeString(fNextSyncType)); 00497 00498 s.append(CSL1(" (")); 00499 if (fPilotLink) 00500 { 00501 s.append(fPilotLink->statusString()); 00502 } 00503 s.append(CSL1(")")); 00504 00505 return s; 00506 } 00507 00508 00509 00510 bool PilotDaemon::setupPilotLink() 00511 { 00512 FUNCTIONSETUP; 00513 00514 if (fPilotLink) 00515 { 00516 delete fPilotLink; 00517 00518 fPilotLink = 0; 00519 } 00520 00521 fPilotLink = KPilotDeviceLink::init(); 00522 if (!fPilotLink) 00523 { 00524 kdWarning() << k_funcinfo 00525 << ": Can't get pilot link." << endl; 00526 return false; 00527 } 00528 00529 QObject::connect(fPilotLink, SIGNAL(deviceReady()), 00530 this, SLOT(startHotSync())); 00531 // connect the signals emitted by the pilotDeviceLink 00532 QObject::connect(fPilotLink, SIGNAL(logError(const QString &)), 00533 this, SLOT(logError(const QString &))); 00534 QObject::connect(fPilotLink, SIGNAL(logMessage(const QString &)), 00535 this, SLOT(logMessage(const QString &))); 00536 QObject::connect(fPilotLink, 00537 SIGNAL(logProgress(const QString &,int)), 00538 this, SLOT(logProgress(const QString &,int))); 00539 00540 00541 return true; 00542 } 00543 00544 00545 /* DCOP ASYNC */ void PilotDaemon::quitNow() 00546 { 00547 FUNCTIONSETUP; 00548 // Using switch to make sure we cover all the cases. 00549 // 00550 // 00551 switch (fStatus) 00552 { 00553 case INIT: 00554 case HOTSYNC_END: 00555 case ERROR: 00556 getKPilot().daemonStatus(KPilotDCOP::DaemonQuit); 00557 kapp->quit(); 00558 break; 00559 case READY: 00560 case HOTSYNC_START: 00561 case FILE_INSTALL_REQ: 00562 fPostSyncAction |= Quit; 00563 break; 00564 } 00565 } 00566 00567 /* DCOP ASYNC */ void PilotDaemon::requestRegularSyncNext() 00568 { 00569 requestSync(PilotDaemonDCOP::HotSync); 00570 } 00571 00572 /* DCOP ASYNC */ void PilotDaemon::requestFastSyncNext() 00573 { 00574 requestSync(PilotDaemonDCOP::FastSync); 00575 } 00576 00577 00578 /* DCOP ASYNC */ void PilotDaemon::requestSync(int mode) 00579 { 00580 FUNCTIONSETUP; 00581 00582 #ifdef DEBUG 00583 DEBUGDAEMON << fname 00584 << ": Next sync is: " 00585 << syncTypeString(mode) 00586 << endl ; 00587 #endif 00588 00589 fNextSyncType = mode; 00590 00591 updateTrayStatus(); 00592 } 00593 00594 /* DCOP */ int PilotDaemon::nextSyncType() const 00595 { 00596 return fNextSyncType; 00597 } 00598 00599 QString PilotDaemon::syncTypeString(int i) const 00600 { 00601 FUNCTIONSETUP; 00602 switch (i) 00603 { 00604 case PilotDaemonDCOP::Test: 00605 return QString(CSL1("Test")); 00606 case PilotDaemonDCOP::HotSync: 00607 return QString(CSL1("HotSync")); 00608 case PilotDaemonDCOP::FastSync: 00609 return QString(CSL1("FastSync")); 00610 case PilotDaemonDCOP::Backup: 00611 return QString(CSL1("Backup")); 00612 case PilotDaemonDCOP::Restore: 00613 return QString(CSL1("Restore")); 00614 default: 00615 return QString(CSL1("<unknown>")); 00616 } 00617 } 00618 00619 /* slot */ void PilotDaemon::startHotSync() 00620 { 00621 FUNCTIONSETUP; 00622 00623 00624 if (fTray) 00625 { 00626 #ifdef DEBUG 00627 DEBUGKPILOT << fname << ": Changing tray icon." << endl; 00628 #endif 00629 00630 fTray->changeIcon(PilotDaemonTray::Busy); 00631 } 00632 00633 // Tell KPilot what's going on. 00634 getKPilot().daemonStatus(KPilotDCOP::StartOfHotSync); 00635 00636 fStatus = HOTSYNC_START ; 00637 int mode=0; 00638 bool pcchanged=false; 00639 00640 #ifdef DEBUG 00641 DEBUGDAEMON << fname 00642 << ": Starting Sync with type " 00643 << syncTypeString(fNextSyncType) 00644 << " (" << fNextSyncType << ")" << endl; 00645 #endif 00646 00647 KPilotConfigSettings &c = KPilotConfig::getConfig(); 00648 QStringList conduits( c.getInstalledConduits() ); 00649 if ( (conduits.findIndex( CSL1("internal_fileinstall") ) >= 0) && 00650 fInstaller) mode |= ActionQueue::WithInstaller; 00651 00652 // Queue to add all the actions for this sync to. 00653 fSyncStack = new ActionQueue(fPilotLink); 00654 00655 #ifdef ENABLE_KROUPWARE 00656 bool _syncWithKMail = false; 00657 int _kroupwareParts = 0; 00658 #endif 00659 00666 int kpilotstatus = getKPilot().kpilotStatus(); 00667 DCOPStub::Status callstatus = getKPilot().status(); 00668 00669 #ifdef DEBUG 00670 if (callstatus != DCOPStub::CallSucceeded) 00671 { 00672 DEBUGDAEMON << fname << 00673 ": Could not call KPilot for status." << endl; 00674 } 00675 else 00676 { 00677 DEBUGDAEMON << fname << ": KPilot status " << kpilotstatus << endl; 00678 } 00679 #endif 00680 00684 if ((callstatus == DCOPStub::CallSucceeded) && 00685 (kpilotstatus != KPilotDCOP::WaitingForDaemon)) 00686 { 00687 kdWarning() << k_funcinfo << 00688 ": KPilot returned status " << kpilotstatus << endl; 00689 00690 fSyncStack->queueInit(); 00691 fSyncStack->addAction(new SorryAction(fPilotLink)); 00692 // Near the end of this function - sets up 00693 // signal/slot connections and fires off the sync. 00694 goto launch; 00695 } 00696 else 00697 { 00698 fSyncStack->queueInit(ActionQueue::WithUserCheck); 00699 } 00700 00701 #ifdef ENABLE_KROUPWARE 00702 if ( conduits.findIndex( CSL1("internal_kroupware") ) >= 0 ) 00703 { 00704 logMessage( i18n("Kroupware syncing is enabled.") ); 00705 00706 QString errmsg; 00707 if (!KroupwareSync::startKMail(&errmsg)) 00708 { 00709 logMessage( i18n("Could not start KMail. The " 00710 "error message was: %1.").arg(errmsg)); 00711 } 00712 00713 _syncWithKMail = true; 00714 00715 if (conduits.findIndex( CSL1("vcal-conduit") ) >= 0 ) 00716 _kroupwareParts |= KroupwareSync::Cal ; 00717 if (conduits.findIndex( CSL1("todo-conduit") ) >= 0 ) 00718 _kroupwareParts |= KroupwareSync::Todo ; 00719 if (conduits.findIndex( CSL1("knotes-conduit") ) >= 0 ) 00720 _kroupwareParts |= KroupwareSync::Notes ; 00721 if (conduits.findIndex( CSL1("abbrowser_conduit") ) >= 0 ) 00722 _kroupwareParts |= KroupwareSync::Address ; 00723 } 00724 00725 if (_syncWithKMail) 00726 { 00727 fSyncStack->addAction(new KroupwareSync(true /* pre-sync */, 00728 _kroupwareParts,fPilotLink)); 00729 } 00730 #endif 00731 00732 switch (fNextSyncType) 00733 { 00734 case PilotDaemonDCOP::Test: 00735 fSyncStack->addAction(new TestLink(fPilotLink)); 00736 // No conduits, nothing. 00737 break; 00738 case PilotDaemonDCOP::Backup: 00739 mode |= ActionQueue::BackupMode | ActionQueue::FlagFull; 00740 if (conduits.count() > 0) 00741 { 00742 fSyncStack->queueConduits(&KPilotConfig::getConfig(), 00743 conduits, mode); 00744 } 00745 fSyncStack->addAction(new BackupAction(fPilotLink, mode)); 00746 break; 00747 case PilotDaemonDCOP::Restore: 00748 mode |= ActionQueue::RestoreMode | ActionQueue::FlagFull; 00749 fSyncStack->addAction(new RestoreAction(fPilotLink)); 00750 if (mode & ActionQueue::WithInstaller) 00751 { 00752 fSyncStack->queueInstaller(fInstaller->dir(), 00753 fInstaller->fileNames()); 00754 } 00755 break; 00756 case PilotDaemonDCOP::HotSync: 00757 // first install the files, and only then do the conduits 00758 // (conduits might want to sync a database that will be installed 00759 mode |= ActionQueue::HotSyncMode; 00760 if (mode & ActionQueue::WithInstaller) 00761 { 00762 fSyncStack->queueInstaller(fInstaller->dir(), 00763 fInstaller->fileNames()); 00764 } 00765 switch (c.getSyncType()) 00766 { 00767 case SyncAction::eFastSync: 00768 break; 00769 case SyncAction::eHotSync: 00770 mode |= ActionQueue::WithBackup; 00771 break; 00772 case SyncAction::eFullSync: 00773 mode |= ActionQueue::WithBackup | ActionQueue::FlagFull; 00774 break; 00775 case SyncAction::eCopyPCToHH: 00776 mode |= ActionQueue::FlagPCToHH; 00777 break; 00778 case SyncAction::eCopyHHToPC: 00779 mode |= ActionQueue::FlagHHToPC; 00780 break; 00781 } 00782 if (c.getInternalEditors() && !(mode & ActionQueue::FlagHHToPC) ) 00783 { 00784 fSyncStack->addAction(new InternalEditorAction(fPilotLink, mode)); 00785 } 00786 // Now check for changed PC 00787 { 00788 KPilotUser *usr = fPilotLink->getPilotUser(); 00789 // changing the PC or using a different Palm Desktop app causes a full sync 00790 // Use gethostid for this, since JPilot uses 1+(2000000000.0*random()/(RAND_MAX+1.0)) 00791 // as PC_ID, so using JPilot and KPilot is the same as using two differenc PCs 00792 pcchanged = usr->getLastSyncPC() !=(unsigned long) gethostid(); 00793 } 00794 00795 if (conduits.count() > 0) 00796 { 00797 fSyncStack->queueConduits(&KPilotConfig::getConfig(), 00798 conduits, pcchanged?(mode|ActionQueue::FlagFull):mode); 00799 } 00800 if (pcchanged && c.getFullSyncOnPCChange()) 00801 mode |= (ActionQueue::WithBackup | ActionQueue::FlagFull); 00802 #ifdef DEBUG 00803 DEBUGDAEMON << fname 00804 << ": Sync Mode=" 00805 << mode << ", Sync Type="<<c.getSyncType()<<endl; 00806 #endif 00807 if (mode & ActionQueue::WithBackup) 00808 fSyncStack->addAction(new BackupAction(fPilotLink, mode)); 00809 break; 00810 default: 00811 #ifdef DEBUG 00812 DEBUGDAEMON << fname 00813 << ": Can't handle sync type " 00814 << syncTypeString(fNextSyncType) << endl; 00815 #endif 00816 break; 00817 } 00818 00819 #ifdef ENABLE_KROUPWARE 00820 if (_syncWithKMail) 00821 { 00822 fSyncStack->addAction(new KroupwareSync(false /* post-sync */ , 00823 _kroupwareParts,fPilotLink)); 00824 } 00825 #endif 00826 00827 // Jump here to finalize the connections to the sync action 00828 // queue and start the actual sync. 00829 launch: 00830 fSyncStack->queueCleanup(); 00831 00832 QObject::connect(fSyncStack, SIGNAL(logError(const QString &)), 00833 this, SLOT(logError(const QString &))); 00834 QObject::connect(fSyncStack, SIGNAL(logMessage(const QString &)), 00835 this, SLOT(logMessage(const QString &))); 00836 QObject::connect(fSyncStack, 00837 SIGNAL(logProgress(const QString &,int)), 00838 this, SLOT(logProgress(const QString &,int))); 00839 00840 QObject::connect(fSyncStack, SIGNAL(syncDone(SyncAction *)), 00841 this, SLOT(endHotSync())); 00842 00843 QTimer::singleShot(0,fSyncStack,SLOT(execConduit())); 00844 00845 updateTrayStatus(); 00846 } 00847 00848 /* slot */ void PilotDaemon::logMessage(const QString & s) 00849 { 00850 FUNCTIONSETUPL(2); 00851 00852 getLogger().logMessage(s); 00853 updateTrayStatus(s); 00854 } 00855 00856 /* slot */ void PilotDaemon::logError(const QString & s) 00857 { 00858 FUNCTIONSETUP; 00859 00860 getLogger().logError(s); 00861 updateTrayStatus(s); 00862 } 00863 00864 /* slot */ void PilotDaemon::logProgress(const QString & s, int i) 00865 { 00866 FUNCTIONSETUPL(2); 00867 00868 getLogger().logProgress(s, i); 00869 if (!s.isEmpty()) updateTrayStatus(s); 00870 } 00871 00872 /* slot */ void PilotDaemon::endHotSync() 00873 { 00874 FUNCTIONSETUP; 00875 00876 if (fTray) 00877 { 00878 QTimer::singleShot(2000,fTray,SLOT(slotShowNormal())); 00879 } 00880 00881 KPILOT_DELETE(fSyncStack); 00882 fPilotLink->close(); 00883 00884 getLogger().logProgress(i18n("HotSync Completed.<br>"), 100); 00885 getKPilot().daemonStatus(KPilotDCOP::EndOfHotSync); 00886 00887 fStatus = HOTSYNC_END; 00888 00889 if (fPostSyncAction & Quit) 00890 { 00891 getKPilot().daemonStatus(KPilotDCOP::DaemonQuit); 00892 kapp->quit(); 00893 } 00894 if (fPostSyncAction & ReloadSettings) 00895 { 00896 reloadSettings(); 00897 } 00898 else 00899 { 00900 QTimer::singleShot(2000,fPilotLink,SLOT(reset())); 00901 } 00902 00903 fPostSyncAction = None; 00904 00905 updateTrayStatus(); 00906 } 00907 00908 00909 void PilotDaemon::slotFilesChanged() 00910 { 00911 FUNCTIONSETUP; 00912 } 00913 00914 void PilotDaemon::slotRunKPilot() 00915 { 00916 FUNCTIONSETUP; 00917 00918 QString kpilotError; 00919 QCString kpilotDCOP; 00920 int kpilotPID; 00921 00922 if (KApplication::startServiceByDesktopName(CSL1("kpilot"), 00923 QString::null, &kpilotError, &kpilotDCOP, &kpilotPID 00924 #if (KDE_VERSION >= 220) 00925 // Startup notification added in 2.2 00926 , "" 00927 #endif 00928 )) 00929 { 00930 kdWarning() << k_funcinfo 00931 << ": Couldn't start KPilot! " << kpilotError << endl; 00932 } 00933 else 00934 { 00935 #ifdef DEBUG 00936 DEBUGDAEMON << fname 00937 << ": Started KPilot with DCOP name " 00938 << kpilotDCOP << " (pid " << kpilotPID << ")" << endl; 00939 #endif 00940 } 00941 } 00942 00943 void PilotDaemon::slotRunConduitConfig() 00944 { 00945 FUNCTIONSETUP; 00946 00947 // This function tries to send the raise() DCOP call to kpilot. 00948 // If it succeeds, we can assume kpilot is running and then try 00949 // to send the configureConduits() DCOP call. 00950 // If it fails (probably because kpilot isn't running) it tries 00951 // to call kpilot via KProcess (using a command line switch to 00952 // only bring up the configure conduits dialog). 00953 // 00954 // Implementing the function this way catches all cases. 00955 // ie 1 KPilot running with configure conduit dialog open (raise()) 00956 // 2 KPilot running with dialog NOT open (configureConduits()) 00957 // 3 KPilot NOT running (KProcess) 00958 00959 DCOPClient *client = kapp->dcopClient(); 00960 00961 // This DCOP call to kpilot's raise function solves the final case 00962 // ie when kpilot already has the dialog open 00963 00964 if (client->send("kpilot", "kpilot-mainwindow#1", "raise()", 00965 QString::null)) 00966 { 00967 client->send("kpilot", "KPilotIface", "configureConduits()", 00968 QString::null); 00969 } 00970 else 00971 { 00972 KProcess *p = new KProcess; 00973 *p << "kpilot" << "-c"; 00974 00975 p->start(); 00976 } 00977 } 00978 00979 void PilotDaemon::updateTrayStatus(const QString &s) 00980 { 00981 if (!fTray) return; 00982 00983 QToolTip::remove(fTray); 00984 QToolTip::add(fTray, 00985 i18n("<qt>%1<br/>%2</qt>") 00986 .arg(statusString()) 00987 .arg(s) 00988 ); 00989 } 00990 00991 static KCmdLineOptions daemonoptions[] = { 00992 { "dummy", I18N_NOOP("Dummy command line argument."), 0}, 00993 #ifdef DEBUG 00994 {"debug <level>", I18N_NOOP("Set debugging level"), "0"}, 00995 #endif 00996 KCmdLineLastOption 00997 } ; 00998 00999 01000 int main(int argc, char **argv) 01001 { 01002 FUNCTIONSETUP; 01003 01004 KAboutData about("kpilotDaemon", 01005 I18N_NOOP("KPilot Daemon"), 01006 KPILOT_VERSION, 01007 "KPilot - HotSync software for KDE\n\n", 01008 KAboutData::License_GPL, "(c) 1998-2001, Dan Pilone"); 01009 about.addAuthor("Dan Pilone", 01010 I18N_NOOP("Project Leader"), 01011 "pilone@slac.com", "http://www.slac.com/pilone/kpilot_home/"); 01012 about.addAuthor("Adriaan de Groot", 01013 I18N_NOOP("Maintainer"), 01014 "groot@kde.org", "http://www.cs.kun.nl/~adridg/kpilot/"); 01015 01016 KCmdLineArgs::init(argc, argv, &about); 01017 KCmdLineArgs::addCmdLineOptions(daemonoptions,"kpilotconfig"); 01018 KUniqueApplication::addCmdLineOptions(); 01019 KCmdLineArgs *p = KCmdLineArgs::parsedArgs(); 01020 01021 #ifdef DEBUG 01022 KPilotConfig::getDebugLevel(p); 01023 #endif 01024 01025 if (!KUniqueApplication::start()) 01026 { 01027 return 0; 01028 } 01029 KUniqueApplication a(true, true); 01030 01031 // A block just to keep variables local. 01032 // 01033 // 01034 { 01035 KPilotConfigSettings & c = KPilotConfig::getConfig(); 01036 c.setReadOnly(false); 01037 01038 if (c.getVersion() < KPilotConfig::ConfigurationVersion) 01039 { 01040 kdError() << k_funcinfo 01041 << ": Is still not configured for use." 01042 << endl; 01043 KPilotConfig::sorryVersionOutdated(c.getVersion()); 01044 return 1; 01045 } 01046 01047 #ifdef DEBUG 01048 DEBUGDAEMON << fname 01049 << ": Configuration version " 01050 << c.getVersion() << endl; 01051 #endif 01052 } 01053 01054 01055 PilotDaemon *gPilotDaemon = new PilotDaemon(); 01056 01057 if (gPilotDaemon->status() == PilotDaemon::ERROR) 01058 { 01059 delete gPilotDaemon; 01060 01061 gPilotDaemon = 0; 01062 kdError() << k_funcinfo 01063 << ": **\n" 01064 ": Failed to start up daemon\n" 01065 ": due to errors constructing it.\n" ": **" << endl; 01066 return 2; 01067 } 01068 01069 gPilotDaemon->showTray(); 01070 01071 return a.exec(); 01072 01073 /* NOTREACHED */ 01074 (void) pilotdaemon_id; 01075 } 01076 01077 01078
KDE Logo
This file is part of the documentation for kpilot Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Jul 28 23:57:49 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003