30#include <QtCore/QString>
31#include <QtCore/QBuffer>
36static 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 !=
'=' ) {
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 );
75VCardTool::~VCardTool()
79QByteArray VCardTool::exportVCards(
const Addressee::List &list, VCard::Version version )
const
81 return createVCards( list, version,
true );
84QByteArray VCardTool::createVCards(
const Addressee::List &list, VCard::Version version )
const
86 return createVCards( list, version,
false );
89void 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 );
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 );
1016QDateTime 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 );
1070QString 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' );
1092Picture 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() );
1112VCardLine 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" ) );
1137Sound 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() );
1158VCardLine 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" ) );
1180Key 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" ) ) {
1205VCardLine 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" ) );
1233Secrecy 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 );
1249VCardLine 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" ) );
1266QStringList 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 );
Postal address information.
void setType(Type type)
Sets the type of address.
void setStreet(const QString &street)
Sets the street (including house number).
void setCountry(const QString &country)
Sets the country.
void setPostOfficeBox(const QString &postOfficeBox)
Sets the post office box.
void setRegion(const QString ®ion)
Sets the region, e.g.
void setExtended(const QString &extended)
Sets the extended address information.
QList< Address > List
List of addresses.
void setPostalCode(const QString &code)
Sets the postal code.
void setLocality(const QString &locality)
Sets the locality, e.g.
void setLabel(const QString &label)
Sets the delivery label.
a QValueList of Addressee, with sorting functionality
void setMailer(const QString &mailer)
Set mail client.
void setLogo(const Picture &logo)
Set logo.
void setAdditionalName(const QString &additionalName)
Set additional names.
void setSecrecy(const Secrecy &secrecy)
Set security class.
void setBirthday(const QDateTime &birthday)
Set birthday.
void setOrganization(const QString &organization)
Set organization.
void insertPhoneNumber(const PhoneNumber &phoneNumber)
Insert a phone number.
void setPrefix(const QString &prefix)
Set honorific prefixes.
void insertCustom(const QString &app, const QString &name, const QString &value)
Insert custom entry.
void setProductId(const QString &productId)
Set product identifier.
KUrl url() const
Return homepage.
void setRevision(const QDateTime &revision)
Set revision date.
void setSuffix(const QString &suffix)
Set honorific suffixes.
Sound sound() const
Return sound.
Picture photo() const
Return photo.
void setGivenName(const QString &givenName)
Set given name.
void setNickName(const QString &nickName)
Set nick name.
void setDepartment(const QString &department)
Set department.
void insertEmail(const QString &email, bool preferred=false)
Insert an email address.
void setSound(const Sound &sound)
Set sound.
void setCategories(const QStringList &)
Set categories to given value.
void setTimeZone(const TimeZone &timeZone)
Set time zone.
Picture logo() const
Return logo.
void setNote(const QString ¬e)
Set note.
void setPhoto(const Picture &photo)
Set photo.
void setName(const QString &name)
Set name.
void insertAddress(const Address &address)
Insert an address.
Address::List addresses() const
Return list of all addresses.
void insertKey(const Key &key)
Insert a key.
void setRole(const QString &role)
Set role.
void setUrl(const KUrl &url)
Set homepage.
void setFormattedName(const QString &formattedName)
Set formatted name.
void setFamilyName(const QString &familyName)
Set family name.
void setTitle(const QString &title)
Set title.
void setUid(const QString &uid)
Set unique identifier.
void setGeo(const Geo &geo)
Set geographic position.
void setSortString(const QString &sortString)
Set sort string.
bool isValid() const
Returns, whether this object contains a valid geographical position.
void setLatitude(float latitude)
Sets the latitude.
float longitude() const
Returns the longitude.
float latitude() const
Returns the latitude.
QString toString() const
Returns string representation of geographical position.
void setLongitude(float longitude)
Sets the longitude.
A class to store an encryption key.
Type type() const
Returns the type, see Type.
bool isBinary() const
Returns whether the key contains binary or text data.
@ PGP
Pretty Good Privacy key.
@ Custom
Custom or IANA conform key.
void setCustomTypeString(const QString &type)
Sets custom type string.
QByteArray binaryData() const
Returns the binary data.
QString customTypeString() const
Returns the custom type string.
QList< Key > List
List of keys.
void setBinaryData(const QByteArray &data)
Sets binary data.
void setType(Type type)
Sets the type.
void setTextData(const QString &data)
Sets text data.
QString textData() const
Returns the text data.
void setType(Type type)
Sets the type.
void setNumber(const QString &number)
Sets the phone number.
@ Pcs
Personal Communication Service.
QList< PhoneNumber > List
List of phone numbers.
A class to store a picture of an addressee.
void setUrl(const QString &url)
Sets a URL for the location of the picture file.
bool isIntern() const
Returns whether the picture is described by a URL (extern) or by the raw data (intern).
void setRawData(const QByteArray &rawData, const QString &type)
Sets the raw data of the picture.
bool isEmpty() const
Returns true, if the picture is empty.
QByteArray rawData() const
Returns the raw data of this picture.
QString type() const
Returns the type of this picture.
QString url() const
Returns the location URL of this picture.
Class that holds a Sound clip for a contact.
QByteArray data() const
Returns the raw data of this sound.
void setData(const QByteArray &data)
Sets the raw data of the sound.
QString url() const
Returns the location URL of this sound.
void setUrl(const QString &url)
Sets a URL for the location of the sound file.
bool isIntern() const
Returns whether the sound is described by a URL (extern) or by the raw data (intern).
bool isEmpty() const
Returns true, if the sound object is empty.
void setOffset(int offset)
Set time zone offset relative to UTC.
int offset() const
Return offset in minutes relative to UTC.
QString toString() const
Return string representation of time zone offset.
bool isValid() const
Return, if this time zone object is valid.
Class that holds a Calendar Url (FBURL/CALADRURI/CALURI)