diff options
author | David Robillard <d@drobilla.net> | 2010-03-04 06:34:58 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2010-03-04 06:34:58 +0000 |
commit | c3b76bacaddce404f3bc86ed29e8b18a6861238d (patch) | |
tree | 57d3d9e05f9513593358f9ca9d6ba5e08df1e032 /src | |
parent | 3157f13a4f8227d53d4c6c0669d2ea2e7ebe7d6b (diff) | |
download | ingen-c3b76bacaddce404f3bc86ed29e8b18a6861238d.tar.gz ingen-c3b76bacaddce404f3bc86ed29e8b18a6861238d.tar.bz2 ingen-c3b76bacaddce404f3bc86ed29e8b18a6861238d.zip |
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
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/App.cpp | 2 | ||||
-rw-r--r-- | src/gui/LoadPatchWindow.cpp | 3 | ||||
-rw-r--r-- | src/gui/PatchWindow.cpp | 83 | ||||
-rw-r--r-- | src/gui/ThreadedLoader.cpp | 2 | ||||
-rw-r--r-- | src/serialisation/Parser.cpp | 15 |
5 files changed, 66 insertions, 39 deletions
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<Path> 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 <cassert> #include <sstream> -#include <fstream> #include <boost/format.hpp> +#include <glib/gstdio.h> +#include <glibmm/fileutils.h> #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, - "<b>Ingen patch file names must be valid symbols</b>", 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."); +"<b>" "Ingen patches must be saved to Ingen bundles (*.ingen.lv2)." "</b>", + 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, + "<b>" "Ingen bundle names must be valid symbols." "</b>", + 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("<b>" + "A bundle named \"%1%\" already exists. Replace it?" + "</b>") % 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("<b>" +"A directory named \"%1%\" already exists, but is not an Ingen bundle. \ +Save into it anyway?" "</b>") % 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("<b>" +"A file named \"%1%\" already exists. Replace it with an Ingen bundle?" "</b>") % 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<PatchModel> 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); diff --git a/src/serialisation/Parser.cpp b/src/serialisation/Parser.cpp index 68ac46ce..11c0efb1 100644 --- a/src/serialisation/Parser.cpp +++ b/src/serialisation/Parser.cpp @@ -19,6 +19,8 @@ #include <locale.h> #include <glibmm/ustring.h> #include <glibmm/miscutils.h> +#include <glibmm/fileutils.h> +#include <glibmm/convert.h> #include "raul/log.hpp" #include "redlandmm/Model.hpp" #include "redlandmm/Node.hpp" @@ -83,11 +85,20 @@ Parser::parse_document( { normalise_uri(document_uri); + const std::string filename(Glib::filename_from_uri(document_uri)); + const size_t ext = filename.find(".ingen.lv2"); + if (ext == filename.length() - 10 + || (ext == filename.length() - 11 && filename[filename.length() - 1] == '/')) { + std::string basename(Glib::path_get_basename(filename)); + basename = basename.substr(0, basename.find('.')); + document_uri += "/" + basename + ".ingen.ttl"; + } + Redland::Model model(*world->rdf_world, document_uri, document_uri); - LOG(info) << "Parsing document " << document_uri << endl; + LOG(info) << "Parsing " << document_uri << endl; if (data_path) - LOG(info) << "Document path: " << *data_path << endl; + LOG(info) << "Path: " << *data_path << endl; if (parent) LOG(info) << "Parent: " << *parent << endl; if (symbol) |