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

KDE's Doxygen guidelines are available online.