+ boost::shared_ptr<AutomationList> al = (*i)->line().the_list();
+ if (lists.find (al) == lists.end ()) {
+ /* We haven't seen this list yet, so make a record for it. This includes
+ taking a copy of its current state, in case this is needed for undo later.
+ */
+ lists[al] = AutomationRecord (&al->get_state ());
+ }
+ }
+
+ if (op == Cut || op == Copy) {
+ /* This operation will involve putting things in the cut buffer, so create an empty
+ ControlList for each of our source lists to put the cut buffer data in.
+ */
+ for (Lists::iterator i = lists.begin(); i != lists.end(); ++i) {
+ i->second.copy = i->first->create (i->first->parameter ());
+ }
+
+ /* Add all selected points to the relevant copy ControlLists */
+ for (PointSelection::iterator i = selection->points.begin(); i != selection->points.end(); ++i) {
+ boost::shared_ptr<AutomationList> al = (*i)->line().the_list();
+ AutomationList::const_iterator j = (*i)->model ();
+ lists[al].copy->add ((*j)->when, (*j)->value);
+ }
+
+ for (Lists::iterator i = lists.begin(); i != lists.end(); ++i) {
+ /* Correct this copy list so that it starts at time 0 */
+ double const start = i->second.copy->front()->when;
+ for (AutomationList::iterator j = i->second.copy->begin(); j != i->second.copy->end(); ++j) {
+ (*j)->when -= start;
+ }
+
+ /* And add it to the cut buffer */
+ cut_buffer->add (i->second.copy);
+ }
+ }
+
+ if (op == Delete || op == Cut) {
+ /* This operation needs to remove things from the main AutomationList, so do that now */
+
+ for (Lists::iterator i = lists.begin(); i != lists.end(); ++i) {
+ i->first->freeze ();
+ }