Fix up undo/redo of MIDI note paste (#3815).
authorCarl Hetherington <carl@carlh.net>
Wed, 2 Mar 2011 16:18:59 +0000 (16:18 +0000)
committerCarl Hetherington <carl@carlh.net>
Wed, 2 Mar 2011 16:18:59 +0000 (16:18 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@9033 d708f5d6-7413-0410-9779-e7cbd77b26cf

gtk2_ardour/editor_ops.cc
gtk2_ardour/midi_region_view.cc
gtk2_ardour/midi_region_view.h

index d6e3761f3f87641c2dd454f287981d312eb5ebd7..e521beb64f87c89af8378f209db156a4f304f1e3 100644 (file)
@@ -3911,8 +3911,6 @@ Editor::mouse_paste ()
 void
 Editor::paste_internal (framepos_t position, float times)
 {
-       bool commit = false;
-
         DEBUG_TRACE (DEBUG::CutNPaste, string_compose ("apparent paste position is %1\n", position));
 
        if (internal_editing()) {
@@ -3930,8 +3928,6 @@ Editor::paste_internal (framepos_t position, float times)
                 DEBUG_TRACE (DEBUG::CutNPaste, string_compose ("preferred edit position is %1\n", position));
        }
 
-       begin_reversible_command (Operations::paste);
-
        TrackViewList ts;
        TrackViewList::iterator i;
        size_t nth;
@@ -3949,18 +3945,18 @@ Editor::paste_internal (framepos_t position, float times)
                ts.push_back (_last_cut_copy_source_track);
        }
 
-       for (nth = 0, i = ts.begin(); i != ts.end(); ++i, ++nth) {
+       if (internal_editing ()) {
 
                /* undo/redo is handled by individual tracks/regions */
-
-               if (internal_editing()) {
-
+               
+               for (nth = 0, i = ts.begin(); i != ts.end(); ++i, ++nth) {
+                       
                        RegionSelection rs;
                        RegionSelection::iterator r;
                        MidiNoteSelection::iterator cb;
-
+                       
                        get_regions_at (rs, position, ts);
-
+                       
                        for (cb = cut_buffer->midi_notes.begin(), r = rs.begin();
                             cb != cut_buffer->midi_notes.end() && r != rs.end(); ++r) {
                                MidiRegionView* mrv = dynamic_cast<MidiRegionView*> (*r);
@@ -3969,16 +3965,18 @@ Editor::paste_internal (framepos_t position, float times)
                                        ++cb;
                                }
                        }
+               }
+               
+       } else {
 
-               } else {
+               /* we do redo (do you do voodoo?) */
 
-                       if ((*i)->paste (position, times, *cut_buffer, nth)) {
-                               commit = true;
-                       }
+               begin_reversible_command (Operations::paste);
+               
+               for (nth = 0, i = ts.begin(); i != ts.end(); ++i, ++nth) {
+                       (*i)->paste (position, times, *cut_buffer, nth);
                }
-       }
-
-       if (commit) {
+               
                commit_reversible_command ();
        }
 }
index f7b9c8f9e0cc5808ed16afd16822ea61d81f77ee..24ad86f7d6f18c7a4571bf3af3828252ca6bd87a 100644 (file)
@@ -921,7 +921,7 @@ MidiRegionView::note_diff_add_change (ArdourCanvas::CanvasNoteEvent* ev,
 }
 
 void
-MidiRegionView::apply_diff ()
+MidiRegionView::apply_diff (bool as_subcommand)
 {
         bool add_or_remove;
 
@@ -936,7 +936,12 @@ MidiRegionView::apply_diff ()
                 }
         }
 
-       _model->apply_command(*trackview.session(), _note_diff_command);
+       if (as_subcommand) {
+               _model->apply_command_as_subcommand (*trackview.session(), _note_diff_command);
+       } else {
+               _model->apply_command (*trackview.session(), _note_diff_command);
+       }
+       
        _note_diff_command = 0;
        midi_view()->midi_track()->playlist_modified();
         
@@ -947,33 +952,6 @@ MidiRegionView::apply_diff ()
        _marked_for_velocity.clear();
 }
 
-void
-MidiRegionView::apply_diff_as_subcommand ()
-{
-        bool add_or_remove;
-
-       if (!_note_diff_command) {
-               return;
-       }
-
-        if ((add_or_remove = _note_diff_command->adds_or_removes())) {
-                // Mark all selected notes for selection when model reloads
-                for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i) {
-                        _marked_for_selection.insert((*i)->note());
-                }
-        }
-
-       _model->apply_command_as_subcommand(*trackview.session(), _note_diff_command);
-       _note_diff_command = 0;
-       midi_view()->midi_track()->playlist_modified();
-
-        if (add_or_remove) {
-                _marked_for_selection.clear();
-        }
-       _marked_for_velocity.clear();
-}
-
-
 void
 MidiRegionView::abort_command()
 {
@@ -2976,6 +2954,7 @@ MidiRegionView::selection_as_cut_buffer () const
        return cb;
 }
 
+/** This method handles undo */
 void
 MidiRegionView::paste (framepos_t pos, float times, const MidiCutBuffer& mcb)
 {
@@ -2985,6 +2964,8 @@ MidiRegionView::paste (framepos_t pos, float times, const MidiCutBuffer& mcb)
 
         DEBUG_TRACE (DEBUG::CutNPaste, string_compose ("MIDI paste @ %1 times %2\n", pos, times));
 
+       trackview.session()->begin_reversible_command (_("paste"));
+
        start_note_diff_command (_("paste"));
 
        Evoral::MusicalTime beat_delta;
@@ -3030,14 +3011,14 @@ MidiRegionView::paste (framepos_t pos, float times, const MidiCutBuffer& mcb)
 
                 DEBUG_TRACE (DEBUG::CutNPaste, string_compose ("Paste extended region from %1 to %2\n", region_end, end_frame));
 
-               trackview.session()->begin_reversible_command (_("paste"));
-
                 _region->clear_changes ();
                _region->set_length (end_frame, this);
                trackview.session()->add_command (new StatefulDiffCommand (_region));
        }
 
-       apply_diff ();
+       apply_diff (true);
+       
+       trackview.session()->commit_reversible_command ();
 }
 
 struct EventNoteTimeEarlyFirstComparator {
index d7634141fb8691146e5ab5090268c263e835ee43..ccd6a82dec7c9385886fa7cbf941d938b1d9390b 100644 (file)
@@ -176,8 +176,7 @@ class MidiRegionView : public RegionView
        void note_diff_add_note (const boost::shared_ptr<NoteType> note, bool selected, bool show_velocity = false);
        void note_diff_remove_note (ArdourCanvas::CanvasNoteEvent* ev);
 
-       void apply_diff();
-       void apply_diff_as_subcommand();
+       void apply_diff (bool as_subcommand = false);
        void abort_command();
 
        void   note_entered(ArdourCanvas::CanvasNoteEvent* ev);