diff options
Diffstat (limited to 'kpilot/kpilot/hotSync.cc')
-rw-r--r-- | kpilot/kpilot/hotSync.cc | 1156 |
1 files changed, 0 insertions, 1156 deletions
diff --git a/kpilot/kpilot/hotSync.cc b/kpilot/kpilot/hotSync.cc deleted file mode 100644 index 7a4d3e44c..000000000 --- a/kpilot/kpilot/hotSync.cc +++ /dev/null @@ -1,1156 +0,0 @@ -/* KPilot -** -** Copyright (C) 2001 by Dan Pilone -** Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com> -** Copyright (C) 2006 Adriaan de Groot <groot@kde.org> -** -** This file defines SyncActions, which are used to perform some specific -** task during a HotSync. Conduits are not included here, nor are -** sync actions requiring user interaction. Those can be found in the -** conduits subdirectory or interactiveSync.h. -*/ - -/* -** This program is free software; you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 2 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program in a file called COPYING; if not, write to -** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, -** MA 02110-1301, USA. -*/ - -/* -** Bug reports and questions can be sent to kde-pim@kde.org. -*/ - - -#include "options.h" - -#include <time.h> -#include <unistd.h> -#include <stdio.h> - -#include <pi-file.h> -#include <pi-util.h> - -#include <tqtimer.h> -#include <tqfile.h> -#include <tqfileinfo.h> -#include <tqdir.h> -#include <tqvaluelist.h> -#include <tqregexp.h> -#include <tqstringlist.h> -#include <tqthread.h> - -#include <kglobal.h> -#include <kstandarddirs.h> -#include <kapplication.h> -#include <kmessagebox.h> - -#include "pilotUser.h" -#include "pilotRecord.h" -#include "actionQueue.h" -#include "pilotSerialDatabase.h" -#include "pilotLocalDatabase.h" -#include "pilotDatabase.h" -#include "kpilotSettings.h" - -#include "hotSync.moc" - -class BackupAction::Thread : public QThread -{ -public: - Thread( BackupAction *parent, - KPilotLink *link, - const TQString &filename, - const DBInfo *info ); - - enum { - TerminateOK = TQEvent::User, - TerminateFailure - } ; - -protected: - virtual void run(); -private: - BackupAction *fParent; - KPilotLink *fLink; - TQString fFilename; - struct DBInfo fDBInfo; -} ; - -class BackupAction::Private -{ -public: - bool fFullBackup; ///< Is this a full backup (all DBs, not just changed ones)? - TQStringList fNoBackupDBs; - TQValueList<unsigned long> fNoBackupCreators; - TQStringList fDeviceDBs; - - TQString fPreferBackupDir; ///< Directory to write backup in, overrides default - - // Remainder is used to hand around info during sync - - int fDBIndex; ///< Database number we're now doing - TQString fBackupDir; ///< Directory to write backup in. - - /** - * Add the database described by the info block to the list of - * databases definitely found on the handheld. - */ - void addDBInfo( const DBInfo *info ) - { - FUNCTIONSETUP; - fDBIndex = info->index + 1; - - // Each character of buff[] is written to - char buff[7]; - buff[0] = '['; - set_long( &buff[1], info->creator ); - buff[5] = ']'; - buff[6] = '\0'; - TQString creator = TQString::fromLatin1( buff ); - - TQString dbname = Pilot::fromPilot( info->name, 32 ); - - if ( !fDeviceDBs.contains( creator ) ) - { - fDeviceDBs << creator; - } - if ( !fDeviceDBs.contains( dbname ) ) - { - fDeviceDBs << dbname; - } - - DEBUGKPILOT << fname << ": Added <" << dbname - << "> " << creator << endl; - } - - - /** - * Check if this database, described by @p info , should - * be backed up (i.e. is allowed to be backed up by the - * user settings for no-backup DBs). - * - * @return @c true if the database may be backed up. - */ - bool allowBackup( const DBInfo *info ) const - { - // Special case - skip database Unsaved Preferences - if ( (info->creator == pi_mktag('p','s','y','s')) && - (info->type == pi_mktag('p','r','e','f')) ) - { - return false; - } - - if (fNoBackupCreators.findIndex(info->creator) != -1) - { - return false; - } - - // Now take wildcards into account - TQString db = Pilot::fromPilot(info->name); - for (TQStringList::const_iterator i = fNoBackupDBs.begin(); - i != fNoBackupDBs.end(); ++i) - { - TQRegExp re(*i,true,true); // Wildcard match - if (re.exactMatch(db)) - { - return false; - } - } - return true; - } - -} ; - -BackupAction::BackupAction(KPilotLink * p, bool full) : - SyncAction(p, "backupAction"), - fP( new Private ), - fBackupThread( 0L ) -{ - FUNCTIONSETUP; - - fP->fFullBackup = full; -} - -/* virtual */ TQString BackupAction::statusString() const -{ - FUNCTIONSETUP; - TQString s(CSL1("BackupAction=")); - - switch (status()) - { - case Init: - s.append(CSL1("Init")); - break; - case Error: - s.append(CSL1("Error")); - break; - case FullBackup: - s.append(CSL1("FullBackup")); - break; - case FastBackup: - s.append(CSL1("FastBackup")); - break; - case BackupEnded: - s.append(CSL1("BackupEnded")); - break; - case BackupIncomplete: - s.append(CSL1("BackupIncomplete")); - break; - case BackupComplete: - s.append(CSL1("BackupComplete")); - break; - default: - s.append(CSL1("(unknown ")); - s.append(TQString::number(status())); - s.append(CSL1(")")); - } - - return s; -} - -void BackupAction::setDirectory( const TQString &p ) -{ - fP->fPreferBackupDir = p; - if (!p.endsWith(CSL1("/"))) - { - fP->fPreferBackupDir.append(CSL1("/")); - } -} - -static inline void initNoBackup(TQStringList &dbnames, - TQValueList<unsigned long> &dbcreators) -{ - FUNCTIONSETUP; - dbnames.clear(); - dbcreators.clear(); - - TQStringList configuredSkip = KPilotSettings::skipBackupDB(); - TQStringList::const_iterator e = configuredSkip.end(); - for (TQStringList::const_iterator i = configuredSkip.begin(); - i!= e; ++i) - { - TQString s = *i; - if (s.startsWith(CSL1("[")) && s.endsWith(CSL1("]"))) - { - if (s.length() != 6) - { - WARNINGKPILOT << "Creator ID " << s << " is malformed." << endl; - } - else - { - TQCString data = s.mid(1,4).latin1(); - unsigned long creator = pi_mktag(data[0],data[1],data[2],data[3]); - dbcreators.append(creator); - } - } - else - { - dbnames.append(s); - } - } - - DEBUGKPILOT << fname << ": Will skip databases " - << dbnames.join(CSL1(",")) << endl; - TQString creatorids; - char buf[5]; - for (TQValueList<unsigned long>::const_iterator i = dbcreators.begin(); - i != dbcreators.end(); ++i) - { - unsigned long tag = *i; - pi_untag(buf,tag); - buf[4]=0; - creatorids.append(CSL1("[%1]").arg(buf)); - } - DEBUGKPILOT << fname << ": Will skip creators " << creatorids << endl; -} - -/** Make sure that the backup directory @p backupDir -* exists and is a directory; returns @c false -* if this is not the case. This method will try -* to create the directory if it doesn't exist yet. -*/ -static inline bool checkBackupDirectory( const TQString &backupDir ) -{ - FUNCTIONSETUP; - TQFileInfo fi(backupDir); - - if (fi.exists() && fi.isDir()) - { - return true; - } - - if (fi.exists() && !fi.isDir()) - { - WARNINGKPILOT << "Requested backup directory " - << backupDir - << " exists but is not a directory." - << endl; - return false; - } - - if ( !backupDir.endsWith("/") ) - { - WARNINGKPILOT << "Backup dir does not end with a / " - << endl; - return false; - } - - Q_ASSERT(!fi.exists()); - - DEBUGKPILOT << fname - << ": Creating directory " << backupDir << endl; - - KStandardDirs::makeDir( backupDir ); - - fi = TQFileInfo(backupDir); - - return fi.exists() && fi.isDir(); -} - - -/* virtual */ bool BackupAction::exec() -{ - FUNCTIONSETUP; - - fP->fDeviceDBs = KPilotSettings::deviceDBs(); - - if (fP->fPreferBackupDir.isEmpty()) - { - fP->fBackupDir = - KGlobal::dirs()->saveLocation("data",CSL1("kpilot/DBBackup/")) + - deviceLink()->getPilotUser().name() + '/'; - } - else - { - fP->fBackupDir = fP->fPreferBackupDir; - } - - logMessage(i18n("Backup directory: %1.").arg(fP->fBackupDir)); - - DEBUGKPILOT << fname - << ": This Pilot user's name is \"" - << deviceLink()->getPilotUser().name() << "\"" << endl; - DEBUGKPILOT << fname - << ": Using backup dir: " << fP->fBackupDir << endl; - DEBUGKPILOT << fname - << ": Full Backup? " << fP->fFullBackup << endl; - - - if (fP->fFullBackup) - { - fActionStatus = FullBackup; - addSyncLogEntry(i18n("Full backup started.")); - } - else - { - fActionStatus = FastBackup; - addSyncLogEntry(i18n("Fast backup started")); - } - - if (!checkBackupDirectory(fP->fBackupDir)) - { - fActionStatus=BackupIncomplete; - // Don't issue an error message, checkBackupDirectory - // did this already... - return false; - } - - initNoBackup( fP->fNoBackupDBs, fP->fNoBackupCreators ); - - fP->fDBIndex = 0; - TQTimer::singleShot(0,this,TQT_SLOT(backupOneDB())); - return true; -} - -/* slot */ void BackupAction::backupOneDB() -{ - FUNCTIONSETUP; - - struct DBInfo info; - - // TODO: make the progress reporting more accurate - emit logProgress(TQString::null, fP->fDBIndex); - - if (openConduit() < 0) - { - addSyncLogEntry(i18n("Exiting on cancel.")); - endBackup(); - fActionStatus = BackupIncomplete; - return; - } - - // TODO: Is there a way to skip unchanged databases? - int res = deviceLink()->getNextDatabase( fP->fDBIndex, &info ); - if (res < 0) - { - if ( fP->fFullBackup ) - { - addSyncLogEntry( i18n("Full backup complete.") ); - } - else - { - addSyncLogEntry( i18n("Fast backup complete.") ); - } - endBackup(); - fActionStatus = BackupComplete; - return; - } - - fP->addDBInfo( &info ); - - // see if user told us not to back this creator or database up... - if (fP->allowBackup(&info)) - { - // back up DB if this is a full backup *or* in non-full backups, - // only backup data, not applications. - if ( (fP->fFullBackup) || !PilotDatabase::isResource(&info) ) - { - addSyncLogEntry(i18n("Backing up: %1").arg(Pilot::fromPilot(info.name))); - - if (!startBackupThread(&info)) - { - WARNINGKPILOT << "Could not create local database for <" - << info.name << ">" << endl; - } - else - { - // The thread has started, so we will be woken - // up by it eventually when it is done. Do *NOT* - // fall through to the single-shot timer below, - // because that would return us to the backup - // function too soon. - return; - } - } - else - { - // Just skip resource DBs during an update hotsync. - DEBUGKPILOT << fname << ": Skipping database <" << info.name - << "> (resource database)" << endl; - } - } - else - { - DEBUGKPILOT << fname << ": Skipping database <" << info.name - << "> (no-backup list)" << endl; - TQString s = i18n("Skipping %1") - .arg(Pilot::fromPilot(info.name)); - addSyncLogEntry(s); - } - TQTimer::singleShot(0,this,TQT_SLOT(backupOneDB())); -} - -/** - * This method will back up a single database from the Pilot to a directory on - * our filesystem. If our user asks us to do a full backup, then we will unconditionally - * copy the database file from the Pilot into the backup directory. Otherwise, we will - * check to see if the database has any modified records in it on the pilot. If the - * database has not changed on the Pilot, then there's nothing to backup and we return. - * - * @return @c true if the backup has started (in another thread). - * You must wait on the thread to end with a User or User+1 - * type event and not start another backup thread. - * @return @c false if there is no backup to do. Diagnostic messages - * will already have been printed. - */ -bool BackupAction::startBackupThread(DBInfo *info) -{ - FUNCTIONSETUP; - - // now we look to see if the database on the pilot has at least one changed record - // in it. we do this so that we don't waste time backing up a database that has - // not changed. note: don't bother with this check if we're doing a full backup. - if (!fP->fFullBackup) - { - // Check if this DB has modified records. - PilotDatabase *serial=deviceLink()->database(info); - if (!serial->isOpen()) - { - WARNINGKPILOT << "Unable to open database <" << info->name << ">" << endl; - KPILOT_DELETE(serial); - addSyncLogEntry(i18n("Backup of %1 failed.\n") - .arg(Pilot::fromPilot(info->name))); - return false; - } - - int index=0; - PilotRecord*rec=serial->readNextModifiedRec(&index); - if (!rec) - { - DEBUGKPILOT << fname << ": No modified records." << endl; - KPILOT_DELETE(serial); - return false; - } - // Exists, with modified records. - KPILOT_DELETE(rec); - KPILOT_DELETE(serial); - } - - - // if we're here then we are going to back this database up. do some basic sanity - // checks and proceed.... - TQString databaseName(Pilot::fromPilot(info->name)); - databaseName.replace('/', '_'); - - TQString fullBackupName = fP->fBackupDir + databaseName; - - if (PilotDatabase::isResource(info)) - { - fullBackupName.append(CSL1(".prc")); - } - else - { - fullBackupName.append(CSL1(".pdb")); - } - - DEBUGKPILOT << fname - << ": Backing up database to: [" << fullBackupName << "]" << endl; - - /* Ensure that DB-open flag is not kept */ - info->flags &= ~dlpDBFlagOpen; - - if (fBackupThread) - { - WARNINGKPILOT << "Starting new backup thread before the old one is done." << endl; - return false; - } - - fBackupThread = new Thread(this,deviceLink(),fullBackupName,info); - fBackupThread->start(); - return true; -} - -/* virtual */ bool BackupAction::event( TQEvent *e ) -{ - if (e->type() == (TQEvent::Type)Thread::TerminateOK) - { - KPILOT_DELETE(fBackupThread); - // This was a successful termination. - addSyncLogEntry( i18n("... OK.\n"), false ); - TQTimer::singleShot(0,this,TQT_SLOT(backupOneDB())); - return true; - } - if (e->type() == (TQEvent::Type)Thread::TerminateFailure) - { - KPILOT_DELETE(fBackupThread); - // Unsuccessful termination. - addSyncLogEntry( i18n("Backup failed.") ); - TQTimer::singleShot(0,this,TQT_SLOT(backupOneDB())); - return true; - } - return SyncAction::event(e); -} - -void BackupAction::endBackup() -{ - FUNCTIONSETUP; - - fP->fDBIndex = (-1); - fActionStatus = BackupEnded; - fP->fDeviceDBs.sort(); - TQString old( TQString::null ); - TQStringList::Iterator itr = fP->fDeviceDBs.begin(); - while ( itr != fP->fDeviceDBs.end() ) { - if ( old == *itr ) { - itr = fP->fDeviceDBs.remove( itr ); - } else { - old = *itr; - ++itr; - } - } - KPilotSettings::setDeviceDBs( fP->fDeviceDBs ); - - emit syncDone(this); -} - -FileInstallAction::FileInstallAction(KPilotLink * p, - const TQString & d) : - SyncAction(p, "fileInstall"), - fDBIndex(-1), - fTimer(0L), - fDir(d) -{ - FUNCTIONSETUP; -} - -FileInstallAction::~FileInstallAction() -{ - FUNCTIONSETUP; - - KPILOT_DELETE(fTimer); -} - -/* virtual */ bool FileInstallAction::exec() -{ - FUNCTIONSETUP; - - TQDir installDir(fDir); - fList = installDir.entryList(TQDir::Files | - TQDir::NoSymLinks | TQDir::Readable); -#ifdef DEBUG - DEBUGKPILOT << fname - << ": Installing " << fList.count() << " files" << endl; -#endif - - fDBIndex = 0; - emit logMessage(i18n("[File Installer]")); - - // Possibly no files to install? - if (!fList.count()) - { - emit logMessage(i18n("No Files to install")); - delayDone(); - return true; - } - - fTimer = new TQTimer(this); - TQObject::connect(fTimer, TQT_SIGNAL(timeout()), - this, TQT_SLOT(installNextFile())); - - fTimer->start(0, false); - - emit logProgress(i18n("Installing one file", - "Installing %n Files",fList.count()), 0); - return true; -} - -/* slot */ void FileInstallAction::installNextFile() -{ - FUNCTIONSETUP; - - Q_ASSERT(fDBIndex >= 0); - Q_ASSERT((unsigned) fDBIndex <= fList.count()); - -#ifdef DEBUG - DEBUGKPILOT << fname - << ": Installing file index " - << fDBIndex << " (of " << fList.count() << ")" << endl; -#endif - - if ((!fList.count()) || ((unsigned) fDBIndex >= fList.count())) - { -#ifdef DEBUG - DEBUGKPILOT << fname - << ": Peculiar file index, bailing out." << endl; -#endif - KPILOT_DELETE(fTimer); - fDBIndex = (-1); - emit logProgress(i18n("Done Installing Files"), 100); - delayDone(); - return; - } - - const TQString filePath = fDir + fList[fDBIndex]; - const TQString fileName = fList[fDBIndex]; - - fDBIndex++; - -#ifdef DEBUG - DEBUGKPILOT << fname << ": Installing file " << filePath << endl; -#endif - - TQString m = i18n("Installing %1").arg(fileName); - emit logProgress(m,(100 * fDBIndex) / (fList.count()+1)); - m+=CSL1("\n"); - emit addSyncLogEntry(m,false /* Don't print in KPilot's log. */ ); - - struct pi_file *f = 0L; - - // Check DB is ok, return false after warning user - if (!resourceOK(fileName,filePath)) goto nextFile; - - f = pi_file_open(const_cast <char *> - ((const char *) TQFile::encodeName(filePath))); - - -#if PILOT_LINK_NUMBER < PILOT_LINK_0_12_0 - if (pi_file_install(f, pilotSocket(), 0) < 0) -#else - if (pi_file_install(f, pilotSocket(), 0, NULL) < 0) -#endif - { - WARNINGKPILOT << "Failed to install." << endl; - - - emit logError(i18n("Cannot install file "%1"."). - arg(fileName)); - } - else - { - TQFile::remove(filePath); - } - - -nextFile: - if (f) pi_file_close(f); - if (fDBIndex == -1) - { - fTimer->stop(); - delayDone(); - // emit syncDone(this); - } -} - -// Check that the given file path is a good resource -// file - in particular that the resource name is ok. -bool FileInstallAction::resourceOK(const TQString &fileName, const TQString &filePath) -{ - FUNCTIONSETUP; - - if (!TQFile::exists(filePath)) - { - emit logError(i18n("Unable to open file "%1"."). - arg(fileName)); - return false; - } - - struct pi_file *f = pi_file_open(const_cast <char *> - ((const char *) TQFile::encodeName(filePath))); - - if (!f) - { - emit logError(i18n("Unable to open file "%1"."). - arg(fileName)); - return false; - } - - struct DBInfo info; -#if PILOT_LINK_NUMBER < PILOT_LINK_0_12_0 - if (pi_file_get_info(f,&info) < 0) - { - emit logError(i18n("Unable to read file "%1"."). - arg(fileName)); - return false; - } -#else - pi_file_get_info(f,&info); -#endif - - // Looks like strlen, but we can't be sure of a NUL - // termination. - info.name[sizeof(info.name)-1]=0; - bool r = (strlen(info.name) < 32); - pi_file_close(f); - - if (!r) - { - emit logError(i18n("The database in "%1" has a " - "resource name that is longer than 31 characters. " - "This suggests a bug in the tool used to create the database. " - "KPilot cannot install this database.").arg(fileName)); - } - - return r; -} - -/* virtual */ TQString FileInstallAction::statusString() const -{ - FUNCTIONSETUP; - if (fDBIndex < 0) - { - return TQString(CSL1("Idle")); - } - else - { - if ((unsigned) fDBIndex >= fList.count()) - { - return TQString(CSL1("Index out of range")); - } - else - { - return TQString(CSL1("Installing %1")).arg(fList[fDBIndex]); - } - } -} - -CheckUser::CheckUser(KPilotLink * p, TQWidget * vp): - SyncAction(p, vp, "userCheck") -{ - FUNCTIONSETUP; - -} - -CheckUser::~CheckUser() -{ - FUNCTIONSETUP; -} - -/* virtual */ bool CheckUser::exec() -{ - FUNCTIONSETUP; - - TQString guiUserName = KPilotSettings::userName(); - TQString pilotUserName = fHandle->getPilotUser().name(); - bool pilotUserEmpty = pilotUserName.isEmpty(); - // 4 cases to handle: - // guiUserName empty / not empty - // pilotUserName empty / not empty - // - // - if (guiUserName.isEmpty()) - { - if (pilotUserEmpty) - { - TQString defaultUserName = - i18n("A common name", "John Doe"); - - TQString q = i18n("<qt>Neither KPilot nor the " - "handheld have a username set. " - "They <i>should</i> be set. " - "Should KPilot set them to a default value " - "(<i>%1</i>)?</qt>").arg(defaultUserName); - - if (questionYesNo(q, i18n("User Unknown") /* ,"askUserNone" */) == - KMessageBox::Yes) - { - KPilotSettings::setUserName(defaultUserName); - fHandle->getPilotUser().setName(defaultUserName); - guiUserName=defaultUserName; - pilotUserName=defaultUserName; - } - - } - else - { - TQString q = i18n("<qt>The handheld has a username set " - "(<i>%1</i>) but KPilot does not. Should " - "KPilot use this username in future?</qt>"). - arg(pilotUserName); - - if (questionYesNo(q, i18n("User Unknown") /* ,"askUserSome" */ ) == - KMessageBox::Yes) - { - KPilotSettings::setUserName(pilotUserName); - guiUserName=pilotUserName; - } - } - } - else - { - if (pilotUserEmpty) - { - TQString q = CSL1("<qt>"); - q += i18n("KPilot has a username set " - "(<i>%1</i>) but the handheld does not. " - "Should KPilot's username be set in the " - "handheld as well?").arg(guiUserName); - q += i18n("<br/>(<i>Note:</i> If your handheld " - "has been reset to factory defaults, you " - "should use <i>Restore</i> instead of a " - "regular HotSync. Click on Cancel to " - "stop this sync.)"); - q += CSL1("</qt>"); - - int r = questionYesNoCancel(q, i18n("User Unknown")); - switch (r) - { - case KMessageBox::Yes: - DEBUGKPILOT << fname - << ": Setting user name in pilot to " - << guiUserName << endl; - fHandle->getPilotUser().setName(guiUserName); - pilotUserName=guiUserName; - break; - case KMessageBox::No: - // Nothing to do .. continue with sync - break; - case KMessageBox::Cancel: - default: - return false; - } - } - else - { - if (guiUserName != pilotUserName) - { - TQString q = i18n("<qt>The handheld thinks that " - "the username is %1; " - "however, KPilot says you are %2." - "Which of these is the correct name?\n" - "If you click on Cancel, the sync will proceed, " - "but the usernames will not be changed.</qt>"). - arg(pilotUserName). - arg(guiUserName); - - int r = questionYesNoCancel(q, - i18n("User Mismatch"), - TQString::null, - 20, - i18n("Use KPilot Name"), - i18n("Use Handheld Name")); - switch (r) - { - case KMessageBox::Yes: - fHandle->getPilotUser().setName(guiUserName); - pilotUserName=guiUserName; - break; - case KMessageBox::No: - KPilotSettings::setUserName(pilotUserName); - guiUserName=pilotUserName; - break; - case KMessageBox::Cancel: - default: - // TODO: cancel the sync... Or just don't change any user name? - break; - } - } - } - } - - -#ifdef DEBUG - DEBUGKPILOT << fname - << ": User name set to pc <" - << guiUserName - << "> hh <" - << fHandle->getPilotUser().name() << ">" << endl; -#endif - - KPilotSettings::writeConfig(); - - // Now we've established which user will be used, - // fix the database location for local databases. - // - // - TQString pathName = KGlobal::dirs()->saveLocation("data", - CSL1("kpilot/DBBackup/")); - if (!guiUserName.isEmpty()) - { - pathName.append(guiUserName); - pathName.append(CSL1("/")); - } - PilotLocalDatabase::setDBPath(pathName); - - delayDone(); - return true; -} - -class RestoreInfo -{ -public: - struct DBInfo DBInfo; - TQString path; -} ; - -class RestoreAction::Private -{ -public: - TQString fPreferRestoreDir; /**< Preference setting where to get data from. */ - - TQValueList<RestoreInfo> fDBList; - TQTimer fTimer; - TQValueList<RestoreInfo>::ConstIterator fDBIterator; - int fDBIndex; -}; - - -RestoreAction::RestoreAction(KPilotLink * p, TQWidget * visible ) : - SyncAction(p, visible, "restoreAction") -{ - FUNCTIONSETUP; - - fP = new Private; -} - -void RestoreAction::setDirectory( const TQString &path ) -{ - fP->fPreferRestoreDir = path; -} - -/* virtual */ bool RestoreAction::exec() -{ - FUNCTIONSETUP; - - TQString dirname; - if (fP->fPreferRestoreDir.isEmpty()) - { - dirname = PilotLocalDatabase::getDBPath(); - } - else - { - dirname = fP->fPreferRestoreDir; - } - -#ifdef DEBUG - DEBUGKPILOT << fname << ": Restoring user " << dirname << endl; -#endif - - TQDir dir(dirname, TQString::null, TQDir::Name, - TQDir::Files | TQDir::Readable | TQDir::NoSymLinks); - - if (!dir.exists()) - { - WARNINGKPILOT << "Restore directory " - << dirname << " does not exist." << endl; - fActionStatus = Error; - addSyncLogEntry(i18n("Restore directory does not exist.") + - CSL1(" ") + i18n("Restore not performed.")); - return false; - } - - dirname = dir.absPath(); - if (questionYesNo(i18n("<qt>Are you sure you want to completely " - "restore your Pilot from the backup directory " - "(<i>%1</i>)? This will erase any information " - "you currently have on your Pilot.</qt>"). - arg(dirname), - i18n("Restore Pilot")) != KMessageBox::Yes) - { - emit logError(i18n("Restore <i>not</i> performed.")); - - addSyncLogEntry(i18n("Canceled by user.") + CSL1(" ") + - i18n("Restore not performed.")); - - // You might call this an error, but that causes - // a frightening message in the log .. and the - // user already _knows_ the restore didn't happen. - // So instead, act as if everything was ok. - delayDone(); - return true; - } - - - emit logProgress(i18n("Restoring %1...").arg(TQString::null),1); - - for (unsigned int i = 0; i < dir.count(); i++) - { - TQString s; - RestoreInfo info; - - s = dirname + TQDir::separator() + dir[i]; - - DEBUGKPILOT << fname - << ": Adding " << s << " to restore list." << endl; - - if ( PilotLocalDatabase::infoFromFile( s, &info.DBInfo ) ) - { - info.path = s; - fP->fDBList.append(info); - } - else - { - WARNINGKPILOT << "Can't open " << s << endl; - logMessage(i18n("File '%1' cannot be read.").arg(s)); - } - } - - fP->fDBIndex = 0; - fP->fDBIterator = fP->fDBList.begin(); - fActionStatus = InstallingFiles; - - TQObject::connect(&(fP->fTimer), TQT_SIGNAL(timeout()), - this, TQT_SLOT(installNextFile())); - - fP->fTimer.start(0, false); - return true; -} - -/* slot */ void RestoreAction::installNextFile() -{ - FUNCTIONSETUP; - - Q_ASSERT(fActionStatus == InstallingFiles); - - - if (fP->fDBIterator == fP->fDBList.end()) - { - fP->fTimer.stop(); - - fActionStatus = Done; - addSyncLogEntry(i18n("OK.")); - delayDone(); - return; - } - - const RestoreInfo dbi = *(fP->fDBIterator); - ++(fP->fDBIterator); - ++(fP->fDBIndex); - - DEBUGKPILOT << fname << ": Trying to install " << dbi.path << endl; - - if (openConduit() < 0) - { - WARNINGKPILOT << "Restore apparently canceled." << endl; - logMessage(i18n("Restore incomplete.")); - fActionStatus = Done; - emit syncDone(this); - - return; - } - - TQFileInfo databaseInfo(dbi.path); - addSyncLogEntry(databaseInfo.fileName()); - emit logProgress(i18n("Restoring %1...").arg(databaseInfo.fileName()), - (100*fP->fDBIndex) / (fP->fDBList.count()+1)) ; - - if ( !deviceLink()->installFiles( dbi.path, false /* don't delete */ ) ) - { - WARNINGKPILOT << "Couldn't restore " << dbi.path << endl; - logError(i18n("Cannot restore file `%1'.") - .arg(databaseInfo.fileName())); - } -} - -/* virtual */ TQString RestoreAction::statusString() const -{ - FUNCTIONSETUP; - TQString s; - - switch (status()) - { - case InstallingFiles: - s.append(CSL1("Installing Files (")); - s.append(TQString::number(fP->fDBIndex)); - s.append(CSL1(")")); - break; - case GettingFileInfo: - s.append(CSL1("Getting File Info (")); - s.append(TQString::number(fP->fDBIndex)); - s.append(CSL1(")")); - break; - default: - return SyncAction::statusString(); - } - - return s; -} - - - -BackupAction::Thread::Thread( BackupAction *parent, - KPilotLink *link, - const TQString &filename, - const DBInfo *info ) -{ - fParent = parent; - fLink = link; - fFilename = filename; - memcpy(&fDBInfo,info,sizeof(DBInfo)); -} - -void BackupAction::Thread::run() -{ - if (fLink->retrieveDatabase(fFilename,&fDBInfo)) - { - // Successful. - TQApplication::postEvent( fParent, new TQEvent( (TQEvent::Type)TerminateOK ) ); - } - else - { - // Failed - TQApplication::postEvent( fParent, new TQEvent( (TQEvent::Type)TerminateFailure ) ); - } -} - - |