File indexing completed on 2024-05-19 04:59:02

0001 /* ============================================================
0002 * Falkon - Qt web browser
0003 * Copyright (C) 2010-2014  David Rosca <nowrep@gmail.com>
0004 *
0005 * This program is free software: you can redistribute it and/or modify
0006 * it under the terms of the GNU General Public License as published by
0007 * the Free Software Foundation, either version 3 of the License, or
0008 * (at your option) any later version.
0009 *
0010 * This program is distributed in the hope that it will be useful,
0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013 * GNU General Public License for more details.
0014 *
0015 * You should have received a copy of the GNU General Public License
0016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
0017 * ============================================================ */
0018 #include "thememanager.h"
0019 #include "ui_thememanager.h"
0020 #include "qztools.h"
0021 #include "settings.h"
0022 #include "datapaths.h"
0023 #include "licenseviewer.h"
0024 #include "preferences.h"
0025 #include "desktopfile.h"
0026 #include "mainapplication.h"
0027 
0028 #include <QDir>
0029 #include <QMessageBox>
0030 #include <QtCoreVersion>
0031 
0032 ThemeManager::ThemeManager(QWidget* parent, Preferences* preferences)
0033     : QWidget(parent)
0034     , ui(new Ui::ThemeManager)
0035     , m_preferences(preferences)
0036 {
0037     ui->setupUi(parent);
0038     ui->listWidget->setLayoutDirection(Qt::LeftToRight);
0039     ui->license->hide();
0040     ui->remove->setIcon(QIcon::fromTheme(QSL("edit-delete")));
0041 
0042     Settings settings;
0043     settings.beginGroup(QSL("Themes"));
0044     m_activeTheme = settings.value(QSL("activeTheme"), DEFAULT_THEME_NAME).toString();
0045     settings.endGroup();
0046 
0047     const QStringList themePaths = DataPaths::allPaths(DataPaths::Themes);
0048 
0049     for (const QString &path : themePaths) {
0050         QDir dir(path);
0051         const QStringList list = dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot);
0052         for (const QString &name : list) {
0053             Theme themeInfo = parseTheme(dir.absoluteFilePath(name) + QLatin1Char('/'), name);
0054             if (!themeInfo.isValid) {
0055                 continue;
0056             }
0057 
0058             auto* item = new QListWidgetItem(ui->listWidget);
0059             item->setText(themeInfo.name);
0060             item->setIcon(themeInfo.icon);
0061             item->setData(Qt::UserRole, name);
0062 
0063             if (m_activeTheme == name) {
0064                 ui->listWidget->setCurrentItem(item);
0065             }
0066 
0067             ui->listWidget->addItem(item);
0068         }
0069     }
0070 
0071     connect(ui->listWidget, &QListWidget::currentItemChanged, this, &ThemeManager::currentChanged);
0072     connect(ui->license, &ClickableLabel::clicked, this, &ThemeManager::showLicense);
0073     connect(ui->remove, &QPushButton::clicked, this, &ThemeManager::removeTheme);
0074 
0075     currentChanged();
0076 }
0077 
0078 void ThemeManager::showLicense()
0079 {
0080     QListWidgetItem* currentItem = ui->listWidget->currentItem();
0081     if (!currentItem) {
0082         return;
0083     }
0084 
0085     Theme currentTheme = m_themeHash[currentItem->data(Qt::UserRole).toString()];
0086 
0087     auto* v = new LicenseViewer(m_preferences);
0088     v->setText(currentTheme.license);
0089     v->show();
0090 }
0091 
0092 void ThemeManager::removeTheme()
0093 {
0094     QListWidgetItem* currentItem = ui->listWidget->currentItem();
0095     if (!currentItem) {
0096         return;
0097     }
0098     Theme currentTheme = m_themeHash[currentItem->data(Qt::UserRole).toString()];
0099 
0100     const auto button = QMessageBox::warning(this, tr("Confirmation"),
0101                                              tr("Are you sure you want to remove '%1'?").arg(currentTheme.name),
0102                                              QMessageBox::Yes | QMessageBox::No);
0103     if (button != QMessageBox::Yes) {
0104         return;
0105     }
0106 
0107     QDir(currentTheme.themePath).removeRecursively();
0108     delete currentItem;
0109 }
0110 
0111 void ThemeManager::currentChanged()
0112 {
0113     QListWidgetItem* currentItem = ui->listWidget->currentItem();
0114     if (!currentItem) {
0115         return;
0116     }
0117 
0118     Theme currentTheme = m_themeHash[currentItem->data(Qt::UserRole).toString()];
0119 
0120     ui->name->setText(currentTheme.name);
0121     ui->author->setText(currentTheme.author);
0122     ui->description->setText(currentTheme.description);
0123     ui->license->setHidden(currentTheme.license.isEmpty());
0124     ui->remove->setEnabled(QFileInfo(currentTheme.themePath).isWritable());
0125 }
0126 
0127 ThemeManager::Theme ThemeManager::parseTheme(const QString &path, const QString &name)
0128 {
0129     Theme info;
0130     info.isValid = false;
0131 
0132     if (!QFile(path + QStringLiteral("main.css")).exists() || !QFile(path + QSL("metadata.desktop")).exists()) {
0133         info.isValid = false;
0134         return info;
0135     }
0136 
0137     DesktopFile metadata(path + QSL("metadata.desktop"));
0138     info.name = metadata.name();
0139     info.description = metadata.comment();
0140     info.author = metadata.value(QSL("X-Falkon-Author")).toString();
0141     info.themePath = path.chopped(1);
0142 
0143     const QString iconName = metadata.icon();
0144     if (!iconName.isEmpty()) {
0145         if (QFileInfo::exists(path + iconName)) {
0146             info.icon = QIcon(path + iconName);
0147         } else {
0148             info.icon = QIcon::fromTheme(iconName);
0149         }
0150     }
0151 
0152     const QString licensePath = metadata.value(QSL("X-Falkon-License")).toString();
0153     if (!licensePath.isEmpty() && QFileInfo::exists(path + licensePath)) {
0154         info.license = QzTools::readAllFileContents(path + licensePath);
0155     }
0156 
0157     if (info.name.isEmpty() || m_themeHash.contains(name)) {
0158         return info;
0159     }
0160 
0161     info.isValid = true;
0162     m_themeHash.insert(name, info);
0163     return info;
0164 }
0165 
0166 void ThemeManager::save()
0167 {
0168     QListWidgetItem* currentItem = ui->listWidget->currentItem();
0169     if (!currentItem) {
0170         return;
0171     }
0172 
0173     Settings settings;
0174     settings.beginGroup(QSL("Themes"));
0175     settings.setValue(QSL("activeTheme"), currentItem->data(Qt::UserRole));
0176     settings.endGroup();
0177 }
0178 
0179 ThemeManager::~ThemeManager()
0180 {
0181     delete ui;
0182 }