22 #include "vcardtool.h"
30 #include <QtCore/QString>
31 #include <QtCore/QBuffer>
36 static bool needsEncoding(
const QString &value )
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 !=
'=' ) {
49 VCardTool::VCardTool()
51 mAddressTypeMap.insert( QLatin1String(
"dom" ),
Address::Dom );
52 mAddressTypeMap.insert( QLatin1String(
"intl" ),
Address::Intl );
55 mAddressTypeMap.insert( QLatin1String(
"home" ),
Address::Home );
56 mAddressTypeMap.insert( QLatin1String(
"work" ),
Address::Work );
57 mAddressTypeMap.insert( QLatin1String(
"pref" ),
Address::Pref );
75 VCardTool::~VCardTool()
79 QByteArray VCardTool::exportVCards(
const Addressee::List &list, VCard::Version version )
const
81 return createVCards( list, version,
true );
84 QByteArray VCardTool::createVCards(
const Addressee::List &list, VCard::Version version )
const
86 return createVCards( list, version,
false );
89 void VCardTool::addParameter(VCardLine &line, VCard::Version version,
const QString &key,
const QStringList &valueStringList)
const
91 if (version == VCard::v2_1) {
92 Q_FOREACH(
const QString &valueStr, valueStringList) {
93 line.addParameter( valueStr, QString() );
96 line.addParameter( key, valueStringList.join(QLatin1String(
",")) );
101 VCard::Version version,
bool exportVcard )
const
103 VCard::List vCardList;
105 Addressee::List::ConstIterator addrIt;
106 Addressee::List::ConstIterator listEnd( list.constEnd() );
107 for ( addrIt = list.constBegin(); addrIt != listEnd; ++addrIt ) {
109 QStringList::ConstIterator strIt;
113 for ( Address::List::ConstIterator it = addresses.begin(); it != addresses.end(); ++it ) {
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() );
124 address.append( ( *it ).postOfficeBox().replace( QLatin1Char(
';' ),
125 QLatin1String(
"\\;" ) ) );
127 address.append( ( *it ).extended().replace( QLatin1Char(
';' ),
128 QLatin1String(
"\\;" ) ) );
130 address.append( ( *it ).street().replace( QLatin1Char(
';' ),
131 QLatin1String(
"\\;" ) ) );
133 address.append( ( *it ).locality().replace( QLatin1Char(
';' ),
134 QLatin1String(
"\\;" ) ) );
136 address.append( ( *it ).region().replace( QLatin1Char(
';' ),
137 QLatin1String(
"\\;" ) ) );
139 address.append( ( *it ).postalCode().replace( QLatin1Char(
';' ),
140 QLatin1String(
"\\;" ) ) );
142 address.append( ( *it ).country().replace( QLatin1Char(
';' ),
143 QLatin1String(
"\\;" ) ) );
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" ) );
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" ) );
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());
164 addParameter(labelLine, version, QLatin1String(
"TYPE" ), QStringList()<<typeIt.key());
170 card.addLine( adrLine );
173 card.addLine( labelLine );
178 card.addLine( VCardLine( QLatin1String(
"BDAY" ), createDateTime( ( *addrIt ).birthday() ) ) );
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(
"\\," ) );
192 VCardLine catLine( QLatin1String(
"CATEGORIES" ), categories.join( QLatin1String(
"," ) ) );
193 card.addLine( catLine );
198 if ( version == VCard::v4_0) {
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 );
209 Q_FOREACH (
const KUrl &url, ( *addrIt ).sourcesUrlList()) {
210 VCardLine line = VCardLine( QLatin1String(
"SOURCE" ), url.url() );
211 card.addLine( line );
215 if (version == VCard::v4_0) {
216 Q_FOREACH (
const QString &relation, ( *addrIt ).relationShips() ) {
217 VCardLine line( QLatin1String(
"RELATED" ), relation );
218 card.addLine( line );
222 if ( version == VCard::v3_0 ) {
223 card.addLine( createSecrecy( ( *addrIt ).secrecy() ) );
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()) {
236 line.addParameter( i.key(), i.value().join(QLatin1String(
",")) );
238 card.addLine( line );
242 const Email::List emailList = ( *addrIt ).emailList();
243 Email::List::ConstIterator emailIt;
244 Email::List::ConstIterator emailEnd( emailList.end() );
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;
254 QMapIterator<QString, QStringList> i((*emailIt).parameters());
255 bool foundType =
false;
256 while (i.hasNext()) {
258 QStringList valueStringList = i.value();
259 if (i.key().toLower() == QLatin1String(
"type" )) {
260 if (!valueStringList.contains(QLatin1String(
"PREF"))) {
262 valueStringList.append(QLatin1String(
"PREF" ));
264 needToAddPref =
false;
267 if (!needToAddPref) {
268 valueStringList.removeAll(QLatin1String(
"PREF" ));
273 if (!valueStringList.isEmpty()) {
274 if (i.key().toLower() == QLatin1String(
"type" )) {
275 addParameter(line, version, i.key(), valueStringList);
277 line.addParameter( i.key(), valueStringList.join(QLatin1String(
",")) );
281 if (!foundType && needToAddPref) {
282 if (version == VCard::v2_1) {
283 line.addParameter( QLatin1String(
"PREF" ), QString() );
285 line.addParameter( QLatin1String(
"TYPE" ), QLatin1String(
"PREF" ) );
288 card.addLine( line );
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" ) );
297 card.addLine( fnLine );
300 const Geo geo = ( *addrIt ).geo();
303 if (version == VCard::v4_0 ) {
308 card.addLine( VCardLine( QLatin1String(
"GEO" ), str ) );
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 ) );
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 ) );
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" ) );
332 card.addLine( mailerLine );
337 name.append( ( *addrIt ).familyName().replace( QLatin1Char(
';' ),
338 QLatin1String(
"\\;" ) ) );
340 name.append( ( *addrIt ).givenName().replace( QLatin1Char(
';' ),
341 QLatin1String(
"\\;" ) ) );
343 name.append( ( *addrIt ).additionalName().replace( QLatin1Char(
';' ),
344 QLatin1String(
"\\;" ) ) );
346 name.append( ( *addrIt ).prefix().replace( QLatin1Char(
';' ),
347 QLatin1String(
"\\;" ) ) );
349 name.append( ( *addrIt ).suffix().replace( QLatin1Char(
';' ),
350 QLatin1String(
"\\;" ) ) );
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" ) );
357 if ( version == VCard::v4_0 && !( *addrIt ).sortString().isEmpty() ) {
358 nLine.addParameter( QLatin1String(
"SORT-AS" ), ( *addrIt ).sortString() );
361 card.addLine( nLine );
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" ) );
370 card.addLine( nameLine );
374 if ( version != VCard::v2_1 ) {
375 card.addLine( VCardLine( QLatin1String(
"NICKNAME" ), ( *addrIt ).nickName() ) );
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" ) );
384 card.addLine( noteLine );
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(
"\\;" ) ) );
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" ) );
399 card.addLine( orgLine );
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 ) );
408 if ( version != VCard::v2_1 ) {
409 card.addLine( VCardLine( QLatin1String(
"PRODID" ), ( *addrIt ).productId() ) );
413 card.addLine( VCardLine( QLatin1String(
"REV" ), createDateTime( ( *addrIt ).revision() ) ) );
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" ) );
421 card.addLine( roleLine );
424 if ( version == VCard::v3_0 ) {
425 card.addLine( VCardLine( QLatin1String(
"SORT-STRING" ), ( *addrIt ).sortString() ) );
429 card.addLine( createSound( ( *addrIt ).sound(), version ) );
430 Q_FOREACH (
const KABC::Sound &sound, ( *addrIt ).extraSoundList()) {
431 card.addLine( createSound( sound, version ) );
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() );
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());
449 card.addLine( line );
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" ) );
458 card.addLine( titleLine );
462 const TimeZone timeZone = ( *addrIt ).timeZone();
467 if ( timeZone.
offset() < 0 ) {
471 str.sprintf(
"%c%02d:%02d", ( timeZone.
offset() >= 0 ?
'+' :
'-' ),
472 ( timeZone.
offset() / 60 ) * neg,
473 ( timeZone.
offset() % 60 ) * neg );
475 card.addLine( VCardLine( QLatin1String(
"TZ" ), str ) );
479 card.addLine( VCardLine( QLatin1String(
"UID" ), ( *addrIt ).uid() ) );
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 );
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" ) ) );
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() ) {
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" );
530 }
else if ( identifier == QLatin1String(
"X-messaging/googletalk-All" ) ) {
532 identifier = QLatin1String(
"X-GTALK" );
536 if (version == VCard::v4_0) {
538 const Gender gender = ( *addrIt ).gender();
539 if (gender.isValid()) {
541 if (!gender.gender().isEmpty()) {
542 genderStr = gender.gender();
544 if (!gender.comment().isEmpty()) {
545 genderStr += QLatin1Char(
';') + gender.comment();
547 VCardLine line( QLatin1String(
"GENDER" ), genderStr );
548 card.addLine( line );
551 if (!( *addrIt ).kind().isEmpty()) {
552 VCardLine line( QLatin1String(
"KIND" ), ( *addrIt ).kind() );
556 if (identifier.toLower() == QLatin1String(
"x-kaddressbook-x-anniversary" ) && version == VCard::v4_0) {
558 if (!value.isEmpty()) {
559 const QDate date = QDate::fromString( value, Qt::ISODate );
560 QDateTime dt = QDateTime(date);
562 card.addLine( VCardLine( QLatin1String(
"ANNIVERSARY" ), createDateTime( dt ) ) );
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" ) );
570 card.addLine( line );
574 vCardList.append( card );
577 return VCardParser::createVCards( vCardList );
580 Addressee::List VCardTool::parseVCards(
const QByteArray &vcard )
const
582 static const QLatin1Char semicolonSep(
';' );
583 static const QLatin1Char commaSep(
',' );
587 const VCard::List vCardList = VCardParser::parseVCards( vcard );
589 VCard::List::ConstIterator cardIt;
590 VCard::List::ConstIterator listEnd( vCardList.end() );
591 for ( cardIt = vCardList.begin(); cardIt != listEnd; ++cardIt ) {
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;
602 for ( lineIt = lines.begin(); lineIt != lines.end(); ++lineIt ) {
603 identifier = ( *lineIt ).identifier().toLower();
605 if ( identifier == QLatin1String(
"adr" ) ) {
607 const QStringList addrParts = splitString( semicolonSep, ( *lineIt ).value().toString() );
608 if ( addrParts.count() > 0 ) {
611 if ( addrParts.count() > 1 ) {
614 if ( addrParts.count() > 2 ) {
617 if ( addrParts.count() > 3 ) {
620 if ( addrParts.count() > 4 ) {
623 if ( addrParts.count() > 5 ) {
626 if ( addrParts.count() > 6 ) {
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() ];
639 if ( !( *lineIt ).parameter( QLatin1String(
"label" ) ).isEmpty() ) {
640 address.
setLabel( ( *lineIt ).parameter( QLatin1String(
"label" ) ) );
646 else if ( identifier == QLatin1String(
"bday" ) ) {
647 addr.
setBirthday( parseDateTime( ( *lineIt ).value().toString() ) );
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) );
656 else if ( identifier == QLatin1String(
"categories" ) ) {
657 const QStringList categories = splitString( commaSep, ( *lineIt ).value().toString() );
661 else if (identifier == QLatin1String(
"fburl" ) ) {
662 CalendarUrl calendarUrl(CalendarUrl::FBUrl);
664 addr.insertCalendarUrl(calendarUrl);
667 else if (identifier == QLatin1String(
"caladruri" ) ) {
668 CalendarUrl calendarUrl(CalendarUrl::CALADRUri);
670 addr.insertCalendarUrl(calendarUrl);
673 else if (identifier == QLatin1String(
"caluri" ) ) {
674 CalendarUrl calendarUrl(CalendarUrl::CALUri);
676 addr.insertCalendarUrl(calendarUrl);
680 else if ( identifier == QLatin1String(
"class" ) ) {
685 else if ( identifier == QLatin1String(
"email" ) ) {
686 const QStringList types = ( *lineIt ).parameters( QLatin1String(
"type" ) );
688 types.contains( QLatin1String(
"PREF" ) ), (*lineIt).parameterMap() );
691 else if ( identifier == QLatin1String(
"gender" ) ) {
692 QString genderStr = ( *lineIt ).value().toString();
693 if (!genderStr.isEmpty()) {
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));
701 gender.setComment(genderStr.right(genderStr.length()-1));
703 addr.setGender(gender);
708 else if ( identifier == QLatin1String(
"lang" ) ) {
710 lang.setLanguage(( *lineIt ).value().toString());
711 lang.setParameters((*lineIt).parameterMap());
712 addr.insertLang(lang);
715 else if ( identifier == QLatin1String(
"kind" ) ) {
716 addr.setKind( ( *lineIt ).value().toString() );
719 else if ( identifier == QLatin1String(
"fn" ) ) {
724 else if ( identifier == QLatin1String(
"geo" ) ) {
726 QString lineStr = ( *lineIt ).value().
toString();
727 if (lineStr.startsWith(QLatin1String(
"geo:"))) {
728 lineStr.remove(QLatin1String(
"geo:"));
729 const QStringList geoParts =
730 lineStr.split( QLatin1Char(
',' ), QString::KeepEmptyParts );
731 if ( geoParts.size() >= 2 ) {
737 const QStringList geoParts =
738 lineStr.split( QLatin1Char(
';' ), QString::KeepEmptyParts );
739 if ( geoParts.size() >= 2 ) {
748 else if ( identifier == QLatin1String(
"key" ) ) {
753 else if ( identifier == QLatin1String(
"label" ) ) {
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() ];
762 bool available =
false;
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() );
776 address.
setLabel( ( *lineIt ).value().toString() );
782 else if ( identifier == QLatin1String(
"logo" ) ) {
783 Picture picture = parsePicture( *lineIt );
787 addr.insertExtraLogo( picture );
792 else if ( identifier == QLatin1String(
"mailer" ) ) {
793 addr.
setMailer( ( *lineIt ).value().toString() );
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 ) {
803 if ( numberOfParts > 1 ) {
806 if ( numberOfParts > 2 ) {
809 if ( numberOfParts > 3 ) {
812 if ( numberOfParts > 4 ) {
815 if ( !( *lineIt ).parameter( QLatin1String(
"sort-as" ) ).isEmpty() ) {
816 addr.
setSortString( ( *lineIt ).parameter( QLatin1String(
"sort-as" ) ) );
821 else if ( identifier == QLatin1String(
"name" ) ) {
822 addr.
setName( ( *lineIt ).value().toString() );
826 else if ( identifier == QLatin1String(
"nickname" ) ) {
827 addr.
setNickName( ( *lineIt ).value().toString() );
831 else if ( identifier == QLatin1String(
"note" ) ) {
832 addr.
setNote( ( *lineIt ).value().toString() );
836 else if ( identifier == QLatin1String(
"org" ) ) {
837 const QStringList orgParts = splitString( semicolonSep, ( *lineIt ).value().toString() );
838 if ( orgParts.count() > 0 ) {
841 if ( orgParts.count() > 1 ) {
844 if ( !( *lineIt ).parameter( QLatin1String(
"sort-as" ) ).isEmpty() ) {
845 addr.
setSortString( ( *lineIt ).parameter( QLatin1String(
"sort-as" ) ) );
850 else if ( identifier == QLatin1String(
"photo" ) ) {
851 Picture picture = parsePicture( *lineIt );
855 addr.insertExtraPhoto( picture );
860 else if ( identifier == QLatin1String(
"prodid" ) ) {
865 else if ( identifier == QLatin1String(
"rev" ) ) {
866 addr.
setRevision( parseDateTime( ( *lineIt ).value().toString() ) );
870 else if ( identifier == QLatin1String(
"role" ) ) {
871 addr.
setRole( ( *lineIt ).value().toString() );
875 else if ( identifier == QLatin1String(
"sort-string" ) ) {
880 else if ( identifier == QLatin1String(
"sound" ) ) {
881 Sound sound = parseSound( *lineIt );
885 addr.insertExtraSound(sound);
890 else if ( identifier == QLatin1String(
"tel" ) ) {
892 phone.
setNumber( ( *lineIt ).value().toString() );
894 PhoneNumber::Type type;
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()];
908 else if ( identifier == QLatin1String(
"title" ) ) {
909 addr.
setTitle( ( *lineIt ).value().toString() );
913 else if ( identifier == QLatin1String(
"tz" ) ) {
915 const QString date = ( *lineIt ).value().
toString();
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 );
929 else if ( identifier == QLatin1String(
"uid" ) ) {
930 addr.
setUid( ( *lineIt ).value().toString() );
934 else if ( identifier == QLatin1String(
"url" ) ) {
935 const KUrl url = KUrl( ( *lineIt ).value().toString() );
936 if (addr.
url().isEmpty()) {
939 addr.insertExtraUrl(url);
943 else if ( identifier == QLatin1String(
"source" ) ) {
944 const KUrl url = KUrl( ( *lineIt ).value().toString() );
945 addr.insertSourceUrl( url );
948 else if ( identifier == QLatin1String(
"member" ) ) {
949 addr.insertMember( ( *lineIt ).value().toString() );
952 else if ( identifier == QLatin1String(
"related" ) ) {
953 addr.insertRelationShip( ( *lineIt ).value().toString() );
957 else if ( identifier.startsWith( QLatin1String(
"x-" ) ) ) {
958 QString ident = ( *lineIt ).identifier();
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" );
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() );
1010 addrList.append( addr );
1016 QDateTime VCardTool::parseDateTime(
const QString &str )
const
1021 if ( str.indexOf( QLatin1Char(
'-' ) ) == -1 ) {
1022 date = QDate( str.left( 4 ).toInt(), str.mid( 4, 2 ).toInt(),
1023 str.mid( 6, 2 ).toInt() );
1025 date = QDate( str.left( 4 ).toInt(), str.mid( 5, 2 ).toInt(),
1026 str.mid( 8, 2 ).toInt() );
1029 int timeStart = str.indexOf( QLatin1Char(
'T' ) );
1030 if ( timeStart >= 0 ) {
1031 int hour = 0, minute = 0, second = 0;
1033 hour = str.mid( timeStart + 1, 2 ).toInt();
1035 if ( str.indexOf( QLatin1Char(
':' ), timeStart + 1 ) > 0 ) {
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();
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();
1051 time = QTime( hour, minute, second );
1054 Qt::TimeSpec spec = ( str.right( 1 ) == QLatin1String(
"Z" ) ) ? Qt::UTC : Qt::LocalTime;
1056 QDateTime dateTime( date );
1064 dateTime.setTime( time );
1066 dateTime.setTimeSpec( spec );
1070 QString VCardTool::createDateTime(
const QDateTime &dateTime )
const
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() ) {
1079 tmp.sprintf(
"T%02d:%02d:%02d", dateTime.time().hour(), dateTime.time().minute(),
1080 dateTime.time().second() );
1083 if ( dateTime.timeSpec() == Qt::UTC ) {
1084 str += QLatin1Char(
'Z' );
1092 Picture VCardTool::parsePicture(
const VCardLine &line )
const
1096 const QStringList params = line.parameterList();
1098 if ( params.contains( QLatin1String(
"type" ) ) ) {
1099 type = line.parameter( QLatin1String(
"type" ) );
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() );
1112 VCardLine VCardTool::createPicture(
const QString &identifier,
const Picture &pic, VCard::Version version )
const
1114 VCardLine line( identifier );
1121 line.setValue( pic.
rawData() );
1122 if (version == VCard::v2_1) {
1123 line.addParameter( QLatin1String(
"ENCODING" ), QLatin1String(
"BASE64" ) );
1124 line.addParameter( pic.
type(), QString() );
1126 line.addParameter( QLatin1String(
"encoding" ), QLatin1String(
"b" ) );
1127 line.addParameter( QLatin1String(
"type" ), pic.
type() );
1130 line.setValue( pic.
url() );
1131 line.addParameter( QLatin1String(
"value" ), QLatin1String(
"URI" ) );
1137 Sound VCardTool::parseSound(
const VCardLine &line )
const
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() );
1158 VCardLine VCardTool::createSound(
const Sound &snd, VCard::Version version )
const
1160 VCardLine line( QLatin1String(
"SOUND" ) );
1163 if ( !snd.
data().isEmpty() ) {
1164 line.setValue( snd.
data() );
1165 if (version == VCard::v2_1) {
1166 line.addParameter( QLatin1String(
"ENCODING" ), QLatin1String(
"BASE64" ) );
1168 line.addParameter( QLatin1String(
"encoding" ), QLatin1String(
"b" ) );
1172 }
else if ( !snd.
url().isEmpty() ) {
1173 line.setValue( snd.
url() );
1174 line.addParameter( QLatin1String(
"value" ), QLatin1String(
"URI" ) );
1180 Key VCardTool::parseKey(
const VCardLine &line )
const
1184 const QStringList params = line.parameterList();
1185 if ( params.contains( QLatin1String(
"encoding" ) ) ) {
1191 if ( params.contains( QLatin1String(
"type" ) ) ) {
1192 if ( line.parameter( QLatin1String(
"type" ) ).toLower() == QLatin1String(
"x509" ) ) {
1194 }
else if ( line.parameter( QLatin1String(
"type" ) ).toLower() == QLatin1String(
"pgp" ) ) {
1205 VCardLine VCardTool::createKey(
const Key &key, VCard::Version version )
const
1208 VCardLine line( QLatin1String(
"KEY" ) );
1213 if (version == VCard::v2_1)
1214 line.addParameter( QLatin1String(
"ENCODING" ), QLatin1String(
"BASE64" ) );
1216 line.addParameter( QLatin1String(
"encoding" ), QLatin1String(
"b" ) );
1218 }
else if ( !key.
textData().isEmpty() ) {
1223 line.addParameter( QLatin1String(
"type" ), QLatin1String(
"X509" ) );
1225 line.addParameter( QLatin1String(
"type" ), QLatin1String(
"PGP" ) );
1233 Secrecy VCardTool::parseSecrecy(
const VCardLine &line )
const
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 );
1249 VCardLine VCardTool::createSecrecy(
const Secrecy &secrecy )
const
1251 VCardLine line( QLatin1String(
"CLASS" ) );
1253 int type = secrecy.type();
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" ) );
1266 QStringList VCardTool::splitString(
const QChar &sep,
const QString &str )
const
1269 QString value( str );
1272 int pos = value.indexOf( sep, start );
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 );
1283 pos = value.indexOf( sep, start );
1285 value.replace( pos - 1, 2, sep );
1286 pos = value.indexOf( sep, pos );
1290 int l = value.length() - 1;
1291 if ( value.mid( start, l - start + 1 ).length() > 0 ) {
1292 list << value.mid( start, l - start + 1 );