fix stupid MIDI::Manager design to properly handle multiple MIDI ports with the same...
[ardour.git] / gtk2_ardour / editor.cc
index a68f51af4933753373a7f85f5b6e19477d2d6430..3bc2980e153ea58e1183021b5bb5d6310601ca31 100644 (file)
 #include "mixer_strip.h"
 #include "editor_route_groups.h"
 #include "editor_regions.h"
+#include "editor_locations.h"
 #include "editor_snapshots.h"
 
 #include "i18n.h"
@@ -129,9 +130,9 @@ const double Editor::timebar_height = 15.0;
 
 static const gchar *_snap_type_strings[] = {
        N_("CD Frames"),
-       N_("SMPTE Frames"),
-       N_("SMPTE Seconds"),
-       N_("SMPTE Minutes"),
+       N_("Timecode Frames"),
+       N_("Timecode Seconds"),
+       N_("Timecode Minutes"),
        N_("Seconds"),
        N_("Minutes"),
        N_("Beats/32"),
@@ -214,7 +215,7 @@ Editor::Editor ()
          /* time display buttons */
        : minsec_label (_("Mins:Secs"))
        , bbt_label (_("Bars:Beats"))
-       , smpte_label (_("Timecode"))
+       , timecode_label (_("Timecode"))
        , frame_label (_("Samples"))
        , tempo_label (_("Tempo"))
        , meter_label (_("Meter"))
@@ -233,7 +234,6 @@ Editor::Editor ()
 
          /* tool bar related */
 
-       , edit_point_clock (X_("editpoint"), false, X_("EditPointClock"), true)
        , zoom_range_clock (X_("zoomrange"), false, X_("ZoomRangeClock"), true, true)
 
        , toolbar_selection_clock_table (2,3)
@@ -338,7 +338,6 @@ Editor::Editor ()
        _dragging_edit_point = false;
        _dragging_hscrollbar = false;
        select_new_marker = false;
-       zoomed_to_region = false;
        rhythm_ferret = 0;
        _bundle_manager = 0;
        for (ARDOUR::DataType::iterator i = ARDOUR::DataType::begin(); i != ARDOUR::DataType::end(); ++i) {
@@ -381,12 +380,12 @@ Editor::Editor ()
        minsec_label.set_padding (5,0);
        minsec_label.hide ();
        minsec_label.set_no_show_all();
-       smpte_label.set_name ("EditorTimeButton");
-       smpte_label.set_size_request (-1, (int)timebar_height);
-       smpte_label.set_alignment (1.0, 0.5);
-       smpte_label.set_padding (5,0);
-       smpte_label.hide ();
-       smpte_label.set_no_show_all();
+       timecode_label.set_name ("EditorTimeButton");
+       timecode_label.set_size_request (-1, (int)timebar_height);
+       timecode_label.set_alignment (1.0, 0.5);
+       timecode_label.set_padding (5,0);
+       timecode_label.hide ();
+       timecode_label.set_no_show_all();
        frame_label.set_name ("EditorTimeButton");
        frame_label.set_size_request (-1, (int)timebar_height);
        frame_label.set_alignment (1.0, 0.5);
@@ -471,8 +470,6 @@ Editor::Editor ()
 
        build_cursors ();
 
-       edit_point_clock.ValueChanged.connect (mem_fun(*this, &Editor::edit_point_clock_changed));
-
        ArdourCanvas::Canvas* time_pad = manage(new ArdourCanvas::Canvas());
        ArdourCanvas::SimpleLine* pad_line_1 = manage(new ArdourCanvas::SimpleLine(*time_pad->root(),
                        0.0, 1.0, 100.0, 1.0));
@@ -525,22 +522,7 @@ Editor::Editor ()
        _routes = new EditorRoutes (this);
        _regions = new EditorRegions (this);
        _snapshots = new EditorSnapshots (this);
-
-       named_selection_scroller.add (named_selection_display);
-       named_selection_scroller.set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
-
-       named_selection_model = TreeStore::create (named_selection_columns);
-       named_selection_display.set_model (named_selection_model);
-       named_selection_display.append_column (_("Chunks"), named_selection_columns.text);
-       named_selection_display.set_headers_visible (false);
-       named_selection_display.set_size_request (100, -1);
-       named_selection_display.set_name ("NamedSelectionDisplay");
-
-       named_selection_display.get_selection()->set_mode (SELECTION_SINGLE);
-       named_selection_display.set_size_request (100, -1);
-       named_selection_display.signal_button_release_event().connect (mem_fun(*this, &Editor::named_selection_display_button_release), false);
-       named_selection_display.signal_key_release_event().connect (mem_fun(*this, &Editor::named_selection_display_key_release), false);
-       named_selection_display.get_selection()->signal_changed().connect (mem_fun (*this, &Editor::named_selection_display_selection_changed));
+       _locations = new EditorLocations (this);
 
        Gtk::Label* nlabel;
 
@@ -556,19 +538,16 @@ Editor::Editor ()
        nlabel = manage (new Label (_("Route Groups")));
        nlabel->set_angle (-90);
        the_notebook.append_page (_route_groups->widget (), *nlabel);
-
-       if (!Profile->get_sae()) {
-               nlabel = manage (new Label (_("Chunks")));
-               nlabel->set_angle (-90);
-               the_notebook.append_page (named_selection_scroller, *nlabel);
-       }
+       nlabel = manage (new Label (_("Ranges & Marks")));
+       nlabel->set_angle (-90);
+       the_notebook.append_page (_locations->widget (), *nlabel);
 
        the_notebook.set_show_tabs (true);
        the_notebook.set_scrollable (true);
-       the_notebook.popup_enable ();
+       the_notebook.popup_disable ();
        the_notebook.set_tab_pos (Gtk::POS_RIGHT);
        the_notebook.show_all ();
-
+       
        post_maximal_editor_width = 0;
        post_maximal_pane_position = 0;
 
@@ -606,15 +585,15 @@ Editor::Editor ()
        setup_toolbar ();
        setup_midi_toolbar ();
 
-       snap_type = SnapToBeat;
-       set_snap_to (snap_type);
-       snap_mode = SnapOff;
-       set_snap_mode (snap_mode);
+       _snap_type = SnapToBeat;
+       set_snap_to (_snap_type);
+       _snap_mode = SnapOff;
+       set_snap_mode (_snap_mode);
        set_mouse_mode (MouseObject, true);
        set_edit_point_preference (EditAtMouse, true);
 
        XMLNode* node = ARDOUR_UI::instance()->editor_settings();
-       set_state (*node);
+       set_state (*node, Stateful::loading_state_version);
 
        _playlist_selector = new PlaylistSelector();
        _playlist_selector->signal_delete_event().connect (bind (sigc::ptr_fun (just_hide_it), static_cast<Window *> (_playlist_selector)));
@@ -803,27 +782,6 @@ Editor::instant_save ()
        }
 }
 
-void
-Editor::edit_point_clock_changed()
-{
-       if (_dragging_edit_point) {
-               return;
-       }
-
-       if (selection->markers.empty()) {
-               return;
-       }
-
-       bool ignored;
-       Location* loc = find_location_from_marker (selection->markers.front(), ignored);
-
-       if (!loc) {
-               return;
-       }
-
-       loc->move_to (edit_point_clock.current_time());
-}
-
 void
 Editor::zoom_adjustment_changed ()
 {
@@ -1061,7 +1019,7 @@ Editor::connect_to_session (Session *t)
        sensitize_the_right_region_actions (false);
 
        XMLNode* node = ARDOUR_UI::instance()->editor_settings();
-       set_state (*node);
+       set_state (*node, Stateful::loading_state_version);
 
        /* catch up with the playhead */
 
@@ -1081,21 +1039,17 @@ Editor::connect_to_session (Session *t)
        session_connections.push_back (session->PositionChanged.connect (mem_fun(*this, &Editor::map_position_change)));
        session_connections.push_back (session->RouteAdded.connect (mem_fun(*this, &Editor::handle_new_route)));
        session_connections.push_back (session->DurationChanged.connect (mem_fun(*this, &Editor::handle_new_duration)));
-       session_connections.push_back (session->NamedSelectionAdded.connect (mem_fun(*this, &Editor::handle_new_named_selection)));
-       session_connections.push_back (session->NamedSelectionRemoved.connect (mem_fun(*this, &Editor::handle_new_named_selection)));
        session_connections.push_back (session->DirtyChanged.connect (mem_fun(*this, &Editor::update_title)));
        session_connections.push_back (session->StateSaved.connect (mem_fun(*this, &Editor::update_title_s)));
        session_connections.push_back (session->AskAboutPlaylistDeletion.connect (mem_fun(*this, &Editor::playlist_deletion_dialog)));
 
-       session_connections.push_back (session->SMPTEOffsetChanged.connect (mem_fun(*this, &Editor::update_just_smpte)));
+       session_connections.push_back (session->TimecodeOffsetChanged.connect (mem_fun(*this, &Editor::update_just_timecode)));
 
        session_connections.push_back (session->tempo_map().StateChanged.connect (mem_fun(*this, &Editor::tempo_map_changed)));
 
        session_connections.push_back (session->Located.connect (mem_fun (*this, &Editor::located)));
        session_connections.push_back (session->config.ParameterChanged.connect (mem_fun (*this, &Editor::parameter_changed)));
 
-       edit_point_clock.set_mode(AudioClock::BBT);
-       edit_point_clock.set_session (session);
        zoom_range_clock.set_session (session);
        _playlist_selector->set_session (session);
        nudge_clock.set_session (session);
@@ -1109,7 +1063,7 @@ Editor::connect_to_session (Session *t)
                nudge_clock.set (pos, true, 0, AudioClock::BBT);
 
        } else {
-               nudge_clock.set (session->frame_rate() * 5, true, 0, AudioClock::SMPTE); // default of 5 seconds
+               nudge_clock.set (session->frame_rate() * 5, true, 0, AudioClock::Timecode); // default of 5 seconds
        }
 
        playhead_cursor->canvas_item.show ();
@@ -1165,8 +1119,6 @@ Editor::connect_to_session (Session *t)
 
        handle_new_duration ();
 
-       redisplay_named_selections ();
-
        restore_ruler_visibility ();
        //tempo_map_changed (Change (0));
        session->tempo_map().apply_with_metrics (*this, &Editor::draw_metric_marks);
@@ -1177,7 +1129,7 @@ Editor::connect_to_session (Session *t)
 
        start_scrolling ();
 
-       switch (snap_type) {
+       switch (_snap_type) {
        case SnapToRegionStart:
        case SnapToRegionEnd:
        case SnapToRegionSync:
@@ -1198,6 +1150,7 @@ Editor::connect_to_session (Session *t)
        _regions->connect_to_session (session);
        _snapshots->connect_to_session (session);
        _routes->connect_to_session (session);
+       _locations->connect_to_session (session);
 
        start_updating ();
 }
@@ -1706,9 +1659,9 @@ Editor::add_region_context_items (StreamView* sv, boost::shared_ptr<Region> regi
 
                items.push_back (MenuElem (_("Rename"), mem_fun(*this, &Editor::rename_region)));
                if (mr && internal_editing()) {
-                       items.push_back (MenuElem (_("Popup list editor"), mem_fun(*this, &Editor::show_midi_list_editor)));
+                       items.push_back (MenuElem (_("List editor..."), mem_fun(*this, &Editor::show_midi_list_editor)));
                } else {
-                       items.push_back (MenuElem (_("Popup region editor"), mem_fun(*this, &Editor::edit_region)));
+                       items.push_back (MenuElem (_("Region editor"), mem_fun(*this, &Editor::edit_region)));
                }
        }
 
@@ -1716,6 +1669,9 @@ Editor::add_region_context_items (StreamView* sv, boost::shared_ptr<Region> regi
        items.push_back (MenuElem (_("Lower to bottom layer"), mem_fun  (*this, &Editor::lower_region_to_bottom)));
        items.push_back (SeparatorElem());
        items.push_back (MenuElem (_("Define sync point"), mem_fun(*this, &Editor::set_region_sync_from_edit_point)));
+       if (_edit_point == EditAtMouse) {
+               items.back ().set_sensitive (false);
+       }
        items.push_back (MenuElem (_("Remove sync point"), mem_fun(*this, &Editor::remove_region_sync)));
        items.push_back (SeparatorElem());
 
@@ -1949,7 +1905,6 @@ Editor::add_selection_context_items (Menu_Helpers::MenuList& edit_items)
        edit_items.push_back (MenuElem (_("Crop Region to Range"), mem_fun(*this, &Editor::crop_region_to_selection)));
        edit_items.push_back (MenuElem (_("Fill Range with Region"), mem_fun(*this, &Editor::region_fill_selection)));
        edit_items.push_back (MenuElem (_("Duplicate Range"), bind (mem_fun(*this, &Editor::duplicate_dialog), false)));
-       edit_items.push_back (MenuElem (_("Create Chunk from Range"), mem_fun(*this, &Editor::create_named_selection)));
 
        edit_items.push_back (SeparatorElem());
        edit_items.push_back (MenuElem (_("Consolidate Range"), bind (mem_fun(*this, &Editor::bounce_range_selection), true, false)));
@@ -2020,8 +1975,6 @@ Editor::add_dstream_context_items (Menu_Helpers::MenuList& edit_items)
 
        cutnpaste_items.push_back (SeparatorElem());
 
-       cutnpaste_items.push_back (MenuElem (_("Insert chunk"), bind (mem_fun(*this, &Editor::paste_named_selection), 1.0f)));
-
        edit_items.push_back (MenuElem (_("Edit"), *cutnpaste_menu));
 
        /* Adding new material */
@@ -2101,16 +2054,28 @@ Editor::add_bus_context_items (Menu_Helpers::MenuList& edit_items)
        edit_items.push_back (MenuElem (_("Nudge"), *nudge_menu));
 }
 
+SnapType
+Editor::snap_type() const
+{
+       return _snap_type;
+}
+
+SnapMode
+Editor::snap_mode() const
+{
+       return _snap_mode;
+}
+
 void
 Editor::set_snap_to (SnapType st)
 {
        unsigned int snap_ind = (unsigned int)st;
 
-       snap_type = st;
+       _snap_type = st;
 
        if (snap_ind > snap_type_strings.size() - 1) {
                snap_ind = 0;
-               snap_type = (SnapType)snap_ind;
+               _snap_type = (SnapType)snap_ind;
        }
 
        string str = snap_type_strings[snap_ind];
@@ -2121,7 +2086,7 @@ Editor::set_snap_to (SnapType st)
 
        instant_save ();
 
-       switch (snap_type) {
+       switch (_snap_type) {
        case SnapToAThirtysecondBeat:
        case SnapToASixteenthBeat:
        case SnapToAEighthBeat:
@@ -2147,7 +2112,7 @@ Editor::set_snap_to (SnapType st)
 void
 Editor::set_snap_mode (SnapMode mode)
 {
-       snap_mode = mode;
+       _snap_mode = mode;
        string str = snap_mode_strings[(int)mode];
 
        if (str != snap_mode_selector.get_active_text ()) {
@@ -2226,7 +2191,7 @@ Editor::set_edit_point_preference (EditPoint ep, bool force)
 }
 
 int
-Editor::set_state (const XMLNode& node)
+Editor::set_state (const XMLNode& node, int /*version*/)
 {
        const XMLProperty* prop;
        XMLNode* geometry;
@@ -2474,9 +2439,9 @@ Editor::get_state ()
        node->add_property ("zoom-focus", buf);
        snprintf (buf, sizeof(buf), "%f", frames_per_unit);
        node->add_property ("zoom", buf);
-       snprintf (buf, sizeof(buf), "%d", (int) snap_type);
+       snprintf (buf, sizeof(buf), "%d", (int) _snap_type);
        node->add_property ("snap-to", buf);
-       snprintf (buf, sizeof(buf), "%d", (int) snap_mode);
+       snprintf (buf, sizeof(buf), "%d", (int) _snap_mode);
        node->add_property ("snap-mode", buf);
 
        node->add_property ("edit-point", enum_2_string (_edit_point));
@@ -2541,11 +2506,11 @@ Editor::snap_to_with_modifier (nframes64_t& start, GdkEvent const * event, int32
        }
 
        if (Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
-               if (snap_mode == SnapOff) {
+               if (_snap_mode == SnapOff) {
                        snap_to_internal (start, direction, for_mark);
                }
        } else {
-               if (snap_mode != SnapOff) {
+               if (_snap_mode != SnapOff) {
                        snap_to_internal (start, direction, for_mark);
                }
        }
@@ -2554,7 +2519,7 @@ Editor::snap_to_with_modifier (nframes64_t& start, GdkEvent const * event, int32
 void
 Editor::snap_to (nframes64_t& start, int32_t direction, bool for_mark)
 {
-       if (!session || snap_mode == SnapOff) {
+       if (!session || _snap_mode == SnapOff) {
                return;
        }
 
@@ -2562,72 +2527,86 @@ Editor::snap_to (nframes64_t& start, int32_t direction, bool for_mark)
 }
 
 void
-Editor::snap_to_internal (nframes64_t& start, int32_t direction, bool for_mark)
+Editor::timecode_snap_to_internal (nframes64_t& start, int32_t direction, bool /*for_mark*/)
 {
-       Location* before = 0;
-       Location* after = 0;
-
-       const nframes64_t one_second = session->frame_rate();
-       const nframes64_t one_minute = session->frame_rate() * 60;
-       const nframes64_t one_smpte_second = (nframes64_t)(rint(session->smpte_frames_per_second()) * session->frames_per_smpte_frame());
-       nframes64_t one_smpte_minute = (nframes64_t)(rint(session->smpte_frames_per_second()) * session->frames_per_smpte_frame() * 60);
-       nframes64_t presnap = start;
+       const nframes64_t one_timecode_second = (nframes64_t)(rint(session->timecode_frames_per_second()) * session->frames_per_timecode_frame());
+       nframes64_t one_timecode_minute = (nframes64_t)(rint(session->timecode_frames_per_second()) * session->frames_per_timecode_frame() * 60);
 
-       switch (snap_type) {
-       case SnapToCDFrame:
-               if (((direction == 0) && (start % (one_second/75) > (one_second/75) / 2)) || (direction > 0)) {
-                       start = (nframes64_t) ceil ((double) start / (one_second / 75)) * (one_second / 75);
-               } else {
-                       start = (nframes64_t) floor ((double) start / (one_second / 75)) * (one_second / 75);
-               }
-               break;
-
-       case SnapToSMPTEFrame:
-               if (((direction == 0) && (fmod((double)start, (double)session->frames_per_smpte_frame()) > (session->frames_per_smpte_frame() / 2))) || (direction > 0)) {
-                       start = (nframes64_t) (ceil ((double) start / session->frames_per_smpte_frame()) * session->frames_per_smpte_frame());
+       switch (_snap_type) {
+       case SnapToTimecodeFrame:
+               if (((direction == 0) && (fmod((double)start, (double)session->frames_per_timecode_frame()) > (session->frames_per_timecode_frame() / 2))) || (direction > 0)) {
+                       start = (nframes64_t) (ceil ((double) start / session->frames_per_timecode_frame()) * session->frames_per_timecode_frame());
                } else {
-                       start = (nframes64_t) (floor ((double) start / session->frames_per_smpte_frame()) *  session->frames_per_smpte_frame());
+                       start = (nframes64_t) (floor ((double) start / session->frames_per_timecode_frame()) *  session->frames_per_timecode_frame());
                }
                break;
 
-       case SnapToSMPTESeconds:
-               if (session->smpte_offset_negative())
+       case SnapToTimecodeSeconds:
+               if (session->timecode_offset_negative())
                {
-                       start += session->smpte_offset ();
+                       start += session->timecode_offset ();
                } else {
-                       start -= session->smpte_offset ();
+                       start -= session->timecode_offset ();
                }
-               if (((direction == 0) && (start % one_smpte_second > one_smpte_second / 2)) || direction > 0) {
-                       start = (nframes64_t) ceil ((double) start / one_smpte_second) * one_smpte_second;
+               if (((direction == 0) && (start % one_timecode_second > one_timecode_second / 2)) || direction > 0) {
+                       start = (nframes64_t) ceil ((double) start / one_timecode_second) * one_timecode_second;
                } else {
-                       start = (nframes64_t) floor ((double) start / one_smpte_second) * one_smpte_second;
+                       start = (nframes64_t) floor ((double) start / one_timecode_second) * one_timecode_second;
                }
 
-               if (session->smpte_offset_negative())
+               if (session->timecode_offset_negative())
                {
-                       start -= session->smpte_offset ();
+                       start -= session->timecode_offset ();
                } else {
-                       start += session->smpte_offset ();
+                       start += session->timecode_offset ();
                }
                break;
 
-       case SnapToSMPTEMinutes:
-               if (session->smpte_offset_negative())
+       case SnapToTimecodeMinutes:
+               if (session->timecode_offset_negative())
                {
-                       start += session->smpte_offset ();
+                       start += session->timecode_offset ();
                } else {
-                       start -= session->smpte_offset ();
+                       start -= session->timecode_offset ();
                }
-               if (((direction == 0) && (start % one_smpte_minute > one_smpte_minute / 2)) || direction > 0) {
-                       start = (nframes64_t) ceil ((double) start / one_smpte_minute) * one_smpte_minute;
+               if (((direction == 0) && (start % one_timecode_minute > one_timecode_minute / 2)) || direction > 0) {
+                       start = (nframes64_t) ceil ((double) start / one_timecode_minute) * one_timecode_minute;
                } else {
-                       start = (nframes64_t) floor ((double) start / one_smpte_minute) * one_smpte_minute;
+                       start = (nframes64_t) floor ((double) start / one_timecode_minute) * one_timecode_minute;
                }
-               if (session->smpte_offset_negative())
+               if (session->timecode_offset_negative())
                {
-                       start -= session->smpte_offset ();
+                       start -= session->timecode_offset ();
                } else {
-                       start += session->smpte_offset ();
+                       start += session->timecode_offset ();
+               }
+               break;
+       default:
+               fatal << "Editor::smpte_snap_to_internal() called with non-timecode snap type!" << endmsg;
+               /*NOTREACHED*/
+       }
+}
+
+void
+Editor::snap_to_internal (nframes64_t& start, int32_t direction, bool for_mark)
+{
+       const nframes64_t one_second = session->frame_rate();
+       const nframes64_t one_minute = session->frame_rate() * 60;
+       nframes64_t presnap = start;
+       nframes64_t before;
+       nframes64_t after;
+
+       switch (_snap_type) {
+       case SnapToTimecodeFrame:
+       case SnapToTimecodeSeconds:
+       case SnapToTimecodeMinutes:
+               return timecode_snap_to_internal (start, direction, for_mark);
+
+       case SnapToCDFrame:
+               if (((direction == 0) && (start % (one_second/75) > (one_second/75) / 2)) || (direction > 0)) {
+                       start = (nframes64_t) ceil ((double) start / (one_second / 75)) * (one_second / 75);
+               } else {
+                       start = (nframes64_t) floor ((double) start / (one_second / 75)) * (one_second / 75);
                }
                break;
 
@@ -2680,39 +2659,21 @@ Editor::snap_to_internal (nframes64_t& start, int32_t direction, bool for_mark)
                        return;
                }
 
-               before = session->locations()->first_location_before (start);
-               after = session->locations()->first_location_after (start);
+               session->locations()->marks_either_side (start, before, after);
 
-               if (direction < 0) {
-                       if (before) {
-                               start = before->start();
-                       } else {
-                               start = 0;
-                       }
-               } else if (direction > 0) {
-                       if (after) {
-                               start = after->start();
+               if (before == max_frames) {
+                       start = after;
+               } else if (after == max_frames) {
+                       start = before;
+               } else if (before != max_frames && after != max_frames) {
+                       /* have before and after */
+                       if ((start - before) < (after - start)) {
+                               start = before;
                        } else {
-                               start = session->current_end_frame();
-                       }
-               } else {
-                       if (before) {
-                               if (after) {
-                                       /* find nearest of the two */
-                                       if ((start - before->start()) < (after->start() - start)) {
-                                               start = before->start();
-                                       } else {
-                                               start = after->start();
-                                       }
-                               } else {
-                                       start = before->start();
-                               }
-                       } else if (after) {
-                               start = after->start();
-                       } else {
-                               /* relax */
+                               start = after;
                        }
                }
+
                break;
 
        case SnapToRegionStart:
@@ -2747,7 +2708,7 @@ Editor::snap_to_internal (nframes64_t& start, int32_t direction, bool for_mark)
                break;
        }
 
-       switch (snap_mode) {
+       switch (_snap_mode) {
        case SnapNormal:
                return;
 
@@ -2865,20 +2826,17 @@ Editor::setup_toolbar ()
        zoom_box.set_border_width (0);
 
        zoom_in_button.set_name ("EditorTimeButton");
-       zoom_in_button.set_size_request(-1,16);
-       zoom_in_button.add (*(manage (new Image (::get_icon("zoom_in")))));
+       zoom_in_button.set_image (*(manage (new Image (Stock::ZOOM_IN, Gtk::ICON_SIZE_BUTTON))));
        zoom_in_button.signal_clicked().connect (bind (mem_fun(*this, &Editor::temporal_zoom_step), false));
        ARDOUR_UI::instance()->tooltips().set_tip (zoom_in_button, _("Zoom In"));
 
        zoom_out_button.set_name ("EditorTimeButton");
-       zoom_out_button.set_size_request(-1,16);
-       zoom_out_button.add (*(manage (new Image (::get_icon("zoom_out")))));
+       zoom_out_button.set_image (*(manage (new Image (Stock::ZOOM_OUT, Gtk::ICON_SIZE_BUTTON))));
        zoom_out_button.signal_clicked().connect (bind (mem_fun(*this, &Editor::temporal_zoom_step), true));
        ARDOUR_UI::instance()->tooltips().set_tip (zoom_out_button, _("Zoom Out"));
 
        zoom_out_full_button.set_name ("EditorTimeButton");
-       zoom_out_full_button.set_size_request(-1,16);
-       zoom_out_full_button.add (*(manage (new Image (::get_icon("zoom_full")))));
+       zoom_out_full_button.set_image (*(manage (new Image (Stock::ZOOM_100, Gtk::ICON_SIZE_BUTTON))));
        zoom_out_full_button.signal_clicked().connect (mem_fun(*this, &Editor::temporal_zoom_session));
        ARDOUR_UI::instance()->tooltips().set_tip (zoom_out_full_button, _("Zoom to Session"));
 
@@ -2934,7 +2892,6 @@ Editor::setup_toolbar ()
        edit_point_selector.signal_changed().connect (mem_fun(*this, &Editor::edit_point_selection_done));
        ARDOUR_UI::instance()->tooltips().set_tip (edit_point_selector, _("Edit point"));
 
-       snap_box.pack_start (edit_point_clock, false, false);
        snap_box.pack_start (snap_mode_selector, false, false);
        snap_box.pack_start (snap_type_selector, false, false);
        snap_box.pack_start (edit_point_selector, false, false);
@@ -3020,6 +2977,7 @@ Editor::setup_midi_toolbar ()
 
        act = ActionManager::get_action (X_("MIDI"), X_("panic"));
        midi_panic_button.set_name("MidiPanicButton");
+       ARDOUR_UI::instance()->tooltips().set_tip (midi_panic_button, _("Send note off and reset controller messages on all MIDI channels"));
        act->connect_proxy (midi_panic_button);
 
        panic_box.pack_start (midi_sound_notes , true, true);
@@ -3275,7 +3233,7 @@ Editor::duplicate_dialog (bool with_dialog)
 
        if (with_dialog) {
 
-               ArdourDialog win ("Duplication Dialog");
+               ArdourDialog win ("Duplicate");
                Label  label (_("Number of Duplications:"));
                Adjustment adjustment (1.0, 1.0, 1000000.0, 1.0, 5.0);
                SpinButton spinner (adjustment, 0.0, 1);
@@ -3479,12 +3437,12 @@ Editor::snap_type_selection_done ()
                snaptype = SnapToRegionSync;
        } else if (choice == _("CD Frames")) {
                snaptype = SnapToCDFrame;
-       } else if (choice == _("SMPTE Frames")) {
-               snaptype = SnapToSMPTEFrame;
-       } else if (choice == _("SMPTE Seconds")) {
-               snaptype = SnapToSMPTESeconds;
-       } else if (choice == _("SMPTE Minutes")) {
-               snaptype = SnapToSMPTEMinutes;
+       } else if (choice == _("Timecode Frames")) {
+               snaptype = SnapToTimecodeFrame;
+       } else if (choice == _("Timecode Seconds")) {
+               snaptype = SnapToTimecodeSeconds;
+       } else if (choice == _("Timecode Minutes")) {
+               snaptype = SnapToTimecodeMinutes;
        } else if (choice == _("Seconds")) {
                snaptype = SnapToSeconds;
        } else if (choice == _("Minutes")) {
@@ -3837,7 +3795,7 @@ Editor::get_grid_type_as_beats (bool& success, nframes64_t position)
 {
        success = true;
 
-       switch (snap_type) {
+       switch (_snap_type) {
        case SnapToBeat:
                return 1.0;
                break;
@@ -3869,9 +3827,9 @@ Editor::get_grid_type_as_beats (bool& success, nframes64_t position)
                break;
 
        case SnapToCDFrame:
-       case SnapToSMPTEFrame:
-       case SnapToSMPTESeconds:
-       case SnapToSMPTEMinutes:
+       case SnapToTimecodeFrame:
+       case SnapToTimecodeSeconds:
+       case SnapToTimecodeMinutes:
        case SnapToSeconds:
        case SnapToMinutes:
        case SnapToRegionStart:
@@ -4179,7 +4137,6 @@ Editor::current_visual_state (bool with_tracks)
        vs->frames_per_unit = frames_per_unit;
        vs->leftmost_frame = leftmost_frame;
        vs->zoom_focus = zoom_focus;
-       vs->zoomed_to_region = zoomed_to_region;
 
        if (with_tracks) {
                for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
@@ -4237,7 +4194,6 @@ Editor::use_visual_state (VisualState& vs)
 
        set_zoom_focus (vs.zoom_focus);
        reposition_and_zoom (vs.leftmost_frame, vs.frames_per_unit);
-       zoomed_to_region = vs.zoomed_to_region;
 
        for (list<TAVState>::iterator i = vs.track_states.begin(); i != vs.track_states.end(); ++i) {
                TrackViewList::iterator t;
@@ -4245,7 +4201,7 @@ Editor::use_visual_state (VisualState& vs)
                /* check if the track still exists - it could have been deleted */
 
                if ((t = find (track_views.begin(), track_views.end(), i->first)) != track_views.end()) {
-                       (*t)->set_state (*(i->second));
+                       (*t)->set_state (*(i->second), Stateful::loading_state_version);
                }
        }
 
@@ -4946,7 +4902,13 @@ Editor::remove_route (TimeAxisView *tv)
        ENSURE_GUI_THREAD(bind (mem_fun(*this, &Editor::remove_route), tv));
 
        TrackViewList::iterator i;
+
        boost::shared_ptr<Route> route;
+       RouteTimeAxisView* rtav = dynamic_cast<RouteTimeAxisView*> (tv);
+       if (rtav) {
+               route = rtav->route ();
+       }
+               
        TimeAxisView* next_tv = 0;
 
        if (tv == entered_track) {