Merged with trunk R1736.
authorDavid Robillard <d@drobilla.net>
Sun, 22 Apr 2007 18:01:10 +0000 (18:01 +0000)
committerDavid Robillard <d@drobilla.net>
Sun, 22 Apr 2007 18:01:10 +0000 (18:01 +0000)
git-svn-id: svn://localhost/ardour2/branches/midi@1737 d708f5d6-7413-0410-9779-e7cbd77b26cf

18 files changed:
ardour.rc.in
gtk2_ardour/actions.cc
gtk2_ardour/ardour.menus
gtk2_ardour/ardour_ui.cc
gtk2_ardour/ardour_ui.h
gtk2_ardour/ardour_ui_dialogs.cc
gtk2_ardour/ardour_ui_ed.cc
gtk2_ardour/ardour_ui_options.cc
gtk2_ardour/editor.cc
gtk2_ardour/editor.h
gtk2_ardour/editor_actions.cc
gtk2_ardour/editor_ops.cc
gtk2_ardour/po/sv_SE.po
gtk2_ardour/time_axis_view.cc
libs/ardour/ardour/configuration_vars.h
libs/ardour/ardour/session.h
libs/ardour/crossfade.cc
libs/ardour/session_state.cc

index 44738f806288ef6b6df4bfffe7b2e94ed09828f1..a1d0d371776a24cd3b46317b713e019c7fca3291 100644 (file)
@@ -33,6 +33,8 @@
     <Option name="use-vst" value="yes"/>
     <Option name="use-tranzport" value="yes"/>
     <Option name="destructive-xfade-msecs" value="20"/>
+    <Option name="periodic-safety-backups" value="1"/>
+    <Option name="periodic-safety-backup-interval" value="120"/>
   </Config>
   <extra>
     <Keyboard edit-button="3" edit-modifier="4" delete-button="3" delete-modifier="1" snap-modifier="32"/>
index 6e4a525ba7a3f425e6d885f8c326d7af3825abbe..40af880f9cc902591f26c292400708b7a38327f2 100644 (file)
@@ -256,6 +256,13 @@ ActionManager::uncheck_toggleaction (const char * name)
        delete [] group_name;
 }
 
+/** Examine the state of a Configuration setting and a toggle action, and toggle the Configuration
+ * setting if its state doesn't match the toggle action.
+ * @param group Action group.
+ * @param action Action name.
+ * @param Method to set the state of the Configuration setting.
+ * @param Method to get the state of the Configuration setting.
+ */
 void
 ActionManager::toggle_config_state (const char* group, const char* action, bool (Configuration::*set)(bool), bool (Configuration::*get)(void) const)
 {
@@ -285,6 +292,12 @@ ActionManager::toggle_config_state (const char* group, const char* action, sigc:
        }
 }
 
+
+/** Set the state of a ToggleAction using a particular Configuration get() method
+ * @param group Action group.
+ * @param action Action name.
+ * @param get Method to obtain the state that the ToggleAction should have.
+ */
 void
 ActionManager::map_some_state (const char* group, const char* action, bool (Configuration::*get)() const)
 {
index c01195f4f40d693989e1e8f269894d7b1ab0bdea..635def7794d224895f141d78d9b07ea13dcdbda9 100644 (file)
                <menuitem action='LatchedRecordEnable'/>
                <menuitem action='RegionEquivalentsOverlap'/>
                <separator/>
+               <menuitem action='PeriodicSafetyBackups'/>
                <menuitem action='VerifyRemoveLastCapture'/>
                <menuitem action='StopRecordingOnXrun'/>
                <menuitem action='StopTransportAtEndOfSession'/>
index adea076f7f5d86628349b558582ed99c0a3ce048..e990f5ce20d8ec23cc19b891dc17d9d136427407 100644 (file)
@@ -432,6 +432,39 @@ ARDOUR_UI::save_ardour_state ()
        save_keybindings ();
 }
 
+gint
+ARDOUR_UI::autosave_session ()
+{
+        if (!Config->get_periodic_safety_backups())
+                return 1;
+        
+        if (session) {
+                session->maybe_write_autosave();
+        }
+
+        return 1;
+}
+
+void
+ARDOUR_UI::update_autosave ()
+{
+        ENSURE_GUI_THREAD (mem_fun (*this, &ARDOUR_UI::update_autosave));
+        
+        if (session->dirty()) {
+                if (_autosave_connection.connected()) {
+                        _autosave_connection.disconnect();
+                }
+
+                _autosave_connection = Glib::signal_timeout().connect (mem_fun (*this, &ARDOUR_UI::autosave_session),
+                                                                   Config->get_periodic_safety_backup_interval() * 1000);
+
+        } else {
+                if (_autosave_connection.connected()) {
+                        _autosave_connection.disconnect();
+                }               
+        }
+}
+
 void
 ARDOUR_UI::startup ()
 {
index 8b1304ef2a15dd9db2ae7a4606c17921aec692b8..0b5016ea2874328c6077e8bd2ac140f8c835bde2 100644 (file)
@@ -297,6 +297,11 @@ class ARDOUR_UI : public Gtkmm2ext::UI
        int  ask_about_saving_session (const string & why);
        int  save_the_session;
 
+       /* periodic safety backup, to be precise */
+       gint autosave_session();
+       void update_autosave();
+       sigc::connection _autosave_connection;
+
        void queue_transport_change ();
        void map_transport_state ();
        int32_t do_engine_start ();
@@ -675,6 +680,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI
        void toggle_StopPluginsWithTransport();
        void toggle_DoNotRunPluginsWhileRecording();
        void toggle_VerifyRemoveLastCapture();
+       void toggle_PeriodicSafetyBackups();
        void toggle_StopRecordingOnXrun();
        void toggle_StopTransportAtEndOfSession();
        void toggle_GainReduceFastTransport();
index c3b82c74a84a9e2bb599c2958471821cc52a7d1a..8a50697e85b9b76efad70c2a9b365a23e89cebc4 100644 (file)
@@ -126,6 +126,10 @@ ARDOUR_UI::connect_to_session (Session *s)
 
        solo_alert_button.set_active (session->soloing());
 
+       /* update autochange callback on dirty state changing */
+
+       session->DirtyChanged.connect (mem_fun(*this, &ARDOUR_UI::update_autosave));
+
        /* can't be auditioning here */
 
        primary_clock.set_session (s);
index c889eea0f7b6504150a14a2afc17a378e5c1cc07..2cf67508128c76bcc5cfbba1bf02aa2aba0b3c0d 100644 (file)
@@ -406,6 +406,7 @@ ARDOUR_UI::install_actions ()
 
        ActionManager::register_toggle_action (option_actions, X_("StopPluginsWithTransport"), _("Stop plugins with transport"), mem_fun (*this, &ARDOUR_UI::toggle_StopPluginsWithTransport));
        ActionManager::register_toggle_action (option_actions, X_("VerifyRemoveLastCapture"), _("Verify remove last capture"), mem_fun (*this, &ARDOUR_UI::toggle_VerifyRemoveLastCapture));
+       ActionManager::register_toggle_action (option_actions, X_("PeriodicSafetyBackups"), _("Make periodic safety backups"), mem_fun (*this, &ARDOUR_UI::toggle_PeriodicSafetyBackups));
        ActionManager::register_toggle_action (option_actions, X_("StopRecordingOnXrun"), _("Stop recording on xrun"), mem_fun (*this, &ARDOUR_UI::toggle_StopRecordingOnXrun));
        ActionManager::register_toggle_action (option_actions, X_("StopTransportAtEndOfSession"), _("Stop transport at session end"), mem_fun (*this, &ARDOUR_UI::toggle_StopTransportAtEndOfSession));
        ActionManager::register_toggle_action (option_actions, X_("GainReduceFastTransport"), _("-12dB gain reduce ffwd/rewind"), mem_fun (*this, &ARDOUR_UI::toggle_GainReduceFastTransport));
index 9565c46e4010bd7e7dc46e5109575637feb04416..34431aeafbe12c34370163c2a1f0dc8355621ce5 100644 (file)
@@ -398,6 +398,12 @@ ARDOUR_UI::toggle_VerifyRemoveLastCapture()
        ActionManager::toggle_config_state ("options", "VerifyRemoveLastCapture", &Configuration::set_verify_remove_last_capture, &Configuration::get_verify_remove_last_capture);
 }
 
+void
+ARDOUR_UI::toggle_PeriodicSafetyBackups()
+{
+       ActionManager::toggle_config_state ("options", "PeriodicSafetyBackups", &Configuration::set_periodic_safety_backups, &Configuration::get_periodic_safety_backups);
+}
+
 void
 ARDOUR_UI::toggle_StopRecordingOnXrun()
 {
@@ -891,6 +897,8 @@ ARDOUR_UI::parameter_changed (const char* parameter_name)
                ActionManager::map_some_state ("options", "LatchedRecordEnable", &Configuration::get_latched_record_enable);
        } else if (PARAM_IS ("verify-remove-last-capture")) {
                ActionManager::map_some_state ("options",  "VerifyRemoveLastCapture", &Configuration::get_verify_remove_last_capture);
+       } else if (PARAM_IS ("periodic-safety-backups")) {
+               ActionManager::map_some_state ("options",  "PeriodicSafetyBackups", &Configuration::get_periodic_safety_backups);
        } else if (PARAM_IS ("stop-recording-on-xrun")) {
                ActionManager::map_some_state ("options",  "StopRecordingOnXrun", &Configuration::get_stop_recording_on_xrun);
        } else if (PARAM_IS ("stop-at-session-end")) {
@@ -944,8 +952,6 @@ ARDOUR_UI::parameter_changed (const char* parameter_name)
                map_meter_hold ();
        } else if (PARAM_IS ("meter-falloff")) {
                map_meter_falloff ();
-       } else if (PARAM_IS ("verify-remove-last-capture")) {
-               ActionManager::map_some_state ("options", "VerifyRemoveLastCapture", &Configuration::get_verify_remove_last_capture);
        } else if (PARAM_IS ("video-pullup") || PARAM_IS ("smpte-format")) {
                if (session) {
                        primary_clock.set (session->audible_frame(), true);
index 2fc4488fabfc017350b59e2a1caca2660d3d186f..8ea8aaf87d68ccabcdbe0f2c0da5e04f60218efc 100644 (file)
@@ -2105,16 +2105,16 @@ Editor::set_state (const XMLNode& node)
 
        if ((prop = node.property ("follow-playhead"))) {
                bool yn = (prop->value() == "yes");
+               set_follow_playhead (yn);
                RefPtr<Action> act = ActionManager::get_action (X_("Editor"), X_("toggle-follow-playhead"));
                if (act) {
                        RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
-                       /* do it twice to force the change */
-                       tact->set_active (!yn);
-                       tact->set_active (yn);
+                       if (tact->get_active() != yn) {
+                               tact->set_active (yn);
+                       }
                }
        }
 
-
        if ((prop = node.property ("region-list-sort-type"))) {
                region_list_sort_type = (Editing::RegionListSortType) -1; // force change 
                reset_region_list_sort_type(str2regionlistsorttype(prop->value()));
index 327a2d2e8e504cc4d6e9f23cf5b7ac41c427af55..8748816c316d5e174f6d55a86505c8f961ac379a 100644 (file)
@@ -305,6 +305,7 @@ class Editor : public PublicEditor
        void toggle_xfades_active ();
        void toggle_xfade_visibility ();
        bool xfade_visibility() const { return _xfade_visibility; }
+       void update_xfade_visibility ();
        void update_crossfade_model ();
        void set_crossfade_model (ARDOUR::CrossfadeModel);
 
index 4ce9be20bd9f2766926e8a56110eb6c5f1bcf1f4..3525910250113f973a123dcae067253ec41add13 100644 (file)
@@ -1065,9 +1065,12 @@ Editor::toggle_xfades_active ()
 void
 Editor::toggle_xfade_visibility ()
 {
-       ActionManager::toggle_config_state ("Editor", "toggle-xfades-visibility", &Configuration::set_xfades_visible, &Configuration::get_xfades_visible);
+       ActionManager::toggle_config_state ("Editor", "toggle-xfades-visible", &Configuration::set_xfades_visible, &Configuration::get_xfades_visible);
 }
 
+/** A Configuration parameter has changed.
+ * @param parameter_name Name of the changed parameter.
+ */
 void
 Editor::parameter_changed (const char* parameter_name)
 {
@@ -1092,6 +1095,7 @@ Editor::parameter_changed (const char* parameter_name)
                ActionManager::map_some_state ("Editor", "toggle-xfades-active", &Configuration::get_xfades_active);
        } else if (PARAM_IS ("xfades-visible")) {
                ActionManager::map_some_state ("Editor", "toggle-xfades-visible", &Configuration::get_xfades_visible);
+               update_xfade_visibility ();
        } else if (PARAM_IS ("auto-xfade")) {
                ActionManager::map_some_state ("Editor", "toggle-auto-xfades", &Configuration::get_auto_xfade);
        } else if (PARAM_IS ("xfade-model")) {
index b098815208ae33d662466348d2d2b27bc341a249..917f93243e5f15cf2b3143ac951a4fa4c302f605 100644 (file)
@@ -3535,3 +3535,21 @@ Editor::set_fade_out_active (bool yn)
        }
 }
 
+
+/** Update crossfade visibility after its configuration has been changed */
+void
+Editor::update_xfade_visibility ()
+{
+       _xfade_visibility = Config->get_xfades_visible ();
+       
+       for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
+               AudioTimeAxisView* v = dynamic_cast<AudioTimeAxisView*>(*i);
+               if (v) {
+                       if (_xfade_visibility) {
+                               v->show_all_xfades ();
+                       } else {
+                               v->hide_all_xfades ();
+                       }
+               }
+       }
+}
index cc567f3fb9ed08735d5c6af2bd447b322155625d..2bf641b0890cac1f5bf8478bad7d1d9a43d9e55c 100644 (file)
@@ -1350,6 +1350,10 @@ msgstr "Stoppa insticksprogram vid stopp"
 msgid "Verify remove last capture"
 msgstr "Bekräfta borttagning av senaste inspelade ljudet"
 
+#: gtk2_ardour/ardour_ui_ed.cc:405
+msgid "Make periodic safety backups"
+msgstr "Gör periodiska säkerhetskopior"
+
 #: ../ardour_ui_ed.cc:411
 msgid "Stop recording on xrun"
 msgstr "Stanna inspelning vid xrun-förekomst"
index d46c457fea99554610d7f9e60aa5b8cebd8bfbd2..1351ef9105b261edcfe366c1093a25772ce47685 100644 (file)
@@ -221,6 +221,9 @@ TimeAxisView::show_at (double y, int& nth, VBox *parent)
        order = nth;
        _hidden = false;
        
+       /* height in pixels depends on _order, so update it now we've changed _order */
+       set_height (height_style);
+       
        effective_height = height;
 
        /* now show children */
index 62bf826dc905a1e8c74c1731878e0e782c582d8e..395732e72701b47bad9b24080883136bd5bd255d 100644 (file)
@@ -137,6 +137,8 @@ CONFIG_VARIABLE (bool, use_vst, "use-vst", true)
 CONFIG_VARIABLE (uint32_t, subframes_per_frame, "subframes-per-frame", 100)
 CONFIG_VARIABLE (uint32_t, saved_history_depth, "save-history-depth", 100)
 CONFIG_VARIABLE (bool, use_overlap_equivalency, "use-overlap-equivalency", false)
+CONFIG_VARIABLE (bool, periodic_safety_backups, "periodic-safety-backups", true)
+CONFIG_VARIABLE (uint32_t, periodic_safety_backup_interval, "periodic-safety-backup-interval", 120)
 
 /* BWAV */
 
index 71f990928b6d511d687ba67d3647beaea3e41421..d173f434070ea201de17a04c9270f493ba5f6a00 100644 (file)
@@ -336,6 +336,8 @@ class Session : public PBD::StatefulDestructible
        void disable_record (bool rt_context, bool force = false);
        void step_back_from_record ();
        
+       void maybe_write_autosave ();
+
        /* Proxy signal for region hidden changes */
 
        sigc::signal<void,boost::shared_ptr<Region> > RegionHiddenChange;
index d75758dfb03e4d6c6eb58558aa112d1eee9634b3..f142d57628a1c1bbbb0df231a1be0cf5717aab3d 100644 (file)
@@ -548,7 +548,7 @@ Crossfade::compute (boost::shared_ptr<AudioRegion> a, boost::shared_ptr<AudioReg
 
                        _in = bottom;
                        _out = top;
-                       _anchor_point = StartOfIn;
+                       _anchor_point = EndOfOut;
 
                        if (model == FullCrossfade) {
                                _position = bottom->first_frame(); // "{"
index 609725c20190ec86aa949e37c8ac5d735bcb8e05..e60774e2b1f8d301769468747b84c3476c762dde 100644 (file)
@@ -593,6 +593,14 @@ Session::load_diskstreams (const XMLNode& node)
        return 0;
 }
 
+void
+Session::maybe_write_autosave()
+{
+        if (dirty() && record_status() != Recording) {
+                save_state("", true);
+        }
+}
+
 void
 Session::remove_pending_capture_state ()
 {
@@ -700,7 +708,7 @@ Session::save_state (string snapshot_name, bool pending)
        tmp_path += snapshot_name;
        tmp_path += ".tmp";
 
-       cerr << "actually writing state\n";
+       cerr << "actually writing state to " << xml_path << endl;
 
        if (!tree.write (tmp_path)) {
                error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;