summaryrefslogtreecommitdiff
path: root/gtk2_ardour
diff options
context:
space:
mode:
Diffstat (limited to 'gtk2_ardour')
-rw-r--r--gtk2_ardour/editor.cc9
-rw-r--r--gtk2_ardour/editor.h3
-rw-r--r--gtk2_ardour/editor_mixer.cc2
-rw-r--r--gtk2_ardour/editor_ops.cc116
-rw-r--r--gtk2_ardour/editor_selection.cc61
-rw-r--r--gtk2_ardour/playlist_selector.cc12
-rw-r--r--gtk2_ardour/time_axis_view.cc27
-rwxr-xr-xgtk2_ardour/track_view_list.h3
8 files changed, 167 insertions, 66 deletions
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc
index e98a63b6a0..28659d077d 100644
--- a/gtk2_ardour/editor.cc
+++ b/gtk2_ardour/editor.cc
@@ -4349,15 +4349,10 @@ struct EditorOrderTimeAxisSorter {
};
void
-Editor::sort_track_selection (TrackViewList* sel)
+Editor::sort_track_selection (TrackViewList& sel)
{
EditorOrderTimeAxisSorter cmp;
-
- if (sel) {
- sel->sort (cmp);
- } else {
- selection->tracks.sort (cmp);
- }
+ sel.sort (cmp);
}
framepos_t
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index c8d4efd4e8..9fa45ba85d 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -632,11 +632,12 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
CrossfadeView* clicked_crossfadeview;
ControlPoint* clicked_control_point;
- void sort_track_selection (TrackViewList* sel = 0);
+ void sort_track_selection (TrackViewList&);
void get_equivalent_regions (RegionView* rv, std::vector<RegionView*> &, PBD::PropertyID) const;
RegionSelection get_equivalent_regions (RegionSelection &, PBD::PropertyID) const;
void mapover_tracks (sigc::slot<void,RouteTimeAxisView&,uint32_t> sl, TimeAxisView*, PBD::PropertyID) const;
+ void mapover_tracks_with_unique_playlists (sigc::slot<void,RouteTimeAxisView&,uint32_t> sl, TimeAxisView*, PBD::PropertyID) const;
/* functions to be passed to mapover_tracks(), possibly with sigc::bind()-supplied arguments */
diff --git a/gtk2_ardour/editor_mixer.cc b/gtk2_ardour/editor_mixer.cc
index 69f60ad3cf..12b5ff3f30 100644
--- a/gtk2_ardour/editor_mixer.cc
+++ b/gtk2_ardour/editor_mixer.cc
@@ -99,7 +99,7 @@ Editor::show_editor_mixer (bool yn)
}
} else {
- sort_track_selection ();
+ sort_track_selection (selection->tracks);
for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
RouteTimeAxisView* atv;
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index c598af2453..738737f46d 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -560,11 +560,11 @@ Editor::build_region_boundary_cache ()
TimeAxisView *ontrack = 0;
TrackViewList tlist;
-
+
if (!selection->tracks.empty()) {
- tlist = selection->tracks;
+ tlist = selection->tracks.filter_to_unique_playlists ();
} else {
- tlist = track_views;
+ tlist = track_views.filter_to_unique_playlists ();
}
while (pos < _session->current_end_frame() && !at_end) {
@@ -2339,9 +2339,10 @@ Editor::create_region_from_selection (vector<boost::shared_ptr<Region> >& new_re
framepos_t start = selection->time[clicked_selection].start;
framepos_t end = selection->time[clicked_selection].end;
- sort_track_selection ();
+ TrackViewList ts = selection->tracks.filter_to_unique_playlists ();
+ sort_track_selection (ts);
- for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
+ for (TrackSelection::iterator i = ts.begin(); i != ts.end(); ++i) {
boost::shared_ptr<Region> current;
boost::shared_ptr<Playlist> playlist;
framepos_t internal_start;
@@ -2437,7 +2438,7 @@ Editor::get_tracks_for_range_action () const
t = selection->tracks;
}
- return t;
+ return t.filter_to_unique_playlists();
}
void
@@ -2448,7 +2449,7 @@ Editor::separate_regions_between (const TimeSelection& ts)
RegionSelection new_selection;
TrackViewList tmptracks = get_tracks_for_range_action ();
- sort_track_selection (&tmptracks);
+ sort_track_selection (tmptracks);
for (TrackSelection::iterator i = tmptracks.begin(); i != tmptracks.end(); ++i) {
@@ -2691,16 +2692,17 @@ Editor::crop_region_to (framepos_t start, framepos_t end)
{
vector<boost::shared_ptr<Playlist> > playlists;
boost::shared_ptr<Playlist> playlist;
- TrackViewList* ts;
+ TrackViewList ts;
if (selection->tracks.empty()) {
- ts = &track_views;
+ ts = track_views.filter_to_unique_playlists();
} else {
- sort_track_selection ();
- ts = &selection->tracks;
+ ts = selection->tracks.filter_to_unique_playlists ();
}
- for (TrackSelection::iterator i = ts->begin(); i != ts->end(); ++i) {
+ sort_track_selection (ts);
+
+ for (TrackSelection::iterator i = ts.begin(); i != ts.end(); ++i) {
RouteTimeAxisView* rtv;
@@ -2825,7 +2827,9 @@ Editor::region_fill_selection ()
begin_reversible_command (Operations::fill_selection);
- for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
+ TrackViewList ts = selection->tracks.filter_to_unique_playlists ();
+
+ for (TrackViewList::iterator i = ts.begin(); i != ts.end(); ++i) {
if ((playlist = (*i)->playlist()) == 0) {
continue;
@@ -3513,12 +3517,9 @@ Editor::cut_copy (CutCopyOp op)
/* we only want to cut regions if some are selected */
- if (!selection->regions.empty()) {
- rs = selection->regions;
- }
-
switch (current_mouse_mode()) {
case MouseObject:
+ rs = get_regions_from_selection ();
if (!rs.empty() || !selection->points.empty()) {
begin_reversible_command (opname + _(" objects"));
@@ -3676,23 +3677,15 @@ Editor::remove_selected_regions ()
continue;
}
- vector<boost::shared_ptr<Playlist> >::iterator i;
-
- //only prep history if this is a new playlist.
- for (i = playlists.begin(); i != playlists.end(); ++i) {
- if ((*i) == playlist) {
- break;
- }
- }
-
- if (i == playlists.end()) {
-
- playlist->clear_changes ();
- playlist->freeze ();
+ /* get_regions_from_selection_and_entered() guarantees that
+ the playlists involved are unique, so there is no need
+ to check here.
+ */
- playlists.push_back (playlist);
- }
+ playlists.push_back (playlist);
+ playlist->clear_changes ();
+ playlist->freeze ();
playlist->remove_region (*rl);
}
@@ -3868,27 +3861,24 @@ Editor::cut_copy_regions (CutCopyOp op, RegionSelection& rs)
void
Editor::cut_copy_ranges (CutCopyOp op)
{
- TrackViewList* ts;
- TrackViewList entered;
+ TrackViewList ts = selection->tracks.filter_to_unique_playlists ();
/* Sort the track selection now, so that it if is used, the playlists
selected by the calls below to cut_copy_clear are in the order that
their tracks appear in the editor. This makes things like paste
of ranges work properly.
*/
- sort_track_selection (&selection->tracks);
- if (selection->tracks.empty()) {
+ sort_track_selection (ts);
+
+ if (ts.empty()) {
if (!entered_track) {
return;
}
- entered.push_back (entered_track);
- ts = &entered;
- } else {
- ts = &selection->tracks;
- }
+ ts.push_back (entered_track);
+ }
- for (TrackSelection::iterator i = ts->begin(); i != ts->end(); ++i) {
+ for (TrackViewList::iterator i = ts.begin(); i != ts.end(); ++i) {
(*i)->cut_copy_clear (*selection, op);
}
}
@@ -3942,8 +3932,8 @@ Editor::paste_internal (framepos_t position, float times)
if (!selection->tracks.empty()) {
/* there are some selected tracks, so paste to them */
- sort_track_selection ();
- ts = selection->tracks;
+ ts = selection->tracks.filter_to_unique_playlists ();
+ sort_track_selection (ts);
} else if (_last_cut_copy_source_track) {
/* otherwise paste to the track that the cut/copy came from;
see discussion in mantis #3333.
@@ -4048,7 +4038,9 @@ Editor::duplicate_selection (float times)
ri = new_regions.begin();
- for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
+ TrackViewList ts = selection->tracks.filter_to_unique_playlists ();
+
+ for (TrackViewList::iterator i = ts.begin(); i != ts.end(); ++i) {
if ((playlist = (*i)->playlist()) == 0) {
continue;
}
@@ -4127,7 +4119,9 @@ Editor::nudge_track (bool use_edit, bool forwards)
begin_reversible_command (_("nudge track"));
- for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
+ TrackViewList ts = selection->tracks.filter_to_unique_playlists ();
+
+ for (TrackViewList::iterator i = ts.begin(); i != ts.end(); ++i) {
if ((playlist = (*i)->playlist()) == 0) {
continue;
@@ -5935,7 +5929,12 @@ Editor::tab_to_transient (bool forward)
if (!selection->tracks.empty()) {
- for (TrackSelection::iterator t = selection->tracks.begin(); t != selection->tracks.end(); ++t) {
+ /* don't waste time searching for transients in duplicate playlists.
+ */
+
+ TrackViewList ts = selection->tracks.filter_to_unique_playlists ();
+
+ for (TrackViewList::iterator t = ts.begin(); t != ts.end(); ++t) {
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (*t);
@@ -6212,23 +6211,34 @@ Editor::insert_time (
begin_reversible_command (_("insert time"));
- for (TrackSelection::iterator x = selection->tracks.begin(); x != selection->tracks.end(); ++x) {
+ TrackViewList ts = selection->tracks.filter_to_unique_playlists ();
+
+ for (TrackViewList::iterator x = ts.begin(); x != ts.end(); ++x) {
/* regions */
- vector<boost::shared_ptr<Playlist> > pl;
+ /* don't operate on any playlist more than once, which could
+ * happen if "all playlists" is enabled, but there is more
+ * than 1 track using playlists "from" a given track.
+ */
+
+ set<boost::shared_ptr<Playlist> > pl;
+
if (all_playlists) {
RouteTimeAxisView* rtav = dynamic_cast<RouteTimeAxisView*> (*x);
if (rtav) {
- pl = _session->playlists->playlists_for_track (rtav->track ());
+ vector<boost::shared_ptr<Playlist> > all = _session->playlists->playlists_for_track (rtav->track ());
+ for (vector<boost::shared_ptr<Playlist> >::iterator p = all.begin(); p != all.end(); ++p) {
+ pl.insert (*p);
+ }
}
} else {
if ((*x)->playlist ()) {
- pl.push_back ((*x)->playlist ());
+ pl.insert ((*x)->playlist ());
}
}
-
- for (vector<boost::shared_ptr<Playlist> >::iterator i = pl.begin(); i != pl.end(); ++i) {
+
+ for (set<boost::shared_ptr<Playlist> >::iterator i = pl.begin(); i != pl.end(); ++i) {
(*i)->clear_changes ();
(*i)->clear_owned_changes ();
diff --git a/gtk2_ardour/editor_selection.cc b/gtk2_ardour/editor_selection.cc
index 57db35ccf3..142204f9b4 100644
--- a/gtk2_ardour/editor_selection.cc
+++ b/gtk2_ardour/editor_selection.cc
@@ -401,6 +401,63 @@ Editor::mapover_tracks (sigc::slot<void, RouteTimeAxisView&, uint32_t> sl, TimeA
}
}
+/** Call a slot for a given `basis' track and also for any track that is in the same
+ * active route group with a particular set of properties.
+ *
+ * @param sl Slot to call.
+ * @param basis Basis track.
+ * @param prop Properties that active edit groups must share to be included in the map.
+ */
+
+void
+Editor::mapover_tracks_with_unique_playlists (sigc::slot<void, RouteTimeAxisView&, uint32_t> sl, TimeAxisView* basis, PBD::PropertyID prop) const
+{
+ RouteTimeAxisView* route_basis = dynamic_cast<RouteTimeAxisView*> (basis);
+ set<boost::shared_ptr<Playlist> > playlists;
+
+ if (route_basis == 0) {
+ return;
+ }
+
+ set<RouteTimeAxisView*> tracks;
+ tracks.insert (route_basis);
+
+ RouteGroup* group = route_basis->route()->route_group(); // could be null, not a problem
+
+ if (group && group->enabled_property(prop) && group->enabled_property (Properties::active.property_id) ) {
+
+ /* the basis is a member of an active route group, with the appropriate
+ properties; find other members */
+
+ for (TrackViewList::const_iterator i = track_views.begin(); i != track_views.end(); ++i) {
+ RouteTimeAxisView* v = dynamic_cast<RouteTimeAxisView*> (*i);
+
+ if (v && v->route()->route_group() == group) {
+
+ boost::shared_ptr<Track> t = v->track();
+ if (t) {
+ if (playlists.insert (t->playlist()).second) {
+ /* haven't seen this playlist yet */
+ tracks.insert (v);
+ }
+ } else {
+ /* not actually a "Track", but a timeaxis view that
+ we should mapover anyway.
+ */
+ tracks.insert (v);
+ }
+ }
+ }
+ }
+
+ /* call the slots */
+ uint32_t const sz = tracks.size ();
+
+ for (set<RouteTimeAxisView*>::iterator i = tracks.begin(); i != tracks.end(); ++i) {
+ sl (**i, sz);
+ }
+}
+
void
Editor::mapped_get_equivalent_regions (RouteTimeAxisView& tv, uint32_t, RegionView * basis, vector<RegionView*>* all_equivs) const
{
@@ -433,7 +490,7 @@ Editor::mapped_get_equivalent_regions (RouteTimeAxisView& tv, uint32_t, RegionVi
void
Editor::get_equivalent_regions (RegionView* basis, vector<RegionView*>& equivalent_regions, PBD::PropertyID property) const
{
- mapover_tracks (sigc::bind (sigc::mem_fun (*this, &Editor::mapped_get_equivalent_regions), basis, &equivalent_regions), &basis->get_time_axis_view(), property);
+ mapover_tracks_with_unique_playlists (sigc::bind (sigc::mem_fun (*this, &Editor::mapped_get_equivalent_regions), basis, &equivalent_regions), &basis->get_time_axis_view(), property);
/* add clicked regionview since we skipped all other regions in the same track as the one it was in */
@@ -449,7 +506,7 @@ Editor::get_equivalent_regions (RegionSelection & basis, PBD::PropertyID prop) c
vector<RegionView*> eq;
- mapover_tracks (
+ mapover_tracks_with_unique_playlists (
sigc::bind (sigc::mem_fun (*this, &Editor::mapped_get_equivalent_regions), *i, &eq),
&(*i)->get_time_axis_view(), prop);
diff --git a/gtk2_ardour/playlist_selector.cc b/gtk2_ardour/playlist_selector.cc
index e0c51082a1..f81e199d62 100644
--- a/gtk2_ardour/playlist_selector.cc
+++ b/gtk2_ardour/playlist_selector.cc
@@ -121,6 +121,14 @@ PlaylistSelector::show_for (RouteUI* ruix)
for (TrackPlaylistMap::iterator x = trpl_map.begin(); x != trpl_map.end(); ++x) {
boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (_session->route_by_id (x->first));
+
+ /* legacy sessions stored the diskstream ID as the original
+ * playlist owner. so try there instead.
+ */
+
+ if (tr == 0) {
+ tr = _session->track_by_diskstream_id (x->first);
+ }
if (tr == 0) {
continue;
@@ -222,8 +230,8 @@ PlaylistSelector::add_playlist_to_map (boost::shared_ptr<Playlist> pl)
TrackPlaylistMap::iterator x;
- if ((x = trpl_map.find (apl->get_orig_diskstream_id())) == trpl_map.end()) {
- x = trpl_map.insert (trpl_map.end(), make_pair (apl->get_orig_diskstream_id(), new list<boost::shared_ptr<Playlist> >));
+ if ((x = trpl_map.find (apl->get_orig_track_id())) == trpl_map.end()) {
+ x = trpl_map.insert (trpl_map.end(), make_pair (apl->get_orig_track_id(), new list<boost::shared_ptr<Playlist> >));
}
x->second->push_back (pl);
diff --git a/gtk2_ardour/time_axis_view.cc b/gtk2_ardour/time_axis_view.cc
index 56dd2b746d..e71bbe4778 100644
--- a/gtk2_ardour/time_axis_view.cc
+++ b/gtk2_ardour/time_axis_view.cc
@@ -1304,3 +1304,30 @@ TimeAxisView::reset_visual_state ()
set_height (preset_height (HeightNormal));
}
}
+
+TrackViewList
+TrackViewList::filter_to_unique_playlists ()
+{
+ std::set<boost::shared_ptr<ARDOUR::Playlist> > playlists;
+ TrackViewList ts;
+
+ for (iterator i = begin(); i != end(); ++i) {
+ RouteTimeAxisView* rtav = dynamic_cast<RouteTimeAxisView*> (*i);
+ if (!rtav) {
+ /* not a route: include it anyway */
+ ts.push_back (*i);
+ } else {
+ boost::shared_ptr<ARDOUR::Track> t = rtav->track();
+ if (t) {
+ if (playlists.insert (t->playlist()).second) {
+ /* playlist not seen yet */
+ ts.push_back (*i);
+ }
+ } else {
+ /* not a track: include it anyway */
+ ts.push_back (*i);
+ }
+ }
+ }
+ return ts;
+}
diff --git a/gtk2_ardour/track_view_list.h b/gtk2_ardour/track_view_list.h
index d7b5433edc..24f26465ef 100755
--- a/gtk2_ardour/track_view_list.h
+++ b/gtk2_ardour/track_view_list.h
@@ -21,6 +21,7 @@
#define __ardour_gtk_track_view_list_h__
#include <list>
+#include <set>
class TimeAxisView;
@@ -34,6 +35,8 @@ public:
virtual TrackViewList add (TrackViewList const &);
bool contains (TimeAxisView const *) const;
+
+ TrackViewList filter_to_unique_playlists ();
};
#endif