Skip to content

Commit dda27cd

Browse files
committed
Allow removing multiple control points
It was surprising that removing on multiple selected control points only removed one of them. This allows selecting multiple points by dragging a box or Ctrl-clicking, then removing all from the context menu of one of the points. Some more trivial implementations of this suffered from problems when deletion of control points in the model also invalidated the iterator over selected control points.
1 parent 80d6aa1 commit dda27cd

File tree

5 files changed

+29
-9
lines changed

5 files changed

+29
-9
lines changed

Diff for: gtk2_ardour/automation_line.cc

+10-2
Original file line numberDiff line numberDiff line change
@@ -926,13 +926,21 @@ AutomationLine::is_first_point (ControlPoint& cp)
926926

927927
// This is copied into AudioRegionGainLine
928928
void
929-
AutomationLine::remove_point (ControlPoint& cp)
929+
AutomationLine::remove_points (std::vector<ControlPoint*> const& cps)
930930
{
931931
trackview.editor().begin_reversible_command (_("remove control point"));
932932
XMLNode &before = alist->get_state();
933933

934934
trackview.editor ().get_selection ().clear_points ();
935-
alist->erase (cp.model());
935+
936+
// Extract models before the ControlPoints iterator mutates on ControlPoint deletion
937+
std::list<Evoral::ControlList::iterator> models;
938+
for (auto const & cp : cps) {
939+
models.push_back(cp->model());
940+
}
941+
for (auto const & model : models) {
942+
alist->erase (model);
943+
}
936944

937945
trackview.editor().session()->add_command(
938946
new MementoCommand<AutomationList> (memento_command_binder (), &before, &alist->get_state()));

Diff for: gtk2_ardour/automation_line.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ class AutomationLine : public sigc::trackable, public PBD::StatefulDestructible
8585
void get_selectables (Temporal::timepos_t const &, Temporal::timepos_t const &, double, double, std::list<Selectable*>&);
8686
void get_inverted_selectables (Selection&, std::list<Selectable*>& results);
8787

88-
virtual void remove_point (ControlPoint&);
8988
bool control_points_adjacent (double xval, uint32_t& before, uint32_t& after);
9089

9190
/* dragging API */
@@ -150,6 +149,7 @@ class AutomationLine : public sigc::trackable, public PBD::StatefulDestructible
150149
void set_colors();
151150

152151
void modify_points_y (std::vector<ControlPoint*> const&, double);
152+
virtual void remove_points (std::vector<ControlPoint*> const& cps);
153153

154154
virtual MementoCommandBinder<ARDOUR::AutomationList>* memento_command_binder ();
155155

Diff for: gtk2_ardour/editor_mouse.cc

+7-3
Original file line numberDiff line numberDiff line change
@@ -2476,11 +2476,15 @@ Editor::remove_control_point (ArdourCanvas::Item* item)
24762476
abort(); /*NOTREACHED*/
24772477
}
24782478

2479-
if (!can_remove_control_point (*control_point)) {
2480-
return;
2479+
std::vector<ControlPoint*> cps;
2480+
2481+
for (auto const& cp : selection->points) {
2482+
if ((&cp->line() == &control_point->line ()) && can_remove_control_point (*cp)) {
2483+
cps.push_back (cp);
2484+
}
24812485
}
24822486

2483-
control_point->line().remove_point (*control_point);
2487+
control_point->line().remove_points (cps);
24842488
}
24852489

24862490
void

Diff for: gtk2_ardour/region_gain_line.cc

+10-2
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ AudioRegionGainLine::start_drag_single (ControlPoint* cp, double x, float fracti
7979

8080
// This is an extended copy from AutomationList
8181
void
82-
AudioRegionGainLine::remove_point (ControlPoint& cp)
82+
AudioRegionGainLine::remove_points (std::vector<ControlPoint*> const& cps)
8383
{
8484
trackview.editor().begin_reversible_command (_("remove control point"));
8585
XMLNode &before = alist->get_state();
@@ -91,7 +91,15 @@ AudioRegionGainLine::remove_point (ControlPoint& cp)
9191
}
9292

9393
trackview.editor ().get_selection ().clear_points ();
94-
alist->erase (cp.model());
94+
95+
// Extract models before the ControlPoints iterator mutates on ControlPoint deletion
96+
std::list<Evoral::ControlList::iterator> models;
97+
for (auto const & cp : cps) {
98+
models.push_back(cp->model());
99+
}
100+
for (auto const & model : models) {
101+
alist->erase (model);
102+
}
95103

96104
trackview.editor().session()->add_command (new MementoCommand<AutomationList>(*alist.get(), &before, &alist->get_state()));
97105
trackview.editor().commit_reversible_command ();

Diff for: gtk2_ardour/region_gain_line.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class AudioRegionGainLine : public AutomationLine
4747
void start_drag_single (ControlPoint*, double, float);
4848
void end_drag (bool with_push, uint32_t final_index);
4949

50-
void remove_point (ControlPoint&);
50+
void remove_points (std::vector<ControlPoint*> const& cps);
5151
AudioRegionView& region_view () { return rv; }
5252

5353
private:

0 commit comments

Comments
 (0)