+string
+AutomationTimeAxisView::state_id() const
+{
+ if (_control) {
+ return string_compose ("automation %1", _control->id().to_s());
+ } else {
+ assert (_parameter);
+ return string_compose ("automation %1 %2/%3/%4",
+ _route->id(),
+ _parameter.type(),
+ _parameter.id(),
+ (int) _parameter.channel());
+ }
+}
+
+/** Given a state id string, see if it is one generated by
+ * this class. If so, parse it into its components.
+ * @param state_id State ID string to parse.
+ * @param route_id Filled in with the route's ID if the state ID string is parsed.
+ * @param has_parameter Filled in with true if the state ID has a parameter, otherwise false.
+ * @param parameter Filled in with the state ID's parameter, if it has one.
+ * @return true if this is a state ID generated by this class, otherwise false.
+ */
+
+bool
+AutomationTimeAxisView::parse_state_id (
+ string const & state_id,
+ PBD::ID & route_id,
+ bool & has_parameter,
+ Evoral::Parameter & parameter)
+{
+ stringstream s;
+ s << state_id;
+
+ string a, b, c;
+ s >> a >> b >> c;
+
+ if (a != X_("automation")) {
+ return false;
+ }
+
+ route_id = PBD::ID (b);
+
+ if (c.empty ()) {
+ has_parameter = false;
+ return true;
+ }
+
+ has_parameter = true;
+
+ vector<string> p;
+ boost::split (p, c, boost::is_any_of ("/"));
+
+ assert (p.size() == 3);
+
+ parameter = Evoral::Parameter (
+ boost::lexical_cast<int> (p[0]),
+ boost::lexical_cast<int> (p[2]),
+ boost::lexical_cast<int> (p[1])
+ );
+
+ return true;
+}