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 }