From 0c9c47086c49d27a38cef5f5cc819e1aec56857c Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 16 Nov 2011 23:03:59 +0000 Subject: Slightly unpleasant fix for creation of tracks from templates; it would be nice if we could set things up using the Route's logic for setting names of its children, rather than repeating the same logic in XML-land (#4303). git-svn-id: svn://localhost/ardour2/branches/3.0@10655 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/ardour/route.h | 1 + libs/ardour/io.cc | 12 ++++++++---- libs/ardour/route.cc | 32 ++++++++++++++++++++++++++++++++ libs/ardour/session.cc | 41 ++++++++++++++++++++++++----------------- libs/ardour/track.cc | 8 -------- libs/pbd/controllable.cc | 5 +---- libs/pbd/pbd/xml++.h | 1 + libs/pbd/xml++.cc | 10 ++++++++++ 8 files changed, 77 insertions(+), 33 deletions(-) diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index 54904bf016..f89f47778d 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -98,6 +98,7 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember, void set_comment (std::string str, void *src); bool set_name (const std::string& str); + static void set_name_in_state (XMLNode &, const std::string &); int32_t order_key (std::string const &) const; void set_order_key (std::string const &, int32_t); diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc index 4f1b03dfda..23c7594d40 100644 --- a/libs/ardour/io.cc +++ b/libs/ardour/io.cc @@ -1478,10 +1478,14 @@ IO::name_from_state (const XMLNode& node) void IO::set_name_in_state (XMLNode& node, const string& new_name) { - const XMLProperty* prop; - - if ((prop = node.property ("name")) != 0) { - node.add_property ("name", new_name); + node.add_property (X_("name"), new_name); + XMLNodeList children = node.children (); + for (XMLNodeIterator i = children.begin(); i != children.end(); ++i) { + if ((*i)->name() == X_("Port")) { + string const old_name = (*i)->property(X_("name"))->value(); + string const old_name_second_part = old_name.substr (old_name.find_first_of ("/") + 1); + (*i)->add_property (X_("name"), string_compose ("%1/%2", new_name, old_name_second_part)); + } } } diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 57793098d8..b13602635d 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -3286,6 +3286,38 @@ Route::set_name (const string& str) return ret; } +/** Set the name of a route in an XML description. + * @param node XML node to set the name in. + * @param name New name. + */ +void +Route::set_name_in_state (XMLNode& node, string const & name) +{ + node.add_property (X_("name"), name); + + XMLNodeList children = node.children(); + for (XMLNodeIterator i = children.begin(); i != children.end(); ++i) { + + if ((*i)->name() == X_("IO")) { + + IO::set_name_in_state (**i, name); + + } else if ((*i)->name() == X_("Processor")) { + + XMLProperty* role = (*i)->property (X_("role")); + if (role && role->value() == X_("Main")) { + (*i)->add_property (X_("name"), name); + } + + } else if ((*i)->name() == X_("Diskstream")) { + + (*i)->add_property (X_("playlist"), string_compose ("%1.1", name).c_str()); + (*i)->add_property (X_("name"), name); + + } + } +} + boost::shared_ptr Route::internal_send_for (boost::shared_ptr target) const { diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 6f03392548..f72cfa7026 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -1897,7 +1897,6 @@ Session::new_audio_route (int input_channels, int output_channels, RouteGroup* r RouteList Session::new_route_from_template (uint32_t how_many, const std::string& template_path) { - char name[32]; RouteList ret; uint32_t control_id; XMLTree tree; @@ -1913,27 +1912,35 @@ Session::new_route_from_template (uint32_t how_many, const std::string& template while (how_many) { - XMLNode node_copy (*node); // make a copy so we can change the name if we need to + XMLNode node_copy (*node); - std::string node_name = IO::name_from_state (*node_copy.children().front()); + /* Remove IDs of everything so that new ones are used */ + node_copy.remove_property_recursively (X_("id")); - /* generate a new name by adding a number to the end of the template name */ - if (!find_route_name (node_name.c_str(), ++number, name, sizeof(name), true)) { - fatal << _("Session: UINT_MAX routes? impossible!") << endmsg; - /*NOTREACHED*/ - } - - /* set IO children to use the new name */ - XMLNodeList const & children = node_copy.children (); - for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) { - if ((*i)->name() == IO::state_node_name) { - IO::set_name_in_state (**i, name); + try { + string const route_name = node_copy.property(X_("name"))->value (); + + /* generate a new name by adding a number to the end of the template name */ + char name[32]; + if (!find_route_name (route_name.c_str(), ++number, name, sizeof(name), true)) { + fatal << _("Session: UINT_MAX routes? impossible!") << endmsg; + /*NOTREACHED*/ } - } - Track::zero_diskstream_id_in_xml (node_copy); + /* set this name in the XML description that we are about to use */ + Route::set_name_in_state (node_copy, name); - try { + /* trim bitslots from listen sends so that new ones are used */ + XMLNodeList children = node_copy.children (); + for (XMLNodeList::iterator i = children.begin(); i != children.end(); ++i) { + if ((*i)->name() == X_("Processor")) { + XMLProperty* role = (*i)->property (X_("role")); + if (role && role->value() == X_("Listen")) { + (*i)->remove_property (X_("bitslot")); + } + } + } + boost::shared_ptr route (XMLRouteFactory (node_copy, 3000)); if (route == 0) { diff --git a/libs/ardour/track.cc b/libs/ardour/track.cc index 38230f0677..d2274e5039 100644 --- a/libs/ardour/track.cc +++ b/libs/ardour/track.cc @@ -259,14 +259,6 @@ Track::set_latency_compensation (framecnt_t longest_session_latency) _diskstream->set_roll_delay (_roll_delay); } -void -Track::zero_diskstream_id_in_xml (XMLNode& node) -{ - if (node.property ("diskstream-id")) { - node.add_property ("diskstream-id", "0"); - } -} - int Track::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, bool session_state_changing) { diff --git a/libs/pbd/controllable.cc b/libs/pbd/controllable.cc index 51877ee206..d4ceefe330 100644 --- a/libs/pbd/controllable.cc +++ b/libs/pbd/controllable.cc @@ -129,10 +129,7 @@ Controllable::set_state (const XMLNode& node, int /*version*/) Stateful::save_extra_xml (node); - if (!set_id (node)) { - error << _("Controllable state node has no ID property") << endmsg; - return -1; - } + set_id (node); if ((prop = node.property (X_("flags"))) != 0) { _flags = (Flag) string_2_enum (prop->value(), _flags); diff --git a/libs/pbd/pbd/xml++.h b/libs/pbd/pbd/xml++.h index e0b6a885d2..6a5097780e 100644 --- a/libs/pbd/pbd/xml++.h +++ b/libs/pbd/pbd/xml++.h @@ -102,6 +102,7 @@ public: XMLProperty* add_property(const char* name, const long value); void remove_property(const std::string&); + void remove_property_recursively(const std::string&); /** Remove all nodes with the name passed to remove_nodes */ void remove_nodes(const std::string&); diff --git a/libs/pbd/xml++.cc b/libs/pbd/xml++.cc index 1b006fd63d..58a0c4e747 100644 --- a/libs/pbd/xml++.cc +++ b/libs/pbd/xml++.cc @@ -422,6 +422,16 @@ XMLNode::remove_property(const string& n) } } +/** Remove any property with the given name from this node and its children */ +void +XMLNode::remove_property_recursively(const string& n) +{ + remove_property (n); + for (XMLNodeIterator i = _children.begin(); i != _children.end(); ++i) { + (*i)->remove_property_recursively (n); + } +} + void XMLNode::remove_nodes(const string& n) { -- cgit v1.2.3