~ubuntu-branches/ubuntu/utopic/ardour3/utopic

« back to all changes in this revision

Viewing changes to gtk2_ardour/region_selection.cc

  • Committer: Package Import Robot
  • Author(s): Felipe Sateler
  • Date: 2013-09-21 19:05:02 UTC
  • Revision ID: package-import@ubuntu.com-20130921190502-8gsftrku6jnzhd7v
Tags: upstream-3.4~dfsg
ImportĀ upstreamĀ versionĀ 3.4~dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 "region_view.h"
 
25
#include "region_selection.h"
 
26
#include "time_axis_view.h"
 
27
 
 
28
using namespace std;
 
29
using namespace ARDOUR;
 
30
using namespace PBD;
 
31
 
 
32
/** Construct an empty RegionSelection.
 
33
 */
 
34
RegionSelection::RegionSelection ()
 
35
{
 
36
        RegionView::RegionViewGoingAway.connect (death_connection, MISSING_INVALIDATOR, boost::bind (&RegionSelection::remove_it, this, _1), gui_context());
 
37
}
 
38
 
 
39
/** Copy constructor.
 
40
 *  @param other RegionSelection to copy.
 
41
 */
 
42
RegionSelection::RegionSelection (const RegionSelection& other)
 
43
        : std::list<RegionView*>()
 
44
{
 
45
        RegionView::RegionViewGoingAway.connect (death_connection, MISSING_INVALIDATOR, boost::bind (&RegionSelection::remove_it, this, _1), gui_context());
 
46
 
 
47
        for (RegionSelection::const_iterator i = other.begin(); i != other.end(); ++i) {
 
48
                add (*i);
 
49
        }
 
50
}
 
51
 
 
52
/** operator= to set a RegionSelection to be the same as another.
 
53
 *  @param other Other RegionSelection.
 
54
 */
 
55
RegionSelection&
 
56
RegionSelection::operator= (const RegionSelection& other)
 
57
{
 
58
        if (this != &other) {
 
59
 
 
60
                clear_all();
 
61
 
 
62
                for (RegionSelection::const_iterator i = other.begin(); i != other.end(); ++i) {
 
63
                        add (*i);
 
64
                }
 
65
        }
 
66
 
 
67
        return *this;
 
68
}
 
69
 
 
70
/** Empty this RegionSelection.
 
71
 */
 
72
void
 
73
RegionSelection::clear_all()
 
74
{
 
75
        clear();
 
76
        _bylayer.clear();
 
77
}
 
78
 
 
79
/**
 
80
 *  @param rv RegionView.
 
81
 *  @return true if this selection contains rv.
 
82
 */
 
83
bool RegionSelection::contains (RegionView* rv) const
 
84
{
 
85
        return find (begin(), end(), rv) != end();
 
86
}
 
87
 
 
88
/** Add a region to the selection.
 
89
 *  @param rv Region to add.
 
90
 *  @return false if we already had the region or if it cannot be added,
 
91
 *          otherwise true.
 
92
 */
 
93
bool
 
94
RegionSelection::add (RegionView* rv)
 
95
{
 
96
        if (!rv->region()->playlist()) {
 
97
                /* not attached to a playlist - selection not allowed.
 
98
                   This happens if the user tries to select a region
 
99
                   during a capture pass.
 
100
                */
 
101
                return false;
 
102
        }
 
103
 
 
104
        if (contains (rv)) {
 
105
                /* we already have it */
 
106
                return false;
 
107
        }
 
108
 
 
109
        push_back (rv);
 
110
 
 
111
        /* add to layer sorted list */
 
112
 
 
113
        add_to_layer (rv);
 
114
 
 
115
        return true;
 
116
}
 
117
 
 
118
/** Remove a region from the selection.
 
119
 *  @param rv Region to remove.
 
120
 */
 
121
void
 
122
RegionSelection::remove_it (RegionView *rv)
 
123
{
 
124
        remove (rv);
 
125
}
 
126
 
 
127
/** Remove a region from the selection.
 
128
 *  @param rv Region to remove.
 
129
 *  @return true if the region was in the selection, false if not.
 
130
 */
 
131
bool
 
132
RegionSelection::remove (RegionView* rv)
 
133
{
 
134
        RegionSelection::iterator r;
 
135
 
 
136
        if ((r = find (begin(), end(), rv)) != end()) {
 
137
 
 
138
                // remove from layer sorted list
 
139
                _bylayer.remove (rv);
 
140
 
 
141
                erase (r);
 
142
                return true;
 
143
        }
 
144
 
 
145
        return false;
 
146
}
 
147
 
 
148
/** Add a region to the list sorted by layer.
 
149
 *  @param rv Region to add.
 
150
 */
 
151
void
 
152
RegionSelection::add_to_layer (RegionView * rv)
 
153
{
 
154
        // insert it into layer sorted position
 
155
 
 
156
        list<RegionView*>::iterator i;
 
157
 
 
158
        for (i = _bylayer.begin(); i != _bylayer.end(); ++i)
 
159
        {
 
160
                if (rv->region()->layer() < (*i)->region()->layer()) {
 
161
                        _bylayer.insert(i, rv);
 
162
                        return;
 
163
                }
 
164
        }
 
165
 
 
166
        // insert at end if we get here
 
167
        _bylayer.insert(i, rv);
 
168
}
 
169
 
 
170
struct RegionSortByTime {
 
171
    bool operator() (const RegionView* a, const RegionView* b) const {
 
172
            return a->region()->position() < b->region()->position();
 
173
    }
 
174
};
 
175
 
 
176
 
 
177
/**
 
178
 *  @param foo List which will be filled with the selection's regions
 
179
 *  sorted by position.
 
180
 */
 
181
void
 
182
RegionSelection::by_position (list<RegionView*>& foo) const
 
183
{
 
184
        list<RegionView*>::const_iterator i;
 
185
        RegionSortByTime sorter;
 
186
 
 
187
        for (i = _bylayer.begin(); i != _bylayer.end(); ++i) {
 
188
                foo.push_back (*i);
 
189
        }
 
190
 
 
191
        foo.sort (sorter);
 
192
        return;
 
193
}
 
194
 
 
195
struct RegionSortByTrack {
 
196
    bool operator() (const RegionView* a, const RegionView* b) const {
 
197
 
 
198
            /* really, track and position */
 
199
 
 
200
            if (a->get_time_axis_view().order() == b->get_time_axis_view().order()) {
 
201
                    return a->region()->position() < b->region()->position();
 
202
            } else {
 
203
                    return a->get_time_axis_view().order() < b->get_time_axis_view().order();
 
204
            }
 
205
    }
 
206
};
 
207
 
 
208
 
 
209
/**
 
210
 *  @param List which will be filled with the selection's regions
 
211
 *  sorted by track and position.
 
212
 */
 
213
void
 
214
RegionSelection::by_track (list<RegionView*>& foo) const
 
215
{
 
216
        list<RegionView*>::const_iterator i;
 
217
        RegionSortByTrack sorter;
 
218
 
 
219
        for (i = _bylayer.begin(); i != _bylayer.end(); ++i) {
 
220
                foo.push_back (*i);
 
221
        }
 
222
 
 
223
        foo.sort (sorter);
 
224
        return;
 
225
}
 
226
 
 
227
/**
 
228
 *  @param Sort the selection by position and track.
 
229
 */
 
230
void
 
231
RegionSelection::sort_by_position_and_track ()
 
232
{
 
233
        RegionSortByTrack sorter;
 
234
        sort (sorter);
 
235
}
 
236
 
 
237
/**
 
238
 *  @param tv Track.
 
239
 *  @return true if any of the selection's regions are on tv.
 
240
 */
 
241
bool
 
242
RegionSelection::involves (const TimeAxisView& tv) const
 
243
{
 
244
        for (RegionSelection::const_iterator i = begin(); i != end(); ++i) {
 
245
                if (&(*i)->get_time_axis_view() == &tv) {
 
246
                        return true;
 
247
                }
 
248
        }
 
249
        return false;
 
250
}
 
251
 
 
252
framepos_t
 
253
RegionSelection::start () const
 
254
{
 
255
        framepos_t s = max_framepos;
 
256
        for (RegionSelection::const_iterator i = begin(); i != end(); ++i) {
 
257
                s = min (s, (*i)->region()->position ());
 
258
        }
 
259
 
 
260
        if (s == max_framepos) {
 
261
                return 0;
 
262
        }
 
263
 
 
264
        return s;
 
265
}
 
266
 
 
267
framepos_t
 
268
RegionSelection::end_frame () const
 
269
{
 
270
        framepos_t e = 0;
 
271
        for (RegionSelection::const_iterator i = begin(); i != end(); ++i) {
 
272
                e = max (e, (*i)->region()->last_frame ());
 
273
        }
 
274
 
 
275
        return e;
 
276
}
 
277
 
 
278
/** @return the playlists that the regions in the selection are on */
 
279
set<boost::shared_ptr<Playlist> >
 
280
RegionSelection::playlists () const
 
281
{
 
282
        set<boost::shared_ptr<Playlist> > pl;
 
283
        for (RegionSelection::const_iterator i = begin(); i != end(); ++i) {
 
284
                pl.insert ((*i)->region()->playlist ());
 
285
        }
 
286
 
 
287
        return pl;
 
288
}