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 #include "options.h"
00034 #include "abbrowser-conduit.moc"
00035
00036 #include <unistd.h>
00037
00038 #include <qtimer.h>
00039 #include <qvbuttongroup.h>
00040 #include <qcheckbox.h>
00041 #include <qtextcodec.h>
00042
00043 #include <kglobal.h>
00044 #include <kdebug.h>
00045 #include <kconfig.h>
00046 #include <kabc/addressbook.h>
00047 #include <kabc/stdaddressbook.h>
00048
00049 #include <pilotUser.h>
00050 #include <pilotSerialDatabase.h>
00051
00052 #include "abbrowser-factory.h"
00053 #include "resolutionDialog.h"
00054
00055
00056
00057
00058
00059 const char *abbrowser_conduit_id="$Id: abbrowser-conduit.cc,v 1.54.2.10 2003/07/30 23:46:20 kainhofe Exp $";
00060
00061 const QString AbbrowserConduit::flagString=CSL1("Flag");
00062 const QString AbbrowserConduit::appString=CSL1("KPILOT");
00063 const QString AbbrowserConduit::idString=CSL1("RecordID");
00064
00065 bool AbbrowserConduit::fPilotStreetHome=true;
00066 bool AbbrowserConduit::fPilotFaxHome=true;
00067 enum AbbrowserConduit::ePilotOtherEnum AbbrowserConduit::ePilotOther=AbbrowserConduit::eOtherPhone;
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 AbbrowserConduit::AbbrowserConduit(KPilotDeviceLink * o, const char *n, const QStringList & a):
00080 ConduitAction(o, n, a),
00081 addresseeMap(),
00082 syncedIds(),
00083 aBook(0L),
00084 abiter()
00085 {
00086 FUNCTIONSETUP;
00087 #ifdef DEBUG
00088 DEBUGCONDUIT<<abbrowser_conduit_id<<endl;
00089 #endif
00090 }
00091
00092
00093
00094 AbbrowserConduit::~AbbrowserConduit()
00095 {
00096 FUNCTIONSETUP;
00097 }
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 void AbbrowserConduit::_mapContactsToPilot(QMap < recordid_t, QString > &idContactMap) const
00114 {
00115 FUNCTIONSETUP;
00116
00117 idContactMap.clear();
00118
00119 for(KABC::AddressBook::Iterator contactIter = aBook->begin();
00120 contactIter != aBook->end(); ++contactIter)
00121 {
00122 KABC::Addressee aContact = *contactIter;
00123 QString recid = aContact.custom(appString, idString);
00124 if(!recid.isEmpty())
00125 {
00126 recordid_t id = recid.toULong();
00127 idContactMap.insert(id, aContact.uid());
00128 }
00129 }
00130 #ifdef DEBUG
00131 DEBUGCONDUIT << fname << ": Loaded " << idContactMap.size() <<
00132 " addresses from the addressbook " <<
00133 dynamic_cast <KABC::StdAddressBook*>(aBook)->fileName() << endl;
00134 #endif
00135 }
00136
00137
00138
00139 bool AbbrowserConduit::_prepare()
00140 {
00141 FUNCTIONSETUP;
00142
00143 readConfig();
00144 syncedIds.clear();
00145
00146 return true;
00147 }
00148
00149
00150
00151 void AbbrowserConduit::readConfig()
00152 {
00153 FUNCTIONSETUP;
00154
00155 KConfigGroupSaver g(fConfig, AbbrowserConduitFactory::group());
00156
00157 fSmartMerge=fConfig->readBoolEntry(AbbrowserConduitFactory::smartMerge(), true);
00158 fConflictResolution=(EConflictResolution) fConfig->readNumEntry(AbbrowserConduitFactory::conflictResolution(), eUserChoose);
00159 fArchive=fConfig->readBoolEntry(AbbrowserConduitFactory::archiveDeletedRecs(), true);
00160 fPilotStreetHome=!fConfig->readBoolEntry(AbbrowserConduitFactory::streetType(), true);
00161 fPilotFaxHome=!fConfig->readBoolEntry(AbbrowserConduitFactory::faxType(), true);
00162 syncAction=fConfig->readNumEntry(AbbrowserConduitFactory::syncMode(), SYNC_FAST);
00163 fFirstTime=fConfig->readBoolEntry(AbbrowserConduitFactory::firstSync(), false);
00164 ePilotOther=(ePilotOtherEnum)(fConfig->readNumEntry(AbbrowserConduitFactory::otherField(), eOtherPhone));
00165
00166 #ifdef DEBUG
00167 DEBUGCONDUIT << fname
00168 << ": Settings "
00169 << " fSmartMerge=" << fSmartMerge
00170 << " fConflictResolution=" << fConflictResolution
00171 << " fPilotStreetHome=" << fPilotStreetHome
00172 << " fPilotFaxHome=" << fPilotFaxHome
00173 << " syncAction=" << syncAction
00174 << " fArchive=" << fArchive
00175 << " fFirstTime=" << fFirstTime << endl;
00176 #endif
00177 }
00178
00179
00180
00181 bool AbbrowserConduit::_loadAddressBook()
00182 {
00183 FUNCTIONSETUP;
00184 aBook = KABC::StdAddressBook::self();
00185 aBook->load();
00186 abChanged = false;
00187
00188
00189 if(aBook->begin() == aBook->end())
00190 {
00191 fFirstTime = true;
00192 }
00193 else
00194 {
00195 _mapContactsToPilot(addresseeMap);
00196 }
00197 return(aBook != 0L);
00198 }
00199
00200
00201
00202 bool AbbrowserConduit::_saveAddressBook()
00203 {
00204 FUNCTIONSETUP;
00205
00206 if(!abChanged) return true;
00207 return StdAddressBook::save();
00208 }
00209
00210
00211
00212 void AbbrowserConduit::_setAppInfo()
00213 {
00214 FUNCTIONSETUP;
00215
00216 unsigned char *buffer = new unsigned char[PilotAddress::APP_BUFFER_SIZE];
00217 int appLen=fDatabase->readAppBlock(buffer, PilotAddress::APP_BUFFER_SIZE);
00218
00219 unpack_AddressAppInfo(&fAddressAppInfo, buffer, appLen);
00220 delete[]buffer;
00221 buffer = NULL;
00222
00223 #ifdef DEBUG
00224 DEBUGCONDUIT << fname << " lastUniqueId" << fAddressAppInfo.category.lastUniqueID << endl;
00225 for(int i = 0; i < 16; i++)
00226 {
00227 DEBUGCONDUIT << fname << " cat " << i << " =" << fAddressAppInfo.category.name[i] << endl;
00228 }
00229
00230 for(int x = 0; x < 8; x++)
00231 {
00232 DEBUGCONDUIT << fname << " phone[" << x << "] = " << fAddressAppInfo.phoneLabels[x] << endl;
00233 }
00234 #endif
00235 }
00236
00237
00238 QString AbbrowserConduit::getOtherField(const KABC::Addressee & abEntry)
00239 {
00240 switch(ePilotOther)
00241 {
00242 case eOtherPhone:
00243 return abEntry.phoneNumber(0).number();
00244 case eAssistant:
00245 return abEntry.custom(CSL1("KADDRESSBOOK"), CSL1("AssistantsName"));
00246 case eBusinessFax:
00247 return abEntry.phoneNumber(KABC::PhoneNumber::Fax | KABC::PhoneNumber::Work).number();
00248 case eCarPhone:
00249 return abEntry.phoneNumber(KABC::PhoneNumber::Car).number();
00250 case eEmail2:
00251 return abEntry.emails().first();
00252 case eHomeFax:
00253 return abEntry.phoneNumber(KABC::PhoneNumber::Fax | KABC::PhoneNumber::Home).number();
00254 case eTelex:
00255 return abEntry.phoneNumber(KABC::PhoneNumber::Bbs).number();
00256 case eTTYTTDPhone:
00257 return abEntry.phoneNumber(KABC::PhoneNumber::Pcs).number();
00258 default:
00259 return QString::null;
00260 }
00261 }
00262
00263
00264 void AbbrowserConduit::setOtherField(KABC::Addressee & abEntry, QString nr)
00265 {
00266 KABC::PhoneNumber phone;
00267 switch(ePilotOther)
00268 {
00269 case eOtherPhone:
00270 phone = abEntry.phoneNumber(0);
00271 phone.setNumber(nr);
00272 abEntry.insertPhoneNumber(phone);
00273 break;
00274 case eAssistant:
00275 abEntry.insertCustom(CSL1("KADDRESSBOOK"), CSL1("AssistantsName"), nr);
00276 break;
00277 case eBusinessFax:
00278 phone = abEntry.phoneNumber(KABC::PhoneNumber::Fax | KABC::PhoneNumber::Work);
00279 phone.setNumber(nr);
00280 abEntry.insertPhoneNumber(phone);
00281 break;
00282 case eCarPhone:
00283 phone = abEntry.phoneNumber(KABC::PhoneNumber::Car);
00284 phone.setNumber(nr);
00285 abEntry.insertPhoneNumber(phone);
00286 break;
00287 case eEmail2:
00288 return abEntry.insertEmail(nr);
00289 case eHomeFax:
00290 phone = abEntry.phoneNumber(KABC::PhoneNumber::Fax | KABC::PhoneNumber::Home);
00291 phone.setNumber(nr);
00292 abEntry.insertPhoneNumber(phone);
00293 break;
00294 case eTelex:
00295 phone = abEntry.phoneNumber(KABC::PhoneNumber::Bbs);
00296 phone.setNumber(nr);
00297 abEntry.insertPhoneNumber(phone);
00298 break;
00299 case eTTYTTDPhone:
00300 phone = abEntry.phoneNumber(KABC::PhoneNumber::Pcs);
00301 phone.setNumber(nr);
00302 abEntry.insertPhoneNumber(phone);
00303 break;
00304 }
00305 }
00306
00307
00308 KABC::PhoneNumber AbbrowserConduit::getFax(const KABC::Addressee & abEntry)
00309 {
00310 return abEntry.phoneNumber(KABC::PhoneNumber::Fax |
00311 ( (fPilotFaxHome) ?(KABC::PhoneNumber::Home) :(KABC::PhoneNumber::Work)));
00312 }
00313
00314
00319 KABC::Address AbbrowserConduit::getAddress(const KABC::Addressee & abEntry)
00320 {
00321 int type=(fPilotStreetHome)?(KABC::Address::Home):(KABC::Address::Work);
00322 KABC::Address ad(abEntry.address(KABC::Address::Pref));
00323 if (!ad.isEmpty()) return ad;
00324 ad=abEntry.address(type);
00325 if (!ad.isEmpty()) return ad;
00326 ad=abEntry.address((fPilotStreetHome) ?(KABC::Address::Work):(KABC::Address::Home));
00327 if (!ad.isEmpty()) return ad;
00328
00329 return abEntry.address(type | KABC::Address::Pref);
00330 }
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343 #ifdef DEBUG
00344 void AbbrowserConduit::showAddressee(const KABC::Addressee & abAddress)
00345 {
00346 FUNCTIONSETUP;
00347 DEBUGCONDUIT << "\tAbbrowser Contact Entry" << endl;
00348 DEBUGCONDUIT << "\t\tLast name = " << abAddress.familyName() << endl;
00349 DEBUGCONDUIT << "\t\tFirst name = " << abAddress.givenName() << endl;
00350 DEBUGCONDUIT << "\t\tCompany = " << abAddress.organization() << endl;
00351 DEBUGCONDUIT << "\t\tJob Title = " << abAddress.title() << endl;
00352 DEBUGCONDUIT << "\t\tNote = " << abAddress.note() << endl;
00353 DEBUGCONDUIT << "\t\tHome phone = " << abAddress.phoneNumber(KABC::PhoneNumber::Home).number() << endl;
00354 DEBUGCONDUIT << "\t\tWork phone = " << abAddress.phoneNumber(KABC::PhoneNumber::Work).number() << endl;
00355 DEBUGCONDUIT << "\t\tMobile phone = " << abAddress.phoneNumber(KABC::PhoneNumber::Cell).number() << endl;
00356 DEBUGCONDUIT << "\t\tEmail = " << abAddress.preferredEmail() << endl;
00357 DEBUGCONDUIT << "\t\tFax = " << getFax(abAddress).number() << endl;
00358 DEBUGCONDUIT << "\t\tPager = " << abAddress.phoneNumber(KABC::PhoneNumber::Pager).number() << endl;
00359 DEBUGCONDUIT << "\t\tCategory = " << abAddress.categories().first() << endl;
00360 }
00361
00362
00363
00364 void AbbrowserConduit::showPilotAddress(const PilotAddress & pilotAddress)
00365 {
00366 FUNCTIONSETUP;
00367 DEBUGCONDUIT << "\tPilot Address" << endl;
00368 DEBUGCONDUIT << "\t\tLast name = " << pilotAddress.getField(entryLastname) << endl;
00369 DEBUGCONDUIT << "\t\tFirst name = " << pilotAddress.getField(entryFirstname) << endl;
00370 DEBUGCONDUIT << "\t\tCompany = " << pilotAddress.getField(entryCompany) << endl;
00371 DEBUGCONDUIT << "\t\tJob Title = " << pilotAddress.getField(entryTitle) << endl;
00372 DEBUGCONDUIT << "\t\tNote = " << pilotAddress.getField(entryNote) << endl;
00373 DEBUGCONDUIT << "\t\tHome phone = " << pilotAddress.getPhoneField(PilotAddress::eHome) << endl;
00374 DEBUGCONDUIT << "\t\tWork phone = " << pilotAddress.getPhoneField(PilotAddress::eWork) << endl;
00375 DEBUGCONDUIT << "\t\tMobile phone = " << pilotAddress.getPhoneField(PilotAddress::eMobile) << endl;
00376 DEBUGCONDUIT << "\t\tEmail = " << pilotAddress.getPhoneField(PilotAddress::eEmail) << endl;
00377 DEBUGCONDUIT << "\t\tFax = " << pilotAddress.getPhoneField(PilotAddress::eFax) << endl;
00378 DEBUGCONDUIT << "\t\tPager = " << pilotAddress.getPhoneField(PilotAddress::ePager) << endl;
00379 DEBUGCONDUIT << "\t\tOther = " << pilotAddress.getPhoneField(PilotAddress::eOther) << endl;
00380 DEBUGCONDUIT << "\t\tCategory = " << pilotAddress.getCategoryLabel() << endl;
00381 }
00382 #endif
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396 bool AbbrowserConduit::exec()
00397 {
00398 FUNCTIONSETUP;
00399 DEBUGCONDUIT<<abbrowser_conduit_id<<endl;
00400
00401 KPilotUser *usr;
00402
00403 if(!fConfig)
00404 {
00405 kdWarning() << k_funcinfo << ": No config file was set!" << endl;
00406 emit logError(i18n("Unable to load configuration of the addressbook conduit."));
00407 return false;
00408 }
00409
00410 _prepare();
00411
00412 usr = fHandle->getPilotUser();
00413
00414
00415
00416 fFullSync =(syncAction == SYNC_FULL) ||
00417 ((usr->getLastSyncPC() !=(unsigned long) gethostid())
00418 && fConfig->readBoolEntry(AbbrowserConduitFactory::fullSyncOnPCChange(), true));
00419
00420 fFirstTime = false;
00421
00422 if(!openDatabases(QString::fromLatin1("AddressDB"), &fFirstTime))
00423 {
00424 emit logError(i18n("Unable to open the addressbook databases on the handheld."));
00425 return false;
00426 }
00427 _setAppInfo();
00428 if(!_loadAddressBook())
00429 {
00430 emit logError(i18n("Unable to open the addressbook."));
00431 return false;
00432 }
00433 fFirstTime |=(aBook->begin() == aBook->end());
00434
00435
00436
00437 pilotindex = 0;
00438
00439 #ifdef DEBUG
00440 DEBUGCONDUIT << fname << ": fullsync=" << fFullSync << ", firstSync=" << fFirstTime << endl;
00441 DEBUGCONDUIT << fname << ": syncAction=" << syncAction << ", archive = " << fArchive << endl;
00442 DEBUGCONDUIT << fname << ": smartmerge=" << fSmartMerge << ", conflictRes="<< fConflictResolution << endl;
00443 DEBUGCONDUIT << fname << ": PilotStreetHome=" << fPilotStreetHome << ", PilotFaxHOme" << fPilotFaxHome << endl;
00444 #endif
00445
00446 QTimer::singleShot(0, this, SLOT(syncPalmRecToPC()));
00447
00448 return true;
00449 }
00450
00451
00452
00453 void AbbrowserConduit::syncPalmRecToPC()
00454 {
00455 FUNCTIONSETUP;
00456 PilotRecord *r = 0L, *s = 0L;
00457
00458 if(fFirstTime || fFullSync)
00459 {
00460 r = fDatabase->readRecordByIndex(pilotindex++);
00461 }
00462 else
00463 {
00464 r = dynamic_cast <PilotSerialDatabase * >(fDatabase)->readNextModifiedRec();
00465 }
00466
00467 if(!r)
00468 {
00469 abiter = aBook->begin();
00470 QTimer::singleShot(0, this, SLOT(syncPCRecToPalm()));
00471 return;
00472 }
00473 else
00474 {
00475
00476 if(syncedIds.contains(r->getID()))
00477 {
00478 #ifdef DEBUG
00479 DEBUGCONDUIT << "already synced, so skipping" << endl;
00480 #endif
00481 QTimer::singleShot(0, this, SLOT(syncPalmRecToPC()));
00482 return;
00483 }
00484 }
00485
00486 bool archiveRecord =(r->getAttrib() & dlpRecAttrArchived);
00487
00488 KABC::Addressee e;
00489 s = fLocalDatabase->readRecordById(r->getID());
00490 if(!s)
00491 {
00492 e = _findMatch(PilotAddress(fAddressAppInfo, r));
00493 }
00494
00495 if((!s && e.isEmpty()) || fFirstTime)
00496 {
00497
00498 if(!r->isDeleted() ||(fArchive && archiveRecord))
00499 {
00500 e = _addToPC(r);
00501 if(fArchive && archiveRecord && !e.isEmpty() )
00502 {
00503 e.insertCustom(appString, flagString, QString::number(SYNCDEL));
00504 _saveAbEntry(e);
00505 }
00506 }
00507 }
00508 else
00509 {
00510
00511 if(r->isDeleted())
00512 {
00513 _checkDelete(r,s);
00514 }
00515 else
00516 {
00517
00518 if (archiveRecord && !fArchive)
00519 {
00520
00521 _checkDelete(r, s);
00522 }
00523 else
00524 {
00525 e = _changeOnPC(r, s);
00526 if(fArchive && archiveRecord && !e.isEmpty() )
00527 {
00528 e.insertCustom(appString, flagString, QString::number(SYNCDEL));
00529 _saveAbEntry(e);
00530 }
00531 }
00532 }
00533 }
00534
00535 syncedIds.append(r->getID());
00536 KPILOT_DELETE(r);
00537 KPILOT_DELETE(s);
00538
00539 QTimer::singleShot(0, this, SLOT(syncPalmRecToPC()));
00540 }
00541
00542
00543
00544 void AbbrowserConduit::syncPCRecToPalm()
00545 {
00546 FUNCTIONSETUP;
00547
00548 if(abiter == aBook->end() ||(*abiter).isEmpty())
00549 {
00550 pilotindex = 0;
00551 QTimer::singleShot(0, this, SLOT(syncDeletedRecord()));
00552 return;
00553 }
00554 bool ok;
00555 KABC::Addressee ad = *abiter;
00556 abiter++;
00557 QString recID(ad.custom(appString, idString));
00558 recordid_t rid = recID.toLong(&ok);
00559 if(recID.isEmpty() || !ok || !rid)
00560 {
00561
00562 _addToPalm(ad);
00563 QTimer::singleShot(0, this, SLOT(syncPCRecToPalm()));
00564 return;
00565 }
00566
00567 else if(syncedIds.contains(rid))
00568 {
00569 #ifdef DEBUG
00570 DEBUGCONDUIT << fname << ": address with id " << rid <<
00571 " already synced." << endl;
00572 #endif
00573 QTimer::singleShot(0, this, SLOT(syncPCRecToPalm()));
00574 return;
00575 }
00576 if(ad.custom(appString, flagString) == QString::number(SYNCDEL))
00577 {
00578 #ifdef DEBUG
00579 DEBUGCONDUIT << fname << ": address with id " << rid <<
00580 " marked archived, so don't sync." << endl;
00581 #endif
00582 syncedIds.append(rid);
00583 QTimer::singleShot(0, this, SLOT(syncPCRecToPalm()));
00584 return;
00585 }
00586
00587
00588 PilotRecord *backup = fLocalDatabase->readRecordById(rid);
00589
00590 PilotAddress pbackupadr(fAddressAppInfo, backup);
00591 if(!backup || !_equal(pbackupadr, ad) || fFirstTime)
00592 {
00593 PilotRecord *rec = fDatabase->readRecordById(rid);
00594 if (!rec && !backup)
00595 {
00596
00597
00598
00599
00600
00601
00602
00603 #ifdef DEBUG
00604 DEBUGCONDUIT<<"Addressbook entry "<<ad.realName()<<" has a non-existent Record-ID "<<ad.custom(appString, idString)<<", so disregard that ID"<<endl;
00605 #endif
00606 ad.removeCustom(appString, idString);
00607 _saveAbEntry(ad);
00608 abiter--;
00609
00610 QTimer::singleShot(0, this, SLOT(syncPCRecToPalm()));
00611 return;
00612 }
00613
00614 if(!rec)
00615 {
00616 if(fFirstTime) _addToPalm(ad);
00617 else _checkDelete(rec, backup);
00618 }
00619 else
00620 {
00621
00622 _changeOnPalm(rec, backup, ad);
00623 }
00624 KPILOT_DELETE(rec);
00625 }
00626 KPILOT_DELETE(backup);
00627 syncedIds.append(rid);
00628
00629 QTimer::singleShot(0, this, SLOT(syncPCRecToPalm()));
00630 }
00631
00632
00633
00634 void AbbrowserConduit::syncDeletedRecord()
00635 {
00636 FUNCTIONSETUP;
00637
00638 PilotRecord *s = fLocalDatabase->readRecordByIndex(pilotindex++);
00639 if(!s || fFirstTime)
00640 {
00641 QTimer::singleShot(0, this, SLOT(cleanup()));
00642 return;
00643 }
00644
00645
00646 if(syncedIds.contains(s->getID()))
00647 {
00648 QTimer::singleShot(0, this, SLOT(syncDeletedRecord()));
00649 return;
00650 }
00651
00652 QString uid = addresseeMap[s->getID()];
00653 KABC::Addressee e = aBook->findByUid(uid);
00654 if(uid.isEmpty() || e.isEmpty())
00655 {
00656 #ifdef DEBUG
00657 DEBUGCONDUIT << "Item " << s->getID() << " deleted from the PC, so delete from Palm too (or do deconfliction)!" << endl;
00658 #endif
00659
00660
00661
00662
00663
00664
00665 PilotRecord*r=fDatabase->readRecordById(s->getID());
00666 PilotAddress adr(fAddressAppInfo, r), backadr(fAddressAppInfo, s);
00667 if (r && s && !(adr==backadr) )
00668 {
00669 _changeOnPC(r, s);
00670 }
00671 else
00672 {
00673 _deleteFromPalm(s);
00674 }
00675 KPILOT_DELETE(r);
00676 }
00677
00678 KPILOT_DELETE(s);
00679 QTimer::singleShot(0, this, SLOT(syncDeletedRecord()));
00680 }
00681
00682 void AbbrowserConduit::cleanup()
00683 {
00684 FUNCTIONSETUP;
00685
00686 if(fDatabase)
00687 {
00688 fDatabase->resetSyncFlags();
00689 fDatabase->cleanup();
00690 }
00691 if(fLocalDatabase)
00692 {
00693 fLocalDatabase->resetSyncFlags();
00694 fLocalDatabase->cleanup();
00695 }
00696 KPILOT_DELETE(fDatabase);
00697 KPILOT_DELETE(fLocalDatabase);
00698 _saveAddressBook();
00699
00700 emit syncDone(this);
00701 }
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716 void AbbrowserConduit::_removePilotAddress(PilotAddress & address)
00717 {
00718 FUNCTIONSETUP;
00719
00720 #ifdef DEBUG
00721 DEBUGCONDUIT << fname << " deleting from palm pilot " << endl;
00722 showPilotAddress(address);
00723 #endif
00724
00725 address.makeDeleted();
00726 PilotRecord *pilotRec = address.pack();
00727 _deleteFromPalm(pilotRec);
00728 delete pilotRec;
00729 }
00730
00731
00732
00733 void AbbrowserConduit::_removeAbEntry(KABC::Addressee addressee)
00734 {
00735 FUNCTIONSETUP;
00736
00737 #ifdef DEBUG
00738 DEBUGCONDUIT << fname << " removing " << addressee.formattedName() << endl;
00739 #endif
00740 abChanged = true;
00741 aBook->removeAddressee(addressee);
00742 }
00743
00744
00745
00746 KABC::Addressee AbbrowserConduit::_saveAbEntry(KABC::Addressee & abEntry)
00747 {
00748 FUNCTIONSETUP;
00749
00750 #ifdef DEBUG
00751 DEBUGCONDUIT<<"Before _saveAbEntry, abEntry.custom="<<abEntry.custom(appString, idString)<<endl;
00752 #endif
00753 if(!abEntry.custom(appString, idString).isEmpty())
00754 {
00755 addresseeMap.insert(abEntry.custom(appString, idString).toLong(), abEntry.uid());
00756 }
00757 #ifdef DEBUG
00758 DEBUGCONDUIT<<"Before insertAddressee, abEntry.custom="<<abEntry.custom(appString, idString)<<endl;
00759 #endif
00760
00761 aBook->insertAddressee(abEntry);
00762 #ifdef DEBUG
00763 DEBUGCONDUIT<<"After insertAddressee, abEntry.custom="<<abEntry.custom(appString, idString)<<endl;
00764 #endif
00765
00766 abChanged = true;
00767 return abEntry;
00768 }
00769
00770
00771
00772 bool AbbrowserConduit::_savePilotAddress(PilotAddress & address, KABC::Addressee & abEntry)
00773 {
00774 FUNCTIONSETUP;
00775
00776 #ifdef DEBUG
00777 DEBUGCONDUIT << fname <<
00778 " saving to pilot " << address.id()
00779 << " " << address.getField(entryFirstname)
00780 << " " << address.getField(entryLastname)
00781 << " " << address.getField(entryCompany) << endl;
00782 #endif
00783
00784 PilotRecord *pilotRec = address.pack();
00785 #ifdef DEBUG
00786 DEBUGCONDUIT<<"PilotRec vor writeRecord: ID="<<pilotRec->getID()<<", address.id="<<address.id()<<endl;
00787 #endif
00788 recordid_t pilotId = fDatabase->writeRecord(pilotRec);
00789 #ifdef DEBUG
00790 DEBUGCONDUIT<<"PilotRec nach writeRecord ("<<pilotId<<": ID="<<pilotRec->getID()<<endl;
00791 #endif
00792 pilotRec->setID(pilotId);
00793 fLocalDatabase->writeRecord(pilotRec);
00794 KPILOT_DELETE(pilotRec);
00795
00796
00797 if(pilotId != 0) address.setID(pilotId);
00798
00799 recordid_t abId = 0;
00800
00801 abId = abEntry.custom(appString, idString).toUInt();
00802 if(abId != pilotId)
00803 {
00804 abEntry.insertCustom(appString, idString, QString::number(pilotId));
00805 return true;
00806 }
00807
00808 return false;
00809 }
00810
00811
00812
00813
00814
00815
00816 bool AbbrowserConduit::_saveBackupAddress(PilotAddress & backup)
00817 {
00818 FUNCTIONSETUP;
00819
00820 #ifdef DEBUG
00821 showPilotAddress(backup);
00822 #endif
00823 PilotRecord *pilotRec = backup.pack();
00824 fLocalDatabase->writeRecord(pilotRec);
00825 KPILOT_DELETE(pilotRec);
00826 return true;
00827 }
00828
00829
00830
00831
00832
00833
00834 KABC::Addressee AbbrowserConduit::_addToAbbrowser(const PilotAddress & address)
00835 {
00836 FUNCTIONSETUP;
00837 KABC::Addressee entry;
00838
00839
00840
00841
00842 if((address.isModified() && address.isDeleted())
00843 &&(address.getField(entryLastname).isEmpty())
00844 &&(address.getField(entryFirstname).isEmpty()))
00845 return entry;
00846
00847 _copy(entry, address);
00848 return _saveAbEntry(entry);
00849 }
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867 KABC::Addressee AbbrowserConduit::_addToPC(PilotRecord * r)
00868 {
00869 return _changeOnPC(r, NULL);
00870 }
00871
00872
00873
00874 KABC::Addressee AbbrowserConduit::_changeOnPC(PilotRecord * rec, PilotRecord * backup)
00875 {
00876 FUNCTIONSETUP;
00877 PilotAddress padr(fAddressAppInfo, rec);
00878 #ifdef DEBUG
00879 showPilotAddress(padr);
00880 #endif
00881 struct AddressAppInfo ai = fAddressAppInfo;
00882 PilotAddress pbackupadr(ai, backup);
00883 KABC::Addressee ad;
00884
00885 #ifdef DEBUG
00886 DEBUGCONDUIT << "---------------------------------" << endl;
00887 DEBUGCONDUIT << "Now syncing " <<
00888 padr.getField(entryFirstname) << " " <<
00889 padr.getField(entryLastname) << " / backup: " <<
00890 pbackupadr.getField(entryFirstname) << " " <<
00891 pbackupadr.getField(entryLastname) << endl;
00892 #endif
00893
00894 if(backup) ad = _findMatch(pbackupadr);
00895 if(ad.isEmpty()) ad = _findMatch(padr);
00896 #ifdef DEBUG
00897 DEBUGCONDUIT << "ad.custom=" << ad.custom(appString, idString) << endl;
00898 #endif
00899
00900 if(ad.isEmpty())
00901 {
00902 #ifdef DEBUG
00903 DEBUGCONDUIT << "ad.isEmpty() " << endl;
00904 #endif
00905 if(!backup)
00906 {
00907
00908 ad = _addToAbbrowser(padr);
00909 fLocalDatabase->writeRecord(rec);
00910 }
00911 else
00912 {
00913 #ifdef DEBUG
00914 DEBUGCONDUIT <<
00915 "not a new entry, but PC entry does not exist => deconfliction of "
00916 << padr.getField(entryLastname) << endl;
00917 #endif
00918 KABC::Addressee ab;
00919 switch(getEntryResolution(ad, pbackupadr, padr))
00920 {
00921 case ePilotOverides:
00922 _addToAbbrowser(padr);
00923 break;
00924 case eAbbrowserOverides:
00925 _removePilotAddress(padr);
00926 break;
00927 case eRevertToBackup:
00928 ab = _addToAbbrowser(pbackupadr);
00929 if(_savePilotAddress(pbackupadr, ab)) _saveAbEntry(ab);
00930 break;
00931 case eDoNotResolve:
00932 default:
00933 break;
00934 }
00935 }
00936 }
00937 else
00938 {
00939 #ifdef DEBUG
00940 DEBUGCONDUIT << "!ad.isEmpty()" << endl;
00941 showAddressee(ad);
00942 #endif
00943 PilotAddress backupadr(fAddressAppInfo, backup);
00944 _mergeEntries(padr, backupadr, ad);
00945
00946 }
00947 return ad;
00948 }
00949
00950
00951
00952 bool AbbrowserConduit::_deleteOnPC(PilotRecord * rec, PilotRecord * backup)
00953 {
00954 FUNCTIONSETUP;
00955 recordid_t id;
00956 if(rec) id = rec->getID();
00957 else if(backup) id = backup->getID();
00958 else id = 0;
00959
00960 #ifdef DEBUG
00961 DEBUGCONDUIT << fname << ": deleting record with id " << id << ", rec " <<
00962 (rec != NULL) << ", backup " <<(backup != NULL) << endl;
00963 #endif
00964 if(!id) return false;
00965
00966 KABC::Addressee ad = aBook->findByUid(addresseeMap[id]);
00967 PilotAddress backupAdr(fAddressAppInfo, backup);
00968
00969 if((!backup) || !_equal(backupAdr, ad))
00970 {
00971 #ifdef DEBUG
00972 DEBUGCONDUIT << fname << ": record with id " << id <<
00973 " is either new on PC or was changed, but is is requested to be removed. Ignoring this request"
00974 << endl;
00975 #endif
00976
00977 }
00978 if(!ad.isEmpty())
00979 {
00980 _removeAbEntry(ad);
00981
00982 }
00983 if(!rec)
00984 {
00985 backup->makeDeleted();
00986 fLocalDatabase->writeRecord(backup);
00987 }
00988 else
00989 {
00990 fLocalDatabase->writeRecord(rec);
00991 }
00992 return true;
00993 }
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003 void AbbrowserConduit::_addToPalm(KABC::Addressee & entry)
01004 {
01005 FUNCTIONSETUP;
01006 PilotAddress pilotAddress(fAddressAppInfo);
01007
01008 _copy(pilotAddress, entry);
01009 #ifdef DEBUG
01010 DEBUGCONDUIT<<"pilotAddress.id="<<pilotAddress.getID()<<", abEntry.ID="<<entry.custom(appString, idString)<<endl;
01011 #endif
01012
01013 if(_savePilotAddress(pilotAddress, entry))
01014 {
01015 #ifdef DEBUG
01016 DEBUGCONDUIT<<"Vor _saveAbEntry, pilotAddress.id="<<pilotAddress.getID()<<", abEntry.ID="<<entry.custom(appString, idString)<<endl;
01017 #endif
01018 _saveAbEntry(entry);
01019 }
01020 }
01021
01022
01023
01024 void AbbrowserConduit::_changeOnPalm(PilotRecord * rec, PilotRecord * backuprec, KABC::Addressee & ad)
01025 {
01026 FUNCTIONSETUP;
01027 PilotAddress padr(fAddressAppInfo);
01028 PilotAddress pbackupadr(fAddressAppInfo);
01029
01030 if(rec) padr = PilotAddress(fAddressAppInfo, rec);
01031 if(backuprec) pbackupadr = PilotAddress(fAddressAppInfo, backuprec);
01032 #ifdef DEBUG
01033 DEBUGCONDUIT << "---------------------------------" << endl;
01034 DEBUGCONDUIT << "Now syncing " << padr.getField(entryLastname) << " / backup: " << pbackupadr.getField(entryLastname) << endl;
01035 #endif
01036 _mergeEntries(padr, pbackupadr, ad);
01037 }
01038
01039
01040
01041 void AbbrowserConduit::_deleteFromPalm(PilotRecord * rec)
01042 {
01043 FUNCTIONSETUP;
01044 rec->makeDeleted();
01045 recordid_t pilotId = fDatabase->writeRecord(rec);
01046 rec->setID(pilotId);
01047 fLocalDatabase->writeRecord(rec);
01048 syncedIds.append(rec->getID());
01049 }
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062 bool AbbrowserConduit::_equal(const PilotAddress & piAddress, KABC::Addressee & abEntry) const
01063 {
01064 if(_compare(abEntry.familyName(), piAddress.getField(entryLastname))) return false;
01065 if(_compare(abEntry.givenName(), piAddress.getField(entryFirstname))) return false;
01066 if(_compare(abEntry.title(), piAddress.getField(entryTitle))) return false;
01067 if(_compare(abEntry.organization(), piAddress.getField(entryCompany))) return false;
01068 if(_compare(abEntry.note(), piAddress.getField(entryNote))) return false;
01069 int cat = _getCat(abEntry.categories());
01070
01071
01072 if(_compare(PilotAppCategory::codec()->toUnicode(fAddressAppInfo.category.name[cat]),
01073 piAddress.getCategoryLabel())) return false;
01074 if(_compare(abEntry.phoneNumber(KABC::PhoneNumber::Work).number(),
01075 piAddress.getPhoneField(PilotAddress::eWork))) return false;
01076 if(_compare(abEntry.phoneNumber(KABC::PhoneNumber::Home).number(),
01077 piAddress.getPhoneField(PilotAddress::eHome))) return false;
01078 if(_compare(getOtherField(abEntry),
01079 piAddress.getPhoneField(PilotAddress::eOther))) return false;
01080 if(_compare(abEntry.preferredEmail(),
01081 piAddress.getPhoneField(PilotAddress::eEmail))) return false;
01082 if(_compare(getFax(abEntry).number(),
01083 piAddress.getPhoneField(PilotAddress::eFax))) return false;
01084 if(_compare(abEntry.phoneNumber(KABC::PhoneNumber::Cell).number(),
01085 piAddress.getPhoneField(PilotAddress::eMobile))) return false;
01086
01087 KABC::Address address = getAddress(abEntry);
01088 if(_compare(address.street(), piAddress.getField(entryAddress))) return false;
01089 if(_compare(address.locality(), piAddress.getField(entryCity))) return false;
01090 if(_compare(address.region(), piAddress.getField(entryState))) return false;
01091 if(_compare(address.postalCode(), piAddress.getField(entryZip))) return false;
01092 if(_compare(address.country(), piAddress.getField(entryCountry))) return false;
01093
01094 if(
01095 _compare(abEntry.custom(appString, CSL1("CUSTOM1")), piAddress.getField(entryCustom1)) ||
01096 _compare(abEntry.custom(appString, CSL1("CUSTOM2")), piAddress.getField(entryCustom2)) ||
01097 _compare(abEntry.custom(appString, CSL1("CUSTOM3")), piAddress.getField(entryCustom3)) ||
01098 _compare(abEntry.custom(appString, CSL1("CUSTOM4")), piAddress.getField(entryCustom4)))
01099 {
01100 return false;
01101 }
01102
01103 if (piAddress.getCat()!=_getCat(abEntry.categories())) return false;
01104
01105 return true;
01106 }
01107
01108
01109
01110 void AbbrowserConduit::_copy(PilotAddress & toPilotAddr, KABC::Addressee & fromAbEntry)
01111 {
01112 FUNCTIONSETUP;
01113
01114
01115 toPilotAddr.setField(entryLastname, fromAbEntry.familyName());
01116 QString firstAndMiddle = fromAbEntry.givenName();
01117 if(!fromAbEntry.additionalName().isEmpty()) firstAndMiddle += CSL1(" ") + fromAbEntry.additionalName();
01118 toPilotAddr.setField(entryFirstname, firstAndMiddle);
01119 toPilotAddr.setField(entryCompany, fromAbEntry.organization());
01120 toPilotAddr.setField(entryTitle, fromAbEntry.title());
01121 toPilotAddr.setField(entryNote, fromAbEntry.note());
01122
01123
01124 toPilotAddr.setPhoneField(PilotAddress::eEmail, fromAbEntry.preferredEmail());
01125 toPilotAddr.setPhoneField(PilotAddress::eWork,
01126 fromAbEntry.phoneNumber(KABC::PhoneNumber::Work).number());
01127 toPilotAddr.setPhoneField(PilotAddress::eHome,
01128 fromAbEntry.phoneNumber(KABC::PhoneNumber::Home).number());
01129 toPilotAddr.setPhoneField(PilotAddress::eMobile,
01130 fromAbEntry.phoneNumber(KABC::PhoneNumber::Cell).number());
01131 toPilotAddr.setPhoneField(PilotAddress::eFax, getFax(fromAbEntry).number());
01132 toPilotAddr.setPhoneField(PilotAddress::ePager,
01133 fromAbEntry.phoneNumber(KABC::PhoneNumber::Pager).number());
01134 toPilotAddr.setPhoneField(PilotAddress::eOther, getOtherField(fromAbEntry));
01135 toPilotAddr.setShownPhone(PilotAddress::eMobile);
01136
01137 KABC::Address homeAddress = getAddress(fromAbEntry);
01138 _setPilotAddress(toPilotAddr, homeAddress);
01139
01140
01141
01142
01143
01144
01145
01146 toPilotAddr.setField(entryCustom1, fromAbEntry.custom(appString, CSL1("CUSTOM1")));
01147 toPilotAddr.setField(entryCustom2, fromAbEntry.custom(appString, CSL1("CUSTOM2")));
01148 toPilotAddr.setField(entryCustom3, fromAbEntry.custom(appString, CSL1("CUSTOM3")));
01149 toPilotAddr.setField(entryCustom4, fromAbEntry.custom(appString, CSL1("CUSTOM4")));
01150
01151 toPilotAddr.setCat(_getCat(fromAbEntry.categories()));
01152 }
01153
01154
01155
01160 int AbbrowserConduit::_getCat(const QStringList cats) const
01161 {
01162
01163 int j;
01164 for(QStringList::ConstIterator it = cats.begin(); it != cats.end(); ++it)
01165 {
01166 for(j = 1; j <= 15; j++)
01167 {
01168 QString catName = PilotAppCategory::codec()->
01169 toUnicode(fAddressAppInfo.category.name[j]);
01170 if(!(*it).isEmpty() && !_compare(*it, catName))
01171 {
01172 return j;
01173 }
01174 }
01175 }
01176 return 0;
01177 }
01178
01179
01180
01181 void AbbrowserConduit::_setPilotAddress(PilotAddress & toPilotAddr, const KABC::Address & abAddress)
01182 {
01183 toPilotAddr.setField(entryAddress, abAddress.street());
01184 toPilotAddr.setField(entryCity, abAddress.locality());
01185 toPilotAddr.setField(entryState, abAddress.region());
01186 toPilotAddr.setField(entryZip, abAddress.postalCode());
01187 toPilotAddr.setField(entryCountry, abAddress.country());
01188 }
01189
01190
01191 void AbbrowserConduit::_copyPhone(KABC::Addressee & toAbEntry,
01192 KABC::PhoneNumber phone, QString palmphone)
01193 {
01194 if(!palmphone.isEmpty())
01195 {
01196 phone.setNumber(palmphone);
01197 toAbEntry.insertPhoneNumber(phone);
01198 }
01199 else
01200 {
01201 toAbEntry.removePhoneNumber(phone);
01202 }
01203 }
01204
01205 void AbbrowserConduit::_setCategory(Addressee & abEntry, QString cat)
01206 {
01207 for(int j = 1; j <= 15; j++)
01208 {
01209 abEntry.removeCategory(
01210 PilotAppCategory::codec()->toUnicode(fAddressAppInfo.category.name[j]));
01211 }
01212 if(!cat.isEmpty()) abEntry.insertCategory(cat);
01213 }
01214
01215 void AbbrowserConduit::_copy(KABC::Addressee & toAbEntry, const PilotAddress & fromPiAddr)
01216 {
01217 FUNCTIONSETUP;
01218
01219 toAbEntry.setFamilyName(fromPiAddr.getField(entryLastname));
01220 toAbEntry.setGivenName(fromPiAddr.getField(entryFirstname));
01221 toAbEntry.setOrganization(fromPiAddr.getField(entryCompany));
01222 toAbEntry.setTitle(fromPiAddr.getField(entryTitle));
01223 toAbEntry.setNote(fromPiAddr.getField(entryNote));
01224
01225
01226 toAbEntry.removeEmail(toAbEntry.preferredEmail());
01227 toAbEntry.insertEmail(fromPiAddr.getPhoneField(PilotAddress::eEmail));
01228
01229 _copyPhone(toAbEntry,
01230 toAbEntry.phoneNumber(KABC::PhoneNumber::Home),
01231 fromPiAddr.getPhoneField(PilotAddress::eHome));
01232 _copyPhone(toAbEntry,
01233 toAbEntry.phoneNumber(KABC::PhoneNumber::Work),
01234 fromPiAddr.getPhoneField(PilotAddress::eWork));
01235 _copyPhone(toAbEntry,
01236 toAbEntry.phoneNumber(KABC::PhoneNumber::Cell),
01237 fromPiAddr.getPhoneField(PilotAddress::eMobile));
01238 _copyPhone(toAbEntry,
01239 getFax(toAbEntry),
01240 fromPiAddr.getPhoneField(PilotAddress::eFax));
01241 _copyPhone(toAbEntry,
01242 toAbEntry.phoneNumber(KABC::PhoneNumber::Pager),
01243 fromPiAddr.getPhoneField(PilotAddress::ePager));
01244 setOtherField(toAbEntry, fromPiAddr.getPhoneField(PilotAddress::eOther));
01245
01246 KABC::Address homeAddress = getAddress(toAbEntry);
01247 homeAddress.setStreet(fromPiAddr.getField(entryAddress));
01248 homeAddress.setLocality(fromPiAddr.getField(entryCity));
01249 homeAddress.setRegion(fromPiAddr.getField(entryState));
01250 homeAddress.setPostalCode(fromPiAddr.getField(entryZip));
01251 homeAddress.setCountry(fromPiAddr.getField(entryCountry));
01252 toAbEntry.insertAddress(homeAddress);
01253
01254 toAbEntry.insertCustom(appString, CSL1("CUSTOM1"), fromPiAddr.getField(entryCustom1));
01255 toAbEntry.insertCustom(appString, CSL1("CUSTOM2"), fromPiAddr.getField(entryCustom2));
01256 toAbEntry.insertCustom(appString, CSL1("CUSTOM3"), fromPiAddr.getField(entryCustom3));
01257 toAbEntry.insertCustom(appString, CSL1("CUSTOM4"), fromPiAddr.getField(entryCustom4));
01258
01259
01260
01261
01262
01263 toAbEntry.insertCustom(appString, idString, QString::number(fromPiAddr.getID()));
01264
01265
01266 int cat = fromPiAddr.getCat();
01267 QString category;
01268 if (0 < cat && cat <= 15) category = fAddressAppInfo.category.name[cat];
01269 _setCategory(toAbEntry, category);
01270 #ifdef DEBUG
01271 showAddressee(toAbEntry);
01272 #endif
01273 }
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01297 int AbbrowserConduit::_conflict(const QString & entry, const QString & field, const QString & palm,
01298 const QString & backup, const QString & pc, bool & mergeNeeded, QString & mergedStr)
01299 {
01300 FUNCTIONSETUP;
01301 mergeNeeded = false;
01302 QString bckup = backup;
01303
01304
01305 if(pc == palm) return CHANGED_NONE;
01306
01307
01308 if(fFirstTime)
01309 {
01310 bckup = QString();
01311 if(pc.isEmpty())
01312 {
01313 mergeNeeded = true;
01314 mergedStr = palm;
01315 return CHANGED_PC;
01316 }
01317 if(palm.isEmpty())
01318 {
01319 mergeNeeded = true;
01320 mergedStr = pc;
01321 return CHANGED_PALM;
01322 }
01323 }
01324 else
01325 {
01326
01327 if(palm == backup)
01328 {
01329 mergeNeeded = true;
01330 mergedStr = pc;
01331 return CHANGED_PALM;
01332 }
01333
01334 if(pc == backup)
01335 {
01336 mergeNeeded = true;
01337 mergedStr = palm;
01338 return CHANGED_PC;
01339 }
01340 }
01341
01342
01343 EConflictResolution fieldres = getFieldResolution(entry, field, palm, bckup, pc);
01344 #ifdef DEBUG
01345 DEBUGCONDUIT << "fieldres=" << fieldres << endl;
01346 #endif
01347 switch(fieldres)
01348 {
01349 case eAbbrowserOverides:
01350 mergeNeeded = true;
01351 mergedStr = pc;
01352 return CHANGED_PALM;
01353 break;
01354 case ePilotOverides:
01355 mergeNeeded = true;
01356 mergedStr = palm;
01357 return CHANGED_PC;
01358 break;
01359 case eRevertToBackup:
01360 mergeNeeded = true;
01361 mergedStr = backup;
01362 return CHANGED_BOTH;
01363 break;
01364 case eKeepBothInAbbrowser:
01365 return CHANGED_DUPLICATE;
01366 case eDoNotResolve:
01367 default:
01368 return CHANGED_NORES;
01369 }
01370 return CHANGED_NONE;
01371 }
01372
01373
01374
01375 int AbbrowserConduit::_compare(const QString & str1, const QString & str2) const
01376 {
01377 if(str1.isEmpty() && str2.isEmpty()) return 0;
01378 else return str1.compare(str2);
01379 }
01380
01381
01382 int AbbrowserConduit::_smartMergePhone(KABC::Addressee & abEntry,
01383 const PilotAddress & backupAddress,
01384 PilotAddress & pilotAddress,
01385 PilotAddress::EPhoneType PalmFlag,
01386 KABC::PhoneNumber phone, QString thisName,
01387 QString name)
01388 {
01389 bool mergeNeeded = false;
01390 QString mergedStr;
01391
01392 int res = _conflict(thisName, name,
01393 pilotAddress.getPhoneField(PalmFlag),
01394 backupAddress.getPhoneField(PalmFlag),
01395 phone.number(), mergeNeeded, mergedStr);
01396 if(res & CHANGED_NORES) return res;
01397 if(mergeNeeded)
01398 {
01399 pilotAddress.setPhoneField(PalmFlag, mergedStr);
01400 phone.setNumber(mergedStr);
01401 abEntry.insertPhoneNumber(phone);
01402 }
01403 return -1;
01404 }
01405
01406 int AbbrowserConduit::_smartMergeEntry(QString abEntry,
01407 const PilotAddress & backupAddress,
01408 PilotAddress & pilotAddress, int PalmFlag,
01409 QString thisName, QString name,
01410 QString & mergedString)
01411 {
01412 bool mergeNeeded = false;
01413 QString mergedStr;
01414 mergedString = QString();
01415
01416 int res = _conflict(thisName, name,
01417 pilotAddress.getField(PalmFlag),
01418 backupAddress.getField(PalmFlag),
01419 abEntry, mergeNeeded, mergedStr);
01420 if(res & CHANGED_NORES) return res;
01421 if(mergeNeeded)
01422 {
01423 #ifdef DEBUG
01424 DEBUGCONDUIT << "Merged string=" << mergedStr << endl;
01425 #endif
01426 pilotAddress.setField(PalmFlag, mergedStr);
01427 mergedString = mergedStr;
01428 }
01429 return -1;
01430 }
01431
01432
01433 int AbbrowserConduit::_smartMergeCategories(KABC::Addressee & abEntry,
01434 const PilotAddress & backupAddress,
01435 PilotAddress & pilotAddress,
01436 QString thisName, QString name,
01437 QString & mergedString)
01438 {
01439 int pccat = _getCat(abEntry.categories());
01440 QString abAddressCat =
01441 PilotAppCategory::codec()->toUnicode(fAddressAppInfo.category.name[pccat]);
01442 bool mergeNeeded = false;
01443 QString mergedStr;
01444 mergedString = QString();
01445
01446 int res = _conflict(thisName, name,
01447 pilotAddress.getCategoryLabel(),
01448 backupAddress.getCategoryLabel(),
01449 abAddressCat, mergeNeeded, mergedStr);
01450 if(res & CHANGED_NORES) return res;
01451 if(mergeNeeded)
01452 {
01453 pilotAddress.setCategory(mergedStr);
01454 _setCategory(abEntry, mergedStr);
01455 mergedString = mergedStr;
01456 }
01457 return -1;
01458 }
01459
01460
01461 void AbbrowserConduit::showAdresses(PilotAddress & pilotAddress,
01462 const PilotAddress & backupAddress, KABC::Addressee & abEntry)
01463 {
01464 #ifdef DEBUG
01465 DEBUGCONDUIT << "abEntry:" << endl;
01466 showAddressee(abEntry);
01467 DEBUGCONDUIT << "pilotAddress:" << endl;
01468 showPilotAddress(pilotAddress);
01469 DEBUGCONDUIT << "backupAddress:" << endl;
01470 showPilotAddress(backupAddress);
01471 DEBUGCONDUIT << "------------------------------------------------" << endl;
01472 #endif
01473 }
01474
01475 int AbbrowserConduit::_smartMerge(PilotAddress & outPilotAddress,
01476 const PilotAddress & backupAddress, KABC::Addressee & outAbEntry)
01477 {
01478 FUNCTIONSETUP;
01479 fEntryResolution = getResolveConflictOption();
01480 PilotAddress pilotAddress(outPilotAddress);
01481 KABC::Addressee abEntry(outAbEntry);
01482 QString thisName(outAbEntry.realName());
01483 bool mergeNeeded = false;
01484 QString mergedStr;
01485 int res;
01486
01487 res = _smartMergeEntry(abEntry.familyName(), backupAddress, pilotAddress,
01488 (int) entryLastname, thisName, i18n("last name"), mergedStr);
01489 if(res >= 0) return res;
01490 else if(!mergedStr.isEmpty()) abEntry.setFamilyName(mergedStr);
01491
01492 res = _smartMergeEntry(abEntry.givenName(), backupAddress, pilotAddress,
01493 (int) entryFirstname, thisName, i18n("first name"), mergedStr);
01494 if(res >= 0) return res;
01495 else if(!mergedStr.isEmpty()) abEntry.setGivenName(mergedStr);
01496
01497 res = _smartMergeEntry(abEntry.organization(), backupAddress, pilotAddress,
01498 (int) entryCompany, thisName, i18n("organization"), mergedStr);
01499 if(res >= 0) return res;
01500 else if(!mergedStr.isEmpty()) abEntry.setOrganization(mergedStr);
01501
01502 res = _smartMergeEntry(abEntry.title(), backupAddress, pilotAddress,
01503 (int) entryTitle, thisName, i18n("title"), mergedStr);
01504 if(res >= 0) return res;
01505 else if(!mergedStr.isEmpty()) abEntry.setTitle(mergedStr);
01506
01507 res = _smartMergeEntry(abEntry.note(), backupAddress, pilotAddress,
01508 (int) entryNote, thisName, i18n("note"), mergedStr);
01509 if(res >= 0) return res;
01510 else if(!mergedStr.isEmpty()) abEntry.setNote(mergedStr);
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520 res = _smartMergeEntry(abEntry.custom(appString, CSL1("CUSTOM1")), backupAddress, pilotAddress, entryCustom1, thisName, i18n("custom 1"), mergedStr);
01521 if(res >= 0) return res;
01522 else if(!mergedStr.isEmpty()) abEntry.insertCustom(appString, CSL1("CUSTOM1"), mergedStr);
01523
01524 res = _smartMergeEntry(abEntry.custom(appString, CSL1("CUSTOM2")), backupAddress, pilotAddress, entryCustom2, thisName, i18n("custom 2"), mergedStr);
01525 if(res >= 0) return res;
01526 else if(!mergedStr.isEmpty()) abEntry.insertCustom(appString, CSL1("CUSTOM2"), mergedStr);
01527
01528 res = _smartMergeEntry(abEntry.custom(appString, CSL1("CUSTOM3")), backupAddress, pilotAddress, entryCustom3, thisName, i18n("custom 3"), mergedStr);
01529 if(res >= 0) return res;
01530 else if(!mergedStr.isEmpty()) abEntry.insertCustom(appString, CSL1("CUSTOM3"), mergedStr);
01531
01532 res = _smartMergeEntry(abEntry.custom(appString, CSL1("CUSTOM4")), backupAddress, pilotAddress, entryCustom4, thisName, i18n("custom 4"), mergedStr);
01533 if(res >= 0) return res;
01534 else if(!mergedStr.isEmpty()) abEntry.insertCustom(appString, CSL1("CUSTOM4"), mergedStr);
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545 res = _smartMergePhone(abEntry, backupAddress, pilotAddress,
01546 PilotAddress::eWork, abEntry.phoneNumber(KABC::PhoneNumber::Work),
01547 thisName, i18n("work phone"));
01548 if(res >= 0) return res;
01549 res = _smartMergePhone(abEntry, backupAddress, pilotAddress,
01550 PilotAddress::eHome, abEntry.phoneNumber(KABC::PhoneNumber::Home),
01551 thisName, i18n("home phone"));
01552 if(res >= 0) return res;
01553 res = _smartMergePhone(abEntry, backupAddress, pilotAddress,
01554 PilotAddress::eMobile, abEntry.phoneNumber(KABC::PhoneNumber::Cell),
01555 thisName, i18n("mobile phone"));
01556 if(res >= 0) return res;
01557 res = _smartMergePhone(abEntry, backupAddress, pilotAddress,
01558 PilotAddress::eFax, getFax(abEntry), thisName, i18n("fax"));
01559 if(res >= 0) return res;
01560 res = _smartMergePhone(abEntry, backupAddress, pilotAddress,
01561 PilotAddress::ePager, abEntry.phoneNumber(KABC::PhoneNumber::Pager),
01562 thisName, i18n("pager"));
01563 if(res >= 0) return res;
01564
01565 res = _conflict(thisName, i18n("other"),
01566 pilotAddress.getPhoneField(PilotAddress::eOther),
01567 backupAddress.getPhoneField(PilotAddress::eOther),
01568 getOtherField(abEntry), mergeNeeded, mergedStr);
01569 if(res & CHANGED_NORES) return res;
01570 if(mergeNeeded)
01571 {
01572 pilotAddress.setPhoneField(PilotAddress::eOther, mergedStr);
01573 setOtherField(abEntry, mergedStr);
01574 }
01575
01576 res = _conflict(thisName, i18n("email"),
01577 pilotAddress.getPhoneField(PilotAddress::eEmail),
01578 backupAddress.getPhoneField(PilotAddress::eEmail),
01579 abEntry.preferredEmail(), mergeNeeded, mergedStr);
01580 if(res & CHANGED_NORES) return res;
01581 if(mergeNeeded)
01582 {
01583 pilotAddress.setPhoneField(PilotAddress::eEmail, mergedStr);
01584 abEntry.removeEmail(backupAddress.getPhoneField(PilotAddress::eEmail));
01585 abEntry.removeEmail(pilotAddress.getPhoneField(PilotAddress::eEmail));
01586 abEntry.insertEmail(mergedStr, true);
01587 }
01588
01589
01590
01591 KABC::Address abAddress = getAddress(abEntry);
01592
01593 res = _smartMergeEntry(abAddress.street(),
01594 backupAddress, pilotAddress, entryAddress,
01595 thisName, i18n("address"), mergedStr);
01596 if(res >= 0) return res;
01597 else if(!mergedStr.isEmpty()) abAddress.setStreet(mergedStr);
01598
01599 res = _smartMergeEntry(abAddress.locality(),
01600 backupAddress, pilotAddress, entryCity,
01601 thisName, i18n("city"), mergedStr);
01602 if(res >= 0) return res;
01603 else if(!mergedStr.isEmpty()) abAddress.setLocality(mergedStr);
01604
01605 res = _smartMergeEntry(abAddress.region(),
01606 backupAddress, pilotAddress, entryState,
01607 thisName, i18n("region"), mergedStr);
01608 if(res >= 0) return res;
01609 else if(!mergedStr.isEmpty()) abAddress.setRegion(mergedStr);
01610
01611 res = _smartMergeEntry(abAddress.postalCode(),
01612 backupAddress, pilotAddress, entryZip,
01613 thisName, i18n("postal code"), mergedStr);
01614 if(res >= 0) return res;
01615 else if(!mergedStr.isEmpty()) abAddress.setPostalCode(mergedStr);
01616
01617 res = _smartMergeEntry(abAddress.country(),
01618 backupAddress, pilotAddress, entryCountry,
01619 thisName, i18n("country"), mergedStr);
01620 if(res >= 0) return res;
01621 else if(!mergedStr.isEmpty()) abAddress.setCountry(mergedStr);
01622
01623 abEntry.insertAddress(abAddress);
01624
01625 res = _smartMergeCategories(abEntry,
01626 backupAddress, pilotAddress,
01627 thisName, i18n("category"), mergedStr);
01628 if(res >= 0) return res;
01629
01630 abEntry.insertCustom(appString, idString, QString::number(pilotAddress.id()));
01631
01632
01633 outPilotAddress = pilotAddress;
01634 outAbEntry = abEntry;
01635
01636 return CHANGED_BOTH;
01637 }
01638
01639
01645 int AbbrowserConduit::_mergeEntries(PilotAddress & pilotAddress, PilotAddress & backupAddress, KABC::Addressee & abEntry)
01646 {
01647 FUNCTIONSETUP;
01648
01649 int res = _handleConflict(pilotAddress, backupAddress, abEntry);
01650 if(res & CHANGED_NORES)
01651 {
01652 if(res & CHANGED_DUPLICATE)
01653 {
01654 if(res & CHANGED_PALM)
01655 {
01656
01657 abEntry.insertCustom(appString, idString, QString::number(0));
01658 _addToPalm(abEntry);
01659 }
01660 if(res & CHANGED_PC)
01661 {
01662 _addToAbbrowser(pilotAddress);
01663 _saveBackupAddress(pilotAddress);
01664 }
01665 }
01666 }
01667 else
01668 {
01669 if(res & CHANGED_PALM)
01670 {
01671 _savePilotAddress(pilotAddress, abEntry);
01672 }
01673 if(res & CHANGED_PC)
01674 {
01675 _saveAbEntry(abEntry);
01676 }
01677 _saveBackupAddress(pilotAddress);
01678
01679
01680 QString idStr(abEntry.custom(appString, idString));
01681
01682 if(idStr.isEmpty() ||(idStr != QString::number(pilotAddress.getID())))
01683 {
01684 abEntry.insertCustom(appString, idString, QString::number(pilotAddress.getID()));
01685 _saveAbEntry(abEntry);
01686 }
01687 }
01688 return 0;
01689 }
01690
01691
01696 int AbbrowserConduit::_handleConflict(PilotAddress & pilotAddress, PilotAddress & backupAddress, KABC::Addressee & abEntry)
01697 {
01698 FUNCTIONSETUP;
01699
01700 if(abEntry.isEmpty())
01701 {
01702 _copy(abEntry, pilotAddress);
01703 return CHANGED_PC | CHANGED_ADD;
01704 }
01705
01706
01707 if(_equal(pilotAddress, abEntry)) return CHANGED_NONE;
01708
01709 if(pilotAddress == backupAddress)
01710 {
01711 if(!_equal(backupAddress, abEntry))
01712 {
01713 _copy(pilotAddress, abEntry);
01714 return CHANGED_PALM;
01715 }
01716 else
01717 {
01718
01719
01720 return CHANGED_NONE;
01721 }
01722 }
01723 else
01724 {
01725 if(_equal(backupAddress, abEntry))
01726 {
01727 _copy(abEntry, pilotAddress);
01728 return CHANGED_PC;
01729 }
01730 else
01731 {
01732
01733 if(doSmartMerge())
01734 {
01735 PilotAddress pAdr(pilotAddress);
01736 KABC::Addressee abEnt(abEntry);
01737 int res = _smartMerge(pilotAddress, backupAddress, abEntry);
01738 switch(res)
01739 {
01740 case CHANGED_NORES:
01741 case CHANGED_DUPLICATE:
01742 pilotAddress = pAdr;
01743 abEntry = abEnt;
01744 }
01745 return res;
01746 }
01747 else
01748 {
01749 switch(getEntryResolution(abEntry, backupAddress, pilotAddress))
01750 {
01751 case eKeepBothInAbbrowser:
01752 return CHANGED_DUPLICATE;
01753 case ePilotOverides:
01754 _copy(abEntry, pilotAddress);
01755 return CHANGED_PC;
01756 case eAbbrowserOverides:
01757 _copy(pilotAddress, abEntry);
01758 return CHANGED_PALM;
01759 case eRevertToBackup:
01760 _copy(abEntry, backupAddress);
01761 pilotAddress = backupAddress;
01762 return CHANGED_BOTH;
01763 case eDoNotResolve:
01764 return CHANGED_NORES;
01765 default:
01766 return CHANGED_NONE;
01767 }
01768 }
01769 }
01770 }
01771
01772 return CHANGED_NONE;
01773 }
01774
01775 AbbrowserConduit::EConflictResolution AbbrowserConduit::getFieldResolution(const QString & entry, const QString & field,
01776 const QString & palm, const QString & backup, const QString & pc)
01777 {
01778 FUNCTIONSETUP;
01779 EConflictResolution res = fEntryResolution;
01780 if(res == eUserChoose)
01781 {
01782 res = getResolveConflictOption();
01783 }
01784 switch(res)
01785 {
01786 case eKeepBothInAbbrowser:
01787 case ePilotOverides:
01788 case eAbbrowserOverides:
01789 case eDoNotResolve:
01790 return res;
01791 break;
01792 case eRevertToBackup:
01793 if(backup.isNull()) return eDoNotResolve;
01794 else return res;
01795 break;
01796 case eUserChoose:
01797 default:
01798 QStringList lst;
01799 lst <<
01800 i18n("Leave untouched") <<
01801 i18n("Handheld overrides") <<
01802 i18n("PC overrides");
01803 if(!backup.isNull()) lst << i18n("Use the value from the last sync");
01804 lst << i18n("Duplicate both");
01805 bool remember = FALSE;
01806 res = ResolutionDialog(i18n("Address conflict"),
01807 i18n("<html><p>The field \"%1\" of the entry \"%2\" was changed on the handheld and on the PC.</p>"
01808 "<table border=0>"
01809 "<tr><td><b>Handheld:</b></td><td>%3</td></tr>"
01810 "<tr><td><b>PC:</b></td><td>%4</td></tr>"
01811 "<tr><td><b>last sync:</b></td><td>%5</td></tr>"
01812 "</table>"
01813 "<p>How should this conflict be resolved?</p></html>").arg(field).arg(entry).arg(palm).arg(pc).arg(backup),
01814 lst, i18n("Apply to all fields of this entry"), &remember);
01815 if(backup.isNull() && res == 4) res =(EConflictResolution) 5;
01816 if(remember)
01817 {
01818 fEntryResolution = res;
01819 }
01820 return res;
01821 }
01822 }
01823
01824 AbbrowserConduit::EConflictResolution AbbrowserConduit::getEntryResolution(const KABC::Addressee & abEntry, const PilotAddress &backupAddress, const PilotAddress & pilotAddress)
01825 {
01826 FUNCTIONSETUP;
01827 EConflictResolution res = getResolveConflictOption();
01828 switch(res)
01829 {
01830 case eKeepBothInAbbrowser:
01831 case ePilotOverides:
01832 case eAbbrowserOverides:
01833 case eRevertToBackup:
01834 case eDoNotResolve:
01835 return res;
01836 break;
01837 case eUserChoose:
01838 default:
01839 QStringList lst;
01840 lst << i18n("Leave untouched") <<
01841 i18n("Handheld overrides") <<
01842 i18n("PC overrides") <<
01843 i18n("Use the value from the last sync");
01844
01845 bool remember = FALSE;
01846
01847 PilotAddress emptyAddress(fAddressAppInfo);
01848 bool backupEmpty=backupAddress.isDeleted() || emptyAddress==backupAddress;
01849 bool pilotEmpty=pilotAddress.isDeleted() || emptyAddress==pilotAddress;
01850 QString backupEntryString;
01851 if(!backupEmpty) backupEntryString=CSL1("%1 %2").arg(backupAddress.getField(entryFirstname)).arg(backupAddress.getField(entryLastname));
01852 else backupEntryString=i18n("(deleted)");
01853 QString pilotEntryString;
01854 if(!pilotEmpty) pilotEntryString=CSL1("%1 %2").arg(pilotAddress.getField(entryFirstname)).arg(pilotAddress.getField(entryLastname));
01855 else pilotEntryString=i18n("(deleted)");
01856
01857 if(!abEntry.isEmpty() && !pilotEmpty) lst << i18n("Duplicate both");
01858
01859 #ifdef DEBUG
01860 DEBUGCONDUIT<<"pilotAddress.firstName="<<pilotAddress.getField(entryFirstname)<<", pilotAddress.LastName="<<pilotAddress.getField(entryLastname)<<", pilotEmpty="<<pilotEmpty<<", pilotEntryString="<<pilotEntryString<<endl;
01861 DEBUGCONDUIT<<"backupAddress.firstName="<<backupAddress.getField(entryFirstname)<<", backupAddress.LastName="<<backupAddress.getField(entryLastname)<<", backupEmpty="<<backupEmpty<<", backupEntryString="<<backupEntryString<<endl;
01862 #endif
01863 res = ResolutionDialog(i18n("Address conflict"),
01864 i18n("<html><p>The following record was changed on the handheld and on the PC. </p>"
01865 "<table border=0>"
01866 "<tr><td><b>Handheld:</b></td><td>%1</td></tr>"
01867 "<tr><td><b>PC:</b></td><td>%2</td></tr>"
01868 "<tr><td><b>last sync:</b></td><td>%3</td></tr>"
01869 "</table>"
01870 "<p>How should this conflict be resolved?</p></html>")
01871 .arg(pilotEntryString)
01872 .arg(abEntry.isEmpty()? i18n("(deleted)") : abEntry.realName())
01873 .arg(backupEntryString)
01874 , lst, i18n("Remember my choice for all other records"), &remember);
01875 if(remember)
01876 {
01877 fConflictResolution = res;
01878 }
01879 return res;
01880 }
01881 }
01882
01883
01884 AbbrowserConduit::EConflictResolution AbbrowserConduit::ResolutionDialog(QString Title, QString Text, QStringList & lst, QString remember, bool * rem) const
01885 {
01886 FUNCTIONSETUP;
01887 ResolutionDlg *dlg = new ResolutionDlg(0L, fHandle, Title, Text, lst, remember);
01888 if(dlg->exec() == KDialogBase::Cancel)
01889 {
01890 delete dlg;
01891 return eDoNotResolve;
01892 }
01893 else
01894 {
01895 EConflictResolution res = (EConflictResolution)(dlg->ResolutionButtonGroup->id(dlg->ResolutionButtonGroup->selected()) + 1);
01896
01897 if(!remember.isEmpty() && rem)
01898 {
01899 *rem = dlg->rememberCheck->isChecked();
01900 }
01901 delete dlg;
01902 return res;
01903 }
01904 }
01905
01906
01907
01908
01909
01910 KABC::Addressee AbbrowserConduit::_findMatch(const PilotAddress & pilotAddress) const
01911 {
01912 FUNCTIONSETUP;
01913
01914
01915 if(!fFirstTime &&(pilotAddress.id() > 0))
01916 {
01917 QString id(addresseeMap[pilotAddress.id()]);
01918 #ifdef DEBUG
01919 DEBUGCONDUIT << fname << ": PilotRecord has id " << pilotAddress.id() << ", mapped to " << id << endl;
01920 #endif
01921 if(!id.isEmpty())
01922 {
01923 KABC::Addressee res(aBook->findByUid(id));
01924 if(!res.isEmpty()) return res;
01925 #ifdef DEBUG
01926 DEBUGCONDUIT << fname << ": PilotRecord has id " << pilotAddress.id() << ", but could not be found in the addressbook" << endl;
01927 #endif
01928 }
01929 }
01930
01931 bool piFirstEmpty =(pilotAddress.getField(entryFirstname).isEmpty());
01932 bool piLastEmpty =(pilotAddress.getField(entryLastname).isEmpty());
01933 bool piCompanyEmpty =(pilotAddress.getField(entryCompany).isEmpty());
01934
01935
01936 if(piFirstEmpty && piLastEmpty && piCompanyEmpty)
01937 {
01938 #ifdef DEBUG
01939 DEBUGCONDUIT << fname << ": entry has empty first, last name and company! Will not search in Addressbook" << endl;
01940 #endif
01941 return KABC::Addressee();
01942 }
01943
01944
01945
01946 for(KABC::AddressBook::Iterator iter = aBook->begin(); iter != aBook->end(); ++iter)
01947 {
01948 KABC::Addressee abEntry = *iter;
01949
01950 if(piFirstEmpty != abEntry.givenName().isEmpty() ||
01951 piLastEmpty != abEntry.familyName().isEmpty() ||
01952 piCompanyEmpty != abEntry.organization().isEmpty())
01953 {
01954 continue;
01955 }
01956 if(piFirstEmpty && piLastEmpty)
01957 {
01958 if(abEntry.organization() == pilotAddress.getField(entryCompany))
01959 {
01960 return *iter;
01961 }
01962 }
01963 else
01964
01965
01966 if(
01967 ((piLastEmpty && abEntry.familyName().isEmpty()) || (abEntry.familyName() == pilotAddress.getField(entryLastname))) &&
01968 ((piFirstEmpty && abEntry.givenName().isEmpty()) || (abEntry.givenName() == pilotAddress.getField(entryFirstname))) )
01969 {
01970 return *iter;
01971 }
01972
01973 }
01974 #ifdef DEBUG
01975 DEBUGCONDUIT << fname << ": Could not find any addressbook enty matching " << pilotAddress.getField(entryLastname) << endl;
01976 #endif
01977 return KABC::Addressee();
01978 }
01979
01980
01981
01982 void AbbrowserConduit::_checkDelete(PilotRecord* r, PilotRecord *s)
01983 {
01984 FUNCTIONSETUP;
01985
01986 bool archiveRecord =(r)?(r->getAttrib() & dlpRecAttrArchived):false;
01987
01988 KABC::Addressee e;
01989 PilotAddress adr(fAddressAppInfo, r), badr(fAddressAppInfo, s);
01990 if (r) e = _findMatch(adr);
01991 else if (s) e=_findMatch(badr);
01992
01993 if (!e.isEmpty() && !_equal(badr, e))
01994 {
01995
01996 switch(getEntryResolution(e, badr, adr))
01997 {
01998 case ePilotOverides:
01999 _deleteOnPC(r, s);
02000 break;
02001 case eAbbrowserOverides:
02002 _copy(adr, e);
02003
02004 adr.setAttrib(adr.getAttrib() & ~dlpRecAttrDeleted);
02005 if (_savePilotAddress(adr, e)) _saveAbEntry(e);
02006 break;
02007 case eRevertToBackup:
02008 _copy(e, badr);
02009 _savePilotAddress(badr, e);
02010 _saveAbEntry(e);
02011 break;
02012 case eDoNotResolve:
02013 default:
02014 break;
02015 }
02016 }
02017 else
02018 {
02019 if(fArchive && archiveRecord)
02020 {
02021 e = _changeOnPC(r, s);
02022 e.insertCustom(appString, flagString, QString::number(SYNCDEL));
02023 aBook->insertAddressee(e);
02024 }
02025 else
02026 {
02027 _deleteOnPC(r, s);
02028 }
02029 }
02030 }