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 static const char *interactivesync_id =
00032 "$Id: interactiveSync.cc 437980 2005-07-23 19:53:57Z kainhofe $";
00033
00034 #include "options.h"
00035
00036 #include <time.h>
00037 #include <unistd.h>
00038 #include <stdio.h>
00039
00040 #include <pi-socket.h>
00041 #include <pi-file.h>
00042
00043 #include <qtimer.h>
00044 #include <qvbox.h>
00045 #include <qlayout.h>
00046 #include <qlabel.h>
00047 #include <qmessagebox.h>
00048 #include <qdir.h>
00049 #include <qfile.h>
00050 #include <qfileinfo.h>
00051 #include <qtl.h>
00052 #include <qstyle.h>
00053 #include <qtextcodec.h>
00054
00055 #include <kdialogbase.h>
00056 #include <kglobal.h>
00057 #include <kstandarddirs.h>
00058 #include <kmessagebox.h>
00059
00060 #include <kapplication.h>
00061
00062 #include "pilotUser.h"
00063 #include "pilotAppCategory.h"
00064 #include "pilotLocalDatabase.h"
00065 #include "kpilotConfig.h"
00066 #include "kpilotlink.h"
00067
00068 #include "interactiveSync.moc"
00069
00070
00071 CheckUser::CheckUser(KPilotDeviceLink * p, QWidget * vp):
00072 SyncAction(p, vp, "userCheck")
00073 {
00074 FUNCTIONSETUP;
00075
00076 (void) interactivesync_id;
00077 }
00078
00079 CheckUser::~CheckUser()
00080 {
00081 FUNCTIONSETUP;
00082 }
00083
00084 bool CheckUser::exec()
00085 {
00086 FUNCTIONSETUP;
00087
00088 QString guiUserName = KPilotSettings::userName();
00089 QString pilotUserName = PilotAppCategory::codec()->
00090 toUnicode(fHandle->getPilotUser()->getUserName());
00091 bool pilotUserEmpty = pilotUserName.isEmpty();
00092
00093
00094
00095
00096
00097 if (guiUserName.isEmpty())
00098 {
00099 if (pilotUserEmpty)
00100 {
00101 QString defaultUserName =
00102 i18n("A common name", "John Doe");
00103
00104 QString q = i18n("<qt>Neither KPilot nor the "
00105 "handheld have a username set. "
00106 "They <i>should</i> be set. "
00107 "Should KPilot set them to a default value "
00108 "(<i>%1</i>)?</qt>").arg(defaultUserName);
00109
00110 if (questionYesNo(q, i18n("User Unknown") ) ==
00111 KMessageBox::Yes)
00112 {
00113 KPilotSettings::setUserName(defaultUserName);
00114 fHandle->getPilotUser()->
00115 setUserName(PilotAppCategory::codec()->fromUnicode(defaultUserName));
00116 guiUserName=defaultUserName;
00117 pilotUserName=defaultUserName;
00118 }
00119
00120 }
00121 else
00122 {
00123 QString q = i18n("<qt>The handheld has a username set "
00124 "(<i>%1</i>) but KPilot does not. Should "
00125 "KPilot use this username in future?").
00126 arg(pilotUserName);
00127
00128 if (questionYesNo(q, i18n("User Unknown") ) ==
00129 KMessageBox::Yes)
00130 {
00131 KPilotSettings::setUserName(pilotUserName);
00132 guiUserName=pilotUserName;
00133 }
00134 }
00135 }
00136 else
00137 {
00138 if (pilotUserEmpty)
00139 {
00140 QString q = i18n("<qt>KPilot has a username set "
00141 "(<i>%1</i>) but the handheld does not. "
00142 "Should KPilot's username be set in the "
00143 "handheld as well?").arg(guiUserName);
00144
00145 if (questionYesNo(q, i18n("User Unknown") ) ==
00146 KMessageBox::Yes)
00147 {
00148 #ifdef DEBUG
00149 DEBUGDAEMON << fname
00150 << ": Setting user name in pilot to "
00151 << guiUserName << endl;
00152 #endif
00153
00154 QCString l1 = PilotAppCategory::codec()->fromUnicode(guiUserName);
00155
00156 fHandle->getPilotUser()->setUserName(l1.data());
00157 pilotUserName=guiUserName;
00158 }
00159 }
00160 else
00161 {
00162 if (guiUserName != pilotUserName)
00163 {
00164 QString q = i18n("<qt>The handheld thinks that "
00165 "the username is %1; "
00166 "however, KPilot says you are %2."
00167 "Which of these is the correct name?\n"
00168 "If you click on Cancel, the sync will proceed, "
00169 "but the usernames will not be changed.").
00170 arg(pilotUserName).
00171 arg(guiUserName);
00172
00173 int r = questionYesNoCancel(q,
00174 i18n("User Mismatch"),
00175 QString::null,
00176 20,
00177 i18n("Use KPilot Name"),
00178 i18n("Use Handheld Name"));
00179 switch (r)
00180 {
00181 case KMessageBox::Yes:
00182 fHandle->getPilotUser()->setUserName(
00183 PilotAppCategory::codec()->fromUnicode(guiUserName));
00184 pilotUserName=guiUserName;
00185 break;
00186 case KMessageBox::No:
00187 KPilotSettings::setUserName(pilotUserName);
00188 guiUserName=pilotUserName;
00189 break;
00190 case KMessageBox::Cancel:
00191 default:
00192
00193 break;
00194 }
00195 }
00196 }
00197 }
00198
00199
00200 #ifdef DEBUG
00201 DEBUGCONDUIT << fname
00202 << ": User name set to gui<"
00203 << guiUserName
00204 << "> hh<"
00205 << fHandle->getPilotUser()->getUserName() << ">" << endl;
00206 #endif
00207
00208 KPilotSettings::writeConfig();
00209
00210
00211
00212
00213
00214 QString pathName = KGlobal::dirs()->saveLocation("data",
00215 CSL1("kpilot/DBBackup/"));
00216 if (!guiUserName.isEmpty())
00217 {
00218 pathName.append(guiUserName);
00219 pathName.append(CSL1("/"));
00220 }
00221 PilotLocalDatabase::setDBPath(pathName);
00222
00223 emit syncDone(this);
00224 return true;
00225 }
00226
00227 class RestoreInfo
00228 {
00229 public:
00230 struct db DBInfo;
00231 QString path;
00232 } ;
00233
00234 class RestoreAction::RestoreActionPrivate
00235 {
00236 public:
00237 QString fDatabaseDir;
00238 QValueList<RestoreInfo *> fDBList;
00239 QTimer fTimer;
00240 QValueList<RestoreInfo *>::ConstIterator fDBIterator;
00241 int fDBIndex;
00242 };
00243
00244
00245 RestoreAction::RestoreAction(KPilotDeviceLink * p, QWidget * visible ) :
00246 SyncAction(p, visible, "restoreAction")
00247 {
00248 FUNCTIONSETUP;
00249
00250 fP = new RestoreActionPrivate;
00251 fP->fDatabaseDir = KGlobal::dirs()->saveLocation("data",
00252 CSL1("kpilot/DBBackup/"));
00253 }
00254
00255 bool RestoreAction::exec()
00256 {
00257 FUNCTIONSETUP;
00258
00259 #ifdef DEBUG
00260 DEBUGDAEMON << fname
00261 << ": Restoring from base directory "
00262 << *(PilotLocalDatabase::getDBPath()) << endl;
00263 #endif
00264
00265 QString dirname = *(PilotLocalDatabase::getDBPath());
00266
00267 #ifdef DEBUG
00268 DEBUGDAEMON << fname << ": Restoring user " << dirname << endl;
00269 #endif
00270
00271 if (questionYesNo(i18n("<qt>Are you sure you want to completely "
00272 "restore your Pilot from the backup directory "
00273 "(<i>%1</i>)? This will erase any information "
00274 "you currently have on your Pilot.</qt>").
00275 arg(dirname),
00276 i18n("Restore Pilot")) != KMessageBox::Yes)
00277 {
00278 emit logError(i18n("Restore <i>not</i> performed."));
00279
00280 addSyncLogEntry(i18n("Canceled by user.") + CSL1(" ") +
00281 i18n("Restore not performed."));
00282 emit syncDone(this);
00283
00284 return true;
00285 }
00286
00287 QDir dir(dirname, QString::null, QDir::Name,
00288 QDir::Files | QDir::Readable | QDir::NoSymLinks);
00289
00290 if (!dir.exists())
00291 {
00292 kdWarning() << k_funcinfo
00293 << ": Restore directory "
00294 << dirname << " does not exist." << endl;
00295 fActionStatus = Error;
00296 addSyncLogEntry(i18n("Restore directory does not exist.") +
00297 CSL1(" ") + i18n("Restore not performed."));
00298 return false;
00299 }
00300
00301 emit logProgress(i18n("Restoring %1...").arg(QString::null),1);
00302
00303 for (unsigned int i = 0; i < dir.count(); i++)
00304 {
00305 QString s;
00306 RestoreInfo *dbi;
00307 struct DBInfo info;
00308 struct pi_file *f;
00309
00310 s = dir[i];
00311
00312 #ifdef DEBUG
00313 DEBUGDAEMON << fname
00314 << ": Adding " << s << " to restore list." << endl;
00315 #endif
00316
00317 char * fileName = qstrdup( QFile::encodeName(dirname + s) );
00318 f = pi_file_open( fileName );
00319 delete fileName;
00320 if (!f)
00321 {
00322 kdWarning() << k_funcinfo
00323 << ": Can't open " << s << endl;
00324 logMessage(i18n("File '%1' cannot be read.").arg(s));
00325 continue;
00326 }
00327
00328 #if PILOT_LINK_NUMBER < PILOT_LINK_0_12_0
00329 if (!pi_file_get_info(f, &info))
00330 #else
00331 pi_file_get_info(f,&info);
00332 if (true)
00333 #endif
00334 {
00335 dbi = new RestoreInfo;
00336 memcpy(&dbi->DBInfo,&info,sizeof(struct DBInfo));
00337 dbi->path = dirname + s;
00338 fP->fDBList.append(dbi);
00339 }
00340 else
00341 {
00342 kdWarning() << k_funcinfo
00343 << ": Can't open " << s << endl;
00344 logMessage(i18n("File '%1' cannot be read.").arg(s));
00345 }
00346
00347 pi_file_close(f);
00348 f = 0L;
00349 }
00350
00351 fP->fDBIndex = 0;
00352 fP->fDBIterator = fP->fDBList.begin();
00353 fActionStatus = GettingFileInfo;
00354
00355 QObject::connect(&(fP->fTimer), SIGNAL(timeout()),
00356 this, SLOT(getNextFileInfo()));
00357
00358 fP->fTimer.start(0, false);
00359 return true;
00360 }
00361
00362 void RestoreAction::getNextFileInfo()
00363 {
00364 FUNCTIONSETUP;
00365
00366 Q_ASSERT(fActionStatus == GettingFileInfo);
00367
00368 QObject::disconnect(&(fP->fTimer), SIGNAL(timeout()),
00369 this, SLOT(getNextFileInfo()));
00370 fP->fTimer.stop();
00371
00372 qBubbleSort(fP->fDBList);
00373
00374 fP->fDBIndex = 0;
00375 fP->fDBIterator = fP->fDBList.begin();
00376 fActionStatus = InstallingFiles;
00377
00378 QObject::connect(&(fP->fTimer), SIGNAL(timeout()),
00379 this, SLOT(installNextFile()));
00380 fP->fTimer.start(0, false);
00381 }
00382
00383 void RestoreAction::installNextFile()
00384 {
00385 FUNCTIONSETUP;
00386
00387 Q_ASSERT(fActionStatus == InstallingFiles);
00388
00389 const RestoreInfo *dbi = 0L;
00390
00391 if (fP->fDBIterator == fP->fDBList.end())
00392 {
00393 QObject::disconnect(&(fP->fTimer), SIGNAL(timeout()),
00394 this, SLOT(getNextFileInfo()));
00395 fP->fTimer.stop();
00396
00397 fActionStatus = Done;
00398 addSyncLogEntry(i18n("OK."));
00399 delayDone();
00400 return;
00401 }
00402
00403 dbi = *fP->fDBIterator;
00404 ++(fP->fDBIterator);
00405 ++(fP->fDBIndex);
00406 #ifdef DEBUG
00407 DEBUGDAEMON << fname << ": Trying to install " << dbi->path << endl;
00408 #endif
00409
00410 if (openConduit() < 0)
00411 {
00412 kdWarning() << k_funcinfo
00413 << ": Restore apparently canceled." << endl;
00414 logMessage(i18n("Restore incomplete."));
00415 fActionStatus = Done;
00416 emit syncDone(this);
00417
00418 return;
00419 }
00420
00421 QFileInfo databaseInfo(dbi->path);
00422 addSyncLogEntry(databaseInfo.fileName());
00423 emit logProgress(i18n("Restoring %1...").arg(databaseInfo.fileName()),
00424 (100*fP->fDBIndex) / (fP->fDBList.count()+1)) ;
00425
00426 char * fileName = qstrdup( dbi->path.utf8() );
00427 pi_file *f = pi_file_open( fileName );
00428 delete fileName;
00429
00430 if (!f)
00431 {
00432 kdWarning() << k_funcinfo
00433 << ": Can't open "
00434 << dbi->path << " for restore." << endl;
00435 logError(i18n("Cannot open file `%1' for restore.")
00436 .arg(databaseInfo.fileName()));
00437 return;
00438 }
00439
00440 #if PILOT_LINK_NUMBER < PILOT_LINK_0_12_0
00441 if (pi_file_install(f, pilotSocket(), 0) < 0)
00442 #else
00443 if (pi_file_install(f, pilotSocket(), 0, NULL) < 0)
00444 #endif
00445 {
00446 kdWarning() << k_funcinfo
00447 << ": Couldn't restore " << dbi->path << endl;
00448 logError(i18n("Cannot restore file `%1'.")
00449 .arg(databaseInfo.fileName()));
00450 }
00451
00452 pi_file_close(f);
00453 }
00454
00455 QString RestoreAction::statusString() const
00456 {
00457 FUNCTIONSETUP;
00458 QString s;
00459
00460 switch (status())
00461 {
00462 case InstallingFiles:
00463 s.append(CSL1("Installing Files ("));
00464 s.append(QString::number(fP->fDBIndex));
00465 s.append(CSL1(")"));
00466 break;
00467 case GettingFileInfo:
00468 s.append(CSL1("Getting File Info ("));
00469 s.append(QString::number(fP->fDBIndex));
00470 s.append(CSL1(")"));
00471 break;
00472 default:
00473 return SyncAction::statusString();
00474 }
00475
00476 return s;
00477 }
00478
00479