+Command *
+Session::global_state_command_factory (const XMLNode& node)
+{
+ const XMLProperty* prop;
+ Command* command = 0;
+
+ if ((prop = node.property ("type")) == 0) {
+ error << _("GlobalRouteStateCommand has no \"type\" node, ignoring") << endmsg;
+ return 0;
+ }
+
+ try {
+
+ if (prop->value() == "solo") {
+ command = new GlobalSoloStateCommand (*this, node);
+ } else if (prop->value() == "mute") {
+ command = new GlobalMuteStateCommand (*this, node);
+ } else if (prop->value() == "rec-enable") {
+ command = new GlobalRecordEnableStateCommand (*this, node);
+ } else if (prop->value() == "metering") {
+ command = new GlobalMeteringStateCommand (*this, node);
+ } else {
+ error << string_compose (_("unknown type of GlobalRouteStateCommand (%1), ignored"), prop->value()) << endmsg;
+ }
+ }
+
+ catch (failed_constructor& err) {
+ return 0;
+ }
+
+ return command;
+}
+
+Session::GlobalRouteStateCommand::GlobalRouteStateCommand (Session& s, void* p)
+ : sess (s), src (p)
+{
+}
+
+Session::GlobalRouteStateCommand::GlobalRouteStateCommand (Session& s, const XMLNode& node)
+ : sess (s), src (this)
+{
+ if (set_state (node)) {
+ throw failed_constructor ();
+ }
+}
+
+int
+Session::GlobalRouteStateCommand::set_state (const XMLNode& node)
+{
+ GlobalRouteBooleanState states;
+ XMLNodeList nlist;
+ const XMLProperty* prop;
+ XMLNode* child;
+ XMLNodeConstIterator niter;
+ int loop;
+
+ before.clear ();
+ after.clear ();
+
+ for (loop = 0; loop < 2; ++loop) {
+
+ const char *str;
+
+ if (loop) {
+ str = "after";
+ } else {
+ str = "before";
+ }
+
+ if ((child = node.child (str)) == 0) {
+ warning << string_compose (_("global route state command has no \"%1\" node, ignoring entire command"), str) << endmsg;
+ return -1;
+ }
+
+ nlist = child->children();
+
+ for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
+
+ RouteBooleanState rbs;
+ boost::shared_ptr<Route> route;
+ ID id;
+
+ prop = (*niter)->property ("id");
+ id = prop->value ();
+
+ if ((route = sess.route_by_id (id)) == 0) {
+ warning << string_compose (_("cannot find track/bus \"%1\" while rebuilding a global route state command, ignored"), id.to_s()) << endmsg;
+ continue;
+ }
+
+ rbs.first = boost::weak_ptr<Route> (route);
+
+ prop = (*niter)->property ("yn");
+ rbs.second = (prop->value() == "1");
+
+ if (loop) {
+ after.push_back (rbs);
+ } else {
+ before.push_back (rbs);
+ }
+ }
+ }
+
+ return 0;
+}
+
+XMLNode&
+Session::GlobalRouteStateCommand::get_state ()
+{
+ XMLNode* node = new XMLNode (X_("GlobalRouteStateCommand"));
+ XMLNode* nbefore = new XMLNode (X_("before"));
+ XMLNode* nafter = new XMLNode (X_("after"));
+
+ for (Session::GlobalRouteBooleanState::iterator x = before.begin(); x != before.end(); ++x) {
+ XMLNode* child = new XMLNode ("s");
+ boost::shared_ptr<Route> r = x->first.lock();
+
+ if (r) {
+ child->add_property (X_("id"), r->id().to_s());
+ child->add_property (X_("yn"), (x->second ? "1" : "0"));
+ nbefore->add_child_nocopy (*child);
+ }
+ }
+
+ for (Session::GlobalRouteBooleanState::iterator x = after.begin(); x != after.end(); ++x) {
+ XMLNode* child = new XMLNode ("s");
+ boost::shared_ptr<Route> r = x->first.lock();
+
+ if (r) {
+ child->add_property (X_("id"), r->id().to_s());
+ child->add_property (X_("yn"), (x->second ? "1" : "0"));
+ nafter->add_child_nocopy (*child);
+ }
+ }
+
+ node->add_child_nocopy (*nbefore);
+ node->add_child_nocopy (*nafter);
+
+ return *node;
+}
+