mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 08:29:56 +00:00
Merge branch 'std-filesystem' into 'master'
Replace all remaining occurrences of boost::filesystem with std::filesystem. Closes #6085 See merge request OpenMW/openmw!1996
This commit is contained in:
commit
052a3d9bc5
203 changed files with 1659 additions and 1290 deletions
|
@ -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;
|
||||||
|
@ -55,7 +58,7 @@ bool parseOptions (int argc, char** argv, Arguments &info)
|
||||||
|
|
||||||
hidden.add_options()
|
hidden.add_options()
|
||||||
( "mode,m", bpo::value<std::string>(), "bsatool mode")
|
( "mode,m", bpo::value<std::string>(), "bsatool mode")
|
||||||
( "input-file,i", bpo::value< std::vector<std::string> >(), "input file")
|
( "input-file,i", bpo::value< Files::MaybeQuotedPathContainer >(), "input file")
|
||||||
;
|
;
|
||||||
|
|
||||||
bpo::positional_options_description p;
|
bpo::positional_options_description p;
|
||||||
|
@ -112,37 +115,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 +181,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 +199,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 +219,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 +243,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 +261,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 +273,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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,7 +145,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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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"
|
||||||
|
@ -83,7 +85,7 @@ bool parseOptions (int argc, char** argv, Arguments &info)
|
||||||
|
|
||||||
hidden.add_options()
|
hidden.add_options()
|
||||||
( "mode,m", bpo::value<std::string>(), "esmtool mode")
|
( "mode,m", bpo::value<std::string>(), "esmtool mode")
|
||||||
( "input-file,i", bpo::value< std::vector<std::string> >(), "input file")
|
( "input-file,i", bpo::value< Files::MaybeQuotedPathContainer >(), "input file")
|
||||||
;
|
;
|
||||||
|
|
||||||
bpo::positional_options_description p;
|
bpo::positional_options_description p;
|
||||||
|
@ -154,9 +156,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 +287,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 +422,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 +493,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 +502,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 +566,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,8 @@ int main(int argc, char** argv)
|
||||||
bpo::positional_options_description p_desc;
|
bpo::positional_options_description p_desc;
|
||||||
desc.add_options()
|
desc.add_options()
|
||||||
("help,h", "produce help message")
|
("help,h", "produce help message")
|
||||||
("mwsave,m", bpo::value<std::string>(), "morrowind .ess save file")
|
("mwsave,m", bpo::value<Files::MaybeQuotedPath>(), "morrowind .ess save file")
|
||||||
("output,o", bpo::value<std::string>(), "output file (.omwsave)")
|
("output,o", bpo::value<Files::MaybeQuotedPath>(), "output file (.omwsave)")
|
||||||
("compare,c", "compare two .ess files")
|
("compare,c", "compare two .ess files")
|
||||||
("encoding", boost::program_options::value<std::string>()->default_value("win1252"), "encoding of the save file")
|
("encoding", boost::program_options::value<std::string>()->default_value("win1252"), "encoding of the save file")
|
||||||
;
|
;
|
||||||
|
@ -45,8 +45,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 +55,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?");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
|
|
||||||
|
@ -230,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)
|
||||||
|
@ -264,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));
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
@ -155,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;
|
||||||
}
|
}
|
||||||
|
@ -295,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));
|
||||||
|
@ -328,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;
|
||||||
|
|
||||||
|
@ -479,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
|
||||||
|
@ -509,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
|
||||||
|
|
|
@ -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"
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,7 +55,6 @@ 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
|
||||||
|
@ -62,9 +64,9 @@ int wmain(int argc, wchar_t *wargv[]) {
|
||||||
desc.add_options()
|
desc.add_options()
|
||||||
("help,h", "produce help message")
|
("help,h", "produce help message")
|
||||||
("verbose,v", "verbose output")
|
("verbose,v", "verbose output")
|
||||||
("ini,i", bpo::value<std::string>(), "morrowind.ini file")
|
("ini,i", bpo::value<Files::MaybeQuotedPath>(), "morrowind.ini file")
|
||||||
("cfg,c", bpo::value<std::string>(), "openmw.cfg file")
|
("cfg,c", bpo::value<Files::MaybeQuotedPath>(), "openmw.cfg file")
|
||||||
("output,o", bpo::value<std::string>()->default_value(""), "openmw.cfg file")
|
("output,o", bpo::value<Files::MaybeQuotedPath>()->default_value({}), "openmw.cfg file")
|
||||||
("game-files,g", "import esm and esp files")
|
("game-files,g", "import esm and esp files")
|
||||||
("fonts,f", "import bitmap fonts")
|
("fonts,f", "import bitmap fonts")
|
||||||
("no-archives,A", "disable bsa archives import")
|
("no-archives,A", "disable bsa archives import")
|
||||||
|
@ -92,20 +94,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 +138,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)
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
@ -143,7 +144,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 +180,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);
|
||||||
|
|
||||||
|
|
|
@ -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,7 +68,7 @@ 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("Ensure that OpenMW can use the provided NIF and BSA files\n\n"
|
||||||
"Usages:\n"
|
"Usages:\n"
|
||||||
|
@ -75,7 +77,7 @@ bool parseOptions (int argc, char** argv, std::vector<std::string>& files)
|
||||||
"Allowed options");
|
"Allowed options");
|
||||||
desc.add_options()
|
desc.add_options()
|
||||||
("help,h", "print help message.")
|
("help,h", "print help message.")
|
||||||
("input-file", bpo::value< std::vector<std::string> >(), "input file")
|
("input-file", bpo::value< Files::MaybeQuotedPathContainer >(), "input file")
|
||||||
;
|
;
|
||||||
|
|
||||||
//Default option if none provided
|
//Default option if none provided
|
||||||
|
@ -96,7 +98,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 +116,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)
|
||||||
|
|
|
@ -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
|
||||||
)
|
)
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
@ -63,7 +66,7 @@ CS::Editor::Editor (int argc, char **argv)
|
||||||
connect (&mStartup, &CSVDoc::StartupDialogue::editConfig, this, &Editor::showSettings);
|
connect (&mStartup, &CSVDoc::StartupDialogue::editConfig, this, &Editor::showSettings);
|
||||||
|
|
||||||
connect (&mFileDialog, &CSVDoc::FileDialog::signalOpenFiles,
|
connect (&mFileDialog, &CSVDoc::FileDialog::signalOpenFiles,
|
||||||
this, [this](const boost::filesystem::path &savePath){ this->openFiles(savePath); });
|
this, [this](const std::filesystem::path &savePath){ this->openFiles(savePath); });
|
||||||
connect (&mFileDialog, &CSVDoc::FileDialog::signalCreateNewFile, this, &Editor::createNewFile);
|
connect (&mFileDialog, &CSVDoc::FileDialog::signalCreateNewFile, this, &Editor::createNewFile);
|
||||||
connect (&mFileDialog, &CSVDoc::FileDialog::rejected, this, &Editor::cancelFileDialog);
|
connect (&mFileDialog, &CSVDoc::FileDialog::rejected, this, &Editor::cancelFileDialog);
|
||||||
|
|
||||||
|
@ -77,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()
|
||||||
|
@ -107,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;
|
||||||
}
|
}
|
||||||
|
@ -122,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 (
|
||||||
|
@ -135,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);
|
||||||
|
@ -225,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
|
||||||
{
|
{
|
||||||
|
@ -244,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);
|
||||||
|
@ -259,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);
|
||||||
|
|
||||||
|
@ -292,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.";
|
||||||
|
@ -321,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.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -374,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");
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
@ -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();
|
||||||
|
@ -369,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;
|
||||||
}
|
}
|
||||||
|
@ -481,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);
|
||||||
|
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
@ -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,10 +11,10 @@
|
||||||
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();
|
||||||
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,14 +1,19 @@
|
||||||
#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, qOverload<int, QProcess::ExitStatus>(&QProcess::finished),
|
connect (&mProcess, qOverload<int, QProcess::ExitStatus>(&QProcess::finished),
|
||||||
this, &Runner::finished);
|
this, &Runner::finished);
|
||||||
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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";
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,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)
|
||||||
|
@ -88,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;
|
||||||
|
|
||||||
|
@ -958,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;
|
||||||
|
|
||||||
|
@ -966,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();
|
||||||
}
|
}
|
||||||
|
@ -977,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);
|
||||||
|
@ -989,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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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.";
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ CSVDoc::NewGameDialogue::NewGameDialogue()
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 ();
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
@ -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 << " *";
|
||||||
|
@ -747,7 +748,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
|
||||||
|
|
|
@ -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"
|
||||||
|
@ -261,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);
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
|
|
||||||
#include "merge.hpp"
|
#include "merge.hpp"
|
||||||
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
#include <QDialogButtonBox>
|
#include <QDialogButtonBox>
|
||||||
#include <QSplitter>
|
|
||||||
#include <QPushButton>
|
|
||||||
#include <QListWidget>
|
|
||||||
#include <QLabel>
|
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QListWidget>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QSplitter>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
#include <components/files/conversion.hpp>
|
||||||
|
#include <components/files/qtconversion.hpp>
|
||||||
|
|
||||||
#include "../../model/doc/document.hpp"
|
#include "../../model/doc/document.hpp"
|
||||||
#include "../../model/doc/documentmanager.hpp"
|
#include "../../model/doc/documentmanager.hpp"
|
||||||
|
@ -98,14 +101,14 @@ void CSVTools::Merge::configure (CSMDoc::Document *document)
|
||||||
while (mFiles->count())
|
while (mFiles->count())
|
||||||
delete mFiles->takeItem (0);
|
delete mFiles->takeItem (0);
|
||||||
|
|
||||||
std::vector<boost::filesystem::path> files = document->getContentFiles();
|
std::vector<std::filesystem::path> files = document->getContentFiles();
|
||||||
|
|
||||||
for (std::vector<boost::filesystem::path>::const_iterator iter (files.begin());
|
for (std::vector<std::filesystem::path>::const_iterator iter (files.begin());
|
||||||
iter!=files.end(); ++iter)
|
iter!=files.end(); ++iter)
|
||||||
mFiles->addItem (QString::fromUtf8 (iter->filename().string().c_str()));
|
mFiles->addItem (Files::pathToQString(iter->filename()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVTools::Merge::setLocalData (const boost::filesystem::path& localData)
|
void CSVTools::Merge::setLocalData (const std::filesystem::path& localData)
|
||||||
{
|
{
|
||||||
mAdjuster->setLocalData (localData);
|
mAdjuster->setLocalData (localData);
|
||||||
}
|
}
|
||||||
|
@ -125,7 +128,7 @@ void CSVTools::Merge::accept()
|
||||||
{
|
{
|
||||||
if ((mDocument->getState() & CSMDoc::State_Merging)==0)
|
if ((mDocument->getState() & CSMDoc::State_Merging)==0)
|
||||||
{
|
{
|
||||||
std::vector< boost::filesystem::path > files (1, mAdjuster->getPath());
|
std::vector< std::filesystem::path > files { mAdjuster->getPath() };
|
||||||
|
|
||||||
std::unique_ptr<CSMDoc::Document> target (
|
std::unique_ptr<CSMDoc::Document> target (
|
||||||
mDocumentManager.makeDocument (files, files[0], true));
|
mDocumentManager.makeDocument (files, files[0], true));
|
||||||
|
|
|
@ -3,9 +3,7 @@
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
#ifndef Q_MOC_RUN
|
#include <filesystem>
|
||||||
#include <boost/filesystem/path.hpp>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class QPushButton;
|
class QPushButton;
|
||||||
class QListWidget;
|
class QListWidget;
|
||||||
|
@ -44,7 +42,7 @@ namespace CSVTools
|
||||||
/// Configure dialogue for a new merge
|
/// Configure dialogue for a new merge
|
||||||
void configure (CSMDoc::Document *document);
|
void configure (CSMDoc::Document *document);
|
||||||
|
|
||||||
void setLocalData (const boost::filesystem::path& localData);
|
void setLocalData (const std::filesystem::path& localData);
|
||||||
|
|
||||||
CSMDoc::Document *getDocument() const;
|
CSMDoc::Document *getDocument() const;
|
||||||
|
|
||||||
|
|
|
@ -143,9 +143,6 @@ target_link_libraries(openmw
|
||||||
${OSGDB_LIBRARIES}
|
${OSGDB_LIBRARIES}
|
||||||
${OSGUTIL_LIBRARIES}
|
${OSGUTIL_LIBRARIES}
|
||||||
${OSG_LIBRARIES}
|
${OSG_LIBRARIES}
|
||||||
|
|
||||||
${Boost_SYSTEM_LIBRARY}
|
|
||||||
${Boost_FILESYSTEM_LIBRARY}
|
|
||||||
${Boost_PROGRAM_OPTIONS_LIBRARY}
|
${Boost_PROGRAM_OPTIONS_LIBRARY}
|
||||||
${OPENAL_LIBRARY}
|
${OPENAL_LIBRARY}
|
||||||
${FFmpeg_LIBRARIES}
|
${FFmpeg_LIBRARIES}
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
#include "engine.hpp"
|
#include "engine.hpp"
|
||||||
|
|
||||||
#include <iomanip>
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <filesystem>
|
|
||||||
|
|
||||||
#include <boost/filesystem/fstream.hpp>
|
|
||||||
|
|
||||||
#include <osgViewer/ViewerEventHandlers>
|
#include <osgViewer/ViewerEventHandlers>
|
||||||
#include <osgDB/WriteFile>
|
#include <osgDB/WriteFile>
|
||||||
|
@ -532,7 +528,7 @@ void OMW::Engine::enableFSStrict(bool fsStrict)
|
||||||
void OMW::Engine::setDataDirs (const Files::PathContainer& dataDirs)
|
void OMW::Engine::setDataDirs (const Files::PathContainer& dataDirs)
|
||||||
{
|
{
|
||||||
mDataDirs = dataDirs;
|
mDataDirs = dataDirs;
|
||||||
mDataDirs.insert(mDataDirs.begin(), (mResDir / "vfs"));
|
mDataDirs.insert(mDataDirs.begin(), mResDir / "vfs");
|
||||||
mFileCollections = Files::Collections (mDataDirs, !mFSStrict);
|
mFileCollections = Files::Collections (mDataDirs, !mFSStrict);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -542,7 +538,7 @@ void OMW::Engine::addArchive (const std::string& archive) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set resource dir
|
// Set resource dir
|
||||||
void OMW::Engine::setResourceDir (const boost::filesystem::path& parResDir)
|
void OMW::Engine::setResourceDir (const std::filesystem::path& parResDir)
|
||||||
{
|
{
|
||||||
mResDir = parResDir;
|
mResDir = parResDir;
|
||||||
}
|
}
|
||||||
|
@ -712,7 +708,7 @@ void OMW::Engine::createWindow()
|
||||||
void OMW::Engine::setWindowIcon()
|
void OMW::Engine::setWindowIcon()
|
||||||
{
|
{
|
||||||
std::ifstream windowIconStream;
|
std::ifstream windowIconStream;
|
||||||
std::string windowIcon = (mResDir / "openmw.png").string();
|
const auto windowIcon = mResDir / "openmw.png";
|
||||||
windowIconStream.open(windowIcon, std::ios_base::in | std::ios_base::binary);
|
windowIconStream.open(windowIcon, std::ios_base::in | std::ios_base::binary);
|
||||||
if (windowIconStream.fail())
|
if (windowIconStream.fail())
|
||||||
Log(Debug::Error) << "Error: Failed to open " << windowIcon;
|
Log(Debug::Error) << "Error: Failed to open " << windowIcon;
|
||||||
|
@ -769,7 +765,7 @@ void OMW::Engine::prepareEngine()
|
||||||
mScreenCaptureOperation = new SceneUtil::AsyncScreenCaptureOperation(
|
mScreenCaptureOperation = new SceneUtil::AsyncScreenCaptureOperation(
|
||||||
mWorkQueue,
|
mWorkQueue,
|
||||||
new SceneUtil::WriteScreenshotToFileOperation(
|
new SceneUtil::WriteScreenshotToFileOperation(
|
||||||
mCfgMgr.getScreenshotPath().string(),
|
mCfgMgr.getScreenshotPath(),
|
||||||
Settings::Manager::getString("screenshot format", "General"),
|
Settings::Manager::getString("screenshot format", "General"),
|
||||||
Settings::Manager::getBool("notify on saved screenshot", "General")
|
Settings::Manager::getBool("notify on saved screenshot", "General")
|
||||||
? std::function<void (std::string)>(ScheduleNonDialogMessageBox {})
|
? std::function<void (std::string)>(ScheduleNonDialogMessageBox {})
|
||||||
|
@ -781,35 +777,34 @@ void OMW::Engine::prepareEngine()
|
||||||
|
|
||||||
mViewer->addEventHandler(mScreenCaptureHandler);
|
mViewer->addEventHandler(mScreenCaptureHandler);
|
||||||
|
|
||||||
mLuaManager = std::make_unique<MWLua::LuaManager>(mVFS.get(), (mResDir / "lua_libs").string());
|
mLuaManager = std::make_unique<MWLua::LuaManager>(mVFS.get(), mResDir / "lua_libs");
|
||||||
mEnvironment.setLuaManager(*mLuaManager);
|
mEnvironment.setLuaManager(*mLuaManager);
|
||||||
|
|
||||||
// Create input and UI first to set up a bootstrapping environment for
|
// Create input and UI first to set up a bootstrapping environment for
|
||||||
// showing a loading screen and keeping the window responsive while doing so
|
// showing a loading screen and keeping the window responsive while doing so
|
||||||
|
|
||||||
std::string keybinderUser = (mCfgMgr.getUserConfigPath() / "input_v3.xml").string();
|
const auto keybinderUser = mCfgMgr.getUserConfigPath() / "input_v3.xml";
|
||||||
bool keybinderUserExists = std::filesystem::exists(keybinderUser);
|
bool keybinderUserExists = std::filesystem::exists(keybinderUser);
|
||||||
if(!keybinderUserExists)
|
if(!keybinderUserExists)
|
||||||
{
|
{
|
||||||
std::string input2 = (mCfgMgr.getUserConfigPath() / "input_v2.xml").string();
|
const auto input2 = (mCfgMgr.getUserConfigPath() / "input_v2.xml");
|
||||||
if(std::filesystem::exists(input2)) {
|
if(std::filesystem::exists(input2)) {
|
||||||
std::filesystem::copy_file(input2, keybinderUser);
|
keybinderUserExists = std::filesystem::copy_file(input2, keybinderUser);
|
||||||
keybinderUserExists = std::filesystem::exists(keybinderUser);
|
|
||||||
Log(Debug::Info) << "Loading keybindings file: " << keybinderUser;
|
Log(Debug::Info) << "Loading keybindings file: " << keybinderUser;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Log(Debug::Info) << "Loading keybindings file: " << keybinderUser;
|
Log(Debug::Info) << "Loading keybindings file: " << keybinderUser;
|
||||||
|
|
||||||
const std::string userdefault = mCfgMgr.getUserConfigPath().string() + "/gamecontrollerdb.txt";
|
const auto userdefault = mCfgMgr.getUserConfigPath() / "gamecontrollerdb.txt";
|
||||||
const std::string localdefault = mCfgMgr.getLocalPath().string() + "/gamecontrollerdb.txt";
|
const auto localdefault = mCfgMgr.getLocalPath() / "gamecontrollerdb.txt";
|
||||||
const std::string globaldefault = mCfgMgr.getGlobalPath().string() + "/gamecontrollerdb.txt";
|
const auto globaldefault = mCfgMgr.getGlobalPath() / "gamecontrollerdb.txt";
|
||||||
|
|
||||||
std::string userGameControllerdb;
|
std::filesystem::path userGameControllerdb;
|
||||||
if (std::filesystem::exists(userdefault))
|
if (std::filesystem::exists(userdefault))
|
||||||
userGameControllerdb = userdefault;
|
userGameControllerdb = userdefault;
|
||||||
|
|
||||||
std::string gameControllerdb;
|
std::filesystem::path gameControllerdb;
|
||||||
if (std::filesystem::exists(localdefault))
|
if (std::filesystem::exists(localdefault))
|
||||||
gameControllerdb = localdefault;
|
gameControllerdb = localdefault;
|
||||||
else if (std::filesystem::exists(globaldefault))
|
else if (std::filesystem::exists(globaldefault))
|
||||||
|
@ -817,7 +812,7 @@ void OMW::Engine::prepareEngine()
|
||||||
//else if it doesn't exist, pass in an empty string
|
//else if it doesn't exist, pass in an empty string
|
||||||
|
|
||||||
// gui needs our shaders path before everything else
|
// gui needs our shaders path before everything else
|
||||||
mResourceSystem->getSceneManager()->setShaderPath((mResDir / "shaders").string());
|
mResourceSystem->getSceneManager()->setShaderPath(mResDir / "shaders");
|
||||||
|
|
||||||
osg::ref_ptr<osg::GLExtensions> exts = osg::GLExtensions::Get(0, false);
|
osg::ref_ptr<osg::GLExtensions> exts = osg::GLExtensions::Get(0, false);
|
||||||
bool shadersSupported = exts && (exts->glslLanguageVersion >= 1.2f);
|
bool shadersSupported = exts && (exts->glslLanguageVersion >= 1.2f);
|
||||||
|
@ -835,9 +830,9 @@ void OMW::Engine::prepareEngine()
|
||||||
rootNode->addChild(guiRoot);
|
rootNode->addChild(guiRoot);
|
||||||
|
|
||||||
mWindowManager = std::make_unique<MWGui::WindowManager>(mWindow, mViewer, guiRoot, mResourceSystem.get(), mWorkQueue.get(),
|
mWindowManager = std::make_unique<MWGui::WindowManager>(mWindow, mViewer, guiRoot, mResourceSystem.get(), mWorkQueue.get(),
|
||||||
mCfgMgr.getLogPath().string() + std::string("/"),
|
mCfgMgr.getLogPath(),
|
||||||
mScriptConsoleMode, mTranslationDataStorage, mEncoding,
|
mScriptConsoleMode, mTranslationDataStorage, mEncoding,
|
||||||
Version::getOpenmwVersionDescription(mResDir.string()), shadersSupported);
|
Version::getOpenmwVersionDescription(mResDir), shadersSupported);
|
||||||
mEnvironment.setWindowManager(*mWindowManager);
|
mEnvironment.setWindowManager(*mWindowManager);
|
||||||
|
|
||||||
mInputManager = std::make_unique<MWInput::InputManager>(mWindow, mViewer, mScreenCaptureHandler,
|
mInputManager = std::make_unique<MWInput::InputManager>(mWindow, mViewer, mScreenCaptureHandler,
|
||||||
|
@ -858,7 +853,7 @@ void OMW::Engine::prepareEngine()
|
||||||
// Create the world
|
// Create the world
|
||||||
mWorld = std::make_unique<MWWorld::World>(mViewer, rootNode, mResourceSystem.get(), mWorkQueue.get(), *mUnrefQueue,
|
mWorld = std::make_unique<MWWorld::World>(mViewer, rootNode, mResourceSystem.get(), mWorkQueue.get(), *mUnrefQueue,
|
||||||
mFileCollections, mContentFiles, mGroundcoverFiles, mEncoder.get(), mActivationDistanceOverride, mCellName,
|
mFileCollections, mContentFiles, mGroundcoverFiles, mEncoder.get(), mActivationDistanceOverride, mCellName,
|
||||||
mStartupScript, mResDir.string(), mCfgMgr.getUserDataPath().string());
|
mStartupScript, mResDir, mCfgMgr.getUserDataPath());
|
||||||
mWorld->setupPlayer();
|
mWorld->setupPlayer();
|
||||||
mWorld->setRandomSeed(mRandomSeed);
|
mWorld->setRandomSeed(mRandomSeed);
|
||||||
mEnvironment.setWorld(*mWorld);
|
mEnvironment.setWorld(*mWorld);
|
||||||
|
@ -869,8 +864,8 @@ void OMW::Engine::prepareEngine()
|
||||||
|
|
||||||
//Load translation data
|
//Load translation data
|
||||||
mTranslationDataStorage.setEncoder(mEncoder.get());
|
mTranslationDataStorage.setEncoder(mEncoder.get());
|
||||||
for (size_t i = 0; i < mContentFiles.size(); i++)
|
for (auto & mContentFile : mContentFiles)
|
||||||
mTranslationDataStorage.loadTranslationData(mFileCollections, mContentFiles[i]);
|
mTranslationDataStorage.loadTranslationData(mFileCollections, mContentFile);
|
||||||
|
|
||||||
Compiler::registerExtensions (mExtensions);
|
Compiler::registerExtensions (mExtensions);
|
||||||
|
|
||||||
|
@ -914,7 +909,7 @@ void OMW::Engine::prepareEngine()
|
||||||
}
|
}
|
||||||
|
|
||||||
mLuaManager->init();
|
mLuaManager->init();
|
||||||
mLuaManager->loadPermanentStorage(mCfgMgr.getUserConfigPath().string());
|
mLuaManager->loadPermanentStorage(mCfgMgr.getUserConfigPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
class OMW::Engine::LuaWorker
|
class OMW::Engine::LuaWorker
|
||||||
|
@ -1018,7 +1013,7 @@ void OMW::Engine::go()
|
||||||
|
|
||||||
Misc::Rng::init(mRandomSeed);
|
Misc::Rng::init(mRandomSeed);
|
||||||
|
|
||||||
Settings::ShaderManager::get().load((mCfgMgr.getUserConfigPath() / "shaders.yaml").string());
|
Settings::ShaderManager::get().load(mCfgMgr.getUserConfigPath() / "shaders.yaml");
|
||||||
|
|
||||||
MWClass::registerClasses();
|
MWClass::registerClasses();
|
||||||
|
|
||||||
|
@ -1036,8 +1031,18 @@ void OMW::Engine::go()
|
||||||
|
|
||||||
prepareEngine();
|
prepareEngine();
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
const auto* stats_file = _wgetenv(L"OPENMW_OSG_STATS_FILE");
|
||||||
|
#else
|
||||||
|
const auto* stats_file = std::getenv("OPENMW_OSG_STATS_FILE");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::filesystem::path path;
|
||||||
|
if (stats_file != nullptr)
|
||||||
|
path = stats_file;
|
||||||
|
|
||||||
std::ofstream stats;
|
std::ofstream stats;
|
||||||
if (const auto path = std::getenv("OPENMW_OSG_STATS_FILE"))
|
if (!path.empty())
|
||||||
{
|
{
|
||||||
stats.open(path, std::ios_base::out);
|
stats.open(path, std::ios_base::out);
|
||||||
if (stats.is_open())
|
if (stats.is_open())
|
||||||
|
@ -1140,9 +1145,9 @@ void OMW::Engine::go()
|
||||||
luaWorker.join();
|
luaWorker.join();
|
||||||
|
|
||||||
// Save user settings
|
// Save user settings
|
||||||
Settings::Manager::saveUser((mCfgMgr.getUserConfigPath() / "settings.cfg").string());
|
Settings::Manager::saveUser(mCfgMgr.getUserConfigPath() / "settings.cfg");
|
||||||
Settings::ShaderManager::get().save();
|
Settings::ShaderManager::get().save();
|
||||||
mLuaManager->savePermanentStorage(mCfgMgr.getUserConfigPath().string());
|
mLuaManager->savePermanentStorage(mCfgMgr.getUserConfigPath());
|
||||||
|
|
||||||
Log(Debug::Info) << "Quitting peacefully.";
|
Log(Debug::Info) << "Quitting peacefully.";
|
||||||
}
|
}
|
||||||
|
@ -1197,7 +1202,7 @@ void OMW::Engine::setScriptBlacklistUse (bool use)
|
||||||
mScriptBlacklistUse = use;
|
mScriptBlacklistUse = use;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OMW::Engine::setSaveGameFile(const std::string &savegame)
|
void OMW::Engine::setSaveGameFile(const std::filesystem::path &savegame)
|
||||||
{
|
{
|
||||||
mSaveGameFile = savegame;
|
mSaveGameFile = savegame;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef ENGINE_H
|
#ifndef ENGINE_H
|
||||||
#define ENGINE_H
|
#define ENGINE_H
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
#include <components/compiler/extensions.hpp>
|
#include <components/compiler/extensions.hpp>
|
||||||
#include <components/files/collections.hpp>
|
#include <components/files/collections.hpp>
|
||||||
#include <components/translation/translation.hpp>
|
#include <components/translation/translation.hpp>
|
||||||
|
@ -135,7 +137,7 @@ namespace OMW
|
||||||
std::unique_ptr<ToUTF8::Utf8Encoder> mEncoder;
|
std::unique_ptr<ToUTF8::Utf8Encoder> mEncoder;
|
||||||
Files::PathContainer mDataDirs;
|
Files::PathContainer mDataDirs;
|
||||||
std::vector<std::string> mArchives;
|
std::vector<std::string> mArchives;
|
||||||
boost::filesystem::path mResDir;
|
std::filesystem::path mResDir;
|
||||||
osg::ref_ptr<osgViewer::Viewer> mViewer;
|
osg::ref_ptr<osgViewer::Viewer> mViewer;
|
||||||
osg::ref_ptr<osgViewer::ScreenCaptureHandler> mScreenCaptureHandler;
|
osg::ref_ptr<osgViewer::ScreenCaptureHandler> mScreenCaptureHandler;
|
||||||
osg::ref_ptr<SceneUtil::AsyncScreenCaptureOperation> mScreenCaptureOperation;
|
osg::ref_ptr<SceneUtil::AsyncScreenCaptureOperation> mScreenCaptureOperation;
|
||||||
|
@ -156,7 +158,7 @@ namespace OMW
|
||||||
bool mScriptConsoleMode;
|
bool mScriptConsoleMode;
|
||||||
std::string mStartupScript;
|
std::string mStartupScript;
|
||||||
int mActivationDistanceOverride;
|
int mActivationDistanceOverride;
|
||||||
std::string mSaveGameFile;
|
std::filesystem::path mSaveGameFile;
|
||||||
// Grab mouse?
|
// Grab mouse?
|
||||||
bool mGrab;
|
bool mGrab;
|
||||||
|
|
||||||
|
@ -203,7 +205,7 @@ namespace OMW
|
||||||
void addArchive(const std::string& archive);
|
void addArchive(const std::string& archive);
|
||||||
|
|
||||||
/// Set resource dir
|
/// Set resource dir
|
||||||
void setResourceDir(const boost::filesystem::path& parResDir);
|
void setResourceDir(const std::filesystem::path& parResDir);
|
||||||
|
|
||||||
/// Set start cell name
|
/// Set start cell name
|
||||||
void setCell(const std::string& cellName);
|
void setCell(const std::string& cellName);
|
||||||
|
@ -254,7 +256,7 @@ namespace OMW
|
||||||
void setScriptBlacklistUse (bool use);
|
void setScriptBlacklistUse (bool use);
|
||||||
|
|
||||||
/// Set the save game file to load after initialising the engine.
|
/// Set the save game file to load after initialising the engine.
|
||||||
void setSaveGameFile(const std::string& savegame);
|
void setSaveGameFile(const std::filesystem::path &savegame);
|
||||||
|
|
||||||
void setRandomSeed(unsigned int seed);
|
void setRandomSeed(unsigned int seed);
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
||||||
{
|
{
|
||||||
cfgMgr.readConfiguration(variables, desc, true);
|
cfgMgr.readConfiguration(variables, desc, true);
|
||||||
|
|
||||||
Version::Version v = Version::getOpenmwVersion(variables["resources"].as<Files::MaybeQuotedPath>().string());
|
Version::Version v = Version::getOpenmwVersion(variables["resources"].as<Files::MaybeQuotedPath>().u8string()); // This call to u8string is redundant, but required to build on MSVC 14.26 due to implementation bugs.
|
||||||
getRawStdout() << v.describe() << std::endl;
|
getRawStdout() << v.describe() << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -69,10 +69,10 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
||||||
cfgMgr.readConfiguration(variables, desc);
|
cfgMgr.readConfiguration(variables, desc);
|
||||||
Settings::Manager::load(cfgMgr);
|
Settings::Manager::load(cfgMgr);
|
||||||
|
|
||||||
setupLogging(cfgMgr.getLogPath().string(), "OpenMW");
|
setupLogging(cfgMgr.getLogPath(), "OpenMW");
|
||||||
MWGui::DebugWindow::startLogRecording();
|
MWGui::DebugWindow::startLogRecording();
|
||||||
|
|
||||||
Version::Version v = Version::getOpenmwVersion(variables["resources"].as<Files::MaybeQuotedPath>().string());
|
Version::Version v = Version::getOpenmwVersion(variables["resources"].as<Files::MaybeQuotedPath>().u8string()); // This call to u8string is redundant, but required to build on MSVC 14.26 due to implementation bugs.
|
||||||
Log(Debug::Info) << v.describe();
|
Log(Debug::Info) << v.describe();
|
||||||
|
|
||||||
engine.setGrabMouse(!variables["no-grab"].as<bool>());
|
engine.setGrabMouse(!variables["no-grab"].as<bool>());
|
||||||
|
@ -87,13 +87,13 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
||||||
|
|
||||||
Files::PathContainer dataDirs(asPathContainer(variables["data"].as<Files::MaybeQuotedPathContainer>()));
|
Files::PathContainer 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())
|
||||||
dataDirs.push_back(local);
|
dataDirs.push_back(local);
|
||||||
|
|
||||||
cfgMgr.filterOutNonExistingPaths(dataDirs);
|
cfgMgr.filterOutNonExistingPaths(dataDirs);
|
||||||
|
|
||||||
engine.setResourceDir(variables["resources"].as<Files::MaybeQuotedPath>());
|
engine.setResourceDir(variables["resources"].as<Files::MaybeQuotedPath>().u8string()); // This call to u8string is redundant, but required to build on MSVC 14.26 due to implementation bugs.
|
||||||
engine.setDataDirs(dataDirs);
|
engine.setDataDirs(dataDirs);
|
||||||
|
|
||||||
// fallback archives
|
// fallback archives
|
||||||
|
@ -150,7 +150,7 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
||||||
engine.setWarningsMode (variables["script-warn"].as<int>());
|
engine.setWarningsMode (variables["script-warn"].as<int>());
|
||||||
engine.setScriptBlacklist (variables["script-blacklist"].as<StringsVector>());
|
engine.setScriptBlacklist (variables["script-blacklist"].as<StringsVector>());
|
||||||
engine.setScriptBlacklistUse (variables["script-blacklist-use"].as<bool>());
|
engine.setScriptBlacklistUse (variables["script-blacklist-use"].as<bool>());
|
||||||
engine.setSaveGameFile (variables["load-savegame"].as<Files::MaybeQuotedPath>().string());
|
engine.setSaveGameFile (variables["load-savegame"].as<Files::MaybeQuotedPath>().u8string());
|
||||||
|
|
||||||
// other settings
|
// other settings
|
||||||
Fallback::Map::init(variables["fallback"].as<FallbackMap>().mMap);
|
Fallback::Map::init(variables["fallback"].as<FallbackMap>().mMap);
|
||||||
|
|
|
@ -62,12 +62,12 @@ namespace MWBase
|
||||||
///
|
///
|
||||||
/// \note Slot must belong to the current character.
|
/// \note Slot must belong to the current character.
|
||||||
|
|
||||||
virtual void loadGame (const std::string& filepath) = 0;
|
virtual void loadGame (const std::filesystem::path &filepath) = 0;
|
||||||
///< Load a saved game directly from the given file path. This will search the CharacterManager
|
///< Load a saved game directly from the given file path. This will search the CharacterManager
|
||||||
/// for a Character containing this save file, and set this Character current if one was found.
|
/// for a Character containing this save file, and set this Character current if one was found.
|
||||||
/// Otherwise, a new Character will be created.
|
/// Otherwise, a new Character will be created.
|
||||||
|
|
||||||
virtual void loadGame (const MWState::Character *character, const std::string& filepath) = 0;
|
virtual void loadGame (const MWState::Character *character, const std::filesystem::path &filepath) = 0;
|
||||||
///< Load a saved game file belonging to the given character.
|
///< Load a saved game file belonging to the given character.
|
||||||
|
|
||||||
///Simple saver, writes over the file if already existing
|
///Simple saver, writes over the file if already existing
|
||||||
|
|
|
@ -639,7 +639,7 @@ namespace MWBase
|
||||||
|
|
||||||
/// Export scene graph to a file and return the filename.
|
/// Export scene graph to a file and return the filename.
|
||||||
/// \param ptr object to export scene graph for (if empty, export entire scene graph)
|
/// \param ptr object to export scene graph for (if empty, export entire scene graph)
|
||||||
virtual std::string exportSceneGraph(const MWWorld::Ptr& ptr) = 0;
|
virtual std::filesystem::path exportSceneGraph(const MWWorld::Ptr& ptr) = 0;
|
||||||
|
|
||||||
/// Preload VFX associated with this effect list
|
/// Preload VFX associated with this effect list
|
||||||
virtual void preloadEffects(const ESM::EffectList* effectList) = 0;
|
virtual void preloadEffects(const ESM::EffectList* effectList) = 0;
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
#include <components/settings/settings.hpp>
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
#include <components/files/memorystream.hpp>
|
#include <components/files/memorystream.hpp>
|
||||||
|
#include <components/misc/timeconvert.hpp>
|
||||||
|
#include <components/files/conversion.hpp>
|
||||||
|
|
||||||
#include <components/esm3/loadclas.hpp>
|
#include <components/esm3/loadclas.hpp>
|
||||||
|
|
||||||
|
@ -199,7 +201,7 @@ namespace MWGui
|
||||||
|
|
||||||
if (mCurrentCharacter == &*it ||
|
if (mCurrentCharacter == &*it ||
|
||||||
(!mCurrentCharacter && !mSaving && directory==Misc::StringUtils::lowerCase (
|
(!mCurrentCharacter && !mSaving && directory==Misc::StringUtils::lowerCase (
|
||||||
it->begin()->mPath.parent_path().filename().string())))
|
Files::pathToUnicodeString(it->begin()->mPath.parent_path().filename()))))
|
||||||
{
|
{
|
||||||
mCurrentCharacter = &*it;
|
mCurrentCharacter = &*it;
|
||||||
selectedIndex = mCharacterSelection->getItemCount()-1;
|
selectedIndex = mCharacterSelection->getItemCount()-1;
|
||||||
|
@ -302,7 +304,7 @@ namespace MWGui
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
assert (mCurrentCharacter && mCurrentSlot);
|
assert (mCurrentCharacter && mCurrentSlot);
|
||||||
MWBase::Environment::get().getStateManager()->loadGame (mCurrentCharacter, mCurrentSlot->mPath.string());
|
MWBase::Environment::get().getStateManager()->loadGame (mCurrentCharacter, mCurrentSlot->mPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,7 +405,7 @@ namespace MWGui
|
||||||
throw std::runtime_error("Can't find selected slot");
|
throw std::runtime_error("Can't find selected slot");
|
||||||
|
|
||||||
std::stringstream text;
|
std::stringstream text;
|
||||||
time_t time = mCurrentSlot->mTimeStamp;
|
time_t time = Misc::to_time_t(mCurrentSlot->mTimeStamp);
|
||||||
struct tm* timeinfo;
|
struct tm* timeinfo;
|
||||||
timeinfo = localtime(&time);
|
timeinfo = localtime(&time);
|
||||||
|
|
||||||
|
@ -438,7 +440,7 @@ namespace MWGui
|
||||||
const std::vector<char>& data = mCurrentSlot->mProfile.mScreenshot;
|
const std::vector<char>& data = mCurrentSlot->mProfile.mScreenshot;
|
||||||
if (!data.size())
|
if (!data.size())
|
||||||
{
|
{
|
||||||
Log(Debug::Warning) << "Selected save file '" << mCurrentSlot->mPath.filename().string() << "' has no savegame screenshot";
|
Log(Debug::Warning) << "Selected save file '" << Files::pathToUnicodeString(mCurrentSlot->mPath.filename()) << "' has no savegame screenshot";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -120,7 +120,7 @@ namespace MWGui
|
||||||
{
|
{
|
||||||
WindowManager::WindowManager(
|
WindowManager::WindowManager(
|
||||||
SDL_Window* window, osgViewer::Viewer* viewer, osg::Group* guiRoot, Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue,
|
SDL_Window* window, osgViewer::Viewer* viewer, osg::Group* guiRoot, Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue,
|
||||||
const std::string& logpath, bool consoleOnlyScripts, Translation::Storage& translationDataStorage,
|
const std::filesystem::path& logpath, bool consoleOnlyScripts, Translation::Storage& translationDataStorage,
|
||||||
ToUTF8::FromType encoding, const std::string& versionDescription, bool useShaders)
|
ToUTF8::FromType encoding, const std::string& versionDescription, bool useShaders)
|
||||||
: mOldUpdateMask(0)
|
: mOldUpdateMask(0)
|
||||||
, mOldCullMask(0)
|
, mOldCullMask(0)
|
||||||
|
@ -180,7 +180,7 @@ namespace MWGui
|
||||||
mScalingFactor = std::clamp(Settings::Manager::getFloat("scaling factor", "GUI"), 0.5f, 8.f);
|
mScalingFactor = std::clamp(Settings::Manager::getFloat("scaling factor", "GUI"), 0.5f, 8.f);
|
||||||
mGuiPlatform = std::make_unique<osgMyGUI::Platform>(viewer, guiRoot, resourceSystem->getImageManager(),
|
mGuiPlatform = std::make_unique<osgMyGUI::Platform>(viewer, guiRoot, resourceSystem->getImageManager(),
|
||||||
resourceSystem->getVFS(), mScalingFactor, "mygui",
|
resourceSystem->getVFS(), mScalingFactor, "mygui",
|
||||||
(std::filesystem::path(logpath) / "MyGUI.log").generic_string());
|
logpath / "MyGUI.log");
|
||||||
|
|
||||||
mGui = std::make_unique<MyGUI::Gui>();
|
mGui = std::make_unique<MyGUI::Gui>();
|
||||||
mGui->initialise("");
|
mGui->initialise("");
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include <MyGUI_Gui.h>
|
#include <MyGUI_Gui.h>
|
||||||
#include <MyGUI_KeyCode.h>
|
#include <MyGUI_KeyCode.h>
|
||||||
#include <MyGUI_Types.h>
|
#include <MyGUI_Types.h>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
namespace MyGUI
|
namespace MyGUI
|
||||||
{
|
{
|
||||||
|
@ -124,7 +125,7 @@ namespace MWGui
|
||||||
typedef std::vector<Faction> FactionList;
|
typedef std::vector<Faction> FactionList;
|
||||||
|
|
||||||
WindowManager(SDL_Window* window, osgViewer::Viewer* viewer, osg::Group* guiRoot, Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue,
|
WindowManager(SDL_Window* window, osgViewer::Viewer* viewer, osg::Group* guiRoot, Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue,
|
||||||
const std::string& logpath, bool consoleOnlyScripts, Translation::Storage& translationDataStorage,
|
const std::filesystem::path& logpath, bool consoleOnlyScripts, Translation::Storage& translationDataStorage,
|
||||||
ToUTF8::FromType encoding, const std::string& versionDescription, bool useShaders);
|
ToUTF8::FromType encoding, const std::string& versionDescription, bool useShaders);
|
||||||
virtual ~WindowManager();
|
virtual ~WindowManager();
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <extern/oics/ICSInputControlSystem.h>
|
#include <extern/oics/ICSInputControlSystem.h>
|
||||||
|
|
||||||
#include <components/sdlutil/sdlmappings.hpp>
|
#include <components/sdlutil/sdlmappings.hpp>
|
||||||
|
#include <components/files/conversion.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/inputmanager.hpp"
|
#include "../mwbase/inputmanager.hpp"
|
||||||
|
@ -43,8 +44,8 @@ namespace MWInput
|
||||||
class InputControlSystem : public ICS::InputControlSystem
|
class InputControlSystem : public ICS::InputControlSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
InputControlSystem(const std::string& bindingsFile)
|
InputControlSystem(const std::filesystem::path &bindingsFile)
|
||||||
: ICS::InputControlSystem(bindingsFile, true, nullptr, nullptr, A_Last)
|
: ICS::InputControlSystem(Files::pathToUnicodeString(bindingsFile), true, nullptr, nullptr, A_Last)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -167,11 +168,11 @@ namespace MWInput
|
||||||
bool mDetectingKeyboard;
|
bool mDetectingKeyboard;
|
||||||
};
|
};
|
||||||
|
|
||||||
BindingsManager::BindingsManager(const std::string& userFile, bool userFileExists)
|
BindingsManager::BindingsManager(const std::filesystem::path &userFile, bool userFileExists)
|
||||||
: mUserFile(userFile)
|
: mUserFile(userFile)
|
||||||
, mDragDrop(false)
|
, mDragDrop(false)
|
||||||
{
|
{
|
||||||
std::string file = userFileExists ? userFile : "";
|
const auto file = userFileExists ? userFile : std::filesystem::path();
|
||||||
mInputBinder = std::make_unique<InputControlSystem>(file);
|
mInputBinder = std::make_unique<InputControlSystem>(file);
|
||||||
mListener = std::make_unique<BindingsListener>(mInputBinder.get(), this);
|
mListener = std::make_unique<BindingsListener>(mInputBinder.get(), this);
|
||||||
mInputBinder->setDetectingBindingListener(mListener.get());
|
mInputBinder->setDetectingBindingListener(mListener.get());
|
||||||
|
@ -192,7 +193,7 @@ namespace MWInput
|
||||||
|
|
||||||
BindingsManager::~BindingsManager()
|
BindingsManager::~BindingsManager()
|
||||||
{
|
{
|
||||||
mInputBinder->save(mUserFile);
|
mInputBinder->save(Files::pathToUnicodeString(mUserFile));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BindingsManager::update(float dt)
|
void BindingsManager::update(float dt)
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
#include <components/sdlutil/events.hpp>
|
#include <components/sdlutil/events.hpp>
|
||||||
|
|
||||||
|
@ -15,7 +16,7 @@ namespace MWInput
|
||||||
class BindingsManager
|
class BindingsManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BindingsManager(const std::string& userFile, bool userFileExists);
|
BindingsManager(const std::filesystem::path &userFile, bool userFileExists);
|
||||||
|
|
||||||
virtual ~BindingsManager();
|
virtual ~BindingsManager();
|
||||||
|
|
||||||
|
@ -70,7 +71,7 @@ namespace MWInput
|
||||||
std::unique_ptr<InputControlSystem> mInputBinder;
|
std::unique_ptr<InputControlSystem> mInputBinder;
|
||||||
std::unique_ptr<BindingsListener> mListener;
|
std::unique_ptr<BindingsListener> mListener;
|
||||||
|
|
||||||
std::string mUserFile;
|
std::filesystem::path mUserFile;
|
||||||
|
|
||||||
bool mDragDrop;
|
bool mDragDrop;
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include <components/debug/debuglog.hpp>
|
#include <components/debug/debuglog.hpp>
|
||||||
#include <components/sdlutil/sdlmappings.hpp>
|
#include <components/sdlutil/sdlmappings.hpp>
|
||||||
|
#include <components/files/conversion.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/inputmanager.hpp"
|
#include "../mwbase/inputmanager.hpp"
|
||||||
|
@ -27,8 +28,8 @@ namespace MWInput
|
||||||
ControllerManager::ControllerManager(BindingsManager* bindingsManager,
|
ControllerManager::ControllerManager(BindingsManager* bindingsManager,
|
||||||
ActionManager* actionManager,
|
ActionManager* actionManager,
|
||||||
MouseManager* mouseManager,
|
MouseManager* mouseManager,
|
||||||
const std::string& userControllerBindingsFile,
|
const std::filesystem::path &userControllerBindingsFile,
|
||||||
const std::string& controllerBindingsFile)
|
const std::filesystem::path &controllerBindingsFile)
|
||||||
: mBindingsManager(bindingsManager)
|
: mBindingsManager(bindingsManager)
|
||||||
, mActionManager(actionManager)
|
, mActionManager(actionManager)
|
||||||
, mMouseManager(mouseManager)
|
, mMouseManager(mouseManager)
|
||||||
|
@ -43,12 +44,12 @@ namespace MWInput
|
||||||
{
|
{
|
||||||
if (!controllerBindingsFile.empty())
|
if (!controllerBindingsFile.empty())
|
||||||
{
|
{
|
||||||
SDL_GameControllerAddMappingsFromFile(controllerBindingsFile.c_str());
|
SDL_GameControllerAddMappingsFromFile(Files::pathToUnicodeString(controllerBindingsFile).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!userControllerBindingsFile.empty())
|
if (!userControllerBindingsFile.empty())
|
||||||
{
|
{
|
||||||
SDL_GameControllerAddMappingsFromFile(userControllerBindingsFile.c_str());
|
SDL_GameControllerAddMappingsFromFile(Files::pathToUnicodeString(userControllerBindingsFile).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open all presently connected sticks
|
// Open all presently connected sticks
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include <components/settings/settings.hpp>
|
#include <components/settings/settings.hpp>
|
||||||
#include <components/sdlutil/events.hpp>
|
#include <components/sdlutil/events.hpp>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
namespace MWInput
|
namespace MWInput
|
||||||
{
|
{
|
||||||
|
@ -18,8 +19,8 @@ namespace MWInput
|
||||||
ControllerManager(BindingsManager* bindingsManager,
|
ControllerManager(BindingsManager* bindingsManager,
|
||||||
ActionManager* actionManager,
|
ActionManager* actionManager,
|
||||||
MouseManager* mouseManager,
|
MouseManager* mouseManager,
|
||||||
const std::string& userControllerBindingsFile,
|
const std::filesystem::path &userControllerBindingsFile,
|
||||||
const std::string& controllerBindingsFile);
|
const std::filesystem::path &controllerBindingsFile);
|
||||||
|
|
||||||
virtual ~ControllerManager() = default;
|
virtual ~ControllerManager() = default;
|
||||||
|
|
||||||
|
|
|
@ -28,8 +28,8 @@ namespace MWInput
|
||||||
osg::ref_ptr<osgViewer::Viewer> viewer,
|
osg::ref_ptr<osgViewer::Viewer> viewer,
|
||||||
osg::ref_ptr<osgViewer::ScreenCaptureHandler> screenCaptureHandler,
|
osg::ref_ptr<osgViewer::ScreenCaptureHandler> screenCaptureHandler,
|
||||||
osgViewer::ScreenCaptureHandler::CaptureOperation *screenCaptureOperation,
|
osgViewer::ScreenCaptureHandler::CaptureOperation *screenCaptureOperation,
|
||||||
const std::string& userFile, bool userFileExists, const std::string& userControllerBindingsFile,
|
const std::filesystem::path &userFile, bool userFileExists, const std::filesystem::path &userControllerBindingsFile,
|
||||||
const std::string& controllerBindingsFile, bool grab)
|
const std::filesystem::path &controllerBindingsFile, bool grab)
|
||||||
: mControlsDisabled(false)
|
: mControlsDisabled(false)
|
||||||
, mInputWrapper(std::make_unique<SDLUtil::InputWrapper>(window, viewer, grab))
|
, mInputWrapper(std::make_unique<SDLUtil::InputWrapper>(window, viewer, grab))
|
||||||
, mBindingsManager(std::make_unique<BindingsManager>(userFile, userFileExists))
|
, mBindingsManager(std::make_unique<BindingsManager>(userFile, userFileExists))
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include <components/settings/settings.hpp>
|
#include <components/settings/settings.hpp>
|
||||||
#include <components/sdlutil/events.hpp>
|
#include <components/sdlutil/events.hpp>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
#include "../mwbase/inputmanager.hpp"
|
#include "../mwbase/inputmanager.hpp"
|
||||||
|
|
||||||
|
@ -52,9 +53,9 @@ namespace MWInput
|
||||||
osg::ref_ptr<osgViewer::Viewer> viewer,
|
osg::ref_ptr<osgViewer::Viewer> viewer,
|
||||||
osg::ref_ptr<osgViewer::ScreenCaptureHandler> screenCaptureHandler,
|
osg::ref_ptr<osgViewer::ScreenCaptureHandler> screenCaptureHandler,
|
||||||
osgViewer::ScreenCaptureHandler::CaptureOperation *screenCaptureOperation,
|
osgViewer::ScreenCaptureHandler::CaptureOperation *screenCaptureOperation,
|
||||||
const std::string& userFile, bool userFileExists,
|
const std::filesystem::path &userFile, bool userFileExists,
|
||||||
const std::string& userControllerBindingsFile,
|
const std::filesystem::path &userControllerBindingsFile,
|
||||||
const std::string& controllerBindingsFile, bool grab);
|
const std::filesystem::path &controllerBindingsFile, bool grab);
|
||||||
|
|
||||||
~InputManager() final;
|
~InputManager() final;
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
namespace MWLua
|
namespace MWLua
|
||||||
{
|
{
|
||||||
|
|
||||||
LuaManager::LuaManager(const VFS::Manager* vfs, const std::string& libsDir)
|
LuaManager::LuaManager(const VFS::Manager* vfs, const std::filesystem::path &libsDir)
|
||||||
: mLua(vfs, &mConfiguration)
|
: mLua(vfs, &mConfiguration)
|
||||||
, mUiResourceManager(vfs)
|
, mUiResourceManager(vfs)
|
||||||
, mL10n(vfs, &mLua)
|
, mL10n(vfs, &mLua)
|
||||||
|
@ -110,21 +110,20 @@ namespace MWLua
|
||||||
return mL10n.translate(contextName, key);
|
return mL10n.translate(contextName, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaManager::loadPermanentStorage(const std::string& userConfigPath)
|
void LuaManager::loadPermanentStorage(const std::filesystem::path &userConfigPath)
|
||||||
{
|
{
|
||||||
auto globalPath = std::filesystem::path(userConfigPath) / "global_storage.bin";
|
const auto globalPath = userConfigPath / "global_storage.bin";
|
||||||
auto playerPath = std::filesystem::path(userConfigPath) / "player_storage.bin";
|
const auto playerPath = userConfigPath / "player_storage.bin";
|
||||||
if (std::filesystem::exists(globalPath))
|
if (std::filesystem::exists(globalPath))
|
||||||
mGlobalStorage.load(globalPath.string());
|
mGlobalStorage.load(globalPath);
|
||||||
if (std::filesystem::exists(playerPath))
|
if (std::filesystem::exists(playerPath))
|
||||||
mPlayerStorage.load(playerPath.string());
|
mPlayerStorage.load(playerPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaManager::savePermanentStorage(const std::string& userConfigPath)
|
void LuaManager::savePermanentStorage(const std::filesystem::path &userConfigPath)
|
||||||
{
|
{
|
||||||
std::filesystem::path confDir(userConfigPath);
|
mGlobalStorage.save(userConfigPath / "global_storage.bin");
|
||||||
mGlobalStorage.save((confDir / "global_storage.bin").string());
|
mPlayerStorage.save(userConfigPath / "player_storage.bin");
|
||||||
mPlayerStorage.save((confDir / "player_storage.bin").string());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaManager::update()
|
void LuaManager::update()
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <components/lua_ui/resources.hpp>
|
#include <components/lua_ui/resources.hpp>
|
||||||
|
|
||||||
#include <components/misc/color.hpp>
|
#include <components/misc/color.hpp>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
#include "../mwbase/luamanager.hpp"
|
#include "../mwbase/luamanager.hpp"
|
||||||
|
|
||||||
|
@ -26,7 +27,7 @@ namespace MWLua
|
||||||
class LuaManager : public MWBase::LuaManager
|
class LuaManager : public MWBase::LuaManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LuaManager(const VFS::Manager* vfs, const std::string& libsDir);
|
LuaManager(const VFS::Manager* vfs, const std::filesystem::path &libsDir);
|
||||||
|
|
||||||
// Called by engine.cpp before UI setup.
|
// Called by engine.cpp before UI setup.
|
||||||
void initL10n();
|
void initL10n();
|
||||||
|
@ -34,8 +35,8 @@ namespace MWLua
|
||||||
// Called by engine.cpp when the environment is fully initialized.
|
// Called by engine.cpp when the environment is fully initialized.
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
void loadPermanentStorage(const std::string& userConfigPath);
|
void loadPermanentStorage(const std::filesystem::path &userConfigPath);
|
||||||
void savePermanentStorage(const std::string& userConfigPath);
|
void savePermanentStorage(const std::filesystem::path &userConfigPath);
|
||||||
|
|
||||||
// Called by engine.cpp every frame. For performance reasons it works in a separate
|
// Called by engine.cpp every frame. For performance reasons it works in a separate
|
||||||
// thread (in parallel with osg Cull). Can not use scene graph.
|
// thread (in parallel with osg Cull). Can not use scene graph.
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <components/vfs/manager.hpp>
|
#include <components/vfs/manager.hpp>
|
||||||
#include <components/stereo/multiview.hpp>
|
#include <components/stereo/multiview.hpp>
|
||||||
#include <components/stereo/stereomanager.hpp>
|
#include <components/stereo/stereomanager.hpp>
|
||||||
|
#include <components/files/conversion.hpp>
|
||||||
|
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
|
@ -217,12 +218,12 @@ namespace MWRender
|
||||||
{
|
{
|
||||||
for (const auto& name : mVFS->getRecursiveDirectoryIterator(fx::Technique::sSubdir))
|
for (const auto& name : mVFS->getRecursiveDirectoryIterator(fx::Technique::sSubdir))
|
||||||
{
|
{
|
||||||
std::filesystem::path path = name;
|
std::filesystem::path path = Files::pathFromUnicodeString(name);
|
||||||
std::string fileExt = Misc::StringUtils::lowerCase(path.extension().string());
|
std::string fileExt = Misc::StringUtils::lowerCase(Files::pathToUnicodeString(path.extension()));
|
||||||
if (!path.parent_path().has_parent_path() && fileExt == fx::Technique::sExt)
|
if (!path.parent_path().has_parent_path() && fileExt == fx::Technique::sExt)
|
||||||
{
|
{
|
||||||
auto absolutePath = std::filesystem::path(mVFS->getAbsoluteFileName(name));
|
const auto absolutePath = mVFS->getAbsoluteFileName(path);
|
||||||
mTechniqueFileMap[absolutePath.stem().string()] = absolutePath;
|
mTechniqueFileMap[Files::pathToUnicodeString(absolutePath.stem())] = absolutePath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -387,7 +388,7 @@ namespace MWRender
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||||||
|
|
||||||
if (technique->compile())
|
if (technique->compile())
|
||||||
Log(Debug::Info) << "Reloaded technique : " << mTechniqueFileMap[technique->getName()].string();
|
Log(Debug::Info) << "Reloaded technique : " << mTechniqueFileMap[technique->getName()];
|
||||||
|
|
||||||
mReload = technique->isValid();
|
mReload = technique->isValid();
|
||||||
}
|
}
|
||||||
|
|
|
@ -369,7 +369,7 @@ namespace MWRender
|
||||||
};
|
};
|
||||||
|
|
||||||
RenderingManager::RenderingManager(osgViewer::Viewer* viewer, osg::ref_ptr<osg::Group> rootNode,
|
RenderingManager::RenderingManager(osgViewer::Viewer* viewer, osg::ref_ptr<osg::Group> rootNode,
|
||||||
Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, const std::string& resourcePath,
|
Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, const std::filesystem::path& resourcePath,
|
||||||
DetourNavigator::Navigator& navigator, const MWWorld::GroundcoverStore& groundcoverStore,
|
DetourNavigator::Navigator& navigator, const MWWorld::GroundcoverStore& groundcoverStore,
|
||||||
SceneUtil::UnrefQueue& unrefQueue)
|
SceneUtil::UnrefQueue& unrefQueue)
|
||||||
: mSkyBlending(Settings::Manager::getBool("sky blending", "Fog"))
|
: mSkyBlending(Settings::Manager::getBool("sky blending", "Fog"))
|
||||||
|
@ -1526,7 +1526,7 @@ namespace MWRender
|
||||||
updateProjectionMatrix();
|
updateProjectionMatrix();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void RenderingManager::exportSceneGraph(const MWWorld::Ptr &ptr, const std::string &filename, const std::string &format)
|
void RenderingManager::exportSceneGraph(const MWWorld::Ptr &ptr, const std::filesystem::path& filename, const std::string &format)
|
||||||
{
|
{
|
||||||
osg::Node* node = mViewer->getSceneData();
|
osg::Node* node = mViewer->getSceneData();
|
||||||
if (!ptr.isEmpty())
|
if (!ptr.isEmpty())
|
||||||
|
|
|
@ -102,7 +102,7 @@ namespace MWRender
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RenderingManager(osgViewer::Viewer* viewer, osg::ref_ptr<osg::Group> rootNode,
|
RenderingManager(osgViewer::Viewer* viewer, osg::ref_ptr<osg::Group> rootNode,
|
||||||
Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, const std::string& resourcePath,
|
Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, const std::filesystem::path& resourcePath,
|
||||||
DetourNavigator::Navigator& navigator, const MWWorld::GroundcoverStore& groundcoverStore,
|
DetourNavigator::Navigator& navigator, const MWWorld::GroundcoverStore& groundcoverStore,
|
||||||
SceneUtil::UnrefQueue& unrefQueue);
|
SceneUtil::UnrefQueue& unrefQueue);
|
||||||
~RenderingManager();
|
~RenderingManager();
|
||||||
|
@ -232,7 +232,7 @@ namespace MWRender
|
||||||
|
|
||||||
osg::Vec3f getHalfExtents(const MWWorld::ConstPtr& object) const;
|
osg::Vec3f getHalfExtents(const MWWorld::ConstPtr& object) const;
|
||||||
|
|
||||||
void exportSceneGraph(const MWWorld::Ptr& ptr, const std::string& filename, const std::string& format);
|
void exportSceneGraph(const MWWorld::Ptr& ptr, const std::filesystem::path& filename, const std::string& format);
|
||||||
|
|
||||||
LandManager* getLandManager() const;
|
LandManager* getLandManager() const;
|
||||||
|
|
||||||
|
|
|
@ -238,7 +238,7 @@ private:
|
||||||
float mRainIntensity;
|
float mRainIntensity;
|
||||||
};
|
};
|
||||||
|
|
||||||
osg::ref_ptr<osg::Image> readPngImage (const std::string& file)
|
osg::ref_ptr<osg::Image> readPngImage (const std::filesystem::path& file)
|
||||||
{
|
{
|
||||||
std::ifstream inStream;
|
std::ifstream inStream;
|
||||||
inStream.open(file, std::ios_base::in | std::ios_base::binary);
|
inStream.open(file, std::ios_base::in | std::ios_base::binary);
|
||||||
|
@ -444,7 +444,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
Water::Water(osg::Group *parent, osg::Group* sceneRoot, Resource::ResourceSystem *resourceSystem,
|
Water::Water(osg::Group *parent, osg::Group* sceneRoot, Resource::ResourceSystem *resourceSystem,
|
||||||
osgUtil::IncrementalCompileOperation *ico, const std::string& resourcePath)
|
osgUtil::IncrementalCompileOperation *ico, const std::filesystem::path& resourcePath)
|
||||||
: mRainIntensityUpdater(nullptr)
|
: mRainIntensityUpdater(nullptr)
|
||||||
, mParent(parent)
|
, mParent(parent)
|
||||||
, mSceneRoot(sceneRoot)
|
, mSceneRoot(sceneRoot)
|
||||||
|
@ -695,7 +695,7 @@ void Water::createShaderWaterStateSet(osg::Node* node, Reflection* reflection, R
|
||||||
osg::ref_ptr<osg::Shader> fragmentShader(shaderMgr.getShader("water_fragment.glsl", defineMap, osg::Shader::FRAGMENT));
|
osg::ref_ptr<osg::Shader> fragmentShader(shaderMgr.getShader("water_fragment.glsl", defineMap, osg::Shader::FRAGMENT));
|
||||||
osg::ref_ptr<osg::Program> program = shaderMgr.getProgram(vertexShader, fragmentShader);
|
osg::ref_ptr<osg::Program> program = shaderMgr.getProgram(vertexShader, fragmentShader);
|
||||||
|
|
||||||
osg::ref_ptr<osg::Texture2D> normalMap(new osg::Texture2D(readPngImage(mResourcePath + "/shaders/water_nm.png")));
|
osg::ref_ptr<osg::Texture2D> normalMap(new osg::Texture2D(readPngImage(mResourcePath / "shaders" / "water_nm.png")));
|
||||||
|
|
||||||
if (normalMap->getImage())
|
if (normalMap->getImage())
|
||||||
normalMap->getImage()->flipVertical();
|
normalMap->getImage()->flipVertical();
|
||||||
|
|
|
@ -65,7 +65,7 @@ namespace MWRender
|
||||||
osg::ref_ptr<Refraction> mRefraction;
|
osg::ref_ptr<Refraction> mRefraction;
|
||||||
osg::ref_ptr<Reflection> mReflection;
|
osg::ref_ptr<Reflection> mReflection;
|
||||||
|
|
||||||
const std::string mResourcePath;
|
const std::filesystem::path mResourcePath;
|
||||||
|
|
||||||
bool mEnabled;
|
bool mEnabled;
|
||||||
bool mToggled;
|
bool mToggled;
|
||||||
|
@ -90,7 +90,7 @@ namespace MWRender
|
||||||
public:
|
public:
|
||||||
Water(osg::Group* parent, osg::Group* sceneRoot,
|
Water(osg::Group* parent, osg::Group* sceneRoot,
|
||||||
Resource::ResourceSystem* resourceSystem, osgUtil::IncrementalCompileOperation* ico,
|
Resource::ResourceSystem* resourceSystem, osgUtil::IncrementalCompileOperation* ico,
|
||||||
const std::string& resourcePath);
|
const std::filesystem::path& resourcePath);
|
||||||
~Water();
|
~Water();
|
||||||
|
|
||||||
void setCullCallback(osg::Callback* callback);
|
void setCullCallback(osg::Callback* callback);
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <components/esm3/loadcrea.hpp>
|
#include <components/esm3/loadcrea.hpp>
|
||||||
|
|
||||||
#include <components/vfs/manager.hpp>
|
#include <components/vfs/manager.hpp>
|
||||||
|
#include <components/files/conversion.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
@ -1527,8 +1528,8 @@ namespace MWScript
|
||||||
runtime.getContext().report("Exporting the entire scene graph will result in a large file. Confirm this action using 'showscenegraph 1' or select an object instead.");
|
runtime.getContext().report("Exporting the entire scene graph will result in a large file. Confirm this action using 'showscenegraph 1' or select an object instead.");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const std::string& filename = MWBase::Environment::get().getWorld()->exportSceneGraph(ptr);
|
const auto filename = MWBase::Environment::get().getWorld()->exportSceneGraph(ptr);
|
||||||
runtime.getContext().report("Wrote '" + filename + "'");
|
runtime.getContext().report("Wrote '" + Files::pathToUnicodeString(filename) + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -35,7 +35,7 @@ namespace MWScript
|
||||||
mScriptBlacklist.resize (scriptBlacklist.size());
|
mScriptBlacklist.resize (scriptBlacklist.size());
|
||||||
|
|
||||||
std::transform (scriptBlacklist.begin(), scriptBlacklist.end(),
|
std::transform (scriptBlacklist.begin(), scriptBlacklist.end(),
|
||||||
mScriptBlacklist.begin(), Misc::StringUtils::lowerCase);
|
mScriptBlacklist.begin(), [](const std::string& s) { return Misc::StringUtils::lowerCase(s); });
|
||||||
std::sort (mScriptBlacklist.begin(), mScriptBlacklist.end());
|
std::sort (mScriptBlacklist.begin(), mScriptBlacklist.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
#include "character.hpp"
|
#include "character.hpp"
|
||||||
|
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
|
#include <filesystem>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include <boost/filesystem.hpp>
|
|
||||||
|
|
||||||
#include <components/esm3/esmreader.hpp>
|
|
||||||
#include <components/esm/defs.hpp>
|
#include <components/esm/defs.hpp>
|
||||||
|
#include <components/esm3/esmreader.hpp>
|
||||||
#include <components/misc/utf8stream.hpp>
|
#include <components/misc/utf8stream.hpp>
|
||||||
|
|
||||||
#include <components/misc/strings/algorithm.hpp>
|
#include <components/misc/strings/algorithm.hpp>
|
||||||
|
@ -27,14 +26,14 @@ std::string MWState::getFirstGameFile(const std::vector<std::string>& contentFil
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void MWState::Character::addSlot (const boost::filesystem::path& path, const std::string& game)
|
void MWState::Character::addSlot (const std::filesystem::path& path, const std::string& game)
|
||||||
{
|
{
|
||||||
Slot slot;
|
Slot slot;
|
||||||
slot.mPath = path;
|
slot.mPath = path;
|
||||||
slot.mTimeStamp = boost::filesystem::last_write_time (path);
|
slot.mTimeStamp = std::filesystem::last_write_time (path);
|
||||||
|
|
||||||
ESM::ESMReader reader;
|
ESM::ESMReader reader;
|
||||||
reader.open (slot.mPath.string());
|
reader.open (slot.mPath);
|
||||||
|
|
||||||
if (reader.getRecName()!=ESM::REC_SAVE)
|
if (reader.getRecName()!=ESM::REC_SAVE)
|
||||||
return; // invalid save file -> ignore
|
return; // invalid save file -> ignore
|
||||||
|
@ -71,35 +70,32 @@ void MWState::Character::addSlot (const ESM::SavedGame& profile)
|
||||||
|
|
||||||
// Append an index if necessary to ensure a unique file
|
// Append an index if necessary to ensure a unique file
|
||||||
int i=0;
|
int i=0;
|
||||||
while (boost::filesystem::exists(slot.mPath))
|
while (std::filesystem::exists(slot.mPath))
|
||||||
{
|
{
|
||||||
const std::string test = stream.str() + " - " + std::to_string(++i);
|
const std::string test = stream.str() + " - " + std::to_string(++i);
|
||||||
slot.mPath = mPath / (test + ext);
|
slot.mPath = mPath / (test + ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
slot.mProfile = profile;
|
slot.mProfile = profile;
|
||||||
slot.mTimeStamp = std::time (nullptr);
|
slot.mTimeStamp = std::filesystem::file_time_type ();
|
||||||
|
|
||||||
mSlots.push_back (slot);
|
mSlots.push_back (slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
MWState::Character::Character (const boost::filesystem::path& saves, const std::string& game)
|
MWState::Character::Character (std::filesystem::path saves, const std::string& game)
|
||||||
: mPath (saves)
|
: mPath (std::move(saves))
|
||||||
{
|
{
|
||||||
if (!boost::filesystem::is_directory (mPath))
|
if (!std::filesystem::is_directory (mPath))
|
||||||
{
|
{
|
||||||
boost::filesystem::create_directories (mPath);
|
std::filesystem::create_directories (mPath);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (boost::filesystem::directory_iterator iter (mPath);
|
for (const auto& iter : std::filesystem::directory_iterator (mPath))
|
||||||
iter!=boost::filesystem::directory_iterator(); ++iter)
|
|
||||||
{
|
{
|
||||||
boost::filesystem::path slotPath = *iter;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
addSlot (slotPath, game);
|
addSlot (iter, game);
|
||||||
}
|
}
|
||||||
catch (...) {} // ignoring bad saved game files for now
|
catch (...) {} // ignoring bad saved game files for now
|
||||||
}
|
}
|
||||||
|
@ -110,15 +106,15 @@ MWState::Character::Character (const boost::filesystem::path& saves, const std::
|
||||||
|
|
||||||
void MWState::Character::cleanup()
|
void MWState::Character::cleanup()
|
||||||
{
|
{
|
||||||
if (mSlots.size() == 0)
|
if (mSlots.empty())
|
||||||
{
|
{
|
||||||
// All slots are gone, no need to keep the empty directory
|
// All slots are gone, no need to keep the empty directory
|
||||||
if (boost::filesystem::is_directory (mPath))
|
if (std::filesystem::is_directory (mPath))
|
||||||
{
|
{
|
||||||
// Extra safety check to make sure the directory is empty (e.g. slots failed to parse header)
|
// Extra safety check to make sure the directory is empty (e.g. slots failed to parse header)
|
||||||
boost::filesystem::directory_iterator it(mPath);
|
std::filesystem::directory_iterator it(mPath);
|
||||||
if (it == boost::filesystem::directory_iterator())
|
if (it == std::filesystem::directory_iterator())
|
||||||
boost::filesystem::remove_all(mPath);
|
std::filesystem::remove_all(mPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -140,7 +136,7 @@ void MWState::Character::deleteSlot (const Slot *slot)
|
||||||
throw std::logic_error ("slot not found");
|
throw std::logic_error ("slot not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::filesystem::remove(slot->mPath);
|
std::filesystem::remove(slot->mPath);
|
||||||
|
|
||||||
mSlots.erase (mSlots.begin()+index);
|
mSlots.erase (mSlots.begin()+index);
|
||||||
}
|
}
|
||||||
|
@ -157,7 +153,7 @@ const MWState::Slot *MWState::Character::updateSlot (const Slot *slot, const ESM
|
||||||
|
|
||||||
Slot newSlot = *slot;
|
Slot newSlot = *slot;
|
||||||
newSlot.mProfile = profile;
|
newSlot.mProfile = profile;
|
||||||
newSlot.mTimeStamp = std::time (nullptr);
|
newSlot.mTimeStamp = std::filesystem::file_time_type ();
|
||||||
|
|
||||||
mSlots.erase (mSlots.begin()+index);
|
mSlots.erase (mSlots.begin()+index);
|
||||||
|
|
||||||
|
@ -195,7 +191,7 @@ ESM::SavedGame MWState::Character::getSignature() const
|
||||||
return slot.mProfile;
|
return slot.mProfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
const boost::filesystem::path& MWState::Character::getPath() const
|
const std::filesystem::path& MWState::Character::getPath() const
|
||||||
{
|
{
|
||||||
return mPath;
|
return mPath;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef GAME_STATE_CHARACTER_H
|
#ifndef GAME_STATE_CHARACTER_H
|
||||||
#define GAME_STATE_CHARACTER_H
|
#define GAME_STATE_CHARACTER_H
|
||||||
|
|
||||||
#include <boost/filesystem/path.hpp>
|
#include <filesystem>
|
||||||
|
|
||||||
#include <components/esm3/savedgame.hpp>
|
#include <components/esm3/savedgame.hpp>
|
||||||
|
|
||||||
|
@ -9,9 +9,9 @@ namespace MWState
|
||||||
{
|
{
|
||||||
struct Slot
|
struct Slot
|
||||||
{
|
{
|
||||||
boost::filesystem::path mPath;
|
std::filesystem::path mPath;
|
||||||
ESM::SavedGame mProfile;
|
ESM::SavedGame mProfile;
|
||||||
std::time_t mTimeStamp;
|
std::filesystem::file_time_type mTimeStamp;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool operator< (const Slot& left, const Slot& right);
|
bool operator< (const Slot& left, const Slot& right);
|
||||||
|
@ -26,16 +26,16 @@ namespace MWState
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
boost::filesystem::path mPath;
|
std::filesystem::path mPath;
|
||||||
std::vector<Slot> mSlots;
|
std::vector<Slot> mSlots;
|
||||||
|
|
||||||
void addSlot (const boost::filesystem::path& path, const std::string& game);
|
void addSlot (const std::filesystem::path& path, const std::string& game);
|
||||||
|
|
||||||
void addSlot (const ESM::SavedGame& profile);
|
void addSlot (const ESM::SavedGame& profile);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Character (const boost::filesystem::path& saves, const std::string& game);
|
Character (std::filesystem::path saves, const std::string& game);
|
||||||
|
|
||||||
void cleanup();
|
void cleanup();
|
||||||
///< Delete the directory we used, if it is empty
|
///< Delete the directory we used, if it is empty
|
||||||
|
@ -60,7 +60,7 @@ namespace MWState
|
||||||
|
|
||||||
SlotIterator end() const;
|
SlotIterator end() const;
|
||||||
|
|
||||||
const boost::filesystem::path& getPath() const;
|
const std::filesystem::path& getPath() const;
|
||||||
|
|
||||||
ESM::SavedGame getSignature() const;
|
ESM::SavedGame getSignature() const;
|
||||||
///< Return signature information for this character.
|
///< Return signature information for this character.
|
||||||
|
|
|
@ -2,27 +2,27 @@
|
||||||
|
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <filesystem>
|
||||||
#include <boost/filesystem.hpp>
|
#include <utility>
|
||||||
|
|
||||||
#include <components/misc/utf8stream.hpp>
|
#include <components/misc/utf8stream.hpp>
|
||||||
|
|
||||||
MWState::CharacterManager::CharacterManager (const boost::filesystem::path& saves,
|
MWState::CharacterManager::CharacterManager (std::filesystem::path saves,
|
||||||
const std::vector<std::string>& contentFiles)
|
const std::vector<std::string>& contentFiles)
|
||||||
: mPath (saves), mCurrent (nullptr), mGame (getFirstGameFile(contentFiles))
|
: mPath (std::move(saves)), mCurrent (nullptr), mGame (getFirstGameFile(contentFiles))
|
||||||
{
|
{
|
||||||
if (!boost::filesystem::is_directory (mPath))
|
if (!std::filesystem::is_directory (mPath))
|
||||||
{
|
{
|
||||||
boost::filesystem::create_directories (mPath);
|
std::filesystem::create_directories (mPath);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (boost::filesystem::directory_iterator iter (mPath);
|
for (std::filesystem::directory_iterator iter (mPath);
|
||||||
iter!=boost::filesystem::directory_iterator(); ++iter)
|
iter!=std::filesystem::directory_iterator(); ++iter)
|
||||||
{
|
{
|
||||||
boost::filesystem::path characterDir = *iter;
|
std::filesystem::path characterDir = *iter;
|
||||||
|
|
||||||
if (boost::filesystem::is_directory (characterDir))
|
if (std::filesystem::is_directory (characterDir))
|
||||||
{
|
{
|
||||||
Character character (characterDir, mGame);
|
Character character (characterDir, mGame);
|
||||||
|
|
||||||
|
@ -69,11 +69,11 @@ MWState::Character* MWState::CharacterManager::createCharacter(const std::string
|
||||||
stream << '_';
|
stream << '_';
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::filesystem::path path = mPath / stream.str();
|
std::filesystem::path path = mPath / stream.str();
|
||||||
|
|
||||||
// Append an index if necessary to ensure a unique directory
|
// Append an index if necessary to ensure a unique directory
|
||||||
int i=0;
|
int i=0;
|
||||||
while (boost::filesystem::exists(path))
|
while (std::filesystem::exists(path))
|
||||||
{
|
{
|
||||||
std::ostringstream test;
|
std::ostringstream test;
|
||||||
test << stream.str();
|
test << stream.str();
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
#ifndef GAME_STATE_CHARACTERMANAGER_H
|
#ifndef GAME_STATE_CHARACTERMANAGER_H
|
||||||
#define GAME_STATE_CHARACTERMANAGER_H
|
#define GAME_STATE_CHARACTERMANAGER_H
|
||||||
|
|
||||||
#include <boost/filesystem/path.hpp>
|
#include <filesystem>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
#include "character.hpp"
|
#include "character.hpp"
|
||||||
|
|
||||||
|
@ -9,7 +10,7 @@ namespace MWState
|
||||||
{
|
{
|
||||||
class CharacterManager
|
class CharacterManager
|
||||||
{
|
{
|
||||||
boost::filesystem::path mPath;
|
std::filesystem::path mPath;
|
||||||
|
|
||||||
// Uses std::list, so that mCurrent stays valid when characters are deleted
|
// Uses std::list, so that mCurrent stays valid when characters are deleted
|
||||||
std::list<Character> mCharacters;
|
std::list<Character> mCharacters;
|
||||||
|
@ -29,7 +30,7 @@ namespace MWState
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
CharacterManager (const boost::filesystem::path& saves, const std::vector<std::string>& contentFiles);
|
CharacterManager (std::filesystem::path saves, const std::vector<std::string>& contentFiles);
|
||||||
|
|
||||||
Character *getCurrentCharacter ();
|
Character *getCurrentCharacter ();
|
||||||
///< @note May return null
|
///< @note May return null
|
||||||
|
|
|
@ -13,14 +13,12 @@
|
||||||
#include <components/loadinglistener/loadinglistener.hpp>
|
#include <components/loadinglistener/loadinglistener.hpp>
|
||||||
|
|
||||||
#include <components/settings/settings.hpp>
|
#include <components/settings/settings.hpp>
|
||||||
|
#include <components/files/conversion.hpp>
|
||||||
|
|
||||||
#include <osg/Image>
|
#include <osg/Image>
|
||||||
|
|
||||||
#include <osgDB/Registry>
|
#include <osgDB/Registry>
|
||||||
|
|
||||||
#include <boost/filesystem/fstream.hpp>
|
|
||||||
#include <boost/filesystem/operations.hpp>
|
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
#include "../mwbase/journal.hpp"
|
#include "../mwbase/journal.hpp"
|
||||||
|
@ -91,7 +89,7 @@ std::map<int, int> MWState::StateManager::buildContentFileIndexMap (const ESM::E
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
MWState::StateManager::StateManager (const boost::filesystem::path& saves, const std::vector<std::string>& contentFiles)
|
MWState::StateManager::StateManager (const std::filesystem::path& saves, const std::vector<std::string>& contentFiles)
|
||||||
: mQuitRequest (false), mAskLoadRecent(false), mState (State_NoGame), mCharacterManager (saves, contentFiles), mTimePlayed (0)
|
: mQuitRequest (false), mAskLoadRecent(false), mState (State_NoGame), mCharacterManager (saves, contentFiles), mTimePlayed (0)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -301,14 +299,14 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot
|
||||||
throw std::runtime_error("Write operation failed (memory stream)");
|
throw std::runtime_error("Write operation failed (memory stream)");
|
||||||
|
|
||||||
// All good, write to file
|
// All good, write to file
|
||||||
boost::filesystem::ofstream filestream (slot->mPath, std::ios::binary);
|
std::ofstream filestream (slot->mPath, std::ios::binary);
|
||||||
filestream << stream.rdbuf();
|
filestream << stream.rdbuf();
|
||||||
|
|
||||||
if (filestream.fail())
|
if (filestream.fail())
|
||||||
throw std::runtime_error("Write operation failed (file stream)");
|
throw std::runtime_error("Write operation failed (file stream)");
|
||||||
|
|
||||||
Settings::Manager::setString ("character", "Saves",
|
Settings::Manager::setString ("character", "Saves",
|
||||||
slot->mPath.parent_path().filename().string());
|
Files::pathToUnicodeString(slot->mPath.parent_path().filename()));
|
||||||
|
|
||||||
const auto finish = std::chrono::steady_clock::now();
|
const auto finish = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
|
@ -327,7 +325,7 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot
|
||||||
MWBase::Environment::get().getWindowManager()->interactiveMessageBox(error.str(), buttons);
|
MWBase::Environment::get().getWindowManager()->interactiveMessageBox(error.str(), buttons);
|
||||||
|
|
||||||
// If no file was written, clean up the slot
|
// If no file was written, clean up the slot
|
||||||
if (character && slot && !boost::filesystem::exists(slot->mPath))
|
if (character && slot && !std::filesystem::exists(slot->mPath))
|
||||||
{
|
{
|
||||||
character->deleteSlot(slot);
|
character->deleteSlot(slot);
|
||||||
character->cleanup();
|
character->cleanup();
|
||||||
|
@ -367,15 +365,15 @@ void MWState::StateManager::quickSave (std::string name)
|
||||||
saveGame(name, saveFinder.getNextQuickSaveSlot());
|
saveGame(name, saveFinder.getNextQuickSaveSlot());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MWState::StateManager::loadGame(const std::string& filepath)
|
void MWState::StateManager::loadGame(const std::filesystem::path &filepath)
|
||||||
{
|
{
|
||||||
for (const auto& character : mCharacterManager)
|
for (const auto& character : mCharacterManager)
|
||||||
{
|
{
|
||||||
for (const auto& slot : character)
|
for (const auto& slot : character)
|
||||||
{
|
{
|
||||||
if (slot.mPath == boost::filesystem::path(filepath))
|
if (slot.mPath == filepath)
|
||||||
{
|
{
|
||||||
loadGame(&character, slot.mPath.string());
|
loadGame(&character, slot.mPath);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -385,13 +383,13 @@ void MWState::StateManager::loadGame(const std::string& filepath)
|
||||||
loadGame(character, filepath);
|
loadGame(character, filepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MWState::StateManager::loadGame (const Character *character, const std::string& filepath)
|
void MWState::StateManager::loadGame (const Character *character, const std::filesystem::path &filepath)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|
||||||
Log(Debug::Info) << "Reading save file " << std::filesystem::path(filepath).filename().string();
|
Log(Debug::Info) << "Reading save file " << filepath.filename();
|
||||||
|
|
||||||
ESM::ESMReader reader;
|
ESM::ESMReader reader;
|
||||||
reader.open (filepath);
|
reader.open (filepath);
|
||||||
|
@ -524,7 +522,7 @@ void MWState::StateManager::loadGame (const Character *character, const std::str
|
||||||
|
|
||||||
if (character)
|
if (character)
|
||||||
Settings::Manager::setString ("character", "Saves",
|
Settings::Manager::setString ("character", "Saves",
|
||||||
character->getPath().filename().string());
|
Files::pathToUnicodeString(character->getPath().filename()));
|
||||||
|
|
||||||
MWBase::Environment::get().getWindowManager()->setNewGame(false);
|
MWBase::Environment::get().getWindowManager()->setNewGame(false);
|
||||||
MWBase::Environment::get().getWorld()->saveLoaded();
|
MWBase::Environment::get().getWorld()->saveLoaded();
|
||||||
|
@ -596,7 +594,7 @@ void MWState::StateManager::quickLoad()
|
||||||
{
|
{
|
||||||
if (currentCharacter->begin() == currentCharacter->end())
|
if (currentCharacter->begin() == currentCharacter->end())
|
||||||
return;
|
return;
|
||||||
loadGame (currentCharacter, currentCharacter->begin()->mPath.string()); //Get newest save
|
loadGame (currentCharacter, currentCharacter->begin()->mPath); //Get newest save
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -635,7 +633,7 @@ void MWState::StateManager::update (float duration)
|
||||||
//Load last saved game for current character
|
//Load last saved game for current character
|
||||||
|
|
||||||
MWState::Slot lastSave = *curCharacter->begin();
|
MWState::Slot lastSave = *curCharacter->begin();
|
||||||
loadGame(curCharacter, lastSave.mPath.string());
|
loadGame(curCharacter, lastSave.mPath);
|
||||||
}
|
}
|
||||||
else if(iButton==1)
|
else if(iButton==1)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,11 +2,10 @@
|
||||||
#define GAME_STATE_STATEMANAGER_H
|
#define GAME_STATE_STATEMANAGER_H
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
#include "../mwbase/statemanager.hpp"
|
#include "../mwbase/statemanager.hpp"
|
||||||
|
|
||||||
#include <boost/filesystem/path.hpp>
|
|
||||||
|
|
||||||
#include "charactermanager.hpp"
|
#include "charactermanager.hpp"
|
||||||
|
|
||||||
namespace MWState
|
namespace MWState
|
||||||
|
@ -31,7 +30,7 @@ namespace MWState
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
StateManager (const boost::filesystem::path& saves, const std::vector<std::string>& contentFiles);
|
StateManager (const std::filesystem::path& saves, const std::vector<std::string>& contentFiles);
|
||||||
|
|
||||||
void requestQuit() override;
|
void requestQuit() override;
|
||||||
|
|
||||||
|
@ -67,12 +66,12 @@ namespace MWState
|
||||||
/** Used for quickload **/
|
/** Used for quickload **/
|
||||||
void quickLoad() override;
|
void quickLoad() override;
|
||||||
|
|
||||||
void loadGame (const std::string& filepath) override;
|
void loadGame (const std::filesystem::path &filepath) override;
|
||||||
///< Load a saved game directly from the given file path. This will search the CharacterManager
|
///< Load a saved game directly from the given file path. This will search the CharacterManager
|
||||||
/// for a Character containing this save file, and set this Character current if one was found.
|
/// for a Character containing this save file, and set this Character current if one was found.
|
||||||
/// Otherwise, a new Character will be created.
|
/// Otherwise, a new Character will be created.
|
||||||
|
|
||||||
void loadGame (const Character *character, const std::string &filepath) override;
|
void loadGame (const Character *character, const std::filesystem::path &filepath) override;
|
||||||
///< Load a saved game file belonging to the given character.
|
///< Load a saved game file belonging to the given character.
|
||||||
|
|
||||||
Character *getCurrentCharacter () override;
|
Character *getCurrentCharacter () override;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef CONTENTLOADER_HPP
|
#ifndef CONTENTLOADER_HPP
|
||||||
#define CONTENTLOADER_HPP
|
#define CONTENTLOADER_HPP
|
||||||
|
|
||||||
#include <boost/filesystem/path.hpp>
|
#include <filesystem>
|
||||||
|
|
||||||
namespace Loading
|
namespace Loading
|
||||||
{
|
{
|
||||||
|
@ -15,7 +15,7 @@ struct ContentLoader
|
||||||
{
|
{
|
||||||
virtual ~ContentLoader() = default;
|
virtual ~ContentLoader() = default;
|
||||||
|
|
||||||
virtual void load(const boost::filesystem::path& filepath, int& index, Loading::Listener* listener) = 0;
|
virtual void load(const std::filesystem::path& filepath, int& index, Loading::Listener* listener) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace MWWorld */
|
} /* namespace MWWorld */
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <components/esm3/esmreader.hpp>
|
#include <components/esm3/esmreader.hpp>
|
||||||
#include <components/esm3/readerscache.hpp>
|
#include <components/esm3/readerscache.hpp>
|
||||||
|
#include <components/files/conversion.hpp>
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
|
@ -16,19 +17,19 @@ EsmLoader::EsmLoader(MWWorld::ESMStore& store, ESM::ReadersCache& readers, ToUTF
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void EsmLoader::load(const boost::filesystem::path& filepath, int& index, Loading::Listener* listener)
|
void EsmLoader::load(const std::filesystem::path& filepath, int& index, Loading::Listener* listener)
|
||||||
{
|
{
|
||||||
const ESM::ReadersCache::BusyItem reader = mReaders.get(static_cast<std::size_t>(index));
|
const ESM::ReadersCache::BusyItem reader = mReaders.get(static_cast<std::size_t>(index));
|
||||||
|
|
||||||
reader->setEncoder(mEncoder);
|
reader->setEncoder(mEncoder);
|
||||||
reader->setIndex(index);
|
reader->setIndex(index);
|
||||||
reader->open(filepath.string());
|
reader->open(filepath);
|
||||||
reader->resolveParentFileIndices(mReaders);
|
reader->resolveParentFileIndices(mReaders);
|
||||||
|
|
||||||
assert(reader->getGameFiles().size() == reader->getParentFileIndices().size());
|
assert(reader->getGameFiles().size() == reader->getParentFileIndices().size());
|
||||||
for (std::size_t i = 0, n = reader->getParentFileIndices().size(); i < n; ++i)
|
for (std::size_t i = 0, n = reader->getParentFileIndices().size(); i < n; ++i)
|
||||||
if (i == static_cast<std::size_t>(reader->getIndex()))
|
if (i == static_cast<std::size_t>(reader->getIndex()))
|
||||||
throw std::runtime_error("File " + reader->getName() + " asks for parent file "
|
throw std::runtime_error("File " + Files::pathToUnicodeString(reader->getName()) + " asks for parent file "
|
||||||
+ reader->getGameFiles()[i].name
|
+ reader->getGameFiles()[i].name
|
||||||
+ ", but it is not available or has been loaded in the wrong order. "
|
+ ", but it is not available or has been loaded in the wrong order. "
|
||||||
"Please run the launcher to fix this issue.");
|
"Please run the launcher to fix this issue.");
|
||||||
|
@ -36,8 +37,8 @@ void EsmLoader::load(const boost::filesystem::path& filepath, int& index, Loadin
|
||||||
mESMVersions[index] = reader->getVer();
|
mESMVersions[index] = reader->getVer();
|
||||||
mStore.load(*reader, listener, mDialogue);
|
mStore.load(*reader, listener, mDialogue);
|
||||||
|
|
||||||
if (!mMasterFileFormat.has_value() && (Misc::StringUtils::ciEndsWith(reader->getName(), ".esm")
|
if (!mMasterFileFormat.has_value() && (Misc::StringUtils::ciEndsWith(reader->getName().u8string(), u8".esm")
|
||||||
|| Misc::StringUtils::ciEndsWith(reader->getName(), ".omwgame")))
|
|| Misc::StringUtils::ciEndsWith(reader->getName().u8string(), u8".omwgame")))
|
||||||
mMasterFileFormat = reader->getFormat();
|
mMasterFileFormat = reader->getFormat();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define ESMLOADER_HPP
|
#define ESMLOADER_HPP
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "contentloader.hpp"
|
#include "contentloader.hpp"
|
||||||
|
|
||||||
|
@ -27,7 +28,7 @@ struct EsmLoader : public ContentLoader
|
||||||
|
|
||||||
std::optional<int> getMasterFileFormat() const { return mMasterFileFormat; }
|
std::optional<int> getMasterFileFormat() const { return mMasterFileFormat; }
|
||||||
|
|
||||||
void load(const boost::filesystem::path& filepath, int& index, Loading::Listener* listener) override;
|
void load(const std::filesystem::path& filepath, int& index, Loading::Listener* listener) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ESM::ReadersCache& mReaders;
|
ESM::ReadersCache& mReaders;
|
||||||
|
|
|
@ -321,13 +321,13 @@ ESM::LuaScriptsCfg ESMStore::getLuaScriptsCfg() const
|
||||||
ESM::LuaScriptsCfg cfg;
|
ESM::LuaScriptsCfg cfg;
|
||||||
for (const LuaContent& c : mLuaContent)
|
for (const LuaContent& c : mLuaContent)
|
||||||
{
|
{
|
||||||
if (std::holds_alternative<std::string>(c))
|
if (std::holds_alternative<std::filesystem::path>(c))
|
||||||
{
|
{
|
||||||
// *.omwscripts are intentionally reloaded every time when `getLuaScriptsCfg` is called.
|
// *.omwscripts are intentionally reloaded every time when `getLuaScriptsCfg` is called.
|
||||||
// It is important for the `reloadlua` console command.
|
// It is important for the `reloadlua` console command.
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
auto file = std::ifstream(std::get<std::string>(c));
|
auto file = std::ifstream(std::get<std::filesystem::path>(c));
|
||||||
std::string fileContent(std::istreambuf_iterator<char>(file), {});
|
std::string fileContent(std::istreambuf_iterator<char>(file), {});
|
||||||
LuaUtil::parseOMWScripts(cfg, fileContent);
|
LuaUtil::parseOMWScripts(cfg, fileContent);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
#include <components/esm/luascripts.hpp>
|
#include <components/esm/luascripts.hpp>
|
||||||
#include <components/esm3/loadgmst.hpp>
|
#include <components/esm3/loadgmst.hpp>
|
||||||
|
@ -159,11 +160,11 @@ namespace MWWorld
|
||||||
|
|
||||||
using LuaContent = std::variant<
|
using LuaContent = std::variant<
|
||||||
ESM::LuaScriptsCfg, // data from an omwaddon
|
ESM::LuaScriptsCfg, // data from an omwaddon
|
||||||
std::string>; // path to an omwscripts file
|
std::filesystem::path>; // path to an omwscripts file
|
||||||
std::vector<LuaContent> mLuaContent;
|
std::vector<LuaContent> mLuaContent;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void addOMWScripts(std::string filePath) { mLuaContent.push_back(std::move(filePath)); }
|
void addOMWScripts(std::filesystem::path filePath) { mLuaContent.push_back(std::move(filePath)); }
|
||||||
ESM::LuaScriptsCfg getLuaScriptsCfg() const;
|
ESM::LuaScriptsCfg getLuaScriptsCfg() const;
|
||||||
|
|
||||||
/// \todo replace with SharedIterator<StoreBase>
|
/// \todo replace with SharedIterator<StoreBase>
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#include <components/detournavigator/navigatorimpl.hpp>
|
#include <components/detournavigator/navigatorimpl.hpp>
|
||||||
|
|
||||||
#include <components/loadinglistener/loadinglistener.hpp>
|
#include <components/loadinglistener/loadinglistener.hpp>
|
||||||
|
#include <components/files/conversion.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/soundmanager.hpp"
|
#include "../mwbase/soundmanager.hpp"
|
||||||
|
@ -102,21 +103,21 @@ namespace MWWorld
|
||||||
mLoaders.emplace(std::move(extension), &loader);
|
mLoaders.emplace(std::move(extension), &loader);
|
||||||
}
|
}
|
||||||
|
|
||||||
void load(const boost::filesystem::path& filepath, int& index, Loading::Listener* listener) override
|
void load(const std::filesystem::path& filepath, int& index, Loading::Listener* listener) override
|
||||||
{
|
{
|
||||||
const auto it = mLoaders.find(Misc::StringUtils::lowerCase(filepath.extension().string()));
|
const auto it = mLoaders.find(Misc::StringUtils::lowerCase( Files::pathToUnicodeString(filepath.extension())));
|
||||||
if (it != mLoaders.end())
|
if (it != mLoaders.end())
|
||||||
{
|
{
|
||||||
const std::string filename = filepath.filename().string();
|
const auto filename = filepath.filename();
|
||||||
Log(Debug::Info) << "Loading content file " << filename;
|
Log(Debug::Info) << "Loading content file " << filename;
|
||||||
if (listener != nullptr)
|
if (listener != nullptr)
|
||||||
listener->setLabel(MyGUI::TextIterator::toTagsString(filename));
|
listener->setLabel(MyGUI::TextIterator::toTagsString(Files::pathToUnicodeString(filename)));
|
||||||
it->second->load(filepath, index, listener);
|
it->second->load(filepath, index, listener);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::string msg("Cannot load file: ");
|
std::string msg("Cannot load file: ");
|
||||||
msg += filepath.string();
|
msg += Files::pathToUnicodeString(filepath);
|
||||||
throw std::runtime_error(msg.c_str());
|
throw std::runtime_error(msg.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,9 +130,9 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
ESMStore& mStore;
|
ESMStore& mStore;
|
||||||
OMWScriptsLoader(ESMStore& store) : mStore(store) {}
|
OMWScriptsLoader(ESMStore& store) : mStore(store) {}
|
||||||
void load(const boost::filesystem::path& filepath, int& /*index*/, Loading::Listener* /*listener*/) override
|
void load(const std::filesystem::path& filepath, int& /*index*/, Loading::Listener* /*listener*/) override
|
||||||
{
|
{
|
||||||
mStore.addOMWScripts(filepath.string());
|
mStore.addOMWScripts(filepath);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -156,7 +157,7 @@ namespace MWWorld
|
||||||
const std::vector<std::string>& groundcoverFiles,
|
const std::vector<std::string>& groundcoverFiles,
|
||||||
ToUTF8::Utf8Encoder* encoder, int activationDistanceOverride,
|
ToUTF8::Utf8Encoder* encoder, int activationDistanceOverride,
|
||||||
const std::string& startCell, const std::string& startupScript,
|
const std::string& startCell, const std::string& startupScript,
|
||||||
const std::string& resourcePath, const std::string& userDataPath)
|
const std::filesystem::path& resourcePath, const std::filesystem::path& userDataPath)
|
||||||
: mResourceSystem(resourceSystem), mLocalScripts(mStore),
|
: mResourceSystem(resourceSystem), mLocalScripts(mStore),
|
||||||
mCells(mStore, mReaders), mSky(true),
|
mCells(mStore, mReaders), mSky(true),
|
||||||
mGodMode(false), mScriptsEnabled(true), mDiscardMovements(true), mContentFiles (contentFiles),
|
mGodMode(false), mScriptsEnabled(true), mDiscardMovements(true), mContentFiles (contentFiles),
|
||||||
|
@ -2963,8 +2964,8 @@ namespace MWWorld
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
for (const std::string &file : content)
|
for (const std::string &file : content)
|
||||||
{
|
{
|
||||||
boost::filesystem::path filename(file);
|
const auto filename = Files::pathFromUnicodeString( file);
|
||||||
const Files::MultiDirCollection& col = fileCollections.getCollection(filename.extension().string());
|
const Files::MultiDirCollection& col = fileCollections.getCollection(Files::pathToUnicodeString(filename.extension()));
|
||||||
if (col.doesExist(file))
|
if (col.doesExist(file))
|
||||||
{
|
{
|
||||||
gameContentLoader.load(col.getPath(file), idx, listener);
|
gameContentLoader.load(col.getPath(file), idx, listener);
|
||||||
|
@ -3694,9 +3695,9 @@ namespace MWWorld
|
||||||
return mPhysics->getHalfExtents(object);
|
return mPhysics->getHalfExtents(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string World::exportSceneGraph(const Ptr &ptr)
|
std::filesystem::path World::exportSceneGraph(const Ptr& ptr)
|
||||||
{
|
{
|
||||||
std::string file = mUserDataPath + "/openmw.osgt";
|
auto file = mUserDataPath / "openmw.osgt";
|
||||||
if (!ptr.isEmpty())
|
if (!ptr.isEmpty())
|
||||||
{
|
{
|
||||||
mRendering->pagingBlacklistObject(mStore.find(ptr.getCellRef().getRefId()), ptr);
|
mRendering->pagingBlacklistObject(mStore.find(ptr.getCellRef().getRefId()), ptr);
|
||||||
|
|
|
@ -109,7 +109,7 @@ namespace MWWorld
|
||||||
bool mDiscardMovements;
|
bool mDiscardMovements;
|
||||||
std::vector<std::string> mContentFiles;
|
std::vector<std::string> mContentFiles;
|
||||||
|
|
||||||
std::string mUserDataPath;
|
std::filesystem::path mUserDataPath;
|
||||||
|
|
||||||
osg::Vec3f mDefaultHalfExtents;
|
osg::Vec3f mDefaultHalfExtents;
|
||||||
DetourNavigator::CollisionShapeType mDefaultActorCollisionShapeType;
|
DetourNavigator::CollisionShapeType mDefaultActorCollisionShapeType;
|
||||||
|
@ -203,7 +203,7 @@ namespace MWWorld
|
||||||
const std::vector<std::string>& groundcoverFiles,
|
const std::vector<std::string>& groundcoverFiles,
|
||||||
ToUTF8::Utf8Encoder* encoder, int activationDistanceOverride,
|
ToUTF8::Utf8Encoder* encoder, int activationDistanceOverride,
|
||||||
const std::string& startCell, const std::string& startupScript,
|
const std::string& startCell, const std::string& startupScript,
|
||||||
const std::string& resourcePath, const std::string& userDataPath);
|
const std::filesystem::path& resourcePath, const std::filesystem::path& userDataPath);
|
||||||
|
|
||||||
virtual ~World();
|
virtual ~World();
|
||||||
|
|
||||||
|
@ -730,7 +730,7 @@ namespace MWWorld
|
||||||
|
|
||||||
/// Export scene graph to a file and return the filename.
|
/// Export scene graph to a file and return the filename.
|
||||||
/// \param ptr object to export scene graph for (if empty, export entire scene graph)
|
/// \param ptr object to export scene graph for (if empty, export entire scene graph)
|
||||||
std::string exportSceneGraph(const MWWorld::Ptr& ptr) override;
|
std::filesystem::path exportSceneGraph(const MWWorld::Ptr& ptr) override;
|
||||||
|
|
||||||
/// Preload VFX associated with this effect list
|
/// Preload VFX associated with this effect list
|
||||||
void preloadEffects(const ESM::EffectList* effectList) override;
|
void preloadEffects(const ESM::EffectList* effectList) override;
|
||||||
|
|
|
@ -75,6 +75,7 @@ file(GLOB UNITTEST_SRC_FILES
|
||||||
esmloader/record.cpp
|
esmloader/record.cpp
|
||||||
|
|
||||||
files/hash.cpp
|
files/hash.cpp
|
||||||
|
files/conversion_tests.cpp
|
||||||
|
|
||||||
toutf8/toutf8.cpp
|
toutf8/toutf8.cpp
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ namespace
|
||||||
const Files::PathContainer mDataDirs {{std::string(OPENMW_DATA_DIR)}};
|
const Files::PathContainer mDataDirs {{std::string(OPENMW_DATA_DIR)}};
|
||||||
const Files::Collections mFileCollections {mDataDirs, true};
|
const Files::Collections mFileCollections {mDataDirs, true};
|
||||||
const std::string mContentFile = "template.omwgame";
|
const std::string mContentFile = "template.omwgame";
|
||||||
const std::string mContentFilePath = mFileCollections.getCollection(".omwgame").getPath(mContentFile).string();
|
const std::filesystem::path mContentFilePath = mFileCollections.getCollection(".omwgame").getPath(mContentFile);
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(ESM3ReadersCacheWithContentFile, shouldKeepOpenReleasedOpenReader)
|
TEST_F(ESM3ReadersCacheWithContentFile, shouldKeepOpenReleasedOpenReader)
|
||||||
|
|
25
apps/openmw_test_suite/files/conversion_tests.cpp
Normal file
25
apps/openmw_test_suite/files/conversion_tests.cpp
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#include <components/files/conversion.hpp>
|
||||||
|
#include <components/misc/strings/conversion.hpp>
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
using namespace testing;
|
||||||
|
using namespace Files;
|
||||||
|
|
||||||
|
constexpr auto test_path_u8 = u8"./tmp/ÒĎƎɠˠΏЌԹעڨ/ऊঋਐઊଊ/ஐఋಋഊ/ฎນ༈ႩᄇḮὯ⁂₁₩ℒ/Ⅷ↝∑/☝✌〥ぐズ㌎丕.갔3갛";
|
||||||
|
constexpr auto test_path = "./tmp/ÒĎƎɠˠΏЌԹעڨ/ऊঋਐઊଊ/ஐఋಋഊ/ฎນ༈ႩᄇḮὯ⁂₁₩ℒ/Ⅷ↝∑/☝✌〥ぐズ㌎丕.갔3갛";
|
||||||
|
|
||||||
|
TEST(OpenMWConversion, should_support_unicode_string_to_path)
|
||||||
|
{
|
||||||
|
auto p = Files::pathFromUnicodeString(test_path);
|
||||||
|
EXPECT_EQ(Misc::StringUtils::u8StringToString(p.u8string()), Misc::StringUtils::u8StringToString(test_path_u8));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(OpenMWConversion, should_support_path_to_unicode_string)
|
||||||
|
{
|
||||||
|
std::filesystem::path p{ test_path_u8 };
|
||||||
|
EXPECT_EQ(Files::pathToUnicodeString(p), test_path);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
#include <components/files/hash.hpp>
|
#include <components/files/hash.hpp>
|
||||||
#include <components/files/constrainedfilestream.hpp>
|
#include <components/files/constrainedfilestream.hpp>
|
||||||
|
#include <components/files/conversion.hpp>
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <gmock/gmock.h>
|
#include <gmock/gmock.h>
|
||||||
|
@ -27,7 +28,7 @@ namespace
|
||||||
|
|
||||||
TEST(FilesGetHash, shouldClearErrors)
|
TEST(FilesGetHash, shouldClearErrors)
|
||||||
{
|
{
|
||||||
const std::string fileName = temporaryFilePath("fileName");
|
const auto fileName = temporaryFilePath("fileName");
|
||||||
std::string content;
|
std::string content;
|
||||||
std::fill_n(std::back_inserter(content), 1, 'a');
|
std::fill_n(std::back_inserter(content), 1, 'a');
|
||||||
std::istringstream stream(content);
|
std::istringstream stream(content);
|
||||||
|
@ -37,7 +38,7 @@ namespace
|
||||||
|
|
||||||
TEST_P(FilesGetHash, shouldReturnHashForStringStream)
|
TEST_P(FilesGetHash, shouldReturnHashForStringStream)
|
||||||
{
|
{
|
||||||
const std::string fileName = temporaryFilePath("fileName");
|
const auto fileName = temporaryFilePath("fileName");
|
||||||
std::string content;
|
std::string content;
|
||||||
std::fill_n(std::back_inserter(content), GetParam().mSize, 'a');
|
std::fill_n(std::back_inserter(content), GetParam().mSize, 'a');
|
||||||
std::istringstream stream(content);
|
std::istringstream stream(content);
|
||||||
|
@ -50,11 +51,11 @@ namespace
|
||||||
std::replace(fileName.begin(), fileName.end(), '/', '_');
|
std::replace(fileName.begin(), fileName.end(), '/', '_');
|
||||||
std::string content;
|
std::string content;
|
||||||
std::fill_n(std::back_inserter(content), GetParam().mSize, 'a');
|
std::fill_n(std::back_inserter(content), GetParam().mSize, 'a');
|
||||||
fileName = outputFilePath(fileName);
|
const auto file = outputFilePath(fileName);
|
||||||
std::fstream(fileName, std::ios_base::out | std::ios_base::binary)
|
std::fstream(file, std::ios_base::out | std::ios_base::binary)
|
||||||
.write(content.data(), static_cast<std::streamsize>(content.size()));
|
.write(content.data(), static_cast<std::streamsize>(content.size()));
|
||||||
const auto stream = Files::openConstrainedFileStream(fileName, 0, content.size());
|
const auto stream = Files::openConstrainedFileStream(file, 0, content.size());
|
||||||
EXPECT_EQ(getHash(fileName, *stream), GetParam().mHash);
|
EXPECT_EQ(getHash(file, *stream), GetParam().mHash);
|
||||||
}
|
}
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(Params, FilesGetHash, Values(
|
INSTANTIATE_TEST_SUITE_P(Params, FilesGetHash, Values(
|
||||||
|
|
|
@ -88,7 +88,7 @@ namespace
|
||||||
mLua.safe_script("permanent:set('x', 1)");
|
mLua.safe_script("permanent:set('x', 1)");
|
||||||
mLua.safe_script("temporary:set('y', 2)");
|
mLua.safe_script("temporary:set('y', 2)");
|
||||||
|
|
||||||
std::string tmpFile = (std::filesystem::temp_directory_path() / "test_storage.bin").string();
|
const auto tmpFile = std::filesystem::temp_directory_path() / "test_storage.bin";
|
||||||
storage.save(tmpFile);
|
storage.save(tmpFile);
|
||||||
EXPECT_EQ(get<int>(mLua, "permanent:get('x')"), 1);
|
EXPECT_EQ(get<int>(mLua, "permanent:get('x')"), 1);
|
||||||
EXPECT_EQ(get<int>(mLua, "temporary:get('y')"), 2);
|
EXPECT_EQ(get<int>(mLua, "temporary:get('y')"), 2);
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <components/esm/records.hpp>
|
#include <components/esm/records.hpp>
|
||||||
#include <components/loadinglistener/loadinglistener.hpp>
|
#include <components/loadinglistener/loadinglistener.hpp>
|
||||||
#include <components/misc/strings/algorithm.hpp>
|
#include <components/misc/strings/algorithm.hpp>
|
||||||
|
#include <components/files/conversion.hpp>
|
||||||
|
|
||||||
#include "apps/openmw/mwworld/esmstore.hpp"
|
#include "apps/openmw/mwworld/esmstore.hpp"
|
||||||
#include "apps/openmw/mwmechanics/spelllist.hpp"
|
#include "apps/openmw/mwmechanics/spelllist.hpp"
|
||||||
|
@ -41,7 +42,7 @@ struct ContentFileTest : public ::testing::Test
|
||||||
ESM::ESMReader lEsm;
|
ESM::ESMReader lEsm;
|
||||||
lEsm.setEncoder(nullptr);
|
lEsm.setEncoder(nullptr);
|
||||||
lEsm.setIndex(index);
|
lEsm.setIndex(index);
|
||||||
lEsm.open(mContentFile.string());
|
lEsm.open(mContentFile);
|
||||||
mEsmStore.load(lEsm, &dummyListener, dialogue);
|
mEsmStore.load(lEsm, &dummyListener, dialogue);
|
||||||
|
|
||||||
++index;
|
++index;
|
||||||
|
@ -74,7 +75,7 @@ struct ContentFileTest : public ::testing::Test
|
||||||
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());
|
||||||
if (!local.empty())
|
if (!local.empty())
|
||||||
dataLocal.push_back(local);
|
dataLocal.push_back(local);
|
||||||
|
|
||||||
|
@ -97,7 +98,7 @@ struct ContentFileTest : public ::testing::Test
|
||||||
protected:
|
protected:
|
||||||
Files::ConfigurationManager mConfigurationManager;
|
Files::ConfigurationManager mConfigurationManager;
|
||||||
MWWorld::ESMStore mEsmStore;
|
MWWorld::ESMStore mEsmStore;
|
||||||
std::vector<boost::filesystem::path> mContentFiles;
|
std::vector<std::filesystem::path> mContentFiles;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Print results of the dialogue merging process, i.e. the resulting linked list.
|
/// Print results of the dialogue merging process, i.e. the resulting linked list.
|
||||||
|
@ -109,7 +110,7 @@ TEST_F(ContentFileTest, dialogue_merging_test)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string file = TestingOpenMW::outputFilePath("test_dialogue_merging.txt");
|
const auto file = TestingOpenMW::outputFilePath("test_dialogue_merging.txt");
|
||||||
std::ofstream stream(file);
|
std::ofstream stream(file);
|
||||||
|
|
||||||
const MWWorld::Store<ESM::Dialogue>& dialStore = mEsmStore.get<ESM::Dialogue>();
|
const MWWorld::Store<ESM::Dialogue>& dialStore = mEsmStore.get<ESM::Dialogue>();
|
||||||
|
@ -124,7 +125,7 @@ TEST_F(ContentFileTest, dialogue_merging_test)
|
||||||
stream << std::endl;
|
stream << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "dialogue_merging_test successful, results printed to " << file << std::endl;
|
std::cout << "dialogue_merging_test successful, results printed to " << Files::pathToUnicodeString(file) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: here we don't test records that don't use string names (e.g. Land, Pathgrid, Cell)
|
// Note: here we don't test records that don't use string names (e.g. Land, Pathgrid, Cell)
|
||||||
|
@ -189,12 +190,12 @@ TEST_F(ContentFileTest, content_diagnostics_test)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string file = TestingOpenMW::outputFilePath("test_content_diagnostics.txt");
|
const auto file = TestingOpenMW::outputFilePath("test_content_diagnostics.txt");
|
||||||
std::ofstream stream(file);
|
std::ofstream stream(file);
|
||||||
|
|
||||||
RUN_TEST_FOR_TYPES(printRecords, mEsmStore, stream);
|
RUN_TEST_FOR_TYPES(printRecords, mEsmStore, stream);
|
||||||
|
|
||||||
std::cout << "diagnostics_test successful, results printed to " << file << std::endl;
|
std::cout << "diagnostics_test successful, results printed to " << Files::pathToUnicodeString(file) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
|
|
|
@ -353,7 +353,7 @@ namespace
|
||||||
MOCK_METHOD(std::string, getString, (uint32_t), (const, override));
|
MOCK_METHOD(std::string, getString, (uint32_t), (const, override));
|
||||||
MOCK_METHOD(void, setUseSkinning, (bool), (override));
|
MOCK_METHOD(void, setUseSkinning, (bool), (override));
|
||||||
MOCK_METHOD(bool, getUseSkinning, (), (const, override));
|
MOCK_METHOD(bool, getUseSkinning, (), (const, override));
|
||||||
MOCK_METHOD(std::string, getFilename, (), (const, override));
|
MOCK_METHOD(std::filesystem::path, getFilename, (), (const, override));
|
||||||
MOCK_METHOD(std::string, getHash, (), (const, override));
|
MOCK_METHOD(std::string, getHash, (), (const, override));
|
||||||
MOCK_METHOD(unsigned int, getVersion, (), (const, override));
|
MOCK_METHOD(unsigned int, getVersion, (), (const, override));
|
||||||
MOCK_METHOD(unsigned int, getUserVersion, (), (const, override));
|
MOCK_METHOD(unsigned int, getUserVersion, (), (const, override));
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include <apps/openmw/options.hpp>
|
#include <apps/openmw/options.hpp>
|
||||||
#include <components/files/configurationmanager.hpp>
|
#include <components/files/configurationmanager.hpp>
|
||||||
|
#include <components/files/conversion.hpp>
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <gmock/gmock.h>
|
#include <gmock/gmock.h>
|
||||||
|
@ -38,7 +39,7 @@ namespace
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
MATCHER_P(IsPath, v, "") { return arg.string() == v; }
|
MATCHER_P(IsPath, v, "") { return Files::pathToUnicodeString(arg) == v; }
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void parseArgs(const T& arguments, bpo::variables_map& variables, bpo::options_description& description)
|
void parseArgs(const T& arguments, bpo::variables_map& variables, bpo::options_description& description)
|
||||||
|
@ -52,7 +53,7 @@ namespace
|
||||||
const std::array arguments {"openmw", "--load-savegame=save.omwsave"};
|
const std::array arguments {"openmw", "--load-savegame=save.omwsave"};
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
parseArgs(arguments, variables, description);
|
parseArgs(arguments, variables, description);
|
||||||
EXPECT_EQ(variables["load-savegame"].as<Files::MaybeQuotedPath>().string(), "save.omwsave");
|
EXPECT_EQ(Files::pathToUnicodeString(variables["load-savegame"].as<Files::MaybeQuotedPath>()), "save.omwsave");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(OpenMWOptionsFromArguments, should_support_single_word_load_savegame_path)
|
TEST(OpenMWOptionsFromArguments, should_support_single_word_load_savegame_path)
|
||||||
|
@ -61,7 +62,7 @@ namespace
|
||||||
const std::array arguments {"openmw", "--load-savegame", "save.omwsave"};
|
const std::array arguments {"openmw", "--load-savegame", "save.omwsave"};
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
parseArgs(arguments, variables, description);
|
parseArgs(arguments, variables, description);
|
||||||
EXPECT_EQ(variables["load-savegame"].as<Files::MaybeQuotedPath>().string(), "save.omwsave");
|
EXPECT_EQ(Files::pathToUnicodeString(variables["load-savegame"].as<Files::MaybeQuotedPath>()), "save.omwsave");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(OpenMWOptionsFromArguments, should_support_multi_component_load_savegame_path)
|
TEST(OpenMWOptionsFromArguments, should_support_multi_component_load_savegame_path)
|
||||||
|
@ -70,7 +71,7 @@ namespace
|
||||||
const std::array arguments {"openmw", "--load-savegame", "/home/user/openmw/save.omwsave"};
|
const std::array arguments {"openmw", "--load-savegame", "/home/user/openmw/save.omwsave"};
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
parseArgs(arguments, variables, description);
|
parseArgs(arguments, variables, description);
|
||||||
EXPECT_EQ(variables["load-savegame"].as<Files::MaybeQuotedPath>().string(), "/home/user/openmw/save.omwsave");
|
EXPECT_EQ(Files::pathToUnicodeString(variables["load-savegame"].as<Files::MaybeQuotedPath>()), "/home/user/openmw/save.omwsave");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(OpenMWOptionsFromArguments, should_support_windows_multi_component_load_savegame_path)
|
TEST(OpenMWOptionsFromArguments, should_support_windows_multi_component_load_savegame_path)
|
||||||
|
@ -79,7 +80,7 @@ namespace
|
||||||
const std::array arguments {"openmw", "--load-savegame", R"(C:\OpenMW\save.omwsave)"};
|
const std::array arguments {"openmw", "--load-savegame", R"(C:\OpenMW\save.omwsave)"};
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
parseArgs(arguments, variables, description);
|
parseArgs(arguments, variables, description);
|
||||||
EXPECT_EQ(variables["load-savegame"].as<Files::MaybeQuotedPath>().string(), R"(C:\OpenMW\save.omwsave)");
|
EXPECT_EQ(Files::pathToUnicodeString(variables["load-savegame"].as<Files::MaybeQuotedPath>()), R"(C:\OpenMW\save.omwsave)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(OpenMWOptionsFromArguments, should_support_load_savegame_path_with_spaces)
|
TEST(OpenMWOptionsFromArguments, should_support_load_savegame_path_with_spaces)
|
||||||
|
@ -88,7 +89,7 @@ namespace
|
||||||
const std::array arguments {"openmw", "--load-savegame", "my save.omwsave"};
|
const std::array arguments {"openmw", "--load-savegame", "my save.omwsave"};
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
parseArgs(arguments, variables, description);
|
parseArgs(arguments, variables, description);
|
||||||
EXPECT_EQ(variables["load-savegame"].as<Files::MaybeQuotedPath>().string(), "my save.omwsave");
|
EXPECT_EQ(Files::pathToUnicodeString(variables["load-savegame"].as<Files::MaybeQuotedPath>()), "my save.omwsave");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(OpenMWOptionsFromArguments, should_support_load_savegame_path_with_octothorpe)
|
TEST(OpenMWOptionsFromArguments, should_support_load_savegame_path_with_octothorpe)
|
||||||
|
@ -97,7 +98,7 @@ namespace
|
||||||
const std::array arguments {"openmw", "--load-savegame", "my#save.omwsave"};
|
const std::array arguments {"openmw", "--load-savegame", "my#save.omwsave"};
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
parseArgs(arguments, variables, description);
|
parseArgs(arguments, variables, description);
|
||||||
EXPECT_EQ(variables["load-savegame"].as<Files::MaybeQuotedPath>().string(), "my#save.omwsave");
|
EXPECT_EQ(Files::pathToUnicodeString(variables["load-savegame"].as<Files::MaybeQuotedPath>()), "my#save.omwsave");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(OpenMWOptionsFromArguments, should_support_load_savegame_path_with_at_sign)
|
TEST(OpenMWOptionsFromArguments, should_support_load_savegame_path_with_at_sign)
|
||||||
|
@ -106,7 +107,7 @@ namespace
|
||||||
const std::array arguments {"openmw", "--load-savegame", "my@save.omwsave"};
|
const std::array arguments {"openmw", "--load-savegame", "my@save.omwsave"};
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
parseArgs(arguments, variables, description);
|
parseArgs(arguments, variables, description);
|
||||||
EXPECT_EQ(variables["load-savegame"].as<Files::MaybeQuotedPath>().string(), "my@save.omwsave");
|
EXPECT_EQ(Files::pathToUnicodeString(variables["load-savegame"].as<Files::MaybeQuotedPath>()), "my@save.omwsave");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(OpenMWOptionsFromArguments, should_support_load_savegame_path_with_quote)
|
TEST(OpenMWOptionsFromArguments, should_support_load_savegame_path_with_quote)
|
||||||
|
@ -115,7 +116,7 @@ namespace
|
||||||
const std::array arguments {"openmw", "--load-savegame", R"(my"save.omwsave)"};
|
const std::array arguments {"openmw", "--load-savegame", R"(my"save.omwsave)"};
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
parseArgs(arguments, variables, description);
|
parseArgs(arguments, variables, description);
|
||||||
EXPECT_EQ(variables["load-savegame"].as<Files::MaybeQuotedPath>().string(), R"(my"save.omwsave)");
|
EXPECT_EQ(Files::pathToUnicodeString(variables["load-savegame"].as<Files::MaybeQuotedPath>()), R"(my"save.omwsave)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(OpenMWOptionsFromArguments, should_support_quoted_load_savegame_path)
|
TEST(OpenMWOptionsFromArguments, should_support_quoted_load_savegame_path)
|
||||||
|
@ -124,7 +125,7 @@ namespace
|
||||||
const std::array arguments {"openmw", "--load-savegame", R"("save".omwsave)"};
|
const std::array arguments {"openmw", "--load-savegame", R"("save".omwsave)"};
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
parseArgs(arguments, variables, description);
|
parseArgs(arguments, variables, description);
|
||||||
EXPECT_EQ(variables["load-savegame"].as<Files::MaybeQuotedPath>().string(), R"(save)");
|
EXPECT_EQ(Files::pathToUnicodeString(variables["load-savegame"].as<Files::MaybeQuotedPath>()), R"(save)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(OpenMWOptionsFromArguments, should_support_quoted_load_savegame_path_with_escaped_quote_by_ampersand)
|
TEST(OpenMWOptionsFromArguments, should_support_quoted_load_savegame_path_with_escaped_quote_by_ampersand)
|
||||||
|
@ -133,7 +134,7 @@ namespace
|
||||||
const std::array arguments {"openmw", "--load-savegame", R"("save&".omwsave")"};
|
const std::array arguments {"openmw", "--load-savegame", R"("save&".omwsave")"};
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
parseArgs(arguments, variables, description);
|
parseArgs(arguments, variables, description);
|
||||||
EXPECT_EQ(variables["load-savegame"].as<Files::MaybeQuotedPath>().string(), R"(save".omwsave)");
|
EXPECT_EQ(Files::pathToUnicodeString(variables["load-savegame"].as<Files::MaybeQuotedPath>()), R"(save".omwsave)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(OpenMWOptionsFromArguments, should_support_quoted_load_savegame_path_with_escaped_ampersand)
|
TEST(OpenMWOptionsFromArguments, should_support_quoted_load_savegame_path_with_escaped_ampersand)
|
||||||
|
@ -142,7 +143,7 @@ namespace
|
||||||
const std::array arguments {"openmw", "--load-savegame", R"("save.omwsave&&")"};
|
const std::array arguments {"openmw", "--load-savegame", R"("save.omwsave&&")"};
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
parseArgs(arguments, variables, description);
|
parseArgs(arguments, variables, description);
|
||||||
EXPECT_EQ(variables["load-savegame"].as<Files::MaybeQuotedPath>().string(), "save.omwsave&");
|
EXPECT_EQ(Files::pathToUnicodeString(variables["load-savegame"].as<Files::MaybeQuotedPath>()), "save.omwsave&");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(OpenMWOptionsFromArguments, should_support_load_savegame_path_with_ampersand)
|
TEST(OpenMWOptionsFromArguments, should_support_load_savegame_path_with_ampersand)
|
||||||
|
@ -151,7 +152,7 @@ namespace
|
||||||
const std::array arguments {"openmw", "--load-savegame", "save&.omwsave"};
|
const std::array arguments {"openmw", "--load-savegame", "save&.omwsave"};
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
parseArgs(arguments, variables, description);
|
parseArgs(arguments, variables, description);
|
||||||
EXPECT_EQ(variables["load-savegame"].as<Files::MaybeQuotedPath>().string(), "save&.omwsave");
|
EXPECT_EQ(Files::pathToUnicodeString(variables["load-savegame"].as<Files::MaybeQuotedPath>()), "save&.omwsave");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(OpenMWOptionsFromArguments, should_support_load_savegame_path_with_multiple_quotes)
|
TEST(OpenMWOptionsFromArguments, should_support_load_savegame_path_with_multiple_quotes)
|
||||||
|
@ -160,7 +161,7 @@ namespace
|
||||||
const std::array arguments {"openmw", "--load-savegame", R"(my"save".omwsave)"};
|
const std::array arguments {"openmw", "--load-savegame", R"(my"save".omwsave)"};
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
parseArgs(arguments, variables, description);
|
parseArgs(arguments, variables, description);
|
||||||
EXPECT_EQ(variables["load-savegame"].as<Files::MaybeQuotedPath>().string(), R"(my"save".omwsave)");
|
EXPECT_EQ(Files::pathToUnicodeString(variables["load-savegame"].as<Files::MaybeQuotedPath>()), R"(my"save".omwsave)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(OpenMWOptionsFromArguments, should_compose_data)
|
TEST(OpenMWOptionsFromArguments, should_compose_data)
|
||||||
|
@ -199,7 +200,7 @@ namespace
|
||||||
const std::array arguments {"openmw", "--load-savegame", pathArgument.c_str()};
|
const std::array arguments {"openmw", "--load-savegame", pathArgument.c_str()};
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
parseArgs(arguments, variables, description);
|
parseArgs(arguments, variables, description);
|
||||||
EXPECT_EQ(variables["load-savegame"].as<Files::MaybeQuotedPath>().string(), path);
|
EXPECT_EQ(Files::pathToUnicodeString(variables["load-savegame"].as<Files::MaybeQuotedPath>()), path);
|
||||||
}
|
}
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
@ -214,7 +215,7 @@ namespace
|
||||||
std::istringstream stream("load-savegame=save.omwsave");
|
std::istringstream stream("load-savegame=save.omwsave");
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
Files::parseConfig(stream, variables, description);
|
Files::parseConfig(stream, variables, description);
|
||||||
EXPECT_EQ(variables["load-savegame"].as<Files::MaybeQuotedPath>().string(), "save.omwsave");
|
EXPECT_EQ(Files::pathToUnicodeString(variables["load-savegame"].as<Files::MaybeQuotedPath>()), "save.omwsave");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(OpenMWOptionsFromConfig, should_strip_quotes_from_load_savegame_path)
|
TEST(OpenMWOptionsFromConfig, should_strip_quotes_from_load_savegame_path)
|
||||||
|
@ -223,7 +224,7 @@ namespace
|
||||||
std::istringstream stream(R"(load-savegame="save.omwsave")");
|
std::istringstream stream(R"(load-savegame="save.omwsave")");
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
Files::parseConfig(stream, variables, description);
|
Files::parseConfig(stream, variables, description);
|
||||||
EXPECT_EQ(variables["load-savegame"].as<Files::MaybeQuotedPath>().string(), "save.omwsave");
|
EXPECT_EQ(Files::pathToUnicodeString(variables["load-savegame"].as<Files::MaybeQuotedPath>()), "save.omwsave");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(OpenMWOptionsFromConfig, should_strip_outer_quotes_from_load_savegame_path)
|
TEST(OpenMWOptionsFromConfig, should_strip_outer_quotes_from_load_savegame_path)
|
||||||
|
@ -232,7 +233,7 @@ namespace
|
||||||
std::istringstream stream(R"(load-savegame=""save".omwsave")");
|
std::istringstream stream(R"(load-savegame=""save".omwsave")");
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
Files::parseConfig(stream, variables, description);
|
Files::parseConfig(stream, variables, description);
|
||||||
EXPECT_EQ(variables["load-savegame"].as<Files::MaybeQuotedPath>().string(), "");
|
EXPECT_EQ(Files::pathToUnicodeString(variables["load-savegame"].as<Files::MaybeQuotedPath>()), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(OpenMWOptionsFromConfig, should_strip_quotes_from_load_savegame_path_with_space)
|
TEST(OpenMWOptionsFromConfig, should_strip_quotes_from_load_savegame_path_with_space)
|
||||||
|
@ -241,7 +242,7 @@ namespace
|
||||||
std::istringstream stream(R"(load-savegame="my save.omwsave")");
|
std::istringstream stream(R"(load-savegame="my save.omwsave")");
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
Files::parseConfig(stream, variables, description);
|
Files::parseConfig(stream, variables, description);
|
||||||
EXPECT_EQ(variables["load-savegame"].as<Files::MaybeQuotedPath>().string(), "my save.omwsave");
|
EXPECT_EQ(Files::pathToUnicodeString(variables["load-savegame"].as<Files::MaybeQuotedPath>()), "my save.omwsave");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(OpenMWOptionsFromConfig, should_support_quoted_load_savegame_path_with_octothorpe)
|
TEST(OpenMWOptionsFromConfig, should_support_quoted_load_savegame_path_with_octothorpe)
|
||||||
|
@ -250,7 +251,7 @@ namespace
|
||||||
std::istringstream stream("load-savegame=save#.omwsave");
|
std::istringstream stream("load-savegame=save#.omwsave");
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
Files::parseConfig(stream, variables, description);
|
Files::parseConfig(stream, variables, description);
|
||||||
EXPECT_EQ(variables["load-savegame"].as<Files::MaybeQuotedPath>().string(), "save#.omwsave");
|
EXPECT_EQ(Files::pathToUnicodeString(variables["load-savegame"].as<Files::MaybeQuotedPath>()), "save#.omwsave");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(OpenMWOptionsFromConfig, should_support_quoted_load_savegame_path_with_at_sign)
|
TEST(OpenMWOptionsFromConfig, should_support_quoted_load_savegame_path_with_at_sign)
|
||||||
|
@ -259,7 +260,7 @@ namespace
|
||||||
std::istringstream stream("load-savegame=save@.omwsave");
|
std::istringstream stream("load-savegame=save@.omwsave");
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
Files::parseConfig(stream, variables, description);
|
Files::parseConfig(stream, variables, description);
|
||||||
EXPECT_EQ(variables["load-savegame"].as<Files::MaybeQuotedPath>().string(), "save@.omwsave");
|
EXPECT_EQ(Files::pathToUnicodeString(variables["load-savegame"].as<Files::MaybeQuotedPath>()), "save@.omwsave");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(OpenMWOptionsFromConfig, should_support_quoted_load_savegame_path_with_quote)
|
TEST(OpenMWOptionsFromConfig, should_support_quoted_load_savegame_path_with_quote)
|
||||||
|
@ -268,7 +269,7 @@ namespace
|
||||||
std::istringstream stream(R"(load-savegame=save".omwsave)");
|
std::istringstream stream(R"(load-savegame=save".omwsave)");
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
Files::parseConfig(stream, variables, description);
|
Files::parseConfig(stream, variables, description);
|
||||||
EXPECT_EQ(variables["load-savegame"].as<Files::MaybeQuotedPath>().string(), R"(save".omwsave)");
|
EXPECT_EQ(Files::pathToUnicodeString(variables["load-savegame"].as<Files::MaybeQuotedPath>()), R"(save".omwsave)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(OpenMWOptionsFromConfig, should_support_confusing_savegame_path_with_lots_going_on)
|
TEST(OpenMWOptionsFromConfig, should_support_confusing_savegame_path_with_lots_going_on)
|
||||||
|
@ -277,7 +278,7 @@ namespace
|
||||||
std::istringstream stream(R"(load-savegame="one &"two"three".omwsave")");
|
std::istringstream stream(R"(load-savegame="one &"two"three".omwsave")");
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
Files::parseConfig(stream, variables, description);
|
Files::parseConfig(stream, variables, description);
|
||||||
EXPECT_EQ(variables["load-savegame"].as<Files::MaybeQuotedPath>().string(), R"(one "two)");
|
EXPECT_EQ(Files::pathToUnicodeString(variables["load-savegame"].as<Files::MaybeQuotedPath>()), R"(one "two)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(OpenMWOptionsFromConfig, should_support_confusing_savegame_path_with_even_more_going_on)
|
TEST(OpenMWOptionsFromConfig, should_support_confusing_savegame_path_with_even_more_going_on)
|
||||||
|
@ -286,7 +287,7 @@ namespace
|
||||||
std::istringstream stream(R"(load-savegame="one &"two"three ".omwsave")");
|
std::istringstream stream(R"(load-savegame="one &"two"three ".omwsave")");
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
Files::parseConfig(stream, variables, description);
|
Files::parseConfig(stream, variables, description);
|
||||||
EXPECT_EQ(variables["load-savegame"].as<Files::MaybeQuotedPath>().string(), R"(one "two)");
|
EXPECT_EQ(Files::pathToUnicodeString(variables["load-savegame"].as<Files::MaybeQuotedPath>()), R"(one "two)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(OpenMWOptionsFromConfig, should_ignore_commented_option)
|
TEST(OpenMWOptionsFromConfig, should_ignore_commented_option)
|
||||||
|
@ -295,7 +296,7 @@ namespace
|
||||||
std::istringstream stream("#load-savegame=save.omwsave");
|
std::istringstream stream("#load-savegame=save.omwsave");
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
Files::parseConfig(stream, variables, description);
|
Files::parseConfig(stream, variables, description);
|
||||||
EXPECT_EQ(variables["load-savegame"].as<Files::MaybeQuotedPath>().string(), "");
|
EXPECT_EQ(Files::pathToUnicodeString(variables["load-savegame"].as<Files::MaybeQuotedPath>()), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(OpenMWOptionsFromConfig, should_ignore_whitespace_prefixed_commented_option)
|
TEST(OpenMWOptionsFromConfig, should_ignore_whitespace_prefixed_commented_option)
|
||||||
|
@ -304,7 +305,7 @@ namespace
|
||||||
std::istringstream stream(" \t#load-savegame=save.omwsave");
|
std::istringstream stream(" \t#load-savegame=save.omwsave");
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
Files::parseConfig(stream, variables, description);
|
Files::parseConfig(stream, variables, description);
|
||||||
EXPECT_EQ(variables["load-savegame"].as<Files::MaybeQuotedPath>().string(), "");
|
EXPECT_EQ(Files::pathToUnicodeString(variables["load-savegame"].as<Files::MaybeQuotedPath>()), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(OpenMWOptionsFromConfig, should_support_whitespace_around_option)
|
TEST(OpenMWOptionsFromConfig, should_support_whitespace_around_option)
|
||||||
|
@ -313,7 +314,7 @@ namespace
|
||||||
std::istringstream stream(" load-savegame = save.omwsave ");
|
std::istringstream stream(" load-savegame = save.omwsave ");
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
Files::parseConfig(stream, variables, description);
|
Files::parseConfig(stream, variables, description);
|
||||||
EXPECT_EQ(variables["load-savegame"].as<Files::MaybeQuotedPath>().string(), "save.omwsave");
|
EXPECT_EQ(Files::pathToUnicodeString(variables["load-savegame"].as<Files::MaybeQuotedPath>()), "save.omwsave");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(OpenMWOptionsFromConfig, should_throw_on_multiple_load_savegame)
|
TEST(OpenMWOptionsFromConfig, should_throw_on_multiple_load_savegame)
|
||||||
|
@ -330,7 +331,7 @@ namespace
|
||||||
std::istringstream stream("load-savegame=/home/user/openmw/save.omwsave");
|
std::istringstream stream("load-savegame=/home/user/openmw/save.omwsave");
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
Files::parseConfig(stream, variables, description);
|
Files::parseConfig(stream, variables, description);
|
||||||
EXPECT_EQ(variables["load-savegame"].as<Files::MaybeQuotedPath>().string(), "/home/user/openmw/save.omwsave");
|
EXPECT_EQ(Files::pathToUnicodeString(variables["load-savegame"].as<Files::MaybeQuotedPath>()), "/home/user/openmw/save.omwsave");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(OpenMWOptionsFromConfig, should_support_windows_multi_component_load_savegame_path)
|
TEST(OpenMWOptionsFromConfig, should_support_windows_multi_component_load_savegame_path)
|
||||||
|
@ -339,7 +340,7 @@ namespace
|
||||||
std::istringstream stream(R"(load-savegame=C:\OpenMW\save.omwsave)");
|
std::istringstream stream(R"(load-savegame=C:\OpenMW\save.omwsave)");
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
Files::parseConfig(stream, variables, description);
|
Files::parseConfig(stream, variables, description);
|
||||||
EXPECT_EQ(variables["load-savegame"].as<Files::MaybeQuotedPath>().string(), R"(C:\OpenMW\save.omwsave)");
|
EXPECT_EQ(Files::pathToUnicodeString(variables["load-savegame"].as<Files::MaybeQuotedPath>()), R"(C:\OpenMW\save.omwsave)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(OpenMWOptionsFromConfig, should_compose_data)
|
TEST(OpenMWOptionsFromConfig, should_compose_data)
|
||||||
|
@ -357,7 +358,7 @@ namespace
|
||||||
std::istringstream stream(R"(load-savegame="save&".omwsave")");
|
std::istringstream stream(R"(load-savegame="save&".omwsave")");
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
Files::parseConfig(stream, variables, description);
|
Files::parseConfig(stream, variables, description);
|
||||||
EXPECT_EQ(variables["load-savegame"].as<Files::MaybeQuotedPath>().string(), R"(save".omwsave)");
|
EXPECT_EQ(Files::pathToUnicodeString(variables["load-savegame"].as<Files::MaybeQuotedPath>()), R"(save".omwsave)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(OpenMWOptionsFromConfig, should_support_quoted_load_savegame_path_with_escaped_ampersand)
|
TEST(OpenMWOptionsFromConfig, should_support_quoted_load_savegame_path_with_escaped_ampersand)
|
||||||
|
@ -366,7 +367,7 @@ namespace
|
||||||
std::istringstream stream(R"(load-savegame="save.omwsave&&")");
|
std::istringstream stream(R"(load-savegame="save.omwsave&&")");
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
Files::parseConfig(stream, variables, description);
|
Files::parseConfig(stream, variables, description);
|
||||||
EXPECT_EQ(variables["load-savegame"].as<Files::MaybeQuotedPath>().string(), "save.omwsave&");
|
EXPECT_EQ(Files::pathToUnicodeString(variables["load-savegame"].as<Files::MaybeQuotedPath>()), "save.omwsave&");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(OpenMWOptionsFromConfig, should_support_load_savegame_path_with_ampersand)
|
TEST(OpenMWOptionsFromConfig, should_support_load_savegame_path_with_ampersand)
|
||||||
|
@ -375,7 +376,7 @@ namespace
|
||||||
std::istringstream stream("load-savegame=save&.omwsave");
|
std::istringstream stream("load-savegame=save&.omwsave");
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
Files::parseConfig(stream, variables, description);
|
Files::parseConfig(stream, variables, description);
|
||||||
EXPECT_EQ(variables["load-savegame"].as<Files::MaybeQuotedPath>().string(), "save&.omwsave");
|
EXPECT_EQ(Files::pathToUnicodeString(variables["load-savegame"].as<Files::MaybeQuotedPath>()), "save&.omwsave");
|
||||||
}
|
}
|
||||||
|
|
||||||
struct OpenMWOptionsFromConfigStrings : TestWithParam<std::string> {};
|
struct OpenMWOptionsFromConfigStrings : TestWithParam<std::string> {};
|
||||||
|
@ -387,7 +388,7 @@ namespace
|
||||||
std::istringstream stream("load-savegame=\"" + path + "\"");
|
std::istringstream stream("load-savegame=\"" + path + "\"");
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
Files::parseConfig(stream, variables, description);
|
Files::parseConfig(stream, variables, description);
|
||||||
EXPECT_EQ(variables["load-savegame"].as<Files::MaybeQuotedPath>().string(), path);
|
EXPECT_EQ(Files::pathToUnicodeString(variables["load-savegame"].as<Files::MaybeQuotedPath>()), path);
|
||||||
}
|
}
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
|
|
@ -19,7 +19,7 @@ namespace
|
||||||
template <typename F>
|
template <typename F>
|
||||||
void withSettingsFile( const std::string& content, F&& f)
|
void withSettingsFile( const std::string& content, F&& f)
|
||||||
{
|
{
|
||||||
std::string path = TestingOpenMW::outputFilePath(
|
auto path = TestingOpenMW::outputFilePath(
|
||||||
std::string(UnitTest::GetInstance()->current_test_info()->name()) + ".cfg");
|
std::string(UnitTest::GetInstance()->current_test_info()->name()) + ".cfg");
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace
|
||||||
template <typename F>
|
template <typename F>
|
||||||
void withSettingsFile( const std::string& content, F&& f)
|
void withSettingsFile( const std::string& content, F&& f)
|
||||||
{
|
{
|
||||||
std::string path = TestingOpenMW::outputFilePath(
|
auto path = TestingOpenMW::outputFilePath(
|
||||||
std::string(UnitTest::GetInstance()->current_test_info()->name()) + ".yaml");
|
std::string(UnitTest::GetInstance()->current_test_info()->name()) + ".yaml");
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include <components/shader/shadermanager.hpp>
|
#include <components/shader/shadermanager.hpp>
|
||||||
|
#include <components/files/conversion.hpp>
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
@ -30,7 +31,7 @@ namespace
|
||||||
template <class F>
|
template <class F>
|
||||||
void withShaderFile(const std::string& suffix, const std::string& content, F&& f)
|
void withShaderFile(const std::string& suffix, const std::string& content, F&& f)
|
||||||
{
|
{
|
||||||
std::string path = TestingOpenMW::outputFilePath(
|
auto path = TestingOpenMW::outputFilePath(
|
||||||
std::string(UnitTest::GetInstance()->current_test_info()->name()) + suffix + ".glsl");
|
std::string(UnitTest::GetInstance()->current_test_info()->name()) + suffix + ".glsl");
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -47,8 +48,8 @@ namespace
|
||||||
{
|
{
|
||||||
const std::string content;
|
const std::string content;
|
||||||
|
|
||||||
withShaderFile(content, [this] (const std::string& templateName) {
|
withShaderFile(content, [this] (const std::filesystem::path& templateName) {
|
||||||
EXPECT_TRUE(mManager.getShader(templateName, {}, osg::Shader::VERTEX));
|
EXPECT_TRUE(mManager.getShader(Files::pathToUnicodeString(templateName), {}, osg::Shader::VERTEX));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,8 +59,8 @@ namespace
|
||||||
"#version 120\n"
|
"#version 120\n"
|
||||||
"void main() {}\n";
|
"void main() {}\n";
|
||||||
|
|
||||||
withShaderFile(content, [&] (const std::string& templateName) {
|
withShaderFile(content, [&] (const std::filesystem::path& templateName) {
|
||||||
const auto shader = mManager.getShader(templateName, mDefines, osg::Shader::VERTEX);
|
const auto shader = mManager.getShader(Files::pathToUnicodeString(templateName), mDefines, osg::Shader::VERTEX);
|
||||||
ASSERT_TRUE(shader);
|
ASSERT_TRUE(shader);
|
||||||
EXPECT_EQ(shader->getShaderSource(), content);
|
EXPECT_EQ(shader->getShaderSource(), content);
|
||||||
});
|
});
|
||||||
|
@ -70,19 +71,19 @@ namespace
|
||||||
const std::string content0 =
|
const std::string content0 =
|
||||||
"void foo() {}\n";
|
"void foo() {}\n";
|
||||||
|
|
||||||
withShaderFile("_0", content0, [&] (const std::string& templateName0) {
|
withShaderFile("_0", content0, [&] (const std::filesystem::path& templateName0) {
|
||||||
const std::string content1 =
|
const std::string content1 =
|
||||||
"#include \"" + templateName0 + "\"\n"
|
"#include \"" + Files::pathToUnicodeString(templateName0) + "\"\n"
|
||||||
"void bar() { foo() }\n";
|
"void bar() { foo() }\n";
|
||||||
|
|
||||||
withShaderFile("_1", content1, [&] (const std::string& templateName1) {
|
withShaderFile("_1", content1, [&] (const std::filesystem::path& templateName1) {
|
||||||
const std::string content2 =
|
const std::string content2 =
|
||||||
"#version 120\n"
|
"#version 120\n"
|
||||||
"#include \"" + templateName1 + "\"\n"
|
"#include \"" + Files::pathToUnicodeString(templateName1) + "\"\n"
|
||||||
"void main() { bar() }\n";
|
"void main() { bar() }\n";
|
||||||
|
|
||||||
withShaderFile(content2, [&] (const std::string& templateName2) {
|
withShaderFile(content2, [&] (const std::filesystem::path& templateName2) {
|
||||||
const auto shader = mManager.getShader(templateName2, mDefines, osg::Shader::VERTEX);
|
const auto shader = mManager.getShader(Files::pathToUnicodeString(templateName2), mDefines, osg::Shader::VERTEX);
|
||||||
ASSERT_TRUE(shader);
|
ASSERT_TRUE(shader);
|
||||||
const std::string expected =
|
const std::string expected =
|
||||||
"#version 120\n"
|
"#version 120\n"
|
||||||
|
@ -111,9 +112,9 @@ namespace
|
||||||
"void main() {}\n"
|
"void main() {}\n"
|
||||||
;
|
;
|
||||||
|
|
||||||
withShaderFile(content, [&] (const std::string& templateName) {
|
withShaderFile(content, [&] (const std::filesystem::path& templateName) {
|
||||||
mDefines["flag"] = "1";
|
mDefines["flag"] = "1";
|
||||||
const auto shader = mManager.getShader(templateName, mDefines, osg::Shader::VERTEX);
|
const auto shader = mManager.getShader(Files::pathToUnicodeString(templateName), mDefines, osg::Shader::VERTEX);
|
||||||
ASSERT_TRUE(shader);
|
ASSERT_TRUE(shader);
|
||||||
const std::string expected =
|
const std::string expected =
|
||||||
"#version 120\n"
|
"#version 120\n"
|
||||||
|
@ -133,9 +134,9 @@ namespace
|
||||||
"void main() {}\n"
|
"void main() {}\n"
|
||||||
;
|
;
|
||||||
|
|
||||||
withShaderFile(content, [&] (const std::string& templateName) {
|
withShaderFile(content, [&] (const std::filesystem::path& templateName) {
|
||||||
mDefines["list"] = "1,2,3";
|
mDefines["list"] = "1,2,3";
|
||||||
const auto shader = mManager.getShader(templateName, mDefines, osg::Shader::VERTEX);
|
const auto shader = mManager.getShader(Files::pathToUnicodeString(templateName), mDefines, osg::Shader::VERTEX);
|
||||||
ASSERT_TRUE(shader);
|
ASSERT_TRUE(shader);
|
||||||
const std::string expected =
|
const std::string expected =
|
||||||
"#version 120\n"
|
"#version 120\n"
|
||||||
|
@ -174,9 +175,9 @@ namespace
|
||||||
"}\n"
|
"}\n"
|
||||||
;
|
;
|
||||||
|
|
||||||
withShaderFile(content, [&] (const std::string& templateName) {
|
withShaderFile(content, [&] (const std::filesystem::path& templateName) {
|
||||||
mDefines["list"] = "1,2,3";
|
mDefines["list"] = "1,2,3";
|
||||||
const auto shader = mManager.getShader(templateName, mDefines, osg::Shader::VERTEX);
|
const auto shader = mManager.getShader(Files::pathToUnicodeString(templateName), mDefines, osg::Shader::VERTEX);
|
||||||
ASSERT_TRUE(shader);
|
ASSERT_TRUE(shader);
|
||||||
const std::string expected =
|
const std::string expected =
|
||||||
"#version 120\n"
|
"#version 120\n"
|
||||||
|
@ -222,8 +223,8 @@ namespace
|
||||||
"void main() {}\n"
|
"void main() {}\n"
|
||||||
;
|
;
|
||||||
|
|
||||||
withShaderFile(content, [&] (const std::string& templateName) {
|
withShaderFile(content, [&] (const std::filesystem::path& templateName) {
|
||||||
EXPECT_FALSE(mManager.getShader(templateName, mDefines, osg::Shader::VERTEX));
|
EXPECT_FALSE(mManager.getShader(Files::pathToUnicodeString(templateName), mDefines, osg::Shader::VERTEX));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,8 +236,8 @@ namespace
|
||||||
"void main() {}\n"
|
"void main() {}\n"
|
||||||
;
|
;
|
||||||
|
|
||||||
withShaderFile(content, [&] (const std::string& templateName) {
|
withShaderFile(content, [&] (const std::filesystem::path& templateName) {
|
||||||
EXPECT_FALSE(mManager.getShader(templateName, mDefines, osg::Shader::VERTEX));
|
EXPECT_FALSE(mManager.getShader(Files::pathToUnicodeString(templateName), mDefines, osg::Shader::VERTEX));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,20 +6,21 @@
|
||||||
|
|
||||||
#include <components/vfs/archive.hpp>
|
#include <components/vfs/archive.hpp>
|
||||||
#include <components/vfs/manager.hpp>
|
#include <components/vfs/manager.hpp>
|
||||||
|
#include <components/misc/strings/conversion.hpp>
|
||||||
|
|
||||||
namespace TestingOpenMW
|
namespace TestingOpenMW
|
||||||
{
|
{
|
||||||
|
|
||||||
inline std::string outputFilePath(const std::string name)
|
inline std::filesystem::path outputFilePath(const std::string name)
|
||||||
{
|
{
|
||||||
std::filesystem::path dir("tests_output");
|
std::filesystem::path dir("tests_output");
|
||||||
std::filesystem::create_directory(dir);
|
std::filesystem::create_directory(dir);
|
||||||
return (dir / name).string();
|
return dir / Misc::StringUtils::stringToU8String(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string temporaryFilePath(const std::string name)
|
inline std::filesystem::path temporaryFilePath(const std::string name)
|
||||||
{
|
{
|
||||||
return (std::filesystem::temp_directory_path() / name).string();
|
return std::filesystem::temp_directory_path() / name;
|
||||||
}
|
}
|
||||||
|
|
||||||
class VFSTestFile : public VFS::File
|
class VFSTestFile : public VFS::File
|
||||||
|
@ -32,7 +33,7 @@ namespace TestingOpenMW
|
||||||
return std::make_unique<std::stringstream>(mContent, std::ios_base::in);
|
return std::make_unique<std::stringstream>(mContent, std::ios_base::in);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getPath() override
|
std::filesystem::path getPath() override
|
||||||
{
|
{
|
||||||
return "TestFile";
|
return "TestFile";
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue