diff options
-rw-r--r-- | gtk2_ardour/automation_time_axis.cc | 24 | ||||
-rw-r--r-- | gtk2_ardour/automation_time_axis.h | 4 | ||||
-rw-r--r-- | gtk2_ardour/editor_ops.cc | 22 | ||||
-rw-r--r-- | gtk2_ardour/midi_region_view.cc | 11 | ||||
-rw-r--r-- | gtk2_ardour/midi_region_view.h | 2 | ||||
-rw-r--r-- | gtk2_ardour/paste_context.h | 41 | ||||
-rw-r--r-- | gtk2_ardour/route_time_axis.cc | 13 | ||||
-rw-r--r-- | gtk2_ardour/route_time_axis.h | 2 | ||||
-rw-r--r-- | gtk2_ardour/time_axis_view.h | 10 |
9 files changed, 96 insertions, 33 deletions
diff --git a/gtk2_ardour/automation_time_axis.cc b/gtk2_ardour/automation_time_axis.cc index 67e7c06421..e2a0effb39 100644 --- a/gtk2_ardour/automation_time_axis.cc +++ b/gtk2_ardour/automation_time_axis.cc @@ -43,6 +43,7 @@ #include "gui_thread.h" #include "route_time_axis.h" #include "automation_line.h" +#include "paste_context.h" #include "public_editor.h" #include "selection.h" #include "rgb_macros.h" @@ -633,14 +634,19 @@ AutomationTimeAxisView::add_automation_event (GdkEvent* event, framepos_t when, } bool -AutomationTimeAxisView::paste (framepos_t pos, unsigned paste_count, float times, const Selection& selection, ItemCounts& counts) +AutomationTimeAxisView::paste (framepos_t pos, const Selection& selection, PasteContext& ctx) { if (_line) { - return paste_one (pos, paste_count, times, selection, counts); + return paste_one (pos, ctx.count, ctx.times, selection, ctx.counts, ctx.greedy); } else if (_view) { - AutomationSelection::const_iterator l = selection.lines.get_nth(_parameter, counts.n_lines(_parameter)); - if (l != selection.lines.end() && _view->paste (pos, paste_count, times, *l)) { - counts.increase_n_lines(_parameter); + AutomationSelection::const_iterator l = selection.lines.get_nth(_parameter, ctx.counts.n_lines(_parameter)); + if (l == selection.lines.end()) { + if (ctx.greedy && selection.lines.size() == 1) { + l = selection.lines.begin(); + } + } + if (l != selection.lines.end() && _view->paste (pos, ctx.count, ctx.times, *l)) { + ctx.counts.increase_n_lines(_parameter); return true; } } @@ -649,7 +655,7 @@ AutomationTimeAxisView::paste (framepos_t pos, unsigned paste_count, float times } bool -AutomationTimeAxisView::paste_one (framepos_t pos, unsigned paste_count, float times, const Selection& selection, ItemCounts& counts) +AutomationTimeAxisView::paste_one (framepos_t pos, unsigned paste_count, float times, const Selection& selection, ItemCounts& counts, bool greedy) { boost::shared_ptr<AutomationList> alist(_line->the_list()); @@ -661,7 +667,11 @@ AutomationTimeAxisView::paste_one (framepos_t pos, unsigned paste_count, float t /* Get appropriate list from selection. */ AutomationSelection::const_iterator p = selection.lines.get_nth(_parameter, counts.n_lines(_parameter)); if (p == selection.lines.end()) { - return false; + if (greedy && selection.lines.size() == 1) { + p = selection.lines.begin(); + } else { + return false; + } } counts.increase_n_lines(_parameter); diff --git a/gtk2_ardour/automation_time_axis.h b/gtk2_ardour/automation_time_axis.h index 156a5701e3..b726de6440 100644 --- a/gtk2_ardour/automation_time_axis.h +++ b/gtk2_ardour/automation_time_axis.h @@ -93,7 +93,7 @@ class AutomationTimeAxisView : public TimeAxisView { /* editing operations */ void cut_copy_clear (Selection&, Editing::CutCopyOp); - bool paste (ARDOUR::framepos_t, unsigned paste_count, float times, const Selection&, ItemCounts&); + bool paste (ARDOUR::framepos_t, const Selection&, PasteContext&); int set_state (const XMLNode&, int version); @@ -175,7 +175,7 @@ class AutomationTimeAxisView : public TimeAxisView { void build_display_menu (); void cut_copy_clear_one (AutomationLine&, Selection&, Editing::CutCopyOp); - bool paste_one (ARDOUR::framepos_t, unsigned, float times, const Selection&, ItemCounts& counts); + bool paste_one (ARDOUR::framepos_t, unsigned, float times, const Selection&, ItemCounts& counts, bool greedy=false); void route_going_away (); void set_automation_state (ARDOUR::AutoState); diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index 00703dfc94..c84bae6ad4 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -83,6 +83,7 @@ #include "mixer_strip.h" #include "mouse_cursors.h" #include "normalize_dialog.h" +#include "paste_context.h" #include "patch_change_dialog.h" #include "quantize_dialog.h" #include "region_gain_line.h" @@ -4446,11 +4447,24 @@ Editor::paste_internal (framepos_t position, float times) RegionSelection rs; get_regions_at (rs, position, ts); - ItemCounts counts; + if (ts.size() == 1 && cut_buffer->lines.size() == 1) { + AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*>(ts.front()); + if (atv) { + /* Only one line, and one automation track selected. Do a + "greedy" paste from one automation type to another. */ + PasteContext ctx(paste_count, times, ItemCounts(), true); + begin_reversible_command (Operations::paste); + atv->paste (position, *cut_buffer, ctx); + commit_reversible_command (); + return; + } + } + + PasteContext ctx(paste_count, times, ItemCounts(), false); for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ++r) { MidiRegionView* mrv = dynamic_cast<MidiRegionView*> (*r); if (mrv) { - mrv->paste (position, paste_count, times, *cut_buffer, counts); + mrv->paste (position, *cut_buffer, ctx); } } @@ -4460,9 +4474,9 @@ Editor::paste_internal (framepos_t position, float times) begin_reversible_command (Operations::paste); - ItemCounts counts; + PasteContext ctx(paste_count, times, ItemCounts(), false); for (TrackViewList::iterator i = ts.begin(); i != ts.end(); ++i) { - (*i)->paste (position, paste_count, times, *cut_buffer, counts); + (*i)->paste (position, *cut_buffer, ctx); } commit_reversible_command (); diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index 54c37267a7..bad479bc26 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -66,6 +66,7 @@ #include "midi_velocity_dialog.h" #include "mouse_cursors.h" #include "note_player.h" +#include "paste_context.h" #include "public_editor.h" #include "route_time_axis.h" #include "rgb_macros.h" @@ -3322,22 +3323,22 @@ MidiRegionView::selection_as_cut_buffer () const /** This method handles undo */ bool -MidiRegionView::paste (framepos_t pos, unsigned paste_count, float times, const ::Selection& selection, ItemCounts& counts) +MidiRegionView::paste (framepos_t pos, const ::Selection& selection, PasteContext& ctx) { trackview.session()->begin_reversible_command (Operations::paste); // Paste notes, if available - MidiNoteSelection::const_iterator m = selection.midi_notes.get_nth(counts.n_notes()); + MidiNoteSelection::const_iterator m = selection.midi_notes.get_nth(ctx.counts.n_notes()); if (m != selection.midi_notes.end()) { - counts.increase_n_notes(); - paste_internal(pos, paste_count, times, **m); + ctx.counts.increase_n_notes(); + paste_internal(pos, ctx.count, ctx.times, **m); } // Paste control points to automation children, if available 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, paste_count, times, selection, counts); + a->second->paste(pos, selection, ctx); } trackview.session()->commit_reversible_command (); diff --git a/gtk2_ardour/midi_region_view.h b/gtk2_ardour/midi_region_view.h index 08005497df..e846fc2764 100644 --- a/gtk2_ardour/midi_region_view.h +++ b/gtk2_ardour/midi_region_view.h @@ -113,7 +113,7 @@ public: void resolve_note(uint8_t note_num, Evoral::MusicalTime end_time); void cut_copy_clear (Editing::CutCopyOp); - bool paste (framepos_t pos, unsigned paste_count, float times, const ::Selection& selection, ItemCounts& counts); + bool paste (framepos_t pos, const ::Selection& selection, PasteContext& ctx); void paste_internal (framepos_t pos, unsigned paste_count, float times, const MidiCutBuffer&); void add_canvas_patch_change (ARDOUR::MidiModel::PatchChangePtr patch, const std::string& displaytext, bool); diff --git a/gtk2_ardour/paste_context.h b/gtk2_ardour/paste_context.h new file mode 100644 index 0000000000..418ee98acf --- /dev/null +++ b/gtk2_ardour/paste_context.h @@ -0,0 +1,41 @@ +/* + Copyright (C) 2014 Paul Davis + Author: David Robillard + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __ardour_paste_context_h__ +#define __ardour_paste_context_h__ + +#include "item_counts.h" + +class PasteContext +{ +public: + PasteContext(unsigned count, float times, ItemCounts counts, bool greedy) + : count(count) + , times(times) + , counts(counts) + , greedy(greedy) + {} + + unsigned count; ///< Number of previous pastes to the same position + float times; ///< Number of times to paste + ItemCounts counts; ///< Count of consumed selection items + bool greedy; ///< If true, greedily steal items that don't match +}; + +#endif /* __ardour_paste_context_h__ */ diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc index d741b70501..0e71f858a4 100644 --- a/gtk2_ardour/route_time_axis.cc +++ b/gtk2_ardour/route_time_axis.cc @@ -67,6 +67,7 @@ #include "gui_thread.h" #include "item_counts.h" #include "keyboard.h" +#include "paste_context.h" #include "playlist_selector.h" #include "point_selection.h" #include "prompter.h" @@ -1572,7 +1573,7 @@ RouteTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op) } bool -RouteTimeAxisView::paste (framepos_t pos, unsigned paste_count, float times, const Selection& selection, ItemCounts& counts) +RouteTimeAxisView::paste (framepos_t pos, const Selection& selection, PasteContext& ctx) { if (!is_track()) { return false; @@ -1580,12 +1581,12 @@ RouteTimeAxisView::paste (framepos_t pos, unsigned paste_count, float times, con boost::shared_ptr<Playlist> pl = playlist (); const ARDOUR::DataType type = pl->data_type(); - PlaylistSelection::const_iterator p = selection.playlists.get_nth(type, counts.n_playlists(type)); + PlaylistSelection::const_iterator p = selection.playlists.get_nth(type, ctx.counts.n_playlists(type)); if (p == selection.playlists.end()) { return false; } - counts.increase_n_playlists(type); + ctx.counts.increase_n_playlists(type); DEBUG_TRACE (DEBUG::CutNPaste, string_compose ("paste to %1\n", pos)); @@ -1597,15 +1598,15 @@ RouteTimeAxisView::paste (framepos_t pos, unsigned paste_count, float times, con /* add multi-paste offset if applicable */ std::pair<framepos_t, framepos_t> extent = (*p)->get_extent(); const framecnt_t duration = extent.second - extent.first; - pos += _editor.get_paste_offset(pos, paste_count, duration); + pos += _editor.get_paste_offset(pos, ctx.count, duration); pl->clear_changes (); if (Config->get_edit_mode() == Ripple) { std::pair<framepos_t, framepos_t> extent = (*p)->get_extent_with_endspace(); framecnt_t amount = extent.second - extent.first; - pl->ripple(pos, amount * times, boost::shared_ptr<Region>()); + pl->ripple(pos, amount * ctx.times, boost::shared_ptr<Region>()); } - pl->paste (*p, pos, times); + pl->paste (*p, pos, ctx.times); vector<Command*> cmds; pl->rdiff (cmds); diff --git a/gtk2_ardour/route_time_axis.h b/gtk2_ardour/route_time_axis.h index 008ed932de..7ea86e9b1b 100644 --- a/gtk2_ardour/route_time_axis.h +++ b/gtk2_ardour/route_time_axis.h @@ -100,7 +100,7 @@ public: /* Editing operations */ void cut_copy_clear (Selection&, Editing::CutCopyOp); - bool paste (ARDOUR::framepos_t, unsigned paste_count, float times, const Selection&, ItemCounts&); + bool paste (ARDOUR::framepos_t, const Selection&, PasteContext& ctx); RegionView* combine_regions (); void uncombine_regions (); void uncombine_region (RegionView*); diff --git a/gtk2_ardour/time_axis_view.h b/gtk2_ardour/time_axis_view.h index c46d23ae58..6dc02110c2 100644 --- a/gtk2_ardour/time_axis_view.h +++ b/gtk2_ardour/time_axis_view.h @@ -79,6 +79,7 @@ class GhostRegion; class StreamView; class ArdourDialog; class ItemCounts; +class PasteContext; /** Abstract base class for time-axis views (horizontal editor 'strips') * @@ -169,17 +170,12 @@ class TimeAxisView : public virtual AxisView /** Paste a selection. * @param pos Position to paste to (session frames). - * @param paste_count Number of pastes to the same location previously (multi-paste). - * @param times Number of times to paste. * @param selection Selection to paste. - * @param counts Count of consumed selection items (used to find the - * correct item to paste here, then updated for the next pastee). + * @param ctx Paste context. */ virtual bool paste (ARDOUR::framepos_t pos, - unsigned paste_count, - float times, const Selection& selection, - ItemCounts& counts) { return false; } + PasteContext& ctx) { return false; } virtual void set_selected_regionviews (RegionSelection&) {} virtual void set_selected_points (PointSelection&) {} |