00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "options.h"
00033
00034 #include <stdlib.h>
00035
00036 #include <qtimer.h>
00037 #include <qtooltip.h>
00038 #include <qpixmap.h>
00039
00040 #include <kuniqueapplication.h>
00041 #include <kaboutapplication.h>
00042 #include <kcmdlineargs.h>
00043 #include <kwin.h>
00044 #include <kurl.h>
00045 #include <kpopupmenu.h>
00046 #include <kiconloader.h>
00047 #include <kdebug.h>
00048 #include <kprocess.h>
00049 #include <dcopclient.h>
00050 #include <kurldrag.h>
00051 #include <kservice.h>
00052 #include <kapplication.h>
00053 #include <khelpmenu.h>
00054
00055 #include "pilotRecord.h"
00056
00057 #include "fileInstaller.h"
00058 #include "pilotUser.h"
00059 #include "pilotDatabase.h"
00060 #include "kpilotlink.h"
00061 #include "kpilotdevicelink.h"
00062 #include "actionQueue.h"
00063 #include "actions.h"
00064
00065 #include "hotSync.h"
00066 #include "internalEditorAction.h"
00067 #include "logFile.h"
00068
00069 #include "kpilotConfig.h"
00070
00071
00072 #include "kpilotDCOP_stub.h"
00073 #include "kpilotDCOP.h"
00074 #include "loggerDCOP_stub.h"
00075
00076 #include "pilotDaemon.moc"
00077
00078 static KAboutData *aboutData = 0L;
00079
00080 PilotDaemonTray::PilotDaemonTray(PilotDaemon * p) :
00081 KSystemTray(0, "pilotDaemon"),
00082 fSyncTypeMenu(0L),
00083 daemon(p),
00084 kap(0L),
00085 fBlinkTimer(0L)
00086 {
00087 FUNCTIONSETUP;
00088 setupWidget();
00089 setAcceptDrops(true);
00090 }
00091
00092 void PilotDaemonTray::dragEnterEvent(QDragEnterEvent * e)
00093 {
00094 FUNCTIONSETUP;
00095 e->accept(KURLDrag::canDecode(e));
00096 }
00097
00098 void PilotDaemonTray::dropEvent(QDropEvent * e)
00099 {
00100 FUNCTIONSETUP;
00101
00102 KURL::List list;
00103
00104 KURLDrag::decode(e, list);
00105
00106 QStringList files;
00107 for(KURL::List::ConstIterator it = list.begin(); it != list.end(); ++it)
00108 {
00109 if ((*it).isLocalFile())
00110 files << (*it).path();
00111 }
00112
00113 daemon->addInstallFiles(files);
00114 }
00115
00116 void PilotDaemonTray::mousePressEvent(QMouseEvent * e)
00117 {
00118 FUNCTIONSETUP;
00119
00120 switch (e->button())
00121 {
00122 case RightButton:
00123 {
00124 KPopupMenu *menu = contextMenu();
00125 contextMenuAboutToShow(menu);
00126 menu->popup(e->globalPos());
00127 }
00128 break;
00129 case LeftButton:
00130 if (daemon) daemon->slotRunKPilot();
00131 break;
00132 default:
00133 KSystemTray::mousePressEvent(e);
00134 }
00135 }
00136
00137 void PilotDaemonTray::closeEvent(QCloseEvent *)
00138 {
00139 FUNCTIONSETUP;
00140 daemon->quitNow();
00141 }
00142
00143 void PilotDaemonTray::setupWidget()
00144 {
00145 FUNCTIONSETUP;
00146
00147 KGlobal::iconLoader()->addAppDir( CSL1("kpilot") );
00148 icons[Normal] = loadIcon( CSL1("kpilotDaemon") );
00149 icons[Busy] = loadIcon( CSL1("busysync") );
00150 icons[NotListening] = loadIcon( CSL1("nosync") );
00151
00152 slotShowNotListening();
00153 QTimer::singleShot(2000,this,SLOT(slotShowNormal()));
00154
00155 KPopupMenu *menu = contextMenu();
00156
00157 menuKPilotItem = menu->insertItem(i18n("Start &KPilot"), daemon,
00158 SLOT(slotRunKPilot()));
00159 menuConfigureConduitsItem = menu->insertItem(i18n("&Configure KPilot..."),
00160 daemon, SLOT(slotRunConfig()));
00161 menu->insertSeparator();
00162
00163 fSyncTypeMenu = new KPopupMenu(menu,"sync_type_menu");
00164 QString once = i18n("Appended to names of sync types to indicate the sync will happen just one time"," (once)");
00165 #define MI(a) fSyncTypeMenu->insertItem( \
00166 SyncAction::SyncMode::name(SyncAction::SyncMode::a) + once, \
00167 (int)(SyncAction::SyncMode::a));
00168 fSyncTypeMenu->insertItem(i18n("Default (%1)")
00169 .arg(SyncAction::SyncMode::name((SyncAction::SyncMode::Mode)KPilotSettings::syncType())),
00170 0);
00171 fSyncTypeMenu->insertSeparator();
00172
00173
00174 MI(eHotSync);
00175 MI(eFullSync);
00176 MI(eBackup);
00177 MI(eRestore);
00178 MI(eCopyHHToPC);
00179 MI(eCopyPCToHH);
00180
00181 fSyncTypeMenu->setCheckable(true);
00182 fSyncTypeMenu->setItemChecked(0,true);
00183 #undef MI
00184 connect(fSyncTypeMenu,SIGNAL(activated(int)),daemon,SLOT(requestSync(int)));
00185 menu->insertItem(i18n("Next &Sync"),fSyncTypeMenu);
00186
00187 KHelpMenu *help = new KHelpMenu(menu,aboutData);
00188 menu->insertItem(
00189 KGlobal::iconLoader()->loadIconSet(CSL1("help"),KIcon::Small,0,true),
00190 i18n("&Help"),help->menu(),false );
00191
00192
00193
00194 #ifdef DEBUG
00195 DEBUGKPILOT << fname << ": Finished getting icons" << endl;
00196 #endif
00197 }
00198
00199 void PilotDaemonTray::slotShowAbout()
00200 {
00201 FUNCTIONSETUP;
00202
00203 if (!kap)
00204 {
00205 kap = new KAboutApplication(0, "kpdab", false);
00206 }
00207
00208 kap->show();
00209 }
00210
00211
00212 void PilotDaemonTray::enableRunKPilot(bool b)
00213 {
00214 FUNCTIONSETUP;
00215 contextMenu()->setItemEnabled(menuKPilotItem, b);
00216 contextMenu()->setItemEnabled(menuConfigureConduitsItem, b);
00217 }
00218
00219
00220 void PilotDaemonTray::changeIcon(IconShape i)
00221 {
00222 FUNCTIONSETUP;
00223 if (icons[i].isNull())
00224 {
00225 WARNINGKPILOT << "Icon #"<<i<<" is NULL!" << endl;
00226 }
00227 setPixmap(icons[i]);
00228 fCurrentIcon = i;
00229 }
00230
00231 void PilotDaemonTray::slotShowNormal()
00232 {
00233 FUNCTIONSETUP;
00234 changeIcon(Normal);
00235 }
00236
00237 void PilotDaemonTray::slotShowBusy()
00238 {
00239 FUNCTIONSETUP;
00240 changeIcon(Busy);
00241 }
00242
00243 void PilotDaemonTray::slotShowNotListening()
00244 {
00245 FUNCTIONSETUP;
00246 changeIcon( NotListening );
00247 }
00248
00249 void PilotDaemonTray::slotBusyTimer()
00250 {
00251 if (fCurrentIcon == Busy) changeIcon(Normal);
00252 else if (fCurrentIcon == Normal) changeIcon(Busy);
00253 }
00254
00255 void PilotDaemonTray::startHotSync()
00256 {
00257 changeIcon(Busy);
00258 if (!fBlinkTimer)
00259 {
00260 fBlinkTimer = new QTimer(this,"blink timer");
00261 }
00262 if (fBlinkTimer)
00263 {
00264 connect(fBlinkTimer,SIGNAL(timeout()),
00265 this,SLOT(slotBusyTimer()));
00266 fBlinkTimer->start(750,false);
00267 }
00268 }
00269
00270 void PilotDaemonTray::endHotSync()
00271 {
00272 changeIcon(Normal);
00273 if (fBlinkTimer)
00274 {
00275 fBlinkTimer->stop();
00276 }
00277 }
00278
00279
00280 PilotDaemon::PilotDaemon() :
00281 DCOPObject("KPilotDaemonIface"),
00282 fDaemonStatus(INIT),
00283 fPostSyncAction(None),
00284 fPilotLink(0L),
00285 fNextSyncType(SyncAction::SyncMode::eHotSync,true),
00286 fSyncStack(0L),
00287 fTray(0L),
00288 fInstaller(0L),
00289 fLogFile(0L),
00290 fLogStub(new LoggerDCOP_stub("kpilot", "LogIface")),
00291 fLogFileStub(new LoggerDCOP_stub("kpilotDaemon", "LogIface")),
00292 fKPilotStub(new KPilotDCOP_stub("kpilot", "KPilotIface")),
00293 fTempDevice(QString::null)
00294 {
00295 FUNCTIONSETUP;
00296
00297 setupPilotLink();
00298 reloadSettings();
00299
00300 if (fDaemonStatus == ERROR)
00301 {
00302 WARNINGKPILOT << "Connecting to device failed." << endl;
00303 return;
00304 }
00305
00306 fInstaller = new FileInstaller;
00307 fLogFile = new LogFile;
00308 connect(fInstaller, SIGNAL(filesChanged()),
00309 this, SLOT(slotFilesChanged()));
00310
00311 fNextSyncType.setMode( KPilotSettings::syncType() );
00312
00313 #ifdef DEBUG
00314 DEBUGKPILOT << fname
00315 << ": The daemon is ready with status "
00316 << statusString() << " (" << (int) fDaemonStatus << ")" << endl;
00317 #endif
00318 }
00319
00320 PilotDaemon::~PilotDaemon()
00321 {
00322 FUNCTIONSETUP;
00323
00324 KPILOT_DELETE(fPilotLink);
00325 KPILOT_DELETE(fSyncStack);
00326 KPILOT_DELETE(fInstaller);
00327
00328 (void) PilotDatabase::instanceCount();
00329 }
00330
00331 void PilotDaemon::addInstallFiles(const QStringList &l)
00332 {
00333 FUNCTIONSETUP;
00334
00335 fInstaller->addFiles( l, fTray );
00336 }
00337
00338 int PilotDaemon::getPilotSpeed()
00339 {
00340 FUNCTIONSETUP;
00341
00342 int speed = KPilotSettings::pilotSpeed();
00343
00344
00345
00346
00347
00348
00349 const char *speedname = 0L;
00350
00351 switch (speed)
00352 {
00353 case 0:
00354 speedname = "PILOTRATE=9600";
00355 break;
00356 case 1:
00357 speedname = "PILOTRATE=19200";
00358 break;
00359 case 2:
00360 speedname = "PILOTRATE=38400";
00361 break;
00362 case 3:
00363 speedname = "PILOTRATE=57600";
00364 break;
00365 case 4:
00366 speedname = "PILOTRATE=115200";
00367 break;
00368 default:
00369 speedname = "PILOTRATE=9600";
00370 }
00371
00372 #ifdef DEBUG
00373 DEBUGKPILOT << fname
00374 << ": Speed set to "
00375 << speedname << " (" << speed << ")" << endl;
00376 #endif
00377
00378 putenv((char *) speedname);
00379
00380 return speed;
00381 }
00382
00383
00384 void PilotDaemon::showTray()
00385 {
00386 FUNCTIONSETUP;
00387
00388 if (!fTray)
00389 {
00390 #ifdef DEBUG
00391 DEBUGKPILOT << fname << ": No tray icon to display!" << endl;
00392 #endif
00393
00394 return;
00395 }
00396
00397
00398 KWin::setSystemTrayWindowFor(fTray->winId(), 0);
00399 fTray->setGeometry(-100, -100, 42, 42);
00400 fTray->show();
00401
00402 #ifdef DEBUG
00403 DEBUGKPILOT << fname << ": Tray icon displayed." << endl;
00404 #endif
00405
00406 updateTrayStatus();
00407 }
00408
00409 void PilotDaemon::setTempDevice(QString d)
00410 {
00411 if ( !d.isEmpty() ){
00412 fTempDevice = d;
00413 if (fPilotLink)
00414 fPilotLink->setTempDevice( fTempDevice );
00415 reloadSettings();
00416 }
00417 }
00418
00419 void PilotDaemon::reloadSettings()
00420 {
00421 FUNCTIONSETUP;
00422
00423 switch (fDaemonStatus)
00424 {
00425 case INIT:
00426 case HOTSYNC_END:
00427 case ERROR:
00428 case READY:
00429 case NOT_LISTENING:
00430
00431 break;
00432 case HOTSYNC_START:
00433 case FILE_INSTALL_REQ:
00434
00435 fPostSyncAction |= ReloadSettings;
00436 return;
00437 break;
00438 }
00439
00440
00441 delete KPilotSettings::self();
00442 KPilotSettings::self()->config()->reparseConfiguration();
00443 KPilotSettings::self()->readConfig();
00444 getPilotSpeed();
00445
00446 (void) Pilot::setupPilotCodec(KPilotSettings::encoding());
00447
00448 #ifdef DEBUG
00449 DEBUGKPILOT << fname
00450 << ": Got configuration "
00451 << KPilotSettings::pilotDevice()
00452 << endl;
00453 DEBUGKPILOT << fname
00454 << ": Got conduit list "
00455 << (KPilotSettings::installedConduits().join(CSL1(",")))
00456 << endl;
00457 #endif
00458
00459 requestSync(0);
00460
00461
00462 if (fPilotLink)
00463 {
00464 #ifdef DEBUG
00465 DEBUGKPILOT << fname
00466 << ": Resetting with device "
00467 << KPilotSettings::pilotDevice()
00468 << endl;
00469 #endif
00470
00471 fPilotLink->reset( KPilotSettings::pilotDevice() );
00472 #ifdef DEBUG
00473 DEBUGKPILOT << fname
00474 << ": Using workarounds "
00475 << KPilotSettings::workarounds()
00476 << endl;
00477 #endif
00478 if ( KPilotSettings::workarounds() == KPilotSettings::eWorkaroundUSB )
00479 {
00480 #ifdef DEBUG
00481 DEBUGKPILOT << fname
00482 << ": Using Zire31 USB workaround." << endl;
00483 #endif
00484 fPilotLink->setWorkarounds(true);
00485 }
00486 }
00487
00488 if (KPilotSettings::dockDaemon())
00489 {
00490 if (!fTray)
00491 {
00492 fTray = new PilotDaemonTray(this);
00493 fTray->show();
00494 }
00495 else
00496 {
00497 fTray->show();
00498 }
00499 }
00500 else
00501 {
00502 if (fTray)
00503 {
00504 fTray->hide();
00505 delete fTray;
00506
00507 fTray = 0L;
00508 }
00509 }
00510
00511 updateTrayStatus();
00512 logProgress(QString::null,0);
00513 }
00514
00515 void PilotDaemon::stopListening()
00516 {
00517 fIsListening=false;
00518 fTray->changeIcon(PilotDaemonTray::NotListening);
00519 fDaemonStatus=NOT_LISTENING;
00520 fPilotLink->close();
00521 }
00522
00523 void PilotDaemon::startListening()
00524 {
00525 fIsListening=true;
00526 fTray->changeIcon(PilotDaemonTray::Normal);
00527 fDaemonStatus=INIT;
00528 fPilotLink->reset();
00529 }
00530
00531 QString PilotDaemon::statusString()
00532 {
00533 FUNCTIONSETUP;
00534
00535 QString s = CSL1("PilotDaemon=");
00536 s.append(shortStatusString());
00537
00538 s.append(CSL1("; NextSync="));
00539 s.append(fNextSyncType.name());
00540
00541 s.append(CSL1(" ("));
00542 if (fPilotLink)
00543 {
00544 s.append(fPilotLink->statusString());
00545 }
00546 s.append(CSL1(");"));
00547
00548 return s;
00549 }
00550
00551 QString PilotDaemon::shortStatusString()
00552 {
00553 QString s;
00554
00555 switch (status())
00556 {
00557 case INIT:
00558 s.append(CSL1("Waiting for sync"));
00559 break;
00560 case READY:
00561 s.append(CSL1("Listening on device"));
00562 break;
00563 case ERROR:
00564 s=CSL1("Error");
00565 break;
00566 case FILE_INSTALL_REQ:
00567 s=CSL1("Installing File");
00568 break;
00569 case HOTSYNC_END:
00570 s=CSL1("End of Hotsync");
00571 break;
00572 case HOTSYNC_START:
00573 s=CSL1("Syncing");
00574 break;
00575 case NOT_LISTENING:
00576 s.append(CSL1("Not Listening (stopped manually)"));
00577 break;
00578 }
00579
00580 return s;
00581 }
00582
00583
00584
00585 bool PilotDaemon::setupPilotLink()
00586 {
00587 FUNCTIONSETUP;
00588
00589 KPILOT_DELETE(fPilotLink);
00590 fPilotLink = new KPilotDeviceLink( 0, 0, fTempDevice );
00591 if (!fPilotLink)
00592 {
00593 WARNINGKPILOT << "Can't get pilot link." << endl;
00594 return false;
00595 }
00596
00597 QObject::connect(fPilotLink, SIGNAL(deviceReady(KPilotLink*)),
00598 this, SLOT(startHotSync(KPilotLink*)));
00599
00600 QObject::connect(fPilotLink, SIGNAL(logError(const QString &)),
00601 this, SLOT(logError(const QString &)));
00602 QObject::connect(fPilotLink, SIGNAL(logMessage(const QString &)),
00603 this, SLOT(logMessage(const QString &)));
00604 QObject::connect(fPilotLink,
00605 SIGNAL(logProgress(const QString &,int)),
00606 this, SLOT(logProgress(const QString &,int)));
00607
00608
00609 return true;
00610 }
00611
00612
00613 void PilotDaemon::quitNow()
00614 {
00615 FUNCTIONSETUP;
00616
00617
00618
00619 switch (fDaemonStatus)
00620 {
00621 case INIT:
00622 case HOTSYNC_END:
00623 case ERROR:
00624 case NOT_LISTENING:
00625 getKPilot().daemonStatus(KPilotDCOP::DaemonQuit);
00626 kapp->quit();
00627 break;
00628 case READY:
00629 case HOTSYNC_START:
00630 case FILE_INSTALL_REQ:
00631 fPostSyncAction |= Quit;
00632 break;
00633 }
00634 emitDCOPSignal( "kpilotDaemonStatusChanged()", QByteArray() );
00635 }
00636
00637 void PilotDaemon::requestRegularSyncNext()
00638 {
00639 requestSync(SyncAction::SyncMode::eHotSync);
00640 }
00641
00642
00643 void PilotDaemon::requestSync(int mode)
00644 {
00645 FUNCTIONSETUP;
00646
00647 if ( 0==mode )
00648 {
00649 mode = KPilotSettings::syncType();
00650 }
00651
00652 if ( !fNextSyncType.setMode(mode) )
00653 {
00654 WARNINGKPILOT << "Ignored fake sync type " << mode << endl;
00655 return;
00656 }
00657
00658 updateTrayStatus();
00659
00660 if (fTray && (fTray->fSyncTypeMenu))
00661 {
00662 for (int i=((int)SyncAction::SyncMode::eHotSync);
00663 i<=((int)SyncAction::SyncMode::eRestore) ;
00664 ++i)
00665 {
00666 fTray->fSyncTypeMenu->setItemChecked(i,mode==i);
00667 }
00668 }
00669
00670 getLogger().logMessage(i18n("Next HotSync will be: %1. ").arg(fNextSyncType.name()) +
00671 i18n("Please press the HotSync button."));
00672 }
00673
00674 void PilotDaemon::requestSyncType(QString s)
00675 {
00676 FUNCTIONSETUP;
00677
00678
00679 if (s.startsWith(CSL1("H"))) requestSync(SyncAction::SyncMode::eHotSync);
00680 else if (s.startsWith(CSL1("Fu"))) requestSync(SyncAction::SyncMode::eFullSync);
00681 else if (s.startsWith(CSL1("B"))) requestSync(SyncAction::SyncMode::eBackup);
00682 else if (s.startsWith(CSL1("R"))) requestSync(SyncAction::SyncMode::eRestore);
00683 else if (s.startsWith(CSL1("T"))) { fNextSyncType.setOptions(true,false); }
00684 else if (s.startsWith(CSL1("CopyHHToPC"))) requestSync(SyncAction::SyncMode::eCopyHHToPC);
00685 else if (s.startsWith(CSL1("CopyPCToHH"))) requestSync(SyncAction::SyncMode::eCopyPCToHH);
00686 else if (s.startsWith(CSL1("D"))) requestSync(0);
00687 else
00688 {
00689 WARNINGKPILOT << "Unknown sync type " << ( s.isEmpty() ? CSL1("<none>") : s )
00690 << endl;
00691 }
00692 }
00693
00694 void PilotDaemon::requestSyncOptions(bool test, bool local)
00695 {
00696 if ( !fNextSyncType.setOptions(test,local) )
00697 {
00698 WARNINGKPILOT << "Nonsensical request for "
00699 << (test ? "test" : "notest")
00700 << ' '
00701 << (local ? "local" : "nolocal")
00702 << " in mode "
00703 << fNextSyncType.name() << endl;
00704 }
00705 }
00706
00707 int PilotDaemon::nextSyncType() const
00708 {
00709 return fNextSyncType.mode();
00710 }
00711
00715 QDateTime PilotDaemon::lastSyncDate()
00716 {
00717 return KPilotSettings::lastSyncTime();
00718 }
00719
00720
00721 static QDict<QString> *conduitNameMap = 0L;
00722
00723 static void fillConduitNameMap()
00724 {
00725 if ( !conduitNameMap )
00726 {
00727 conduitNameMap = new QDict<QString>;
00728 conduitNameMap->setAutoDelete(true);
00729 }
00730 conduitNameMap->clear();
00731
00732 QStringList l = KPilotSettings::installedConduits();
00733
00734 if ( l.find( CSL1("internal_fileinstall") ) != l.end() ) {
00735 conduitNameMap->insert( CSL1("internal_fileinstall"),
00736 new QString(i18n("File Installer")) );
00737 }
00738
00739 QStringList::ConstIterator end = l.end();
00740 for (QStringList::ConstIterator i = l.begin(); i != end; ++i)
00741 {
00742 if (!conduitNameMap->find(*i))
00743 {
00744 QString readableName = CSL1("<unknown>");
00745 KSharedPtr < KService > o = KService::serviceByDesktopName(*i);
00746 if (!o)
00747 {
00748 WARNINGKPILOT << "No service for " << *i << endl;
00749 }
00750 else
00751 {
00752 readableName = o->name();
00753 }
00754 conduitNameMap->insert( *i, new QString(readableName) );
00755 }
00756 }
00757 }
00758
00759
00760 QStringList PilotDaemon::configuredConduitList()
00761 {
00762 fillConduitNameMap();
00763
00764 QStringList keys;
00765
00766 QDictIterator<QString> it(*conduitNameMap);
00767 for ( ; *it; ++it)
00768 {
00769 keys << it.currentKey();
00770 }
00771 keys.sort();
00772
00773 QStringList::ConstIterator end = keys.end();
00774 QStringList result;
00775 for (QStringList::ConstIterator i = keys.begin(); i != end; ++i)
00776 {
00777 result << *(conduitNameMap->find(*i));
00778 }
00779
00780 return result;
00781 }
00782
00783 QString PilotDaemon::logFileName()
00784 {
00785 return KPilotSettings::logFileName();
00786 }
00787
00788 QString PilotDaemon::userName()
00789 {
00790 return KPilotSettings::userName();
00791 }
00792 QString PilotDaemon::pilotDevice()
00793 {
00794 return KPilotSettings::pilotDevice();
00795 }
00796
00797 bool PilotDaemon::killDaemonOnExit()
00798 {
00799 return KPilotSettings::killDaemonAtExit();
00800 }
00801
00802 typedef enum { NotLocked=0, Locked=1, DCOPError=2 } KDesktopLockStatus;
00803 static KDesktopLockStatus isKDesktopLockRunning()
00804 {
00805 if (!KPilotSettings::screenlockSecure()) return NotLocked;
00806
00807 DCOPClient *dcopptr = KApplication::kApplication()->dcopClient();
00808
00809
00810 if (!dcopptr || !dcopptr->isAttached())
00811 {
00812 WARNINGKPILOT << "Could not make DCOP connection. "
00813 << "Assuming screensaver is active." << endl;
00814 return DCOPError;
00815 }
00816
00817 QByteArray data,returnValue;
00818 QCString returnType;
00819
00820 if (!dcopptr->call("kdesktop","KScreensaverIface","isBlanked()",
00821 data,returnType,returnValue,true))
00822 {
00823 WARNINGKPILOT << "Check for screensaver failed."
00824 << "Assuming screensaver is active." << endl;
00825
00826 return DCOPError;
00827 }
00828
00829 if (returnType == "bool")
00830 {
00831 bool b;
00832 QDataStream reply(returnValue,IO_ReadOnly);
00833 reply >> b;
00834 return (b ? Locked : NotLocked);
00835 }
00836 else
00837 {
00838 WARNINGKPILOT << "Strange return value from screensaver. "
00839 << "Assuming screensaver is active." << endl;
00840
00841 return DCOPError;
00842 }
00843 }
00844
00845
00846 static void informOthers(KPilotDCOP_stub &kpilot,
00847 LoggerDCOP_stub &log,
00848 LoggerDCOP_stub &filelog)
00849 {
00850 kpilot.daemonStatus(KPilotDCOP::StartOfHotSync);
00851 log.logStartSync();
00852 filelog.logStartSync();
00853 }
00854
00855 static bool isSyncPossible(ActionQueue *fSyncStack,
00856 KPilotLink *pilotLink,
00857 KPilotDCOP_stub &kpilot)
00858 {
00859 FUNCTIONSETUP;
00860
00867 int kpilotstatus = kpilot.kpilotStatus();
00868 DCOPStub::Status callstatus = kpilot.status();
00869
00870 #ifdef DEBUG
00871 if (callstatus != DCOPStub::CallSucceeded)
00872 {
00873 DEBUGKPILOT << fname <<
00874 ": Could not call KPilot for status." << endl;
00875 }
00876 else
00877 {
00878 DEBUGKPILOT << fname << ": KPilot status " << kpilotstatus << endl;
00879 }
00880 #endif
00881
00885 if ((callstatus == DCOPStub::CallSucceeded) &&
00886 (kpilotstatus != KPilotDCOP::WaitingForDaemon))
00887 {
00888 WARNINGKPILOT << "KPilot returned status " << kpilotstatus << endl;
00889
00890 fSyncStack->queueInit();
00891 fSyncStack->addAction(new SorryAction(pilotLink));
00892 return false;
00893 }
00894
00895 switch (isKDesktopLockRunning())
00896 {
00897 case NotLocked :
00898 break;
00899 case Locked :
00900 fSyncStack->queueInit();
00901 fSyncStack->addAction(new SorryAction(pilotLink,
00902 i18n("HotSync is disabled while the screen is locked.")));
00903 return false;
00904 case DCOPError :
00905 fSyncStack->queueInit();
00906 fSyncStack->addAction(new SorryAction(pilotLink,
00907 i18n("HotSync is disabled because KPilot could not "
00908 "determine the state of the screen saver. You "
00909 "can disable this security feature by unchecking "
00910 "the 'do not sync when screensaver is active' box "
00911 "in the HotSync page of the configuration dialog.")));
00912 return false;
00913 }
00914
00915 return true;
00916 }
00917
00918 static void queueInstaller(ActionQueue *fSyncStack,
00919 KPilotLink *pilotLink,
00920 FileInstaller *fInstaller,
00921 const QStringList &c)
00922 {
00923 if (c.findIndex(CSL1("internal_fileinstall")) >= 0)
00924 {
00925 fSyncStack->addAction(new FileInstallAction(pilotLink,fInstaller->dir()));
00926 }
00927 }
00928
00929 static void queueEditors(ActionQueue *fSyncStack, KPilotLink *pilotLink)
00930 {
00931 if (KPilotSettings::internalEditors())
00932 {
00933 fSyncStack->addAction(new InternalEditorAction(pilotLink));
00934 }
00935 }
00936
00937 static void queueConduits(ActionQueue *fSyncStack,
00938 const QStringList &conduits,
00939 SyncAction::SyncMode e)
00940 {
00941 if (conduits.count() > 0)
00942 {
00943 fSyncStack->queueConduits(conduits,e);
00944
00945
00946
00947 }
00948 }
00949
00950 bool PilotDaemon::shouldBackup()
00951 {
00952
00953 FUNCTIONSETUP;
00954
00955 bool ret = false;
00956 int backupfreq = KPilotSettings::backupFrequency();
00957
00958 #ifdef DEBUG
00959 DEBUGKPILOT << fname << ": Backup Frequency is: [" << backupfreq <<
00960 "]. " << endl;
00961 #endif
00962
00963 if ( (fNextSyncType == SyncAction::SyncMode::eHotSync) ||
00964 (fNextSyncType == SyncAction::SyncMode::eFullSync) )
00965 {
00969 if ( backupfreq == SyncAction::eOnRequestOnly )
00970 {
00971 #ifdef DEBUG
00972 DEBUGKPILOT << fname << ": Should not do backup..." << endl;
00973 #endif
00974 ret = false;
00975 }
00976 else if ( backupfreq == SyncAction::eEveryHotSync )
00977 {
00978 #ifdef DEBUG
00979 DEBUGKPILOT << fname << ": Should do backup..." << endl;
00980 #endif
00981 ret = true;
00982 }
00983 }
00984
00985 return ret;
00986
00987 }
00988
00989
00990 void PilotDaemon::startHotSync(KPilotLink *pilotLink)
00991 {
00992 FUNCTIONSETUP;
00993
00994 bool pcchanged=false;
00995 QStringList conduits ;
00996 QString s;
00997
00998 #ifdef DEBUG
00999 DEBUGKPILOT << fname
01000 << ": Starting Sync with type "
01001 << fNextSyncType.name() << endl;
01002 DEBUGKPILOT << fname << ": Status is " << shortStatusString() << endl;
01003 (void) PilotDatabase::instanceCount();
01004 #endif
01005
01006 fDaemonStatus = HOTSYNC_START ;
01007 if (fTray)
01008 {
01009 fTray->startHotSync();
01010 }
01011 informOthers(getKPilot(),getLogger(),getFileLogger());
01012
01013
01014
01015 fSyncStack = new ActionQueue(pilotLink);
01016
01017
01018 if (!isSyncPossible(fSyncStack,pilotLink,getKPilot()))
01019 {
01020
01021
01022 goto launch;
01023 }
01024
01025
01026
01027
01028 if (fNextSyncType.mode() != SyncAction::SyncMode::eRestore)
01029 {
01030
01031 KPilotUser &usr = pilotLink->getPilotUser();
01032 pcchanged = usr.getLastSyncPC() !=(unsigned long) gethostid();
01033
01034 if (pcchanged)
01035 {
01036 #ifdef DEBUG
01037 DEBUGKPILOT << fname << ": PC changed. Last sync PC: [" << usr.getLastSyncPC()
01038 << "], me: [" << (unsigned long) gethostid() << "]" << endl;
01039 #endif
01040 if ( KPilotSettings::fullSyncOnPCChange() )
01041 {
01042 #ifdef DEBUG
01043 DEBUGKPILOT << fname << ": Setting sync mode to full sync. " << endl;
01044 #endif
01045 fNextSyncType = SyncAction::SyncMode::eFullSync;
01046 }
01047 else
01048 {
01049 #ifdef DEBUG
01050 DEBUGKPILOT << fname << ": Not changing sync mode because of settings. " << endl;
01051 #endif
01052 }
01053 }
01054 }
01055
01056
01057 fSyncStack->queueInit();
01058 fSyncStack->addAction(new CheckUser(pilotLink));
01059
01060 conduits = KPilotSettings::installedConduits() ;
01061
01062 if (fNextSyncType.isTest())
01063 {
01064 fSyncStack->addAction(new TestLink(pilotLink));
01065 }
01066 else
01067 {
01068 switch (fNextSyncType.mode())
01069 {
01070 case SyncAction::SyncMode::eBackup:
01071 if (KPilotSettings::runConduitsWithBackup() && (conduits.count() > 0))
01072 {
01073 queueConduits(fSyncStack,conduits,fNextSyncType);
01074 }
01075 fSyncStack->addAction(new BackupAction(pilotLink,true));
01076 break;
01077 case SyncAction::SyncMode::eRestore:
01078 fSyncStack->addAction(new RestoreAction(pilotLink));
01079 queueInstaller(fSyncStack,pilotLink,fInstaller,conduits);
01080 break;
01081 case SyncAction::SyncMode::eFullSync:
01082 case SyncAction::SyncMode::eHotSync:
01083
01084
01085 queueInstaller(fSyncStack,pilotLink,fInstaller,conduits);
01086 queueEditors(fSyncStack,pilotLink);
01087 queueConduits(fSyncStack,conduits,fNextSyncType);
01088
01089 queueInstaller(fSyncStack,pilotLink,fInstaller,conduits);
01090
01091 if (shouldBackup())
01092 {
01093 fSyncStack->addAction(new BackupAction(pilotLink, (fNextSyncType == SyncAction::SyncMode::eFullSync)));
01094 }
01095 break;
01096 case SyncAction::SyncMode::eCopyPCToHH:
01097 queueConduits(fSyncStack,conduits,SyncAction::SyncMode::eCopyPCToHH);
01098 break;
01099 case SyncAction::SyncMode::eCopyHHToPC:
01100 queueConduits(fSyncStack,conduits,SyncAction::SyncMode::eCopyHHToPC);
01101 break;
01102 }
01103 }
01104
01105
01106
01107 launch:
01108 fSyncStack->queueCleanup();
01109
01110 QObject::connect(fSyncStack, SIGNAL(logError(const QString &)),
01111 this, SLOT(logError(const QString &)));
01112 QObject::connect(fSyncStack, SIGNAL(logMessage(const QString &)),
01113 this, SLOT(logMessage(const QString &)));
01114 QObject::connect(fSyncStack,
01115 SIGNAL(logProgress(const QString &,int)),
01116 this, SLOT(logProgress(const QString &,int)));
01117
01118 QObject::connect(fSyncStack, SIGNAL(syncDone(SyncAction *)),
01119 this, SLOT(endHotSync()));
01120
01121 QTimer::singleShot(0,fSyncStack,SLOT(execConduit()));
01122
01123 updateTrayStatus();
01124 }
01125
01126 void PilotDaemon::logMessage(const QString & s)
01127 {
01128 FUNCTIONSETUPL(2);
01129
01130 getLogger().logMessage(s);
01131 getFileLogger().logMessage(s);
01132 updateTrayStatus(s);
01133 }
01134
01135 void PilotDaemon::logError(const QString & s)
01136 {
01137 FUNCTIONSETUP;
01138
01139 getLogger().logError(s);
01140 getFileLogger().logError(s);
01141 updateTrayStatus(s);
01142 }
01143
01144 void PilotDaemon::logProgress(const QString & s, int i)
01145 {
01146 FUNCTIONSETUPL(2);
01147
01148 getLogger().logProgress(s, i);
01149 getFileLogger().logProgress(s, i);
01150 if (!s.isEmpty()) updateTrayStatus(s);
01151 }
01152
01153 void PilotDaemon::endHotSync()
01154 {
01155 FUNCTIONSETUP;
01156
01157 if (fTray)
01158 {
01159 fTray->endHotSync();
01160 }
01161
01162 KPILOT_DELETE(fSyncStack);
01163 fPilotLink->close();
01164
01165 getLogger().logProgress(i18n("HotSync Completed.<br>"), 100);
01166 getFileLogger().logProgress(i18n("HotSync Completed.<br>"), 100);
01167 getLogger().logEndSync();
01168 getFileLogger().logEndSync();
01169 getKPilot().daemonStatus(KPilotDCOP::EndOfHotSync);
01170 KPilotSettings::setLastSyncTime(QDateTime::currentDateTime());
01171 KPilotSettings::self()->writeConfig();
01172
01173 fDaemonStatus = HOTSYNC_END;
01174
01175 if (fPostSyncAction & Quit)
01176 {
01177 getKPilot().daemonStatus(KPilotDCOP::DaemonQuit);
01178 kapp->quit();
01179 }
01180 if (fPostSyncAction & ReloadSettings)
01181 {
01182 reloadSettings();
01183 }
01184 else
01185 {
01186 QTimer::singleShot(10000,fPilotLink,SLOT(reset()));
01187 }
01188
01189 fPostSyncAction = None;
01190 requestSync(0);
01191
01192 (void) PilotDatabase::instanceCount();
01193
01194 updateTrayStatus();
01195 }
01196
01197
01198 void PilotDaemon::slotFilesChanged()
01199 {
01200 FUNCTIONSETUP;
01201 }
01202
01203 void PilotDaemon::slotRunKPilot()
01204 {
01205 FUNCTIONSETUP;
01206
01207 QString kpilotError;
01208 QCString kpilotDCOP;
01209 int kpilotPID;
01210
01211 if (KApplication::startServiceByDesktopName(CSL1("kpilot"),
01212 QString::null, &kpilotError, &kpilotDCOP, &kpilotPID
01213 #if (KDE_VERSION >= 220)
01214
01215 , ""
01216 #endif
01217 ))
01218 {
01219 WARNINGKPILOT << "Couldn't start KPilot! " << kpilotError << endl;
01220 }
01221 else
01222 {
01223 #ifdef DEBUG
01224 DEBUGKPILOT << fname
01225 << ": Started KPilot with DCOP name "
01226 << kpilotDCOP << " (pid " << kpilotPID << ")" << endl;
01227 #endif
01228 }
01229 }
01230
01231 void PilotDaemon::slotRunConfig()
01232 {
01233 FUNCTIONSETUP;
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247 DCOPClient *client = kapp->dcopClient();
01248
01249
01250
01251
01252 if ( client->isApplicationRegistered( "kpilot" ) )
01253 {
01254 client->send("kpilot", "kpilot-mainwindow#1", "raise()",QString::null);
01255 client->send("kpilot", "KPilotIface", "configure()", QString::null);
01256 }
01257 else
01258 {
01259
01260 KProcess *p = new KProcess;
01261 *p << "kpilot" << "-s";
01262
01263 p->start();
01264 }
01265 }
01266
01267 void PilotDaemon::updateTrayStatus(const QString &s)
01268 {
01269 if (!fTray) return;
01270
01271 QString tipText = CSL1("<qt>");
01272 tipText.append( s );
01273 tipText.append( CSL1(" ") );
01274 tipText.append( i18n("Next sync is %1.")
01275 .arg( fNextSyncType.name() ) );
01276 tipText.append( CSL1("</qt>") );
01277
01278 QToolTip::remove(fTray);
01279 QToolTip::add(fTray,tipText);
01280 emitDCOPSignal( "kpilotDaemonStatusChanged()", QByteArray() );
01281
01282 QByteArray data;
01283 QDataStream arg(data, IO_WriteOnly);
01284 arg << lastSyncDate();
01285 arg << shortStatusString();
01286 arg << configuredConduitList();
01287 arg << logFileName();
01288 arg << userName();
01289 arg << pilotDevice();
01290 arg << killDaemonOnExit();
01291 emitDCOPSignal( "kpilotDaemonStatusDetails(QDateTime,QString,QStringList,QString,QString,QString,bool)", data );
01292 }
01293
01294 static KCmdLineOptions daemonoptions[] = {
01295 #ifdef DEBUG
01296 {"debug <level>", I18N_NOOP("Set debugging level"), "0"},
01297 #endif
01298 { "device <device>", I18N_NOOP("Device to try first"), ""},
01299 {"fail-silently", I18N_NOOP("Exit instead of complaining about bad configuration files"), 0},
01300 KCmdLineLastOption
01301 } ;
01302
01303
01304 int main(int argc, char **argv)
01305 {
01306 FUNCTIONSETUP;
01307
01308 KLocale::setMainCatalogue("kpilot");
01309
01310 KAboutData about("kpilotDaemon",
01311 I18N_NOOP("KPilot Daemon"),
01312 KPILOT_VERSION,
01313 "KPilot - HotSync software for KDE\n\n",
01314 KAboutData::License_GPL,
01315 "(c) 1998-2000,2001, Dan Pilone (c) 2000-2004, Adriaan de Groot",
01316 0L,
01317 "http://www.kpilot.org/"
01318 );
01319 about.addAuthor("Dan Pilone",
01320 I18N_NOOP("Project Leader"),
01321 "pilone@slac.com");
01322 about.addAuthor("Adriaan de Groot",
01323 I18N_NOOP("Maintainer"),
01324 "groot@kde.org", "http://www.kpilot.org/");
01325 about.addAuthor("Reinhold Kainhofer",
01326 I18N_NOOP("Developer"),
01327 "reinhold@kainhofer.com", "http://reinhold.kainhofer.com/Linux/");
01328 aboutData = &about;
01329
01330
01331 KCmdLineArgs::init(argc, argv, &about);
01332 KCmdLineArgs::addCmdLineOptions(daemonoptions,"kpilotconfig");
01333 KUniqueApplication::addCmdLineOptions();
01334 KCmdLineArgs *p = KCmdLineArgs::parsedArgs();
01335
01336 #ifdef DEBUG
01337 KPilotConfig::getDebugLevel(p);
01338 #endif
01339 if (!KUniqueApplication::start())
01340 {
01341 if (p->isSet("device")){
01342
01343
01344 DCOPClient d;
01345 QString dev(p->getOption("device"));
01346 QByteArray data;
01347 QDataStream arg(data, IO_WriteOnly);
01348 arg << dev;
01349 if (d.attach()){
01350 d.send("kpilotDaemon", "KPilotDaemonIface", "setTempDevice(QString)", data );
01351 d.detach();
01352 }
01353 }
01354 return 0;
01355 }
01356 KUniqueApplication a(true, true);
01357
01358
01359
01360
01361 {
01362
01363
01364 if (KPilotSettings::configVersion() < KPilotConfig::ConfigurationVersion)
01365 {
01366 WARNINGKPILOT << "Is still not configured for use."
01367 << endl;
01368 if (!p->isSet("fail-silently"))
01369 {
01370 KPilotConfig::sorryVersionOutdated(KPilotSettings::configVersion());
01371 }
01372 return 1;
01373 }
01374
01375 #ifdef DEBUG
01376 DEBUGKPILOT << fname
01377 << ": Configuration version "
01378 << KPilotSettings::configVersion() << endl;
01379 #endif
01380 }
01381
01382
01383 PilotDaemon *gPilotDaemon = new PilotDaemon();
01384
01385 if (p->isSet("device"))
01386 gPilotDaemon->setTempDevice(p->getOption("device"));
01387
01388 if (gPilotDaemon->status() == PilotDaemon::ERROR)
01389 {
01390 delete gPilotDaemon;
01391
01392 gPilotDaemon = 0;
01393 WARNINGKPILOT << "Failed to start up daemon "
01394 "due to errors constructing it." << endl;
01395 return 2;
01396 }
01397
01398 gPilotDaemon->showTray();
01399
01400 return a.exec();
01401 }
01402
01403
01404