diff options
author | David Robillard <d@drobilla.net> | 2010-02-14 20:19:11 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2010-02-14 20:19:11 +0000 |
commit | 449af7b35ac64ed90ef635e7657870f524e12c26 (patch) | |
tree | 23ca3f19ebf51b2290ee1c4fa4de9a41c416e202 /src | |
parent | 2bbf30f19ee91c930f564fcb3b44308910bc20a7 (diff) | |
download | ingen-449af7b35ac64ed90ef635e7657870f524e12c26.tar.gz ingen-449af7b35ac64ed90ef635e7657870f524e12c26.tar.bz2 ingen-449af7b35ac64ed90ef635e7657870f524e12c26.zip |
Fix loading of subpatches.
git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@2450 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src')
-rw-r--r-- | src/engine/events/SetMetadata.cpp | 2 | ||||
-rw-r--r-- | src/gui/LoadPatchWindow.cpp | 41 | ||||
-rw-r--r-- | src/gui/LoadPatchWindow.hpp | 14 | ||||
-rw-r--r-- | src/gui/LoadPluginWindow.cpp | 22 | ||||
-rw-r--r-- | src/gui/LoadPluginWindow.hpp | 2 | ||||
-rw-r--r-- | src/gui/LoadSubpatchWindow.cpp | 101 | ||||
-rw-r--r-- | src/gui/LoadSubpatchWindow.hpp | 13 | ||||
-rw-r--r-- | src/gui/WindowFactory.cpp | 2 | ||||
-rw-r--r-- | src/gui/ingen_gui.glade | 439 | ||||
-rw-r--r-- | src/serialisation/Parser.cpp | 73 |
10 files changed, 361 insertions, 348 deletions
diff --git a/src/engine/events/SetMetadata.cpp b/src/engine/events/SetMetadata.cpp index 48de6b85..5e289928 100644 --- a/src/engine/events/SetMetadata.cpp +++ b/src/engine/events/SetMetadata.cpp @@ -68,6 +68,7 @@ SetMetadata::SetMetadata( , _create(create) , _is_meta(meta) { +#if 0 LOG(debug) << "Set " << subject << " {" << endl; typedef Resource::Properties::const_iterator iterator; for (iterator i = properties.begin(); i != properties.end(); ++i) @@ -79,6 +80,7 @@ SetMetadata::SetMetadata( for (iterator i = remove.begin(); i != remove.end(); ++i) LOG(debug) << " " << i->first << " = " << i->second << " :: " << i->second.type() << endl; LOG(debug) << "}" << endl; +#endif } diff --git a/src/gui/LoadPatchWindow.cpp b/src/gui/LoadPatchWindow.cpp index db65968b..bba7c75d 100644 --- a/src/gui/LoadPatchWindow.cpp +++ b/src/gui/LoadPatchWindow.cpp @@ -39,27 +39,30 @@ namespace GUI { LoadPatchWindow::LoadPatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml) : Gtk::FileChooserDialog(cobject) - , _replace(true) + , _merge_ports(true) { - xml->get_widget("load_patch_poly_from_current_radio", _poly_from_current_radio); + xml->get_widget("load_patch_poly_voices_radio", _poly_voices_radio); xml->get_widget("load_patch_poly_from_file_radio", _poly_from_file_radio); - xml->get_widget("load_patch_poly_from_user_radio", _poly_from_user_radio); xml->get_widget("load_patch_poly_spinbutton", _poly_spinbutton); + xml->get_widget("load_patch_merge_ports_radio", _merge_ports_radio); + xml->get_widget("load_patch_insert_ports_radio", _insert_ports_radio); xml->get_widget("load_patch_ok_button", _ok_button); xml->get_widget("load_patch_cancel_button", _cancel_button); - _poly_from_current_radio->signal_toggled().connect( - sigc::mem_fun(this, &LoadPatchWindow::poly_from_file_selected)); _poly_from_file_radio->signal_toggled().connect( sigc::mem_fun(this, &LoadPatchWindow::poly_from_file_selected)); - _poly_from_user_radio->signal_toggled().connect( - sigc::mem_fun(this, &LoadPatchWindow::poly_from_user_selected)); + _poly_voices_radio->signal_toggled().connect( + sigc::mem_fun(this, &LoadPatchWindow::poly_voices_selected)); + _merge_ports_radio->signal_toggled().connect( + sigc::mem_fun(this, &LoadPatchWindow::merge_ports_selected)); + _insert_ports_radio->signal_toggled().connect( + sigc::mem_fun(this, &LoadPatchWindow::insert_ports_selected)); _ok_button->signal_clicked().connect( sigc::mem_fun(this, &LoadPatchWindow::ok_clicked)); _cancel_button->signal_clicked().connect( sigc::mem_fun(this, &LoadPatchWindow::cancel_clicked)); - _poly_from_current_radio->set_active(true); + _poly_voices_radio->set_active(true); Gtk::FileFilter filt; filt.add_pattern("*.om"); @@ -89,7 +92,7 @@ LoadPatchWindow::present(SharedPtr<PatchModel> patch, GraphObject::Properties da } -/** Sets the patch controller for this window and initializes everything. +/** Sets the patch model for this window and initializes everything. * * This function MUST be called before using the window in any way! */ @@ -97,6 +100,7 @@ void LoadPatchWindow::set_patch(SharedPtr<PatchModel> patch) { _patch = patch; + _poly_spinbutton->set_value(patch->poly()); } @@ -120,11 +124,24 @@ LoadPatchWindow::poly_from_file_selected() void -LoadPatchWindow::poly_from_user_selected() +LoadPatchWindow::poly_voices_selected() { _poly_spinbutton->property_sensitive() = true; } +void +LoadPatchWindow::merge_ports_selected() +{ + _merge_ports = true; +} + + +void +LoadPatchWindow::insert_ports_selected() +{ + _merge_ports = false; +} + void LoadPatchWindow::ok_clicked() @@ -136,7 +153,7 @@ LoadPatchWindow::ok_clicked() optional<Path> parent; optional<Symbol> symbol; - if (_poly_from_user_radio->get_active()) + if (_poly_voices_radio->get_active()) _initial_data.insert(make_pair( App::instance().uris().ingen_polyphony, _poly_spinbutton->get_value_as_int())); @@ -146,6 +163,8 @@ LoadPatchWindow::ok_clicked() symbol = _patch->symbol(); } + cout << "MERGE PORTS: " << _merge_ports << endl; + _patch.reset(); hide(); diff --git a/src/gui/LoadPatchWindow.hpp b/src/gui/LoadPatchWindow.hpp index a3356de6..faae39dd 100644 --- a/src/gui/LoadPatchWindow.hpp +++ b/src/gui/LoadPatchWindow.hpp @@ -52,29 +52,29 @@ public: void set_patch(SharedPtr<PatchModel> patch); - void set_replace() { _replace = true; } - void set_merge() { _replace = false; } - void present(SharedPtr<PatchModel> patch, GraphObject::Properties data); protected: void on_show(); private: + void poly_voices_selected(); void poly_from_file_selected(); - void poly_from_user_selected(); + void merge_ports_selected(); + void insert_ports_selected(); void ok_clicked(); void cancel_clicked(); GraphObject::Properties _initial_data; SharedPtr<PatchModel> _patch; - bool _replace; + bool _merge_ports; - Gtk::RadioButton* _poly_from_current_radio; + Gtk::RadioButton* _poly_voices_radio; Gtk::RadioButton* _poly_from_file_radio; - Gtk::RadioButton* _poly_from_user_radio; Gtk::SpinButton* _poly_spinbutton; + Gtk::RadioButton* _merge_ports_radio; + Gtk::RadioButton* _insert_ports_radio; Gtk::Button* _ok_button; Gtk::Button* _cancel_button; }; diff --git a/src/gui/LoadPluginWindow.cpp b/src/gui/LoadPluginWindow.cpp index 39ed0f3d..ab94b919 100644 --- a/src/gui/LoadPluginWindow.cpp +++ b/src/gui/LoadPluginWindow.cpp @@ -38,7 +38,7 @@ namespace GUI { LoadPluginWindow::LoadPluginWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml) : Window(cobject) - , _plugin_name_offset(0) + , _name_offset(0) , _has_shown(false) , _refresh_list(true) { @@ -290,23 +290,27 @@ LoadPluginWindow::plugin_selection_changed() { size_t n_selected = _selection->get_selected_rows().size(); if (n_selected == 0) { - _plugin_name_offset = 0; + _name_offset = 0; _node_name_entry->set_text(""); + _node_name_entry->set_sensitive(false); } else if (n_selected == 1) { Gtk::TreeModel::iterator iter = _plugins_liststore->get_iter( *_selection->get_selected_rows().begin()); if (iter) { Gtk::TreeModel::Row row = *iter; boost::shared_ptr<PluginModel> p = row.get_value(_plugins_columns._col_plugin); - _plugin_name_offset = App::instance().store()->child_name_offset( + _name_offset = App::instance().store()->child_name_offset( _patch->path(), p->default_node_symbol()); - _node_name_entry->set_text(generate_module_name(p, _plugin_name_offset)); + _node_name_entry->set_text(generate_module_name(p, _name_offset)); + _node_name_entry->set_sensitive(true); } else { - _plugin_name_offset = 0; + _name_offset = 0; _node_name_entry->set_text(""); + _node_name_entry->set_sensitive(false); } } else { - _node_name_entry->set_text(NAME_ENTRY_MULTI_STRING); + _node_name_entry->set_text(""); + _node_name_entry->set_sensitive(false); } } @@ -338,7 +342,7 @@ LoadPluginWindow::load_plugin(const Gtk::TreeModel::iterator& iter) string name = _node_name_entry->get_text(); if (name.empty() || name == NAME_ENTRY_MULTI_STRING) - name = generate_module_name(plugin, _plugin_name_offset); + name = generate_module_name(plugin, _name_offset); if (name.empty() || !Symbol::is_valid(name)) { Gtk::MessageDialog dialog(*this, @@ -355,7 +359,7 @@ LoadPluginWindow::load_plugin(const Gtk::TreeModel::iterator& iter) App::instance().engine()->put(path, props); if (_selection->get_selected_rows().size() == 1) - _node_name_entry->set_text(generate_module_name(plugin, _plugin_name_offset + 1)); + _node_name_entry->set_text(generate_module_name(plugin, _name_offset + 1)); // Cascade next node Atom& x = _initial_data.find(uris.ingenui_canvas_x)->second; @@ -372,7 +376,7 @@ LoadPluginWindow::add_clicked() _selection->selected_foreach_iter( sigc::mem_fun(*this, &LoadPluginWindow::load_plugin)); - ++_plugin_name_offset; + ++_name_offset; } diff --git a/src/gui/LoadPluginWindow.hpp b/src/gui/LoadPluginWindow.hpp index 71ac3f89..c75c1eb6 100644 --- a/src/gui/LoadPluginWindow.hpp +++ b/src/gui/LoadPluginWindow.hpp @@ -130,7 +130,7 @@ private: Glib::RefPtr<Gtk::TreeSelection> _selection; - int _plugin_name_offset; // see comments for generate_plugin_name + int _name_offset; // see comments for generate_plugin_name bool _has_shown; bool _refresh_list; diff --git a/src/gui/LoadSubpatchWindow.cpp b/src/gui/LoadSubpatchWindow.cpp index d299e327..65daa638 100644 --- a/src/gui/LoadSubpatchWindow.cpp +++ b/src/gui/LoadSubpatchWindow.cpp @@ -19,10 +19,12 @@ #include <dirent.h> #include <cassert> #include <boost/optional.hpp> +#include <glibmm/miscutils.h> #include "interface/EngineInterface.hpp" #include "shared/LV2URIMap.hpp" #include "client/NodeModel.hpp" #include "client/PatchModel.hpp" +#include "client/ClientStore.hpp" #include "shared/runtime_paths.hpp" #include "App.hpp" #include "LoadSubpatchWindow.hpp" @@ -41,21 +43,14 @@ namespace GUI { LoadSubpatchWindow::LoadSubpatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml) : Gtk::FileChooserDialog(cobject) { - xml->get_widget("load_subpatch_name_from_file_radio", _name_from_file_radio); - xml->get_widget("load_subpatch_name_from_user_radio", _name_from_user_radio); - xml->get_widget("load_subpatch_name_entry", _name_entry); + xml->get_widget("load_subpatch_symbol_entry", _symbol_entry); + xml->get_widget("load_subpatch_poly_voices_radio", _poly_voices_radio); xml->get_widget("load_subpatch_poly_from_file_radio", _poly_from_file_radio); - xml->get_widget("load_subpatch_poly_from_parent_radio", _poly_from_parent_radio); - xml->get_widget("load_subpatch_poly_from_user_radio", _poly_from_user_radio); xml->get_widget("load_subpatch_poly_spinbutton", _poly_spinbutton); xml->get_widget("load_subpatch_ok_button", _ok_button); xml->get_widget("load_subpatch_cancel_button", _cancel_button); - _name_from_file_radio->signal_toggled().connect(sigc::mem_fun(this, &LoadSubpatchWindow::disable_name_entry)); - _name_from_user_radio->signal_toggled().connect(sigc::mem_fun(this, &LoadSubpatchWindow::enable_name_entry)); - _poly_from_file_radio->signal_toggled().connect(sigc::mem_fun(this, &LoadSubpatchWindow::disable_poly_spinner)); - _poly_from_parent_radio->signal_toggled().connect(sigc::mem_fun(this, &LoadSubpatchWindow::disable_poly_spinner)); - _poly_from_user_radio->signal_toggled().connect(sigc::mem_fun(this, &LoadSubpatchWindow::enable_poly_spinner)); + _poly_voices_radio->signal_toggled().connect(sigc::mem_fun(this, &LoadSubpatchWindow::enable_poly_spinner)); _ok_button->signal_clicked().connect(sigc::mem_fun(this, &LoadSubpatchWindow::ok_clicked)); _cancel_button->signal_clicked().connect(sigc::mem_fun(this, &LoadSubpatchWindow::cancel_clicked)); @@ -75,6 +70,9 @@ LoadSubpatchWindow::LoadSubpatchWindow(BaseObjectType* cobject, const Glib::RefP add_shortcut_folder(examples_dir); closedir(d); } + + signal_selection_changed().connect( + sigc::mem_fun(this, &LoadSubpatchWindow::selection_changed)); } @@ -87,7 +85,7 @@ LoadSubpatchWindow::present(SharedPtr<PatchModel> patch, GraphObject::Properties } -/** Sets the patch controller for this window and initializes everything. +/** Sets the patch model for this window and initializes everything. * * This function MUST be called before using the window in any way! */ @@ -95,12 +93,8 @@ void LoadSubpatchWindow::set_patch(SharedPtr<PatchModel> patch) { _patch = patch; - - char temp_buf[4]; - snprintf(temp_buf, 4, "%u", patch->poly()); - Glib::ustring txt = "Same as parent ("; - txt.append(temp_buf).append(")"); - _poly_from_parent_radio->set_label(txt); + _symbol_entry->set_text(patch->path().symbol()); + _poly_spinbutton->set_value(patch->poly()); } @@ -116,21 +110,6 @@ LoadSubpatchWindow::on_show() ///// Event Handlers ////// - -void -LoadSubpatchWindow::disable_name_entry() -{ - _name_entry->property_sensitive() = false; -} - - -void -LoadSubpatchWindow::enable_name_entry() -{ - _name_entry->property_sensitive() = true; -} - - void LoadSubpatchWindow::disable_poly_spinner() { @@ -150,21 +129,10 @@ LoadSubpatchWindow::ok_clicked() { assert(_patch); - // If unset load_patch will load values - optional<Raul::Symbol> symbol; - string name_str = ""; - - if (_name_from_user_radio->get_active()) { - name_str = _name_entry->get_text(); - symbol = Symbol::symbolify(name_str); - } - const LV2URIMap& uris = App::instance().uris(); - if (_poly_from_user_radio->get_active()) { + if (_poly_voices_radio->get_active()) { _initial_data.insert(make_pair(uris.ingen_polyphony, (int)_poly_spinbutton->get_value_as_int())); - } else if (_poly_from_parent_radio->get_active()) { - _initial_data.insert(make_pair(uris.ingen_polyphony, (int)_patch->poly())); } std::list<Glib::ustring> uri_list = get_uris(); @@ -175,6 +143,12 @@ LoadSubpatchWindow::ok_clicked() Atom& y = _initial_data.find(uris.ingenui_canvas_y)->second; y = Atom(y.get_float() + 20.0f); + Raul::Symbol symbol(symbol_from_filename(*i)); + if (uri_list.size() == 1 && _symbol_entry->get_text() != "") + symbol = Symbol::symbolify(_symbol_entry->get_text()); + + symbol = avoid_symbol_clash(symbol); + App::instance().loader()->load_patch(false, *i, Path("/"), _patch->path(), symbol, _initial_data); } @@ -190,5 +164,44 @@ LoadSubpatchWindow::cancel_clicked() } +Raul::Symbol +LoadSubpatchWindow::symbol_from_filename(const Glib::ustring& filename) +{ + std::string symbol_str = Glib::path_get_basename(get_filename()); + symbol_str = symbol_str.substr(0, symbol_str.find('.')); + return Raul::Symbol::symbolify(symbol_str); +} + + +Raul::Symbol +LoadSubpatchWindow::avoid_symbol_clash(const Raul::Symbol& symbol) +{ + unsigned offset = App::instance().store()->child_name_offset( + _patch->path(), symbol); + + if (offset != 0) { + std::stringstream ss; + ss << symbol << "_" << offset + 1; + return ss.str(); + } else { + return symbol; + } +} + + +void +LoadSubpatchWindow::selection_changed() +{ + if (get_filenames().size() != 1) { + _symbol_entry->set_text(""); + _symbol_entry->set_sensitive(false); + } else { + _symbol_entry->set_text(avoid_symbol_clash( + symbol_from_filename(get_filename()).c_str()).c_str()); + _symbol_entry->set_sensitive(true); + } +} + + } // namespace GUI } // namespace Ingen diff --git a/src/gui/LoadSubpatchWindow.hpp b/src/gui/LoadSubpatchWindow.hpp index 6f71642b..c216f26a 100644 --- a/src/gui/LoadSubpatchWindow.hpp +++ b/src/gui/LoadSubpatchWindow.hpp @@ -51,24 +51,23 @@ protected: void on_show(); private: - void disable_name_entry(); - void enable_name_entry(); void disable_poly_spinner(); void enable_poly_spinner(); void ok_clicked(); void cancel_clicked(); + void selection_changed(); + + Raul::Symbol symbol_from_filename(const Glib::ustring& filename); + Raul::Symbol avoid_symbol_clash(const Raul::Symbol& symbol); GraphObject::Properties _initial_data; SharedPtr<PatchModel> _patch; - Gtk::RadioButton* _name_from_file_radio; - Gtk::RadioButton* _name_from_user_radio; - Gtk::Entry* _name_entry; + Gtk::Entry* _symbol_entry; + Gtk::RadioButton* _poly_voices_radio; Gtk::RadioButton* _poly_from_file_radio; - Gtk::RadioButton* _poly_from_parent_radio; - Gtk::RadioButton* _poly_from_user_radio; Gtk::SpinButton* _poly_spinbutton; Gtk::Button* _ok_button; Gtk::Button* _cancel_button; diff --git a/src/gui/WindowFactory.cpp b/src/gui/WindowFactory.cpp index 1842a04a..d5493339 100644 --- a/src/gui/WindowFactory.cpp +++ b/src/gui/WindowFactory.cpp @@ -269,8 +269,6 @@ WindowFactory::present_load_patch(SharedPtr<PatchModel> patch, GraphObject::Prop if (w != _patch_windows.end()) _load_patch_win->set_transient_for(*w->second); - _load_patch_win->set_merge(); // Import is the only choice - _load_patch_win->present(patch, data); } diff --git a/src/gui/ingen_gui.glade b/src/gui/ingen_gui.glade index 9178a7fe..8c35c2e8 100644 --- a/src/gui/ingen_gui.glade +++ b/src/gui/ingen_gui.glade @@ -831,191 +831,140 @@ <property name="visible">True</property> <property name="spacing">24</property> <child> - <widget class="GtkTable" id="table6"> + <widget class="GtkAlignment" id="alignment1"> <property name="visible">True</property> - <property name="n_rows">2</property> - <property name="n_columns">4</property> - <property name="column_spacing">12</property> - <property name="row_spacing">4</property> - <child> - <widget class="GtkLabel" id="label79"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes"><b>Name: </b></property> - <property name="use_markup">True</property> - </widget> - <packing> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label80"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes"><b>Polyphony: </b></property> - <property name="use_markup">True</property> - </widget> - <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkRadioButton" id="load_subpatch_name_from_file_radio"> - <property name="label" translatable="yes">Load from file</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="tooltip" translatable="yes">Use the name stored in the patch file</property> - <property name="use_underline">True</property> - <property name="active">True</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> + <property name="xalign">0</property> + <property name="xscale">0</property> + <property name="yscale">0</property> <child> - <widget class="GtkRadioButton" id="load_subpatch_poly_from_file_radio"> - <property name="label" translatable="yes">Load from file</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="tooltip" translatable="yes">Use the polyphony value stored in the patch file</property> - <property name="use_underline">True</property> - <property name="active">True</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkHBox" id="hbox46"> + <widget class="GtkTable" id="table6"> <property name="visible">True</property> + <property name="n_rows">2</property> + <property name="n_columns">3</property> + <property name="column_spacing">12</property> + <property name="row_spacing">12</property> <child> - <widget class="GtkRadioButton" id="load_subpatch_poly_from_user_radio"> - <property name="label" translatable="yes">Specify: </property> + <widget class="GtkLabel" id="label79"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="tooltip" translatable="yes">Specify a custom polyphony value for new patch</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">_Symbol: </property> + <property name="use_markup">True</property> <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - <property name="group">load_subpatch_poly_from_file_radio</property> + <property name="mnemonic_widget">load_subpatch_symbol_entry</property> </widget> <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> </packing> </child> <child> - <widget class="GtkSpinButton" id="load_subpatch_poly_spinbutton"> + <widget class="GtkLabel" id="label80"> <property name="visible">True</property> - <property name="sensitive">False</property> - <property name="can_focus">True</property> - <property name="tooltip" translatable="yes">Specify a custom polyphony value for new patch</property> - <property name="adjustment">1 0 1000 1 10 0</property> - <property name="climb_rate">1</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Polyphony: </property> + <property name="use_markup">True</property> </widget> <packing> - <property name="expand">False</property> - <property name="position">1</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> </packing> </child> - </widget> - <packing> - <property name="left_attach">3</property> - <property name="right_attach">4</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options">GTK_FILL</property> - </packing> - </child> - <child> - <widget class="GtkRadioButton" id="load_subpatch_poly_from_parent_radio"> - <property name="label" translatable="yes">Same as parent (?)</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="tooltip" translatable="yes">Set polyphony to the same value as the parent (containing) patch</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - <property name="group">load_subpatch_poly_from_file_radio</property> - </widget> - <packing> - <property name="left_attach">2</property> - <property name="right_attach">3</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label104"> - <property name="visible">True</property> - <property name="xalign">0</property> - </widget> - <packing> - <property name="left_attach">2</property> - <property name="right_attach">3</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkHBox" id="hbox45"> - <property name="visible">True</property> <child> - <widget class="GtkRadioButton" id="load_subpatch_name_from_user_radio"> - <property name="label" translatable="yes">Specify: </property> + <widget class="GtkRadioButton" id="load_subpatch_poly_from_file_radio"> + <property name="label" translatable="yes">Load from _file</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> - <property name="tooltip" translatable="yes">Specify the name for the new patch</property> + <property name="has_tooltip">True</property> + <property name="tooltip" translatable="yes">Use the polyphony value stored in the patch file</property> <property name="use_underline">True</property> <property name="draw_indicator">True</property> - <property name="group">load_subpatch_name_from_file_radio</property> + <property name="group">load_subpatch_poly_voices_radio</property> </widget> <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> </packing> </child> <child> - <widget class="GtkEntry" id="load_subpatch_name_entry"> + <widget class="GtkHBox" id="hbox46"> + <property name="visible">True</property> + <child> + <widget class="GtkRadioButton" id="load_subpatch_poly_voices_radio"> + <property name="label" translatable="yes">_Voices: </property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="has_tooltip">True</property> + <property name="tooltip" translatable="yes">Specify a custom polyphony value for new patch</property> + <property name="use_underline">True</property> + <property name="active">True</property> + <property name="draw_indicator">True</property> + <property name="group">load_subpatch_poly_from_file_radio</property> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <widget class="GtkSpinButton" id="load_subpatch_poly_spinbutton"> + <property name="visible">True</property> + <property name="sensitive">False</property> + <property name="can_focus">True</property> + <property name="tooltip" translatable="yes">Specify a custom polyphony value for new patch</property> + <property name="invisible_char">●</property> + <property name="adjustment">1 0 1000 1 10 0</property> + <property name="climb_rate">1</property> + </widget> + <packing> + <property name="expand">False</property> + <property name="position">1</property> + </packing> + </child> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <widget class="GtkLabel" id="label104"> + <property name="visible">True</property> + <property name="xalign">0</property> + </widget> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <widget class="GtkEntry" id="load_subpatch_symbol_entry"> <property name="visible">True</property> - <property name="sensitive">False</property> <property name="can_focus">True</property> <property name="tooltip" translatable="yes">Specify the name for the new patch</property> + <property name="invisible_char">●</property> <property name="activates_default">True</property> </widget> <packing> - <property name="expand">False</property> - <property name="position">1</property> + <property name="left_attach">1</property> + <property name="right_attach">3</property> </packing> </child> </widget> - <packing> - <property name="left_attach">3</property> - <property name="right_attach">4</property> - <property name="y_options">GTK_FILL</property> - </packing> </child> </widget> <packing> @@ -1078,103 +1027,151 @@ <widget class="GtkVBox" id="vbox11"> <property name="spacing">24</property> <child> - <widget class="GtkTable" id="table14"> + <widget class="GtkAlignment" id="alignment1"> <property name="visible">True</property> - <property name="n_columns">4</property> - <property name="column_spacing">12</property> - <property name="row_spacing">4</property> - <child> - <widget class="GtkLabel" id="label123"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes"><b>Polyphony: </b></property> - <property name="use_markup">True</property> - </widget> - <packing> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> + <property name="xalign">0</property> + <property name="xscale">0</property> <child> - <widget class="GtkRadioButton" id="load_patch_poly_from_current_radio"> - <property name="label" translatable="yes">Keep current</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="tooltip" translatable="yes">Use the same polyphony as the current patch</property> - <property name="use_underline">True</property> - <property name="active">True</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkRadioButton" id="load_patch_poly_from_file_radio"> - <property name="label" translatable="yes">Load from file</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="tooltip" translatable="yes">Use the polyphony value stored in the patch file</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - <property name="group">load_patch_poly_from_current_radio</property> - </widget> - <packing> - <property name="left_attach">2</property> - <property name="right_attach">3</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkHBox" id="hbox58"> + <widget class="GtkTable" id="table14"> <property name="visible">True</property> + <property name="n_rows">2</property> + <property name="n_columns">3</property> + <property name="column_spacing">12</property> + <property name="row_spacing">12</property> + <child> + <widget class="GtkLabel" id="label123"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Polyphony: </property> + <property name="use_markup">True</property> + </widget> + <packing> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> <child> - <widget class="GtkRadioButton" id="load_patch_poly_from_user_radio"> - <property name="label" translatable="yes">Specify:</property> + <widget class="GtkRadioButton" id="load_patch_poly_from_file_radio"> + <property name="label" translatable="yes">Load from _File</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> + <property name="has_tooltip">True</property> + <property name="tooltip" translatable="yes">Use the polyphony value stored in the patch file</property> <property name="use_underline">True</property> <property name="draw_indicator">True</property> - <property name="group">load_patch_poly_from_current_radio</property> + <property name="group">load_patch_poly_voices_radio</property> </widget> <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> </packing> </child> <child> - <widget class="GtkSpinButton" id="load_patch_poly_spinbutton"> + <widget class="GtkLabel" id="label1"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Ports: </property> + <property name="use_markup">True</property> + </widget> + <packing> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <widget class="GtkRadioButton" id="load_patch_insert_ports_radio"> + <property name="label" translatable="yes">_Insert new ports</property> <property name="visible">True</property> - <property name="sensitive">False</property> <property name="can_focus">True</property> - <property name="tooltip" translatable="yes">Specify a custom polyphony value for new patch</property> - <property name="adjustment">1 0 100 1 10 0</property> - <property name="climb_rate">1</property> + <property name="receives_default">False</property> + <property name="has_tooltip">True</property> + <property name="tooltip" translatable="yes">Create new ports for all of the loaded patch's ports</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + <property name="group">load_patch_merge_ports_radio</property> </widget> <packing> - <property name="expand">False</property> - <property name="position">1</property> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <widget class="GtkRadioButton" id="load_patch_merge_ports_radio"> + <property name="label" translatable="yes">_Merge with existing ports</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="has_tooltip">True</property> + <property name="tooltip" translatable="yes">Merge current ports and loaded patch's ports wherever possible</property> + <property name="use_underline">True</property> + <property name="active">True</property> + <property name="draw_indicator">True</property> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <widget class="GtkHBox" id="hbox58"> + <property name="visible">True</property> + <property name="spacing">6</property> + <child> + <widget class="GtkRadioButton" id="load_patch_poly_voices_radio"> + <property name="label" translatable="yes">_Voices:</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="has_tooltip">True</property> + <property name="tooltip" translatable="yes">Set polyphonic to a specific number of voices</property> + <property name="use_underline">True</property> + <property name="active">True</property> + <property name="draw_indicator">True</property> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <widget class="GtkSpinButton" id="load_patch_poly_spinbutton"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="tooltip" translatable="yes">Specify a custom polyphony value for new patch</property> + <property name="invisible_char">●</property> + <property name="adjustment">1 0 100 1 10 0</property> + <property name="climb_rate">1</property> + </widget> + <packing> + <property name="expand">False</property> + <property name="position">1</property> + </packing> + </child> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> </packing> </child> </widget> - <packing> - <property name="left_attach">3</property> - <property name="right_attach">4</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options">GTK_FILL</property> - </packing> </child> </widget> <packing> <property name="expand">False</property> + <property name="fill">False</property> <property name="position">2</property> </packing> </child> diff --git a/src/serialisation/Parser.cpp b/src/serialisation/Parser.cpp index f59c7263..67651e6b 100644 --- a/src/serialisation/Parser.cpp +++ b/src/serialisation/Parser.cpp @@ -18,6 +18,7 @@ #include <set> #include <locale.h> #include <glibmm/ustring.h> +#include <glibmm/miscutils.h> #include "raul/log.hpp" #include "redlandmm/Model.hpp" #include "redlandmm/Node.hpp" @@ -43,33 +44,16 @@ namespace Serialisation { static Glib::ustring relative_uri(Glib::ustring base, const Glib::ustring uri, bool leading_slash) { - Glib::ustring ret; - if (uri.substr(0, base.length()) == base) { - ret = (leading_slash ? "/" : "") + uri.substr(base.length()); - while (ret[0] == '#' || ret[0] == '/') - ret = ret.substr(1); - if (leading_slash && ret[0] != '/') - ret = string("/") + ret; - return ret; - } - - size_t last_slash = base.find_last_of("/"); - if (last_slash != string::npos) - base = base.substr(0, last_slash + 1); + raptor_uri* base_uri = raptor_new_uri((const unsigned char*)base.c_str()); + raptor_uri* full_uri = raptor_new_uri((const unsigned char*)uri.c_str()); - size_t last_hash = base.find_last_of("#"); - if (last_hash != string::npos) - base = base.substr(0, last_hash + 1); + Glib::ustring ret((const char*)raptor_uri_to_relative_uri_string(base_uri, full_uri)); - if (uri.length() >= base.length() && uri.substr(0, base.length()) == base) - ret = uri.substr(base.length()); - else - ret = uri; + raptor_free_uri(base_uri); + raptor_free_uri(full_uri); - if (leading_slash && (ret.empty() || ret[0] != '/')) - ret = "/" + ret; - else if (!leading_slash && !ret.empty() && ret[0] == '/') - ret = ret.substr(1); + if (leading_slash && ret[0] != '/') + ret = Glib::ustring("/") + ret; return ret; } @@ -371,17 +355,18 @@ Parser::parse_patch( const Glib::ustring base_uri = model.base_uri().to_string(); - string symbol; + Raul::Symbol symbol = "_"; if (a_symbol) { - symbol = a_symbol->c_str(); - } else { // Guess symbol from base URI (filename) if we need to - symbol = base_uri.substr(base_uri.find_last_of("/") + 1); - symbol = symbol.substr(0, symbol.find(".")); - if (!symbol.empty()) - symbol = Path::nameify(symbol); + symbol = *a_symbol; + } else { + const std::string basename = Glib::path_get_basename(base_uri); + symbol = Raul::Symbol::symbolify(basename.substr(0, basename.find('.'))); } string patch_path_str = relative_uri(base_uri, subject_node.to_string(), true); + if (parent && a_symbol) + patch_path_str = parent->child(*a_symbol).str(); + if (!Path::is_valid(patch_path_str)) { LOG(error) << "Patch has invalid path: " << patch_path_str << endl; return boost::optional<Raul::Path>(); @@ -472,7 +457,7 @@ Parser::parse_patch( /* Create patch nodes */ for (Objects::iterator i = patch_nodes.begin(); i != patch_nodes.end(); ++i) { - const Path node_path = Path(relative_uri(base_uri, i->first, true)); + const Path node_path = patch_path.child(relative_uri(base_uri, i->first, false)); Types::iterator type_i = types.find(i->first); if (type_i == types.end()) continue; @@ -489,7 +474,7 @@ Parser::parse_patch( Types::iterator type_i = types.find(i->first); if (type_i == types.end()) continue; - const Path node_path(relative_uri(base_uri, i->first, true)); + const Path node_path = patch_path.child(relative_uri(base_uri, i->first, false)); Resource::Properties props; props.insert(make_pair(uris.rdf_type, Raul::URI(uris.ingen_Node))); props.insert(make_pair(uris.rdf_instanceOf, Raul::URI(type_i->second))); @@ -520,7 +505,7 @@ Parser::parse_patch( if (p == node_ports.end()) p = node_ports.insert(make_pair(port_uri, Properties())).first; - const Path node_path(relative_uri(base_uri, node_uri, true)); + const Path node_path = patch_path.child(relative_uri(base_uri, node_uri, false)); const Symbol port_sym = port_uri.substr(node_uri.length() + 1); const Path port_path = node_path.child(port_sym); const string key = (*i)["key"].to_string(); @@ -528,7 +513,7 @@ Parser::parse_patch( } for (Objects::iterator i = node_ports.begin(); i != node_ports.end(); ++i) { - target->put(Raul::Path(relative_uri(base_uri, i->first, true)), i->second); + target->put(patch_path.child(relative_uri(base_uri, i->first, false)), i->second); } @@ -561,7 +546,7 @@ Parser::parse_patch( for (Results::iterator i = results.begin(); i != results.end(); ++i) { Glib::Mutex::Lock lock(world->rdf_world->mutex()); const string port_uri = (*i)["port"].to_string(); - const Path port_path(Path(relative_uri(base_uri, port_uri, true))); + const Path port_path = patch_path.child(relative_uri(base_uri, port_uri, false)); const string key = (*i)["key"].to_string(); Objects::iterator ports_i = patch_ports.find(port_uri); if (ports_i == patch_ports.end()) @@ -606,7 +591,7 @@ Parser::parse_patch( for (uint32_t index = 0; index < patch_ports.size(); ++index) { Objects::iterator i = ports_by_index[index]; Glib::Mutex::Lock lock(world->rdf_world->mutex()); - const Path port_path(relative_uri(base_uri, i->first, true)); + const Path port_path = patch_path.child(relative_uri(base_uri, i->first, false)); std::pair<Properties::iterator,Properties::iterator> types_range = i->second.equal_range(uris.rdf_type); if (types_range.first == i->second.end()) { @@ -639,7 +624,7 @@ Parser::parse_patch( } parse_properties(world, target, model, subject_node, patch_path, data); - parse_connections(world, target, model, subject_node, "/"); + parse_connections(world, target, model, subject_node, patch_path); /* Enable */ @@ -722,17 +707,13 @@ Parser::parse_connections( const Glib::ustring& base_uri = model.base_uri().to_string(); + std::cout << "PARSE CONNECTIONS " << subject << " : " << parent << endl; Redland::Query::Results results = query.run(*world->rdf_world, model); for (Redland::Query::Results::iterator i = results.begin(); i != results.end(); ++i) { Glib::Mutex::Lock lock(world->rdf_world->mutex()); - string src_path = parent.base() + relative_uri(base_uri, (*i)["src"].to_string(), false); - string dst_path = parent.base() + relative_uri(base_uri, (*i)["dst"].to_string(), false); - if (Path::is_valid(src_path) && Path::is_valid(dst_path)) { - target->connect(src_path, dst_path); - } else { - LOG(error) << "Invalid path in connection " - << src_path << " => " << dst_path << endl; - } + const Path src_path(parent.child(relative_uri(base_uri, (*i)["src"].to_string(), false))); + const Path dst_path(parent.child(relative_uri(base_uri, (*i)["dst"].to_string(), false))); + target->connect(src_path, dst_path); } return true; |