From a66ce50db88c9f3d07075d8979f6b363b85142d8 Mon Sep 17 00:00:00 2001 From: Ted John Date: Tue, 29 Nov 2016 13:22:11 +0000 Subject: [PATCH] Fix duplicate sequence --- src/core/Collections.hpp | 15 ++++ src/title/TitleSequenceManager.cpp | 137 +++++++++++++++++++++-------- src/title/TitleSequenceManager.h | 6 +- src/windows/title_editor.c | 11 ++- 4 files changed, 126 insertions(+), 43 deletions(-) diff --git a/src/core/Collections.hpp b/src/core/Collections.hpp index 2dbde38388..5775e57718 100644 --- a/src/core/Collections.hpp +++ b/src/core/Collections.hpp @@ -57,6 +57,21 @@ namespace Collections return SIZE_MAX; } + template + static size_t IndexOf(TCollection &collection, TPred predicate) + { + size_t index = 0; + for (auto item : collection) + { + if (predicate(item)) + { + return index; + } + index++; + } + return SIZE_MAX; + } + #pragma region String helpers template diff --git a/src/title/TitleSequenceManager.cpp b/src/title/TitleSequenceManager.cpp index a91b38d425..bed29349cf 100644 --- a/src/title/TitleSequenceManager.cpp +++ b/src/title/TitleSequenceManager.cpp @@ -16,6 +16,7 @@ #include #include +#include "../core/Collections.hpp" #include "../core/FileScanner.h" #include "../core/Memory.hpp" #include "../core/Path.hpp" @@ -50,7 +51,10 @@ namespace TitleSequenceManager std::vector _items; + static size_t FindItemIndexByPath(const utf8 * path); static void Scan(const utf8 * directory); + static void AddSequence(const utf8 * scanPath); + static void SortSequences(); static std::string GetNameFromSequencePath(const std::string &path); static void GetDataSequencesPath(utf8 * buffer, size_t bufferSize); static void GetUserSequencesPath(utf8 * buffer, size_t bufferSize); @@ -65,6 +69,15 @@ namespace TitleSequenceManager return &_items[i]; } + static size_t FindItemIndexByPath(const utf8 * path) + { + size_t index = Collections::IndexOf(_items, [path](const TitleSequenceManagerItem &item) -> bool + { + return String::Equals(path, item.Path.c_str()); + }); + return index; + } + void DeleteItem(size_t i) { auto item = GetItem(i); @@ -80,7 +93,7 @@ namespace TitleSequenceManager _items.erase(_items.begin() + i); } - void RenameItem(size_t i, const utf8 * newName) + size_t RenameItem(size_t i, const utf8 * newName) { auto item = &_items[i]; const utf8 * oldPath = item->Path.c_str(); @@ -100,6 +113,33 @@ namespace TitleSequenceManager item->Name = std::string(newName); item->Path = std::string(newPath); + + SortSequences(); + size_t index = FindItemIndexByPath(newPath); + return index; + } + + size_t DuplicateItem(size_t i, const utf8 * name) + { + auto item = &_items[i]; + const utf8 * srcPath = item->Path.c_str(); + + utf8 dstPath[MAX_PATH]; + Path::GetDirectory(dstPath, sizeof(dstPath), srcPath); + Path::Append(dstPath, sizeof(dstPath), name); + if (item->IsZip) + { + String::Append(dstPath, sizeof(dstPath), TITLE_SEQUENCE_EXTENSION); + } + if (!platform_file_copy(srcPath, dstPath, true)) + { + return SIZE_MAX; + } + + AddSequence(dstPath); + SortSequences(); + size_t index = FindItemIndexByPath(dstPath); + return index; } static const uint16 GetPredefinedIndex(const std::string &path) @@ -115,20 +155,8 @@ namespace TitleSequenceManager return PREDEFINED_INDEX_CUSTOM; } - static void Scan() + static void SortSequences() { - utf8 path[MAX_PATH]; - - _items.clear(); - - // Scan data path - GetDataSequencesPath(path, sizeof(path)); - Scan(path); - - // Scan user path - GetUserSequencesPath(path, sizeof(path)); - Scan(path); - // Sort sequences by predefined index and then name std::sort(_items.begin(), _items.end(), [](const TitleSequenceManagerItem &a, const TitleSequenceManagerItem &b) -> bool @@ -145,6 +173,23 @@ namespace TitleSequenceManager }); } + static void Scan() + { + utf8 path[MAX_PATH]; + + _items.clear(); + + // Scan data path + GetDataSequencesPath(path, sizeof(path)); + Scan(path); + + // Scan user path + GetUserSequencesPath(path, sizeof(path)); + Scan(path); + + SortSequences(); + } + static void Scan(const utf8 * directory) { utf8 pattern[MAX_PATH]; @@ -154,32 +199,43 @@ namespace TitleSequenceManager IFileScanner * fileScanner = Path::ScanDirectory(pattern, true); while (fileScanner->Next()) { - std::string path = std::string(fileScanner->GetPath()); - bool isZip = true; - if (String::Equals(Path::GetExtension(path.c_str()), ".txt", true)) - { - path = std::string(Path::GetDirectory(path.c_str())); - isZip = false; - } - - TitleSequenceManagerItem item; - item.PredefinedIndex = GetPredefinedIndex(path); - item.Path = path; - if (item.PredefinedIndex != PREDEFINED_INDEX_CUSTOM) - { - rct_string_id stringId = PredefinedSequences[item.PredefinedIndex].StringId; - item.Name = String::Duplicate(language_get_string(stringId)); - } - else - { - item.Name = GetNameFromSequencePath(path); - } - item.IsZip = isZip; - _items.push_back(item); + const utf8 * path = fileScanner->GetPath(); + AddSequence(path); } delete fileScanner; } + static void AddSequence(const utf8 * scanPath) + { + std::string path; + bool isZip = true; + if (String::Equals(Path::GetExtension(scanPath), ".txt", true)) + { + // If we are given a .txt file, set the path to the containing directory + path = std::string(Path::GetDirectory(scanPath)); + isZip = false; + } + else + { + path = std::string(scanPath); + } + + TitleSequenceManagerItem item; + item.PredefinedIndex = GetPredefinedIndex(path); + item.Path = path; + if (item.PredefinedIndex != PREDEFINED_INDEX_CUSTOM) + { + rct_string_id stringId = PredefinedSequences[item.PredefinedIndex].StringId; + item.Name = String::Duplicate(language_get_string(stringId)); + } + else + { + item.Name = GetNameFromSequencePath(path); + } + item.IsZip = isZip; + _items.push_back(item); + } + static std::string GetNameFromSequencePath(const std::string &path) { utf8 * name = Path::GetFileNameWithoutExtension(path.c_str()); @@ -281,8 +337,13 @@ extern "C" TitleSequenceManager::DeleteItem(i); } - void title_sequence_manager_rename(size_t i, const utf8 * newName) + size_t title_sequence_manager_rename(size_t i, const utf8 * name) { - TitleSequenceManager::RenameItem(i, newName); + return TitleSequenceManager::RenameItem(i, name); + } + + size_t title_sequence_manager_duplicate(size_t i, const utf8 * name) + { + return TitleSequenceManager::DuplicateItem(i, name); } } diff --git a/src/title/TitleSequenceManager.h b/src/title/TitleSequenceManager.h index 27e96a5e86..57d04119c5 100644 --- a/src/title/TitleSequenceManager.h +++ b/src/title/TitleSequenceManager.h @@ -35,7 +35,8 @@ namespace TitleSequenceManager size_t GetCount(); const TitleSequenceManagerItem * GetItem(size_t i); void DeleteItem(size_t i); - void RenameItem(size_t i, const utf8 * newName); + size_t RenameItem(size_t i, const utf8 * name); + size_t DuplicateItem(size_t i, const utf8 * name); } constexpr uint16 PREDEFINED_INDEX_CUSTOM = UINT16_MAX; @@ -52,7 +53,8 @@ extern "C" { size_t title_sequence_manager_get_index_for_name(const utf8 * name); void title_sequence_manager_scan(); void title_sequence_manager_delete(size_t i); - void title_sequence_manager_rename(size_t i, const utf8 * newName); + size_t title_sequence_manager_rename(size_t i, const utf8 * name); + size_t title_sequence_manager_duplicate(size_t i, const utf8 * name); #ifdef __cplusplus } diff --git a/src/windows/title_editor.c b/src/windows/title_editor.c index 8024ad8ffd..e48debe268 100644 --- a/src/windows/title_editor.c +++ b/src/windows/title_editor.c @@ -611,10 +611,11 @@ static void window_title_editor_textinput(rct_window *w, int widgetIndex, char * if (widgetIndex == WIDX_TITLE_EDITOR_NEW_BUTTON) { title_sequence_create_preset(text); } else if (widgetIndex == WIDX_TITLE_EDITOR_DUPLICATE_BUTTON) { - // title_sequence_duplicate_preset(_selectedTitleSequence, text); + size_t newIndex = title_sequence_manager_duplicate(_selectedTitleSequence, text); + window_title_editor_load_sequence(newIndex); } else { - title_sequence_manager_rename(_selectedTitleSequence, text); - _sequenceName = title_sequence_manager_get_name(_selectedTitleSequence); + size_t newIndex = title_sequence_manager_rename(_selectedTitleSequence, text); + window_title_editor_load_sequence(newIndex); } config_save_default(); window_invalidate(w); @@ -936,6 +937,10 @@ static void window_title_editor_draw_tab_images(rct_drawpixelinfo *dpi, rct_wind static void window_title_editor_load_sequence(size_t index) { + if (index >= title_sequence_manager_get_count()) { + return; + } + const char * path = title_sequence_manager_get_path(index); TitleSequence * titleSequence = LoadTitleSequence(path); if (titleSequence == NULL) {