author | zautrix <zautrix> | 2004-06-26 19:01:18 (UTC) |
---|---|---|
committer | zautrix <zautrix> | 2004-06-26 19:01:18 (UTC) |
commit | b9aad1f15dc600e4dbe4c62d3fcced6363188ba3 (patch) (unidiff) | |
tree | 2c3d4004fb21c72cba65793859f9bcd8ffd3a49c /kabc/vcardformatimpl.cpp | |
download | kdepimpi-b9aad1f15dc600e4dbe4c62d3fcced6363188ba3.zip kdepimpi-b9aad1f15dc600e4dbe4c62d3fcced6363188ba3.tar.gz kdepimpi-b9aad1f15dc600e4dbe4c62d3fcced6363188ba3.tar.bz2 |
Initial revision
-rw-r--r-- | kabc/vcardformatimpl.cpp | 1023 |
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 | /* | ||
22 | Enhanced Version of the file for platform independent KDE tools. | ||
23 | Copyright (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 | |||
41 | using namespace KABC; | ||
42 | using namespace VCARD; | ||
43 | |||
44 | bool 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 | |||
64 | bool 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 | |||
86 | void 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 | |||
103 | void 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 | |||
125 | bool 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 | |||
282 | void 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 | |||
352 | void 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 | |||
365 | void 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 | |||
375 | void 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 | |||
388 | void 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 | |||
401 | void 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 | |||
424 | void 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 | |||
437 | void 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 | |||
450 | void 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 | |||
465 | void 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 | |||
482 | void 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 | |||
505 | Address 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 | |||
522 | int 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 | |||
541 | void 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 | |||
556 | void 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 | |||
566 | void 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 | |||
595 | PhoneNumber 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 | |||
627 | QString 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 | |||
638 | QDate 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 | |||
647 | QDateTime 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 | |||
656 | Geo 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 | |||
666 | TimeZone 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 | |||
677 | Secrecy 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 | |||
699 | void 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 | |||
728 | Key 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 | |||
766 | void 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 | |||
808 | Agent 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 | |||
845 | void 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 | |||
889 | Picture 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 | |||
929 | void 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 | |||
962 | Sound 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 | |||
994 | bool 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 | |||
1008 | bool 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 | } | ||