• Skip to content
  • Skip to link menu
KDE 4.3 API Reference
  • KDE API Reference
  • KDE-PIM Libraries
  • Sitemap
  • Contact Us
 

kabc

vcardtool.cpp

00001 /*
00002     This file is part of libkabc.
00003     Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>
00004 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Library General Public
00007     License as published by the Free Software Foundation; either
00008     version 2 of the License, or (at your option) any later version.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Library General Public License for more details.
00014 
00015     You should have received a copy of the GNU Library General Public License
00016     along with this library; see the file COPYING.LIB.  If not, write to
00017     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018     Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include "vcardtool.h"
00022 #include "key.h"
00023 #include "picture.h"
00024 #include "secrecy.h"
00025 #include "sound.h"
00026 
00027 #include <QtCore/QString>
00028 #include <QtCore/QBuffer>
00029 
00030 using namespace KABC;
00031 
00032 static bool needsEncoding( const QString &value )
00033 {
00034   uint length = value.length();
00035   for ( uint i = 0; i < length; ++i ) {
00036     char c = value.at( i ).toLatin1();
00037     if ( ( c < 33 || c > 126 ) && c != ' ' && c != '=' ) {
00038       return true;
00039     }
00040   }
00041 
00042   return false;
00043 }
00044 
00045 VCardTool::VCardTool()
00046 {
00047   mAddressTypeMap.insert( QLatin1String( "dom" ), Address::Dom );
00048   mAddressTypeMap.insert( QLatin1String( "intl" ), Address::Intl );
00049   mAddressTypeMap.insert( QLatin1String( "postal" ), Address::Postal );
00050   mAddressTypeMap.insert( QLatin1String( "parcel" ), Address::Parcel );
00051   mAddressTypeMap.insert( QLatin1String( "home" ), Address::Home );
00052   mAddressTypeMap.insert( QLatin1String( "work" ), Address::Work );
00053   mAddressTypeMap.insert( QLatin1String( "pref" ), Address::Pref );
00054 
00055   mPhoneTypeMap.insert( QLatin1String( "HOME" ), PhoneNumber::Home );
00056   mPhoneTypeMap.insert( QLatin1String( "WORK" ), PhoneNumber::Work );
00057   mPhoneTypeMap.insert( QLatin1String( "MSG" ), PhoneNumber::Msg );
00058   mPhoneTypeMap.insert( QLatin1String( "PREF" ), PhoneNumber::Pref );
00059   mPhoneTypeMap.insert( QLatin1String( "VOICE" ), PhoneNumber::Voice );
00060   mPhoneTypeMap.insert( QLatin1String( "FAX" ), PhoneNumber::Fax );
00061   mPhoneTypeMap.insert( QLatin1String( "CELL" ), PhoneNumber::Cell );
00062   mPhoneTypeMap.insert( QLatin1String( "VIDEO" ), PhoneNumber::Video );
00063   mPhoneTypeMap.insert( QLatin1String( "BBS" ), PhoneNumber::Bbs );
00064   mPhoneTypeMap.insert( QLatin1String( "MODEM" ), PhoneNumber::Modem );
00065   mPhoneTypeMap.insert( QLatin1String( "CAR" ), PhoneNumber::Car );
00066   mPhoneTypeMap.insert( QLatin1String( "ISDN" ), PhoneNumber::Isdn );
00067   mPhoneTypeMap.insert( QLatin1String( "PCS" ), PhoneNumber::Pcs );
00068   mPhoneTypeMap.insert( QLatin1String( "PAGER" ), PhoneNumber::Pager );
00069 }
00070 
00071 VCardTool::~VCardTool()
00072 {
00073 }
00074 
00075 QByteArray VCardTool::createVCards( const Addressee::List &list, VCard::Version version ) const
00076 {
00077   VCard::List vCardList;
00078 
00079   Addressee::List::ConstIterator addrIt;
00080   Addressee::List::ConstIterator listEnd( list.constEnd() );
00081   for ( addrIt = list.constBegin(); addrIt != listEnd; ++addrIt ) {
00082     VCard card;
00083     QStringList::ConstIterator strIt;
00084 
00085     // ADR + LABEL
00086     const Address::List addresses = (*addrIt).addresses();
00087     for ( Address::List::ConstIterator it = addresses.begin(); it != addresses.end(); ++it ) {
00088       QStringList address;
00089 
00090       const bool isEmpty = ( (*it).postOfficeBox().isEmpty() &&
00091                              (*it).extended().isEmpty() &&
00092                              (*it).street().isEmpty() &&
00093                              (*it).locality().isEmpty() &&
00094                              (*it).region().isEmpty() &&
00095                              (*it).postalCode().isEmpty() &&
00096                              (*it).country().isEmpty() );
00097 
00098       address.append( (*it).postOfficeBox().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) );
00099       address.append( (*it).extended().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) );
00100       address.append( (*it).street().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) );
00101       address.append( (*it).locality().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) );
00102       address.append( (*it).region().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) );
00103       address.append( (*it).postalCode().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) );
00104       address.append( (*it).country().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) );
00105 
00106       VCardLine adrLine( QLatin1String( "ADR" ), address.join( QLatin1String( ";" ) ) );
00107       if ( version == VCard::v2_1 && needsEncoding( address.join( QLatin1String( ";" ) ) ) ) {
00108         adrLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) );
00109         adrLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) );
00110       }
00111 
00112       VCardLine labelLine( QLatin1String( "LABEL" ), (*it).label() );
00113       if ( version == VCard::v2_1 && needsEncoding( (*it).label() ) ) {
00114         labelLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) );
00115         labelLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) );
00116       }
00117 
00118       const bool hasLabel = !(*it).label().isEmpty();
00119       QMap<QString, Address::TypeFlag>::ConstIterator typeIt;
00120       for ( typeIt = mAddressTypeMap.constBegin();
00121             typeIt != mAddressTypeMap.constEnd(); ++typeIt ) {
00122         if ( typeIt.value() & (*it).type() ) {
00123           adrLine.addParameter( QLatin1String( "TYPE" ), typeIt.key() );
00124           if ( hasLabel ) {
00125             labelLine.addParameter( QLatin1String( "TYPE" ), typeIt.key() );
00126           }
00127         }
00128       }
00129 
00130       if ( !isEmpty ) {
00131         card.addLine( adrLine );
00132       }
00133       if ( hasLabel ) {
00134         card.addLine( labelLine );
00135       }
00136     }
00137 
00138     // BDAY
00139     card.addLine( VCardLine( QLatin1String( "BDAY" ), createDateTime( (*addrIt).birthday() ) ) );
00140 
00141     // CATEGORIES
00142     if ( version == VCard::v3_0 ) {
00143       QStringList categories = (*addrIt).categories();
00144       QStringList::Iterator catIt;
00145       for ( catIt = categories.begin(); catIt != categories.end(); ++catIt ) {
00146         (*catIt).replace( QLatin1Char( ',' ), QLatin1String( "\\," ) );
00147       }
00148 
00149       VCardLine catLine( QLatin1String( "CATEGORIES" ), categories.join( QLatin1String( "," ) ) );
00150       card.addLine( catLine );
00151     }
00152 
00153     // CLASS
00154     if ( version == VCard::v3_0 ) {
00155       card.addLine( createSecrecy( (*addrIt).secrecy() ) );
00156     }
00157 
00158     // EMAIL
00159     const QStringList emails = (*addrIt).emails();
00160     bool pref = true;
00161     for ( strIt = emails.begin(); strIt != emails.end(); ++strIt ) {
00162       VCardLine line( QLatin1String( "EMAIL" ), *strIt );
00163       if ( pref == true && emails.count() > 1 ) {
00164         line.addParameter( QLatin1String( "TYPE" ), QLatin1String( "PREF" ) );
00165         pref = false;
00166       }
00167       card.addLine( line );
00168     }
00169 
00170     // FN
00171     VCardLine fnLine( QLatin1String( "FN" ), (*addrIt).formattedName() );
00172     if ( version == VCard::v2_1 && needsEncoding( (*addrIt).formattedName() ) ) {
00173       fnLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) );
00174       fnLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) );
00175     }
00176     card.addLine( fnLine );
00177 
00178     // GEO
00179     const Geo geo = (*addrIt).geo();
00180     if ( geo.isValid() ) {
00181       QString str;
00182       str.sprintf( "%.6f;%.6f", geo.latitude(), geo.longitude() );
00183       card.addLine( VCardLine( QLatin1String( "GEO" ), str ) );
00184     }
00185 
00186     // KEY
00187     const Key::List keys = (*addrIt).keys();
00188     Key::List::ConstIterator keyIt;
00189     for ( keyIt = keys.begin(); keyIt != keys.end(); ++keyIt ) {
00190       card.addLine( createKey( *keyIt ) );
00191     }
00192 
00193     // LOGO
00194     card.addLine( createPicture( QLatin1String( "LOGO" ), (*addrIt).logo() ) );
00195 
00196     // MAILER
00197     VCardLine mailerLine( QLatin1String( "MAILER" ), (*addrIt).mailer() );
00198     if ( version == VCard::v2_1 && needsEncoding( (*addrIt).mailer() ) ) {
00199       mailerLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) );
00200       mailerLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) );
00201     }
00202     card.addLine( mailerLine );
00203 
00204     // N
00205     QStringList name;
00206     name.append( (*addrIt).familyName().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) );
00207     name.append( (*addrIt).givenName().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) );
00208     name.append( (*addrIt).additionalName().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) );
00209     name.append( (*addrIt).prefix().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) );
00210     name.append( (*addrIt).suffix().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) );
00211 
00212     VCardLine nLine( QLatin1String( "N" ), name.join( QLatin1String( ";" ) ) );
00213     if ( version == VCard::v2_1 && needsEncoding( name.join( QLatin1String( ";" ) ) ) ) {
00214       nLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) );
00215       nLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) );
00216     }
00217     card.addLine( nLine );
00218 
00219     // NAME
00220     VCardLine nameLine( QLatin1String( "NAME" ), (*addrIt).name() );
00221     if ( version == VCard::v2_1 && needsEncoding( (*addrIt).name() ) ) {
00222       nameLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) );
00223       nameLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) );
00224     }
00225     card.addLine( nameLine );
00226 
00227     // NICKNAME
00228     if ( version == VCard::v3_0 ) {
00229       card.addLine( VCardLine( QLatin1String( "NICKNAME" ), (*addrIt).nickName() ) );
00230     }
00231 
00232     // NOTE
00233     VCardLine noteLine( QLatin1String( "NOTE" ), (*addrIt).note() );
00234     if ( version == VCard::v2_1 && needsEncoding( (*addrIt).note() ) ) {
00235       noteLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) );
00236       noteLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) );
00237     }
00238     card.addLine( noteLine );
00239 
00240     // ORG
00241     QStringList organization;
00242     organization.append( ( *addrIt ).organization().replace( QLatin1Char( ';' ),
00243                                                              QLatin1String( "\\;" ) ) );
00244     if ( !( *addrIt ).department().isEmpty() ) {
00245       organization.append( ( *addrIt ).department().replace( QLatin1Char( ';' ),
00246                                                              QLatin1String( "\\;" ) ) );
00247     }
00248     VCardLine orgLine( QLatin1String( "ORG" ), organization.join( QLatin1String( ";" ) ) );
00249     if ( version == VCard::v2_1 && needsEncoding( organization.join( QLatin1String( ";" ) ) ) ) {
00250       orgLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) );
00251       orgLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) );
00252     }
00253     card.addLine( orgLine );
00254 
00255     // PHOTO
00256     card.addLine( createPicture( QLatin1String( "PHOTO" ), (*addrIt).photo() ) );
00257 
00258     // PROID
00259     if ( version == VCard::v3_0 ) {
00260       card.addLine( VCardLine( QLatin1String( "PRODID" ), (*addrIt).productId() ) );
00261     }
00262 
00263     // REV
00264     card.addLine( VCardLine( QLatin1String( "REV" ), createDateTime( (*addrIt).revision() ) ) );
00265 
00266     // ROLE
00267     VCardLine roleLine( QLatin1String( "ROLE" ), (*addrIt).role() );
00268     if ( version == VCard::v2_1 && needsEncoding( (*addrIt).role() ) ) {
00269       roleLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) );
00270       roleLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) );
00271     }
00272     card.addLine( roleLine );
00273 
00274     // SORT-STRING
00275     if ( version == VCard::v3_0 ) {
00276       card.addLine( VCardLine( QLatin1String( "SORT-STRING" ), (*addrIt).sortString() ) );
00277     }
00278 
00279     // SOUND
00280     card.addLine( createSound( (*addrIt).sound() ) );
00281 
00282     // TEL
00283     const PhoneNumber::List phoneNumbers = (*addrIt).phoneNumbers();
00284     PhoneNumber::List::ConstIterator phoneIt;
00285     for ( phoneIt = phoneNumbers.begin(); phoneIt != phoneNumbers.end(); ++phoneIt ) {
00286       VCardLine line( QLatin1String( "TEL" ), (*phoneIt).number() );
00287 
00288       QMap<QString, PhoneNumber::TypeFlag>::ConstIterator typeIt;
00289       for ( typeIt = mPhoneTypeMap.constBegin(); typeIt != mPhoneTypeMap.constEnd(); ++typeIt ) {
00290         if ( typeIt.value() & (*phoneIt).type() ) {
00291           line.addParameter( QLatin1String( "TYPE" ), typeIt.key() );
00292         }
00293       }
00294 
00295       card.addLine( line );
00296     }
00297 
00298     // TITLE
00299     VCardLine titleLine( QLatin1String( "TITLE" ), (*addrIt).title() );
00300     if ( version == VCard::v2_1 && needsEncoding( (*addrIt).title() ) ) {
00301       titleLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) );
00302       titleLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) );
00303     }
00304     card.addLine( titleLine );
00305 
00306     // TZ
00307     const TimeZone timeZone = (*addrIt).timeZone();
00308     if ( timeZone.isValid() ) {
00309       QString str;
00310 
00311       int neg = 1;
00312       if ( timeZone.offset() < 0 ) {
00313         neg = -1;
00314       }
00315 
00316       str.sprintf( "%c%02d:%02d", ( timeZone.offset() >= 0 ? '+' : '-' ),
00317                                   ( timeZone.offset() / 60 ) * neg,
00318                                   ( timeZone.offset() % 60 ) * neg );
00319 
00320       card.addLine( VCardLine( QLatin1String( "TZ" ), str ) );
00321     }
00322 
00323     // UID
00324     card.addLine( VCardLine( QLatin1String( "UID" ), (*addrIt).uid() ) );
00325 
00326     // URL
00327     card.addLine( VCardLine( QLatin1String( "URL" ), (*addrIt).url().url() ) );
00328 
00329     // VERSION
00330     if ( version == VCard::v2_1 ) {
00331       card.addLine( VCardLine( QLatin1String( "VERSION" ), QLatin1String( "2.1" ) ) );
00332     }
00333     if ( version == VCard::v3_0 ) {
00334       card.addLine( VCardLine( QLatin1String( "VERSION" ), QLatin1String( "3.0" ) ) );
00335     }
00336 
00337     // X-
00338     const QStringList customs = (*addrIt).customs();
00339     for ( strIt = customs.begin(); strIt != customs.end(); ++strIt ) {
00340       const QString identifier = QLatin1String( "X-" ) +
00341                                  (*strIt).left( (*strIt).indexOf( QLatin1Char( ':' ) ) );
00342       const QString value = (*strIt).mid( (*strIt).indexOf( QLatin1Char( ':' ) ) + 1 );
00343       if ( value.isEmpty() ) {
00344         continue;
00345       }
00346 
00347       VCardLine line( identifier, value );
00348       if ( version == VCard::v2_1 && needsEncoding( value ) ) {
00349         line.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) );
00350         line.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) );
00351       }
00352       card.addLine( line );
00353     }
00354 
00355     vCardList.append( card );
00356   }
00357 
00358   return VCardParser::createVCards( vCardList );
00359 }
00360 
00361 Addressee::List VCardTool::parseVCards( const QByteArray &vcard ) const
00362 {
00363   static const QLatin1Char semicolonSep( ';' );
00364   static const QLatin1Char commaSep( ',' );
00365   QString identifier;
00366 
00367   Addressee::List addrList;
00368   const VCard::List vCardList = VCardParser::parseVCards( vcard );
00369 
00370   VCard::List::ConstIterator cardIt;
00371   VCard::List::ConstIterator listEnd( vCardList.end() );
00372   for ( cardIt = vCardList.begin(); cardIt != listEnd; ++cardIt ) {
00373     Addressee addr;
00374 
00375     const QStringList idents = (*cardIt).identifiers();
00376     QStringList::ConstIterator identIt;
00377     QStringList::ConstIterator identEnd( idents.end() );
00378     for ( identIt = idents.begin(); identIt != identEnd; ++identIt ) {
00379       const VCardLine::List lines = (*cardIt).lines( (*identIt) );
00380       VCardLine::List::ConstIterator lineIt;
00381 
00382       // iterate over the lines
00383       for ( lineIt = lines.begin(); lineIt != lines.end(); ++lineIt ) {
00384         identifier = (*lineIt).identifier().toLower();
00385         // ADR
00386         if ( identifier == QLatin1String( "adr" ) ) {
00387           Address address;
00388           const QStringList addrParts = splitString( semicolonSep, (*lineIt).value().toString() );
00389           if ( addrParts.count() > 0 ) {
00390             address.setPostOfficeBox( addrParts[ 0 ] );
00391           }
00392           if ( addrParts.count() > 1 ) {
00393             address.setExtended( addrParts[ 1 ] );
00394           }
00395           if ( addrParts.count() > 2 ) {
00396             address.setStreet( addrParts[ 2 ] );
00397           }
00398           if ( addrParts.count() > 3 ) {
00399             address.setLocality( addrParts[ 3 ] );
00400           }
00401           if ( addrParts.count() > 4 ) {
00402             address.setRegion( addrParts[ 4 ] );
00403           }
00404           if ( addrParts.count() > 5 ) {
00405             address.setPostalCode( addrParts[ 5 ] );
00406           }
00407           if ( addrParts.count() > 6 ) {
00408             address.setCountry( addrParts[ 6 ] );
00409           }
00410 
00411           Address::Type type;
00412 
00413           const QStringList types = (*lineIt).parameters( QLatin1String( "type" ) );
00414           for ( QStringList::ConstIterator it = types.begin(); it != types.end(); ++it ) {
00415             type |= mAddressTypeMap[ (*it).toLower() ];
00416           }
00417 
00418           address.setType( type );
00419           addr.insertAddress( address );
00420         }
00421 
00422         // BDAY
00423         else if ( identifier == QLatin1String( "bday" ) ) {
00424           addr.setBirthday( parseDateTime( (*lineIt).value().toString() ) );
00425         }
00426 
00427         // CATEGORIES
00428         else if ( identifier == QLatin1String( "categories" ) ) {
00429           const QStringList categories = splitString( commaSep, (*lineIt).value().toString() );
00430           addr.setCategories( categories );
00431         }
00432 
00433         // CLASS
00434         else if ( identifier == QLatin1String( "class" ) ) {
00435           addr.setSecrecy( parseSecrecy( *lineIt ) );
00436         }
00437 
00438         // EMAIL
00439         else if ( identifier == QLatin1String( "email" ) ) {
00440           const QStringList types = (*lineIt).parameters( QLatin1String( "type" ) );
00441           addr.insertEmail( (*lineIt).value().toString(),
00442                             types.contains( QLatin1String( "PREF" ) ) );
00443         }
00444 
00445         // FN
00446         else if ( identifier == QLatin1String( "fn" ) ) {
00447           addr.setFormattedName( (*lineIt).value().toString() );
00448         }
00449 
00450         // GEO
00451         else if ( identifier == QLatin1String( "geo" ) ) {
00452           Geo geo;
00453 
00454           const QStringList geoParts =
00455             (*lineIt).value().toString().split( QLatin1Char( ';' ), QString::KeepEmptyParts );
00456           if ( geoParts.size() >= 2 ) {
00457             geo.setLatitude( geoParts[ 0 ].toFloat() );
00458             geo.setLongitude( geoParts[ 1 ].toFloat() );
00459             addr.setGeo( geo );
00460           }
00461         }
00462 
00463         // KEY
00464         else if ( identifier == QLatin1String( "key" ) ) {
00465           addr.insertKey( parseKey( *lineIt ) );
00466         }
00467 
00468         // LABEL
00469         else if ( identifier == QLatin1String( "label" ) ) {
00470           Address::Type type;
00471 
00472           const QStringList types = (*lineIt).parameters( QLatin1String( "type" ) );
00473           for ( QStringList::ConstIterator it = types.begin(); it != types.end(); ++it ) {
00474             type |= mAddressTypeMap[ (*it).toLower() ];
00475           }
00476 
00477           bool available = false;
00478           KABC::Address::List addressList = addr.addresses();
00479           for ( KABC::Address::List::Iterator it = addressList.begin();
00480                 it != addressList.end(); ++it ) {
00481             if ( (*it).type() == type ) {
00482               (*it).setLabel( (*lineIt).value().toString() );
00483               addr.insertAddress( *it );
00484               available = true;
00485               break;
00486             }
00487           }
00488 
00489           if ( !available ) { // a standalone LABEL tag
00490             KABC::Address address( type );
00491             address.setLabel( (*lineIt).value().toString() );
00492             addr.insertAddress( address );
00493           }
00494         }
00495 
00496         // LOGO
00497         else if ( identifier == QLatin1String( "logo" ) ) {
00498           addr.setLogo( parsePicture( *lineIt ) );
00499         }
00500 
00501         // MAILER
00502         else if ( identifier == QLatin1String( "mailer" ) ) {
00503           addr.setMailer( (*lineIt).value().toString() );
00504         }
00505 
00506         // N
00507         else if ( identifier == QLatin1String( "n" ) ) {
00508           const QStringList nameParts = splitString( semicolonSep, (*lineIt).value().toString() );
00509           if ( nameParts.count() > 0 ) {
00510             addr.setFamilyName( nameParts[ 0 ] );
00511           }
00512           if ( nameParts.count() > 1 ) {
00513             addr.setGivenName( nameParts[ 1 ] );
00514           }
00515           if ( nameParts.count() > 2 ) {
00516             addr.setAdditionalName( nameParts[ 2 ] );
00517           }
00518           if ( nameParts.count() > 3 ) {
00519             addr.setPrefix( nameParts[ 3 ] );
00520           }
00521           if ( nameParts.count() > 4 ) {
00522             addr.setSuffix( nameParts[ 4 ] );
00523           }
00524         }
00525 
00526         // NAME
00527         else if ( identifier == QLatin1String( "name" ) ) {
00528           addr.setName( (*lineIt).value().toString() );
00529         }
00530 
00531         // NICKNAME
00532         else if ( identifier == QLatin1String( "nickname" ) ) {
00533           addr.setNickName( (*lineIt).value().toString() );
00534         }
00535 
00536         // NOTE
00537         else if ( identifier == QLatin1String( "note" ) ) {
00538           addr.setNote( (*lineIt).value().toString() );
00539         }
00540 
00541         // ORGANIZATION
00542         else if ( identifier == QLatin1String( "org" ) ) {
00543           const QStringList orgParts = splitString( semicolonSep, (*lineIt).value().toString() );
00544           if ( orgParts.count() > 0 ) {
00545             addr.setOrganization( orgParts[ 0 ] );
00546           }
00547           if ( orgParts.count() > 1 ) {
00548             addr.setDepartment( orgParts[ 1 ] );
00549           }
00550         }
00551 
00552         // PHOTO
00553         else if ( identifier == QLatin1String( "photo" ) ) {
00554           addr.setPhoto( parsePicture( *lineIt ) );
00555         }
00556 
00557         // PROID
00558         else if ( identifier == QLatin1String( "prodid" ) ) {
00559           addr.setProductId( (*lineIt).value().toString() );
00560         }
00561 
00562         // REV
00563         else if ( identifier == QLatin1String( "rev" ) ) {
00564           addr.setRevision( parseDateTime( (*lineIt).value().toString() ) );
00565         }
00566 
00567         // ROLE
00568         else if ( identifier == QLatin1String( "role" ) ) {
00569           addr.setRole( (*lineIt).value().toString() );
00570         }
00571 
00572         // SORT-STRING
00573         else if ( identifier == QLatin1String( "sort-string" ) ) {
00574           addr.setSortString( (*lineIt).value().toString() );
00575         }
00576 
00577         // SOUND
00578         else if ( identifier == QLatin1String( "sound" ) ) {
00579           addr.setSound( parseSound( *lineIt ) );
00580         }
00581 
00582         // TEL
00583         else if ( identifier == QLatin1String( "tel" ) ) {
00584           PhoneNumber phone;
00585           phone.setNumber( (*lineIt).value().toString() );
00586 
00587           PhoneNumber::Type type;
00588 
00589           const QStringList types = (*lineIt).parameters( QLatin1String( "type" ) );
00590           for ( QStringList::ConstIterator it = types.begin(); it != types.end(); ++it ) {
00591             type |= mPhoneTypeMap[(*it).toUpper()];
00592           }
00593 
00594           phone.setType( type );
00595 
00596           addr.insertPhoneNumber( phone );
00597         }
00598 
00599         // TITLE
00600         else if ( identifier == QLatin1String( "title" ) ) {
00601           addr.setTitle( (*lineIt).value().toString() );
00602         }
00603 
00604         // TZ
00605         else if ( identifier == QLatin1String( "tz" ) ) {
00606           TimeZone tz;
00607           const QString date = (*lineIt).value().toString();
00608 
00609           int hours = date.mid( 1, 2 ).toInt();
00610           int minutes = date.mid( 4, 2 ).toInt();
00611           int offset = ( hours * 60 ) + minutes;
00612           offset = offset * ( date[ 0 ] == QLatin1Char( '+' ) ? 1 : -1 );
00613 
00614           tz.setOffset( offset );
00615           addr.setTimeZone( tz );
00616         }
00617 
00618         // UID
00619         else if ( identifier == QLatin1String( "uid" ) ) {
00620           addr.setUid( (*lineIt).value().toString() );
00621         }
00622 
00623         // URL
00624         else if ( identifier == QLatin1String( "url" ) ) {
00625           addr.setUrl( KUrl( (*lineIt).value().toString() ) );
00626         }
00627 
00628         // X-
00629         else if ( identifier.startsWith( QLatin1String( "x-" ) ) ) {
00630           const QString key = (*lineIt).identifier().mid( 2 );
00631           int dash = key.indexOf( QLatin1Char( '-' ) );
00632           addr.insertCustom( key.left( dash ), key.mid( dash + 1 ), (*lineIt).value().toString() );
00633         }
00634       }
00635     }
00636 
00637     addrList.append( addr );
00638   }
00639 
00640   return addrList;
00641 }
00642 
00643 QDateTime VCardTool::parseDateTime( const QString &str ) const
00644 {
00645   QDate date;
00646   QTime time;
00647 
00648   if ( str.indexOf( QLatin1Char( '-' ) ) == -1 ) { // is base format (yyyymmdd)
00649     date = QDate( str.left( 4 ).toInt(), str.mid( 4, 2 ).toInt(),
00650                   str.mid( 6, 2 ).toInt() );
00651   } else { // is extended format yyyy-mm-dd
00652     date = QDate( str.left( 4 ).toInt(), str.mid( 5, 2 ).toInt(),
00653                   str.mid( 8, 2 ).toInt() );
00654   }
00655 
00656   // does it also contain a time ? (Note: mm, ss are optional according ISO-8601)
00657   int timeStart = str.indexOf( QLatin1Char( 'T' ) );
00658   if ( timeStart >= 0 ) {
00659     int hour = 0, minute = 0, second = 0;
00660 
00661     hour = str.mid( timeStart + 1, 2 ).toInt();  // hour must always be given
00662 
00663     if ( str.indexOf( QLatin1Char( ':' ), timeStart + 1 ) > 0 ) {  // extended format (hh:mm:ss)
00664       if ( str.length() >= ( timeStart + 5 ) ) {
00665         minute = str.mid( timeStart + 4, 2 ).toInt();
00666         if ( str.length() >= ( timeStart + 8 ) ) {
00667           second = str.mid( timeStart + 7, 2 ).toInt();
00668         }
00669       }
00670     } else {  // basic format (hhmmss)
00671       if ( str.length() >= ( timeStart + 4 ) ) {
00672         minute = str.mid( timeStart + 3, 2 ).toInt();
00673         if ( str.length() >= ( timeStart + 6 ) ) {
00674           second = str.mid( timeStart + 5, 2 ).toInt();
00675         }
00676       }
00677     }
00678 
00679     time = QTime( hour, minute, second );
00680   }
00681 
00682   Qt::TimeSpec spec = ( str.right( 1 ) == QLatin1String( "Z" ) ) ? Qt::UTC : Qt::LocalTime;
00683 
00684   QDateTime dateTime(date);
00685 
00686   // explicitly set the time, which might be invalid, to keep the information
00687   // that the time is invalid. In createDateTime() the time/invalid flag is
00688   // checked which omits then to print the timestamp
00689   // This is needed to reproduce the given string in input
00690   // e.g. BDAY:2008-12-30
00691   // without time shall also result in a string without a time
00692   dateTime.setTime(time);
00693 
00694   dateTime.setTimeSpec(spec);
00695   return dateTime;
00696 }
00697 
00698 QString VCardTool::createDateTime( const QDateTime &dateTime ) const
00699 {
00700   QString str;
00701 
00702   if ( dateTime.date().isValid() ) {
00703     str.sprintf( "%4d-%02d-%02d", dateTime.date().year(), dateTime.date().month(),
00704                  dateTime.date().day() );
00705     if ( dateTime.time().isValid() ) {
00706       QString tmp;
00707       tmp.sprintf( "T%02d:%02d:%02d", dateTime.time().hour(), dateTime.time().minute(),
00708                    dateTime.time().second() );
00709       str += tmp;
00710 
00711       if ( dateTime.timeSpec() == Qt::UTC ) {
00712         str += QLatin1Char( 'Z' );
00713       }
00714     }
00715   }
00716 
00717   return str;
00718 }
00719 
00720 Picture VCardTool::parsePicture( const VCardLine &line ) const
00721 {
00722   Picture pic;
00723 
00724   const QStringList params = line.parameterList();
00725   if ( params.contains( QLatin1String( "encoding" ) ) ) {
00726     QImage img;
00727     img.loadFromData( line.value().toByteArray() );
00728     pic.setData( img );
00729   } else if ( params.contains( QLatin1String( "value" ) ) ) {
00730     if ( line.parameter( QLatin1String( "value" ) ).toLower() == QLatin1String( "uri" ) ) {
00731       pic.setUrl( line.value().toString() );
00732     }
00733   }
00734 
00735   if ( params.contains( QLatin1String( "type" ) ) ) {
00736     pic.setType( line.parameter( QLatin1String( "type" ) ) );
00737   }
00738 
00739   return pic;
00740 }
00741 
00742 VCardLine VCardTool::createPicture( const QString &identifier, const Picture &pic ) const
00743 {
00744   VCardLine line( identifier );
00745 
00746   if ( pic.isIntern() ) {
00747     if ( !pic.data().isNull() ) {
00748       QByteArray input;
00749       QBuffer buffer( &input );
00750       buffer.open( QIODevice::WriteOnly );
00751 
00752       if ( !pic.data().hasAlphaChannel() ) {
00753         pic.data().save( &buffer, "JPEG" );
00754 
00755         line.setValue( input );
00756         line.addParameter( QLatin1String( "encoding" ), QLatin1String( "b" ) );
00757         line.addParameter( QLatin1String( "type" ), QLatin1String( "image/jpeg" ) );
00758       } else {
00759         pic.data().save( &buffer, "PNG" );
00760 
00761         line.setValue( input );
00762         line.addParameter( QLatin1String( "encoding" ), QLatin1String( "b" ) );
00763         line.addParameter( QLatin1String( "type" ), QLatin1String( "image/png" ) );
00764       }
00765     }
00766   } else if ( !pic.url().isEmpty() ) {
00767     line.setValue( pic.url() );
00768     line.addParameter( QLatin1String( "value" ), QLatin1String( "URI" ) );
00769   }
00770 
00771   return line;
00772 }
00773 
00774 Sound VCardTool::parseSound( const VCardLine &line ) const
00775 {
00776   Sound snd;
00777 
00778   const QStringList params = line.parameterList();
00779   if ( params.contains( QLatin1String( "encoding" ) ) ) {
00780     snd.setData( line.value().toByteArray() );
00781   } else if ( params.contains( QLatin1String( "value" ) ) ) {
00782     if ( line.parameter( QLatin1String( "value" ) ).toLower() == QLatin1String( "uri" ) ) {
00783       snd.setUrl( line.value().toString() );
00784     }
00785   }
00786 
00787 /* TODO: support sound types
00788   if ( params.contains( "type" ) )
00789     snd.setType( line.parameter( "type" ) );
00790 */
00791 
00792   return snd;
00793 }
00794 
00795 VCardLine VCardTool::createSound( const Sound &snd ) const
00796 {
00797   VCardLine line( QLatin1String( "SOUND" ) );
00798 
00799   if ( snd.isIntern() ) {
00800     if ( !snd.data().isEmpty() ) {
00801       line.setValue( snd.data() );
00802       line.addParameter( QLatin1String( "encoding" ), QLatin1String( "b" ) );
00803       // TODO: need to store sound type!!!
00804     }
00805   } else if ( !snd.url().isEmpty() ) {
00806     line.setValue( snd.url() );
00807     line.addParameter( QLatin1String( "value" ), QLatin1String( "URI" ) );
00808   }
00809 
00810   return line;
00811 }
00812 
00813 Key VCardTool::parseKey( const VCardLine &line ) const
00814 {
00815   Key key;
00816 
00817   const QStringList params = line.parameterList();
00818   if ( params.contains( QLatin1String( "encoding" ) ) ) {
00819     key.setBinaryData( line.value().toByteArray() );
00820   } else {
00821     key.setTextData( line.value().toString() );
00822   }
00823 
00824   if ( params.contains( QLatin1String( "type" ) ) ) {
00825     if ( line.parameter( QLatin1String( "type" ) ).toLower() == QLatin1String( "x509" ) ) {
00826       key.setType( Key::X509 );
00827     } else if ( line.parameter( QLatin1String( "type" ) ).toLower() == QLatin1String( "pgp" ) ) {
00828       key.setType( Key::PGP );
00829     } else {
00830       key.setType( Key::Custom );
00831       key.setCustomTypeString( line.parameter( QLatin1String( "type" ) ) );
00832     }
00833   }
00834 
00835   return key;
00836 }
00837 
00838 VCardLine VCardTool::createKey( const Key &key ) const
00839 {
00840   VCardLine line( QLatin1String( "KEY" ) );
00841 
00842   if ( key.isBinary() ) {
00843     if ( !key.binaryData().isEmpty() ) {
00844       line.setValue( key.binaryData() );
00845       line.addParameter( QLatin1String( "encoding" ), QLatin1String( "b" ) );
00846     }
00847   } else if ( !key.textData().isEmpty() ) {
00848     line.setValue( key.textData() );
00849   }
00850 
00851   if ( key.type() == Key::X509 ) {
00852     line.addParameter( QLatin1String( "type" ), QLatin1String( "X509" ) );
00853   } else if ( key.type() == Key::PGP ) {
00854     line.addParameter( QLatin1String( "type" ), QLatin1String( "PGP" ) );
00855   } else if ( key.type() == Key::Custom ) {
00856     line.addParameter( QLatin1String( "type" ), key.customTypeString() );
00857   }
00858 
00859   return line;
00860 }
00861 
00862 Secrecy VCardTool::parseSecrecy( const VCardLine &line ) const
00863 {
00864   Secrecy secrecy;
00865 
00866   const QString value = line.value().toString().toLower();
00867   if ( value == QLatin1String( "public" ) ) {
00868     secrecy.setType( Secrecy::Public );
00869   } else if ( value == QLatin1String( "private" ) ) {
00870     secrecy.setType( Secrecy::Private );
00871   } else if ( value == QLatin1String( "confidential" ) ) {
00872     secrecy.setType( Secrecy::Confidential );
00873   }
00874 
00875   return secrecy;
00876 }
00877 
00878 VCardLine VCardTool::createSecrecy( const Secrecy &secrecy ) const
00879 {
00880   VCardLine line( QLatin1String( "CLASS" ) );
00881 
00882   int type = secrecy.type();
00883 
00884   if ( type == Secrecy::Public ) {
00885     line.setValue( QLatin1String( "PUBLIC" ) );
00886   } else if ( type == Secrecy::Private ) {
00887     line.setValue( QLatin1String( "PRIVATE" ) );
00888   } else if ( type == Secrecy::Confidential ) {
00889     line.setValue( QLatin1String( "CONFIDENTIAL" ) );
00890   }
00891 
00892   return line;
00893 }
00894 
00895 QStringList VCardTool::splitString( const QChar &sep, const QString &str ) const
00896 {
00897   QStringList list;
00898   QString value( str );
00899 
00900   int start = 0;
00901   int pos = value.indexOf( sep, start );
00902 
00903   while ( pos != -1 ) {
00904     if ( pos == 0 || value[ pos - 1 ] != QLatin1Char( '\\' ) ) {
00905       if ( pos > start && pos <= (int)value.length() ) {
00906         list << value.mid( start, pos - start );
00907       } else {
00908         list << QString();
00909       }
00910 
00911       start = pos + 1;
00912       pos = value.indexOf( sep, start );
00913     } else {
00914       value.replace( pos - 1, 2, sep );
00915       pos = value.indexOf( sep, pos );
00916     }
00917   }
00918 
00919   int l = value.length() - 1;
00920   if ( value.mid( start, l - start + 1 ).length() > 0 ) {
00921     list << value.mid( start, l - start + 1 );
00922   } else {
00923     list << QString();
00924   }
00925 
00926   return list;
00927 }

kabc

Skip menu "kabc"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • akonadi
  • kabc
  • kblog
  • kcal
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  • kldap
  • kmime
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal