| @@ -81,6 +81,8 @@ extern float frameRateLimit; | |||||
| /** Interval between autosaves in seconds. */ | /** Interval between autosaves in seconds. */ | ||||
| extern float autosaveInterval; | extern float autosaveInterval; | ||||
| extern bool skipLoadOnLaunch; | extern bool skipLoadOnLaunch; | ||||
| extern std::string lastPatchDirectory; | |||||
| extern std::string lastSelectionDirectory; | |||||
| extern std::list<std::string> recentPatchPaths; | extern std::list<std::string> recentPatchPaths; | ||||
| extern std::vector<NVGcolor> cableColors; | extern std::vector<NVGcolor> cableColors; | ||||
| extern std::vector<std::string> cableLabels; | extern std::vector<std::string> cableLabels; | ||||
| @@ -1094,25 +1094,33 @@ void RackWidget::loadSelection(std::string path) { | |||||
| } | } | ||||
| void RackWidget::loadSelectionDialog() { | void RackWidget::loadSelectionDialog() { | ||||
| std::string selectionDir = asset::user("selections"); | |||||
| system::createDirectories(selectionDir); | |||||
| std::string dir = settings::lastSelectionDirectory; | |||||
| // Use fallback <Rack user dir>/selections | |||||
| if (dir == "" || !system::isDirectory(dir)) { | |||||
| dir = asset::user("selections"); | |||||
| system::createDirectory(dir); | |||||
| } | |||||
| osdialog_filters* filters = osdialog_filters_parse(SELECTION_FILTERS); | osdialog_filters* filters = osdialog_filters_parse(SELECTION_FILTERS); | ||||
| DEFER({osdialog_filters_free(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) { | if (!pathC) { | ||||
| // No path selected | |||||
| // Cancel silently | |||||
| return; | return; | ||||
| } | } | ||||
| DEFER({std::free(pathC);}); | |||||
| std::string path = pathC; | |||||
| std::free(pathC); | |||||
| try { | try { | ||||
| loadSelection(pathC); | |||||
| loadSelection(path); | |||||
| } | } | ||||
| catch (Exception& e) { | catch (Exception& e) { | ||||
| osdialog_message(OSDIALOG_WARNING, OSDIALOG_OK, e.what()); | osdialog_message(OSDIALOG_WARNING, OSDIALOG_OK, e.what()); | ||||
| } | } | ||||
| settings::lastSelectionDirectory = system::getDirectory(path); | |||||
| } | } | ||||
| void RackWidget::saveSelection(std::string path) { | void RackWidget::saveSelection(std::string path) { | ||||
| @@ -1136,25 +1144,32 @@ void RackWidget::saveSelection(std::string path) { | |||||
| } | } | ||||
| void RackWidget::saveSelectionDialog() { | void RackWidget::saveSelectionDialog() { | ||||
| std::string selectionDir = asset::user("selections"); | |||||
| system::createDirectories(selectionDir); | |||||
| std::string dir = settings::lastSelectionDirectory; | |||||
| // Use fallback <Rack user dir>/selections | |||||
| if (dir == "" || !system::isDirectory(dir)) { | |||||
| dir = asset::user("selections"); | |||||
| system::createDirectory(dir); | |||||
| } | |||||
| osdialog_filters* filters = osdialog_filters_parse(SELECTION_FILTERS); | osdialog_filters* filters = osdialog_filters_parse(SELECTION_FILTERS); | ||||
| DEFER({osdialog_filters_free(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) { | if (!pathC) { | ||||
| // No path selected | // No path selected | ||||
| return; | return; | ||||
| } | } | ||||
| DEFER({std::free(pathC);}); | |||||
| std::string path = pathC; | std::string path = pathC; | ||||
| std::free(pathC); | |||||
| // Automatically append .vcvs extension | // Automatically append .vcvs extension | ||||
| if (system::getExtension(path) != ".vcvs") | if (system::getExtension(path) != ".vcvs") | ||||
| path += ".vcvs"; | path += ".vcvs"; | ||||
| saveSelection(path); | saveSelection(path); | ||||
| settings::lastSelectionDirectory = system::getDirectory(path); | |||||
| } | } | ||||
| void RackWidget::copyClipboardSelection() { | void RackWidget::copyClipboardSelection() { | ||||
| @@ -167,12 +167,18 @@ void Manager::saveAsDialog(bool setPath) { | |||||
| filename = system::getFilename(this->path); | filename = system::getFilename(this->path); | ||||
| } | } | ||||
| // Default to <Rack user dir>/patches | |||||
| // Use fallback lastPatchDirectory | |||||
| if (dir == "" || !system::isDirectory(dir)) { | if (dir == "" || !system::isDirectory(dir)) { | ||||
| dir = asset::user("patches"); | |||||
| system::createDirectories(dir); | |||||
| dir = settings::lastPatchDirectory; | |||||
| // Use fallback <Rack user dir>/patches | |||||
| if (dir == "" || !system::isDirectory(dir)) { | |||||
| dir = asset::user("patches"); | |||||
| system::createDirectory(dir); | |||||
| } | |||||
| } | } | ||||
| // Use fallback filename | |||||
| if (filename == "") { | if (filename == "") { | ||||
| filename = "Untitled.vcv"; | filename = "Untitled.vcv"; | ||||
| } | } | ||||
| @@ -185,19 +191,14 @@ void Manager::saveAsDialog(bool setPath) { | |||||
| // Cancel silently | // Cancel silently | ||||
| return; | return; | ||||
| } | } | ||||
| DEFER({std::free(pathC);}); | |||||
| std::string path = pathC; | |||||
| std::free(pathC); | |||||
| // Automatically append .vcv extension | // Automatically append .vcv extension | ||||
| std::string path = pathC; | |||||
| if (system::getExtension(path) != ".vcv") { | if (system::getExtension(path) != ".vcv") { | ||||
| path += ".vcv"; | path += ".vcv"; | ||||
| } | } | ||||
| APP->history->setSaved(); | |||||
| if (setPath) { | |||||
| this->path = path; | |||||
| } | |||||
| try { | try { | ||||
| save(path); | save(path); | ||||
| } | } | ||||
| @@ -207,7 +208,13 @@ void Manager::saveAsDialog(bool setPath) { | |||||
| return; | 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); | dir = system::getDirectory(this->path); | ||||
| } | } | ||||
| // Default to <Rack user dir>/patches | |||||
| // Use fallback lastPatchDirectory | |||||
| if (dir == "" || !system::isDirectory(dir)) { | if (dir == "" || !system::isDirectory(dir)) { | ||||
| dir = asset::user("patches"); | |||||
| system::createDirectory(dir); | |||||
| dir = settings::lastPatchDirectory; | |||||
| // Use fallback <Rack user dir>/patches | |||||
| if (dir == "" || !system::isDirectory(dir)) { | |||||
| dir = asset::user("patches"); | |||||
| system::createDirectory(dir); | |||||
| } | |||||
| } | } | ||||
| osdialog_filters* filters = osdialog_filters_parse(PATCH_FILTERS); | 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); | char* pathC = osdialog_file(OSDIALOG_OPEN, dir.c_str(), NULL, filters); | ||||
| if (!pathC) { | if (!pathC) { | ||||
| // Fail silently | |||||
| // Cancel silently | |||||
| return; | return; | ||||
| } | } | ||||
| std::string path = pathC; | std::string path = pathC; | ||||
| @@ -55,6 +55,8 @@ bool preferDarkPanels = false; | |||||
| #endif | #endif | ||||
| float autosaveInterval = 15.0; | float autosaveInterval = 15.0; | ||||
| bool skipLoadOnLaunch = false; | bool skipLoadOnLaunch = false; | ||||
| std::string lastPatchDirectory; | |||||
| std::string lastSelectionDirectory; | |||||
| std::list<std::string> recentPatchPaths; | std::list<std::string> recentPatchPaths; | ||||
| bool cableAutoRotate = true; | bool cableAutoRotate = true; | ||||
| std::vector<NVGcolor> cableColors; | std::vector<NVGcolor> cableColors; | ||||
| @@ -190,6 +192,10 @@ json_t* toJson() { | |||||
| if (skipLoadOnLaunch) | if (skipLoadOnLaunch) | ||||
| json_object_set_new(rootJ, "skipLoadOnLaunch", json_boolean(true)); | 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(); | json_t* recentPatchPathsJ = json_array(); | ||||
| for (const std::string& path : recentPatchPaths) { | for (const std::string& path : recentPatchPaths) { | ||||
| json_array_append_new(recentPatchPathsJ, json_string(path.c_str())); | json_array_append_new(recentPatchPathsJ, json_string(path.c_str())); | ||||
| @@ -421,6 +427,14 @@ void fromJson(json_t* rootJ) { | |||||
| if (skipLoadOnLaunchJ) | if (skipLoadOnLaunchJ) | ||||
| skipLoadOnLaunch = json_boolean_value(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(); | recentPatchPaths.clear(); | ||||
| json_t* recentPatchPathsJ = json_object_get(rootJ, "recentPatchPaths"); | json_t* recentPatchPathsJ = json_object_get(rootJ, "recentPatchPaths"); | ||||
| if (recentPatchPathsJ) { | if (recentPatchPathsJ) { | ||||