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 #include "options.h"
00035
00036 #include <qregexp.h>
00037
00038 #include <kglobal.h>
00039 #include <kabc/addressee.h>
00040
00041 #include "kabcRecord.h"
00042
00066 static KABC::PhoneNumber::Types pilotToPhoneMap[8] = {
00067 KABC::PhoneNumber::Work,
00068 KABC::PhoneNumber::Home,
00069 KABC::PhoneNumber::Fax,
00070 (KABC::PhoneNumber::Types)0,
00071 (KABC::PhoneNumber::Types)0,
00072 KABC::PhoneNumber::Home,
00073 KABC::PhoneNumber::Pager,
00074 KABC::PhoneNumber::Cell
00075 } ;
00076
00077 KABC::PhoneNumber::List KABCSync::getPhoneNumbers(const PilotAddress &a)
00078 {
00079 FUNCTIONSETUP;
00080
00081 KABC::PhoneNumber::List list;
00082 QString test;
00083
00084 PhoneSlot shownPhone = a.getShownPhone();
00085
00086 DEBUGKPILOT << fname << ": preferred pilot index is: ["
00087 << shownPhone << "], preferred phone number is: ["
00088 << a.getField(shownPhone) << "]" << endl;
00089
00090 for (PhoneSlot i = PhoneSlot::begin(); i.isValid(); ++i)
00091 {
00092
00093 if ( a.getPhoneType(i) == PilotAddressInfo::eEmail )
00094 {
00095 continue;
00096 }
00097
00098 test = a.getField(i);
00099
00100 if (test.isEmpty())
00101 {
00102 continue;
00103 }
00104
00105 int phoneType = pilotToPhoneMap[a.getPhoneType(i)];
00106
00107
00108 if (phoneType >=0)
00109 {
00110
00111 if (shownPhone == i)
00112 {
00113 phoneType |= KABC::PhoneNumber::Pref;
00114 DEBUGKPILOT << fname << ": found preferred pilot index: ["
00115 << i << "], text: [" << test << "]" << endl;
00116 }
00117 KABC::PhoneNumber ph(test, phoneType);
00118 list.append(ph);
00119 }
00120 else
00121 {
00122 DEBUGKPILOT << fname << ": whoopsie. pilot phone number: ["
00123 << test << "], index: [" << i << "], type: ["
00124 << phoneType << "], has no corresponding PhoneNumber type." << endl;
00125 }
00126 }
00127
00128 DEBUGKPILOT << fname << ": returning: ["
00129 << list.count() << "] phone numbers." << endl;
00130
00131 return list;
00132 }
00133
00134 void KABCSync::setPhoneNumbers(const PilotAddressInfo &info,
00135 PilotAddress &a,
00136 const KABC::PhoneNumber::List &list)
00137 {
00138 FUNCTIONSETUP;
00139 QString test;
00140
00141
00142 for ( PhoneSlot i = PhoneSlot::begin(); i.isValid() ; ++i )
00143 {
00144 PilotAddressInfo::EPhoneType ind = a.getPhoneType( i );
00145 if (ind != PilotAddressInfo::eEmail)
00146 {
00147 a.setField(i, QString());
00148 }
00149 }
00150
00151
00152
00153
00154 for(KABC::PhoneNumber::List::ConstIterator listIter = list.begin();
00155 listIter != list.end(); ++listIter)
00156 {
00157 KABC::PhoneNumber phone = *listIter;
00158
00159 PilotAddressInfo::EPhoneType phoneType = PilotAddressInfo::eHome;
00160
00161 for ( int pilotPhoneType = PilotAddressInfo::eWork;
00162 pilotPhoneType <= PilotAddressInfo::eMobile;
00163 ++pilotPhoneType)
00164 {
00165 int phoneKey = pilotToPhoneMap[pilotPhoneType];
00166 if ( phone.type() & phoneKey)
00167 {
00168 DEBUGKPILOT << fname << ": found pilot type: ["
00169 << pilotPhoneType << "] ("
00170 << info.phoneLabel( (PilotAddressInfo::EPhoneType)pilotPhoneType)
00171 << ") for PhoneNumber: ["
00172 << phone.number() << "]" << endl;
00173
00174 phoneType = (PilotAddressInfo::EPhoneType) pilotPhoneType;
00175 break;
00176 }
00177 }
00178 PhoneSlot fieldSlot =
00179 a.setPhoneField(phoneType, phone.number(), PilotAddress::NoFlags);
00180
00181
00182 if (fieldSlot.isValid() && (phone.type() & KABC::PhoneNumber::Pref))
00183 {
00184 DEBUGKPILOT << fname << ": found preferred PhoneNumber. "
00185 << "setting showPhone to index: ["
00186 << fieldSlot << "], PhoneNumber: ["
00187 << phone.number() << "]" << endl;
00188 a.setShownPhone( fieldSlot );
00189 }
00190
00191 if (!fieldSlot.isValid())
00192 {
00193 DEBUGKPILOT << fname << ": Phone listing overflowed." << endl;
00194 }
00195 }
00196
00197 DEBUGKPILOT << fname << ": Pilot's showPhone now: ["
00198 << a.getShownPhone() << "]." << endl;
00199
00200
00201
00202 QString pref = a.getField(a.getShownPhone());
00203 if (!a.getShownPhone().isValid() || pref.isEmpty())
00204 {
00205 DEBUGKPILOT << fname << ": Pilot's showPhone: ["
00206 << a.getShownPhone()
00207 << "] not properly set to a default."
00208 << endl;
00209
00210 for (PhoneSlot i = PhoneSlot::begin(); i.isValid(); ++i)
00211 {
00212 pref = a.getField(i);
00213 if (!pref.isEmpty())
00214 {
00215 a.setShownPhone( i );
00216 DEBUGKPILOT << fname << ": Pilot's showPhone now: ["
00217 << a.getShownPhone()
00218 << "], and that's final." << endl;
00219 break;
00220 }
00221 }
00222 }
00223 }
00224
00225 unsigned int KABCSync::bestMatchedCategory(const QStringList &pccategories,
00226 const PilotAddressInfo &info,
00227 unsigned int hhcategory)
00228 {
00229 FUNCTIONSETUP;
00230
00231 if (pccategories.size()<1)
00232 {
00233 return Pilot::Unfiled;
00234 }
00235
00236
00237
00238 if (Pilot::validCategory(hhcategory) &&
00239 pccategories.contains(info.categoryName(hhcategory)))
00240 {
00241 return hhcategory;
00242 }
00243
00244
00245
00246 for(QStringList::ConstIterator it = pccategories.begin(); it != pccategories.end(); ++it)
00247 {
00248
00249 int c = info.findCategory( *it, false );
00250 if ( c >= 0)
00251 {
00252 Q_ASSERT(Pilot::validCategory(c));
00253 return c;
00254 }
00255 }
00256
00257
00258 return Pilot::Unfiled;
00259 }
00260
00261 void KABCSync::setCategory(KABC::Addressee & abEntry, const QString &cat)
00262 {
00263 if ( (!cat.isEmpty()))
00264 {
00265 abEntry.insertCategory(cat);
00266 }
00267 }
00268
00269
00270 QString KABCSync::getFieldForHHCustom(
00271 const unsigned int index,
00272 const KABC::Addressee &abEntry,
00273 const KABCSync::Settings &settings)
00274 {
00275 FUNCTIONSETUPL(4);
00276
00277 QString retval;
00278
00279 if (index>3)
00280 {
00281 WARNINGKPILOT << "Bad index number " << index << endl;
00282 retval = QString();
00283 }
00284 if (settings.customMapping().count() != 4)
00285 {
00286 WARNINGKPILOT << "Mapping does not have 4 elements." << index << endl;
00287 retval = QString();
00288 }
00289
00290 switch (settings.custom(index))
00291 {
00292 case eCustomBirthdate:
00293 if (settings.dateFormat().isEmpty())
00294 {
00295 retval = KGlobal::locale()->formatDate(abEntry.birthday().date());
00296 }
00297 else
00298 {
00299 QString tmpfmt(KGlobal::locale()->dateFormat());
00300 KGlobal::locale()->setDateFormat(settings.dateFormat());
00301 QString ret(KGlobal::locale()->formatDate(abEntry.birthday().date()));
00302 KGlobal::locale()->setDateFormat(tmpfmt);
00303 retval = ret;
00304 }
00305 break;
00306 case eCustomURL:
00307 retval = abEntry.url().url();
00308 break;
00309 case eCustomIM:
00310 retval = abEntry.custom(CSL1("KADDRESSBOOK"), CSL1("X-IMAddress"));
00311 break;
00312 case eCustomField:
00313 default:
00314 retval = abEntry.custom(appString, CSL1("CUSTOM")+QString::number(index));
00315 break;
00316 }
00317
00318 return retval;
00319 }
00320
00321 void KABCSync::setFieldFromHHCustom(
00322 const unsigned int index,
00323 KABC::Addressee &abEntry,
00324 const QString &value,
00325 const KABCSync::Settings &settings)
00326 {
00327 FUNCTIONSETUPL(4);
00328
00329 if (index>3)
00330 {
00331 WARNINGKPILOT << "Bad index number " << index << endl;
00332 return;
00333 }
00334 if (settings.customMapping().count() != 4)
00335 {
00336 WARNINGKPILOT << "Mapping does not have 4 elements." << index << endl;
00337 return;
00338 }
00339
00340 switch (settings.custom(index))
00341 {
00342 case eCustomBirthdate:
00343 {
00344 QDate bdate;
00345 bool ok=false;
00346 if (settings.dateFormat().isEmpty())
00347 {
00348
00349 bdate=KGlobal::locale()->readDate(value, &ok);
00350 }
00351 else
00352 {
00353
00354 bdate=KGlobal::locale()->readDate(value, settings.dateFormat(), &ok);
00355 }
00356
00357 if (!ok)
00358 {
00359 QString format = KGlobal::locale()->dateFormatShort();
00360 QRegExp re(CSL1("%[yY][^%]*"));
00361 format.remove(re);
00362 bdate = KGlobal::locale()->readDate(value, format, &ok);
00363 }
00364 DEBUGKPILOT << "Birthdate from " << index << "-th custom field: "
00365 << bdate.toString() << endl;
00366 DEBUGKPILOT << "Is Valid: " << bdate.isValid() << endl;
00367 if (bdate.isValid())
00368 {
00369 abEntry.setBirthday(bdate);
00370 }
00371 else
00372 {
00373 abEntry.insertCustom(CSL1("KADDRESSBOOK"), CSL1("X-Birthday"), value);
00374 }
00375 break;
00376 }
00377 case eCustomURL:
00378 abEntry.setUrl(value);
00379 break;
00380 case eCustomIM:
00381 abEntry.insertCustom(CSL1("KADDRESSBOOK"), CSL1("X-IMAddress"), value);
00382 break;
00383 case eCustomField:
00384 default:
00385 abEntry.insertCustom(appString, CSL1("CUSTOM")+QString::number(index), value);
00386 break;
00387 }
00388 }
00389
00390
00395 KABC::Address KABCSync::getAddress(const KABC::Addressee &abEntry, const KABCSync::Settings &s)
00396 {
00397
00398
00399
00400 KABC::Address ad(abEntry.address(KABC::Address::Pref));
00401 if (!ad.isEmpty()) return ad;
00402
00403
00404 int type = s.preferHome() ? KABC::Address::Home : KABC::Address::Work;
00405 ad=abEntry.address(type);
00406 if (!ad.isEmpty()) return ad;
00407
00408
00409 type = !s.preferHome() ? KABC::Address::Home : KABC::Address::Work;
00410 ad=abEntry.address(type);
00411 if (!ad.isEmpty()) return ad;
00412
00413
00414 type = s.preferHome() ? KABC::Address::Home : KABC::Address::Work;
00415 return abEntry.address(type | KABC::Address::Pref);
00416 }
00417
00418
00419 QString KABCSync::getFieldForHHOtherPhone(const KABC::Addressee & abEntry, const KABCSync::Settings &s)
00420 {
00421 switch(s.fieldForOtherPhone())
00422 {
00423 case eOtherPhone:
00424 return abEntry.phoneNumber(0).number();
00425 case eAssistant:
00426 return abEntry.custom(CSL1("KADDRESSBOOK"), CSL1("AssistantsName"));
00427 case eBusinessFax:
00428 return abEntry.phoneNumber(KABC::PhoneNumber::Fax | KABC::PhoneNumber::Work).number();
00429 case eCarPhone:
00430 return abEntry.phoneNumber(KABC::PhoneNumber::Car).number();
00431 case eEmail2:
00432 return abEntry.emails().first();
00433 case eHomeFax:
00434 return abEntry.phoneNumber(KABC::PhoneNumber::Fax | KABC::PhoneNumber::Home).number();
00435 case eTelex:
00436 return abEntry.phoneNumber(KABC::PhoneNumber::Bbs).number();
00437 case eTTYTTDPhone:
00438 return abEntry.phoneNumber(KABC::PhoneNumber::Pcs).number();
00439 default:
00440 return QString::null;
00441 }
00442 }
00443
00444 void KABCSync::setFieldFromHHOtherPhone(KABC::Addressee & abEntry, const QString &nr, const KABCSync::Settings &s)
00445 {
00446 int phoneType = 0;
00447 switch (s.fieldForOtherPhone())
00448 {
00449
00450 case eAssistant:
00451 abEntry.insertCustom(CSL1("KADDRESSBOOK"), CSL1("AssistantsName"), nr);
00452 return;
00453
00454 case eEmail2:
00455 abEntry.insertEmail(nr);
00456 return;
00457
00458 case eOtherPhone:
00459 phoneType = 0;
00460 break;
00461 case eBusinessFax:
00462 phoneType = KABC::PhoneNumber::Fax | KABC::PhoneNumber::Work;
00463 break;
00464 case eHomeFax:
00465 phoneType = KABC::PhoneNumber::Fax | KABC::PhoneNumber::Home;
00466 break;
00467 case eCarPhone:
00468 phoneType = KABC::PhoneNumber::Car;
00469 break;
00470 case eTelex:
00471 phoneType = KABC::PhoneNumber::Bbs;
00472 break;
00473 case eTTYTTDPhone:
00474 phoneType = KABC::PhoneNumber::Pcs;
00475 break;
00476 default:
00477 WARNINGKPILOT << "Unknown phone mapping " << s.fieldForOtherPhone() << endl;
00478 phoneType = 0;
00479 }
00480 KABC::PhoneNumber phone = abEntry.phoneNumber(phoneType);
00481 phone.setNumber(nr);
00482 phone.setType(phoneType);
00483 abEntry.insertPhoneNumber(phone);
00484 }
00485
00486 void KABCSync::setAddress(PilotAddress &toPilotAddr,
00487 const KABC::Address & abAddress)
00488 {
00489 toPilotAddr.setField(entryAddress, abAddress.street());
00490 toPilotAddr.setField(entryCity, abAddress.locality());
00491 toPilotAddr.setField(entryState, abAddress.region());
00492 toPilotAddr.setField(entryZip, abAddress.postalCode());
00493 toPilotAddr.setField(entryCountry, abAddress.country());
00494 }
00495
00496
00497 bool KABCSync::isArchived(const KABC::Addressee &addr)
00498 {
00499 return addr.custom(KABCSync::appString, KABCSync::flagString) == QString::number(SYNCDEL);
00500 }
00501
00502 void KABCSync::makeArchived(KABC::Addressee &addr)
00503 {
00504 FUNCTIONSETUP;
00505 addr.insertCustom(KABCSync::appString, KABCSync::flagString, QString::number(SYNCDEL));
00506 addr.removeCustom(KABCSync::appString, KABCSync::idString);
00507 }
00508
00509
00510
00511
00512 void KABCSync::copy(PilotAddress &toPilotAddr,
00513 const KABC::Addressee &fromAbEntry,
00514 const PilotAddressInfo &appInfo,
00515 const KABCSync::Settings &syncSettings)
00516 {
00517 FUNCTIONSETUP;
00518
00519 toPilotAddr.setDeleted(false);
00520
00521
00522
00523 toPilotAddr.setField(entryLastname, fromAbEntry.familyName());
00524 toPilotAddr.setField(entryFirstname, fromAbEntry.givenName());
00525 toPilotAddr.setField(entryCompany, fromAbEntry.organization());
00526 toPilotAddr.setField(entryTitle, fromAbEntry.prefix());
00527 toPilotAddr.setField(entryNote, fromAbEntry.note());
00528
00529
00530 toPilotAddr.setEmails(fromAbEntry.emails());
00531
00532
00533
00534
00535 KABCSync::setPhoneNumbers(appInfo,toPilotAddr,fromAbEntry.phoneNumbers());
00536
00537
00538
00539 QString oth = KABCSync::getFieldForHHOtherPhone(fromAbEntry,syncSettings);
00540 DEBUGKPILOT << fname << ": putting: ["<<oth<<"] into Palm's other"<<endl;
00541 toPilotAddr.setPhoneField(PilotAddressInfo::eOther,
00542 oth, PilotAddress::Replace);
00543
00544 KABC::Address homeAddress = KABCSync::getAddress(fromAbEntry, syncSettings);
00545 KABCSync::setAddress(toPilotAddr, homeAddress);
00546
00547
00548 unsigned int customIndex = 0;
00549 unsigned int hhField = entryCustom1;
00550
00551 for ( ; customIndex<4; ++customIndex,++hhField )
00552 {
00553 toPilotAddr.setField(hhField,getFieldForHHCustom(customIndex,fromAbEntry,syncSettings));
00554 }
00555
00556 int categoryForHH = KABCSync::bestMatchedCategory(fromAbEntry.categories(),
00557 appInfo,toPilotAddr.category());
00558 toPilotAddr.setCategory(categoryForHH);
00559
00560 if (isArchived(fromAbEntry))
00561 {
00562 toPilotAddr.setArchived( true );
00563 }
00564 else
00565 {
00566 toPilotAddr.setArchived( false );
00567 }
00568 }
00569
00570 void KABCSync::copy(KABC::Addressee &toAbEntry,
00571 const PilotAddress &fromPiAddr,
00572 const PilotAddressInfo &appInfo,
00573 const KABCSync::Settings &syncSettings)
00574 {
00575 FUNCTIONSETUP;
00576
00577
00578 toAbEntry.setFamilyName(fromPiAddr.getField(entryLastname));
00579 toAbEntry.setGivenName(fromPiAddr.getField(entryFirstname));
00580 toAbEntry.setOrganization(fromPiAddr.getField(entryCompany));
00581 toAbEntry.setPrefix(fromPiAddr.getField(entryTitle));
00582 toAbEntry.setNote(fromPiAddr.getField(entryNote));
00583
00584
00585
00586 toAbEntry.setFormattedName(toAbEntry.realName());
00587
00588
00589
00590
00591 toAbEntry.setEmails(fromPiAddr.getEmails());
00592
00593
00594
00595
00596
00597 KABC::PhoneNumber::List old = toAbEntry.phoneNumbers();
00598 for (KABC::PhoneNumber::List::Iterator it = old.begin(); it != old.end(); ++it) {
00599 KABC::PhoneNumber phone = *it;
00600 toAbEntry.removePhoneNumber(phone);
00601 }
00602
00603
00604 KABC::PhoneNumber::List phones = KABCSync::getPhoneNumbers(fromPiAddr);
00605 for (KABC::PhoneNumber::List::Iterator it = phones.begin(); it != phones.end(); ++it) {
00606 KABC::PhoneNumber phone = *it;
00607
00608 if (phone.type() & KABC::PhoneNumber::Fax)
00609 {
00610 phone.setType(syncSettings.faxTypeOnPC());
00611 }
00612 toAbEntry.insertPhoneNumber(phone);
00613 }
00614
00615
00616
00617
00618 KABCSync::setFieldFromHHOtherPhone(toAbEntry,
00619 fromPiAddr.getPhoneField(PilotAddressInfo::eOther),syncSettings);
00620
00621
00622
00623
00624
00625 KABC::Address::List oAddr = toAbEntry.addresses();
00626 for (KABC::Address::List::Iterator it = oAddr.begin(); it != oAddr.end(); ++it) {
00627 const KABC::Address addr = *it;
00628 toAbEntry.removeAddress(addr);
00629 }
00630 KABC::Address homeAddress = KABCSync::getAddress(toAbEntry,syncSettings);
00631 homeAddress.setStreet(fromPiAddr.getField(entryAddress));
00632 homeAddress.setLocality(fromPiAddr.getField(entryCity));
00633 homeAddress.setRegion(fromPiAddr.getField(entryState));
00634 homeAddress.setPostalCode(fromPiAddr.getField(entryZip));
00635 homeAddress.setCountry(fromPiAddr.getField(entryCountry));
00636 toAbEntry.insertAddress(homeAddress);
00637
00638 unsigned int customIndex = 0;
00639 unsigned int hhField = entryCustom1;
00640
00641 for ( ; customIndex<4; ++customIndex,++hhField )
00642 {
00643 KABCSync::setFieldFromHHCustom(customIndex,
00644 toAbEntry,
00645 fromPiAddr.getField(hhField),
00646 syncSettings);
00647 }
00648
00649
00650
00651
00652
00653 toAbEntry.insertCustom(KABCSync::appString, KABCSync::idString, QString::number(fromPiAddr.id()));
00654
00655 KABCSync::setCategory(toAbEntry, appInfo.categoryName(fromPiAddr.category()));
00656
00657 showAddressee(toAbEntry);
00658 }
00659
00660 void KABCSync::showAddressee(const KABC::Addressee & abAddress)
00661 {
00662 FUNCTIONSETUP;
00663 #ifdef DEBUG
00664 DEBUGKPILOT << "\tAbbrowser Contact Entry" << endl;
00665 if (abAddress.isEmpty())
00666 {
00667 DEBUGKPILOT<< "\t\tEMPTY"<<endl;
00668 return;
00669 }
00670 DEBUGKPILOT << "\t\tLast name = " << abAddress.familyName() << endl;
00671 DEBUGKPILOT << "\t\tFirst name = " << abAddress.givenName() << endl;
00672 DEBUGKPILOT << "\t\tCompany = " << abAddress.organization() << endl;
00673 DEBUGKPILOT << "\t\tJob Title = " << abAddress.prefix() << endl;
00674 DEBUGKPILOT << "\t\tNote = " << abAddress.note() << endl;
00675 DEBUGKPILOT << "\t\tCategory = " << abAddress.categories().first() << endl;
00676 DEBUGKPILOT << "\t\tEmail = " << abAddress.emails().join(",") << endl;
00677
00678 KABC::PhoneNumber::List phs = abAddress.phoneNumbers();
00679 for (KABC::PhoneNumber::List::Iterator it = phs.begin(); it != phs.end(); ++it) {
00680 KABC::PhoneNumber phone = *it;
00681 DEBUGKPILOT << "\t\t" << phone.label()
00682 << "= " << phone.number() << endl;
00683 }
00684
00685 KABC::Address::List ads = abAddress.addresses();
00686 for (KABC::Address::List::Iterator it = ads.begin(); it != ads.end(); ++it) {
00687 const KABC::Address addr = *it;
00688 DEBUGKPILOT << "\t\tAddress = " << addr.street() <<endl;
00689 DEBUGKPILOT << "\t\tLocality = " << addr.locality() <<endl;
00690 DEBUGKPILOT << "\t\tRegion = " << addr.region() <<endl;
00691 DEBUGKPILOT << "\t\tPostal code = " << addr.postalCode() <<endl;
00692 DEBUGKPILOT << "\t\tCountry = " << addr.country() <<endl << endl;
00693 }
00694 #else
00695 Q_UNUSED( abAddress );
00696 #endif
00697 }
00698
00699
00700
00701
00702 KABCSync::Settings::Settings() :
00703 fDateFormat(),
00704 fCustomMapping(4),
00705 fOtherPhone(eOtherPhone),
00706 fPreferHome(true),
00707 fFaxTypeOnPC(KABC::PhoneNumber::Fax | KABC::PhoneNumber::Home)
00708 {
00709 }
00710