r229@gwythaint (orig r769): fugalh | 2006-08-09 08:15:05 -0600
authorHans Fugal <hans@fugal.net>
Wed, 9 Aug 2006 21:29:43 +0000 (21:29 +0000)
committerHans Fugal <hans@fugal.net>
Wed, 9 Aug 2006 21:29:43 +0000 (21:29 +0000)
  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/trunk@772 d708f5d6-7413-0410-9779-e7cbd77b26cf

21 files changed:
gtk2_ardour/ardour_ui.cc
gtk2_ardour/ardour_ui_dialogs.cc
gtk2_ardour/automation_line.h
gtk2_ardour/editor.h
gtk2_ardour/region_gain_line.h
libs/ardour/ardour/automation_event.h
libs/ardour/ardour/location.h
libs/ardour/ardour/playlist.h
libs/ardour/ardour/session.h
libs/ardour/ardour/tempo.h
libs/ardour/session.cc
libs/ardour/session_state.cc
libs/ardour/session_transport.cc
libs/ardour/track.cc
libs/pbd/command.cc
libs/pbd/id.cc
libs/pbd/pbd/id.h
libs/pbd/pbd/memento_command.h
libs/pbd/pbd/undo.h
libs/pbd/undo.cc
libs/surfaces/control_protocol/basic_ui.cc

index e5367d6280f633b88ec6d707e0c66cf142005c27..d18756fb7fdacd716a6050e637c34afaeab31408 100644 (file)
@@ -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;
                }
        }
index 25f3068a813d39c04d0b38157e98f79dee0e6c7c..d2cc3e1e1cc084779ca1cd6c7a7c3a32cc076271 100644 (file)
@@ -156,6 +156,7 @@ ARDOUR_UI::unload_session ()
                        
                case 1:
                        session->save_state ("");
+                        session->save_history();
                        break;
                }
        }
index 9c6b932dfdd0159f9b7f2ac5c81d55080c6eaff5..ec86b7455fd2cfddf4c6d3de4cd6997698abbe64 100644 (file)
@@ -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;
index c31dfd5ede788d14dd0425bf9db8a3e46d4b78ad..5ddb2b0d2ed56046c5fe462976e8c9061321213d 100644 (file)
@@ -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);
index bf6de0d8103d96fca526b83f4146cee4c09be69e..02340c8bae29e49feae6b77dccf36b1a140b8a4c 100644 (file)
@@ -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;
 };
 
 
index 1fa29d4adf5e581a86aaabe2c49d4c62221f122b..5864de73c668201a761dc9209afa62b5d1ac4815 100644 (file)
@@ -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;
 
index 30c02a80a1eaa0802f7937f9a9af1e0c89cf7083..ff953d1d7895ab8c138776acc1565480900bd0ce 100644 (file)
@@ -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
index 9fb5b0eb2b5b2baf97a6bb054f51754027695aa9..b389258860bce55ccbd9ae251852d56e0fd1ded4 100644 (file)
@@ -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 */
index 65daeafca72afd553d120264f7609dbb430cf603..69ba373456596b96b9851d10e15221e016af4284 100644 (file)
@@ -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);
 
index db0689460728a34670d324122f2b421fc7e94906..c4032b9ed9ecab3ad7df55b84ebe8c00ab87a2aa 100644 (file)
@@ -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 */
index 806ec3b17f09843cab6a7f3b441efd2874d6e6f5..8a68e5a3b5ac6053f27b9e15f52c17a5a16addf9 100644 (file)
@@ -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 */
index 9619e77ad1fed018e532bdea311ba795d9806791..2813cc72f09d785c12d6b217d9ecb83d7a96706e 100644 (file)
@@ -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;
+}
index 3bd54aa69c054139ad2b884b2c8bb2d568e1a11b..df9d4aa2e9887422b17bfb61a53508ef08853677 100644 (file)
@@ -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 */
index c13b7abf2cb97ec60fdcd71797094d03118a26cf..941524b54cf03b92477b84b9cc36f841c7d3a7f9 100644 (file)
@@ -224,6 +224,7 @@ Track::set_name (string str, void *src)
 
        if ((ret = IO::set_name (str, src)) == 0) {
                _session.save_state ("");
+                _session.save_history();
        }
        return ret;
 }
index c0fcf361872dccef28aaed7e50dac67768ccb50d..5b41691c07cae0ff3ad8754f7f901489952e0dc8 100644 (file)
@@ -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;
 }
index f9afa72c985a359f667e985c5666544759c5c64e..0de0d052c3d7a5e2d6e5c84697f8d553adba61df 100644 (file)
@@ -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)
 {
index 9a3f10478ddcc57bf328ed66e2fab095b8806edb..1ce448d58bd1397b15d7379f4a8a426f9c6d1a98 100644 (file)
@@ -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; }
index a86006a6ae48243f2887499aab5f5399bcdfc5ca..46c724e9ea61be335ac5a2790b84a11356783a0d 100644 (file)
@@ -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:
index 49ff19ccceca24bfd794e0ad27fd199cf34a0be8..724e86aaa05ccfa58a898babf351a313be08b45e 100644 (file)
@@ -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;
index a5ca6b713a4f4117b15b1e2c2f64d9f73b264e50..8d1b416c16bcf66d1c611eaf45902288b9113cba 100644 (file)
@@ -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;
+}
index 3dc93cc64ad980070886d6215a613b25a5288260..47401c8cfe896dd9974cc7405a004e8312d155c4 100644 (file)
@@ -145,6 +145,7 @@ void
 BasicUI::save_state ()
 {
        session->save_state ("");
+        session->save_history();
 }
 
 void