File indexing completed on 2024-05-19 05:38:25

0001 /*
0002     SPDX-FileCopyrightText: 2020 Mikhail Zolotukhin <zomial@protonmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005 */
0006 
0007 #include <QDBusPendingCall>
0008 #include <QDir>
0009 #include <QStandardPaths>
0010 #include <QUrl>
0011 
0012 #include <KLocalizedString>
0013 #include <KTar>
0014 
0015 #include "gtkpage.h"
0016 
0017 GtkPage::GtkPage(QObject *parent)
0018     : QObject(parent)
0019     , m_gtkThemesModel(new GtkThemesModel(this))
0020     , m_gtkConfigInterface(QStringLiteral("org.kde.GtkConfig"), QStringLiteral("/GtkConfig"), QDBusConnection::sessionBus())
0021 {
0022     connect(m_gtkThemesModel, &GtkThemesModel::themeRemoved, this, &GtkPage::onThemeRemoved);
0023 
0024     connect(m_gtkThemesModel, &GtkThemesModel::selectedThemeChanged, this, [this]() {
0025         Q_EMIT gtkThemeSettingsChanged();
0026     });
0027 
0028     load();
0029 }
0030 
0031 GtkPage::~GtkPage() = default;
0032 
0033 bool GtkPage::gtkPreviewAvailable()
0034 {
0035     return !QStandardPaths::findExecutable(QStringLiteral("gtk3_preview"), {CMAKE_INSTALL_FULL_LIBEXECDIR}).isEmpty();
0036 }
0037 
0038 void GtkPage::showGtkPreview()
0039 {
0040     m_gtkConfigInterface.showGtkThemePreview(m_gtkThemesModel->selectedTheme());
0041 }
0042 
0043 void GtkPage::onThemeRemoved()
0044 {
0045     load();
0046     defaults();
0047     save();
0048 }
0049 
0050 void GtkPage::installGtkThemeFromFile(const QUrl &fileUrl)
0051 {
0052     QString themesInstallDirectoryPath(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/themes"));
0053     QDir::home().mkpath(themesInstallDirectoryPath);
0054     KTar themeArchive(fileUrl.path());
0055     themeArchive.open(QIODevice::ReadOnly);
0056 
0057     auto showError = [this, fileUrl]() {
0058         Q_EMIT showErrorMessage(i18n("%1 is not a valid GTK Theme archive.", fileUrl.fileName()));
0059     };
0060 
0061     QString firstEntryName = themeArchive.directory()->entries().first();
0062     const KArchiveEntry *possibleThemeDirectory = themeArchive.directory()->entry(firstEntryName);
0063     if (possibleThemeDirectory->isDirectory()) {
0064         const KArchiveDirectory *themeDirectory = static_cast<const KArchiveDirectory *>(possibleThemeDirectory);
0065         QStringList archiveSubitems = themeDirectory->entries();
0066 
0067         if (!archiveSubitems.contains(QStringLiteral("gtk-2.0")) && archiveSubitems.indexOf(QRegularExpression(QStringLiteral("gtk-3.*"))) == -1) {
0068             showError();
0069             return;
0070         }
0071     } else {
0072         showError();
0073         return;
0074     }
0075 
0076     themeArchive.directory()->copyTo(themesInstallDirectoryPath);
0077 
0078     load();
0079 }
0080 
0081 void GtkPage::save()
0082 {
0083     auto call = m_gtkConfigInterface.setGtkTheme(m_gtkThemesModel->selectedTheme());
0084     // needs to block so "OK" button closing kcmshell still saves properly
0085     call.waitForFinished();
0086 }
0087 
0088 void GtkPage::defaults()
0089 {
0090     m_gtkThemesModel->setSelectedTheme(QStringLiteral("Breeze"));
0091 }
0092 
0093 void GtkPage::load()
0094 {
0095     m_gtkThemesModel->load();
0096     m_gtkThemesModel->setSelectedTheme(m_gtkConfigInterface.gtkTheme());
0097 }
0098 
0099 bool GtkPage::isDefaults() const
0100 {
0101     return m_gtkThemesModel->selectedTheme() == QLatin1String("Breeze");
0102 }
0103 
0104 bool GtkPage::isSaveNeeded()
0105 {
0106     return m_gtkThemesModel->selectedTheme() != m_gtkConfigInterface.gtkTheme();
0107 }