mirror of
https://github.com/ModOrganizer2/modorganizer.git
synced 2025-12-28 06:34:38 +00:00
Start updating the settings tab for extension.
Some checks failed
Lint ModOrganizer 2 / lint (push) Has been cancelled
Some checks failed
Lint ModOrganizer 2 / lint (push) Has been cancelled
This commit is contained in:
parent
890bee5444
commit
8006988b20
@ -29,7 +29,7 @@
|
||||
"value": "x64"
|
||||
},
|
||||
"cacheVariables": {
|
||||
"CMAKE_CXX_FLAGS": "/EHsc /MP /W4",
|
||||
"CMAKE_CXX_FLAGS": "/EHsc /MP /W3",
|
||||
"VCPKG_TARGET_TRIPLET": {
|
||||
"type": "STRING",
|
||||
"value": "x64-windows-static-md"
|
||||
|
||||
@ -25,7 +25,7 @@ set_target_properties(organizer PROPERTIES
|
||||
|
||||
# disable translations because we want to be able to install somewhere else if
|
||||
# required
|
||||
mo2_configure_target(organizer WARNINGS 4 TRANSLATIONS OFF)
|
||||
mo2_configure_target(organizer WARNINGS 3 TRANSLATIONS OFF)
|
||||
|
||||
# we add translations "manually" to handle MO2_INSTALL_IS_BIN
|
||||
mo2_add_translations(organizer
|
||||
|
||||
@ -1,10 +1,14 @@
|
||||
#include "extensionmanager.h"
|
||||
|
||||
#include <log.h>
|
||||
#include <uibase/log.h>
|
||||
|
||||
#include "organizercore.h"
|
||||
|
||||
using namespace MOBase;
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
ExtensionManager::ExtensionManager(OrganizerCore* core) : m_core{core} {}
|
||||
|
||||
void ExtensionManager::loadExtensions(fs::path const& directory)
|
||||
{
|
||||
for (const auto& entry : fs::directory_iterator{directory}) {
|
||||
@ -60,8 +64,18 @@ const IExtension* ExtensionManager::extension(QString const& identifier) const
|
||||
|
||||
bool ExtensionManager::isEnabled(MOBase::IExtension const& extension) const
|
||||
{
|
||||
// TODO
|
||||
return true;
|
||||
if (!m_core) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (auto& requirement : extension.metadata().requirements()) {
|
||||
// TODO: needs an organizerproxy...
|
||||
// if (!requirement.check(m_core)) {
|
||||
// return false;
|
||||
//}
|
||||
}
|
||||
|
||||
return m_core->settings().extensions().isEnabled(extension, true);
|
||||
}
|
||||
|
||||
bool ExtensionManager::isEnabled(QString const& identifier) const
|
||||
|
||||
@ -10,10 +10,15 @@
|
||||
#include <uibase/extensions/extension.h>
|
||||
|
||||
#include "extensionwatcher.h"
|
||||
#include "organizerproxy.h"
|
||||
|
||||
class OrganizerCore;
|
||||
|
||||
class ExtensionManager
|
||||
{
|
||||
public:
|
||||
ExtensionManager(OrganizerCore* core);
|
||||
|
||||
// retrieve the list of currently loaded extensions
|
||||
//
|
||||
const auto& extensions() const { return m_extensions; }
|
||||
@ -58,6 +63,8 @@ private:
|
||||
void triggerWatchers(const MOBase::IExtension& extension) const;
|
||||
|
||||
private:
|
||||
OrganizerCore* m_core;
|
||||
std::unique_ptr<OrganizerProxy> m_proxy;
|
||||
std::vector<std::unique_ptr<const MOBase::IExtension>> m_extensions;
|
||||
|
||||
using WatcherMap = boost::fusion::map<
|
||||
|
||||
@ -4,9 +4,55 @@
|
||||
|
||||
using namespace MOBase;
|
||||
|
||||
static const QString EXTENSIONS_GROUP = "Extensions";
|
||||
static const QString EXTENSIONS_ENABLED_GROUP = "ExtensionsEnabled";
|
||||
static const QString PLUGINS_GROUP = "Plugins";
|
||||
static const QString PLUGINS_PERSISTENT_GROUP = "PluginPersistance";
|
||||
|
||||
ExtensionSettings::ExtensionSettings(QSettings& settings) : m_Settings(settings) {}
|
||||
|
||||
QString ExtensionSettings::path(const IExtension& extension, const Setting& setting)
|
||||
{
|
||||
QString path = extension.metadata().identifier();
|
||||
if (!setting.group().isEmpty()) {
|
||||
path += "/" + setting.group();
|
||||
}
|
||||
return path + "/" + setting.name();
|
||||
}
|
||||
|
||||
bool ExtensionSettings::isEnabled(const MOBase::IExtension& extension,
|
||||
bool defaultValue) const
|
||||
{
|
||||
return get<bool>(m_Settings, EXTENSIONS_ENABLED_GROUP,
|
||||
extension.metadata().identifier(), defaultValue);
|
||||
}
|
||||
|
||||
void ExtensionSettings::setEnabled(const MOBase::IExtension& extension,
|
||||
bool enabled) const
|
||||
{
|
||||
set(m_Settings, EXTENSIONS_ENABLED_GROUP, extension.metadata().identifier(), enabled);
|
||||
}
|
||||
|
||||
QVariant ExtensionSettings::setting(const IExtension& extension,
|
||||
const Setting& setting) const
|
||||
{
|
||||
return get<QVariant>(m_Settings, EXTENSIONS_GROUP, path(extension, setting),
|
||||
setting.defaultValue());
|
||||
}
|
||||
|
||||
void ExtensionSettings::setSetting(const IExtension& extension, const Setting& setting,
|
||||
const QVariant& value)
|
||||
{
|
||||
set(m_Settings, EXTENSIONS_GROUP, path(extension, setting), value);
|
||||
}
|
||||
|
||||
// commits all the settings to the ini
|
||||
//
|
||||
void ExtensionSettings::save()
|
||||
{
|
||||
m_Settings.sync();
|
||||
}
|
||||
|
||||
PluginSettings::PluginSettings(QSettings& settings) : m_Settings(settings) {}
|
||||
|
||||
QString PluginSettings::path(const QString& pluginName, const QString& key)
|
||||
@ -57,7 +103,7 @@ void PluginSettings::fixPluginEnabledSetting(const IPlugin* plugin)
|
||||
QVariant PluginSettings::setting(const QString& pluginName, const QString& key,
|
||||
const QVariant& defaultValue) const
|
||||
{
|
||||
return get<QVariant>(m_Settings, "Settings", path(pluginName, key), defaultValue);
|
||||
return get<QVariant>(m_Settings, PLUGINS_GROUP, path(pluginName, key), defaultValue);
|
||||
}
|
||||
|
||||
void PluginSettings::setSetting(const QString& pluginName, const QString& key,
|
||||
|
||||
@ -4,8 +4,48 @@
|
||||
#include <QObject>
|
||||
#include <QSettings>
|
||||
|
||||
#include <uibase/extensions/extension.h>
|
||||
#include <uibase/iplugin.h>
|
||||
|
||||
// settings about extensions
|
||||
class ExtensionSettings : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ExtensionSettings(QSettings& settings);
|
||||
|
||||
// check if the specified extension is enabled in the settings
|
||||
//
|
||||
bool isEnabled(const MOBase::IExtension& extension, bool defaultValue = true) const;
|
||||
|
||||
// set the extension as enabled or disabled in the settings
|
||||
//
|
||||
void setEnabled(const MOBase::IExtension& extension, bool enabled) const;
|
||||
|
||||
// returns the plugin setting for the given key
|
||||
//
|
||||
QVariant setting(const MOBase::IExtension& extension,
|
||||
const MOBase::Setting& setting) const;
|
||||
|
||||
// sets the plugin setting for the given key
|
||||
//
|
||||
void setSetting(const MOBase::IExtension& extension, const MOBase::Setting& setting,
|
||||
const QVariant& value);
|
||||
|
||||
// commits all the settings to the ini
|
||||
//
|
||||
void save();
|
||||
|
||||
private:
|
||||
QSettings& m_Settings;
|
||||
|
||||
// retrieve the path to the given setting
|
||||
//
|
||||
static QString path(const MOBase::IExtension& extension,
|
||||
const MOBase::Setting& setting);
|
||||
};
|
||||
|
||||
// settings about plugins
|
||||
//
|
||||
class PluginSettings : public QObject
|
||||
|
||||
@ -704,7 +704,7 @@ std::unique_ptr<Instance> selectInstance()
|
||||
// since there is no instance currently active, load plugins with a null
|
||||
// OrganizerCore; see PluginManager::initPlugin()
|
||||
NexusInterface ni(nullptr);
|
||||
ExtensionManager ec;
|
||||
ExtensionManager ec(nullptr);
|
||||
ec.loadExtensions(QDir(QCoreApplication::applicationDirPath() + "/extensions")
|
||||
.filesystemAbsolutePath());
|
||||
|
||||
|
||||
@ -215,7 +215,7 @@ int MOApplication::setup(MOMultiProcess& multiProcess, bool forceSelect)
|
||||
m_themes = std::make_unique<ThemeManager>(this);
|
||||
m_translations = std::make_unique<TranslationManager>(this);
|
||||
|
||||
m_extensions = std::make_unique<ExtensionManager>();
|
||||
m_extensions = std::make_unique<ExtensionManager>(m_core.get());
|
||||
m_extensions->registerWatcher(*m_themes);
|
||||
m_extensions->registerWatcher(*m_translations);
|
||||
|
||||
|
||||
@ -162,11 +162,9 @@ NexusSSOLogin::NexusSSOLogin() : m_keyReceived(false), m_active(false)
|
||||
onConnected();
|
||||
});
|
||||
|
||||
QObject::connect(&m_socket,
|
||||
qOverload<QAbstractSocket::SocketError>(&QWebSocket::error),
|
||||
[&](auto&& e) {
|
||||
onError(e);
|
||||
});
|
||||
QObject::connect(&m_socket, &QWebSocket::errorOccurred, [&](auto&& e) {
|
||||
onError(e);
|
||||
});
|
||||
|
||||
QObject::connect(&m_socket, &QWebSocket::sslErrors, [&](auto&& errors) {
|
||||
onSslErrors(errors);
|
||||
|
||||
@ -1786,22 +1786,12 @@ Right now the only case I know of where this needs to be overwritten is for the
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="settingsdialogextensioninfo.ui" line="121"/>
|
||||
<location filename="settingsdialogextensioninfo.ui" line="115"/>
|
||||
<source>Key</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="settingsdialogextensioninfo.ui" line="126"/>
|
||||
<source>Value</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="settingsdialogextensioninfo.ui" line="134"/>
|
||||
<source>No plugin found.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="settingsdialogextensioninfo.cpp" line="41"/>
|
||||
<location filename="settingsdialogextensioninfo.cpp" line="148"/>
|
||||
<source>Translation and theme extensions cannot be disabled.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@ -1822,6 +1812,24 @@ Right now the only case I know of where this needs to be overwritten is for the
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ExtensionSettingWidget</name>
|
||||
<message>
|
||||
<location filename="settingsdialogextensioninfo.cpp" line="45"/>
|
||||
<source>False</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="settingsdialogextensioninfo.cpp" line="45"/>
|
||||
<source>True</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="settingsdialogextensioninfo.cpp" line="77"/>
|
||||
<source>Edit</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>FileTree</name>
|
||||
<message>
|
||||
@ -7382,94 +7390,94 @@ Destination:<byte value="xd"/>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="nxmaccessmanager.cpp" line="192"/>
|
||||
<location filename="nxmaccessmanager.cpp" line="190"/>
|
||||
<source>Connecting to Nexus...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="nxmaccessmanager.cpp" line="195"/>
|
||||
<location filename="nxmaccessmanager.cpp" line="193"/>
|
||||
<source>Waiting for Nexus...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="nxmaccessmanager.cpp" line="198"/>
|
||||
<location filename="nxmaccessmanager.cpp" line="196"/>
|
||||
<source>Opened Nexus in browser.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="nxmaccessmanager.cpp" line="199"/>
|
||||
<location filename="nxmaccessmanager.cpp" line="197"/>
|
||||
<source>Switch to your browser and accept the request.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="nxmaccessmanager.cpp" line="202"/>
|
||||
<location filename="nxmaccessmanager.cpp" line="200"/>
|
||||
<source>Finished.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="nxmaccessmanager.cpp" line="205"/>
|
||||
<location filename="nxmaccessmanager.cpp" line="203"/>
|
||||
<source>No answer from Nexus.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="nxmaccessmanager.cpp" line="206"/>
|
||||
<location filename="nxmaccessmanager.cpp" line="210"/>
|
||||
<location filename="nxmaccessmanager.cpp" line="204"/>
|
||||
<location filename="nxmaccessmanager.cpp" line="208"/>
|
||||
<source>A firewall might be blocking Mod Organizer.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="nxmaccessmanager.cpp" line="209"/>
|
||||
<location filename="nxmaccessmanager.cpp" line="207"/>
|
||||
<source>Nexus closed the connection.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="nxmaccessmanager.cpp" line="213"/>
|
||||
<location filename="nxmaccessmanager.cpp" line="211"/>
|
||||
<source>Cancelled.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="nxmaccessmanager.cpp" line="401"/>
|
||||
<location filename="nxmaccessmanager.cpp" line="399"/>
|
||||
<source>Failed to request %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="nxmaccessmanager.cpp" line="423"/>
|
||||
<location filename="nxmaccessmanager.cpp" line="753"/>
|
||||
<location filename="nxmaccessmanager.cpp" line="421"/>
|
||||
<location filename="nxmaccessmanager.cpp" line="751"/>
|
||||
<source>Cancelled</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="nxmaccessmanager.cpp" line="469"/>
|
||||
<location filename="nxmaccessmanager.cpp" line="467"/>
|
||||
<source>Internal error</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="nxmaccessmanager.cpp" line="504"/>
|
||||
<location filename="nxmaccessmanager.cpp" line="502"/>
|
||||
<source>HTTP code %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="nxmaccessmanager.cpp" line="514"/>
|
||||
<location filename="nxmaccessmanager.cpp" line="512"/>
|
||||
<source>Invalid JSON</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="nxmaccessmanager.cpp" line="519"/>
|
||||
<location filename="nxmaccessmanager.cpp" line="517"/>
|
||||
<source>Bad response</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="nxmaccessmanager.cpp" line="529"/>
|
||||
<location filename="nxmaccessmanager.cpp" line="527"/>
|
||||
<source>API key is empty</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="nxmaccessmanager.cpp" line="552"/>
|
||||
<location filename="nxmaccessmanager.cpp" line="550"/>
|
||||
<source>SSL error</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="nxmaccessmanager.cpp" line="557"/>
|
||||
<location filename="nxmaccessmanager.cpp" line="555"/>
|
||||
<source>Timed out</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@ -7537,12 +7545,12 @@ This program is known to cause issues with Mod Organizer, such as freezing or bl
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="settings.cpp" line="1750"/>
|
||||
<location filename="settings.cpp" line="1761"/>
|
||||
<source>Failed</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="settings.cpp" line="1751"/>
|
||||
<location filename="settings.cpp" line="1762"/>
|
||||
<source>Failed to start the helper application: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
||||
@ -73,7 +73,7 @@ PluginDetails::PluginDetails(PluginManager* manager, PluginExtension const& exte
|
||||
|
||||
void PluginDetails::fetchRequirements()
|
||||
{
|
||||
// m_requirements = m_plugin->requirements();
|
||||
m_requirements = m_plugin->requirements();
|
||||
}
|
||||
|
||||
std::vector<IPluginRequirement::Problem> PluginDetails::problems() const
|
||||
@ -133,6 +133,11 @@ PluginManager::PluginManager(ExtensionManager const& manager, OrganizerCore* cor
|
||||
m_gameFeatures(std::make_unique<GameFeatures>(core, this))
|
||||
{
|
||||
m_loaders = makeLoaders();
|
||||
|
||||
if (m_core) {
|
||||
bf::at_key<IPluginDiagnose>(m_plugins).push_back(m_core);
|
||||
m_core->connectPlugins(this);
|
||||
}
|
||||
}
|
||||
|
||||
QStringList PluginManager::implementedInterfaces(IPlugin* plugin) const
|
||||
@ -249,12 +254,7 @@ bool PluginManager::isEnabled(MOBase::IPlugin* plugin) const
|
||||
return plugin == m_core->managedGame();
|
||||
}
|
||||
|
||||
// check the master of the group
|
||||
const auto& d = details(plugin);
|
||||
if (d.master() && d.master() != plugin) {
|
||||
return isEnabled(d.master());
|
||||
}
|
||||
|
||||
// TODO: allow disabling/enabling plugins alone?
|
||||
return m_extensions.isEnabled(details(plugin).extension());
|
||||
}
|
||||
|
||||
@ -499,28 +499,12 @@ bool PluginManager::loadPlugins(const MOBase::PluginExtension& extension)
|
||||
continue;
|
||||
}
|
||||
|
||||
// find the best interface
|
||||
auto it = std::min_element(std::begin(objectGroup), std::end(objectGroup),
|
||||
[&](auto const& lhs, auto const& rhs) {
|
||||
return isBetterInterface(lhs, rhs);
|
||||
});
|
||||
IPlugin* master = qobject_cast<IPlugin*>(*it);
|
||||
|
||||
// register plugins in the group
|
||||
for (auto* object : objectGroup) {
|
||||
IPlugin* plugin = registerPlugin(extension, object, objectGroup);
|
||||
|
||||
if (plugin) {
|
||||
m_details.at(plugin).m_master = master;
|
||||
}
|
||||
registerPlugin(extension, object, objectGroup);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: move this elsewhere, e.g., in core
|
||||
if (m_core) {
|
||||
bf::at_key<IPluginDiagnose>(m_plugins).push_back(m_core);
|
||||
m_core->connectPlugins(this);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -48,10 +48,6 @@ public:
|
||||
//
|
||||
const auto* proxy() const { return m_organizer; }
|
||||
|
||||
// the "master" of the group this plugin belongs to
|
||||
//
|
||||
MOBase::IPlugin* master() const { return m_master; }
|
||||
|
||||
// the extension containing this plugin
|
||||
//
|
||||
const MOBase::PluginExtension& extension() const { return *m_extension; }
|
||||
@ -79,7 +75,6 @@ private:
|
||||
PluginManager* m_manager;
|
||||
MOBase::IPlugin* m_plugin;
|
||||
const MOBase::PluginExtension* m_extension;
|
||||
MOBase::IPlugin* m_master;
|
||||
std::vector<std::shared_ptr<const MOBase::IPluginRequirement>> m_requirements;
|
||||
OrganizerProxy* m_organizer;
|
||||
|
||||
|
||||
@ -64,9 +64,10 @@ Settings* Settings::s_Instance = nullptr;
|
||||
Settings::Settings(const QString& path, bool globalInstance)
|
||||
: m_Settings(path, QSettings::IniFormat), m_Game(m_Settings),
|
||||
m_Geometry(m_Settings), m_Widgets(m_Settings, globalInstance),
|
||||
m_Colors(m_Settings), m_Plugins(m_Settings), m_Paths(m_Settings),
|
||||
m_Network(m_Settings, globalInstance), m_Nexus(*this, m_Settings),
|
||||
m_Steam(*this, m_Settings), m_Interface(m_Settings), m_Diagnostics(m_Settings)
|
||||
m_Colors(m_Settings), m_Extensions(m_Settings), m_Plugins(m_Settings),
|
||||
m_Paths(m_Settings), m_Network(m_Settings, globalInstance),
|
||||
m_Nexus(*this, m_Settings), m_Steam(*this, m_Settings), m_Interface(m_Settings),
|
||||
m_Diagnostics(m_Settings)
|
||||
{
|
||||
if (globalInstance) {
|
||||
if (s_Instance != nullptr) {
|
||||
@ -457,6 +458,16 @@ const ColorSettings& Settings::colors() const
|
||||
return m_Colors;
|
||||
}
|
||||
|
||||
ExtensionSettings& Settings::extensions()
|
||||
{
|
||||
return m_Extensions;
|
||||
}
|
||||
|
||||
const ExtensionSettings& Settings::extensions() const
|
||||
{
|
||||
return m_Extensions;
|
||||
}
|
||||
|
||||
PluginSettings& Settings::plugins()
|
||||
{
|
||||
return m_Plugins;
|
||||
|
||||
@ -768,6 +768,9 @@ public:
|
||||
ColorSettings& colors();
|
||||
const ColorSettings& colors() const;
|
||||
|
||||
ExtensionSettings& extensions();
|
||||
const ExtensionSettings& extensions() const;
|
||||
|
||||
PluginSettings& plugins();
|
||||
const PluginSettings& plugins() const;
|
||||
|
||||
@ -818,6 +821,7 @@ private:
|
||||
GeometrySettings m_Geometry;
|
||||
WidgetSettings m_Widgets;
|
||||
ColorSettings m_Colors;
|
||||
ExtensionSettings m_Extensions;
|
||||
PluginSettings m_Plugins;
|
||||
PathSettings m_Paths;
|
||||
NetworkSettings m_Network;
|
||||
|
||||
@ -4,10 +4,99 @@
|
||||
|
||||
#include <format>
|
||||
|
||||
#include <QComboBox>
|
||||
|
||||
#include <uibase/formatters.h>
|
||||
|
||||
#include "extensionmanager.h"
|
||||
#include "pluginmanager.h"
|
||||
#include "settings.h"
|
||||
|
||||
using namespace MOBase;
|
||||
|
||||
ExtensionSettingWidget::ExtensionSettingWidget(Setting const& setting,
|
||||
QVariant const& value, QWidget* parent)
|
||||
: QWidget(parent), m_value(value)
|
||||
{
|
||||
setLayout(new QVBoxLayout());
|
||||
|
||||
{
|
||||
auto* titleLabel = new QLabel(setting.title());
|
||||
auto font = titleLabel->font();
|
||||
font.setBold(true);
|
||||
titleLabel->setFont(font);
|
||||
layout()->addWidget(titleLabel);
|
||||
}
|
||||
|
||||
if (!setting.description().isEmpty()) {
|
||||
auto* descriptionLabel = new QLabel(setting.description());
|
||||
auto font = descriptionLabel->font();
|
||||
font.setItalic(true);
|
||||
font.setPointSize(static_cast<int>(font.pointSize() * 0.85));
|
||||
descriptionLabel->setFont(font);
|
||||
layout()->addWidget(descriptionLabel);
|
||||
}
|
||||
|
||||
{
|
||||
QWidget* valueWidget = nullptr;
|
||||
switch (setting.defaultValue().typeId()) {
|
||||
case QMetaType::Bool: {
|
||||
auto* comboBox = new QComboBox();
|
||||
comboBox->addItems({tr("False"), tr("True")});
|
||||
comboBox->setCurrentIndex(value.toBool());
|
||||
valueWidget = comboBox;
|
||||
} break;
|
||||
case QMetaType::QString: {
|
||||
auto* lineEdit = new QLineEdit(value.toString());
|
||||
valueWidget = lineEdit;
|
||||
} break;
|
||||
case QMetaType::Float:
|
||||
case QMetaType::Double: {
|
||||
auto* lineEdit = new QLineEdit(QString::number(value.toInt()));
|
||||
lineEdit->setValidator(new QDoubleValidator(lineEdit));
|
||||
valueWidget = lineEdit;
|
||||
} break;
|
||||
case QMetaType::Int:
|
||||
case QMetaType::LongLong:
|
||||
case QMetaType::UInt:
|
||||
case QMetaType::ULongLong: {
|
||||
auto* lineEdit = new QLineEdit(QString::number(value.toInt()));
|
||||
lineEdit->setValidator(new QIntValidator(lineEdit));
|
||||
valueWidget = lineEdit;
|
||||
} break;
|
||||
case QMetaType::QColor: {
|
||||
valueWidget = new QWidget(this);
|
||||
auto* layout = new QHBoxLayout();
|
||||
valueWidget->setLayout(layout);
|
||||
|
||||
const auto color = m_value.value<QColor>();
|
||||
auto* textWidget = new QLabel(color.name());
|
||||
auto* colorWidget = new QLabel("");
|
||||
colorWidget->setStyleSheet(
|
||||
QString("QLabel { background-color: %1; }").arg(color.name()));
|
||||
auto* button = new QPushButton(tr("Edit"));
|
||||
connect(button, &QPushButton::clicked, [textWidget, colorWidget, this]() {
|
||||
const auto newColor = QColorDialog::getColor(m_value.value<QColor>());
|
||||
if (newColor.isValid()) {
|
||||
m_value = newColor;
|
||||
textWidget->setText(newColor.name());
|
||||
colorWidget->setStyleSheet(
|
||||
QString("QLabel { background-color: %1; }").arg(newColor.name()));
|
||||
}
|
||||
});
|
||||
|
||||
layout->addWidget(textWidget);
|
||||
layout->addWidget(colorWidget, 1);
|
||||
layout->addWidget(button);
|
||||
} break;
|
||||
}
|
||||
|
||||
if (valueWidget) {
|
||||
layout()->addWidget(valueWidget);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ExtensionListInfoWidget::ExtensionListInfoWidget(QWidget* parent)
|
||||
: QWidget(parent), ui{new Ui::ExtensionListInfoWidget()}
|
||||
{
|
||||
@ -15,12 +104,30 @@ ExtensionListInfoWidget::ExtensionListInfoWidget(QWidget* parent)
|
||||
|
||||
ui->authorLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
|
||||
ui->authorLabel->setOpenExternalLinks(true);
|
||||
|
||||
ui->pluginSettingsList->setRootIsDecorated(true);
|
||||
ui->pluginSettingsList->setSelectionMode(QAbstractItemView::NoSelection);
|
||||
ui->pluginSettingsList->setItemsExpandable(true);
|
||||
ui->pluginSettingsList->setColumnCount(1);
|
||||
ui->pluginSettingsList->header()->setSectionResizeMode(
|
||||
0, QHeaderView::ResizeMode::Stretch);
|
||||
}
|
||||
|
||||
void ExtensionListInfoWidget::setup(Settings& settings,
|
||||
ExtensionManager& extensionManager,
|
||||
PluginManager& pluginManager)
|
||||
{
|
||||
m_settings = &settings;
|
||||
m_extensionManager = &extensionManager;
|
||||
m_pluginManager = &pluginManager;
|
||||
}
|
||||
|
||||
void ExtensionListInfoWidget::setExtension(const IExtension& extension)
|
||||
{
|
||||
m_extension = &extension;
|
||||
|
||||
// update the header for the extension
|
||||
|
||||
const auto& metadata = m_extension->metadata();
|
||||
const auto& author = metadata.author();
|
||||
|
||||
@ -40,9 +147,43 @@ void ExtensionListInfoWidget::setExtension(const IExtension& extension)
|
||||
ui->enabledCheckbox->setToolTip(
|
||||
tr("Translation and theme extensions cannot be disabled."));
|
||||
} else {
|
||||
// TODO:
|
||||
// ui->enabledCheckbox->setChecked();
|
||||
ui->enabledCheckbox->setChecked(m_extensionManager->isEnabled(extension));
|
||||
ui->enabledCheckbox->setEnabled(true);
|
||||
ui->enabledCheckbox->setToolTip(QString());
|
||||
}
|
||||
|
||||
ui->pluginSettingsList->clear();
|
||||
|
||||
// update the list of settings
|
||||
if (const auto* pluginExtension = dynamic_cast<const PluginExtension*>(m_extension)) {
|
||||
|
||||
// TODO: refactor code somewhere to have direct access of the plugins for a given
|
||||
// extension
|
||||
for (auto& plugin : m_pluginManager->plugins()) {
|
||||
if (&m_pluginManager->details(plugin).extension() != m_extension) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto settings = plugin->settings();
|
||||
if (settings.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
QTreeWidgetItem* pluginItem = new QTreeWidgetItem({plugin->localizedName()});
|
||||
ui->pluginSettingsList->addTopLevelItem(pluginItem);
|
||||
|
||||
for (auto& setting : settings) {
|
||||
auto* settingItem = new QTreeWidgetItem();
|
||||
auto* settingWidget = new ExtensionSettingWidget(
|
||||
setting, m_settings->plugins().setting(plugin->name(), setting.name(),
|
||||
setting.defaultValue()));
|
||||
pluginItem->addChild(settingItem);
|
||||
ui->pluginSettingsList->setItemWidget(settingItem, 0, settingWidget);
|
||||
settingItem->setSizeHint(0, settingWidget->sizeHint());
|
||||
}
|
||||
|
||||
pluginItem->setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator);
|
||||
pluginItem->setExpanded(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,11 +10,31 @@ namespace Ui
|
||||
class ExtensionListInfoWidget;
|
||||
}
|
||||
|
||||
class ExtensionManager;
|
||||
class PluginManager;
|
||||
class Settings;
|
||||
|
||||
class ExtensionSettingWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ExtensionSettingWidget(MOBase::Setting const& setting, QVariant const& value,
|
||||
QWidget* parent = nullptr);
|
||||
|
||||
private:
|
||||
QVariant m_value;
|
||||
};
|
||||
|
||||
class ExtensionListInfoWidget : public QWidget
|
||||
{
|
||||
public:
|
||||
ExtensionListInfoWidget(QWidget* parent = nullptr);
|
||||
|
||||
// setup the widget, should be called before any other functions
|
||||
//
|
||||
void setup(Settings& settings, ExtensionManager& extensionManager,
|
||||
PluginManager& pluginManager);
|
||||
|
||||
// set the extension to display
|
||||
//
|
||||
void setExtension(const MOBase::IExtension& extension);
|
||||
@ -22,6 +42,10 @@ public:
|
||||
private:
|
||||
Ui::ExtensionListInfoWidget* ui;
|
||||
|
||||
Settings* m_settings;
|
||||
ExtensionManager* m_extensionManager;
|
||||
PluginManager* m_pluginManager;
|
||||
|
||||
// currently displayed extension (default to nullptr)
|
||||
const MOBase::IExtension* m_extension{nullptr};
|
||||
};
|
||||
|
||||
@ -101,41 +101,20 @@
|
||||
<property name="indentation">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rootIsDecorated">
|
||||
<bool>false</bool>
|
||||
<property name="headerHidden">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="itemsExpandable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="expandsOnDoubleClick">
|
||||
<bool>false</bool>
|
||||
<property name="columnCount">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<attribute name="headerVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="headerDefaultSectionSize">
|
||||
<number>170</number>
|
||||
</attribute>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Key</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Value</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="noPluginLabel">
|
||||
<property name="text">
|
||||
<string>No plugin found.</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
||||
@ -17,6 +17,8 @@ ExtensionsSettingsTab::ExtensionsSettingsTab(Settings& s,
|
||||
: SettingsTab(s, d), m_extensionManager(&extensionManager),
|
||||
m_pluginManager(&pluginManager)
|
||||
{
|
||||
ui->infoWidget->setup(s, extensionManager, pluginManager);
|
||||
|
||||
// TODO: use Qt system to sort extensions instead of sorting beforehand
|
||||
std::vector<const IExtension*> extensions;
|
||||
for (auto& extension : m_extensionManager->extensions()) {
|
||||
|
||||
@ -464,7 +464,7 @@ TextEditorToolbar::TextEditorToolbar(TextEditor& editor)
|
||||
m_save = new QAction(QIcon(":/MO/gui/save"), QObject::tr("&Save"), &editor);
|
||||
|
||||
m_save->setShortcutContext(Qt::WidgetWithChildrenShortcut);
|
||||
m_save->setShortcut(Qt::CTRL + Qt::Key_S);
|
||||
m_save->setShortcut(Qt::CTRL | Qt::Key_S);
|
||||
m_editor.addAction(m_save);
|
||||
|
||||
m_wordWrap =
|
||||
|
||||
@ -47,7 +47,7 @@ void TranslationManager::addOldFormatTranslations()
|
||||
|
||||
QString languageString = QString("%1 (%2)")
|
||||
.arg(locale.nativeLanguageName())
|
||||
.arg(locale.nativeCountryName());
|
||||
.arg(locale.nativeTerritoryName());
|
||||
|
||||
if (locale.language() == QLocale::Chinese) {
|
||||
if (languageCode == "zh_TW") {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user