00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
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
00139 card.addLine( createAgent( version, (*addrIt).agent() ) );
00140
00141
00142 card.addLine( VCardLine( "BDAY", createDateTime( TQT_TQDATETIME_OBJECT((*addrIt).birthday()) ) ) );
00143
00144
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
00161 if ( version == VCard::v3_0 ) {
00162 card.addLine( createSecrecy( (*addrIt).secrecy() ) );
00163 }
00164
00165
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
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
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
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
00200 card.addLine( createPicture( "LOGO", (*addrIt).logo() ) );
00201
00202
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
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
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
00234 if ( version == VCard::v3_0 )
00235 card.addLine( VCardLine( "NICKNAME", TQString((*addrIt).nickName()) ) );
00236
00237
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
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
00258 card.addLine( createPicture( "PHOTO", (*addrIt).photo() ) );
00259
00260
00261 if ( version == VCard::v3_0 )
00262 card.addLine( VCardLine( "PRODID", TQString((*addrIt).productId()) ) );
00263
00264
00265 card.addLine( VCardLine( "REV", createDateTime( TQT_TQDATETIME_OBJECT((*addrIt).revision()) ) ) );
00266
00267
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
00276 if ( version == VCard::v3_0 )
00277 card.addLine( VCardLine( "SORT-STRING", TQString((*addrIt).sortString()) ) );
00278
00279
00280 card.addLine( createSound( (*addrIt).sound() ) );
00281
00282
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
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
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
00322 card.addLine( VCardLine( "UID", (*addrIt).uid() ) );
00323
00324
00325 card.addLine( VCardLine( "URI", (*addrIt).uri() ) );
00326
00327
00328 card.addLine( VCardLine( "URL", (*addrIt).url().url() ) );
00329
00330
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
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
00380 for ( lineIt = lines.begin(); lineIt != lines.end(); ++lineIt ) {
00381 identifier = (*lineIt).identifier().lower();
00382
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
00412 else if ( identifier == "agent" )
00413 addr.setAgent( parseAgent( *lineIt ) );
00414
00415
00416 else if ( identifier == "bday" ) {
00417 TQString s((*lineIt).value().asString());
00418 if ( s.length() > 0 )
00419 addr.setBirthday( parseDateTime( s ) );
00420 }
00421
00422
00423 else if ( identifier == "categories" ) {
00424 const TQStringList categories = splitString( commaSep, (*lineIt).value().asString() );
00425 addr.setCategories( categories );
00426 }
00427
00428
00429 else if ( identifier == "class" )
00430 addr.setSecrecy( parseSecrecy( *lineIt ) );
00431
00432
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
00439 else if ( identifier == "fn" )
00440 addr.setFormattedName( (*lineIt).value().asString() );
00441
00442
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
00454 else if ( identifier == "key" )
00455 addr.insertKey( parseKey( *lineIt ) );
00456
00457
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 ) {
00478 TDEABC::Address address( type );
00479 address.setLabel( (*lineIt).value().asString() );
00480 addr.insertAddress( address );
00481 }
00482 }
00483
00484
00485 else if ( identifier == "logo" )
00486 addr.setLogo( parsePicture( *lineIt ) );
00487
00488
00489 else if ( identifier == "mailer" )
00490 addr.setMailer( (*lineIt).value().asString() );
00491
00492
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
00508 else if ( identifier == "name" )
00509 addr.setName( (*lineIt).value().asString() );
00510
00511
00512 else if ( identifier == "nickname" )
00513 addr.setNickName( (*lineIt).value().asString() );
00514
00515
00516 else if ( identifier == "note" )
00517 addr.setNote( (*lineIt).value().asString() );
00518
00519
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
00529 else if ( identifier == "photo" )
00530 addr.setPhoto( parsePicture( *lineIt ) );
00531
00532
00533 else if ( identifier == "prodid" )
00534 addr.setProductId( (*lineIt).value().asString() );
00535
00536
00537 else if ( identifier == "rev" )
00538 addr.setRevision( parseDateTime( (*lineIt).value().asString() ) );
00539
00540
00541 else if ( identifier == "role" )
00542 addr.setRole( (*lineIt).value().asString() );
00543
00544
00545 else if ( identifier == "sort-string" )
00546 addr.setSortString( (*lineIt).value().asString() );
00547
00548
00549 else if ( identifier == "sound" )
00550 addr.setSound( parseSound( *lineIt ) );
00551
00552
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
00569 else if ( identifier == "title" )
00570 addr.setTitle( (*lineIt).value().asString() );
00571
00572
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
00587 else if ( identifier == "uid" )
00588 addr.setUid( (*lineIt).value().asString() );
00589
00590
00591 else if ( identifier == "uri" )
00592 addr.setUri( (*lineIt).value().asString() );
00593
00594
00595 else if ( identifier == "url" )
00596 addr.setUrl( KURL( (*lineIt).value().asString() ) );
00597
00598
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
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
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
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
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
00666 dateTime.setDate(TQDate(re.cap(1).toInt(),
00667 !re.cap(2).isEmpty() ? re.cap(2).toInt() : 1,
00668 !re.cap(3).isEmpty() ? re.cap(3).toInt() : 1));
00669 if (!re.cap(4).isEmpty())
00670 {
00671
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(),
00680 re.cap(5).toInt(),
00681 !re.cap(6).isEmpty() ? re.cap(6).toInt() : 0,
00682 millis));
00683
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
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
00777
00778
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
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 }