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