• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.14.10 API Reference
  • KDE Home
  • Contact Us
 

kabc

  • kabc
vcardtool.cpp
1/*
2 This file is part of libkabc.
3 Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>
4 Copyright (c) 2015 Laurent Montel <montel@kde.org>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20*/
21
22#include "vcardtool.h"
23#include "key.h"
24#include "picture.h"
25#include "secrecy.h"
26#include "sound.h"
27#include "lang.h"
28#include "gender.h"
29
30#include <QtCore/QString>
31#include <QtCore/QBuffer>
32#include <QDebug>
33
34using namespace KABC;
35
36static bool needsEncoding( const QString &value )
37{
38 uint length = value.length();
39 for ( uint i = 0; i < length; ++i ) {
40 char c = value.at( i ).toLatin1();
41 if ( ( c < 33 || c > 126 ) && c != ' ' && c != '=' ) {
42 return true;
43 }
44 }
45
46 return false;
47}
48
49VCardTool::VCardTool()
50{
51 mAddressTypeMap.insert( QLatin1String( "dom" ), Address::Dom );
52 mAddressTypeMap.insert( QLatin1String( "intl" ), Address::Intl );
53 mAddressTypeMap.insert( QLatin1String( "postal" ), Address::Postal );
54 mAddressTypeMap.insert( QLatin1String( "parcel" ), Address::Parcel );
55 mAddressTypeMap.insert( QLatin1String( "home" ), Address::Home );
56 mAddressTypeMap.insert( QLatin1String( "work" ), Address::Work );
57 mAddressTypeMap.insert( QLatin1String( "pref" ), Address::Pref );
58
59 mPhoneTypeMap.insert( QLatin1String( "HOME" ), PhoneNumber::Home );
60 mPhoneTypeMap.insert( QLatin1String( "WORK" ), PhoneNumber::Work );
61 mPhoneTypeMap.insert( QLatin1String( "MSG" ), PhoneNumber::Msg );
62 mPhoneTypeMap.insert( QLatin1String( "PREF" ), PhoneNumber::Pref );
63 mPhoneTypeMap.insert( QLatin1String( "VOICE" ), PhoneNumber::Voice );
64 mPhoneTypeMap.insert( QLatin1String( "FAX" ), PhoneNumber::Fax );
65 mPhoneTypeMap.insert( QLatin1String( "CELL" ), PhoneNumber::Cell );
66 mPhoneTypeMap.insert( QLatin1String( "VIDEO" ), PhoneNumber::Video );
67 mPhoneTypeMap.insert( QLatin1String( "BBS" ), PhoneNumber::Bbs );
68 mPhoneTypeMap.insert( QLatin1String( "MODEM" ), PhoneNumber::Modem );
69 mPhoneTypeMap.insert( QLatin1String( "CAR" ), PhoneNumber::Car );
70 mPhoneTypeMap.insert( QLatin1String( "ISDN" ), PhoneNumber::Isdn );
71 mPhoneTypeMap.insert( QLatin1String( "PCS" ), PhoneNumber::Pcs );
72 mPhoneTypeMap.insert( QLatin1String( "PAGER" ), PhoneNumber::Pager );
73}
74
75VCardTool::~VCardTool()
76{
77}
78
79QByteArray VCardTool::exportVCards( const Addressee::List &list, VCard::Version version ) const
80{
81 return createVCards( list, version, true /*export vcard*/);
82}
83
84QByteArray VCardTool::createVCards( const Addressee::List &list, VCard::Version version ) const
85{
86 return createVCards( list, version, false /*don't export*/);
87}
88
89void VCardTool::addParameter(VCardLine &line, VCard::Version version, const QString &key, const QStringList &valueStringList) const
90{
91 if (version == VCard::v2_1) {
92 Q_FOREACH(const QString &valueStr, valueStringList) {
93 line.addParameter( valueStr, QString() );
94 }
95 } else {
96 line.addParameter( key, valueStringList.join(QLatin1String(",")) );
97 }
98}
99
100QByteArray VCardTool::createVCards( const Addressee::List &list,
101 VCard::Version version, bool exportVcard ) const
102{
103 VCard::List vCardList;
104
105 Addressee::List::ConstIterator addrIt;
106 Addressee::List::ConstIterator listEnd( list.constEnd() );
107 for ( addrIt = list.constBegin(); addrIt != listEnd; ++addrIt ) {
108 VCard card;
109 QStringList::ConstIterator strIt;
110
111 // ADR + LABEL
112 const Address::List addresses = ( *addrIt ).addresses();
113 for ( Address::List::ConstIterator it = addresses.begin(); it != addresses.end(); ++it ) {
114 QStringList address;
115
116 const bool isEmpty = ( ( *it ).postOfficeBox().isEmpty() &&
117 ( *it ).extended().isEmpty() &&
118 ( *it ).street().isEmpty() &&
119 ( *it ).locality().isEmpty() &&
120 ( *it ).region().isEmpty() &&
121 ( *it ).postalCode().isEmpty() &&
122 ( *it ).country().isEmpty() );
123
124 address.append( ( *it ).postOfficeBox().replace( QLatin1Char( ';' ),
125 QLatin1String( "\\;" ) ) );
126
127 address.append( ( *it ).extended().replace( QLatin1Char( ';' ),
128 QLatin1String( "\\;" ) ) );
129
130 address.append( ( *it ).street().replace( QLatin1Char( ';' ),
131 QLatin1String( "\\;" ) ) );
132
133 address.append( ( *it ).locality().replace( QLatin1Char( ';' ),
134 QLatin1String( "\\;" ) ) );
135
136 address.append( ( *it ).region().replace( QLatin1Char( ';' ),
137 QLatin1String( "\\;" ) ) );
138
139 address.append( ( *it ).postalCode().replace( QLatin1Char( ';' ),
140 QLatin1String( "\\;" ) ) );
141
142 address.append( ( *it ).country().replace( QLatin1Char( ';' ),
143 QLatin1String( "\\;" ) ) );
144
145 VCardLine adrLine( QLatin1String( "ADR" ), address.join( QLatin1String( ";" ) ) );
146 if ( version == VCard::v2_1 && needsEncoding( address.join( QLatin1String( ";" ) ) ) ) {
147 adrLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) );
148 adrLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) );
149 }
150
151 VCardLine labelLine( QLatin1String( "LABEL" ), ( *it ).label() );
152 if ( version == VCard::v2_1 && needsEncoding( ( *it ).label() ) ) {
153 labelLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) );
154 labelLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) );
155 }
156
157 const bool hasLabel = !( *it ).label().isEmpty();
158 QMap<QString, Address::TypeFlag>::ConstIterator typeIt;
159 for ( typeIt = mAddressTypeMap.constBegin();
160 typeIt != mAddressTypeMap.constEnd(); ++typeIt ) {
161 if ( typeIt.value() & ( *it ).type() ) {
162 addParameter(adrLine, version, QLatin1String( "TYPE" ), QStringList()<<typeIt.key());
163 if ( hasLabel ) {
164 addParameter(labelLine, version, QLatin1String( "TYPE" ), QStringList()<<typeIt.key());
165 }
166 }
167 }
168
169 if ( !isEmpty ) {
170 card.addLine( adrLine );
171 }
172 if ( hasLabel ) {
173 card.addLine( labelLine );
174 }
175 }
176
177 // BDAY
178 card.addLine( VCardLine( QLatin1String( "BDAY" ), createDateTime( ( *addrIt ).birthday() ) ) );
179
180 //Laurent: 31 Jan 2015. Not necessary to export it. When Categories were changes as AkonadiTag nobody thought that it was break categorie support...
181 //=> not necessary to export just tag...
182 // CATEGORIES only > 2.1
183 if (!exportVcard) {
184 if ( version != VCard::v2_1 ) {
185 QStringList categories = ( *addrIt ).categories();
186 QStringList::Iterator catIt;
187 QStringList::Iterator catEnd( categories.end() );
188 for ( catIt = categories.begin(); catIt != catEnd; ++catIt ) {
189 ( *catIt ).replace( QLatin1Char( ',' ), QLatin1String( "\\," ) );
190 }
191
192 VCardLine catLine( QLatin1String( "CATEGORIES" ), categories.join( QLatin1String( "," ) ) );
193 card.addLine( catLine );
194 }
195 }
196
197 // MEMBER (only in 4.0)
198 if ( version == VCard::v4_0) {
199 // The KIND property must be set to "group" in order to use this property.
200 if (( *addrIt ).kind().toLower() == QLatin1String("group")) {
201 Q_FOREACH (const QString &member, ( *addrIt ).members() ) {
202 VCardLine line( QLatin1String( "MEMBER" ), member );
203 card.addLine( line );
204 }
205 }
206 }
207
208 // SOURCE
209 Q_FOREACH (const KUrl &url, ( *addrIt ).sourcesUrlList()) {
210 VCardLine line = VCardLine( QLatin1String( "SOURCE" ), url.url() );
211 card.addLine( line );
212 }
213
214 // RELATED
215 if (version == VCard::v4_0) {
216 Q_FOREACH (const QString &relation, ( *addrIt ).relationShips() ) {
217 VCardLine line( QLatin1String( "RELATED" ), relation );
218 card.addLine( line );
219 }
220 }
221 // CLASS only for version == 3.0
222 if ( version == VCard::v3_0 ) {
223 card.addLine( createSecrecy( ( *addrIt ).secrecy() ) );
224 }
225
226 // LANG only for version == 4.0
227 if ( version == VCard::v4_0 ) {
228 const Lang::List langList = ( *addrIt ).langs();
229 Lang::List::ConstIterator langIt;
230 Lang::List::ConstIterator langEnd( langList.end() );
231 for ( langIt = langList.begin(); langIt != langEnd; ++langIt ) {
232 VCardLine line( QLatin1String( "LANG" ), (*langIt).language() );
233 QMapIterator<QString, QStringList> i((*langIt).parameters());
234 while (i.hasNext()) {
235 i.next();
236 line.addParameter( i.key(), i.value().join(QLatin1String(",")) );
237 }
238 card.addLine( line );
239 }
240 }
241 // EMAIL
242 const Email::List emailList = ( *addrIt ).emailList();
243 Email::List::ConstIterator emailIt;
244 Email::List::ConstIterator emailEnd( emailList.end() );
245 bool pref = true;
246
247 for ( emailIt = emailList.begin(); emailIt != emailEnd; ++emailIt ) {
248 bool needToAddPref = false;
249 VCardLine line( QLatin1String( "EMAIL" ), (*emailIt).mail() );
250 if ( pref == true && emailList.count() > 1 ) {
251 needToAddPref = true;
252 pref = false;
253 }
254 QMapIterator<QString, QStringList> i((*emailIt).parameters());
255 bool foundType = false;
256 while (i.hasNext()) {
257 i.next();
258 QStringList valueStringList = i.value();
259 if (i.key().toLower() == QLatin1String( "type" )) {
260 if (!valueStringList.contains(QLatin1String("PREF"))) {
261 if (needToAddPref) {
262 valueStringList.append(QLatin1String( "PREF" ));
263 } else {
264 needToAddPref = false;
265 }
266 } else {
267 if (!needToAddPref) {
268 valueStringList.removeAll(QLatin1String( "PREF" ));
269 }
270 }
271 foundType = true;
272 }
273 if (!valueStringList.isEmpty()) {
274 if (i.key().toLower() == QLatin1String( "type" )) {
275 addParameter(line, version, i.key(), valueStringList);
276 } else {
277 line.addParameter( i.key(), valueStringList.join(QLatin1String(",")) );
278 }
279 }
280 }
281 if (!foundType && needToAddPref) {
282 if (version == VCard::v2_1) {
283 line.addParameter( QLatin1String( "PREF" ), QString() );
284 } else {
285 line.addParameter( QLatin1String( "TYPE" ), QLatin1String( "PREF" ) );
286 }
287 }
288 card.addLine( line );
289 }
290
291 // FN required for only version > 2.1
292 VCardLine fnLine( QLatin1String( "FN" ), ( *addrIt ).formattedName() );
293 if ( version == VCard::v2_1 && needsEncoding( ( *addrIt ).formattedName() ) ) {
294 fnLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) );
295 fnLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) );
296 }
297 card.addLine( fnLine );
298
299 // GEO
300 const Geo geo = ( *addrIt ).geo();
301 if ( geo.isValid() ) {
302 QString str;
303 if (version == VCard::v4_0 ) {
304 str.sprintf( "geo:%.6f,%.6f", geo.latitude(), geo.longitude() );
305 } else {
306 str.sprintf( "%.6f;%.6f", geo.latitude(), geo.longitude() );
307 }
308 card.addLine( VCardLine( QLatin1String( "GEO" ), str ) );
309 }
310
311 // KEY
312 const Key::List keys = ( *addrIt ).keys();
313 Key::List::ConstIterator keyIt;
314 Key::List::ConstIterator keyEnd( keys.end() );
315 for ( keyIt = keys.begin(); keyIt != keyEnd; ++keyIt ) {
316 card.addLine( createKey( *keyIt, version ) );
317 }
318
319 // LOGO
320 card.addLine( createPicture( QLatin1String( "LOGO" ), ( *addrIt ).logo(), version ) );
321 Q_FOREACH (const KABC::Picture &logo, ( *addrIt ).extraLogoList()) {
322 card.addLine( createPicture( QLatin1String( "LOGO" ), logo, version ) );
323 }
324
325 // MAILER only for version < 4.0
326 if ( version != VCard::v4_0 ) {
327 VCardLine mailerLine( QLatin1String( "MAILER" ), ( *addrIt ).mailer() );
328 if ( version == VCard::v2_1 && needsEncoding( ( *addrIt ).mailer() ) ) {
329 mailerLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) );
330 mailerLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) );
331 }
332 card.addLine( mailerLine );
333 }
334
335 // N required for only version < 4.0
336 QStringList name;
337 name.append( ( *addrIt ).familyName().replace( QLatin1Char( ';' ),
338 QLatin1String( "\\;" ) ) );
339
340 name.append( ( *addrIt ).givenName().replace( QLatin1Char( ';' ),
341 QLatin1String( "\\;" ) ) );
342
343 name.append( ( *addrIt ).additionalName().replace( QLatin1Char( ';' ),
344 QLatin1String( "\\;" ) ) );
345
346 name.append( ( *addrIt ).prefix().replace( QLatin1Char( ';' ),
347 QLatin1String( "\\;" ) ) );
348
349 name.append( ( *addrIt ).suffix().replace( QLatin1Char( ';' ),
350 QLatin1String( "\\;" ) ) );
351
352 VCardLine nLine( QLatin1String( "N" ), name.join( QLatin1String( ";" ) ) );
353 if ( version == VCard::v2_1 && needsEncoding( name.join( QLatin1String( ";" ) ) ) ) {
354 nLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) );
355 nLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) );
356 }
357 if ( version == VCard::v4_0 && !( *addrIt ).sortString().isEmpty() ) {
358 nLine.addParameter( QLatin1String( "SORT-AS" ), ( *addrIt ).sortString() );
359 }
360
361 card.addLine( nLine );
362
363 // NAME only for version < 4.0
364 if ( version != VCard::v4_0 ) {
365 VCardLine nameLine( QLatin1String( "NAME" ), ( *addrIt ).name() );
366 if ( version == VCard::v2_1 && needsEncoding( ( *addrIt ).name() ) ) {
367 nameLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) );
368 nameLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) );
369 }
370 card.addLine( nameLine );
371 }
372
373 // NICKNAME only for version > 2.1
374 if ( version != VCard::v2_1 ) {
375 card.addLine( VCardLine( QLatin1String( "NICKNAME" ), ( *addrIt ).nickName() ) );
376 }
377
378 // NOTE
379 VCardLine noteLine( QLatin1String( "NOTE" ), ( *addrIt ).note() );
380 if ( version == VCard::v2_1 && needsEncoding( ( *addrIt ).note() ) ) {
381 noteLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) );
382 noteLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) );
383 }
384 card.addLine( noteLine );
385
386 // ORG
387 QStringList organization;
388 organization.append( ( *addrIt ).organization().replace( QLatin1Char( ';' ),
389 QLatin1String( "\\;" ) ) );
390 if ( !( *addrIt ).department().isEmpty() ) {
391 organization.append( ( *addrIt ).department().replace( QLatin1Char( ';' ),
392 QLatin1String( "\\;" ) ) );
393 }
394 VCardLine orgLine( QLatin1String( "ORG" ), organization.join( QLatin1String( ";" ) ) );
395 if ( version == VCard::v2_1 && needsEncoding( organization.join( QLatin1String( ";" ) ) ) ) {
396 orgLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) );
397 orgLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) );
398 }
399 card.addLine( orgLine );
400
401 // PHOTO
402 card.addLine( createPicture( QLatin1String( "PHOTO" ), ( *addrIt ).photo(), version ) );
403 Q_FOREACH (const KABC::Picture &photo, ( *addrIt ).extraPhotoList()) {
404 card.addLine( createPicture( QLatin1String( "PHOTO" ), photo, version ) );
405 }
406
407 // PROID only for version > 2.1
408 if ( version != VCard::v2_1 ) {
409 card.addLine( VCardLine( QLatin1String( "PRODID" ), ( *addrIt ).productId() ) );
410 }
411
412 // REV
413 card.addLine( VCardLine( QLatin1String( "REV" ), createDateTime( ( *addrIt ).revision() ) ) );
414
415 // ROLE
416 VCardLine roleLine( QLatin1String( "ROLE" ), ( *addrIt ).role() );
417 if ( version == VCard::v2_1 && needsEncoding( ( *addrIt ).role() ) ) {
418 roleLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) );
419 roleLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) );
420 }
421 card.addLine( roleLine );
422
423 // SORT-STRING
424 if ( version == VCard::v3_0 ) {
425 card.addLine( VCardLine( QLatin1String( "SORT-STRING" ), ( *addrIt ).sortString() ) );
426 }
427
428 // SOUND
429 card.addLine( createSound( ( *addrIt ).sound(), version ) );
430 Q_FOREACH (const KABC::Sound &sound, ( *addrIt ).extraSoundList()) {
431 card.addLine( createSound( sound, version ) );
432 }
433
434 // TEL
435 const PhoneNumber::List phoneNumbers = ( *addrIt ).phoneNumbers();
436 PhoneNumber::List::ConstIterator phoneIt;
437 PhoneNumber::List::ConstIterator phoneEnd( phoneNumbers.end() );
438 for ( phoneIt = phoneNumbers.begin(); phoneIt != phoneEnd; ++phoneIt ) {
439 VCardLine line( QLatin1String( "TEL" ), ( *phoneIt ).number() );
440
441 QMap<QString, PhoneNumber::TypeFlag>::ConstIterator typeIt;
442 QMap<QString, PhoneNumber::TypeFlag>::ConstIterator typeEnd( mPhoneTypeMap.constEnd() );
443 for ( typeIt = mPhoneTypeMap.constBegin(); typeIt != typeEnd; ++typeIt ) {
444 if ( typeIt.value() & ( *phoneIt ).type() ) {
445 addParameter(line, version, QLatin1String( "TYPE" ), QStringList()<<typeIt.key());
446 }
447 }
448
449 card.addLine( line );
450 }
451
452 // TITLE
453 VCardLine titleLine( QLatin1String( "TITLE" ), ( *addrIt ).title() );
454 if ( version == VCard::v2_1 && needsEncoding( ( *addrIt ).title() ) ) {
455 titleLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) );
456 titleLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) );
457 }
458 card.addLine( titleLine );
459
460 // TZ
461 // TODO Add vcard4.0 support
462 const TimeZone timeZone = ( *addrIt ).timeZone();
463 if ( timeZone.isValid() ) {
464 QString str;
465
466 int neg = 1;
467 if ( timeZone.offset() < 0 ) {
468 neg = -1;
469 }
470
471 str.sprintf( "%c%02d:%02d", ( timeZone.offset() >= 0 ? '+' : '-' ),
472 ( timeZone.offset() / 60 ) * neg,
473 ( timeZone.offset() % 60 ) * neg );
474
475 card.addLine( VCardLine( QLatin1String( "TZ" ), str ) );
476 }
477
478 // UID
479 card.addLine( VCardLine( QLatin1String( "UID" ), ( *addrIt ).uid() ) );
480
481 // URL
482 card.addLine( VCardLine( QLatin1String( "URL" ), ( *addrIt ).url().url() ) );
483 Q_FOREACH (const KUrl &url, ( *addrIt ).extraUrlList()) {
484 VCardLine line = VCardLine( QLatin1String( "URL" ), url.url() );
485 card.addLine( line );
486 }
487
488 // VERSION
489 if ( version == VCard::v2_1 ) {
490 card.addLine( VCardLine( QLatin1String( "VERSION" ), QLatin1String( "2.1" ) ) );
491 } else if ( version == VCard::v3_0 ) {
492 card.addLine( VCardLine( QLatin1String( "VERSION" ), QLatin1String( "3.0" ) ) );
493 } else if ( version == VCard::v4_0 ) {
494 card.addLine( VCardLine( QLatin1String( "VERSION" ), QLatin1String( "4.0" ) ) );
495 }
496
497 // X-
498 const QStringList customs = ( *addrIt ).customs();
499 for ( strIt = customs.begin(); strIt != customs.end(); ++strIt ) {
500 QString identifier = QLatin1String( "X-" ) +
501 ( *strIt ).left( ( *strIt ).indexOf( QLatin1Char( ':' ) ) );
502 const QString value = ( *strIt ).mid( ( *strIt ).indexOf( QLatin1Char( ':' ) ) + 1 );
503 if ( value.isEmpty() ) {
504 continue;
505 }
506 //Convert to standard identifier
507 if ( exportVcard ) {
508 if ( identifier == QLatin1String( "X-messaging/aim-All" ) ) {
509 identifier = QLatin1String( "X-AIM" );
510 } else if ( identifier == QLatin1String( "X-messaging/icq-All" ) ) {
511 identifier = QLatin1String( "X-ICQ" );
512 } else if ( identifier == QLatin1String( "X-messaging/xmpp-All" ) ) {
513 identifier = QLatin1String( "X-JABBER" );
514 } else if ( identifier == QLatin1String( "X-messaging/msn-All" ) ) {
515 identifier = QLatin1String( "X-MSN" );
516 } else if ( identifier == QLatin1String( "X-messaging/yahoo-All" ) ) {
517 identifier = QLatin1String( "X-YAHOO" );
518 } else if ( identifier == QLatin1String( "X-messaging/gadu-All" ) ) {
519 identifier = QLatin1String( "X-GADUGADU" );
520 } else if ( identifier == QLatin1String( "X-messaging/skype-All" ) ) {
521 identifier = QLatin1String( "X-SKYPE" );
522 } else if ( identifier == QLatin1String( "X-messaging/groupwise-All" ) ) {
523 identifier = QLatin1String( "X-GROUPWISE" );
524 } else if ( identifier == QLatin1String( "X-messaging/sms-All" ) ) {
525 identifier = QLatin1String( "X-SMS" );
526 } else if ( identifier == QLatin1String( "X-messaging/meanwhile-All" ) ) {
527 identifier = QLatin1String( "X-MEANWHILE" );
528 } else if ( identifier == QLatin1String( "X-messaging/irc-All" ) ) {
529 identifier = QLatin1String( "X-IRC" ); //Not defined by rfc but need for fixing #300869
530 } else if ( identifier == QLatin1String( "X-messaging/googletalk-All" ) ) {
531 //Not defined by rfc but need for fixing #300869
532 identifier = QLatin1String( "X-GTALK" );
533 }
534 }
535
536 if (version == VCard::v4_0) {
537 // GENDER
538 const Gender gender = ( *addrIt ).gender();
539 if (gender.isValid()) {
540 QString genderStr;
541 if (!gender.gender().isEmpty()) {
542 genderStr = gender.gender();
543 }
544 if (!gender.comment().isEmpty()) {
545 genderStr += QLatin1Char(';') + gender.comment();
546 }
547 VCardLine line( QLatin1String( "GENDER" ), genderStr );
548 card.addLine( line );
549 }
550 // KIND
551 if (!( *addrIt ).kind().isEmpty()) {
552 VCardLine line( QLatin1String( "KIND" ), ( *addrIt ).kind() );
553 card.addLine(line);
554 }
555 }
556 if (identifier.toLower() == QLatin1String( "x-kaddressbook-x-anniversary" ) && version == VCard::v4_0) {
557 // ANNIVERSARY
558 if (!value.isEmpty()) {
559 const QDate date = QDate::fromString( value, Qt::ISODate );
560 QDateTime dt = QDateTime(date);
561 dt.setTime(QTime());
562 card.addLine( VCardLine( QLatin1String( "ANNIVERSARY" ), createDateTime( dt ) ) );
563 }
564 } else {
565 VCardLine line( identifier, value );
566 if ( version == VCard::v2_1 && needsEncoding( value ) ) {
567 line.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) );
568 line.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) );
569 }
570 card.addLine( line );
571 }
572 }
573
574 vCardList.append( card );
575 }
576
577 return VCardParser::createVCards( vCardList );
578}
579
580Addressee::List VCardTool::parseVCards( const QByteArray &vcard ) const
581{
582 static const QLatin1Char semicolonSep( ';' );
583 static const QLatin1Char commaSep( ',' );
584 QString identifier;
585
586 Addressee::List addrList;
587 const VCard::List vCardList = VCardParser::parseVCards( vcard );
588
589 VCard::List::ConstIterator cardIt;
590 VCard::List::ConstIterator listEnd( vCardList.end() );
591 for ( cardIt = vCardList.begin(); cardIt != listEnd; ++cardIt ) {
592 Addressee addr;
593
594 const QStringList idents = ( *cardIt ).identifiers();
595 QStringList::ConstIterator identIt;
596 QStringList::ConstIterator identEnd( idents.end() );
597 for ( identIt = idents.begin(); identIt != identEnd; ++identIt ) {
598 const VCardLine::List lines = ( *cardIt ).lines( ( *identIt ) );
599 VCardLine::List::ConstIterator lineIt;
600
601 // iterate over the lines
602 for ( lineIt = lines.begin(); lineIt != lines.end(); ++lineIt ) {
603 identifier = ( *lineIt ).identifier().toLower();
604 // ADR
605 if ( identifier == QLatin1String( "adr" ) ) {
606 Address address;
607 const QStringList addrParts = splitString( semicolonSep, ( *lineIt ).value().toString() );
608 if ( addrParts.count() > 0 ) {
609 address.setPostOfficeBox( addrParts.at(0) );
610 }
611 if ( addrParts.count() > 1 ) {
612 address.setExtended( addrParts.at(1) );
613 }
614 if ( addrParts.count() > 2 ) {
615 address.setStreet( addrParts.at(2) );
616 }
617 if ( addrParts.count() > 3 ) {
618 address.setLocality( addrParts.at(3) );
619 }
620 if ( addrParts.count() > 4 ) {
621 address.setRegion( addrParts.at(4) );
622 }
623 if ( addrParts.count() > 5 ) {
624 address.setPostalCode( addrParts.at(5) );
625 }
626 if ( addrParts.count() > 6 ) {
627 address.setCountry( addrParts.at(6) );
628 }
629
630 Address::Type type;
631
632 const QStringList types = ( *lineIt ).parameters( QLatin1String( "type" ) );
633 QStringList::ConstIterator end(types.end());
634 for ( QStringList::ConstIterator it = types.begin(); it != end; ++it ) {
635 type |= mAddressTypeMap[ ( *it ).toLower() ];
636 }
637
638 address.setType( type );
639 if ( !( *lineIt ).parameter( QLatin1String( "label" ) ).isEmpty() ) {
640 address.setLabel( ( *lineIt ).parameter( QLatin1String( "label" ) ) );
641 }
642 addr.insertAddress( address );
643 }
644
645 // BDAY
646 else if ( identifier == QLatin1String( "bday" ) ) {
647 addr.setBirthday( parseDateTime( ( *lineIt ).value().toString() ) );
648 }
649 // ANNIVERSARY
650 else if ( identifier == QLatin1String( "anniversary" ) ) {
651 const QString t = ( *lineIt ).value().toString();
652 const QDateTime dt(parseDateTime( t ));
653 addr.insertCustom( QLatin1String("KADDRESSBOOK"), QLatin1String("X-Anniversary"), dt.date().toString(Qt::ISODate) );
654 }
655 // CATEGORIES
656 else if ( identifier == QLatin1String( "categories" ) ) {
657 const QStringList categories = splitString( commaSep, ( *lineIt ).value().toString() );
658 addr.setCategories( categories );
659 }
660 // FBURL
661 else if (identifier == QLatin1String( "fburl" ) ) {
662 CalendarUrl calendarUrl(CalendarUrl::FBUrl);
663 //TODO extract emails
664 addr.insertCalendarUrl(calendarUrl);
665 }
666 // CALADRURI
667 else if (identifier == QLatin1String( "caladruri" ) ) {
668 CalendarUrl calendarUrl(CalendarUrl::CALADRUri);
669 //TODO extract emails
670 addr.insertCalendarUrl(calendarUrl);
671 }
672 // CALURI
673 else if (identifier == QLatin1String( "caluri" ) ) {
674 CalendarUrl calendarUrl(CalendarUrl::CALUri);
675 //TODO extract emails
676 addr.insertCalendarUrl(calendarUrl);
677 }
678
679 // CLASS
680 else if ( identifier == QLatin1String( "class" ) ) {
681 addr.setSecrecy( parseSecrecy( *lineIt ) );
682 }
683
684 // EMAIL
685 else if ( identifier == QLatin1String( "email" ) ) {
686 const QStringList types = ( *lineIt ).parameters( QLatin1String( "type" ) );
687 addr.insertEmail( ( *lineIt ).value().toString(),
688 types.contains( QLatin1String( "PREF" ) ), (*lineIt).parameterMap() );
689 }
690 // GENDER
691 else if ( identifier == QLatin1String( "gender" ) ) {
692 QString genderStr = ( *lineIt ).value().toString();
693 if (!genderStr.isEmpty()) {
694 Gender gender;
695 if (genderStr.at(0) != QLatin1Char(';')) {
696 gender.setGender(genderStr.at(0));
697 if (genderStr.length() > 2) {
698 gender.setComment(genderStr.right(genderStr.length()-2));
699 }
700 } else {
701 gender.setComment(genderStr.right(genderStr.length()-1));
702 }
703 addr.setGender(gender);
704 }
705 }
706
707 // LANG
708 else if ( identifier == QLatin1String( "lang" ) ) {
709 Lang lang;
710 lang.setLanguage(( *lineIt ).value().toString());
711 lang.setParameters((*lineIt).parameterMap());
712 addr.insertLang(lang);
713 }
714 // KIND
715 else if ( identifier == QLatin1String( "kind" ) ) {
716 addr.setKind( ( *lineIt ).value().toString() );
717 }
718 // FN
719 else if ( identifier == QLatin1String( "fn" ) ) {
720 addr.setFormattedName( ( *lineIt ).value().toString() );
721 }
722
723 // GEO
724 else if ( identifier == QLatin1String( "geo" ) ) {
725 Geo geo;
726 QString lineStr = ( *lineIt ).value().toString();
727 if (lineStr.startsWith(QLatin1String("geo:"))) { //VCard 4.0
728 lineStr.remove(QLatin1String("geo:"));
729 const QStringList geoParts =
730 lineStr.split( QLatin1Char( ',' ), QString::KeepEmptyParts );
731 if ( geoParts.size() >= 2 ) {
732 geo.setLatitude( geoParts.at( 0 ).toFloat() );
733 geo.setLongitude( geoParts.at( 1 ).toFloat() );
734 addr.setGeo( geo );
735 }
736 } else {
737 const QStringList geoParts =
738 lineStr.split( QLatin1Char( ';' ), QString::KeepEmptyParts );
739 if ( geoParts.size() >= 2 ) {
740 geo.setLatitude( geoParts.at( 0 ).toFloat() );
741 geo.setLongitude( geoParts.at( 1 ).toFloat() );
742 addr.setGeo( geo );
743 }
744 }
745 }
746
747 // KEY
748 else if ( identifier == QLatin1String( "key" ) ) {
749 addr.insertKey( parseKey( *lineIt ) );
750 }
751
752 // LABEL
753 else if ( identifier == QLatin1String( "label" ) ) {
754 Address::Type type;
755
756 const QStringList types = ( *lineIt ).parameters( QLatin1String( "type" ) );
757 QStringList::ConstIterator end(types.end());
758 for ( QStringList::ConstIterator it = types.begin(); it != end; ++it ) {
759 type |= mAddressTypeMap[ ( *it ).toLower() ];
760 }
761
762 bool available = false;
763 KABC::Address::List addressList = addr.addresses();
764 for ( KABC::Address::List::Iterator it = addressList.begin();
765 it != addressList.end(); ++it ) {
766 if ( ( *it ).type() == type ) {
767 ( *it ).setLabel( ( *lineIt ).value().toString() );
768 addr.insertAddress( *it );
769 available = true;
770 break;
771 }
772 }
773
774 if ( !available ) { // a standalone LABEL tag
775 KABC::Address address( type );
776 address.setLabel( ( *lineIt ).value().toString() );
777 addr.insertAddress( address );
778 }
779 }
780
781 // LOGO
782 else if ( identifier == QLatin1String( "logo" ) ) {
783 Picture picture = parsePicture( *lineIt );
784 if (addr.logo().isEmpty()) {
785 addr.setLogo( picture );
786 } else {
787 addr.insertExtraLogo( picture );
788 }
789 }
790
791 // MAILER
792 else if ( identifier == QLatin1String( "mailer" ) ) {
793 addr.setMailer( ( *lineIt ).value().toString() );
794 }
795
796 // N
797 else if ( identifier == QLatin1String( "n" ) ) {
798 const QStringList nameParts = splitString( semicolonSep, ( *lineIt ).value().toString() );
799 const int numberOfParts( nameParts.count() );
800 if ( numberOfParts > 0 ) {
801 addr.setFamilyName( nameParts.at( 0 ) );
802 }
803 if ( numberOfParts > 1 ) {
804 addr.setGivenName( nameParts.at( 1 ) );
805 }
806 if ( numberOfParts > 2 ) {
807 addr.setAdditionalName( nameParts.at( 2 ) );
808 }
809 if ( numberOfParts > 3 ) {
810 addr.setPrefix( nameParts.at( 3 ) );
811 }
812 if ( numberOfParts > 4 ) {
813 addr.setSuffix( nameParts.at( 4 ) );
814 }
815 if ( !( *lineIt ).parameter( QLatin1String( "sort-as" ) ).isEmpty() ) {
816 addr.setSortString( ( *lineIt ).parameter( QLatin1String( "sort-as" ) ) );
817 }
818 }
819
820 // NAME
821 else if ( identifier == QLatin1String( "name" ) ) {
822 addr.setName( ( *lineIt ).value().toString() );
823 }
824
825 // NICKNAME
826 else if ( identifier == QLatin1String( "nickname" ) ) {
827 addr.setNickName( ( *lineIt ).value().toString() );
828 }
829
830 // NOTE
831 else if ( identifier == QLatin1String( "note" ) ) {
832 addr.setNote( ( *lineIt ).value().toString() );
833 }
834
835 // ORGANIZATION
836 else if ( identifier == QLatin1String( "org" ) ) {
837 const QStringList orgParts = splitString( semicolonSep, ( *lineIt ).value().toString() );
838 if ( orgParts.count() > 0 ) {
839 addr.setOrganization( orgParts.at( 0 ) );
840 }
841 if ( orgParts.count() > 1 ) {
842 addr.setDepartment( orgParts.at( 1 ) );
843 }
844 if ( !( *lineIt ).parameter( QLatin1String( "sort-as" ) ).isEmpty() ) {
845 addr.setSortString( ( *lineIt ).parameter( QLatin1String( "sort-as" ) ) );
846 }
847 }
848
849 // PHOTO
850 else if ( identifier == QLatin1String( "photo" ) ) {
851 Picture picture = parsePicture( *lineIt );
852 if (addr.photo().isEmpty()) {
853 addr.setPhoto( picture );
854 } else {
855 addr.insertExtraPhoto( picture );
856 }
857 }
858
859 // PROID
860 else if ( identifier == QLatin1String( "prodid" ) ) {
861 addr.setProductId( ( *lineIt ).value().toString() );
862 }
863
864 // REV
865 else if ( identifier == QLatin1String( "rev" ) ) {
866 addr.setRevision( parseDateTime( ( *lineIt ).value().toString() ) );
867 }
868
869 // ROLE
870 else if ( identifier == QLatin1String( "role" ) ) {
871 addr.setRole( ( *lineIt ).value().toString() );
872 }
873
874 // SORT-STRING
875 else if ( identifier == QLatin1String( "sort-string" ) ) {
876 addr.setSortString( ( *lineIt ).value().toString() );
877 }
878
879 // SOUND
880 else if ( identifier == QLatin1String( "sound" ) ) {
881 Sound sound = parseSound( *lineIt );
882 if (addr.sound().isEmpty()) {
883 addr.setSound( sound );
884 } else {
885 addr.insertExtraSound(sound);
886 }
887 }
888
889 // TEL
890 else if ( identifier == QLatin1String( "tel" ) ) {
891 PhoneNumber phone;
892 phone.setNumber( ( *lineIt ).value().toString() );
893
894 PhoneNumber::Type type;
895
896 const QStringList types = ( *lineIt ).parameters( QLatin1String( "type" ) );
897 QStringList::ConstIterator typeEnd( types.end() );
898 for ( QStringList::ConstIterator it = types.begin(); it != typeEnd; ++it ) {
899 type |= mPhoneTypeMap[( *it ).toUpper()];
900 }
901
902 phone.setType( type );
903
904 addr.insertPhoneNumber( phone );
905 }
906
907 // TITLE
908 else if ( identifier == QLatin1String( "title" ) ) {
909 addr.setTitle( ( *lineIt ).value().toString() );
910 }
911
912 // TZ
913 else if ( identifier == QLatin1String( "tz" ) ) {
914 TimeZone tz;
915 const QString date = ( *lineIt ).value().toString();
916
917 if ( !date.isEmpty() ) {
918 int hours = date.mid( 1, 2 ).toInt();
919 int minutes = date.mid( 4, 2 ).toInt();
920 int offset = ( hours * 60 ) + minutes;
921 offset = offset * ( date[ 0 ] == QLatin1Char( '+' ) ? 1 : -1 );
922
923 tz.setOffset( offset );
924 addr.setTimeZone( tz );
925 }
926 }
927
928 // UID
929 else if ( identifier == QLatin1String( "uid" ) ) {
930 addr.setUid( ( *lineIt ).value().toString() );
931 }
932
933 // URL
934 else if ( identifier == QLatin1String( "url" ) ) {
935 const KUrl url = KUrl( ( *lineIt ).value().toString() );
936 if (addr.url().isEmpty()) {
937 addr.setUrl( url );
938 } else {
939 addr.insertExtraUrl(url);
940 }
941 }
942 // SOURCE
943 else if ( identifier == QLatin1String( "source" ) ) {
944 const KUrl url = KUrl( ( *lineIt ).value().toString() );
945 addr.insertSourceUrl( url );
946 }
947 // MEMBER (vcard 4.0)
948 else if ( identifier == QLatin1String( "member" ) ) {
949 addr.insertMember( ( *lineIt ).value().toString() );
950 }
951 // RELATED (vcard 4.0)
952 else if ( identifier == QLatin1String( "related" ) ) {
953 addr.insertRelationShip( ( *lineIt ).value().toString() );
954 }
955
956 // X-
957 else if ( identifier.startsWith( QLatin1String( "x-" ) ) ) {
958 QString ident = ( *lineIt ).identifier();
959 //X-Evolution
960 if ( identifier == QLatin1String( "x-evolution-spouse" ) ||
961 identifier == QLatin1String( "x-spouse" ) ) {
962 ident = QLatin1String( "X-KADDRESSBOOK-X-SpousesName" );
963 } else if ( identifier == QLatin1String( "x-evolution-blog-url" ) ) {
964 ident = QLatin1String( "X-KADDRESSBOOK-BlogFeed" );
965 } else if ( identifier == QLatin1String( "x-evolution-assistant" ) ||
966 identifier == QLatin1String( "x-assistant" ) ) {
967 ident = QLatin1String( "X-KADDRESSBOOK-X-AssistantsName" );
968 } else if ( identifier == QLatin1String( "x-evolution-anniversary" ) ||
969 identifier == QLatin1String( "x-anniversary" ) ) {
970 ident = QLatin1String( "X-KADDRESSBOOK-X-Anniversary" );
971 } else if ( identifier == QLatin1String( "x-evolution-manager" ) ||
972 identifier == QLatin1String( "x-manager" ) ) {
973 ident = QLatin1String( "X-KADDRESSBOOK-X-ManagersName" );
974 } else if ( identifier == QLatin1String( "x-aim" ) ) {
975 ident = QLatin1String( "X-messaging/aim-All" );
976 } else if ( identifier == QLatin1String( "x-icq" ) ) {
977 ident = QLatin1String( "X-messaging/icq-All" );
978 } else if ( identifier == QLatin1String( "x-jabber" ) ) {
979 ident = QLatin1String( "X-messaging/xmpp-All" );
980 } else if ( identifier == QLatin1String( "x-jabber" ) ) {
981 ident = QLatin1String( "X-messaging/xmpp-All" );
982 } else if ( identifier == QLatin1String( "x-msn" ) ) {
983 ident = QLatin1String( "X-messaging/msn-All" );
984 } else if ( identifier == QLatin1String( "x-yahoo" ) ) {
985 ident = QLatin1String( "X-messaging/yahoo-All" );
986 } else if ( identifier == QLatin1String( "x-gadugadu" ) ) {
987 ident = QLatin1String( "X-messaging/gadu-All" );
988 } else if ( identifier == QLatin1String( "x-skype" ) ) {
989 ident = QLatin1String( "X-messaging/skype-All" );
990 } else if ( identifier == QLatin1String( "x-groupwise" ) ) {
991 ident = QLatin1String( "X-messaging/groupwise-All" );
992 } else if ( identifier == QLatin1String( "x-sms" ) ) {
993 ident = QLatin1String( "X-messaging/sms-All" );
994 } else if ( identifier == QLatin1String( "x-meanwhile" ) ) {
995 ident = QLatin1String( "X-messaging/meanwhile-All" );
996 } else if ( identifier == QLatin1String( "x-irc" ) ) {
997 ident = QLatin1String( "X-messaging/irc-All" );
998 } else if ( identifier == QLatin1String( "x-gtalk" ) ) {
999 ident = QLatin1String( "X-messaging/googletalk-All" );
1000 }
1001
1002 const QString key = ident.mid( 2 );
1003 const int dash = key.indexOf( QLatin1Char( '-' ) );
1004 addr.insertCustom( key.left( dash ), key.mid( dash + 1 ),
1005 ( *lineIt ).value().toString() );
1006 }
1007 }
1008 }
1009
1010 addrList.append( addr );
1011 }
1012
1013 return addrList;
1014}
1015
1016QDateTime VCardTool::parseDateTime( const QString &str ) const
1017{
1018 QDate date;
1019 QTime time;
1020
1021 if ( str.indexOf( QLatin1Char( '-' ) ) == -1 ) { // is base format (yyyymmdd)
1022 date = QDate( str.left( 4 ).toInt(), str.mid( 4, 2 ).toInt(),
1023 str.mid( 6, 2 ).toInt() );
1024 } else { // is extended format yyyy-mm-dd
1025 date = QDate( str.left( 4 ).toInt(), str.mid( 5, 2 ).toInt(),
1026 str.mid( 8, 2 ).toInt() );
1027 }
1028 // does it also contain a time ? (Note: mm, ss are optional according ISO-8601)
1029 int timeStart = str.indexOf( QLatin1Char( 'T' ) );
1030 if ( timeStart >= 0 ) {
1031 int hour = 0, minute = 0, second = 0;
1032
1033 hour = str.mid( timeStart + 1, 2 ).toInt(); // hour must always be given
1034
1035 if ( str.indexOf( QLatin1Char( ':' ), timeStart + 1 ) > 0 ) { // extended format (hh:mm:ss)
1036 if ( str.length() >= ( timeStart + 5 ) ) {
1037 minute = str.mid( timeStart + 4, 2 ).toInt();
1038 if ( str.length() >= ( timeStart + 8 ) ) {
1039 second = str.mid( timeStart + 7, 2 ).toInt();
1040 }
1041 }
1042 } else { // basic format (hhmmss)
1043 if ( str.length() >= ( timeStart + 4 ) ) {
1044 minute = str.mid( timeStart + 3, 2 ).toInt();
1045 if ( str.length() >= ( timeStart + 6 ) ) {
1046 second = str.mid( timeStart + 5, 2 ).toInt();
1047 }
1048 }
1049 }
1050
1051 time = QTime( hour, minute, second );
1052 }
1053
1054 Qt::TimeSpec spec = ( str.right( 1 ) == QLatin1String( "Z" ) ) ? Qt::UTC : Qt::LocalTime;
1055
1056 QDateTime dateTime( date );
1057
1058 // explicitly set the time, which might be invalid, to keep the information
1059 // that the time is invalid. In createDateTime() the time/invalid flag is
1060 // checked which omits then to print the timestamp
1061 // This is needed to reproduce the given string in input
1062 // e.g. BDAY:2008-12-30
1063 // without time shall also result in a string without a time
1064 dateTime.setTime( time );
1065
1066 dateTime.setTimeSpec( spec );
1067 return dateTime;
1068}
1069
1070QString VCardTool::createDateTime( const QDateTime &dateTime ) const
1071{
1072 QString str;
1073
1074 if ( dateTime.date().isValid() ) {
1075 str.sprintf( "%4d-%02d-%02d", dateTime.date().year(), dateTime.date().month(),
1076 dateTime.date().day() );
1077 if ( dateTime.time().isValid() ) {
1078 QString tmp;
1079 tmp.sprintf( "T%02d:%02d:%02d", dateTime.time().hour(), dateTime.time().minute(),
1080 dateTime.time().second() );
1081 str += tmp;
1082
1083 if ( dateTime.timeSpec() == Qt::UTC ) {
1084 str += QLatin1Char( 'Z' );
1085 }
1086 }
1087 }
1088
1089 return str;
1090}
1091
1092Picture VCardTool::parsePicture( const VCardLine &line ) const
1093{
1094 Picture pic;
1095
1096 const QStringList params = line.parameterList();
1097 QString type;
1098 if ( params.contains( QLatin1String( "type" ) ) ) {
1099 type = line.parameter( QLatin1String( "type" ) );
1100 }
1101 if ( params.contains( QLatin1String( "encoding" ) ) ) {
1102 pic.setRawData( line.value().toByteArray(), type );
1103 } else if ( params.contains( QLatin1String( "value" ) ) ) {
1104 if ( line.parameter( QLatin1String( "value" ) ).toLower() == QLatin1String( "uri" ) ) {
1105 pic.setUrl( line.value().toString() );
1106 }
1107 }
1108
1109 return pic;
1110}
1111
1112VCardLine VCardTool::createPicture( const QString &identifier, const Picture &pic, VCard::Version version ) const
1113{
1114 VCardLine line( identifier );
1115
1116 if ( pic.isEmpty() ) {
1117 return line;
1118 }
1119
1120 if ( pic.isIntern() ) {
1121 line.setValue( pic.rawData() );
1122 if (version == VCard::v2_1) {
1123 line.addParameter( QLatin1String( "ENCODING" ), QLatin1String( "BASE64" ) );
1124 line.addParameter( pic.type(), QString() );
1125 } else {
1126 line.addParameter( QLatin1String( "encoding" ), QLatin1String( "b" ) );
1127 line.addParameter( QLatin1String( "type" ), pic.type() );
1128 }
1129 } else {
1130 line.setValue( pic.url() );
1131 line.addParameter( QLatin1String( "value" ), QLatin1String( "URI" ) );
1132 }
1133
1134 return line;
1135}
1136
1137Sound VCardTool::parseSound( const VCardLine &line ) const
1138{
1139 Sound snd;
1140
1141 const QStringList params = line.parameterList();
1142 if ( params.contains( QLatin1String( "encoding" ) ) ) {
1143 snd.setData( line.value().toByteArray() );
1144 } else if ( params.contains( QLatin1String( "value" ) ) ) {
1145 if ( line.parameter( QLatin1String( "value" ) ).toLower() == QLatin1String( "uri" ) ) {
1146 snd.setUrl( line.value().toString() );
1147 }
1148 }
1149
1150/* TODO: support sound types
1151 if ( params.contains( "type" ) )
1152 snd.setType( line.parameter( "type" ) );
1153*/
1154
1155 return snd;
1156}
1157
1158VCardLine VCardTool::createSound( const Sound &snd, VCard::Version version ) const
1159{
1160 VCardLine line( QLatin1String( "SOUND" ) );
1161
1162 if ( snd.isIntern() ) {
1163 if ( !snd.data().isEmpty() ) {
1164 line.setValue( snd.data() );
1165 if (version == VCard::v2_1) {
1166 line.addParameter( QLatin1String( "ENCODING" ), QLatin1String( "BASE64" ) );
1167 } else {
1168 line.addParameter( QLatin1String( "encoding" ), QLatin1String( "b" ) );
1169 }
1170 // TODO: need to store sound type!!!
1171 }
1172 } else if ( !snd.url().isEmpty() ) {
1173 line.setValue( snd.url() );
1174 line.addParameter( QLatin1String( "value" ), QLatin1String( "URI" ) );
1175 }
1176
1177 return line;
1178}
1179
1180Key VCardTool::parseKey( const VCardLine &line ) const
1181{
1182 Key key;
1183
1184 const QStringList params = line.parameterList();
1185 if ( params.contains( QLatin1String( "encoding" ) ) ) {
1186 key.setBinaryData( line.value().toByteArray() );
1187 } else {
1188 key.setTextData( line.value().toString() );
1189 }
1190
1191 if ( params.contains( QLatin1String( "type" ) ) ) {
1192 if ( line.parameter( QLatin1String( "type" ) ).toLower() == QLatin1String( "x509" ) ) {
1193 key.setType( Key::X509 );
1194 } else if ( line.parameter( QLatin1String( "type" ) ).toLower() == QLatin1String( "pgp" ) ) {
1195 key.setType( Key::PGP );
1196 } else {
1197 key.setType( Key::Custom );
1198 key.setCustomTypeString( line.parameter( QLatin1String( "type" ) ) );
1199 }
1200 }
1201
1202 return key;
1203}
1204
1205VCardLine VCardTool::createKey( const Key &key, VCard::Version version ) const
1206{
1207 Q_UNUSED(version);
1208 VCardLine line( QLatin1String( "KEY" ) );
1209
1210 if ( key.isBinary() ) {
1211 if ( !key.binaryData().isEmpty() ) {
1212 line.setValue( key.binaryData() );
1213 if (version == VCard::v2_1)
1214 line.addParameter( QLatin1String( "ENCODING" ), QLatin1String( "BASE64" ) );
1215 else
1216 line.addParameter( QLatin1String( "encoding" ), QLatin1String( "b" ) );
1217 }
1218 } else if ( !key.textData().isEmpty() ) {
1219 line.setValue( key.textData() );
1220 }
1221
1222 if ( key.type() == Key::X509 ) {
1223 line.addParameter( QLatin1String( "type" ), QLatin1String( "X509" ) );
1224 } else if ( key.type() == Key::PGP ) {
1225 line.addParameter( QLatin1String( "type" ), QLatin1String( "PGP" ) );
1226 } else if ( key.type() == Key::Custom ) {
1227 line.addParameter( QLatin1String( "type" ), key.customTypeString() );
1228 }
1229
1230 return line;
1231}
1232
1233Secrecy VCardTool::parseSecrecy( const VCardLine &line ) const
1234{
1235 Secrecy secrecy;
1236
1237 const QString value = line.value().toString().toLower();
1238 if ( value == QLatin1String( "public" ) ) {
1239 secrecy.setType( Secrecy::Public );
1240 } else if ( value == QLatin1String( "private" ) ) {
1241 secrecy.setType( Secrecy::Private );
1242 } else if ( value == QLatin1String( "confidential" ) ) {
1243 secrecy.setType( Secrecy::Confidential );
1244 }
1245
1246 return secrecy;
1247}
1248
1249VCardLine VCardTool::createSecrecy( const Secrecy &secrecy ) const
1250{
1251 VCardLine line( QLatin1String( "CLASS" ) );
1252
1253 int type = secrecy.type();
1254
1255 if ( type == Secrecy::Public ) {
1256 line.setValue( QLatin1String( "PUBLIC" ) );
1257 } else if ( type == Secrecy::Private ) {
1258 line.setValue( QLatin1String( "PRIVATE" ) );
1259 } else if ( type == Secrecy::Confidential ) {
1260 line.setValue( QLatin1String( "CONFIDENTIAL" ) );
1261 }
1262
1263 return line;
1264}
1265
1266QStringList VCardTool::splitString( const QChar &sep, const QString &str ) const
1267{
1268 QStringList list;
1269 QString value( str );
1270
1271 int start = 0;
1272 int pos = value.indexOf( sep, start );
1273
1274 while ( pos != -1 ) {
1275 if ( pos == 0 || value[ pos - 1 ] != QLatin1Char( '\\' ) ) {
1276 if ( pos > start && pos <= (int)value.length() ) {
1277 list << value.mid( start, pos - start );
1278 } else {
1279 list << QString();
1280 }
1281
1282 start = pos + 1;
1283 pos = value.indexOf( sep, start );
1284 } else {
1285 value.replace( pos - 1, 2, sep );
1286 pos = value.indexOf( sep, pos );
1287 }
1288 }
1289
1290 int l = value.length() - 1;
1291 if ( value.mid( start, l - start + 1 ).length() > 0 ) {
1292 list << value.mid( start, l - start + 1 );
1293 } else {
1294 list << QString();
1295 }
1296
1297 return list;
1298}
KABC::Address
Postal address information.
Definition address.h:38
KABC::Address::setType
void setType(Type type)
Sets the type of address.
Definition address.cpp:322
KABC::Address::setStreet
void setStreet(const QString &street)
Sets the street (including house number).
Definition address.cpp:388
KABC::Address::Pref
@ Pref
preferred address
Definition address.h:58
KABC::Address::Parcel
@ Parcel
parcel
Definition address.h:55
KABC::Address::Work
@ Work
address at work
Definition address.h:57
KABC::Address::Dom
@ Dom
domestic
Definition address.h:52
KABC::Address::Home
@ Home
home address
Definition address.h:56
KABC::Address::Intl
@ Intl
international
Definition address.h:53
KABC::Address::Postal
@ Postal
postal
Definition address.h:54
KABC::Address::setCountry
void setCountry(const QString &country)
Sets the country.
Definition address.cpp:452
KABC::Address::setPostOfficeBox
void setPostOfficeBox(const QString &postOfficeBox)
Sets the post office box.
Definition address.cpp:356
KABC::Address::setRegion
void setRegion(const QString &region)
Sets the region, e.g.
Definition address.cpp:420
KABC::Address::setExtended
void setExtended(const QString &extended)
Sets the extended address information.
Definition address.cpp:372
KABC::Address::List
QList< Address > List
List of addresses.
Definition address.h:46
KABC::Address::setPostalCode
void setPostalCode(const QString &code)
Sets the postal code.
Definition address.cpp:436
KABC::Address::setLocality
void setLocality(const QString &locality)
Sets the locality, e.g.
Definition address.cpp:404
KABC::Address::setLabel
void setLabel(const QString &label)
Sets the delivery label.
Definition address.cpp:468
KABC::AddresseeList
a QValueList of Addressee, with sorting functionality
Definition addresseelist.h:289
KABC::Addressee
address book entry
Definition addressee.h:79
KABC::Addressee::setMailer
void setMailer(const QString &mailer)
Set mail client.
Definition addressee.cpp:868
KABC::Addressee::setLogo
void setLogo(const Picture &logo)
Set logo.
Definition addressee.cpp:1128
KABC::Addressee::setAdditionalName
void setAdditionalName(const QString &additionalName)
Set additional names.
Definition addressee.cpp:630
KABC::Addressee::setSecrecy
void setSecrecy(const Secrecy &secrecy)
Set security class.
Definition addressee.cpp:1108
KABC::Addressee::setBirthday
void setBirthday(const QDateTime &birthday)
Set birthday.
Definition addressee.cpp:710
KABC::Addressee::setOrganization
void setOrganization(const QString &organization)
Set organization.
Definition addressee.cpp:968
KABC::Addressee::insertPhoneNumber
void insertPhoneNumber(const PhoneNumber &phoneNumber)
Insert a phone number.
Definition addressee.cpp:1525
KABC::Addressee::setPrefix
void setPrefix(const QString &prefix)
Set honorific prefixes.
Definition addressee.cpp:650
KABC::Addressee::insertCustom
void insertCustom(const QString &app, const QString &name, const QString &value)
Insert custom entry.
Definition addressee.cpp:1928
KABC::Addressee::setProductId
void setProductId(const QString &productId)
Set product identifier.
Definition addressee.cpp:1028
KABC::Addressee::url
KUrl url() const
Return homepage.
Definition addressee.cpp:1097
KABC::Addressee::setRevision
void setRevision(const QDateTime &revision)
Set revision date.
Definition addressee.cpp:1048
KABC::Addressee::setSuffix
void setSuffix(const QString &suffix)
Set honorific suffixes.
Definition addressee.cpp:670
KABC::Addressee::sound
Sound sound() const
Return sound.
Definition addressee.cpp:1177
KABC::Addressee::photo
Picture photo() const
Return photo.
Definition addressee.cpp:1157
KABC::Addressee::setGivenName
void setGivenName(const QString &givenName)
Set given name.
Definition addressee.cpp:610
KABC::Addressee::setNickName
void setNickName(const QString &nickName)
Set nick name.
Definition addressee.cpp:690
KABC::Addressee::setDepartment
void setDepartment(const QString &department)
Set department.
Definition addressee.cpp:988
KABC::Addressee::insertEmail
void insertEmail(const QString &email, bool preferred=false)
Insert an email address.
Definition addressee.cpp:1420
KABC::Addressee::setSound
void setSound(const Sound &sound)
Set sound.
Definition addressee.cpp:1168
KABC::Addressee::setCategories
void setCategories(const QStringList &)
Set categories to given value.
Definition addressee.cpp:1916
KABC::Addressee::setTimeZone
void setTimeZone(const TimeZone &timeZone)
Set time zone.
Definition addressee.cpp:888
KABC::Addressee::logo
Picture logo() const
Return logo.
Definition addressee.cpp:1137
KABC::Addressee::setNote
void setNote(const QString &note)
Set note.
Definition addressee.cpp:1008
KABC::Addressee::setPhoto
void setPhoto(const Picture &photo)
Set photo.
Definition addressee.cpp:1148
KABC::Addressee::setName
void setName(const QString &name)
Set name.
Definition addressee.cpp:452
KABC::Addressee::insertAddress
void insertAddress(const Address &address)
Insert an address.
Definition addressee.cpp:1773
KABC::Addressee::addresses
Address::List addresses() const
Return list of all addresses.
Definition addressee.cpp:1820
KABC::Addressee::insertKey
void insertKey(const Key &key)
Insert a key.
Definition addressee.cpp:1599
KABC::Addressee::setRole
void setRole(const QString &role)
Set role.
Definition addressee.cpp:948
KABC::Addressee::setUrl
void setUrl(const KUrl &url)
Set homepage.
Definition addressee.cpp:1088
KABC::Addressee::setFormattedName
void setFormattedName(const QString &formattedName)
Set formatted name.
Definition addressee.cpp:570
KABC::Addressee::setFamilyName
void setFamilyName(const QString &familyName)
Set family name.
Definition addressee.cpp:590
KABC::Addressee::setTitle
void setTitle(const QString &title)
Set title.
Definition addressee.cpp:928
KABC::Addressee::setUid
void setUid(const QString &uid)
Set unique identifier.
Definition addressee.cpp:433
KABC::Addressee::setGeo
void setGeo(const Geo &geo)
Set geographic position.
Definition addressee.cpp:908
KABC::Addressee::setSortString
void setSortString(const QString &sortString)
Set sort string.
Definition addressee.cpp:1068
KABC::Geo
Geographic position.
Definition geo.h:36
KABC::Geo::isValid
bool isValid() const
Returns, whether this object contains a valid geographical position.
Definition geo.cpp:106
KABC::Geo::setLatitude
void setLatitude(float latitude)
Sets the latitude.
Definition geo.cpp:74
KABC::Geo::longitude
float longitude() const
Returns the longitude.
Definition geo.cpp:101
KABC::Geo::latitude
float latitude() const
Returns the latitude.
Definition geo.cpp:85
KABC::Geo::toString
QString toString() const
Returns string representation of geographical position.
Definition geo.cpp:142
KABC::Geo::setLongitude
void setLongitude(float longitude)
Sets the longitude.
Definition geo.cpp:90
KABC::Key
A class to store an encryption key.
Definition key.h:35
KABC::Key::type
Type type() const
Returns the type, see Type.
Definition key.cpp:168
KABC::Key::isBinary
bool isBinary() const
Returns whether the key contains binary or text data.
Definition key.cpp:153
KABC::Key::X509
@ X509
X509 key.
Definition key.h:49
KABC::Key::PGP
@ PGP
Pretty Good Privacy key.
Definition key.h:50
KABC::Key::Custom
@ Custom
Custom or IANA conform key.
Definition key.h:51
KABC::Key::setCustomTypeString
void setCustomTypeString(const QString &type)
Sets custom type string.
Definition key.cpp:163
KABC::Key::binaryData
QByteArray binaryData() const
Returns the binary data.
Definition key.cpp:137
KABC::Key::customTypeString
QString customTypeString() const
Returns the custom type string.
Definition key.cpp:173
KABC::Key::List
QList< Key > List
List of keys.
Definition key.h:43
KABC::Key::setBinaryData
void setBinaryData(const QByteArray &data)
Sets binary data.
Definition key.cpp:131
KABC::Key::setType
void setType(Type type)
Sets the type.
Definition key.cpp:158
KABC::Key::setTextData
void setTextData(const QString &data)
Sets text data.
Definition key.cpp:142
KABC::Key::textData
QString textData() const
Returns the text data.
Definition key.cpp:148
KABC::PhoneNumber
Phonenumber information.
Definition phonenumber.h:39
KABC::PhoneNumber::setType
void setType(Type type)
Sets the type.
Definition phonenumber.cpp:133
KABC::PhoneNumber::setNumber
void setNumber(const QString &number)
Sets the phone number.
Definition phonenumber.cpp:123
KABC::PhoneNumber::Bbs
@ Bbs
Mailbox.
Definition phonenumber.h:56
KABC::PhoneNumber::Pref
@ Pref
Preferred number.
Definition phonenumber.h:51
KABC::PhoneNumber::Fax
@ Fax
Fax machine.
Definition phonenumber.h:53
KABC::PhoneNumber::Work
@ Work
Office number.
Definition phonenumber.h:49
KABC::PhoneNumber::Voice
@ Voice
Voice.
Definition phonenumber.h:52
KABC::PhoneNumber::Cell
@ Cell
Cell phone.
Definition phonenumber.h:54
KABC::PhoneNumber::Car
@ Car
Car phone.
Definition phonenumber.h:58
KABC::PhoneNumber::Isdn
@ Isdn
ISDN connection.
Definition phonenumber.h:59
KABC::PhoneNumber::Video
@ Video
Video phone.
Definition phonenumber.h:55
KABC::PhoneNumber::Modem
@ Modem
Modem.
Definition phonenumber.h:57
KABC::PhoneNumber::Pcs
@ Pcs
Personal Communication Service.
Definition phonenumber.h:60
KABC::PhoneNumber::Home
@ Home
Home number.
Definition phonenumber.h:48
KABC::PhoneNumber::Pager
@ Pager
Pager.
Definition phonenumber.h:61
KABC::PhoneNumber::Msg
@ Msg
Messaging.
Definition phonenumber.h:50
KABC::PhoneNumber::List
QList< PhoneNumber > List
List of phone numbers.
Definition phonenumber.h:74
KABC::Picture
A class to store a picture of an addressee.
Definition picture.h:40
KABC::Picture::setUrl
void setUrl(const QString &url)
Sets a URL for the location of the picture file.
Definition picture.cpp:143
KABC::Picture::isIntern
bool isIntern() const
Returns whether the picture is described by a URL (extern) or by the raw data (intern).
Definition picture.cpp:184
KABC::Picture::setRawData
void setRawData(const QByteArray &rawData, const QString &type)
Sets the raw data of the picture.
Definition picture.cpp:171
KABC::Picture::isEmpty
bool isEmpty() const
Returns true, if the picture is empty.
Definition picture.cpp:136
KABC::Picture::rawData
QByteArray rawData() const
Returns the raw data of this picture.
Definition picture.cpp:203
KABC::Picture::type
QString type() const
Returns the type of this picture.
Definition picture.cpp:216
KABC::Picture::url
QString url() const
Returns the location URL of this picture.
Definition picture.cpp:189
KABC::Sound
Class that holds a Sound clip for a contact.
Definition sound.h:59
KABC::Sound::data
QByteArray data() const
Returns the raw data of this sound.
Definition sound.cpp:138
KABC::Sound::setData
void setData(const QByteArray &data)
Sets the raw data of the sound.
Definition sound.cpp:116
KABC::Sound::url
QString url() const
Returns the location URL of this sound.
Definition sound.cpp:133
KABC::Sound::setUrl
void setUrl(const QString &url)
Sets a URL for the location of the sound file.
Definition sound.cpp:110
KABC::Sound::isIntern
bool isIntern() const
Returns whether the sound is described by a URL (extern) or by the raw data (intern).
Definition sound.cpp:122
KABC::Sound::isEmpty
bool isEmpty() const
Returns true, if the sound object is empty.
Definition sound.cpp:127
KABC::TimeZone
Time zone information.
Definition timezone.h:36
KABC::TimeZone::setOffset
void setOffset(int offset)
Set time zone offset relative to UTC.
Definition timezone.cpp:66
KABC::TimeZone::offset
int offset() const
Return offset in minutes relative to UTC.
Definition timezone.cpp:72
KABC::TimeZone::toString
QString toString() const
Return string representation of time zone offset.
Definition timezone.cpp:113
KABC::TimeZone::isValid
bool isValid() const
Return, if this time zone object is valid.
Definition timezone.cpp:77
KABC
Class that holds a Calendar Url (FBURL/CALADRURI/CALURI)
Definition address.h:29
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Wed Jan 24 2024 00:00:00 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kabc

Skip menu "kabc"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • Related Pages

kdepimlibs-4.14.10 API Reference

Skip menu "kdepimlibs-4.14.10 API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal