mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-08 07:45:00 +01:00
fix for most (all? we can dream ...) issues involved in #4399 (editing multiply-applies operations to playlists used more than once), and as a side-issue, fix playlist selection which broke when we hid Diskstreams inside Tracks by using orig_track_id() rather than orig_diskstream_id()
git-svn-id: svn://localhost/ardour2/branches/3.0@10968 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
6e211e27e2
commit
d23a6de077
19 changed files with 220 additions and 100 deletions
|
|
@ -4349,15 +4349,10 @@ struct EditorOrderTimeAxisSorter {
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
Editor::sort_track_selection (TrackViewList* sel)
|
Editor::sort_track_selection (TrackViewList& sel)
|
||||||
{
|
{
|
||||||
EditorOrderTimeAxisSorter cmp;
|
EditorOrderTimeAxisSorter cmp;
|
||||||
|
sel.sort (cmp);
|
||||||
if (sel) {
|
|
||||||
sel->sort (cmp);
|
|
||||||
} else {
|
|
||||||
selection->tracks.sort (cmp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
framepos_t
|
framepos_t
|
||||||
|
|
|
||||||
|
|
@ -632,11 +632,12 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
|
||||||
CrossfadeView* clicked_crossfadeview;
|
CrossfadeView* clicked_crossfadeview;
|
||||||
ControlPoint* clicked_control_point;
|
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;
|
void get_equivalent_regions (RegionView* rv, std::vector<RegionView*> &, PBD::PropertyID) const;
|
||||||
RegionSelection get_equivalent_regions (RegionSelection &, 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 (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 */
|
/* functions to be passed to mapover_tracks(), possibly with sigc::bind()-supplied arguments */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ Editor::show_editor_mixer (bool yn)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
sort_track_selection ();
|
sort_track_selection (selection->tracks);
|
||||||
|
|
||||||
for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
|
for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
|
||||||
RouteTimeAxisView* atv;
|
RouteTimeAxisView* atv;
|
||||||
|
|
|
||||||
|
|
@ -560,11 +560,11 @@ Editor::build_region_boundary_cache ()
|
||||||
|
|
||||||
TimeAxisView *ontrack = 0;
|
TimeAxisView *ontrack = 0;
|
||||||
TrackViewList tlist;
|
TrackViewList tlist;
|
||||||
|
|
||||||
if (!selection->tracks.empty()) {
|
if (!selection->tracks.empty()) {
|
||||||
tlist = selection->tracks;
|
tlist = selection->tracks.filter_to_unique_playlists ();
|
||||||
} else {
|
} else {
|
||||||
tlist = track_views;
|
tlist = track_views.filter_to_unique_playlists ();
|
||||||
}
|
}
|
||||||
|
|
||||||
while (pos < _session->current_end_frame() && !at_end) {
|
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 start = selection->time[clicked_selection].start;
|
||||||
framepos_t end = selection->time[clicked_selection].end;
|
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<Region> current;
|
||||||
boost::shared_ptr<Playlist> playlist;
|
boost::shared_ptr<Playlist> playlist;
|
||||||
framepos_t internal_start;
|
framepos_t internal_start;
|
||||||
|
|
@ -2437,7 +2438,7 @@ Editor::get_tracks_for_range_action () const
|
||||||
t = selection->tracks;
|
t = selection->tracks;
|
||||||
}
|
}
|
||||||
|
|
||||||
return t;
|
return t.filter_to_unique_playlists();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -2448,7 +2449,7 @@ Editor::separate_regions_between (const TimeSelection& ts)
|
||||||
RegionSelection new_selection;
|
RegionSelection new_selection;
|
||||||
|
|
||||||
TrackViewList tmptracks = get_tracks_for_range_action ();
|
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) {
|
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;
|
vector<boost::shared_ptr<Playlist> > playlists;
|
||||||
boost::shared_ptr<Playlist> playlist;
|
boost::shared_ptr<Playlist> playlist;
|
||||||
TrackViewList* ts;
|
TrackViewList ts;
|
||||||
|
|
||||||
if (selection->tracks.empty()) {
|
if (selection->tracks.empty()) {
|
||||||
ts = &track_views;
|
ts = track_views.filter_to_unique_playlists();
|
||||||
} else {
|
} else {
|
||||||
sort_track_selection ();
|
ts = selection->tracks.filter_to_unique_playlists ();
|
||||||
ts = &selection->tracks;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
RouteTimeAxisView* rtv;
|
||||||
|
|
||||||
|
|
@ -2825,7 +2827,9 @@ Editor::region_fill_selection ()
|
||||||
|
|
||||||
begin_reversible_command (Operations::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) {
|
if ((playlist = (*i)->playlist()) == 0) {
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -3513,12 +3517,9 @@ Editor::cut_copy (CutCopyOp op)
|
||||||
|
|
||||||
/* we only want to cut regions if some are selected */
|
/* we only want to cut regions if some are selected */
|
||||||
|
|
||||||
if (!selection->regions.empty()) {
|
|
||||||
rs = selection->regions;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (current_mouse_mode()) {
|
switch (current_mouse_mode()) {
|
||||||
case MouseObject:
|
case MouseObject:
|
||||||
|
rs = get_regions_from_selection ();
|
||||||
if (!rs.empty() || !selection->points.empty()) {
|
if (!rs.empty() || !selection->points.empty()) {
|
||||||
|
|
||||||
begin_reversible_command (opname + _(" objects"));
|
begin_reversible_command (opname + _(" objects"));
|
||||||
|
|
@ -3676,23 +3677,15 @@ Editor::remove_selected_regions ()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<boost::shared_ptr<Playlist> >::iterator i;
|
/* get_regions_from_selection_and_entered() guarantees that
|
||||||
|
the playlists involved are unique, so there is no need
|
||||||
|
to check here.
|
||||||
|
*/
|
||||||
|
|
||||||
//only prep history if this is a new playlist.
|
playlists.push_back (playlist);
|
||||||
for (i = playlists.begin(); i != playlists.end(); ++i) {
|
|
||||||
if ((*i) == playlist) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i == playlists.end()) {
|
|
||||||
|
|
||||||
playlist->clear_changes ();
|
|
||||||
playlist->freeze ();
|
|
||||||
|
|
||||||
playlists.push_back (playlist);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
playlist->clear_changes ();
|
||||||
|
playlist->freeze ();
|
||||||
playlist->remove_region (*rl);
|
playlist->remove_region (*rl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3868,27 +3861,24 @@ Editor::cut_copy_regions (CutCopyOp op, RegionSelection& rs)
|
||||||
void
|
void
|
||||||
Editor::cut_copy_ranges (CutCopyOp op)
|
Editor::cut_copy_ranges (CutCopyOp op)
|
||||||
{
|
{
|
||||||
TrackViewList* ts;
|
TrackViewList ts = selection->tracks.filter_to_unique_playlists ();
|
||||||
TrackViewList entered;
|
|
||||||
|
|
||||||
/* Sort the track selection now, so that it if is used, the 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
|
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
|
their tracks appear in the editor. This makes things like paste
|
||||||
of ranges work properly.
|
of ranges work properly.
|
||||||
*/
|
*/
|
||||||
sort_track_selection (&selection->tracks);
|
|
||||||
|
|
||||||
if (selection->tracks.empty()) {
|
sort_track_selection (ts);
|
||||||
|
|
||||||
|
if (ts.empty()) {
|
||||||
if (!entered_track) {
|
if (!entered_track) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
entered.push_back (entered_track);
|
ts.push_back (entered_track);
|
||||||
ts = &entered;
|
}
|
||||||
} else {
|
|
||||||
ts = &selection->tracks;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
(*i)->cut_copy_clear (*selection, op);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3942,8 +3932,8 @@ Editor::paste_internal (framepos_t position, float times)
|
||||||
|
|
||||||
if (!selection->tracks.empty()) {
|
if (!selection->tracks.empty()) {
|
||||||
/* there are some selected tracks, so paste to them */
|
/* there are some selected tracks, so paste to them */
|
||||||
sort_track_selection ();
|
ts = selection->tracks.filter_to_unique_playlists ();
|
||||||
ts = selection->tracks;
|
sort_track_selection (ts);
|
||||||
} else if (_last_cut_copy_source_track) {
|
} else if (_last_cut_copy_source_track) {
|
||||||
/* otherwise paste to the track that the cut/copy came from;
|
/* otherwise paste to the track that the cut/copy came from;
|
||||||
see discussion in mantis #3333.
|
see discussion in mantis #3333.
|
||||||
|
|
@ -4048,7 +4038,9 @@ Editor::duplicate_selection (float times)
|
||||||
|
|
||||||
ri = new_regions.begin();
|
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) {
|
if ((playlist = (*i)->playlist()) == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -4127,7 +4119,9 @@ Editor::nudge_track (bool use_edit, bool forwards)
|
||||||
|
|
||||||
begin_reversible_command (_("nudge track"));
|
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) {
|
if ((playlist = (*i)->playlist()) == 0) {
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -5935,7 +5929,12 @@ Editor::tab_to_transient (bool forward)
|
||||||
|
|
||||||
if (!selection->tracks.empty()) {
|
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);
|
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (*t);
|
||||||
|
|
||||||
|
|
@ -6212,23 +6211,34 @@ Editor::insert_time (
|
||||||
|
|
||||||
begin_reversible_command (_("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 */
|
/* 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) {
|
if (all_playlists) {
|
||||||
RouteTimeAxisView* rtav = dynamic_cast<RouteTimeAxisView*> (*x);
|
RouteTimeAxisView* rtav = dynamic_cast<RouteTimeAxisView*> (*x);
|
||||||
if (rtav) {
|
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 {
|
} else {
|
||||||
if ((*x)->playlist ()) {
|
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_changes ();
|
||||||
(*i)->clear_owned_changes ();
|
(*i)->clear_owned_changes ();
|
||||||
|
|
|
||||||
|
|
@ -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
|
void
|
||||||
Editor::mapped_get_equivalent_regions (RouteTimeAxisView& tv, uint32_t, RegionView * basis, vector<RegionView*>* all_equivs) const
|
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
|
void
|
||||||
Editor::get_equivalent_regions (RegionView* basis, vector<RegionView*>& equivalent_regions, PBD::PropertyID property) const
|
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 */
|
/* 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;
|
vector<RegionView*> eq;
|
||||||
|
|
||||||
mapover_tracks (
|
mapover_tracks_with_unique_playlists (
|
||||||
sigc::bind (sigc::mem_fun (*this, &Editor::mapped_get_equivalent_regions), *i, &eq),
|
sigc::bind (sigc::mem_fun (*this, &Editor::mapped_get_equivalent_regions), *i, &eq),
|
||||||
&(*i)->get_time_axis_view(), prop);
|
&(*i)->get_time_axis_view(), prop);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -121,6 +121,14 @@ PlaylistSelector::show_for (RouteUI* ruix)
|
||||||
for (TrackPlaylistMap::iterator x = trpl_map.begin(); x != trpl_map.end(); ++x) {
|
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));
|
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) {
|
if (tr == 0) {
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -222,8 +230,8 @@ PlaylistSelector::add_playlist_to_map (boost::shared_ptr<Playlist> pl)
|
||||||
|
|
||||||
TrackPlaylistMap::iterator x;
|
TrackPlaylistMap::iterator x;
|
||||||
|
|
||||||
if ((x = trpl_map.find (apl->get_orig_diskstream_id())) == trpl_map.end()) {
|
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_diskstream_id(), new list<boost::shared_ptr<Playlist> >));
|
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);
|
x->second->push_back (pl);
|
||||||
|
|
|
||||||
|
|
@ -1304,3 +1304,30 @@ TimeAxisView::reset_visual_state ()
|
||||||
set_height (preset_height (HeightNormal));
|
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;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
#define __ardour_gtk_track_view_list_h__
|
#define __ardour_gtk_track_view_list_h__
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
class TimeAxisView;
|
class TimeAxisView;
|
||||||
|
|
||||||
|
|
@ -34,6 +35,8 @@ public:
|
||||||
|
|
||||||
virtual TrackViewList add (TrackViewList const &);
|
virtual TrackViewList add (TrackViewList const &);
|
||||||
bool contains (TimeAxisView const *) const;
|
bool contains (TimeAxisView const *) const;
|
||||||
|
|
||||||
|
TrackViewList filter_to_unique_playlists ();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -201,9 +201,8 @@ public:
|
||||||
void raise_region_to_top (boost::shared_ptr<Region>);
|
void raise_region_to_top (boost::shared_ptr<Region>);
|
||||||
void lower_region_to_bottom (boost::shared_ptr<Region>);
|
void lower_region_to_bottom (boost::shared_ptr<Region>);
|
||||||
|
|
||||||
/* XXX: use of diskstream here is a little unfortunate */
|
const PBD::ID& get_orig_track_id () const { return _orig_track_id; }
|
||||||
const PBD::ID& get_orig_diskstream_id () const { return _orig_diskstream_id; }
|
void set_orig_track_id (const PBD::ID& did) { _orig_track_id = did; }
|
||||||
void set_orig_diskstream_id (const PBD::ID& did) { _orig_diskstream_id = did; }
|
|
||||||
|
|
||||||
/* destructive editing */
|
/* destructive editing */
|
||||||
|
|
||||||
|
|
@ -290,7 +289,7 @@ public:
|
||||||
bool in_partition;
|
bool in_partition;
|
||||||
bool _frozen;
|
bool _frozen;
|
||||||
uint32_t subcnt;
|
uint32_t subcnt;
|
||||||
PBD::ID _orig_diskstream_id;
|
PBD::ID _orig_track_id;
|
||||||
uint64_t layer_op_counter;
|
uint64_t layer_op_counter;
|
||||||
framecnt_t freeze_length;
|
framecnt_t freeze_length;
|
||||||
bool auto_partition;
|
bool auto_partition;
|
||||||
|
|
|
||||||
|
|
@ -243,6 +243,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
||||||
boost::shared_ptr<Route> route_by_name (std::string);
|
boost::shared_ptr<Route> route_by_name (std::string);
|
||||||
boost::shared_ptr<Route> route_by_id (PBD::ID);
|
boost::shared_ptr<Route> route_by_id (PBD::ID);
|
||||||
boost::shared_ptr<Route> route_by_remote_id (uint32_t id);
|
boost::shared_ptr<Route> route_by_remote_id (uint32_t id);
|
||||||
|
boost::shared_ptr<Track> track_by_diskstream_id (PBD::ID);
|
||||||
void routes_using_input_from (const std::string& str, RouteList& rl);
|
void routes_using_input_from (const std::string& str, RouteList& rl);
|
||||||
|
|
||||||
bool route_name_unique (std::string) const;
|
bool route_name_unique (std::string) const;
|
||||||
|
|
|
||||||
|
|
@ -98,8 +98,7 @@ class Track : public Route, public PublicDiskstream
|
||||||
bool record_enabled() const;
|
bool record_enabled() const;
|
||||||
void set_record_enabled (bool yn, void *src);
|
void set_record_enabled (bool yn, void *src);
|
||||||
|
|
||||||
/* XXX: unfortunate that this is exposed */
|
bool using_diskstream_id (PBD::ID) const;
|
||||||
PBD::ID const & diskstream_id () const;
|
|
||||||
|
|
||||||
void set_block_size (pframes_t);
|
void set_block_size (pframes_t);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -281,7 +281,6 @@ AudioDiskstream::use_new_playlist ()
|
||||||
|
|
||||||
if ((playlist = boost::dynamic_pointer_cast<AudioPlaylist> (PlaylistFactory::create (DataType::AUDIO, _session, newname, hidden()))) != 0) {
|
if ((playlist = boost::dynamic_pointer_cast<AudioPlaylist> (PlaylistFactory::create (DataType::AUDIO, _session, newname, hidden()))) != 0) {
|
||||||
|
|
||||||
playlist->set_orig_diskstream_id (id());
|
|
||||||
return use_playlist (playlist);
|
return use_playlist (playlist);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -309,7 +308,6 @@ AudioDiskstream::use_copy_playlist ()
|
||||||
newname = Playlist::bump_name (_playlist->name(), _session);
|
newname = Playlist::bump_name (_playlist->name(), _session);
|
||||||
|
|
||||||
if ((playlist = boost::dynamic_pointer_cast<AudioPlaylist>(PlaylistFactory::create (audio_playlist(), newname))) != 0) {
|
if ((playlist = boost::dynamic_pointer_cast<AudioPlaylist>(PlaylistFactory::create (audio_playlist(), newname))) != 0) {
|
||||||
playlist->set_orig_diskstream_id (id());
|
|
||||||
return use_playlist (playlist);
|
return use_playlist (playlist);
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
||||||
|
|
@ -643,7 +643,7 @@ AudioTrack::freeze_me (InterThreadInfo& itt)
|
||||||
|
|
||||||
boost::shared_ptr<Region> region (RegionFactory::create (srcs, plist, false));
|
boost::shared_ptr<Region> region (RegionFactory::create (srcs, plist, false));
|
||||||
|
|
||||||
new_playlist->set_orig_diskstream_id (_diskstream->id());
|
new_playlist->set_orig_track_id (id());
|
||||||
new_playlist->add_region (region, _session.current_start_frame());
|
new_playlist->add_region (region, _session.current_start_frame());
|
||||||
new_playlist->set_frozen (true);
|
new_playlist->set_frozen (true);
|
||||||
region->set_locked (true);
|
region->set_locked (true);
|
||||||
|
|
|
||||||
|
|
@ -504,16 +504,8 @@ Diskstream::set_state (const XMLNode& node, int /*version*/)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
if (find_and_use_playlist (prop->value())) {
|
||||||
bool had_playlist = (_playlist != 0);
|
return -1;
|
||||||
|
|
||||||
if (find_and_use_playlist (prop->value())) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!had_playlist) {
|
|
||||||
_playlist->set_orig_diskstream_id (id());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((prop = node.property ("speed")) != 0) {
|
if ((prop = node.property ("speed")) != 0) {
|
||||||
|
|
|
||||||
|
|
@ -252,7 +252,6 @@ MidiDiskstream::use_new_playlist ()
|
||||||
if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist> (PlaylistFactory::create (
|
if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist> (PlaylistFactory::create (
|
||||||
DataType::MIDI, _session, newname, hidden()))) != 0) {
|
DataType::MIDI, _session, newname, hidden()))) != 0) {
|
||||||
|
|
||||||
playlist->set_orig_diskstream_id (id());
|
|
||||||
return use_playlist (playlist);
|
return use_playlist (playlist);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -280,7 +279,6 @@ MidiDiskstream::use_copy_playlist ()
|
||||||
newname = Playlist::bump_name (_playlist->name(), _session);
|
newname = Playlist::bump_name (_playlist->name(), _session);
|
||||||
|
|
||||||
if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist>(PlaylistFactory::create (midi_playlist(), newname))) != 0) {
|
if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist>(PlaylistFactory::create (midi_playlist(), newname))) != 0) {
|
||||||
playlist->set_orig_diskstream_id (id());
|
|
||||||
return use_playlist (playlist);
|
return use_playlist (playlist);
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
||||||
|
|
@ -161,7 +161,7 @@ Playlist::Playlist (boost::shared_ptr<const Playlist> other, string namestr, boo
|
||||||
: SessionObject(other->_session, namestr)
|
: SessionObject(other->_session, namestr)
|
||||||
, regions (*this)
|
, regions (*this)
|
||||||
, _type(other->_type)
|
, _type(other->_type)
|
||||||
, _orig_diskstream_id (other->_orig_diskstream_id)
|
, _orig_track_id (other->_orig_track_id)
|
||||||
{
|
{
|
||||||
init (hide);
|
init (hide);
|
||||||
|
|
||||||
|
|
@ -195,7 +195,7 @@ Playlist::Playlist (boost::shared_ptr<const Playlist> other, framepos_t start, f
|
||||||
: SessionObject(other->_session, str)
|
: SessionObject(other->_session, str)
|
||||||
, regions (*this)
|
, regions (*this)
|
||||||
, _type(other->_type)
|
, _type(other->_type)
|
||||||
, _orig_diskstream_id (other->_orig_diskstream_id)
|
, _orig_track_id (other->_orig_track_id)
|
||||||
{
|
{
|
||||||
RegionLock rlock2 (const_cast<Playlist*> (other.get()));
|
RegionLock rlock2 (const_cast<Playlist*> (other.get()));
|
||||||
|
|
||||||
|
|
@ -2221,7 +2221,10 @@ Playlist::flush_notifications (bool from_undo)
|
||||||
_name = prop->value();
|
_name = prop->value();
|
||||||
_set_sort_id ();
|
_set_sort_id ();
|
||||||
} else if (prop->name() == X_("orig-diskstream-id")) {
|
} else if (prop->name() == X_("orig-diskstream-id")) {
|
||||||
_orig_diskstream_id = prop->value ();
|
/* XXX legacy session: fix up later */
|
||||||
|
_orig_track_id = prop->value ();
|
||||||
|
} else if (prop->name() == X_("orig-track-id")) {
|
||||||
|
_orig_track_id = prop->value ();
|
||||||
} else if (prop->name() == X_("frozen")) {
|
} else if (prop->name() == X_("frozen")) {
|
||||||
_frozen = string_is_affirmative (prop->value());
|
_frozen = string_is_affirmative (prop->value());
|
||||||
} else if (prop->name() == X_("combine-ops")) {
|
} else if (prop->name() == X_("combine-ops")) {
|
||||||
|
|
@ -2318,8 +2321,8 @@ Playlist::state (bool full_state)
|
||||||
node->add_property (X_("name"), _name);
|
node->add_property (X_("name"), _name);
|
||||||
node->add_property (X_("type"), _type.to_string());
|
node->add_property (X_("type"), _type.to_string());
|
||||||
|
|
||||||
_orig_diskstream_id.print (buf, sizeof (buf));
|
_orig_track_id.print (buf, sizeof (buf));
|
||||||
node->add_property (X_("orig-diskstream-id"), buf);
|
node->add_property (X_("orig-track-id"), buf);
|
||||||
node->add_property (X_("frozen"), _frozen ? "yes" : "no");
|
node->add_property (X_("frozen"), _frozen ? "yes" : "no");
|
||||||
|
|
||||||
if (full_state) {
|
if (full_state) {
|
||||||
|
|
|
||||||
|
|
@ -2603,6 +2603,21 @@ Session::route_by_id (PBD::ID id)
|
||||||
return boost::shared_ptr<Route> ((Route*) 0);
|
return boost::shared_ptr<Route> ((Route*) 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boost::shared_ptr<Track>
|
||||||
|
Session::track_by_diskstream_id (PBD::ID id)
|
||||||
|
{
|
||||||
|
boost::shared_ptr<RouteList> r = routes.reader ();
|
||||||
|
|
||||||
|
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
|
||||||
|
boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (*i);
|
||||||
|
if (t && t->using_diskstream_id (id)) {
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return boost::shared_ptr<Track> ();
|
||||||
|
}
|
||||||
|
|
||||||
boost::shared_ptr<Route>
|
boost::shared_ptr<Route>
|
||||||
Session::route_by_remote_id (uint32_t id)
|
Session::route_by_remote_id (uint32_t id)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -207,13 +207,13 @@ SessionPlaylists::unassigned (std::list<boost::shared_ptr<Playlist> > & list)
|
||||||
Glib::Mutex::Lock lm (lock);
|
Glib::Mutex::Lock lm (lock);
|
||||||
|
|
||||||
for (List::iterator i = playlists.begin(); i != playlists.end(); ++i) {
|
for (List::iterator i = playlists.begin(); i != playlists.end(); ++i) {
|
||||||
if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
|
if (!(*i)->get_orig_track_id().to_s().compare ("0")) {
|
||||||
list.push_back (*i);
|
list.push_back (*i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (List::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
|
for (List::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
|
||||||
if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
|
if (!(*i)->get_orig_track_id().to_s().compare ("0")) {
|
||||||
list.push_back (*i);
|
list.push_back (*i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -462,7 +462,7 @@ SessionPlaylists::playlists_for_track (boost::shared_ptr<Track> tr) const
|
||||||
vector<boost::shared_ptr<Playlist> > pl_tr;
|
vector<boost::shared_ptr<Playlist> > pl_tr;
|
||||||
|
|
||||||
for (vector<boost::shared_ptr<Playlist> >::iterator i = pl.begin(); i != pl.end(); ++i) {
|
for (vector<boost::shared_ptr<Playlist> >::iterator i = pl.begin(); i != pl.end(); ++i) {
|
||||||
if (((*i)->get_orig_diskstream_id() == tr->diskstream_id()) || (tr->playlist()->id() == (*i)->id())) {
|
if (((*i)->get_orig_track_id() == tr->id()) || (tr->playlist()->id() == (*i)->id())) {
|
||||||
pl_tr.push_back (*i);
|
pl_tr.push_back (*i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,8 @@ Track::set_state (const XMLNode& node, int version)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_diskstream->playlist()->set_orig_track_id (id());
|
||||||
|
|
||||||
/* set rec-enable control *AFTER* setting up diskstream, because it may
|
/* set rec-enable control *AFTER* setting up diskstream, because it may
|
||||||
want to operate on the diskstream as it sets its own state
|
want to operate on the diskstream as it sets its own state
|
||||||
*/
|
*/
|
||||||
|
|
@ -694,13 +696,25 @@ Track::use_playlist (boost::shared_ptr<Playlist> p)
|
||||||
int
|
int
|
||||||
Track::use_copy_playlist ()
|
Track::use_copy_playlist ()
|
||||||
{
|
{
|
||||||
return _diskstream->use_copy_playlist ();
|
int ret = _diskstream->use_copy_playlist ();
|
||||||
|
|
||||||
|
if (ret == 0) {
|
||||||
|
_diskstream->playlist()->set_orig_track_id (id());
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
Track::use_new_playlist ()
|
Track::use_new_playlist ()
|
||||||
{
|
{
|
||||||
return _diskstream->use_new_playlist ();
|
int ret = _diskstream->use_new_playlist ();
|
||||||
|
|
||||||
|
if (ret == 0) {
|
||||||
|
_diskstream->playlist()->set_orig_track_id (id());
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -715,10 +729,10 @@ Track::set_align_choice (AlignChoice s, bool force)
|
||||||
_diskstream->set_align_choice (s, force);
|
_diskstream->set_align_choice (s, force);
|
||||||
}
|
}
|
||||||
|
|
||||||
PBD::ID const &
|
bool
|
||||||
Track::diskstream_id () const
|
Track::using_diskstream_id (PBD::ID id) const
|
||||||
{
|
{
|
||||||
return _diskstream->id ();
|
return (id == _diskstream->id ());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue