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