Skip to content

Commit 16db2ec

Browse files
committed
Refactor and clean plugin settings stuff.
1 parent 45dfe0b commit 16db2ec

File tree

9 files changed

+262
-413
lines changed

9 files changed

+262
-413
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@ edit
1212
/msbuild.log
1313
/*std*.log
1414
/*build
15+
.vscode
1516

1617
/src/version.aps

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ mo2_add_filter(NAME src/register GROUPS
296296
)
297297

298298
mo2_add_filter(NAME src/settings GROUPS
299+
extensionsettings
299300
settings
300301
settingsutilities
301302
)

src/extensionsettings.cpp

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
#include "extensionsettings.h"
2+
3+
#include "settingsutilities.h"
4+
5+
using namespace MOBase;
6+
7+
static const QString PLUGINS_GROUP = "Plugins";
8+
static const QString PLUGINS_PERSISTENT_GROUP = "PluginPersistance";
9+
10+
PluginSettings::PluginSettings(QSettings& settings) : m_Settings(settings) {}
11+
12+
QString PluginSettings::path(const QString& pluginName, const QString& key)
13+
{
14+
return pluginName + "/" + key;
15+
}
16+
17+
void PluginSettings::checkPluginSettings(const IPlugin* plugin) const
18+
{
19+
for (const auto& setting : plugin->settings()) {
20+
const auto settingPath = path(plugin->name(), setting.name());
21+
22+
QVariant temp = get<QVariant>(m_Settings, PLUGINS_GROUP, settingPath, QVariant());
23+
24+
// No previous enabled? Skip.
25+
if (setting.name() == "enabled" && (!temp.isValid() || !temp.canConvert<bool>())) {
26+
continue;
27+
}
28+
29+
if (!temp.isValid()) {
30+
temp = setting.defaultValue();
31+
} else if (!temp.convert(setting.defaultValue().metaType())) {
32+
log::warn("failed to interpret \"{}\" as correct type for \"{}\" in plugin "
33+
"\"{}\", using default",
34+
temp.toString(), setting.name(), plugin->name());
35+
36+
temp = setting.defaultValue();
37+
}
38+
}
39+
}
40+
41+
void PluginSettings::fixPluginEnabledSetting(const IPlugin* plugin)
42+
{
43+
// handle previous "enabled" settings
44+
// TODO: keep this?
45+
const auto previousEnabledPath = plugin->name() + "/enabled";
46+
const QVariant previousEnabled =
47+
get<QVariant>(m_Settings, PLUGINS_GROUP, previousEnabledPath, QVariant());
48+
if (previousEnabled.isValid()) {
49+
setPersistent(plugin->name(), "enabled", previousEnabled.toBool(), true);
50+
51+
// We need to drop it manually in Settings since it is not possible to remove
52+
// plugin settings:
53+
remove(m_Settings, PLUGINS_GROUP, previousEnabledPath);
54+
}
55+
}
56+
57+
QVariant PluginSettings::setting(const QString& pluginName, const QString& key,
58+
const QVariant& defaultValue) const
59+
{
60+
return get<QVariant>(m_Settings, "Settings", path(pluginName, key), defaultValue);
61+
}
62+
63+
void PluginSettings::setSetting(const QString& pluginName, const QString& key,
64+
const QVariant& value)
65+
{
66+
const auto settingPath = path(pluginName, key);
67+
const auto oldValue =
68+
get<QVariant>(m_Settings, PLUGINS_GROUP, settingPath, QVariant());
69+
set(m_Settings, PLUGINS_GROUP, settingPath, value);
70+
emit pluginSettingChanged(pluginName, key, oldValue, value);
71+
}
72+
73+
QVariant PluginSettings::persistent(const QString& pluginName, const QString& key,
74+
const QVariant& def) const
75+
{
76+
return get<QVariant>(m_Settings, "PluginPersistance", pluginName + "/" + key, def);
77+
}
78+
79+
void PluginSettings::setPersistent(const QString& pluginName, const QString& key,
80+
const QVariant& value, bool sync)
81+
{
82+
set(m_Settings, PLUGINS_PERSISTENT_GROUP, pluginName + "/" + key, value);
83+
84+
if (sync) {
85+
m_Settings.sync();
86+
}
87+
}
88+
89+
void PluginSettings::addBlacklist(const QString& fileName)
90+
{
91+
m_PluginBlacklist.insert(fileName);
92+
writeBlacklist();
93+
}
94+
95+
bool PluginSettings::blacklisted(const QString& fileName) const
96+
{
97+
return m_PluginBlacklist.contains(fileName);
98+
}
99+
100+
void PluginSettings::setBlacklist(const QStringList& pluginNames)
101+
{
102+
m_PluginBlacklist.clear();
103+
104+
for (const auto& name : pluginNames) {
105+
m_PluginBlacklist.insert(name);
106+
}
107+
}
108+
109+
const QSet<QString>& PluginSettings::blacklist() const
110+
{
111+
return m_PluginBlacklist;
112+
}
113+
114+
void PluginSettings::save()
115+
{
116+
m_Settings.sync();
117+
writeBlacklist();
118+
}
119+
120+
void PluginSettings::writeBlacklist()
121+
{
122+
const auto current = readBlacklist();
123+
124+
if (current.size() > m_PluginBlacklist.size()) {
125+
// Qt can't remove array elements, the section must be cleared
126+
removeSection(m_Settings, "pluginBlacklist");
127+
}
128+
129+
ScopedWriteArray swa(m_Settings, "pluginBlacklist", m_PluginBlacklist.size());
130+
131+
for (const QString& plugin : m_PluginBlacklist) {
132+
swa.next();
133+
swa.set("name", plugin);
134+
}
135+
}
136+
137+
QSet<QString> PluginSettings::readBlacklist() const
138+
{
139+
QSet<QString> set;
140+
141+
ScopedReadArray sra(m_Settings, "pluginBlacklist");
142+
sra.for_each([&] {
143+
set.insert(sra.get<QString>("name"));
144+
});
145+
146+
return set;
147+
}

src/extensionsettings.h

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#ifndef EXTENSIONSETTINGS_H
2+
#define EXTENSIONSETTINGS_H
3+
4+
#include <QObject>
5+
#include <QSettings>
6+
7+
#include <uibase/iplugin.h>
8+
9+
// settings about plugins
10+
//
11+
class PluginSettings : public QObject
12+
{
13+
Q_OBJECT
14+
15+
public:
16+
PluginSettings(QSettings& settings);
17+
18+
// fix enabled settings from previous MO2 installation
19+
//
20+
void fixPluginEnabledSetting(const MOBase::IPlugin* plugin);
21+
22+
// check that the settings stored for the given plugin are of the appropriate type,
23+
// warning user if not
24+
//
25+
void checkPluginSettings(const MOBase::IPlugin* plugin) const;
26+
27+
// returns the plugin setting for the given key
28+
//
29+
QVariant setting(const QString& pluginName, const QString& key,
30+
const QVariant& defaultValue = {}) const;
31+
32+
// sets the plugin setting for the given key
33+
//
34+
void setSetting(const QString& pluginName, const QString& key, const QVariant& value);
35+
36+
// get/set persistent settings
37+
QVariant persistent(const QString& pluginName, const QString& key,
38+
const QVariant& def) const;
39+
void setPersistent(const QString& pluginName, const QString& key,
40+
const QVariant& value, bool sync);
41+
42+
// adds the given plugin to the blacklist
43+
//
44+
void addBlacklist(const QString& fileName);
45+
46+
// returns whether the given plugin is blacklisted
47+
//
48+
bool blacklisted(const QString& fileName) const;
49+
50+
// overwrites the whole blacklist
51+
//
52+
void setBlacklist(const QStringList& pluginNames);
53+
54+
// returns the blacklist
55+
//
56+
const QSet<QString>& blacklist() const;
57+
58+
// commits all the settings to the ini
59+
//
60+
void save();
61+
62+
Q_SIGNALS:
63+
64+
// emitted when a plugin setting changes
65+
//
66+
void pluginSettingChanged(QString const& pluginName, const QString& key,
67+
const QVariant& oldValue, const QVariant& newValue);
68+
69+
private:
70+
QSettings& m_Settings;
71+
QSet<QString> m_PluginBlacklist;
72+
73+
// retrieve the path to the given setting
74+
//
75+
static QString path(const QString& pluginName, const QString& key);
76+
77+
// commits the blacklist to the ini
78+
//
79+
void writeBlacklist();
80+
81+
// reads the blacklist from the ini
82+
//
83+
QSet<QString> readBlacklist() const;
84+
};
85+
86+
#endif

src/organizer_en.ts

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6247,7 +6247,6 @@ Continue?</source>
62476247
<message>
62486248
<location filename="pluginlistview.cpp" line="100"/>
62496249
<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>
6250-
<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>
62516250
<translation type="unfinished"></translation>
62526251
</message>
62536252
<message>
@@ -7538,19 +7537,12 @@ This program is known to cause issues with Mod Organizer, such as freezing or bl
75387537
<translation type="unfinished"></translation>
75397538
</message>
75407539
<message>
7541-
<location filename="settings.cpp" line="1425"/>
7542-
<location filename="settings.cpp" line="1449"/>
7543-
<location filename="settings.cpp" line="1497"/>
7544-
<source>attempt to store setting for unknown plugin &quot;%1&quot;</source>
7545-
<translation type="unfinished"></translation>
7546-
</message>
7547-
<message>
7548-
<location filename="settings.cpp" line="1995"/>
7540+
<location filename="settings.cpp" line="1750"/>
75497541
<source>Failed</source>
75507542
<translation type="unfinished"></translation>
75517543
</message>
75527544
<message>
7553-
<location filename="settings.cpp" line="1996"/>
7545+
<location filename="settings.cpp" line="1751"/>
75547546
<source>Failed to start the helper application: %1</source>
75557547
<translation type="unfinished"></translation>
75567548
</message>
@@ -8765,6 +8757,11 @@ If you disable this feature, MO will only display official DLCs this way. Please
87658757
<source>Preferred Servers (Drag &amp; Drop)</source>
87668758
<translation type="unfinished"></translation>
87678759
</message>
8760+
<message>
8761+
<location filename="settingsdialog.ui" line="1481"/>
8762+
<source>Extensions</source>
8763+
<translation type="unfinished"></translation>
8764+
</message>
87688765
<message>
87698766
<location filename="settingsdialog.ui" line="1578"/>
87708767
<source>Blacklisted Plugins (use &lt;del&gt; to remove):</source>
@@ -8928,6 +8925,11 @@ p, li { white-space: pre-wrap; }
89288925
</source>
89298926
<translation type="unfinished"></translation>
89308927
</message>
8928+
<message>
8929+
<location filename="settingsdialog.ui" line="1904"/>
8930+
<source>Back-date BSAs</source>
8931+
<translation type="unfinished"></translation>
8932+
</message>
89318933
<message>
89328934
<location filename="settingsdialog.ui" line="1943"/>
89338935
<source>Add executables to the blacklist to prevent them from
@@ -8947,16 +8949,6 @@ programs you are intentionally running.</source>
89478949
<source>Executables Blacklist</source>
89488950
<translation type="unfinished"></translation>
89498951
</message>
8950-
<message>
8951-
<location filename="settingsdialog.ui" line="1904"/>
8952-
<source>Back-date BSAs</source>
8953-
<translation type="unfinished"></translation>
8954-
</message>
8955-
<message>
8956-
<location filename="settingsdialog.ui" line="1481"/>
8957-
<source>Extensions</source>
8958-
<translation type="unfinished"></translation>
8959-
</message>
89608952
<message>
89618953
<location filename="settingsdialog.ui" line="1963"/>
89628954
<location filename="settingsdialog.ui" line="1966"/>

src/pluginmanager.cpp

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,8 @@ IPlugin* PluginManager::registerPlugin(const PluginExtension& extension,
383383
plugin->setParent(this);
384384

385385
if (m_core) {
386-
m_core->settings().plugins().registerPlugin(pluginObj);
386+
m_core->settings().plugins().fixPluginEnabledSetting(pluginObj);
387+
m_core->settings().plugins().checkPluginSettings(pluginObj);
387388
}
388389

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

567-
m_core->settings().plugins().unregisterPlugin(plugin);
568-
569568
// force disconnection of the signals from the proxies
570569
//
571570
// this is a safety operations since those signals should be disconnected when the
@@ -611,16 +610,6 @@ bool PluginManager::unloadPlugins(const MOBase::PluginExtension& extension)
611610

612611
void PluginManager::unloadPlugins()
613612
{
614-
if (m_core) {
615-
// this will clear several structures that can hold on to pointers to
616-
// plugins, as well as read the plugin blacklist from the ini file, which
617-
// is used in loadPlugins() below to skip plugins
618-
//
619-
// note that the first thing loadPlugins() does is call unloadPlugins(),
620-
// so this makes sure the blacklist is always available
621-
m_core->settings().plugins().clearPlugins();
622-
}
623-
624613
bf::for_each(m_plugins, [](auto& t) {
625614
t.second.clear();
626615
});

0 commit comments

Comments
 (0)