diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2011-02-16 20:17:18 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2011-02-16 20:17:18 +0000 |
commit | f4fae92b6768541e2952173c3d4b09040f95bf7e (patch) | |
tree | d8c5d93232235cd635f3310b4d95490df181ba2d /kpilot/conduits/docconduit/doc-conduit.cc | |
parent | 125c0a08265b75a133644d3b55f47e37c919f45d (diff) | |
download | tdepim-f4fae92b6768541e2952173c3d4b09040f95bf7e.tar.gz tdepim-f4fae92b6768541e2952173c3d4b09040f95bf7e.zip |
Moved kpilot from kdepim to applications, as the core Trinity libraries should not contain hardware-dependent software
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdepim@1221127 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kpilot/conduits/docconduit/doc-conduit.cc')
-rw-r--r-- | kpilot/conduits/docconduit/doc-conduit.cc | 1018 |
1 files changed, 0 insertions, 1018 deletions
diff --git a/kpilot/conduits/docconduit/doc-conduit.cc b/kpilot/conduits/docconduit/doc-conduit.cc deleted file mode 100644 index fbaa22f59..000000000 --- a/kpilot/conduits/docconduit/doc-conduit.cc +++ /dev/null @@ -1,1018 +0,0 @@ -/* KPilot -** -** Copyright (C) 2002 by Reinhold Kainhofer -** -** The doc conduit synchronizes text files on the PC with DOC databases on the Palm -*/ - -/* -** 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. -*/ - - -// naming of the bookmark file: -// PDB->TXT: convert bookmarks to a .bm file -// TXT->PDB: If a .bmk file exists, use it, otherwise use the .bm file (from the PDB->TXT conversion) -// This way, the bookmark file is not overwritten, a manual bookmark file overrides, but the bookmarks from the handheld are still available - - -#include "options.h" -#include "doc-conduit.moc" - -#include <tqtimer.h> -#include <tqdir.h> - -#include <kconfig.h> -#include <kmdcodec.h> - -#include <pilotLocalDatabase.h> -#include <pilotSerialDatabase.h> - -#include "doc-factory.h" -#include "doc-conflictdialog.h" -#include "DOC-converter.h" -#include "pilotDOCHead.h" -#include "docconduitSettings.h" - - -// Something to allow us to check what revision -// the modules are that make up a binary distribution. -extern "C" -{ -unsigned long version_conduit_doc = Pilot::PLUGIN_API; -} - -TQString dirToString(eSyncDirectionEnum dir) { - switch(dir) { -// case eSyncAll: return "eSyncAll"; - case eSyncPDAToPC: return CSL1("eSyncPDAToPC"); - case eSyncPCToPDA: return CSL1("eSyncPCToPDA"); - case eSyncNone: return CSL1("eSyncNone"); - case eSyncConflict: return CSL1("eSyncConflict"); - case eSyncDelete: return CSL1("eSyncDelete"); - default: return CSL1("ERROR"); - } -} - - -/********************************************************************* - C O N S T R U C T O R - *********************************************************************/ - - -DOCConduit::DOCConduit(KPilotLink * o, - const char *n, const TQStringList & a):ConduitAction(o, n, a) -{ - FUNCTIONSETUP; - fConduitName=i18n("DOC"); -} - - - -DOCConduit::~DOCConduit() -{ - FUNCTIONSETUP; -} - - -bool DOCConduit::isCorrectDBTypeCreator(DBInfo dbinfo) { - return dbinfo.type == dbtype() && dbinfo.creator == dbcreator(); -} -const unsigned long DOCConduit::dbtype() { - return get_long(DOCConduitFactory::dbDOCtype); -} -const unsigned long DOCConduit::dbcreator() { - return get_long(DOCConduitFactory::dbDOCcreator); -} - - - -/********************************************************************* - L O A D I N G T H E D A T A - *********************************************************************/ - - - -void DOCConduit::readConfig() -{ - FUNCTIONSETUP; - DOCConduitSettings::self()->readConfig(); - - eConflictResolution = (enum eSyncDirectionEnum) (DOCConduitSettings::conflictResolution() ); - fTXTBookmarks = DOCConverter::eBmkNone; - if ( DOCConduitSettings::convertBookmarks() ) - { - if ( DOCConduitSettings::bmkFileBookmarks() ) - fTXTBookmarks |= DOCConverter::eBmkFile; - if ( DOCConduitSettings::inlineBookmarks() ) - fTXTBookmarks |= DOCConverter::eBmkInline; - if ( DOCConduitSettings::endtagBookmarks() ) - fTXTBookmarks |= DOCConverter::eBmkEndtags; - } - - eSyncDirection = (enum eSyncDirectionEnum)(DOCConduitSettings::syncDirection() ); - -#ifdef DEBUG - DEBUGKPILOT << fname - << ": Settings " - << " tXTDirectory=" << DOCConduitSettings::tXTDirectory() - << " pDBDirectory=" << DOCConduitSettings::pDBDirectory() - << " keepPDBLocally=" << DOCConduitSettings::keepPDBsLocally() - << " eConflictResolution=" << eConflictResolution - << " tXTBookmarks=" << fTXTBookmarks - << " pDBBookmarks=" << DOCConduitSettings::bookmarksToPC() - << " compress=" << DOCConduitSettings::compress() - << " eSyncDirection=" << eSyncDirection << endl; -#endif -} - - - -bool DOCConduit::pcTextChanged(TQString txtfn) -{ - FUNCTIONSETUP; - // How do I find out if a text file has changed shince we last synced it?? - // Use KMD5 for now. If I realize it is too slow, then I have to go back to comparing modification times - // if there is no config setting yet, assume the file has been changed. the md5 sum will be written to the config file after the sync. - TQString oldDigest=DOCConduitSettings::self()->config()->readEntry(txtfn); - if (oldDigest.length()<=0) - { - return true; - } -#ifdef DEBUG - DEBUGKPILOT<<"Old digest is "<<oldDigest<<endl; -#endif - - KMD5 docmd5; - TQFile txtfile(txtfn); - if (txtfile.open(IO_ReadOnly)){ - docmd5.update(txtfile); - TQString thisDigest(docmd5.hexDigest() /* .data() */); -#ifdef DEBUG - DEBUGKPILOT<<"New digest is "<<thisDigest<<endl; -#endif - return (thisDigest.length()<=0) || (thisDigest!=oldDigest); - } else { - // File does not exist. This should actually never happen. Anyways, just return true to indicate it has changed. - // doSync should detect this and delete the doc from the handheld. - return true; - } - return false; -} - - - -bool DOCConduit::hhTextChanged(PilotDatabase*docdb) -{ - FUNCTIONSETUP; - if (!docdb) return false; - - PilotRecord *firstRec = docdb->readRecordByIndex(0); - PilotDOCHead docHeader(firstRec); - KPILOT_DELETE(firstRec); - - int storyRecs = docHeader.numRecords; - - // determine the index of the next modified record (does it lie - // beyond the actual text records?) - int modRecInd=-1; - PilotRecord*modRec=docdb->readNextModifiedRec(&modRecInd); -#ifdef DEBUG - DEBUGKPILOT<<"Index of first changed record: "<<modRecInd<<endl; -#endif - - KPILOT_DELETE(modRec); - // if the header record was changed, find out which is the first changed - // real document record: - if (modRecInd==0) { - modRec=docdb->readNextModifiedRec(&modRecInd); -#ifdef DEBUG - DEBUGKPILOT<<"Reread Index of first changed records: "<<modRecInd<<endl; -#endif - KPILOT_DELETE(modRec); - } - - // The record index starts with 0, so only a negative number means - // no modified record was found - if (modRecInd >= 0) { -#ifdef DEBUG - DEBUGKPILOT<<"Handheld side has changed, condition="<< - ((!DOCConduitSettings::ignoreBmkChanges()) || (modRecInd <= storyRecs))<<endl; -#endif - if ((!DOCConduitSettings::ignoreBmkChanges()) || (modRecInd <= storyRecs)) - return true; - } else { -#ifdef DEBUG - DEBUGKPILOT<<"Handheld side has NOT changed!"<<endl; -#endif - return false; - } - return false; -} - - - -/********************************************************************* - * Helper functions - ********************************************************************/ - -TQString DOCConduit::constructPDBFileName(TQString name) { - FUNCTIONSETUP; - TQString fn; - TQDir dr(DOCConduitSettings::pDBDirectory()); - TQFileInfo pth(dr, name); - if (!name.isEmpty()) fn=pth.absFilePath()+CSL1(".pdb"); - return fn; -} -TQString DOCConduit::constructTXTFileName(TQString name) { - FUNCTIONSETUP; - TQString fn; - TQDir dr( DOCConduitSettings::tXTDirectory() ); - TQFileInfo pth(dr, name); - if (!name.isEmpty()) fn=pth.absFilePath()+CSL1(".txt"); - return fn; -} - - - - - -/********************************************************************* - S Y N C S T R U C T U R E - *********************************************************************/ - - - - - -/* virtual */ bool DOCConduit::exec() -{ - FUNCTIONSETUP; - - readConfig(); - dbnr=0; - - emit logMessage(i18n("Searching for texts and databases to synchronize")); - - TQTimer::singleShot(0, this, TQT_SLOT(syncNextDB())); - return true; -} - - - -bool DOCConduit::doSync(docSyncInfo &sinfo) -{ - FUNCTIONSETUP; - bool res=false; - - if (sinfo.direction==eSyncDelete) { - if (!sinfo.txtfilename.isEmpty()) { - if (!TQFile::remove(sinfo.txtfilename)) { - WARNINGKPILOT << "Unable to delete the text file " << sinfo.txtfilename << " on the PC" << endl; - } - TQString bmkfilename = sinfo.txtfilename; - if (bmkfilename.endsWith(CSL1(".txt"))){ - bmkfilename.remove(bmkfilename.length()-4, 4); - } - bmkfilename+=CSL1(PDBBMK_SUFFIX); - if (!TQFile::remove(bmkfilename)) { -#ifdef DEBUG - DEBUGKPILOT<<"Could not remove bookmarks file "<<bmkfilename<<" for database "<<sinfo.handheldDB<<endl; -#endif - } - } - if (!sinfo.pdbfilename.isEmpty() && DOCConduitSettings::keepPDBsLocally() ) { - PilotLocalDatabase*database=new PilotLocalDatabase(DOCConduitSettings::pDBDirectory(), - TQString::fromLatin1(sinfo.dbinfo.name), false); - if (database) { - if ( database->deleteDatabase() !=0 ) { - WARNINGKPILOT << "Unable to delete database " << sinfo.dbinfo.name << " on the PC" << endl; - } - KPILOT_DELETE(database); - } - } - if (!DOCConduitSettings::localSync()) { - PilotDatabase *database=deviceLink()->database( sinfo.dbinfo.name ); - if ( database->deleteDatabase() !=0 ) { - WARNINGKPILOT << "Unable to delete database " << sinfo.dbinfo.name << " from the handheld" << endl; - } - KPILOT_DELETE(database); - } - return true; - } - // preSyncAction should initialize the custom databases/files for the - // specific action chosen for this db and return a pointer to a docDBInfo - // instance which points either to a local database or a database on the handheld. - PilotDatabase *database = preSyncAction(sinfo); - - if (database && ( !database->isOpen() ) ) { -#ifdef DEBUG - DEBUGKPILOT<<"Database "<<sinfo.dbinfo.name<<" does not yet exist. Creating it:"<<endl; -#endif - if (!database->createDatabase(dbcreator(), dbtype()) ) { -#ifdef DEBUG - DEBUGKPILOT<<"Failed"<<endl; - emit logMessage(i18n("Database created.")); -#endif - } - } - - if (database && database->isOpen()) { - DOCConverter docconverter; - connect(&docconverter, TQT_SIGNAL(logError(const TQString &)), TQT_SIGNAL(logError(const TQString &))); - connect(&docconverter, TQT_SIGNAL(logMessage(const TQString &)), TQT_SIGNAL(logMessage(const TQString &))); - - docconverter.setTXTpath( DOCConduitSettings::tXTDirectory(), sinfo.txtfilename ); - docconverter.setPDB(database); - docconverter.setCompress(DOCConduitSettings::compress()); - - switch (sinfo.direction) { - case eSyncPDAToPC: - docconverter.setBookmarkTypes(DOCConduitSettings::bookmarksToPC()); - res = docconverter.convertPDBtoTXT(); - break; - case eSyncPCToPDA: - docconverter.setBookmarkTypes(fTXTBookmarks); - res = docconverter.convertTXTtoPDB(); - break; - default: - break; - } - - // Now calculate the md5 checksum of the PC text and write it to the config file - if (res) - { - KMD5 docmd5; - TQFile txtfile(docconverter.txtFilename()); - if (txtfile.open(IO_ReadOnly)) { - docmd5.update(txtfile); - TQString thisDigest(docmd5.hexDigest() /* .data() */); - DOCConduitSettings::self()->config()->writeEntry(docconverter.txtFilename(), thisDigest); - DOCConduitSettings::self()->config()->sync(); -#ifdef DEBUG - DEBUGKPILOT<<"MD5 Checksum of the text "<<sinfo.txtfilename<<" is "<<thisDigest<<endl; -#endif - } else { -#ifdef DEBUG - DEBUGKPILOT<<"couldn't open file "<<docconverter.txtFilename()<<" for reading!!!"<<endl; -#endif - } - } - - if (!postSyncAction(database, sinfo, res)) - emit logError(i18n("Unable to install the locally created PalmDOC %1 to the handheld.") - .arg(TQString::fromLatin1(sinfo.dbinfo.name))); - if (!res) - emit logError(i18n("Conversion of PalmDOC \"%1\" failed.") - .arg(TQString::fromLatin1(sinfo.dbinfo.name))); -// disconnect(&docconverter, TQT_SIGNAL(logError(const TQString &)), TQT_SIGNAL(logError(const TQString &))); -// disconnect(&docconverter, TQT_SIGNAL(logMessage(const TQString &)), TQT_SIGNAL(logMessage(const TQString &))); -// KPILOT_DELETE(database); - } - else - { - emit logError(i18n("Unable to open or create the database %1.") - .arg(TQString::fromLatin1(sinfo.dbinfo.name))); - } - return res; -} - - -/** syncNextDB walks through all PalmDoc databases on the handheld and decides if they are supposed to be synced to the PC. - * syncNextDB and syncNextTXT fist build the list of all PalmDoc texts, and then the method syncDatabases does the actual sync. */ -void DOCConduit::syncNextDB() { - FUNCTIONSETUP; - DBInfo dbinfo; - - if (eSyncDirection==eSyncPCToPDA || fHandle->findDatabase(NULL, &dbinfo, dbnr, dbtype(), dbcreator() /*, cardno */ ) < 0) - { - // no more databases available, so check for PC->Palm sync - TQTimer::singleShot(0, this, TQT_SLOT(syncNextTXT())); - return; - } - dbnr=dbinfo.index+1; -#ifdef DEBUG - DEBUGKPILOT<<"Next Palm database to sync: "<<dbinfo.name<<", Index="<<dbinfo.index<<endl; -#endif - - // if creator and/or type don't match, go to next db - if (!isCorrectDBTypeCreator(dbinfo) || - fDBNames.contains(TQString::fromLatin1(dbinfo.name))) - { - TQTimer::singleShot(0, this, TQT_SLOT(syncNextDB())); - return; - } - - TQString txtfilename=constructTXTFileName(TQString::fromLatin1(dbinfo.name)); - TQString pdbfilename=constructPDBFileName(TQString::fromLatin1(dbinfo.name)); - - docSyncInfo syncInfo(TQString::fromLatin1(dbinfo.name), - txtfilename, pdbfilename, eSyncNone); - syncInfo.dbinfo=dbinfo; - needsSync(syncInfo); - fSyncInfoList.append(syncInfo); - fDBNames.append(TQString::fromLatin1(dbinfo.name)); - - TQTimer::singleShot(0, this, TQT_SLOT(syncNextDB())); - return; -} - - - -void DOCConduit::syncNextTXT() -{ - FUNCTIONSETUP; - - if (eSyncDirection==eSyncPDAToPC ) - { - // We don't sync from PC to PDB, so start the conflict resolution and then the actual sync process - docnames.clear(); - TQTimer::singleShot(0, this, TQT_SLOT(checkPDBFiles())); - return; - } - - // if docnames isn't initialized, get a list of all *.txt files in DOCConduitSettings::tXTDirectory() - if (docnames.isEmpty()/* || dociterator==docnames.end() */) { - docnames=TQDir( DOCConduitSettings::tXTDirectory(), CSL1("*.txt")).entryList() ; - dociterator=docnames.begin(); - } - if (dociterator==docnames.end()) { - // no more databases available, so start the conflict resolution and then the actual sync proces - docnames.clear(); - TQTimer::singleShot(0, this, TQT_SLOT(checkPDBFiles())); - return; - } - - TQString fn=(*dociterator); - - TQDir dr( DOCConduitSettings::tXTDirectory() ); - TQFileInfo fl(dr, fn ); - TQString txtfilename=fl.absFilePath(); - TQString pdbfilename; - ++dociterator; - - DBInfo dbinfo; - // Include all "extensions" except the last. This allows full stops inside the database name (e.g. abbreviations) - // first fill everything with 0, so we won't have a buffer overflow. - memset(&dbinfo.name[0], 0, 33); - strncpy(&dbinfo.name[0], fl.baseName(TRUE).latin1(), 30); - - bool alreadySynced=fDBNames.contains(fl.baseName(TRUE)); - if (!alreadySynced) { - docSyncInfo syncInfo(TQString::fromLatin1(dbinfo.name), - txtfilename, pdbfilename, eSyncNone); - syncInfo.dbinfo=dbinfo; - needsSync(syncInfo); - fSyncInfoList.append(syncInfo); - fDBNames.append(TQString::fromLatin1(dbinfo.name)); - } else { -#ifdef DEBUG - DEBUGKPILOT<<txtfilename<<" has already been synced, skipping it."<<endl; -#endif - } - - TQTimer::singleShot(0, this, TQT_SLOT(syncNextTXT())); - return; -} - - - -/** This slot will only be used if DOCConduitSettings::keepPDBsLocally() to check if new doc databases have been copied to the pdb directory. - * If so, install it to the handheld and sync it to the PC */ -void DOCConduit::checkPDBFiles() { - FUNCTIONSETUP; - - if ( DOCConduitSettings::localSync() || !DOCConduitSettings::keepPDBsLocally() || eSyncDirection==eSyncPCToPDA ) - { - // no more databases available, so check for PC->Palm sync - TQTimer::singleShot(0, this, TQT_SLOT(checkDeletedDocs())); - return; - } - - // Walk through all files in the pdb directory and check if it has already been synced. - // if docnames isn't initialized, get a list of all *.pdb files in DOCConduitSettings::pDBDirectory() - if (docnames.isEmpty()/* || dociterator==docnames.end() */) { - docnames=TQDir(DOCConduitSettings::pDBDirectory(), CSL1("*.pdb")).entryList() ; - dociterator=docnames.begin(); - } - if (dociterator==docnames.end()) { - // no more databases available, so start the conflict resolution and then the actual sync proces - docnames.clear(); - TQTimer::singleShot(0, this, TQT_SLOT(checkDeletedDocs())); - return; - } - - TQString fn=(*dociterator); - - TQDir dr(DOCConduitSettings::pDBDirectory()); - TQFileInfo fl(dr, fn ); - TQString pdbfilename=fl.absFilePath(); - ++dociterator; - - // Get the doc title and check if it has already been synced (in the synced docs list of in fDBNames to be synced) - // If the doc title doesn't appear in either list, install it to the Handheld, and add it to the list of dbs to be synced. - TQString dbname=fl.baseName(TRUE).left(30); - if (!fDBNames.contains(dbname) && !fDBListSynced.contains(dbname)) { - if (fHandle->installFiles(pdbfilename, false)) { - DBInfo dbinfo; - // Include all "extensions" except the last. This allows full stops inside the database name (e.g. abbreviations) - // first fill everything with 0, so we won't have a buffer overflow. - memset(&dbinfo.name[0], 0, 33); - strncpy(&dbinfo.name[0], dbname.latin1(), 30); - - docSyncInfo syncInfo(dbname, constructTXTFileName(dbname), pdbfilename, eSyncNone); - syncInfo.dbinfo=dbinfo; - needsSync(syncInfo); - fSyncInfoList.append(syncInfo); - fDBNames.append(dbname); - } else { -#ifdef DEBUG - DEBUGKPILOT<<"Could not install database "<<dbname<<" ("<<pdbfilename<<") to the handheld"<<endl; -#endif - } - } - - TQTimer::singleShot(0, this, TQT_SLOT(checkPDBFiles())); -} - - - -void DOCConduit::checkDeletedDocs() -{ - FUNCTIONSETUP; - - for (TQStringList::Iterator it=fDBListSynced.begin(); it!=fDBListSynced.end(); ++it ) { - if (!fDBNames.contains(*it)) { - // We need to delete this doc: - TQString dbname(*it); - TQString txtfilename=constructTXTFileName(dbname); - TQString pdbfilename=constructPDBFileName(dbname); - docSyncInfo syncInfo(dbname, txtfilename, pdbfilename, eSyncDelete); - - DBInfo dbinfo; - memset(&dbinfo.name[0], 0, 33); - strncpy(&dbinfo.name[0], dbname.latin1(), 30); - syncInfo.dbinfo=dbinfo; - - fSyncInfoList.append(syncInfo); - } - } - TQTimer::singleShot(0, this, TQT_SLOT(resolve())); - return; -} - - - -void DOCConduit::resolve() { - FUNCTIONSETUP; - - for (fSyncInfoListIterator=fSyncInfoList.begin(); fSyncInfoListIterator!=fSyncInfoList.end(); ++fSyncInfoListIterator) { - // Walk through each database and apply the conflictResolution option. - // the remaining conflicts will be resolved in the resolution dialog - if ((*fSyncInfoListIterator).direction==eSyncConflict){ -#ifdef DEBUG - DEBUGKPILOT<<"We have a conflict for "<<(*fSyncInfoListIterator).handheldDB<<", default="<<eConflictResolution<<endl; -#endif - switch (eConflictResolution) - { - case eSyncPDAToPC: -#ifdef DEBUG - DEBUGKPILOT<<"PDA overrides for database "<<(*fSyncInfoListIterator).handheldDB<<endl; -#endif - (*fSyncInfoListIterator).direction = eSyncPDAToPC; - break; - case eSyncPCToPDA: -#ifdef DEBUG - DEBUGKPILOT<<"PC overrides for database "<<(*fSyncInfoListIterator).handheldDB<<endl; -#endif - (*fSyncInfoListIterator).direction = eSyncPCToPDA; - break; - case eSyncNone: -#ifdef DEBUG - DEBUGKPILOT<<"No sync for database "<<(*fSyncInfoListIterator).handheldDB<<endl; -#endif - (*fSyncInfoListIterator).direction = eSyncNone; - break; - case eSyncDelete: - case eSyncConflict: - default: -#ifdef DEBUG - DEBUGKPILOT<<"Conflict remains due to default resolution setting for database "<<(*fSyncInfoListIterator).handheldDB<<endl; -#endif - break; - } - } - } - - // Show the conflict resolution dialog and ask for the action for each database - ResolutionDialog*dlg=new ResolutionDialog( 0, i18n("Conflict Resolution"), &fSyncInfoList , fHandle); - bool show=DOCConduitSettings::alwaysShowResolutionDialog() || (dlg && dlg->hasConflicts); - if (show) { - if (!dlg || !dlg->exec() ) { - KPILOT_DELETE(dlg) - emit logMessage(i18n("Sync aborted by user.")); - TQTimer::singleShot(0, this, TQT_SLOT(cleanup())); - return; - } - } - KPILOT_DELETE(dlg) - - - // fDBNames will be filled with the names of the databases that are actually synced (not deleted), so I can write the list to the config file - fDBNames.clear(); - fSyncInfoListIterator=fSyncInfoList.begin(); - TQTimer::singleShot(0,this, TQT_SLOT(syncDatabases())); - return; -} - - - -void DOCConduit::syncDatabases() { - FUNCTIONSETUP; - if (fSyncInfoListIterator==fSyncInfoList.end()) { - // We're done, so clean up - TQTimer::singleShot(0, this, TQT_SLOT(cleanup())); - return; - } - - docSyncInfo sinfo=(*fSyncInfoListIterator); - ++fSyncInfoListIterator; - - switch (sinfo.direction) { - case eSyncConflict: -#ifdef DEBUG - DEBUGKPILOT<<"Entry "<<sinfo.handheldDB<<"( txtfilename: "<<sinfo.txtfilename<< - ", pdbfilename: "<<sinfo.pdbfilename<<") had sync direction eSyncConflict!!!"<<endl; -#endif - break; - case eSyncDelete: - case eSyncPDAToPC: - case eSyncPCToPDA: - emit logMessage(i18n("Synchronizing text \"%1\"").arg(sinfo.handheldDB)); - if (!doSync(sinfo)) { - // The sync could not be done, so inform the user (the error message should probably issued inside doSync) -#ifdef DEBUG - DEBUGKPILOT<<"There was some error syncing the text \""<<sinfo.handheldDB<<"\" with the file "<<sinfo.txtfilename<<endl; -#endif - } - break; - case eSyncNone: -// case eSyncAll: - break; - } - if (sinfo.direction != eSyncDelete) fDBNames.append(sinfo.handheldDB); - - TQTimer::singleShot(0,this, TQT_SLOT(syncDatabases())); - return; -} - - -PilotDatabase*DOCConduit::openDOCDatabase(const TQString &dbname) { - if (DOCConduitSettings::localSync()) - { - return new PilotLocalDatabase(DOCConduitSettings::pDBDirectory(), dbname, false); - } - else - { - return deviceLink()->database( dbname ); - } -} - - -bool DOCConduit::needsSync(docSyncInfo &sinfo) -{ - FUNCTIONSETUP; - sinfo.direction = eSyncNone; - - PilotDatabase*docdb=openDOCDatabase(TQString::fromLatin1(sinfo.dbinfo.name)); - if (!fDBListSynced.contains(sinfo.handheldDB)) { - // the database wasn't included on last sync, so it has to be new. -#ifdef DEBUG - DEBUGKPILOT<<"Database "<<sinfo.dbinfo.name<<" wasn't included in the previous sync!"<<endl; -#endif - - /* Resolution Table: - PC HH | normal PC->HH HH->PC - ----------------------------------------- - N - | P P D - - N | H D H - N N | C P H - */ - - if (TQFile::exists(sinfo.txtfilename)) sinfo.fPCStatus=eStatNew; - else sinfo.fPCStatus=eStatDoesntExist; - if (docdb && docdb->isOpen()) sinfo.fPalmStatus=eStatNew; - else sinfo.fPalmStatus=eStatDoesntExist; - KPILOT_DELETE(docdb); - - switch (eSyncDirection) { - case eSyncPDAToPC: - if (sinfo.fPalmStatus==eStatDoesntExist) - sinfo.direction=eSyncDelete; - else sinfo.direction=eSyncPDAToPC; - break; - case eSyncPCToPDA: - if (sinfo.fPCStatus==eStatDoesntExist) - sinfo.direction=eSyncDelete; - else sinfo.direction=eSyncPCToPDA; - break; - case eSyncNone: // means actually both directions! - if (sinfo.fPCStatus==eStatNew) { - if (sinfo.fPalmStatus==eStatNew) sinfo.direction=eSyncConflict; - else sinfo.direction=eSyncPCToPDA; - } else { - if (sinfo.fPalmStatus==eStatNew) sinfo.direction=eSyncPDAToPC; - else { - sinfo.direction=eSyncNone; -#ifdef DEBUG - DEBUGKPILOT<<"I'm supposed to find a sync direction, but the "<< - " text "<<sinfo.dbinfo.name<<" doesn't exist on either "<< - " the handheld or the PC"<<endl; -#endif - } - } - break; - default: - break; - } - return true; - } - - // Text was included in the last sync - if (!TQFile::exists(sinfo.txtfilename)) sinfo.fPCStatus=eStatDeleted; - else if(pcTextChanged(sinfo.txtfilename)) { - sinfo.fPCStatus=eStatChanged; -#ifdef DEBUG - DEBUGKPILOT<<"PC side has changed!"<<endl; -#endif - // TODO: Check for changed bookmarks on the PC side -#ifdef DEBUG - } else { - DEBUGKPILOT<<"PC side has NOT changed!"<<endl; -#endif - } - - if (!docdb || !docdb->isOpen()) sinfo.fPalmStatus=eStatDeleted; - else if (hhTextChanged(docdb)) { -#ifdef DEBUG - DEBUGKPILOT<<"Handheld side has changed!"<<endl; -#endif - sinfo.fPalmStatus=eStatChanged; -#ifdef DEBUG - } else { - DEBUGKPILOT<<"Handheld side has NOT changed!"<<endl; -#endif - } - KPILOT_DELETE(docdb); - - - // Now that we know the status of both sides, determine what to do. - /* Resolution Table: - PC HH | normal PC->HH HH->PC - ----------------------------------------- - - - | - - - - C - | P P H - - C | H P H - C C | C P H - D - | D D H - - D | D P D - D D | D D D - ----------------------------------------- - C D | C P D - D C | C D H - */ - - - if (sinfo.fPCStatus == eStatNone && sinfo.fPalmStatus==eStatNone) { -#ifdef DEBUG - DEBUGKPILOT<<"Nothing has changed, not need for a sync."<<endl; -#endif - sinfo.direction=eSyncNone; - return false; - } - - // In all other cases, if only one direction (PC->HH or HH->PC) - // should be done, check if the DB was deleted or if we are supposed - // to sync that direction - - if (eSyncDirection==eSyncPCToPDA) { - if (sinfo.fPCStatus==eStatDeleted) sinfo.direction=eSyncDelete; - else sinfo.direction=eSyncPCToPDA; - return true; - } - if (eSyncDirection==eSyncPDAToPC) { - if (sinfo.fPalmStatus==eStatDeleted) sinfo.direction=eSyncDelete; - else sinfo.direction=eSyncPDAToPC; - return true; - } - - - // --------------------------------------------------------------- - // Finally, do the normal case, where both directions are possible - // --------------------------------------------------------------- - - - // if either is deleted, and the other is not changed, delete - if ( ((sinfo.fPCStatus==eStatDeleted) && (sinfo.fPalmStatus!=eStatChanged)) || - ((sinfo.fPalmStatus==eStatDeleted) && (sinfo.fPCStatus!=eStatChanged)) ) - { -#ifdef DEBUG - DEBUGKPILOT<<"DB was deleted on one side and not changed on " - "the other -> Delete it."<<endl; -#endif - sinfo.direction=eSyncDelete; - return true; - } - - // eStatDeleted (and both not changed) have already been treated, for all - // other values in combination with eStatNone, just copy the texts. - if (sinfo.fPCStatus==eStatNone) { -#ifdef DEBUG - DEBUGKPILOT<<"PC side has changed!"<<endl; -#endif - sinfo.direction=eSyncPDAToPC; - return true; - } - - if (sinfo.fPalmStatus==eStatNone) { - sinfo.direction=eSyncPCToPDA; - return true; - } - - // All other cases - // (deleted,changed), (changed, deleted), (changed,changed) - // create a conflict: - sinfo.direction=eSyncConflict; - return true; -} - - - -PilotDatabase *DOCConduit::preSyncAction(docSyncInfo &sinfo) const -{ - FUNCTIONSETUP; - - { - // make sure the dir for the local texts really exists! - TQDir dir( DOCConduitSettings::tXTDirectory() ); - if (!dir.exists()) - { - dir.mkdir(dir.absPath()); - } - } - - DBInfo dbinfo=sinfo.dbinfo; - switch (sinfo.direction) - { - case eSyncPDAToPC: - if (DOCConduitSettings::keepPDBsLocally()) - { - // make sure the dir for the local db really exists! - TQDir dir(DOCConduitSettings::pDBDirectory()); - - if (!dir.exists()) - { - dir.mkdir(dir.absPath()); - } -#ifdef DEBUG - DEBUGKPILOT<<"Need to fetch database "<<dbinfo.name<< - " to the directory "<<dir.absPath()<<endl; -#endif - dbinfo.flags &= ~dlpDBFlagOpen; - - if (!fHandle->retrieveDatabase(sinfo.pdbfilename, &dbinfo) ) - { - WARNINGKPILOT << "Unable to retrieve database " << dbinfo.name << - " from the handheld into " << sinfo.pdbfilename << "." << endl; - return 0L; - } - } - break; - case eSyncPCToPDA: - if (DOCConduitSettings::keepPDBsLocally()) - { - // make sure the dir for the local db really exists! - TQDir dir(DOCConduitSettings::pDBDirectory()); - if (!dir.exists()) - { - dir.mkdir(dir.absPath()); - } - } - break; - default: - break; - } - if (DOCConduitSettings::keepPDBsLocally()) - { - return new PilotLocalDatabase(DOCConduitSettings::pDBDirectory(), - TQString::fromLatin1(dbinfo.name), false); - } - else - { - return deviceLink()->database(TQString::fromLatin1(dbinfo.name)); - } -} - - -// res gives us information whether the sync worked and the db might need to be -// transferred to the handheld or not (and we just need to clean up the mess) -bool DOCConduit::postSyncAction(PilotDatabase * database, - docSyncInfo &sinfo, bool res) -{ - FUNCTIONSETUP; - bool rs = true; - - switch (sinfo.direction) - { - case eSyncPDAToPC: - // also reset the sync flags on the handheld -#ifdef DEBUG - DEBUGKPILOT<<"Resetting sync flags for database " - <<sinfo.dbinfo.name<<endl; -#endif - if (DOCConduitSettings::keepPDBsLocally() && !DOCConduitSettings::localSync()) - { - PilotDatabase*db=deviceLink()->database( - TQString::fromLatin1(sinfo.dbinfo.name)); -#ifdef DEBUG - DEBUGKPILOT<<"Middle 1 Resetting sync flags for database " - <<sinfo.dbinfo.name<<endl; -#endif - if (db) - { - db->resetSyncFlags(); - KPILOT_DELETE(db); - } - } -#ifdef DEBUG - DEBUGKPILOT<<"End Resetting sync flags for database " - <<sinfo.dbinfo.name<<endl; -#endif - break; - case eSyncPCToPDA: - if (DOCConduitSettings::keepPDBsLocally() && !DOCConduitSettings::localSync() && res) - { - // Copy the database to the palm - PilotLocalDatabase*localdb=dynamic_cast<PilotLocalDatabase*>(database); - if (localdb) - { -#ifdef DEBUG - DEBUGKPILOT<<"Installing file "<<localdb->dbPathName()<<" (" - <<sinfo.handheldDB<<") to the handheld"<<endl; -#endif - TQString dbpathname=localdb->dbPathName(); - // This deletes localdb as well, which is just a cast from database - KPILOT_DELETE(database); - if (!fHandle->installFiles(dbpathname, false)) - { - rs = false; -#ifdef DEBUG - DEBUGKPILOT<<"Could not install the database "<<dbpathname<<" (" - <<sinfo.handheldDB<<")"<<endl; -#endif - } - } - } - default: - break; - } - -#ifdef DEBUG - DEBUGKPILOT<<"Vor KPILOT_DELETE(database)"<<endl; -#endif - - KPILOT_DELETE(database); -#ifdef DEBUG - DEBUGKPILOT<<"End postSyncAction"<<endl; -#endif - return rs; -} - - - -void DOCConduit::cleanup() -{ - FUNCTIONSETUP; - DOCConduitSettings::setConvertedDOCfiles( fDBNames ); - DOCConduitSettings::self()->writeConfig(); - - emit syncDone(this); -} - |