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