From c3b76bacaddce404f3bc86ed29e8b18a6861238d Mon Sep 17 00:00:00 2001 From: David Robillard Date: Thu, 4 Mar 2010 06:34:58 +0000 Subject: Always save to Ingen bundles (directories with names like foo.ingen.lv2 containg at least manifest.ttl and foo.ingen.ttl). Gracefully handle attempts to save over files, directories resembling ingen bundles, and non-ingen directories. Use Glib::file_test instead of attempting to open files with fstream. Construct a root patch URI from the bundle URI if Parser::parse_document is passed a bundle URI. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@2515 a436a847-0d15-0410-975c-d299462d15a1 --- src/gui/App.cpp | 2 -- src/gui/LoadPatchWindow.cpp | 3 ++ src/gui/PatchWindow.cpp | 83 ++++++++++++++++++++++++++------------------- src/gui/ThreadedLoader.cpp | 2 +- 4 files changed, 53 insertions(+), 37 deletions(-) (limited to 'src/gui') diff --git a/src/gui/App.cpp b/src/gui/App.cpp index 968d5940..be15d4cb 100644 --- a/src/gui/App.cpp +++ b/src/gui/App.cpp @@ -339,8 +339,6 @@ App::quit(Gtk::Window& dialog_parent) if (quit) Gtk::Main::quit(); - //App::instance().engine()->quit(); - return quit; } diff --git a/src/gui/LoadPatchWindow.cpp b/src/gui/LoadPatchWindow.cpp index c274a30d..3a06843b 100644 --- a/src/gui/LoadPatchWindow.cpp +++ b/src/gui/LoadPatchWindow.cpp @@ -162,6 +162,9 @@ LoadPatchWindow::ok_clicked() uris.ingen_polyphony, _poly_spinbutton->get_value_as_int())); + if (get_uri() == "") + return; + if (_import) { // If unset load_patch will load value optional parent; diff --git a/src/gui/PatchWindow.cpp b/src/gui/PatchWindow.cpp index c4e7a39a..a9fe62d2 100644 --- a/src/gui/PatchWindow.cpp +++ b/src/gui/PatchWindow.cpp @@ -18,8 +18,9 @@ #include "PatchWindow.hpp" #include #include -#include #include +#include +#include #include "raul/AtomRDF.hpp" #include "interface/EngineInterface.hpp" #include "shared/LV2URIMap.hpp" @@ -408,7 +409,8 @@ PatchWindow::event_save() } else { App::instance().loader()->save_patch(_patch, document.get_uri()); _status_bar->push( - (boost::format("Wrote %1% to %2%") % _patch->path() % document.get_uri()).str(), + (boost::format("Saved %1% to %2%") % _patch->path().chop_scheme() + % document.get_uri()).str(), STATUS_CONTEXT_PATCH); } } @@ -426,8 +428,6 @@ PatchWindow::event_save_as() save_button->property_has_default() = true; Gtk::FileFilter filt; - filt.add_pattern("*.ingen.ttl"); - filt.set_name("Ingen patches"); filt.add_pattern("*.ingen.lv2"); filt.set_name("Ingen bundles"); dialog.set_filter(filt); @@ -442,50 +442,68 @@ PatchWindow::event_save_as() if (dialog.run() != Gtk::RESPONSE_OK) break; - string filename = dialog.get_filename(); - - string base = filename.substr(0, filename.find(".")); - if (base.find("/") != string::npos) - base = base.substr(base.find_last_of("/") + 1); + std::string filename = dialog.get_filename(); + std::string basename = Glib::path_get_basename(filename); - if (!Symbol::is_valid(base)) { + if (basename.find('.') == string::npos) { + filename += ".ingen.lv2"; + basename += ".ingen.lv2"; + } else if (filename.substr(filename.length() - 10) != ".ingen.lv2") { Gtk::MessageDialog error_dialog(*this, - "Ingen patch file names must be valid symbols", true, - Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); - error_dialog.set_secondary_text( - "The first character must be _, a-z, or A-Z, and " - "subsequent characters must be _, a-z, A-Z, or 0-9."); +"" "Ingen patches must be saved to Ingen bundles (*.ingen.lv2)." "", + true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); error_dialog.run(); continue; } - const bool is_bundle = filename.find(".ingen.lv2") != string::npos; - const bool is_patch = filename.find(".ingen.ttl") != string::npos; + const std::string symbol(basename.substr(0, basename.find('.'))); - // Save a bundle by default - if (!is_bundle && !is_patch) - filename += ".ingen.ttl"; + if (!Symbol::is_valid(symbol)) { + Gtk::MessageDialog error_dialog(*this, + "" "Ingen bundle names must be valid symbols." "", + true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); + error_dialog.set_secondary_text( +"All characters must be _, a-z, A-Z, or 0-9, but the first may not be 0-9."); + error_dialog.run(); + continue; + } - _patch->set_property(uris.lv2_symbol, Atom(base.c_str())); + _patch->set_property(uris.lv2_symbol, Atom(symbol.c_str())); bool confirm = true; - std::fstream fin; - fin.open(filename.c_str(), std::ios::in); - if (fin.is_open()) { // File exists - string msg = "File already exists! Are you sure you want to overwrite "; - msg += filename + "?"; - Gtk::MessageDialog confirm_dialog(*this, - msg, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true); + if (Glib::file_test(filename, Glib::FILE_TEST_IS_DIR)) { + if (Glib::file_test(filename + "/manifest.ttl", Glib::FILE_TEST_EXISTS)) { + Gtk::MessageDialog confirm_dialog(*this, (boost::format("" + "A bundle named \"%1%\" already exists. Replace it?" + "") % basename).str(), + true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true); + confirm = (confirm_dialog.run() == Gtk::RESPONSE_YES); + } else { + Gtk::MessageDialog confirm_dialog(*this, (boost::format("" +"A directory named \"%1%\" already exists, but is not an Ingen bundle. \ +Save into it anyway?" "") % basename).str(), + true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true); + confirm_dialog.set_secondary_text( +"This will create at least 2 .ttl files in this directory, and possibly several \ +more files and/or directories, recursively. Existing files will be overwritten."); + confirm = (confirm_dialog.run() == Gtk::RESPONSE_YES); + } + } else if (Glib::file_test(filename, Glib::FILE_TEST_EXISTS)) { + Gtk::MessageDialog confirm_dialog(*this, (boost::format("" +"A file named \"%1%\" already exists. Replace it with an Ingen bundle?" "") % basename).str(), + true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true); confirm = (confirm_dialog.run() == Gtk::RESPONSE_YES); + if (confirm) + ::g_remove(filename.c_str()); } - fin.close(); if (confirm) { const Glib::ustring uri = Glib::filename_to_uri(filename); App::instance().loader()->save_patch(_patch, uri); _patch->set_property(uris.ingen_document, Atom(Atom::URI, uri.c_str())); _status_bar->push( - (boost::format("Wrote %1% to %2%") % _patch->path() % uri).str(), + (boost::format("Saved %1% to %2%") % _patch->path().chop_scheme() + % filename).str(), STATUS_CONTEXT_PATCH); } @@ -519,16 +537,13 @@ PatchWindow::event_draw() filename += ".dot"; bool confirm = true; - std::fstream fin; - fin.open(filename.c_str(), std::ios::in); - if (fin.is_open()) { // File exists + if (Glib::file_test(filename, Glib::FILE_TEST_EXISTS)) { const string msg = string("File exists!\n") + "Are you sure you want to overwrite " + filename + "?"; Gtk::MessageDialog confirm_dialog(*this, msg, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true); confirm = (confirm_dialog.run() == Gtk::RESPONSE_YES); } - fin.close(); if (confirm) { _view->canvas()->render_to_dot(filename); diff --git a/src/gui/ThreadedLoader.cpp b/src/gui/ThreadedLoader.cpp index 007bb816..6da5bcd0 100644 --- a/src/gui/ThreadedLoader.cpp +++ b/src/gui/ThreadedLoader.cpp @@ -137,7 +137,7 @@ ThreadedLoader::save_patch_event(SharedPtr model, const string& file { if (App::instance().serialiser()) { Serialiser::Record r(model, filename); - if (filename.find(".ingen.lv2") != string::npos) + if (filename.find(".ingen") != string::npos) App::instance().serialiser()->write_bundle(r); else App::instance().serialiser()->to_file(r); -- cgit v1.2.1