File indexing completed on 2025-01-19 03:39:53
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 {"FTP", ResourceLocatorUrl::Ftp}, 0060 {"RESERVATION", ResourceLocatorUrl::Reservation}, 0061 {"APPINSTALLPAGE", ResourceLocatorUrl::AppInstallPage}, 0062 }; 0063 0064 ResourceLocatorUrl::Type ResourceLocatorUrl::type() const 0065 { 0066 const auto it = d->mParamMap.findParam(QLatin1String("type")); 0067 if (it == d->mParamMap.cend()) { 0068 return Unknown; 0069 } 0070 0071 Type type = Unknown; 0072 for (const QString &s : it->paramValues) { 0073 const auto typeIt = std::find_if(std::begin(url_type_names), std::end(url_type_names), [&s](const url_type_name &t) { 0074 return QLatin1String(t.name) == s; 0075 }); 0076 if (typeIt != std::end(url_type_names)) { 0077 type |= (*typeIt).type; 0078 } 0079 } 0080 return type; 0081 } 0082 0083 void ResourceLocatorUrl::setType(ResourceLocatorUrl::Type type) 0084 { 0085 const auto oldType = this->type(); 0086 0087 const QString paramName(QStringLiteral("type")); 0088 0089 auto it = d->mParamMap.findParam(paramName); 0090 if (it == d->mParamMap.end()) { 0091 it = d->mParamMap.insertParam({QLatin1String("type"), {}}); 0092 } 0093 0094 for (const auto &t : url_type_names) { 0095 if (((type ^ oldType) & t.type) == 0) { 0096 continue; // no change 0097 } 0098 0099 const QLatin1String str(t.name); 0100 if (type & t.type) { 0101 it->paramValues.push_back(str); 0102 } else { 0103 it->paramValues.removeAll(str); 0104 } 0105 } 0106 } 0107 0108 bool ResourceLocatorUrl::isPreferred() const 0109 { 0110 auto it = d->mParamMap.findParam(QLatin1String("pref")); 0111 if (it != d->mParamMap.cend()) { 0112 return !it->paramValues.isEmpty() && it->paramValues.at(0) == QLatin1Char('1'); 0113 } 0114 0115 it = d->mParamMap.findParam(QLatin1String("type")); 0116 if (it != d->mParamMap.cend()) { 0117 return it->paramValues.contains(QLatin1String("PREF"), Qt::CaseInsensitive); 0118 } 0119 0120 return false; 0121 } 0122 0123 void ResourceLocatorUrl::setPreferred(bool preferred) 0124 { 0125 if (preferred == isPreferred()) { 0126 return; 0127 } 0128 0129 const QString paramName(QStringLiteral("type")); 0130 0131 auto it = d->mParamMap.findParam(paramName); 0132 QStringList types = it != d->mParamMap.end() ? it->paramValues : QStringList{}; 0133 0134 const QLatin1String PREF_Str("PREF"); 0135 if (!preferred) { 0136 auto prefIt = d->mParamMap.findParam(QLatin1String("pref")); 0137 if (prefIt != d->mParamMap.end()) { 0138 d->mParamMap.erase(prefIt); 0139 } 0140 0141 types.removeAll(PREF_Str); 0142 } else { 0143 types.push_back(PREF_Str); 0144 } 0145 0146 // The above erase() call could have invalidated "it" 0147 it = d->mParamMap.findParam(paramName); 0148 if (it != d->mParamMap.end()) { 0149 it->paramValues = types; 0150 } else { 0151 d->mParamMap.insertParam({QLatin1String("type"), types}); 0152 } 0153 } 0154 0155 bool ResourceLocatorUrl::operator==(const ResourceLocatorUrl &other) const 0156 { 0157 return (d->mParamMap == other.d->mParamMap) && (d->url == other.url()); 0158 } 0159 0160 bool ResourceLocatorUrl::operator!=(const ResourceLocatorUrl &other) const 0161 { 0162 return !(other == *this); 0163 } 0164 0165 ResourceLocatorUrl &ResourceLocatorUrl::operator=(const ResourceLocatorUrl &other) 0166 { 0167 if (this != &other) { 0168 d = other.d; 0169 } 0170 0171 return *this; 0172 } 0173 0174 QString ResourceLocatorUrl::toString() const 0175 { 0176 QString str = QLatin1String("ResourceLocatorUrl {\n"); 0177 str += QStringLiteral(" url: %1\n").arg(d->url.toString()); 0178 str += d->mParamMap.toString(); 0179 str += QLatin1String("}\n"); 0180 return str; 0181 } 0182 0183 void ResourceLocatorUrl::setParams(const ParameterMap ¶ms) 0184 { 0185 d->mParamMap = params; 0186 } 0187 0188 ParameterMap ResourceLocatorUrl::params() const 0189 { 0190 return d->mParamMap; 0191 } 0192 0193 bool ResourceLocatorUrl::isValid() const 0194 { 0195 return d->url.isValid(); 0196 } 0197 0198 void ResourceLocatorUrl::setUrl(const QUrl &url) 0199 { 0200 d->url = url; 0201 } 0202 0203 QUrl ResourceLocatorUrl::url() const 0204 { 0205 return d->url; 0206 } 0207 0208 QDataStream &KContacts::operator<<(QDataStream &s, const ResourceLocatorUrl &calUrl) 0209 { 0210 return s << calUrl.d->mParamMap << calUrl.d->url; 0211 } 0212 0213 QDataStream &KContacts::operator>>(QDataStream &s, ResourceLocatorUrl &calUrl) 0214 { 0215 s >> calUrl.d->mParamMap >> calUrl.d->url; 0216 return s; 0217 } 0218 0219 #include "moc_resourcelocatorurl.cpp"