From 74ec078976fbd64433142e6974f30cc113047c00 Mon Sep 17 00:00:00 2001 From: Mikaël Capelle Date: Tue, 10 Nov 2020 21:38:58 +0100 Subject: Replace usage of IPlugin::isActive(). --- src/mainwindow.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/mainwindow.cpp') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 94bc5800..93ca415d 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1132,7 +1132,7 @@ void MainWindow::checkForProblemsImpl() size_t numProblems = 0; for (QObject *pluginObj : m_PluginContainer.plugins()) { IPlugin *plugin = qobject_cast(pluginObj); - if (plugin == nullptr || plugin->isActive()) { + if (plugin == nullptr || m_PluginContainer.isEnabled(plugin)) { IPluginDiagnose *diagnose = qobject_cast(pluginObj); if (diagnose != nullptr) numProblems += diagnose->activeProblems().size(); @@ -1663,9 +1663,11 @@ void MainWindow::registerPluginTools(std::vector toolPlugins) } ); + // TODO: I don't know when this method is called? Maybe the check should be perform when + // the context menu is opened? // Remove inactive plugins toolPlugins.erase( - std::remove_if(toolPlugins.begin(), toolPlugins.end(), [](IPluginTool *plugin) -> bool { return !plugin->isActive(); }), + std::remove_if(toolPlugins.begin(), toolPlugins.end(), [this](IPluginTool *plugin) { return !m_PluginContainer.isEnabled(plugin); }), toolPlugins.end() ); @@ -5972,7 +5974,7 @@ void MainWindow::on_actionNotifications_triggered() future.waitForFinished(); - ProblemsDialog problems(m_PluginContainer.plugins(), this); + ProblemsDialog problems(m_PluginContainer, this); problems.exec(); scheduleCheckForProblems(); -- cgit v1.3.1 From f53d04a84d148a771dab3de9fe5f2f28e2d0240d Mon Sep 17 00:00:00 2001 From: Mikaël Capelle Date: Wed, 11 Nov 2020 14:08:11 +0100 Subject: Hide Tool action instead of not adding them. --- src/mainwindow.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'src/mainwindow.cpp') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 93ca415d..9bbe3da9 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1652,6 +1652,9 @@ void MainWindow::registerPluginTool(IPluginTool *tool, QString name, QMenu *menu connect(action, SIGNAL(triggered()), this, SLOT(toolPluginInvoke()), Qt::QueuedConnection); menu->addAction(action); + if (!m_PluginContainer.isEnabled(tool)) { + action->setVisible(false); + } } void MainWindow::registerPluginTools(std::vector toolPlugins) @@ -1663,14 +1666,6 @@ void MainWindow::registerPluginTools(std::vector toolPlugins) } ); - // TODO: I don't know when this method is called? Maybe the check should be perform when - // the context menu is opened? - // Remove inactive plugins - toolPlugins.erase( - std::remove_if(toolPlugins.begin(), toolPlugins.end(), [this](IPluginTool *plugin) { return !m_PluginContainer.isEnabled(plugin); }), - toolPlugins.end() - ); - // Group the plugins into submenus QMap>> submenuMap; for (auto toolPlugin : toolPlugins) { -- cgit v1.3.1 From e528d8b0ad843bf2e728f26c3a1bade145e5ad07 Mon Sep 17 00:00:00 2001 From: Mikaël Capelle Date: Wed, 11 Nov 2020 14:59:11 +0100 Subject: Fix display of tools in the MainWindow menu. --- src/iuserinterface.h | 2 -- src/mainwindow.cpp | 51 ++++++++++++++++++++++--------------------- src/mainwindow.h | 9 ++++---- src/plugincontainer.cpp | 4 ---- src/settingsdialogplugins.cpp | 9 ++++---- 5 files changed, 34 insertions(+), 41 deletions(-) (limited to 'src/mainwindow.cpp') diff --git a/src/iuserinterface.h b/src/iuserinterface.h index cce89070..a2a91e62 100644 --- a/src/iuserinterface.h +++ b/src/iuserinterface.h @@ -13,8 +13,6 @@ class IUserInterface { public: - virtual void registerPluginTool(MOBase::IPluginTool *tool, QString name = QString(), QMenu *menu = nullptr) = 0; - virtual void registerPluginTools(std::vector toolPlugins) = 0; virtual void registerModPage(MOBase::IPluginModPage *modPage) = 0; virtual void installTranslator(const QString &name) = 0; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 9bbe3da9..b5a6382f 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -467,6 +467,7 @@ MainWindow::MainWindow(Settings &settings connect(ui->toolBar, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(toolBar_customContextMenuRequested(QPoint))); connect(ui->menuToolbars, &QMenu::aboutToShow, [&]{ updateToolbarMenu(); }); connect(ui->menuView, &QMenu::aboutToShow, [&]{ updateViewMenu(); }); + connect(ui->actionTool->menu(), &QMenu::aboutToShow, [&] { updateToolMenu(); }); connect(&m_OrganizerCore, &OrganizerCore::modInstalled, this, &MainWindow::modInstalled); connect(&m_OrganizerCore, &OrganizerCore::close, this, &QMainWindow::close); @@ -508,8 +509,6 @@ MainWindow::MainWindow(Settings &settings installTranslator(QFileInfo(fileName).baseName()); } - registerPluginTools(m_PluginContainer.plugins()); - for (IPluginModPage *modPagePlugin : m_PluginContainer.plugins()) { registerModPage(modPagePlugin); } @@ -1597,22 +1596,6 @@ bool MainWindow::eventFilter(QObject *object, QEvent *event) return false; } - -void MainWindow::toolPluginInvoke() -{ - QAction *triggeredAction = qobject_cast(sender()); - IPluginTool *plugin = qobject_cast(triggeredAction->data().value()); - if (plugin != nullptr) { - try { - plugin->display(); - } catch (const std::exception &e) { - reportError(tr("Plugin \"%1\" failed: %2").arg(plugin->name()).arg(e.what())); - } catch (...) { - reportError(tr("Plugin \"%1\" failed").arg(plugin->name())); - } - } -} - void MainWindow::modPagePluginInvoke() { QAction *triggeredAction = qobject_cast(sender()); @@ -1648,24 +1631,42 @@ void MainWindow::registerPluginTool(IPluginTool *tool, QString name, QMenu *menu QAction *action = new QAction(tool->icon(), name, menu); action->setToolTip(tool->tooltip()); tool->setParentWidget(this); - action->setData(QVariant::fromValue((QObject*)tool)); - connect(action, SIGNAL(triggered()), this, SLOT(toolPluginInvoke()), Qt::QueuedConnection); + connect(action, &QAction::triggered, this, [this, tool]() { + try { + tool->display(); + } + catch (const std::exception& e) { + reportError(tr("Plugin \"%1\" failed: %2").arg(tool->localizedName()).arg(e.what())); + } + catch (...) { + reportError(tr("Plugin \"%1\" failed").arg(tool->localizedName())); + } + }, Qt::QueuedConnection); menu->addAction(action); - if (!m_PluginContainer.isEnabled(tool)) { - action->setVisible(false); - } } -void MainWindow::registerPluginTools(std::vector toolPlugins) +void MainWindow::updateToolMenu() { + // Clear the menu: + ui->actionTool->menu()->clear(); + + std::vector toolPlugins = m_PluginContainer.plugins(); + // Sort the plugins by display name - std::sort(toolPlugins.begin(), toolPlugins.end(), + std::sort(std::begin(toolPlugins), std::end(toolPlugins), [](IPluginTool *left, IPluginTool *right) { return left->displayName().toLower() < right->displayName().toLower(); } ); + // Remove disabled plugins: + toolPlugins.erase( + std::remove_if(std::begin(toolPlugins), std::end(toolPlugins), [&](auto* tool) { + return !m_PluginContainer.isEnabled(tool); + }), + toolPlugins.end()); + // Group the plugins into submenus QMap>> submenuMap; for (auto toolPlugin : toolPlugins) { diff --git a/src/mainwindow.h b/src/mainwindow.h index 8b2188c8..d4aa0bc2 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -129,10 +129,6 @@ public: void saveArchiveList(); - void registerPluginTool(MOBase::IPluginTool *tool, QString name = QString(), QMenu *menu = nullptr); - void registerPluginTools(std::vector toolPlugins); - void registerModPage(MOBase::IPluginModPage *modPage); - void addPrimaryCategoryCandidates(QMenu *primaryCategoryMenu, ModInfo::Ptr info); void installTranslator(const QString &name); @@ -160,7 +156,6 @@ public slots: void directory_refreshed(); - void toolPluginInvoke(); void modPagePluginInvoke(); signals: @@ -212,7 +207,11 @@ private: void setToolbarSize(const QSize& s); void setToolbarButtonStyle(Qt::ToolButtonStyle s); + void registerModPage(MOBase::IPluginModPage* modPage); + void registerPluginTool(MOBase::IPluginTool* tool, QString name = QString(), QMenu* menu = nullptr); + void updateToolbarMenu(); + void updateToolMenu(); void updateViewMenu(); QMenu* createPopupMenu() override; diff --git a/src/plugincontainer.cpp b/src/plugincontainer.cpp index 021fe3c8..030fdb31 100644 --- a/src/plugincontainer.cpp +++ b/src/plugincontainer.cpp @@ -180,10 +180,6 @@ void PluginContainer::setUserInterface(IUserInterface *userInterface, QWidget *w for (IPluginModPage *modPage : bf::at_key(m_Plugins)) { userInterface->registerModPage(modPage); } - - for (IPluginTool *tool : bf::at_key(m_Plugins)) { - userInterface->registerPluginTool(tool); - } } m_UserInterface = userInterface; diff --git a/src/settingsdialogplugins.cpp b/src/settingsdialogplugins.cpp index 8a70475c..0c02ffb0 100644 --- a/src/settingsdialogplugins.cpp +++ b/src/settingsdialogplugins.cpp @@ -88,10 +88,9 @@ void PluginsSettingsTab::updateListItems() auto* item = topLevelItem->child(j); auto* plugin = this->plugin(item); - if (!m_pluginContainer->implementInterface(plugin) - && !m_pluginContainer->isEnabled(plugin)) { - item->setBackgroundColor(0, Qt::gray); - } + bool inactive = !m_pluginContainer->implementInterface(plugin) + && !m_pluginContainer->isEnabled(plugin); + // TODO: Better display. } } @@ -198,7 +197,7 @@ void PluginsSettingsTab::on_checkboxEnabled_clicked(bool checked) return; } - m_pluginContainer->setEnabled(plugin, false, true); + m_pluginContainer->setEnabled(plugin, true, false); } else { // Custom check for proxy + current game: -- cgit v1.3.1 From fe6654f89220c6739405ff7d9a54bc49f92a4c5b Mon Sep 17 00:00:00 2001 From: Mikaël Capelle Date: Fri, 13 Nov 2020 13:04:22 +0100 Subject: Better 'Browse Mod Page' menu. --- src/mainwindow.cpp | 56 +++++++++++++++++++++--------------------------------- src/mainwindow.h | 4 ---- src/mainwindow.ui | 22 +++++++++++++++++++++ 3 files changed, 44 insertions(+), 38 deletions(-) (limited to 'src/mainwindow.cpp') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index b5a6382f..d20fd3ba 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -260,7 +260,6 @@ MainWindow::MainWindow(Settings &settings , m_ContextItem(nullptr) , m_ContextAction(nullptr) , m_ContextRow(-1) - , m_browseModPage(nullptr) , m_CurrentSaveView(nullptr) , m_OrganizerCore(organizerCore) , m_PluginContainer(pluginContainer) @@ -811,6 +810,7 @@ static QModelIndex mapToModel(const QAbstractItemModel *targetModel, QModelIndex void MainWindow::setupToolbar() { + setupActionMenu(ui->actionModPage); setupActionMenu(ui->actionTool); setupActionMenu(ui->actionHelp); setupActionMenu(ui->actionEndorseMO); @@ -1596,29 +1596,6 @@ bool MainWindow::eventFilter(QObject *object, QEvent *event) return false; } -void MainWindow::modPagePluginInvoke() -{ - QAction *triggeredAction = qobject_cast(sender()); - IPluginModPage *plugin = qobject_cast(triggeredAction->data().value()); - if (plugin != nullptr) { - if (plugin->useIntegratedBrowser()) { - - if (!m_IntegratedBrowser) { - m_IntegratedBrowser.reset(new BrowserDialog); - - connect( - m_IntegratedBrowser.get(), SIGNAL(requestDownload(QUrl,QNetworkReply*)), - &m_OrganizerCore, SLOT(requestDownload(QUrl,QNetworkReply*))); - } - - m_IntegratedBrowser->setWindowTitle(plugin->displayName()); - m_IntegratedBrowser->openUrl(plugin->pageURL()); - } else { - QDesktopServices::openUrl(QUrl(plugin->pageURL())); - } - } -} - void MainWindow::registerPluginTool(IPluginTool *tool, QString name, QMenu *menu) { if (!menu) { @@ -1694,23 +1671,34 @@ void MainWindow::updateToolMenu() void MainWindow::registerModPage(IPluginModPage *modPage) { // turn the browser action into a drop-down menu if necessary - if (!m_browseModPage) { - m_browseModPage = new QAction(ui->actionNexus->icon(), tr("Browse Mod Page"), this); - setupActionMenu(m_browseModPage); - - m_browseModPage->menu()->addAction(ui->actionNexus); - - ui->toolBar->insertAction(ui->actionNexus, m_browseModPage); + if (!ui->actionModPage->isVisible()) { ui->toolBar->removeAction(ui->actionNexus); + ui->actionModPage->menu()->addAction(ui->actionNexus); + ui->actionModPage->setVisible(true); } QAction *action = new QAction(modPage->icon(), modPage->displayName(), this); modPage->setParentWidget(this); - action->setData(QVariant::fromValue(reinterpret_cast(modPage))); + connect(action, &QAction::triggered, this, [this, modPage]() { + if (modPage->useIntegratedBrowser()) { + + if (!m_IntegratedBrowser) { + m_IntegratedBrowser.reset(new BrowserDialog); + + connect( + m_IntegratedBrowser.get(), SIGNAL(requestDownload(QUrl, QNetworkReply*)), + &m_OrganizerCore, SLOT(requestDownload(QUrl, QNetworkReply*))); + } - connect(action, SIGNAL(triggered()), this, SLOT(modPagePluginInvoke()), Qt::QueuedConnection); + m_IntegratedBrowser->setWindowTitle(modPage->displayName()); + m_IntegratedBrowser->openUrl(modPage->pageURL()); + } + else { + QDesktopServices::openUrl(QUrl(modPage->pageURL())); + } + }, Qt::QueuedConnection); - m_browseModPage->menu()->addAction(action); + ui->actionModPage->menu()->addAction(action); } diff --git a/src/mainwindow.h b/src/mainwindow.h index d4aa0bc2..78ffec47 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -156,8 +156,6 @@ public slots: void directory_refreshed(); - void modPagePluginInvoke(); - signals: /** @@ -325,8 +323,6 @@ private: QTreeWidgetItem *m_ContextItem; QAction *m_ContextAction; - QAction* m_browseModPage; - CategoryFactory &m_CategoryFactory; QTimer m_CheckBSATimer; diff --git a/src/mainwindow.ui b/src/mainwindow.ui index ace0dfeb..dbc6013d 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1411,6 +1411,7 @@ p, li { white-space: pre-wrap; } + @@ -1684,6 +1685,27 @@ p, li { white-space: pre-wrap; } Ctrl+N + + + + :/MO/gui/resources/internet-web-browser.png:/MO/gui/resources/internet-web-browser.png + + + Browse Mod Page + + + Browse Mod Page + + + Browse Mod Page + + + Browse Mod Page + + + false + + false -- cgit v1.3.1 From 4d94ba8dbba20da6d030a8a3adf73d2dbd6fc56f Mon Sep 17 00:00:00 2001 From: Mikaël Capelle Date: Fri, 13 Nov 2020 13:18:05 +0100 Subject: Proper handling of mod pages. --- src/mainwindow.cpp | 51 +++++++++++++++++++++++++++++++++++++++++---------- src/mainwindow.h | 1 + 2 files changed, 42 insertions(+), 10 deletions(-) (limited to 'src/mainwindow.cpp') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index d20fd3ba..c927a691 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -467,6 +467,11 @@ MainWindow::MainWindow(Settings &settings connect(ui->menuToolbars, &QMenu::aboutToShow, [&]{ updateToolbarMenu(); }); connect(ui->menuView, &QMenu::aboutToShow, [&]{ updateViewMenu(); }); connect(ui->actionTool->menu(), &QMenu::aboutToShow, [&] { updateToolMenu(); }); + connect(&m_PluginContainer, &PluginContainer::pluginEnabled, this, [this](IPlugin* plugin) { + if (m_PluginContainer.implementInterface(plugin)) { updateModPageMenu(); } }); + connect(&m_PluginContainer, &PluginContainer::pluginDisabled, this, [this](IPlugin* plugin) { + if (m_PluginContainer.implementInterface(plugin)) { updateModPageMenu(); } }); + connect(&m_OrganizerCore, &OrganizerCore::modInstalled, this, &MainWindow::modInstalled); connect(&m_OrganizerCore, &OrganizerCore::close, this, &QMainWindow::close); @@ -508,9 +513,7 @@ MainWindow::MainWindow(Settings &settings installTranslator(QFileInfo(fileName).baseName()); } - for (IPluginModPage *modPagePlugin : m_PluginContainer.plugins()) { - registerModPage(modPagePlugin); - } + updateModPageMenu(); // refresh profiles so the current profile can be activated refreshProfiles(false); @@ -1670,13 +1673,6 @@ void MainWindow::updateToolMenu() void MainWindow::registerModPage(IPluginModPage *modPage) { - // turn the browser action into a drop-down menu if necessary - if (!ui->actionModPage->isVisible()) { - ui->toolBar->removeAction(ui->actionNexus); - ui->actionModPage->menu()->addAction(ui->actionNexus); - ui->actionModPage->setVisible(true); - } - QAction *action = new QAction(modPage->icon(), modPage->displayName(), this); modPage->setParentWidget(this); connect(action, &QAction::triggered, this, [this, modPage]() { @@ -1701,6 +1697,41 @@ void MainWindow::registerModPage(IPluginModPage *modPage) ui->actionModPage->menu()->addAction(action); } +void MainWindow::updateModPageMenu() +{ + // Clear the menu: + ui->actionModPage->menu()->clear(); + ui->actionModPage->menu()->addAction(ui->actionNexus); + + std::vector modPagePlugins = m_PluginContainer.plugins(); + + // Sort the plugins by display name + std::sort(std::begin(modPagePlugins), std::end(modPagePlugins), + [](IPluginModPage* left, IPluginModPage* right) { + return left->displayName().toLower() < right->displayName().toLower(); + } + ); + + // Remove disabled plugins: + modPagePlugins.erase( + std::remove_if(std::begin(modPagePlugins), std::end(modPagePlugins), [&](auto* tool) { + return !m_PluginContainer.isEnabled(tool); + }), + modPagePlugins.end()); + + for (auto* modPagePlugin : modPagePlugins) { + registerModPage(modPagePlugin); + } + + // No mod page plugin and the menu was visible: + if (modPagePlugins.empty()) { + ui->toolBar->insertAction(ui->actionAdd_Profile, ui->actionNexus); + } + else { + ui->toolBar->removeAction(ui->actionNexus); + } + ui->actionModPage->setVisible(!modPagePlugins.empty()); +} void MainWindow::startExeAction() { diff --git a/src/mainwindow.h b/src/mainwindow.h index 78ffec47..e2805b25 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -210,6 +210,7 @@ private: void updateToolbarMenu(); void updateToolMenu(); + void updateModPageMenu(); void updateViewMenu(); QMenu* createPopupMenu() override; -- cgit v1.3.1 From e39de4dd2ab6c19c6b9557f99117f7ffc9ed1cc1 Mon Sep 17 00:00:00 2001 From: Mikaël Capelle Date: Wed, 18 Nov 2020 19:22:05 +0100 Subject: Update following addition of IPluginGame::listSaves(). --- src/mainwindow.cpp | 53 +++++++--------------- src/mainwindow.h | 1 + src/transfersavesdialog.cpp | 105 ++++---------------------------------------- src/transfersavesdialog.h | 7 +-- 4 files changed, 30 insertions(+), 136 deletions(-) (limited to 'src/mainwindow.cpp') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index c2aefdd2..ecb4319b 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1206,7 +1206,7 @@ void MainWindow::createHelpMenu() ActionList tutorials; - QString tutorialPath = QApplication::applicationDirPath() + QString tutorialPath = QApplication::applicationDirPath() + "/" + QString::fromStdWString(AppConfig::tutorialsPath()) + "/"; QDirIterator dirIter(tutorialPath, QStringList("*.js"), QDir::Files); while (dirIter.hasNext()) { @@ -1532,7 +1532,6 @@ void MainWindow::displaySaveGameInfo(QListWidgetItem *newItem) return; } - QString const &save = newItem->data(Qt::UserRole).toString(); if (m_CurrentSaveView == nullptr) { IPluginGame const *game = m_OrganizerCore.managedGame(); SaveGameInfo const *info = game->feature(); @@ -1543,7 +1542,7 @@ void MainWindow::displaySaveGameInfo(QListWidgetItem *newItem) return; } } - m_CurrentSaveView->setSave(save); + m_CurrentSaveView->setSave(*m_SaveGames[ui->savegameList->row(newItem)]); QWindow *window = m_CurrentSaveView->window()->windowHandle(); QRect screenRect; @@ -1964,36 +1963,23 @@ void MainWindow::stopMonitorSaves() void MainWindow::refreshSaveList() { - ui->savegameList->clear(); + TimeThis tt("MainWindow::refreshSaveList()"); startMonitorSaves(); // re-starts monitoring - QStringList filters; - filters << QString("*.") + m_OrganizerCore.managedGame()->savegameExtension(); - QDir savesDir = currentSavesDir(); - savesDir.setNameFilters(filters); - savesDir.setFilter(QDir::Files); - QDirIterator it(savesDir, QDirIterator::Subdirectories); - log::debug("reading save games from {}", savesDir.absolutePath()); - - QFileInfoList files; - while (it.hasNext()) { - it.next(); - files.append(it.fileInfo()); - } - std::sort(files.begin(), files.end(), [](auto const& lhs, auto const& rhs) { - return lhs.fileTime(QFileDevice::FileModificationTime) > rhs.fileTime(QFileDevice::FileModificationTime); + MOBase::log::debug("reading save games from {}", savesDir.absolutePath()); + m_SaveGames = m_OrganizerCore.managedGame()->listSaves(savesDir); + std::sort(m_SaveGames.begin(), m_SaveGames.end(), [](auto const& lhs, auto const& rhs) { + return lhs->getCreationTime() > rhs->getCreationTime(); }); - for (const QFileInfo &file : files) { - QListWidgetItem *item = new QListWidgetItem(savesDir.relativeFilePath(file.absoluteFilePath())); - item->setData(Qt::UserRole, file.absoluteFilePath()); - ui->savegameList->addItem(item); + ui->savegameList->clear(); + for (auto& save: m_SaveGames) { + ui->savegameList->addItem(savesDir.relativeFilePath(save->getFilepath())); } } - static bool BySortValue(const std::pair &LHS, const std::pair &RHS) { return LHS.first < RHS.first; @@ -4960,20 +4946,15 @@ void MainWindow::deleteSavegame_clicked() int count = 0; for (const QModelIndex &idx : ui->savegameList->selectionModel()->selectedIndexes()) { - QString name = idx.data(Qt::UserRole).toString(); + + auto& saveGame = m_SaveGames[idx.row()]; if (count < 10) { - savesMsgLabel += "
  • " + QFileInfo(name).completeBaseName() + "
  • "; + savesMsgLabel += "
  • " + QFileInfo(saveGame->getFilepath()).completeBaseName() + "
  • "; } ++count; - if (info == nullptr) { - deleteFiles.push_back(name); - } else { - ISaveGame const *save = info->getSaveGameInfo(name); - deleteFiles += save->allFiles(); - delete save; - } + deleteFiles += saveGame->allFiles(); } if (count > 10) { @@ -5032,8 +5013,8 @@ void MainWindow::on_savegameList_customContextMenuRequested(const QPoint& pos) QAction* action = menu.addAction(tr("Enable Mods...")); action->setEnabled(false); if (selection->selectedIndexes().count() == 1) { - QString save = ui->savegameList->currentItem()->data(Qt::UserRole).toString(); - SaveGameInfo::MissingAssets missing = info->getMissingAssets(save); + auto& save = m_SaveGames[selection->selectedIndexes()[0].row()]; + SaveGameInfo::MissingAssets missing = info->getMissingAssets(*save); if (missing.size() != 0) { connect(action, &QAction::triggered, this, [this, missing] { fixMods_clicked(missing); }); action->setEnabled(true); @@ -5229,7 +5210,7 @@ void MainWindow::installTranslator(const QString &name) { QTranslator *translator = new QTranslator(this); QString fileName = name + "_" + m_CurrentLanguage; - QString translationsPath = qApp->applicationDirPath() + QString translationsPath = qApp->applicationDirPath() + "/" + QString::fromStdWString(AppConfig::translationsPath()); if (!translator->load(fileName, translationsPath)) { if (m_CurrentLanguage.contains(QRegularExpression("^.*_(EN|en)(-.*)?$"))) { diff --git a/src/mainwindow.h b/src/mainwindow.h index e2805b25..da916d2a 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -334,6 +334,7 @@ private: QTime m_StartTime; //SaveGameInfoWidget *m_CurrentSaveView; + std::vector> m_SaveGames; MOBase::ISaveGameInfoWidget *m_CurrentSaveView; OrganizerCore &m_OrganizerCore; diff --git a/src/transfersavesdialog.cpp b/src/transfersavesdialog.cpp index f8ebbb9d..5288d408 100644 --- a/src/transfersavesdialog.cpp +++ b/src/transfersavesdialog.cpp @@ -42,74 +42,6 @@ along with Mod Organizer. If not, see . using namespace MOBase; using namespace MOShared; -//These two classes give the save-transfer box a smidgin of useful info even -//if save game isn't supported yet. -namespace { - -class DummySave : public ISaveGame -{ -public: - DummySave(QString const &filename) : - m_File(filename) - {} - - ~DummySave() {} - - virtual QString getFilename() const override - { - return m_File; - } - - virtual QDateTime getCreationTime() const override - { - return QFileInfo(m_File).birthTime(); - } - - virtual QString getSaveGroupIdentifier() const override - { - return m_File; - } - - virtual QStringList allFiles() const override - { - return { m_File }; - } - - virtual bool hasScriptExtenderFile() const override - { - return false; - } - -private: - QString m_File; -}; - -class DummyInfo : public SaveGameInfo -{ -public: - virtual MOBase::ISaveGame const *getSaveGameInfo(QString const &file) const override - { - return new DummySave(file); - } - - virtual MissingAssets getMissingAssets(QString const &) const override - { - return {}; - } - - MOBase::ISaveGameInfoWidget *getSaveGameWidget(QWidget *) const override - { - return nullptr; - } - - virtual bool hasScriptExtenderSave(QString const &file) const override - { - return false; - } -}; - -} //end anonymous namespace - TransferSavesDialog::TransferSavesDialog(const Profile &profile, IPluginGame const *gamePlugin, QWidget *parent) : TutorableDialog("TransferSaves", parent) , ui(new Ui::TransferSavesDialog) @@ -263,7 +195,7 @@ void TransferSavesDialog::on_globalCharacterList_currentTextChanged(const QStrin SaveCollection::const_iterator saveList = m_GlobalSaves.find(currentText); if (saveList != m_GlobalSaves.end()) { for (SaveListItem const &save : saveList->second) { - ui->globalSavesList->addItem(QFileInfo(save->getFilename()).fileName()); + ui->globalSavesList->addItem(QFileInfo(save->getFilepath()).fileName()); } } } @@ -276,7 +208,7 @@ void TransferSavesDialog::on_localCharacterList_currentTextChanged(const QString SaveCollection::const_iterator saveList = m_LocalSaves.find(currentText); if (saveList != m_LocalSaves.end()) { for (SaveListItem const &save : saveList->second) { - ui->localSavesList->addItem(QFileInfo(save->getFilename()).fileName()); + ui->localSavesList->addItem(QFileInfo(save->getFilepath()).fileName()); } } } @@ -285,34 +217,13 @@ void TransferSavesDialog::refreshSaves(SaveCollection &saveCollection, QString c { saveCollection.clear(); - SaveGameInfo const *info = m_GamePlugin->feature(); - if (info == nullptr) { - static DummyInfo dummyInfo; - info = &dummyInfo; - } - - QStringList filters; - filters << QString("*.") + m_GamePlugin->savegameExtension(); - - QDir savesDir(savedir); - savesDir.setNameFilters(QStringList() << QString("*.") + m_GamePlugin->savegameExtension()); - savesDir.setFilter(QDir::Files); - QDirIterator it(savesDir, QDirIterator::Subdirectories); - log::debug("reading save games from {}", savesDir.absolutePath()); - - QFileInfoList files; - while (it.hasNext()) { - it.next(); - files.append(it.fileInfo()); - } - std::sort(files.begin(), files.end(), [](auto const& lhs, auto const& rhs) { - return lhs.fileTime(QFileDevice::FileModificationTime) < rhs.fileTime(QFileDevice::FileModificationTime); + auto saves = m_GamePlugin->listSaves(savedir); + std::sort(saves.begin(), saves.end(), [](auto const& lhs, auto const& rhs) { + return lhs->getCreationTime() > rhs->getCreationTime(); }); - for (const QFileInfo &file: files) { - MOBase::ISaveGame const *save = info->getSaveGameInfo(file.absoluteFilePath()); - saveCollection[save->getSaveGroupIdentifier()].push_back( - std::unique_ptr(save)); + for (auto& save: saves) { + saveCollection[save->getSaveGroupIdentifier()].push_back(save); } } @@ -334,7 +245,7 @@ void TransferSavesDialog::refreshCharacters(const SaveCollection &saveCollection } bool TransferSavesDialog::transferCharacters( - QString const &character, char const *message, + QString const &character, char const *message, QDir const& sourceDirectory, SaveList &saves, QDir const& destination, diff --git a/src/transfersavesdialog.h b/src/transfersavesdialog.h index b983ad9e..fe78aa83 100644 --- a/src/transfersavesdialog.h +++ b/src/transfersavesdialog.h @@ -80,9 +80,10 @@ private: MOBase::IPluginGame const *m_GamePlugin; - typedef std::unique_ptr SaveListItem; - typedef std::vector SaveList; - typedef std::map SaveCollection; + using SaveListItem = std::shared_ptr; + using SaveList = std::vector; + using SaveCollection = std::map; + SaveCollection m_GlobalSaves; SaveCollection m_LocalSaves; -- cgit v1.3.1 From 0a912afe72a8fb765f240d59db17f7b50094b014 Mon Sep 17 00:00:00 2001 From: Mikaël Capelle Date: Sat, 21 Nov 2020 12:13:20 +0100 Subject: Add timer to the save list watcher to avoid error during refresh. --- src/mainwindow.cpp | 5 ++++- src/mainwindow.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src/mainwindow.cpp') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index ecb4319b..04833e6a 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -430,7 +430,10 @@ MainWindow::MainWindow(Settings &settings this, &MainWindow::refresherProgress); connect(m_OrganizerCore.directoryRefresher(), SIGNAL(error(QString)), this, SLOT(showError(QString))); - connect(&m_SavesWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(refreshSavesIfOpen())); + m_SavesWatcherTimer.setSingleShot(true); + m_SavesWatcherTimer.setInterval(500); + connect(&m_SavesWatcher, &QFileSystemWatcher::directoryChanged, [this]() { m_SavesWatcherTimer.start(); }); + connect(&m_SavesWatcherTimer, &QTimer::timeout, this, &MainWindow::refreshSavesIfOpen); connect(&m_OrganizerCore.settings(), SIGNAL(languageChanged(QString)), this, SLOT(languageChange(QString))); connect(&m_OrganizerCore.settings(), SIGNAL(styleChanged(QString)), this, SIGNAL(styleChanged(QString))); diff --git a/src/mainwindow.h b/src/mainwindow.h index da916d2a..da7bb6ee 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -345,6 +345,7 @@ private: std::unique_ptr m_IntegratedBrowser; + QTimer m_SavesWatcherTimer; QFileSystemWatcher m_SavesWatcher; QByteArray m_ArchiveListHash; -- cgit v1.3.1 From f3f0036a056b17ed481cf3ec4dea78a59c04b16e Mon Sep 17 00:00:00 2001 From: Mikaël Capelle Date: Mon, 23 Nov 2020 15:30:21 +0100 Subject: Fix PluginContainer::setUserInterface(). --- src/mainwindow.cpp | 4 ++-- src/modinfowithconflictinfo.cpp | 4 ++-- src/modinfowithconflictinfo.h | 4 +++- src/plugincontainer.cpp | 18 ++++++++++-------- src/plugincontainer.h | 2 +- 5 files changed, 18 insertions(+), 14 deletions(-) (limited to 'src/mainwindow.cpp') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 04833e6a..7558076d 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -511,6 +511,7 @@ MainWindow::MainWindow(Settings &settings m_Tutorial.expose("espList", m_OrganizerCore.pluginList()); m_OrganizerCore.setUserInterface(this); + m_PluginContainer.setUserInterface(this); connect(this, &MainWindow::userInterfaceInitialized, &m_OrganizerCore, &OrganizerCore::userInterfaceInitialized); for (const QString &fileName : m_PluginContainer.pluginFileNames()) { installTranslator(QFileInfo(fileName).baseName()); @@ -703,7 +704,7 @@ MainWindow::~MainWindow() try { cleanup(); - m_PluginContainer.setUserInterface(nullptr, nullptr); + m_PluginContainer.setUserInterface(nullptr); m_OrganizerCore.setUserInterface(nullptr); if (m_IntegratedBrowser) { @@ -1679,7 +1680,6 @@ void MainWindow::updateToolMenu() void MainWindow::registerModPage(IPluginModPage *modPage) { QAction *action = new QAction(modPage->icon(), modPage->displayName(), this); - modPage->setParentWidget(this); connect(action, &QAction::triggered, this, [this, modPage]() { if (modPage->useIntegratedBrowser()) { diff --git a/src/modinfowithconflictinfo.cpp b/src/modinfowithconflictinfo.cpp index 6e3f751e..ad7eda3f 100644 --- a/src/modinfowithconflictinfo.cpp +++ b/src/modinfowithconflictinfo.cpp @@ -15,7 +15,7 @@ namespace fs = std::filesystem; ModInfoWithConflictInfo::ModInfoWithConflictInfo( PluginContainer *pluginContainer, const MOBase::IPluginGame* gamePlugin, DirectoryEntry **directoryStructure) - : ModInfo(pluginContainer), m_GamePlugin(gamePlugin), + : ModInfo(pluginContainer), m_GamePlugin(gamePlugin), m_FileTree([this]() { return QDirFileTree::makeTree(absolutePath()); }), m_Valid([this]() { return doIsValid(); }), m_Contents([this]() { return doGetContents(); }), @@ -27,7 +27,7 @@ void ModInfoWithConflictInfo::clearCaches() } std::vector ModInfoWithConflictInfo::getFlags() const -{ +{ std::vector result = std::vector(); if (hasHiddenFiles()) { result.push_back(ModInfo::FLAG_HIDDEN_FILES); diff --git a/src/modinfowithconflictinfo.h b/src/modinfowithconflictinfo.h index e312a89a..0d11fcb1 100644 --- a/src/modinfowithconflictinfo.h +++ b/src/modinfowithconflictinfo.h @@ -34,7 +34,9 @@ public: * * @return true if the content is there, false otherwise. */ - virtual bool hasContent(int content) const override; /** + virtual bool hasContent(int content) const override; + + /** * @brief Retrieve a file tree corresponding to the underlying disk content * of this mod. * diff --git a/src/plugincontainer.cpp b/src/plugincontainer.cpp index fc7f5cd0..44c9a651 100644 --- a/src/plugincontainer.cpp +++ b/src/plugincontainer.cpp @@ -289,15 +289,17 @@ PluginContainer::~PluginContainer() { unloadPlugins(); } -void PluginContainer::setUserInterface(IUserInterface *userInterface, QWidget *widget) +void PluginContainer::setUserInterface(IUserInterface *userInterface) { - for (IPluginProxy *proxy : bf::at_key(m_Plugins)) { - proxy->setParentWidget(widget); - } - - if (userInterface != nullptr) { - for (IPluginModPage *modPage : bf::at_key(m_Plugins)) { - userInterface->registerModPage(modPage); + if (userInterface) { + for (IPluginProxy* proxy : bf::at_key(m_Plugins)) { + proxy->setParentWidget(userInterface->mainWindow()); + } + for (IPluginModPage* modPage : bf::at_key(m_Plugins)) { + modPage->setParentWidget(userInterface->mainWindow()); + } + for (IPluginTool* tool : bf::at_key(m_Plugins)) { + tool->setParentWidget(userInterface->mainWindow()); } } diff --git a/src/plugincontainer.h b/src/plugincontainer.h index 0c1290b4..26e12659 100644 --- a/src/plugincontainer.h +++ b/src/plugincontainer.h @@ -188,7 +188,7 @@ public: PluginContainer(OrganizerCore *organizer); virtual ~PluginContainer(); - void setUserInterface(IUserInterface *userInterface, QWidget *widget); + void setUserInterface(IUserInterface *userInterface); void loadPlugins(); void unloadPlugins(); -- cgit v1.3.1 From ef1188811633e8c1403f960c9196de92d0a81020 Mon Sep 17 00:00:00 2001 From: Mikaël Capelle Date: Fri, 27 Nov 2020 19:20:41 +0100 Subject: Fix conflicts with master. --- src/mainwindow.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'src/mainwindow.cpp') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 7558076d..69f90ce4 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1210,9 +1210,7 @@ void MainWindow::createHelpMenu() ActionList tutorials; - QString tutorialPath = QApplication::applicationDirPath() - + "/" + QString::fromStdWString(AppConfig::tutorialsPath()) + "/"; - QDirIterator dirIter(tutorialPath, QStringList("*.js"), QDir::Files); + QDirIterator dirIter(QApplication::applicationDirPath() + "/tutorials", QStringList("*.js"), QDir::Files); while (dirIter.hasNext()) { dirIter.next(); QString fileName = dirIter.fileName(); @@ -1324,8 +1322,7 @@ bool MainWindow::addProfile() void MainWindow::hookUpWindowTutorials() { - QString tutorialPath = QApplication::applicationDirPath() + "/" + QString::fromStdWString(AppConfig::tutorialsPath()) + "/"; - QDirIterator dirIter(tutorialPath, QStringList("*.js"), QDir::Files); + QDirIterator dirIter(QApplication::applicationDirPath() + "/tutorials", QStringList("*.js"), QDir::Files); while (dirIter.hasNext()) { dirIter.next(); QString fileName = dirIter.fileName(); @@ -5213,9 +5210,7 @@ void MainWindow::installTranslator(const QString &name) { QTranslator *translator = new QTranslator(this); QString fileName = name + "_" + m_CurrentLanguage; - QString translationsPath = qApp->applicationDirPath() - + "/" + QString::fromStdWString(AppConfig::translationsPath()); - if (!translator->load(fileName, translationsPath)) { + if (!translator->load(fileName, qApp->applicationDirPath() + "/translations")) { if (m_CurrentLanguage.contains(QRegularExpression("^.*_(EN|en)(-.*)?$"))) { log::debug("localization file %s not found", fileName); } // we don't actually expect localization files for English (en, en-us, en-uk, and any variation thereof) -- cgit v1.3.1