Bundle icons using the Qt resource system.
Simplify resource loading logic and enable reproducible builds. Fixes #2582
This commit is contained in:
committed by
Jonathan White
parent
4ff781fa48
commit
b045160e4f
@@ -70,6 +70,7 @@ namespace Bootstrap
|
||||
#ifdef QT_NO_DEBUG
|
||||
disableCoreDumps();
|
||||
#endif
|
||||
|
||||
setupSearchPaths();
|
||||
applyEarlyQNetworkAccessManagerWorkaround();
|
||||
Translator::installTranslators();
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
#include "DatabaseIcons.h"
|
||||
|
||||
#include "core/FilePath.h"
|
||||
#include "core/Resources.h"
|
||||
|
||||
DatabaseIcons* DatabaseIcons::m_instance(nullptr);
|
||||
const int DatabaseIcons::IconCount(69);
|
||||
@@ -103,18 +103,15 @@ QImage DatabaseIcons::icon(int index)
|
||||
{
|
||||
if (index < 0 || index >= IconCount) {
|
||||
qWarning("DatabaseIcons::icon: invalid icon index %d", index);
|
||||
return QImage();
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!m_iconCache[index].isNull()) {
|
||||
return m_iconCache[index];
|
||||
} else {
|
||||
QString iconPath = QString("icons/database/").append(m_indexToName[index]);
|
||||
QImage icon(filePath()->dataPath(iconPath));
|
||||
|
||||
m_iconCache[index] = icon;
|
||||
return icon;
|
||||
}
|
||||
QImage icon(QStringLiteral(":/icons/database/").append(m_indexToName[index]));
|
||||
m_iconCache[index] = icon;
|
||||
return icon;
|
||||
}
|
||||
|
||||
QPixmap DatabaseIcons::iconPixmap(int index)
|
||||
|
||||
@@ -1,259 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
* Copyright (C) 2011 Felix Geyer <debfx@fobos.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 or (at your option)
|
||||
* version 3 of the License.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "FilePath.h"
|
||||
|
||||
#include <QBitmap>
|
||||
#include <QDir>
|
||||
#include <QLibrary>
|
||||
#include <QStyle>
|
||||
|
||||
#include "config-keepassx.h"
|
||||
#include "core/Config.h"
|
||||
#include "core/Global.h"
|
||||
#include "gui/MainWindow.h"
|
||||
|
||||
FilePath* FilePath::m_instance(nullptr);
|
||||
|
||||
QString FilePath::dataPath(const QString& name)
|
||||
{
|
||||
if (name.isEmpty() || name.startsWith('/')) {
|
||||
return m_dataPath + name;
|
||||
} else {
|
||||
return m_dataPath + "/" + name;
|
||||
}
|
||||
}
|
||||
|
||||
QString FilePath::pluginPath(const QString& name)
|
||||
{
|
||||
QStringList pluginPaths;
|
||||
|
||||
QDir buildDir(QCoreApplication::applicationDirPath() + "/autotype");
|
||||
const QStringList buildDirEntryList = buildDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
|
||||
for (const QString& dir : buildDirEntryList) {
|
||||
pluginPaths << QCoreApplication::applicationDirPath() + "/autotype/" + dir;
|
||||
}
|
||||
|
||||
// for TestAutoType
|
||||
pluginPaths << QCoreApplication::applicationDirPath() + "/../src/autotype/test";
|
||||
|
||||
#if defined(Q_OS_MACOS) && defined(WITH_APP_BUNDLE)
|
||||
pluginPaths << QCoreApplication::applicationDirPath() + "/../PlugIns";
|
||||
#endif
|
||||
|
||||
pluginPaths << QCoreApplication::applicationDirPath();
|
||||
|
||||
QString configuredPluginDir = KEEPASSX_PLUGIN_DIR;
|
||||
if (configuredPluginDir != ".") {
|
||||
if (QDir(configuredPluginDir).isAbsolute()) {
|
||||
pluginPaths << configuredPluginDir;
|
||||
} else {
|
||||
QString relativePluginDir =
|
||||
QString("%1/../%2").arg(QCoreApplication::applicationDirPath(), configuredPluginDir);
|
||||
pluginPaths << QDir(relativePluginDir).canonicalPath();
|
||||
|
||||
QString absolutePluginDir = QString("%1/%2").arg(KEEPASSX_PREFIX_DIR, configuredPluginDir);
|
||||
pluginPaths << QDir(absolutePluginDir).canonicalPath();
|
||||
}
|
||||
}
|
||||
|
||||
QStringList dirFilter;
|
||||
dirFilter << QString("*%1*").arg(name);
|
||||
|
||||
for (const QString& path : asConst(pluginPaths)) {
|
||||
const QStringList fileCandidates = QDir(path).entryList(dirFilter, QDir::Files);
|
||||
|
||||
for (const QString& file : fileCandidates) {
|
||||
QString filePath = path + "/" + file;
|
||||
|
||||
if (QLibrary::isLibrary(filePath)) {
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString FilePath::wordlistPath(const QString& name)
|
||||
{
|
||||
return dataPath("wordlists/" + name);
|
||||
}
|
||||
|
||||
QIcon FilePath::applicationIcon()
|
||||
{
|
||||
return icon("apps", "keepassxc", false);
|
||||
}
|
||||
|
||||
QIcon FilePath::trayIcon()
|
||||
{
|
||||
return useDarkIcon() ? icon("apps", "keepassxc-dark", false) : icon("apps", "keepassxc", false);
|
||||
}
|
||||
|
||||
QIcon FilePath::trayIconLocked()
|
||||
{
|
||||
return icon("apps", "keepassxc-locked", false);
|
||||
}
|
||||
|
||||
QIcon FilePath::trayIconUnlocked()
|
||||
{
|
||||
return useDarkIcon() ? icon("apps", "keepassxc-dark", false) : icon("apps", "keepassxc-unlocked", false);
|
||||
}
|
||||
|
||||
QIcon FilePath::icon(const QString& category, const QString& name, bool recolor)
|
||||
{
|
||||
QString combinedName = category + "/" + name;
|
||||
QIcon icon = m_iconCache.value(combinedName);
|
||||
|
||||
if (!icon.isNull()) {
|
||||
return icon;
|
||||
}
|
||||
|
||||
if (icon.isNull()) {
|
||||
const QList<int> pngSizes = {16, 22, 24, 32, 48, 64, 128};
|
||||
QString filename;
|
||||
for (int size : pngSizes) {
|
||||
filename =
|
||||
QString("%1/icons/application/%2x%2/%3.png").arg(m_dataPath, QString::number(size), combinedName);
|
||||
if (QFile::exists(filename)) {
|
||||
icon.addFile(filename, QSize(size, size));
|
||||
}
|
||||
}
|
||||
filename = QString("%1/icons/application/scalable/%2.svg").arg(m_dataPath, combinedName);
|
||||
if (QFile::exists(filename) && getMainWindow() && recolor) {
|
||||
QPalette palette = getMainWindow()->palette();
|
||||
|
||||
QFile f(filename);
|
||||
QIcon scalable(filename);
|
||||
QPixmap pixmap = scalable.pixmap({128, 128});
|
||||
|
||||
auto mask = QBitmap::fromImage(pixmap.toImage().createAlphaMask());
|
||||
pixmap.fill(palette.color(QPalette::WindowText));
|
||||
pixmap.setMask(mask);
|
||||
icon.addPixmap(pixmap, QIcon::Mode::Normal);
|
||||
|
||||
pixmap.fill(palette.color(QPalette::HighlightedText));
|
||||
pixmap.setMask(mask);
|
||||
icon.addPixmap(pixmap, QIcon::Mode::Selected);
|
||||
|
||||
pixmap.fill(palette.color(QPalette::Disabled, QPalette::WindowText));
|
||||
pixmap.setMask(mask);
|
||||
icon.addPixmap(pixmap, QIcon::Mode::Disabled);
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
|
||||
icon.setIsMask(true);
|
||||
#endif
|
||||
} else if (QFile::exists(filename)) {
|
||||
icon.addFile(filename);
|
||||
}
|
||||
}
|
||||
|
||||
m_iconCache.insert(combinedName, icon);
|
||||
|
||||
return icon;
|
||||
}
|
||||
|
||||
QIcon FilePath::onOffIcon(const QString& category, const QString& name, bool recolor)
|
||||
{
|
||||
QString combinedName = category + "/" + name;
|
||||
QString cacheName = "onoff/" + combinedName;
|
||||
|
||||
QIcon icon = m_iconCache.value(cacheName);
|
||||
|
||||
if (!icon.isNull()) {
|
||||
return icon;
|
||||
}
|
||||
|
||||
QIcon on = FilePath::icon(category, name + "-on", recolor);
|
||||
for (const auto& size : on.availableSizes()) {
|
||||
icon.addPixmap(on.pixmap(size, QIcon::Mode::Normal), QIcon::Mode::Normal, QIcon::On);
|
||||
icon.addPixmap(on.pixmap(size, QIcon::Mode::Selected), QIcon::Mode::Selected, QIcon::On);
|
||||
icon.addPixmap(on.pixmap(size, QIcon::Mode::Disabled), QIcon::Mode::Disabled, QIcon::On);
|
||||
}
|
||||
QIcon off = FilePath::icon(category, name + "-off", recolor);
|
||||
for (const auto& size : off.availableSizes()) {
|
||||
icon.addPixmap(off.pixmap(size, QIcon::Mode::Normal), QIcon::Mode::Normal, QIcon::Off);
|
||||
icon.addPixmap(off.pixmap(size, QIcon::Mode::Selected), QIcon::Mode::Selected, QIcon::Off);
|
||||
icon.addPixmap(off.pixmap(size, QIcon::Mode::Disabled), QIcon::Mode::Disabled, QIcon::Off);
|
||||
}
|
||||
|
||||
m_iconCache.insert(cacheName, icon);
|
||||
|
||||
return icon;
|
||||
}
|
||||
|
||||
FilePath::FilePath()
|
||||
{
|
||||
const QString appDirPath = QCoreApplication::applicationDirPath();
|
||||
bool isDataDirAbsolute = QDir::isAbsolutePath(KEEPASSX_DATA_DIR);
|
||||
Q_UNUSED(isDataDirAbsolute);
|
||||
|
||||
if (false) {
|
||||
}
|
||||
#ifdef QT_DEBUG
|
||||
else if (testSetDir(QString(KEEPASSX_SOURCE_DIR) + "/share")) {
|
||||
}
|
||||
#endif
|
||||
#if defined(Q_OS_UNIX) && !(defined(Q_OS_MACOS) && defined(WITH_APP_BUNDLE))
|
||||
else if (isDataDirAbsolute && testSetDir(KEEPASSX_DATA_DIR)) {
|
||||
} else if (!isDataDirAbsolute && testSetDir(QString("%1/../%2").arg(appDirPath, KEEPASSX_DATA_DIR))) {
|
||||
} else if (!isDataDirAbsolute && testSetDir(QString("%1/%2").arg(KEEPASSX_PREFIX_DIR, KEEPASSX_DATA_DIR))) {
|
||||
}
|
||||
#endif
|
||||
#if defined(Q_OS_MACOS) && defined(WITH_APP_BUNDLE)
|
||||
else if (testSetDir(appDirPath + "/../Resources")) {
|
||||
}
|
||||
#endif
|
||||
#ifdef Q_OS_WIN
|
||||
else if (testSetDir(appDirPath + "/share")) {
|
||||
}
|
||||
#endif
|
||||
// Last ditch test when running in the build directory (mainly for travis tests)
|
||||
else if (testSetDir(QString(KEEPASSX_SOURCE_DIR) + "/share")) {
|
||||
}
|
||||
|
||||
if (m_dataPath.isEmpty()) {
|
||||
qWarning("FilePath::DataPath: can't find data dir");
|
||||
} else {
|
||||
m_dataPath = QDir::cleanPath(m_dataPath);
|
||||
}
|
||||
}
|
||||
|
||||
bool FilePath::testSetDir(const QString& dir)
|
||||
{
|
||||
if (QFile::exists(dir + "/icons/database/C00_Password.png")) {
|
||||
m_dataPath = dir;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool FilePath::useDarkIcon()
|
||||
{
|
||||
return config()->get("GUI/DarkTrayIcon").toBool();
|
||||
}
|
||||
|
||||
FilePath* FilePath::instance()
|
||||
{
|
||||
if (!m_instance) {
|
||||
m_instance = new FilePath();
|
||||
}
|
||||
|
||||
return m_instance;
|
||||
}
|
||||
@@ -21,7 +21,7 @@
|
||||
#include <QTextStream>
|
||||
#include <cmath>
|
||||
|
||||
#include "core/FilePath.h"
|
||||
#include "core/Resources.h"
|
||||
#include "crypto/Random.h"
|
||||
|
||||
const char* PassphraseGenerator::DefaultSeparator = " ";
|
||||
@@ -80,7 +80,7 @@ void PassphraseGenerator::setWordList(const QString& path)
|
||||
|
||||
void PassphraseGenerator::setDefaultWordList()
|
||||
{
|
||||
const QString path = filePath()->wordlistPath(PassphraseGenerator::DefaultWordList);
|
||||
const QString path = resources()->wordlistPath(PassphraseGenerator::DefaultWordList);
|
||||
setWordList(path);
|
||||
}
|
||||
|
||||
|
||||
232
src/core/Resources.cpp
Normal file
232
src/core/Resources.cpp
Normal file
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
* Copyright (C) 2020 KeePassXC Team <team@keepassxc.org>
|
||||
* Copyright (C) 2011 Felix Geyer <debfx@fobos.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 or (at your option)
|
||||
* version 3 of the License.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Resources.h"
|
||||
|
||||
#include <QBitmap>
|
||||
#include <QDir>
|
||||
#include <QLibrary>
|
||||
#include <QStyle>
|
||||
|
||||
#include "config-keepassx.h"
|
||||
#include "core/Config.h"
|
||||
#include "core/Global.h"
|
||||
#include "gui/MainWindow.h"
|
||||
|
||||
Resources* Resources::m_instance(nullptr);
|
||||
|
||||
QString Resources::dataPath(const QString& name)
|
||||
{
|
||||
if (name.isEmpty() || name.startsWith('/')) {
|
||||
return m_dataPath + name;
|
||||
}
|
||||
return m_dataPath + "/" + name;
|
||||
}
|
||||
|
||||
QString Resources::pluginPath(const QString& name)
|
||||
{
|
||||
QStringList pluginPaths;
|
||||
|
||||
QDir buildDir(QCoreApplication::applicationDirPath() + "/autotype");
|
||||
const QStringList buildDirEntryList = buildDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
|
||||
for (const QString& dir : buildDirEntryList) {
|
||||
pluginPaths << QCoreApplication::applicationDirPath() + "/autotype/" + dir;
|
||||
}
|
||||
|
||||
// for TestAutoType
|
||||
pluginPaths << QCoreApplication::applicationDirPath() + "/../src/autotype/test";
|
||||
|
||||
#if defined(Q_OS_MACOS) && defined(WITH_APP_BUNDLE)
|
||||
pluginPaths << QCoreApplication::applicationDirPath() + "/../PlugIns";
|
||||
#endif
|
||||
|
||||
pluginPaths << QCoreApplication::applicationDirPath();
|
||||
|
||||
QString configuredPluginDir = KEEPASSX_PLUGIN_DIR;
|
||||
if (configuredPluginDir != ".") {
|
||||
if (QDir(configuredPluginDir).isAbsolute()) {
|
||||
pluginPaths << configuredPluginDir;
|
||||
} else {
|
||||
QString relativePluginDir =
|
||||
QStringLiteral("%1/../%2").arg(QCoreApplication::applicationDirPath(), configuredPluginDir);
|
||||
pluginPaths << QDir(relativePluginDir).canonicalPath();
|
||||
|
||||
QString absolutePluginDir = QStringLiteral("%1/%2").arg(KEEPASSX_PREFIX_DIR, configuredPluginDir);
|
||||
pluginPaths << QDir(absolutePluginDir).canonicalPath();
|
||||
}
|
||||
}
|
||||
|
||||
QStringList dirFilter;
|
||||
dirFilter << QStringLiteral("*%1*").arg(name);
|
||||
|
||||
for (const QString& path : asConst(pluginPaths)) {
|
||||
const QStringList fileCandidates = QDir(path).entryList(dirFilter, QDir::Files);
|
||||
|
||||
for (const QString& file : fileCandidates) {
|
||||
QString filePath = path + "/" + file;
|
||||
|
||||
if (QLibrary::isLibrary(filePath)) {
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
QString Resources::wordlistPath(const QString& name)
|
||||
{
|
||||
return dataPath(QStringLiteral("wordlists/%1").arg(name));
|
||||
}
|
||||
|
||||
QIcon Resources::applicationIcon()
|
||||
{
|
||||
return icon("keepassxc", false);
|
||||
}
|
||||
|
||||
QIcon Resources::trayIcon()
|
||||
{
|
||||
return useDarkIcon() ? icon("keepassxc-dark", false) : icon("keepassxc", false);
|
||||
}
|
||||
|
||||
QIcon Resources::trayIconLocked()
|
||||
{
|
||||
return icon("keepassxc-locked", false);
|
||||
}
|
||||
|
||||
QIcon Resources::trayIconUnlocked()
|
||||
{
|
||||
return useDarkIcon() ? icon("keepassxc-dark", false) : icon("keepassxc-unlocked", false);
|
||||
}
|
||||
|
||||
QIcon Resources::icon(const QString& name, bool recolor)
|
||||
{
|
||||
QIcon icon = m_iconCache.value(name);
|
||||
|
||||
if (!icon.isNull()) {
|
||||
return icon;
|
||||
}
|
||||
|
||||
icon = QIcon::fromTheme(name);
|
||||
if (getMainWindow() && recolor) {
|
||||
QPixmap pixmap = icon.pixmap(128, 128);
|
||||
icon = {};
|
||||
|
||||
QPalette palette = getMainWindow()->palette();
|
||||
|
||||
auto mask = QBitmap::fromImage(pixmap.toImage().createAlphaMask());
|
||||
pixmap.fill(palette.color(QPalette::WindowText));
|
||||
pixmap.setMask(mask);
|
||||
icon.addPixmap(pixmap, QIcon::Mode::Normal);
|
||||
|
||||
pixmap.fill(palette.color(QPalette::HighlightedText));
|
||||
pixmap.setMask(mask);
|
||||
icon.addPixmap(pixmap, QIcon::Mode::Selected);
|
||||
|
||||
pixmap.fill(palette.color(QPalette::Disabled, QPalette::WindowText));
|
||||
pixmap.setMask(mask);
|
||||
icon.addPixmap(pixmap, QIcon::Mode::Disabled);
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
|
||||
icon.setIsMask(true);
|
||||
#endif
|
||||
}
|
||||
|
||||
m_iconCache.insert(name, icon);
|
||||
|
||||
return icon;
|
||||
}
|
||||
|
||||
QIcon Resources::onOffIcon(const QString& name, bool recolor)
|
||||
{
|
||||
QString cacheName = "onoff/" + name;
|
||||
|
||||
QIcon icon = m_iconCache.value(cacheName);
|
||||
|
||||
if (!icon.isNull()) {
|
||||
return icon;
|
||||
}
|
||||
|
||||
QIcon on = Resources::icon(name + "-on", recolor);
|
||||
for (const auto& size : on.availableSizes()) {
|
||||
icon.addPixmap(on.pixmap(size, QIcon::Mode::Normal), QIcon::Mode::Normal, QIcon::On);
|
||||
icon.addPixmap(on.pixmap(size, QIcon::Mode::Selected), QIcon::Mode::Selected, QIcon::On);
|
||||
icon.addPixmap(on.pixmap(size, QIcon::Mode::Disabled), QIcon::Mode::Disabled, QIcon::On);
|
||||
}
|
||||
QIcon off = Resources::icon(name + "-off", recolor);
|
||||
for (const auto& size : off.availableSizes()) {
|
||||
icon.addPixmap(off.pixmap(size, QIcon::Mode::Normal), QIcon::Mode::Normal, QIcon::Off);
|
||||
icon.addPixmap(off.pixmap(size, QIcon::Mode::Selected), QIcon::Mode::Selected, QIcon::Off);
|
||||
icon.addPixmap(off.pixmap(size, QIcon::Mode::Disabled), QIcon::Mode::Disabled, QIcon::Off);
|
||||
}
|
||||
|
||||
m_iconCache.insert(cacheName, icon);
|
||||
|
||||
return icon;
|
||||
}
|
||||
|
||||
Resources::Resources()
|
||||
{
|
||||
const QString appDirPath = QCoreApplication::applicationDirPath();
|
||||
#if defined(Q_OS_UNIX) && !(defined(Q_OS_MACOS) && defined(WITH_APP_BUNDLE))
|
||||
testResourceDir(KEEPASSX_DATA_DIR) || testResourceDir(QStringLiteral("%1/../%2").arg(appDirPath, KEEPASSX_DATA_DIR))
|
||||
|| testResourceDir(QStringLiteral("%1/%2").arg(KEEPASSX_PREFIX_DIR, KEEPASSX_DATA_DIR));
|
||||
#elif defined(Q_OS_MACOS) && defined(WITH_APP_BUNDLE)
|
||||
testResourceDir(appDirPath + QStringLiteral("/../Resources"));
|
||||
#elif defined(Q_OS_WIN)
|
||||
testResourceDir(appDirPath + QStringLiteral("/share"));
|
||||
#endif
|
||||
|
||||
if (m_dataPath.isEmpty()) {
|
||||
// Last ditch check if we are running from inside the src or test build directory
|
||||
testResourceDir(appDirPath + QStringLiteral("/../../share"))
|
||||
|| testResourceDir(appDirPath + QStringLiteral("/../share"))
|
||||
|| testResourceDir(appDirPath + QStringLiteral("/../../../share"));
|
||||
}
|
||||
|
||||
if (m_dataPath.isEmpty()) {
|
||||
qWarning("Resources::DataPath: can't find data dir");
|
||||
}
|
||||
}
|
||||
|
||||
bool Resources::testResourceDir(const QString& dir)
|
||||
{
|
||||
if (QFile::exists(dir + QStringLiteral("/icons/application/256x256/apps/keepassxc.png"))) {
|
||||
m_dataPath = QDir::cleanPath(dir);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Resources::useDarkIcon()
|
||||
{
|
||||
return config()->get("GUI/DarkTrayIcon").toBool();
|
||||
}
|
||||
|
||||
Resources* Resources::instance()
|
||||
{
|
||||
if (!m_instance) {
|
||||
m_instance = new Resources();
|
||||
|
||||
Q_INIT_RESOURCE(icons);
|
||||
QIcon::setThemeSearchPaths({":/icons"});
|
||||
QIcon::setThemeName("application");
|
||||
}
|
||||
|
||||
return m_instance;
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2020 KeePassXC Team <team@keepassxc.org>
|
||||
* Copyright (C) 2011 Felix Geyer <debfx@fobos.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@@ -15,14 +16,14 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef KEEPASSX_FILEPATH_H
|
||||
#define KEEPASSX_FILEPATH_H
|
||||
#ifndef KEEPASSX_RESOURCES_H
|
||||
#define KEEPASSX_RESOURCES_H
|
||||
|
||||
#include <QHash>
|
||||
#include <QIcon>
|
||||
#include <QString>
|
||||
|
||||
class FilePath
|
||||
class Resources
|
||||
{
|
||||
public:
|
||||
QString dataPath(const QString& name);
|
||||
@@ -32,27 +33,27 @@ public:
|
||||
QIcon trayIcon();
|
||||
QIcon trayIconLocked();
|
||||
QIcon trayIconUnlocked();
|
||||
QIcon icon(const QString& category, const QString& name, bool recolor = true);
|
||||
QIcon onOffIcon(const QString& category, const QString& name, bool recolor = true);
|
||||
QIcon icon(const QString& name, bool recolor = true);
|
||||
QIcon onOffIcon(const QString& name, bool recolor = true);
|
||||
|
||||
static FilePath* instance();
|
||||
static Resources* instance();
|
||||
|
||||
private:
|
||||
FilePath();
|
||||
bool testSetDir(const QString& dir);
|
||||
Resources();
|
||||
bool testResourceDir(const QString& dir);
|
||||
bool useDarkIcon();
|
||||
|
||||
static FilePath* m_instance;
|
||||
static Resources* m_instance;
|
||||
|
||||
QString m_dataPath;
|
||||
QHash<QString, QIcon> m_iconCache;
|
||||
|
||||
Q_DISABLE_COPY(FilePath)
|
||||
Q_DISABLE_COPY(Resources)
|
||||
};
|
||||
|
||||
inline FilePath* filePath()
|
||||
inline Resources* resources()
|
||||
{
|
||||
return FilePath::instance();
|
||||
return Resources::instance();
|
||||
}
|
||||
|
||||
#endif // KEEPASSX_FILEPATH_H
|
||||
#endif // KEEPASSX_RESOURCES_H
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#include "config-keepassx.h"
|
||||
#include "core/Config.h"
|
||||
#include "core/FilePath.h"
|
||||
#include "core/Resources.h"
|
||||
|
||||
/**
|
||||
* Install all KeePassXC and Qt translators.
|
||||
@@ -53,7 +53,7 @@ void Translator::installTranslators()
|
||||
#ifdef QT_DEBUG
|
||||
QString("%1/share/translations").arg(KEEPASSX_BINARY_DIR),
|
||||
#endif
|
||||
filePath()->dataPath("translations")};
|
||||
resources()->dataPath("translations")};
|
||||
|
||||
bool translationsLoaded = false;
|
||||
for (const QString& path : paths) {
|
||||
@@ -121,7 +121,7 @@ QList<QPair<QString, QString>> Translator::availableLanguages()
|
||||
#ifdef QT_DEBUG
|
||||
QString("%1/share/translations").arg(KEEPASSX_BINARY_DIR),
|
||||
#endif
|
||||
filePath()->dataPath("translations")};
|
||||
resources()->dataPath("translations")};
|
||||
|
||||
QList<QPair<QString, QString>> languages;
|
||||
languages.append(QPair<QString, QString>("system", "System default"));
|
||||
|
||||
Reference in New Issue
Block a user