+void
+Selection::remove (Marker* m)
+{
+ MarkerSelection::iterator i;
+
+ if ((i = find (markers.begin(), markers.end(), m)) != markers.end()) {
+ markers.erase (i);
+ MarkersChanged();
+ }
+}
+
+void
+Selection::add (Marker* m)
+{
+ clear_time (); //enforce region/object exclusivity
+
+ if (find (markers.begin(), markers.end(), m) == markers.end()) {
+ markers.push_back (m);
+ MarkersChanged();
+ }
+}
+
+void
+Selection::add (const list<Marker*>& m)
+{
+ clear_time (); //enforce region/object exclusivity
+
+ markers.insert (markers.end(), m.begin(), m.end());
+ markers.sort ();
+ markers.unique ();
+
+ MarkersChanged ();
+}
+
+void
+MarkerSelection::range (framepos_t& s, framepos_t& e)
+{
+ s = max_framepos;
+ e = 0;
+
+ for (MarkerSelection::iterator i = begin(); i != end(); ++i) {
+
+ if ((*i)->position() < s) {
+ s = (*i)->position();
+ }
+
+ if ((*i)->position() > e) {
+ e = (*i)->position();
+ }
+ }
+
+ s = std::min (s, e);
+ e = std::max (s, e);
+}
+
+XMLNode&
+Selection::get_state () const
+{
+ /* XXX: not complete; just sufficient to get track selection state
+ so that re-opening plugin windows for editor mixer strips works
+ */
+
+ XMLNode* node = new XMLNode (X_("Selection"));
+
+ for (TrackSelection::const_iterator i = tracks.begin(); i != tracks.end(); ++i) {
+ RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (*i);
+ AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*> (*i);
+ if (rtv) {
+ XMLNode* t = node->add_child (X_("RouteView"));
+ t->add_property (X_("id"), atoi (rtv->route()->id().to_s().c_str()));
+ } else if (atv) {
+ XMLNode* t = node->add_child (X_("AutomationView"));
+ t->add_property (X_("id"), atoi (atv->parent_route()->id().to_s().c_str()));
+ t->add_property (X_("parameter"), EventTypeMap::instance().to_symbol (atv->parameter ()));
+ }
+ }
+
+ for (MarkerSelection::const_iterator i = markers.begin(); i != markers.end(); ++i) {
+ XMLNode* t = node->add_child (X_("Marker"));
+
+ bool is_start;
+ Location* loc = editor->find_location_from_marker (*i, is_start);
+
+ t->add_property (X_("id"), atoi (loc->id().to_s().c_str()));
+ t->add_property (X_("start"), is_start ? X_("yes") : X_("no"));
+ }
+
+ return *node;
+}
+
+int
+Selection::set_state (XMLNode const & node, int)
+{
+ if (node.name() != X_("Selection")) {
+ return -1;
+ }
+
+ XMLNodeList children = node.children ();
+ for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
+ if ((*i)->name() == X_("RouteView")) {
+
+ XMLProperty* prop_id = (*i)->property (X_("id"));
+ assert (prop_id);
+ PBD::ID id (prop_id->value ());
+ RouteTimeAxisView* rtv = editor->get_route_view_by_route_id (id);
+ if (rtv) {
+ add (rtv);
+ }
+
+ } else if ((*i)->name() == X_("AutomationView")) {
+
+ XMLProperty* prop_id = (*i)->property (X_("id"));
+ XMLProperty* prop_parameter = (*i)->property (X_("parameter"));
+
+ assert (prop_id);
+ assert (prop_parameter);
+
+ PBD::ID id (prop_id->value ());
+ RouteTimeAxisView* rtv = editor->get_route_view_by_route_id (id);
+
+ if (rtv) {
+ boost::shared_ptr<AutomationTimeAxisView> atv = rtv->automation_child (EventTypeMap::instance().new_parameter (prop_parameter->value ()));
+
+ /* the automation could be for an entity that was never saved
+ in the session file. Don't freak out if we can't find
+ it.
+ */
+
+ if (atv) {
+ add (atv.get());
+ }
+ }
+
+ } else if ((*i)->name() == X_("Marker")) {
+
+ XMLProperty* prop_id = (*i)->property (X_("id"));
+ XMLProperty* prop_start = (*i)->property (X_("start"));
+ assert (prop_id);
+ assert (prop_start);
+
+ PBD::ID id (prop_id->value ());
+ Marker* m = editor->find_marker_from_location_id (id, string_is_affirmative (prop_start->value ()));
+ if (m) {
+ add (m);
+ }
+
+ }
+
+ }
+
+ return 0;
+}
+
+void
+Selection::remove_regions (TimeAxisView* t)
+{
+ RegionSelection::iterator i = regions.begin();
+ while (i != regions.end ()) {
+ RegionSelection::iterator tmp = i;
+ ++tmp;
+
+ if (&(*i)->get_time_axis_view() == t) {
+ remove (*i);
+ }
+
+ i = tmp;
+ }
+}
+
+void
+Selection::block_tracks_changed (bool yn)
+{
+ _no_tracks_changed = yn;