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
15using namespace KContacts;
16
17class Q_DECL_HIDDEN ResourceLocatorUrl::Private : public QSharedData
18{
19public:
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
35ResourceLocatorUrl::ResourceLocatorUrl()
36 : d(new Private)
37{
38}
39
40ResourceLocatorUrl::ResourceLocatorUrl(const ResourceLocatorUrl &other)
41 : d(other.d)
42{
43}
44
45ResourceLocatorUrl::~ResourceLocatorUrl()
46{
47}
48
49struct url_type_name {
50 const char *name;
51 ResourceLocatorUrl::Type type;
52};
53
54static 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
64ResourceLocatorUrl::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
83void 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
108bool 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
123void 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
155bool ResourceLocatorUrl::operator==(const ResourceLocatorUrl &other) const
156{
157 return (d->mParamMap == other.d->mParamMap) && (d->url == other.url());
158}
159
160bool ResourceLocatorUrl::operator!=(const ResourceLocatorUrl &other) const
161{
162 return !(other == *this);
163}
164
165ResourceLocatorUrl &ResourceLocatorUrl::operator=(const ResourceLocatorUrl &other)
166{
167 if (this != &other) {
168 d = other.d;
169 }
170
171 return *this;
172}
173
174QString 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
183void ResourceLocatorUrl::setParams(const ParameterMap &params)
184{
185 d->mParamMap = params;
186}
187
188ParameterMap ResourceLocatorUrl::params() const
189{
190 return d->mParamMap;
191}
192
193bool ResourceLocatorUrl::isValid() const
194{
195 return d->url.isValid();
196}
197
198void ResourceLocatorUrl::setUrl(const QUrl &url)
199{
200 d->url = url;
201}
202
203QUrl ResourceLocatorUrl::url() const
204{
205 return d->url;
206}
207
208QDataStream &KContacts::operator<<(QDataStream &s, const ResourceLocatorUrl &calUrl)
209{
210 return s << calUrl.d->mParamMap << calUrl.d->url;
211}
212
213QDataStream &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

source code of kcontacts/src/resourcelocatorurl.cpp