• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdeabc
 

tdeabc

vcardtool.cpp

00001 /*
00002     This file is part of libtdeabc.
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 <tqbuffer.h>
00022 #include <tqdatastream.h>
00023 #include <tqregexp.h>
00024 #include <tqstring.h>
00025 
00026 #include "agent.h"
00027 #include "key.h"
00028 #include "picture.h"
00029 #include "secrecy.h"
00030 #include "sound.h"
00031 
00032 #include "vcardtool.h"
00033 
00034 using namespace TDEABC;
00035 
00036 static bool needsEncoding( const TQString &value )
00037 {
00038   uint length = value.length();
00039   for ( uint i = 0; i < length; ++i ) {
00040     char c = value.at( i ).latin1();
00041     if ( (c < 33 || c > 126) && c != ' ' && c != '=' )
00042       return true;
00043   }
00044 
00045   return false;
00046 }
00047 
00048 VCardTool::VCardTool()
00049 {
00050   mAddressTypeMap.insert( "dom", Address::Dom );
00051   mAddressTypeMap.insert( "intl", Address::Intl );
00052   mAddressTypeMap.insert( "postal", Address::Postal );
00053   mAddressTypeMap.insert( "parcel", Address::Parcel );
00054   mAddressTypeMap.insert( "home", Address::Home );
00055   mAddressTypeMap.insert( "work", Address::Work );
00056   mAddressTypeMap.insert( "pref", Address::Pref );
00057 
00058   mPhoneTypeMap.insert( "HOME", PhoneNumber::Home );
00059   mPhoneTypeMap.insert( "WORK", PhoneNumber::Work );
00060   mPhoneTypeMap.insert( "MSG", PhoneNumber::Msg );
00061   mPhoneTypeMap.insert( "PREF", PhoneNumber::Pref );
00062   mPhoneTypeMap.insert( "VOICE", PhoneNumber::Voice );
00063   mPhoneTypeMap.insert( "FAX", PhoneNumber::Fax );
00064   mPhoneTypeMap.insert( "CELL", PhoneNumber::Cell );
00065   mPhoneTypeMap.insert( "VIDEO", PhoneNumber::Video );
00066   mPhoneTypeMap.insert( "BBS", PhoneNumber::Bbs );
00067   mPhoneTypeMap.insert( "MODEM", PhoneNumber::Modem );
00068   mPhoneTypeMap.insert( "CAR", PhoneNumber::Car );
00069   mPhoneTypeMap.insert( "ISDN", PhoneNumber::Isdn );
00070   mPhoneTypeMap.insert( "PCS", PhoneNumber::Pcs );
00071   mPhoneTypeMap.insert( "PAGER", PhoneNumber::Pager );
00072 }
00073 
00074 VCardTool::~VCardTool()
00075 {
00076 }
00077 
00078 // TODO: make list a const&
00079 TQString VCardTool::createVCards( Addressee::List list, VCard::Version version )
00080 {
00081   VCard::List vCardList;
00082 
00083   Addressee::List::ConstIterator addrIt;
00084   Addressee::List::ConstIterator listEnd( list.constEnd() );
00085   for ( addrIt = list.constBegin(); addrIt != listEnd; ++addrIt ) {
00086     VCard card;
00087     TQStringList::ConstIterator strIt;
00088 
00089     // ADR + LABEL
00090     const Address::List addresses = (*addrIt).addresses();
00091     for ( Address::List::ConstIterator it = addresses.begin(); it != addresses.end(); ++it ) {
00092       TQStringList address;
00093 
00094       bool isEmpty = ( (*it).postOfficeBox().isEmpty() &&
00095                      (*it).extended().isEmpty() &&
00096                      (*it).street().isEmpty() &&
00097                      (*it).locality().isEmpty() &&
00098                      (*it).region().isEmpty() &&
00099                      (*it).postalCode().isEmpty() &&
00100                      (*it).country().isEmpty() );
00101 
00102       address.append( (*it).postOfficeBox().replace( ';', "\\;" ) );
00103       address.append( (*it).extended().replace( ';', "\\;" ) );
00104       address.append( (*it).street().replace( ';', "\\;" ) );
00105       address.append( (*it).locality().replace( ';', "\\;" ) );
00106       address.append( (*it).region().replace( ';', "\\;" ) );
00107       address.append( (*it).postalCode().replace( ';', "\\;" ) );
00108       address.append( (*it).country().replace( ';', "\\;" ) );
00109 
00110       VCardLine adrLine( "ADR", address.join( ";" ) );
00111       if ( version == VCard::v2_1 && needsEncoding( address.join( ";" ) ) ) {
00112         adrLine.addParameter( "charset", "UTF-8" );
00113         adrLine.addParameter( "encoding", "QUOTED-PRINTABLE" );
00114       }
00115 
00116       VCardLine labelLine( "LABEL", (*it).label() );
00117       if ( version == VCard::v2_1 && needsEncoding( (*it).label() ) ) {
00118         labelLine.addParameter( "charset", "UTF-8" );
00119         labelLine.addParameter( "encoding", "QUOTED-PRINTABLE" );
00120       }
00121 
00122       bool hasLabel = !(*it).label().isEmpty();
00123       TQMap<TQString, int>::ConstIterator typeIt;
00124       for ( typeIt = mAddressTypeMap.constBegin(); typeIt != mAddressTypeMap.constEnd(); ++typeIt ) {
00125         if ( typeIt.data() & (*it).type() ) {
00126           adrLine.addParameter( "TYPE", typeIt.key() );
00127           if ( hasLabel )
00128             labelLine.addParameter( "TYPE",  typeIt.key() );
00129         }
00130       }
00131 
00132       if ( !isEmpty )
00133         card.addLine( adrLine );
00134       if ( hasLabel )
00135         card.addLine( labelLine );
00136     }
00137 
00138     // AGENT
00139     card.addLine( createAgent( version, (*addrIt).agent() ) );
00140 
00141     // BDAY
00142     card.addLine( VCardLine( "BDAY", createDateTime( TQT_TQDATETIME_OBJECT((*addrIt).birthday()) ) ) );
00143 
00144     // CATEGORIES
00145     if ( version == VCard::v3_0 ) {
00146       TQStringList categories = (*addrIt).categories();
00147       TQStringList::Iterator catIt;
00148       for ( catIt = categories.begin(); catIt != categories.end(); ++catIt )
00149         (*catIt).replace( ',', "\\," );
00150 
00151       VCardLine catLine( "CATEGORIES", categories.join( "," ) );
00152       if ( version == VCard::v2_1 && needsEncoding( categories.join( "," ) ) ) {
00153         catLine.addParameter( "charset", "UTF-8" );
00154         catLine.addParameter( "encoding", "QUOTED-PRINTABLE" );
00155       }
00156 
00157       card.addLine( catLine );
00158     }
00159 
00160     // CLASS
00161     if ( version == VCard::v3_0 ) {
00162       card.addLine( createSecrecy( (*addrIt).secrecy() ) );
00163     }
00164 
00165     // EMAIL
00166     const TQStringList emails = (*addrIt).emails();
00167     bool pref = true;
00168     for ( strIt = emails.begin(); strIt != emails.end(); ++strIt ) {
00169       VCardLine line( "EMAIL", *strIt );
00170       if ( pref == true && emails.count() > 1 ) {
00171         line.addParameter( "TYPE", "PREF" );
00172         pref = false;
00173       }
00174       card.addLine( line );
00175     }
00176 
00177     // FN
00178     VCardLine fnLine( "FN", TQString((*addrIt).formattedName()) );
00179     if ( version == VCard::v2_1 && needsEncoding( (*addrIt).formattedName() ) ) {
00180       fnLine.addParameter( "charset", "UTF-8" );
00181       fnLine.addParameter( "encoding", "QUOTED-PRINTABLE" );
00182     }
00183     card.addLine( fnLine );
00184 
00185     // GEO
00186     Geo geo = (*addrIt).geo();
00187     if ( geo.isValid() ) {
00188       TQString str;
00189       str.sprintf( "%.6f;%.6f", geo.latitude(), geo.longitude() );
00190       card.addLine( VCardLine( "GEO", str ) );
00191     }
00192 
00193     // KEY
00194     const Key::List keys = (*addrIt).keys();
00195     Key::List::ConstIterator keyIt;
00196     for ( keyIt = keys.begin(); keyIt != keys.end(); ++keyIt )
00197       card.addLine( createKey( *keyIt ) );
00198 
00199     // LOGO
00200     card.addLine( createPicture( "LOGO", (*addrIt).logo() ) );
00201 
00202     // MAILER
00203     VCardLine mailerLine( "MAILER", TQString((*addrIt).mailer()) );
00204     if ( version == VCard::v2_1 && needsEncoding( (*addrIt).mailer() ) ) {
00205       mailerLine.addParameter( "charset", "UTF-8" );
00206       mailerLine.addParameter( "encoding", "QUOTED-PRINTABLE" );
00207     }
00208     card.addLine( mailerLine );
00209 
00210     // N
00211     TQStringList name;
00212     name.append( (*addrIt).familyName().replace( ';', "\\;" ) );
00213     name.append( (*addrIt).givenName().replace( ';', "\\;" ) );
00214     name.append( (*addrIt).additionalName().replace( ';', "\\;" ) );
00215     name.append( (*addrIt).prefix().replace( ';', "\\;" ) );
00216     name.append( (*addrIt).suffix().replace( ';', "\\;" ) );
00217 
00218     VCardLine nLine( "N", name.join( ";" ) );
00219     if ( version == VCard::v2_1 && needsEncoding( name.join( ";" ) ) ) {
00220       nLine.addParameter( "charset", "UTF-8" );
00221       nLine.addParameter( "encoding", "QUOTED-PRINTABLE" );
00222     }
00223     card.addLine( nLine );
00224 
00225     // NAME
00226     VCardLine nameLine( "NAME", TQString((*addrIt).name()) );
00227     if ( version == VCard::v2_1 && needsEncoding( (*addrIt).name() ) ) {
00228       nameLine.addParameter( "charset", "UTF-8" );
00229       nameLine.addParameter( "encoding", "QUOTED-PRINTABLE" );
00230     }
00231     card.addLine( nameLine );
00232 
00233     // NICKNAME
00234     if ( version == VCard::v3_0 )
00235       card.addLine( VCardLine( "NICKNAME", TQString((*addrIt).nickName()) ) );
00236 
00237     // NOTE
00238     VCardLine noteLine( "NOTE", TQString((*addrIt).note()) );
00239     if ( version == VCard::v2_1 && needsEncoding( (*addrIt).note() ) ) {
00240       noteLine.addParameter( "charset", "UTF-8" );
00241       noteLine.addParameter( "encoding", "QUOTED-PRINTABLE" );
00242     }
00243     card.addLine( noteLine );
00244 
00245     // ORG
00246     TQStringList organization;
00247     organization.append( ( *addrIt ).organization().replace( ';', "\\;" ) );
00248     if ( !( *addrIt ).department().isEmpty() )
00249       organization.append( ( *addrIt ).department().replace( ';', "\\;" ) );
00250     VCardLine orgLine( "ORG", organization.join( ";" ) );
00251     if ( version == VCard::v2_1 && needsEncoding( organization.join( ";" ) ) ) {
00252       orgLine.addParameter( "charset", "UTF-8" );
00253       orgLine.addParameter( "encoding", "QUOTED-PRINTABLE" );
00254     }
00255     card.addLine( orgLine );
00256 
00257     // PHOTO
00258     card.addLine( createPicture( "PHOTO", (*addrIt).photo() ) );
00259 
00260     // PROID
00261     if ( version == VCard::v3_0 )
00262       card.addLine( VCardLine( "PRODID", TQString((*addrIt).productId()) ) );
00263 
00264     // REV
00265     card.addLine( VCardLine( "REV", createDateTime( TQT_TQDATETIME_OBJECT((*addrIt).revision()) ) ) );
00266 
00267     // ROLE
00268     VCardLine roleLine( "ROLE", TQString((*addrIt).role()) );
00269     if ( version == VCard::v2_1 && needsEncoding( (*addrIt).role() ) ) {
00270       roleLine.addParameter( "charset", "UTF-8" );
00271       roleLine.addParameter( "encoding", "QUOTED-PRINTABLE" );
00272     }
00273     card.addLine( roleLine );
00274 
00275     // SORT-STRING
00276     if ( version == VCard::v3_0 )
00277       card.addLine( VCardLine( "SORT-STRING", TQString((*addrIt).sortString()) ) );
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( "TEL", (*phoneIt).number() );
00287 
00288       TQMap<TQString, int>::ConstIterator typeIt;
00289       for ( typeIt = mPhoneTypeMap.constBegin(); typeIt != mPhoneTypeMap.constEnd(); ++typeIt ) {
00290         if ( typeIt.data() & (*phoneIt).type() )
00291           line.addParameter( "TYPE", typeIt.key() );
00292       }
00293 
00294       card.addLine( line );
00295     }
00296 
00297     // TITLE
00298     VCardLine titleLine( "TITLE", TQString((*addrIt).title()) );
00299     if ( version == VCard::v2_1 && needsEncoding( (*addrIt).title() ) ) {
00300       titleLine.addParameter( "charset", "UTF-8" );
00301       titleLine.addParameter( "encoding", "QUOTED-PRINTABLE" );
00302     }
00303     card.addLine( titleLine );
00304 
00305     // TZ
00306     TimeZone timeZone = (*addrIt).timeZone();
00307     if ( timeZone.isValid() ) {
00308       TQString str;
00309 
00310       int neg = 1;
00311       if ( timeZone.offset() < 0 )
00312         neg = -1;
00313 
00314       str.sprintf( "%c%02d:%02d", ( timeZone.offset() >= 0 ? '+' : '-' ),
00315                                   ( timeZone.offset() / 60 ) * neg,
00316                                   ( timeZone.offset() % 60 ) * neg );
00317 
00318       card.addLine( VCardLine( "TZ", str ) );
00319     }
00320 
00321     // UID
00322     card.addLine( VCardLine( "UID", (*addrIt).uid() ) );
00323 
00324     // UID
00325     card.addLine( VCardLine( "URI", (*addrIt).uri() ) );
00326 
00327     // URL
00328     card.addLine( VCardLine( "URL", (*addrIt).url().url() ) );
00329 
00330     // VERSION
00331     if ( version == VCard::v2_1 )
00332       card.addLine( VCardLine( "VERSION", "2.1" ) );
00333     if ( version == VCard::v3_0 )
00334       card.addLine( VCardLine( "VERSION", "3.0" ) );
00335 
00336     // X-
00337     const TQStringList customs = (*addrIt).customs();
00338     for ( strIt = customs.begin(); strIt != customs.end(); ++strIt ) {
00339       TQString identifier = "X-" + (*strIt).left( (*strIt).find( ":" ) );
00340       TQString value = (*strIt).mid( (*strIt).find( ":" ) + 1 );
00341       if ( value.isEmpty() )
00342         continue;
00343 
00344       VCardLine line( identifier, value );
00345       if ( version == VCard::v2_1 && needsEncoding( value ) ) {
00346         line.addParameter( "charset", "UTF-8" );
00347         line.addParameter( "encoding", "QUOTED-PRINTABLE" );
00348       }
00349       card.addLine( line );
00350     }
00351 
00352     vCardList.append( card );
00353   }
00354 
00355   return VCardParser::createVCards( vCardList );
00356 }
00357 
00358 Addressee::List VCardTool::parseVCards( const TQString& vcard )
00359 {
00360   static const TQChar semicolonSep( ';' );
00361   static const TQChar commaSep( ',' );
00362   TQString identifier;
00363 
00364   Addressee::List addrList;
00365   const VCard::List vCardList = VCardParser::parseVCards( vcard );
00366 
00367   VCard::List::ConstIterator cardIt;
00368   VCard::List::ConstIterator listEnd( vCardList.end() );
00369   for ( cardIt = vCardList.begin(); cardIt != listEnd; ++cardIt ) {
00370     Addressee addr;
00371 
00372     const TQStringList idents = (*cardIt).identifiers();
00373     TQStringList::ConstIterator identIt;
00374     TQStringList::ConstIterator identEnd( idents.end() );
00375     for ( identIt = idents.begin(); identIt != identEnd; ++identIt ) {
00376       const VCardLine::List lines = (*cardIt).lines( (*identIt) );
00377       VCardLine::List::ConstIterator lineIt;
00378 
00379       // iterate over the lines
00380       for ( lineIt = lines.begin(); lineIt != lines.end(); ++lineIt ) {
00381         identifier = (*lineIt).identifier().lower();
00382         // ADR
00383         if ( identifier == "adr" ) {
00384           Address address;
00385           const TQStringList addrParts = splitString( semicolonSep, (*lineIt).value().asString() );
00386           if ( addrParts.count() > 0 )
00387             address.setPostOfficeBox( addrParts[ 0 ] );
00388           if ( addrParts.count() > 1 )
00389             address.setExtended( addrParts[ 1 ] );
00390           if ( addrParts.count() > 2 )
00391             address.setStreet( addrParts[ 2 ] );
00392           if ( addrParts.count() > 3 )
00393             address.setLocality( addrParts[ 3 ] );
00394           if ( addrParts.count() > 4 )
00395             address.setRegion( addrParts[ 4 ] );
00396           if ( addrParts.count() > 5 )
00397             address.setPostalCode( addrParts[ 5 ] );
00398           if ( addrParts.count() > 6 )
00399             address.setCountry( addrParts[ 6 ] );
00400 
00401           int type = 0;
00402 
00403           const TQStringList types = (*lineIt).parameters( "type" );
00404           for ( TQStringList::ConstIterator it = types.begin(); it != types.end(); ++it )
00405             type += mAddressTypeMap[ (*it).lower() ];
00406 
00407           address.setType( type );
00408           addr.insertAddress( address );
00409         }
00410 
00411         // AGENT
00412         else if ( identifier == "agent" )
00413           addr.setAgent( parseAgent( *lineIt ) );
00414 
00415         // BDAY
00416         else if ( identifier == "bday" ) {
00417           TQString s((*lineIt).value().asString());
00418           if ( s.length() > 0 )
00419             addr.setBirthday( parseDateTime( s ) );
00420         }
00421         
00422         // CATEGORIES
00423         else if ( identifier == "categories" ) {
00424           const TQStringList categories = splitString( commaSep, (*lineIt).value().asString() );
00425           addr.setCategories( categories );
00426         }
00427 
00428         // CLASS
00429         else if ( identifier == "class" )
00430           addr.setSecrecy( parseSecrecy( *lineIt ) );
00431 
00432         // EMAIL
00433         else if ( identifier == "email" ) {
00434           const TQStringList types = (*lineIt).parameters( "type" );
00435           addr.insertEmail( (*lineIt).value().asString(), types.findIndex( "PREF" ) != -1 );
00436         }
00437 
00438         // FN
00439         else if ( identifier == "fn" )
00440           addr.setFormattedName( (*lineIt).value().asString() );
00441 
00442         // GEO
00443         else if ( identifier == "geo" ) {
00444           Geo geo;
00445 
00446           const TQStringList geoParts = TQStringList::split( ';', (*lineIt).value().asString(), true );
00447           geo.setLatitude( geoParts[ 0 ].toFloat() );
00448           geo.setLongitude( geoParts[ 1 ].toFloat() );
00449 
00450           addr.setGeo( geo );
00451         }
00452 
00453         // KEY
00454         else if ( identifier == "key" )
00455           addr.insertKey( parseKey( *lineIt ) );
00456 
00457         // LABEL
00458         else if ( identifier == "label" ) {
00459           int type = 0;
00460 
00461           const TQStringList types = (*lineIt).parameters( "type" );
00462           for ( TQStringList::ConstIterator it = types.begin(); it != types.end(); ++it )
00463             type += mAddressTypeMap[ (*it).lower() ];
00464 
00465           bool available = false;
00466           TDEABC::Address::List addressList = addr.addresses();
00467           TDEABC::Address::List::Iterator it;
00468           for ( it = addressList.begin(); it != addressList.end(); ++it ) {
00469             if ( (*it).type() == type ) {
00470               (*it).setLabel( (*lineIt).value().asString() );
00471               addr.insertAddress( *it );
00472               available = true;
00473               break;
00474             }
00475           }
00476 
00477           if ( !available ) { // a standalone LABEL tag
00478             TDEABC::Address address( type );
00479             address.setLabel( (*lineIt).value().asString() );
00480             addr.insertAddress( address );
00481           }
00482         }
00483 
00484         // LOGO
00485         else if ( identifier == "logo" )
00486           addr.setLogo( parsePicture( *lineIt ) );
00487 
00488         // MAILER
00489         else if ( identifier == "mailer" )
00490           addr.setMailer( (*lineIt).value().asString() );
00491 
00492         // N
00493         else if ( identifier == "n" ) {
00494           const TQStringList nameParts = splitString( semicolonSep, (*lineIt).value().asString() );
00495           if ( nameParts.count() > 0 )
00496             addr.setFamilyName( nameParts[ 0 ] );
00497           if ( nameParts.count() > 1 )
00498             addr.setGivenName( nameParts[ 1 ] );
00499           if ( nameParts.count() > 2 )
00500             addr.setAdditionalName( nameParts[ 2 ] );
00501           if ( nameParts.count() > 3 )
00502             addr.setPrefix( nameParts[ 3 ] );
00503           if ( nameParts.count() > 4 )
00504             addr.setSuffix( nameParts[ 4 ] );
00505         }
00506 
00507         // NAME
00508         else if ( identifier == "name" )
00509           addr.setName( (*lineIt).value().asString() );
00510 
00511         // NICKNAME
00512         else if ( identifier == "nickname" )
00513           addr.setNickName( (*lineIt).value().asString() );
00514 
00515         // NOTE
00516         else if ( identifier == "note" )
00517           addr.setNote( (*lineIt).value().asString() );
00518 
00519         // ORGANIZATION
00520         else if ( identifier == "org" ) {
00521           const TQStringList orgParts = splitString( semicolonSep, (*lineIt).value().asString() );
00522           if ( orgParts.count() > 0 )
00523             addr.setOrganization( orgParts[ 0 ] );
00524           if ( orgParts.count() > 1 )
00525             addr.setDepartment( orgParts[ 1 ] );
00526         }
00527 
00528         // PHOTO
00529         else if ( identifier == "photo" )
00530           addr.setPhoto( parsePicture( *lineIt ) );
00531 
00532         // PROID
00533         else if ( identifier == "prodid" )
00534           addr.setProductId( (*lineIt).value().asString() );
00535 
00536         // REV
00537         else if ( identifier == "rev" )
00538           addr.setRevision( parseDateTime( (*lineIt).value().asString() ) );
00539 
00540         // ROLE
00541         else if ( identifier == "role" )
00542           addr.setRole( (*lineIt).value().asString() );
00543 
00544         // SORT-STRING
00545         else if ( identifier == "sort-string" )
00546           addr.setSortString( (*lineIt).value().asString() );
00547 
00548         // SOUND
00549         else if ( identifier == "sound" )
00550           addr.setSound( parseSound( *lineIt ) );
00551 
00552         // TEL
00553         else if ( identifier == "tel" ) {
00554           PhoneNumber phone;
00555           phone.setNumber( (*lineIt).value().asString() );
00556 
00557           int type = 0;
00558 
00559           const TQStringList types = (*lineIt).parameters( "type" );
00560           for ( TQStringList::ConstIterator it = types.begin(); it != types.end(); ++it )
00561             type += mPhoneTypeMap[(*it).upper()];
00562 
00563           phone.setType( type );
00564 
00565           addr.insertPhoneNumber( phone );
00566         }
00567 
00568         // TITLE
00569         else if ( identifier == "title" )
00570           addr.setTitle( (*lineIt).value().asString() );
00571 
00572         // TZ
00573         else if ( identifier == "tz" ) {
00574           TimeZone tz;
00575           const TQString date = (*lineIt).value().asString();
00576 
00577           int hours = date.mid( 1, 2).toInt();
00578           int minutes = date.mid( 4, 2 ).toInt();
00579           int offset = ( hours * 60 ) + minutes;
00580           offset = offset * ( date[ 0 ] == '+' ? 1 : -1 );
00581 
00582           tz.setOffset( offset );
00583           addr.setTimeZone( tz );
00584         }
00585 
00586         // UID
00587         else if ( identifier == "uid" )
00588           addr.setUid( (*lineIt).value().asString() );
00589 
00590         // URI
00591         else if ( identifier == "uri" )
00592           addr.setUri( (*lineIt).value().asString() );
00593 
00594         // URL
00595         else if ( identifier == "url" )
00596           addr.setUrl( KURL( (*lineIt).value().asString() ) );
00597 
00598         // X-
00599         else if ( identifier.startsWith( "x-" ) ) {
00600           const TQString key = (*lineIt).identifier().mid( 2 );
00601           int dash = key.find( "-" );
00602           addr.insertCustom( key.left( dash ), key.mid( dash + 1 ), (*lineIt).value().asString() );
00603         }
00604       }
00605     }
00606 
00607     addrList.append( addr );
00608   }
00609 
00610   return addrList;
00611 }
00612 
00613 TQDateTime VCardTool::parseDateTime(const TQString &str)
00614 {
00615   TQDateTime dateTime;
00616   
00617   /* This regex matches one of the following formats (description taken from 
00618      https://www.w3.org/TR/NOTE-datetime, copyright remains of the respective documentation author(s))
00619      Year:            YYYY (eg 1997)
00620          Year and month:  YYYY-MM (eg 1997-07)
00621          Complete date:   YYYY-MM-DD (eg 1997-07-16)
00622          Complete date plus hours and minutes:             YYYY-MM-DDThh:mmTZD (eg 1997-07-16T19:20+01:00)
00623          Complete date plus hours, minutes and seconds:    YYYY-MM-DDThh:mm:ssTZD (eg 1997-07-16T19:20:30+01:00)
00624          Complete date plus hours, minutes, seconds and a decimal fraction of a second
00625                                             YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00)
00626          where:
00627          YYYY = four-digit year
00628          MM   = two-digit month (01=January, etc.)
00629          DD   = two-digit day of month (01 through 31)
00630          hh   = two digits of hour (00 through 23) (am/pm NOT allowed)
00631          mm   = two digits of minute (00 through 59)
00632          ss   = two digits of second (00 through 59)
00633          s    = one or more digits representing a decimal fraction of a second
00634          TZD  = time zone designator (Z or +hh:mm or -hh:mm)
00635   */
00636     TQRegExp re("(\\d{4})(?:-(\\d{2})(?:-(\\d{2})(?:T(\\d{2}):(\\d{2})(?::(\\d{2})(?:\\.(\\d+))?)?"
00637                 "(?:(Z)|([+-])(\\d{2}):(\\d{2})))?)?)?", true, false);
00638     if (!re.exactMatch(str))
00639     {
00640         // Try alternative format if pattern does not match
00641         /* This regex matches one of the following formats (description adapted from 
00642              https://www.w3.org/TR/NOTE-datetime, copyright remains of the respective documentation author(s))
00643              Year:            YYYY (eg 1997)
00644              Year and month:  YYYYMM (eg 199707)
00645              Complete date:   YYYYMMDD (eg 19970716)
00646              Complete date plus hours and minutes:             YYYYMMDDThhmmTZD (eg 19970716T1920+0100)
00647              Complete date plus hours, minutes and seconds:    YYYYMMDDThhmmssTZD (eg 19970716T192030+0100)
00648              Complete date plus hours, minutes, seconds and a decimal fraction of a second
00649                                                 YYYYMMDDThhmmsslTZD (eg 19970716T19203045+0100)
00650              where:
00651              YYYY = four-digit year
00652              MM   = two-digit month (01=January, etc.)
00653              DD   = two-digit day of month (01 through 31)
00654              hh   = two digits of hour (00 through 23) (am/pm NOT allowed)
00655              mm   = two digits of minute (00 through 59)
00656              ss   = two digits of second (00 through 59)
00657              l    = one or more digits representing a decimal fraction of a second
00658              TZD  = time zone designator (Z or +hhmm or -hhmm)
00659         */
00660         re.setPattern("(\\d{4})(?:(\\d{2})(?:(\\d{2})(?:T(\\d{2})(\\d{2})(?:(\\d{2})(?:(\\d+))?)?"
00661                 "(?:(Z)|([+-])(\\d{2})(\\d{2})))?)?)?");
00662     }
00663     if (re.exactMatch(str))
00664     {
00665         // Insert date
00666       dateTime.setDate(TQDate(re.cap(1).toInt(),                              // year
00667                               !re.cap(2).isEmpty() ? re.cap(2).toInt() : 1,   // month
00668                               !re.cap(3).isEmpty() ? re.cap(3).toInt() : 1)); // day
00669       if (!re.cap(4).isEmpty())
00670       {
00671         // Time was also specified
00672         int millis = 0;
00673         if (!re.cap(7).isEmpty())
00674         {
00675           millis += re.cap(7)[0].isDigit() ? re.cap(7)[0].digitValue() * 100 : 0;
00676           millis += re.cap(7)[1].isDigit() ? re.cap(7)[1].digitValue() * 10  : 0;
00677           millis += re.cap(7)[2].isDigit() ? re.cap(7)[2].digitValue()       : 0;
00678         }
00679         dateTime.setTime(TQTime(re.cap(4).toInt(),                            // hours
00680                                 re.cap(5).toInt(),                            // minutes
00681                                 !re.cap(6).isEmpty() ? re.cap(6).toInt() : 0, // seconds
00682                                 millis));                                     // milliseconds
00683             // Add time offset if time not in UTC format
00684             if (!re.cap(9).isEmpty())
00685             {
00686                 int offset = re.cap(10).toInt() * 3600 + re.cap(11).toInt() * 60;
00687                 if (re.cap(9) == "+")
00688                 { 
00689                   // Local time zone is ahead of UTC time
00690                     offset = -offset;
00691                 }
00692                 dateTime = dateTime.addSecs(offset);
00693             }
00694       }
00695     }
00696   return dateTime;
00697 }
00698 
00699 TQString VCardTool::createDateTime( const TQDateTime &dateTime )
00700 {
00701   TQString str;
00702 
00703   if ( dateTime.date().isValid() ) {
00704     str.sprintf( "%4d-%02d-%02d", dateTime.date().year(), dateTime.date().month(),
00705                  dateTime.date().day() );
00706     if ( dateTime.time().isValid() ) {
00707       TQString tmp;
00708       tmp.sprintf( "T%02d:%02d:%02dZ", dateTime.time().hour(), dateTime.time().minute(),
00709                    dateTime.time().second() );
00710       str += tmp;
00711     }
00712   }
00713 
00714   return str;
00715 }
00716 
00717 Picture VCardTool::parsePicture( const VCardLine &line )
00718 {
00719   Picture pic;
00720 
00721   const TQStringList params = line.parameterList();
00722   if ( params.findIndex( "encoding" ) != -1 ) {
00723     TQImage img;
00724     img.loadFromData( line.value().asByteArray() );
00725     pic.setData( img );
00726   } else if ( params.findIndex( "value" ) != -1 ) {
00727     if ( line.parameter( "value" ).lower() == "uri" )
00728       pic.setUrl( line.value().asString() );
00729   }
00730 
00731   if ( params.findIndex( "type" ) != -1 )
00732     pic.setType( line.parameter( "type" ) );
00733 
00734   return pic;
00735 }
00736 
00737 VCardLine VCardTool::createPicture( const TQString &identifier, const Picture &pic )
00738 {
00739   VCardLine line( identifier );
00740 
00741   if ( pic.isIntern() ) {
00742     if ( !pic.data().isNull() ) {
00743       TQByteArray input;
00744       TQBuffer buffer( input );
00745       buffer.open( IO_WriteOnly );
00746 
00747       TQImageIO iio( &buffer, "JPEG" );
00748       iio.setImage( pic.data() );
00749       iio.setQuality( 100 );
00750       iio.write();
00751 
00752       line.setValue( input );
00753       line.addParameter( "encoding", "b" );
00754       line.addParameter( "type", "image/jpeg" );
00755     }
00756   } else if ( !pic.url().isEmpty() ) {
00757     line.setValue( pic.url() );
00758     line.addParameter( "value", "URI" );
00759   }
00760 
00761   return line;
00762 }
00763 
00764 Sound VCardTool::parseSound( const VCardLine &line )
00765 {
00766   Sound snd;
00767 
00768   const TQStringList params = line.parameterList();
00769   if ( params.findIndex( "encoding" ) != -1 )
00770     snd.setData( line.value().asByteArray() );
00771   else if ( params.findIndex( "value" ) != -1 ) {
00772     if ( line.parameter( "value" ).lower() == "uri" )
00773       snd.setUrl( line.value().asString() );
00774   }
00775 
00776 /* TODO: support sound types
00777   if ( params.contains( "type" ) )
00778     snd.setType( line.parameter( "type" ) );
00779 */
00780 
00781   return snd;
00782 }
00783 
00784 VCardLine VCardTool::createSound( const Sound &snd )
00785 {
00786   VCardLine line( "SOUND" );
00787 
00788   if ( snd.isIntern() ) {
00789     if ( !snd.data().isEmpty() ) {
00790       line.setValue( snd.data() );
00791       line.addParameter( "encoding", "b" );
00792       // TODO: need to store sound type!!!
00793     }
00794   } else if ( !snd.url().isEmpty() ) {
00795     line.setValue( snd.url() );
00796     line.addParameter( "value", "URI" );
00797   }
00798 
00799   return line;
00800 }
00801 
00802 Key VCardTool::parseKey( const VCardLine &line )
00803 {
00804   Key key;
00805 
00806   const TQStringList params = line.parameterList();
00807   if ( params.findIndex( "encoding" ) != -1 )
00808     key.setBinaryData( line.value().asByteArray() );
00809   else
00810     key.setTextData( line.value().asString() );
00811 
00812   if ( params.findIndex( "type" ) != -1 ) {
00813     if ( line.parameter( "type" ).lower() == "x509" )
00814       key.setType( Key::X509 );
00815     else if ( line.parameter( "type" ).lower() == "pgp" )
00816       key.setType( Key::PGP );
00817     else {
00818       key.setType( Key::Custom );
00819       key.setCustomTypeString( line.parameter( "type" ) );
00820     }
00821   }
00822 
00823   return key;
00824 }
00825 
00826 VCardLine VCardTool::createKey( const Key &key )
00827 {
00828   VCardLine line( "KEY" );
00829 
00830   if ( key.isBinary() ) {
00831     if ( !key.binaryData().isEmpty() ) {
00832       line.setValue( key.binaryData() );
00833       line.addParameter( "encoding", "b" );
00834     }
00835   } else if ( !key.textData().isEmpty() )
00836     line.setValue( key.textData() );
00837 
00838   if ( key.type() == Key::X509 )
00839     line.addParameter( "type", "X509" );
00840   else if ( key.type() == Key::PGP )
00841     line.addParameter( "type", "PGP" );
00842   else if ( key.type() == Key::Custom )
00843     line.addParameter( "type", key.customTypeString() );
00844 
00845   return line;
00846 }
00847 
00848 Secrecy VCardTool::parseSecrecy( const VCardLine &line )
00849 {
00850   Secrecy secrecy;
00851 
00852   if ( line.value().asString().lower() == "public" )
00853     secrecy.setType( Secrecy::Public );
00854   if ( line.value().asString().lower() == "private" )
00855     secrecy.setType( Secrecy::Private );
00856   if ( line.value().asString().lower() == "confidential" )
00857     secrecy.setType( Secrecy::Confidential );
00858 
00859   return secrecy;
00860 }
00861 
00862 VCardLine VCardTool::createSecrecy( const Secrecy &secrecy )
00863 {
00864   VCardLine line( "CLASS" );
00865 
00866   int type = secrecy.type();
00867 
00868   if ( type == Secrecy::Public )
00869     line.setValue( "PUBLIC" );
00870   else if ( type == Secrecy::Private )
00871     line.setValue( "PRIVATE" );
00872   else if ( type == Secrecy::Confidential )
00873     line.setValue( "CONFIDENTIAL" );
00874 
00875   return line;
00876 }
00877 
00878 Agent VCardTool::parseAgent( const VCardLine &line )
00879 {
00880   Agent agent;
00881 
00882   const TQStringList params = line.parameterList();
00883   if ( params.findIndex( "value" ) != -1 ) {
00884     if ( line.parameter( "value" ).lower() == "uri" )
00885       agent.setUrl( line.value().asString() );
00886   } else {
00887     TQString str = line.value().asString();
00888     str.replace( "\\n", "\r\n" );
00889     str.replace( "\\N", "\r\n" );
00890     str.replace( "\\;", ";" );
00891     str.replace( "\\:", ":" );
00892     str.replace( "\\,", "," );
00893 
00894     const Addressee::List list = parseVCards( str );
00895     if ( list.count() > 0 ) {
00896       Addressee *addr = new Addressee;
00897       *addr = list[ 0 ];
00898       agent.setAddressee( addr );
00899     }
00900   }
00901 
00902   return agent;
00903 }
00904 
00905 VCardLine VCardTool::createAgent( VCard::Version version, const Agent &agent )
00906 {
00907   VCardLine line( "AGENT" );
00908 
00909   if ( agent.isIntern() ) {
00910     if ( agent.addressee() != 0 ) {
00911       Addressee::List list;
00912       list.append( *agent.addressee() );
00913 
00914       TQString str = createVCards( list, version );
00915       str.replace( "\r\n", "\\n" );
00916       str.replace( ";", "\\;" );
00917       str.replace( ":", "\\:" );
00918       str.replace( ",", "\\," );
00919       line.setValue( str );
00920     }
00921   } else if ( !agent.url().isEmpty() ) {
00922     line.setValue( agent.url() );
00923     line.addParameter( "value", "URI" );
00924   }
00925 
00926   return line;
00927 }
00928 
00929 TQStringList VCardTool::splitString( const TQChar &sep, const TQString &str )
00930 {
00931   TQStringList list;
00932   TQString value( str );
00933 
00934   int start = 0;
00935   int pos = value.find( sep, start );
00936 
00937   while ( pos != -1 ) {
00938     if ( value[ pos - 1 ] != '\\' ) {
00939       if ( pos > start && pos <= (int)value.length() )
00940         list << value.mid( start, pos - start );
00941       else
00942         list << TQString::null;
00943 
00944       start = pos + 1;
00945       pos = value.find( sep, start );
00946     } else {
00947       if ( pos != 0 ) {
00948         value.replace( pos - 1, 2, sep );
00949         pos = value.find( sep, pos );
00950       } else
00951         pos = value.find( sep, pos + 1 );
00952     }
00953   }
00954 
00955   int l = value.length() - 1;
00956   if ( value.mid( start, l - start + 1 ).length() > 0 )
00957     list << value.mid( start, l - start + 1 );
00958   else
00959     list << TQString::null;
00960 
00961   return list;
00962 }

tdeabc

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

tdeabc

Skip menu "tdeabc"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdeabc by doxygen 1.6.3
This website is maintained by Timothy Pearson.