Skip to content

Commit

Permalink
Refactor and clean plugin settings stuff.
Browse files Browse the repository at this point in the history
  • Loading branch information
Holt59 committed Oct 20, 2024
1 parent 263eb6a commit 890bee5
Show file tree
Hide file tree
Showing 9 changed files with 262 additions and 413 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ edit
/msbuild.log
/*std*.log
/*build
.vscode

/src/version.aps
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ mo2_add_filter(NAME src/register GROUPS
)

mo2_add_filter(NAME src/settings GROUPS
extensionsettings
settings
settingsutilities
)
Expand Down
147 changes: 147 additions & 0 deletions src/extensionsettings.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
#include "extensionsettings.h"

#include "settingsutilities.h"

using namespace MOBase;

static const QString PLUGINS_GROUP = "Plugins";
static const QString PLUGINS_PERSISTENT_GROUP = "PluginPersistance";

PluginSettings::PluginSettings(QSettings& settings) : m_Settings(settings) {}

QString PluginSettings::path(const QString& pluginName, const QString& key)
{
return pluginName + "/" + key;
}

void PluginSettings::checkPluginSettings(const IPlugin* plugin) const
{
for (const auto& setting : plugin->settings()) {
const auto settingPath = path(plugin->name(), setting.name());

QVariant temp = get<QVariant>(m_Settings, PLUGINS_GROUP, settingPath, QVariant());

// No previous enabled? Skip.
if (setting.name() == "enabled" && (!temp.isValid() || !temp.canConvert<bool>())) {
continue;
}

if (!temp.isValid()) {
temp = setting.defaultValue();
} else if (!temp.convert(setting.defaultValue().metaType())) {
log::warn("failed to interpret \"{}\" as correct type for \"{}\" in plugin "
"\"{}\", using default",
temp.toString(), setting.name(), plugin->name());

temp = setting.defaultValue();
}
}
}

void PluginSettings::fixPluginEnabledSetting(const IPlugin* plugin)
{
// handle previous "enabled" settings
// TODO: keep this?
const auto previousEnabledPath = plugin->name() + "/enabled";
const QVariant previousEnabled =
get<QVariant>(m_Settings, PLUGINS_GROUP, previousEnabledPath, QVariant());
if (previousEnabled.isValid()) {
setPersistent(plugin->name(), "enabled", previousEnabled.toBool(), true);

// We need to drop it manually in Settings since it is not possible to remove
// plugin settings:
remove(m_Settings, PLUGINS_GROUP, previousEnabledPath);
}
}

QVariant PluginSettings::setting(const QString& pluginName, const QString& key,
const QVariant& defaultValue) const
{
return get<QVariant>(m_Settings, "Settings", path(pluginName, key), defaultValue);
}

void PluginSettings::setSetting(const QString& pluginName, const QString& key,
const QVariant& value)
{
const auto settingPath = path(pluginName, key);
const auto oldValue =
get<QVariant>(m_Settings, PLUGINS_GROUP, settingPath, QVariant());
set(m_Settings, PLUGINS_GROUP, settingPath, value);
emit pluginSettingChanged(pluginName, key, oldValue, value);
}

QVariant PluginSettings::persistent(const QString& pluginName, const QString& key,
const QVariant& def) const
{
return get<QVariant>(m_Settings, "PluginPersistance", pluginName + "/" + key, def);
}

void PluginSettings::setPersistent(const QString& pluginName, const QString& key,
const QVariant& value, bool sync)
{
set(m_Settings, PLUGINS_PERSISTENT_GROUP, pluginName + "/" + key, value);

if (sync) {
m_Settings.sync();
}
}

void PluginSettings::addBlacklist(const QString& fileName)
{
m_PluginBlacklist.insert(fileName);
writeBlacklist();
}

bool PluginSettings::blacklisted(const QString& fileName) const
{
return m_PluginBlacklist.contains(fileName);
}

void PluginSettings::setBlacklist(const QStringList& pluginNames)
{
m_PluginBlacklist.clear();

for (const auto& name : pluginNames) {
m_PluginBlacklist.insert(name);
}
}

const QSet<QString>& PluginSettings::blacklist() const
{
return m_PluginBlacklist;
}

void PluginSettings::save()
{
m_Settings.sync();
writeBlacklist();
}

void PluginSettings::writeBlacklist()
{
const auto current = readBlacklist();

if (current.size() > m_PluginBlacklist.size()) {
// Qt can't remove array elements, the section must be cleared
removeSection(m_Settings, "pluginBlacklist");
}

ScopedWriteArray swa(m_Settings, "pluginBlacklist", m_PluginBlacklist.size());

for (const QString& plugin : m_PluginBlacklist) {
swa.next();
swa.set("name", plugin);
}
}

QSet<QString> PluginSettings::readBlacklist() const
{
QSet<QString> set;

ScopedReadArray sra(m_Settings, "pluginBlacklist");
sra.for_each([&] {
set.insert(sra.get<QString>("name"));
});

return set;
}
86 changes: 86 additions & 0 deletions src/extensionsettings.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#ifndef EXTENSIONSETTINGS_H
#define EXTENSIONSETTINGS_H

#include <QObject>
#include <QSettings>

#include <uibase/iplugin.h>

// settings about plugins
//
class PluginSettings : public QObject
{
Q_OBJECT

public:
PluginSettings(QSettings& settings);

// fix enabled settings from previous MO2 installation
//
void fixPluginEnabledSetting(const MOBase::IPlugin* plugin);

// check that the settings stored for the given plugin are of the appropriate type,
// warning user if not
//
void checkPluginSettings(const MOBase::IPlugin* plugin) const;

// returns the plugin setting for the given key
//
QVariant setting(const QString& pluginName, const QString& key,
const QVariant& defaultValue = {}) const;

// sets the plugin setting for the given key
//
void setSetting(const QString& pluginName, const QString& key, const QVariant& value);

// get/set persistent settings
QVariant persistent(const QString& pluginName, const QString& key,
const QVariant& def) const;
void setPersistent(const QString& pluginName, const QString& key,
const QVariant& value, bool sync);

// adds the given plugin to the blacklist
//
void addBlacklist(const QString& fileName);

// returns whether the given plugin is blacklisted
//
bool blacklisted(const QString& fileName) const;

// overwrites the whole blacklist
//
void setBlacklist(const QStringList& pluginNames);

// returns the blacklist
//
const QSet<QString>& blacklist() const;

// commits all the settings to the ini
//
void save();

Q_SIGNALS:

// emitted when a plugin setting changes
//
void pluginSettingChanged(QString const& pluginName, const QString& key,
const QVariant& oldValue, const QVariant& newValue);

private:
QSettings& m_Settings;
QSet<QString> m_PluginBlacklist;

// retrieve the path to the given setting
//
static QString path(const QString& pluginName, const QString& key);

// commits the blacklist to the ini
//
void writeBlacklist();

// reads the blacklist from the ini
//
QSet<QString> readBlacklist() const;
};

#endif
32 changes: 12 additions & 20 deletions src/organizer_en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6247,7 +6247,6 @@ Continue?</source>
<message>
<location filename="pluginlistview.cpp" line="100"/>
<source>&lt;table cellspacing=&quot;6&quot;&gt;&lt;tr&gt;&lt;th&gt;Type&lt;/th&gt;&lt;th&gt;Active &lt;/th&gt;&lt;th&gt;Total&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;All plugins:&lt;/td&gt;&lt;td align=right&gt;%1 &lt;/td&gt;&lt;td align=right&gt;%2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;ESMs:&lt;/td&gt;&lt;td align=right&gt;%3 &lt;/td&gt;&lt;td align=right&gt;%4&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;ESPs:&lt;/td&gt;&lt;td align=right&gt;%7 &lt;/td&gt;&lt;td align=right&gt;%8&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;ESMs+ESPs:&lt;/td&gt;&lt;td align=right&gt;%9 &lt;/td&gt;&lt;td align=right&gt;%10&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;ESHs:&lt;/td&gt;&lt;td align=right&gt;%11 &lt;/td&gt;&lt;td align=right&gt;%12&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;ESLs:&lt;/td&gt;&lt;td align=right&gt;%5 &lt;/td&gt;&lt;td align=right&gt;%6&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</source>
<oldsource>&lt;table cellspacing=&quot;6&quot;&gt;&lt;tr&gt;&lt;th&gt;Type&lt;/th&gt;&lt;th&gt;Active &lt;/th&gt;&lt;th&gt;Total&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;All plugins:&lt;/td&gt;&lt;td align=right&gt;%1 &lt;/td&gt;&lt;td align=right&gt;%2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;ESMs:&lt;/td&gt;&lt;td align=right&gt;%3 &lt;/td&gt;&lt;td align=right&gt;%4&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;ESPs:&lt;/td&gt;&lt;td align=right&gt;%7 &lt;/td&gt;&lt;td align=right&gt;%8&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;ESMs+ESPs:&lt;/td&gt;&lt;td align=right&gt;%9 &lt;/td&gt;&lt;td align=right&gt;%10&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;ESLs:&lt;/td&gt;&lt;td align=right&gt;%5 &lt;/td&gt;&lt;td align=right&gt;%6&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Overlay:&lt;/td&gt;&lt;td align=right&gt;%11 &lt;/td&gt;&lt;td align=right&gt;%12&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</oldsource>
<translation type="unfinished"></translation>
</message>
<message>
Expand Down Expand Up @@ -7538,19 +7537,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="1425"/>
<location filename="settings.cpp" line="1449"/>
<location filename="settings.cpp" line="1497"/>
<source>attempt to store setting for unknown plugin &quot;%1&quot;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="settings.cpp" line="1995"/>
<location filename="settings.cpp" line="1750"/>
<source>Failed</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="settings.cpp" line="1996"/>
<location filename="settings.cpp" line="1751"/>
<source>Failed to start the helper application: %1</source>
<translation type="unfinished"></translation>
</message>
Expand Down Expand Up @@ -8765,6 +8757,11 @@ If you disable this feature, MO will only display official DLCs this way. Please
<source>Preferred Servers (Drag &amp; Drop)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="settingsdialog.ui" line="1481"/>
<source>Extensions</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="settingsdialog.ui" line="1578"/>
<source>Blacklisted Plugins (use &lt;del&gt; to remove):</source>
Expand Down Expand Up @@ -8928,6 +8925,11 @@ p, li { white-space: pre-wrap; }
</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="settingsdialog.ui" line="1904"/>
<source>Back-date BSAs</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="settingsdialog.ui" line="1943"/>
<source>Add executables to the blacklist to prevent them from
Expand All @@ -8947,16 +8949,6 @@ programs you are intentionally running.</source>
<source>Executables Blacklist</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="settingsdialog.ui" line="1904"/>
<source>Back-date BSAs</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="settingsdialog.ui" line="1481"/>
<source>Extensions</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="settingsdialog.ui" line="1963"/>
<location filename="settingsdialog.ui" line="1966"/>
Expand Down
15 changes: 2 additions & 13 deletions src/pluginmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,8 @@ IPlugin* PluginManager::registerPlugin(const PluginExtension& extension,
plugin->setParent(this);

if (m_core) {
m_core->settings().plugins().registerPlugin(pluginObj);
m_core->settings().plugins().fixPluginEnabledSetting(pluginObj);
m_core->settings().plugins().checkPluginSettings(pluginObj);
}

{ // diagnosis plugin
Expand Down Expand Up @@ -564,8 +565,6 @@ void PluginManager::unloadPlugin(MOBase::IPlugin* plugin, QObject* object)
mapNames.erase(plugin->name());
}

m_core->settings().plugins().unregisterPlugin(plugin);

// force disconnection of the signals from the proxies
//
// this is a safety operations since those signals should be disconnected when the
Expand Down Expand Up @@ -611,16 +610,6 @@ bool PluginManager::unloadPlugins(const MOBase::PluginExtension& extension)

void PluginManager::unloadPlugins()
{
if (m_core) {
// this will clear several structures that can hold on to pointers to
// plugins, as well as read the plugin blacklist from the ini file, which
// is used in loadPlugins() below to skip plugins
//
// note that the first thing loadPlugins() does is call unloadPlugins(),
// so this makes sure the blacklist is always available
m_core->settings().plugins().clearPlugins();
}

bf::for_each(m_plugins, [](auto& t) {
t.second.clear();
});
Expand Down
Loading

0 comments on commit 890bee5

Please sign in to comment.