summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk2_ardour/automation_time_axis.cc24
-rw-r--r--gtk2_ardour/automation_time_axis.h4
-rw-r--r--gtk2_ardour/editor_ops.cc22
-rw-r--r--gtk2_ardour/midi_region_view.cc11
-rw-r--r--gtk2_ardour/midi_region_view.h2
-rw-r--r--gtk2_ardour/paste_context.h41
-rw-r--r--gtk2_ardour/route_time_axis.cc13
-rw-r--r--gtk2_ardour/route_time_axis.h2
-rw-r--r--gtk2_ardour/time_axis_view.h10
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&) {}