# HG changeset patch # User Chris Cannam # Date 1480066733 0 # Node ID 22f66068b464abca422ba876d42ef08c9477de86 # Parent fa574c909c3db7dc9ef6f2294e100315553b0498 Implement "Subdivide Selected Instants". Also add the relabel command to the history, which I previously forgot to do! diff -r fa574c909c3d -r 22f66068b464 data/model/Labeller.h --- a/data/model/Labeller.h Thu Nov 24 17:06:31 2016 +0000 +++ b/data/model/Labeller.h Fri Nov 25 09:38:53 2016 +0000 @@ -171,8 +171,14 @@ } } + /** + * Relabel all points in the given model that lie within the given + * multi-selection, according to the labelling properties of this + * labeller. Return a command that has been executed but not yet + * added to the history. + */ template - void labelAll(SparseModel &model, MultiSelection *ms) { + Command *labelAll(SparseModel &model, MultiSelection *ms) { typename SparseModel::PointList::iterator i; typename SparseModel::PointList pl(model.getPoints()); @@ -215,7 +221,61 @@ prevPoint = p; } - command->finish(); + return command->finish(); + } + + /** + * For each point in the given model (except the last), if that + * point lies within the given multi-selection, add n-1 new points + * at equally spaced intervals between it and the following point. + * Return a command that has been executed but not yet added to + * the history. + */ + template + Command *subdivide(SparseModel &model, MultiSelection *ms, int n) { + + typename SparseModel::PointList::iterator i; + typename SparseModel::PointList pl(model.getPoints()); + + typename SparseModel::EditCommand *command = + new typename SparseModel::EditCommand + (&model, tr("Subdivide")); + + for (i = pl.begin(); i != pl.end(); ++i) { + + auto j = i; + // require a "next point" even if it's not in selection + if (++j == pl.end()) { + break; + } + + bool inRange = true; + if (ms) { + Selection s(ms->getContainingSelection(i->frame, false)); + if (s.isEmpty() || !s.contains(i->frame)) { + inRange = false; + } + } + if (!inRange) { + continue; + } + + PointType p(*i); + PointType nextP(*j); + + // n is the number of subdivisions, so we add n-1 new + // points equally spaced between p and nextP + + for (int m = 1; m < n; ++m) { + sv_frame_t f = p.frame + (m * (nextP.frame - p.frame)) / n; + PointType newPoint(p); + newPoint.frame = f; + newPoint.label = tr("%1.%2").arg(p.label).arg(m+1); + command->addPoint(newPoint); + } + } + + return command->finish(); } template