diff options
| author | Jeremy Rimpo <jeremy.rimpo@servermonkey.com> | 2023-09-21 17:43:29 -0500 |
|---|---|---|
| committer | Jeremy Rimpo <jeremy.rimpo@servermonkey.com> | 2023-09-21 17:43:29 -0500 |
| commit | d2e48ed72e3526c08580d5c4b3531778267532c5 (patch) | |
| tree | 49e8e02641055f6f0ed46d9467a288868f7f1262 /src | |
| parent | 133c072eb7f63e807f2a211804537f59d1f8b0ed (diff) | |
Fix rebase issues
Diffstat (limited to 'src')
| -rw-r--r-- | src/categories.cpp | 8 | ||||
| -rw-r--r-- | src/categoriesdialog.cpp | 1 | ||||
| -rw-r--r-- | src/directoryrefresher.h | 1 | ||||
| -rw-r--r-- | src/filterlist.cpp | 25 | ||||
| -rw-r--r-- | src/filterlist.h | 7 | ||||
| -rw-r--r-- | src/mainwindow.cpp | 1228 | ||||
| -rw-r--r-- | src/mainwindow.h | 9 | ||||
| -rw-r--r-- | src/moapplication.h | 1 | ||||
| -rw-r--r-- | src/modinfodialogcategories.cpp | 12 | ||||
| -rw-r--r-- | src/modinfodialogcategories.h | 5 | ||||
| -rw-r--r-- | src/modinforegular.cpp | 3 | ||||
| -rw-r--r-- | src/modlist.cpp | 10 | ||||
| -rw-r--r-- | src/modlistcontextmenu.cpp | 6 | ||||
| -rw-r--r-- | src/modlistsortproxy.cpp | 185 | ||||
| -rw-r--r-- | src/nexusinterface.h | 28 | ||||
| -rw-r--r-- | src/settingsdialog.ui | 8 | ||||
| -rw-r--r-- | src/settingsdialoggeneral.cpp | 2 |
17 files changed, 157 insertions, 1382 deletions
diff --git a/src/categories.cpp b/src/categories.cpp index 61cd6334..18cee4f9 100644 --- a/src/categories.cpp +++ b/src/categories.cpp @@ -40,15 +40,9 @@ QString CategoryFactory::categoriesFilePath() return qApp->property("dataPath").toString() + "/categories.dat"; } - -QString CategoryFactory::nexusMappingFilePath() -{ - return qApp->property("dataPath").toString() + "/nexuscatmap.dat"; -} - - CategoryFactory::CategoryFactory() : QObject() { + atexit(&cleanup); } QString CategoryFactory::nexusMappingFilePath() diff --git a/src/categoriesdialog.cpp b/src/categoriesdialog.cpp index d97edb8e..4b42495e 100644 --- a/src/categoriesdialog.cpp +++ b/src/categoriesdialog.cpp @@ -193,7 +193,6 @@ void CategoriesDialog::fillTable() QTableWidget* table = ui->categoriesTable; QListWidget* list = ui->nexusCategoryList; -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) table->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed); table->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch); table->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Fixed); diff --git a/src/directoryrefresher.h b/src/directoryrefresher.h index 49eb15be..2e6de1a0 100644 --- a/src/directoryrefresher.h +++ b/src/directoryrefresher.h @@ -54,7 +54,6 @@ public: int priority; }; - DirectoryRefresher(std::size_t threadCount); /** diff --git a/src/filterlist.cpp b/src/filterlist.cpp index ba0671a7..c88945f8 100644 --- a/src/filterlist.cpp +++ b/src/filterlist.cpp @@ -188,9 +188,9 @@ private: } }; - -FilterList::FilterList(Ui::MainWindow* ui, OrganizerCore* organizer, PluginContainer* pluginContainer, CategoryFactory* factory) - : ui(ui), m_Organizer(organizer), m_pluginContainer(pluginContainer), m_factory(factory) +FilterList::FilterList(Ui::MainWindow* ui, OrganizerCore& core, + CategoryFactory& factory) + : ui(ui), m_core(core), m_factory(factory) { auto* eventFilter = new CriteriaItemFilter(ui->filters, [&](auto* item, int dir) { return cycleItem(item, dir); @@ -275,15 +275,15 @@ void FilterList::addContentCriteria() void FilterList::addCategoryCriteria(QTreeWidgetItem* root, const std::set<int>& categoriesUsed, int targetID) { - const auto count = static_cast<unsigned int>(m_factory->numCategories()); + const auto count = static_cast<unsigned int>(m_factory.numCategories()); for (unsigned int i = 1; i < count; ++i) { - if (m_factory->getParentID(i) == targetID) { - int categoryID = m_factory->getCategoryID(i); + if (m_factory.getParentID(i) == targetID) { + int categoryID = m_factory.getCategoryID(i); if (categoriesUsed.find(categoryID) != categoriesUsed.end()) { QTreeWidgetItem* item = - addCriteriaItem(root, m_factory->getCategoryName(i), - categoryID, ModListSortProxy::TypeCategory); - if (m_factory->hasChildren(i)) { + addCriteriaItem(root, m_factory.getCategoryName(i), categoryID, + ModListSortProxy::TypeCategory); + if (m_factory.hasChildren(i)) { addCategoryCriteria(item, categoriesUsed, categoryID); } } @@ -295,9 +295,8 @@ void FilterList::addSpecialCriteria(int type) { const auto sc = static_cast<CategoryFactory::SpecialCategories>(type); - addCriteriaItem( - nullptr, m_factory->getSpecialCategoryName(sc), - type, ModListSortProxy::TypeSpecial); + addCriteriaItem(nullptr, m_factory.getSpecialCategoryName(sc), type, + ModListSortProxy::TypeSpecial); } void FilterList::refresh() @@ -334,7 +333,7 @@ void FilterList::refresh() log::warn("cycle in categories: {}", SetJoin(cycleTest, ", ")); break; } - currentID = m_factory->getParentID(m_factory->getCategoryIndex(currentID)); + currentID = m_factory.getParentID(m_factory.getCategoryIndex(currentID)); } } } diff --git a/src/filterlist.h b/src/filterlist.h index 823a63c2..c28b08c0 100644 --- a/src/filterlist.h +++ b/src/filterlist.h @@ -18,7 +18,7 @@ class FilterList : public QObject Q_OBJECT; public: - FilterList(Ui::MainWindow* ui, OrganizerCore* organizer, PluginContainer* pluginContainer, CategoryFactory* factory); + FilterList(Ui::MainWindow* ui, OrganizerCore& organizer, CategoryFactory& factory); void restoreState(const Settings& s); void saveState(Settings& s) const; @@ -36,9 +36,8 @@ private: class CriteriaItem; Ui::MainWindow* ui; - OrganizerCore* m_Organizer; - CategoryFactory* m_factory; - PluginContainer* m_pluginContainer; + OrganizerCore& m_core; + CategoryFactory& m_factory; bool onClick(QMouseEvent* e); void onItemActivated(QTreeWidgetItem* item); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index e34b648c..74504ed6 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -290,19 +290,6 @@ MainWindow::MainWindow(Settings& settings, OrganizerCore& organizerCore, ui->statusBar->setAPI(ni.getAPIStats(), ni.getAPIUserAccount()); } - languageChange(settings.interface().language()); - - m_CategoryFactory->loadCategories(); - m_Filters.reset(new FilterList(ui, &m_OrganizerCore, &m_PluginContainer, m_CategoryFactory)); - - connect( - m_Filters.get(), &FilterList::criteriaChanged, - [&](auto&& v) { onFiltersCriteria(v); }); - - connect( - m_Filters.get(), &FilterList::optionsChanged, - [&](auto&& mode, auto&& sep) { onFiltersOptions(mode, sep); }); - m_CategoryFactory->loadCategories(); ui->logList->setCore(m_OrganizerCore); @@ -421,13 +408,9 @@ MainWindow::MainWindow(Settings& settings, OrganizerCore& organizerCore, connect(&NexusInterface::instance(), SIGNAL(needLogin()), &m_OrganizerCore, SLOT(nexusApi())); - connect(CategoryFactory::instance(), SIGNAL(requestNexusCategories()), this, SLOT(requestNexusCategories())); - - connect( - NexusInterface::instance(&pluginContainer)->getAccessManager(), - SIGNAL(credentialsReceived(const APIUserAccount&)), - this, - SLOT(updateWindowTitle(const APIUserAccount&))); + connect(NexusInterface::instance().getAccessManager(), + SIGNAL(credentialsReceived(const APIUserAccount&)), this, + SLOT(updateWindowTitle(const APIUserAccount&))); connect(NexusInterface::instance().getAccessManager(), SIGNAL(credentialsReceived(const APIUserAccount&)), @@ -2574,738 +2557,6 @@ void MainWindow::refreshProfile_activated() m_OrganizerCore.profileRefresh(); } -void MainWindow::updateModCount() -{ - int activeCount = 0; - int visActiveCount = 0; - int backupCount = 0; - int visBackupCount = 0; - int foreignCount = 0; - int visForeignCount = 0; - int separatorCount = 0; - int visSeparatorCount = 0; - int regularCount = 0; - int visRegularCount = 0; - - QStringList allMods = m_OrganizerCore.modList()->allMods(); - - auto hasFlag = [](std::vector<ModInfo::EFlag> flags, ModInfo::EFlag filter) { - return std::find(flags.begin(), flags.end(), filter) != flags.end(); - }; - - bool isEnabled; - bool isVisible; - for (QString mod : allMods) { - int modIndex = ModInfo::getIndex(mod); - ModInfo::Ptr modInfo = ModInfo::getByIndex(modIndex); - std::vector<ModInfo::EFlag> modFlags = modInfo->getFlags(); - isEnabled = m_OrganizerCore.currentProfile()->modEnabled(modIndex); - isVisible = m_ModListSortProxy->filterMatchesMod(modInfo, isEnabled); - - for (auto flag : modFlags) { - switch (flag) { - case ModInfo::FLAG_BACKUP: backupCount++; - if (isVisible) - visBackupCount++; - break; - case ModInfo::FLAG_FOREIGN: foreignCount++; - if (isVisible) - visForeignCount++; - break; - case ModInfo::FLAG_SEPARATOR: separatorCount++; - if (isVisible) - visSeparatorCount++; - break; - } - } - - if (!hasFlag(modFlags, ModInfo::FLAG_BACKUP) && - !hasFlag(modFlags, ModInfo::FLAG_FOREIGN) && - !hasFlag(modFlags, ModInfo::FLAG_SEPARATOR) && - !hasFlag(modFlags, ModInfo::FLAG_OVERWRITE)) { - if (isEnabled) { - activeCount++; - if (isVisible) - visActiveCount++; - } - if (isVisible) - visRegularCount++; - regularCount++; - } - } - - ui->activeModsCounter->display(visActiveCount); - ui->activeModsCounter->setToolTip(tr("<table cellspacing=\"5\">" - "<tr><th>Type</th><th>All</th><th>Visible</th>" - "<tr><td>Enabled mods: </td><td align=right>%1 / %2</td><td align=right>%3 / %4</td></tr>" - "<tr><td>Unmanaged/DLCs: </td><td align=right>%5</td><td align=right>%6</td></tr>" - "<tr><td>Mod backups: </td><td align=right>%7</td><td align=right>%8</td></tr>" - "<tr><td>Separators: </td><td align=right>%9</td><td align=right>%10</td></tr>" - "</table>") - .arg(activeCount) - .arg(regularCount) - .arg(visActiveCount) - .arg(visRegularCount) - .arg(foreignCount) - .arg(visForeignCount) - .arg(backupCount) - .arg(visBackupCount) - .arg(separatorCount) - .arg(visSeparatorCount) - ); -} - -void MainWindow::updatePluginCount() -{ - int activeMasterCount = 0; - int activeLightMasterCount = 0; - int activeRegularCount = 0; - int masterCount = 0; - int lightMasterCount = 0; - int regularCount = 0; - int activeVisibleCount = 0; - - PluginList *list = m_OrganizerCore.pluginList(); - QString filter = ui->espFilterEdit->text(); - - for (QString plugin : list->pluginNames()) { - bool active = list->isEnabled(plugin); - bool visible = m_PluginListSortProxy->filterMatchesPlugin(plugin); - if (list->isLight(plugin) || list->isLightFlagged(plugin)) { - lightMasterCount++; - activeLightMasterCount += active; - activeVisibleCount += visible && active; - } else if (list->isMaster(plugin)) { - masterCount++; - activeMasterCount += active; - activeVisibleCount += visible && active; - } else { - regularCount++; - activeRegularCount += active; - activeVisibleCount += visible && active; - } - } - - int activeCount = activeMasterCount + activeLightMasterCount + activeRegularCount; - int totalCount = masterCount + lightMasterCount + regularCount; - - ui->activePluginsCounter->display(activeVisibleCount); - ui->activePluginsCounter->setToolTip(tr("<table cellspacing=\"6\">" - "<tr><th>Type</th><th>Active </th><th>Total</th></tr>" - "<tr><td>All plugins:</td><td align=right>%1 </td><td align=right>%2</td></tr>" - "<tr><td>ESMs:</td><td align=right>%3 </td><td align=right>%4</td></tr>" - "<tr><td>ESPs:</td><td align=right>%7 </td><td align=right>%8</td></tr>" - "<tr><td>ESMs+ESPs:</td><td align=right>%9 </td><td align=right>%10</td></tr>" - "<tr><td>ESLs:</td><td align=right>%5 </td><td align=right>%6</td></tr>" - "</table>") - .arg(activeCount).arg(totalCount) - .arg(activeMasterCount).arg(masterCount) - .arg(activeLightMasterCount).arg(lightMasterCount) - .arg(activeRegularCount).arg(regularCount) - .arg(activeMasterCount+activeRegularCount).arg(masterCount+regularCount) - ); -} - -void MainWindow::information_clicked() -{ - try { - displayModInformation(m_ContextRow); - } catch (const std::exception &e) { - reportError(e.what()); - } -} - -void MainWindow::createEmptyMod_clicked() -{ - GuessedValue<QString> name; - name.setFilter(&fixDirectoryName); - - while (name->isEmpty()) { - bool ok; - name.update(QInputDialog::getText(this, tr("Create Mod..."), - tr("This will create an empty mod.\n" - "Please enter a name:"), QLineEdit::Normal, "", &ok), - GUESS_USER); - if (!ok) { - return; - } - } - - if (m_OrganizerCore.getMod(name) != nullptr) { - reportError(tr("A mod with this name already exists")); - return; - } - - int newPriority = -1; - if (m_ContextRow >= 0 && m_ModListSortProxy->sortColumn() == ModList::COL_PRIORITY) { - newPriority = m_OrganizerCore.currentProfile()->getModPriority(m_ContextRow); - } - - IModInterface *newMod = m_OrganizerCore.createMod(name); - if (newMod == nullptr) { - return; - } - - m_OrganizerCore.refreshModList(); - - if (newPriority >= 0) { - m_OrganizerCore.modList()->changeModPriority(ModInfo::getIndex(name), newPriority); - } -} - -void MainWindow::createSeparator_clicked() -{ - GuessedValue<QString> name; - name.setFilter(&fixDirectoryName); - while (name->isEmpty()) - { - bool ok; - name.update(QInputDialog::getText(this, tr("Create Separator..."), - tr("This will create a new separator.\n" - "Please enter a name:"), QLineEdit::Normal, "", &ok), - GUESS_USER); - if (!ok) { return; } - } - if (m_OrganizerCore.getMod(name) != nullptr) - { - reportError(tr("A separator with this name already exists")); - return; - } - name->append("_separator"); - if (m_OrganizerCore.getMod(name) != nullptr) - { - return; - } - - int newPriority = -1; - if (m_ContextRow >= 0 && m_ModListSortProxy->sortColumn() == ModList::COL_PRIORITY) - { - newPriority = m_OrganizerCore.currentProfile()->getModPriority(m_ContextRow); - } - - if (m_OrganizerCore.createMod(name) == nullptr) { return; } - m_OrganizerCore.refreshModList(); - - if (newPriority >= 0) - { - m_OrganizerCore.modList()->changeModPriority(ModInfo::getIndex(name), newPriority); - } - - if (auto c=m_OrganizerCore.settings().colors().previousSeparatorColor()) { - ModInfo::getByIndex(ModInfo::getIndex(name))->setColor(*c); - } -} - -void MainWindow::setColor_clicked() -{ - auto& settings = m_OrganizerCore.settings(); - ModInfo::Ptr modInfo = ModInfo::getByIndex(m_ContextRow); - - QColorDialog dialog(this); - dialog.setOption(QColorDialog::ShowAlphaChannel); - - QColor currentColor = modInfo->color(); - if (currentColor.isValid()) { - dialog.setCurrentColor(currentColor); - } - else if (auto c=settings.colors().previousSeparatorColor()) { - dialog.setCurrentColor(*c); - } - - if (!dialog.exec()) - return; - - currentColor = dialog.currentColor(); - if (!currentColor.isValid()) - return; - - settings.colors().setPreviousSeparatorColor(currentColor); - - QItemSelectionModel *selection = ui->modList->selectionModel(); - if (selection->hasSelection() && selection->selectedRows().count() > 1) { - for (QModelIndex idx : selection->selectedRows()) { - ModInfo::Ptr info = ModInfo::getByIndex(idx.data(Qt::UserRole + 1).toInt()); - info->setColor(currentColor); - } - } - else { - modInfo->setColor(currentColor); - } -} - -void MainWindow::resetColor_clicked() -{ - ModInfo::Ptr modInfo = ModInfo::getByIndex(m_ContextRow); - QColor color = QColor(); - QItemSelectionModel *selection = ui->modList->selectionModel(); - if (selection->hasSelection() && selection->selectedRows().count() > 1) { - for (QModelIndex idx : selection->selectedRows()) { - ModInfo::Ptr info = ModInfo::getByIndex(idx.data(Qt::UserRole + 1).toInt()); - info->setColor(color); - } - } - else { - modInfo->setColor(color); - } - - m_OrganizerCore.settings().colors().removePreviousSeparatorColor(); -} - -void MainWindow::createModFromOverwrite() -{ - GuessedValue<QString> name; - name.setFilter(&fixDirectoryName); - - while (name->isEmpty()) { - bool ok; - name.update(QInputDialog::getText(this, tr("Create Mod..."), - tr("This will move all files from overwrite into a new, regular mod.\n" - "Please enter a name:"), QLineEdit::Normal, "", &ok), - GUESS_USER); - if (!ok) { - return; - } - } - - if (m_OrganizerCore.getMod(name) != nullptr) { - reportError(tr("A mod with this name already exists")); - return; - } - - const IModInterface *newMod = m_OrganizerCore.createMod(name); - if (newMod == nullptr) { - return; - } - - doMoveOverwriteContentToMod(newMod->absolutePath()); -} - -void MainWindow::moveOverwriteContentToExistingMod() -{ - QStringList mods; - auto indexesByPriority = m_OrganizerCore.currentProfile()->getAllIndexesByPriority(); - for (auto & iter : indexesByPriority) { - if ((iter.second != UINT_MAX)) { - ModInfo::Ptr modInfo = ModInfo::getByIndex(iter.second); - if (!modInfo->hasFlag(ModInfo::FLAG_SEPARATOR) && !modInfo->hasFlag(ModInfo::FLAG_FOREIGN) && !modInfo->hasFlag(ModInfo::FLAG_OVERWRITE)) { - mods << modInfo->name(); - } - } - } - - ListDialog dialog(this); - dialog.setWindowTitle("Select a mod..."); - dialog.setChoices(mods); - - if (dialog.exec() == QDialog::Accepted) { - QString result = dialog.getChoice(); - if (!result.isEmpty()) { - - QString modAbsolutePath; - - for (const auto& mod : m_OrganizerCore.modsSortedByProfilePriority()) { - if (result.compare(mod) == 0) { - ModInfo::Ptr modInfo = ModInfo::getByIndex(ModInfo::getIndex(mod)); - modAbsolutePath = modInfo->absolutePath(); - break; - } - } - - if (modAbsolutePath.isNull()) { - log::warn("Mod {} has not been found, for some reason", result); - return; - } - - doMoveOverwriteContentToMod(modAbsolutePath); - } - } -} - -void MainWindow::doMoveOverwriteContentToMod(const QString &modAbsolutePath) -{ - unsigned int overwriteIndex = ModInfo::findMod([](ModInfo::Ptr mod) -> bool { - std::vector<ModInfo::EFlag> flags = mod->getFlags(); - return std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end(); }); - - ModInfo::Ptr overwriteInfo = ModInfo::getByIndex(overwriteIndex); - bool successful = shellMove((QDir::toNativeSeparators(overwriteInfo->absolutePath()) + "\\*"), - (QDir::toNativeSeparators(modAbsolutePath)), false, this); - - if (successful) { - MessageDialog::showMessage(tr("Move successful."), this); - } - else { - const auto e = GetLastError(); - log::error("Move operation failed: {}", formatSystemMessage(e)); - } - - m_OrganizerCore.refreshModList(); -} - -void MainWindow::clearOverwrite() -{ - unsigned int overwriteIndex = ModInfo::findMod([](ModInfo::Ptr mod) -> bool { - std::vector<ModInfo::EFlag> flags = mod->getFlags(); - return std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) - != flags.end(); - }); - - ModInfo::Ptr modInfo = ModInfo::getByIndex(overwriteIndex); - if (modInfo) - { - QDir overwriteDir(modInfo->absolutePath()); - if (QMessageBox::question(this, tr("Are you sure?"), - tr("About to recursively delete:\n") + overwriteDir.absolutePath(), - QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) - { - QStringList delList; - for (auto f : overwriteDir.entryList(QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot)) - delList.push_back(overwriteDir.absoluteFilePath(f)); - if (shellDelete(delList, true)) { - scheduleCheckForProblems(); - m_OrganizerCore.refreshModList(); - } else { - const auto e = GetLastError(); - log::error("Delete operation failed: {}", formatSystemMessage(e)); - } - } - } -} - -void MainWindow::cancelModListEditor() -{ - ui->modList->setEnabled(false); - ui->modList->setEnabled(true); -} - -void MainWindow::on_modList_doubleClicked(const QModelIndex &index) -{ - if (!index.isValid()) { - return; - } - - if (m_OrganizerCore.modList()->timeElapsedSinceLastChecked() <= QApplication::doubleClickInterval()) { - // don't interpret double click if we only just checked a mod - return; - } - - QModelIndex sourceIdx = mapToModel(m_OrganizerCore.modList(), index); - if (!sourceIdx.isValid()) { - return; - } - - Qt::KeyboardModifiers modifiers = QApplication::queryKeyboardModifiers(); - if (modifiers.testFlag(Qt::ControlModifier)) { - try { - m_ContextRow = m_ModListSortProxy->mapToSource(index).row(); - - ModInfo::Ptr modInfo = ModInfo::getByIndex(m_ContextRow); - shell::Explore(modInfo->absolutePath()); - - // workaround to cancel the editor that might have opened because of - // selection-click - ui->modList->closePersistentEditor(index); - } - catch (const std::exception &e) { - reportError(e.what()); - } - } - else if (modifiers.testFlag(Qt::ShiftModifier)) { - try { - m_ContextRow = m_ModListSortProxy->mapToSource(index).row(); - QModelIndex idx = m_OrganizerCore.modList()->index(m_ContextRow, 0); - visitNexusOrWebPage(idx); - ui->modList->closePersistentEditor(index); - } - catch (const std::exception & e) { - reportError(e.what()); - } - } - else{ - try { - m_ContextRow = m_ModListSortProxy->mapToSource(index).row(); - sourceIdx.column(); - - auto tab = ModInfoTabIDs::None; - - switch (sourceIdx.column()) { - case ModList::COL_NOTES: tab = ModInfoTabIDs::Notes; break; - case ModList::COL_VERSION: tab = ModInfoTabIDs::Nexus; break; - case ModList::COL_MODID: tab = ModInfoTabIDs::Nexus; break; - case ModList::COL_GAME: tab = ModInfoTabIDs::Nexus; break; - case ModList::COL_CATEGORY: tab = ModInfoTabIDs::Categories; break; - case ModList::COL_CONFLICTFLAGS: tab = ModInfoTabIDs::Conflicts; break; - } - - displayModInformation(sourceIdx.row(), tab); - // workaround to cancel the editor that might have opened because of - // selection-click - ui->modList->closePersistentEditor(index); - } - catch (const std::exception &e) { - reportError(e.what()); - } - } -} - -void MainWindow::on_listOptionsBtn_pressed() -{ - m_ContextRow = -1; -} - -void MainWindow::openOriginInformation_clicked() -{ - try { - QItemSelectionModel *selection = ui->espList->selectionModel(); - //we don't want to open multiple modinfodialogs. - /*if (selection->hasSelection() && selection->selectedRows().count() > 0) { - - for (QModelIndex idx : selection->selectedRows()) { - QString fileName = idx.data().toString(); - ModInfo::Ptr modInfo = ModInfo::getByIndex(ModInfo::getIndex(m_OrganizerCore.pluginList()->origin(fileName))); - std::vector<ModInfo::EFlag> flags = modInfo->getFlags(); - - if (modInfo->isRegular() || (std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end())) { - displayModInformation(ModInfo::getIndex(m_OrganizerCore.pluginList()->origin(fileName))); - } - } - } - else {}*/ - QModelIndex idx = selection->currentIndex(); - QString fileName = idx.data().toString(); - - ModInfo::Ptr modInfo = ModInfo::getByIndex(ModInfo::getIndex(m_OrganizerCore.pluginList()->origin(fileName))); - std::vector<ModInfo::EFlag> flags = modInfo->getFlags(); - - if (modInfo->isRegular() || (std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end())) { - displayModInformation(ModInfo::getIndex(m_OrganizerCore.pluginList()->origin(fileName))); - } - } - catch (const std::exception &e) { - reportError(e.what()); - } -} - -void MainWindow::on_espList_doubleClicked(const QModelIndex &index) -{ - if (!index.isValid()) { - return; - } - - if (m_OrganizerCore.pluginList()->timeElapsedSinceLastChecked() <= QApplication::doubleClickInterval()) { - // don't interpret double click if we only just checked a plugin - return; - } - - QModelIndex sourceIdx = mapToModel(m_OrganizerCore.pluginList(), index); - if (!sourceIdx.isValid()) { - return; - } - try { - - QItemSelectionModel *selection = ui->espList->selectionModel(); - - if (selection->hasSelection() && selection->selectedRows().count() == 1) { - - QModelIndex idx = selection->currentIndex(); - QString fileName = idx.data().toString(); - - if (ModInfo::getIndex(m_OrganizerCore.pluginList()->origin(fileName)) == UINT_MAX) - return; - - ModInfo::Ptr modInfo = ModInfo::getByIndex(ModInfo::getIndex(m_OrganizerCore.pluginList()->origin(fileName))); - std::vector<ModInfo::EFlag> flags = modInfo->getFlags(); - - if (modInfo->isRegular() || (std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end())) { - - Qt::KeyboardModifiers modifiers = QApplication::queryKeyboardModifiers(); - if (modifiers.testFlag(Qt::ControlModifier)) { - openExplorer_activated(); - // workaround to cancel the editor that might have opened because of - // selection-click - ui->espList->closePersistentEditor(index); - } - else { - - displayModInformation(ModInfo::getIndex(m_OrganizerCore.pluginList()->origin(fileName))); - // workaround to cancel the editor that might have opened because of - // selection-click - ui->espList->closePersistentEditor(index); - } - } - } - } - catch (const std::exception &e) { - reportError(e.what()); - } -} - -bool MainWindow::populateMenuCategories(QMenu *menu, int targetID) -{ - ModInfo::Ptr modInfo = ModInfo::getByIndex(m_ContextRow); - const std::set<int> &categories = modInfo->getCategories(); - - bool childEnabled = false; - - for (unsigned int i = 1; i < m_CategoryFactory->numCategories(); ++i) { - if (m_CategoryFactory->getParentID(i) == targetID) { - QMenu *targetMenu = menu; - if (m_CategoryFactory->hasChildren(i)) { - targetMenu = menu->addMenu(m_CategoryFactory->getCategoryName(i).replace('&', "&&")); - } - - int id = m_CategoryFactory->getCategoryID(i); - QScopedPointer<QCheckBox> checkBox(new QCheckBox(targetMenu)); - bool enabled = categories.find(id) != categories.end(); - checkBox->setText(m_CategoryFactory->getCategoryName(i).replace('&', "&&")); - if (enabled) { - childEnabled = true; - } - checkBox->setChecked(enabled ? Qt::Checked : Qt::Unchecked); - - QScopedPointer<QWidgetAction> checkableAction(new QWidgetAction(targetMenu)); - checkableAction->setDefaultWidget(checkBox.take()); - checkableAction->setData(id); - targetMenu->addAction(checkableAction.take()); - - if (m_CategoryFactory->hasChildren(i)) { - if (populateMenuCategories(targetMenu, m_CategoryFactory->getCategoryID(i)) || enabled) { - targetMenu->setIcon(QIcon(":/MO/gui/resources/check.png")); - } - } - } - } - return childEnabled; -} - -void MainWindow::replaceCategoriesFromMenu(QMenu *menu, int modRow) -{ - ModInfo::Ptr modInfo = ModInfo::getByIndex(modRow); - for (QAction* action : menu->actions()) { - if (action->menu() != nullptr) { - replaceCategoriesFromMenu(action->menu(), modRow); - } else { - QWidgetAction *widgetAction = qobject_cast<QWidgetAction*>(action); - if (widgetAction != nullptr) { - QCheckBox *checkbox = qobject_cast<QCheckBox*>(widgetAction->defaultWidget()); - modInfo->setCategory(widgetAction->data().toInt(), checkbox->isChecked()); - } - } - } -} - -void MainWindow::addRemoveCategoriesFromMenu(QMenu *menu, int modRow, int referenceRow) -{ - if (referenceRow != -1 && referenceRow != modRow) { - ModInfo::Ptr editedModInfo = ModInfo::getByIndex(referenceRow); - for (QAction* action : menu->actions()) { - if (action->menu() != nullptr) { - addRemoveCategoriesFromMenu(action->menu(), modRow, referenceRow); - } else { - QWidgetAction *widgetAction = qobject_cast<QWidgetAction*>(action); - if (widgetAction != nullptr) { - QCheckBox *checkbox = qobject_cast<QCheckBox*>(widgetAction->defaultWidget()); - int categoryId = widgetAction->data().toInt(); - bool checkedBefore = editedModInfo->categorySet(categoryId); - bool checkedAfter = checkbox->isChecked(); - - if (checkedBefore != checkedAfter) { // only update if the category was changed on the edited mod - ModInfo::Ptr currentModInfo = ModInfo::getByIndex(modRow); - currentModInfo->setCategory(categoryId, checkedAfter); - } - } - } - } - } else { - replaceCategoriesFromMenu(menu, modRow); - } -} - -void MainWindow::addRemoveCategories_MenuHandler() { - QMenu *menu = qobject_cast<QMenu*>(sender()); - if (menu == nullptr) { - log::error("not a menu?"); - return; - } - - QList<QPersistentModelIndex> selected; - for (const QModelIndex &idx : ui->modList->selectionModel()->selectedRows()) { - selected.append(QPersistentModelIndex(idx)); - } - - if (selected.size() > 0) { - int minRow = INT_MAX; - int maxRow = -1; - - for (const QPersistentModelIndex &idx : selected) { - log::debug("change categories on: {}", idx.data().toString()); - QModelIndex modIdx = mapToModel(m_OrganizerCore.modList(), idx); - if (modIdx.row() != m_ContextIdx.row()) { - addRemoveCategoriesFromMenu(menu, modIdx.row(), m_ContextIdx.row()); - } - if (idx.row() < minRow) minRow = idx.row(); - if (idx.row() > maxRow) maxRow = idx.row(); - } - replaceCategoriesFromMenu(menu, m_ContextIdx.row()); - - m_OrganizerCore.modList()->notifyChange(minRow, maxRow + 1); - - for (const QPersistentModelIndex &idx : selected) { - ui->modList->selectionModel()->select(idx, QItemSelectionModel::Select | QItemSelectionModel::Rows); - } - } else { - //For single mod selections, just do a replace - replaceCategoriesFromMenu(menu, m_ContextRow); - m_OrganizerCore.modList()->notifyChange(m_ContextRow); - } - - refreshFilters(); -} - -void MainWindow::replaceCategories_MenuHandler() { - QMenu *menu = qobject_cast<QMenu*>(sender()); - if (menu == nullptr) { - log::error("not a menu?"); - return; - } - - QList<QPersistentModelIndex> selected; - for (const QModelIndex &idx : ui->modList->selectionModel()->selectedRows()) { - selected.append(QPersistentModelIndex(idx)); - } - - if (selected.size() > 0) { - QStringList selectedMods; - int minRow = INT_MAX; - int maxRow = -1; - for (int i = 0; i < selected.size(); ++i) { - QModelIndex temp = mapToModel(m_OrganizerCore.modList(), selected.at(i)); - selectedMods.append(temp.data().toString()); - replaceCategoriesFromMenu(menu, mapToModel(m_OrganizerCore.modList(), selected.at(i)).row()); - if (temp.row() < minRow) minRow = temp.row(); - if (temp.row() > maxRow) maxRow = temp.row(); - } - - m_OrganizerCore.modList()->notifyChange(minRow, maxRow + 1); - - // find mods by their name because indices are invalidated - QAbstractItemModel *model = ui->modList->model(); - for (const QString &mod : selectedMods) { - QModelIndexList matches = model->match(model->index(0, 0), Qt::DisplayRole, mod, 1, - Qt::MatchFixedString | Qt::MatchCaseSensitive | Qt::MatchRecursive); - if (matches.size() > 0) { - ui->modList->selectionModel()->select(matches.at(0), QItemSelectionModel::Select | QItemSelectionModel::Rows); - } - } - } else { - //For single mod selections, just do a replace - replaceCategoriesFromMenu(menu, m_ContextRow); - m_OrganizerCore.modList()->notifyChange(m_ContextRow); - } - - refreshFilters(); -} - void MainWindow::saveArchiveList() { if (m_OrganizerCore.isArchivesInit()) { @@ -3325,180 +2576,6 @@ void MainWindow::saveArchiveList() } } -void MainWindow::checkModsForUpdates() -{ - bool checkingModsForUpdate = false; - if (NexusInterface::instance(&m_PluginContainer)->getAccessManager()->validated()) { - checkingModsForUpdate = ModInfo::checkAllForUpdate(&m_PluginContainer, this); - NexusInterface::instance(&m_PluginContainer)->requestEndorsementInfo(this, QVariant(), QString()); - NexusInterface::instance(&m_PluginContainer)->requestTrackingInfo(this, QVariant(), QString()); - } else { - QString apiKey; - if (m_OrganizerCore.settings().nexus().apiKey(apiKey)) { - m_OrganizerCore.doAfterLogin([this] () { this->checkModsForUpdates(); }); - NexusInterface::instance(&m_PluginContainer)->getAccessManager()->apiCheck(apiKey); - } else { - log::warn("{}", tr("You are not currently authenticated with Nexus. Please do so under Settings -> Nexus.")); - } - } - - bool updatesAvailable = false; - for (auto mod : m_OrganizerCore.modList()->allMods()) { - ModInfo::Ptr modInfo = ModInfo::getByName(mod); - if (modInfo->updateAvailable()) { - updatesAvailable = true; - break; - } - } - - if (updatesAvailable || checkingModsForUpdate) { - m_ModListSortProxy->setCriteria({{ - ModListSortProxy::TypeSpecial, - CategoryFactory::UpdateAvailable, - false} - }); - - m_Filters->setSelection({{ - ModListSortProxy::TypeSpecial, - CategoryFactory::UpdateAvailable, - false - }}); - } -} - -void MainWindow::changeVersioningScheme() { - if (QMessageBox::question(this, tr("Continue?"), - tr("The versioning scheme decides which version is considered newer than another.\n" - "This function will guess the versioning scheme under the assumption that the installed version is outdated."), - QMessageBox::Yes | QMessageBox::Cancel) == QMessageBox::Yes) { - - ModInfo::Ptr info = ModInfo::getByIndex(m_ContextRow); - - bool success = false; - - static VersionInfo::VersionScheme schemes[] = { VersionInfo::SCHEME_REGULAR, VersionInfo::SCHEME_DECIMALMARK, VersionInfo::SCHEME_NUMBERSANDLETTERS }; - - for (int i = 0; i < sizeof(schemes) / sizeof(VersionInfo::VersionScheme) && !success; ++i) { - VersionInfo verOld(info->version().canonicalString(), schemes[i]); - VersionInfo verNew(info->newestVersion().canonicalString(), schemes[i]); - if (verOld < verNew) { - info->setVersion(verOld); - info->setNewestVersion(verNew); - success = true; - } - } - if (!success) { - QMessageBox::information(this, tr("Sorry"), - tr("I don't know a versioning scheme where %1 is newer than %2.").arg(info->newestVersion().canonicalString()).arg(info->version().canonicalString()), - QMessageBox::Ok); - } - } -} - -void MainWindow::ignoreUpdate() { - QItemSelectionModel *selection = ui->modList->selectionModel(); - if (selection->hasSelection() && selection->selectedRows().count() > 1) { - for (QModelIndex idx : selection->selectedRows()) { - ModInfo::Ptr info = ModInfo::getByIndex(idx.data(Qt::UserRole + 1).toInt()); - info->ignoreUpdate(true); - } - } - else { - ModInfo::Ptr info = ModInfo::getByIndex(m_ContextRow); - info->ignoreUpdate(true); - } - if (m_ModListSortProxy != nullptr) - m_ModListSortProxy->invalidate(); -} - -void MainWindow::checkModUpdates_clicked() -{ - std::multimap<QString, int> IDs; - QItemSelectionModel *selection = ui->modList->selectionModel(); - if (selection->hasSelection() && selection->selectedRows().count() > 1) { - for (QModelIndex idx : selection->selectedRows()) { - ModInfo::Ptr info = ModInfo::getByIndex(idx.data(Qt::UserRole + 1).toInt()); - IDs.insert(std::make_pair<QString, int>(info->gameName(), info->nexusId())); - } - } else { - ModInfo::Ptr info = ModInfo::getByIndex(m_ContextRow); - IDs.insert(std::make_pair<QString, int>(info->gameName(), info->nexusId())); - } - modUpdateCheck(IDs); -} - -void MainWindow::unignoreUpdate() -{ - QItemSelectionModel *selection = ui->modList->selectionModel(); - if (selection->hasSelection() && selection->selectedRows().count() > 1) { - for (QModelIndex idx : selection->selectedRows()) { - ModInfo::Ptr info = ModInfo::getByIndex(idx.data(Qt::UserRole + 1).toInt()); - info->ignoreUpdate(false); - } - } - else { - ModInfo::Ptr info = ModInfo::getByIndex(m_ContextRow); - info->ignoreUpdate(false); - } - if (m_ModListSortProxy != nullptr) - m_ModListSortProxy->invalidate(); -} - -void MainWindow::addPrimaryCategoryCandidates(QMenu *primaryCategoryMenu, - ModInfo::Ptr info) { - const std::set<int> &categories = info->getCategories(); - for (int categoryID : categories) { - int catIdx = m_CategoryFactory->getCategoryIndex(categoryID); - QWidgetAction *action = new QWidgetAction(primaryCategoryMenu); - try { - QRadioButton *categoryBox = new QRadioButton( - m_CategoryFactory->getCategoryName(catIdx).replace('&', "&&"), - primaryCategoryMenu); - connect(categoryBox, &QRadioButton::toggled, [info, categoryID](bool enable) { - if (enable) { - info->setPrimaryCategory(categoryID); - } - }); - categoryBox->setChecked(categoryID == info->primaryCategory()); - action->setDefaultWidget(categoryBox); - } catch (const std::exception &e) { - log::error("failed to create category checkbox: {}", e.what()); - } - - action->setData(categoryID); - primaryCategoryMenu->addAction(action); - } -} - -void MainWindow::addPrimaryCategoryCandidates() -{ - QMenu *menu = qobject_cast<QMenu*>(sender()); - if (menu == nullptr) { - log::error("not a menu?"); - return; - } - menu->clear(); - ModInfo::Ptr modInfo = ModInfo::getByIndex(m_ContextRow); - - addPrimaryCategoryCandidates(menu, modInfo); -} - -void MainWindow::enableVisibleMods() -{ - if (QMessageBox::question(nullptr, tr("Confirm"), tr("Really enable all visible mods?"), - QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { - m_ModListSortProxy->enableAllVisible(); - } -} - -void MainWindow::disableVisibleMods() -{ - if (QMessageBox::question(nullptr, tr("Confirm"), tr("Really disable all visible mods?"), - QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { - m_ModListSortProxy->disableAllVisible(); - } -} - void MainWindow::openInstanceFolder() { QString dataPath = qApp->property("dataPath").toString(); @@ -3558,184 +2635,6 @@ void MainWindow::openMyGamesFolder() shell::Explore(m_OrganizerCore.managedGame()->documentsDirectory()); } - -void MainWindow::exportModListCSV() -{ - //SelectionDialog selection(tr("Choose what to export")); - - //selection.addChoice(tr("Everything"), tr("All installed mods are included in the list"), 0); - //selection.addChoice(tr("Active Mods"), tr("Only active (checked) mods from your current profile are included"), 1); - //selection.addChoice(tr("Visible"), tr("All mods visible in the mod list are included"), 2); - - QDialog selection(this); - QGridLayout *grid = new QGridLayout; - selection.setWindowTitle(tr("Export to csv")); - - QLabel *csvDescription = new QLabel(); - csvDescription->setText(tr("CSV (Comma Separated Values) is a format that can be imported in programs like Excel to create a spreadsheet.\nYou can also use online editors and converters instead.")); - grid->addWidget(csvDescription); - - QGroupBox *groupBoxRows = new QGroupBox(tr("Select what mods you want export:")); - QRadioButton *all = new QRadioButton(tr("All installed mods")); - QRadioButton *active = new QRadioButton(tr("Only active (checked) mods from your current profile")); - QRadioButton *visible = new QRadioButton(tr("All currently visible mods in the mod list")); - - QVBoxLayout *vbox = new QVBoxLayout; - vbox->addWidget(all); - vbox->addWidget(active); - vbox->addWidget(visible); - vbox->addStretch(1); - groupBoxRows->setLayout(vbox); - - - - grid->addWidget(groupBoxRows); - - QButtonGroup *buttonGroupRows = new QButtonGroup(); - buttonGroupRows->addButton(all, 0); - buttonGroupRows->addButton(active, 1); - buttonGroupRows->addButton(visible, 2); - buttonGroupRows->button(0)->setChecked(true); - - - - QGroupBox *groupBoxColumns = new QGroupBox(tr("Choose what Columns to export:")); - groupBoxColumns->setFlat(true); - - QCheckBox *mod_Priority = new QCheckBox(tr("Mod_Priority")); - mod_Priority->setChecked(true); - QCheckBox *mod_Name = new QCheckBox(tr("Mod_Name")); - mod_Name->setChecked(true); - QCheckBox *mod_Note = new QCheckBox(tr("Notes_column")); - QCheckBox *mod_Status = new QCheckBox(tr("Mod_Status")); - mod_Status->setChecked(true); - QCheckBox *primary_Category = new QCheckBox(tr("Primary_Category")); - QCheckBox *nexus_ID = new QCheckBox(tr("Nexus_ID")); - QCheckBox *mod_Nexus_URL = new QCheckBox(tr("Mod_Nexus_URL")); - QCheckBox *mod_Version = new QCheckBox(tr("Mod_Version")); - QCheckBox *install_Date = new QCheckBox(tr("Install_Date")); - QCheckBox *download_File_Name = new QCheckBox(tr("Download_File_Name")); - - QVBoxLayout *vbox1 = new QVBoxLayout; - vbox1->addWidget(mod_Priority); - vbox1->addWidget(mod_Name); - vbox1->addWidget(mod_Status); - vbox1->addWidget(mod_Note); - vbox1->addWidget(primary_Category); - vbox1->addWidget(nexus_ID); - vbox1->addWidget(mod_Nexus_URL); - vbox1->addWidget(mod_Version); - vbox1->addWidget(install_Date); - vbox1->addWidget(download_File_Name); - groupBoxColumns->setLayout(vbox1); - - grid->addWidget(groupBoxColumns); - - QPushButton *ok = new QPushButton("Ok"); - QPushButton *cancel = new QPushButton("Cancel"); - QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - - connect(buttons, SIGNAL(accepted()), &selection, SLOT(accept())); - connect(buttons, SIGNAL(rejected()), &selection, SLOT(reject())); - - grid->addWidget(buttons); - - selection.setLayout(grid); - - - if (selection.exec() == QDialog::Accepted) { - - unsigned int numMods = ModInfo::getNumMods(); - int selectedRowID = buttonGroupRows->checkedId(); - - try { - QBuffer buffer; - buffer.open(QIODevice::ReadWrite); - CSVBuilder builder(&buffer); - builder.setEscapeMode(CSVBuilder::TYPE_STRING, CSVBuilder::QUOTE_ALWAYS); - std::vector<std::pair<QString, CSVBuilder::EFieldType> > fields; - if (mod_Priority->isChecked()) - fields.push_back(std::make_pair(QString("#Mod_Priority"), CSVBuilder::TYPE_STRING)); - if (mod_Status->isChecked()) - fields.push_back(std::make_pair(QString("#Mod_Status"), CSVBuilder::TYPE_STRING)); - if (mod_Name->isChecked()) - fields.push_back(std::make_pair(QString("#Mod_Name"), CSVBuilder::TYPE_STRING)); - if (mod_Note->isChecked()) - fields.push_back(std::make_pair(QString("#Note"), CSVBuilder::TYPE_STRING)); - if (primary_Category->isChecked()) - fields.push_back(std::make_pair(QString("#Primary_Category"), CSVBuilder::TYPE_STRING)); - if (nexus_ID->isChecked()) - fields.push_back(std::make_pair(QString("#Nexus_ID"), CSVBuilder::TYPE_INTEGER)); - if (mod_Nexus_URL->isChecked()) - fields.push_back(std::make_pair(QString("#Mod_Nexus_URL"), CSVBuilder::TYPE_STRING)); - if (mod_Version->isChecked()) - fields.push_back(std::make_pair(QString("#Mod_Version"), CSVBuilder::TYPE_STRING)); - if (install_Date->isChecked()) - fields.push_back(std::make_pair(QString("#Install_Date"), CSVBuilder::TYPE_STRING)); - if (download_File_Name->isChecked()) - fields.push_back(std::make_pair(QString("#Download_File_Name"), CSVBuilder::TYPE_STRING)); - - builder.setFields(fields); - - builder.writeHeader(); - - auto indexesByPriority = m_OrganizerCore.currentProfile()->getAllIndexesByPriority(); - for (auto& iter : indexesByPriority) { - ModInfo::Ptr info = ModInfo::getByIndex(iter.second); - bool enabled = m_OrganizerCore.currentProfile()->modEnabled(iter.second); - if ((selectedRowID == 1) && !enabled) { - continue; - } - else if ((selectedRowID == 2) && !m_ModListSortProxy->filterMatchesMod(info, enabled)) { - continue; - } - std::vector<ModInfo::EFlag> flags = info->getFlags(); - if ((std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) == flags.end()) && - (std::find(flags.begin(), flags.end(), ModInfo::FLAG_BACKUP) == flags.end())) { - if (mod_Priority->isChecked()) - builder.setRowField("#Mod_Priority", QString("%1").arg(iter.first, 4, 10, QChar('0'))); - if (mod_Status->isChecked()) - builder.setRowField("#Mod_Status", (enabled) ? "+" : "-"); - if (mod_Name->isChecked()) - builder.setRowField("#Mod_Name", info->name()); - if (mod_Note->isChecked()) - builder.setRowField("#Note", QString("%1").arg(info->comments().remove(','))); - if (primary_Category->isChecked()) - builder.setRowField("#Primary_Category", (m_CategoryFactory->categoryExists(info->primaryCategory())) ? m_CategoryFactory->getCategoryNameByID(info->primaryCategory()) : ""); - if (nexus_ID->isChecked()) - builder.setRowField("#Nexus_ID", info->nexusId()); - if (mod_Nexus_URL->isChecked()) - builder.setRowField("#Mod_Nexus_URL",(info->nexusId()>0)? NexusInterface::instance(&m_PluginContainer)->getModURL(info->nexusId(), info->gameName()) : ""); - if (mod_Version->isChecked()) - builder.setRowField("#Mod_Version", info->version().canonicalString()); - if (install_Date->isChecked()) - builder.setRowField("#Install_Date", info->creationTime().toString("yyyy/MM/dd HH:mm:ss")); - if (download_File_Name->isChecked()) - builder.setRowField("#Download_File_Name", info->installationFile()); - - builder.writeRow(); - } - } - - SaveTextAsDialog saveDialog(this); - saveDialog.setText(buffer.data()); - saveDialog.exec(); - } - catch (const std::exception &e) { - reportError(tr("export failed: %1").arg(e.what())); - } - } -} - -static void addMenuAsPushButton(QMenu *menu, QMenu *subMenu) -{ - QPushButton *pushBtn = new QPushButton(subMenu->title()); - pushBtn->setMenu(subMenu); - QWidgetAction *action = new QWidgetAction(menu); - action->setDefaultWidget(pushBtn); - menu->addAction(action); -} - QMenu* MainWindow::openFolderMenu() { QMenu* FolderMenu = new QMenu(this); @@ -4010,65 +2909,6 @@ void MainWindow::originModified(int originID) DirectoryRefresher::cleanStructure(m_OrganizerCore.directoryStructure()); } - -void MainWindow::enableSelectedPlugins_clicked() -{ - m_OrganizerCore.pluginList()->enableSelected(ui->espList->selectionModel()); -} - - -void MainWindow::disableSelectedPlugins_clicked() -{ - m_OrganizerCore.pluginList()->disableSelected(ui->espList->selectionModel()); -} - -void MainWindow::sendSelectedPluginsToTop_clicked() -{ - m_OrganizerCore.pluginList()->sendToPriority(ui->espList->selectionModel(), 0); -} - -void MainWindow::sendSelectedPluginsToBottom_clicked() -{ - m_OrganizerCore.pluginList()->sendToPriority(ui->espList->selectionModel(), INT_MAX); -} - -void MainWindow::sendSelectedPluginsToPriority_clicked() -{ - bool ok; - int newPriority = QInputDialog::getInt(this, - tr("Set Priority"), tr("Set the priority of the selected plugins"), - 0, 0, INT_MAX, 1, &ok); - if (!ok) return; - - m_OrganizerCore.pluginList()->sendToPriority(ui->espList->selectionModel(), newPriority); -} - -void MainWindow::requestNexusCategories() -{ - CategoriesDialog dialog(&m_PluginContainer, this); - - if (dialog.exec() == QDialog::Accepted) { - dialog.commitChanges(); - } -} - -void MainWindow::enableSelectedMods_clicked() -{ - m_OrganizerCore.modList()->enableSelected(ui->modList->selectionModel()); - if (m_ModListSortProxy != nullptr) { - m_ModListSortProxy->invalidate(); - } -} - - -void MainWindow::disableSelectedMods_clicked() -{ - m_OrganizerCore.modList()->disableSelected(ui->modList->selectionModel()); - if (m_ModListSortProxy != nullptr) { - m_ModListSortProxy->invalidate(); - } -} - void MainWindow::updateAvailable() { ui->actionUpdate->setEnabled(true); @@ -4813,67 +3653,7 @@ void MainWindow::on_displayCategoriesBtn_toggled(bool checked) setCategoryListVisible(checked); } -void MainWindow::deselectFilters() -{ - m_Filters->clearSelection(); -} - -void MainWindow::refreshFilters() -{ - QItemSelection currentSelection = ui->modList->selectionModel()->selection(); - - int idxRow = ui->modList->currentIndex().row(); - QVariant currentIndexName = ui->modList->model()->index(idxRow, 0).data(); - ui->modList->setCurrentIndex(QModelIndex()); - - m_Filters->refresh(); - - ui->modList->selectionModel()->select(currentSelection, QItemSelectionModel::Select); - - QModelIndexList matchList; - if (currentIndexName.isValid()) { - matchList = ui->modList->model()->match( - ui->modList->model()->index(0, 0), - Qt::DisplayRole, - currentIndexName); - } - - if (matchList.size() > 0) { - ui->modList->setCurrentIndex(matchList.at(0)); - } -} - -void MainWindow::onFiltersCriteria(const std::vector<ModListSortProxy::Criteria>& criteria) -{ - m_ModListSortProxy->setCriteria(criteria); - - QString label = "?"; - - if (criteria.empty()) { - label = ""; - } else if (criteria.size() == 1) { - const auto& c = criteria[0]; - - if (c.type == ModListSortProxy::TypeContent) { - const auto *content = m_OrganizerCore.modDataContents().findById(c.id); - label = content ? content->name() : QString(); - } else { - label = m_CategoryFactory->getCategoryNameByID(c.id); - } - - if (label.isEmpty()) { - log::error("category {}:{} not found", c.type, c.id); - } - } else { - label = tr("<Multiple>"); - } - - ui->currentCategoryLabel->setText(label); - ui->modList->reset(); -} - -void MainWindow::onFiltersOptions( - ModListSortProxy::FilterMode mode, ModListSortProxy::SeparatorsMode sep) +void MainWindow::removeFromToolbar(QAction* action) { const auto& title = action->text(); auto& list = *m_OrganizerCore.executablesList(); diff --git a/src/mainwindow.h b/src/mainwindow.h index 67e88846..eae50aa0 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -157,13 +157,6 @@ public: public slots: void refresherProgress(const DirectoryRefreshProgress* p); - void directory_refreshed(); - - void toolPluginInvoke(); - void modPagePluginInvoke(); - - void requestNexusCategories(); - signals: // emitted after the information dialog has been closed, used by tutorials // @@ -290,8 +283,6 @@ private: QAction* m_ContextAction; - QAction* m_browseModPage; - CategoryFactory* m_CategoryFactory; QTimer m_CheckBSATimer; diff --git a/src/moapplication.h b/src/moapplication.h index 43ae6243..498242f3 100644 --- a/src/moapplication.h +++ b/src/moapplication.h @@ -23,7 +23,6 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include "env.h" #include <QApplication> #include <QFileSystemWatcher> -#include "env.h" class Settings; class MOMultiProcess; diff --git a/src/modinfodialogcategories.cpp b/src/modinfodialogcategories.cpp index 8819c0fa..5665df9f 100644 --- a/src/modinfodialogcategories.cpp +++ b/src/modinfodialogcategories.cpp @@ -44,19 +44,19 @@ bool CategoriesTab::usesOriginFiles() const return false; } -void CategoriesTab::add( - const CategoryFactory* factory, const std::set<int>& enabledCategories, - QTreeWidgetItem* root, int rootLevel) +void CategoriesTab::add(const CategoryFactory* factory, + const std::set<int>& enabledCategories, QTreeWidgetItem* root, + int rootLevel) { - for (int i=0; i<static_cast<int>(factory->numCategories()); ++i) { + for (int i = 0; i < static_cast<int>(factory->numCategories()); ++i) { if (factory->getParentID(i) != rootLevel) { continue; } int categoryID = factory->getCategoryID(i); - QTreeWidgetItem* newItem - = new QTreeWidgetItem(QStringList(factory->getCategoryName(i))); + QTreeWidgetItem* newItem = + new QTreeWidgetItem(QStringList(factory->getCategoryName(i))); newItem->setFlags(newItem->flags() | Qt::ItemIsUserCheckable); diff --git a/src/modinfodialogcategories.h b/src/modinfodialogcategories.h index e73bfa32..b390146c 100644 --- a/src/modinfodialogcategories.h +++ b/src/modinfodialogcategories.h @@ -13,9 +13,8 @@ public: bool usesOriginFiles() const override; private: - void add( - const CategoryFactory* factory, const std::set<int>& enabledCategories, - QTreeWidgetItem* root, int rootLevel); + void add(const CategoryFactory* factory, const std::set<int>& enabledCategories, + QTreeWidgetItem* root, int rootLevel); void updatePrimary(); void addChecked(QTreeWidgetItem* tree); diff --git a/src/modinforegular.cpp b/src/modinforegular.cpp index e238075a..58590477 100644 --- a/src/modinforegular.cpp +++ b/src/modinforegular.cpp @@ -212,7 +212,8 @@ void ModInfoRegular::readMeta() // ignore invalid id continue; } - if (ok && (categoryID != 0) && (CategoryFactory::instance()->categoryExists(categoryID))) { + if (ok && (categoryID != 0) && + (CategoryFactory::instance()->categoryExists(categoryID))) { m_Categories.insert(categoryID); if (iter == categories.begin()) { m_PrimaryCategory = categoryID; diff --git a/src/modlist.cpp b/src/modlist.cpp index 41d679d9..9f64cc71 100644 --- a/src/modlist.cpp +++ b/src/modlist.cpp @@ -285,10 +285,11 @@ QVariant ModList::data(const QModelIndex& modelIndex, int role) const } else if (role == GroupingRole) { if (column == COL_CATEGORY) { QVariantList categoryNames; - std::set<int> categories = modInfo->getCategories(); + std::set<int> categories = modInfo->getCategories(); CategoryFactory* categoryFactory = CategoryFactory::instance(); for (auto iter = categories.begin(); iter != categories.end(); ++iter) { - categoryNames.append(categoryFactory->getCategoryName(categoryFactory->getCategoryIndex(*iter))); + categoryNames.append( + categoryFactory->getCategoryName(categoryFactory->getCategoryIndex(*iter))); } if (categoryNames.count() != 0) { return categoryNames; @@ -453,7 +454,10 @@ QVariant ModList::data(const QModelIndex& modelIndex, int role) const categoryString << " , "; } try { - categoryString << "<span style=\"white-space: nowrap;\"><i>" << ToWString(categoryFactory->getCategoryName(categoryFactory->getCategoryIndex(*catIter))) << "</font></span>"; + categoryString << "<span style=\"white-space: nowrap;\"><i>" + << ToWString(categoryFactory->getCategoryName( + categoryFactory->getCategoryIndex(*catIter))) + << "</font></span>"; } catch (const std::exception& e) { log::error("failed to generate tooltip: {}", e.what()); return QString(); diff --git a/src/modlistcontextmenu.cpp b/src/modlistcontextmenu.cpp index 6954652e..06cd19d6 100644 --- a/src/modlistcontextmenu.cpp +++ b/src/modlistcontextmenu.cpp @@ -95,7 +95,7 @@ void ModListGlobalContextMenu::populate(OrganizerCore& core, ModListView* view, view->actions().checkModsForUpdates(); }); addAction(tr("Auto assign categories"), [=]() { - view->actions().assignCategories(); + view->actions().assignCategories(); }); addAction(tr("Refresh"), &core, &OrganizerCore::profileRefresh); addAction(tr("Export to csv..."), [=]() { @@ -187,11 +187,11 @@ void ModListPrimaryCategoryMenu::populate(const CategoryFactory* factory, clear(); const std::set<int>& categories = mod->getCategories(); for (int categoryID : categories) { - int catIdx = factory.getCategoryIndex(categoryID); + int catIdx = factory->getCategoryIndex(categoryID); QWidgetAction* action = new QWidgetAction(this); try { QRadioButton* categoryBox = - new QRadioButton(factory.getCategoryName(catIdx).replace('&', "&&"), this); + new QRadioButton(factory->getCategoryName(catIdx).replace('&', "&&"), this); categoryBox->setChecked(categoryID == mod->primaryCategory()); action->setDefaultWidget(categoryBox); action->setData(categoryID); diff --git a/src/modlistsortproxy.cpp b/src/modlistsortproxy.cpp index 1d54dfa4..e61f9494 100644 --- a/src/modlistsortproxy.cpp +++ b/src/modlistsortproxy.cpp @@ -125,104 +125,111 @@ bool ModListSortProxy::lessThan(const QModelIndex& left, const QModelIndex& righ right.data(ModList::PriorityRole).toInt(); switch (left.column()) { - case ModList::COL_FLAGS: { - std::vector<ModInfo::EFlag> leftFlags = leftMod->getFlags(); - std::vector<ModInfo::EFlag> rightFlags = rightMod->getFlags(); - if (leftFlags.size() != rightFlags.size()) { - lt = leftFlags.size() < rightFlags.size(); - } else { - lt = flagsId(leftFlags) < flagsId(rightFlags); - } - } break; - case ModList::COL_CONFLICTFLAGS: { - std::vector<ModInfo::EConflictFlag> leftFlags = leftMod->getConflictFlags(); - std::vector<ModInfo::EConflictFlag> rightFlags = rightMod->getConflictFlags(); - if (leftFlags.size() != rightFlags.size()) { - lt = leftFlags.size() < rightFlags.size(); - } else { - lt = conflictFlagsId(leftFlags) < conflictFlagsId(rightFlags); - } - } break; - case ModList::COL_CONTENT: { - const auto& lContents = leftMod->getContents(); - const auto& rContents = rightMod->getContents(); - unsigned int lValue = 0; - unsigned int rValue = 0; - m_Organizer->modDataContents().forEachContentIn( + case ModList::COL_FLAGS: { + std::vector<ModInfo::EFlag> leftFlags = leftMod->getFlags(); + std::vector<ModInfo::EFlag> rightFlags = rightMod->getFlags(); + if (leftFlags.size() != rightFlags.size()) { + lt = leftFlags.size() < rightFlags.size(); + } else { + lt = flagsId(leftFlags) < flagsId(rightFlags); + } + } break; + case ModList::COL_CONFLICTFLAGS: { + std::vector<ModInfo::EConflictFlag> leftFlags = leftMod->getConflictFlags(); + std::vector<ModInfo::EConflictFlag> rightFlags = rightMod->getConflictFlags(); + if (leftFlags.size() != rightFlags.size()) { + lt = leftFlags.size() < rightFlags.size(); + } else { + lt = conflictFlagsId(leftFlags) < conflictFlagsId(rightFlags); + } + } break; + case ModList::COL_CONTENT: { + const auto& lContents = leftMod->getContents(); + const auto& rContents = rightMod->getContents(); + unsigned int lValue = 0; + unsigned int rValue = 0; + m_Organizer->modDataContents().forEachContentIn( lContents, [&lValue](auto const& content) { lValue += 2U << static_cast<unsigned int>(content.id()); }); - m_Organizer->modDataContents().forEachContentIn( + m_Organizer->modDataContents().forEachContentIn( rContents, [&rValue](auto const& content) { rValue += 2U << static_cast<unsigned int>(content.id()); - }); - lt = lValue < rValue; - } break; - case ModList::COL_NAME: { - int comp = QString::compare(leftMod->name(), rightMod->name(), Qt::CaseInsensitive); - if (comp != 0) - lt = comp < 0; - } break; - case ModList::COL_CATEGORY: { - if (leftMod->primaryCategory() != rightMod->primaryCategory()) { - if (leftMod->primaryCategory() < 0) - lt = false; - else if (rightMod->primaryCategory() < 0) - lt = true; - else { - try { - CategoryFactory* categories = CategoryFactory::instance(); - QString leftCatName = categories->getCategoryName(categories->getCategoryIndex(leftMod->primaryCategory())); - QString rightCatName = categories->getCategoryName(categories->getCategoryIndex(rightMod->primaryCategory())); - lt = leftCatName < rightCatName; - } catch (const std::exception& e) { - log::error("failed to compare categories: {}", e.what()); - } + }); + lt = lValue < rValue; + } break; + case ModList::COL_NAME: { + int comp = QString::compare(leftMod->name(), rightMod->name(), Qt::CaseInsensitive); + if (comp != 0) + lt = comp < 0; + } break; + case ModList::COL_CATEGORY: { + if (leftMod->primaryCategory() != rightMod->primaryCategory()) { + if (leftMod->primaryCategory() < 0) + lt = false; + else if (rightMod->primaryCategory() < 0) + lt = true; + else { + try { + CategoryFactory* categories = CategoryFactory::instance(); + QString leftCatName = categories->getCategoryName( + categories->getCategoryIndex(leftMod->primaryCategory())); + QString rightCatName = categories->getCategoryName( + categories->getCategoryIndex(rightMod->primaryCategory())); + lt = leftCatName < rightCatName; + } catch (const std::exception& e) { + log::error("failed to compare categories: {}", e.what()); } } - } break; - case ModList::COL_MODID: { - if (leftMod->nexusId() != rightMod->nexusId()) - lt = leftMod->nexusId() < rightMod->nexusId(); - } break; - case ModList::COL_VERSION: { - if (leftMod->version() != rightMod->version()) - lt = leftMod->version() < rightMod->version(); - } break; - case ModList::COL_INSTALLTIME: { - QDateTime leftTime = left.data().toDateTime(); - QDateTime rightTime = right.data().toDateTime(); - if (leftTime != rightTime) - return leftTime < rightTime; - } break; - case ModList::COL_GAME: { - if (leftMod->gameName() != rightMod->gameName()) { - lt = leftMod->gameName() < rightMod->gameName(); + } + } break; + case ModList::COL_MODID: { + if (leftMod->nexusId() != rightMod->nexusId()) + lt = leftMod->nexusId() < rightMod->nexusId(); + } break; + case ModList::COL_VERSION: { + if (leftMod->version() != rightMod->version()) + lt = leftMod->version() < rightMod->version(); + } break; + case ModList::COL_INSTALLTIME: { + QDateTime leftTime = left.data().toDateTime(); + QDateTime rightTime = right.data().toDateTime(); + if (leftTime != rightTime) + return leftTime < rightTime; + } break; + case ModList::COL_GAME: { + if (leftMod->gameName() != rightMod->gameName()) { + lt = leftMod->gameName() < rightMod->gameName(); + } else { + int comp = + QString::compare(leftMod->name(), rightMod->name(), Qt::CaseInsensitive); + if (comp != 0) + lt = comp < 0; + } + } break; + case ModList::COL_NOTES: { + QString leftComments = leftMod->comments(); + QString rightComments = rightMod->comments(); + if (leftComments != rightComments) { + if (leftComments.isEmpty()) { + lt = sortOrder() == Qt::DescendingOrder; + } else if (rightComments.isEmpty()) { + lt = sortOrder() == Qt::AscendingOrder; } else { - int comp = QString::compare(leftMod->name(), rightMod->name(), Qt::CaseInsensitive); - if (comp != 0) - lt = comp < 0; - } - } break; - case ModList::COL_NOTES: { - QString leftComments = leftMod->comments(); - QString rightComments = rightMod->comments(); - if (leftComments != rightComments) { - if (leftComments.isEmpty()) { - lt = sortOrder() == Qt::DescendingOrder; - } else if (rightComments.isEmpty()) { - lt = sortOrder() == Qt::AscendingOrder; - } else { - lt = leftComments < rightComments; - } + lt = leftComments < rightComments; } - } break; - case ModList::COL_PRIORITY: { - // nop, already compared by priority - } break; - default: { - log::warn("Sorting is not defined for column {}", left.column()); - } break; + } + } break; + case ModList::COL_PRIORITY: { + if (leftMod->isBackup() != rightMod->isBackup()) { + lt = leftMod->isBackup(); + } else if (leftMod->isOverwrite() != rightMod->isOverwrite()) { + lt = rightMod->isOverwrite(); + } + } break; + default: { + log::warn("Sorting is not defined for column {}", left.column()); + } break; } return lt; } diff --git a/src/nexusinterface.h b/src/nexusinterface.h index b79127af..5fab222f 100644 --- a/src/nexusinterface.h +++ b/src/nexusinterface.h @@ -135,7 +135,8 @@ public slots: void nxmTrackedModsAvailable(QVariant userData, QVariant resultData, int requestID); void nxmTrackingToggled(QString gameName, int modID, QVariant userData, bool tracked, int requestID); - void nxmGameInfoAvailable(QString gameName, QVariant userData, QVariant resultData, int requestID); + void nxmGameInfoAvailable(QString gameName, QVariant userData, QVariant resultData, + int requestID); void nxmRequestFailed(QString gameName, int modID, int fileID, QVariant userData, int requestID, int errorCode, const QString& errorMessage); @@ -452,16 +453,18 @@ public: MOBase::IPluginGame const* game); /** - * @param gameName the game short name to support multiple game sources - * @brief toggle tracking state of the mod - * @param modID id of the mod - * @param track true if the mod should be tracked, false for not tracked - * @param receiver the object to receive the result asynchronously via a signal (nxmFilesAvailable) - * @param userData user data to be returned with the result - * @param game the game with which the mods are associated - * @return int an id to identify the request - */ - int requestGameInfo(QString gameName, QObject* receiver, QVariant userData, const QString& subModule) + * @param gameName the game short name to support multiple game sources + * @brief toggle tracking state of the mod + * @param modID id of the mod + * @param track true if the mod should be tracked, false for not tracked + * @param receiver the object to receive the result asynchronously via a signal + * (nxmFilesAvailable) + * @param userData user data to be returned with the result + * @param game the game with which the mods are associated + * @return int an id to identify the request + */ + int requestGameInfo(QString gameName, QObject* receiver, QVariant userData, + const QString& subModule) { return requestGameInfo(gameName, receiver, userData, subModule, getGame(gameName)); } @@ -588,7 +591,8 @@ signals: void nxmTrackedModsAvailable(QVariant userData, QVariant resultData, int requestID); void nxmTrackingToggled(QString gameName, int modID, QVariant userData, bool tracked, int requestID); - void nxmGameInfoAvailable(QString gameName, QVariant userData, QVariant resultData, int requestID); + void nxmGameInfoAvailable(QString gameName, QVariant userData, QVariant resultData, + int requestID); void nxmRequestFailed(QString gameName, int modID, int fileID, QVariant userData, int requestID, int errorCode, const QString& errorString); void requestsChanged(const APIStats& stats, const APIUserAccount& user); diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index 40921d9d..3ed66456 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -1052,8 +1052,8 @@ If you disable this feature, MO will only display official DLCs this way. Please <rect> <x>0</x> <y>0</y> - <width>761</width> - <height>515</height> + <width>778</width> + <height>497</height> </rect> </property> <property name="autoFillBackground"> @@ -1742,8 +1742,8 @@ If you disable this feature, MO will only display official DLCs this way. Please <rect> <x>0</x> <y>0</y> - <width>390</width> - <height>342</height> + <width>778</width> + <height>475</height> </rect> </property> <property name="autoFillBackground"> diff --git a/src/settingsdialoggeneral.cpp b/src/settingsdialoggeneral.cpp index 4ce72110..6a666437 100644 --- a/src/settingsdialoggeneral.cpp +++ b/src/settingsdialoggeneral.cpp @@ -160,7 +160,7 @@ void GeneralSettingsTab::resetDialogs() void GeneralSettingsTab::onEditCategories() { - CategoriesDialog dialog(m_PluginContainer, &dialog()); + CategoriesDialog catDialog(m_PluginContainer, &dialog()); if (catDialog.exec() == QDialog::Accepted) { catDialog.commitChanges(); |
