preliminary utf-16 stuff
This commit is contained in:
@@ -24,20 +24,22 @@ namespace anm2ed::anm2
|
||||
XMLDocument document;
|
||||
|
||||
#ifdef _WIN32
|
||||
FILE* file = _wfopen(path.native().c_str(), L"wb");
|
||||
FILE* file = _wfopen(path.native().c_str(), L"rb");
|
||||
#else
|
||||
FILE* file = fopen(path.c_str(), "wb");
|
||||
FILE* file = fopen(path.c_str(), "rb");
|
||||
#endif
|
||||
|
||||
if (!file)
|
||||
{
|
||||
if (errorString) *errorString = localize.get(ERROR_FILE_NOT_FOUND);
|
||||
isValid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (document.LoadFile(file) != XML_SUCCESS)
|
||||
{
|
||||
if (errorString) *errorString = document.ErrorStr();
|
||||
isValid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ namespace anm2ed::anm2
|
||||
class Anm2
|
||||
{
|
||||
public:
|
||||
bool isValid{true};
|
||||
Info info{};
|
||||
Content content{};
|
||||
Animations animations{};
|
||||
|
||||
100
src/document.cpp
100
src/document.cpp
@@ -4,6 +4,7 @@
|
||||
|
||||
#include <format>
|
||||
|
||||
#include "filesystem_.h"
|
||||
#include "log.h"
|
||||
#include "strings.h"
|
||||
#include "toast.h"
|
||||
@@ -11,33 +12,47 @@
|
||||
using namespace anm2ed::anm2;
|
||||
using namespace anm2ed::imgui;
|
||||
using namespace anm2ed::types;
|
||||
|
||||
using namespace glm;
|
||||
|
||||
namespace filesystem = anm2ed::util::filesystem;
|
||||
|
||||
namespace anm2ed
|
||||
{
|
||||
Document::Document(Anm2& anm2, const std::string& path)
|
||||
Document::Document(Anm2& anm2, const std::filesystem::path& path)
|
||||
{
|
||||
this->anm2 = std::move(anm2);
|
||||
this->path = path;
|
||||
isValid = this->anm2.isValid;
|
||||
if (!isValid) return;
|
||||
clean();
|
||||
change(Document::ALL);
|
||||
}
|
||||
|
||||
Document::Document(const std::string& path, bool isNew, std::string* errorString)
|
||||
Document::Document(const std::filesystem::path& path, bool isNew, std::string* errorString)
|
||||
{
|
||||
if (isNew)
|
||||
{
|
||||
anm2 = anm2::Anm2();
|
||||
if (!save(path)) return;
|
||||
if (!save(path, errorString))
|
||||
{
|
||||
isValid = false;
|
||||
this->path.clear();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
anm2 = Anm2(path, errorString);
|
||||
if (errorString && !errorString->empty()) return;
|
||||
if (!anm2.isValid)
|
||||
{
|
||||
isValid = false;
|
||||
this->path.clear();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this->path = path;
|
||||
isValid = anm2.isValid;
|
||||
clean();
|
||||
change(Document::ALL);
|
||||
}
|
||||
@@ -49,8 +64,8 @@ namespace anm2ed
|
||||
spritesheet(current.spritesheet), frames(current.frames), message(current.message),
|
||||
previewZoom(other.previewZoom), previewPan(other.previewPan), editorPan(other.editorPan),
|
||||
editorZoom(other.editorZoom), overlayIndex(other.overlayIndex), hash(other.hash), saveHash(other.saveHash),
|
||||
autosaveHash(other.autosaveHash), lastAutosaveTime(other.lastAutosaveTime), isOpen(other.isOpen),
|
||||
isForceDirty(other.isForceDirty), isAnimationPreviewSet(other.isAnimationPreviewSet),
|
||||
autosaveHash(other.autosaveHash), lastAutosaveTime(other.lastAutosaveTime), isValid(other.isValid),
|
||||
isOpen(other.isOpen), isForceDirty(other.isForceDirty), isAnimationPreviewSet(other.isAnimationPreviewSet),
|
||||
isSpritesheetEditorSet(other.isSpritesheetEditorSet)
|
||||
{
|
||||
}
|
||||
@@ -70,6 +85,7 @@ namespace anm2ed
|
||||
saveHash = other.saveHash;
|
||||
autosaveHash = other.autosaveHash;
|
||||
lastAutosaveTime = other.lastAutosaveTime;
|
||||
isValid = other.isValid;
|
||||
isOpen = other.isOpen;
|
||||
isForceDirty = other.isForceDirty;
|
||||
isAnimationPreviewSet = other.isAnimationPreviewSet;
|
||||
@@ -78,25 +94,26 @@ namespace anm2ed
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool Document::save(const std::string& path, std::string* errorString)
|
||||
bool Document::save(const std::filesystem::path& path, std::string* errorString)
|
||||
{
|
||||
this->path = !path.empty() ? path : this->path.string();
|
||||
this->path = !path.empty() ? path : this->path;
|
||||
|
||||
auto absolutePath = this->path.string();
|
||||
auto absolutePath = this->path;
|
||||
auto absolutePathUtf8 = filesystem::path_to_utf8(absolutePath);
|
||||
if (anm2.serialize(absolutePath, errorString))
|
||||
{
|
||||
toasts.push(std::vformat(localize.get(TOAST_SAVE_DOCUMENT), std::make_format_args(absolutePath)));
|
||||
logger.info(
|
||||
std::vformat(localize.get(TOAST_SAVE_DOCUMENT, anm2ed::ENGLISH), std::make_format_args(absolutePath)));
|
||||
toasts.push(std::vformat(localize.get(TOAST_SAVE_DOCUMENT), std::make_format_args(absolutePathUtf8)));
|
||||
logger.info(std::vformat(localize.get(TOAST_SAVE_DOCUMENT, anm2ed::ENGLISH),
|
||||
std::make_format_args(absolutePathUtf8)));
|
||||
clean();
|
||||
return true;
|
||||
}
|
||||
else if (errorString)
|
||||
{
|
||||
toasts.push(
|
||||
std::vformat(localize.get(TOAST_SAVE_DOCUMENT_FAILED), std::make_format_args(absolutePath, *errorString)));
|
||||
toasts.push(std::vformat(localize.get(TOAST_SAVE_DOCUMENT_FAILED),
|
||||
std::make_format_args(absolutePathUtf8, *errorString)));
|
||||
logger.error(std::vformat(localize.get(TOAST_SAVE_DOCUMENT_FAILED, anm2ed::ENGLISH),
|
||||
std::make_format_args(absolutePath, *errorString)));
|
||||
std::make_format_args(absolutePathUtf8, *errorString)));
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -104,39 +121,41 @@ namespace anm2ed
|
||||
|
||||
std::filesystem::path Document::autosave_path_get()
|
||||
{
|
||||
return directory_get() / std::string("." + filename_get().string() + ".autosave");
|
||||
auto fileNameUtf8 = filesystem::path_to_utf8(filename_get());
|
||||
auto autosaveNameUtf8 = "." + fileNameUtf8 + ".autosave";
|
||||
return directory_get() / filesystem::path_from_utf8(autosaveNameUtf8);
|
||||
}
|
||||
|
||||
std::filesystem::path Document::path_from_autosave_get(std::filesystem::path& path)
|
||||
{
|
||||
auto fileName = path.filename().string();
|
||||
auto fileName = path.filename().u8string();
|
||||
if (!fileName.empty() && fileName.front() == '.') fileName.erase(fileName.begin());
|
||||
|
||||
auto restorePath = path.parent_path() / fileName;
|
||||
auto restorePath = path.parent_path() / std::filesystem::path(std::u8string(fileName.begin(), fileName.end()));
|
||||
restorePath.replace_extension("");
|
||||
|
||||
return path;
|
||||
return restorePath;
|
||||
}
|
||||
|
||||
bool Document::autosave(std::string* errorString)
|
||||
{
|
||||
auto autosavePath = autosave_path_get();
|
||||
auto autosavePathString = autosavePath.string();
|
||||
if (anm2.serialize(autosavePathString, errorString))
|
||||
auto autosavePathUtf8 = filesystem::path_to_utf8(autosavePath);
|
||||
if (anm2.serialize(autosavePath, errorString))
|
||||
{
|
||||
autosaveHash = hash;
|
||||
lastAutosaveTime = 0.0f;
|
||||
toasts.push(localize.get(TOAST_AUTOSAVING));
|
||||
logger.info(localize.get(TOAST_AUTOSAVING, anm2ed::ENGLISH));
|
||||
logger.info(std::format("Autosaved document to: {}", autosavePath.string()));
|
||||
logger.info(std::format("Autosaved document to: {}", autosavePathUtf8));
|
||||
return true;
|
||||
}
|
||||
else if (errorString)
|
||||
{
|
||||
toasts.push(
|
||||
std::vformat(localize.get(TOAST_AUTOSAVE_FAILED), std::make_format_args(autosavePathString, *errorString)));
|
||||
toasts.push(std::vformat(localize.get(TOAST_AUTOSAVE_FAILED),
|
||||
std::make_format_args(autosavePathUtf8, *errorString)));
|
||||
logger.error(std::vformat(localize.get(TOAST_AUTOSAVE_FAILED, anm2ed::ENGLISH),
|
||||
std::make_format_args(autosavePathString, *errorString)));
|
||||
std::make_format_args(autosavePathUtf8, *errorString)));
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -223,7 +242,7 @@ namespace anm2ed
|
||||
bool Document::is_autosave_dirty() const { return hash != autosaveHash; }
|
||||
std::filesystem::path Document::directory_get() const { return path.parent_path(); }
|
||||
std::filesystem::path Document::filename_get() const { return path.filename(); }
|
||||
bool Document::is_valid() const { return !path.empty(); }
|
||||
bool Document::is_valid() const { return isValid && !path.empty(); }
|
||||
|
||||
anm2::Frame* Document::frame_get()
|
||||
{
|
||||
@@ -237,43 +256,45 @@ namespace anm2ed
|
||||
anm2::Animation* Document::animation_get() { return anm2.animation_get(reference.animationIndex); }
|
||||
anm2::Spritesheet* Document::spritesheet_get() { return anm2.spritesheet_get(spritesheet.reference); }
|
||||
|
||||
void Document::spritesheet_add(const std::string& path)
|
||||
void Document::spritesheet_add(const std::filesystem::path& path)
|
||||
{
|
||||
auto add = [&]()
|
||||
{
|
||||
int id{};
|
||||
auto pathCopy = path;
|
||||
if (anm2.spritesheet_add(directory_get().string(), path, id))
|
||||
if (anm2.spritesheet_add(directory_get(), path, id))
|
||||
{
|
||||
anm2::Spritesheet& spritesheet = anm2.content.spritesheets[id];
|
||||
auto path = spritesheet.path.string();
|
||||
auto pathString = filesystem::path_to_utf8(spritesheet.path);
|
||||
this->spritesheet.selection = {id};
|
||||
this->spritesheet.reference = id;
|
||||
toasts.push(std::vformat(localize.get(TOAST_SPRITESHEET_INITIALIZED), std::make_format_args(id, path)));
|
||||
toasts.push(
|
||||
std::vformat(localize.get(TOAST_SPRITESHEET_INITIALIZED), std::make_format_args(id, pathString)));
|
||||
logger.info(std::vformat(localize.get(TOAST_SPRITESHEET_INITIALIZED, anm2ed::ENGLISH),
|
||||
std::make_format_args(id, path)));
|
||||
std::make_format_args(id, pathString)));
|
||||
}
|
||||
else
|
||||
{
|
||||
toasts.push(std::vformat(localize.get(TOAST_SPRITESHEET_INIT_FAILED), std::make_format_args(pathCopy)));
|
||||
auto pathUtf8 = filesystem::path_to_utf8(pathCopy);
|
||||
toasts.push(std::vformat(localize.get(TOAST_SPRITESHEET_INIT_FAILED), std::make_format_args(pathUtf8)));
|
||||
logger.error(std::vformat(localize.get(TOAST_SPRITESHEET_INIT_FAILED, anm2ed::ENGLISH),
|
||||
std::make_format_args(pathCopy)));
|
||||
std::make_format_args(pathUtf8)));
|
||||
}
|
||||
};
|
||||
|
||||
DOCUMENT_EDIT_PTR(this, localize.get(EDIT_ADD_SPRITESHEET), Document::SPRITESHEETS, add());
|
||||
}
|
||||
|
||||
void Document::sound_add(const std::string& path)
|
||||
void Document::sound_add(const std::filesystem::path& path)
|
||||
{
|
||||
auto add = [&]()
|
||||
{
|
||||
int id{};
|
||||
auto pathCopy = path;
|
||||
if (anm2.sound_add(directory_get().string(), path, id))
|
||||
if (anm2.sound_add(directory_get(), path, id))
|
||||
{
|
||||
auto& soundInfo = anm2.content.sounds[id];
|
||||
auto soundPath = soundInfo.path.string();
|
||||
auto soundPath = filesystem::path_to_utf8(soundInfo.path);
|
||||
sound.selection = {id};
|
||||
sound.reference = id;
|
||||
toasts.push(std::vformat(localize.get(TOAST_SOUND_INITIALIZED), std::make_format_args(id, soundPath)));
|
||||
@@ -282,9 +303,10 @@ namespace anm2ed
|
||||
}
|
||||
else
|
||||
{
|
||||
toasts.push(std::vformat(localize.get(TOAST_SOUND_INITIALIZE_FAILED), std::make_format_args(pathCopy)));
|
||||
auto pathUtf8 = filesystem::path_to_utf8(pathCopy);
|
||||
toasts.push(std::vformat(localize.get(TOAST_SOUND_INITIALIZE_FAILED), std::make_format_args(pathUtf8)));
|
||||
logger.error(std::vformat(localize.get(TOAST_SOUND_INITIALIZE_FAILED, anm2ed::ENGLISH),
|
||||
std::make_format_args(pathCopy)));
|
||||
std::make_format_args(pathUtf8)));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -58,18 +58,19 @@ namespace anm2ed
|
||||
uint64_t saveHash{};
|
||||
uint64_t autosaveHash{};
|
||||
double lastAutosaveTime{};
|
||||
bool isValid{true};
|
||||
bool isOpen{true};
|
||||
bool isForceDirty{false};
|
||||
bool isAnimationPreviewSet{false};
|
||||
bool isSpritesheetEditorSet{false};
|
||||
|
||||
Document(anm2::Anm2& anm2, const std::string&);
|
||||
Document(const std::string&, bool = false, std::string* = nullptr);
|
||||
Document(anm2::Anm2& anm2, const std::filesystem::path&);
|
||||
Document(const std::filesystem::path&, bool = false, std::string* = nullptr);
|
||||
Document(const Document&) = delete;
|
||||
Document& operator=(const Document&) = delete;
|
||||
Document(Document&&) noexcept;
|
||||
Document& operator=(Document&&) noexcept;
|
||||
bool save(const std::string& = {}, std::string* = nullptr);
|
||||
bool save(const std::filesystem::path& = {}, std::string* = nullptr);
|
||||
void hash_set();
|
||||
void clean();
|
||||
void change(ChangeType);
|
||||
@@ -84,8 +85,8 @@ namespace anm2ed
|
||||
anm2::Spritesheet* spritesheet_get();
|
||||
anm2::Animation* animation_get();
|
||||
|
||||
void spritesheet_add(const std::string&);
|
||||
void sound_add(const std::string&);
|
||||
void spritesheet_add(const std::filesystem::path&);
|
||||
void sound_add(const std::filesystem::path&);
|
||||
|
||||
bool autosave(std::string* = nullptr);
|
||||
std::filesystem::path autosave_path_get();
|
||||
|
||||
@@ -268,7 +268,7 @@ namespace anm2ed::imgui
|
||||
if (ImGui::MenuItem(localize.get(LABEL_SAVE_AS), settings.shortcutSaveAs.c_str(), false, document))
|
||||
dialog.file_save(dialog::ANM2_SAVE);
|
||||
if (ImGui::MenuItem(localize.get(LABEL_EXPLORE_XML_LOCATION), nullptr, false, document))
|
||||
dialog.file_explorer_open(document->directory_get().string());
|
||||
dialog.file_explorer_open(document->directory_get());
|
||||
|
||||
ImGui::Separator();
|
||||
if (ImGui::MenuItem(localize.get(LABEL_EXIT), settings.shortcutExit.c_str())) isQuitting = true;
|
||||
|
||||
@@ -94,7 +94,7 @@ namespace anm2ed::imgui
|
||||
{
|
||||
auto& id = *selection.begin();
|
||||
anm2::Sound& sound = anm2.content.sounds[id];
|
||||
sound = anm2::Sound(document.directory_get().string(), path);
|
||||
sound = anm2::Sound(document.directory_get(), path);
|
||||
auto pathString = sound.path.string();
|
||||
toasts.push(std::vformat(localize.get(TOAST_REPLACE_SOUND), std::make_format_args(id, pathString)));
|
||||
logger.info(
|
||||
@@ -129,7 +129,7 @@ namespace anm2ed::imgui
|
||||
{
|
||||
std::string errorString{};
|
||||
document.snapshot(localize.get(TOAST_SOUNDS_PASTE));
|
||||
if (anm2.sounds_deserialize(clipboard.get(), document.directory_get().string(), merge::APPEND, &errorString))
|
||||
if (anm2.sounds_deserialize(clipboard.get(), document.directory_get(), merge::APPEND, &errorString))
|
||||
document.change(Document::SOUNDS);
|
||||
else
|
||||
{
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace anm2ed::imgui
|
||||
auto add = [&](const std::filesystem::path& path)
|
||||
{
|
||||
if (path.empty()) return;
|
||||
document.spritesheet_add(path.string());
|
||||
document.spritesheet_add(path);
|
||||
newSpritesheetId = document.spritesheet.reference;
|
||||
};
|
||||
|
||||
@@ -87,7 +87,7 @@ namespace anm2ed::imgui
|
||||
{
|
||||
auto& id = *selection.begin();
|
||||
anm2::Spritesheet& spritesheet = anm2.content.spritesheets[id];
|
||||
spritesheet = anm2::Spritesheet(document.directory_get().string(), path);
|
||||
spritesheet = anm2::Spritesheet(document.directory_get(), path);
|
||||
auto pathString = spritesheet.path.string();
|
||||
toasts.push(std::vformat(localize.get(TOAST_REPLACE_SPRITESHEET), std::make_format_args(id, pathString)));
|
||||
logger.info(std::vformat(localize.get(TOAST_REPLACE_SPRITESHEET, anm2ed::ENGLISH),
|
||||
@@ -105,7 +105,7 @@ namespace anm2ed::imgui
|
||||
{
|
||||
anm2::Spritesheet& spritesheet = anm2.content.spritesheets[id];
|
||||
auto pathString = spritesheet.path.string();
|
||||
if (spritesheet.save(document.directory_get().string()))
|
||||
if (spritesheet.save(document.directory_get()))
|
||||
{
|
||||
toasts.push(std::vformat(localize.get(TOAST_SAVE_SPRITESHEET), std::make_format_args(id, pathString)));
|
||||
logger.info(std::vformat(localize.get(TOAST_SAVE_SPRITESHEET, anm2ed::ENGLISH),
|
||||
@@ -145,7 +145,7 @@ namespace anm2ed::imgui
|
||||
{
|
||||
std::string errorString{};
|
||||
document.snapshot(localize.get(EDIT_PASTE_SPRITESHEETS));
|
||||
if (anm2.spritesheets_deserialize(clipboard.get(), document.directory_get().string(), merge::APPEND,
|
||||
if (anm2.spritesheets_deserialize(clipboard.get(), document.directory_get(), merge::APPEND,
|
||||
&errorString))
|
||||
document.change(Document::SPRITESHEETS);
|
||||
else
|
||||
|
||||
@@ -26,7 +26,9 @@ namespace anm2ed
|
||||
if (parent.empty()) return;
|
||||
std::error_code ec{};
|
||||
std::filesystem::create_directories(parent, ec);
|
||||
if (ec) logger.warning(std::format("Could not create directory for {}: {}", path.string(), ec.message()));
|
||||
if (ec)
|
||||
logger.warning(
|
||||
std::format("Could not create directory for {}: {}", filesystem::path_to_utf8(path), ec.message()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,9 +72,9 @@ namespace anm2ed
|
||||
|
||||
void Manager::open(const std::filesystem::path& path, bool isNew, bool isRecent)
|
||||
{
|
||||
const auto pathString = path.string();
|
||||
std::string errorString{};
|
||||
documents.emplace_back(pathString, isNew, &errorString);
|
||||
documents.emplace_back(path, isNew, &errorString);
|
||||
auto pathString = filesystem::path_to_utf8(path);
|
||||
|
||||
auto& document = documents.back();
|
||||
if (!document.is_valid())
|
||||
@@ -103,7 +105,7 @@ namespace anm2ed
|
||||
std::string errorString{};
|
||||
document->path = !path.empty() ? path : document->path;
|
||||
document->path.replace_extension(".anm2");
|
||||
document->save(document->path.string(), &errorString);
|
||||
document->save(document->path, &errorString);
|
||||
recent_file_add(document->path);
|
||||
}
|
||||
}
|
||||
@@ -133,7 +135,9 @@ namespace anm2ed
|
||||
{
|
||||
std::error_code ec{};
|
||||
std::filesystem::remove(autosavePath, ec);
|
||||
if (ec) logger.warning(std::format("Could not remove autosave file {}: {}", autosavePath.string(), ec.message()));
|
||||
if (ec)
|
||||
logger.warning(std::format("Could not remove autosave file {}: {}", filesystem::path_to_utf8(autosavePath),
|
||||
ec.message()));
|
||||
}
|
||||
|
||||
autosave_files_write();
|
||||
@@ -248,7 +252,7 @@ namespace anm2ed
|
||||
std::vector<std::filesystem::path> ordered;
|
||||
ordered.reserve(orderedEntries.size());
|
||||
for (const auto& [pathString, _] : orderedEntries)
|
||||
ordered.emplace_back(pathString);
|
||||
ordered.emplace_back(filesystem::path_from_utf8(pathString));
|
||||
return ordered;
|
||||
}
|
||||
|
||||
@@ -258,11 +262,11 @@ namespace anm2ed
|
||||
std::error_code ec{};
|
||||
if (!std::filesystem::exists(path, ec))
|
||||
{
|
||||
logger.warning(std::format("Skipping missing recent file: {}", path.string()));
|
||||
logger.warning(std::format("Skipping missing recent file: {}", filesystem::path_to_utf8(path)));
|
||||
return;
|
||||
}
|
||||
|
||||
recentFiles[path.string()] = ++recentFilesCounter;
|
||||
recentFiles[filesystem::path_to_utf8(path)] = ++recentFilesCounter;
|
||||
recent_files_trim();
|
||||
recent_files_write();
|
||||
}
|
||||
@@ -274,11 +278,12 @@ namespace anm2ed
|
||||
std::ifstream file(path);
|
||||
if (!file)
|
||||
{
|
||||
logger.warning(std::format("Could not load recent files from: {}. Skipping...", path.string()));
|
||||
logger.warning(
|
||||
std::format("Could not load recent files from: {}. Skipping...", filesystem::path_to_utf8(path)));
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info(std::format("Loading recent files from: {}", path.string()));
|
||||
logger.info(std::format("Loading recent files from: {}", filesystem::path_to_utf8(path)));
|
||||
|
||||
std::string line{};
|
||||
std::vector<std::string> loaded{};
|
||||
@@ -288,14 +293,14 @@ namespace anm2ed
|
||||
{
|
||||
if (line.empty()) continue;
|
||||
if (!line.empty() && line.back() == '\r') line.pop_back();
|
||||
std::filesystem::path entry = line;
|
||||
auto entry = filesystem::path_from_utf8(line);
|
||||
std::error_code ec{};
|
||||
if (!std::filesystem::exists(entry, ec))
|
||||
{
|
||||
logger.warning(std::format("Skipping missing recent file: {}", line));
|
||||
continue;
|
||||
}
|
||||
auto entryString = entry.string();
|
||||
auto entryString = filesystem::path_to_utf8(entry);
|
||||
if (!seen.insert(entryString).second) continue;
|
||||
loaded.emplace_back(std::move(entryString));
|
||||
}
|
||||
@@ -319,13 +324,14 @@ namespace anm2ed
|
||||
|
||||
if (!file.is_open())
|
||||
{
|
||||
logger.warning(std::format("Could not write recent files to: {}. Skipping...", path.string()));
|
||||
logger.warning(
|
||||
std::format("Could not write recent files to: {}. Skipping...", filesystem::path_to_utf8(path)));
|
||||
return;
|
||||
}
|
||||
|
||||
auto ordered = recent_files_ordered();
|
||||
for (auto& entry : ordered)
|
||||
file << entry.string() << '\n';
|
||||
file << filesystem::path_to_utf8(entry) << '\n';
|
||||
}
|
||||
|
||||
void Manager::recent_files_clear()
|
||||
@@ -339,10 +345,12 @@ namespace anm2ed
|
||||
{
|
||||
for (auto& path : autosaveFiles)
|
||||
{
|
||||
auto fileName = path.filename().string();
|
||||
if (!fileName.empty() && fileName.front() == '.') fileName.erase(fileName.begin());
|
||||
auto fileNamePath = path.filename();
|
||||
auto fileNameUtf8 = filesystem::path_to_utf8(fileNamePath);
|
||||
if (!fileNameUtf8.empty() && fileNameUtf8.front() == '.') fileNameUtf8.erase(fileNameUtf8.begin());
|
||||
fileNamePath = filesystem::path_from_utf8(fileNameUtf8);
|
||||
|
||||
auto restorePath = path.parent_path() / fileName;
|
||||
auto restorePath = path.parent_path() / fileNamePath;
|
||||
restorePath.replace_extension("");
|
||||
open(path, false, false);
|
||||
|
||||
@@ -364,11 +372,12 @@ namespace anm2ed
|
||||
std::ifstream file(path);
|
||||
if (!file)
|
||||
{
|
||||
logger.warning(std::format("Could not load autosave files from: {}. Skipping...", path.string()));
|
||||
logger.warning(
|
||||
std::format("Could not load autosave files from: {}. Skipping...", filesystem::path_to_utf8(path)));
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info(std::format("Loading autosave files from: {}", path.string()));
|
||||
logger.info(std::format("Loading autosave files from: {}", filesystem::path_to_utf8(path)));
|
||||
|
||||
std::string line{};
|
||||
|
||||
@@ -376,7 +385,7 @@ namespace anm2ed
|
||||
{
|
||||
if (line.empty()) continue;
|
||||
if (!line.empty() && line.back() == '\r') line.pop_back();
|
||||
std::filesystem::path entry = line;
|
||||
auto entry = filesystem::path_from_utf8(line);
|
||||
if (std::find(autosaveFiles.begin(), autosaveFiles.end(), entry) != autosaveFiles.end()) continue;
|
||||
autosaveFiles.emplace_back(std::move(entry));
|
||||
}
|
||||
@@ -389,7 +398,7 @@ namespace anm2ed
|
||||
autosaveWriteFile.open(autosave_path_get(), std::ofstream::out | std::ofstream::trunc);
|
||||
|
||||
for (auto& path : autosaveFiles)
|
||||
autosaveWriteFile << path.string() << "\n";
|
||||
autosaveWriteFile << filesystem::path_to_utf8(path) << "\n";
|
||||
|
||||
autosaveWriteFile.close();
|
||||
}
|
||||
|
||||
@@ -21,11 +21,13 @@
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#include "filesystem_.h"
|
||||
#include "math_.h"
|
||||
|
||||
using namespace anm2ed::resource::texture;
|
||||
using namespace anm2ed::util::math;
|
||||
using namespace glm;
|
||||
namespace filesystem = anm2ed::util::filesystem;
|
||||
|
||||
namespace anm2ed::resource
|
||||
{
|
||||
@@ -116,7 +118,8 @@ namespace anm2ed::resource
|
||||
|
||||
Texture::Texture(const std::filesystem::path& pngPath)
|
||||
{
|
||||
if (const uint8_t* data = stbi_load(pngPath.string().c_str(), &size.x, &size.y, nullptr, CHANNELS); data)
|
||||
auto pngPathUtf8 = filesystem::path_to_utf8(pngPath);
|
||||
if (const uint8_t* data = stbi_load(pngPathUtf8.c_str(), &size.x, &size.y, nullptr, CHANNELS); data)
|
||||
{
|
||||
upload(data);
|
||||
stbi_image_free((void*)data);
|
||||
@@ -125,7 +128,8 @@ namespace anm2ed::resource
|
||||
|
||||
bool Texture::write_png(const std::filesystem::path& path)
|
||||
{
|
||||
return stbi_write_png(path.string().c_str(), size.x, size.y, CHANNELS, this->pixels.data(), size.x * CHANNELS);
|
||||
auto pathUtf8 = filesystem::path_to_utf8(path);
|
||||
return stbi_write_png(pathUtf8.c_str(), size.x, size.y, CHANNELS, this->pixels.data(), size.x * CHANNELS);
|
||||
}
|
||||
|
||||
vec4 Texture::pixel_read(vec2 position) const
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
using namespace anm2ed::util;
|
||||
using namespace glm;
|
||||
namespace filesystem = anm2ed::util::filesystem;
|
||||
|
||||
namespace anm2ed
|
||||
{
|
||||
@@ -121,8 +122,9 @@ DockSpace ID=0x123F8F08 Window=0x6D581B32 Pos=8,62 Size=1902,994 Spl
|
||||
|
||||
Settings::Settings(const std::filesystem::path& path)
|
||||
{
|
||||
auto pathUtf8 = filesystem::path_to_utf8(path);
|
||||
if (filesystem::path_is_exist(path))
|
||||
logger.info(std::format("Using settings from: {}", path.string()));
|
||||
logger.info(std::format("Using settings from: {}", pathUtf8));
|
||||
else
|
||||
{
|
||||
logger.warning("Settings file does not exist; using default");
|
||||
@@ -133,7 +135,7 @@ DockSpace ID=0x123F8F08 Window=0x6D581B32 Pos=8,62 Size=1902,994 Spl
|
||||
std::ifstream file(path);
|
||||
if (!file.is_open())
|
||||
{
|
||||
logger.error(std::format("Failed to open settings file: {}", path.string()));
|
||||
logger.error(std::format("Failed to open settings file: {}", pathUtf8));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace anm2ed
|
||||
dialog = Dialog(window);
|
||||
|
||||
for (const auto& argument : arguments)
|
||||
manager.open(argument);
|
||||
manager.open(filesystem::path_from_utf8(argument));
|
||||
|
||||
manager.chords_set(settings);
|
||||
}
|
||||
@@ -44,10 +44,11 @@ namespace anm2ed
|
||||
{
|
||||
case SDL_EVENT_DROP_FILE:
|
||||
{
|
||||
auto droppedFile = event.drop.data;
|
||||
if (filesystem::path_is_extension(droppedFile, "anm2"))
|
||||
std::string droppedFile = event.drop.data ? event.drop.data : "";
|
||||
if (droppedFile.empty()) break;
|
||||
auto droppedPath = filesystem::path_from_utf8(droppedFile);
|
||||
if (filesystem::path_is_extension(droppedPath, "anm2"))
|
||||
{
|
||||
std::filesystem::path droppedPath{droppedFile};
|
||||
if (manager.documents.empty())
|
||||
manager.open(droppedPath);
|
||||
else
|
||||
@@ -59,21 +60,21 @@ namespace anm2ed
|
||||
}
|
||||
SDL_FlashWindow(window, SDL_FLASH_UNTIL_FOCUSED);
|
||||
}
|
||||
else if (filesystem::path_is_extension(droppedFile, "png"))
|
||||
else if (filesystem::path_is_extension(droppedPath, "png"))
|
||||
{
|
||||
if (auto document = manager.get())
|
||||
document->spritesheet_add(droppedFile);
|
||||
document->spritesheet_add(droppedPath);
|
||||
else
|
||||
{
|
||||
toasts.push(localize.get(TOAST_ADD_SPRITESHEET_FAILED));
|
||||
logger.warning(localize.get(TOAST_ADD_SPRITESHEET_FAILED, anm2ed::ENGLISH));
|
||||
}
|
||||
}
|
||||
else if (filesystem::path_is_extension(droppedFile, "wav") ||
|
||||
filesystem::path_is_extension(droppedFile, "ogg"))
|
||||
else if (filesystem::path_is_extension(droppedPath, "wav") ||
|
||||
filesystem::path_is_extension(droppedPath, "ogg"))
|
||||
{
|
||||
if (auto document = manager.get())
|
||||
document->sound_add(droppedFile);
|
||||
document->sound_add(droppedPath);
|
||||
else
|
||||
{
|
||||
toasts.push(localize.get(TOAST_ADD_SOUND_FAILED));
|
||||
@@ -84,10 +85,12 @@ namespace anm2ed
|
||||
}
|
||||
case SDL_EVENT_USER: // Opening files
|
||||
{
|
||||
auto droppedFile = event.drop.data;
|
||||
if (filesystem::path_is_extension(droppedFile, "anm2"))
|
||||
std::string droppedFile = event.drop.data ? event.drop.data : "";
|
||||
if (droppedFile.empty()) break;
|
||||
auto droppedPath = filesystem::path_from_utf8(droppedFile);
|
||||
if (filesystem::path_is_extension(droppedPath, "anm2"))
|
||||
{
|
||||
manager.open(droppedFile);
|
||||
manager.open(droppedPath);
|
||||
SDL_FlashWindow(window, SDL_FLASH_UNTIL_FOCUSED);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -22,9 +22,10 @@ namespace anm2ed::util::filesystem
|
||||
|
||||
std::filesystem::path path_preferences_get()
|
||||
{
|
||||
auto path = SDL_GetPrefPath(nullptr, "anm2ed");
|
||||
auto filePath = std::filesystem::path(path);
|
||||
SDL_free(path);
|
||||
auto sdlPath = SDL_GetPrefPath(nullptr, "anm2ed");
|
||||
if (!sdlPath) return {};
|
||||
auto filePath = path_from_utf8(sdlPath);
|
||||
SDL_free(sdlPath);
|
||||
return filePath;
|
||||
}
|
||||
|
||||
@@ -46,6 +47,17 @@ namespace anm2ed::util::filesystem
|
||||
return std::filesystem::path(native);
|
||||
}
|
||||
|
||||
std::string path_to_utf8(const std::filesystem::path& path)
|
||||
{
|
||||
auto u8 = path.u8string();
|
||||
return std::string(u8.begin(), u8.end());
|
||||
}
|
||||
|
||||
std::filesystem::path path_from_utf8(const std::string& utf8)
|
||||
{
|
||||
return std::filesystem::path(std::u8string(utf8.begin(), utf8.end()));
|
||||
}
|
||||
|
||||
bool path_is_exist(const std::filesystem::path& path)
|
||||
{
|
||||
std::error_code errorCode;
|
||||
@@ -54,9 +66,9 @@ namespace anm2ed::util::filesystem
|
||||
|
||||
bool path_is_extension(const std::filesystem::path& path, const std::string& extension)
|
||||
{
|
||||
auto e = std::filesystem::path(path).extension().string();
|
||||
std::transform(e.begin(), e.end(), e.begin(), ::tolower);
|
||||
return e == ("." + extension);
|
||||
auto extensionUtf8 = path_to_utf8(std::filesystem::path(path).extension());
|
||||
std::transform(extensionUtf8.begin(), extensionUtf8.end(), extensionUtf8.begin(), ::tolower);
|
||||
return extensionUtf8 == ("." + extension);
|
||||
}
|
||||
|
||||
std::filesystem::path path_lower_case_backslash_handle(const std::filesystem::path& path)
|
||||
|
||||
@@ -8,6 +8,8 @@ namespace anm2ed::util::filesystem
|
||||
std::filesystem::path path_preferences_get();
|
||||
std::filesystem::path path_to_lower(const std::filesystem::path&);
|
||||
std::filesystem::path path_backslash_replace(const std::filesystem::path&);
|
||||
std::string path_to_utf8(const std::filesystem::path&);
|
||||
std::filesystem::path path_from_utf8(const std::string&);
|
||||
|
||||
bool path_is_exist(const std::filesystem::path&);
|
||||
bool path_is_extension(const std::filesystem::path&, const std::string&);
|
||||
|
||||
Reference in New Issue
Block a user