private static CellRange[] ToArray(IList temp) { CellRange[] cellranges=new CellRange[temp.Count]; IEnumerator enumerator = temp.GetEnumerator(); int i=0; while (enumerator.MoveNext()) { cellranges[i] = (CellRange)enumerator.Current; } return cellranges; }
/** * @param range never a full row or full column range * @return an array including <b>this</b> <tt>CellRange</tt> and all parts of <tt>range</tt> * outside of this range */ private CellRange[] sliceUp(CellRange range) { ArrayList temp = new ArrayList(); // Chop up range horizontally and vertically temp.Add(range); if (!IsFullColumnRange()) { temp = CutHorizontally(_firstRow, temp); temp = CutHorizontally(_lastRow + 1, temp); } if (!IsFullRowRange()) { temp = CutVertically(_firstColumn, temp); temp = CutVertically(_lastColumn + 1, temp); } CellRange[] crParts = ToArray(temp); // form result array temp.Clear(); temp.Add(this); for (int i = 0; i < crParts.Length; i++) { CellRange crPart = crParts[i]; // only include parts that are not enclosed by this if (intersect(crPart) != ENCLOSES) { temp.Add(crPart); } } return ToArray(temp); }
/** * @return the new range(s) to Replace the supplied ones. <code>null</code> if no merge Is possible */ private static CellRange[] MergeRanges(CellRange range1, CellRange range2) { int x = range1.intersect(range2); switch (x) { case CellRange.NO_INTERSECTION: if (range1.HasExactSharedBorder(range2)) { return new CellRange[] { range1.CreateEnclosingCellRange(range2), }; } // else - No intersection and no shared border: do nothing return null; case CellRange.OVERLAP: return resolveRangeOverlap(range1, range2); case CellRange.INSIDE: // Remove range2, since it Is completely inside of range1 return new CellRange[] { range1, }; case CellRange.ENCLOSES: // range2 encloses range1, so Replace it with the enclosing one return new CellRange[] { range2, }; } throw new Exception("unexpected intersection result (" + x + ")"); }
// TODO - Write junit test for this static CellRange[] resolveRangeOverlap(CellRange rangeA, CellRange rangeB) { if (rangeA.IsFullColumnRange()) { if (rangeB.IsFullRowRange()) { // Excel seems to leave these Unresolved return null; } return rangeA.sliceUp(rangeB); } if (rangeA.IsFullRowRange()) { if (rangeB.IsFullColumnRange()) { // Excel seems to leave these Unresolved return null; } return rangeA.sliceUp(rangeB); } if (rangeB.IsFullColumnRange()) { return rangeB.sliceUp(rangeA); } if (rangeB.IsFullRowRange()) { return rangeB.sliceUp(rangeA); } return rangeA.sliceUp(rangeB); }
/** * Check if the specified cell range Has a shared border with the current range. * * @return <code>true</code> if the ranges have a complete shared border (i.e. * the two ranges toGether make a simple rectangular region. */ public bool HasExactSharedBorder(CellRange range) { int oFirstRow = range._firstRow; int oLastRow = range._lastRow; int oFirstCol = range._firstColumn; int oLastCol = range._lastColumn; if (_firstRow > 0 && _firstRow - 1 == oLastRow || oFirstRow > 0 && oFirstRow - 1 == _lastRow) { // ranges have a horizontal border in common // make sure columns are identical: return _firstColumn == oFirstCol && _lastColumn == oLastCol; } if (_firstColumn > 0 && _firstColumn - 1 == oLastCol || oFirstCol > 0 && _lastColumn == oFirstCol - 1) { // ranges have a vertical border in common // make sure rows are identical: return _firstRow == oFirstRow && _lastRow == oLastRow; } return false; }
/** * Intersect this range with the specified range. * * @param another - the specified range * @return code which reflects how the specified range Is related to this range.<br/> * Possible return codes are: * NO_INTERSECTION - the specified range Is outside of this range;<br/> * OVERLAP - both ranges partially overlap;<br/> * INSIDE - the specified range Is inside of this one<br/> * ENCLOSES - the specified range encloses (possibly exactly the same as) this range<br/> */ public int intersect(CellRange another) { int firstRow = another.FirstRow; int lastRow = another.LastRow; int firstCol = another.FirstColumn; int lastCol = another.LastColumn; if ( gt(FirstRow, lastRow) || lt(LastRow, firstRow) || gt(FirstColumn, lastCol) || lt(LastColumn, firstCol) ) { return NO_INTERSECTION; } else if (Contains(another)) { return INSIDE; } else if (another.Contains(this)) { return ENCLOSES; } else { return OVERLAP; } }
/** * Create an enclosing CellRange for the two cell ranges. * * @return enclosing CellRange */ public CellRange CreateEnclosingCellRange(CellRange range) { if (range == null) { return CloneCellRange(); } else { CellRange cellRange = new CellRange( lt(range.FirstRow, FirstRow) ? range.FirstRow : FirstRow, gt(range.LastRow, LastRow) ? range.LastRow : LastRow, lt(range.FirstColumn, FirstColumn) ? range.FirstColumn : FirstColumn, gt(range.LastColumn, LastColumn) ? range.LastColumn : LastColumn ); return cellRange; } }
/** * Check if the specified range Is located inside of this cell range. * * @param range * @return true if this cell range Contains the argument range inside if it's area */ public bool Contains(CellRange range) { int firstRow = range.FirstRow; int lastRow = range.LastRow; int firstCol = range.FirstColumn; int lastCol = range.LastColumn; return le(FirstRow, firstRow) && ge(LastRow, lastRow) && le(FirstColumn, firstCol) && ge(LastColumn, lastCol); }
/** * Do all possible cell merges between cells of the list so that:<br> * <li>if a cell range Is completely inside of another cell range, it Gets Removed from the list * <li>if two cells have a shared border, merge them into one bigger cell range * @param cellRangeList * @return updated List of cell ranges */ public static CellRange[] MergeCellRanges(CellRange[] cellRanges) { if (cellRanges.Length < 1) { return cellRanges; } IList temp = MergeCellRanges(cellRanges); return ToArray(temp); }
/** * Convert array of regions to a List of CellRange objects * * @param regions * @return List of CellRange objects */ public static CellRange[] ConvertRegionsToCellRanges(Region[] regions) { CellRange[] result = new CellRange[regions.Length]; for (int i = 0; i < regions.Length; i++) { result[i] = CreateFromRegion(regions[i]); } return result; }
/** * Convert a List of CellRange objects to an array of regions * * @param List of CellRange objects * @return regions */ public static Region[] ConvertCellRangesToRegions(CellRange[] cellRanges) { int size = cellRanges.Length; if (size < 1) { return EMPTY_REGION_ARRAY; } Region[] result = new Region[size]; for (int i = 0; i != size; i++) { result[i] = cellRanges[i].ConvertToRegion(); } return result; }