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