Compare commits

..
Author SHA1 Message Date
Jonathan Feenstra d4ce82a262 Extract getValidGameShortName method in download manager (#2380) 2026-05-04 13:39:08 +02:00
AL 4242abeab1 Guard the .meta creation in openMetaFile against the directory watcher
openMetaFile creates the .meta file via QSettings when one does not
exist; the disk write fires directoryChanged and triggers a spurious
refreshList. Wrap it in a DirWatcherManager::Guard like the other
meta-file editing paths.
2026-05-04 13:39:08 +02:00
AL 7d8d4bb545 Coalesce the removeDownload reset with the following refreshList
Moves the ModelResetGuard out of the try-catch so it also wraps the
refreshList() call below. Without this, one reset fires when the guard
destructs at the end of the try block and another fires from
refreshList's own guard, producing two resets where one is sufficient.
2026-05-04 13:39:08 +02:00
AL af789246f9 Address PR feedback: fix redundant check and move refresh outside try catch. 2026-05-04 13:39:08 +02:00
AL 6b5ffc41f4 Remove unused alphabetical translation vector
m_AlphabeticalTranslation was written but never read; drop it along with
refreshAlphabeticalTranslation, ByName, and the LessThanWrapper helper.
2026-05-04 13:39:07 +02:00
pre-commit-ci[bot] 5a44a6d934 [pre-commit.ci] Auto fixes from pre-commit.com hooks. 2026-05-04 13:39:07 +02:00
AL 78f4343304 Sanitize suffix path in getDownloadFileName
The collision-avoidance branch was using the raw baseName, so invalid
characters sanitized out of the initial path leaked into the suffixed one.
2026-05-04 13:39:07 +02:00
AL 6eb5191653 Fix memory leak in DownloadInfo::createFromMeta
Move the allocation past the early-return checks so path-mismatch and
hidden-skip paths no longer leak a fresh DownloadInfo.
2026-05-04 13:39:07 +02:00
AL 1e8ada5348 Fix lost finished() signal on fast downloads
Hoist the file-exists prompt out of startDownload so setup is straight-line.
Connect finished() last and dispatch manually if the reply already finished.
2026-05-04 13:39:07 +02:00
AL f7bb36b1b1 Fix comma operator in addNXMDownload pending-dedup check
The game-name comparison result was discarded by the comma operator,
so the dedup only matched modId/fileId across all games.
2026-05-04 13:39:07 +02:00
AL c94858be4d Centralize row notifications in setState and fix missed emits
setState emits notifyRowChanged itself, uses indexByInfo (-1 when
untracked), and re-looks up the row at each use so reply->abort() and
plugin callbacks that re-enter and erase info don't produce stale
signals.

Remove the trailing emit loop from createMetaFile and the now-redundant
notifyRowChanged calls scattered after setState. Add the two missing
emits in restoreDownload (after m_Hidden) and metaDataChanged (after
rename). Guard downloadFinished with a top-level DirWatcherGuard to
prevent filesystem events from its writes racing with model updates.
2026-05-04 13:39:07 +02:00
AL 07faf9c635 Replace aboutToUpdate/update(int) with ModelResetGuard
Replace the fragile two-signal protocol with a refcounted RAII
ModelResetGuard. Split update(int) into aboutToResetModel/modelReset
(guard only) and rowChanged(int); notifyRowChanged() is suppressed while
a reset is active.

Fixes "beginResetModel without endResetModel" warnings from three sites
in downloadFinished/removeDownload that were pairing reset with a row
update. removePending only opens a guard when an actual match is removed.
2026-05-04 13:39:07 +02:00
AL 829ee4f9c2 Encapsulate the downloads directory watcher in DirWatcherManager
QFileSystemWatcher suppression currently relies on public static start/end
methods and a static counter. Seven call sites pair them raw, one of them
outside the class. Any exception between a pair permanently disables the
watcher, and the static counter implies a singleton DownloadManager.

A new DirWatcherManager owns the watcher, the counter (now an instance
member), and the filtering. The only way to suspend is an RAII Guard
obtained via a scopedGuard() factory. All raw pairs migrate to guards. A
TODO flags the existing processEvents() in the dtor as a known reentrancy
hazard worth replacing later.
2026-05-04 13:39:06 +02:00
Al ca7a149874 Improve mod update check accuracy (#2385)
* Index API response into lookup maps

* extract new findLatestActiveSuccessor method from update check function

* extract method to check if a file is active

* use new isActiveFileStatus in modInfoRegular

* fix bug when merging during mod install

* remember ordering of installed nexus file ids

* refactor update check logic to prioritize Nexus file IDs over filenames

* refactor nxmUpdatesAvailable to simplify update checking logic

* refactor update check logic to find Nexus file IDs by filename and streamline successor retrieval

* refactor update checking to streamline version resolution and improve successor retrieval
2026-05-03 21:47:20 -05:00
Jeremy Rimpo ef7499aade Extended MODL / direct download handling (#2384)
* Extended MODL / direct download handling
- name, modname, version, and source options added to download command
- nxmhandler init adds schemas and MODL entry with default launch args
- Add MODL register button to general tab
- On window display, call meta function to trigger both registrations
2026-05-03 03:04:49 -05:00
Jeremy Rimpo 2e393aa3cc Handle Nexus collections links (#2383)
- Pops up dialog when the NXM link is a collection
- Collection link data available, though still unsupported
2026-05-02 10:45:09 -05:00
Mick dc420a258a Change IconDelegate::paintIcons to only execute when iconWidth > 0 (#2362) 2026-04-27 08:58:17 +02:00
Jonathan Feenstra 49da80c2a4 Make command-line arguments -i "" launch the portable instance (#2341) 2026-04-27 08:57:00 +02:00
Al f80ad0435c fix crash when CWD is not set to app directory (#2379) 2026-04-26 21:43:16 -05:00
Jeremy Rimpo 925bade315 Disabling tutorials (#2366) 2026-04-17 10:17:59 +02:00
Jonathan Feenstra 9deaf71362 Add more contributors to the about dialog (#2369) 2026-04-17 10:17:11 +02:00
Jeremy Rimpo 3a5140bb8f Starfield: Updated blueprint / blueprint prefix support (#2368)
* Add blueprint handling with blueprintships

* Blueprint changes
- Add tooltips
- Add warnings
- Handle blueprint prefixes properly

* Make sure we're assigning the property
2026-04-16 10:20:50 -05:00
Jeremy Rimpo 05593c0347 Update libloot dll name in sanity check (#2370) 2026-04-16 10:17:13 -05:00
Jeremy Rimpo ca4e81ca86 Removing references to openssl (#2367) 2026-04-16 14:09:53 +02:00
Jeremy Rimpo 6bd8bcc239 Update vcpkg targets (#2365) 2026-04-15 09:59:11 +02:00
Mick 7528d023c4 fix header guard typos (#2364) 2026-04-15 09:27:38 +02:00
pre-commit-ci[bot] 662f033295 [pre-commit.ci] Pre-commit autoupdate. (#2357)
* [pre-commit.ci] Pre-commit autoupdate.

updates:
- [github.com/pre-commit/mirrors-clang-format: v21.1.8 → v22.1.2](https://github.com/pre-commit/mirrors-clang-format/compare/v21.1.8...v22.1.2)

* [pre-commit.ci] Auto fixes from pre-commit.com hooks.

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-04-09 13:16:16 +02:00
Jonathan Feenstra 2043d9931c Remove "Categories: " tooltips when there are no categories (#2339) 2026-02-18 19:48:12 +01:00
Jonathan Feenstra 4da0bffeee Add instance manager to plugin API (#2335) 2026-02-08 10:08:10 +01:00
Jonathan Feenstra a394f02e97 Add executables list to plugin API (#2327) 2026-01-31 16:49:46 +01:00
Jonathan Feenstra aa44561e86 Change IOrganizer::profile return type to a shared_ptr (#2322) 2026-01-11 17:31:26 +01:00
Jonathan Feenstra 717b5ac389 Add instanceName and profiles methods to plugin API (#2321) 2026-01-11 12:36:07 +01:00
pre-commit-ci[bot] 1505519ecd [pre-commit.ci] Pre-commit autoupdate. (#2320)
updates:
- [github.com/pre-commit/mirrors-clang-format: v21.1.2 → v21.1.8](https://github.com/pre-commit/mirrors-clang-format/compare/v21.1.2...v21.1.8)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-01-05 19:38:47 +01:00
Jonathan Feenstra e5ac1cc82d Add executable setting to minimize MO2 to the system tray while running (#2313) 2026-01-03 15:48:06 +01:00
Mikaël Capelle d5bd9603c6 Add missing Qt dependencies in CI. (#2317) 2026-01-03 14:49:24 +01:00
pre-commit-ci[bot] cc78137eb5 [pre-commit.ci] Pre-commit autoupdate. (#2295)
updates:
- [github.com/pre-commit/pre-commit-hooks: v5.0.0 → v6.0.0](https://github.com/pre-commit/pre-commit-hooks/compare/v5.0.0...v6.0.0)
- [github.com/pre-commit/mirrors-clang-format: v20.1.7 → v21.1.2](https://github.com/pre-commit/mirrors-clang-format/compare/v20.1.7...v21.1.2)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-10-07 15:01:47 +02:00
itch 8016e77723 fix(qt): remove obsolete call to AA_EnableHighDpiScaling (#2283) 2025-09-15 09:40:50 +02:00
Mikaël Capelle b77b2722b7 Fix an issue with implementation of CombinedModDataContent. (#2278) 2025-09-03 10:13:06 +02:00
Jonathan Feenstra d52fcccb83 Add author and uploader columns to mod list (#2269) 2025-08-18 07:55:52 +02:00
Mikaël Capelle 6c64236e2e Allow non-cache build in CI when Azure variables are not available. (#2270) 2025-08-17 12:32:23 +02:00
pre-commit-ci[bot] 95b9ab2e45 [pre-commit.ci] Pre-commit autoupdate. (#2258)
updates:
- [github.com/pre-commit/mirrors-clang-format: v19.1.5 → v20.1.7](https://github.com/pre-commit/mirrors-clang-format/compare/v19.1.5...v20.1.7)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-07-08 07:50:31 +02:00
Mikaël Capelle 28e712c8a3 Add version of MO2 plugin loaded in logs. (#2252) 2025-06-06 15:06:11 +02:00
Mikaël Capelle 87d0f2eeb6 Fix registry for 2.5.3-beta.2. (#2250) 2025-05-29 14:24:52 +02:00
Mikaël Capelle 455b5075f1 Update registry for 2.5.3-beta.2. (#2249) 2025-05-29 13:06:12 +02:00
Mikaël Capelle 39210af3e5 Move to VCPKG (#2068)
* Remove SConscript related files.
* Force-load translations from uibase and gamebryo/creation.
* Bring githubpp here and add a standalone preset.
* Switch VersionInfo -> Version for ModOrganizer2. (#2063)
* Add pre-commit hook.
* Use 7zip build from VCPKG registry.
* Use archive.dll from the bin folder instead of dlls.
2025-05-29 11:04:36 +02:00
Jeremy RimpoandMikaël Capelle 3a8ea3ccce Oblivion Remastered Meta PR (#2241)
* Allow for mod directory maps
- Set main data files based on game
- Mapped mod directories to VFS
- Update overwrite setup

* Skip if mod contains no 'data' dir

* More mod directory compatibility fixes

* Workaround for Obl:Rem save location
- SLocalSavePath does nothing yet MO2 wants to use it to override the default save location
- This only applies to BGS games anyway, we should move this logic

* First pass for overwrite mod directory support

* More overwrite move / delete restrictions

* Fix issue with moving directories that are not required

* Formatting pass

* More modDataDirectory updates

* Formatting

---------

Co-authored-by: Mikaël Capelle <capelle.mikael@gmail.com>
2025-05-23 14:08:01 -05:00
5d766e94a7 Mass Metadata Parsing: Prevent re-querying and manual prompts to enter missing data (#2135)
* Add a button to "Query Info" of every download in the list

---------

Co-authored-by: Deewens <dudonadrien@gmail.com>
Co-authored-by: KenJyn76 <liambonilla@gmail.com>
Co-authored-by: Al <26797547+Al12rs@users.noreply.github.com>
2025-05-23 09:24:23 +02:00
Jonathan Feenstra a823d2aa88 Ignore conflicts between hidden files (#2148)
* Ignore conflicts between hidden files
* Optimize checks for .mohidden extension
2025-05-23 09:23:36 +02:00
RJandRJ b531bbff39 Update following SafeWriteFile changes (#2218)
Co-authored-by: RJ <Liderate@users.noreply.github.com>
2025-05-23 09:18:03 +02:00
RJandRJ 3ef0db4cca Speedup refresh when archive parsing is enabled and updateBSAList (#2239)
* Precompute load order for ModThreads
* Precompute file infos for plugin association check

---------

Co-authored-by: RJ <Liderate@users.noreply.github.com>
2025-05-23 09:15:43 +02:00
Jeremy Rimpo 15f3d2ba05 Fix an error when filters hide highlighted rows (#2245)
- Crash caused by dataChanged triggering selectionChanged in loop
- Repaint accomplishes what we need
2025-05-22 14:35:48 -05:00
Jeremy Rimpo 48f1f600de Update copyrights (#2246) 2025-05-22 20:51:49 +02:00
Mikaël Capelle a41028fafc Update following USVFS move to VCPKG. (#2244) 2025-05-22 19:35:44 +02:00
Jeremy Rimpo eddc30a47f Dependency Updates Meta PR (#2242)
* Update dll manifests
* Fixes for emit / model refresh issues
2025-05-22 10:38:39 +02:00
RJandRJ 52b37a760c Store integer instead of QString in categories table ID columns (#2230)
Co-authored-by: RJ <Liderate@users.noreply.github.com>
2025-04-12 14:46:03 +02:00
RJandRJ bff386d277 Do not sort categories table while adding rows (#2229)
Co-authored-by: RJ <Liderate@users.noreply.github.com>
2025-04-01 13:33:52 +02:00
Jonathan Feenstra d2832ec9c3 Add new contributors to the about dialog (#2175) 2025-03-01 11:49:18 +01:00
Chris Djali 62ccbb1d02 Write BOM if original file used one (#2213)
Important for UTF-16 as lots of things can't detect or read UTF-16 without a BOM
2025-02-28 19:52:49 +01:00
Jonathan Feenstra 6299be28e1 Add form and header versions to plugin list tool tips and plugin API and add more columns (#2200) 2025-01-31 20:07:41 +01:00
Jonathan Feenstra 9049e65c5e Add startDownloadNexusFileForGame (#2181) 2025-01-02 14:10:53 +01:00
Jonathan Feenstra f8340e1620 Highlight mods that contain selected files in data tab (#2179) 2025-01-02 08:52:38 +01:00
Jonathan Feenstra 110014bf5e Update readme (#2180) 2024-12-25 11:22:19 +01:00
Jonathan Feenstra 91912f5fef (Un-)endorse & (un-)track mods from the same source (#2141) 2024-10-30 16:20:39 +01:00
Jonathan Feenstra f42a9f1cef Fix error message showing even though instance is already selected (#2154) 2024-10-30 15:20:04 +01:00
283 changed files with 8199 additions and 9658 deletions
@@ -7,7 +7,7 @@ assignees: ''
---
**This template is useful to add basic support using https://github.com/ModOrganizer2/modorganizer-basic_games.**
**This template is useful to add basic support using https://github.com/ModOrganizer2/modorganizer-basic_games.**
**If you are vaguely familiar with programming you can try following the instructions on that link to get something working yourself. If you have trouble with that please fill in this template.**
+11 -30
View File
@@ -2,51 +2,32 @@ name: Build ModOrganizer 2
on:
push:
branches: master
branches: [master]
pull_request:
types: [opened, synchronize, reopened]
env:
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
VCPKG_BINARY_SOURCES: ${{ vars.AZ_BLOB_VCPKG_URL != '' && format('clear;x-azblob,{0},{1},readwrite', vars.AZ_BLOB_VCPKG_URL, secrets.AZ_BLOB_SAS) || '' }}
jobs:
build:
runs-on: windows-2022
steps:
# https://learn.microsoft.com/en-us/vcpkg/consume/binary-caching-github-actions-cache
- name: Export GitHub Actions cache environment variables
uses: actions/github-script@v7
- name: Build ModOrganizer
id: build-modorganizer
uses: ModOrganizer2/build-with-mob-action@master
with:
script: |
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
qt-modules: qtpositioning qtwebchannel qtwebengine qtwebsockets qtnetworkauth
mo2-dependencies: usvfs uibase bsatk esptk archive lootcli
- name: Install Qt
uses: jurplel/install-qt-action@v3
with:
version: 6.7.1
modules: qtpositioning qtwebchannel qtwebengine qtwebsockets
cache: true
- uses: actions/checkout@v4
- name: "Set environmental variables"
shell: bash
run: |
echo "VCPKG_ROOT=$VCPKG_INSTALLATION_ROOT" >> $GITHUB_ENV
- name: Configure ModOrganizer
- name: Install ModOrganizer
shell: pwsh
run: |
cmake --preset vs2022-windows-standalone `
"-DCMAKE_PREFIX_PATH=${env:QT_ROOT_DIR}\msvc2019_64" `
"-DCMAKE_INSTALL_PREFIX=install"
- name: Build ModOrganizer
run: cmake --build vsbuild --config RelWithDebInfo --target INSTALL
cmake --install vsbuild --config RelWithDebInfo
working-directory: ./build/${{ github.event.repository.name }}
- name: Package ModOrganizer
uses: actions/upload-artifact@master
with:
name: modorganizer
path: ./install
path: ./install/bin
-1
View File
@@ -12,6 +12,5 @@ edit
/msbuild.log
/*std*.log
/*build
.vscode
/src/version.aps
+20
View File
@@ -0,0 +1,20 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-merge-conflict
- id: check-case-conflict
- repo: https://github.com/pre-commit/mirrors-clang-format
rev: v22.1.2
hooks:
- id: clang-format
'types_or': [c++, c]
ci:
autofix_commit_msg: "[pre-commit.ci] Auto fixes from pre-commit.com hooks."
autofix_prs: true
autoupdate_commit_msg: "[pre-commit.ci] Pre-commit autoupdate."
autoupdate_schedule: quarterly
submodules: false
+12 -5
View File
@@ -3,15 +3,22 @@ cmake_minimum_required(VERSION 3.16)
# TODO: clean include directives
set(MO2_CMAKE_DEPRECATED_UIBASE_INCLUDE ON)
# Remove tutorials until Qt is fixed
set(MO2_SKIP_TUTORIALS_INSTALL ON)
project(organizer)
find_package(mo2-cmake CONFIG REQUIRED)
set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1)
# if MO2_INSTALL_IS_BIN is set, this means that we should install directly into the
# installation prefix, without the bin/ subfolder, typically for a standalone build
# to update an existing install
if (MO2_INSTALL_IS_BIN)
set(_bin ".")
else()
set(_bin bin)
endif()
add_subdirectory(src)
add_subdirectory(themes)
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT organizer)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/dump_running_process.bat DESTINATION ${MO2_INSTALL_BIN})
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/dump_running_process.bat DESTINATION ${_bin})
+13 -1
View File
@@ -29,7 +29,7 @@
"value": "x64"
},
"cacheVariables": {
"CMAKE_CXX_FLAGS": "/EHsc /MP /W3",
"CMAKE_CXX_FLAGS": "/EHsc /MP /W4",
"VCPKG_TARGET_TRIPLET": {
"type": "STRING",
"value": "x64-windows-static-md"
@@ -55,5 +55,17 @@
"name": "vs2022-windows-standalone"
}
],
"buildPresets": [
{
"name": "vs2022-windows",
"resolvePackageReferences": "on",
"configurePreset": "vs2022-windows"
},
{
"name": "vs2022-windows-standalone",
"resolvePackageReferences": "on",
"configurePreset": "vs2022-windows-standalone"
}
],
"version": 4
}
+1 -1
View File
@@ -671,4 +671,4 @@ into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+5 -4
View File
@@ -12,8 +12,8 @@ The project took up speed again after a few more coders showed up in late 2017,
## Help Wanted!
Mod Organizer 2 is an open project in the hands of the community, there are problems that need to be solved and things that could be added. MO2 really needs developers and if you have the programming skills and some free time you can really improve the experience of the modding community.
To have more information, please join the open MO2 Development discord server: [Mod Organizer 2](https://discord.gg/ewUVAqyrQX)
If you want to help translate MO2 to your language you should join the discord server too and head to the #translation channel.
To have more information, please join the open MO2 Development Discord server: [Mod Organizer 2](https://discord.gg/ewUVAqyrQX)
If you want to help translate MO2 to your language you should join the Discord server too and head to the #translation channel.
To setup a development environment on your machine, there is the [mob project](https://github.com/modorganizer2/mob) that handles that.
If you want to submit your code changes, please use a good formatting style like the default one in Visual Studio.
@@ -22,7 +22,7 @@ Through the work of a few people of the community MO2 has come quite far, now it
## Reporting Issues:
Issues should be reported to the GitHub page or on the open discord server: [Mod Organizer 2](https://discord.gg/ewUVAqyrQX). Here is also where dev builds are tested, bugs are reported and investigated, suggestions are discussed and a lot more.
Credits to Tannin, LePresidente, Silarn, erasmux, AL12, LostDragonist, AnyOldName3, isa, Holt59 and many others for the development.
Credits to Tannin, LePresidente, Silarn, erasmux, AL12, LostDragonist, AnyOldName3, isa, Holt59, Project579, przester, Qudix, RJ, Jonathan Feenstra and many others for the development.
## Download Location
@@ -39,7 +39,7 @@ Please refer to [Modorganizer2/mob](https://github.com/modorganizer2/mob) for bu
## Other Repositories
MO2 consists of multiple repositories on github. The mob project will download them automatically as required. They should however also be buildable individually.
MO2 consists of multiple repositories on GitHub. The mob project will download them automatically as required. They should however also be buildable individually.
Here is a complete list:
* https://github.com/LePresidente/cpython-1
@@ -67,6 +67,7 @@ Here is a complete list:
* https://github.com/ModOrganizer2/modorganizer-game_skyrim
* https://github.com/ModOrganizer2/modorganizer-game_skyrimSE
* https://github.com/ModOrganizer2/modorganizer-game_skyrimVR
* https://github.com/ModOrganizer2/modorganizer-game_starfield
* https://github.com/ModOrganizer2/modorganizer-game_ttw
* https://github.com/ModOrganizer2/modorganizer-installer_bain
* https://github.com/ModOrganizer2/modorganizer-installer_wizard
+25 -30
View File
@@ -25,16 +25,16 @@ set_target_properties(organizer PROPERTIES
# disable translations because we want to be able to install somewhere else if
# required
mo2_configure_target(organizer WARNINGS 3 TRANSLATIONS OFF)
mo2_configure_target(organizer WARNINGS 4 TRANSLATIONS OFF)
# we add translations "manually" to handle MO2_INSTALL_IS_BIN
mo2_add_translations(organizer
INSTALL_RELEASE
INSTALL_DIRECTORY "${MO2_INSTALL_BIN}/translations"
INSTALL_DIRECTORY "${_bin}/translations"
SOURCES ${CMAKE_CURRENT_SOURCE_DIR})
mo2_set_project_to_run_from_install(
organizer EXECUTABLE ${CMAKE_INSTALL_PREFIX}/${MO2_INSTALL_BIN}/ModOrganizer.exe)
organizer EXECUTABLE ${CMAKE_INSTALL_PREFIX}/${_bin}/ModOrganizer.exe)
target_link_libraries(organizer PRIVATE
Shlwapi Bcrypt
@@ -44,30 +44,35 @@ target_link_libraries(organizer PRIVATE
Qt6::WebEngineWidgets Qt6::WebSockets Version Dbghelp)
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/dlls.manifest.qt6"
DESTINATION ${MO2_INSTALL_BIN}/dlls
DESTINATION ${_bin}/dlls
CONFIGURATIONS Release RelWithDebInfo
RENAME dlls.manifest)
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/dlls.manifest.debug.qt6"
DESTINATION ${MO2_INSTALL_BIN}/dlls
DESTINATION ${_bin}/dlls
CONFIGURATIONS Debug
RENAME dlls.manifest)
if (NOT MO2_SKIP_STYLESHEETS_INSTALL)
install(
DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/stylesheets"
DESTINATION ${_bin})
endif()
if (NOT MO2_SKIP_TUTORIALS_INSTALL)
install(
DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/tutorials"
DESTINATION ${MO2_INSTALL_BIN})
DESTINATION ${_bin})
endif()
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/resources/markdown.html"
DESTINATION ${MO2_INSTALL_BIN}/resources)
DESTINATION ${_bin}/resources)
# install ModOrganizer.exe itself
install(FILES $<TARGET_FILE:organizer> DESTINATION ${MO2_INSTALL_BIN})
install(FILES $<TARGET_FILE:organizer> DESTINATION ${_bin})
# install dependencies DLLs
install(FILES $<TARGET_FILE:mo2::libbsarch> DESTINATION ${MO2_INSTALL_BIN}/dlls)
install(FILES $<TARGET_FILE:mo2::archive> DESTINATION ${MO2_INSTALL_BIN}/dlls)
install(FILES $<TARGET_FILE:7zip::7zip> DESTINATION ${MO2_INSTALL_BIN}/dlls)
install(FILES $<TARGET_FILE:mo2::libbsarch> DESTINATION ${_bin}/dlls)
install(FILES $<TARGET_FILE:7zip::7zip> DESTINATION ${_bin}/dlls)
# this may copy over the ones from uibase/usvfs
# - when building with mob, this should not matter as the files should be identical
@@ -83,7 +88,7 @@ install(FILES
$<TARGET_FILE:usvfs_x86::usvfs_dll>
$<TARGET_FILE:usvfs_x64::usvfs_proxy>
$<TARGET_FILE:usvfs_x86::usvfs_proxy>
DESTINATION ${MO2_INSTALL_BIN})
DESTINATION ${_bin})
# do not install PDB if CMAKE_INSTALL_PREFIX is "bin"
if (NOT MO2_INSTALL_IS_BIN)
@@ -91,7 +96,7 @@ if (NOT MO2_INSTALL_IS_BIN)
endif()
mo2_deploy_qt(
DIRECTORY ${MO2_INSTALL_BIN}
DIRECTORY ${_bin}
BINARIES ModOrganizer.exe $<TARGET_FILE_NAME:mo2::uibase>)
# set source groups for VS
@@ -104,6 +109,7 @@ mo2_add_filter(NAME src/application GROUPS
multiprocess
sanitychecks
selfupdater
systemtraymanager
updatedialog
)
@@ -121,12 +127,13 @@ mo2_add_filter(NAME src/categories GROUPS
mo2_add_filter(NAME src/core GROUPS
archivefiletree
github
inibakery
githubpp
installationmanager
nexusinterface
nxmaccessmanager
organizercore
game_features
plugincontainer
apiuseraccount
processrunner
qdirfiletree
@@ -134,16 +141,6 @@ mo2_add_filter(NAME src/core GROUPS
uilocker
)
mo2_add_filter(NAME src/extensions GROUPS
game_features
thememanager
translationmanager
extensionmanager
extensionwatcher
pluginmanager
proxyqt
)
mo2_add_filter(NAME src/dialogs GROUPS
aboutdialog
activatemodsdialog
@@ -277,9 +274,10 @@ mo2_add_filter(NAME src/profiles GROUPS
mo2_add_filter(NAME src/proxies GROUPS
downloadmanagerproxy
executableslistproxy
gamefeaturesproxy
instancemanagerproxy
modlistproxy
extensionlistproxy
organizerproxy
pluginlistproxy
proxyutils
@@ -296,7 +294,6 @@ mo2_add_filter(NAME src/register GROUPS
)
mo2_add_filter(NAME src/settings GROUPS
extensionsettings
settings
settingsutilities
)
@@ -307,9 +304,7 @@ mo2_add_filter(NAME src/settingsdialog GROUPS
settingsdialoggeneral
settingsdialognexus
settingsdialogpaths
settingsdialogextensions
settingsdialogextensionrow
settingsdialogextensioninfo
settingsdialogplugins
settingsdialogworkarounds
settingsdialogmodlist
settingsdialogtheme
-2331
View File
File diff suppressed because it is too large Load Diff
-2
View File
@@ -45,7 +45,6 @@ AboutDialog::AboutDialog(const QString& version, QWidget* parent)
m_LicenseFiles[LICENSE_CCBY3] = "BY-SA-v3.0.txt";
m_LicenseFiles[LICENSE_ZLIB] = "zlib.txt";
m_LicenseFiles[LICENSE_PYTHON] = "python.txt";
m_LicenseFiles[LICENSE_SSL] = "openssl.txt";
m_LicenseFiles[LICENSE_CPPTOML] = "cpptoml.txt";
m_LicenseFiles[LICENSE_UDIS] = "udis86.txt";
m_LicenseFiles[LICENSE_SPDLOG] = "spdlog.txt";
@@ -69,7 +68,6 @@ AboutDialog::AboutDialog(const QString& version, QWidget* parent)
addLicense("ANTLR", LICENSE_ANTLR);
addLicense("LOOT", LICENSE_GPL3);
addLicense("Python", LICENSE_PYTHON);
addLicense("OpenSSL", LICENSE_SSL);
addLicense("cpptoml", LICENSE_CPPTOML);
addLicense("Udis86", LICENSE_UDIS);
addLicense("spdlog", LICENSE_SPDLOG);
-1
View File
@@ -51,7 +51,6 @@ private:
LICENSE_BOOST,
LICENSE_CCBY3,
LICENSE_PYTHON,
LICENSE_SSL,
LICENSE_CPPTOML,
LICENSE_7ZIP,
LICENSE_ZLIB,
+186 -6
View File
@@ -127,7 +127,7 @@
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string notr="true">&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Copyright © 2011-2016 Sebastian Herbord&lt;br/&gt;Copyright © 2016-2023 Mod Organizer 2 Contributors&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string notr="true">&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Copyright © 2011-2016 Sebastian Herbord&lt;br/&gt;Copyright © 2016-2026 Mod Organizer 2 Contributors&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
@@ -222,7 +222,7 @@
</item>
<item>
<property name="text">
<string>Holt59</string>
<string notr="true">Holt59</string>
</property>
</item>
</widget>
@@ -266,6 +266,16 @@
<string notr="true">Qudix</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">RJ</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">Jonathan Feenstra</string>
</property>
</item>
</widget>
</item>
</layout>
@@ -402,7 +412,7 @@
</item>
<item>
<property name="text">
<string>zDas (Portuguese)</string>
<string>Dasinho (Portuguese)</string>
</property>
</item>
<item>
@@ -474,6 +484,21 @@
<string notr="true">6788</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">AkiraJkr</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">AmeliaCute</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">ashemedai</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">blacksol</string>
@@ -494,6 +519,16 @@
<string notr="true">Brixified</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">CheffieGithub</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">daescha</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">ddbb07</string>
@@ -504,11 +539,31 @@
<string notr="true">deathneko11</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">Deewens</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">DefinitelyNotSade</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">dekart811</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">Deorder</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">diegofesanto</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">DoubleYou</string>
@@ -519,6 +574,11 @@
<string notr="true">Drew Warwick</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">Eddoursul</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">erri120</string>
@@ -569,11 +629,66 @@
<string notr="true">jimfcarroll</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">Jonny_Bro</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">ju5tA1ex</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">Kane Dou</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">KenJyn76</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">Ketsuban</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">LaughingHyena</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">Luca|EzioTheDeadPoet</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">mick-lue</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">ModZero</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">mopioid</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">mrudat</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">Nikirack</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">ogrotten</string>
@@ -589,21 +704,46 @@
<string notr="true">Patchier</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">Paynamia</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">PurpleFez</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">Ra2-IFV</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">reedts</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">RodolfoFigueroa</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">Ryan Young</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">Schilduin</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">shellbj</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">SuperSandro2000</string>
@@ -611,17 +751,22 @@
</item>
<item>
<property name="text">
<string notr="true">Trosski</string>
<string notr="true">Syer10</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">Uhuru</string>
<string notr="true">The Conceptionist</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">Wolverine2710</string>
<string notr="true">TheForgotten69</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">TheUnlocked</string>
</property>
</item>
<item>
@@ -629,11 +774,46 @@
<string notr="true">thosrtanner</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">Trosski</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">Twinki</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">Uhuru</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">uwx</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">Wolverine2710</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">xieve</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">z929669</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">Zash</string>
</property>
</item>
</widget>
</item>
</layout>
+2 -2
View File
@@ -17,8 +17,8 @@ You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ARCHIVEFILENETRY_H
#define ARCHIVEFILENTRY_H
#ifndef ARCHIVEFILETREE_H
#define ARCHIVEFILETREE_H
#include <archive/archive.h>
#include <uibase/ifiletree.h>
+19 -7
View File
@@ -97,6 +97,11 @@ public:
int pos = 0;
QString editText = edit->text();
if (m_Validator->validate(editText, pos) == QValidator::Acceptable) {
// Set ID and Parent ID as ints so sorting works as expected
if (index.column() == 0 || index.column() == 2) {
model->setData(index, editText.toInt());
return;
}
QItemDelegate::setModelData(editor, model, index);
}
}
@@ -198,8 +203,8 @@ void CategoriesDialog::fillTable()
table->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);
table->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Fixed);
table->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Stretch);
table->verticalHeader()->setSectionsMovable(true);
table->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);
table->verticalHeader()->setVisible(false);
table->setItemDelegateForColumn(
0, new ValidatingDelegate(this, new NewIDValidator(m_IDs)));
table->setItemDelegateForColumn(
@@ -217,7 +222,6 @@ void CategoriesDialog::fillTable()
}
++row;
table->insertRow(row);
// table->setVerticalHeaderItem(row, new QTableWidgetItem(" "));
QScopedPointer<QTableWidgetItem> idItem(new QTableWidgetItem());
idItem->setData(Qt::DisplayRole, category.ID());
@@ -254,19 +258,26 @@ void CategoriesDialog::fillTable()
}
}
table->setSortingEnabled(true);
refreshIDs();
}
void CategoriesDialog::addCategory_clicked()
{
int row = m_ContextRow >= 0 ? m_ContextRow : 0;
ui->categoriesTable->setSortingEnabled(false);
ui->categoriesTable->insertRow(row);
ui->categoriesTable->setVerticalHeaderItem(row, new QTableWidgetItem(" "));
ui->categoriesTable->setItem(row, 0,
new QTableWidgetItem(QString::number(++m_HighestID)));
QScopedPointer<QTableWidgetItem> idItem(new QTableWidgetItem());
idItem->setData(Qt::DisplayRole, ++m_HighestID);
QScopedPointer<QTableWidgetItem> parentIDItem(new QTableWidgetItem());
parentIDItem->setData(Qt::DisplayRole, 0);
ui->categoriesTable->setItem(row, 0, idItem.take());
ui->categoriesTable->setItem(row, 1, new QTableWidgetItem("new"));
ui->categoriesTable->setItem(row, 2, new QTableWidgetItem("0"));
ui->categoriesTable->setItem(row, 2, parentIDItem.take());
ui->categoriesTable->setItem(row, 3, new QTableWidgetItem(""));
ui->categoriesTable->setSortingEnabled(true);
}
void CategoriesDialog::removeCategory_clicked()
@@ -300,6 +311,7 @@ void CategoriesDialog::nexusImport_clicked()
m_HighestID = 0;
}
int row = 0;
table->setSortingEnabled(false);
for (int i = 0; i < list->count(); ++i) {
QString name = list->item(i)->data(Qt::DisplayRole).toString();
int nexusID = list->item(i)->data(Qt::UserRole).toInt();
@@ -316,7 +328,6 @@ void CategoriesDialog::nexusImport_clicked()
if (!table->findItems(name, Qt::MatchExactly).size()) {
row = table->rowCount();
table->insertRow(table->rowCount());
// table->setVerticalHeaderItem(row, new QTableWidgetItem(" "));
QScopedPointer<QTableWidgetItem> idItem(new QTableWidgetItem());
idItem->setData(Qt::DisplayRole, ++m_HighestID);
@@ -344,6 +355,7 @@ void CategoriesDialog::nexusImport_clicked()
}
}
}
table->setSortingEnabled(true);
refreshIDs();
}
}
+2
View File
@@ -21,6 +21,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#define CATEGORIESDIALOG_H
#include "categories.h"
#include "plugincontainer.h"
#include "tutorabledialog.h"
#include <set>
@@ -70,6 +71,7 @@ private:
private:
Ui::CategoriesDialog* ui;
PluginContainer* m_PluginContainer;
int m_ContextRow;
int m_HighestID;
-3
View File
@@ -79,9 +79,6 @@
<property name="gridStyle">
<enum>Qt::DashLine</enum>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
+3 -3
View File
@@ -233,12 +233,12 @@ void ColorTable::load(Settings& s)
});
addColor(
QObject::tr("Mod contains selected plugin"), QColor(0, 0, 255, 64),
QObject::tr("Mod contains selected file"), QColor(0, 0, 255, 64),
[this] {
return m_settings->colors().modlistContainsPlugin();
return m_settings->colors().modlistContainsFile();
},
[this](auto&& v) {
m_settings->colors().setModlistContainsPlugin(v);
m_settings->colors().setModlistContainsFile(v);
});
addColor(
+50 -8
View File
@@ -10,6 +10,8 @@
#include <log.h>
#include <report.h>
#include <boost/optional/optional_io.hpp>
namespace cl
{
@@ -221,8 +223,12 @@ std::optional<int> CommandLine::runEarly()
std::optional<int> CommandLine::runPostApplication(MOApplication& a)
{
// handle -i with no arguments
if (m_vm.count("instance") && m_vm["instance"].as<std::string>() == "") {
const auto instanceArg = m_vm.find("instance");
if (instanceArg != m_vm.end() &&
!instanceArg->second.as<boost::optional<std::string>>().has_value()) {
// handle -i with no arguments (distinct from -i "", which will launch the
// portable instance if it exists, hence the use of boost::optional)
env::Console c;
if (auto i = InstanceManager::singleton().currentInstance()) {
@@ -314,7 +320,9 @@ void CommandLine::createOptions()
("logs", "duplicates the logs to stdout")
("instance,i", po::value<std::string>()->implicit_value(""),
("instance,i",
po::value<boost::optional<std::string>>()->implicit_value(
boost::none),
"use the given instance (defaults to last used)")
("profile,p", po::value<std::string>(),
@@ -402,8 +410,14 @@ std::optional<QString> CommandLine::instance() const
if (m_shortcut.isValid() && m_shortcut.hasInstance()) {
return m_shortcut.instanceName();
} else if (m_vm.count("instance")) {
return QString::fromStdString(m_vm["instance"].as<std::string>());
} else {
const auto instanceArg = m_vm.find("instance");
if (instanceArg != m_vm.end()) {
const auto& instanceVal = instanceArg->second.as<boost::optional<std::string>>();
if (instanceVal.has_value()) {
return QString::fromStdString(instanceVal.value());
}
}
}
return {};
@@ -828,9 +842,8 @@ std::optional<int> ReloadPluginCommand::runPostOrganizer(OrganizerCore& core)
QDir(qApp->applicationDirPath() + "/" + ToQString(AppConfig::pluginPath()))
.absoluteFilePath(name);
// TODO: reload extension, not plugin
log::debug("reloading plugin from {}", filepath);
// core.pluginManager().reloadPlugin(filepath);
core.pluginContainer().reloadPlugin(filepath);
return {};
}
@@ -840,6 +853,18 @@ Command::Meta DownloadFileCommand::meta() const
return {"download", "downloads a file", "URL", ""};
}
po::options_description DownloadFileCommand::getVisibleOptions() const
{
po::options_description d;
d.add_options()("name,n", po::value<std::string>(), "(optional) the download name")(
"modname,m", po::value<std::string>(), "(optional) the mod name")(
"version,v", po::value<std::string>(), "(optional) the download / mod version")(
"source,s", po::value<std::string>(), "(optional) the download source");
return d;
}
po::options_description DownloadFileCommand::getInternalOptions() const
{
po::options_description d;
@@ -866,16 +891,33 @@ bool DownloadFileCommand::canForwardToPrimary() const
std::optional<int> DownloadFileCommand::runPostOrganizer(OrganizerCore& core)
{
const QString url = QString::fromStdString(vm()["URL"].as<std::string>());
QString name, modName, version, source;
if (!url.startsWith("https://")) {
reportError(QObject::tr("Download URL must start with https://"));
return 1;
}
if (vm().count("name")) {
name = QString::fromStdString(vm()["name"].as<std::string>());
}
if (vm().count("modname")) {
modName = QString::fromStdString(vm()["modname"].as<std::string>());
}
if (vm().count("version")) {
version = QString::fromStdString(vm()["version"].as<std::string>());
}
if (vm().count("source")) {
source = QString::fromStdString(vm()["source"].as<std::string>());
}
log::debug("starting direct download from command line: {}", url.toStdString());
MessageDialog::showMessage(QObject::tr("Download started"), qApp->activeWindow(),
false);
core.downloadManager()->startDownloadURLs(QStringList() << url);
core.downloadManager()->startDownloadURLWithMeta(url, name, modName, version, source);
return {};
}
+1
View File
@@ -212,6 +212,7 @@ class DownloadFileCommand : public Command
protected:
Meta meta() const override;
po::options_description getVisibleOptions() const override;
po::options_description getInternalOptions() const override;
po::positional_options_description getPositional() const override;

Some files were not shown because too many files have changed in this diff Show More