| /* ==================================================================== |
| 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.apache.poi.xwpf.usermodel; |
| |
| import java.math.BigInteger; |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.apache.poi.util.Internal; |
| import org.apache.poi.xwpf.model.WMLHelper; |
| import org.apache.xmlbeans.XmlCursor; |
| import org.apache.xmlbeans.XmlObject; |
| import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHeight; |
| import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTOnOff; |
| import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow; |
| import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtCell; |
| import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc; |
| import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTrPr; |
| |
| |
| /** |
| * A row within an {@link XWPFTable}. Rows mostly just have |
| * sizings and stylings, the interesting content lives inside |
| * the child {@link XWPFTableCell}s |
| */ |
| public class XWPFTableRow { |
| private CTRow ctRow; |
| private XWPFTable table; |
| private List<XWPFTableCell> tableCells; |
| |
| public XWPFTableRow(CTRow row, XWPFTable table) { |
| this.table = table; |
| this.ctRow = row; |
| getTableCells(); |
| } |
| |
| @Internal |
| public CTRow getCtRow() { |
| return ctRow; |
| } |
| |
| /** |
| * create a new XWPFTableCell and add it to the tableCell-list of this tableRow |
| * |
| * @return the newly created XWPFTableCell |
| */ |
| public XWPFTableCell createCell() { |
| XWPFTableCell tableCell = new XWPFTableCell(ctRow.addNewTc(), this, table.getBody()); |
| tableCells.add(tableCell); |
| return tableCell; |
| } |
| |
| public XWPFTableCell getCell(int pos) { |
| if (pos >= 0 && pos < ctRow.sizeOfTcArray()) { |
| return getTableCells().get(pos); |
| } |
| return null; |
| } |
| |
| public void removeCell(int pos) { |
| if (pos >= 0 && pos < ctRow.sizeOfTcArray()) { |
| tableCells.remove(pos); |
| } |
| } |
| |
| /** |
| * adds a new TableCell at the end of this tableRow |
| */ |
| public XWPFTableCell addNewTableCell() { |
| CTTc cell = ctRow.addNewTc(); |
| XWPFTableCell tableCell = new XWPFTableCell(cell, this, table.getBody()); |
| tableCells.add(tableCell); |
| return tableCell; |
| } |
| |
| /** |
| * This element specifies the height of the current table row within the |
| * current table. This height shall be used to determine the resulting |
| * height of the table row, which may be absolute or relative (depending on |
| * its attribute values). If omitted, then the table row shall automatically |
| * resize its height to the height required by its contents (the equivalent |
| * of an hRule value of auto). |
| * |
| * @return height |
| */ |
| public int getHeight() { |
| CTTrPr properties = getTrPr(); |
| return properties.sizeOfTrHeightArray() == 0 ? 0 : properties.getTrHeightArray(0).getVal().intValue(); |
| } |
| |
| /** |
| * This element specifies the height of the current table row within the |
| * current table. This height shall be used to determine the resulting |
| * height of the table row, which may be absolute or relative (depending on |
| * its attribute values). If omitted, then the table row shall automatically |
| * resize its height to the height required by its contents (the equivalent |
| * of an hRule value of auto). |
| * |
| * @param height |
| */ |
| public void setHeight(int height) { |
| CTTrPr properties = getTrPr(); |
| CTHeight h = properties.sizeOfTrHeightArray() == 0 ? properties.addNewTrHeight() : properties.getTrHeightArray(0); |
| h.setVal(new BigInteger("" + height)); |
| } |
| |
| private CTTrPr getTrPr() { |
| return (ctRow.isSetTrPr()) ? ctRow.getTrPr() : ctRow.addNewTrPr(); |
| } |
| |
| public XWPFTable getTable() { |
| return table; |
| } |
| |
| /** |
| * create and return a list of all XWPFTableCell |
| * who belongs to this row |
| * |
| * @return a list of {@link XWPFTableCell} |
| */ |
| public List<ICell> getTableICells() { |
| |
| List<ICell> cells = new ArrayList<ICell>(); |
| //Can't use ctRow.getTcList because that only gets table cells |
| //Can't use ctRow.getSdtList because that only gets sdts that are at cell level |
| XmlCursor cursor = ctRow.newCursor(); |
| cursor.selectPath("./*"); |
| while (cursor.toNextSelection()) { |
| XmlObject o = cursor.getObject(); |
| if (o instanceof CTTc) { |
| cells.add(new XWPFTableCell((CTTc) o, this, table.getBody())); |
| } else if (o instanceof CTSdtCell) { |
| cells.add(new XWPFSDTCell((CTSdtCell) o, this, table.getBody())); |
| } |
| } |
| cursor.dispose(); |
| return cells; |
| } |
| |
| /** |
| * create and return a list of all XWPFTableCell |
| * who belongs to this row |
| * |
| * @return a list of {@link XWPFTableCell} |
| */ |
| public List<XWPFTableCell> getTableCells() { |
| if (tableCells == null) { |
| List<XWPFTableCell> cells = new ArrayList<XWPFTableCell>(); |
| for (CTTc tableCell : ctRow.getTcArray()) { |
| cells.add(new XWPFTableCell(tableCell, this, table.getBody())); |
| } |
| //TODO: it is possible to have an SDT that contains a cell in within a row |
| //need to modify this code so that it pulls out SDT wrappers around cells, too. |
| |
| this.tableCells = cells; |
| } |
| return tableCells; |
| } |
| |
| /** |
| * returns the XWPFTableCell which belongs to the CTTC cell |
| * if there is no XWPFTableCell which belongs to the parameter CTTc cell null will be returned |
| */ |
| public XWPFTableCell getTableCell(CTTc cell) { |
| for (int i = 0; i < tableCells.size(); i++) { |
| if (tableCells.get(i).getCTTc() == cell) |
| return tableCells.get(i); |
| } |
| return null; |
| } |
| |
| /** |
| * Return true if the "can't split row" value is true. The logic for this |
| * attribute is a little unusual: a TRUE value means DON'T allow rows to |
| * split, FALSE means allow rows to split. |
| * |
| * @return true if rows can't be split, false otherwise. |
| */ |
| public boolean isCantSplitRow() { |
| boolean isCant = false; |
| if (ctRow.isSetTrPr()) { |
| CTTrPr trpr = getTrPr(); |
| if (trpr.sizeOfCantSplitArray() > 0) { |
| CTOnOff onoff = trpr.getCantSplitArray(0); |
| isCant = (onoff.isSetVal() ? WMLHelper.convertSTOnOffToBoolean(onoff.getVal()) : true); |
| } |
| } |
| return isCant; |
| } |
| |
| /** |
| * Controls whether to allow this table row to split across pages. |
| * The logic for this attribute is a little unusual: a true value means |
| * DON'T allow rows to split, false means allow rows to split. |
| * |
| * @param split - if true, don't allow row to be split. If false, allow |
| * row to be split. |
| */ |
| public void setCantSplitRow(boolean split) { |
| CTTrPr trpr = getTrPr(); |
| CTOnOff onoff = (trpr.sizeOfCantSplitArray() > 0 ? trpr.getCantSplitArray(0) : trpr.addNewCantSplit()); |
| onoff.setVal(WMLHelper.convertBooleanToSTOnOff(split)); |
| } |
| |
| /** |
| * Return true if a table's header row should be repeated at the top of a |
| * table split across pages. NOTE - Word will not repeat a table row unless |
| * all preceding rows of the table are also repeated. This function returns |
| * false if the row will not be repeated even if the repeat tag is present |
| * for this row. |
| * |
| * @return true if table's header row should be repeated at the top of each |
| * page of table, false otherwise. |
| */ |
| public boolean isRepeatHeader() { |
| boolean repeat = false; |
| for (XWPFTableRow row : table.getRows()) { |
| repeat = row.getRepeat(); |
| if (row == this || !repeat) { |
| break; |
| } |
| } |
| return repeat; |
| } |
| |
| private boolean getRepeat() { |
| boolean repeat = false; |
| if (ctRow.isSetTrPr()) { |
| CTTrPr trpr = getTrPr(); |
| if (trpr.sizeOfTblHeaderArray() > 0) { |
| CTOnOff rpt = trpr.getTblHeaderArray(0); |
| repeat = (rpt.isSetVal() ? WMLHelper.convertSTOnOffToBoolean(rpt.getVal()) : true); |
| } |
| } |
| return repeat; |
| } |
| |
| /** |
| * This attribute controls whether to repeat a table's header row at the top |
| * of a table split across pages. NOTE - for a row to be repeated, all preceding |
| * rows in the table must also be repeated. |
| * |
| * @param repeat - if TRUE, repeat header row at the top of each page of table; |
| * if FALSE, don't repeat header row. |
| */ |
| public void setRepeatHeader(boolean repeat) { |
| CTTrPr trpr = getTrPr(); |
| CTOnOff onoff = (trpr.sizeOfTblHeaderArray() > 0 ? trpr.getTblHeaderArray(0) : trpr.addNewTblHeader()); |
| onoff.setVal(WMLHelper.convertBooleanToSTOnOff(repeat)); |
| } |
| } |