You are viewing a plain text version of this content. The canonical link for it is here.
Posted to odf-commits@incubator.apache.org by sv...@apache.org on 2016/10/04 20:38:44 UTC
svn commit: r1763327 [2/3] - in /incubator/odf/trunk/simple/src:
main/java/org/odftoolkit/simple/table/Table.java
test/java/org/odftoolkit/simple/SpreadsheetIteratorTest.java
test/resources/SpreadsheetIteratorTest.ods
Modified: incubator/odf/trunk/simple/src/main/java/org/odftoolkit/simple/table/Table.java
URL: http://svn.apache.org/viewvc/incubator/odf/trunk/simple/src/main/java/org/odftoolkit/simple/table/Table.java?rev=1763327&r1=1763326&r2=1763327&view=diff
==============================================================================
--- incubator/odf/trunk/simple/src/main/java/org/odftoolkit/simple/table/Table.java (original)
+++ incubator/odf/trunk/simple/src/main/java/org/odftoolkit/simple/table/Table.java Tue Oct 4 20:38:44 2016
@@ -1,3490 +1,3492 @@
-/*
-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 org.odftoolkit.simple.table;
-
-import java.text.DecimalFormat;
-import java.text.DecimalFormatSymbols;
-import java.util.ArrayList;
-import java.util.IdentityHashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.StringTokenizer;
-import java.util.Vector;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import org.odftoolkit.odfdom.dom.OdfContentDom;
-import org.odftoolkit.odfdom.dom.OdfDocumentNamespace;
-import org.odftoolkit.odfdom.dom.OdfStylesDom;
-import org.odftoolkit.odfdom.dom.attribute.table.TableAlignAttribute;
-import org.odftoolkit.odfdom.dom.element.OdfStyleBase;
-import org.odftoolkit.odfdom.dom.element.office.OfficeAnnotationElement;
-import org.odftoolkit.odfdom.dom.element.style.StylePageLayoutPropertiesElement;
-import org.odftoolkit.odfdom.dom.element.style.StyleTableCellPropertiesElement;
-import org.odftoolkit.odfdom.dom.element.style.StyleTableColumnPropertiesElement;
-import org.odftoolkit.odfdom.dom.element.style.StyleTablePropertiesElement;
-import org.odftoolkit.odfdom.dom.element.table.TableCoveredTableCellElement;
-import org.odftoolkit.odfdom.dom.element.table.TableNamedExpressionsElement;
-import org.odftoolkit.odfdom.dom.element.table.TableNamedRangeElement;
-import org.odftoolkit.odfdom.dom.element.table.TableTableCellElement;
-import org.odftoolkit.odfdom.dom.element.table.TableTableCellElementBase;
-import org.odftoolkit.odfdom.dom.element.table.TableTableColumnElement;
-import org.odftoolkit.odfdom.dom.element.table.TableTableColumnsElement;
-import org.odftoolkit.odfdom.dom.element.table.TableTableElement;
-import org.odftoolkit.odfdom.dom.element.table.TableTableHeaderColumnsElement;
-import org.odftoolkit.odfdom.dom.element.table.TableTableHeaderRowsElement;
-import org.odftoolkit.odfdom.dom.element.table.TableTableRowElement;
-import org.odftoolkit.odfdom.dom.element.table.TableTableRowGroupElement;
-import org.odftoolkit.odfdom.dom.element.table.TableTableRowsElement;
-import org.odftoolkit.odfdom.dom.element.text.TextHElement;
-import org.odftoolkit.odfdom.dom.element.text.TextListElement;
-import org.odftoolkit.odfdom.dom.element.text.TextPElement;
-import org.odftoolkit.odfdom.dom.style.OdfStyleFamily;
-import org.odftoolkit.odfdom.dom.style.props.OdfTableProperties;
-import org.odftoolkit.odfdom.incubator.doc.office.OdfOfficeAutomaticStyles;
-import org.odftoolkit.odfdom.incubator.doc.style.OdfStyle;
-import org.odftoolkit.odfdom.incubator.doc.style.OdfStylePageLayout;
-import org.odftoolkit.odfdom.pkg.OdfElement;
-import org.odftoolkit.odfdom.pkg.OdfFileDom;
-import org.odftoolkit.odfdom.pkg.OdfName;
-import org.odftoolkit.odfdom.pkg.OdfXMLFactory;
-import org.odftoolkit.odfdom.type.Length;
-import org.odftoolkit.odfdom.type.PositiveLength;
-import org.odftoolkit.odfdom.type.Length.Unit;
-import org.odftoolkit.simple.Component;
-import org.odftoolkit.simple.Document;
-import org.odftoolkit.simple.SpreadsheetDocument;
-import org.odftoolkit.simple.TextDocument;
-import org.odftoolkit.simple.style.DefaultStyleHandler;
-import org.odftoolkit.simple.text.Paragraph;
-import org.w3c.dom.DOMException;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-/**
- * Table represents the table feature in ODF spreadsheet and text documents.
- * <p>
- * Table provides methods to get/add/delete/modify table column/row/cell.
- *
- */
-public class Table extends Component {
-
- private final TableTableElement mTableElement;
- protected Document mDocument;
- protected boolean mIsSpreadsheet;
- protected boolean mIsCellStyleInheritance = true;
- protected boolean mIsDescribedBySingleElement = true;
- private static final int DEFAULT_ROW_COUNT = 2;
- private static final int DEFAULT_COLUMN_COUNT = 5;
- private static final double DEFAULT_TABLE_WIDTH = 6.692; // 6
- private static final int DEFAULT_REL_TABLE_WIDTH = 65535;
- private static final String DEFAULT_TABLE_ALIGN = "margins";
- private static final DecimalFormat IN_FORMAT = new DecimalFormat("##0.0000");
- // TODO: should save seperately for different dom tree
- IdentityHashMap<TableTableCellElementBase, Vector<Cell>> mCellRepository = new IdentityHashMap<TableTableCellElementBase, Vector<Cell>>();
- IdentityHashMap<TableTableRowElement, Vector<Row>> mRowRepository = new IdentityHashMap<TableTableRowElement, Vector<Row>>();
- IdentityHashMap<TableTableColumnElement, Vector<Column>> mColumnRepository = new IdentityHashMap<TableTableColumnElement, Vector<Column>>();
- private DefaultStyleHandler mStyleHandler;
- static {
- IN_FORMAT.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.US));
- }
-
- /**
- * This is a tool class which supplies all of the table creation detail.
- * <p>
- * The end user isn't allowed to create it directly, otherwise an
- * <code>IllegalStateException</code> will be thrown.
- *
- *@since 0.3.5
- */
- public static class TableBuilder {
-
- private final TableContainer ownerContainer;
-
- private final IdentityHashMap<TableTableElement, Table> mTableRepository = new IdentityHashMap<TableTableElement, Table>();
-
- /**
- * TableBuilder constructor. This constructor should only be use in
- * owner {@link org.odftoolkit.simple.table.TableContainer
- * TableContainer} constructor. The end user isn't allowed to call it
- * directly, otherwise an <code>IllegalStateException</code> will be
- * thrown.
- *
- * @param container
- * the owner <code>TableContainer</code>.
- * @throws IllegalStateException
- * if new TableBuilder out of owner Document constructor,
- * this exception will be thrown.
- */
- public TableBuilder(TableContainer container) {
- if (container.getTableBuilder() == null) {
- ownerContainer = container;
- } else {
- throw new IllegalStateException("TableBuilder only can be created in table containter constructor.");
- }
- }
-
- /**
- * Get a table feature instance by an instance of
- * <code>TableTableElement</code>.
- *
- * @param odfElement
- * an instance of <code>TableTableElement</code>
- * @return an instance of <code>Table</code> that can represent
- * <code>odfElement</code>
- */
- public synchronized Table getTableInstance(TableTableElement odfElement) {
- if (mTableRepository.containsKey(odfElement)) {
- return mTableRepository.get(odfElement);
- } else {
- Table newTable = new Table(ownerContainer, odfElement);
- mTableRepository.put(odfElement, newTable);
- return newTable;
- }
- }
-
- /**
- * Construct the <code>Table</code> feature. The default column count is
- * 5. The default row count is 2.
- * <p>
- * The table will be inserted at the end of the table container. An
- * unique table name will be given, you may set a custom table name
- * using the <code>setTableName</code> method.
- * <p>
- * If the container is a text document, cell borders will be created by
- * default.
- *
- * @return the created <code>Table</code> feature instance
- */
- public Table newTable() {
- return newTable(DEFAULT_ROW_COUNT, DEFAULT_COLUMN_COUNT, 0, 0);
- }
-
- /**
- * Construct the <code>Table</code> feature with a specified row number,
- * column number, header row number, header column number.
- * <p>
- * The table will be inserted at the end of the container. An unique
- * table name will be given, you may set a custom table name using the
- * <code>setTableName</code> method.
- * <p>
- * If the container is a text document, cell borders will be created by
- * default.
- *
- * @param numRows
- * the row number
- * @param numCols
- * the column number
- * @param headerRowNumber
- * the header row number
- * @param headerColumnNumber
- * the header column number
- * @return a new instance of <code>Table</code>
- * */
- public Table newTable(int numRows, int numCols, int headerRowNumber, int headerColumnNumber) {
- try {
- TableTableElement newTEle = createTable(ownerContainer, numRows, numCols, headerRowNumber,
- headerColumnNumber);
- ownerContainer.getTableContainerElement().appendChild(newTEle);
- return getTableInstance(newTEle);
- } catch (DOMException e) {
- Logger.getLogger(Table.class.getName()).log(Level.SEVERE, e.getMessage(), e);
- } catch (Exception e) {
- Logger.getLogger(Table.class.getName()).log(Level.SEVERE, e.getMessage(), e);
- }
- return null;
- }
-
- /**
- * Construct the <code>Table</code> feature with a specified row number,
- * column number, header row number, header column number, left margin
- * space and right margin space.
- * <p>
- * The table will be inserted at the end of the container. An unique
- * table name will be given, you may set a custom table name using the
- * <code>setTableName</code> method.
- * <p>
- * If the container is a text document, cell borders will be created by
- * default.
- *
- * @param numRows
- * the row number
- * @param numCols
- * the column number
- * @param headerRowNumber
- * the header row number
- * @param headerColumnNumber
- * the header column number
- * @param marginLeft
- * the left table margin in centimeter(cm), between the left
- * margin of table container and the table
- * @param marginRight
- * the right table margin in centimeter(cm), between the
- * right margin of table container and the table
- *
- * @return a new instance of <code>Table</code>
- *
- * @since 0.5.5
- * */
- public Table newTable(int numRows, int numCols, int headerRowNumber, int headerColumnNumber, double marginLeft,
- double marginRight) {
- try {
- TableTableElement newTEle = createTable(ownerContainer, numRows, numCols, headerRowNumber,
- headerColumnNumber, marginLeft, marginRight);
- ownerContainer.getTableContainerElement().appendChild(newTEle);
- return getTableInstance(newTEle);
- } catch (Exception e) {
- Logger.getLogger(Table.class.getName()).log(Level.SEVERE, e.getMessage(), e);
- }
- return null;
- }
-
- /**
- * Construct the <code>Table</code> feature with a specified row number
- * and column number.
- * <p>
- * The table will be inserted at the end of the container. An unique
- * table name will be given, you may set a custom table name using the
- * <code>setTableName</code> method.
- * <p>
- * If the container is a text document, cell borders will be created by
- * default.
- *
- * @param numRows
- * the row number
- * @param numCols
- * the column number
- * @return a new instance of <code>Table</code>
- */
- public Table newTable(int numRows, int numCols) {
- return newTable(numRows, numCols, 0, 0);
- }
-
- /**
- * Construct the Table feature with a specified 2 dimension array as the
- * data of this table. The value type of each cell is float.
- * <p>
- * The table will be inserted at the end of the container. An unique
- * table name will be given, you may set a custom table name using the
- * <code>setTableName</code> method.
- * <p>
- * If the container is a text document, cell borders will be created by
- * default.
- *
- * @param rowLabel
- * set as the header row, it can be null if no header row
- * needed
- * @param columnLabel
- * set as the header column, it can be null if no header
- * column needed
- * @param data
- * the two dimension array of double as the data of this
- * table
- * @return a new instance of <code>Table</code>
- */
- public Table newTable(String[] rowLabel, String[] columnLabel, double[][] data) {
- int rowNumber = DEFAULT_ROW_COUNT;
- int columnNumber = DEFAULT_COLUMN_COUNT;
- if (data != null) {
- rowNumber = data.length;
- columnNumber = data[0].length;
- }
- int rowHeaders = 0, columnHeaders = 0;
-
- if (rowLabel != null) {
- rowHeaders = 1;
- }
- if (columnLabel != null) {
- columnHeaders = 1;
- }
- try {
- TableTableElement newTEle = createTable(ownerContainer, rowNumber + rowHeaders, columnNumber
- + columnHeaders, rowHeaders, columnHeaders);
- // append to the end of table container
- ownerContainer.getTableContainerElement().appendChild(newTEle);
- Table table = getTableInstance(newTEle);
- List<Row> rowList = table.getRowList();
- for (int i = 0; i < rowNumber + rowHeaders; i++) {
- Row row = rowList.get(i);
- for (int j = 0; j < columnNumber + columnHeaders; j++) {
- if ((i == 0) && (j == 0)) {
- continue;
- }
- Cell cell = row.getCellByIndex(j);
- if (i == 0 && columnLabel != null) // first row, should
- // fill column
- // labels
- {
- if (j <= columnLabel.length) {
- cell.setStringValue(columnLabel[j - 1]);
- } else {
- cell.setStringValue("");
- }
- } else if (j == 0 && rowLabel != null) // first column,
- // should fill
- // row labels
- {
- if (i <= rowLabel.length) {
- cell.setStringValue(rowLabel[i - 1]);
- } else {
- cell.setStringValue("");
- }
- } else {// data
- if ((data != null) && (i >= rowHeaders) && (j >= columnHeaders)) {
- cell.setDoubleValue(data[i - rowHeaders][j - columnHeaders]);
- }
- }
- }
- }
- return table;
-
- } catch (DOMException e) {
- Logger.getLogger(Table.class.getName()).log(Level.SEVERE, e.getMessage(), e);
- } catch (Exception e) {
- Logger.getLogger(Table.class.getName()).log(Level.SEVERE, e.getMessage(), e);
- }
- return null;
- }
-
- /**
- * Construct the Table feature with a specified 2 dimension array as the
- * data of this table. The value type of each cell is string.
- * <p>
- * The table will be inserted at the end of the container. An unique
- * table name will be given, you may set a custom table name using the
- * <code>setTableName</code> method.
- * <p>
- * If the container is a text document, cell borders will be created by
- * default.
- *
- * @param rowLabel
- * set as the header row, it can be null if no header row
- * needed
- * @param columnLabel
- * set as the header column, it can be null if no header
- * column needed
- * @param data
- * the two dimension array of string as the data of this
- * table
- * @return a new instance of <code>Table</code>
- */
- public Table newTable(String[] rowLabel, String[] columnLabel, String[][] data) {
- int rowNumber = DEFAULT_ROW_COUNT;
- int columnNumber = DEFAULT_COLUMN_COUNT;
- if (data != null) {
- rowNumber = data.length;
- columnNumber = data[0].length;
- }
- int rowHeaders = 0, columnHeaders = 0;
-
- if (rowLabel != null) {
- rowHeaders = 1;
- }
- if (columnLabel != null) {
- columnHeaders = 1;
- }
- try {
- TableTableElement newTEle = createTable(ownerContainer, rowNumber + rowHeaders, columnNumber
- + columnHeaders, rowHeaders, columnHeaders);
- // append to the end of table container
- ownerContainer.getTableContainerElement().appendChild(newTEle);
-
- Table table = getTableInstance(newTEle);
- List<Row> rowList = table.getRowList();
- for (int i = 0; i < rowNumber + rowHeaders; i++) {
- Row row = rowList.get(i);
- for (int j = 0; j < columnNumber + columnHeaders; j++) {
- if ((i == 0) && (j == 0)) {
- continue;
- }
- Cell cell = row.getCellByIndex(j);
- if (i == 0 && columnLabel != null) // first row, should
- // fill column
- // labels
- {
- if (j <= columnLabel.length) {
- cell.setStringValue(columnLabel[j - 1]);
- } else {
- cell.setStringValue("");
- }
- } else if (j == 0 && rowLabel != null) // first column,
- // should fill
- // row labels
- {
- if (i <= rowLabel.length) {
- cell.setStringValue(rowLabel[i - 1]);
- } else {
- cell.setStringValue("");
- }
- } else {
- if ((data != null) && (i >= rowHeaders) && (j >= columnHeaders)) {
- cell.setStringValue(data[i - rowHeaders][j - columnHeaders]);
- }
- }
- }
- }
- return table;
-
- } catch (DOMException e) {
- Logger.getLogger(Table.class.getName()).log(Level.SEVERE, e.getMessage(), e);
- } catch (Exception e) {
- Logger.getLogger(Table.class.getName()).log(Level.SEVERE, e.getMessage(), e);
- }
- return null;
- }
- }
-
- private Table(TableContainer container, TableTableElement table) {
- mTableElement = table;
- mDocument = getOwnerDocument(container);
- if (mDocument instanceof SpreadsheetDocument) {
- mIsSpreadsheet = true;
- } else {
- mIsSpreadsheet = false;
- }
- }
-
- private static Document getOwnerDocument(TableContainer tableContainer) {
- OdfElement containerElement = tableContainer.getTableContainerElement();
- OdfFileDom ownerDocument = (OdfFileDom) containerElement.getOwnerDocument();
- return (Document) ownerDocument.getDocument();
- }
-
- /**
- * Get a table feature instance by an instance of
- * <code>TableTableElement</code>.
- *
- * @param element
- * an instance of <code>TableTableElement</code>
- * @return an instance of <code>Table</code> that can represent
- * <code>element</code>
- */
- public static Table getInstance(TableTableElement element) {
- Document ownerDocument = (Document) ((OdfFileDom) (element.getOwnerDocument())).getDocument();
- return ownerDocument.getTableBuilder().getTableInstance(element);
- }
-
- /**
- * Construct the <code>Table</code> feature. The default column count is 5.
- * The default row count is 2.
- * <p>
- * The table will be inserted at the end of the container. An unique table
- * name will be given, you may set a custom table name using the
- * <code>setTableName</code> method.
- * <p>
- * If the <code>tableContainer</code> is a text document, cell borders will
- * be created by default.
- *
- * @param tableContainer
- * the table container that contains this table
- * @return the created <code>Table</code> feature instance
- */
- public static Table newTable(TableContainer tableContainer) {
- return tableContainer.getTableBuilder().newTable();
- }
-
- /**
- * Construct the <code>Table</code> feature with a specified row number and
- * column number.
- * <p>
- * The table will be inserted at the end of the tableContainer. An unique
- * table name will be given, you may set a custom table name using the
- * <code>setTableName</code> method.
- * <p>
- * If the <code>tableContainer</code> is a text document, cell borders will
- * be created by default.
- *
- * @param tableContainer
- * the table container that contains this table
- * @param numRows
- * the row number
- * @param numCols
- * the column number
- * @return a new instance of <code>Table</code>
- */
- public static Table newTable(TableContainer tableContainer, int numRows, int numCols) {
- return tableContainer.getTableBuilder().newTable(numRows, numCols);
- }
-
- /**
- * Construct the <code>Table</code> feature with a specified row number and
- * column number.
- * <p>
- * The table will be inserted at the end of the tableContainer. An unique
- * table name will be given, you may set a custom table name using the
- * <code>setTableName</code> method.
- * <p>
- * If the <code>tableContainer</code> is a text document, cell borders will
- * be created by default.
- *
- * @param tableContainer
- * the table container that contains this table
- * @param numRows
- * the row number
- * @param numCols
- * the column number
- * @param marginLeft double
- * <I>the left table margin in cm (between the left margin of document and the table)</I>
- * @param marginRight double
- * <I>the right table margin in cm (between the right margin of document and the table)</I>
- * @return a new instance of <code>Table</code>
- */
- public static Table newTable(TableContainer tableContainer, int numRows, int numCols,
- double marginLeft, double marginRight) {
- return tableContainer.getTableBuilder().newTable(numRows, numCols, 0, 0, marginLeft, marginRight);
- }
-
- /**
- * Construct the <code>Table</code> feature with a specified row number,
- * column number, header row number, header column number.
- * <p>
- * The table will be inserted at the end of the tableContainer. An unique
- * table name will be given, you may set a custom table name using the
- * <code>setTableName</code> method.
- * <p>
- * If the <code>tableContainer</code> is a text document, cell borders will
- * be created by default.
- *
- * @param tableContainer
- * the ODF document that contains this feature
- * @param numRows
- * the row number
- * @param numCols
- * the column number
- * @param headerRowNumber
- * the header row number
- * @param headerColumnNumber
- * the header column number
- * @return a new instance of <code>Table</code>
- * */
- public static Table newTable(TableContainer tableContainer, int numRows, int numCols, int headerRowNumber,
- int headerColumnNumber) {
- return tableContainer.getTableBuilder().newTable(numRows, numCols, headerRowNumber, headerColumnNumber);
- }
-
-
-
- /**
- * Construct the Table feature with a specified 2 dimension array as the
- * data of this table. The value type of each cell is float.
- * <p>
- * The table will be inserted at the end of the tableContainer. An unique
- * table name will be given, you may set a custom table name using the
- * <code>setTableName</code> method.
- * <p>
- * If the <code>tableContainer</code> is a text document, cell borders will
- * be created by default.
- *
- * @param tableContainer
- * the table container that contains this table
- * @param rowLabel
- * set as the header row, it can be null if no header row needed
- * @param columnLabel
- * set as the header column, it can be null if no header column
- * needed
- * @param data
- * the two dimension array of double as the data of this table
- * @return a new instance of <code>Table</code>
- */
- public static Table newTable(TableContainer tableContainer, String[] rowLabel, String[] columnLabel, double[][] data) {
- return tableContainer.getTableBuilder().newTable(rowLabel, columnLabel, data);
- }
-
- /**
- * Construct the Table feature with a specified 2 dimension array as the
- * data of this table. The value type of each cell is string.
- * <p>
- * The table will be inserted at the end of the tableContainer. An unique
- * table name will be given, you may set a custom table name using the
- * <code>setTableName</code> method.
- * <p>
- * If the <code>tableContainer</code> is a text document, cell borders will
- * be created by default.
- *
- * @param tableContainer
- * the table container that contains this table
- * @param rowLabel
- * set as the header row, it can be null if no header row needed
- * @param columnLabel
- * set as the header column, it can be null if no header column
- * needed
- * @param data
- * the two dimension array of string as the data of this table
- * @return a new instance of <code>Table</code>
- */
- public static Table newTable(TableContainer tableContainer, String[] rowLabel, String[] columnLabel, String[][] data) {
- return tableContainer.getTableBuilder().newTable(rowLabel, columnLabel, data);
- }
-
- Cell getCellInstance(TableTableCellElementBase cell, int repeatedColIndex, int repeatedRowIndex) {
- if (mCellRepository.containsKey(cell)) {
- Vector<Cell> list = mCellRepository.get(cell);
- Cell fCell = null;
- for (int i = 0; i < list.size(); i++) {
- if (list.get(i).getOdfElement() == cell && list.get(i).mnRepeatedColIndex == repeatedColIndex
- && list.get(i).mnRepeatedRowIndex == repeatedRowIndex) {
- fCell = list.get(i);
- break;
- }
- }
- if (fCell == null) {
- fCell = new Cell(cell, repeatedColIndex, repeatedRowIndex);
- list.add(fCell);
- }
- return fCell;
- } else {
- Cell newCell = new Cell(cell, repeatedColIndex, repeatedRowIndex);
- Vector<Cell> list = new Vector<Cell>();
- list.add(newCell);
- mCellRepository.put(cell, list);
- return newCell;
- }
- }
-
- Row getRowInstance(TableTableRowElement row, int repeatedRowIndex) {
- if (mRowRepository.containsKey(row)) {
- Vector<Row> list = mRowRepository.get(row);
- if (list.size() <= repeatedRowIndex) {
- list.setSize(repeatedRowIndex + 1);
- }
- Row fCell = list.get(repeatedRowIndex);
- if (fCell == null) {
- fCell = new Row(row, repeatedRowIndex);
- list.set(repeatedRowIndex, fCell);
- }
- return fCell;
- } else {
- Row newRow = new Row(row, repeatedRowIndex);
- int size = (repeatedRowIndex > 7) ? (repeatedRowIndex + 1) : 8;
- Vector<Row> list = new Vector<Row>(size);
- list.setSize(repeatedRowIndex + 1);
- list.set(repeatedRowIndex, newRow);
- mRowRepository.put(row, list);
- return newRow;
- }
- }
-
- Column getColumnInstance(TableTableColumnElement col, int repeatedColIndex) {
- if (mColumnRepository.containsKey(col)) {
- Vector<Column> list = mColumnRepository.get(col);
- if (list.size() <= repeatedColIndex) {
- list.setSize(repeatedColIndex + 1);
- }
- Column fClm = list.get(repeatedColIndex);
- if (fClm == null) {
- fClm = new Column(col, repeatedColIndex);
- list.set(repeatedColIndex, fClm);
- }
- return fClm;
- } else {
- Column newColumn = new Column(col, repeatedColIndex);
- int size = (repeatedColIndex > 7) ? (repeatedColIndex + 1) : 8;
- Vector<Column> list = new Vector<Column>(size);
- list.setSize(repeatedColIndex + 1);
- list.set(repeatedColIndex, newColumn);
- mColumnRepository.put(col, list);
- return newColumn;
- }
- }
-
- TableTableColumnElement getColumnElementByIndex(int colIndex) {
- int result = 0;
- TableTableColumnElement columnEle = null;
- for (Node n : new DomNodeList(mTableElement.getChildNodes())) {
- if (n instanceof TableTableHeaderColumnsElement) {
- TableTableHeaderColumnsElement headers = (TableTableHeaderColumnsElement) n;
- for (Node m : new DomNodeList(headers.getChildNodes())) {
- if (m instanceof TableTableColumnElement) {
- columnEle = (TableTableColumnElement) m;
- if (columnEle.getTableNumberColumnsRepeatedAttribute() == null) {
- result += 1;
- } else {
- result += columnEle.getTableNumberColumnsRepeatedAttribute();
- }
- }
- if (result > colIndex) {
- break;
- }
- }
- }
- if (n instanceof TableTableColumnElement) {
- columnEle = (TableTableColumnElement) n;
- if (columnEle.getTableNumberColumnsRepeatedAttribute() == null) {
- result += 1;
- } else {
- result += columnEle.getTableNumberColumnsRepeatedAttribute();
- }
- }
- if (result > colIndex) {
- break;
- }
- }
- return columnEle;
- }
-
- TableTableRowElement getRowElementByIndex(int rowIndex) {
- int result = 0;
- TableTableRowElement rowEle = null;
- for (Node n : new DomNodeList(mTableElement.getChildNodes())) {
- if (n instanceof TableTableHeaderRowsElement) {
- TableTableHeaderRowsElement headers = (TableTableHeaderRowsElement) n;
- for (Node m : new DomNodeList(headers.getChildNodes())) {
- if (m instanceof TableTableRowElement) {
- rowEle = (TableTableRowElement) m;
- result += rowEle.getTableNumberRowsRepeatedAttribute();
- }
- if (result > rowIndex) {
- break;
- }
- }
- }
- if (n instanceof TableTableRowElement) {
- rowEle = (TableTableRowElement) n;
- result += ((TableTableRowElement) n).getTableNumberRowsRepeatedAttribute();
- }
- if (result > rowIndex) {
- break;
- }
- }
- return rowEle;
- }
-
- /**
- * Get the width of the table (in Millimeter).
- * <p>
- * Throw an UnsupportedOperationException if the table is one sheet of a
- * spreadsheet document. because the sheet doesn't have an attribute of
- * table width.
- *
- * @return the width of the current table (in Millimeter).
- * <p>
- * An UnsupportedOperationException will be thrown if the table is
- * in the spreadsheet document.
- */
- public double getWidth() {
- if (!mIsSpreadsheet) {
- String sWidth = mTableElement.getProperty(OdfTableProperties.Width);
- if (sWidth == null) {
- int colCount = getColumnCount();
- double tableWidth = 0;
- for (int i = 0; i < colCount; i++) {
- Column col = getColumnByIndex(i);
- tableWidth += col.getWidth();
- }
- return tableWidth;
- } else{
- return PositiveLength.parseDouble(sWidth, Unit.MILLIMETER);
- }
- } else {
- throw new UnsupportedOperationException();
- }
- }
-
- /**
- * Set the width of the table (in Millimeter).
- * <p>
- * Throw an UnsupportedOperationException if the table is part of a
- * spreadsheet document that does not allow to change the table size,
- * because spreadsheet is not allow user to set the table size.
- *
- * @param width
- * the width that need to set (in Millimeter).
- * <p>
- * An UnsupportedOperationException will be thrown if the table
- * is in the spreadsheet document.
- */
- public void setWidth(double width) {
- if (!mIsSpreadsheet) {
- double roundingFactor = 10000.0;
- //TODO:need refactor to PositiveLength.
- double inValue = Math.round(roundingFactor * width / Unit.INCH.unitInMillimiter()) / roundingFactor;
- String sWidthIN = String.valueOf(inValue) + Unit.INCH.abbr();
- mTableElement.setProperty(OdfTableProperties.Width, sWidthIN);
- // if the width is changed, we should also change the table:align
- // properties if it is "margins"
- // otherwise the width seems not changed
- String alineStyle = mTableElement.getProperty(StyleTablePropertiesElement.Align);
- if (TableAlignAttribute.Value.MARGINS.toString().equals(alineStyle)) {
- mTableElement.setProperty(StyleTablePropertiesElement.Align, TableAlignAttribute.Value.LEFT.toString());
- }
- } else {
- throw new UnsupportedOperationException();
- }
- }
-
- static void setLeftTopBorderStyleProperties(OdfStyle style) {
- style.setProperty(StyleTableCellPropertiesElement.Padding, "0.0382in");
- style.setProperty(StyleTableCellPropertiesElement.BorderLeft, "0.0007in solid #000000");
- style.setProperty(StyleTableCellPropertiesElement.BorderRight, "none");
- style.setProperty(StyleTableCellPropertiesElement.BorderTop, "0.0007in solid #000000");
- style.setProperty(StyleTableCellPropertiesElement.BorderBottom, "0.0007in solid #000000");
- }
-
- static void setRightTopBorderStyleProperties(OdfStyle style) {
- style.setProperty(StyleTableCellPropertiesElement.Padding, "0.0382in");
- style.setProperty(StyleTableCellPropertiesElement.Border, "0.0007in solid #000000");
- }
-
- static void setLeftBottomBorderStylesProperties(OdfStyle style) {
- style.setProperty(StyleTableCellPropertiesElement.Padding, "0.0382in");
- style.setProperty(StyleTableCellPropertiesElement.BorderLeft, "0.0007in solid #000000");
- style.setProperty(StyleTableCellPropertiesElement.BorderRight, "none");
- style.setProperty(StyleTableCellPropertiesElement.BorderTop, "none");
- style.setProperty(StyleTableCellPropertiesElement.BorderBottom, "0.0007in solid #000000");
-
- }
-
- static void setRightBottomBorderStylesProperties(OdfStyle style) {
- style.setProperty(StyleTableCellPropertiesElement.Padding, "0.0382in");
- style.setProperty(StyleTableCellPropertiesElement.Border, "0.0007in solid #000000");
- style.setProperty(StyleTableCellPropertiesElement.BorderTop, "none");
- style.setProperty(StyleTableCellPropertiesElement.BorderBottom, "0.0007in solid #000000");
- }
-
- private static TableTableElement createTable(TableContainer container, int numRows, int numCols,
- int headerRowNumber, int headerColumnNumber) throws Exception {
- return createTable(container, numRows, numCols, headerRowNumber, headerColumnNumber, 0, 0);
- }
-
- private static TableTableElement createTable(TableContainer container, int numRows, int numCols,
- int headerRowNumber, int headerColumnNumber, double marginLeft, double marginRight) throws Exception {
- Document document = getOwnerDocument(container);
- OdfElement containerElement = container.getTableContainerElement();
- OdfFileDom dom = (OdfFileDom) containerElement.getOwnerDocument();
- double tableWidth = getTableWidth(container, marginLeft, marginRight);
-
- boolean isTextDocument = document instanceof TextDocument;
-
- // check arguments
- if (numRows < 1 || numCols < 1 || headerRowNumber < 0 || headerColumnNumber < 0 || headerRowNumber > numRows
- || headerColumnNumber > numCols) {
- throw new IllegalArgumentException("Can not create table with the given parameters:\n" + "Rows " + numRows
- + ", Columns " + numCols + ", HeaderRows " + headerRowNumber + ", HeaderColumns "
- + headerColumnNumber);
- }
- OdfOfficeAutomaticStyles styles = null;
- if (dom instanceof OdfContentDom) {
- styles = ((OdfContentDom) dom).getAutomaticStyles();
- } else if (dom instanceof OdfStylesDom) {
- styles = ((OdfStylesDom) dom).getAutomaticStyles();
- }
- // 1. create table element
- TableTableElement newTEle = (TableTableElement) OdfXMLFactory.newOdfElement(dom, OdfName.newName(
- OdfDocumentNamespace.TABLE, "table"));
- String tablename = getUniqueTableName(container);
- newTEle.setTableNameAttribute(tablename);
- // create style
- OdfStyle tableStyle = styles.newStyle(OdfStyleFamily.Table);
- String stylename = tableStyle.getStyleNameAttribute();
- tableStyle.setProperty(StyleTablePropertiesElement.Width, tableWidth + "in");
- tableStyle.setProperty(StyleTablePropertiesElement.Align, DEFAULT_TABLE_ALIGN);
- if (marginLeft != 0) {
- tableStyle.setProperty(StyleTablePropertiesElement.MarginLeft, (new DecimalFormat("#0.##")
- .format(marginLeft) + Unit.CENTIMETER.abbr()).replace(",", "."));
- }
- if (marginRight != 0) {
- tableStyle.setProperty(StyleTablePropertiesElement.MarginRight, (new DecimalFormat("#0.##")
- .format(marginRight) + Unit.CENTIMETER.abbr()).replace(",", "."));
- }
- newTEle.setStyleName(stylename);
-
- // 2. create column elements
- // 2.0 create column style
- OdfStyle columnStyle = styles.newStyle(OdfStyleFamily.TableColumn);
- String columnStylename = columnStyle.getStyleNameAttribute();
- // for spreadsheet document, no need compute column width.
- if (isTextDocument) {
- columnStyle.setProperty(StyleTableColumnPropertiesElement.ColumnWidth, IN_FORMAT.format(tableWidth
- / numCols)
- + "in");
- columnStyle.setProperty(StyleTableColumnPropertiesElement.RelColumnWidth, Math
- .round(DEFAULT_REL_TABLE_WIDTH / numCols)
- + "*");
- }
- // 2.1 create header column elements
- if (headerColumnNumber > 0) {
- TableTableHeaderColumnsElement headercolumns = (TableTableHeaderColumnsElement) OdfXMLFactory
- .newOdfElement(dom, OdfName.newName(OdfDocumentNamespace.TABLE, "table-header-columns"));
- TableTableColumnElement headercolumn = (TableTableColumnElement) OdfXMLFactory.newOdfElement(dom, OdfName
- .newName(OdfDocumentNamespace.TABLE, "table-column"));
- if (headerColumnNumber > 1) {
- headercolumn.setTableNumberColumnsRepeatedAttribute(headerColumnNumber);
- } else {
- headercolumn.removeAttributeNS(OdfDocumentNamespace.TABLE.getUri(), "number-columns-repeated");
- }
- headercolumns.appendChild(headercolumn);
- newTEle.appendChild(headercolumns);
- headercolumn.setStyleName(columnStylename);
- }
- // 2.2 create common column elements
- TableTableColumnElement columns = (TableTableColumnElement) OdfXMLFactory.newOdfElement(dom, OdfName.newName(
- OdfDocumentNamespace.TABLE, "table-column"));
- int tableNumberColumnsRepeatedValue = numCols - headerColumnNumber;
- if (tableNumberColumnsRepeatedValue > 1) {
- columns.setTableNumberColumnsRepeatedAttribute(tableNumberColumnsRepeatedValue);
- }
- columns.setStyleName(columnStylename);
- newTEle.appendChild(columns);
-
- // 3. create row elements
- // 3.0 create 4 kinds of styles
- OdfStyle lefttopStyle = null, leftbottomStyle = null, righttopStyle = null, rightbottomStyle = null;
-
- if (isTextDocument) {
- lefttopStyle = styles.newStyle(OdfStyleFamily.TableCell);
- setLeftTopBorderStyleProperties(lefttopStyle);
-
- leftbottomStyle = styles.newStyle(OdfStyleFamily.TableCell);
- setLeftBottomBorderStylesProperties(leftbottomStyle);
-
- righttopStyle = styles.newStyle(OdfStyleFamily.TableCell);
- setRightTopBorderStyleProperties(righttopStyle);
-
- rightbottomStyle = styles.newStyle(OdfStyleFamily.TableCell);
- setRightBottomBorderStylesProperties(rightbottomStyle);
- }
-
- // 3.1 create header row elements
- if (headerRowNumber > 0) {
- TableTableHeaderRowsElement headerrows = (TableTableHeaderRowsElement) OdfXMLFactory.newOdfElement(dom,
- OdfName.newName(OdfDocumentNamespace.TABLE, "table-header-rows"));
- for (int i = 0; i < headerRowNumber; i++) {
- TableTableRowElement aRow = (TableTableRowElement) OdfXMLFactory.newOdfElement(dom, OdfName.newName(
- OdfDocumentNamespace.TABLE, "table-row"));
- for (int j = 0; j < numCols; j++) {
- TableTableCellElement aCell = (TableTableCellElement) OdfXMLFactory.newOdfElement(dom, OdfName
- .newName(OdfDocumentNamespace.TABLE, "table-cell"));
- if (isTextDocument) {
- if ((j + 1 == numCols) && (i == 0)) {
- aCell.setStyleName(righttopStyle.getStyleNameAttribute());
- } else if (i == 0) {
- aCell.setStyleName(lefttopStyle.getStyleNameAttribute());
- } else if ((j + 1 == numCols) && (i > 0)) {
- aCell.setStyleName(rightbottomStyle.getStyleNameAttribute());
- } else {
- aCell.setStyleName(leftbottomStyle.getStyleNameAttribute());
- }
- }
- aRow.appendChild(aCell);
- }
- headerrows.appendChild(aRow);
- }
- newTEle.appendChild(headerrows);
- }
-
- // 3.2 create common row elements
- for (int i = headerRowNumber; i < numRows; i++) {
- TableTableRowElement aRow = (TableTableRowElement) OdfXMLFactory.newOdfElement(dom, OdfName.newName(
- OdfDocumentNamespace.TABLE, "table-row"));
- for (int j = 0; j < numCols; j++) {
- TableTableCellElement aCell = (TableTableCellElement) OdfXMLFactory.newOdfElement(dom, OdfName.newName(
- OdfDocumentNamespace.TABLE, "table-cell"));
- if (isTextDocument) {
- if ((j + 1 == numCols) && (i == 0)) {
- aCell.setStyleName(righttopStyle.getStyleNameAttribute());
- } else if (i == 0) {
- aCell.setStyleName(lefttopStyle.getStyleNameAttribute());
- } else if ((j + 1 == numCols) && (i > 0)) {
- aCell.setStyleName(rightbottomStyle.getStyleNameAttribute());
- } else {
- aCell.setStyleName(leftbottomStyle.getStyleNameAttribute());
- }
- }
- aRow.appendChild(aCell);
- }
- newTEle.appendChild(aRow);
- }
-
- return newTEle;
- }
-
- /**
- * Apply the formatting specified in the template to corresponding table
- * cells.
- * <p>
- * A table can only be formatted as one type of styles: even-odd-rows or
- * even-odd-columns. The rule is to check the style of odd rows and even
- * rows in the template, only if they have one different properties, table:
- * style-name or table:paragraph-style-name, the table template will be
- * treated as a even-odd-columns styled table.
- * <p>
- * If one style in the template is null, the style of corresponding cells
- * will be removed. An empty template can be used to remove all the styles
- * in a table.
- *
- * @param template
- * @throws IllegalArgumentException
- * if the given template is null
- * @throws Exception
- * if content DOM could not be initialized
- */
- public void applyStyle(TableTemplate template) throws Exception {
-
- if (template == null)
- throw new IllegalArgumentException(
- "The template cannot null to be applied to a table.");
-
- Document doc = this.getOwnerDocument();
- OdfOfficeAutomaticStyles styles = doc.getContentDom()
- .getAutomaticStyles();
-
- // decide row style or column style
- boolean isEqualTableStyle = true;
- boolean isEqualParaStyle = true;
- OdfStyle evenRowsTableStyle = styles.getStyle(template
- .getTableEvenRowsTableStyle(), OdfStyleFamily.TableCell);
- OdfStyle oddRowsTableStyle = styles.getStyle(template
- .getTableOddRowsTableStyle(), OdfStyleFamily.TableCell);
- OdfStyle evenRowsParagraphStyle = styles.getStyle(template
- .getTableEvenRowsParagraphStyle(), OdfStyleFamily.Paragraph);
- OdfStyle oddRowsParagraphStyle = styles.getStyle(template
- .getTableOddRowsParagraphStyle(), OdfStyleFamily.Paragraph);
- if (evenRowsTableStyle != null || oddRowsTableStyle != null)
- isEqualTableStyle = evenRowsTableStyle.compareTo(oddRowsTableStyle) == 0;
- if (evenRowsParagraphStyle != null || oddRowsParagraphStyle != null)
- isEqualParaStyle = evenRowsParagraphStyle
- .compareTo(oddRowsParagraphStyle) == 0;
-
- Iterator<Row> rowIterator = this.getRowIterator();
-
- if (rowIterator.hasNext()) { // first row
- Row currentRow = rowIterator.next();
- String firstCellTableStyle = template
- .getExtendedTableStyleByType(TableTemplate.ExtendedStyleType.FIRSTROWSTARTCOLUM);
- String firstCellParagraphStyle = template
- .getExtendedParagraphStyleByType(TableTemplate.ExtendedStyleType.FIRSTROWSTARTCOLUM);
- String lastCellTableStyle = template
- .getExtendedTableStyleByType(TableTemplate.ExtendedStyleType.FIRSTROWENDCOLUMN);
- String lastCellParagraphStyle = template
- .getExtendedParagraphStyleByType(TableTemplate.ExtendedStyleType.FIRSTROWENDCOLUMN);
- String evenCellTableStyle = template.getTableFirstRowTableStyle();
- String evenCellParagraphStyle = template
- .getTableFirstRowParagraphStyle();
- String oddCellTableStyle = evenCellTableStyle;
- String oddCellParagraphStyle = evenCellParagraphStyle;
-
- applyStyleToRow(template, currentRow, firstCellTableStyle,
- oddCellTableStyle, evenCellTableStyle, lastCellTableStyle,
- firstCellParagraphStyle, oddCellParagraphStyle,
- evenCellParagraphStyle, lastCellParagraphStyle);
-
- int line = 0;
- while (rowIterator.hasNext()) {
- currentRow = rowIterator.next();
- line++;
-
- if (!rowIterator.hasNext()) { // last row
- firstCellTableStyle = template
- .getExtendedTableStyleByType(TableTemplate.ExtendedStyleType.LASTROWSTARTCOLUMN);
- firstCellParagraphStyle = template
- .getExtendedParagraphStyleByType(TableTemplate.ExtendedStyleType.LASTROWSTARTCOLUMN);
- lastCellTableStyle = template
- .getExtendedTableStyleByType(TableTemplate.ExtendedStyleType.LASTROWENDCOLUMN);
- lastCellParagraphStyle = template
- .getExtendedParagraphStyleByType(TableTemplate.ExtendedStyleType.LASTROWENDCOLUMN);
- oddCellTableStyle = evenCellTableStyle = template
- .getTableLastRowTableStyle();
- oddCellParagraphStyle = evenCellParagraphStyle = template
- .getTableLastRowParagraphStyle();
-
- applyStyleToRow(template, currentRow, firstCellTableStyle,
- oddCellTableStyle, evenCellTableStyle,
- lastCellTableStyle, firstCellParagraphStyle,
- oddCellParagraphStyle, evenCellParagraphStyle,
- lastCellParagraphStyle);
-
- } else if (!isEqualTableStyle || !isEqualParaStyle) {
- firstCellTableStyle = template
- .getTableFirstColumnTableStyle();
- firstCellParagraphStyle = template
- .getTableFirstColumnParagraphStyle();
- lastCellTableStyle = template
- .getTableLastColumnTableStyle();
- lastCellParagraphStyle = template
- .getTableLastColumnParagraphStyle();
-
- if (line % 2 != 0) { // odd row
-
- oddCellTableStyle = evenCellTableStyle = template
- .getTableOddRowsTableStyle();
- oddCellParagraphStyle = evenCellParagraphStyle = template
- .getTableOddRowsParagraphStyle();
- applyStyleToRow(template, currentRow,
- firstCellTableStyle, oddCellTableStyle,
- evenCellTableStyle, lastCellTableStyle,
- firstCellParagraphStyle, oddCellParagraphStyle,
- evenCellParagraphStyle, lastCellParagraphStyle);
- } else { // even row
-
- oddCellTableStyle = evenCellTableStyle = template
- .getTableEvenRowsTableStyle();
- oddCellParagraphStyle = evenCellParagraphStyle = template
- .getTableEvenRowsParagraphStyle();
-
- applyStyleToRow(template, currentRow,
- firstCellTableStyle, oddCellTableStyle,
- evenCellTableStyle, lastCellTableStyle,
- firstCellParagraphStyle, oddCellParagraphStyle,
- evenCellParagraphStyle, lastCellParagraphStyle);
- }
-
- } else { // even&odd column
- firstCellTableStyle = template
- .getTableFirstColumnTableStyle();
- firstCellParagraphStyle = template
- .getTableFirstColumnParagraphStyle();
- lastCellTableStyle = template
- .getTableLastColumnTableStyle();
- lastCellParagraphStyle = template
- .getTableLastColumnParagraphStyle();
- evenCellTableStyle = template
- .getTableEvenColumnsTableStyle();
- evenCellParagraphStyle = template
- .getTableEvenColumnsParagraphStyle();
- oddCellTableStyle = template.getTableOddColumnsTableStyle();
- oddCellParagraphStyle = template
- .getTableOddColumnsParagraphStyle();
- applyStyleToRow(template, currentRow, firstCellTableStyle,
- oddCellTableStyle, evenCellTableStyle,
- lastCellTableStyle, firstCellParagraphStyle,
- oddCellParagraphStyle, evenCellParagraphStyle,
- lastCellParagraphStyle);
- }
- }
-
- }
-
- }
-
- private void applyStyleToRow(TableTemplate template, Row row,
- String firstCellTableStyle, String oddCellTableStyle,
- String evenCellTableStyle, String lastCellTableStyle,
- String firstCellParagraphStyle, String oddCellParagraphStyle,
- String evenCellParagraphStyle, String lastCellParagraphStyle) {
- int cellIndex = 0;
- int mnRepeatedIndex = row.getRowsRepeatedNumber();
- int lastIndex = row.getCellCount() - 1;
- Cell cell;
- String tableStyle, paraStyle;
- for (Node n : new DomNodeList(row.getOdfElement().getChildNodes())) {
- if (n instanceof TableTableCellElementBase) {
- cell = this.getCellInstance((TableTableCellElementBase) n, 0,
- mnRepeatedIndex);
- if (cell.getColumnsRepeatedNumber() > 1)
- lastIndex -= cell.getColumnsRepeatedNumber() - 1;
- if (cellIndex == 0) {
- tableStyle = firstCellTableStyle;
- paraStyle = firstCellParagraphStyle;
- } else if (cellIndex == lastIndex) {
- tableStyle = lastCellTableStyle;
- paraStyle = lastCellParagraphStyle;
- } else if (cellIndex % 2 == 0) {
- tableStyle = evenCellTableStyle;
- paraStyle = evenCellParagraphStyle;
- } else {
- tableStyle = oddCellTableStyle;
- paraStyle = oddCellParagraphStyle;
- }
- cell.setCellStyleName(tableStyle);
- Iterator<Paragraph> paraIterator = cell.getParagraphIterator();
- while (paraIterator.hasNext()) {
- Paragraph t = paraIterator.next();
- t.getOdfElement().setStyleName(paraStyle);
- }
- cellIndex++;
- }
- }
- }
-
- private static String getUniqueTableName(TableContainer container) {
- List<Table> tableList = container.getTableList();
- boolean notUnique = true;
-
- String tablename = "Table" + (tableList.size() + 1);
-
- while (notUnique) {
- notUnique = false;
- for (int i = 0; i < tableList.size(); i++) {
- if (tableList.get(i).getTableName() != null) {
- if (tableList.get(i).getTableName().equalsIgnoreCase(tablename)) {
- notUnique = true;
- break;
- }
- }
- }
- if (notUnique) {
- tablename = tablename + Math.round(Math.random() * 10);
- }
- }
-
- return tablename;
-
- }
-
- /**
- * Get the row count of this table.
- *
- * @return total count of rows
- */
- public int getRowCount() {
- int result = 0;
- for (Node n : new DomNodeList(mTableElement.getChildNodes())) {
- if (n instanceof TableTableHeaderRowsElement) {
- result += getHeaderRowCount((TableTableHeaderRowsElement) n);
- }
- if (n instanceof TableTableRowElement) {
- result += ((TableTableRowElement) n).getTableNumberRowsRepeatedAttribute();
- }
- if (n instanceof TableTableRowsElement) {
- for (Node nn : new DomNodeList(n.getChildNodes())) {
- if (nn instanceof TableTableRowElement) {
- result += ((TableTableRowElement) nn).getTableNumberRowsRepeatedAttribute();
- }
- }
- }
- }
- return result;
- }
-
- /**
- * Get the column count of this table.
- *
- * @return total count of columns
- */
- public int getColumnCount() {
- int result = 0;
- for (Node n : new DomNodeList(mTableElement.getChildNodes())) {
- // TODO: how about <table:table-column-group>
- if (n instanceof TableTableHeaderColumnsElement) {
- result += getHeaderColumnCount((TableTableHeaderColumnsElement) n);
- }
-
- // <table:table-columns>
- if (n instanceof TableTableColumnsElement) {
- result += getColumnsCount((TableTableColumnsElement) n);
- }
-
- if (n instanceof TableTableColumnElement) {
- result += ((TableTableColumnElement) n).getTableNumberColumnsRepeatedAttribute();
- }
- // as different type of elements appear in order, so if n is one of
- // the the following elements, computing will stop. It's helpful
- // when the table has lots of rows.
- if (n instanceof TableTableHeaderRowsElement || n instanceof TableTableRowsElement
- || n instanceof TableTableRowGroupElement || n instanceof TableTableRowElement) {
- break;
- }
- }
- return result;
- }
-
- /**
- * This method is invoked by appendRow. When a table has no row, the first
- * row is a default row.
- */
- private TableTableRowElement createDefaultRow(int columnCount, boolean createRepeatedCell) {
- OdfFileDom dom = (OdfFileDom) mTableElement.getOwnerDocument();
- TableTableRowElement aRow = (TableTableRowElement) OdfXMLFactory.newOdfElement(dom, OdfName.newName(
- OdfDocumentNamespace.TABLE, "table-row"));
- if (createRepeatedCell) {
- TableTableCellElement aCell = (TableTableCellElement) OdfXMLFactory.newOdfElement(dom, OdfName.newName(
- OdfDocumentNamespace.TABLE, "table-cell"));
- if (columnCount > 1) {
- aCell.setTableNumberColumnsRepeatedAttribute(columnCount);
- }
- if (!mIsSpreadsheet) {
- OdfOfficeAutomaticStyles automaticStyles = mTableElement.getAutomaticStyles();
- OdfStyle borderStyle = automaticStyles.newStyle(OdfStyleFamily.TableCell);
- setRightTopBorderStyleProperties(borderStyle);
- aCell.setStyleName(borderStyle.getStyleNameAttribute());
- }
- aRow.appendChild(aCell);
- } else {
- OdfStyle lefttopStyle = null, righttopStyle = null;
- // create 2 kinds of styles
- if (!mIsSpreadsheet) {
- OdfOfficeAutomaticStyles automaticStyles = mTableElement.getAutomaticStyles();
- lefttopStyle = automaticStyles.newStyle(OdfStyleFamily.TableCell);
- setLeftTopBorderStyleProperties(lefttopStyle);
- righttopStyle = automaticStyles.newStyle(OdfStyleFamily.TableCell);
- setRightTopBorderStyleProperties(righttopStyle);
- }
- for (int j = 0; j < columnCount; j++) {
- TableTableCellElement aCell = (TableTableCellElement) OdfXMLFactory.newOdfElement(dom, OdfName.newName(
- OdfDocumentNamespace.TABLE, "table-cell"));
- if (!mIsSpreadsheet) {
- if (j + 1 == columnCount) {
- aCell.setStyleName(righttopStyle.getStyleNameAttribute());
- } else {
- aCell.setStyleName(lefttopStyle.getStyleNameAttribute());
- }
- }
- aRow.appendChild(aCell);
- }
- }
- return aRow;
- }
-
- /**
- * Append a row to the end of the table. The style of new row is same with
- * the last row in the table.
- * <p>
- * Since SIMPLE supports automatic table expansion. Whenever a cell outside
- * the current table is addressed the table is instantly expanded. Method
- * <code>getCellByPosition</code> can randomly access any cell, no matter it
- * in or out of the table original range.
- *
- * @return a new appended row
- * @see #appendRows(int)
- * @see #getRowByIndex(int)
- * @see #getCellByPosition(int, int)
- * @see #getCellByPosition(String)
- */
- public Row appendRow() {
- // find append position
- Node childNode = mTableElement.getLastChild();
- // where is the new row inserted before.
- Node positionNode = null;
- // row style and structure clone from.
- TableTableRowElement refRowElement = null;
- TableTableRowElement newRow = null;
- if (childNode instanceof TableNamedExpressionsElement) {
- childNode = childNode.getPreviousSibling();
- positionNode = childNode;
- }
- if (childNode instanceof TableTableRowElement) {
- refRowElement = (TableTableRowElement) childNode;
- }
- // TODO: what about childNode instanceof TableTableHeaderRowsElement,
- // TableTableRowsElement or TableTableRowGroupElement
- int columnCount = getColumnCount();
- // no row, create a default row
- if (refRowElement == null) {
- newRow = createDefaultRow(columnCount, true);
- mTableElement.appendChild(newRow);
- } else {
- newRow = (TableTableRowElement) OdfXMLFactory.newOdfElement((OdfFileDom) mTableElement.getOwnerDocument(),
- OdfName.newName(OdfDocumentNamespace.TABLE, "table-row"));
- TableTableCellElementBase cellElement = (TableTableCellElementBase) refRowElement.getFirstChild();
- int i = 1;
- while (cellElement != null && i <= columnCount) {
- // covered element
- String tableNameSpace = OdfDocumentNamespace.TABLE.getUri();
- if (cellElement instanceof TableCoveredTableCellElement) {
- TableCoveredTableCellElement coveredCellEle = (TableCoveredTableCellElement) cellElement;
- // find cover cell element
- TableTableRowElement aRowEle = (TableTableRowElement) (coveredCellEle.getParentNode()
- .getPreviousSibling());
- while (aRowEle != null) {
- // the cover cell and the first covered cell must have
- // the same column index.
- TableTableCellElementBase coverCellEle = (TableTableCellElementBase) (aRowEle.getFirstChild());
- int j = coverCellEle.getTableNumberColumnsRepeatedAttribute();
- while (j < i) {
- coverCellEle = (TableTableCellElementBase) (coverCellEle.getNextSibling());
- if (coverCellEle instanceof TableTableCellElement) {
- j += (coverCellEle.getTableNumberColumnsRepeatedAttribute() * (((TableTableCellElement) coverCellEle)
- .getTableNumberColumnsSpannedAttribute()));
- } else {
- j += coverCellEle.getTableNumberColumnsRepeatedAttribute();
- }
- }
- // find the cover cell, now start cell clone.
- if (coverCellEle instanceof TableTableCellElement) {
- TableTableCellElement newCellEle = (TableTableCellElement) (coverCellEle.cloneNode(true));
- cleanCell(newCellEle);
- newCellEle.removeAttributeNS(tableNameSpace, "number-rows-spanned");
- newRow.appendChild(newCellEle);
- // deal with the following covered cell, spread
- // sheet need change these covered cell to cell.
- if (mIsSpreadsheet) {
- // update column repeated number.
- int columnsSpannedNumber = newCellEle.getTableNumberColumnsSpannedAttribute();
- newCellEle.removeAttributeNS(tableNameSpace, "number-columns-spanned");
- int newColumnRepeatedNumber = newCellEle.getTableNumberColumnsRepeatedAttribute()
- * columnsSpannedNumber;
- if (newColumnRepeatedNumber > 1) {
- newCellEle.setTableNumberColumnsRepeatedAttribute(newColumnRepeatedNumber);
- } else {
- newCellEle.removeAttributeNS(tableNameSpace, "number-columns-repeated");
- }
- // ignore the following covered cell of
- // reference row.
- // added by Daisy because of a bug in demo4
- // cellElement is a covered cell. coverCellEle
- // is its cover cell.
- // below codes will count
- // newColumnRepeatedNumber covered cell.
- int tempi = newColumnRepeatedNumber;
- while (tempi > 0) {
- int iColumnRepeatedNumber = cellElement.getTableNumberColumnsRepeatedAttribute();
- if (iColumnRepeatedNumber > tempi) {
- // split covered cell
- if (cellElement instanceof TableCoveredTableCellElement) {
- cellElement.setTableNumberColumnsRepeatedAttribute(iColumnRepeatedNumber
- - tempi);
- TableTableCellElementBase newCoveredCellEle = (TableTableCellElementBase) cellElement
- .cloneNode(true);
- cleanCell(newCoveredCellEle);
- if (tempi > 1) {
- newCoveredCellEle.setTableNumberColumnsRepeatedAttribute(tempi);
- } else {
- newCoveredCellEle.removeAttributeNS(
- OdfDocumentNamespace.TABLE.getUri(), "number-columns-repeated");
- }
- refRowElement.insertBefore(newCoveredCellEle, cellElement);
- cellElement = newCoveredCellEle;
- }
- }
- tempi = tempi - cellElement.getTableNumberColumnsRepeatedAttribute();
- i = i + cellElement.getTableNumberColumnsRepeatedAttribute();
- if (!(cellElement instanceof TableCoveredTableCellElement) && (tempi > 0)){
- Logger.getLogger(Table.class.getName()).log(Level.FINE, "Not covered cell was ignored");
- }
- cellElement = (TableTableCellElementBase) (cellElement.getNextSibling());
- // while ((cellElement != null) &&
- // (cellElement instanceof
- // TableCoveredTableCellElement)) {
- // cellElement = (TableTableCellElementBase)
- // (cellElement.getNextSibling());
- // }
- }
- // i += newColumnRepeatedNumber;
- } else {
- // clone the following covered cell of reference
- // row.
- // added by Daisy because of a bug in demo4
- cellElement = (TableTableCellElementBase) cellElement.getNextSibling();
- i += cellElement.getTableNumberColumnsRepeatedAttribute();
- int newColumnSpanNumber = newCellEle.getTableNumberColumnsSpannedAttribute();
- while ((cellElement != null) && (cellElement instanceof TableCoveredTableCellElement)
- && (newColumnSpanNumber > 1)) {
- TableCoveredTableCellElement newCoveredCellElement = (TableCoveredTableCellElement) cellElement
- .cloneNode(true);
- cleanCell(newCoveredCellElement);
- newRow.appendChild(newCoveredCellElement);
- i += cellElement.getTableNumberColumnsRepeatedAttribute();
- cellElement = (TableTableCellElementBase) cellElement.getNextSibling();
- newColumnSpanNumber--;
- }
- }
- break;
- }
- // continue find cover cell
- Node preNode = aRowEle.getPreviousSibling();
- if (preNode instanceof TableTableRowElement) {
- aRowEle = (TableTableRowElement) preNode;
- } else {
- // </table:table-header-rows>
- aRowEle = (TableTableRowElement) (preNode.getLastChild());
- }
- }
- } else {
- TableTableCellElement newCellEle = (TableTableCellElement) cellElement.cloneNode(true);
- cleanCell(newCellEle);
- newRow.appendChild(newCellEle);
- Integer tableNumberColumnsRepeated = newCellEle.getTableNumberColumnsRepeatedAttribute();
- Integer tableNumberColumnsSpanned = newCellEle.getTableNumberColumnsSpannedAttribute();
- i += tableNumberColumnsRepeated * tableNumberColumnsSpanned;
- cellElement = (TableTableCellElementBase) cellElement.getNextSibling();
- if (tableNumberColumnsSpanned > 1) {
- int j = 1;
- if (mIsSpreadsheet) {
- newCellEle.removeAttributeNS(tableNameSpace, "number-columns-spanned");
- int newColumnRepeatedNumber = tableNumberColumnsRepeated * tableNumberColumnsSpanned;
- if (newColumnRepeatedNumber > 1) {
- newCellEle.setTableNumberColumnsRepeatedAttribute(newColumnRepeatedNumber);
- } else {
- newCellEle.removeAttributeNS(tableNameSpace, "number-columns-repeated");
- }
- // cellElement is not a covered cell.
- // below codes will count
- // (newColumnRepeatedNumber-1) covered cell.
- int tempi = newColumnRepeatedNumber;
- while (tempi > 1) {
- int iColumnRepeatedNumber = cellElement.getTableNumberColumnsRepeatedAttribute();
- if (iColumnRepeatedNumber > tempi + 1) {
- // split covered cell
- if (cellElement instanceof TableCoveredTableCellElement) {
- cellElement.setTableNumberColumnsRepeatedAttribute(iColumnRepeatedNumber
- - tempi + 1);
- TableTableCellElementBase newCoveredCellEle = (TableTableCellElementBase) cellElement
- .cloneNode(true);
- cleanCell(newCoveredCellEle);
- newCoveredCellEle.setTableNumberColumnsRepeatedAttribute(tempi - 1);
- refRowElement.insertBefore(newCoveredCellEle, cellElement);
- cellElement = newCoveredCellEle;
- }
- }
- tempi = tempi - cellElement.getTableNumberColumnsRepeatedAttribute();
- if (!(cellElement instanceof TableCoveredTableCellElement) && (tempi > 1)){
- Logger.getLogger(Table.class.getName()).log(Level.FINE, "Not covered cell was ignored");
- }
- cellElement = (TableTableCellElementBase) (cellElement.getNextSibling());
- }
- } else {
- while ((j < tableNumberColumnsSpanned) && (cellElement != null)) {
- int iColumnRepeatedNumber = cellElement.getTableNumberColumnsRepeatedAttribute();
- if (iColumnRepeatedNumber > tableNumberColumnsSpanned - j) {
- // split covered cell
- if (cellElement instanceof TableCoveredTableCellElement) {
- cellElement.setTableNumberColumnsRepeatedAttribute(iColumnRepeatedNumber
- - tableNumberColumnsSpanned + j);
- TableTableCellElementBase newCoveredCellEle = (TableTableCellElementBase) cellElement
- .cloneNode(true);
- cleanCell(newCoveredCellEle);
- newCoveredCellEle
- .setTableNumberColumnsRepeatedAttribute(tableNumberColumnsSpanned - j);
- refRowElement.insertBefore(newCoveredCellEle, cellElement);
- cellElement = newCoveredCellEle;
- }
- }
- TableTableCellElementBase newCoveredCellEle = (TableTableCellElementBase) cellElement
- .cloneNode(true);
- cleanCell(newCoveredCellEle);
- newRow.appendChild(newCoveredCellEle);
- j += newCoveredCellEle.getTableNumberColumnsRepeatedAttribute();
- cellElement = (TableTableCellElementBase) cellElement.getNextSibling();
- }
- }
- }
- }
- }
- if (positionNode == null) {
- mTableElement.appendChild(newRow);
- } else {
- mTableElement.insertBefore(newRow, positionNode);
- }
- }
- return getRowInstance(newRow, 0);
- }
-
- /**
- * Append a specific number of rows to the end of the table. The style of
- * new rows are same with the last row in the table.
- * <p>
- * Since SIMPLE supports automatic table expansion. Whenever a cell outside
- * the current table is addressed the table is instantly expanded. Method
- * <code>getCellByPosition</code> can randomly access any cell, no matter it
- * in or out of the table original range.
- *
- * @param rowCount
- * is the number of rows to be appended.
- * @return a list of new appended rows
- * @see #appendRow()
- * @see #getRowByIndex(int)
- * @see #getCellByPosition(int, int)
- * @see #getCellByPosition(String)
- */
- public List<Row> appendRows(int rowCount) {
- return appendRows(rowCount, false);
- }
-
- List<Row> appendRows(int rowCount, boolean isCleanStyle) {
- List<Row> resultList = new ArrayList<Row>();
- if (rowCount <= 0) {
- return resultList;
- }
- if (isUseRepeat()) {
- Row firstRow = appendRow();
- resultList.add(firstRow);
- if (rowCount > 1) {
- firstRow.setRowsRepeatedNumber(rowCount);
- TableTableRowElement firstRowEle = firstRow.getOdfElement();
- for (int i = 1; i < rowCount; i++) {
- Row row = getRowInstance(firstRowEle, i);
- resultList.add(row);
- }
- }
- } else {
- for (int i = 0; i < rowCount; i++) {
- Row firstRow = appendRow();
- resultList.add(firstRow);
- }
- }
- if (isCleanStyle) {
- // clean style name
- String tableNameSpace = OdfDocumentNamespace.TABLE.getUri();
- for (Row row : resultList) {
- Node cellE = row.getOdfElement().getFirstChild();
- while (cellE != null) {
- ((TableTableCellElementBase) cellE).removeAttributeNS(tableNameSpace, "style-name");
- cellE = cellE.getNextSibling();
- }
- }
- }
- return resultList;
- }
-
- /**
- * Append a column at the end of the table. The style of new column is same
- * with the last column in the table.
- * <p>
- * Since SIMPLE supports automatic table expansion. Whenever a cell outside
- * the current table is addressed the table is instantly expanded. Method
- * <code>getCellByPosition</code> can randomly access any cell, no matter it
- * in or out of the table original range.
- *
- * @return a new appended column
- * @see #appendColumns(int)
- * @see #getColumnByIndex(int)
- * @see #getCellByPosition(int, int)
- * @see #getCellByPosition(String)
- */
- public Column appendColumn() {
- List<Column> columnList = getColumnList();
- int columnCount = columnList.size();
-
- TableTableColumnElement newColumn;
- OdfElement positonElement = getRowElementByIndex(0);
- if (positonElement.getParentNode() instanceof TableTableHeaderRowsElement) {
- positonElement = (OdfElement) positonElement.getParentNode();
- }
-
- // Moved before column elements inserted
- // insert cells firstly
- // Or else, wrong column number will be gotten in updateCellRepository,
- // which will cause a NPE.
- // insertCellBefore()->splitRepeatedRows()->updateRowRepository()->updateCellRepository()
- List<Row> rowList = getRowList();
- for (int i = 0; i < rowList.size();) {
- Row row1 = rowList.get(i);
- row1.insertCellBefore(row1.getCellByIndex(columnCount - 1), null);
- i = i + row1.getRowsRepeatedNumber();
- }
-
- // insert columns secondly
- if (columnList.size() == 0) // no column, create a new column
- {
- OdfStyle columnStyle = mTableElement.getAutomaticStyles().newStyle(OdfStyleFamily.TableColumn);
- String columnStylename = columnStyle.getStyleNameAttribute();
- columnStyle.setProperty(StyleTableColumnPropertiesElement.ColumnWidth, DEFAULT_TABLE_WIDTH + "in");
- columnStyle.setProperty(StyleTableColumnPropertiesElement.RelColumnWidth, DEFAULT_REL_TABLE_WIDTH + "*");
-
- newColumn = (TableTableColumnElement) OdfXMLFactory.newOdfElement((OdfFileDom) mTableElement
- .getOwnerDocument(), OdfName.newName(OdfDocumentNamespace.TABLE, "table-column"));
- newColumn.setStyleName(columnStylename);
- mTableElement.insertBefore(newColumn, positonElement);
- } else { // has column, append a same column as the last one.
- TableTableColumnElement refColumn = columnList.get(columnList.size() - 1).getOdfElement();
- newColumn = (TableTableColumnElement) refColumn.cloneNode(true);
- String tableNameSpace = OdfDocumentNamespace.TABLE.getUri();
- newColumn.removeAttributeNS(tableNameSpace, "number-columns-repeated");
- mTableElement.insertBefore(newColumn, positonElement);
- }
-
- return getColumnInstance(newColumn, 0);
- }
-
- /**
- * Append a specific number of columns to the right of the table. The style
- * of new columns are same with the rightmost column in the table.
- * <p>
- * Since SIMPLE supports automatic table expansion. Whenever a cell outside
- * the current table is addressed the table is instantly expanded. Method
- * <code>getCellByPosition</code> can randomly access any cell, no matter it
- * in or out of the table original range.
- *
- * @param columnCount
- * is the number of columns to be appended.
- * @return a list of new appended columns
- * @see #appendColumn()
- * @see #getColumnByIndex(int)
- * @see #getCellByPosition(int, int)
- * @see #getCellByPosition(String)
- */
- public List<Column> appendColumns(int columnCount) {
- return appendColumns(columnCount, false);
- }
-
- List<Column> appendColumns(int columnCount, boolean isCleanStyle) {
- List<Column> resultList = new ArrayList<Column>();
- if (columnCount <= 0) {
- return resultList;
- }
- Column firstClm = appendColumn();
- resultList.add(firstClm);
- if (columnCount > 1) {
- List<Column> list = insertColumnsBefore((getColumnCount() - 1), (columnCount - 1));
- resultList.addAll(list);
- }
- // clean style name
- if (isCleanStyle) {
- for (Column column : resultList) {
- int length = column.getCellCount();
- for (int i = 0; i < length; i++) {
- TableTableCellElementBase cellElement = column.getCellByIndex(i).mCellElement;
- cellElement.removeAttributeNS(OdfDocumentNamespace.TABLE.getUri(), "style-name");
- }
- }
- }
- return resultList;
- }
-
- /**
- * This method is to insert a numbers of row
- */
- private List<Row> insertMultipleRowsBefore(Row refRow, Row positionRow, int count) {
- List<Row> resultList = new ArrayList<Row>();
- int j = 1;
-
- if (count <= 0) {
- return resultList;
- }
-
- Row firstRow = insertRowBefore(refRow, positionRow, getColumnCount());
- resultList.add(firstRow);
-
- if (count == 1) {
- return resultList;
- }
- TableTableRowElement rowEle = firstRow.getOdfElement();
- for (int i = 0; i < getColumnCount();) {
- Cell refCell = refRow.getCellByIndex(i);
- if (!refCell.isCoveredElement()) {
- int coveredHeigth = refCell.getRowSpannedNumber();
- if (coveredHeigth > 1) {
- refCell.setRowSpannedNumber(coveredHeigth + 1);
- }
- }
- i += refCell.getColumnsRepeatedNumber();
- }
- if (isUseRepeat()) {
- firstRow.setRowsRepeatedNumber(count);
- while (j < count) {
- resultList.add(getRowInstance(rowEle, j));
- j++;
- }
- } else {
- while (j < count) {
- TableTableRowElement newRowEle = (TableTableRowElement) rowEle.cloneNode(true);
- newRowEle.removeAttributeNS(OdfDocumentNamespace.TABLE.getUri(), "number-rows-repeated");
- mTableElement.insertBefore(newRowEle, positionRow.getOdfElement());
- resultList.add(getRowInstance(newRowEle, 0));
- j++;
- }
- }
- return resultList;
- }
-
- // only insert one Row
- private Row insertRowBefore(Row refRow, Row positionRow, int columnCount) {
- TableTableRowElement aRow = (TableTableRowElement) OdfXMLFactory.newOdfElement((OdfFileDom) mTableElement
- .getOwnerDocument(), OdfName.newName(OdfDocumentNamespace.TABLE, "table-row"));
- int coveredLength = 0, coveredHeigth = 0;
- for (int i = 0; i < columnCount;) {
- Cell refCell = refRow.getCellByIndex(i);
- int columnsRepeatedNumber = refCell.getColumnsRepeatedNumber();
- if (!refCell.isCoveredElement()) // not cover element
- {
- TableTableCellElement aCellEle = (TableTableCellElement) refCell.getOdfElement();
- coveredHeigth = aCellEle.getTableNumberRowsSpannedAttribute();
- if (coveredHeigth == 1) {
- TableTableCellElement newCellEle = (TableTableCellElement) aCellEle.cloneNode(true);
- cleanCell(newCellEle);
- aRow.appendChild(newCellEle);
- } else { // cover more rows
- aCellEle.setTableNumberRowsSpannedAttribute(coveredHeigth + 1);
- TableCoveredTableCellElement newCellEle = (TableCoveredTableCellElement) OdfXMLFactory
- .newOdfElement((OdfFileDom) mTableElement.getOwnerDocument(), OdfName.newName(
- OdfDocumentNamespace.TABLE, "covered-table-cell"));
- if (columnsRepeatedNumber > 1) {
- newCellEle.setTableNumberColumnsRepeatedAttribute(columnsRepeatedNumber);
- } else {
- newCellEle.removeAttributeNS(OdfDocumentNamespace.TABLE.getUri(), "number-columns-repeated");
- }
- aRow.appendChild(newCellEle);
- }
-
- coveredLength = aCellEle.getTableNumberColumnsSpannedAttribute() - columnsRepeatedNumber;
- i = i + columnsRepeatedNumber;
- } else {
- TableCoveredTableCellElement aCellEle = (TableCoveredTableCellElement) refCell.getOdfElement();
- if (coveredLength >= 1) {
- TableCoveredTableCellElement newCellEle = (TableCoveredTableCellElement) aCellEle.cloneNode(true);
- aRow.appendChild(newCellEle);
- coveredLength -= newCellEle.getTableNumberColumnsRepeatedAttribute();
- } else {
- TableTableCellElement coveredCell = (TableTableCellElement) refCell.getCoverCell().getOdfElement();
- TableTableCellElement newCellEle = (TableTableCellElement) coveredCell.cloneNode(true);
- cleanCell(newCellEle);
- newCellEle.removeAttributeNS(OdfDocumentNamespace.TABLE.getUri(), "number-rows-spanned");
- aRow.appendChild(newCellEle);
- coveredLength = coveredCell.getTableNumberColumnsSpannedAttribute() - columnsRepeatedNumber;
- }
- i = i + columnsRepeatedNumber;
- }
- }
- if (positionRow == null) {
- mTableElement.appendChild(aRow);
- } else {
- mTableElement.insertBefore(aRow, positionRow.getOdfElement());
- }
-
- return getRowInstance(aRow, 0);
- }
-
- void cleanCell(TableTableCellElementBase newCellEle) {
- String officeNameSpaceURI = OdfDocumentNamespace.OFFICE.getUri();
- String tableNameSpaceURI = OdfDocumentNamespace.TABLE.getUri();
- newCellEle.removeAttributeNS(officeNameSpaceURI, "value");
- newCellEle.removeAttributeNS(officeNameSpaceURI, "date-value");
- newCellEle.removeAttributeNS(officeNameSpaceURI, "time-value");
- newCellEle.removeAttributeNS(officeNameSpaceURI, "boolean-value");
- newCellEle.removeAttributeNS(officeNameSpaceURI, "string-value");
- newCellEle.removeAttributeNS(tableNameSpaceURI, "formula");
- newCellEle.removeAttributeNS(officeNameSpaceURI, "value-type");
- if (!isCellStyleInheritance()) {
- newCellEle.removeAttributeNS(tableNameSpaceURI, "style-name");
- }
- Node n = newCellEle.getFirstChild();
- while (n != null) {
- Node m = n.getNextSibling();
- if (n instanceof TextPElement || n instanceof TextHElement || n instanceof TextListElement
- || n instanceof OfficeAnnotationElement) {
- newCellEle.removeChild(n);
- }
- n = m;
- }
- }
-
- /**
- * Return an instance of <code>TableTableElement</code> which represents
- * this feature.
- *
- * @return an instance of <code>TableTableElement</code>
- */
- public TableTableElement getOdfElement() {
- return mTableElement;
- }
-
- /**
- * Insert a specific number of columns before the column whose index is
- * <code>index</code>.
- *
- * @param index
- * is the index of the column to insert before.
- * @param columnCount
- * is the number of columns to insert.
- * @return a list of new inserted columns
- */
- public List<Column> insertColumnsBefore(int index, int columnCount) {
- Column refColumn, positionCol;
- String tableNameSpace = OdfDocumentNamespace.TABLE.getUri();
- ArrayList<Column> list = new ArrayList<Column>();
- int columncount = getColumnCount();
-
- if (index >= columncount) {
- throw new IndexOutOfBoundsException();
- }
-
- if (index == 0) {
- int iRowCount = getRowCount();
- for (int i = 0; i < iRowCount; i++) {
- Row row = getRowByIndex(i);
- row.insertCellByIndex(index, columnCount);
- }
- refColumn = getColumnByIndex(index);
- positionCol = refColumn;
- // add a single column element to describe columns.
- if (isUseRepeat()) {
- TableTableColumnElement newColumnEle = (TableTableColumnElement) refColumn.getOdfElement().cloneNode(
- true);
- if (columnCount > 1) {
- newColumnEle.setTableNumberColumnsRepeatedAttribute(columnCount);
- } else {
- newColumnEle.removeAttributeNS(tableNameSpace, "number-columns-repeated");
- }
- mTableElement.insertBefore(newColumnEle, positionCol.getOdfElement());
- for (int i = 0; i < columnCount; i++) {
- list.add(getColumnInstance(newColumnEle, i));
- }
- } else {
- for (int i = 0; i < columnCount; i++) {
- TableTableColumnElement newColumnEle = (TableTableColumnElement) refColumn.getOdfElement()
- .cloneNode(true);
- mTableElement.insertBefore(newColumnEle, positionCol.getOdfElement());
- newColumnEle.removeAttributeNS(tableNameSpace, "number-columns-repeated");
- list.add(getColumnInstance(newColumnEle, 0));
- }
- }
- return list;
- }
-
- // 1. insert the cell
- int iRowCount = getRowCount();
- for (int i = iRowCount - 1; i >= 0;) {
- Row row = getRowByIndex(i);
- Cell refCell = row.getCellByIndex(index - 1);
- Cell positionCell = null;
- positionCell = row.getCellByIndex(index);
- row.insertCellBefore(refCell, positionCell, columnCount);
- i = i - row.getRowsRepeatedNumber();
- }
-
- refColumn = getColumnByIndex(index - 1);
- positionCol = getColumnByIndex(index);
- // 2. insert a <table:table-column>
- if (refColumn.getOdfElement() == positionCol.getOdfElement()) {
- TableTableColumnElement column = refColumn.getOdfElement();
- int repeatedCount = column.getTableNumberColumnsRepeatedAttribute();
- TableTableColumnElement columnEle = positionCol.getOdfElement();
- // add a single column element to describe columns.
- if (isUseRepeat()) {
- column.setTableNumberColumnsRepeatedAttribute(repeatedCount + columnCount);
- Column startCol = getColumnInstance(positionCol.getOdfElement(), 0);
- for (int i = repeatedCount + columnCount - 1; i >= columnCount + (index - startCol.getColumnIndex()); i--) {
- updateColumnRepository(columnEle, i - columnCount, columnEle, i);
- }
- for (int i = 0; i < columnCount; i++) {
- list.add(getColumnInstance(column, refColumn.mnRepeatedIndex + 1 + i));
- }
- } else {
- TableTableColumnElement newBeforeColumnEle = (TableTableColumnElement) refColumn.getOdfElement()
- .cloneNode(true);
- if (index > 1) {
- newBeforeColumnEle.setTableNumberColumnsRepeatedAttribute(index);
- } else {
- newBeforeColumnEle.removeAttributeNS(tableNameSpace, "number-columns-repeated");
- }
- mTableElement.insertBefore(newBeforeColumnEle, positionCol.getOdfElement());
- for (int i = 0; i < index; i++) {
- updateColumnRepository(columnEle, i, newBeforeColumnEle, i);
- }
- int newAfterCount = repeatedCount - index;
- if (newAfterCount > 1) {
- positionCol.setColumnsRepeatedNumber(newAfterCount);
- } else {
- positionCol.getOdfElement().removeAttributeNS(tableNameSpace, "number-columns-repeated");
- }
- for (int i = repeatedCount - 1; i >= index; i--) {
- updateColumnRepository(columnEle, i, columnEle, i - index);
- }
- for (int i = 0; i < columnCount; i++) {
- TableTableColumnElement newColumnEle = (TableTableColumnElement) refColumn.getOdfElement()
- .cloneNode(true);
- newColumnEle.removeAttributeNS(tableNameSpace, "number-columns-repeated");
- mTableElement.insertBefore(newColumnEle, positionCol.getOdfElement());
- list.add(getColumnInstance(newColumnEle, 0));
- }
- }
- } else {
- // add a single column element to describe columns.
- if (isUseRepeat()) {
- TableTableColumnElement newColumnEle = (TableTableColumnElement) refColumn.getOdfElement().cloneNode(
- true);
- if (columnCount > 1) {
- newColumnEle.setTableNumberColumnsRepeatedAttribute(columnCount);
- } else {
- newColumnEle.removeAttributeNS(tableNameSpace, "number-columns-repeated");
- }
- mTableElement.insertBefore(newColumnEle, positionCol.getOdfElement());
- for (int i = 0; i < columnCount; i++) {
- list.add(getColumnInstance(newColumnEle, i));
- }
- } else {
- for (int i = 0; i < columnCount; i++) {
- TableTableColumnElement newColumnEle = (TableTableColumnElement) refColumn.getOdfElement()
- .cloneNode(true);
- newColumnEle.removeAttributeNS(tableNameSpace, "number-columns-repeated");
- mTableElement.insertBefore(newColumnEle, positionCol.getOdfElement());
- list.add(getColumnInstance(newColumnEle, 0));
- }
- }
- }
- return list;
- }
-
- /**
- * Remove a specific number of columns, starting from the column at
- * <code>index</code>.
- *
- * @param startIndex
- * is the index of the first column to delete.
- * @param deleteColCount
- * is the number of columns to delete.
- */
- public void removeColumnsByIndex(int startIndex, int deleteColCount) {
- // 0. verify the index
- if (deleteColCount <= 0) {
- return;
- }
- if (startIndex < 0) {
- throw new IllegalArgumentException("startIndex of the deleted columns should not be negative");
- }
- int colCount = getColumnCount();
- if (startIndex >= colCount) {
- throw new IndexOutOfBoundsException("Start column index is out of bound");
- }
- if (startIndex + deleteColCount >= colCount) {
- deleteColCount = colCount - startIndex;
- }
-
- // 1. remove cell
- for (int i = 0; i < getRowCount(); i++) {
- Row aRow = getRowByIndex(i);
- aRow.removeCellByIndex(startIndex, deleteColCount);
- }
-
- // 2. remove column
- Column firstColumn;
- for (int i = 0; i < deleteColCount; i++) {
- firstColumn = getColumnByIndex(startIndex);
- int repeatedAttr = firstColumn.getColumnsRepeatedNumber();
- if (repeatedAttr == 1) {
- TableTableColumnElement columnEle = OdfElement.findNextChildNode(TableTableColumnElement.class,
- firstColumn.getOdfElement());
- mTableElement.removeChild(firstColumn.getOdfElement());
- if (i < (deleteColCount - 1)) {
- firstColumn = this.getColumnInstance(columnEle, 0);
- }
- } else {
- if (repeatedAttr > firstColumn.mnRepeatedIndex) {
- firstColumn.setColumnsRepeatedNumber(repeatedAttr - 1);
- Column startCol = this.getColumnInstance(firstColumn.getOdfElement(), 0);
- updateColumnRepository(firstColumn.getOdfElement(), startIndex - startCol.getColumnIndex(), null, 0);
- }
- }
- }
-
- }
-
- /**
- * Calculates the width between the left and right margins of the table
- * container.
- *
- * @param container
- * TableContainer
- * @param marginLeft
- * space between left margin and the table
- * @param marginRight
- * space between right margin and the table
- * @return width that can be attributed at the table (in)
- */
- private static double getTableWidth(TableContainer container, double marginLeft, double marginRight) {
- String pageWidthStr = null;
- double pageWidth = 0;
- double tableWidth = DEFAULT_TABLE_WIDTH;
- OdfOfficeAutomaticStyles automaticStyles = null;
- try {
- automaticStyles = getOwnerDocument(container).getStylesDom().getAutomaticStyles();
- } catch (Exception e) {
- Logger.getLogger(Table.class.getName()).log(Level.SEVERE, e.getMessage(), e);
- }
- OdfStylePageLayout pageLayout = automaticStyles.getPageLayout("pm1");
- if (pageLayout == null) {
- pageLayout = automaticStyles.getPageLayout("Mpm1");
- }
- if (pageLayout != null) {
- pageWidthStr = pageLayout.getProperty(StylePageLayoutPropertiesElement.PageWidth);
- if (pageWidthStr != null) {
- pageWidth = Length.parseDouble(pageWidthStr, Unit.CENTIMETER);
- }
- // margins
- double dLeftPageMargin = 0;
- double dRightPageMargin = 0;
- String leftPageMargin = pageLayout.getProperty(StylePageLayoutPropertiesElement.MarginLeft);
- String rightPageMargin = pageLayout.getProperty(StylePageLayoutPropertiesElement.MarginRight);
- if (leftPageMargin != null && rightPageMargin != null) {
- dLeftPageMargin = Length.parseDouble(leftPageMargin, Unit.CENTIMETER);
- dRightPageMargin = Length.parseDouble(rightPageMargin, Unit.CENTIMETER);
- }
- tableWidth = (pageWidth - (dLeftPageMargin + dRightPageMargin + marginLeft + marginRight)) / 2.5399;
- if (tableWidth <= 0) {
- tableWidth = DEFAULT_TABLE_WIDTH;
- }
- }
- return Double.valueOf(new DecimalFormat("#0.###").format(tableWidth).replace(",", ".")).doubleValue();
- }
-
- private void reviseStyleFromTopRowToMediumRow(Row oldTopRow) {
- if (mIsSpreadsheet)
- return;
- int length = getColumnCount();
-
- for (int i = 0; i < length;) {
- Cell cell = oldTopRow.getCellByIndex(i);
- if (cell.isCoveredElement()) {
- i = i + cell.getColumnsRepeatedNumber();
- continue;
- }
- OdfStyle styleEle = cell.getStyleHandler().getStyleElementForWrite();
- if (i < length - 1) {
- setLeftBottomBorderStylesProperties(styleEle);
- } else {
- setRightBottomBorderStylesProperties(styleEle);
- }
- i = i + cell.getColumnsRepeatedNumber();
- }
- }
-
- private void reviseStyleFromMediumRowToTopRow(Row newTopRow) {
- if (mIsSpreadsheet) {
- return;
- }
- int length = getColumnCount();
-
- for (int i = 0; i < length;) {
- Cell cell = newTopRow.getCellByIndex(i);
- if (cell.isCoveredElement()) {
- i = i + cell.getColumnsRepeatedNumber();
- continue;
- }
- OdfStyle styleEle = cell.getStyleHandler().getStyleElementForWrite();
- if (i < length - 1) {
- setLeftTopBorderStyleProperties(styleEle);
- } else {
- setRightTopBorderStyleProperties(styleEle);
- }
- i = i + cell.getColumnsRepeatedNumber();
- }
- }
-
- /**
- * Insert a specific number of rows before the row at <code>index</code>.
- *
- * @param index
- * is the index of the row to insert before.
- * @param rowCount
- * is the number of rows to insert.
- * @return a list of new inserted rows
- */
- public List<Row> insertRowsBefore(int index, int rowCount) {
- if (index >= getRowCount()) {
- throw new IndexOutOfBoundsException();
- }
- ArrayList<Row> list = new ArrayList<Row>();
- if (index == 0) {
- Row refRow = getRowByIndex(index);
- Row positionRow = refRow;
- // add first row
- Row newFirstRow = insertRowBefore(refRow, positionRow, getColumnCount());
- reviseStyleFromTopRowToMediumRow(refRow);
- list.add(newFirstRow);
- List<Row> rowList = insertMultipleRowsBefore(refRow, refRow, rowCount - 1);
- for (int i = 0; i < rowList.size(); i++) {
- list.add(rowList.get(i));
- }
- return list;
- }
-
- Row refRow = getRowByIndex(index - 1);
- Row positionRow = getRowByIndex(index);
- // 1. insert a <table:table-row>
- if (refRow.getOdfElement() == positionRow.getOdfElement()) {
- TableTableRowElement row = refRow.getOdfElement();
- int repeatedCount = refRow.getRowsRepeatedNumber();
- refRow.setRowsRepeatedNumber(repeatedCount + rowCount);
- TableTableRowElement rowEle = positionRow.getOdfElement();
- Row startRow = getRowInstance(positionRow.getOdfElement(), 0);
- for (int i = repeatedCount + rowCount - 1; i >= rowCount + (index - startRow.getRowIndex()); i--) {
- updateRowRepository(rowEle, i - rowCount, rowEle, i);
- }
- for (int i = 0; i < rowCount; i++) {
- list.add(getRowInstance(row, refRow.mnRepeatedIndex + 1 + i));
- }
- } else {
- List<Row> newRowList = insertMultipleRowsBefore(refRow, positionRow, rowCount);
- if (index - 1 == 0) {
- // correct styles
- reviseStyleFromTopRowToMediumRow(newRowList.get(0));
- }
- for (int i = 0; i < newRowList.size(); i++) {
- list.add(newRowList.get(i));
- }
- }
-
- return list;
- }
-
- /**
- * Return a list of columns in the current table.
- *
- * @return a list of table columns
- */
- public List<Column> getColumnList() {
- ArrayList<Column> list = new ArrayList<Column>();
- TableTableColumnElement colEle = null;
- for (Node n : new DomNodeList(mTableElement.getChildNodes())) {
- if (n instanceof TableTableHeaderColumnsElement) {
- TableTableHeaderColumnsElement headers = (TableTableHeaderColumnsElement) n;
- for (Node m : new DomNodeList(headers.getChildNodes())) {
- if (m instanceof TableTableColumnElement) {
- colEle = (TableTableColumnElement) m;
- int columnsRepeatedNumber = colEle.getTableNumberColumnsRepeatedAttribute();
- for (int i = 0; i < columnsRepeatedNumber; i++) {
- list.add(getColumnInstance(colEle, i));
- }
- }
- }
- }
- if (n instanceof TableTableColumnElement) {
- colEle = (TableTableColumnElement) n;
- int columnsRepeatedNumber = colEle.getTableNumberColumnsRepeatedAttribute();
[... 4742 lines stripped ...]