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:
Paul Davis 2011-12-10 19:20:15 +00:00
parent 6e211e27e2
commit d23a6de077
19 changed files with 220 additions and 100 deletions

View file

@ -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

View file

@ -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 */

View file

@ -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;

View file

@ -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 ();

View file

@ -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);

View file

@ -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);

View file

@ -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;
}

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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) {

View file

@ -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;

View file

@ -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) {

View file

@ -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)
{ {

View file

@ -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);
} }
} }

View file

@ -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