kpilot Library API Documentation

pilotAddress.cc

00001 /* pilotAddress.cc          KPilot
00002 **
00003 ** Copyright (C) 1998-2001 by Dan Pilone
00004 **
00005 ** This is a C++ wrapper for the pilot's address database structures.
00006 */
00007 
00008 /*
00009 ** This program is free software; you can redistribute it and/or modify
00010 ** it under the terms of the GNU Lesser General Public License as published by
00011 ** the Free Software Foundation; either version 2.1 of the License, or
00012 ** (at your option) any later version.
00013 **
00014 ** This program is distributed in the hope that it will be useful,
00015 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00017 ** GNU Lesser General Public License for more details.
00018 **
00019 ** You should have received a copy of the GNU Lesser General Public License
00020 ** along with this program in a file called COPYING; if not, write to
00021 ** the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00022 ** MA 02111-1307, USA.
00023 */
00024 
00025 /*
00026 ** Bug reports and questions can be sent to kde-pim@kde.org
00027 */
00028 
00029 
00030 static const char *pilotadress_id =
00031     "$Id: pilotAddress.cc,v 1.13 2003/10/01 10:13:39 kainhofe Exp $";
00032 
00033 #ifndef _KPILOT_OPTIONS_H
00034 #include "options.h"
00035 #endif
00036 
00037 #include <stdlib.h>
00038 #include <assert.h>
00039 
00040 #include <qtextcodec.h>
00041 
00042 #ifndef _KPILOT_PILOTADDRESS_H
00043 #include "pilotAddress.h"
00044 #endif
00045 
00046 
00047 const int PilotAddress::APP_BUFFER_SIZE = 0xffff;
00048 #define MAXFIELDS 19
00049 
00050 PilotAddress::PilotAddress(struct AddressAppInfo &appInfo,
00051     PilotRecord * rec) :
00052     PilotAppCategory(rec),
00053     fAppInfo(appInfo),
00054     fAddressInfo()
00055 {
00056     FUNCTIONSETUPL(4);
00057     if (rec) unpack_Address(&fAddressInfo, (unsigned char *) rec->getData(), rec->getLen());
00058     (void) pilotadress_id;
00059 }
00060 
00061 PilotAddress::PilotAddress(struct AddressAppInfo &appInfo) :
00062     PilotAppCategory(),
00063     fAppInfo(appInfo)
00064 {
00065     FUNCTIONSETUPL(4);
00066     reset();
00067 
00068     // assign the phoneLabel so it doesn't appear in the pilot as
00069     // work for all fields, but at least shows other fields
00070     fAddressInfo.phoneLabel[0] = (int) eWork;
00071     fAddressInfo.phoneLabel[1] = (int) eHome;
00072     fAddressInfo.phoneLabel[2] = (int) eOther;
00073     fAddressInfo.phoneLabel[3] = (int) eMobile;
00074     fAddressInfo.phoneLabel[4] = (int) eEmail;
00075 }
00076 
00077 PilotAddress::PilotAddress(const PilotAddress & copyFrom) :
00078     PilotAppCategory(copyFrom),
00079     fAppInfo(copyFrom.fAppInfo),
00080     fAddressInfo()
00081 {
00082     FUNCTIONSETUPL(4);
00083     _copyAddressInfo(copyFrom.fAddressInfo);
00084 }
00085 
00086 PilotAddress & PilotAddress::operator = (const PilotAddress & copyFrom)
00087 {
00088     FUNCTIONSETUPL(4);
00089     PilotAppCategory::operator = (copyFrom);
00090     _copyAddressInfo(copyFrom.fAddressInfo);
00091     return *this;
00092 }
00093 
00094 bool PilotAddress::operator==(const PilotAddress &compareTo)
00095 {
00096     FUNCTIONSETUPL(4);
00097     // TODO: call == of PilotAppCategory. I don't think this is necessary, but I'm not so sure...
00098 //  if (!(PilotAppCategory)(this)->operator==(compareTo) ) return false;
00099 
00100     // now compare all the fields stored in the fAddressInfo.entry array of char*[19]
00101     for (int i=0; i<MAXFIELDS; i++) {
00102         // if one is NULL, and the other non-empty, they are not equal for sure
00103         if ( !getFieldP(i) && compareTo.getFieldP(i)) return false;
00104         if ( getFieldP(i) && !compareTo.getFieldP(i)) return false;
00105         // test for getField(i)!=... to prevent strcmp or NULL strings!  None or both can be zero, but not a single one.
00106         if ( (getFieldP(i) != compareTo.getFieldP(i)) && ( strcmp(getFieldP(i), compareTo.getFieldP(i)) ) )  return false;
00107     }
00108     return true;
00109 }
00110 
00111 
00112 void PilotAddress::_copyAddressInfo(const struct Address &copyFrom)
00113 {
00114     FUNCTIONSETUPL(4);
00115     fAddressInfo.showPhone = copyFrom.showPhone;
00116 
00117     for (int labelLp = 0; labelLp < 5; labelLp++)
00118     {
00119         fAddressInfo.phoneLabel[labelLp] =
00120             copyFrom.phoneLabel[labelLp];
00121     }
00122 
00123     for (int entryLp = 0; entryLp < 19; entryLp++)
00124     {
00125         if (copyFrom.entry[entryLp])
00126             fAddressInfo.entry[entryLp] =
00127                 qstrdup(copyFrom.entry[entryLp]);
00128         else
00129             fAddressInfo.entry[entryLp] = 0L;
00130     }
00131 }
00132 
00133 
00134 PilotAddress::~PilotAddress()
00135 {
00136     FUNCTIONSETUPL(4);
00137     free_Address(&fAddressInfo);
00138 }
00139 
00140 QString PilotAddress::getTextRepresentation(bool richText)
00141 {
00142     QString text, tmp;
00143 
00144     QString par = richText?CSL1("<p>"):CSL1("");
00145     QString ps = richText?CSL1("</p>"):CSL1("\n");
00146     QString br = richText?CSL1("<br/>"):CSL1("\n");
00147 
00148     // title + name
00149     text += par;
00150     if (!getField(entryTitle).isEmpty())
00151     {
00152         text += rtExpand(getField(entryTitle), richText);
00153         text += CSL1(" ");
00154     }
00155 
00156     tmp = richText?CSL1("<b><big>%1%2%3</big></b>"):CSL1("%1%2%3");
00157     if (!getField(entryFirstname).isEmpty())
00158         tmp=rtExpand(tmp.arg(getField(entryFirstname)), richText).arg(CSL1(" "));
00159     else
00160         tmp=tmp.arg(CSL1(" ")).arg(CSL1(" "));
00161     tmp=tmp.arg(rtExpand(getField(entryLastname), richText));
00162     text += tmp;
00163     text += ps;
00164 
00165     // company
00166     if (!getField(entryCompany).isEmpty())
00167     {
00168         text += par;
00169         text += rtExpand(getField(entryCompany), richText);
00170         text += ps;
00171     }
00172 
00173     // phone numbers (+ labels)
00174     text += par;
00175     for (int i = entryPhone1; i <= entryPhone5; i++)
00176         if (!getField(i).isEmpty())
00177         {
00178             if (richText)
00179             {
00180                 if (getShownPhone() == i - entryPhone1)
00181                     tmp=CSL1("<small>%1: </small><b>%2</b>");
00182                 else
00183                     tmp=CSL1("<small>%1: </small>%2");
00184             }
00185             else
00186                 tmp=CSL1("%1: %2");
00187             tmp=tmp.arg(PilotAppCategory::codec()->toUnicode(
00188                 fAppInfo.phoneLabels[getPhoneLabelIndex(i-entryPhone1)]));
00189             tmp=tmp.arg(rtExpand(getField(i), richText));
00190             text += tmp;
00191             text += br;
00192         }
00193     text += ps;
00194 
00195     // address, city, state, country
00196     text += par;
00197     if (!getField(entryAddress).isEmpty())
00198     {
00199         text += rtExpand(getField(entryAddress), richText);
00200         text += br;
00201     }
00202     if (!getField(entryCity).isEmpty())
00203     {
00204         text += rtExpand(getField(entryCity), richText);
00205         text += CSL1(" ");
00206     }
00207     if (!getField(entryState).isEmpty())
00208     {
00209         text += rtExpand(getField(entryState), richText);
00210         text += CSL1(" ");
00211     }
00212     if (!getField(entryZip).isEmpty())
00213     {
00214         text += rtExpand(getField(entryZip), richText);
00215     }
00216     text += br;
00217     if (!getField(entryCountry).isEmpty())
00218     {
00219         text += rtExpand(getField(entryCountry), richText);
00220         text += br;
00221     }
00222     text += ps;
00223 
00224     // custom fields
00225     text += par;
00226     for (int i = entryCustom1; i <= entryCustom4; i++)
00227         if (!getField(i).isEmpty())
00228         {
00229             text += rtExpand(getField(i), richText);
00230             text += br;
00231         }
00232     text += ps;
00233 
00234     // note
00235     if (!getField(entryNote).isEmpty())
00236     {
00237         text += richText?CSL1("<hr/>"):CSL1("-----------------------------\n");
00238         text += par;
00239         text += rtExpand(getField(entryNote), richText);
00240         text += ps;
00241     }
00242     return text;
00243 }
00244 
00245 bool PilotAddress::setCategory(const QString &label)
00246 {
00247     FUNCTIONSETUPL(4);
00248     if (label.isEmpty())
00249     {
00250         setCat(0);
00251         return true;
00252     }
00253     for (int catId = 1; catId < 16; catId++)
00254     {
00255         QString aCat = codec()->toUnicode(fAppInfo.category.name[catId]);
00256 
00257         if (label == aCat)
00258         {
00259             setCat(catId);
00260             return true;
00261         }
00262         else
00263             // if empty, then no more labels; add it
00264         if (aCat.isEmpty())
00265         {
00266             qstrncpy(fAppInfo.category.name[catId],
00267                 codec()->fromUnicode(label), 16);
00268             setCat(catId);
00269             return true;
00270         }
00271     }
00272     // if got here, the category slots were full
00273     return false;
00274 }
00275 
00276 QString PilotAddress::getCategoryLabel() const
00277 {
00278     int cat(getCat());
00279     if (cat>0) return codec()->toUnicode(fAppInfo.category.name[cat]);
00280     else return QString::null;
00281 }
00282 
00283 QString PilotAddress::getField(int field) const
00284 {
00285     return codec()->toUnicode(fAddressInfo.entry[field]);
00286 }
00287 
00288 int PilotAddress::_getNextEmptyPhoneSlot() const
00289 {
00290     FUNCTIONSETUPL(4);
00291     for (int phoneSlot = entryPhone1; phoneSlot <= entryPhone5;
00292         phoneSlot++)
00293     {
00294         QString phoneField = getField(phoneSlot);
00295 
00296         if (phoneField.isEmpty())
00297             return phoneSlot;
00298     }
00299     return entryCustom4;
00300 }
00301 
00302 void PilotAddress::setPhoneField(EPhoneType type, const QString &field,
00303     bool overflowCustom)
00304 {
00305     FUNCTIONSETUPL(4);
00306     // first look to see if the type is already assigned to a fieldSlot
00307     //QString typeStr(_typeToStr(type));
00308     //int appPhoneLabelNum = _getAppPhoneLabelNum(typeStr);
00309     int appPhoneLabelNum = (int) type;
00310     QString fieldStr(field);
00311     int fieldSlot = _findPhoneFieldSlot(appPhoneLabelNum);
00312 
00313     if (fieldSlot == -1)
00314         fieldSlot = _getNextEmptyPhoneSlot();
00315 
00316     // store the overflow phone
00317     if (fieldSlot == entryCustom4)
00318     {
00319         if (!fieldStr.isEmpty() && overflowCustom)
00320         {
00321             QString custom4Field = getField(entryCustom4);
00322             QString typeStr(
00323                 codec()->toUnicode(fAppInfo.phoneLabels[appPhoneLabelNum]));
00324 
00325             custom4Field += typeStr + CSL1(" ") + fieldStr;
00326             setField(entryCustom4, custom4Field);
00327         }
00328     }
00329     else            // phone field 1 - 5; straight forward storage
00330     {
00331         setField(fieldSlot, field);
00332         int labelIndex = fieldSlot - entryPhone1;
00333 
00334         fAddressInfo.phoneLabel[labelIndex] = appPhoneLabelNum;
00335     }
00336 }
00337 
00338 int PilotAddress::_findPhoneFieldSlot(int appTypeNum) const
00339 {
00340     FUNCTIONSETUPL(4);
00341     for (int index = 0; index < 5; index++)
00342     {
00343         if (fAddressInfo.phoneLabel[index] == appTypeNum)
00344             return index + entryPhone1;
00345     }
00346 
00347     return -1;
00348 }
00349 
00350 QString PilotAddress::getPhoneField(EPhoneType type, bool checkCustom4) const
00351 {
00352     FUNCTIONSETUPL(4);
00353     // given the type, need to find which slot is associated with it
00354     //QString typeToStr(_typeToStr(type));
00355     //int appTypeNum = _getAppPhoneLabelNum(typeToStr);
00356     int appTypeNum = (int) type;
00357 
00358     int fieldSlot = _findPhoneFieldSlot(appTypeNum);
00359 
00360     if (fieldSlot != -1)
00361         return getField(fieldSlot);
00362 
00363     // look through custom 4 for the field
00364     if (!checkCustom4)
00365         return QString::null;
00366 
00367     // look for the phone type str
00368     QString typeToStr(codec()->toUnicode(fAppInfo.phoneLabels[appTypeNum]));
00369     QString customField(getField(entryCustom4));
00370     int foundField = customField.find(typeToStr);
00371 
00372     if (foundField == -1)
00373         return QString::null;
00374 
00375     // parse out the next token
00376     int startPos = foundField + typeToStr.length() + 1;
00377     int endPos = customField.find(' ', startPos);
00378 
00379     if (endPos == -1)
00380         endPos = customField.length();
00381     QString field = customField.mid(startPos, endPos);
00382 
00383     field = field.simplifyWhiteSpace();
00384 
00385     // return the token
00386     return field;
00387 }
00388 
00389 
00390 int PilotAddress::_getAppPhoneLabelNum(const QString & phoneType) const
00391 {
00392     FUNCTIONSETUPL(4);
00393     for (int index = 0; index < 8; index++)
00394     {
00395         if (phoneType == codec()->toUnicode(fAppInfo.phoneLabels[index]))
00396             return index;
00397     }
00398 
00399     return -1;
00400 }
00401 
00402 void PilotAddress::setShownPhone(EPhoneType type)
00403 {
00404     FUNCTIONSETUPL(4);
00405     int appPhoneLabelNum = (int) type;
00406     int fieldSlot = _findPhoneFieldSlot(appPhoneLabelNum);
00407 
00408     if (fieldSlot == -1)
00409     {
00410         if (type != eHome)
00411         {
00412             setShownPhone(eHome);
00413             return;
00414         }
00415         fieldSlot = entryPhone1;
00416     }
00417     fAddressInfo.showPhone = fieldSlot - entryPhone1;
00418 }
00419 
00420 void PilotAddress::setField(int field, const QString &text)
00421 {
00422     FUNCTIONSETUPL(4);
00423     // This will have either been created with unpack_Address, and/or will
00424     // be released with free_Address, so use malloc/free here:
00425     if (fAddressInfo.entry[field])
00426     {
00427         free(fAddressInfo.entry[field]);
00428     }
00429     if (!text.isEmpty())
00430     {
00431         fAddressInfo.entry[field] = (char *) malloc(text.length() + 1);
00432         strcpy(fAddressInfo.entry[field], codec()->fromUnicode(text));
00433     }
00434     else
00435     {
00436         fAddressInfo.entry[field] = 0L;
00437     }
00438 }
00439 
00440 void *PilotAddress::pack(void *buf, int *len)
00441 {
00442     FUNCTIONSETUPL(4);
00443     int i;
00444 
00445     i = pack_Address(&fAddressInfo, (unsigned char *) buf, *len);
00446     *len = i;
00447     return buf;
00448 }
00449 
KDE Logo
This file is part of the documentation for kpilot Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat May 1 11:36:48 2004 by doxygen 1.2.15 written by Dimitri van Heesch, © 1997-2003