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