git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1839259 13f79535-47bb-0310-9956-ffa450edef68pull/123/merge
@@ -1152,10 +1152,8 @@ under the License. | |||
<target name="retest-ooxml" depends="jar"> | |||
<delete dir="${ooxml.reports.test}"/> | |||
<delete dir="${ooxml.output.test}"/> | |||
<delete dir="${ooxml.output.test.dir}"/> | |||
<mkdir dir="${ooxml.reports.test}"/> | |||
<mkdir dir="${ooxml.output.test}"/> | |||
<mkdir dir="${ooxml.output.test.dir}"/> | |||
<!-- compile the sources --> | |||
<javac target="${jdk.version.class}" |
@@ -21,34 +21,28 @@ package org.apache.poi.xslf.usermodel; | |||
import org.apache.poi.sl.usermodel.AutoShape; | |||
import org.apache.poi.util.Beta; | |||
import org.apache.poi.xddf.usermodel.text.XDDFTextBody; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBodyProperties; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.STTextAlignType; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.STTextAnchoringType; | |||
import org.openxmlformats.schemas.presentationml.x2006.main.CTShape; | |||
import org.openxmlformats.schemas.presentationml.x2006.main.CTShapeNonVisual; | |||
/** | |||
* Represents a shape with a preset geometry. | |||
* | |||
* @author Yegor Kozlov | |||
*/ | |||
@Beta | |||
public class XSLFAutoShape extends XSLFTextShape | |||
implements AutoShape<XSLFShape,XSLFTextParagraph> { | |||
public class XSLFAutoShape extends XSLFTextShape implements AutoShape<XSLFShape, XSLFTextParagraph> { | |||
/*package*/ XSLFAutoShape(CTShape shape, XSLFSheet sheet) { | |||
/* package */ XSLFAutoShape(CTShape shape, XSLFSheet sheet) { | |||
super(shape, sheet); | |||
} | |||
/*package*/ | |||
/* package */ | |||
static XSLFAutoShape create(CTShape shape, XSLFSheet sheet) { | |||
if (shape.getSpPr().isSetCustGeom()) { | |||
return new XSLFFreeformShape(shape, sheet); | |||
@@ -60,7 +54,8 @@ public class XSLFAutoShape extends XSLFTextShape | |||
} | |||
/** | |||
* @param shapeId 1-based shapeId | |||
* @param shapeId | |||
* 1-based shapeId | |||
*/ | |||
static CTShape prototype(int shapeId) { | |||
CTShape ct = CTShape.Factory.newInstance(); | |||
@@ -76,22 +71,10 @@ public class XSLFAutoShape extends XSLFTextShape | |||
prst.addNewAvLst(); | |||
return ct; | |||
} | |||
protected static void initTextBody(CTTextBody txBody) { | |||
CTTextBodyProperties bodypr = txBody.addNewBodyPr(); | |||
bodypr.setAnchor(STTextAnchoringType.T); | |||
bodypr.setRtlCol(false); | |||
CTTextParagraph p = txBody.addNewP(); | |||
p.addNewPPr().setAlgn(STTextAlignType.L); | |||
CTTextCharacterProperties endPr = p.addNewEndParaRPr(); | |||
endPr.setLang("en-US"); | |||
endPr.setSz(1100); | |||
p.addNewR().setT(""); | |||
txBody.addNewLstStyle(); | |||
} | |||
protected CTTextBody getTextBody(boolean create){ | |||
CTShape shape = (CTShape)getXmlObject(); | |||
@Override | |||
protected CTTextBody getTextBody(boolean create) { | |||
CTShape shape = (CTShape) getXmlObject(); | |||
CTTextBody txBody = shape.getTxBody(); | |||
if (txBody == null && create) { | |||
txBody = shape.addNewTxBody(); | |||
@@ -101,7 +84,7 @@ public class XSLFAutoShape extends XSLFTextShape | |||
} | |||
@Override | |||
public String toString(){ | |||
public String toString() { | |||
return "[" + getClass().getSimpleName() + "] " + getShapeName(); | |||
} | |||
@@ -33,6 +33,7 @@ import org.apache.poi.sl.usermodel.StrokeStyle.LineDash; | |||
import org.apache.poi.sl.usermodel.TableCell; | |||
import org.apache.poi.sl.usermodel.VerticalAlignment; | |||
import org.apache.poi.util.Units; | |||
import org.apache.poi.xddf.usermodel.text.XDDFTextBody; | |||
import org.apache.poi.xslf.usermodel.XSLFPropertiesDelegate.XSLFFillProperties; | |||
import org.apache.poi.xslf.usermodel.XSLFTableStyle.TablePartStyle; | |||
import org.apache.xmlbeans.XmlObject; | |||
@@ -67,7 +68,7 @@ import org.openxmlformats.schemas.drawingml.x2006.main.STTextVerticalType; | |||
/** | |||
* Represents a cell of a table in a .pptx presentation | |||
*/ | |||
public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,XSLFTextParagraph> { | |||
public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape, XSLFTextParagraph> { | |||
private CTTableCellProperties _tcPr; | |||
private final XSLFTable table; | |||
private int row, col; | |||
@@ -77,18 +78,20 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape, | |||
*/ | |||
private Rectangle2D anchor; | |||
/*package*/ XSLFTableCell(CTTableCell cell, XSLFTable table){ | |||
/* package */ XSLFTableCell(CTTableCell cell, XSLFTable table) { | |||
super(cell, table.getSheet()); | |||
this.table = table; | |||
} | |||
@Override | |||
protected CTTextBody getTextBody(boolean create){ | |||
protected CTTextBody getTextBody(boolean create) { | |||
CTTableCell cell = getCell(); | |||
CTTextBody txBody = cell.getTxBody(); | |||
if (txBody == null && create) { | |||
txBody = cell.addNewTxBody(); | |||
XSLFAutoShape.initTextBody(txBody); | |||
XDDFTextBody body = new XDDFTextBody(this); | |||
initTextBody(body); | |||
cell.setTxBody(body.getXmlObject()); | |||
txBody = cell.getTxBody(); | |||
} | |||
return txBody; | |||
} | |||
@@ -116,25 +119,25 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape, | |||
} | |||
@Override | |||
public void setLeftInset(double margin){ | |||
public void setLeftInset(double margin) { | |||
CTTableCellProperties pr = getCellProperties(true); | |||
pr.setMarL(Units.toEMU(margin)); | |||
} | |||
@Override | |||
public void setRightInset(double margin){ | |||
public void setRightInset(double margin) { | |||
CTTableCellProperties pr = getCellProperties(true); | |||
pr.setMarR(Units.toEMU(margin)); | |||
} | |||
@Override | |||
public void setTopInset(double margin){ | |||
public void setTopInset(double margin) { | |||
CTTableCellProperties pr = getCellProperties(true); | |||
pr.setMarT(Units.toEMU(margin)); | |||
} | |||
@Override | |||
public void setBottomInset(double margin){ | |||
public void setBottomInset(double margin) { | |||
CTTableCellProperties pr = getCellProperties(true); | |||
pr.setMarB(Units.toEMU(margin)); | |||
} | |||
@@ -150,16 +153,16 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape, | |||
} | |||
switch (edge) { | |||
case bottom: | |||
return (pr.isSetLnB()) ? pr.getLnB() : (create ? pr.addNewLnB() : null); | |||
case left: | |||
return (pr.isSetLnL()) ? pr.getLnL() : (create ? pr.addNewLnL() : null); | |||
case top: | |||
return (pr.isSetLnT()) ? pr.getLnT() : (create ? pr.addNewLnT() : null); | |||
case right: | |||
return (pr.isSetLnR()) ? pr.getLnR() : (create ? pr.addNewLnR() : null); | |||
default: | |||
return null; | |||
case bottom: | |||
return (pr.isSetLnB()) ? pr.getLnB() : (create ? pr.addNewLnB() : null); | |||
case left: | |||
return (pr.isSetLnL()) ? pr.getLnL() : (create ? pr.addNewLnL() : null); | |||
case top: | |||
return (pr.isSetLnT()) ? pr.getLnT() : (create ? pr.addNewLnT() : null); | |||
case right: | |||
return (pr.isSetLnR()) ? pr.getLnR() : (create ? pr.addNewLnR() : null); | |||
default: | |||
return null; | |||
} | |||
} | |||
@@ -170,28 +173,28 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape, | |||
return; | |||
} | |||
switch (edge) { | |||
case bottom: | |||
if (pr.isSetLnB()) { | |||
pr.unsetLnB(); | |||
} | |||
break; | |||
case left: | |||
if (pr.isSetLnL()) { | |||
pr.unsetLnL(); | |||
} | |||
break; | |||
case top: | |||
if (pr.isSetLnT()) { | |||
pr.unsetLnT(); | |||
} | |||
break; | |||
case right: | |||
if (pr.isSetLnR()) { | |||
pr.unsetLnB(); | |||
} | |||
break; | |||
default: | |||
throw new IllegalArgumentException(); | |||
case bottom: | |||
if (pr.isSetLnB()) { | |||
pr.unsetLnB(); | |||
} | |||
break; | |||
case left: | |||
if (pr.isSetLnL()) { | |||
pr.unsetLnL(); | |||
} | |||
break; | |||
case top: | |||
if (pr.isSetLnT()) { | |||
pr.unsetLnT(); | |||
} | |||
break; | |||
case right: | |||
if (pr.isSetLnR()) { | |||
pr.unsetLnB(); | |||
} | |||
break; | |||
default: | |||
throw new IllegalArgumentException(); | |||
} | |||
} | |||
@@ -276,7 +279,7 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape, | |||
ln.unsetNoFill(); | |||
} | |||
if(!ln.isSetPrstDash()) { | |||
if (!ln.isSetPrstDash()) { | |||
ln.addNewPrstDash().setVal(STPresetLineDashVal.SOLID); | |||
} | |||
if (!ln.isSetCmpd()) { | |||
@@ -396,19 +399,19 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape, | |||
ln.setCap(STLineCap.Enum.forInt(cap.ooxmlId)); | |||
} | |||
/** | |||
* Specifies a solid color fill. The shape is filled entirely with the specified color. | |||
* Specifies a solid color fill. The shape is filled entirely with the | |||
* specified color. | |||
* | |||
* @param color the solid color fill. | |||
* The value of <code>null</code> unsets the solidFIll attribute from the underlying xml | |||
* @param color | |||
* the solid color fill. The value of <code>null</code> unsets | |||
* the solidFIll attribute from the underlying xml | |||
*/ | |||
@Override | |||
public void setFillColor(Color color) { | |||
CTTableCellProperties spPr = getCellProperties(true); | |||
if (color == null) { | |||
if(spPr.isSetSolidFill()) { | |||
if (spPr.isSetSolidFill()) { | |||
spPr.unsetSolidFill(); | |||
} | |||
} else { | |||
@@ -423,13 +426,13 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape, | |||
* @return solid fill color of null if not set | |||
*/ | |||
@Override | |||
public Color getFillColor(){ | |||
public Color getFillColor() { | |||
PaintStyle ps = getFillPaint(); | |||
if (ps instanceof SolidPaint) { | |||
ColorStyle cs = ((SolidPaint)ps).getSolidColor(); | |||
ColorStyle cs = ((SolidPaint) ps).getSolidColor(); | |||
return DrawPaint.applyColorTransform(cs); | |||
} | |||
return null; | |||
} | |||
@@ -465,23 +468,24 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape, | |||
} else { | |||
return null; | |||
} | |||
fp = XSLFPropertiesDelegate.getFillDelegate(props); | |||
if (fp != null) { | |||
if (fp != null) { | |||
PaintStyle paint = XSLFShape.selectPaint(fp, null, slideShow.getPackagePart(), theme, hasPlaceholder); | |||
if (paint != null) { | |||
return paint; | |||
} | |||
} | |||
return null; | |||
} | |||
/** | |||
* Retrieves the part style depending on the location of this cell | |||
* | |||
* @param tablePartStyle the part to be returned, usually this is null | |||
* and only set when used as a helper method | |||
* @param tablePartStyle | |||
* the part to be returned, usually this is null and only set | |||
* when used as a helper method | |||
* @return the table part style | |||
*/ | |||
private CTTablePartStyle getTablePartStyle(TablePartStyle tablePartStyle) { | |||
@@ -503,11 +507,11 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape, | |||
tps = tablePartStyle; | |||
} else if (row == 0 && firstRow) { | |||
tps = TablePartStyle.firstRow; | |||
} else if (row == table.getNumberOfRows()-1 && lastRow) { | |||
} else if (row == table.getNumberOfRows() - 1 && lastRow) { | |||
tps = TablePartStyle.lastRow; | |||
} else if (col == 0 && firstCol) { | |||
tps = TablePartStyle.firstCol; | |||
} else if (col == table.getNumberOfColumns()-1 && lastCol) { | |||
} else if (col == table.getNumberOfColumns() - 1 && lastCol) { | |||
tps = TablePartStyle.lastCol; | |||
} else { | |||
tps = TablePartStyle.wholeTbl; | |||
@@ -559,28 +563,28 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape, | |||
} | |||
@Override | |||
public void setVerticalAlignment(VerticalAlignment anchor){ | |||
CTTableCellProperties cellProps = getCellProperties(true); | |||
if(anchor == null) { | |||
if(cellProps.isSetAnchor()) { | |||
cellProps.unsetAnchor(); | |||
} | |||
} else { | |||
cellProps.setAnchor(STTextAnchoringType.Enum.forInt(anchor.ordinal() + 1)); | |||
} | |||
public void setVerticalAlignment(VerticalAlignment anchor) { | |||
CTTableCellProperties cellProps = getCellProperties(true); | |||
if (anchor == null) { | |||
if (cellProps.isSetAnchor()) { | |||
cellProps.unsetAnchor(); | |||
} | |||
} else { | |||
cellProps.setAnchor(STTextAnchoringType.Enum.forInt(anchor.ordinal() + 1)); | |||
} | |||
} | |||
@Override | |||
public VerticalAlignment getVerticalAlignment(){ | |||
public VerticalAlignment getVerticalAlignment() { | |||
CTTableCellProperties cellProps = getCellProperties(false); | |||
VerticalAlignment align = VerticalAlignment.TOP; | |||
if(cellProps != null && cellProps.isSetAnchor()) { | |||
if (cellProps != null && cellProps.isSetAnchor()) { | |||
int ival = cellProps.getAnchor().intValue(); | |||
align = VerticalAlignment.values()[ival - 1]; | |||
} | |||
return align; | |||
} | |||
} | |||
/** | |||
* @since POI 3.15-beta2 | |||
@@ -588,7 +592,7 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape, | |||
@Override | |||
public void setTextDirection(TextDirection orientation) { | |||
CTTableCellProperties cellProps = getCellProperties(true); | |||
if(orientation == null) { | |||
if (orientation == null) { | |||
if (cellProps.isSetVert()) { | |||
cellProps.unsetVert(); | |||
} | |||
@@ -629,23 +633,23 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape, | |||
} | |||
switch (orientation.intValue()) { | |||
default: | |||
case STTextVerticalType.INT_HORZ: | |||
return TextDirection.HORIZONTAL; | |||
case STTextVerticalType.INT_VERT: | |||
case STTextVerticalType.INT_EA_VERT: | |||
case STTextVerticalType.INT_MONGOLIAN_VERT: | |||
return TextDirection.VERTICAL; | |||
case STTextVerticalType.INT_VERT_270: | |||
return TextDirection.VERTICAL_270; | |||
case STTextVerticalType.INT_WORD_ART_VERT: | |||
case STTextVerticalType.INT_WORD_ART_VERT_RTL: | |||
return TextDirection.STACKED; | |||
default: | |||
case STTextVerticalType.INT_HORZ: | |||
return TextDirection.HORIZONTAL; | |||
case STTextVerticalType.INT_VERT: | |||
case STTextVerticalType.INT_EA_VERT: | |||
case STTextVerticalType.INT_MONGOLIAN_VERT: | |||
return TextDirection.VERTICAL; | |||
case STTextVerticalType.INT_VERT_270: | |||
return TextDirection.VERTICAL_270; | |||
case STTextVerticalType.INT_WORD_ART_VERT: | |||
case STTextVerticalType.INT_WORD_ART_VERT_RTL: | |||
return TextDirection.STACKED; | |||
} | |||
} | |||
private CTTableCell getCell() { | |||
return (CTTableCell)getXmlObject(); | |||
return (CTTableCell) getXmlObject(); | |||
} | |||
/* package */ void setRowColIndex(int row, int col) { | |||
@@ -669,15 +673,16 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape, | |||
} | |||
/** | |||
* There's no real anchor for table cells - this method is used to temporarily store the location | |||
* of the cell for a later retrieval, e.g. for rendering | |||
* There's no real anchor for table cells - this method is used to | |||
* temporarily store the location of the cell for a later retrieval, e.g. | |||
* for rendering | |||
* | |||
* @since POI 3.15-beta2 | |||
*/ | |||
@Override | |||
public void setAnchor(Rectangle2D anchor) { | |||
if (this.anchor == null) { | |||
this.anchor = (Rectangle2D)anchor.clone(); | |||
this.anchor = (Rectangle2D) anchor.clone(); | |||
} else { | |||
this.anchor.setRect(anchor); | |||
} | |||
@@ -692,7 +697,7 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape, | |||
table.updateCellAnchor(); | |||
} | |||
// anchor should be set, after updateCellAnchor is through | |||
assert(anchor != null); | |||
assert (anchor != null); | |||
return anchor; | |||
} | |||
@@ -717,7 +722,7 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape, | |||
protected XmlObject getShapeProperties() { | |||
return getCellProperties(false); | |||
} | |||
/** | |||
* @since POI 3.15-beta2 | |||
*/ | |||
@@ -741,7 +746,7 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape, | |||
} | |||
@Override | |||
public PaintStyle getFontColor(){ | |||
public PaintStyle getFontColor() { | |||
CTTableStyleTextStyle txStyle = getTextStyle(); | |||
if (txStyle == null) { | |||
return super.getFontColor(); | |||
@@ -752,7 +757,7 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape, | |||
if (fontRef != null) { | |||
phClr = fontRef.getSchemeClr(); | |||
} | |||
XSLFTheme theme = getSheet().getTheme(); | |||
final XSLFColor c = new XSLFColor(txStyle, theme, phClr); | |||
return DrawPaint.createSolidPaint(c.getColorStyle()); | |||
@@ -777,7 +782,7 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape, | |||
return txStyle.isSetI() && txStyle.getI().intValue() == STOnOffStyleType.INT_ON; | |||
} | |||
} | |||
private CTTableStyleTextStyle getTextStyle() { | |||
CTTablePartStyle tps = getTablePartStyle(null); | |||
if (tps == null || !tps.isSetTcTxStyle()) { |
@@ -21,27 +21,30 @@ package org.apache.poi.xslf.usermodel; | |||
import org.apache.poi.sl.usermodel.TextBox; | |||
import org.apache.poi.util.Beta; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.*; | |||
import org.apache.poi.xddf.usermodel.text.XDDFTextBody; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType; | |||
import org.openxmlformats.schemas.presentationml.x2006.main.CTShape; | |||
import org.openxmlformats.schemas.presentationml.x2006.main.CTShapeNonVisual; | |||
/** | |||
* @author Yegor Kozlov | |||
*/ | |||
@Beta | |||
public class XSLFTextBox extends XSLFAutoShape | |||
implements TextBox<XSLFShape,XSLFTextParagraph> { | |||
public class XSLFTextBox extends XSLFAutoShape implements TextBox<XSLFShape, XSLFTextParagraph> { | |||
/*package*/ XSLFTextBox(CTShape shape, XSLFSheet sheet){ | |||
/* package */ XSLFTextBox(CTShape shape, XSLFSheet sheet) { | |||
super(shape, sheet); | |||
} | |||
/** | |||
* | |||
* @param shapeId 1-based shapeId | |||
* @param shapeId | |||
* 1-based shapeId | |||
*/ | |||
static CTShape prototype(int shapeId){ | |||
static CTShape prototype(int shapeId) { | |||
CTShape ct = CTShape.Factory.newInstance(); | |||
CTShapeNonVisual nvSpPr = ct.addNewNvSpPr(); | |||
CTNonVisualDrawingProps cnv = nvSpPr.addNewCNvPr(); | |||
@@ -53,9 +56,10 @@ public class XSLFTextBox extends XSLFAutoShape | |||
CTPresetGeometry2D prst = spPr.addNewPrstGeom(); | |||
prst.setPrst(STShapeType.RECT); | |||
prst.addNewAvLst(); | |||
CTTextBody txBody = ct.addNewTxBody(); | |||
XSLFAutoShape.initTextBody(txBody); | |||
XDDFTextBody body = new XDDFTextBody(null); | |||
initTextBody(body); | |||
ct.setTxBody(body.getXmlObject()); | |||
return ct; | |||
} | |||
} | |||
} |
@@ -24,6 +24,8 @@ import java.awt.geom.Rectangle2D; | |||
import java.util.ArrayList; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import java.util.Optional; | |||
import java.util.function.Function; | |||
import org.apache.poi.ooxml.POIXMLException; | |||
import org.apache.poi.sl.draw.DrawFactory; | |||
@@ -34,6 +36,9 @@ import org.apache.poi.sl.usermodel.TextShape; | |||
import org.apache.poi.sl.usermodel.VerticalAlignment; | |||
import org.apache.poi.util.Beta; | |||
import org.apache.poi.util.Units; | |||
import org.apache.poi.xddf.usermodel.text.TextContainer; | |||
import org.apache.poi.xddf.usermodel.text.XDDFTextBody; | |||
import org.apache.poi.xddf.usermodel.text.XDDFTextParagraph; | |||
import org.apache.poi.xslf.model.PropertyFetcher; | |||
import org.apache.poi.xslf.model.TextBodyPropertyFetcher; | |||
import org.apache.xmlbeans.XmlObject; | |||
@@ -52,10 +57,10 @@ import org.openxmlformats.schemas.drawingml.x2006.main.STTextWrappingType; | |||
*/ | |||
@Beta | |||
public abstract class XSLFTextShape extends XSLFSimpleShape | |||
implements TextShape<XSLFShape,XSLFTextParagraph> { | |||
implements TextContainer, TextShape<XSLFShape, XSLFTextParagraph> { | |||
private final List<XSLFTextParagraph> _paragraphs; | |||
/*package*/ XSLFTextShape(XmlObject shape, XSLFSheet sheet) { | |||
/* package */ XSLFTextShape(XmlObject shape, XSLFSheet sheet) { | |||
super(shape, sheet); | |||
_paragraphs = new ArrayList<>(); | |||
@@ -67,8 +72,22 @@ public abstract class XSLFTextShape extends XSLFSimpleShape | |||
} | |||
} | |||
protected static void initTextBody(XDDFTextBody body) { | |||
XDDFTextParagraph p = body.getParagraph(0); | |||
p.appendRegularRun(""); | |||
} | |||
@Beta | |||
public XDDFTextBody getTextBody() { | |||
CTTextBody txBody = getTextBody(false); | |||
if (txBody == null) { | |||
return null; | |||
} | |||
return new XDDFTextBody(this, txBody); | |||
} | |||
@Override | |||
public Iterator<XSLFTextParagraph> iterator(){ | |||
public Iterator<XSLFTextParagraph> iterator() { | |||
return getTextParagraphs().iterator(); | |||
} | |||
@@ -87,7 +106,7 @@ public abstract class XSLFTextShape extends XSLFSimpleShape | |||
/** | |||
* unset text from this shape | |||
*/ | |||
public void clearText(){ | |||
public void clearText() { | |||
_paragraphs.clear(); | |||
CTTextBody txBody = getTextBody(true); | |||
txBody.setPArray(null); // remove any existing paragraphs | |||
@@ -95,13 +114,14 @@ public abstract class XSLFTextShape extends XSLFSimpleShape | |||
@Override | |||
public XSLFTextRun setText(String text) { | |||
// calling clearText or setting to a new Array leads to a XmlValueDisconnectedException | |||
// calling clearText or setting to a new Array leads to a | |||
// XmlValueDisconnectedException | |||
if (!_paragraphs.isEmpty()) { | |||
CTTextBody txBody = getTextBody(false); | |||
int cntPs = txBody.sizeOfPArray(); | |||
for (int i = cntPs; i > 1; i--) { | |||
txBody.removeP(i-1); | |||
_paragraphs.remove(i-1); | |||
txBody.removeP(i - 1); | |||
_paragraphs.remove(i - 1); | |||
} | |||
_paragraphs.get(0).clearButKeepProperties(); | |||
@@ -127,18 +147,19 @@ public abstract class XSLFTextShape extends XSLFSimpleShape | |||
para = null; | |||
} else { | |||
firstPara = !newParagraph; | |||
para = _paragraphs.get(_paragraphs.size()-1); | |||
para = _paragraphs.get(_paragraphs.size() - 1); | |||
CTTextParagraph ctp = para.getXmlObject(); | |||
otherPPr = ctp.getPPr(); | |||
List<XSLFTextRun> runs = para.getTextRuns(); | |||
if (!runs.isEmpty()) { | |||
XSLFTextRun r0 = runs.get(runs.size()-1); | |||
XSLFTextRun r0 = runs.get(runs.size() - 1); | |||
otherRPr = r0.getRPr(false); | |||
if (otherRPr == null) { | |||
otherRPr = ctp.getEndParaRPr(); | |||
} | |||
} | |||
// don't copy endParaRPr to the run in case there aren't any other runs | |||
// don't copy endParaRPr to the run in case there aren't any other | |||
// runs | |||
// this is the case when setText() was called initially | |||
// otherwise the master style will be overridden/ignored | |||
} | |||
@@ -173,7 +194,7 @@ public abstract class XSLFTextShape extends XSLFSimpleShape | |||
firstPara = false; | |||
} | |||
assert(run != null); | |||
assert (run != null); | |||
return run; | |||
} | |||
@@ -203,11 +224,11 @@ public abstract class XSLFTextShape extends XSLFSimpleShape | |||
} | |||
@Override | |||
public void setVerticalAlignment(VerticalAlignment anchor){ | |||
public void setVerticalAlignment(VerticalAlignment anchor) { | |||
CTTextBodyProperties bodyPr = getTextBodyPr(true); | |||
if (bodyPr != null) { | |||
if(anchor == null) { | |||
if(bodyPr.isSetAnchor()) { | |||
if (anchor == null) { | |||
if (bodyPr.isSetAnchor()) { | |||
bodyPr.unsetAnchor(); | |||
} | |||
} else { | |||
@@ -217,11 +238,11 @@ public abstract class XSLFTextShape extends XSLFSimpleShape | |||
} | |||
@Override | |||
public VerticalAlignment getVerticalAlignment(){ | |||
PropertyFetcher<VerticalAlignment> fetcher = new TextBodyPropertyFetcher<VerticalAlignment>(){ | |||
public VerticalAlignment getVerticalAlignment() { | |||
PropertyFetcher<VerticalAlignment> fetcher = new TextBodyPropertyFetcher<VerticalAlignment>() { | |||
@Override | |||
public boolean fetch(CTTextBodyProperties props){ | |||
if(props.isSetAnchor()){ | |||
public boolean fetch(CTTextBodyProperties props) { | |||
if (props.isSetAnchor()) { | |||
int val = props.getAnchor().intValue(); | |||
setValue(VerticalAlignment.values()[val - 1]); | |||
return true; | |||
@@ -234,10 +255,10 @@ public abstract class XSLFTextShape extends XSLFSimpleShape | |||
} | |||
@Override | |||
public void setHorizontalCentered(Boolean isCentered){ | |||
public void setHorizontalCentered(Boolean isCentered) { | |||
CTTextBodyProperties bodyPr = getTextBodyPr(true); | |||
if (bodyPr != null) { | |||
if (isCentered == null) { | |||
if (isCentered == null) { | |||
if (bodyPr.isSetAnchorCtr()) { | |||
bodyPr.unsetAnchorCtr(); | |||
} | |||
@@ -248,11 +269,11 @@ public abstract class XSLFTextShape extends XSLFSimpleShape | |||
} | |||
@Override | |||
public boolean isHorizontalCentered(){ | |||
PropertyFetcher<Boolean> fetcher = new TextBodyPropertyFetcher<Boolean>(){ | |||
public boolean isHorizontalCentered() { | |||
PropertyFetcher<Boolean> fetcher = new TextBodyPropertyFetcher<Boolean>() { | |||
@Override | |||
public boolean fetch(CTTextBodyProperties props){ | |||
if(props.isSetAnchorCtr()){ | |||
public boolean fetch(CTTextBodyProperties props) { | |||
if (props.isSetAnchorCtr()) { | |||
setValue(props.getAnchorCtr()); | |||
return true; | |||
} | |||
@@ -264,11 +285,11 @@ public abstract class XSLFTextShape extends XSLFSimpleShape | |||
} | |||
@Override | |||
public void setTextDirection(TextDirection orientation){ | |||
public void setTextDirection(TextDirection orientation) { | |||
CTTextBodyProperties bodyPr = getTextBodyPr(true); | |||
if (bodyPr != null) { | |||
if(orientation == null) { | |||
if(bodyPr.isSetVert()) { | |||
if (orientation == null) { | |||
if (bodyPr.isSetVert()) { | |||
bodyPr.unsetVert(); | |||
} | |||
} else { | |||
@@ -278,24 +299,24 @@ public abstract class XSLFTextShape extends XSLFSimpleShape | |||
} | |||
@Override | |||
public TextDirection getTextDirection(){ | |||
public TextDirection getTextDirection() { | |||
CTTextBodyProperties bodyPr = getTextBodyPr(); | |||
if (bodyPr != null) { | |||
STTextVerticalType.Enum val = bodyPr.getVert(); | |||
if(val != null) { | |||
if (val != null) { | |||
switch (val.intValue()) { | |||
default: | |||
case STTextVerticalType.INT_HORZ: | |||
return TextDirection.HORIZONTAL; | |||
case STTextVerticalType.INT_EA_VERT: | |||
case STTextVerticalType.INT_MONGOLIAN_VERT: | |||
case STTextVerticalType.INT_VERT: | |||
return TextDirection.VERTICAL; | |||
case STTextVerticalType.INT_VERT_270: | |||
return TextDirection.VERTICAL_270; | |||
case STTextVerticalType.INT_WORD_ART_VERT_RTL: | |||
case STTextVerticalType.INT_WORD_ART_VERT: | |||
return TextDirection.STACKED; | |||
default: | |||
case STTextVerticalType.INT_HORZ: | |||
return TextDirection.HORIZONTAL; | |||
case STTextVerticalType.INT_EA_VERT: | |||
case STTextVerticalType.INT_MONGOLIAN_VERT: | |||
case STTextVerticalType.INT_VERT: | |||
return TextDirection.VERTICAL; | |||
case STTextVerticalType.INT_VERT_270: | |||
return TextDirection.VERTICAL_270; | |||
case STTextVerticalType.INT_WORD_ART_VERT_RTL: | |||
case STTextVerticalType.INT_WORD_ART_VERT: | |||
return TextDirection.STACKED; | |||
} | |||
} | |||
} | |||
@@ -315,22 +336,22 @@ public abstract class XSLFTextShape extends XSLFSimpleShape | |||
public void setTextRotation(Double rotation) { | |||
CTTextBodyProperties bodyPr = getTextBodyPr(true); | |||
if (bodyPr != null) { | |||
bodyPr.setRot((int)(rotation * 60000.)); | |||
bodyPr.setRot((int) (rotation * 60000.)); | |||
} | |||
} | |||
/** | |||
* Returns the distance (in points) between the bottom of the text frame | |||
* and the bottom of the inscribed rectangle of the shape that contains the text. | |||
* Returns the distance (in points) between the bottom of the text frame and | |||
* the bottom of the inscribed rectangle of the shape that contains the | |||
* text. | |||
* | |||
* @return the bottom inset in points | |||
*/ | |||
public double getBottomInset(){ | |||
PropertyFetcher<Double> fetcher = new TextBodyPropertyFetcher<Double>(){ | |||
public double getBottomInset() { | |||
PropertyFetcher<Double> fetcher = new TextBodyPropertyFetcher<Double>() { | |||
@Override | |||
public boolean fetch(CTTextBodyProperties props){ | |||
if(props.isSetBIns()){ | |||
public boolean fetch(CTTextBodyProperties props) { | |||
if (props.isSetBIns()) { | |||
double val = Units.toPoints(props.getBIns()); | |||
setValue(val); | |||
return true; | |||
@@ -344,17 +365,17 @@ public abstract class XSLFTextShape extends XSLFSimpleShape | |||
} | |||
/** | |||
* Returns the distance (in points) between the left edge of the text frame | |||
* and the left edge of the inscribed rectangle of the shape that contains | |||
* the text. | |||
* Returns the distance (in points) between the left edge of the text frame | |||
* and the left edge of the inscribed rectangle of the shape that contains | |||
* the text. | |||
* | |||
* @return the left inset in points | |||
*/ | |||
public double getLeftInset(){ | |||
PropertyFetcher<Double> fetcher = new TextBodyPropertyFetcher<Double>(){ | |||
public double getLeftInset() { | |||
PropertyFetcher<Double> fetcher = new TextBodyPropertyFetcher<Double>() { | |||
@Override | |||
public boolean fetch(CTTextBodyProperties props){ | |||
if(props.isSetLIns()){ | |||
public boolean fetch(CTTextBodyProperties props) { | |||
if (props.isSetLIns()) { | |||
double val = Units.toPoints(props.getLIns()); | |||
setValue(val); | |||
return true; | |||
@@ -368,17 +389,17 @@ public abstract class XSLFTextShape extends XSLFSimpleShape | |||
} | |||
/** | |||
* Returns the distance (in points) between the right edge of the | |||
* text frame and the right edge of the inscribed rectangle of the shape | |||
* that contains the text. | |||
* Returns the distance (in points) between the right edge of the text frame | |||
* and the right edge of the inscribed rectangle of the shape that contains | |||
* the text. | |||
* | |||
* @return the right inset in points | |||
*/ | |||
public double getRightInset(){ | |||
PropertyFetcher<Double> fetcher = new TextBodyPropertyFetcher<Double>(){ | |||
public double getRightInset() { | |||
PropertyFetcher<Double> fetcher = new TextBodyPropertyFetcher<Double>() { | |||
@Override | |||
public boolean fetch(CTTextBodyProperties props){ | |||
if(props.isSetRIns()){ | |||
public boolean fetch(CTTextBodyProperties props) { | |||
if (props.isSetRIns()) { | |||
double val = Units.toPoints(props.getRIns()); | |||
setValue(val); | |||
return true; | |||
@@ -392,16 +413,16 @@ public abstract class XSLFTextShape extends XSLFSimpleShape | |||
} | |||
/** | |||
* Returns the distance (in points) between the top of the text frame | |||
* and the top of the inscribed rectangle of the shape that contains the text. | |||
* Returns the distance (in points) between the top of the text frame and | |||
* the top of the inscribed rectangle of the shape that contains the text. | |||
* | |||
* @return the top inset in points | |||
*/ | |||
public double getTopInset(){ | |||
PropertyFetcher<Double> fetcher = new TextBodyPropertyFetcher<Double>(){ | |||
public double getTopInset() { | |||
PropertyFetcher<Double> fetcher = new TextBodyPropertyFetcher<Double>() { | |||
@Override | |||
public boolean fetch(CTTextBodyProperties props){ | |||
if(props.isSetTIns()){ | |||
public boolean fetch(CTTextBodyProperties props) { | |||
if (props.isSetTIns()) { | |||
double val = Units.toPoints(props.getTIns()); | |||
setValue(val); | |||
return true; | |||
@@ -416,14 +437,16 @@ public abstract class XSLFTextShape extends XSLFSimpleShape | |||
/** | |||
* Sets the bottom margin. | |||
* | |||
* @see #getBottomInset() | |||
* | |||
* @param margin the bottom margin | |||
* @param margin | |||
* the bottom margin | |||
*/ | |||
public void setBottomInset(double margin){ | |||
public void setBottomInset(double margin) { | |||
CTTextBodyProperties bodyPr = getTextBodyPr(true); | |||
if (bodyPr != null) { | |||
if(margin == -1) { | |||
if (margin == -1) { | |||
bodyPr.unsetBIns(); | |||
} else { | |||
bodyPr.setBIns(Units.toEMU(margin)); | |||
@@ -433,14 +456,16 @@ public abstract class XSLFTextShape extends XSLFSimpleShape | |||
/** | |||
* Sets the left margin. | |||
* | |||
* @see #getLeftInset() | |||
* | |||
* @param margin the left margin | |||
* @param margin | |||
* the left margin | |||
*/ | |||
public void setLeftInset(double margin){ | |||
public void setLeftInset(double margin) { | |||
CTTextBodyProperties bodyPr = getTextBodyPr(true); | |||
if (bodyPr != null) { | |||
if(margin == -1) { | |||
if (margin == -1) { | |||
bodyPr.unsetLIns(); | |||
} else { | |||
bodyPr.setLIns(Units.toEMU(margin)); | |||
@@ -450,14 +475,16 @@ public abstract class XSLFTextShape extends XSLFSimpleShape | |||
/** | |||
* Sets the right margin. | |||
* | |||
* @see #getRightInset() | |||
* | |||
* @param margin the right margin | |||
* @param margin | |||
* the right margin | |||
*/ | |||
public void setRightInset(double margin){ | |||
public void setRightInset(double margin) { | |||
CTTextBodyProperties bodyPr = getTextBodyPr(true); | |||
if (bodyPr != null) { | |||
if(margin == -1) { | |||
if (margin == -1) { | |||
bodyPr.unsetRIns(); | |||
} else { | |||
bodyPr.setRIns(Units.toEMU(margin)); | |||
@@ -467,14 +494,16 @@ public abstract class XSLFTextShape extends XSLFSimpleShape | |||
/** | |||
* Sets the top margin. | |||
* | |||
* @see #getTopInset() | |||
* | |||
* @param margin the top margin | |||
* @param margin | |||
* the top margin | |||
*/ | |||
public void setTopInset(double margin){ | |||
public void setTopInset(double margin) { | |||
CTTextBodyProperties bodyPr = getTextBodyPr(true); | |||
if (bodyPr != null) { | |||
if(margin == -1) { | |||
if (margin == -1) { | |||
bodyPr.unsetTIns(); | |||
} else { | |||
bodyPr.setTIns(Units.toEMU(margin)); | |||
@@ -496,11 +525,11 @@ public abstract class XSLFTextShape extends XSLFSimpleShape | |||
} | |||
@Override | |||
public boolean getWordWrap(){ | |||
PropertyFetcher<Boolean> fetcher = new TextBodyPropertyFetcher<Boolean>(){ | |||
public boolean getWordWrap() { | |||
PropertyFetcher<Boolean> fetcher = new TextBodyPropertyFetcher<Boolean>() { | |||
@Override | |||
public boolean fetch(CTTextBodyProperties props){ | |||
if(props.isSetWrap()){ | |||
public boolean fetch(CTTextBodyProperties props) { | |||
if (props.isSetWrap()) { | |||
setValue(props.getWrap() == STTextWrappingType.SQUARE); | |||
return true; | |||
} | |||
@@ -512,7 +541,7 @@ public abstract class XSLFTextShape extends XSLFSimpleShape | |||
} | |||
@Override | |||
public void setWordWrap(boolean wrap){ | |||
public void setWordWrap(boolean wrap) { | |||
CTTextBodyProperties bodyPr = getTextBodyPr(true); | |||
if (bodyPr != null) { | |||
bodyPr.setWrap(wrap ? STTextWrappingType.SQUARE : STTextWrappingType.NONE); | |||
@@ -521,28 +550,36 @@ public abstract class XSLFTextShape extends XSLFSimpleShape | |||
/** | |||
* | |||
* Specifies that a shape should be auto-fit to fully contain the text described within it. | |||
* Auto-fitting is when text within a shape is scaled in order to contain all the text inside | |||
* Specifies that a shape should be auto-fit to fully contain the text | |||
* described within it. Auto-fitting is when text within a shape is scaled | |||
* in order to contain all the text inside | |||
* | |||
* @param value type of autofit | |||
* @param value | |||
* type of autofit | |||
*/ | |||
public void setTextAutofit(TextAutofit value){ | |||
public void setTextAutofit(TextAutofit value) { | |||
CTTextBodyProperties bodyPr = getTextBodyPr(true); | |||
if (bodyPr != null) { | |||
if(bodyPr.isSetSpAutoFit()) { | |||
if (bodyPr.isSetSpAutoFit()) { | |||
bodyPr.unsetSpAutoFit(); | |||
} | |||
if(bodyPr.isSetNoAutofit()) { | |||
if (bodyPr.isSetNoAutofit()) { | |||
bodyPr.unsetNoAutofit(); | |||
} | |||
if(bodyPr.isSetNormAutofit()) { | |||
if (bodyPr.isSetNormAutofit()) { | |||
bodyPr.unsetNormAutofit(); | |||
} | |||
switch(value){ | |||
case NONE: bodyPr.addNewNoAutofit(); break; | |||
case NORMAL: bodyPr.addNewNormAutofit(); break; | |||
case SHAPE: bodyPr.addNewSpAutoFit(); break; | |||
switch (value) { | |||
case NONE: | |||
bodyPr.addNewNoAutofit(); | |||
break; | |||
case NORMAL: | |||
bodyPr.addNewNormAutofit(); | |||
break; | |||
case SHAPE: | |||
bodyPr.addNewSpAutoFit(); | |||
break; | |||
} | |||
} | |||
} | |||
@@ -551,10 +588,10 @@ public abstract class XSLFTextShape extends XSLFSimpleShape | |||
* | |||
* @return type of autofit | |||
*/ | |||
public TextAutofit getTextAutofit(){ | |||
public TextAutofit getTextAutofit() { | |||
CTTextBodyProperties bodyPr = getTextBodyPr(); | |||
if (bodyPr != null) { | |||
if(bodyPr.isSetNoAutofit()) { | |||
if (bodyPr.isSetNoAutofit()) { | |||
return TextAutofit.NONE; | |||
} else if (bodyPr.isSetNormAutofit()) { | |||
return TextAutofit.NORMAL; | |||
@@ -565,7 +602,7 @@ public abstract class XSLFTextShape extends XSLFSimpleShape | |||
return TextAutofit.NORMAL; | |||
} | |||
protected CTTextBodyProperties getTextBodyPr(){ | |||
protected CTTextBodyProperties getTextBodyPr() { | |||
return getTextBodyPr(false); | |||
} | |||
@@ -588,89 +625,88 @@ public abstract class XSLFTextShape extends XSLFSimpleShape | |||
super.setPlaceholder(placeholder); | |||
} | |||
public Placeholder getTextType(){ | |||
public Placeholder getTextType() { | |||
return getPlaceholder(); | |||
} | |||
@Override | |||
public double getTextHeight(){ | |||
public double getTextHeight() { | |||
return getTextHeight(null); | |||
} | |||
@Override | |||
public double getTextHeight(Graphics2D graphics){ | |||
public double getTextHeight(Graphics2D graphics) { | |||
DrawFactory drawFact = DrawFactory.getInstance(graphics); | |||
DrawTextShape dts = drawFact.getDrawable(this); | |||
return dts.getTextHeight(graphics); | |||
} | |||
@Override | |||
public Rectangle2D resizeToFitText(){ | |||
public Rectangle2D resizeToFitText() { | |||
return resizeToFitText(null); | |||
} | |||
@Override | |||
public Rectangle2D resizeToFitText(Graphics2D graphics) { | |||
Rectangle2D anchor = getAnchor(); | |||
if(anchor.getWidth() == 0.) { | |||
if (anchor.getWidth() == 0.) { | |||
throw new POIXMLException("Anchor of the shape was not set."); | |||
} | |||
double height = getTextHeight(graphics); | |||
height += 1; // add a pixel to compensate rounding errors | |||
Insets2D insets = getInsets(); | |||
anchor.setRect(anchor.getX(), anchor.getY(), anchor.getWidth(), height+insets.top+insets.bottom); | |||
anchor.setRect(anchor.getX(), anchor.getY(), anchor.getWidth(), height + insets.top + insets.bottom); | |||
setAnchor(anchor); | |||
return anchor; | |||
} | |||
@Override | |||
void copy(XSLFShape other){ | |||
void copy(XSLFShape other) { | |||
super.copy(other); | |||
XSLFTextShape otherTS = (XSLFTextShape)other; | |||
XSLFTextShape otherTS = (XSLFTextShape) other; | |||
CTTextBody otherTB = otherTS.getTextBody(false); | |||
CTTextBody thisTB = getTextBody(true); | |||
if (otherTB == null) { | |||
return; | |||
} | |||
thisTB.setBodyPr((CTTextBodyProperties)otherTB.getBodyPr().copy()); | |||
thisTB.setBodyPr((CTTextBodyProperties) otherTB.getBodyPr().copy()); | |||
if (thisTB.isSetLstStyle()) { | |||
thisTB.unsetLstStyle(); | |||
} | |||
if (otherTB.isSetLstStyle()) { | |||
thisTB.setLstStyle((CTTextListStyle)otherTB.getLstStyle().copy()); | |||
thisTB.setLstStyle((CTTextListStyle) otherTB.getLstStyle().copy()); | |||
} | |||
boolean srcWordWrap = otherTS.getWordWrap(); | |||
if(srcWordWrap != getWordWrap()){ | |||
if (srcWordWrap != getWordWrap()) { | |||
setWordWrap(srcWordWrap); | |||
} | |||
double leftInset = otherTS.getLeftInset(); | |||
if(leftInset != getLeftInset()) { | |||
if (leftInset != getLeftInset()) { | |||
setLeftInset(leftInset); | |||
} | |||
double rightInset = otherTS.getRightInset(); | |||
if(rightInset != getRightInset()) { | |||
if (rightInset != getRightInset()) { | |||
setRightInset(rightInset); | |||
} | |||
double topInset = otherTS.getTopInset(); | |||
if(topInset != getTopInset()) { | |||
if (topInset != getTopInset()) { | |||
setTopInset(topInset); | |||
} | |||
double bottomInset = otherTS.getBottomInset(); | |||
if(bottomInset != getBottomInset()) { | |||
if (bottomInset != getBottomInset()) { | |||
setBottomInset(bottomInset); | |||
} | |||
VerticalAlignment vAlign = otherTS.getVerticalAlignment(); | |||
if(vAlign != getVerticalAlignment()) { | |||
if (vAlign != getVerticalAlignment()) { | |||
setVerticalAlignment(vAlign); | |||
} | |||
@@ -685,26 +721,26 @@ public abstract class XSLFTextShape extends XSLFSimpleShape | |||
@Override | |||
public void setTextPlaceholder(TextPlaceholder placeholder) { | |||
switch (placeholder) { | |||
default: | |||
case NOTES: | |||
case HALF_BODY: | |||
case QUARTER_BODY: | |||
case BODY: | |||
setPlaceholder(Placeholder.BODY); | |||
break; | |||
case TITLE: | |||
setPlaceholder(Placeholder.TITLE); | |||
break; | |||
case CENTER_BODY: | |||
setPlaceholder(Placeholder.BODY); | |||
setHorizontalCentered(true); | |||
break; | |||
case CENTER_TITLE: | |||
setPlaceholder(Placeholder.CENTERED_TITLE); | |||
break; | |||
case OTHER: | |||
setPlaceholder(Placeholder.CONTENT); | |||
break; | |||
default: | |||
case NOTES: | |||
case HALF_BODY: | |||
case QUARTER_BODY: | |||
case BODY: | |||
setPlaceholder(Placeholder.BODY); | |||
break; | |||
case TITLE: | |||
setPlaceholder(Placeholder.TITLE); | |||
break; | |||
case CENTER_BODY: | |||
setPlaceholder(Placeholder.BODY); | |||
setHorizontalCentered(true); | |||
break; | |||
case CENTER_TITLE: | |||
setPlaceholder(Placeholder.CENTERED_TITLE); | |||
break; | |||
case OTHER: | |||
setPlaceholder(Placeholder.CONTENT); | |||
break; | |||
} | |||
} | |||
@@ -715,18 +751,23 @@ public abstract class XSLFTextShape extends XSLFSimpleShape | |||
return TextPlaceholder.BODY; | |||
} | |||
switch (ph) { | |||
case BODY: return TextPlaceholder.BODY; | |||
case TITLE: return TextPlaceholder.TITLE; | |||
case CENTERED_TITLE: return TextPlaceholder.CENTER_TITLE; | |||
case BODY: | |||
return TextPlaceholder.BODY; | |||
case TITLE: | |||
return TextPlaceholder.TITLE; | |||
case CENTERED_TITLE: | |||
return TextPlaceholder.CENTER_TITLE; | |||
default: | |||
case CONTENT: return TextPlaceholder.OTHER; | |||
case CONTENT: | |||
return TextPlaceholder.OTHER; | |||
} | |||
} | |||
/** | |||
* Helper method to allow subclasses to provide their own text paragraph | |||
* | |||
* @param p the xml reference | |||
* @param p | |||
* the xml reference | |||
* | |||
* @return a new text paragraph | |||
* | |||
@@ -735,4 +776,19 @@ public abstract class XSLFTextShape extends XSLFSimpleShape | |||
protected XSLFTextParagraph newTextParagraph(CTTextParagraph p) { | |||
return new XSLFTextParagraph(p, this); | |||
} | |||
} | |||
@Override | |||
public <R> Optional<R> findDefinedParagraphProperty(Function<CTTextParagraphProperties, Boolean> isSet, | |||
Function<CTTextParagraphProperties, R> getter) { | |||
// TODO Auto-generated method stub | |||
return Optional.empty(); | |||
} | |||
@Override | |||
public <R> Optional<R> findDefinedRunProperty(Function<CTTextCharacterProperties, Boolean> isSet, | |||
Function<CTTextCharacterProperties, R> getter) { | |||
// TODO Auto-generated method stub | |||
return Optional.empty(); | |||
} | |||
} |
@@ -74,7 +74,7 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor | |||
private XSSFGraphicFrame frame; | |||
@Deprecated | |||
@Removal(version="4.2") | |||
@Removal(version = "4.2") | |||
List<XSSFChartAxis> axis = new ArrayList<>(); | |||
/** | |||
@@ -89,7 +89,8 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor | |||
* Construct a SpreadsheetML chart from a package part. | |||
* | |||
* @param part | |||
* the package part holding the chart data, the content type must be | |||
* the package part holding the chart data, the content type must | |||
* be | |||
* <code>application/vnd.openxmlformats-officedocument.drawingml.chart+xml</code> | |||
* | |||
* @since POI 3.14-Beta1 | |||
@@ -114,7 +115,8 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor | |||
} | |||
/** | |||
* Construct a new CTChartSpace bean. By default, it's just an empty placeholder for chart objects. | |||
* Construct a new CTChartSpace bean. By default, it's just an empty | |||
* placeholder for chart objects. | |||
*/ | |||
private void createChart() { | |||
CTPlotArea plotArea = getCTPlotArea(); | |||
@@ -140,12 +142,15 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor | |||
XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS); | |||
/* | |||
* Saved chart space must have the following namespaces set: <c:chartSpace | |||
* Saved chart space must have the following namespaces set: | |||
* <c:chartSpace | |||
* xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart" | |||
* xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r= | |||
* xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" | |||
* xmlns:r= | |||
* "http://schemas.openxmlformats.org/officeDocument/2006/relationships"> | |||
*/ | |||
xmlOptions.setSaveSyntheticDocumentElement(new QName(CTChartSpace.type.getName().getNamespaceURI(), "chartSpace", "c")); | |||
xmlOptions.setSaveSyntheticDocumentElement( | |||
new QName(CTChartSpace.type.getName().getNamespaceURI(), "chartSpace", "c")); | |||
PackagePart part = getPackagePart(); | |||
try (OutputStream out = part.getOutputStream()) { | |||
@@ -171,76 +176,76 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor | |||
@Override | |||
@Deprecated | |||
@Removal(version="4.2") | |||
public XSSFChartDataFactory getChartDataFactory() { | |||
return XSSFChartDataFactory.getInstance(); | |||
} | |||
@Removal(version = "4.2") | |||
public XSSFChartDataFactory getChartDataFactory() { | |||
return XSSFChartDataFactory.getInstance(); | |||
} | |||
@Override | |||
@Deprecated | |||
@Removal(version="4.2") | |||
public XSSFChart getChartAxisFactory() { | |||
return this; | |||
} | |||
@Removal(version = "4.2") | |||
public XSSFChart getChartAxisFactory() { | |||
return this; | |||
} | |||
@Override | |||
@Deprecated | |||
@Removal(version="4.2") | |||
public void plot(ChartData data, ChartAxis... chartAxis) { | |||
data.fillChart(this, chartAxis); | |||
} | |||
@Removal(version = "4.2") | |||
public void plot(ChartData data, ChartAxis... chartAxis) { | |||
data.fillChart(this, chartAxis); | |||
} | |||
@Override | |||
@Deprecated | |||
@Removal(version="4.2") | |||
public XSSFValueAxis createValueAxis(org.apache.poi.ss.usermodel.charts.AxisPosition pos) { | |||
long id = axis.size() + 1; | |||
XSSFValueAxis valueAxis = new XSSFValueAxis(this, id, pos); | |||
if (axis.size() == 1) { | |||
ChartAxis ax = axis.get(0); | |||
ax.crossAxis(valueAxis); | |||
valueAxis.crossAxis(ax); | |||
} | |||
axis.add(valueAxis); | |||
return valueAxis; | |||
} | |||
@Removal(version = "4.2") | |||
public XSSFValueAxis createValueAxis(org.apache.poi.ss.usermodel.charts.AxisPosition pos) { | |||
long id = axis.size() + 1; | |||
XSSFValueAxis valueAxis = new XSSFValueAxis(this, id, pos); | |||
if (axis.size() == 1) { | |||
ChartAxis ax = axis.get(0); | |||
ax.crossAxis(valueAxis); | |||
valueAxis.crossAxis(ax); | |||
} | |||
axis.add(valueAxis); | |||
return valueAxis; | |||
} | |||
@Override | |||
@Deprecated | |||
@Removal(version="4.2") | |||
public XSSFCategoryAxis createCategoryAxis(org.apache.poi.ss.usermodel.charts.AxisPosition pos) { | |||
long id = axis.size() + 1; | |||
XSSFCategoryAxis categoryAxis = new XSSFCategoryAxis(this, id, pos); | |||
if (axis.size() == 1) { | |||
ChartAxis ax = axis.get(0); | |||
ax.crossAxis(categoryAxis); | |||
categoryAxis.crossAxis(ax); | |||
} | |||
axis.add(categoryAxis); | |||
return categoryAxis; | |||
} | |||
@Removal(version = "4.2") | |||
public XSSFCategoryAxis createCategoryAxis(org.apache.poi.ss.usermodel.charts.AxisPosition pos) { | |||
long id = axis.size() + 1; | |||
XSSFCategoryAxis categoryAxis = new XSSFCategoryAxis(this, id, pos); | |||
if (axis.size() == 1) { | |||
ChartAxis ax = axis.get(0); | |||
ax.crossAxis(categoryAxis); | |||
categoryAxis.crossAxis(ax); | |||
} | |||
axis.add(categoryAxis); | |||
return categoryAxis; | |||
} | |||
@Override | |||
@Deprecated | |||
@Removal(version="4.2") | |||
public XSSFDateAxis createDateAxis(org.apache.poi.ss.usermodel.charts.AxisPosition pos) { | |||
long id = axis.size() + 1; | |||
XSSFDateAxis dateAxis = new XSSFDateAxis(this, id, pos); | |||
if (axis.size() == 1) { | |||
ChartAxis ax = axis.get(0); | |||
ax.crossAxis(dateAxis); | |||
dateAxis.crossAxis(ax); | |||
} | |||
axis.add(dateAxis); | |||
return dateAxis; | |||
} | |||
@Removal(version = "4.2") | |||
public XSSFDateAxis createDateAxis(org.apache.poi.ss.usermodel.charts.AxisPosition pos) { | |||
long id = axis.size() + 1; | |||
XSSFDateAxis dateAxis = new XSSFDateAxis(this, id, pos); | |||
if (axis.size() == 1) { | |||
ChartAxis ax = axis.get(0); | |||
ax.crossAxis(dateAxis); | |||
dateAxis.crossAxis(ax); | |||
} | |||
axis.add(dateAxis); | |||
return dateAxis; | |||
} | |||
/** | |||
* @deprecated use {@link #getAxes()} instead | |||
*/ | |||
@Override | |||
@Deprecated | |||
@Removal(version="4.2") | |||
@Removal(version = "4.2") | |||
public List<? extends XSSFChartAxis> getAxis() { | |||
if (axis.isEmpty() && hasAxis()) { | |||
parseAxis(); | |||
@@ -250,56 +255,57 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor | |||
@Override | |||
@Deprecated | |||
@Removal(version="4.2") | |||
public XSSFManualLayout getManualLayout() { | |||
return new XSSFManualLayout(this); | |||
} | |||
/** | |||
* Returns the title static text, or null if none is set. | |||
* Note that a title formula may be set instead. | |||
* @return static title text, if set | |||
* @deprecated POI 3.16, use {@link #getTitleText()} instead. | |||
*/ | |||
@Removal(version = "4.2") | |||
public XSSFManualLayout getManualLayout() { | |||
return new XSSFManualLayout(this); | |||
} | |||
/** | |||
* Returns the title static text, or null if none is set. Note that a title | |||
* formula may be set instead. | |||
* | |||
* @return static title text, if set | |||
* @deprecated POI 3.16, use {@link #getTitleText()} instead. | |||
*/ | |||
@Deprecated | |||
@Removal(version="4.0") | |||
public XSSFRichTextString getTitle() { | |||
return getTitleText(); | |||
} | |||
/** | |||
* Returns the title static text, or null if none is set. | |||
* Note that a title formula may be set instead. | |||
* Empty text result is for backward compatibility, and could mean the title text is empty or there is a formula instead. | |||
* Check for a formula first, falling back on text for cleaner logic. | |||
* @return static title text if set, | |||
* null if there is no title, | |||
* empty string if the title text is empty or the title uses a formula instead | |||
*/ | |||
public XSSFRichTextString getTitleText() { | |||
if(! chart.isSetTitle()) { | |||
return null; | |||
} | |||
// TODO Do properly | |||
CTTitle title = chart.getTitle(); | |||
StringBuilder text = new StringBuilder(64); | |||
XmlObject[] t = title | |||
.selectPath("declare namespace a='"+XSSFDrawing.NAMESPACE_A+"' .//a:t"); | |||
for (XmlObject element : t) { | |||
NodeList kids = element.getDomNode().getChildNodes(); | |||
final int count = kids.getLength(); | |||
for (int n = 0; n < count; n++) { | |||
Node kid = kids.item(n); | |||
if (kid instanceof Text) { | |||
text.append(kid.getNodeValue()); | |||
} | |||
} | |||
} | |||
return new XSSFRichTextString(text.toString()); | |||
} | |||
@Removal(version = "4.0") | |||
public XSSFRichTextString getTitle() { | |||
return getTitleText(); | |||
} | |||
/** | |||
* Returns the title static text, or null if none is set. Note that a title | |||
* formula may be set instead. Empty text result is for backward | |||
* compatibility, and could mean the title text is empty or there is a | |||
* formula instead. Check for a formula first, falling back on text for | |||
* cleaner logic. | |||
* | |||
* @return static title text if set, null if there is no title, empty string | |||
* if the title text is empty or the title uses a formula instead | |||
*/ | |||
public XSSFRichTextString getTitleText() { | |||
if (!chart.isSetTitle()) { | |||
return null; | |||
} | |||
// TODO Do properly | |||
CTTitle title = chart.getTitle(); | |||
StringBuilder text = new StringBuilder(64); | |||
XmlObject[] t = title.selectPath("declare namespace a='" + XSSFDrawing.NAMESPACE_A + "' .//a:t"); | |||
for (XmlObject element : t) { | |||
NodeList kids = element.getDomNode().getChildNodes(); | |||
final int count = kids.getLength(); | |||
for (int n = 0; n < count; n++) { | |||
Node kid = kids.item(n); | |||
if (kid instanceof Text) { | |||
text.append(kid.getNodeValue()); | |||
} | |||
} | |||
} | |||
return new XSSFRichTextString(text.toString()); | |||
} | |||
/** | |||
* Sets the title text as a static string. | |||
@@ -331,7 +337,8 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor | |||
rich = tx.getRich(); | |||
} else { | |||
rich = tx.addNewRich(); | |||
rich.addNewBodyPr(); // body properties must exist (but can be empty) | |||
rich.addNewBodyPr(); // body properties must exist (but can be | |||
// empty) | |||
} | |||
CTTextParagraph para; | |||
@@ -414,21 +421,22 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor | |||
@Override | |||
@Deprecated | |||
@Removal(version="4.2") | |||
public XSSFChartLegend getOrCreateLegend() { | |||
return new XSSFChartLegend(this); | |||
} | |||
@Deprecated | |||
@Removal(version="4.2") | |||
private boolean hasAxis() { | |||
@Removal(version = "4.2") | |||
public XSSFChartLegend getOrCreateLegend() { | |||
return new XSSFChartLegend(this); | |||
} | |||
@Deprecated | |||
@Removal(version = "4.2") | |||
private boolean hasAxis() { | |||
CTPlotArea ctPlotArea = chart.getPlotArea(); | |||
int totalAxisCount = ctPlotArea.sizeOfValAxArray() + ctPlotArea.sizeOfCatAxArray() + ctPlotArea.sizeOfDateAxArray() + ctPlotArea.sizeOfSerAxArray(); | |||
int totalAxisCount = ctPlotArea.sizeOfValAxArray() + ctPlotArea.sizeOfCatAxArray() + ctPlotArea | |||
.sizeOfDateAxArray() + ctPlotArea.sizeOfSerAxArray(); | |||
return totalAxisCount > 0; | |||
} | |||
} | |||
@Deprecated | |||
@Removal(version="4.2") | |||
@Removal(version = "4.2") | |||
private void parseAxis() { | |||
// TODO: add other axis types | |||
parseCategoryAxis(); | |||
@@ -437,7 +445,7 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor | |||
} | |||
@Deprecated | |||
@Removal(version="4.2") | |||
@Removal(version = "4.2") | |||
private void parseCategoryAxis() { | |||
for (CTCatAx catAx : chart.getPlotArea().getCatAxArray()) { | |||
axis.add(new XSSFCategoryAxis(this, catAx)); | |||
@@ -445,7 +453,7 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor | |||
} | |||
@Deprecated | |||
@Removal(version="4.2") | |||
@Removal(version = "4.2") | |||
private void parseDateAxis() { | |||
for (CTDateAx dateAx : chart.getPlotArea().getDateAxArray()) { | |||
axis.add(new XSSFDateAxis(this, dateAx)); | |||
@@ -453,7 +461,7 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor | |||
} | |||
@Deprecated | |||
@Removal(version="4.2") | |||
@Removal(version = "4.2") | |||
private void parseValueAxis() { | |||
for (CTValAx valAx : chart.getPlotArea().getValAxArray()) { | |||
axis.add(new XSSFValueAxis(this, valAx)); |
@@ -103,7 +103,7 @@ public final class XSSFShapeGroup extends XSSFShape implements ShapeContainer<XS | |||
XSSFTextBox shape = new XSSFTextBox(getDrawing(), ctShape); | |||
shape.parent = this; | |||
shape.anchor = anchor; | |||
shape.getCTShape().getSpPr().setXfrm(anchor.getCTTransform2D()); | |||
shape.setXfrm(anchor.getCTTransform2D()); | |||
return shape; | |||
} | |||
@@ -122,7 +122,7 @@ public final class XSSFShapeGroup extends XSSFShape implements ShapeContainer<XS | |||
XSSFSimpleShape shape = new XSSFSimpleShape(getDrawing(), ctShape); | |||
shape.parent = this; | |||
shape.anchor = anchor; | |||
shape.getCTShape().getSpPr().setXfrm(anchor.getCTTransform2D()); | |||
shape.setXfrm(anchor.getCTTransform2D()); | |||
return shape; | |||
} | |||
@@ -179,9 +179,9 @@ public final class XSSFShapeGroup extends XSSFShape implements ShapeContainer<XS | |||
XSSFShapeGroup shape = new XSSFShapeGroup(getDrawing(), ctShape); | |||
shape.parent = this; | |||
shape.anchor = anchor; | |||
// TODO: calculate bounding rectangle on anchor and set off/ext correctly | |||
CTGroupTransform2D xfrm = shape.getCTGroupShape().getGrpSpPr().getXfrm(); | |||
CTTransform2D t2 = anchor.getCTTransform2D(); | |||
xfrm.setOff(t2.getOff()); | |||
@@ -190,7 +190,7 @@ public final class XSSFShapeGroup extends XSSFShape implements ShapeContainer<XS | |||
xfrm.setChExt(t2.getExt()); | |||
xfrm.setFlipH(t2.getFlipH()); | |||
xfrm.setFlipV(t2.getFlipV()); | |||
return shape; | |||
} | |||
@@ -220,6 +220,7 @@ public final class XSSFShapeGroup extends XSSFShape implements ShapeContainer<XS | |||
chExt.setCy(y2); | |||
} | |||
@Override | |||
protected CTShapeProperties getShapeProperties() { | |||
throw new IllegalStateException("Not supported for shape group"); | |||
} |
@@ -0,0 +1,81 @@ | |||
/* ==================================================================== | |||
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.xddf.usermodel.text; | |||
import static org.junit.Assert.assertEquals; | |||
import static org.junit.Assert.assertFalse; | |||
import static org.junit.Assert.assertTrue; | |||
import java.io.IOException; | |||
import org.apache.poi.util.Units; | |||
import org.junit.Test; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBodyProperties; | |||
public class TestXDDFTextBodyProperties { | |||
@Test | |||
public void testProperties() throws IOException { | |||
XDDFBodyProperties body = new XDDFTextBody(null).getBodyProperties(); | |||
CTTextBodyProperties props = body.getXmlObject(); | |||
body.setBottomInset(null); | |||
assertFalse(props.isSetBIns()); | |||
body.setBottomInset(3.6); | |||
assertTrue(props.isSetBIns()); | |||
assertEquals(Units.toEMU(3.6), props.getBIns()); | |||
body.setLeftInset(null); | |||
assertFalse(props.isSetLIns()); | |||
body.setLeftInset(3.6); | |||
assertTrue(props.isSetLIns()); | |||
assertEquals(Units.toEMU(3.6), props.getLIns()); | |||
body.setRightInset(null); | |||
assertFalse(props.isSetRIns()); | |||
body.setRightInset(3.6); | |||
assertTrue(props.isSetRIns()); | |||
assertEquals(Units.toEMU(3.6), props.getRIns()); | |||
body.setTopInset(null); | |||
assertFalse(props.isSetTIns()); | |||
body.setTopInset(3.6); | |||
assertTrue(props.isSetTIns()); | |||
assertEquals(Units.toEMU(3.6), props.getTIns()); | |||
body.setAutoFit(null); | |||
assertFalse(props.isSetNoAutofit()); | |||
assertFalse(props.isSetNormAutofit()); | |||
assertFalse(props.isSetSpAutoFit()); | |||
body.setAutoFit(new XDDFNoAutoFit()); | |||
assertTrue(props.isSetNoAutofit()); | |||
assertFalse(props.isSetNormAutofit()); | |||
assertFalse(props.isSetSpAutoFit()); | |||
body.setAutoFit(new XDDFNormalAutoFit()); | |||
assertFalse(props.isSetNoAutofit()); | |||
assertTrue(props.isSetNormAutofit()); | |||
assertFalse(props.isSetSpAutoFit()); | |||
body.setAutoFit(new XDDFShapeAutoFit()); | |||
assertFalse(props.isSetNoAutofit()); | |||
assertFalse(props.isSetNormAutofit()); | |||
assertTrue(props.isSetSpAutoFit()); | |||
} | |||
} |
@@ -0,0 +1,135 @@ | |||
/* ==================================================================== | |||
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.xddf.usermodel.text; | |||
import static org.junit.Assert.assertEquals; | |||
import static org.junit.Assert.assertFalse; | |||
import static org.junit.Assert.assertNotNull; | |||
import static org.junit.Assert.assertNull; | |||
import static org.junit.Assert.assertTrue; | |||
import java.io.IOException; | |||
import java.util.List; | |||
import org.apache.poi.util.LocaleUtil; | |||
import org.apache.poi.xslf.usermodel.XMLSlideShow; | |||
import org.apache.poi.xslf.usermodel.XSLFSlide; | |||
import org.apache.poi.xslf.usermodel.XSLFTextShape; | |||
import org.apache.poi.xssf.usermodel.XSSFClientAnchor; | |||
import org.apache.poi.xssf.usermodel.XSSFDrawing; | |||
import org.apache.poi.xssf.usermodel.XSSFSheet; | |||
import org.apache.poi.xssf.usermodel.XSSFTextBox; | |||
import org.apache.poi.xssf.usermodel.XSSFWorkbook; | |||
import org.junit.Test; | |||
public class TestXDDFTextRun { | |||
@Test | |||
public void testTextRunPropertiesInSlide() throws IOException { | |||
try (XMLSlideShow ppt = new XMLSlideShow()) { | |||
XSLFSlide slide = ppt.createSlide(); | |||
XSLFTextShape sh = slide.createAutoShape(); | |||
sh.addNewTextParagraph(); | |||
XDDFTextBody body = sh.getTextBody(); | |||
XDDFTextParagraph para = body.getParagraph(0); | |||
XDDFTextRun r = para.appendRegularRun("text"); | |||
assertEquals(LocaleUtil.getUserLocale().toLanguageTag(), r.getLanguage().toLanguageTag()); | |||
assertNull(r.getCharacterSpacing()); | |||
r.setCharacterSpacing(3.0); | |||
assertEquals(3., r.getCharacterSpacing(), 0); | |||
r.setCharacterSpacing(-3.0); | |||
assertEquals(-3., r.getCharacterSpacing(), 0); | |||
r.setCharacterSpacing(0.0); | |||
assertEquals(0., r.getCharacterSpacing(), 0); | |||
assertEquals(11.0, r.getFontSize(), 0); | |||
r.setFontSize(13.0); | |||
assertEquals(13.0, r.getFontSize(), 0); | |||
assertFalse(r.isSuperscript()); | |||
r.setSuperscript(0.8); | |||
assertTrue(r.isSuperscript()); | |||
r.setSuperscript(null); | |||
assertFalse(r.isSuperscript()); | |||
assertFalse(r.isSubscript()); | |||
r.setSubscript(0.7); | |||
assertTrue(r.isSubscript()); | |||
r.setSubscript(null); | |||
assertFalse(r.isSubscript()); | |||
r.setBaseline(0.9); | |||
assertTrue(r.isSuperscript()); | |||
r.setBaseline(-0.6); | |||
assertTrue(r.isSubscript()); | |||
} | |||
} | |||
@Test | |||
public void testTextRunPropertiesInSheet() throws IOException { | |||
try (XSSFWorkbook wb = new XSSFWorkbook()) { | |||
XSSFSheet sheet = wb.createSheet(); | |||
XSSFDrawing drawing = sheet.createDrawingPatriarch(); | |||
XSSFTextBox shape = drawing.createTextbox(new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 4)); | |||
shape.addNewTextParagraph().addNewTextRun().setText("Line 1"); | |||
XDDFTextBody body = shape.getTextBody(); | |||
XDDFTextParagraph para = body.getParagraph(1); | |||
List<XDDFTextRun> runs = para.getTextRuns(); | |||
assertEquals(1, runs.size()); | |||
XDDFTextRun run = runs.get(0); | |||
assertEquals("Line 1", run.getText()); | |||
assertFalse(run.isStrikeThrough()); | |||
run.setStrikeThrough(StrikeType.SINGLE_STRIKE); | |||
assertTrue(run.isStrikeThrough()); | |||
run.setStrikeThrough(StrikeType.NO_STRIKE); | |||
assertFalse(run.isStrikeThrough()); | |||
assertFalse(run.isCapitals()); | |||
run.setCapitals(CapsType.SMALL); | |||
assertTrue(run.isCapitals()); | |||
run.setCapitals(CapsType.NONE); | |||
assertFalse(run.isCapitals()); | |||
assertFalse(run.isBold()); | |||
run.setBold(true); | |||
assertTrue(run.isBold()); | |||
run.setBold(false); | |||
assertFalse(run.isBold()); | |||
assertFalse(run.isItalic()); | |||
run.setItalic(true); | |||
assertTrue(run.isItalic()); | |||
run.setItalic(false); | |||
assertFalse(run.isItalic()); | |||
assertFalse(run.isUnderline()); | |||
run.setUnderline(UnderlineType.WAVY_DOUBLE); | |||
assertTrue(run.isUnderline()); | |||
run.setUnderline(UnderlineType.NONE); | |||
assertFalse(run.isUnderline()); | |||
assertNotNull(run.getText()); | |||
} | |||
} | |||
} |
@@ -30,6 +30,7 @@ import java.awt.Color; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.util.List; | |||
import java.util.stream.Collectors; | |||
import org.apache.poi.POIDataSamples; | |||
import org.apache.poi.hslf.usermodel.HSLFTextShape; | |||
@@ -38,6 +39,8 @@ import org.apache.poi.sl.usermodel.SlideShow; | |||
import org.apache.poi.sl.usermodel.SlideShowFactory; | |||
import org.apache.poi.sl.usermodel.TextParagraph.TextAlign; | |||
import org.apache.poi.sl.usermodel.VerticalAlignment; | |||
import org.apache.poi.xddf.usermodel.text.XDDFBodyProperties; | |||
import org.apache.poi.xddf.usermodel.text.XDDFTextBody; | |||
import org.apache.poi.xslf.XSLFTestDataSamples; | |||
import org.junit.BeforeClass; | |||
import org.junit.Test; | |||
@@ -83,6 +86,8 @@ public class TestXSLFTextShape { | |||
assertEquals("Title Slide",layout.getName()); | |||
XSLFTextShape shape1 = (XSLFTextShape)shapes.get(0); | |||
XDDFTextBody tb1 = shape1.getTextBody(); | |||
XDDFBodyProperties tbp1 = tb1.getBodyProperties(); | |||
CTPlaceholder ph1 = shape1.getPlaceholderDetails().getCTPlaceholder(false); | |||
assertEquals(STPlaceholderType.CTR_TITLE, ph1.getType()); | |||
// anchor is not defined in the shape | |||
@@ -104,15 +109,24 @@ public class TestXSLFTextShape { | |||
assertEquals(3.6, shape1.getTopInset(), 0); // 0.05" | |||
assertEquals(3.6, shape1.getBottomInset(), 0); // 0.05" | |||
assertEquals(VerticalAlignment.MIDDLE, shape1.getVerticalAlignment()); | |||
assertNull(tbp1.getLeftInset()); | |||
assertNull(tbp1.getRightInset()); | |||
assertNull(tbp1.getBottomInset()); | |||
assertNull(tbp1.getTopInset()); | |||
assertNull(tbp1.getAnchoring()); | |||
// now check text properties | |||
assertEquals("Centered Title", shape1.getText()); | |||
assertEquals("Centered Title", | |||
tb1.getParagraphs().stream().map(p -> p.getText()).collect(Collectors.joining("\n"))); | |||
XSLFTextRun r1 = shape1.getTextParagraphs().get(0).getTextRuns().get(0); | |||
assertEquals("Calibri", r1.getFontFamily()); | |||
assertEquals(44.0, r1.getFontSize(), 0); | |||
assertTrue(sameColor(Color.black, r1.getFontColor())); | |||
XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1); | |||
XDDFTextBody tb2 = shape2.getTextBody(); | |||
XDDFBodyProperties tbp2 = tb2.getBodyProperties(); | |||
CTPlaceholder ph2 = shape2.getPlaceholderDetails().getCTPlaceholder(false); | |||
assertEquals(STPlaceholderType.SUB_TITLE, ph2.getType()); | |||
// anchor is not defined in the shape | |||
@@ -134,8 +148,14 @@ public class TestXSLFTextShape { | |||
assertEquals(3.6, shape2.getTopInset(), 0); // 0.05" | |||
assertEquals(3.6, shape2.getBottomInset(), 0); // 0.05" | |||
assertEquals(VerticalAlignment.TOP, shape2.getVerticalAlignment()); | |||
assertNull(tbp2.getLeftInset()); | |||
assertNull(tbp2.getRightInset()); | |||
assertNull(tbp2.getBottomInset()); | |||
assertNull(tbp2.getTopInset()); | |||
assertNull(tbp2.getAnchoring()); | |||
assertEquals("subtitle", shape2.getText()); | |||
assertEquals("subtitle", tb2.getParagraphs().stream().map(p -> p.getText()).collect(Collectors.joining("\n"))); | |||
XSLFTextRun r2 = shape2.getTextParagraphs().get(0).getTextRuns().get(0); | |||
assertEquals("Calibri", r2.getFontFamily()); | |||
assertEquals(32.0, r2.getFontSize(), 0); |
@@ -16,12 +16,23 @@ | |||
==================================================================== */ | |||
package org.apache.poi.xssf.usermodel; | |||
import static org.junit.Assert.*; | |||
import static org.junit.Assert.assertEquals; | |||
import static org.junit.Assert.assertFalse; | |||
import static org.junit.Assert.assertNotNull; | |||
import static org.junit.Assert.assertNull; | |||
import static org.junit.Assert.assertTrue; | |||
import java.awt.Color; | |||
import java.io.IOException; | |||
import java.util.List; | |||
import org.apache.poi.ss.usermodel.VerticalAlignment; | |||
import org.apache.poi.xddf.usermodel.text.XDDFBodyProperties; | |||
import org.apache.poi.xddf.usermodel.text.XDDFNoAutoFit; | |||
import org.apache.poi.xddf.usermodel.text.XDDFNormalAutoFit; | |||
import org.apache.poi.xddf.usermodel.text.XDDFShapeAutoFit; | |||
import org.apache.poi.xddf.usermodel.text.XDDFTextBody; | |||
import org.apache.poi.xddf.usermodel.text.XDDFTextParagraph; | |||
import org.junit.Test; | |||
public class TestXSSFSimpleShape { | |||
@@ -31,43 +42,53 @@ public class TestXSSFSimpleShape { | |||
try { | |||
XSSFSheet sheet = wb.createSheet(); | |||
XSSFDrawing drawing = sheet.createDrawingPatriarch(); | |||
XSSFTextBox shape = drawing.createTextbox(new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 4)); | |||
XSSFRichTextString rt = new XSSFRichTextString("Test String"); | |||
XSSFFont font = wb.createFont(); | |||
Color color = new Color(0, 255, 255); | |||
font.setColor(new XSSFColor(color, wb.getStylesSource().getIndexedColors())); | |||
font.setFontName("Arial"); | |||
rt.applyFont(font); | |||
shape.setText(rt); | |||
assertNotNull(shape.getCTShape()); | |||
assertNotNull(shape.iterator()); | |||
assertNotNull(XSSFSimpleShape.prototype()); | |||
for(ListAutoNumber nr : ListAutoNumber.values()) { | |||
for (ListAutoNumber nr : ListAutoNumber.values()) { | |||
shape.getTextParagraphs().get(0).setBullet(nr); | |||
assertNotNull(shape.getText()); | |||
} | |||
shape.getTextParagraphs().get(0).setBullet(false); | |||
assertNotNull(shape.getText()); | |||
shape.setText("testtext"); | |||
assertEquals("testtext", shape.getText()); | |||
shape.setText(new XSSFRichTextString()); | |||
assertEquals("null", shape.getText()); | |||
shape.addNewTextParagraph(); | |||
shape.addNewTextParagraph("test-other-text"); | |||
shape.addNewTextParagraph(new XSSFRichTextString("rtstring")); | |||
shape.addNewTextParagraph(new XSSFRichTextString()); | |||
assertEquals("null\n\ntest-other-text\nrtstring\nnull", shape.getText()); | |||
XDDFTextBody body = shape.getTextBody(); | |||
assertNotNull(body); | |||
List<XDDFTextParagraph> paragraphs = body.getParagraphs(); | |||
assertEquals(5, paragraphs.size()); | |||
assertEquals("null", body.getParagraph(0).getText()); | |||
assertEquals("", body.getParagraph(1).getText()); | |||
assertEquals("test-other-text", body.getParagraph(2).getText()); | |||
assertEquals("rtstring", body.getParagraph(3).getText()); | |||
assertEquals("null", body.getParagraph(4).getText()); | |||
assertEquals(TextHorizontalOverflow.OVERFLOW, shape.getTextHorizontalOverflow()); | |||
shape.setTextHorizontalOverflow(TextHorizontalOverflow.CLIP); | |||
assertEquals(TextHorizontalOverflow.CLIP, shape.getTextHorizontalOverflow()); | |||
@@ -77,7 +98,7 @@ public class TestXSSFSimpleShape { | |||
assertEquals(TextHorizontalOverflow.OVERFLOW, shape.getTextHorizontalOverflow()); | |||
shape.setTextHorizontalOverflow(null); | |||
assertEquals(TextHorizontalOverflow.OVERFLOW, shape.getTextHorizontalOverflow()); | |||
assertEquals(TextVerticalOverflow.OVERFLOW, shape.getTextVerticalOverflow()); | |||
shape.setTextVerticalOverflow(TextVerticalOverflow.CLIP); | |||
assertEquals(TextVerticalOverflow.CLIP, shape.getTextVerticalOverflow()); | |||
@@ -108,38 +129,57 @@ public class TestXSSFSimpleShape { | |||
shape.setTextDirection(null); | |||
assertEquals(TextDirection.HORIZONTAL, shape.getTextDirection()); | |||
XDDFBodyProperties props = body.getBodyProperties(); | |||
assertNotNull(props); | |||
assertEquals(3.6, shape.getBottomInset(), 0.01); | |||
assertNull(props.getBottomInset()); | |||
shape.setBottomInset(12.32); | |||
assertEquals(12.32, shape.getBottomInset(), 0.01); | |||
assertEquals(12.32, props.getBottomInset(), 0.01); | |||
shape.setBottomInset(-1); | |||
assertEquals(3.6, shape.getBottomInset(), 0.01); | |||
assertNull(props.getBottomInset()); | |||
shape.setBottomInset(-1); | |||
assertEquals(3.6, shape.getBottomInset(), 0.01); | |||
assertNull(props.getBottomInset()); | |||
assertEquals(3.6, shape.getLeftInset(), 0.01); | |||
assertNull(props.getLeftInset()); | |||
shape.setLeftInset(12.31); | |||
assertEquals(12.31, shape.getLeftInset(), 0.01); | |||
assertEquals(12.31, props.getLeftInset(), 0.01); | |||
shape.setLeftInset(-1); | |||
assertEquals(3.6, shape.getLeftInset(), 0.01); | |||
assertNull(props.getLeftInset()); | |||
shape.setLeftInset(-1); | |||
assertEquals(3.6, shape.getLeftInset(), 0.01); | |||
assertNull(props.getLeftInset()); | |||
assertEquals(3.6, shape.getRightInset(), 0.01); | |||
assertNull(props.getRightInset()); | |||
shape.setRightInset(13.31); | |||
assertEquals(13.31, shape.getRightInset(), 0.01); | |||
assertEquals(13.31, props.getRightInset(), 0.01); | |||
shape.setRightInset(-1); | |||
assertEquals(3.6, shape.getRightInset(), 0.01); | |||
assertNull(props.getRightInset()); | |||
shape.setRightInset(-1); | |||
assertEquals(3.6, shape.getRightInset(), 0.01); | |||
assertNull(props.getRightInset()); | |||
assertEquals(3.6, shape.getTopInset(), 0.01); | |||
assertNull(props.getTopInset()); | |||
shape.setTopInset(23.31); | |||
assertEquals(23.31, shape.getTopInset(), 0.01); | |||
assertEquals(23.31, props.getTopInset(), 0.01); | |||
shape.setTopInset(-1); | |||
assertEquals(3.6, shape.getTopInset(), 0.01); | |||
assertNull(props.getTopInset()); | |||
shape.setTopInset(-1); | |||
assertEquals(3.6, shape.getTopInset(), 0.01); | |||
assertNull(props.getTopInset()); | |||
assertTrue(shape.getWordWrap()); | |||
shape.setWordWrap(false); | |||
assertFalse(shape.getWordWrap()); | |||
@@ -147,23 +187,27 @@ public class TestXSSFSimpleShape { | |||
assertTrue(shape.getWordWrap()); | |||
assertEquals(TextAutofit.NORMAL, shape.getTextAutofit()); | |||
assertTrue(props.getAutoFit() instanceof XDDFNormalAutoFit); | |||
shape.setTextAutofit(TextAutofit.NORMAL); | |||
assertEquals(TextAutofit.NORMAL, shape.getTextAutofit()); | |||
assertTrue(props.getAutoFit() instanceof XDDFNormalAutoFit); | |||
shape.setTextAutofit(TextAutofit.SHAPE); | |||
assertEquals(TextAutofit.SHAPE, shape.getTextAutofit()); | |||
assertTrue(props.getAutoFit() instanceof XDDFShapeAutoFit); | |||
shape.setTextAutofit(TextAutofit.NONE); | |||
assertEquals(TextAutofit.NONE, shape.getTextAutofit()); | |||
assertTrue(props.getAutoFit() instanceof XDDFNoAutoFit); | |||
assertEquals(5, shape.getShapeType()); | |||
shape.setShapeType(23); | |||
assertEquals(23, shape.getShapeType()); | |||
// TODO: should this be supported? | |||
// shape.setShapeType(-1); | |||
// assertEquals(-1, shape.getShapeType()); | |||
// shape.setShapeType(-1); | |||
// assertEquals(-1, shape.getShapeType()); | |||
// shape.setShapeType(-1); | |||
// assertEquals(-1, shape.getShapeType()); | |||
// shape.setShapeType(-1); | |||
// assertEquals(-1, shape.getShapeType()); | |||
assertNotNull(shape.getShapeProperties()); | |||
} finally { | |||
wb.close(); |