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 #include "options.h"
00031
00032 #include <unistd.h>
00033
00034 #include <qtimer.h>
00035 #include <qfile.h>
00036 #include <qdir.h>
00037
00038 #include <kservice.h>
00039 #include <kservicetype.h>
00040 #include <kuserprofile.h>
00041 #include <klibloader.h>
00042 #include <ksavefile.h>
00043
00044 #include "pilotUser.h"
00045 #include "hotSync.h"
00046 #include "interactiveSync.h"
00047 #include "fileInstaller.h"
00048 #include "kpilotSettings.h"
00049 #include "pilotRecord.h"
00050
00051 #include "syncStack.moc"
00052
00053
00054
00055 WelcomeAction::WelcomeAction(KPilotLink *p) :
00056 SyncAction(p,"welcomeAction")
00057 {
00058 FUNCTIONSETUP;
00059 }
00060
00061 bool WelcomeAction::exec()
00062 {
00063 FUNCTIONSETUP;
00064
00065 addSyncLogEntry(i18n("KPilot %1 HotSync starting...\n")
00066 .arg(QString::fromLatin1(KPILOT_VERSION)));
00067 emit logMessage( i18n("Using encoding %1 on the handheld.").arg(Pilot::codecName()) );
00068 emit syncDone(this);
00069 return true;
00070 }
00071
00072 SorryAction::SorryAction(KPilotLink *p, const QString &s) :
00073 SyncAction(p,"sorryAction"),
00074 fMessage(s)
00075 {
00076 if (fMessage.isEmpty())
00077 {
00078 fMessage = i18n("KPilot is busy and cannot process the "
00079 "HotSync right now.");
00080 }
00081 }
00082
00083 bool SorryAction::exec()
00084 {
00085 FUNCTIONSETUP;
00086
00087 addSyncLogEntry(fMessage);
00088 return delayDone();
00089 }
00090
00091 LocalBackupAction::LocalBackupAction(KPilotLink *p, const QString &d) :
00092 SyncAction(p,"LocalBackupAction"),
00093 fDir(d)
00094 {
00095 }
00096
00097 bool LocalBackupAction::exec()
00098 {
00099 FUNCTIONSETUP;
00100
00101 startTickle();
00102
00103 QString dirname = fDir +
00104 Pilot::fromPilot(fHandle->getPilotUser().getUserName()) +
00105 CSL1("/");
00106 QDir dir(dirname,QString::null,QDir::Unsorted,QDir::Files);
00107
00108 if (!dir.exists())
00109 {
00110 emit logMessage( i18n("Cannot create local backup.") );
00111 return false;
00112 }
00113
00114 logMessage( i18n("Creating local backup of databases in %1.").arg(dirname) );
00115 addSyncLogEntry( i18n("Creating local backup ..") );
00116 qApp->processEvents();
00117
00118 QStringList files = dir.entryList();
00119
00120 for (QStringList::Iterator i = files.begin() ;
00121 i != files.end();
00122 ++i)
00123 {
00124 KSaveFile::backupFile(dirname + (*i));
00125 }
00126
00127 stopTickle();
00128
00129 return delayDone();
00130 }
00131
00132
00133 ConduitProxy::ConduitProxy(KPilotLink *p,
00134 const QString &name,
00135 const SyncAction::SyncMode &m) :
00136 ConduitAction(p,name.latin1(),m.list()),
00137 fDesktopName(name)
00138 {
00139 FUNCTIONSETUP;
00140 }
00141
00142 bool ConduitProxy::exec()
00143 {
00144 FUNCTIONSETUP;
00145
00146
00147 KSharedPtr < KService > o = KService::serviceByDesktopName(fDesktopName);
00148 if (!o)
00149 {
00150 kdWarning() << k_funcinfo
00151 << ": Can't find desktop file for conduit "
00152 << fDesktopName
00153 << endl;
00154 addSyncLogEntry(i18n("Could not find conduit %1.").arg(fDesktopName));
00155 emit syncDone(this);
00156 return true;
00157 }
00158
00159
00160
00161 fLibraryName = o->library();
00162 #ifdef DEBUG
00163 DEBUGKPILOT << fname
00164 << ": Loading desktop "
00165 << fDesktopName
00166 << " with lib "
00167 << fLibraryName
00168 << endl;
00169 #endif
00170
00171 KLibrary *library = KLibLoader::self()->library(
00172 QFile::encodeName(fLibraryName));
00173 if (!library)
00174 {
00175 kdWarning() << k_funcinfo
00176 << ": Can't load library "
00177 << fLibraryName
00178 << " - "
00179 << KLibLoader::self()->lastErrorMessage()
00180 << endl;
00181 addSyncLogEntry(i18n("Could not load conduit %1.").arg(fDesktopName));
00182 emit syncDone(this);
00183 return true;
00184 }
00185
00186 unsigned long version = PluginUtility::pluginVersion(library);
00187 if ( Pilot::PLUGIN_API != version )
00188 {
00189 kdWarning() << k_funcinfo
00190 << ": Library "
00191 << fLibraryName
00192 << " has version "
00193 << version
00194 << endl;
00195 addSyncLogEntry(i18n("Conduit %1 has wrong version (%2).").arg(fDesktopName).arg(version));
00196 emit syncDone(this);
00197 return true;
00198 }
00199
00200 KLibFactory *factory = library->factory();
00201 if (!factory)
00202 {
00203 kdWarning() << k_funcinfo
00204 << ": Can't find factory in library "
00205 << fLibraryName
00206 << endl;
00207 addSyncLogEntry(i18n("Could not initialize conduit %1.").arg(fDesktopName));
00208 emit syncDone(this);
00209 return true;
00210 }
00211
00212 QStringList l = syncMode().list();
00213
00214 #ifdef DEBUG
00215 DEBUGKPILOT << fname << ": Flags: " << syncMode().name() << endl;
00216 #endif
00217
00218 QObject *object = factory->create(fHandle,name(),"SyncAction",l);
00219
00220 if (!object)
00221 {
00222 kdWarning() << k_funcinfo
00223 << ": Can't create SyncAction."
00224 << endl;
00225 addSyncLogEntry(i18n("Could not create conduit %1.").arg(fDesktopName));
00226 emit syncDone(this);
00227 return true;
00228 }
00229
00230 fConduit = dynamic_cast<ConduitAction *>(object);
00231
00232 if (!fConduit)
00233 {
00234 kdWarning() << k_funcinfo
00235 << ": Can't cast to ConduitAction."
00236 << endl;
00237 addSyncLogEntry(i18n("Could not create conduit %1.").arg(fDesktopName));
00238 emit syncDone(this);
00239 return true;
00240 }
00241
00242 addSyncLogEntry(i18n("[Conduit %1]").arg(fDesktopName));
00243
00244
00245 QObject::connect(fConduit,SIGNAL(syncDone(SyncAction *)),
00246 this,SLOT(execDone(SyncAction *)));
00247
00248 QObject::connect(fConduit,SIGNAL(logMessage(const QString &)),
00249 this,SIGNAL(logMessage(const QString &)));
00250 QObject::connect(fConduit,SIGNAL(logError(const QString &)),
00251 this,SIGNAL(logError(const QString &)));
00252 QObject::connect(fConduit,SIGNAL(logProgress(const QString &,int)),
00253 this,SIGNAL(logProgress(const QString &,int)));
00254
00255 QTimer::singleShot(0,fConduit,SLOT(execConduit()));
00256 return true;
00257 }
00258
00259 void ConduitProxy::execDone(SyncAction *p)
00260 {
00261 FUNCTIONSETUP;
00262
00263 if (p!=fConduit)
00264 {
00265 kdError() << k_funcinfo
00266 << ": Unknown conduit @"
00267 << (long) p
00268 << " finished."
00269 << endl;
00270 emit syncDone(this);
00271 return;
00272 }
00273
00274 delete p;
00275 addSyncLogEntry(CSL1("\n"),false);
00276 emit syncDone(this);
00277 }
00278
00279
00280 ActionQueue::ActionQueue(KPilotLink *d) :
00281 SyncAction(d,"ActionQueue"),
00282 fReady(false)
00283
00284 {
00285 FUNCTIONSETUP;
00286 }
00287
00288 ActionQueue::~ActionQueue()
00289 {
00290 FUNCTIONSETUP;
00291 }
00292
00293
00294 void ActionQueue::queueInit( ActionQueue::InitFlags checkUser)
00295 {
00296 FUNCTIONSETUP;
00297
00298 addAction(new WelcomeAction(fHandle));
00299
00300 if ( ActionQueue::queueCheckUser == checkUser)
00301 {
00302 addAction(new CheckUser(fHandle));
00303 }
00304 }
00305
00306 void ActionQueue::queueConduits(const QStringList &l,const SyncAction::SyncMode &m, bool )
00307 {
00308 FUNCTIONSETUP;
00309
00310
00311
00312
00313 for (QStringList::ConstIterator it = l.begin();
00314 it != l.end();
00315 ++it)
00316 {
00317 if ((*it).startsWith(CSL1("internal_")))
00318 {
00319 #ifdef DEBUG
00320 DEBUGKPILOT << fname <<
00321 ": Ignoring conduit " << *it << endl;
00322 #endif
00323 continue;
00324 }
00325
00326 #ifdef DEBUG
00327 DEBUGKPILOT << fname
00328 << ": Creating proxy with mode=" << m.name() << endl;
00329 #endif
00330 ConduitProxy *cp = new ConduitProxy(fHandle,*it,m);
00331 addAction(cp);
00332 }
00333 }
00334
00335 void ActionQueue::queueInstaller(const QString &dir)
00336 {
00337 addAction(new FileInstallAction(fHandle,dir));
00338 }
00339
00340 void ActionQueue::queueCleanup()
00341 {
00342 addAction(new CleanupAction(fHandle));
00343 }
00344
00345 bool ActionQueue::exec()
00346 {
00347 actionCompleted(0L);
00348 return true;
00349 }
00350
00351 void ActionQueue::actionCompleted(SyncAction *b)
00352 {
00353 FUNCTIONSETUP;
00354
00355 if (b)
00356 {
00357 #ifdef DEBUG
00358 DEBUGKPILOT << fname
00359 << ": Completed action "
00360 << b->name()
00361 << endl;
00362 #endif
00363 delete b;
00364 }
00365
00366 if (isEmpty())
00367 {
00368 delayDone();
00369 return;
00370 }
00371 if ( deviceLink() && (!deviceLink()->tickle()) )
00372 {
00373 emit logError(i18n("The connection to the handheld "
00374 "was lost. Synchronization cannot continue."));
00375 SyncAction *del = 0L;
00376 while ( (del = nextAction()) )
00377 {
00378 delete del;
00379 }
00380 delayDone();
00381 return;
00382 }
00383
00384 SyncAction *a = nextAction();
00385
00386 if (!a)
00387 {
00388 kdWarning() << k_funcinfo
00389 << ": NULL action on stack."
00390 << endl;
00391 return;
00392 }
00393
00394 #ifdef DEBUG
00395 DEBUGKPILOT << fname
00396 << ": Will run action "
00397 << a->name()
00398 << endl;
00399 #endif
00400
00401 QObject::connect(a, SIGNAL(logMessage(const QString &)),
00402 this, SIGNAL(logMessage(const QString &)));
00403 QObject::connect(a, SIGNAL(logError(const QString &)),
00404 this, SIGNAL(logMessage(const QString &)));
00405 QObject::connect(a, SIGNAL(logProgress(const QString &, int)),
00406 this, SIGNAL(logProgress(const QString &, int)));
00407 QObject::connect(a, SIGNAL(syncDone(SyncAction *)),
00408 this, SLOT(actionCompleted(SyncAction *)));
00409
00410 QTimer::singleShot(0,a,SLOT(execConduit()));
00411 }
00412