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 Sat May 1 11:36:47 2004 by doxygen 1.2.15 written by Dimitri van Heesch, © 1997-2003