1 | /* |
2 | This file is part of the KContacts framework. |
3 | SPDX-FileCopyrightText: 2015-2019 Laurent Montel <montel@kde.org> |
4 | |
5 | SPDX-License-Identifier: LGPL-2.0-or-later |
6 | */ |
7 | |
8 | #include "resourcelocatorurl.h" |
9 | |
10 | #include "parametermap_p.h" |
11 | |
12 | #include <QDataStream> |
13 | #include <QStringList> |
14 | |
15 | using namespace KContacts; |
16 | |
17 | class Q_DECL_HIDDEN ResourceLocatorUrl::Private : public QSharedData |
18 | { |
19 | public: |
20 | Private() |
21 | { |
22 | } |
23 | |
24 | Private(const Private &other) |
25 | : QSharedData(other) |
26 | { |
27 | mParamMap = other.mParamMap; |
28 | url = other.url; |
29 | } |
30 | |
31 | ParameterMap mParamMap; |
32 | QUrl url; |
33 | }; |
34 | |
35 | ResourceLocatorUrl::ResourceLocatorUrl() |
36 | : d(new Private) |
37 | { |
38 | } |
39 | |
40 | ResourceLocatorUrl::ResourceLocatorUrl(const ResourceLocatorUrl &other) |
41 | : d(other.d) |
42 | { |
43 | } |
44 | |
45 | ResourceLocatorUrl::~ResourceLocatorUrl() |
46 | { |
47 | } |
48 | |
49 | struct url_type_name { |
50 | const char *name; |
51 | ResourceLocatorUrl::Type type; |
52 | }; |
53 | |
54 | static const url_type_name url_type_names[] = { |
55 | {.name: "HOME" , .type: ResourceLocatorUrl::Home}, |
56 | {.name: "WORK" , .type: ResourceLocatorUrl::Work}, |
57 | {.name: "OTHER" , .type: ResourceLocatorUrl::Other}, |
58 | {.name: "PROFILE" , .type: ResourceLocatorUrl::Profile}, |
59 | {.name: "FTP" , .type: ResourceLocatorUrl::Ftp}, |
60 | {.name: "RESERVATION" , .type: ResourceLocatorUrl::Reservation}, |
61 | {.name: "APPINSTALLPAGE" , .type: ResourceLocatorUrl::AppInstallPage}, |
62 | }; |
63 | |
64 | ResourceLocatorUrl::Type ResourceLocatorUrl::type() const |
65 | { |
66 | const auto it = d->mParamMap.findParam(param: QLatin1String("type" )); |
67 | if (it == d->mParamMap.cend()) { |
68 | return Unknown; |
69 | } |
70 | |
71 | Type type = Unknown; |
72 | for (const QString &s : it->paramValues) { |
73 | const auto typeIt = std::find_if(first: std::begin(arr: url_type_names), last: std::end(arr: url_type_names), pred: [&s](const url_type_name &t) { |
74 | return QLatin1String(t.name) == s; |
75 | }); |
76 | if (typeIt != std::end(arr: url_type_names)) { |
77 | type |= (*typeIt).type; |
78 | } |
79 | } |
80 | return type; |
81 | } |
82 | |
83 | void ResourceLocatorUrl::setType(ResourceLocatorUrl::Type type) |
84 | { |
85 | const auto oldType = this->type(); |
86 | |
87 | const QString paramName(QStringLiteral("type" )); |
88 | |
89 | auto it = d->mParamMap.findParam(param: paramName); |
90 | if (it == d->mParamMap.end()) { |
91 | it = d->mParamMap.insertParam(newdata: {.param: QLatin1String("type" ), .paramValues: {}}); |
92 | } |
93 | |
94 | for (const auto &t : url_type_names) { |
95 | if (((type ^ oldType) & t.type) == 0) { |
96 | continue; // no change |
97 | } |
98 | |
99 | const QLatin1String str(t.name); |
100 | if (type & t.type) { |
101 | it->paramValues.push_back(t: str); |
102 | } else { |
103 | it->paramValues.removeAll(t: str); |
104 | } |
105 | } |
106 | } |
107 | |
108 | bool ResourceLocatorUrl::isPreferred() const |
109 | { |
110 | auto it = d->mParamMap.findParam(param: QLatin1String("pref" )); |
111 | if (it != d->mParamMap.cend()) { |
112 | return !it->paramValues.isEmpty() && it->paramValues.at(i: 0) == QLatin1Char('1'); |
113 | } |
114 | |
115 | it = d->mParamMap.findParam(param: QLatin1String("type" )); |
116 | if (it != d->mParamMap.cend()) { |
117 | return it->paramValues.contains(str: QLatin1String("PREF" ), cs: Qt::CaseInsensitive); |
118 | } |
119 | |
120 | return false; |
121 | } |
122 | |
123 | void ResourceLocatorUrl::setPreferred(bool preferred) |
124 | { |
125 | if (preferred == isPreferred()) { |
126 | return; |
127 | } |
128 | |
129 | const QString paramName(QStringLiteral("type" )); |
130 | |
131 | auto it = d->mParamMap.findParam(param: paramName); |
132 | QStringList types = it != d->mParamMap.end() ? it->paramValues : QStringList{}; |
133 | |
134 | const QLatin1String PREF_Str("PREF" ); |
135 | if (!preferred) { |
136 | auto prefIt = d->mParamMap.findParam(param: QLatin1String("pref" )); |
137 | if (prefIt != d->mParamMap.end()) { |
138 | d->mParamMap.erase(position: prefIt); |
139 | } |
140 | |
141 | types.removeAll(t: PREF_Str); |
142 | } else { |
143 | types.push_back(t: PREF_Str); |
144 | } |
145 | |
146 | // The above erase() call could have invalidated "it" |
147 | it = d->mParamMap.findParam(param: paramName); |
148 | if (it != d->mParamMap.end()) { |
149 | it->paramValues = types; |
150 | } else { |
151 | d->mParamMap.insertParam(newdata: {.param: QLatin1String("type" ), .paramValues: types}); |
152 | } |
153 | } |
154 | |
155 | bool ResourceLocatorUrl::operator==(const ResourceLocatorUrl &other) const |
156 | { |
157 | return (d->mParamMap == other.d->mParamMap) && (d->url == other.url()); |
158 | } |
159 | |
160 | bool ResourceLocatorUrl::operator!=(const ResourceLocatorUrl &other) const |
161 | { |
162 | return !(other == *this); |
163 | } |
164 | |
165 | ResourceLocatorUrl &ResourceLocatorUrl::operator=(const ResourceLocatorUrl &other) |
166 | { |
167 | if (this != &other) { |
168 | d = other.d; |
169 | } |
170 | |
171 | return *this; |
172 | } |
173 | |
174 | QString ResourceLocatorUrl::toString() const |
175 | { |
176 | QString str = QLatin1String("ResourceLocatorUrl {\n" ); |
177 | str += QStringLiteral(" url: %1\n" ).arg(a: d->url.toString()); |
178 | str += d->mParamMap.toString(); |
179 | str += QLatin1String("}\n" ); |
180 | return str; |
181 | } |
182 | |
183 | void ResourceLocatorUrl::setParams(const ParameterMap ¶ms) |
184 | { |
185 | d->mParamMap = params; |
186 | } |
187 | |
188 | ParameterMap ResourceLocatorUrl::params() const |
189 | { |
190 | return d->mParamMap; |
191 | } |
192 | |
193 | bool ResourceLocatorUrl::isValid() const |
194 | { |
195 | return d->url.isValid(); |
196 | } |
197 | |
198 | void ResourceLocatorUrl::setUrl(const QUrl &url) |
199 | { |
200 | d->url = url; |
201 | } |
202 | |
203 | QUrl ResourceLocatorUrl::url() const |
204 | { |
205 | return d->url; |
206 | } |
207 | |
208 | QDataStream &KContacts::operator<<(QDataStream &s, const ResourceLocatorUrl &calUrl) |
209 | { |
210 | return s << calUrl.d->mParamMap << calUrl.d->url; |
211 | } |
212 | |
213 | QDataStream &KContacts::operator>>(QDataStream &s, ResourceLocatorUrl &calUrl) |
214 | { |
215 | s >> calUrl.d->mParamMap >> calUrl.d->url; |
216 | return s; |
217 | } |
218 | |
219 | #include "moc_resourcelocatorurl.cpp" |
220 | |