package com.vaadin.addon.spreadsheet.client; import java.io.Serializable; /* * #%L * Vaadin Spreadsheet * %% * Copyright (C) 2013 - 2015 Vaadin Ltd * %% * This program is available under Commercial Vaadin Add-On License 3.0 * (CVALv3). * * See the file license.html distributed with this software for more * information about licensing. * * You should have received a copy of the CVALv3 along with this program. * If not, see <http://vaadin.com/license/cval-3>. * #L% */ public class MergedRegionUtil { public interface MergedRegionContainer extends Serializable { /** * Gets the merged region starting at the given coordinates. * * @param column * Column index, 1-based * @param row * Row index, 1-based * @return Merged region or null if not found. */ public MergedRegion getMergedRegionStartingFrom(int column, int row); /** * Gets the merged region overlapping the given coordinates. * * @param column * Column index, 1-based * @param row * Row index, 1-based * @return Merged region or null if not found. */ public MergedRegion getMergedRegion(int column, int row); } /** * Goes through the given selection and checks that the cells on the edges * of the selection are not in "the beginning / middle / end" of a merged * cell. Returns the correct increased selection, after taking the merged * cells into account. * * Parameters 1-based. * * @param topRow * @param bottomRow * @param leftColumn * @param rightColumn * @return */ public static MergedRegion findIncreasingSelection( MergedRegionContainer container, int topRow, int bottomRow, int leftColumn, int rightColumn) { if (topRow == bottomRow && leftColumn == rightColumn) { MergedRegion mergedRegion = container.getMergedRegion(leftColumn, topRow); if (mergedRegion == null) { mergedRegion = new MergedRegion(); mergedRegion.col1 = leftColumn; mergedRegion.col2 = rightColumn; mergedRegion.row1 = topRow; mergedRegion.row2 = bottomRow; } return mergedRegion; } else { MergedRegion merged = container.getMergedRegionStartingFrom( leftColumn, topRow); if (merged != null && merged.col2 >= rightColumn && merged.row2 >= bottomRow) { return merged; } } boolean trouble = false; int i = leftColumn; // go through top edge while (i <= rightColumn) { MergedRegion region = container.getMergedRegion(i, topRow); if (region != null) { i = region.col2 + 1; if (leftColumn > region.col1) { leftColumn = region.col1; trouble = true; } if (rightColumn < region.col2) { rightColumn = region.col2; trouble = true; } if (topRow > region.row1) { topRow = region.row1; trouble = true; } } else { i++; } } if (topRow > bottomRow) { topRow = bottomRow; } // go through right edge i = topRow; while (i <= bottomRow) { MergedRegion region = container.getMergedRegion(rightColumn, i); if (region != null) { i = region.row2 + 1; if (rightColumn < region.col2) { rightColumn = region.col2; trouble = true; } if (topRow > region.row1) { topRow = region.row1; trouble = true; } if (bottomRow < region.row2) { bottomRow = region.row2; trouble = true; } } else { i++; } } if (rightColumn < leftColumn) { rightColumn = leftColumn; } // go through bottom edge i = leftColumn; while (i <= rightColumn) { MergedRegion region = container.getMergedRegion(i, bottomRow); if (region != null) { i = region.col2 + 1; if (leftColumn > region.col1) { leftColumn = region.col1; trouble = true; } if (rightColumn < region.col2) { rightColumn = region.col2; trouble = true; } if (bottomRow < region.row2) { bottomRow = region.row2; trouble = true; } } else { i++; } } if (bottomRow < topRow) { bottomRow = topRow; } // go through left edge i = topRow; while (i <= bottomRow) { MergedRegion region = container.getMergedRegion(leftColumn, i); if (region != null) { i = region.row2 + 1; if (leftColumn > region.col1) { leftColumn = region.col1; trouble = true; } if (topRow > region.row1) { topRow = region.row1; trouble = true; } if (bottomRow < region.row2) { bottomRow = region.row2; trouble = true; } } else { i++; } } if (leftColumn > rightColumn) { leftColumn = rightColumn; } if (trouble) { return findIncreasingSelection(container, topRow, bottomRow, leftColumn, rightColumn); } else if (topRow == bottomRow && leftColumn == rightColumn) { MergedRegion mergedRegion = container.getMergedRegion(leftColumn, topRow); if (mergedRegion == null) { mergedRegion = new MergedRegion(); mergedRegion.col1 = leftColumn; mergedRegion.col2 = rightColumn; mergedRegion.row1 = topRow; mergedRegion.row2 = bottomRow; } return mergedRegion; } else { MergedRegion merged = container.getMergedRegionStartingFrom( leftColumn, topRow); if (merged != null && merged.col2 >= rightColumn && merged.row2 >= bottomRow) { return merged; } } MergedRegion result = new MergedRegion(); result.col1 = leftColumn; result.col2 = rightColumn; result.row1 = topRow; result.row2 = bottomRow; return result; } }