kpilot Library API Documentation

interactiveSync.cc

00001 /* interactiveSync.cc KPilot 00002 ** 00003 ** Copyright (C) 2001 by Dan Pilone 00004 ** 00005 ** This file specializes SyncAction to a kind that can have interaction 00006 ** with the user without the Sync timing out. 00007 */ 00008 00009 /* 00010 ** This program is free software; you can redistribute it and/or modify 00011 ** it under the terms of the GNU General Public License as published by 00012 ** the Free Software Foundation; either version 2 of the License, or 00013 ** (at your option) any later version. 00014 ** 00015 ** This program is distributed in the hope that it will be useful, 00016 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 ** GNU General Public License for more details. 00019 ** 00020 ** You should have received a copy of the GNU General Public License 00021 ** along with this program in a file called COPYING; if not, write to 00022 ** the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 00023 ** MA 02111-1307, USA. 00024 */ 00025 00026 /* 00027 ** Bug reports and questions can be sent to kde-pim@kde.org. 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 /* virtual */ 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 // 4 cases to handle: 00093 // guiUserName empty / not empty 00094 // pilotUserName empty / not empty 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") /* ,"askUserNone" */) == 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") /* ,"askUserSome" */ ) == 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") /* ,"askUserSome" */) == 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") /* ,"askUserDiff" */); 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 // TODO: cancel the sync... Or just don't change any user name? 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 // Now we've established which user will be used, 00213 // fix the database location for local databases. 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 /* virtual */ 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 /* 305 ok? */ 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 /* slot */ 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 /* slot */ 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( /* const_cast < 00468 char *>((const char *)QFile::encodeName */ (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 /* virtual */ 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
KDE Logo
This file is part of the documentation for kpilot Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Jul 28 23:57:48 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003