summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2010-03-04 06:34:58 +0000
committerDavid Robillard <d@drobilla.net>2010-03-04 06:34:58 +0000
commitc3b76bacaddce404f3bc86ed29e8b18a6861238d (patch)
tree57d3d9e05f9513593358f9ca9d6ba5e08df1e032
parent3157f13a4f8227d53d4c6c0669d2ea2e7ebe7d6b (diff)
downloadingen-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
-rw-r--r--src/gui/App.cpp2
-rw-r--r--src/gui/LoadPatchWindow.cpp3
-rw-r--r--src/gui/PatchWindow.cpp83
-rw-r--r--src/gui/ThreadedLoader.cpp2
-rw-r--r--src/serialisation/Parser.cpp15
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)