fix incorrect accumulation of export video options each time the dialog is used
[ardour.git] / gtk2_ardour / location_ui.cc
index 68262c1817cb61f88c9616f863fc9da9c12644a8..7f658b9816c13b4ae27dd44968b85c491e275234 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;
@@ -65,12 +65,8 @@ LocationEditRow::LocationEditRow(Session * sess, Location * loc, int32_t num)
 {
        i_am_the_modifier = 0;
 
-       remove_button.set_image (*manage (new Image (Stock::REMOVE, Gtk::ICON_SIZE_MENU)));
-
-       start_to_playhead_button.set_name ("LocationEditCdButton");
-       end_to_playhead_button.set_name ("LocationEditCdButton");
-       locate_to_start_button.set_name ("LocationEditCdButton");
-       locate_to_end_button.set_name ("LocationEditCdButton");
+       remove_button.set_icon (ArdourIcon::CloseCross);
+       remove_button.set_events (remove_button.get_events() & ~(Gdk::ENTER_NOTIFY_MASK|Gdk::LEAVE_NOTIFY_MASK));
 
        number_label.set_name ("LocationEditNumberLabel");
        name_label.set_name ("LocationEditNameLabel");
@@ -79,7 +75,6 @@ LocationEditRow::LocationEditRow(Session * sess, Location * loc, int32_t num)
        hide_check_button.set_name ("LocationEditHideButton");
        lock_check_button.set_name ("LocationEditLockButton");
        glue_check_button.set_name ("LocationEditGlueButton");
-       remove_button.set_name ("LocationEditRemoveButton");
        isrc_label.set_name ("LocationEditNumberLabel");
        isrc_entry.set_name ("LocationEditNameEntry");
        scms_check_button.set_name ("LocationEditCdButton");
@@ -135,30 +130,27 @@ LocationEditRow::LocationEditRow(Session * sess, Location * loc, int32_t num)
        set_session (sess);
 
        start_hbox.set_spacing (2);
+       start_hbox.pack_start (locate_to_start_button, false, false);
        start_hbox.pack_start (start_clock, false, false);
        start_hbox.pack_start (start_to_playhead_button, false, false);
-       start_hbox.pack_start (locate_to_start_button, false, false);
 
        /* this is always in this location, no matter what the location is */
 
-       VBox *rbox = manage (new VBox);
-       rbox->pack_start (remove_button, false, false);
+       item_table.attach (remove_button, 8, 9, 0, 1, SHRINK, SHRINK, 4, 1);
+       item_table.attach (start_hbox, 0, 1, 0, 1, FILL, Gtk::AttachOptions(0), 4, 0);
 
-       item_table.attach (*rbox, 0, 1, 0, 1, FILL, Gtk::AttachOptions (0), 4, 0);
-       item_table.attach (start_hbox, 2, 3, 0, 1, FILL, Gtk::AttachOptions(0), 4, 0);
-
-       start_to_playhead_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &LocationEditRow::to_playhead_button_pressed), LocStart));
-       locate_to_start_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &LocationEditRow::locate_button_pressed), LocStart));
+       start_to_playhead_button.signal_clicked.connect (sigc::bind (sigc::mem_fun (*this, &LocationEditRow::to_playhead_button_pressed), LocStart));
+       locate_to_start_button.signal_clicked.connect (sigc::bind (sigc::mem_fun (*this, &LocationEditRow::locate_button_pressed), LocStart));
        start_clock.ValueChanged.connect (sigc::bind (sigc::mem_fun (*this, &LocationEditRow::clock_changed), LocStart));
        start_clock.signal_button_press_event().connect (sigc::bind (sigc::mem_fun (*this, &LocationEditRow::locate_to_clock), &start_clock), false);
 
        end_hbox.set_spacing (2);
+       end_hbox.pack_start (locate_to_end_button, false, false);
        end_hbox.pack_start (end_clock, false, false);
        end_hbox.pack_start (end_to_playhead_button, false, false);
-       end_hbox.pack_start (locate_to_end_button, false, false);
 
-       end_to_playhead_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &LocationEditRow::to_playhead_button_pressed), LocEnd));
-       locate_to_end_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &LocationEditRow::locate_button_pressed), LocEnd));
+       end_to_playhead_button.signal_clicked.connect (sigc::bind (sigc::mem_fun (*this, &LocationEditRow::to_playhead_button_pressed), LocEnd));
+       locate_to_end_button.signal_clicked.connect (sigc::bind (sigc::mem_fun (*this, &LocationEditRow::locate_button_pressed), LocEnd));
        end_clock.ValueChanged.connect (sigc::bind (sigc::mem_fun (*this, &LocationEditRow::clock_changed), LocEnd));
        end_clock.signal_button_press_event().connect (sigc::bind (sigc::mem_fun (*this, &LocationEditRow::locate_to_clock), &end_clock), false);
 
@@ -169,7 +161,7 @@ LocationEditRow::LocationEditRow(Session * sess, Location * loc, int32_t num)
        lock_check_button.signal_toggled().connect(sigc::mem_fun(*this, &LocationEditRow::lock_toggled));
        glue_check_button.signal_toggled().connect(sigc::mem_fun(*this, &LocationEditRow::glue_toggled));
 
-       remove_button.signal_clicked().connect(sigc::mem_fun(*this, &LocationEditRow::remove_button_pressed));
+       remove_button.signal_clicked.connect(sigc::mem_fun(*this, &LocationEditRow::remove_button_pressed));
 
        pack_start(item_table, true, true);
 
@@ -247,9 +239,9 @@ LocationEditRow::set_location (Location *loc)
        ++i_am_the_modifier;
 
        if (!hide_check_button.get_parent()) {
-               item_table.attach (hide_check_button, 6, 7, 0, 1, FILL, Gtk::FILL, 4, 0);
-               item_table.attach (lock_check_button, 7, 8, 0, 1, FILL, Gtk::FILL, 4, 0);
-               item_table.attach (glue_check_button, 8, 9, 0, 1, FILL, Gtk::FILL, 4, 0);
+               item_table.attach (hide_check_button, 5, 6, 0, 1, FILL, Gtk::FILL, 4, 0);
+               item_table.attach (lock_check_button, 6, 7, 0, 1, FILL, Gtk::FILL, 4, 0);
+               item_table.attach (glue_check_button, 7, 8, 0, 1, FILL, Gtk::FILL, 4, 0);
        }
        hide_check_button.set_active (location->is_hidden());
        lock_check_button.set_active (location->locked());
@@ -264,7 +256,7 @@ LocationEditRow::set_location (Location *loc)
                remove_button.hide ();
 
                if (!name_label.get_parent()) {
-                       item_table.attach (name_label, 1, 2, 0, 1, FILL, FILL, 4, 0);
+                       item_table.attach (name_label, 2, 3, 0, 1, EXPAND|FILL, FILL, 4, 0);
                }
 
                name_label.show();
@@ -277,12 +269,12 @@ LocationEditRow::set_location (Location *loc)
                name_entry.signal_changed().connect (sigc::mem_fun(*this, &LocationEditRow::name_entry_changed));
 
                if (!name_entry.get_parent()) {
-                       item_table.attach (name_entry, 1, 2, 0, 1, FILL | EXPAND, FILL, 4, 0);
+                       item_table.attach (name_entry, 2, 3, 0, 1, FILL | EXPAND, FILL, 4, 0);
                }
                name_entry.show();
 
                if (!cd_check_button.get_parent()) {
-                       item_table.attach (cd_check_button, 5, 6, 0, 1, FILL, Gtk::AttachOptions (0), 4, 0);
+                       item_table.attach (cd_check_button, 4, 5, 0, 1, FILL, Gtk::AttachOptions (0), 4, 0);
                }
 
                if (location->is_session_range()) {
@@ -292,7 +284,7 @@ LocationEditRow::set_location (Location *loc)
                cd_check_button.set_active (location->is_cd_marker());
                cd_check_button.show();
 
-               if (location->start() == _session->current_start_frame()) {
+               if (location->start() == _session->current_start_sample()) {
                        cd_check_button.set_sensitive (false);
                } else {
                        cd_check_button.set_sensitive (true);
@@ -308,10 +300,10 @@ LocationEditRow::set_location (Location *loc)
 
        if (!location->is_mark()) {
                if (!end_hbox.get_parent()) {
-                       item_table.attach (end_hbox, 3, 4, 0, 1, FILL, Gtk::AttachOptions (0), 4, 0);
+                       item_table.attach (end_hbox, 1, 2, 0, 1, FILL, Gtk::AttachOptions (0), 4, 0);
                }
                if (!length_clock.get_parent()) {
-                       end_hbox.pack_start (length_clock, false, false);
+                       end_hbox.pack_start (length_clock, false, false, 4);
                }
 
                end_clock.set (location->end(), true);
@@ -324,20 +316,20 @@ LocationEditRow::set_location (Location *loc)
                        show_cd_track_details ();
                }
 
-               set_tooltip (remove_button, _("Remove this range"));
+               set_tooltip (&remove_button, _("Remove this range"));
                set_tooltip (start_clock, _("Start time - middle click to locate here"));
                set_tooltip (end_clock, _("End time - middle click to locate here"));
                set_tooltip (length_clock, _("Length"));
 
-               set_tooltip (start_to_playhead_button, _("Set range start from playhead location"));
-               set_tooltip (end_to_playhead_button, _("Set range end from playhead location"));
+               set_tooltip (&start_to_playhead_button, _("Set range start from playhead location"));
+               set_tooltip (&end_to_playhead_button, _("Set range end from playhead location"));
 
        } else {
 
-               set_tooltip (remove_button, _("Remove this marker"));
+               set_tooltip (&remove_button, _("Remove this marker"));
                set_tooltip (start_clock, _("Position - middle click to locate here"));
 
-               set_tooltip (start_to_playhead_button, _("Set marker time from playhead location"));
+               set_tooltip (&start_to_playhead_button, _("Set marker time from playhead location"));
 
                end_clock.hide();
                length_clock.hide();
@@ -422,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_sample (), false, true, divisions);
                        break;
                case LocEnd:
-                       location->set_end (_session->transport_frame ());
+                       location->set_end (_session->transport_sample (), false, true,divisions);
+                       if (location->is_session_range()) {
+                               _session->set_end_is_free (false);
+                       }
                        break;
                default:
                        break;
@@ -466,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;
        }
@@ -519,7 +524,7 @@ LocationEditRow::cd_toggled ()
        //}
 
        if (cd_check_button.get_active()) {
-               if (location->start() <= _session->current_start_frame()) {
+               if (location->start() <= _session->current_start_sample()) {
                        error << _("You cannot put a CD marker at the start of the session") << endmsg;
                        cd_check_button.set_active (false);
                        return;
@@ -641,7 +646,7 @@ LocationEditRow::start_changed ()
 
        start_clock.set (location->start());
 
-       if (location->start() == _session->current_start_frame()) {
+       if (location->start() == _session->current_start_sample()) {
                cd_check_button.set_sensitive (false);
        } else {
                cd_check_button.set_sensitive (true);
@@ -745,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::Samples)
+       , _mode_set (false)
+       , _state_node_name (state_node_name)
 {
        i_am_the_modifier = 0;
 
@@ -769,6 +777,7 @@ LocationUI::LocationUI ()
        loop_edit_row.set_clock_group (*_clock_group);
        punch_edit_row.set_clock_group (*_clock_group);
 
+       loop_punch_box.set_border_width (6); // 5 + 1 px framebox-border
        loop_punch_box.pack_start (loop_edit_row, false, false);
        loop_punch_box.pack_start (punch_edit_row, false, false);
 
@@ -810,7 +819,7 @@ LocationUI::LocationUI ()
        table->attach (loc_frame_box, 0, 2, table_row, table_row + 1);
        ++table_row;
 
-       loc_range_panes.pack1 (*table, true, false);
+       loc_range_panes.add (*table);
 
        table = manage (new Table (3, 2));
        table->set_spacings (2);
@@ -842,7 +851,7 @@ LocationUI::LocationUI ()
        table->attach (range_frame_box, 0, 2, table_row, table_row + 1);
        ++table_row;
 
-       loc_range_panes.pack2 (*table, true, false);
+       loc_range_panes.add (*table);
 
        HBox* add_button_box = manage (new HBox);
        add_button_box->pack_start (add_location_button, true, true);
@@ -1038,7 +1047,7 @@ LocationUI::add_new_location()
        string markername;
 
        if (_session) {
-               framepos_t where = _session->audible_frame();
+               samplepos_t where = _session->audible_sample();
                _session->locations()->next_available_name(markername,"mark");
                Location *location = new Location (*_session, where, where, markername, Location::IsMark);
                if (UIConfiguration::instance().get_name_new_markers()) {
@@ -1060,7 +1069,7 @@ LocationUI::add_new_range()
        string rangename;
 
        if (_session) {
-               framepos_t where = _session->audible_frame();
+               samplepos_t where = _session->audible_sample();
                _session->locations()->next_available_name(rangename,"unnamed");
                Location *location = new Location (*_session, where, where, rangename, Location::IsRangeMarker);
                PublicEditor::instance().begin_reversible_command (_("add range marker"));
@@ -1105,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);
@@ -1131,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()->primary_clock->mode();
        }
 
-       XMLProperty* p = node->property (X_("clock-mode"));
-       if (!p) {
-               return ARDOUR_UI::instance()->secondary_clock->mode();
+       if (!node->get_property (X_("clock-mode"), _mode)) {
+               return ARDOUR_UI::instance()->primary_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");