kabc Library API Documentation

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