amend e3da18fd
[ardour.git] / gtk2_ardour / midi_region_view.cc
index 23c761178c1403ec521e513c385af74e3ba56ade..e3179e0f9494dbf9eed994a762849b036e791bd7 100644 (file)
@@ -598,7 +598,7 @@ MidiRegionView::button_release (GdkEventButton* ev)
                break;
        }
 
-       if(_mouse_changed_selection) {
+       if (_mouse_changed_selection) {
                trackview.editor().begin_reversible_selection_op (_("Mouse Selection Change"));
                trackview.editor().commit_reversible_selection_op ();
        }
@@ -758,7 +758,7 @@ MidiRegionView::key_press (GdkEventKey* ev)
                delete_selection();
                return true;
 
-       } else if (ev->keyval == GDK_Tab) {
+       } else if (ev->keyval == GDK_Tab || ev->keyval == GDK_ISO_Left_Tab) {
 
                trackview.editor().begin_reversible_selection_op (_("Select Adjacent Note"));
 
@@ -772,24 +772,6 @@ MidiRegionView::key_press (GdkEventKey* ev)
 
                return true;
 
-       } else if (ev->keyval == GDK_ISO_Left_Tab) {
-
-               /* Shift-TAB generates ISO Left Tab, for some reason */
-
-               trackview.editor().begin_reversible_selection_op (_("Select Adjacent Note"));
-
-               if (Keyboard::modifier_state_contains (ev->state, Keyboard::PrimaryModifier)) {
-                       goto_previous_note (Keyboard::modifier_state_contains (ev->state, Keyboard::TertiaryModifier));
-               } else {
-                       goto_next_note (Keyboard::modifier_state_contains (ev->state, Keyboard::TertiaryModifier));
-               }
-
-               trackview.editor().commit_reversible_selection_op();
-
-               return true;
-
-
-
        } else if (ev->keyval == GDK_Up) {
 
                bool allow_smush = Keyboard::modifier_state_contains (ev->state, Keyboard::TertiaryModifier);
@@ -969,11 +951,12 @@ MidiRegionView::create_note_at (framepos_t t, double y, Evoral::Beats length, bo
 
        view->update_note_range(new_note->note());
 
-       trackview.editor().begin_reversible_command(_("add note"));
-       MidiModel::NoteDiffCommand* cmd = _model->new_note_diff_command(_("add note"));
-       cmd->add (new_note);
-       _model->apply_command(*trackview.session(), cmd);
-       trackview.editor().commit_reversible_command();
+       start_note_diff_command(_("add note"));
+
+       clear_selection ();
+       note_diff_add_note (new_note, true, false);
+
+       apply_diff();
 
        play_midi_note (new_note);
 }
@@ -1007,7 +990,7 @@ MidiRegionView::display_model(boost::shared_ptr<MidiModel> model)
 
        content_connection.disconnect ();
        _model->ContentsChanged.connect (content_connection, invalidator (*this), boost::bind (&MidiRegionView::redisplay_model, this), gui_context());
-       /* Don't signal as nobody else needs to know until selection has been altered.*/
+       /* Don't signal as nobody else needs to know until selection has been altered. */
        clear_events (false);
 
        if (_enable_display) {
@@ -1131,21 +1114,15 @@ MidiRegionView::find_canvas_note (boost::shared_ptr<NoteType> note)
        return 0;
 }
 
-/** This version finds any canvas note matching the supplied note.*/
+/** This version finds any canvas note matching the supplied note. */
 NoteBase*
 MidiRegionView::find_canvas_note (NoteType note)
 {
-       if (_optimization_iterator != _events.end()) {
-               ++_optimization_iterator;
-       }
-
-       if (_optimization_iterator != _events.end() && (*(*_optimization_iterator)->note()) == note) {
-               return *_optimization_iterator;
-       }
+       Events::iterator it;
 
-       for (_optimization_iterator = _events.begin(); _optimization_iterator != _events.end(); ++_optimization_iterator) {
-               if (*((*_optimization_iterator)->note()) == note) {
-                       return *_optimization_iterator;
+       for (it = _events.begin(); it != _events.end(); ++it) {
+               if (*((*it)->note()) == note) {
+                       return *it;
                }
        }
 
@@ -1680,8 +1657,12 @@ MidiRegionView::start_playing_midi_chord (vector<boost::shared_ptr<NoteType> > n
 bool
 MidiRegionView::note_in_region_range (const boost::shared_ptr<NoteType> note, bool& visible) const
 {
+       /* This is imprecise due to all the conversion conversion involved, so only
+          hide notes if they seem to start more than one tick before the start. */
+       const framecnt_t tick_frames       = Evoral::Beats::tick().to_ticks(trackview.session()->frame_rate());
        const framepos_t note_start_frames = source_beats_to_region_frames (note->time());
-       bool outside = (note_start_frames  < 0) || (note_start_frames > _region->last_frame());
+       const bool       outside           = ((note_start_frames <= -tick_frames) ||
+                                             (note_start_frames > _region->last_frame()));
 
        visible = (note->note() >= midi_stream_view()->lowest_note()) &&
                (note->note() <= midi_stream_view()->highest_note());
@@ -1876,10 +1857,12 @@ MidiRegionView::step_add_note (uint8_t channel, uint8_t number, uint8_t velocity
        view->update_note_range(new_note->note());
 
        _marked_for_selection.clear ();
-       clear_selection ();
 
        start_note_diff_command (_("step add"));
+
+       clear_selection ();
        note_diff_add_note (new_note, true, false);
+
        apply_diff();
 
        // last_step_edit_note = new_note;
@@ -2803,7 +2786,7 @@ MidiRegionView::update_resizing (NoteBase* primary, bool at_front, double delta_
 void
 MidiRegionView::commit_resizing (NoteBase* primary, bool at_front, double delta_x, bool relative)
 {
-       start_note_diff_command (_("resize notes"));
+       _note_diff_command = _model->new_note_diff_command (_("resize notes"));
 
        for (std::vector<NoteResizeData *>::iterator i = _resize_data.begin(); i != _resize_data.end(); ++i) {
                Note*  canvas_note = (*i)->note;
@@ -2864,7 +2847,7 @@ MidiRegionView::commit_resizing (NoteBase* primary, bool at_front, double delta_
        }
 
        _resize_data.clear();
-       apply_diff();
+       apply_diff(true);
 }
 
 void
@@ -3442,10 +3425,12 @@ MidiRegionView::selection_as_cut_buffer () const
 bool
 MidiRegionView::paste (framepos_t pos, const ::Selection& selection, PasteContext& ctx)
 {
+       bool commit = false;
        // Paste notes, if available
        MidiNoteSelection::const_iterator m = selection.midi_notes.get_nth(ctx.counts.n_notes());
        if (m != selection.midi_notes.end()) {
                ctx.counts.increase_n_notes();
+               if (!(*m)->empty()) { commit = true; }
                paste_internal(pos, ctx.count, ctx.times, **m);
        }
 
@@ -3453,9 +3438,14 @@ MidiRegionView::paste (framepos_t pos, const ::Selection& selection, PasteContex
        typedef RouteTimeAxisView::AutomationTracks ATracks;
        const ATracks& atracks = midi_view()->automation_tracks();
        for (ATracks::const_iterator a = atracks.begin(); a != atracks.end(); ++a) {
-               a->second->paste(pos, selection, ctx);
+               if (a->second->paste(pos, selection, ctx)) {
+                       commit = true;
+               }
        }
 
+       if (commit) {
+               trackview.editor().commit_reversible_command ();
+       }
        return true;
 }