- /*
- * check hidden columns are either both null, or match
- */
- if (this.hiddenColumns == null)
- {
- return (that.hiddenColumns == null);
- }
- if (that.hiddenColumns == null
- || that.hiddenColumns.size() != this.hiddenColumns.size())
- {
- return false;
- }
- int i = 0;
- for (int[] thisRange : hiddenColumns)
+ int previndex = 0;
+ int prevHiddenCount = 0;
+ int regionindex = 0;
+ if (hiddenColumns == null)
+ {
+ hiddenColumns = new ArrayList<>();
+ }
+ else
+ {
+ // set up cursor reset values
+ HiddenCursorPosition cursorPos = cursor.findRegionForColumn(start);
+ regionindex = cursorPos.getRegionIndex();
+
+ if (regionindex > 0)
+ {
+ // get previous index and hidden count for updating the cursor later
+ previndex = regionindex - 1;
+ int[] prevRegion = hiddenColumns.get(previndex);
+ prevHiddenCount = cursorPos.getHiddenSoFar()
+ - (prevRegion[1] - prevRegion[0] + 1);
+ }
+ }
+
+ /*
+ * new range follows everything else; check first to avoid looping over whole hiddenColumns collection
+ */
+ if (hiddenColumns.isEmpty()
+ || start > hiddenColumns.get(hiddenColumns.size() - 1)[1])
+ {
+ hiddenColumns.add(new int[] { start, end });
+ }
+ else
+ {
+ /*
+ * traverse existing hidden ranges and insert / amend / append as
+ * appropriate
+ */
+ boolean added = false;
+ if (regionindex > 0)
+ {
+ added = insertRangeAtRegion(regionindex - 1, start, end);
+ }
+ if (!added && regionindex < hiddenColumns.size())
+ {
+ insertRangeAtRegion(regionindex, start, end);
+ }
+ }
+
+ // reset the cursor to just before our insertion point: this saves
+ // a lot of reprocessing in large alignments
+ cursor.resetCursor(hiddenColumns, previndex, prevHiddenCount);
+
+ // reset the number of columns so they will be recounted
+ numColumns = 0;
+
+ } finally