From 02deb03d7d21d5940fae9d64f5092fcc6b5bc0d2 Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Fri, 7 Mar 2025 20:56:45 -0500 Subject: [PATCH] Add settings::lastPatchDirectory and lastSelectionDirectory. Remember these directories when saving/loading patches and selections. --- include/settings.hpp | 2 ++ src/app/RackWidget.cpp | 37 ++++++++++++++++++++++++++----------- src/patch.cpp | 42 +++++++++++++++++++++++++++--------------- src/settings.cpp | 14 ++++++++++++++ 4 files changed, 69 insertions(+), 26 deletions(-) diff --git a/include/settings.hpp b/include/settings.hpp index a867b5fc..f6a7656b 100644 --- a/include/settings.hpp +++ b/include/settings.hpp @@ -81,6 +81,8 @@ extern float frameRateLimit; /** Interval between autosaves in seconds. */ extern float autosaveInterval; extern bool skipLoadOnLaunch; +extern std::string lastPatchDirectory; +extern std::string lastSelectionDirectory; extern std::list recentPatchPaths; extern std::vector cableColors; extern std::vector cableLabels; diff --git a/src/app/RackWidget.cpp b/src/app/RackWidget.cpp index e4c35158..4e7d40d8 100644 --- a/src/app/RackWidget.cpp +++ b/src/app/RackWidget.cpp @@ -1094,25 +1094,33 @@ void RackWidget::loadSelection(std::string path) { } void RackWidget::loadSelectionDialog() { - std::string selectionDir = asset::user("selections"); - system::createDirectories(selectionDir); + std::string dir = settings::lastSelectionDirectory; + + // Use fallback /selections + if (dir == "" || !system::isDirectory(dir)) { + dir = asset::user("selections"); + system::createDirectory(dir); + } osdialog_filters* filters = osdialog_filters_parse(SELECTION_FILTERS); DEFER({osdialog_filters_free(filters);}); - char* pathC = osdialog_file(OSDIALOG_OPEN, selectionDir.c_str(), NULL, filters); + char* pathC = osdialog_file(OSDIALOG_OPEN, dir.c_str(), NULL, filters); if (!pathC) { - // No path selected + // Cancel silently return; } - DEFER({std::free(pathC);}); + std::string path = pathC; + std::free(pathC); try { - loadSelection(pathC); + loadSelection(path); } catch (Exception& e) { osdialog_message(OSDIALOG_WARNING, OSDIALOG_OK, e.what()); } + + settings::lastSelectionDirectory = system::getDirectory(path); } void RackWidget::saveSelection(std::string path) { @@ -1136,25 +1144,32 @@ void RackWidget::saveSelection(std::string path) { } void RackWidget::saveSelectionDialog() { - std::string selectionDir = asset::user("selections"); - system::createDirectories(selectionDir); + std::string dir = settings::lastSelectionDirectory; + + // Use fallback /selections + if (dir == "" || !system::isDirectory(dir)) { + dir = asset::user("selections"); + system::createDirectory(dir); + } osdialog_filters* filters = osdialog_filters_parse(SELECTION_FILTERS); DEFER({osdialog_filters_free(filters);}); - char* pathC = osdialog_file(OSDIALOG_SAVE, selectionDir.c_str(), "Untitled.vcvs", filters); + char* pathC = osdialog_file(OSDIALOG_SAVE, dir.c_str(), "Untitled.vcvs", filters); if (!pathC) { // No path selected return; } - DEFER({std::free(pathC);}); - std::string path = pathC; + std::free(pathC); + // Automatically append .vcvs extension if (system::getExtension(path) != ".vcvs") path += ".vcvs"; saveSelection(path); + + settings::lastSelectionDirectory = system::getDirectory(path); } void RackWidget::copyClipboardSelection() { diff --git a/src/patch.cpp b/src/patch.cpp index 428a185a..344a03e6 100644 --- a/src/patch.cpp +++ b/src/patch.cpp @@ -167,12 +167,18 @@ void Manager::saveAsDialog(bool setPath) { filename = system::getFilename(this->path); } - // Default to /patches + // Use fallback lastPatchDirectory if (dir == "" || !system::isDirectory(dir)) { - dir = asset::user("patches"); - system::createDirectories(dir); + dir = settings::lastPatchDirectory; + + // Use fallback /patches + if (dir == "" || !system::isDirectory(dir)) { + dir = asset::user("patches"); + system::createDirectory(dir); + } } + // Use fallback filename if (filename == "") { filename = "Untitled.vcv"; } @@ -185,19 +191,14 @@ void Manager::saveAsDialog(bool setPath) { // Cancel silently return; } - DEFER({std::free(pathC);}); + std::string path = pathC; + std::free(pathC); // Automatically append .vcv extension - std::string path = pathC; if (system::getExtension(path) != ".vcv") { path += ".vcv"; } - APP->history->setSaved(); - if (setPath) { - this->path = path; - } - try { save(path); } @@ -207,7 +208,13 @@ void Manager::saveAsDialog(bool setPath) { return; } - pushRecentPath(path); + // Commit patch path + APP->history->setSaved(); + if (setPath) { + this->path = path; + settings::lastPatchDirectory = system::getDirectory(path); + pushRecentPath(path); + } } @@ -400,10 +407,15 @@ void Manager::loadDialog() { dir = system::getDirectory(this->path); } - // Default to /patches + // Use fallback lastPatchDirectory if (dir == "" || !system::isDirectory(dir)) { - dir = asset::user("patches"); - system::createDirectory(dir); + dir = settings::lastPatchDirectory; + + // Use fallback /patches + if (dir == "" || !system::isDirectory(dir)) { + dir = asset::user("patches"); + system::createDirectory(dir); + } } osdialog_filters* filters = osdialog_filters_parse(PATCH_FILTERS); @@ -411,7 +423,7 @@ void Manager::loadDialog() { char* pathC = osdialog_file(OSDIALOG_OPEN, dir.c_str(), NULL, filters); if (!pathC) { - // Fail silently + // Cancel silently return; } std::string path = pathC; diff --git a/src/settings.cpp b/src/settings.cpp index e4c702ba..68f5f48f 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -55,6 +55,8 @@ bool preferDarkPanels = false; #endif float autosaveInterval = 15.0; bool skipLoadOnLaunch = false; +std::string lastPatchDirectory; +std::string lastSelectionDirectory; std::list recentPatchPaths; bool cableAutoRotate = true; std::vector cableColors; @@ -190,6 +192,10 @@ json_t* toJson() { if (skipLoadOnLaunch) json_object_set_new(rootJ, "skipLoadOnLaunch", json_boolean(true)); + json_object_set_new(rootJ, "lastPatchDirectory", json_stringn(lastPatchDirectory.c_str(), lastPatchDirectory.size())); + + json_object_set_new(rootJ, "lastSelectionDirectory", json_stringn(lastSelectionDirectory.c_str(), lastSelectionDirectory.size())); + json_t* recentPatchPathsJ = json_array(); for (const std::string& path : recentPatchPaths) { json_array_append_new(recentPatchPathsJ, json_string(path.c_str())); @@ -421,6 +427,14 @@ void fromJson(json_t* rootJ) { if (skipLoadOnLaunchJ) skipLoadOnLaunch = json_boolean_value(skipLoadOnLaunchJ); + json_t* lastPatchDirectoryJ = json_object_get(rootJ, "lastPatchDirectory"); + if (lastPatchDirectoryJ) + lastPatchDirectory = json_string_value(lastPatchDirectoryJ); + + json_t* lastSelectionDirectoryJ = json_object_get(rootJ, "lastSelectionDirectory"); + if (lastSelectionDirectoryJ) + lastSelectionDirectory = json_string_value(lastSelectionDirectoryJ); + recentPatchPaths.clear(); json_t* recentPatchPathsJ = json_object_get(rootJ, "recentPatchPaths"); if (recentPatchPathsJ) {