File indexing completed on 2024-05-12 17:07:10

0001 /*
0002     SPDX-FileCopyrightText: 2020 Kevin Ottens <kevin.ottens@enioka.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "desktoppathssettings.h"
0008 
0009 #include <KBookmark>
0010 #include <KFilePlacesModel>
0011 #include <KLocalizedString>
0012 
0013 #include <QDir>
0014 
0015 namespace
0016 {
0017 // save in XDG user-dirs.dirs config file, this is where KGlobalSettings/QDesktopServices reads from.
0018 KSharedConfig::Ptr userDirsConfig()
0019 {
0020     const QString userDirsFilePath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QStringLiteral("/user-dirs.dirs");
0021     return KSharedConfig::openConfig(userDirsFilePath, KConfig::SimpleConfig);
0022 }
0023 }
0024 
0025 class XdgPathsSettingsStore : public QObject
0026 {
0027     Q_OBJECT
0028     Q_PROPERTY(QUrl desktopLocation READ desktopLocation WRITE setDesktopLocation)
0029     Q_PROPERTY(QUrl documentsLocation READ documentsLocation WRITE setDocumentsLocation)
0030     Q_PROPERTY(QUrl downloadsLocation READ downloadsLocation WRITE setDownloadsLocation)
0031     Q_PROPERTY(QUrl musicLocation READ musicLocation WRITE setMusicLocation)
0032     Q_PROPERTY(QUrl picturesLocation READ picturesLocation WRITE setPicturesLocation)
0033     Q_PROPERTY(QUrl videosLocation READ videosLocation WRITE setVideosLocation)
0034     Q_PROPERTY(QUrl publicLocation READ publicLocation WRITE setPublicLocation)
0035     Q_PROPERTY(QUrl templatesLocation READ templatesLocation WRITE setTemplatesLocation)
0036 public:
0037     XdgPathsSettingsStore(DesktopPathsSettings *parent = nullptr)
0038         : QObject(parent)
0039         , m_settings(parent)
0040     {
0041     }
0042 
0043     QUrl desktopLocation() const
0044     {
0045         return readUrl(QStringLiteral("XDG_DESKTOP_DIR"), m_settings->defaultDesktopLocation());
0046     }
0047 
0048     void setDesktopLocation(const QUrl &url)
0049     {
0050         writeUrl(QStringLiteral("XDG_DESKTOP_DIR"), url);
0051     }
0052 
0053     QUrl documentsLocation() const
0054     {
0055         return readUrl(QStringLiteral("XDG_DOCUMENTS_DIR"), m_settings->defaultDocumentsLocation());
0056     }
0057 
0058     void setDocumentsLocation(const QUrl &url)
0059     {
0060         writeUrl(QStringLiteral("XDG_DOCUMENTS_DIR"), url);
0061     }
0062 
0063     QUrl downloadsLocation() const
0064     {
0065         return readUrl(QStringLiteral("XDG_DOWNLOAD_DIR"), m_settings->defaultDownloadsLocation());
0066     }
0067 
0068     void setDownloadsLocation(const QUrl &url)
0069     {
0070         writeUrl(QStringLiteral("XDG_DOWNLOAD_DIR"), url);
0071     }
0072 
0073     QUrl musicLocation() const
0074     {
0075         return readUrl(QStringLiteral("XDG_MUSIC_DIR"), m_settings->defaultMusicLocation());
0076     }
0077 
0078     void setMusicLocation(const QUrl &url)
0079     {
0080         writeUrl(QStringLiteral("XDG_MUSIC_DIR"), url);
0081     }
0082 
0083     QUrl picturesLocation() const
0084     {
0085         return readUrl(QStringLiteral("XDG_PICTURES_DIR"), m_settings->defaultPicturesLocation());
0086     }
0087 
0088     void setPicturesLocation(const QUrl &url)
0089     {
0090         writeUrl(QStringLiteral("XDG_PICTURES_DIR"), url);
0091     }
0092 
0093     QUrl videosLocation() const
0094     {
0095         return readUrl(QStringLiteral("XDG_VIDEOS_DIR"), m_settings->defaultVideosLocation());
0096     }
0097 
0098     void setVideosLocation(const QUrl &url)
0099     {
0100         writeUrl(QStringLiteral("XDG_VIDEOS_DIR"), url);
0101     }
0102 
0103     QUrl publicLocation() const
0104     {
0105         return readUrl(QStringLiteral("XDG_PUBLICSHARE_DIR"), m_settings->defaultPublicLocation());
0106     }
0107 
0108     void setPublicLocation(const QUrl &url)
0109     {
0110         writeUrl(QStringLiteral("XDG_PUBLICSHARE_DIR"), url);
0111     }
0112 
0113     QUrl templatesLocation() const
0114     {
0115         return readUrl(QStringLiteral("XDG_TEMPLATES_DIR"), m_settings->defaultTemplatesLocation());
0116     }
0117 
0118     void setTemplatesLocation(const QUrl &url)
0119     {
0120         writeUrl(QStringLiteral("XDG_TEMPLATES_DIR"), url);
0121     }
0122 
0123 private:
0124     QUrl readUrl(const QString &key, const QUrl &defaultValue) const
0125     {
0126         KConfigGroup group(m_settings->config(), QString());
0127         const auto path = group.readPathEntry(key, QString());
0128         if (path.isEmpty()) {
0129             return defaultValue;
0130         } else {
0131             return QUrl::fromLocalFile(path.mid(1, path.length() - 2));
0132         }
0133     }
0134 
0135     void writeUrl(const QString &key, const QUrl &url)
0136     {
0137         const auto oldUrl = readUrl(key, QUrl());
0138 
0139         KConfigGroup group(m_settings->config(), QString());
0140         // HACK to benefit from path translation (thus unexpanding $HOME)
0141         group.writePathEntry(key, url.toLocalFile());
0142         const auto path = group.readEntryUntranslated(key, QString());
0143         group.writeEntry(key, QString(QStringLiteral("\"") + path + QStringLiteral("\"")));
0144 
0145         if (oldUrl.isValid() && oldUrl != url) {
0146             KFilePlacesModel placesModel;
0147 
0148             const auto &bookmark = placesModel.bookmarkForUrl(oldUrl);
0149             if (bookmark.isNull()) {
0150                 return;
0151             }
0152             const auto &matchedPlaces = placesModel.match(placesModel.index(0, 0), KFilePlacesModel::UrlRole, oldUrl, 1, Qt::MatchFixedString);
0153             if (matchedPlaces.count() == 1) {
0154                 placesModel.editPlace(matchedPlaces.at(0), url.fileName(), url, bookmark.icon(), bookmark.metaDataItem(QStringLiteral("OnlyInApp")));
0155             }
0156         }
0157     }
0158 
0159     DesktopPathsSettings *const m_settings;
0160 };
0161 
0162 DesktopPathsSettings::DesktopPathsSettings(QObject *parent)
0163     : KCoreConfigSkeleton(userDirsConfig(), parent)
0164     , m_xdgPathsStore(new XdgPathsSettingsStore(this))
0165 {
0166     addItemInternal("desktopLocation", defaultDesktopLocation());
0167     addItemInternal("documentsLocation", defaultDocumentsLocation());
0168     addItemInternal("downloadsLocation", defaultDownloadsLocation());
0169     addItemInternal("musicLocation", defaultMusicLocation());
0170     addItemInternal("picturesLocation", defaultPicturesLocation());
0171     addItemInternal("videosLocation", defaultVideosLocation());
0172     addItemInternal("publicLocation", defaultPublicLocation());
0173     addItemInternal("templatesLocation", defaultTemplatesLocation());
0174 }
0175 
0176 void DesktopPathsSettings::addItemInternal(const QByteArray &propertyName, const QVariant &defaultValue)
0177 {
0178     auto *item = new KPropertySkeletonItem(m_xdgPathsStore, propertyName, defaultValue);
0179     item->setNotifyFunction([this] {
0180         Q_EMIT this->widgetChanged();
0181     });
0182     addItem(item, propertyName);
0183 }
0184 
0185 QUrl DesktopPathsSettings::desktopLocation() const
0186 {
0187     return findItem("desktopLocation")->property().toUrl();
0188 }
0189 
0190 void DesktopPathsSettings::setDesktopLocation(const QUrl &url)
0191 {
0192     findItem("desktopLocation")->setProperty(url);
0193 }
0194 
0195 QUrl DesktopPathsSettings::defaultDesktopLocation() const
0196 {
0197     return QUrl::fromLocalFile(QDir::homePath() + QLatin1Char('/') + i18nd("xdg-user-dirs", "Desktop"));
0198 }
0199 
0200 QUrl DesktopPathsSettings::documentsLocation() const
0201 {
0202     return findItem("documentsLocation")->property().toUrl();
0203 }
0204 
0205 void DesktopPathsSettings::setDocumentsLocation(const QUrl &url)
0206 {
0207     findItem("documentsLocation")->setProperty(url);
0208 }
0209 
0210 QUrl DesktopPathsSettings::defaultDocumentsLocation() const
0211 {
0212     return QUrl::fromLocalFile(QDir::homePath() + QLatin1Char('/') + i18nd("xdg-user-dirs", "Documents"));
0213 }
0214 
0215 QUrl DesktopPathsSettings::downloadsLocation() const
0216 {
0217     return findItem("downloadsLocation")->property().toUrl();
0218 }
0219 
0220 void DesktopPathsSettings::setDownloadsLocation(const QUrl &url)
0221 {
0222     findItem("downloadsLocation")->setProperty(url);
0223 }
0224 
0225 QUrl DesktopPathsSettings::defaultDownloadsLocation() const
0226 {
0227     return QUrl::fromLocalFile(QDir::homePath() + QLatin1Char('/') + i18nd("xdg-user-dirs", "Downloads"));
0228 }
0229 
0230 QUrl DesktopPathsSettings::musicLocation() const
0231 {
0232     return findItem("musicLocation")->property().toUrl();
0233 }
0234 
0235 void DesktopPathsSettings::setMusicLocation(const QUrl &url)
0236 {
0237     findItem("musicLocation")->setProperty(url);
0238 }
0239 
0240 QUrl DesktopPathsSettings::defaultMusicLocation() const
0241 {
0242     return QUrl::fromLocalFile(QDir::homePath() + QLatin1Char('/') + i18nd("xdg-user-dirs", "Music"));
0243 }
0244 
0245 QUrl DesktopPathsSettings::picturesLocation() const
0246 {
0247     return findItem("picturesLocation")->property().toUrl();
0248 }
0249 
0250 void DesktopPathsSettings::setPicturesLocation(const QUrl &url)
0251 {
0252     findItem("picturesLocation")->setProperty(url);
0253 }
0254 
0255 QUrl DesktopPathsSettings::defaultPicturesLocation() const
0256 {
0257     return QUrl::fromLocalFile(QDir::homePath() + QLatin1Char('/') + i18nd("xdg-user-dirs", "Pictures"));
0258 }
0259 
0260 QUrl DesktopPathsSettings::videosLocation() const
0261 {
0262     return findItem("videosLocation")->property().toUrl();
0263 }
0264 
0265 void DesktopPathsSettings::setVideosLocation(const QUrl &url)
0266 {
0267     findItem("videosLocation")->setProperty(url);
0268 }
0269 
0270 QUrl DesktopPathsSettings::defaultVideosLocation() const
0271 {
0272     return QUrl::fromLocalFile(QDir::homePath() + QLatin1Char('/') + i18nd("xdg-user-dirs", "Videos"));
0273 }
0274 
0275 QUrl DesktopPathsSettings::publicLocation() const
0276 {
0277     return findItem("publicLocation")->property().toUrl();
0278 }
0279 
0280 void DesktopPathsSettings::setPublicLocation(const QUrl &url)
0281 {
0282     findItem("publicLocation")->setProperty(url);
0283 }
0284 
0285 QUrl DesktopPathsSettings::defaultPublicLocation() const
0286 {
0287     return QUrl::fromLocalFile(QDir::homePath() + QLatin1Char('/') + i18nd("xdg-user-dirs", "Public"));
0288 }
0289 
0290 QUrl DesktopPathsSettings::templatesLocation() const
0291 {
0292     return findItem("templatesLocation")->property().toUrl();
0293 }
0294 
0295 void DesktopPathsSettings::setTemplatesLocation(const QUrl &url)
0296 {
0297     findItem("templatesLocation")->setProperty(url);
0298 }
0299 
0300 QUrl DesktopPathsSettings::defaultTemplatesLocation() const
0301 {
0302     return QUrl::fromLocalFile(QDir::homePath() + QLatin1Char('/') + i18nd("xdg-user-dirs", "Templates"));
0303 }
0304 
0305 #include "desktoppathssettings.moc"