1 | /* |
2 | SPDX-FileCopyrightText: 2022 Volker Krause <vkrause@kde.org> |
3 | SPDX-License-Identifier: LGPL-2.0-or-later |
4 | */ |
5 | |
6 | #include "addressformat.h" |
7 | #include "address.h" |
8 | #include "addressformat_p.h" |
9 | #include "addressformatparser_p.h" |
10 | #include "addressformatscript_p.h" |
11 | |
12 | #include <KConfig> |
13 | #include <KConfigGroup> |
14 | #include <KCountry> |
15 | |
16 | #include <QDebug> |
17 | #include <QLocale> |
18 | |
19 | using namespace KContacts; |
20 | |
21 | AddressFormatElement::AddressFormatElement() |
22 | : d(new AddressFormatElementPrivate) |
23 | { |
24 | } |
25 | |
26 | AddressFormatElement::AddressFormatElement(const AddressFormatElement &) = default; |
27 | AddressFormatElement::~AddressFormatElement() = default; |
28 | AddressFormatElement &AddressFormatElement::operator=(const AddressFormatElement &) = default; |
29 | |
30 | bool AddressFormatElement::isField() const |
31 | { |
32 | return d->field != AddressFormatField::NoField; |
33 | } |
34 | |
35 | AddressFormatField AddressFormatElement::field() const |
36 | { |
37 | return d->field; |
38 | } |
39 | |
40 | bool AddressFormatElement::isLiteral() const |
41 | { |
42 | return !d->literal.isEmpty(); |
43 | } |
44 | |
45 | QString AddressFormatElement::literal() const |
46 | { |
47 | return d->literal; |
48 | } |
49 | |
50 | bool AddressFormatElement::isSeparator() const |
51 | { |
52 | return !isField() && !isLiteral(); |
53 | } |
54 | |
55 | AddressFormat::AddressFormat() |
56 | : d(new AddressFormatPrivate) |
57 | { |
58 | } |
59 | |
60 | AddressFormat::AddressFormat(const AddressFormat &) = default; |
61 | AddressFormat::~AddressFormat() = default; |
62 | AddressFormat &AddressFormat::operator=(const AddressFormat &) = default; |
63 | |
64 | const std::vector<AddressFormatElement> &AddressFormat::elements() const |
65 | { |
66 | return d->elements; |
67 | } |
68 | |
69 | AddressFormatFields AddressFormat::requiredFields() const |
70 | { |
71 | return d->required; |
72 | } |
73 | |
74 | AddressFormatFields AddressFormat::usedFields() const |
75 | { |
76 | return std::accumulate(first: d->elements.begin(), last: d->elements.end(), init: AddressFormatFields(AddressFormatField::NoField), binary_op: [](auto lhs, const auto &rhs) { |
77 | return lhs | rhs.field(); |
78 | }); |
79 | } |
80 | |
81 | AddressFormatFields AddressFormat::upperCaseFields() const |
82 | { |
83 | return d->upper; |
84 | } |
85 | |
86 | QString AddressFormat::postalCodeRegularExpression() const |
87 | { |
88 | return d->postalCodeFormat; |
89 | } |
90 | |
91 | QString AddressFormat::country() const |
92 | { |
93 | return d->country; |
94 | } |
95 | |
96 | QList<AddressFormatElement> AddressFormat::elementsForQml() const |
97 | { |
98 | QList<AddressFormatElement> l; |
99 | l.reserve(asize: d->elements.size()); |
100 | std::copy(first: d->elements.begin(), last: d->elements.end(), result: std::back_inserter(x&: l)); |
101 | return l; |
102 | } |
103 | |
104 | static QString addressFormatRc() |
105 | { |
106 | Q_INIT_RESOURCE(kcontacts); // must be called outside of a namespace |
107 | return QStringLiteral(":/org.kde.kcontacts/addressformatrc" ); |
108 | } |
109 | |
110 | AddressFormat |
111 | AddressFormatRepository::formatForCountry(const QString &countryCode, AddressFormatScriptPreference scriptPref, AddressFormatPreference formatPref) |
112 | { |
113 | static const KConfig entry(addressFormatRc(), KConfig::SimpleConfig); |
114 | KConfigGroup group = entry.group(group: countryCode); |
115 | |
116 | AddressFormat format; |
117 | auto fmt = AddressFormatPrivate::get(format); |
118 | fmt->required = AddressFormatParser::parseFields(s: group.readEntry(key: "Required" , aDefault: QString())); |
119 | fmt->upper = AddressFormatParser::parseFields(s: group.readEntry(key: "Upper" , aDefault: QString())); |
120 | |
121 | QString formatString; |
122 | if (scriptPref == AddressFormatScriptPreference::Latin && formatPref == AddressFormatPreference::Business) { |
123 | formatString = group.readEntry(key: "LatinBusinessAddressFormat" , aDefault: QString()); |
124 | } |
125 | if (formatString.isEmpty() && scriptPref == AddressFormatScriptPreference::Latin) { |
126 | formatString = group.readEntry(key: "LatinAddressFormat" , aDefault: QString()); |
127 | } |
128 | if (formatString.isEmpty() && formatPref == AddressFormatPreference::Business) { |
129 | formatString = group.readEntry(key: "BusinessAddressFormat" , aDefault: QString()); |
130 | } |
131 | if (formatString.isEmpty()) { |
132 | formatString = group.readEntry(key: "AddressFormat" , QStringLiteral("%N%n%O%n%A%nPO BOX %P%n%C %S %Z" )); |
133 | } |
134 | fmt->elements = AddressFormatParser::parseElements(s: formatString); |
135 | fmt->postalCodeFormat = group.readEntry(key: "PostalCodeFormat" , aDefault: QString()); |
136 | fmt->country = countryCode; |
137 | return format; |
138 | } |
139 | |
140 | AddressFormat AddressFormatRepository::formatForAddress(const Address &address, AddressFormatPreference formatPref) |
141 | { |
142 | KCountry c; |
143 | if (address.country().size() == 2) { |
144 | c = KCountry::fromAlpha2(alpha2Code: address.country()); |
145 | } |
146 | if (!c.isValid()) { |
147 | c = KCountry::fromName(name: address.country()); |
148 | } |
149 | // fall back to our own country |
150 | if (!c.isValid()) { |
151 | c = KCountry::fromQLocale(country: QLocale().territory()); |
152 | } |
153 | |
154 | const auto scriptPref = AddressFormatScript::detect(addr: address) == AddressFormatScript::LatinLikeScript ? AddressFormatScriptPreference::Latin |
155 | : AddressFormatScriptPreference::Local; |
156 | return formatForCountry(countryCode: c.alpha2(), scriptPref, formatPref); |
157 | } |
158 | |
159 | #include "moc_addressformat.cpp" |
160 | |