File indexing completed on 2024-04-14 03:51:27

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