1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-03-05 13:19:43 +00:00

Merge commit 'cd8b20439ec707574826679a8f851546c78e294e' into re-sign-mac-applications

This commit is contained in:
Andrew Dunn 2022-09-17 18:25:20 +10:00
commit e4f04390b5
755 changed files with 20380 additions and 18992 deletions
.clang-format.git-blame-ignore-revsCHANGELOG.mdCMakeLists.txtREADME.md
apps

View file

@ -9,15 +9,15 @@ AlignOperands: false
AlignTrailingComments: false AlignTrailingComments: false
AllowAllParametersOfDeclarationOnNextLine: true AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: true AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: false AllowShortIfStatementsOnASingleLine: false
AllowShortLambdasOnASingleLine: All AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: false AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: false AlwaysBreakTemplateDeclarations: true
BinPackArguments: true BinPackArguments: true
BinPackParameters: true BinPackParameters: true
BraceWrapping: BraceWrapping:
@ -33,14 +33,15 @@ BraceWrapping:
AfterExternBlock: true AfterExternBlock: true
BeforeCatch: true BeforeCatch: true
BeforeElse: true BeforeElse: true
BeforeLambdaBody: true BeforeLambdaBody: false
IndentBraces: false
BreakBeforeBinaryOperators: All BreakBeforeBinaryOperators: All
BreakBeforeBraces: Custom BreakBeforeBraces: Custom
BreakBeforeInheritanceComma: false BreakBeforeInheritanceComma: false
BreakBeforeTernaryOperators: true BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false BreakConstructorInitializersBeforeComma: true
BreakStringLiterals: true BreakStringLiterals: true
ColumnLimit: 0 ColumnLimit: 120
CompactNamespaces: false CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4 ConstructorInitializerIndentWidth: 4
@ -98,3 +99,5 @@ SpacesInSquareBrackets: false
Standard: c++20 Standard: c++20
TabWidth: 4 TabWidth: 4
UseTab: Never UseTab: Never
StatementMacros:
- META_Object

12
.git-blame-ignore-revs Normal file
View file

@ -0,0 +1,12 @@
# This file lists revisions meant to be ignored by `git blame`.
# Pass `--ignore-revs-file .git-blame-ignore-revs` to `git blame` to make your life easier.
# Author: Alexei Kotov <alexdobrohotov@yandex.ru>
# Date: Fri Sep 2 02:52:49 2022 +0000
# Reformat NIF record type mapping
8df0587793a07ec556dc9cb575cd2af4204c456b
# Author: AnyOldName3 <krizdjali@gmail.com>
# Date: Fri Sep 16 00:53:24 2022 +0100
# Renormalise line endings
84f8a6848a8b05502d7618ca7af8cca74f2c3bae

View file

@ -5,10 +5,23 @@
Bug #4816: GetWeaponDrawn returns 1 before weapon is attached Bug #4816: GetWeaponDrawn returns 1 before weapon is attached
Bug #5057: Weapon swing sound plays at same pitch whether it hits or misses Bug #5057: Weapon swing sound plays at same pitch whether it hits or misses
Bug #5129: Stuttering animation on Centurion Archer Bug #5129: Stuttering animation on Centurion Archer
Bug #5714: Touch spells cast using ExplodeSpell don't always explode
Bug #5977: Fatigueless NPCs' corpse underwater changes animation on game load Bug #5977: Fatigueless NPCs' corpse underwater changes animation on game load
Bug #6427: Enemy health bar disappears before damaging effect ends
Bug #6661: Saved games that have no preview screenshot cause issues or crashes
Bug #6939: OpenMW-CS: ID columns are too short Bug #6939: OpenMW-CS: ID columns are too short
Bug #6949: Sun Damage effect doesn't work in quasi exteriors Bug #6949: Sun Damage effect doesn't work in quasi exteriors
Bug #6964: Nerasa Dralor Won't Follow
Bug #6974: Only harmful effects are reflected
Bug #6986: Sound magic effect does not make noise
Bug #6987: Set/Mod Blindness should not darken the screen
Bug #6992: Crossbow reloading doesn't look the same as in Morrowind
Bug #6993: Shooting your last round of ammunition causes the attack animation to cancel
Feature #6933: Support high-resolution cursor textures
Feature #6945: Support S3TC-compressed and BGR/BGRA NiPixelData Feature #6945: Support S3TC-compressed and BGR/BGRA NiPixelData
Feature #6979: Add support of loading and displaying LOD assets purely based on their filename extension
Feature #6983: PCVisionBonus script functions
Feature #6995: Localize the "show effect duration" option
0.48.0 0.48.0
------ ------
@ -165,6 +178,8 @@
Bug #6910: Torches should not be extinguished when not being held Bug #6910: Torches should not be extinguished when not being held
Bug #6913: Constant effect enchanted items don't break invisibility Bug #6913: Constant effect enchanted items don't break invisibility
Bug #6923: Dispose of corpse prevents respawning after load Bug #6923: Dispose of corpse prevents respawning after load
Bug #6937: Divided by Nix Hounds quest is broken
Bug #7008: Race condition on initializing a vector of reserved node names
Feature #890: OpenMW-CS: Column filtering Feature #890: OpenMW-CS: Column filtering
Feature #1465: "Reset" argument for AI functions Feature #1465: "Reset" argument for AI functions
Feature #2491: Ability to make OpenMW "portable" Feature #2491: Ability to make OpenMW "portable"

View file

@ -20,6 +20,11 @@ if(POLICY CMP0092)
cmake_policy(SET CMP0092 NEW) cmake_policy(SET CMP0092 NEW)
endif() endif()
# set the timestamps of extracted contents to the time of extraction
if(POLICY CMP0135)
cmake_policy(SET CMP0135 NEW)
endif()
project(OpenMW) project(OpenMW)
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD 20)
@ -238,17 +243,20 @@ if (USE_QT)
endif() endif()
set(USED_OSG_COMPONENTS set(USED_OSG_COMPONENTS
osgAnimation
osgDB osgDB
osgViewer
osgText
osgGA osgGA
osgParticle
osgUtil
osgFX osgFX
osgParticle
osgText
osgUtil
osgShadow osgShadow
osgAnimation) osgSim
osgViewer
)
set(USED_OSG_PLUGINS set(USED_OSG_PLUGINS
osgdb_bmp osgdb_bmp
osgdb_dae
osgdb_dds osgdb_dds
osgdb_freetype osgdb_freetype
osgdb_jpeg osgdb_jpeg

View file

@ -14,8 +14,8 @@ OpenMW also comes with OpenMW-CS, a replacement for Bethesda's Construction Set.
Font Licenses: Font Licenses:
* DejaVuLGCSansMono.ttf: custom (see [files/data/fonts/DejaVuFontLicense.txt](https://gitlab.com/OpenMW/openmw/-/raw/master/files/data/fonts/DejaVuFontLicense.txt) for more information) * DejaVuLGCSansMono.ttf: custom (see [files/data/fonts/DejaVuFontLicense.txt](https://gitlab.com/OpenMW/openmw/-/raw/master/files/data/fonts/DejaVuFontLicense.txt) for more information)
* OMWAyembedt.ttf: SIL Open Font License (see [files/data/fonts/OMWAyembedtFontLicense.txt](https://gitlab.com/OpenMW/openmw/-/raw/master/files/data/fonts/OMWAyembedtFontLicense.txt) for more information) * DemonicLetters.ttf: SIL Open Font License (see [files/data/fonts/DemonicLettersFontLicense.txt](https://gitlab.com/OpenMW/openmw/-/raw/master/files/data/fonts/DemonicLettersFontLicense.txt) for more information)
* Pelagiad.ttf: SIL Open Font License (see [files/data/fonts/PelagiadFontLicense.txt](https://gitlab.com/OpenMW/openmw/-/raw/master/files/data/fonts/PelagiadFontLicense.txt) for more information) * MysticCards.ttf: SIL Open Font License (see [files/data/fonts/MysticCardsFontLicense.txt](https://gitlab.com/OpenMW/openmw/-/raw/master/files/data/fonts/MysticCardsFontLicense.txt) for more information)
Current Status Current Status
-------------- --------------

View file

@ -1,6 +1,7 @@
#include <benchmark/benchmark.h> #include <benchmark/benchmark.h>
#include <components/detournavigator/navmeshtilescache.hpp> #include <components/detournavigator/navmeshtilescache.hpp>
#include <components/detournavigator/stats.hpp>
#include <components/esm3/loadland.hpp> #include <components/esm3/loadland.hpp>
#include <algorithm> #include <algorithm>
@ -139,12 +140,14 @@ namespace
const CollisionShapeType agentShapeType = CollisionShapeType::Aabb; const CollisionShapeType agentShapeType = CollisionShapeType::Aabb;
const osg::Vec3f agentHalfExtents = generateAgentHalfExtents(0.5, 1.5, random); const osg::Vec3f agentHalfExtents = generateAgentHalfExtents(0.5, 1.5, random);
const TilePosition tilePosition = generateVec2i(10000, random); const TilePosition tilePosition = generateVec2i(10000, random);
const std::size_t generation = std::uniform_int_distribution<std::size_t>(0, 100)(random); const Version version {
const std::size_t revision = std::uniform_int_distribution<std::size_t>(0, 10000)(random); .mGeneration = std::uniform_int_distribution<std::size_t>(0, 100)(random),
.mRevision = std::uniform_int_distribution<std::size_t>(0, 10000)(random),
};
Mesh mesh = generateMesh(triangles, random); Mesh mesh = generateMesh(triangles, random);
std::vector<CellWater> water; std::vector<CellWater> water;
generateWater(std::back_inserter(water), 1, random); generateWater(std::back_inserter(water), 1, random);
RecastMesh recastMesh(generation, revision, std::move(mesh), std::move(water), RecastMesh recastMesh(version, std::move(mesh), std::move(water),
{generateHeightfield(random)}, {generateFlatHeightfield(random)}, {}); {generateHeightfield(random)}, {generateFlatHeightfield(random)}, {});
return Key {AgentBounds {agentShapeType, agentHalfExtents}, tilePosition, std::move(recastMesh)}; return Key {AgentBounds {agentShapeType, agentHalfExtents}, tilePosition, std::move(recastMesh)};
} }

View file

@ -8,6 +8,9 @@
#include <components/bsa/compressedbsafile.hpp> #include <components/bsa/compressedbsafile.hpp>
#include <components/misc/strings/algorithm.hpp> #include <components/misc/strings/algorithm.hpp>
#include <components/files/configurationmanager.hpp>
#include <components/files/conversion.hpp>
#include <components/misc/strings/conversion.hpp>
#define BSATOOL_VERSION 1.1 #define BSATOOL_VERSION 1.1
@ -17,10 +20,10 @@ namespace bpo = boost::program_options;
struct Arguments struct Arguments
{ {
std::string mode; std::string mode;
std::string filename; std::filesystem::path filename;
std::string extractfile; std::filesystem::path extractfile;
std::string addfile; std::filesystem::path addfile;
std::string outdir; std::filesystem::path outdir;
bool longformat; bool longformat;
bool fullpath; bool fullpath;
@ -28,35 +31,37 @@ struct Arguments
bool parseOptions (int argc, char** argv, Arguments &info) bool parseOptions (int argc, char** argv, Arguments &info)
{ {
bpo::options_description desc("Inspect and extract files from Bethesda BSA archives\n\n" bpo::options_description desc(R"(Inspect and extract files from Bethesda BSA archives
"Usages:\n"
" bsatool list [-l] archivefile\n"
" List the files presents in the input archive.\n\n"
" bsatool extract [-f] archivefile [file_to_extract] [output_directory]\n"
" Extract a file from the input archive.\n\n"
" bsatool extractall archivefile [output_directory]\n"
" Extract all files from the input archive.\n\n"
" bsatool add [-a] archivefile file_to_add\n"
" Add a file to the input archive.\n\n"
" bsatool create [-c] archivefile\n"
" Create an archive.\n\n"
"Allowed options");
desc.add_options() Usages:
("help,h", "print help message.") bsatool list [-l] archivefile\n
("version,v", "print version information and quit.") List the files presents in the input archive.
("long,l", "Include extra information in archive listing.")
("full-path,f", "Create directory hierarchy on file extraction " bsatool extract [-f] archivefile [file_to_extract] [output_directory]
"(always true for extractall).") Extract a file from the input archive.
;
bsatool extractall archivefile [output_directory]
Extract all files from the input archive.
bsatool add [-a] archivefile file_to_add
Add a file to the input archive.
bsatool create [-c] archivefile
Create an archive.
Allowed options)");
auto addOption = desc.add_options();
addOption("help,h", "print help message.");
addOption("version,v", "print version information and quit.");
addOption("long,l", "Include extra information in archive listing.");
addOption("full-path,f", "Create directory hierarchy on file extraction (always true for extractall).");
// input-file is hidden and used as a positional argument // input-file is hidden and used as a positional argument
bpo::options_description hidden("Hidden Options"); bpo::options_description hidden("Hidden Options");
hidden.add_options() auto addHiddenOption = hidden.add_options();
( "mode,m", bpo::value<std::string>(), "bsatool mode") addHiddenOption("mode,m", bpo::value<std::string>(), "bsatool mode");
( "input-file,i", bpo::value< std::vector<std::string> >(), "input file") addHiddenOption("input-file,i", bpo::value< Files::MaybeQuotedPathContainer >(), "input file");
;
bpo::positional_options_description p; bpo::positional_options_description p;
p.add("mode", 1).add("input-file", 3); p.add("mode", 1).add("input-file", 3);
@ -112,37 +117,39 @@ bool parseOptions (int argc, char** argv, Arguments &info)
<< desc << std::endl; << desc << std::endl;
return false; return false;
} }
info.filename = variables["input-file"].as< std::vector<std::string> >()[0]; auto inputFiles = variables["input-file"].as< Files::MaybeQuotedPathContainer >();
info.filename = inputFiles[0].u8string(); // This call to u8string is redundant, but required to build on MSVC 14.26 due to implementation bugs.
// Default output to the working directory // Default output to the working directory
info.outdir = "."; info.outdir = std::filesystem::current_path();
if (info.mode == "extract") if (info.mode == "extract")
{ {
if (variables["input-file"].as< std::vector<std::string> >().size() < 2) if (inputFiles.size() < 2)
{ {
std::cout << "\nERROR: file to extract unspecified\n\n" std::cout << "\nERROR: file to extract unspecified\n\n"
<< desc << std::endl; << desc << std::endl;
return false; return false;
} }
if (variables["input-file"].as< std::vector<std::string> >().size() > 1) if (inputFiles.size() > 1)
info.extractfile = variables["input-file"].as< std::vector<std::string> >()[1]; info.extractfile = inputFiles[1].u8string(); // This call to u8string is redundant, but required to build on MSVC 14.26 due to implementation bugs.
if (variables["input-file"].as< std::vector<std::string> >().size() > 2) if (inputFiles.size() > 2)
info.outdir = variables["input-file"].as< std::vector<std::string> >()[2]; info.outdir = inputFiles[2].u8string(); // This call to u8string is redundant, but required to build on MSVC 14.26 due to implementation bugs.
} }
else if (info.mode == "add") else if (info.mode == "add")
{ {
if (variables["input-file"].as< std::vector<std::string> >().size() < 1) if (inputFiles.empty())
{ {
std::cout << "\nERROR: file to add unspecified\n\n" std::cout << "\nERROR: file to add unspecified\n\n"
<< desc << std::endl; << desc << std::endl;
return false; return false;
} }
if (variables["input-file"].as< std::vector<std::string> >().size() > 1) if (inputFiles.size() > 1)
info.addfile = variables["input-file"].as< std::vector<std::string> >()[1]; info.addfile = inputFiles[1].u8string(); // This call to u8string is redundant, but required to build on MSVC 14.26 due to implementation bugs.
} }
else if (variables["input-file"].as< std::vector<std::string> >().size() > 1) else if (inputFiles.size() > 1)
info.outdir = variables["input-file"].as< std::vector<std::string> >()[1]; info.outdir = inputFiles[1].u8string(); // This call to u8string is redundant, but required to build on MSVC 14.26 due to implementation bugs.
info.longformat = variables.count("long") != 0; info.longformat = variables.count("long") != 0;
info.fullpath = variables.count("full-path") != 0; info.fullpath = variables.count("full-path") != 0;
@ -176,17 +183,17 @@ int list(std::unique_ptr<File>& bsa, Arguments& info)
template<typename File> template<typename File>
int extract(std::unique_ptr<File>& bsa, Arguments& info) int extract(std::unique_ptr<File>& bsa, Arguments& info)
{ {
std::string archivePath = info.extractfile; auto archivePath = info.extractfile.u8string();
Misc::StringUtils::replaceAll(archivePath, "/", "\\"); Misc::StringUtils::replaceAll(archivePath, u8"/", u8"\\");
std::string extractPath = info.extractfile; auto extractPath = info.extractfile.u8string();
Misc::StringUtils::replaceAll(extractPath, "\\", "/"); Misc::StringUtils::replaceAll(extractPath, u8"\\", u8"/");
Files::IStreamPtr stream; Files::IStreamPtr stream;
// Get a stream for the file to extract // Get a stream for the file to extract
for (auto it = bsa->getList().rbegin(); it != bsa->getList().rend(); ++it) for (auto it = bsa->getList().rbegin(); it != bsa->getList().rend(); ++it)
{ {
if (Misc::StringUtils::ciEqual(std::string(it->name()), archivePath)) if (Misc::StringUtils::ciEqual(Misc::StringUtils::stringToU8String(it->name()), archivePath))
{ {
stream = bsa->getFile(&*it); stream = bsa->getFile(&*it);
break; break;
@ -194,20 +201,19 @@ int extract(std::unique_ptr<File>& bsa, Arguments& info)
} }
if (!stream) if (!stream)
{ {
std::cout << "ERROR: file '" << archivePath << "' not found\n"; std::cout << "ERROR: file '" << Misc::StringUtils::u8StringToString(archivePath) << "' not found\n";
std::cout << "In archive: " << info.filename << std::endl; std::cout << "In archive: " << Files::pathToUnicodeString(info.filename) << std::endl;
return 3; return 3;
} }
// Get the target path (the path the file will be extracted to) // Get the target path (the path the file will be extracted to)
std::filesystem::path relPath (extractPath); std::filesystem::path relPath (extractPath);
std::filesystem::path outdir (info.outdir);
std::filesystem::path target; std::filesystem::path target;
if (info.fullpath) if (info.fullpath)
target = outdir / relPath; target = info.outdir / relPath;
else else
target = outdir / relPath.filename(); target = info.outdir / relPath.filename();
// Create the directory hierarchy // Create the directory hierarchy
std::filesystem::create_directories(target.parent_path()); std::filesystem::create_directories(target.parent_path());
@ -215,14 +221,14 @@ int extract(std::unique_ptr<File>& bsa, Arguments& info)
std::filesystem::file_status s = std::filesystem::status(target.parent_path()); std::filesystem::file_status s = std::filesystem::status(target.parent_path());
if (!std::filesystem::is_directory(s)) if (!std::filesystem::is_directory(s))
{ {
std::cout << "ERROR: " << target.parent_path() << " is not a directory." << std::endl; std::cout << "ERROR: " << Files::pathToUnicodeString(target.parent_path()) << " is not a directory." << std::endl;
return 3; return 3;
} }
std::ofstream out(target, std::ios::binary); std::ofstream out(target, std::ios::binary);
// Write the file to disk // Write the file to disk
std::cout << "Extracting " << info.extractfile << " to " << target << std::endl; std::cout << "Extracting " << Files::pathToUnicodeString(info.extractfile) << " to " << Files::pathToUnicodeString(target) << std::endl;
out << stream->rdbuf(); out << stream->rdbuf();
out.close(); out.close();
@ -239,8 +245,8 @@ int extractAll(std::unique_ptr<File>& bsa, Arguments& info)
Misc::StringUtils::replaceAll(extractPath, "\\", "/"); Misc::StringUtils::replaceAll(extractPath, "\\", "/");
// Get the target path (the path the file will be extracted to) // Get the target path (the path the file will be extracted to)
std::filesystem::path target (info.outdir); auto target = info.outdir;
target /= extractPath; target /= Misc::StringUtils::stringToU8String(extractPath);
// Create the directory hierarchy // Create the directory hierarchy
std::filesystem::create_directories(target.parent_path()); std::filesystem::create_directories(target.parent_path());
@ -257,7 +263,7 @@ int extractAll(std::unique_ptr<File>& bsa, Arguments& info)
std::ofstream out(target, std::ios::binary); std::ofstream out(target, std::ios::binary);
// Write the file to disk // Write the file to disk
std::cout << "Extracting " << target << std::endl; std::cout << "Extracting " << Files::pathToUnicodeString(target) << std::endl;
out << data->rdbuf(); out << data->rdbuf();
out.close(); out.close();
} }
@ -269,7 +275,7 @@ template<typename File>
int add(std::unique_ptr<File>& bsa, Arguments& info) int add(std::unique_ptr<File>& bsa, Arguments& info)
{ {
std::fstream stream(info.addfile, std::ios_base::binary | std::ios_base::out | std::ios_base::in); std::fstream stream(info.addfile, std::ios_base::binary | std::ios_base::out | std::ios_base::in);
bsa->addFile(info.addfile, stream); bsa->addFile(Files::pathToUnicodeString(info.addfile), stream);
return 0; return 0;
} }

View file

@ -39,41 +39,39 @@ namespace
using Fallback::FallbackMap; using Fallback::FallbackMap;
bpo::options_description result; bpo::options_description result;
auto addOption = result.add_options();
addOption("help", "print help message");
result.add_options() addOption("version", "print version information and quit");
("help", "print help message")
("version", "print version information and quit") addOption("data", bpo::value<Files::MaybeQuotedPathContainer>()->default_value(Files::MaybeQuotedPathContainer(), "data")
->multitoken()->composing(), "set data directories (later directories have higher priority)");
("data", bpo::value<Files::MaybeQuotedPathContainer>()->default_value(Files::MaybeQuotedPathContainer(), "data") addOption("data-local", bpo::value<Files::MaybeQuotedPathContainer::value_type>()->default_value(Files::MaybeQuotedPathContainer::value_type(), ""),
->multitoken()->composing(), "set data directories (later directories have higher priority)") "set local data directory (highest priority)");
("data-local", bpo::value<Files::MaybeQuotedPathContainer::value_type>()->default_value(Files::MaybeQuotedPathContainer::value_type(), ""), addOption("fallback-archive", bpo::value<StringsVector>()->default_value(StringsVector(), "fallback-archive")
"set local data directory (highest priority)") ->multitoken()->composing(), "set fallback BSA archives (later archives have higher priority)");
("fallback-archive", bpo::value<StringsVector>()->default_value(StringsVector(), "fallback-archive") addOption("resources", bpo::value<Files::MaybeQuotedPath>()->default_value(Files::MaybeQuotedPath(), "resources"),
->multitoken()->composing(), "set fallback BSA archives (later archives have higher priority)") "set resources directory");
("resources", bpo::value<Files::MaybeQuotedPath>()->default_value(Files::MaybeQuotedPath(), "resources"), addOption("content", bpo::value<StringsVector>()->default_value(StringsVector(), "")
"set resources directory") ->multitoken()->composing(), "content file(s): esm/esp, or omwgame/omwaddon/omwscripts");
("content", bpo::value<StringsVector>()->default_value(StringsVector(), "") addOption("fs-strict", bpo::value<bool>()->implicit_value(true)
->multitoken()->composing(), "content file(s): esm/esp, or omwgame/omwaddon/omwscripts") ->default_value(false), "strict file system handling (no case folding)");
("fs-strict", bpo::value<bool>()->implicit_value(true) addOption("encoding", bpo::value<std::string>()->
->default_value(false), "strict file system handling (no case folding)")
("encoding", bpo::value<std::string>()->
default_value("win1252"), default_value("win1252"),
"Character encoding used in OpenMW game messages:\n" "Character encoding used in OpenMW game messages:\n"
"\n\twin1250 - Central and Eastern European such as Polish, Czech, Slovak, Hungarian, Slovene, Bosnian, Croatian, Serbian (Latin script), Romanian and Albanian languages\n" "\n\twin1250 - Central and Eastern European such as Polish, Czech, Slovak, Hungarian, Slovene, Bosnian, Croatian, Serbian (Latin script), Romanian and Albanian languages\n"
"\n\twin1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages\n" "\n\twin1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages\n"
"\n\twin1252 - Western European (Latin) alphabet, used by default") "\n\twin1252 - Western European (Latin) alphabet, used by default");
("fallback", bpo::value<FallbackMap>()->default_value(FallbackMap(), "") addOption("fallback", bpo::value<FallbackMap>()->default_value(FallbackMap(), "")
->multitoken()->composing(), "fallback values") ->multitoken()->composing(), "fallback values");
; ;
Files::ConfigurationManager::addCommonOptions(result); Files::ConfigurationManager::addCommonOptions(result);
return result; return result;
@ -145,7 +143,7 @@ namespace
const auto fsStrict = variables["fs-strict"].as<bool>(); const auto fsStrict = variables["fs-strict"].as<bool>();
const auto resDir = variables["resources"].as<Files::MaybeQuotedPath>(); const auto resDir = variables["resources"].as<Files::MaybeQuotedPath>();
Version::Version v = Version::getOpenmwVersion(resDir.string()); const auto v = Version::getOpenmwVersion(resDir);
Log(Debug::Info) << v.describe(); Log(Debug::Info) << v.describe();
dataDirs.insert(dataDirs.begin(), resDir / "vfs"); dataDirs.insert(dataDirs.begin(), resDir / "vfs");
const auto fileCollections = Files::Collections(dataDirs, !fsStrict); const auto fileCollections = Files::Collections(dataDirs, !fsStrict);

View file

@ -3,7 +3,7 @@
#include <vector> #include <vector>
#include <optional> #include <optional>
#include <string> #include <filesystem>
#include <components/esm/format.hpp> #include <components/esm/format.hpp>
@ -18,8 +18,8 @@ namespace EsmTool
std::string mode; std::string mode;
std::string encoding; std::string encoding;
std::string filename; std::filesystem::path filename;
std::string outname; std::filesystem::path outname;
std::vector<std::string> types; std::vector<std::string> types;
std::string name; std::string name;

View file

@ -17,6 +17,8 @@
#include <components/esm/format.hpp> #include <components/esm/format.hpp>
#include <components/files/openfile.hpp> #include <components/files/openfile.hpp>
#include <components/misc/strings/algorithm.hpp> #include <components/misc/strings/algorithm.hpp>
#include <components/files/configurationmanager.hpp>
#include <components/files/conversion.hpp>
#include "record.hpp" #include "record.hpp"
#include "labels.hpp" #include "labels.hpp"
@ -46,29 +48,35 @@ struct ESMData
bool parseOptions (int argc, char** argv, Arguments &info) bool parseOptions (int argc, char** argv, Arguments &info)
{ {
bpo::options_description desc("Inspect and extract from Morrowind ES files (ESM, ESP, ESS)\nSyntax: esmtool [options] mode infile [outfile]\nAllowed modes:\n dump\t Dumps all readable data from the input file.\n clone\t Clones the input file to the output file.\n comp\t Compares the given files.\n\nAllowed options"); bpo::options_description desc(R"(Inspect and extract from Morrowind ES files (ESM, ESP, ESS)
Syntax: esmtool [options] mode infile [outfile]
Allowed modes:
dump Dumps all readable data from the input file.
clone Clones the input file to the output file.
comp Compares the given files.
desc.add_options() Allowed options)");
("help,h", "print help message.") auto addOption = desc.add_options();
("version,v", "print version information and quit.") addOption("help,h", "print help message.");
("raw,r", bpo::value<std::string>(), addOption("version,v", "print version information and quit.");
addOption("raw,r", bpo::value<std::string>(),
"Show an unformatted list of all records and subrecords of given format:\n" "Show an unformatted list of all records and subrecords of given format:\n"
"\n\tTES3" "\n\tTES3"
"\n\tTES4") "\n\tTES4");
// The intention is that this option would interact better // The intention is that this option would interact better
// with other modes including clone, dump, and raw. // with other modes including clone, dump, and raw.
("type,t", bpo::value< std::vector<std::string> >(), addOption("type,t", bpo::value< std::vector<std::string> >(),
"Show only records of this type (four character record code). May " "Show only records of this type (four character record code). May "
"be specified multiple times. Only affects dump mode.") "be specified multiple times. Only affects dump mode.");
("name,n", bpo::value<std::string>(), addOption("name,n", bpo::value<std::string>(),
"Show only the record with this name. Only affects dump mode.") "Show only the record with this name. Only affects dump mode.");
("plain,p", "Print contents of dialogs, books and scripts. " addOption("plain,p", "Print contents of dialogs, books and scripts. "
"(skipped by default)" "(skipped by default)"
"Only affects dump mode.") "Only affects dump mode.");
("quiet,q", "Suppress all record information. Useful for speed tests.") addOption("quiet,q", "Suppress all record information. Useful for speed tests.");
("loadcells,C", "Browse through contents of all cells.") addOption("loadcells,C", "Browse through contents of all cells.");
( "encoding,e", bpo::value<std::string>(&(info.encoding))-> addOption( "encoding,e", bpo::value<std::string>(&(info.encoding))->
default_value("win1252"), default_value("win1252"),
"Character encoding used in ESMTool:\n" "Character encoding used in ESMTool:\n"
"\n\twin1250 - Central and Eastern European such as Polish, Czech, Slovak, Hungarian, Slovene, Bosnian, Croatian, Serbian (Latin script), Romanian and Albanian languages\n" "\n\twin1250 - Central and Eastern European such as Polish, Czech, Slovak, Hungarian, Slovene, Bosnian, Croatian, Serbian (Latin script), Romanian and Albanian languages\n"
@ -80,11 +88,9 @@ bool parseOptions (int argc, char** argv, Arguments &info)
// input-file is hidden and used as a positional argument // input-file is hidden and used as a positional argument
bpo::options_description hidden("Hidden Options"); bpo::options_description hidden("Hidden Options");
auto addHiddenOption = hidden.add_options();
hidden.add_options() addHiddenOption( "mode,m", bpo::value<std::string>(), "esmtool mode");
( "mode,m", bpo::value<std::string>(), "esmtool mode") addHiddenOption( "input-file,i", bpo::value< Files::MaybeQuotedPathContainer >(), "input file");
( "input-file,i", bpo::value< std::vector<std::string> >(), "input file")
;
bpo::positional_options_description p; bpo::positional_options_description p;
p.add("mode", 1).add("input-file", 2); p.add("mode", 1).add("input-file", 2);
@ -154,9 +160,10 @@ bool parseOptions (int argc, char** argv, Arguments &info)
return false; return false;
}*/ }*/
info.filename = variables["input-file"].as< std::vector<std::string> >()[0]; const auto inputFiles = variables["input-file"].as< Files::MaybeQuotedPathContainer >();
if (variables["input-file"].as< std::vector<std::string> >().size() > 1) info.filename = inputFiles[0].u8string(); // This call to u8string is redundant, but required to build on MSVC 14.26 due to implementation bugs.
info.outname = variables["input-file"].as< std::vector<std::string> >()[1]; if (inputFiles.size() > 1)
info.outname = inputFiles[1].u8string(); // This call to u8string is redundant, but required to build on MSVC 14.26 due to implementation bugs.
if (const auto it = variables.find("raw"); it != variables.end()) if (const auto it = variables.find("raw"); it != variables.end())
info.mRawFormat = ESM::parseFormat(it->second.as<std::string>()); info.mRawFormat = ESM::parseFormat(it->second.as<std::string>());
@ -284,9 +291,9 @@ void loadCell(const Arguments& info, ESM::Cell &cell, ESM::ESMReader &esm, ESMDa
} }
} }
void printRawTes3(std::string_view path) void printRawTes3(const std::filesystem::path &path)
{ {
std::cout << "TES3 RAW file listing: " << path << '\n'; std::cout << "TES3 RAW file listing: " << Files::pathToUnicodeString(path) << '\n';
ESM::ESMReader esm; ESM::ESMReader esm;
esm.openRaw(path); esm.openRaw(path);
while(esm.hasMoreRecs()) while(esm.hasMoreRecs())
@ -419,7 +426,7 @@ int load(const Arguments& info, ESMData* data)
printRawTes3(info.filename); printRawTes3(info.filename);
break; break;
case ESM::Format::Tes4: case ESM::Format::Tes4:
std::cout << "Printing raw TES4 file is not supported: " << info.filename << "\n"; std::cout << "Printing raw TES4 file is not supported: " << Files::pathToUnicodeString(info.filename) << "\n";
break; break;
} }
return 0; return 0;
@ -490,7 +497,7 @@ int clone(const Arguments& info)
if (i % 3 != 0) if (i % 3 != 0)
std::cout << '\n'; std::cout << '\n';
std::cout << "\nSaving records to: " << info.outname << "...\n"; std::cout << "\nSaving records to: " << Files::pathToUnicodeString(info.outname) << "...\n";
ESM::ESMWriter esm; ESM::ESMWriter esm;
ToUTF8::Utf8Encoder encoder (ToUTF8::calculateEncoding(info.encoding)); ToUTF8::Utf8Encoder encoder (ToUTF8::calculateEncoding(info.encoding));
@ -499,7 +506,7 @@ int clone(const Arguments& info)
esm.setVersion(ESM::VER_13); esm.setVersion(ESM::VER_13);
esm.setRecordCount (recordCount); esm.setRecordCount (recordCount);
std::fstream save(info.outname.c_str(), std::fstream::out | std::fstream::binary); std::fstream save(info.outname, std::fstream::out | std::fstream::binary);
esm.save(save); esm.save(save);
int saved = 0; int saved = 0;
@ -563,14 +570,14 @@ int comp(const Arguments& info)
ESMData dataOne; ESMData dataOne;
if (load(fileOne, &dataOne) != 0) if (load(fileOne, &dataOne) != 0)
{ {
std::cout << "Failed to load " << info.filename << ", aborting comparison." << std::endl; std::cout << "Failed to load " << Files::pathToUnicodeString(info.filename) << ", aborting comparison." << std::endl;
return 1; return 1;
} }
ESMData dataTwo; ESMData dataTwo;
if (load(fileTwo, &dataTwo) != 0) if (load(fileTwo, &dataTwo) != 0)
{ {
std::cout << "Failed to load " << info.outname << ", aborting comparison." << std::endl; std::cout << "Failed to load " << Files::pathToUnicodeString(info.outname) << ", aborting comparison." << std::endl;
return 1; return 1;
} }

View file

@ -15,11 +15,11 @@
#include <components/misc/strings/format.hpp> #include <components/misc/strings/format.hpp>
std::string bodyPartLabel(int idx) std::string_view bodyPartLabel(int idx)
{ {
if (idx >= 0 && idx <= 26) if (idx >= 0 && idx <= 26)
{ {
static const char *bodyPartLabels[] = { static constexpr std::string_view bodyPartLabels[] = {
"Head", "Head",
"Hair", "Hair",
"Neck", "Neck",
@ -46,7 +46,7 @@ std::string bodyPartLabel(int idx)
"Right Shoulder", "Right Shoulder",
"Left Shoulder", "Left Shoulder",
"Weapon", "Weapon",
"Tail" "Tail",
}; };
return bodyPartLabels[idx]; return bodyPartLabels[idx];
} }
@ -54,11 +54,11 @@ std::string bodyPartLabel(int idx)
return "Invalid"; return "Invalid";
} }
std::string meshPartLabel(int idx) std::string_view meshPartLabel(int idx)
{ {
if (idx >= 0 && idx <= ESM::BodyPart::MP_Tail) if (idx >= 0 && idx <= ESM::BodyPart::MP_Tail)
{ {
static const char *meshPartLabels[] = { static constexpr std::string_view meshPartLabels[] = {
"Head", "Head",
"Hair", "Hair",
"Neck", "Neck",
@ -73,7 +73,7 @@ std::string meshPartLabel(int idx)
"Knee", "Knee",
"Upper Leg", "Upper Leg",
"Clavicle", "Clavicle",
"Tail" "Tail",
}; };
return meshPartLabels[idx]; return meshPartLabels[idx];
} }
@ -81,14 +81,14 @@ std::string meshPartLabel(int idx)
return "Invalid"; return "Invalid";
} }
std::string meshTypeLabel(int idx) std::string_view meshTypeLabel(int idx)
{ {
if (idx >= 0 && idx <= ESM::BodyPart::MT_Armor) if (idx >= 0 && idx <= ESM::BodyPart::MT_Armor)
{ {
static const char *meshTypeLabels[] = { static constexpr std::string_view meshTypeLabels[] = {
"Skin", "Skin",
"Clothing", "Clothing",
"Armor" "Armor",
}; };
return meshTypeLabels[idx]; return meshTypeLabels[idx];
} }
@ -96,11 +96,11 @@ std::string meshTypeLabel(int idx)
return "Invalid"; return "Invalid";
} }
std::string clothingTypeLabel(int idx) std::string_view clothingTypeLabel(int idx)
{ {
if (idx >= 0 && idx <= 9) if (idx >= 0 && idx <= 9)
{ {
static const char *clothingTypeLabels[] = { static constexpr std::string_view clothingTypeLabels[] = {
"Pants", "Pants",
"Shoes", "Shoes",
"Shirt", "Shirt",
@ -110,7 +110,7 @@ std::string clothingTypeLabel(int idx)
"Left Glove", "Left Glove",
"Skirt", "Skirt",
"Ring", "Ring",
"Amulet" "Amulet",
}; };
return clothingTypeLabels[idx]; return clothingTypeLabels[idx];
} }
@ -118,11 +118,11 @@ std::string clothingTypeLabel(int idx)
return "Invalid"; return "Invalid";
} }
std::string armorTypeLabel(int idx) std::string_view armorTypeLabel(int idx)
{ {
if (idx >= 0 && idx <= 10) if (idx >= 0 && idx <= 10)
{ {
static const char *armorTypeLabels[] = { static constexpr std::string_view armorTypeLabels[] = {
"Helmet", "Helmet",
"Cuirass", "Cuirass",
"Left Pauldron", "Left Pauldron",
@ -133,7 +133,7 @@ std::string armorTypeLabel(int idx)
"Right Gauntlet", "Right Gauntlet",
"Shield", "Shield",
"Left Bracer", "Left Bracer",
"Right Bracer" "Right Bracer",
}; };
return armorTypeLabels[idx]; return armorTypeLabels[idx];
} }
@ -141,16 +141,16 @@ std::string armorTypeLabel(int idx)
return "Invalid"; return "Invalid";
} }
std::string dialogTypeLabel(int idx) std::string_view dialogTypeLabel(int idx)
{ {
if (idx >= 0 && idx <= 4) if (idx >= 0 && idx <= 4)
{ {
static const char *dialogTypeLabels[] = { static constexpr std::string_view dialogTypeLabels[] = {
"Topic", "Topic",
"Voice", "Voice",
"Greeting", "Greeting",
"Persuasion", "Persuasion",
"Journal" "Journal",
}; };
return dialogTypeLabels[idx]; return dialogTypeLabels[idx];
} }
@ -160,16 +160,16 @@ std::string dialogTypeLabel(int idx)
return "Invalid"; return "Invalid";
} }
std::string questStatusLabel(int idx) std::string_view questStatusLabel(int idx)
{ {
if (idx >= 0 && idx <= 4) if (idx >= 0 && idx <= 4)
{ {
static const char *questStatusLabels[] = { static constexpr std::string_view questStatusLabels[] = {
"None", "None",
"Name", "Name",
"Finished", "Finished",
"Restart", "Restart",
"Deleted" "Deleted",
}; };
return questStatusLabels[idx]; return questStatusLabels[idx];
} }
@ -177,11 +177,11 @@ std::string questStatusLabel(int idx)
return "Invalid"; return "Invalid";
} }
std::string creatureTypeLabel(int idx) std::string_view creatureTypeLabel(int idx)
{ {
if (idx >= 0 && idx <= 3) if (idx >= 0 && idx <= 3)
{ {
static const char *creatureTypeLabels[] = { static constexpr std::string_view creatureTypeLabels[] = {
"Creature", "Creature",
"Daedra", "Daedra",
"Undead", "Undead",
@ -193,11 +193,11 @@ std::string creatureTypeLabel(int idx)
return "Invalid"; return "Invalid";
} }
std::string soundTypeLabel(int idx) std::string_view soundTypeLabel(int idx)
{ {
if (idx >= 0 && idx <= 7) if (idx >= 0 && idx <= 7)
{ {
static const char *soundTypeLabels[] = { static constexpr std::string_view soundTypeLabels[] = {
"Left Foot", "Left Foot",
"Right Foot", "Right Foot",
"Swim Left", "Swim Left",
@ -205,7 +205,7 @@ std::string soundTypeLabel(int idx)
"Moan", "Moan",
"Roar", "Roar",
"Scream", "Scream",
"Land" "Land",
}; };
return soundTypeLabels[idx]; return soundTypeLabels[idx];
} }
@ -213,11 +213,11 @@ std::string soundTypeLabel(int idx)
return "Invalid"; return "Invalid";
} }
std::string weaponTypeLabel(int idx) std::string_view weaponTypeLabel(int idx)
{ {
if (idx >= 0 && idx <= 13) if (idx >= 0 && idx <= 13)
{ {
static const char *weaponTypeLabels[] = { static constexpr std::string_view weaponTypeLabels[] = {
"Short Blade One Hand", "Short Blade One Hand",
"Long Blade One Hand", "Long Blade One Hand",
"Long Blade Two Hand", "Long Blade Two Hand",
@ -231,7 +231,7 @@ std::string weaponTypeLabel(int idx)
"Marksman Crossbow", "Marksman Crossbow",
"Marksman Thrown", "Marksman Thrown",
"Arrow", "Arrow",
"Bolt" "Bolt",
}; };
return weaponTypeLabels[idx]; return weaponTypeLabels[idx];
} }
@ -239,21 +239,24 @@ std::string weaponTypeLabel(int idx)
return "Invalid"; return "Invalid";
} }
std::string aiTypeLabel(int type) std::string_view aiTypeLabel(ESM::AiPackageType type)
{ {
if (type == ESM::AI_Wander) return "Wander"; switch (type)
else if (type == ESM::AI_Travel) return "Travel"; {
else if (type == ESM::AI_Follow) return "Follow"; case ESM::AI_Wander: return "Wander";
else if (type == ESM::AI_Escort) return "Escort"; case ESM::AI_Travel: return "Travel";
else if (type == ESM::AI_Activate) return "Activate"; case ESM::AI_Follow: return "Follow";
else return "Invalid"; case ESM::AI_Escort: return "Escort";
case ESM::AI_Activate: return "Activate";
}
return "Invalid";
} }
std::string magicEffectLabel(int idx) std::string_view magicEffectLabel(int idx)
{ {
if (idx >= 0 && idx <= 142) if (idx >= 0 && idx <= 142)
{ {
const char* magicEffectLabels [] = { static constexpr std::string_view magicEffectLabels [] = {
"Water Breathing", "Water Breathing",
"Swift Swim", "Swift Swim",
"Water Walking", "Water Walking",
@ -396,7 +399,7 @@ std::string magicEffectLabel(int idx)
"sEffectSummonCreature02", "sEffectSummonCreature02",
"sEffectSummonCreature03", "sEffectSummonCreature03",
"sEffectSummonCreature04", "sEffectSummonCreature04",
"sEffectSummonCreature05" "sEffectSummonCreature05",
}; };
return magicEffectLabels[idx]; return magicEffectLabels[idx];
} }
@ -404,11 +407,11 @@ std::string magicEffectLabel(int idx)
return "Invalid"; return "Invalid";
} }
std::string attributeLabel(int idx) std::string_view attributeLabel(int idx)
{ {
if (idx >= 0 && idx <= 7) if (idx >= 0 && idx <= 7)
{ {
const char* attributeLabels [] = { static constexpr std::string_view attributeLabels [] = {
"Strength", "Strength",
"Intelligence", "Intelligence",
"Willpower", "Willpower",
@ -416,7 +419,7 @@ std::string attributeLabel(int idx)
"Speed", "Speed",
"Endurance", "Endurance",
"Personality", "Personality",
"Luck" "Luck",
}; };
return attributeLabels[idx]; return attributeLabels[idx];
} }
@ -424,17 +427,17 @@ std::string attributeLabel(int idx)
return "Invalid"; return "Invalid";
} }
std::string spellTypeLabel(int idx) std::string_view spellTypeLabel(int idx)
{ {
if (idx >= 0 && idx <= 5) if (idx >= 0 && idx <= 5)
{ {
const char* spellTypeLabels [] = { static constexpr std::string_view spellTypeLabels [] = {
"Spells", "Spells",
"Abilities", "Abilities",
"Blight Disease", "Blight Disease",
"Disease", "Disease",
"Curse", "Curse",
"Powers" "Powers",
}; };
return spellTypeLabels[idx]; return spellTypeLabels[idx];
} }
@ -442,14 +445,14 @@ std::string spellTypeLabel(int idx)
return "Invalid"; return "Invalid";
} }
std::string specializationLabel(int idx) std::string_view specializationLabel(int idx)
{ {
if (idx >= 0 && idx <= 2) if (idx >= 0 && idx <= 2)
{ {
const char* specializationLabels [] = { static constexpr std::string_view specializationLabels [] = {
"Combat", "Combat",
"Magic", "Magic",
"Stealth" "Stealth",
}; };
return specializationLabels[idx]; return specializationLabels[idx];
} }
@ -457,11 +460,11 @@ std::string specializationLabel(int idx)
return "Invalid"; return "Invalid";
} }
std::string skillLabel(int idx) std::string_view skillLabel(int idx)
{ {
if (idx >= 0 && idx <= 26) if (idx >= 0 && idx <= 26)
{ {
const char* skillLabels [] = { static constexpr std::string_view skillLabels [] = {
"Block", "Block",
"Armorer", "Armorer",
"Medium Armor", "Medium Armor",
@ -488,7 +491,7 @@ std::string skillLabel(int idx)
"Marksman", "Marksman",
"Mercantile", "Mercantile",
"Speechcraft", "Speechcraft",
"Hand-to-hand" "Hand-to-hand",
}; };
return skillLabels[idx]; return skillLabels[idx];
} }
@ -496,11 +499,11 @@ std::string skillLabel(int idx)
return "Invalid"; return "Invalid";
} }
std::string apparatusTypeLabel(int idx) std::string_view apparatusTypeLabel(int idx)
{ {
if (idx >= 0 && idx <= 3) if (idx >= 0 && idx <= 3)
{ {
const char* apparatusTypeLabels [] = { static constexpr std::string_view apparatusTypeLabels [] = {
"Mortar", "Mortar",
"Alembic", "Alembic",
"Calcinator", "Calcinator",
@ -512,14 +515,14 @@ std::string apparatusTypeLabel(int idx)
return "Invalid"; return "Invalid";
} }
std::string rangeTypeLabel(int idx) std::string_view rangeTypeLabel(int idx)
{ {
if (idx >= 0 && idx <= 2) if (idx >= 0 && idx <= 2)
{ {
const char* rangeTypeLabels [] = { static constexpr std::string_view rangeTypeLabels [] = {
"Self", "Self",
"Touch", "Touch",
"Target" "Target",
}; };
return rangeTypeLabels[idx]; return rangeTypeLabels[idx];
} }
@ -527,17 +530,17 @@ std::string rangeTypeLabel(int idx)
return "Invalid"; return "Invalid";
} }
std::string schoolLabel(int idx) std::string_view schoolLabel(int idx)
{ {
if (idx >= 0 && idx <= 5) if (idx >= 0 && idx <= 5)
{ {
const char* schoolLabels [] = { static constexpr std::string_view schoolLabels [] = {
"Alteration", "Alteration",
"Conjuration", "Conjuration",
"Destruction", "Destruction",
"Illusion", "Illusion",
"Mysticism", "Mysticism",
"Restoration" "Restoration",
}; };
return schoolLabels[idx]; return schoolLabels[idx];
} }
@ -545,15 +548,15 @@ std::string schoolLabel(int idx)
return "Invalid"; return "Invalid";
} }
std::string enchantTypeLabel(int idx) std::string_view enchantTypeLabel(int idx)
{ {
if (idx >= 0 && idx <= 3) if (idx >= 0 && idx <= 3)
{ {
const char* enchantTypeLabels [] = { static constexpr std::string_view enchantTypeLabels [] = {
"Cast Once", "Cast Once",
"Cast When Strikes", "Cast When Strikes",
"Cast When Used", "Cast When Used",
"Constant Effect" "Constant Effect",
}; };
return enchantTypeLabels[idx]; return enchantTypeLabels[idx];
} }
@ -561,11 +564,11 @@ std::string enchantTypeLabel(int idx)
return "Invalid"; return "Invalid";
} }
std::string ruleFunction(int idx) std::string_view ruleFunction(int idx)
{ {
if (idx >= 0 && idx <= 72) if (idx >= 0 && idx <= 72)
{ {
std::string ruleFunctions[] = { static constexpr std::string_view ruleFunctions[] = {
"Reaction Low", "Reaction Low",
"Reaction High", "Reaction High",
"Rank Requirement", "Rank Requirement",
@ -638,7 +641,7 @@ std::string ruleFunction(int idx)
"Alarm", "Alarm",
"Flee", "Flee",
"Should Attack", "Should Attack",
"Werewolf" "Werewolf",
}; };
return ruleFunctions[idx]; return ruleFunctions[idx];
} }

View file

@ -2,26 +2,29 @@
#define OPENMW_ESMTOOL_LABELS_H #define OPENMW_ESMTOOL_LABELS_H
#include <string> #include <string>
#include <string_view>
std::string bodyPartLabel(int idx); #include <components/esm3/aipackage.hpp>
std::string meshPartLabel(int idx);
std::string meshTypeLabel(int idx); std::string_view bodyPartLabel(int idx);
std::string clothingTypeLabel(int idx); std::string_view meshPartLabel(int idx);
std::string armorTypeLabel(int idx); std::string_view meshTypeLabel(int idx);
std::string dialogTypeLabel(int idx); std::string_view clothingTypeLabel(int idx);
std::string questStatusLabel(int idx); std::string_view armorTypeLabel(int idx);
std::string creatureTypeLabel(int idx); std::string_view dialogTypeLabel(int idx);
std::string soundTypeLabel(int idx); std::string_view questStatusLabel(int idx);
std::string weaponTypeLabel(int idx); std::string_view creatureTypeLabel(int idx);
std::string_view soundTypeLabel(int idx);
std::string_view weaponTypeLabel(int idx);
// This function's a bit different because the types are record types, // This function's a bit different because the types are record types,
// not consecutive values. // not consecutive values.
std::string aiTypeLabel(int type); std::string_view aiTypeLabel(ESM::AiPackageType type);
// This one's also a bit different, because it enumerates dialog // This one's also a bit different, because it enumerates dialog
// select rule functions, not types. Structurally, it still converts // select rule functions, not types. Structurally, it still converts
// indexes to strings for display. // indexes to strings for display.
std::string ruleFunction(int idx); std::string_view ruleFunction(int idx);
// The labels below here can all be loaded from GMSTs, but are not // The labels below here can all be loaded from GMSTs, but are not
// currently because among other things, that requires loading the // currently because among other things, that requires loading the
@ -32,15 +35,15 @@ std::string ruleFunction(int idx);
// and the indexes for referencing the types in other records in the // and the indexes for referencing the types in other records in the
// database. Then a single label function could work for all types. // database. Then a single label function could work for all types.
std::string magicEffectLabel(int idx); std::string_view magicEffectLabel(int idx);
std::string attributeLabel(int idx); std::string_view attributeLabel(int idx);
std::string spellTypeLabel(int idx); std::string_view spellTypeLabel(int idx);
std::string specializationLabel(int idx); std::string_view specializationLabel(int idx);
std::string skillLabel(int idx); std::string_view skillLabel(int idx);
std::string apparatusTypeLabel(int idx); std::string_view apparatusTypeLabel(int idx);
std::string rangeTypeLabel(int idx); std::string_view rangeTypeLabel(int idx);
std::string schoolLabel(int idx); std::string_view schoolLabel(int idx);
std::string enchantTypeLabel(int idx); std::string_view enchantTypeLabel(int idx);
// The are the flag functions that convert a bitmask into a list of // The are the flag functions that convert a bitmask into a list of
// human readble strings representing the set bits. // human readble strings representing the set bits.

View file

@ -73,7 +73,7 @@ std::string ruleString(const ESM::DialInfo::SelectStruct& ss)
{ {
case '1': case '1':
type_str = "Function"; type_str = "Function";
func_str = ruleFunction(func); func_str = std::string(ruleFunction(func));
break; break;
case '2': case '2':
if (indicator == 's') type_str = "Global short"; if (indicator == 's') type_str = "Global short";

View file

@ -9,6 +9,7 @@
#include <components/esm/esmcommon.hpp> #include <components/esm/esmcommon.hpp>
#include <components/esm4/reader.hpp> #include <components/esm4/reader.hpp>
#include <components/esm4/records.hpp> #include <components/esm4/records.hpp>
#include <components/to_utf8/to_utf8.hpp>
namespace EsmTool namespace EsmTool
{ {
@ -61,6 +62,63 @@ namespace EsmTool
template <class T> template <class T>
constexpr bool hasFlags = HasFlags<T>::value; constexpr bool hasFlags = HasFlags<T>::value;
template <class T, class = std::void_t<>>
struct HasEditorId : std::false_type {};
template <class T>
struct HasEditorId<T, std::void_t<decltype(T::mEditorId)>> : std::true_type {};
template <class T>
constexpr bool hasEditorId = HasEditorId<T>::value;
template <class T, class = std::void_t<>>
struct HasModel : std::false_type {};
template <class T>
struct HasModel<T, std::void_t<decltype(T::mModel)>> : std::true_type {};
template <class T>
constexpr bool hasModel = HasModel<T>::value;
template <class T, class = std::void_t<>>
struct HasNif : std::false_type {};
template <class T>
struct HasNif<T, std::void_t<decltype(T::mNif)>> : std::true_type {};
template <class T>
constexpr bool hasNif = HasNif<T>::value;
template <class T, class = std::void_t<>>
struct HasKf : std::false_type {};
template <class T>
struct HasKf<T, std::void_t<decltype(T::mKf)>> : std::true_type {};
template <class T>
constexpr bool hasKf = HasKf<T>::value;
template <class T>
struct WriteArray
{
std::string_view mPrefix;
const T& mValue;
explicit WriteArray(std::string_view prefix, const T& value)
: mPrefix(prefix)
, mValue(value)
{
}
};
template <class T>
std::ostream& operator<<(std::ostream& stream, const WriteArray<T>& write)
{
for (const auto& value : write.mValue)
stream << write.mPrefix << value;
return stream;
}
template <class T> template <class T>
void readTypedRecord(const Params& params, ESM4::Reader& reader) void readTypedRecord(const Params& params, ESM4::Reader& reader)
{ {
@ -74,9 +132,17 @@ namespace EsmTool
std::cout << "\n Record: " << ESM::NAME(reader.hdr().record.typeId).toStringView(); std::cout << "\n Record: " << ESM::NAME(reader.hdr().record.typeId).toStringView();
if constexpr (hasFormId<T>) if constexpr (hasFormId<T>)
std::cout << ' ' << value.mFormId; std::cout << "\n FormId: " << value.mFormId;
if constexpr (hasFlags<T>) if constexpr (hasFlags<T>)
std::cout << "\n Record flags: " << recordFlags(value.mFlags); std::cout << "\n Record flags: " << recordFlags(value.mFlags);
if constexpr (hasEditorId<T>)
std::cout << "\n EditorId: " << value.mEditorId;
if constexpr (hasModel<T>)
std::cout << "\n Model: " << value.mModel;
if constexpr (hasNif<T>)
std::cout << "\n Nif:" << WriteArray("\n - ", value.mNif);
if constexpr (hasKf<T>)
std::cout << "\n Kf:" << WriteArray("\n - ", value.mKf);
std::cout << '\n'; std::cout << '\n';
} }

View file

@ -104,11 +104,11 @@ namespace ESSImport
esm.getSubNameIs("MAPD"); esm.getSubNameIs("MAPD");
esm.getSubHeader(); esm.getSubHeader();
data.resize(esm.getSubSize()); data.resize(esm.getSubSize());
esm.getExact(&data[0], data.size()); esm.getExact(data.data(), data.size());
mGlobalMapImage = new osg::Image; mGlobalMapImage = new osg::Image;
mGlobalMapImage->allocateImage(maph.size, maph.size, 1, GL_RGB, GL_UNSIGNED_BYTE); mGlobalMapImage->allocateImage(maph.size, maph.size, 1, GL_RGB, GL_UNSIGNED_BYTE);
memcpy(mGlobalMapImage->data(), &data[0], data.size()); memcpy(mGlobalMapImage->data(), data.data(), data.size());
// to match openmw size // to match openmw size
// FIXME: filtering? // FIXME: filtering?
@ -135,7 +135,7 @@ namespace ESSImport
data.resize(width*height*4, 0); data.resize(width*height*4, 0);
image2->allocateImage(width, height, 1, GL_RGBA, GL_UNSIGNED_BYTE); image2->allocateImage(width, height, 1, GL_RGBA, GL_UNSIGNED_BYTE);
memcpy(image2->data(), &data[0], data.size()); memcpy(image2->data(), data.data(), data.size());
for (const auto & exploredCell : mContext->mExploredCells) for (const auto & exploredCell : mContext->mExploredCells)
{ {

View file

@ -85,7 +85,7 @@ namespace
namespace ESSImport namespace ESSImport
{ {
Importer::Importer(const std::string &essfile, const std::string &outfile, const std::string &encoding) Importer::Importer(const std::filesystem::path &essfile, const std::filesystem::path &outfile, const std::string &encoding)
: mEssFile(essfile) : mEssFile(essfile)
, mOutFile(outfile) , mOutFile(outfile)
, mEncoding(encoding) , mEncoding(encoding)
@ -112,7 +112,7 @@ namespace ESSImport
std::vector<Record> mRecords; std::vector<Record> mRecords;
}; };
void read(const std::string& filename, File& file) void read(const std::filesystem::path &filename, File& file)
{ {
ESM::ESMReader esm; ESM::ESMReader esm;
esm.open(filename); esm.open(filename);
@ -345,7 +345,7 @@ namespace ESSImport
writer.setFormat (ESM::SavedGame::sCurrentFormat); writer.setFormat (ESM::SavedGame::sCurrentFormat);
std::ofstream stream(std::filesystem::path(mOutFile), std::ios::out | std::ios::binary); std::ofstream stream(mOutFile, std::ios::out | std::ios::binary);
// all unused // all unused
writer.setVersion(0); writer.setVersion(0);
writer.setType(0); writer.setType(0);

View file

@ -1,7 +1,7 @@
#ifndef OPENMW_ESSIMPORTER_IMPORTER_H #ifndef OPENMW_ESSIMPORTER_IMPORTER_H
#define OPENMW_ESSIMPORTER_IMPORTER_H #define OPENMW_ESSIMPORTER_IMPORTER_H
#include <string> #include <filesystem>
namespace ESSImport namespace ESSImport
{ {
@ -9,15 +9,15 @@ namespace ESSImport
class Importer class Importer
{ {
public: public:
Importer(const std::string& essfile, const std::string& outfile, const std::string& encoding); Importer(const std::filesystem::path &essfile, const std::filesystem::path &outfile, const std::string& encoding);
void run(); void run();
void compare(); void compare();
private: private:
std::string mEssFile; std::filesystem::path mEssFile;
std::string mOutFile; std::filesystem::path mOutFile;
std::string mEncoding; std::string mEncoding;
}; };

View file

@ -14,15 +14,15 @@ int main(int argc, char** argv)
{ {
try try
{ {
bpo::options_description desc("Syntax: openmw-essimporter <options> infile.ess outfile.omwsave\nAllowed options"); bpo::options_description desc(R"(Syntax: openmw-essimporter <options> infile.ess outfile.omwsave
Allowed options)");
bpo::positional_options_description p_desc; bpo::positional_options_description p_desc;
desc.add_options() auto addOption = desc.add_options();
("help,h", "produce help message") addOption("help,h", "produce help message");
("mwsave,m", bpo::value<std::string>(), "morrowind .ess save file") addOption("mwsave,m", bpo::value<Files::MaybeQuotedPath>(), "morrowind .ess save file");
("output,o", bpo::value<std::string>(), "output file (.omwsave)") addOption("output,o", bpo::value<Files::MaybeQuotedPath>(), "output file (.omwsave)");
("compare,c", "compare two .ess files") addOption("compare,c", "compare two .ess files");
("encoding", boost::program_options::value<std::string>()->default_value("win1252"), "encoding of the save file") addOption("encoding", boost::program_options::value<std::string>()->default_value("win1252"), "encoding of the save file");
;
p_desc.add("mwsave", 1).add("output", 1); p_desc.add("mwsave", 1).add("output", 1);
Files::ConfigurationManager::addCommonOptions(desc); Files::ConfigurationManager::addCommonOptions(desc);
@ -32,7 +32,6 @@ int main(int argc, char** argv)
.options(desc) .options(desc)
.positional(p_desc) .positional(p_desc)
.run(); .run();
bpo::store(parsed, variables); bpo::store(parsed, variables);
if(variables.count("help") || !variables.count("mwsave") || !variables.count("output")) { if(variables.count("help") || !variables.count("mwsave") || !variables.count("output")) {
@ -45,8 +44,8 @@ int main(int argc, char** argv)
Files::ConfigurationManager cfgManager(true); Files::ConfigurationManager cfgManager(true);
cfgManager.readConfiguration(variables, desc); cfgManager.readConfiguration(variables, desc);
std::string essFile = variables["mwsave"].as<std::string>(); const auto essFile = variables["mwsave"].as<Files::MaybeQuotedPath>();
std::string outputFile = variables["output"].as<std::string>(); const auto outputFile = variables["output"].as<Files::MaybeQuotedPath>();
std::string encoding = variables["encoding"].as<std::string>(); std::string encoding = variables["encoding"].as<std::string>();
ESSImport::Importer importer(essFile, outputFile, encoding); ESSImport::Importer importer(essFile, outputFile, encoding);
@ -55,9 +54,10 @@ int main(int argc, char** argv)
importer.compare(); importer.compare();
else else
{ {
const std::string& ext = ".omwsave"; static constexpr std::u8string_view ext{u8".omwsave"};
if (std::filesystem::exists(std::filesystem::path(outputFile)) const auto length = outputFile.native().size();
&& (outputFile.size() < ext.size() || outputFile.substr(outputFile.size()-ext.size()) != ext)) if (std::filesystem::exists(outputFile)
&& (length < ext.size() || outputFile.u8string().substr(length-ext.size()) != ext))
{ {
throw std::runtime_error("Output file already exists and does not end in .omwsave. Did you mean to use --compare?"); throw std::runtime_error("Output file already exists and does not end in .omwsave. Did you mean to use --compare?");
} }

View file

@ -128,7 +128,7 @@ bool Launcher::AdvancedPage::loadSettings()
antialiasAlphaTestCheckBox->setCheckState(Qt::Unchecked); antialiasAlphaTestCheckBox->setCheckState(Qt::Unchecked);
} }
loadSettingBool(magicItemAnimationsCheckBox, "use magic item animations", "Game"); loadSettingBool(magicItemAnimationsCheckBox, "use magic item animations", "Game");
connect(animSourcesCheckBox, SIGNAL(toggled(bool)), this, SLOT(slotAnimSourcesToggled(bool))); connect(animSourcesCheckBox, &QCheckBox::toggled, this, &AdvancedPage::slotAnimSourcesToggled);
loadSettingBool(animSourcesCheckBox, "use additional anim sources", "Game"); loadSettingBool(animSourcesCheckBox, "use additional anim sources", "Game");
if (animSourcesCheckBox->checkState() != Qt::Unchecked) if (animSourcesCheckBox->checkState() != Qt::Unchecked)
{ {
@ -150,12 +150,12 @@ bool Launcher::AdvancedPage::loadSettings()
loadSettingBool(nightDaySwitchesCheckBox, "day night switches", "Game"); loadSettingBool(nightDaySwitchesCheckBox, "day night switches", "Game");
connect(postprocessEnabledCheckBox, SIGNAL(toggled(bool)), this, SLOT(slotPostProcessToggled(bool))); connect(postprocessEnabledCheckBox, &QCheckBox::toggled, this, &AdvancedPage::slotPostProcessToggled);
loadSettingBool(postprocessEnabledCheckBox, "enabled", "Post Processing"); loadSettingBool(postprocessEnabledCheckBox, "enabled", "Post Processing");
loadSettingBool(postprocessTransparentPostpassCheckBox, "transparent postpass", "Post Processing"); loadSettingBool(postprocessTransparentPostpassCheckBox, "transparent postpass", "Post Processing");
postprocessHDRTimeComboBox->setValue(Settings::Manager::getDouble("auto exposure speed", "Post Processing")); postprocessHDRTimeComboBox->setValue(Settings::Manager::getDouble("auto exposure speed", "Post Processing"));
connect(skyBlendingCheckBox, SIGNAL(toggled(bool)), this, SLOT(slotSkyBlendingToggled(bool))); connect(skyBlendingCheckBox, &QCheckBox::toggled, this, &AdvancedPage::slotSkyBlendingToggled);
loadSettingBool(radialFogCheckBox, "radial fog", "Fog"); loadSettingBool(radialFogCheckBox, "radial fog", "Fog");
loadSettingBool(exponentialFogCheckBox, "exponential fog", "Fog"); loadSettingBool(exponentialFogCheckBox, "exponential fog", "Fog");
loadSettingBool(skyBlendingCheckBox, "sky blending", "Fog"); loadSettingBool(skyBlendingCheckBox, "sky blending", "Fog");
@ -164,7 +164,7 @@ bool Launcher::AdvancedPage::loadSettings()
// Audio // Audio
{ {
std::string selectedAudioDevice = Settings::Manager::getString("device", "Sound"); const std::string& selectedAudioDevice = Settings::Manager::getString("device", "Sound");
if (selectedAudioDevice.empty() == false) if (selectedAudioDevice.empty() == false)
{ {
int audioDeviceIndex = audioDeviceSelectorComboBox->findData(QString::fromStdString(selectedAudioDevice)); int audioDeviceIndex = audioDeviceSelectorComboBox->findData(QString::fromStdString(selectedAudioDevice));
@ -178,7 +178,7 @@ bool Launcher::AdvancedPage::loadSettings()
{ {
enableHRTFComboBox->setCurrentIndex(hrtfEnabledIndex + 1); enableHRTFComboBox->setCurrentIndex(hrtfEnabledIndex + 1);
} }
std::string selectedHRTFProfile = Settings::Manager::getString("hrtf", "Sound"); const std::string& selectedHRTFProfile = Settings::Manager::getString("hrtf", "Sound");
if (selectedHRTFProfile.empty() == false) if (selectedHRTFProfile.empty() == false)
{ {
int hrtfProfileIndex = hrtfProfileSelectorComboBox->findData(QString::fromStdString(selectedHRTFProfile)); int hrtfProfileIndex = hrtfProfileSelectorComboBox->findData(QString::fromStdString(selectedHRTFProfile));
@ -205,7 +205,6 @@ bool Launcher::AdvancedPage::loadSettings()
loadSettingBool(graphicHerbalismCheckBox, "graphic herbalism", "Game"); loadSettingBool(graphicHerbalismCheckBox, "graphic herbalism", "Game");
scalingSpinBox->setValue(Settings::Manager::getFloat("scaling factor", "GUI")); scalingSpinBox->setValue(Settings::Manager::getFloat("scaling factor", "GUI"));
fontSizeSpinBox->setValue(Settings::Manager::getInt("font size", "GUI")); fontSizeSpinBox->setValue(Settings::Manager::getInt("font size", "GUI"));
ttfResolutionSpinBox->setValue(Settings::Manager::getInt("ttf resolution", "GUI"));
} }
// Bug fixes // Bug fixes
@ -320,11 +319,11 @@ void Launcher::AdvancedPage::saveSettings()
saveSettingBool(skyBlendingCheckBox, "sky blending", "Fog"); saveSettingBool(skyBlendingCheckBox, "sky blending", "Fog");
Settings::Manager::setDouble("sky blending start", "Fog", skyBlendingStartComboBox->value()); Settings::Manager::setDouble("sky blending start", "Fog", skyBlendingStartComboBox->value());
} }
// Audio // Audio
{ {
int audioDeviceIndex = audioDeviceSelectorComboBox->currentIndex(); int audioDeviceIndex = audioDeviceSelectorComboBox->currentIndex();
std::string prevAudioDevice = Settings::Manager::getString("device", "Sound"); const std::string& prevAudioDevice = Settings::Manager::getString("device", "Sound");
if (audioDeviceIndex != 0) if (audioDeviceIndex != 0)
{ {
const std::string& newAudioDevice = audioDeviceSelectorComboBox->currentText().toUtf8().constData(); const std::string& newAudioDevice = audioDeviceSelectorComboBox->currentText().toUtf8().constData();
@ -341,7 +340,7 @@ void Launcher::AdvancedPage::saveSettings()
Settings::Manager::setInt("hrtf enable", "Sound", hrtfEnabledIndex); Settings::Manager::setInt("hrtf enable", "Sound", hrtfEnabledIndex);
} }
int selectedHRTFProfileIndex = hrtfProfileSelectorComboBox->currentIndex(); int selectedHRTFProfileIndex = hrtfProfileSelectorComboBox->currentIndex();
std::string prevHRTFProfile = Settings::Manager::getString("hrtf", "Sound"); const std::string& prevHRTFProfile = Settings::Manager::getString("hrtf", "Sound");
if (selectedHRTFProfileIndex != 0) if (selectedHRTFProfileIndex != 0)
{ {
const std::string& newHRTFProfile = hrtfProfileSelectorComboBox->currentText().toUtf8().constData(); const std::string& newHRTFProfile = hrtfProfileSelectorComboBox->currentText().toUtf8().constData();
@ -373,10 +372,6 @@ void Launcher::AdvancedPage::saveSettings()
int fontSize = fontSizeSpinBox->value(); int fontSize = fontSizeSpinBox->value();
if (fontSize != Settings::Manager::getInt("font size", "GUI")) if (fontSize != Settings::Manager::getInt("font size", "GUI"))
Settings::Manager::setInt("font size", "GUI", fontSize); Settings::Manager::setInt("font size", "GUI", fontSize);
int ttfResolution = ttfResolutionSpinBox->value();
if (ttfResolution != Settings::Manager::getInt("ttf resolution", "GUI"))
Settings::Manager::setInt("ttf resolution", "GUI", ttfResolution);
} }
// Bug fixes // Bug fixes

View file

@ -19,13 +19,15 @@
#include <components/config/gamesettings.hpp> #include <components/config/gamesettings.hpp>
#include <components/config/launchersettings.hpp> #include <components/config/launchersettings.hpp>
#include <components/settings/settings.hpp>
#include <components/bsa/compressedbsafile.hpp> #include <components/bsa/compressedbsafile.hpp>
#include <components/files/qtconversion.hpp>
#include <components/misc/strings/conversion.hpp>
#include <components/navmeshtool/protocol.hpp> #include <components/navmeshtool/protocol.hpp>
#include <components/settings/settings.hpp>
#include <components/vfs/bsaarchive.hpp> #include <components/vfs/bsaarchive.hpp>
#include "utils/textinputdialog.hpp"
#include "utils/profilescombobox.hpp" #include "utils/profilescombobox.hpp"
#include "utils/textinputdialog.hpp"
#include "ui_directorypicker.h" #include "ui_directorypicker.h"
@ -132,10 +134,10 @@ Launcher::DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, Config:
mNewProfileDialog = new TextInputDialog(tr("New Content List"), tr("Content List name:"), this); mNewProfileDialog = new TextInputDialog(tr("New Content List"), tr("Content List name:"), this);
mCloneProfileDialog = new TextInputDialog(tr("Clone Content List"), tr("Content List name:"), this); mCloneProfileDialog = new TextInputDialog(tr("Clone Content List"), tr("Content List name:"), this);
connect(mNewProfileDialog->lineEdit(), SIGNAL(textChanged(QString)), connect(mNewProfileDialog->lineEdit(), &LineEdit::textChanged,
this, SLOT(updateNewProfileOkButton(QString))); this, &DataFilesPage::updateNewProfileOkButton);
connect(mCloneProfileDialog->lineEdit(), SIGNAL(textChanged(QString)), connect(mCloneProfileDialog->lineEdit(), &LineEdit::textChanged,
this, SLOT(updateCloneProfileOkButton(QString))); this, &DataFilesPage::updateCloneProfileOkButton);
connect(ui.directoryAddSubdirsButton, &QPushButton::released, this, [this]() { this->addSubdirectories(true); }); connect(ui.directoryAddSubdirsButton, &QPushButton::released, this, [this]() { this->addSubdirectories(true); });
connect(ui.directoryInsertButton, &QPushButton::released, this, [this]() { this->addSubdirectories(false); }); connect(ui.directoryInsertButton, &QPushButton::released, this, [this]() { this->addSubdirectories(false); });
connect(ui.directoryUpButton, &QPushButton::released, this, [this]() { this->moveDirectory(-1); }); connect(ui.directoryUpButton, &QPushButton::released, this, [this]() { this->moveDirectory(-1); });
@ -150,8 +152,8 @@ Launcher::DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, Config:
// Connect signal and slot after the settings have been loaded. We only care about the user changing // Connect signal and slot after the settings have been loaded. We only care about the user changing
// the addons and don't want to get signals of the system doing it during startup. // the addons and don't want to get signals of the system doing it during startup.
connect(mSelector, SIGNAL(signalAddonDataChanged(QModelIndex,QModelIndex)), connect(mSelector, &ContentSelectorView::ContentSelector::signalAddonDataChanged,
this, SLOT(slotAddonDataChanged())); this, &DataFilesPage::slotAddonDataChanged);
// Call manually to indicate all changes to addon data during startup. // Call manually to indicate all changes to addon data during startup.
slotAddonDataChanged(); slotAddonDataChanged();
} }
@ -177,23 +179,24 @@ void Launcher::DataFilesPage::buildView()
refreshButton->setDefaultAction(ui.refreshDataFilesAction); refreshButton->setDefaultAction(ui.refreshDataFilesAction);
//establish connections //establish connections
connect (ui.profilesComboBox, SIGNAL (currentIndexChanged(int)), connect (ui.profilesComboBox, qOverload<int>(&::ProfilesComboBox::currentIndexChanged),
this, SLOT (slotProfileChanged(int))); this, &DataFilesPage::slotProfileChanged);
connect (ui.profilesComboBox, SIGNAL (profileRenamed(QString, QString)), connect (ui.profilesComboBox, &::ProfilesComboBox::profileRenamed,
this, SLOT (slotProfileRenamed(QString, QString))); this, &DataFilesPage::slotProfileRenamed);
connect (ui.profilesComboBox, SIGNAL (signalProfileChanged(QString, QString)), connect (ui.profilesComboBox, qOverload<const QString&,const QString&>(&::ProfilesComboBox::signalProfileChanged),
this, SLOT (slotProfileChangedByUser(QString, QString))); this, &DataFilesPage::slotProfileChangedByUser);
connect(ui.refreshDataFilesAction, SIGNAL(triggered()),this, SLOT(slotRefreshButtonClicked())); connect(ui.refreshDataFilesAction, &QAction::triggered,
this, &DataFilesPage::slotRefreshButtonClicked);
connect(ui.updateNavMeshButton, SIGNAL(clicked()), this, SLOT(startNavMeshTool())); connect(ui.updateNavMeshButton, &QPushButton::clicked, this, &DataFilesPage::startNavMeshTool);
connect(ui.cancelNavMeshButton, SIGNAL(clicked()), this, SLOT(killNavMeshTool())); connect(ui.cancelNavMeshButton, &QPushButton::clicked, this, &DataFilesPage::killNavMeshTool);
connect(mNavMeshToolInvoker->getProcess(), SIGNAL(readyReadStandardOutput()), this, SLOT(readNavMeshToolStdout())); connect(mNavMeshToolInvoker->getProcess(), &QProcess::readyReadStandardOutput, this, &DataFilesPage::readNavMeshToolStdout);
connect(mNavMeshToolInvoker->getProcess(), SIGNAL(readyReadStandardError()), this, SLOT(readNavMeshToolStderr())); connect(mNavMeshToolInvoker->getProcess(), &QProcess::readyReadStandardError, this, &DataFilesPage::readNavMeshToolStderr);
connect(mNavMeshToolInvoker->getProcess(), SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(navMeshToolFinished(int, QProcess::ExitStatus))); connect(mNavMeshToolInvoker->getProcess(), qOverload<int,QProcess::ExitStatus>(&QProcess::finished), this, &DataFilesPage::navMeshToolFinished);
} }
bool Launcher::DataFilesPage::loadSettings() bool Launcher::DataFilesPage::loadSettings()
@ -229,9 +232,9 @@ void Launcher::DataFilesPage::populateFileViews(const QString& contentModelName)
if (!mDataLocal.isEmpty()) if (!mDataLocal.isEmpty())
directories.insert(0, mDataLocal); directories.insert(0, mDataLocal);
const auto globalDataDir = QString(mGameSettings.getGlobalDataDir().c_str()); const auto& globalDataDir = mGameSettings.getGlobalDataDir();
if (!globalDataDir.isEmpty()) if (!globalDataDir.empty())
directories.insert(0, globalDataDir); directories.insert(0, Files::pathToQString(globalDataDir));
// normalize user supplied directories: resolve symlink, convert to native separator, make absolute // normalize user supplied directories: resolve symlink, convert to native separator, make absolute
for (auto& currentDir : directories) for (auto& currentDir : directories)
@ -263,7 +266,8 @@ void Launcher::DataFilesPage::populateFileViews(const QString& contentModelName)
} }
// deactivate data-local and global data directory: they are always included // deactivate data-local and global data directory: they are always included
if (currentDir == mDataLocal || currentDir == globalDataDir) const auto tmp = currentDir.toUtf8();
if (currentDir == mDataLocal || std::filesystem::path(Misc::StringUtils::stringToU8String(tmp)) == globalDataDir)
{ {
auto flags = item->flags(); auto flags = item->flags();
item->setFlags(flags & ~(Qt::ItemIsDragEnabled|Qt::ItemIsDropEnabled|Qt::ItemIsEnabled)); item->setFlags(flags & ~(Qt::ItemIsDragEnabled|Qt::ItemIsDropEnabled|Qt::ItemIsEnabled));

View file

@ -42,11 +42,11 @@ Launcher::GraphicsPage::GraphicsPage(QWidget *parent)
customWidthSpinBox->setMaximum(res.width()); customWidthSpinBox->setMaximum(res.width());
customHeightSpinBox->setMaximum(res.height()); customHeightSpinBox->setMaximum(res.height());
connect(windowModeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotFullScreenChanged(int))); connect(windowModeComboBox, qOverload<int>(&QComboBox::currentIndexChanged), this, &GraphicsPage::slotFullScreenChanged);
connect(standardRadioButton, SIGNAL(toggled(bool)), this, SLOT(slotStandardToggled(bool))); connect(standardRadioButton, &QRadioButton::toggled, this, &GraphicsPage::slotStandardToggled);
connect(screenComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(screenChanged(int))); connect(screenComboBox, qOverload<int>(&QComboBox::currentIndexChanged), this, &GraphicsPage::screenChanged);
connect(framerateLimitCheckBox, SIGNAL(toggled(bool)), this, SLOT(slotFramerateLimitToggled(bool))); connect(framerateLimitCheckBox, &QCheckBox::toggled, this, &GraphicsPage::slotFramerateLimitToggled);
connect(shadowDistanceCheckBox, SIGNAL(toggled(bool)), this, SLOT(slotShadowDistLimitToggled(bool))); connect(shadowDistanceCheckBox, &QCheckBox::toggled, this, &GraphicsPage::slotShadowDistLimitToggled);
} }
bool Launcher::GraphicsPage::setupSDL() bool Launcher::GraphicsPage::setupSDL()

View file

@ -12,12 +12,14 @@
#include <boost/program_options/options_description.hpp> #include <boost/program_options/options_description.hpp>
#include <boost/program_options/variables_map.hpp> #include <boost/program_options/variables_map.hpp>
#include <components/files/conversion.hpp>
#include <components/files/qtconversion.hpp>
#include "playpage.hpp"
#include "graphicspage.hpp"
#include "datafilespage.hpp"
#include "settingspage.hpp"
#include "advancedpage.hpp" #include "advancedpage.hpp"
#include "datafilespage.hpp"
#include "graphicspage.hpp"
#include "playpage.hpp"
#include "settingspage.hpp"
using namespace Process; using namespace Process;
@ -38,11 +40,11 @@ Launcher::MainDialog::MainDialog(QWidget *parent)
mGameInvoker = new ProcessInvoker(); mGameInvoker = new ProcessInvoker();
mWizardInvoker = new ProcessInvoker(); mWizardInvoker = new ProcessInvoker();
connect(mWizardInvoker->getProcess(), SIGNAL(started()), connect(mWizardInvoker->getProcess(), &QProcess::started,
this, SLOT(wizardStarted())); this, &MainDialog::wizardStarted);
connect(mWizardInvoker->getProcess(), SIGNAL(finished(int,QProcess::ExitStatus)), connect(mWizardInvoker->getProcess(), qOverload<int,QProcess::ExitStatus>(&QProcess::finished),
this, SLOT(wizardFinished(int,QProcess::ExitStatus))); this, &MainDialog::wizardFinished);
iconWidget->setViewMode(QListView::IconMode); iconWidget->setViewMode(QListView::IconMode);
iconWidget->setWrapping(false); iconWidget->setWrapping(false);
@ -60,9 +62,9 @@ Launcher::MainDialog::MainDialog(QWidget *parent)
buttonBox->addButton(helpButton, QDialogButtonBox::HelpRole); buttonBox->addButton(helpButton, QDialogButtonBox::HelpRole);
buttonBox->addButton(playButton, QDialogButtonBox::AcceptRole); buttonBox->addButton(playButton, QDialogButtonBox::AcceptRole);
connect(buttonBox, SIGNAL(rejected()), this, SLOT(close())); connect(buttonBox, &QDialogButtonBox::rejected, this, &MainDialog::close);
connect(buttonBox, SIGNAL(accepted()), this, SLOT(play())); connect(buttonBox, &QDialogButtonBox::accepted, this, &MainDialog::play);
connect(buttonBox, SIGNAL(helpRequested()), this, SLOT(help())); connect(buttonBox, &QDialogButtonBox::helpRequested, this, &MainDialog::help);
// Remove what's this? button // Remove what's this? button
setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint); setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint);
@ -111,9 +113,7 @@ void Launcher::MainDialog::createIcons()
advancedButton->setTextAlignment(Qt::AlignHCenter | Qt::AlignBottom); advancedButton->setTextAlignment(Qt::AlignHCenter | Qt::AlignBottom);
advancedButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); advancedButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
connect(iconWidget, connect(iconWidget, &QListWidget::currentItemChanged, this, &MainDialog::changePage);
SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
this, SLOT(changePage(QListWidgetItem*,QListWidgetItem*)));
} }
@ -143,12 +143,12 @@ void Launcher::MainDialog::createPages()
// Select the first page // Select the first page
iconWidget->setCurrentItem(iconWidget->item(0), QItemSelectionModel::Select); iconWidget->setCurrentItem(iconWidget->item(0), QItemSelectionModel::Select);
connect(mPlayPage, SIGNAL(playButtonClicked()), this, SLOT(play())); connect(mPlayPage, &PlayPage::playButtonClicked, this, &MainDialog::play);
connect(mPlayPage, SIGNAL(signalProfileChanged(int)), mDataFilesPage, SLOT(slotProfileChanged(int))); connect(mPlayPage, &PlayPage::signalProfileChanged, mDataFilesPage, &DataFilesPage::slotProfileChanged);
connect(mDataFilesPage, SIGNAL(signalProfileChanged(int)), mPlayPage, SLOT(setProfilesIndex(int))); connect(mDataFilesPage, &DataFilesPage::signalProfileChanged, mPlayPage, &PlayPage::setProfilesIndex);
// Using Qt::QueuedConnection because signal is emitted in a subthread and slot is in the main thread // Using Qt::QueuedConnection because signal is emitted in a subthread and slot is in the main thread
connect(mDataFilesPage, SIGNAL(signalLoadedCellsChanged(QStringList)), mAdvancedPage, SLOT(slotLoadedCellsChanged(QStringList)), Qt::QueuedConnection); connect(mDataFilesPage, &DataFilesPage::signalLoadedCellsChanged, mAdvancedPage, &AdvancedPage::slotLoadedCellsChanged, Qt::QueuedConnection);
} }
Launcher::FirstRunDialogResult Launcher::MainDialog::showFirstRunDialog() Launcher::FirstRunDialogResult Launcher::MainDialog::showFirstRunDialog()
@ -157,14 +157,14 @@ Launcher::FirstRunDialogResult Launcher::MainDialog::showFirstRunDialog()
return FirstRunDialogResultFailure; return FirstRunDialogResultFailure;
// Dialog wizard and setup will fail if the config directory does not already exist // Dialog wizard and setup will fail if the config directory does not already exist
QDir userConfigDir = QDir(QString::fromStdString(mCfgMgr.getUserConfigPath().string())); const auto& userConfigDir = mCfgMgr.getUserConfigPath();
if ( ! userConfigDir.exists() ) { if ( ! exists(userConfigDir) ) {
if ( ! userConfigDir.mkpath(".") ) if ( ! create_directories(userConfigDir) )
{ {
cfgError(tr("Error opening OpenMW configuration file"), cfgError(tr("Error opening OpenMW configuration file"),
tr("<br><b>Could not create directory %0</b><br><br> \ tr("<br><b>Could not create directory %0</b><br><br> \
Please make sure you have the right permissions \ Please make sure you have the right permissions \
and try again.<br>").arg(userConfigDir.canonicalPath()) and try again.<br>").arg(Files::pathToQString(canonical(userConfigDir)))
); );
return FirstRunDialogResultFailure; return FirstRunDialogResultFailure;
} }
@ -297,7 +297,7 @@ bool Launcher::MainDialog::setupLauncherSettings()
mLauncherSettings.setMultiValueEnabled(true); mLauncherSettings.setMultiValueEnabled(true);
QString userPath = QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str()); const auto userPath = Files::pathToQString(mCfgMgr.getUserConfigPath());
QStringList paths; QStringList paths;
paths.append(QString(Config::LauncherSettings::sLauncherConfigFileName)); paths.append(QString(Config::LauncherSettings::sLauncherConfigFileName));
@ -330,9 +330,9 @@ bool Launcher::MainDialog::setupGameSettings()
{ {
mGameSettings.clear(); mGameSettings.clear();
QString localPath = QString::fromUtf8(mCfgMgr.getLocalPath().string().c_str()); const auto localPath = Files::pathToQString(mCfgMgr.getLocalPath());
QString userPath = QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str()); const auto userPath = Files::pathToQString(mCfgMgr.getUserConfigPath());
QString globalPath = QString::fromUtf8(mCfgMgr.getGlobalPath().string().c_str()); const auto globalPath = Files::pathToQString(mCfgMgr.getGlobalPath());
QFile file; QFile file;
@ -481,21 +481,24 @@ bool Launcher::MainDialog::writeSettings()
mSettingsPage->saveSettings(); mSettingsPage->saveSettings();
mAdvancedPage->saveSettings(); mAdvancedPage->saveSettings();
QString userPath = QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str()); const auto& userPath = mCfgMgr.getUserConfigPath();
QDir dir(userPath);
if (!dir.exists()) { if (!exists(userPath)) {
if (!dir.mkpath(userPath)) { if (!create_directories(userPath)) {
cfgError(tr("Error creating OpenMW configuration directory"), cfgError(tr("Error creating OpenMW configuration directory"),
tr("<br><b>Could not create %0</b><br><br> \ tr("<br><b>Could not create %0</b><br><br> \
Please make sure you have the right permissions \ Please make sure you have the right permissions \
and try again.<br>").arg(userPath)); and try again.<br>").arg(Files::pathToQString(userPath)));
return false; return false;
} }
} }
// Game settings // Game settings
QFile file(userPath + QString("openmw.cfg")); #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QFile file(userPath / "openmw.cfg");
#else
QFile file(Files::pathToQString(userPath / "openmw.cfg"));
#endif
if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) { if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) {
// File cannot be opened or created // File cannot be opened or created
@ -511,19 +514,19 @@ bool Launcher::MainDialog::writeSettings()
file.close(); file.close();
// Graphics settings // Graphics settings
const std::string settingsPath = (mCfgMgr.getUserConfigPath() / "settings.cfg").string(); const auto settingsPath = mCfgMgr.getUserConfigPath() / "settings.cfg";
try { try {
Settings::Manager::saveUser(settingsPath); Settings::Manager::saveUser(settingsPath);
} }
catch (std::exception& e) { catch (std::exception& e) {
std::string msg = "<br><b>Error writing settings.cfg</b><br><br>" + std::string msg = "<br><b>Error writing settings.cfg</b><br><br>" +
settingsPath + "<br><br>" + e.what(); Files::pathToUnicodeString(settingsPath) + "<br><br>" + e.what();
cfgError(tr("Error writing user settings file"), tr(msg.c_str())); cfgError(tr("Error writing user settings file"), tr(msg.c_str()));
return false; return false;
} }
// Launcher settings // Launcher settings
file.setFileName(userPath + QString(Config::LauncherSettings::sLauncherConfigFileName)); file.setFileName(Files::pathToQString(userPath / Config::LauncherSettings::sLauncherConfigFileName));
if (!file.open(QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate)) { if (!file.open(QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate)) {
// File cannot be opened or created // File cannot be opened or created

View file

@ -9,8 +9,8 @@ Launcher::PlayPage::PlayPage(QWidget *parent) : QWidget(parent)
profilesComboBox->setView(new QListView()); profilesComboBox->setView(new QListView());
connect(profilesComboBox, SIGNAL(activated(int)), this, SIGNAL (signalProfileChanged(int))); connect(profilesComboBox, qOverload<int>(&QComboBox::activated), this, &PlayPage::signalProfileChanged);
connect(playButton, SIGNAL(clicked()), this, SLOT(slotPlayClicked())); connect(playButton, &QPushButton::clicked, this, &PlayPage::slotPlayClicked);
} }

View file

@ -5,6 +5,9 @@
#include <QDebug> #include <QDebug>
#include <QDir> #include <QDir>
#include <components/files/conversion.hpp>
#include <components/files/qtconversion.hpp>
#include "utils/textinputdialog.hpp" #include "utils/textinputdialog.hpp"
#include "datafilespage.hpp" #include "datafilespage.hpp"
@ -36,22 +39,22 @@ Launcher::SettingsPage::SettingsPage(Files::ConfigurationManager &cfg,
mImporterInvoker = new ProcessInvoker(); mImporterInvoker = new ProcessInvoker();
resetProgressBar(); resetProgressBar();
connect(mWizardInvoker->getProcess(), SIGNAL(started()), connect(mWizardInvoker->getProcess(), &QProcess::started,
this, SLOT(wizardStarted())); this, &SettingsPage::wizardStarted);
connect(mWizardInvoker->getProcess(), SIGNAL(finished(int,QProcess::ExitStatus)), connect(mWizardInvoker->getProcess(), qOverload<int,QProcess::ExitStatus>(&QProcess::finished),
this, SLOT(wizardFinished(int,QProcess::ExitStatus))); this, &SettingsPage::wizardFinished);
connect(mImporterInvoker->getProcess(), SIGNAL(started()), connect(mImporterInvoker->getProcess(), &QProcess::started,
this, SLOT(importerStarted())); this, &SettingsPage::importerStarted);
connect(mImporterInvoker->getProcess(), SIGNAL(finished(int,QProcess::ExitStatus)), connect(mImporterInvoker->getProcess(), qOverload<int,QProcess::ExitStatus>(&QProcess::finished),
this, SLOT(importerFinished(int,QProcess::ExitStatus))); this, &SettingsPage::importerFinished);
mProfileDialog = new TextInputDialog(tr("New Content List"), tr("Content List name:"), this); mProfileDialog = new TextInputDialog(tr("New Content List"), tr("Content List name:"), this);
connect(mProfileDialog->lineEdit(), SIGNAL(textChanged(QString)), connect(mProfileDialog->lineEdit(), &LineEdit::textChanged,
this, SLOT(updateOkButton(QString))); this, &SettingsPage::updateOkButton);
// Detect Morrowind configuration files // Detect Morrowind configuration files
QStringList iniPaths; QStringList iniPaths;
@ -102,9 +105,13 @@ void Launcher::SettingsPage::on_importerButton_clicked()
mMain->writeSettings(); mMain->writeSettings();
// Create the file if it doesn't already exist, else the importer will fail // Create the file if it doesn't already exist, else the importer will fail
QString path(QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str())); auto path = mCfgMgr.getUserConfigPath();
path.append(QLatin1String("openmw.cfg")); path /= "openmw.cfg";
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QFile file(path); QFile file(path);
#else
QFile file(Files::pathToQString(path));
#endif
if (!file.exists()) { if (!file.exists()) {
if (!file.open(QIODevice::ReadWrite)) { if (!file.open(QIODevice::ReadWrite)) {
@ -137,7 +144,7 @@ void Launcher::SettingsPage::on_importerButton_clicked()
arguments.append(QString("--ini")); arguments.append(QString("--ini"));
arguments.append(settingsComboBox->currentText()); arguments.append(settingsComboBox->currentText());
arguments.append(QString("--cfg")); arguments.append(QString("--cfg"));
arguments.append(path); arguments.append(Files::pathToQString(path));
qDebug() << "arguments " << arguments; qDebug() << "arguments " << arguments;

View file

@ -15,8 +15,8 @@ void LineEdit::setupClearButton()
mClearButton->setCursor(Qt::ArrowCursor); mClearButton->setCursor(Qt::ArrowCursor);
mClearButton->setStyleSheet("QToolButton { border: none; padding: 0px; }"); mClearButton->setStyleSheet("QToolButton { border: none; padding: 0px; }");
mClearButton->hide(); mClearButton->hide();
connect(mClearButton, SIGNAL(clicked()), this, SLOT(clear())); connect(mClearButton, &QToolButton::clicked, this, &LineEdit::clear);
connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(updateClearButton(const QString&))); connect(this, &LineEdit::textChanged, this, &LineEdit::updateClearButton);
} }
void LineEdit::resizeEvent(QResizeEvent *) void LineEdit::resizeEvent(QResizeEvent *)

View file

@ -6,8 +6,8 @@
ProfilesComboBox::ProfilesComboBox(QWidget *parent) : ProfilesComboBox::ProfilesComboBox(QWidget *parent) :
ContentSelectorView::ComboBox(parent) ContentSelectorView::ComboBox(parent)
{ {
connect(this, SIGNAL(activated(int)), this, connect(this, qOverload<int>(&ProfilesComboBox::activated),
SLOT(slotIndexChangedByUser(int))); this, &ProfilesComboBox::slotIndexChangedByUser);
setInsertPolicy(QComboBox::NoInsert); setInsertPolicy(QComboBox::NoInsert);
} }
@ -18,8 +18,8 @@ void ProfilesComboBox::setEditEnabled(bool editable)
return; return;
if (!editable) { if (!editable) {
disconnect(lineEdit(), SIGNAL(editingFinished()), this, SLOT(slotEditingFinished())); disconnect(lineEdit(), &QLineEdit::editingFinished, this, &ProfilesComboBox::slotEditingFinished);
disconnect(lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(slotTextChanged(QString))); disconnect(lineEdit(), &QLineEdit::textChanged, this, &ProfilesComboBox::slotTextChanged);
return setEditable(false); return setEditable(false);
} }
@ -32,14 +32,11 @@ void ProfilesComboBox::setEditEnabled(bool editable)
setLineEdit(edit); setLineEdit(edit);
setCompleter(nullptr); setCompleter(nullptr);
connect(lineEdit(), SIGNAL(editingFinished()), this, connect(lineEdit(), &QLineEdit::editingFinished, this, &ProfilesComboBox::slotEditingFinished);
SLOT(slotEditingFinished()));
connect(lineEdit(), SIGNAL(textChanged(QString)), this, connect(lineEdit(), &QLineEdit::textChanged, this, &ProfilesComboBox::slotTextChanged);
SLOT(slotTextChanged(QString)));
connect (lineEdit(), SIGNAL(textChanged(QString)), this, connect(lineEdit(), &QLineEdit::textChanged, this, &ProfilesComboBox::signalProfileTextChanged);
SIGNAL (signalProfileTextChanged (QString)));
} }
void ProfilesComboBox::slotTextChanged(const QString &text) void ProfilesComboBox::slotTextChanged(const QString &text)
@ -74,7 +71,7 @@ void ProfilesComboBox::slotEditingFinished()
return; return;
setItemText(currentIndex(), current); setItemText(currentIndex(), current);
emit(profileRenamed(previous, current)); emit profileRenamed(previous, current);
} }
void ProfilesComboBox::slotIndexChangedByUser(int index) void ProfilesComboBox::slotIndexChangedByUser(int index)
@ -82,7 +79,7 @@ void ProfilesComboBox::slotIndexChangedByUser(int index)
if (index == -1) if (index == -1)
return; return;
emit (signalProfileChanged(mOldProfile, currentText())); emit signalProfileChanged(mOldProfile, currentText());
mOldProfile = currentText(); mOldProfile = currentText();
} }

View file

@ -39,8 +39,8 @@ Launcher::TextInputDialog::TextInputDialog(const QString& title, const QString &
setModal(true); setModal(true);
connect(mButtonBox, SIGNAL(accepted()), this, SLOT(accept())); connect(mButtonBox, &QDialogButtonBox::accepted, this, &TextInputDialog::accept);
connect(mButtonBox, SIGNAL(rejected()), this, SLOT(reject())); connect(mButtonBox, &QDialogButtonBox::rejected, this, &TextInputDialog::reject);
} }
Launcher::TextInputDialog::~TextInputDialog() Launcher::TextInputDialog::~TextInputDialog()

View file

@ -15,7 +15,6 @@ openmw_add_executable(openmw-iniimporter
target_link_libraries(openmw-iniimporter target_link_libraries(openmw-iniimporter
${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY}
${Boost_FILESYSTEM_LIBRARY}
components components
) )

View file

@ -1,16 +1,19 @@
#include "importer.hpp" #include "importer.hpp"
#include <iostream> #include <iostream>
#include <filesystem>
#include <fstream>
#include <components/misc/strings/algorithm.hpp> #include <components/misc/strings/algorithm.hpp>
#include <components/misc/strings/format.hpp> #include <components/misc/strings/format.hpp>
#include <components/misc/strings/lower.hpp> #include <components/misc/strings/lower.hpp>
#include <components/esm3/esmreader.hpp> #include <components/esm3/esmreader.hpp>
#include <components/misc/timeconvert.hpp>
#include <boost/filesystem.hpp> #include <components/files/conversion.hpp>
#include <boost/filesystem/fstream.hpp>
namespace bfs = boost::filesystem;
namespace sfs = std::filesystem;
MwIniImporter::MwIniImporter() MwIniImporter::MwIniImporter()
: mVerbose(false) : mVerbose(false)
@ -654,12 +657,12 @@ void MwIniImporter::setVerbose(bool verbose) {
mVerbose = verbose; mVerbose = verbose;
} }
MwIniImporter::multistrmap MwIniImporter::loadIniFile(const boost::filesystem::path& filename) const { MwIniImporter::multistrmap MwIniImporter::loadIniFile(const std::filesystem::path& filename) const {
std::cout << "load ini file: " << filename << std::endl; std::cout << "load ini file: " << Files::pathToUnicodeString(filename) << std::endl;
std::string section(""); std::string section("");
MwIniImporter::multistrmap map; MwIniImporter::multistrmap map;
bfs::ifstream file((bfs::path(filename))); std::ifstream file(filename);
ToUTF8::Utf8Encoder encoder(mEncoding); ToUTF8::Utf8Encoder encoder(mEncoding);
std::string line; std::string line;
@ -715,11 +718,11 @@ MwIniImporter::multistrmap MwIniImporter::loadIniFile(const boost::filesystem::p
return map; return map;
} }
MwIniImporter::multistrmap MwIniImporter::loadCfgFile(const boost::filesystem::path& filename) { MwIniImporter::multistrmap MwIniImporter::loadCfgFile(const std::filesystem::path& filename) {
std::cout << "load cfg file: " << filename << std::endl; std::cout << "load cfg file: " << Files::pathToUnicodeString(filename) << std::endl;
MwIniImporter::multistrmap map; MwIniImporter::multistrmap map;
bfs::ifstream file((bfs::path(filename))); std::ifstream file(filename);
std::string line; std::string line;
while (std::getline(file, line)) { while (std::getline(file, line)) {
@ -861,7 +864,7 @@ std::vector<std::string>::iterator MwIniImporter::findString(std::vector<std::st
}); });
} }
void MwIniImporter::addPaths(std::vector<boost::filesystem::path>& output, std::vector<std::string> input) { void MwIniImporter::addPaths(std::vector<std::filesystem::path>& output, std::vector<std::string> input) {
for (auto& path : input) for (auto& path : input)
{ {
if (path.front() == '"') if (path.front() == '"')
@ -869,18 +872,18 @@ void MwIniImporter::addPaths(std::vector<boost::filesystem::path>& output, std::
// Drop first and last characters - quotation marks // Drop first and last characters - quotation marks
path = path.substr(1, path.size() - 2); path = path.substr(1, path.size() - 2);
} }
output.emplace_back(path); output.emplace_back(Files::pathFromUnicodeString(path));
} }
} }
void MwIniImporter::importGameFiles(multistrmap &cfg, const multistrmap &ini, const boost::filesystem::path& iniFilename) const void MwIniImporter::importGameFiles(multistrmap &cfg, const multistrmap &ini, const std::filesystem::path& iniFilename) const
{ {
std::vector<std::pair<std::time_t, boost::filesystem::path>> contentFiles; std::vector<std::pair<std::time_t, std::filesystem::path>> contentFiles;
std::string baseGameFile("Game Files:GameFile"); std::string baseGameFile("Game Files:GameFile");
std::time_t defaultTime = 0; std::time_t defaultTime = 0;
ToUTF8::Utf8Encoder encoder(mEncoding); ToUTF8::Utf8Encoder encoder(mEncoding);
std::vector<boost::filesystem::path> dataPaths; std::vector<std::filesystem::path> dataPaths;
if (cfg.count("data")) if (cfg.count("data"))
addPaths(dataPaths, cfg["data"]); addPaths(dataPaths, cfg["data"]);
@ -909,7 +912,7 @@ void MwIniImporter::importGameFiles(multistrmap &cfg, const multistrmap &ini, co
bool found = false; bool found = false;
for (auto & dataPath : dataPaths) for (auto & dataPath : dataPaths)
{ {
boost::filesystem::path path = dataPath / *entry; std::filesystem::path path = dataPath / *entry;
std::time_t time = lastWriteTime(path, defaultTime); std::time_t time = lastWriteTime(path, defaultTime);
if (time != defaultTime) if (time != defaultTime)
{ {
@ -936,13 +939,13 @@ void MwIniImporter::importGameFiles(multistrmap &cfg, const multistrmap &ini, co
reader.setEncoder(&encoder); reader.setEncoder(&encoder);
for (auto& file : contentFiles) for (auto& file : contentFiles)
{ {
reader.open(file.second.string()); reader.open(file.second);
std::vector<std::string> dependencies; std::vector<std::string> dependencies;
for (auto& gameFile : reader.getGameFiles()) for (auto& gameFile : reader.getGameFiles())
{ {
dependencies.push_back(gameFile.name); dependencies.push_back(gameFile.name);
} }
unsortedFiles.emplace_back(boost::filesystem::path(reader.getName()).filename().string(), dependencies); unsortedFiles.emplace_back(Files::pathToUnicodeString(reader.getName().filename()), dependencies);
reader.close(); reader.close();
} }
@ -983,13 +986,13 @@ void MwIniImporter::setInputEncoding(const ToUTF8::FromType &encoding)
mEncoding = encoding; mEncoding = encoding;
} }
std::time_t MwIniImporter::lastWriteTime(const boost::filesystem::path& filename, std::time_t defaultTime) std::time_t MwIniImporter::lastWriteTime(const std::filesystem::path& filename, std::time_t defaultTime)
{ {
std::time_t writeTime(defaultTime); std::time_t writeTime(defaultTime);
if (boost::filesystem::exists(filename)) if (std::filesystem::exists(filename))
{ {
boost::filesystem::path resolved = boost::filesystem::canonical(filename); std::filesystem::path resolved = std::filesystem::canonical(filename);
writeTime = boost::filesystem::last_write_time(resolved); writeTime = Misc::to_time_t(std::filesystem::last_write_time (resolved));
// print timestamp // print timestamp
const int size=1024; const int size=1024;

View file

@ -6,7 +6,7 @@
#include <vector> #include <vector>
#include <exception> #include <exception>
#include <iosfwd> #include <iosfwd>
#include <boost/filesystem/path.hpp> #include <filesystem>
#include <components/to_utf8/to_utf8.hpp> #include <components/to_utf8/to_utf8.hpp>
@ -19,12 +19,12 @@ class MwIniImporter {
MwIniImporter(); MwIniImporter();
void setInputEncoding(const ToUTF8::FromType& encoding); void setInputEncoding(const ToUTF8::FromType& encoding);
void setVerbose(bool verbose); void setVerbose(bool verbose);
multistrmap loadIniFile(const boost::filesystem::path& filename) const; multistrmap loadIniFile(const std::filesystem::path& filename) const;
static multistrmap loadCfgFile(const boost::filesystem::path& filename); static multistrmap loadCfgFile(const std::filesystem::path& filename);
void merge(multistrmap &cfg, const multistrmap &ini) const; void merge(multistrmap &cfg, const multistrmap &ini) const;
void mergeFallback(multistrmap &cfg, const multistrmap &ini) const; void mergeFallback(multistrmap &cfg, const multistrmap &ini) const;
void importGameFiles(multistrmap &cfg, const multistrmap &ini, void importGameFiles(multistrmap &cfg, const multistrmap &ini,
const boost::filesystem::path& iniFilename) const; const std::filesystem::path& iniFilename) const;
void importArchives(multistrmap &cfg, const multistrmap &ini) const; void importArchives(multistrmap &cfg, const multistrmap &ini) const;
static void writeToFile(std::ostream &out, const multistrmap &cfg); static void writeToFile(std::ostream &out, const multistrmap &cfg);
@ -35,10 +35,10 @@ class MwIniImporter {
static std::vector<std::string>::iterator findString(std::vector<std::string>& source, const std::string& string); static std::vector<std::string>::iterator findString(std::vector<std::string>& source, const std::string& string);
static void insertMultistrmap(multistrmap &cfg, const std::string& key, const std::string& value); static void insertMultistrmap(multistrmap &cfg, const std::string& key, const std::string& value);
static void addPaths(std::vector<boost::filesystem::path>& output, std::vector<std::string> input); static void addPaths(std::vector<std::filesystem::path>& output, std::vector<std::string> input);
/// \return file's "last modified time", used in original MW to determine plug-in load order /// \return file's "last modified time", used in original MW to determine plug-in load order
static std::time_t lastWriteTime(const boost::filesystem::path& filename, std::time_t defaultTime); static std::time_t lastWriteTime(const std::filesystem::path& filename, std::time_t defaultTime);
bool mVerbose; bool mVerbose;
strmap mMergeMap; strmap mMergeMap;

View file

@ -1,13 +1,16 @@
#include "importer.hpp" #include "importer.hpp"
#include <iostream> #include <iostream>
#include <filesystem>
#include <fstream>
#include <boost/program_options.hpp> #include <boost/program_options.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp> #include <components/files/configurationmanager.hpp>
#include <components/files/conversion.hpp>
namespace bpo = boost::program_options; namespace bpo = boost::program_options;
namespace bfs = boost::filesystem; namespace sfs = std::filesystem;
#ifndef _WIN32 #ifndef _WIN32
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
@ -52,27 +55,26 @@ private:
int wmain(int argc, wchar_t *wargv[]) { int wmain(int argc, wchar_t *wargv[]) {
utf8argv converter(argc, wargv); utf8argv converter(argc, wargv);
char **argv = converter.get(); char **argv = converter.get();
boost::filesystem::path::imbue(boost::locale::generator().generate(""));
#endif #endif
try try
{ {
bpo::options_description desc("Syntax: openmw-iniimporter <options> inifile configfile\nAllowed options"); bpo::options_description desc("Syntax: openmw-iniimporter <options> inifile configfile\nAllowed options");
bpo::positional_options_description p_desc; bpo::positional_options_description p_desc;
desc.add_options() auto addOption = desc.add_options();
("help,h", "produce help message") addOption("help,h", "produce help message");
("verbose,v", "verbose output") addOption("verbose,v", "verbose output");
("ini,i", bpo::value<std::string>(), "morrowind.ini file") addOption("ini,i", bpo::value<Files::MaybeQuotedPath>(), "morrowind.ini file");
("cfg,c", bpo::value<std::string>(), "openmw.cfg file") addOption("cfg,c", bpo::value<Files::MaybeQuotedPath>(), "openmw.cfg file");
("output,o", bpo::value<std::string>()->default_value(""), "openmw.cfg file") addOption("output,o", bpo::value<Files::MaybeQuotedPath>()->default_value({}), "openmw.cfg file");
("game-files,g", "import esm and esp files") addOption("game-files,g", "import esm and esp files");
("fonts,f", "import bitmap fonts") addOption("fonts,f", "import bitmap fonts");
("no-archives,A", "disable bsa archives import") addOption("no-archives,A", "disable bsa archives import");
("encoding,e", bpo::value<std::string>()-> default_value("win1252"), addOption("encoding,e", bpo::value<std::string>()-> default_value("win1252"),
"Character encoding used in OpenMW game messages:\n" "Character encoding used in OpenMW game messages:\n"
"\n\twin1250 - Central and Eastern European such as Polish, Czech, Slovak, Hungarian, Slovene, Bosnian, Croatian, Serbian (Latin script), Romanian and Albanian languages\n" "\n\twin1250 - Central and Eastern European such as Polish, Czech, Slovak, Hungarian, Slovene, Bosnian, Croatian, Serbian (Latin script), Romanian and Albanian languages\n"
"\n\twin1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages\n" "\n\twin1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages\n"
"\n\twin1252 - Western European (Latin) alphabet, used by default") "\n\twin1252 - Western European (Latin) alphabet, used by default");
; ;
p_desc.add("ini", 1).add("cfg", 1); p_desc.add("ini", 1).add("cfg", 1);
@ -82,7 +84,6 @@ int wmain(int argc, wchar_t *wargv[]) {
.options(desc) .options(desc)
.positional(p_desc) .positional(p_desc)
.run(); .run();
bpo::store(parsed, vm); bpo::store(parsed, vm);
if(vm.count("help") || !vm.count("ini") || !vm.count("cfg")) { if(vm.count("help") || !vm.count("ini") || !vm.count("cfg")) {
@ -92,20 +93,20 @@ int wmain(int argc, wchar_t *wargv[]) {
bpo::notify(vm); bpo::notify(vm);
boost::filesystem::path iniFile(vm["ini"].as<std::string>()); std::filesystem::path iniFile(vm["ini"].as<Files::MaybeQuotedPath>().u8string()); // This call to u8string is redundant, but required to build on MSVC 14.26 due to implementation bugs.
boost::filesystem::path cfgFile(vm["cfg"].as<std::string>()); std::filesystem::path cfgFile(vm["cfg"].as<Files::MaybeQuotedPath>().u8string()); // This call to u8string is redundant, but required to build on MSVC 14.26 due to implementation bugs.
// if no output is given, write back to cfg file // if no output is given, write back to cfg file
std::string outputFile(vm["output"].as<std::string>()); std::filesystem::path outputFile = vm["output"].as<Files::MaybeQuotedPath>().u8string(); // This call to u8string is redundant, but required to build on MSVC 14.26 due to implementation bugs.
if(vm["output"].defaulted()) { if(vm["output"].defaulted()) {
outputFile = vm["cfg"].as<std::string>(); outputFile = vm["cfg"].as<Files::MaybeQuotedPath>().u8string(); // This call to u8string is redundant, but required to build on MSVC 14.26 due to implementation bugs.
} }
if(!boost::filesystem::exists(iniFile)) { if(!std::filesystem::exists(iniFile)) {
std::cerr << "ini file does not exist" << std::endl; std::cerr << "ini file does not exist" << std::endl;
return -3; return -3;
} }
if(!boost::filesystem::exists(cfgFile)) if(!std::filesystem::exists(cfgFile))
std::cerr << "cfg file does not exist" << std::endl; std::cerr << "cfg file does not exist" << std::endl;
MwIniImporter importer; MwIniImporter importer;
@ -136,8 +137,8 @@ int wmain(int argc, wchar_t *wargv[]) {
importer.importArchives(cfg, ini); importer.importArchives(cfg, ini);
} }
std::cout << "write to: " << outputFile << std::endl; std::cout << "write to: " << Files::pathToUnicodeString(outputFile) << std::endl;
bfs::ofstream file((bfs::path(outputFile))); std::ofstream file(outputFile);
importer.writeToFile(file, cfg); importer.writeToFile(file, cfg);
} }
catch (std::exception& e) catch (std::exception& e)

View file

@ -24,6 +24,7 @@
#include <components/esm3/readerscache.hpp> #include <components/esm3/readerscache.hpp>
#include <components/platform/platform.hpp> #include <components/platform/platform.hpp>
#include <components/detournavigator/agentbounds.hpp> #include <components/detournavigator/agentbounds.hpp>
#include <components/files/conversion.hpp>
#include <osg/Vec3f> #include <osg/Vec3f>
@ -53,52 +54,51 @@ namespace NavMeshTool
using Fallback::FallbackMap; using Fallback::FallbackMap;
bpo::options_description result; bpo::options_description result;
auto addOption = result.add_options();
addOption("help", "print help message");
result.add_options() addOption("version", "print version information and quit");
("help", "print help message")
("version", "print version information and quit") addOption("data", bpo::value<Files::MaybeQuotedPathContainer>()->default_value(Files::MaybeQuotedPathContainer(), "data")
->multitoken()->composing(), "set data directories (later directories have higher priority)");
("data", bpo::value<Files::MaybeQuotedPathContainer>()->default_value(Files::MaybeQuotedPathContainer(), "data") addOption("data-local", bpo::value<Files::MaybeQuotedPathContainer::value_type>()->default_value(Files::MaybeQuotedPathContainer::value_type(), ""),
->multitoken()->composing(), "set data directories (later directories have higher priority)") "set local data directory (highest priority)");
("data-local", bpo::value<Files::MaybeQuotedPathContainer::value_type>()->default_value(Files::MaybeQuotedPathContainer::value_type(), ""), addOption("fallback-archive", bpo::value<StringsVector>()->default_value(StringsVector(), "fallback-archive")
"set local data directory (highest priority)") ->multitoken()->composing(), "set fallback BSA archives (later archives have higher priority)");
("fallback-archive", bpo::value<StringsVector>()->default_value(StringsVector(), "fallback-archive") addOption("resources", bpo::value<Files::MaybeQuotedPath>()->default_value(Files::MaybeQuotedPath(), "resources"),
->multitoken()->composing(), "set fallback BSA archives (later archives have higher priority)") "set resources directory");
("resources", bpo::value<Files::MaybeQuotedPath>()->default_value(Files::MaybeQuotedPath(), "resources"), addOption("content", bpo::value<StringsVector>()->default_value(StringsVector(), "")
"set resources directory") ->multitoken()->composing(), "content file(s): esm/esp, or omwgame/omwaddon/omwscripts");
("content", bpo::value<StringsVector>()->default_value(StringsVector(), "") addOption("fs-strict", bpo::value<bool>()->implicit_value(true)
->multitoken()->composing(), "content file(s): esm/esp, or omwgame/omwaddon/omwscripts") ->default_value(false), "strict file system handling (no case folding)");
("fs-strict", bpo::value<bool>()->implicit_value(true) addOption("encoding", bpo::value<std::string>()->
->default_value(false), "strict file system handling (no case folding)")
("encoding", bpo::value<std::string>()->
default_value("win1252"), default_value("win1252"),
"Character encoding used in OpenMW game messages:\n" "Character encoding used in OpenMW game messages:\n"
"\n\twin1250 - Central and Eastern European such as Polish, Czech, Slovak, Hungarian, Slovene, Bosnian, Croatian, Serbian (Latin script), Romanian and Albanian languages\n" "\n\twin1250 - Central and Eastern European such as Polish, Czech, Slovak, Hungarian, Slovene, Bosnian, Croatian, Serbian (Latin script), Romanian and Albanian languages\n"
"\n\twin1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages\n" "\n\twin1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages\n"
"\n\twin1252 - Western European (Latin) alphabet, used by default") "\n\twin1252 - Western European (Latin) alphabet, used by default");
("fallback", bpo::value<Fallback::FallbackMap>()->default_value(Fallback::FallbackMap(), "") addOption("fallback", bpo::value<Fallback::FallbackMap>()->default_value(Fallback::FallbackMap(), "")
->multitoken()->composing(), "fallback values") ->multitoken()->composing(), "fallback values");
("threads", bpo::value<std::size_t>()->default_value(std::max<std::size_t>(std::thread::hardware_concurrency() - 1, 1)), addOption("threads", bpo::value<std::size_t>()->default_value(std::max<std::size_t>(std::thread::hardware_concurrency() - 1, 1)),
"number of threads for parallel processing") "number of threads for parallel processing");
("process-interior-cells", bpo::value<bool>()->implicit_value(true) addOption("process-interior-cells", bpo::value<bool>()->implicit_value(true)
->default_value(false), "build navmesh for interior cells") ->default_value(false), "build navmesh for interior cells");
("remove-unused-tiles", bpo::value<bool>()->implicit_value(true) addOption("remove-unused-tiles", bpo::value<bool>()->implicit_value(true)
->default_value(false), "remove tiles from cache that will not be used with current content profile") ->default_value(false), "remove tiles from cache that will not be used with current content profile");
addOption("write-binary-log", bpo::value<bool>()->implicit_value(true)
->default_value(false), "write progress in binary messages to be consumed by the launcher");
("write-binary-log", bpo::value<bool>()->implicit_value(true)
->default_value(false), "write progress in binary messages to be consumed by the launcher")
;
Files::ConfigurationManager::addCommonOptions(result); Files::ConfigurationManager::addCommonOptions(result);
return result; return result;
@ -143,7 +143,7 @@ namespace NavMeshTool
const auto fsStrict = variables["fs-strict"].as<bool>(); const auto fsStrict = variables["fs-strict"].as<bool>();
const auto resDir = variables["resources"].as<Files::MaybeQuotedPath>(); const auto resDir = variables["resources"].as<Files::MaybeQuotedPath>();
Version::Version v = Version::getOpenmwVersion(resDir.string()); Version::Version v = Version::getOpenmwVersion(resDir);
Log(Debug::Info) << v.describe(); Log(Debug::Info) << v.describe();
dataDirs.insert(dataDirs.begin(), resDir / "vfs"); dataDirs.insert(dataDirs.begin(), resDir / "vfs");
const auto fileCollections = Files::Collections(dataDirs, !fsStrict); const auto fileCollections = Files::Collections(dataDirs, !fsStrict);
@ -179,7 +179,7 @@ namespace NavMeshTool
const osg::Vec3f agentHalfExtents = Settings::Manager::getVector3("default actor pathfind half extents", "Game"); const osg::Vec3f agentHalfExtents = Settings::Manager::getVector3("default actor pathfind half extents", "Game");
const DetourNavigator::AgentBounds agentBounds {agentCollisionShape, agentHalfExtents}; const DetourNavigator::AgentBounds agentBounds {agentCollisionShape, agentHalfExtents};
const std::uint64_t maxDbFileSize = static_cast<std::uint64_t>(Settings::Manager::getInt64("max navmeshdb file size", "Navigator")); const std::uint64_t maxDbFileSize = static_cast<std::uint64_t>(Settings::Manager::getInt64("max navmeshdb file size", "Navigator"));
const std::string dbPath = (config.getUserDataPath() / "navmesh.db").string(); const auto dbPath = Files::pathToUnicodeString(config.getUserDataPath() / "navmesh.db");
DetourNavigator::NavMeshDb db(dbPath, maxDbFileSize); DetourNavigator::NavMeshDb db(dbPath, maxDbFileSize);

View file

@ -276,11 +276,13 @@ namespace NavMeshTool
{ {
it = navMeshInputs.emplace(cell.mCellId.mWorldspace, it = navMeshInputs.emplace(cell.mCellId.mWorldspace,
std::make_unique<WorldspaceNavMeshInput>(cell.mCellId.mWorldspace, settings.mRecast)).first; std::make_unique<WorldspaceNavMeshInput>(cell.mCellId.mWorldspace, settings.mRecast)).first;
it->second->mTileCachedRecastMeshManager.setWorldspace(cell.mCellId.mWorldspace); it->second->mTileCachedRecastMeshManager.setWorldspace(cell.mCellId.mWorldspace, nullptr);
} }
return *it->second; return *it->second;
} (); } ();
const TileCachedRecastMeshManager::UpdateGuard guard(navMeshInput.mTileCachedRecastMeshManager);
if (exterior) if (exterior)
{ {
const auto it = std::lower_bound(esmData.mLands.begin(), esmData.mLands.end(), cellPosition, LessByXY {}); const auto it = std::lower_bound(esmData.mLands.begin(), esmData.mLands.end(), cellPosition, LessByXY {});
@ -292,19 +294,22 @@ namespace NavMeshTool
mergeOrAssign(getAabb(cellPosition, minHeight, maxHeight), mergeOrAssign(getAabb(cellPosition, minHeight, maxHeight),
navMeshInput.mAabb, navMeshInput.mAabbInitialized); navMeshInput.mAabb, navMeshInput.mAabbInitialized);
navMeshInput.mTileCachedRecastMeshManager.addHeightfield(cellPosition, ESM::Land::REAL_SIZE, heightfieldShape); navMeshInput.mTileCachedRecastMeshManager.addHeightfield(cellPosition, ESM::Land::REAL_SIZE, heightfieldShape, &guard);
navMeshInput.mTileCachedRecastMeshManager.addWater(cellPosition, ESM::Land::REAL_SIZE, -1); navMeshInput.mTileCachedRecastMeshManager.addWater(cellPosition, ESM::Land::REAL_SIZE, -1, &guard);
} }
else else
{ {
if ((cell.mData.mFlags & ESM::Cell::HasWater) != 0) if ((cell.mData.mFlags & ESM::Cell::HasWater) != 0)
navMeshInput.mTileCachedRecastMeshManager.addWater(cellPosition, std::numeric_limits<int>::max(), cell.mWater); navMeshInput.mTileCachedRecastMeshManager.addWater(cellPosition, std::numeric_limits<int>::max(), cell.mWater, &guard);
} }
forEachObject(cell, esmData, vfs, bulletShapeManager, readers, forEachObject(cell, esmData, vfs, bulletShapeManager, readers,
[&] (BulletObject object) [&] (BulletObject object)
{ {
if (object.getShapeInstance()->mVisualCollisionType != Resource::VisualCollisionType::None)
return;
const btTransform& transform = object.getCollisionObject().getWorldTransform(); const btTransform& transform = object.getCollisionObject().getWorldTransform();
const btAABB aabb = BulletHelpers::getAabb(*object.getCollisionObject().getCollisionShape(), transform); const btAABB aabb = BulletHelpers::getAabb(*object.getCollisionObject().getCollisionShape(), transform);
mergeOrAssign(aabb, navMeshInput.mAabb, navMeshInput.mAabbInitialized); mergeOrAssign(aabb, navMeshInput.mAabb, navMeshInput.mAabbInitialized);
@ -315,13 +320,13 @@ namespace NavMeshTool
const CollisionShape shape(object.getShapeInstance(), *object.getCollisionObject().getCollisionShape(), object.getObjectTransform()); const CollisionShape shape(object.getShapeInstance(), *object.getCollisionObject().getCollisionShape(), object.getObjectTransform());
navMeshInput.mTileCachedRecastMeshManager.addObject(objectId, shape, transform, navMeshInput.mTileCachedRecastMeshManager.addObject(objectId, shape, transform,
DetourNavigator::AreaType_ground, [] (const auto&) {}); DetourNavigator::AreaType_ground, &guard);
if (const btCollisionShape* avoid = object.getShapeInstance()->mAvoidCollisionShape.get()) if (const btCollisionShape* avoid = object.getShapeInstance()->mAvoidCollisionShape.get())
{ {
const CollisionShape avoidShape(object.getShapeInstance(), *avoid, object.getObjectTransform()); const CollisionShape avoidShape(object.getShapeInstance(), *avoid, object.getObjectTransform());
navMeshInput.mTileCachedRecastMeshManager.addObject(objectId, avoidShape, transform, navMeshInput.mTileCachedRecastMeshManager.addObject(objectId, avoidShape, transform,
DetourNavigator::AreaType_null, [] (const auto&) {}); DetourNavigator::AreaType_null, &guard);
} }
data.mObjects.emplace_back(std::move(object)); data.mObjects.emplace_back(std::move(object));

View file

@ -8,6 +8,7 @@
#include <components/resource/bulletshape.hpp> #include <components/resource/bulletshape.hpp>
#include <BulletCollision/CollisionDispatch/btCollisionObject.h> #include <BulletCollision/CollisionDispatch/btCollisionObject.h>
#include <BulletCollision/Gimpact/btBoxCollision.h>
#include <LinearMath/btVector3.h> #include <LinearMath/btVector3.h>
#include <memory> #include <memory>

View file

@ -9,6 +9,8 @@
#include <components/vfs/manager.hpp> #include <components/vfs/manager.hpp>
#include <components/vfs/bsaarchive.hpp> #include <components/vfs/bsaarchive.hpp>
#include <components/vfs/filesystemarchive.hpp> #include <components/vfs/filesystemarchive.hpp>
#include <components/files/configurationmanager.hpp>
#include <components/files/conversion.hpp>
#include <boost/program_options.hpp> #include <boost/program_options.hpp>
@ -16,26 +18,26 @@
namespace bpo = boost::program_options; namespace bpo = boost::program_options;
///See if the file has the named extension ///See if the file has the named extension
bool hasExtension(std::string filename, std::string extensionToFind) bool hasExtension(const std::filesystem::path& filename, const std::string& extensionToFind)
{ {
std::string extension = filename.substr(filename.find_last_of('.')+1); const auto extension = Files::pathToUnicodeString(filename.extension());
return Misc::StringUtils::ciEqual(extension, extensionToFind); return Misc::StringUtils::ciEqual(extension, extensionToFind);
} }
///See if the file has the "nif" extension. ///See if the file has the "nif" extension.
bool isNIF(const std::string & filename) bool isNIF(const std::filesystem::path &filename)
{ {
return hasExtension(filename,"nif"); return hasExtension(filename,"nif");
} }
///See if the file has the "bsa" extension. ///See if the file has the "bsa" extension.
bool isBSA(const std::string & filename) bool isBSA(const std::filesystem::path &filename)
{ {
return hasExtension(filename,"bsa"); return hasExtension(filename,"bsa");
} }
/// Check all the nif files in a given VFS::Archive /// Check all the nif files in a given VFS::Archive
/// \note Can not read a bsa file inside of a bsa file. /// \note Can not read a bsa file inside of a bsa file.
void readVFS(std::unique_ptr<VFS::Archive>&& anArchive, std::string archivePath = "") void readVFS(std::unique_ptr<VFS::Archive>&& anArchive, const std::filesystem::path& archivePath = {})
{ {
VFS::Manager myManager(true); VFS::Manager myManager(true);
myManager.addArchive(std::move(anArchive)); myManager.addArchive(std::move(anArchive));
@ -47,14 +49,14 @@ void readVFS(std::unique_ptr<VFS::Archive>&& anArchive, std::string archivePath
if(isNIF(name)) if(isNIF(name))
{ {
// std::cout << "Decoding: " << name << std::endl; // std::cout << "Decoding: " << name << std::endl;
Nif::NIFFile temp_nif(myManager.get(name),archivePath+name); Nif::NIFFile temp_nif(myManager.get(name),archivePath / name);
} }
else if(isBSA(name)) else if(isBSA(name))
{ {
if(!archivePath.empty() && !isBSA(archivePath)) if(!archivePath.empty() && !isBSA(archivePath))
{ {
// std::cout << "Reading BSA File: " << name << std::endl; // std::cout << "Reading BSA File: " << name << std::endl;
readVFS(std::make_unique<VFS::BsaArchive>(archivePath + name), archivePath + name + "/"); readVFS(std::make_unique<VFS::BsaArchive>(archivePath / name), archivePath / name);
// std::cout << "Done with BSA File: " << name << std::endl; // std::cout << "Done with BSA File: " << name << std::endl;
} }
} }
@ -66,17 +68,18 @@ void readVFS(std::unique_ptr<VFS::Archive>&& anArchive, std::string archivePath
} }
} }
bool parseOptions (int argc, char** argv, std::vector<std::string>& files) bool parseOptions (int argc, char** argv, std::vector<Files::MaybeQuotedPath> &files)
{ {
bpo::options_description desc("Ensure that OpenMW can use the provided NIF and BSA files\n\n" bpo::options_description desc(R"(Ensure that OpenMW can use the provided NIF and BSA files
"Usages:\n"
" niftool <nif files, BSA files, or directories>\n" Usages:
" Scan the file or directories for nif errors.\n\n" niftool <nif files, BSA files, or directories>
"Allowed options"); Scan the file or directories for nif errors.
desc.add_options()
("help,h", "print help message.") Allowed options)");
("input-file", bpo::value< std::vector<std::string> >(), "input file") auto addOption = desc.add_options();
; addOption("help,h", "print help message.");
addOption("input-file", bpo::value< Files::MaybeQuotedPathContainer >(), "input file");
//Default option if none provided //Default option if none provided
bpo::positional_options_description p; bpo::positional_options_description p;
@ -96,7 +99,7 @@ bool parseOptions (int argc, char** argv, std::vector<std::string>& files)
} }
if (variables.count("input-file")) if (variables.count("input-file"))
{ {
files = variables["input-file"].as< std::vector<std::string> >(); files = variables["input-file"].as< Files::MaybeQuotedPathContainer >();
return true; return true;
} }
} }
@ -114,36 +117,34 @@ bool parseOptions (int argc, char** argv, std::vector<std::string>& files)
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
std::vector<std::string> files; std::vector<Files::MaybeQuotedPath> files;
if(!parseOptions (argc, argv, files)) if(!parseOptions (argc, argv, files))
return 1; return 1;
Nif::NIFFile::setLoadUnsupportedFiles(true); Nif::NIFFile::setLoadUnsupportedFiles(true);
// std::cout << "Reading Files" << std::endl; // std::cout << "Reading Files" << std::endl;
for(auto it=files.begin(); it!=files.end(); ++it) for(const auto& path : files)
{ {
std::string name = *it;
try try
{ {
if(isNIF(name)) if(isNIF(path))
{ {
//std::cout << "Decoding: " << name << std::endl; //std::cout << "Decoding: " << name << std::endl;
Nif::NIFFile temp_nif(Files::openConstrainedFileStream(name), name); Nif::NIFFile temp_nif(Files::openConstrainedFileStream(path), path);
} }
else if(isBSA(name)) else if(isBSA(path))
{ {
// std::cout << "Reading BSA File: " << name << std::endl; // std::cout << "Reading BSA File: " << name << std::endl;
readVFS(std::make_unique<VFS::BsaArchive>(name)); readVFS(std::make_unique<VFS::BsaArchive>(path));
} }
else if(std::filesystem::is_directory(std::filesystem::path(name))) else if(std::filesystem::is_directory(path))
{ {
// std::cout << "Reading All Files in: " << name << std::endl; // std::cout << "Reading All Files in: " << name << std::endl;
readVFS(std::make_unique<VFS::FileSystemArchive>(name), name); readVFS(std::make_unique<VFS::FileSystemArchive>(path), path);
} }
else else
{ {
std::cerr << "ERROR: \"" << name << "\" is not a nif file, bsa file, or directory!" << std::endl; std::cerr << "ERROR: \"" << Files::pathToUnicodeString(path) << "\" is not a nif file, bsa file, or directory!" << std::endl;
} }
} }
catch (std::exception& e) catch (std::exception& e)

View file

@ -224,8 +224,6 @@ target_link_libraries(openmw-cs
${OSGTEXT_LIBRARIES} ${OSGTEXT_LIBRARIES}
${OSG_LIBRARIES} ${OSG_LIBRARIES}
${EXTERN_OSGQT_LIBRARY} ${EXTERN_OSGQT_LIBRARY}
${Boost_SYSTEM_LIBRARY}
${Boost_FILESYSTEM_LIBRARY}
${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY}
components_qt components_qt
) )

View file

@ -10,7 +10,10 @@
#include <components/debug/debugging.hpp> #include <components/debug/debugging.hpp>
#include <components/debug/debuglog.hpp> #include <components/debug/debuglog.hpp>
#include <components/fallback/validate.hpp> #include <components/fallback/validate.hpp>
#include <components/files/conversion.hpp>
#include <components/files/qtconversion.hpp>
#include <components/misc/rng.hpp> #include <components/misc/rng.hpp>
#include <components/misc/strings/conversion.hpp>
#include <components/nifosg/nifloader.hpp> #include <components/nifosg/nifloader.hpp>
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>
@ -44,34 +47,31 @@ CS::Editor::Editor (int argc, char **argv)
mFileDialog.setLocalData (mLocal); mFileDialog.setLocalData (mLocal);
mMerge.setLocalData (mLocal); mMerge.setLocalData (mLocal);
connect (&mDocumentManager, SIGNAL (documentAdded (CSMDoc::Document *)), connect (&mDocumentManager, &CSMDoc::DocumentManager::documentAdded,
this, SLOT (documentAdded (CSMDoc::Document *))); this, &Editor::documentAdded);
connect (&mDocumentManager, SIGNAL (documentAboutToBeRemoved (CSMDoc::Document *)), connect (&mDocumentManager, &CSMDoc::DocumentManager::documentAboutToBeRemoved,
this, SLOT (documentAboutToBeRemoved (CSMDoc::Document *))); this, &Editor::documentAboutToBeRemoved);
connect (&mDocumentManager, SIGNAL (lastDocumentDeleted()), connect (&mDocumentManager, &CSMDoc::DocumentManager::lastDocumentDeleted,
this, SLOT (lastDocumentDeleted())); this, &Editor::lastDocumentDeleted);
connect (mViewManager, SIGNAL (newGameRequest ()), this, SLOT (createGame ())); connect (mViewManager, &CSVDoc::ViewManager::newGameRequest, this, &Editor::createGame);
connect (mViewManager, SIGNAL (newAddonRequest ()), this, SLOT (createAddon ())); connect (mViewManager, &CSVDoc::ViewManager::newAddonRequest, this, &Editor::createAddon);
connect (mViewManager, SIGNAL (loadDocumentRequest ()), this, SLOT (loadDocument ())); connect (mViewManager, &CSVDoc::ViewManager::loadDocumentRequest, this, &Editor::loadDocument);
connect (mViewManager, SIGNAL (editSettingsRequest()), this, SLOT (showSettings ())); connect (mViewManager, &CSVDoc::ViewManager::editSettingsRequest, this, &Editor::showSettings);
connect (mViewManager, SIGNAL (mergeDocument (CSMDoc::Document *)), this, SLOT (mergeDocument (CSMDoc::Document *))); connect (mViewManager, &CSVDoc::ViewManager::mergeDocument, this, &Editor::mergeDocument);
connect (&mStartup, SIGNAL (createGame()), this, SLOT (createGame ())); connect (&mStartup, &CSVDoc::StartupDialogue::createGame, this, &Editor::createGame);
connect (&mStartup, SIGNAL (createAddon()), this, SLOT (createAddon ())); connect (&mStartup, &CSVDoc::StartupDialogue::createAddon, this, &Editor::createAddon);
connect (&mStartup, SIGNAL (loadDocument()), this, SLOT (loadDocument ())); connect (&mStartup, &CSVDoc::StartupDialogue::loadDocument, this, &Editor::loadDocument);
connect (&mStartup, SIGNAL (editConfig()), this, SLOT (showSettings ())); connect (&mStartup, &CSVDoc::StartupDialogue::editConfig, this, &Editor::showSettings);
connect (&mFileDialog, SIGNAL(signalOpenFiles (const boost::filesystem::path&)), connect (&mFileDialog, &CSVDoc::FileDialog::signalOpenFiles,
this, SLOT(openFiles (const boost::filesystem::path&))); this, [this](const std::filesystem::path &savePath){ this->openFiles(savePath); });
connect (&mFileDialog, &CSVDoc::FileDialog::signalCreateNewFile, this, &Editor::createNewFile);
connect (&mFileDialog, &CSVDoc::FileDialog::rejected, this, &Editor::cancelFileDialog);
connect (&mFileDialog, SIGNAL(signalCreateNewFile (const boost::filesystem::path&)), connect (&mNewGame, &CSVDoc::NewGameDialogue::createRequest, this, &Editor::createNewGame);
this, SLOT(createNewFile (const boost::filesystem::path&))); connect (&mNewGame, &CSVDoc::NewGameDialogue::cancelCreateGame, this, &Editor::cancelCreateGame);
connect (&mFileDialog, SIGNAL (rejected()), this, SLOT (cancelFileDialog ()));
connect (&mNewGame, SIGNAL (createRequest (const boost::filesystem::path&)),
this, SLOT (createNewGame (const boost::filesystem::path&)));
connect (&mNewGame, SIGNAL (cancelCreateGame()), this, SLOT (cancelCreateGame ()));
} }
CS::Editor::~Editor () CS::Editor::~Editor ()
@ -80,9 +80,8 @@ CS::Editor::~Editor ()
mPidFile.close(); mPidFile.close();
if(mServer && boost::filesystem::exists(mPid)) if(mServer && std::filesystem::exists(mPid))
static_cast<void> ( // silence coverity warning std::filesystem::remove(mPid);
remove(mPid.string().c_str())); // ignore any error
} }
boost::program_options::variables_map CS::Editor::readConfiguration() boost::program_options::variables_map CS::Editor::readConfiguration()
@ -90,19 +89,19 @@ boost::program_options::variables_map CS::Editor::readConfiguration()
boost::program_options::variables_map variables; boost::program_options::variables_map variables;
boost::program_options::options_description desc("Syntax: openmw-cs <options>\nAllowed options"); boost::program_options::options_description desc("Syntax: openmw-cs <options>\nAllowed options");
desc.add_options() auto addOption = desc.add_options();
("data", boost::program_options::value<Files::MaybeQuotedPathContainer>()->default_value(Files::MaybeQuotedPathContainer(), "data")->multitoken()->composing()) addOption("data", boost::program_options::value<Files::MaybeQuotedPathContainer>()->default_value(Files::MaybeQuotedPathContainer(), "data")->multitoken()->composing());
("data-local", boost::program_options::value<Files::MaybeQuotedPathContainer::value_type>()->default_value(Files::MaybeQuotedPathContainer::value_type(), "")) addOption("data-local", boost::program_options::value<Files::MaybeQuotedPathContainer::value_type>()->default_value(Files::MaybeQuotedPathContainer::value_type(), ""));
("fs-strict", boost::program_options::value<bool>()->implicit_value(true)->default_value(false)) addOption("fs-strict", boost::program_options::value<bool>()->implicit_value(true)->default_value(false));
("encoding", boost::program_options::value<std::string>()->default_value("win1252")) addOption("encoding", boost::program_options::value<std::string>()->default_value("win1252"));
("resources", boost::program_options::value<Files::MaybeQuotedPath>()->default_value(Files::MaybeQuotedPath(), "resources")) addOption("resources", boost::program_options::value<Files::MaybeQuotedPath>()->default_value(Files::MaybeQuotedPath(), "resources"));
("fallback-archive", boost::program_options::value<std::vector<std::string>>()-> addOption("fallback-archive", boost::program_options::value<std::vector<std::string>>()->
default_value(std::vector<std::string>(), "fallback-archive")->multitoken()) default_value(std::vector<std::string>(), "fallback-archive")->multitoken());
("fallback", boost::program_options::value<FallbackMap>()->default_value(FallbackMap(), "") addOption("fallback", boost::program_options::value<FallbackMap>()->default_value(FallbackMap(), "")
->multitoken()->composing(), "fallback values") ->multitoken()->composing(), "fallback values");
("script-blacklist", boost::program_options::value<std::vector<std::string>>()->default_value(std::vector<std::string>(), "") addOption("script-blacklist", boost::program_options::value<std::vector<std::string>>()->default_value(std::vector<std::string>(), "")
->multitoken(), "exclude specified script from the verifier (if the use of the blacklist is enabled)") ->multitoken(), "exclude specified script from the verifier (if the use of the blacklist is enabled)");
("script-blacklist-use", boost::program_options::value<bool>()->implicit_value(true) addOption("script-blacklist-use", boost::program_options::value<bool>()->implicit_value(true)
->default_value(true), "enable script blacklisting"); ->default_value(true), "enable script blacklisting");
Files::ConfigurationManager::addCommonOptions(desc); Files::ConfigurationManager::addCommonOptions(desc);
@ -110,7 +109,7 @@ boost::program_options::variables_map CS::Editor::readConfiguration()
mCfgMgr.readConfiguration(variables, desc, false); mCfgMgr.readConfiguration(variables, desc, false);
Settings::Manager::load(mCfgMgr, true); Settings::Manager::load(mCfgMgr, true);
setupLogging(mCfgMgr.getLogPath().string(), "OpenMW-CS"); setupLogging(mCfgMgr.getLogPath(), "OpenMW-CS");
return variables; return variables;
} }
@ -125,7 +124,7 @@ std::pair<Files::PathContainer, std::vector<std::string> > CS::Editor::readConfi
mDocumentManager.setEncoding(ToUTF8::calculateEncoding(mEncodingName)); mDocumentManager.setEncoding(ToUTF8::calculateEncoding(mEncodingName));
mFileDialog.setEncoding (QString::fromUtf8(mEncodingName.c_str())); mFileDialog.setEncoding (QString::fromUtf8(mEncodingName.c_str()));
mDocumentManager.setResourceDir (mResources = variables["resources"].as<Files::MaybeQuotedPath>()); mDocumentManager.setResourceDir (mResources = variables["resources"].as<Files::MaybeQuotedPath>().u8string()); // This call to u8string is redundant, but required to build on MSVC 14.26 due to implementation bugs.
if (variables["script-blacklist-use"].as<bool>()) if (variables["script-blacklist-use"].as<bool>())
mDocumentManager.setBlacklistedScripts ( mDocumentManager.setBlacklistedScripts (
@ -138,10 +137,10 @@ std::pair<Files::PathContainer, std::vector<std::string> > CS::Editor::readConfi
dataDirs = asPathContainer(variables["data"].as<Files::MaybeQuotedPathContainer>()); dataDirs = asPathContainer(variables["data"].as<Files::MaybeQuotedPathContainer>());
} }
Files::PathContainer::value_type local(variables["data-local"].as<Files::MaybeQuotedPathContainer::value_type>()); Files::PathContainer::value_type local(variables["data-local"].as<Files::MaybeQuotedPathContainer::value_type>().u8string()); // This call to u8string is redundant, but required to build on MSVC 14.26 due to implementation bugs.
if (!local.empty()) if (!local.empty())
{ {
boost::filesystem::create_directories(local); std::filesystem::create_directories(local);
dataLocal.push_back(local); dataLocal.push_back(local);
} }
mCfgMgr.filterOutNonExistingPaths(dataDirs); mCfgMgr.filterOutNonExistingPaths(dataDirs);
@ -228,14 +227,15 @@ void CS::Editor::loadDocument()
mFileDialog.showDialog (CSVDoc::ContentAction_Edit); mFileDialog.showDialog (CSVDoc::ContentAction_Edit);
} }
void CS::Editor::openFiles (const boost::filesystem::path &savePath, const std::vector<boost::filesystem::path> &discoveredFiles) void CS::Editor::openFiles (const std::filesystem::path &savePath, const std::vector<std::filesystem::path> &discoveredFiles)
{ {
std::vector<boost::filesystem::path> files; std::vector<std::filesystem::path> files;
if(discoveredFiles.empty()) if(discoveredFiles.empty())
{ {
for (const QString &path : mFileDialog.selectedFilePaths()) for (const QString &path : mFileDialog.selectedFilePaths()) {
files.emplace_back(path.toUtf8().constData()); files.emplace_back(Files::pathFromQString(path));
}
} }
else else
{ {
@ -247,12 +247,12 @@ void CS::Editor::openFiles (const boost::filesystem::path &savePath, const std::
mFileDialog.hide(); mFileDialog.hide();
} }
void CS::Editor::createNewFile (const boost::filesystem::path &savePath) void CS::Editor::createNewFile (const std::filesystem::path &savePath)
{ {
std::vector<boost::filesystem::path> files; std::vector<std::filesystem::path> files;
for (const QString &path : mFileDialog.selectedFilePaths()) { for (const QString &path : mFileDialog.selectedFilePaths()) {
files.emplace_back(path.toUtf8().constData()); files.emplace_back(Files::pathFromQString(path));
} }
files.push_back (savePath); files.push_back (savePath);
@ -262,9 +262,9 @@ void CS::Editor::createNewFile (const boost::filesystem::path &savePath)
mFileDialog.hide(); mFileDialog.hide();
} }
void CS::Editor::createNewGame (const boost::filesystem::path& file) void CS::Editor::createNewGame (const std::filesystem::path& file)
{ {
std::vector<boost::filesystem::path> files; std::vector<std::filesystem::path> files;
files.push_back (file); files.push_back (file);
@ -295,13 +295,13 @@ bool CS::Editor::makeIPCServer()
{ {
try try
{ {
mPid = boost::filesystem::temp_directory_path(); mPid = std::filesystem::temp_directory_path();
mPid /= "openmw-cs.pid"; mPid /= "openmw-cs.pid";
bool pidExists = boost::filesystem::exists(mPid); bool pidExists = std::filesystem::exists(mPid);
mPidFile.open(mPid); mPidFile.open(mPid);
mLock = boost::interprocess::file_lock(mPid.string().c_str()); mLock = boost::interprocess::file_lock(mPid.c_str());
if(!mLock.try_lock()) if(!mLock.try_lock())
{ {
Log(Debug::Error) << "Error: OpenMW-CS is already running."; Log(Debug::Error) << "Error: OpenMW-CS is already running.";
@ -324,12 +324,13 @@ bool CS::Editor::makeIPCServer()
mServer->close(); mServer->close();
fullPath.remove(QRegExp("dummy$")); fullPath.remove(QRegExp("dummy$"));
fullPath += mIpcServerName; fullPath += mIpcServerName;
if(boost::filesystem::exists(fullPath.toUtf8().constData())) const auto path = Files::pathFromQString(fullPath);
if(exists(path))
{ {
// TODO: compare pid of the current process with that in the file // TODO: compare pid of the current process with that in the file
Log(Debug::Info) << "Detected unclean shutdown."; Log(Debug::Info) << "Detected unclean shutdown.";
// delete the stale file // delete the stale file
if(remove(fullPath.toUtf8().constData())) if(remove(path))
Log(Debug::Error) << "Error: can not remove stale connection file."; Log(Debug::Error) << "Error: can not remove stale connection file.";
} }
} }
@ -343,7 +344,7 @@ bool CS::Editor::makeIPCServer()
if(mServer->listen(mIpcServerName)) if(mServer->listen(mIpcServerName))
{ {
connect(mServer, SIGNAL(newConnection()), this, SLOT(showStartup())); connect(mServer, &QLocalServer::newConnection, this, &Editor::showStartup);
return true; return true;
} }
@ -377,27 +378,24 @@ int CS::Editor::run()
ESM::ESMReader fileReader; ESM::ESMReader fileReader;
ToUTF8::Utf8Encoder encoder(ToUTF8::calculateEncoding(mEncodingName)); ToUTF8::Utf8Encoder encoder(ToUTF8::calculateEncoding(mEncodingName));
fileReader.setEncoder(&encoder); fileReader.setEncoder(&encoder);
fileReader.open(mFileToLoad.string()); fileReader.open(mFileToLoad);
std::vector<boost::filesystem::path> discoveredFiles; std::vector<std::filesystem::path> discoveredFiles;
for (std::vector<ESM::Header::MasterData>::const_iterator itemIter = fileReader.getGameFiles().begin(); for (const auto& item : fileReader.getGameFiles())
itemIter != fileReader.getGameFiles().end(); ++itemIter)
{ {
for (Files::PathContainer::const_iterator pathIter = mDataDirs.begin(); for (const auto& path : mDataDirs)
pathIter != mDataDirs.end(); ++pathIter)
{ {
const boost::filesystem::path masterPath = *pathIter / itemIter->name; if (auto masterPath = path / item.name; std::filesystem::exists(masterPath))
if (boost::filesystem::exists(masterPath))
{ {
discoveredFiles.push_back(masterPath); discoveredFiles.emplace_back(std::move(masterPath));
break; break;
} }
} }
} }
discoveredFiles.push_back(mFileToLoad); discoveredFiles.push_back(mFileToLoad);
QString extension = QString::fromStdString(mFileToLoad.extension().string()).toLower(); const auto extension = Files::pathToQString(mFileToLoad.extension()).toLower();
if (extension == ".esm") if (extension == ".esm")
{ {
mFileToLoad.replace_extension(".omwgame"); mFileToLoad.replace_extension(".omwgame");

View file

@ -1,8 +1,9 @@
#ifndef CS_EDITOR_H #ifndef CS_EDITOR_H
#define CS_EDITOR_H #define CS_EDITOR_H
#include <fstream>
#include <boost/interprocess/sync/file_lock.hpp> #include <boost/interprocess/sync/file_lock.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/program_options/variables_map.hpp> #include <boost/program_options/variables_map.hpp>
#include <QObject> #include <QObject>
@ -48,15 +49,15 @@ namespace CS
CSVDoc::NewGameDialogue mNewGame; CSVDoc::NewGameDialogue mNewGame;
CSVPrefs::Dialogue mSettings; CSVPrefs::Dialogue mSettings;
CSVDoc::FileDialog mFileDialog; CSVDoc::FileDialog mFileDialog;
boost::filesystem::path mLocal; std::filesystem::path mLocal;
boost::filesystem::path mResources; std::filesystem::path mResources;
boost::filesystem::path mPid; std::filesystem::path mPid;
boost::interprocess::file_lock mLock; boost::interprocess::file_lock mLock;
boost::filesystem::ofstream mPidFile; std::ofstream mPidFile;
bool mFsStrict; bool mFsStrict;
CSVTools::Merge mMerge; CSVTools::Merge mMerge;
CSVDoc::ViewManager* mViewManager; CSVDoc::ViewManager* mViewManager;
boost::filesystem::path mFileToLoad; std::filesystem::path mFileToLoad;
Files::PathContainer mDataDirs; Files::PathContainer mDataDirs;
std::string mEncodingName; std::string mEncodingName;
@ -88,9 +89,9 @@ namespace CS
void cancelFileDialog(); void cancelFileDialog();
void loadDocument(); void loadDocument();
void openFiles (const boost::filesystem::path &path, const std::vector<boost::filesystem::path> &discoveredFiles = std::vector<boost::filesystem::path>()); void openFiles (const std::filesystem::path &path, const std::vector<std::filesystem::path> &discoveredFiles = {});
void createNewFile (const boost::filesystem::path& path); void createNewFile (const std::filesystem::path& path);
void createNewGame (const boost::filesystem::path& file); void createNewGame (const std::filesystem::path& file);
void showStartup(); void showStartup();

View file

@ -25,6 +25,6 @@ void CSMDoc::Blacklist::add (CSMWorld::UniversalId::Type type,
list.resize (size+ids.size()); list.resize (size+ids.size());
std::transform (ids.begin(), ids.end(), list.begin()+size, Misc::StringUtils::lowerCase); std::transform (ids.begin(), ids.end(), list.begin()+size, [](const std::string& s) { return Misc::StringUtils::lowerCase(s); } );
std::sort (list.begin(), list.end()); std::sort (list.begin(), list.end());
} }

View file

@ -4,9 +4,8 @@
#include <cassert> #include <cassert>
#include <memory> #include <memory>
#include <filesystem>
#include <boost/filesystem.hpp> #include <utility>
#include <boost/filesystem/fstream.hpp>
#include "../world/defaultgmsts.hpp" #include "../world/defaultgmsts.hpp"
@ -15,6 +14,7 @@
#endif #endif
#include <components/debug/debuglog.hpp> #include <components/debug/debuglog.hpp>
#include <components/files/conversion.hpp>
void CSMDoc::Document::addGmsts() void CSMDoc::Document::addGmsts()
{ {
@ -87,7 +87,7 @@ void CSMDoc::Document::addOptionalGlobals()
"DaysPassed", "DaysPassed",
"PCWerewolf", "PCWerewolf",
"PCYear", "PCYear",
0 nullptr,
}; };
for (int i=0; sGlobals[i]; ++i) for (int i=0; sGlobals[i]; ++i)
@ -162,7 +162,7 @@ void CSMDoc::Document::createBase()
"PCVampire", "PCVampire",
"PCWerewolf", "PCWerewolf",
"PCYear", "PCYear",
0 nullptr,
}; };
for (int i=0; sGlobals[i]; ++i) for (int i=0; sGlobals[i]; ++i)
@ -200,7 +200,7 @@ void CSMDoc::Document::createBase()
"Idle", "Idle",
"Flee", "Flee",
"Hit", "Hit",
0 nullptr,
}; };
for (int i=0; sVoice[i]; ++i) for (int i=0; sVoice[i]; ++i)
@ -225,7 +225,7 @@ void CSMDoc::Document::createBase()
"Greeting 7", "Greeting 7",
"Greeting 8", "Greeting 8",
"Greeting 9", "Greeting 9",
0 nullptr,
}; };
for (int i=0; sGreetings[i]; ++i) for (int i=0; sGreetings[i]; ++i)
@ -250,7 +250,7 @@ void CSMDoc::Document::createBase()
"Admire Fail", "Admire Fail",
"Taunt Fail", "Taunt Fail",
"Bribe Fail", "Bribe Fail",
0 nullptr,
}; };
for (int i=0; sPersuasion[i]; ++i) for (int i=0; sPersuasion[i]; ++i)
@ -277,14 +277,14 @@ void CSMDoc::Document::createBase()
} }
CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, CSMDoc::Document::Document (const Files::ConfigurationManager& configuration,
const std::vector< boost::filesystem::path >& files,bool new_, std::vector< std::filesystem::path > files,bool new_,
const boost::filesystem::path& savePath, const boost::filesystem::path& resDir, const std::filesystem::path& savePath, const std::filesystem::path& resDir,
ToUTF8::FromType encoding, const std::vector<std::string>& blacklistedScripts, ToUTF8::FromType encoding, const std::vector<std::string>& blacklistedScripts,
bool fsStrict, const Files::PathContainer& dataPaths, const std::vector<std::string>& archives) bool fsStrict, const Files::PathContainer& dataPaths, const std::vector<std::string>& archives)
: mSavePath (savePath), mContentFiles (files), mNew (new_), mData (encoding, fsStrict, dataPaths, archives, resDir), : mSavePath (savePath), mContentFiles (std::move(files)), mNew (new_), mData (encoding, fsStrict, dataPaths, archives, resDir),
mTools (*this, encoding), mTools (*this, encoding),
mProjectPath ((configuration.getUserDataPath() / "projects") / mProjectPath ((configuration.getUserDataPath() / "projects") /
(savePath.filename().string() + ".project")), (savePath.filename().u8string() + u8".project")),
mSavingOperation (*this, mProjectPath, encoding), mSavingOperation (*this, mProjectPath, encoding),
mSaving (&mSavingOperation), mSaving (&mSavingOperation),
mResDir(resDir), mRunner (mProjectPath), mResDir(resDir), mRunner (mProjectPath),
@ -293,21 +293,21 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration,
if (mContentFiles.empty()) if (mContentFiles.empty())
throw std::runtime_error ("Empty content file sequence"); throw std::runtime_error ("Empty content file sequence");
if (mNew || !boost::filesystem::exists (mProjectPath)) if (mNew || !std::filesystem::exists (mProjectPath))
{ {
boost::filesystem::path filtersPath (configuration.getUserDataPath() / "defaultfilters"); auto filtersPath = configuration.getUserDataPath() / "defaultfilters";
boost::filesystem::ofstream destination(mProjectPath, std::ios::out | std::ios::binary); std::ofstream destination(mProjectPath, std::ios::out | std::ios::binary);
if (!destination.is_open()) if (!destination.is_open())
throw std::runtime_error("Can not create project file: " + mProjectPath.string()); throw std::runtime_error("Can not create project file: " + Files::pathToUnicodeString(mProjectPath));
destination.exceptions(std::ios::failbit | std::ios::badbit); destination.exceptions(std::ios::failbit | std::ios::badbit);
if (!boost::filesystem::exists (filtersPath)) if (!std::filesystem::exists (filtersPath))
filtersPath = mResDir / "defaultfilters"; filtersPath = mResDir / "defaultfilters";
boost::filesystem::ifstream source(filtersPath, std::ios::in | std::ios::binary); std::ifstream source(filtersPath, std::ios::in | std::ios::binary);
if (!source.is_open()) if (!source.is_open())
throw std::runtime_error("Can not read filters file: " + filtersPath.string()); throw std::runtime_error("Can not read filters file: " + Files::pathToUnicodeString(filtersPath));
source.exceptions(std::ios::failbit | std::ios::badbit); source.exceptions(std::ios::failbit | std::ios::badbit);
destination << source.rdbuf(); destination << source.rdbuf();
@ -325,22 +325,20 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration,
addOptionalGlobals(); addOptionalGlobals();
addOptionalMagicEffects(); addOptionalMagicEffects();
connect (&mUndoStack, SIGNAL (cleanChanged (bool)), this, SLOT (modificationStateChanged (bool))); connect (&mUndoStack, &QUndoStack::cleanChanged, this, &Document::modificationStateChanged);
connect (&mTools, SIGNAL (progress (int, int, int)), this, SLOT (progress (int, int, int))); connect (&mTools, &CSMTools::Tools::progress, this, qOverload<int, int, int>(&Document::progress));
connect (&mTools, SIGNAL (done (int, bool)), this, SIGNAL (operationDone (int, bool))); connect (&mTools, &CSMTools::Tools::done, this, &Document::operationDone);
connect (&mTools, SIGNAL (done (int, bool)), this, SLOT (operationDone2 (int, bool))); connect (&mTools, &CSMTools::Tools::done, this, &Document::operationDone2);
connect (&mTools, SIGNAL (mergeDone (CSMDoc::Document*)), connect (&mTools, &CSMTools::Tools::mergeDone, this, &Document::mergeDone);
this, SIGNAL (mergeDone (CSMDoc::Document*)));
connect (&mSaving, SIGNAL (progress (int, int, int)), this, SLOT (progress (int, int, int))); connect (&mSaving, &OperationHolder::progress,
connect (&mSaving, SIGNAL (done (int, bool)), this, SLOT (operationDone2 (int, bool))); this, qOverload<int, int, int>(&Document::progress));
connect (&mSaving, &OperationHolder::done, this, &Document::operationDone2);
connect ( connect (&mSaving, &OperationHolder::reportMessage, this, &Document::reportMessage);
&mSaving, SIGNAL (reportMessage (const CSMDoc::Message&, int)),
this, SLOT (reportMessage (const CSMDoc::Message&, int)));
connect (&mRunner, SIGNAL (runStateChanged()), this, SLOT (runStateChanged())); connect (&mRunner, &Runner::runStateChanged, this, &Document::runStateChanged);
} }
CSMDoc::Document::~Document() CSMDoc::Document::~Document()
@ -371,22 +369,22 @@ int CSMDoc::Document::getState() const
return state; return state;
} }
const boost::filesystem::path& CSMDoc::Document::getResourceDir() const const std::filesystem::path& CSMDoc::Document::getResourceDir() const
{ {
return mResDir; return mResDir;
} }
const boost::filesystem::path& CSMDoc::Document::getSavePath() const const std::filesystem::path& CSMDoc::Document::getSavePath() const
{ {
return mSavePath; return mSavePath;
} }
const boost::filesystem::path& CSMDoc::Document::getProjectPath() const const std::filesystem::path& CSMDoc::Document::getProjectPath() const
{ {
return mProjectPath; return mProjectPath;
} }
const std::vector<boost::filesystem::path>& CSMDoc::Document::getContentFiles() const const std::vector<std::filesystem::path>& CSMDoc::Document::getContentFiles() const
{ {
return mContentFiles; return mContentFiles;
} }
@ -483,11 +481,11 @@ bool CSMDoc::Document::isBlacklisted (const CSMWorld::UniversalId& id)
void CSMDoc::Document::startRunning (const std::string& profile, void CSMDoc::Document::startRunning (const std::string& profile,
const std::string& startupInstruction) const std::string& startupInstruction)
{ {
std::vector<std::string> contentFiles; std::vector<std::filesystem::path> contentFiles;
for (std::vector<boost::filesystem::path>::const_iterator iter (mContentFiles.begin()); for (const auto & mContentFile : mContentFiles) {
iter!=mContentFiles.end(); ++iter) contentFiles.emplace_back(mContentFile.filename());
contentFiles.push_back (iter->filename().string()); }
mRunner.configure (getData().getDebugProfiles().getRecord (profile).get(), contentFiles, mRunner.configure (getData().getDebugProfiles().getRecord (profile).get(), contentFiles,
startupInstruction); startupInstruction);

View file

@ -3,8 +3,6 @@
#include <string> #include <string>
#include <boost/filesystem/path.hpp>
#include <QUndoStack> #include <QUndoStack>
#include <QObject> #include <QObject>
@ -58,15 +56,15 @@ namespace CSMDoc
private: private:
boost::filesystem::path mSavePath; std::filesystem::path mSavePath;
std::vector<boost::filesystem::path> mContentFiles; std::vector<std::filesystem::path> mContentFiles;
bool mNew; bool mNew;
CSMWorld::Data mData; CSMWorld::Data mData;
CSMTools::Tools mTools; CSMTools::Tools mTools;
boost::filesystem::path mProjectPath; std::filesystem::path mProjectPath;
Saving mSavingOperation; Saving mSavingOperation;
OperationHolder mSaving; OperationHolder mSaving;
boost::filesystem::path mResDir; std::filesystem::path mResDir;
Blacklist mBlacklist; Blacklist mBlacklist;
Runner mRunner; Runner mRunner;
bool mDirty; bool mDirty;
@ -100,8 +98,8 @@ namespace CSMDoc
public: public:
Document (const Files::ConfigurationManager& configuration, Document (const Files::ConfigurationManager& configuration,
const std::vector< boost::filesystem::path >& files, bool new_, std::vector< std::filesystem::path > files, bool new_,
const boost::filesystem::path& savePath, const boost::filesystem::path& resDir, const std::filesystem::path& savePath, const std::filesystem::path& resDir,
ToUTF8::FromType encoding, const std::vector<std::string>& blacklistedScripts, ToUTF8::FromType encoding, const std::vector<std::string>& blacklistedScripts,
bool fsStrict, const Files::PathContainer& dataPaths, const std::vector<std::string>& archives); bool fsStrict, const Files::PathContainer& dataPaths, const std::vector<std::string>& archives);
@ -111,13 +109,13 @@ namespace CSMDoc
int getState() const; int getState() const;
const boost::filesystem::path& getResourceDir() const; const std::filesystem::path& getResourceDir() const;
const boost::filesystem::path& getSavePath() const; const std::filesystem::path& getSavePath() const;
const boost::filesystem::path& getProjectPath() const; const std::filesystem::path& getProjectPath() const;
const std::vector<boost::filesystem::path>& getContentFiles() const; const std::vector<std::filesystem::path>& getContentFiles() const;
///< \attention The last element in this collection is the file that is being edited, ///< \attention The last element in this collection is the file that is being edited,
/// but with its original path instead of the save path. /// but with its original path instead of the save path.

View file

@ -1,6 +1,6 @@
#include "documentmanager.hpp" #include "documentmanager.hpp"
#include <boost/filesystem.hpp> #include <filesystem>
#ifndef Q_MOC_RUN #ifndef Q_MOC_RUN
#include <components/files/configurationmanager.hpp> #include <components/files/configurationmanager.hpp>
@ -11,28 +11,28 @@
CSMDoc::DocumentManager::DocumentManager (const Files::ConfigurationManager& configuration) CSMDoc::DocumentManager::DocumentManager (const Files::ConfigurationManager& configuration)
: mConfiguration (configuration), mEncoding (ToUTF8::WINDOWS_1252), mFsStrict(false) : mConfiguration (configuration), mEncoding (ToUTF8::WINDOWS_1252), mFsStrict(false)
{ {
boost::filesystem::path projectPath = configuration.getUserDataPath() / "projects"; std::filesystem::path projectPath = configuration.getUserDataPath() / "projects";
if (!boost::filesystem::is_directory (projectPath)) if (!std::filesystem::is_directory (projectPath))
boost::filesystem::create_directories (projectPath); std::filesystem::create_directories (projectPath);
mLoader.moveToThread (&mLoaderThread); mLoader.moveToThread (&mLoaderThread);
mLoaderThread.start(); mLoaderThread.start();
connect (&mLoader, SIGNAL (documentLoaded (Document *)), connect (&mLoader, &Loader::documentLoaded,
this, SLOT (documentLoaded (Document *))); this, &DocumentManager::documentLoaded);
connect (&mLoader, SIGNAL (documentNotLoaded (Document *, const std::string&)), connect (&mLoader, &Loader::documentNotLoaded,
this, SLOT (documentNotLoaded (Document *, const std::string&))); this, &DocumentManager::documentNotLoaded);
connect (this, SIGNAL (loadRequest (CSMDoc::Document *)), connect (this, &DocumentManager::loadRequest,
&mLoader, SLOT (loadDocument (CSMDoc::Document *))); &mLoader, &Loader::loadDocument);
connect (&mLoader, SIGNAL (nextStage (CSMDoc::Document *, const std::string&, int)), connect (&mLoader, &Loader::nextStage,
this, SIGNAL (nextStage (CSMDoc::Document *, const std::string&, int))); this, &DocumentManager::nextStage);
connect (&mLoader, SIGNAL (nextRecord (CSMDoc::Document *, int)), connect (&mLoader, &Loader::nextRecord,
this, SIGNAL (nextRecord (CSMDoc::Document *, int))); this, &DocumentManager::nextRecord);
connect (this, SIGNAL (cancelLoading (CSMDoc::Document *)), connect (this, &DocumentManager::cancelLoading,
&mLoader, SLOT (abortLoading (CSMDoc::Document *))); &mLoader, &Loader::abortLoading);
connect (&mLoader, SIGNAL (loadMessage (CSMDoc::Document *, const std::string&)), connect (&mLoader, &Loader::loadMessage,
this, SIGNAL (loadMessage (CSMDoc::Document *, const std::string&))); this, &DocumentManager::loadMessage);
} }
CSMDoc::DocumentManager::~DocumentManager() CSMDoc::DocumentManager::~DocumentManager()
@ -51,7 +51,7 @@ bool CSMDoc::DocumentManager::isEmpty()
return mDocuments.empty(); return mDocuments.empty();
} }
void CSMDoc::DocumentManager::addDocument (const std::vector<boost::filesystem::path>& files, const boost::filesystem::path& savePath, void CSMDoc::DocumentManager::addDocument (const std::vector<std::filesystem::path>& files, const std::filesystem::path& savePath,
bool new_) bool new_)
{ {
Document *document = makeDocument (files, savePath, new_); Document *document = makeDocument (files, savePath, new_);
@ -59,8 +59,8 @@ void CSMDoc::DocumentManager::addDocument (const std::vector<boost::filesystem::
} }
CSMDoc::Document *CSMDoc::DocumentManager::makeDocument ( CSMDoc::Document *CSMDoc::DocumentManager::makeDocument (
const std::vector< boost::filesystem::path >& files, const std::vector< std::filesystem::path >& files,
const boost::filesystem::path& savePath, bool new_) const std::filesystem::path& savePath, bool new_)
{ {
return new Document (mConfiguration, files, new_, savePath, mResDir, mEncoding, mBlacklistedScripts, mFsStrict, mDataPaths, mArchives); return new Document (mConfiguration, files, new_, savePath, mResDir, mEncoding, mBlacklistedScripts, mFsStrict, mDataPaths, mArchives);
} }
@ -93,9 +93,9 @@ void CSMDoc::DocumentManager::removeDocument (CSMDoc::Document *document)
emit lastDocumentDeleted(); emit lastDocumentDeleted();
} }
void CSMDoc::DocumentManager::setResourceDir (const boost::filesystem::path& parResDir) void CSMDoc::DocumentManager::setResourceDir (const std::filesystem::path& parResDir)
{ {
mResDir = boost::filesystem::system_complete(parResDir); mResDir = std::filesystem::absolute(parResDir);
} }
void CSMDoc::DocumentManager::setEncoding (ToUTF8::FromType encoding) void CSMDoc::DocumentManager::setEncoding (ToUTF8::FromType encoding)

View file

@ -4,8 +4,6 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include <boost/filesystem/path.hpp>
#include <QObject> #include <QObject>
#include <QThread> #include <QThread>
@ -40,7 +38,7 @@ namespace CSMDoc
ToUTF8::FromType mEncoding; ToUTF8::FromType mEncoding;
std::vector<std::string> mBlacklistedScripts; std::vector<std::string> mBlacklistedScripts;
boost::filesystem::path mResDir; std::filesystem::path mResDir;
bool mFsStrict; bool mFsStrict;
Files::PathContainer mDataPaths; Files::PathContainer mDataPaths;
@ -55,8 +53,8 @@ namespace CSMDoc
~DocumentManager(); ~DocumentManager();
void addDocument (const std::vector< boost::filesystem::path >& files, void addDocument (const std::vector< std::filesystem::path >& files,
const boost::filesystem::path& savePath, bool new_); const std::filesystem::path& savePath, bool new_);
///< \param new_ Do not load the last content file in \a files and instead create in an ///< \param new_ Do not load the last content file in \a files and instead create in an
/// appropriate way. /// appropriate way.
@ -66,10 +64,10 @@ namespace CSMDoc
/// ///
/// \param new_ Do not load the last content file in \a files and instead create in an /// \param new_ Do not load the last content file in \a files and instead create in an
/// appropriate way. /// appropriate way.
Document *makeDocument (const std::vector< boost::filesystem::path >& files, Document *makeDocument (const std::vector< std::filesystem::path >& files,
const boost::filesystem::path& savePath, bool new_); const std::filesystem::path& savePath, bool new_);
void setResourceDir (const boost::filesystem::path& parResDir); void setResourceDir (const std::filesystem::path& parResDir);
void setEncoding (ToUTF8::FromType encoding); void setEncoding (ToUTF8::FromType encoding);

View file

@ -1,5 +1,7 @@
#include "loader.hpp" #include "loader.hpp"
#include <components/files/conversion.hpp>
#include <iostream> #include <iostream>
#include "../tools/reportmodel.hpp" #include "../tools/reportmodel.hpp"
@ -14,7 +16,7 @@ CSMDoc::Loader::Loader()
{ {
mTimer = new QTimer (this); mTimer = new QTimer (this);
connect (mTimer, SIGNAL (timeout()), this, SLOT (load())); connect (mTimer, &QTimer::timeout, this, &Loader::load);
mTimer->start(); mTimer->start();
} }
@ -87,13 +89,13 @@ void CSMDoc::Loader::load()
if (iter->second.mFile<size) // start loading the files if (iter->second.mFile<size) // start loading the files
{ {
boost::filesystem::path path = document->getContentFiles()[iter->second.mFile]; std::filesystem::path path = document->getContentFiles()[iter->second.mFile];
int steps = document->getData().startLoading (path, iter->second.mFile!=editedIndex, /*project*/false); int steps = document->getData().startLoading (path, iter->second.mFile!=editedIndex, /*project*/false);
iter->second.mRecordsLeft = true; iter->second.mRecordsLeft = true;
iter->second.mRecordsLoaded = 0; iter->second.mRecordsLoaded = 0;
emit nextStage (document, path.filename().string(), steps); emit nextStage (document, Files::pathToUnicodeString(path.filename()), steps);
} }
else if (iter->second.mFile==size) // start loading the last (project) file else if (iter->second.mFile==size) // start loading the last (project) file
{ {

View file

@ -45,7 +45,7 @@ void CSMDoc::Operation::run()
if (!mConnected) if (!mConnected)
{ {
connect (mTimer, SIGNAL (timeout()), this, SLOT (executeStage())); connect (mTimer, &QTimer::timeout, this, &Operation::executeStage);
mConnected = true; mConnected = true;
} }

View file

@ -15,21 +15,18 @@ void CSMDoc::OperationHolder::setOperation (Operation *operation)
mOperation = operation; mOperation = operation;
mOperation->moveToThread (&mThread); mOperation->moveToThread (&mThread);
connect ( connect (mOperation, &Operation::progress,
mOperation, SIGNAL (progress (int, int, int)), this, &OperationHolder::progress);
this, SIGNAL (progress (int, int, int)));
connect ( connect (mOperation, &Operation::reportMessage,
mOperation, SIGNAL (reportMessage (const CSMDoc::Message&, int)), this, &OperationHolder::reportMessage);
this, SIGNAL (reportMessage (const CSMDoc::Message&, int)));
connect ( connect (mOperation, &Operation::done,
mOperation, SIGNAL (done (int, bool)), this, &OperationHolder::doneSlot);
this, SLOT (doneSlot (int, bool)));
connect (this, SIGNAL (abortSignal()), mOperation, SLOT (abort())); connect (this, &OperationHolder::abortSignal, mOperation, &Operation::abort);
connect (&mThread, SIGNAL (started()), mOperation, SLOT (run())); connect (&mThread, &QThread::started, mOperation, &Operation::run);
} }
bool CSMDoc::OperationHolder::isRunning() const bool CSMDoc::OperationHolder::isRunning() const

View file

@ -1,20 +1,25 @@
#include "runner.hpp" #include "runner.hpp"
#include <utility>
#include <QDir> #include <QDir>
#include <QTemporaryFile> #include <QTemporaryFile>
#include <QTextStream> #include <QTextStream>
#include <QCoreApplication> #include <QCoreApplication>
#include <components/files/conversion.hpp>
#include <components/files/qtconversion.hpp>
#include "operationholder.hpp" #include "operationholder.hpp"
CSMDoc::Runner::Runner (const boost::filesystem::path& projectPath) CSMDoc::Runner::Runner (std::filesystem::path projectPath)
: mRunning (false), mStartup (nullptr), mProjectPath (projectPath) : mRunning (false), mStartup (nullptr), mProjectPath (std::move(projectPath))
{ {
connect (&mProcess, SIGNAL (finished (int, QProcess::ExitStatus)), connect (&mProcess, qOverload<int, QProcess::ExitStatus>(&QProcess::finished),
this, SLOT (finished (int, QProcess::ExitStatus))); this, &Runner::finished);
connect (&mProcess, SIGNAL (readyReadStandardOutput()), connect (&mProcess, &QProcess::readyReadStandardOutput,
this, SLOT (readyReadStandardOutput())); this, &Runner::readyReadStandardOutput);
mProcess.setProcessChannelMode (QProcess::MergedChannels); mProcess.setProcessChannelMode (QProcess::MergedChannels);
@ -78,23 +83,21 @@ void CSMDoc::Runner::start (bool delayed)
else else
arguments << "--new-game=1"; arguments << "--new-game=1";
arguments << ("--script-run="+mStartup->fileName()); arguments << ("--script-run=" + mStartup->fileName());
arguments << arguments << "--data=\"" + Files::pathToQString(mProjectPath.parent_path()) + "\"";
QString::fromUtf8 (("--data=\""+mProjectPath.parent_path().string()+"\"").c_str());
arguments << "--replace=content"; arguments << "--replace=content";
for (std::vector<std::string>::const_iterator iter (mContentFiles.begin()); for (const auto& mContentFile : mContentFiles)
iter!=mContentFiles.end(); ++iter)
{ {
arguments << QString::fromUtf8 (("--content="+*iter).c_str()); arguments << "--content=" + Files::pathToQString(mContentFile);
} }
arguments arguments
<< QString::fromUtf8 (("--content="+mProjectPath.filename().string()).c_str()); << "--content=" + Files::pathToQString(mProjectPath.filename());
mProcess.start (path, arguments); mProcess.start(path, arguments);
} }
mRunning = true; mRunning = true;
@ -121,7 +124,7 @@ bool CSMDoc::Runner::isRunning() const
} }
void CSMDoc::Runner::configure (const ESM::DebugProfile& profile, void CSMDoc::Runner::configure (const ESM::DebugProfile& profile,
const std::vector<std::string>& contentFiles, const std::string& startupInstruction) const std::vector<std::filesystem::path> &contentFiles, const std::string& startupInstruction)
{ {
mProfile = profile; mProfile = profile;
mContentFiles = contentFiles; mContentFiles = contentFiles;
@ -149,7 +152,7 @@ void CSMDoc::Runner::readyReadStandardOutput()
CSMDoc::SaveWatcher::SaveWatcher (Runner *runner, OperationHolder *operation) CSMDoc::SaveWatcher::SaveWatcher (Runner *runner, OperationHolder *operation)
: QObject (runner), mRunner (runner) : QObject (runner), mRunner (runner)
{ {
connect (operation, SIGNAL (done (int, bool)), this, SLOT (saveDone (int, bool))); connect (operation, &OperationHolder::done, this, &SaveWatcher::saveDone);
} }
void CSMDoc::SaveWatcher::saveDone (int type, bool failed) void CSMDoc::SaveWatcher::saveDone (int type, bool failed)

View file

@ -4,14 +4,14 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include <boost/filesystem/path.hpp>
#include <QObject> #include <QObject>
#include <QProcess> #include <QProcess>
#include <QTextDocument> #include <QTextDocument>
#include <components/esm3/debugprofile.hpp> #include <components/esm3/debugprofile.hpp>
#include <filesystem>
class QTemporaryFile; class QTemporaryFile;
namespace CSMDoc namespace CSMDoc
@ -25,15 +25,15 @@ namespace CSMDoc
QProcess mProcess; QProcess mProcess;
bool mRunning; bool mRunning;
ESM::DebugProfile mProfile; ESM::DebugProfile mProfile;
std::vector<std::string> mContentFiles; std::vector<std::filesystem::path> mContentFiles;
std::string mStartupInstruction; std::string mStartupInstruction;
QTemporaryFile *mStartup; QTemporaryFile *mStartup;
QTextDocument mLog; QTextDocument mLog;
boost::filesystem::path mProjectPath; std::filesystem::path mProjectPath;
public: public:
Runner (const boost::filesystem::path& projectPath); Runner (std::filesystem::path projectPath);
~Runner(); ~Runner();
@ -48,7 +48,7 @@ namespace CSMDoc
bool isRunning() const; bool isRunning() const;
void configure (const ESM::DebugProfile& profile, void configure (const ESM::DebugProfile& profile,
const std::vector<std::string>& contentFiles, const std::vector<std::filesystem::path> &contentFiles,
const std::string& startupInstruction); const std::string& startupInstruction);
QTextDocument *getLog(); QTextDocument *getLog();

View file

@ -7,7 +7,7 @@
#include "savingstages.hpp" #include "savingstages.hpp"
#include "document.hpp" #include "document.hpp"
CSMDoc::Saving::Saving (Document& document, const boost::filesystem::path& projectPath, CSMDoc::Saving::Saving (Document& document, const std::filesystem::path& projectPath,
ToUTF8::FromType encoding) ToUTF8::FromType encoding)
: Operation (State_Saving, true, true), mDocument (document), mState (*this, projectPath, encoding) : Operation (State_Saving, true, true), mDocument (document), mState (*this, projectPath, encoding)
{ {

View file

@ -1,8 +1,6 @@
#ifndef CSM_DOC_SAVING_H #ifndef CSM_DOC_SAVING_H
#define CSM_DOC_SAVING_H #define CSM_DOC_SAVING_H
#include <boost/filesystem/path.hpp>
#include <components/to_utf8/to_utf8.hpp> #include <components/to_utf8/to_utf8.hpp>
#include "operation.hpp" #include "operation.hpp"
@ -21,7 +19,7 @@ namespace CSMDoc
public: public:
Saving (Document& document, const boost::filesystem::path& projectPath, Saving (Document& document, const std::filesystem::path& projectPath,
ToUTF8::FromType encoding); ToUTF8::FromType encoding);
}; };

View file

@ -1,10 +1,10 @@
#include "savingstages.hpp" #include "savingstages.hpp"
#include <sstream> #include <sstream>
#include <filesystem>
#include <boost/filesystem.hpp>
#include <components/esm3/loaddial.hpp> #include <components/esm3/loaddial.hpp>
#include <components/files/conversion.hpp>
#include "../world/infocollection.hpp" #include "../world/infocollection.hpp"
#include "../world/cellcoordinates.hpp" #include "../world/cellcoordinates.hpp"
@ -67,14 +67,14 @@ void CSMDoc::WriteHeaderStage::perform (int stage, Messages& messages)
mDocument.getData().count (CSMWorld::RecordBase::State_Deleted)); mDocument.getData().count (CSMWorld::RecordBase::State_Deleted));
/// \todo refine dependency list (at least remove redundant dependencies) /// \todo refine dependency list (at least remove redundant dependencies)
std::vector<boost::filesystem::path> dependencies = mDocument.getContentFiles(); std::vector<std::filesystem::path> dependencies = mDocument.getContentFiles();
std::vector<boost::filesystem::path>::const_iterator end (--dependencies.end()); std::vector<std::filesystem::path>::const_iterator end (--dependencies.end());
for (std::vector<boost::filesystem::path>::const_iterator iter (dependencies.begin()); for (std::vector<std::filesystem::path>::const_iterator iter (dependencies.begin());
iter!=end; ++iter) iter!=end; ++iter)
{ {
std::string name = iter->filename().string(); auto name = Files::pathToUnicodeString(iter->filename());
uint64_t size = boost::filesystem::file_size (*iter); auto size = std::filesystem::file_size (*iter);
mState.getWriter().addMaster (name, size); mState.getWriter().addMaster (name, size);
} }
@ -519,15 +519,15 @@ void CSMDoc::FinalSavingStage::perform (int stage, Messages& messages)
mState.getWriter().close(); mState.getWriter().close();
mState.getStream().close(); mState.getStream().close();
if (boost::filesystem::exists (mState.getTmpPath())) if (std::filesystem::exists (mState.getTmpPath()))
boost::filesystem::remove (mState.getTmpPath()); std::filesystem::remove (mState.getTmpPath());
} }
else if (!mState.isProjectFile()) else if (!mState.isProjectFile())
{ {
if (boost::filesystem::exists (mState.getPath())) if (std::filesystem::exists (mState.getPath()))
boost::filesystem::remove (mState.getPath()); std::filesystem::remove (mState.getPath());
boost::filesystem::rename (mState.getTmpPath(), mState.getPath()); std::filesystem::rename (mState.getTmpPath(), mState.getPath());
mDocument.getUndoStack().setClean(); mDocument.getUndoStack().setClean();
} }

View file

@ -1,13 +1,14 @@
#include "savingstate.hpp" #include "savingstate.hpp"
#include <boost/filesystem/fstream.hpp> #include <filesystem>
#include <utility>
#include "operation.hpp" #include "operation.hpp"
#include "document.hpp" #include "document.hpp"
CSMDoc::SavingState::SavingState (Operation& operation, const boost::filesystem::path& projectPath, CSMDoc::SavingState::SavingState (Operation& operation, std::filesystem::path projectPath,
ToUTF8::FromType encoding) ToUTF8::FromType encoding)
: mOperation (operation), mEncoder (encoding), mProjectPath (projectPath), mProjectFile (false) : mOperation (operation), mEncoder (encoding), mProjectPath (std::move(projectPath)), mProjectFile (false)
{ {
mWriter.setEncoder (&mEncoder); mWriter.setEncoder (&mEncoder);
} }
@ -33,24 +34,24 @@ void CSMDoc::SavingState::start (Document& document, bool project)
else else
mPath = document.getSavePath(); mPath = document.getSavePath();
boost::filesystem::path file (mPath.filename().string() + ".tmp"); std::filesystem::path file (mPath.filename().u8string() + u8".tmp");
mTmpPath = mPath.parent_path(); mTmpPath = mPath.parent_path();
mTmpPath /= file; mTmpPath /= file;
} }
const boost::filesystem::path& CSMDoc::SavingState::getPath() const const std::filesystem::path& CSMDoc::SavingState::getPath() const
{ {
return mPath; return mPath;
} }
const boost::filesystem::path& CSMDoc::SavingState::getTmpPath() const const std::filesystem::path& CSMDoc::SavingState::getTmpPath() const
{ {
return mTmpPath; return mTmpPath;
} }
boost::filesystem::ofstream& CSMDoc::SavingState::getStream() std::ofstream& CSMDoc::SavingState::getStream()
{ {
return mStream; return mStream;
} }

View file

@ -4,9 +4,7 @@
#include <fstream> #include <fstream>
#include <map> #include <map>
#include <deque> #include <deque>
#include <filesystem>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/fstream.hpp>
#include <components/esm3/esmwriter.hpp> #include <components/esm3/esmwriter.hpp>
@ -20,18 +18,18 @@ namespace CSMDoc
class SavingState class SavingState
{ {
Operation& mOperation; Operation& mOperation;
boost::filesystem::path mPath; std::filesystem::path mPath;
boost::filesystem::path mTmpPath; std::filesystem::path mTmpPath;
ToUTF8::Utf8Encoder mEncoder; ToUTF8::Utf8Encoder mEncoder;
boost::filesystem::ofstream mStream; std::ofstream mStream;
ESM::ESMWriter mWriter; ESM::ESMWriter mWriter;
boost::filesystem::path mProjectPath; std::filesystem::path mProjectPath;
bool mProjectFile; bool mProjectFile;
std::map<std::string, std::deque<int> > mSubRecords; // record ID, list of subrecords std::map<std::string, std::deque<int> > mSubRecords; // record ID, list of subrecords
public: public:
SavingState (Operation& operation, const boost::filesystem::path& projectPath, SavingState (Operation& operation, std::filesystem::path projectPath,
ToUTF8::FromType encoding); ToUTF8::FromType encoding);
bool hasError() const; bool hasError() const;
@ -39,11 +37,11 @@ namespace CSMDoc
void start (Document& document, bool project); void start (Document& document, bool project);
///< \param project Save project file instead of content file. ///< \param project Save project file instead of content file.
const boost::filesystem::path& getPath() const; const std::filesystem::path& getPath() const;
const boost::filesystem::path& getTmpPath() const; const std::filesystem::path& getTmpPath() const;
boost::filesystem::ofstream& getStream(); std::ofstream& getStream();
ESM::ESMWriter& getWriter(); ESM::ESMWriter& getWriter();

View file

@ -199,7 +199,7 @@ CSMFilter::Token CSMFilter::Parser::checkKeywords (const Token& token)
"true", "false", "true", "false",
"and", "or", "not", "and", "or", "not",
"string", "value", "string", "value",
0 nullptr,
}; };
std::string string = Misc::StringUtils::lowerCase (token.mString); std::string string = Misc::StringUtils::lowerCase (token.mString);

View file

@ -30,7 +30,7 @@ std::pair<QWidget *, QWidget *> CSMPrefs::BoolSetting::makeWidgets (QWidget *par
mWidget->setToolTip (tooltip); mWidget->setToolTip (tooltip);
} }
connect (mWidget, SIGNAL (stateChanged (int)), this, SLOT (valueChanged (int))); connect (mWidget, &QCheckBox::stateChanged, this, &BoolSetting::valueChanged);
return std::make_pair (static_cast<QWidget *> (nullptr), mWidget); return std::make_pair (static_cast<QWidget *> (nullptr), mWidget);
} }

View file

@ -35,7 +35,7 @@ std::pair<QWidget *, QWidget *> CSMPrefs::ColourSetting::makeWidgets (QWidget *p
mWidget->setToolTip (tooltip); mWidget->setToolTip (tooltip);
} }
connect (mWidget, SIGNAL (pickingFinished()), this, SLOT (valueChanged())); connect (mWidget, &CSVWidget::ColorEditor::pickingFinished, this, &ColourSetting::valueChanged);
return std::make_pair (label, mWidget); return std::make_pair (label, mWidget);
} }

View file

@ -66,7 +66,7 @@ std::pair<QWidget *, QWidget *> CSMPrefs::DoubleSetting::makeWidgets (QWidget *p
mWidget->setToolTip (tooltip); mWidget->setToolTip (tooltip);
} }
connect (mWidget, SIGNAL (valueChanged (double)), this, SLOT (valueChanged (double))); connect (mWidget, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &DoubleSetting::valueChanged);
return std::make_pair (label, mWidget); return std::make_pair (label, mWidget);
} }

View file

@ -97,7 +97,7 @@ std::pair<QWidget *, QWidget *> CSMPrefs::EnumSetting::makeWidgets (QWidget *par
label->setToolTip (tooltip); label->setToolTip (tooltip);
} }
connect (mWidget, SIGNAL (currentIndexChanged (int)), this, SLOT (valueChanged (int))); connect (mWidget, qOverload<int>(&QComboBox::currentIndexChanged), this, &EnumSetting::valueChanged);
return std::make_pair (label, mWidget); return std::make_pair (label, mWidget);
} }

View file

@ -58,7 +58,7 @@ std::pair<QWidget *, QWidget *> CSMPrefs::IntSetting::makeWidgets (QWidget *pare
mWidget->setToolTip (tooltip); mWidget->setToolTip (tooltip);
} }
connect (mWidget, SIGNAL (valueChanged (int)), this, SLOT (valueChanged (int))); connect (mWidget, qOverload<int>(&QSpinBox::valueChanged), this, &IntSetting::valueChanged);
return std::make_pair (label, mWidget); return std::make_pair (label, mWidget);
} }

View file

@ -40,7 +40,7 @@ namespace CSMPrefs
mButton = widget; mButton = widget;
connect(widget, SIGNAL(toggled(bool)), this, SLOT(buttonToggled(bool))); connect (widget, &QPushButton::toggled, this, &ModifierSetting::buttonToggled);
return std::make_pair(label, widget); return std::make_pair(label, widget);
} }
@ -49,7 +49,7 @@ namespace CSMPrefs
{ {
if (mButton) if (mButton)
{ {
std::string shortcut = Settings::Manager::getString(getKey(), getParent()->getKey()); const std::string& shortcut = Settings::Manager::getString(getKey(), getParent()->getKey());
int modifier; int modifier;
State::get().getShortcutManager().convertFromString(shortcut, modifier); State::get().getShortcutManager().convertFromString(shortcut, modifier);

View file

@ -176,8 +176,8 @@ namespace CSMPrefs
{ {
mAction->setText(mActionText); mAction->setText(mActionText);
disconnect(this, SIGNAL(activated()), mAction, SLOT(trigger())); disconnect(this, qOverload<>(&Shortcut::activated), mAction, &QAction::trigger);
disconnect(mAction, SIGNAL(destroyed()), this, SLOT(actionDeleted())); disconnect(mAction, &QAction::destroyed, this, &Shortcut::actionDeleted);
} }
mAction = action; mAction = action;
@ -187,8 +187,8 @@ namespace CSMPrefs
mActionText = mAction->text(); mActionText = mAction->text();
mAction->setText(mActionText + "\t" + State::get().getShortcutManager().convertToString(mSequence).data()); mAction->setText(mActionText + "\t" + State::get().getShortcutManager().convertToString(mSequence).data());
connect(this, SIGNAL(activated()), mAction, SLOT(trigger())); connect(this, qOverload<>(&Shortcut::activated), mAction, &QAction::trigger);
connect(mAction, SIGNAL(destroyed()), this, SLOT(actionDeleted())); connect(mAction, &QAction::destroyed, this, &Shortcut::actionDeleted);
} }
} }

View file

@ -34,7 +34,7 @@ namespace CSMPrefs
// Intercept widget events // Intercept widget events
widget->installEventFilter(this); widget->installEventFilter(this);
connect(widget, SIGNAL(destroyed()), this, SLOT(widgetDestroyed())); connect(widget, &QWidget::destroyed, this, &ShortcutEventHandler::widgetDestroyed);
} }
// Add to list // Add to list

View file

@ -780,7 +780,7 @@ namespace CSMPrefs
std::make_pair((int)Qt::Key_LastNumberRedial , "LastNumberRedial"), std::make_pair((int)Qt::Key_LastNumberRedial , "LastNumberRedial"),
std::make_pair((int)Qt::Key_Camera , "Camera"), std::make_pair((int)Qt::Key_Camera , "Camera"),
std::make_pair((int)Qt::Key_CameraFocus , "CameraFocus"), std::make_pair((int)Qt::Key_CameraFocus , "CameraFocus"),
std::make_pair(0 , (const char*) nullptr) std::make_pair(0 , static_cast<const char*>(nullptr)),
}; };
} }

View file

@ -46,7 +46,7 @@ namespace CSMPrefs
mButton = widget; mButton = widget;
connect(widget, SIGNAL(toggled(bool)), this, SLOT(buttonToggled(bool))); connect(widget, &QPushButton::toggled, this, &ShortcutSetting::buttonToggled);
return std::make_pair(label, widget); return std::make_pair(label, widget);
} }
@ -55,7 +55,7 @@ namespace CSMPrefs
{ {
if (mButton) if (mButton)
{ {
std::string shortcut = Settings::Manager::getString(getKey(), getParent()->getKey()); const std::string& shortcut = Settings::Manager::getString(getKey(), getParent()->getKey());
QKeySequence sequence; QKeySequence sequence;
State::get().getShortcutManager().convertFromString(shortcut, sequence); State::get().getShortcutManager().convertFromString(shortcut, sequence);

View file

@ -648,8 +648,7 @@ CSMPrefs::State::~State()
void CSMPrefs::State::save() void CSMPrefs::State::save()
{ {
boost::filesystem::path user = mConfigurationManager.getUserConfigPath() / mConfigFile; Settings::Manager::saveUser (mConfigurationManager.getUserConfigPath() / mConfigFile);
Settings::Manager::saveUser (user.string());
} }
CSMPrefs::State::Iterator CSMPrefs::State::begin() CSMPrefs::State::Iterator CSMPrefs::State::begin()
@ -679,7 +678,7 @@ CSMPrefs::Category& CSMPrefs::State::operator[] (const std::string& key)
void CSMPrefs::State::update (const Setting& setting) void CSMPrefs::State::update (const Setting& setting)
{ {
emit (settingChanged (&setting)); emit settingChanged(&setting);
} }
CSMPrefs::State& CSMPrefs::State::get() CSMPrefs::State& CSMPrefs::State::get()

View file

@ -30,7 +30,7 @@ std::pair<QWidget *, QWidget *> CSMPrefs::StringSetting::makeWidgets (QWidget *p
mWidget->setToolTip (tooltip); mWidget->setToolTip (tooltip);
} }
connect (mWidget, SIGNAL (textChanged (QString)), this, SLOT (textChanged (QString))); connect (mWidget, &QLineEdit::textChanged, this, &StringSetting::textChanged);
return std::make_pair (static_cast<QWidget *> (nullptr), mWidget); return std::make_pair (static_cast<QWidget *> (nullptr), mWidget);
} }

View file

@ -40,11 +40,11 @@ void CSMTools::FinishMergedDocumentStage::perform (int stage, CSMDoc::Messages&
// We know that the content file list contains at least two entries and that the first one // We know that the content file list contains at least two entries and that the first one
// does exist on disc (otherwise it would have been impossible to initiate a merge on that // does exist on disc (otherwise it would have been impossible to initiate a merge on that
// document). // document).
boost::filesystem::path path = mState.mSource.getContentFiles()[0]; std::filesystem::path path = mState.mSource.getContentFiles()[0];
ESM::ESMReader reader; ESM::ESMReader reader;
reader.setEncoder (&mEncoder); reader.setEncoder (&mEncoder);
reader.open (path.string()); reader.open (path);
CSMWorld::MetaData source; CSMWorld::MetaData source;
source.mId = "sys::meta"; source.mId = "sys::meta";

View file

@ -55,10 +55,10 @@ CSMDoc::OperationHolder *CSMTools::Tools::getVerifier()
{ {
mVerifierOperation = new CSMDoc::Operation (CSMDoc::State_Verifying, false); mVerifierOperation = new CSMDoc::Operation (CSMDoc::State_Verifying, false);
connect (&mVerifier, SIGNAL (progress (int, int, int)), this, SIGNAL (progress (int, int, int))); connect (&mVerifier, &CSMDoc::OperationHolder::progress, this, &Tools::progress);
connect (&mVerifier, SIGNAL (done (int, bool)), this, SIGNAL (done (int, bool))); connect (&mVerifier, &CSMDoc::OperationHolder::done, this, &Tools::done);
connect (&mVerifier, SIGNAL (reportMessage (const CSMDoc::Message&, int)), connect (&mVerifier, &CSMDoc::OperationHolder::reportMessage,
this, SLOT (verifierMessage (const CSMDoc::Message&, int))); this, &Tools::verifierMessage);
std::vector<std::string> mandatoryIds {"Day", "DaysPassed", "GameHour", "Month", "PCRace"}; std::vector<std::string> mandatoryIds {"Day", "DaysPassed", "GameHour", "Month", "PCRace"};
@ -143,13 +143,13 @@ CSMTools::Tools::Tools (CSMDoc::Document& document, ToUTF8::FromType encoding)
mReports.insert (std::make_pair (mNextReportNumber++, new ReportModel)); mReports.insert (std::make_pair (mNextReportNumber++, new ReportModel));
mActiveReports.insert (std::make_pair (CSMDoc::State_Loading, 0)); mActiveReports.insert (std::make_pair (CSMDoc::State_Loading, 0));
connect (&mSearch, SIGNAL (progress (int, int, int)), this, SIGNAL (progress (int, int, int))); connect (&mSearch, &CSMDoc::OperationHolder::progress, this, &Tools::progress);
connect (&mSearch, SIGNAL (done (int, bool)), this, SIGNAL (done (int, bool))); connect (&mSearch, &CSMDoc::OperationHolder::done, this, &Tools::done);
connect (&mSearch, SIGNAL (reportMessage (const CSMDoc::Message&, int)), connect (&mSearch, &CSMDoc::OperationHolder::reportMessage,
this, SLOT (verifierMessage (const CSMDoc::Message&, int))); this, &Tools::verifierMessage);
connect (&mMerge, SIGNAL (progress (int, int, int)), this, SIGNAL (progress (int, int, int))); connect (&mMerge, &CSMDoc::OperationHolder::progress, this, &Tools::progress);
connect (&mMerge, SIGNAL (done (int, bool)), this, SIGNAL (done (int, bool))); connect (&mMerge, &CSMDoc::OperationHolder::done, this, &Tools::done);
// don't need to connect report message, since there are no messages for merge // don't need to connect report message, since there are no messages for merge
} }
@ -222,8 +222,7 @@ void CSMTools::Tools::runMerge (std::unique_ptr<CSMDoc::Document> target)
{ {
mMergeOperation = new MergeOperation (mDocument, mEncoding); mMergeOperation = new MergeOperation (mDocument, mEncoding);
mMerge.setOperation (mMergeOperation); mMerge.setOperation (mMergeOperation);
connect (mMergeOperation, SIGNAL (mergeDone (CSMDoc::Document*)), connect (mMergeOperation, &MergeOperation::mergeDone, this, &Tools::mergeDone);
this, SIGNAL (mergeDone (CSMDoc::Document*)));
} }
target->flagAsDirty(); target->flagAsDirty();
@ -246,7 +245,7 @@ int CSMTools::Tools::getRunningOperations() const
CSMDoc::State_Verifying, CSMDoc::State_Verifying,
CSMDoc::State_Searching, CSMDoc::State_Searching,
CSMDoc::State_Merging, CSMDoc::State_Merging,
-1 -1,
}; };
int result = 0; int result = 0;

View file

@ -8,8 +8,6 @@
#include <QObject> #include <QObject>
#include <boost/filesystem/path.hpp>
#include "../doc/operationholder.hpp" #include "../doc/operationholder.hpp"
namespace CSMWorld namespace CSMWorld

View file

@ -194,28 +194,28 @@ namespace CSMWorld
{ {
// Setup qt slots and signals // Setup qt slots and signals
QAbstractItemModel* refModel = data.getTableModel(UniversalId::Type_Referenceable); QAbstractItemModel* refModel = data.getTableModel(UniversalId::Type_Referenceable);
connect(refModel, SIGNAL(rowsInserted(const QModelIndex&, int, int)), connect(refModel, &QAbstractItemModel::rowsInserted,
this, SLOT(handleReferenceablesInserted(const QModelIndex&, int, int))); this, &ActorAdapter::handleReferenceablesInserted);
connect(refModel, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), connect(refModel, &QAbstractItemModel::dataChanged,
this, SLOT(handleReferenceableChanged(const QModelIndex&, const QModelIndex&))); this, &ActorAdapter::handleReferenceableChanged);
connect(refModel, SIGNAL(rowsAboutToBeRemoved(const QModelIndex&, int, int)), connect(refModel, &QAbstractItemModel::rowsAboutToBeRemoved,
this, SLOT(handleReferenceablesAboutToBeRemoved(const QModelIndex&, int, int))); this, &ActorAdapter::handleReferenceablesAboutToBeRemoved);
QAbstractItemModel* raceModel = data.getTableModel(UniversalId::Type_Race); QAbstractItemModel* raceModel = data.getTableModel(UniversalId::Type_Race);
connect(raceModel, SIGNAL(rowsInserted(const QModelIndex&, int, int)), connect(raceModel, &QAbstractItemModel::rowsInserted,
this, SLOT(handleRacesAboutToBeRemoved(const QModelIndex&, int, int))); this, &ActorAdapter::handleRacesAboutToBeRemoved);
connect(raceModel, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), connect(raceModel, &QAbstractItemModel::dataChanged,
this, SLOT(handleRaceChanged(const QModelIndex&, const QModelIndex&))); this, &ActorAdapter::handleRaceChanged);
connect(raceModel, SIGNAL(rowsAboutToBeRemoved(const QModelIndex&, int, int)), connect(raceModel, &QAbstractItemModel::rowsAboutToBeRemoved,
this, SLOT(handleRacesAboutToBeRemoved(const QModelIndex&, int, int))); this, &ActorAdapter::handleRacesAboutToBeRemoved);
QAbstractItemModel* partModel = data.getTableModel(UniversalId::Type_BodyPart); QAbstractItemModel* partModel = data.getTableModel(UniversalId::Type_BodyPart);
connect(partModel, SIGNAL(rowsInserted(const QModelIndex&, int, int)), connect(partModel, &QAbstractItemModel::rowsInserted,
this, SLOT(handleBodyPartsInserted(const QModelIndex&, int, int))); this, &ActorAdapter::handleBodyPartsInserted);
connect(partModel, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), connect(partModel, &QAbstractItemModel::dataChanged,
this, SLOT(handleBodyPartChanged(const QModelIndex&, const QModelIndex&))); this, &ActorAdapter::handleBodyPartChanged);
connect(partModel, SIGNAL(rowsAboutToBeRemoved(const QModelIndex&, int, int)), connect(partModel, &QAbstractItemModel::rowsAboutToBeRemoved,
this, SLOT(handleBodyPartsAboutToBeRemoved(const QModelIndex&, int, int))); this, &ActorAdapter::handleBodyPartsAboutToBeRemoved);
} }
ActorAdapter::ActorDataPtr ActorAdapter::getActorData(const std::string& id) ActorAdapter::ActorDataPtr ActorAdapter::getActorData(const std::string& id)

View file

@ -91,7 +91,7 @@ bool CSMWorld::ColumnBase::isId (Display display)
Display_EffectAttribute, Display_EffectAttribute,
Display_IngredEffectId, Display_IngredEffectId,
Display_None Display_None,
}; };
for (int i=0; ids[i]!=Display_None; ++i) for (int i=0; ids[i]!=Display_None; ++i)

View file

@ -375,7 +375,8 @@ namespace CSMWorld
{ ColumnId_LevelledCreatureId,"Levelled Creature" }, { ColumnId_LevelledCreatureId,"Levelled Creature" },
{ -1, 0 } // end marker // end marker
{ -1, 0 },
}; };
} }
} }
@ -629,7 +630,7 @@ std::vector<std::pair<int,std::string>>CSMWorld::Columns::getEnums (ColumnId col
{ {
for (int i=0; i<8; i++) for (int i=0; i<8; i++)
{ {
const std::string& bloodName = Fallback::Map::getString("Blood_Texture_Name_" + std::to_string(i)); std::string_view bloodName = Fallback::Map::getString("Blood_Texture_Name_" + std::to_string(i));
if (!bloodName.empty()) if (!bloodName.empty())
enums.emplace_back(i, bloodName); enums.emplace_back(i, bloodName);
} }

View file

@ -95,7 +95,9 @@ void CSMWorld::CommandDispatcher::setEditLock (bool locked)
void CSMWorld::CommandDispatcher::setSelection (const std::vector<std::string>& selection) void CSMWorld::CommandDispatcher::setSelection (const std::vector<std::string>& selection)
{ {
mSelection = selection; mSelection = selection;
std::for_each (mSelection.begin(), mSelection.end(), Misc::StringUtils::lowerCaseInPlace); for (auto& sel : mSelection) {
Misc::StringUtils::lowerCaseInPlace(sel);
}
std::sort (mSelection.begin(), mSelection.end()); std::sort (mSelection.begin(), mSelection.end());
} }

View file

@ -38,12 +38,9 @@ void CSMWorld::Data::addModel (QAbstractItemModel *model, UniversalId::Type type
if (update) if (update)
{ {
connect (model, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)), connect (model, &QAbstractItemModel::dataChanged, this, &Data::dataChanged);
this, SLOT (dataChanged (const QModelIndex&, const QModelIndex&))); connect (model, &QAbstractItemModel::rowsInserted, this, &Data::rowsChanged);
connect (model, SIGNAL (rowsInserted (const QModelIndex&, int, int)), connect (model, &QAbstractItemModel::rowsRemoved, this, &Data::rowsChanged);
this, SLOT (rowsChanged (const QModelIndex&, int, int)));
connect (model, SIGNAL (rowsRemoved (const QModelIndex&, int, int)),
this, SLOT (rowsChanged (const QModelIndex&, int, int)));
} }
} }
@ -67,7 +64,7 @@ int CSMWorld::Data::count (RecordBase::State state, const CollectionBase& collec
} }
CSMWorld::Data::Data (ToUTF8::FromType encoding, bool fsStrict, const Files::PathContainer& dataPaths, CSMWorld::Data::Data (ToUTF8::FromType encoding, bool fsStrict, const Files::PathContainer& dataPaths,
const std::vector<std::string>& archives, const boost::filesystem::path& resDir) const std::vector<std::string>& archives, const std::filesystem::path& resDir)
: mEncoder (encoding), mPathgrids (mCells), mRefs (mCells), : mEncoder (encoding), mPathgrids (mCells), mRefs (mCells),
mReader (nullptr), mDialogue (nullptr), mReaderIndex(1), mReader (nullptr), mDialogue (nullptr), mReaderIndex(1),
mFsStrict(fsStrict), mDataPaths(dataPaths), mArchives(archives) mFsStrict(fsStrict), mDataPaths(dataPaths), mArchives(archives)
@ -91,7 +88,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, bool fsStrict, const Files::Pat
defines[define.first] = define.second; defines[define.first] = define.second;
mResourceSystem->getSceneManager()->getShaderManager().setGlobalDefines(defines); mResourceSystem->getSceneManager()->getShaderManager().setGlobalDefines(defines);
mResourceSystem->getSceneManager()->setShaderPath((resDir / "shaders").string()); mResourceSystem->getSceneManager()->setShaderPath(resDir / "shaders");
int index = 0; int index = 0;
@ -961,7 +958,7 @@ void CSMWorld::Data::merge()
mGlobals.merge(); mGlobals.merge();
} }
int CSMWorld::Data::getTotalRecords (const std::vector<boost::filesystem::path>& files) int CSMWorld::Data::getTotalRecords (const std::vector<std::filesystem::path>& files)
{ {
int records = 0; int records = 0;
@ -969,10 +966,10 @@ int CSMWorld::Data::getTotalRecords (const std::vector<boost::filesystem::path>&
for (unsigned int i = 0; i < files.size(); ++i) for (unsigned int i = 0; i < files.size(); ++i)
{ {
if (!boost::filesystem::exists(files[i])) if (!std::filesystem::exists(files[i]))
continue; continue;
reader->open(files[i].string()); reader->open(files[i]);
records += reader->getRecordCount(); records += reader->getRecordCount();
reader->close(); reader->close();
} }
@ -980,7 +977,7 @@ int CSMWorld::Data::getTotalRecords (const std::vector<boost::filesystem::path>&
return records; return records;
} }
int CSMWorld::Data::startLoading (const boost::filesystem::path& path, bool base, bool project) int CSMWorld::Data::startLoading (const std::filesystem::path& path, bool base, bool project)
{ {
// Don't delete the Reader yet. Some record types store a reference to the Reader to handle on-demand loading // Don't delete the Reader yet. Some record types store a reference to the Reader to handle on-demand loading
std::shared_ptr<ESM::ESMReader> ptr(mReader); std::shared_ptr<ESM::ESMReader> ptr(mReader);
@ -992,9 +989,7 @@ int CSMWorld::Data::startLoading (const boost::filesystem::path& path, bool base
mReader = new ESM::ESMReader; mReader = new ESM::ESMReader;
mReader->setEncoder (&mEncoder); mReader->setEncoder (&mEncoder);
mReader->setIndex((project || !base) ? 0 : mReaderIndex++); mReader->setIndex((project || !base) ? 0 : mReaderIndex++);
mReader->open (path.string()); mReader->open (path);
mContentFileNames.insert(std::make_pair(path.filename().string(), mReader->getIndex()));
mBase = base; mBase = base;
mProject = project; mProject = project;

View file

@ -4,8 +4,6 @@
#include <map> #include <map>
#include <vector> #include <vector>
#include <boost/filesystem/path.hpp>
#include <QObject> #include <QObject>
#include <QModelIndex> #include <QModelIndex>
@ -128,8 +126,6 @@ namespace CSMWorld
std::vector<std::shared_ptr<ESM::ESMReader> > mReaders; std::vector<std::shared_ptr<ESM::ESMReader> > mReaders;
std::map<std::string, int> mContentFileNames;
// not implemented // not implemented
Data (const Data&); Data (const Data&);
Data& operator= (const Data&); Data& operator= (const Data&);
@ -148,7 +144,7 @@ namespace CSMWorld
public: public:
Data (ToUTF8::FromType encoding, bool fsStrict, const Files::PathContainer& dataPaths, Data (ToUTF8::FromType encoding, bool fsStrict, const Files::PathContainer& dataPaths,
const std::vector<std::string>& archives, const boost::filesystem::path& resDir); const std::vector<std::string>& archives, const std::filesystem::path& resDir);
~Data() override; ~Data() override;
@ -290,9 +286,9 @@ namespace CSMWorld
void merge(); void merge();
///< Merge modified into base. ///< Merge modified into base.
int getTotalRecords (const std::vector<boost::filesystem::path>& files); // for better loading bar int getTotalRecords (const std::vector<std::filesystem::path>& files); // for better loading bar
int startLoading (const boost::filesystem::path& path, bool base, bool project); int startLoading (const std::filesystem::path& path, bool base, bool project);
///< Begin merging content of a file into base or modified. ///< Begin merging content of a file into base or modified.
/// ///
/// \param project load project file instead of content file /// \param project load project file instead of content file
@ -318,10 +314,12 @@ namespace CSMWorld
void assetTablesChanged(); void assetTablesChanged();
private slots: public slots:
void assetsChanged(); void assetsChanged();
private slots:
void dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); void dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight);
void rowsChanged (const QModelIndex& parent, int start, int end); void rowsChanged (const QModelIndex& parent, int start, int end);

View file

@ -267,7 +267,7 @@ const char* CSMWorld::DefaultGmsts::Floats[CSMWorld::DefaultGmsts::FloatCount] =
"fWereWolfStrength", "fWereWolfStrength",
"fWereWolfUnarmored", "fWereWolfUnarmored",
"fWereWolfWillPower", "fWereWolfWillPower",
"fWortChanceValue" "fWortChanceValue",
}; };
const char * CSMWorld::DefaultGmsts::Ints[CSMWorld::DefaultGmsts::IntCount] = const char * CSMWorld::DefaultGmsts::Ints[CSMWorld::DefaultGmsts::IntCount] =
@ -360,7 +360,7 @@ const char * CSMWorld::DefaultGmsts::Ints[CSMWorld::DefaultGmsts::IntCount] =
"iWereWolfBounty", "iWereWolfBounty",
"iWereWolfFightMod", "iWereWolfFightMod",
"iWereWolfFleeMod", "iWereWolfFleeMod",
"iWereWolfLevelToAttack" "iWereWolfLevelToAttack",
}; };
const char * CSMWorld::DefaultGmsts::Strings[CSMWorld::DefaultGmsts::StringCount] = const char * CSMWorld::DefaultGmsts::Strings[CSMWorld::DefaultGmsts::StringCount] =
@ -1538,7 +1538,7 @@ const char * CSMWorld::DefaultGmsts::Strings[CSMWorld::DefaultGmsts::StringCount
"sXTimes", "sXTimes",
"sXTimesINT", "sXTimesINT",
"sYes", "sYes",
"sYourGold" "sYourGold",
}; };
const char * CSMWorld::DefaultGmsts::OptionalFloats[CSMWorld::DefaultGmsts::OptionalFloatCount] = const char * CSMWorld::DefaultGmsts::OptionalFloats[CSMWorld::DefaultGmsts::OptionalFloatCount] =
@ -1584,7 +1584,7 @@ const char * CSMWorld::DefaultGmsts::OptionalFloats[CSMWorld::DefaultGmsts::Opti
"fWereWolfSpeed", "fWereWolfSpeed",
"fWereWolfStrength", "fWereWolfStrength",
"fWereWolfUnarmored", "fWereWolfUnarmored",
"fWereWolfWillPower" "fWereWolfWillPower",
}; };
const char * CSMWorld::DefaultGmsts::OptionalInts[CSMWorld::DefaultGmsts::OptionalIntCount] = const char * CSMWorld::DefaultGmsts::OptionalInts[CSMWorld::DefaultGmsts::OptionalIntCount] =
@ -1592,7 +1592,7 @@ const char * CSMWorld::DefaultGmsts::OptionalInts[CSMWorld::DefaultGmsts::Option
"iWereWolfBounty", "iWereWolfBounty",
"iWereWolfFightMod", "iWereWolfFightMod",
"iWereWolfFleeMod", "iWereWolfFleeMod",
"iWereWolfLevelToAttack" "iWereWolfLevelToAttack",
}; };
const char * CSMWorld::DefaultGmsts::OptionalStrings[CSMWorld::DefaultGmsts::OptionalStringCount] = const char * CSMWorld::DefaultGmsts::OptionalStrings[CSMWorld::DefaultGmsts::OptionalStringCount] =
@ -1622,7 +1622,7 @@ const char * CSMWorld::DefaultGmsts::OptionalStrings[CSMWorld::DefaultGmsts::Opt
"sWerewolfAlarmMessage", "sWerewolfAlarmMessage",
"sWerewolfPopup", "sWerewolfPopup",
"sWerewolfRefusal", "sWerewolfRefusal",
"sWerewolfRestMessage" "sWerewolfRestMessage",
}; };
const float CSMWorld::DefaultGmsts::FloatsDefaultValues[CSMWorld::DefaultGmsts::FloatCount] = const float CSMWorld::DefaultGmsts::FloatsDefaultValues[CSMWorld::DefaultGmsts::FloatCount] =
@ -1884,7 +1884,7 @@ const float CSMWorld::DefaultGmsts::FloatsDefaultValues[CSMWorld::DefaultGmsts::
150.0f, // fWereWolfStrength 150.0f, // fWereWolfStrength
100.0f, // fWereWolfUnarmored 100.0f, // fWereWolfUnarmored
1.0f, // fWereWolfWillPower 1.0f, // fWereWolfWillPower
15.0f // fWortChanceValue 15.0f, // fWortChanceValue
}; };
const int CSMWorld::DefaultGmsts::IntsDefaultValues[CSMWorld::DefaultGmsts::IntCount] = const int CSMWorld::DefaultGmsts::IntsDefaultValues[CSMWorld::DefaultGmsts::IntCount] =
@ -1977,7 +1977,7 @@ const int CSMWorld::DefaultGmsts::IntsDefaultValues[CSMWorld::DefaultGmsts::IntC
10000, // iWereWolfBounty 10000, // iWereWolfBounty
100, // iWereWolfFightMod 100, // iWereWolfFightMod
100, // iWereWolfFleeMod 100, // iWereWolfFleeMod
20 // iWereWolfLevelToAttack 20, // iWereWolfLevelToAttack
}; };
const float CSMWorld::DefaultGmsts::FloatLimits[CSMWorld::DefaultGmsts::FloatCount * 2] = const float CSMWorld::DefaultGmsts::FloatLimits[CSMWorld::DefaultGmsts::FloatCount * 2] =
@ -2239,7 +2239,7 @@ const float CSMWorld::DefaultGmsts::FloatLimits[CSMWorld::DefaultGmsts::FloatCou
-FInf, FInf, // fWereWolfStrength -FInf, FInf, // fWereWolfStrength
-FInf, FInf, // fWereWolfUnarmored -FInf, FInf, // fWereWolfUnarmored
-FInf, FInf, // fWereWolfWillPower -FInf, FInf, // fWereWolfWillPower
0, FInf // fWortChanceValue 0, FInf, // fWortChanceValue
}; };
const int CSMWorld::DefaultGmsts::IntLimits[CSMWorld::DefaultGmsts::IntCount * 2] = const int CSMWorld::DefaultGmsts::IntLimits[CSMWorld::DefaultGmsts::IntCount * 2] =
@ -2332,5 +2332,5 @@ const int CSMWorld::DefaultGmsts::IntLimits[CSMWorld::DefaultGmsts::IntCount * 2
IMin, IMax, // iWereWolfBounty IMin, IMax, // iWereWolfBounty
IMin, IMax, // iWereWolfFightMod IMin, IMax, // iWereWolfFightMod
IMin, IMax, // iWereWolfFleeMod IMin, IMax, // iWereWolfFleeMod
IMin, IMax // iWereWolfLevelToAttack IMin, IMax, // iWereWolfLevelToAttack
}; };

View file

@ -26,7 +26,7 @@ void CSMWorld::IdTableProxyModel::updateColumnMap()
{ {
std::vector<int> columns = mFilter->getReferencedColumns(); std::vector<int> columns = mFilter->getReferencedColumns();
for (std::vector<int>::const_iterator iter (columns.begin()); iter!=columns.end(); ++iter) for (std::vector<int>::const_iterator iter (columns.begin()); iter!=columns.end(); ++iter)
mColumnMap.insert (std::make_pair (*iter, mColumnMap.insert (std::make_pair (*iter,
mSourceModel->searchColumnIndex (static_cast<CSMWorld::Columns::ColumnId> (*iter)))); mSourceModel->searchColumnIndex (static_cast<CSMWorld::Columns::ColumnId> (*iter))));
} }
} }
@ -51,7 +51,7 @@ bool CSMWorld::IdTableProxyModel::filterAcceptsRow (int sourceRow, const QModelI
} }
CSMWorld::IdTableProxyModel::IdTableProxyModel (QObject *parent) CSMWorld::IdTableProxyModel::IdTableProxyModel (QObject *parent)
: QSortFilterProxyModel (parent), : QSortFilterProxyModel (parent),
mSourceModel(nullptr) mSourceModel(nullptr)
{ {
setSortCaseSensitivity (Qt::CaseInsensitive); setSortCaseSensitivity (Qt::CaseInsensitive);
@ -69,18 +69,12 @@ void CSMWorld::IdTableProxyModel::setSourceModel(QAbstractItemModel *model)
QSortFilterProxyModel::setSourceModel(model); QSortFilterProxyModel::setSourceModel(model);
mSourceModel = dynamic_cast<IdTableBase *>(sourceModel()); mSourceModel = dynamic_cast<IdTableBase *>(sourceModel());
connect(mSourceModel, connect(mSourceModel, &IdTableBase::rowsInserted,
SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, &IdTableProxyModel::sourceRowsInserted);
this, connect(mSourceModel, &IdTableBase::rowsRemoved,
SLOT(sourceRowsInserted(const QModelIndex &, int, int))); this, &IdTableProxyModel::sourceRowsRemoved);
connect(mSourceModel, connect(mSourceModel, &IdTableBase::dataChanged,
SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, &IdTableProxyModel::sourceDataChanged);
this,
SLOT(sourceRowsRemoved(const QModelIndex &, int, int)));
connect(mSourceModel,
SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)),
this,
SLOT(sourceDataChanged(const QModelIndex &, const QModelIndex &)));
} }
void CSMWorld::IdTableProxyModel::setFilter (const std::shared_ptr<CSMFilter::Node>& filter) void CSMWorld::IdTableProxyModel::setFilter (const std::shared_ptr<CSMFilter::Node>& filter)

View file

@ -98,7 +98,7 @@ const char* CSMWorld::ConstInfoSelectWrapper::FunctionEnumStrings[] =
"Not Race", "Not Race",
"Not Cell", "Not Cell",
"Not Local", "Not Local",
0 nullptr,
}; };
const char* CSMWorld::ConstInfoSelectWrapper::RelationEnumStrings[] = const char* CSMWorld::ConstInfoSelectWrapper::RelationEnumStrings[] =
@ -109,7 +109,7 @@ const char* CSMWorld::ConstInfoSelectWrapper::RelationEnumStrings[] =
">=", ">=",
"<", "<",
"<=", "<=",
0 nullptr,
}; };
const char* CSMWorld::ConstInfoSelectWrapper::ComparisonEnumStrings[] = const char* CSMWorld::ConstInfoSelectWrapper::ComparisonEnumStrings[] =
@ -117,7 +117,7 @@ const char* CSMWorld::ConstInfoSelectWrapper::ComparisonEnumStrings[] =
"Boolean", "Boolean",
"Integer", "Integer",
"Numeric", "Numeric",
0 nullptr,
}; };
// static functions // static functions

View file

@ -15,26 +15,26 @@ CSMWorld::NestedTableProxyModel::NestedTableProxyModel(const QModelIndex& parent
QAbstractProxyModel::setSourceModel(parentModel); QAbstractProxyModel::setSourceModel(parentModel);
connect(mMainModel, SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int)), connect(mMainModel, &IdTree::rowsAboutToBeInserted,
this, SLOT(forwardRowsAboutToInserted(const QModelIndex &, int, int))); this, &NestedTableProxyModel::forwardRowsAboutToInserted);
connect(mMainModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)), connect(mMainModel, &IdTree::rowsInserted,
this, SLOT(forwardRowsInserted(const QModelIndex &, int, int))); this, &NestedTableProxyModel::forwardRowsInserted);
connect(mMainModel, SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int)), connect(mMainModel, &IdTree::rowsAboutToBeRemoved,
this, SLOT(forwardRowsAboutToRemoved(const QModelIndex &, int, int))); this, &NestedTableProxyModel::forwardRowsAboutToRemoved);
connect(mMainModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), connect(mMainModel, &IdTree::rowsRemoved,
this, SLOT(forwardRowsRemoved(const QModelIndex &, int, int))); this, &NestedTableProxyModel::forwardRowsRemoved);
connect(mMainModel, SIGNAL(resetStart(const QString&)), connect(mMainModel, &IdTree::resetStart,
this, SLOT(forwardResetStart(const QString&))); this, &NestedTableProxyModel::forwardResetStart);
connect(mMainModel, SIGNAL(resetEnd(const QString&)), connect(mMainModel, &IdTree::resetEnd,
this, SLOT(forwardResetEnd(const QString&))); this, &NestedTableProxyModel::forwardResetEnd);
connect(mMainModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), connect(mMainModel, &IdTree::dataChanged,
this, SLOT(forwardDataChanged(const QModelIndex &, const QModelIndex &))); this, &NestedTableProxyModel::forwardDataChanged);
} }
QModelIndex CSMWorld::NestedTableProxyModel::mapFromSource(const QModelIndex& sourceIndex) const QModelIndex CSMWorld::NestedTableProxyModel::mapFromSource(const QModelIndex& sourceIndex) const

View file

@ -1756,7 +1756,6 @@ namespace CSMWorld
case ESM::AI_Follow: return 2; case ESM::AI_Follow: return 2;
case ESM::AI_Escort: return 3; case ESM::AI_Escort: return 3;
case ESM::AI_Activate: return 4; case ESM::AI_Activate: return 4;
case ESM::AI_CNDT:
default: return QVariant(); default: return QVariant();
} }
case 1: // wander dist case 1: // wander dist

View file

@ -169,7 +169,9 @@ void CSMWorld::RegionMap::updateRegions (const std::vector<std::string>& regions
{ {
std::vector<std::string> regions2 (regions); std::vector<std::string> regions2 (regions);
std::for_each (regions2.begin(), regions2.end(), Misc::StringUtils::lowerCaseInPlace); for (auto& region2 : regions2) {
Misc::StringUtils::lowerCaseInPlace(region2);
}
std::sort (regions2.begin(), regions2.end()); std::sort (regions2.begin(), regions2.end());
for (std::map<CellCoordinates, CellDescription>::const_iterator iter (mMap.begin()); for (std::map<CellCoordinates, CellDescription>::const_iterator iter (mMap.begin());
@ -280,21 +282,21 @@ CSMWorld::RegionMap::RegionMap (Data& data) : mData (data)
QAbstractItemModel *regions = data.getTableModel (UniversalId (UniversalId::Type_Regions)); QAbstractItemModel *regions = data.getTableModel (UniversalId (UniversalId::Type_Regions));
connect (regions, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)), connect (regions, &QAbstractItemModel::rowsAboutToBeRemoved,
this, SLOT (regionsAboutToBeRemoved (const QModelIndex&, int, int))); this, &RegionMap::regionsAboutToBeRemoved);
connect (regions, SIGNAL (rowsInserted (const QModelIndex&, int, int)), connect (regions, &QAbstractItemModel::rowsInserted,
this, SLOT (regionsInserted (const QModelIndex&, int, int))); this, &RegionMap::regionsInserted);
connect (regions, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)), connect (regions, &QAbstractItemModel::dataChanged,
this, SLOT (regionsChanged (const QModelIndex&, const QModelIndex&))); this, &RegionMap::regionsChanged);
QAbstractItemModel *cells = data.getTableModel (UniversalId (UniversalId::Type_Cells)); QAbstractItemModel *cells = data.getTableModel (UniversalId (UniversalId::Type_Cells));
connect (cells, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)), connect (cells, &QAbstractItemModel::rowsAboutToBeRemoved,
this, SLOT (cellsAboutToBeRemoved (const QModelIndex&, int, int))); this, &RegionMap::cellsAboutToBeRemoved);
connect (cells, SIGNAL (rowsInserted (const QModelIndex&, int, int)), connect (cells, &QAbstractItemModel::rowsInserted,
this, SLOT (cellsInserted (const QModelIndex&, int, int))); this, &RegionMap::cellsInserted);
connect (cells, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)), connect (cells, &QAbstractItemModel::dataChanged,
this, SLOT (cellsChanged (const QModelIndex&, const QModelIndex&))); this, &RegionMap::cellsChanged);
} }
int CSMWorld::RegionMap::rowCount (const QModelIndex& parent) const int CSMWorld::RegionMap::rowCount (const QModelIndex& parent) const

View file

@ -94,7 +94,9 @@ bool CSMWorld::ScriptContext::isId (const std::string& name) const
{ {
mIds = mData.getIds(); mIds = mData.getIds();
std::for_each (mIds.begin(), mIds.end(), &Misc::StringUtils::lowerCaseInPlace); for (auto& id : mIds) {
Misc::StringUtils::lowerCaseInPlace(id);
}
std::sort (mIds.begin(), mIds.end()); std::sort (mIds.begin(), mIds.end());
mIdsUpdated = true; mIdsUpdated = true;

View file

@ -54,7 +54,8 @@ namespace
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Pathgrids, "Pathgrids", ":./pathgrid.png" }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Pathgrids, "Pathgrids", ":./pathgrid.png" },
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_StartScripts, "Start Scripts", ":./start-script.png" }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_StartScripts, "Start Scripts", ":./start-script.png" },
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_MetaDatas, "Metadata", ":./metadata.png" }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_MetaDatas, "Metadata", ":./metadata.png" },
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker // end marker
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 },
}; };
static const TypeData sIdArg[] = static const TypeData sIdArg[] =
@ -120,8 +121,8 @@ namespace
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Pathgrid, "Pathgrid", ":./pathgrid.png" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Pathgrid, "Pathgrid", ":./pathgrid.png" },
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_StartScript, "Start Script", ":./start-script.png" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_StartScript, "Start Script", ":./start-script.png" },
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_MetaData, "Metadata", ":./metadata.png" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_MetaData, "Metadata", ":./metadata.png" },
// end marker
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 },
}; };
static const TypeData sIndexArg[] = static const TypeData sIndexArg[] =
@ -129,7 +130,8 @@ namespace
{ CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_VerificationResults, "Verification Results", ":./menu-verify.png" }, { CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_VerificationResults, "Verification Results", ":./menu-verify.png" },
{ CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_LoadErrorLog, "Load Error Log", ":./error-log.png" }, { CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_LoadErrorLog, "Load Error Log", ":./error-log.png" },
{ CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_Search, "Global Search", ":./menu-search.png" }, { CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_Search, "Global Search", ":./menu-search.png" },
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker // end marker
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 },
}; };
} }

View file

@ -1,13 +1,14 @@
#include "adjusterwidget.hpp" #include "adjusterwidget.hpp"
#include <filesystem>
#include <components/misc/strings/lower.hpp>
#include <boost/filesystem.hpp>
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QLabel> #include <QLabel>
#include <QStyle> #include <QStyle>
#include <components/files/qtconversion.hpp>
#include <components/misc/strings/conversion.hpp>
#include <components/misc/strings/lower.hpp>
CSVDoc::AdjusterWidget::AdjusterWidget (QWidget *parent) CSVDoc::AdjusterWidget::AdjusterWidget (QWidget *parent)
: QWidget (parent), mValid (false), mAction (ContentAction_Undefined) : QWidget (parent), mValid (false), mAction (ContentAction_Undefined)
{ {
@ -33,12 +34,12 @@ void CSVDoc::AdjusterWidget::setAction (ContentAction action)
mAction = action; mAction = action;
} }
void CSVDoc::AdjusterWidget::setLocalData (const boost::filesystem::path& localData) void CSVDoc::AdjusterWidget::setLocalData (const std::filesystem::path& localData)
{ {
mLocalData = localData; mLocalData = localData;
} }
boost::filesystem::path CSVDoc::AdjusterWidget::getPath() const std::filesystem::path CSVDoc::AdjusterWidget::getPath() const
{ {
if (!mValid) if (!mValid)
throw std::logic_error ("invalid content file path"); throw std::logic_error ("invalid content file path");
@ -69,14 +70,14 @@ void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon)
} }
else else
{ {
boost::filesystem::path path (name.toUtf8().data()); auto path = Files::pathFromQString(name);
std::string extension = Misc::StringUtils::lowerCase(path.extension().string()); const auto extension = Misc::StringUtils::lowerCase(path.extension().u8string());
bool isLegacyPath = (extension == ".esm" || bool isLegacyPath = (extension == u8".esm" ||
extension == ".esp"); extension == u8".esp");
bool isFilePathChanged = (path.parent_path().string() != mLocalData.string()); bool isFilePathChanged = (path.parent_path() != mLocalData);
if (isLegacyPath) if (isLegacyPath)
path.replace_extension (addon ? ".omwaddon" : ".omwgame"); path.replace_extension (addon ? ".omwaddon" : ".omwgame");
@ -86,7 +87,7 @@ void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon)
if (!isFilePathChanged && !isLegacyPath) if (!isFilePathChanged && !isLegacyPath)
{ {
// path already points to the local data directory // path already points to the local data directory
message = QString::fromUtf8 (("Will be saved as: " + path.string()).c_str()); message = "Will be saved as: " + Files::pathToQString(path);
mResultPath = path; mResultPath = path;
} }
//in all other cases, ensure the path points to data-local and do an existing file check //in all other cases, ensure the path points to data-local and do an existing file check
@ -96,10 +97,10 @@ void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon)
if (isFilePathChanged) if (isFilePathChanged)
path = mLocalData / path.filename(); path = mLocalData / path.filename();
message = QString::fromUtf8 (("Will be saved as: " + path.string()).c_str()); message = "Will be saved as: " + Files::pathToQString(path);
mResultPath = path; mResultPath = path;
if (boost::filesystem::exists (path)) if (std::filesystem::exists (path))
{ {
/// \todo add an user setting to make this an error. /// \todo add an user setting to make this an error.
message += "<p>A file with the same name already exists. If you continue, it will be overwritten."; message += "<p>A file with the same name already exists. If you continue, it will be overwritten.";

View file

@ -1,10 +1,11 @@
#ifndef CSV_DOC_ADJUSTERWIDGET_H #ifndef CSV_DOC_ADJUSTERWIDGET_H
#define CSV_DOC_ADJUSTERWIDGET_H #define CSV_DOC_ADJUSTERWIDGET_H
#include <boost/filesystem/path.hpp>
#include <QWidget> #include <QWidget>
#include <filesystem>
class QLabel; class QLabel;
namespace CSVDoc namespace CSVDoc
@ -22,11 +23,11 @@ namespace CSVDoc
public: public:
boost::filesystem::path mLocalData; std::filesystem::path mLocalData;
QLabel *mMessage; QLabel *mMessage;
QLabel *mIcon; QLabel *mIcon;
bool mValid; bool mValid;
boost::filesystem::path mResultPath; std::filesystem::path mResultPath;
ContentAction mAction; ContentAction mAction;
bool mDoFilenameCheck; bool mDoFilenameCheck;
@ -34,13 +35,13 @@ namespace CSVDoc
AdjusterWidget (QWidget *parent = nullptr); AdjusterWidget (QWidget *parent = nullptr);
void setLocalData (const boost::filesystem::path& localData); void setLocalData (const std::filesystem::path& localData);
void setAction (ContentAction action); void setAction (ContentAction action);
void setFilenameCheck (bool doCheck); void setFilenameCheck (bool doCheck);
bool isValid() const; bool isValid() const;
boost::filesystem::path getPath() const; std::filesystem::path getPath() const;
///< This function must not be called if there is no valid path. ///< This function must not be called if there is no valid path.
public slots: public slots:

View file

@ -20,7 +20,7 @@ CSVDoc::FileDialog::FileDialog(QWidget *parent) :
mAdjusterWidget = new AdjusterWidget (this); mAdjusterWidget = new AdjusterWidget (this);
} }
void CSVDoc::FileDialog::addFiles(const std::vector<boost::filesystem::path>& dataDirs) void CSVDoc::FileDialog::addFiles(const std::vector<std::filesystem::path>& dataDirs)
{ {
for (auto iter = dataDirs.rbegin(); iter != dataDirs.rend(); ++iter) for (auto iter = dataDirs.rbegin(); iter != dataDirs.rend(); ++iter)
{ {
@ -50,7 +50,7 @@ QStringList CSVDoc::FileDialog::selectedFilePaths()
return filePaths; return filePaths;
} }
void CSVDoc::FileDialog::setLocalData (const boost::filesystem::path& localData) void CSVDoc::FileDialog::setLocalData (const std::filesystem::path& localData)
{ {
mAdjusterWidget->setLocalData (localData); mAdjusterWidget->setLocalData (localData);
} }
@ -80,10 +80,10 @@ void CSVDoc::FileDialog::showDialog (ContentAction action)
if(!mDialogBuilt) if(!mDialogBuilt)
{ {
//connections common to both dialog view flavors //connections common to both dialog view flavors
connect (mSelector, SIGNAL (signalCurrentGamefileIndexChanged (int)), connect (mSelector, &ContentSelectorView::ContentSelector::signalCurrentGamefileIndexChanged,
this, SLOT (slotUpdateAcceptButton (int))); this, qOverload<int>(&FileDialog::slotUpdateAcceptButton));
connect (ui.projectButtonBox, SIGNAL (rejected()), this, SLOT (slotRejected())); connect (ui.projectButtonBox, &QDialogButtonBox::rejected, this, &FileDialog::slotRejected);
mDialogBuilt = true; mDialogBuilt = true;
} }
@ -107,16 +107,16 @@ void CSVDoc::FileDialog::buildNewFileView()
mFileWidget->setType (true); mFileWidget->setType (true);
mFileWidget->extensionLabelIsVisible(true); mFileWidget->extensionLabelIsVisible(true);
connect (mFileWidget, SIGNAL (nameChanged (const QString&, bool)), connect (mFileWidget, &FileWidget::nameChanged,
mAdjusterWidget, SLOT (setName (const QString&, bool))); mAdjusterWidget, &AdjusterWidget::setName);
connect (mFileWidget, SIGNAL (nameChanged(const QString &, bool)), connect (mFileWidget, &FileWidget::nameChanged,
this, SLOT (slotUpdateAcceptButton(const QString &, bool))); this, qOverload<const QString &, bool>(&FileDialog::slotUpdateAcceptButton));
} }
ui.projectGroupBoxLayout->insertWidget (0, mFileWidget); ui.projectGroupBoxLayout->insertWidget (0, mFileWidget);
connect (ui.projectButtonBox, SIGNAL (accepted()), this, SLOT (slotNewFile())); connect (ui.projectButtonBox, &QDialogButtonBox::accepted, this, &FileDialog::slotNewFile);
} }
void CSVDoc::FileDialog::buildOpenFileView() void CSVDoc::FileDialog::buildOpenFileView()
@ -131,9 +131,10 @@ void CSVDoc::FileDialog::buildOpenFileView()
if(!mDialogBuilt) if(!mDialogBuilt)
{ {
connect (mSelector, SIGNAL (signalAddonDataChanged (const QModelIndex&, const QModelIndex&)), this, SLOT (slotAddonDataChanged(const QModelIndex&, const QModelIndex&))); connect (mSelector, &ContentSelectorView::ContentSelector::signalAddonDataChanged,
this, &FileDialog::slotAddonDataChanged);
} }
connect (ui.projectButtonBox, SIGNAL (accepted()), this, SLOT (slotOpenFile())); connect (ui.projectButtonBox, &QDialogButtonBox::accepted, this, &FileDialog::slotOpenFile);
} }
void CSVDoc::FileDialog::slotAddonDataChanged(const QModelIndex &topleft, const QModelIndex &bottomright) void CSVDoc::FileDialog::slotAddonDataChanged(const QModelIndex &topleft, const QModelIndex &bottomright)
@ -181,8 +182,8 @@ QString CSVDoc::FileDialog::filename() const
void CSVDoc::FileDialog::slotRejected() void CSVDoc::FileDialog::slotRejected()
{ {
emit rejected(); emit rejected();
disconnect (ui.projectButtonBox, SIGNAL (accepted()), this, SLOT (slotNewFile())); disconnect (ui.projectButtonBox, &QDialogButtonBox::accepted, this, &FileDialog::slotNewFile);
disconnect (ui.projectButtonBox, SIGNAL (accepted()), this, SLOT (slotOpenFile())); disconnect (ui.projectButtonBox, &QDialogButtonBox::accepted, this, &FileDialog::slotOpenFile);
if(mFileWidget) if(mFileWidget)
{ {
delete mFileWidget; delete mFileWidget;
@ -199,7 +200,7 @@ void CSVDoc::FileDialog::slotNewFile()
delete mFileWidget; delete mFileWidget;
mFileWidget = nullptr; mFileWidget = nullptr;
} }
disconnect (ui.projectButtonBox, SIGNAL (accepted()), this, SLOT (slotNewFile())); disconnect (ui.projectButtonBox, &QDialogButtonBox::accepted, this, &FileDialog::slotNewFile);
close(); close();
} }
@ -210,6 +211,6 @@ void CSVDoc::FileDialog::slotOpenFile()
mAdjusterWidget->setName (file->filePath(), !file->isGameFile()); mAdjusterWidget->setName (file->filePath(), !file->isGameFile());
emit signalOpenFiles (mAdjusterWidget->getPath()); emit signalOpenFiles (mAdjusterWidget->getPath());
disconnect (ui.projectButtonBox, SIGNAL (accepted()), this, SLOT (slotOpenFile())); disconnect (ui.projectButtonBox, &QDialogButtonBox::accepted, this, &FileDialog::slotOpenFile);
close(); close();
} }

View file

@ -6,12 +6,11 @@
#ifndef Q_MOC_RUN #ifndef Q_MOC_RUN
#include <boost/filesystem/path.hpp>
#include "adjusterwidget.hpp" #include "adjusterwidget.hpp"
#ifndef CS_QT_BOOST_FILESYSTEM_PATH_DECLARED #ifndef CS_QT_STD_FILESYSTEM_PATH_DECLARED
#define CS_QT_BOOST_FILESYSTEM_PATH_DECLARED #define CS_QT_STD_FILESYSTEM_PATH_DECLARED
Q_DECLARE_METATYPE (boost::filesystem::path) Q_DECLARE_METATYPE (std::filesystem::path)
#endif #endif
#endif #endif
@ -45,14 +44,14 @@ namespace CSVDoc
explicit FileDialog(QWidget *parent = nullptr); explicit FileDialog(QWidget *parent = nullptr);
void showDialog (ContentAction action); void showDialog (ContentAction action);
void addFiles(const std::vector<boost::filesystem::path>& dataDirs); void addFiles(const std::vector<std::filesystem::path>& dataDirs);
void setEncoding (const QString &encoding); void setEncoding (const QString &encoding);
void clearFiles (); void clearFiles ();
QString filename() const; QString filename() const;
QStringList selectedFilePaths(); QStringList selectedFilePaths();
void setLocalData (const boost::filesystem::path& localData); void setLocalData (const std::filesystem::path& localData);
private: private:
@ -61,8 +60,8 @@ namespace CSVDoc
signals: signals:
void signalOpenFiles (const boost::filesystem::path &path); void signalOpenFiles (const std::filesystem::path &path);
void signalCreateNewFile (const boost::filesystem::path &path); void signalCreateNewFile (const std::filesystem::path &path);
void signalUpdateAcceptButton (bool, int); void signalUpdateAcceptButton (bool, int);

View file

@ -23,7 +23,7 @@ CSVDoc::FileWidget::FileWidget (QWidget *parent) : QWidget (parent), mAddon (fal
layout ->addWidget (mType); layout ->addWidget (mType);
connect (mInput, SIGNAL (textChanged (const QString&)), this, SLOT (textChanged (const QString&))); connect (mInput, &QLineEdit::textChanged, this, &FileWidget::textChanged);
setLayout (layout); setLayout (layout);
} }

View file

@ -36,7 +36,7 @@ void CSVDoc::GlobalDebugProfileMenu::rebuild()
} }
mActions = new QActionGroup (this); mActions = new QActionGroup (this);
connect (mActions, SIGNAL (triggered (QAction *)), this, SLOT (actionTriggered (QAction *))); connect (mActions, &QActionGroup::triggered, this, &GlobalDebugProfileMenu::actionTriggered);
std::sort (ids.begin(), ids.end()); std::sort (ids.begin(), ids.end());
@ -52,14 +52,14 @@ CSVDoc::GlobalDebugProfileMenu::GlobalDebugProfileMenu (CSMWorld::IdTable *debug
{ {
rebuild(); rebuild();
connect (mDebugProfiles, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)), connect (mDebugProfiles, &CSMWorld::IdTable::rowsAboutToBeRemoved,
this, SLOT (profileAboutToBeRemoved (const QModelIndex&, int, int))); this, &GlobalDebugProfileMenu::profileAboutToBeRemoved);
connect (mDebugProfiles, SIGNAL (rowsInserted (const QModelIndex&, int, int)), connect (mDebugProfiles, &CSMWorld::IdTable::rowsInserted,
this, SLOT (profileInserted (const QModelIndex&, int, int))); this, &GlobalDebugProfileMenu::profileInserted);
connect (mDebugProfiles, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)), connect (mDebugProfiles, &CSMWorld::IdTable::dataChanged,
this, SLOT (profileChanged (const QModelIndex&, const QModelIndex&))); this, &GlobalDebugProfileMenu::profileChanged);
} }
void CSVDoc::GlobalDebugProfileMenu::updateActions (bool running) void CSVDoc::GlobalDebugProfileMenu::updateActions (bool running)

View file

@ -8,6 +8,9 @@
#include <QCloseEvent> #include <QCloseEvent>
#include <QListWidget> #include <QListWidget>
#include <components/files/conversion.hpp>
#include <components/files/qtconversion.hpp>
#include "../../model/doc/document.hpp" #include "../../model/doc/document.hpp"
void CSVDoc::LoadingDocument::closeEvent (QCloseEvent *event) void CSVDoc::LoadingDocument::closeEvent (QCloseEvent *event)
@ -19,7 +22,7 @@ void CSVDoc::LoadingDocument::closeEvent (QCloseEvent *event)
CSVDoc::LoadingDocument::LoadingDocument (CSMDoc::Document *document) CSVDoc::LoadingDocument::LoadingDocument (CSMDoc::Document *document)
: mDocument (document), mTotalRecordsLabel (0), mRecordsLabel (0), mAborted (false), mMessages (nullptr), mRecords(0) : mDocument (document), mTotalRecordsLabel (0), mRecordsLabel (0), mAborted (false), mMessages (nullptr), mRecords(0)
{ {
setWindowTitle (QString::fromUtf8((std::string("Opening ") + document->getSavePath().filename().string()).c_str())); setWindowTitle ("Opening " + Files::pathToQString(document->getSavePath().filename()));
setMinimumWidth (400); setMinimumWidth (400);
@ -70,7 +73,7 @@ CSVDoc::LoadingDocument::LoadingDocument (CSMDoc::Document *document)
show(); show();
connect (mButtons, SIGNAL (rejected()), this, SLOT (cancel())); connect (mButtons, &QDialogButtonBox::rejected, this, qOverload<>(&LoadingDocument::cancel));
} }
void CSVDoc::LoadingDocument::nextStage (const std::string& name, int fileRecords) void CSVDoc::LoadingDocument::nextStage (const std::string& name, int fileRecords)
@ -89,16 +92,16 @@ void CSVDoc::LoadingDocument::nextStage (const std::string& name, int fileRecord
mRecords = fileRecords; mRecords = fileRecords;
} }
void CSVDoc::LoadingDocument::nextRecord (int records) void CSVDoc::LoadingDocument::nextRecord(int records)
{ {
if (records <= mRecords) if (records <= mRecords)
{ {
mTotalProgress->setValue (mTotalRecords+records); mTotalProgress->setValue(mTotalRecords + records);
mRecordProgress->setValue(records); mRecordProgress->setValue(records);
mRecordsLabel->setText(QString::fromStdString( mRecordsLabel->setText(
"Records: "+std::to_string(records)+" of "+std::to_string(mRecords))); "Records: " + QString::number(records) + " of " + QString::number(mRecords));
} }
} }
@ -146,10 +149,10 @@ void CSVDoc::Loader::add (CSMDoc::Document *document)
LoadingDocument *loading = new LoadingDocument (document); LoadingDocument *loading = new LoadingDocument (document);
mDocuments.insert (std::make_pair (document, loading)); mDocuments.insert (std::make_pair (document, loading));
connect (loading, SIGNAL (cancel (CSMDoc::Document *)), connect (loading, qOverload<CSMDoc::Document *>(&LoadingDocument::cancel),
this, SIGNAL (cancel (CSMDoc::Document *))); this, &Loader::cancel);
connect (loading, SIGNAL (close (CSMDoc::Document *)), connect (loading, &LoadingDocument::close,
this, SIGNAL (close (CSMDoc::Document *))); this, &Loader::close);
} }
void CSVDoc::Loader::loadingStopped (CSMDoc::Document *document, bool completed, void CSVDoc::Loader::loadingStopped (CSMDoc::Document *document, bool completed,

View file

@ -40,18 +40,17 @@ CSVDoc::NewGameDialogue::NewGameDialogue()
setLayout (layout); setLayout (layout);
connect (mAdjusterWidget, SIGNAL (stateChanged (bool)), this, SLOT (stateChanged (bool))); connect (mAdjusterWidget, &AdjusterWidget::stateChanged, this, &NewGameDialogue::stateChanged);
connect (mCreate, SIGNAL (clicked()), this, SLOT (create())); connect (mCreate, &QPushButton::clicked, this, &NewGameDialogue::create);
connect (cancel, SIGNAL (clicked()), this, SLOT (reject())); connect (cancel, &QPushButton::clicked, this, &NewGameDialogue::reject);
connect (mFileWidget, SIGNAL (nameChanged (const QString&, bool)), connect (mFileWidget, &FileWidget::nameChanged, mAdjusterWidget, &AdjusterWidget::setName);
mAdjusterWidget, SLOT (setName (const QString&, bool)));
QRect scr = QGuiApplication::primaryScreen()->geometry(); QRect scr = QGuiApplication::primaryScreen()->geometry();
QRect rect = geometry(); QRect rect = geometry();
move (scr.center().x() - rect.center().x(), scr.center().y() - rect.center().y()); move (scr.center().x() - rect.center().x(), scr.center().y() - rect.center().y());
} }
void CSVDoc::NewGameDialogue::setLocalData (const boost::filesystem::path& localData) void CSVDoc::NewGameDialogue::setLocalData (const std::filesystem::path& localData)
{ {
mAdjusterWidget->setLocalData (localData); mAdjusterWidget->setLocalData (localData);
} }

View file

@ -1,14 +1,14 @@
#ifndef CSV_DOC_NEWGAME_H #ifndef CSV_DOC_NEWGAME_H
#define CSV_DOC_NEWGAME_H #define CSV_DOC_NEWGAME_H
#include <boost/filesystem/path.hpp>
#include <QDialog> #include <QDialog>
#include <QMetaType> #include <QMetaType>
#ifndef CS_QT_BOOST_FILESYSTEM_PATH_DECLARED #include <filesystem>
#define CS_QT_BOOST_FILESYSTEM_PATH_DECLARED
Q_DECLARE_METATYPE (boost::filesystem::path) #ifndef CS_QT_STD_FILESYSTEM_PATH_DECLARED
#define CS_QT_STD_FILESYSTEM_PATH_DECLARED
Q_DECLARE_METATYPE (std::filesystem::path)
#endif #endif
class QPushButton; class QPushButton;
@ -30,11 +30,11 @@ namespace CSVDoc
NewGameDialogue(); NewGameDialogue();
void setLocalData (const boost::filesystem::path& localData); void setLocalData (const std::filesystem::path& localData);
signals: signals:
void createRequest (const boost::filesystem::path& file); void createRequest (const std::filesystem::path& file);
void cancelCreateGame (); void cancelCreateGame ();

View file

@ -63,7 +63,7 @@ void CSVDoc::Operation::initWidgets()
mLayout->addWidget (mProgressBar); mLayout->addWidget (mProgressBar);
mLayout->addWidget (mAbortButton); mLayout->addWidget (mAbortButton);
connect (mAbortButton, SIGNAL (clicked()), this, SLOT (abortOperation())); connect (mAbortButton, &QPushButton::clicked, this, qOverload<>(&Operation::abortOperation));
} }
void CSVDoc::Operation::setProgress (int current, int max, int threads) void CSVDoc::Operation::setProgress (int current, int max, int threads)

View file

@ -33,7 +33,7 @@ void CSVDoc::Operations::setProgress (int current, int max, int type, int thread
int newCount = oldCount + 1; int newCount = oldCount + 1;
Operation *operation = new Operation (type, this); Operation *operation = new Operation (type, this);
connect (operation, SIGNAL (abortOperation (int)), this, SIGNAL (abortOperation (int))); connect (operation, qOverload<int>(&Operation::abortOperation), this, &Operations::abortOperation);
mLayout->addLayout (operation->getLayout()); mLayout->addLayout (operation->getLayout());
mOperations.push_back (operation); mOperations.push_back (operation);

View file

@ -41,13 +41,13 @@ QWidget *CSVDoc::StartupDialogue::createButtons()
/// \todo add icons /// \todo add icons
QPushButton *loadDocument = addButton ("Edit A Content File", QIcon (":startup/edit-content")); QPushButton *loadDocument = addButton ("Edit A Content File", QIcon (":startup/edit-content"));
connect (loadDocument, SIGNAL (clicked()), this, SIGNAL (loadDocument())); connect (loadDocument, &QPushButton::clicked, this, &StartupDialogue::loadDocument);
QPushButton *createAddon = addButton ("Create A New Addon", QIcon (":startup/create-addon")); QPushButton *createAddon = addButton ("Create A New Addon", QIcon (":startup/create-addon"));
connect (createAddon, SIGNAL (clicked()), this, SIGNAL (createAddon())); connect (createAddon, &QPushButton::clicked, this, &StartupDialogue::createAddon);
QPushButton *createGame = addButton ("Create A New Game", QIcon (":startup/create-game")); QPushButton *createGame = addButton ("Create A New Game", QIcon (":startup/create-game"));
connect (createGame, SIGNAL (clicked()), this, SIGNAL (createGame())); connect (createGame, &QPushButton::clicked, this, &StartupDialogue::createGame);
for (int i=0; i<3; ++i) for (int i=0; i<3; ++i)
mLayout->setColumnMinimumWidth (i, mWidth); mLayout->setColumnMinimumWidth (i, mWidth);
@ -88,7 +88,7 @@ QWidget *CSVDoc::StartupDialogue::createTools()
widget->setLayout (layout); widget->setLayout (layout);
connect (config, SIGNAL (clicked()), this, SIGNAL (editConfig())); connect (config, &QPushButton::clicked, this, &StartupDialogue::editConfig);
return widget; return widget;
} }

View file

@ -30,6 +30,7 @@
#include <components/misc/helpviewer.hpp> #include <components/misc/helpviewer.hpp>
#include <components/version/version.hpp> #include <components/version/version.hpp>
#include <components/files/conversion.hpp>
#include "viewmanager.hpp" #include "viewmanager.hpp"
#include "operations.hpp" #include "operations.hpp"
@ -54,43 +55,43 @@ void CSVDoc::View::setupFileMenu()
QMenu *file = menuBar()->addMenu (tr ("File")); QMenu *file = menuBar()->addMenu (tr ("File"));
QAction* newGame = createMenuEntry("New Game", ":./menu-new-game.png", file, "document-file-newgame"); QAction* newGame = createMenuEntry("New Game", ":./menu-new-game.png", file, "document-file-newgame");
connect (newGame, SIGNAL (triggered()), this, SIGNAL (newGameRequest())); connect (newGame, &QAction::triggered, this, &View::newGameRequest);
QAction* newAddon = createMenuEntry("New Addon", ":./menu-new-addon.png", file, "document-file-newaddon"); QAction* newAddon = createMenuEntry("New Addon", ":./menu-new-addon.png", file, "document-file-newaddon");
connect (newAddon, SIGNAL (triggered()), this, SIGNAL (newAddonRequest())); connect (newAddon, &QAction::triggered, this, &View::newAddonRequest);
QAction* open = createMenuEntry("Open", ":./menu-open.png", file, "document-file-open"); QAction* open = createMenuEntry("Open", ":./menu-open.png", file, "document-file-open");
connect (open, SIGNAL (triggered()), this, SIGNAL (loadDocumentRequest())); connect (open, &QAction::triggered, this, &View::loadDocumentRequest);
QAction* save = createMenuEntry("Save", ":./menu-save.png", file, "document-file-save"); QAction* save = createMenuEntry("Save", ":./menu-save.png", file, "document-file-save");
connect (save, SIGNAL (triggered()), this, SLOT (save())); connect (save, &QAction::triggered, this, &View::save);
mSave = save; mSave = save;
file->addSeparator(); file->addSeparator();
QAction* verify = createMenuEntry("Verify", ":./menu-verify.png", file, "document-file-verify"); QAction* verify = createMenuEntry("Verify", ":./menu-verify.png", file, "document-file-verify");
connect (verify, SIGNAL (triggered()), this, SLOT (verify())); connect (verify, &QAction::triggered, this, &View::verify);
mVerify = verify; mVerify = verify;
QAction* merge = createMenuEntry("Merge", ":./menu-merge.png", file, "document-file-merge"); QAction* merge = createMenuEntry("Merge", ":./menu-merge.png", file, "document-file-merge");
connect (merge, SIGNAL (triggered()), this, SLOT (merge())); connect (merge, &QAction::triggered, this, &View::merge);
mMerge = merge; mMerge = merge;
QAction* loadErrors = createMenuEntry("Error Log", ":./error-log.png", file, "document-file-errorlog"); QAction* loadErrors = createMenuEntry("Error Log", ":./error-log.png", file, "document-file-errorlog");
connect (loadErrors, SIGNAL (triggered()), this, SLOT (loadErrorLog())); connect (loadErrors, &QAction::triggered, this, &View::loadErrorLog);
QAction* meta = createMenuEntry(CSMWorld::UniversalId::Type_MetaDatas, file, "document-file-metadata"); QAction* meta = createMenuEntry(CSMWorld::UniversalId::Type_MetaDatas, file, "document-file-metadata");
connect (meta, SIGNAL (triggered()), this, SLOT (addMetaDataSubView())); connect (meta, &QAction::triggered, this, &View::addMetaDataSubView);
file->addSeparator(); file->addSeparator();
QAction* close = createMenuEntry("Close", ":./menu-close.png", file, "document-file-close"); QAction* close = createMenuEntry("Close", ":./menu-close.png", file, "document-file-close");
connect (close, SIGNAL (triggered()), this, SLOT (close())); connect (close, &QAction::triggered, this, &View::close);
QAction* exit = createMenuEntry("Exit", ":./menu-exit.png", file, "document-file-exit"); QAction* exit = createMenuEntry("Exit", ":./menu-exit.png", file, "document-file-exit");
connect (exit, SIGNAL (triggered()), this, SLOT (exit())); connect (exit, &QAction::triggered, this, &View::exit);
connect (this, SIGNAL(exitApplicationRequest(CSVDoc::View *)), &mViewManager, SLOT(exitApplication(CSVDoc::View *))); connect (this, &View::exitApplicationRequest, &mViewManager, &ViewManager::exitApplication);
} }
namespace namespace
@ -121,21 +122,21 @@ void CSVDoc::View::setupEditMenu()
mUndo = mDocument->getUndoStack().createUndoAction (this, tr("Undo")); mUndo = mDocument->getUndoStack().createUndoAction (this, tr("Undo"));
setupShortcut("document-edit-undo", mUndo); setupShortcut("document-edit-undo", mUndo);
connect(mUndo, SIGNAL (changed ()), this, SLOT (undoActionChanged ())); connect(mUndo, &QAction::changed, this, &View::undoActionChanged);
mUndo->setIcon(QIcon(QString::fromStdString(":./menu-undo.png"))); mUndo->setIcon(QIcon(QString::fromStdString(":./menu-undo.png")));
edit->addAction (mUndo); edit->addAction (mUndo);
mRedo = mDocument->getUndoStack().createRedoAction (this, tr("Redo")); mRedo = mDocument->getUndoStack().createRedoAction (this, tr("Redo"));
connect(mRedo, SIGNAL (changed ()), this, SLOT (redoActionChanged ())); connect(mRedo, &QAction::changed, this, &View::redoActionChanged);
setupShortcut("document-edit-redo", mRedo); setupShortcut("document-edit-redo", mRedo);
mRedo->setIcon(QIcon(QString::fromStdString(":./menu-redo.png"))); mRedo->setIcon(QIcon(QString::fromStdString(":./menu-redo.png")));
edit->addAction (mRedo); edit->addAction (mRedo);
QAction* userSettings = createMenuEntry("Preferences", ":./menu-preferences.png", edit, "document-edit-preferences"); QAction* userSettings = createMenuEntry("Preferences", ":./menu-preferences.png", edit, "document-edit-preferences");
connect (userSettings, SIGNAL (triggered()), this, SIGNAL (editSettingsRequest())); connect (userSettings, &QAction::triggered, this, &View::editSettingsRequest);
QAction* search = createMenuEntry(CSMWorld::UniversalId::Type_Search, edit, "document-edit-search"); QAction* search = createMenuEntry(CSMWorld::UniversalId::Type_Search, edit, "document-edit-search");
connect (search, SIGNAL (triggered()), this, SLOT (addSearchSubView())); connect (search, &QAction::triggered, this, &View::addSearchSubView);
} }
void CSVDoc::View::setupViewMenu() void CSVDoc::View::setupViewMenu()
@ -143,17 +144,17 @@ void CSVDoc::View::setupViewMenu()
QMenu *view = menuBar()->addMenu (tr ("View")); QMenu *view = menuBar()->addMenu (tr ("View"));
QAction *newWindow = createMenuEntry("New View", ":./menu-new-window.png", view, "document-view-newview"); QAction *newWindow = createMenuEntry("New View", ":./menu-new-window.png", view, "document-view-newview");
connect (newWindow, SIGNAL (triggered()), this, SLOT (newView())); connect (newWindow, &QAction::triggered, this, &View::newView);
mShowStatusBar = createMenuEntry("Toggle Status Bar", ":./menu-status-bar.png", view, "document-view-statusbar"); mShowStatusBar = createMenuEntry("Toggle Status Bar", ":./menu-status-bar.png", view, "document-view-statusbar");
connect (mShowStatusBar, SIGNAL (toggled (bool)), this, SLOT (toggleShowStatusBar (bool))); connect (mShowStatusBar, &QAction::toggled, this, &View::toggleShowStatusBar);
mShowStatusBar->setCheckable (true); mShowStatusBar->setCheckable (true);
mShowStatusBar->setChecked (CSMPrefs::get()["Windows"]["show-statusbar"].isTrue()); mShowStatusBar->setChecked (CSMPrefs::get()["Windows"]["show-statusbar"].isTrue());
view->addAction (mShowStatusBar); view->addAction (mShowStatusBar);
QAction *filters = createMenuEntry(CSMWorld::UniversalId::Type_Filters, view, "document-mechanics-filters"); QAction *filters = createMenuEntry(CSMWorld::UniversalId::Type_Filters, view, "document-mechanics-filters");
connect (filters, SIGNAL (triggered()), this, SLOT (addFiltersSubView())); connect (filters, &QAction::triggered, this, &View::addFiltersSubView);
} }
void CSVDoc::View::setupWorldMenu() void CSVDoc::View::setupWorldMenu()
@ -161,32 +162,32 @@ void CSVDoc::View::setupWorldMenu()
QMenu *world = menuBar()->addMenu (tr ("World")); QMenu *world = menuBar()->addMenu (tr ("World"));
QAction* referenceables = createMenuEntry(CSMWorld::UniversalId::Type_Referenceables, world, "document-world-referencables"); QAction* referenceables = createMenuEntry(CSMWorld::UniversalId::Type_Referenceables, world, "document-world-referencables");
connect (referenceables, SIGNAL (triggered()), this, SLOT (addReferenceablesSubView())); connect (referenceables, &QAction::triggered, this, &View::addReferenceablesSubView);
QAction* references = createMenuEntry(CSMWorld::UniversalId::Type_References, world, "document-world-references"); QAction* references = createMenuEntry(CSMWorld::UniversalId::Type_References, world, "document-world-references");
connect (references, SIGNAL (triggered()), this, SLOT (addReferencesSubView())); connect (references, &QAction::triggered, this, &View::addReferencesSubView);
world->addSeparator(); world->addSeparator();
QAction* cells = createMenuEntry(CSMWorld::UniversalId::Type_Cells, world, "document-world-cells"); QAction* cells = createMenuEntry(CSMWorld::UniversalId::Type_Cells, world, "document-world-cells");
connect (cells, SIGNAL (triggered()), this, SLOT (addCellsSubView())); connect (cells, &QAction::triggered, this, &View::addCellsSubView);
QAction *lands = createMenuEntry(CSMWorld::UniversalId::Type_Lands, world, "document-world-lands"); QAction *lands = createMenuEntry(CSMWorld::UniversalId::Type_Lands, world, "document-world-lands");
connect (lands, SIGNAL (triggered()), this, SLOT (addLandsSubView())); connect (lands, &QAction::triggered, this, &View::addLandsSubView);
QAction *landTextures = createMenuEntry(CSMWorld::UniversalId::Type_LandTextures, world, "document-world-landtextures"); QAction *landTextures = createMenuEntry(CSMWorld::UniversalId::Type_LandTextures, world, "document-world-landtextures");
connect (landTextures, SIGNAL (triggered()), this, SLOT (addLandTexturesSubView())); connect (landTextures, &QAction::triggered, this, &View::addLandTexturesSubView);
QAction *grid = createMenuEntry(CSMWorld::UniversalId::Type_Pathgrids, world, "document-world-pathgrid"); QAction *grid = createMenuEntry(CSMWorld::UniversalId::Type_Pathgrids, world, "document-world-pathgrid");
connect (grid, SIGNAL (triggered()), this, SLOT (addPathgridSubView())); connect (grid, &QAction::triggered, this, &View::addPathgridSubView);
world->addSeparator(); world->addSeparator();
QAction* regions = createMenuEntry(CSMWorld::UniversalId::Type_Regions, world, "document-world-regions"); QAction* regions = createMenuEntry(CSMWorld::UniversalId::Type_Regions, world, "document-world-regions");
connect (regions, SIGNAL (triggered()), this, SLOT (addRegionsSubView())); connect (regions, &QAction::triggered, this, &View::addRegionsSubView);
QAction *regionMap = createMenuEntry(CSMWorld::UniversalId::Type_RegionMap, world, "document-world-regionmap"); QAction *regionMap = createMenuEntry(CSMWorld::UniversalId::Type_RegionMap, world, "document-world-regionmap");
connect (regionMap, SIGNAL (triggered()), this, SLOT (addRegionMapSubView())); connect (regionMap, &QAction::triggered, this, &View::addRegionMapSubView);
} }
void CSVDoc::View::setupMechanicsMenu() void CSVDoc::View::setupMechanicsMenu()
@ -194,27 +195,27 @@ void CSVDoc::View::setupMechanicsMenu()
QMenu *mechanics = menuBar()->addMenu (tr ("Mechanics")); QMenu *mechanics = menuBar()->addMenu (tr ("Mechanics"));
QAction* scripts = createMenuEntry(CSMWorld::UniversalId::Type_Scripts, mechanics, "document-mechanics-scripts"); QAction* scripts = createMenuEntry(CSMWorld::UniversalId::Type_Scripts, mechanics, "document-mechanics-scripts");
connect (scripts, SIGNAL (triggered()), this, SLOT (addScriptsSubView())); connect (scripts, &QAction::triggered, this, &View::addScriptsSubView);
QAction* startScripts = createMenuEntry(CSMWorld::UniversalId::Type_StartScripts, mechanics, "document-mechanics-startscripts"); QAction* startScripts = createMenuEntry(CSMWorld::UniversalId::Type_StartScripts, mechanics, "document-mechanics-startscripts");
connect (startScripts, SIGNAL (triggered()), this, SLOT (addStartScriptsSubView())); connect (startScripts, &QAction::triggered, this, &View::addStartScriptsSubView);
QAction* globals = createMenuEntry(CSMWorld::UniversalId::Type_Globals, mechanics, "document-mechanics-globals"); QAction* globals = createMenuEntry(CSMWorld::UniversalId::Type_Globals, mechanics, "document-mechanics-globals");
connect (globals, SIGNAL (triggered()), this, SLOT (addGlobalsSubView())); connect (globals, &QAction::triggered, this, &View::addGlobalsSubView);
QAction* gmsts = createMenuEntry(CSMWorld::UniversalId::Type_Gmsts, mechanics, "document-mechanics-gamesettings"); QAction* gmsts = createMenuEntry(CSMWorld::UniversalId::Type_Gmsts, mechanics, "document-mechanics-gamesettings");
connect (gmsts, SIGNAL (triggered()), this, SLOT (addGmstsSubView())); connect (gmsts, &QAction::triggered, this, &View::addGmstsSubView);
mechanics->addSeparator(); mechanics->addSeparator();
QAction* spells = createMenuEntry(CSMWorld::UniversalId::Type_Spells, mechanics, "document-mechanics-spells"); QAction* spells = createMenuEntry(CSMWorld::UniversalId::Type_Spells, mechanics, "document-mechanics-spells");
connect (spells, SIGNAL (triggered()), this, SLOT (addSpellsSubView())); connect (spells, &QAction::triggered, this, &View::addSpellsSubView);
QAction* enchantments = createMenuEntry(CSMWorld::UniversalId::Type_Enchantments, mechanics, "document-mechanics-enchantments"); QAction* enchantments = createMenuEntry(CSMWorld::UniversalId::Type_Enchantments, mechanics, "document-mechanics-enchantments");
connect (enchantments, SIGNAL (triggered()), this, SLOT (addEnchantmentsSubView())); connect (enchantments, &QAction::triggered, this, &View::addEnchantmentsSubView);
QAction* magicEffects = createMenuEntry(CSMWorld::UniversalId::Type_MagicEffects, mechanics, "document-mechanics-magiceffects"); QAction* magicEffects = createMenuEntry(CSMWorld::UniversalId::Type_MagicEffects, mechanics, "document-mechanics-magiceffects");
connect (magicEffects, SIGNAL (triggered()), this, SLOT (addMagicEffectsSubView())); connect (magicEffects, &QAction::triggered, this, &View::addMagicEffectsSubView);
} }
void CSVDoc::View::setupCharacterMenu() void CSVDoc::View::setupCharacterMenu()
@ -222,38 +223,38 @@ void CSVDoc::View::setupCharacterMenu()
QMenu *characters = menuBar()->addMenu (tr ("Characters")); QMenu *characters = menuBar()->addMenu (tr ("Characters"));
QAction* skills = createMenuEntry(CSMWorld::UniversalId::Type_Skills, characters, "document-character-skills"); QAction* skills = createMenuEntry(CSMWorld::UniversalId::Type_Skills, characters, "document-character-skills");
connect (skills, SIGNAL (triggered()), this, SLOT (addSkillsSubView())); connect (skills, &QAction::triggered, this, &View::addSkillsSubView);
QAction* classes = createMenuEntry(CSMWorld::UniversalId::Type_Classes, characters, "document-character-classes"); QAction* classes = createMenuEntry(CSMWorld::UniversalId::Type_Classes, characters, "document-character-classes");
connect (classes, SIGNAL (triggered()), this, SLOT (addClassesSubView())); connect (classes, &QAction::triggered, this, &View::addClassesSubView);
QAction* factions = createMenuEntry(CSMWorld::UniversalId::Type_Faction, characters, "document-character-factions"); QAction* factions = createMenuEntry(CSMWorld::UniversalId::Type_Faction, characters, "document-character-factions");
connect (factions, SIGNAL (triggered()), this, SLOT (addFactionsSubView())); connect (factions, &QAction::triggered, this, &View::addFactionsSubView);
QAction* races = createMenuEntry(CSMWorld::UniversalId::Type_Races, characters, "document-character-races"); QAction* races = createMenuEntry(CSMWorld::UniversalId::Type_Races, characters, "document-character-races");
connect (races, SIGNAL (triggered()), this, SLOT (addRacesSubView())); connect (races, &QAction::triggered, this, &View::addRacesSubView);
QAction* birthsigns = createMenuEntry(CSMWorld::UniversalId::Type_Birthsigns, characters, "document-character-birthsigns"); QAction* birthsigns = createMenuEntry(CSMWorld::UniversalId::Type_Birthsigns, characters, "document-character-birthsigns");
connect (birthsigns, SIGNAL (triggered()), this, SLOT (addBirthsignsSubView())); connect (birthsigns, &QAction::triggered, this, &View::addBirthsignsSubView);
QAction* bodyParts = createMenuEntry(CSMWorld::UniversalId::Type_BodyParts, characters, "document-character-bodyparts"); QAction* bodyParts = createMenuEntry(CSMWorld::UniversalId::Type_BodyParts, characters, "document-character-bodyparts");
connect (bodyParts, SIGNAL (triggered()), this, SLOT (addBodyPartsSubView())); connect (bodyParts, &QAction::triggered, this, &View::addBodyPartsSubView);
characters->addSeparator(); characters->addSeparator();
QAction* topics = createMenuEntry(CSMWorld::UniversalId::Type_Topics, characters, "document-character-topics"); QAction* topics = createMenuEntry(CSMWorld::UniversalId::Type_Topics, characters, "document-character-topics");
connect (topics, SIGNAL (triggered()), this, SLOT (addTopicsSubView())); connect (topics, &QAction::triggered, this, &View::addTopicsSubView);
QAction* topicInfos = createMenuEntry(CSMWorld::UniversalId::Type_TopicInfos, characters, "document-character-topicinfos"); QAction* topicInfos = createMenuEntry(CSMWorld::UniversalId::Type_TopicInfos, characters, "document-character-topicinfos");
connect (topicInfos, SIGNAL (triggered()), this, SLOT (addTopicInfosSubView())); connect (topicInfos, &QAction::triggered, this, &View::addTopicInfosSubView);
characters->addSeparator(); characters->addSeparator();
QAction* journals = createMenuEntry(CSMWorld::UniversalId::Type_Journals, characters, "document-character-journals"); QAction* journals = createMenuEntry(CSMWorld::UniversalId::Type_Journals, characters, "document-character-journals");
connect (journals, SIGNAL (triggered()), this, SLOT (addJournalsSubView())); connect (journals, &QAction::triggered, this, &View::addJournalsSubView);
QAction* journalInfos = createMenuEntry(CSMWorld::UniversalId::Type_JournalInfos, characters, "document-character-journalinfos"); QAction* journalInfos = createMenuEntry(CSMWorld::UniversalId::Type_JournalInfos, characters, "document-character-journalinfos");
connect (journalInfos, SIGNAL (triggered()), this, SLOT (addJournalInfosSubView())); connect (journalInfos, &QAction::triggered, this, &View::addJournalInfosSubView);
} }
void CSVDoc::View::setupAssetsMenu() void CSVDoc::View::setupAssetsMenu()
@ -261,35 +262,35 @@ void CSVDoc::View::setupAssetsMenu()
QMenu *assets = menuBar()->addMenu (tr ("Assets")); QMenu *assets = menuBar()->addMenu (tr ("Assets"));
QAction* reload = createMenuEntry("Reload", ":./menu-reload.png", assets, "document-assets-reload"); QAction* reload = createMenuEntry("Reload", ":./menu-reload.png", assets, "document-assets-reload");
connect (reload, SIGNAL (triggered()), &mDocument->getData(), SLOT (assetsChanged())); connect (reload, &QAction::triggered, &mDocument->getData(), &CSMWorld::Data::assetsChanged);
assets->addSeparator(); assets->addSeparator();
QAction* sounds = createMenuEntry(CSMWorld::UniversalId::Type_Sounds, assets, "document-assets-sounds"); QAction* sounds = createMenuEntry(CSMWorld::UniversalId::Type_Sounds, assets, "document-assets-sounds");
connect (sounds, SIGNAL (triggered()), this, SLOT (addSoundsSubView())); connect (sounds, &QAction::triggered, this, &View::addSoundsSubView);
QAction* soundGens = createMenuEntry(CSMWorld::UniversalId::Type_SoundGens, assets, "document-assets-soundgens"); QAction* soundGens = createMenuEntry(CSMWorld::UniversalId::Type_SoundGens, assets, "document-assets-soundgens");
connect (soundGens, SIGNAL (triggered()), this, SLOT (addSoundGensSubView())); connect (soundGens, &QAction::triggered, this, &View::addSoundGensSubView);
assets->addSeparator(); // resources follow here assets->addSeparator(); // resources follow here
QAction* meshes = createMenuEntry(CSMWorld::UniversalId::Type_Meshes, assets, "document-assets-meshes"); QAction* meshes = createMenuEntry(CSMWorld::UniversalId::Type_Meshes, assets, "document-assets-meshes");
connect (meshes, SIGNAL (triggered()), this, SLOT (addMeshesSubView())); connect (meshes, &QAction::triggered, this, &View::addMeshesSubView);
QAction* icons = createMenuEntry(CSMWorld::UniversalId::Type_Icons, assets, "document-assets-icons"); QAction* icons = createMenuEntry(CSMWorld::UniversalId::Type_Icons, assets, "document-assets-icons");
connect (icons, SIGNAL (triggered()), this, SLOT (addIconsSubView())); connect (icons, &QAction::triggered, this, &View::addIconsSubView);
QAction* musics = createMenuEntry(CSMWorld::UniversalId::Type_Musics, assets, "document-assets-musics"); QAction* musics = createMenuEntry(CSMWorld::UniversalId::Type_Musics, assets, "document-assets-musics");
connect (musics, SIGNAL (triggered()), this, SLOT (addMusicsSubView())); connect (musics, &QAction::triggered, this, &View::addMusicsSubView);
QAction* soundFiles = createMenuEntry(CSMWorld::UniversalId::Type_SoundsRes, assets, "document-assets-soundres"); QAction* soundFiles = createMenuEntry(CSMWorld::UniversalId::Type_SoundsRes, assets, "document-assets-soundres");
connect (soundFiles, SIGNAL (triggered()), this, SLOT (addSoundsResSubView())); connect (soundFiles, &QAction::triggered, this, &View::addSoundsResSubView);
QAction* textures = createMenuEntry(CSMWorld::UniversalId::Type_Textures, assets, "document-assets-textures"); QAction* textures = createMenuEntry(CSMWorld::UniversalId::Type_Textures, assets, "document-assets-textures");
connect (textures, SIGNAL (triggered()), this, SLOT (addTexturesSubView())); connect (textures, &QAction::triggered, this, &View::addTexturesSubView);
QAction* videos = createMenuEntry(CSMWorld::UniversalId::Type_Videos, assets, "document-assets-videos"); QAction* videos = createMenuEntry(CSMWorld::UniversalId::Type_Videos, assets, "document-assets-videos");
connect (videos, SIGNAL (triggered()), this, SLOT (addVideosSubView())); connect (videos, &QAction::triggered, this, &View::addVideosSubView);
} }
void CSVDoc::View::setupDebugMenu() void CSVDoc::View::setupDebugMenu()
@ -297,7 +298,7 @@ void CSVDoc::View::setupDebugMenu()
QMenu *debug = menuBar()->addMenu (tr ("Debug")); QMenu *debug = menuBar()->addMenu (tr ("Debug"));
QAction* profiles = createMenuEntry(CSMWorld::UniversalId::Type_DebugProfiles, debug, "document-debug-profiles"); QAction* profiles = createMenuEntry(CSMWorld::UniversalId::Type_DebugProfiles, debug, "document-debug-profiles");
connect (profiles, SIGNAL (triggered()), this, SLOT (addDebugProfilesSubView())); connect (profiles, &QAction::triggered, this, &View::addDebugProfilesSubView);
debug->addSeparator(); debug->addSeparator();
@ -305,8 +306,8 @@ void CSVDoc::View::setupDebugMenu()
&dynamic_cast<CSMWorld::IdTable&> (*mDocument->getData().getTableModel ( &dynamic_cast<CSMWorld::IdTable&> (*mDocument->getData().getTableModel (
CSMWorld::UniversalId::Type_DebugProfiles)), this); CSMWorld::UniversalId::Type_DebugProfiles)), this);
connect (mGlobalDebugProfileMenu, SIGNAL (triggered (const std::string&)), connect (mGlobalDebugProfileMenu, &GlobalDebugProfileMenu::triggered,
this, SLOT (run (const std::string&))); this, [this](const std::string &profile){ this->run(profile, ""); });
QAction *runDebug = debug->addMenu (mGlobalDebugProfileMenu); QAction *runDebug = debug->addMenu (mGlobalDebugProfileMenu);
runDebug->setText (tr ("Run OpenMW")); runDebug->setText (tr ("Run OpenMW"));
@ -314,11 +315,11 @@ void CSVDoc::View::setupDebugMenu()
runDebug->setIcon(QIcon(QString::fromStdString(":./run-openmw.png"))); runDebug->setIcon(QIcon(QString::fromStdString(":./run-openmw.png")));
QAction* stopDebug = createMenuEntry("Stop OpenMW", ":./stop-openmw.png", debug, "document-debug-shutdown"); QAction* stopDebug = createMenuEntry("Stop OpenMW", ":./stop-openmw.png", debug, "document-debug-shutdown");
connect (stopDebug, SIGNAL (triggered()), this, SLOT (stop())); connect (stopDebug, &QAction::triggered, this, &View::stop);
mStopDebug = stopDebug; mStopDebug = stopDebug;
QAction* runLog = createMenuEntry(CSMWorld::UniversalId::Type_RunLog, debug, "document-debug-runlog"); QAction* runLog = createMenuEntry(CSMWorld::UniversalId::Type_RunLog, debug, "document-debug-runlog");
connect (runLog, SIGNAL (triggered()), this, SLOT (addRunLogSubView())); connect (runLog, &QAction::triggered, this, &View::addRunLogSubView);
} }
void CSVDoc::View::setupHelpMenu() void CSVDoc::View::setupHelpMenu()
@ -326,16 +327,16 @@ void CSVDoc::View::setupHelpMenu()
QMenu *help = menuBar()->addMenu (tr ("Help")); QMenu *help = menuBar()->addMenu (tr ("Help"));
QAction* helpInfo = createMenuEntry("Help", ":/info.png", help, "document-help-help"); QAction* helpInfo = createMenuEntry("Help", ":/info.png", help, "document-help-help");
connect (helpInfo, SIGNAL (triggered()), this, SLOT (openHelp())); connect (helpInfo, &QAction::triggered, this, &View::openHelp);
QAction* tutorial = createMenuEntry("Tutorial", ":/info.png", help, "document-help-tutorial"); QAction* tutorial = createMenuEntry("Tutorial", ":/info.png", help, "document-help-tutorial");
connect (tutorial, SIGNAL (triggered()), this, SLOT (tutorial())); connect (tutorial, &QAction::triggered, this, &View::tutorial);
QAction* about = createMenuEntry("About OpenMW-CS", ":./info.png", help, "document-help-about"); QAction* about = createMenuEntry("About OpenMW-CS", ":./info.png", help, "document-help-about");
connect (about, SIGNAL (triggered()), this, SLOT (infoAbout())); connect (about, &QAction::triggered, this, &View::infoAbout);
QAction* aboutQt = createMenuEntry("About Qt", ":./qt.png", help, "document-help-qt"); QAction* aboutQt = createMenuEntry("About Qt", ":./qt.png", help, "document-help-qt");
connect (aboutQt, SIGNAL (triggered()), this, SLOT (infoAboutQt())); connect (aboutQt, &QAction::triggered, this, &View::infoAboutQt);
} }
QAction* CSVDoc::View::createMenuEntry(CSMWorld::UniversalId::Type type, QMenu* menu, const char* shortcutName) QAction* CSVDoc::View::createMenuEntry(CSMWorld::UniversalId::Type type, QMenu* menu, const char* shortcutName)
@ -387,7 +388,7 @@ void CSVDoc::View::updateTitle()
{ {
std::ostringstream stream; std::ostringstream stream;
stream << mDocument->getSavePath().filename().string(); stream << Files::pathToUnicodeString(mDocument->getSavePath().filename());
if (mDocument->getState() & CSMDoc::State_Modified) if (mDocument->getState() & CSMDoc::State_Modified)
stream << " *"; stream << " *";
@ -501,10 +502,10 @@ CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int to
mSubViewFactory.add (CSMWorld::UniversalId::Type_RunLog, new SubViewFactory<RunLogSubView>); mSubViewFactory.add (CSMWorld::UniversalId::Type_RunLog, new SubViewFactory<RunLogSubView>);
connect (mOperations, SIGNAL (abortOperation (int)), this, SLOT (abortOperation (int))); connect (mOperations, &Operations::abortOperation, this, &View::abortOperation);
connect (&CSMPrefs::State::get(), SIGNAL (settingChanged (const CSMPrefs::Setting *)), connect (&CSMPrefs::State::get(), &CSMPrefs::State::settingChanged,
this, SLOT (settingChanged (const CSMPrefs::Setting *))); this, &View::settingChanged);
} }
CSVDoc::View::~View() CSVDoc::View::~View()
@ -537,7 +538,8 @@ void CSVDoc::View::updateDocumentState()
{ {
CSMDoc::State_Saving, CSMDoc::State_Verifying, CSMDoc::State_Searching, CSMDoc::State_Saving, CSMDoc::State_Verifying, CSMDoc::State_Searching,
CSMDoc::State_Merging, CSMDoc::State_Merging,
-1 // end marker // end marker
-1,
}; };
int state = mDocument->getState() ; int state = mDocument->getState() ;
@ -584,8 +586,8 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::strin
} }
if (mScroll) if (mScroll)
QObject::connect(mScroll->horizontalScrollBar(), QObject::connect(mScroll->horizontalScrollBar(), &QScrollBar::rangeChanged,
SIGNAL(rangeChanged(int,int)), this, SLOT(moveScrollBarToEnd(int,int))); this, &View::moveScrollBarToEnd);
// User setting for limiting the number of sub views per top level view. // User setting for limiting the number of sub views per top level view.
// Automatically open a new top level view if this number is exceeded // Automatically open a new top level view if this number is exceeded
@ -637,28 +639,27 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::strin
updateSubViewIndices(); updateSubViewIndices();
connect (view, SIGNAL (focusId (const CSMWorld::UniversalId&, const std::string&)), this, connect (view, &SubView::focusId, this, &View::addSubView);
SLOT (addSubView (const CSMWorld::UniversalId&, const std::string&)));
connect (view, SIGNAL (closeRequest (SubView *)), this, SLOT (closeRequest (SubView *))); connect (view, qOverload<SubView *>(&SubView::closeRequest),
this, &View::closeRequest);
connect (view, SIGNAL (updateTitle()), this, SLOT (updateTitle())); connect (view, &SubView::updateTitle, this, &View::updateTitle);
connect (view, SIGNAL (updateSubViewIndices (SubView *)), connect (view, &SubView::updateSubViewIndices, this, &View::updateSubViewIndices);
this, SLOT (updateSubViewIndices (SubView *)));
CSVWorld::TableSubView* tableView = dynamic_cast<CSVWorld::TableSubView*>(view); CSVWorld::TableSubView* tableView = dynamic_cast<CSVWorld::TableSubView*>(view);
if (tableView) if (tableView)
{ {
connect (this, SIGNAL (requestFocus (const std::string&)), connect (this, &View::requestFocus,
tableView, SLOT (requestFocus (const std::string&))); tableView, &CSVWorld::TableSubView::requestFocus);
} }
CSVWorld::SceneSubView* sceneView = dynamic_cast<CSVWorld::SceneSubView*>(view); CSVWorld::SceneSubView* sceneView = dynamic_cast<CSVWorld::SceneSubView*>(view);
if (sceneView) if (sceneView)
{ {
connect(sceneView, SIGNAL(requestFocus(const std::string&)), connect(sceneView, &CSVWorld::SceneSubView::requestFocus,
this, SLOT(onRequestFocus(const std::string&))); this, &View::onRequestFocus);
} }
if (CSMPrefs::State::get()["ID Tables"]["subview-new-window"].isTrue()) if (CSMPrefs::State::get()["ID Tables"]["subview-new-window"].isTrue())
@ -684,8 +685,8 @@ void CSVDoc::View::moveScrollBarToEnd(int min, int max)
{ {
mScroll->horizontalScrollBar()->setValue(max); mScroll->horizontalScrollBar()->setValue(max);
QObject::disconnect(mScroll->horizontalScrollBar(), QObject::disconnect(mScroll->horizontalScrollBar(), &QScrollBar::rangeChanged,
SIGNAL(rangeChanged(int,int)), this, SLOT(moveScrollBarToEnd(int,int))); this, &View::moveScrollBarToEnd);
} }
} }
@ -748,7 +749,7 @@ void CSVDoc::View::tutorial()
void CSVDoc::View::infoAbout() void CSVDoc::View::infoAbout()
{ {
// Get current OpenMW version // Get current OpenMW version
QString versionInfo = (Version::getOpenmwVersionDescription(mDocument->getResourceDir().string())+ QString versionInfo = (Version::getOpenmwVersionDescription(mDocument->getResourceDir())+
#if defined(__x86_64__) || defined(_M_X64) #if defined(__x86_64__) || defined(_M_X64)
" (64-bit)").c_str(); " (64-bit)").c_str();
#else #else

View file

@ -7,8 +7,10 @@
#include <QMessageBox> #include <QMessageBox>
#include <QPushButton> #include <QPushButton>
#include "../../model/doc/documentmanager.hpp" #include <components/files/qtconversion.hpp>
#include "../../model/doc/document.hpp" #include "../../model/doc/document.hpp"
#include "../../model/doc/documentmanager.hpp"
#include "../../model/doc/state.hpp" #include "../../model/doc/state.hpp"
#include "../../model/world/columns.hpp" #include "../../model/world/columns.hpp"
@ -110,39 +112,33 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager)
{ CSMWorld::ColumnBase::Display_BookType, CSMWorld::Columns::ColumnId_BookType, false }, { CSMWorld::ColumnBase::Display_BookType, CSMWorld::Columns::ColumnId_BookType, false },
{ CSMWorld::ColumnBase::Display_BloodType, CSMWorld::Columns::ColumnId_BloodType, false }, { CSMWorld::ColumnBase::Display_BloodType, CSMWorld::Columns::ColumnId_BloodType, false },
{ CSMWorld::ColumnBase::Display_EmitterType, CSMWorld::Columns::ColumnId_EmitterType, false }, { CSMWorld::ColumnBase::Display_EmitterType, CSMWorld::Columns::ColumnId_EmitterType, false },
{ CSMWorld::ColumnBase::Display_GenderNpc, CSMWorld::Columns::ColumnId_Gender, false } { CSMWorld::ColumnBase::Display_GenderNpc, CSMWorld::Columns::ColumnId_Gender, false },
}; };
for (std::size_t i=0; i<sizeof (sMapping)/sizeof (Mapping); ++i) for (std::size_t i=0; i<sizeof (sMapping)/sizeof (Mapping); ++i)
mDelegateFactories->add (sMapping[i].mDisplay, new CSVWorld::EnumDelegateFactory ( mDelegateFactories->add (sMapping[i].mDisplay, new CSVWorld::EnumDelegateFactory (
CSMWorld::Columns::getEnums (sMapping[i].mColumnId), sMapping[i].mAllowNone)); CSMWorld::Columns::getEnums (sMapping[i].mColumnId), sMapping[i].mAllowNone));
connect (&mDocumentManager, SIGNAL (loadRequest (CSMDoc::Document *)), connect (&mDocumentManager, &CSMDoc::DocumentManager::loadRequest,
&mLoader, SLOT (add (CSMDoc::Document *))); &mLoader, &Loader::add);
connect ( connect (&mDocumentManager, &CSMDoc::DocumentManager::loadingStopped,
&mDocumentManager, SIGNAL (loadingStopped (CSMDoc::Document *, bool, const std::string&)), &mLoader, &Loader::loadingStopped);
&mLoader, SLOT (loadingStopped (CSMDoc::Document *, bool, const std::string&)));
connect ( connect (&mDocumentManager, &CSMDoc::DocumentManager::nextStage,
&mDocumentManager, SIGNAL (nextStage (CSMDoc::Document *, const std::string&, int)), &mLoader, &Loader::nextStage);
&mLoader, SLOT (nextStage (CSMDoc::Document *, const std::string&, int)));
connect ( connect (&mDocumentManager, &CSMDoc::DocumentManager::nextRecord,
&mDocumentManager, SIGNAL (nextRecord (CSMDoc::Document *, int)), &mLoader, &Loader::nextRecord);
&mLoader, SLOT (nextRecord (CSMDoc::Document *, int)));
connect ( connect (&mDocumentManager, &CSMDoc::DocumentManager::loadMessage,
&mDocumentManager, SIGNAL (loadMessage (CSMDoc::Document *, const std::string&)), &mLoader, &Loader::loadMessage);
&mLoader, SLOT (loadMessage (CSMDoc::Document *, const std::string&)));
connect ( connect (&mLoader, &Loader::cancel,
&mLoader, SIGNAL (cancel (CSMDoc::Document *)), &mDocumentManager, &CSMDoc::DocumentManager::cancelLoading);
&mDocumentManager, SIGNAL (cancelLoading (CSMDoc::Document *)));
connect ( connect (&mLoader, &Loader::close,
&mLoader, SIGNAL (close (CSMDoc::Document *)), &mDocumentManager, &CSMDoc::DocumentManager::removeDocument);
&mDocumentManager, SLOT (removeDocument (CSMDoc::Document *)));
} }
CSVDoc::ViewManager::~ViewManager() CSVDoc::ViewManager::~ViewManager()
@ -158,11 +154,11 @@ CSVDoc::View *CSVDoc::ViewManager::addView (CSMDoc::Document *document)
if (countViews (document)==0) if (countViews (document)==0)
{ {
// new document // new document
connect (document, SIGNAL (stateChanged (int, CSMDoc::Document *)), connect (document, &CSMDoc::Document::stateChanged,
this, SLOT (documentStateChanged (int, CSMDoc::Document *))); this, &ViewManager::documentStateChanged);
connect (document, SIGNAL (progress (int, int, int, int, CSMDoc::Document *)), connect (document, qOverload<int,int,int,int,CSMDoc::Document*>(&CSMDoc::Document::progress),
this, SLOT (progress (int, int, int, int, CSMDoc::Document *))); this, &ViewManager::progress);
} }
View *view = new View (*this, document, countViews (document)+1); View *view = new View (*this, document, countViews (document)+1);
@ -172,11 +168,11 @@ CSVDoc::View *CSVDoc::ViewManager::addView (CSMDoc::Document *document)
view->toggleStatusBar (CSMPrefs::get()["Windows"]["show-statusbar"].isTrue()); view->toggleStatusBar (CSMPrefs::get()["Windows"]["show-statusbar"].isTrue());
view->show(); view->show();
connect (view, SIGNAL (newGameRequest ()), this, SIGNAL (newGameRequest())); connect (view, &View::newGameRequest, this, &ViewManager::newGameRequest);
connect (view, SIGNAL (newAddonRequest ()), this, SIGNAL (newAddonRequest())); connect (view, &View::newAddonRequest, this, &ViewManager::newAddonRequest);
connect (view, SIGNAL (loadDocumentRequest ()), this, SIGNAL (loadDocumentRequest())); connect (view, &View::loadDocumentRequest, this, &ViewManager::loadDocumentRequest);
connect (view, SIGNAL (editSettingsRequest()), this, SIGNAL (editSettingsRequest())); connect (view, &View::editSettingsRequest, this, &ViewManager::editSettingsRequest);
connect (view, SIGNAL (mergeDocument (CSMDoc::Document *)), this, SIGNAL (mergeDocument (CSMDoc::Document *))); connect (view, &View::mergeDocument, this, &ViewManager::mergeDocument);
updateIndices(); updateIndices();
@ -267,7 +263,7 @@ bool CSVDoc::ViewManager::showModifiedDocumentMessageBox (CSVDoc::View *view)
QMessageBox messageBox(view); QMessageBox messageBox(view);
CSMDoc::Document *document = view->getDocument(); CSMDoc::Document *document = view->getDocument();
messageBox.setWindowTitle (QString::fromUtf8(document->getSavePath().filename().string().c_str())); messageBox.setWindowTitle (Files::pathToQString(document->getSavePath().filename()));
messageBox.setText ("The document has been modified."); messageBox.setText ("The document has been modified.");
messageBox.setInformativeText ("Do you want to save your changes?"); messageBox.setInformativeText ("Do you want to save your changes?");
messageBox.setStandardButtons (QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); messageBox.setStandardButtons (QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
@ -278,9 +274,9 @@ bool CSVDoc::ViewManager::showModifiedDocumentMessageBox (CSVDoc::View *view)
bool retVal = true; bool retVal = true;
connect (this, SIGNAL (closeMessageBox()), &messageBox, SLOT (close())); connect (this, &ViewManager::closeMessageBox, &messageBox, &QMessageBox::close);
connect (document, SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onExitWarningHandler(int, CSMDoc::Document *))); connect (document, &CSMDoc::Document::stateChanged, this, &ViewManager::onExitWarningHandler);
mUserWarned = true; mUserWarned = true;
int response = messageBox.exec(); int response = messageBox.exec();
@ -297,13 +293,15 @@ bool CSVDoc::ViewManager::showModifiedDocumentMessageBox (CSVDoc::View *view)
case QMessageBox::Discard: case QMessageBox::Discard:
disconnect (document, SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onExitWarningHandler(int, CSMDoc::Document *))); disconnect (document, &CSMDoc::Document::stateChanged,
this, &ViewManager::onExitWarningHandler);
break; break;
case QMessageBox::Cancel: case QMessageBox::Cancel:
//disconnect to prevent unintended view closures //disconnect to prevent unintended view closures
disconnect (document, SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onExitWarningHandler(int, CSMDoc::Document *))); disconnect (document, &CSMDoc::Document::stateChanged,
this, &ViewManager::onExitWarningHandler);
retVal = false; retVal = false;
break; break;
@ -332,8 +330,8 @@ bool CSVDoc::ViewManager::showSaveInProgressMessageBox (CSVDoc::View *view)
bool retVal = true; bool retVal = true;
//Connections shut down message box if operation ends before user makes a decision. //Connections shut down message box if operation ends before user makes a decision.
connect (document, SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onExitWarningHandler(int, CSMDoc::Document *))); connect (document, &CSMDoc::Document::stateChanged, this, &ViewManager::onExitWarningHandler);
connect (this, SIGNAL (closeMessageBox()), &messageBox, SLOT (close())); connect (this, &ViewManager::closeMessageBox, &messageBox, &QMessageBox::close);
//set / clear the user warned flag to indicate whether or not the message box is currently active. //set / clear the user warned flag to indicate whether or not the message box is currently active.
mUserWarned = true; mUserWarned = true;
@ -351,7 +349,7 @@ bool CSVDoc::ViewManager::showSaveInProgressMessageBox (CSVDoc::View *view)
else if (messageBox.clickedButton() == closeButton) else if (messageBox.clickedButton() == closeButton)
{ {
//disconnect to avoid segmentation fault //disconnect to avoid segmentation fault
disconnect (document, SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onExitWarningHandler(int, CSMDoc::Document *))); disconnect (document, &CSMDoc::Document::stateChanged, this, &ViewManager::onExitWarningHandler);
view->abortOperation(CSMDoc::State_Saving); view->abortOperation(CSMDoc::State_Saving);
mExitOnSaveStateChange = true; mExitOnSaveStateChange = true;
@ -362,7 +360,7 @@ bool CSVDoc::ViewManager::showSaveInProgressMessageBox (CSVDoc::View *view)
//abort shutdown, allow save to complete //abort shutdown, allow save to complete
//disconnection to prevent unintended view closures //disconnection to prevent unintended view closures
mExitOnSaveStateChange = false; mExitOnSaveStateChange = false;
disconnect (document, SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (onExitWarningHandler(int, CSMDoc::Document *))); disconnect (document, &CSMDoc::Document::stateChanged, this, &ViewManager::onExitWarningHandler);
retVal = false; retVal = false;
} }

View file

@ -19,26 +19,23 @@ CSVFilter::EditWidget::EditWidget (CSMWorld::Data& data, QWidget *parent)
: QLineEdit (parent), mParser (data), mIsEmpty(true) : QLineEdit (parent), mParser (data), mIsEmpty(true)
{ {
mPalette = palette(); mPalette = palette();
connect (this, SIGNAL (textChanged (const QString&)), this, SLOT (textChanged (const QString&))); connect (this, &QLineEdit::textChanged, this, &EditWidget::textChanged);
const CSMWorld::IdTableBase *model = const CSMWorld::IdTableBase *model =
static_cast<const CSMWorld::IdTableBase *> (data.getTableModel (CSMWorld::UniversalId::Type_Filters)); static_cast<const CSMWorld::IdTableBase *> (data.getTableModel (CSMWorld::UniversalId::Type_Filters));
connect (model, SIGNAL (dataChanged (const QModelIndex &, const QModelIndex&)), connect (model, &CSMWorld::IdTableBase::dataChanged,
this, SLOT (filterDataChanged (const QModelIndex &, const QModelIndex&)), this, &EditWidget::filterDataChanged, Qt::QueuedConnection);
Qt::QueuedConnection); connect (model, &CSMWorld::IdTableBase::rowsRemoved,
connect (model, SIGNAL (rowsRemoved (const QModelIndex&, int, int)), this, &EditWidget::filterRowsRemoved, Qt::QueuedConnection);
this, SLOT (filterRowsRemoved (const QModelIndex&, int, int)), connect (model, &CSMWorld::IdTableBase::rowsInserted,
Qt::QueuedConnection); this, &EditWidget::filterRowsInserted, Qt::QueuedConnection);
connect (model, SIGNAL (rowsInserted (const QModelIndex&, int, int)),
this, SLOT (filterRowsInserted (const QModelIndex&, int, int)),
Qt::QueuedConnection);
mStateColumnIndex = model->findColumnIndex(CSMWorld::Columns::ColumnId_Modification); mStateColumnIndex = model->findColumnIndex(CSMWorld::Columns::ColumnId_Modification);
mDescColumnIndex = model->findColumnIndex(CSMWorld::Columns::ColumnId_Description); mDescColumnIndex = model->findColumnIndex(CSMWorld::Columns::ColumnId_Description);
mHelpAction = new QAction (tr ("Help"), this); mHelpAction = new QAction (tr ("Help"), this);
connect (mHelpAction, SIGNAL (triggered()), this, SLOT (openHelp())); connect (mHelpAction, &QAction::triggered, this, &EditWidget::openHelp);
mHelpAction->setIcon(QIcon(":/info.png")); mHelpAction->setIcon(QIcon(":/info.png"));
addAction (mHelpAction); addAction (mHelpAction);
auto* openHelpShortcut = new CSMPrefs::Shortcut("help", this); auto* openHelpShortcut = new CSMPrefs::Shortcut("help", this);

View file

@ -20,9 +20,8 @@ CSVFilter::FilterBox::FilterBox (CSMWorld::Data& data, QWidget *parent)
setLayout (layout); setLayout (layout);
connect (mRecordFilterBox, connect (mRecordFilterBox, &RecordFilterBox::filterChanged,
SIGNAL (filterChanged (std::shared_ptr<CSMFilter::Node>)), this, &FilterBox::recordFilterChanged);
this, SIGNAL (recordFilterChanged (std::shared_ptr<CSMFilter::Node>)));
setAcceptDrops(true); setAcceptDrops(true);
} }

View file

@ -22,9 +22,8 @@ CSVFilter::RecordFilterBox::RecordFilterBox (CSMWorld::Data& data, QWidget *pare
setLayout (layout); setLayout (layout);
connect ( connect (mEdit, &EditWidget::filterChanged,
mEdit, SIGNAL (filterChanged (std::shared_ptr<CSMFilter::Node>)), this, &RecordFilterBox::filterChanged);
this, SIGNAL (filterChanged (std::shared_ptr<CSMFilter::Node>)));
} }
void CSVFilter::RecordFilterBox::setFilter (const std::string& filter) void CSVFilter::RecordFilterBox::setFilter (const std::string& filter)

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