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