• Skip to content
  • Skip to link menu
Brand

API Documentation

  1. KDE API Reference
  2. The KDE Frameworks
  3. KContacts
  • KDE Home
  • Contact Us

Quick Links

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

Class Picker

About

Address book API for KDE

Maintainer
Laurent Montel
Supported platforms
Android, FreeBSD, iOS, Linux, MacOSX, Windows
Community
IRC: #kde-devel on Freenode
Mailing list: kde-frameworks-devel
Use with CMake
find_package(KF5Contacts)
target_link_libraries(yourapp KF5::Contacts)
Use with QMake
QT += KContacts 
Clone
git clone git://anongit.kde.org/kcontacts.git
Browse source
KContacts on cgit.kde.org

KContacts

  • frameworks
  • frameworks
  • kcontacts
  • src
vcardtool.cpp
1 /*
2  This file is part of the KContacts framework.
3  Copyright (c) 2003 Tobias Koenig <[email protected]>
4  Copyright (C) 2015-2019 Laurent Montel <[email protected]>
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Library General Public
8  License as published by the Free Software Foundation; either
9  version 2 of the License, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Library General Public License for more details.
15 
16  You should have received a copy of the GNU Library General Public License
17  along with this library; see the file COPYING.LIB. If not, write to
18  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  Boston, MA 02110-1301, USA.
20 */
21 
22 #include "vcardtool_p.h"
23 #include "key.h"
24 #include "picture.h"
25 #include "secrecy.h"
26 #include "sound.h"
27 #include "lang.h"
28 #include "gender.h"
29 #include "related.h"
30 #include "fieldgroup.h"
31 #include "kcontacts_debug.h"
32 #include <QString>
33 
34 using namespace KContacts;
35 
36 static bool needsEncoding(const QString &value)
37 {
38  int length = value.length();
39  for (int i = 0; i < length; ++i) {
40  char c = value.at(i).toLatin1();
41  if ((c < 33 || c > 126) && c != ' ' && c != '=') {
42  return true;
43  }
44  }
45 
46  return false;
47 }
48 
49 static const struct {
50  const char *addressType;
51  Address::TypeFlag flag;
52 } s_addressTypes[] = {
53  { "dom", Address::Dom },
54  { "home", Address::Home },
55  { "intl", Address::Intl },
56  { "parcel", Address::Parcel },
57  { "postal", Address::Postal },
58  { "pref", Address::Pref },
59  { "work", Address::Work },
60 };
61 
62 static const unsigned int s_numAddressTypes
63  = sizeof s_addressTypes / sizeof *s_addressTypes;
64 
65 static Address::TypeFlag stringToAddressType(const QString &str)
66 {
67  for (unsigned int i = 0; i < s_numAddressTypes; ++i) {
68  if (str == QLatin1String(s_addressTypes[i].addressType)) {
69  return s_addressTypes[i].flag;
70  }
71  }
72  return {};
73 }
74 
75 static const struct {
76  const char *phoneType;
77  PhoneNumber::TypeFlag flag;
78 } s_phoneTypes[] = {
79  { "BBS", PhoneNumber::Bbs },
80  { "CAR", PhoneNumber::Car },
81  { "CELL", PhoneNumber::Cell },
82  { "FAX", PhoneNumber::Fax },
83  { "HOME", PhoneNumber::Home },
84  { "ISDN", PhoneNumber::Isdn },
85  { "MODEM", PhoneNumber::Modem },
86  { "MSG", PhoneNumber::Msg },
87  { "PAGER", PhoneNumber::Pager },
88  { "PCS", PhoneNumber::Pcs },
89  { "PREF", PhoneNumber::Pref },
90  { "VIDEO", PhoneNumber::Video },
91  { "VOICE", PhoneNumber::Voice },
92  { "WORK", PhoneNumber::Work },
93 };
94 
95 static const unsigned int s_numPhoneTypes
96  = sizeof s_phoneTypes / sizeof *s_phoneTypes;
97 
98 static PhoneNumber::TypeFlag stringToPhoneType(const QString &str)
99 {
100  for (unsigned int i = 0; i < s_numPhoneTypes; ++i) {
101  if (str == QLatin1String(s_phoneTypes[i].phoneType)) {
102  return s_phoneTypes[i].flag;
103  }
104  }
105  return {};
106 }
107 
108 VCardTool::VCardTool()
109 {
110 }
111 
112 VCardTool::~VCardTool()
113 {
114 }
115 
116 QByteArray VCardTool::exportVCards(const Addressee::List &list, VCard::Version version) const
117 {
118  return createVCards(list, version, true /*export vcard*/);
119 }
120 
121 QByteArray VCardTool::createVCards(const Addressee::List &list, VCard::Version version) const
122 {
123  return createVCards(list, version, false /*don't export*/);
124 }
125 
126 void VCardTool::addParameters(VCardLine &line, const QMap<QString, QStringList> &params) const
127 {
128  QMapIterator<QString, QStringList> i(params);
129  while (i.hasNext()) {
130  i.next();
131  line.addParameter(i.key(), i.value().join(QLatin1Char(',')));
132  }
133 }
134 
135 void VCardTool::addParameter(VCardLine &line, VCard::Version version, const QString &key, const QStringList &valueStringList) const
136 {
137  if (version == VCard::v2_1) {
138  for (const QString &valueStr : valueStringList) {
139  line.addParameter(valueStr, QString());
140  }
141  } else if (version == VCard::v3_0) {
142  line.addParameter(key, valueStringList.join(QLatin1Char(',')));
143  } else {
144  if (valueStringList.count() < 2) {
145  line.addParameter(key, valueStringList.join(QLatin1Char(',')));
146  } else {
147  line.addParameter(key, QLatin1Char('"') + valueStringList.join(QLatin1Char(',')) + QLatin1Char('"'));
148  }
149  }
150 }
151 
152 QByteArray VCardTool::createVCards(const Addressee::List &list, VCard::Version version, bool exportVcard) const
153 {
154  VCard::List vCardList;
155 
156  Addressee::List::ConstIterator addrIt;
157  Addressee::List::ConstIterator listEnd(list.constEnd());
158  for (addrIt = list.constBegin(); addrIt != listEnd; ++addrIt) {
159  VCard card;
160  QStringList::ConstIterator strIt;
161  // VERSION
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")));
168  }
169 
170  // ADR + LABEL
171  const Address::List addresses = (*addrIt).addresses();
172  Address::List::ConstIterator end(addresses.end());
173  for (Address::List::ConstIterator it = addresses.begin(); it != end; ++it) {
174  QStringList address;
175 
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());
183 
184  address.append((*it).postOfficeBox().replace(QLatin1Char(';'),
185  QStringLiteral("\\;")));
186 
187  address.append((*it).extended().replace(QLatin1Char(';'),
188  QStringLiteral("\\;")));
189 
190  address.append((*it).street().replace(QLatin1Char(';'),
191  QStringLiteral("\\;")));
192 
193  address.append((*it).locality().replace(QLatin1Char(';'),
194  QStringLiteral("\\;")));
195 
196  address.append((*it).region().replace(QLatin1Char(';'),
197  QStringLiteral("\\;")));
198 
199  address.append((*it).postalCode().replace(QLatin1Char(';'),
200  QStringLiteral("\\;")));
201 
202  address.append((*it).country().replace(QLatin1Char(';'),
203  QStringLiteral("\\;")));
204 
205  const QString addressJoined(address.join(QLatin1Char(';')));
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"));
210  }
211 
212  const bool hasLabel = !(*it).label().isEmpty();
213  QStringList addreLineType;
214  QStringList labelLineType;
215  for (unsigned int i = 0; i < s_numAddressTypes; ++i) {
216  if (s_addressTypes[i].flag & (*it).type()) {
217  const QString str = QString::fromLatin1(s_addressTypes[i].addressType);
218  addreLineType << str;
219  if (hasLabel) {
220  labelLineType << str;
221  }
222  }
223  }
224 
225  if (hasLabel) {
226  if (version == VCard::v4_0) {
227  if (!(*it).label().isEmpty()) {
228  adrLine.addParameter(QStringLiteral("LABEL"), QStringLiteral("\"%1\"").arg((*it).label()));
229  }
230  } else {
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"));
235  }
236  addParameter(labelLine, version, QStringLiteral("TYPE"), labelLineType);
237  card.addLine(labelLine);
238  }
239  }
240  if (version == VCard::v4_0) {
241  Geo geo = (*it).geo();
242  if (geo.isValid()) {
243  QString str = QString::asprintf("\"geo:%.6f,%.6f\"", geo.latitude(), geo.longitude());
244  adrLine.addParameter(QStringLiteral("GEO"), str);
245  }
246  }
247  if (!isEmpty) {
248  addParameter(adrLine, version, QStringLiteral("TYPE"), addreLineType);
249  card.addLine(adrLine);
250  }
251  }
252 
253  // BDAY
254  const bool withTime = (*addrIt).birthdayHasTime();
255  const QString birthdayString = createDateTime((*addrIt).birthday(), version, withTime);
256  card.addLine(VCardLine(QStringLiteral("BDAY"), birthdayString));
257 
258  //Laurent: 31 Jan 2015. Not necessary to export it. When Categories were changes as AkonadiTag nobody thought that it was break categorie support...
259  //=> not necessary to export just tag...
260  // CATEGORIES only > 2.1
261  if (!exportVcard) {
262  if (version != VCard::v2_1) {
263  QStringList categories = (*addrIt).categories();
264  QStringList::Iterator catIt;
265  QStringList::Iterator catEnd(categories.end());
266  for (catIt = categories.begin(); catIt != catEnd; ++catIt) {
267  (*catIt).replace(QLatin1Char(','), QStringLiteral("\\,"));
268  }
269 
270  VCardLine catLine(QStringLiteral("CATEGORIES"), categories.join(QLatin1Char(',')));
271  card.addLine(catLine);
272  }
273  }
274  // MEMBER (only in 4.0)
275  if (version == VCard::v4_0) {
276  // The KIND property must be set to "group" in order to use this property.
277  if ((*addrIt).kind().toLower() == QLatin1String("group")) {
278  const QStringList lst = (*addrIt).members();
279  for (const QString &member : lst) {
280  VCardLine line(QStringLiteral("MEMBER"), member);
281  card.addLine(line);
282  }
283  }
284  }
285  // SOURCE
286  const QVector<QUrl> lstUrl = (*addrIt).sourcesUrlList();
287  for (const QUrl &url : lstUrl) {
288  VCardLine line = VCardLine(QStringLiteral("SOURCE"), url.url());
289  card.addLine(line);
290  }
291 
292  const Related::List relatedList = (*addrIt).relationships();
293  Related::List::ConstIterator relatedIt;
294  Related::List::ConstIterator relatedEnd(relatedList.end());
295  for (relatedIt = relatedList.begin(); relatedIt != relatedEnd; ++relatedIt) {
296  VCardLine line(QStringLiteral("RELATED"), (*relatedIt).related());
297  addParameters(line, (*relatedIt).parameters());
298  card.addLine(line);
299  }
300  // CLASS only for version == 3.0
301  if (version == VCard::v3_0) {
302  card.addLine(createSecrecy((*addrIt).secrecy()));
303  }
304  // LANG only for version == 4.0
305  if (version == VCard::v4_0) {
306  const Lang::List langList = (*addrIt).langs();
307  Lang::List::ConstIterator langIt;
308  Lang::List::ConstIterator langEnd(langList.end());
309  for (langIt = langList.begin(); langIt != langEnd; ++langIt) {
310  VCardLine line(QStringLiteral("LANG"), (*langIt).language());
311  addParameters(line, (*langIt).parameters());
312  card.addLine(line);
313  }
314  }
315  // CLIENTPIDMAP
316  if (version == VCard::v4_0) {
317  const ClientPidMap::List clientpidmapList = (*addrIt).clientPidMapList();
318  ClientPidMap::List::ConstIterator clientPidMapIt;
319  ClientPidMap::List::ConstIterator clientPidMapEnd(clientpidmapList.end());
320  for (clientPidMapIt = clientpidmapList.begin(); clientPidMapIt != clientPidMapEnd; ++clientPidMapIt) {
321  VCardLine line(QStringLiteral("CLIENTPIDMAP"), (*clientPidMapIt).clientPidMap());
322  addParameters(line, (*clientPidMapIt).parameters());
323  card.addLine(line);
324  }
325  }
326  // EMAIL
327  const Email::List emailList = (*addrIt).emailList();
328  Email::List::ConstIterator emailIt;
329  Email::List::ConstIterator emailEnd(emailList.end());
330  for (emailIt = emailList.begin(); emailIt != emailEnd; ++emailIt) {
331  VCardLine line(QStringLiteral("EMAIL"), (*emailIt).mail());
332  QMapIterator<QString, QStringList> i((*emailIt).parameters());
333  while (i.hasNext()) {
334  i.next();
335  if (version == VCard::v2_1) {
336  if (i.key().toLower() == QLatin1String("type")) {
337  QStringList valueStringList = i.value();
338  bool hasPreferred = false;
339  const int removeItems = valueStringList.removeAll(QStringLiteral("PREF"));
340  if (removeItems > 0) {
341  hasPreferred = true;
342  }
343  if (!valueStringList.isEmpty()) {
344  addParameter(line, version, i.key(), valueStringList);
345  }
346  if (hasPreferred) {
347  line.addParameter(QStringLiteral("PREF"), QString());
348  }
349  } else {
350  line.addParameter(i.key(), i.value().join(QLatin1Char(',')));
351  }
352  } else {
353  line.addParameter(i.key(), i.value().join(QLatin1Char(',')));
354  }
355  }
356  card.addLine(line);
357  }
358 
359  // FN required for only version > 2.1
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"));
364  }
365  card.addLine(fnLine);
366 
367  // GEO
368  const Geo geo = (*addrIt).geo();
369  if (geo.isValid()) {
370  QString str;
371  if (version == VCard::v4_0) {
372  str = QString::asprintf("geo:%.6f,%.6f", geo.latitude(), geo.longitude());
373  } else {
374  str = QString::asprintf("%.6f;%.6f", geo.latitude(), geo.longitude());
375  }
376  card.addLine(VCardLine(QStringLiteral("GEO"), str));
377  }
378 
379  // KEY
380  const Key::List keys = (*addrIt).keys();
381  Key::List::ConstIterator keyIt;
382  Key::List::ConstIterator keyEnd(keys.end());
383  for (keyIt = keys.begin(); keyIt != keyEnd; ++keyIt) {
384  card.addLine(createKey(*keyIt, version));
385  }
386 
387  // LOGO
388  card.addLine(createPicture(QStringLiteral("LOGO"), (*addrIt).logo(), version));
389  const QVector<Picture> lstLogo = (*addrIt).extraLogoList();
390  for (const Picture &logo : lstLogo) {
391  card.addLine(createPicture(QStringLiteral("LOGO"), logo, version));
392  }
393 
394  // MAILER only for version < 4.0
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"));
400  }
401  card.addLine(mailerLine);
402  }
403 
404  // N required for only version < 4.0
405  QStringList name;
406  name.append((*addrIt).familyName().replace(QLatin1Char(';'),
407  QStringLiteral("\\;")));
408 
409  name.append((*addrIt).givenName().replace(QLatin1Char(';'),
410  QStringLiteral("\\;")));
411 
412  name.append((*addrIt).additionalName().replace(QLatin1Char(';'),
413  QStringLiteral("\\;")));
414 
415  name.append((*addrIt).prefix().replace(QLatin1Char(';'),
416  QStringLiteral("\\;")));
417 
418  name.append((*addrIt).suffix().replace(QLatin1Char(';'),
419  QStringLiteral("\\;")));
420 
421  VCardLine nLine(QStringLiteral("N"), name.join(QLatin1Char(';')));
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"));
425  }
426  if (version == VCard::v4_0 && !(*addrIt).sortString().isEmpty()) {
427  nLine.addParameter(QStringLiteral("SORT-AS"), (*addrIt).sortString());
428  }
429 
430  card.addLine(nLine);
431 
432  // NAME only for version < 4.0
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"));
438  }
439  card.addLine(nameLine);
440  }
441 
442  // NICKNAME only for version > 2.1
443  if (version != VCard::v2_1) {
444  const QVector<NickName> lstNickName = (*addrIt).extraNickNameList();
445  for (const NickName &nickName : lstNickName) {
446  VCardLine nickNameLine(QStringLiteral("NICKNAME"), nickName.nickname());
447  addParameters(nickNameLine, nickName.parameters());
448 
449  card.addLine(nickNameLine);
450  }
451  }
452 
453  // NOTE
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"));
458  }
459  card.addLine(noteLine);
460 
461  // ORG
462  const QVector<Org> lstOrg = (*addrIt).extraOrganizationList();
463  for (const Org &org : lstOrg) {
464  QStringList organization;
465  organization.append(org.organization().replace(QLatin1Char(';'),
466  QStringLiteral("\\;")));
467  if (!(*addrIt).department().isEmpty()) {
468  organization.append((*addrIt).department().replace(QLatin1Char(';'),
469  QStringLiteral("\\;")));
470  }
471  const QString orgStr = organization.join(QLatin1Char(';'));
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"));
476  }
477  addParameters(orgLine, org.parameters());
478  card.addLine(orgLine);
479  }
480 
481  // PHOTO
482  card.addLine(createPicture(QStringLiteral("PHOTO"), (*addrIt).photo(), version));
483  const QVector<Picture> lstExtraPhoto = (*addrIt).extraPhotoList();
484  for (const Picture &photo : lstExtraPhoto) {
485  card.addLine(createPicture(QStringLiteral("PHOTO"), photo, version));
486  }
487 
488  // PROID only for version > 2.1
489  if (version != VCard::v2_1) {
490  card.addLine(VCardLine(QStringLiteral("PRODID"), (*addrIt).productId()));
491  }
492 
493  // REV
494  card.addLine(VCardLine(QStringLiteral("REV"), createDateTime((*addrIt).revision(), version)));
495 
496  // ROLE
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"));
503  }
504  addParameters(roleLine, role.parameters());
505  card.addLine(roleLine);
506  }
507 
508  // SORT-STRING
509  if (version == VCard::v3_0) {
510  card.addLine(VCardLine(QStringLiteral("SORT-STRING"), (*addrIt).sortString()));
511  }
512 
513  // SOUND
514  card.addLine(createSound((*addrIt).sound(), version));
515  const QVector<Sound> lstSound = (*addrIt).extraSoundList();
516  for (const Sound &sound : lstSound) {
517  card.addLine(createSound(sound, version));
518  }
519 
520  // TEL
521  const PhoneNumber::List phoneNumbers = (*addrIt).phoneNumbers();
522  PhoneNumber::List::ConstIterator phoneIt;
523  PhoneNumber::List::ConstIterator phoneEnd(phoneNumbers.end());
524  for (phoneIt = phoneNumbers.begin(); phoneIt != phoneEnd; ++phoneIt) {
525  VCardLine line(QStringLiteral("TEL"), (*phoneIt).number());
526  QMapIterator<QString, QStringList> i((*phoneIt).parameters());
527  while (i.hasNext()) {
528  i.next();
529  if (i.key().toUpper() != QLatin1String("TYPE")) {
530  line.addParameter(i.key(), i.value().join(QLatin1Char(',')));
531  }
532  }
533 
534  QStringList lst;
535  for (unsigned int i = 0; i < s_numPhoneTypes; ++i) {
536  if (s_phoneTypes[i].flag & (*phoneIt).type()) {
537  const QString str = QString::fromLatin1(s_phoneTypes[i].phoneType);
538  if (version == VCard::v4_0) {
539  lst << str.toLower();
540  } else {
541  lst << str;
542  }
543  }
544  }
545  if (!lst.isEmpty()) {
546  addParameter(line, version, QStringLiteral("TYPE"), lst);
547  }
548  card.addLine(line);
549  }
550 
551  // TITLE
552  const QVector<Title> lstTitle = (*addrIt).extraTitleList();
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"));
558  }
559  addParameters(titleLine, title.parameters());
560 
561  card.addLine(titleLine);
562  }
563 
564  // TZ
565  // TODO Add vcard4.0 support
566  const TimeZone timeZone = (*addrIt).timeZone();
567  if (timeZone.isValid()) {
568 
569  int neg = 1;
570  if (timeZone.offset() < 0) {
571  neg = -1;
572  }
573 
574  QString str = QString::asprintf("%c%02d:%02d", (timeZone.offset() >= 0 ? '+' : '-'),
575  (timeZone.offset() / 60) * neg,
576  (timeZone.offset() % 60) * neg);
577 
578  card.addLine(VCardLine(QStringLiteral("TZ"), str));
579  }
580 
581  // UID
582  card.addLine(VCardLine(QStringLiteral("UID"), (*addrIt).uid()));
583 
584  // URL
585  const QVector<ResourceLocatorUrl> lstExtraUrl = (*addrIt).extraUrlList();
586  for (const ResourceLocatorUrl &url : lstExtraUrl) {
587  VCardLine line(QStringLiteral("URL"), url.url());
588  addParameters(line, url.parameters());
589  card.addLine(line);
590  }
591  if (version == VCard::v4_0) {
592  // GENDER
593  const Gender gender = (*addrIt).gender();
594  if (gender.isValid()) {
595  QString genderStr;
596  if (!gender.gender().isEmpty()) {
597  genderStr = gender.gender();
598  }
599  if (!gender.comment().isEmpty()) {
600  genderStr += QLatin1Char(';') + gender.comment();
601  }
602  VCardLine line(QStringLiteral("GENDER"), genderStr);
603  card.addLine(line);
604  }
605  // KIND
606  if (!(*addrIt).kind().isEmpty()) {
607  VCardLine line(QStringLiteral("KIND"), (*addrIt).kind());
608  card.addLine(line);
609  }
610  }
611  // From vcard4.
612  if (version == VCard::v4_0) {
613  const QVector<CalendarUrl> lstCalendarUrl = (*addrIt).calendarUrlList();
614  for (const CalendarUrl &url : lstCalendarUrl) {
615  if (url.isValid()) {
616  QString type;
617  switch (url.type()) {
618  case CalendarUrl::Unknown:
619  case CalendarUrl::EndCalendarType:
620  break;
621  case CalendarUrl::FBUrl:
622  type = QStringLiteral("FBURL");
623  break;
624  case CalendarUrl::CALUri:
625  type = QStringLiteral("CALURI");
626  break;
627  case CalendarUrl::CALADRUri:
628  type = QStringLiteral("CALADRURI");
629  break;
630  }
631  if (!type.isEmpty()) {
632  VCardLine line(type, url.url().toDisplayString());
633  addParameters(line, url.parameters());
634  card.addLine(line);
635  }
636  }
637  }
638  }
639  //FieldGroup
640  const QVector<FieldGroup> lstGroup = (*addrIt).fieldGroupList();
641  for (const FieldGroup &group : lstGroup) {
642  VCardLine line(group.fieldGroupName(), group.value());
643  addParameters(line, group.parameters());
644  card.addLine(line);
645  }
646 
647  // IMPP (supported in vcard 3 too)
648  const QVector<Impp> lstImpp = (*addrIt).imppList();
649  for (const Impp &impp : lstImpp) {
650  VCardLine line(QStringLiteral("IMPP"), impp.address().url());
651  QMapIterator<QString, QStringList> i(impp.parameters());
652  while (i.hasNext()) {
653  i.next();
654  if (i.key().toLower() != QLatin1String("x-service-type")) {
655  line.addParameter(i.key(), i.value().join(QLatin1Char(',')));
656  }
657  }
658  card.addLine(line);
659  }
660 
661  // X-
662  const QStringList customs = (*addrIt).customs();
663  for (strIt = customs.begin(); strIt != customs.end(); ++strIt) {
664  QString identifier = QLatin1String("X-")
665  +(*strIt).left((*strIt).indexOf(QLatin1Char(':')));
666  const QString value = (*strIt).mid((*strIt).indexOf(QLatin1Char(':')) + 1);
667  if (value.isEmpty()) {
668  continue;
669  }
670  //Convert to standard identifier
671  if (exportVcard) {
672  if (identifier == QLatin1String("X-messaging/aim-All")) {
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"); //Not defined by rfc but need for fixing #300869
694  } else if (identifier == QLatin1String("X-messaging/googletalk-All")) {
695  //Not defined by rfc but need for fixing #300869
696  identifier = QStringLiteral("X-GTALK");
697  } else if (identifier == QLatin1String("X-messaging/twitter-All")) {
698  identifier = QStringLiteral("X-TWITTER");
699  }
700  }
701  if (identifier.toLower() == QLatin1String("x-kaddressbook-x-anniversary") && version == VCard::v4_0) {
702  // ANNIVERSARY
703  if (!value.isEmpty()) {
704  const QDate date = QDate::fromString(value, Qt::ISODate);
705  QDateTime dt = QDateTime(date);
706  dt.setTime(QTime());
707  VCardLine line(QStringLiteral("ANNIVERSARY"), createDateTime(dt, version, false));
708  card.addLine(line);
709  }
710  } else if (identifier.toLower() == QLatin1String("x-kaddressbook-x-spousesname") && version == VCard::v4_0) {
711  if (!value.isEmpty()) {
712  VCardLine line(QStringLiteral("RELATED"), QStringLiteral(";"));
713  line.addParameter(QStringLiteral("TYPE"), QStringLiteral("spouse"));
714  line.addParameter(QStringLiteral("VALUE"), value);
715  card.addLine(line);
716  }
717  } else {
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"));
722  }
723  card.addLine(line);
724  }
725  }
726 
727  vCardList.append(card);
728  }
729 
730  return VCardParser::createVCards(vCardList);
731 }
732 
733 Addressee::List VCardTool::parseVCards(const QByteArray &vcard) const
734 {
735  static const QLatin1Char semicolonSep(';');
736  static const QLatin1Char commaSep(',');
737  QString identifier;
738  QString group;
739  Addressee::List addrList;
740  const VCard::List vCardList = VCardParser::parseVCards(vcard);
741 
742  VCard::List::ConstIterator cardIt;
743  VCard::List::ConstIterator listEnd(vCardList.end());
744  for (cardIt = vCardList.begin(); cardIt != listEnd; ++cardIt) {
745  Addressee addr;
746 
747  const QStringList idents = (*cardIt).identifiers();
748  QStringList::ConstIterator identIt;
749  QStringList::ConstIterator identEnd(idents.end());
750  for (identIt = idents.begin(); identIt != identEnd; ++identIt) {
751  const VCardLine::List lines = (*cardIt).lines((*identIt));
752  VCardLine::List::ConstIterator lineIt;
753 
754  // iterate over the lines
755  for (lineIt = lines.begin(); lineIt != lines.end(); ++lineIt) {
756  identifier = (*lineIt).identifier().toLower();
757  group = (*lineIt).group();
758  if (!group.isEmpty() && identifier != QLatin1String("adr")) {
759  KContacts::FieldGroup groupField(group + QLatin1Char('.') + (*lineIt).identifier());
760  groupField.setParameters((*lineIt).parameterMap());
761  groupField.setValue((*lineIt).value().toString());
762  addr.insertFieldGroup(groupField);
763  }
764  // ADR
765  else if (identifier == QLatin1String("adr")) {
766  Address address;
767  const QStringList addrParts = splitString(semicolonSep, (*lineIt).value().toString());
768  const int addrPartsCount(addrParts.count());
769  if (addrPartsCount > 0) {
770  address.setPostOfficeBox(addrParts.at(0));
771  }
772  if (addrPartsCount > 1) {
773  address.setExtended(addrParts.at(1));
774  }
775  if (addrPartsCount > 2) {
776  address.setStreet(addrParts.at(2));
777  }
778  if (addrPartsCount > 3) {
779  address.setLocality(addrParts.at(3));
780  }
781  if (addrPartsCount > 4) {
782  address.setRegion(addrParts.at(4));
783  }
784  if (addrPartsCount > 5) {
785  address.setPostalCode(addrParts.at(5));
786  }
787  if (addrPartsCount > 6) {
788  address.setCountry(addrParts.at(6));
789  }
790 
791  Address::Type type;
792 
793  const QStringList types = (*lineIt).parameters(QStringLiteral("type"));
794  QStringList::ConstIterator end(types.end());
795  for (QStringList::ConstIterator it = types.begin(); it != end; ++it) {
796  type |= stringToAddressType((*it).toLower());
797  }
798 
799  address.setType(type);
800  QString label = (*lineIt).parameter(QStringLiteral("label"));
801  if (!label.isEmpty()) {
802  if (label.length() > 1) {
803  if (label.at(0) == QLatin1Char('"') && label.at(label.length() - 1) == QLatin1Char('"')) {
804  label = label.mid(1, label.length() - 2);
805  }
806  }
807  address.setLabel(label);
808  }
809  QString geoStr = (*lineIt).parameter(QStringLiteral("geo"));
810  if (!geoStr.isEmpty()) {
811  geoStr.remove(QLatin1Char('\"'));
812  geoStr.remove(QStringLiteral("geo:"));
813  if (geoStr.contains(QLatin1Char(','))) {
814  QStringList arguments = geoStr.split(QLatin1Char(','));
815  KContacts::Geo geo;
816  geo.setLatitude(arguments.at(0).toDouble());
817  geo.setLongitude(arguments.at(1).toDouble());
818  address.setGeo(geo);
819  }
820  }
821  addr.insertAddress(address);
822  }
823  // ANNIVERSARY
824  else if (identifier == QLatin1String("anniversary")) {
825  const QString t = (*lineIt).value().toString();
826  const QDateTime dt(parseDateTime(t));
827  addr.insertCustom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("X-Anniversary"), dt.date().toString(Qt::ISODate));
828  }
829  // BDAY
830  else if (identifier == QLatin1String("bday")) {
831  bool withTime;
832  const QDateTime bday = parseDateTime((*lineIt).value().toString(), &withTime);
833  addr.setBirthday(bday, withTime);
834  }
835  // CATEGORIES
836  else if (identifier == QLatin1String("categories")) {
837  const QStringList categories = splitString(commaSep, (*lineIt).value().toString());
838  addr.setCategories(categories);
839  }
840  // FBURL
841  else if (identifier == QLatin1String("fburl")) {
842  CalendarUrl calurl;
843  calurl.setType(CalendarUrl::FBUrl);
844  const QUrl url = QUrl((*lineIt).value().toString());
845  calurl.setUrl(url);
846  calurl.setParameters((*lineIt).parameterMap());
847  addr.insertCalendarUrl(calurl);
848  }
849  // CALADRURI
850  else if (identifier == QLatin1String("caladruri")) {
851  CalendarUrl calurl;
852  calurl.setType(CalendarUrl::CALADRUri);
853  const QUrl url = QUrl((*lineIt).value().toString());
854  calurl.setUrl(url);
855  calurl.setParameters((*lineIt).parameterMap());
856  addr.insertCalendarUrl(calurl);
857  }
858  // CALURI
859  else if (identifier == QLatin1String("caluri")) {
860  CalendarUrl calurl;
861  calurl.setType(CalendarUrl::CALUri);
862  const QUrl url = QUrl((*lineIt).value().toString());
863  calurl.setUrl(url);
864  calurl.setParameters((*lineIt).parameterMap());
865  addr.insertCalendarUrl(calurl);
866  }
867  //IMPP
868  else if (identifier == QLatin1String("impp")) {
869  QUrl imppUrl((*lineIt).value().toString());
870  Impp impp;
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()));
874  }
875  impp.setAddress(imppUrl);
876  addr.insertImpp(impp);
877  }
878  // CLASS
879  else if (identifier == QLatin1String("class")) {
880  addr.setSecrecy(parseSecrecy(*lineIt));
881  }
882  // GENDER
883  else if (identifier == QLatin1String("gender")) {
884  QString genderStr = (*lineIt).value().toString();
885  if (!genderStr.isEmpty()) {
886  Gender gender;
887  if (genderStr.at(0) != QLatin1Char(';')) {
888  gender.setGender(genderStr.at(0));
889  if (genderStr.length() > 2 && (genderStr.at(1) == QLatin1Char(';'))) {
890  gender.setComment(genderStr.right(genderStr.length() - 2));
891  }
892  } else {
893  gender.setComment(genderStr.right(genderStr.length() - 1));
894  }
895  addr.setGender(gender);
896  }
897  }
898  // LANG
899  else if (identifier == QLatin1String("lang")) {
900  Lang lang;
901  lang.setLanguage((*lineIt).value().toString());
902  lang.setParameters((*lineIt).parameterMap());
903  addr.insertLang(lang);
904  }
905  // EMAIL
906  else if (identifier == QLatin1String("email")) {
907  const QStringList types = (*lineIt).parameters(QStringLiteral("type"));
908  addr.insertEmail((*lineIt).value().toString(),
909  types.contains(QLatin1String("PREF")), (*lineIt).parameterMap());
910  }
911  // KIND
912  else if (identifier == QLatin1String("kind")) {
913  addr.setKind((*lineIt).value().toString());
914  }
915  // FN
916  else if (identifier == QLatin1String("fn")) {
917  addr.setFormattedName((*lineIt).value().toString());
918  }
919  // GEO
920  else if (identifier == QLatin1String("geo")) {
921  Geo geo;
922  QString lineStr = (*lineIt).value().toString();
923  if (lineStr.startsWith(QLatin1String("geo:"))) { //VCard 4.0
924  lineStr.remove(QStringLiteral("geo:"));
925  const QStringList geoParts
926  = lineStr.split(QLatin1Char(','), QString::KeepEmptyParts);
927  if (geoParts.size() >= 2) {
928  geo.setLatitude(geoParts.at(0).toFloat());
929  geo.setLongitude(geoParts.at(1).toFloat());
930  addr.setGeo(geo);
931  }
932  } else {
933  const QStringList geoParts
934  = lineStr.split(QLatin1Char(';'), QString::KeepEmptyParts);
935  if (geoParts.size() >= 2) {
936  geo.setLatitude(geoParts.at(0).toFloat());
937  geo.setLongitude(geoParts.at(1).toFloat());
938  addr.setGeo(geo);
939  }
940  }
941  }
942  // KEY
943  else if (identifier == QLatin1String("key")) {
944  addr.insertKey(parseKey(*lineIt));
945  }
946  // LABEL
947  else if (identifier == QLatin1String("label")) {
948  Address::Type type;
949 
950  const QStringList types = (*lineIt).parameters(QStringLiteral("type"));
951  QStringList::ConstIterator end(types.end());
952  for (QStringList::ConstIterator it = types.begin(); it != end; ++it) {
953  type |= stringToAddressType((*it).toLower());
954  }
955 
956  bool available = false;
957  KContacts::Address::List addressList = addr.addresses();
958  for (KContacts::Address::List::Iterator it = addressList.begin();
959  it != addressList.end(); ++it) {
960  if ((*it).type() == type) {
961  (*it).setLabel((*lineIt).value().toString());
962  addr.insertAddress(*it);
963  available = true;
964  break;
965  }
966  }
967 
968  if (!available) { // a standalone LABEL tag
969  KContacts::Address address(type);
970  address.setLabel((*lineIt).value().toString());
971  addr.insertAddress(address);
972  }
973  }
974  // LOGO
975  else if (identifier == QLatin1String("logo")) {
976  Picture picture = parsePicture(*lineIt);
977  if (addr.logo().isEmpty()) {
978  addr.setLogo(picture);
979  } else {
980  addr.insertExtraLogo(picture);
981  }
982  }
983  // MAILER
984  else if (identifier == QLatin1String("mailer")) {
985  addr.setMailer((*lineIt).value().toString());
986  }
987  // N
988  else if (identifier == QLatin1Char('n')) {
989  const QStringList nameParts = splitString(semicolonSep, (*lineIt).value().toString());
990  const int numberOfParts(nameParts.count());
991  if (numberOfParts > 0) {
992  addr.setFamilyName(nameParts.at(0));
993  }
994  if (numberOfParts > 1) {
995  addr.setGivenName(nameParts.at(1));
996  }
997  if (numberOfParts > 2) {
998  addr.setAdditionalName(nameParts.at(2));
999  }
1000  if (numberOfParts > 3) {
1001  addr.setPrefix(nameParts.at(3));
1002  }
1003  if (numberOfParts > 4) {
1004  addr.setSuffix(nameParts.at(4));
1005  }
1006  if (!(*lineIt).parameter(QStringLiteral("sort-as")).isEmpty()) {
1007  addr.setSortString((*lineIt).parameter(QStringLiteral("sort-as")));
1008  }
1009  }
1010  // NAME
1011  else if (identifier == QLatin1String("name")) {
1012  addr.setName((*lineIt).value().toString());
1013  }
1014  // NICKNAME
1015  else if (identifier == QLatin1String("nickname")) {
1016  NickName nickName((*lineIt).value().toString());
1017  nickName.setParameters((*lineIt).parameterMap());
1018  addr.insertExtraNickName(nickName);
1019  }
1020  // NOTE
1021  else if (identifier == QLatin1String("note")) {
1022  addr.setNote((*lineIt).value().toString());
1023  }
1024  // ORGANIZATION
1025  else if (identifier == QLatin1String("org")) {
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);
1032  }
1033  if (orgPartsCount > 1) {
1034  addr.setDepartment(orgParts.at(1));
1035  }
1036  if (!(*lineIt).parameter(QStringLiteral("sort-as")).isEmpty()) {
1037  addr.setSortString((*lineIt).parameter(QStringLiteral("sort-as")));
1038  }
1039  }
1040  // PHOTO
1041  else if (identifier == QLatin1String("photo")) {
1042  Picture picture = parsePicture(*lineIt);
1043  if (addr.photo().isEmpty()) {
1044  addr.setPhoto(picture);
1045  } else {
1046  addr.insertExtraPhoto(picture);
1047  }
1048  }
1049  // PROID
1050  else if (identifier == QLatin1String("prodid")) {
1051  addr.setProductId((*lineIt).value().toString());
1052  }
1053  // REV
1054  else if (identifier == QLatin1String("rev")) {
1055  addr.setRevision(parseDateTime((*lineIt).value().toString()));
1056  }
1057  // ROLE
1058  else if (identifier == QLatin1String("role")) {
1059  Role role((*lineIt).value().toString());
1060  role.setParameters((*lineIt).parameterMap());
1061  addr.insertExtraRole(role);
1062  }
1063  // SORT-STRING
1064  else if (identifier == QLatin1String("sort-string")) {
1065  addr.setSortString((*lineIt).value().toString());
1066  }
1067  // SOUND
1068  else if (identifier == QLatin1String("sound")) {
1069  Sound sound = parseSound(*lineIt);
1070  if (addr.sound().isEmpty()) {
1071  addr.setSound(sound);
1072  } else {
1073  addr.insertExtraSound(sound);
1074  }
1075  }
1076  // TEL
1077  else if (identifier == QLatin1String("tel")) {
1078  PhoneNumber phone;
1079  phone.setNumber((*lineIt).value().toString());
1080 
1081  PhoneNumber::Type type;
1082  bool foundType = false;
1083  const QStringList types = (*lineIt).parameters(QStringLiteral("type"));
1084  QStringList::ConstIterator typeEnd(types.constEnd());
1085  for (QStringList::ConstIterator it = types.constBegin(); it != typeEnd; ++it) {
1086  type |= stringToPhoneType((*it).toUpper());
1087  foundType = true;
1088  }
1089  phone.setType(foundType ? type : PhoneNumber::Undefined);
1090  phone.setParameters((*lineIt).parameterMap());
1091 
1092  addr.insertPhoneNumber(phone);
1093  }
1094  // TITLE
1095  else if (identifier == QLatin1String("title")) {
1096  Title title((*lineIt).value().toString());
1097  title.setParameters((*lineIt).parameterMap());
1098  addr.insertExtraTitle(title);
1099  }
1100  // TZ
1101  else if (identifier == QLatin1String("tz")) {
1102  //TODO add vcard4 support
1103  TimeZone tz;
1104  const QString date = (*lineIt).value().toString();
1105 
1106  if (!date.isEmpty()) {
1107  int hours = date.midRef(1, 2).toInt();
1108  int minutes = date.midRef(4, 2).toInt();
1109  int offset = (hours * 60) + minutes;
1110  offset = offset * (date[ 0 ] == QLatin1Char('+') ? 1 : -1);
1111 
1112  tz.setOffset(offset);
1113  addr.setTimeZone(tz);
1114  }
1115  }
1116  // UID
1117  else if (identifier == QLatin1String("uid")) {
1118  addr.setUid((*lineIt).value().toString());
1119  }
1120  // URL
1121  else if (identifier == QLatin1String("url")) {
1122  const QUrl url = QUrl((*lineIt).value().toString());
1123  ResourceLocatorUrl resourceLocatorUrl;
1124  resourceLocatorUrl.setUrl(url);
1125  resourceLocatorUrl.setParameters((*lineIt).parameterMap());
1126  addr.insertExtraUrl(resourceLocatorUrl);
1127  }
1128  // SOURCE
1129  else if (identifier == QLatin1String("source")) {
1130  const QUrl url = QUrl((*lineIt).value().toString());
1131  addr.insertSourceUrl(url);
1132  }
1133  // MEMBER (vcard 4.0)
1134  else if (identifier == QLatin1String("member")) {
1135  addr.insertMember((*lineIt).value().toString());
1136  }
1137  // RELATED (vcard 4.0)
1138  else if (identifier == QLatin1String("related")) {
1139  Related related;
1140  related.setRelated((*lineIt).value().toString());
1141  related.setParameters((*lineIt).parameterMap());
1142  addr.insertRelationship(related);
1143  }
1144  // CLIENTPIDMAP (vcard 4.0)
1145  else if (identifier == QLatin1String("clientpidmap")) {
1146  ClientPidMap clientpidmap;
1147  clientpidmap.setClientPidMap((*lineIt).value().toString());
1148  clientpidmap.setParameters((*lineIt).parameterMap());
1149  addr.insertClientPidMap(clientpidmap);
1150  }
1151  // X-
1152  //TODO import X-GENDER
1153  else if (identifier.startsWith(QLatin1String("x-"))) {
1154  QString ident = (*lineIt).identifier();
1155  //X-Evolution
1156  // also normalize case of our own extensions, some backends "adjust" that
1157  if (identifier == QLatin1String("x-evolution-spouse")
1158  || identifier == QLatin1String("x-spouse")) {
1159  ident = QStringLiteral("X-KADDRESSBOOK-X-SpousesName");
1160  } else if (identifier == QLatin1String("x-evolution-blog-url") || identifier.compare(QLatin1String("X-KADDRESSBOOK-BLOGFEED"), Qt::CaseInsensitive) == 0) {
1161  ident = QStringLiteral("X-KADDRESSBOOK-BlogFeed");
1162  } else if (identifier == QLatin1String("x-evolution-assistant")
1163  || identifier == QLatin1String("x-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")
1167  || identifier == QLatin1String("x-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")
1171  || identifier == QLatin1String("x-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");
1180  } else if (identifier == QLatin1String("x-aim")) {
1181  ident = QStringLiteral("X-messaging/aim-All");
1182  } else if (identifier == QLatin1String("x-icq")) {
1183  ident = QStringLiteral("X-messaging/icq-All");
1184  } else if (identifier == QLatin1String("x-jabber")) {
1185  ident = QStringLiteral("X-messaging/xmpp-All");
1186  } else if (identifier == QLatin1String("x-jabber")) {
1187  ident = QStringLiteral("X-messaging/xmpp-All");
1188  } else if (identifier == QLatin1String("x-msn")) {
1189  ident = QStringLiteral("X-messaging/msn-All");
1190  } else if (identifier == QLatin1String("x-yahoo")) {
1191  ident = QStringLiteral("X-messaging/yahoo-All");
1192  } else if (identifier == QLatin1String("x-gadugadu")) {
1193  ident = QStringLiteral("X-messaging/gadu-All");
1194  } else if (identifier == QLatin1String("x-skype")) {
1195  ident = QStringLiteral("X-messaging/skype-All");
1196  } else if (identifier == QLatin1String("x-groupwise")) {
1197  ident = QStringLiteral("X-messaging/groupwise-All");
1198  } else if (identifier == QLatin1String("x-sms")) {
1199  ident = QStringLiteral("X-messaging/sms-All");
1200  } else if (identifier == QLatin1String("x-meanwhile")) {
1201  ident = QStringLiteral("X-messaging/meanwhile-All");
1202  } else if (identifier == QLatin1String("x-irc")) {
1203  ident = QStringLiteral("X-messaging/irc-All");
1204  } else if (identifier == QLatin1String("x-gtalk")) {
1205  ident = QStringLiteral("X-messaging/googletalk-All");
1206  } else if (identifier == QLatin1String("x-twitter")) {
1207  ident = QStringLiteral("X-messaging/twitter-All");
1208  }
1209 
1210  const QString key = ident.mid(2);
1211  const int dash = key.indexOf(QLatin1Char('-'));
1212 
1213  // convert legacy messaging fields into IMPP ones
1214  if (key.startsWith(QLatin1String("messaging/"))) {
1215  QUrl url;
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) {
1219  url.setPath(value);
1220  Impp impp;
1221  impp.setParameters((*lineIt).parameterMap());
1222  impp.setAddress(url);
1223  addr.insertImpp(impp);
1224  }
1225  } else {
1226  addr.insertCustom(key.left(dash), key.mid(dash + 1), (*lineIt).value().toString());
1227  }
1228  }
1229  }
1230  }
1231 
1232  addrList.append(addr);
1233  }
1234 
1235  return addrList;
1236 }
1237 
1238 QDateTime VCardTool::parseDateTime(const QString &str, bool *timeValid)
1239 {
1240  const int posT = str.indexOf(QLatin1Char('T'));
1241  QString dateString = posT >= 0 ? str.left(posT) : str;
1242  const bool noYear = dateString.startsWith(QLatin1String("--"));
1243  dateString.remove(QLatin1Char('-'));
1244  QDate date;
1245  if (noYear) {
1246  date = QDate::fromString(dateString, QStringLiteral("MMdd"));
1247  date = date.addYears(-1900);
1248  } else {
1249  date = QDate::fromString(dateString, QStringLiteral("yyyyMMdd"));
1250  }
1251 
1252  QTime time;
1253  Qt::TimeSpec spec = Qt::LocalTime;
1254  int offsetSecs = 0;
1255  if (posT >= 0) {
1256  QString timeString = str.mid(posT + 1);
1257  timeString.remove(QLatin1Char(':'));
1258  const int zPos = timeString.indexOf(QLatin1Char('Z'));
1259  const int plusPos = timeString.indexOf(QLatin1Char('+'));
1260  const int minusPos = timeString.indexOf(QLatin1Char('-'));
1261  const int tzPos = qMax(qMax(zPos, plusPos), minusPos);
1262  const QString hhmmssString = tzPos >= 0 ? timeString.left(tzPos) : timeString;
1263  switch (hhmmssString.size()) {
1264  case 2:
1265  time = QTime::fromString(hhmmssString, QStringLiteral("hh"));
1266  break;
1267  case 4:
1268  time = QTime::fromString(hhmmssString, QStringLiteral("hhmm"));
1269  break;
1270  case 6:
1271  time = QTime::fromString(hhmmssString, QStringLiteral("hhmmss"));
1272  break;
1273  }
1274  if (tzPos >= 0) {
1275  if (zPos >= 0) {
1276  spec = Qt::UTC;
1277  } else {
1278  spec = Qt::OffsetFromUTC;
1279  QTime offsetTime;
1280  const QString offsetString = timeString.mid(tzPos + 1);
1281  switch (offsetString.size()) {
1282  case 2:
1283  offsetTime = QTime::fromString(offsetString, QStringLiteral("hh"));
1284  break;
1285  case 4:
1286  offsetTime = QTime::fromString(offsetString, QStringLiteral("hhmm"));
1287  break;
1288  }
1289  offsetSecs = offsetTime.hour() * 3600 + offsetTime.minute() * 60;
1290  }
1291  if (minusPos >= 0) {
1292  offsetSecs *= -1;
1293  }
1294  }
1295  }
1296  if (timeValid) {
1297  *timeValid = time.isValid();
1298  }
1299 
1300  return QDateTime(date, time, spec, offsetSecs);
1301 }
1302 
1303 QString VCardTool::createDateTime(const QDateTime &dateTime, VCard::Version version, bool withTime)
1304 {
1305  if (!dateTime.date().isValid()) {
1306  return QString();
1307  }
1308  QString str = createDate(dateTime.date(), version);
1309  if (!withTime) {
1310  return str;
1311  }
1312  str += createTime(dateTime.time(), version);
1313  if (dateTime.timeSpec() == Qt::UTC) {
1314  str += QLatin1Char('Z');
1315  } else if (dateTime.timeSpec() == Qt::OffsetFromUTC) {
1316  const int offsetSecs = dateTime.offsetFromUtc();
1317  if (offsetSecs >= 0) {
1318  str += QLatin1Char('+');
1319  } else {
1320  str += QLatin1Char('-');
1321  }
1322  QTime offsetTime = QTime(0, 0).addSecs(abs(offsetSecs));
1323  if (version == VCard::v4_0) {
1324  str += offsetTime.toString(QStringLiteral("HHmm"));
1325  } else {
1326  str += offsetTime.toString(QStringLiteral("HH:mm"));
1327  }
1328  }
1329  return str;
1330 }
1331 
1332 QString VCardTool::createDate(const QDate &date, VCard::Version version)
1333 {
1334  QString format;
1335  if (date.year() > 0) {
1336  format = QStringLiteral("yyyyMMdd");
1337  } else {
1338  format = QStringLiteral("--MMdd");
1339  }
1340  if (version != VCard::v4_0) {
1341  format.replace(QStringLiteral("yyyy"), QStringLiteral("yyyy-"));
1342  format.replace(QStringLiteral("MM"), QStringLiteral("MM-"));
1343  }
1344  return date.toString(format);
1345 }
1346 
1347 QString VCardTool::createTime(const QTime &time, VCard::Version version)
1348 {
1349  QString format;
1350  if (version == VCard::v4_0) {
1351  format = QStringLiteral("HHmmss");
1352  } else {
1353  format = QStringLiteral("HH:mm:ss");
1354  }
1355  return QLatin1Char('T') + time.toString(format);
1356 }
1357 
1358 Picture VCardTool::parsePicture(const VCardLine &line) const
1359 {
1360  Picture pic;
1361 
1362  const QStringList params = line.parameterList();
1363  QString type;
1364  if (params.contains(QLatin1String("type"))) {
1365  type = line.parameter(QStringLiteral("type"));
1366  }
1367  if (params.contains(QLatin1String("encoding"))) {
1368  pic.setRawData(line.value().toByteArray(), type);
1369  } else if (params.contains(QLatin1String("value"))) {
1370  if (line.parameter(QStringLiteral("value")).toLower() == QLatin1String("uri")) {
1371  pic.setUrl(line.value().toString());
1372  }
1373  }
1374 
1375  return pic;
1376 }
1377 
1378 VCardLine VCardTool::createPicture(const QString &identifier, const Picture &pic, VCard::Version version) const
1379 {
1380  VCardLine line(identifier);
1381 
1382  if (pic.isEmpty()) {
1383  return line;
1384  }
1385 
1386  if (pic.isIntern()) {
1387  line.setValue(pic.rawData());
1388  if (version == VCard::v2_1) {
1389  line.addParameter(QStringLiteral("ENCODING"), QStringLiteral("BASE64"));
1390  line.addParameter(pic.type(), QString());
1391  } else { /*if (version == VCard::v3_0) */
1392  line.addParameter(QStringLiteral("encoding"), QStringLiteral("b"));
1393  line.addParameter(QStringLiteral("type"), pic.type());
1394 #if 0
1395  } else { //version 4.0
1396  line.addParameter(QStringLiteral("data") + QStringLiteral(":image/") + pic.type(), QStringLiteral("base64"));
1397 #endif
1398  }
1399  } else {
1400  line.setValue(pic.url());
1401  line.addParameter(QStringLiteral("value"), QStringLiteral("URI"));
1402  }
1403 
1404  return line;
1405 }
1406 
1407 Sound VCardTool::parseSound(const VCardLine &line) const
1408 {
1409  Sound snd;
1410 
1411  const QStringList params = line.parameterList();
1412  if (params.contains(QLatin1String("encoding"))) {
1413  snd.setData(line.value().toByteArray());
1414  } else if (params.contains(QLatin1String("value"))) {
1415  if (line.parameter(QStringLiteral("value")).toLower() == QLatin1String("uri")) {
1416  snd.setUrl(line.value().toString());
1417  }
1418  }
1419 
1420  /* TODO: support sound types
1421  if ( params.contains( "type" ) )
1422  snd.setType( line.parameter( "type" ) );
1423  */
1424 
1425  return snd;
1426 }
1427 
1428 VCardLine VCardTool::createSound(const Sound &snd, VCard::Version version) const
1429 {
1430  Q_UNUSED(version);
1431  VCardLine line(QStringLiteral("SOUND"));
1432 
1433  if (snd.isIntern()) {
1434  if (!snd.data().isEmpty()) {
1435  line.setValue(snd.data());
1436  if (version == VCard::v2_1) {
1437  line.addParameter(QStringLiteral("ENCODING"), QStringLiteral("BASE64"));
1438  } else {
1439  line.addParameter(QStringLiteral("encoding"), QStringLiteral("b"));
1440  }
1441  // TODO: need to store sound type!!!
1442  }
1443  } else if (!snd.url().isEmpty()) {
1444  line.setValue(snd.url());
1445  line.addParameter(QStringLiteral("value"), QStringLiteral("URI"));
1446  }
1447 
1448  return line;
1449 }
1450 
1451 Key VCardTool::parseKey(const VCardLine &line) const
1452 {
1453  Key key;
1454 
1455  const QStringList params = line.parameterList();
1456  if (params.contains(QLatin1String("encoding"))) {
1457  key.setBinaryData(line.value().toByteArray());
1458  } else {
1459  key.setTextData(line.value().toString());
1460  }
1461 
1462  if (params.contains(QLatin1String("type"))) {
1463  if (line.parameter(QStringLiteral("type")).toLower() == QLatin1String("x509")) {
1464  key.setType(Key::X509);
1465  } else if (line.parameter(QStringLiteral("type")).toLower() == QLatin1String("pgp")) {
1466  key.setType(Key::PGP);
1467  } else {
1468  key.setType(Key::Custom);
1469  key.setCustomTypeString(line.parameter(QStringLiteral("type")));
1470  }
1471  } else if (params.contains(QLatin1String("mediatype"))) {
1472  const QString param = line.parameter(QStringLiteral("mediatype")).toLower();
1473  if (param == QLatin1String("application/x-x509-ca-cert")) {
1474  key.setType(Key::X509);
1475  } else if (param == QLatin1String("application/pgp-keys")) {
1476  key.setType(Key::PGP);
1477  } else {
1478  key.setType(Key::Custom);
1479  key.setCustomTypeString(line.parameter(QStringLiteral("type")));
1480  }
1481  }
1482 
1483  return key;
1484 }
1485 
1486 VCardLine VCardTool::createKey(const Key &key, VCard::Version version) const
1487 {
1488  VCardLine line(QStringLiteral("KEY"));
1489 
1490  if (key.isBinary()) {
1491  if (!key.binaryData().isEmpty()) {
1492  line.setValue(key.binaryData());
1493  if (version == VCard::v2_1) {
1494  line.addParameter(QStringLiteral("ENCODING"), QStringLiteral("BASE64"));
1495  } else {
1496  line.addParameter(QStringLiteral("encoding"), QStringLiteral("b"));
1497  }
1498  }
1499  } else if (!key.textData().isEmpty()) {
1500  line.setValue(key.textData());
1501  }
1502 
1503  if (version == VCard::v4_0) {
1504  if (key.type() == Key::X509) {
1505  line.addParameter(QStringLiteral("MEDIATYPE"), QStringLiteral("application/x-x509-ca-cert"));
1506  } else if (key.type() == Key::PGP) {
1507  line.addParameter(QStringLiteral("MEDIATYPE"), QStringLiteral("application/pgp-keys"));
1508  } else if (key.type() == Key::Custom) {
1509  line.addParameter(QStringLiteral("MEDIATYPE"), key.customTypeString());
1510  }
1511  } else {
1512  if (key.type() == Key::X509) {
1513  line.addParameter(QStringLiteral("type"), QStringLiteral("X509"));
1514  } else if (key.type() == Key::PGP) {
1515  line.addParameter(QStringLiteral("type"), QStringLiteral("PGP"));
1516  } else if (key.type() == Key::Custom) {
1517  line.addParameter(QStringLiteral("type"), key.customTypeString());
1518  }
1519  }
1520 
1521  return line;
1522 }
1523 
1524 Secrecy VCardTool::parseSecrecy(const VCardLine &line) const
1525 {
1526  Secrecy secrecy;
1527 
1528  const QString value = line.value().toString().toLower();
1529  if (value == QLatin1String("public")) {
1530  secrecy.setType(Secrecy::Public);
1531  } else if (value == QLatin1String("private")) {
1532  secrecy.setType(Secrecy::Private);
1533  } else if (value == QLatin1String("confidential")) {
1534  secrecy.setType(Secrecy::Confidential);
1535  }
1536 
1537  return secrecy;
1538 }
1539 
1540 VCardLine VCardTool::createSecrecy(const Secrecy &secrecy) const
1541 {
1542  VCardLine line(QStringLiteral("CLASS"));
1543 
1544  int type = secrecy.type();
1545 
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"));
1552  }
1553 
1554  return line;
1555 }
1556 
1557 QStringList VCardTool::splitString(QChar sep, const QString &str) const
1558 {
1559  QStringList list;
1560  QString value(str);
1561 
1562  int start = 0;
1563  int pos = value.indexOf(sep, start);
1564 
1565  while (pos != -1) {
1566  if (pos == 0 || value[ pos - 1 ] != QLatin1Char('\\')) {
1567  if (pos > start && pos <= value.length()) {
1568  list << value.mid(start, pos - start);
1569  } else {
1570  list << QString();
1571  }
1572 
1573  start = pos + 1;
1574  pos = value.indexOf(sep, start);
1575  } else {
1576  value.replace(pos - 1, 2, sep);
1577  pos = value.indexOf(sep, pos);
1578  }
1579  }
1580 
1581  int l = value.length() - 1;
1582  const QString mid = value.mid(start, l - start + 1);
1583  if (!mid.isEmpty()) {
1584  list << mid;
1585  } else {
1586  list << QString();
1587  }
1588 
1589  return list;
1590 }
1591 
1592 QString VCardTool::normalizeImppServiceType(const QString &serviceType) const
1593 {
1594  if (serviceType == QLatin1String("jabber")) {
1595  return QStringLiteral("xmpp");
1596  }
1597  if (serviceType == QLatin1String("yahoo")) {
1598  return QStringLiteral("ymsgr");
1599  }
1600  if (serviceType == QLatin1String("gadugadu")) {
1601  return QStringLiteral("gg");
1602  }
1603  return serviceType;
1604 }
KContacts::Addressee::setFormattedName
void setFormattedName(const QString &formattedName)
Set formatted name.
Definition: addressee.cpp:632
KContacts::FieldGroup
Class that holds a FieldGroup for a contact.
Definition: fieldgroup.h:34
KContacts::TimeZone::setOffset
void setOffset(int offset)
Set time zone offset relative to UTC.
Definition: timezone.cpp:67
KContacts::Addressee::setMailer
void setMailer(const QString &mailer)
Set mail client.
Definition: addressee.cpp:958
QStringRef::toInt
int toInt(bool *ok, int base) const
QTime::minute
int minute() const
QString::indexOf
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
KContacts::Picture::type
QString type() const
Returns the type of this picture.
Definition: picture.cpp:211
KContacts::Key::setTextData
void setTextData(const QString &data)
Sets text data.
Definition: key.cpp:142
KContacts::PhoneNumber::setNumber
void setNumber(const QString &number)
Sets the phone number.
Definition: phonenumber.cpp:129
QVector::Iterator
typedef Iterator
QDate::addYears
QDate addYears(int nyears) const
KContacts::Key::Custom
Custom or IANA conform key.
Definition: key.h:50
KContacts::Addressee::insertLang
void insertLang(const Lang &language)
Insert Language.
Definition: addressee.cpp:1690
KContacts::Key::isBinary
bool isBinary() const
Returns whether the key contains binary or text data.
Definition: key.cpp:153
KContacts::Address::setLocality
void setLocality(const QString &locality)
Sets the locality, e.g.
Definition: address.cpp:432
KContacts::Key::type
Type type() const
Returns the type, see Type.
Definition: key.cpp:168
KItinerary::LocationUtil::name
QString name(const QVariant &location)
KContacts::Addressee::insertPhoneNumber
void insertPhoneNumber(const PhoneNumber &phoneNumber)
Insert a phone number.
Definition: addressee.cpp:1729
QTime::toString
QString toString(Qt::DateFormat format) const
QDate::toString
QString toString(Qt::DateFormat format) const
KContacts::Related
Descripes a relationship of an Addressee.
Definition: related.h:31
QVector::append
void append(const T &value)
QVector::begin
iterator begin()
KContacts::Addressee::setTimeZone
void setTimeZone(const TimeZone &timeZone)
Set time zone.
Definition: addressee.cpp:978
QByteArray
KContacts::Role
Class that holds a Role for a contact.
Definition: role.h:33
KContacts::Addressee::setPhoto
void setPhoto(const Picture &photo)
Set photo.
Definition: addressee.cpp:1337
KContacts::Addressee::setSuffix
void setSuffix(const QString &suffix)
Set honorific suffixes.
Definition: addressee.cpp:732
KContacts::Sound::data
QByteArray data() const
Returns the raw data of this sound.
Definition: sound.cpp:138
QChar
QString::split
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
KContacts::ResourceLocatorUrl
Class that holds a Resource Locator.
Definition: resourcelocatorurl.h:37
date
time_t date() const
KContacts::Addressee::setUid
void setUid(const QString &uid)
Set unique identifier.
Definition: addressee.cpp:416
QVector::constEnd
const_iterator constEnd() const
QList::at
const T & at(int i) const
QMap< QString, QStringList >
QString::size
int size() const
KContacts::Geo
Geographic position.
Definition: geo.h:36
KContacts::CalendarUrl
Class that holds a Calendar Url (FBURL/CALADRURI/CALURI)
Definition: calendarurl.h:34
QDateTime::setTime
void setTime(const QTime &time)
QStringList::contains
bool contains(const QString &str, Qt::CaseSensitivity cs) const
QByteArray::isEmpty
bool isEmpty() const
QTime::isValid
bool isValid() const
KContacts::Address::setStreet
void setStreet(const QString &street)
Sets the street (including house number).
Definition: address.cpp:416
KContacts::Secrecy::type
Type type() const
Returns the type.
Definition: secrecy.cpp:91
KContacts::Addressee::setPrefix
void setPrefix(const QString &prefix)
Set honorific prefixes.
Definition: addressee.cpp:712
QDateTime::time
QTime time() const
KContacts::Address::setLabel
void setLabel(const QString &label)
Sets the delivery label.
Definition: address.cpp:496
KContacts::PhoneNumber::Fax
Fax machine.
Definition: phonenumber.h:65
KContacts::Address::setGeo
void setGeo(const Geo &geo)
Set geographic position.
Definition: address.cpp:544
QTime::fromString
QTime fromString(const QString &string, Qt::DateFormat format)
KContacts::PhoneNumber::Pcs
Personal Communication Service.
Definition: phonenumber.h:72
KContacts::PhoneNumber::setType
void setType(Type type)
Sets the type.
Definition: phonenumber.cpp:152
QStringList::join
QString join(const QString &separator) const
KContacts::Picture::isEmpty
bool isEmpty() const
Returns true, if the picture is empty.
Definition: picture.cpp:136
KContacts::Addressee::setGivenName
void setGivenName(const QString &givenName)
Set given name.
Definition: addressee.cpp:672
QString::remove
QString & remove(int position, int n)
QVector::ConstIterator
typedef ConstIterator
KContacts::Addressee::setDepartment
void setDepartment(const QString &department)
Set department.
Definition: addressee.cpp:1171
QTime
KContacts::Addressee::sound
Sound sound() const
Return sound.
Definition: addressee.cpp:1367
KContacts::Addressee::setAdditionalName
void setAdditionalName(const QString &additionalName)
Set additional names.
Definition: addressee.cpp:692
KContacts::PhoneNumber::TypeFlag
TypeFlag
Phone number types.
Definition: phonenumber.h:59
KContacts::Address::Pref
preferred address
Definition: address.h:83
KContacts::Geo::setLongitude
void setLongitude(float longitude)
Sets the longitude.
Definition: geo.cpp:92
KContacts::Addressee::insertEmail
void insertEmail(const QString &email, bool preferred=false, const QMap< QString, QStringList > &param=QMap< QString, QStringList >())
Insert an email address.
Definition: addressee.cpp:1596
QList::size
int size() const
KContacts::Sound::isEmpty
bool isEmpty() const
Returns true, if the sound object is empty.
Definition: sound.cpp:127
KContacts::PhoneNumber::Video
Video phone.
Definition: phonenumber.h:67
KContacts::PhoneNumber::Car
Car phone.
Definition: phonenumber.h:70
QList::value
T value(int i) const
values
QVector< V > values(const QMultiHash< K, V > &c)
QUrl::setPath
void setPath(const QString &path, ParsingMode mode)
KContacts::Address::setType
void setType(Type type)
Sets the type of address.
Definition: address.cpp:324
KContacts::Addressee::setCategories
void setCategories(const QStringList &category)
Set categories to given value.
Definition: addressee.cpp:2094
KContacts::PhoneNumber::Pref
Preferred number.
Definition: phonenumber.h:63
QDate::fromString
QDate fromString(const QString &string, Qt::DateFormat format)
KContacts::Address::Dom
domestic
Definition: address.h:77
QList::count
int count(const T &value) const
KContacts::ClientPidMap
Class that holds a ClientPidMap for a contact.
Definition: clientpidmap.h:33
QList::append
void append(const T &value)
KContacts::TimeZone::offset
int offset() const
Return offset in minutes relative to UTC.
Definition: timezone.cpp:73
QMapIterator
KContacts::Addressee::setSortString
void setSortString(const QString &sortString)
Set sort string.
Definition: addressee.cpp:1251
KItinerary::LocationUtil::address
PostalAddress address(const QVariant &location)
KContacts::PhoneNumber::Msg
Messaging.
Definition: phonenumber.h:62
KContacts::Key::textData
QString textData() const
Returns the text data.
Definition: key.cpp:148
QMapIterator::next
Item next()
Akonadi::Server::DbType::type
Type type(const QSqlDatabase &db)
KStandardShortcut::label
QString label(StandardShortcut id)
KContacts::Addressee::setFamilyName
void setFamilyName(const QString &familyName)
Set family name.
Definition: addressee.cpp:652
KItinerary::LocationUtil::geo
GeoCoordinates geo(const QVariant &location)
QList::isEmpty
bool isEmpty() const
KContacts::Picture::url
QString url() const
Returns the location URL of this picture.
Definition: picture.cpp:184
QString::isEmpty
bool isEmpty() const
QList::removeAll
int removeAll(const T &value)
KContacts::PhoneNumber::Pager
Pager.
Definition: phonenumber.h:73
QString::startsWith
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
KContacts::Address::Home
home address
Definition: address.h:81
KContacts::Key
A class to store an encryption key.
Definition: key.h:33
QUrl::setScheme
void setScheme(const QString &scheme)
QDate::isValid
bool isValid() const
KContacts::Address::setRegion
void setRegion(const QString &region)
Sets the region, e.g.
Definition: address.cpp:448
QTime::addSecs
QTime addSecs(int s) const
QList::Iterator
typedef Iterator
KContacts::Addressee::photo
Picture photo() const
Return photo.
Definition: addressee.cpp:1347
QDate
KContacts::PhoneNumber::Bbs
Mailbox.
Definition: phonenumber.h:68
QDate::year
int year() const
KContacts::Secrecy::setType
void setType(Type type)
Sets the type.
Definition: secrecy.cpp:86
QString
KContacts::Address::Parcel
parcel
Definition: address.h:80
QStringList
KContacts::Impp
Class that holds a IMPP for a contact.
Definition: impp.h:39
QString::right
QString right(int n) const
KContacts::Geo::setLatitude
void setLatitude(float latitude)
Sets the latitude.
Definition: geo.cpp:76
KContacts::Picture
A class to store a picture of an addressee.
Definition: picture.h:39
QTime::hour
int hour() const
KContacts::PhoneNumber::Modem
Modem.
Definition: phonenumber.h:69
QList::end
iterator end()
QString::toLower
QString toLower() const
KContacts::Sound::setData
void setData(const QByteArray &data)
Sets the raw data of the sound.
Definition: sound.cpp:116
KContacts::Picture::rawData
QByteArray rawData() const
Returns the raw data of this picture.
Definition: picture.cpp:198
QString::contains
bool contains(QChar ch, Qt::CaseSensitivity cs) const
QUrl
QLatin1Char
KContacts::Address::setExtended
void setExtended(const QString &extended)
Sets the extended address information.
Definition: address.cpp:400
QDateTime::timeSpec
Qt::TimeSpec timeSpec() const
KContacts::Addressee::setProductId
void setProductId(const QString &productId)
Set product identifier.
Definition: addressee.cpp:1211
QString::midRef
QStringRef midRef(int position, int n) const
QChar::toLatin1
char toLatin1() const
KContacts::Address::setPostalCode
void setPostalCode(const QString &code)
Sets the postal code.
Definition: address.cpp:464
KContacts::PhoneNumber::Isdn
ISDN connection.
Definition: phonenumber.h:71
KContacts::Key::binaryData
QByteArray binaryData() const
Returns the binary data.
Definition: key.cpp:137
KContacts::Addressee::insertCustom
void insertCustom(const QString &app, const QString &name, const QString &value)
Insert custom entry.
Definition: addressee.cpp:2257
QString::replace
QString & replace(int position, int n, QChar after)
KStandardShortcut::end
const QList< QKeySequence > & end()
KContacts::Addressee::insertKey
void insertKey(const Key &key)
Insert a key.
Definition: addressee.cpp:1812
QVector::constBegin
const_iterator constBegin() const
org
KContacts::Sound
Class that holds a Sound clip for a contact.
Definition: sound.h:57
KContacts::Sound::url
QString url() const
Returns the location URL of this sound.
Definition: sound.cpp:133
KContacts
Definition: address.h:32
QString::mid
QString mid(int position, int n) const
QDateTime::date
QDate date() const
QVector
KContacts::Key::PGP
Pretty Good Privacy key.
Definition: key.h:49
KContacts::Addressee::setNote
void setNote(const QString &note)
Set note.
Definition: addressee.cpp:1191
KContacts::Address
Postal address information.
Definition: address.h:40
KContacts::Address::setPostOfficeBox
void setPostOfficeBox(const QString &postOfficeBox)
Sets the post office box.
Definition: address.cpp:384
QLatin1String
KContacts::NickName
Class that holds a NickName for a contact.
Definition: nickname.h:33
KContacts::Address::setCountry
void setCountry(const QString &country)
Sets the country.
Definition: address.cpp:480
KContacts::Picture::setRawData
void setRawData(const QByteArray &rawData, const QString &type)
Sets the raw data of the picture.
Definition: picture.cpp:171
KContacts::Picture::setUrl
void setUrl(const QString &url)
Sets a URL for the location of the picture file.
Definition: picture.cpp:143
KContacts::Addressee::setGeo
void setGeo(const Geo &geo)
Set geographic position.
Definition: addressee.cpp:998
QString::at
const QChar at(int position) const
KContacts::PhoneNumber::Cell
Cell phone.
Definition: phonenumber.h:66
KContacts::Addressee::setRevision
void setRevision(const QDateTime &revision)
Set revision date.
Definition: addressee.cpp:1231
KContacts::Lang
Class that holds a Language for a contact.
Definition: lang.h:33
KContacts::Key::X509
X509 key.
Definition: key.h:48
QList::ConstIterator
typedef ConstIterator
KContacts::Secrecy
Descripes the confidentiality of an addressee.
Definition: secrecy.h:30
KContacts::Addressee::setLogo
void setLogo(const Picture &logo)
Set logo.
Definition: addressee.cpp:1317
KContacts::Addressee::setBirthday
void setBirthday(const QDateTime &birthday, bool withTime=true)
Set birthday (date and time).
Definition: addressee.cpp:803
KContacts::Gender
Class that holds a Gender for a contact.
Definition: gender.h:32
KContacts::Title
Class that holds a Title for a contact.
Definition: title.h:33
QString::length
int length() const
QString::left
QString left(int n) const
QString::fromLatin1
QString fromLatin1(const char *str, int size)
KContacts::TimeZone::isValid
bool isValid() const
Return, if this time zone object is valid.
Definition: timezone.cpp:78
KContacts::Key::setType
void setType(Type type)
Sets the type.
Definition: key.cpp:158
KContacts::Key::setCustomTypeString
void setCustomTypeString(const QString &type)
Sets custom type string.
Definition: key.cpp:163
KContacts::Sound::isIntern
bool isIntern() const
Returns whether the sound is described by a URL (extern) or by the raw data (intern).
Definition: sound.cpp:122
KContacts::Picture::isIntern
bool isIntern() const
Returns whether the picture is described by a URL (extern) or by the raw data (intern).
Definition: picture.cpp:179
KContacts::Addressee
address book entry
Definition: addressee.h:81
KContacts::PhoneNumber::Voice
Voice.
Definition: phonenumber.h:64
KContacts::Address::Intl
international
Definition: address.h:78
KContacts::Org
Class that holds a Organization for a contact.
Definition: org.h:33
KContacts::TimeZone
Time zone information.
Definition: timezone.h:34
KContacts::Addressee::setName
void setName(const QString &name)
Set name.
Definition: addressee.cpp:436
KContacts::Address::TypeFlag
TypeFlag
Address types:
Definition: address.h:76
QList::constEnd
const_iterator constEnd() const
QList::constBegin
const_iterator constBegin() const
KContacts::Address::Work
address at work
Definition: address.h:82
KContacts::PhoneNumber::Home
Home number.
Definition: phonenumber.h:60
QDateTime::offsetFromUtc
int offsetFromUtc() const
QString::compare
int compare(const QString &other, Qt::CaseSensitivity cs) const
KContacts::PhoneNumber::Work
Office number.
Definition: phonenumber.h:61
KContacts::Sound::setUrl
void setUrl(const QString &url)
Sets a URL for the location of the sound file.
Definition: sound.cpp:110
QVector::end
iterator end()
KContacts::Key::customTypeString
QString customTypeString() const
Returns the custom type string.
Definition: key.cpp:173
QList::begin
iterator begin()
KContacts::Addressee::setSecrecy
void setSecrecy(const Secrecy &secrecy)
Set security class.
Definition: addressee.cpp:1297
KContacts::PhoneNumber
Phonenumber information.
Definition: phonenumber.h:40
KContacts::Key::setBinaryData
void setBinaryData(const QByteArray &data)
Sets binary data.
Definition: key.cpp:131
QDateTime
KContacts::Addressee::insertAddress
void insertAddress(const Address &address)
Insert an address.
Definition: addressee.cpp:1990
KAlarmCal::CalEvent::types
Types types(const QStringList &mimeTypes)
KContacts::Address::Postal
postal
Definition: address.h:79
KContacts::Addressee::setSound
void setSound(const Sound &sound)
Set sound.
Definition: addressee.cpp:1357
KContacts::Addressee::logo
Picture logo() const
Return logo.
Definition: addressee.cpp:1327
This file is part of the KDE documentation.
Documentation copyright © 1996-2019 The KDE developers.
Generated on Mon Dec 16 2019 01:11:11 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

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