KContacts

address.cpp
1 /*
2  This file is part of the KContacts framework.
3  SPDX-FileCopyrightText: 2001 Cornelius Schumacher <[email protected]>
4 
5  SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7 
8 #include "address.h"
9 #include "countrytoisomap_data.cpp"
10 #include "isotocountrymap_data.cpp"
11 
12 #include "kcontacts_debug.h"
13 #include <KConfig>
14 #include <KLocalizedString>
15 #include <krandom.h>
16 
17 #include <KConfigGroup>
18 
19 #include <QDataStream>
20 #include <QLocale>
21 #include <QSharedData>
22 #include <QStandardPaths>
23 
24 using namespace KContacts;
25 
26 // template tags for address formatting localization
27 #define KCONTACTS_FMTTAG_realname QStringLiteral("%n")
28 #define KCONTACTS_FMTTAG_REALNAME QStringLiteral("%N")
29 #define KCONTACTS_FMTTAG_company QStringLiteral("%cm")
30 #define KCONTACTS_FMTTAG_COMPANY QStringLiteral("%CM")
31 #define KCONTACTS_FMTTAG_pobox QStringLiteral("%p")
32 #define KCONTACTS_FMTTAG_street QStringLiteral("%s")
33 #define KCONTACTS_FMTTAG_STREET QStringLiteral("%S")
34 #define KCONTACTS_FMTTAG_zipcode QStringLiteral("%z")
35 #define KCONTACTS_FMTTAG_location QStringLiteral("%l")
36 #define KCONTACTS_FMTTAG_LOCATION QStringLiteral("%L")
37 #define KCONTACTS_FMTTAG_region QStringLiteral("%r")
38 #define KCONTACTS_FMTTAG_REGION QStringLiteral("%R")
39 #define KCONTACTS_FMTTAG_newline QStringLiteral("\\n")
40 #define KCONTACTS_FMTTAG_condcomma QStringLiteral("%,")
41 #define KCONTACTS_FMTTAG_condwhite QStringLiteral("%w")
42 #define KCONTACTS_FMTTAG_purgeempty QStringLiteral("%0")
43 
44 /**
45  Finds the balanced closing bracket starting from the opening bracket at
46  pos in tsection.
47  @return position of closing bracket, -1 for unbalanced brackets
48 */
49 static int findBalancedBracket(const QString &tsection, int pos)
50 {
51  int balancecounter = 0;
52  for (int i = pos + 1; i < tsection.length(); ++i) {
53  if (QLatin1Char(')') == tsection[i] && 0 == balancecounter) {
54  // found end of brackets
55  return i;
56  } else {
57  if (QLatin1Char('(') == tsection[i]) {
58  // nested brackets
59  balancecounter++;
60  }
61  }
62  }
63  return -1;
64 }
65 
66 /**
67  Parses a snippet of an address template
68  @param tsection the template string to be parsed
69  @param result QString reference in which the result will be stored
70  @return true if at least one tag evaluated positively, else false
71 */
72 static bool
73 parseAddressTemplateSection(const QString &tsection, QString &result, const QString &realName, const QString &orgaName, const KContacts::Address &address)
74 {
75  // This method first parses and substitutes any bracketed sections and
76  // after that replaces any tags with their values. If a bracketed section
77  // or a tag evaluate to zero, they are not just removed but replaced
78  // with a placeholder. This is because in the last step conditionals are
79  // resolved which depend on information about zero-evaluations.
80  result = tsection;
81  int stpos = 0;
82  bool ret = false;
83 
84  // first check for brackets that have to be evaluated first
85  int fpos = result.indexOf(KCONTACTS_FMTTAG_purgeempty, stpos);
86  while (-1 != fpos) {
87  int bpos1 = fpos + KCONTACTS_FMTTAG_purgeempty.length();
88  // expect opening bracket and find next balanced closing bracket. If
89  // next char is no opening bracket, continue parsing (no valid tag)
90  if (QLatin1Char('(') == result[bpos1]) {
91  int bpos2 = findBalancedBracket(result, bpos1);
92  if (-1 != bpos2) {
93  // we have balanced brackets, recursively parse:
94  QString rplstr;
95  bool purge = !parseAddressTemplateSection(result.mid(bpos1 + 1, bpos2 - bpos1 - 1), //
96  rplstr,
97  realName,
98  orgaName,
99  address);
100  if (purge) {
101  // purge -> remove all
102  // replace with !_P_!, so conditional tags work later
103  result.replace(fpos, bpos2 - fpos + 1, QStringLiteral("!_P_!"));
104  // leave stpos as it is
105  } else {
106  // no purge -> replace with recursively parsed string
107  result.replace(fpos, bpos2 - fpos + 1, rplstr);
108  ret = true;
109  stpos = fpos + rplstr.length();
110  }
111  } else {
112  // unbalanced brackets: keep on parsing (should not happen
113  // and will result in bad formatting)
114  stpos = bpos1;
115  }
116  }
117  fpos = result.indexOf(KCONTACTS_FMTTAG_purgeempty, stpos);
118  }
119 
120  // after sorting out all purge tags, we just search'n'replace the rest,
121  // keeping track of whether at least one tag evaluates to something.
122  // The following macro needs QString for R_FIELD
123  // It substitutes !_P_! for empty fields so conditional tags work later
124  // clang-format off
125 #define REPLTAG(R_TAG, R_FIELD) \
126  if (result.contains(R_TAG)) { \
127  QString rpl = R_FIELD.isEmpty() ? QStringLiteral("!_P_!") : R_FIELD; \
128  result.replace(R_TAG, rpl); \
129  if (!R_FIELD.isEmpty()) { \
130  ret = true; \
131  } \
132  }
133  // clang-format on
134  REPLTAG(KCONTACTS_FMTTAG_realname, realName);
135  REPLTAG(KCONTACTS_FMTTAG_REALNAME, realName.toUpper());
136  REPLTAG(KCONTACTS_FMTTAG_company, orgaName);
137  REPLTAG(KCONTACTS_FMTTAG_COMPANY, orgaName.toUpper());
138  REPLTAG(KCONTACTS_FMTTAG_pobox, address.postOfficeBox());
139  REPLTAG(KCONTACTS_FMTTAG_street, address.street());
140  REPLTAG(KCONTACTS_FMTTAG_STREET, address.street().toUpper());
141  REPLTAG(KCONTACTS_FMTTAG_zipcode, address.postalCode());
142  REPLTAG(KCONTACTS_FMTTAG_location, address.locality());
143  REPLTAG(KCONTACTS_FMTTAG_LOCATION, address.locality().toUpper());
144  REPLTAG(KCONTACTS_FMTTAG_region, address.region());
145  REPLTAG(KCONTACTS_FMTTAG_REGION, address.region().toUpper());
146  result.replace(KCONTACTS_FMTTAG_newline, QLatin1String("\n"));
147 #undef REPLTAG
148 
149  // conditional comma
150  fpos = result.indexOf(KCONTACTS_FMTTAG_condcomma, 0);
151  while (-1 != fpos) {
152  const QString str1 = result.mid(fpos - 5, 5);
153  const QString str2 = result.mid(fpos + 2, 5);
154  if (str1 != QLatin1String("!_P_!") && str2 != QLatin1String("!_P_!")) {
155  result.replace(fpos, 2, QStringLiteral(", "));
156  } else {
157  result.remove(fpos, 2);
158  }
159  fpos = result.indexOf(KCONTACTS_FMTTAG_condcomma, fpos);
160  }
161  // conditional whitespace
162  fpos = result.indexOf(KCONTACTS_FMTTAG_condwhite, 0);
163  while (-1 != fpos) {
164  const QString str1 = result.mid(fpos - 5, 5);
165  const QString str2 = result.mid(fpos + 2, 5);
166  if (str1 != QLatin1String("!_P_!") && str2 != QLatin1String("!_P_!")) {
167  result.replace(fpos, 2, QLatin1Char(' '));
168  } else {
169  result.remove(fpos, 2);
170  }
171  fpos = result.indexOf(KCONTACTS_FMTTAG_condwhite, fpos);
172  }
173 
174  // remove purged:
175  result.remove(QStringLiteral("!_P_!"));
176 
177  return ret;
178 }
179 
180 class Q_DECL_HIDDEN Address::Private : public QSharedData
181 {
182 public:
183  Private()
184  : mEmpty(true)
185  {
186  mId = KRandom::randomString(10);
187  }
188 
189  Private(const Private &other)
190  : QSharedData(other)
191  {
192  mEmpty = other.mEmpty;
193  mId = other.mId;
194  mType = other.mType;
195 
196  mPostOfficeBox = other.mPostOfficeBox;
197  mExtended = other.mExtended;
198  mStreet = other.mStreet;
199  mLocality = other.mLocality;
200  mRegion = other.mRegion;
201  mPostalCode = other.mPostalCode;
202  mCountry = other.mCountry;
203  mLabel = other.mLabel;
204  }
205 
206  bool mEmpty;
207  QString mId;
208  Type mType;
209  Geo mGeo;
210 
211  QString mPostOfficeBox;
212  QString mExtended;
213  QString mStreet;
214  QString mLocality;
215  QString mRegion;
216  QString mPostalCode;
217  QString mCountry;
218  QString mLabel;
219 };
220 
222  : d(new Private)
223 {
224 }
225 
227  : d(new Private)
228 {
229  d->mType = type;
230 }
231 
233  : d(other.d)
234 {
235 }
236 
238 {
239 }
240 
242 {
243  if (this != &other) {
244  d = other.d;
245  }
246 
247  return *this;
248 }
249 
250 bool Address::operator==(const Address &other) const
251 {
252  if (d->mId != other.d->mId) {
253  return false;
254  }
255  if (d->mType != other.d->mType) {
256  return false;
257  }
258  if (d->mPostOfficeBox != other.d->mPostOfficeBox) {
259  return false;
260  }
261  if (d->mExtended != other.d->mExtended) {
262  return false;
263  }
264  if (d->mStreet != other.d->mStreet) {
265  return false;
266  }
267  if (d->mLocality != other.d->mLocality) {
268  return false;
269  }
270  if (d->mRegion != other.d->mRegion) {
271  return false;
272  }
273  if (d->mPostalCode != other.d->mPostalCode) {
274  return false;
275  }
276  if (d->mCountry != other.d->mCountry) {
277  return false;
278  }
279  if (d->mLabel != other.d->mLabel) {
280  return false;
281  }
282 
283  if (d->mGeo != other.d->mGeo) {
284  return false;
285  }
286 
287  return true;
288 }
289 
290 bool Address::operator!=(const Address &a) const
291 {
292  return !(a == *this);
293 }
294 
295 bool Address::isEmpty() const
296 {
297  return d->mEmpty;
298 }
299 
301 {
302  *this = Address();
303 }
304 
305 void Address::setId(const QString &id)
306 {
307  d->mEmpty = false;
308  d->mId = id;
309 }
310 
311 QString Address::id() const
312 {
313  return d->mId;
314 }
315 
317 {
318  d->mEmpty = false;
319  d->mType = type;
320 }
321 
323 {
324  return d->mType;
325 }
326 
328 {
329  QString label;
330  bool first = true;
331  const TypeList list = typeList();
332 
334  TypeList::ConstIterator end(list.end());
335  for (it = list.begin(); it != end; ++it) {
336  // these are actually flags
337  const TypeFlag flag = static_cast<TypeFlag>(static_cast<int>(*it));
338  if (type & flag) {
339  if (!first) {
340  label.append(QLatin1Char('/'));
341  }
342 
343  label.append(typeFlagLabel(flag));
344 
345  if (first) {
346  first = false;
347  }
348  }
349  }
350  return label;
351 }
352 
354 {
355  QString label;
356  bool first = true;
357 
358  const TypeList list = typeList();
359 
361  for (it = list.begin(); it != list.end(); ++it) {
362  if ((type() & (*it)) && ((*it) != Pref)) {
363  if (!first) {
364  label.append(QLatin1Char('/'));
365  }
366  label.append(typeLabel(*it));
367  if (first) {
368  first = false;
369  }
370  }
371  }
372 
373  return label;
374 }
375 
377 {
378  d->mEmpty = false;
379  d->mPostOfficeBox = postOfficeBox;
380 }
381 
383 {
384  return d->mPostOfficeBox;
385 }
386 
388 {
389  return i18n("Post Office Box");
390 }
391 
393 {
394  d->mEmpty = false;
395  d->mExtended = extended;
396 }
397 
399 {
400  return d->mExtended;
401 }
402 
404 {
405  return i18n("Extended Address Information");
406 }
407 
409 {
410  d->mEmpty = false;
411  d->mStreet = street;
412 }
413 
414 QString Address::street() const
415 {
416  return d->mStreet;
417 }
418 
420 {
421  return i18n("Street");
422 }
423 
425 {
426  d->mEmpty = false;
427  d->mLocality = locality;
428 }
429 
431 {
432  return d->mLocality;
433 }
434 
436 {
437  return i18n("Locality");
438 }
439 
441 {
442  d->mEmpty = false;
443  d->mRegion = region;
444 }
445 
446 QString Address::region() const
447 {
448  return d->mRegion;
449 }
450 
452 {
453  return i18n("Region");
454 }
455 
457 {
458  d->mEmpty = false;
459  d->mPostalCode = postalCode;
460 }
461 
463 {
464  return d->mPostalCode;
465 }
466 
468 {
469  return i18n("Postal Code");
470 }
471 
473 {
474  d->mEmpty = false;
475  d->mCountry = country;
476 }
477 
479 {
480  return d->mCountry;
481 }
482 
484 {
485  return i18n("Country");
486 }
487 
489 {
490  d->mEmpty = false;
491  d->mLabel = label;
492 }
493 
494 QString Address::label() const
495 {
496  return d->mLabel;
497 }
498 
500 {
501  return i18n("Delivery Label");
502 }
503 
505 {
506  static TypeList list;
507 
508  if (list.isEmpty()) {
509  list << Dom << Intl << Postal << Parcel << Home << Work << Pref;
510  }
511 
512  return list;
513 }
514 
515 QString Address::typeFlagLabel(TypeFlag type)
516 {
517  switch (type) {
518  case Dom:
519  return i18nc("Address is in home country", "Domestic");
520  case Intl:
521  return i18nc("Address is not in home country", "International");
522  case Postal:
523  return i18nc("Address for delivering letters", "Postal");
524  case Parcel:
525  return i18nc("Address for delivering packages", "Parcel");
526  case Home:
527  return i18nc("Home Address", "Home");
528  case Work:
529  return i18nc("Work Address", "Work");
530  case Pref:
531  return i18n("Preferred Address");
532  }
533  return i18nc("another type of address", "Other");
534 }
535 
536 void Address::setGeo(const Geo &geo)
537 {
538  d->mEmpty = false;
539  d->mGeo = geo;
540 }
541 
542 Geo Address::geo() const
543 {
544  return d->mGeo;
545 }
546 
548 {
549  QString str = QLatin1String("Address {\n");
550  str += QStringLiteral(" IsEmpty: %1\n").arg(d->mEmpty ? QStringLiteral("true") : QStringLiteral("false"));
551  str += QStringLiteral(" Id: %1\n").arg(d->mId);
552  str += QStringLiteral(" Type: %1\n").arg(typeLabel(d->mType));
553  str += QStringLiteral(" Post office box: %1\n").arg(d->mPostOfficeBox);
554  str += QStringLiteral(" Extended: %1\n").arg(d->mExtended);
555  str += QStringLiteral(" Street: %1\n").arg(d->mStreet);
556  str += QStringLiteral(" Locality: %1\n").arg(d->mLocality);
557  str += QStringLiteral(" Region: %1\n").arg(d->mRegion);
558  str += QStringLiteral(" Postal code: %1\n").arg(d->mPostalCode);
559  str += QStringLiteral(" Country: %1\n").arg(d->mCountry);
560  str += QStringLiteral(" Label: %1\n").arg(d->mLabel);
561  str += QStringLiteral(" Geo: %1\n").arg(d->mGeo.toString());
562  str += QLatin1String("}\n");
563 
564  return str;
565 }
566 
567 static QString countryCodeFromLocale()
568 {
569  const auto n = QLocale().name(); // this is in the form <lang>_<COUNTRY>, with the exception of 'C'
570  const auto idx = n.indexOf(QLatin1Char('_'));
571  if (idx > 0) {
572  return n.mid(idx + 1).toLower();
573  }
574  return {};
575 }
576 
577 static QString addressFormatRc()
578 {
579  Q_INIT_RESOURCE(kcontacts); // must be called outside of a namespace
580  return QStringLiteral(":/org.kde.kcontacts/addressformatrc");
581 }
582 
583 QString Address::formattedAddress(const QString &realName, const QString &orgaName) const
584 {
585  QString ciso;
586  QString addrTemplate;
587  QString ret;
588 
589  // FIXME: first check for iso-country-field and prefer that one
590  if (!country().isEmpty()) {
591  ciso = countryToISO(country());
592  } else {
593  // fall back to our own country
594  ciso = countryCodeFromLocale();
595  }
596  static const KConfig entry(addressFormatRc());
597 
598  KConfigGroup group = entry.group(ciso);
599  // decide whether this needs special business address formatting
600  if (orgaName.isEmpty()) {
601  addrTemplate = group.readEntry("AddressFormat");
602  } else {
603  addrTemplate = group.readEntry("BusinessAddressFormat");
604  if (addrTemplate.isEmpty()) {
605  addrTemplate = group.readEntry("AddressFormat");
606  }
607  }
608 
609  // in the case there's no format found at all, default to what we've always
610  // used:
611  if (addrTemplate.isEmpty()) {
612  qCWarning(KCONTACTS_LOG) << "address format database incomplete"
613  << "(no format for locale" << ciso << "found). Using default address formatting.";
614  addrTemplate = QStringLiteral("%0(%n\\n)%0(%cm\\n)%0(%s\\n)%0(PO BOX %p\\n)%0(%l%w%r)%,%z");
615  }
616 
617  // scan
618  parseAddressTemplateSection(addrTemplate, ret, realName, orgaName, *this);
619 
620  // now add the country line if needed (formatting this time according to
621  // the rules of our own system country )
622  if (!country().isEmpty()) {
623  // Don't include line breaks if country is the only text
624  if (ret.isEmpty()) {
625  return country().toUpper();
626  }
627 
628  KConfigGroup group = entry.group(countryCodeFromLocale());
629  QString cpos = group.readEntry("AddressCountryPosition");
630  if (QLatin1String("BELOW") == cpos || cpos.isEmpty()) {
631  ret = ret + QLatin1String("\n\n") + country().toUpper();
632  } else if (QLatin1String("below") == cpos) {
633  ret = ret + QLatin1String("\n\n") + country();
634  } else if (QLatin1String("ABOVE") == cpos) {
635  ret = country().toUpper() + QLatin1String("\n\n") + ret;
636  } else if (QLatin1String("above") == cpos) {
637  ret = country() + QLatin1String("\n\n") + ret;
638  }
639  }
640 
641  return ret;
642 }
643 
645 {
646  const auto lookupKey = normalizeCountryName(cname);
647 
648  // look for an exact match
649  auto it =
650  std::lower_bound(std::begin(country_to_iso_index), std::end(country_to_iso_index), lookupKey, [](const CountryToIsoIndex &lhs, const QByteArray &rhs) {
651  return strcmp(country_name_stringtable + lhs.m_offset, rhs.constData()) < 0;
652  });
653  if (it != std::end(country_to_iso_index) && strcmp(country_name_stringtable + (*it).m_offset, lookupKey.constData()) == 0) {
654  return (*it).isoCode();
655  }
656 
657  // a unique prefix will do too
658  it = std::lower_bound(std::begin(country_to_iso_index), std::end(country_to_iso_index), lookupKey, [](const CountryToIsoIndex &lhs, const QByteArray &rhs) {
659  return strncmp(country_name_stringtable + lhs.m_offset, rhs.constData(), strlen(country_name_stringtable + lhs.m_offset)) < 0;
660  });
661  const auto endIt =
662  std::upper_bound(std::begin(country_to_iso_index), std::end(country_to_iso_index), lookupKey, [](const QByteArray &lhs, const CountryToIsoIndex &rhs) {
663  return strncmp(lhs.constData(), country_name_stringtable + rhs.m_offset, strlen(country_name_stringtable + rhs.m_offset)) < 0;
664  });
665  if (it != std::end(country_to_iso_index) && endIt == (it + 1)
666  && strncmp(country_name_stringtable + (*it).m_offset, lookupKey.constData(), strlen(country_name_stringtable + (*it).m_offset)) == 0) {
667  return (*it).isoCode();
668  }
669 
670  return {};
671 }
672 
674 {
675  // get country name from ISO country code (e.g. "no" -> i18n("Norway"))
676  const auto iso = ISOname.simplified().toLower().toUtf8();
677  if (iso.size() != 2) {
678  return ISOname;
679  }
680 
681  const auto it =
682  std::lower_bound(std::begin(iso_to_country_index), std::end(iso_to_country_index), iso.constData(), [](const IsoToCountryIndex &lhs, const char *rhs) {
683  return strncmp(&lhs.m_c1, rhs, 2) < 0;
684  });
685  if (it != std::end(iso_to_country_index) && strncmp(&(*it).m_c1, iso.constData(), 2) == 0) {
686  return i18nd("iso_3166-1", en_country_name_stringtable + (*it).m_offset);
687  }
688 
689  return ISOname;
690 }
691 
692 // clang-format off
693 QDataStream &KContacts::operator<<(QDataStream &s, const Address &addr)
694 {
695  return s << addr.d->mId << (uint)addr.d->mType << addr.d->mPostOfficeBox
696  << addr.d->mExtended << addr.d->mStreet << addr.d->mLocality
697  << addr.d->mRegion << addr.d->mPostalCode << addr.d->mCountry
698  << addr.d->mLabel << addr.d->mEmpty << addr.d->mGeo;
699 }
700 
701 QDataStream &KContacts::operator>>(QDataStream &s, Address &addr)
702 {
703  uint type;
704  s >> addr.d->mId >> type >> addr.d->mPostOfficeBox >> addr.d->mExtended
705  >> addr.d->mStreet >> addr.d->mLocality >> addr.d->mRegion
706  >> addr.d->mPostalCode >> addr.d->mCountry >> addr.d->mLabel
707  >> addr.d->mEmpty >> addr.d->mGeo;
708 
709  addr.d->mType = Address::Type(type);
710 
711  return s;
712 }
713 // clang-format on
QString street() const
Returns the street.
static QString labelLabel()
Returns the translated label for delivery label field.
Definition: address.cpp:499
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const const
void setId(const QString &identifier)
Sets the unique identifier.
Definition: address.cpp:305
QString region() const
Returns the region.
QString & append(QChar ch)
QString toUpper() const const
void setLocality(const QString &locality)
Sets the locality, e.g.
Definition: address.cpp:424
static QString localityLabel()
Returns the translated label for locality field.
Definition: address.cpp:435
QString id() const
Returns the unique identifier.
static QString countryToISO(const QString &cname)
Returns ISO code for a localized country name.
Definition: address.cpp:644
QString country() const
Returns the country.
Geographic position.
Definition: geo.h:24
QString simplified() const const
void setStreet(const QString &street)
Sets the street (including house number).
Definition: address.cpp:408
void setLabel(const QString &label)
Sets the delivery label.
Definition: address.cpp:488
void setGeo(const Geo &geo)
Set geographic position.
Definition: address.cpp:536
QString & remove(int position, int n)
preferred address
Definition: address.h:72
static QString extendedLabel()
Returns the translated label for extended field.
Definition: address.cpp:403
void setType(Type type)
Sets the type of address.
Definition: address.cpp:316
static QString postalCodeLabel()
Returns the translated label for postal code field.
Definition: address.cpp:467
bool operator!=(const Address &other) const
Not-equal operator.
Definition: address.cpp:290
bool operator==(const Address &other) const
Equality operator.
Definition: address.cpp:250
QString postOfficeBox() const
Returns the post office box.
Address()
Creates an empty address.
Definition: address.cpp:221
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString label() const
Returns the delivery label.
QString formattedAddress
Country-specific formatted address without an addressee.
Definition: address.h:53
bool isEmpty() const const
bool isEmpty() const const
const char * constData() const const
home address
Definition: address.h:70
void setRegion(const QString &region)
Sets the region, e.g.
Definition: address.cpp:440
QString postalCode() const
Returns the postal code.
Type type() const
Returns the type of address.
QString name() const const
QString locality() const
Returns the locality.
Address & operator=(const Address &other)
Assignment operator.
Definition: address.cpp:241
~Address()
Destroys the address.
Definition: address.cpp:237
QString extended() const
Returns the extended address information.
QList::iterator end()
QString toLower() const const
void setExtended(const QString &extended)
Sets the extended address information.
Definition: address.cpp:392
static QString postOfficeBoxLabel()
Returns the translated label for post office box field.
Definition: address.cpp:387
void setPostalCode(const QString &code)
Sets the postal code.
Definition: address.cpp:456
void clear()
Clears all entries of the address.
Definition: address.cpp:300
static TypeList typeList()
Returns the list of available types.
Definition: address.cpp:504
QString i18n(const char *text, const TYPE &arg...)
KConfigGroup group(const QString &group)
QString & replace(int position, int n, QChar after)
static QString streetLabel()
Returns the translated label for street field.
Definition: address.cpp:419
static QString regionLabel()
Returns the translated label for region field.
Definition: address.cpp:451
QString typeLabel() const
Returns a translated string of all types the address has.
QString mid(int position, int n) const const
Postal address information.
Definition: address.h:28
void setPostOfficeBox(const QString &postOfficeBox)
Sets the post office box.
Definition: address.cpp:376
Geo geo() const
Return geographic position.
void setCountry(const QString &country)
Sets the country.
Definition: address.cpp:472
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
static QString ISOtoCountry(const QString &ISOname)
Returns a localized country name for a ISO code.
Definition: address.cpp:673
typedef ConstIterator
bool isEmpty() const
Returns true, if the address is empty.
int length() const const
static QString countryLabel()
Returns the translated label for country field.
Definition: address.cpp:483
QString toString() const
Returns a string representation of the address.
Definition: address.cpp:547
international
Definition: address.h:67
TypeFlag
Address types:
Definition: address.h:65
address at work
Definition: address.h:71
QString i18nd(const char *domain, const char *text, const TYPE &arg...)
KCOREADDONS_EXPORT QString randomString(int length)
T readEntry(const QString &key, const T &aDefault) const
QList::iterator begin()
QFlags< TypeFlag > Type
Stores a combination of TypeFlag values.
Definition: address.h:78
QByteArray toUtf8() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Mon Sep 20 2021 22:56:06 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.