summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk2_ardour/ardour_ui.cc2
-rw-r--r--gtk2_ardour/ardour_ui_dialogs.cc1
-rw-r--r--gtk2_ardour/automation_line.h2
-rw-r--r--gtk2_ardour/editor.h4
-rw-r--r--gtk2_ardour/region_gain_line.h3
-rw-r--r--libs/ardour/ardour/automation_event.h3
-rw-r--r--libs/ardour/ardour/location.h6
-rw-r--r--libs/ardour/ardour/playlist.h3
-rw-r--r--libs/ardour/ardour/session.h1
-rw-r--r--libs/ardour/ardour/tempo.h3
-rw-r--r--libs/ardour/session.cc4
-rw-r--r--libs/ardour/session_state.cc48
-rw-r--r--libs/ardour/session_transport.cc1
-rw-r--r--libs/ardour/track.cc1
-rw-r--r--libs/pbd/command.cc2
-rw-r--r--libs/pbd/id.cc8
-rw-r--r--libs/pbd/pbd/id.h1
-rw-r--r--libs/pbd/pbd/memento_command.h21
-rw-r--r--libs/pbd/pbd/undo.h2
-rw-r--r--libs/pbd/undo.cc18
-rw-r--r--libs/surfaces/control_protocol/basic_ui.cc1
21 files changed, 122 insertions, 13 deletions
diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc
index e5367d6280..d18756fb7f 100644
--- a/gtk2_ardour/ardour_ui.cc
+++ b/gtk2_ardour/ardour_ui.cc
@@ -1298,6 +1298,7 @@ ARDOUR_UI::start_engine ()
settings for a new session
*/
session->save_state ("");
+ session->save_history ();
}
/* there is too much going on, in too many threads, for us to
@@ -1471,6 +1472,7 @@ ARDOUR_UI::save_state_canfail (string name)
}
if ((ret = session->save_state (name)) != 0) {
+ session->save_history();
return ret;
}
}
diff --git a/gtk2_ardour/ardour_ui_dialogs.cc b/gtk2_ardour/ardour_ui_dialogs.cc
index 25f3068a81..d2cc3e1e1c 100644
--- a/gtk2_ardour/ardour_ui_dialogs.cc
+++ b/gtk2_ardour/ardour_ui_dialogs.cc
@@ -156,6 +156,7 @@ ARDOUR_UI::unload_session ()
case 1:
session->save_state ("");
+ session->save_history();
break;
}
}
diff --git a/gtk2_ardour/automation_line.h b/gtk2_ardour/automation_line.h
index 9c6b932dfd..ec86b7455f 100644
--- a/gtk2_ardour/automation_line.h
+++ b/gtk2_ardour/automation_line.h
@@ -161,7 +161,9 @@ class AutomationLine : public sigc::trackable, public Stateful
XMLNode& get_state (void);
int set_state (const XMLNode&);
+ PBD::ID id() { return _id; }
protected:
+ PBD::ID _id;
string _name;
guint32 _height;
uint32_t _line_color;
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index c31dfd5ede..5ddb2b0d2e 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -143,6 +143,8 @@ class Editor : public PublicEditor
XMLNode& get_state ();
int set_state (const XMLNode& );
+ PBD::ID id() { return _id; }
+
void set_mouse_mode (Editing::MouseMode, bool force=true);
void step_mouse_mode (bool next);
Editing::MouseMode current_mouse_mode () { return mouse_mode; }
@@ -347,6 +349,8 @@ class Editor : public PublicEditor
ARDOUR::AudioEngine& engine;
bool constructed;
+ PBD::ID _id;
+
PlaylistSelector* _playlist_selector;
void set_frames_per_unit (double);
diff --git a/gtk2_ardour/region_gain_line.h b/gtk2_ardour/region_gain_line.h
index bf6de0d810..02340c8bae 100644
--- a/gtk2_ardour/region_gain_line.h
+++ b/gtk2_ardour/region_gain_line.h
@@ -26,6 +26,7 @@ class AudioRegionGainLine : public AutomationLine
void remove_point (ControlPoint&);
+ PBD::ID id() { return _id; }
private:
@@ -33,6 +34,8 @@ class AudioRegionGainLine : public AutomationLine
AudioRegionView& rv;
UndoAction get_memento();
+
+ PBD::ID _id;
};
diff --git a/libs/ardour/ardour/automation_event.h b/libs/ardour/ardour/automation_event.h
index 1fa29d4adf..5864de73c6 100644
--- a/libs/ardour/ardour/automation_event.h
+++ b/libs/ardour/ardour/automation_event.h
@@ -156,6 +156,8 @@ class AutomationList : public StateManager, public Stateful
XMLNode &get_state(void);
int set_state (const XMLNode &s);
+ PBD::ID id() { return _id; }
+
void set_max_xval (double);
double get_max_xval() const { return max_xval; }
@@ -182,6 +184,7 @@ class AutomationList : public StateManager, public Stateful
};
protected:
+ PBD::ID _id;
struct State : public ARDOUR::StateManager::State {
AutomationEventList events;
diff --git a/libs/ardour/ardour/location.h b/libs/ardour/ardour/location.h
index 30c02a80a1..ff953d1d78 100644
--- a/libs/ardour/ardour/location.h
+++ b/libs/ardour/ardour/location.h
@@ -119,7 +119,10 @@ class Location : public Stateful, public sigc::trackable
XMLNode& get_state (void);
int set_state (const XMLNode&);
+ PBD::ID id() { return _id; }
+
private:
+ PBD::ID _id;
string _name;
jack_nframes_t _start;
jack_nframes_t _end;
@@ -145,6 +148,7 @@ class Locations : public Stateful, public StateManager
XMLNode& get_state (void);
int set_state (const XMLNode&);
+ PBD::ID id() { return _id; }
Location* auto_loop_location () const;
Location* auto_punch_location () const;
@@ -197,6 +201,8 @@ class Locations : public Stateful, public StateManager
Change restore_state (StateManager::State&);
StateManager::State* state_factory (std::string why) const;
+
+ PBD::ID _id;
};
} // namespace ARDOUR
diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h
index 9fb5b0eb2b..b389258860 100644
--- a/libs/ardour/ardour/playlist.h
+++ b/libs/ardour/ardour/playlist.h
@@ -76,6 +76,7 @@ class Playlist : public Stateful, public StateManager {
EditMode get_edit_mode() const { return _edit_mode; }
void set_edit_mode (EditMode);
+ PBD::ID id() { return _id; }
/* Editing operations */
void add_region (const Region&, jack_nframes_t position, float times = 1, bool with_save = true);
@@ -273,6 +274,8 @@ class Playlist : public Stateful, public StateManager {
void unset_freeze_child (Playlist*);
void timestamp_layer_op (Region&);
+
+ PBD::ID _id;
};
} /* namespace ARDOUR */
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 65daeafca7..69ba373456 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -477,6 +477,7 @@ class Session : public sigc::trackable, public Stateful
int save_state (string snapshot_name, bool pending = false);
int restore_state (string snapshot_name);
int save_template (string template_name);
+ int save_history ();
static int rename_template (string old_name, string new_name);
diff --git a/libs/ardour/ardour/tempo.h b/libs/ardour/ardour/tempo.h
index db06894607..c4032b9ed9 100644
--- a/libs/ardour/ardour/tempo.h
+++ b/libs/ardour/ardour/tempo.h
@@ -238,6 +238,7 @@ class TempoMap : public Stateful, public StateManager {
XMLNode& get_state (void);
int set_state (const XMLNode&);
+ PBD::ID id();
void dump (std::ostream&) const;
void clear ();
@@ -315,6 +316,8 @@ class TempoMap : public Stateful, public StateManager {
void save_state (std::string why);
+ PBD::ID _id;
+
};
}; /* namespace ARDOUR */
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 806ec3b17f..8a68e5a3b5 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -1011,6 +1011,7 @@ Session::auto_punch_start_changed (Location* location)
if (get_record_enabled() && get_punch_in()) {
/* capture start has been changed, so save new pending state */
save_state ("", true);
+ save_history();
}
}
@@ -1328,6 +1329,7 @@ Session::maybe_enable_record ()
*/
save_state ("", true);
+ save_history();
if (_transport_speed) {
if (!punch_in) {
@@ -1922,6 +1924,7 @@ Session::add_diskstream (Diskstream* dstream)
set_dirty();
save_state (_current_snapshot_name);
+ save_history();
DiskstreamAdded (dstream); /* EMIT SIGNAL */
}
@@ -2674,6 +2677,7 @@ Session::remove_source (Source* source)
*/
save_state (_current_snapshot_name);
+ save_history();
}
SourceRemoved(source); /* EMIT SIGNAL */
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index 9619e77ad1..2813cc72f0 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -608,6 +608,7 @@ Session::create (bool& new_session, string* mix_template, jack_nframes_t initial
_state_of_the_state = Clean;
if (save_state (_current_snapshot_name)) {
+ save_history();
return -1;
}
}
@@ -1690,6 +1691,7 @@ Session::set_state (const XMLNode& node)
if (state_was_pending) {
save_state (_current_snapshot_name);
+ save_history();
remove_pending_capture_state ();
state_was_pending = false;
}
@@ -2477,6 +2479,7 @@ void
Session::auto_save()
{
save_state (_current_snapshot_name);
+ save_history();
}
RouteGroup *
@@ -3278,3 +3281,48 @@ Session::add_instant_xml (XMLNode& node, const std::string& dir)
Stateful::add_instant_xml (node, dir);
Config->add_instant_xml (node, get_user_ardour_path());
}
+
+
+int
+Session::save_history ()
+{
+ XMLTree tree;
+ string xml_path;
+ string bak_path;
+
+ tree.set_root (&history.get_state());
+
+ xml_path = _path + _current_snapshot_name + ".history";
+
+ bak_path = xml_path + ".bak";
+
+ if ((access (xml_path.c_str(), F_OK) == 0) &&
+ (rename (xml_path.c_str(), bak_path.c_str())))
+ {
+ error << _("could not backup old history file, current history not saved.") << endmsg;
+ return -1;
+ }
+
+ if (!tree.write (xml_path))
+ {
+ error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
+
+ /* don't leave a corrupt file lying around if it is
+ * possible to fix.
+ */
+
+ if (unlink (xml_path.c_str()))
+ {
+ error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
+ } else {
+ if (rename (bak_path.c_str(), xml_path.c_str()))
+ {
+ error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
+ }
+ }
+
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc
index 3bd54aa69c..df9d4aa2e9 100644
--- a/libs/ardour/session_transport.cc
+++ b/libs/ardour/session_transport.cc
@@ -411,6 +411,7 @@ Session::non_realtime_stop (bool abort)
if ((post_transport_work & PostTransportLocate) && get_record_enabled()) {
/* capture start has been changed, so save pending state */
save_state ("", true);
+ save_history();
}
/* always try to get rid of this */
diff --git a/libs/ardour/track.cc b/libs/ardour/track.cc
index 3b3b705a87..709e76f5e1 100644
--- a/libs/ardour/track.cc
+++ b/libs/ardour/track.cc
@@ -206,6 +206,7 @@ Track::set_name (string str, void *src)
if ((ret = IO::set_name (str, src)) == 0) {
_session.save_state ("");
+ _session.save_history();
}
return ret;
}
diff --git a/libs/pbd/command.cc b/libs/pbd/command.cc
index c0fcf36187..5b41691c07 100644
--- a/libs/pbd/command.cc
+++ b/libs/pbd/command.cc
@@ -5,6 +5,6 @@
XMLNode &Command::get_state()
{
XMLNode *node = new XMLNode ("Command");
- // TODO
+ node->add_content("WARNING: Somebody forgot to subclass Command.");
return *node;
}
diff --git a/libs/pbd/id.cc b/libs/pbd/id.cc
index f9afa72c98..0de0d052c3 100644
--- a/libs/pbd/id.cc
+++ b/libs/pbd/id.cc
@@ -8,6 +8,7 @@
#include <inttypes.h>
#include <pbd/id.h>
+#include <string>
using namespace std;
using namespace PBD;
@@ -45,6 +46,13 @@ ID::print (char* buf) const
snprintf (buf, 16, "%" PRIu64, id);
}
+string ID::to_s() const
+{
+ char buf[16]; // see print()
+ print(buf);
+ return string(buf);
+}
+
ID&
ID::operator= (string str)
{
diff --git a/libs/pbd/pbd/id.h b/libs/pbd/pbd/id.h
index 9a3f10478d..1ce448d58b 100644
--- a/libs/pbd/pbd/id.h
+++ b/libs/pbd/pbd/id.h
@@ -28,6 +28,7 @@ class ID {
}
void print (char* buf) const;
+ std::string to_s() const;
static uint64_t counter() { return _counter; }
static void init_counter (uint64_t val) { _counter = val; }
diff --git a/libs/pbd/pbd/memento_command.h b/libs/pbd/pbd/memento_command.h
index a86006a6ae..46c724e9ea 100644
--- a/libs/pbd/pbd/memento_command.h
+++ b/libs/pbd/pbd/memento_command.h
@@ -22,6 +22,7 @@
#define __lib_pbd_memento_command_h__
#include <pbd/command.h>
+#include <pbd/xml++.h>
#include <sigc++/slot.h>
/** This command class is initialized with before and after mementos
@@ -42,9 +43,9 @@ class MementoCommand : public Command
virtual XMLNode &get_state()
{
XMLNode *node = new XMLNode("MementoCommand");
- // obj.id
- // key is "MementoCommand" or something
- // before and after mementos
+ node->add_property("obj_id", obj.id().to_s());
+ node->add_child_nocopy(before);
+ node->add_child_nocopy(after);
return *node;
}
// TODO does this need a copy constructor?
@@ -64,10 +65,9 @@ public:
void undo() { obj.set_state(before); }
virtual XMLNode &get_state()
{
- XMLNode *node = new XMLNode("MementoUndoCommand"); // XXX
- // obj.id
- // key is "MementoCommand" or something
- // before and after mementos
+ XMLNode *node = new XMLNode("MementoUndoCommand");
+ node->add_property("obj_id", obj.id().to_s());
+ node->add_child_nocopy(before);
return *node;
}
protected:
@@ -86,10 +86,9 @@ public:
void undo() { /* noop */ }
virtual XMLNode &get_state()
{
- XMLNode *node = new XMLNode("MementoUndoCommand");
- // obj.id
- // key is "MementoCommand" or something
- // before and after mementos
+ XMLNode *node = new XMLNode("MementoRedoCommand");
+ node->add_property("obj_id", obj.id().to_s());
+ node->add_child_nocopy(after);
return *node;
}
protected:
diff --git a/libs/pbd/pbd/undo.h b/libs/pbd/pbd/undo.h
index 49ff19ccce..724e86aaa0 100644
--- a/libs/pbd/pbd/undo.h
+++ b/libs/pbd/pbd/undo.h
@@ -90,6 +90,8 @@ class UndoHistory
void clear_undo ();
void clear_redo ();
+ XMLNode &get_state();
+ void save_state();
private:
list<UndoTransaction> UndoList;
list<UndoTransaction> RedoList;
diff --git a/libs/pbd/undo.cc b/libs/pbd/undo.cc
index a5ca6b713a..8d1b416c16 100644
--- a/libs/pbd/undo.cc
+++ b/libs/pbd/undo.cc
@@ -22,6 +22,7 @@
#include <pbd/undo.h>
#include <pbd/xml++.h>
+#include <string>
using namespace std;
using namespace sigc;
@@ -86,7 +87,11 @@ UndoTransaction::redo ()
XMLNode &UndoTransaction::get_state()
{
XMLNode *node = new XMLNode ("UndoTransaction");
- // TODO
+
+ list<Command*>::iterator it;
+ for (it=actions.begin(); it!=actions.end(); it++)
+ node->add_child_nocopy((*it)->get_state());
+
return *node;
}
@@ -142,3 +147,14 @@ UndoHistory::clear ()
RedoList.clear ();
UndoList.clear ();
}
+
+XMLNode & UndoHistory::get_state()
+{
+ XMLNode *node = new XMLNode ("UndoHistory");
+
+ list<UndoTransaction>::iterator it;
+ for (it=UndoList.begin(); it != UndoList.end(); it++)
+ node->add_child_nocopy(it->get_state());
+
+ return *node;
+}
diff --git a/libs/surfaces/control_protocol/basic_ui.cc b/libs/surfaces/control_protocol/basic_ui.cc
index 3dc93cc64a..47401c8cfe 100644
--- a/libs/surfaces/control_protocol/basic_ui.cc
+++ b/libs/surfaces/control_protocol/basic_ui.cc
@@ -145,6 +145,7 @@ void
BasicUI::save_state ()
{
session->save_state ("");
+ session->save_history();
}
void