File indexing completed on 2025-01-19 03:39:48
0001 /* 0002 This file is part of the KContacts framework. 0003 SPDX-FileCopyrightText: 2001 Cornelius Schumacher <schumacher@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "address.h" 0009 #include "addressformat.h" 0010 #include "addressformatter_p.h" 0011 0012 #include "kcontacts_debug.h" 0013 #include <KConfig> 0014 #include <KCountry> 0015 #include <KLocalizedString> 0016 #include <krandom.h> 0017 0018 #include <KConfigGroup> 0019 0020 #include <QDataStream> 0021 #include <QSharedData> 0022 #include <QUrlQuery> 0023 0024 using namespace KContacts; 0025 0026 class Q_DECL_HIDDEN Address::Private : public QSharedData 0027 { 0028 public: 0029 Private() 0030 : mEmpty(true) 0031 { 0032 mId = KRandom::randomString(10); 0033 } 0034 0035 Private(const Private &other) 0036 : QSharedData(other) 0037 { 0038 mEmpty = other.mEmpty; 0039 mId = other.mId; 0040 mType = other.mType; 0041 0042 mPostOfficeBox = other.mPostOfficeBox; 0043 mExtended = other.mExtended; 0044 mStreet = other.mStreet; 0045 mLocality = other.mLocality; 0046 mRegion = other.mRegion; 0047 mPostalCode = other.mPostalCode; 0048 mCountry = other.mCountry; 0049 mLabel = other.mLabel; 0050 } 0051 0052 bool mEmpty; 0053 QString mId; 0054 Type mType; 0055 Geo mGeo; 0056 0057 QString mPostOfficeBox; 0058 QString mExtended; 0059 QString mStreet; 0060 QString mLocality; 0061 QString mRegion; 0062 QString mPostalCode; 0063 QString mCountry; 0064 QString mLabel; 0065 }; 0066 0067 Address::Address() 0068 : d(new Private) 0069 { 0070 } 0071 0072 Address::Address(Type type) 0073 : d(new Private) 0074 { 0075 d->mType = type; 0076 } 0077 0078 Address::Address(const Address &other) 0079 : d(other.d) 0080 { 0081 } 0082 0083 Address::~Address() 0084 { 0085 } 0086 0087 Address &Address::operator=(const Address &other) 0088 { 0089 if (this != &other) { 0090 d = other.d; 0091 } 0092 0093 return *this; 0094 } 0095 0096 bool Address::operator==(const Address &other) const 0097 { 0098 if (d->mId != other.d->mId) { 0099 return false; 0100 } 0101 if (d->mType != other.d->mType) { 0102 return false; 0103 } 0104 if (d->mPostOfficeBox != other.d->mPostOfficeBox) { 0105 return false; 0106 } 0107 if (d->mExtended != other.d->mExtended) { 0108 return false; 0109 } 0110 if (d->mStreet != other.d->mStreet) { 0111 return false; 0112 } 0113 if (d->mLocality != other.d->mLocality) { 0114 return false; 0115 } 0116 if (d->mRegion != other.d->mRegion) { 0117 return false; 0118 } 0119 if (d->mPostalCode != other.d->mPostalCode) { 0120 return false; 0121 } 0122 if (d->mCountry != other.d->mCountry) { 0123 return false; 0124 } 0125 if (d->mLabel != other.d->mLabel) { 0126 return false; 0127 } 0128 0129 if (d->mGeo != other.d->mGeo) { 0130 return false; 0131 } 0132 0133 return true; 0134 } 0135 0136 bool Address::operator!=(const Address &a) const 0137 { 0138 return !(a == *this); 0139 } 0140 0141 bool Address::isEmpty() const 0142 { 0143 return d->mEmpty; 0144 } 0145 0146 void Address::clear() 0147 { 0148 *this = Address(); 0149 } 0150 0151 void Address::setId(const QString &id) 0152 { 0153 d->mEmpty = false; 0154 d->mId = id; 0155 } 0156 0157 QString Address::id() const 0158 { 0159 return d->mId; 0160 } 0161 0162 void Address::setType(Type type) 0163 { 0164 d->mEmpty = false; 0165 d->mType = type; 0166 } 0167 0168 Address::Type Address::type() const 0169 { 0170 return d->mType; 0171 } 0172 0173 QString Address::typeLabel(Type type) 0174 { 0175 QString label; 0176 const TypeList list = typeList(); 0177 0178 for (const auto typeFlag : list) { 0179 // these are actually flags 0180 const TypeFlag flag = static_cast<TypeFlag>(static_cast<int>(typeFlag)); 0181 if (type & flag) { 0182 label.append(QLatin1Char('/') + typeFlagLabel(flag)); 0183 } 0184 } 0185 0186 // Remove the first '/' 0187 if (!label.isEmpty()) { 0188 label.remove(0, 1); 0189 } 0190 0191 return label; 0192 } 0193 0194 QString Address::typeLabel() const 0195 { 0196 QString label; 0197 const TypeList list = typeList(); 0198 0199 for (const auto f : list) { 0200 if ((type() & f) && (f != Pref)) { 0201 label.append(QLatin1Char('/') + typeLabel(f)); 0202 } 0203 } 0204 // Remove the first '/' 0205 if (!label.isEmpty()) { 0206 label.remove(0, 1); 0207 } 0208 return label; 0209 } 0210 0211 void Address::setPostOfficeBox(const QString &postOfficeBox) 0212 { 0213 d->mEmpty = false; 0214 d->mPostOfficeBox = postOfficeBox; 0215 } 0216 0217 QString Address::postOfficeBox() const 0218 { 0219 return d->mPostOfficeBox; 0220 } 0221 0222 QString Address::postOfficeBoxLabel() 0223 { 0224 return i18n("Post Office Box"); 0225 } 0226 0227 void Address::setExtended(const QString &extended) 0228 { 0229 d->mEmpty = false; 0230 d->mExtended = extended; 0231 } 0232 0233 QString Address::extended() const 0234 { 0235 return d->mExtended; 0236 } 0237 0238 QString Address::extendedLabel() 0239 { 0240 return i18n("Extended Address Information"); 0241 } 0242 0243 void Address::setStreet(const QString &street) 0244 { 0245 d->mEmpty = false; 0246 d->mStreet = street; 0247 } 0248 0249 QString Address::street() const 0250 { 0251 return d->mStreet; 0252 } 0253 0254 QString Address::streetLabel() 0255 { 0256 return i18n("Street"); 0257 } 0258 0259 void Address::setLocality(const QString &locality) 0260 { 0261 d->mEmpty = false; 0262 d->mLocality = locality; 0263 } 0264 0265 QString Address::locality() const 0266 { 0267 return d->mLocality; 0268 } 0269 0270 QString Address::localityLabel() 0271 { 0272 return i18n("Locality"); 0273 } 0274 0275 void Address::setRegion(const QString ®ion) 0276 { 0277 d->mEmpty = false; 0278 d->mRegion = region; 0279 } 0280 0281 QString Address::region() const 0282 { 0283 return d->mRegion; 0284 } 0285 0286 QString Address::regionLabel() 0287 { 0288 return i18n("Region"); 0289 } 0290 0291 void Address::setPostalCode(const QString &postalCode) 0292 { 0293 d->mEmpty = false; 0294 d->mPostalCode = postalCode; 0295 } 0296 0297 QString Address::postalCode() const 0298 { 0299 return d->mPostalCode; 0300 } 0301 0302 QString Address::postalCodeLabel() 0303 { 0304 return i18n("Postal Code"); 0305 } 0306 0307 void Address::setCountry(const QString &country) 0308 { 0309 d->mEmpty = false; 0310 d->mCountry = country; 0311 } 0312 0313 QString Address::country() const 0314 { 0315 return d->mCountry; 0316 } 0317 0318 QString Address::countryLabel() 0319 { 0320 return i18n("Country"); 0321 } 0322 0323 void Address::setLabel(const QString &label) 0324 { 0325 d->mEmpty = false; 0326 d->mLabel = label; 0327 } 0328 0329 QString Address::label() const 0330 { 0331 return d->mLabel; 0332 } 0333 0334 QString Address::labelLabel() 0335 { 0336 return i18n("Delivery Label"); 0337 } 0338 0339 Address::TypeList Address::typeList() 0340 { 0341 static TypeList list; 0342 0343 if (list.isEmpty()) { 0344 list << Dom << Intl << Postal << Parcel << Home << Work << Pref; 0345 } 0346 0347 return list; 0348 } 0349 0350 QString Address::typeFlagLabel(TypeFlag type) 0351 { 0352 switch (type) { 0353 case Dom: 0354 return i18nc("Address is in home country", "Domestic"); 0355 case Intl: 0356 return i18nc("Address is not in home country", "International"); 0357 case Postal: 0358 return i18nc("Address for delivering letters", "Postal"); 0359 case Parcel: 0360 return i18nc("Address for delivering packages", "Parcel"); 0361 case Home: 0362 return i18nc("Home Address", "Home"); 0363 case Work: 0364 return i18nc("Work Address", "Work"); 0365 case Pref: 0366 return i18n("Preferred Address"); 0367 } 0368 return i18nc("another type of address", "Other"); 0369 } 0370 0371 void Address::setGeo(const Geo &geo) 0372 { 0373 d->mEmpty = false; 0374 d->mGeo = geo; 0375 } 0376 0377 Geo Address::geo() const 0378 { 0379 return d->mGeo; 0380 } 0381 0382 QString Address::toString() const 0383 { 0384 QString str = QLatin1String("Address {\n"); 0385 str += QStringLiteral(" IsEmpty: %1\n").arg(d->mEmpty ? QStringLiteral("true") : QStringLiteral("false")); 0386 str += QStringLiteral(" Id: %1\n").arg(d->mId); 0387 str += QStringLiteral(" Type: %1\n").arg(typeLabel(d->mType)); 0388 str += QStringLiteral(" Post office box: %1\n").arg(d->mPostOfficeBox); 0389 str += QStringLiteral(" Extended: %1\n").arg(d->mExtended); 0390 str += QStringLiteral(" Street: %1\n").arg(d->mStreet); 0391 str += QStringLiteral(" Locality: %1\n").arg(d->mLocality); 0392 str += QStringLiteral(" Region: %1\n").arg(d->mRegion); 0393 str += QStringLiteral(" Postal code: %1\n").arg(d->mPostalCode); 0394 str += QStringLiteral(" Country: %1\n").arg(d->mCountry); 0395 str += QStringLiteral(" Label: %1\n").arg(d->mLabel); 0396 str += QStringLiteral(" Geo: %1\n").arg(d->mGeo.toString()); 0397 str += QLatin1String("}\n"); 0398 0399 return str; 0400 } 0401 0402 QString Address::formatted(AddressFormatStyle style, const QString &realName, const QString &orgaName) const 0403 { 0404 const auto formatPref = (orgaName.isEmpty() || style != AddressFormatStyle::Postal) ? AddressFormatPreference::Generic : AddressFormatPreference::Business; 0405 const auto format = AddressFormatRepository::formatForAddress(*this, formatPref); 0406 return AddressFormatter::format(*this, realName, orgaName, format, style); 0407 } 0408 0409 QString Address::formattedPostalAddress() const 0410 { 0411 return formatted(AddressFormatStyle::Postal); 0412 } 0413 0414 QUrl Address::geoUri() const 0415 { 0416 QUrl url; 0417 url.setScheme(QStringLiteral("geo")); 0418 0419 if (geo().isValid()) { 0420 url.setPath(QString::number(geo().latitude()) + QLatin1Char(',') + QString::number(geo().longitude())); 0421 return url; 0422 } 0423 0424 if (!isEmpty()) { 0425 url.setPath(QStringLiteral("0,0")); 0426 QUrlQuery query; 0427 query.addQueryItem(QStringLiteral("q"), formatted(KContacts::AddressFormatStyle::GeoUriQuery)); 0428 url.setQuery(query); 0429 return url; 0430 } 0431 0432 return {}; 0433 } 0434 0435 // clang-format off 0436 QDataStream &KContacts::operator<<(QDataStream &s, const Address &addr) 0437 { 0438 return s << addr.d->mId << (uint)addr.d->mType << addr.d->mPostOfficeBox 0439 << addr.d->mExtended << addr.d->mStreet << addr.d->mLocality 0440 << addr.d->mRegion << addr.d->mPostalCode << addr.d->mCountry 0441 << addr.d->mLabel << addr.d->mEmpty << addr.d->mGeo; 0442 } 0443 0444 QDataStream &KContacts::operator>>(QDataStream &s, Address &addr) 0445 { 0446 uint type; 0447 s >> addr.d->mId >> type >> addr.d->mPostOfficeBox >> addr.d->mExtended 0448 >> addr.d->mStreet >> addr.d->mLocality >> addr.d->mRegion 0449 >> addr.d->mPostalCode >> addr.d->mCountry >> addr.d->mLabel 0450 >> addr.d->mEmpty >> addr.d->mGeo; 0451 0452 addr.d->mType = Address::Type(type); 0453 0454 return s; 0455 } 0456 // clang-format on 0457 0458 #include "moc_address.cpp"