summaryrefslogtreecommitdiff
path: root/gtk2_ardour/editor_ops.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gtk2_ardour/editor_ops.cc')
-rw-r--r--gtk2_ardour/editor_ops.cc90
1 files changed, 77 insertions, 13 deletions
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index 6b48311b15..bae511e031 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -63,6 +63,7 @@
#include "route_time_axis.h"
#include "audio_time_axis.h"
#include "automation_time_axis.h"
+#include "control_point.h"
#include "streamview.h"
#include "audio_streamview.h"
#include "audio_region_view.h"
@@ -3721,19 +3722,87 @@ Editor::cut_copy (CutCopyOp op)
}
}
+struct AutomationRecord {
+ AutomationRecord () : state (0) {}
+ AutomationRecord (XMLNode* s) : state (s) {}
+
+ XMLNode* state; ///< state before any operation
+ boost::shared_ptr<Evoral::ControlList> copy; ///< copied events for the cut buffer
+};
+
/** Cut, copy or clear selected automation points.
- * @param op Operation (Cut, Copy or Clear)
+ * @param op Operation (Cut, Copy or Clear)
*/
void
Editor::cut_copy_points (CutCopyOp op)
{
+ if (selection->points.empty ()) {
+ return;
+ }
+
+ /* XXX: not ideal, as there may be more than one track involved in the point selection */
+ _last_cut_copy_source_track = &selection->points.front()->line().trackview;
+
+ /* Keep a record of the AutomationLists that we end up using in this operation */
+ typedef std::map<boost::shared_ptr<AutomationList>, AutomationRecord> Lists;
+ Lists lists;
+
+ /* Go through all selected points, making an AutomationRecord for each distinct AutomationList */
for (PointSelection::iterator i = selection->points.begin(); i != selection->points.end(); ++i) {
+ 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 ());
+ }
- AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*>((*i).track);
- _last_cut_copy_source_track = atv;
+ /* 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;
+ }
- if (atv) {
- atv->cut_copy_clear_objects (selection->points, op);
+ /* 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 ();
+ }
+
+ /* Remove each selected point from its AutomationList */
+ for (PointSelection::iterator i = selection->points.begin(); i != selection->points.end(); ++i) {
+ boost::shared_ptr<AutomationList> al = (*i)->line().the_list();
+ al->erase ((*i)->model ());
+ }
+
+ /* Thaw the lists and add undo records for them */
+ for (Lists::iterator i = lists.begin(); i != lists.end(); ++i) {
+ boost::shared_ptr<AutomationList> al = i->first;
+ al->thaw ();
+ _session->add_command (new MementoCommand<AutomationList> (*al.get(), i->second.state, &(al->get_state ())));
}
}
}
@@ -4229,18 +4298,13 @@ Editor::duplicate_selection (float times)
commit_reversible_command ();
}
+/** Reset all selected points to the relevant default value */
void
Editor::reset_point_selection ()
{
- /* reset all selected points to the relevant default value */
-
for (PointSelection::iterator i = selection->points.begin(); i != selection->points.end(); ++i) {
-
- AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*>((*i).track);
-
- if (atv) {
- atv->reset_objects (selection->points);
- }
+ ARDOUR::AutomationList::iterator j = (*i)->model ();
+ (*j)->value = (*i)->line().the_list()->default_value ();
}
}