changes to help strp silence
[ardour.git] / gtk2_ardour / editor_drag.cc
index 0aa5e53b4ebba955fd0da716a2d36b3e3bf41f57..c436822ae3220d01394379e0d29a0cd9202ef933 100644 (file)
 
 */
 
+#define __STDC_LIMIT_MACROS 1
+#include <stdint.h>
 #include "pbd/memento_command.h"
 #include "pbd/basename.h"
+#include "pbd/stateful_diff_command.h"
 #include "ardour/diskstream.h"
 #include "ardour/session.h"
 #include "ardour/dB.h"
@@ -53,16 +56,128 @@ using Gtkmm2ext::Keyboard;
 
 double const ControlPointDrag::_zero_gain_fraction = gain_to_slider_position (dB_to_coefficient (0.0));
 
+DragManager::DragManager (Editor* e)
+       : _editor (e)
+       , _ending (false)
+       , _current_pointer_frame (0)
+{
+
+}
+
+DragManager::~DragManager ()
+{
+       abort ();
+}
+
+void
+DragManager::abort ()
+{
+       for (list<Drag*>::const_iterator i = _drags.begin(); i != _drags.end(); ++i) {
+               (*i)->end_grab (0);
+               delete *i;
+       }
+
+       _drags.clear ();
+}
+
+void
+DragManager::break_drag ()
+{
+       _ending = true;
+       
+       for (list<Drag*>::const_iterator i = _drags.begin(); i != _drags.end(); ++i) {
+               (*i)->break_drag ();
+               delete *i;
+       }
+
+       _drags.clear ();
+
+       _ending = false;
+}
+
+void
+DragManager::add (Drag* d)
+{
+       d->set_manager (this);
+       _drags.push_back (d);
+}
+
+void
+DragManager::set (Drag* d, GdkEvent* e, Gdk::Cursor* c)
+{
+       assert (_drags.empty ());
+       d->set_manager (this);
+       _drags.push_back (d);
+       start_grab (e);
+}
+
+void
+DragManager::start_grab (GdkEvent* e)
+{
+       _current_pointer_frame = _editor->event_frame (e, &_current_pointer_x, &_current_pointer_y);
+       
+       for (list<Drag*>::const_iterator i = _drags.begin(); i != _drags.end(); ++i) {
+               (*i)->start_grab (e);
+       }
+}
+
+bool
+DragManager::end_grab (GdkEvent* e)
+{
+       _ending = true;
+       
+       bool r = false;
+       for (list<Drag*>::iterator i = _drags.begin(); i != _drags.end(); ++i) {
+               bool const t = (*i)->end_grab (e);
+               if (t) {
+                       r = true;
+               }
+               delete *i;
+       }
+
+       _drags.clear ();
+
+       _ending = false;
+       
+       return r;
+}
+
+bool
+DragManager::motion_handler (GdkEvent* e, bool from_autoscroll)
+{
+       bool r = false;
+
+       _current_pointer_frame = _editor->event_frame (e, &_current_pointer_x, &_current_pointer_y);
+       
+       for (list<Drag*>::iterator i = _drags.begin(); i != _drags.end(); ++i) {
+               bool const t = (*i)->motion_handler (e, from_autoscroll);
+               if (t) {
+                       r = true;
+               }
+               
+       }
+
+       return r;
+}
+
+bool
+DragManager::have_item (ArdourCanvas::Item* i) const
+{
+       list<Drag*>::const_iterator j = _drags.begin ();
+       while (j != _drags.end() && (*j)->item () != i) {
+               ++j;
+       }
+
+       return j != _drags.end ();
+}
+
 Drag::Drag (Editor* e, ArdourCanvas::Item* i) 
        : _editor (e)
        , _item (i)
        , _pointer_frame_offset (0)
-       , _have_transaction (false)
-       , _ending (false)
        , _move_threshold_passed (false)
        , _grab_frame (0)
        , _last_pointer_frame (0)
-       , _current_pointer_frame (0)
 {
 
 }
@@ -105,11 +220,8 @@ Drag::start_grab (GdkEvent* event, Gdk::Cursor *cursor)
        _grab_frame = _editor->event_frame (event, &_grab_x, &_grab_y);
        _grab_frame = adjusted_frame (_grab_frame, event);
        _last_pointer_frame = _grab_frame;
-       _current_pointer_frame = _grab_frame;
-       _current_pointer_x = _grab_x;
-       _current_pointer_y = _grab_y;
-       _last_pointer_x = _current_pointer_x;
-       _last_pointer_y = _current_pointer_y;
+       _last_pointer_x = _grab_x;
+       _last_pointer_y = _grab_y;
 
        _item->grab (Gdk::POINTER_MOTION_MASK|Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK,
                              *cursor,
@@ -139,20 +251,14 @@ Drag::start_grab (GdkEvent* event, Gdk::Cursor *cursor)
 bool
 Drag::end_grab (GdkEvent* event)
 {
-       _ending = true;
-
        _editor->stop_canvas_autoscroll ();
 
        _item->ungrab (event ? event->button.time : 0);
 
-       _last_pointer_x = _current_pointer_x;
-       _last_pointer_y = _current_pointer_y;
        finished (event, _move_threshold_passed);
 
        _editor->hide_verbose_canvas_cursor();
 
-       _ending = false;
-
        return _move_threshold_passed;
 }
 
@@ -175,17 +281,15 @@ Drag::adjusted_frame (nframes64_t f, GdkEvent const * event, bool snap) const
 nframes64_t
 Drag::adjusted_current_frame (GdkEvent const * event, bool snap) const
 {
-       return adjusted_frame (_current_pointer_frame, event, snap);
+       return adjusted_frame (_drags->current_pointer_frame (), event, snap);
 }
 
 bool
 Drag::motion_handler (GdkEvent* event, bool from_autoscroll)
 {
-       _current_pointer_frame = _editor->event_frame (event, &_current_pointer_x, &_current_pointer_y);
-
        /* check to see if we have moved in any way that matters since the last motion event */
        if ( (!x_movement_matters() || _last_pointer_frame == adjusted_current_frame (event)) &&
-            (!y_movement_matters() || _last_pointer_y == _current_pointer_y) ) {
+            (!y_movement_matters() || _last_pointer_y == _drags->current_pointer_y ()) ) {
                return false;
        }
 
@@ -196,7 +300,7 @@ Drag::motion_handler (GdkEvent* event, bool from_autoscroll)
        if (!from_autoscroll && !_move_threshold_passed) {
 
                bool const xp = (::llabs (adjusted_current_frame (event) - _grab_frame) >= threshold.first);
-               bool const yp = (::fabs ((_current_pointer_y - _grab_y)) >= threshold.second);
+               bool const yp = (::fabs ((_drags->current_pointer_y () - _grab_y)) >= threshold.second);
 
                _move_threshold_passed = ((xp && x_movement_matters()) || (yp && y_movement_matters()));
        }
@@ -210,8 +314,8 @@ Drag::motion_handler (GdkEvent* event, bool from_autoscroll)
 
                        motion (event, _move_threshold_passed != old_move_threshold_passed);
 
-                       _last_pointer_x = _current_pointer_x;
-                       _last_pointer_y = _current_pointer_y;
+                       _last_pointer_x = _drags->current_pointer_x ();
+                       _last_pointer_y = _drags->current_pointer_y ();
                        _last_pointer_frame = adjusted_current_frame (event);
                        
                        return true;
@@ -224,8 +328,6 @@ Drag::motion_handler (GdkEvent* event, bool from_autoscroll)
 void
 Drag::break_drag ()
 {
-       _ending = true;
-       
        if (_item) {
                _item->ungrab (0);
        }
@@ -234,15 +336,6 @@ Drag::break_drag ()
 
        _editor->stop_canvas_autoscroll ();
        _editor->hide_verbose_canvas_cursor ();
-       
-       _ending = false;
-}
-
-pair<nframes64_t, nframes64_t>
-Drag::extent () const
-{
-       nframes64_t const f = adjusted_current_frame (0);
-       return make_pair (f, f);
 }
 
 RegionDrag::RegionDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<RegionView*> const & v)
@@ -256,19 +349,9 @@ RegionDrag::RegionDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<Re
 void
 RegionDrag::region_going_away (RegionView* v)
 {
-       if (!ending ()) {
-               _views.remove (v);
-       }
-}
-
-pair<nframes64_t, nframes64_t>
-RegionDrag::extent () const
-{
-       nframes64_t const f = adjusted_current_frame (0);
-       return make_pair (f, f + _primary->region()->length ());
+       _views.remove (v);
 }
 
-
 RegionMotionDrag::RegionMotionDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<RegionView*> const & v, bool b)
        : RegionDrag (e, i, p, v),
          _dest_trackview (0),
@@ -735,6 +818,7 @@ RegionMoveDrag::finished (GdkEvent* /*event*/, bool movement_occurred)
        vector<RegionView*> copies;
        boost::shared_ptr<Diskstream> ds;
        boost::shared_ptr<Playlist> from_playlist;
+       boost::shared_ptr<Playlist> to_playlist;
        RegionSelection new_views;
        typedef set<boost::shared_ptr<Playlist> > PlaylistSet;
        PlaylistSet modified_playlists;
@@ -745,6 +829,7 @@ RegionMoveDrag::finished (GdkEvent* /*event*/, bool movement_occurred)
        bool changed_tracks, changed_position;
        map<RegionView*, pair<RouteTimeAxisView*, int> > final;
        RouteTimeAxisView* source_tv;
+        vector<StatefulDiffCommand*> sdc;
 
        if (!movement_occurred) {
                /* just a click */
@@ -785,8 +870,6 @@ RegionMoveDrag::finished (GdkEvent* /*event*/, bool movement_occurred)
                }
        }
 
-       _have_transaction = true;
-
        changed_position = (_last_frame_position != (nframes64_t) (_primary->region()->position()));
        changed_tracks = (_dest_trackview != &_primary->get_time_axis_view());
 
@@ -797,6 +880,8 @@ RegionMoveDrag::finished (GdkEvent* /*event*/, bool movement_occurred)
        /* make a list of where each region ended up */
        final = find_time_axis_views_and_layers ();
 
+        cerr << "Iterate over " << _views.size() << " views\n";
+
        for (list<RegionView*>::const_iterator i = _views.begin(); i != _views.end(); ) {
 
                RegionView* rv = (*i);
@@ -805,6 +890,9 @@ RegionMoveDrag::finished (GdkEvent* /*event*/, bool movement_occurred)
 
                nframes64_t where;
 
+                from_playlist.reset ();
+                to_playlist.reset ();
+
                if (rv->region()->locked()) {
                        ++i;
                        continue;
@@ -834,7 +922,7 @@ RegionMoveDrag::finished (GdkEvent* /*event*/, bool movement_occurred)
 
                if (changed_tracks || _copy) {
 
-                       boost::shared_ptr<Playlist> to_playlist = dest_rtv->playlist();
+                       to_playlist = dest_rtv->playlist();
 
                        if (!to_playlist) {
                                ++i;
@@ -848,10 +936,18 @@ RegionMoveDrag::finished (GdkEvent* /*event*/, bool movement_occurred)
                        insert_result = modified_playlists.insert (to_playlist);
 
                        if (insert_result.second) {
-                               _editor->session()->add_command (new MementoCommand<Playlist>(*to_playlist, &to_playlist->get_state(), 0));
+                                to_playlist->clear_history ();
                        }
 
+                        cerr << "To playlist " << to_playlist->name() << " region history contains "
+                             << to_playlist->region_list().change().added.size() << " adds and " 
+                             << to_playlist->region_list().change().removed.size() << " removes\n";
+
+                        cerr << "Adding new region " << new_region->id() << " based on "
+                             << rv->region()->id() << endl;
+                        
                        to_playlist->add_region (new_region, where);
+
                        if (dest_rtv->view()->layer_display() == Stacked) {
                                new_region->set_layer (dest_layer);
                                new_region->set_pending_explicit_relayer (true);
@@ -867,6 +963,8 @@ RegionMoveDrag::finished (GdkEvent* /*event*/, bool movement_occurred)
                        }
 
                } else {
+                       rv->region()->clear_history ();
+
                        /*
                           motion on the same track. plonk the previously reparented region
                           back to its original canvas group (its streamview).
@@ -880,25 +978,25 @@ RegionMoveDrag::finished (GdkEvent* /*event*/, bool movement_occurred)
                        /* just change the model */
 
                        boost::shared_ptr<Playlist> playlist = dest_rtv->playlist();
-
+                       
                        if (dest_rtv->view()->layer_display() == Stacked) {
                                rv->region()->set_layer (dest_layer);
                                rv->region()->set_pending_explicit_relayer (true);
                        }
+                       
+                       /* freeze playlist to avoid lots of relayering in the case of a multi-region drag */
 
-                       insert_result = modified_playlists.insert (playlist);
-
-                       if (insert_result.second) {
-                               _editor->session()->add_command (new MementoCommand<Playlist>(*playlist, &playlist->get_state(), 0));
-                       }
-                       /* freeze to avoid lots of relayering in the case of a multi-region drag */
                        frozen_insert_result = frozen_playlists.insert(playlist);
 
                        if (frozen_insert_result.second) {
                                playlist->freeze();
                        }
 
+                        cerr << "Moving region " << rv->region()->id() << endl;
+
                        rv->region()->set_position (where, (void*) this);
+
+                       sdc.push_back (new StatefulDiffCommand (rv->region()));
                }
 
                if (changed_tracks && !_copy) {
@@ -931,9 +1029,15 @@ RegionMoveDrag::finished (GdkEvent* /*event*/, bool movement_occurred)
                        insert_result = modified_playlists.insert (from_playlist);
 
                        if (insert_result.second) {
-                               _editor->session()->add_command (new MementoCommand<Playlist>(*from_playlist, &from_playlist->get_state(), 0));
+                               from_playlist->clear_history ();
                        }
+                        
+                        cerr << "From playlist " << from_playlist->name() << " region history contains "
+                             << from_playlist->region_list().change().added.size() << " adds and " 
+                             << from_playlist->region_list().change().removed.size() << " removes\n";
 
+                        cerr << "removing region " << rv->region() << endl;
+                        
                        from_playlist->remove_region (rv->region());
 
                        /* OK, this is where it gets tricky. If the playlist was being used by >1 tracks, and the region
@@ -954,7 +1058,16 @@ RegionMoveDrag::finished (GdkEvent* /*event*/, bool movement_occurred)
                        */
 
                        if (_views.empty()) {
-                               break;
+                                if (to_playlist) {
+                                        sdc.push_back (new StatefulDiffCommand (to_playlist));
+                                        cerr << "Saved diff for to:" << to_playlist->name() << endl;
+                                }
+                                
+                                if (from_playlist && (from_playlist != to_playlist)) {
+                                        sdc.push_back (new StatefulDiffCommand (from_playlist));
+                                        cerr << "Saved diff for from:" << from_playlist->name() << endl;
+                                }                              
+                                break;
                        } else {
                                i = _views.begin();
                        }
@@ -966,11 +1079,25 @@ RegionMoveDrag::finished (GdkEvent* /*event*/, bool movement_occurred)
                if (_copy) {
                        copies.push_back (rv);
                }
+
+                cerr << "Done with TV, top = " << to_playlist << " from = " << from_playlist << endl;
+
+                if (to_playlist) {
+                        sdc.push_back (new StatefulDiffCommand (to_playlist));
+                        cerr << "Saved diff for to:" << to_playlist->name() << endl;
+                }
+
+                if (from_playlist && (from_playlist != to_playlist)) {
+                        sdc.push_back (new StatefulDiffCommand (from_playlist));
+                        cerr << "Saved diff for from:" << from_playlist->name() << endl;
+                }
        }
+
        /*
           if we've created new regions either by copying or moving 
           to a new track, we want to replace the old selection with the new ones 
        */
+
        if (new_views.size() > 0) {
                _editor->selection->set (new_views);
        }
@@ -980,9 +1107,9 @@ RegionMoveDrag::finished (GdkEvent* /*event*/, bool movement_occurred)
        }
 
   out:
-       for (set<boost::shared_ptr<Playlist> >::iterator p = modified_playlists.begin(); p != modified_playlists.end(); ++p) {
-               _editor->session()->add_command (new MementoCommand<Playlist>(*(*p), 0, &(*p)->get_state()));
-       }
+        for (vector<StatefulDiffCommand*>::iterator i = sdc.begin(); i != sdc.end(); ++i) {
+               _editor->session()->add_command (*i);
+        }
 
        _editor->commit_reversible_command ();
 
@@ -1052,11 +1179,13 @@ RegionMotionDrag::copy_regions (GdkEvent* event)
 
                const boost::shared_ptr<const Region> original = rv->region();
                boost::shared_ptr<Region> region_copy = RegionFactory::create (original);
+                region_copy->set_position (original->position(), this);
 
                RegionView* nrv;
                if (arv) {
                        boost::shared_ptr<AudioRegion> audioregion_copy
                                = boost::dynamic_pointer_cast<AudioRegion>(region_copy);
+
                        nrv = new AudioRegionView (*arv, audioregion_copy);
                } else if (mrv) {
                        boost::shared_ptr<MidiRegion> midiregion_copy
@@ -1105,7 +1234,7 @@ RegionMotionDrag::check_possible (RouteTimeAxisView** tv, layer_t* layer)
 {
        /* Which trackview is this ? */
 
-       pair<TimeAxisView*, int> const tvp = _editor->trackview_by_y_position (current_pointer_y ());
+       pair<TimeAxisView*, int> const tvp = _editor->trackview_by_y_position (_drags->current_pointer_y ());
        (*tv) = dynamic_cast<RouteTimeAxisView*> (tvp.first);
        (*layer) = tvp.second;
 
@@ -1298,9 +1427,9 @@ RegionInsertDrag::finished (GdkEvent* /*event*/, bool /*movement_occurred*/)
        boost::shared_ptr<Playlist> playlist = dest_rtv->playlist();
 
        _editor->begin_reversible_command (_("insert region"));
-       XMLNode& before = playlist->get_state ();
+        playlist->clear_history ();
        playlist->add_region (_primary->region (), _last_frame_position);
-       _editor->session()->add_command (new MementoCommand<Playlist> (*playlist, &before, &playlist->get_state()));
+       _editor->session()->add_command (new StatefulDiffCommand (playlist));
        _editor->commit_reversible_command ();
 
        delete _primary;
@@ -1338,7 +1467,7 @@ RegionSpliceDrag::motion (GdkEvent* event, bool)
 
        int dir;
 
-       if ((current_pointer_x() - last_pointer_x()) > 0) {
+       if ((_drags->current_pointer_x() - last_pointer_x()) > 0) {
                dir = 1;
        } else {
                dir = -1;
@@ -1504,7 +1633,7 @@ NoteResizeDrag::motion (GdkEvent* /*event*/, bool /*first_move*/)
 {
        MidiRegionSelection& ms (_editor->get_selection().midi_regions);
        for (MidiRegionSelection::iterator r = ms.begin(); r != ms.end(); ++r) {
-               (*r)->update_resizing (at_front, current_pointer_x() - grab_x(), relative);
+               (*r)->update_resizing (at_front, _drags->current_pointer_x() - grab_x(), relative);
        }
 }
 
@@ -1513,7 +1642,7 @@ NoteResizeDrag::finished (GdkEvent*, bool /*movement_occurred*/)
 {
        MidiRegionSelection& ms (_editor->get_selection().midi_regions);
        for (MidiRegionSelection::iterator r = ms.begin(); r != ms.end(); ++r) {
-               (*r)->commit_resizing (at_front, current_pointer_x() - grab_x(), relative);
+               (*r)->commit_resizing (at_front, _drags->current_pointer_x() - grab_x(), relative);
        }
 }
 
@@ -1543,6 +1672,7 @@ RegionGainDrag::aborted ()
 
 TrimDrag::TrimDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<RegionView*> const & v)
        : RegionDrag (e, i, p, v)
+       , _have_transaction (false)
 {
 
 }
@@ -1644,7 +1774,8 @@ TrimDrag::motion (GdkEvent* event, bool first_move)
 
                for (list<RegionView*>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
                        (*i)->fake_set_opaque(false);
-                       (*i)->region()->freeze ();
+                        (*i)->region()->clear_history ();
+                       (*i)->region()->suspend_property_changes ();
 
                        AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
 
@@ -1656,15 +1787,11 @@ TrimDrag::motion (GdkEvent* event, bool first_move)
                        insert_result = _editor->motion_frozen_playlists.insert (pl);
 
                        if (insert_result.second) {
-                               _editor->session()->add_command(new MementoCommand<Playlist>(*pl, &pl->get_state(), 0));
                                pl->freeze();
                        }
                }
        }
 
-       /* XXX i hope to god that we can really conclude this ... */
-       _have_transaction = true;
-
        if (left_direction) {
                frame_delta = (last_pointer_frame() - pf);
        } else {
@@ -1742,13 +1869,13 @@ TrimDrag::finished (GdkEvent* event, bool movement_occurred)
                        for (list<RegionView*>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
                                _editor->thaw_region_after_trim (**i);
                                (*i)->fake_set_opaque (true);
+                                if (_have_transaction) {
+                                        _editor->session()->add_command (new StatefulDiffCommand ((*i)->region()));
+                                }
                        }
                }
                for (set<boost::shared_ptr<Playlist> >::iterator p = _editor->motion_frozen_playlists.begin(); p != _editor->motion_frozen_playlists.end(); ++p) {
                        (*p)->thaw ();
-                       if (_have_transaction) {
-                               _editor->session()->add_command (new MementoCommand<Playlist>(*(*p).get(), 0, &(*p)->get_state()));
-                       }
                }
 
                _editor->motion_frozen_playlists.clear ();
@@ -1759,7 +1886,7 @@ TrimDrag::finished (GdkEvent* event, bool movement_occurred)
 
        } else {
                /* no mouse movement */
-               _editor->point_trim (event);
+               _editor->point_trim (event, adjusted_current_frame (event));
        }
 }
 
@@ -2619,8 +2746,8 @@ ControlPointDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*cursor*/)
 void
 ControlPointDrag::motion (GdkEvent* event, bool)
 {
-       double dx = current_pointer_x() - last_pointer_x();
-       double dy = current_pointer_y() - last_pointer_y();
+       double dx = _drags->current_pointer_x() - last_pointer_x();
+       double dy = _drags->current_pointer_y() - last_pointer_y();
 
        if (event->button.state & Keyboard::SecondaryModifier) {
                dx *= 0.1;
@@ -2758,7 +2885,7 @@ LineDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*cursor*/)
 void
 LineDrag::motion (GdkEvent* event, bool)
 {
-       double dy = current_pointer_y() - last_pointer_y();
+       double dy = _drags->current_pointer_y() - last_pointer_y();
 
        if (event->button.state & Keyboard::SecondaryModifier) {
                dy *= 0.1;
@@ -2832,11 +2959,11 @@ RubberbandSelectDrag::motion (GdkEvent* event, bool)
                start = grab;
        }
 
-       if (current_pointer_y() < grab_y()) {
-               y1 = current_pointer_y();
+       if (_drags->current_pointer_y() < grab_y()) {
+               y1 = _drags->current_pointer_y();
                y2 = grab_y();
        } else {
-               y2 = current_pointer_y();
+               y2 = _drags->current_pointer_y();
                y1 = grab_y();
        }
 
@@ -2866,11 +2993,11 @@ RubberbandSelectDrag::finished (GdkEvent* event, bool movement_occurred)
                motion (event, false);
 
                double y1,y2;
-               if (current_pointer_y() < grab_y()) {
-                       y1 = current_pointer_y();
+               if (_drags->current_pointer_y() < grab_y()) {
+                       y1 = _drags->current_pointer_y();
                        y2 = grab_y();
                } else {
-                       y2 = current_pointer_y();
+                       y2 = _drags->current_pointer_y();
                        y1 = grab_y();
                }
 
@@ -2983,7 +3110,7 @@ ScrubDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
 void
 ScrubDrag::motion (GdkEvent* /*event*/, bool)
 {
-       _editor->scrub ();
+       _editor->scrub (adjusted_current_frame (0, false), _drags->current_pointer_x ());
 }
 
 void
@@ -3065,7 +3192,7 @@ SelectionDrag::start_grab (GdkEvent* event, Gdk::Cursor*)
                _editor->show_verbose_time_cursor (adjusted_current_frame (event), 10);
        }
 
-       _original_pointer_time_axis = _editor->trackview_by_y_position (current_pointer_y ()).first->order ();
+       _original_pointer_time_axis = _editor->trackview_by_y_position (_drags->current_pointer_y ()).first->order ();
 }
 
 void
@@ -3075,7 +3202,7 @@ SelectionDrag::motion (GdkEvent* event, bool first_move)
        nframes64_t end = 0;
        nframes64_t length;
 
-       pair<TimeAxisView*, int> const pending_time_axis = _editor->trackview_by_y_position (current_pointer_y ());
+       pair<TimeAxisView*, int> const pending_time_axis = _editor->trackview_by_y_position (_drags->current_pointer_y ());
        if (pending_time_axis.first == 0) {
                return;
        }
@@ -3111,9 +3238,6 @@ SelectionDrag::motion (GdkEvent* event, bool first_move)
 
                if (first_move) {
 
-                       _editor->begin_reversible_command (_("range selection"));
-                       _have_transaction = true;
-
                        if (_copy) {
                                /* adding to the selection */
                                _editor->selection->add (_editor->clicked_axisview);
@@ -3162,11 +3286,6 @@ SelectionDrag::motion (GdkEvent* event, bool first_move)
 
        case SelectionStartTrim:
 
-               if (first_move) {
-                       _editor->begin_reversible_command (_("trim selection start"));
-                       _have_transaction = true;
-               }
-               
                start = _editor->selection->time[_editor->clicked_selection].start;
                end = _editor->selection->time[_editor->clicked_selection].end;
 
@@ -3179,11 +3298,6 @@ SelectionDrag::motion (GdkEvent* event, bool first_move)
 
        case SelectionEndTrim:
 
-               if (first_move) {
-                       _editor->begin_reversible_command (_("trim selection end"));
-                       _have_transaction = true;
-               }
-
                start = _editor->selection->time[_editor->clicked_selection].start;
                end = _editor->selection->time[_editor->clicked_selection].end;
 
@@ -3197,11 +3311,6 @@ SelectionDrag::motion (GdkEvent* event, bool first_move)
 
        case SelectionMove:
 
-               if (first_move) {
-                       _editor->begin_reversible_command (_("move selection"));
-                       _have_transaction = true;
-               }
-
                start = _editor->selection->time[_editor->clicked_selection].start;
                end = _editor->selection->time[_editor->clicked_selection].end;
 
@@ -3242,10 +3351,6 @@ SelectionDrag::finished (GdkEvent* event, bool movement_occurred)
                        _editor->selection->TimeChanged ();
                }
 
-               if (_have_transaction) {
-                       _editor->commit_reversible_command ();
-               }
-
                /* XXX what if its a music time selection? */
                if (s && (s->config.get_auto_play() || (s->get_play_range() && s->transport_rolling()))) {
                        s->request_play_range (&_editor->selection->time, true);
@@ -3574,8 +3679,8 @@ NoteDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
        double event_x;
        double event_y;
 
-       event_x = current_pointer_x();
-       event_y = current_pointer_y();
+       event_x = _drags->current_pointer_x();
+       event_y = _drags->current_pointer_y();
 
        _item->property_parent().get_value()->w2i(event_x, event_y);
 
@@ -3612,8 +3717,8 @@ NoteDrag::motion (GdkEvent*, bool)
        double event_x;
        double event_y;
 
-       event_x = current_pointer_x();
-       event_y = current_pointer_y();
+       event_x = _drags->current_pointer_x();
+       event_y = _drags->current_pointer_y();
 
        _item->property_parent().get_value()->w2i(event_x, event_y);
 
@@ -3765,7 +3870,7 @@ AutomationRangeDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
                return;
        }
 
-       _line->start_drag_multiple (points, 1 - (current_pointer_y() / _line->height ()), state);
+       _line->start_drag_multiple (points, 1 - (_drags->current_pointer_y() / _line->height ()), state);
 }
 
 void
@@ -3775,7 +3880,7 @@ AutomationRangeDrag::motion (GdkEvent* event, bool first_move)
                return;
        }
        
-       float const f = 1 - (current_pointer_y() / _line->height());
+       float const f = 1 - (_drags->current_pointer_y() / _line->height());
 
        /* we are ignoring x position for this drag, so we can just pass in anything */
        _line->drag_motion (0, f, true, false);