diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 372ff2491..25f24cc8d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -232,7 +232,8 @@ mo2_add_filter(NAME src/settingsdialog GROUPS settingsdialoggeneral settingsdialognexus settingsdialogpaths - settingsdialogplugins + settingsdialogextensions + settingsdialogextensionrow settingsdialogworkarounds settingsdialogmodlist settingsdialogtheme diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index e34e2afe6..ebc6046d2 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -230,14 +230,15 @@ void setFilterShortcuts(QWidget* widget, QLineEdit* edit) } MainWindow::MainWindow(Settings& settings, OrganizerCore& organizerCore, - PluginManager& pluginManager, ThemeManager& themeManager, + ExtensionManager& extensionManager, PluginManager& pluginManager, + ThemeManager& themeManager, TranslationManager& translationManager, QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWindow), m_WasVisible(false), m_FirstPaint(true), m_linksSeparator(nullptr), m_Tutorial(this, "MainWindow"), m_OldProfileIndex(-1), m_OldExecutableIndex(-1), m_CategoryFactory(CategoryFactory::instance()), m_OrganizerCore(organizerCore), - m_PluginManager(pluginManager), m_ThemeManager(themeManager), - m_TranslationManager(translationManager), + m_ExtensionManager(extensionManager), m_PluginManager(pluginManager), + m_ThemeManager(themeManager), m_TranslationManager(translationManager), m_ArchiveListWriter(std::bind(&MainWindow::saveArchiveList, this)), m_LinkToolbar(nullptr), m_LinkDesktop(nullptr), m_LinkStartMenu(nullptr), m_NumberOfProblems(0), m_ProblemsCheckRequired(false) @@ -2731,8 +2732,8 @@ void MainWindow::on_actionSettings_triggered() const bool oldCheckForUpdates = settings.checkForUpdates(); const int oldMaxDumps = settings.diagnostics().maxCoreDumps(); - SettingsDialog dialog(m_PluginManager, m_ThemeManager, m_TranslationManager, settings, - this); + SettingsDialog dialog(m_ExtensionManager, m_PluginManager, m_ThemeManager, + m_TranslationManager, settings, this); dialog.exec(); auto e = dialog.exitNeeded(); diff --git a/src/mainwindow.h b/src/mainwindow.h index 3e99f79ed..ba67f6f3a 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -23,8 +23,9 @@ along with Mod Organizer. If not, see . #include "bsafolder.h" #include "delayedfilewriter.h" #include "errorcodes.h" +#include "extensionmanager.h" #include "imoinfo.h" -#include "iplugingame.h" //namespace MOBase { class IPluginGame; } +#include "iplugingame.h" #include "iuserinterface.h" #include "modinfo.h" #include "modlistbypriorityproxy.h" @@ -126,7 +127,8 @@ class MainWindow : public QMainWindow, public IUserInterface public: explicit MainWindow(Settings& settings, OrganizerCore& organizerCore, - PluginManager& pluginManager, ThemeManager& themeManager, + ExtensionManager& extensionManager, PluginManager& pluginManager, + ThemeManager& themeManager, TranslationManager& translationManager, QWidget* parent = 0); ~MainWindow(); @@ -296,6 +298,7 @@ private slots: QTime m_StartTime; OrganizerCore& m_OrganizerCore; + ExtensionManager& m_ExtensionManager; PluginManager& m_PluginManager; ThemeManager& m_ThemeManager; TranslationManager& m_TranslationManager; diff --git a/src/moapplication.cpp b/src/moapplication.cpp index 189c29970..bcea9ea0c 100644 --- a/src/moapplication.cpp +++ b/src/moapplication.cpp @@ -294,7 +294,8 @@ int MOApplication::run(MOMultiProcess& multiProcess) { tt.start("MOApplication::doOneRun() MainWindow setup"); - MainWindow mainWindow(*m_settings, *m_core, *m_plugins, *m_themes, *m_translations); + MainWindow mainWindow(*m_settings, *m_core, *m_extensions, *m_plugins, *m_themes, + *m_translations); // the nexus interface can show dialogs, make sure they're parented to the // main window diff --git a/src/pluginmanager.cpp b/src/pluginmanager.cpp index 785aee24d..2d9a3b5bc 100644 --- a/src/pluginmanager.cpp +++ b/src/pluginmanager.cpp @@ -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 PluginDetails::problems() const diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index 1db59117e..d352489ba 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -19,23 +19,24 @@ along with Mod Organizer. If not, see . #include "settingsdialog.h" #include "settingsdialogdiagnostics.h" +#include "settingsdialogextensions.h" #include "settingsdialoggeneral.h" #include "settingsdialogmodlist.h" #include "settingsdialognexus.h" #include "settingsdialogpaths.h" -#include "settingsdialogplugins.h" #include "settingsdialogtheme.h" #include "settingsdialogworkarounds.h" #include "ui_settingsdialog.h" using namespace MOBase; -SettingsDialog::SettingsDialog(PluginManager& pluginManager, +SettingsDialog::SettingsDialog(ExtensionManager& extensionManager, + PluginManager& pluginManager, ThemeManager const& themeManager, TranslationManager const& translationManager, Settings& settings, QWidget* parent) : TutorableDialog("SettingsDialog", parent), ui(new Ui::SettingsDialog), - m_settings(settings), m_exit(Exit::None), m_pluginManager(&pluginManager) + m_settings(settings), m_exit(Exit::None) { ui->setupUi(this); @@ -50,7 +51,7 @@ SettingsDialog::SettingsDialog(PluginManager& pluginManager, std::unique_ptr(new DiagnosticsSettingsTab(settings, *this))); m_tabs.push_back(std::unique_ptr(new NexusSettingsTab(settings, *this))); m_tabs.push_back(std::unique_ptr( - new PluginsSettingsTab(settings, *m_pluginManager, *this))); + new ExtensionsSettingsTab(settings, extensionManager, pluginManager, *this))); m_tabs.push_back( std::unique_ptr(new WorkaroundsSettingsTab(settings, *this))); } diff --git a/src/settingsdialog.h b/src/settingsdialog.h index 25a6bf9d9..da3555f3d 100644 --- a/src/settingsdialog.h +++ b/src/settingsdialog.h @@ -24,6 +24,7 @@ along with Mod Organizer. If not, see . #include "tutorabledialog.h" class PluginManager; +class ExtensionManager; class Settings; class SettingsDialog; class ThemeManager; @@ -66,7 +67,8 @@ class SettingsDialog : public MOBase::TutorableDialog friend class SettingsTab; public: - explicit SettingsDialog(PluginManager& pluginManager, + explicit SettingsDialog(ExtensionManager& extensionManager, + PluginManager& pluginManager, ThemeManager const& themeManager, TranslationManager const& translationManager, Settings& settings, QWidget* parent = 0); @@ -94,7 +96,6 @@ public slots: Settings& m_settings; std::vector> m_tabs; ExitFlags m_exit; - PluginManager* m_pluginManager; }; #endif // SETTINGSDIALOG_H diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index 0c611ff09..48da701aa 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -1476,9 +1476,9 @@ If you disable this feature, MO will only display official DLCs this way. Please - + - Plugins + Extensions @@ -1532,13 +1532,7 @@ If you disable this feature, MO will only display official DLCs this way. Please 0 - - - - 1 - - - + diff --git a/src/settingsdialogextensionrow.cpp b/src/settingsdialogextensionrow.cpp new file mode 100644 index 000000000..7f5b37642 --- /dev/null +++ b/src/settingsdialogextensionrow.cpp @@ -0,0 +1,18 @@ +#include "settingsdialogextensionrow.h" + +#include "ui_settingsdialogextensionrow.h" + +using namespace MOBase; + +ExtensionListItemWidget::ExtensionListItemWidget(const IExtension& extension) + : ui{new Ui::ExtensionListItemWidget()}, m_extension{&extension} +{ + ui->setupUi(this); + + QIcon icon = style()->standardIcon(QStyle::SP_DialogOkButton); + ui->extensionIcon->setPixmap(extension.metadata().icon().pixmap(QSize(48, 48))); + ui->extensionName->setText(extension.metadata().name()); + + ui->extensionDescription->setText(extension.metadata().description()); + ui->extensionAuthor->setText(extension.metadata().author().name()); +} diff --git a/src/settingsdialogextensionrow.h b/src/settingsdialogextensionrow.h new file mode 100644 index 000000000..e2aa52806 --- /dev/null +++ b/src/settingsdialogextensionrow.h @@ -0,0 +1,23 @@ +#ifndef SETTINGSDIALOGEXTENSIONROW_H +#define SETTINGSDIALOGEXTENSIONROW_H + +#include + +#include "extension.h" + +namespace Ui +{ +class ExtensionListItemWidget; +} + +class ExtensionListItemWidget : public QWidget +{ +public: + ExtensionListItemWidget(MOBase::IExtension const& extension); + +private: + Ui::ExtensionListItemWidget* ui; + const MOBase::IExtension* m_extension; +}; + +#endif diff --git a/src/settingsdialogextensionrow.ui b/src/settingsdialogextensionrow.ui new file mode 100644 index 000000000..bb9986a17 --- /dev/null +++ b/src/settingsdialogextensionrow.ui @@ -0,0 +1,123 @@ + + + ExtensionListItemWidget + + + + 0 + 0 + 250 + 60 + + + + Form + + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + 0 + 0 + + + + + 48 + 48 + + + + + 45 + 48 + + + + TextLabel + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 5 + 20 + + + + + + + + 2 + + + + + + 10 + true + + + + TextLabel + + + + + + + + 8 + true + + + + TextLabel + + + + + + + + + + 8 + + + + TextLabel + + + + + + + + + + + + diff --git a/src/settingsdialogextensions.cpp b/src/settingsdialogextensions.cpp new file mode 100644 index 000000000..300655e88 --- /dev/null +++ b/src/settingsdialogextensions.cpp @@ -0,0 +1,300 @@ +#include "settingsdialogextensions.h" +#include "noeditdelegate.h" +#include "ui_settingsdialog.h" +#include + +#include "organizercore.h" +#include "pluginmanager.h" + +#include "settingsdialogextensionrow.h" + +using namespace MOBase; + +struct PluginExtensionComparator +{ + bool operator()(const PluginExtension* lhs, const PluginExtension* rhs) const + { + return lhs->metadata().name().compare(rhs->metadata().name(), Qt::CaseInsensitive); + } +}; + +ExtensionsSettingsTab::ExtensionsSettingsTab(Settings& s, + ExtensionManager& extensionManager, + PluginManager& pluginManager, + SettingsDialog& d) + : SettingsTab(s, d), m_extensionManager(&extensionManager), + m_pluginManager(&pluginManager) +{ + // TODO: use Qt system to sort extensions instead of sorting beforehand + std::vector extensions; + for (auto& extension : m_extensionManager->extensions()) { + extensions.push_back(extension.get()); + } + std::sort(extensions.begin(), extensions.end(), [](auto* lhs, auto* rhs) { + return lhs->metadata().name().compare(rhs->metadata().name(), Qt::CaseInsensitive) < + 0; + }); + + ui->extensionsList->setSortingEnabled(false); + + for (const auto* extension : extensions) { + auto* item = new QListWidgetItem(); + auto* widget = new ExtensionListItemWidget(*extension); + item->setSizeHint(widget->sizeHint()); + ui->extensionsList->addItem(item); + ui->extensionsList->setItemWidget(item, widget); + } + + // ui->pluginSettingsList->setStyleSheet("QTreeWidget::item {padding-right: 10px;}"); + // ui->pluginsList->setHeaderHidden(true); + + //// display plugin settings + // std::map, PluginExtensionComparator> + // pluginsPerExtension; + + // for (IPlugin* plugin : pluginManager.plugins()) { + // pluginsPerExtension[&pluginManager.details(plugin).extension()].push_back(plugin); + // } + + // for (auto& [extension, plugins] : pluginsPerExtension) { + + // QTreeWidgetItem* extensionItem = new QTreeWidgetItem(); + // extensionItem->setData(0, Qt::DisplayRole, extension->metadata().name()); + // ui->pluginsList->addTopLevelItem(extensionItem); + + // for (auto* plugin : plugins) { + + // // only show master + // if (pluginManager.details(plugin).master() != plugin) { + // continue; + // } + + // QTreeWidgetItem* pluginItem = new QTreeWidgetItem(extensionItem); + // pluginItem->setData(0, Qt::DisplayRole, plugin->localizedName()); + // } + //} + + // ui->pluginsList->sortByColumn(0, Qt::AscendingOrder); + + //// display plugin blacklist + // for (const QString& pluginName : settings().plugins().blacklist()) { + // ui->pluginBlacklist->addItem(pluginName); + // } + + // m_filter.setEdit(ui->pluginFilterEdit); + + // QObject::connect(ui->pluginsList, &QTreeWidget::currentItemChanged, + // [&](auto* current, auto* previous) { + // on_pluginsList_currentItemChanged(current, previous); + // }); + + // QShortcut* delShortcut = + // new QShortcut(QKeySequence(Qt::Key_Delete), ui->pluginBlacklist); + // QObject::connect(delShortcut, &QShortcut::activated, &dialog(), [&] { + // deleteBlacklistItem(); + // }); + // 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_pluginManager->implementInterface(plugin) && +// !m_pluginManager->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) { +// auto* topLevelItem = ui->pluginsList->topLevelItem(i); +// +// bool found = false; +// for (auto j = 0; j < topLevelItem->childCount(); ++j) { +// auto* item = topLevelItem->child(j); +// auto* plugin = this->plugin(item); +// +// // 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(); +// }); +// +// if (match) { +// found = true; +// item->setHidden(false); +// +// if (firstNotHidden == nullptr) { +// firstNotHidden = item; +// } +// } else { +// item->setHidden(true); +// } +// } +// +// topLevelItem->setHidden(!found); +// } +// +// // Unselect item if hidden: +// 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); +// } +//} +// +// IPlugin* PluginsSettingsTab::plugin(QTreeWidgetItem* pluginItem) const +//{ +// return static_cast(qvariant_cast(pluginItem->data(0, PluginRole))); +//} + +void ExtensionsSettingsTab::update() +{ + // transfer plugin settings to in-memory structure + // for (int i = 0; i < ui->pluginsList->topLevelItemCount(); ++i) { + // auto* topLevelItem = ui->pluginsList->topLevelItem(i); + // for (int j = 0; j < topLevelItem->childCount(); ++j) { + // auto* item = topLevelItem->child(j); + // settings().plugins().setSettings(plugin(item)->name(), + // item->data(0, SettingsRole).toMap()); + // } + //} + + // set plugin blacklist + QStringList names; + for (QListWidgetItem* item : ui->pluginBlacklist->findItems("*", Qt::MatchWildcard)) { + names.push_back(item->text()); + } + + settings().plugins().setBlacklist(names); + + settings().plugins().save(); +} + +void ExtensionsSettingsTab::closing() +{ + // storeSettings(ui->pluginsList->currentItem()); +} +// +// void PluginsSettingsTab::on_pluginsList_currentItemChanged(QTreeWidgetItem* current, +// QTreeWidgetItem* previous) +//{ +// storeSettings(previous); +// +// if (!current->data(0, PluginRole).isValid()) { +// return; +// } +// +// ui->pluginSettingsList->clear(); +// IPlugin* plugin = this->plugin(current); +// // ui->authorLabel->setText(plugin->author()); +// // 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_pluginManager->implementInterface(plugin) && +// // plugin->master().isEmpty()); +// +// bool enabled = m_pluginManager->isEnabled(plugin); +// auto& requirements = m_pluginManager->details(plugin); +// auto problems = requirements.problems(); +// +// // Plugin is enable or can be enabled. +// 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("
  • " + descriptions.join("
  • ") + +// "
"); +// } +// } +// +// QVariantMap settings = current->data(0, SettingsRole).toMap(); +// QVariantMap descriptions = current->data(0, DescriptionsRole).toMap(); +// ui->pluginSettingsList->setEnabled(settings.count() != 0); +// for (auto iter = settings.begin(); iter != settings.end(); ++iter) { +// QTreeWidgetItem* newItem = new QTreeWidgetItem(QStringList(iter.key())); +// QVariant value = *iter; +// QString description; +// { +// auto descriptionIter = descriptions.find(iter.key()); +// if (descriptionIter != descriptions.end()) { +// description = descriptionIter->toString(); +// } +// } +// +// ui->pluginSettingsList->setItemDelegateForColumn(0, new NoEditDelegate()); +// newItem->setData(1, Qt::DisplayRole, value); +// newItem->setData(1, Qt::EditRole, value); +// newItem->setToolTip(1, description); +// +// newItem->setFlags(newItem->flags() | Qt::ItemIsEditable); +// ui->pluginSettingsList->addTopLevelItem(newItem); +// } +// +// ui->pluginSettingsList->resizeColumnToContents(0); +// ui->pluginSettingsList->resizeColumnToContents(1); +//} +// +// void PluginsSettingsTab::deleteBlacklistItem() +//{ +// ui->pluginBlacklist->takeItem(ui->pluginBlacklist->currentIndex().row()); +//} +// +// void PluginsSettingsTab::storeSettings(QTreeWidgetItem* pluginItem) +//{ +// if (pluginItem != nullptr && pluginItem->data(0, PluginRole).isValid()) { +// QVariantMap settings = pluginItem->data(0, SettingsRole).toMap(); +// +// for (int i = 0; i < ui->pluginSettingsList->topLevelItemCount(); ++i) { +// const QTreeWidgetItem* item = ui->pluginSettingsList->topLevelItem(i); +// settings[item->text(0)] = item->data(1, Qt::DisplayRole); +// } +// +// pluginItem->setData(0, SettingsRole, settings); +// } +//} diff --git a/src/settingsdialogextensions.h b/src/settingsdialogextensions.h new file mode 100644 index 000000000..96eb6ceb3 --- /dev/null +++ b/src/settingsdialogextensions.h @@ -0,0 +1,60 @@ +#ifndef SETTINGSDIALOGEXTENSIONS_H +#define SETTINGSDIALOGEXTENSIONS_H + +#include "filterwidget.h" + +#include "settings.h" +#include "settingsdialog.h" + +#include "extensionmanager.h" +#include "pluginmanager.h" + +class ExtensionsSettingsTab : public SettingsTab +{ +public: + ExtensionsSettingsTab(Settings& settings, ExtensionManager& extensionManager, + PluginManager& pluginManager, SettingsDialog& dialog); + + void update(); + void closing() override; + + // private: + // void on_pluginsList_currentItemChanged(QListWidgetItem* current, + // QListWidgetItem* previous); + // void deleteBlacklistItem(); + // void storeSettings(QListWidgetItem* pluginItem); + +private slots: + + ///** + // * @brief Update the list item to display inactive plugins. + // */ + // void updateListItems(); + + ///** + // * @brief Filter the plugin list according to the filter widget. + // * + // */ + // void filterPluginList(); + + ///** + // * @brief Retrieve the plugin associated to the given item in the list. + // * + // */ + // MOBase::IPlugin* plugin(QListWidgetItem* pluginItem) const; + + enum + { + PluginRole = Qt::UserRole, + SettingsRole = Qt::UserRole + 1, + DescriptionsRole = Qt::UserRole + 2 + }; + +private: + ExtensionManager* m_extensionManager; + PluginManager* m_pluginManager; + + MOBase::FilterWidget m_filter; +}; + +#endif // SETTINGSDIALOGPLUGINS_H diff --git a/src/settingsdialogplugins.cpp b/src/settingsdialogplugins.cpp deleted file mode 100644 index 1a6d0c90d..000000000 --- a/src/settingsdialogplugins.cpp +++ /dev/null @@ -1,275 +0,0 @@ -#include "settingsdialogplugins.h" -#include "noeditdelegate.h" -#include "ui_settingsdialog.h" -#include - -#include "organizercore.h" -#include "pluginmanager.h" - -using namespace MOBase; - -struct PluginExtensionComparator -{ - bool operator()(const PluginExtension* lhs, const PluginExtension* rhs) const - { - return lhs->metadata().name().compare(rhs->metadata().name(), Qt::CaseInsensitive); - } -}; - -PluginsSettingsTab::PluginsSettingsTab(Settings& s, PluginManager& pluginManager, - SettingsDialog& d) - : SettingsTab(s, d), m_pluginManager(&pluginManager) -{ - ui->pluginSettingsList->setStyleSheet("QTreeWidget::item {padding-right: 10px;}"); - ui->pluginsList->setHeaderHidden(true); - - // display plugin settings - std::map, PluginExtensionComparator> - pluginsPerExtension; - - for (IPlugin* plugin : pluginManager.plugins()) { - pluginsPerExtension[&pluginManager.details(plugin).extension()].push_back(plugin); - } - - for (auto& [extension, plugins] : pluginsPerExtension) { - - QTreeWidgetItem* extensionItem = new QTreeWidgetItem(); - extensionItem->setData(0, Qt::DisplayRole, extension->metadata().name()); - ui->pluginsList->addTopLevelItem(extensionItem); - - for (auto* plugin : plugins) { - - // only show master - if (pluginManager.details(plugin).master() != plugin) { - continue; - } - - QTreeWidgetItem* pluginItem = new QTreeWidgetItem(extensionItem); - pluginItem->setData(0, Qt::DisplayRole, plugin->localizedName()); - } - } - - ui->pluginsList->sortByColumn(0, Qt::AscendingOrder); - - // display plugin blacklist - for (const QString& pluginName : settings().plugins().blacklist()) { - ui->pluginBlacklist->addItem(pluginName); - } - - m_filter.setEdit(ui->pluginFilterEdit); - - QObject::connect(ui->pluginsList, &QTreeWidget::currentItemChanged, - [&](auto* current, auto* previous) { - on_pluginsList_currentItemChanged(current, previous); - }); - - QShortcut* delShortcut = - new QShortcut(QKeySequence(Qt::Key_Delete), ui->pluginBlacklist); - QObject::connect(delShortcut, &QShortcut::activated, &dialog(), [&] { - deleteBlacklistItem(); - }); - 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_pluginManager->implementInterface(plugin) && - !m_pluginManager->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) { - auto* topLevelItem = ui->pluginsList->topLevelItem(i); - - bool found = false; - for (auto j = 0; j < topLevelItem->childCount(); ++j) { - auto* item = topLevelItem->child(j); - auto* plugin = this->plugin(item); - - // 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(); - }); - - if (match) { - found = true; - item->setHidden(false); - - if (firstNotHidden == nullptr) { - firstNotHidden = item; - } - } else { - item->setHidden(true); - } - } - - topLevelItem->setHidden(!found); - } - - // Unselect item if hidden: - 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); - } -} - -IPlugin* PluginsSettingsTab::plugin(QTreeWidgetItem* pluginItem) const -{ - return static_cast(qvariant_cast(pluginItem->data(0, PluginRole))); -} - -void PluginsSettingsTab::update() -{ - // transfer plugin settings to in-memory structure - // for (int i = 0; i < ui->pluginsList->topLevelItemCount(); ++i) { - // auto* topLevelItem = ui->pluginsList->topLevelItem(i); - // for (int j = 0; j < topLevelItem->childCount(); ++j) { - // auto* item = topLevelItem->child(j); - // settings().plugins().setSettings(plugin(item)->name(), - // item->data(0, SettingsRole).toMap()); - // } - //} - - // set plugin blacklist - QStringList names; - for (QListWidgetItem* item : ui->pluginBlacklist->findItems("*", Qt::MatchWildcard)) { - names.push_back(item->text()); - } - - settings().plugins().setBlacklist(names); - - settings().plugins().save(); -} - -void PluginsSettingsTab::closing() -{ - storeSettings(ui->pluginsList->currentItem()); -} - -void PluginsSettingsTab::on_pluginsList_currentItemChanged(QTreeWidgetItem* current, - QTreeWidgetItem* previous) -{ - storeSettings(previous); - - if (!current->data(0, PluginRole).isValid()) { - return; - } - - ui->pluginSettingsList->clear(); - IPlugin* plugin = this->plugin(current); - ui->authorLabel->setText(plugin->author()); - 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_pluginManager->implementInterface(plugin) && - plugin->master().isEmpty()); - - bool enabled = m_pluginManager->isEnabled(plugin); - auto& requirements = m_pluginManager->details(plugin); - auto problems = requirements.problems(); - - // Plugin is enable or can be enabled. - 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("
  • " + descriptions.join("
  • ") + - "
"); - } - } - - QVariantMap settings = current->data(0, SettingsRole).toMap(); - QVariantMap descriptions = current->data(0, DescriptionsRole).toMap(); - ui->pluginSettingsList->setEnabled(settings.count() != 0); - for (auto iter = settings.begin(); iter != settings.end(); ++iter) { - QTreeWidgetItem* newItem = new QTreeWidgetItem(QStringList(iter.key())); - QVariant value = *iter; - QString description; - { - auto descriptionIter = descriptions.find(iter.key()); - if (descriptionIter != descriptions.end()) { - description = descriptionIter->toString(); - } - } - - ui->pluginSettingsList->setItemDelegateForColumn(0, new NoEditDelegate()); - newItem->setData(1, Qt::DisplayRole, value); - newItem->setData(1, Qt::EditRole, value); - newItem->setToolTip(1, description); - - newItem->setFlags(newItem->flags() | Qt::ItemIsEditable); - ui->pluginSettingsList->addTopLevelItem(newItem); - } - - ui->pluginSettingsList->resizeColumnToContents(0); - ui->pluginSettingsList->resizeColumnToContents(1); -} - -void PluginsSettingsTab::deleteBlacklistItem() -{ - ui->pluginBlacklist->takeItem(ui->pluginBlacklist->currentIndex().row()); -} - -void PluginsSettingsTab::storeSettings(QTreeWidgetItem* pluginItem) -{ - if (pluginItem != nullptr && pluginItem->data(0, PluginRole).isValid()) { - QVariantMap settings = pluginItem->data(0, SettingsRole).toMap(); - - for (int i = 0; i < ui->pluginSettingsList->topLevelItemCount(); ++i) { - const QTreeWidgetItem* item = ui->pluginSettingsList->topLevelItem(i); - settings[item->text(0)] = item->data(1, Qt::DisplayRole); - } - - pluginItem->setData(0, SettingsRole, settings); - } -} diff --git a/src/settingsdialogplugins.h b/src/settingsdialogplugins.h deleted file mode 100644 index 218bd7469..000000000 --- a/src/settingsdialogplugins.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef SETTINGSDIALOGPLUGINS_H -#define SETTINGSDIALOGPLUGINS_H - -#include "filterwidget.h" - -#include "settings.h" -#include "settingsdialog.h" - -class PluginsSettingsTab : public SettingsTab -{ -public: - PluginsSettingsTab(Settings& settings, PluginManager& pluginManager, - SettingsDialog& dialog); - - void update(); - void closing() override; - -private: - void on_pluginsList_currentItemChanged(QTreeWidgetItem* current, - QTreeWidgetItem* previous); - void deleteBlacklistItem(); - void storeSettings(QTreeWidgetItem* pluginItem); - -private slots: - - /** - * @brief Update the list item to display inactive plugins. - */ - void updateListItems(); - - /** - * @brief Filter the plugin list according to the filter widget. - * - */ - void filterPluginList(); - - /** - * @brief Retrieve the plugin associated to the given item in the list. - * - */ - MOBase::IPlugin* plugin(QTreeWidgetItem* pluginItem) const; - - enum - { - PluginRole = Qt::UserRole, - SettingsRole = Qt::UserRole + 1, - DescriptionsRole = Qt::UserRole + 2 - }; - -private: - PluginManager* m_pluginManager; - - MOBase::FilterWidget m_filter; -}; - -#endif // SETTINGSDIALOGPLUGINS_H