X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fregion_selection.cc;h=54e5aa3acce47b69ff6fb737253bdf6bdaee29a7;hb=8c8bc5103492aeacc64565655f4e939dbb73d02d;hp=d1970138c5dde1e345eda16613b772f4c48f9874;hpb=042997e5ed35778c5309b6119ca1dcf8f696c3cc;p=ardour.git diff --git a/gtk2_ardour/region_selection.cc b/gtk2_ardour/region_selection.cc index d1970138c5..54e5aa3acc 100644 --- a/gtk2_ardour/region_selection.cc +++ b/gtk2_ardour/region_selection.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2006 Paul Davis + Copyright (C) 2006 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -18,112 +18,95 @@ #include -#include +#include "ardour/region.h" +#include "gui_thread.h" #include "region_view.h" #include "region_selection.h" #include "time_axis_view.h" +using namespace std; using namespace ARDOUR; using namespace PBD; -using namespace sigc; -/** - * Construct an empty RegionSelection. +/** Construct an empty RegionSelection. */ - RegionSelection::RegionSelection () { - RegionView::RegionViewGoingAway.connect (mem_fun(*this, &RegionSelection::remove_it)); - - _current_start = 0; - _current_end = 0; + RegionView::RegionViewGoingAway.connect (death_connection, MISSING_INVALIDATOR, boost::bind (&RegionSelection::remove_it, this, _1), gui_context()); } -/** - * Copy constructor. +/** Copy constructor. * @param other RegionSelection to copy. */ - RegionSelection::RegionSelection (const RegionSelection& other) + : std::list() { - RegionView::RegionViewGoingAway.connect (mem_fun(*this, &RegionSelection::remove_it)); + RegionView::RegionViewGoingAway.connect (death_connection, MISSING_INVALIDATOR, boost::bind (&RegionSelection::remove_it, this, _1), gui_context()); for (RegionSelection::const_iterator i = other.begin(); i != other.end(); ++i) { add (*i); } - _current_start = other._current_start; - _current_end = other._current_end; } -/** - * operator= to set a RegionSelection to be the same as another. +/** operator= to set a RegionSelection to be the same as another. * @param other Other RegionSelection. */ - RegionSelection& RegionSelection::operator= (const RegionSelection& other) { if (this != &other) { clear_all(); - + for (RegionSelection::const_iterator i = other.begin(); i != other.end(); ++i) { add (*i); } - - _current_start = other._current_start; - _current_end = other._current_end; } return *this; } -/** - * Empty this RegionSelection. +/** Empty this RegionSelection. */ - void RegionSelection::clear_all() { clear(); + pending.clear (); _bylayer.clear(); - _current_start = 0; - _current_end = 0; } /** * @param rv RegionView. * @return true if this selection contains rv. */ - bool RegionSelection::contains (RegionView* rv) const { return find (begin(), end(), rv) != end(); } -/** - * Add a region to the selection. +/** Add a region to the selection. * @param rv Region to add. - * @return false if we already had the region, otherwise true. + * @return false if we already had the region or if it cannot be added, + * otherwise true. */ - bool RegionSelection::add (RegionView* rv) { + if (!rv->region()->playlist()) { + /* not attached to a playlist - selection not allowed. + This happens if the user tries to select a region + during a capture pass. + */ + return false; + } + if (contains (rv)) { /* we already have it */ return false; } - if (rv->region()->first_frame() < _current_start || empty()) { - _current_start = rv->region()->first_frame(); - } - - if (rv->region()->last_frame() > _current_end || empty()) { - _current_end = rv->region()->last_frame(); - } - push_back (rv); /* add to layer sorted list */ @@ -133,23 +116,19 @@ RegionSelection::add (RegionView* rv) return true; } -/** - * Remove a region from the selection. +/** Remove a region from the selection. * @param rv Region to remove. */ - void RegionSelection::remove_it (RegionView *rv) { remove (rv); } -/** - * Remove a region from the selection. +/** Remove a region from the selection. * @param rv Region to remove. * @return true if the region was in the selection, false if not. */ - bool RegionSelection::remove (RegionView* rv) { @@ -159,65 +138,17 @@ RegionSelection::remove (RegionView* rv) // remove from layer sorted list _bylayer.remove (rv); - - if (size() == 1) { - - /* this is the last one, so when we delete it - we will be empty. - */ - - _current_start = 0; - _current_end = 0; - - } else { - - boost::shared_ptr region ((*r)->region()); - - if (region->first_frame() == _current_start) { - - /* reset current start */ - - nframes_t ref = max_frames; - - for (RegionSelection::iterator i = begin (); i != end(); ++i) { - if (region->first_frame() < ref) { - ref = region->first_frame(); - } - } - - _current_start = ref; - - } - - if (region->last_frame() == _current_end) { - - /* reset current end */ - - nframes_t ref = 0; - - for (RegionSelection::iterator i = begin (); i != end(); ++i) { - if (region->first_frame() > ref) { - ref = region->first_frame(); - } - } - - _current_end = ref; - } - } erase (r); - return true; } return false; } -/** - * Add a region to the list sorted by layer. +/** Add a region to the list sorted by layer. * @param rv Region to add. */ - void RegionSelection::add_to_layer (RegionView * rv) { @@ -248,7 +179,6 @@ struct RegionSortByTime { * @param foo List which will be filled with the selection's regions * sorted by position. */ - void RegionSelection::by_position (list& foo) const { @@ -265,13 +195,13 @@ RegionSelection::by_position (list& foo) const struct RegionSortByTrack { bool operator() (const RegionView* a, const RegionView* b) const { - + /* really, track and position */ - if (a->get_trackview().order() == b->get_trackview().order()) { + if (a->get_time_axis_view().order() == b->get_time_axis_view().order()) { return a->region()->position() < b->region()->position(); } else { - return a->get_trackview().order() < b->get_trackview().order(); + return a->get_time_axis_view().order() < b->get_time_axis_view().order(); } } }; @@ -281,7 +211,6 @@ struct RegionSortByTrack { * @param List which will be filled with the selection's regions * sorted by track and position. */ - void RegionSelection::by_track (list& foo) const { @@ -299,7 +228,6 @@ RegionSelection::by_track (list& foo) const /** * @param Sort the selection by position and track. */ - void RegionSelection::sort_by_position_and_track () { @@ -311,15 +239,51 @@ RegionSelection::sort_by_position_and_track () * @param tv Track. * @return true if any of the selection's regions are on tv. */ - bool RegionSelection::involves (const TimeAxisView& tv) const { for (RegionSelection::const_iterator i = begin(); i != end(); ++i) { - if (&(*i)->get_trackview() == &tv) { + if (&(*i)->get_time_axis_view() == &tv) { return true; } } return false; } - + +framepos_t +RegionSelection::start () const +{ + framepos_t s = max_framepos; + for (RegionSelection::const_iterator i = begin(); i != end(); ++i) { + s = min (s, (*i)->region()->position ()); + } + + if (s == max_framepos) { + return 0; + } + + return s; +} + +framepos_t +RegionSelection::end_frame () const +{ + framepos_t e = 0; + for (RegionSelection::const_iterator i = begin(); i != end(); ++i) { + e = max (e, (*i)->region()->last_frame ()); + } + + return e; +} + +/** @return the playlists that the regions in the selection are on */ +set > +RegionSelection::playlists () const +{ + set > pl; + for (RegionSelection::const_iterator i = begin(); i != end(); ++i) { + pl.insert ((*i)->region()->playlist ()); + } + + return pl; +}