Merge branch 'master' into cairocanvas
[ardour.git] / gtk2_ardour / editor.cc
index acbb792db50aab15c9310c6d3bdd5898643df9ae..f3e14f3390c46636c986397ddc35d158a1878988 100644 (file)
@@ -44,6 +44,7 @@
 #include "pbd/memento_command.h"
 #include "pbd/unknown_type.h"
 #include "pbd/unwind.h"
+#include "pbd/stacktrace.h"
 
 #include <glibmm/miscutils.h>
 #include <gtkmm/image.h>
@@ -69,6 +70,9 @@
 #include "ardour/tempo.h"
 #include "ardour/utils.h"
 
+#include "canvas/debug.h"
+#include "canvas/text.h"
+
 #include "control_protocol/control_protocol.h"
 
 #include "actions.h"
@@ -80,8 +84,6 @@
 #include "audio_time_axis.h"
 #include "automation_time_axis.h"
 #include "bundle_manager.h"
-#include "canvas-noevent-text.h"
-#include "canvas_impl.h"
 #include "crossfade_edit.h"
 #include "debug.h"
 #include "editing.h"
 #include "rhythm_ferret.h"
 #include "selection.h"
 #include "sfdb_ui.h"
-#include "simpleline.h"
 #include "tempo_lines.h"
 #include "time_axis_view.h"
 #include "utils.h"
@@ -245,6 +246,7 @@ Editor::Editor ()
        , range_mark_label (_("Range Markers"))
        , transport_mark_label (_("Loop/Punch Ranges"))
        , cd_mark_label (_("CD Markers"))
+       , videotl_label (_("Video Timeline"))
        , edit_packer (4, 4, true)
 
          /* the values here don't matter: layout widgets
@@ -312,8 +314,8 @@ Editor::Editor ()
 
        snap_threshold = 5.0;
        bbt_beat_subdivision = 4;
-       _canvas_width = 0;
-       _canvas_height = 0;
+       _visible_canvas_width = 0;
+       _visible_canvas_height = 0;
        last_autoscroll_x = 0;
        last_autoscroll_y = 0;
        autoscroll_active = false;
@@ -375,7 +377,7 @@ Editor::Editor ()
        _internal_editing = false;
        current_canvas_cursor = 0;
 
-       frames_per_unit = 2048; /* too early to use reset_zoom () */
+       frames_per_pixel = 2048; /* too early to use reset_zoom () */
 
        _scroll_callbacks = 0;
 
@@ -383,67 +385,75 @@ Editor::Editor ()
        set_zoom_focus (ZoomFocusLeft);
        zoom_range_clock->ValueChanged.connect (sigc::mem_fun(*this, &Editor::zoom_adjustment_changed));
 
-       bbt_label.set_name ("EditorTimeButton");
+       bbt_label.set_name ("EditorRulerLabel");
        bbt_label.set_size_request (-1, (int)timebar_height);
        bbt_label.set_alignment (1.0, 0.5);
        bbt_label.set_padding (5,0);
        bbt_label.hide ();
        bbt_label.set_no_show_all();
-       minsec_label.set_name ("EditorTimeButton");
+       minsec_label.set_name ("EditorRulerLabel");
        minsec_label.set_size_request (-1, (int)timebar_height);
        minsec_label.set_alignment (1.0, 0.5);
        minsec_label.set_padding (5,0);
        minsec_label.hide ();
        minsec_label.set_no_show_all();
-       timecode_label.set_name ("EditorTimeButton");
+       timecode_label.set_name ("EditorRulerLabel");
        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();
-       samples_label.set_name ("EditorTimeButton");
+       samples_label.set_name ("EditorRulerLabel");
        samples_label.set_size_request (-1, (int)timebar_height);
        samples_label.set_alignment (1.0, 0.5);
        samples_label.set_padding (5,0);
        samples_label.hide ();
        samples_label.set_no_show_all();
 
-       tempo_label.set_name ("EditorTimeButton");
+       tempo_label.set_name ("EditorRulerLabel");
        tempo_label.set_size_request (-1, (int)timebar_height);
        tempo_label.set_alignment (1.0, 0.5);
        tempo_label.set_padding (5,0);
        tempo_label.hide();
        tempo_label.set_no_show_all();
 
-       meter_label.set_name ("EditorTimeButton");
+       meter_label.set_name ("EditorRulerLabel");
        meter_label.set_size_request (-1, (int)timebar_height);
        meter_label.set_alignment (1.0, 0.5);
        meter_label.set_padding (5,0);
        meter_label.hide();
        meter_label.set_no_show_all();
 
-       mark_label.set_name ("EditorTimeButton");
+       mark_label.set_name ("EditorRulerLabel");
        mark_label.set_size_request (-1, (int)timebar_height);
        mark_label.set_alignment (1.0, 0.5);
        mark_label.set_padding (5,0);
        mark_label.hide();
        mark_label.set_no_show_all();
 
-       cd_mark_label.set_name ("EditorTimeButton");
+       cd_mark_label.set_name ("EditorRulerLabel");
        cd_mark_label.set_size_request (-1, (int)timebar_height);
        cd_mark_label.set_alignment (1.0, 0.5);
        cd_mark_label.set_padding (5,0);
        cd_mark_label.hide();
        cd_mark_label.set_no_show_all();
 
-       range_mark_label.set_name ("EditorTimeButton");
+       videotl_bar_height = 4;
+       videotl_label.set_name ("EditorRulerLabel");
+       videotl_label.set_size_request (-1, (int)timebar_height * videotl_bar_height);
+       videotl_label.set_alignment (1.0, 0.5);
+       videotl_label.set_padding (5,0);
+       videotl_label.hide();
+       videotl_label.set_no_show_all();
+
+       range_mark_label.set_name ("EditorRulerLabel");
        range_mark_label.set_size_request (-1, (int)timebar_height);
        range_mark_label.set_alignment (1.0, 0.5);
        range_mark_label.set_padding (5,0);
        range_mark_label.hide();
        range_mark_label.set_no_show_all();
 
-       transport_mark_label.set_name ("EditorTimeButton");
+       transport_mark_label.set_name ("EditorRulerLabel");
        transport_mark_label.set_size_request (-1, (int)timebar_height);
        transport_mark_label.set_alignment (1.0, 0.5);
        transport_mark_label.set_padding (5,0);
@@ -465,7 +475,7 @@ Editor::Editor ()
 
        edit_controls_vbox.set_spacing (0);
        vertical_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &Editor::tie_vertical_scrolling), true);
-       track_canvas->signal_map_event().connect (sigc::mem_fun (*this, &Editor::track_canvas_map_handler));
+       _track_canvas->signal_map_event().connect (sigc::mem_fun (*this, &Editor::track_canvas_map_handler));
 
        HBox* h = manage (new HBox);
        _group_tabs = new EditorGroupTabs (this);
@@ -482,13 +492,14 @@ Editor::Editor ()
 
        _cursors = new MouseCursors;
 
-       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));
+       ArdourCanvas::GtkCanvas* time_pad = manage (new ArdourCanvas::GtkCanvas ());
 
-       pad_line_1->property_color_rgba() = 0xFF0000FF;
+       ArdourCanvas::Line* pad_line_1 = new ArdourCanvas::Line (time_pad->root());
+       pad_line_1->set (ArdourCanvas::Duple (0.0, 1.0), ArdourCanvas::Duple (100.0, 1.0));
+       pad_line_1->set_outline_color (0xFF0000FF);
        pad_line_1->show();
 
+       // CAIROCANVAS
        time_pad->show();
 
        time_canvas_vbox.set_size_request (-1, (int)(timebar_height * visible_timebars) + 2);
@@ -498,15 +509,15 @@ Editor::Editor ()
        ruler_label_event_box.set_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
        ruler_label_event_box.signal_button_release_event().connect (sigc::mem_fun(*this, &Editor::ruler_label_button_release));
 
-       time_button_event_box.add (time_button_vbox);
-       time_button_event_box.set_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
-       time_button_event_box.signal_button_release_event().connect (sigc::mem_fun(*this, &Editor::ruler_label_button_release));
+       time_bars_event_box.add (time_bars_vbox);
+       time_bars_event_box.set_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
+       time_bars_event_box.signal_button_release_event().connect (sigc::mem_fun(*this, &Editor::ruler_label_button_release));
 
        /* these enable us to have a dedicated window (for cursor setting, etc.)
           for the canvas areas.
        */
 
-       track_canvas_event_box.add (*track_canvas);
+       track_canvas_event_box.add (*_track_canvas_viewport);
 
        time_canvas_event_box.add (time_canvas_vbox);
        time_canvas_event_box.set_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::POINTER_MOTION_MASK);
@@ -519,14 +530,16 @@ Editor::Editor ()
 
        /* labels for the rulers */
        edit_packer.attach (ruler_label_event_box,   1, 2, 0, 1,    FILL,        SHRINK, 0, 0);
-       /* labels for the marker "tracks" */
-       edit_packer.attach (time_button_event_box,   1, 2, 1, 2,    FILL,        SHRINK, 0, 0);
+       /* labels for the marker "tracks" (time bars) */
+       edit_packer.attach (time_bars_event_box,     1, 2, 1, 2,    FILL,        SHRINK, 0, 0);
        /* the rulers */
        edit_packer.attach (time_canvas_event_box,   2, 3, 0, 1,    FILL|EXPAND, FILL, 0, 0);
        /* track controls */
        edit_packer.attach (controls_layout,         0, 2, 2, 3,    FILL,        FILL|EXPAND, 0, 0);
-       /* main canvas */
-       edit_packer.attach (track_canvas_event_box,  2, 3, 1, 3,    FILL|EXPAND, FILL|EXPAND, 0, 0);
+       /* time bars canvas */
+       edit_packer.attach (*_time_bars_canvas_viewport, 2, 3, 1, 2,    FILL,    FILL, 0, 0);
+       /* track canvas */
+       edit_packer.attach (track_canvas_event_box,  2, 3, 2, 3,    FILL|EXPAND, FILL|EXPAND, 0, 0);
 
        bottom_hbox.set_border_width (2);
        bottom_hbox.set_spacing (3);
@@ -771,7 +784,7 @@ Editor::~Editor()
         delete button_bindings;
        delete _routes;
        delete _route_groups;
-       delete track_canvas;
+       delete _track_canvas_viewport;
        delete _drags;
 }
 
@@ -920,11 +933,11 @@ Editor::zoom_adjustment_changed ()
                return;
        }
 
-       double fpu = zoom_range_clock->current_duration() / _canvas_width;
-       bool clamped = clamp_frames_per_unit (fpu);
+       double fpu = zoom_range_clock->current_duration() / _visible_canvas_width;
+       bool clamped = clamp_frames_per_pixel (fpu);
        
        if (clamped) {
-               zoom_range_clock->set ((framepos_t) floor (fpu * _canvas_width));
+               zoom_range_clock->set ((framepos_t) floor (fpu * _visible_canvas_width));
        }
 
        temporal_zoom (fpu);
@@ -1131,7 +1144,7 @@ Editor::map_position_change (framepos_t frame)
 void
 Editor::center_screen (framepos_t frame)
 {
-       double page = _canvas_width * frames_per_unit;
+       double const page = _visible_canvas_width * frames_per_pixel;
 
        /* if we're off the page, then scroll.
         */
@@ -1261,7 +1274,7 @@ Editor::set_session (Session *t)
 
        /* catch up with the playhead */
 
-       _session->request_locate (playhead_cursor->current_frame);
+       _session->request_locate (playhead_cursor->current_frame ());
        _pending_initial_locate = true;
 
        update_title ();
@@ -1286,7 +1299,7 @@ Editor::set_session (Session *t)
        _session->locations()->StateChanged.connect (_session_connections, invalidator (*this), boost::bind (&Editor::refresh_location_display, this), gui_context());
        _session->history().Changed.connect (_session_connections, invalidator (*this), boost::bind (&Editor::history_changed, this), gui_context());
 
-       playhead_cursor->canvas_item.show ();
+       playhead_cursor->show ();
 
        boost::function<void (string)> pc (boost::bind (&Editor::parameter_changed, this, _1));
        Config->map_parameters (pc);
@@ -1297,7 +1310,7 @@ Editor::set_session (Session *t)
        _session->tempo_map().apply_with_metrics (*this, &Editor::draw_metric_marks);
 
        for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
-               (static_cast<TimeAxisView*>(*i))->set_samples_per_unit (frames_per_unit);
+               (static_cast<TimeAxisView*>(*i))->set_frames_per_pixel (frames_per_pixel);
        }
 
        super_rapid_screen_update_connection = ARDOUR_UI::instance()->SuperRapidScreenUpdate.connect (
@@ -1369,7 +1382,7 @@ Editor::fill_xfade_menu (Menu_Helpers::MenuList& items, bool start)
        
        items.push_back (
                ImageMenuElem (
-                       _("ConstantPower"),
+                       _("Constant power"),
                        *(*images)[FadeConstantPower],
                        sigc::bind (sigc::mem_fun (*this, emf), FadeConstantPower)
                        ));
@@ -1506,7 +1519,7 @@ Editor::popup_fade_context_menu (int button, int32_t time, ArdourCanvas::Item* i
                                
                        items.push_back (
                                ImageMenuElem (
-                                       _("Constant Power"),
+                                       _("Constant power"),
                                        *_fade_in_images[FadeConstantPower],
                                        sigc::bind (sigc::mem_fun (*this, &Editor::set_fade_in_shape), FadeConstantPower)
                                        ));
@@ -1568,7 +1581,7 @@ Editor::popup_fade_context_menu (int button, int32_t time, ArdourCanvas::Item* i
 
                        items.push_back (
                                ImageMenuElem (
-                                       _("Constant Power"),
+                                       _("Constant power"),
                                        *_fade_out_images[FadeConstantPower],
                                        sigc::bind (sigc::mem_fun (*this, &Editor::set_fade_out_shape), FadeConstantPower)
                                        ));
@@ -2139,9 +2152,16 @@ Editor::set_snap_to (SnapType st)
 void
 Editor::set_snap_mode (SnapMode mode)
 {
-       _snap_mode = mode;
        string str = snap_mode_strings[(int)mode];
 
+       if (_internal_editing) {
+               internal_snap_mode = mode;
+       } else {
+               pre_internal_snap_mode = mode;
+       }
+
+       _snap_mode = mode;
+
        if (str != snap_mode_selector.get_active_text ()) {
                snap_mode_selector.set_active_text (str);
        }
@@ -2266,7 +2286,7 @@ Editor::set_state (const XMLNode& node, int /*version*/)
        if ((prop = node.property ("zoom"))) {
                reset_zoom (PBD::atof (prop->value()));
        } else {
-               reset_zoom (frames_per_unit);
+               reset_zoom (frames_per_pixel);
        }
 
        if ((prop = node.property ("snap-to"))) {
@@ -2289,6 +2309,7 @@ Editor::set_state (const XMLNode& node, int /*version*/)
                pre_internal_snap_type = (SnapType) string_2_enum (prop->value(), pre_internal_snap_type);
        }
 
+
        if ((prop = node.property ("pre-internal-snap-mode"))) {
                pre_internal_snap_mode = (SnapMode) string_2_enum (prop->value(), pre_internal_snap_mode);
        }
@@ -2485,7 +2506,7 @@ Editor::get_state ()
        maybe_add_mixer_strip_width (*node);
 
        node->add_property ("zoom-focus", enum_2_string (zoom_focus));
-       snprintf (buf, sizeof(buf), "%f", frames_per_unit);
+       snprintf (buf, sizeof(buf), "%f", frames_per_pixel);
        node->add_property ("zoom", buf);
        node->add_property ("snap-to", enum_2_string (_snap_type));
        node->add_property ("snap-mode", enum_2_string (_snap_mode));
@@ -2495,7 +2516,7 @@ Editor::get_state ()
        node->add_property ("pre-internal-snap-mode", enum_2_string (pre_internal_snap_mode));
        node->add_property ("edit-point", enum_2_string (_edit_point));
 
-       snprintf (buf, sizeof (buf), "%" PRIi64, playhead_cursor->current_frame);
+       snprintf (buf, sizeof (buf), "%" PRIi64, playhead_cursor->current_frame ());
        node->add_property ("playhead", buf);
        snprintf (buf, sizeof (buf), "%" PRIi64, leftmost_frame);
        node->add_property ("left-frame", buf);
@@ -4015,7 +4036,7 @@ Editor::restore_editing_space ()
 
 /**
  *  Make new playlists for a given track and also any others that belong
- *  to the same active route group with the `edit' property.
+ *  to the same active route group with the `select' property.
  *  @param v Track.
  */
 
@@ -4031,7 +4052,7 @@ Editor::new_playlists (TimeAxisView* v)
 
 /**
  *  Use a copy of the current playlist for a given track and also any others that belong
- *  to the same active route group with the `edit' property.
+ *  to the same active route group with the `select' property.
  *  @param v Track.
  */
 
@@ -4046,7 +4067,7 @@ Editor::copy_playlists (TimeAxisView* v)
 }
 
 /** Clear the current playlist for a given track and also any others that belong
- *  to the same active route group with the `edit' property.
+ *  to the same active route group with the `select' property.
  *  @param v Track.
  */
 
@@ -4111,16 +4132,16 @@ Editor::reset_y_origin (double y)
 }
 
 void
-Editor::reset_zoom (double fpu)
+Editor::reset_zoom (double fpp)
 {
-       clamp_frames_per_unit (fpu);
+       clamp_frames_per_pixel (fpp);
 
-       if (fpu == frames_per_unit) {
+       if (fpp == frames_per_pixel) {
                return;
        }
 
        pending_visual_change.add (VisualChange::ZoomLevel);
-       pending_visual_change.frames_per_unit = fpu;
+       pending_visual_change.frames_per_pixel = fpp;
        ensure_visual_change_idle_handler ();
 }
 
@@ -4150,7 +4171,7 @@ Editor::current_visual_state (bool with_tracks)
 {
        VisualState* vs = new VisualState (with_tracks);
        vs->y_position = vertical_adjustment.get_value();
-       vs->frames_per_unit = frames_per_unit;
+       vs->frames_per_pixel = frames_per_pixel;
        vs->leftmost_frame = leftmost_frame;
        vs->zoom_focus = zoom_focus;
 
@@ -4212,7 +4233,7 @@ Editor::use_visual_state (VisualState& vs)
        vertical_adjustment.set_value (vs.y_position);
 
        set_zoom_focus (vs.zoom_focus);
-       reposition_and_zoom (vs.leftmost_frame, vs.frames_per_unit);
+       reposition_and_zoom (vs.leftmost_frame, vs.frames_per_pixel);
        
        if (vs.gui_state) {
                *ARDOUR_UI::instance()->gui_object_state = *vs.gui_state;
@@ -4231,19 +4252,19 @@ Editor::use_visual_state (VisualState& vs)
  *  @param fpu New frames per unit; should already have been clamped so that it is sensible.
  */
 void
-Editor::set_frames_per_unit (double fpu)
+Editor::set_frames_per_pixel (double fpp)
 {
        if (tempo_lines) {
                tempo_lines->tempo_map_changed();
        }
 
-       frames_per_unit = fpu;
+       frames_per_pixel = fpp;
 
        /* convert fpu to frame count */
 
-       framepos_t frames = (framepos_t) floor (frames_per_unit * _canvas_width);
+       framepos_t frames = (framepos_t) floor (frames_per_pixel * _visible_canvas_width);
 
-       if (frames_per_unit != zoom_range_clock->current_duration()) {
+       if (frames_per_pixel != zoom_range_clock->current_duration()) {
                zoom_range_clock->set (frames);
        }
 
@@ -4260,7 +4281,7 @@ Editor::set_frames_per_unit (double fpu)
        //reset_scrolling_region ();
 
        if (playhead_cursor) {
-               playhead_cursor->set_position (playhead_cursor->current_frame);
+               playhead_cursor->set_position (playhead_cursor->current_frame ());
        }
 
        refresh_location_display();
@@ -4271,11 +4292,25 @@ Editor::set_frames_per_unit (double fpu)
        instant_save ();
 }
 
+void
+Editor::queue_visual_videotimeline_update ()
+{
+       /* TODO:
+        * pending_visual_change.add (VisualChange::VideoTimeline);
+        * or maybe even more specific: which videotimeline-image
+        * currently it calls update_video_timeline() to update
+        * _all outdated_ images on the video-timeline.
+        * see 'exposeimg()' in video_image_frame.cc
+        */
+       ensure_visual_change_idle_handler ();
+}
+
 void
 Editor::ensure_visual_change_idle_handler ()
 {
        if (pending_visual_change.idle_handler_id < 0) {
                pending_visual_change.idle_handler_id = g_idle_add (_idle_visual_changer, this);
+               pending_visual_change.being_handled = false;
        }
 }
 
@@ -4307,7 +4342,7 @@ Editor::idle_visual_changer ()
        double const last_time_origin = horizontal_position ();
 
        if (p & VisualChange::ZoomLevel) {
-               set_frames_per_unit (pending_visual_change.frames_per_unit);
+               set_frames_per_pixel (pending_visual_change.frames_per_pixel);
 
                compute_fixed_ruler_scale ();
 
@@ -4320,9 +4355,15 @@ Editor::idle_visual_changer ()
                                         current_bbt_points_begin, current_bbt_points_end);
                update_tempo_based_rulers (current_bbt_points_begin, current_bbt_points_end);
        }
+
+       if (p & VisualChange::ZoomLevel) {
+               update_video_timeline();
+       }
+
        if (p & VisualChange::TimeOrigin) {
-               set_horizontal_position (pending_visual_change.time_origin / frames_per_unit);
+               set_horizontal_position (pending_visual_change.time_origin / frames_per_pixel);
        }
+
        if (p & VisualChange::YOrigin) {
                vertical_adjustment.set_value (pending_visual_change.y_origin);
        }
@@ -4333,6 +4374,10 @@ Editor::idle_visual_changer ()
                redisplay_tempo (true);
        }
 
+       if (!(p & VisualChange::ZoomLevel)) {
+               update_video_timeline();
+       }
+
        _summary->set_overlays_dirty ();
 
        pending_visual_change.being_handled = false;
@@ -4530,7 +4575,7 @@ Editor::get_regions_after (RegionSelection& rs, framepos_t where, const TrackVie
                                        RegionView* rv = rtv->view()->find_view (*i);
 
                                        if (rv) {
-                                               rs.push_back (rv);
+                                               rs.add (rv);
                                        }
                                }
                        }
@@ -4538,32 +4583,16 @@ Editor::get_regions_after (RegionSelection& rs, framepos_t where, const TrackVie
        }
 }
 
-/** Start with regions that are selected.  Then add equivalent regions
- *  on tracks in the same active edit-enabled route group as any of
- *  the regions that we started with.
- */
-
-RegionSelection
-Editor::get_regions_from_selection ()
-{
-       return get_equivalent_regions (selection->regions, ARDOUR::Properties::select.property_id);
-}
-
 /** Get regions using the following method:
  *
- *  Make an initial region list using the selected regions, unless
+ *  Make a region list using the selected regions, unless
  *  the edit point is `mouse' and the mouse is over an unselected
- *  region.  In this case, start with just that region.
- *
- *  Then, add equivalent regions in active edit groups to the region list.
- *
- *  Then, search the list of selected tracks to find any selected tracks which
- *  do not contain regions already in the region list. If there are no selected
- *  tracks and 'No Selection = All Tracks' is active, search all tracks rather
- *  than just the selected.
+ *  region.  In this case, use just that region.
  *
- *  Add any regions that are under the edit point on these tracks to get the
- *  returned region list.
+ *  If the edit point is not 'mouse', and there are no regions selected,
+ *  search the list of selected tracks and return regions that are under
+ *  the edit point on these tracks. If there are no selected tracks and
+ *  'No Selection = All Tracks' is active, search all tracks,
  *
  *  The rationale here is that the mouse edit point is special in that
  *  its position describes both a time and a track; the other edit
@@ -4585,48 +4614,25 @@ Editor::get_regions_from_selection_and_edit_point ()
                regions = selection->regions;
        }
 
-       TrackViewList tracks;
 
-       if (_edit_point != EditAtMouse) {
-               tracks = selection->tracks;
-       }
+       if (regions.empty() && _edit_point != EditAtMouse) {
+               TrackViewList tracks = selection->tracks;
 
-       /* Add any other regions that are in the same
-          edit-activated route group as one of our regions.
-        */
-       regions = get_equivalent_regions (regions, ARDOUR::Properties::select.property_id);
-       framepos_t const where = get_preferred_edit_position ();
-
-       if (_route_groups->all_group_active_button().get_active() && tracks.empty()) {
-               /* tracks is empty (no track selected), and 'No Selection = All Tracks'
-                * is enabled, so consider all tracks
-                */
-               tracks = track_views; 
-       }
-
-       if (!tracks.empty()) {
-               /* now search the selected tracks for tracks which don't
-                  already contain regions to be acted upon, and get regions at
-                  the edit point on those tracks too.
-                */
-               TrackViewList tracks_without_relevant_regions;
-
-               for (TrackViewList::iterator t = tracks.begin (); t != tracks.end (); ++t) {
-                       if (!regions.involves (**t)) {
-                               /* there are no equivalent regions on this track */
-                               tracks_without_relevant_regions.push_back (*t);
-                       }
+               if (_route_groups->all_group_active_button().get_active() && tracks.empty()) {
+                       /* tracks is empty (no track selected), and 'No Selection = All Tracks'
+                        * is enabled, so consider all tracks
+                        */
+                       tracks = track_views; 
                }
 
-               if (!tracks_without_relevant_regions.empty()) {
-                       /* there are some selected tracks with neither selected
-                        * regions or their equivalents: act upon all regions in
-                        * those tracks
-                        */
-                       get_regions_at (regions, where, tracks_without_relevant_regions);
+               if (!tracks.empty()) {
+                       /* no region selected or entered, but some selected tracks:
+                        * act on all regions on the selected tracks at the edit point
+                        *
+                       framepos_t const where = get_preferred_edit_position ();
+                       get_regions_at(regions, where, tracks);
                }
        }
-
        return regions;
 }
 
@@ -4644,7 +4650,7 @@ Editor::get_regions_from_selection_and_entered ()
                regions.add (entered_regionview);
        }
 
-       return get_equivalent_regions (regions, ARDOUR::Properties::select.property_id);
+       return regions;
 }
 
 void
@@ -4856,17 +4862,17 @@ Editor::add_routes (RouteList& routes)
        for (RouteList::iterator x = routes.begin(); x != routes.end(); ++x) {
                boost::shared_ptr<Route> route = (*x);
 
-               if (route->is_hidden() || route->is_monitor()) {
+               if (route->is_auditioner() || route->is_monitor()) {
                        continue;
                }
 
                DataType dt = route->input()->default_type();
 
                if (dt == ARDOUR::DataType::AUDIO) {
-                       rtv = new AudioTimeAxisView (*this, _session, *track_canvas);
+                       rtv = new AudioTimeAxisView (*this, _session, *_track_canvas);
                        rtv->set_route (route);
                } else if (dt == ARDOUR::DataType::MIDI) {
-                       rtv = new MidiTimeAxisView (*this, _session, *track_canvas);
+                       rtv = new MidiTimeAxisView (*this, _session, *_track_canvas);
                        rtv->set_route (route);
                } else {
                        throw unknown_type();
@@ -5169,7 +5175,7 @@ Editor::scroll_release ()
 void
 Editor::reset_x_origin_to_follow_playhead ()
 {
-       framepos_t const frame = playhead_cursor->current_frame;
+       framepos_t const frame = playhead_cursor->current_frame ();
 
        if (frame < leftmost_frame || frame > leftmost_frame + current_page_frames()) {
 
@@ -5280,11 +5286,11 @@ Editor::super_rapid_screen_update ()
                        */
 #if 0
                        // FIXME DO SOMETHING THAT WORKS HERE - this is 2.X code
-                       double target = ((double)frame - (double)current_page_frames()/2.0) / frames_per_unit;
+                       double target = ((double)frame - (double)current_page_frames()/2.0) / frames_per_pixel;
                        if (target <= 0.0) {
                                target = 0.0;
                        }
-                       if (fabs(target - current) < current_page_frames() / frames_per_unit) {
+                       if (fabs(target - current) < current_page_frames() / frames_per_pixel) {
                                target = (target * 0.15) + (current * 0.85);
                        } else {
                                /* relax */
@@ -5319,7 +5325,7 @@ Editor::session_going_away ()
        last_update_frame = 0;
        _drags->abort ();
 
-       playhead_cursor->canvas_item.hide ();
+       playhead_cursor->hide ();
 
        /* rip everything out of the list displays */
 
@@ -5524,3 +5530,12 @@ Editor::shift_key_released ()
 {
        _stepping_axis_view = 0;
 }
+
+
+void
+Editor::save_canvas_state ()
+{
+       XMLTree* tree = static_cast<ArdourCanvas::Canvas*>(_track_canvas)->get_state ();
+       string path = string_compose ("%1/canvas-state.xml", _session->path());
+       tree->write (path);
+}