summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2006-10-19 22:02:30 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2006-10-19 22:02:30 +0000
commit2592a320d42dd4a157ee16101c042d875d3142be (patch)
tree0409a06f1ef030dc9339c5c17bd3ff1854125256
parent0c31e4c4f3d0bfe37d26a793c934f1b436f8fa0f (diff)
major changes to Region, AudioRegion, Playlist, AudioPlaylist and Crossfade state management, to try to fix undo/redo. Not finished, butthe speedups etc. are in place
git-svn-id: svn://localhost/ardour2/trunk@993 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--gtk2_ardour/audio_streamview.cc8
-rw-r--r--gtk2_ardour/editor.cc9
-rw-r--r--gtk2_ardour/editor_mouse.cc2
-rw-r--r--gtk2_ardour/editor_ops.cc31
-rw-r--r--gtk2_ardour/route_time_axis.cc3
-rw-r--r--gtk2_ardour/route_time_axis.h1
-rw-r--r--gtk2_ardour/streamview.cc15
-rw-r--r--gtk2_ardour/streamview.h1
-rw-r--r--libs/ardour/ardour/audioplaylist.h31
-rw-r--r--libs/ardour/ardour/audioregion.h20
-rw-r--r--libs/ardour/ardour/crossfade.h24
-rw-r--r--libs/ardour/ardour/playlist.h18
-rw-r--r--libs/ardour/ardour/region.h29
-rw-r--r--libs/ardour/audio_playlist.cc252
-rw-r--r--libs/ardour/audioregion.cc171
-rw-r--r--libs/ardour/auditioner.cc6
-rw-r--r--libs/ardour/crossfade.cc139
-rw-r--r--libs/ardour/diskstream.cc1
-rw-r--r--libs/ardour/playlist.cc136
-rw-r--r--libs/ardour/region.cc268
-rw-r--r--libs/ardour/session_command.cc92
-rw-r--r--libs/ardour/session_state.cc78
22 files changed, 391 insertions, 944 deletions
diff --git a/gtk2_ardour/audio_streamview.cc b/gtk2_ardour/audio_streamview.cc
index 0a74d89d35..3cca792523 100644
--- a/gtk2_ardour/audio_streamview.cc
+++ b/gtk2_ardour/audio_streamview.cc
@@ -254,7 +254,7 @@ AudioStreamView::add_crossfade (Crossfade *crossfade)
/* first see if we already have a CrossfadeView for this Crossfade */
for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
- if (&(*i)->crossfade == crossfade) {
+ if ((*i)->crossfade == *crossfade) {
if (!crossfades_visible) {
(*i)->hide();
} else {
@@ -313,7 +313,6 @@ AudioStreamView::redisplay_diskstream ()
list<RegionView *>::iterator i, tmp;
list<CrossfadeView*>::iterator xi, tmpx;
-
for (i = region_views.begin(); i != region_views.end(); ++i) {
(*i)->set_valid (false);
}
@@ -327,6 +326,7 @@ AudioStreamView::redisplay_diskstream ()
if (_trackview.is_audio_track()) {
_trackview.get_diskstream()->playlist()->foreach_region (static_cast<StreamView*>(this), &StreamView::add_region_view);
+
AudioPlaylist* apl = dynamic_cast<AudioPlaylist*>(_trackview.get_diskstream()->playlist());
if (apl)
apl->foreach_crossfade (this, &AudioStreamView::add_crossfade);
@@ -358,7 +358,9 @@ AudioStreamView::redisplay_diskstream ()
/* now fix layering */
- playlist_modified ();
+ for (RegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) {
+ region_layered (*i);
+ }
}
void
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc
index 67f3acccf9..99e1f5bb1e 100644
--- a/gtk2_ardour/editor.cc
+++ b/gtk2_ardour/editor.cc
@@ -3074,9 +3074,6 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op,
switch (clicked_regionview->region()->coverage (first_frame, last_frame)) {
case OverlapNone:
- cerr << "no overlap, first = " << first_frame << " last = " << last_frame << " region = "
- << clicked_regionview->region()->first_frame() << " .. " << clicked_regionview->region()->last_frame() << endl;
-
if (last_frame < clicked_regionview->region()->first_frame()) {
first_frame = last_frame;
last_frame = clicked_regionview->region()->last_frame();
@@ -3087,9 +3084,6 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op,
break;
case OverlapExternal:
- cerr << "external overlap, first = " << first_frame << " last = " << last_frame << " region = "
- << clicked_regionview->region()->first_frame() << " .. " << clicked_regionview->region()->last_frame() << endl;
-
if (last_frame < clicked_regionview->region()->first_frame()) {
first_frame = last_frame;
last_frame = clicked_regionview->region()->last_frame();
@@ -3100,9 +3094,6 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op,
break;
case OverlapInternal:
- cerr << "internal overlap, first = " << first_frame << " last = " << last_frame << " region = "
- << clicked_regionview->region()->first_frame() << " .. " << clicked_regionview->region()->last_frame() << endl;
-
if (last_frame < clicked_regionview->region()->first_frame()) {
first_frame = last_frame;
last_frame = clicked_regionview->region()->last_frame();
diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc
index 0ee110bf30..45252e052c 100644
--- a/gtk2_ardour/editor_mouse.cc
+++ b/gtk2_ardour/editor_mouse.cc
@@ -4837,7 +4837,7 @@ Editor::mouse_brush_insert_region (RegionView* rv, nframes_t pos)
// playlist is frozen, so we have to update manually
- playlist->StateChanged (Change (~0)); /* EMIT SIGNAL */
+ playlist->Modified(); /* EMIT SIGNAL */
}
gint
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index 0a3104d36a..280804c94f 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -2910,14 +2910,26 @@ Editor::cut_copy_points (CutCopyOp op)
}
}
+struct PlaylistState {
+ Playlist* playlist;
+ XMLNode* before;
+};
+
+struct lt_playlist {
+ bool operator () (const PlaylistState& a, const PlaylistState& b) {
+ return a.playlist < b.playlist;
+ }
+};
+
void
Editor::cut_copy_regions (CutCopyOp op)
{
typedef std::map<AudioPlaylist*,AudioPlaylist*> PlaylistMapping;
PlaylistMapping pmap;
nframes_t first_position = max_frames;
- set<Playlist*> freezelist;
- pair<set<Playlist*>::iterator,bool> insert_result;
+
+ set<PlaylistState, lt_playlist> freezelist;
+ pair<set<PlaylistState, lt_playlist>::iterator,bool> insert_result;
for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) {
first_position = min ((*x)->region()->position(), first_position);
@@ -2925,10 +2937,15 @@ Editor::cut_copy_regions (CutCopyOp op)
if (op == Cut || op == Clear) {
AudioPlaylist *pl = dynamic_cast<AudioPlaylist*>((*x)->region()->playlist());
if (pl) {
- insert_result = freezelist.insert (pl);
+
+ PlaylistState before;
+ before.playlist = pl;
+ before.before = &pl->get_state();
+
+ insert_result = freezelist.insert (before);
+
if (insert_result.second) {
pl->freeze ();
- session->add_command (new MementoCommand<Playlist>(*pl, &pl->get_state(), 0));
}
}
}
@@ -2990,9 +3007,9 @@ Editor::cut_copy_regions (CutCopyOp op)
cut_buffer->set (foo);
}
- for (set<Playlist*>::iterator pl = freezelist.begin(); pl != freezelist.end(); ++pl) {
- (*pl)->thaw ();
- session->add_command (new MementoCommand<Playlist>(*(*pl), 0, &(*pl)->get_state()));
+ for (set<PlaylistState, lt_playlist>::iterator pl = freezelist.begin(); pl != freezelist.end(); ++pl) {
+ (*pl).playlist->thaw ();
+ session->add_command (new MementoCommand<Playlist>(*(*pl).playlist, (*pl).before, &(*pl).playlist->get_state()));
}
}
diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc
index e0d976c233..eb96791d28 100644
--- a/gtk2_ardour/route_time_axis.cc
+++ b/gtk2_ardour/route_time_axis.cc
@@ -244,9 +244,6 @@ RouteTimeAxisView::set_playlist (Playlist *newplaylist)
assert(pl);
modified_connection.disconnect ();
- state_changed_connection.disconnect ();
-
- state_changed_connection = pl->StateChanged.connect (mem_fun(*this, &RouteTimeAxisView::playlist_state_changed));
modified_connection = pl->Modified.connect (mem_fun(*this, &RouteTimeAxisView::playlist_modified));
}
diff --git a/gtk2_ardour/route_time_axis.h b/gtk2_ardour/route_time_axis.h
index 65d82506b8..1eb0cea00b 100644
--- a/gtk2_ardour/route_time_axis.h
+++ b/gtk2_ardour/route_time_axis.h
@@ -248,7 +248,6 @@ protected:
vector<RedirectAutomationLine*> redirect_automation_curves;
sigc::connection modified_connection;
- sigc::connection state_changed_connection;
};
#endif /* __ardour_route_time_axis_h__ */
diff --git a/gtk2_ardour/streamview.cc b/gtk2_ardour/streamview.cc
index 10d409a9b0..75fb003d77 100644
--- a/gtk2_ardour/streamview.cc
+++ b/gtk2_ardour/streamview.cc
@@ -206,9 +206,7 @@ StreamView::playlist_modified ()
{
ENSURE_GUI_THREAD (mem_fun (*this, &StreamView::playlist_modified));
- for (RegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) {
- region_layered (*i);
- }
+ redisplay_diskstream ();
}
void
@@ -231,21 +229,10 @@ StreamView::playlist_changed (boost::shared_ptr<Diskstream> ds)
/* catch changes */
- playlist_connections.push_back (ds->playlist()->RegionAdded.connect (mem_fun (*this, &StreamView::add_region_view)));
- playlist_connections.push_back (ds->playlist()->RegionRemoved.connect (mem_fun (*this, &StreamView::remove_region_view)));
- playlist_connections.push_back (ds->playlist()->StateChanged.connect (mem_fun (*this, &StreamView::playlist_state_changed)));
playlist_connections.push_back (ds->playlist()->Modified.connect (mem_fun (*this, &StreamView::playlist_modified)));
}
void
-StreamView::playlist_state_changed (Change ignored)
-{
- ENSURE_GUI_THREAD (bind (mem_fun (*this, &StreamView::playlist_state_changed), ignored));
-
- redisplay_diskstream ();
-}
-
-void
StreamView::diskstream_changed ()
{
Track *t;
diff --git a/gtk2_ardour/streamview.h b/gtk2_ardour/streamview.h
index cc5f9cb414..657bfa9044 100644
--- a/gtk2_ardour/streamview.h
+++ b/gtk2_ardour/streamview.h
@@ -116,7 +116,6 @@ protected:
virtual void redisplay_diskstream () = 0;
void diskstream_changed ();
- void playlist_state_changed (ARDOUR::Change);
virtual void playlist_changed (boost::shared_ptr<ARDOUR::Diskstream>);
virtual void playlist_modified ();
diff --git a/libs/ardour/ardour/audioplaylist.h b/libs/ardour/ardour/audioplaylist.h
index 341b08930c..6d67e0f793 100644
--- a/libs/ardour/ardour/audioplaylist.h
+++ b/libs/ardour/ardour/audioplaylist.h
@@ -38,19 +38,6 @@ class AudioPlaylist : public ARDOUR::Playlist
{
public:
typedef std::list<Crossfade*> Crossfades;
-
- private:
-
- struct State : public ARDOUR::StateManager::State {
- RegionList regions;
- std::list<UndoAction> region_states;
-
- Crossfades crossfades;
- std::list<UndoAction> crossfade_states;
-
- State (std::string why) : ARDOUR::StateManager::State (why) {}
- ~State ();
- };
public:
AudioPlaylist (Session&, const XMLNode&, bool hidden = false);
@@ -58,35 +45,21 @@ class AudioPlaylist : public ARDOUR::Playlist
AudioPlaylist (const AudioPlaylist&, string name, bool hidden = false);
AudioPlaylist (const AudioPlaylist&, nframes_t start, nframes_t cnt, string name, bool hidden = false);
- void clear (bool with_save = true);
+ void clear ();
nframes_t read (Sample *dst, Sample *mixdown, float *gain_buffer, nframes_t start, nframes_t cnt, uint32_t chan_n=0);
int set_state (const XMLNode&);
- UndoAction get_memento() const;
sigc::signal<void,Crossfade *> NewCrossfade;
template<class T> void foreach_crossfade (T *t, void (T::*func)(Crossfade *));
void crossfades_at (nframes_t frame, Crossfades&);
- template<class T> void apply_to_history (T& obj, void (T::*method)(const ARDOUR::StateManager::StateMap&, state_id_t)) {
- RegionLock rlock (this);
- (obj.*method) (states, _current_state_id);
- }
-
bool destroy_region (boost::shared_ptr<Region>);
- void drop_all_states ();
-
protected:
- /* state management */
-
- StateManager::State* state_factory (std::string) const;
- Change restore_state (StateManager::State&);
- void send_state_change (Change);
-
/* playlist "callbacks" */
void notify_crossfade_added (Crossfade *);
void flush_notifications ();
@@ -101,7 +74,7 @@ class AudioPlaylist : public ARDOUR::Playlist
~AudioPlaylist (); /* public should use unref() */
private:
- Crossfades _crossfades;
+ Crossfades _crossfades; /* xfades currently in use */
Crossfades _pending_xfade_adds;
void crossfade_invalidated (Crossfade*);
diff --git a/libs/ardour/ardour/audioregion.h b/libs/ardour/ardour/audioregion.h
index c9cb2b8152..4be5d27a6b 100644
--- a/libs/ardour/ardour/audioregion.h
+++ b/libs/ardour/ardour/audioregion.h
@@ -42,18 +42,6 @@ class Session;
class AudioFilter;
class AudioSource;
-struct AudioRegionState : public RegionState
-{
- AudioRegionState (std::string why);
-
- Curve _fade_in;
- Curve _fade_out;
- Curve _envelope;
- gain_t _scale_amplitude;
- uint32_t _fade_in_disabled;
- uint32_t _fade_out_disabled;
-};
-
class AudioRegion : public Region
{
public:
@@ -131,8 +119,6 @@ class AudioRegion : public Region
int separate_by_channel (ARDOUR::Session&, vector<AudioRegion*>&) const;
- UndoAction get_memento() const;
-
/* filter */
int apply (AudioFilter&);
@@ -167,9 +153,6 @@ class AudioRegion : public Region
void set_default_fade_out ();
void set_default_envelope ();
- StateManager::State* state_factory (std::string why) const;
- Change restore_state (StateManager::State&);
-
void recompute_gain_at_end ();
void recompute_gain_at_start ();
@@ -204,6 +187,9 @@ class AudioRegion : public Region
gain_t _scale_amplitude;
uint32_t _fade_in_disabled;
uint32_t _fade_out_disabled;
+
+ protected:
+ int set_live_state (const XMLNode&, Change&, bool send);
};
} /* namespace ARDOUR */
diff --git a/libs/ardour/ardour/crossfade.h b/libs/ardour/ardour/crossfade.h
index 7fd7323b36..d1b2e8f1e1 100644
--- a/libs/ardour/ardour/crossfade.h
+++ b/libs/ardour/ardour/crossfade.h
@@ -33,7 +33,6 @@
#include <ardour/ardour.h>
#include <ardour/curve.h>
#include <ardour/audioregion.h>
-#include <ardour/state_manager.h>
#include <ardour/crossfade_compare.h>
namespace ARDOUR {
@@ -41,19 +40,7 @@ namespace ARDOUR {
class AudioRegion;
class Playlist;
-struct CrossfadeState : public StateManager::State {
- CrossfadeState (std::string reason) : StateManager::State (reason) {}
-
- UndoAction fade_in_memento;
- UndoAction fade_out_memento;
- nframes_t position;
- nframes_t length;
- AnchorPoint anchor_point;
- bool follow_overlap;
- bool active;
-};
-
-class Crossfade : public PBD::StatefulDestructible, public StateManager
+class Crossfade : public PBD::StatefulDestructible
{
public:
@@ -122,6 +109,7 @@ class Crossfade : public PBD::StatefulDestructible, public StateManager
nframes_t position() const { return _position; }
sigc::signal<void,Crossfade*> Invalidated;
+ sigc::signal<void,Change> StateChanged;
bool covers (nframes_t frame) const {
return _position <= frame && frame < _position + _length;
@@ -129,8 +117,6 @@ class Crossfade : public PBD::StatefulDestructible, public StateManager
OverlapType coverage (nframes_t start, nframes_t end) const;
- UndoAction get_memento() const;
-
static void set_buffer_size (nframes_t);
bool active () const { return _active; }
@@ -172,15 +158,11 @@ class Crossfade : public PBD::StatefulDestructible, public StateManager
static Sample* crossfade_buffer_out;
static Sample* crossfade_buffer_in;
- void initialize (bool savestate=true);
+ void initialize ();
int compute (boost::shared_ptr<ARDOUR::AudioRegion>, boost::shared_ptr<ARDOUR::AudioRegion>, CrossfadeModel);
bool update (bool force);
- StateManager::State* state_factory (std::string why) const;
- Change restore_state (StateManager::State&);
-
void member_changed (ARDOUR::Change);
-
};
diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h
index 4c2e75c6c9..8f08c58466 100644
--- a/libs/ardour/ardour/playlist.h
+++ b/libs/ardour/ardour/playlist.h
@@ -40,14 +40,13 @@
#include <ardour/ardour.h>
#include <ardour/crossfade_compare.h>
#include <ardour/location.h>
-#include <ardour/state_manager.h>
namespace ARDOUR {
class Session;
class Region;
-class Playlist : public StateManager, public PBD::StatefulDestructible {
+class Playlist : public PBD::StatefulDestructible {
public:
typedef list<boost::shared_ptr<Region> > RegionList;
@@ -56,9 +55,8 @@ class Playlist : public StateManager, public PBD::StatefulDestructible {
Playlist (const Playlist&, string name, bool hidden = false);
Playlist (const Playlist&, nframes_t start, nframes_t cnt, string name, bool hidden = false);
- virtual void clear (bool with_save = true);
+ virtual void clear ();
virtual void dump () const;
- virtual UndoAction get_memento() const = 0;
void ref();
void unref();
@@ -80,7 +78,7 @@ class Playlist : public StateManager, public PBD::StatefulDestructible {
/* Editing operations */
- void add_region (boost::shared_ptr<Region>, nframes_t position, float times = 1, bool with_save = true);
+ void add_region (boost::shared_ptr<Region>, nframes_t position, float times = 1);
void remove_region (boost::shared_ptr<Region>);
void get_equivalent_regions (boost::shared_ptr<Region>, std::vector<boost::shared_ptr<Region> >&);
void get_region_list_equivalent_regions (boost::shared_ptr<Region>, std::vector<boost::shared_ptr<Region> >&);
@@ -111,8 +109,6 @@ class Playlist : public StateManager, public PBD::StatefulDestructible {
int set_state (const XMLNode&);
XMLNode& get_template ();
- sigc::signal<void,boost::shared_ptr<Region> > RegionAdded;
- sigc::signal<void,boost::shared_ptr<Region> > RegionRemoved;
sigc::signal<void,Playlist*,bool> InUse;
sigc::signal<void> Modified;
sigc::signal<void> NameChanged;
@@ -169,13 +165,12 @@ class Playlist : public StateManager, public PBD::StatefulDestructible {
friend class RegionLock;
RegionList regions; /* the current list of regions in the playlist */
+ std::set<boost::shared_ptr<Region> > all_regions; /* all regions ever added to this playlist */
string _name;
Session& _session;
mutable gint block_notifications;
mutable gint ignore_state_changes;
mutable Glib::Mutex region_lock;
- RegionList pending_removals;
- RegionList pending_adds;
RegionList pending_bounds;
bool pending_modified;
bool pending_length;
@@ -244,10 +239,7 @@ class Playlist : public StateManager, public PBD::StatefulDestructible {
virtual XMLNode& state (bool);
- /* override state_manager::save_state so we can check in_set_state() */
-
- void save_state (std::string why);
- void maybe_save_state (std::string why);
+ boost::shared_ptr<Region> region_by_id (PBD::ID);
void add_region_internal (boost::shared_ptr<Region>, nframes_t position, bool delay_sort = false);
diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h
index 30cd3267df..67e00d0ee8 100644
--- a/libs/ardour/ardour/region.h
+++ b/libs/ardour/ardour/region.h
@@ -28,7 +28,6 @@
#include <pbd/statefuldestructible.h>
#include <ardour/ardour.h>
-#include <ardour/state_manager.h>
class XMLNode;
@@ -42,21 +41,7 @@ enum RegionEditState {
EditChangesID = 2
};
-struct RegionState : public StateManager::State
-{
- RegionState (std::string why) : StateManager::State (why) {}
-
- nframes_t _start;
- nframes_t _length;
- nframes_t _position;
- uint32_t _flags;
- nframes_t _sync_position;
- layer_t _layer;
- string _name;
- mutable RegionEditState _first_edit;
-};
-
-class Region : public PBD::StatefulDestructible, public StateManager, public boost::enable_shared_from_this<Region>
+class Region : public PBD::StatefulDestructible, public boost::enable_shared_from_this<Region>
{
public:
enum Flag {
@@ -92,6 +77,8 @@ class Region : public PBD::StatefulDestructible, public StateManager, public boo
static Change LayerChanged;
static Change HiddenChanged;
+ sigc::signal<void,Change> StateChanged;
+
virtual ~Region();
/* Note: changing the name of a Region does not constitute an edit */
@@ -176,8 +163,6 @@ class Region : public PBD::StatefulDestructible, public StateManager, public boo
ARDOUR::Playlist* playlist() const { return _playlist; }
- virtual UndoAction get_memento() const = 0;
-
void set_playlist (ARDOUR::Playlist*);
virtual void lock_sources () {}
@@ -188,6 +173,7 @@ class Region : public PBD::StatefulDestructible, public StateManager, public boo
XMLNode& get_state ();
virtual XMLNode& state (bool);
virtual int set_state (const XMLNode&);
+ virtual int set_live_state (const XMLNode&, Change&, bool send);
virtual boost::shared_ptr<Region> get_parent() = 0;
@@ -207,15 +193,8 @@ class Region : public PBD::StatefulDestructible, public StateManager, public boo
protected:
XMLNode& get_short_state (); /* used only by Session */
- /* state management */
-
void send_change (Change);
- /* derived classes need these during their own state management calls */
-
- void store_state (RegionState&) const;
- Change restore_and_return_flags (RegionState&);
-
void trim_to_internal (nframes_t position, nframes_t length, void *src);
bool copied() const { return _flags & Copied; }
diff --git a/libs/ardour/audio_playlist.cc b/libs/ardour/audio_playlist.cc
index 2d2f4e5365..e39be5d402 100644
--- a/libs/ardour/audio_playlist.cc
+++ b/libs/ardour/audio_playlist.cc
@@ -39,10 +39,6 @@ using namespace sigc;
using namespace std;
using namespace PBD;
-AudioPlaylist::State::~State ()
-{
-}
-
AudioPlaylist::AudioPlaylist (Session& session, const XMLNode& node, bool hidden)
: Playlist (session, node, hidden)
{
@@ -50,8 +46,6 @@ AudioPlaylist::AudioPlaylist (Session& session, const XMLNode& node, bool hidden
set_state (node);
in_set_state = false;
- save_state (_("initial state"));
-
if (!hidden) {
PlaylistCreated (this); /* EMIT SIGNAL */
}
@@ -60,8 +54,6 @@ AudioPlaylist::AudioPlaylist (Session& session, const XMLNode& node, bool hidden
AudioPlaylist::AudioPlaylist (Session& session, string name, bool hidden)
: Playlist (session, name, hidden)
{
- save_state (_("initial state"));
-
if (!hidden) {
PlaylistCreated (this); /* EMIT SIGNAL */
}
@@ -71,8 +63,6 @@ AudioPlaylist::AudioPlaylist (Session& session, string name, bool hidden)
AudioPlaylist::AudioPlaylist (const AudioPlaylist& other, string name, bool hidden)
: Playlist (other, name, hidden)
{
- save_state (_("initial state"));
-
RegionList::const_iterator in_o = other.regions.begin();
RegionList::iterator in_n = regions.begin();
@@ -118,8 +108,6 @@ AudioPlaylist::AudioPlaylist (const AudioPlaylist& other, string name, bool hidd
AudioPlaylist::AudioPlaylist (const AudioPlaylist& other, nframes_t start, nframes_t cnt, string name, bool hidden)
: Playlist (other, start, cnt, name, hidden)
{
- save_state (_("initial state"));
-
/* this constructor does NOT notify others (session) */
}
@@ -134,24 +122,7 @@ AudioPlaylist::~AudioPlaylist ()
notify_callbacks ();
for (Crossfades::iterator x = _crossfades.begin(); x != _crossfades.end(); ++x) {
- all_xfades.insert (*x);
- }
-
- for (StateMap::iterator i = states.begin(); i != states.end(); ++i) {
-
- AudioPlaylist::State* apstate = dynamic_cast<AudioPlaylist::State*> (*i);
-
- for (Crossfades::iterator xf = apstate->crossfades.begin(); xf != apstate->crossfades.end(); ++xf) {
- all_xfades.insert (*xf);
- }
-
- delete apstate;
- }
-
- /* delete every crossfade */
-
- for (set<Crossfade *>::iterator axf = all_xfades.begin(); axf != all_xfades.end(); ++axf) {
- delete *axf;
+ delete *x;
}
}
@@ -447,7 +418,7 @@ AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh)
add_crossfade (*xfade);
} else {
-
+
xfade = new Crossfade (other, region, Config->get_xfade_model(), Config->get_crossfades_active());
add_crossfade (*xfade);
}
@@ -519,7 +490,7 @@ AudioPlaylist::set_state (const XMLNode& node)
if (!in_set_state) {
Playlist::set_state (node);
- }
+ }
nlist = node.children();
@@ -527,155 +498,60 @@ AudioPlaylist::set_state (const XMLNode& node)
child = *niter;
- if (child->name() == "Crossfade") {
-
- Crossfade *xfade;
-
- try {
- xfade = new Crossfade (*((const Playlist *)this), *child);
- }
-
- catch (failed_constructor& err) {
- // cout << string_compose (_("could not create crossfade object in playlist %1"),
- // _name)
- // << endl;
- continue;
- }
-
- Crossfades::iterator ci;
-
- for (ci = _crossfades.begin(); ci != _crossfades.end(); ++ci) {
- if (*(*ci) == *xfade) {
- break;
- }
- }
-
- if (ci == _crossfades.end()) {
- _crossfades.push_back (xfade);
- xfade->Invalidated.connect (mem_fun (*this, &AudioPlaylist::crossfade_invalidated));
- xfade->StateChanged.connect (mem_fun (*this, &AudioPlaylist::crossfade_changed));
- NewCrossfade(xfade);
- } else {
- delete xfade;
- }
+ if (child->name() != "Crossfade") {
+ continue;
}
- }
-
- return 0;
-}
-
-void
-AudioPlaylist::drop_all_states ()
-{
- set<Crossfade*> all_xfades;
- set<boost::shared_ptr<Region> > all_regions;
-
- /* find every region we've ever used, and add it to the set of
- all regions. same for xfades;
- */
-
- for (StateMap::iterator i = states.begin(); i != states.end(); ++i) {
+ Crossfade *xfade;
- AudioPlaylist::State* apstate = dynamic_cast<AudioPlaylist::State*> (*i);
-
- for (RegionList::iterator r = apstate->regions.begin(); r != apstate->regions.end(); ++r) {
- all_regions.insert (*r);
- }
-
- for (Crossfades::iterator xf = apstate->crossfades.begin(); xf != apstate->crossfades.end(); ++xf) {
- all_xfades.insert (*xf);
+ try {
+ xfade = new Crossfade (*((const Playlist *)this), *child);
}
- }
-
- /* now remove from the "all" lists every region that is in the current list. */
-
- for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
- set<boost::shared_ptr<Region> >::iterator x = all_regions.find (*i);
- if (x != all_regions.end()) {
- all_regions.erase (x);
+
+ catch (failed_constructor& err) {
+ // cout << string_compose (_("could not create crossfade object in playlist %1"),
+ // _name)
+ // << endl;
+ continue;
}
- }
-
- /* ditto for every crossfade */
-
- for (list<Crossfade*>::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
- set<Crossfade*>::iterator x = all_xfades.find (*i);
- if (x != all_xfades.end()) {
- all_xfades.erase (x);
+
+ Crossfades::iterator ci;
+
+ for (ci = _crossfades.begin(); ci != _crossfades.end(); ++ci) {
+ if (*(*ci) == *xfade) {
+ break;
+ }
}
- }
-
- /* delete every crossfade that is left (ditto as per regions) */
-
- for (set<Crossfade *>::iterator axf = all_xfades.begin(); axf != all_xfades.end(); ++axf) {
- delete *axf;
- }
-
- /* Now do the generic thing ... */
-
- StateManager::drop_all_states ();
-}
-
-StateManager::State*
-AudioPlaylist::state_factory (std::string why) const
-{
- State* state = new State (why);
-
- state->regions = regions;
- state->region_states.clear ();
- for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
- state->region_states.push_back ((*i)->get_memento());
- }
-
- state->crossfades = _crossfades;
- state->crossfade_states.clear ();
- for (Crossfades::const_iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
- state->crossfade_states.push_back ((*i)->get_memento());
- }
- return state;
-}
-
-Change
-AudioPlaylist::restore_state (StateManager::State& state)
-{
- {
- RegionLock rlock (this);
- State* apstate = dynamic_cast<State*> (&state);
-
- in_set_state = true;
+
+ if (ci == _crossfades.end()) {
+ _crossfades.push_back (xfade);
+ xfade->Invalidated.connect (mem_fun (*this, &AudioPlaylist::crossfade_invalidated));
+ xfade->StateChanged.connect (mem_fun (*this, &AudioPlaylist::crossfade_changed));
+ NewCrossfade(xfade);
+ } else {
- regions = apstate->regions;
+ /* adjust the current state of the existing crossfade */
- for (list<UndoAction>::iterator s = apstate->region_states.begin(); s != apstate->region_states.end(); ++s) {
- (*s) ();
- }
+ (*ci)->set_state (*child);
- _crossfades = apstate->crossfades;
-
- for (list<UndoAction>::iterator s = apstate->crossfade_states.begin(); s != apstate->crossfade_states.end(); ++s) {
- (*s) ();
+ /* drop the new one */
+ delete xfade;
}
-
- in_set_state = false;
}
- notify_length_changed ();
- return Change (~0);
-}
-
-UndoAction
-AudioPlaylist::get_memento () const
-{
- return sigc::bind (mem_fun (*(const_cast<AudioPlaylist*> (this)), &StateManager::use_state), _current_state_id);
+ return 0;
}
void
-AudioPlaylist::clear (bool with_save)
+AudioPlaylist::clear ()
{
+ for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
+ delete *i;
+ }
+
_crossfades.clear ();
- Playlist::clear (with_save);
+ Playlist::clear ();
}
XMLNode&
@@ -776,52 +652,6 @@ AudioPlaylist::destroy_region (boost::shared_ptr<Region> region)
c = ctmp;
}
- for (StateMap::iterator s = states.begin(); s != states.end(); ) {
- StateMap::iterator tmp;
-
- tmp = s;
- ++tmp;
-
- State* astate = dynamic_cast<State*> (*s);
-
- for (c = astate->crossfades.begin(); c != astate->crossfades.end(); ) {
-
- ctmp = c;
- ++ctmp;
-
- if ((*c)->involves (r)) {
- unique_xfades.insert (*c);
- _crossfades.erase (c);
- }
-
- c = ctmp;
- }
-
- list<UndoAction>::iterator rsi, rsitmp;
- RegionList::iterator ri, ritmp;
-
- for (ri = astate->regions.begin(), rsi = astate->region_states.begin();
- ri != astate->regions.end() && rsi != astate->region_states.end();) {
-
-
- ritmp = ri;
- ++ritmp;
-
- rsitmp = rsi;
- ++rsitmp;
-
- if (region == (*ri)) {
- astate->regions.erase (ri);
- astate->region_states.erase (rsi);
- }
-
- ri = ritmp;
- rsi = rsitmp;
- }
-
- s = tmp;
- }
-
for (set<Crossfade*>::iterator c = unique_xfades.begin(); c != unique_xfades.end(); ++c) {
delete *c;
}
@@ -847,8 +677,6 @@ AudioPlaylist::crossfade_changed (Change ignored)
that occured.
*/
- maybe_save_state (_("xfade change"));
-
notify_modified ();
}
@@ -870,8 +698,6 @@ AudioPlaylist::region_changed (Change what_changed, boost::shared_ptr<Region> re
parent_wants_notify = Playlist::region_changed (what_changed, region);
- maybe_save_state (_("region modified"));
-
if ((parent_wants_notify || (what_changed & our_interests))) {
notify_modified ();
}
diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc
index 1a09cad032..a2a86f6a95 100644
--- a/libs/ardour/audioregion.cc
+++ b/libs/ardour/audioregion.cc
@@ -58,14 +58,6 @@ Change AudioRegion::EnvelopeActiveChanged = ARDOUR::new_change();
Change AudioRegion::ScaleAmplitudeChanged = ARDOUR::new_change();
Change AudioRegion::EnvelopeChanged = ARDOUR::new_change();
-AudioRegionState::AudioRegionState (string why)
- : RegionState (why),
- _fade_in (0.0, 2.0, 1.0, false),
- _fade_out (0.0, 2.0, 1.0, false),
- _envelope (0.0, 2.0, 1.0, false)
-{
-}
-
AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, nframes_t start, nframes_t length)
: Region (start, length, PBD::basename_nosuffix(src->name()), 0, Region::Flag(Region::DefaultFlags|Region::External)),
_fade_in (0.0, 2.0, 1.0, false),
@@ -88,8 +80,6 @@ AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, nframes_t start, n
set_default_fades ();
set_default_envelope ();
- save_state ("initial state");
-
_envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed));
}
@@ -114,7 +104,6 @@ AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, nframes_t start, n
set_default_fades ();
set_default_envelope ();
- save_state ("initial state");
_envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed));
}
@@ -142,7 +131,6 @@ AudioRegion::AudioRegion (SourceList& srcs, nframes_t start, nframes_t length, c
set_default_fades ();
set_default_envelope ();
- save_state ("initial state");
_envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed));
}
@@ -208,8 +196,6 @@ AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, nframes_t
_scale_amplitude = other->_scale_amplitude;
- save_state ("initial state");
-
_envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed));
}
@@ -251,8 +237,6 @@ AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other)
_fade_in_disabled = 0;
_fade_out_disabled = 0;
- save_state ("initial state");
-
_envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed));
}
@@ -277,8 +261,6 @@ AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, const XMLNode& nod
throw failed_constructor();
}
- save_state ("initial state");
-
_envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed));
}
@@ -319,8 +301,6 @@ AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node)
throw failed_constructor();
}
- save_state ("initial state");
-
_envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed));
}
@@ -330,88 +310,6 @@ AudioRegion::~AudioRegion ()
GoingAway (); /* EMIT SIGNAL */
}
-StateManager::State*
-AudioRegion::state_factory (std::string why) const
-{
- AudioRegionState* state = new AudioRegionState (why);
-
- Region::store_state (*state);
-
- state->_fade_in = _fade_in;
- state->_fade_out = _fade_out;
- state->_envelope = _envelope;
- state->_scale_amplitude = _scale_amplitude;
- state->_fade_in_disabled = _fade_in_disabled;
- state->_fade_out_disabled = _fade_out_disabled;
-
- return state;
-}
-
-Change
-AudioRegion::restore_state (StateManager::State& sstate)
-{
- AudioRegionState* state = dynamic_cast<AudioRegionState*> (&sstate);
-
- Change what_changed = Region::restore_and_return_flags (*state);
-
- if (_flags != Flag (state->_flags)) {
-
- uint32_t old_flags = _flags;
-
- _flags = Flag (state->_flags);
-
- if ((old_flags ^ state->_flags) & EnvelopeActive) {
- what_changed = Change (what_changed|EnvelopeActiveChanged);
- }
- }
-
- if (!(_fade_in == state->_fade_in)) {
- _fade_in = state->_fade_in;
- what_changed = Change (what_changed|FadeInChanged);
- }
-
- if (!(_fade_out == state->_fade_out)) {
- _fade_out = state->_fade_out;
- what_changed = Change (what_changed|FadeOutChanged);
- }
-
- if (_scale_amplitude != state->_scale_amplitude) {
- _scale_amplitude = state->_scale_amplitude;
- what_changed = Change (what_changed|ScaleAmplitudeChanged);
- }
-
- if (_fade_in_disabled != state->_fade_in_disabled) {
- if (_fade_in_disabled == 0 && state->_fade_in_disabled) {
- set_fade_in_active (false);
- } else if (_fade_in_disabled && state->_fade_in_disabled == 0) {
- set_fade_in_active (true);
- }
- _fade_in_disabled = state->_fade_in_disabled;
- }
-
- if (_fade_out_disabled != state->_fade_out_disabled) {
- if (_fade_out_disabled == 0 && state->_fade_out_disabled) {
- set_fade_out_active (false);
- } else if (_fade_out_disabled && state->_fade_out_disabled == 0) {
- set_fade_out_active (true);
- }
- _fade_out_disabled = state->_fade_out_disabled;
- }
-
- /* XXX need a way to test stored state versus current for envelopes */
-
- _envelope = state->_envelope;
- what_changed = Change (what_changed);
-
- return what_changed;
-}
-
-UndoAction
-AudioRegion::get_memento() const
-{
- return sigc::bind (mem_fun (*(const_cast<AudioRegion *> (this)), &StateManager::use_state), _current_state_id);
-}
-
bool
AudioRegion::verify_length (nframes_t len)
{
@@ -482,11 +380,7 @@ AudioRegion::set_envelope_active (bool yn)
snprintf (buf, sizeof (buf), "envelope off");
_flags = Flag (_flags & ~EnvelopeActive);
}
- if (!_frozen) {
- save_state (buf);
- }
send_change (EnvelopeActiveChanged);
-
}
}
@@ -706,6 +600,8 @@ AudioRegion::state (bool full)
} else {
_fade_in.store_state (*child);
}
+
+ child->add_property (X_("active"), _fade_in_disabled ? X_("no") : X_("yes"));
child = node.add_child (X_("FadeOut"));
@@ -714,6 +610,8 @@ AudioRegion::state (bool full)
} else {
_fade_out.store_state (*child);
}
+
+ child->add_property (X_("active"), _fade_out_disabled ? X_("no") : X_("yes"));
}
child = node.add_child ("Envelope");
@@ -736,6 +634,7 @@ AudioRegion::state (bool full)
} else {
_envelope.store_state (*child);
}
+
} else {
child->add_property ("default", "yes");
}
@@ -748,14 +647,16 @@ AudioRegion::state (bool full)
}
int
-AudioRegion::set_state (const XMLNode& node)
+AudioRegion::set_live_state (const XMLNode& node, Change& what_changed, bool send)
{
const XMLNodeList& nlist = node.children();
const XMLProperty *prop;
LocaleGuard lg (X_("POSIX"));
- Region::set_state (node);
+ Region::set_live_state (node, what_changed, false);
+ uint32_t old_flags = _flags;
+
if ((prop = node.property ("flags")) != 0) {
_flags = Flag (strtol (prop->value().c_str(), (char **) 0, 16));
@@ -763,6 +664,16 @@ AudioRegion::set_state (const XMLNode& node)
_flags = Flag (_flags & ~Region::RightOfSplit);
}
+ if ((old_flags ^ _flags) & Muted) {
+ what_changed = Change (what_changed|MuteChanged);
+ }
+ if ((old_flags ^ _flags) & Opaque) {
+ what_changed = Change (what_changed|OpacityChanged);
+ }
+ if ((old_flags ^ _flags) & Locked) {
+ what_changed = Change (what_changed|LockChanged);
+ }
+
if ((prop = node.property ("scale-gain")) != 0) {
_scale_amplitude = atof (prop->value().c_str());
} else {
@@ -798,7 +709,6 @@ AudioRegion::set_state (const XMLNode& node)
if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
set_default_fade_in ();
} else {
-
_fade_in.load_state (*child);
}
@@ -814,9 +724,24 @@ AudioRegion::set_state (const XMLNode& node)
}
}
+ if (send) {
+ send_change (what_changed);
+ }
+
return 0;
}
+int
+AudioRegion::set_state (const XMLNode& node)
+{
+ /* Region::set_state() calls the virtual set_live_state(),
+ which will get us back to AudioRegion::set_live_state()
+ to handle the relevant stuff.
+ */
+
+ return Region::set_state (node);
+}
+
void
AudioRegion::set_fade_in_shape (FadeShape shape)
{
@@ -886,10 +811,6 @@ AudioRegion::set_fade_in (FadeShape shape, nframes_t len)
_fade_in.thaw ();
_fade_in_shape = shape;
- if (!_frozen) {
- save_state (_("fade in change"));
- }
-
send_change (FadeInChanged);
}
@@ -948,10 +869,6 @@ AudioRegion::set_fade_out (FadeShape shape, nframes_t len)
_fade_out.thaw ();
_fade_out_shape = shape;
- if (!_frozen) {
- save_state (_("fade in change"));
- }
-
send_change (FadeOutChanged);
}
@@ -962,13 +879,6 @@ AudioRegion::set_fade_in_length (nframes_t len)
if (changed) {
_flags = Flag (_flags & ~DefaultFadeIn);
-
- if (!_frozen) {
- char buf[64];
- snprintf (buf, sizeof (buf), "fade in length changed to %u", len);
- save_state (buf);
- }
-
send_change (FadeInChanged);
}
}
@@ -980,12 +890,6 @@ AudioRegion::set_fade_out_length (nframes_t len)
if (changed) {
_flags = Flag (_flags & ~DefaultFadeOut);
-
- if (!_frozen) {
- char buf[64];
- snprintf (buf, sizeof (buf), "fade out length changed to %u", len);
- save_state (buf);
- }
}
send_change (FadeOutChanged);
@@ -1324,12 +1228,6 @@ AudioRegion::normalize_to (float target_dB)
_scale_amplitude = target/maxamp;
- if (!_frozen) {
- char buf[64];
- snprintf (buf, sizeof (buf), _("normalized to %.2fdB"), target_dB);
- save_state (buf);
- }
-
/* tell the diskstream we're in */
if (_playlist) {
@@ -1344,7 +1242,6 @@ AudioRegion::normalize_to (float target_dB)
void
AudioRegion::envelope_changed (Change ignored)
{
- save_state (_("envelope change"));
send_change (EnvelopeChanged);
}
diff --git a/libs/ardour/auditioner.cc b/libs/ardour/auditioner.cc
index 7bf9f0542a..0c5e8bc6a2 100644
--- a/libs/ardour/auditioner.cc
+++ b/libs/ardour/auditioner.cc
@@ -78,7 +78,7 @@ Auditioner::prepare_playlist ()
AudioPlaylist* const apl = dynamic_cast<AudioPlaylist*>(_diskstream->playlist());
assert(apl);
- apl->clear (false);
+ apl->clear ();
return *apl;
}
@@ -126,8 +126,8 @@ Auditioner::audition_region (boost::shared_ptr<Region> region)
boost::shared_ptr<AudioRegion> the_region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (region)));
the_region->set_position (0, this);
- _diskstream->playlist()->clear (false);
- _diskstream->playlist()->add_region (the_region, 0, 1, false);
+ _diskstream->playlist()->clear ();
+ _diskstream->playlist()->add_region (the_region, 0, 1);
while (_diskstream->n_channels() < the_region->n_channels()) {
audio_diskstream()->add_channel ();
diff --git a/libs/ardour/crossfade.cc b/libs/ardour/crossfade.cc
index 32a9e2b533..a197459971 100644
--- a/libs/ardour/crossfade.cc
+++ b/libs/ardour/crossfade.cc
@@ -151,28 +151,24 @@ Crossfade::Crossfade (const Playlist& playlist, XMLNode& node)
}
_length = 0;
- initialize(false);
+ initialize();
if (set_state (node)) {
throw failed_constructor();
}
-
- save_state ("initial");
}
Crossfade::Crossfade (const Crossfade &orig, boost::shared_ptr<AudioRegion> newin, boost::shared_ptr<AudioRegion> newout)
: _fade_in(orig._fade_in),
_fade_out(orig._fade_out)
{
- _active = orig._active;
- _in_update = orig._in_update;
- _length = orig._length;
- _position = orig._position;
- _anchor_point = orig._anchor_point;
- _follow_overlap = orig._follow_overlap;
- _fixed = orig._fixed;
- _follow_overlap = orig._follow_overlap;
- _short_xfade_length = orig._short_xfade_length;
+ _active = orig._active;
+ _in_update = orig._in_update;
+ _length = orig._length;
+ _position = orig._position;
+ _anchor_point = orig._anchor_point;
+ _follow_overlap = orig._follow_overlap;
+ _fixed = orig._fixed;
_in = newin;
_out = newout;
@@ -192,13 +188,10 @@ Crossfade::Crossfade (const Crossfade &orig, boost::shared_ptr<AudioRegion> newi
Crossfade::~Crossfade ()
{
- for (StateMap::iterator i = states.begin(); i != states.end(); ++i) {
- delete *i;
- }
}
void
-Crossfade::initialize (bool savestate)
+Crossfade::initialize ()
{
_in_update = false;
@@ -225,14 +218,10 @@ Crossfade::initialize (bool savestate)
_fade_in.add (_length, 1.0);
_fade_in.thaw ();
-// _in->StateChanged.connect (slot (*this, &Crossfade::member_changed));
-// _out->StateChanged.connect (slot (*this, &Crossfade::member_changed));
+ _in->StateChanged.connect (sigc::mem_fun (*this, &Crossfade::member_changed));
+ _out->StateChanged.connect (sigc::mem_fun (*this, &Crossfade::member_changed));
overlap_type = _in->coverage (_out->position(), _out->last_frame());
-
- if (savestate) {
- save_state ("initial");
- }
}
int
@@ -488,8 +477,7 @@ Crossfade::set_active (bool yn)
{
if (_active != yn) {
_active = yn;
- save_state (_("active changed"));
- send_state_changed (ActiveChanged);
+ StateChanged (ActiveChanged);
}
}
@@ -535,7 +523,6 @@ bool
Crossfade::update (bool force)
{
nframes_t newlen;
- bool save = false;
if (_follow_overlap) {
newlen = _out->first_frame() + _out->length() - _in->first_frame();
@@ -559,41 +546,32 @@ Crossfade::update (bool force)
_length = newlen;
- save = true;
-
}
switch (_anchor_point) {
case StartOfIn:
if (_position != _in->first_frame()) {
_position = _in->first_frame();
- save = true;
}
break;
case EndOfIn:
if (_position != _in->last_frame() - _length) {
_position = _in->last_frame() - _length;
- save = true;
}
break;
case EndOfOut:
if (_position != _out->last_frame() - _length) {
_position = _out->last_frame() - _length;
- save = true;
}
}
- if (save) {
- save_state ("updated");
- }
-
/* UI's may need to know that the overlap changed even
though the xfade length did not.
*/
- send_state_changed (BoundsChanged); /* EMIT SIGNAL */
+ StateChanged (BoundsChanged); /* EMIT SIGNAL */
_in_update = false;
@@ -612,65 +590,6 @@ Crossfade::member_changed (Change what_changed)
}
}
-Change
-Crossfade::restore_state (StateManager::State& state)
-{
- CrossfadeState* xfstate = dynamic_cast<CrossfadeState*> (&state);
- Change what_changed = Change (0);
-
- _in_update = true;
-
- xfstate->fade_in_memento ();
- xfstate->fade_out_memento ();
-
- if (_length != xfstate->length) {
- what_changed = Change (what_changed|LengthChanged);
- _length = xfstate->length;
- }
- if (_active != xfstate->active) {
- what_changed = Change (what_changed|ActiveChanged);
- _active = xfstate->active;
- }
- if (_position != xfstate->position) {
- what_changed = Change (what_changed|PositionChanged);
- _position = xfstate->position;
- }
-
- /* XXX what to do about notifications for these? I don't
- think (G)UI cares about them because they are
- implicit in the bounds.
- */
-
- _follow_overlap = xfstate->follow_overlap;
- _anchor_point = xfstate->anchor_point;
-
- _in_update = false;
-
- return Change (what_changed);
-}
-
-StateManager::State*
-Crossfade::state_factory (std::string why) const
-{
- CrossfadeState* state = new CrossfadeState (why);
-
- state->fade_in_memento = _fade_in.get_memento ();
- state->fade_out_memento = _fade_out.get_memento ();
- state->active = _active;
- state->length = _length;
- state->position = _position;
- state->follow_overlap = _follow_overlap;
- state->anchor_point = _anchor_point;
-
- return state;
-}
-
-UndoAction
-Crossfade::get_memento() const
-{
- return sigc::bind (mem_fun (*(const_cast<Crossfade *> (this)), &StateManager::use_state), _current_state_id);
-}
-
XMLNode&
Crossfade::get_state ()
{
@@ -733,16 +652,26 @@ Crossfade::set_state (const XMLNode& node)
XMLNode* fo;
const XMLProperty* prop;
LocaleGuard lg (X_("POSIX"));
+ Change what_changed = Change (0);
+ nframes_t val;
if ((prop = node.property ("position")) != 0) {
- _position = atoi (prop->value().c_str());
+ sscanf (prop->value().c_str(), "%" PRIu32, &val);
+ if (val != _position) {
+ _position = val;
+ what_changed = Change (what_changed | PositionChanged);
+ }
} else {
warning << _("old-style crossfade information - no position information") << endmsg;
_position = _in->first_frame();
}
if ((prop = node.property ("active")) != 0) {
- _active = (prop->value() == "yes");
+ bool x = (prop->value() == "yes");
+ if (x != _active) {
+ _active = x;
+ what_changed = Change (what_changed | ActiveChanged);
+ }
} else {
_active = true;
}
@@ -767,7 +696,11 @@ Crossfade::set_state (const XMLNode& node)
if ((prop = node.property ("length")) != 0) {
- _length = atol (prop->value().c_str());
+ sscanf (prop->value().c_str(), "%" PRIu32, &val);
+ if (val != _length) {
+ _length = atol (prop->value().c_str());
+ what_changed = Change (what_changed | LengthChanged);
+ }
} else {
@@ -790,6 +723,7 @@ Crossfade::set_state (const XMLNode& node)
/* fade in */
+ _fade_in.freeze ();
_fade_in.clear ();
children = fi->children();
@@ -808,9 +742,12 @@ Crossfade::set_state (const XMLNode& node)
_fade_in.add (x, y);
}
}
+
+ _fade_in.thaw ();
/* fade out */
+ _fade_in.freeze ();
_fade_out.clear ();
children = fo->children();
@@ -831,6 +768,10 @@ Crossfade::set_state (const XMLNode& node)
}
}
+ _fade_out.thaw ();
+
+ StateChanged (what_changed); /* EMIT SIGNAL */
+
return 0;
}
@@ -887,9 +828,7 @@ Crossfade::set_length (nframes_t len)
_length = len;
- save_state ("length changed");
-
- send_state_changed (LengthChanged);
+ StateChanged (LengthChanged);
return len;
}
diff --git a/libs/ardour/diskstream.cc b/libs/ardour/diskstream.cc
index f9fb540099..9e83c5e21a 100644
--- a/libs/ardour/diskstream.cc
+++ b/libs/ardour/diskstream.cc
@@ -331,7 +331,6 @@ Diskstream::use_playlist (Playlist* playlist)
reset_write_sources (false);
}
- plstate_connection = _playlist->StateChanged.connect (mem_fun (*this, &Diskstream::playlist_changed));
plmod_connection = _playlist->Modified.connect (mem_fun (*this, &Diskstream::playlist_modified));
plgone_connection = _playlist->GoingAway.connect (bind (mem_fun (*this, &Diskstream::playlist_deleted), _playlist));
}
diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc
index 3ef817cc55..f87a30c931 100644
--- a/libs/ardour/playlist.cc
+++ b/libs/ardour/playlist.cc
@@ -117,7 +117,6 @@ Playlist::Playlist (const Playlist& other, string namestr, bool hide)
subcnt = 0;
_read_data_count = 0;
_frozen = other._frozen;
- save_on_thaw = false;
layer_op_counter = other.layer_op_counter;
freeze_length = other.freeze_length;
@@ -238,7 +237,6 @@ Playlist::init (bool hide)
subcnt = 0;
_read_data_count = 0;
_frozen = false;
- save_on_thaw = false;
layer_op_counter = 0;
freeze_length = 0;
@@ -333,9 +331,9 @@ void
Playlist::notify_region_removed (boost::shared_ptr<Region> r)
{
if (holding_state ()) {
- pending_removals.insert (pending_removals.end(), r);
+ pending_modified = true;
+ pending_length = true;
} else {
- RegionRemoved (r); /* EMIT SIGNAL */
/* this might not be true, but we have to act
as though it could be.
*/
@@ -347,13 +345,14 @@ Playlist::notify_region_removed (boost::shared_ptr<Region> r)
void
Playlist::notify_region_added (boost::shared_ptr<Region> r)
{
+ /* the length change might not be true, but we have to act
+ as though it could be.
+ */
+
if (holding_state()) {
- pending_adds.insert (pending_adds.end(), r);
+ pending_modified = true;
+ pending_length = true;
} else {
- RegionAdded (r); /* EMIT SIGNAL */
- /* this might not be true, but we have to act
- as though it could be.
- */
LengthChanged (); /* EMIT SIGNAL */
Modified (); /* EMIT SIGNAL */
}
@@ -406,22 +405,10 @@ Playlist::flush_notifications ()
/* don't increment n again - its the same list */
}
- for (a = pending_adds.begin(); a != pending_adds.end(); ++a) {
- dependent_checks_needed.insert (*a);
- RegionAdded (*a); /* EMIT SIGNAL */
- n++;
- }
-
for (set<boost::shared_ptr<Region> >::iterator x = dependent_checks_needed.begin(); x != dependent_checks_needed.end(); ++x) {
check_dependents (*x, false);
}
- for (r = pending_removals.begin(); r != pending_removals.end(); ++r) {
- remove_dependents (*r);
- RegionRemoved (*r); /* EMIT SIGNAL */
- n++;
- }
-
if ((freeze_length != _get_maximum_extent()) || pending_length) {
pending_length = 0;
LengthChanged(); /* EMIT SIGNAL */
@@ -437,15 +424,8 @@ Playlist::flush_notifications ()
Modified (); /* EMIT SIGNAL */
}
- pending_adds.clear ();
- pending_removals.clear ();
pending_bounds.clear ();
- if (save_on_thaw) {
- save_on_thaw = false;
- save_state (last_save_reason);
- }
-
in_flush = false;
}
@@ -454,7 +434,7 @@ Playlist::flush_notifications ()
*************************************************************/
void
-Playlist::add_region (boost::shared_ptr<Region> region, nframes_t position, float times, bool with_save)
+Playlist::add_region (boost::shared_ptr<Region> region, nframes_t position, float times)
{
RegionLock rlock (this);
@@ -493,10 +473,6 @@ Playlist::add_region (boost::shared_ptr<Region> region, nframes_t position, floa
boost::shared_ptr<Region> sub = RegionFactory::create (region, 0, length, name, region->layer(), region->flags());
add_region_internal (sub, pos, true);
}
-
- if (with_save) {
- maybe_save_state (_("add region"));
- }
}
void
@@ -515,6 +491,7 @@ Playlist::add_region_internal (boost::shared_ptr<Region> region, nframes_t posit
timestamp_layer_op (region);
regions.insert (upper_bound (regions.begin(), regions.end(), region, cmp), region);
+ all_regions.insert (region);
if (!holding_state () && !in_set_state) {
/* layers get assigned from XML state */
@@ -547,8 +524,6 @@ Playlist::replace_region (boost::shared_ptr<Region> old, boost::shared_ptr<Regio
if (!holding_state ()) {
possibly_splice_unlocked ();
}
-
- maybe_save_state (_("replace region"));
}
void
@@ -560,8 +535,6 @@ Playlist::remove_region (boost::shared_ptr<Region> region)
if (!holding_state ()) {
possibly_splice_unlocked ();
}
-
- maybe_save_state (_("remove region"));
}
int
@@ -632,8 +605,6 @@ Playlist::partition (nframes_t start, nframes_t end, bool just_top_level)
for (RegionList::iterator i = thawlist.begin(); i != thawlist.end(); ++i) {
(*i)->thaw ("separation");
}
-
- maybe_save_state (_("separate"));
}
void
@@ -897,8 +868,6 @@ Playlist::cut (nframes_t start, nframes_t cnt, bool result_is_hidden)
(*i)->thaw ("playlist cut");
}
- maybe_save_state (_("cut"));
-
return the_copy;
}
@@ -958,8 +927,6 @@ Playlist::paste (Playlist& other, nframes_t position, float times)
}
- maybe_save_state (_("paste"));
-
return 0;
}
@@ -986,8 +953,6 @@ Playlist::duplicate (boost::shared_ptr<Region> region, nframes_t position, float
boost::shared_ptr<Region> sub = RegionFactory::create (region, 0, length, name, region->layer(), region->flags());
add_region_internal (sub, pos, true);
}
-
- maybe_save_state (_("duplicate"));
}
void
@@ -1041,8 +1006,6 @@ Playlist::split_region (boost::shared_ptr<Region> region, nframes_t playlist_pos
if (remove_region_internal (region, true)) {
return;
}
-
- maybe_save_state (_("split"));
}
void
@@ -1192,7 +1155,7 @@ Playlist::region_changed (Change what_changed, boost::shared_ptr<Region> region)
}
void
-Playlist::clear (bool with_save)
+Playlist::clear ()
{
RegionList::iterator i;
RegionList tmp;
@@ -1206,10 +1169,6 @@ Playlist::clear (bool with_save)
for (i = tmp.begin(); i != tmp.end(); ++i) {
notify_region_removed (*i);
}
-
- if (with_save) {
- maybe_save_state (_("clear"));
- }
}
/***********************************************************************
@@ -1339,8 +1298,6 @@ Playlist::mark_session_dirty ()
int
Playlist::set_state (const XMLNode& node)
{
- in_set_state = true;
-
XMLNode *child;
XMLNodeList nlist;
XMLNodeConstIterator niter;
@@ -1350,13 +1307,15 @@ Playlist::set_state (const XMLNode& node)
boost::shared_ptr<Region> region;
string region_name;
- clear (false);
+ in_set_state = true;
if (node.name() != "Playlist") {
in_set_state = false;
return -1;
}
+ freeze ();
+
plist = node.properties();
for (piter = plist.begin(); piter != plist.end(); ++piter) {
@@ -1372,6 +1331,11 @@ Playlist::set_state (const XMLNode& node)
}
}
+ {
+ RegionLock rl (this);
+ regions.clear ();
+ }
+
nlist = node.children();
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
@@ -1385,19 +1349,29 @@ Playlist::set_state (const XMLNode& node)
continue;
}
- if ((region = RegionFactory::create (_session, *child, true)) == 0) {
- error << _("Playlist: cannot create region from state file") << endmsg;
+ ID id = prop->value ();
+
+ if ((region = region_by_id (id))) {
+
+ Change what_changed = Change (0);
+
+ if (region->set_live_state (*child, what_changed, true)) {
+ error << _("Playlist: cannot reset region state from XML") << endmsg;
+ continue;
+ }
+
+ } else if ((region = RegionFactory::create (_session, *child, true)) == 0) {
+ error << _("Playlist: cannot create region from XML") << endmsg;
continue;
}
- add_region (region, region->position(), 1.0, false);
+ add_region (region, region->position(), 1.0);
// So that layer_op ordering doesn't get screwed up
region->set_last_layer_op( region->layer());
}
}
-
/* update dependents, which was not done during add_region_internal
due to in_set_state being true
@@ -1406,9 +1380,13 @@ Playlist::set_state (const XMLNode& node)
for (RegionList::iterator r = regions.begin(); r != regions.end(); ++r) {
check_dependents (*r, false);
}
-
+
+ notify_modified ();
+
in_set_state = false;
+ thaw ();
+
return 0;
}
@@ -1746,7 +1724,6 @@ Playlist::nudge_after (nframes_t start, nframes_t distance, bool forwards)
if (moved) {
_nudging = false;
- maybe_save_state (_("nudged"));
notify_length_changed ();
}
@@ -1756,26 +1733,31 @@ boost::shared_ptr<Region>
Playlist::find_region (const ID& id) const
{
RegionLock rlock (const_cast<Playlist*> (this));
- RegionList::const_iterator i;
- boost::shared_ptr<Region> ret;
- for (i = regions.begin(); i != regions.end(); ++i) {
+ /* searches all regions currently in use by the playlist */
+
+ for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
if ((*i)->id() == id) {
- ret = *i;
+ return *i;
}
}
- return ret;
+ return boost::shared_ptr<Region> ();
}
-
-void
-Playlist::save_state (std::string why)
+
+boost::shared_ptr<Region>
+Playlist::region_by_id (ID id)
{
- if (!in_set_state) {
- StateManager::save_state (why);
+ /* searches all regions ever added to this playlist */
+
+ for (set<boost::shared_ptr<Region> >::iterator i = all_regions.begin(); i != all_regions.end(); ++i) {
+ if ((*i)->id() == id) {
+ return *i;
+ }
}
+ return boost::shared_ptr<Region> ();
}
-
+
void
Playlist::dump () const
{
@@ -1811,13 +1793,3 @@ Playlist::timestamp_layer_op (boost::shared_ptr<Region> region)
region->set_last_layer_op (++layer_op_counter);
}
-void
-Playlist::maybe_save_state (string why)
-{
- if (holding_state ()) {
- save_on_thaw = true;
- last_save_reason = why;
- } else {
- save_state (why);
- }
-}
diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc
index ccdf3bdb5d..3a31fe254c 100644
--- a/libs/ardour/region.cc
+++ b/libs/ardour/region.cc
@@ -64,7 +64,6 @@ Region::Region (nframes_t start, nframes_t length, const string& name, layer_t l
_length = length;
_position = 0;
_layer = layer;
- _current_state_id = 0;
_read_data_count = 0;
_first_edit = EditChangesNothing;
_last_layer_op = 0;
@@ -90,7 +89,6 @@ Region::Region (boost::shared_ptr<const Region> other, nframes_t offset, nframes
_position = 0;
_layer = layer;
_flags = Flag (flags & ~(Locked|WholeFile|Hidden));
- _current_state_id = 0;
_first_edit = EditChangesNothing;
_last_layer_op = 0;
}
@@ -120,7 +118,6 @@ Region::Region (boost::shared_ptr<const Region> other)
_position = other->_position;
_layer = other->_layer;
_flags = Flag (other->_flags & ~Locked);
- _current_state_id = 0;
_last_layer_op = other->_last_layer_op;
}
@@ -137,7 +134,6 @@ Region::Region (const XMLNode& node)
_position = 0;
_layer = 0;
_flags = Flag (0);
- _current_state_id = 0;
_first_edit = EditChangesNothing;
if (set_state (node)) {
@@ -157,69 +153,7 @@ Region::set_playlist (Playlist* pl)
}
void
-Region::store_state (RegionState& state) const
-{
- state._start = _start;
- state._length = _length;
- state._position = _position;
- state._flags = _flags;
- state._sync_position = _sync_position;
- state._layer = _layer;
- state._name = _name;
- state._first_edit = _first_edit;
-}
-
-Change
-Region::restore_and_return_flags (RegionState& state)
-{
- Change what_changed = Change (0);
-
- {
- Glib::Mutex::Lock lm (lock);
-
- if (_start != state._start) {
- what_changed = Change (what_changed|StartChanged);
- _start = state._start;
- }
- if (_length != state._length) {
- what_changed = Change (what_changed|LengthChanged);
- _length = state._length;
- }
- if (_position != state._position) {
- what_changed = Change (what_changed|PositionChanged);
- _position = state._position;
- }
- if (_sync_position != state._sync_position) {
- _sync_position = state._sync_position;
- what_changed = Change (what_changed|SyncOffsetChanged);
- }
- if (_layer != state._layer) {
- what_changed = Change (what_changed|LayerChanged);
- _layer = state._layer;
- }
-
- uint32_t old_flags = _flags;
- _flags = Flag (state._flags);
-
- if ((old_flags ^ state._flags) & Muted) {
- what_changed = Change (what_changed|MuteChanged);
- }
- if ((old_flags ^ state._flags) & Opaque) {
- what_changed = Change (what_changed|OpacityChanged);
- }
- if ((old_flags ^ state._flags) & Locked) {
- what_changed = Change (what_changed|LockChanged);
- }
-
- _first_edit = state._first_edit;
- }
-
- return what_changed;
-}
-
-void
Region::set_name (string str)
-
{
if (_name != str) {
_name = str;
@@ -257,10 +191,6 @@ Region::set_length (nframes_t len, void *src)
if (!_frozen) {
recompute_at_end ();
-
- char buf[64];
- snprintf (buf, sizeof (buf), "length set to %u", len);
- save_state (buf);
}
send_change (LengthChanged);
@@ -328,12 +258,6 @@ Region::set_position (nframes_t pos, void *src)
if (max_frames - _length < _position) {
_length = max_frames - _position;
}
-
- if (!_frozen) {
- char buf[64];
- snprintf (buf, sizeof (buf), "position set to %u", pos);
- save_state (buf);
- }
}
/* do this even if the position is the same. this helps out
@@ -352,12 +276,6 @@ Region::set_position_on_top (nframes_t pos, void *src)
if (_position != pos) {
_position = pos;
-
- if (!_frozen) {
- char buf[64];
- snprintf (buf, sizeof (buf), "position set to %u", pos);
- save_state (buf);
- }
}
_playlist->raise_region_to_top (boost::shared_ptr<Region>(this));
@@ -394,12 +312,6 @@ Region::nudge_position (long n, void *src)
}
}
- if (!_frozen) {
- char buf[64];
- snprintf (buf, sizeof (buf), "position set to %u", _position);
- save_state (buf);
- }
-
send_change (PositionChanged);
}
@@ -424,12 +336,6 @@ Region::set_start (nframes_t pos, void *src)
_flags = Region::Flag (_flags & ~WholeFile);
first_edit ();
- if (!_frozen) {
- char buf[64];
- snprintf (buf, sizeof (buf), "start set to %u", pos);
- save_state (buf);
- }
-
send_change (StartChanged);
}
}
@@ -480,12 +386,6 @@ Region::trim_start (nframes_t new_position, void *src)
_flags = Region::Flag (_flags & ~WholeFile);
first_edit ();
- if (!_frozen) {
- char buf[64];
- snprintf (buf, sizeof (buf), "slipped start to %u", _start);
- save_state (buf);
- }
-
send_change (StartChanged);
}
@@ -619,13 +519,6 @@ Region::trim_to_internal (nframes_t position, nframes_t length, void *src)
}
if (what_changed) {
-
- if (!_frozen) {
- char buf[64];
- snprintf (buf, sizeof (buf), "trimmed to %u-%u", _position, _position+_length-1);
- save_state (buf);
- }
-
send_change (what_changed);
}
}
@@ -656,16 +549,6 @@ Region::set_muted (bool yn)
_flags = Flag (_flags & ~Muted);
}
- if (!_frozen) {
- char buf[64];
- if (yn) {
- snprintf (buf, sizeof (buf), "muted");
- } else {
- snprintf (buf, sizeof (buf), "unmuted");
- }
- save_state (buf);
- }
-
send_change (MuteChanged);
}
}
@@ -674,16 +557,10 @@ void
Region::set_opaque (bool yn)
{
if (opaque() != yn) {
- if (!_frozen) {
- char buf[64];
- if (yn) {
- snprintf (buf, sizeof (buf), "opaque");
- _flags = Flag (_flags|Opaque);
- } else {
- snprintf (buf, sizeof (buf), "translucent");
- _flags = Flag (_flags & ~Opaque);
- }
- save_state (buf);
+ if (yn) {
+ _flags = Flag (_flags|Opaque);
+ } else {
+ _flags = Flag (_flags & ~Opaque);
}
send_change (OpacityChanged);
}
@@ -693,16 +570,10 @@ void
Region::set_locked (bool yn)
{
if (locked() != yn) {
- if (!_frozen) {
- char buf[64];
- if (yn) {
- snprintf (buf, sizeof (buf), "locked");
- _flags = Flag (_flags|Locked);
- } else {
- snprintf (buf, sizeof (buf), "unlocked");
- _flags = Flag (_flags & ~Locked);
- }
- save_state (buf);
+ if (yn) {
+ _flags = Flag (_flags|Locked);
+ } else {
+ _flags = Flag (_flags & ~Locked);
}
send_change (LockChanged);
}
@@ -721,10 +592,7 @@ Region::set_sync_position (nframes_t absolute_pos)
_flags = Flag (_flags|SyncMarked);
if (!_frozen) {
- char buf[64];
maybe_uncopy ();
- snprintf (buf, sizeof (buf), "sync point set to %u", _sync_position);
- save_state (buf);
}
send_change (SyncOffsetChanged);
}
@@ -738,7 +606,6 @@ Region::clear_sync_position ()
if (!_frozen) {
maybe_uncopy ();
- save_state ("sync point removed");
}
send_change (SyncOffsetChanged);
}
@@ -842,12 +709,6 @@ Region::set_layer (layer_t l)
if (_layer != l) {
_layer = l;
- if (!_frozen) {
- char buf[64];
- snprintf (buf, sizeof (buf), "layer set to %" PRIu32, _layer);
- save_state (buf);
- }
-
send_change (LayerChanged);
}
}
@@ -857,7 +718,8 @@ Region::state (bool full_state)
{
XMLNode *node = new XMLNode ("Region");
char buf[64];
-
+ char* fe;
+
_id.print (buf, sizeof (buf));
node->add_property ("id", buf);
node->add_property ("name", _name);
@@ -867,6 +729,20 @@ Region::state (bool full_state)
node->add_property ("length", buf);
snprintf (buf, sizeof (buf), "%u", _position);
node->add_property ("position", buf);
+
+ switch (_first_edit) {
+ case EditChangesNothing:
+ fe = X_("nothing");
+ break;
+ case EditChangesName:
+ fe = X_("name");
+ break;
+ case EditChangesID:
+ fe = X_("id");
+ break;
+ }
+
+ node->add_property ("first_edit", fe);
/* note: flags are stored by derived classes */
@@ -885,54 +761,83 @@ Region::get_state ()
}
int
-Region::set_state (const XMLNode& node)
+Region::set_live_state (const XMLNode& node, Change& what_changed, bool send)
{
const XMLNodeList& nlist = node.children();
const XMLProperty *prop;
+ nframes_t val;
- if (_extra_xml) {
- delete _extra_xml;
- _extra_xml = 0;
- }
-
- if ((prop = node.property ("id")) == 0) {
- error << _("Session: XMLNode describing a Region is incomplete (no id)") << endmsg;
- return -1;
- }
-
- _id = prop->value();
+ /* this is responsible for setting those aspects of Region state
+ that are mutable after construction.
+ */
if ((prop = node.property ("name")) == 0) {
- error << _("Session: XMLNode describing a Region is incomplete (no name)") << endmsg;
+ error << _("XMLNode describing a Region is incomplete (no name)") << endmsg;
return -1;
}
_name = prop->value();
if ((prop = node.property ("start")) != 0) {
- sscanf (prop->value().c_str(), "%" PRIu32, &_start);
+ sscanf (prop->value().c_str(), "%" PRIu32, &val);
+ if (val != _start) {
+ what_changed = Change (what_changed|StartChanged);
+ _start = val;
+ }
+ } else {
+ _start = 0;
}
if ((prop = node.property ("length")) != 0) {
- sscanf (prop->value().c_str(), "%" PRIu32, &_length);
+ sscanf (prop->value().c_str(), "%" PRIu32, &val);
+ if (val != _length) {
+ what_changed = Change (what_changed|LengthChanged);
+ _length = val;
+ }
+ } else {
+ _length = 1;
}
if ((prop = node.property ("position")) != 0) {
- sscanf (prop->value().c_str(), "%" PRIu32, &_position);
+ sscanf (prop->value().c_str(), "%" PRIu32, &val);
+ if (val != _position) {
+ what_changed = Change (what_changed|PositionChanged);
+ _position = val;
+ }
+ } else {
+ _position = 0;
}
if ((prop = node.property ("layer")) != 0) {
- _layer = (layer_t) atoi (prop->value().c_str());
+ layer_t x;
+ x = (layer_t) atoi (prop->value().c_str());
+ if (x != _layer) {
+ what_changed = Change (what_changed|LayerChanged);
+ _layer = x;
+ }
+ } else {
+ _layer = 0;
}
- /* note: derived classes set flags */
-
if ((prop = node.property ("sync-position")) != 0) {
- sscanf (prop->value().c_str(), "%" PRIu32, &_sync_position);
+ sscanf (prop->value().c_str(), "%" PRIu32, &val);
+ if (val != _sync_position) {
+ what_changed = Change (what_changed|SyncOffsetChanged);
+ _sync_position = val;
+ }
} else {
_sync_position = _start;
}
+
+ /* XXX FIRST EDIT !!! */
+ /* note: derived classes set flags */
+
+ if (_extra_xml) {
+ delete _extra_xml;
+ _extra_xml = 0;
+ }
+
for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
XMLNode *child;
@@ -945,7 +850,31 @@ Region::set_state (const XMLNode& node)
}
}
+ if (send) {
+ send_change (what_changed);
+ }
+
+ return 0;
+}
+
+int
+Region::set_state (const XMLNode& node)
+{
+ const XMLProperty *prop;
+ Change what_changed = Change (0);
+
+ /* ID is not allowed to change, ever */
+
+ if ((prop = node.property ("id")) == 0) {
+ error << _("Session: XMLNode describing a Region is incomplete (no id)") << endmsg;
+ return -1;
+ }
+
+ _id = prop->value();
+
_first_edit = EditChangesNothing;
+
+ set_live_state (node, what_changed, true);
return 0;
}
@@ -985,7 +914,6 @@ Region::thaw (const string& why)
recompute_at_end ();
}
- save_state (why);
StateChanged (what_changed);
}
@@ -1000,7 +928,7 @@ Region::send_change (Change what_changed)
}
}
- StateManager::send_state_changed (what_changed);
+ StateChanged (what_changed);
}
void
diff --git a/libs/ardour/session_command.cc b/libs/ardour/session_command.cc
index b54e5c8398..c5c31b7c17 100644
--- a/libs/ardour/session_command.cc
+++ b/libs/ardour/session_command.cc
@@ -28,22 +28,23 @@ Command *Session::memento_command_factory(XMLNode *n)
id = PBD::ID(n->property("obj_id")->value());
/* get before/after */
- if (n->name() == "MementoCommand")
- {
- before = new XMLNode(*n->children().front());
- after = new XMLNode(*n->children().back());
- child = before;
- } else if (n->name() == "MementoUndoCommand")
- {
- before = new XMLNode(*n->children().front());
- child = before;
- }
- else if (n->name() == "MementoRedoCommand")
- {
- after = new XMLNode(*n->children().front());
- child = after;
- }
+ if (n->name() == "MementoCommand") {
+ before = new XMLNode(*n->children().front());
+ after = new XMLNode(*n->children().back());
+ child = before;
+ } else if (n->name() == "MementoUndoCommand") {
+ before = new XMLNode(*n->children().front());
+ child = before;
+ } else if (n->name() == "MementoRedoCommand") {
+ after = new XMLNode(*n->children().front());
+ child = after;
+ } else if (n->name() == "PlaylistCommand") {
+ before = new XMLNode(*n->children().front());
+ after = new XMLNode(*n->children().back());
+ child = before;
+ }
+
if (!child)
{
error << _("Tried to reconstitute a MementoCommand with no contents, failing. id=") << id.to_s() << endmsg;
@@ -53,43 +54,32 @@ Command *Session::memento_command_factory(XMLNode *n)
/* create command */
string obj_T = n->children().front()->name();
- if (obj_T == "AudioRegion" || obj_T == "Region")
- {
- if (audio_regions.count(id))
- return new MementoCommand<AudioRegion>(*audio_regions[id], before, after);
- }
- else if (obj_T == "AudioSource")
- {
- if (audio_sources.count(id))
- return new MementoCommand<AudioSource>(*audio_sources[id], before, after);
- }
- else if (obj_T == "Location")
- return new MementoCommand<Location>(*_locations.get_location_by_id(id), before, after);
- else if (obj_T == "Locations")
- return new MementoCommand<Locations>(_locations, before, after);
- else if (obj_T == "TempoMap")
- return new MementoCommand<TempoMap>(*_tempo_map, before, after);
- else if (obj_T == "Playlist" || obj_T == "AudioPlaylist")
- {
- if (Playlist *pl = playlist_by_name(child->property("name")->value()))
- return new MementoCommand<Playlist>(*pl, before, after);
- }
- else if (obj_T == "Route") // inlcudes AudioTrack
- return new MementoCommand<Route>(*route_by_id(id), before, after);
- else if (obj_T == "Curve")
- {
- if (curves.count(id))
- return new MementoCommand<Curve>(*curves[id], before, after);
- }
- else if (obj_T == "AutomationList")
- {
- if (automation_lists.count(id))
- return new MementoCommand<AutomationList>(*automation_lists[id], before, after);
+ if (obj_T == "AudioRegion" || obj_T == "Region") {
+ if (audio_regions.count(id))
+ return new MementoCommand<AudioRegion>(*audio_regions[id], before, after);
+ } else if (obj_T == "AudioSource") {
+ if (audio_sources.count(id))
+ return new MementoCommand<AudioSource>(*audio_sources[id], before, after);
+ } else if (obj_T == "Location") {
+ return new MementoCommand<Location>(*_locations.get_location_by_id(id), before, after);
+ } else if (obj_T == "Locations") {
+ return new MementoCommand<Locations>(_locations, before, after);
+ } else if (obj_T == "TempoMap") {
+ return new MementoCommand<TempoMap>(*_tempo_map, before, after);
+ } else if (obj_T == "Playlist" || obj_T == "AudioPlaylist") {
+ if (Playlist *pl = playlist_by_name(child->property("name")->value()))
+ return new MementoCommand<Playlist>(*pl, before, after);
+ } else if (obj_T == "Route") { // includes AudioTrack
+ return new MementoCommand<Route>(*route_by_id(id), before, after);
+ } else if (obj_T == "Curve") {
+ if (curves.count(id))
+ return new MementoCommand<Curve>(*curves[id], before, after);
+ } else if (obj_T == "AutomationList") {
+ if (automation_lists.count(id))
+ return new MementoCommand<AutomationList>(*automation_lists[id], before, after);
+ } else if (registry.count(id)) { // For Editor and AutomationLine which are off-limits here
+ return new MementoCommand<StatefulDestructible>(*registry[id], before, after);
}
- // For Editor and AutomationLine which are off-limits here
- else if (registry.count(id))
- return new MementoCommand<StatefulDestructible>(*registry[id], before, after);
-
/* we failed */
error << _("could not reconstitute MementoCommand from XMLNode. id=") << id.to_s() << endmsg;
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index 3c51bbfaf8..c3e0fe9388 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -2434,13 +2434,7 @@ Session::cleanup_sources (Session::cleanup_report& rep)
delete *x;
}
- /* step 2: clear the undo/redo history for all playlists */
-
- for (PlaylistList::iterator x = playlists.begin(); x != playlists.end(); ++x) {
- (*x)->drop_all_states ();
- }
-
- /* step 3: find all un-referenced sources */
+ /* step 2: find all un-referenced sources */
rep.paths.clear ();
rep.space = 0;
@@ -2470,7 +2464,7 @@ Session::cleanup_sources (Session::cleanup_report& rep)
i = tmp;
}
- /* Step 4: get rid of all regions in the region list that use any dead sources
+ /* Step 3: get rid of all regions in the region list that use any dead sources
in case the sources themselves don't go away (they might be referenced in
other snapshots).
*/
@@ -2863,41 +2857,39 @@ Session::restore_history (string snapshot_name)
/* replace history */
history.clear();
- for (XMLNodeConstIterator it = tree.root()->children().begin();
- it != tree.root()->children().end();
- it++)
- {
- XMLNode *t = *it;
- UndoTransaction* ut = new UndoTransaction ();
- struct timeval tv;
-
- ut->set_name(t->property("name")->value());
- stringstream ss(t->property("tv_sec")->value());
- ss >> tv.tv_sec;
- ss.str(t->property("tv_usec")->value());
- ss >> tv.tv_usec;
- ut->set_timestamp(tv);
-
- for (XMLNodeConstIterator child_it = t->children().begin();
- child_it != t->children().end();
- child_it++)
- {
- XMLNode *n = *child_it;
- Command *c;
- if (n->name() == "MementoCommand" ||
- n->name() == "MementoUndoCommand" ||
- n->name() == "MementoRedoCommand")
- {
- c = memento_command_factory(n);
- if (c)
- ut->add_command(c);
- }
- else
- {
- error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
- }
- }
- history.add(ut);
+
+ for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
+
+ XMLNode *t = *it;
+ UndoTransaction* ut = new UndoTransaction ();
+ struct timeval tv;
+
+ ut->set_name(t->property("name")->value());
+ stringstream ss(t->property("tv_sec")->value());
+ ss >> tv.tv_sec;
+ ss.str(t->property("tv_usec")->value());
+ ss >> tv.tv_usec;
+ ut->set_timestamp(tv);
+
+ for (XMLNodeConstIterator child_it = t->children().begin();
+ child_it != t->children().end();
+ child_it++)
+ {
+ XMLNode *n = *child_it;
+ Command *c;
+
+ if (n->name() == "MementoCommand" ||
+ n->name() == "MementoUndoCommand" ||
+ n->name() == "MementoRedoCommand") {
+ if ((c = memento_command_factory(n))) {
+ ut->add_command(c);
+ }
+ } else {
+ error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
+ }
+ }
+
+ history.add (ut);
}
return 0;