From c50ad588432a27612fe5be39b1520e2962d5eef7 Mon Sep 17 00:00:00 2001 From: Jeremy Rimpo Date: Tue, 19 Sep 2023 02:37:24 -0500 Subject: Add nexus category ID to mod info - We will check the mod info first then fall back to the download file - Add category field in the info dialog nexus tab --- src/mainwindow.cpp | 2 + src/modinfo.h | 10 ++ src/modinfobackup.h | 2 + src/modinfodialog.ui | 25 ++++- src/modinfodialognexus.cpp | 16 ++++ src/modinfodialognexus.h | 1 + src/modinfoforeign.h | 2 + src/modinfooverwrite.h | 2 + src/modinforegular.cpp | 23 ++++- src/modinforegular.h | 11 +++ src/modinfoseparator.h | 2 + src/modlistviewactions.cpp | 44 +++++---- src/organizer_en.ts | 233 +++++++++++++++++++++++---------------------- src/version.rc | 53 ++++------- 14 files changed, 255 insertions(+), 171 deletions(-) (limited to 'src') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 18a288c6..ac4e093d 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -4476,6 +4476,8 @@ void MainWindow::nxmModInfoAvailable(QString gameName, int modID, QVariant userD mod->setNexusDescription(result["description"].toString()); + mod->setNexusCategory(result["category_id"].toInt()); + if ((mod->endorsedState() != EndorsedState::ENDORSED_NEVER) && (result.contains("endorsement"))) { QVariantMap endorsement = result["endorsement"].toMap(); diff --git a/src/modinfo.h b/src/modinfo.h index 9895d44c..0736aa20 100644 --- a/src/modinfo.h +++ b/src/modinfo.h @@ -887,6 +887,16 @@ public: // Nexus stuff * @brief Set the last time the mod was updated on Nexus. */ virtual void setNexusLastModified(QDateTime time) = 0; + + /** + * @return the assigned nexus category ID + */ + virtual int getNexusCategory() const = 0; + + /** + * @brief Assigns the given Nexus category ID + */ + virtual void setNexusCategory(int category) = 0; public: // Conflicts // retrieve the list of mods (as mod index) that are overwritten by this one. diff --git a/src/modinfobackup.h b/src/modinfobackup.h index 01abf184..0c3c29d7 100644 --- a/src/modinfobackup.h +++ b/src/modinfobackup.h @@ -38,6 +38,8 @@ public: virtual QDateTime getNexusLastModified() const override { return QDateTime(); } virtual void setNexusLastModified(QDateTime) override {} virtual QString getNexusDescription() const override { return QString(); } + virtual void setNexusCategory(int) override {} + virtual int getNexusCategory() const override { return 0; } virtual bool isBackup() const override { return true; } virtual void addInstalledFile(int, int) override {} diff --git a/src/modinfodialog.ui b/src/modinfodialog.ui index 269aebe3..53655aa5 100644 --- a/src/modinfodialog.ui +++ b/src/modinfodialog.ui @@ -966,7 +966,7 @@ text-align: left; 0 - + @@ -1026,6 +1026,29 @@ p, li { white-space: pre-wrap; } + + + + Category + + + + + + + + 1 + 0 + + + + + 0 + 0 + + + + diff --git a/src/modinfodialognexus.cpp b/src/modinfodialognexus.cpp index 56636145..485f138a 100644 --- a/src/modinfodialognexus.cpp +++ b/src/modinfodialognexus.cpp @@ -32,6 +32,9 @@ NexusTab::NexusTab(ModInfoDialogTabContext cx) connect(ui->version, &QLineEdit::editingFinished, [&] { onVersionChanged(); }); + connect(ui->category, &QLineEdit::editingFinished, [&] { + onCategoryChanged(); + }); connect(ui->refresh, &QPushButton::clicked, [&] { onRefreshBrowser(); @@ -75,6 +78,7 @@ void NexusTab::clear() ui->modID->clear(); ui->sourceGame->clear(); ui->version->clear(); + ui->category->clear(); ui->browser->setPage(new NexusTabWebpage(ui->browser)); ui->hasCustomURL->setChecked(false); ui->customURL->clear(); @@ -108,6 +112,8 @@ void NexusTab::update() ui->sourceGame->setCurrentIndex(ui->sourceGame->findData(gameName)); + ui->category->setText(QString("%1").arg(mod().getNexusCategory())); + auto* page = new NexusTabWebpage(ui->browser); ui->browser->setPage(page); @@ -360,6 +366,16 @@ void NexusTab::onVersionChanged() updateVersionColor(); } +void NexusTab::onCategoryChanged() +{ + if (m_loading) { + return; + } + + int category = ui->category->text().toInt(); + mod().setNexusCategory(category); +} + void NexusTab::onRefreshBrowser() { const auto modID = mod().nexusId(); diff --git a/src/modinfodialognexus.h b/src/modinfodialognexus.h index e9a8720f..e752018a 100644 --- a/src/modinfodialognexus.h +++ b/src/modinfodialognexus.h @@ -57,6 +57,7 @@ private: void onModIDChanged(); void onSourceGameChanged(); void onVersionChanged(); + void onCategoryChanged(); void onRefreshBrowser(); void onVisitNexus(); diff --git a/src/modinfoforeign.h b/src/modinfoforeign.h index 2c956fb7..dc66e1b0 100644 --- a/src/modinfoforeign.h +++ b/src/modinfoforeign.h @@ -60,6 +60,8 @@ public: virtual void setNexusFileStatus(int) override {} virtual QDateTime getLastNexusUpdate() const override { return QDateTime(); } virtual void setLastNexusUpdate(QDateTime) override {} + virtual int getNexusCategory() const override { return 0; } + virtual void setNexusCategory(int) override {} virtual QDateTime getLastNexusQuery() const override { return QDateTime(); } virtual void setLastNexusQuery(QDateTime) override {} virtual QDateTime getNexusLastModified() const override { return QDateTime(); } diff --git a/src/modinfooverwrite.h b/src/modinfooverwrite.h index 02154902..45b5bbdd 100644 --- a/src/modinfooverwrite.h +++ b/src/modinfooverwrite.h @@ -68,6 +68,8 @@ public: virtual QDateTime getNexusLastModified() const override { return QDateTime(); } virtual void setNexusLastModified(QDateTime) override {} virtual QString getNexusDescription() const override { return QString(); } + virtual void setNexusCategory(int) override {} + virtual int getNexusCategory() const override { return 0; } virtual QStringList archives(bool checkOnDisk = false) override; virtual void addInstalledFile(int, int) override {} virtual std::set> installedFiles() const override { return {}; } diff --git a/src/modinforegular.cpp b/src/modinforegular.cpp index 9cb89307..e238075a 100644 --- a/src/modinforegular.cpp +++ b/src/modinforegular.cpp @@ -97,6 +97,7 @@ void ModInfoRegular::readMeta() m_InstallationFile = metaFile.value("installationFile", "").toString(); m_NexusDescription = metaFile.value("nexusDescription", "").toString(); m_NexusFileStatus = metaFile.value("nexusFileStatus", "1").toInt(); + m_NexusCategory = metaFile.value("nexusCategory", 0).toInt(); m_Repository = metaFile.value("repository", "Nexus").toString(); m_Converted = metaFile.value("converted", false).toBool(); m_Validated = metaFile.value("validated", false).toBool(); @@ -171,10 +172,11 @@ void ModInfoRegular::readMeta() m_NexusLastModified = QDateTime::fromString( metaFile.value("nexusLastModified", QDateTime::currentDateTimeUtc()).toString(), Qt::ISODate); - m_Color = metaFile.value("color", QColor()).value(); - m_TrackedState = metaFile.value("tracked", false).toBool() - ? TrackedState::TRACKED_TRUE - : TrackedState::TRACKED_FALSE; + m_NexusCategory = metaFile.value("nexusCategory", 0).toInt(); + m_Color = metaFile.value("color", QColor()).value(); + m_TrackedState = metaFile.value("tracked", false).toBool() + ? TrackedState::TRACKED_TRUE + : TrackedState::TRACKED_FALSE; if (metaFile.contains("endorsed")) { if (metaFile.value("endorsed").canConvert()) { using ut = std::underlying_type_t; @@ -266,6 +268,7 @@ void ModInfoRegular::saveMeta() metaFile.setValue("lastNexusQuery", m_LastNexusQuery.toString(Qt::ISODate)); metaFile.setValue("lastNexusUpdate", m_LastNexusUpdate.toString(Qt::ISODate)); metaFile.setValue("nexusLastModified", m_NexusLastModified.toString(Qt::ISODate)); + metaFile.setValue("nexusCategory", m_NexusCategory); metaFile.setValue("converted", m_Converted); metaFile.setValue("validated", m_Validated); metaFile.setValue("color", m_Color); @@ -833,6 +836,18 @@ void ModInfoRegular::setNexusLastModified(QDateTime time) emit modDetailsUpdated(true); } +int ModInfoRegular::getNexusCategory() const +{ + return m_NexusCategory; +} + +void ModInfoRegular::setNexusCategory(int category) +{ + m_NexusCategory = category; + m_MetaInfoChanged = true; + saveMeta(); +} + void ModInfoRegular::setCustomURL(QString const& url) { m_CustomURL = url; diff --git a/src/modinforegular.h b/src/modinforegular.h index 6c85d66c..a408d966 100644 --- a/src/modinforegular.h +++ b/src/modinforegular.h @@ -379,6 +379,16 @@ public: */ virtual void setNexusLastModified(QDateTime time) override; + /** + * @return the assigned nexus category ID + */ + virtual int getNexusCategory() const override; + + /** + * @brief Assigns the given Nexus category ID + */ + virtual void setNexusCategory(int category) override; + virtual QStringList archives(bool checkOnDisk = false) override; virtual void setColor(QColor color) override; @@ -457,6 +467,7 @@ private: QDateTime m_LastNexusQuery; QDateTime m_LastNexusUpdate; QDateTime m_NexusLastModified; + int m_NexusCategory; QColor m_Color; diff --git a/src/modinfoseparator.h b/src/modinfoseparator.h index c34dd92b..67bc3d56 100644 --- a/src/modinfoseparator.h +++ b/src/modinfoseparator.h @@ -45,6 +45,8 @@ public: virtual void setLastNexusQuery(QDateTime) override {} virtual QDateTime getNexusLastModified() const override { return QDateTime(); } virtual void setNexusLastModified(QDateTime) override {} + virtual int getNexusCategory() const override { return 0; } + virtual void setNexusCategory(int) override {} virtual QDateTime creationTime() const override { return QDateTime(); } virtual QString getNexusDescription() const override { return QString(); } virtual void addInstalledFile(int /*modId*/, int /*fileId*/) override {} diff --git a/src/modlistviewactions.cpp b/src/modlistviewactions.cpp index aa962c1e..a86c9067 100644 --- a/src/modlistviewactions.cpp +++ b/src/modlistviewactions.cpp @@ -265,18 +265,20 @@ void ModListViewActions::assignCategories() const for (auto mod : m_core.modList()->allMods()) { ModInfo::Ptr modInfo = ModInfo::getByName(mod); QString file = modInfo->installationFile(); - auto download = m_core.downloadManager()->getDownloadIndex(file); - if (download >= 0) { - int nexusCategory = m_core.downloadManager()->getCategoryID(download); - int newCategory = CategoryFactory::instance()->resolveNexusID(nexusCategory); - if (newCategory != 0) { - for (auto category : modInfo->categories()) { - modInfo->removeCategory(category); - } + int nexusCategory = modInfo->getNexusCategory(); + if (!nexusCategory) { + auto download = m_core.downloadManager()->getDownloadIndex(file); + if (download >= 0) { + int nexusCategory = m_core.downloadManager()->getCategoryID(download); + } + } + int newCategory = CategoryFactory::instance()->resolveNexusID(nexusCategory); + if (newCategory != 0) { + for (auto category : modInfo->categories()) { + modInfo->removeCategory(category); } - modInfo->setCategory(CategoryFactory::instance()->getCategoryID(newCategory), - true); } + modInfo->setCategory(CategoryFactory::instance()->getCategoryID(newCategory), true); } } @@ -1108,16 +1110,20 @@ void ModListViewActions::remapCategory(const QModelIndexList& indices) const for (auto& idx : indices) { ModInfo::Ptr modInfo = ModInfo::getByIndex(idx.data(ModList::IndexRole).toInt()); - int downloadIndex = - m_core.downloadManager()->getDownloadIndex(modInfo->installationFile()); - if (downloadIndex >= 0) { - auto downloadInfo = m_core.downloadManager()->getFileInfo(downloadIndex); - unsigned int categoryIndex = - CategoryFactory::instance()->resolveNexusID(downloadInfo->categoryID); - if (categoryIndex != 0) - modInfo->setPrimaryCategory( - CategoryFactory::instance()->getCategoryID(categoryIndex)); + int categoryID = modInfo->getNexusCategory(); + if (!categoryID) { + int downloadIndex = + m_core.downloadManager()->getDownloadIndex(modInfo->installationFile()); + if (downloadIndex >= 0) { + auto downloadInfo = m_core.downloadManager()->getFileInfo(downloadIndex); + categoryID = downloadInfo->categoryID; + } } + unsigned int categoryIndex = + CategoryFactory::instance()->resolveNexusID(categoryID); + if (categoryIndex != 0) + modInfo->setPrimaryCategory( + CategoryFactory::instance()->getCategoryID(categoryIndex)); } } diff --git a/src/organizer_en.ts b/src/organizer_en.ts index 71be4187..228b275a 100644 --- a/src/organizer_en.ts +++ b/src/organizer_en.ts @@ -4048,115 +4048,115 @@ You will have to visit the mod page on the %1 Nexus site to change your mind. - + Thank you! - + Thank you for your endorsement! - + Mod ID %1 no longer seems to be available on Nexus. - + Error %1: Request to Nexus failed: %2 - - + + failed to read %1: %2 - + Error - + failed to extract %1 (errorcode %2) - + Extract BSA - + This archive contains invalid hashes. Some files may be broken. - + Extract... - + Remove '%1' from the toolbar - + Backup of load order created - + Choose backup to restore - + No Backups - + There are no backups to restore - - + + Restore failed - - + + Failed to restore the backup. Errorcode: %1 - + Backup of mod list created - + A file with the same name has already been downloaded. What would you like to do? - + Overwrite - + Rename new file - + Ignore file @@ -4480,88 +4480,93 @@ p, li { white-space: pre-wrap; } - - + + Category + + + + + Refresh - + Refresh all information from Nexus. - - + + Open in Browser - + Endorse - + Track - + about:blank - + Use Custom URL - + Notes - - - + + + Enter comments about the mod here. These are displayed in the notes column of the mod list. - + Set Color - + Reset Color - - - + + + Enter notes about the mod here. These can be viewed in the mod list by hovering over the notes column or the flags column. - + Filetree - + Open Mod in Explorer - + A directory view of this mod - + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } @@ -4571,17 +4576,17 @@ p, li { white-space: pre-wrap; } - + Previous - + Next - + Close @@ -4620,12 +4625,12 @@ p, li { white-space: pre-wrap; } ModInfoRegular - + %1 contains no esp/esm/esl and no asset (textures, meshes, interface, ...) directory - + Categories: <br> @@ -5324,7 +5329,7 @@ Please enter the name: - + Create Mod... @@ -5336,7 +5341,7 @@ Please enter a name: - + A mod with this name already exists @@ -5368,258 +5373,258 @@ Please enter a name: - - + + Confirm - + You are not currently authenticated with Nexus. Please do so under Settings -> Nexus. - + Export to csv - + CSV (Comma Separated Values) is a format that can be imported in programs like Excel to create a spreadsheet. You can also use online editors and converters instead. - + Select what mods you want export: - + All installed mods - + Only active (checked) mods from your current profile - + All currently visible mods in the mod list - + Choose what Columns to export: - + Mod_Priority - + Mod_Name - + Notes_column - + Mod_Status - + Primary_Category - + Nexus_ID - + Mod_Nexus_URL - + Mod_Version - + Install_Date - + Download_File_Name - + export failed: %1 - + Failed to display overwrite dialog: %1 - + Set Priority - + Set the priority of the selected mods - + failed to rename mod: %1 - + Remove the following mods?<br><ul>%1</ul> - + failed to remove mod: %1 - + Continue? - + The versioning scheme decides which version is considered newer than another. This function will guess the versioning scheme under the assumption that the installed version is outdated. - + Sorry - + I don't know a versioning scheme where %1 is newer than %2. - + Opening Nexus Links - + You are trying to open %1 links to Nexus Mods. Are you sure you want to do this? - - + + Opening Web Pages - - + + You are trying to open %1 Web Pages. Are you sure you want to do this? - - - + + + Failed - + Installation file no longer exists - + Mods installed with old versions of MO can't be reinstalled in this way. - + Failed to create backup. - + Restore all hidden files in the following mods?<br><ul>%1</ul> - - + + Are you sure? - + About to restore all hidden files in: - + Endorsing multiple mods will take a while. Please wait... - + Overwrite? - + This will replace the existing mod "%1". Continue? - + failed to remove mod "%1" - + failed to rename "%1" to "%2" - + Move successful. - + This will move all files from overwrite into a new, regular mod. Please enter a name: - + About to recursively delete: @@ -5760,27 +5765,27 @@ Please enter a name: NexusTab - + Current Version: %1 - + No update available - + Tracked - + Untracked - + <div style="text-align: center;"> <p>This mod does not have a valid Nexus ID. You can add a custom web diff --git a/src/version.rc b/src/version.rc index 0db83d44..aa92aee1 100644 --- a/src/version.rc +++ b/src/version.rc @@ -1,37 +1,24 @@ #include "Winver.h" -// If VS_FF_PRERELEASE is not set, MO labels the build as a release and uses VER_FILEVERSION to determine version number. -// Otherwise, if letters are used in VER_FILEVERSION_STR, uses the full MOBase::VersionInfo parser -// Otherwise, uses the numbers from VER_FILEVERSION and sets the release type as pre-alpha -#define VER_FILEVERSION 2,5,0 -#define VER_FILEVERSION_STR "2.5.0-beta7\0" +// If VS_FF_PRERELEASE is not set, MO labels the build as a release and uses +// VER_FILEVERSION to determine version number. Otherwise, if letters are used in +// VER_FILEVERSION_STR, uses the full MOBase::VersionInfo parser Otherwise, uses the +// numbers from VER_FILEVERSION and sets the release type as pre-alpha +#define VER_FILEVERSION 2, 5, 0 +#define VER_FILEVERSION_STR "2.5.0-beta9\0" -VS_VERSION_INFO VERSIONINFO -FILEVERSION VER_FILEVERSION -PRODUCTVERSION VER_FILEVERSION -FILEFLAGSMASK VS_FFI_FILEFLAGSMASK -FILEFLAGS VS_FF_PRERELEASE -FILEOS VOS__WINDOWS32 -FILETYPE VFT_APP -FILESUBTYPE (0) -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904B0" - BEGIN - VALUE "FileVersion", VER_FILEVERSION_STR - VALUE "CompanyName", "Mod Organizer 2 Team\0" - VALUE "FileDescription", "Mod Organizer 2 GUI\0" - VALUE "OriginalFilename", "ModOrganizer.exe\0" - VALUE "InternalName", "ModOrganizer2\0" - VALUE "LegalCopyright", "Copyright 2011-2016 Sebastian Herbord\r\nCopyright 2016-2023 Mod Organizer 2 contributors\0" - VALUE "ProductName", "Mod Organizer 2\0" - VALUE "ProductVersion", VER_FILEVERSION_STR - END - END +VS_VERSION_INFO VERSIONINFO FILEVERSION VER_FILEVERSION PRODUCTVERSION VER_FILEVERSION + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK FILEFLAGS VS_FF_PRERELEASE FILEOS VOS__WINDOWS32 + FILETYPE VFT_APP FILESUBTYPE(0) BEGIN BLOCK + "StringFileInfo" BEGIN BLOCK "040904B0" BEGIN VALUE "FileVersion", + VER_FILEVERSION_STR VALUE "CompanyName", + "Mod Organizer 2 Team\0" VALUE "FileDescription", + "Mod Organizer 2 GUI\0" VALUE "OriginalFilename", + "ModOrganizer.exe\0" VALUE "InternalName", "ModOrganizer2\0" VALUE "LegalCopyright", + "Copyright 2011-2016 Sebastian Herbord\r\nCopyright 2016-2023 Mod Organizer 2 " + "contributors\0" VALUE "ProductName", + "Mod Organizer 2\0" VALUE "ProductVersion", + VER_FILEVERSION_STR END END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x0409, 1200 - END -END + BLOCK "VarFileInfo" BEGIN VALUE "Translation", + 0x0409, 1200 END END -- cgit v1.3.1