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 <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         // not yet supported by kabc
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 ) { // only for vCard export we really write the data inline
00835       QByteArray data;
00836       QDataStream s( data, IO_WriteOnly );
00837       s.setVersion( 4 ); // to produce valid png files
00838       s << img;
00839       cl.setValue( new TextValue( KCodecs::base64Encode( data ) ) );
00840     } else { // save picture in cache
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>" ) { // no picture inline stored => picture is in cache
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 ) { // only for vCard export we really write the data inline
00917         cl.setValue( new TextValue( KCodecs::base64Encode( data ) ) );
00918     } else { // save sound in cache
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>" ) { // no sound inline stored => sound is in cache
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 }
KDE Home | KDE Accessibility Home | Description of Access Keys