From ceec70e014db629aa8ba3472839cc42781d73d4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Sun, 1 Mar 2015 22:20:57 +0100 Subject: [PATCH] GH-796 Icon theme loading workaround Replacing the Qt machinery with other Qt machinery under our control --- CMakeLists.txt | 9 +- MultiMC.cpp | 11 + MultiMC.h | 5 + depends/iconfix/CMakeLists.txt | 20 + depends/iconfix/internal/qhexstring_p.h | 100 ++++ depends/iconfix/internal/qiconloader.cpp | 688 +++++++++++++++++++++++ depends/iconfix/internal/qiconloader_p.h | 219 ++++++++ depends/iconfix/xdgicon.cpp | 152 +++++ depends/iconfix/xdgicon.h | 46 ++ gui/MainWindow.cpp | 295 +++++++++- gui/MainWindow.ui | 517 ----------------- gui/dialogs/AboutDialog.cpp | 2 +- gui/pages/InstanceSettingsPage.h | 3 +- gui/pages/LegacyJarModPage.h | 3 +- gui/pages/LegacyUpgradePage.h | 3 +- gui/pages/LogPage.h | 3 +- gui/pages/ModFolderPage.h | 3 +- gui/pages/NotesPage.h | 5 +- gui/pages/OtherLogsPage.h | 3 +- gui/pages/ScreenshotsPage.cpp | 3 +- gui/pages/ScreenshotsPage.h | 3 +- gui/pages/global/AccountListPage.h | 5 +- gui/pages/global/ExternalToolsPage.h | 5 +- gui/pages/global/JavaPage.h | 3 +- gui/pages/global/MinecraftPage.h | 3 +- gui/pages/global/MultiMCPage.cpp | 2 +- gui/pages/global/MultiMCPage.h | 3 +- gui/pages/global/ProxyPage.h | 3 +- gui/widgets/PageContainer.cpp | 3 +- gui/widgets/ServerStatus.cpp | 8 +- main.cpp | 2 +- 31 files changed, 1578 insertions(+), 552 deletions(-) create mode 100644 depends/iconfix/CMakeLists.txt create mode 100644 depends/iconfix/internal/qhexstring_p.h create mode 100644 depends/iconfix/internal/qiconloader.cpp create mode 100644 depends/iconfix/internal/qiconloader_p.h create mode 100644 depends/iconfix/xdgicon.cpp create mode 100644 depends/iconfix/xdgicon.h delete mode 100644 gui/MainWindow.ui diff --git a/CMakeLists.txt b/CMakeLists.txt index 69af0136c..fff6e61e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -254,6 +254,10 @@ add_subdirectory(mmc_updater) add_subdirectory(depends/LogicalGui) include_directories(${LOGICALGUI_INCLUDE_DIR}) +# Add the GUI -> Logic connection header +add_subdirectory(depends/iconfix) +include_directories(${ICONFIX_INCLUDE_DIR}) + ################################ FILES ################################ ######## Sources and headers ######## @@ -638,9 +642,6 @@ SET(MULTIMC_SOURCES ######## UIs ######## SET(MULTIMC_UIS - # Windows - gui/MainWindow.ui - # Option pages gui/pages/VersionPage.ui gui/pages/ModFolderPage.ui @@ -741,7 +742,7 @@ add_executable(MultiMC MACOSX_BUNDLE WIN32 main.cpp ${MULTIMC_RCS}) # Link target_link_libraries(MultiMC MultiMC_common) -target_link_libraries(MultiMC_common xz-embedded unpack200 libUtil LogicalGui ${QUAZIP_LIBRARIES} ${MultiMC_LINK_ADDITIONAL_LIBS}) +target_link_libraries(MultiMC_common xz-embedded unpack200 iconfix libUtil LogicalGui ${QUAZIP_LIBRARIES} ${MultiMC_LINK_ADDITIONAL_LIBS}) qt5_use_modules(MultiMC Core Widgets Network Xml Concurrent WebKitWidgets ${MultiMC_QT_ADDITIONAL_MODULES}) qt5_use_modules(MultiMC_common Core Widgets Network Xml Concurrent WebKitWidgets ${MultiMC_QT_ADDITIONAL_MODULES}) diff --git a/MultiMC.cpp b/MultiMC.cpp index d2a5e29b5..abb302250 100644 --- a/MultiMC.cpp +++ b/MultiMC.cpp @@ -39,6 +39,7 @@ #include "pathutils.h" #include "cmdutils.h" +#include #include "logic/settings/INISettingsObject.h" #include "logic/settings/Setting.h" #include "logger/QsLog.h" @@ -739,6 +740,16 @@ void MultiMC::installUpdates(const QString updateFilesDir, UpdateFlags flags) MMC->quit(); } +void MultiMC::setIconTheme(const QString& name) +{ + XdgIcon::setThemeName(name); +} + +QIcon MultiMC::getThemedIcon(const QString& name) +{ + return XdgIcon::fromTheme(name); +} + void MultiMC::onExit() { if (m_updateOnExitPath.size()) diff --git a/MultiMC.h b/MultiMC.h index dc63ea53a..bce8a53be 100644 --- a/MultiMC.h +++ b/MultiMC.h @@ -5,6 +5,7 @@ #include "logger/QsLog.h" #include "logger/QsLogDest.h" #include +#include class MinecraftVersionList; class LWJGLVersionList; @@ -72,6 +73,10 @@ public: std::shared_ptr icons(); + QIcon getThemedIcon(const QString& name); + + void setIconTheme(const QString& name); + Status status() { return m_status; diff --git a/depends/iconfix/CMakeLists.txt b/depends/iconfix/CMakeLists.txt new file mode 100644 index 000000000..53d8c28e8 --- /dev/null +++ b/depends/iconfix/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 2.8.11) +project(iconfix) + +find_package(Qt5Core REQUIRED QUIET) +find_package(Qt5Widgets REQUIRED QUIET) + +include_directories(${Qt5Core_INCLUDE_DIRS}) +include_directories(${Qt5Widgets_INCLUDE_DIRS}) + +set(ICONFIX_SOURCES +xdgicon.h +xdgicon.cpp +internal/qhexstring_p.h +internal/qiconloader.cpp +internal/qiconloader_p.h +) + +set(ICONFIX_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}" PARENT_SCOPE) +add_library(iconfix STATIC ${ICONFIX_SOURCES}) +qt5_use_modules(iconfix Core Widgets) diff --git a/depends/iconfix/internal/qhexstring_p.h b/depends/iconfix/internal/qhexstring_p.h new file mode 100644 index 000000000..f01b4cddb --- /dev/null +++ b/depends/iconfix/internal/qhexstring_p.h @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include + +#pragma once + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +// internal helper. Converts an integer value to an unique string token +template struct HexString +{ + inline HexString(const T t) : val(t) + { + } + + inline void write(QChar *&dest) const + { + const ushort hexChars[] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + const char *c = reinterpret_cast(&val); + for (uint i = 0; i < sizeof(T); ++i) + { + *dest++ = hexChars[*c & 0xf]; + *dest++ = hexChars[(*c & 0xf0) >> 4]; + ++c; + } + } + const T val; +}; + +// specialization to enable fast concatenating of our string tokens to a string +template struct QConcatenable> +{ + typedef HexString type; + enum + { + ExactSize = true + }; + static int size(const HexString &) + { + return sizeof(T) * 2; + } + static inline void appendTo(const HexString &str, QChar *&out) + { + str.write(out); + } + typedef QString ConvertTo; +}; diff --git a/depends/iconfix/internal/qiconloader.cpp b/depends/iconfix/internal/qiconloader.cpp new file mode 100644 index 000000000..b1195893e --- /dev/null +++ b/depends/iconfix/internal/qiconloader.cpp @@ -0,0 +1,688 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "qiconloader_p.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "qhexstring_p.h" + +namespace QtXdg +{ + +Q_GLOBAL_STATIC(QIconLoader, iconLoaderInstance) + +/* Theme to use in last resort, if the theme does not have the icon, neither the parents */ + +static QString fallbackTheme() +{ + return QString("hicolor"); +} + +QIconLoader::QIconLoader() : m_themeKey(1), m_supportsSvg(false), m_initialized(false) +{ +} + +// We lazily initialize the loader to make static icons +// work. Though we do not officially support this. + +static inline QString systemThemeName() +{ + return QIcon::themeName(); +} + +static inline QStringList systemIconSearchPaths() +{ + auto paths = QIcon::themeSearchPaths(); + paths.push_front(":/icons"); + return paths; +} + +void QIconLoader::ensureInitialized() +{ + if (!m_initialized) + { + m_initialized = true; + + Q_ASSERT(qApp); + + m_systemTheme = QIcon::themeName(); + + if (m_systemTheme.isEmpty()) + m_systemTheme = fallbackTheme(); + m_supportsSvg = true; + } +} + +QIconLoader *QIconLoader::instance() +{ + iconLoaderInstance()->ensureInitialized(); + return iconLoaderInstance(); +} + +// Queries the system theme and invalidates existing +// icons if the theme has changed. +void QIconLoader::updateSystemTheme() +{ + // Only change if this is not explicitly set by the user + if (m_userTheme.isEmpty()) + { + QString theme = systemThemeName(); + if (theme.isEmpty()) + theme = fallbackTheme(); + if (theme != m_systemTheme) + { + m_systemTheme = theme; + invalidateKey(); + } + } +} + +void QIconLoader::setThemeName(const QString &themeName) +{ + m_userTheme = themeName; + invalidateKey(); +} + +void QIconLoader::setThemeSearchPath(const QStringList &searchPaths) +{ + m_iconDirs = searchPaths; + themeList.clear(); + invalidateKey(); +} + +QStringList QIconLoader::themeSearchPaths() const +{ + if (m_iconDirs.isEmpty()) + { + m_iconDirs = systemIconSearchPaths(); + } + return m_iconDirs; +} + +QIconTheme::QIconTheme(const QString &themeName) : m_valid(false) +{ + QFile themeIndex; + + QStringList iconDirs = systemIconSearchPaths(); + for (int i = 0; i < iconDirs.size(); ++i) + { + QDir iconDir(iconDirs[i]); + QString themeDir = iconDir.path() + QLatin1Char('/') + themeName; + themeIndex.setFileName(themeDir + QLatin1String("/index.theme")); + if (themeIndex.exists()) + { + m_contentDir = themeDir; + m_valid = true; + + foreach (QString path, iconDirs) + { + if (QFileInfo(path).isDir()) + m_contentDirs.append(path + QLatin1Char('/') + themeName); + } + + break; + } + } + + // if there is no index file, abscond. + if (!themeIndex.exists()) + return; + + // otherwise continue reading index file + const QSettings indexReader(themeIndex.fileName(), QSettings::IniFormat); + QStringListIterator keyIterator(indexReader.allKeys()); + while (keyIterator.hasNext()) + { + const QString key = keyIterator.next(); + if (!key.endsWith(QLatin1String("/Size"))) + continue; + + // Note the QSettings ini-format does not accept + // slashes in key names, hence we have to cheat + int size = indexReader.value(key).toInt(); + if (!size) + continue; + + QString directoryKey = key.left(key.size() - 5); + QIconDirInfo dirInfo(directoryKey); + dirInfo.size = size; + QString type = + indexReader.value(directoryKey + QLatin1String("/Type")).toString(); + + if (type == QLatin1String("Fixed")) + dirInfo.type = QIconDirInfo::Fixed; + else if (type == QLatin1String("Scalable")) + dirInfo.type = QIconDirInfo::Scalable; + else + dirInfo.type = QIconDirInfo::Threshold; + + dirInfo.threshold = + indexReader.value(directoryKey + QLatin1String("/Threshold"), 2) + .toInt(); + + dirInfo.minSize = + indexReader.value(directoryKey + QLatin1String("/MinSize"), size) + .toInt(); + + dirInfo.maxSize = + indexReader.value(directoryKey + QLatin1String("/MaxSize"), size) + .toInt(); + m_keyList.append(dirInfo); + } + + // Parent themes provide fallbacks for missing icons + m_parents = indexReader.value(QLatin1String("Icon Theme/Inherits")).toStringList(); + m_parents.removeAll(QString()); + + // Ensure a default platform fallback for all themes + if (m_parents.isEmpty()) + { + const QString fallback = fallbackTheme(); + if (!fallback.isEmpty()) + m_parents.append(fallback); + } + + // Ensure that all themes fall back to hicolor + if (!m_parents.contains(QLatin1String("hicolor"))) + m_parents.append(QLatin1String("hicolor")); +} + +QThemeIconEntries QIconLoader::findIconHelper(const QString &themeName, const QString &iconName, + QStringList &visited) const +{ + QThemeIconEntries entries; + Q_ASSERT(!themeName.isEmpty()); + + QPixmap pixmap; + + // Used to protect against potential recursions + visited << themeName; + + QIconTheme theme = themeList.value(themeName); + if (!theme.isValid()) + { + theme = QIconTheme(themeName); + if (!theme.isValid()) + theme = QIconTheme(fallbackTheme()); + + themeList.insert(themeName, theme); + } + + QStringList contentDirs = theme.contentDirs(); + const QVector subDirs = theme.keyList(); + + const QString svgext(QLatin1String(".svg")); + const QString pngext(QLatin1String(".png")); + const QString xpmext(QLatin1String(".xpm")); + + // Add all relevant files + for (int i = 0; i < subDirs.size(); ++i) + { + const QIconDirInfo &dirInfo = subDirs.at(i); + QString subdir = dirInfo.path; + + foreach (QString contentDir, contentDirs) + { + QDir currentDir(contentDir + '/' + subdir); + + if (currentDir.exists(iconName + pngext)) + { + PixmapEntry *iconEntry = new PixmapEntry; + iconEntry->dir = dirInfo; + iconEntry->filename = currentDir.filePath(iconName + pngext); + // Notice we ensure that pixmap entries always come before + // scalable to preserve search order afterwards + entries.prepend(iconEntry); + } + else if (m_supportsSvg && currentDir.exists(iconName + svgext)) + { + ScalableEntry *iconEntry = new ScalableEntry; + iconEntry->dir = dirInfo; + iconEntry->filename = currentDir.filePath(iconName + svgext); + entries.append(iconEntry); + break; + } + else if (currentDir.exists(iconName + xpmext)) + { + PixmapEntry *iconEntry = new PixmapEntry; + iconEntry->dir = dirInfo; + iconEntry->filename = currentDir.filePath(iconName + xpmext); + // Notice we ensure that pixmap entries always come before + // scalable to preserve search order afterwards + entries.append(iconEntry); + break; + } + } + } + + if (entries.isEmpty()) + { + const QStringList parents = theme.parents(); + // Search recursively through inherited themes + for (int i = 0; i < parents.size(); ++i) + { + + const QString parentTheme = parents.at(i).trimmed(); + + if (!visited.contains(parentTheme)) // guard against recursion + entries = findIconHelper(parentTheme, iconName, visited); + + if (!entries.isEmpty()) // success + break; + } + } + +/********************************************************************* +Author: Kaitlin Rupert +Date: Aug 12, 2010 +Description: Make it so that the QIcon loader honors /usr/share/pixmaps + directory. This is a valid directory per the Freedesktop.org + icon theme specification. +Bug: https://bugreports.qt.nokia.com/browse/QTBUG-12874 + *********************************************************************/ +#ifdef Q_OS_LINUX + /* Freedesktop standard says to look in /usr/share/pixmaps last */ + if (entries.isEmpty()) + { + const QString pixmaps(QLatin1String("/usr/share/pixmaps")); + + QDir currentDir(pixmaps); + QIconDirInfo dirInfo(pixmaps); + if (currentDir.exists(iconName + pngext)) + { + PixmapEntry *iconEntry = new PixmapEntry; + iconEntry->dir = dirInfo; + iconEntry->filename = currentDir.filePath(iconName + pngext); + // Notice we ensure that pixmap entries always come before + // scalable to preserve search order afterwards + entries.prepend(iconEntry); + } + else if (m_supportsSvg && currentDir.exists(iconName + svgext)) + { + ScalableEntry *iconEntry = new ScalableEntry; + iconEntry->dir = dirInfo; + iconEntry->filename = currentDir.filePath(iconName + svgext); + entries.append(iconEntry); + } + else if (currentDir.exists(iconName + xpmext)) + { + PixmapEntry *iconEntry = new PixmapEntry; + iconEntry->dir = dirInfo; + iconEntry->filename = currentDir.filePath(iconName + xpmext); + // Notice we ensure that pixmap entries always come before + // scalable to preserve search order afterwards + entries.append(iconEntry); + } + } +#endif + + if (entries.isEmpty()) + { + // Search for unthemed icons in main dir of search paths + QStringList themeSearchPaths = QIcon::themeSearchPaths(); + foreach (QString contentDir, themeSearchPaths) + { + QDir currentDir(contentDir); + + if (currentDir.exists(iconName + pngext)) + { + PixmapEntry *iconEntry = new PixmapEntry; + iconEntry->filename = currentDir.filePath(iconName + pngext); + // Notice we ensure that pixmap entries always come before + // scalable to preserve search order afterwards + entries.prepend(iconEntry); + } + else if (m_supportsSvg && currentDir.exists(iconName + svgext)) + { + ScalableEntry *iconEntry = new ScalableEntry; + iconEntry->filename = currentDir.filePath(iconName + svgext); + entries.append(iconEntry); + break; + } + else if (currentDir.exists(iconName + xpmext)) + { + PixmapEntry *iconEntry = new PixmapEntry; + iconEntry->filename = currentDir.filePath(iconName + xpmext); + // Notice we ensure that pixmap entries always come before + // scalable to preserve search order afterwards + entries.append(iconEntry); + break; + } + } + } + return entries; +} + +QThemeIconEntries QIconLoader::loadIcon(const QString &name) const +{ + if (!themeName().isEmpty()) + { + QStringList visited; + return findIconHelper(themeName(), name, visited); + } + + return QThemeIconEntries(); +} + +// -------- Icon Loader Engine -------- // + +QIconLoaderEngineFixed::QIconLoaderEngineFixed(const QString &iconName) + : m_iconName(iconName), m_key(0) +{ +} + +QIconLoaderEngineFixed::~QIconLoaderEngineFixed() +{ + qDeleteAll(m_entries); +} + +QIconLoaderEngineFixed::QIconLoaderEngineFixed(const QIconLoaderEngineFixed &other) + : QIconEngine(other), m_iconName(other.m_iconName), m_key(0) +{ +} + +QIconEngine *QIconLoaderEngineFixed::clone() const +{ + return new QIconLoaderEngineFixed(*this); +} + +bool QIconLoaderEngineFixed::read(QDataStream &in) +{ + in >> m_iconName; + return true; +} + +bool QIconLoaderEngineFixed::write(QDataStream &out) const +{ + out << m_iconName; + return true; +} + +bool QIconLoaderEngineFixed::hasIcon() const +{ + return !(m_entries.isEmpty()); +} + +// Lazily load the icon +void QIconLoaderEngineFixed::ensureLoaded() +{ + if (!(QIconLoader::instance()->themeKey() == m_key)) + { + + qDeleteAll(m_entries); + + m_entries = QIconLoader::instance()->loadIcon(m_iconName); + m_key = QIconLoader::instance()->themeKey(); + } +} + +void QIconLoaderEngineFixed::paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, + QIcon::State state) +{ + QSize pixmapSize = rect.size(); +#if defined(Q_WS_MAC) + pixmapSize *= qt_mac_get_scalefactor(); +#endif + painter->drawPixmap(rect, pixmap(pixmapSize, mode, state)); +} + +/* + * This algorithm is defined by the freedesktop spec: + * http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html + */ +static bool directoryMatchesSize(const QIconDirInfo &dir, int iconsize) +{ + if (dir.type == QIconDirInfo::Fixed) + { + return dir.size == iconsize; + } + else if (dir.type == QIconDirInfo::Scalable) + { + return dir.size <= dir.maxSize && iconsize >= dir.minSize; + } + else if (dir.type == QIconDirInfo::Threshold) + { + return iconsize >= dir.size - dir.threshold && iconsize <= dir.size + dir.threshold; + } + + Q_ASSERT(1); // Not a valid value + return false; +} + +/* + * This algorithm is defined by the freedesktop spec: + * http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html + */ +static int directorySizeDistance(const QIconDirInfo &dir, int iconsize) +{ + if (dir.type == QIconDirInfo::Fixed) + { + return qAbs(dir.size - iconsize); + } + else if (dir.type == QIconDirInfo::Scalable) + { + if (iconsize < dir.minSize) + return dir.minSize - iconsize; + else if (iconsize > dir.maxSize) + return iconsize - dir.maxSize; + else + return 0; + } + else if (dir.type == QIconDirInfo::Threshold) + { + if (iconsize < dir.size - dir.threshold) + return dir.minSize - iconsize; + else if (iconsize > dir.size + dir.threshold) + return iconsize - dir.maxSize; + else + return 0; + } + + Q_ASSERT(1); // Not a valid value + return INT_MAX; +} + +QIconLoaderEngineEntry *QIconLoaderEngineFixed::entryForSize(const QSize &size) +{ + int iconsize = qMin(size.width(), size.height()); + + // Note that m_entries are sorted so that png-files + // come first + + const int numEntries = m_entries.size(); + + // Search for exact matches first + for (int i = 0; i < numEntries; ++i) + { + QIconLoaderEngineEntry *entry = m_entries.at(i); + if (directoryMatchesSize(entry->dir, iconsize)) + { + return entry; + } + } + + // Find the minimum distance icon + int minimalSize = INT_MAX; + QIconLoaderEngineEntry *closestMatch = 0; + for (int i = 0; i < numEntries; ++i) + { + QIconLoaderEngineEntry *entry = m_entries.at(i); + int distance = directorySizeDistance(entry->dir, iconsize); + if (distance < minimalSize) + { + minimalSize = distance; + closestMatch = entry; + } + } + return closestMatch; +} + +/* + * Returns the actual icon size. For scalable svg's this is equivalent + * to the requested size. Otherwise the closest match is returned but + * we can never return a bigger size than the requested size. + * + */ +QSize QIconLoaderEngineFixed::actualSize(const QSize &size, QIcon::Mode mode, + QIcon::State state) +{ + ensureLoaded(); + + QIconLoaderEngineEntry *entry = entryForSize(size); + if (entry) + { + const QIconDirInfo &dir = entry->dir; + if (dir.type == QIconDirInfo::Scalable) + return size; + else + { + int result = qMin(dir.size, qMin(size.width(), size.height())); + return QSize(result, result); + } + } + return QIconEngine::actualSize(size, mode, state); +} + +QPixmap PixmapEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) +{ + Q_UNUSED(state); + + // Ensure that basePixmap is lazily initialized before generating the + // key, otherwise the cache key is not unique + if (basePixmap.isNull()) + basePixmap.load(filename); + + QSize actualSize = basePixmap.size(); + if (!actualSize.isNull() && + (actualSize.width() > size.width() || actualSize.height() > size.height())) + actualSize.scale(size, Qt::KeepAspectRatio); + + QString key = QLatin1String("$qt_theme_") % HexString(basePixmap.cacheKey()) % + HexString(mode) % + HexString(QGuiApplication::palette().cacheKey()) % + HexString(actualSize.width()) % HexString(actualSize.height()); + + QPixmap cachedPixmap; + if (QPixmapCache::find(key, &cachedPixmap)) + { + return cachedPixmap; + } + else + { + if (basePixmap.size() != actualSize) + { + cachedPixmap = basePixmap.scaled(actualSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + } + else + { + cachedPixmap = basePixmap; + } + QPixmapCache::insert(key, cachedPixmap); + } + return cachedPixmap; +} + +QPixmap ScalableEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) +{ + if (svgIcon.isNull()) + { + svgIcon = QIcon(filename); + } + + // Simply reuse svg icon engine + return svgIcon.pixmap(size, mode, state); +} + +QPixmap QIconLoaderEngineFixed::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) +{ + ensureLoaded(); + + QIconLoaderEngineEntry *entry = entryForSize(size); + if (entry) + { + return entry->pixmap(size, mode, state); + } + + return QPixmap(); +} + +QString QIconLoaderEngineFixed::key() const +{ + return QLatin1String("QIconLoaderEngineFixed"); +} + +void QIconLoaderEngineFixed::virtual_hook(int id, void *data) +{ + ensureLoaded(); + + switch (id) + { + case QIconEngine::AvailableSizesHook: + { + QIconEngine::AvailableSizesArgument &arg = + *reinterpret_cast(data); + const int N = m_entries.size(); + QList sizes; + sizes.reserve(N); + + // Gets all sizes from the DirectoryInfo entries + for (int i = 0; i < N; ++i) + { + int size = m_entries.at(i)->dir.size; + sizes.append(QSize(size, size)); + } + arg.sizes.swap(sizes); // commit + } + break; + case QIconEngine::IconNameHook: + { + QString &name = *reinterpret_cast(data); + name = m_iconName; + } + break; + default: + QIconEngine::virtual_hook(id, data); + } +} + +} // QtXdg diff --git a/depends/iconfix/internal/qiconloader_p.h b/depends/iconfix/internal/qiconloader_p.h new file mode 100644 index 000000000..23880f8f5 --- /dev/null +++ b/depends/iconfix/internal/qiconloader_p.h @@ -0,0 +1,219 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#pragma once + +#include + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include +#include +#include +#include +#include + + +namespace QtXdg +{ + +class QIconLoader; + +struct QIconDirInfo +{ + enum Type + { + Fixed, + Scalable, + Threshold + }; + QIconDirInfo(const QString &_path = QString()) + : path(_path), size(0), maxSize(0), minSize(0), threshold(0), type(Threshold) + { + } + QString path; + short size; + short maxSize; + short minSize; + short threshold; + Type type : 4; +}; + +class QIconLoaderEngineEntry +{ +public: + virtual ~QIconLoaderEngineEntry() + { + } + virtual QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) = 0; + QString filename; + QIconDirInfo dir; + static int count; +}; + +struct ScalableEntry : public QIconLoaderEngineEntry +{ + QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) Q_DECL_OVERRIDE; + QIcon svgIcon; +}; + +struct PixmapEntry : public QIconLoaderEngineEntry +{ + QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) Q_DECL_OVERRIDE; + QPixmap basePixmap; +}; + +typedef QList QThemeIconEntries; + +// class QIconLoaderEngine : public QIconEngine +class QIconLoaderEngineFixed : public QIconEngine +{ +public: + QIconLoaderEngineFixed(const QString &iconName = QString()); + ~QIconLoaderEngineFixed(); + + void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state); + QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state); + QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state); + QIconEngine *clone() const; + bool read(QDataStream &in); + bool write(QDataStream &out) const; + +private: + QString key() const; + bool hasIcon() const; + void ensureLoaded(); + void virtual_hook(int id, void *data); + QIconLoaderEngineEntry *entryForSize(const QSize &size); + QIconLoaderEngineFixed(const QIconLoaderEngineFixed &other); + QThemeIconEntries m_entries; + QString m_iconName; + uint m_key; + + friend class QIconLoader; +}; + +class QIconTheme +{ +public: + QIconTheme(const QString &name); + QIconTheme() : m_valid(false) + { + } + QStringList parents() + { + return m_parents; + } + QVector keyList() + { + return m_keyList; + } + QString contentDir() + { + return m_contentDir; + } + QStringList contentDirs() + { + return m_contentDirs; + } + bool isValid() + { + return m_valid; + } + +private: + QString m_contentDir; + QStringList m_contentDirs; + QVector m_keyList; + QStringList m_parents; + bool m_valid; +}; + +class Q_GUI_EXPORT QIconLoader +{ +public: + QIconLoader(); + QThemeIconEntries loadIcon(const QString &iconName) const; + uint themeKey() const + { + return m_themeKey; + } + + QString themeName() const + { + return m_userTheme.isEmpty() ? m_systemTheme : m_userTheme; + } + void setThemeName(const QString &themeName); + QIconTheme theme() + { + return themeList.value(themeName()); + } + void setThemeSearchPath(const QStringList &searchPaths); + QStringList themeSearchPaths() const; + QIconDirInfo dirInfo(int dirindex); + static QIconLoader *instance(); + void updateSystemTheme(); + void invalidateKey() + { + m_themeKey++; + } + void ensureInitialized(); + +private: + QThemeIconEntries findIconHelper(const QString &themeName, const QString &iconName, + QStringList &visited) const; + uint m_themeKey; + bool m_supportsSvg; + bool m_initialized; + + mutable QString m_userTheme; + mutable QString m_systemTheme; + mutable QStringList m_iconDirs; + mutable QHash themeList; +}; + +} // QtXdg + +// Note: class template specialization of 'QTypeInfo' must occur at +// global scope +Q_DECLARE_TYPEINFO(QtXdg::QIconDirInfo, Q_MOVABLE_TYPE); diff --git a/depends/iconfix/xdgicon.cpp b/depends/iconfix/xdgicon.cpp new file mode 100644 index 000000000..a36d80a9a --- /dev/null +++ b/depends/iconfix/xdgicon.cpp @@ -0,0 +1,152 @@ +/* BEGIN_COMMON_COPYRIGHT_HEADER + * (c)LGPL2+ + * + * Razor - a lightweight, Qt based, desktop toolset + * http://razor-qt.org + * + * Copyright: 2010-2011 Razor team + * Authors: + * Alexander Sokoloff + * + * This program or library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * + * END_COMMON_COPYRIGHT_HEADER */ + +#include "xdgicon.h" + +#include +#include +#include +#include +#include +#include +#include "internal/qiconloader_p.h" +#include + +/************************************************ + + ************************************************/ +static void qt_cleanup_icon_cache(); +typedef QCache IconCache; + +namespace +{ +struct QtIconCache : public IconCache +{ + QtIconCache() + { + qAddPostRoutine(qt_cleanup_icon_cache); + } +}; +} +Q_GLOBAL_STATIC(IconCache, qtIconCache); + +static void qt_cleanup_icon_cache() +{ + qtIconCache()->clear(); +} + +/************************************************ + + ************************************************/ +XdgIcon::XdgIcon() +{ +} + +/************************************************ + + ************************************************/ +XdgIcon::~XdgIcon() +{ +} + +/************************************************ + Returns the name of the current icon theme. + ************************************************/ +QString XdgIcon::themeName() +{ + return QIcon::themeName(); +} + +/************************************************ + Sets the current icon theme to name. + ************************************************/ +void XdgIcon::setThemeName(const QString &themeName) +{ + QIcon::setThemeName(themeName); + QtXdg::QIconLoader::instance()->updateSystemTheme(); +} + +/************************************************ + Returns the QIcon corresponding to name in the current icon theme. If no such icon + is found in the current theme fallback is return instead. + ************************************************/ +QIcon XdgIcon::fromTheme(const QString &iconName, const QIcon &fallback) +{ + if (iconName.isEmpty()) + return fallback; + + bool isAbsolute = (iconName[0] == '/'); + + QString name = QFileInfo(iconName).fileName(); + if (name.endsWith(".png", Qt::CaseInsensitive) || + name.endsWith(".svg", Qt::CaseInsensitive) || + name.endsWith(".xpm", Qt::CaseInsensitive)) + { + name.truncate(name.length() - 4); + } + + QIcon icon; + + if (qtIconCache()->contains(name)) + { + icon = *qtIconCache()->object(name); + } + else + { + QIcon *cachedIcon; + if (!isAbsolute) + cachedIcon = new QIcon(new QtXdg::QIconLoaderEngineFixed(name)); + else + cachedIcon = new QIcon(iconName); + qtIconCache()->insert(name, cachedIcon); + icon = *cachedIcon; + } + + // Note the qapp check is to allow lazy loading of static icons + // Supporting fallbacks will not work for this case. + if (qApp && !isAbsolute && icon.availableSizes().isEmpty()) + { + return fallback; + } + return icon; +} + +/************************************************ + Returns the QIcon corresponding to names in the current icon theme. If no such icon + is found in the current theme fallback is return instead. + ************************************************/ +QIcon XdgIcon::fromTheme(const QStringList &iconNames, const QIcon &fallback) +{ + foreach (QString iconName, iconNames) + { + QIcon icon = fromTheme(iconName); + if (!icon.isNull()) + return icon; + } + + return fallback; +} diff --git a/depends/iconfix/xdgicon.h b/depends/iconfix/xdgicon.h new file mode 100644 index 000000000..9c11683a8 --- /dev/null +++ b/depends/iconfix/xdgicon.h @@ -0,0 +1,46 @@ +/* BEGIN_COMMON_COPYRIGHT_HEADER + * (c)LGPL2+ + * + * Razor - a lightweight, Qt based, desktop toolset + * http://razor-qt.org + * + * Copyright: 2010-2011 Razor team + * Authors: + * Alexander Sokoloff + * + * This program or library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * + * END_COMMON_COPYRIGHT_HEADER */ + +#pragma once + +#include +#include +#include + +class XdgIcon +{ +public: + static QIcon fromTheme(const QString &iconName, const QIcon &fallback = QIcon()); + static QIcon fromTheme(const QStringList &iconNames, const QIcon &fallback = QIcon()); + + static QString themeName(); + static void setThemeName(const QString &themeName); + +protected: + explicit XdgIcon(); + virtual ~XdgIcon(); +}; diff --git a/gui/MainWindow.cpp b/gui/MainWindow.cpp index fbb575a04..0231dd442 100644 --- a/gui/MainWindow.cpp +++ b/gui/MainWindow.cpp @@ -20,7 +20,292 @@ #include "BuildConfig.h" #include "MainWindow.h" -#include "ui_MainWindow.h" + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class Ui_MainWindow +{ +public: + QAction *actionAddInstance; + QAction *actionViewInstanceFolder; + QAction *actionRefresh; + QAction *actionViewCentralModsFolder; + QAction *actionCheckUpdate; + QAction *actionSettings; + QAction *actionReportBug; + QAction *actionPatreon; + QAction *actionMoreNews; + QAction *actionAbout; + QAction *actionLaunchInstance; + QAction *actionRenameInstance; + QAction *actionChangeInstGroup; + QAction *actionChangeInstIcon; + QAction *actionEditInstNotes; + QAction *actionEditInstance; + QAction *actionViewSelectedInstFolder; + QAction *actionDeleteInstance; + QAction *actionConfig_Folder; + QAction *actionCAT; + QAction *actionCopyInstance; + QAction *actionManageAccounts; + QAction *actionLaunchInstanceOffline; + QAction *actionScreenshots; + QAction *actionInstanceSettings; + QAction *actionExportInstance; + QWidget *centralWidget; + QHBoxLayout *horizontalLayout; + QToolBar *mainToolBar; + QStatusBar *statusBar; + QToolBar *instanceToolBar; + QToolBar *newsToolBar; + + void setupUi(QMainWindow *MainWindow) + { + if (MainWindow->objectName().isEmpty()) + { + MainWindow->setObjectName(QStringLiteral("MainWindow")); + } + MainWindow->resize(694, 563); + MainWindow->setWindowIcon(MMC->getThemedIcon("multimc")); + actionAddInstance = new QAction(MainWindow); + actionAddInstance->setObjectName(QStringLiteral("actionAddInstance")); + actionAddInstance->setIcon(MMC->getThemedIcon("new")); + actionViewInstanceFolder = new QAction(MainWindow); + actionViewInstanceFolder->setObjectName(QStringLiteral("actionViewInstanceFolder")); + actionViewInstanceFolder->setIcon(MMC->getThemedIcon("viewfolder")); + actionRefresh = new QAction(MainWindow); + actionRefresh->setObjectName(QStringLiteral("actionRefresh")); + actionRefresh->setIcon(MMC->getThemedIcon("refresh")); + actionViewCentralModsFolder = new QAction(MainWindow); + actionViewCentralModsFolder->setObjectName(QStringLiteral("actionViewCentralModsFolder")); + actionViewCentralModsFolder->setIcon(MMC->getThemedIcon("centralmods")); + actionCheckUpdate = new QAction(MainWindow); + actionCheckUpdate->setObjectName(QStringLiteral("actionCheckUpdate")); + actionCheckUpdate->setIcon(MMC->getThemedIcon("checkupdate")); + actionSettings = new QAction(MainWindow); + actionSettings->setObjectName(QStringLiteral("actionSettings")); + actionSettings->setIcon(MMC->getThemedIcon("settings")); + actionSettings->setMenuRole(QAction::PreferencesRole); + actionReportBug = new QAction(MainWindow); + actionReportBug->setObjectName(QStringLiteral("actionReportBug")); + actionReportBug->setIcon(MMC->getThemedIcon("bug")); + actionPatreon = new QAction(MainWindow); + actionPatreon->setObjectName(QStringLiteral("actionPatreon")); + actionPatreon->setIcon(MMC->getThemedIcon("patreon")); + actionMoreNews = new QAction(MainWindow); + actionMoreNews->setObjectName(QStringLiteral("actionMoreNews")); + actionMoreNews->setIcon(MMC->getThemedIcon("news")); + actionAbout = new QAction(MainWindow); + actionAbout->setObjectName(QStringLiteral("actionAbout")); + actionAbout->setIcon(MMC->getThemedIcon("about")); + actionAbout->setMenuRole(QAction::AboutRole); + actionLaunchInstance = new QAction(MainWindow); + actionLaunchInstance->setObjectName(QStringLiteral("actionLaunchInstance")); + actionRenameInstance = new QAction(MainWindow); + actionRenameInstance->setObjectName(QStringLiteral("actionRenameInstance")); + actionChangeInstGroup = new QAction(MainWindow); + actionChangeInstGroup->setObjectName(QStringLiteral("actionChangeInstGroup")); + actionChangeInstIcon = new QAction(MainWindow); + actionChangeInstIcon->setObjectName(QStringLiteral("actionChangeInstIcon")); + actionChangeInstIcon->setEnabled(true); + actionChangeInstIcon->setIcon(QIcon(":/icons/instances/infinity")); + actionChangeInstIcon->setIconVisibleInMenu(true); + actionEditInstNotes = new QAction(MainWindow); + actionEditInstNotes->setObjectName(QStringLiteral("actionEditInstNotes")); + actionEditInstance = new QAction(MainWindow); + actionEditInstance->setObjectName(QStringLiteral("actionEditInstance")); + actionViewSelectedInstFolder = new QAction(MainWindow); + actionViewSelectedInstFolder->setObjectName(QStringLiteral("actionViewSelectedInstFolder")); + actionDeleteInstance = new QAction(MainWindow); + actionDeleteInstance->setObjectName(QStringLiteral("actionDeleteInstance")); + actionConfig_Folder = new QAction(MainWindow); + actionConfig_Folder->setObjectName(QStringLiteral("actionConfig_Folder")); + actionCAT = new QAction(MainWindow); + actionCAT->setObjectName(QStringLiteral("actionCAT")); + actionCAT->setCheckable(true); + actionCAT->setIcon(MMC->getThemedIcon("cat")); + actionCopyInstance = new QAction(MainWindow); + actionCopyInstance->setObjectName(QStringLiteral("actionCopyInstance")); + actionCopyInstance->setIcon(MMC->getThemedIcon("copy")); + actionManageAccounts = new QAction(MainWindow); + actionManageAccounts->setObjectName(QStringLiteral("actionManageAccounts")); + actionLaunchInstanceOffline = new QAction(MainWindow); + actionLaunchInstanceOffline->setObjectName(QStringLiteral("actionLaunchInstanceOffline")); + actionScreenshots = new QAction(MainWindow); + actionScreenshots->setObjectName(QStringLiteral("actionScreenshots")); + actionInstanceSettings = new QAction(MainWindow); + actionInstanceSettings->setObjectName(QStringLiteral("actionInstanceSettings")); + actionExportInstance = new QAction(MainWindow); + actionExportInstance->setObjectName(QStringLiteral("actionExportInstance")); + centralWidget = new QWidget(MainWindow); + centralWidget->setObjectName(QStringLiteral("centralWidget")); + horizontalLayout = new QHBoxLayout(centralWidget); + horizontalLayout->setSpacing(0); + horizontalLayout->setContentsMargins(11, 11, 11, 11); + horizontalLayout->setObjectName(QStringLiteral("horizontalLayout")); + horizontalLayout->setSizeConstraint(QLayout::SetDefaultConstraint); + horizontalLayout->setContentsMargins(0, 0, 0, 0); + MainWindow->setCentralWidget(centralWidget); + mainToolBar = new QToolBar(MainWindow); + mainToolBar->setObjectName(QStringLiteral("mainToolBar")); + mainToolBar->setMovable(false); + mainToolBar->setAllowedAreas(Qt::TopToolBarArea); + mainToolBar->setToolButtonStyle(Qt::ToolButtonIconOnly); + mainToolBar->setFloatable(false); + MainWindow->addToolBar(Qt::TopToolBarArea, mainToolBar); + statusBar = new QStatusBar(MainWindow); + statusBar->setObjectName(QStringLiteral("statusBar")); + MainWindow->setStatusBar(statusBar); + instanceToolBar = new QToolBar(MainWindow); + instanceToolBar->setObjectName(QStringLiteral("instanceToolBar")); + instanceToolBar->setEnabled(true); + instanceToolBar->setAllowedAreas(Qt::LeftToolBarArea|Qt::RightToolBarArea); + instanceToolBar->setIconSize(QSize(80, 80)); + instanceToolBar->setToolButtonStyle(Qt::ToolButtonIconOnly); + instanceToolBar->setFloatable(false); + MainWindow->addToolBar(Qt::RightToolBarArea, instanceToolBar); + newsToolBar = new QToolBar(MainWindow); + newsToolBar->setObjectName(QStringLiteral("newsToolBar")); + newsToolBar->setMovable(false); + newsToolBar->setAllowedAreas(Qt::BottomToolBarArea); + newsToolBar->setIconSize(QSize(16, 16)); + newsToolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + newsToolBar->setFloatable(false); + MainWindow->addToolBar(Qt::BottomToolBarArea, newsToolBar); + + mainToolBar->addAction(actionAddInstance); + mainToolBar->addAction(actionCopyInstance); + mainToolBar->addSeparator(); + mainToolBar->addAction(actionViewInstanceFolder); + mainToolBar->addAction(actionViewCentralModsFolder); + mainToolBar->addAction(actionRefresh); + mainToolBar->addSeparator(); + mainToolBar->addAction(actionCheckUpdate); + mainToolBar->addAction(actionSettings); + mainToolBar->addSeparator(); + mainToolBar->addAction(actionReportBug); + mainToolBar->addAction(actionAbout); + mainToolBar->addSeparator(); + mainToolBar->addAction(actionPatreon); + mainToolBar->addAction(actionCAT); + instanceToolBar->addAction(actionChangeInstIcon); + instanceToolBar->addAction(actionLaunchInstance); + instanceToolBar->addAction(actionLaunchInstanceOffline); + instanceToolBar->addAction(actionChangeInstGroup); + instanceToolBar->addSeparator(); + instanceToolBar->addAction(actionEditInstance); + instanceToolBar->addAction(actionInstanceSettings); + instanceToolBar->addAction(actionEditInstNotes); + instanceToolBar->addAction(actionScreenshots); + instanceToolBar->addSeparator(); + instanceToolBar->addAction(actionViewSelectedInstFolder); + instanceToolBar->addAction(actionConfig_Folder); + instanceToolBar->addSeparator(); + instanceToolBar->addAction(actionExportInstance); + instanceToolBar->addAction(actionDeleteInstance); + newsToolBar->addAction(actionMoreNews); + + retranslateUi(MainWindow); + + QMetaObject::connectSlotsByName(MainWindow); + } // setupUi + + void retranslateUi(QMainWindow *MainWindow) + { + MainWindow->setWindowTitle(QApplication::translate("MainWindow", "MultiMC 5", 0)); + actionAddInstance->setText(QApplication::translate("MainWindow", "Add Instance", 0)); + actionAddInstance->setToolTip(QApplication::translate("MainWindow", "Add a new instance.", 0)); + actionAddInstance->setStatusTip(QApplication::translate("MainWindow", "Add a new instance.", 0)); + actionViewInstanceFolder->setText(QApplication::translate("MainWindow", "View Instance Folder", 0)); + actionViewInstanceFolder->setToolTip(QApplication::translate("MainWindow", "Open the instance folder in a file browser.", 0)); + actionViewInstanceFolder->setStatusTip(QApplication::translate("MainWindow", "Open the instance folder in a file browser.", 0)); + actionRefresh->setText(QApplication::translate("MainWindow", "Refresh", 0)); + actionRefresh->setToolTip(QApplication::translate("MainWindow", "Reload the instance list.", 0)); + actionRefresh->setStatusTip(QApplication::translate("MainWindow", "Reload the instance list.", 0)); + actionViewCentralModsFolder->setText(QApplication::translate("MainWindow", "View Central Mods Folder", 0)); + actionViewCentralModsFolder->setToolTip(QApplication::translate("MainWindow", "Open the central mods folder in a file browser.", 0)); + actionViewCentralModsFolder->setStatusTip(QApplication::translate("MainWindow", "Open the central mods folder in a file browser.", 0)); + actionCheckUpdate->setText(QApplication::translate("MainWindow", "Check for Updates", 0)); + actionCheckUpdate->setToolTip(QApplication::translate("MainWindow", "Check for new updates for MultiMC", 0)); + actionCheckUpdate->setStatusTip(QApplication::translate("MainWindow", "Check for new updates for MultiMC", 0)); + actionSettings->setText(QApplication::translate("MainWindow", "Settings", 0)); + actionSettings->setToolTip(QApplication::translate("MainWindow", "Change settings.", 0)); + actionSettings->setStatusTip(QApplication::translate("MainWindow", "Change settings.", 0)); + actionReportBug->setText(QApplication::translate("MainWindow", "Report a Bug", 0)); + actionReportBug->setToolTip(QApplication::translate("MainWindow", "Open the bug tracker to report a bug with MultiMC.", 0)); + actionReportBug->setStatusTip(QApplication::translate("MainWindow", "Open the bug tracker to report a bug with MultiMC.", 0)); + actionPatreon->setText(QApplication::translate("MainWindow", "Support us on Patreon!", 0)); + actionPatreon->setToolTip(QApplication::translate("MainWindow", "Open the MultiMC Patreon page.", 0)); + actionPatreon->setStatusTip(QApplication::translate("MainWindow", "Open the MultiMC Patreon page.", 0)); + actionMoreNews->setText(QApplication::translate("MainWindow", "More News", 0)); + actionMoreNews->setIconText(QApplication::translate("MainWindow", "More news...", 0)); + actionMoreNews->setToolTip(QApplication::translate("MainWindow", "Open the MultiMC development blog to read more news about MultiMC.", 0)); + actionMoreNews->setStatusTip(QApplication::translate("MainWindow", "Open the MultiMC development blog to read more news about MultiMC.", 0)); + actionAbout->setText(QApplication::translate("MainWindow", "About MultiMC", 0)); + actionAbout->setToolTip(QApplication::translate("MainWindow", "View information about MultiMC.", 0)); + actionAbout->setStatusTip(QApplication::translate("MainWindow", "About MultiMC", 0)); + actionLaunchInstance->setText(QApplication::translate("MainWindow", "Play", 0)); + actionLaunchInstance->setToolTip(QApplication::translate("MainWindow", "Launch the selected instance.", 0)); + actionLaunchInstance->setStatusTip(QApplication::translate("MainWindow", "Launch the selected instance.", 0)); + actionRenameInstance->setText(QApplication::translate("MainWindow", "Instance Name", 0)); + actionRenameInstance->setToolTip(QApplication::translate("MainWindow", "Rename the selected instance.", 0)); + actionRenameInstance->setStatusTip(QApplication::translate("MainWindow", "Rename the selected instance.", 0)); + actionChangeInstGroup->setText(QApplication::translate("MainWindow", "Change Group", 0)); + actionChangeInstGroup->setToolTip(QApplication::translate("MainWindow", "Change the selected instance's group.", 0)); + actionChangeInstGroup->setStatusTip(QApplication::translate("MainWindow", "Change the selected instance's group.", 0)); + actionChangeInstIcon->setText(QApplication::translate("MainWindow", "Change Icon", 0)); + actionChangeInstIcon->setToolTip(QApplication::translate("MainWindow", "Change the selected instance's icon.", 0)); + actionChangeInstIcon->setStatusTip(QApplication::translate("MainWindow", "Change the selected instance's icon.", 0)); + actionEditInstNotes->setText(QApplication::translate("MainWindow", "Edit Notes", 0)); + actionEditInstNotes->setToolTip(QApplication::translate("MainWindow", "Edit the notes for the selected instance.", 0)); + actionEditInstNotes->setStatusTip(QApplication::translate("MainWindow", "Edit the notes for the selected instance.", 0)); + actionEditInstance->setText(QApplication::translate("MainWindow", "Edit Instance", 0)); + actionEditInstance->setIconText(QApplication::translate("MainWindow", "Edit Instance", 0)); + actionEditInstance->setToolTip(QApplication::translate("MainWindow", "Change the instance settings, mods and versions.", 0)); + actionEditInstance->setStatusTip(QApplication::translate("MainWindow", "Change the instance settings, mods and versions.", 0)); + actionViewSelectedInstFolder->setText(QApplication::translate("MainWindow", "Instance Folder", 0)); + actionViewSelectedInstFolder->setToolTip(QApplication::translate("MainWindow", "Open the selected instance's root folder in a file browser.", 0)); + actionViewSelectedInstFolder->setStatusTip(QApplication::translate("MainWindow", "Open the selected instance's root folder in a file browser.", 0)); + actionDeleteInstance->setText(QApplication::translate("MainWindow", "Delete", 0)); + actionDeleteInstance->setToolTip(QApplication::translate("MainWindow", "Delete the selected instance.", 0)); + actionDeleteInstance->setStatusTip(QApplication::translate("MainWindow", "Delete the selected instance.", 0)); + actionConfig_Folder->setText(QApplication::translate("MainWindow", "Config Folder", 0)); + actionConfig_Folder->setToolTip(QApplication::translate("MainWindow", "Open the instance's config folder", 0)); + actionCAT->setText(QApplication::translate("MainWindow", "Meow", 0)); + actionCAT->setToolTip(QApplication::translate("MainWindow", "

It's a fluffy kitty :3

", 0)); + actionCopyInstance->setText(QApplication::translate("MainWindow", "Copy Instance", 0)); + actionCopyInstance->setToolTip(QApplication::translate("MainWindow", "Copy the selected instance.", 0)); + actionCopyInstance->setStatusTip(QApplication::translate("MainWindow", "Add a new instance.", 0)); + actionManageAccounts->setText(QApplication::translate("MainWindow", "Manage Accounts", 0)); + actionManageAccounts->setToolTip(QApplication::translate("MainWindow", "Manage your Mojang or Minecraft accounts.", 0)); + actionLaunchInstanceOffline->setText(QApplication::translate("MainWindow", "Play Offline", 0)); + actionLaunchInstanceOffline->setToolTip(QApplication::translate("MainWindow", "Launch the selected instance in offline mode.", 0)); + actionLaunchInstanceOffline->setStatusTip(QApplication::translate("MainWindow", "Launch the selected instance.", 0)); + actionScreenshots->setText(QApplication::translate("MainWindow", "Manage Screenshots", 0)); + actionScreenshots->setToolTip(QApplication::translate("MainWindow", "

View and upload screenshots for this instance

", 0)); + actionInstanceSettings->setText(QApplication::translate("MainWindow", "Instance Settings", 0)); + actionInstanceSettings->setToolTip(QApplication::translate("MainWindow", "Change the settings specific to the instance", 0)); + actionExportInstance->setText(QApplication::translate("MainWindow", "Export Instance", 0)); + mainToolBar->setWindowTitle(QApplication::translate("MainWindow", "Main Toolbar", 0)); + instanceToolBar->setWindowTitle(QApplication::translate("MainWindow", "Instance Toolbar", 0)); + newsToolBar->setWindowTitle(QApplication::translate("MainWindow", "News Toolbar", 0)); + } // retranslateUi + +}; + +namespace Ui { + class MainWindow: public Ui_MainWindow {}; +} // namespace Ui #include #include @@ -152,7 +437,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi // Add the news label to the news toolbar. { newsLabel = new QToolButton(); - newsLabel->setIcon(QIcon::fromTheme("news")); + newsLabel->setIcon(MMC->getThemedIcon("news")); newsLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); newsLabel->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); ui->newsToolBar->insertWidget(ui->actionMoreNews, newsLabel); @@ -248,7 +533,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi accountMenuButton->setMenu(accountMenu); accountMenuButton->setPopupMode(QToolButton::InstantPopup); accountMenuButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - accountMenuButton->setIcon(QIcon::fromTheme("noaccount")); + accountMenuButton->setIcon(MMC->getThemedIcon("noaccount")); QWidgetAction *accountMenuButtonAction = new QWidgetAction(this); accountMenuButtonAction->setDefaultWidget(accountMenuButton); @@ -514,7 +799,7 @@ void MainWindow::repopulateAccountsMenu() QAction *action = new QAction(tr("No Default Account"), this); action->setCheckable(true); - action->setIcon(QIcon::fromTheme("noaccount")); + action->setIcon(MMC->getThemedIcon("noaccount")); action->setData(""); if (active_username.isEmpty()) { @@ -568,7 +853,7 @@ void MainWindow::activeAccountChanged() } // Set the icon to the "no account" icon. - accountMenuButton->setIcon(QIcon::fromTheme("noaccount")); + accountMenuButton->setIcon(MMC->getThemedIcon("noaccount")); } bool MainWindow::eventFilter(QObject *obj, QEvent *ev) diff --git a/gui/MainWindow.ui b/gui/MainWindow.ui deleted file mode 100644 index 800862d13..000000000 --- a/gui/MainWindow.ui +++ /dev/null @@ -1,517 +0,0 @@ - - - MainWindow - - - - 0 - 0 - 694 - 563 - - - - MultiMC 5 - - - - - - - - 0 - - - QLayout::SetDefaultConstraint - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - Main Toolbar - - - false - - - Qt::TopToolBarArea - - - Qt::ToolButtonIconOnly - - - false - - - TopToolBarArea - - - false - - - - - - - - - - - - - - - - - - - - - true - - - Instance Toolbar - - - Qt::LeftToolBarArea|Qt::RightToolBarArea - - - - 80 - 80 - - - - Qt::ToolButtonIconOnly - - - false - - - RightToolBarArea - - - false - - - - - - - - - - - - - - - - - - - - News Toolbar - - - false - - - Qt::BottomToolBarArea - - - - 16 - 16 - - - - Qt::ToolButtonTextBesideIcon - - - false - - - BottomToolBarArea - - - false - - - - - - - - - - - Add Instance - - - Add a new instance. - - - Add a new instance. - - - - - - - - - - View Instance Folder - - - Open the instance folder in a file browser. - - - Open the instance folder in a file browser. - - - - - - - - - - Refresh - - - Reload the instance list. - - - Reload the instance list. - - - - - - - - - - View Central Mods Folder - - - Open the central mods folder in a file browser. - - - Open the central mods folder in a file browser. - - - - - - - - - - Check for Updates - - - Check for new updates for MultiMC - - - Check for new updates for MultiMC - - - - - - - - - - Settings - - - Change settings. - - - Change settings. - - - QAction::PreferencesRole - - - - - - - - - - Report a Bug - - - Open the bug tracker to report a bug with MultiMC. - - - Open the bug tracker to report a bug with MultiMC. - - - - - - - - - - Support us on Patreon! - - - Open the MultiMC Patreon page. - - - Open the MultiMC Patreon page. - - - - - - - - - - More News - - - More news... - - - Open the MultiMC development blog to read more news about MultiMC. - - - Open the MultiMC development blog to read more news about MultiMC. - - - - - - - - - - About MultiMC - - - View information about MultiMC. - - - About MultiMC - - - QAction::AboutRole - - - - - Play - - - Launch the selected instance. - - - Launch the selected instance. - - - - - Instance Name - - - Rename the selected instance. - - - Rename the selected instance. - - - - - Change Group - - - Change the selected instance's group. - - - Change the selected instance's group. - - - - - true - - - - :/icons/instances/infinity:/icons/instances/infinity - - - Change Icon - - - Change the selected instance's icon. - - - Change the selected instance's icon. - - - true - - - - - Edit Notes - - - Edit the notes for the selected instance. - - - Edit the notes for the selected instance. - - - - - Edit Instance - - - Edit Instance - - - Change the instance settings, mods and versions. - - - Change the instance settings, mods and versions. - - - - - Instance Folder - - - Open the selected instance's root folder in a file browser. - - - Open the selected instance's root folder in a file browser. - - - - - Delete - - - Delete the selected instance. - - - Delete the selected instance. - - - - - Config Folder - - - Open the instance's config folder - - - - - true - - - - - - - - Meow - - - <html><head/><body><p align="center">It's a fluffy kitty :3</p></body></html> - - - - - - - - - - Copy Instance - - - Copy the selected instance. - - - Add a new instance. - - - - - Manage Accounts - - - Manage your Mojang or Minecraft accounts. - - - - - Play Offline - - - Launch the selected instance in offline mode. - - - Launch the selected instance. - - - - - Manage Screenshots - - - <html><head/><body><p>View and upload screenshots for this instance</p></body></html> - - - - - Instance Settings - - - Change the settings specific to the instance - - - - - Export Instance - - - - - - - - - - - - - - - - diff --git a/gui/dialogs/AboutDialog.cpp b/gui/dialogs/AboutDialog.cpp index bacdc2fd5..6b31113c4 100644 --- a/gui/dialogs/AboutDialog.cpp +++ b/gui/dialogs/AboutDialog.cpp @@ -81,7 +81,7 @@ AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDia ui->urlLabel->setOpenExternalLinks(true); - ui->icon->setPixmap(QIcon::fromTheme("multimc").pixmap(64)); + ui->icon->setPixmap(MMC->getThemedIcon("multimc").pixmap(64)); ui->title->setText("MultiMC 5 " + BuildConfig.printableVersionString()); ui->versionLabel->setText(tr("Version") +": " + BuildConfig.printableVersionString()); diff --git a/gui/pages/InstanceSettingsPage.h b/gui/pages/InstanceSettingsPage.h index a95e65e42..b43ce610b 100644 --- a/gui/pages/InstanceSettingsPage.h +++ b/gui/pages/InstanceSettingsPage.h @@ -21,6 +21,7 @@ #include "logic/net/NetJob.h" #include "logic/java/JavaChecker.h" #include "BasePage.h" +#include "MultiMC.h" class JavaChecker; namespace Ui @@ -41,7 +42,7 @@ public: } virtual QIcon icon() const override { - return QIcon::fromTheme("instance-settings"); + return MMC->getThemedIcon("instance-settings"); } virtual QString id() const override { diff --git a/gui/pages/LegacyJarModPage.h b/gui/pages/LegacyJarModPage.h index cda6d2a01..e1ffd5d61 100644 --- a/gui/pages/LegacyJarModPage.h +++ b/gui/pages/LegacyJarModPage.h @@ -19,6 +19,7 @@ #include "logic/net/NetJob.h" #include "BasePage.h" +#include class ModList; class LegacyInstance; @@ -41,7 +42,7 @@ public: } virtual QIcon icon() const { - return QIcon::fromTheme("jarmods"); + return MMC->getThemedIcon("jarmods"); } virtual QString id() const { diff --git a/gui/pages/LegacyUpgradePage.h b/gui/pages/LegacyUpgradePage.h index 7a53c21ac..969b54404 100644 --- a/gui/pages/LegacyUpgradePage.h +++ b/gui/pages/LegacyUpgradePage.h @@ -20,6 +20,7 @@ #include "logic/OneSixInstance.h" #include "logic/net/NetJob.h" #include "BasePage.h" +#include class EnabledItemFilter; namespace Ui @@ -40,7 +41,7 @@ public: } virtual QIcon icon() const override { - return QIcon::fromTheme("checkupdate"); + return MMC->getThemedIcon("checkupdate"); } virtual QString id() const override { diff --git a/gui/pages/LogPage.h b/gui/pages/LogPage.h index c566528d7..7d073a53a 100644 --- a/gui/pages/LogPage.h +++ b/gui/pages/LogPage.h @@ -21,6 +21,7 @@ #include "logic/net/NetJob.h" #include "logic/MinecraftProcess.h" #include "BasePage.h" +#include class EnabledItemFilter; class MinecraftProcess; @@ -43,7 +44,7 @@ public: } virtual QIcon icon() const override { - return QIcon::fromTheme("log"); + return MMC->getThemedIcon("log"); } virtual QString id() const override { diff --git a/gui/pages/ModFolderPage.h b/gui/pages/ModFolderPage.h index 09f6adc7c..8859ad997 100644 --- a/gui/pages/ModFolderPage.h +++ b/gui/pages/ModFolderPage.h @@ -20,6 +20,7 @@ #include "logic/OneSixInstance.h" #include "logic/net/NetJob.h" #include "BasePage.h" +#include class EnabledItemFilter; class ModList; @@ -43,7 +44,7 @@ public: } virtual QIcon icon() const override { - return QIcon::fromTheme(m_iconName); + return MMC->getThemedIcon(m_iconName); } virtual QString id() const override { diff --git a/gui/pages/NotesPage.h b/gui/pages/NotesPage.h index bbe9d8567..f77ea5301 100644 --- a/gui/pages/NotesPage.h +++ b/gui/pages/NotesPage.h @@ -20,6 +20,7 @@ #include "logic/BaseInstance.h" #include "logic/net/NetJob.h" #include "BasePage.h" +#include class EnabledItemFilter; namespace Ui @@ -40,9 +41,9 @@ public: } virtual QIcon icon() const override { - auto icon = QIcon::fromTheme("notes"); + auto icon = MMC->getThemedIcon("notes"); if(icon.isNull()) - icon = QIcon::fromTheme("news"); + icon = MMC->getThemedIcon("news"); return icon; } virtual QString id() const override diff --git a/gui/pages/OtherLogsPage.h b/gui/pages/OtherLogsPage.h index 86844749d..5777cb83d 100644 --- a/gui/pages/OtherLogsPage.h +++ b/gui/pages/OtherLogsPage.h @@ -18,6 +18,7 @@ #include #include "BasePage.h" +#include namespace Ui { @@ -46,7 +47,7 @@ public: } QIcon icon() const override { - return QIcon::fromTheme("log"); + return MMC->getThemedIcon("log"); } QString helpPage() const override { diff --git a/gui/pages/ScreenshotsPage.cpp b/gui/pages/ScreenshotsPage.cpp index d47a28978..1771a1189 100644 --- a/gui/pages/ScreenshotsPage.cpp +++ b/gui/pages/ScreenshotsPage.cpp @@ -16,6 +16,7 @@ #include #include +#include #include "gui/dialogs/ProgressDialog.h" #include "gui/dialogs/CustomMessageBox.h" @@ -103,7 +104,7 @@ public: { m_thumbnailingPool.setMaxThreadCount(4); m_thumbnailCache = std::make_shared(); - m_thumbnailCache->add("placeholder", QIcon::fromTheme("screenshot-placeholder")); + m_thumbnailCache->add("placeholder", MMC->getThemedIcon("screenshot-placeholder")); connect(&watcher, SIGNAL(fileChanged(QString)), SLOT(fileChanged(QString))); // FIXME: the watched file set is not updated when files are removed } diff --git a/gui/pages/ScreenshotsPage.h b/gui/pages/ScreenshotsPage.h index ccf3856dd..6be2a26d6 100644 --- a/gui/pages/ScreenshotsPage.h +++ b/gui/pages/ScreenshotsPage.h @@ -19,6 +19,7 @@ #include "logic/OneSixInstance.h" #include "BasePage.h" +#include class QFileSystemModel; class QIdentityProxyModel; @@ -53,7 +54,7 @@ public: } virtual QIcon icon() const override { - return QIcon::fromTheme("screenshots"); + return MMC->getThemedIcon("screenshots"); } virtual QString id() const override { diff --git a/gui/pages/global/AccountListPage.h b/gui/pages/global/AccountListPage.h index 87f773d91..9fd894b8f 100644 --- a/gui/pages/global/AccountListPage.h +++ b/gui/pages/global/AccountListPage.h @@ -21,6 +21,7 @@ #include "gui/pages/BasePage.h" #include "logic/auth/MojangAccountList.h" +#include namespace Ui { @@ -42,10 +43,10 @@ public: } QIcon icon() const override { - auto icon = QIcon::fromTheme("accounts"); + auto icon = MMC->getThemedIcon("accounts"); if(icon.isNull()) { - icon = QIcon::fromTheme("noaccount"); + icon = MMC->getThemedIcon("noaccount"); } return icon; } diff --git a/gui/pages/global/ExternalToolsPage.h b/gui/pages/global/ExternalToolsPage.h index 79078fa35..7c5efad67 100644 --- a/gui/pages/global/ExternalToolsPage.h +++ b/gui/pages/global/ExternalToolsPage.h @@ -18,6 +18,7 @@ #include #include "gui/pages/BasePage.h" +#include namespace Ui { class ExternalToolsPage; @@ -37,10 +38,10 @@ public: } QIcon icon() const override { - auto icon = QIcon::fromTheme("externaltools"); + auto icon = MMC->getThemedIcon("externaltools"); if(icon.isNull()) { - icon = QIcon::fromTheme("loadermods"); + icon = MMC->getThemedIcon("loadermods"); } return icon; } diff --git a/gui/pages/global/JavaPage.h b/gui/pages/global/JavaPage.h index 779ca86d5..f70d9dbd9 100644 --- a/gui/pages/global/JavaPage.h +++ b/gui/pages/global/JavaPage.h @@ -20,6 +20,7 @@ #include "logic/java/JavaChecker.h" #include "gui/pages/BasePage.h" +#include class SettingsObject; @@ -42,7 +43,7 @@ public: } QIcon icon() const override { - return QIcon::fromTheme("java"); + return MMC->getThemedIcon("java"); } QString id() const override { diff --git a/gui/pages/global/MinecraftPage.h b/gui/pages/global/MinecraftPage.h index a47fd48ba..6dd86338c 100644 --- a/gui/pages/global/MinecraftPage.h +++ b/gui/pages/global/MinecraftPage.h @@ -20,6 +20,7 @@ #include "logic/java/JavaChecker.h" #include "gui/pages/BasePage.h" +#include class SettingsObject; @@ -42,7 +43,7 @@ public: } QIcon icon() const override { - return QIcon::fromTheme("minecraft"); + return MMC->getThemedIcon("minecraft"); } QString id() const override { diff --git a/gui/pages/global/MultiMCPage.cpp b/gui/pages/global/MultiMCPage.cpp index cc2b27810..cc923b2f6 100644 --- a/gui/pages/global/MultiMCPage.cpp +++ b/gui/pages/global/MultiMCPage.cpp @@ -302,7 +302,7 @@ void MultiMCPage::applySettings() if(original != s->get("IconTheme")) { - QIcon::setThemeName(s->get("IconTheme").toString()); + MMC->setIconTheme(s->get("IconTheme").toString()); } // Console settings diff --git a/gui/pages/global/MultiMCPage.h b/gui/pages/global/MultiMCPage.h index 1a6ad39ab..96e56f47a 100644 --- a/gui/pages/global/MultiMCPage.h +++ b/gui/pages/global/MultiMCPage.h @@ -20,6 +20,7 @@ #include "logic/java/JavaChecker.h" #include "gui/pages/BasePage.h" +#include class QTextCharFormat; class SettingsObject; @@ -43,7 +44,7 @@ public: } QIcon icon() const override { - return QIcon::fromTheme("multimc"); + return MMC->getThemedIcon("multimc"); } QString id() const override { diff --git a/gui/pages/global/ProxyPage.h b/gui/pages/global/ProxyPage.h index 014548dd6..edb7587a4 100644 --- a/gui/pages/global/ProxyPage.h +++ b/gui/pages/global/ProxyPage.h @@ -20,6 +20,7 @@ #include "logic/java/JavaChecker.h" #include "gui/pages/BasePage.h" +#include namespace Ui { @@ -40,7 +41,7 @@ public: } QIcon icon() const override { - return QIcon::fromTheme("proxy"); + return MMC->getThemedIcon("proxy"); } QString id() const override { diff --git a/gui/widgets/PageContainer.cpp b/gui/widgets/PageContainer.cpp index b84594c1f..59b800cc2 100644 --- a/gui/widgets/PageContainer.cpp +++ b/gui/widgets/PageContainer.cpp @@ -32,6 +32,7 @@ #include "gui/widgets/IconLabel.h" #include "gui/Platform.h" #include "PageContainer_p.h" +#include class PageEntryFilterModel : public QSortFilterProxyModel { @@ -174,7 +175,7 @@ void PageContainer::showPage(int row) { m_pageStack->setCurrentIndex(0); m_header->setText(QString()); - m_iconHeader->setIcon(QIcon::fromTheme("bug")); + m_iconHeader->setIcon(MMC->getThemedIcon("bug")); } } diff --git a/gui/widgets/ServerStatus.cpp b/gui/widgets/ServerStatus.cpp index 3b02fd244..93781e1c6 100644 --- a/gui/widgets/ServerStatus.cpp +++ b/gui/widgets/ServerStatus.cpp @@ -16,9 +16,9 @@ ServerStatus::ServerStatus(QWidget *parent, Qt::WindowFlags f) : QWidget(parent, { layout = new QHBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); - goodIcon = QIcon::fromTheme("status-good"); - yellowIcon = QIcon::fromTheme("status-yellow"); - badIcon = QIcon::fromTheme("status-bad"); + goodIcon = MMC->getThemedIcon("status-good"); + yellowIcon = MMC->getThemedIcon("status-yellow"); + badIcon = MMC->getThemedIcon("status-bad"); addStatus("minecraft.net", tr("Web")); addLine(); @@ -33,7 +33,7 @@ ServerStatus::ServerStatus(QWidget *parent, Qt::WindowFlags f) : QWidget(parent, m_statusRefresh = new QToolButton(this); m_statusRefresh->setCheckable(true); m_statusRefresh->setToolButtonStyle(Qt::ToolButtonIconOnly); - m_statusRefresh->setIcon(QIcon::fromTheme("refresh")); + m_statusRefresh->setIcon(MMC->getThemedIcon("refresh")); layout->addWidget(m_statusRefresh); setLayout(layout); diff --git a/main.cpp b/main.cpp index 1a474708a..ed35a9e89 100644 --- a/main.cpp +++ b/main.cpp @@ -4,7 +4,7 @@ int main_gui(MultiMC &app) { // show main window - QIcon::setThemeName(MMC->settings()->get("IconTheme").toString()); + app.setIconTheme(MMC->settings()->get("IconTheme").toString()); MainWindow mainWin; mainWin.restoreState(QByteArray::fromBase64(MMC->settings()->get("MainWindowState").toByteArray())); mainWin.restoreGeometry(QByteArray::fromBase64(MMC->settings()->get("MainWindowGeometry").toByteArray()));