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

source code of kcontacts/src/resourcelocatorurl.cpp