more color/modifier tweaks
[ardour.git] / gtk2_ardour / selection.cc
index d1b712e3d76fb6c133b5a0b2cc499d3c3790526a..b00f59ce83f558f36a6e47ff41ad750f5a69f93c 100644 (file)
@@ -173,6 +173,10 @@ Selection::clear_midi_notes ()
                midi_notes.clear ();
                MidiNotesChanged ();
        }
+
+       /* The note selection is actually stored in MidiRegionView, emit signal to
+          tell them to clear their selection. */
+       ClearMidiNoteSelection();  /* EMIT SIGNAL */
 }
 
 void
@@ -399,6 +403,8 @@ Selection::add (const list<boost::shared_ptr<Playlist> >& pllist)
 void
 Selection::add (const TrackViewList& track_list)
 {
+       clear_objects();  //enforce object/range exclusivity
+
        TrackViewList added = tracks.add (track_list);
 
        if (!added.empty()) {
@@ -414,6 +420,8 @@ Selection::add (const TrackViewList& track_list)
 void
 Selection::add (TimeAxisView* track)
 {
+       clear_objects();  //enforce object/range exclusivity
+
        TrackViewList tr;
        track->set_selected (true);
        tr.push_back (track);
@@ -836,7 +844,6 @@ long
 Selection::set (framepos_t start, framepos_t end)
 {
        clear_objects();  //enforce region/object exclusivity
-       clear_tracks();  //enforce object/track exclusivity
        clear_time();
 
        if ((start == 0 && end == 0) || end < start) {
@@ -948,7 +955,7 @@ Selection::empty (bool internal_selection)
           as a cut buffer.
        */
 
-       return object_level_empty && midi_notes.empty();
+       return object_level_empty && midi_notes.empty() && points.empty();
 }
 
 void
@@ -999,7 +1006,7 @@ Selection::toggle (list<Selectable*> const & selectables)
                        fatal << _("programming error: ")
                              << X_("unknown selectable type passed to Selection::toggle()")
                              << endmsg;
-                       /*NOTREACHED*/
+                       abort(); /*NOTREACHED*/
                }
        }
 
@@ -1053,7 +1060,7 @@ Selection::add (list<Selectable*> const & selectables)
                        fatal << _("programming error: ")
                              << X_("unknown selectable type passed to Selection::add()")
                              << endmsg;
-                       /*NOTREACHED*/
+                       abort(); /*NOTREACHED*/
                }
        }
 
@@ -1203,6 +1210,7 @@ Selection::get_state () const
           so that re-opening plugin windows for editor mixer strips works
        */
 
+       char buf[32];
        XMLNode* node = new XMLNode (X_("Selection"));
 
        for (TrackSelection::const_iterator i = tracks.begin(); i != tracks.end(); ++i) {
@@ -1218,9 +1226,23 @@ Selection::get_state () const
                }
        }
 
+       for (RegionSelection::const_iterator i = regions.begin(); i != regions.end(); ++i) {
+               XMLNode* r = node->add_child (X_("Region"));
+               r->add_property (X_("id"), atoi ((*i)->region ()->id ().to_s ().c_str()));
+               
+       }
+
+       for (TimeSelection::const_iterator i = time.begin(); i != time.end(); ++i) {
+               XMLNode* t = node->add_child (X_("AudioRange"));
+               snprintf(buf, sizeof(buf), "%ld", (*i).start);
+               t->add_property (X_("start"), string(buf));
+               snprintf(buf, sizeof(buf), "%ld", (*i).end);
+               t->add_property (X_("end"), string(buf));
+       }
+       
        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);
 
@@ -1238,6 +1260,11 @@ Selection::set_state (XMLNode const & node, int)
                return -1;
        }
 
+       clear_regions ();
+       clear_time ();
+       clear_tracks ();
+       clear_markers ();
+
        XMLNodeList children = node.children ();
        for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
                if ((*i)->name() == X_("RouteView")) {
@@ -1250,6 +1277,36 @@ Selection::set_state (XMLNode const & node, int)
                                add (rtv);
                        }
 
+               } else if ((*i)->name() == X_("Region")) {
+                       XMLProperty* prop_id = (*i)->property (X_("id"));
+                       assert (prop_id);
+                       PBD::ID id (prop_id->value ());
+                       
+                       RegionSelection rs;
+                       editor->get_regionviews_by_id (id, rs);
+                       
+                       if (!rs.empty ()) {
+                               add (rs);
+                       } else {
+                               /*
+                                 regionviews are being constructed - stash the region IDs 
+                                 so we can identify them in Editor::region_view_added ()
+                               */
+                               regions.pending.push_back (id);
+                       }
+                       
+               } else if  ((*i)->name() == X_("AudioRange")) {
+                       XMLProperty* prop_start = (*i)->property (X_("start"));
+                       XMLProperty* prop_end = (*i)->property (X_("end"));
+
+                       assert (prop_start);
+                       assert (prop_end);
+
+                       framepos_t s (atol (prop_start->value ().c_str()));
+                       framepos_t e (atol (prop_end->value ().c_str()));
+
+                       set_preserving_all_ranges (s, e);
+
                } else if ((*i)->name() == X_("AutomationView")) {
 
                        XMLProperty* prop_id = (*i)->property (X_("id"));
@@ -1262,7 +1319,7 @@ Selection::set_state (XMLNode const & node, int)
                        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 ()));
+                               boost::shared_ptr<AutomationTimeAxisView> atv = rtv->automation_child (EventTypeMap::instance().from_symbol (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