summaryrefslogtreecommitdiff
path: root/src/settingsdialogplugins.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/settingsdialogplugins.cpp')
-rw-r--r--src/settingsdialogplugins.cpp193
1 files changed, 177 insertions, 16 deletions
diff --git a/src/settingsdialogplugins.cpp b/src/settingsdialogplugins.cpp
index 5faa0dc9..16f6fb0a 100644
--- a/src/settingsdialogplugins.cpp
+++ b/src/settingsdialogplugins.cpp
@@ -3,9 +3,11 @@
#include "noeditdelegate.h"
#include <iplugin.h>
+#include "disableproxyplugindialog.h"
+#include "organizercore.h"
#include "plugincontainer.h"
-using MOBase::IPlugin;
+using namespace MOBase;
PluginsSettingsTab::PluginsSettingsTab(Settings& s, PluginContainer* pluginContainer, SettingsDialog& d)
: SettingsTab(s, d), m_pluginContainer(pluginContainer)
@@ -24,20 +26,17 @@ PluginsSettingsTab::PluginsSettingsTab(Settings& s, PluginContainer* pluginConta
item->setFont(0, font);
topItems[interfaceName] = item;
item->setExpanded(true);
+ item->setFlags(item->flags() & ~Qt::ItemIsSelectable);
}
ui->pluginsList->setHeaderHidden(true);
// display plugin settings
QSet<QString> handledNames;
for (IPlugin* plugin : settings().plugins().plugins()) {
- if (handledNames.contains(plugin->name())) {
- continue;
- }
- if (!m_filter.matches([plugin](const QRegularExpression& regex) {
- return regex.match(plugin->localizedName()).hasMatch();
- })) {
+ if (handledNames.contains(plugin->name()) || m_pluginContainer->requirements(plugin).master()) {
continue;
}
+
QTreeWidgetItem* listItem = new QTreeWidgetItem(
topItems.at(m_pluginContainer->topImplementedInterface(plugin)));
listItem->setData(0, Qt::DisplayRole, plugin->localizedName());
@@ -45,6 +44,18 @@ PluginsSettingsTab::PluginsSettingsTab(Settings& s, PluginContainer* pluginConta
listItem->setData(0, ROLE_SETTINGS, settings().plugins().settings(plugin->name()));
listItem->setData(0, ROLE_DESCRIPTIONS, settings().plugins().descriptions(plugin->name()));
+ // Handle child item:
+ auto children = m_pluginContainer->requirements(plugin).children();
+ for (auto* child : children) {
+ QTreeWidgetItem* childItem = new QTreeWidgetItem(listItem);
+ childItem->setData(0, Qt::DisplayRole, child->localizedName());
+ childItem->setData(0, ROLE_PLUGIN, QVariant::fromValue((void*)child));
+ childItem->setData(0, ROLE_SETTINGS, settings().plugins().settings(child->name()));
+ childItem->setData(0, ROLE_DESCRIPTIONS, settings().plugins().descriptions(child->name()));
+
+ handledNames.insert(child->name());
+ }
+
handledNames.insert(plugin->name());
}
@@ -66,17 +77,44 @@ PluginsSettingsTab::PluginsSettingsTab(Settings& s, PluginContainer* pluginConta
QObject::connect(
ui->pluginsList, &QTreeWidget::currentItemChanged,
[&](auto* current, auto* previous) { on_pluginsList_currentItemChanged(current, previous); });
+ QObject::connect(
+ ui->enabledCheckbox, &QCheckBox::clicked,
+ [&](bool checked) { on_checkboxEnabled_clicked(checked); });
QShortcut *delShortcut = new QShortcut(
QKeySequence(Qt::Key_Delete), ui->pluginBlacklist);
QObject::connect(delShortcut, &QShortcut::activated, &dialog(), [&] { deleteBlacklistItem(); });
- QObject::connect(&m_filter, &MOBase::FilterWidget::changed, [&] { filterPluginList(); });
+ QObject::connect(&m_filter, &FilterWidget::changed, [&] { filterPluginList(); });
+ updateListItems();
filterPluginList();
}
+void PluginsSettingsTab::updateListItems()
+{
+ for (auto i = 0; i < ui->pluginsList->topLevelItemCount(); ++i) {
+ auto* topLevelItem = ui->pluginsList->topLevelItem(i);
+ for (auto j = 0; j < topLevelItem->childCount(); ++j) {
+ auto* item = topLevelItem->child(j);
+ auto* plugin = this->plugin(item);
+
+ bool inactive = !m_pluginContainer->implementInterface<IPluginGame>(plugin)
+ && !m_pluginContainer->isEnabled(plugin);
+
+ auto font = item->font(0);
+ font.setItalic(inactive);
+ item->setFont(0, font);
+ for (auto k = 0; k < item->childCount(); ++k) {
+ item->child(k)->setFont(0, font);
+ }
+ }
+ }
+
+}
+
void PluginsSettingsTab::filterPluginList()
{
+ auto selectedItems = ui->pluginsList->selectedItems();
QTreeWidgetItem* firstNotHidden = nullptr;
for (auto i = 0; i < ui->pluginsList->topLevelItemCount(); ++i) {
@@ -87,9 +125,18 @@ void PluginsSettingsTab::filterPluginList()
auto* item = topLevelItem->child(j);
auto* plugin = this->plugin(item);
- if (m_filter.matches([plugin](const QRegularExpression& regex) {
+ // Check the item or the child - If any match (item or child), the whole
+ // group is displayed.
+ bool match = m_filter.matches([plugin](const QRegularExpression& regex) {
return regex.match(plugin->localizedName()).hasMatch();
- })) {
+ });
+ for (auto* child : m_pluginContainer->requirements(plugin).children()) {
+ match = match || m_filter.matches([child](const QRegularExpression& regex) {
+ return regex.match(child->localizedName()).hasMatch();
+ });
+ }
+
+ if (match) {
found = true;
item->setHidden(false);
@@ -106,13 +153,21 @@ void PluginsSettingsTab::filterPluginList()
}
// Unselect item if hidden:
- auto selectedItems = ui->pluginsList->selectedItems();
- if (!selectedItems.isEmpty() && selectedItems[0]->isHidden()) {
- selectedItems[0]->setSelected(false);
-
- if (firstNotHidden) {
- firstNotHidden->setSelected(true);
+ if (firstNotHidden) {
+ ui->pluginDescription->setVisible(true);
+ ui->pluginSettingsList->setVisible(true);
+ ui->noPluginLabel->setVisible(false);
+ if (selectedItems.isEmpty()) {
+ ui->pluginsList->setCurrentItem(firstNotHidden);
}
+ else if (selectedItems[0]->isHidden()) {
+ ui->pluginsList->setCurrentItem(firstNotHidden);
+ }
+ }
+ else {
+ ui->pluginDescription->setVisible(false);
+ ui->pluginSettingsList->setVisible(false);
+ ui->noPluginLabel->setVisible(true);
}
}
@@ -150,6 +205,75 @@ void PluginsSettingsTab::closing()
storeSettings(ui->pluginsList->currentItem());
}
+void PluginsSettingsTab::on_checkboxEnabled_clicked(bool checked)
+{
+ // Retrieve the plugin:
+ auto *item = ui->pluginsList->currentItem();
+ if (!item || !item->data(0, ROLE_PLUGIN).isValid()) {
+ return;
+ }
+ IPlugin* plugin = this->plugin(item);
+ const auto& requirements = m_pluginContainer->requirements(plugin);
+
+ // User wants to enable:
+ if (checked) {
+ m_pluginContainer->setEnabled(plugin, true, false);
+ }
+ 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(
+ parentWidget(), QObject::tr("Cannot disable plugin"),
+ QObject::tr("The '%1' plugin is used by the current game plugin and cannot disabled.")
+ .arg(plugin->localizedName()), QMessageBox::Ok);
+ ui->enabledCheckbox->setChecked(true);
+ return;
+ }
+
+ // Check the proxied plugins:
+ auto proxied = requirements.proxied();
+ if (!proxied.empty()) {
+ DisableProxyPluginDialog dialog(plugin, proxied, parentWidget());
+ if (dialog.exec() != QDialog::Accepted) {
+ ui->enabledCheckbox->setChecked(true);
+ return;
+ }
+ }
+ }
+
+ // Check if the plugins is required for other plugins:
+ auto requiredFor = requirements.requiredFor();
+ if (!requiredFor.empty()) {
+ QStringList pluginNames;
+ for (auto& p : requiredFor) {
+ pluginNames.append(p->localizedName());
+ }
+ pluginNames.sort();
+ QString message = QObject::tr(
+ "<p>Disabling the '%1' plugin will also disable the following plugins:</p><ul>%1</ul><p>Do you want to continue?</p>")
+ .arg(plugin->localizedName()).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;
+ }
+ }
+ m_pluginContainer->setEnabled(plugin, false, true);
+ }
+
+ // Proxy was disabled / enabled, need restart:
+ if (m_pluginContainer->implementInterface<IPluginProxy>(plugin)) {
+ dialog().setExitNeeded(Exit::Restart);
+ }
+
+ updateListItems();
+}
+
void PluginsSettingsTab::on_pluginsList_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
{
storeSettings(previous);
@@ -164,6 +288,43 @@ void PluginsSettingsTab::on_pluginsList_currentItemChanged(QTreeWidgetItem *curr
ui->versionLabel->setText(plugin->version().canonicalString());
ui->descriptionLabel->setText(plugin->description());
+ // Checkbox, do not show for children or game plugins, disable
+ // if the plugin cannot be enabled.
+ ui->enabledCheckbox->setVisible(
+ !m_pluginContainer->implementInterface<IPluginGame>(plugin)
+ && plugin->master().isEmpty());
+
+ bool enabled = m_pluginContainer->isEnabled(plugin);
+ auto& requirements = m_pluginContainer->requirements(plugin);
+ auto problems = requirements.problems();
+
+ if (m_pluginContainer->requirements(plugin).isCorePlugin()) {
+ ui->enabledCheckbox->setDisabled(true);
+ ui->enabledCheckbox->setToolTip(
+ QObject::tr("This plugin is required for Mod Organizer to work properly and cannot be disabled."));
+ }
+ // Plugin is enable or can be enabled.
+ else if (enabled || problems.empty()) {
+ ui->enabledCheckbox->setDisabled(false);
+ ui->enabledCheckbox->setToolTip("");
+ ui->enabledCheckbox->setChecked(enabled);
+ }
+ // Plugin is disable and cannot be enabled.
+ else {
+ ui->enabledCheckbox->setDisabled(true);
+ ui->enabledCheckbox->setChecked(false);
+ if (problems.size() == 1) {
+ ui->enabledCheckbox->setToolTip(problems[0].shortDescription());
+ }
+ else {
+ QStringList descriptions;
+ for (auto& problem : problems) {
+ descriptions.append(problem.shortDescription());
+ }
+ ui->enabledCheckbox->setToolTip("<ul><li>" + descriptions.join("</li><li>") + "</li></ul>");
+ }
+ }
+
QVariantMap settings = current->data(0, ROLE_SETTINGS).toMap();
QVariantMap descriptions = current->data(0, ROLE_DESCRIPTIONS).toMap();
ui->pluginSettingsList->setEnabled(settings.count() != 0);