00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <qfile.h>
00021 #include <qregexp.h>
00022
00023 #include <kdebug.h>
00024 #include <kmdcodec.h>
00025 #include <kstandarddirs.h>
00026 #include <ktempfile.h>
00027
00028 #include <VCard.h>
00029
00030 #include "addressbook.h"
00031 #include "vcardformatimpl.h"
00032
00033 using namespace KABC;
00034 using namespace VCARD;
00035
00036 bool VCardFormatImpl::load( Addressee &addressee, QFile *file )
00037 {
00038 kdDebug(5700) << "VCardFormat::load()" << endl;
00039
00040 QByteArray fdata = file->readAll();
00041 QCString data(fdata.data(), fdata.size()+1);
00042
00043 VCardEntity e( data );
00044
00045 VCardListIterator it( e.cardList() );
00046
00047 if ( it.current() ) {
00048 VCARD::VCard v(*it.current());
00049 loadAddressee( addressee, v );
00050 return true;
00051 }
00052
00053 return false;
00054 }
00055
00056 bool VCardFormatImpl::loadAll( AddressBook *addressBook, Resource *resource, QFile *file )
00057 {
00058 kdDebug(5700) << "VCardFormat::loadAll()" << endl;
00059
00060 QByteArray fdata = file->readAll();
00061 QCString data(fdata.data(), fdata.size()+1);
00062
00063 VCardEntity e( data );
00064
00065 VCardListIterator it( e.cardList() );
00066
00067 for (; it.current(); ++it) {
00068 VCARD::VCard v(*it.current());
00069 Addressee addressee;
00070 loadAddressee( addressee, v );
00071 addressee.setResource( resource );
00072 addressBook->insertAddressee( addressee );
00073 }
00074
00075 return true;
00076 }
00077
00078 void VCardFormatImpl::save( const Addressee &addressee, QFile *file )
00079 {
00080 VCardEntity vcards;
00081 VCardList vcardlist;
00082 vcardlist.setAutoDelete( true );
00083
00084 VCARD::VCard *v = new VCARD::VCard;
00085
00086 saveAddressee( addressee, v, false );
00087
00088 vcardlist.append( v );
00089 vcards.setCardList( vcardlist );
00090
00091 QCString vcardData = vcards.asString();
00092 file->writeBlock( (const char*)vcardData, vcardData.length() );
00093 }
00094
00095 void VCardFormatImpl::saveAll( AddressBook *ab, Resource *resource, QFile *file )
00096 {
00097 VCardEntity vcards;
00098 VCardList vcardlist;
00099 vcardlist.setAutoDelete( true );
00100
00101 AddressBook::Iterator it;
00102 for ( it = ab->begin(); it != ab->end(); ++it ) {
00103 if ( (*it).resource() == resource ) {
00104 VCARD::VCard *v = new VCARD::VCard;
00105 saveAddressee( (*it), v, false );
00106 (*it).setChanged( false );
00107 vcardlist.append( v );
00108 }
00109 }
00110
00111 vcards.setCardList( vcardlist );
00112
00113 QCString vcardData = vcards.asString();
00114 file->writeBlock( (const char*)vcardData, vcardData.length() );
00115 }
00116
00117 bool VCardFormatImpl::loadAddressee( Addressee& addressee, VCARD::VCard &v )
00118 {
00119 QPtrList<ContentLine> contentLines = v.contentLineList();
00120 ContentLine *cl;
00121
00122 for( cl = contentLines.first(); cl; cl = contentLines.next() ) {
00123 QCString n = cl->name();
00124 if ( n.left( 2 ) == "X-" ) {
00125 n = n.mid( 2 );
00126 int posDash = n.find( "-" );
00127 addressee.insertCustom( QString::fromUtf8( n.left( posDash ) ),
00128 QString::fromUtf8( n.mid( posDash + 1 ) ),
00129 QString::fromUtf8( cl->value()->asString() ) );
00130 continue;
00131 }
00132
00133 EntityType type = cl->entityType();
00134 switch( type ) {
00135
00136 case EntityUID:
00137 addressee.setUid( readTextValue( cl ) );
00138 break;
00139
00140 case EntityEmail:
00141 addressee.insertEmail( readTextValue( cl ) );
00142 break;
00143
00144 case EntityName:
00145 addressee.setName( readTextValue( cl ) );
00146 break;
00147
00148 case EntityFullName:
00149 addressee.setFormattedName( readTextValue( cl ) );
00150 break;
00151
00152 case EntityURL:
00153 addressee.setUrl( KURL( readTextValue( cl ) ) );
00154 break;
00155
00156 case EntityNickname:
00157 addressee.setNickName( readTextValue( cl ) );
00158 break;
00159
00160 case EntityLabel:
00161
00162 break;
00163
00164 case EntityMailer:
00165 addressee.setMailer( readTextValue( cl ) );
00166 break;
00167
00168 case EntityTitle:
00169 addressee.setTitle( readTextValue( cl ) );
00170 break;
00171
00172 case EntityRole:
00173 addressee.setRole( readTextValue( cl ) );
00174 break;
00175
00176 case EntityOrganisation:
00177 addressee.setOrganization( readTextValue( cl ) );
00178 break;
00179
00180 case EntityNote:
00181 addressee.setNote( readTextValue( cl ) );
00182 break;
00183
00184 case EntityProductID:
00185 addressee.setProductId( readTextValue( cl ) );
00186 break;
00187
00188 case EntitySortString:
00189 addressee.setSortString( readTextValue( cl ) );
00190 break;
00191
00192 case EntityN:
00193 readNValue( cl, addressee );
00194 break;
00195
00196 case EntityAddress:
00197 addressee.insertAddress( readAddressValue( cl ) );
00198 break;
00199
00200 case EntityTelephone:
00201 addressee.insertPhoneNumber( readTelephoneValue( cl ) );
00202 break;
00203
00204 case EntityCategories:
00205 addressee.setCategories( QStringList::split( ",", readTextValue( cl ) ) );
00206 break;
00207
00208 case EntityBirthday:
00209 addressee.setBirthday( readDateValue( cl ) );
00210 break;
00211
00212 case EntityRevision:
00213 addressee.setRevision( readDateTimeValue( cl ) );
00214 break;
00215
00216 case EntityGeo:
00217 addressee.setGeo( readGeoValue( cl ) );
00218 break;
00219
00220 case EntityTimeZone:
00221 addressee.setTimeZone( readUTCValue( cl ) );
00222 break;
00223
00224 case EntityVersion:
00225 break;
00226
00227 case EntityClass:
00228 addressee.setSecrecy( readClassValue( cl ) );
00229 break;
00230
00231 case EntityKey:
00232 addressee.insertKey( readKeyValue( cl ) );
00233 break;
00234
00235 case EntityPhoto:
00236 addressee.setPhoto( readPictureValue( cl, EntityPhoto, addressee ) );
00237 break;
00238
00239 case EntityLogo:
00240 addressee.setLogo( readPictureValue( cl, EntityLogo, addressee ) );
00241 break;
00242
00243 case EntityAgent:
00244 addressee.setAgent( readAgentValue( cl ) );
00245 break;
00246
00247 case EntitySound:
00248 addressee.setSound( readSoundValue( cl, addressee ) );
00249 break;
00250
00251 default:
00252 kdDebug(5700) << "VCardFormat::load(): Unsupported entity: "
00253 << int( type ) << ": " << cl->asString() << endl;
00254 break;
00255 }
00256 }
00257
00258 for( cl = contentLines.first(); cl; cl = contentLines.next() ) {
00259 EntityType type = cl->entityType();
00260 if ( type == EntityLabel ) {
00261 int type = readAddressParam( cl );
00262 Address address = addressee.address( type );
00263 if ( address.isEmpty() )
00264 address.setType( type );
00265
00266 address.setLabel( QString::fromUtf8( cl->value()->asString() ) );
00267 addressee.insertAddress( address );
00268 }
00269 }
00270
00271 return true;
00272 }
00273
00274 void VCardFormatImpl::saveAddressee( const Addressee &addressee, VCARD::VCard *v, bool intern )
00275 {
00276 ContentLine cl;
00277 QString value;
00278
00279 addTextValue( v, EntityName, addressee.name() );
00280 addTextValue( v, EntityUID, addressee.uid() );
00281 addTextValue( v, EntityFullName, addressee.formattedName() );
00282
00283 QStringList emails = addressee.emails();
00284 QStringList::ConstIterator it4;
00285 for( it4 = emails.begin(); it4 != emails.end(); ++it4 ) {
00286 addTextValue( v, EntityEmail, *it4 );
00287 }
00288
00289 QStringList customs = addressee.customs();
00290 QStringList::ConstIterator it5;
00291 for( it5 = customs.begin(); it5 != customs.end(); ++it5 ) {
00292 addCustomValue( v, *it5 );
00293 }
00294
00295 addTextValue( v, EntityURL, addressee.url().url() );
00296
00297 addNValue( v, addressee );
00298
00299 addTextValue( v, EntityNickname, addressee.nickName() );
00300 addTextValue( v, EntityMailer, addressee.mailer() );
00301 addTextValue( v, EntityTitle, addressee.title() );
00302 addTextValue( v, EntityRole, addressee.role() );
00303 addTextValue( v, EntityOrganisation, addressee.organization() );
00304 addTextValue( v, EntityNote, addressee.note() );
00305 addTextValue( v, EntityProductID, addressee.productId() );
00306 addTextValue( v, EntitySortString, addressee.sortString() );
00307
00308 Address::List addresses = addressee.addresses();
00309 Address::List::ConstIterator it3;
00310 for( it3 = addresses.begin(); it3 != addresses.end(); ++it3 ) {
00311 addAddressValue( v, *it3 );
00312 addLabelValue( v, *it3 );
00313 }
00314
00315 PhoneNumber::List phoneNumbers = addressee.phoneNumbers();
00316 PhoneNumber::List::ConstIterator it2;
00317 for( it2 = phoneNumbers.begin(); it2 != phoneNumbers.end(); ++it2 ) {
00318 addTelephoneValue( v, *it2 );
00319 }
00320
00321 Key::List keys = addressee.keys();
00322 Key::List::ConstIterator it6;
00323 for( it6 = keys.begin(); it6 != keys.end(); ++it6 ) {
00324 addKeyValue( v, *it6 );
00325 }
00326
00327 addTextValue( v, EntityCategories, addressee.categories().join(",") );
00328
00329 addDateValue( v, EntityBirthday, addressee.birthday().date() );
00330 addDateTimeValue( v, EntityRevision, addressee.revision() );
00331 addGeoValue( v, addressee.geo() );
00332 addUTCValue( v, addressee.timeZone() );
00333
00334 addClassValue( v, addressee.secrecy() );
00335
00336 addPictureValue( v, EntityPhoto, addressee.photo(), addressee, intern );
00337 addPictureValue( v, EntityLogo, addressee.logo(), addressee, intern );
00338
00339 addAgentValue( v, addressee.agent() );
00340
00341 addSoundValue( v, addressee.sound(), addressee, intern );
00342 }
00343
00344 void VCardFormatImpl::addCustomValue( VCARD::VCard *v, const QString &txt )
00345 {
00346 if ( txt.isEmpty() ) return;
00347
00348 ContentLine cl;
00349 cl.setName( "X-" + txt.left( txt.find( ":" ) ).utf8() );
00350 QString value = txt.mid( txt.find( ":" ) + 1 );
00351 if ( value.isEmpty() )
00352 return;
00353 cl.setValue( new TextValue( value.utf8() ) );
00354 v->add(cl);
00355 }
00356
00357 void VCardFormatImpl::addTextValue( VCARD::VCard *v, EntityType type, const QString &txt )
00358 {
00359 if ( txt.isEmpty() ) return;
00360
00361 ContentLine cl;
00362 cl.setName( EntityTypeToParamName( type ) );
00363 cl.setValue( new TextValue( txt.utf8() ) );
00364 v->add(cl);
00365 }
00366
00367 void VCardFormatImpl::addDateValue( VCARD::VCard *vcard, EntityType type,
00368 const QDate &date )
00369 {
00370 if ( !date.isValid() ) return;
00371
00372 ContentLine cl;
00373 cl.setName( EntityTypeToParamName( type ) );
00374
00375 DateValue *v = new DateValue( date );
00376 cl.setValue( v );
00377 vcard->add(cl);
00378 }
00379
00380 void VCardFormatImpl::addDateTimeValue( VCARD::VCard *vcard, EntityType type,
00381 const QDateTime &dateTime )
00382 {
00383 if ( !dateTime.isValid() ) return;
00384
00385 ContentLine cl;
00386 cl.setName( EntityTypeToParamName( type ) );
00387
00388 DateValue *v = new DateValue( dateTime );
00389 cl.setValue( v );
00390 vcard->add(cl);
00391 }
00392
00393 void VCardFormatImpl::addAddressValue( VCARD::VCard *vcard, const Address &a )
00394 {
00395 if ( a.isEmpty() )
00396 return;
00397
00398 ContentLine cl;
00399 cl.setName( EntityTypeToParamName( EntityAddress ) );
00400
00401 AdrValue *v = new AdrValue;
00402 v->setPOBox( a.postOfficeBox().utf8() );
00403 v->setExtAddress( a.extended().utf8() );
00404 v->setStreet( a.street().utf8() );
00405 v->setLocality( a.locality().utf8() );
00406 v->setRegion( a.region().utf8() );
00407 v->setPostCode( a.postalCode().utf8() );
00408 v->setCountryName( a.country().utf8() );
00409 cl.setValue( v );
00410
00411 addAddressParam( &cl, a.type() );
00412
00413 vcard->add( cl );
00414 }
00415
00416 void VCardFormatImpl::addLabelValue( VCARD::VCard *vcard, const Address &a )
00417 {
00418 if ( a.label().isEmpty() ) return;
00419
00420 ContentLine cl;
00421 cl.setName( EntityTypeToParamName( EntityLabel ) );
00422 cl.setValue( new TextValue( a.label().utf8() ) );
00423
00424 addAddressParam( &cl, a.type() );
00425
00426 vcard->add( cl );
00427 }
00428
00429 void VCardFormatImpl::addAddressParam( ContentLine *cl, int type )
00430 {
00431 ParamList params;
00432 if ( type & Address::Dom ) params.append( new Param( "TYPE", "dom" ) );
00433 if ( type & Address::Intl ) params.append( new Param( "TYPE", "intl" ) );
00434 if ( type & Address::Parcel ) params.append( new Param( "TYPE", "parcel" ) );
00435 if ( type & Address::Postal ) params.append( new Param( "TYPE", "postal" ) );
00436 if ( type & Address::Work ) params.append( new Param( "TYPE", "work" ) );
00437 if ( type & Address::Home ) params.append( new Param( "TYPE", "home" ) );
00438 if ( type & Address::Pref ) params.append( new Param( "TYPE", "pref" ) );
00439 cl->setParamList( params );
00440 }
00441
00442 void VCardFormatImpl::addGeoValue( VCARD::VCard *vcard, const Geo &geo )
00443 {
00444 if ( !geo.isValid() ) return;
00445
00446 ContentLine cl;
00447 cl.setName( EntityTypeToParamName( EntityGeo ) );
00448
00449 GeoValue *v = new GeoValue;
00450 v->setLatitude( geo.latitude() );
00451 v->setLongitude( geo.longitude() );
00452
00453 cl.setValue( v );
00454 vcard->add(cl);
00455 }
00456
00457 void VCardFormatImpl::addUTCValue( VCARD::VCard *vcard, const TimeZone &tz )
00458 {
00459 if ( !tz.isValid() ) return;
00460
00461 ContentLine cl;
00462 cl.setName( EntityTypeToParamName( EntityTimeZone ) );
00463
00464 UTCValue *v = new UTCValue;
00465
00466 v->setPositive( tz.offset() >= 0 );
00467 v->setHour( (tz.offset() / 60) * ( tz.offset() >= 0 ? 1 : -1 ) );
00468 v->setMinute( (tz.offset() % 60) * ( tz.offset() >= 0 ? 1 : -1 ) );
00469
00470 cl.setValue( v );
00471 vcard->add(cl);
00472 }
00473
00474 void VCardFormatImpl::addClassValue( VCARD::VCard *vcard, const Secrecy &secrecy )
00475 {
00476 ContentLine cl;
00477 cl.setName( EntityTypeToParamName( EntityClass ) );
00478
00479 ClassValue *v = new ClassValue;
00480 switch ( secrecy.type() ) {
00481 case Secrecy::Public:
00482 v->setType( (int)ClassValue::Public );
00483 break;
00484 case Secrecy::Private:
00485 v->setType( (int)ClassValue::Private );
00486 break;
00487 case Secrecy::Confidential:
00488 v->setType( (int)ClassValue::Confidential );
00489 break;
00490 }
00491
00492 cl.setValue( v );
00493 vcard->add(cl);
00494 }
00495
00496
00497 Address VCardFormatImpl::readAddressValue( ContentLine *cl )
00498 {
00499 Address a;
00500 AdrValue *v = (AdrValue *)cl->value();
00501 a.setPostOfficeBox( QString::fromUtf8( v->poBox() ) );
00502 a.setExtended( QString::fromUtf8( v->extAddress() ) );
00503 a.setStreet( QString::fromUtf8( v->street() ) );
00504 a.setLocality( QString::fromUtf8( v->locality() ) );
00505 a.setRegion( QString::fromUtf8( v->region() ) );
00506 a.setPostalCode( QString::fromUtf8( v->postCode() ) );
00507 a.setCountry( QString::fromUtf8( v->countryName() ) );
00508
00509 a.setType( readAddressParam( cl ) );
00510
00511 return a;
00512 }
00513
00514 int VCardFormatImpl::readAddressParam( ContentLine *cl )
00515 {
00516 int type = 0;
00517 ParamList params = cl->paramList();
00518 ParamListIterator it( params );
00519 for( ; it.current(); ++it ) {
00520 if ( (*it)->name() == "TYPE" ) {
00521 if ( (*it)->value() == "dom" ) type |= Address::Dom;
00522 else if ( (*it)->value() == "intl" ) type |= Address::Intl;
00523 else if ( (*it)->value() == "parcel" ) type |= Address::Parcel;
00524 else if ( (*it)->value() == "postal" ) type |= Address::Postal;
00525 else if ( (*it)->value() == "work" ) type |= Address::Work;
00526 else if ( (*it)->value() == "home" ) type |= Address::Home;
00527 else if ( (*it)->value() == "pref" ) type |= Address::Pref;
00528 }
00529 }
00530 return type;
00531 }
00532
00533 void VCardFormatImpl::addNValue( VCARD::VCard *vcard, const Addressee &a )
00534 {
00535 ContentLine cl;
00536 cl.setName(EntityTypeToParamName( EntityN ) );
00537 NValue *v = new NValue;
00538 v->setFamily( a.familyName().utf8() );
00539 v->setGiven( a.givenName().utf8() );
00540 v->setMiddle( a.additionalName().utf8() );
00541 v->setPrefix( a.prefix().utf8() );
00542 v->setSuffix( a.suffix().utf8() );
00543
00544 cl.setValue( v );
00545 vcard->add(cl);
00546 }
00547
00548 void VCardFormatImpl::readNValue( ContentLine *cl, Addressee &a )
00549 {
00550 NValue *v = (NValue *)cl->value();
00551 a.setFamilyName( QString::fromUtf8( v->family() ) );
00552 a.setGivenName( QString::fromUtf8( v->given() ) );
00553 a.setAdditionalName( QString::fromUtf8( v->middle() ) );
00554 a.setPrefix( QString::fromUtf8( v->prefix() ) );
00555 a.setSuffix( QString::fromUtf8( v->suffix() ) );
00556 }
00557
00558 void VCardFormatImpl::addTelephoneValue( VCARD::VCard *v, const PhoneNumber &p )
00559 {
00560 if ( p.number().isEmpty() )
00561 return;
00562
00563 ContentLine cl;
00564 cl.setName(EntityTypeToParamName(EntityTelephone));
00565 cl.setValue(new TelValue( p.number().utf8() ));
00566
00567 ParamList params;
00568 if( p.type() & PhoneNumber::Home ) params.append( new Param( "TYPE", "home" ) );
00569 if( p.type() & PhoneNumber::Work ) params.append( new Param( "TYPE", "work" ) );
00570 if( p.type() & PhoneNumber::Msg ) params.append( new Param( "TYPE", "msg" ) );
00571 if( p.type() & PhoneNumber::Pref ) params.append( new Param( "TYPE", "pref" ) );
00572 if( p.type() & PhoneNumber::Voice ) params.append( new Param( "TYPE", "voice" ) );
00573 if( p.type() & PhoneNumber::Fax ) params.append( new Param( "TYPE", "fax" ) );
00574 if( p.type() & PhoneNumber::Cell ) params.append( new Param( "TYPE", "cell" ) );
00575 if( p.type() & PhoneNumber::Video ) params.append( new Param( "TYPE", "video" ) );
00576 if( p.type() & PhoneNumber::Bbs ) params.append( new Param( "TYPE", "bbs" ) );
00577 if( p.type() & PhoneNumber::Modem ) params.append( new Param( "TYPE", "modem" ) );
00578 if( p.type() & PhoneNumber::Car ) params.append( new Param( "TYPE", "car" ) );
00579 if( p.type() & PhoneNumber::Isdn ) params.append( new Param( "TYPE", "isdn" ) );
00580 if( p.type() & PhoneNumber::Pcs ) params.append( new Param( "TYPE", "pcs" ) );
00581 if( p.type() & PhoneNumber::Pager ) params.append( new Param( "TYPE", "pager" ) );
00582 cl.setParamList( params );
00583
00584 v->add(cl);
00585 }
00586
00587 PhoneNumber VCardFormatImpl::readTelephoneValue( ContentLine *cl )
00588 {
00589 PhoneNumber p;
00590 TelValue *value = (TelValue *)cl->value();
00591 p.setNumber( QString::fromUtf8( value->asString() ) );
00592
00593 int type = 0;
00594 ParamList params = cl->paramList();
00595 ParamListIterator it( params );
00596 for( ; it.current(); ++it ) {
00597 if ( (*it)->name() == "TYPE" ) {
00598 if ( (*it)->value() == "home" ) type |= PhoneNumber::Home;
00599 else if ( (*it)->value() == "work" ) type |= PhoneNumber::Work;
00600 else if ( (*it)->value() == "msg" ) type |= PhoneNumber::Msg;
00601 else if ( (*it)->value() == "pref" ) type |= PhoneNumber::Pref;
00602 else if ( (*it)->value() == "voice" ) type |= PhoneNumber::Voice;
00603 else if ( (*it)->value() == "fax" ) type |= PhoneNumber::Fax;
00604 else if ( (*it)->value() == "cell" ) type |= PhoneNumber::Cell;
00605 else if ( (*it)->value() == "video" ) type |= PhoneNumber::Video;
00606 else if ( (*it)->value() == "bbs" ) type |= PhoneNumber::Bbs;
00607 else if ( (*it)->value() == "modem" ) type |= PhoneNumber::Modem;
00608 else if ( (*it)->value() == "car" ) type |= PhoneNumber::Car;
00609 else if ( (*it)->value() == "isdn" ) type |= PhoneNumber::Isdn;
00610 else if ( (*it)->value() == "pcs" ) type |= PhoneNumber::Pcs;
00611 else if ( (*it)->value() == "pager" ) type |= PhoneNumber::Pager;
00612 }
00613 }
00614 p.setType( type );
00615
00616 return p;
00617 }
00618
00619 QString VCardFormatImpl::readTextValue( ContentLine *cl )
00620 {
00621 VCARD::Value *value = cl->value();
00622 if ( value ) {
00623 return QString::fromUtf8( value->asString() );
00624 } else {
00625 kdDebug(5700) << "No value: " << cl->asString() << endl;
00626 return QString::null;
00627 }
00628 }
00629
00630 QDate VCardFormatImpl::readDateValue( ContentLine *cl )
00631 {
00632 DateValue *dateValue = (DateValue *)cl->value();
00633 if ( dateValue )
00634 return dateValue->qdate();
00635 else
00636 return QDate();
00637 }
00638
00639 QDateTime VCardFormatImpl::readDateTimeValue( ContentLine *cl )
00640 {
00641 DateValue *dateValue = (DateValue *)cl->value();
00642 if ( dateValue )
00643 return dateValue->qdt();
00644 else
00645 return QDateTime();
00646 }
00647
00648 Geo VCardFormatImpl::readGeoValue( ContentLine *cl )
00649 {
00650 GeoValue *geoValue = (GeoValue *)cl->value();
00651 if ( geoValue ) {
00652 Geo geo( geoValue->latitude(), geoValue->longitude() );
00653 return geo;
00654 } else
00655 return Geo();
00656 }
00657
00658 TimeZone VCardFormatImpl::readUTCValue( ContentLine *cl )
00659 {
00660 UTCValue *utcValue = (UTCValue *)cl->value();
00661 if ( utcValue ) {
00662 TimeZone tz;
00663 tz.setOffset(((utcValue->hour()*60)+utcValue->minute())*(utcValue->positive() ? 1 : -1));
00664 return tz;
00665 } else
00666 return TimeZone();
00667 }
00668
00669 Secrecy VCardFormatImpl::readClassValue( ContentLine *cl )
00670 {
00671 ClassValue *classValue = (ClassValue *)cl->value();
00672 if ( classValue ) {
00673 Secrecy secrecy;
00674 switch ( classValue->type() ) {
00675 case ClassValue::Public:
00676 secrecy.setType( Secrecy::Public );
00677 break;
00678 case ClassValue::Private:
00679 secrecy.setType( Secrecy::Private );
00680 break;
00681 case ClassValue::Confidential:
00682 secrecy.setType( Secrecy::Confidential );
00683 break;
00684 }
00685
00686 return secrecy;
00687 } else
00688 return Secrecy();
00689 }
00690
00691 void VCardFormatImpl::addKeyValue( VCARD::VCard *vcard, const Key &key )
00692 {
00693 ContentLine cl;
00694 cl.setName( EntityTypeToParamName( EntityKey ) );
00695
00696 ParamList params;
00697 if ( key.isBinary() ) {
00698 cl.setValue( new TextValue( KCodecs::base64Encode( key.binaryData() ) ) );
00699 params.append( new Param( "ENCODING", "b" ) );
00700 } else {
00701 cl.setValue( new TextValue( key.textData().utf8() ) );
00702 }
00703
00704 switch ( key.type() ) {
00705 case Key::X509:
00706 params.append( new Param( "TYPE", "X509" ) );
00707 break;
00708 case Key::PGP:
00709 params.append( new Param( "TYPE", "PGP" ) );
00710 break;
00711 case Key::Custom:
00712 params.append( new Param( "TYPE", key.customTypeString().utf8() ) );
00713 break;
00714 }
00715
00716 cl.setParamList( params );
00717 vcard->add( cl );
00718 }
00719
00720 Key VCardFormatImpl::readKeyValue( VCARD::ContentLine *cl )
00721 {
00722 Key key;
00723 bool isBinary = false;
00724 TextValue *v = (TextValue *)cl->value();
00725
00726 ParamList params = cl->paramList();
00727 ParamListIterator it( params );
00728 for( ; it.current(); ++it ) {
00729 if ( (*it)->name() == "ENCODING" && (*it)->value() == "b" )
00730 isBinary = true;
00731 if ( (*it)->name() == "TYPE" ) {
00732 if ( (*it)->value().isEmpty() )
00733 continue;
00734 if ( (*it)->value() == "X509" )
00735 key.setType( Key::X509 );
00736 else if ( (*it)->value() == "PGP" )
00737 key.setType( Key::PGP );
00738 else {
00739 key.setType( Key::Custom );
00740 key.setCustomTypeString( QString::fromUtf8( (*it)->value() ) );
00741 }
00742 }
00743 }
00744
00745
00746 if ( isBinary ) {
00747 QByteArray data;
00748 KCodecs::base64Decode( v->asString().stripWhiteSpace(), data );
00749 key.setBinaryData( data );
00750 } else {
00751 key.setTextData( QString::fromUtf8( v->asString() ) );
00752 }
00753
00754 return key;
00755 }
00756
00757
00758 void VCardFormatImpl::addAgentValue( VCARD::VCard *vcard, const Agent &agent )
00759 {
00760 if ( agent.isIntern() && !agent.addressee() )
00761 return;
00762
00763 if ( !agent.isIntern() && agent.url().isEmpty() )
00764 return;
00765
00766 ContentLine cl;
00767 cl.setName( EntityTypeToParamName( EntityAgent ) );
00768
00769 ParamList params;
00770 if ( agent.isIntern() ) {
00771 QString vstr;
00772 Addressee *addr = agent.addressee();
00773 if ( addr ) {
00774 writeToString( (*addr), vstr );
00775 vstr.replace( ":", "\\:" );
00776 vstr.replace( ",", "\\," );
00777 vstr.replace( ";", "\\;" );
00778 vstr.replace( "\r\n", "\\n" );
00779 cl.setValue( new TextValue( vstr.utf8() ) );
00780 } else
00781 return;
00782 } else {
00783 cl.setValue( new TextValue( agent.url().utf8() ) );
00784 params.append( new Param( "VALUE", "uri" ) );
00785 }
00786
00787 cl.setParamList( params );
00788 vcard->add( cl );
00789 }
00790
00791 Agent VCardFormatImpl::readAgentValue( VCARD::ContentLine *cl )
00792 {
00793 Agent agent;
00794 bool isIntern = true;
00795 TextValue *v = (TextValue *)cl->value();
00796
00797 ParamList params = cl->paramList();
00798 ParamListIterator it( params );
00799 for( ; it.current(); ++it ) {
00800 if ( (*it)->name() == "VALUE" && (*it)->value() == "uri" )
00801 isIntern = false;
00802 }
00803
00804 if ( isIntern ) {
00805 QString vstr = QString::fromUtf8( v->asString() );
00806 vstr.replace( "\\n", "\r\n" );
00807 vstr.replace( "\\:", ":" );
00808 vstr.replace( "\\,", "," );
00809 vstr.replace( "\\;", ";" );
00810 Addressee *addr = new Addressee;
00811 readFromString( vstr, *addr );
00812 agent.setAddressee( addr );
00813 } else {
00814 agent.setUrl( QString::fromUtf8( v->asString() ) );
00815 }
00816
00817 return agent;
00818 }
00819
00820 void VCardFormatImpl::addPictureValue( VCARD::VCard *vcard, VCARD::EntityType type, const Picture &pic, const Addressee &addr, bool intern )
00821 {
00822 ContentLine cl;
00823 cl.setName( EntityTypeToParamName( type ) );
00824
00825 if ( pic.isIntern() && pic.data().isNull() )
00826 return;
00827
00828 if ( !pic.isIntern() && pic.url().isEmpty() )
00829 return;
00830
00831 ParamList params;
00832 if ( pic.isIntern() ) {
00833 QImage img = pic.data();
00834 if ( intern ) {
00835 QByteArray data;
00836 QDataStream s( data, IO_WriteOnly );
00837 s.setVersion( 4 );
00838 s << img;
00839 cl.setValue( new TextValue( KCodecs::base64Encode( data ) ) );
00840 } else {
00841 QString dir;
00842 if ( type == EntityPhoto )
00843 dir = "photos";
00844 if ( type == EntityLogo )
00845 dir = "logos";
00846
00847 img.save( locateLocal( "data", "kabc/" + dir + "/" + addr.uid() ), pic.type().utf8() );
00848 cl.setValue( new TextValue( "<dummy>" ) );
00849 }
00850 params.append( new Param( "ENCODING", "b" ) );
00851 if ( !pic.type().isEmpty() )
00852 params.append( new Param( "TYPE", pic.type().utf8() ) );
00853 } else {
00854 cl.setValue( new TextValue( pic.url().utf8() ) );
00855 params.append( new Param( "VALUE", "uri" ) );
00856 }
00857
00858 cl.setParamList( params );
00859 vcard->add( cl );
00860 }
00861
00862 Picture VCardFormatImpl::readPictureValue( VCARD::ContentLine *cl, VCARD::EntityType type, const Addressee &addr )
00863 {
00864 Picture pic;
00865 bool isInline = false;
00866 QString picType;
00867 TextValue *v = (TextValue *)cl->value();
00868
00869 ParamList params = cl->paramList();
00870 ParamListIterator it( params );
00871 for( ; it.current(); ++it ) {
00872 if ( (*it)->name() == "ENCODING" && (*it)->value() == "b" )
00873 isInline = true;
00874 if ( (*it)->name() == "TYPE" && !(*it)->value().isEmpty() )
00875 picType = QString::fromUtf8( (*it)->value() );
00876 }
00877
00878 if ( isInline ) {
00879 QImage img;
00880 if ( v->asString() == "<dummy>" ) {
00881 QString dir;
00882 if ( type == EntityPhoto )
00883 dir = "photos";
00884 if ( type == EntityLogo )
00885 dir = "logos";
00886
00887 img.load( locateLocal( "data", "kabc/" + dir + "/" + addr.uid() ) );
00888 } else {
00889 QByteArray data;
00890 KCodecs::base64Decode( v->asString(), data );
00891 img.loadFromData( data );
00892 }
00893 pic.setData( img );
00894 pic.setType( picType );
00895 } else {
00896 pic.setUrl( QString::fromUtf8( v->asString() ) );
00897 }
00898
00899 return pic;
00900 }
00901
00902 void VCardFormatImpl::addSoundValue( VCARD::VCard *vcard, const Sound &sound, const Addressee &addr, bool intern )
00903 {
00904 ContentLine cl;
00905 cl.setName( EntityTypeToParamName( EntitySound ) );
00906
00907 if ( sound.isIntern() && sound.data().isNull() )
00908 return;
00909
00910 if ( !sound.isIntern() && sound.url().isEmpty() )
00911 return;
00912
00913 ParamList params;
00914 if ( sound.isIntern() ) {
00915 QByteArray data = sound.data();
00916 if ( intern ) {
00917 cl.setValue( new TextValue( KCodecs::base64Encode( data ) ) );
00918 } else {
00919 QFile file( locateLocal( "data", "kabc/sounds/" + addr.uid() ) );
00920 if ( file.open( IO_WriteOnly ) ) {
00921 file.writeBlock( data );
00922 }
00923 cl.setValue( new TextValue( "<dummy>" ) );
00924 }
00925 params.append( new Param( "ENCODING", "b" ) );
00926 } else {
00927 cl.setValue( new TextValue( sound.url().utf8() ) );
00928 params.append( new Param( "VALUE", "uri" ) );
00929 }
00930
00931 cl.setParamList( params );
00932 vcard->add( cl );
00933 }
00934
00935 Sound VCardFormatImpl::readSoundValue( VCARD::ContentLine *cl, const Addressee &addr )
00936 {
00937 Sound sound;
00938 bool isInline = false;
00939 TextValue *v = (TextValue *)cl->value();
00940
00941 ParamList params = cl->paramList();
00942 ParamListIterator it( params );
00943 for( ; it.current(); ++it ) {
00944 if ( (*it)->name() == "ENCODING" && (*it)->value() == "b" )
00945 isInline = true;
00946 }
00947
00948 if ( isInline ) {
00949 QByteArray data;
00950 if ( v->asString() == "<dummy>" ) {
00951 QFile file( locateLocal( "data", "kabc/sounds/" + addr.uid() ) );
00952 if ( file.open( IO_ReadOnly ) ) {
00953 data = file.readAll();
00954 file.close();
00955 }
00956 } else {
00957 KCodecs::base64Decode( v->asString(), data );
00958 }
00959 sound.setData( data );
00960 } else {
00961 sound.setUrl( QString::fromUtf8( v->asString() ) );
00962 }
00963
00964 return sound;
00965 }
00966
00967 bool VCardFormatImpl::readFromString( const QString &vcard, Addressee &addressee )
00968 {
00969 VCardEntity e( vcard.utf8() );
00970 VCardListIterator it( e.cardList() );
00971
00972 if ( it.current() ) {
00973 VCARD::VCard v(*it.current());
00974 loadAddressee( addressee, v );
00975 return true;
00976 }
00977
00978 return false;
00979 }
00980
00981 bool VCardFormatImpl::writeToString( const Addressee &addressee, QString &vcard )
00982 {
00983 VCardEntity vcards;
00984 VCardList vcardlist;
00985 vcardlist.setAutoDelete( true );
00986
00987 VCARD::VCard *v = new VCARD::VCard;
00988
00989 saveAddressee( addressee, v, true );
00990
00991 vcardlist.append( v );
00992 vcards.setCardList( vcardlist );
00993 vcard = QString::fromUtf8( vcards.asString() );
00994
00995 return true;
00996 }