kitchensync Library API Documentation

addressbook.cpp

00001 /*
00002     This file is part of KitchenSync.
00003 
00004     Copyright (c) 2002,2003 Holger Freyther <freyther@kde.org>
00005 
00006     This library is free software; you can redistribute it and/or
00007     modify it under the terms of the GNU Library General Public
00008     License as published by the Free Software Foundation; either
00009     version 2 of the License, or (at your option) any later version.
00010 
00011     This library is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014     Library General Public License for more details.
00015 
00016     You should have received a copy of the GNU Library General Public License
00017     along with this library; see the file COPYING.LIB.  If not, write to
00018     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00019     Boston, MA 02111-1307, USA.
00020 */
00021 
00022 #include <qdom.h>
00023 #include <qfile.h>
00024 
00025 #include <kdebug.h>
00026 
00027 
00028 #include "device.h"
00029 #include "addressbook.h"
00030 
00031 
00032 using namespace OpieHelper;
00033 
00034 AddressBook::AddressBook( CategoryEdit *edit,
00035                           KSync::KonnectorUIDHelper* helper,
00036                           const QString &tz,
00037                           bool meta, Device *dev )
00038     : Base( edit,  helper,  tz,  meta, dev )
00039 {
00040 }
00041 AddressBook::~AddressBook(){
00042 }
00043 
00044 KSync::AddressBookSyncee* AddressBook::toKDE( const QString &fileName, ExtraMap& map )
00045 {
00046   KSync::AddressBookSyncee *syncee = new KSync::AddressBookSyncee();
00047   syncee->setSource( "Opie");
00048   if ( device() )
00049     syncee->setSupports( device()->supports( Device::Addressbook ) );
00050 
00051   //return entry;
00052   QFile file( fileName );
00053   if ( !file.open(IO_ReadOnly ) ) {
00054     //delete syncee; there is not addressbook so to get one synced we need to add an empty Syncee
00055     return syncee;
00056   }
00057 
00058   QDomDocument doc("mydocument" );
00059   if ( !doc.setContent( &file ) ) {
00060     file.close();
00061     delete syncee;
00062     return 0;
00063   }
00064 
00065 
00066   QDomElement docElem = doc.documentElement( );
00067   QDomNode n =  docElem.firstChild();
00068   QStringList attr = attributes();
00069   while ( !n.isNull() ) {
00070     QDomElement e = n.toElement();
00071     if ( !e.isNull() ) {
00072       kdDebug(5228) << "Tage Name" << e.tagName() << endl;
00073       if ( e.tagName() == QString::fromLatin1( "Contacts" ) ) { // we're looking for them
00074         QDomNode no = e.firstChild();
00075         while ( !no.isNull() ) {
00076           QDomElement el = no.toElement();
00077           if ( !el.isNull() ) {
00078             kdDebug(5228) << "Contacts: " << el.tagName() << endl;
00079             KABC::Addressee adr;
00080             adr.setUid( kdeId( "AddressBookSyncEntry",  el.attribute("Uid" ) ) );
00081             adr.setFamilyName( el.attribute( "LastName" ) );
00082             adr.setGivenName( el.attribute( "FirstName" ) );
00083             adr.setAdditionalName( el.attribute( "MiddleName" )  );
00084             adr.setSuffix( el.attribute( "Suffix" ) );
00085             adr.setNickName( el.attribute( "Nickname" ) );
00086 
00087             QDate date = dateFromString( el.attribute( "Birthday" ) );
00088             if ( date.isValid() )
00089               adr.setBirthday( date );
00090 
00091             adr.setRole( el.attribute( "JobTitle" ) );
00092             if ( !el.attribute( "FileAs" ).isEmpty() )
00093               adr.setFormattedName( el.attribute( "FileAs" ) );
00094 
00095             adr.setOrganization( el.attribute( "Company" ) );
00096 
00097             KABC::PhoneNumber businessPhoneNum( el.attribute( "BusinessPhone" ),
00098                                                 KABC::PhoneNumber::Work );
00099             KABC::PhoneNumber businessFaxNum( el.attribute( "BusinessFax" ),
00100                                               KABC::PhoneNumber::Work | KABC::PhoneNumber::Fax );
00101             KABC::PhoneNumber businessMobile( el.attribute( "BusinessMobile" ),
00102                                               KABC::PhoneNumber::Work | KABC::PhoneNumber::Cell );
00103             KABC::PhoneNumber businessPager( el.attribute( "BusinessPager" ),
00104                                              KABC::PhoneNumber::Work | KABC::PhoneNumber::Pager );
00105             if ( !businessPhoneNum.number().isEmpty() )
00106               adr.insertPhoneNumber( businessPhoneNum );
00107             if ( !businessFaxNum.number().isEmpty() )
00108               adr.insertPhoneNumber( businessFaxNum );
00109             if ( !businessMobile.number().isEmpty() )
00110               adr.insertPhoneNumber( businessMobile );
00111             if ( !businessPager.number().isEmpty() )
00112               adr.insertPhoneNumber( businessPager  );
00113 
00114             // Handle multiple mail addresses
00115             QString DefaultEmail = el.attribute( "DefaultEmail" );
00116             if ( !DefaultEmail.isEmpty() )
00117               adr.insertEmail( DefaultEmail, true ); // preferred
00118 
00119             QString Emails = el.attribute("Emails");
00120             int emailCount = 1;
00121             QString Email = Emails.section( ' ', 1, 1, QString::SectionSkipEmpty );
00122             while ( !Email.isEmpty() ) {
00123               // Handle all the secondary emails ...
00124               if ( Email != DefaultEmail )
00125                 adr.insertEmail( Email, false );
00126               emailCount++;
00127               Email = Emails.section( ' ', emailCount, emailCount, QString::SectionSkipEmpty );
00128             }
00129 
00130 
00131             KABC::PhoneNumber homePhoneNum( el.attribute( "HomePhone" ),
00132                                             KABC::PhoneNumber::Home );
00133             KABC::PhoneNumber homeFax( el.attribute( "HomeFax" ),
00134                                        KABC::PhoneNumber::Home | KABC::PhoneNumber::Fax );
00135 
00136             KABC::PhoneNumber homeMobile( el.attribute( "HomeMobile" ),
00137                                           KABC::PhoneNumber::Cell );
00138 
00139             if ( !homePhoneNum.number().isEmpty() )
00140               adr.insertPhoneNumber( homePhoneNum );
00141             if ( !homeFax.number().isEmpty() )
00142               adr.insertPhoneNumber( homeFax );
00143             if ( !homeMobile.number().isEmpty() )
00144               adr.insertPhoneNumber( homeMobile );
00145 
00146             KABC::Address business( KABC::Address::Work );
00147             business.setStreet( el.attribute( "BusinessStreet" ) );
00148             business.setLocality( el.attribute( "BusinessCity"  ) );
00149             business.setRegion( el.attribute( "BusinessState" ) );
00150             business.setPostalCode( el.attribute( "BusinessZip" )  );
00151             business.setCountry( el.attribute( "BusinessCountry" ) );
00152 
00153             if ( !business.isEmpty() )
00154               adr.insertAddress( business );
00155 
00156             KABC::Address home( KABC::Address::Home );
00157             home.setStreet( el.attribute( "HomeStreet" ) );
00158             home.setLocality( el.attribute( "HomeCity" ) );
00159             home.setRegion( el.attribute( "HomeState" ) );
00160             home.setPostalCode( el.attribute( "HomeZip" ) );
00161             home.setCountry( el.attribute( "HomeCountry" ) );
00162 
00163             if ( !home.isEmpty() )
00164               adr.insertAddress( home );
00165 
00166             adr.setNickName( el.attribute( "Nickname" ) );
00167             adr.setNote( el.attribute( "Notes" ) );
00168 
00169             {
00170               QStringList categories = QStringList::split(";", el.attribute("Categories" ) );
00171               QString cat;
00172               QStringList added;
00173               for ( uint i = 0; i < categories.count(); i++ ) {
00174                 cat = m_edit->categoryById( categories[ i ], "Contacts" );
00175 
00176                 // if name is not empty and we did not add the
00177                 // cat try to repair broken files
00178                 if ( !cat.isEmpty() && !added.contains( cat ) ) {
00179                   adr.insertCategory( cat );
00180                   added << cat;
00181                 }
00182               }
00183             }
00184 
00185             if ( !el.attribute( "Department" ).isEmpty() )
00186               adr.insertCustom( "KADDRESSBOOK", "X-Department",  el.attribute( "Department" ) );
00187             if ( !el.attribute( "HomeWebPage" ).isEmpty() )
00188               adr.insertCustom( "opie", "HomeWebPage", el.attribute( "HomeWebPage" ) );
00189             if ( !el.attribute( "Spouse" ).isEmpty() )
00190               adr.insertCustom( "KADDRESSBOOK", "X-SpousesName", el.attribute( "Spouse" ) );
00191             if ( !el.attribute( "Gender" ).isEmpty() )
00192               adr.insertCustom( "opie", "Gender", el.attribute( "Gender" ) );
00193 
00194             QDate ann = dateFromString( el.attribute( "Anniversary" ) );
00195             if ( ann.isValid() ) {
00196               adr.insertCustom( "KADDRESSBOOK", "X-Anniversary", ann.toString( Qt::ISODate ) );
00197             }
00198 
00199             if ( !el.attribute( "Children" ).isEmpty() )
00200               adr.insertCustom("opie", "Children", el.attribute("Children") );
00201             if ( !el.attribute( "Office" ).isEmpty() )
00202               adr.insertCustom("KADDRESSBOOK", "X-Office", el.attribute("Office") );
00203             if ( !el.attribute( "Profession" ).isEmpty() )
00204               adr.insertCustom("KADDRESSBOOK", "X-Profession", el.attribute("Profession") );
00205             if ( !el.attribute( "Assistant" ).isEmpty() )
00206               adr.insertCustom("KADDRESSBOOK", "X-AssistantsName", el.attribute("Assistant") );
00207             if ( !el.attribute( "Manager" ).isEmpty() )
00208               adr.insertCustom("KADDRESSBOOK", "X-ManagersName", el.attribute("Manager") );
00209 
00210             KSync::AddressBookSyncEntry* entry = new KSync::AddressBookSyncEntry( adr, syncee );
00211             syncee->addEntry ( entry );
00212 
00213             // now on to the extra stuff
00214             map.add( "addressbook", el.attribute( "Uid" ), el.attributes(), attr );
00215           }
00216 
00217           no = no.nextSibling();
00218         }
00219       }
00220     }
00221 
00222     n = n.nextSibling();
00223   }
00224 
00225   return syncee;
00226 }
00227 KTempFile* AddressBook::fromKDE( KSync::AddressBookSyncee *syncee, ExtraMap& map )
00228 {
00229     kdDebug(5228 ) << "From KDE " << endl;
00230     //  ok lets write back the changes from the Konnector
00231     m_kde2opie.clear(); // clear the reference first
00232     Kontainer::ValueList newIds = syncee->ids( "AddressBookSyncEntry");
00233     for ( Kontainer::ValueList::ConstIterator idIt = newIds.begin(); idIt != newIds.end(); ++idIt ) {
00234         m_helper->addId("AddressBookSyncEntry",  (*idIt).first(),  (*idIt).second() ); // FIXME update this name later
00235     }
00236     KTempFile* tempFile = file();
00237     if ( tempFile->textStream() ) {
00238         QTextStream *stream = tempFile->textStream();
00239         stream->setEncoding( QTextStream::UnicodeUTF8 );
00240         *stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>" << endl;
00241         *stream << " <Groups>" << endl;
00242         *stream << " </Groups>" << endl;
00243         *stream << " <Contacts> " << endl;
00244 // for all entries
00245         KABC::Addressee ab;
00246         KSync::AddressBookSyncEntry *entry;
00247         for ( entry = syncee->firstEntry(); entry != 0l;  entry = syncee->nextEntry() ) {
00248             if (entry->state() == KSync::SyncEntry::Removed )
00249                 continue;
00250             ab = entry->addressee();
00251             *stream << "<Contact ";
00252             *stream << "FirstName=\"" << escape(ab.givenName()) << "\" ";
00253             *stream << "MiddleName=\"" << escape(ab.additionalName()) << "\" ";
00254             *stream << "LastName=\"" << escape(ab.familyName()) << "\" ";
00255             *stream << "Suffix=\"" << escape(ab.suffix()) << "\" ";
00256 
00257             QString sortStr;
00258             sortStr = ab.formattedName();
00259             /* is formattedName is empty we use the assembled name as fallback */
00260             if (sortStr.isEmpty() )
00261                 sortStr = ab.assembledName();
00262             *stream << "FileAs=\"" << escape(sortStr) << "\" ";
00263 
00264             *stream << "JobTitle=\"" << escape(ab.role()) << "\" ";
00265             *stream << "Department=\"" << escape(ab.custom( "KADDRESSBOOK", "X-Department" )) << "\" ";
00266             *stream << "Company=\"" << escape(ab.organization()) << "\" ";
00267 
00268             KABC::PhoneNumber businessPhoneNum = ab.phoneNumber(KABC::PhoneNumber::Work );
00269             *stream << "BusinessPhone=\"" << escape( businessPhoneNum.number() ) << "\" ";
00270 
00271             KABC::PhoneNumber businessFaxNum = ab.phoneNumber(KABC::PhoneNumber::Work | KABC::PhoneNumber::Fax );
00272             *stream << "BusinessFax=\"" << escape( businessFaxNum.number() )<< "\" ";
00273 
00274             KABC::PhoneNumber businessMobile = ab.phoneNumber(KABC::PhoneNumber::Work | KABC::PhoneNumber::Cell );
00275             *stream << "BusinessMobile=\"" << escape( businessMobile.number() ) << "\" ";
00276 
00277             *stream << "DefaultEmail=\"" << escape( ab.preferredEmail() ) << "\" ";
00278             QStringList list = ab.emails();
00279             if ( list.count() > 0 ) {
00280         QStringList::Iterator it = list.begin();
00281                 *stream << "Emails=\"" << escape( *it );
00282         while (++it != list.end())
00283           *stream << ' ' << escape( *it );
00284                 *stream << "\" ";
00285         }
00286 
00287             KABC::PhoneNumber homePhoneNum = ab.phoneNumber(KABC::PhoneNumber::Home );
00288             *stream << "HomePhone=\"" << escape( homePhoneNum.number() ) << "\" ";
00289 
00290             KABC::PhoneNumber homeFax = ab.phoneNumber( KABC::PhoneNumber::Home | KABC::PhoneNumber::Fax );
00291             *stream << "HomeFax=\"" << escape( homeFax.number() ) << "\" ";
00292 
00293             KABC::PhoneNumber homeMobile = ab.phoneNumber( KABC::PhoneNumber::Cell );
00294             *stream << "HomeMobile=\"" << escape( homeMobile.number() ) << "\" ";
00295 
00296             KABC::Address business = ab.address(KABC::Address::Work  );
00297             *stream << "BusinessStreet=\"" << escape( business.street() ) << "\" ";
00298             *stream << "BusinessCity=\"" << escape( business.locality() ) << "\" ";
00299             *stream << "BusinessZip=\"" << escape( business.postalCode() ) << "\" ";
00300             *stream << "BusinessCountry=\"" << escape( business.country() ) << "\" ";
00301             *stream << "BusinessState=\"" << escape( business.region() ) << "\" ";
00302             //stream << "BusinessPager=\"" << << "\" ";
00303             *stream << "Office=\"" << escape( ab.custom( "KADDRESSBOOK",  "X-Office" ) ) << "\" ";
00304             *stream << "Profession=\"" << escape( ab.custom( "KADDRESSBOOK",  "X-Profession" ) ) << "\" ";
00305             *stream << "Assistant=\"" << escape( ab.custom( "KADDRESSBOOK",  "X-AssistantsName") ) << "\" ";
00306             *stream << "Manager=\"" << escape( ab.custom( "KADDRESSBOOK",  "X-ManagersName" ) ) << "\" ";
00307 
00308             KABC::Address home = ab.address( KABC::Address::Home );
00309             *stream << "HomeStreet=\"" << escape( home.street() ) << "\" ";
00310             *stream << "HomeCity=\"" <<  escape( home.locality() ) << "\" ";
00311             *stream << "HomeState=\"" <<  escape( home.region() ) << "\" ";
00312             *stream << "HomeZip=\"" <<  escape( home.postalCode() ) << "\" ";
00313             *stream << "HomeCountry=\"" << escape( home.country() ) << "\" ";
00314 
00315             *stream << "HomeWebPage=\"" << escape( ab.custom( "opie", "HomeWebPage" ) ) << "\" ";
00316             *stream << "Spouse=\"" << escape( ab.custom( "KADDRESSBOOK",  "X-SpousesName") ) << "\" ";
00317             *stream << "Gender=\"" << escape( ab.custom( "opie",  "Gender") ) << "\" ";
00318 
00319             if ( ab.birthday().date().isValid() )
00320                 *stream << "Birthday=\"" << escape( dateToString(ab.birthday().date() ) ) << "\" ";
00321 
00322             /*
00323              * Anniversary block again
00324              * Go from ISO -> QDate -> toString and then escape
00325              */
00326             {
00327                 QDate ann = QDate::fromString( ab.custom("KADDRESSBOOK", "X-Anniversary"), Qt::ISODate );
00328                 if (ann.isValid() ) {
00329                     *stream << "Anniversary=\"" << escape( dateToString( ann )  ) << "\" ";
00330                 }
00331             }
00332             *stream << "Nickname=\"" << escape( ab.nickName() ) << "\" ";
00333             *stream << "Children=\"" << escape( ab.custom("opie", "Children" ) ) << "\" ";
00334             *stream << "Notes=\"" << escape( ab.note() ) << "\" ";
00335             *stream << "Categories=\"" << categoriesToNumber( ab.categories(),  "Contacts") << "\" ";
00336 
00337             QString uid = konnectorId( "AddressBookSyncEntry", ab.uid() );
00338             *stream << "Uid=\"" <<  uid << "\" ";
00339             *stream << map.toString( "addressbook", uid );
00340             *stream << " />" << endl;
00341         } // off for
00342         *stream << "</Contacts>" << endl;
00343         *stream << "</AddressBook>" << endl;
00344     }
00345     // now replace the UIDs for us
00346     m_helper->replaceIds( "AddressBookSyncEntry",  m_kde2opie ); // to keep the use small
00347 
00348     tempFile->close();
00349 
00350     return tempFile;
00351 }
00352 
00353 QStringList AddressBook::attributes()const {
00354     QStringList lst;
00355     lst << "FirstName";
00356     lst << "MiddleName";
00357     lst << "LastName";
00358     lst << "Suffix";
00359     lst << "FileAs";
00360     lst << "JobTitle";
00361     lst << "Department";
00362     lst << "Company";
00363     lst << "BusinessPhone";
00364     lst << "BusinessFax";
00365     lst << "BusinessMobile";
00366     lst << "DefaultEmail";
00367     lst << "Emails";
00368     lst << "HomePhone";
00369     lst << "HomeFax";
00370     lst << "HomeMobile";
00371     lst << "BusinessStreet";
00372     lst << "BusinessCity";
00373     lst << "BusinessZip";
00374     lst << "BusinessCountry";
00375     lst << "BusinessState";
00376     lst << "Office";
00377     lst << "Profession";
00378     lst << "Assistant";
00379     lst << "Manager";
00380     lst << "HomeStreet";
00381     lst << "HomeCity";
00382     lst << "HomeState";
00383     lst << "HomeZip";
00384     lst << "HomeCountry";
00385     lst << "HomeWebPage";
00386     lst << "Spouse";
00387     lst << "Gender";
00388     lst << "Anniversary";
00389     lst << "Nickname";
00390     lst << "Children";
00391     lst << "Notes";
00392     lst << "Categories";
00393     lst << "Uid";
00394     lst << "Birthday";
00395 
00396     return lst;
00397 }
00398 
00399 // FROM TT timeconversion.cpp GPLed
00400 QDate AddressBook::fromString( const QString &datestr )
00401 {
00402     if (datestr.isEmpty() )
00403         return QDate();
00404 
00405     int monthPos = datestr.find('.');
00406     int yearPos = datestr.find('.', monthPos+1 );
00407     if ( monthPos == -1 || yearPos == -1 ) {
00408     return QDate();
00409     }
00410     int d = datestr.left( monthPos ).toInt();
00411     int m = datestr.mid( monthPos+1, yearPos - monthPos - 1 ).toInt();
00412     int y = datestr.mid( yearPos+1 ).toInt();
00413     QDate date ( y,m,d );
00414 
00415 
00416     return date;
00417 }
00418 
00419 
00420 QString AddressBook::dateToString( const QDate &d )
00421 {
00422     if ( d.isNull() || !d.isValid() )
00423         return QString::null;
00424 
00425     // ISO format in year, month, day (YYYYMMDD); e.g. 20021231
00426     QString year = QString::number( d.year() );
00427     QString month = QString::number( d.month() );
00428     month = month.rightJustify( 2, '0' );
00429     QString day = QString::number( d.day() );
00430     day = day.rightJustify( 2, '0' );
00431 
00432     QString str = year + month + day;
00433 
00434     return str;
00435 }
00436 
00437 QDate AddressBook::dateFromString( const QString& s )
00438 {
00439     QDate date;
00440 
00441     if ( s.isEmpty() )
00442         return date;
00443 
00444     // Be backward compatible to old Opie format:
00445     // Try to load old format. If it fails, try new ISO-Format!
00446     date = fromString ( s );
00447     if ( date.isValid() )
00448         return date;
00449 
00450     // Read ISO-Format (YYYYMMDD)
00451     int year = s.mid(0, 4).toInt();
00452     int month = s.mid(4,2).toInt();
00453     int day = s.mid(6,2).toInt();
00454 
00455     // do some quick sanity checking
00456     if ( year < 1900 || year > 3000 )
00457         return date;
00458 
00459     if ( month < 0 || month > 12 )
00460         return date;
00461 
00462     if ( day < 0 || day > 31 )
00463         return date;
00464 
00465 
00466     date.setYMD( year, month, day );
00467 
00468     if ( !date.isValid() )
00469         return QDate();
00470 
00471 
00472     return date;
00473 }
KDE Logo
This file is part of the documentation for kitchensync Library Version 3.3.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Mon Apr 4 04:47:07 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003