X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fselection.cc;h=3f6c282d3afbfd6f018fc7e721e670baa7af200c;hb=beb3eea62bf217d0a7b2a86a96d5c375329df10a;hp=6dae5b0bcde81b9c5bebe248b66b29912203a6c9;hpb=cc2767caf32486365a33814149e75c6e588e8603;p=ardour.git diff --git a/gtk2_ardour/selection.cc b/gtk2_ardour/selection.cc index 6dae5b0bcd..3f6c282d3a 100644 --- a/gtk2_ardour/selection.cc +++ b/gtk2_ardour/selection.cc @@ -15,20 +15,21 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include #include #include +#include #include -#include "regionview.h" +#include "region_view.h" #include "selection.h" #include "selection_templates.h" #include "time_axis_view.h" #include "automation_time_axis.h" +#include "public_editor.h" #include "i18n.h" @@ -46,7 +47,7 @@ Selection& Selection::operator= (const Selection& other) { if (&other != this) { - audio_regions = other.audio_regions; + regions = other.regions; tracks = other.tracks; time = other.time; lines = other.lines; @@ -57,52 +58,42 @@ Selection::operator= (const Selection& other) bool operator== (const Selection& a, const Selection& b) { - return a.audio_regions == b.audio_regions && + return a.regions == b.regions && a.tracks == b.tracks && a.time.track == b.time.track && a.time.group == b.time.group && a.time == b.time && a.lines == b.lines && - a.playlists == b.playlists && - a.redirects == b.redirects; + a.playlists == b.playlists; } +/** Clear everything from the Selection */ void Selection::clear () { clear_tracks (); - clear_audio_regions (); + clear_regions (); clear_points (); clear_lines(); clear_time (); clear_playlists (); - clear_redirects (); } void Selection::dump_region_layers() { cerr << "region selection layer dump" << endl; - for (AudioRegionSelection::iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) { - cerr << "layer: " << (int)(*i)->region.layer() << endl; + for (RegionSelection::iterator i = regions.begin(); i != regions.end(); ++i) { + cerr << "layer: " << (int)(*i)->region()->layer() << endl; } } void -Selection::clear_redirects () +Selection::clear_regions () { - if (!redirects.empty()) { - redirects.clear (); - RedirectsChanged (); - } -} - -void -Selection::clear_audio_regions () -{ - if (!audio_regions.empty()) { - audio_regions.clear_all (); + if (!regions.empty()) { + regions.clear_all (); RegionsChanged(); } } @@ -132,7 +123,9 @@ Selection::clear_playlists () /* Selections own their playlists */ for (PlaylistSelection::iterator i = playlists.begin(); i != playlists.end(); ++i) { - (*i)->unref (); + /* selections own their own regions, which are copies of the "originals". make them go away */ + (*i)->drop_regions (); + (*i)->release (); } if (!playlists.empty()) { @@ -151,26 +144,21 @@ Selection::clear_lines () } void -Selection::toggle (boost::shared_ptr r) +Selection::clear_markers () { - RedirectSelection::iterator i; - - if ((i = find (redirects.begin(), redirects.end(), r)) == redirects.end()) { - redirects.push_back (r); - } else { - redirects.erase (i); + if (!markers.empty()) { + markers.clear (); + MarkersChanged(); } - RedirectsChanged(); - } void -Selection::toggle (Playlist* pl) +Selection::toggle (boost::shared_ptr pl) { PlaylistSelection::iterator i; if ((i = find (playlists.begin(), playlists.end(), pl)) == playlists.end()) { - pl->ref (); + pl->use (); playlists.push_back(pl); } else { playlists.erase (i); @@ -179,6 +167,14 @@ Selection::toggle (Playlist* pl) PlaylistsChanged (); } +void +Selection::toggle (const list& track_list) +{ + for (list::const_iterator i = track_list.begin(); i != track_list.end(); ++i) { + toggle ( (*i) ); + } +} + void Selection::toggle (TimeAxisView* track) { @@ -196,29 +192,29 @@ Selection::toggle (TimeAxisView* track) } void -Selection::toggle (AudioRegionView* r) +Selection::toggle (RegionView* r) { - AudioRegionSelection::iterator i; + RegionSelection::iterator i; - if ((i = find (audio_regions.begin(), audio_regions.end(), r)) == audio_regions.end()) { - audio_regions.add (r); + if ((i = find (regions.begin(), regions.end(), r)) == regions.end()) { + add (r); } else { - audio_regions.erase (i); + remove (*i); } RegionsChanged (); } void -Selection::toggle (vector& r) +Selection::toggle (vector& r) { - AudioRegionSelection::iterator i; + RegionSelection::iterator i; - for (vector::iterator x = r.begin(); x != r.end(); ++x) { - if ((i = find (audio_regions.begin(), audio_regions.end(), (*x))) == audio_regions.end()) { - audio_regions.add ((*x)); + for (vector::iterator x = r.begin(); x != r.end(); ++x) { + if ((i = find (regions.begin(), regions.end(), (*x))) == regions.end()) { + add ((*x)); } else { - audio_regions.erase (i); + remove (*x); } } @@ -226,7 +222,7 @@ Selection::toggle (vector& r) } long -Selection::toggle (jack_nframes_t start, jack_nframes_t end) +Selection::toggle (nframes_t start, nframes_t end) { AudioRangeComparator cmp; @@ -241,34 +237,24 @@ Selection::toggle (jack_nframes_t start, jack_nframes_t end) return next_time_id - 1; } - void -Selection::add (boost::shared_ptr r) -{ - if (find (redirects.begin(), redirects.end(), r) == redirects.end()) { - redirects.push_back (r); - RedirectsChanged(); - } -} - -void -Selection::add (Playlist* pl) +Selection::add (boost::shared_ptr pl) { if (find (playlists.begin(), playlists.end(), pl) == playlists.end()) { - pl->ref (); + pl->use (); playlists.push_back(pl); PlaylistsChanged (); } } void -Selection::add (const list& pllist) +Selection::add (const list >& pllist) { bool changed = false; - for (list::const_iterator i = pllist.begin(); i != pllist.end(); ++i) { + for (list >::const_iterator i = pllist.begin(); i != pllist.end(); ++i) { if (find (playlists.begin(), playlists.end(), (*i)) == playlists.end()) { - (*i)->ref (); + (*i)->use (); playlists.push_back (*i); changed = true; } @@ -310,33 +296,64 @@ Selection::add (TimeAxisView* track) } void -Selection::add (AudioRegionView* r) +Selection::add (vector& v) { - if (find (audio_regions.begin(), audio_regions.end(), r) == audio_regions.end()) { - audio_regions.add (r); + /* XXX This method or the add (const RegionSelection&) needs to go + */ + + bool changed = false; + + for (vector::iterator i = v.begin(); i != v.end(); ++i) { + if (find (regions.begin(), regions.end(), (*i)) == regions.end()) { + changed = regions.add ((*i)); + if (Config->get_link_region_and_track_selection() && changed) { + add (&(*i)->get_trackview()); + } + } + } + + if (changed) { RegionsChanged (); } } void -Selection::add (vector& v) +Selection::add (const RegionSelection& rs) { - bool changed = false; + /* XXX This method or the add (const vector&) needs to go + */ - for (vector::iterator i = v.begin(); i != v.end(); ++i) { - if (find (audio_regions.begin(), audio_regions.end(), (*i)) == audio_regions.end()) { - audio_regions.add ((*i)); - changed = true; + bool changed = false; + + for (RegionSelection::const_iterator i = rs.begin(); i != rs.end(); ++i) { + if (find (regions.begin(), regions.end(), (*i)) == regions.end()) { + changed = regions.add ((*i)); + if (Config->get_link_region_and_track_selection() && changed) { + add (&(*i)->get_trackview()); + } } } - + if (changed) { + select_edit_group_regions (); + RegionsChanged (); + } +} + +void +Selection::add (RegionView* r) +{ + if (find (regions.begin(), regions.end(), r) == regions.end()) { + regions.add (r); + if (Config->get_link_region_and_track_selection()) { + add (&r->get_trackview()); + } RegionsChanged (); } } long -Selection::add (jack_nframes_t start, jack_nframes_t end) +Selection::add (nframes_t start, nframes_t end) { AudioRangeComparator cmp; @@ -352,7 +369,7 @@ Selection::add (jack_nframes_t start, jack_nframes_t end) } void -Selection::replace (uint32_t sid, jack_nframes_t start, jack_nframes_t end) +Selection::replace (uint32_t sid, nframes_t start, nframes_t end) { for (list::iterator i = time.begin(); i != time.end(); ++i) { if ((*i).id == sid) { @@ -372,21 +389,18 @@ Selection::replace (uint32_t sid, jack_nframes_t start, jack_nframes_t end) } void -Selection::add (AutomationList* ac) +Selection::add (boost::shared_ptr cl) { - if (find (lines.begin(), lines.end(), ac) == lines.end()) { - lines.push_back (ac); - LinesChanged(); + boost::shared_ptr al + = boost::dynamic_pointer_cast(cl); + if (!al) { + warning << "Programming error: Selected list is not an ARDOUR::AutomationList" << endmsg; + return; + return; } -} - -void -Selection::remove (boost::shared_ptr r) -{ - RedirectSelection::iterator i; - if ((i = find (redirects.begin(), redirects.end(), r)) != redirects.end()) { - redirects.erase (i); - RedirectsChanged (); + if (find (lines.begin(), lines.end(), al) == lines.end()) { + lines.push_back (al); + LinesChanged(); } } @@ -421,9 +435,9 @@ Selection::remove (const list& track_list) } void -Selection::remove (Playlist* track) +Selection::remove (boost::shared_ptr track) { - list::iterator i; + list >::iterator i; if ((i = find (playlists.begin(), playlists.end(), track)) != playlists.end()) { playlists.erase (i); PlaylistsChanged(); @@ -431,13 +445,13 @@ Selection::remove (Playlist* track) } void -Selection::remove (const list& pllist) +Selection::remove (const list >& pllist) { bool changed = false; - for (list::const_iterator i = pllist.begin(); i != pllist.end(); ++i) { + for (list >::const_iterator i = pllist.begin(); i != pllist.end(); ++i) { - list::iterator x; + list >::iterator x; if ((x = find (playlists.begin(), playlists.end(), (*i))) != playlists.end()) { playlists.erase (x); @@ -451,10 +465,15 @@ Selection::remove (const list& pllist) } void -Selection::remove (AudioRegionView* r) +Selection::remove (RegionView* r) { - audio_regions.remove (r); - RegionsChanged (); + if (regions.remove (r)) { + RegionsChanged (); + } + + if (Config->get_link_region_and_track_selection() && !regions.involves (r->get_trackview())) { + remove (&r->get_trackview()); + } } @@ -476,27 +495,20 @@ Selection::remove (uint32_t selection_id) } void -Selection::remove (jack_nframes_t start, jack_nframes_t end) +Selection::remove (nframes_t start, nframes_t end) { } void -Selection::remove (AutomationList *ac) +Selection::remove (boost::shared_ptr ac) { - list::iterator i; + AutomationSelection::iterator i; if ((i = find (lines.begin(), lines.end(), ac)) != lines.end()) { lines.erase (i); LinesChanged(); } } -void -Selection::set (boost::shared_ptr r) -{ - clear_redirects (); - add (r); -} - void Selection::set (TimeAxisView* track) { @@ -512,38 +524,51 @@ Selection::set (const list& track_list) } void -Selection::set (Playlist* playlist) +Selection::set (boost::shared_ptr playlist) { clear_playlists (); add (playlist); } void -Selection::set (const list& pllist) +Selection::set (const list >& pllist) { clear_playlists (); add (pllist); } void -Selection::set (AudioRegionView* r) +Selection::set (const RegionSelection& rs) { - clear_audio_regions (); - add (r); + clear_regions(); + regions = rs; + RegionsChanged(); /* EMIT SIGNAL */ } void -Selection::set (vector& v) +Selection::set (RegionView* r, bool also_clear_tracks) { + clear_regions (); + if (also_clear_tracks) { + clear_tracks (); + } + add (r); +} - clear_audio_regions (); - // make sure to deselect any automation selections - clear_points(); +void +Selection::set (vector& v) +{ + clear_regions (); + if (Config->get_link_region_and_track_selection()) { + clear_tracks (); + // make sure to deselect any automation selections + clear_points(); + } add (v); } long -Selection::set (TimeAxisView* track, jack_nframes_t start, jack_nframes_t end) +Selection::set (TimeAxisView* track, nframes_t start, nframes_t end) { if ((start == 0 && end == 0) || end < start) { return 0; @@ -577,12 +602,18 @@ Selection::set (TimeAxisView* track, jack_nframes_t start, jack_nframes_t end) } void -Selection::set (AutomationList *ac) +Selection::set (boost::shared_ptr ac) { lines.clear(); add (ac); } +bool +Selection::selected (Marker* m) +{ + return find (markers.begin(), markers.end(), m) != markers.end(); +} + bool Selection::selected (TimeAxisView* tv) { @@ -590,56 +621,103 @@ Selection::selected (TimeAxisView* tv) } bool -Selection::selected (AudioRegionView* arv) +Selection::selected (RegionView* rv) { - return find (audio_regions.begin(), audio_regions.end(), arv) != audio_regions.end(); + return find (regions.begin(), regions.end(), rv) != regions.end(); } bool Selection::empty () { - return audio_regions.empty () && + return regions.empty () && tracks.empty () && points.empty () && playlists.empty () && lines.empty () && time.empty () && playlists.empty () && - redirects.empty () + markers.empty() ; } +void +Selection::toggle (const vector& autos) +{ + for (vector::const_iterator x = autos.begin(); x != autos.end(); ++x) { + if ((*x)->get_selected()) { + points.remove (**x); + } else { + points.push_back (**x); + } + + delete *x; + } + + PointsChanged (); /* EMIT SIGNAL */ +} + +void +Selection::toggle (list& selectables) +{ + RegionView* rv; + AutomationSelectable* as; + vector rvs; + vector autos; + + for (std::list::iterator i = selectables.begin(); i != selectables.end(); ++i) { + if ((rv = dynamic_cast (*i)) != 0) { + rvs.push_back (rv); + } else if ((as = dynamic_cast (*i)) != 0) { + autos.push_back (as); + } else { + fatal << _("programming error: ") + << X_("unknown selectable type passed to Selection::toggle()") + << endmsg; + /*NOTREACHED*/ + } + } + + if (!rvs.empty()) { + toggle (rvs); + } + + if (!autos.empty()) { + toggle (autos); + } +} + void Selection::set (list& selectables) { - clear_audio_regions(); + clear_regions(); clear_points (); add (selectables); } + void Selection::add (list& selectables) { - AudioRegionView* arv; + RegionView* rv; AutomationSelectable* as; - vector arvs; + vector rvs; vector autos; for (std::list::iterator i = selectables.begin(); i != selectables.end(); ++i) { - if ((arv = dynamic_cast (*i)) != 0) { - arvs.push_back (arv); + if ((rv = dynamic_cast (*i)) != 0) { + rvs.push_back (rv); } else if ((as = dynamic_cast (*i)) != 0) { autos.push_back (as); } else { fatal << _("programming error: ") - << X_("unknown selectable type passed to Selection::set()") + << X_("unknown selectable type passed to Selection::add()") << endmsg; /*NOTREACHED*/ } } - if (!arvs.empty()) { - add (arvs); + if (!rvs.empty()) { + add (rvs); } if (!autos.empty()) { @@ -661,8 +739,99 @@ Selection::add (vector& autos) { for (vector::iterator i = autos.begin(); i != autos.end(); ++i) { points.push_back (**i); - delete *i; } PointsChanged (); } + +void +Selection::select_edit_group_regions () +{ + std::set regions_to_add; + + for (RegionSelection::iterator i = regions.begin(); i != regions.end(); ++i) { + vector e; + editor->get_equivalent_regions (*i, e); + for (vector::iterator j = e.begin(); j != e.end(); ++j) { + regions_to_add.insert(*j); + } + } + + for (std::set::iterator i = regions_to_add.begin(); i != regions_to_add.end(); ++i) { + add (*i); + } +} + +void +Selection::set (Marker* m) +{ + clear_markers (); + add (m); +} + +void +Selection::toggle (Marker* m) +{ + MarkerSelection::iterator i; + + if ((i = find (markers.begin(), markers.end(), m)) == markers.end()) { + add (m); + } else { + remove (m); + } +} + +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) +{ + if (find (markers.begin(), markers.end(), m) == markers.end()) { + + /* disambiguate which remove() for the compiler */ + + void (Selection::*pmf)(Marker*) = &Selection::remove; + + m->GoingAway.connect (bind (mem_fun (*this, pmf), m)); + + markers.push_back (m); + MarkersChanged(); + } +} + +void +Selection::add (const list& m) +{ + markers.insert (markers.end(), m.begin(), m.end()); + MarkersChanged (); +} + +void +MarkerSelection::range (nframes64_t& s, nframes64_t& e) +{ + s = max_frames; + 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); +}