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 static const char *pilotadress_id =
00032 "$Id: pilotAddress.cc 450284 2005-08-17 20:49:09Z adridg $";
00033
00034 #ifndef _KPILOT_OPTIONS_H
00035 #include "options.h"
00036 #endif
00037
00038 #include <stdlib.h>
00039 #include <assert.h>
00040
00041 #include <qtextcodec.h>
00042 #include <qstringlist.h>
00043
00044 #include "pilotAddress.h"
00045
00046
00047 #define MAXFIELDS 19
00048
00049 PilotAddress::PilotAddress(struct AddressAppInfo &appInfo,
00050 PilotRecord * rec) :
00051 PilotAppCategory(rec),
00052 fAppInfo(appInfo),
00053 fAddressInfo()
00054 {
00055 FUNCTIONSETUPL(4);
00056 #if PILOT_LINK_NUMBER >= PILOT_LINK_0_12_0
00057 pi_buffer_t b;
00058 b.data = (unsigned char *) rec->getData();
00059 b.allocated = b.used = rec->size();
00060 if (rec) unpack_Address(&fAddressInfo, &b, address_v1);
00061 #else
00062 if (rec) unpack_Address(&fAddressInfo, (unsigned char *) rec->data(), rec->size());
00063 #endif
00064 (void) pilotadress_id;
00065 _loadMaps();
00066 }
00067
00068 PilotAddress::PilotAddress(struct AddressAppInfo &appInfo) :
00069 PilotAppCategory(),
00070 fAppInfo(appInfo)
00071 {
00072 FUNCTIONSETUPL(4);
00073 reset();
00074
00075
00076
00077 fAddressInfo.phoneLabel[0] = (int) eWork;
00078 fAddressInfo.phoneLabel[1] = (int) eHome;
00079 fAddressInfo.phoneLabel[2] = (int) eOther;
00080 fAddressInfo.phoneLabel[3] = (int) eMobile;
00081 fAddressInfo.phoneLabel[4] = (int) eEmail;
00082
00083 _loadMaps();
00084 }
00085
00086 PilotAddress::PilotAddress(PilotAddressInfo *info, PilotRecord *rec) :
00087 PilotAppCategory(rec),
00088 fAppInfo(*(info->info())),
00089 fAddressInfo()
00090 {
00091 FUNCTIONSETUPL(4);
00092 reset();
00093
00094 if (rec)
00095 {
00096 #if PILOT_LINK_NUMBER >= PILOT_LINK_0_12_0
00097 pi_buffer_t b;
00098 b.data = (unsigned char *) rec->getData();
00099 b.allocated = b.used = rec->size();
00100 unpack_Address(&fAddressInfo, &b, address_v1);
00101 #else
00102 unpack_Address(&fAddressInfo, (unsigned char *) rec->data(), rec->size());
00103 #endif
00104 }
00105 else
00106 {
00107 fAddressInfo.phoneLabel[0] = (int) eWork;
00108 fAddressInfo.phoneLabel[1] = (int) eHome;
00109 fAddressInfo.phoneLabel[2] = (int) eOther;
00110 fAddressInfo.phoneLabel[3] = (int) eMobile;
00111 fAddressInfo.phoneLabel[4] = (int) eEmail;
00112 }
00113
00114 _loadMaps();
00115 }
00116
00117 PilotAddress::PilotAddress(const PilotAddress & copyFrom) :
00118 PilotAppCategory(copyFrom),
00119 fAppInfo(copyFrom.fAppInfo),
00120 fAddressInfo()
00121 {
00122 FUNCTIONSETUPL(4);
00123 _copyAddressInfo(copyFrom.fAddressInfo);
00124
00125 _loadMaps();
00126 }
00127
00128 PilotAddress & PilotAddress::operator = (const PilotAddress & copyFrom)
00129 {
00130 FUNCTIONSETUPL(4);
00131 PilotAppCategory::operator = (copyFrom);
00132 _copyAddressInfo(copyFrom.fAddressInfo);
00133 return *this;
00134 }
00135
00136 bool PilotAddress::operator==(const PilotAddress &compareTo)
00137 {
00138 FUNCTIONSETUPL(4);
00139
00140
00141
00142
00143 for (int i=0; i<MAXFIELDS; i++) {
00144
00145 if ( !getFieldP(i) && compareTo.getFieldP(i)) return false;
00146 if ( getFieldP(i) && !compareTo.getFieldP(i)) return false;
00147
00148 if ( (getFieldP(i) != compareTo.getFieldP(i)) && ( strcmp(getFieldP(i), compareTo.getFieldP(i)) ) ) return false;
00149 }
00150 return true;
00151 }
00152
00153
00154 void PilotAddress::_copyAddressInfo(const struct Address ©From)
00155 {
00156 FUNCTIONSETUPL(4);
00157 fAddressInfo.showPhone = copyFrom.showPhone;
00158
00159 for (int labelLp = 0; labelLp < 5; labelLp++)
00160 {
00161 fAddressInfo.phoneLabel[labelLp] =
00162 copyFrom.phoneLabel[labelLp];
00163 }
00164
00165 for (int entryLp = 0; entryLp < MAXFIELDS; entryLp++)
00166 {
00167 if (copyFrom.entry[entryLp])
00168 fAddressInfo.entry[entryLp] =
00169 qstrdup(copyFrom.entry[entryLp]);
00170 else
00171 fAddressInfo.entry[entryLp] = 0L;
00172 }
00173 }
00174
00175
00176 PilotAddress::~PilotAddress()
00177 {
00178 FUNCTIONSETUPL(4);
00179 free_Address(&fAddressInfo);
00180 }
00181
00182 QString PilotAddress::getTextRepresentation(bool richText)
00183 {
00184 QString text, tmp;
00185
00186 QString par = richText?CSL1("<p>"):CSL1("");
00187 QString ps = richText?CSL1("</p>"):CSL1("\n");
00188 QString br = richText?CSL1("<br/>"):CSL1("\n");
00189
00190
00191 text += par;
00192 if (!getField(entryTitle).isEmpty())
00193 {
00194 text += rtExpand(getField(entryTitle), richText);
00195 text += CSL1(" ");
00196 }
00197
00198 tmp = richText?CSL1("<b><big>%1%2%3</big></b>"):CSL1("%1%2%3");
00199 if (!getField(entryFirstname).isEmpty())
00200 tmp=rtExpand(tmp.arg(getField(entryFirstname)), richText).arg(CSL1(" "));
00201 else
00202 tmp=tmp.arg(CSL1(" ")).arg(CSL1(" "));
00203 tmp=tmp.arg(rtExpand(getField(entryLastname), richText));
00204 text += tmp;
00205 text += ps;
00206
00207
00208 if (!getField(entryCompany).isEmpty())
00209 {
00210 text += par;
00211 text += rtExpand(getField(entryCompany), richText);
00212 text += ps;
00213 }
00214
00215
00216 text += par;
00217 for (int i = entryPhone1; i <= entryPhone5; i++)
00218 if (!getField(i).isEmpty())
00219 {
00220 if (richText)
00221 {
00222 if (getShownPhone() == i - entryPhone1)
00223 tmp=CSL1("<small>%1: </small><b>%2</b>");
00224 else
00225 tmp=CSL1("<small>%1: </small>%2");
00226 }
00227 else
00228 tmp=CSL1("%1: %2");
00229 tmp=tmp.arg(PilotAppCategory::codec()->toUnicode(
00230 fAppInfo.phoneLabels[getPhoneLabelIndex(i-entryPhone1)]));
00231 tmp=tmp.arg(rtExpand(getField(i), richText));
00232 text += tmp;
00233 text += br;
00234 }
00235 text += ps;
00236
00237
00238 text += par;
00239 if (!getField(entryAddress).isEmpty())
00240 {
00241 text += rtExpand(getField(entryAddress), richText);
00242 text += br;
00243 }
00244 if (!getField(entryCity).isEmpty())
00245 {
00246 text += rtExpand(getField(entryCity), richText);
00247 text += CSL1(" ");
00248 }
00249 if (!getField(entryState).isEmpty())
00250 {
00251 text += rtExpand(getField(entryState), richText);
00252 text += CSL1(" ");
00253 }
00254 if (!getField(entryZip).isEmpty())
00255 {
00256 text += rtExpand(getField(entryZip), richText);
00257 }
00258 text += br;
00259 if (!getField(entryCountry).isEmpty())
00260 {
00261 text += rtExpand(getField(entryCountry), richText);
00262 text += br;
00263 }
00264 text += ps;
00265
00266
00267 text += par;
00268 for (int i = entryCustom1; i <= entryCustom4; i++)
00269 if (!getField(i).isEmpty())
00270 {
00271 text += rtExpand(getField(i), richText);
00272 text += br;
00273 }
00274 text += ps;
00275
00276
00277 if (!getCategoryLabel().isEmpty())
00278 {
00279 text += par;
00280 text += rtExpand(getCategoryLabel(), richText);
00281 text += ps;
00282 }
00283
00284
00285 if (!getField(entryNote).isEmpty())
00286 {
00287 text += richText?CSL1("<hr/>"):CSL1("-----------------------------\n");
00288 text += par;
00289 text += rtExpand(getField(entryNote), richText);
00290 text += ps;
00291 }
00292
00293 return text;
00294 }
00295
00296 QString PilotAddress::getCategoryLabel() const
00297 {
00298 int cat(category());
00299 if (cat>0) return codec()->toUnicode(fAppInfo.category.name[cat]);
00300 else return QString::null;
00301 }
00302
00303 QStringList PilotAddress::getEmails() const
00304 {
00305 FUNCTIONSETUP;
00306 QStringList list;
00307 QString test;
00308
00309 for (int i = entryPhone1; i <= entryPhone5; i++)
00310 {
00311 test = getField(i);
00312 if (!test.isEmpty())
00313 {
00314 int ind = getPhoneLabelIndex(i-entryPhone1);
00315 if (ind == eEmail)
00316 {
00317 list.append(test);
00318 }
00319 }
00320 }
00321
00322 #ifdef DEBUG
00323 DEBUGDAEMON << fname << ": returning: ["
00324 << list.size() << "] e-mail addresses." << endl;
00325 #endif
00326 return list;
00327 }
00328
00329 KABC::PhoneNumber::List PilotAddress::getPhoneNumbers() const
00330 {
00331 FUNCTIONSETUP;
00332
00333 KABC::PhoneNumber::List list;
00334 QString test;
00335
00336 int shownPhone = getShownPhone() + entryPhone1;
00337 #ifdef DEBUG
00338 DEBUGDAEMON << fname << ": preferred pilot index is: ["
00339 << shownPhone << "], preferred phone number is: ["
00340 << getField(shownPhone) << "]" << endl;
00341 #endif
00342
00343 for (int i = entryPhone1; i <= entryPhone5; i++)
00344 {
00345 test = getField(i);
00346
00347 if (!test.isEmpty())
00348 {
00349 int ind = getPhoneLabelIndex(i-entryPhone1);
00350
00351 if (ind != eEmail)
00352 {
00353 int phoneType = pilotToPhoneMap[ind];
00354
00355
00356 if (phoneType >=0)
00357 {
00358
00359 if (shownPhone == i) {
00360 phoneType |= KABC::PhoneNumber::Pref;
00361 #ifdef DEBUG
00362 DEBUGDAEMON << fname << ": found preferred pilot index: ["
00363 << i << "], text: [" << test << "]" << endl;
00364 #endif
00365 }
00366 KABC::PhoneNumber ph(test, phoneType);
00367 list.append(ph);
00368 } else {
00369 #ifdef DEBUG
00370 DEBUGDAEMON << fname << ": whoopsie. pilot phone number: ["
00371 << test << "], index: [" << i << "], type: ["
00372 << ind << "], has no corresponding PhoneNumber type." << endl;
00373 #endif
00374 }
00375 }
00376 }
00377 }
00378 #ifdef DEBUG
00379 DEBUGDAEMON << fname << ": returning: ["
00380 << list.size() << "] phone numbers" << endl;
00381 #endif
00382 return list;
00383 }
00384
00385 void PilotAddress::setPhoneNumbers(KABC::PhoneNumber::List list)
00386 {
00387 FUNCTIONSETUP;
00388 QString test;
00389
00390
00391 for (int i = entryPhone1; i <= entryPhone5; i++)
00392 {
00393 test = getField(i);
00394 if (!test.isEmpty())
00395 {
00396 int ind = getPhoneLabelIndex(i-entryPhone1);
00397 if (ind != eEmail)
00398 {
00399 setField(i, "");
00400 }
00401 }
00402 }
00403
00404
00405
00406
00407 QMap<int, int>::ConstIterator it;
00408
00409 for(KABC::PhoneNumber::List::Iterator listIter = list.begin();
00410 listIter != list.end(); ++listIter)
00411 {
00412 KABC::PhoneNumber phone = *listIter;
00413
00414 int category = eHome;
00415
00416 for ( it = pilotToPhoneMap.begin(); it != pilotToPhoneMap.end(); ++it )
00417 {
00418 int pilotKey = it.key();
00419 int phoneKey = it.data();
00420 if ( phone.type() & phoneKey)
00421 {
00422 #ifdef DEBUG
00423 DEBUGDAEMON << fname << ": found pilot type: ["
00424 << pilotKey << "] ("
00425 << fAppInfo.phoneLabels[pilotKey]
00426 << ") for PhoneNumber: ["
00427 << phone.number() << "]" << endl;
00428 #endif
00429 category = pilotKey;
00430 break;
00431 }
00432 }
00433 int fieldSlot = setPhoneField(static_cast<PilotAddress::EPhoneType>(category),
00434 phone.number(), true, false);
00435
00436
00437 if (phone.type() & KABC::PhoneNumber::Pref) {
00438 #ifdef DEBUG
00439 DEBUGDAEMON << fname << ": found preferred PhoneNumber. "
00440 << "setting showPhone to index: ["
00441 << fieldSlot << "], PhoneNumber: ["
00442 << phone.number() << "]" << endl;
00443 #endif
00444 fAddressInfo.showPhone = fieldSlot - entryPhone1;
00445 }
00446 }
00447
00448 #ifdef DEBUG
00449 DEBUGDAEMON << fname << ": Pilot's showPhone now: ["
00450 << fAddressInfo.showPhone << "]." << endl;
00451 #endif
00452
00453
00454
00455 QString pref = getField(fAddressInfo.showPhone + entryPhone1);
00456 if (fAddressInfo.showPhone < 0 || fAddressInfo.showPhone > 4 || pref.isEmpty()) {
00457 #ifdef DEBUG
00458 DEBUGDAEMON << fname << ": Pilot's showPhone: ["
00459 << fAddressInfo.showPhone
00460 << "] not properly set to a default. trying to set a sensible one."
00461 << endl;
00462 #endif
00463 for (int i = entryPhone1; i <= entryPhone5; i++)
00464 {
00465 pref = getField(i);
00466 if (!pref.isEmpty())
00467 {
00468 fAddressInfo.showPhone = i - entryPhone1;
00469 break;
00470 }
00471 }
00472 }
00473 #ifdef DEBUG
00474 DEBUGDAEMON << fname << ": Pilot's showPhone now: ["
00475 << fAddressInfo.showPhone << "], and that's final." << endl;
00476 #endif
00477 }
00478
00479 void PilotAddress::setEmails(QStringList list)
00480 {
00481 QString test;
00482
00483
00484 for (int i = entryPhone1; i <= entryPhone5; i++)
00485 {
00486 test = getField(i);
00487 if (!test.isEmpty())
00488 {
00489 int ind = getPhoneLabelIndex(i-entryPhone1);
00490 if (ind == eEmail)
00491 {
00492 setField(i, "");
00493 }
00494 }
00495 }
00496
00497 for(QStringList::Iterator listIter = list.begin();
00498 listIter != list.end(); ++listIter)
00499 {
00500 QString email = *listIter;
00501 setPhoneField(eEmail, email, true, false);
00502 }
00503 }
00504
00511 void PilotAddress::_loadMaps()
00512 {
00524 pilotToPhoneMap.clear();
00525
00526
00527 pilotToPhoneMap.insert(eFax, KABC::PhoneNumber::Fax);
00528
00529 pilotToPhoneMap.insert(eWork, KABC::PhoneNumber::Work);
00530 pilotToPhoneMap.insert(eHome, KABC::PhoneNumber::Home);
00531 pilotToPhoneMap.insert(ePager, KABC::PhoneNumber::Pager);
00532 pilotToPhoneMap.insert(eMobile, KABC::PhoneNumber::Cell);
00533
00534
00535
00536 pilotToPhoneMap.insert(eMain, KABC::PhoneNumber::Home);
00537
00538
00539
00540
00541
00542
00543 }
00544
00545 QString PilotAddress::getField(int field) const
00546 {
00547 return codec()->toUnicode(fAddressInfo.entry[field]);
00548 }
00549
00550 int PilotAddress::_getNextEmptyPhoneSlot() const
00551 {
00552 FUNCTIONSETUPL(4);
00553 for (int phoneSlot = entryPhone1; phoneSlot <= entryPhone5;
00554 phoneSlot++)
00555 {
00556 QString phoneField = getField(phoneSlot);
00557
00558 if (phoneField.isEmpty())
00559 return phoneSlot;
00560 }
00561 return entryCustom4;
00562 }
00563
00564 int PilotAddress::setPhoneField(EPhoneType type, const QString &field,
00565 bool overflowCustom, bool overwriteExisting)
00566 {
00567 FUNCTIONSETUPL(4);
00568
00569
00570
00571 int appPhoneLabelNum = (int) type;
00572 QString fieldStr(field);
00573 int fieldSlot = (overwriteExisting) ? _findPhoneFieldSlot(appPhoneLabelNum) : -1;
00574
00575 if (fieldSlot == -1)
00576 fieldSlot = _getNextEmptyPhoneSlot();
00577
00578
00579 if (fieldSlot == entryCustom4)
00580 {
00581 if (!fieldStr.isEmpty() && overflowCustom)
00582 {
00583 QString custom4Field = getField(entryCustom4);
00584 QString typeStr(
00585 codec()->toUnicode(fAppInfo.phoneLabels[appPhoneLabelNum]));
00586
00587 custom4Field += typeStr + CSL1(" ") + fieldStr;
00588 setField(entryCustom4, custom4Field);
00589 }
00590 }
00591 else
00592 {
00593 setField(fieldSlot, field);
00594 int labelIndex = fieldSlot - entryPhone1;
00595
00596 fAddressInfo.phoneLabel[labelIndex] = appPhoneLabelNum;
00597 }
00598 return fieldSlot;
00599 }
00600
00601 int PilotAddress::_findPhoneFieldSlot(int appTypeNum) const
00602 {
00603 FUNCTIONSETUPL(4);
00604 for (int index = 0; index < 5; index++)
00605 {
00606 if (fAddressInfo.phoneLabel[index] == appTypeNum)
00607 return index + entryPhone1;
00608 }
00609
00610 return -1;
00611 }
00612
00613 QString PilotAddress::getPhoneField(EPhoneType type, bool checkCustom4) const
00614 {
00615 FUNCTIONSETUPL(4);
00616
00617
00618
00619 int appTypeNum = (int) type;
00620
00621 int fieldSlot = _findPhoneFieldSlot(appTypeNum);
00622
00623 if (fieldSlot != -1)
00624 return getField(fieldSlot);
00625
00626
00627 if (!checkCustom4)
00628 return QString::null;
00629
00630
00631 QString typeToStr(codec()->toUnicode(fAppInfo.phoneLabels[appTypeNum]));
00632 QString customField(getField(entryCustom4));
00633 int foundField = customField.find(typeToStr);
00634
00635 if (foundField == -1)
00636 return QString::null;
00637
00638
00639 int startPos = foundField + typeToStr.length() + 1;
00640 int endPos = customField.find(' ', startPos);
00641
00642 if (endPos == -1)
00643 endPos = customField.length();
00644 QString field = customField.mid(startPos, endPos);
00645
00646 field = field.simplifyWhiteSpace();
00647
00648
00649 return field;
00650 }
00651
00652
00653 int PilotAddress::_getAppPhoneLabelNum(const QString & phoneType) const
00654 {
00655 FUNCTIONSETUPL(4);
00656 for (int index = 0; index < 8; index++)
00657 {
00658 if (phoneType == codec()->toUnicode(fAppInfo.phoneLabels[index]))
00659 return index;
00660 }
00661
00662 return -1;
00663 }
00664
00665 void PilotAddress::setShownPhone(EPhoneType type)
00666 {
00667 FUNCTIONSETUPL(4);
00668 int appPhoneLabelNum = (int) type;
00669 int fieldSlot = _findPhoneFieldSlot(appPhoneLabelNum);
00670
00671 if (fieldSlot == -1)
00672 {
00673 if (type != eHome)
00674 {
00675 setShownPhone(eHome);
00676 return;
00677 }
00678 fieldSlot = entryPhone1;
00679 }
00680 fAddressInfo.showPhone = fieldSlot - entryPhone1;
00681 }
00682
00683 void PilotAddress::setField(int field, const QString &text)
00684 {
00685 FUNCTIONSETUPL(4);
00686
00687
00688 if (fAddressInfo.entry[field])
00689 {
00690 free(fAddressInfo.entry[field]);
00691 fAddressInfo.entry[field]=0L;
00692 }
00693 if (!text.isEmpty())
00694 {
00695 fAddressInfo.entry[field] = (char *) malloc(text.length() + 1);
00696 strlcpy(fAddressInfo.entry[field], codec()->fromUnicode(text), text.length() + 1);
00697 }
00698 else
00699 {
00700 fAddressInfo.entry[field] = 0L;
00701 }
00702 }
00703
00704 void *PilotAddress::pack_(void *buf, int *len)
00705 {
00706 FUNCTIONSETUPL(4);
00707 int i;
00708
00709 #if PILOT_LINK_NUMBER >= PILOT_LINK_0_12_0
00710 pi_buffer_t b = { 0,0,0 } ;
00711 i = pack_Address(&fAddressInfo, &b, address_v1);
00712 memcpy(buf,b.data,kMin(i,*len));
00713 *len = kMin(i,*len);
00714 #else
00715 i = pack_Address(&fAddressInfo, (unsigned char *) buf, *len);
00716 *len = i;
00717 #endif
00718 return buf;
00719 }
00720