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