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