diff options
| author | Mikaël Capelle <capelle.mikael@gmail.com> | 2020-11-11 22:45:33 +0100 |
|---|---|---|
| committer | Mikaël Capelle <capelle.mikael@gmail.com> | 2020-11-11 22:45:33 +0100 |
| commit | 90beed8c7b356ef58431721ffe8eb4abff3da032 (patch) | |
| tree | dae08a323a54f9a53d05e6d3d50cbe40fd094da1 | |
| parent | 7ec0128eb59c085cd5961995280238cc22683b8e (diff) | |
Handle proxy dependencies differently.
| -rw-r--r-- | src/plugincontainer.cpp | 37 | ||||
| -rw-r--r-- | src/plugincontainer.h | 10 | ||||
| -rw-r--r-- | src/settingsdialogplugins.cpp | 26 |
3 files changed, 60 insertions, 13 deletions
diff --git a/src/plugincontainer.cpp b/src/plugincontainer.cpp index bcd0db44..05c6790d 100644 --- a/src/plugincontainer.cpp +++ b/src/plugincontainer.cpp @@ -58,14 +58,11 @@ PluginRequirements::PluginRequirements(PluginContainer* pluginContainer, MOBase: , m_Plugin(plugin)
, m_PluginProxy(pluginProxy)
, m_Organizer(proxy)
-{
- for (auto* requirement : plugin->requirements()) {
- m_Requirements.emplace_back(requirement);
- }
+{ }
- // TODO:
- if (pluginProxy) {
- m_Requirements.emplace_back(PluginRequirementFactory::pluginDependency(pluginProxy->name()));
+void PluginRequirements::fetchRequirements() {
+ for (auto* requirement : m_Plugin->requirements()) {
+ m_Requirements.emplace_back(requirement);
}
}
@@ -74,6 +71,20 @@ IPluginProxy* PluginRequirements::proxy() const return m_PluginProxy;
}
+std::vector<IPlugin*> PluginRequirements::proxied() const
+{
+ std::vector<IPlugin*> children;
+ if (dynamic_cast<IPluginProxy*>(m_Plugin)) {
+ for (auto* obj : m_PluginContainer->plugins<QObject>()) {
+ auto* plugin = qobject_cast<IPlugin*>(obj);
+ if (plugin && m_PluginContainer->requirements(plugin).proxy() == m_Plugin) {
+ children.push_back(plugin);
+ }
+ }
+ }
+ return children;
+}
+
IPlugin* PluginRequirements::master() const
{
if (m_Plugin->master().isEmpty()) {
@@ -322,12 +333,15 @@ bool PluginContainer::initPlugin(IPlugin *plugin, IPluginProxy *pluginProxy) return true;
}
+ auto [it, bl] = m_Requirements.emplace(plugin, PluginRequirements(this, plugin, proxy, pluginProxy));
+
if (!plugin->init(proxy)) {
log::warn("plugin failed to initialize");
return false;
}
- m_Requirements.emplace(plugin, PluginRequirements(this, plugin, proxy, pluginProxy));
+ // Update requirements:
+ it->second.fetchRequirements();
return true;
}
@@ -519,11 +533,8 @@ bool PluginContainer::isEnabled(IPlugin* plugin) const return false;
}
- // Check the requirements (if a plugin checks in init(), the requirements have
- // not been computed yet):
- auto it = m_Requirements.find(plugin);
-
- return it == std::end(m_Requirements) ? true : it->second.canEnable();
+ // Check the requirements:
+ return m_Requirements.at(plugin).canEnable();
}
void PluginContainer::setEnabled(MOBase::IPlugin* plugin, bool enable, bool dependencies)
diff --git a/src/plugincontainer.h b/src/plugincontainer.h index e9761cb1..b37b48cd 100644 --- a/src/plugincontainer.h +++ b/src/plugincontainer.h @@ -50,6 +50,11 @@ public: MOBase::IPluginProxy* proxy() const;
/**
+ * @return the list of plugins this plugin proxies (if it's a proxy plugin).
+ */
+ std::vector<MOBase::IPlugin*> proxied() const;
+
+ /**
* @return the master of this plugin, if any.
*/
MOBase::IPlugin* master() const;
@@ -81,6 +86,11 @@ private: // Accumulator version for requiredFor() to avoid infinite recursion.
void requiredFor(std::vector<MOBase::IPlugin*>& required, std::set<MOBase::IPlugin*>& visited) const;
+ // Retrieve the requirements from the underlying plugin, take ownership on them
+ // and store them. We cannot do this in the constructor because we want to have a
+ // constructed object before calling init().
+ void fetchRequirements();
+
friend class PluginContainer;
PluginContainer* m_PluginContainer;
diff --git a/src/settingsdialogplugins.cpp b/src/settingsdialogplugins.cpp index 15c0b424..e9d36c57 100644 --- a/src/settingsdialogplugins.cpp +++ b/src/settingsdialogplugins.cpp @@ -225,6 +225,8 @@ void PluginsSettingsTab::on_checkboxEnabled_clicked(bool checked) else { // Custom check for proxy + current game: if (m_pluginContainer->implementInterface<IPluginProxy>(plugin)) { + + // Current game: auto* game = m_pluginContainer->managedGame(); if (m_pluginContainer->requirements(game).proxy() == plugin) { QMessageBox::warning( @@ -233,6 +235,25 @@ void PluginsSettingsTab::on_checkboxEnabled_clicked(bool checked) ui->enabledCheckbox->setChecked(true); return; } + + // Check the proxied plugins: + auto proxied = requirements.proxied(); + QStringList pluginNames; + for (auto& p : proxied) { + pluginNames.append(p->localizedName()); + } + pluginNames.sort(); + QString message = QObject::tr( + "<p>Disabling this plugin will prevent the following plugins from working correctly:</p><ul>%1</ul>" + "<p>Do you want to continue? You will need to restart ModOrganizer2 for the change to take effect.</p>") + .arg("<li>" + pluginNames.join("</li><li>") + "</li>"); + if (QMessageBox::warning( + parentWidget(), QObject::tr("Really disable plugin?"), message, + QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) { + ui->enabledCheckbox->setChecked(true); + return; + } + } // Check if the plugins is required for other plugins: @@ -256,6 +277,11 @@ void PluginsSettingsTab::on_checkboxEnabled_clicked(bool checked) m_pluginContainer->setEnabled(plugin, false, true); } + // Proxy was disabled / enabled, need restart: + if (m_pluginContainer->implementInterface<IPluginProxy>(plugin)) { + dialog().setExitNeeded(Exit::Restart); + } + updateListItems(); } |
