From b56ab2189d3447d20fcab920710228ea5cd233d1 Mon Sep 17 00:00:00 2001 From: SulfurNitride Date: Sat, 27 Jun 2026 12:23:00 -0500 Subject: Restrict stylesheets to Fluorine install --- src/src/mainwindow.cpp | 11 ++------- src/src/moapplication.cpp | 43 ++++++++++++-------------------- src/src/settingsdialogtheme.cpp | 54 ++++++++++------------------------------- 3 files changed, 31 insertions(+), 77 deletions(-) (limited to 'src') diff --git a/src/src/mainwindow.cpp b/src/src/mainwindow.cpp index acdde48..e3cb1e4 100644 --- a/src/src/mainwindow.cpp +++ b/src/src/mainwindow.cpp @@ -2821,15 +2821,8 @@ void MainWindow::openPluginsFolder() void MainWindow::openStylesheetsFolder() { - // Open the instance's stylesheets directory (where custom themes from - // modlists live), or the user data dir as fallback. - QString ssPath; - if (auto ci = InstanceManager::singleton().currentInstance()) { - ssPath = - ci->directory() + "/" + QString::fromStdWString(AppConfig::stylesheetsPath()); - } else { - ssPath = fluorineDataDir() + "/stylesheets"; - } + const QString ssPath = QCoreApplication::applicationDirPath() + "/" + + QString::fromStdWString(AppConfig::stylesheetsPath()); QDir().mkpath(ssPath); shell::Explore(ssPath); } diff --git a/src/src/moapplication.cpp b/src/src/moapplication.cpp index eb6e46d..f09f746 100644 --- a/src/src/moapplication.cpp +++ b/src/src/moapplication.cpp @@ -721,42 +721,31 @@ bool MOApplication::setStyleFile(const QString& styleName) } // set new stylesheet or clear it if (styleName.length() != 0) { - // Search for the stylesheet in multiple locations: - // 1. applicationDirPath()/stylesheets/ — bundled themes - // 2. instance baseDir/stylesheets/ — instance/portable themes (modlists) - // 3. fluorineDataDir()/stylesheets/ — user-installed custom themes + // Stylesheets are application resources. Do not load copies supplied by an + // instance or from another user-writable search location. const QString ssSubdir = MOBase::ToQString(AppConfig::stylesheetsPath()); - QStringList searchDirs; - searchDirs << applicationDirPath() + "/" + ssSubdir; - if (m_instance) { - // Prefer baseDirectory() (populated after readFromIni), fall back to - // directory() which is always set by the constructor. - QString base = m_instance->baseDirectory(); - if (base.isEmpty()) - base = m_instance->directory(); - const QString instanceDir = base + "/" + ssSubdir; - if (!searchDirs.contains(instanceDir)) - searchDirs << instanceDir; - } - const QString userDir = fluorineDataDir() + "/stylesheets"; - if (!searchDirs.contains(userDir)) - searchDirs << userDir; - + const QString stylesheetDir = applicationDirPath() + "/" + ssSubdir; QString resolved; - for (const auto& dir : searchDirs) { - QString const candidate = dir + "/" + styleName; - if (QFile::exists(candidate)) { - resolved = candidate; - break; + if (QFileInfo(styleName).fileName() == styleName) { + const QString candidate = stylesheetDir + "/" + styleName; + const QString canonicalDir = QDir(stylesheetDir).canonicalPath(); + const QString canonicalFile = QFileInfo(candidate).canonicalFilePath(); + if (!canonicalDir.isEmpty() && + canonicalFile.startsWith(canonicalDir + "/") && + QFileInfo(canonicalFile).isFile()) { + resolved = canonicalFile; } } if (!resolved.isEmpty()) { m_styleWatcher.addPath(resolved); updateStyle(resolved); - } else { - // Could be a built-in Qt style name (e.g. "Fusion") + } else if (QStyleFactory::keys().contains(styleName)) { updateStyle(styleName); + } else { + log::warn("stylesheet '{}' is not installed in '{}'", styleName, + stylesheetDir); + return false; } } else { setStyle(new ProxyStyle(QStyleFactory::create(m_defaultStyle))); diff --git a/src/src/settingsdialogtheme.cpp b/src/src/settingsdialogtheme.cpp index 951e997..289f550 100644 --- a/src/src/settingsdialogtheme.cpp +++ b/src/src/settingsdialogtheme.cpp @@ -1,11 +1,9 @@ #include "settingsdialogtheme.h" #include "categoriesdialog.h" #include "colortable.h" -#include "instancemanager.h" #include "modlist.h" #include "shared/appconfig.h" #include "ui_settingsdialog.h" -#include "fluorinepaths.h" #include #include @@ -83,33 +81,14 @@ void ThemeSettingsTab::addStyles() ui->styleBox->insertSeparator(ui->styleBox->count()); - // Collect .qss files from all stylesheet search directories, deduplicating - // by filename so bundled themes aren't listed twice. - const QString ssSubdir = QString::fromStdWString(AppConfig::stylesheetsPath()); - QStringList searchDirs; - searchDirs << QCoreApplication::applicationDirPath() + "/" + ssSubdir; - if (auto ci = InstanceManager::singleton().currentInstance()) { - // currentInstance() returns a bare Instance (readFromIni() not called), - // so baseDirectory() is empty. Use directory() which is always set. - const QString instanceDir = ci->directory() + "/" + ssSubdir; - if (!searchDirs.contains(instanceDir)) - searchDirs << instanceDir; - } - const QString userDir = fluorineDataDir() + "/stylesheets"; - if (!searchDirs.contains(userDir)) - searchDirs << userDir; - - QSet seen; - for (const auto& dir : searchDirs) { - QDirIterator iter(dir, QStringList("*.qss"), QDir::Files); - while (iter.hasNext()) { - iter.next(); - const QString fileName = iter.fileName(); - if (seen.contains(fileName)) - continue; - seen.insert(fileName); - ui->styleBox->addItem(iter.fileInfo().completeBaseName(), fileName); - } + // Only expose stylesheets installed with Fluorine Manager. + const QString ssSubdir = QString::fromStdWString(AppConfig::stylesheetsPath()); + const QString stylesheetDir = + QCoreApplication::applicationDirPath() + "/" + ssSubdir; + QDirIterator iter(stylesheetDir, QStringList("*.qss"), QDir::Files); + while (iter.hasNext()) { + iter.next(); + ui->styleBox->addItem(iter.fileInfo().completeBaseName(), iter.fileName()); } } @@ -159,15 +138,8 @@ void ThemeSettingsTab::selectFontFamily() void ThemeSettingsTab::onExploreStyles() { - // Open the instance's stylesheets directory (where custom themes from - // modlists live), or the user data dir as fallback. - QString ssPath; - if (auto ci = InstanceManager::singleton().currentInstance()) { - ssPath = - ci->directory() + "/" + QString::fromStdWString(AppConfig::stylesheetsPath()); - } else { - ssPath = fluorineDataDir() + "/stylesheets"; - } - QDir().mkpath(ssPath); - shell::Explore(ssPath); -} + const QString ssPath = QCoreApplication::applicationDirPath() + "/" + + QString::fromStdWString(AppConfig::stylesheetsPath()); + QDir().mkpath(ssPath); + shell::Explore(ssPath); +} -- cgit v1.3.1