00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "options.h"
00039
00040 #include <qtimer.h>
00041 #include <qfile.h>
00042
00043 #include "pilotAppCategory.h"
00044 #include "pilotSerialDatabase.h"
00045 #include "pilotLocalDatabase.h"
00046 #include "recordConduit.h"
00047
00048
00049
00050
00051
00052
00053 extern "C"
00054 {
00055 long version_record_conduit = Pilot::PLUGIN_API;
00056 }
00057
00058
00059 bool RecordConduitBase::exec()
00060 {
00061 FUNCTIONSETUP;
00062 fState = Initialize;
00063
00064 setFirstSync(false);
00065
00066 bool retrieved = false;
00067 if (!openDatabases( fDBName, &retrieved))
00068 {
00069 emit logError(i18n("Unable to open the %1 database on the handheld.").arg( fDBName ) );
00070 return false;
00071 }
00072 if (retrieved) setFirstSync(true);
00073
00074 if (isFirstSync()) fIDList=fDatabase->idList();
00075 else fIDList=fDatabase->modifiedIDList();
00076 fIDListIterator = fIDList.begin();
00077
00078 fTimer = new QTimer(this);
00079 connect(fTimer,SIGNAL(timeout()),this,SLOT(process()));
00080 fTimer->start(0,false);
00081 return true;
00082 }
00083
00084 void RecordConduitBase::process()
00085 {
00086 FUNCTIONSETUP;
00087 SyncProgress p = Error;
00088
00089 #ifdef DEBUG
00090 DEBUGKPILOT << fname << ": From state " << name(fState) << endl;
00091 #endif
00092
00093 switch(fState)
00094 {
00095 case Initialize :
00096 p = loadPC();
00097 break;
00098 case PalmToPC :
00099 p = palmRecToPC();
00100 break;
00101 case PCToPalm :
00102 p = pcRecToPalm();
00103 break;
00104 case Cleanup :
00105 p = cleanup();
00106 break;
00107 }
00108
00109 #ifdef DEBUG
00110 DEBUGKPILOT << fname << ": Step returned " << name(p) << endl;
00111 #endif
00112
00113 switch(p)
00114 {
00115 case Error :
00116 fTimer->stop();
00117 delayDone();
00118 return;
00119 case NotDone :
00120
00121 return;
00122 case Done :
00123
00124 break;
00125 }
00126
00127 #ifdef DEBUG
00128 DEBUGKPILOT << fname << ": Step is done, moving to next state." << endl;
00129 #endif
00130
00131
00132 switch(fState)
00133 {
00134 case Initialize :
00135 switch (syncMode().mode())
00136 {
00137 case SyncMode::eRestore :
00138 case SyncMode::eCopyPCToHH :
00139 fState = PCToPalm;
00140 break;
00141 default :
00142 fState = PalmToPC;
00143 }
00144 break;
00145 case PalmToPC :
00146 switch (syncMode().mode())
00147 {
00148 case SyncMode::eBackup :
00149 case SyncMode::eCopyHHToPC :
00150 fState = Cleanup;
00151 break;
00152 default :
00153 fState = PCToPalm;
00154 }
00155 break;
00156 case PCToPalm :
00157 fState = Cleanup;
00158 break;
00159 case Cleanup :
00160 fTimer->stop();
00161 delayDone();
00162
00163 break;
00164 }
00165
00166 #ifdef DEBUG
00167 DEBUGKPILOT << fname << ": Next state is " << name(fState) << endl;
00168 #endif
00169
00170 }
00171
00172
00173 QString RecordConduitBase::name(RecordConduitBase::SyncProgress s)
00174 {
00175 switch(s)
00176 {
00177 case RecordConduitBase::NotDone:
00178 return CSL1("NotDone");
00179 case RecordConduitBase::Done:
00180 return CSL1("Done");
00181 case RecordConduitBase::Error:
00182 return CSL1("Error");
00183 }
00184 }
00185
00186
00187 QString RecordConduitBase::name(RecordConduitBase::States s)
00188 {
00189 switch(s)
00190 {
00191 case RecordConduitBase::Initialize:
00192 return CSL1("Initialize");
00193 case RecordConduitBase::PalmToPC:
00194 return CSL1("Handheld-to-PC");
00195 case RecordConduitBase::PCToPalm:
00196 return CSL1("PC-to-Handheld");
00197 case RecordConduitBase::Cleanup:
00198 return CSL1("Cleanup");
00199 }
00200 }
00201
00202
00203 #if 0
00204
00206 bool RecordConduit::PCData::makeArchived( RecordConduit::PCEntry *pcEntry )
00207 {
00208 if ( pcEntry ) {
00209 pcEntry->makeArchived();
00210 setChanged( true );
00211 return true;
00212 } else return false;
00213 }
00214
00215
00216
00217
00218
00219 bool RecordConduit::PCData::mapContactsToPilot( QMap<recordid_t,QString> &idContactMap )
00220 {
00221 FUNCTIONSETUP;
00222
00223 idContactMap.clear();
00224
00225 Iterator it = begin();
00226 PCEntry *ent;
00227 while ( !atEnd( it ) ) {
00228 ent = *it;
00229 recordid_t id( ent->recid() );
00230 if ( id != 0 ) {
00231 idContactMap.insert( id, ent->uid() );
00232 }
00233 ++it;
00234 }
00235 #ifdef DEBUG
00236 DEBUGKPILOT << fname << ": Loaded " << idContactMap.size() <<
00237 " Entries on the pc and mapped them to records on the handheld. " << endl;
00238 #endif
00239 return true;
00240 }
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 bool RecordConduit::mArchiveDeleted = false;
00251
00252 RecordConduit::RecordConduit(QString name, KPilotDeviceLink * o, const char *n, const QStringList & a):
00253 ConduitAction(o, n, a),
00254 mPCData(0), mPalmIndex(0),
00255 mEntryMap(), mSyncedIds(), mAllIds()
00256 {
00257 FUNCTIONSETUP;
00258 fConduitName = name;
00259 }
00260
00261
00262
00263 RecordConduit::~RecordConduit()
00264 {
00265 if ( mPCData ) KPILOT_DELETE(mPCData);
00266 }
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 bool RecordConduit::exec()
00280 {
00281 FUNCTIONSETUP;
00282
00283 if ( !_prepare() ) return false;
00284
00285 fFirstSync = false;
00286
00287 if( !openDatabases( dbName(), &fFirstSync ) )
00288 {
00289 emit logError(i18n("Unable to open the %1 database on the handheld.").arg( dbName() ) );
00290 return false;
00291 }
00292 _getAppInfo();
00293 if( !mPCData->loadData() )
00294 {
00295 emit logError( i18n("Unable to open %1.").arg( mPCData->description() ) );
00296 return false;
00297 }
00298
00299
00300 if ( mPCData->isEmpty() )
00301 fFirstSync = true;
00302 else
00303 mPCData->mapContactsToPilot( mEntryMap );
00304 fFirstSync = fFirstSync || ( mPCData->isEmpty() );
00305
00306
00307
00308 mPalmIndex = 0;
00309
00310 #ifdef DEBUG
00311 DEBUGKPILOT << fname << ": fullsync=" << isFullSync() << ", firstSync=" << isFirstSync() << endl;
00312 DEBUGKPILOT << fname << ": "
00313 << "syncDirection=" << getSyncDirection() << ", "
00314
00315 << endl;
00316 DEBUGKPILOT << fname << ": conflictRes="<< getConflictResolution() << endl;
00317
00318 #endif
00319
00320 if ( !isFirstSync() )
00321 mAllIds=fDatabase->idList();
00322
00323
00324
00325
00326
00327
00328
00329
00330 QTimer::singleShot(0, this, SLOT(slotPalmRecToPC()));
00331
00332 return true;
00333 }
00334
00335
00336
00337 void RecordConduit::slotPalmRecToPC()
00338 {
00339 FUNCTIONSETUP;
00340 PilotRecord *palmRec = 0L, *backupRec = 0L;
00341
00342 if ( getSyncDirection() == SyncAction::eCopyPCToHH )
00343 {
00344 mPCIter = mPCData->begin();
00345 QTimer::singleShot(0, this, SLOT(slotPCRecToPalm()));
00346 return;
00347 }
00348
00349 if ( isFullSync() )
00350 palmRec = fDatabase->readRecordByIndex( mPalmIndex++ );
00351 else
00352 palmRec = dynamic_cast <PilotSerialDatabase * >(fDatabase)->readNextModifiedRec();
00353
00354 if ( !palmRec )
00355 {
00356 mPCIter = mPCData->begin();
00357 QTimer::singleShot( 0, this, SLOT( slotPCRecToPalm() ) );
00358 return;
00359 }
00360
00361
00362 if ( mSyncedIds.contains( palmRec->id() ) )
00363 {
00364 KPILOT_DELETE( palmRec );
00365 QTimer::singleShot( 0, this, SLOT( slotPalmRecToPC() ) );
00366 return;
00367 }
00368
00369 backupRec = fLocalDatabase->readRecordById( palmRec->id() );
00370 PilotRecord *compareRec = backupRec ? backupRec : palmRec;
00371 PilotAppCategory *compareEntry = createPalmEntry( compareRec );
00372 PCEntry *pcEntry = findMatch( compareEntry );
00373 KPILOT_DELETE( compareEntry );
00374
00375 PilotAppCategory *backupEntry=0L;
00376 if ( backupRec )
00377 backupEntry = createPalmEntry( backupRec );
00378 PilotAppCategory *palmEntry=0L;
00379 if ( palmRec )
00380 palmEntry = createPalmEntry( palmRec );
00381
00382 syncEntry( pcEntry, backupEntry, palmEntry );
00383
00384 mSyncedIds.append( palmRec->id() );
00385
00386 KPILOT_DELETE( pcEntry );
00387 KPILOT_DELETE( palmEntry );
00388 KPILOT_DELETE( backupEntry );
00389 KPILOT_DELETE( palmRec );
00390 KPILOT_DELETE( backupRec );
00391
00392 QTimer::singleShot(0, this, SLOT(slotPalmRecToPC()));
00393 }
00394
00395
00396
00397 void RecordConduit::slotPCRecToPalm()
00398 {
00399 FUNCTIONSETUP;
00400
00401 if ( ( getSyncDirection()==SyncAction::eCopyHHToPC ) ||
00402 mPCData->atEnd( mPCIter ) )
00403 {
00404 mPalmIndex = 0;
00405 QTimer::singleShot( 0, this, SLOT( slotDeletedRecord() ) );
00406 return;
00407 }
00408
00409 PilotRecord *backupRec=0L;
00410 PCEntry *pcEntry = *mPCIter;
00411 ++mPCIter;
00412
00413
00414 if ( isArchived( pcEntry ) )
00415 {
00416 #ifdef DEBUG
00417 DEBUGKPILOT << fname << ": address with id " << pcEntry->uid() <<
00418 " marked archived, so don't sync." << endl;
00419 #endif
00420 KPILOT_DELETE( pcEntry );
00421 QTimer::singleShot( 0, this, SLOT( slotPCRecToPalm() ) );
00422 return;
00423 }
00424
00425 recordid_t recID( pcEntry->recid() );
00426 if ( recID == 0 )
00427 {
00428
00429 syncEntry( pcEntry, 0L, 0L );
00430 KPILOT_DELETE( pcEntry );
00431 QTimer::singleShot( 0, this, SLOT( slotPCRecToPalm() ) );
00432 return;
00433 }
00434
00435
00436 if ( mSyncedIds.contains( recID ) )
00437 {
00438 #ifdef DEBUG
00439 DEBUGKPILOT << ": address with id " << recID << " already synced." << endl;
00440 #endif
00441 KPILOT_DELETE( pcEntry );
00442 QTimer::singleShot( 0, this, SLOT( slotPCRecToPalm() ) );
00443 return;
00444 }
00445
00446
00447 backupRec = fLocalDatabase->readRecordById( recID );
00448
00449
00450 PilotAppCategory*backupEntry=0L;
00451 if ( backupRec )
00452 backupEntry = createPalmEntry( backupRec );
00453 if( !backupRec || isFirstSync() || !_equal( backupEntry, pcEntry ) )
00454 {
00455 PilotRecord *palmRec = fDatabase->readRecordById( recID );
00456 PilotAppCategory *palmEntry=0L;
00457 if (palmRec)
00458 palmEntry = createPalmEntry( palmRec );
00459 syncEntry( pcEntry, backupEntry, palmEntry );
00460
00461 if ( palmRec )
00462 recID = palmRec->id();
00463 KPILOT_DELETE( palmRec );
00464 KPILOT_DELETE( palmEntry );
00465 }
00466
00467 KPILOT_DELETE( pcEntry );
00468 KPILOT_DELETE( backupEntry );
00469 KPILOT_DELETE( backupRec );
00470 mSyncedIds.append( recID );
00471
00472
00473 QTimer::singleShot( 0, this, SLOT( slotPCRecToPalm() ) );
00474 }
00475
00476
00477
00478 void RecordConduit::slotDeletedRecord()
00479 {
00480 FUNCTIONSETUP;
00481
00482 PilotRecord *backupRec = fLocalDatabase->readRecordByIndex( mPalmIndex++ );
00483 if( !backupRec || isFirstSync() )
00484 {
00485 KPILOT_DELETE(backupRec);
00486 QTimer::singleShot( 0, this, SLOT( slotDeleteUnsyncedPCRecords() ) );
00487 return;
00488 }
00489
00490
00491 if ( mSyncedIds.contains( backupRec->id() ) )
00492 {
00493 KPILOT_DELETE( backupRec );
00494 QTimer::singleShot( 0, this, SLOT( slotDeletedRecord() ) );
00495 return;
00496 }
00497
00498 QString uid = mEntryMap[ backupRec->id() ];
00499 PCEntry *pcEntry = mPCData->findByUid( uid );
00500 PilotRecord *palmRec = fDatabase->readRecordById( backupRec->id() );
00501 PilotAppCategory *backupEntry = 0L;
00502 if (backupRec)
00503 backupEntry = createPalmEntry( backupRec );
00504 PilotAppCategory*palmEntry=0L;
00505 if (palmRec)
00506 palmEntry = createPalmEntry( palmRec );
00507
00508 mSyncedIds.append( backupRec->id() );
00509 syncEntry( pcEntry, backupEntry, palmEntry );
00510
00511 KPILOT_DELETE( pcEntry );
00512 KPILOT_DELETE( palmEntry );
00513 KPILOT_DELETE( backupEntry );
00514 KPILOT_DELETE( palmRec );
00515 KPILOT_DELETE( backupRec );
00516 QTimer::singleShot( 0, this, SLOT( slotDeletedRecord() ) );
00517 }
00518
00519
00520
00521 void RecordConduit::slotDeleteUnsyncedPCRecords()
00522 {
00523 FUNCTIONSETUP;
00524 if ( getSyncDirection() == SyncAction::eCopyHHToPC )
00525 {
00526 QStringList uids;
00527 RecordIDList::iterator it;
00528 QString uid;
00529 for ( it = mSyncedIds.begin(); it != mSyncedIds.end(); ++it)
00530 {
00531 uid = mEntryMap[ *it ];
00532 if ( !uid.isEmpty() ) uids.append( uid );
00533 }
00534
00535
00536 const QStringList alluids( mPCData->uids() );
00537 QStringList::ConstIterator uidit;
00538 for ( uidit = alluids.constBegin(); uidit != alluids.constEnd(); ++uidit )
00539 {
00540 if ( !uids.contains( *uidit ) )
00541 {
00542 #ifdef DEBUG
00543 DEBUGKPILOT << "Deleting PCEntry with uid " << (*uidit) << " from PC (is not on HH, and syncing with HH->PC direction)" << endl;
00544 #endif
00545 mPCData->removeEntry( *uidit );
00546 }
00547 }
00548 }
00549 QTimer::singleShot(0, this, SLOT(slotDeleteUnsyncedHHRecords()));
00550 }
00551
00552
00553
00554 void RecordConduit::slotDeleteUnsyncedHHRecords()
00555 {
00556 FUNCTIONSETUP;
00557 if ( getSyncDirection() == SyncAction::eCopyPCToHH )
00558 {
00559 RecordIDList ids = fDatabase->idList();
00560 RecordIDList::iterator it;
00561 for ( it = ids.begin(); it != ids.end(); ++it )
00562 {
00563 if ( !mSyncedIds.contains(*it) )
00564 {
00565 #ifdef DEBUG
00566 DEBUGKPILOT << "Deleting record with ID " << *it << " from handheld (is not on PC, and syncing with PC->HH direction)" << endl;
00567 #endif
00568 fDatabase->deleteRecord(*it);
00569 fLocalDatabase->deleteRecord(*it);
00570 }
00571 }
00572 }
00573 QTimer::singleShot( 0, this, SLOT( slotCleanup() ) );
00574 }
00575
00576
00577 void RecordConduit::slotCleanup()
00578 {
00579 FUNCTIONSETUP;
00580
00581
00582 _setAppInfo();
00583 doPostSync();
00584 if(fDatabase)
00585 {
00586 fDatabase->resetSyncFlags();
00587 fDatabase->cleanup();
00588 }
00589 if(fLocalDatabase)
00590 {
00591 fLocalDatabase->resetSyncFlags();
00592 fLocalDatabase->cleanup();
00593 }
00594 KPILOT_DELETE( fDatabase );
00595 KPILOT_DELETE( fLocalDatabase );
00596
00597 mPCData->saveData();
00598 mPCData->cleanup();
00599 emit syncDone(this);
00600 }
00601
00602
00605 const QStringList RecordConduit::categories() const
00606 {
00607 QStringList cats;
00608 for ( unsigned int j = 0; j < Pilot::CATEGORY_COUNT; j++ ) {
00609 QString catName( category( j ) );
00610 if ( !catName.isEmpty() ) cats << catName;
00611 }
00612 return cats;
00613 }
00614 int RecordConduit::findFlags() const
00615 {
00616 return eqFlagsAlmostAll;
00617 }
00618
00619
00620 bool RecordConduit::isDeleted( const PilotAppCategory *palmEntry )
00621 {
00622 if ( !palmEntry )
00623 return true;
00624 if ( palmEntry->isDeleted() && !palmEntry->isArchived() )
00625 return true;
00626 if ( palmEntry->isArchived() )
00627 return !archiveDeleted();
00628 return false;
00629 }
00630 bool RecordConduit::isArchived( const PilotAppCategory *palmEntry )
00631 {
00632 if ( palmEntry && palmEntry->isArchived() )
00633 return archiveDeleted();
00634 else
00635 return false;
00636 }
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647 bool RecordConduit::_prepare()
00648 {
00649 FUNCTIONSETUP;
00650
00651 readConfig();
00652 mSyncedIds.clear();
00653 mPCData = initializePCData();
00654
00655 return mPCData && doPrepare();
00656 }
00657
00658
00659 void RecordConduit::_getAppInfo()
00660 {
00661 FUNCTIONSETUP;
00662
00663 unsigned char *buffer = new unsigned char[Pilot::MAX_APPINFO_SIZE];
00664 int appLen=fDatabase->readAppBlock(buffer, Pilot::MAX_APPINFO_SIZE);
00665
00666 doUnpackAppInfo( buffer, appLen );
00667 delete[] buffer;
00668 buffer = 0;
00669 }
00670
00671 void RecordConduit::_setAppInfo()
00672 {
00673 FUNCTIONSETUP;
00674
00675 int appLen = 0;
00676 unsigned char *buffer = doPackAppInfo( &appLen );
00677 if ( buffer )
00678 { if (fDatabase)
00679 fDatabase->writeAppBlock( buffer, appLen );
00680 if (fLocalDatabase)
00681 fLocalDatabase->writeAppBlock( buffer, appLen );
00682 delete[] buffer;
00683 }
00684 }
00685
00686
00687 int RecordConduit::compareStr( const QString & str1, const QString & str2 )
00688 {
00689
00690 if ( str1.isEmpty() && str2.isEmpty() )
00691 return 0;
00692 else
00693 return str1.compare( str2 );
00694 }
00695
00696
00704 QString RecordConduit::getCatForHH( const QStringList cats, const QString curr ) const
00705 {
00706 FUNCTIONSETUP;
00707 if ( cats.size() < 1 )
00708 return QString::null;
00709 if ( cats.contains( curr ) )
00710 return curr;
00711 for ( QStringList::ConstIterator it = cats.begin(); it != cats.end(); ++it)
00712 {
00713 for ( unsigned int j = 0; j < Pilot::CATEGORY_COUNT; j++ )
00714 {
00715 QString catnm( category( j ) );
00716 if ( !(*it).isEmpty() && ( (*it)==catnm ) )
00717 {
00718 return catnm;
00719 }
00720 }
00721 }
00722
00723 QString lastCat( category( Pilot::CATEGORY_COUNT-1 ) );
00724 return ( lastCat.isEmpty() ) ? ( cats.first() ) : ( QString::null );
00725 }
00726
00727 void RecordConduit::setCategory(PCEntry * pcEntry, QString cat)
00728 {
00729 if ( !cat.isEmpty() && cat!=category( 0 ) )
00730 pcEntry->insertCategory(cat);
00731 }
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745 bool RecordConduit::syncEntry( PCEntry *pcEntry, PilotAppCategory*backupEntry,
00746 PilotAppCategory*palmEntry)
00747 {
00748 FUNCTIONSETUP;
00749
00750 if ( getSyncDirection() == SyncAction::eCopyPCToHH )
00751 {
00752 if ( pcEntry->isEmpty() )
00753 {
00754 return pcDeleteEntry( pcEntry, backupEntry, palmEntry );
00755 }
00756 else
00757 {
00758 return pcCopyToPalm( pcEntry, backupEntry, palmEntry );
00759 }
00760 }
00761
00762 if ( getSyncDirection() == SyncAction::eCopyHHToPC )
00763 {
00764 if (!palmEntry)
00765 return pcDeleteEntry(pcEntry, backupEntry, palmEntry);
00766 else
00767 return palmCopyToPC(pcEntry, backupEntry, palmEntry);
00768 }
00769
00770 if ( !backupEntry || isFirstSync() )
00771 {
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783 if ( !palmEntry && isArchived( pcEntry ) )
00784 {
00785 return true;
00786 }
00787 else if ( !palmEntry && !pcEntry->isEmpty() )
00788 {
00789
00790 bool res = pcCopyToPalm( pcEntry, 0L, 0L );
00791 return res;
00792 }
00793 else if ( !palmEntry && pcEntry->isEmpty() )
00794 {
00795
00796 return false;
00797 }
00798 else if ( ( isDeleted( palmEntry ) || isArchived( palmEntry ) ) && pcEntry->isEmpty())
00799 {
00800 if ( isArchived( palmEntry ) )
00801 return palmCopyToPC( pcEntry, 0L, palmEntry );
00802 else
00803
00804 return pcDeleteEntry( pcEntry, 0L, palmEntry );
00805 }
00806 else if ( ( isDeleted(palmEntry) || isArchived( palmEntry ) ) && !pcEntry->isEmpty() )
00807 {
00808
00809 return smartMergeEntry( pcEntry, 0L, palmEntry );
00810 }
00811 else if ( pcEntry->isEmpty() )
00812 {
00813
00814 return palmCopyToPC( pcEntry, 0L, palmEntry );
00815 }
00816 else
00817 {
00818
00819 return smartMergeEntry( pcEntry, 0L, palmEntry );
00820 }
00821 }
00822 else
00823 {
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836 if ( !palmEntry || isDeleted(palmEntry) )
00837 {
00838 if ( _equal( backupEntry, pcEntry ) || pcEntry->isEmpty() )
00839 {
00840 return pcDeleteEntry( pcEntry, backupEntry, 0L );
00841 }
00842 else
00843 {
00844 return smartMergeEntry( pcEntry, backupEntry, 0L );
00845 }
00846 }
00847 else if ( pcEntry->isEmpty() )
00848 {
00849 if (*palmEntry == *backupEntry)
00850 {
00851 return pcDeleteEntry( pcEntry, backupEntry, palmEntry );
00852 }
00853 else
00854 {
00855 return smartMergeEntry( pcEntry, backupEntry, palmEntry );
00856 }
00857 }
00858 else if ( _equal( palmEntry, pcEntry ) )
00859 {
00860
00861 return backupSaveEntry( palmEntry );
00862 }
00863 else if ( _equal( backupEntry, pcEntry ) )
00864 {
00865 #ifdef DEBUG
00866 DEBUGKPILOT << "Flags: " << palmEntry->getAttrib() << ", isDeleted=" <<
00867 isDeleted( palmEntry ) << ", isArchived=" << isArchived( palmEntry )
00868 << endl;
00869 #endif
00870 if ( isDeleted( palmEntry ) )
00871 {
00872 return pcDeleteEntry( pcEntry, backupEntry, palmEntry );
00873 }
00874 else
00875 {
00876 return palmCopyToPC( pcEntry, backupEntry, palmEntry );
00877 }
00878 }
00879 else if ( *palmEntry == *backupEntry )
00880 {
00881 return pcCopyToPalm( pcEntry, backupEntry, palmEntry );
00882 }
00883 else
00884 {
00885
00886 return smartMergeEntry( pcEntry, backupEntry, palmEntry );
00887 }
00888 }
00889 return false;
00890 }
00891
00892 bool RecordConduit::pcCopyToPalm( PCEntry *pcEntry, PilotAppCategory *backupEntry,
00893 PilotAppCategory*palmEntry )
00894 {
00895 FUNCTIONSETUP;
00896
00897 if ( pcEntry->isEmpty() ) return false;
00898 PilotAppCategory *hhEntry = palmEntry;
00899 bool hhEntryCreated = false;
00900 if ( !hhEntry )
00901 {
00902 hhEntry = createPalmEntry( 0 );
00903 hhEntryCreated=true;
00904 }
00905 _copy( hhEntry, pcEntry );
00906 #ifdef DEBUG
00907 DEBUGKPILOT << "palmEntry->id=" << hhEntry->id() << ", pcEntry.ID=" <<
00908 pcEntry->uid() << endl;
00909 #endif
00910
00911 if( palmSaveEntry( hhEntry, pcEntry ) )
00912 {
00913 #ifdef DEBUG
00914 DEBUGKPILOT << "Entry palmEntry->id=" <<
00915 hhEntry->id() << "saved to palm, now updating pcEntry->uid()=" << pcEntry->uid() << endl;
00916 #endif
00917 pcSaveEntry( pcEntry, backupEntry, hhEntry );
00918 }
00919 if ( hhEntryCreated ) KPILOT_DELETE( hhEntry );
00920 return true;
00921 }
00922
00923
00924
00925
00926 bool RecordConduit::palmCopyToPC( PCEntry *pcEntry, PilotAppCategory *backupEntry,
00927 PilotAppCategory *palmEntry )
00928 {
00929 FUNCTIONSETUP;
00930 if ( !palmEntry )
00931 {
00932 return false;
00933 }
00934 _copy( pcEntry, palmEntry );
00935 pcSaveEntry( pcEntry, backupEntry, palmEntry );
00936 backupSaveEntry( palmEntry );
00937 return true;
00938 }
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949 bool RecordConduit::palmSaveEntry( PilotAppCategory *palmEntry, PCEntry *pcEntry )
00950 {
00951 FUNCTIONSETUP;
00952
00953 #ifdef DEBUG
00954 DEBUGKPILOT << "Saving to pilot " << palmEntry->id() << endl;
00955 #endif
00956
00957 PilotRecord *pilotRec = palmEntry->pack();
00958 recordid_t pilotId = fDatabase->writeRecord(pilotRec);
00959 #ifdef DEBUG
00960 DEBUGKPILOT << "PilotRec nach writeRecord (" << pilotId <<
00961 ": ID=" << pilotRec->id() << endl;
00962 #endif
00963 fLocalDatabase->writeRecord( pilotRec );
00964 KPILOT_DELETE( pilotRec );
00965
00966
00967 if ( pilotId != 0 )
00968 {
00969 palmEntry->setID( pilotId );
00970 if ( !mSyncedIds.contains( pilotId ) )
00971 {
00972 mSyncedIds.append( pilotId );
00973 }
00974 }
00975
00976 recordid_t hhId( pcEntry->recid() );
00977 if ( hhId != pilotId )
00978 {
00979 pcEntry->setRecid( pilotId );
00980 return true;
00981 }
00982
00983 return false;
00984 }
00985
00986
00987
00988 bool RecordConduit::backupSaveEntry( PilotAppCategory *backup )
00989 {
00990 FUNCTIONSETUP;
00991 if ( !backup ) return false;
00992
00993
00994 #ifdef DEBUG
00995
00996 #endif
00997 PilotRecord *pilotRec = backup->pack();
00998 fLocalDatabase->writeRecord( pilotRec );
00999 KPILOT_DELETE( pilotRec );
01000 return true;
01001 }
01002
01003
01004
01005 bool RecordConduit::pcSaveEntry( PCEntry *pcEntry, PilotAppCategory *,
01006 PilotAppCategory * )
01007 {
01008 FUNCTIONSETUP;
01009
01010 #ifdef DEBUG
01011 DEBUGKPILOT << "Before _savepcEntry, pcEntry->uid()=" <<
01012 pcEntry->uid() << endl;
01013 #endif
01014 if ( pcEntry->recid() != 0 )
01015 {
01016 mEntryMap.insert( pcEntry->recid(), pcEntry->uid() );
01017 }
01018
01019 mPCData->updateEntry( pcEntry );
01020 return true;
01021 }
01022
01023
01024
01025 bool RecordConduit::pcDeleteEntry( PCEntry *pcEntry, PilotAppCategory *backupEntry,
01026 PilotAppCategory *palmEntry )
01027 {
01028 FUNCTIONSETUP;
01029
01030 if ( palmEntry )
01031 {
01032 if ( !mSyncedIds.contains( palmEntry->id() ) )
01033 {
01034 mSyncedIds.append(palmEntry->id());
01035 }
01036 palmEntry->makeDeleted();
01037 PilotRecord *pilotRec = palmEntry->pack();
01038 pilotRec->setDeleted();
01039 mPalmIndex--;
01040 fDatabase->writeRecord( pilotRec );
01041 fLocalDatabase->writeRecord( pilotRec );
01042 mSyncedIds.append( pilotRec->id() );
01043 KPILOT_DELETE( pilotRec );
01044 }
01045 else if ( backupEntry )
01046 {
01047 if ( !mSyncedIds.contains( backupEntry->id() ) )
01048 {
01049 mSyncedIds.append( backupEntry->id() );
01050 }
01051 backupEntry->makeDeleted();
01052 PilotRecord *pilotRec = backupEntry->pack();
01053 pilotRec->setDeleted();
01054 mPalmIndex--;
01055 fLocalDatabase->writeRecord( pilotRec );
01056 mSyncedIds.append( pilotRec->id() );
01057 KPILOT_DELETE( pilotRec );
01058 }
01059 if ( !pcEntry->isEmpty() )
01060 {
01061 #ifdef DEBUG
01062 DEBUGKPILOT << fname << " removing " << pcEntry->uid() << endl;
01063 #endif
01064 mPCData->removeEntry( pcEntry );
01065 }
01066 return true;
01067 }
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089 RecordConduit::PCEntry *RecordConduit::findMatch( PilotAppCategory *palmEntry ) const
01090 {
01091 FUNCTIONSETUP;
01092 if ( !palmEntry )
01093 return 0;
01094
01095
01096
01097 if( !isFirstSync() && ( palmEntry->id() > 0) )
01098 {
01099 QString id( mEntryMap[palmEntry->id()] );
01100 #ifdef DEBUG
01101 DEBUGKPILOT << fname << ": PilotRecord has id " << palmEntry->id() << ", mapped to " << id << endl;
01102 #endif
01103 if( !id.isEmpty() )
01104 {
01105 PCEntry *res = mPCData->findByUid( id );
01106 if ( !res && !res->isEmpty() ) return res;
01107 KPILOT_DELETE( res );
01108 #ifdef DEBUG
01109 DEBUGKPILOT << fname << ": PilotRecord has id " << palmEntry->id() <<
01110 ", but could not be found on the PC side" << endl;
01111 #endif
01112 }
01113 }
01114
01115 for ( PCData::Iterator iter = mPCData->begin(); !mPCData->atEnd( iter ); ++iter )
01116 {
01117 PCEntry *abEntry = *iter;
01118 recordid_t rid( abEntry->recid() );
01119 if ( rid>0 )
01120 {
01121 if ( rid == palmEntry->id() )
01122 return abEntry;
01123
01124
01125 }
01126
01127 if ( _equal( palmEntry, abEntry, eqFlagsAlmostAll ) )
01128 {
01129 return abEntry;
01130 }
01131 KPILOT_DELETE( abEntry );
01132 }
01133 #ifdef DEBUG
01134 DEBUGKPILOT << fname << ": Could not find any entry matching Palm record with id " << QString::number( palmEntry->id() ) << endl;
01135 #endif
01136 return 0;
01137 }
01138
01139 #endif
01140
01141
01142
01143
01144 #include "recordConduit.moc"
01145