From e1241ed9752b7bc5c46cc774fab3ec3874aa8ab3 Mon Sep 17 00:00:00 2001 From: Andreas Beeker Date: Sat, 18 Jun 2016 23:48:00 +0000 Subject: [PATCH] #59702 - Setting background color in slide master git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1749108 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/xslf/usermodel/XSLFBackground.java | 79 +- .../poi/xslf/usermodel/XSLFFreeformShape.java | 17 +- .../usermodel/XSLFPropertiesDelegate.java | 1830 +++++++++++++++++ .../apache/poi/xslf/usermodel/XSLFShape.java | 200 +- .../poi/xslf/usermodel/XSLFSimpleShape.java | 571 +++-- .../poi/xslf/usermodel/XSLFTableCell.java | 76 +- .../poi/xslf/usermodel/XSLFTextRun.java | 47 +- .../apache/poi/xslf/TestXSLFSlideShow.java | 27 + .../usermodel/TestXSLFConnectorShape.java | 52 +- .../xslf/usermodel/TestXSLFFreeformShape.java | 7 +- .../xslf/usermodel/TestXSLFSimpleShape.java | 97 +- .../poi/xslf/usermodel/TestXSLFTextShape.java | 49 +- 12 files changed, 2553 insertions(+), 499 deletions(-) create mode 100644 src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPropertiesDelegate.java diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFBackground.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFBackground.java index 290b5f494..1eac4b277 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFBackground.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFBackground.java @@ -22,20 +22,16 @@ import java.awt.Dimension; import java.awt.geom.Rectangle2D; import org.apache.poi.POIXMLException; -import org.apache.poi.sl.draw.DrawPaint; import org.apache.poi.sl.usermodel.Background; -import org.apache.poi.sl.usermodel.ColorStyle; -import org.apache.poi.sl.usermodel.FillStyle; -import org.apache.poi.sl.usermodel.PaintStyle; import org.apache.poi.sl.usermodel.Placeholder; -import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; +import org.apache.xmlbeans.XmlObject; +import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties; import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D; import org.openxmlformats.schemas.presentationml.x2006.main.CTBackground; +import org.openxmlformats.schemas.presentationml.x2006.main.CTBackgroundProperties; /** * Background shape - * - * @author Yegor Kozlov */ public class XSLFBackground extends XSLFSimpleShape implements Background { @@ -50,27 +46,16 @@ public class XSLFBackground extends XSLFSimpleShape return new Rectangle2D.Double(0, 0, pg.getWidth(), pg.getHeight()); } - @Override - public Color getFillColor(){ - FillStyle fs = getFillStyle(); - PaintStyle ps = fs.getPaint(); - if (ps instanceof SolidPaint) { - SolidPaint sp = (SolidPaint)ps; - ColorStyle cs = sp.getSolidColor(); - return DrawPaint.applyColorTransform(cs); - } - return null; - } - /** - * background does not have a associated transform. - * we return a dummy transform object to prevent exceptions in inherited methods. + * background does not have a associated transform, therefore we return null + * + * @param create ignored * - * @return dummy CTTransform2D bean + * @return null */ @Override - protected CTTransform2D getXfrm() { - return CTTransform2D.Factory.newInstance(); + protected CTTransform2D getXfrm(boolean create) { + return null; } @Override @@ -78,4 +63,50 @@ public class XSLFBackground extends XSLFSimpleShape // extending XSLFSimpleShape is a bit unlucky ... throw new POIXMLException("Can't set a placeholder for a background"); } + + protected CTBackgroundProperties getBgPr(boolean create) { + CTBackground bg = (CTBackground)getXmlObject(); + if (!bg.isSetBgPr() && create) { + if (bg.isSetBgRef()) { + bg.unsetBgRef(); + } + return bg.addNewBgPr(); + } + return bg.getBgPr(); + } + + public void setFillColor(Color color) { + CTBackgroundProperties bgPr = getBgPr(true); + + if (color == null) { + if (bgPr.isSetSolidFill()) { + bgPr.unsetSolidFill(); + } + + if (!bgPr.isSetNoFill()) { + bgPr.addNewNoFill(); + } + } else { + if (bgPr.isSetNoFill()) { + bgPr.unsetNoFill(); + } + + CTSolidColorFillProperties fill = bgPr.isSetSolidFill() ? bgPr.getSolidFill() : bgPr.addNewSolidFill(); + + XSLFColor col = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr()); + col.setColor(color); + } + } + + @Override + protected XmlObject getShapeProperties() { + CTBackground bg = (CTBackground)getXmlObject(); + if (bg.isSetBgPr()) { + return bg.getBgPr(); + } else if (bg.isSetBgRef()) { + return bg.getBgRef(); + } else { + return null; + } + } } diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFreeformShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFreeformShape.java index 0e9e741b3..3e482d3ea 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFreeformShape.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFreeformShape.java @@ -45,8 +45,6 @@ import org.openxmlformats.schemas.presentationml.x2006.main.CTShapeNonVisual; /** * Represents a custom geometric shape. * This shape will consist of a series of lines and curves described within a creation path. - * - * @author Yegor Kozlov */ @Beta public class XSLFFreeformShape extends XSLFAutoShape @@ -115,7 +113,13 @@ public class XSLFFreeformShape extends XSLFAutoShape } it.next(); } - getSpPr().getCustGeom().getPathLst().setPathArray(new CTPath2D[]{ctPath}); + + XmlObject xo = getShapeProperties(); + if (!(xo instanceof CTShapeProperties)) { + return -1; + } + + ((CTShapeProperties)xo).getCustGeom().getPathLst().setPathArray(new CTPath2D[]{ctPath}); setAnchor(bounds); return numPoints; } @@ -125,7 +129,12 @@ public class XSLFFreeformShape extends XSLFAutoShape Path2D.Double path = new Path2D.Double(); Rectangle2D bounds = getAnchor(); - CTCustomGeometry2D geom = getSpPr().getCustGeom(); + XmlObject xo = getShapeProperties(); + if (!(xo instanceof CTShapeProperties)) { + return null; + } + + CTCustomGeometry2D geom = ((CTShapeProperties)xo).getCustGeom(); for(CTPath2D spPath : geom.getPathLst().getPathArray()){ double scaleW = bounds.getWidth() / Units.toPoints(spPath.getW()); double scaleH = bounds.getHeight() / Units.toPoints(spPath.getH()); diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPropertiesDelegate.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPropertiesDelegate.java new file mode 100644 index 000000000..f6e5ad0a9 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPropertiesDelegate.java @@ -0,0 +1,1830 @@ +/* ==================================================================== + 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.xslf.usermodel; + +import org.apache.poi.util.Internal; +import org.apache.poi.util.POILogFactory; +import org.apache.poi.util.POILogger; +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.XmlObject; +import org.openxmlformats.schemas.drawingml.x2006.main.CTBlipFillProperties; +import org.openxmlformats.schemas.drawingml.x2006.main.CTCustomGeometry2D; +import org.openxmlformats.schemas.drawingml.x2006.main.CTEffectContainer; +import org.openxmlformats.schemas.drawingml.x2006.main.CTEffectList; +import org.openxmlformats.schemas.drawingml.x2006.main.CTFillProperties; +import org.openxmlformats.schemas.drawingml.x2006.main.CTGradientFillProperties; +import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupFillProperties; +import org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties; +import org.openxmlformats.schemas.drawingml.x2006.main.CTNoFillProperties; +import org.openxmlformats.schemas.drawingml.x2006.main.CTPatternFillProperties; +import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D; +import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; +import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties; +import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrixReference; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTableCellProperties; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties; +import org.openxmlformats.schemas.presentationml.x2006.main.CTBackgroundProperties; + +/** + * Internal helper class to unify property access. + * + * This class is experimental and not (yet) supposed for public usage. + * Maybe the xml schemas might be enhanced with interfaces to make this class superfluous + * + * @since POI 3.15-beta2 + */ +@Internal +/* package */ class XSLFPropertiesDelegate { + private static final POILogger LOG = POILogFactory.getLogger(XSLFPropertiesDelegate.class); + + + public static XSLFFillProperties getFillDelegate(XmlObject props) { + return getDelegate(XSLFFillProperties.class, props); + } + + public static XSLFGeometryProperties getGeometryDelegate(XmlObject props) { + return getDelegate(XSLFGeometryProperties.class, props); + } + + public static XSLFEffectProperties getEffectDelegate(XmlObject props) { + return getDelegate(XSLFEffectProperties.class, props); + } + + public interface XSLFFillProperties { + /** + * Gets the "noFill" element + */ + CTNoFillProperties getNoFill(); + + /** + * True if has "noFill" element + */ + boolean isSetNoFill(); + + /** + * Sets the "noFill" element + */ + void setNoFill(CTNoFillProperties noFill); + + /** + * Appends and returns a new empty "noFill" element + */ + CTNoFillProperties addNewNoFill(); + + /** + * Unsets the "noFill" element + */ + void unsetNoFill(); + + /** + * Gets the "solidFill" element + */ + CTSolidColorFillProperties getSolidFill(); + + /** + * True if has "solidFill" element + */ + boolean isSetSolidFill(); + + /** + * Sets the "solidFill" element + */ + void setSolidFill(CTSolidColorFillProperties solidFill); + + /** + * Appends and returns a new empty "solidFill" element + */ + CTSolidColorFillProperties addNewSolidFill(); + + /** + * Unsets the "solidFill" element + */ + void unsetSolidFill(); + + /** + * Gets the "gradFill" element + */ + CTGradientFillProperties getGradFill(); + + /** + * True if has "gradFill" element + */ + boolean isSetGradFill(); + + /** + * Sets the "gradFill" element + */ + void setGradFill(CTGradientFillProperties gradFill); + + /** + * Appends and returns a new empty "gradFill" element + */ + CTGradientFillProperties addNewGradFill(); + + /** + * Unsets the "gradFill" element + */ + void unsetGradFill(); + + /** + * Gets the "blipFill" element + */ + CTBlipFillProperties getBlipFill(); + + /** + * True if has "blipFill" element + */ + boolean isSetBlipFill(); + + /** + * Sets the "blipFill" element + */ + void setBlipFill(CTBlipFillProperties blipFill); + + /** + * Appends and returns a new empty "blipFill" element + */ + CTBlipFillProperties addNewBlipFill(); + + /** + * Unsets the "blipFill" element + */ + void unsetBlipFill(); + + /** + * Gets the "pattFill" element + */ + CTPatternFillProperties getPattFill(); + + /** + * True if has "pattFill" element + */ + boolean isSetPattFill(); + + /** + * Sets the "pattFill" element + */ + void setPattFill(CTPatternFillProperties pattFill); + + /** + * Appends and returns a new empty "pattFill" element + */ + CTPatternFillProperties addNewPattFill(); + + /** + * Unsets the "pattFill" element + */ + void unsetPattFill(); + + /** + * Gets the "grpFill" element + */ + CTGroupFillProperties getGrpFill(); + + /** + * True if has "grpFill" element + */ + boolean isSetGrpFill(); + + /** + * Sets the "grpFill" element + */ + void setGrpFill(CTGroupFillProperties grpFill); + + /** + * Appends and returns a new empty "grpFill" element + */ + CTGroupFillProperties addNewGrpFill(); + + /** + * Unsets the "grpFill" element + */ + void unsetGrpFill(); + + /** + * Helper method to unify other properties with style matrix references + * @return true, if this is a matrix style delegate + */ + boolean isSetMatrixStyle(); + + /** + * Helper method to unify other properties with style matrix references + */ + CTStyleMatrixReference getMatrixStyle(); + + /** + * Helper method to choose between fill and line style + * + * @return true, if this applies to a line + */ + boolean isLineStyle(); + } + + public interface XSLFGeometryProperties { + /** + * Gets the "custGeom" element + */ + CTCustomGeometry2D getCustGeom(); + + /** + * True if has "custGeom" element + */ + boolean isSetCustGeom(); + + /** + * Sets the "custGeom" element + */ + void setCustGeom(CTCustomGeometry2D custGeom); + + /** + * Appends and returns a new empty "custGeom" element + */ + CTCustomGeometry2D addNewCustGeom(); + + /** + * Unsets the "custGeom" element + */ + void unsetCustGeom(); + + /** + * Gets the "prstGeom" element + */ + CTPresetGeometry2D getPrstGeom(); + + /** + * True if has "prstGeom" element + */ + boolean isSetPrstGeom(); + + /** + * Sets the "prstGeom" element + */ + void setPrstGeom(CTPresetGeometry2D prstGeom); + + /** + * Appends and returns a new empty "prstGeom" element + */ + CTPresetGeometry2D addNewPrstGeom(); + + /** + * Unsets the "prstGeom" element + */ + void unsetPrstGeom(); + } + + public interface XSLFEffectProperties { + /** + * Gets the "effectLst" element + */ + CTEffectList getEffectLst(); + + /** + * True if has "effectLst" element + */ + boolean isSetEffectLst(); + + /** + * Sets the "effectLst" element + */ + void setEffectLst(CTEffectList effectLst); + + /** + * Appends and returns a new empty "effectLst" element + */ + CTEffectList addNewEffectLst(); + + /** + * Unsets the "effectLst" element + */ + void unsetEffectLst(); + + /** + * Gets the "effectDag" element + */ + CTEffectContainer getEffectDag(); + + /** + * True if has "effectDag" element + */ + boolean isSetEffectDag(); + + /** + * Sets the "effectDag" element + */ + void setEffectDag(CTEffectContainer effectDag); + + /** + * Appends and returns a new empty "effectDag" element + */ + CTEffectContainer addNewEffectDag(); + + /** + * Unsets the "effectDag" element + */ + void unsetEffectDag(); + } + + private static class ShapeDelegate implements XSLFFillProperties, XSLFGeometryProperties, XSLFEffectProperties { + final CTShapeProperties props; + + ShapeDelegate(CTShapeProperties props) { + this.props = props; + } + + @Override + public CTNoFillProperties getNoFill() { + return props.getNoFill(); + } + + @Override + public boolean isSetNoFill() { + return props.isSetNoFill(); + } + + @Override + public void setNoFill(CTNoFillProperties noFill) { + props.setNoFill(noFill); + } + + @Override + public CTNoFillProperties addNewNoFill() { + return props.addNewNoFill(); + } + + @Override + public void unsetNoFill() { + props.unsetNoFill(); + } + + @Override + public CTSolidColorFillProperties getSolidFill() { + return props.getSolidFill(); + } + + @Override + public boolean isSetSolidFill() { + return props.isSetSolidFill(); + } + + @Override + public void setSolidFill(CTSolidColorFillProperties solidFill) { + props.setSolidFill(solidFill); + } + + @Override + public CTSolidColorFillProperties addNewSolidFill() { + return props.addNewSolidFill(); + } + + @Override + public void unsetSolidFill() { + props.unsetSolidFill(); + } + + @Override + public CTGradientFillProperties getGradFill() { + return props.getGradFill(); + } + + @Override + public boolean isSetGradFill() { + return props.isSetGradFill(); + } + + @Override + public void setGradFill(CTGradientFillProperties gradFill) { + props.setGradFill(gradFill); + } + + @Override + public CTGradientFillProperties addNewGradFill() { + return props.addNewGradFill(); + } + + @Override + public void unsetGradFill() { + props.unsetGradFill(); + } + + @Override + public CTBlipFillProperties getBlipFill() { + return props.getBlipFill(); + } + + @Override + public boolean isSetBlipFill() { + return props.isSetBlipFill(); + } + + @Override + public void setBlipFill(CTBlipFillProperties blipFill) { + props.setBlipFill(blipFill); + } + + @Override + public CTBlipFillProperties addNewBlipFill() { + return props.addNewBlipFill(); + } + + @Override + public void unsetBlipFill() { + props.unsetBlipFill(); + } + + @Override + public CTPatternFillProperties getPattFill() { + return props.getPattFill(); + } + + @Override + public boolean isSetPattFill() { + return props.isSetPattFill(); + } + + @Override + public void setPattFill(CTPatternFillProperties pattFill) { + props.setPattFill(pattFill); + } + + @Override + public CTPatternFillProperties addNewPattFill() { + return props.addNewPattFill(); + } + + @Override + public void unsetPattFill() { + props.unsetPattFill(); + } + + @Override + public CTGroupFillProperties getGrpFill() { + return props.getGrpFill(); + } + + @Override + public boolean isSetGrpFill() { + return props.isSetGrpFill(); + } + + @Override + public void setGrpFill(CTGroupFillProperties grpFill) { + props.setGrpFill(grpFill); + } + + @Override + public CTGroupFillProperties addNewGrpFill() { + return props.addNewGrpFill(); + } + + @Override + public void unsetGrpFill() { + props.unsetGrpFill(); + } + + @Override + public CTCustomGeometry2D getCustGeom() { + return props.getCustGeom(); + } + + @Override + public boolean isSetCustGeom() { + return props.isSetCustGeom(); + } + + @Override + public void setCustGeom(CTCustomGeometry2D custGeom) { + props.setCustGeom(custGeom); + } + + @Override + public CTCustomGeometry2D addNewCustGeom() { + return props.addNewCustGeom(); + } + + @Override + public void unsetCustGeom() { + props.unsetCustGeom(); + } + + @Override + public CTPresetGeometry2D getPrstGeom() { + return props.getPrstGeom(); + } + + @Override + public boolean isSetPrstGeom() { + return props.isSetPrstGeom(); + } + + @Override + public void setPrstGeom(CTPresetGeometry2D prstGeom) { + props.setPrstGeom(prstGeom); + } + + @Override + public CTPresetGeometry2D addNewPrstGeom() { + return props.addNewPrstGeom(); + } + + @Override + public void unsetPrstGeom() { + props.unsetPrstGeom(); + } + + @Override + public CTEffectList getEffectLst() { + return props.getEffectLst(); + } + + @Override + public boolean isSetEffectLst() { + return props.isSetEffectLst(); + } + + @Override + public void setEffectLst(CTEffectList effectLst) { + props.setEffectLst(effectLst); + } + + @Override + public CTEffectList addNewEffectLst() { + return props.addNewEffectLst(); + } + + @Override + public void unsetEffectLst() { + props.unsetEffectLst(); + } + + @Override + public CTEffectContainer getEffectDag() { + return props.getEffectDag(); + } + + @Override + public boolean isSetEffectDag() { + return props.isSetEffectDag(); + } + + @Override + public void setEffectDag(CTEffectContainer effectDag) { + props.setEffectDag(effectDag); + } + + @Override + public CTEffectContainer addNewEffectDag() { + return props.addNewEffectDag(); + } + + @Override + public void unsetEffectDag() { + props.unsetEffectDag(); + } + + @Override + public boolean isSetMatrixStyle() { + return false; + } + + @Override + public CTStyleMatrixReference getMatrixStyle() { + return null; + } + + @Override + public boolean isLineStyle() { + return false; + } + } + + private static class BackgroundDelegate implements XSLFFillProperties, XSLFEffectProperties { + final CTBackgroundProperties props; + + BackgroundDelegate(CTBackgroundProperties props) { + this.props = props; + } + + @Override + public CTNoFillProperties getNoFill() { + return props.getNoFill(); + } + + @Override + public boolean isSetNoFill() { + return props.isSetNoFill(); + } + + @Override + public void setNoFill(CTNoFillProperties noFill) { + props.setNoFill(noFill); + } + + @Override + public CTNoFillProperties addNewNoFill() { + return props.addNewNoFill(); + } + + @Override + public void unsetNoFill() { + props.unsetNoFill(); + } + + @Override + public CTSolidColorFillProperties getSolidFill() { + return props.getSolidFill(); + } + + @Override + public boolean isSetSolidFill() { + return props.isSetSolidFill(); + } + + @Override + public void setSolidFill(CTSolidColorFillProperties solidFill) { + props.setSolidFill(solidFill); + } + + @Override + public CTSolidColorFillProperties addNewSolidFill() { + return props.addNewSolidFill(); + } + + @Override + public void unsetSolidFill() { + props.unsetSolidFill(); + } + + @Override + public CTGradientFillProperties getGradFill() { + return props.getGradFill(); + } + + @Override + public boolean isSetGradFill() { + return props.isSetGradFill(); + } + + @Override + public void setGradFill(CTGradientFillProperties gradFill) { + props.setGradFill(gradFill); + } + + @Override + public CTGradientFillProperties addNewGradFill() { + return props.addNewGradFill(); + } + + @Override + public void unsetGradFill() { + props.unsetGradFill(); + } + + @Override + public CTBlipFillProperties getBlipFill() { + return props.getBlipFill(); + } + + @Override + public boolean isSetBlipFill() { + return props.isSetBlipFill(); + } + + @Override + public void setBlipFill(CTBlipFillProperties blipFill) { + props.setBlipFill(blipFill); + } + + @Override + public CTBlipFillProperties addNewBlipFill() { + return props.addNewBlipFill(); + } + + @Override + public void unsetBlipFill() { + props.unsetBlipFill(); + } + + @Override + public CTPatternFillProperties getPattFill() { + return props.getPattFill(); + } + + @Override + public boolean isSetPattFill() { + return props.isSetPattFill(); + } + + @Override + public void setPattFill(CTPatternFillProperties pattFill) { + props.setPattFill(pattFill); + } + + @Override + public CTPatternFillProperties addNewPattFill() { + return props.addNewPattFill(); + } + + @Override + public void unsetPattFill() { + props.unsetPattFill(); + } + + @Override + public CTGroupFillProperties getGrpFill() { + return props.getGrpFill(); + } + + @Override + public boolean isSetGrpFill() { + return props.isSetGrpFill(); + } + + @Override + public void setGrpFill(CTGroupFillProperties grpFill) { + props.setGrpFill(grpFill); + } + + @Override + public CTGroupFillProperties addNewGrpFill() { + return props.addNewGrpFill(); + } + + @Override + public void unsetGrpFill() { + props.unsetGrpFill(); + } + + @Override + public CTEffectList getEffectLst() { + return props.getEffectLst(); + } + + @Override + public boolean isSetEffectLst() { + return props.isSetEffectLst(); + } + + @Override + public void setEffectLst(CTEffectList effectLst) { + props.setEffectLst(effectLst); + } + + @Override + public CTEffectList addNewEffectLst() { + return props.addNewEffectLst(); + } + + @Override + public void unsetEffectLst() { + props.unsetEffectLst(); + } + + @Override + public CTEffectContainer getEffectDag() { + return props.getEffectDag(); + } + + @Override + public boolean isSetEffectDag() { + return props.isSetEffectDag(); + } + + @Override + public void setEffectDag(CTEffectContainer effectDag) { + props.setEffectDag(effectDag); + } + + @Override + public CTEffectContainer addNewEffectDag() { + return props.addNewEffectDag(); + } + + @Override + public void unsetEffectDag() { + props.unsetEffectDag(); + } + + @Override + public boolean isSetMatrixStyle() { + return false; + } + + @Override + public CTStyleMatrixReference getMatrixStyle() { + return null; + } + + @Override + public boolean isLineStyle() { + return false; + } + } + + private static class TableCellDelegate implements XSLFFillProperties { + final CTTableCellProperties props; + + TableCellDelegate(CTTableCellProperties props) { + this.props = props; + } + + @Override + public CTNoFillProperties getNoFill() { + return props.getNoFill(); + } + + @Override + public boolean isSetNoFill() { + return props.isSetNoFill(); + } + + @Override + public void setNoFill(CTNoFillProperties noFill) { + props.setNoFill(noFill); + } + + @Override + public CTNoFillProperties addNewNoFill() { + return props.addNewNoFill(); + } + + @Override + public void unsetNoFill() { + props.unsetNoFill(); + } + + @Override + public CTSolidColorFillProperties getSolidFill() { + return props.getSolidFill(); + } + + @Override + public boolean isSetSolidFill() { + return props.isSetSolidFill(); + } + + @Override + public void setSolidFill(CTSolidColorFillProperties solidFill) { + props.setSolidFill(solidFill); + } + + @Override + public CTSolidColorFillProperties addNewSolidFill() { + return props.addNewSolidFill(); + } + + @Override + public void unsetSolidFill() { + props.unsetSolidFill(); + } + + @Override + public CTGradientFillProperties getGradFill() { + return props.getGradFill(); + } + + @Override + public boolean isSetGradFill() { + return props.isSetGradFill(); + } + + @Override + public void setGradFill(CTGradientFillProperties gradFill) { + props.setGradFill(gradFill); + } + + @Override + public CTGradientFillProperties addNewGradFill() { + return props.addNewGradFill(); + } + + @Override + public void unsetGradFill() { + props.unsetGradFill(); + } + + @Override + public CTBlipFillProperties getBlipFill() { + return props.getBlipFill(); + } + + @Override + public boolean isSetBlipFill() { + return props.isSetBlipFill(); + } + + @Override + public void setBlipFill(CTBlipFillProperties blipFill) { + props.setBlipFill(blipFill); + } + + @Override + public CTBlipFillProperties addNewBlipFill() { + return props.addNewBlipFill(); + } + + @Override + public void unsetBlipFill() { + props.unsetBlipFill(); + } + + @Override + public CTPatternFillProperties getPattFill() { + return props.getPattFill(); + } + + @Override + public boolean isSetPattFill() { + return props.isSetPattFill(); + } + + @Override + public void setPattFill(CTPatternFillProperties pattFill) { + props.setPattFill(pattFill); + } + + @Override + public CTPatternFillProperties addNewPattFill() { + return props.addNewPattFill(); + } + + @Override + public void unsetPattFill() { + props.unsetPattFill(); + } + + @Override + public CTGroupFillProperties getGrpFill() { + return props.getGrpFill(); + } + + @Override + public boolean isSetGrpFill() { + return props.isSetGrpFill(); + } + + @Override + public void setGrpFill(CTGroupFillProperties grpFill) { + props.setGrpFill(grpFill); + } + + @Override + public CTGroupFillProperties addNewGrpFill() { + return props.addNewGrpFill(); + } + + @Override + public void unsetGrpFill() { + props.unsetGrpFill(); + } + + @Override + public boolean isSetMatrixStyle() { + return false; + } + + @Override + public CTStyleMatrixReference getMatrixStyle() { + return null; + } + + @Override + public boolean isLineStyle() { + return false; + } + } + + private static class StyleMatrixDelegate implements XSLFFillProperties { + final CTStyleMatrixReference props; + + StyleMatrixDelegate(CTStyleMatrixReference props) { + this.props = props; + } + + @Override + public CTNoFillProperties getNoFill() { + return null; + } + + @Override + public boolean isSetNoFill() { + return false; + } + + @Override + public void setNoFill(CTNoFillProperties noFill) {} + + @Override + public CTNoFillProperties addNewNoFill() { + return null; + } + + @Override + public void unsetNoFill() {} + + @Override + public CTSolidColorFillProperties getSolidFill() { + return null; + } + + @Override + public boolean isSetSolidFill() { + return false; + } + + @Override + public void setSolidFill(CTSolidColorFillProperties solidFill) {} + + @Override + public CTSolidColorFillProperties addNewSolidFill() { + return null; + } + + @Override + public void unsetSolidFill() {} + + @Override + public CTGradientFillProperties getGradFill() { + return null; + } + + @Override + public boolean isSetGradFill() { + return false; + } + + @Override + public void setGradFill(CTGradientFillProperties gradFill) {} + + @Override + public CTGradientFillProperties addNewGradFill() { + return null; + } + + @Override + public void unsetGradFill() {} + + @Override + public CTBlipFillProperties getBlipFill() { + return null; + } + + @Override + public boolean isSetBlipFill() { + return false; + } + + @Override + public void setBlipFill(CTBlipFillProperties blipFill) {} + + @Override + public CTBlipFillProperties addNewBlipFill() { + return null; + } + + @Override + public void unsetBlipFill() {} + + @Override + public CTPatternFillProperties getPattFill() { + return null; + } + + @Override + public boolean isSetPattFill() { + return false; + } + + @Override + public void setPattFill(CTPatternFillProperties pattFill) {} + + @Override + public CTPatternFillProperties addNewPattFill() { + return null; + } + + @Override + public void unsetPattFill() {} + + @Override + public CTGroupFillProperties getGrpFill() { + return null; + } + + @Override + public boolean isSetGrpFill() { + return false; + } + + @Override + public void setGrpFill(CTGroupFillProperties grpFill) {} + + @Override + public CTGroupFillProperties addNewGrpFill() { + return null; + } + + @Override + public void unsetGrpFill() {} + + + @Override + public boolean isSetMatrixStyle() { + return true; + } + + @Override + public CTStyleMatrixReference getMatrixStyle() { + return props; + } + + @Override + public boolean isLineStyle() { + XmlCursor cur = props.newCursor(); + String name = cur.getName().getLocalPart(); + cur.dispose(); + return "lnRef".equals(name); + } + } + + private static class FillDelegate implements XSLFFillProperties { + final CTFillProperties props; + + FillDelegate(CTFillProperties props) { + this.props = props; + } + + @Override + public CTNoFillProperties getNoFill() { + return props.getNoFill(); + } + + @Override + public boolean isSetNoFill() { + return props.isSetNoFill(); + } + + @Override + public void setNoFill(CTNoFillProperties noFill) { + props.setNoFill(noFill); + } + + @Override + public CTNoFillProperties addNewNoFill() { + return props.addNewNoFill(); + } + + @Override + public void unsetNoFill() { + props.unsetNoFill(); + } + + @Override + public CTSolidColorFillProperties getSolidFill() { + return props.getSolidFill(); + } + + @Override + public boolean isSetSolidFill() { + return props.isSetSolidFill(); + } + + @Override + public void setSolidFill(CTSolidColorFillProperties solidFill) { + props.setSolidFill(solidFill); + } + + @Override + public CTSolidColorFillProperties addNewSolidFill() { + return props.addNewSolidFill(); + } + + @Override + public void unsetSolidFill() { + props.unsetSolidFill(); + } + + @Override + public CTGradientFillProperties getGradFill() { + return props.getGradFill(); + } + + @Override + public boolean isSetGradFill() { + return props.isSetGradFill(); + } + + @Override + public void setGradFill(CTGradientFillProperties gradFill) { + props.setGradFill(gradFill); + } + + @Override + public CTGradientFillProperties addNewGradFill() { + return props.addNewGradFill(); + } + + @Override + public void unsetGradFill() { + props.unsetGradFill(); + } + + @Override + public CTBlipFillProperties getBlipFill() { + return props.getBlipFill(); + } + + @Override + public boolean isSetBlipFill() { + return props.isSetBlipFill(); + } + + @Override + public void setBlipFill(CTBlipFillProperties blipFill) { + props.setBlipFill(blipFill); + } + + @Override + public CTBlipFillProperties addNewBlipFill() { + return props.addNewBlipFill(); + } + + @Override + public void unsetBlipFill() { + props.unsetBlipFill(); + } + + @Override + public CTPatternFillProperties getPattFill() { + return props.getPattFill(); + } + + @Override + public boolean isSetPattFill() { + return props.isSetPattFill(); + } + + @Override + public void setPattFill(CTPatternFillProperties pattFill) { + props.setPattFill(pattFill); + } + + @Override + public CTPatternFillProperties addNewPattFill() { + return props.addNewPattFill(); + } + + @Override + public void unsetPattFill() { + props.unsetPattFill(); + } + + @Override + public CTGroupFillProperties getGrpFill() { + return props.getGrpFill(); + } + + @Override + public boolean isSetGrpFill() { + return props.isSetGrpFill(); + } + + @Override + public void setGrpFill(CTGroupFillProperties grpFill) { + props.setGrpFill(grpFill); + } + + @Override + public CTGroupFillProperties addNewGrpFill() { + return props.addNewGrpFill(); + } + + @Override + public void unsetGrpFill() { + props.unsetGrpFill(); + } + + @Override + public boolean isSetMatrixStyle() { + return false; + } + + @Override + public CTStyleMatrixReference getMatrixStyle() { + return null; + } + + @Override + public boolean isLineStyle() { + return false; + } + } + + private static class FillPartDelegate implements XSLFFillProperties { + final XmlObject props; + + FillPartDelegate(XmlObject props) { + this.props = props; + } + + public CTNoFillProperties getNoFill() { + return isSetNoFill() ? (CTNoFillProperties)props : null; + } + + public boolean isSetNoFill() { + return (props instanceof CTNoFillProperties); + } + + public void setNoFill(CTNoFillProperties noFill) {} + + public CTNoFillProperties addNewNoFill() { + return null; + } + + public void unsetNoFill() {} + + public CTSolidColorFillProperties getSolidFill() { + return isSetSolidFill() ? (CTSolidColorFillProperties)props : null; + } + + public boolean isSetSolidFill() { + return (props instanceof CTSolidColorFillProperties); + } + + public void setSolidFill(CTSolidColorFillProperties solidFill) {} + + public CTSolidColorFillProperties addNewSolidFill() { + return null; + } + + public void unsetSolidFill() {} + + public CTGradientFillProperties getGradFill() { + return isSetGradFill() ? (CTGradientFillProperties)props : null; + } + + public boolean isSetGradFill() { + return (props instanceof CTGradientFillProperties); + } + + public void setGradFill(CTGradientFillProperties gradFill) {} + + public CTGradientFillProperties addNewGradFill() { + return null; + } + + public void unsetGradFill() {} + + public CTBlipFillProperties getBlipFill() { + return isSetBlipFill() ? (CTBlipFillProperties)props : null; + } + + public boolean isSetBlipFill() { + return (props instanceof CTBlipFillProperties); + } + + public void setBlipFill(CTBlipFillProperties blipFill) {} + + public CTBlipFillProperties addNewBlipFill() { + return null; + } + + public void unsetBlipFill() {} + + public CTPatternFillProperties getPattFill() { + return isSetPattFill() ? (CTPatternFillProperties)props : null; + } + + public boolean isSetPattFill() { + return (props instanceof CTPatternFillProperties); + } + + public void setPattFill(CTPatternFillProperties pattFill) {} + + public CTPatternFillProperties addNewPattFill() { + return null; + } + + public void unsetPattFill() {} + + public CTGroupFillProperties getGrpFill() { + return isSetGrpFill() ? (CTGroupFillProperties)props : null; + } + + public boolean isSetGrpFill() { + return (props instanceof CTGroupFillProperties); + } + + public void setGrpFill(CTGroupFillProperties grpFill) {} + + public CTGroupFillProperties addNewGrpFill() { + return null; + } + + public void unsetGrpFill() {} + + public boolean isSetMatrixStyle() { + return false; + } + + public CTStyleMatrixReference getMatrixStyle() { + return null; + } + + @Override + public boolean isLineStyle() { + return false; + } + } + + private static class LineStyleDelegate implements XSLFFillProperties { + final CTLineProperties props; + + LineStyleDelegate(CTLineProperties props) { + this.props = props; + } + + @Override + public CTNoFillProperties getNoFill() { + return props.getNoFill(); + } + + @Override + public boolean isSetNoFill() { + return props.isSetNoFill(); + } + + @Override + public void setNoFill(CTNoFillProperties noFill) { + props.setNoFill(noFill); + } + + @Override + public CTNoFillProperties addNewNoFill() { + return props.addNewNoFill(); + } + + @Override + public void unsetNoFill() { + props.unsetNoFill(); + } + + @Override + public CTSolidColorFillProperties getSolidFill() { + return props.getSolidFill(); + } + + @Override + public boolean isSetSolidFill() { + return props.isSetSolidFill(); + } + + @Override + public void setSolidFill(CTSolidColorFillProperties solidFill) { + props.setSolidFill(solidFill); + } + + @Override + public CTSolidColorFillProperties addNewSolidFill() { + return props.addNewSolidFill(); + } + + @Override + public void unsetSolidFill() { + props.unsetSolidFill(); + } + + @Override + public CTGradientFillProperties getGradFill() { + return props.getGradFill(); + } + + @Override + public boolean isSetGradFill() { + return props.isSetGradFill(); + } + + @Override + public void setGradFill(CTGradientFillProperties gradFill) { + props.setGradFill(gradFill); + } + + @Override + public CTGradientFillProperties addNewGradFill() { + return props.addNewGradFill(); + } + + @Override + public void unsetGradFill() { + props.unsetGradFill(); + } + + @Override + public CTBlipFillProperties getBlipFill() { + return null; + } + + @Override + public boolean isSetBlipFill() { + return false; + } + + @Override + public void setBlipFill(CTBlipFillProperties blipFill) {} + + @Override + public CTBlipFillProperties addNewBlipFill() { + return null; + } + + @Override + public void unsetBlipFill() {} + + @Override + public CTPatternFillProperties getPattFill() { + return props.getPattFill(); + } + + @Override + public boolean isSetPattFill() { + return props.isSetPattFill(); + } + + @Override + public void setPattFill(CTPatternFillProperties pattFill) { + props.setPattFill(pattFill); + } + + @Override + public CTPatternFillProperties addNewPattFill() { + return props.addNewPattFill(); + } + + @Override + public void unsetPattFill() { + props.unsetPattFill(); + } + + @Override + public CTGroupFillProperties getGrpFill() { + return null; + } + + @Override + public boolean isSetGrpFill() { + return false; + } + + @Override + public void setGrpFill(CTGroupFillProperties grpFill) {} + + @Override + public CTGroupFillProperties addNewGrpFill() { + return null; + } + + @Override + public void unsetGrpFill() {} + + @Override + public boolean isSetMatrixStyle() { + return false; + } + + @Override + public CTStyleMatrixReference getMatrixStyle() { + return null; + } + + @Override + public boolean isLineStyle() { + return true; + } + } + + private static class TextCharDelegate implements XSLFFillProperties { + final CTTextCharacterProperties props; + + TextCharDelegate(CTTextCharacterProperties props) { + this.props = props; + } + + @Override + public CTNoFillProperties getNoFill() { + return props.getNoFill(); + } + + @Override + public boolean isSetNoFill() { + return props.isSetNoFill(); + } + + @Override + public void setNoFill(CTNoFillProperties noFill) { + props.setNoFill(noFill); + } + + @Override + public CTNoFillProperties addNewNoFill() { + return props.addNewNoFill(); + } + + @Override + public void unsetNoFill() { + props.unsetNoFill(); + } + + @Override + public CTSolidColorFillProperties getSolidFill() { + return props.getSolidFill(); + } + + @Override + public boolean isSetSolidFill() { + return props.isSetSolidFill(); + } + + @Override + public void setSolidFill(CTSolidColorFillProperties solidFill) { + props.setSolidFill(solidFill); + } + + @Override + public CTSolidColorFillProperties addNewSolidFill() { + return props.addNewSolidFill(); + } + + @Override + public void unsetSolidFill() { + props.unsetSolidFill(); + } + + @Override + public CTGradientFillProperties getGradFill() { + return props.getGradFill(); + } + + @Override + public boolean isSetGradFill() { + return props.isSetGradFill(); + } + + @Override + public void setGradFill(CTGradientFillProperties gradFill) { + props.setGradFill(gradFill); + } + + @Override + public CTGradientFillProperties addNewGradFill() { + return props.addNewGradFill(); + } + + @Override + public void unsetGradFill() { + props.unsetGradFill(); + } + + @Override + public CTBlipFillProperties getBlipFill() { + return props.getBlipFill(); + } + + @Override + public boolean isSetBlipFill() { + return props.isSetBlipFill(); + } + + @Override + public void setBlipFill(CTBlipFillProperties blipFill) { + props.setBlipFill(blipFill); + } + + @Override + public CTBlipFillProperties addNewBlipFill() { + return props.addNewBlipFill(); + } + + @Override + public void unsetBlipFill() { + props.unsetBlipFill(); + } + + @Override + public CTPatternFillProperties getPattFill() { + return props.getPattFill(); + } + + @Override + public boolean isSetPattFill() { + return props.isSetPattFill(); + } + + @Override + public void setPattFill(CTPatternFillProperties pattFill) { + props.setPattFill(pattFill); + } + + @Override + public CTPatternFillProperties addNewPattFill() { + return props.addNewPattFill(); + } + + @Override + public void unsetPattFill() { + props.unsetPattFill(); + } + + @Override + public CTGroupFillProperties getGrpFill() { + return props.getGrpFill(); + } + + @Override + public boolean isSetGrpFill() { + return props.isSetGrpFill(); + } + + @Override + public void setGrpFill(CTGroupFillProperties grpFill) { + props.setGrpFill(grpFill); + } + + @Override + public CTGroupFillProperties addNewGrpFill() { + return props.addNewGrpFill(); + } + + @Override + public void unsetGrpFill() { + props.unsetGrpFill(); + } + + @Override + public boolean isSetMatrixStyle() { + return false; + } + + @Override + public CTStyleMatrixReference getMatrixStyle() { + return null; + } + + @Override + public boolean isLineStyle() { + return false; + } + } + + @SuppressWarnings("unchecked") + private static T getDelegate(Class clazz, XmlObject props) { + Object obj = null; + if (props == null) { + return null; + } else if (props instanceof CTShapeProperties) { + obj = new ShapeDelegate((CTShapeProperties)props); + } else if (props instanceof CTBackgroundProperties) { + obj = new BackgroundDelegate((CTBackgroundProperties)props); + } else if (props instanceof CTStyleMatrixReference) { + obj = new StyleMatrixDelegate((CTStyleMatrixReference)props); + } else if (props instanceof CTTableCellProperties) { + obj = new TableCellDelegate((CTTableCellProperties)props); + } else if (props instanceof CTNoFillProperties + || props instanceof CTSolidColorFillProperties + || props instanceof CTGradientFillProperties + || props instanceof CTBlipFillProperties + || props instanceof CTPatternFillProperties + || props instanceof CTGroupFillProperties) { + obj = new FillPartDelegate(props); + } else if (props instanceof CTFillProperties) { + obj = new FillDelegate((CTFillProperties)props); + } else if (props instanceof CTLineProperties) { + obj = new LineStyleDelegate((CTLineProperties)props); + } else if (props instanceof CTTextCharacterProperties) { + obj = new TextCharDelegate((CTTextCharacterProperties)props); + } else { + LOG.log(POILogger.ERROR, props.getClass().toString()+" is an unknown properties type"); + return null; + } + + if (clazz.isInstance(obj)) { + return (T)obj; + } + + LOG.log(POILogger.WARN, obj.getClass().toString()+" doesn't implement "+clazz.toString()); + return null; + } +} diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java index 6dfe1d0c9..0c4e4971d 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java @@ -41,13 +41,14 @@ import org.apache.poi.sl.usermodel.Shape; import org.apache.poi.util.Beta; import org.apache.poi.util.Internal; import org.apache.poi.xslf.model.PropertyFetcher; +import org.apache.poi.xslf.usermodel.XSLFPropertiesDelegate.XSLFFillProperties; +import org.apache.xmlbeans.XmlCursor; import org.apache.xmlbeans.XmlObject; import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip; import org.openxmlformats.schemas.drawingml.x2006.main.CTBlipFillProperties; import org.openxmlformats.schemas.drawingml.x2006.main.CTGradientFillProperties; import org.openxmlformats.schemas.drawingml.x2006.main.CTGradientStop; import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupShapeProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTNoFillProperties; import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor; import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; @@ -57,7 +58,6 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrix; import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrixReference; import org.openxmlformats.schemas.drawingml.x2006.main.STPathShadeType; import org.openxmlformats.schemas.presentationml.x2006.main.CTApplicationNonVisualDrawingProps; -import org.openxmlformats.schemas.presentationml.x2006.main.CTBackground; import org.openxmlformats.schemas.presentationml.x2006.main.CTBackgroundProperties; import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder; import org.openxmlformats.schemas.presentationml.x2006.main.CTShape; @@ -68,11 +68,12 @@ import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType; */ @Beta public abstract class XSLFShape implements Shape { + protected static final String PML_NS = "http://schemas.openxmlformats.org/presentationml/2006/main"; + private final XmlObject _shape; private final XSLFSheet _sheet; private XSLFShapeContainer _parent; - private CTShapeProperties _spPr; private CTShapeStyle _spStyle; private CTNonVisualDrawingProps _nvPr; private CTPlaceholder _ph; @@ -151,75 +152,52 @@ public abstract class XSLFShape implements Shape { final XSLFTheme theme = getSheet().getTheme(); PropertyFetcher fetcher = new PropertyFetcher() { public boolean fetch(XSLFShape shape) { - XmlObject pr = null; - try { - pr = shape.getSpPr(); - if (((CTShapeProperties)pr).isSetNoFill()) { - setValue(null); - return true; - } - } catch (IllegalStateException e) {} - // trying background properties now - if (pr == null) { - pr = shape.getBgPr(); + XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(shape.getShapeProperties()); + if (fp == null) { + return false; } - if (pr == null) { - pr = shape.getGrpSpPr(); - } - if (pr == null) { - if (shape.getXmlObject() instanceof CTBackground) { - pr = shape.getXmlObject(); - } + + if (fp.isSetNoFill()) { + setValue(null); + return true; } - if (pr == null) return false; - - PaintStyle paint = null; - PackagePart pp = getSheet().getPackagePart(); - for (XmlObject obj : pr.selectPath("*")) { - paint = selectPaint(obj, null, pp, theme); - if (paint != null) { - setValue(paint); - return true; - } + PackagePart pp = shape.getSheet().getPackagePart(); + PaintStyle paint = selectPaint(fp, null, pp, theme); + if (paint != null) { + setValue(paint); + return true; } + + CTShapeStyle style = shape.getSpStyle(); + if (style != null) { + fp = XSLFPropertiesDelegate.getFillDelegate(style.getFillRef()); + paint = selectPaint(fp, null, pp, theme); + } + if (paint != null) { + setValue(paint); + return true; + } + return false; } }; fetchShapeProperty(fetcher); - PaintStyle paint = fetcher.getValue(); - if (paint != null) return paint; - - // fill color was not found, check if it is defined in the theme - // get a reference to a fill style within the style matrix. - CTStyleMatrixReference fillRef = null; - if (fillRef == null) { - CTShapeStyle style = getSpStyle(); - if (style != null) fillRef = style.getFillRef(); - } - if (fillRef == null) { - fillRef = getBgRef(); - } - paint = selectPaint(fillRef, theme); - - return paint; + return fetcher.getValue(); } protected CTBackgroundProperties getBgPr() { - String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' p:bgPr"; - return selectProperty(CTBackgroundProperties.class, xquery); + return getChild(CTBackgroundProperties.class, PML_NS, "bgPr"); } protected CTStyleMatrixReference getBgRef() { - String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' p:bgRef"; - return selectProperty(CTStyleMatrixReference.class, xquery); + return getChild(CTStyleMatrixReference.class, PML_NS, "bgRef"); } protected CTGroupShapeProperties getGrpSpPr() { - String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' p:grpSpPr"; - return selectProperty(CTGroupShapeProperties.class, xquery); + return getChild(CTGroupShapeProperties.class, PML_NS, "grpSpPr"); } protected CTNonVisualDrawingProps getCNvPr() { @@ -230,28 +208,35 @@ public abstract class XSLFShape implements Shape { return _nvPr; } - protected CTShapeProperties getSpPr() { - if (_spPr == null) { - String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' p:spPr"; - _spPr = selectProperty(CTShapeProperties.class, xquery); - } - if (_spPr == null) { - throw new IllegalStateException("CTShapeProperties was not found."); - } - return _spPr; - } - protected CTShapeStyle getSpStyle() { if (_spStyle == null) { - String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' p:style"; - _spStyle = selectProperty(CTShapeStyle.class, xquery); + _spStyle = getChild(CTShapeStyle.class, PML_NS, "style"); } return _spStyle; } + /** + * Return direct child objects of this shape + * + * @param childClass the class to cast the properties to + * @param namespace the namespace - usually it is {@code "http://schemas.openxmlformats.org/presentationml/2006/main"} + * @param nodename the node name, without prefix + * @return the properties object or null if it can't be found + */ + @SuppressWarnings("unchecked") + protected T getChild(Class childClass, String namespace, String nodename) { + XmlCursor cur = getXmlObject().newCursor(); + T child = null; + if (cur.toChild(namespace, nodename)) { + child = (T)cur.getObject(); + } + cur.dispose(); + return child; + } + protected CTPlaceholder getCTPlaceholder() { if (_ph == null) { - String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:nvPr/p:ph"; + String xquery = "declare namespace p='"+PML_NS+"' .//*/p:nvPr/p:ph"; _ph = selectProperty(CTPlaceholder.class, xquery); } return _ph; @@ -275,7 +260,7 @@ public abstract class XSLFShape implements Shape { * @param placeholder */ protected void setPlaceholder(Placeholder placeholder) { - String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:nvPr"; + String xquery = "declare namespace p='"+PML_NS+"' .//*/p:nvPr"; CTApplicationNonVisualDrawingProps nv = selectProperty(CTApplicationNonVisualDrawingProps.class, xquery); if (nv == null) return; if(placeholder == null) { @@ -362,48 +347,28 @@ public abstract class XSLFShape implements Shape { return ok; } - protected PaintStyle getPaint(XmlObject spPr, CTSchemeColor phClr) { - PaintStyle paint = null; - XSLFSheet sheet = getSheet(); - PackagePart pp = sheet.getPackagePart(); - XSLFTheme theme = sheet.getTheme(); - for (XmlObject obj : spPr.selectPath("*")) { - paint = selectPaint(obj, phClr, pp, theme); - if(paint != null) break; - } - return paint; - } - /** * Convert shape fill into java.awt.Paint. The result is either Color or * TexturePaint or GradientPaint or null * - * @param obj the xml to read. Must contain elements from the EG_ColorChoice group: - * - * a:scrgbClr RGB Color Model - Percentage Variant - * a:srgbClr RGB Color Model - Hex Variant - * a:hslClr Hue, Saturation, Luminance Color Model - * a:sysClr System Color - * a:schemeClr Scheme Color - * a:prstClr Preset Color - * - * - * @param phClr context color - * @param parentPart the parent package part. Any external references (images, etc.) are resolved relative to it. + * @param fp a properties handler specific to the underlying shape properties + * @param phClr context color + * @param parentPart the parent package part. Any external references (images, etc.) are resolved relative to it. + * @param theme the theme for the shape/sheet * * @return the applied Paint or null if none was applied */ - protected static PaintStyle selectPaint(XmlObject obj, final CTSchemeColor phClr, final PackagePart parentPart, final XSLFTheme theme) { - if (obj instanceof CTNoFillProperties) { + protected static PaintStyle selectPaint(XSLFFillProperties fp, final CTSchemeColor phClr, final PackagePart parentPart, final XSLFTheme theme) { + if (fp == null || fp.isSetNoFill()) { return null; - } else if (obj instanceof CTSolidColorFillProperties) { - return selectPaint((CTSolidColorFillProperties)obj, phClr, theme); - } else if (obj instanceof CTBlipFillProperties) { - return selectPaint((CTBlipFillProperties)obj, parentPart); - } else if (obj instanceof CTGradientFillProperties) { - return selectPaint((CTGradientFillProperties) obj, phClr, theme); - } else if (obj instanceof CTStyleMatrixReference) { - return selectPaint((CTStyleMatrixReference)obj, theme); + } else if (fp.isSetSolidFill()) { + return selectPaint(fp.getSolidFill(), phClr, theme); + } else if (fp.isSetBlipFill()) { + return selectPaint(fp.getBlipFill(), parentPart); + } else if (fp.isSetGradFill()) { + return selectPaint(fp.getGradFill(), phClr, theme); + } else if (fp.isSetMatrixStyle()) { + return selectPaint(fp.getMatrixStyle(), theme, fp.isLineStyle()); } else { return null; } @@ -518,7 +483,7 @@ public abstract class XSLFShape implements Shape { }; } - protected static PaintStyle selectPaint(CTStyleMatrixReference fillRef, final XSLFTheme theme) { + protected static PaintStyle selectPaint(CTStyleMatrixReference fillRef, final XSLFTheme theme, boolean isLineStyle) { if (fillRef == null) return null; // The idx attribute refers to the index of a fill style or @@ -528,18 +493,39 @@ public abstract class XSLFShape implements Shape { // values 1001 and above refer to the index of a background fill style within the bgFillStyleLst element. int idx = (int)fillRef.getIdx(); CTSchemeColor phClr = fillRef.getSchemeClr(); - XmlObject fillProps = null; CTStyleMatrix matrix = theme.getXmlObject().getThemeElements().getFmtScheme(); + XmlObject styleLst = null; + int childIdx; if (idx >= 1 && idx <= 999) { - fillProps = matrix.getFillStyleLst().selectPath("*")[idx - 1]; + childIdx = idx-1; + styleLst = (isLineStyle) ? matrix.getLnStyleLst() : matrix.getFillStyleLst(); } else if (idx >= 1001 ){ - fillProps = matrix.getBgFillStyleLst().selectPath("*")[idx - 1001]; + childIdx = idx - 1001; + styleLst = matrix.getBgFillStyleLst(); + } else { + return null; } - return (fillProps == null) ? null : selectPaint(fillProps, phClr, theme.getPackagePart(), theme); + XmlCursor cur = styleLst.newCursor(); + XSLFFillProperties fp = null; + if (cur.toChild(childIdx)) { + fp = XSLFPropertiesDelegate.getFillDelegate(cur.getObject()); + } + cur.dispose(); + + return selectPaint(fp, phClr, theme.getPackagePart(), theme); } @Override public void draw(Graphics2D graphics, Rectangle2D bounds) { DrawFactory.getInstance(graphics).drawShape(graphics, this, bounds); } + + /** + * Return the shape specific (visual) properties + * + * @return the shape specific properties + */ + protected XmlObject getShapeProperties() { + return getChild(CTShapeProperties.class, PML_NS, "spPr"); + } } \ No newline at end of file diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java index b90fbb067..6116941cf 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java @@ -26,6 +26,7 @@ import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import org.apache.poi.openxml4j.opc.PackagePart; +import org.apache.poi.sl.draw.DrawPaint; import org.apache.poi.sl.draw.geom.CustomGeometry; import org.apache.poi.sl.draw.geom.Guide; import org.apache.poi.sl.draw.geom.PresetGeometries; @@ -43,8 +44,13 @@ import org.apache.poi.sl.usermodel.StrokeStyle.LineCap; import org.apache.poi.sl.usermodel.StrokeStyle.LineCompound; import org.apache.poi.sl.usermodel.StrokeStyle.LineDash; import org.apache.poi.util.Beta; +import org.apache.poi.util.POILogFactory; +import org.apache.poi.util.POILogger; import org.apache.poi.util.Units; import org.apache.poi.xslf.model.PropertyFetcher; +import org.apache.poi.xslf.usermodel.XSLFPropertiesDelegate.XSLFEffectProperties; +import org.apache.poi.xslf.usermodel.XSLFPropertiesDelegate.XSLFFillProperties; +import org.apache.poi.xslf.usermodel.XSLFPropertiesDelegate.XSLFGeometryProperties; import org.apache.xmlbeans.XmlObject; import org.openxmlformats.schemas.drawingml.x2006.main.CTBaseStyles; import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip; @@ -82,6 +88,7 @@ import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder; public abstract class XSLFSimpleShape extends XSLFShape implements SimpleShape { private static CTOuterShadowEffect NO_SHADOW = CTOuterShadowEffect.Factory.newInstance(); + private static final POILogger LOG = POILogFactory.getLogger(XSLFSimpleShape.class); /* package */XSLFSimpleShape(XmlObject shape, XSLFSheet sheet) { super(shape,sheet); @@ -89,40 +96,64 @@ public abstract class XSLFSimpleShape extends XSLFShape @Override public void setShapeType(ShapeType type) { - STShapeType.Enum geom = STShapeType.Enum.forInt(type.ooxmlId); - getSpPr().getPrstGeom().setPrst(geom); + XSLFGeometryProperties gp = XSLFPropertiesDelegate.getGeometryDelegate(getShapeProperties()); + if (gp == null) { + return; + } + if (gp.isSetCustGeom()) { + gp.unsetCustGeom(); + } + CTPresetGeometry2D prst = (gp.isSetPrstGeom()) ? gp.getPrstGeom() : gp.addNewPrstGeom(); + prst.setPrst(STShapeType.Enum.forInt(type.ooxmlId)); } @Override public ShapeType getShapeType(){ - STShapeType.Enum geom = getSpPr().getPrstGeom().getPrst(); - return ShapeType.forId(geom.intValue(), true); + XSLFGeometryProperties gp = XSLFPropertiesDelegate.getGeometryDelegate(getShapeProperties()); + if (gp != null && gp.isSetPrstGeom()) { + STShapeType.Enum geom = gp.getPrstGeom().getPrst(); + if (geom != null) { + return ShapeType.forId(geom.intValue(), true); + } + } + return null; } - protected CTTransform2D getSafeXfrm() { - CTTransform2D xfrm = getXfrm(); - return (xfrm == null ? getSpPr().addNewXfrm() : xfrm); - } - - protected CTTransform2D getXfrm() { + protected CTTransform2D getXfrm(boolean create) { PropertyFetcher fetcher = new PropertyFetcher() { public boolean fetch(XSLFShape shape) { - CTShapeProperties pr = shape.getSpPr(); - if (pr.isSetXfrm()) { - setValue(pr.getXfrm()); + XmlObject xo = shape.getShapeProperties(); + if (xo instanceof CTShapeProperties && ((CTShapeProperties)xo).isSetXfrm()) { + setValue(((CTShapeProperties)xo).getXfrm()); return true; } return false; } }; fetchShapeProperty(fetcher); - return fetcher.getValue(); + + CTTransform2D xfrm = fetcher.getValue(); + if (!create || xfrm != null) { + return xfrm; + } else { + XmlObject xo = getShapeProperties(); + if (xo instanceof CTShapeProperties) { + return ((CTShapeProperties)xo).addNewXfrm(); + } else { + // ... group shapes have their own getXfrm() + LOG.log(POILogger.WARN, getClass().toString()+" doesn't have xfrm element."); + return null; + } + } } @Override public Rectangle2D getAnchor() { - CTTransform2D xfrm = getXfrm(); + CTTransform2D xfrm = getXfrm(false); + if (xfrm == null) { + return null; + } CTPoint2D off = xfrm.getOff(); double x = Units.toPoints(off.getX()); @@ -135,7 +166,10 @@ public abstract class XSLFSimpleShape extends XSLFShape @Override public void setAnchor(Rectangle2D anchor) { - CTTransform2D xfrm = getSafeXfrm(); + CTTransform2D xfrm = getXfrm(true); + if (xfrm == null) { + return; + } CTPoint2D off = xfrm.isSetOff() ? xfrm.getOff() : xfrm.addNewOff(); long x = Units.toEMU(anchor.getX()); long y = Units.toEMU(anchor.getY()); @@ -151,35 +185,44 @@ public abstract class XSLFSimpleShape extends XSLFShape @Override public void setRotation(double theta) { - getSafeXfrm().setRot((int) (theta * 60000)); + CTTransform2D xfrm = getXfrm(true); + if (xfrm != null) { + xfrm.setRot((int) (theta * 60000)); + } } @Override public double getRotation() { - CTTransform2D xfrm = getXfrm(); + CTTransform2D xfrm = getXfrm(false); return (xfrm == null || !xfrm.isSetRot()) ? 0 : (xfrm.getRot() / 60000.d); } @Override public void setFlipHorizontal(boolean flip) { - getSafeXfrm().setFlipH(flip); + CTTransform2D xfrm = getXfrm(true); + if (xfrm != null) { + xfrm.setFlipH(flip); + } } @Override public void setFlipVertical(boolean flip) { - getSafeXfrm().setFlipV(flip); + CTTransform2D xfrm = getXfrm(true); + if (xfrm != null) { + xfrm.setFlipV(flip); + } } @Override public boolean getFlipHorizontal() { - CTTransform2D xfrm = getXfrm(); - return (xfrm == null || !xfrm.isSetFlipH()) ? false : getXfrm().getFlipH(); + CTTransform2D xfrm = getXfrm(false); + return (xfrm == null || !xfrm.isSetFlipH()) ? false : xfrm.getFlipH(); } @Override public boolean getFlipVertical() { - CTTransform2D xfrm = getXfrm(); - return (xfrm == null || !xfrm.isSetFlipV()) ? false : getXfrm().getFlipV(); + CTTransform2D xfrm = getXfrm(false); + return (xfrm == null || !xfrm.isSetFlipV()) ? false : xfrm.getFlipV(); } @@ -187,7 +230,7 @@ public abstract class XSLFSimpleShape extends XSLFShape * Get default line properties defined in the theme (if any). * Used internally to resolve shape properties. * - * @return line propeties from the theme of null + * @return line properties from the theme of null */ CTLineProperties getDefaultLineProperties() { CTShapeStyle style = getSpStyle(); @@ -214,30 +257,29 @@ public abstract class XSLFSimpleShape extends XSLFShape * A null value turns off the shape outline. */ public void setLineColor(Color color) { - CTShapeProperties spPr = getSpPr(); - CTLineProperties ln = spPr.getLn(); - if (color == null) { - if (ln == null) { - return; - } - - if (ln.isSetSolidFill()) { - ln.unsetSolidFill(); - } - - if (!ln.isSetNoFill()) { - ln.addNewNoFill(); - } - } else { - if (ln == null) { - ln = spPr.addNewLn(); - } - if (ln.isSetNoFill()) { - ln.unsetNoFill(); - } - - CTSolidColorFillProperties fill = ln.isSetSolidFill() ? ln.getSolidFill() : ln.addNewSolidFill(); + CTLineProperties ln = getLn(this, true); + if (ln == null) { + return; + } + if (ln.isSetSolidFill()) { + ln.unsetSolidFill(); + } + if (ln.isSetGradFill()) { + ln.unsetGradFill(); + } + if (ln.isSetPattFill()) { + ln.unsetPattFill(); + } + if (ln.isSetNoFill()) { + ln.unsetNoFill(); + } + + + if (color == null) { + ln.addNewNoFill(); + } else { + CTSolidColorFillProperties fill = ln.addNewSolidFill(); XSLFColor col = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr()); col.setColor(color); } @@ -257,37 +299,29 @@ public abstract class XSLFSimpleShape extends XSLFShape } protected PaintStyle getLinePaint() { - final XSLFTheme theme = getSheet().getTheme(); + XSLFSheet sheet = getSheet(); + final XSLFTheme theme = sheet.getTheme(); PropertyFetcher fetcher = new PropertyFetcher() { public boolean fetch(XSLFShape shape) { - CTLineProperties spPr = shape.getSpPr().getLn(); - if (spPr != null) { - if (spPr.isSetNoFill()) { - setValue(null); // use it as 'nofill' value - return true; - } + CTLineProperties spPr = getLn(shape, false); + XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(spPr); + PackagePart pp = shape.getSheet().getPackagePart(); + PaintStyle paint = selectPaint(fp, null, pp, theme); + if (paint != null) { + setValue(paint); + return true; + } - PaintStyle paint = null; - PackagePart pp = getSheet().getPackagePart(); - for (XmlObject obj : spPr.selectPath("*")) { - paint = selectPaint(obj, null, pp, theme); - if (paint != null) { - setValue(paint); - return true; - } - } - - CTShapeStyle style = shape.getSpStyle(); - if (style != null) { - paint = selectPaint(style.getLnRef(), theme); - if (paint != null) { - setValue(paint); - return true; - } - } + CTShapeStyle style = shape.getSpStyle(); + if (style != null) { + fp = XSLFPropertiesDelegate.getFillDelegate(style.getLnRef()); + paint = selectPaint(fp, null, pp, theme); + } + if (paint != null) { + setValue(paint); + return true; } return false; - } }; fetchShapeProperty(fetcher); @@ -304,9 +338,10 @@ public abstract class XSLFSimpleShape extends XSLFShape int idx = (int)lnRef.getIdx(); CTSchemeColor phClr = lnRef.getSchemeClr(); if(idx > 0){ - XmlObject lnProps = theme.getXmlObject(). - getThemeElements().getFmtScheme().getLnStyleLst().selectPath("*")[idx - 1]; - paint = getPaint(lnProps, phClr); + CTLineProperties props = theme.getXmlObject().getThemeElements().getFmtScheme().getLnStyleLst().getLnArray(idx - 1); + XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(props); + PackagePart pp = sheet.getPackagePart(); + paint = selectPaint(fp, phClr, pp, theme); } return paint; @@ -317,14 +352,33 @@ public abstract class XSLFSimpleShape extends XSLFShape * @param width line width in points. 0 means no line */ public void setLineWidth(double width) { - CTShapeProperties spPr = getSpPr(); + CTLineProperties lnPr = getLn(this, true); + if (lnPr == null) { + return; + } + if (width == 0.) { - if (spPr.isSetLn() && spPr.getLn().isSetW()) - spPr.getLn().unsetW(); + if (lnPr.isSetW()) { + lnPr.unsetW(); + } + if (!lnPr.isSetNoFill()) { + lnPr.addNewNoFill(); + } + if (lnPr.isSetSolidFill()) { + lnPr.unsetSolidFill(); + } + if (lnPr.isSetGradFill()) { + lnPr.unsetGradFill(); + } + if (lnPr.isSetPattFill()) { + lnPr.unsetPattFill(); + } } else { - CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr - .addNewLn(); - ln.setW(Units.toEMU(width)); + if (lnPr.isSetNoFill()) { + lnPr.unsetNoFill(); + } + + lnPr.setW(Units.toEMU(width)); } } @@ -334,8 +388,7 @@ public abstract class XSLFSimpleShape extends XSLFShape public double getLineWidth() { PropertyFetcher fetcher = new PropertyFetcher() { public boolean fetch(XSLFShape shape) { - CTShapeProperties spPr = shape.getSpPr(); - CTLineProperties ln = spPr.getLn(); + CTLineProperties ln = getLn(shape, false); if (ln != null) { if (ln.isSetNoFill()) { setValue(0.); @@ -370,12 +423,15 @@ public abstract class XSLFSimpleShape extends XSLFShape * @param compound set the line compound style */ public void setLineCompound(LineCompound compound) { - CTShapeProperties spPr = getSpPr(); + CTLineProperties ln = getLn(this, true); + if (ln == null) { + return; + } if (compound == null) { - if (spPr.isSetLn() && spPr.getLn().isSetCmpd()) - spPr.getLn().unsetCmpd(); + if (ln.isSetCmpd()) { + ln.unsetCmpd(); + } } else { - CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr.addNewLn(); STCompoundLine.Enum xCmpd; switch (compound) { default: @@ -405,8 +461,7 @@ public abstract class XSLFSimpleShape extends XSLFShape public LineCompound getLineCompound() { PropertyFetcher fetcher = new PropertyFetcher() { public boolean fetch(XSLFShape shape) { - CTShapeProperties spPr = shape.getSpPr(); - CTLineProperties ln = spPr.getLn(); + CTLineProperties ln = getLn(shape, false); if (ln != null) { STCompoundLine.Enum stCmpd = ln.getCmpd(); if (stCmpd != null) { @@ -422,29 +477,24 @@ public abstract class XSLFSimpleShape extends XSLFShape Integer cmpd = fetcher.getValue(); if (cmpd == null) { CTLineProperties defaultLn = getDefaultLineProperties(); - if (defaultLn != null) { - STCompoundLine.Enum stCmpd = defaultLn.getCmpd(); - if (stCmpd != null) { - cmpd = stCmpd.intValue(); + if (defaultLn != null && defaultLn.isSetCmpd()) { + switch (defaultLn.getCmpd().intValue()) { + default: + case STCompoundLine.INT_SNG: + return LineCompound.SINGLE; + case STCompoundLine.INT_DBL: + return LineCompound.DOUBLE; + case STCompoundLine.INT_THICK_THIN: + return LineCompound.THICK_THIN; + case STCompoundLine.INT_THIN_THICK: + return LineCompound.THIN_THICK; + case STCompoundLine.INT_TRI: + return LineCompound.TRIPLE; } } } - if (cmpd == null) return null; - - switch (cmpd) { - default: - case STCompoundLine.INT_SNG: - return LineCompound.SINGLE; - case STCompoundLine.INT_DBL: - return LineCompound.DOUBLE; - case STCompoundLine.INT_THICK_THIN: - return LineCompound.THICK_THIN; - case STCompoundLine.INT_THIN_THICK: - return LineCompound.THIN_THICK; - case STCompoundLine.INT_TRI: - return LineCompound.TRIPLE; - } + return null; } /** @@ -452,34 +502,34 @@ public abstract class XSLFSimpleShape extends XSLFShape * @param dash a preset line dashing scheme to stroke thr shape outline */ public void setLineDash(LineDash dash) { - CTShapeProperties spPr = getSpPr(); + CTLineProperties ln = getLn(this, true); + if (ln == null) { + return; + } if (dash == null) { - if (spPr.isSetLn() && spPr.getLn().isSetPrstDash()) - spPr.getLn().unsetPrstDash(); + if (ln.isSetPrstDash()) { + ln.unsetPrstDash(); + } } else { - CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr.addNewLn(); CTPresetLineDashProperties ldp = ln.isSetPrstDash() ? ln.getPrstDash() : ln.addNewPrstDash(); ldp.setVal(STPresetLineDashVal.Enum.forInt(dash.ooxmlId)); } } /** - * @return a preset line dashing scheme to stroke thr shape outline + * @return a preset line dashing scheme to stroke the shape outline */ public LineDash getLineDash() { PropertyFetcher fetcher = new PropertyFetcher() { public boolean fetch(XSLFShape shape) { - CTShapeProperties spPr = shape.getSpPr(); - CTLineProperties ln = spPr.getLn(); - if (ln != null) { - CTPresetLineDashProperties ctDash = ln.getPrstDash(); - if (ctDash != null) { - setValue(LineDash.fromOoxmlId(ctDash.getVal().intValue())); - return true; - } + CTLineProperties ln = getLn(shape, false); + if (ln == null || !ln.isSetPrstDash()) { + return false; } - return false; + + setValue(LineDash.fromOoxmlId(ln.getPrstDash().getVal().intValue())); + return true; } }; fetchShapeProperty(fetcher); @@ -487,11 +537,8 @@ public abstract class XSLFSimpleShape extends XSLFShape LineDash dash = fetcher.getValue(); if (dash == null) { CTLineProperties defaultLn = getDefaultLineProperties(); - if (defaultLn != null) { - CTPresetLineDashProperties ctDash = defaultLn.getPrstDash(); - if (ctDash != null) { - dash = LineDash.fromOoxmlId(ctDash.getVal().intValue()); - } + if (defaultLn != null && defaultLn.isSetPrstDash()) { + dash = LineDash.fromOoxmlId(defaultLn.getPrstDash().getVal().intValue()); } } return dash; @@ -502,13 +549,16 @@ public abstract class XSLFSimpleShape extends XSLFShape * @param cap the line end cap style */ public void setLineCap(LineCap cap) { - CTShapeProperties spPr = getSpPr(); + CTLineProperties ln = getLn(this, true); + if (ln == null) { + return; + } + if (cap == null) { - if (spPr.isSetLn() && spPr.getLn().isSetCap()) - spPr.getLn().unsetCap(); + if (ln.isSetCap()) { + ln.unsetCap(); + } } else { - CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr - .addNewLn(); ln.setCap(STLineCap.Enum.forInt(cap.ooxmlId)); } } @@ -520,14 +570,10 @@ public abstract class XSLFSimpleShape extends XSLFShape public LineCap getLineCap() { PropertyFetcher fetcher = new PropertyFetcher() { public boolean fetch(XSLFShape shape) { - CTShapeProperties spPr = shape.getSpPr(); - CTLineProperties ln = spPr.getLn(); - if (ln != null) { - STLineCap.Enum stCap = ln.getCap(); - if (stCap != null) { - setValue(LineCap.fromOoxmlId(stCap.intValue())); - return true; - } + CTLineProperties ln = getLn(shape, false); + if (ln != null && ln.isSetCap()) { + setValue(LineCap.fromOoxmlId(ln.getCap().intValue())); + return true; } return false; } @@ -537,11 +583,8 @@ public abstract class XSLFSimpleShape extends XSLFShape LineCap cap = fetcher.getValue(); if (cap == null) { CTLineProperties defaultLn = getDefaultLineProperties(); - if (defaultLn != null) { - STLineCap.Enum stCap = defaultLn.getCap(); - if (stCap != null) { - cap = LineCap.fromOoxmlId(stCap.intValue()); - } + if (defaultLn != null && defaultLn.isSetCap()) { + cap = LineCap.fromOoxmlId(defaultLn.getCap().intValue()); } } return cap; @@ -549,21 +592,36 @@ public abstract class XSLFSimpleShape extends XSLFShape @Override public void setFillColor(Color color) { - CTShapeProperties spPr = getSpPr(); + XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(getShapeProperties()); + if (fp == null) { + return; + } if (color == null) { - if (spPr.isSetSolidFill()) { - spPr.unsetSolidFill(); + if (fp.isSetSolidFill()) { + fp.unsetSolidFill(); + } + + if (fp.isSetGradFill()) { + fp.unsetGradFill(); } - if (!spPr.isSetNoFill()) { - spPr.addNewNoFill(); + if (fp.isSetPattFill()) { + fp.unsetGradFill(); + } + + if (fp.isSetBlipFill()) { + fp.unsetBlipFill(); + } + + if (!fp.isSetNoFill()) { + fp.addNewNoFill(); } } else { - if (spPr.isSetNoFill()) { - spPr.unsetNoFill(); + if (fp.isSetNoFill()) { + fp.unsetNoFill(); } - CTSolidColorFillProperties fill = spPr.isSetSolidFill() ? spPr.getSolidFill() : spPr.addNewSolidFill(); + CTSolidColorFillProperties fill = fp.isSetSolidFill() ? fp.getSolidFill() : fp.addNewSolidFill(); XSLFColor col = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr()); col.setColor(color); @@ -574,7 +632,7 @@ public abstract class XSLFSimpleShape extends XSLFShape public Color getFillColor() { PaintStyle ps = getFillPaint(); if (ps instanceof SolidPaint) { - return ((SolidPaint)ps).getSolidColor().getColor(); + return DrawPaint.applyColorTransform(((SolidPaint)ps).getSolidColor()); } return null; } @@ -585,9 +643,9 @@ public abstract class XSLFSimpleShape extends XSLFShape public XSLFShadow getShadow() { PropertyFetcher fetcher = new PropertyFetcher() { public boolean fetch(XSLFShape shape) { - CTShapeProperties spPr = shape.getSpPr(); - if (spPr.isSetEffectLst()) { - CTOuterShadowEffect obj = spPr.getEffectLst().getOuterShdw(); + XSLFEffectProperties ep = XSLFPropertiesDelegate.getEffectDelegate(shape.getShapeProperties()); + if (ep != null && ep.isSetEffectLst()) { + CTOuterShadowEffect obj = ep.getEffectLst().getOuterShdw(); setValue(obj == null ? NO_SHADOW : obj); return true; } @@ -600,7 +658,7 @@ public abstract class XSLFSimpleShape extends XSLFShape if (obj == null) { // fill color was not found, check if it is defined in the theme CTShapeStyle style = getSpStyle(); - if (style != null) { + if (style != null && style.getEffectRef() != null) { // 1-based index of a shadow style within the style matrix int idx = (int) style.getEffectRef().getIdx(); if(idx != 0) { @@ -618,17 +676,22 @@ public abstract class XSLFSimpleShape extends XSLFShape * @return definition of the shape geometry */ public CustomGeometry getGeometry(){ - CTShapeProperties spPr = getSpPr(); + XSLFGeometryProperties gp = XSLFPropertiesDelegate.getGeometryDelegate(getShapeProperties()); + + if (gp == null) { + return null; + } + CustomGeometry geom; PresetGeometries dict = PresetGeometries.getInstance(); - if(spPr.isSetPrstGeom()){ - String name = spPr.getPrstGeom().getPrst().toString(); + if(gp.isSetPrstGeom()){ + String name = gp.getPrstGeom().getPrst().toString(); geom = dict.get(name); if(geom == null) { throw new IllegalStateException("Unknown shape geometry: " + name + ", available geometries are: " + dict.keySet()); } - } else if (spPr.isSetCustGeom()){ - XMLStreamReader staxReader = spPr.getCustGeom().newXMLStreamReader(); + } else if (gp.isSetCustGeom()){ + XMLStreamReader staxReader = gp.getCustGeom().newXMLStreamReader(); geom = PresetGeometries.convertCustomGeometry(staxReader); try { staxReader.close(); } catch (XMLStreamException e) {} @@ -650,8 +713,9 @@ public abstract class XSLFSimpleShape extends XSLFShape setFillColor(srsSolidFill); } - if(getSpPr().isSetBlipFill()){ - CTBlip blip = getSpPr().getBlipFill().getBlip(); + XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(getShapeProperties()); + if(fp != null && fp.isSetBlipFill()){ + CTBlip blip = fp.getBlipFill().getBlip(); String blipId = blip.getEmbed(); String relId = getSheet().importBlip(blipId, s.getSheet().getPackagePart()); @@ -686,130 +750,193 @@ public abstract class XSLFSimpleShape extends XSLFShape /** * Specifies the line end decoration, such as a triangle or arrowhead. + * + * @param style the line end docoration style */ public void setLineHeadDecoration(DecorationShape style) { - CTLineProperties ln = getSpPr().getLn(); + CTLineProperties ln = getLn(this, true); + if (ln == null) { + return; + } CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd(); if (style == null) { - if (lnEnd.isSetType()) lnEnd.unsetType(); + if (lnEnd.isSetType()) { + lnEnd.unsetType(); + } } else { lnEnd.setType(STLineEndType.Enum.forInt(style.ooxmlId)); } } + /** + * @return the line end decoration shape + */ public DecorationShape getLineHeadDecoration() { - CTLineProperties ln = getSpPr().getLn(); - if (ln == null || !ln.isSetHeadEnd()) return DecorationShape.NONE; - - STLineEndType.Enum end = ln.getHeadEnd().getType(); - return end == null ? DecorationShape.NONE : DecorationShape.fromOoxmlId(end.intValue()); + CTLineProperties ln = getLn(this, false); + DecorationShape ds = DecorationShape.NONE; + if (ln != null && ln.isSetHeadEnd() && ln.getHeadEnd().isSetType()) { + ds = DecorationShape.fromOoxmlId(ln.getHeadEnd().getType().intValue()); + } + return ds; } /** - * specifies decorations which can be added to the head of a line. + * specifies decoration width of the head of a line. + * + * @param style the decoration width */ public void setLineHeadWidth(DecorationSize style) { - CTLineProperties ln = getSpPr().getLn(); + CTLineProperties ln = getLn(this, true); + if (ln == null) { + return; + } CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd(); if (style == null) { - if (lnEnd.isSetW()) lnEnd.unsetW(); + if (lnEnd.isSetW()) { + lnEnd.unsetW(); + } } else { lnEnd.setW(STLineEndWidth.Enum.forInt(style.ooxmlId)); } } + /** + * @return the line end decoration width + */ public DecorationSize getLineHeadWidth() { - CTLineProperties ln = getSpPr().getLn(); - if (ln == null || !ln.isSetHeadEnd()) return DecorationSize.MEDIUM; - - STLineEndWidth.Enum w = ln.getHeadEnd().getW(); - return w == null ? DecorationSize.MEDIUM : DecorationSize.fromOoxmlId(w.intValue()); + CTLineProperties ln = getLn(this, false); + DecorationSize ds = DecorationSize.MEDIUM; + if (ln != null && ln.isSetHeadEnd() && ln.getHeadEnd().isSetW()) { + ds = DecorationSize.fromOoxmlId(ln.getHeadEnd().getW().intValue()); + } + return ds; } /** * Specifies the line end width in relation to the line width. */ public void setLineHeadLength(DecorationSize style) { - CTLineProperties ln = getSpPr().getLn(); + CTLineProperties ln = getLn(this, true); + if (ln == null) { + return; + } + CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd(); - if (style == null) { - if (lnEnd.isSetLen()) lnEnd.unsetLen(); + if (lnEnd.isSetLen()) { + lnEnd.unsetLen(); + } } else { lnEnd.setLen(STLineEndLength.Enum.forInt(style.ooxmlId)); } } + /** + * @return the line end decoration length + */ public DecorationSize getLineHeadLength() { - CTLineProperties ln = getSpPr().getLn(); - if (ln == null || !ln.isSetHeadEnd()) return DecorationSize.MEDIUM; - - STLineEndLength.Enum len = ln.getHeadEnd().getLen(); - return len == null ? DecorationSize.MEDIUM : DecorationSize.fromOoxmlId(len.intValue()); + CTLineProperties ln = getLn(this, false); + + DecorationSize ds = DecorationSize.MEDIUM; + if (ln != null && ln.isSetHeadEnd() && ln.getHeadEnd().isSetLen()) { + ds = DecorationSize.fromOoxmlId(ln.getHeadEnd().getLen().intValue()); + } + return ds; } /** * Specifies the line end decoration, such as a triangle or arrowhead. */ public void setLineTailDecoration(DecorationShape style) { - CTLineProperties ln = getSpPr().getLn(); + CTLineProperties ln = getLn(this, true); + if (ln == null) { + return; + } + CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd(); if (style == null) { - if (lnEnd.isSetType()) lnEnd.unsetType(); + if (lnEnd.isSetType()) { + lnEnd.unsetType(); + } } else { lnEnd.setType(STLineEndType.Enum.forInt(style.ooxmlId)); } } + /** + * @return the line end decoration shape + */ public DecorationShape getLineTailDecoration() { - CTLineProperties ln = getSpPr().getLn(); - if (ln == null || !ln.isSetTailEnd()) return DecorationShape.NONE; - - STLineEndType.Enum end = ln.getTailEnd().getType(); - return end == null ? DecorationShape.NONE : DecorationShape.fromOoxmlId(end.intValue()); + CTLineProperties ln = getLn(this, false); + + DecorationShape ds = DecorationShape.NONE; + if (ln != null && ln.isSetTailEnd() && ln.getTailEnd().isSetType()) { + ds = DecorationShape.fromOoxmlId(ln.getTailEnd().getType().intValue()); + } + return ds; } /** * specifies decorations which can be added to the tail of a line. */ public void setLineTailWidth(DecorationSize style) { - CTLineProperties ln = getSpPr().getLn(); + CTLineProperties ln = getLn(this, true); + if (ln == null) { + return; + } + CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd(); if (style == null) { - if (lnEnd.isSetW()) lnEnd.unsetW(); + if (lnEnd.isSetW()) { + lnEnd.unsetW(); + } } else { lnEnd.setW(STLineEndWidth.Enum.forInt(style.ooxmlId)); } } + /** + * @return the line end decoration width + */ public DecorationSize getLineTailWidth() { - CTLineProperties ln = getSpPr().getLn(); - if (ln == null || !ln.isSetTailEnd()) return DecorationSize.MEDIUM; - - STLineEndWidth.Enum w = ln.getTailEnd().getW(); - return w == null ? DecorationSize.MEDIUM : DecorationSize.fromOoxmlId(w.intValue()); + CTLineProperties ln = getLn(this, false); + DecorationSize ds = DecorationSize.MEDIUM; + if (ln != null && ln.isSetTailEnd() && ln.getTailEnd().isSetW()) { + ds = DecorationSize.fromOoxmlId(ln.getTailEnd().getW().intValue()); + } + return ds; } /** * Specifies the line end width in relation to the line width. */ public void setLineTailLength(DecorationSize style) { - CTLineProperties ln = getSpPr().getLn(); + CTLineProperties ln = getLn(this, true); + if (ln == null) { + return; + } + CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd(); - if (style == null) { - if (lnEnd.isSetLen()) lnEnd.unsetLen(); + if (lnEnd.isSetLen()) { + lnEnd.unsetLen(); + } } else { lnEnd.setLen(STLineEndLength.Enum.forInt(style.ooxmlId)); } } + /** + * @return the line end decoration length + */ public DecorationSize getLineTailLength() { - CTLineProperties ln = getSpPr().getLn(); - if (ln == null || !ln.isSetTailEnd()) return DecorationSize.MEDIUM; - - STLineEndLength.Enum len = ln.getTailEnd().getLen(); - return len == null ? DecorationSize.MEDIUM : DecorationSize.fromOoxmlId(len.intValue()); + CTLineProperties ln = getLn(this, false); + + DecorationSize ds = DecorationSize.MEDIUM; + if (ln != null && ln.isSetTailEnd() && ln.getTailEnd().isSetLen()) { + ds = DecorationSize.fromOoxmlId(ln.getTailEnd().getLen().intValue()); + } + return ds; } public boolean isPlaceholder() { @@ -818,9 +945,10 @@ public abstract class XSLFSimpleShape extends XSLFShape } public Guide getAdjustValue(String name) { - CTPresetGeometry2D prst = getSpPr().getPrstGeom(); - if (prst.isSetAvLst()) { - for (CTGeomGuide g : prst.getAvLst().getGdArray()) { + XSLFGeometryProperties gp = XSLFPropertiesDelegate.getGeometryDelegate(getShapeProperties()); + + if (gp != null && gp.isSetPrstGeom() && gp.getPrstGeom().isSetAvLst()) { + for (CTGeomGuide g : gp.getPrstGeom().getAvLst().getGdArray()) { if (g.getName().equals(name)) { return new Guide(g.getName(), g.getFmla()); } @@ -943,4 +1071,15 @@ public abstract class XSLFSimpleShape extends XSLFShape } return hl; } -} + + private static CTLineProperties getLn(XSLFShape shape, boolean create) { + XmlObject pr = shape.getShapeProperties(); + if (!(pr instanceof CTShapeProperties)) { + LOG.log(POILogger.WARN, shape.getClass().toString()+" doesn't have line properties"); + return null; + } + + CTShapeProperties spr = (CTShapeProperties)pr; + return (spr.isSetLn() || !create) ? spr.getLn() : spr.addNewLn(); + } +} \ No newline at end of file diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java index 9a309157a..de707dfd2 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java @@ -23,7 +23,9 @@ import java.awt.Color; import java.awt.geom.Rectangle2D; import org.apache.poi.sl.draw.DrawPaint; +import org.apache.poi.sl.usermodel.ColorStyle; import org.apache.poi.sl.usermodel.PaintStyle; +import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; import org.apache.poi.sl.usermodel.StrokeStyle; import org.apache.poi.sl.usermodel.StrokeStyle.LineCap; import org.apache.poi.sl.usermodel.StrokeStyle.LineCompound; @@ -31,9 +33,9 @@ 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.xslf.usermodel.XSLFPropertiesDelegate.XSLFFillProperties; import org.apache.poi.xslf.usermodel.XSLFTableStyle.TablePartStyle; import org.apache.xmlbeans.XmlObject; -import org.openxmlformats.schemas.drawingml.x2006.main.CTFillProperties; import org.openxmlformats.schemas.drawingml.x2006.main.CTFontReference; import org.openxmlformats.schemas.drawingml.x2006.main.CTLineEndProperties; import org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties; @@ -41,13 +43,13 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D; import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D; import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun; import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor; -import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties; import org.openxmlformats.schemas.drawingml.x2006.main.CTTable; import org.openxmlformats.schemas.drawingml.x2006.main.CTTableCell; import org.openxmlformats.schemas.drawingml.x2006.main.CTTableCellProperties; import org.openxmlformats.schemas.drawingml.x2006.main.CTTablePartStyle; import org.openxmlformats.schemas.drawingml.x2006.main.CTTableProperties; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTableStyleCellStyle; import org.openxmlformats.schemas.drawingml.x2006.main.CTTableStyleTextStyle; import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody; import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph; @@ -393,22 +395,27 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell fetcher = new CharacterPropertyFetcher(_p.getIndentLevel()){ public boolean fetch(CTTextCharacterProperties props){ - if (props != null) { - XSLFShape shape = _p.getParentShape(); - CTShapeStyle style = shape.getSpStyle(); - CTSchemeColor phClr = null; - if (style != null && style.getFontRef() != null) { - phClr = style.getFontRef().getSchemeClr(); - } - - PaintStyle ps = shape.getPaint(props, phClr); - if (ps != null) { - setValue(ps); - return true; - } + if (props == null) { + return false; + } + + XSLFShape shape = _p.getParentShape(); + CTShapeStyle style = shape.getSpStyle(); + CTSchemeColor phClr = null; + if (style != null && style.getFontRef() != null) { + phClr = style.getFontRef().getSchemeClr(); + } + + XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(props); + XSLFSheet sheet = shape.getSheet(); + PackagePart pp = sheet.getPackagePart(); + XSLFTheme theme = sheet.getTheme(); + PaintStyle ps = XSLFShape.selectPaint(fp, phClr, pp, theme); + + if (ps != null) { + setValue(ps); + return true; } return false; diff --git a/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFSlideShow.java b/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFSlideShow.java index 8e13603da..95dd57d15 100644 --- a/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFSlideShow.java +++ b/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFSlideShow.java @@ -22,6 +22,8 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import java.awt.Color; +import java.awt.geom.Rectangle2D; import java.io.IOException; import org.apache.poi.POIDataSamples; @@ -29,7 +31,12 @@ import org.apache.poi.POIXMLProperties.CoreProperties; import org.apache.poi.openxml4j.exceptions.OpenXML4JException; import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.PackagePart; +import org.apache.poi.sl.usermodel.ShapeType; +import org.apache.poi.xslf.usermodel.XMLSlideShow; +import org.apache.poi.xslf.usermodel.XSLFAutoShape; +import org.apache.poi.xslf.usermodel.XSLFBackground; import org.apache.poi.xslf.usermodel.XSLFRelation; +import org.apache.poi.xslf.usermodel.XSLFSlide; import org.apache.poi.xslf.usermodel.XSLFSlideShow; import org.apache.xmlbeans.XmlException; import org.junit.Before; @@ -126,4 +133,24 @@ public class TestXSLFSlideShow { xml.close(); } + + @Test + public void testMasterBackground() throws IOException { + XMLSlideShow ppt = new XMLSlideShow(); + XSLFBackground b = ppt.getSlideMasters().get(0).getBackground(); + b.setFillColor(Color.RED); + + XSLFSlide sl = ppt.createSlide(); + XSLFAutoShape as = sl.createAutoShape(); + as.setAnchor(new Rectangle2D.Double(100,100,100,100)); + as.setShapeType(ShapeType.CLOUD); + + XMLSlideShow ppt2 = XSLFTestDataSamples.writeOutAndReadBack(ppt); + ppt.close(); + + XSLFBackground b2 = ppt2.getSlideMasters().get(0).getBackground(); + assertEquals(Color.RED, b2.getFillColor()); + + ppt2.close(); + } } diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFConnectorShape.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFConnectorShape.java index fb86c1926..059856242 100644 --- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFConnectorShape.java +++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFConnectorShape.java @@ -18,9 +18,11 @@ package org.apache.poi.xslf.usermodel; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.apache.poi.xslf.usermodel.TestXSLFSimpleShape.getSpPr; import java.awt.Color; import java.awt.geom.Rectangle2D; +import java.io.IOException; import org.apache.poi.sl.usermodel.LineDecoration.DecorationShape; import org.apache.poi.sl.usermodel.LineDecoration.DecorationSize; @@ -34,21 +36,18 @@ import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndWidth; import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType; import org.openxmlformats.schemas.presentationml.x2006.main.CTConnector; -/** - * @author Yegor Kozlov - */ public class TestXSLFConnectorShape { @Test - public void testLineDecorations() { + public void testLineDecorations() throws IOException { XMLSlideShow ppt = new XMLSlideShow(); XSLFSlide slide = ppt.createSlide(); XSLFConnectorShape shape = slide.createConnector(); assertEquals(1, slide.getShapes().size()); - assertFalse(shape.getSpPr().getLn().isSetHeadEnd()); - assertFalse(shape.getSpPr().getLn().isSetTailEnd()); + assertFalse(getSpPr(shape).getLn().isSetHeadEnd()); + assertFalse(getSpPr(shape).getLn().isSetTailEnd()); // line decorations assertEquals(DecorationShape.NONE, shape.getLineHeadDecoration()); @@ -57,22 +56,22 @@ public class TestXSLFConnectorShape { shape.setLineTailDecoration(null); assertEquals(DecorationShape.NONE, shape.getLineHeadDecoration()); assertEquals(DecorationShape.NONE, shape.getLineTailDecoration()); - assertFalse(shape.getSpPr().getLn().getHeadEnd().isSetType()); - assertFalse(shape.getSpPr().getLn().getTailEnd().isSetType()); + assertFalse(getSpPr(shape).getLn().getHeadEnd().isSetType()); + assertFalse(getSpPr(shape).getLn().getTailEnd().isSetType()); shape.setLineHeadDecoration(DecorationShape.ARROW); shape.setLineTailDecoration(DecorationShape.DIAMOND); assertEquals(DecorationShape.ARROW, shape.getLineHeadDecoration()); assertEquals(DecorationShape.DIAMOND, shape.getLineTailDecoration()); - assertEquals(STLineEndType.ARROW, shape.getSpPr().getLn().getHeadEnd().getType()); - assertEquals(STLineEndType.DIAMOND, shape.getSpPr().getLn().getTailEnd().getType()); + assertEquals(STLineEndType.ARROW, getSpPr(shape).getLn().getHeadEnd().getType()); + assertEquals(STLineEndType.DIAMOND, getSpPr(shape).getLn().getTailEnd().getType()); shape.setLineHeadDecoration(DecorationShape.DIAMOND); shape.setLineTailDecoration(DecorationShape.ARROW); assertEquals(DecorationShape.DIAMOND, shape.getLineHeadDecoration()); assertEquals(DecorationShape.ARROW, shape.getLineTailDecoration()); - assertEquals(STLineEndType.DIAMOND, shape.getSpPr().getLn().getHeadEnd().getType()); - assertEquals(STLineEndType.ARROW, shape.getSpPr().getLn().getTailEnd().getType()); + assertEquals(STLineEndType.DIAMOND, getSpPr(shape).getLn().getHeadEnd().getType()); + assertEquals(STLineEndType.ARROW, getSpPr(shape).getLn().getTailEnd().getType()); // line end width assertEquals(DecorationSize.MEDIUM, shape.getLineHeadWidth()); @@ -81,20 +80,20 @@ public class TestXSLFConnectorShape { shape.setLineHeadWidth(null); assertEquals(DecorationSize.MEDIUM, shape.getLineHeadWidth()); assertEquals(DecorationSize.MEDIUM, shape.getLineTailWidth()); - assertFalse(shape.getSpPr().getLn().getHeadEnd().isSetW()); - assertFalse(shape.getSpPr().getLn().getTailEnd().isSetW()); + assertFalse(getSpPr(shape).getLn().getHeadEnd().isSetW()); + assertFalse(getSpPr(shape).getLn().getTailEnd().isSetW()); shape.setLineHeadWidth(DecorationSize.LARGE); shape.setLineTailWidth(DecorationSize.MEDIUM); assertEquals(DecorationSize.LARGE, shape.getLineHeadWidth()); assertEquals(DecorationSize.MEDIUM, shape.getLineTailWidth()); - assertEquals(STLineEndWidth.LG, shape.getSpPr().getLn().getHeadEnd().getW()); - assertEquals(STLineEndWidth.MED, shape.getSpPr().getLn().getTailEnd().getW()); + assertEquals(STLineEndWidth.LG, getSpPr(shape).getLn().getHeadEnd().getW()); + assertEquals(STLineEndWidth.MED, getSpPr(shape).getLn().getTailEnd().getW()); shape.setLineHeadWidth(DecorationSize.MEDIUM); shape.setLineTailWidth(DecorationSize.LARGE); assertEquals(DecorationSize.MEDIUM, shape.getLineHeadWidth()); assertEquals(DecorationSize.LARGE, shape.getLineTailWidth()); - assertEquals(STLineEndWidth.MED, shape.getSpPr().getLn().getHeadEnd().getW()); - assertEquals(STLineEndWidth.LG, shape.getSpPr().getLn().getTailEnd().getW()); + assertEquals(STLineEndWidth.MED, getSpPr(shape).getLn().getHeadEnd().getW()); + assertEquals(STLineEndWidth.LG, getSpPr(shape).getLn().getTailEnd().getW()); // line end length assertEquals(DecorationSize.MEDIUM, shape.getLineHeadLength()); @@ -103,25 +102,26 @@ public class TestXSLFConnectorShape { shape.setLineTailLength(null); assertEquals(DecorationSize.MEDIUM, shape.getLineHeadLength()); assertEquals(DecorationSize.MEDIUM, shape.getLineTailLength()); - assertFalse(shape.getSpPr().getLn().getHeadEnd().isSetLen()); - assertFalse(shape.getSpPr().getLn().getTailEnd().isSetLen()); + assertFalse(getSpPr(shape).getLn().getHeadEnd().isSetLen()); + assertFalse(getSpPr(shape).getLn().getTailEnd().isSetLen()); shape.setLineHeadLength(DecorationSize.LARGE); shape.setLineTailLength(DecorationSize.MEDIUM); assertEquals(DecorationSize.LARGE, shape.getLineHeadLength()); assertEquals(DecorationSize.MEDIUM, shape.getLineTailLength()); - assertEquals(STLineEndLength.LG, shape.getSpPr().getLn().getHeadEnd().getLen()); - assertEquals(STLineEndLength.MED, shape.getSpPr().getLn().getTailEnd().getLen()); + assertEquals(STLineEndLength.LG, getSpPr(shape).getLn().getHeadEnd().getLen()); + assertEquals(STLineEndLength.MED, getSpPr(shape).getLn().getTailEnd().getLen()); shape.setLineHeadLength(DecorationSize.MEDIUM); shape.setLineTailLength(DecorationSize.LARGE); assertEquals(DecorationSize.MEDIUM, shape.getLineHeadLength()); assertEquals(DecorationSize.LARGE, shape.getLineTailLength()); - assertEquals(STLineEndLength.MED, shape.getSpPr().getLn().getHeadEnd().getLen()); - assertEquals(STLineEndLength.LG, shape.getSpPr().getLn().getTailEnd().getLen()); + assertEquals(STLineEndLength.MED, getSpPr(shape).getLn().getHeadEnd().getLen()); + assertEquals(STLineEndLength.LG, getSpPr(shape).getLn().getTailEnd().getLen()); + ppt.close(); } @Test - public void testAddConnector(){ + public void testAddConnector() throws IOException { XMLSlideShow pptx = new XMLSlideShow(); XSLFSlide slide = pptx.createSlide(); @@ -152,6 +152,8 @@ public class TestXSLFConnectorShape { end.setId(rect2.getShapeId()); // side of the rectangle to attach the connector: left=1, bottom=2,right=3, top=4 end.setIdx(3); + + pptx.close(); } } \ No newline at end of file diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFFreeformShape.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFFreeformShape.java index b7b902f54..5a4e100e6 100644 --- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFFreeformShape.java +++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFFreeformShape.java @@ -16,7 +16,9 @@ ==================================================================== */ package org.apache.poi.xslf.usermodel; + import static org.junit.Assert.assertEquals; +import static org.apache.poi.xslf.usermodel.TestXSLFSimpleShape.getSpPr; import java.awt.geom.Ellipse2D; import java.awt.geom.Path2D; @@ -25,9 +27,6 @@ import java.io.IOException; import org.junit.Test; -/** - * @author Yegor Kozlov - */ public class TestXSLFFreeformShape { @Test @@ -49,7 +48,7 @@ public class TestXSLFFreeformShape { XSLFFreeformShape shape2 = slide.createFreeform(); shape2.setPath(path2); - assertEquals(shape1.getSpPr().getCustGeom().toString(), shape2.getSpPr().getCustGeom().toString()); + assertEquals(getSpPr(shape1).getCustGeom().toString(), getSpPr(shape2).getCustGeom().toString()); ppt.close(); } diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSimpleShape.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSimpleShape.java index 64dde4e66..c000da8a4 100644 --- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSimpleShape.java +++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSimpleShape.java @@ -23,7 +23,10 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import java.awt.*; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.RenderingHints; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.List; @@ -36,6 +39,7 @@ import org.apache.poi.sl.usermodel.StrokeStyle.LineCap; import org.apache.poi.sl.usermodel.StrokeStyle.LineDash; import org.apache.poi.util.Units; import org.apache.poi.xslf.XSLFTestDataSamples; +import org.apache.xmlbeans.XmlObject; import org.junit.Test; import org.openxmlformats.schemas.drawingml.x2006.main.CTEffectStyleItem; import org.openxmlformats.schemas.drawingml.x2006.main.CTEffectStyleList; @@ -48,9 +52,6 @@ import org.openxmlformats.schemas.drawingml.x2006.main.STLineCap; import org.openxmlformats.schemas.drawingml.x2006.main.STPresetLineDashVal; import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType; -/** - * @author Yegor Kozlov - */ public class TestXSLFSimpleShape { @Test @@ -61,7 +62,7 @@ public class TestXSLFSimpleShape { XSLFSimpleShape shape = slide.createAutoShape(); assertEquals(1, slide.getShapes().size()); // line properties are not set by default - assertFalse(shape.getSpPr().isSetLn()); + assertFalse(getSpPr(shape).isSetLn()); assertEquals(0., shape.getLineWidth(), 0); assertEquals(null, shape.getLineColor()); @@ -73,60 +74,60 @@ public class TestXSLFSimpleShape { shape.setLineDash(null); shape.setLineCap(null); - // still no line properties - assertFalse(shape.getSpPr().isSetLn()); + assertTrue(getSpPr(shape).isSetLn()); + assertTrue(getSpPr(shape).getLn().isSetNoFill()); // line width shape.setLineWidth(1.0); assertEquals(1.0, shape.getLineWidth(), 0); - assertEquals(Units.EMU_PER_POINT, shape.getSpPr().getLn().getW()); + assertEquals(Units.EMU_PER_POINT, getSpPr(shape).getLn().getW()); shape.setLineWidth(5.5); assertEquals(5.5, shape.getLineWidth(), 0); - assertEquals(Units.toEMU(5.5), shape.getSpPr().getLn().getW()); + assertEquals(Units.toEMU(5.5), getSpPr(shape).getLn().getW()); shape.setLineWidth(0.0); // setting line width to zero unsets the W attribute - assertFalse(shape.getSpPr().getLn().isSetW()); + assertFalse(getSpPr(shape).getLn().isSetW()); // line cap shape.setLineCap(LineCap.FLAT); assertEquals(LineCap.FLAT, shape.getLineCap()); - assertEquals(STLineCap.FLAT, shape.getSpPr().getLn().getCap()); + assertEquals(STLineCap.FLAT, getSpPr(shape).getLn().getCap()); shape.setLineCap(LineCap.SQUARE); assertEquals(LineCap.SQUARE, shape.getLineCap()); - assertEquals(STLineCap.SQ, shape.getSpPr().getLn().getCap()); + assertEquals(STLineCap.SQ, getSpPr(shape).getLn().getCap()); shape.setLineCap(LineCap.ROUND); assertEquals(LineCap.ROUND, shape.getLineCap()); - assertEquals(STLineCap.RND, shape.getSpPr().getLn().getCap()); + assertEquals(STLineCap.RND, getSpPr(shape).getLn().getCap()); shape.setLineCap(null); // setting cap to null unsets the Cap attribute - assertFalse(shape.getSpPr().getLn().isSetCap()); + assertFalse(getSpPr(shape).getLn().isSetCap()); // line dash shape.setLineDash(LineDash.SOLID); assertEquals(LineDash.SOLID, shape.getLineDash()); - assertEquals(STPresetLineDashVal.SOLID, shape.getSpPr().getLn().getPrstDash().getVal()); + assertEquals(STPresetLineDashVal.SOLID, getSpPr(shape).getLn().getPrstDash().getVal()); shape.setLineDash(LineDash.DASH_DOT); assertEquals(LineDash.DASH_DOT, shape.getLineDash()); - assertEquals(STPresetLineDashVal.DASH_DOT, shape.getSpPr().getLn().getPrstDash().getVal()); + assertEquals(STPresetLineDashVal.DASH_DOT, getSpPr(shape).getLn().getPrstDash().getVal()); shape.setLineDash(LineDash.LG_DASH_DOT); assertEquals(LineDash.LG_DASH_DOT, shape.getLineDash()); - assertEquals(STPresetLineDashVal.LG_DASH_DOT, shape.getSpPr().getLn().getPrstDash().getVal()); + assertEquals(STPresetLineDashVal.LG_DASH_DOT, getSpPr(shape).getLn().getPrstDash().getVal()); shape.setLineDash(null); // setting dash width to null unsets the Dash element - assertFalse(shape.getSpPr().getLn().isSetPrstDash()); + assertFalse(getSpPr(shape).getLn().isSetPrstDash()); // line color - assertFalse(shape.getSpPr().getLn().isSetSolidFill()); + assertFalse(getSpPr(shape).getLn().isSetSolidFill()); shape.setLineColor(Color.RED); assertEquals(Color.RED, shape.getLineColor()); - assertTrue(shape.getSpPr().getLn().isSetSolidFill()); + assertTrue(getSpPr(shape).getLn().isSetSolidFill()); shape.setLineColor(Color.BLUE); assertEquals(Color.BLUE, shape.getLineColor()); - assertTrue(shape.getSpPr().getLn().isSetSolidFill()); + assertTrue(getSpPr(shape).getLn().isSetSolidFill()); shape.setLineColor(null); assertEquals(null, shape.getLineColor()); // setting dash width to null unsets the SolidFill element - assertFalse(shape.getSpPr().getLn().isSetSolidFill()); + assertFalse(getSpPr(shape).getLn().isSetSolidFill()); XSLFSimpleShape ln2 = slide.createAutoShape(); ln2.setLineDash(LineDash.DOT); @@ -152,22 +153,22 @@ public class TestXSLFSimpleShape { XSLFAutoShape shape = slide.createAutoShape(); // line properties are not set by default - assertFalse(shape.getSpPr().isSetSolidFill()); + assertFalse(getSpPr(shape).isSetSolidFill()); assertNull(shape.getFillColor()); shape.setFillColor(null); assertNull(shape.getFillColor()); - assertFalse(shape.getSpPr().isSetSolidFill()); + assertFalse(getSpPr(shape).isSetSolidFill()); shape.setFillColor(Color.RED); assertEquals(Color.RED, shape.getFillColor()); shape.setFillColor(Color.DARK_GRAY); assertEquals(Color.DARK_GRAY, shape.getFillColor()); - assertTrue(shape.getSpPr().isSetSolidFill()); + assertTrue(getSpPr(shape).isSetSolidFill()); shape.setFillColor(null); assertNull(shape.getFillColor()); - assertFalse(shape.getSpPr().isSetSolidFill()); + assertFalse(getSpPr(shape).isSetSolidFill()); ppt.close(); } @@ -188,56 +189,56 @@ public class TestXSLFSimpleShape { XSLFSimpleShape s0 = (XSLFSimpleShape) shapes.get(0); // fill is not set - assertNull(s0.getSpPr().getSolidFill()); + assertNull(getSpPr(s0).getSolidFill()); //assertEquals(slide6.getTheme().getColor("accent1").getColor(), s0.getFillColor()); assertEquals(new Color(79, 129, 189), s0.getFillColor()); // lighter 80% XSLFSimpleShape s1 = (XSLFSimpleShape)shapes.get(1); - CTSchemeColor ref1 = s1.getSpPr().getSolidFill().getSchemeClr(); + CTSchemeColor ref1 = getSpPr(s1).getSolidFill().getSchemeClr(); assertEquals(1, ref1.sizeOfLumModArray()); assertEquals(1, ref1.sizeOfLumOffArray()); assertEquals(20000, ref1.getLumModArray(0).getVal()); assertEquals(80000, ref1.getLumOffArray(0).getVal()); assertEquals("accent1", ref1.getVal().toString()); - assertEquals(new Color(79, 129, 189), s1.getFillColor()); + assertEquals(new Color(220, 230, 242), s1.getFillColor()); // lighter 60% XSLFSimpleShape s2 = (XSLFSimpleShape)shapes.get(2); - CTSchemeColor ref2 = s2.getSpPr().getSolidFill().getSchemeClr(); + CTSchemeColor ref2 = getSpPr(s2).getSolidFill().getSchemeClr(); assertEquals(1, ref2.sizeOfLumModArray()); assertEquals(1, ref2.sizeOfLumOffArray()); assertEquals(40000, ref2.getLumModArray(0).getVal()); assertEquals(60000, ref2.getLumOffArray(0).getVal()); assertEquals("accent1", ref2.getVal().toString()); - assertEquals(new Color(79, 129, 189), s2.getFillColor()); + assertEquals(new Color(185, 205, 229), s2.getFillColor()); // lighter 40% XSLFSimpleShape s3 = (XSLFSimpleShape)shapes.get(3); - CTSchemeColor ref3 = s3.getSpPr().getSolidFill().getSchemeClr(); + CTSchemeColor ref3 = getSpPr(s3).getSolidFill().getSchemeClr(); assertEquals(1, ref3.sizeOfLumModArray()); assertEquals(1, ref3.sizeOfLumOffArray()); assertEquals(60000, ref3.getLumModArray(0).getVal()); assertEquals(40000, ref3.getLumOffArray(0).getVal()); assertEquals("accent1", ref3.getVal().toString()); - assertEquals(new Color(79, 129, 189), s3.getFillColor()); + assertEquals(new Color(149, 179, 215), s3.getFillColor()); // darker 25% XSLFSimpleShape s4 = (XSLFSimpleShape)shapes.get(4); - CTSchemeColor ref4 = s4.getSpPr().getSolidFill().getSchemeClr(); + CTSchemeColor ref4 = getSpPr(s4).getSolidFill().getSchemeClr(); assertEquals(1, ref4.sizeOfLumModArray()); assertEquals(0, ref4.sizeOfLumOffArray()); assertEquals(75000, ref4.getLumModArray(0).getVal()); assertEquals("accent1", ref3.getVal().toString()); - assertEquals(new Color(79, 129, 189), s4.getFillColor()); + assertEquals(new Color(55, 96, 146), s4.getFillColor()); XSLFSimpleShape s5 = (XSLFSimpleShape)shapes.get(5); - CTSchemeColor ref5 = s5.getSpPr().getSolidFill().getSchemeClr(); + CTSchemeColor ref5 = getSpPr(s5).getSolidFill().getSchemeClr(); assertEquals(1, ref5.sizeOfLumModArray()); assertEquals(0, ref5.sizeOfLumOffArray()); assertEquals(50000, ref5.getLumModArray(0).getVal()); assertEquals("accent1", ref5.getVal().toString()); - assertEquals(new Color(79, 129, 189), s5.getFillColor()); + assertEquals(new Color(37, 64, 97), s5.getFillColor()); ppt.close(); } @@ -253,13 +254,13 @@ public class TestXSLFSimpleShape { XSLFTextShape sh1 = (XSLFTextShape)shapes2.get(0); assertEquals(Placeholder.CENTERED_TITLE, sh1.getTextType()); assertEquals("PPTX Title", sh1.getText()); - assertNull(sh1.getSpPr().getXfrm()); // xfrm is not set, the query is delegated to the slide layout + assertFalse(getSpPr(sh1).isSetXfrm()); // xfrm is not set, the query is delegated to the slide layout assertEquals(sh1.getAnchor(), layout2.getTextShapeByType(Placeholder.CENTERED_TITLE).getAnchor()); XSLFTextShape sh2 = (XSLFTextShape)shapes2.get(1); assertEquals("Subtitle\nAnd second line", sh2.getText()); assertEquals(Placeholder.SUBTITLE, sh2.getTextType()); - assertNull(sh2.getSpPr().getXfrm()); // xfrm is not set, the query is delegated to the slide layout + assertFalse(getSpPr(sh2).isSetXfrm()); // xfrm is not set, the query is delegated to the slide layout assertEquals(sh2.getAnchor(), layout2.getTextShapeByType(Placeholder.SUBTITLE).getAnchor()); XSLFSlide slide5 = slide.get(4); @@ -267,16 +268,16 @@ public class TestXSLFSimpleShape { XSLFTextShape shTitle = slide5.getTextShapeByType(Placeholder.TITLE); assertEquals("Hyperlinks", shTitle.getText()); // xfrm is not set, the query is delegated to the slide layout - assertNull(shTitle.getSpPr().getXfrm()); + assertFalse(getSpPr(shTitle).isSetXfrm()); // xfrm is not set, the query is delegated to the slide master - assertNull(layout5.getTextShapeByType(Placeholder.TITLE).getSpPr().getXfrm()); - assertNotNull(layout5.getSlideMaster().getTextShapeByType(Placeholder.TITLE).getSpPr().getXfrm()); + assertFalse(getSpPr(layout5.getTextShapeByType(Placeholder.TITLE)).isSetXfrm()); + assertTrue(getSpPr(layout5.getSlideMaster().getTextShapeByType(Placeholder.TITLE)).isSetXfrm()); assertEquals(shTitle.getAnchor(), layout5.getSlideMaster().getTextShapeByType(Placeholder.TITLE).getAnchor()); ppt.close(); } - @SuppressWarnings({ "deprecation", "unused" }) + @SuppressWarnings("unused") @Test public void testShadowEffects() throws IOException{ XMLSlideShow ppt = new XMLSlideShow(); @@ -296,7 +297,7 @@ public class TestXSLFSimpleShape { XSLFSlide slide = ppt.createSlide(); XSLFSimpleShape shape = slide.createAutoShape(); - CTShapeProperties spPr = shape.getSpPr(); + CTShapeProperties spPr = getSpPr(shape); CTPresetGeometry2D prstGeom = CTPresetGeometry2D.Factory.newInstance(); prstGeom.setPrst(STShapeType.Enum.forInt(1)); @@ -320,7 +321,7 @@ public class TestXSLFSimpleShape { XSLFSlide slide = ppt.createSlide(); XSLFSimpleShape shape = slide.createAutoShape(); - CTShapeProperties spPr = shape.getSpPr(); + CTShapeProperties spPr = getSpPr(shape); CTPresetGeometry2D prstGeom = CTPresetGeometry2D.Factory.newInstance(); prstGeom.setPrst(STShapeType.Enum.forInt(1)); @@ -376,4 +377,10 @@ public class TestXSLFSimpleShape { } ppt.close(); } + + static CTShapeProperties getSpPr(XSLFShape shape) { + XmlObject xo = shape.getShapeProperties(); + assertTrue(xo instanceof CTShapeProperties); + return (CTShapeProperties)xo; + } } \ No newline at end of file diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java index a87a9cb55..8ae19f265 100644 --- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java +++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java @@ -23,6 +23,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; +import static org.apache.poi.xslf.usermodel.TestXSLFSimpleShape.getSpPr; import java.awt.Color; import java.io.File; @@ -73,10 +74,10 @@ public class TestXSLFTextShape { CTPlaceholder ph1 = shape1.getCTPlaceholder(); assertEquals(STPlaceholderType.CTR_TITLE, ph1.getType()); // anchor is not defined in the shape - assertNull(shape1.getSpPr().getXfrm()); + assertNull(getSpPr(shape1).getXfrm()); XSLFTextShape masterShape1 = (XSLFTextShape)layout.getPlaceholder(ph1); - assertNotNull(masterShape1.getSpPr().getXfrm()); + assertNotNull(getSpPr(masterShape1).getXfrm()); assertEquals(masterShape1.getAnchor(), shape1.getAnchor()); CTTextBodyProperties bodyPr1 = shape1.getTextBodyPr(); @@ -103,10 +104,10 @@ public class TestXSLFTextShape { CTPlaceholder ph2 = shape2.getCTPlaceholder(); assertEquals(STPlaceholderType.SUB_TITLE, ph2.getType()); // anchor is not defined in the shape - assertNull(shape2.getSpPr().getXfrm()); + assertNull(getSpPr(shape2).getXfrm()); XSLFTextShape masterShape2 = (XSLFTextShape)layout.getPlaceholder(ph2); - assertNotNull(masterShape2.getSpPr().getXfrm()); + assertNotNull(getSpPr(masterShape2).getXfrm()); assertEquals(masterShape2.getAnchor(), shape2.getAnchor()); CTTextBodyProperties bodyPr2 = shape2.getTextBodyPr(); @@ -139,13 +140,13 @@ public class TestXSLFTextShape { CTPlaceholder ph1 = shape1.getCTPlaceholder(); assertEquals(STPlaceholderType.TITLE, ph1.getType()); // anchor is not defined in the shape - assertNull(shape1.getSpPr().getXfrm()); + assertNull(getSpPr(shape1).getXfrm()); XSLFTextShape masterShape1 = (XSLFTextShape)layout.getPlaceholder(ph1); // layout does not have anchor info either, it is in the slide master - assertNull(masterShape1.getSpPr().getXfrm()); + assertNull(getSpPr(masterShape1).getXfrm()); masterShape1 = (XSLFTextShape)layout.getSlideMaster().getPlaceholder(ph1); - assertNotNull(masterShape1.getSpPr().getXfrm()); + assertNotNull(getSpPr(masterShape1).getXfrm()); assertEquals(masterShape1.getAnchor(), shape1.getAnchor()); CTTextBodyProperties bodyPr1 = shape1.getTextBodyPr(); @@ -174,13 +175,13 @@ public class TestXSLFTextShape { assertTrue(ph2.isSetIdx()); assertEquals(1, ph2.getIdx()); // anchor is not defined in the shape - assertNull(shape2.getSpPr().getXfrm()); + assertNull(getSpPr(shape2).getXfrm()); XSLFTextShape masterShape2 = (XSLFTextShape)layout.getPlaceholder(ph2); // anchor of the body text is missing in the slide layout, llokup in the slide master - assertNull(masterShape2.getSpPr().getXfrm()); + assertNull(getSpPr(masterShape2).getXfrm()); masterShape2 = (XSLFTextShape)layout.getSlideMaster().getPlaceholder(ph2); - assertNotNull(masterShape2.getSpPr().getXfrm()); + assertNotNull(getSpPr(masterShape2).getXfrm()); assertEquals(masterShape2.getAnchor(), shape2.getAnchor()); CTTextBodyProperties bodyPr2 = shape2.getTextBodyPr(); @@ -252,10 +253,10 @@ public class TestXSLFTextShape { CTPlaceholder ph1 = shape1.getCTPlaceholder(); assertEquals(STPlaceholderType.TITLE, ph1.getType()); // anchor is not defined in the shape - assertNull(shape1.getSpPr().getXfrm()); + assertNull(getSpPr(shape1).getXfrm()); XSLFTextShape masterShape1 = (XSLFTextShape)layout.getPlaceholder(ph1); - assertNotNull(masterShape1.getSpPr().getXfrm()); + assertNotNull(getSpPr(masterShape1).getXfrm()); assertEquals(masterShape1.getAnchor(), shape1.getAnchor()); CTTextBodyProperties bodyPr1 = shape1.getTextBodyPr(); @@ -286,10 +287,10 @@ public class TestXSLFTextShape { CTPlaceholder ph2 = shape2.getCTPlaceholder(); assertEquals(STPlaceholderType.BODY, ph2.getType()); // anchor is not defined in the shape - assertNull(shape2.getSpPr().getXfrm()); + assertNull(getSpPr(shape2).getXfrm()); XSLFTextShape masterShape2 = (XSLFTextShape)layout.getPlaceholder(ph2); - assertNotNull(masterShape2.getSpPr().getXfrm()); + assertNotNull(getSpPr(masterShape2).getXfrm()); assertEquals(masterShape2.getAnchor(), shape2.getAnchor()); CTTextBodyProperties bodyPr2 = shape2.getTextBodyPr(); @@ -323,13 +324,13 @@ public class TestXSLFTextShape { CTPlaceholder ph1 = shape1.getCTPlaceholder(); assertEquals(STPlaceholderType.TITLE, ph1.getType()); // anchor is not defined in the shape - assertNull(shape1.getSpPr().getXfrm()); + assertNull(getSpPr(shape1).getXfrm()); XSLFTextShape masterShape1 = (XSLFTextShape)layout.getPlaceholder(ph1); // layout does not have anchor info either, it is in the slide master - assertNull(masterShape1.getSpPr().getXfrm()); + assertNull(getSpPr(masterShape1).getXfrm()); masterShape1 = (XSLFTextShape)layout.getSlideMaster().getPlaceholder(ph1); - assertNotNull(masterShape1.getSpPr().getXfrm()); + assertNotNull(getSpPr(masterShape1).getXfrm()); assertEquals(masterShape1.getAnchor(), shape1.getAnchor()); CTTextBodyProperties bodyPr1 = shape1.getTextBodyPr(); @@ -359,10 +360,10 @@ public class TestXSLFTextShape { assertTrue(ph2.isSetIdx()); assertEquals(1, ph2.getIdx()); // // anchor is not defined in the shape - assertNull(shape2.getSpPr().getXfrm()); + assertNull(getSpPr(shape2).getXfrm()); XSLFTextShape masterShape2 = (XSLFTextShape)layout.getPlaceholder(ph2); - assertNotNull(masterShape2.getSpPr().getXfrm()); + assertNotNull(getSpPr(masterShape2).getXfrm()); assertEquals(masterShape2.getAnchor(), shape2.getAnchor()); CTTextBodyProperties bodyPr2 = shape2.getTextBodyPr(); @@ -438,7 +439,7 @@ public class TestXSLFTextShape { CTPlaceholder ph1 = shape1.getCTPlaceholder(); assertEquals(STPlaceholderType.TITLE, ph1.getType()); // anchor is not defined in the shape - assertNull(shape1.getSpPr().getXfrm()); + assertNull(getSpPr(shape1).getXfrm()); CTTextBodyProperties bodyPr1 = shape1.getTextBodyPr(); // none of the following properties are set in the shapes and fetched from the master shape @@ -506,11 +507,11 @@ public class TestXSLFTextShape { CTPlaceholder ph1 = shape1.getCTPlaceholder(); assertEquals(STPlaceholderType.TITLE, ph1.getType()); // anchor is not defined in the shape - assertNull(shape1.getSpPr().getXfrm()); + assertNull(getSpPr(shape1).getXfrm()); XSLFTextShape masterShape1 = (XSLFTextShape)layout.getPlaceholder(ph1); // layout does not have anchor info either, it is in the slide master - assertNotNull(masterShape1.getSpPr().getXfrm()); + assertNotNull(getSpPr(masterShape1).getXfrm()); assertEquals(masterShape1.getAnchor(), shape1.getAnchor()); CTTextBodyProperties bodyPr1 = shape1.getTextBodyPr(); @@ -541,10 +542,10 @@ public class TestXSLFTextShape { assertTrue(ph2.isSetIdx()); assertEquals(1, ph2.getIdx()); // anchor is not defined in the shape - assertNull(shape2.getSpPr().getXfrm()); + assertNull(getSpPr(shape2).getXfrm()); XSLFTextShape masterShape2 = (XSLFTextShape)layout.getPlaceholder(ph2); - assertNotNull(masterShape2.getSpPr().getXfrm()); + assertNotNull(getSpPr(masterShape2).getXfrm()); assertEquals(masterShape2.getAnchor(), shape2.getAnchor()); CTTextBodyProperties bodyPr2 = shape2.getTextBodyPr();