File indexing completed on 2024-04-21 14:54:35

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> &params)
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 &params)
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"