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