/* * 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 ro.nextreports.designer; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Collections; import java.util.Comparator; import ro.nextreports.designer.grid.Cell; import ro.nextreports.designer.grid.CellSpan; import ro.nextreports.designer.grid.DefaultSpanModel; import ro.nextreports.designer.grid.SpanModel; /** * Created by IntelliJ IDEA. * User: mihai.panaitescu * Date: Nov 10, 2008 * Time: 11:36:44 AM */ public class MergeAlgorithm { public static final int VALID = 1; public static final int INVALID_ONE = 2; public static final int INVALID_CONTENT = 3; public static final int INVALID_BAND = 4; public static final int INVALID_SPAN = 5; public static final int INVALID_NEIGHBOUR = 6; public static final int INVALID_MATRIX = 7; // A merge algorithm is possible on a list of ordered cells if the cells // are grouped in a matrix. public static int isPossible(List<Cell> cells) { if ((cells == null) || (cells.size() == 1)) { return INVALID_ONE; } if (!oneNotNull(cells)) { return INVALID_CONTENT; } if (!sameBand(cells)) { return INVALID_BAND; } if (containsSpan(cells)) { return INVALID_SPAN; } if (!neighbours(cells)) { return INVALID_NEIGHBOUR; } if (!isMatrix(cells)) { return INVALID_MATRIX; } return VALID; } public static int isCopyPossible(List<Cell> selCells, SpanModel spanModel) { List<Cell> cells = getAllCells(selCells, spanModel); if ((cells == null) || (cells.size() == 1)) { return INVALID_ONE; } if (!sameBand(cells)) { return INVALID_BAND; } if (!neighbours(cells)) { return INVALID_NEIGHBOUR; } if (!isMatrix(cells)) { return INVALID_MATRIX; } return VALID; } public static Cell getLastCell(List<Cell> selCells) { Cell first = selCells.get(0); int rows = first.getRow(); int columns = first.getColumn(); boolean computeColumns = true; for (int i=1; i<selCells.size(); i++) { Cell cell = selCells.get(i); if (first.getRow() == cell.getRow()) { if (computeColumns) { columns = cell.getColumn(); } } else { computeColumns = false; first = cell; rows = cell.getRow(); } } return new Cell(rows, columns); } private static boolean oneNotNull(List<Cell> cells) { ReportGrid grid = Globals.getReportGrid(); boolean flag = false; for (Cell cell : cells) { if ((grid.getBandElement(cell) != null) && (!"".equals(grid.getBandElement(cell).getText())) ) { if (!flag) { flag = true; } else { return false; } } } return true; } private static boolean sameBand(List<Cell> cells) { String bandName = null; ReportGrid grid = Globals.getReportGrid(); for (Cell cell : cells) { String tmp = grid.getBandName(cell); if (bandName == null) { bandName = tmp; } if (!bandName.equals(tmp)) { return false; } } return true; } private static boolean containsSpan(List<Cell> cells) { ReportGrid grid = Globals.getReportGrid(); for (Cell cell : cells) { if (grid.getSpanModel().isCellSpan(cell.getRow(), cell.getColumn())) { return true; } } return false; } // test to see cells are neighbours private static boolean neighbours(List<Cell> cells) { Cell firstOnRow = null; int size = cells.size(); for (int i = 0; i < size - 1; i++) { Cell cellOne = cells.get(i); Cell cellTwo = cells.get(i + 1); Cell firstCell, secondCell; if (i == 0) { firstOnRow = cellOne; if (cellOne.getRow() != cellTwo.getRow()) { firstOnRow = cellTwo; } firstCell = cellOne; secondCell = cellTwo; } else { if (cellOne.getRow() != cellTwo.getRow()) { firstCell = new Cell(firstOnRow.getRow(), firstOnRow.getColumn()); secondCell = cellTwo; firstOnRow = cellTwo; } else { firstCell = cellOne; secondCell = cellTwo; } } if (!neighbours(firstCell, secondCell)) { return false; } } return true; } private static boolean neighbours(Cell cellOne, Cell cellTwo) { if (cellOne.equals(cellTwo)) { throw new IllegalArgumentException("Cells must be different!"); } if (cellOne.getRow() == cellTwo.getRow()) { return Math.abs(cellOne.getColumn() - cellTwo.getColumn()) == 1; } else if (cellOne.getColumn() == cellTwo.getColumn()) { return Math.abs(cellOne.getRow() - cellTwo.getRow()) == 1; } else { return false; } } private static boolean neighbours(Cell cellOne, Cell cellTwo, SpanModel spanModel) { if (cellOne.equals(cellTwo)) { throw new IllegalArgumentException("Cells must be different!"); } int rowOne = cellOne.getRow(); int colOne = cellOne.getColumn(); int rowTwo = cellTwo.getRow(); int colTwo = cellTwo.getColumn(); if (spanModel.isCellSpan(rowOne, colOne)) { CellSpan span = spanModel.getSpanOver(rowOne, colOne); rowOne = span.getLastRow(); colOne = span.getLastColumn(); } if (cellOne.getRow() == cellTwo.getRow()) { return Math.abs(cellOne.getColumn() - cellTwo.getColumn()) == 1; } else if (cellOne.getColumn() == cellTwo.getColumn()) { return Math.abs(cellOne.getRow() - cellTwo.getRow()) == 1; } else { return false; } } // test if list with neighbour cells is matrix private static boolean isMatrix(List<Cell> cells) { // all rows must have same number of cells // all columns must have same number of cells Map<Integer, Integer> rows = new HashMap<Integer, Integer>(); Map<Integer, Integer> cols = new HashMap<Integer, Integer>(); int size = cells.size(); for (int i = 0; i < size; i++) { int cellRow = cells.get(i).getRow(); int cellColumn = cells.get(i).getColumn(); Integer rowNo = rows.get(cellRow); Integer colNo = cols.get(cellColumn); int rowN = (rowNo == null) ? 0 : rowNo; int colN = (colNo == null) ? 0 : colNo; rows.put(cellRow, rowN + 1); cols.put(cellColumn, colN + 1); } int no = -1; for (Integer row : rows.keySet()) { int value = rows.get(row); if (no == -1) { no = value; } else if (no != value) { return false; } } no = -1; for (Integer col : cols.keySet()) { int value = cols.get(col); if (no == -1) { no = value; } else if (no != value) { return false; } } return true; } // get all cells (without span) : a span means more cells! private static List<Cell> getAllCells(List<Cell> cells, SpanModel spanModel) { List<Cell> allCells = new ArrayList<Cell>(); allCells.addAll(cells); for (Cell cell : cells) { if (spanModel.isCellSpan(cell.getRow(), cell.getColumn())) { CellSpan span = spanModel.getSpanOver(cell.getRow(), cell.getColumn()); for (int i = span.getFirstRow(); i <= span.getLastRow(); i++) { for (int j = span.getFirstColumn(); j <= span.getLastColumn(); j++) { Cell newCell = new Cell(i, j); if (!allCells.contains(newCell)) { allCells.add(newCell); } } } } } Collections.sort(allCells, new Comparator<Cell>() { public int compare(Cell o1, Cell o2) { if (o1.getRow() < o2.getRow()) { return -1; } else if (o1.getRow() == o2.getRow()) { return o1.getColumn() - o2.getColumn(); } else { return 1; } } }); return allCells; } public static void main(String[] args) { List<Cell> cells = new ArrayList<Cell>(); // cells.add(new Cell(0, 0)); // cells.add(new Cell(0, 1)); // cells.add(new Cell(0, 2)); // cells.add(new Cell(1, 0)); // cells.add(new Cell(1, 1)); // cells.add(new Cell(1, 2)); // System.out.println(MergeAlgorithm.isPossible(cells)); cells.add(new Cell(0, 0)); cells.add(new Cell(0, 2)); cells.add(new Cell(1, 2)); cells.add(new Cell(2, 0)); cells.add(new Cell(2, 1)); DefaultSpanModel model = new DefaultSpanModel(); model.addSpan(new CellSpan(0,0,2,2)); model.addSpan(new CellSpan(2,1,1,2)); //System.out.println("validStatus = "+isCopyPossible(cells, model)); System.out.println("last cell = " + getLastCell(cells)); } }