All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.odftoolkit.odfdom.doc.table.OdfTableRow Maven / Gradle / Ivy

/************************************************************************
* 
*  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.odfdom.doc.table;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.xpath.XPath;

import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;

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.doc.OdfDocument;
import org.odftoolkit.odfdom.dom.OdfContentDom;
import org.odftoolkit.odfdom.dom.OdfDocumentNamespace;
import org.odftoolkit.odfdom.dom.element.table.TableCoveredTableCellElement;
import org.odftoolkit.odfdom.dom.element.table.TableTableCellElement;
import org.odftoolkit.odfdom.dom.element.table.TableTableCellElementBase;
import org.odftoolkit.odfdom.dom.element.table.TableTableElement;
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.OdfTableRowProperties;
import org.odftoolkit.odfdom.incubator.doc.style.OdfStyle;
import org.odftoolkit.odfdom.type.PositiveLength;
import org.odftoolkit.odfdom.type.Length.Unit;
import org.w3c.dom.Node;

/**
 * OdfTableRow represents table row feature in ODF document.
 * 

* OdfTableRow provides methods to get table cells that belong to this table row. * * @deprecated As of release 0.8.8, replaced by {@link org.odftoolkit.simple.table.Row} in Simple API. */ public class OdfTableRow { //boolean mbVisible; TableTableRowElement maRowElement; int mnRepeatedIndex; int mRowsRepeatedNumber = -1; private static final String DEFAULT_HEIGHT = "0.30in"; private OdfDocument mDocument; /** * Construct the OdfTableRow feature. * @param rowElement the row element represent this row * @param repeatedIndex the index in the repeated rows */ OdfTableRow(TableTableRowElement rowElement, int repeatedIndex) { maRowElement = rowElement; mnRepeatedIndex = repeatedIndex; mDocument = (OdfDocument) ((OdfFileDom) maRowElement.getOwnerDocument()).getDocument(); } /** * Get the OdfTableRow instance from the TableTableRowElement instance. *

* Each TableTableRowElement instance has a one-to-one relationship to a OdfTableRow instance. * * @param rowElement the row element that need to get the corresponding OdfTableRow instance * @return the OdfTableRow instance represent the specified row element */ public static OdfTableRow getInstance(TableTableRowElement rowElement) { TableTableElement tableElement = null; Node node = rowElement.getParentNode(); while (node != null) { if (node instanceof TableTableElement) { tableElement = (TableTableElement) node; } node = node.getParentNode(); } OdfTable table = null; if (tableElement != null) { table = OdfTable.getInstance(tableElement); } else { throw new IllegalArgumentException("the rowElement is not in the table dom tree"); } OdfTableRow row = table.getRowInstance(rowElement, 0); if (row.getRowsRepeatedNumber() > 1) { Logger.getLogger(OdfTableRow.class.getName()).log(Level.WARNING, "the row has the repeated row number, and puzzled about get which repeated index of the row," + "here just return the first row of the repeated rows."); } return row; } /** * Get the TableTableElement who contains this row. * * @return the table element that contains the row. */ private TableTableElement getTableElement() { Node node = maRowElement.getParentNode(); while (node != null) { if (node instanceof TableTableElement) { return (TableTableElement) node; } node = node.getParentNode(); } return null; } /** * Get owner table of the current row. * @return the parent table of this row */ public OdfTable getTable() { TableTableElement tableElement = getTableElement(); if (tableElement != null) { return OdfTable.getInstance(tableElement); } return null; } /** * Return the height of the row (in Millimeter). *

* Return the minimal height, if the row height is not set, * @return the height of the current row (in Millimeter). */ public long getHeight() { String sHeight = maRowElement.getProperty(OdfTableRowProperties.RowHeight); if (sHeight == null) { sHeight = maRowElement.getProperty(OdfTableRowProperties.MinRowHeight); } if (sHeight == null) { sHeight = DEFAULT_HEIGHT; } return PositiveLength.parseLong(sHeight, Unit.MILLIMETER); } /** * Set the height/minimal height of the row (in Millimeter) according to the second parameter. * @param height * the height/minimal height that will be set to the row (in Millimeter). * @param isMinHeight * if it is true, the row can fit the height to the text, vice versa. */ public void setHeight(long height, boolean isMinHeight) { String sHeightMM = String.valueOf(height) + Unit.MILLIMETER.abbr(); String sHeightIN = PositiveLength.mapToUnit(sHeightMM, Unit.INCH); splitRepeatedRows(); maRowElement.removeAttributeNS(OdfDocumentNamespace.TABLE.getUri(), "style-name"); maRowElement.setProperty(OdfTableRowProperties.RowHeight, sHeightIN); } //if one of the repeated row want to change something //then this repeated row have to split to repeated number rows //the maRowElement/mnRepeatedIndex should also be updated according to the original index in the repeated column void splitRepeatedRows() { int repeateNum = getRowsRepeatedNumber(); if (repeateNum > 1) { OdfTable table = getTable(); TableTableElement tableEle = table.getOdfElement(); //change this repeated row to several single rows TableTableRowElement ownerRowElement = null; int repeatedRowIndex = mnRepeatedIndex; Node refElement = maRowElement; Node oldRowElement = maRowElement; for (int i = repeateNum - 1; i >= 0; i--) { TableTableRowElement newRow = (TableTableRowElement) maRowElement.cloneNode(true); newRow.removeAttributeNS(OdfDocumentNamespace.TABLE.getUri(), "number-rows-repeated"); tableEle.insertBefore(newRow, refElement); refElement = newRow; if (repeatedRowIndex == i) { ownerRowElement = newRow; } else { table.updateRowRepository(maRowElement, i, newRow, 0); } } if (ownerRowElement != null) { table.updateRowRepository(maRowElement, mnRepeatedIndex, ownerRowElement, 0); } tableEle.removeChild(oldRowElement); mRowsRepeatedNumber = -1; } } /** * Return if the row always keeps its optimal height. * @return * true if the row always keeps its optimal height; * vice versa */ public boolean isOptimalHeight() { return Boolean.parseBoolean(maRowElement.getProperty(OdfTableRowProperties.UseOptimalRowHeight)); } /** * Set if the row always keeps its optimal height. * @param isUseOptimalHeight * the flag that indicate row should keep its optimal height or not */ public void setUseOptimalHeight(boolean isUseOptimalHeight) { maRowElement.setProperty(OdfTableRowProperties.UseOptimalRowHeight, String.valueOf(isUseOptimalHeight)); } /** * Return an instance of TableTableRowElement which represents this feature. * @return an instance of TableTableRowElement */ public TableTableRowElement getOdfElement() { return maRowElement; } /** * Get a cell with a specific index. The table will be automatically * expanded, when the given index is outside of the original table. * * @param index * the cell index in this row * @return the cell object in the given cell index */ public OdfTableCell getCellByIndex(int index) { OdfTable table = getTable(); if (index < 0) { throw new IllegalArgumentException("index should be nonnegative integer."); } // expand column as needed. int lastColumnIndex = table.getColumnCount() - 1; if (index > lastColumnIndex) { //need clean cell style. table.appendColumns((index - lastColumnIndex), true); } for (Node n : new DomNodeList(maRowElement.getChildNodes())) { if (n instanceof TableTableCellElementBase) { if (index == 0) { return table.getCellInstance((TableTableCellElementBase) n, 0, mnRepeatedIndex); } else { int nextIndex = index - ((TableTableCellElementBase) n).getTableNumberColumnsRepeatedAttribute().intValue(); if (nextIndex < 0) { OdfTableCell cell = table.getCellInstance( (TableTableCellElementBase) n, index, mnRepeatedIndex); return cell; } else { index = nextIndex; } } } } return null; } /** * Return the count of real cells in this row. * The cells covered by top cells are not counted. *

* Please note it might not equal to the column count of the owner table, * because some of them are the covered cells. * @return the cell count */ public int getCellCount() { OdfTable table = getTable(); Set realCells = new HashSet(); List coverList = table.getCellCoverInfos(0, 0, table.getColumnCount() - 1, table.getRowCount() - 1); int rowIndex = getRowIndex(); for (int i = 0; i < table.getColumnCount(); i++) { OdfTableCell cell = table.getOwnerCellByPosition(coverList, i, rowIndex); realCells.add(cell); } return realCells.size(); } /** * Return the previous row of the current row. * * @return the previous row before this row in the owner table */ public OdfTableRow getPreviousRow() { OdfTable table = getTable(); //the row has repeated row number > 1 if (getRowsRepeatedNumber() > 1) { if (mnRepeatedIndex > 0) { return table.getRowInstance(maRowElement, mnRepeatedIndex - 1); } } //the row has repeated row number > 1 && the index is 0 //or the row has repeated row num = 1 Node aPrevNode = maRowElement.getPreviousSibling(); Node aCurNode = maRowElement; TableTableRowElement lastRow; while (true) { if (aPrevNode == null) { //does not have previous sibling, then get the parent //because aCurNode might be the child element of table-header-rows, table-rows, table-row-group Node parentNode = aCurNode.getParentNode(); //if the parent is table, then it means that this row is the first row in this table //it has no previous row if (parentNode instanceof TableTableElement) { return null; } aPrevNode = parentNode.getPreviousSibling(); } //else the previous node might be table-header-rows, table-rows, table-row-group if (aPrevNode != null) { try { if (aPrevNode instanceof TableTableRowElement) { return table.getRowInstance((TableTableRowElement) aPrevNode, ((TableTableRowElement) aPrevNode).getTableNumberRowsRepeatedAttribute().intValue() - 1); } else if (aPrevNode instanceof TableTableRowsElement || aPrevNode instanceof TableTableHeaderRowsElement || aPrevNode instanceof TableTableRowGroupElement) { XPath xpath = ((OdfContentDom) aPrevNode.getOwnerDocument()).getXPath(); synchronized (mDocument) { lastRow = (TableTableRowElement) xpath.evaluate(".//table:table-row[last()]", aPrevNode, XPathConstants.NODE); } if (lastRow != null) { return table.getRowInstance(lastRow, lastRow.getTableNumberRowsRepeatedAttribute().intValue() - 1); } } else { aCurNode = aPrevNode; aPrevNode = aPrevNode.getPreviousSibling(); } } catch (XPathExpressionException e) { Logger.getLogger(OdfTableRow.class.getName()).log(Level.SEVERE, e.getMessage(), e); } } } } /** * Return the next row of the current row. * * @return the next row after this row in the owner table */ public OdfTableRow getNextRow() { OdfTable table = getTable(); //the row has repeated row number > 1 if (getRowsRepeatedNumber() > 1) { if (mnRepeatedIndex < (getRowsRepeatedNumber() - 1)) { return table.getRowInstance(maRowElement, mnRepeatedIndex + 1); } } Node aNextNode = maRowElement.getNextSibling(); Node aCurNode = maRowElement; TableTableRowElement firstRow; while (true) { if (aNextNode == null) { //does not have next sibling, then get the parent //because aCurNode might be the child element of table-header-rows, table-rows, table-row-group Node parentNode = aCurNode.getParentNode(); //if the parent is table, then it means that this row is the last row in this table //it has no next row if (parentNode instanceof TableTableElement) { return null; } aNextNode = parentNode.getNextSibling(); } //else the next node might be table-header-rows, table-rows, table-row-group if (aNextNode != null) { try { if (aNextNode instanceof TableTableRowElement) { return table.getRowInstance((TableTableRowElement) aNextNode, 0); } else if (aNextNode instanceof TableTableRowsElement || aNextNode instanceof TableTableHeaderRowsElement || aNextNode instanceof TableTableRowGroupElement) { XPath xpath = ((OdfContentDom) aNextNode.getOwnerDocument()).getXPath(); synchronized (mDocument) { firstRow = (TableTableRowElement) xpath.evaluate(".//table:table-row[first()]", aNextNode, XPathConstants.NODE); } if (firstRow != null) { return table.getRowInstance(firstRow, 0); } } else { aCurNode = aNextNode; aNextNode = aNextNode.getNextSibling(); } } catch (XPathExpressionException e) { Logger.getLogger(OdfTableRow.class.getName()).log(Level.SEVERE, e.getMessage(), e); } } } } /** * Set the default cell style to this row. *

* The style should already exist in this document. * @param style * the cell style of the document */ public void setDefaultCellStyle(OdfStyle style) { splitRepeatedRows(); OdfStyle defaultStyle = getDefaultCellStyle(); if (defaultStyle != null) { defaultStyle.removeStyleUser(maRowElement); } if (style != null) { style.addStyleUser(maRowElement); maRowElement.setTableDefaultCellStyleNameAttribute( style.getStyleNameAttribute()); } } /** * Get the default cell style of this row. * * @return the default cell style of this row */ public OdfStyle getDefaultCellStyle() { String styleName = maRowElement.getTableDefaultCellStyleNameAttribute(); OdfStyle style = maRowElement.getAutomaticStyles().getStyle( styleName, OdfStyleFamily.TableCell); if (style == null) { style = mDocument.getDocumentStyles().getStyle(styleName, OdfStyleFamily.TableCell); } return style; } /** * Return the index of this row in the owner table. * * @return the index of the row */ public int getRowIndex() { int result = 0; TableTableElement mTableElement = getTableElement(); 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; if (rowEle == getOdfElement()) { return result + mnRepeatedIndex; } result += rowEle.getTableNumberRowsRepeatedAttribute(); } } } if (n instanceof TableTableRowElement) { rowEle = (TableTableRowElement) n; if (rowEle == getOdfElement()) { break; } result += ((TableTableRowElement) n).getTableNumberRowsRepeatedAttribute(); } } return result + mnRepeatedIndex; } //insert count number of cell from index //this is called after insertColumn has been called by OdfTable void insertCellByIndex(int index, int count) { splitRepeatedRows(); //all insert the real cell OdfTable table = getTable(); List coverList = table.getCellCoverInfos(0, 0, table.getColumnCount() - 1, table.getRowCount() - 1); int rowIndex = getRowIndex(); OdfTableCell preCell; if (index == 0) { preCell = table.getOwnerCellByPosition(coverList, 0, rowIndex); } else { preCell = table.getOwnerCellByPosition(coverList, index - 1, rowIndex); } OdfTableCell nextCell = getCellByIndex(index); if (nextCell == null) { nextCell = getCellByIndex(getCellCount() - 1); } for (int i = index + count; i > index; i--) { TableTableCellElement newCell = (TableTableCellElement) OdfXMLFactory.newOdfElement((OdfFileDom) maRowElement.getOwnerDocument() , OdfName.newName(OdfDocumentNamespace.TABLE, "table-cell")); newCell.setTableStyleNameAttribute(preCell.getStyleName()); maRowElement.insertBefore(newCell, nextCell.getOdfElement()); } } //note: we have to use this method to modify the row repeated number //in order to update mnRepeatedIndex of the each row void setRowsRepeatedNumber(int num) { mRowsRepeatedNumber = num; //update the mnRepeatedIndex for the ever repeated row maRowElement.setTableNumberRowsRepeatedAttribute(Integer.valueOf(num)); } int getRowsRepeatedNumber() { if (mRowsRepeatedNumber < 0) { Integer count = maRowElement.getTableNumberRowsRepeatedAttribute(); if (count == null) { mRowsRepeatedNumber = 1; } else { mRowsRepeatedNumber = count.intValue(); } } return mRowsRepeatedNumber; } /**************************** * Moved from OdfTable * */ private void insertCellElementBefore(OdfElement parentEle, TableTableCellElementBase positionEle, TableTableCellElementBase cellEle, int count) { if (positionEle == null) { parentEle.appendChild(cellEle); for (int i = 1; i < count; i++) { parentEle.appendChild(cellEle.cloneNode(true)); } } else { parentEle.insertBefore(cellEle, positionEle); for (int i = 1; i < count; i++) { parentEle.insertBefore(cellEle.cloneNode(true), positionEle); } } } void insertCellBefore(OdfTableCell refCell, OdfTableCell positionCell, int count) { splitRepeatedRows(); OdfTable ownerTable = getTable(); if (positionCell == null) { if (refCell.isCoveredElement()) { TableTableCellElement coverCellEle = (TableTableCellElement) refCell.getCoverCell().getOdfElement(); TableTableCellElement newCellEle = (TableTableCellElement) coverCellEle.cloneNode(true); cleanCell(newCellEle); insertCellElementBefore(getOdfElement(), null, newCellEle, count); } else { TableTableCellElement endCellEle = (TableTableCellElement) refCell.getOdfElement().cloneNode(true); cleanCell(endCellEle); getOdfElement().appendChild(endCellEle); reviseStyleFromLastColumnToMedium(refCell); if (count > 1) { TableTableCellElement newCellEle = (TableTableCellElement) refCell.getOdfElement().cloneNode(true); cleanCell(newCellEle); insertCellElementBefore(getOdfElement(), endCellEle, newCellEle, count - 1); } } } else { TableTableCellElement coverRefCellEle = null; TableTableCellElement coverPosCellEle = null; OdfTableCell coverRefCell = null; if (refCell.isCoveredElement()) { //get ref cover cell coverRefCell = refCell.getCoverCell(); coverRefCellEle = (TableTableCellElement) coverRefCell.getOdfElement(); } if (positionCell.isCoveredElement()) //get position cover cell { coverPosCellEle = (TableTableCellElement) positionCell.getCoverCell().getOdfElement(); } if ((coverRefCellEle != null && coverRefCellEle == coverPosCellEle) //is cover cell and have the same cover cell || (coverPosCellEle != null && refCell.getOdfElement() == coverPosCellEle)) //position cell is cover cell and refer cell covers position cell { if (coverRefCellEle == null) { coverRefCellEle = (TableTableCellElement) refCell.getOdfElement(); coverRefCell = refCell; } TableCoveredTableCellElement newCellEle = (TableCoveredTableCellElement) OdfXMLFactory.newOdfElement( (OdfFileDom) ownerTable.getOdfElement().getOwnerDocument(), OdfName.newName(OdfDocumentNamespace.TABLE, "covered-table-cell")); insertCellElementBefore(getOdfElement(), positionCell.getOdfElement(), newCellEle, count); if (refCell.getRowIndex() == coverRefCell.getRowIndex()) //the first cover line { coverRefCell.setColumnSpannedNumber(coverRefCell.getColumnSpannedNumber() + count); } } else if (coverRefCellEle != null) //is cover cell { if (refCell.getRowIndex() == coverRefCell.getRowIndex()) { //the first cover line TableTableCellElement newCellEle = (TableTableCellElement) coverRefCellEle.cloneNode(true); cleanCell(newCellEle); insertCellElementBefore(getOdfElement(), positionCell.getOdfElement(), newCellEle, count); } else { //the second and other cover line TableCoveredTableCellElement newCellEle = (TableCoveredTableCellElement) refCell.getOdfElement().cloneNode(true); newCellEle.removeAttributeNS(OdfDocumentNamespace.TABLE.getUri(), "number-columns-repeated"); insertCellElementBefore(getOdfElement(), positionCell.getOdfElement(), newCellEle, count); } } else if ((refCell.getOdfElement() == positionCell.getOdfElement()) && (refCell.getColumnsRepeatedNumber() > 1)) //repeated number { int repeatNum = refCell.getColumnsRepeatedNumber(); //update the cell that after the ref cell for (int i = repeatNum - 1; i > refCell.mnRepeatedColIndex; i--) { ownerTable.updateCellRepository(refCell.getOdfElement(), i, refCell.mnRepeatedRowIndex, refCell.getOdfElement(), i + count, refCell.mnRepeatedRowIndex); } refCell.getOdfElement().setTableNumberColumnsRepeatedAttribute(repeatNum + count); } else { TableTableCellElement newCellEle = (TableTableCellElement) refCell.getOdfElement().cloneNode(true); cleanCell(newCellEle); insertCellElementBefore(getOdfElement(), positionCell.getOdfElement(), newCellEle, count); } } } /** * This method is to insert a cell same as refCell before positionCell. *

* This method is invoked by appendColumn and insertColumnBefore. */ OdfTableCell insertCellBefore(OdfTableCell refCell, OdfTableCell positionCell) { splitRepeatedRows(); OdfTableCell newCell = null; OdfTable ownerTable = getTable(); if (positionCell == null) { if (refCell.isCoveredElement()) { TableTableCellElement coverCellEle = (TableTableCellElement) refCell.getCoverCell().getOdfElement(); TableTableCellElement newCellEle = (TableTableCellElement) coverCellEle.cloneNode(true); cleanCell(newCellEle); getOdfElement().appendChild(newCellEle); newCell = ownerTable.getCellInstance(newCellEle, 0, 0); } else { TableTableCellElement newCellEle = (TableTableCellElement) refCell.getOdfElement().cloneNode(true); cleanCell(newCellEle); getOdfElement().appendChild(newCellEle); newCell = ownerTable.getCellInstance(newCellEle, 0, 0); reviseStyleFromLastColumnToMedium(refCell); } } else { TableTableCellElement coverRefCellEle = null; TableTableCellElement coverPosCellEle = null; OdfTableCell coverRefCell = null; if (refCell.isCoveredElement()) { //get ref cover cell coverRefCell = refCell.getCoverCell(); coverRefCellEle = (TableTableCellElement) coverRefCell.getOdfElement(); } if (positionCell.isCoveredElement()) //get position cover cell { coverPosCellEle = (TableTableCellElement) positionCell.getCoverCell().getOdfElement(); } if ((coverRefCellEle != null && coverRefCellEle == coverPosCellEle) //is cover cell and have the same cover cell || (coverPosCellEle != null && refCell.getOdfElement() == coverPosCellEle)) //position cell is cover cell and refer cell covers position cell { if (coverRefCellEle == null) { coverRefCellEle = (TableTableCellElement) refCell.getOdfElement(); coverRefCell = refCell; } TableCoveredTableCellElement newCellEle = (TableCoveredTableCellElement) OdfXMLFactory.newOdfElement( (OdfFileDom) ownerTable.getOdfElement().getOwnerDocument(), OdfName.newName(OdfDocumentNamespace.TABLE, "covered-table-cell")); getOdfElement().insertBefore(newCellEle, positionCell.getOdfElement()); if (refCell.getRowIndex() == coverRefCell.getRowIndex()) //the first cover line { coverRefCell.setColumnSpannedNumber(coverRefCell.getColumnSpannedNumber() + 1); } newCell = ownerTable.getCellInstance(newCellEle, 0, 0); } else if (coverRefCellEle != null) //is cover cell { if (refCell.getRowIndex() == coverRefCell.getRowIndex()) { //the first cover line TableTableCellElement newCellEle = (TableTableCellElement) coverRefCellEle.cloneNode(true); cleanCell(newCellEle); getOdfElement().insertBefore(newCellEle, positionCell.getOdfElement()); newCell = ownerTable.getCellInstance(newCellEle, 0, 0); } else { //the second and other cover line TableCoveredTableCellElement newCellEle = (TableCoveredTableCellElement) refCell.getOdfElement().cloneNode(true); newCellEle.removeAttributeNS(OdfDocumentNamespace.TABLE.getUri(), "number-columns-repeated"); getOdfElement().insertBefore(newCellEle, positionCell.getOdfElement()); newCell = ownerTable.getCellInstance(newCellEle, 0, 0); } } else if ((refCell.getOdfElement() == positionCell.getOdfElement()) && (refCell.getColumnsRepeatedNumber() > 1)) //repeated number { int repeatNum = refCell.getColumnsRepeatedNumber(); //update the cell that after the ref cell for (int i = repeatNum - 1; i > refCell.mnRepeatedColIndex; i--) { ownerTable.updateCellRepository(refCell.getOdfElement(), i, refCell.mnRepeatedRowIndex, refCell.getOdfElement(), i + 1, refCell.mnRepeatedRowIndex); } refCell.getOdfElement().setTableNumberColumnsRepeatedAttribute(repeatNum + 1); newCell = ownerTable.getCellInstance(refCell.getOdfElement(), refCell.mnRepeatedColIndex + 1, refCell.mnRepeatedRowIndex); } else { TableTableCellElement newCellEle = (TableTableCellElement) refCell.getOdfElement().cloneNode(true); cleanCell(newCellEle); getOdfElement().insertBefore(newCellEle, positionCell.getOdfElement()); newCell = ownerTable.getCellInstance(newCellEle, 0, 0); } } return newCell; } private void cleanCell(TableTableCellElement newCellEle) { newCellEle.removeAttributeNS(OdfDocumentNamespace.OFFICE.getUri(), "value"); newCellEle.removeAttributeNS(OdfDocumentNamespace.OFFICE.getUri(), "date-value"); newCellEle.removeAttributeNS(OdfDocumentNamespace.OFFICE.getUri(), "time-value"); newCellEle.removeAttributeNS(OdfDocumentNamespace.OFFICE.getUri(), "boolean-value"); newCellEle.removeAttributeNS(OdfDocumentNamespace.OFFICE.getUri(), "string-value"); newCellEle.removeAttributeNS(OdfDocumentNamespace.TABLE.getUri(), "formula"); newCellEle.removeAttributeNS(OdfDocumentNamespace.TABLE.getUri(), "number-columns-repeated"); newCellEle.removeAttributeNS(OdfDocumentNamespace.TABLE.getUri(), "number-columns-spanned"); if(!getTable().isCellStyleInheritance()){ newCellEle.removeAttributeNS(OdfDocumentNamespace.TABLE.getUri(), "style-name"); } Node n = newCellEle.getFirstChild(); while (n != null) { Node m = n.getNextSibling(); if (n instanceof TextPElement || n instanceof TextHElement || n instanceof TextListElement) { newCellEle.removeChild(n); } n = m; } } private void reviseStyleFromLastColumnToMedium(OdfTableCell oldLastCell) { if (getTable().mIsSpreadsheet) return; OdfStyle styleEle = oldLastCell.getCellStyleElementForWrite(); if (styleEle != null) { if (oldLastCell.getRowIndex() == 0) { OdfTable.setLeftTopBorderStyleProperties(styleEle); } else { OdfTable.setLeftBottomBorderStylesProperties(styleEle); } } } private void reviseStyleFromMediumColumnToLast(OdfTableCell newLastCell) { if (getTable().mIsSpreadsheet) return; OdfStyle styleEle = newLastCell.getCellStyleElementForWrite(); if (styleEle != null) { if (newLastCell.getRowIndex() == 0) { OdfTable.setRightTopBorderStyleProperties(styleEle); } else { OdfTable.setRightBottomBorderStylesProperties(styleEle); } } } /** * This method is invoked by removeColumnByIndex * So we don't need to care about * the covered and spanned cell in a same column */ void removeCellByIndex(int nStart, int nCount) { splitRepeatedRows(); OdfTableCell startCell = getCellByIndex(nStart); OdfTableCell coverCell = null; if (startCell.isCoveredElement()) { coverCell = startCell.getCoverCellInSameRow(); } int index = nStart; for (int i = 0; i < nCount; i++) { OdfTableCell cell = getCellByIndex(index); cell.splitRepeatedCells(); if (cell.isCoveredElement() && coverCell != null) { coverCell.setColumnSpannedNumber(coverCell.getColumnSpannedNumber() - cell.getColumnsRepeatedNumber()); maRowElement.removeChild(cell.getOdfElement()); i += cell.getColumnsRepeatedNumber() - 1; } else if (cell.isCoveredElement()) { maRowElement.removeChild(cell.getOdfElement()); i += cell.getColumnsRepeatedNumber() - 1; } else if (!cell.isCoveredElement()) { if (i + cell.getColumnSpannedNumber() <= nCount) { maRowElement.removeChild(cell.getOdfElement()); i += cell.getColumnSpannedNumber() - 1; } else { removeCellByIndex(index + 1, nCount - i); } } } int clmnum = getTable().getColumnCount(); if (nStart + nCount >= clmnum) { OdfTableCell cell = getCellByIndex(nStart - 1); reviseStyleFromMediumColumnToLast(cell); } } void removeAllCellsRelationship() { OdfTable table = getTable(); for (int i = 0; i < table.getColumnCount();) { OdfTableCell cell = getCellByIndex(i); if (cell.isCoveredElement()) //cell is a cover cell { OdfTableCell coverCell = cell.getCoverCellInSameColumn(); if (coverCell != null) { coverCell.setRowSpannedNumber(coverCell.getRowSpannedNumber() - getRowsRepeatedNumber()); } getOdfElement().removeChild(cell.getOdfElement()); } else { if (cell.getRowSpannedNumber() > 1) //cell is not a cover cell, and it span more rows { //split the cell under this cell to a single cell OdfTableRow nextRow = table.getRowByIndex(getRowIndex() + 1); if (nextRow.getRowsRepeatedNumber() > 1) { nextRow.splitRepeatedRows(); } OdfTableCell coveredCell = table.getCellByPosition(cell.getColumnIndex(), getRowIndex() + 1); if (coveredCell.getColumnsRepeatedNumber() > 1) { coveredCell.splitRepeatedCells(); coveredCell = table.getCellByPosition(cell.getColumnIndex(), getRowIndex() + 1); } //create a new cell TableTableCellElement newCellEle = (TableTableCellElement) cell.getOdfElement().cloneNode(true); newCellEle.setTableNumberRowsSpannedAttribute(cell.getRowSpannedNumber() - getRowsRepeatedNumber()); //update repository int startRow = coveredCell.getRowIndex(); int endRow = coveredCell.getRowIndex() + newCellEle.getTableNumberRowsSpannedAttribute(); int startClm = coveredCell.getColumnIndex(); int endClm = coveredCell.getColumnIndex() + newCellEle.getTableNumberColumnsSpannedAttribute() * newCellEle.getTableNumberColumnsRepeatedAttribute(); coveredCell.getOdfElement().getParentNode().replaceChild(newCellEle, coveredCell.getOdfElement()); table.updateRepositoryWhenCellElementChanged(startRow, endRow, startClm, endClm, newCellEle); } } i += cell.getColumnSpannedNumber(); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy