ardour
region_selection.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2006 Paul Davis
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18 
19 #include <algorithm>
20 
21 #include "ardour/region.h"
22 
23 #include "gui_thread.h"
24 #include "midi_region_view.h"
25 #include "region_view.h"
26 #include "region_selection.h"
27 #include "time_axis_view.h"
28 
29 using namespace std;
30 using namespace ARDOUR;
31 using namespace PBD;
32 
36 {
37  RegionView::RegionViewGoingAway.connect (death_connection, MISSING_INVALIDATOR, boost::bind (&RegionSelection::remove_it, this, _1), gui_context());
38 }
39 
44  : std::list<RegionView*>()
45 {
47 
48  for (RegionSelection::const_iterator i = other.begin(); i != other.end(); ++i) {
49  add (*i);
50  }
51 }
52 
58 {
59  if (this != &other) {
60 
61  clear_all();
62 
63  for (RegionSelection::const_iterator i = other.begin(); i != other.end(); ++i) {
64  add (*i);
65  }
66  }
67 
68  return *this;
69 }
70 
73 void
75 {
76  clear();
77  pending.clear ();
78  _bylayer.clear();
79 }
80 
86 {
87  return find (begin(), end(), rv) != end();
88 }
89 
95 bool
97 {
98  if (!rv->region()->playlist()) {
99  /* not attached to a playlist - selection not allowed.
100  This happens if the user tries to select a region
101  during a capture pass.
102  */
103  return false;
104  }
105 
106  if (contains (rv)) {
107  /* we already have it */
108  return false;
109  }
110 
111  push_back (rv);
112 
113  /* add to layer sorted list */
114 
115  add_to_layer (rv);
116 
117  return true;
118 }
119 
123 void
125 {
126  remove (rv);
127 }
128 
133 bool
135 {
136  RegionSelection::iterator r;
137 
138  if ((r = find (begin(), end(), rv)) != end()) {
139 
140  // remove from layer sorted list
141  _bylayer.remove (rv);
142 
143  erase (r);
144  return true;
145  }
146 
147  return false;
148 }
149 
153 void
155 {
156  // insert it into layer sorted position
157 
158  list<RegionView*>::iterator i;
159 
160  for (i = _bylayer.begin(); i != _bylayer.end(); ++i)
161  {
162  if (rv->region()->layer() < (*i)->region()->layer()) {
163  _bylayer.insert(i, rv);
164  return;
165  }
166  }
167 
168  // insert at end if we get here
169  _bylayer.insert(i, rv);
170 }
171 
172 struct RegionSortByTime {
173  bool operator() (const RegionView* a, const RegionView* b) const {
174  return a->region()->position() < b->region()->position();
175  }
176 };
177 
178 
183 void
184 RegionSelection::by_position (list<RegionView*>& foo) const
185 {
186  list<RegionView*>::const_iterator i;
187  RegionSortByTime sorter;
188 
189  for (i = _bylayer.begin(); i != _bylayer.end(); ++i) {
190  foo.push_back (*i);
191  }
192 
193  foo.sort (sorter);
194  return;
195 }
196 
198  bool operator() (const RegionView* a, const RegionView* b) const {
199 
200  /* really, track and position */
201 
202  if (a->get_time_axis_view().order() == b->get_time_axis_view().order()) {
203  return a->region()->position() < b->region()->position();
204  } else {
205  return a->get_time_axis_view().order() < b->get_time_axis_view().order();
206  }
207  }
208 };
209 
210 
215 void
216 RegionSelection::by_track (list<RegionView*>& foo) const
217 {
218  list<RegionView*>::const_iterator i;
219  RegionSortByTrack sorter;
220 
221  for (i = _bylayer.begin(); i != _bylayer.end(); ++i) {
222  foo.push_back (*i);
223  }
224 
225  foo.sort (sorter);
226  return;
227 }
228 
232 void
234 {
235  RegionSortByTrack sorter;
236  sort (sorter);
237 }
238 
243 bool
245 {
246  for (RegionSelection::const_iterator i = begin(); i != end(); ++i) {
247  if (&(*i)->get_time_axis_view() == &tv) {
248  return true;
249  }
250  }
251  return false;
252 }
253 
256 {
258  for (RegionSelection::const_iterator i = begin(); i != end(); ++i) {
259  s = min (s, (*i)->region()->position ());
260  }
261 
262  if (s == max_framepos) {
263  return 0;
264  }
265 
266  return s;
267 }
268 
271 {
272  framepos_t e = 0;
273  for (RegionSelection::const_iterator i = begin(); i != end(); ++i) {
274  e = max (e, (*i)->region()->last_frame ());
275  }
276 
277  return e;
278 }
279 
281 set<boost::shared_ptr<Playlist> >
283 {
284  set<boost::shared_ptr<Playlist> > pl;
285  for (RegionSelection::const_iterator i = begin(); i != end(); ++i) {
286  pl.insert ((*i)->region()->playlist ());
287  }
288 
289  return pl;
290 }
291 
292 size_t
294 {
295  size_t count = 0;
296 
297  for (const_iterator r = begin(); r != end(); ++r) {
298  MidiRegionView* const mrv = dynamic_cast<MidiRegionView*> (*r);
299  if (mrv) {
300  ++count;
301  }
302  }
303 
304  return count;
305 }
bool add(RegionView *)
std::list< PBD::ID > pending
static PBD::Signal1< void, RegionView * > RegionViewGoingAway
Definition: region_view.h:100
void by_track(std::list< RegionView * > &) const
TimeAxisView & get_time_axis_view() const
bool operator()(const RegionView *a, const RegionView *b)
Definition: editor_ops.cc:3485
void sort_by_position_and_track()
bool remove(RegionView *)
bool operator()(const RegionView *a, const RegionView *b) const
framepos_t end_frame() const
void remove_it(RegionView *)
size_t n_midi_regions() const
Definition: Beats.hpp:239
void by_position(std::list< RegionView * > &) const
bool contains(RegionView *) const
boost::shared_ptr< ARDOUR::Region > region() const
Definition: region_view.h:66
RegionSelection & operator=(const RegionSelection &)
Definition: amp.h:29
#define gui_context()
Definition: gui_thread.h:36
int64_t framepos_t
Definition: types.h:66
bool involves(const TimeAxisView &) const
layer_t layer() const
Definition: region.h:115
framepos_t position() const
Definition: region.h:112
std::set< boost::shared_ptr< ARDOUR::Playlist > > playlists() const
std::list< RegionView * > _bylayer
list of regions sorted by layer
framepos_t start() const
Definition: debug.h:30
static const framepos_t max_framepos
Definition: types.h:78
#define MISSING_INVALIDATOR
Definition: event_loop.h:86
PBD::ScopedConnection death_connection
int order() const
void add_to_layer(RegionView *)
boost::shared_ptr< ARDOUR::Playlist > playlist() const
Definition: region.h:251