Support cut/copy/paste of several regions and lines at once.
[ardour.git] / gtk2_ardour / route_time_axis.cc
index 31c2eb171229879b7a02dc681e20efd56026bdfb..1d89833b79ba254b1fffd52cb51c100b89ecbb6a 100644 (file)
@@ -63,6 +63,7 @@
 #include "automation_time_axis.h"
 #include "enums.h"
 #include "gui_thread.h"
+#include "item_counts.h"
 #include "keyboard.h"
 #include "playlist_selector.h"
 #include "point_selection.h"
@@ -1534,20 +1535,20 @@ RouteTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op)
 }
 
 bool
-RouteTimeAxisView::paste (framepos_t pos, float times, Selection& selection, size_t nth)
+RouteTimeAxisView::paste (framepos_t pos, unsigned paste_count, float times, const Selection& selection, ItemCounts& counts)
 {
        if (!is_track()) {
                return false;
        }
 
-       boost::shared_ptr<Playlist> pl = playlist ();
-       PlaylistSelection::iterator p;
-
-       for (p = selection.playlists.begin(); p != selection.playlists.end() && nth; ++p, --nth) {}
+       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));
 
        if (p == selection.playlists.end()) {
                return false;
        }
+       counts.increase_n_playlists(type);
 
         DEBUG_TRACE (DEBUG::CutNPaste, string_compose ("paste to %1\n", pos));
 
@@ -1556,6 +1557,11 @@ RouteTimeAxisView::paste (framepos_t pos, float times, Selection& selection, siz
                 DEBUG_TRACE (DEBUG::CutNPaste, string_compose ("modified paste to %1\n", pos));
        }
 
+       /* 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);
+
        pl->clear_changes ();
        if (Config->get_edit_mode() == Ripple) {
                std::pair<framepos_t, framepos_t> extent = (*p)->get_extent_with_endspace();
@@ -2015,7 +2021,7 @@ RouteTimeAxisView::add_processor_automation_curve (boost::shared_ptr<Processor>
                      << string_compose (X_("processor automation curve for %1:%2/%3/%4 not registered with track!"),
                                          processor->name(), what.type(), (int) what.channel(), what.id() )
                      << endmsg;
-               /*NOTREACHED*/
+               abort(); /*NOTREACHED*/
                return;
        }
 
@@ -2481,7 +2487,7 @@ RouteTimeAxisView::add_underlay (StreamView* v, bool /*update_xml*/)
        if (find(_underlay_streams.begin(), _underlay_streams.end(), v) == _underlay_streams.end()) {
                if (find(other._underlay_mirrors.begin(), other._underlay_mirrors.end(), this) != other._underlay_mirrors.end()) {
                        fatal << _("programming error: underlay reference pointer pairs are inconsistent!") << endmsg;
-                       /*NOTREACHED*/
+                       abort(); /*NOTREACHED*/
                }
 
                _underlay_streams.push_back(v);
@@ -2518,7 +2524,7 @@ RouteTimeAxisView::remove_underlay (StreamView* v)
 
                if (gm == other._underlay_mirrors.end()) {
                        fatal << _("programming error: underlay reference pointer pairs are inconsistent!") << endmsg;
-                       /*NOTREACHED*/
+                       abort(); /*NOTREACHED*/
                }
 
                v->foreach_regionview(sigc::mem_fun(*this, &RouteTimeAxisView::remove_ghost));