GenericUI: subscribe to property changes before querying values
[ardour.git] / gtk2_ardour / location_ui.cc
index ba2ef5792d5fad99f5ab48797beb602a2fc6563c..658b7326d9a25ff6b0fc1e5a8b17ea5776706dc0 100644 (file)
 
 #include "ardour/session.h"
 #include "pbd/memento_command.h"
+#include "widgets/tooltips.h"
 
 #include "ardour_ui.h"
 #include "clock_group.h"
+#include "enums_convert.h"
 #include "main_clock.h"
 #include "gui_thread.h"
 #include "keyboard.h"
 #include "location_ui.h"
-#include "prompter.h"
 #include "utils.h"
 #include "public_editor.h"
-#include "tooltips.h"
 #include "ui_config.h"
 
-#include "i18n.h"
+#include "pbd/i18n.h"
 
 using namespace std;
 using namespace ARDOUR;
-using namespace ARDOUR_UI_UTILS;
+using namespace ArdourWidgets;
 using namespace PBD;
 using namespace Gtk;
 using namespace Gtkmm2ext;
@@ -414,12 +414,17 @@ LocationEditRow::to_playhead_button_pressed (LocationPart part)
                return;
        }
 
+       const int32_t divisions = PublicEditor::instance().get_grid_music_divisions (0);
+
        switch (part) {
                case LocStart:
-                       location->set_start (_session->transport_frame ());
+                       location->set_start (_session->transport_frame (), false, true, divisions);
                        break;
                case LocEnd:
-                       location->set_end (_session->transport_frame ());
+                       location->set_end (_session->transport_frame (), false, true,divisions);
+                       if (location->is_session_range()) {
+                               _session->set_end_is_free (false);
+                       }
                        break;
                default:
                        break;
@@ -458,15 +463,23 @@ LocationEditRow::clock_changed (LocationPart part)
                return;
        }
 
+       const int32_t divisions = PublicEditor::instance().get_grid_music_divisions (0);
+
        switch (part) {
                case LocStart:
-                       location->set_start (start_clock.current_time());
+                       location->set_start (start_clock.current_time(), false, true, divisions);
                        break;
                case LocEnd:
-                       location->set_end (end_clock.current_time());
+                       location->set_end (end_clock.current_time(), false, true, divisions);
+                       if (location->is_session_range()) {
+                               _session->set_end_is_free (false);
+                       }
                        break;
                case LocLength:
-                       location->set_end (location->start() + length_clock.current_duration());
+                       location->set_end (location->start() + length_clock.current_duration(), false, true, divisions);
+                       if (location->is_session_range()) {
+                               _session->set_end_is_free (false);
+                       }
                default:
                        break;
        }
@@ -737,9 +750,12 @@ LocationEditRow::set_clock_editable_status ()
 
 /*------------------------------------------------------------------------*/
 
-LocationUI::LocationUI ()
+LocationUI::LocationUI (std::string state_node_name)
        : add_location_button (_("New Marker"))
        , add_range_button (_("New Range"))
+       , _mode (AudioClock::Frames)
+       , _mode_set (false)
+       , _state_node_name (state_node_name)
 {
        i_am_the_modifier = 0;
 
@@ -1098,6 +1114,8 @@ LocationUI::set_session(ARDOUR::Session* s)
                _session->locations()->changed.connect (_session_connections, invalidator (*this), boost::bind (&LocationUI::refresh_location_list, this), gui_context());
 
                _clock_group->set_clock_mode (clock_mode_from_session_instant_xml ());
+       } else {
+               _mode_set = false;
        }
 
        loop_edit_row.set_session (s);
@@ -1124,38 +1142,60 @@ LocationUI::session_going_away()
        punch_edit_row.set_session (0);
        punch_edit_row.set_location (0);
 
+       _mode_set = false;
+
        SessionHandlePtr::session_going_away ();
 }
 
 XMLNode &
 LocationUI::get_state () const
 {
-       XMLNode* node = new XMLNode (X_("LocationUI"));
-       node->add_property (X_("clock-mode"), enum_2_string (_clock_group->clock_mode ()));
+       XMLNode* node = new XMLNode (_state_node_name);
+       node->set_property (X_("clock-mode"), _clock_group->clock_mode ());
        return *node;
 }
 
+int
+LocationUI::set_state (const XMLNode& node)
+{
+       if (node.name() != _state_node_name) {
+               return -1;
+       }
+
+       if (!node.get_property (X_("clock-mode"), _mode)) {
+               return -1;
+       }
+
+       _mode_set = true;
+       _clock_group->set_clock_mode (_mode);
+       return 0;
+}
+
 AudioClock::Mode
-LocationUI::clock_mode_from_session_instant_xml () const
+LocationUI::clock_mode_from_session_instant_xml ()
 {
-       XMLNode* node = _session->instant_xml (X_("LocationUI"));
+       if (_mode_set) {
+               return _mode;
+       }
+
+       XMLNode* node = _session->instant_xml (_state_node_name);
        if (!node) {
-               return AudioClock::Frames;
+               return ARDOUR_UI::instance()->secondary_clock->mode();
        }
 
-       XMLProperty const * p = node->property (X_("clock-mode"));
-       if (!p) {
+       if (!node->get_property (X_("clock-mode"), _mode)) {
                return ARDOUR_UI::instance()->secondary_clock->mode();
        }
 
-       return (AudioClock::Mode) string_2_enum (p->value (), AudioClock::Mode);
+       _mode_set = true;
+       return _mode;
 }
 
 
 /*------------------------*/
 
 LocationUIWindow::LocationUIWindow ()
-       : ArdourWindow (_("Locations"))
+       : ArdourWindow (S_("Ranges|Locations"))
 {
        set_wmclass(X_("ardour_locations"), PROGRAM_NAME);
        set_name ("LocationWindow");