File indexing completed on 2025-04-20 12:20:09
0001 /* 0002 This file is part of the KContacts framework. 0003 SPDX-FileCopyrightText: 2015-2019 Laurent Montel <montel@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "resourcelocatorurl.h" 0009 0010 #include "parametermap_p.h" 0011 0012 #include <QDataStream> 0013 #include <QStringList> 0014 0015 using namespace KContacts; 0016 0017 class Q_DECL_HIDDEN ResourceLocatorUrl::Private : public QSharedData 0018 { 0019 public: 0020 Private() 0021 { 0022 } 0023 0024 Private(const Private &other) 0025 : QSharedData(other) 0026 { 0027 mParamMap = other.mParamMap; 0028 url = other.url; 0029 } 0030 0031 ParameterMap mParamMap; 0032 QUrl url; 0033 }; 0034 0035 ResourceLocatorUrl::ResourceLocatorUrl() 0036 : d(new Private) 0037 { 0038 } 0039 0040 ResourceLocatorUrl::ResourceLocatorUrl(const ResourceLocatorUrl &other) 0041 : d(other.d) 0042 { 0043 } 0044 0045 ResourceLocatorUrl::~ResourceLocatorUrl() 0046 { 0047 } 0048 0049 struct url_type_name { 0050 const char *name; 0051 ResourceLocatorUrl::Type type; 0052 }; 0053 0054 static const url_type_name url_type_names[] = { 0055 {"HOME", ResourceLocatorUrl::Home}, 0056 {"WORK", ResourceLocatorUrl::Work}, 0057 {"OTHER", ResourceLocatorUrl::Other}, 0058 {"PROFILE", ResourceLocatorUrl::Profile}, 0059 }; 0060 0061 ResourceLocatorUrl::Type ResourceLocatorUrl::type() const 0062 { 0063 const auto it = d->mParamMap.findParam(QLatin1String("type")); 0064 if (it == d->mParamMap.cend()) { 0065 return Unknown; 0066 } 0067 0068 Type type = Unknown; 0069 for (const QString &s : it->paramValues) { 0070 const auto typeIt = std::find_if(std::begin(url_type_names), std::end(url_type_names), [&s](const url_type_name &t) { 0071 return QLatin1String(t.name) == s; 0072 }); 0073 if (typeIt != std::end(url_type_names)) { 0074 type |= (*typeIt).type; 0075 } 0076 } 0077 return type; 0078 } 0079 0080 void ResourceLocatorUrl::setType(ResourceLocatorUrl::Type type) 0081 { 0082 const auto oldType = this->type(); 0083 0084 const QString paramName(QStringLiteral("type")); 0085 0086 auto it = d->mParamMap.findParam(paramName); 0087 if (it == d->mParamMap.end()) { 0088 it = d->mParamMap.insertParam({QLatin1String("type"), {}}); 0089 } 0090 0091 for (const auto &t : url_type_names) { 0092 if (((type ^ oldType) & t.type) == 0) { 0093 continue; // no change 0094 } 0095 0096 const QLatin1String str(t.name); 0097 if (type & t.type) { 0098 it->paramValues.push_back(str); 0099 } else { 0100 it->paramValues.removeAll(str); 0101 } 0102 } 0103 } 0104 0105 bool ResourceLocatorUrl::isPreferred() const 0106 { 0107 auto it = d->mParamMap.findParam(QLatin1String("pref")); 0108 if (it != d->mParamMap.cend()) { 0109 return !it->paramValues.isEmpty() && it->paramValues.at(0) == QLatin1Char('1'); 0110 } 0111 0112 it = d->mParamMap.findParam(QLatin1String("type")); 0113 if (it != d->mParamMap.cend()) { 0114 return it->paramValues.contains(QLatin1String("PREF"), Qt::CaseInsensitive); 0115 } 0116 0117 return false; 0118 } 0119 0120 void ResourceLocatorUrl::setPreferred(bool preferred) 0121 { 0122 if (preferred == isPreferred()) { 0123 return; 0124 } 0125 0126 const QString paramName(QStringLiteral("type")); 0127 0128 auto it = d->mParamMap.findParam(paramName); 0129 QStringList types = it != d->mParamMap.end() ? it->paramValues : QStringList{}; 0130 0131 const QLatin1String PREF_Str("PREF"); 0132 if (!preferred) { 0133 auto prefIt = d->mParamMap.findParam(QLatin1String("pref")); 0134 if (prefIt != d->mParamMap.end()) { 0135 d->mParamMap.erase(prefIt); 0136 } 0137 0138 types.removeAll(PREF_Str); 0139 } else { 0140 types.push_back(PREF_Str); 0141 } 0142 0143 // The above erase() call could have invalidated "it" 0144 it = d->mParamMap.findParam(paramName); 0145 if (it != d->mParamMap.end()) { 0146 it->paramValues = types; 0147 } else { 0148 d->mParamMap.insertParam({QLatin1String("type"), types}); 0149 } 0150 } 0151 0152 bool ResourceLocatorUrl::operator==(const ResourceLocatorUrl &other) const 0153 { 0154 return (d->mParamMap == other.d->mParamMap) && (d->url == other.url()); 0155 } 0156 0157 bool ResourceLocatorUrl::operator!=(const ResourceLocatorUrl &other) const 0158 { 0159 return !(other == *this); 0160 } 0161 0162 ResourceLocatorUrl &ResourceLocatorUrl::operator=(const ResourceLocatorUrl &other) 0163 { 0164 if (this != &other) { 0165 d = other.d; 0166 } 0167 0168 return *this; 0169 } 0170 0171 QString ResourceLocatorUrl::toString() const 0172 { 0173 QString str = QLatin1String("ResourceLocatorUrl {\n"); 0174 str += QStringLiteral(" url: %1\n").arg(d->url.toString()); 0175 str += d->mParamMap.toString(); 0176 str += QLatin1String("}\n"); 0177 return str; 0178 } 0179 0180 #if KCONTACTS_BUILD_DEPRECATED_SINCE(5, 88) 0181 void ResourceLocatorUrl::setParameters(const QMap<QString, QStringList> ¶ms) 0182 { 0183 d->mParamMap = ParameterMap::fromQMap(params); 0184 } 0185 #endif 0186 0187 #if KCONTACTS_BUILD_DEPRECATED_SINCE(5, 88) 0188 QMap<QString, QStringList> ResourceLocatorUrl::parameters() const 0189 { 0190 return d->mParamMap.toQMap(); 0191 } 0192 #endif 0193 0194 void ResourceLocatorUrl::setParams(const ParameterMap ¶ms) 0195 { 0196 d->mParamMap = params; 0197 } 0198 0199 ParameterMap ResourceLocatorUrl::params() const 0200 { 0201 return d->mParamMap; 0202 } 0203 0204 bool ResourceLocatorUrl::isValid() const 0205 { 0206 return d->url.isValid(); 0207 } 0208 0209 void ResourceLocatorUrl::setUrl(const QUrl &url) 0210 { 0211 d->url = url; 0212 } 0213 0214 QUrl ResourceLocatorUrl::url() const 0215 { 0216 return d->url; 0217 } 0218 0219 QDataStream &KContacts::operator<<(QDataStream &s, const ResourceLocatorUrl &calUrl) 0220 { 0221 return s << calUrl.d->mParamMap << calUrl.d->url; 0222 } 0223 0224 QDataStream &KContacts::operator>>(QDataStream &s, ResourceLocatorUrl &calUrl) 0225 { 0226 s >> calUrl.d->mParamMap >> calUrl.d->url; 0227 return s; 0228 } 0229 0230 #include "moc_resourcelocatorurl.cpp"