private HiddenColumnsCursor cursor = new HiddenColumnsCursor();
+ private int numColumns = 0;
+
/*
* list of hidden column [start, end] ranges; the list is maintained in
* ascending start column order
if (copy != null)
{
hiddenColumns = new ArrayList<>();
+ numColumns = 0;
Iterator<int[]> it = copy.getBoundedIterator(start, end);
while (it.hasNext())
{
hiddenColumns.add(
new int[]
{ region[0] - offset, region[1] - offset });
+ numColumns += region[1] - region[0] + 1;
}
}
cursor.resetCursor(hiddenColumns);
try
{
LOCK.readLock().lock();
- int size = 0;
- if (hiddenColumns != null)
+
+ if (numColumns == 0 && hiddenColumns != null)
{
- Iterator<int[]> it = hiddenColumns.iterator();
- while (it.hasNext())
+ // numColumns is out of date, so recalculate
+ int size = 0;
+ if (hiddenColumns != null)
{
- int[] range = it.next();
- size += range[1] - range[0] + 1;
+ Iterator<int[]> it = hiddenColumns.iterator();
+ while (it.hasNext())
+ {
+ int[] range = it.next();
+ size += range[1] - range[0] + 1;
+ }
}
+ numColumns = size;
}
- return size;
+
+ return numColumns;
} finally
{
LOCK.readLock().unlock();
if (hiddenColumns != null)
{
- result += cursor.getHiddenOffset(column);
-
- /*
- Iterator<int[]> it = hiddenColumns.iterator();
- while (it.hasNext())
- {
- int[] region = it.next();
- if (result >= region[0])
- {
- result += region[1] - region[0] + 1;
- }
- }*/
+ result += cursor.getHiddenOffset(column).getHiddenSoFar();
}
return result;
{
LOCK.readLock().lock();
int result = hiddenColumn;
- int[] region = null;
+
if (hiddenColumns != null)
{
- Iterator<int[]> it = new RegionsIterator(0,
- hiddenColumn, hiddenColumns, cursor);
- while (it.hasNext())
- {
- region = it.next();
- if (hiddenColumn > region[1])
- {
- result -= region[1] + 1 - region[0];
- }
- }
-
- if (region != null && hiddenColumn >= region[0]
- && hiddenColumn <= region[1])
+ HiddenCursorPosition cursorPos = cursor
+ .findRegionForColumn(hiddenColumn);
+ int index = cursorPos.getRegionIndex();
+ int hiddenBeforeCol = cursorPos.getHiddenSoFar();
+
+ // just subtract hidden cols count - this works fine if column is
+ // visible
+ result = hiddenColumn - hiddenBeforeCol;
+
+ // now check in case column is hidden - it will be in the returned
+ // hidden region
+ if (index < hiddenColumns.size())
{
- // Here the hidden column is within a region, so
- // we want to return the position of region[0]-1, adjusted for any
- // earlier hidden columns.
- // Calculate the difference between the actual hidden col position
- // and region[0]-1, and then subtract from result to convert result
- // from the adjusted hiddenColumn value to the adjusted region[0]-1
- // value.
-
- // However, if the region begins at 0 we cannot return region[0]-1
- // just return 0
- if (region[0] == 0)
- {
- return 0;
- }
- else
+ int[] region = hiddenColumns.get(index);
+ if (hiddenColumn >= region[0] && hiddenColumn <= region[1])
{
- return result - (hiddenColumn - region[0] + 1);
+ // actually col is hidden, return region[0]-1
+ // unless region[0]==0 in which case return 0
+ if (region[0] == 0)
+ {
+ result = 0;
+ }
+ else
+ {
+ result = region[0] - 1 - hiddenBeforeCol;
+ }
}
}
}
+
return result; // return the shifted position after removing hidden
// columns.
} finally
* hidden columns. In otherwords, the next hidden column.
*
* @param alPos
- * the (visible) alignmentPosition to find the next hidden column for
+ * the absolute (visible) alignmentPosition to find the next hidden
+ * column for
*/
public int getHiddenBoundaryRight(int alPos)
{
LOCK.readLock().lock();
if (hiddenColumns != null)
{
- Iterator<int[]> it = hiddenColumns.iterator();
- while (it.hasNext())
+ int index = cursor.findRegionForColumn(alPos).getRegionIndex();
+ if (index < hiddenColumns.size())
{
- int[] region = it.next();
+ int[] region = hiddenColumns.get(index);
if (alPos < region[0])
{
return region[0];
}
+ else if ((alPos <= region[1])
+ && (index + 1 < hiddenColumns.size()))
+ {
+ // alPos is within a hidden region, return the next one
+ // if there is one
+ region = hiddenColumns.get(index + 1);
+ return region[0];
+ }
}
}
return alPos;
* hidden columns. In otherwords, the previous hidden column.
*
* @param alPos
- * the (visible) alignmentPosition to find the previous hidden column
- * for
+ * the absolute (visible) alignmentPosition to find the previous
+ * hidden column for
*/
public int getHiddenBoundaryLeft(int alPos)
{
{
LOCK.readLock().lock();
- Iterator<int[]> it = new ReverseRegionsIterator(0, alPos,
- hiddenColumns);
- while (it.hasNext())
+ if (hiddenColumns != null)
{
- int[] region = it.next();
- if (alPos > region[1])
+ int index = cursor.findRegionForColumn(alPos).getRegionIndex();
+
+ if (index > 0)
{
+ int[] region = hiddenColumns.get(index - 1);
return region[1];
}
}
-
return alPos;
} finally
{
if (!wasAlreadyLocked)
{
cursor.resetCursor(hiddenColumns);
+
+ // reset the number of columns so they will be recounted
+ numColumns = 0;
}
} finally
{
{
LOCK.readLock().lock();
- Iterator<int[]> it = new RegionsIterator(column, column,
- hiddenColumns, cursor);
- while (it.hasNext())
+ int regionindex = cursor.findRegionForColumn(column).getRegionIndex();
+ if (regionindex > -1 && regionindex < hiddenColumns.size())
{
- int[] region = it.next();
+ int[] region = hiddenColumns.get(regionindex);
if (column >= region[0] && column <= region[1])
{
return false;
}
}
-
return true;
+
} finally
{
LOCK.readLock().unlock();
hideColumns(r[0], r[1]);
}
cursor.resetCursor(hiddenColumns);
+ numColumns = 0;
} finally
{
LOCK.writeLock().unlock();
}
hiddenColumns = null;
cursor.resetCursor(hiddenColumns);
+ numColumns = 0;
}
} finally
{
try
{
LOCK.writeLock().lock();
- Iterator<int[]> it = new RegionsIterator(start, start, hiddenColumns,
- cursor);
- while (it.hasNext())
+
+ if (hiddenColumns != null)
{
- int[] region = it.next();
- if (start == region[0])
+ int regionIndex = cursor.findRegionForColumn(start)
+ .getRegionIndex();
+
+ if (regionIndex != -1 && regionIndex != hiddenColumns.size())
{
- for (int j = region[0]; j < region[1] + 1; j++)
+ // regionIndex is the region which either contains start
+ // or lies to the right of start
+ int[] region = hiddenColumns.get(regionIndex);
+ if (start == region[0])
{
- sel.addElement(j);
+ for (int j = region[0]; j < region[1] + 1; j++)
+ {
+ sel.addElement(j);
+ }
+ int colsToRemove = region[1] - region[0] + 1;
+ hiddenColumns.remove(regionIndex);
+
+ if (hiddenColumns.isEmpty())
+ {
+ hiddenColumns = null;
+ numColumns = 0;
+ }
+ else
+ {
+ numColumns -= colsToRemove;
+ }
+ cursor.updateForDeletedRegion(hiddenColumns);
+
}
- it.remove();
- break;
- }
- else if (start < region[0])
- {
- break; // passed all possible matching regions
}
}
-
- if (hiddenColumns.size() == 0)
- {
- hiddenColumns = null;
- }
- cursor.resetCursor(hiddenColumns);
} finally
{
LOCK.writeLock().unlock();
}
hiddenColumns = newhidden;
cursor.resetCursor(hiddenColumns);
+ numColumns = 0;
} finally
{
LOCK.writeLock().unlock();
hideColumns(firstSet, lastSet - 1);
}
cursor.resetCursor(hiddenColumns);
+ numColumns = 0;
} finally
{
LOCK.writeLock().unlock();
int adjres = adjustForHiddenColumns(res);
int[] reveal = null;
- Iterator<int[]> it = new RegionsIterator(adjres - 2,
- adjres + 2, hiddenColumns, cursor);
- while (it.hasNext())
+
+ if (hiddenColumns != null)
{
- int[] region = it.next();
- if (adjres + 1 == region[0] || adjres - 1 == region[1])
+ // look for a region ending just before adjres
+ int regionindex = cursor.findRegionForColumn(adjres - 1)
+ .getRegionIndex();
+ if (regionindex < hiddenColumns.size()
+ && hiddenColumns.get(regionindex)[1] == adjres - 1)
{
- reveal = region;
- break;
+ reveal = hiddenColumns.get(regionindex);
+ }
+ // check if the region ends just after adjres
+ else if (regionindex < hiddenColumns.size()
+ && hiddenColumns.get(regionindex)[0] == adjres + 1)
+ {
+ reveal = hiddenColumns.get(regionindex);
+ }
+ // or try the next region
+ else
+ {
+ regionindex++;
+ if (regionindex < hiddenColumns.size()
+ && hiddenColumns.get(regionindex)[0] == adjres + 1)
+ {
+ reveal = hiddenColumns.get(regionindex);
+ }
}
}
return reveal;
+
} finally
{
LOCK.readLock().unlock();
i++;
}
- if (visSoFar < end - start)
+ if (visSoFar < end - start + 1)
{
// the number of visible columns we've accounted for is less than
// the number specified by end-start; work out the end position of