You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by rw...@apache.org on 2020/05/01 20:47:49 UTC

svn commit: r1877270 - in /pivot/trunk/wtk: src/org/apache/pivot/wtk/RangeSelection.java test/org/apache/pivot/wtk/test/RangeSelectionTest.java

Author: rwhitcomb
Date: Fri May  1 20:47:49 2020
New Revision: 1877270

URL: http://svn.apache.org/viewvc?rev=1877270&view=rev
Log:
Make some style-related changes to RangeSelection, as well as
adding some (presumably) useful methods.

Add a RangeSelectionTest class to do some unit testing.


Added:
    pivot/trunk/wtk/test/org/apache/pivot/wtk/test/RangeSelectionTest.java
Modified:
    pivot/trunk/wtk/src/org/apache/pivot/wtk/RangeSelection.java

Modified: pivot/trunk/wtk/src/org/apache/pivot/wtk/RangeSelection.java
URL: http://svn.apache.org/viewvc/pivot/trunk/wtk/src/org/apache/pivot/wtk/RangeSelection.java?rev=1877270&r1=1877269&r2=1877270&view=diff
==============================================================================
--- pivot/trunk/wtk/src/org/apache/pivot/wtk/RangeSelection.java (original)
+++ pivot/trunk/wtk/src/org/apache/pivot/wtk/RangeSelection.java Fri May  1 20:47:49 2020
@@ -22,12 +22,25 @@ import org.apache.pivot.collections.immu
 
 /**
  * Class for managing a set of indexed range selections.
+ * <p> Note: Since this class is used for 0-based indexes, there
+ * are checks to make sure no negative values are ever added.
  */
 public class RangeSelection {
-    // The coalesced selected ranges
+    /** The coalesced selected ranges, kept normalized and sorted. */
     private ArrayList<Span> selectedRanges = new ArrayList<>();
 
     /**
+     * Add a range to the selection, merging and removing intersecting ranges
+     * as needed.
+     *
+     * @param range The new range to add to the selection.
+     * @return A sequence containing the ranges that were added.
+     */
+    public Sequence<Span> addRange(final Span range) {
+        return addRange(range.start, range.end);
+    }
+
+    /**
      * Adds a range to the selection, merging and removing intersecting ranges
      * as needed.
      *
@@ -35,7 +48,7 @@ public class RangeSelection {
      * @param end The end of the new range.
      * @return A sequence containing the ranges that were added.
      */
-    public Sequence<Span> addRange(int start, int end) {
+    public Sequence<Span> addRange(final int start, final int end) {
         ArrayList<Span> addedRanges = new ArrayList<>();
 
         Span range = Span.normalize(start, end);
@@ -45,7 +58,7 @@ public class RangeSelection {
 
         if (n == 0) {
             // The selection is currently empty; append the new range
-            // and add it to the added range list
+            // and add it to the added range list.
             selectedRanges.add(range);
             addedRanges.add(range);
         } else {
@@ -55,7 +68,7 @@ public class RangeSelection {
                 i = -(i + 1);
             }
 
-            // Merge the selection with the previous range, if necessary
+            // Merge the selection with the previous range, if necessary.
             if (i > 0) {
                 Span previousRange = selectedRanges.get(i - 1);
                 if (range.start == previousRange.end + 1) {
@@ -65,11 +78,11 @@ public class RangeSelection {
 
             if (i == n) {
                 // The new range starts after the last existing selection
-                // ends; append it and add it to the added range list
+                // ends; append it and add it to the added range list.
                 selectedRanges.add(range);
                 addedRanges.add(range);
             } else {
-                // Locate the upper bound of the intersection
+                // Locate the upper bound of the intersection.
                 int j = ArrayList.binarySearch(selectedRanges, range, Span.END_COMPARATOR);
                 if (j < 0) {
                     j = -(j + 1);
@@ -77,7 +90,7 @@ public class RangeSelection {
                     j++;
                 }
 
-                // Merge the selection with the next range, if necessary
+                // Merge the selection with the next range, if necessary.
                 if (j < n) {
                     Span nextRange = selectedRanges.get(j);
                     if (range.end == nextRange.start - 1) {
@@ -89,15 +102,14 @@ public class RangeSelection {
                     selectedRanges.insert(range, i);
                     addedRanges.add(range);
                 } else {
-                    // Create a new range representing the union of the
-                    // intersecting ranges
+                    // Create a new range representing the union of the intersecting ranges.
                     Span lowerRange = selectedRanges.get(i);
                     Span upperRange = selectedRanges.get(j - 1);
 
                     range = new Span(Math.min(range.start, lowerRange.start),
                                      Math.max(range.end, upperRange.end));
 
-                    // Add the gaps to the added list
+                    // Add the gaps to the added list.
                     if (range.start < lowerRange.start) {
                         addedRanges.add(new Span(range.start, lowerRange.start - 1));
                     }
@@ -112,7 +124,7 @@ public class RangeSelection {
                         addedRanges.add(new Span(upperRange.end + 1, range.end));
                     }
 
-                    // Remove all redundant ranges
+                    // Remove all redundant ranges.
                     selectedRanges.update(i, range);
 
                     if (i < j) {
@@ -133,7 +145,7 @@ public class RangeSelection {
      * @param end The end of the range to remove.
      * @return A sequence containing the ranges that were removed.
      */
-    public Sequence<Span> removeRange(int start, int end) {
+    public Sequence<Span> removeRange(final int start, final int end) {
         ArrayList<Span> removedRanges = new ArrayList<>();
 
         Span range = Span.normalize(start, end);
@@ -142,7 +154,7 @@ public class RangeSelection {
         int n = selectedRanges.getLength();
 
         if (n > 0) {
-            // Locate the lower bound of the intersection
+            // Locate the lower bound of the intersection.
             int i = ArrayList.binarySearch(selectedRanges, range, Span.START_COMPARATOR);
             if (i < 0) {
                 i = -(i + 1);
@@ -152,21 +164,20 @@ public class RangeSelection {
                 Span lowerRange = selectedRanges.get(i);
 
                 if (lowerRange.start < range.start && lowerRange.end > range.end) {
-                    // Removing the range will split the intersecting selection
-                    // into two ranges
+                    // Removing the range will split the intersecting selection into two ranges.
                     selectedRanges.update(i, new Span(lowerRange.start, range.start - 1));
                     selectedRanges.insert(new Span(range.end + 1, lowerRange.end), i + 1);
                     removedRanges.add(range);
                 } else {
                     Span leadingRemovedRange = null;
                     if (range.start > lowerRange.start) {
-                        // Remove the tail of this range
+                        // Remove the tail of this range.
                         selectedRanges.update(i, new Span(lowerRange.start, range.start - 1));
                         leadingRemovedRange = new Span(range.start, lowerRange.end);
                         i++;
                     }
 
-                    // Locate the upper bound of the intersection
+                    // Locate the upper bound of the intersection.
                     int j = ArrayList.binarySearch(selectedRanges, range, Span.END_COMPARATOR);
                     if (j < 0) {
                         j = -(j + 1);
@@ -179,16 +190,16 @@ public class RangeSelection {
 
                         Span trailingRemovedRange = null;
                         if (range.end < upperRange.end) {
-                            // Remove the head of this range
+                            // Remove the head of this range.
                             selectedRanges.update(j - 1, new Span(range.end + 1, upperRange.end));
                             trailingRemovedRange = new Span(upperRange.start, range.end);
                             j--;
                         }
 
-                        // Remove all cleared ranges
+                        // Remove all cleared ranges.
                         Sequence<Span> clearedRanges = selectedRanges.remove(i, j - i);
 
-                        // Construct the removed range list
+                        // Construct the removed range list.
                         if (leadingRemovedRange != null) {
                             removedRanges.add(leadingRemovedRange);
                         }
@@ -220,7 +231,7 @@ public class RangeSelection {
      *
      * @param index The index in question.
      */
-    public Span get(int index) {
+    public Span get(final int index) {
         return selectedRanges.get(index);
     }
 
@@ -239,20 +250,45 @@ public class RangeSelection {
     }
 
     /**
+     * @return The smallest start value of this selection, or <tt>-1</tt>
+     * if it is empty.
+     */
+    public int getStart() {
+        if (selectedRanges.getLength() > 0) {
+            return selectedRanges.get(0).start;
+        } else {
+            return -1;
+        }
+    }
+
+    /**
+     * @return The largest end value of this selection, or <tt>-1</tt>
+     * if the range is empty.
+     */
+    public int getEnd() {
+        int len = selectedRanges.getLength();
+        if (len > 0) {
+            return selectedRanges.get(len - 1).end;
+        } else {
+            return -1;
+        }
+    }
+
+    /**
      * Determines the index of a range in the selection.
      *
      * @param range The range to look for.
      * @return The index of the range, if it exists in the selection;
      * <tt>-1</tt>, otherwise.
      */
-    public int indexOf(Span range) {
+    public int indexOf(final Span range) {
         assert (range != null);
 
         int index = -1;
         int i = ArrayList.binarySearch(selectedRanges, range, Span.INTERSECTION_COMPARATOR);
 
-        if (i >= 0) {
-            index = (range.equals(selectedRanges.get(i))) ? i : -1;
+        if (i >= 0 && range.equals(selectedRanges.get(i))) {
+            index = i;
         }
 
         return index;
@@ -264,7 +300,7 @@ public class RangeSelection {
      * @param index The index to look for in the selection.
      * @return <tt>true</tt> if the index is selected; <tt>false</tt>, otherwise.
      */
-    public boolean containsIndex(int index) {
+    public boolean containsIndex(final int index) {
         Span range = new Span(index);
         int i = ArrayList.binarySearch(selectedRanges, range, Span.INTERSECTION_COMPARATOR);
 
@@ -278,32 +314,31 @@ public class RangeSelection {
      * @param index The location to insert into the sequence.
      * @return The number of ranges that were updated.
      */
-    public int insertIndex(int index) {
+    public int insertIndex(final int index) {
         int updated = 0;
 
-        // Get the insertion point for the range corresponding to the given
-        // index
+        // Get the insertion point for the range corresponding to the given index.
         Span range = new Span(index);
         int i = ArrayList.binarySearch(selectedRanges, range, Span.INTERSECTION_COMPARATOR);
 
         if (i < 0) {
-            // The inserted index does not intersect with a selected range
+            // The inserted index does not intersect with a selected range.
             i = -(i + 1);
         } else {
-            // The inserted index intersects with a currently selected range
+            // The inserted index intersects with a currently selected range.
             Span selectedRange = selectedRanges.get(i);
 
             // If the inserted index falls within the current range, increment
-            // the endpoint only
+            // the endpoint only.
             if (selectedRange.start < index) {
                 selectedRanges.update(i, selectedRange.lengthen(1));
 
-                // Start incrementing range bounds beginning at the next range
+                // Start incrementing range bounds beginning at the next range.
                 i++;
             }
         }
 
-        // Increment any subsequent selection indexes
+        // Increment any subsequent selection indexes.
         int n = selectedRanges.getLength();
         while (i < n) {
             Span selectedRange = selectedRanges.get(i);
@@ -323,19 +358,19 @@ public class RangeSelection {
      * @param count Number of indexes to remove.
      * @return The number of ranges that were updated.
      */
-    public int removeIndexes(int index, int count) {
-        // Clear any selections in the given range
+    public int removeIndexes(final int index, final int count) {
+        // Clear any selections in the given range.
         Sequence<Span> removed = removeRange(index, (index + count) - 1);
         int updated = removed.getLength();
 
-        // Decrement any subsequent selection indexes
+        // Decrement any subsequent selection indexes.
         Span range = new Span(index);
         int i = ArrayList.binarySearch(selectedRanges, range, Span.INTERSECTION_COMPARATOR);
         assert (i < 0) : "i should be negative, since index should no longer be selected";
 
         i = -(i + 1);
 
-        // Determine the number of ranges to modify
+        // Determine the number of ranges to modify.
         int n = selectedRanges.getLength();
         while (i < n) {
             Span selectedRange = selectedRanges.get(i);

Added: pivot/trunk/wtk/test/org/apache/pivot/wtk/test/RangeSelectionTest.java
URL: http://svn.apache.org/viewvc/pivot/trunk/wtk/test/org/apache/pivot/wtk/test/RangeSelectionTest.java?rev=1877270&view=auto
==============================================================================
--- pivot/trunk/wtk/test/org/apache/pivot/wtk/test/RangeSelectionTest.java (added)
+++ pivot/trunk/wtk/test/org/apache/pivot/wtk/test/RangeSelectionTest.java Fri May  1 20:47:49 2020
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pivot.wtk.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+import org.apache.pivot.collections.Sequence;
+import org.apache.pivot.wtk.RangeSelection;
+import org.apache.pivot.wtk.Span;
+
+
+public class RangeSelectionTest {
+    @Test
+    public void test1() {
+        RangeSelection r1 = new RangeSelection();
+        r1.addRange(10, 1);
+        Span s1 = new Span(1, 10);
+        assertEquals(1, r1.getLength());
+        assertEquals(0, r1.indexOf(s1));
+
+        r1.addRange(10, 20);
+        Span s2 = new Span(1, 20);
+        assertEquals(1, r1.getLength());
+        assertEquals(0, r1.indexOf(s2));
+
+        Span s3 = new Span(30, 40);
+        r1.addRange(s3);
+        assertEquals(2, r1.getLength());
+        assertEquals(1, r1.indexOf(s3));
+        assertTrue(r1.containsIndex(35));
+
+        int inserted = r1.insertIndex(29);
+        assertEquals(1, inserted);
+        assertEquals(2, r1.getLength());
+
+        Sequence<Span> removed = r1.removeRange(20, 30);
+        assertEquals(1, removed.getLength());
+        assertEquals(2, r1.getLength());
+        assertEquals(1, r1.getStart());
+        assertEquals(41, r1.getEnd());
+        assertFalse(r1.containsIndex(25));
+    }
+
+}
+