11#include "kcontacts_debug.h"
18#include "vcardtool_p.h"
23using namespace KContacts;
25static bool needsEncoding(
const QString &value)
27 int length = value.
length();
28 for (
int i = 0; i < length; ++i) {
30 if ((c < 33 || c > 126) && c !=
' ' && c !=
'=') {
38struct AddressTypeInfo {
39 const char *addressType;
43static const AddressTypeInfo s_addressTypes[] = {
55 auto it = std::find_if(std::begin(s_addressTypes), std::end(s_addressTypes), [&str](
const AddressTypeInfo &info) {
62 const char *phoneType;
66static const PhoneTypeInfo s_phoneTypes[] = {
85 auto it = std::find_if(std::begin(s_phoneTypes), std::end(s_phoneTypes), [&str](
const PhoneTypeInfo &info) {
95VCardTool::~VCardTool()
101 return createVCards(list, version,
true );
106 return createVCards(list, version,
false );
109void VCardTool::addParameter(VCardLine *line, VCard::Version version,
const QString &key,
const QStringList &valueStringList)
const
111 if (version == VCard::v2_1) {
112 for (
const QString &valueStr : valueStringList) {
113 line->addParameter(valueStr,
QString());
115 }
else if (version == VCard::v3_0) {
116 line->addParameter(key, valueStringList.join(
QLatin1Char(
',')));
118 if (valueStringList.count() < 2) {
119 line->addParameter(key, valueStringList.join(
QLatin1Char(
',')));
126void VCardTool::processAddresses(
const Address::List &addresses, VCard::Version version, VCard *card)
const
128 for (
const auto &addr : addresses) {
132 const bool isEmpty = addr.postOfficeBox().
isEmpty()
133 && addr.extended().isEmpty()
134 && addr.street().isEmpty()
135 && addr.locality().isEmpty()
136 && addr.region().isEmpty()
137 && addr.postalCode().isEmpty()
138 && addr.country().isEmpty();
141 address.append(addr.postOfficeBox().replace(
QLatin1Char(
';'), QStringLiteral(
"\\;")));
150 VCardLine adrLine(QStringLiteral(
"ADR"), addressJoined);
151 if (version == VCard::v2_1 && needsEncoding(addressJoined)) {
152 adrLine.addParameter(QStringLiteral(
"charset"), QStringLiteral(
"UTF-8"));
153 adrLine.addParameter(QStringLiteral(
"encoding"), QStringLiteral(
"QUOTED-PRINTABLE"));
156 const bool hasLabel = !addr.label().isEmpty();
160 for (
const auto &info : s_addressTypes) {
161 if (info.flag & addr.type()) {
163 addreLineType << str;
165 labelLineType << str;
171 if (version == VCard::v4_0) {
172 if (!addr.label().isEmpty()) {
173 adrLine.addParameter(QStringLiteral(
"LABEL"), QStringLiteral(
"\"%1\"").arg(addr.label()));
176 VCardLine labelLine(QStringLiteral(
"LABEL"), addr.label());
177 if (version == VCard::v2_1 && needsEncoding(addr.label())) {
178 labelLine.addParameter(QStringLiteral(
"charset"), QStringLiteral(
"UTF-8"));
179 labelLine.addParameter(QStringLiteral(
"encoding"), QStringLiteral(
"QUOTED-PRINTABLE"));
181 addParameter(&labelLine, version, QStringLiteral(
"TYPE"), labelLineType);
182 card->addLine(labelLine);
185 if (version == VCard::v4_0) {
189 adrLine.addParameter(QStringLiteral(
"GEO"), str);
193 addParameter(&adrLine, version, QStringLiteral(
"TYPE"), addreLineType);
194 card->addLine(adrLine);
199void VCardTool::processEmailList(
const Email::List &emailList, VCard::Version version, VCard *card)
const
201 for (
const auto &email : emailList) {
202 VCardLine line(QStringLiteral(
"EMAIL"), email.mail());
203 const ParameterMap pMap = email.params();
204 for (
const auto &[param, l] : pMap) {
206 if (version == VCard::v2_1) {
208 bool hasPreferred =
false;
209 const int removeItems =
list.
removeAll(QStringLiteral(
"PREF"));
210 if (removeItems > 0) {
214 addParameter(&line, version, param, list);
217 line.addParameter(QStringLiteral(
"PREF"),
QString());
230void VCardTool::processOrganizations(
const Addressee &addressee, VCard::Version version, VCard *card)
const
232 const QList<Org> lstOrg = addressee.extraOrganizationList();
233 for (
const Org &
org : lstOrg) {
235 if (!addressee.department().
isEmpty()) {
239 VCardLine orgLine(QStringLiteral(
"ORG"), orgStr);
240 if (version == VCard::v2_1 && needsEncoding(orgStr)) {
241 orgLine.addParameter(QStringLiteral(
"charset"), QStringLiteral(
"UTF-8"));
242 orgLine.addParameter(QStringLiteral(
"encoding"), QStringLiteral(
"QUOTED-PRINTABLE"));
244 orgLine.addParameters(
org.params());
245 card->addLine(orgLine);
249void VCardTool::processPhoneNumbers(
const PhoneNumber::List &phoneNumbers, VCard::Version version, VCard *card)
const
251 for (
const auto &phone : phoneNumbers) {
252 VCardLine line(QStringLiteral(
"TEL"), phone.number());
253 const ParameterMap paramsMap = phone.params();
254 for (
const auto &[param, list] : paramsMap) {
262 for (
const auto &pType : s_phoneTypes) {
263 if (pType.flag & type) {
265 if (version == VCard::v4_0) {
273 addParameter(&line, version, QStringLiteral(
"TYPE"), lst);
279void VCardTool::processCustoms(
const QStringList &customs, VCard::Version version, VCard *card,
bool exportVcard)
const
281 for (
const auto &str : customs) {
290 identifier = QStringLiteral(
"X-AIM");
291 }
else if (identifier ==
QLatin1String(
"X-messaging/icq-All")) {
292 identifier = QStringLiteral(
"X-ICQ");
293 }
else if (identifier ==
QLatin1String(
"X-messaging/xmpp-All")) {
294 identifier = QStringLiteral(
"X-JABBER");
295 }
else if (identifier ==
QLatin1String(
"X-messaging/msn-All")) {
296 identifier = QStringLiteral(
"X-MSN");
297 }
else if (identifier ==
QLatin1String(
"X-messaging/yahoo-All")) {
298 identifier = QStringLiteral(
"X-YAHOO");
299 }
else if (identifier ==
QLatin1String(
"X-messaging/gadu-All")) {
300 identifier = QStringLiteral(
"X-GADUGADU");
301 }
else if (identifier ==
QLatin1String(
"X-messaging/skype-All")) {
302 identifier = QStringLiteral(
"X-SKYPE");
303 }
else if (identifier ==
QLatin1String(
"X-messaging/groupwise-All")) {
304 identifier = QStringLiteral(
"X-GROUPWISE");
305 }
else if (identifier ==
QLatin1String(
"X-messaging/sms-All")) {
306 identifier = QStringLiteral(
"X-SMS");
307 }
else if (identifier ==
QLatin1String(
"X-messaging/meanwhile-All")) {
308 identifier = QStringLiteral(
"X-MEANWHILE");
309 }
else if (identifier ==
QLatin1String(
"X-messaging/irc-All")) {
310 identifier = QStringLiteral(
"X-IRC");
311 }
else if (identifier ==
QLatin1String(
"X-messaging/googletalk-All")) {
313 identifier = QStringLiteral(
"X-GTALK");
314 }
else if (identifier ==
QLatin1String(
"X-messaging/twitter-All")) {
315 identifier = QStringLiteral(
"X-TWITTER");
319 if (identifier.
toLower() ==
QLatin1String(
"x-kaddressbook-x-anniversary") && version == VCard::v4_0) {
325 VCardLine line(QStringLiteral(
"ANNIVERSARY"), createDateTime(dt, version,
false));
328 }
else if (identifier.
toLower() ==
QLatin1String(
"x-kaddressbook-x-spousesname") && version == VCard::v4_0) {
330 VCardLine line(QStringLiteral(
"RELATED"), QStringLiteral(
";"));
331 line.addParameter(QStringLiteral(
"TYPE"), QStringLiteral(
"spouse"));
332 line.addParameter(QStringLiteral(
"VALUE"), value);
336 VCardLine line(identifier, value);
337 if (version == VCard::v2_1 && needsEncoding(value)) {
338 line.addParameter(QStringLiteral(
"charset"), QStringLiteral(
"UTF-8"));
339 line.addParameter(QStringLiteral(
"encoding"), QStringLiteral(
"QUOTED-PRINTABLE"));
348 VCard::List vCardList;
350 for (
const auto &addressee : list) {
353 if (version == VCard::v2_1) {
354 card.addLine(VCardLine(QStringLiteral(
"VERSION"), QStringLiteral(
"2.1")));
355 }
else if (version == VCard::v3_0) {
356 card.addLine(VCardLine(QStringLiteral(
"VERSION"), QStringLiteral(
"3.0")));
357 }
else if (version == VCard::v4_0) {
358 card.addLine(VCardLine(QStringLiteral(
"VERSION"), QStringLiteral(
"4.0")));
363 processAddresses(addresses, version, &card);
366 const bool withTime = addressee.birthdayHasTime();
367 const QString birthdayString = createDateTime(addressee.birthday(), version, withTime);
368 card.addLine(VCardLine(QStringLiteral(
"BDAY"), birthdayString));
371 if (version != VCard::v2_1) {
373 for (
auto &cat : categories) {
377 VCardLine catLine(QStringLiteral(
"CATEGORIES"), categories.join(
QLatin1Char(
',')));
378 card.addLine(catLine);
381 if (version == VCard::v4_0) {
385 for (
const QString &member : lst) {
386 card.addLine(VCardLine(QStringLiteral(
"MEMBER"), member));
391 const QList<QUrl> lstUrl = addressee.sourcesUrlList();
392 for (
const QUrl &url : lstUrl) {
393 VCardLine line = VCardLine(QStringLiteral(
"SOURCE"), url.url());
398 for (
const auto &rel : relatedList) {
399 VCardLine line(QStringLiteral(
"RELATED"), rel.related());
400 line.addParameters(rel.params());
404 if (version == VCard::v3_0) {
405 card.addLine(createSecrecy(addressee.
secrecy()));
408 if (version == VCard::v4_0) {
410 for (
const auto &lang : langList) {
411 VCardLine line(QStringLiteral(
"LANG"), lang.language());
412 line.addParameters(lang.params());
417 if (version == VCard::v4_0) {
419 for (
const auto &pMap : clientpidmapList) {
420 VCardLine line(QStringLiteral(
"CLIENTPIDMAP"), pMap.clientPidMap());
421 line.addParameters(pMap.params());
426 const Email::List emailList = addressee.emailList();
427 processEmailList(emailList, version, &card);
430 VCardLine fnLine(QStringLiteral(
"FN"), addressee.formattedName());
431 if (version == VCard::v2_1 && needsEncoding(addressee.formattedName())) {
432 fnLine.addParameter(QStringLiteral(
"charset"), QStringLiteral(
"UTF-8"));
433 fnLine.addParameter(QStringLiteral(
"encoding"), QStringLiteral(
"QUOTED-PRINTABLE"));
435 card.addLine(fnLine);
438 const Geo geo = addressee.geo();
441 if (version == VCard::v4_0) {
446 card.addLine(VCardLine(QStringLiteral(
"GEO"), str));
451 for (
const auto &k : keys) {
452 card.addLine(createKey(k, version));
456 card.addLine(createPicture(QStringLiteral(
"LOGO"), addressee.
logo(), version));
458 for (
const Picture &logo : lstLogo) {
459 card.addLine(createPicture(QStringLiteral(
"LOGO"), logo, version));
463 if (version != VCard::v4_0) {
464 VCardLine mailerLine(QStringLiteral(
"MAILER"), addressee.mailer());
465 if (version == VCard::v2_1 && needsEncoding(addressee.mailer())) {
466 mailerLine.addParameter(QStringLiteral(
"charset"), QStringLiteral(
"UTF-8"));
467 mailerLine.addParameter(QStringLiteral(
"encoding"), QStringLiteral(
"QUOTED-PRINTABLE"));
469 card.addLine(mailerLine);
481 if (version == VCard::v2_1 && needsEncoding(
name.join(
QLatin1Char(
';')))) {
482 nLine.addParameter(QStringLiteral(
"charset"), QStringLiteral(
"UTF-8"));
483 nLine.addParameter(QStringLiteral(
"encoding"), QStringLiteral(
"QUOTED-PRINTABLE"));
485 if (version == VCard::v4_0 && !addressee.sortString().
isEmpty()) {
486 nLine.addParameter(QStringLiteral(
"SORT-AS"), addressee.sortString());
492 if (version != VCard::v4_0) {
493 VCardLine nameLine(QStringLiteral(
"NAME"), addressee.name());
494 if (version == VCard::v2_1 && needsEncoding(addressee.name())) {
495 nameLine.addParameter(QStringLiteral(
"charset"), QStringLiteral(
"UTF-8"));
496 nameLine.addParameter(QStringLiteral(
"encoding"), QStringLiteral(
"QUOTED-PRINTABLE"));
498 card.addLine(nameLine);
502 if (version != VCard::v2_1) {
504 for (
const NickName &nickName : lstNickName) {
505 VCardLine nickNameLine(QStringLiteral(
"NICKNAME"), nickName.nickname());
506 nickNameLine.addParameters(nickName.params());
508 card.addLine(nickNameLine);
513 VCardLine noteLine(QStringLiteral(
"NOTE"), addressee.note());
514 if (version == VCard::v2_1 && needsEncoding(addressee.note())) {
515 noteLine.addParameter(QStringLiteral(
"charset"), QStringLiteral(
"UTF-8"));
516 noteLine.addParameter(QStringLiteral(
"encoding"), QStringLiteral(
"QUOTED-PRINTABLE"));
518 card.addLine(noteLine);
521 processOrganizations(addressee, version, &card);
524 card.addLine(createPicture(QStringLiteral(
"PHOTO"), addressee.photo(), version));
526 for (
const Picture &photo : lstExtraPhoto) {
527 card.addLine(createPicture(QStringLiteral(
"PHOTO"), photo, version));
531 if (version != VCard::v2_1) {
532 card.addLine(VCardLine(QStringLiteral(
"PRODID"), addressee.productId()));
536 card.addLine(VCardLine(QStringLiteral(
"REV"), createDateTime(addressee.revision(), version)));
539 const QList<Role> lstExtraRole = addressee.extraRoleList();
540 for (
const Role &role : lstExtraRole) {
541 VCardLine roleLine(QStringLiteral(
"ROLE"), role.role());
542 if (version == VCard::v2_1 && needsEncoding(role.role())) {
543 roleLine.addParameter(QStringLiteral(
"charset"), QStringLiteral(
"UTF-8"));
544 roleLine.addParameter(QStringLiteral(
"encoding"), QStringLiteral(
"QUOTED-PRINTABLE"));
546 roleLine.addParameters(role.params());
547 card.addLine(roleLine);
551 if (version == VCard::v3_0) {
552 card.addLine(VCardLine(QStringLiteral(
"SORT-STRING"), addressee.sortString()));
556 card.addLine(createSound(addressee.
sound(), version));
557 const QList<Sound> lstSound = addressee.extraSoundList();
558 for (
const Sound &sound : lstSound) {
559 card.addLine(createSound(sound, version));
564 processPhoneNumbers(phoneNumbers, version, &card);
567 const QList<Title> lstTitle = addressee.extraTitleList();
568 for (
const Title &title : lstTitle) {
569 VCardLine titleLine(QStringLiteral(
"TITLE"), title.title());
570 if (version == VCard::v2_1 && needsEncoding(title.title())) {
571 titleLine.addParameter(QStringLiteral(
"charset"), QStringLiteral(
"UTF-8"));
572 titleLine.addParameter(QStringLiteral(
"encoding"), QStringLiteral(
"QUOTED-PRINTABLE"));
574 titleLine.addParameters(title.params());
576 card.addLine(titleLine);
584 if (timeZone.
offset() < 0) {
591 card.addLine(VCardLine(QStringLiteral(
"TZ"), str));
595 card.addLine(VCardLine(QStringLiteral(
"UID"), addressee.uid()));
600 VCardLine line(QStringLiteral(
"URL"), url.url());
601 line.addParameters(url.params());
604 if (version == VCard::v4_0) {
606 const Gender gender = addressee.gender();
607 if (gender.isValid()) {
609 if (!gender.gender().
isEmpty()) {
610 genderStr = gender.gender();
612 if (!gender.comment().
isEmpty()) {
615 VCardLine line(QStringLiteral(
"GENDER"), genderStr);
619 if (!addressee.kind().
isEmpty()) {
620 VCardLine line(QStringLiteral(
"KIND"), addressee.kind());
625 if (version == VCard::v4_0) {
630 switch (url.type()) {
632 case CalendarUrl::EndCalendarType:
635 type = QStringLiteral(
"FBURL");
638 type = QStringLiteral(
"CALURI");
641 type = QStringLiteral(
"CALADRURI");
644 if (!
type.isEmpty()) {
645 VCardLine line(type, url.url().toDisplayString());
646 line.addParameters(url.params());
656 VCardLine line(group.fieldGroupName(), group.value());
657 line.addParameters(group.params());
663 for (
const Impp &impp : lstImpp) {
664 VCardLine line(QStringLiteral(
"IMPP"), impp.address().url());
665 const ParameterMap pMap = impp.params();
666 for (
const auto &[param, list] : pMap) {
676 processCustoms(customs, version, &card, exportVcard);
678 vCardList.append(card);
681 return VCardParser::createVCards(vCardList);
691 const VCard::List vCardList = VCardParser::parseVCards(vcard);
693 VCard::List::ConstIterator cardIt;
694 VCard::List::ConstIterator listEnd(vCardList.end());
695 for (cardIt = vCardList.begin(); cardIt != listEnd; ++cardIt) {
698 const QStringList idents = (*cardIt).identifiers();
701 for (identIt = idents.
begin(); identIt != identEnd; ++identIt) {
702 const VCardLine::List lines = (*cardIt).lines((*identIt));
703 VCardLine::List::ConstIterator lineIt;
706 for (lineIt = lines.begin(); lineIt != lines.end(); ++lineIt) {
707 identifier = (*lineIt).identifier().
toLower();
708 group = (*lineIt).group();
711 groupField.setParams((*lineIt).parameterMap());
712 groupField.setValue((*lineIt).value().toString());
713 addr.insertFieldGroup(groupField);
719 const int addrPartsCount(addrParts.
count());
720 if (addrPartsCount > 0) {
721 address.setPostOfficeBox(addrParts.
at(0));
723 if (addrPartsCount > 1) {
726 if (addrPartsCount > 2) {
729 if (addrPartsCount > 3) {
732 if (addrPartsCount > 4) {
735 if (addrPartsCount > 5) {
738 if (addrPartsCount > 6) {
744 const QStringList types = (*lineIt).parameters(QStringLiteral(
"type"));
747 type |= stringToAddressType((*it).toLower());
751 QString label = (*lineIt).parameter(QStringLiteral(
"label"));
760 QString geoStr = (*lineIt).parameter(QStringLiteral(
"geo"));
763 geoStr.
remove(QStringLiteral(
"geo:"));
767 geo.setLatitude(arguments.
at(0).toDouble());
768 geo.setLongitude(arguments.
at(1).toDouble());
776 const QString t = (*lineIt).value().toString();
783 const QDateTime bday = parseDateTime((*lineIt).value().toString(), &withTime);
795 const QUrl url =
QUrl((*lineIt).value().toString());
797 calurl.setParams((*lineIt).parameterMap());
798 addr.insertCalendarUrl(calurl);
804 const QUrl url =
QUrl((*lineIt).value().toString());
806 calurl.setParams((*lineIt).parameterMap());
807 addr.insertCalendarUrl(calurl);
813 const QUrl url =
QUrl((*lineIt).value().toString());
815 calurl.setParams((*lineIt).parameterMap());
816 addr.insertCalendarUrl(calurl);
820 QUrl imppUrl((*lineIt).value().toString());
822 impp.setParams((*lineIt).parameterMap());
823 if (!(*lineIt).parameter(QStringLiteral(
"x-service-type")).isEmpty() && imppUrl.scheme().isEmpty()) {
824 imppUrl.setScheme(normalizeImppServiceType((*lineIt).parameter(QStringLiteral(
"x-service-type")).toLower()));
826 impp.setAddress(imppUrl);
827 addr.insertImpp(impp);
835 QString genderStr = (*lineIt).value().toString();
839 gender.setGender(genderStr.
at(0));
841 gender.setComment(genderStr.
right(genderStr.
length() - 2));
844 gender.setComment(genderStr.
right(genderStr.
length() - 1));
846 addr.setGender(gender);
852 lang.setLanguage((*lineIt).value().toString());
853 lang.setParams((*lineIt).parameterMap());
858 const QStringList types = (*lineIt).parameters(QStringLiteral(
"type"));
859 Email mail((*lineIt).value().toString());
860 mail.setParams((*lineIt).parameterMap());
865 addr.setKind((*lineIt).value().toString());
874 QString lineStr = (*lineIt).value().toString();
876 lineStr.
remove(QStringLiteral(
"geo:"));
878 if (geoParts.
size() >= 2) {
879 geo.setLatitude(geoParts.
at(0).toFloat());
880 geo.setLongitude(geoParts.
at(1).toFloat());
885 if (geoParts.
size() >= 2) {
886 geo.setLatitude(geoParts.
at(0).toFloat());
887 geo.setLongitude(geoParts.
at(1).toFloat());
900 const QStringList types = (*lineIt).parameters(QStringLiteral(
"type"));
903 type |= stringToAddressType((*it).toLower());
906 bool available =
false;
909 if ((*it).type() == type) {
910 (*it).setLabel((*lineIt).value().toString());
919 address.setLabel((*lineIt).value().toString());
925 Picture picture = parsePicture(*lineIt);
926 if (addr.
logo().isEmpty()) {
929 addr.insertExtraLogo(picture);
934 addr.
setMailer((*lineIt).value().toString());
939 const int numberOfParts(nameParts.
count());
940 if (numberOfParts > 0) {
943 if (numberOfParts > 1) {
946 if (numberOfParts > 2) {
949 if (numberOfParts > 3) {
952 if (numberOfParts > 4) {
955 if (!(*lineIt).parameter(QStringLiteral(
"sort-as")).isEmpty()) {
956 addr.
setSortString((*lineIt).parameter(QStringLiteral(
"sort-as")));
961 addr.
setName((*lineIt).value().toString());
965 NickName nickName((*lineIt).value().toString());
966 nickName.setParams((*lineIt).parameterMap());
967 addr.insertExtraNickName(nickName);
971 addr.
setNote((*lineIt).value().toString());
976 const int orgPartsCount(orgParts.
count());
977 if (orgPartsCount > 0) {
978 Org organization(orgParts.
at(0));
979 organization.setParams((*lineIt).parameterMap());
980 addr.insertExtraOrganization(organization);
982 if (orgPartsCount > 1) {
985 if (!(*lineIt).parameter(QStringLiteral(
"sort-as")).isEmpty()) {
986 addr.
setSortString((*lineIt).parameter(QStringLiteral(
"sort-as")));
991 Picture picture = parsePicture(*lineIt);
992 if (addr.photo().isEmpty()) {
995 addr.insertExtraPhoto(picture);
1004 addr.
setRevision(parseDateTime((*lineIt).value().toString()));
1008 Role role((*lineIt).value().toString());
1009 role.setParams((*lineIt).parameterMap());
1010 addr.insertExtraRole(role);
1018 Sound sound = parseSound(*lineIt);
1022 addr.insertExtraSound(sound);
1028 phone.
setNumber((*lineIt).value().toString());
1031 bool foundType =
false;
1032 const QStringList types = (*lineIt).parameters(QStringLiteral(
"type"));
1035 type |= stringToPhoneType((*it).toUpper());
1038 phone.
setType(foundType ? type : PhoneNumber::Undefined);
1039 phone.setParams((*lineIt).parameterMap());
1045 Title title((*lineIt).value().toString());
1046 title.setParams((*lineIt).parameterMap());
1047 addr.insertExtraTitle(title);
1057 int hours = dateView.mid(1, 2).toInt();
1058 int minutes = dateView.mid(4, 2).toInt();
1059 int offset = (hours * 60) + minutes;
1060 offset = offset * (date[0] ==
QLatin1Char(
'+') ? 1 : -1);
1068 addr.
setUid((*lineIt).value().toString());
1072 const QUrl url =
QUrl((*lineIt).value().toString());
1074 resourceLocatorUrl.setUrl(url);
1075 resourceLocatorUrl.setParams((*lineIt).parameterMap());
1076 addr.insertExtraUrl(resourceLocatorUrl);
1080 const QUrl url =
QUrl((*lineIt).value().toString());
1081 addr.insertSourceUrl(url);
1085 addr.insertMember((*lineIt).value().toString());
1090 related.setRelated((*lineIt).value().toString());
1091 related.setParams((*lineIt).parameterMap());
1092 addr.insertRelationship(related);
1097 clientpidmap.setClientPidMap((*lineIt).value().toString());
1098 clientpidmap.setParams((*lineIt).parameterMap());
1099 addr.insertClientPidMap(clientpidmap);
1104 QString ident = (*lineIt).identifier();
1110 ident = QStringLiteral(
"X-KADDRESSBOOK-X-SpousesName");
1112 ident = QStringLiteral(
"X-KADDRESSBOOK-BlogFeed");
1113 }
else if (identifier ==
QLatin1String(
"x-evolution-assistant")
1116 ident = QStringLiteral(
"X-KADDRESSBOOK-X-AssistantsName");
1117 }
else if (identifier ==
QLatin1String(
"x-evolution-anniversary")
1120 ident = QStringLiteral(
"X-KADDRESSBOOK-X-Anniversary");
1121 }
else if (identifier ==
QLatin1String(
"x-evolution-manager")
1125 ident = QStringLiteral(
"X-KADDRESSBOOK-X-ManagersName");
1127 ident = QStringLiteral(
"X-KADDRESSBOOK-X-Profession");
1129 ident = QStringLiteral(
"X-KADDRESSBOOK-X-Office");
1131 ident = QStringLiteral(
"X-KADDRESSBOOK-X-SpousesName");
1133 ident = QStringLiteral(
"X-messaging/aim-All");
1135 ident = QStringLiteral(
"X-messaging/icq-All");
1137 ident = QStringLiteral(
"X-messaging/xmpp-All");
1139 ident = QStringLiteral(
"X-messaging/xmpp-All");
1141 ident = QStringLiteral(
"X-messaging/msn-All");
1143 ident = QStringLiteral(
"X-messaging/yahoo-All");
1145 ident = QStringLiteral(
"X-messaging/gadu-All");
1147 ident = QStringLiteral(
"X-messaging/skype-All");
1149 ident = QStringLiteral(
"X-messaging/groupwise-All");
1151 ident = QStringLiteral(
"X-messaging/sms-All");
1153 ident = QStringLiteral(
"X-messaging/meanwhile-All");
1155 ident = QStringLiteral(
"X-messaging/irc-All");
1157 ident = QStringLiteral(
"X-messaging/googletalk-All");
1159 ident = QStringLiteral(
"X-messaging/twitter-All");
1168 url.
setScheme(normalizeImppServiceType(key.
mid(10, dash - 10)));
1170 for (
const auto &value : values) {
1173 impp.setParams((*lineIt).parameterMap());
1174 impp.setAddress(url);
1175 addr.insertImpp(impp);
1195 QString dateString = posT >= 0 ? str.
left(posT) : str;
1202 date.
setDate(-1, dstr.mid(0, 2).toInt(), dstr.mid(2, 2).toInt());
1205 date.
setDate(dstr.mid(0, 4).toInt(), dstr.mid(4, 2).toInt(), dstr.mid(6, 2).toInt());
1215 const int minusPos = timeString.
indexOf(sep);
1216 const int tzPos = qMax(qMax(zPos, plusPos), minusPos);
1221 switch (hhmmssString.
size()) {
1223 hour = hhmmssString.
toInt();
1226 hour = hhmmssString.
mid(0, 2).
toInt();
1227 minutes = hhmmssString.
mid(2, 2).
toInt();
1230 hour = hhmmssString.
mid(0, 2).
toInt();
1231 minutes = hhmmssString.
mid(2, 2).
toInt();
1232 seconds = hhmmssString.
mid(4, 2).
toInt();
1235 time.
setHMS(hour, minutes, seconds);
1242 const auto offsetString =
QStringView(timeString).
mid(tzPos + 1);
1243 switch (offsetString.size()) {
1245 offsetSecs = offsetString.left(2).toInt() * 3600;
1248 offsetSecs = offsetString.left(2).toInt() * 3600 + offsetString.mid(2, 2).toInt() * 60;
1251 if (minusPos >= 0) {
1265QString VCardTool::createDateTime(
const QDateTime &dateTime, VCard::Version version,
bool withTime)
1270 QString str = createDate(dateTime.
date(), version);
1274 str += createTime(dateTime.
time(), version);
1279 if (offsetSecs >= 0) {
1285 if (version == VCard::v4_0) {
1286 str += offsetTime.
toString(QStringLiteral(
"HHmm"));
1288 str += offsetTime.
toString(QStringLiteral(
"HH:mm"));
1294QString VCardTool::createDate(
const QDate &date, VCard::Version version)
1297 if (date.
year() > 0) {
1298 format = QStringLiteral(
"yyyyMMdd");
1300 format = QStringLiteral(
"--MMdd");
1302 if (version != VCard::v4_0) {
1303 format.
replace(QStringLiteral(
"yyyy"), QStringLiteral(
"yyyy-"));
1304 format.
replace(QStringLiteral(
"MM"), QStringLiteral(
"MM-"));
1309QString VCardTool::createTime(
const QTime &time, VCard::Version version)
1312 if (version == VCard::v4_0) {
1313 format = QStringLiteral(
"HHmmss");
1315 format = QStringLiteral(
"HH:mm:ss");
1320Picture VCardTool::parsePicture(
const VCardLine &line)
const
1327 type = line.parameter(QStringLiteral(
"type"));
1330 pic.
setRawData(line.value().toByteArray(), type);
1332 if (line.parameter(QStringLiteral(
"value")).toLower() ==
QLatin1String(
"uri")) {
1333 pic.
setUrl(line.value().toString());
1340VCardLine VCardTool::createPicture(
const QString &identifier,
const Picture &pic, VCard::Version version)
const
1342 VCardLine line(identifier);
1344 if (pic.isEmpty()) {
1348 if (pic.isIntern()) {
1350 if (version == VCard::v2_1) {
1351 line.addParameter(QStringLiteral(
"ENCODING"), QStringLiteral(
"BASE64"));
1354 line.addParameter(QStringLiteral(
"encoding"), QStringLiteral(
"b"));
1355 line.addParameter(QStringLiteral(
"type"), pic.
type());
1358 line.addParameter(QStringLiteral(
"data") + QStringLiteral(
":image/") + pic.
type(), QStringLiteral(
"base64"));
1362 line.setValue(pic.url());
1363 line.addParameter(QStringLiteral(
"value"), QStringLiteral(
"URI"));
1369Sound VCardTool::parseSound(
const VCardLine &line)
const
1375 snd.
setData(line.value().toByteArray());
1377 if (line.parameter(QStringLiteral(
"value")).toLower() ==
QLatin1String(
"uri")) {
1378 snd.
setUrl(line.value().toString());
1390VCardLine VCardTool::createSound(
const Sound &snd, VCard::Version version)
const
1393 VCardLine line(QStringLiteral(
"SOUND"));
1397 line.setValue(snd.
data());
1398 if (version == VCard::v2_1) {
1399 line.addParameter(QStringLiteral(
"ENCODING"), QStringLiteral(
"BASE64"));
1401 line.addParameter(QStringLiteral(
"encoding"), QStringLiteral(
"b"));
1406 line.setValue(snd.
url());
1407 line.addParameter(QStringLiteral(
"value"), QStringLiteral(
"URI"));
1413Key VCardTool::parseKey(
const VCardLine &line)
const
1425 if (line.parameter(QStringLiteral(
"type")).toLower() ==
QLatin1String(
"x509")) {
1427 }
else if (line.parameter(QStringLiteral(
"type")).toLower() ==
QLatin1String(
"pgp")) {
1434 const QString param = line.parameter(QStringLiteral(
"mediatype")).
toLower();
1437 }
else if (param ==
QLatin1String(
"application/pgp-keys")) {
1448VCardLine VCardTool::createKey(
const Key &key, VCard::Version version)
const
1450 VCardLine line(QStringLiteral(
"KEY"));
1455 if (version == VCard::v2_1) {
1456 line.addParameter(QStringLiteral(
"ENCODING"), QStringLiteral(
"BASE64"));
1458 line.addParameter(QStringLiteral(
"encoding"), QStringLiteral(
"b"));
1465 if (version == VCard::v4_0) {
1467 line.addParameter(QStringLiteral(
"MEDIATYPE"), QStringLiteral(
"application/x-x509-ca-cert"));
1469 line.addParameter(QStringLiteral(
"MEDIATYPE"), QStringLiteral(
"application/pgp-keys"));
1475 line.addParameter(QStringLiteral(
"type"), QStringLiteral(
"X509"));
1477 line.addParameter(QStringLiteral(
"type"), QStringLiteral(
"PGP"));
1486Secrecy VCardTool::parseSecrecy(
const VCardLine &line)
const
1492 secrecy.
setType(Secrecy::Public);
1494 secrecy.
setType(Secrecy::Private);
1496 secrecy.
setType(Secrecy::Confidential);
1502VCardLine VCardTool::createSecrecy(
const Secrecy &secrecy)
const
1504 VCardLine line(QStringLiteral(
"CLASS"));
1508 if (type == Secrecy::Public) {
1509 line.setValue(QStringLiteral(
"PUBLIC"));
1510 }
else if (type == Secrecy::Private) {
1511 line.setValue(QStringLiteral(
"PRIVATE"));
1512 }
else if (type == Secrecy::Confidential) {
1513 line.setValue(QStringLiteral(
"CONFIDENTIAL"));
1528 if (pos == 0 || value[pos - 1] !=
QLatin1Char(
'\\')) {
1538 value.
replace(pos - 1, 2, sep);
1539 pos = value.
indexOf(sep, pos);
1543 int l = value.
length() - 1;
1554QString VCardTool::normalizeImppServiceType(
const QString &serviceType)
const
1557 return QStringLiteral(
"xmpp");
1560 return QStringLiteral(
"ymsgr");
1563 return QStringLiteral(
"gg");
Q_SCRIPTABLE Q_NOREPLY void start()
QString name(GameStandardAction id)
QAction * end(const QObject *recvr, const char *slot, QObject *parent)
GeoCoordinates geo(const QVariant &location)
PostalAddress address(const QVariant &location)
VehicleSection::Type type(QStringView coachNumber, QStringView coachClassification)
KIOCORE_EXPORT QStringList list(const QString &fileClass)
QAction * mail(const QObject *recvr, const char *slot, QObject *parent)
QString label(StandardShortcut id)
Trait::StringList splitString(const typename Trait::String &str, const typename Trait::Char &ch)
bool isEmpty() const const
char toLatin1() const const
QDate fromString(QStringView string, QStringView format, QCalendar cal)
bool isValid(int year, int month, int day)
bool setDate(int year, int month, int day)
QDateTime startOfDay() const const
QString toString(QStringView format, QCalendar cal) const const
int offsetFromUtc() const const
Qt::TimeSpec timeSpec() const const
void append(QList< T > &&value)
const_reference at(qsizetype i) const const
const_iterator constBegin() const const
const_iterator constEnd() const const
qsizetype count() const const
bool isEmpty() const const
qsizetype removeAll(const AT &t)
qsizetype size() const const
QString & append(QChar ch)
QString asprintf(const char *cformat,...)
const QChar at(qsizetype position) const const
int compare(QLatin1StringView s1, const QString &s2, Qt::CaseSensitivity cs)
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
QString fromLatin1(QByteArrayView str)
qsizetype indexOf(QChar ch, qsizetype from, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
QString left(qsizetype n) const const
qsizetype length() const const
QString mid(qsizetype position, qsizetype n) const const
QString & remove(QChar ch, Qt::CaseSensitivity cs)
QString & replace(QChar before, QChar after, Qt::CaseSensitivity cs)
QString right(qsizetype n) const const
QStringList split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
QString toLower() const const
bool contains(QLatin1StringView str, Qt::CaseSensitivity cs) const const
QString join(QChar separator) const const
QStringView left(qsizetype length) const const
QStringView mid(qsizetype start, qsizetype length) const const
qsizetype size() const const
int toInt(bool *ok, int base) const const
QTime addSecs(int s) const const
bool isValid(int h, int m, int s, int ms)
bool setHMS(int h, int m, int s, int ms)
QString toString(QStringView format) const const
QTimeZone fromSecondsAheadOfUtc(int offset)
void setPath(const QString &path, ParsingMode mode)
void setScheme(const QString &scheme)