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