From 978b4b234b6ca60224e62c461d76ccc0c32009c4 Mon Sep 17 00:00:00 2001 From: Jeremy Rimpo Date: Mon, 4 Sep 2023 19:40:09 -0500 Subject: [PATCH 01/15] Parse secondary data directories into the directory structure --- src/directoryrefresher.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/directoryrefresher.cpp b/src/directoryrefresher.cpp index 90bfad3b2..e6d5524f9 100644 --- a/src/directoryrefresher.cpp +++ b/src/directoryrefresher.cpp @@ -489,6 +489,11 @@ void DirectoryRefresher::refresh() m_Root->addFromOrigin(L"data", dataDirectory, 0, dummy); } + for (auto directory : game->secondaryDataDirectories().toStdMap()) { + DirectoryStats dummy; + m_Root->addFromOrigin(directory.first.toStdWString(), QDir::toNativeSeparators(directory.second.absolutePath()).toStdWString(), 0, dummy); + } + std::sort(m_Mods.begin(), m_Mods.end(), [](auto lhs, auto rhs) { return lhs.priority < rhs.priority; }); From 69e73933b9ed7254d8260b0901ee0b2be79253f3 Mon Sep 17 00:00:00 2001 From: Jeremy Rimpo Date: Mon, 4 Sep 2023 19:43:07 -0500 Subject: [PATCH 02/15] Version bump --- src/version.rc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.rc b/src/version.rc index 804a276d0..1ae0aca3f 100644 --- a/src/version.rc +++ b/src/version.rc @@ -4,7 +4,7 @@ // 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-alpha3\0" +#define VER_FILEVERSION_STR "2.5.0-beta1\0" VS_VERSION_INFO VERSIONINFO FILEVERSION VER_FILEVERSION @@ -24,7 +24,7 @@ BEGIN 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-2022 Mod Organizer 2 contributors\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 From 3f33571a181a4e00a1169ef9eb85f37399aa4152 Mon Sep 17 00:00:00 2001 From: Jeremy Rimpo Date: Mon, 4 Sep 2023 20:08:21 -0500 Subject: [PATCH 03/15] Add VDF reader to licenses and update openssl --- src/aboutdialog.cpp | 2 ++ src/aboutdialog.h | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/aboutdialog.cpp b/src/aboutdialog.cpp index 98743e051..781848735 100644 --- a/src/aboutdialog.cpp +++ b/src/aboutdialog.cpp @@ -56,6 +56,7 @@ AboutDialog::AboutDialog(const QString &version, QWidget *parent) m_LicenseFiles[LICENSE_CASTLE] = "Castle.txt"; m_LicenseFiles[LICENSE_ANTLR] = "AntlrBuildTask.txt"; m_LicenseFiles[LICENSE_DXTEX] = "DXTex.txt"; + m_LicenseFiles[LICENSE_VDF] = "ValveFileVDF.txt"; addLicense("Qt", LICENSE_LGPL3); addLicense("Qt Json", LICENSE_GPL3); @@ -76,6 +77,7 @@ AboutDialog::AboutDialog(const QString &version, QWidget *parent) addLicense("{fmt}", LICENSE_FMT); addLicense("SIP", LICENSE_SIP); addLicense("DXTex Headers", LICENSE_DXTEX); + addLicense("Valve File VDF Reader", LICENSE_VDF); ui->nameLabel->setText(QString("%1 %2").arg(ui->nameLabel->text()).arg(version)); #if defined(HGID) diff --git a/src/aboutdialog.h b/src/aboutdialog.h index 02d840ec1..ec1bb9d59 100644 --- a/src/aboutdialog.h +++ b/src/aboutdialog.h @@ -61,7 +61,8 @@ class AboutDialog : public QDialog LICENSE_SIP, LICENSE_CASTLE, LICENSE_ANTLR, - LICENSE_DXTEX + LICENSE_DXTEX, + LICENSE_VDF, }; private: From fdc4ebd18ce3c988f85abdc894e1e2d736f4ff65 Mon Sep 17 00:00:00 2001 From: Jeremy Rimpo Date: Mon, 4 Sep 2023 22:20:25 -0500 Subject: [PATCH 04/15] Map multiple data directories to USVFS --- src/organizercore.cpp | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/organizercore.cpp b/src/organizercore.cpp index 3a959cb38..f75a8717d 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -1984,8 +1984,12 @@ std::vector OrganizerCore::fileMapping(const QString &profileName, MappingType result; - QString dataPath - = QDir::toNativeSeparators(game->dataDirectory().absolutePath()); + QStringList dataPaths; + dataPaths.append(QDir::toNativeSeparators(game->dataDirectory().absolutePath())); + + for (auto directory : game->secondaryDataDirectories()) { + dataPaths.append(directory.absolutePath()); + } bool overwriteActive = false; @@ -2002,8 +2006,10 @@ std::vector OrganizerCore::fileMapping(const QString &profileName, overwriteActive |= createTarget; if (modPtr->isRegular()) { - result.insert(result.end(), {QDir::toNativeSeparators(std::get<1>(mod)), - dataPath, true, createTarget}); + for (auto dataPath : dataPaths) { + result.insert(result.end(), { QDir::toNativeSeparators(std::get<1>(mod)), + dataPath, true, createTarget }); + } } } @@ -2024,12 +2030,14 @@ std::vector OrganizerCore::fileMapping(const QString &profileName, } } - result.insert(result.end(), { - QDir::toNativeSeparators(m_Settings.paths().overwrite()), - dataPath, - true, - customOverwrite.isEmpty() - }); + for (auto dataPath : dataPaths) { + result.insert(result.end(), { + QDir::toNativeSeparators(m_Settings.paths().overwrite()), + dataPath, + true, + customOverwrite.isEmpty() + }); + } for (MOBase::IPluginFileMapper *mapper : m_PluginContainer->plugins()) { From 6b0b7a1cec843b4c578122c228cceeebdc3f1ab2 Mon Sep 17 00:00:00 2001 From: Jeremy Rimpo Date: Tue, 5 Sep 2023 00:08:10 -0500 Subject: [PATCH 05/15] beta 2 --- src/version.rc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.rc b/src/version.rc index 1ae0aca3f..49fe45263 100644 --- a/src/version.rc +++ b/src/version.rc @@ -4,7 +4,7 @@ // 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-beta1\0" +#define VER_FILEVERSION_STR "2.5.0-beta2\0" VS_VERSION_INFO VERSIONINFO FILEVERSION VER_FILEVERSION From e0d6bb12bff73f26bd73bc096053cc8b4dd92aab Mon Sep 17 00:00:00 2001 From: Jeremy Rimpo Date: Tue, 5 Sep 2023 00:09:41 -0500 Subject: [PATCH 06/15] Update translation files --- src/organizer_en.ts | 2446 +++++++++++++++++++++---------------------- 1 file changed, 1219 insertions(+), 1227 deletions(-) diff --git a/src/organizer_en.ts b/src/organizer_en.ts index 909187f78..a73eaec0f 100644 --- a/src/organizer_en.ts +++ b/src/organizer_en.ts @@ -130,7 +130,7 @@ - + No license @@ -170,7 +170,7 @@ p, li { white-space: pre-wrap; } - + not found @@ -178,17 +178,17 @@ p, li { white-space: pre-wrap; } AdvancedConflictListModel - + Overwrites - + File - + Overwritten By @@ -206,12 +206,12 @@ p, li { white-space: pre-wrap; } - + new - + failed to start download @@ -281,12 +281,12 @@ p, li { white-space: pre-wrap; } - + Add - + Remove @@ -294,47 +294,47 @@ p, li { white-space: pre-wrap; } ConflictsTab - + &Execute - + Execute with &VFS - + &Open - + Open with &VFS - + &Preview - + &Go to... - + Open in &Explorer - + &Hide - + &Unhide @@ -588,42 +588,42 @@ p, li { white-space: pre-wrap; } - + Setting up instance %1 - + Setting up an instance %1 - + Creating instance... - + Writing %1... - + Format error. - + Error %1. - + Done. - + Finish @@ -664,7 +664,7 @@ p, li { white-space: pre-wrap; } DirectoryRefresher - + failed to read mod (%1): %2 @@ -710,17 +710,17 @@ p, li { white-space: pre-wrap; } DownloadList - + Name - + Mod name - + Version @@ -730,99 +730,99 @@ p, li { white-space: pre-wrap; } - + Size - + Status - + Filetime - + Source Game - + < game %1 mod %2 file %3 > - + Unknown - + Pending - + Started - + Canceling - + Pausing - + Canceled - + Paused - + Error - - - + + + Fetching Info - + Downloaded - + Installed - + Uninstalled - + Pending download - + Information missing, please select "Query Info" from the context menu to re-retrieve. @@ -830,161 +830,161 @@ p, li { white-space: pre-wrap; } DownloadListView - + Install - + Query Info - + Visit on Nexus - + Open File - + Open Meta File - - - + + + Reveal in Explorer - - + + Delete... - + Un-Hide - + Hide - - + + Cancel - + Pause - + Resume - + Delete Installed Downloads... - + Delete Uninstalled Downloads... - + Delete All Downloads... - + Hide Installed... - + Hide Uninstalled... - + Hide All... - + Un-Hide All... - + Delete download - + Move to the Recycle Bin - - - + + + Delete Files? - + This will remove all finished downloads from this list and from disk. Are you absolutely sure you want to proceed? - + This will remove all installed downloads from this list and from disk. Are you absolutely sure you want to proceed? - + This will remove all uninstalled downloads from this list and from disk. Are you absolutely sure you want to proceed? - - - + + + Hide Files? - + This will remove all finished downloads from this list (but NOT from disk). - + This will remove all installed downloads from this list (but NOT from disk). - + This will remove all uninstalled downloads from this list (but NOT from disk). @@ -992,42 +992,42 @@ Are you absolutely sure you want to proceed? DownloadManager - + failed to rename "%1" to "%2" - + Memory allocation error (in refreshing directory). - + failed to download %1: could not open output file: %2 - + Download again? - + A file with the same name "%1" has already been downloaded. Do you want to download it again? The new file will receive a different name. - + Wrong Game - + The download link is for a mod for "%1" but this instance of MO has been set up for "%2". - + There is already a download queued for this file. Mod %1 @@ -1035,12 +1035,12 @@ File %2 - + Already Queued - + There is already a download started for this file. Mod %1: %2 @@ -1048,287 +1048,287 @@ File %3: %4 - + Already Started - - + + remove: invalid download index %1 - + failed to delete %1 - + failed to delete meta file for %1 - + restore: invalid download index: %1 - + cancel: invalid download index %1 - + pause: invalid download index %1 - + resume: invalid download index %1 - + resume (int): invalid download index %1 - + No known download urls. Sorry, this download can't be resumed. - - + + query: invalid download index %1 - + Please enter the nexus mod id - + Mod ID: - + Please select the source game code for %1 - + Hashing download file '%1' - + Cancel - + VisitNexus: invalid download index %1 - + Nexus ID for this Mod is unknown - + OpenFile: invalid download index %1 - + OpenFileInDownloadsFolder: invalid download index %1 - + get pending: invalid download index %1 - + get path: invalid download index %1 - + Main - + Update - + Optional - + Old - + Miscellaneous - + Deleted - + Archived - + Unknown - + display name: invalid download index %1 - + file name: invalid download index %1 - + file time: invalid download index %1 - + file size: invalid download index %1 - + progress: invalid download index %1 - + state: invalid download index %1 - + infocomplete: invalid download index %1 - - - + + + mod id: invalid download index %1 - + ishidden: invalid download index %1 - + file info: invalid download index %1 - + mark installed: invalid download index %1 - + mark uninstalled: invalid download index %1 - + %1% - %2 - ~%3 - + Memory allocation error (in processing progress event). - + Memory allocation error (in processing downloaded data). - + Information updated - - + + No matching file found on Nexus! Maybe this file is no longer available or it was renamed? - + No file on Nexus matches the selected file by name. Please manually choose the correct one. - + No download server available. Please try again later. - + Failed to request file info from nexus: %1 - + Warning: Content type is: %1 - + Download header content length: %1 downloaded file size: %2 - + Download failed: %1 (%2) - + We were unable to download the file due to errors after four retries. There may be an issue with the Nexus servers. - + failed to re-open %1 - + Unable to write download to drive (return %1). Check the drive's available storage. @@ -1548,83 +1548,83 @@ Right now the only case I know of where this needs to be overwritten is for the - + Add from file... - + Add empty - + Clone selected - + Empty output mod - + The output mod for %2 is empty. - + Output mod not found - + The output mod '%1' for %2 does not exist. - + Reset plugin executables - + This will restore all the executables provided by the game plugin. If there are existing executables with the same names, they will be automatically renamed and left unchanged. - - + + New Executable - + Select a directory - + Executables (*.exe *.bat *.jar) - + All Files (*.*) - + Select an executable - + Java required - + MO requires Java to run this application. If you already have it installed, select javaw.exe from that installation as the binary. @@ -1632,194 +1632,194 @@ Right now the only case I know of where this needs to be overwritten is for the FileTree - + Enter Name - + Enter a name for the executable - + Not an executable - + This is not a recognized executable. - - + + File '%1' does not exist, you may need to refresh. - + (only has %1 file(s)) - + %1 file(s) selected - + &Add as Executable - + Add this file to the executables list - + This file is not executable - + Reveal in E&xplorer - + Opens the file in Explorer + - - - - - - + + + + + This file is in an archive - + Open &Mod Info - + Opens the Mod Info Window - + This file is not in a managed mod - + &Un-Hide - + Un-hides the file - + &Hide - + Hides the file - + &Execute - + Launches this program - + Execute with &VFS - + Launches this program hooked to the VFS - + &Open - + Opens this file with its default handler - + Open with &VFS - + Opens this file with its default handler hooked to the VFS - + &Preview - + Previews this file within Mod Organizer - + This file is in an archive or has no preview handler associated with it - + &Save Tree to Text File... - + Writes the list of files to a text file - + &Refresh - + Refreshes the list - + Ex&pand All - + &Collapse All @@ -1827,54 +1827,54 @@ Right now the only case I know of where this needs to be overwritten is for the FileTreeModel - + Name - + Mod - + Type - + Size - + Date modified - + Directory - - + + Virtual path - + Real path - + From - - + + Also in @@ -1893,7 +1893,7 @@ Right now the only case I know of where this needs to be overwritten is for the - + Open with &VFS @@ -1928,48 +1928,48 @@ Right now the only case I know of where this needs to be overwritten is for the - - + + New Folder - + Failed to create "%1" - + Are you sure you want to delete "%1"? - + Are you sure you want to delete the selected files? - + Confirm - + Failed to delete %1 - + &Execute - + Execute with &VFS - + &Open @@ -1977,22 +1977,22 @@ Right now the only case I know of where this needs to be overwritten is for the FilterList - + Filter separators - + Show separators - + Hide separators - + Contains %1 @@ -2116,77 +2116,77 @@ Right now the only case I know of where this needs to be overwritten is for the GamebryoModDataContent - + Plugins (ESP/ESM/ESL) - + Optional Plugins - + Interface - + Meshes - + Bethesda Archive - + Scripts (Papyrus) - + Script Extender Plugin - + Script Extender Files - + SkyProc Patcher - + Sound or Music - + Textures - + MCM Configuration - + INI Files - + FaceGen Data - + ModGroup Files @@ -2219,23 +2219,23 @@ Right now the only case I know of where this needs to be overwritten is for the - + Has Script Extender Data - + Missing ESPs - - + + None - + Missing ESLs @@ -2243,12 +2243,12 @@ Right now the only case I know of where this needs to be overwritten is for the GeneralConflictsTab - + <table cellspacing="5"><tr><th>Type</th><th>%1</th><th>Total</th><th>Percent</th></tr><tr><td>Loose files:&emsp;</td><td align=right>%2</td><td align=right>%3</td><td align=right>%4%</td></tr><tr><td>Archive files:&emsp;</td><td align=right>%5</td><td align=right>%6</td><td align=right>%7%</td></tr><tr><td>Combined:&emsp;</td><td align=right>%8</td><td align=right>%9</td><td align=right>%10%</td></tr></table> - + Winning @@ -2266,119 +2266,119 @@ Right now the only case I know of where this needs to be overwritten is for the InstallationManager - + Password required - + Password - - + + Extraction failed: %1 - + Extracting files - + Failed to create backup - + Mod Name - + Name - + Invalid name - + The name you entered is invalid, please enter a different one. - + File format "%1" not supported - + Invalid file tree returned by plugin. - + Installation failed - + Something went wrong while installing this mod. - + None of the available installer plugins were able to handle that archive. This is likely due to a corrupted or incompatible download or unrecognized archive format. - + no error - + 7z.dll not found - + 7z.dll isn't valid - + archive not found - + failed to open archive - + unsupported archive type - + internal library error - + archive invalid - + unknown archive error @@ -2473,96 +2473,96 @@ This is likely due to a corrupted or incompatible download or unrecognized archi - + Switching instances - + Mod Organizer must restart to manage the instance '%1'. - + This confirmation can be disabled in the settings. - + Restart Mod Organizer - - + + Cancel - - + + Rename instance - + The active instance cannot be renamed. - + Instance name - + Error - + Failed to rename "%1" to "%2": %3 - - - + + + Deleting instance - + The active instance cannot be deleted. - + These files and folders will be deleted - + All checked items will be deleted. - + Move to the recycle bin - + Delete permanently - + Nothing to delete. - + A portable instance already exists. @@ -2583,47 +2583,47 @@ This is likely due to a corrupted or incompatible download or unrecognized archi LogList - + Copy - + &Copy all - + C&lear all - + &Open logs folder - + &Level - + &Debug - + &Info - + &Warnings - + &Errors @@ -2631,33 +2631,33 @@ This is likely due to a corrupted or incompatible download or unrecognized archi Loot - + Loot failed to run - + No errors were reported. The log below might have more information. - + Errors - + Warnings - + failed to start loot - + Loot failed. Exit code was: 0x%1 @@ -2690,12 +2690,12 @@ This is likely due to a corrupted or incompatible download or unrecognized archi - + Stopping LOOT... - + Running LOOT... @@ -2703,37 +2703,37 @@ This is likely due to a corrupted or incompatible download or unrecognized archi MOApplication - + Failed to create log folder. - + Failed to set up data paths. - + Download started - + This shortcut or command line is for instance '%1', but the current instance is '%2'. - + This shortcut or command line is for profile '%1', but the current profile is '%2'. - + an error occurred: %1 - + an error occurred @@ -2741,7 +2741,7 @@ This is likely due to a corrupted or incompatible download or unrecognized archi MOBase::FilterWidget - + Filter options @@ -2756,34 +2756,34 @@ This is likely due to a corrupted or incompatible download or unrecognized archi - + Case sensitive - + Make regular expressions case sensitive (/i) leave "(/i)" verbatim - + Extended - + Ignores unescaped whitespace in regular expressions (/x) leave "(/x)" verbatim - + Keep selection in view - + Scroll to keep the current selection in view after filtering @@ -2791,27 +2791,27 @@ This is likely due to a corrupted or incompatible download or unrecognized archi MOBase::TextViewer - + Save changes? - + Do you want to save changes to %1? - + failed to write to %1 - + file not found: %1 - + Save @@ -2819,7 +2819,7 @@ This is likely due to a corrupted or incompatible download or unrecognized archi MOBase::TutorialControl - + Tutorial failed to start, please check "mo_interface.log" for details. @@ -2827,7 +2827,7 @@ This is likely due to a corrupted or incompatible download or unrecognized archi MOBase::TutorialManager - + tutorial manager not set up yet @@ -2840,17 +2840,17 @@ This is likely due to a corrupted or incompatible download or unrecognized archi - + failed to connect to running process: %1 - + failed to communicate with running process: %1 - + failed to receive data from secondary process: %1 @@ -3188,7 +3188,7 @@ p, li { white-space: pre-wrap; } - + Name @@ -3446,7 +3446,7 @@ p, li { white-space: pre-wrap; } - + Endorse Mod Organizer @@ -3530,429 +3530,429 @@ p, li { white-space: pre-wrap; } - + Toolbar and Menu - + Desktop - + Start Menu - + There is no supported sort mechanism for this game. You will probably have to use a third-party tool. - + Crash on exit - + MO crashed while exiting. Some settings may not be saved. Error: %1 - + There are notifications to read - + There are no notifications - + Endorse - + Won't Endorse - + Help on UI - + Documentation - - + + Game Support Wiki - + Chat on Discord - + Report Issue - + Tutorials - + About - + About Qt - + Please enter a name for the new profile - + failed to create profile: %1 - + Show tutorial? - + You are starting Mod Organizer for the first time. Do you want to show a tutorial of its basic features? If you choose no you can always start the tutorial from the "Help" menu. - + Never ask to show tutorials - + Do you know how to mod this game? Do you need to learn? There's a game support wiki available! Click OK to open the wiki. In the future, you can access this link from the "Help" menu. - + Downloads in progress - + There are still downloads in progress, do you really want to quit? - + Plugin "%1" failed: %2 - + Plugin "%1" failed - + <Edit...> - + (no executables) - + This bsa is enabled in the ini file so it may be required! - + Activating Network Proxy - + Notice: Your current MO version (%1) is lower than the previously used one (%2). The GUI may not downgrade gracefully, so you may experience oddities. However, there should be no serious issues. - + Start Tutorial? - + You're about to start a tutorial. For technical reasons it's not possible to end the tutorial early. Continue? - + failed to change origin name: %1 - + failed to move "%1" from mod "%2" to "%3": %4 - + Open Game folder - + Open MyGames folder - + Open INIs folder - + Open Instance folder - + Open Mods folder - + Open Profile folder - + Open Downloads folder - + Open MO2 Install folder - + Open MO2 Plugins folder - + Open MO2 Stylesheets folder - + Open MO2 Logs folder - + Restart Mod Organizer - + Mod Organizer must restart to finish configuration changes - + Restart - + Continue - + Some things might be weird. - + Can't change download directory while downloads are in progress! - + Update available - + Do you want to endorse Mod Organizer on %1 now? - + Abstain from Endorsing Mod Organizer - + Are you sure you want to abstain from endorsing Mod Organizer 2? You will have to visit the mod page on the %1 Nexus site to change your mind. - + Thank you for endorsing MO2! :) - + Please reconsider endorsing MO2 on Nexus! - + None of your %1 mods appear to have had recent file updates. - + All of your mods have been checked recently. We restrict update checks to help preserve your available API requests. - + 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 @@ -3969,32 +3969,32 @@ You will have to visit the mod page on the %1 Nexus site to change your mind. ModInfo - + invalid mod index: %1 - + remove: invalid mod index %1 - + remove: failed to delete mod '%1' directory - + The update check has found a mod with a Nexus ID and source game of %1, but this game is not a valid Nexus source. - + All of your mods have been checked recently. We restrict update checks to help preserve your available API requests. - + You have mods that haven't been checked within the last month using the new API. These mods must be checked before we can use the bulk update API. This will consume significantly more API requests than usual. You will need to rerun the update check once complete in order to parse the remaining mods. @@ -4002,7 +4002,7 @@ You will have to visit the mod page on the %1 Nexus site to change your mind. ModInfoBackup - + This is the backup of a mod @@ -4408,7 +4408,7 @@ p, li { white-space: pre-wrap; } ModInfoOverwrite - + This pseudo mod contains files from the virtual data tree that got modified (i.e. by the construction kit) @@ -4416,12 +4416,12 @@ p, li { white-space: pre-wrap; } ModInfoRegular - + %1 contains no esp/esm/esl and no asset (textures, meshes, interface, ...) directory - + Categories: <br> @@ -4437,32 +4437,32 @@ p, li { white-space: pre-wrap; } ModList - + Backup - + Separator - + No valid game data - + Not endorsed yet - + This mod is for a different<br> game, make sure it's compatible or it could cause crashes. - + Mod is being tracked on the website @@ -4472,228 +4472,228 @@ p, li { white-space: pre-wrap; } - + Overwrites loose files - + Overwritten loose files - + Loose files Overwrites & Overwritten - + Redundant - + Overwrites an archive with loose files - + Archive is overwritten by loose files - + Overwrites another archive file - + Overwritten by another archive file - + Archive files overwrites & overwritten - + Non-MO - + invalid - + installed version: "%1", newest version: "%2" - + The newest version on Nexus seems to be older than the one you have installed. This could either mean the version you have has been withdrawn (i.e. due to a bug) or the author uses a non-standard versioning scheme and that newest version is actually newer. Either way you may want to "upgrade". - + This file has been marked as "Old". There is most likely an updated version of this file available. - + This file has been marked as "Deleted"! You may want to check for an update or remove the nexus ID from this mod! - + %1 minute(s) and %2 second(s) - + This mod will be available to check in %2. - + Categories: <br> - + Invalid name - + Name is already in use by another mod - + Confirm - + Are you sure you want to remove "%1"? - + Conflicts - + Flags - + Content - + Mod Name - + Version - + Priority - + Category - + Source Game - + Nexus ID - + Installation - + Notes - + unknown - + Name of your mods - + Version of the mod (if available) - + Installation priority of your mod. The higher, the more "important" it is and thus overwrites files from mods with lower priority. - + Primary category of the mod. - + The source game which was the origin of this mod. - + Id of the mod as used on Nexus. - + Indicators of file conflicts between mods. - + Emblems to highlight things that might require attention. - + Depicts the content of the mod: - + Time this mod was installed - + User notes about the mod @@ -4701,7 +4701,7 @@ p, li { white-space: pre-wrap; } ModListChangeCategoryMenu - + Change Categories @@ -4709,236 +4709,236 @@ p, li { white-space: pre-wrap; } ModListContextMenu - + All Mods - + Collapse all - + Collapse others - + Expand all - + Information... - + Send to... - + Lowest priority - + Highest priority - + Priority... - + Separator... - + First conflict - + Last conflict - + Sync to Mods... - + Create Mod... - + Move content to Mod... - + Clear Overwrite... - - - + + + Open in Explorer - + Rename Separator... - + Remove Separator... - - + + Select Color... - - + + Reset Color - + Restore Backup - + Remove Backup... - - + + Ignore missing data - - + + Mark as converted/working - - + + Visit on Nexus - - + + Visit on %1 - + Change versioning scheme - + Force-check updates - + Un-ignore update - + Ignore update - + Enable selected - + Disable selected - + Rename Mod... - + Reinstall Mod - + Remove Mod... - + Create Backup - + Restore hidden files - + Un-Endorse - - + + Endorse - + Won't endorse - + Endorsement state unknown - + Start tracking - + Stop tracking - + Tracked state unknown @@ -4946,97 +4946,97 @@ p, li { white-space: pre-wrap; } ModListGlobalContextMenu - + Install mod above... - + Create empty mod above - + Install mod inside... - + Create empty mod inside - + Install mod below... - + Create empty mod below - + Create separator above - + Install mod... - + Create empty mod - + Create separator - + Collapse all - + Expand all - + Enable all - + Disable all - + Enable all matching mods - + Disable all matching mods - + Check for updates - + Refresh - + Export to csv... @@ -5044,7 +5044,7 @@ p, li { white-space: pre-wrap; } ModListPrimaryCategoryMenu - + Primary Category @@ -5052,7 +5052,7 @@ p, li { white-space: pre-wrap; } ModListSortProxy - + Drag&Drop is only supported when sorting by priority @@ -5060,38 +5060,38 @@ p, li { white-space: pre-wrap; } ModListView - + <table cellspacing="5"><tr><th>Type</th><th>All</th><th>Visible</th><tr><td>Enabled mods:&emsp;</td><td align=right>%1 / %2</td><td align=right>%3 / %4</td></tr><tr><td>Unmanaged/DLCs:&emsp;</td><td align=right>%5</td><td align=right>%6</td></tr><tr><td>Mod backups:&emsp;</td><td align=right>%7</td><td align=right>%8</td></tr><tr><td>Separators:&emsp;</td><td align=right>%9</td><td align=right>%10</td></tr></table> - + Copy Folder... - + This will copy the content of %1 to a new mod. Please enter the name: - + A mod with this name already exists. - + Exception: - + Unknown exception - + <Multiple> @@ -5099,313 +5099,313 @@ Please enter the name: ModListViewActions - + Choose Mod - + Mod Archive - - + + Create Mod... - + This will create an empty mod. Please enter a name: - - + + A mod with this name already exists - + Create Separator... - + This will create a new separator. Please enter a name: - + A separator with this name already exists - + Really enable %1 mod(s)? - + Really disable %1 mod(s)? - - - + + + 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: @@ -5427,42 +5427,42 @@ Please enter a name: NexusConnectionUI - + Connected. - + Not connected. - + Disconnected. - + Checking API key... - + Received API key. - + Received user account information - + Linked with Nexus successfully. - + Failed to set API key @@ -5470,32 +5470,32 @@ Please enter a name: NexusInterface - + Please pick the mod ID for "%1" - + You must authorize MO2 in Settings -> Nexus to use the Nexus API. - + You've exceeded the Nexus API rate limit and requests are now being throttled. Your next batch of requests will be available in approximately %1 minutes and %2 seconds. - + Aborting download: Either you clicked on a premium-only link and your account is not premium, or the download link was generated by a different account than the one stored in Mod Organizer. - + empty response - + invalid response @@ -5546,27 +5546,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 @@ -5578,7 +5578,7 @@ Please enter a name: NoConflictListModel - + File @@ -5586,215 +5586,207 @@ Please enter a name: OrganizerCore - + File is write protected - + Invalid file format (probably a bug) - + Unknown error %1 - + Failed to write settings - + An error occurred trying to write back MO settings to %1: %2 - + Download started - + Download failed - + The selected profile '%1' does not exist. The profile '%2' will be used instead - - + Installation cancelled - - + Another installation is currently in progress. - - + Installation successful - - + Configure Mod - - + This mod contains ini tweaks. Do you want to configure them now? - - + mod not found: %1 - - + Extraction cancelled - - + The installation was cancelled while extracting files. If this was prior to a FOMOD setup, this warning may be ignored. However, if this was during installation, the mod will likely be missing files. - + file not found: %1 - + failed to generate preview for %1 - + Sorry - + Sorry, can't preview anything. This function currently does not support extracting from bsas. - + File '%1' not found. - + Failed to generate preview for %1 - + Failed to refresh list of esps: %1 - + Multiple esps/esls activated, please check that they don't conflict. - + You need to be logged in with Nexus - + Download? - + A download has been started but no installed page plugin recognizes it. If you download anyway no information (i.e. version) will be associated with the download. Continue? - - + + failed to update mod list: %1 - - + + login successful - + Login failed - + Login failed, try again? - + login failed: %1. Download will not be associated with an account - + login failed: %1 - + login failed: %1. You need to log-in with Nexus to update MO. - + MO1 "Script Extender" load mechanism has left hook.dll in your game folder - - + + Description missing - + <a href="%1">hook.dll</a> has been found in your game folder (right click to copy the full path). This is most likely a leftover of setting the ModOrganizer 1 load mechanism to "Script Extender", in which case you must remove this file either by changing the load mechanism in ModOrganizer 1 or manually removing the file, otherwise the game is likely to crash and burn. - + failed to save load order: %1 - + Error - + The designated write target "%1" is not enabled. @@ -5802,12 +5794,12 @@ Continue? OverwriteConflictListModel - + File - + Overwritten Mods @@ -5815,12 +5807,12 @@ Continue? OverwriteFileSystemModel - + Overwrites - + not implemented @@ -5863,43 +5855,43 @@ Continue? - + mod not found: %1 - + Failed to delete "%1" - - - - + + + + Confirm - - + + Are you sure you want to delete "%1"? - - + + Are you sure you want to delete the selected files? - - + + New Folder - + Failed to create "%1" @@ -5907,12 +5899,12 @@ Continue? OverwrittenConflictListModel - + File - + Providing Mod @@ -5920,48 +5912,48 @@ Continue? PluginContainer - + Plugin error - + Mod Organizer failed to load the plugin '%1' last time it was started. - + The plugin can be skipped for this session, blacklisted, or loaded normally, in which case it might fail again. Blacklisted plugins can be re-enabled later in the settings. - + Skip this plugin - + Blacklist this plugin - + Load this plugin - + Some plugins could not be loaded - - + + Description missing - + The following plugins could not be loaded. The reason may be missing dependencies (i.e. python) or an outdated version: @@ -5969,28 +5961,28 @@ Continue? PluginList - + Name - + Priority - + Mod Index - + Flags - + unknown @@ -6000,107 +5992,107 @@ Continue? - + Emblems to highlight things that might require attention. - + Load priority of plugins. The higher, the more "important" it is and thus overwrites data from plugins with lower priority. - + Determines the formids of objects originating from this mods. - + failed to update esp info for file %1 (source id: %2), error: %3 - + Plugin not found: %1 - + Origin - + This plugin can't be disabled (enforced by the game). - + Author - + Description - + Missing Masters - + Enabled Masters - + Loads Archives - + There are Archives connected to this plugin. Their assets will be added to your game, overwriting in case of conflicts following the plugin order. Loose files will always overwrite assets from Archives. (This flag only checks for Archives from the same mod as the plugin) - + Loads INI settings - + There is an ini file connected to this plugin. Its settings will be added to your game settings, overwriting in case of conflicts. - + This ESP is flagged as an ESL. It will adhere to the ESP load order but the records will be loaded in ESL space. - + Incompatible with %1 - + Depends on missing %1 - + Warning - + Error - + failed to restore load order for %1 @@ -6108,7 +6100,7 @@ Continue? PluginListContextMenu - + Enable selected @@ -6118,78 +6110,78 @@ Continue? - + Enable all - - + + Confirm - + Really enable all plugins? - + Disable all - + Really disable all plugins? - + Unlock load order - + Lock load order - + Open Origin in Explorer - + Open Origin Info... - + Send to... - + Top - + Bottom - + Priority... - + Set Priority - + Set the priority of the selected plugins @@ -6197,7 +6189,7 @@ Continue? PluginListSortProxy - + Drag&Drop is only supported when sorting by priority or mod index @@ -6205,34 +6197,34 @@ Continue? PluginListView - + <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> - - + + Sorting plugins - - + + Are you sure you want to sort your plugins list? - + Note: You are currently in offline mode and LOOT will not update the master list. - + Exception: - + Unknown exception @@ -6240,42 +6232,42 @@ Continue? PluginTypeName - + Diagnose - + Game - + Installer - + Mod Page - + Preview - + Tool - + Proxy - + File Mapper @@ -6321,12 +6313,12 @@ p, li { white-space: pre-wrap; } - + No guided fix - + (There are no notifications) @@ -6334,22 +6326,22 @@ p, li { white-space: pre-wrap; } Profile - + invalid profile name: %1 - + failed to create %1 - + failed to write mod list: %1 - + failed to update tweaked ini file, wrong settings may be used: %1 @@ -6359,46 +6351,46 @@ p, li { white-space: pre-wrap; } - + failed to open %1 - + "%1" is missing or inaccessible - - - - - + + + + + invalid mod index: %1 - + A mod named "overwrite" was detected, disabled, and moved to the highest priority on the mod list. You may want to rename this mod and enable it again. - + Delete profile-specific save games? - + Do you want to delete the profile-specific save games? (If you select "No", the save games will show up again if you re-enable profile-specific save games) - + Missing profile-specific game INI files! - + Some of your profile-specific game INI files were missing. They will now be copied from the vanilla game folder. You might want to double-check your settings. Missing files: @@ -6406,12 +6398,12 @@ Missing files: - + Delete profile-specific game INI files? - + Do you want to delete the profile-specific game INI files? (If you select "No", the INI files will be used again if you re-enable profile-specific game INI files.) @@ -6581,103 +6573,103 @@ p, li { white-space: pre-wrap; } - + Archive invalidation isn't required for this game. - + This game does not support profile-specific game saves. - - + + failed to create profile: %1 - + Name - + Please enter a name for the new profile - + failed to copy profile: %1 - + Invalid name - + Invalid profile name - + Deleting active profile - + Unable to delete active profile. Please change to a different profile first. - + Confirm - + Are you sure you want to remove this profile (including profile-specific save games, if any)? - + Profile broken - + This profile you're about to delete seems to be broken or the path is invalid. I'm about to delete the following folder: "%1". Proceed? - + Renaming active profile - + The active profile cannot be renamed. Please change to a different profile first. - + Rename Profile - + New Name - + failed to change archive invalidation state: %1 - + failed to determine if invalidation is active: %1 @@ -6685,51 +6677,51 @@ p, li { white-space: pre-wrap; } QObject - + Regular - + Premium - - + + None - + Failed to save custom categories - - - - + + + + invalid category index: %1 - + Active - + Update available - + Has category - + Conflicted @@ -6739,317 +6731,317 @@ p, li { white-space: pre-wrap; } - + Endorsed - + Has backup - + Managed - + Has valid game data - + Has Nexus ID - + Tracked on Nexus - + invalid category id: %1 - + Is overwritten (loose files) - + Is overwriting (loose files) - + Is overwritten (archives) - + Is overwriting (archives) - + Mod contains selected plugin - + Plugin is contained in selected mod - + failed to start application: %1 - + Executable '%1' not found in instance '%2'. - + Failed to run '%1'. The logs might have more information. - + Failed to run '%1'. The logs might have more information. %2 - + Creating %1 - + Global - - - + + + Portable - - + + Instance type: %1 - + ? - + Find game installation for %1 - + Find game installation - - - + + + Unrecognized game - + The folder %1 does not seem to contain a game Mod Organizer can manage. - + See details for the list of supported games. - + No installation found - + Browse... - + The folder must contain a valid game installation - - + + Microsoft Store game - + The folder %1 seems to be a Microsoft Store game install. Games installed through the Microsoft Store are not supported by Mod Organizer and will not work properly. - - - + + + Use this folder for %1 - + Use this folder - - - + + + I know what I'm doing - - - - - - - - - - + + + + + + + + + + + - - - + + Cancel - + The folder %1 does not seem to contain an installation for <span style="white-space: nowrap; font-weight: bold;">%2</span> or for any other game Mod Organizer can manage. - - + + Incorrect game - + The folder %1 seems to contain an installation for <span style="white-space: nowrap; font-weight: bold;">%2</span>, not <span style="white-space: nowrap; font-weight: bold;">%3</span>. - + Manage %1 instead - + Instance location: %1 - + Instance name: %1 - - + + Base directory: %1 - + Downloads - + Mods - + Profiles - + Overwrite - + Game: %1 - + Game location: %1 - + invalid field name "%1" - + invalid type for "%1" (should be integer) - + invalid type for "%1" (should be string) - + invalid type for "%1" (should be float) - + no fields set up yet! - + field not set "%1" - + invalid character in field "%1" - + empty field name - + Disabling the '%1' plugin will prevent the following %2 plugin(s) from working: @@ -7057,43 +7049,43 @@ p, li { white-space: pre-wrap; } - + No menu available - + Selected files must be in the same directory - + The hidden file "%1" already exists. Replace it? - + The visible file "%1" already exists. Replace it? - + Replace file? - - + + File operation failed - + Failed to remove "%1": %2 - + Failed to rename file: %1. Source: @@ -7104,108 +7096,108 @@ Destination: - + Disabled because - + invalid 7-zip32.dll: %1 - + Cannot open instance '%1', failed to read INI file %2. - + Cannot open instance '%1', the managed game was not found in the INI file %2. Select the game managed by this instance. - + Cannot open instance '%1', the game plugin '%2' doesn't exist. It may have been deleted by an antivirus. Select another instance. - + Cannot open instance '%1', the game directory '%2' doesn't exist or the game plugin '%3' doesn't recognize it. Select the game managed by this instance. - + The instance name must be a valid folder name. - + An instance with this name already exists. - - - + + + - - - - - + + + + + Error - - + + Failed to create "%1". Your user account probably lacks permission. - + General messages - + Plugins - + No messages. - + Incompatibilities - + Missing masters - + Verified clean by %1 - + %1 found %2 ITM record(s), %3 deleted reference(s) and %4 deleted navmesh(es). - + - + Warning - + failed to run loot: %1 @@ -7250,208 +7242,208 @@ Destination: - + Mod Organizer - + An instance of Mod Organizer is already running - + <Unmanaged> - + Please use "Help" from the toolbar to get usage instructions to all elements - + Visit %1 on Nexus - - + + <Manage...> - + failed to parse profile %1: %2 - + Instance at '%1' not found. Select another instance. - + Instance at '%1' not found. You must create a new instance - + File Exists - + A file with that name exists, please enter a new one - - + + Failed to move file - + Failed to create directory "optional" - + Save changes? - + Save changes to "%1"? - + Connecting to Nexus... - + Waiting for Nexus... - + Opened Nexus in browser. - + Switch to your browser and accept the request. - + Finished. - + No answer from Nexus. - + A firewall might be blocking Mod Organizer. - + Nexus closed the connection. - + Cancelled. - + Failed to request %1 - + Cancelled - + Internal error - + HTTP code %1 - + Invalid JSON - + Bad response - + API key is empty - + SSL error - + Timed out - + One of the configured MO2 directories (profiles, mods, or overwrite) is on a path containing a symbolic (or other) link. This is likely to be incompatible with MO2's virtual filesystem. - + failed to initialize plugin %1: %2 - + failed to access %1 - + failed to set file time %1 - - - + + + No profile set - + This shortcut is for instance '%1' but Mod Organizer is currently running for '%2'. Exit Mod Organizer before running the shortcut or change the active instance. - + Executable '%1' does not exist in instance '%2'. @@ -7461,205 +7453,205 @@ Destination: - + Before you can use ModOrganizer, you need to create at least one profile. ATTENTION: Run the game at least once before creating a profile! - + '%1': file is blocked (%2) - + '%1' seems to be missing, an antivirus may have deleted it - + %1 is loaded. This program is known to cause issues with Mod Organizer, such as freezing or blank windows. Consider uninstalling it. - + %1 is loaded. This program is known to cause issues with Mod Organizer and its virtual filesystem, such script extenders or others programs refusing to run. Consider uninstalling it. - - - + + + attempt to store setting for unknown plugin "%1" - + Failed - + Failed to start the helper application: %1 - + Debug - + Info (recommended) - + Trace - + Mini (recommended) - + Data - + Full - + Confirm? - + This will reset all the choices you made to dialogs and make them all visible again. Continue? - + Enter API Key Manually - + Connect to Nexus - - - + + + N/A - + Executables (*.exe) - + All Files (*.*) - + Select the browser executable - + Failed to create "%1", you may not have the necessary permissions. Path remains unchanged. - + Select base directory - + Select download directory - + Select mod directory - + Select cache directory - + Select profiles directory - + Select overwrite directory - + Select game executable - + The given path was not recognized as a valid game installation. The current game plugin requires the executable to be in a "%1" subfolder of the game directory. - + Cannot disable plugin - + The '%1' plugin is used by the current game plugin and cannot disabled. - + <p>Disabling the '%1' plugin will also disable the following plugins:</p><ul>%1</ul><p>Do you want to continue?</p> - + Really disable plugin? - + This plugin is required for Mod Organizer to work properly and cannot be disabled. - + Executables Blacklist - + Enter one executable per line to be blacklisted from the virtual file system. Mods and other virtualized files will not be visible to these executables and any executables launched by them. @@ -7670,24 +7662,24 @@ Example: - - + + Restart Mod Organizer - + Geometries will be reset to their default values. - + unexpected end of path - + invalid file index for remove: {} @@ -7697,267 +7689,267 @@ Example: - + invalid origin name: - + failed to change name lookup from {} to {} - + This error typically happens because an antivirus has deleted critical files from Mod Organizer's installation folder or has made them generally inaccessible. Add an exclusion for Mod Organizer's installation folder in your antivirus, reinstall Mod Organizer and try again. - + This error typically happens because an antivirus is preventing Mod Organizer from starting programs. Add an exclusion for Mod Organizer's installation folder in your antivirus and try again. - + The file '%1' does not exist. - + The working directory '%1' does not exist. - - - - + + + + Cannot start Steam - + The path to the Steam executable cannot be found. You might try reinstalling Steam. - - - + + + Continue without starting Steam - - + + The program may fail to launch. - + Cannot launch program - - - + + + Cannot start %1 - + Cannot launch helper - - + + Elevation required - + This program is requesting to run as administrator but Mod Organizer itself is not running as administrator. Running programs as administrator is typically unnecessary as long as the game and Mod Organizer have been installed outside "Program Files". You can restart Mod Organizer as administrator and try launching the program again. - - + + Restart Mod Organizer as administrator - - + + You must allow "helper.exe" to make changes to the system. - + Launch Steam - + This program requires Steam - + Mod Organizer has detected that this program likely requires Steam to be running to function properly. - + Start Steam - - + + The program might fail to run. - + Steam is running as administrator - + Running Steam as administrator is typically unnecessary and can cause problems when Mod Organizer itself is not running as administrator. You can restart Mod Organizer as administrator and try launching the program again. - - - + + + Continue - + Event Log not running - + The Event Log service is not running - + The Windows Event Log service is not running. This can prevent USVFS from running properly and your mods may not be recognized by the program being launched. - - + + Your mods might not work. - + Blacklisted program - + The program %1 is blacklisted - + The program you are attempting to launch is blacklisted in the virtual filesystem. This will likely prevent it from seeing any mods, INI files or any other virtualized files. - + Change the blacklist - + Waiting - + Please press OK once you're logged into steam. - + Select binary - + Binary - + This tracks the number of queued Nexus API requests, as well as the remaining daily and hourly requests. The Nexus API limits you to a pool of requests per day and requests per hour. It is dynamically updated every time a request is completed. If you run out of requests, you will be unable to queue downloads, check updates, parse mod info, or even log in. Both pools must be consumed before this happens. - + Loading... - + &Save - + &Word wrap - + &Open in Explorer - + Mod Organizer is locked while the application is running. - + Mod Organizer is currently running an application. - + The application must run to completion because its output is required. - + Mod Organizer is waiting on an application to close before exiting. - + Unlock - + Exit Now - - + + Some of your plugins have invalid names! These plugins can not be loaded by the game. Please see mo_interface.log for a list of affected plugins and rename them. @@ -7967,22 +7959,22 @@ You can restart Mod Organizer as administrator and try launching the program aga - + failed to open %1 - + wrong file format - expected %1 got %2 - + failed to query registry path (preflight): %1 - + failed to query registry path (read): %1 @@ -7992,22 +7984,22 @@ You can restart Mod Organizer as administrator and try launching the program aga - + Filter - + One of the following plugins must be enabled: %1. - + This plugin can only be enabled if the '%1' plugin is installed and enabled. - + This plugin can only be enabled for the following game(s): %1. @@ -8017,152 +8009,152 @@ You can restart Mod Organizer as administrator and try launching the program aga - - + + INI file is read-only - + Mod Organizer is attempting to write to "%1" which is currently set to read-only. - - + + Clear the read-only flag - - + + Allow the write once - - + + The file will be set to read-only again. - - + + Skip this file - + You can reset these choices by clicking "Reset Dialog Choices" in the General tab of the Settings - + Always ask - - + + Remember my choice - + Remember my choice for %1 - + Failed to save '{}', could not create a temporary file: {} (error {}) - + removal of "%1" failed: %2 - + removal of "%1" failed - + "%1" doesn't exist (remove) - + Error %1 - - + + You have an invalid custom browser command in the settings. - - + + failed to create directory "%1" - - + + failed to copy "%1" to "%2" - + %1 B - + %1 KB - + %1 MB - + %1 GB - + %1 TB - + %1 B/s - + %1 KB/s - + %1 MB/s - + %1 GB/s - + %1 TB/s @@ -8248,17 +8240,17 @@ p, li { white-space: pre-wrap; } - + Save CSV - + Text Files - + failed to open "%1" for writing @@ -8266,17 +8258,17 @@ p, li { white-space: pre-wrap; } SavesTab - + %1 more - + Confirm - + Are you sure you want to remove the following %n save(s)?<br><ul>%1</ul><br>Removed saves will be sent to the Recycle Bin. @@ -8284,12 +8276,12 @@ p, li { white-space: pre-wrap; } - + Fix enabled mods... - + Delete %n save(s) @@ -8297,7 +8289,7 @@ p, li { white-space: pre-wrap; } - + Open in Explorer... @@ -8323,42 +8315,42 @@ p, li { white-space: pre-wrap; } SelfUpdater - + Download failed - + Failed to find correct download, please try again later. - + Update - + Download in progress - + Download failed: %1 - + Failed to install update: %1 - + Failed to start %1: %2 - + Error @@ -9237,12 +9229,12 @@ For the other games this is not a sufficient replacement for AI! - + Confirm - + Changing the mod directory affects all your profiles! Mods not present (or named differently) in the new location will be disabled in all profiles. There is no way to undo this unless you backed up your profiles manually. Proceed? @@ -9250,7 +9242,7 @@ For the other games this is not a sufficient replacement for AI! StatusBar - + Unknown game @@ -9273,17 +9265,17 @@ For the other games this is not a sufficient replacement for AI! - + <don't sync> - + failed to remove %1 - + failed to move %1 to %2 @@ -9291,7 +9283,7 @@ For the other games this is not a sufficient replacement for AI! T - + Plugin @@ -9420,22 +9412,22 @@ On Windows XP: - + Characters for profile %1 - + Overwrite - + Overwrite the file "%1" - + Confirm @@ -9463,7 +9455,7 @@ On Windows XP: - + Mod Organizer %1 is available. The current version is %2. Updating will not affect your mods or profiles. @@ -9471,7 +9463,7 @@ On Windows XP: UsvfsConnector - + Preparing vfs @@ -9485,7 +9477,7 @@ On Windows XP: - + Connecting to Nexus... @@ -9500,7 +9492,7 @@ On Windows XP: - + Trying again... @@ -10062,19 +10054,19 @@ Please open the "Nexus"-tab uibase - + h Time remaining hours - + m Time remaining minutes - + s Time remaining seconds From 58cc25f3227dd82011c809b50bbedbeec039ccc4 Mon Sep 17 00:00:00 2001 From: Jeremy Rimpo Date: Tue, 5 Sep 2023 13:25:01 -0500 Subject: [PATCH 07/15] Implement 'override' plugin support --- src/organizer_en.ts | 40 ++++++++++++++++++++-------------------- src/pluginlist.cpp | 26 ++++++++++++++++++++++---- src/pluginlist.h | 4 +++- 3 files changed, 45 insertions(+), 25 deletions(-) diff --git a/src/organizer_en.ts b/src/organizer_en.ts index a73eaec0f..18eaac8e9 100644 --- a/src/organizer_en.ts +++ b/src/organizer_en.ts @@ -6007,92 +6007,92 @@ Continue? - + failed to update esp info for file %1 (source id: %2), error: %3 - + Plugin not found: %1 - + Origin - + This plugin can't be disabled (enforced by the game). - + Author - + Description - + Missing Masters - + Enabled Masters - + Loads Archives - + There are Archives connected to this plugin. Their assets will be added to your game, overwriting in case of conflicts following the plugin order. Loose files will always overwrite assets from Archives. (This flag only checks for Archives from the same mod as the plugin) - + Loads INI settings - + There is an ini file connected to this plugin. Its settings will be added to your game settings, overwriting in case of conflicts. - + This ESP is flagged as an ESL. It will adhere to the ESP load order but the records will be loaded in ESL space. - + Incompatible with %1 - + Depends on missing %1 - + Warning - + Error - + failed to restore load order for %1 @@ -7421,12 +7421,12 @@ Destination: - + failed to access %1 - + failed to set file time %1 diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp index 6e54b46d7..311f05ec7 100644 --- a/src/pluginlist.cpp +++ b/src/pluginlist.cpp @@ -179,6 +179,8 @@ void PluginList::refresh(const QString& profileName, GamePlugins* gamePlugins = m_GamePlugin->feature(); const bool lightPluginsAreSupported = gamePlugins ? gamePlugins->lightPluginsAreSupported() : false; + const bool overridePluginsAreSupported = + gamePlugins ? gamePlugins->overridePluginsAreSupported() : false; m_CurrentProfile = profileName; @@ -233,7 +235,7 @@ void PluginList::refresh(const QString& profileName, m_ESPs.push_back(ESPInfo(filename, forceEnabled, originName, ToQString(current->getFullPath()), hasIni, - loadedArchives, lightPluginsAreSupported)); + loadedArchives, lightPluginsAreSupported, overridePluginsAreSupported)); m_ESPs.rbegin()->priority = -1; } catch (const std::exception& e) { reportError( @@ -990,6 +992,16 @@ bool PluginList::isLightFlagged(const QString& name) const } } +bool PluginList::isOverrideFlagged(const QString& name) const +{ + auto iter = m_ESPsByName.find(name); + if (iter == m_ESPsByName.end()) { + return false; + } else { + return m_ESPs[iter->second].isOverrideFlagged; + } +} + boost::signals2::connection PluginList::onPluginStateChanged( const std::function&)>& func) { @@ -1049,6 +1061,8 @@ void PluginList::generatePluginIndexes() GamePlugins* gamePlugins = m_GamePlugin->feature(); const bool lightPluginsSupported = gamePlugins ? gamePlugins->lightPluginsAreSupported() : false; + const bool overridePluginsSupported = + gamePlugins ? gamePlugins->overridePluginsAreSupported() : false; for (int l = 0; l < m_ESPs.size(); ++l) { int i = m_ESPsByPriority.at(l); @@ -1065,6 +1079,8 @@ void PluginList::generatePluginIndexes() .arg((numESLs) % 4096, 3, 16, QChar('0')) .toUpper(); ++numESLs; + } else if (overridePluginsSupported && m_ESPs[i].isOverrideFlagged) { + m_ESPs[i].index = QString(""); } else { m_ESPs[i].index = QString("%1").arg(l - numESLs - numSkipped, 2, 16, QChar('0')).toUpper(); @@ -1705,7 +1721,7 @@ QModelIndex PluginList::parent(const QModelIndex&) const PluginList::ESPInfo::ESPInfo(const QString& name, bool enabled, const QString& originName, const QString& fullPath, bool hasIni, std::set archives, - bool lightPluginsAreSupported) + bool lightSupported, bool overrideSupported) : name(name), fullPath(fullPath), enabled(enabled), forceEnabled(enabled), priority(0), loadOrder(-1), originName(originName), hasIni(hasIni), archives(archives.begin(), archives.end()), modSelected(false) @@ -1714,9 +1730,10 @@ PluginList::ESPInfo::ESPInfo(const QString& name, bool enabled, ESP::File file(ToWString(fullPath)); auto extension = name.right(3).toLower(); hasMasterExtension = (extension == "esm"); - hasLightExtension = lightPluginsAreSupported && (extension == "esl"); + hasLightExtension = lightSupported && (extension == "esl"); isMasterFlagged = file.isMaster(); - isLightFlagged = lightPluginsAreSupported && file.isLight(); + isOverrideFlagged = overrideSupported && file.isOverride(); + isLightFlagged = lightSupported && !isOverrideFlagged && file.isLight(overrideSupported); author = QString::fromLatin1(file.author().c_str()); description = QString::fromLatin1(file.description().c_str()); @@ -1729,6 +1746,7 @@ PluginList::ESPInfo::ESPInfo(const QString& name, bool enabled, hasMasterExtension = false; hasLightExtension = false; isMasterFlagged = false; + isOverrideFlagged = false; isLightFlagged = false; } } diff --git a/src/pluginlist.h b/src/pluginlist.h index e7a65c814..56f9e1a9a 100644 --- a/src/pluginlist.h +++ b/src/pluginlist.h @@ -241,6 +241,7 @@ class PluginList : public QAbstractItemModel bool hasLightExtension(const QString& name) const; bool isMasterFlagged(const QString& name) const; bool isLightFlagged(const QString& name) const; + bool isOverrideFlagged(const QString& name) const; boost::signals2::connection onRefreshed(const std::function& callback); boost::signals2::connection @@ -314,7 +315,7 @@ public slots: { ESPInfo(const QString& name, bool enabled, const QString& originName, const QString& fullPath, bool hasIni, std::set archives, - bool lightSupported); + bool lightSupported, bool overrideSupported); QString name; QString fullPath; @@ -329,6 +330,7 @@ public slots: bool hasLightExtension; bool isMasterFlagged; bool isLightFlagged; + bool isOverrideFlagged; bool modSelected; QString author; QString description; From 94455c2dabea121274d6190f1f0845731f0e3800 Mon Sep 17 00:00:00 2001 From: Jeremy Rimpo Date: Sat, 9 Sep 2023 04:37:03 -0500 Subject: [PATCH 08/15] Add 'None' LoadOrderMechanism which disables managed plugins - Primary plugins are still marked as loaded --- src/pluginlist.cpp | 30 +++++++++++++++++++++--------- src/pluginlist.h | 7 ++++--- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp index 311f05ec7..d3987e4d0 100644 --- a/src/pluginlist.cpp +++ b/src/pluginlist.cpp @@ -205,6 +205,9 @@ void PluginList::refresh(const QString& profileName, bool forceEnabled = Settings::instance().game().forceEnableCoreFiles() && primaryPlugins.contains(filename, Qt::CaseInsensitive); + bool forceDisabled = + m_GamePlugin->loadOrderMechanism() == IPluginGame::LoadOrderMechanism::None && + !forceEnabled; bool archive = false; try { @@ -233,9 +236,10 @@ void PluginList::refresh(const QString& profileName, originName = modInfo->name(); } - m_ESPs.push_back(ESPInfo(filename, forceEnabled, originName, + m_ESPs.push_back(ESPInfo(filename, forceEnabled, forceDisabled, originName, ToQString(current->getFullPath()), hasIni, - loadedArchives, lightPluginsAreSupported, overridePluginsAreSupported)); + loadedArchives, lightPluginsAreSupported, + overridePluginsAreSupported)); m_ESPs.rbegin()->priority = -1; } catch (const std::exception& e) { reportError( @@ -390,7 +394,8 @@ void PluginList::enableESP(const QString& name, bool enable) if (iter != m_ESPsByName.end()) { auto enabled = m_ESPs[iter->second].enabled; - m_ESPs[iter->second].enabled = enable || m_ESPs[iter->second].forceEnabled; + m_ESPs[iter->second].enabled = (enable && !m_ESPs[iter->second].forceDisabled) || + m_ESPs[iter->second].forceEnabled; emit writePluginsList(); if (enabled != m_ESPs[iter->second].enabled) { @@ -856,7 +861,8 @@ void PluginList::setState(const QString& name, PluginStates state) auto iter = m_ESPsByName.find(name); if (iter != m_ESPsByName.end()) { m_ESPs[iter->second].enabled = - (state == IPluginList::STATE_ACTIVE) || m_ESPs[iter->second].forceEnabled; + (state == IPluginList::STATE_ACTIVE && !m_ESPs[iter->second].forceDisabled) || + m_ESPs[iter->second].forceEnabled; } else { log::warn("Plugin not found: {}", name); } @@ -1171,7 +1177,7 @@ QVariant PluginList::checkstateData(const QModelIndex& modelIndex) const { const int index = modelIndex.row(); - if (m_ESPs[index].forceEnabled) { + if (m_ESPs[index].forceEnabled || m_ESPs[index].forceDisabled) { return {}; } @@ -1295,6 +1301,11 @@ QVariant PluginList::tooltipData(const QModelIndex& modelIndex) const tr("This ESP is flagged as an ESL. It will adhere to the ESP load " "order but the records will be loaded in ESL space."); } + + if (esp.forceDisabled) { + toolTip += "

" + tr("This game does not currently permit custom plugin " + "loading. There may be manual workarounds."); + } } // additional info @@ -1718,13 +1729,13 @@ QModelIndex PluginList::parent(const QModelIndex&) const return QModelIndex(); } -PluginList::ESPInfo::ESPInfo(const QString& name, bool enabled, +PluginList::ESPInfo::ESPInfo(const QString& name, bool enabled, bool forceDisabled, const QString& originName, const QString& fullPath, bool hasIni, std::set archives, bool lightSupported, bool overrideSupported) : name(name), fullPath(fullPath), enabled(enabled), forceEnabled(enabled), - priority(0), loadOrder(-1), originName(originName), hasIni(hasIni), - archives(archives.begin(), archives.end()), modSelected(false) + forceDisabled(forceDisabled), priority(0), loadOrder(-1), originName(originName), + hasIni(hasIni), archives(archives.begin(), archives.end()), modSelected(false) { try { ESP::File file(ToWString(fullPath)); @@ -1733,7 +1744,8 @@ PluginList::ESPInfo::ESPInfo(const QString& name, bool enabled, hasLightExtension = lightSupported && (extension == "esl"); isMasterFlagged = file.isMaster(); isOverrideFlagged = overrideSupported && file.isOverride(); - isLightFlagged = lightSupported && !isOverrideFlagged && file.isLight(overrideSupported); + isLightFlagged = + lightSupported && !isOverrideFlagged && file.isLight(overrideSupported); author = QString::fromLatin1(file.author().c_str()); description = QString::fromLatin1(file.description().c_str()); diff --git a/src/pluginlist.h b/src/pluginlist.h index 56f9e1a9a..0c53fc25f 100644 --- a/src/pluginlist.h +++ b/src/pluginlist.h @@ -313,14 +313,15 @@ public slots: private: struct ESPInfo { - ESPInfo(const QString& name, bool enabled, const QString& originName, - const QString& fullPath, bool hasIni, std::set archives, - bool lightSupported, bool overrideSupported); + ESPInfo(const QString& name, bool enabled, bool forceDisabled, + const QString& originName, const QString& fullPath, bool hasIni, + std::set archives, bool lightSupported, bool overrideSupported); QString name; QString fullPath; bool enabled; bool forceEnabled; + bool forceDisabled; int priority; QString index; int loadOrder; From d586bb23e95e0cf2b1e130f9c027c48636c1e3c4 Mon Sep 17 00:00:00 2001 From: Jeremy Rimpo Date: Sat, 9 Sep 2023 05:13:48 -0500 Subject: [PATCH 09/15] Code cleanup --- src/directoryrefresher.cpp | 5 ++++- src/organizercore.cpp | 13 +++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/directoryrefresher.cpp b/src/directoryrefresher.cpp index 63ac28d78..6abbd0c43 100644 --- a/src/directoryrefresher.cpp +++ b/src/directoryrefresher.cpp @@ -475,7 +475,10 @@ void DirectoryRefresher::refresh() for (auto directory : game->secondaryDataDirectories().toStdMap()) { DirectoryStats dummy; - m_Root->addFromOrigin(directory.first.toStdWString(), QDir::toNativeSeparators(directory.second.absolutePath()).toStdWString(), 0, dummy); + m_Root->addFromOrigin( + directory.first.toStdWString(), + QDir::toNativeSeparators(directory.second.absolutePath()).toStdWString(), 0, + dummy); } std::sort(m_Mods.begin(), m_Mods.end(), [](auto lhs, auto rhs) { diff --git a/src/organizercore.cpp b/src/organizercore.cpp index b92c6c6f4..e3d1ff293 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -2015,8 +2015,8 @@ std::vector OrganizerCore::fileMapping(const QString& profileName, if (modPtr->isRegular()) { for (auto dataPath : dataPaths) { - result.insert(result.end(), { QDir::toNativeSeparators(std::get<1>(mod)), - dataPath, true, createTarget }); + result.insert(result.end(), {QDir::toNativeSeparators(std::get<1>(mod)), + dataPath, true, createTarget}); } } } @@ -2039,12 +2039,9 @@ std::vector OrganizerCore::fileMapping(const QString& profileName, } for (auto dataPath : dataPaths) { - result.insert(result.end(), { - QDir::toNativeSeparators(m_Settings.paths().overwrite()), - dataPath, - true, - customOverwrite.isEmpty() - }); + result.insert(result.end(), + {QDir::toNativeSeparators(m_Settings.paths().overwrite()), dataPath, + true, customOverwrite.isEmpty()}); } for (MOBase::IPluginFileMapper* mapper : From 3dc00922ed528659b577116014289ad1c4bd9c8d Mon Sep 17 00:00:00 2001 From: Jeremy Rimpo Date: Tue, 12 Sep 2023 15:08:21 -0500 Subject: [PATCH 10/15] Changes for None-type plugin sorting * Display checkboxes for all plugins * Disable checkboxes for force enabled/disabled plugins * Display tooltip data for all plugins regardless of force status --- src/pluginlist.cpp | 113 ++++++++++++++++++++++++--------------------- 1 file changed, 61 insertions(+), 52 deletions(-) diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp index d3987e4d0..a63617911 100644 --- a/src/pluginlist.cpp +++ b/src/pluginlist.cpp @@ -1178,7 +1178,9 @@ QVariant PluginList::checkstateData(const QModelIndex& modelIndex) const const int index = modelIndex.row(); if (m_ESPs[index].forceEnabled || m_ESPs[index].forceDisabled) { - return {}; + return Qt::Checked; + } else if (m_ESPs[index].forceDisabled) { + return Qt::Unchecked; } return m_ESPs[index].enabled ? Qt::Checked : Qt::Unchecked; @@ -1246,61 +1248,68 @@ QVariant PluginList::tooltipData(const QModelIndex& modelIndex) const if (esp.forceEnabled) { toolTip += "
" + tr("This plugin can't be disabled (enforced by the game).") + ""; - } else { - if (!esp.author.isEmpty()) { - toolTip += "
" + tr("Author") + ": " + TruncateString(esp.author); - } - - if (esp.description.size() > 0) { - toolTip += - "
" + tr("Description") + ": " + TruncateString(esp.description); - } + } - if (esp.masterUnset.size() > 0) { - toolTip += - "
" + tr("Missing Masters") + ": " + "" + - TruncateString( - QStringList(esp.masterUnset.begin(), esp.masterUnset.end()).join(", ")) + - ""; - } + if (!esp.author.isEmpty()) { + toolTip += "
" + tr("Author") + ": " + TruncateString(esp.author); + } - std::set enabledMasters; - std::set_difference(esp.masters.begin(), esp.masters.end(), esp.masterUnset.begin(), - esp.masterUnset.end(), - std::inserter(enabledMasters, enabledMasters.end())); + if (esp.description.size() > 0) { + toolTip += + "
" + tr("Description") + ": " + TruncateString(esp.description); + } - if (!enabledMasters.empty()) { - toolTip += "
" + tr("Enabled Masters") + - ": " + TruncateString(SetJoin(enabledMasters, ", ")); - } + if (esp.masterUnset.size() > 0) { + toolTip += + "
" + tr("Missing Masters") + ": " + "" + + TruncateString( + QStringList(esp.masterUnset.begin(), esp.masterUnset.end()).join(", ")) + + ""; + } + + std::set enabledMasters; + std::set_difference(esp.masters.begin(), esp.masters.end(), esp.masterUnset.begin(), + esp.masterUnset.end(), + std::inserter(enabledMasters, enabledMasters.end())); + + if (!enabledMasters.empty()) { + toolTip += "
" + tr("Enabled Masters") + + ": " + TruncateString(SetJoin(enabledMasters, ", ")); + } + + if (!esp.archives.empty() && esp.archives.size() < 6) { + QString archiveString = + esp.archives.size() < 6 + ? TruncateString( + QStringList(esp.archives.begin(), esp.archives.end()).join(", ")) + + "
" + : ""; + toolTip += "
" + tr("Loads Archives") + ": " + + archiveString + + tr("There are Archives connected to this plugin. Their assets will be " + "added to your game, overwriting in case of conflicts following the " + "plugin order. Loose files will always overwrite assets from " + "Archives. (This flag only checks for Archives from the same mod as " + "the plugin)"); + } - if (!esp.archives.empty()) { - toolTip += - "
" + tr("Loads Archives") + ": " + - TruncateString( - QStringList(esp.archives.begin(), esp.archives.end()).join(", ")) + - "
" + - tr("There are Archives connected to this plugin. Their assets will be " - "added to your game, overwriting in case of conflicts following the " - "plugin order. Loose files will always overwrite assets from " - "Archives. (This flag only checks for Archives from the same mod as " - "the plugin)"); - } + if (esp.hasIni) { + toolTip += "
" + tr("Loads INI settings") + + ": " + "
" + + tr("There is an ini file connected to this plugin. Its settings will " + "be added to your game settings, overwriting in case of conflicts."); + } - if (esp.hasIni) { - toolTip += - "
" + tr("Loads INI settings") + - ": " - "
" + - tr("There is an ini file connected to this plugin. Its settings will " - "be added to your game settings, overwriting in case of conflicts."); - } + if (esp.isLightFlagged && !esp.hasLightExtension) { + toolTip += + "

" + tr("This ESP is flagged as an ESL. It will adhere to the ESP load " + "order but the records will be loaded in ESL space."); + } - if (esp.isLightFlagged && !esp.hasLightExtension) { - toolTip += "

" + - tr("This ESP is flagged as an ESL. It will adhere to the ESP load " - "order but the records will be loaded in ESL space."); - } + if (esp.forceDisabled) { + toolTip += "

" + tr("This game does not currently permit custom plugin " + "loading. There may be manual workarounds."); if (esp.forceDisabled) { toolTip += "

" + tr("This game does not currently permit custom plugin " @@ -1530,8 +1539,8 @@ Qt::ItemFlags PluginList::flags(const QModelIndex& modelIndex) const Qt::ItemFlags result = QAbstractItemModel::flags(modelIndex); if (modelIndex.isValid()) { - if (!m_ESPs[index].forceEnabled) { - result |= Qt::ItemIsUserCheckable | Qt::ItemIsDragEnabled; + if (!m_ESPs[index].forceEnabled && !m_ESPs[index].forceDisabled) { + result |= Qt::ItemIsDragEnabled; } if (modelIndex.column() == COL_PRIORITY) { result |= Qt::ItemIsEditable; From b1f3c7ea510317dc45074f4b930bc15d77b0f03c Mon Sep 17 00:00:00 2001 From: Jeremy Rimpo Date: Tue, 12 Sep 2023 16:53:45 -0500 Subject: [PATCH 11/15] Fix merge issues and small plugin display corrections --- src/pluginlist.cpp | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp index a63617911..b31d60bfd 100644 --- a/src/pluginlist.cpp +++ b/src/pluginlist.cpp @@ -1177,7 +1177,7 @@ QVariant PluginList::checkstateData(const QModelIndex& modelIndex) const { const int index = modelIndex.row(); - if (m_ESPs[index].forceEnabled || m_ESPs[index].forceDisabled) { + if (m_ESPs[index].forceEnabled) { return Qt::Checked; } else if (m_ESPs[index].forceDisabled) { return Qt::Unchecked; @@ -1194,6 +1194,10 @@ QVariant PluginList::foregroundData(const QModelIndex& modelIndex) const return QBrush(Qt::gray); } + if ((modelIndex.column() == COL_NAME) && m_ESPs[index].forceDisabled) { + return QBrush(Qt::darkRed); + } + return {}; } @@ -1277,15 +1281,14 @@ QVariant PluginList::tooltipData(const QModelIndex& modelIndex) const ": " + TruncateString(SetJoin(enabledMasters, ", ")); } - if (!esp.archives.empty() && esp.archives.size() < 6) { + if (!esp.archives.empty()) { QString archiveString = esp.archives.size() < 6 ? TruncateString( QStringList(esp.archives.begin(), esp.archives.end()).join(", ")) + "
" : ""; - toolTip += "
" + tr("Loads Archives") + ": " + - archiveString + + toolTip += "
" + tr("Loads Archives") + ": " + archiveString + tr("There are Archives connected to this plugin. Their assets will be " "added to your game, overwriting in case of conflicts following the " "plugin order. Loose files will always overwrite assets from " @@ -1302,19 +1305,15 @@ QVariant PluginList::tooltipData(const QModelIndex& modelIndex) const } if (esp.isLightFlagged && !esp.hasLightExtension) { + QString type = esp.hasMasterExtension ? "ESM" : "ESP"; toolTip += - "

" + tr("This ESP is flagged as an ESL. It will adhere to the ESP load " - "order but the records will be loaded in ESL space."); + "

" + tr("This %1 is flagged as an ESL. It will adhere to the %1 load " + "order but the records will be loaded in ESL space.").arg(type); } if (esp.forceDisabled) { toolTip += "

" + tr("This game does not currently permit custom plugin " "loading. There may be manual workarounds."); - - if (esp.forceDisabled) { - toolTip += "

" + tr("This game does not currently permit custom plugin " - "loading. There may be manual workarounds."); - } } // additional info From d15a87b0e646e2bffc0605ce8fdae4909e41995c Mon Sep 17 00:00:00 2001 From: Jeremy Rimpo Date: Wed, 13 Sep 2023 03:23:47 -0500 Subject: [PATCH 12/15] Fix lint issues --- src/pluginlist.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp index b31d60bfd..cb3face65 100644 --- a/src/pluginlist.cpp +++ b/src/pluginlist.cpp @@ -1308,7 +1308,8 @@ QVariant PluginList::tooltipData(const QModelIndex& modelIndex) const QString type = esp.hasMasterExtension ? "ESM" : "ESP"; toolTip += "

" + tr("This %1 is flagged as an ESL. It will adhere to the %1 load " - "order but the records will be loaded in ESL space.").arg(type); + "order but the records will be loaded in ESL space.") + .arg(type); } if (esp.forceDisabled) { From 800c2ea084235a09e3f55e38c768b14da40099b3 Mon Sep 17 00:00:00 2001 From: Jeremy Rimpo Date: Fri, 15 Sep 2023 21:30:07 -0500 Subject: [PATCH 13/15] Context menu fix Prevent changing the status of force disabled or enabled plugins via the context menu --- src/pluginlist.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp index cb3face65..a50f242c2 100644 --- a/src/pluginlist.cpp +++ b/src/pluginlist.cpp @@ -421,6 +421,8 @@ void PluginList::setEnabled(const QModelIndexList& indices, bool enabled) { QStringList dirty; for (auto& idx : indices) { + if (m_ESPs[idx.row()].forceEnabled || m_ESPs[idx.row()].forceDisabled) + continue; if (m_ESPs[idx.row()].enabled != enabled) { m_ESPs[idx.row()].enabled = enabled; dirty.append(m_ESPs[idx.row()].name); @@ -437,6 +439,8 @@ void PluginList::setEnabledAll(bool enabled) { QStringList dirty; for (ESPInfo& info : m_ESPs) { + if (info.forceEnabled || info.forceDisabled) + continue; if (info.enabled != enabled) { info.enabled = enabled; dirty.append(info.name); From dff79a6cc01185e2b2f6500ad867e1fa7473a9fc Mon Sep 17 00:00:00 2001 From: Jeremy Rimpo Date: Fri, 15 Sep 2023 21:31:17 -0500 Subject: [PATCH 14/15] Bumping version since betas are pulling ahead --- src/version.rc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.rc b/src/version.rc index 49fe45263..0db83d44d 100644 --- a/src/version.rc +++ b/src/version.rc @@ -4,7 +4,7 @@ // 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-beta2\0" +#define VER_FILEVERSION_STR "2.5.0-beta7\0" VS_VERSION_INFO VERSIONINFO FILEVERSION VER_FILEVERSION From f2a784ed70ef75954a4b9ba5b317794532116619 Mon Sep 17 00:00:00 2001 From: Jeremy Rimpo Date: Sat, 16 Sep 2023 03:21:18 -0500 Subject: [PATCH 15/15] Allow unforced plugins to be checkable again --- src/pluginlist.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp index a50f242c2..efa51ac70 100644 --- a/src/pluginlist.cpp +++ b/src/pluginlist.cpp @@ -1544,7 +1544,7 @@ Qt::ItemFlags PluginList::flags(const QModelIndex& modelIndex) const if (modelIndex.isValid()) { if (!m_ESPs[index].forceEnabled && !m_ESPs[index].forceDisabled) { - result |= Qt::ItemIsDragEnabled; + result |= Qt::ItemIsUserCheckable | Qt::ItemIsDragEnabled; } if (modelIndex.column() == COL_PRIORITY) { result |= Qt::ItemIsEditable;