diff data/model/Labeller.h @ 1365:3382d914e110

Merge from branch 3.0-integration
author Chris Cannam
date Fri, 13 Jan 2017 10:29:44 +0000
parents 114de081a42d
children ad5f892c0c4d
line wrap: on
line diff
--- a/data/model/Labeller.h	Mon Nov 21 16:32:58 2016 +0000
+++ b/data/model/Labeller.h	Fri Jan 13 10:29:44 2017 +0000
@@ -171,37 +171,35 @@
         }
     }
         
+    /**
+     * 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 <typename PointType>
-    void labelAll(SparseModel<PointType> &model, MultiSelection *ms) {
+    Command *labelAll(SparseModel<PointType> &model, MultiSelection *ms) {
 
-        typename SparseModel<PointType>::PointList::iterator i;
-        typename SparseModel<PointType>::PointList pl(model.getPoints());
-
-        typename SparseModel<PointType>::EditCommand *command =
-            new typename SparseModel<PointType>::EditCommand
+        auto points(model.getPoints());
+        auto command = new typename SparseModel<PointType>::EditCommand
             (&model, tr("Label Points"));
 
         PointType prevPoint(0);
+        bool havePrevPoint(false);
 
-        for (i = pl.begin(); i != pl.end(); ++i) {
+        for (auto p: points) {
 
-            bool inRange = true;
             if (ms) {
-                Selection s(ms->getContainingSelection(i->frame, false));
-                if (s.isEmpty() || !s.contains(i->frame)) {
-                    inRange = false;
+                Selection s(ms->getContainingSelection(p.frame, false));
+                if (!s.contains(p.frame)) {
+                    prevPoint = p;
+                    havePrevPoint = true;
+                    continue;
                 }
             }
 
-            PointType p(*i);
-
-            if (!inRange) {
-                prevPoint = p;
-                continue;
-            }
-
             if (actingOnPrevPoint()) {
-                if (i != pl.begin()) {
+                if (havePrevPoint) {
                     command->deletePoint(prevPoint);
                     label<PointType>(p, &prevPoint);
                     command->addPoint(prevPoint);
@@ -213,9 +211,94 @@
             }
 
             prevPoint = p;
+            havePrevPoint = true;
         }
 
-        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 <typename PointType>
+    Command *subdivide(SparseModel<PointType> &model, MultiSelection *ms, int n) {
+        
+        auto points(model.getPoints());
+        auto command = new typename SparseModel<PointType>::EditCommand
+            (&model, tr("Subdivide Points"));
+
+        for (auto i = points.begin(); i != points.end(); ++i) {
+
+            auto j = i;
+            // require a "next point" even if it's not in selection
+            if (++j == points.end()) {
+                break;
+            }
+
+            if (ms) {
+                Selection s(ms->getContainingSelection(i->frame, false));
+                if (!s.contains(i->frame)) {
+                    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();
+    }
+
+    /**
+     * Return a command that has been executed but not yet added to
+     * the history.
+     */
+    template <typename PointType>
+    Command *winnow(SparseModel<PointType> &model, MultiSelection *ms, int n) {
+        
+        auto points(model.getPoints());
+        auto command = new typename SparseModel<PointType>::EditCommand
+            (&model, tr("Winnow Points"));
+
+        int counter = 0;
+        
+        for (auto p: points) {
+
+            if (ms) {
+                Selection s(ms->getContainingSelection(p.frame, false));
+                if (!s.contains(p.frame)) {
+                    counter = 0;
+                    continue;
+                }
+            }
+
+            ++counter;
+
+            if (counter == n+1) counter = 1;
+            if (counter == 1) {
+                // this is an Nth instant, don't remove it
+                continue;
+            }
+            
+            command->deletePoint(p);
+        }
+
+        return command->finish();
     }
 
     template <typename PointType>