mirror of
https://github.com/ModOrganizer2/modorganizer.git
synced 2026-07-27 13:58:24 -07:00
Compare commits
133
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fe8c3aaea5 | ||
|
|
dda9e11976 | ||
|
|
9945b5e926 | ||
|
|
dbbd0c4eec | ||
|
|
4ff751fb7e | ||
|
|
d8d81ee06f | ||
|
|
a4b69c9ed8 | ||
|
|
053ebc898f | ||
|
|
0bd38e3f67 | ||
|
|
7f4f4cafea | ||
|
|
56ba058cd5 | ||
|
|
f25a51446c | ||
|
|
ec07d3d4d9 | ||
|
|
939993aefe | ||
|
|
af9a128b4f | ||
|
|
7d93a9a200 | ||
|
|
90d87a0cf7 | ||
|
|
115315df28 | ||
|
|
c5876cb6a1 | ||
|
|
e7b61cb485 | ||
|
|
a0eb00b6b6 | ||
|
|
f2484c3b0e | ||
|
|
107adbfffc | ||
|
|
de98fe64a3 | ||
|
|
364c385f1a | ||
|
|
3c1c50fefc | ||
|
|
095967451e | ||
|
|
eb901e0dfc | ||
|
|
462c549f77 | ||
|
|
1f8c24ee7a | ||
|
|
8865f9d7bc | ||
|
|
ae82ab7dca | ||
|
|
999810e1d5 | ||
|
|
4dbf01cd56 | ||
|
|
cd7b409c10 | ||
|
|
ff8377a8ff | ||
|
|
4573d111a2 | ||
|
|
84ec954073 | ||
|
|
63188eb6f3 | ||
|
|
0a51fdf08e | ||
|
|
cb315b4179 | ||
|
|
d96d904765 | ||
|
|
9588667404 | ||
|
|
b008753e1d | ||
|
|
3c7ab3b668 | ||
|
|
d85019f4b1 | ||
|
|
05edcf8840 | ||
|
|
2a22461f14 | ||
|
|
0c3c822d77 | ||
|
|
f0ee9c3e4d | ||
|
|
83edfe0c96 | ||
|
|
86d833bcc8 | ||
|
|
58198a6bfd | ||
|
|
32339addbf | ||
|
|
dd875c05de | ||
|
|
17938b503a | ||
|
|
269d4f6765 | ||
|
|
0fa7f7469f | ||
|
|
ea1c2b46fe | ||
|
|
89f3c0d65a | ||
|
|
821f95b8ab | ||
|
|
716dbcc97d | ||
|
|
8e7ac4e064 | ||
|
|
69a8a40b99 | ||
|
|
229161565e | ||
|
|
9c3b390f08 | ||
|
|
5244544424 | ||
|
|
217ca284fe | ||
|
|
0aecc3427a | ||
|
|
b6627ff5e0 | ||
|
|
b0d86c9e01 | ||
|
|
a7d6eb75c2 | ||
|
|
6f09cf2205 | ||
|
|
e6abe486a7 | ||
|
|
52fcfaa292 | ||
|
|
4230313ef5 | ||
|
|
ff8057d34b | ||
|
|
b098214860 | ||
|
|
8cf429a1dd | ||
|
|
9f7bec01d0 | ||
|
|
643a50ad5a | ||
|
|
eaaa1b312d | ||
|
|
9c17ecc87e | ||
|
|
051589c38e | ||
|
|
48fae44566 | ||
|
|
e1c8d00979 | ||
|
|
0503097494 | ||
|
|
3a39f90870 | ||
|
|
18ad656586 | ||
|
|
eaafc489fc | ||
|
|
7799c348ba | ||
|
|
0a1f3efac5 | ||
|
|
1eea37e4e1 | ||
|
|
9a5965afa7 | ||
|
|
7853ba5f9a | ||
|
|
90dcc81715 | ||
|
|
1e75fd8dae | ||
|
|
61033814fd | ||
|
|
ca591dbd23 | ||
|
|
7602fef6e7 | ||
|
|
67b1f9dca2 | ||
|
|
5ae279d8bb | ||
|
|
81ef3d0a81 | ||
|
|
dc0e67a8b3 | ||
|
|
aa21a192cb | ||
|
|
d4d7ce1fd3 | ||
|
|
e31baf3ee6 | ||
|
|
5dcfca7c9d | ||
|
|
e9ee7e7f85 | ||
|
|
67d017fc98 | ||
|
|
a700e6a3ef | ||
|
|
c95de1b3aa | ||
|
|
351fc9ca9c | ||
|
|
53f0a2bc79 | ||
|
|
793dfb1637 | ||
|
|
d25a81071c | ||
|
|
ef9a61886c | ||
|
|
13a40b43c8 | ||
|
|
d7790cd717 | ||
|
|
84d632af6a | ||
|
|
b14b35349d | ||
|
|
83a4db2362 | ||
|
|
c797af8b76 | ||
|
|
ebf6ff3f76 | ||
|
|
02b5e73c2d | ||
|
|
b0b2f1d3a9 | ||
|
|
d8e406daa0 | ||
|
|
50dcc4c1d4 | ||
|
|
e21db0eaea | ||
|
|
859332e18d | ||
|
|
1fd8f44960 | ||
|
|
e0c655330d | ||
|
|
a0999cd42b |
+12
@@ -0,0 +1,12 @@
|
||||
*.user
|
||||
Thumbs.db
|
||||
src/moc_*.cpp
|
||||
src/ui_*.h
|
||||
src/*.qrc.depends
|
||||
src/Modorganizer.*
|
||||
CMakeLists.txt.user
|
||||
edit
|
||||
stderr.log
|
||||
stdout.log
|
||||
build
|
||||
.idea
|
||||
@@ -0,0 +1,14 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
|
||||
PROJECT(organizer)
|
||||
|
||||
SET(DEPENDENCIES_DIR CACHE PATH "")
|
||||
# hint to find qt in dependencies path
|
||||
LIST(APPEND CMAKE_PREFIX_PATH ${DEPENDENCIES_DIR}/qt5/lib/cmake)
|
||||
|
||||
FILE(GLOB_RECURSE BOOST_ROOT ${DEPENDENCIES_DIR}/boost*/project-config.jam)
|
||||
GET_FILENAME_COMPONENT(BOOST_ROOT ${BOOST_ROOT} DIRECTORY)
|
||||
|
||||
SET(ZLIB_ROOT ${DEPENDENCIES_DIR}/zlib)
|
||||
|
||||
ADD_SUBDIRECTORY(src)
|
||||
-273
@@ -1,273 +0,0 @@
|
||||
HOW TO BUILD
|
||||
============
|
||||
|
||||
Intro:
|
||||
------
|
||||
|
||||
Building Mod Organizer can be a rather daunting task especially if you're not very comfortable with C++ development under windows.
|
||||
Please note that if you only want to work on and build a plugin you can save yourself a lot of trouble
|
||||
|
||||
Overview:
|
||||
---------
|
||||
|
||||
As of July 2014 MO consists of the following subprojects:
|
||||
- organizer: The main userinterface. heavy usage of various libraries
|
||||
- hookdll: core library of the virtual file system
|
||||
- uibase: interop between plugins and the main application as well as some reusable functionality
|
||||
- shared: functionality shared between organizer and hookdll. I'm attempting to get rid of this library over time
|
||||
- nxmhandler: tool to pass handling of nxm links to MO or other applications
|
||||
- helper: tool for doing operations requiring elevated priviledges if MO doesn't have them
|
||||
- proxydll: dll used in the "proxy dll" load mechanism
|
||||
- esptk: small library containing functionality to work with esps/esms
|
||||
- bsatk: small library containing functionality to work with bsas. Requires zlib to extract files. Requires boost_thread to provide multi-threaded extraction
|
||||
- archive: small wrapper library around 7zip for dealing with mod archives. Requires 7zip
|
||||
- NCC: extension to NMM to provide a binary with command line interface for fomod installation. This is c# code and does not build with the rest of the project. Requires the rest of NMM
|
||||
- bossdummy: dummy dll that looks like the boss.dll. This is used instead of the real boss dlls in NCC to save some disk space
|
||||
- pythonrunner: library for embedding python code. Requires boost_python, python 2.7 and pyqt5
|
||||
- loot_cli: this is a command line client of loot. This can be better integrated with MO than the official loot client.
|
||||
|
||||
And various plugins:
|
||||
- bsaExtractor: offers to extract bsas after a mod has been installed
|
||||
- checkFNIS: Activates each time an application is started from MO and runs fnis if necessary
|
||||
- diagnoseBasic: Various diagnostic checks on the game
|
||||
- inieditor: minimalistic file editor for ini files
|
||||
- installerBain: handles non-scripted bain installers
|
||||
- installerBundle: handles installation of archives wrapped in archives
|
||||
- installerFomod: handles installation of xml fomods
|
||||
- installerManual: handles installations of archives that aren't supported by any other plugin (or if the user chooses to do the installation manually)
|
||||
- installerNCC: handles installation of any fomod (requires NCC)
|
||||
- installerQuick: handles very simple one-click installations
|
||||
- NMMImport: importer from existing nmm installation
|
||||
- proxyPython: integrates pythonrunner as a plugin into MO
|
||||
- pyniEdit: more user-friendly ini editor. python code
|
||||
- previewBase: used for file previews. this plugin covers image formats supported by the qt installation (usually at least jpg, gif, png) and text files
|
||||
- previewDDS: used to preview dds textures. uses code from the nif file format library
|
||||
|
||||
There are a few more plugins that are either broken or samples
|
||||
- installerBCF: this was intended to use .bcf (bain conversion file) files as installation instructions but currently it is completely function-less
|
||||
- helloWorldCpp: sample for cpp plugins. This should compile even without fulfilling most dependencies below
|
||||
- pageTESAlliance: integrates the tes alliance page into MO. This integration is not nearly as tight as that of nexus.
|
||||
|
||||
Requirements:
|
||||
-------------
|
||||
|
||||
Visual C++ compiler 2013 (VC 12.0) or up
|
||||
- Included in visual c++ express 2013
|
||||
- Do install windows sdk too if only for the cdb debugger which is included in that package
|
||||
Note: If you're having trouble installing the windows sdk, you may be affected by this bug: http://support.microsoft.com/kb/2717426
|
||||
|
||||
Qt Libraries 5.4.x (http://www.qt.io/download-open-source/#section-2)
|
||||
- i.e. "Qt libraries 5.4.0 for Windows (VS 2013, 722 MB)"
|
||||
- tested: 5.4.0 for Windows 32-bit (VS 2013, OpenGL, 695 MB)
|
||||
- Install according to instruction
|
||||
|
||||
boost libraries (http://www.boost.org/)
|
||||
- tested: 1.56
|
||||
- Build according to their instructions (using vc++): http://www.boost.org/doc/libs/1_57_0/more/getting_started/windows.html
|
||||
- A few of the boost libraries need to be built (the rest is header-only). The only compiled libs MO needs (at the time of writing) are
|
||||
boost_thread (for everything that links agains bsatk) and boost_python (for pythonrunner). You can disable the others to save yourself compile time (even on a modern system compiling boost can easily take an hour)
|
||||
|
||||
zlib (http://www.zlib.net/)
|
||||
- Compile static library according to their instructions
|
||||
- Depending on the version of zlib and how you built you should have a file called zlibstatic.lib or zlibstat.lib in "build" or "x86\ZLibStatRelease".
|
||||
- Please copy that lib file to "build\zlibstatic.lib" (if it doesn't exist) so MO finds it.
|
||||
|
||||
7z sourcecode (http://www.7-zip.org/download.html)
|
||||
- only for "archive" subproject
|
||||
- no need to compile, will be linked into project
|
||||
|
||||
Python 2.7 (32-bit)
|
||||
- only for pythonrunner
|
||||
|
||||
PyQt5 for Python 2.7 (http://www.riverbankcomputing.co.uk/software/pyqt/download)
|
||||
- tested: PyQt-gpl-5.4.zip
|
||||
- only for pythonrunner
|
||||
|
||||
SIP (http://www.riverbankcomputing.com/software/sip/download)
|
||||
- presumably only for pythonrunner as it's needed for PyQT5
|
||||
|
||||
Recommended:
|
||||
------------
|
||||
|
||||
Qt Creator
|
||||
- included in Qt SDK
|
||||
- With Qt Creator usually the rule is "the newer the better"
|
||||
- Start Qt Creator and check if things are set up correctly:
|
||||
1) Go to Tools > Options > Build & Run > Qt Versions
|
||||
2.1) If the QtSDK 5.4.x you installed earlier is not auto-detected, click "Add" to add it manually
|
||||
2.2) Navigate to your <your qt5 installation>\bin\qmake.exe
|
||||
2.3) Restart qt creator
|
||||
3) Go to Tools > Options > Build & Run > Kits
|
||||
3.1) If no Kit is auto-detected (or the auto-detected ones have picked up the wrong qt or vc++ installation) click "Add"
|
||||
3.2) Enter a Name (i.e. "Qt 5.4 MSVC2013 32bit")
|
||||
3.3) In Compiler select the visual studio compiler installed earlier (may show up as "Microsoft Windows SDK for Windows x). Make sure you select the x86 variant
|
||||
3.4) CDB should be auto-detected
|
||||
3.5) Select the qt version set up earlier
|
||||
4) Apply and close the options
|
||||
|
||||
Set up (using Qt Creator):
|
||||
--------------------------
|
||||
|
||||
1. Create a file called "LocalPaths.pri" in your ModOrganizer\source directory
|
||||
2. Open that file with any text editor and enter (one entry per line)
|
||||
2a. BOOSTPATH=<path to your boost installation> (i.e. C:\code\boost_1_56_0)
|
||||
2b. LOOTPATH=C:/Users/Tannin/Documents/Projects/loot_api
|
||||
2c. PYTHONPATH=D:/Python278
|
||||
2d. SEVENZIPPATH=D:/Documents/Projects/7zip
|
||||
2e. ZLIBPATH=D:/Documents/Projects/zlib-1.2.7
|
||||
3. Using Qt Creator open source/ModOrganizer.pro from your working copy
|
||||
4. Compile the configuration(s) you want to use (debug and/or release) (Build All). This should compile correctly (though right now it produces a lot of warnings in boost headers).
|
||||
5. <reserved for future use. Maybe grab a coffee?>
|
||||
6. return to the "projects" tab and switch to "Run Settings"
|
||||
7. Determine the folder of the qt binaries in the package you downloaded. This could be "QtSDK\Desktop\Qt\5.4.0\msvc2013\bin" or "Qt5.4.0\bin"
|
||||
For Release build:
|
||||
8r. Add a "Run configuration" that points to <your working copy>\output\ModOrganizer.exe
|
||||
9r. Copy "7z.dll" to <your working copy>\output\dlls
|
||||
10r. From the qt binaries directory, copy the following files to <your working copy>\output\dlls: Qt5Core.dll, Qt5Declarative.dll, Qt5Gui.dll, Qt5Network.dll, Qt5Script.dll, Qt5Sql.dll, Qt5Webkit.dll, Qt5Xml.dll, Qt5XmlPatterns.dll
|
||||
For Debug build:
|
||||
8d. Add a "Run configuration" that points to <your working copy>\outputd\ModOrganizer.exe
|
||||
9d. Copy "7z.dll" to <your working copy>\outputd\dlls
|
||||
10d. From the qt binaries copy the following files to <your working copy>\outputd\dlls: Qt5Cored.dll, Qt5Declaratived.dll, Qt5Guid.dll, Qt5Networkd.dll, Qt5Scriptd.dll, Qt5Sqld.dll, Qt5Webkitd.dll, Qt5Xmld.dll, Qt5XmlPatternsd.dll
|
||||
|
||||
Now you should be able to compile and run Mod Organizer.
|
||||
Please note that when you change anything apart from the "organizer" subproject, qt creator may not pick up on the changes
|
||||
and not recompile the modified subproject. the "organizer" project on the other hand is always re-linked. If anyone knowledgeable enough with qmake
|
||||
can fix that that would be awesome.
|
||||
|
||||
Set up (without Qt Creator):
|
||||
----------------------------
|
||||
|
||||
1. open a command line shell and navigate to <your working copy>\source
|
||||
2. run "qmake -tp vc" to create a visual c++ solution
|
||||
3. Open that solution
|
||||
4. - 98. A miracle happens
|
||||
99. You can now compile MO using VC
|
||||
|
||||
I'm not using this workflow so I can't give more detailed instructions.
|
||||
Please note that the primary project format of MO remains qmake, if you work with visual studio and make changes to the project (like adding
|
||||
source files) you have to manually transfer those changes to the .pro file.
|
||||
|
||||
|
||||
|
||||
-----------------
|
||||
Troubleshooting (thanks to Ross):
|
||||
-----------------
|
||||
|
||||
1) When I try to build, I am seeing the error "error: LNK1104: cannot open file 'zlibstatic.lib'"
|
||||
|
||||
a) Make sure you have the following files
|
||||
{ZLIBPATH}\build\zconf.h
|
||||
{ZLIBPATH}\build\zlib.h
|
||||
{ZLIBPATH}\build\zlibstatic.lib
|
||||
|
||||
b) make sure "zlibstat.lib" was renamed to "zlibstatic.lib"
|
||||
c) currently, there are references to zlibstatic in the following 2 project files:
|
||||
./bsatk/bsatk.pro
|
||||
./hookdll/hookdll.pro
|
||||
|
||||
Please note if building this, you need to switch OFF -DZLIB_WINAPI ...
|
||||
|
||||
2) After building, I try to open {MOPROJECTPATH}\outputd\ModOragnizer.exe and get this error
|
||||
"The program can't start because QtDeclaratived4.dll is missing from your computer. Try reinstalling the program to fix this problem."
|
||||
|
||||
-> When setting up Qt4.8.x, make sure you copied the "d" (debug) versions of the dll files to {MOPROJECTPATH}\outputd\dlls
|
||||
If you copied the release version or did not copy the dlls at all, you may see this error.
|
||||
The *.dll files can be found in {QT48xPATH}\bin
|
||||
|
||||
Similiar:
|
||||
http://stackoverflow.com/questions/11196416/cant-start-qt-exe-file-on-windows-7
|
||||
|
||||
3) I am getting one or more of the the following compiler warnings...
|
||||
|
||||
"{MOPROJECTPATH}\source\bsatk\bsaexception.cpp:32: warning: C4996: 'vsnprintf': This function or variable may be unsafe.
|
||||
Consider using vsnprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details."
|
||||
-> Ignore/suppress warning like this and make be ultra-careful using printf-style functions. vsnprintf_s is a visual-c++ only function so using those would make porting (i.e. to mingw) harder
|
||||
|
||||
"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\stdio.h:354: see declaration of 'vsnprintf'"
|
||||
-> see previous
|
||||
|
||||
"debug\bsaarchive.obj:-1: warning: LNK4042: object specified more than once; extras ignored"
|
||||
|
||||
-> This appears to be an issue when using VC++ 2010 as the compiler. There are some posts on StackOverflow
|
||||
which suggest fixes when using VC++ as the IDE, but not sure how to apply them to Qt Creator.
|
||||
http://stackoverflow.com/questions/3729515
|
||||
http://stackoverflow.com/questions/3695174
|
||||
|
||||
-> Also, not sure if this affects VC++ 2012 / VC++ 2013 / GCC via cygwin/mingw.
|
||||
Not even sure if the project would successfully compile on these.
|
||||
|
||||
"{MOPROJECTPATH}\source\organizer\mainwindow.cpp:3995: warning: C4428: universal-character-name encountered in source"
|
||||
|
||||
-> very pointless warning.
|
||||
http://stackoverflow.com/questions/11589571
|
||||
http://stackoverflow.com/questions/7078013
|
||||
|
||||
the best solution I saw was to just disable the warning altogether...
|
||||
#pragma warning( disable : 4428 )
|
||||
|
||||
"warning: LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs; use /NODEFAULTLIB:library"
|
||||
|
||||
-> You can always add a #pragma to ignore them :P
|
||||
http://msdn.microsoft.com/en-us/library/2c8f766e%28v=vs.80%29.aspx
|
||||
|
||||
4) I got the following error while building...
|
||||
"error: LNK1201: error writing to program database
|
||||
'{MOPROJECTPATH}\{whatever-your-build-directory-name-is}\organizer\debug\ModOrganizer.pdb';
|
||||
check for insufficient disk space, invalid path, or insufficient privilege"
|
||||
|
||||
-> I had this happen after trying to look at something in memory via Process Explorer.
|
||||
To resolve, I killed and restarted PE. Alternatively, you could probably use the
|
||||
Unlocker utility. After unlocking, I manually deleted everything in the directory.
|
||||
|
||||
Unlocker: http://www.filehippo.com/download_unlocker/ or http://www.emptyloop.com/unlocker/
|
||||
Warning: With Unlocker v1.9.2, you must select "Advanced" then uncheck everything to
|
||||
avoid having some Delta toolbar garbage installed...
|
||||
|
||||
5) Problem TT has seen:
|
||||
Complains about 'qtwebkit4' missing. For some reason this seems to insist on
|
||||
living with modorganiser.exe
|
||||
|
||||
6) Debugging the python proxy: I (TT) don't think this is possible unless you have a debug
|
||||
build of PyQt. However, a debug build of PyQt requires a debug build of python. There doesn't
|
||||
appear to be a half way house which is build wiht normal python but debug versions of QT libraries.
|
||||
You can confuse pyqt by copying the debug QT DLLs to appropriate named files in the DLLs
|
||||
directory, and removing QT from your project run path, which results in the python proxy
|
||||
initialising succesfully, but causes mod organiser to crash in strange places.
|
||||
|
||||
-------------------
|
||||
Building with scons
|
||||
-------------------
|
||||
|
||||
1) Download scons from www.scons.org and install
|
||||
2) Download QT4 (and/or QT5) from https://bitbucket.org/dirkbaechle/scons_qt4 and
|
||||
https://bitbucket.org/dirkbaechle/scons_qt5. Install as per instructions
|
||||
3) Copy scons_configure_template.py to scons_configure.py. Edit to point to your
|
||||
boost/python/zlib/7zip/loot directories as appropriate.
|
||||
4) Create build kits as follows:
|
||||
Custom Process step:
|
||||
Command: <python path>\Scripts\scons.bat
|
||||
Arguments: -u .
|
||||
Working directory: %{sourcedir}
|
||||
|
||||
Clean Custom Process step:
|
||||
Command: <python path>\Scripts\scons.bat
|
||||
Arguments: -c -u .
|
||||
Working directory: %{sourcedir}
|
||||
|
||||
For the release build, add 'CONFIG=release' to the arguments.
|
||||
|
||||
If you want to do parallel builds, add -j and a number to the arguments.
|
||||
However you may need to install pywin32 (but it seems to work OK for me).
|
||||
-j 4 did the entire build in 2m 15s. scons uses -Z7 to store debugging
|
||||
information in the .obj files which removes the issues with multiple
|
||||
processes attempting to access one datafile.
|
||||
|
||||
Note. If you want to build a sub project separately, it seems to be better
|
||||
to open the subproject, set that up with the scons kit and build that as a
|
||||
project.
|
||||
|
||||
Please note: the generated (runnable) output files end up in the build directory,
|
||||
in the '_ModOrganizer' subdirectory (not at the top level). Named like that
|
||||
so you can see it! The scons build will also populate the directory with
|
||||
all the necessary DLLs (but see note 6 above about your build tool path if
|
||||
trying to debug).
|
||||
+524
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,40 @@
|
||||
# Mod Organizer
|
||||
|
||||
Mod Organizer (MO) is a tool for managing mod collections of arbitrary size. It is specifically designed for people who like to experiment with mods and thus need an easy and reliable way to install and uninstall them.
|
||||
|
||||
## Building
|
||||
|
||||
Please refer to [TanninOne/modorganizer-umbrella](https://github.com/TanninOne/modorganizer-umbrella) for build instructions.
|
||||
|
||||
## Other Repositories
|
||||
|
||||
MO consists of multiple repositories on github. The Umbrella project will download them automatically as required. They should however also be buildable individually.
|
||||
Here is a complete list:
|
||||
* https://github.com/TanninOne/modorganizer
|
||||
* https://github.com/TanninOne/modorganizer-uibase
|
||||
* https://github.com/TanninOne/modorganizer-hookdll
|
||||
* https://github.com/TanninOne/modorganizer-bsatk
|
||||
* https://github.com/TanninOne/modorganizer-esptk
|
||||
* https://github.com/TanninOne/modorganizer-archive
|
||||
* https://github.com/TanninOne/modorganizer-nxmhandler
|
||||
* https://github.com/TanninOne/modorganizer-lootcli
|
||||
* https://github.com/TanninOne/modorganizer-helper
|
||||
* https://github.com/TanninOne/modorganizer-tool_nmmimport
|
||||
* https://github.com/TanninOne/modorganizer-tool_pyniedit
|
||||
* https://github.com/TanninOne/modorganizer-tool_inieditor
|
||||
* https://github.com/TanninOne/modorganizer-preview_base
|
||||
* https://github.com/TanninOne/modorganizer-diagnose_basic
|
||||
* https://github.com/TanninOne/modorganizer-installer_quick
|
||||
* https://github.com/TanninOne/modorganizer-installer_manual
|
||||
* https://github.com/TanninOne/modorganizer-installer_fomod
|
||||
* https://github.com/TanninOne/modorganizer-installer_bundle
|
||||
* https://github.com/TanninOne/modorganizer-installer_bain
|
||||
* https://github.com/TanninOne/modorganizer-game_skyrim
|
||||
* https://github.com/TanninOne/modorganizer-game_oblivion
|
||||
* https://github.com/TanninOne/modorganizer-game_fallout3
|
||||
* https://github.com/TanninOne/modorganizer-game_falloutnv
|
||||
* https://github.com/TanninOne/modorganizer-game_gamebryo
|
||||
* https://github.com/TanninOne/modorganizer-game_features
|
||||
* https://github.com/TanninOne/modorganizer-check_fnis
|
||||
* https://github.com/TanninOne/modorganizer-plugin_python
|
||||
* https://github.com/TanninOne/modorganizer-bsa_extractor
|
||||
@@ -4,7 +4,7 @@
|
||||
# Path to your boost install - it should have a boost/ subdirectory and a stage/
|
||||
# subdirectory. The scons script will use stage/lib if there, or the appropriate
|
||||
# version for your compiler, if you installed the multiple-build version
|
||||
BOOSTPATH = 'C:\\Apps\\boost_1_55_0'
|
||||
BOOSTPATH = r"C:\Apps\boost_1_55_0"
|
||||
|
||||
# Version of Visual Studio to use, if you wish to use a specific version. If you
|
||||
# don't specify a version, the latest will be picked.. See the scons manual for
|
||||
@@ -14,15 +14,20 @@ BOOSTPATH = 'C:\\Apps\\boost_1_55_0'
|
||||
# Path to your python install
|
||||
# You don't really need to set this up but you might if (say) you have a 32- and
|
||||
# 64-bit python install and scons has been installed for the 64 bit version
|
||||
#PYTHONPATH=C:\Apps\Python
|
||||
#PYTHONPATH=r"C:\Apps\Python"
|
||||
|
||||
# Path to your QT install. This might constrain the version of MSVC you can use.
|
||||
# This seems to be set by QTCreator
|
||||
#QTDIR = 'C:\\Apps\\Qt\\4.8.6'
|
||||
#QTDIR = r"C:\Apps\Qt\4.8.6"
|
||||
|
||||
# Path to 7-zip sources
|
||||
SEVENZIPPATH = 'C:\\Apps\\7-Zip\\7z920'
|
||||
SEVENZIPPATH = r"C:\Apps\7-Zip\7z920"
|
||||
|
||||
# Path to zlib. Please read the README file for more information about how this
|
||||
# needs to be set up
|
||||
ZLIBPATH = 'C:\\Apps\\zlib-1.2.8'
|
||||
ZLIBPATH = r"C:\Apps\zlib-1.2.8"
|
||||
|
||||
# Source control programs. Sadly I can't get this information from qt, even
|
||||
# though you have to set it up in the configuration
|
||||
GIT = r"C:\Program Files\git\bin\git.exe"
|
||||
MERCURIAL = r"C:\Program Files\TortoiseHg\hg.exe"
|
||||
|
||||
@@ -0,0 +1,351 @@
|
||||
CMAKE_MINIMUM_REQUIRED (VERSION 2.8)
|
||||
|
||||
CMAKE_POLICY(SET CMP0020 NEW)
|
||||
#CMAKE_POLICY(SET CMP0043 NEW)
|
||||
|
||||
SET(PROJ_AUTHOR Tannin)
|
||||
SET(PROJ_ARCH x86)
|
||||
IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
SET(PROJ_ARCH x64)
|
||||
ENDIF()
|
||||
|
||||
SET(organizer_SRCS
|
||||
transfersavesdialog.cpp
|
||||
syncoverwritedialog.cpp
|
||||
spawn.cpp
|
||||
singleinstance.cpp
|
||||
settingsdialog.cpp
|
||||
settings.cpp
|
||||
selfupdater.cpp
|
||||
selectiondialog.cpp
|
||||
savegameinfowidgetgamebryo.cpp
|
||||
savegameinfowidget.cpp
|
||||
savegamegamebryo.cpp
|
||||
savegame.cpp
|
||||
queryoverwritedialog.cpp
|
||||
profilesdialog.cpp
|
||||
profile.cpp
|
||||
pluginlistsortproxy.cpp
|
||||
pluginlist.cpp
|
||||
overwriteinfodialog.cpp
|
||||
nxmaccessmanager.cpp
|
||||
nexusinterface.cpp
|
||||
motddialog.cpp
|
||||
modlistsortproxy.cpp
|
||||
modlist.cpp
|
||||
modinfodialog.cpp
|
||||
modinfo.cpp
|
||||
messagedialog.cpp
|
||||
mainwindow.cpp
|
||||
main.cpp
|
||||
loghighlighter.cpp
|
||||
logbuffer.cpp
|
||||
lockeddialog.cpp
|
||||
loadmechanism.cpp
|
||||
installationmanager.cpp
|
||||
helper.cpp
|
||||
filedialogmemory.cpp
|
||||
executableslist.cpp
|
||||
editexecutablesdialog.cpp
|
||||
downloadmanager.cpp
|
||||
downloadlistwidgetcompact.cpp
|
||||
downloadlistwidget.cpp
|
||||
downloadlistsortproxy.cpp
|
||||
downloadlist.cpp
|
||||
directoryrefresher.cpp
|
||||
credentialsdialog.cpp
|
||||
categoriesdialog.cpp
|
||||
categories.cpp
|
||||
bbcode.cpp
|
||||
activatemodsdialog.cpp
|
||||
moapplication.cpp
|
||||
profileinputdialog.cpp
|
||||
icondelegate.cpp
|
||||
gameinfoimpl.cpp
|
||||
csvbuilder.cpp
|
||||
savetextasdialog.cpp
|
||||
qtgroupingproxy.cpp
|
||||
modlistview.cpp
|
||||
problemsdialog.cpp
|
||||
serverinfo.cpp
|
||||
browserview.cpp
|
||||
browserdialog.cpp
|
||||
persistentcookiejar.cpp
|
||||
noeditdelegate.cpp
|
||||
previewgenerator.cpp
|
||||
previewdialog.cpp
|
||||
aboutdialog.cpp
|
||||
json.cpp
|
||||
safewritefile.cpp
|
||||
modflagicondelegate.cpp
|
||||
genericicondelegate.cpp
|
||||
organizerproxy.cpp
|
||||
viewmarkingscrollbar.cpp
|
||||
plugincontainer.cpp
|
||||
organizercore.cpp
|
||||
usvfsconnector.cpp
|
||||
|
||||
shared/inject.cpp
|
||||
shared/windows_error.cpp
|
||||
shared/error_report.cpp
|
||||
shared/directoryentry.cpp
|
||||
shared/gameinfo.cpp
|
||||
shared/oblivioninfo.cpp
|
||||
shared/fallout3info.cpp
|
||||
shared/fallout4info.cpp
|
||||
shared/falloutnvinfo.cpp
|
||||
shared/util.cpp
|
||||
shared/skyriminfo.cpp
|
||||
shared/appconfig.cpp
|
||||
shared/leaktrace.cpp
|
||||
shared/stackdata.cpp
|
||||
)
|
||||
|
||||
SET(organizer_HDRS
|
||||
transfersavesdialog.h
|
||||
syncoverwritedialog.h
|
||||
spawn.h
|
||||
singleinstance.h
|
||||
settingsdialog.h
|
||||
settings.h
|
||||
selfupdater.h
|
||||
selectiondialog.h
|
||||
savegameinfowidgetgamebryo.h
|
||||
savegameinfowidget.h
|
||||
savegamegamebyro.h
|
||||
savegame.h
|
||||
queryoverwritedialog.h
|
||||
profilesdialog.h
|
||||
profile.h
|
||||
pluginlistsortproxy.h
|
||||
pluginlist.h
|
||||
overwriteinfodialog.h
|
||||
nxmaccessmanager.h
|
||||
nexusinterface.h
|
||||
motddialog.h
|
||||
modlistsortproxy.h
|
||||
modlist.h
|
||||
modinfodialog.h
|
||||
modinfo.h
|
||||
messagedialog.h
|
||||
mainwindow.h
|
||||
loghighlighter.h
|
||||
logbuffer.h
|
||||
lockeddialog.h
|
||||
loadmechanism.h
|
||||
installationmanager.h
|
||||
helper.h
|
||||
filedialogmemory.h
|
||||
executableslist.h
|
||||
editexecutablesdialog.h
|
||||
downloadmanager.h
|
||||
downloadlistwidgetcompact.h
|
||||
downloadlistwidget.h
|
||||
downloadlistsortproxy.h
|
||||
downloadlist.h
|
||||
directoryrefresher.h
|
||||
credentialsdialog.h
|
||||
categoriesdialog.h
|
||||
categories.h
|
||||
bbcode.h
|
||||
activatemodsdialog.h
|
||||
moapplication.h
|
||||
profileinputdialog.h
|
||||
icondelegate.h
|
||||
gameinfoimpl.h
|
||||
csvbuilder.h
|
||||
savetextasdialog.h
|
||||
qtgroupingproxy.h
|
||||
modlistview.h
|
||||
problemsdialog.h
|
||||
serverinfo.h
|
||||
browserview.h
|
||||
browserdialog.h
|
||||
persistentcookiejar.h
|
||||
noeditdelegate.h
|
||||
previewgenerator.h
|
||||
previewdialog.h
|
||||
aboutdialog.h
|
||||
json.h
|
||||
safewritefile.h
|
||||
modflagicondelegate.h
|
||||
genericicondelegate.h
|
||||
organizerproxy.h
|
||||
viewmarkingscrollbar.h
|
||||
plugincontainer.h
|
||||
organizercore.h
|
||||
iuserinterface.h
|
||||
usvfsconnector.h
|
||||
|
||||
shared/inject.h
|
||||
shared/windows_error.h
|
||||
shared/error_report.h
|
||||
shared/directoryentry.h
|
||||
shared/gameinfo.h
|
||||
shared/oblivioninfo.h
|
||||
shared/fallout3info.h
|
||||
shared/fallout4info.h
|
||||
shared/falloutnvinfo.h
|
||||
shared/util.h
|
||||
shared/skyriminfo.h
|
||||
shared/appconfig.h
|
||||
shared/appconfig.inc
|
||||
shared/leaktrace.h
|
||||
shared/stackdata.h
|
||||
)
|
||||
|
||||
SET(organizer_UIS
|
||||
transfersavesdialog.ui
|
||||
syncoverwritedialog.ui
|
||||
simpleinstalldialog.ui
|
||||
settingsdialog.ui
|
||||
selectiondialog.ui
|
||||
savegameinfowidget.ui
|
||||
queryoverwritedialog.ui
|
||||
profilesdialog.ui
|
||||
overwriteinfodialog.ui
|
||||
motddialog.ui
|
||||
modinfodialog.ui
|
||||
messagedialog.ui
|
||||
mainwindow.ui
|
||||
lockeddialog.ui
|
||||
installdialog.ui
|
||||
finddialog.ui
|
||||
editexecutablesdialog.ui
|
||||
downloadlistwidgetcompact.ui
|
||||
downloadlistwidget.ui
|
||||
credentialsdialog.ui
|
||||
categoriesdialog.ui
|
||||
activatemodsdialog.ui
|
||||
profileinputdialog.ui
|
||||
savetextasdialog.ui
|
||||
problemsdialog.ui
|
||||
previewdialog.ui
|
||||
browserdialog.ui
|
||||
aboutdialog.ui
|
||||
)
|
||||
|
||||
SET(organizer_QRCS
|
||||
resources.qrc
|
||||
stylesheet_resource.qrc
|
||||
)
|
||||
|
||||
SET(organizer_RCS
|
||||
app_icon.rc
|
||||
version.rc
|
||||
)
|
||||
|
||||
|
||||
SOURCE_GROUP(Source FILES ${organizer_SRCS})
|
||||
SOURCE_GROUP(Headers FILES ${organizer_HDRS})
|
||||
SOURCE_GROUP(UI FILES ${organizer_UIS})
|
||||
|
||||
|
||||
# Qt5
|
||||
SET(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
SET(CMAKE_AUTOMOC ON)
|
||||
SET(CMAKE_AUTOUIC ON)
|
||||
FIND_PACKAGE(Qt5Widgets REQUIRED)
|
||||
FIND_PACKAGE(Qt5Declarative REQUIRED)
|
||||
FIND_PACKAGE(Qt5Network REQUIRED)
|
||||
FIND_PACKAGE(Qt5WinExtras REQUIRED)
|
||||
FIND_PACKAGE(Qt5WebKitWidgets REQUIRED)
|
||||
QT5_WRAP_UI(organizer_UIHDRS ${organizer_UIS})
|
||||
QT5_ADD_RESOURCES(organizer_RCCPPS ${organizer_QRCS})
|
||||
|
||||
INCLUDE_DIRECTORIES(${Qt5Declarative_INCLUDES})
|
||||
|
||||
ADD_DEFINITIONS(-DQT_MESSAGELOGCONTEXT)
|
||||
|
||||
# Boost
|
||||
SET(Boost_USE_STATIC_LIBS ON)
|
||||
SET(Boost_USE_MULTITHREADED ON)
|
||||
SET(Boost_USE_STATIC_RUNTIME OFF)
|
||||
FIND_PACKAGE(Boost REQUIRED)
|
||||
|
||||
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
|
||||
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")
|
||||
SET(lib_path "${project_path}/../../install/libs")
|
||||
|
||||
|
||||
MESSAGE(STATUS ${lib_path})
|
||||
MESSAGE(STATUS ${project_path})
|
||||
|
||||
INCLUDE_DIRECTORIES(${project_path}/uibase/src
|
||||
${project_path}/bsatk/src
|
||||
${project_path}/esptk/src
|
||||
${project_path}/archive/src
|
||||
${project_path}/../usvfs/usvfs
|
||||
${project_path}/game_features/src)
|
||||
|
||||
INCLUDE_DIRECTORIES(shared ${ZLIB_INCLUDE_DIRS})
|
||||
LINK_DIRECTORIES(${lib_path}
|
||||
${project_path}/../zlib/lib)
|
||||
|
||||
ADD_DEFINITIONS(-D_UNICODE -DUNICODE -DNOMINMAX -D_CRT_SECURE_NO_WARNINGS)
|
||||
|
||||
IF("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
|
||||
SET(usvfs_name usvfs_x64)
|
||||
ELSE()
|
||||
SET(usvfs_name usvfs_x86)
|
||||
ENDIF()
|
||||
|
||||
ADD_EXECUTABLE(ModOrganizer WIN32 ${organizer_HDRS} ${organizer_SRCS} ${organizer_UIHDRS} ${organizer_RCS} ${organizer_RCCPPS})
|
||||
TARGET_LINK_LIBRARIES(ModOrganizer
|
||||
Qt5::Widgets Qt5::WinExtras Qt5::WebKitWidgets
|
||||
${Boost_LIBRARIES}
|
||||
zlibstatic
|
||||
uibase esptk bsatk
|
||||
${usvfs_name}
|
||||
Dbghelp advapi32 Version Shlwapi)
|
||||
|
||||
SET_TARGET_PROPERTIES(ModOrganizer PROPERTIES COMPILE_FLAGS /GL)
|
||||
SET_TARGET_PROPERTIES(ModOrganizer PROPERTIES LINK_FLAGS_RELWITHDEBINFO
|
||||
"/LTCG /INCREMENTAL:NO /LARGEADDRESSAWARE /OPT:REF /OPT:ICF")
|
||||
|
||||
|
||||
QT5_USE_MODULES(ModOrganizer Widgets Declarative Network WebKitWidgets)
|
||||
|
||||
|
||||
###############
|
||||
## Installation
|
||||
|
||||
SET(qt5bin ${Qt5Core_DIR}/../../../bin)
|
||||
|
||||
FIND_PROGRAM(WINDEPLOYQT_COMMAND windeployqt PATHS ${qt5bin} NO_DEFAULT_PATH)
|
||||
|
||||
INSTALL(TARGETS ModOrganizer
|
||||
RUNTIME DESTINATION bin)
|
||||
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/ModOrganizer.pdb
|
||||
DESTINATION pdb)
|
||||
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/dlls.manifest.qt5
|
||||
DESTINATION bin/dlls
|
||||
RENAME dlls.manifest)
|
||||
|
||||
# use windeployqt.exe to install all required libraries
|
||||
SET(windeploy_parameters --no-translations --no-plugins --libdir dlls --release-with-debug-info --no-compiler-runtime)
|
||||
INSTALL(
|
||||
CODE
|
||||
"EXECUTE_PROCESS(
|
||||
COMMAND
|
||||
${qt5bin}/windeployqt.exe ModOrganizer.exe ${windeploy_parameters}
|
||||
COMMAND
|
||||
${qt5bin}/windeployqt.exe uibase.dll ${windeploy_parameters}
|
||||
WORKING_DIRECTORY ${CMAKE_INSTALL_PREFIX}/bin
|
||||
)"
|
||||
)
|
||||
|
||||
INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/stylesheets
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tutorials
|
||||
DESTINATION bin)
|
||||
@@ -3,6 +3,7 @@ TEMPLATE = subdirs
|
||||
SUBDIRS = bsatk \
|
||||
shared \
|
||||
uibase \
|
||||
esptk \
|
||||
organizer \
|
||||
hookdll \
|
||||
archive \
|
||||
@@ -11,8 +12,7 @@ SUBDIRS = bsatk \
|
||||
nxmhandler \
|
||||
BossDummy \
|
||||
pythonRunner \
|
||||
loot_cli \
|
||||
esptk
|
||||
loot_cli
|
||||
|
||||
pythonRunner.depends = uibase
|
||||
plugins.depends = pythonRunner uibase
|
||||
|
||||
+48
-6
@@ -1,6 +1,43 @@
|
||||
import ctypes
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
def resolve_name(source):
|
||||
# Get the actual name of the file, after reparse points and symlinks are
|
||||
# taken into account.
|
||||
GENERIC_READ = 0x80000000
|
||||
FILE_SHARE_READ = 0x1
|
||||
OPEN_EXISTING = 0x3
|
||||
FILE_FLAG_BACKUP_SEMANTICS = 0x02000000
|
||||
handle = ctypes.windll.kernel32.CreateFileA(source,
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ,
|
||||
None,
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS,
|
||||
None)
|
||||
# get the target
|
||||
FILE_NAME_NORMALIZED = 0x0
|
||||
FILE_NAME_OPENED = 0x8
|
||||
buff = ctypes.create_string_buffer(1024)
|
||||
res = ctypes.windll.kernel32.GetFinalPathNameByHandleA(handle,
|
||||
buff,
|
||||
ctypes.sizeof(buff),
|
||||
FILE_NAME_NORMALIZED)
|
||||
target = buff.value
|
||||
ctypes.windll.kernel32.CloseHandle(handle)
|
||||
return target
|
||||
|
||||
def search_up(path, target):
|
||||
while True:
|
||||
if os.path.exists(os.path.join(path, target)):
|
||||
return True
|
||||
npath = os.path.dirname(path)
|
||||
if npath == path:
|
||||
break
|
||||
path = npath
|
||||
return False
|
||||
|
||||
Import('qt_env')
|
||||
|
||||
env = qt_env.Clone()
|
||||
@@ -47,16 +84,12 @@ env.AppendUnique(LIBS = [
|
||||
other_sources = env.AddExtraMoc(env.Glob('*.h'))
|
||||
|
||||
for file in env.Glob('*.rc'):
|
||||
# version.rc is included in app_icon.rc. Not sure why it's a separate file.
|
||||
if file.name == 'version.rc':
|
||||
continue
|
||||
other_sources.append(env.RES(file))
|
||||
|
||||
# Note the order of this is important, or you can pick up the wrong report.h...
|
||||
# Doing appendunique seems to throw the moc code into a tizzy
|
||||
env['CPPPATH'] += [
|
||||
'../archive',
|
||||
# '../boss_modified/boss-api',
|
||||
'../plugins/gamefeatures',
|
||||
'.', # Why is this necessary?
|
||||
'${LOOTPATH}',
|
||||
@@ -86,10 +119,19 @@ cpp_files = [
|
||||
]
|
||||
|
||||
about_env = env.Clone()
|
||||
# This is somewhat of a hack until I can work out a way of setting up a build
|
||||
# with all the repos without using millions of junction points
|
||||
try:
|
||||
hgid = subprocess.check_output(['hg', 'id', '-i']).rstrip()
|
||||
target = resolve_name(Dir('.').srcnode().abspath)
|
||||
if search_up(target, '.hg'):
|
||||
hgid = subprocess.check_output([env['MERCURIAL'], 'id', '-i']).rstrip()
|
||||
elif search_up(target, '.git'):
|
||||
hgid = subprocess.check_output([env['GIT'], '-C', target, 'describe',
|
||||
'--tag']).rstrip()
|
||||
else:
|
||||
hgid = "Unknown"
|
||||
except:
|
||||
hgid = 'Unknown version'
|
||||
hgid = "Problem determining version"
|
||||
|
||||
# FIXME: It'd be much easier to stringify this in the source code
|
||||
about_env.AppendUnique(CPPDEFINES = [ 'HGID=\\"%s\\"' % hgid ])
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ AboutDialog::AboutDialog(const QString &version, QWidget *parent)
|
||||
m_LicenseFiles[LICENSE_ZLIB] = "zlib.txt";
|
||||
m_LicenseFiles[LICENSE_APACHE2] = "apache-license-2.0.txt";
|
||||
|
||||
addLicense("Qt 5.4", LICENSE_LGPL3);
|
||||
addLicense("Qt", LICENSE_LGPL3);
|
||||
addLicense("Qt Json", LICENSE_GPL3);
|
||||
addLicense("Boost Library", LICENSE_BOOST);
|
||||
addLicense("7-zip", LICENSE_LGPL3);
|
||||
|
||||
+13
-7
@@ -46,7 +46,7 @@
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>2</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="about">
|
||||
<attribute name="title">
|
||||
@@ -83,14 +83,14 @@
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string notr="true">Copyright 2011-2014 Sebastian Herbord</string>
|
||||
<string notr="true">Copyright 2011-2015 Sebastian Herbord</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string notr="true"><html><head/><body><p>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.</p><p>See the GNU General Public License for more details.</p></body></html></string>
|
||||
<string notr="true"><html><head/><body><p>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.</p><p>See the GNU General Public License for more details.</p><p>Source code can be found at <a href="https://github.com/TanninOne/modorganizer"><span style=" text-decoration: underline; color:#007af4;">GitHub</span></a>.</p></body></html></string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
@@ -180,13 +180,19 @@
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Ren (Korean)</string>
|
||||
<string notr="true">Ren (Korean)</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>... more (Can't track)</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -226,12 +232,12 @@
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>GamerPoet</string>
|
||||
<string notr="true">GamerPoet</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Gopher</string>
|
||||
<string notr="true">Gopher</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
@@ -256,7 +262,7 @@
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>thosrtanner</string>
|
||||
<string notr="true">thosrtanner</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
|
||||
+1
-3
@@ -1,3 +1 @@
|
||||
#include "version.rc"
|
||||
|
||||
IDI_ICON1 ICON DISCARDABLE "mo_icon.ico"
|
||||
IDI_ICON1 ICON DISCARDABLE "mo_icon.ico"
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>BainComplexInstallerDialog</class>
|
||||
<widget class="QDialog" name="BainComplexInstallerDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>398</width>
|
||||
<height>365</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>BAIN Package Installer</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="nameEdit"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>This looks like a Package prepared for Installation through BAIN. You can select options from the list below. If there is a package.txt file, it should contain detailed information about the options.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListWidget" name="optionsList">
|
||||
<property name="toolTip">
|
||||
<string>Components of this package.</string>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string>Components of this package.
|
||||
If there is a component called "00 Core" it is usually required. Options are ordered by priority as set up by the author.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="packageBtn">
|
||||
<property name="toolTip">
|
||||
<string>The package.txt is often part of BAIN packages and contains details about the options available.</string>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string>The package.txt is often part of BAIN packages and contains details about the options available.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Package.txt</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="manualBtn">
|
||||
<property name="toolTip">
|
||||
<string>Opens a Dialog that allows custom modifications.</string>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string>Opens a Dialog that allows custom modifications.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Manual</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="okBtn">
|
||||
<property name="text">
|
||||
<string>Ok</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="cancelBtn">
|
||||
<property name="text">
|
||||
<string>Cancel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+27
-5
@@ -166,22 +166,32 @@ void CategoryFactory::saveCategories()
|
||||
unsigned int CategoryFactory::countCategories(std::tr1::function<bool (const Category &category)> filter)
|
||||
{
|
||||
unsigned int result = 0;
|
||||
for (auto iter = m_Categories.begin(); iter != m_Categories.end(); ++iter) {
|
||||
if (filter(*iter)) {
|
||||
for (const Category &cat : m_Categories) {
|
||||
if (filter(cat)) {
|
||||
++result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int CategoryFactory::addCategory(const QString &name, const std::vector<int> &nexusIDs, int parentID)
|
||||
{
|
||||
int id = 1;
|
||||
while (m_IDMap.find(id) != m_IDMap.end()) {
|
||||
++id;
|
||||
}
|
||||
addCategory(id, name, nexusIDs, parentID);
|
||||
|
||||
saveCategories();
|
||||
return id;
|
||||
}
|
||||
|
||||
void CategoryFactory::addCategory(int id, const QString &name, const std::vector<int> &nexusIDs, int parentID)
|
||||
{
|
||||
int index = m_Categories.size();
|
||||
m_Categories.push_back(Category(index, id, name, nexusIDs, parentID));
|
||||
for (std::vector<int>::const_iterator iter = nexusIDs.begin();
|
||||
iter != nexusIDs.end(); ++iter) {
|
||||
m_NexusMap[*iter] = index;
|
||||
for (int nexusID : nexusIDs) {
|
||||
m_NexusMap[nexusID] = index;
|
||||
}
|
||||
m_IDMap[id] = index;
|
||||
}
|
||||
@@ -305,6 +315,18 @@ int CategoryFactory::getCategoryIndex(int ID) const
|
||||
}
|
||||
|
||||
|
||||
int CategoryFactory::getCategoryID(const QString &name) const
|
||||
{
|
||||
auto iter = std::find_if(m_Categories.begin(), m_Categories.end(), [name] (const Category &cat) -> bool {
|
||||
return cat.m_Name == name;
|
||||
});
|
||||
if (iter != m_Categories.end()) {
|
||||
return iter->m_ID;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned int CategoryFactory::resolveNexusID(int nexusID) const
|
||||
{
|
||||
|
||||
+9
-1
@@ -80,12 +80,14 @@ public:
|
||||
**/
|
||||
void saveCategories();
|
||||
|
||||
int addCategory(const QString &name, const std::vector<int> &nexusIDs, int parentID);
|
||||
|
||||
/**
|
||||
* @brief retrieve the number of available categories
|
||||
*
|
||||
* @return unsigned int number of categories
|
||||
**/
|
||||
unsigned numCategories() const { return m_Categories.size(); }
|
||||
size_t numCategories() const { return m_Categories.size(); }
|
||||
|
||||
/**
|
||||
* @brief count all categories that match a specified filter
|
||||
@@ -142,6 +144,12 @@ public:
|
||||
**/
|
||||
int getCategoryID(unsigned int index) const;
|
||||
|
||||
/**
|
||||
* @brief look up the id of a category by its name
|
||||
* @note O(n)
|
||||
*/
|
||||
int getCategoryID(const QString &name) const;
|
||||
|
||||
/**
|
||||
* @brief look up the index of a category by its id
|
||||
*
|
||||
|
||||
@@ -76,11 +76,12 @@ void DirectoryRefresher::cleanStructure(DirectoryEntry *structure)
|
||||
}
|
||||
}
|
||||
|
||||
void DirectoryRefresher::addModBSAToStructure(DirectoryEntry *directoryStructure, const QString &modName, int priority, const QString &directory, const QStringList &archives)
|
||||
void DirectoryRefresher::addModBSAToStructure(DirectoryEntry *directoryStructure, const QString &modName,
|
||||
int priority, const QString &directory, const QStringList &archives)
|
||||
{
|
||||
std::wstring directoryW = ToWString(QDir::toNativeSeparators(directory));
|
||||
|
||||
foreach (const QString &archive, archives) {
|
||||
for (const QString &archive : archives) {
|
||||
QFileInfo fileInfo(archive);
|
||||
if (m_EnabledArchives.find(fileInfo.fileName()) != m_EnabledArchives.end()) {
|
||||
try {
|
||||
@@ -93,23 +94,27 @@ void DirectoryRefresher::addModBSAToStructure(DirectoryEntry *directoryStructure
|
||||
}
|
||||
}
|
||||
|
||||
void DirectoryRefresher::addModFilesToStructure(DirectoryEntry *directoryStructure, const QString &modName, int priority, const QString &directory, const QStringList &stealFiles)
|
||||
void DirectoryRefresher::addModFilesToStructure(DirectoryEntry *directoryStructure, const QString &modName,
|
||||
int priority, const QString &directory, const QStringList &stealFiles)
|
||||
{
|
||||
std::wstring directoryW = ToWString(QDir::toNativeSeparators(directory));
|
||||
|
||||
if (stealFiles.length() > 0) {
|
||||
// instead of adding all the files of the target directory, we just change the root of the specified
|
||||
// files to this mod
|
||||
FilesOrigin origin = directoryStructure->createOrigin(ToWString(modName), directoryW, priority);
|
||||
foreach (const QString &filename, stealFiles) {
|
||||
FilesOrigin &origin = directoryStructure->createOrigin(ToWString(modName), directoryW, priority);
|
||||
for (const QString &filename : stealFiles) {
|
||||
QFileInfo fileInfo(filename);
|
||||
FileEntry::Ptr file = directoryStructure->findFile(ToWString(fileInfo.fileName()));
|
||||
if (file.get() != nullptr) {
|
||||
if (file->getOrigin() == 0) {
|
||||
// replace data as the origin on this bsa
|
||||
file->removeOrigin(0);
|
||||
file->addOrigin(origin.getID(), file->getFileTime(), L"");
|
||||
}
|
||||
origin.addFile(file->getIndex());
|
||||
file->addOrigin(origin.getID(), file->getFileTime(), L"");
|
||||
} else {
|
||||
qWarning("%s not found", qPrintable(fileInfo.fileName()));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -86,7 +86,7 @@ private:
|
||||
|
||||
quint32 m_TaskProgressId;
|
||||
|
||||
MOBase::ModRepositoryFileInfo *m_FileInfo;
|
||||
MOBase::ModRepositoryFileInfo *m_FileInfo { nullptr };
|
||||
|
||||
bool m_Hidden;
|
||||
|
||||
|
||||
@@ -30,8 +30,10 @@ using namespace MOBase;
|
||||
using namespace MOShared;
|
||||
|
||||
EditExecutablesDialog::EditExecutablesDialog(const ExecutablesList &executablesList, QWidget *parent)
|
||||
: TutorableDialog("EditExecutables", parent),
|
||||
ui(new Ui::EditExecutablesDialog), m_CurrentItem(nullptr), m_ExecutablesList(executablesList)
|
||||
: TutorableDialog("EditExecutables", parent)
|
||||
, ui(new Ui::EditExecutablesDialog)
|
||||
, m_CurrentItem(nullptr)
|
||||
, m_ExecutablesList(executablesList)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
@@ -47,7 +49,7 @@ ExecutablesList EditExecutablesDialog::getExecutablesList() const
|
||||
{
|
||||
ExecutablesList newList;
|
||||
for (int i = 0; i < ui->executablesListBox->count(); ++i) {
|
||||
newList.addExecutable(ui->executablesListBox->item(i)->data(Qt::UserRole).value<Executable>());
|
||||
newList.addExecutable(m_ExecutablesList.find(ui->executablesListBox->item(i)->text()));
|
||||
}
|
||||
return newList;
|
||||
}
|
||||
@@ -60,10 +62,7 @@ void EditExecutablesDialog::refreshExecutablesWidget()
|
||||
|
||||
for(; current != end; ++current) {
|
||||
QListWidgetItem *newItem = new QListWidgetItem(current->m_Title);
|
||||
QVariant temp;
|
||||
temp.setValue(*current);
|
||||
newItem->setData(Qt::UserRole, temp);
|
||||
newItem->setTextColor(current->m_Custom ? QColor(Qt::black) : QColor(Qt::darkGray));
|
||||
newItem->setTextColor(current->isCustom() ? QColor(Qt::black) : QColor(Qt::darkGray));
|
||||
ui->executablesListBox->addItem(newItem);
|
||||
}
|
||||
|
||||
@@ -72,9 +71,9 @@ void EditExecutablesDialog::refreshExecutablesWidget()
|
||||
}
|
||||
|
||||
|
||||
void EditExecutablesDialog::on_binaryEdit_textChanged(const QString &arg1)
|
||||
void EditExecutablesDialog::on_binaryEdit_textChanged(const QString &name)
|
||||
{
|
||||
QFileInfo fileInfo(arg1);
|
||||
QFileInfo fileInfo(name);
|
||||
ui->addButton->setEnabled(fileInfo.exists() && fileInfo.isFile());
|
||||
}
|
||||
|
||||
@@ -87,33 +86,43 @@ void EditExecutablesDialog::resetInput()
|
||||
ui->appIDOverwriteEdit->clear();
|
||||
ui->overwriteAppIDBox->setChecked(false);
|
||||
ui->closeCheckBox->setChecked(false);
|
||||
ui->useAppIconCheckBox->setChecked(false);
|
||||
m_CurrentItem = nullptr;
|
||||
}
|
||||
|
||||
|
||||
void EditExecutablesDialog::saveExecutable()
|
||||
{
|
||||
m_ExecutablesList.addExecutable(ui->titleEdit->text(), QDir::fromNativeSeparators(ui->binaryEdit->text()),
|
||||
ui->argumentsEdit->text(), QDir::fromNativeSeparators(ui->workingDirEdit->text()),
|
||||
(ui->closeCheckBox->checkState() == Qt::Checked) ? ExecutableInfo::CloseMOStyle::DEFAULT_CLOSE
|
||||
: ExecutableInfo::CloseMOStyle::DEFAULT_STAY,
|
||||
ui->overwriteAppIDBox->isChecked() ? ui->appIDOverwriteEdit->text() : "",
|
||||
true, false);
|
||||
}
|
||||
m_ExecutablesList.updateExecutable(ui->titleEdit->text(),
|
||||
QDir::fromNativeSeparators(ui->binaryEdit->text()),
|
||||
ui->argumentsEdit->text(),
|
||||
QDir::fromNativeSeparators(ui->workingDirEdit->text()),
|
||||
(ui->closeCheckBox->checkState() == Qt::Checked) ?
|
||||
ExecutableInfo::CloseMOStyle::DEFAULT_CLOSE
|
||||
: ExecutableInfo::CloseMOStyle::DEFAULT_STAY,
|
||||
ui->overwriteAppIDBox->isChecked() ?
|
||||
ui->appIDOverwriteEdit->text() : "",
|
||||
Executable::UseApplicationIcon | Executable::CustomExecutable,
|
||||
(ui->useAppIconCheckBox->isChecked() ?
|
||||
Executable::UseApplicationIcon : Executable::Flags())
|
||||
| Executable::CustomExecutable);
|
||||
}
|
||||
|
||||
|
||||
void EditExecutablesDialog::delayedRefresh()
|
||||
{
|
||||
int index = ui->executablesListBox->currentIndex().row();
|
||||
QModelIndex index = ui->executablesListBox->currentIndex();
|
||||
resetInput();
|
||||
refreshExecutablesWidget();
|
||||
ui->executablesListBox->setCurrentRow(index);
|
||||
on_executablesListBox_clicked(index);
|
||||
}
|
||||
|
||||
|
||||
void EditExecutablesDialog::on_addButton_clicked()
|
||||
{
|
||||
saveExecutable();
|
||||
if (executableChanged()) {
|
||||
saveExecutable();
|
||||
}
|
||||
|
||||
resetInput();
|
||||
refreshExecutablesWidget();
|
||||
@@ -170,8 +179,6 @@ void EditExecutablesDialog::on_browseDirButton_clicked()
|
||||
|
||||
void EditExecutablesDialog::on_removeButton_clicked()
|
||||
{
|
||||
// QLineEdit *binaryEdit = findChild<QLineEdit*>("binaryEdit");
|
||||
|
||||
if (QMessageBox::question(this, tr("Confirm"), tr("Really remove \"%1\" from executables?").arg(ui->titleEdit->text()),
|
||||
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
|
||||
m_ExecutablesList.remove(ui->titleEdit->text());
|
||||
@@ -206,15 +213,19 @@ void EditExecutablesDialog::on_titleEdit_textChanged(const QString &arg1)
|
||||
bool EditExecutablesDialog::executableChanged()
|
||||
{
|
||||
if (m_CurrentItem != nullptr) {
|
||||
const Executable &selectedExecutable = m_CurrentItem->data(Qt::UserRole).value<Executable>();
|
||||
|
||||
Executable const &selectedExecutable(m_ExecutablesList.find(m_CurrentItem->text()));
|
||||
return selectedExecutable.m_Arguments != ui->argumentsEdit->text()
|
||||
|| selectedExecutable.m_SteamAppID != ui->appIDOverwriteEdit->text()
|
||||
|| selectedExecutable.m_WorkingDirectory != QDir::fromNativeSeparators(ui->workingDirEdit->text())
|
||||
|| selectedExecutable.m_BinaryInfo.absoluteFilePath() != QDir::fromNativeSeparators(ui->binaryEdit->text())
|
||||
|| (selectedExecutable.m_CloseMO == ExecutableInfo::CloseMOStyle::DEFAULT_CLOSE) != ui->closeCheckBox->isChecked();
|
||||
|| (selectedExecutable.m_CloseMO == ExecutableInfo::CloseMOStyle::DEFAULT_CLOSE) != ui->closeCheckBox->isChecked()
|
||||
|| selectedExecutable.usesOwnIcon() != ui->useAppIconCheckBox->isChecked();
|
||||
} else {
|
||||
return false;
|
||||
QFileInfo fileInfo(ui->binaryEdit->text());
|
||||
return !ui->binaryEdit->text().isEmpty()
|
||||
&& !ui->titleEdit->text().isEmpty()
|
||||
&& fileInfo.exists()
|
||||
&& fileInfo.isFile();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,27 +263,29 @@ void EditExecutablesDialog::on_closeButton_clicked()
|
||||
void EditExecutablesDialog::on_executablesListBox_clicked(const QModelIndex ¤t)
|
||||
{
|
||||
if (current.isValid()) {
|
||||
ui->executablesListBox->selectionModel()->clearSelection();
|
||||
ui->executablesListBox->selectionModel()->select(current, QItemSelectionModel::SelectCurrent);
|
||||
|
||||
if (executableChanged()) {
|
||||
QMessageBox::StandardButton res = QMessageBox::question(this, tr("Save Changes?"),
|
||||
tr("You made changes to the current executable, do you want to save them?"),
|
||||
QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
|
||||
if (res == QMessageBox::Cancel) {
|
||||
return;
|
||||
} else if (res == QMessageBox::Yes) {
|
||||
// this invalidates the item passed as a a parameter
|
||||
QMessageBox::Yes | QMessageBox::No);
|
||||
if (res == QMessageBox::Yes) {
|
||||
saveExecutable();
|
||||
|
||||
//This is necessary if we're adding a new item, but it doesn't look very nice.
|
||||
//Ideally we'd end up with the correct row displayed
|
||||
ui->executablesListBox->selectionModel()->clearSelection();
|
||||
ui->executablesListBox->selectionModel()->select(current, QItemSelectionModel::SelectCurrent);
|
||||
QTimer::singleShot(50, this, SLOT(delayedRefresh()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ui->executablesListBox->selectionModel()->clearSelection();
|
||||
ui->executablesListBox->selectionModel()->select(current, QItemSelectionModel::SelectCurrent);
|
||||
|
||||
m_CurrentItem = ui->executablesListBox->item(current.row());
|
||||
|
||||
const Executable &selectedExecutable = m_CurrentItem->data(Qt::UserRole).value<Executable>();
|
||||
Executable const &selectedExecutable(m_ExecutablesList.find(m_CurrentItem->text()));
|
||||
|
||||
ui->titleEdit->setText(selectedExecutable.m_Title);
|
||||
ui->binaryEdit->setText(QDir::toNativeSeparators(selectedExecutable.m_BinaryInfo.absoluteFilePath()));
|
||||
@@ -286,12 +299,13 @@ void EditExecutablesDialog::on_executablesListBox_clicked(const QModelIndex &cur
|
||||
ui->closeCheckBox->setEnabled(true);
|
||||
ui->closeCheckBox->setToolTip(tr("If checked, MO will be closed once the specified executable is run."));
|
||||
}
|
||||
ui->removeButton->setEnabled(selectedExecutable.m_Custom);
|
||||
ui->removeButton->setEnabled(selectedExecutable.isCustom());
|
||||
ui->overwriteAppIDBox->setChecked(!selectedExecutable.m_SteamAppID.isEmpty());
|
||||
if (!selectedExecutable.m_SteamAppID.isEmpty()) {
|
||||
ui->appIDOverwriteEdit->setText(selectedExecutable.m_SteamAppID);
|
||||
} else {
|
||||
ui->appIDOverwriteEdit->clear();
|
||||
}
|
||||
ui->useAppIconCheckBox->setChecked(selectedExecutable.usesOwnIcon());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>384</width>
|
||||
<height>362</height>
|
||||
<height>446</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -26,7 +26,7 @@
|
||||
<enum>QAbstractItemView::InternalMove</enum>
|
||||
</property>
|
||||
<property name="defaultDropAction">
|
||||
<enum>Qt::MoveAction</enum>
|
||||
<enum>Qt::TargetMoveAction</enum>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||
@@ -164,21 +164,28 @@ Right now the only case I know of where this needs to be overwritten is for the
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="closeCheckBox">
|
||||
<property name="toolTip">
|
||||
<string>If checked, MO will be closed once the specified executable is run.</string>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string>If checked, MO will be closed once the specified executable is run.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Close MO when started</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="useAppIconCheckBox">
|
||||
<property name="text">
|
||||
<string>Use Application's Icon for shortcuts</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="closeCheckBox">
|
||||
<property name="toolTip">
|
||||
<string>If checked, MO will be closed once the specified executable is run.</string>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string>If checked, MO will be closed once the specified executable is run.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Close MO when started</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="addButton">
|
||||
<property name="toolTip">
|
||||
@@ -240,6 +247,10 @@ Right now the only case I know of where this needs to be overwritten is for the
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
<zorder>executablesListBox</zorder>
|
||||
<zorder>closeButton</zorder>
|
||||
<zorder>closeCheckBox</zorder>
|
||||
<zorder>useAppIconCheckBox</zorder>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
||||
+37
-74
@@ -30,39 +30,6 @@ using namespace MOBase;
|
||||
using namespace MOShared;
|
||||
|
||||
|
||||
static QDataStream &operator<<(QDataStream &out, const Executable &obj)
|
||||
{
|
||||
out << obj.m_Title
|
||||
<< obj.m_BinaryInfo.absoluteFilePath()
|
||||
<< obj.m_Arguments
|
||||
<< static_cast<std::underlying_type<ExecutableInfo::CloseMOStyle>::type>(obj.m_CloseMO)
|
||||
<< obj.m_SteamAppID
|
||||
<< obj.m_WorkingDirectory
|
||||
<< obj.m_Custom
|
||||
<< obj.m_Toolbar;
|
||||
return out;
|
||||
}
|
||||
|
||||
static QDataStream &operator>>(QDataStream &in, Executable &obj)
|
||||
{
|
||||
QString binaryTemp;
|
||||
int closeStyleTemp;
|
||||
in >> obj.m_Title >> binaryTemp >> obj.m_Arguments >> closeStyleTemp
|
||||
>> obj.m_SteamAppID >> obj.m_WorkingDirectory >> obj.m_Custom >> obj.m_Toolbar;
|
||||
|
||||
obj.m_CloseMO = static_cast<ExecutableInfo::CloseMOStyle>(closeStyleTemp);
|
||||
obj.m_BinaryInfo.setFile(binaryTemp);
|
||||
return in;
|
||||
}
|
||||
|
||||
|
||||
void registerExecutable()
|
||||
{
|
||||
qRegisterMetaType<Executable>("Executable");
|
||||
qRegisterMetaTypeStreamOperators<Executable>("Executable");
|
||||
}
|
||||
|
||||
|
||||
ExecutablesList::ExecutablesList()
|
||||
{
|
||||
}
|
||||
@@ -102,23 +69,23 @@ void ExecutablesList::getExecutables(std::vector<Executable>::const_iterator &be
|
||||
|
||||
const Executable &ExecutablesList::find(const QString &title) const
|
||||
{
|
||||
for (std::vector<Executable>::const_iterator iter = m_Executables.begin(); iter != m_Executables.end(); ++iter) {
|
||||
if (iter->m_Title == title) {
|
||||
return *iter;
|
||||
for (Executable const &exe : m_Executables) {
|
||||
if (exe.m_Title == title) {
|
||||
return exe;
|
||||
}
|
||||
}
|
||||
throw std::runtime_error("invalid name");
|
||||
throw std::runtime_error(QString("invalid name %1").arg(title).toLocal8Bit().constData());
|
||||
}
|
||||
|
||||
|
||||
Executable &ExecutablesList::find(const QString &title)
|
||||
{
|
||||
for (Executable &exe : m_Executables) {
|
||||
if (QString::compare(exe.m_Title, title, Qt::CaseInsensitive) == 0) {
|
||||
if (exe.m_Title == title) {
|
||||
return exe;
|
||||
}
|
||||
}
|
||||
throw std::runtime_error("invalid name");
|
||||
throw std::runtime_error(QString("invalid name %1").arg(title).toLocal8Bit().constData());
|
||||
}
|
||||
|
||||
|
||||
@@ -162,42 +129,34 @@ void ExecutablesList::addExecutable(const Executable &executable)
|
||||
}
|
||||
|
||||
|
||||
void ExecutablesList::position(const QString &title, bool toolbar, int pos)
|
||||
{
|
||||
auto existingExe = findExe(title);
|
||||
if (existingExe != m_Executables.end()) {
|
||||
Executable temp = *existingExe;
|
||||
temp.m_Toolbar = toolbar;
|
||||
m_Executables.erase(existingExe);
|
||||
m_Executables.insert(m_Executables.begin() + pos, temp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ExecutablesList::addExecutable(const QString &title, const QString &executableName, const QString &arguments,
|
||||
const QString &workingDirectory, ExecutableInfo::CloseMOStyle closeMO, const QString &steamAppID,
|
||||
bool custom, bool toolbar, int pos)
|
||||
void ExecutablesList::updateExecutable(const QString &title,
|
||||
const QString &executableName,
|
||||
const QString &arguments,
|
||||
const QString &workingDirectory,
|
||||
ExecutableInfo::CloseMOStyle closeMO,
|
||||
const QString &steamAppID,
|
||||
Executable::Flags mask,
|
||||
Executable::Flags flags)
|
||||
{
|
||||
QFileInfo file(executableName);
|
||||
auto existingExe = findExe(title);
|
||||
flags &= mask;
|
||||
|
||||
if (existingExe != m_Executables.end()) {
|
||||
existingExe->m_Title = title;
|
||||
existingExe->m_Custom = custom;
|
||||
existingExe->m_CloseMO = closeMO;
|
||||
existingExe->m_Toolbar = toolbar;
|
||||
if (custom) {
|
||||
// for pre-configured executables don't overwrite settings we didn't store
|
||||
existingExe->m_BinaryInfo = file;
|
||||
existingExe->m_Flags &= ~mask;
|
||||
existingExe->m_Flags |= flags;
|
||||
// for pre-configured executables don't overwrite settings we didn't store
|
||||
if (flags & Executable::CustomExecutable) {
|
||||
if (file.exists()) {
|
||||
// don't overwrite a valid binary with an invalid one
|
||||
existingExe->m_BinaryInfo = file;
|
||||
}
|
||||
existingExe->m_Arguments = arguments;
|
||||
existingExe->m_WorkingDirectory = workingDirectory;
|
||||
existingExe->m_SteamAppID = steamAppID;
|
||||
}
|
||||
if (pos >= 0) {
|
||||
Executable temp = *existingExe;
|
||||
m_Executables.erase(existingExe);
|
||||
m_Executables.insert(m_Executables.begin() + pos, temp);
|
||||
}
|
||||
} else {
|
||||
Executable newExe;
|
||||
newExe.m_Title = title;
|
||||
@@ -206,13 +165,8 @@ void ExecutablesList::addExecutable(const QString &title, const QString &executa
|
||||
newExe.m_Arguments = arguments;
|
||||
newExe.m_WorkingDirectory = workingDirectory;
|
||||
newExe.m_SteamAppID = steamAppID;
|
||||
newExe.m_Custom = true;
|
||||
newExe.m_Toolbar = toolbar;
|
||||
if ((pos < 0) || (pos >= static_cast<int>(m_Executables.size()))) {
|
||||
m_Executables.push_back(newExe);
|
||||
} else {
|
||||
m_Executables.insert(m_Executables.begin() + pos, newExe);
|
||||
}
|
||||
newExe.m_Flags = Executable::CustomExecutable | flags;
|
||||
m_Executables.push_back(newExe);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,7 +174,7 @@ void ExecutablesList::addExecutable(const QString &title, const QString &executa
|
||||
void ExecutablesList::remove(const QString &title)
|
||||
{
|
||||
for (std::vector<Executable>::iterator iter = m_Executables.begin(); iter != m_Executables.end(); ++iter) {
|
||||
if (iter->m_Custom && (iter->m_Title == title)) {
|
||||
if (iter->isCustom() && (iter->m_Title == title)) {
|
||||
m_Executables.erase(iter);
|
||||
break;
|
||||
}
|
||||
@@ -241,8 +195,17 @@ void ExecutablesList::addExecutableInternal(const QString &title, const QString
|
||||
newExe.m_Arguments = arguments;
|
||||
newExe.m_WorkingDirectory = workingDirectory;
|
||||
newExe.m_SteamAppID = steamAppID;
|
||||
newExe.m_Custom = false;
|
||||
newExe.m_Toolbar = false;
|
||||
newExe.m_Flags = 0;
|
||||
m_Executables.push_back(newExe);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Executable::showOnToolbar(bool state)
|
||||
{
|
||||
if (state) {
|
||||
m_Flags |= ShowInToolbar;
|
||||
} else {
|
||||
m_Flags &= ~ShowInToolbar;
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user