22 #include "vcardtool_p.h" 30 #include "fieldgroup.h" 31 #include "kcontacts_debug.h" 36 static bool needsEncoding(
const QString &value)
38 int length = value.
length();
39 for (
int i = 0; i < length; ++i) {
41 if ((c < 33 || c > 126) && c !=
' ' && c !=
'=') {
50 const char *addressType;
52 } s_addressTypes[] = {
62 static const unsigned int s_numAddressTypes
63 =
sizeof s_addressTypes /
sizeof *s_addressTypes;
67 for (
unsigned int i = 0; i < s_numAddressTypes; ++i) {
69 return s_addressTypes[i].flag;
76 const char *phoneType;
95 static const unsigned int s_numPhoneTypes
96 =
sizeof s_phoneTypes /
sizeof *s_phoneTypes;
100 for (
unsigned int i = 0; i < s_numPhoneTypes; ++i) {
102 return s_phoneTypes[i].flag;
108 VCardTool::VCardTool()
112 VCardTool::~VCardTool()
118 return createVCards(list, version,
true );
123 return createVCards(list, version,
false );
129 while (i.hasNext()) {
131 line.addParameter(i.key(), i.value().join(
QLatin1Char(
',')));
135 void VCardTool::addParameter(VCardLine &line, VCard::Version version,
const QString &key,
const QStringList &valueStringList)
const 137 if (version == VCard::v2_1) {
138 for (
const QString &valueStr : valueStringList) {
139 line.addParameter(valueStr,
QString());
141 }
else if (version == VCard::v3_0) {
142 line.addParameter(key, valueStringList.join(
QLatin1Char(
',')));
144 if (valueStringList.count() < 2) {
145 line.addParameter(key, valueStringList.join(
QLatin1Char(
',')));
158 for (addrIt = list.
constBegin(); addrIt != listEnd; ++addrIt) {
162 if (version == VCard::v2_1) {
163 card.addLine(VCardLine(QStringLiteral(
"VERSION"), QStringLiteral(
"2.1")));
164 }
else if (version == VCard::v3_0) {
165 card.addLine(VCardLine(QStringLiteral(
"VERSION"), QStringLiteral(
"3.0")));
166 }
else if (version == VCard::v4_0) {
167 card.addLine(VCardLine(QStringLiteral(
"VERSION"), QStringLiteral(
"4.0")));
176 const bool isEmpty = ((*it).postOfficeBox().isEmpty()
177 && (*it).extended().isEmpty()
178 && (*it).street().isEmpty()
179 && (*it).locality().isEmpty()
180 && (*it).region().isEmpty()
181 && (*it).postalCode().isEmpty()
182 && (*it).country().isEmpty());
185 QStringLiteral(
"\\;")));
188 QStringLiteral(
"\\;")));
191 QStringLiteral(
"\\;")));
194 QStringLiteral(
"\\;")));
197 QStringLiteral(
"\\;")));
200 QStringLiteral(
"\\;")));
203 QStringLiteral(
"\\;")));
206 VCardLine adrLine(QStringLiteral(
"ADR"), addressJoined);
207 if (version == VCard::v2_1 && needsEncoding(addressJoined)) {
208 adrLine.addParameter(QStringLiteral(
"charset"), QStringLiteral(
"UTF-8"));
209 adrLine.addParameter(QStringLiteral(
"encoding"), QStringLiteral(
"QUOTED-PRINTABLE"));
212 const bool hasLabel = !(*it).label().isEmpty();
215 for (
unsigned int i = 0; i < s_numAddressTypes; ++i) {
216 if (s_addressTypes[i].flag & (*it).type()) {
218 addreLineType << str;
220 labelLineType << str;
226 if (version == VCard::v4_0) {
227 if (!(*it).label().isEmpty()) {
228 adrLine.addParameter(QStringLiteral(
"LABEL"), QStringLiteral(
"\"%1\"").arg((*it).label()));
231 VCardLine labelLine(QStringLiteral(
"LABEL"), (*it).label());
232 if (version == VCard::v2_1 && needsEncoding((*it).label())) {
233 labelLine.addParameter(QStringLiteral(
"charset"), QStringLiteral(
"UTF-8"));
234 labelLine.addParameter(QStringLiteral(
"encoding"), QStringLiteral(
"QUOTED-PRINTABLE"));
236 addParameter(labelLine, version, QStringLiteral(
"TYPE"), labelLineType);
237 card.addLine(labelLine);
240 if (version == VCard::v4_0) {
243 QString str = QString::asprintf(
"\"geo:%.6f,%.6f\"", geo.latitude(), geo.longitude());
244 adrLine.addParameter(QStringLiteral(
"GEO"), str);
248 addParameter(adrLine, version, QStringLiteral(
"TYPE"), addreLineType);
249 card.addLine(adrLine);
254 const bool withTime = (*addrIt).birthdayHasTime();
255 const QString birthdayString = createDateTime((*addrIt).birthday(), version, withTime);
256 card.addLine(VCardLine(QStringLiteral(
"BDAY"), birthdayString));
262 if (version != VCard::v2_1) {
266 for (catIt = categories.
begin(); catIt != catEnd; ++catIt) {
267 (*catIt).replace(
QLatin1Char(
','), QStringLiteral(
"\\,"));
270 VCardLine catLine(QStringLiteral(
"CATEGORIES"), categories.
join(
QLatin1Char(
',')));
271 card.addLine(catLine);
275 if (version == VCard::v4_0) {
279 for (
const QString &member : lst) {
280 VCardLine line(QStringLiteral(
"MEMBER"), member);
287 for (
const QUrl &url : lstUrl) {
288 VCardLine line = VCardLine(QStringLiteral(
"SOURCE"), url.url());
295 for (relatedIt = relatedList.
begin(); relatedIt != relatedEnd; ++relatedIt) {
296 VCardLine line(QStringLiteral(
"RELATED"), (*relatedIt).related());
297 addParameters(line, (*relatedIt).parameters());
301 if (version == VCard::v3_0) {
302 card.addLine(createSecrecy((*addrIt).secrecy()));
305 if (version == VCard::v4_0) {
306 const Lang::List langList = (*addrIt).langs();
309 for (langIt = langList.
begin(); langIt != langEnd; ++langIt) {
310 VCardLine line(QStringLiteral(
"LANG"), (*langIt).language());
311 addParameters(line, (*langIt).parameters());
316 if (version == VCard::v4_0) {
320 for (clientPidMapIt = clientpidmapList.
begin(); clientPidMapIt != clientPidMapEnd; ++clientPidMapIt) {
321 VCardLine line(QStringLiteral(
"CLIENTPIDMAP"), (*clientPidMapIt).clientPidMap());
322 addParameters(line, (*clientPidMapIt).parameters());
327 const Email::List emailList = (*addrIt).emailList();
330 for (emailIt = emailList.
begin(); emailIt != emailEnd; ++emailIt) {
331 VCardLine line(QStringLiteral(
"EMAIL"), (*emailIt).mail());
333 while (i.hasNext()) {
335 if (version == VCard::v2_1) {
338 bool hasPreferred =
false;
339 const int removeItems = valueStringList.
removeAll(QStringLiteral(
"PREF"));
340 if (removeItems > 0) {
343 if (!valueStringList.
isEmpty()) {
344 addParameter(line, version, i.key(), valueStringList);
347 line.addParameter(QStringLiteral(
"PREF"),
QString());
350 line.addParameter(i.key(), i.value().join(
QLatin1Char(
',')));
353 line.addParameter(i.key(), i.value().join(
QLatin1Char(
',')));
360 VCardLine fnLine(QStringLiteral(
"FN"), (*addrIt).formattedName());
361 if (version == VCard::v2_1 && needsEncoding((*addrIt).formattedName())) {
362 fnLine.addParameter(QStringLiteral(
"charset"), QStringLiteral(
"UTF-8"));
363 fnLine.addParameter(QStringLiteral(
"encoding"), QStringLiteral(
"QUOTED-PRINTABLE"));
365 card.addLine(fnLine);
368 const Geo geo = (*addrIt).geo();
371 if (version == VCard::v4_0) {
372 str = QString::asprintf(
"geo:%.6f,%.6f", geo.latitude(), geo.longitude());
374 str = QString::asprintf(
"%.6f;%.6f", geo.latitude(), geo.longitude());
376 card.addLine(VCardLine(QStringLiteral(
"GEO"), str));
383 for (keyIt = keys.
begin(); keyIt != keyEnd; ++keyIt) {
384 card.addLine(createKey(*keyIt, version));
388 card.addLine(createPicture(QStringLiteral(
"LOGO"), (*addrIt).logo(), version));
390 for (
const Picture &logo : lstLogo) {
391 card.addLine(createPicture(QStringLiteral(
"LOGO"), logo, version));
395 if (version != VCard::v4_0) {
396 VCardLine mailerLine(QStringLiteral(
"MAILER"), (*addrIt).mailer());
397 if (version == VCard::v2_1 && needsEncoding((*addrIt).mailer())) {
398 mailerLine.addParameter(QStringLiteral(
"charset"), QStringLiteral(
"UTF-8"));
399 mailerLine.addParameter(QStringLiteral(
"encoding"), QStringLiteral(
"QUOTED-PRINTABLE"));
401 card.addLine(mailerLine);
407 QStringLiteral(
"\\;")));
410 QStringLiteral(
"\\;")));
413 QStringLiteral(
"\\;")));
416 QStringLiteral(
"\\;")));
419 QStringLiteral(
"\\;")));
422 if (version == VCard::v2_1 && needsEncoding(name.
join(
QLatin1Char(
';')))) {
423 nLine.addParameter(QStringLiteral(
"charset"), QStringLiteral(
"UTF-8"));
424 nLine.addParameter(QStringLiteral(
"encoding"), QStringLiteral(
"QUOTED-PRINTABLE"));
426 if (version == VCard::v4_0 && !(*addrIt).sortString().isEmpty()) {
427 nLine.addParameter(QStringLiteral(
"SORT-AS"), (*addrIt).sortString());
433 if (version != VCard::v4_0) {
434 VCardLine nameLine(QStringLiteral(
"NAME"), (*addrIt).name());
435 if (version == VCard::v2_1 && needsEncoding((*addrIt).name())) {
436 nameLine.addParameter(QStringLiteral(
"charset"), QStringLiteral(
"UTF-8"));
437 nameLine.addParameter(QStringLiteral(
"encoding"), QStringLiteral(
"QUOTED-PRINTABLE"));
439 card.addLine(nameLine);
443 if (version != VCard::v2_1) {
445 for (
const NickName &nickName : lstNickName) {
446 VCardLine nickNameLine(QStringLiteral(
"NICKNAME"), nickName.nickname());
447 addParameters(nickNameLine, nickName.parameters());
449 card.addLine(nickNameLine);
454 VCardLine noteLine(QStringLiteral(
"NOTE"), (*addrIt).note());
455 if (version == VCard::v2_1 && needsEncoding((*addrIt).note())) {
456 noteLine.addParameter(QStringLiteral(
"charset"), QStringLiteral(
"UTF-8"));
457 noteLine.addParameter(QStringLiteral(
"encoding"), QStringLiteral(
"QUOTED-PRINTABLE"));
459 card.addLine(noteLine);
462 const QVector<Org> lstOrg = (*addrIt).extraOrganizationList();
463 for (
const Org &
org : lstOrg) {
466 QStringLiteral(
"\\;")));
467 if (!(*addrIt).department().isEmpty()) {
469 QStringLiteral(
"\\;")));
472 VCardLine orgLine(QStringLiteral(
"ORG"), orgStr);
473 if (version == VCard::v2_1 && needsEncoding(orgStr)) {
474 orgLine.addParameter(QStringLiteral(
"charset"), QStringLiteral(
"UTF-8"));
475 orgLine.addParameter(QStringLiteral(
"encoding"), QStringLiteral(
"QUOTED-PRINTABLE"));
477 addParameters(orgLine,
org.parameters());
478 card.addLine(orgLine);
482 card.addLine(createPicture(QStringLiteral(
"PHOTO"), (*addrIt).photo(), version));
484 for (
const Picture &photo : lstExtraPhoto) {
485 card.addLine(createPicture(QStringLiteral(
"PHOTO"), photo, version));
489 if (version != VCard::v2_1) {
490 card.addLine(VCardLine(QStringLiteral(
"PRODID"), (*addrIt).productId()));
494 card.addLine(VCardLine(QStringLiteral(
"REV"), createDateTime((*addrIt).revision(), version)));
497 const QVector<Role> lstExtraRole = (*addrIt).extraRoleList();
498 for (
const Role &role : lstExtraRole) {
499 VCardLine roleLine(QStringLiteral(
"ROLE"), role.role());
500 if (version == VCard::v2_1 && needsEncoding(role.role())) {
501 roleLine.addParameter(QStringLiteral(
"charset"), QStringLiteral(
"UTF-8"));
502 roleLine.addParameter(QStringLiteral(
"encoding"), QStringLiteral(
"QUOTED-PRINTABLE"));
504 addParameters(roleLine, role.parameters());
505 card.addLine(roleLine);
509 if (version == VCard::v3_0) {
510 card.addLine(VCardLine(QStringLiteral(
"SORT-STRING"), (*addrIt).sortString()));
514 card.addLine(createSound((*addrIt).sound(), version));
516 for (
const Sound &sound : lstSound) {
517 card.addLine(createSound(sound, version));
524 for (phoneIt = phoneNumbers.
begin(); phoneIt != phoneEnd; ++phoneIt) {
525 VCardLine line(QStringLiteral(
"TEL"), (*phoneIt).number());
527 while (i.hasNext()) {
530 line.addParameter(i.key(), i.value().join(
QLatin1Char(
',')));
535 for (
unsigned int i = 0; i < s_numPhoneTypes; ++i) {
536 if (s_phoneTypes[i].flag & (*phoneIt).type()) {
538 if (version == VCard::v4_0) {
546 addParameter(line, version, QStringLiteral(
"TYPE"), lst);
553 for (
const Title &title : lstTitle) {
554 VCardLine titleLine(QStringLiteral(
"TITLE"), title.title());
555 if (version == VCard::v2_1 && needsEncoding(title.title())) {
556 titleLine.addParameter(QStringLiteral(
"charset"), QStringLiteral(
"UTF-8"));
557 titleLine.addParameter(QStringLiteral(
"encoding"), QStringLiteral(
"QUOTED-PRINTABLE"));
559 addParameters(titleLine, title.parameters());
561 card.addLine(titleLine);
566 const TimeZone timeZone = (*addrIt).timeZone();
570 if (timeZone.
offset() < 0) {
574 QString str = QString::asprintf(
"%c%02d:%02d", (timeZone.
offset() >= 0 ?
'+' :
'-'),
575 (timeZone.
offset() / 60) * neg,
576 (timeZone.
offset() % 60) * neg);
578 card.addLine(VCardLine(QStringLiteral(
"TZ"), str));
582 card.addLine(VCardLine(QStringLiteral(
"UID"), (*addrIt).uid()));
587 VCardLine line(QStringLiteral(
"URL"), url.url());
588 addParameters(line, url.parameters());
591 if (version == VCard::v4_0) {
593 const Gender gender = (*addrIt).gender();
594 if (gender.isValid()) {
596 if (!gender.gender().
isEmpty()) {
597 genderStr = gender.gender();
599 if (!gender.comment().
isEmpty()) {
602 VCardLine line(QStringLiteral(
"GENDER"), genderStr);
606 if (!(*addrIt).kind().isEmpty()) {
607 VCardLine line(QStringLiteral(
"KIND"), (*addrIt).kind());
612 if (version == VCard::v4_0) {
617 switch (url.type()) {
618 case CalendarUrl::Unknown:
619 case CalendarUrl::EndCalendarType:
621 case CalendarUrl::FBUrl:
622 type = QStringLiteral(
"FBURL");
624 case CalendarUrl::CALUri:
625 type = QStringLiteral(
"CALURI");
627 case CalendarUrl::CALADRUri:
628 type = QStringLiteral(
"CALADRURI");
632 VCardLine line(type, url.url().toDisplayString());
633 addParameters(line, url.parameters());
642 VCardLine line(group.fieldGroupName(), group.value());
643 addParameters(line, group.parameters());
649 for (
const Impp &impp : lstImpp) {
650 VCardLine line(QStringLiteral(
"IMPP"), impp.address().url());
652 while (i.hasNext()) {
655 line.addParameter(i.key(), i.value().join(
QLatin1Char(
',')));
663 for (strIt = customs.
begin(); strIt != customs.
end(); ++strIt) {
665 +(*strIt).left((*strIt).indexOf(
QLatin1Char(
':')));
673 identifier = QStringLiteral(
"X-AIM");
674 }
else if (identifier ==
QLatin1String(
"X-messaging/icq-All")) {
675 identifier = QStringLiteral(
"X-ICQ");
676 }
else if (identifier ==
QLatin1String(
"X-messaging/xmpp-All")) {
677 identifier = QStringLiteral(
"X-JABBER");
678 }
else if (identifier ==
QLatin1String(
"X-messaging/msn-All")) {
679 identifier = QStringLiteral(
"X-MSN");
680 }
else if (identifier ==
QLatin1String(
"X-messaging/yahoo-All")) {
681 identifier = QStringLiteral(
"X-YAHOO");
682 }
else if (identifier ==
QLatin1String(
"X-messaging/gadu-All")) {
683 identifier = QStringLiteral(
"X-GADUGADU");
684 }
else if (identifier ==
QLatin1String(
"X-messaging/skype-All")) {
685 identifier = QStringLiteral(
"X-SKYPE");
686 }
else if (identifier ==
QLatin1String(
"X-messaging/groupwise-All")) {
687 identifier = QStringLiteral(
"X-GROUPWISE");
688 }
else if (identifier ==
QLatin1String(
"X-messaging/sms-All")) {
689 identifier = QStringLiteral(
"X-SMS");
690 }
else if (identifier ==
QLatin1String(
"X-messaging/meanwhile-All")) {
691 identifier = QStringLiteral(
"X-MEANWHILE");
692 }
else if (identifier ==
QLatin1String(
"X-messaging/irc-All")) {
693 identifier = QStringLiteral(
"X-IRC");
694 }
else if (identifier ==
QLatin1String(
"X-messaging/googletalk-All")) {
696 identifier = QStringLiteral(
"X-GTALK");
697 }
else if (identifier ==
QLatin1String(
"X-messaging/twitter-All")) {
698 identifier = QStringLiteral(
"X-TWITTER");
701 if (identifier.
toLower() ==
QLatin1String(
"x-kaddressbook-x-anniversary") && version == VCard::v4_0) {
707 VCardLine line(QStringLiteral(
"ANNIVERSARY"), createDateTime(dt, version,
false));
710 }
else if (identifier.
toLower() ==
QLatin1String(
"x-kaddressbook-x-spousesname") && version == VCard::v4_0) {
712 VCardLine line(QStringLiteral(
"RELATED"), QStringLiteral(
";"));
713 line.addParameter(QStringLiteral(
"TYPE"), QStringLiteral(
"spouse"));
714 line.addParameter(QStringLiteral(
"VALUE"), value);
718 VCardLine line(identifier, value);
719 if (version == VCard::v2_1 && needsEncoding(value)) {
720 line.addParameter(QStringLiteral(
"charset"), QStringLiteral(
"UTF-8"));
721 line.addParameter(QStringLiteral(
"encoding"), QStringLiteral(
"QUOTED-PRINTABLE"));
730 return VCardParser::createVCards(vCardList);
740 const VCard::List vCardList = VCardParser::parseVCards(vcard);
744 for (cardIt = vCardList.
begin(); cardIt != listEnd; ++cardIt) {
747 const QStringList idents = (*cardIt).identifiers();
750 for (identIt = idents.
begin(); identIt != identEnd; ++identIt) {
755 for (lineIt = lines.
begin(); lineIt != lines.
end(); ++lineIt) {
756 identifier = (*lineIt).identifier().
toLower();
757 group = (*lineIt).group();
760 groupField.setParameters((*lineIt).parameterMap());
761 groupField.setValue((*lineIt).value().toString());
762 addr.insertFieldGroup(groupField);
767 const QStringList addrParts = splitString(semicolonSep, (*lineIt).value().toString());
768 const int addrPartsCount(addrParts.
count());
769 if (addrPartsCount > 0) {
772 if (addrPartsCount > 1) {
775 if (addrPartsCount > 2) {
778 if (addrPartsCount > 3) {
781 if (addrPartsCount > 4) {
784 if (addrPartsCount > 5) {
787 if (addrPartsCount > 6) {
796 type |= stringToAddressType((*it).toLower());
800 QString label = (*lineIt).parameter(QStringLiteral(
"label"));
804 label = label.
mid(1, label.
length() - 2);
809 QString geoStr = (*lineIt).parameter(QStringLiteral(
"geo"));
812 geoStr.
remove(QStringLiteral(
"geo:"));
825 const QString t = (*lineIt).value().toString();
827 addr.
insertCustom(QStringLiteral(
"KADDRESSBOOK"), QStringLiteral(
"X-Anniversary"), dt.
date().
toString(Qt::ISODate));
832 const QDateTime bday = parseDateTime((*lineIt).value().toString(), &withTime);
837 const QStringList categories = splitString(commaSep, (*lineIt).value().toString());
843 calurl.setType(CalendarUrl::FBUrl);
844 const QUrl url =
QUrl((*lineIt).value().toString());
846 calurl.setParameters((*lineIt).parameterMap());
847 addr.insertCalendarUrl(calurl);
852 calurl.setType(CalendarUrl::CALADRUri);
853 const QUrl url =
QUrl((*lineIt).value().toString());
855 calurl.setParameters((*lineIt).parameterMap());
856 addr.insertCalendarUrl(calurl);
861 calurl.setType(CalendarUrl::CALUri);
862 const QUrl url =
QUrl((*lineIt).value().toString());
864 calurl.setParameters((*lineIt).parameterMap());
865 addr.insertCalendarUrl(calurl);
869 QUrl imppUrl((*lineIt).value().toString());
871 impp.setParameters((*lineIt).parameterMap());
872 if (!(*lineIt).parameter(QStringLiteral(
"x-service-type")).isEmpty() && imppUrl.scheme().isEmpty()) {
873 imppUrl.setScheme(normalizeImppServiceType((*lineIt).parameter(QStringLiteral(
"x-service-type")).toLower()));
875 impp.setAddress(imppUrl);
876 addr.insertImpp(impp);
884 QString genderStr = (*lineIt).value().toString();
888 gender.setGender(genderStr.
at(0));
890 gender.setComment(genderStr.
right(genderStr.
length() - 2));
893 gender.setComment(genderStr.
right(genderStr.
length() - 1));
895 addr.setGender(gender);
901 lang.setLanguage((*lineIt).value().toString());
902 lang.setParameters((*lineIt).parameterMap());
907 const QStringList types = (*lineIt).parameters(QStringLiteral(
"type"));
913 addr.setKind((*lineIt).value().toString());
922 QString lineStr = (*lineIt).value().toString();
924 lineStr.
remove(QStringLiteral(
"geo:"));
927 if (geoParts.
size() >= 2) {
935 if (geoParts.
size() >= 2) {
950 const QStringList types = (*lineIt).parameters(QStringLiteral(
"type"));
953 type |= stringToAddressType((*it).toLower());
956 bool available =
false;
959 it != addressList.
end(); ++it) {
960 if ((*it).type() == type) {
961 (*it).setLabel((*lineIt).value().toString());
970 address.
setLabel((*lineIt).value().toString());
976 Picture picture = parsePicture(*lineIt);
980 addr.insertExtraLogo(picture);
985 addr.
setMailer((*lineIt).value().toString());
989 const QStringList nameParts = splitString(semicolonSep, (*lineIt).value().toString());
990 const int numberOfParts(nameParts.
count());
991 if (numberOfParts > 0) {
994 if (numberOfParts > 1) {
997 if (numberOfParts > 2) {
1000 if (numberOfParts > 3) {
1003 if (numberOfParts > 4) {
1006 if (!(*lineIt).parameter(QStringLiteral(
"sort-as")).isEmpty()) {
1007 addr.
setSortString((*lineIt).parameter(QStringLiteral(
"sort-as")));
1012 addr.
setName((*lineIt).value().toString());
1016 NickName nickName((*lineIt).value().toString());
1017 nickName.setParameters((*lineIt).parameterMap());
1018 addr.insertExtraNickName(nickName);
1022 addr.
setNote((*lineIt).value().toString());
1026 const QStringList orgParts = splitString(semicolonSep, (*lineIt).value().toString());
1027 const int orgPartsCount(orgParts.
count());
1028 if (orgPartsCount > 0) {
1029 Org organization(orgParts.
at(0));
1030 organization.setParameters((*lineIt).parameterMap());
1031 addr.insertExtraOrganization(organization);
1033 if (orgPartsCount > 1) {
1036 if (!(*lineIt).parameter(QStringLiteral(
"sort-as")).isEmpty()) {
1037 addr.
setSortString((*lineIt).parameter(QStringLiteral(
"sort-as")));
1042 Picture picture = parsePicture(*lineIt);
1046 addr.insertExtraPhoto(picture);
1055 addr.
setRevision(parseDateTime((*lineIt).value().toString()));
1059 Role role((*lineIt).value().toString());
1060 role.setParameters((*lineIt).parameterMap());
1061 addr.insertExtraRole(role);
1069 Sound sound = parseSound(*lineIt);
1073 addr.insertExtraSound(sound);
1079 phone.
setNumber((*lineIt).value().toString());
1081 PhoneNumber::Type type;
1082 bool foundType =
false;
1083 const QStringList types = (*lineIt).parameters(QStringLiteral(
"type"));
1086 type |= stringToPhoneType((*it).toUpper());
1089 phone.
setType(foundType ? type : PhoneNumber::Undefined);
1090 phone.setParameters((*lineIt).parameterMap());
1096 Title title((*lineIt).value().toString());
1097 title.setParameters((*lineIt).parameterMap());
1098 addr.insertExtraTitle(title);
1109 int offset = (hours * 60) + minutes;
1110 offset = offset * (date[ 0 ] ==
QLatin1Char(
'+') ? 1 : -1);
1118 addr.
setUid((*lineIt).value().toString());
1122 const QUrl url =
QUrl((*lineIt).value().toString());
1124 resourceLocatorUrl.setUrl(url);
1125 resourceLocatorUrl.setParameters((*lineIt).parameterMap());
1126 addr.insertExtraUrl(resourceLocatorUrl);
1130 const QUrl url =
QUrl((*lineIt).value().toString());
1131 addr.insertSourceUrl(url);
1135 addr.insertMember((*lineIt).value().toString());
1140 related.setRelated((*lineIt).value().toString());
1141 related.setParameters((*lineIt).parameterMap());
1142 addr.insertRelationship(related);
1147 clientpidmap.setClientPidMap((*lineIt).value().toString());
1148 clientpidmap.setParameters((*lineIt).parameterMap());
1149 addr.insertClientPidMap(clientpidmap);
1154 QString ident = (*lineIt).identifier();
1159 ident = QStringLiteral(
"X-KADDRESSBOOK-X-SpousesName");
1161 ident = QStringLiteral(
"X-KADDRESSBOOK-BlogFeed");
1162 }
else if (identifier ==
QLatin1String(
"x-evolution-assistant")
1164 || identifier.
compare(
QLatin1String(
"X-KADDRESSBOOK-X-ASSISTANTSNAME"), Qt::CaseInsensitive) == 0) {
1165 ident = QStringLiteral(
"X-KADDRESSBOOK-X-AssistantsName");
1166 }
else if (identifier ==
QLatin1String(
"x-evolution-anniversary")
1168 || identifier.
compare(
QLatin1String(
"X-KADDRESSBOOK-X-ANNIVERSARY"), Qt::CaseInsensitive) == 0) {
1169 ident = QStringLiteral(
"X-KADDRESSBOOK-X-Anniversary");
1170 }
else if (identifier ==
QLatin1String(
"x-evolution-manager")
1172 || identifier.
compare(
QLatin1String(
"X-KADDRESSBOOK-X-MANAGERSNAME"), Qt::CaseInsensitive) == 0) {
1173 ident = QStringLiteral(
"X-KADDRESSBOOK-X-ManagersName");
1174 }
else if (identifier.
compare(
QLatin1String(
"X-KADDRESSBOOK-X-PROFESSION"), Qt::CaseInsensitive) == 0) {
1175 ident = QStringLiteral(
"X-KADDRESSBOOK-X-Profession");
1176 }
else if (identifier.
compare(
QLatin1String(
"X-KADDRESSBOOK-X-OFFICE"), Qt::CaseInsensitive) == 0) {
1177 ident = QStringLiteral(
"X-KADDRESSBOOK-X-Office");
1178 }
else if (identifier.
compare(
QLatin1String(
"X-KADDRESSBOOK-X-SPOUSESNAME"), Qt::CaseInsensitive) == 0) {
1179 ident = QStringLiteral(
"X-KADDRESSBOOK-X-SpousesName");
1181 ident = QStringLiteral(
"X-messaging/aim-All");
1183 ident = QStringLiteral(
"X-messaging/icq-All");
1185 ident = QStringLiteral(
"X-messaging/xmpp-All");
1187 ident = QStringLiteral(
"X-messaging/xmpp-All");
1189 ident = QStringLiteral(
"X-messaging/msn-All");
1191 ident = QStringLiteral(
"X-messaging/yahoo-All");
1193 ident = QStringLiteral(
"X-messaging/gadu-All");
1195 ident = QStringLiteral(
"X-messaging/skype-All");
1197 ident = QStringLiteral(
"X-messaging/groupwise-All");
1199 ident = QStringLiteral(
"X-messaging/sms-All");
1201 ident = QStringLiteral(
"X-messaging/meanwhile-All");
1203 ident = QStringLiteral(
"X-messaging/irc-All");
1205 ident = QStringLiteral(
"X-messaging/googletalk-All");
1207 ident = QStringLiteral(
"X-messaging/twitter-All");
1216 url.
setScheme(normalizeImppServiceType(key.
mid(10, dash - 10)));
1217 const auto values = (*lineIt).value().toString().split(
QChar(0xE000), QString::SkipEmptyParts);
1218 for (
const auto &value : values) {
1221 impp.setParameters((*lineIt).parameterMap());
1222 impp.setAddress(url);
1223 addr.insertImpp(impp);
1241 QString dateString = posT >= 0 ? str.
left(posT) : str;
1253 Qt::TimeSpec spec = Qt::LocalTime;
1261 const int tzPos = qMax(qMax(zPos, plusPos), minusPos);
1262 const QString hhmmssString = tzPos >= 0 ? timeString.
left(tzPos) : timeString;
1263 switch (hhmmssString.
size()) {
1278 spec = Qt::OffsetFromUTC;
1280 const QString offsetString = timeString.
mid(tzPos + 1);
1281 switch (offsetString.
size()) {
1289 offsetSecs = offsetTime.
hour() * 3600 + offsetTime.
minute() * 60;
1291 if (minusPos >= 0) {
1300 return QDateTime(date, time, spec, offsetSecs);
1303 QString VCardTool::createDateTime(
const QDateTime &dateTime, VCard::Version version,
bool withTime)
1308 QString str = createDate(dateTime.
date(), version);
1312 str += createTime(dateTime.
time(), version);
1313 if (dateTime.
timeSpec() == Qt::UTC) {
1315 }
else if (dateTime.
timeSpec() == Qt::OffsetFromUTC) {
1317 if (offsetSecs >= 0) {
1323 if (version == VCard::v4_0) {
1324 str += offsetTime.
toString(QStringLiteral(
"HHmm"));
1326 str += offsetTime.
toString(QStringLiteral(
"HH:mm"));
1332 QString VCardTool::createDate(
const QDate &date, VCard::Version version)
1335 if (date.
year() > 0) {
1336 format = QStringLiteral(
"yyyyMMdd");
1338 format = QStringLiteral(
"--MMdd");
1340 if (version != VCard::v4_0) {
1341 format.
replace(QStringLiteral(
"yyyy"), QStringLiteral(
"yyyy-"));
1342 format.
replace(QStringLiteral(
"MM"), QStringLiteral(
"MM-"));
1347 QString VCardTool::createTime(
const QTime &time, VCard::Version version)
1350 if (version == VCard::v4_0) {
1351 format = QStringLiteral(
"HHmmss");
1353 format = QStringLiteral(
"HH:mm:ss");
1358 Picture VCardTool::parsePicture(
const VCardLine &line)
const 1365 type = line.parameter(QStringLiteral(
"type"));
1368 pic.
setRawData(line.value().toByteArray(), type);
1370 if (line.parameter(QStringLiteral(
"value")).toLower() ==
QLatin1String(
"uri")) {
1371 pic.
setUrl(line.value().toString());
1378 VCardLine VCardTool::createPicture(
const QString &identifier,
const Picture &pic, VCard::Version version)
const 1380 VCardLine line(identifier);
1388 if (version == VCard::v2_1) {
1389 line.addParameter(QStringLiteral(
"ENCODING"), QStringLiteral(
"BASE64"));
1392 line.addParameter(QStringLiteral(
"encoding"), QStringLiteral(
"b"));
1393 line.addParameter(QStringLiteral(
"type"), pic.
type());
1396 line.addParameter(QStringLiteral(
"data") + QStringLiteral(
":image/") + pic.
type(), QStringLiteral(
"base64"));
1400 line.setValue(pic.
url());
1401 line.addParameter(QStringLiteral(
"value"), QStringLiteral(
"URI"));
1407 Sound VCardTool::parseSound(
const VCardLine &line)
const 1413 snd.
setData(line.value().toByteArray());
1415 if (line.parameter(QStringLiteral(
"value")).toLower() ==
QLatin1String(
"uri")) {
1416 snd.
setUrl(line.value().toString());
1428 VCardLine VCardTool::createSound(
const Sound &snd, VCard::Version version)
const 1431 VCardLine line(QStringLiteral(
"SOUND"));
1435 line.setValue(snd.
data());
1436 if (version == VCard::v2_1) {
1437 line.addParameter(QStringLiteral(
"ENCODING"), QStringLiteral(
"BASE64"));
1439 line.addParameter(QStringLiteral(
"encoding"), QStringLiteral(
"b"));
1444 line.setValue(snd.
url());
1445 line.addParameter(QStringLiteral(
"value"), QStringLiteral(
"URI"));
1451 Key VCardTool::parseKey(
const VCardLine &line)
const 1463 if (line.parameter(QStringLiteral(
"type")).toLower() ==
QLatin1String(
"x509")) {
1465 }
else if (line.parameter(QStringLiteral(
"type")).toLower() ==
QLatin1String(
"pgp")) {
1472 const QString param = line.parameter(QStringLiteral(
"mediatype")).
toLower();
1475 }
else if (param ==
QLatin1String(
"application/pgp-keys")) {
1486 VCardLine VCardTool::createKey(
const Key &key, VCard::Version version)
const 1488 VCardLine line(QStringLiteral(
"KEY"));
1493 if (version == VCard::v2_1) {
1494 line.addParameter(QStringLiteral(
"ENCODING"), QStringLiteral(
"BASE64"));
1496 line.addParameter(QStringLiteral(
"encoding"), QStringLiteral(
"b"));
1503 if (version == VCard::v4_0) {
1505 line.addParameter(QStringLiteral(
"MEDIATYPE"), QStringLiteral(
"application/x-x509-ca-cert"));
1507 line.addParameter(QStringLiteral(
"MEDIATYPE"), QStringLiteral(
"application/pgp-keys"));
1513 line.addParameter(QStringLiteral(
"type"), QStringLiteral(
"X509"));
1515 line.addParameter(QStringLiteral(
"type"), QStringLiteral(
"PGP"));
1524 Secrecy VCardTool::parseSecrecy(
const VCardLine &line)
const 1530 secrecy.
setType(Secrecy::Public);
1532 secrecy.
setType(Secrecy::Private);
1534 secrecy.
setType(Secrecy::Confidential);
1540 VCardLine VCardTool::createSecrecy(
const Secrecy &secrecy)
const 1542 VCardLine line(QStringLiteral(
"CLASS"));
1544 int type = secrecy.
type();
1546 if (type == Secrecy::Public) {
1547 line.setValue(QStringLiteral(
"PUBLIC"));
1548 }
else if (type == Secrecy::Private) {
1549 line.setValue(QStringLiteral(
"PRIVATE"));
1550 }
else if (type == Secrecy::Confidential) {
1551 line.setValue(QStringLiteral(
"CONFIDENTIAL"));
1563 int pos = value.
indexOf(sep, start);
1566 if (pos == 0 || value[ pos - 1 ] !=
QLatin1Char(
'\\')) {
1567 if (pos > start && pos <= value.
length()) {
1568 list << value.
mid(start, pos - start);
1574 pos = value.
indexOf(sep, start);
1576 value.
replace(pos - 1, 2, sep);
1577 pos = value.
indexOf(sep, pos);
1581 int l = value.
length() - 1;
1582 const QString mid = value.
mid(start, l - start + 1);
1592 QString VCardTool::normalizeImppServiceType(
const QString &serviceType)
const 1595 return QStringLiteral(
"xmpp");
1598 return QStringLiteral(
"ymsgr");
1601 return QStringLiteral(
"gg");
int toInt(bool *ok, int base) const
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
QDate addYears(int nyears) const
QString name(const QVariant &location)
QString toString(Qt::DateFormat format) const
QString toString(Qt::DateFormat format) const
void append(const T &value)
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
const_iterator constEnd() const
const T & at(int i) const
void setTime(const QTime &time)
bool contains(const QString &str, Qt::CaseSensitivity cs) const
QTime fromString(const QString &string, Qt::DateFormat format)
QString join(const QString &separator) const
QString & remove(int position, int n)
QVector< V > values(const QMultiHash< K, V > &c)
void setPath(const QString &path, ParsingMode mode)
QDate fromString(const QString &string, Qt::DateFormat format)
int count(const T &value) const
void append(const T &value)
PostalAddress address(const QVariant &location)
Type type(const QSqlDatabase &db)
QString label(StandardShortcut id)
GeoCoordinates geo(const QVariant &location)
int removeAll(const T &value)
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
void setScheme(const QString &scheme)
QTime addSecs(int s) const
QString right(int n) const
bool contains(QChar ch, Qt::CaseSensitivity cs) const
Qt::TimeSpec timeSpec() const
QStringRef midRef(int position, int n) const
QString & replace(int position, int n, QChar after)
const QList< QKeySequence > & end()
const_iterator constBegin() const
QString mid(int position, int n) const
const QChar at(int position) const
QString left(int n) const
QString fromLatin1(const char *str, int size)
const_iterator constEnd() const
const_iterator constBegin() const
int offsetFromUtc() const
int compare(const QString &other, Qt::CaseSensitivity cs) const
Types types(const QStringList &mimeTypes)