Compare commits

...
163 Commits
Author SHA1 Message Date
Brian Munro 9a3a15b1f6 Merge pull request #454 from Modorganizer2/Develop
Release 2.1.4
2018-08-02 09:15:12 +02:00
Al12rs 1ea43586d8 Merge branch 'Develop' of https://github.com/Modorganizer2/modorganizer into Develop 2018-08-01 20:12:32 +02:00
Al12rs fd51434e5e Enabled Ctrl+C to copy selected stuff instead of the entire log. No one used it before and now it's much more practical. 2018-08-01 20:04:59 +02:00
LostDragonist 7eb4b33214 Tweak shading of mods and plugins to better support dark themes 2018-08-01 12:55:36 -05:00
Al12rs e1e367c7ea Added CTRL+Doubleclick on plugin list as well 2018-08-01 17:55:07 +02:00
Al12rs 696bb3bc47 Added CTRL+Double Click on Modlist to open in Explorer 2018-08-01 17:18:07 +02:00
Al12rs 10be66a62a Revert "Temporarely disable the BSA list refresh if it is hidden from view. this will need to be reversted once the Bsa changes are added I presume."
This reverts commit 8f28e0af36.
2018-08-01 17:07:35 +02:00
LostDragonist a02b920b19 Force nxmhandler.exe registration when the associate button is clicked
This allows the register dialog to appear when the user had previously selected "No, don't ask again".  If a user is clicking this button, there's a good chance they want MO to be the primary nxm handler.
2018-07-27 12:34:28 -05:00
LostDragonist 2f8e5b4f69 Update translation file 2018-07-24 14:00:26 -05:00
LostDragonist 385765ecdd Truncate strings longer than 1024 characters in the plugin list tooltip 2018-07-23 14:13:12 -05:00
LostDragonist 447a2169fe Allow more characters in instance names and add an error message
Previously allowed:  "A-Za-z0-9 "
Now allowed:         "A-Za-z0-9 !@#$%^()_+-=[]{};'."
2018-07-22 19:44:39 -05:00
LostDragonist fc8a6b358f Improve robustness of endorsement checks
At times, the voted_by_user item is returned as Invalid.  toBool() causes this to be false, meaning the item is seen as not endorsed.  Now, the endorsement state is not checked if the data is invalid.
2018-07-22 14:28:38 -05:00
Al12rs edf608ab23 Allow normal QAbstractItemModel event handling for mainwindow. Somehow before it wouldn't work. 2018-07-22 15:49:40 +02:00
Al12rs d02df7e4b4 Avoided downloads defaulting to "File Time" sorting at each startup.
Improved downloads tab header sizes and resize policy.
2018-07-21 23:43:04 +02:00
Al12rs cc63717060 Added "Open Mods folder" to "Open Folder" context menu. 2018-07-21 20:09:25 +02:00
Al12rs 8f28e0af36 Temporarely disable the BSA list refresh if it is hidden from view. this will need to be reversted once the Bsa changes are added I presume. 2018-07-21 20:01:40 +02:00
Al12rs e80bb3a837 Check if there is actually something in overwrite to delete before asking confirmation. 2018-07-18 16:14:16 +02:00
Al12rs f6ecb93d46 Set delete Key to recursively clear overwrite with confirmation message. 2018-07-18 16:00:19 +02:00
Al12rs 4f14598cfc Changed size rappresentation in downloads compact view. 2018-07-18 12:06:35 +02:00
Al12rs ce2494ba20 Don't show info dialog for unmanaged pluugins. 2018-07-18 12:03:02 +02:00
Al12rs d5f3bee642 Changed unit check. 2018-07-18 12:01:50 +02:00
Al12rs b38957d853 Small visual fix for size positioning in compact downloads. 2018-07-18 12:00:55 +02:00
Al12rs f824d255a2 Added clarification to loads archives tooltip. 2018-07-17 19:51:30 +02:00
Al12rs 344b83957e Revert "Fix download index in downloadFinished"
This reverts commit 942e656a71.
2018-07-17 18:35:32 +02:00
Al12rs 023cacab7f Added ability to open mod information window by double cliking on plugins. 2018-07-17 16:26:17 +02:00
Al12rs 35bbe0001e Added a flag to the plugin list indicating if a certain plugin has one or more archives attached.
Changed the tooltip to list the loaded archives.
Fixed tool tip to have titles for subsections.
2018-07-17 14:37:50 +02:00
Al12rs 75478f68a1 Avoid asking users if they are sure they want to close of all downlaods are paused. 2018-07-17 13:32:53 +02:00
Al12rs 5a0b8b431c Added Contains INI files content filter and checking. 2018-07-17 13:10:08 +02:00
Al12rs 61b33a8351 Added feather and scroll content icon to rappresent ini files. Icon curtesy of WolfHeartAurora. 2018-07-17 13:09:57 +02:00
Al 103e3f3098 Merge pull request #438 from LostDragonist/Develop
Added support for selecting multiple mod for multiple modlist options.
Added check for Windows Event Service before spawning new hooked processes.
2018-07-17 02:08:17 +02:00
Al12rs 872c33fe55 Added new "Hide Uninstalled" and "Delete Uninstalled" options to downloads tab. 2018-07-17 00:49:41 +02:00
Al12rs 9ddb26ea51 Added size label to compact download view. 2018-07-17 00:10:30 +02:00
Al12rs 1867c20f02 Added sortable "Size" column to the downlaods tab. 2018-07-17 00:10:03 +02:00
LostDragonist 6552054e58 Detect if the Windows Event Log service is not running 2018-07-16 15:46:44 -05:00
LostDragonist a830f3e09e Allow "unignore update" to work with multiple mods 2018-07-16 15:46:44 -05:00
LostDragonist eaf3655492 Allow "ignore update" to work with multiple mods 2018-07-16 15:46:44 -05:00
LostDragonist 952f1fe8cd Allow "open in explorer" to work with multiple mods 2018-07-16 15:46:44 -05:00
LostDragonist b4530eb843 Allow "mark as converted" to work with multiple mods 2018-07-16 15:46:43 -05:00
LostDragonist f20a1f6a84 Allow "ignore missing data" to work with multiple mods 2018-07-16 15:46:43 -05:00
LostDragonist 942e656a71 Fix download index in downloadFinished
An index of 0 is valid as this is a bog standard array.  This resolves an instance of the warning "no download index 0".
2018-07-16 15:46:43 -05:00
LostDragonist 7f3dc586b0 Redirect endorsements of MO2 to the Skyrim SE nexus 2018-07-16 15:46:43 -05:00
Al12rs 2524d65441 Added "Open in Folder" option to downloads tab. 2018-07-16 20:56:47 +02:00
Al12rs 5efddbd515 Chnged download speed to be a little more consistant in display, to avoid the progrss bar jumping around all the time. Chnaged the kb->MB jumps to happen at 1000 instead of 1024 to avoid going in the 4 digits, but still divide by 1024 to keep units acuurate. 2018-07-16 14:18:25 +02:00
Silarn 181de232f4 Potential fix for corrupted downloads 2018-06-25 20:50:49 -05:00
Al12rs 1f9103c24e Added the path of the managed game in the settings menu under the path tab, it's read only for now as allowing the user to change it would probably require a lot more work. 2018-06-22 02:47:58 +02:00
Al12rs 2d49ba2bef Add open in explorer button to Overwrite dialog. 2018-06-21 18:54:20 +02:00
Al12rs e41c97b64f Merge branch 'Develop' of https://github.com/Modorganizer2/modorganizer into Develop1 2018-06-20 21:33:27 +02:00
Al12rs b7d6bbb451 Fix for downloads getting stuck after pausing them.
Disabled timer check as it appeared to terminate some downloads early.
2018-06-20 19:33:56 +02:00
Al 4a765cc152 Merge pull request #410 from LostDragonist/Develop
Extend mod backups and load order backups to a maximum of 10
2018-06-20 16:17:29 +02:00
LostDragonist 30f170c10d Extend mod backups and load order backups to a maximum of 10 2018-06-20 08:45:05 -05:00
Al12rs b6aa12b323 Fix for downloads getting insta-completed if there isn't enough bandwidth for them to procede. Now they will instead remain in the download state and continue once the bandwidth is available.
There is much room for improvement here but for now I guess this will avoid MO simply stopping the download.
2018-06-19 23:13:06 +02:00
Al 19d80cc23d Merge pull request #400 from LostDragonist/Develop
Sort by game and fix for instance names
2018-06-10 09:55:41 +02:00
LostDragonist 0c4b1e9a92 Prevent instances from ending in a space
Windows directories are not allowed to end in a space.  Allowing
this creates a broken directory that is difficult for the user
to remove.
2018-06-09 10:44:23 -07:00
Lost Dragonist cacf7e0542 Allow sorting by "source game" column 2018-06-08 22:48:53 -05:00
Silarn f09ec53fcf Updated strings 2018-06-08 18:05:01 -05:00
Al12rs ddb40b712e *Avoided some unnecessary refreshes while removing mods.
*Added "Visit on Nexus" menu entry in the downloads tab.

*Added confirmation message when deleting a single download.

*Changed text of messages to more easily distinguish deleting from hiding.
2018-05-25 15:33:53 +02:00
Al12rs 186f26b71e Added un-hide all option to downlods tab.
Improved performace when hiding/unhiding. There is still room for improvement for hiding but it requires refactoring the function
2018-05-21 01:27:13 +02:00
Al12rs 6d6444c126 Made downlods file sizes human readable instead of just being KB 2018-05-20 23:53:57 +02:00
Al12rs 4b66c6c1ef Added "Open Plugins folder" option to Open folder menu. 2018-05-20 23:02:50 +02:00
Al 08f35d6519 Merge pull request #369 from iaz3/Develop
Fix a memory leak in updateToolBar
2018-05-18 14:02:02 +02:00
Diana 6617be8ef9 Fix a memory leak in updateToolBar
updateToolBar was creating new QActions and QWidgets every call, without cleaning them up.

The spacer, help widgets, and toolbuttons only need to be created once.
Those have been moved out into the MainWindow constructor

updateToolBar is called in various places, importantly when adding/removing executable shortcuts.

Also adds a deleteLater() call to clean up executable shortcut actions.
2018-05-18 07:45:13 -04:00
Al 5a5bfee712 Merge pull request #362 from Al12rs/dirWatcher
Downloads tab: fix for freezes and greatly improved performance and responsiveness
2018-05-17 19:59:06 +02:00
Silarn 2fc55ccc86 Updated strings for downloads 2018-05-16 23:54:50 -05:00
Al12rs 8731159bfb Huge performace improvements for downloads tab by disabling the dirWatcher triggered refreshes.
Avoid app freezes caused by stacked refresh calls.
Added chack to see if a download is alerady hidden before trying to hide it.
Made sure to refresh Download tab where it was othwerwise relying in the dirwatcher to refresh.
2018-05-17 00:03:10 +02:00
Al12rs 1c6543454e Initial work on avoiding the spamming of the Downlods tab refresh caused by the fileSystemWatcher picking up changes made by MO itself and triggering multiple refreshes 2018-05-17 00:02:34 +02:00
Silarn 941c50bff9 Add UA to resume and fix edge case for hung download check 2018-05-16 14:58:43 -05:00
Silarn 1e6e055f39 Add the MO user agent string to the download requests (fixes EU#1) 2018-05-16 11:14:44 -05:00
Jeremy Rimpo 81e329fb39 Merge pull request #361 from AnyOldName3/even-better-version-parsing
Move improved version parsing to util.h and use it everywhere.
2018-05-16 09:32:13 -05:00
AnyOldName3 15db1b76f7 Move improved version parsing to util.h and use it everywhere. 2018-05-16 00:42:31 +01:00
Jeremy Rimpo 75e6c72ae4 Merge pull request #360 from AnyOldName3/better-version-parsing
Better version parsing
2018-05-15 17:55:02 -05:00
AnyOldName3 9c1806cc74 Remove sneaky test qDebug instance. 2018-05-15 23:45:15 +01:00
AnyOldName3 8f905e1d49 Change how the VersionInfo object is created from version.rc such that non-release builds are possible and get labelled as such 2018-05-15 23:43:35 +01:00
Silarn 2ee5f0e96d Push version update for 2.1.4 dev 2018-05-15 12:46:49 -05:00
Silarn 0d220b6b41 Fixes for download errors and retrying with alternate mirrors 2018-05-15 11:13:16 -05:00
Silarn decbbb611e Download resume fixes for restarting MO, hung downloads 2018-05-13 18:32:59 -05:00
Silarn aeb0b42cde Refresh the sort proxy when the data is changed 2018-05-10 11:21:27 -05:00
Silarn 38391b10e9 Fix plugin lock slot typo 2018-05-10 09:21:02 -05:00
Jeremy Rimpo 886fb10288 Merge pull request #343 from Modorganizer2/Develop
Better error message when archives can't be extracted
2018-05-08 19:33:47 -05:00
Silarn 693f3c40ee Better error message when archives can't be extracted 2018-05-08 19:33:25 -05:00
Jeremy Rimpo 26b946a905 Merge pull request #342 from Modorganizer2/Develop
Fix an issue with resuming a completed download
2018-05-08 19:24:02 -05:00
Silarn 11aa955d73 Fix issue with resuming a download that was already complete. 2018-05-08 19:22:07 -05:00
Silarn 2486c554a0 Small compat fix for Qt 5.11 2018-05-08 18:47:45 -05:00
Jeremy Rimpo 5e6bb0a16e Merge pull request #341 from Modorganizer2/Develop
Reset the progress bar data after completing the extraction
2018-05-08 11:35:45 -05:00
Silarn 632474ef97 Reset the progress bar data after completing the extraction 2018-05-08 11:31:05 -05:00
Brian Munro 0da6af17b2 Merge pull request #336 from Modorganizer2/Develop
Release 2.1.3
2018-05-08 12:47:54 +02:00
Silarn 44111d12c1 Remove a pointless error when the game doesn't have a script extender 2018-05-07 17:20:33 -05:00
Silarn 02d3f81829 Changes to allow installer_NCC to use the game source set in the DL meta 2018-05-07 01:29:00 -05:00
Silarn fc74aa90d1 Updating about dialog with additional supporters 2018-05-06 17:31:06 -05:00
Silarn 7d9514d497 Translation updates 2018-05-06 17:22:06 -05:00
Silarn 6359d7d23f Fixes for downloads and installs 2018-05-06 17:21:35 -05:00
Silarn 5f8bbaae2a Make sure project_path is set before trying to use it 2018-05-06 10:18:23 -05:00
Silarn fe33d7af43 Rework the existing file download dialog to pause the download while waiting
- Also fixes direct calls to downloadFinished
2018-05-05 01:28:09 -05:00
Silarn 9ae442810b Make sure to update the index when data is changed 2018-05-04 19:00:55 -05:00
Silarn 9998727dba Vastly improved plugin index generation and sorting 2018-05-04 18:26:57 -05:00
Silarn a76d987647 Update the about dialog 2018-05-04 17:28:58 -05:00
Silarn a29192f9b2 Incorporate uibase translations into organizer 2018-05-04 16:16:32 -05:00
Silarn a77433f881 Use queued connections and do while loops to finish event processing 2018-05-04 14:28:19 -05:00
Silarn 54e2197592 Allow update processor to include the managed game if nexus info matches 2018-05-04 11:35:44 -05:00
Silarn 0d7460996a Further offload setValue to avoid threading issues 2018-05-04 11:34:49 -05:00
Silarn d9b1cfdb4b invokeMethod was getting called too late and is unneeded now 2018-05-04 02:30:10 -05:00
Silarn 98b659f0da Updating gitignore 2018-05-04 00:28:43 -05:00
Silarn 979c09b334 Update translation file 2018-05-04 00:15:48 -05:00
Silarn cf5833437d Bump to version 2.1.3 2018-05-03 19:36:39 -05:00
Silarn 0eaa1c6791 Add version check and update processor 2018-05-03 19:36:14 -05:00
Silarn fa193ddabb Initial icons for alternate games 2018-05-03 18:25:27 -05:00
Silarn cc32c8c06b Use a five second delta to calculate speed for more responsive display 2018-05-03 17:14:05 -05:00
Silarn 9872c1e462 Allow for primary game sources and marking mods as converted/working 2018-05-03 16:17:40 -05:00
Silarn e3989fe8f9 Merge branch 'Develop' of https://github.com/Modorganizer2/modorganizer into Develop 2018-05-02 17:04:50 -05:00
Silarn f7c9b8c333 Thread extraction process and properly offload function calls from threads 2018-05-02 17:04:28 -05:00
Jeremy Rimpo 5555a58f84 Merge pull request #335 from AnyOldName3/proxy-multiple-inheritance-support
Proxy multiple inheritance support
2018-05-02 14:01:50 -05:00
Silarn 6588a81b7f Only check for the mod organizer endorsement if the ID is set 2018-05-02 13:48:31 -05:00
Silarn 2091330af2 Clean up handling of managed game instance in NexusInterface 2018-05-02 13:47:59 -05:00
Silarn 168da18aa5 Fix MO endorsement check and add game to ModInfo s_ModsByModID 2018-05-02 12:38:23 -05:00
AnyOldName3 4245036f52 Remove unused function which made things confusing 2018-05-02 17:12:34 +01:00
AnyOldName3 238c252b4c Coalesce plugins with the same name in the settings dialogue (as they already share setting values) 2018-05-02 17:11:54 +01:00
AnyOldName3 938d3ce91b Take a list of proxied plugins for each name to work around multiple inheritance issues 2018-05-02 17:10:38 +01:00
Silarn d62ec9c867 Allow downloads to display speed and complete % 2018-05-01 21:50:20 -05:00
Silarn 3bb7a44610 Update translation files 2018-05-01 17:02:05 -05:00
Silarn 4bf7b4e103 Update the NMM version 2018-05-01 13:18:39 -05:00
Silarn d3c207193f Add all supported games to the nxmhandler config 2018-05-01 13:01:44 -05:00
Silarn 584c6049f9 Remove redundant code causing multiple installs 2018-05-01 12:37:07 -05:00
Silarn 2b7274380e Release memory 2018-05-01 12:36:47 -05:00
Silarn 275afb730f A couple download header-based fixes
* If an unknown content error, only fail if the filesize is off
* If a text content type, output a warning but do not retry the download
2018-04-30 13:56:27 -05:00
Silarn 0306b0fc42 Change Nexus API URL 2018-04-28 23:32:39 -05:00
Silarn 86c97c7c06 4096 was the correct number 2018-04-27 20:24:20 -05:00
Silarn 3114bcbd8d Fix ESL index display and sorting by index 2018-04-27 20:21:42 -05:00
Silarn 41a479bddf Cache the current game as populating the dropdown triggers the save 2018-04-27 20:00:51 -05:00
Silarn e02614ee14 Add alternative game flag and check 2018-04-27 01:57:59 -05:00
Al12rs cfbe399bba Fixed mod rename to allow just changing letters to uppercase or lowercase.
(Previously it would not allow it as it detected an existing mod having the same name (check is caseInsensitive)).
2018-04-25 23:48:18 +02:00
Silarn 10b8d12152 Update to https for other nexus links For Security 2018-04-24 09:28:08 -07:00
Silarn b3ef185866 Update Nexus protocol to https 2018-04-24 09:22:51 -07:00
Silarn 18328587b5 Merge branch 'Develop' of https://github.com/Modorganizer2/modorganizer into Develop 2018-04-23 22:13:03 -07:00
Silarn 31bf15f3b4 Need to check if the file is in the download directory for creating meta 2018-04-23 22:12:46 -07:00
Al12rs 001fddb069 Changed the shortcut to open in explorer a mod to CTRL+Enter to avoid consuming the Enter key press so that people can still use it to finish renaming a mod. 2018-04-22 16:39:26 +02:00
Silarn 141ac311d2 Don't create meta files if they don't exist 2018-04-21 22:32:17 -05:00
Silarn fbb93eaf86 Remove remnants of QtScript and fix some CMake issues 2018-04-19 01:43:57 -05:00
Silarn 7e04542762 Some tweaks to make MO the top window when loading or changing games 2018-04-18 11:46:42 -05:00
Silarn 08b56ee783 Improve and fix handling of external links 2018-04-18 03:41:53 -05:00
Silarn 85faed5de1 Fix issues with download query 2018-04-17 19:14:17 -05:00
Al12rs 189445191d Added Delete shourcut to both modinfodialog and Overwriteinfodilaog. Added confirm messages since delete can't be undone. 2018-04-18 00:08:05 +02:00
Al 618fd543a6 Merge pull request #315 from Al12rs/Develop
Ui and shortcut changes.
2018-04-17 22:43:24 +02:00
Al12rs f276203517 Changed mod Information dialog "Next" and "Previous" buttons to remember the currently viewed tab. 2018-04-17 21:51:22 +02:00
Al12rs b64fd1ed4d Enter shourcut will now open the mod containing the selected plugin if the ESPList has the focus.
Added F5 shourcut to refresh the profile.
Removed a redundant variable I saw by chance.
2018-04-17 21:51:01 +02:00
Al12rs b1329c18cd Added Enter shortcut support for ovewrite as well to open the Explorer window. 2018-04-17 21:50:41 +02:00
Al12rs 62dc387de6 Added key shourtcuts to open in explorer a selected mo by pressing Enter or Return. Needs support for overwrte 2018-04-17 21:50:12 +02:00
Al12rs fc46a6a782 Disabled Hide inactive plugins checkbox in settings as it didn't work. 2018-04-17 21:49:34 +02:00
Al12rs a2d7ce67aa Merged the new open in explorer button with Silarn's code. 2018-04-17 21:49:15 +02:00
Al12rs a14ed8fcd1 Changed the modifodialog to open the first enabled left most tab, if no particular tab was specified by the function caller.
This will allow the users to choose what tab should be opened when opening the mod informations since the order of the tabs can be changed and is saved.
2018-04-17 21:23:40 +02:00
Al12rs c669fed48a Fixed inconsistency in line endings. 2018-04-17 21:22:46 +02:00
Silarn 634825e1b8 Adjust mod info dialog, add tooltips, update old 2018-04-17 03:04:59 -05:00
Silarn 7688175c68 Add source game setter in mod info dialog 2018-04-17 02:47:07 -05:00
Silarn b4eae6e5d1 Fix signal/slot connector for available server parser 2018-04-17 00:33:15 -05:00
Silarn b1c477f8ec Fix for virtualized executable path 2018-04-16 15:31:45 -05:00
Jeremy Rimpo 8b3a83ed8d Merge pull request #311 from AnyOldName3/load-qtbase-qm
Load qtbase qm
2018-04-16 14:18:04 -05:00
Silarn 332cdc155a Merge branch 'Develop' of https://github.com/Modorganizer2/modorganizer into Develop 2018-04-16 12:48:52 -05:00
Silarn 30c177cb37 Support for multi-game downloads 2018-04-16 12:47:17 -05:00
AnyOldName3 ae4e4f9df8 Load qtbase_<language>.qm when possible 2018-04-15 12:59:04 +01:00
AnyOldName3 dd24b60895 Update .gitignore with missing msbuild stuff. 2018-04-15 12:58:27 +01:00
Al12rs fa104b342f Moved the Changelog to the detailed text to avoid the msgbox going below the scree. The readability is not graeat as QMessageBox does not allow resizing for some petty reason. 2018-04-15 02:54:58 +02:00
Al12rs cc2c4cc918 Fix for programs set to start from inside the top level of a mod folder not launching. 2018-04-15 02:54:47 +02:00
Jeremy Rimpo 978d71bb43 Merge pull request #304 from AnyOldName3/proxy-translation-support
Proxy translation support
2018-04-13 12:42:54 -05:00
AnyOldName3 25b6fe1471 Reload plugin translation databases when changing language. 2018-04-13 14:49:59 +01:00
AnyOldName3 6b5680f6e4 Make pluginFileNames() include those of proxied plugins, too. 2018-04-13 14:46:04 +01:00
78 changed files with 9581 additions and 1094 deletions
+4 -7
View File
@@ -2,17 +2,14 @@
Thumbs.db
src/moc_*.cpp
src/ui_*.h
src/organizer_en.ts
src/*.qrc.depends
src/Modorganizer.*
src/*.bak
CMakeLists.txt.user
edit
stderr.log
stdout.log
vs_stderr.log
vs_stdout.log
build
/vsbuild
/CMakeFiles
.idea
/msbuild.log
/*std*.log
/*build
+25 -17
View File
@@ -30,6 +30,7 @@ SET(organizer_SRCS
motddialog.cpp
modlistsortproxy.cpp
modlist.cpp
modidlineedit.cpp
modinfodialog.cpp
modinfo.cpp
modinfobackup.cpp
@@ -120,6 +121,7 @@ SET(organizer_HDRS
motddialog.h
modlistsortproxy.h
modlist.h
modidlineedit.h
modinfodialog.h
modinfo.h
modinfobackup.h
@@ -238,6 +240,13 @@ SOURCE_GROUP(Source FILES ${organizer_SRCS})
SOURCE_GROUP(Headers FILES ${organizer_HDRS})
SOURCE_GROUP(UI FILES ${organizer_UIS})
# MO projects
SET(default_project_path "${CMAKE_SOURCE_DIR}/..")
GET_FILENAME_COMPONENT(${default_project_path} ${default_project_path} REALPATH)
SET(project_path "${default_project_path}" CACHE PATH "path to the other mo projects")
#TODO this should not be a hardcoded path
SET(lib_path "${project_path}/../../install/libs")
# Qt5
SET(CMAKE_INCLUDE_CURRENT_DIR ON)
@@ -249,12 +258,12 @@ FIND_PACKAGE(Qt5Quick REQUIRED)
FIND_PACKAGE(Qt5Network REQUIRED)
FIND_PACKAGE(Qt5WinExtras REQUIRED)
FIND_PACKAGE(Qt5WebEngineWidgets REQUIRED)
FIND_PACKAGE(Qt5Script REQUIRED)
FIND_PACKAGE(Qt5Qml REQUIRED)
FIND_PACKAGE(Qt5LinguistTools)
QT5_WRAP_UI(organizer_UIHDRS ${organizer_UIS})
QT5_ADD_RESOURCES(organizer_RCCPPS ${organizer_QRCS})
QT5_CREATE_TRANSLATION(organizer_translations_qm ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/src/organizer_en.ts)
SET(mo_translation_sources ${CMAKE_SOURCE_DIR}/src ${project_path}/uibase/src)
QT5_CREATE_TRANSLATION(organizer_translations_qm ${mo_translation_sources} ${CMAKE_SOURCE_DIR}/src/organizer_en.ts)
ADD_CUSTOM_TARGET(translations DEPENDS ${organizer_translations_qm})
INCLUDE_DIRECTORIES(${Qt5Declarative_INCLUDES})
@@ -274,16 +283,6 @@ LINK_DIRECTORIES(${Boost_LIBRARY_DIRS})
FIND_PACKAGE(zlib REQUIRED)
# TODO FindZlib doesn't find the static zlib library
# MO projects
SET(default_project_path "${CMAKE_SOURCE_DIR}/..")
GET_FILENAME_COMPONENT(${default_project_path} ${default_project_path} REALPATH)
SET(project_path "${default_project_path}" CACHE PATH "path to the other mo projects")
#TODO this should not be a hardcoded path
SET(lib_path "${project_path}/../../install/libs")
INCLUDE_DIRECTORIES(${project_path}/uibase/src
${project_path}/bsatk/src
${project_path}/esptk/src
@@ -316,18 +315,27 @@ ENDIF()
ADD_EXECUTABLE(ModOrganizer WIN32 ${organizer_HDRS} ${organizer_SRCS} ${organizer_UIHDRS} ${organizer_RCS} ${organizer_RCCPPS} ${organizer_translations_qm})
TARGET_LINK_LIBRARIES(ModOrganizer
Qt5::Widgets Qt5::WinExtras Qt5::WebEngineWidgets Qt5::Quick
Qt5::Script Qt5::Qml Qt5::QuickWidgets Qt5::Network
Qt5::Qml Qt5::QuickWidgets Qt5::Network
${Boost_LIBRARIES}
zlibstatic
uibase esptk bsatk githubpp
${usvfs_name}
Dbghelp advapi32 Version Shlwapi liblz4)
IF (MSVC)
SET_TARGET_PROPERTIES(ModOrganizer PROPERTIES COMPILE_FLAGS "/std:c++latest")
ENDIF()
IF (MSVC AND "${CMAKE_SIZEOF_VOID_P}" EQUAL 4)
# 32 bits
SET_TARGET_PROPERTIES(ModOrganizer PROPERTIES LINK_FLAGS "/LARGEADDRESSAWARE")
ENDIF()
IF (NOT "${OPTIMIZE_COMPILE_FLAGS}" STREQUAL "")
SET_TARGET_PROPERTIES(ModOrganizer PROPERTIES COMPILE_FLAGS_RELWITHDEBINFO
${OPTIMIZE_COMPILE_FLAGS})
SET_TARGET_PROPERTIES(ModOrganizer PROPERTIES COMPILE_FLAGS_RELWITHDEBINFO ${OPTIMIZE_COMPILE_FLAGS})
ENDIF()
IF (NOT "${OPTIMIZE_LINK_FLAGS}" STREQUAL "")
SET_TARGET_PROPERTIES(ModOrganizer PROPERTIES LINK_FLAGS_RELWITHDEBINFO ${OPTIMIZE_LINK_FLAGS})
ENDIF()
SET_TARGET_PROPERTIES(ModOrganizer PROPERTIES LINK_FLAGS_RELWITHDEBINFO
"/LARGEADDRESSAWARE ${OPTIMIZE_LINK_FLAGS}")
###############
+5
View File
@@ -114,3 +114,8 @@ void AboutDialog::on_creditsList_currentItemChanged(QListWidgetItem *current, QL
ui->licenseText->setText(tr("No license"));
}
}
void AboutDialog::on_copyrightText_linkActivated(const QString &link)
{
emit linkClicked(link);
}
+5
View File
@@ -40,6 +40,10 @@ public:
explicit AboutDialog(const QString &version, QWidget *parent = 0);
~AboutDialog();
signals:
void linkClicked(QString link);
private:
enum Licenses {
@@ -70,6 +74,7 @@ private:
private slots:
void on_creditsList_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous);
void on_copyrightText_linkActivated(const QString &link);
private:
+39 -13
View File
@@ -125,7 +125,7 @@
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<widget class="QLabel" name="copyrightText">
<property name="text">
<string notr="true">&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.&lt;/p&gt;&lt;p&gt;See the GNU General Public License for more details.&lt;/p&gt;&lt;p&gt;Source code can be found at &lt;a href=&quot;https://github.com/Modorganizer2/modorganizer&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#007af4;&quot;&gt;GitHub&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
@@ -153,8 +153,8 @@
<attribute name="title">
<string>Thanks</string>
</attribute>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<layout class="QGridLayout" name="gridLayout_0">
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Current Maintainers</string>
@@ -167,12 +167,12 @@
</property>
<item>
<property name="text">
<string notr="true">LePresidente (Project Lead)</string>
<string>LePresidente (Project Lead)</string>
</property>
</item>
<item>
<property name="text">
<string>AL12</string>
<string notr="true">AL12</string>
</property>
</item>
<item>
@@ -195,8 +195,29 @@
</layout>
</widget>
</item>
<item>
<item row="1" column="0">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Major Contributors</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_7" stretch="0">
<item>
<widget class="QListWidget" name="listWidget_2">
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
</property>
<item>
<property name="text">
<string notr="true">AnyOldName3 (Python Plugins)</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="1" rowspan="2">
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Translators</string>
</property>
@@ -317,8 +338,8 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_3">
<item row="0" column="2" rowspan="2">
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>Other Supporters &amp;&amp; Contributors</string>
</property>
@@ -328,11 +349,6 @@
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
</property>
<item>
<property name="text">
<string notr="true">AnyOldName3</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">blacksol</string>
@@ -368,6 +384,11 @@
<string notr="true">Gopher</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">GrantSP</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">GSDFan</string>
@@ -378,6 +399,11 @@
<string notr="true">ogrotten</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">outdatedtv</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">Schilduin</string>
+2 -2
View File
@@ -173,13 +173,13 @@ void BrowserDialog::titleChanged(const QString &title)
QString BrowserDialog::guessFileName(const QString &url)
{
QRegExp uploadsExp(QString("http://.+/uploads/([^/]+)$"));
QRegExp uploadsExp(QString("https://.+/uploads/([^/]+)$"));
if (uploadsExp.indexIn(url) != -1) {
// these seem to be premium downloads
return uploadsExp.cap(1);
}
QRegExp filesExp(QString("http://.+\\?file=([^&]+)"));
QRegExp filesExp(QString("https://.+\\?file=([^&]+)"));
if (filesExp.indexIn(url) != -1) {
// a regular manual download?
return filesExp.cap(1);
+2 -1
View File
@@ -40,7 +40,7 @@ int DownloadList::rowCount(const QModelIndex&) const
int DownloadList::columnCount(const QModelIndex&) const
{
return 3;
return 4;
}
@@ -63,6 +63,7 @@ QVariant DownloadList::headerData(int section, Qt::Orientation orientation, int
switch (section) {
case COL_NAME: return tr("Name");
case COL_FILETIME: return tr("Filetime");
case COL_SIZE: return tr("Size");
default: return tr("Done");
}
} else {
+2 -1
View File
@@ -39,7 +39,8 @@ public:
enum EColumn {
COL_NAME = 0,
COL_FILETIME,
COL_STATUS
COL_STATUS,
COL_SIZE
};
public:
+2
View File
@@ -47,6 +47,8 @@ bool DownloadListSortProxy::lessThan(const QModelIndex &left,
return m_Manager->getFileTime(leftIndex) < m_Manager->getFileTime(rightIndex);
} else if (left.column() == DownloadList::COL_STATUS) {
return m_Manager->getState(leftIndex) < m_Manager->getState(rightIndex);
} else if(left.column() == DownloadList::COL_SIZE){
return m_Manager->getFileSize(leftIndex) < m_Manager->getFileSize(rightIndex);
} else {
return leftIndex < rightIndex;
}
+94 -19
View File
@@ -53,6 +53,7 @@ DownloadListWidgetDelegate::DownloadListWidgetDelegate(DownloadManager *manager,
m_InstallLabel = m_ItemWidget->findChild<QLabel*>("installLabel");
m_InstallLabel->setVisible(false);
m_Progress->setTextVisible(true);
connect(manager, SIGNAL(stateChanged(int,DownloadManager::DownloadState)), this, SLOT(stateChanged(int,DownloadManager::DownloadState)));
connect(manager, SIGNAL(downloadRemoved(int)), this, SLOT(resetCache(int)));
@@ -81,15 +82,34 @@ void DownloadListWidgetDelegate::drawCache(QPainter *painter, const QStyleOption
{
QRect rect = option.rect;
rect.setLeft(0);
rect.setWidth(m_View->columnWidth(0) + m_View->columnWidth(1) + m_View->columnWidth(2));
rect.setWidth(m_View->columnWidth(0) + m_View->columnWidth(1) + m_View->columnWidth(2) + m_View->columnWidth(3));
painter->drawPixmap(rect, cache);
}
QString DownloadListWidgetDelegate::sizeFormat(quint64 size) const
{
qreal calc = size;
QStringList list;
list << "KB" << "MB" << "GB" << "TB";
QStringListIterator i(list);
QString unit("byte(s)");
while (calc >= 1024.0 && i.hasNext())
{
unit = i.next();
calc /= 1024.0;
}
return QString().setNum(calc, 'f', 2) + " " + unit;
}
void DownloadListWidgetDelegate::paintPendingDownload(int downloadIndex) const
{
std::pair<int, int> nexusids = m_Manager->getPendingDownload(downloadIndex);
m_NameLabel->setText(tr("< mod %1 file %2 >").arg(nexusids.first).arg(nexusids.second));
std::tuple<QString, int, int> nexusids = m_Manager->getPendingDownload(downloadIndex);
m_NameLabel->setText(tr("< game %1 mod %2 file %3 >").arg(std::get<0>(nexusids)).arg(std::get<1>(nexusids)).arg(std::get<2>(nexusids)));
m_SizeLabel->setText("???");
m_InstallLabel->setVisible(true);
m_InstallLabel->setText(tr("Pending"));
@@ -105,9 +125,9 @@ void DownloadListWidgetDelegate::paintRegularDownload(int downloadIndex) const
name.append("...");
}
m_NameLabel->setText(name);
m_SizeLabel->setText(QString::number(m_Manager->getFileSize(downloadIndex) / 1024));
m_SizeLabel->setText(sizeFormat(m_Manager->getFileSize(downloadIndex) ));
DownloadManager::DownloadState state = m_Manager->getState(downloadIndex);
if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR)) {
if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR) || (state == DownloadManager::STATE_PAUSING)) {
QPalette labelPalette;
m_InstallLabel->setVisible(true);
m_Progress->setVisible(false);
@@ -159,7 +179,8 @@ void DownloadListWidgetDelegate::paintRegularDownload(int downloadIndex) const
} else {
m_InstallLabel->setVisible(false);
m_Progress->setVisible(true);
m_Progress->setValue(m_Manager->getProgress(downloadIndex));
m_Progress->setValue(m_Manager->getProgress(downloadIndex).first);
m_Progress->setFormat(m_Manager->getProgress(downloadIndex).second);
}
}
@@ -172,7 +193,7 @@ void DownloadListWidgetDelegate::paint(QPainter *painter, const QStyleOptionView
return;
}
m_ItemWidget->resize(QSize(m_View->columnWidth(0) + m_View->columnWidth(1) + m_View->columnWidth(2), option.rect.height()));
m_ItemWidget->resize(QSize(m_View->columnWidth(0) + m_View->columnWidth(1) + m_View->columnWidth(2) + m_View->columnWidth(3), option.rect.height()));
int downloadIndex = index.data().toInt();
@@ -224,7 +245,11 @@ void DownloadListWidgetDelegate::issueQueryInfo()
void DownloadListWidgetDelegate::issueDelete()
{
emit removeDownload(m_ContextRow, true);
if (QMessageBox::question(nullptr, tr("Delete Files?"),
tr("This will permanently delete the selected download."),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
emit removeDownload(m_ContextRow, true);
}
}
void DownloadListWidgetDelegate::issueRemoveFromView()
@@ -234,7 +259,22 @@ void DownloadListWidgetDelegate::issueRemoveFromView()
void DownloadListWidgetDelegate::issueRestoreToView()
{
emit restoreDownload(m_ContextRow);
emit restoreDownload(m_ContextRow);
}
void DownloadListWidgetDelegate::issueRestoreToViewAll()
{
emit restoreDownload(-1);
}
void DownloadListWidgetDelegate::issueVisitOnNexus()
{
emit visitOnNexus(m_ContextRow);
}
void DownloadListWidgetDelegate::issueOpenInDownloadsFolder()
{
emit openInDownloadsFolder(m_ContextRow);
}
void DownloadListWidgetDelegate::issueCancel()
@@ -254,7 +294,7 @@ void DownloadListWidgetDelegate::issueResume()
void DownloadListWidgetDelegate::issueDeleteAll()
{
if (QMessageBox::question(nullptr, tr("Are you sure?"),
if (QMessageBox::question(nullptr, tr("Delete Files?"),
tr("This will remove all finished downloads from this list and from disk."),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
emit removeDownload(-1, true);
@@ -263,13 +303,22 @@ void DownloadListWidgetDelegate::issueDeleteAll()
void DownloadListWidgetDelegate::issueDeleteCompleted()
{
if (QMessageBox::question(nullptr, tr("Are you sure?"),
if (QMessageBox::question(nullptr, tr("Delete Files?"),
tr("This will remove all installed downloads from this list and from disk."),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
emit removeDownload(-2, true);
}
}
void DownloadListWidgetDelegate::issueDeleteUninstalled()
{
if (QMessageBox::question(nullptr, tr("Delete Files?"),
tr("This will remove all uninstalled downloads from this list and from disk."),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
emit removeDownload(-3, true);
}
}
void DownloadListWidgetDelegate::issueRemoveFromViewAll()
{
if (QMessageBox::question(nullptr, tr("Are you sure?"),
@@ -288,6 +337,15 @@ void DownloadListWidgetDelegate::issueRemoveFromViewCompleted()
}
}
void DownloadListWidgetDelegate::issueRemoveFromViewUninstalled()
{
if (QMessageBox::question(nullptr, tr("Are you sure?"),
tr("This will remove all uninstalled downloads from this list (but NOT from disk)."),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
emit removeDownload(-3, false);
}
}
bool DownloadListWidgetDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
const QStyleOptionViewItem &option, const QModelIndex &index)
{
@@ -296,7 +354,7 @@ bool DownloadListWidgetDelegate::editorEvent(QEvent *event, QAbstractItemModel *
QModelIndex sourceIndex = qobject_cast<QSortFilterProxyModel*>(model)->mapToSource(index);
if (m_Manager->getState(sourceIndex.row()) >= DownloadManager::STATE_READY) {
emit installDownload(sourceIndex.row());
} else if (m_Manager->getState(sourceIndex.row()) >= DownloadManager::STATE_PAUSED) {
} else if ((m_Manager->getState(sourceIndex.row()) >= DownloadManager::STATE_PAUSED) || (m_Manager->getState(sourceIndex.row()) == DownloadManager::STATE_PAUSING)) {
emit resumeDownload(sourceIndex.row());
}
return true;
@@ -313,7 +371,14 @@ bool DownloadListWidgetDelegate::editorEvent(QEvent *event, QAbstractItemModel *
menu.addAction(tr("Install"), this, SLOT(issueInstall()));
if (m_Manager->isInfoIncomplete(m_ContextRow)) {
menu.addAction(tr("Query Info"), this, SLOT(issueQueryInfo()));
}else {
menu.addAction(tr("Visit on Nexus"), this,SLOT(issueVisitOnNexus()));
}
menu.addAction(tr("Show in Folder"), this, SLOT(issueOpenInDownloadsFolder()));
menu.addSeparator();
menu.addAction(tr("Delete"), this, SLOT(issueDelete()));
if (hidden) {
menu.addAction(tr("Un-Hide"), this, SLOT(issueRestoreToView()));
@@ -323,20 +388,30 @@ bool DownloadListWidgetDelegate::editorEvent(QEvent *event, QAbstractItemModel *
} else if (state == DownloadManager::STATE_DOWNLOADING){
menu.addAction(tr("Cancel"), this, SLOT(issueCancel()));
menu.addAction(tr("Pause"), this, SLOT(issuePause()));
} else if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR)) {
menu.addAction(tr("Remove"), this, SLOT(issueDelete()));
menu.addAction(tr("Show in Folder"), this, SLOT(issueOpenInDownloadsFolder()));
} else if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR) || (state == DownloadManager::STATE_PAUSING)) {
menu.addAction(tr("Delete"), this, SLOT(issueDelete()));
menu.addAction(tr("Resume"), this, SLOT(issueResume()));
menu.addAction(tr("Show in Folder"), this, SLOT(issueOpenInDownloadsFolder()));
}
menu.addSeparator();
}
menu.addAction(tr("Delete Installed..."), this, SLOT(issueDeleteCompleted()));
menu.addAction(tr("Delete Uninstalled..."), this, SLOT(issueDeleteUninstalled()));
menu.addAction(tr("Delete All..."), this, SLOT(issueDeleteAll()));
if (!hidden) {
menu.addSeparator();
menu.addAction(tr("Hide Installed..."), this, SLOT(issueRemoveFromViewCompleted()));
menu.addAction(tr("Hide All..."), this, SLOT(issueRemoveFromViewAll()));
}
if (!hidden) {
menu.addSeparator();
menu.addAction(tr("Hide Installed..."), this, SLOT(issueRemoveFromViewCompleted()));
menu.addAction(tr("Hide Uninstalled..."), this, SLOT(issueRemoveFromViewUninstalled()));
menu.addAction(tr("Hide All..."), this, SLOT(issueRemoveFromViewAll()));
}
if (hidden) {
menu.addSeparator();
menu.addAction(tr("Un-Hide All..."), this, SLOT(issueRestoreToViewAll()));
}
menu.exec(mouseEvent->globalPos());
event->accept();
+9
View File
@@ -71,14 +71,18 @@ signals:
void cancelDownload(int index);
void pauseDownload(int index);
void resumeDownload(int index);
void visitOnNexus(int index);
void openInDownloadsFolder(int index);
protected:
QString sizeFormat(quint64 size) const;
bool editorEvent(QEvent *event, QAbstractItemModel *model,
const QStyleOptionViewItem &option, const QModelIndex &index);
private:
void drawCache(QPainter *painter, const QStyleOptionViewItem &option, const QPixmap &cache) const;
private slots:
@@ -87,13 +91,18 @@ private slots:
void issueDelete();
void issueRemoveFromView();
void issueRestoreToView();
void issueRestoreToViewAll();
void issueVisitOnNexus();
void issueOpenInDownloadsFolder();
void issueCancel();
void issuePause();
void issueResume();
void issueDeleteAll();
void issueDeleteCompleted();
void issueDeleteUninstalled();
void issueRemoveFromViewAll();
void issueRemoveFromViewCompleted();
void issueRemoveFromViewUninstalled();
void issueQueryInfo();
void stateChanged(int row, DownloadManager::DownloadState);
+3
View File
@@ -86,6 +86,9 @@
<widget class="QLabel" name="label_2">
<property name="text">
<string notr="true">KB</string>
</property>
<property name="visible">
<bool>false</bool>
</property>
</widget>
</item>
+87 -17
View File
@@ -81,18 +81,35 @@ void DownloadListWidgetCompactDelegate::drawCache(QPainter *painter, const QStyl
{
QRect rect = option.rect;
rect.setLeft(0);
rect.setWidth(m_View->columnWidth(0) + m_View->columnWidth(1) + m_View->columnWidth(2));
rect.setWidth(m_View->columnWidth(0) + m_View->columnWidth(1) + m_View->columnWidth(2) + m_View->columnWidth(3));
painter->drawPixmap(rect, cache);
}
QString DownloadListWidgetCompactDelegate::sizeFormat(quint64 size) const
{
qreal calc = size;
QStringList list;
list << "KB" << "MB" << "GB" << "TB";
QStringListIterator i(list);
QString unit("byte(s)");
while (calc >= 1024.0 && i.hasNext())
{
unit = i.next();
calc /= 1024.0;
}
return QString().setNum(calc, 'f', 2) + " " + unit;
}
void DownloadListWidgetCompactDelegate::paintPendingDownload(int downloadIndex) const
{
std::pair<int, int> nexusids = m_Manager->getPendingDownload(downloadIndex);
m_NameLabel->setText(tr("< mod %1 file %2 >").arg(nexusids.first).arg(nexusids.second));
if (m_SizeLabel != nullptr) {
m_SizeLabel->setText("???");
}
std::tuple<QString, int, int> nexusids = m_Manager->getPendingDownload(downloadIndex);
m_NameLabel->setText(tr("< game %1 mod %2 file %3 >").arg(std::get<0>(nexusids)).arg(std::get<1>(nexusids)).arg(std::get<2>(nexusids)));
//if (m_SizeLabel != nullptr) {
// m_SizeLabel->setText("???");
//}
m_DoneLabel->setVisible(true);
m_DoneLabel->setText(tr("Pending"));
m_Progress->setVisible(false);
@@ -110,11 +127,15 @@ void DownloadListWidgetCompactDelegate::paintRegularDownload(int downloadIndex)
DownloadManager::DownloadState state = m_Manager->getState(downloadIndex);
if ((m_SizeLabel != nullptr) && (state >= DownloadManager::STATE_READY)) {
m_SizeLabel->setText(QString::number(m_Manager->getFileSize(downloadIndex) / 1048576));
if (m_SizeLabel != nullptr) {
m_SizeLabel->setText(sizeFormat(m_Manager->getFileSize(downloadIndex)) + " ");
m_SizeLabel->setVisible(true);
}
//else {
// m_SizeLabel->setVisible(false);
//}
if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR)) {
if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR) || (state == DownloadManager::STATE_PAUSING)) {
m_DoneLabel->setVisible(true);
m_Progress->setVisible(false);
m_DoneLabel->setText(QString("%1<img src=\":/MO/gui/inactive\">").arg(tr("Paused")));
@@ -138,7 +159,8 @@ void DownloadListWidgetCompactDelegate::paintRegularDownload(int downloadIndex)
} else {
m_DoneLabel->setVisible(false);
m_Progress->setVisible(true);
m_Progress->setValue(m_Manager->getProgress(downloadIndex));
m_Progress->setValue(m_Manager->getProgress(downloadIndex).first);
m_Progress->setFormat(m_Manager->getProgress(downloadIndex).second);
}
}
@@ -152,7 +174,7 @@ void DownloadListWidgetCompactDelegate::paint(QPainter *painter, const QStyleOpt
return;
}
m_ItemWidget->resize(QSize(m_View->columnWidth(0) + m_View->columnWidth(1) + m_View->columnWidth(2), option.rect.height()));
m_ItemWidget->resize(QSize(m_View->columnWidth(0) + m_View->columnWidth(1) + m_View->columnWidth(2) + m_View->columnWidth(3), option.rect.height()));
if (index.row() % 2 == 1) {
m_ItemWidget->setBackgroundRole(QPalette::AlternateBase);
} else {
@@ -208,7 +230,11 @@ void DownloadListWidgetCompactDelegate::issueQueryInfo()
void DownloadListWidgetCompactDelegate::issueDelete()
{
emit removeDownload(m_ContextIndex.row(), true);
if (QMessageBox::question(nullptr, tr("Are you sure?"),
tr("This will permanently delete the selected download."),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
emit removeDownload(m_ContextIndex.row(), true);
}
}
void DownloadListWidgetCompactDelegate::issueRemoveFromView()
@@ -216,11 +242,27 @@ void DownloadListWidgetCompactDelegate::issueRemoveFromView()
emit removeDownload(m_ContextIndex.row(), false);
}
void DownloadListWidgetCompactDelegate::issueVisitOnNexus()
{
emit visitOnNexus(m_ContextIndex.row());
}
void DownloadListWidgetCompactDelegate::issueOpenInDownloadsFolder()
{
emit openInDownloadsFolder(m_ContextIndex.row());
}
void DownloadListWidgetCompactDelegate::issueRestoreToView()
{
emit restoreDownload(m_ContextIndex.row());
emit restoreDownload(m_ContextIndex.row());
}
void DownloadListWidgetCompactDelegate::issueRestoreToViewAll()
{
emit restoreDownload(-1);
}
void DownloadListWidgetCompactDelegate::issueCancel()
{
emit cancelDownload(m_ContextIndex.row());
@@ -254,6 +296,15 @@ void DownloadListWidgetCompactDelegate::issueDeleteCompleted()
}
}
void DownloadListWidgetCompactDelegate::issueDeleteUninstalled()
{
if (QMessageBox::question(nullptr, tr("Are you sure?"),
tr("This will remove all uninstalled downloads from this list and from disk."),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
emit removeDownload(-3, true);
}
}
void DownloadListWidgetCompactDelegate::issueRemoveFromViewAll()
{
if (QMessageBox::question(nullptr, tr("Are you sure?"),
@@ -272,6 +323,15 @@ void DownloadListWidgetCompactDelegate::issueRemoveFromViewCompleted()
}
}
void DownloadListWidgetCompactDelegate::issueRemoveFromViewUninstalled()
{
if (QMessageBox::question(nullptr, tr("Are you sure?"),
tr("This will permanently remove all uninstalled downloads from this list (but NOT from disk)."),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
emit removeDownload(-3, false);
}
}
bool DownloadListWidgetCompactDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
const QStyleOptionViewItem &option, const QModelIndex &index)
@@ -281,7 +341,7 @@ bool DownloadListWidgetCompactDelegate::editorEvent(QEvent *event, QAbstractItem
QModelIndex sourceIndex = qobject_cast<QSortFilterProxyModel*>(model)->mapToSource(index);
if (m_Manager->getState(sourceIndex.row()) >= DownloadManager::STATE_READY) {
emit installDownload(sourceIndex.row());
} else if (m_Manager->getState(sourceIndex.row()) >= DownloadManager::STATE_PAUSED) {
} else if ((m_Manager->getState(sourceIndex.row()) >= DownloadManager::STATE_PAUSED) || (m_Manager->getState(sourceIndex.row()) == DownloadManager::STATE_PAUSING)) {
emit resumeDownload(sourceIndex.row());
}
return true;
@@ -298,7 +358,11 @@ bool DownloadListWidgetCompactDelegate::editorEvent(QEvent *event, QAbstractItem
menu.addAction(tr("Install"), this, SLOT(issueInstall()));
if (m_Manager->isInfoIncomplete(m_ContextIndex.row())) {
menu.addAction(tr("Query Info"), this, SLOT(issueQueryInfo()));
}else {
menu.addAction(tr("Visit on Nexus"), this, SLOT(issueVisitOnNexus()));
}
menu.addAction(tr("Show in Folder"), this, SLOT(issueOpenInDownloadsFolder()));
menu.addSeparator();
menu.addAction(tr("Delete"), this, SLOT(issueDelete()));
if (hidden) {
menu.addAction(tr("Un-Hide"), this, SLOT(issueRestoreToView()));
@@ -308,20 +372,27 @@ bool DownloadListWidgetCompactDelegate::editorEvent(QEvent *event, QAbstractItem
} else if (state == DownloadManager::STATE_DOWNLOADING){
menu.addAction(tr("Cancel"), this, SLOT(issueCancel()));
menu.addAction(tr("Pause"), this, SLOT(issuePause()));
} else if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR)) {
menu.addAction(tr("Show in Folder"), this, SLOT(issueOpenInDownloadsFolder()));
} else if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR) || (state == DownloadManager::STATE_PAUSING)) {
menu.addAction(tr("Remove"), this, SLOT(issueDelete()));
menu.addAction(tr("Resume"), this, SLOT(issueResume()));
menu.addAction(tr("Show in Folder"), this, SLOT(issueOpenInDownloadsFolder()));
}
menu.addSeparator();
}
menu.addAction(tr("Delete Installed..."), this, SLOT(issueDeleteCompleted()));
menu.addAction(tr("Delete Uninstalled..."), this, SLOT(issueDeleteUninstalled()));
menu.addAction(tr("Delete All..."), this, SLOT(issueDeleteAll()));
if (!hidden) {
menu.addSeparator();
menu.addAction(tr("Hide Installed..."), this, SLOT(issueRemoveFromViewCompleted()));
menu.addAction(tr("Hide Uninstalled..."), this, SLOT(issueRemoveFromViewUninstalled()));
menu.addAction(tr("Hide All..."), this, SLOT(issueRemoveFromViewAll()));
}
if (hidden) {
menu.addSeparator();
menu.addAction(tr("Un-Hide All..."), this, SLOT(issueRestoreToViewAll()));
}
menu.exec(mouseEvent->globalPos());
event->accept();
@@ -334,4 +405,3 @@ bool DownloadListWidgetCompactDelegate::editorEvent(QEvent *event, QAbstractItem
return QItemDelegate::editorEvent(event, model, option, index);
}
+9 -2
View File
@@ -35,7 +35,7 @@ class DownloadListWidgetCompact;
class DownloadListWidgetCompact : public QWidget
{
Q_OBJECT
public:
explicit DownloadListWidgetCompact(QWidget *parent = 0);
~DownloadListWidgetCompact();
@@ -69,9 +69,12 @@ signals:
void cancelDownload(int index);
void pauseDownload(int index);
void resumeDownload(int index);
void visitOnNexus(int index);
void openInDownloadsFolder(int index);
protected:
QString sizeFormat(quint64 size) const;
bool editorEvent(QEvent *event, QAbstractItemModel *model,
const QStyleOptionViewItem &option, const QModelIndex &index);
@@ -87,13 +90,18 @@ private slots:
void issueDelete();
void issueRemoveFromView();
void issueRestoreToView();
void issueRestoreToViewAll();
void issueVisitOnNexus();
void issueOpenInDownloadsFolder();
void issueCancel();
void issuePause();
void issueResume();
void issueDeleteAll();
void issueDeleteCompleted();
void issueDeleteUninstalled();
void issueRemoveFromViewAll();
void issueRemoveFromViewCompleted();
void issueRemoveFromViewUninstalled();
void issueQueryInfo();
void stateChanged(int row, DownloadManager::DownloadState);
@@ -119,4 +127,3 @@ private:
};
#endif // DOWNLOADLISTWIDGETCOMPACT_H
+10 -3
View File
@@ -19,7 +19,7 @@
<property name="autoFillBackground">
<bool>true</bool>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,0,0,0">
<property name="spacing">
<number>2</number>
</property>
@@ -58,18 +58,25 @@
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<width>10</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="sizeLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="doneLabel">
<property name="sizePolicy">
+412 -111
View File
File diff suppressed because it is too large Load Diff
+61 -16
View File
@@ -29,6 +29,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QFile>
#include <QNetworkReply>
#include <QTime>
#include <QTimer>
#include <QVector>
#include <QMap>
#include <QStringList>
@@ -38,6 +39,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
namespace MOBase { class IPluginGame; }
class NexusInterface;
class PluginContainer;
/*!
* \brief manages downloading of files and provides progress information for gui elements
@@ -74,7 +76,9 @@ private:
QNetworkReply *m_Reply;
QTime m_StartTime;
qint64 m_PreResumeSize;
int m_Progress;
std::pair<int, QString> m_Progress;
std::tuple<int, int, int, int, int> m_SpeedDiff;
bool m_HasData;
DownloadState m_State;
int m_CurrentUrl;
QStringList m_Urls;
@@ -92,7 +96,7 @@ private:
bool m_Hidden;
static DownloadInfo *createNew(const MOBase::ModRepositoryFileInfo *fileInfo, const QStringList &URLs);
static DownloadInfo *createFromMeta(const QString &filePath, bool showHidden);
static DownloadInfo *createFromMeta(const QString &filePath, bool showHidden, const QString outputDirectory);
/**
* @brief rename the file
@@ -112,7 +116,7 @@ private:
private:
static unsigned int s_NextDownloadID;
private:
DownloadInfo() : m_TotalSize(0), m_ReQueried(false), m_Hidden(false) {}
DownloadInfo() : m_TotalSize(0), m_ReQueried(false), m_Hidden(false), m_SpeedDiff(std::tuple<int,int,int,int,int>(0,0,0,0,0)), m_HasData(false) {}
};
public:
@@ -134,6 +138,13 @@ public:
**/
bool downloadsInProgress();
/**
* @brief determine if a download is currently in progress, does not count paused ones.
*
* @return true if there is currently a download in progress (that is not paused already).
**/
bool downloadsInProgressNoPause();
/**
* @brief set the output directory to write to
*
@@ -141,6 +152,17 @@ public:
**/
void setOutputDirectory(const QString &outputDirectory);
/**
* @brief disables feedback from the downlods fileSystemWhatcher untill disableDownloadsWatcherEnd() is called
*
**/
static void startDisableDirWatcher();
/**
* @brief re-enables feedback from the downlods fileSystemWhatcher after disableDownloadsWatcherStart() was called
**/
static void endDisableDirWatcher();
/**
* @return current download directory
**/
@@ -162,6 +184,8 @@ public:
*/
void setShowHidden(bool showHidden);
void setPluginContainer(PluginContainer *pluginContainer);
/**
* @brief download from an already open network connection
*
@@ -179,7 +203,7 @@ public:
* @param fileInfo information previously retrieved from the nexus network
* @return true if the download was started, false if it wasn't. The latter currently only happens if there is a duplicate and the user decides not to download again
**/
bool addDownload(QNetworkReply *reply, const QStringList &URLs, const QString &fileName, int modID, int fileID = 0, const MOBase::ModRepositoryFileInfo *fileInfo = new MOBase::ModRepositoryFileInfo());
bool addDownload(QNetworkReply *reply, const QStringList &URLs, const QString &fileName, QString gameName, int modID, int fileID = 0, const MOBase::ModRepositoryFileInfo *fileInfo = new MOBase::ModRepositoryFileInfo());
/**
* @brief start a download using a nxm-link
@@ -209,7 +233,7 @@ public:
* @param index index of the pending download (index in the range [0, numPendingDownloads()[)
* @return pair of modid, fileid
*/
std::pair<int, int> getPendingDownload(int index);
std::tuple<QString, int, int> getPendingDownload(int index);
/**
* @brief retrieve the full path to the download specified by index
@@ -256,7 +280,7 @@ public:
* @param index index of the file to look up
* @return progress of the download in percent (integer)
**/
int getProgress(int index) const;
std::pair<int, QString> getProgress(int index) const;
/**
* @brief retrieve the current state of the download
@@ -285,6 +309,14 @@ public:
**/
int getModID(int index) const;
/**
* @brief retrieve the game name of the downlaod specified by the index
*
* @param index index of the file to look up
* @return the game name
**/
QString getGameName(int index) const;
/**
* @brief determine if the specified file is supposed to be hidden
* @param index index of the file to look up
@@ -411,15 +443,19 @@ public slots:
void queryInfo(int index);
void nxmDescriptionAvailable(int modID, QVariant userData, QVariant resultData, int requestID);
void visitOnNexus(int index);
void nxmFilesAvailable(int modID, QVariant userData, QVariant resultData, int requestID);
void openInDownloadsFolder(int index);
void nxmFileInfoAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID);
void nxmDescriptionAvailable(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID);
void nxmDownloadURLsAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID);
void nxmFilesAvailable(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID);
void nxmRequestFailed(int modID, int fileID, QVariant userData, int requestID, const QString &errorString);
void nxmFileInfoAvailable(QString gameName, int modID, int fileID, QVariant userData, QVariant resultData, int requestID);
void nxmDownloadURLsAvailable(QString gameName, int modID, int fileID, QVariant userData, QVariant resultData, int requestID);
void nxmRequestFailed(QString gameName, int modID, int fileID, QVariant userData, int requestID, const QString &errorString);
void managedGameChanged(MOBase::IPluginGame const *gamePlugin);
@@ -427,10 +463,11 @@ private slots:
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
void downloadReadyRead();
void downloadFinished();
void downloadFinished(int index = 0);
void downloadError(QNetworkReply::NetworkError error);
void metaDataChanged();
void directoryChanged(const QString &dirctory);
void checkDownloadTimeout();
private:
@@ -448,7 +485,7 @@ public:
*
* @return Unique(ish) name
*/
QString getDownloadFileName(const QString &baseName) const;
QString getDownloadFileName(const QString &baseName, bool rename = false) const;
private:
@@ -462,7 +499,7 @@ private:
* @param fileInfo information previously retrieved from the mod page
* @return true if the download was started, false if it wasn't. The latter currently only happens if there is a duplicate and the user decides not to download again
**/
bool addDownload(const QStringList &URLs, int modID, int fileID, const MOBase::ModRepositoryFileInfo *fileInfo);
bool addDownload(const QStringList &URLs, QString gameName, int modID, int fileID, const MOBase::ModRepositoryFileInfo *fileInfo);
// important: the caller has to lock the list-mutex, otherwise the DownloadInfo-pointer might get invalidated at any time
DownloadInfo *findDownload(QObject *reply, int *index = nullptr) const;
@@ -481,7 +518,7 @@ private:
QDateTime matchDate(const QString &timeString);
void removePending(int modID, int fileID);
void removePending(QString gameName, int modID, int fileID);
static QString getFileTypeString(int fileType);
@@ -493,7 +530,7 @@ private:
NexusInterface *m_NexusInterface;
QVector<std::pair<int, int> > m_PendingDownloads;
QVector<std::tuple<QString, int, int>> m_PendingDownloads;
QVector<DownloadInfo*> m_ActiveDownloads;
@@ -505,6 +542,12 @@ private:
QFileSystemWatcher m_DirWatcher;
//The dirWatcher is actually triggering off normal Mo operations such as deleting downloads or editing .meta files
//so it needs to be disabled during operations that are known to cause the creation or deletion of files in the Downloads folder.
//Notably using QSettings to edit a file creates a temporarily .lock file that causes the Watcher to trigger multiple listRefreshes freezing the ui.
static int m_DirWatcherDisabler;
std::map<QString, int> m_DownloadFails;
bool m_ShowHidden;
@@ -512,6 +555,8 @@ private:
QRegExp m_DateExpression;
MOBase::IPluginGame const *m_ManagedGame;
QTimer m_TimeoutTimer;
};
+62 -21
View File
@@ -49,6 +49,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QDirIterator>
#include <QDebug>
#include <QTextDocument>
#include <QtConcurrent/QtConcurrentRun>
#include <Shellapi.h>
@@ -181,6 +182,7 @@ bool InstallationManager::unpackSingleFile(const QString &fileName)
m_InstallationProgress->hide();
m_InstallationProgress->deleteLater();
m_InstallationProgress = nullptr;
m_Progress = 0;
});
m_InstallationProgress->setWindowFlags(
m_InstallationProgress->windowFlags() & ~Qt::WindowContextHelpButtonHint);
@@ -190,10 +192,20 @@ bool InstallationManager::unpackSingleFile(const QString &fileName)
m_InstallationProgress->setFixedSize(600, 100);
m_InstallationProgress->show();
bool res = m_ArchiveHandler->extract(QDir::tempPath(),
new MethodCallback<InstallationManager, void, float>(this, &InstallationManager::updateProgress),
nullptr,
new MethodCallback<InstallationManager, void, QString const &>(this, &InstallationManager::report7ZipError));
QFuture<bool> future = QtConcurrent::run([&]() -> bool {
return m_ArchiveHandler->extract(
QDir::tempPath(),
new MethodCallback<InstallationManager, void, float>(this, &InstallationManager::updateProgress),
nullptr,
new MethodCallback<InstallationManager, void, QString const &>(this, &InstallationManager::report7ZipError)
);
});
do {
if (m_Progress != m_InstallationProgress->value())
m_InstallationProgress->setValue(m_Progress);
QCoreApplication::processEvents();
} while (!future.isFinished() || m_InstallationProgress->isVisible());
bool res = future.result();
return res;
}
@@ -270,6 +282,7 @@ QStringList InstallationManager::extractFiles(const QStringList &filesOrig, bool
m_InstallationProgress->hide();
m_InstallationProgress->deleteLater();
m_InstallationProgress = nullptr;
m_Progress = 0;
});
m_InstallationProgress->setWindowFlags(
m_InstallationProgress->windowFlags() & (~Qt::WindowContextHelpButtonHint));
@@ -279,10 +292,20 @@ QStringList InstallationManager::extractFiles(const QStringList &filesOrig, bool
m_InstallationProgress->show();
// unpack only the files we need for the installer
if (!m_ArchiveHandler->extract(QDir::tempPath(),
new MethodCallback<InstallationManager, void, float>(this, &InstallationManager::updateProgress),
nullptr,
new MethodCallback<InstallationManager, void, QString const &>(this, &InstallationManager::report7ZipError))) {
QFuture<bool> future = QtConcurrent::run([&]() -> bool {
return m_ArchiveHandler->extract(
QDir::tempPath(),
new MethodCallback<InstallationManager, void, float>(this, &InstallationManager::updateProgress),
nullptr,
new MethodCallback<InstallationManager, void, QString const &>(this, &InstallationManager::report7ZipError)
);
});
do {
if (m_Progress != m_InstallationProgress->value())
m_InstallationProgress->setValue(m_Progress);
QCoreApplication::processEvents();
} while (!future.isFinished() || m_InstallationProgress->isVisible());
if (!future.result()) {
throw MyException(QString("extracting failed (%1)").arg(m_ArchiveHandler->getLastError()));
}
@@ -410,7 +433,8 @@ DirectoryTree::Node *InstallationManager::getSimpleArchiveBase(DirectoryTree *da
void InstallationManager::updateProgress(float percentage)
{
if (m_InstallationProgress != nullptr) {
m_InstallationProgress->setValue(static_cast<int>(percentage * 100.0));
m_Progress = static_cast<int>(percentage * 100.0);
if (m_InstallationProgress->wasCanceled()) {
m_ArchiveHandler->cancel();
m_InstallationProgress->reset();
@@ -421,10 +445,7 @@ void InstallationManager::updateProgress(float percentage)
void InstallationManager::updateProgressFile(QString const &fileName)
{
if (m_InstallationProgress != nullptr) {
m_InstallationProgress->setLabelText(fileName);
QCoreApplication::processEvents();
}
m_ProgressFile = fileName;
}
@@ -537,7 +558,7 @@ bool InstallationManager::ensureValidModName(GuessedValue<QString> &name) const
return true;
}
bool InstallationManager::doInstall(GuessedValue<QString> &modName, int modID,
bool InstallationManager::doInstall(GuessedValue<QString> &modName, QString gameName, int modID,
const QString &version, const QString &newestVersion,
int categoryID, const QString &repository)
{
@@ -561,6 +582,8 @@ bool InstallationManager::doInstall(GuessedValue<QString> &modName, int modID,
m_InstallationProgress->hide();
m_InstallationProgress->deleteLater();
m_InstallationProgress = nullptr;
m_Progress = 0;
m_ProgressFile = QString();
});
m_InstallationProgress->setWindowFlags(
@@ -568,10 +591,22 @@ bool InstallationManager::doInstall(GuessedValue<QString> &modName, int modID,
m_InstallationProgress->setWindowModality(Qt::WindowModal);
m_InstallationProgress->setFixedSize(600, 100);
m_InstallationProgress->show();
if (!m_ArchiveHandler->extract(targetDirectory,
new MethodCallback<InstallationManager, void, float>(this, &InstallationManager::updateProgress),
new MethodCallback<InstallationManager, void, QString const &>(this, &InstallationManager::updateProgressFile),
new MethodCallback<InstallationManager, void, QString const &>(this, &InstallationManager::report7ZipError))) {
QFuture<bool> future = QtConcurrent::run([&]() -> bool {
return m_ArchiveHandler->extract(
targetDirectory,
new MethodCallback<InstallationManager, void, float>(this, &InstallationManager::updateProgress),
new MethodCallback<InstallationManager, void, QString const &>(this, &InstallationManager::updateProgressFile),
new MethodCallback<InstallationManager, void, QString const &>(this, &InstallationManager::report7ZipError)
);
});
do {
if (m_Progress != m_InstallationProgress->value())
m_InstallationProgress->setValue(m_Progress);
if (m_ProgressFile != m_InstallationProgress->labelText())
m_InstallationProgress->setLabelText(m_ProgressFile);
QCoreApplication::processEvents();
} while (!future.isFinished());
if (!future.result()) {
if (m_ArchiveHandler->getLastError() == Archive::ERROR_EXTRACT_CANCELLED) {
return false;
} else {
@@ -582,6 +617,9 @@ bool InstallationManager::doInstall(GuessedValue<QString> &modName, int modID,
QSettings settingsFile(targetDirectory + "/meta.ini", QSettings::IniFormat);
// overwrite settings only if they are actually are available or haven't been set before
if ((gameName != "") || !settingsFile.contains("gameName")) {
settingsFile.setValue("gameName", gameName);
}
if ((modID != 0) || !settingsFile.contains("modid")) {
settingsFile.setValue("modid", modID);
}
@@ -662,6 +700,7 @@ bool InstallationManager::install(const QString &fileName,
modName.update(QFileInfo(fileName).completeBaseName(), GUESS_FALLBACK);
// read out meta information from the download if available
QString gameName = "";
int modID = 0;
QString version = "";
QString newestVersion = "";
@@ -671,6 +710,7 @@ bool InstallationManager::install(const QString &fileName,
QString metaName = fileName + ".meta";
if (QFile(metaName).exists()) {
QSettings metaFile(metaName, QSettings::IniFormat);
gameName = metaFile.value("gameName", "").toString();
modID = metaFile.value("modID", 0).toInt();
QTextDocument doc;
doc.setHtml(metaFile.value("name", "").toString());
@@ -759,7 +799,7 @@ bool InstallationManager::install(const QString &fileName,
mapToArchive(filesTree.data());
// the simple installer only prepares the installation, the rest
// works the same for all installers
if (!doInstall(modName, modID, version, newestVersion, categoryID,
if (!doInstall(modName, gameName, modID, version, newestVersion, categoryID,
repository)) {
installResult = IPluginInstaller::RESULT_FAILED;
}
@@ -779,7 +819,7 @@ bool InstallationManager::install(const QString &fileName,
= installerCustom->supportedExtensions();
if (installerExt.find(fileInfo.suffix()) != installerExt.end()) {
installResult
= installerCustom->install(modName, fileName, version, modID);
= installerCustom->install(modName, gameName, fileName, version, modID);
unsigned int idx = ModInfo::getIndex(modName);
if (idx != UINT_MAX) {
ModInfo::Ptr info = ModInfo::getByIndex(idx);
@@ -814,7 +854,8 @@ bool InstallationManager::install(const QString &fileName,
}
}
reportError(tr("None of the available installer plugins were able to handle that archive"));
reportError(tr("None of the available installer plugins were able to handle that archive.\n"
"This is likely due to a corrupted or incompatible download or unrecognized archive format."));
return false;
}
+8 -1
View File
@@ -168,7 +168,7 @@ private:
bool isSimpleArchiveTopLayer(const MOBase::DirectoryTree::Node *node, bool bainStyle);
MOBase::DirectoryTree::Node *getSimpleArchiveBase(MOBase::DirectoryTree *dataTree);
bool doInstall(MOBase::GuessedValue<QString> &modName,
bool doInstall(MOBase::GuessedValue<QString> &modName, QString gameName,
int modID, const QString &version, const QString &newestVersion, int categoryID, const QString &repository);
QString generateBackupName(const QString &directoryName) const;
@@ -177,6 +177,11 @@ private:
void postInstallCleanup();
signals:
void progressUpdate(float percentage);
void progressUpdate(QString const fileName);
private:
struct ByPriority {
@@ -207,6 +212,8 @@ private:
QString m_CurrentFile;
QProgressDialog *m_InstallationProgress { nullptr };
int m_Progress;
QString m_ProgressFile;
std::set<QString> m_TempFilesToDelete;
+32 -3
View File
@@ -131,11 +131,12 @@ QString InstanceManager::manageInstances(const QStringList &instanceList) const
QString InstanceManager::queryInstanceName(const QStringList &instanceList) const
{
QString instanceId;
QString dialogText;
while (instanceId.isEmpty()) {
QInputDialog dialog;
dialog.setWindowTitle(QObject::tr("Enter a Name for the new Instance"));
dialog.setLabelText(QObject::tr("Enter a new name or select one from the sugested list (only letters and numbers allowed):"));
dialog.setWindowTitle(QObject::tr("Enter a Name for the new Instance"));
dialog.setLabelText(QObject::tr("Enter a new name or select one from the suggested list:"));
// would be neat if we could take the names from the game plugins but
// the required initialization order requires the ini file to be
// available *before* we load plugins
@@ -146,7 +147,17 @@ QString InstanceManager::queryInstanceName(const QStringList &instanceList) cons
if (dialog.exec() == QDialog::Rejected) {
throw MOBase::MyException(QObject::tr("Canceled"));
}
instanceId = dialog.textValue().replace(QRegExp("[^0-9a-zA-Z ]"), "");
dialogText = dialog.textValue();
instanceId = sanitizeInstanceName(dialogText);
if (instanceId != dialogText) {
if (QMessageBox::question( nullptr,
QObject::tr("Invalid instance name"),
QObject::tr("The instance name \"%1\" is invalid. Use the name \"%2\" instead?").arg(dialogText,instanceId),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) {
instanceId="";
continue;
}
}
bool alreadyExists=false;
for (const QString &instance : instanceList) {
@@ -296,3 +307,21 @@ QString InstanceManager::determineDataPath()
}
}
QString InstanceManager::sanitizeInstanceName(const QString &name) const
{
QString new_name = name;
// Restrict the allowed characters
new_name = new_name.remove(QRegExp("[^A-Za-z0-9 _=+;!@#$%^'\\-\\.\\[\\]\\{\\}\\(\\)]"));
// Don't end in spaces and periods
new_name = new_name.remove(QRegExp("\\.*$"));
new_name = new_name.remove(QRegExp(" *$"));
// Recurse until stuff stops changing
if (new_name != name) {
return sanitizeInstanceName(new_name);
}
return new_name;
}

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