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
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
@@ -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,20 +229,9 @@ 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 ()
|
||||
{
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
|
||||
@@ -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*);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
/* adjust the current state of the existing crossfade */
|
||||
|
||||
(*ci)->set_state (*child);
|
||||
|
||||
/* drop the new one */
|
||||
delete xfade;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
AudioPlaylist::drop_all_states ()
|
||||
AudioPlaylist::clear ()
|
||||
{
|
||||
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) {
|
||||
|
||||
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);
|
||||
}
|
||||
for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
|
||||
delete *i;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
regions = apstate->regions;
|
||||
|
||||
for (list<UndoAction>::iterator s = apstate->region_states.begin(); s != apstate->region_states.end(); ++s) {
|
||||
(*s) ();
|
||||
}
|
||||
|
||||
_crossfades = apstate->crossfades;
|
||||
|
||||
for (list<UndoAction>::iterator s = apstate->crossfade_states.begin(); s != apstate->crossfade_states.end(); ++s) {
|
||||
(*s) ();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
AudioPlaylist::clear (bool with_save)
|
||||
{
|
||||
_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 ();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
void
|
||||
Playlist::save_state (std::string why)
|
||||
{
|
||||
if (!in_set_state) {
|
||||
StateManager::save_state (why);
|
||||
}
|
||||
return boost::shared_ptr<Region> ();
|
||||
}
|
||||
|
||||
boost::shared_ptr<Region>
|
||||
Playlist::region_by_id (ID id)
|
||||
{
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)) {
|
||||
@@ -156,70 +152,8 @@ Region::set_playlist (Playlist* pl)
|
||||
_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
|
||||
|
||||
@@ -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);
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
// 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;
|
||||
|
||||
@@ -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 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;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
history.add (ut);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user