summaryrefslogtreecommitdiffabout
path: root/kabc/vcardformatimpl.cpp
authorzautrix <zautrix>2004-06-26 19:01:18 (UTC)
committer zautrix <zautrix>2004-06-26 19:01:18 (UTC)
commitb9aad1f15dc600e4dbe4c62d3fcced6363188ba3 (patch) (unidiff)
tree2c3d4004fb21c72cba65793859f9bcd8ffd3a49c /kabc/vcardformatimpl.cpp
downloadkdepimpi-b9aad1f15dc600e4dbe4c62d3fcced6363188ba3.zip
kdepimpi-b9aad1f15dc600e4dbe4c62d3fcced6363188ba3.tar.gz
kdepimpi-b9aad1f15dc600e4dbe4c62d3fcced6363188ba3.tar.bz2
Initial revision
Diffstat (limited to 'kabc/vcardformatimpl.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--kabc/vcardformatimpl.cpp1023
1 files changed, 1023 insertions, 0 deletions
diff --git a/kabc/vcardformatimpl.cpp b/kabc/vcardformatimpl.cpp
new file mode 100644
index 0000000..f90f813
--- a/dev/null
+++ b/kabc/vcardformatimpl.cpp
@@ -0,0 +1,1023 @@
1/*
2 This file is part of libkabc.
3 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/*
22Enhanced Version of the file for platform independent KDE tools.
23Copyright (c) 2004 Ulf Schenk
24
25$Id$
26*/
27
28#include <qfile.h>
29#include <qregexp.h>
30
31#include <kdebug.h>
32#include <kmdcodec.h>
33#include <kstandarddirs.h>
34#include <ktempfile.h>
35
36#include <VCard.h>
37
38#include "addressbook.h"
39#include "vcardformatimpl.h"
40
41using namespace KABC;
42using namespace VCARD;
43
44bool VCardFormatImpl::load( Addressee &addressee, QFile *file )
45{
46 kdDebug(5700) << "VCardFormat::load()" << endl;
47
48 QByteArray fdata = file->readAll();
49 QCString data(fdata.data(), fdata.size()+1);
50
51 VCardEntity e( data );
52
53 VCardListIterator it( e.cardList() );
54
55 if ( it.current() ) {
56 VCard v(*it.current());
57 loadAddressee( addressee, v );
58 return true;
59 }
60
61 return false;
62}
63
64bool VCardFormatImpl::loadAll( AddressBook *addressBook, Resource *resource, QFile *file )
65{
66 kdDebug(5700) << "VCardFormat::loadAll()" << endl;
67
68 QByteArray fdata = file->readAll();
69 QCString data(fdata.data(), fdata.size()+1);
70
71 VCardEntity e( data );
72
73 VCardListIterator it( e.cardList() );
74
75 for (; it.current(); ++it) {
76 VCard v(*it.current());
77 Addressee addressee;
78 loadAddressee( addressee, v );
79 addressee.setResource( resource );
80 addressBook->insertAddressee( addressee );
81 }
82
83 return true;
84}
85
86void VCardFormatImpl::save( const Addressee &addressee, QFile *file )
87{
88 VCardEntity vcards;
89 VCardList vcardlist;
90 vcardlist.setAutoDelete( true );
91
92 VCard *v = new VCard;
93
94 saveAddressee( addressee, v, false );
95
96 vcardlist.append( v );
97 vcards.setCardList( vcardlist );
98
99 QCString vcardData = vcards.asString();
100 file->writeBlock( (const char*)vcardData, vcardData.length() );
101}
102
103void VCardFormatImpl::saveAll( AddressBook *ab, Resource *resource, QFile *file )
104{
105 VCardEntity vcards;
106 VCardList vcardlist;
107 vcardlist.setAutoDelete( true );
108
109 AddressBook::Iterator it;
110 for ( it = ab->begin(); it != ab->end(); ++it ) {
111 if ( (*it).resource() == resource ) {
112 VCard *v = new VCard;
113 saveAddressee( (*it), v, false );
114 (*it).setChanged( false );
115 vcardlist.append( v );
116 }
117 }
118
119 vcards.setCardList( vcardlist );
120
121 QCString vcardData = vcards.asString();
122 file->writeBlock( (const char*)vcardData, vcardData.length() );
123}
124
125bool VCardFormatImpl::loadAddressee( Addressee& addressee, VCard &v )
126{
127 QPtrList<ContentLine> contentLines = v.contentLineList();
128 ContentLine *cl;
129
130 for( cl = contentLines.first(); cl; cl = contentLines.next() ) {
131 QCString n = cl->name();
132 if ( n.left( 2 ) == "X-" ) {
133 n = n.mid( 2 );
134 int posDash = n.find( "-" );
135 addressee.insertCustom( QString::fromUtf8( n.left( posDash ) ),
136 QString::fromUtf8( n.mid( posDash + 1 ) ),
137 QString::fromUtf8( cl->value()->asString() ) );
138 continue;
139 }
140
141 EntityType type = cl->entityType();
142 switch( type ) {
143
144 case EntityUID:
145 addressee.setUid( readTextValue( cl ) );
146 break;
147
148 case EntityEmail:
149 addressee.insertEmail( readTextValue( cl ) );
150 break;
151
152 case EntityName:
153 addressee.setName( readTextValue( cl ) );
154 break;
155
156 case EntityFullName:
157 addressee.setFormattedName( readTextValue( cl ) );
158 break;
159
160 case EntityURL:
161 addressee.setUrl( KURL( readTextValue( cl ) ) );
162 break;
163
164 case EntityNickname:
165 addressee.setNickName( readTextValue( cl ) );
166 break;
167
168 case EntityLabel:
169 // not yet supported by kabc
170 break;
171
172 case EntityMailer:
173 addressee.setMailer( readTextValue( cl ) );
174 break;
175
176 case EntityTitle:
177 addressee.setTitle( readTextValue( cl ) );
178 break;
179
180 case EntityRole:
181 addressee.setRole( readTextValue( cl ) );
182 break;
183
184 case EntityOrganisation:
185 addressee.setOrganization( readTextValue( cl ) );
186 break;
187
188 case EntityNote:
189 addressee.setNote( readTextValue( cl ) );
190 break;
191
192 case EntityProductID:
193 addressee.setProductId( readTextValue( cl ) );
194 break;
195
196 case EntitySortString:
197 addressee.setSortString( readTextValue( cl ) );
198 break;
199
200 case EntityN:
201 readNValue( cl, addressee );
202 break;
203
204 case EntityAddress:
205 addressee.insertAddress( readAddressValue( cl ) );
206 break;
207
208 case EntityTelephone:
209 addressee.insertPhoneNumber( readTelephoneValue( cl ) );
210 break;
211
212 case EntityCategories:
213 addressee.setCategories( QStringList::split( ",", readTextValue( cl ) ) );
214 break;
215
216 case EntityBirthday:
217 addressee.setBirthday( readDateValue( cl ) );
218 break;
219
220 case EntityRevision:
221 addressee.setRevision( readDateTimeValue( cl ) );
222 break;
223
224 case EntityGeo:
225 addressee.setGeo( readGeoValue( cl ) );
226 break;
227
228 case EntityTimeZone:
229 addressee.setTimeZone( readUTCValue( cl ) );
230 break;
231
232 case EntityVersion:
233 break;
234
235 case EntityClass:
236 addressee.setSecrecy( readClassValue( cl ) );
237 break;
238
239 case EntityKey:
240 addressee.insertKey( readKeyValue( cl ) );
241 break;
242
243 case EntityPhoto:
244 addressee.setPhoto( readPictureValue( cl, EntityPhoto, addressee ) );
245 break;
246
247 case EntityLogo:
248 addressee.setLogo( readPictureValue( cl, EntityLogo, addressee ) );
249 break;
250
251 case EntityAgent:
252 addressee.setAgent( readAgentValue( cl ) );
253 break;
254
255 case EntitySound:
256 addressee.setSound( readSoundValue( cl, addressee ) );
257 break;
258
259 default:
260 kdDebug(5700) << "VCardFormat::load(): Unsupported entity: "
261 << int( type ) << ": " << cl->asString() << endl;
262 break;
263 }
264 }
265
266 for( cl = contentLines.first(); cl; cl = contentLines.next() ) {
267 EntityType type = cl->entityType();
268 if ( type == EntityLabel ) {
269 int type = readAddressParam( cl );
270 Address address = addressee.address( type );
271 if ( address.isEmpty() )
272 address.setType( type );
273
274 address.setLabel( QString::fromUtf8( cl->value()->asString() ) );
275 addressee.insertAddress( address );
276 }
277 }
278
279 return true;
280}
281
282void VCardFormatImpl::saveAddressee( const Addressee &addressee, VCard *v, bool intern )
283{
284 ContentLine cl;
285 QString value;
286
287 addTextValue( v, EntityName, addressee.name() );
288 addTextValue( v, EntityUID, addressee.uid() );
289 addTextValue( v, EntityFullName, addressee.formattedName() );
290
291 QStringList emails = addressee.emails();
292 QStringList::ConstIterator it4;
293 for( it4 = emails.begin(); it4 != emails.end(); ++it4 ) {
294 addTextValue( v, EntityEmail, *it4 );
295 }
296
297 QStringList customs = addressee.customs();
298 QStringList::ConstIterator it5;
299 for( it5 = customs.begin(); it5 != customs.end(); ++it5 ) {
300 addCustomValue( v, *it5 );
301 }
302
303 addTextValue( v, EntityURL, addressee.url().url() );
304
305 addNValue( v, addressee );
306
307 addTextValue( v, EntityNickname, addressee.nickName() );
308 addTextValue( v, EntityMailer, addressee.mailer() );
309 addTextValue( v, EntityTitle, addressee.title() );
310 addTextValue( v, EntityRole, addressee.role() );
311 addTextValue( v, EntityOrganisation, addressee.organization() );
312 addTextValue( v, EntityNote, addressee.note() );
313 addTextValue( v, EntityProductID, addressee.productId() );
314 addTextValue( v, EntitySortString, addressee.sortString() );
315
316 Address::List addresses = addressee.addresses();
317 Address::List::ConstIterator it3;
318 for( it3 = addresses.begin(); it3 != addresses.end(); ++it3 ) {
319 addAddressValue( v, *it3 );
320 addLabelValue( v, *it3 );
321 }
322
323 PhoneNumber::List phoneNumbers = addressee.phoneNumbers();
324 PhoneNumber::List::ConstIterator it2;
325 for( it2 = phoneNumbers.begin(); it2 != phoneNumbers.end(); ++it2 ) {
326 addTelephoneValue( v, *it2 );
327 }
328
329 Key::List keys = addressee.keys();
330 Key::List::ConstIterator it6;
331 for( it6 = keys.begin(); it6 != keys.end(); ++it6 ) {
332 addKeyValue( v, *it6 );
333 }
334
335 addTextValue( v, EntityCategories, addressee.categories().join(",") );
336
337 addDateValue( v, EntityBirthday, addressee.birthday().date() );
338 addDateTimeValue( v, EntityRevision, addressee.revision() );
339 addGeoValue( v, addressee.geo() );
340 addUTCValue( v, addressee.timeZone() );
341
342 addClassValue( v, addressee.secrecy() );
343
344 addPictureValue( v, EntityPhoto, addressee.photo(), addressee, intern );
345 addPictureValue( v, EntityLogo, addressee.logo(), addressee, intern );
346
347 addAgentValue( v, addressee.agent() );
348
349 addSoundValue( v, addressee.sound(), addressee, intern );
350}
351
352void VCardFormatImpl::addCustomValue( VCard *v, const QString &txt )
353{
354 if ( txt.isEmpty() ) return;
355
356 ContentLine cl;
357 cl.setName( "X-" + txt.left( txt.find( ":" ) ).utf8() );
358 QString value = txt.mid( txt.find( ":" ) + 1 );
359 if ( value.isEmpty() )
360 return;
361 cl.setValue( new TextValue( value.utf8() ) );
362 v->add(cl);
363}
364
365void VCardFormatImpl::addTextValue( VCard *v, EntityType type, const QString &txt )
366{
367 if ( txt.isEmpty() ) return;
368
369 ContentLine cl;
370 cl.setName( EntityTypeToParamName( type ) );
371 cl.setValue( new TextValue( txt.utf8() ) );
372 v->add(cl);
373}
374
375void VCardFormatImpl::addDateValue( VCard *vcard, EntityType type,
376 const QDate &date )
377{
378 if ( !date.isValid() ) return;
379
380 ContentLine cl;
381 cl.setName( EntityTypeToParamName( type ) );
382
383 DateValue *v = new DateValue( date );
384 cl.setValue( v );
385 vcard->add(cl);
386}
387
388void VCardFormatImpl::addDateTimeValue( VCard *vcard, EntityType type,
389 const QDateTime &dateTime )
390{
391 if ( !dateTime.isValid() ) return;
392
393 ContentLine cl;
394 cl.setName( EntityTypeToParamName( type ) );
395
396 DateValue *v = new DateValue( dateTime );
397 cl.setValue( v );
398 vcard->add(cl);
399}
400
401void VCardFormatImpl::addAddressValue( VCard *vcard, const Address &a )
402{
403 if ( a.isEmpty() )
404 return;
405
406 ContentLine cl;
407 cl.setName( EntityTypeToParamName( EntityAddress ) );
408
409 AdrValue *v = new AdrValue;
410 v->setPOBox( a.postOfficeBox().utf8() );
411 v->setExtAddress( a.extended().utf8() );
412 v->setStreet( a.street().utf8() );
413 v->setLocality( a.locality().utf8() );
414 v->setRegion( a.region().utf8() );
415 v->setPostCode( a.postalCode().utf8() );
416 v->setCountryName( a.country().utf8() );
417 cl.setValue( v );
418
419 addAddressParam( &cl, a.type() );
420
421 vcard->add( cl );
422}
423
424void VCardFormatImpl::addLabelValue( VCard *vcard, const Address &a )
425{
426 if ( a.label().isEmpty() ) return;
427
428 ContentLine cl;
429 cl.setName( EntityTypeToParamName( EntityLabel ) );
430 cl.setValue( new TextValue( a.label().utf8() ) );
431
432 addAddressParam( &cl, a.type() );
433
434 vcard->add( cl );
435}
436
437void VCardFormatImpl::addAddressParam( ContentLine *cl, int type )
438{
439 ParamList params;
440 if ( type & Address::Dom ) params.append( new Param( "TYPE", "dom" ) );
441 if ( type & Address::Intl ) params.append( new Param( "TYPE", "intl" ) );
442 if ( type & Address::Parcel ) params.append( new Param( "TYPE", "parcel" ) );
443 if ( type & Address::Postal ) params.append( new Param( "TYPE", "postal" ) );
444 if ( type & Address::Work ) params.append( new Param( "TYPE", "work" ) );
445 if ( type & Address::Home ) params.append( new Param( "TYPE", "home" ) );
446 if ( type & Address::Pref ) params.append( new Param( "TYPE", "pref" ) );
447 cl->setParamList( params );
448}
449
450void VCardFormatImpl::addGeoValue( VCard *vcard, const Geo &geo )
451{
452 if ( !geo.isValid() ) return;
453
454 ContentLine cl;
455 cl.setName( EntityTypeToParamName( EntityGeo ) );
456
457 GeoValue *v = new GeoValue;
458 v->setLatitude( geo.latitude() );
459 v->setLongitude( geo.longitude() );
460
461 cl.setValue( v );
462 vcard->add(cl);
463}
464
465void VCardFormatImpl::addUTCValue( VCard *vcard, const TimeZone &tz )
466{
467 if ( !tz.isValid() ) return;
468
469 ContentLine cl;
470 cl.setName( EntityTypeToParamName( EntityTimeZone ) );
471
472 UTCValue *v = new UTCValue;
473
474 v->setPositive( tz.offset() >= 0 );
475 v->setHour( (tz.offset() / 60) * ( tz.offset() >= 0 ? 1 : -1 ) );
476 v->setMinute( (tz.offset() % 60) * ( tz.offset() >= 0 ? 1 : -1 ) );
477
478 cl.setValue( v );
479 vcard->add(cl);
480}
481
482void VCardFormatImpl::addClassValue( VCard *vcard, const Secrecy &secrecy )
483{
484 ContentLine cl;
485 cl.setName( EntityTypeToParamName( EntityClass ) );
486
487 ClassValue *v = new ClassValue;
488 switch ( secrecy.type() ) {
489 case Secrecy::Public:
490 v->setType( (int)ClassValue::Public );
491 break;
492 case Secrecy::Private:
493 v->setType( (int)ClassValue::Private );
494 break;
495 case Secrecy::Confidential:
496 v->setType( (int)ClassValue::Confidential );
497 break;
498 }
499
500 cl.setValue( v );
501 vcard->add(cl);
502}
503
504
505Address VCardFormatImpl::readAddressValue( ContentLine *cl )
506{
507 Address a;
508 AdrValue *v = (AdrValue *)cl->value();
509 a.setPostOfficeBox( QString::fromUtf8( v->poBox() ) );
510 a.setExtended( QString::fromUtf8( v->extAddress() ) );
511 a.setStreet( QString::fromUtf8( v->street() ) );
512 a.setLocality( QString::fromUtf8( v->locality() ) );
513 a.setRegion( QString::fromUtf8( v->region() ) );
514 a.setPostalCode( QString::fromUtf8( v->postCode() ) );
515 a.setCountry( QString::fromUtf8( v->countryName() ) );
516
517 a.setType( readAddressParam( cl ) );
518
519 return a;
520}
521
522int VCardFormatImpl::readAddressParam( ContentLine *cl )
523{
524 int type = 0;
525 ParamList params = cl->paramList();
526 ParamListIterator it( params );
527 for( ; it.current(); ++it ) {
528 if ( (*it)->name() == "TYPE" ) {
529 if ( (*it)->value() == "dom" ) type |= Address::Dom;
530 else if ( (*it)->value() == "intl" ) type |= Address::Intl;
531 else if ( (*it)->value() == "parcel" ) type |= Address::Parcel;
532 else if ( (*it)->value() == "postal" ) type |= Address::Postal;
533 else if ( (*it)->value() == "work" ) type |= Address::Work;
534 else if ( (*it)->value() == "home" ) type |= Address::Home;
535 else if ( (*it)->value() == "pref" ) type |= Address::Pref;
536 }
537 }
538 return type;
539}
540
541void VCardFormatImpl::addNValue( VCard *vcard, const Addressee &a )
542{
543 ContentLine cl;
544 cl.setName(EntityTypeToParamName( EntityN ) );
545 NValue *v = new NValue;
546 v->setFamily( a.familyName().utf8() );
547 v->setGiven( a.givenName().utf8() );
548 v->setMiddle( a.additionalName().utf8() );
549 v->setPrefix( a.prefix().utf8() );
550 v->setSuffix( a.suffix().utf8() );
551
552 cl.setValue( v );
553 vcard->add(cl);
554}
555
556void VCardFormatImpl::readNValue( ContentLine *cl, Addressee &a )
557{
558 NValue *v = (NValue *)cl->value();
559 a.setFamilyName( QString::fromUtf8( v->family() ) );
560 a.setGivenName( QString::fromUtf8( v->given() ) );
561 a.setAdditionalName( QString::fromUtf8( v->middle() ) );
562 a.setPrefix( QString::fromUtf8( v->prefix() ) );
563 a.setSuffix( QString::fromUtf8( v->suffix() ) );
564}
565
566void VCardFormatImpl::addTelephoneValue( VCard *v, const PhoneNumber &p )
567{
568 if ( p.number().isEmpty() )
569 return;
570
571 ContentLine cl;
572 cl.setName(EntityTypeToParamName(EntityTelephone));
573 cl.setValue(new TelValue( p.number().utf8() ));
574
575 ParamList params;
576 if( p.type() & PhoneNumber::Home ) params.append( new Param( "TYPE", "home" ) );
577 if( p.type() & PhoneNumber::Work ) params.append( new Param( "TYPE", "work" ) );
578 if( p.type() & PhoneNumber::Msg ) params.append( new Param( "TYPE", "msg" ) );
579 if( p.type() & PhoneNumber::Pref ) params.append( new Param( "TYPE", "pref" ) );
580 if( p.type() & PhoneNumber::Voice ) params.append( new Param( "TYPE", "voice" ) );
581 if( p.type() & PhoneNumber::Fax ) params.append( new Param( "TYPE", "fax" ) );
582 if( p.type() & PhoneNumber::Cell ) params.append( new Param( "TYPE", "cell" ) );
583 if( p.type() & PhoneNumber::Video ) params.append( new Param( "TYPE", "video" ) );
584 if( p.type() & PhoneNumber::Bbs ) params.append( new Param( "TYPE", "bbs" ) );
585 if( p.type() & PhoneNumber::Modem ) params.append( new Param( "TYPE", "modem" ) );
586 if( p.type() & PhoneNumber::Car ) params.append( new Param( "TYPE", "car" ) );
587 if( p.type() & PhoneNumber::Isdn ) params.append( new Param( "TYPE", "isdn" ) );
588 if( p.type() & PhoneNumber::Pcs ) params.append( new Param( "TYPE", "pcs" ) );
589 if( p.type() & PhoneNumber::Pager ) params.append( new Param( "TYPE", "pager" ) );
590 cl.setParamList( params );
591
592 v->add(cl);
593}
594
595PhoneNumber VCardFormatImpl::readTelephoneValue( ContentLine *cl )
596{
597 PhoneNumber p;
598 TelValue *value = (TelValue *)cl->value();
599 p.setNumber( QString::fromUtf8( value->asString() ) );
600
601 int type = 0;
602 ParamList params = cl->paramList();
603 ParamListIterator it( params );
604 for( ; it.current(); ++it ) {
605 if ( (*it)->name() == "TYPE" ) {
606 if ( (*it)->value() == "home" ) type |= PhoneNumber::Home;
607 else if ( (*it)->value() == "work" ) type |= PhoneNumber::Work;
608 else if ( (*it)->value() == "msg" ) type |= PhoneNumber::Msg;
609 else if ( (*it)->value() == "pref" ) type |= PhoneNumber::Pref;
610 else if ( (*it)->value() == "voice" ) type |= PhoneNumber::Voice;
611 else if ( (*it)->value() == "fax" ) type |= PhoneNumber::Fax;
612 else if ( (*it)->value() == "cell" ) type |= PhoneNumber::Cell;
613 else if ( (*it)->value() == "video" ) type |= PhoneNumber::Video;
614 else if ( (*it)->value() == "bbs" ) type |= PhoneNumber::Bbs;
615 else if ( (*it)->value() == "modem" ) type |= PhoneNumber::Modem;
616 else if ( (*it)->value() == "car" ) type |= PhoneNumber::Car;
617 else if ( (*it)->value() == "isdn" ) type |= PhoneNumber::Isdn;
618 else if ( (*it)->value() == "pcs" ) type |= PhoneNumber::Pcs;
619 else if ( (*it)->value() == "pager" ) type |= PhoneNumber::Pager;
620 }
621 }
622 p.setType( type );
623
624 return p;
625}
626
627QString VCardFormatImpl::readTextValue( ContentLine *cl )
628{
629 VCARD::Value *value = cl->value();
630 if ( value ) {
631 return QString::fromUtf8( value->asString() );
632 } else {
633 kdDebug(5700) << "No value: " << cl->asString() << endl;
634 return QString::null;
635 }
636}
637
638QDate VCardFormatImpl::readDateValue( ContentLine *cl )
639{
640 DateValue *dateValue = (DateValue *)cl->value();
641 if ( dateValue )
642 return dateValue->qdate();
643 else
644 return QDate();
645}
646
647QDateTime VCardFormatImpl::readDateTimeValue( ContentLine *cl )
648{
649 DateValue *dateValue = (DateValue *)cl->value();
650 if ( dateValue )
651 return dateValue->qdt();
652 else
653 return QDateTime();
654}
655
656Geo VCardFormatImpl::readGeoValue( ContentLine *cl )
657{
658 GeoValue *geoValue = (GeoValue *)cl->value();
659 if ( geoValue ) {
660 Geo geo( geoValue->latitude(), geoValue->longitude() );
661 return geo;
662 } else
663 return Geo();
664}
665
666TimeZone VCardFormatImpl::readUTCValue( ContentLine *cl )
667{
668 UTCValue *utcValue = (UTCValue *)cl->value();
669 if ( utcValue ) {
670 TimeZone tz;
671 tz.setOffset(((utcValue->hour()*60)+utcValue->minute())*(utcValue->positive() ? 1 : -1));
672 return tz;
673 } else
674 return TimeZone();
675}
676
677Secrecy VCardFormatImpl::readClassValue( ContentLine *cl )
678{
679 ClassValue *classValue = (ClassValue *)cl->value();
680 if ( classValue ) {
681 Secrecy secrecy;
682 switch ( classValue->type() ) {
683 case ClassValue::Public:
684 secrecy.setType( Secrecy::Public );
685 break;
686 case ClassValue::Private:
687 secrecy.setType( Secrecy::Private );
688 break;
689 case ClassValue::Confidential:
690 secrecy.setType( Secrecy::Confidential );
691 break;
692 }
693
694 return secrecy;
695 } else
696 return Secrecy();
697}
698
699void VCardFormatImpl::addKeyValue( VCARD::VCard *vcard, const Key &key )
700{
701 ContentLine cl;
702 cl.setName( EntityTypeToParamName( EntityKey ) );
703
704 ParamList params;
705 if ( key.isBinary() ) {
706 cl.setValue( new TextValue( KCodecs::base64Encode( key.binaryData() ) ) );
707 params.append( new Param( "ENCODING", "b" ) );
708 } else {
709 cl.setValue( new TextValue( key.textData().utf8() ) );
710 }
711
712 switch ( key.type() ) {
713 case Key::X509:
714 params.append( new Param( "TYPE", "X509" ) );
715 break;
716 case Key::PGP:
717 params.append( new Param( "TYPE", "PGP" ) );
718 break;
719 case Key::Custom:
720 params.append( new Param( "TYPE", key.customTypeString().utf8() ) );
721 break;
722 }
723
724 cl.setParamList( params );
725 vcard->add( cl );
726}
727
728Key VCardFormatImpl::readKeyValue( VCARD::ContentLine *cl )
729{
730 Key key;
731 bool isBinary = false;
732 TextValue *v = (TextValue *)cl->value();
733
734 ParamList params = cl->paramList();
735 ParamListIterator it( params );
736 for( ; it.current(); ++it ) {
737 if ( (*it)->name() == "ENCODING" && (*it)->value() == "b" )
738 isBinary = true;
739 if ( (*it)->name() == "TYPE" ) {
740 if ( (*it)->value().isEmpty() )
741 continue;
742 if ( (*it)->value() == "X509" )
743 key.setType( Key::X509 );
744 else if ( (*it)->value() == "PGP" )
745 key.setType( Key::PGP );
746 else {
747 key.setType( Key::Custom );
748 key.setCustomTypeString( QString::fromUtf8( (*it)->value() ) );
749 }
750 }
751 }
752
753
754 if ( isBinary ) {
755 QByteArray data;
756 KCodecs::base64Decode( v->asString().stripWhiteSpace(), data );
757 key.setBinaryData( data );
758 } else {
759 key.setTextData( QString::fromUtf8( v->asString() ) );
760 }
761
762 return key;
763}
764
765
766void VCardFormatImpl::addAgentValue( VCARD::VCard *vcard, const Agent &agent )
767{
768 if ( agent.isIntern() && !agent.addressee() )
769 return;
770
771 if ( !agent.isIntern() && agent.url().isEmpty() )
772 return;
773
774 ContentLine cl;
775 cl.setName( EntityTypeToParamName( EntityAgent ) );
776
777 ParamList params;
778 if ( agent.isIntern() ) {
779 QString vstr;
780 Addressee *addr = agent.addressee();
781 if ( addr ) {
782 writeToString( (*addr), vstr );
783
784 qDebug("VCardFormatImpl::addAgentValue please verify if replace is correct");
785/*US
786 vstr.replace( ":", "\\:" );
787 vstr.replace( ",", "\\," );
788 vstr.replace( ";", "\\;" );
789 vstr.replace( "\r\n", "\\n" );
790*/
791 vstr.replace( QRegExp(":"), "\\:" );
792 vstr.replace( QRegExp(","), "\\," );
793 vstr.replace( QRegExp(";"), "\\;" );
794 vstr.replace( QRegExp("\r\n"), "\\n" );
795
796 cl.setValue( new TextValue( vstr.utf8() ) );
797 } else
798 return;
799 } else {
800 cl.setValue( new TextValue( agent.url().utf8() ) );
801 params.append( new Param( "VALUE", "uri" ) );
802 }
803
804 cl.setParamList( params );
805 vcard->add( cl );
806}
807
808Agent VCardFormatImpl::readAgentValue( VCARD::ContentLine *cl )
809{
810 Agent agent;
811 bool isIntern = true;
812 TextValue *v = (TextValue *)cl->value();
813
814 ParamList params = cl->paramList();
815 ParamListIterator it( params );
816 for( ; it.current(); ++it ) {
817 if ( (*it)->name() == "VALUE" && (*it)->value() == "uri" )
818 isIntern = false;
819 }
820
821 if ( isIntern ) {
822 QString vstr = QString::fromUtf8( v->asString() );
823 qDebug("VCardFormatImpl::addAgentValue please verify if replace is correct");
824/*US
825 vstr.replace( "\\n", "\r\n" );
826 vstr.replace( "\\:", ":" );
827 vstr.replace( "\\,", "," );
828 vstr.replace( "\\;", ";" );
829*/
830 vstr.replace( QRegExp("\\n"), "\r\n" );
831 vstr.replace( QRegExp("\\:"), ":" );
832 vstr.replace( QRegExp("\\,"), "," );
833 vstr.replace( QRegExp("\\;"), ";" );
834
835 Addressee *addr = new Addressee;
836 readFromString( vstr, *addr );
837 agent.setAddressee( addr );
838 } else {
839 agent.setUrl( QString::fromUtf8( v->asString() ) );
840 }
841
842 return agent;
843}
844
845void VCardFormatImpl::addPictureValue( VCARD::VCard *vcard, VCARD::EntityType type, const Picture &pic, const Addressee &addr, bool intern )
846{
847 ContentLine cl;
848 cl.setName( EntityTypeToParamName( type ) );
849
850 if ( pic.isIntern() && pic.data().isNull() )
851 return;
852
853 if ( !pic.isIntern() && pic.url().isEmpty() )
854 return;
855
856 ParamList params;
857 if ( pic.isIntern() ) {
858 QImage img = pic.data();
859 if ( intern ) { // only for vCard export we really write the data inline
860 QByteArray data;
861 QDataStream s( data, IO_WriteOnly );
862 s.setVersion( 4 ); // to produce valid png files
863 s << img;
864 cl.setValue( new TextValue( KCodecs::base64Encode( data ) ) );
865
866 } else { // save picture in cache
867 QString dir;
868 if ( type == EntityPhoto )
869 dir = "photos";
870 if ( type == EntityLogo )
871 dir = "logos";
872
873 img.save( locateLocal( "data", "kabc/" + dir + "/" + addr.uid() ), pic.type().utf8() );
874 cl.setValue( new TextValue( "<dummy>" ) );
875 }
876 params.append( new Param( "ENCODING", "b" ) );
877 if ( !pic.type().isEmpty() )
878 params.append( new Param( "TYPE", pic.type().utf8() ) );
879 } else {
880
881 cl.setValue( new TextValue( pic.url().utf8() ) );
882 params.append( new Param( "VALUE", "uri" ) );
883 }
884
885 cl.setParamList( params );
886 vcard->add( cl );
887}
888
889Picture VCardFormatImpl::readPictureValue( VCARD::ContentLine *cl, VCARD::EntityType type, const Addressee &addr )
890{
891 Picture pic;
892 bool isInline = false;
893 QString picType;
894 TextValue *v = (TextValue *)cl->value();
895
896 ParamList params = cl->paramList();
897 ParamListIterator it( params );
898 for( ; it.current(); ++it ) {
899 if ( (*it)->name() == "ENCODING" && (*it)->value() == "b" )
900 isInline = true;
901 if ( (*it)->name() == "TYPE" && !(*it)->value().isEmpty() )
902 picType = QString::fromUtf8( (*it)->value() );
903 }
904
905 if ( isInline ) {
906 QImage img;
907 if ( v->asString() == "<dummy>" ) { // no picture inline stored => picture is in cache
908 QString dir;
909 if ( type == EntityPhoto )
910 dir = "photos";
911 if ( type == EntityLogo )
912 dir = "logos";
913
914 img.load( locateLocal( "data", "kabc/" + dir + "/" + addr.uid() ) );
915 } else {
916 QByteArray data;
917 KCodecs::base64Decode( v->asString(), data );
918 img.loadFromData( data );
919 }
920 pic.setData( img );
921 pic.setType( picType );
922 } else {
923 pic.setUrl( QString::fromUtf8( v->asString() ) );
924 }
925
926 return pic;
927}
928
929void VCardFormatImpl::addSoundValue( VCARD::VCard *vcard, const Sound &sound, const Addressee &addr, bool intern )
930{
931 ContentLine cl;
932 cl.setName( EntityTypeToParamName( EntitySound ) );
933
934 if ( sound.isIntern() && sound.data().isNull() )
935 return;
936
937 if ( !sound.isIntern() && sound.url().isEmpty() )
938 return;
939
940 ParamList params;
941 if ( sound.isIntern() ) {
942 QByteArray data = sound.data();
943 if ( intern ) { // only for vCard export we really write the data inline
944 cl.setValue( new TextValue( KCodecs::base64Encode( data ) ) );
945 } else { // save sound in cache
946 QFile file( locateLocal( "data", "kabc/sounds/" + addr.uid() ) );
947 if ( file.open( IO_WriteOnly ) ) {
948 file.writeBlock( data );
949 }
950 cl.setValue( new TextValue( "<dummy>" ) );
951 }
952 params.append( new Param( "ENCODING", "b" ) );
953 } else {
954 cl.setValue( new TextValue( sound.url().utf8() ) );
955 params.append( new Param( "VALUE", "uri" ) );
956 }
957
958 cl.setParamList( params );
959 vcard->add( cl );
960}
961
962Sound VCardFormatImpl::readSoundValue( VCARD::ContentLine *cl, const Addressee &addr )
963{
964 Sound sound;
965 bool isInline = false;
966 TextValue *v = (TextValue *)cl->value();
967
968 ParamList params = cl->paramList();
969 ParamListIterator it( params );
970 for( ; it.current(); ++it ) {
971 if ( (*it)->name() == "ENCODING" && (*it)->value() == "b" )
972 isInline = true;
973 }
974
975 if ( isInline ) {
976 QByteArray data;
977 if ( v->asString() == "<dummy>" ) { // no sound inline stored => sound is in cache
978 QFile file( locateLocal( "data", "kabc/sounds/" + addr.uid() ) );
979 if ( file.open( IO_ReadOnly ) ) {
980 data = file.readAll();
981 file.close();
982 }
983 } else {
984 KCodecs::base64Decode( v->asString(), data );
985 }
986 sound.setData( data );
987 } else {
988 sound.setUrl( QString::fromUtf8( v->asString() ) );
989 }
990
991 return sound;
992}
993
994bool VCardFormatImpl::readFromString( const QString &vcard, Addressee &addressee )
995{
996 VCardEntity e( vcard.utf8() );
997 VCardListIterator it( e.cardList() );
998
999 if ( it.current() ) {
1000 VCard v(*it.current());
1001 loadAddressee( addressee, v );
1002 return true;
1003 }
1004
1005 return false;
1006}
1007
1008bool VCardFormatImpl::writeToString( const Addressee &addressee, QString &vcard )
1009{
1010 VCardEntity vcards;
1011 VCardList vcardlist;
1012 vcardlist.setAutoDelete( true );
1013
1014 VCard *v = new VCard;
1015
1016 saveAddressee( addressee, v, true );
1017
1018 vcardlist.append( v );
1019 vcards.setCardList( vcardlist );
1020 vcard = QString::fromUtf8( vcards.asString() );
1021
1022 return true;
1023}