From c26215c1e59b6341da86f94f5b2b3ca950dd3889 Mon Sep 17 00:00:00 2001 From: Hans Fugal Date: Wed, 9 Aug 2006 14:15:05 +0000 Subject: [PATCH] r283@gandalf: fugalh | 2006-08-09 08:13:37 -0600 Save state basics, including adding PBD::ID to the delinquents. Compiles but needs to be tested (because I can't get the whole thing to compile on OSX due to the Rect problem). git-svn-id: svn://localhost/ardour2/branches/undo@769 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/ardour_ui.cc | 2 + gtk2_ardour/ardour_ui_dialogs.cc | 1 + gtk2_ardour/automation_line.h | 2 + gtk2_ardour/editor.h | 4 ++ gtk2_ardour/region_gain_line.h | 3 ++ libs/ardour/ardour/automation_event.h | 3 ++ libs/ardour/ardour/location.h | 6 +++ libs/ardour/ardour/playlist.h | 3 ++ libs/ardour/ardour/session.h | 1 + libs/ardour/ardour/tempo.h | 3 ++ libs/ardour/session.cc | 4 ++ libs/ardour/session_state.cc | 48 ++++++++++++++++++++++ libs/ardour/session_transport.cc | 1 + libs/ardour/track.cc | 1 + libs/pbd/command.cc | 2 +- libs/pbd/id.cc | 8 ++++ libs/pbd/pbd/id.h | 1 + libs/pbd/pbd/memento_command.h | 21 +++++----- libs/pbd/pbd/undo.h | 2 + libs/pbd/undo.cc | 18 +++++++- libs/surfaces/control_protocol/basic_ui.cc | 1 + 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 #include +#include 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 +#include #include /** 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 UndoList; list 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 #include +#include using namespace std; using namespace sigc; @@ -86,7 +87,11 @@ UndoTransaction::redo () XMLNode &UndoTransaction::get_state() { XMLNode *node = new XMLNode ("UndoTransaction"); - // TODO + + list::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::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 -- 2.30.2