mirror of
https://github.com/ModOrganizer2/modorganizer.git
synced 2026-07-27 13:58:24 -07:00
Move to VCPKG.
* Remove SConscript related files. * Update for libbsarch. * Force-load translations from uibase and gamebryo/creation. * Set option to use deprecated uibase include paths. * Bring githubpp here and add a standalone preset. * Full standalone build.
This commit is contained in:
@@ -6,15 +6,47 @@ on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
env:
|
||||
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: windows-2022
|
||||
steps:
|
||||
- name: Build ModOrganizer 2
|
||||
uses: ModOrganizer2/build-with-mob-action@master
|
||||
# https://learn.microsoft.com/en-us/vcpkg/consume/binary-caching-github-actions-cache
|
||||
- name: Export GitHub Actions cache environment variables
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
qt-modules: qtpositioning qtwebchannel qtwebengine qtwebsockets
|
||||
mo2-third-parties:
|
||||
7z zlib gtest libbsarch libloot openssl bzip2 python lz4 spdlog
|
||||
boost boost-di sip pyqt pybind11 ss licenses explorerpp DirectXTex
|
||||
mo2-dependencies: usvfs cmake_common uibase githubpp bsatk esptk archive lootcli game_gamebryo
|
||||
script: |
|
||||
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
|
||||
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
||||
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: 6.7.0
|
||||
modules:
|
||||
cache: true
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: "Set environmental variables"
|
||||
shell: bash
|
||||
run: |
|
||||
echo "VCPKG_ROOT=$VCPKG_INSTALLATION_ROOT" >> $GITHUB_ENV
|
||||
|
||||
- name: Configure ModOrganizer
|
||||
shell: pwsh
|
||||
run: |
|
||||
cmake --preset vs2022-windows-standalone `
|
||||
"-DCMAKE_PREFIX_PATH=${env:QT_ROOT_DIR}\msvc2019_64" `
|
||||
"-DCMAKE_INSTALL_PREFIX=install"
|
||||
|
||||
- name: Build ModOrganizer
|
||||
run: cmake --build vsbuild --config RelWithDebInfo --target INSTALL
|
||||
|
||||
- name: Package ModOrganizer
|
||||
uses: actions/upload-artifact@master
|
||||
with:
|
||||
name: modorganizer
|
||||
path: ./install
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
syntax: glob
|
||||
scons_configure.py
|
||||
scons-ModOrganizer-*
|
||||
ModOrganizer-build-desktop*
|
||||
outputd/*
|
||||
output/*
|
||||
build-ModOrganizer-*
|
||||
source/NCC/*/bin
|
||||
source/NCC/*/obj
|
||||
source/NCC/bin
|
||||
*.orig
|
||||
source/plugins/proxyPython/build
|
||||
staging/*
|
||||
source - Copy/*
|
||||
ModOrganizer-build-*
|
||||
pdbs/*
|
||||
source/NCC/BossDummy.x/*
|
||||
*.ts
|
||||
staging_prepare/*
|
||||
staging_trans/*
|
||||
tools/python_zip/*
|
||||
Makefile
|
||||
html
|
||||
*.vcxproj
|
||||
*.pdb
|
||||
*.dll
|
||||
*.exp
|
||||
*.tlog
|
||||
*.user
|
||||
*.obj
|
||||
*.suo
|
||||
*.sln
|
||||
*.log
|
||||
*.filters
|
||||
*.lib
|
||||
source/organizer/resources/contents/icons
|
||||
source/plugins/build-*
|
||||
*/GeneratedFiles/*
|
||||
translations/*
|
||||
source/LocalPaths.pri
|
||||
source/*/Win32/Debug/*
|
||||
source/plugins/*/Win32/Debug/*
|
||||
*~
|
||||
syntax: regexp
|
||||
Makefile\.(Debug|Release)
|
||||
source/.*/debug/.*
|
||||
+15
-10
@@ -1,16 +1,21 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
# TODO: move these to cmake_common?
|
||||
set(OPENSSL_USE_STATIC_LIBS FALSE CACHE STRING "" FORCE)
|
||||
set(MySQL_INCLUDE_DIRS CACHE STRING "" FORCE)
|
||||
|
||||
if(DEFINED DEPENDENCIES_DIR)
|
||||
include(${DEPENDENCIES_DIR}/modorganizer_super/cmake_common/mo2.cmake)
|
||||
else()
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/../cmake_common/mo2.cmake)
|
||||
endif()
|
||||
# TODO: clean include directives
|
||||
set(MO2_CMAKE_DEPRECATED_UIBASE_INCLUDE ON)
|
||||
|
||||
project(organizer)
|
||||
|
||||
# if MO2_INSTALL_IS_BIN is set, this means that we should install directly into the
|
||||
# installation prefix, without the bin/ subfolder, typically for a standalone build
|
||||
# to update an existing install
|
||||
if (MO2_INSTALL_IS_BIN)
|
||||
set(_bin ".")
|
||||
else()
|
||||
set(_bin bin)
|
||||
endif()
|
||||
|
||||
add_subdirectory(src)
|
||||
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/dump_running_process.bat DESTINATION bin)
|
||||
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT organizer)
|
||||
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/dump_running_process.bat DESTINATION ${_bin})
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
{
|
||||
"configurePresets": [
|
||||
{
|
||||
"errors": {
|
||||
"deprecated": true
|
||||
},
|
||||
"hidden": true,
|
||||
"name": "cmake-dev",
|
||||
"warnings": {
|
||||
"deprecated": true,
|
||||
"dev": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"cacheVariables": {
|
||||
"VCPKG_MANIFEST_NO_DEFAULT_FEATURES": {
|
||||
"type": "BOOL",
|
||||
"value": "ON"
|
||||
}
|
||||
},
|
||||
"toolchainFile": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake",
|
||||
"hidden": true,
|
||||
"name": "vcpkg"
|
||||
},
|
||||
{
|
||||
"binaryDir": "${sourceDir}/vsbuild",
|
||||
"architecture": {
|
||||
"strategy": "set",
|
||||
"value": "x64"
|
||||
},
|
||||
"cacheVariables": {
|
||||
"CMAKE_CXX_FLAGS": "/EHsc /MP /W4",
|
||||
"VCPKG_TARGET_TRIPLET": {
|
||||
"type": "STRING",
|
||||
"value": "x64-windows-static-md"
|
||||
}
|
||||
},
|
||||
"generator": "Visual Studio 17 2022",
|
||||
"inherits": ["cmake-dev", "vcpkg"],
|
||||
"name": "vs2022-windows",
|
||||
"toolset": "v143"
|
||||
},
|
||||
{
|
||||
"cacheVariables": {
|
||||
"VCPKG_MANIFEST_FEATURES": {
|
||||
"type": "STRING",
|
||||
"value": "standalone"
|
||||
},
|
||||
"MO2_INSTALL_IS_BIN": {
|
||||
"type": "BOOL",
|
||||
"value": "ON"
|
||||
}
|
||||
},
|
||||
"inherits": "vs2022-windows",
|
||||
"name": "vs2022-windows-standalone"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
||||
-713
File diff suppressed because it is too large
Load Diff
@@ -1,77 +0,0 @@
|
||||
version: dev-appveyor{build}
|
||||
skip_branch_with_pr: true
|
||||
image: Visual Studio 2019
|
||||
init:
|
||||
- ps: >-
|
||||
# define build version depending on nightly or normal build
|
||||
|
||||
if($env:APPVEYOR_SCHEDULED_BUILD -eq 'True'){
|
||||
$timestamp= Get-Date -Format "ddMMyyyy-HHmm"
|
||||
Update-AppveyorBuild -Version "$($env:MO_VERSION)$($env:VER_STUB_NIGHTLY)$timestamp"
|
||||
} else {
|
||||
Update-AppveyorBuild -Version "$($env:MO_VERSION)$($env:VER_STUB_NORMAL)$($env:APPVEYOR_BUILD_NUMBER)"
|
||||
}
|
||||
|
||||
Write-Host Build version set to: $env:APPVEYOR_BUILD_VERSION
|
||||
environment:
|
||||
WEBHOOK_URL:
|
||||
secure: gOKbXaZM9ImtMD5XrYITvdyZUW/az082G9OIN1EC1VaKiI9iefpxhBavJ6Al6CzIZvQ+3pxnLqjmNgA7cDc22wcj2kB4hSG5qhbTI8wGa8jLQ5L65nuRZ3vrIqghBz9G3GLglgZkg6eqH9r3Kqc6UzcpCGzxxPOqm550nRcIiUU=
|
||||
MO_VERSION: 2.4.0
|
||||
VER_STUB_NORMAL: dev-appveyor-
|
||||
VER_STUB_NIGHTLY: dev-nightly-
|
||||
build_script:
|
||||
- pwsh: >-
|
||||
# Maintenance comments:
|
||||
|
||||
# APPVEYOR_BUILD_FOLDER= "c:\projects\modorganizer-slug"
|
||||
|
||||
# -Need to update py3 version used to invoke unimake.py once in a while.
|
||||
|
||||
# -Need update MO_VERSION env variable after each release.
|
||||
|
||||
# -Always clones umbrella master
|
||||
|
||||
# -Will checkout all the branches matching the one that triggered the build on the main repo.
|
||||
|
||||
# End comments.
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
git clone --depth=1 --no-single-branch https://github.com/ModOrganizer2/modorganizer-umbrella.git c:\projects\modorganizer-umbrella
|
||||
|
||||
New-Item -ItemType Directory -Path ${env:APPVEYOR_BUILD_FOLDER}\modorganizer-build
|
||||
|
||||
cd c:\projects\modorganizer-umbrella
|
||||
|
||||
($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH -eq $null) ? ($branch = $env:APPVEYOR_REPO_BRANCH) : ($branch = $env:APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH)
|
||||
|
||||
git checkout $(git show-ref --verify --quiet refs/remotes/origin/${branch} || echo '-b') ${branch}
|
||||
|
||||
C:\Python38-x64\python.exe unimake.py -d ${env:APPVEYOR_BUILD_FOLDER}\modorganizer-build -s Appveyor_Build=True -s Feature_Branch=${env:APPVEYOR_REPO_BRANCH} -s override_build_version=${env:APPVEYOR_BUILD_VERSION}
|
||||
|
||||
if($LastExitCode -ne 0) { $host.SetShouldExit($LastExitCode ) }
|
||||
test: off
|
||||
artifacts:
|
||||
- path: '\modorganizer-build\install\bin\ModOrganizer.exe'
|
||||
name: Mod.Organizer-$(APPVEYOR_BUILD_VERSION)
|
||||
- path: '\modorganizer-build\install\pdb\ModOrganizer.pdb'
|
||||
name: PDB-Mod.Organizer-$(APPVEYOR_BUILD_VERSION)
|
||||
deploy: off
|
||||
on_success:
|
||||
- ps: >-
|
||||
Set-Location -Path $env:APPVEYOR_BUILD_FOLDER
|
||||
|
||||
Invoke-RestMethod https://raw.githubusercontent.com/DiscordHooks/appveyor-discord-webhook/master/send.ps1 -o send.ps1
|
||||
|
||||
if($env:APPVEYOR_SCHEDULED_BUILD -ne 'True'){
|
||||
./send.ps1 success $env:WEBHOOK_URL
|
||||
}
|
||||
on_failure:
|
||||
- ps: >-
|
||||
Set-Location -Path $env:APPVEYOR_BUILD_FOLDER
|
||||
|
||||
Invoke-RestMethod https://raw.githubusercontent.com/DiscordHooks/appveyor-discord-webhook/master/send.ps1 -o send.ps1
|
||||
|
||||
if($env:APPVEYOR_SCHEDULED_BUILD -ne 'True'){
|
||||
./send.ps1 failure $env:WEBHOOK_URL
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
[
|
||||
|
||||
# for boost???
|
||||
# These are probably correct but might need a revisit as if you look at the boost documentation pages, it
|
||||
# can give you huge lists of alternate includes...
|
||||
{ symbol: [ "BOOST_FOREACH", "private", "<boost/foreach.hpp>", "public" ] },
|
||||
|
||||
{ include: [ "@\"boost/bind/.*\"", "private", "<boost/bind.hpp>", "public" ] },
|
||||
{ include: [ "@\"boost/algorithm/string/.*\"", "private", "<boost/algorithm/string.hpp>", "public" ] },
|
||||
{ include: [ "@\"boost/assign/.*\"", "private", "<boost/assign.hpp>", "public" ] },
|
||||
{ include: [ "@\"boost/filesystem/.*\"", "private", "<boost/filesystem.hpp>", "public" ] },
|
||||
{ include: [ "@\"boost/format/.*\"", "private", "<boost/format.hpp>", "public" ] },
|
||||
{ include: [ "@\"boost/function/.*\"", "private", "<boost/function.hpp>", "public" ] },
|
||||
{ include: [ "@\"boost/local/.*\"", "private", "<boost/locale.hpp>", "public" ] },
|
||||
{ include: [ "@\"boost/python/.*\"", "private", "<boost/python.hpp>", "public" ] },
|
||||
{ include: [ "@\"boost/signals2/.*\"", "private", "<boost/signals2.hpp>", "public" ] },
|
||||
{ include: [ "\"boost/smart_ptr/scoped_array.hpp\"", "private", "<boost/scoped_array.hpp>", "public" ] },
|
||||
{ include: [ "\"boost/smart_ptr/shared_ptr.hpp\"", "private", "<boost/shared_ptr.hpp>", "public" ] },
|
||||
# this appears to be excessive
|
||||
#{ include: [ "@\"boost/thread/.*\"", "private", "<boost/thread.hpp>", "public" ] },
|
||||
|
||||
# And this is specific to us
|
||||
{ include: [ "\"appconfig.inc\"", "private", "\"appconfig.h\"", "public" ] },
|
||||
|
||||
]
|
||||
|
||||
# Ones I don't yet know how to deal with
|
||||
#include "boost/fusion/container/vector/vector10_fwd.hpp" // for fusion
|
||||
#include "boost/iterator/iterator_facade.hpp" // for operator!=
|
||||
#include "boost/iterator/iterator_facade.hpp"
|
||||
@@ -1,33 +0,0 @@
|
||||
# This python script contains the configuration for scons
|
||||
# Copy this to scons_configure.py and adjust to taste.
|
||||
|
||||
# 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 = 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
|
||||
# supported values.
|
||||
#MSVC_VERSION = '10.0Exp'
|
||||
|
||||
# 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=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 = r"C:\Apps\Qt\4.8.6"
|
||||
|
||||
# Path to 7-zip sources
|
||||
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 = 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"
|
||||
+91
-20
@@ -1,36 +1,106 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
find_package(mo2-cmake CONFIG REQUIRED)
|
||||
|
||||
find_package(usvfs CONFIG REQUIRED)
|
||||
|
||||
find_package(mo2-uibase CONFIG REQUIRED)
|
||||
find_package(mo2-archive CONFIG REQUIRED)
|
||||
find_package(mo2-lootcli-header CONFIG REQUIRED)
|
||||
find_package(mo2-bsatk CONFIG REQUIRED)
|
||||
find_package(mo2-esptk CONFIG REQUIRED)
|
||||
find_package(mo2-dds-header CONFIG REQUIRED)
|
||||
find_package(mo2-libbsarch CONFIG REQUIRED)
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS WebEngineWidgets WebSockets)
|
||||
find_package(Boost CONFIG REQUIRED COMPONENTS program_options thread interprocess signals2 uuid accumulators)
|
||||
find_package(7zip CONFIG REQUIRED)
|
||||
find_package(lz4 CONFIG REQUIRED)
|
||||
find_package(ZLIB REQUIRED)
|
||||
|
||||
add_executable(organizer)
|
||||
set_target_properties(organizer PROPERTIES OUTPUT_NAME "ModOrganizer")
|
||||
mo2_configure_executable(organizer
|
||||
WARNINGS OFF
|
||||
EXTRA_TRANSLATIONS ${MO2_SUPER_PATH}/game_gamebryo/src ${MO2_UIBASE_PATH}/src
|
||||
PRIVATE_DEPENDS
|
||||
uibase githubpp bsatk esptk archive usvfs lootcli boost::program_options
|
||||
DirectXTex libbsarch Qt::WebEngineWidgets Qt::WebSockets)
|
||||
target_link_libraries(organizer PUBLIC Shlwapi)
|
||||
target_include_directories(organizer PUBLIC ${DDS_ROOT})
|
||||
mo2_install_target(organizer)
|
||||
set_target_properties(organizer PROPERTIES
|
||||
OUTPUT_NAME "ModOrganizer"
|
||||
WIN32_EXECUTABLE TRUE)
|
||||
|
||||
# disable translations because we want to be able to install somewhere else if
|
||||
# required
|
||||
mo2_configure_target(organizer WARNINGS 4 TRANSLATIONS OFF)
|
||||
|
||||
# we add translations "manually" to handle MO2_INSTALL_IS_BIN
|
||||
mo2_add_translations(organizer
|
||||
INSTALL_RELEASE
|
||||
INSTALL_DIRECTORY "${_bin}/translations"
|
||||
SOURCES ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
mo2_set_project_to_run_from_install(
|
||||
organizer EXECUTABLE ${CMAKE_INSTALL_PREFIX}/${_bin}/ModOrganizer.exe)
|
||||
|
||||
target_link_libraries(organizer PRIVATE
|
||||
Shlwapi Bcrypt
|
||||
usvfs::usvfs mo2::uibase mo2::archive mo2::libbsarch
|
||||
mo2::bsatk mo2::esptk mo2::lootcli-header
|
||||
Boost::program_options Boost::signals2 Boost::uuid Boost::accumulators
|
||||
Qt6::WebEngineWidgets Qt6::WebSockets Version Dbghelp)
|
||||
|
||||
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/dlls.manifest.qt6"
|
||||
DESTINATION bin/dlls
|
||||
DESTINATION ${_bin}/dlls
|
||||
CONFIGURATIONS Release RelWithDebInfo
|
||||
RENAME dlls.manifest)
|
||||
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/dlls.manifest.debug.qt6"
|
||||
DESTINATION bin/dlls
|
||||
DESTINATION ${_bin}/dlls
|
||||
CONFIGURATIONS Debug
|
||||
RENAME dlls.manifest)
|
||||
|
||||
install(DIRECTORY
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/stylesheets"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/tutorials"
|
||||
DESTINATION bin)
|
||||
if (NOT MO2_SKIP_STYLESHEETS_INSTALL)
|
||||
install(
|
||||
DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/stylesheets"
|
||||
DESTINATION ${_bin})
|
||||
endif()
|
||||
|
||||
if (NOT MO2_SKIP_TUTORIALS_INSTALL)
|
||||
install(
|
||||
DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/tutorials"
|
||||
DESTINATION ${_bin})
|
||||
endif()
|
||||
|
||||
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/resources/markdown.html"
|
||||
DESTINATION bin/resources)
|
||||
DESTINATION ${_bin}/resources)
|
||||
|
||||
mo2_deploy_qt(BINARIES ModOrganizer.exe uibase.dll plugins/bsa_packer.dll)
|
||||
# install ModOrganizer.exe itself
|
||||
install(FILES $<TARGET_FILE:organizer> DESTINATION ${_bin})
|
||||
|
||||
# install dependencies DLLs
|
||||
install(FILES $<TARGET_FILE:mo2::libbsarch> DESTINATION ${_bin}/dlls)
|
||||
install(FILES $<TARGET_FILE:mo2::archive> DESTINATION ${_bin}/dlls)
|
||||
install(FILES $<TARGET_FILE:7zip::7zip> DESTINATION ${_bin}/dlls)
|
||||
|
||||
# this may copy over the ones from uibase/usvfs
|
||||
# - when building with mob, this should not matter as the files should be identical
|
||||
# - when building standalone, this should help having matching USVFS DLL between the
|
||||
# build and the installation
|
||||
# - this may cause issue with uibase in standalone mode if the installed version does
|
||||
# not match the one used for the build, but there would be other issue anyway (e.g.
|
||||
# different uibase.dll between modorganizer and plugins)
|
||||
#
|
||||
install(FILES
|
||||
$<TARGET_FILE:mo2::uibase>
|
||||
$<TARGET_FILE:usvfs_x64::usvfs_dll>
|
||||
$<TARGET_FILE:usvfs_x86::usvfs_dll>
|
||||
$<TARGET_FILE:usvfs_x64::usvfs_proxy>
|
||||
$<TARGET_FILE:usvfs_x86::usvfs_proxy>
|
||||
DESTINATION ${_bin})
|
||||
|
||||
# do not install PDB if CMAKE_INSTALL_PREFIX is "bin"
|
||||
if (NOT MO2_INSTALL_IS_BIN)
|
||||
install(FILES $<TARGET_PDB_FILE:organizer> DESTINATION pdb)
|
||||
endif()
|
||||
|
||||
mo2_deploy_qt(
|
||||
DIRECTORY ${_bin}
|
||||
BINARIES ModOrganizer.exe $<TARGET_FILE_NAME:mo2::uibase>)
|
||||
|
||||
# set source groups for VS
|
||||
mo2_add_filter(NAME src/application GROUPS
|
||||
iuserinterface
|
||||
commandline
|
||||
@@ -49,14 +119,15 @@ mo2_add_filter(NAME src/browser GROUPS
|
||||
)
|
||||
|
||||
mo2_add_filter(NAME src/categories GROUPS
|
||||
categories
|
||||
categories
|
||||
categoriestable
|
||||
categoriesdialog
|
||||
categoriesdialog
|
||||
categoryimportdialog
|
||||
)
|
||||
|
||||
mo2_add_filter(NAME src/core GROUPS
|
||||
archivefiletree
|
||||
githubpp
|
||||
installationmanager
|
||||
nexusinterface
|
||||
nxmaccessmanager
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
TEMPLATE = subdirs
|
||||
|
||||
SUBDIRS = bsatk \
|
||||
shared \
|
||||
uibase \
|
||||
esptk \
|
||||
organizer \
|
||||
hookdll \
|
||||
archive \
|
||||
helper \
|
||||
plugins \
|
||||
nxmhandler \
|
||||
BossDummy \
|
||||
pythonRunner \
|
||||
loot_cli
|
||||
|
||||
pythonRunner.depends = uibase
|
||||
plugins.depends = pythonRunner uibase
|
||||
hookdll.depends = shared
|
||||
organizer.depends = shared uibase plugins
|
||||
|
||||
CONFIG(debug, debug|release) {
|
||||
DESTDIR = $$PWD/../outputd
|
||||
} else {
|
||||
DESTDIR = $$PWD/../output
|
||||
}
|
||||
|
||||
STATICDATAPATH = $${DESTDIR}\\..\\tools\\static_data\\dlls
|
||||
DLLSPATH = $${DESTDIR}\\dlls
|
||||
|
||||
otherlibs.path = $$DLLSPATH
|
||||
otherlibs.files += $${STATICDATAPATH}\\7z.dll \
|
||||
$${BOOSTPATH}\\stage\\lib\\boost_python-vc*-mt-1*.dll
|
||||
|
||||
qtlibs.path = $$DLLSPATH
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4) {
|
||||
QTLIBNAMES += Core Gui Network OpenGL Script Sql Svg Qml Quick Webkit Widgets Xml XmlPatterns
|
||||
} else {
|
||||
QTLIBNAMES += Core Declarative Gui Network OpenGL Script Sql Svg Webkit Xml XmlPatterns
|
||||
}
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 5) {
|
||||
QTLIBNAMES += OpenGLWidgets
|
||||
}
|
||||
|
||||
QTLIBSUFFIX = $${QT_MAJOR_VERSION}.dll
|
||||
CONFIG(debug, debug|release): QTLIBSUFFIX = "d$${QTLIBSUFFIX}" # Can't use Debug: .. here, it ignores the line - no idea why, as it works in BossDummy.pro
|
||||
|
||||
for(QTNAME, QTLIBNAMES) {
|
||||
QTFILE = Qt$${QTNAME}
|
||||
qtlibs.files += $$[QT_INSTALL_BINS]\\$${QTFILE}$${QTLIBSUFFIX}
|
||||
}
|
||||
|
||||
INSTALLS += qtlibs otherlibs
|
||||
|
||||
OTHER_FILES +=\
|
||||
../SConstruct\
|
||||
../scons_configure.py\
|
||||
SConscript
|
||||
-179
@@ -1,179 +0,0 @@
|
||||
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()
|
||||
|
||||
modules = [
|
||||
'Core',
|
||||
'Gui',
|
||||
'Network',
|
||||
'Script',
|
||||
'Sql',
|
||||
'WebKit',
|
||||
'Xml',
|
||||
'XmlPatterns',
|
||||
'Declarative'
|
||||
]
|
||||
|
||||
if env['QT_MAJOR_VERSION'] > 4:
|
||||
modules += [
|
||||
'Widgets',
|
||||
'Qml',
|
||||
'WebKitWidgets'
|
||||
]
|
||||
|
||||
env.EnableQtModules(*modules)
|
||||
|
||||
env.Uic(env.Glob('*.ui'))
|
||||
|
||||
env.RequireLibraries('uibase', 'shared', 'bsatk', 'esptk')
|
||||
|
||||
env.AppendUnique(LIBS = [
|
||||
'shell32',
|
||||
'user32',
|
||||
'ole32',
|
||||
'advapi32',
|
||||
'gdi32',
|
||||
'shlwapi',
|
||||
'Psapi',
|
||||
'Version'
|
||||
])
|
||||
|
||||
# We have to 'persuade' moc to generate certain other targets and inject them
|
||||
# into the list of cpps
|
||||
other_sources = env.AddExtraMoc(env.Glob('*.h'))
|
||||
|
||||
for file in env.Glob('*.rc'):
|
||||
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',
|
||||
'../plugins/gamefeatures',
|
||||
'.', # Why is this necessary?
|
||||
'${LOOTPATH}',
|
||||
'${BOOSTPATH}',
|
||||
]
|
||||
|
||||
#########################FUDGE###############################
|
||||
env['CPPPATH'] += [
|
||||
'../plugins/gameGamebryo',
|
||||
]
|
||||
#############################################################
|
||||
|
||||
env.AppendUnique(CPPDEFINES = [
|
||||
'_UNICODE',
|
||||
'_CRT_SECURE_NO_WARNINGS',
|
||||
'_SCL_SECURE_NO_WARNINGS',
|
||||
'BOOST_DISABLE_ASSERTS',
|
||||
'NDEBUG',
|
||||
'QT_MESSAGELOGCONTEXT'
|
||||
])
|
||||
|
||||
# Boost produces very long names with msvc truncates. Doesn't seem to cause
|
||||
# problems.
|
||||
# Also note to remove the -wd4100 I hacked the boost headers (tagged_argument.hpp)
|
||||
# appropriately.
|
||||
env.AppendUnique(CPPFLAGS = [ '-wd4503' ])
|
||||
|
||||
env.AppendUnique(LINKFLAGS = [
|
||||
'/SUBSYSTEM:WINDOWS',
|
||||
'${EXE_MANIFEST_DEPENDENCY}'
|
||||
])
|
||||
|
||||
# modeltest is optional and it doesn't compile anyway...
|
||||
cpp_files = [
|
||||
x for x in env.Glob('*.cpp', source = True)
|
||||
if x.name != 'modeltest.cpp' and x.name != 'aboutdialog.cpp' and \
|
||||
not x.name.startswith('moc_') # I think this is a strange bug
|
||||
]
|
||||
|
||||
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:
|
||||
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 = "Problem determining version"
|
||||
|
||||
# FIXME: It'd be much easier to stringify this in the source code
|
||||
about_env.AppendUnique(CPPDEFINES = [ 'HGID=\\"%s\\"' % hgid ])
|
||||
other_sources.append(about_env.StaticObject('aboutdialog.cpp'))
|
||||
|
||||
env.AppendUnique(LIBPATH = "${ZLIBPATH}/build")
|
||||
env.AppendUnique(LIBS = 'zlibstatic')
|
||||
|
||||
prog = env.Program('ModOrganizer',
|
||||
cpp_files + env.Glob('*.qrc') + other_sources)
|
||||
|
||||
env.InstallModule(prog)
|
||||
|
||||
for subdir in ('tutorials', 'stylesheets'):
|
||||
env.Install(os.path.join(env['INSTALL_PATH'], subdir),
|
||||
env.Glob(os.path.join(subdir, '*')))
|
||||
|
||||
# FIXME Sort the translations. Except they don't exist on the 1.2 branch
|
||||
|
||||
res = env['QT_USED_MODULES']
|
||||
Return('res')
|
||||
|
||||
"""
|
||||
CONFIG(debug, debug|release) {
|
||||
} else {
|
||||
QMAKE_CXXFLAGS += /Zi /GL
|
||||
QMAKE_LFLAGS += /DEBUG /LTCG /OPT:REF /OPT:ICF
|
||||
}
|
||||
|
||||
TRANSLATIONS = organizer_en.ts
|
||||
|
||||
|
||||
QMAKE_POST_LINK += xcopy /y /s /I $$quote($$BASEDIR\\*.qm) $$quote($$DSTDIR)\\translations $$escape_expand(\\n)
|
||||
|
||||
"""
|
||||
@@ -20,8 +20,8 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
#ifndef ARCHIVEFILENETRY_H
|
||||
#define ARCHIVEFILENTRY_H
|
||||
|
||||
#include "archive.h"
|
||||
#include "ifiletree.h"
|
||||
#include <archive/archive.h>
|
||||
#include <uibase/ifiletree.h>
|
||||
|
||||
/**
|
||||
*
|
||||
|
||||
+204
@@ -0,0 +1,204 @@
|
||||
#include "github.h"
|
||||
#include <QEventLoop>
|
||||
#include <QJsonDocument>
|
||||
#include <QNetworkRequest>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QThread>
|
||||
|
||||
static const QString GITHUB_URL("https://api.github.com");
|
||||
static const QString USER_AGENT("GitHubPP");
|
||||
|
||||
GitHub::GitHub(const char* clientId) : m_AccessManager(new QNetworkAccessManager(this))
|
||||
{}
|
||||
|
||||
GitHub::~GitHub()
|
||||
{
|
||||
// delete all the replies since they depend on the access manager, which is
|
||||
// about to be deleted
|
||||
for (auto* reply : m_replies) {
|
||||
reply->disconnect();
|
||||
delete reply;
|
||||
}
|
||||
}
|
||||
|
||||
QJsonArray GitHub::releases(const Repository& repo)
|
||||
{
|
||||
QJsonDocument result = request(
|
||||
Method::GET, QString("repos/%1/%2/releases").arg(repo.owner, repo.project),
|
||||
QByteArray(), true);
|
||||
return result.array();
|
||||
}
|
||||
|
||||
void GitHub::releases(const Repository& repo,
|
||||
const std::function<void(const QJsonArray&)>& callback)
|
||||
{
|
||||
request(
|
||||
Method::GET, QString("repos/%1/%2/releases").arg(repo.owner, repo.project),
|
||||
QByteArray(),
|
||||
[callback](const QJsonDocument& result) {
|
||||
callback(result.array());
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
QJsonDocument GitHub::handleReply(QNetworkReply* reply)
|
||||
{
|
||||
int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
if (statusCode != 200) {
|
||||
return QJsonDocument(QJsonObject(
|
||||
{{"http_status", statusCode},
|
||||
{"redirection",
|
||||
reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toString()},
|
||||
{"reason",
|
||||
reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString()}}));
|
||||
}
|
||||
|
||||
QByteArray data = reply->readAll();
|
||||
if (data.isNull() || data.isEmpty() || (strcmp(data.constData(), "null") == 0)) {
|
||||
return QJsonDocument();
|
||||
}
|
||||
|
||||
QJsonParseError parseError;
|
||||
QJsonDocument result = QJsonDocument::fromJson(data, &parseError);
|
||||
|
||||
if (parseError.error != QJsonParseError::NoError) {
|
||||
return QJsonDocument(QJsonObject({{"parse_error", parseError.errorString()}}));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QNetworkReply* GitHub::genReply(Method method, const QString& path,
|
||||
const QByteArray& data, bool relative)
|
||||
{
|
||||
QNetworkRequest request(relative ? GITHUB_URL + "/" + path : path);
|
||||
|
||||
request.setHeader(QNetworkRequest::UserAgentHeader, USER_AGENT);
|
||||
request.setRawHeader("Accept", "application/vnd.github.v3+json");
|
||||
|
||||
switch (method) {
|
||||
case Method::GET:
|
||||
return m_AccessManager->get(request);
|
||||
case Method::POST:
|
||||
return m_AccessManager->post(request, data);
|
||||
default:
|
||||
// this shouldn't be possible as all enum options are handled
|
||||
throw std::runtime_error("invalid method");
|
||||
}
|
||||
}
|
||||
|
||||
QJsonDocument GitHub::request(Method method, const QString& path,
|
||||
const QByteArray& data, bool relative)
|
||||
{
|
||||
QEventLoop wait;
|
||||
QNetworkReply* reply = genReply(method, path, data, relative);
|
||||
|
||||
connect(reply, SIGNAL(finished), &wait, SLOT(quit()));
|
||||
wait.exec();
|
||||
QJsonDocument result = handleReply(reply);
|
||||
reply->deleteLater();
|
||||
|
||||
QJsonObject object = result.object();
|
||||
if (object.value("http_status").toDouble() == 301.0) {
|
||||
return request(method, object.value("redirection").toString(), data, false);
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
void GitHub::request(Method method, const QString& path, const QByteArray& data,
|
||||
const std::function<void(const QJsonDocument&)>& callback,
|
||||
bool relative)
|
||||
{
|
||||
// make sure the timer is owned by this so it's deleted correctly and
|
||||
// doesn't fire after the GitHub object is destroyed; this happens when
|
||||
// restarting MO by switching instances, for example
|
||||
QTimer* timer = new QTimer(this);
|
||||
timer->setSingleShot(true);
|
||||
timer->setInterval(10000);
|
||||
|
||||
QNetworkReply* reply = genReply(method, path, data, relative);
|
||||
|
||||
// remember this reply so it can be deleted in the destructor if necessary
|
||||
m_replies.push_back(reply);
|
||||
|
||||
Request req = {method, data, callback, timer, reply};
|
||||
|
||||
// finished
|
||||
connect(reply, &QNetworkReply::finished, [this, req] {
|
||||
onFinished(req);
|
||||
});
|
||||
|
||||
// error
|
||||
connect(reply, qOverload<QNetworkReply::NetworkError>(&QNetworkReply::errorOccurred),
|
||||
[this, req](auto&& error) {
|
||||
onError(req, error);
|
||||
});
|
||||
|
||||
// timeout
|
||||
connect(timer, &QTimer::timeout, [this, req] {
|
||||
onTimeout(req);
|
||||
});
|
||||
|
||||
timer->start();
|
||||
}
|
||||
|
||||
void GitHub::onFinished(const Request& req)
|
||||
{
|
||||
QJsonDocument result = handleReply(req.reply);
|
||||
QJsonObject object = result.object();
|
||||
|
||||
req.timer->stop();
|
||||
|
||||
if (object.value("http_status").toInt() == 301) {
|
||||
request(req.method, object.value("redirection").toString(), req.data, req.callback,
|
||||
false);
|
||||
} else {
|
||||
req.callback(result);
|
||||
}
|
||||
|
||||
deleteReply(req.reply);
|
||||
}
|
||||
|
||||
void GitHub::onError(const Request& req, QNetworkReply::NetworkError error)
|
||||
{
|
||||
// the only way the request can be aborted is when there's a timeout, which
|
||||
// already logs a message
|
||||
if (error != QNetworkReply::OperationCanceledError) {
|
||||
qCritical().noquote().nospace()
|
||||
<< "Github: request for " << req.reply->url().toString() << " failed, "
|
||||
<< req.reply->errorString() << " (" << error << ")";
|
||||
}
|
||||
|
||||
req.timer->stop();
|
||||
req.reply->disconnect();
|
||||
|
||||
QJsonObject root({{"network_error", req.reply->errorString()}});
|
||||
QJsonDocument doc(root);
|
||||
|
||||
req.callback(doc);
|
||||
|
||||
deleteReply(req.reply);
|
||||
}
|
||||
|
||||
void GitHub::onTimeout(const Request& req)
|
||||
{
|
||||
qCritical().noquote().nospace()
|
||||
<< "Github: request for " << req.reply->url().toString() << " timed out";
|
||||
|
||||
// don't delete the reply, abort will fire the error() handler above
|
||||
req.reply->abort();
|
||||
}
|
||||
|
||||
void GitHub::deleteReply(QNetworkReply* reply)
|
||||
{
|
||||
// remove from the list
|
||||
auto itor = std::find(m_replies.begin(), m_replies.end(), reply);
|
||||
if (itor != m_replies.end()) {
|
||||
m_replies.erase(itor);
|
||||
}
|
||||
|
||||
// delete
|
||||
reply->deleteLater();
|
||||
}
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
#pragma once
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkCookieJar>
|
||||
#include <QNetworkReply>
|
||||
#include <QTimer>
|
||||
#include <functional>
|
||||
|
||||
class GitHubException : public std::exception
|
||||
{
|
||||
public:
|
||||
GitHubException(const QJsonObject& errorObj) : std::exception()
|
||||
{
|
||||
initMessage(errorObj);
|
||||
}
|
||||
|
||||
virtual ~GitHubException() throw() override {}
|
||||
|
||||
virtual const char* what() const throw() { return m_Message.constData(); }
|
||||
|
||||
private:
|
||||
void initMessage(const QJsonObject& obj)
|
||||
{
|
||||
if (obj.contains("http_status")) {
|
||||
m_Message = QString("HTTP Status %1: %2")
|
||||
.arg(obj.value("http_status").toInt())
|
||||
.arg(obj.value("reason").toString())
|
||||
.toUtf8();
|
||||
} else if (obj.contains("parse_error")) {
|
||||
m_Message = QString("Parsing failed: %1")
|
||||
.arg(obj.value("parse_error").toString())
|
||||
.toUtf8();
|
||||
} else if (obj.contains("network_error")) {
|
||||
m_Message = QString("Network failed: %1")
|
||||
.arg(obj.value("network_error").toString())
|
||||
.toUtf8();
|
||||
} else {
|
||||
m_Message = "Unknown error";
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray m_Message;
|
||||
};
|
||||
|
||||
class GitHub : public QObject
|
||||
{
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum class Method
|
||||
{
|
||||
GET,
|
||||
POST
|
||||
};
|
||||
|
||||
struct Repository
|
||||
{
|
||||
Repository(const QString& owner, const QString& project)
|
||||
: owner(owner), project(project)
|
||||
{}
|
||||
QString owner;
|
||||
QString project;
|
||||
};
|
||||
|
||||
public:
|
||||
GitHub(const char* clientId = nullptr);
|
||||
~GitHub();
|
||||
|
||||
QJsonArray releases(const Repository& repo);
|
||||
void releases(const Repository& repo,
|
||||
const std::function<void(const QJsonArray&)>& callback);
|
||||
|
||||
private:
|
||||
QJsonDocument request(Method method, const QString& path, const QByteArray& data,
|
||||
bool relative);
|
||||
void request(Method method, const QString& path, const QByteArray& data,
|
||||
const std::function<void(const QJsonDocument&)>& callback,
|
||||
bool relative);
|
||||
|
||||
QJsonDocument handleReply(QNetworkReply* reply);
|
||||
QNetworkReply* genReply(Method method, const QString& path, const QByteArray& data,
|
||||
bool relative);
|
||||
|
||||
private:
|
||||
struct Request
|
||||
{
|
||||
Method method = Method::GET;
|
||||
QByteArray data;
|
||||
std::function<void(const QJsonDocument&)> callback;
|
||||
QTimer* timer = nullptr;
|
||||
QNetworkReply* reply = nullptr;
|
||||
};
|
||||
|
||||
QNetworkAccessManager* m_AccessManager;
|
||||
|
||||
// remember the replies that are in flight and delete them in the destructor
|
||||
std::vector<QNetworkReply*> m_replies;
|
||||
|
||||
void onFinished(const Request& req);
|
||||
void onError(const Request& req, QNetworkReply::NetworkError error);
|
||||
void onTimeout(const Request& req);
|
||||
|
||||
void deleteReply(QNetworkReply* reply);
|
||||
};
|
||||
@@ -20,17 +20,17 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
#ifndef INSTALLATIONMANAGER_H
|
||||
#define INSTALLATIONMANAGER_H
|
||||
|
||||
#include <guessedvalue.h>
|
||||
#include <ifiletree.h>
|
||||
#include <iinstallationmanager.h>
|
||||
#include <iplugininstaller.h>
|
||||
#include <archive/archive.h>
|
||||
#include <uibase/errorcodes.h>
|
||||
#include <uibase/guessedvalue.h>
|
||||
#include <uibase/ifiletree.h>
|
||||
#include <uibase/iinstallationmanager.h>
|
||||
#include <uibase/iplugininstaller.h>
|
||||
|
||||
#include <QObject>
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <QProgressDialog>
|
||||
#include <Windows.h>
|
||||
#include <archive.h>
|
||||
#include <errorcodes.h>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
|
||||
+12
-6
@@ -60,8 +60,6 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include "problemsdialog.h"
|
||||
#include "profile.h"
|
||||
#include "profilesdialog.h"
|
||||
#include "report.h"
|
||||
#include "savegameinfo.h"
|
||||
#include "savestab.h"
|
||||
#include "selectiondialog.h"
|
||||
#include "serverinfo.h"
|
||||
@@ -69,15 +67,17 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include "shared/appconfig.h"
|
||||
#include "spawn.h"
|
||||
#include "statusbar.h"
|
||||
#include "tutorialmanager.h"
|
||||
#include "versioninfo.h"
|
||||
#include <bsainvalidation.h>
|
||||
#include <dataarchives.h>
|
||||
#include <safewritefile.h>
|
||||
#include <scopeguard.h>
|
||||
#include <taskprogressmanager.h>
|
||||
#include <usvfs.h>
|
||||
#include <utility.h>
|
||||
#include <uibase/game_features/savegameinfo.h>
|
||||
#include <uibase/report.h>
|
||||
#include <uibase/tutorialmanager.h>
|
||||
#include <uibase/utility.h>
|
||||
#include <uibase/versioninfo.h>
|
||||
#include <usvfs/usvfs.h>
|
||||
|
||||
#include "directoryrefresher.h"
|
||||
#include "shared/directoryentry.h"
|
||||
@@ -2884,6 +2884,12 @@ void MainWindow::languageChange(const QString& newLanguage)
|
||||
installTranslator("qt");
|
||||
installTranslator("qtbase");
|
||||
installTranslator(ToQString(AppConfig::translationPrefix()));
|
||||
installTranslator("uibase");
|
||||
|
||||
// TODO: this will probably be changed once extension come out
|
||||
installTranslator("game_gamebryo");
|
||||
installTranslator("game_creation");
|
||||
|
||||
for (const QString& fileName : m_PluginContainer.pluginFileNames()) {
|
||||
installTranslator(QFileInfo(fileName).baseName());
|
||||
}
|
||||
|
||||
+8
-7
@@ -20,19 +20,20 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include "bsafolder.h"
|
||||
#include <bsatk/bsafolder.h>
|
||||
#include <uibase/errorcodes.h>
|
||||
#include <uibase/imoinfo.h>
|
||||
#include <uibase/iplugingame.h>
|
||||
#include <uibase/log.h>
|
||||
#include <uibase/tutorialcontrol.h>
|
||||
|
||||
#include "delayedfilewriter.h"
|
||||
#include "errorcodes.h"
|
||||
#include "imoinfo.h"
|
||||
#include "iplugingame.h" //namespace MOBase { class IPluginGame; }
|
||||
#include "iuserinterface.h"
|
||||
#include "modinfo.h"
|
||||
#include "modlistbypriorityproxy.h"
|
||||
#include "modlistsortproxy.h"
|
||||
#include "plugincontainer.h" //class PluginContainer;
|
||||
#include "plugincontainer.h"
|
||||
#include "shared/fileregisterfwd.h"
|
||||
#include "tutorialcontrol.h"
|
||||
#include <log.h>
|
||||
|
||||
class Executable;
|
||||
class CategoryFactory;
|
||||
|
||||
@@ -29,15 +29,15 @@
|
||||
#include "spawn.h"
|
||||
#include "syncoverwritedialog.h"
|
||||
#include "virtualfiletree.h"
|
||||
#include <dataarchives.h>
|
||||
#include <ipluginmodpage.h>
|
||||
#include <localsavegames.h>
|
||||
#include <questionboxmemory.h>
|
||||
#include <report.h>
|
||||
#include <scopeguard.h>
|
||||
#include <scriptextender.h>
|
||||
#include <usvfs.h>
|
||||
#include <utility.h>
|
||||
#include <uibase/game_features/dataarchives.h>
|
||||
#include <uibase/game_features/localsavegames.h>
|
||||
#include <uibase/game_features/scriptextender.h>
|
||||
#include <uibase/report.h>
|
||||
#include <uibase/scopeguard.h>
|
||||
#include <uibase/utility.h>
|
||||
#include <usvfs/usvfs.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QCoreApplication>
|
||||
@@ -71,7 +71,7 @@
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
#include "bs_archive.h"
|
||||
#include <libbsarch/bs_archive.h>
|
||||
|
||||
#include "organizerproxy.h"
|
||||
|
||||
|
||||
+18
-19
@@ -16,24 +16,11 @@ GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pluginlist.h"
|
||||
#include "modinfo.h"
|
||||
#include "modlist.h"
|
||||
#include "scopeguard.h"
|
||||
#include "settings.h"
|
||||
#include "shared/directoryentry.h"
|
||||
#include "shared/fileentry.h"
|
||||
#include "shared/filesorigin.h"
|
||||
#include "viewmarkingscrollbar.h"
|
||||
|
||||
#include "shared/windows_error.h"
|
||||
#include <espfile.h>
|
||||
#include <gameplugins.h>
|
||||
#include <iplugingame.h>
|
||||
#include <report.h>
|
||||
#include <safewritefile.h>
|
||||
#include <utility.h>
|
||||
#include <algorithm>
|
||||
#include <ctime>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QCoreApplication>
|
||||
@@ -50,11 +37,23 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include <QString>
|
||||
#include <QtDebug>
|
||||
|
||||
#include <algorithm>
|
||||
#include <ctime>
|
||||
#include <stdexcept>
|
||||
#include <esptk/espfile.h>
|
||||
#include <uibase/iplugingame.h>
|
||||
#include <uibase/report.h>
|
||||
#include <uibase/safewritefile.h>
|
||||
#include <uibase/scopeguard.h>
|
||||
#include <uibase/utility.h>
|
||||
|
||||
#include "gameplugins.h"
|
||||
#include "modinfo.h"
|
||||
#include "modlist.h"
|
||||
#include "organizercore.h"
|
||||
#include "settings.h"
|
||||
#include "shared/directoryentry.h"
|
||||
#include "shared/fileentry.h"
|
||||
#include "shared/filesorigin.h"
|
||||
#include "shared/windows_error.h"
|
||||
#include "viewmarkingscrollbar.h"
|
||||
|
||||
using namespace MOBase;
|
||||
using namespace MOShared;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user