Added: poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFParagraphProperties.java URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFParagraphProperties.java?rev=1839255&view=auto ============================================================================== --- poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFParagraphProperties.java (added) +++ poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFParagraphProperties.java Sun Aug 26 21:18:54 2018 @@ -0,0 +1,258 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.xddf.usermodel.text; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import org.apache.poi.util.Beta; +import org.apache.poi.util.Internal; +import org.apache.poi.util.Units; +import org.apache.poi.xddf.usermodel.XDDFExtensionList; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties; + +@Beta +public class XDDFParagraphProperties { + private CTTextParagraphProperties props; + private XDDFParagraphBulletProperties bullet; + + @Internal + protected XDDFParagraphProperties(CTTextParagraphProperties properties) { + this.props = properties; + this.bullet = new XDDFParagraphBulletProperties(properties); + } + + @Internal + protected CTTextParagraphProperties getXmlObject() { + return props; + } + + public XDDFParagraphBulletProperties getBulletProperties() { + return bullet; + } + + public int getLevel() { + if (props.isSetLvl()) { + return 1 + props.getLvl(); + } else { + return 0; + } + } + + public void setLevel(Integer level) { + if (level == null) { + props.unsetLvl(); + } else if (level < 1 || 9 < level) { + throw new IllegalArgumentException("Minimum inclusive: 1. Maximum inclusive: 9."); + } else { + props.setLvl(level - 1); + } + } + + public XDDFRunProperties getDefaultRunProperties() { + if (props.isSetDefRPr()) { + return new XDDFRunProperties(props.getDefRPr()); + } else { + return null; + } + } + + public void setDefaultRunProperties(XDDFRunProperties properties) { + if (properties == null) { + props.unsetDefRPr(); + } else { + props.setDefRPr(properties.getXmlObject()); + } + } + + public void setEastAsianLineBreak(Boolean value) { + if (value == null) { + props.unsetEaLnBrk(); + } else { + props.setEaLnBrk(value); + } + } + + public void setLatinLineBreak(Boolean value) { + if (value == null) { + props.unsetLatinLnBrk(); + } else { + props.setLatinLnBrk(value); + } + } + + public void setHangingPunctuation(Boolean value) { + if (value == null) { + props.unsetHangingPunct(); + } else { + props.setHangingPunct(value); + } + } + + public void setRightToLeft(Boolean value) { + if (value == null) { + props.unsetRtl(); + } else { + props.setRtl(value); + } + } + + public void setFontAlignment(FontAlignment align) { + if (align == null) { + props.unsetFontAlgn(); + } else { + props.setFontAlgn(align.underlying); + } + } + + public void setTextAlignment(TextAlignment align) { + if (align == null) { + props.unsetAlgn(); + } else { + props.setAlgn(align.underlying); + } + } + + public void setDefaultTabSize(Double points) { + if (points == null) { + props.unsetDefTabSz(); + } else { + props.setDefTabSz(Units.toEMU(points)); + } + } + + public void setIndentation(Double points) { + if (points == null) { + props.unsetIndent(); + } else if (points < -4032 || 4032 < points) { + throw new IllegalArgumentException("Minimum inclusive = -4032. Maximum inclusive = 4032."); + } else { + props.setIndent(Units.toEMU(points)); + } + } + + public void setMarginLeft(Double points) { + if (points == null) { + props.unsetMarL(); + } else if (points < 0 || 4032 < points) { + throw new IllegalArgumentException("Minimum inclusive = 0. Maximum inclusive = 4032."); + } else { + props.setMarL(Units.toEMU(points)); + } + } + + public void setMarginRight(Double points) { + if (points == null) { + props.unsetMarR(); + } else if (points < 0 || 4032 < points) { + throw new IllegalArgumentException("Minimum inclusive = 0. Maximum inclusive = 4032."); + } else { + props.setMarR(Units.toEMU(points)); + } + } + + public void setLineSpacing(XDDFSpacing spacing) { + if (spacing == null) { + props.unsetLnSpc(); + } else { + props.setLnSpc(spacing.getXmlObject()); + } + } + + public void setSpaceAfter(XDDFSpacing spacing) { + if (spacing == null) { + props.unsetSpcAft(); + } else { + props.setSpcAft(spacing.getXmlObject()); + } + } + + public void setSpaceBefore(XDDFSpacing spacing) { + if (spacing == null) { + props.unsetSpcBef(); + } else { + props.setSpcBef(spacing.getXmlObject()); + } + } + + public XDDFTabStop addTabStop() { + if (!props.isSetTabLst()) { + props.addNewTabLst(); + } + return new XDDFTabStop(props.getTabLst().addNewTab()); + } + + public XDDFTabStop insertTabStop(int index) { + if (!props.isSetTabLst()) { + props.addNewTabLst(); + } + return new XDDFTabStop(props.getTabLst().insertNewTab(index)); + } + + public void removeTabStop(int index) { + if (props.isSetTabLst()) { + props.getTabLst().removeTab(index); + } + } + + public XDDFTabStop getTabStop(int index) { + if (props.isSetTabLst()) { + return new XDDFTabStop(props.getTabLst().getTabArray(index)); + } else { + return null; + } + } + + public List<XDDFTabStop> getTabStops() { + if (props.isSetTabLst()) { + return Collections.unmodifiableList(props + .getTabLst() + .getTabList() + .stream() + .map(gs -> new XDDFTabStop(gs)) + .collect(Collectors.toList())); + } else { + return Collections.emptyList(); + } + } + + public int countTabStops() { + if (props.isSetTabLst()) { + return props.getTabLst().sizeOfTabArray(); + } else { + return 0; + } + } + + public XDDFExtensionList getExtensionList() { + if (props.isSetExtLst()) { + return new XDDFExtensionList(props.getExtLst()); + } else { + return null; + } + } + + public void setExtensionList(XDDFExtensionList list) { + if (list == null) { + props.unsetExtLst(); + } else { + props.setExtLst(list.getXmlObject()); + } + } +}
Added: poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFRunProperties.java URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFRunProperties.java?rev=1839255&view=auto ============================================================================== --- poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFRunProperties.java (added) +++ poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFRunProperties.java Sun Aug 26 21:18:54 2018 @@ -0,0 +1,335 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.xddf.usermodel.text; + +import java.util.Locale; + +import org.apache.poi.util.Beta; +import org.apache.poi.util.Internal; +import org.apache.poi.xddf.usermodel.XDDFColor; +import org.apache.poi.xddf.usermodel.XDDFEffectContainer; +import org.apache.poi.xddf.usermodel.XDDFEffectList; +import org.apache.poi.xddf.usermodel.XDDFExtensionList; +import org.apache.poi.xddf.usermodel.XDDFFillProperties; +import org.apache.poi.xddf.usermodel.XDDFGradientFillProperties; +import org.apache.poi.xddf.usermodel.XDDFGroupFillProperties; +import org.apache.poi.xddf.usermodel.XDDFLineProperties; +import org.apache.poi.xddf.usermodel.XDDFNoFillProperties; +import org.apache.poi.xddf.usermodel.XDDFPatternFillProperties; +import org.apache.poi.xddf.usermodel.XDDFPictureFillProperties; +import org.apache.poi.xddf.usermodel.XDDFSolidFillProperties; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextFont; + +@Beta +public class XDDFRunProperties { + private CTTextCharacterProperties props; + + public XDDFRunProperties() { + this(CTTextCharacterProperties.Factory.newInstance()); + } + + @Internal + protected XDDFRunProperties(CTTextCharacterProperties properties) { + this.props = properties; + } + + @Internal + protected CTTextCharacterProperties getXmlObject() { + return props; + } + + public void setBaseline(Integer value) { + if (value == null) { + props.unsetBaseline(); + } else { + props.setBaseline(value); + } + } + + public void setDirty(Boolean dirty) { + if (dirty == null) { + props.unsetDirty(); + } else { + props.setDirty(dirty); + } + } + + public void setSpellError(Boolean error) { + if (error == null) { + props.unsetErr(); + } else { + props.setErr(error); + } + } + + public void setNoProof(Boolean noproof) { + if (noproof == null) { + props.unsetNoProof(); + } else { + props.setNoProof(noproof); + } + } + + public void setNormalizeHeights(Boolean normalize) { + if (normalize == null) { + props.unsetNormalizeH(); + } else { + props.setNormalizeH(normalize); + } + } + + public void setKumimoji(Boolean kumimoji) { + if (kumimoji == null) { + props.unsetKumimoji(); + } else { + props.setKumimoji(kumimoji); + } + } + + public void setBold(Boolean bold) { + if (bold == null) { + props.unsetB(); + } else { + props.setB(bold); + } + } + + public void setItalic(Boolean italic) { + if (italic == null) { + props.unsetI(); + } else { + props.setI(italic); + } + } + + public void setFontSize(Double size) { + if (size == null) { + props.unsetSz(); + } else if (size < 1 || 400 < size) { + throw new IllegalArgumentException("Minimum inclusive = 1. Maximum inclusive = 400."); + } else { + props.setSz((int)(100 * size)); + } + } + + public void setFillProperties(XDDFFillProperties properties) { + props.unsetBlipFill(); + props.unsetGradFill(); + props.unsetGrpFill(); + props.unsetNoFill(); + props.unsetPattFill(); + props.unsetSolidFill(); + if (properties == null) { + return; + } + if (properties instanceof XDDFGradientFillProperties) { + props.setGradFill(((XDDFGradientFillProperties) properties).getXmlObject()); + } else if (properties instanceof XDDFGroupFillProperties) { + props.setGrpFill(((XDDFGroupFillProperties) properties).getXmlObject()); + } else if (properties instanceof XDDFNoFillProperties) { + props.setNoFill(((XDDFNoFillProperties) properties).getXmlObject()); + } else if (properties instanceof XDDFPatternFillProperties) { + props.setPattFill(((XDDFPatternFillProperties) properties).getXmlObject()); + } else if (properties instanceof XDDFPictureFillProperties) { + props.setBlipFill(((XDDFPictureFillProperties) properties).getXmlObject()); + } else if (properties instanceof XDDFSolidFillProperties) { + props.setSolidFill(((XDDFSolidFillProperties) properties).getXmlObject()); + } + } + + public void setCharacterKerning(Double kerning) { + if (kerning == null) { + props.unsetKern(); + } else if (kerning < 0 || 4000 < kerning) { + throw new IllegalArgumentException("Minimum inclusive = 0. Maximum inclusive = 4000."); + } else { + props.setKern((int)(100*kerning)); + } + } + + public void setCharacterSpacing(Double spacing) { + if (spacing == null) { + props.unsetSpc(); + } else if (spacing < -4000 || 4000 < spacing) { + throw new IllegalArgumentException("Minimum inclusive = -4000. Maximum inclusive = 4000."); + } else { + props.setSpc((int)(100*spacing)); + } + } + + public void setFonts(XDDFFont[] fonts) { + for (XDDFFont font: fonts) { + CTTextFont xml = font.getXmlObject(); + switch (font.getGroup()) { + case COMPLEX_SCRIPT: + if (xml == null) { + props.unsetCs(); + } else { + props.setCs(xml); + } + case EAST_ASIAN: + if (xml == null) { + props.unsetEa(); + } else { + props.setEa(xml); + } + case LATIN: + if (xml == null) { + props.unsetLatin(); + } else { + props.setLatin(xml); + } + case SYMBOL: + if (xml == null) { + props.unsetSym(); + } else { + props.setSym(xml); + } + } + } + } + + public void setUnderline(UnderlineType underline) { + if (underline == null) { + props.unsetU(); + } else { + props.setU(underline.underlying); + } + } + + public void setStrikeThrough(StrikeType strike) { + if (strike == null) { + props.unsetStrike(); + } else { + props.setStrike(strike.underlying); + } + } + + public void setCapitals(CapsType caps) { + if (caps == null) { + props.unsetCap(); + } else { + props.setCap(caps.underlying); + } + } + + public void setHyperlink(XDDFHyperlink link) { + if (link == null) { + props.unsetHlinkClick(); + } else { + props.setHlinkClick(link.getXmlObject()); + } + } + + public void setMouseOver(XDDFHyperlink link) { + if (link == null) { + props.unsetHlinkMouseOver(); + } else { + props.setHlinkMouseOver(link.getXmlObject()); + } + } + + public void setLanguage(Locale lang) { + if (lang == null) { + props.unsetLang(); + } else { + props.setLang(lang.toLanguageTag()); + } + } + + public void setAlternativeLanguage(Locale lang) { + if (lang == null) { + props.unsetAltLang(); + } else { + props.setAltLang(lang.toLanguageTag()); + } + } + + public void setHighlight(XDDFColor color) { + if (color == null) { + props.unsetHighlight(); + } else { + props.setHighlight(color.getColorContainer()); + } + } + + public void setLineProperties(XDDFLineProperties properties) { + if (properties == null) { + props.unsetLn(); + } else { + props.setLn(properties.getXmlObject()); + } + } + + public void setBookmark(String bookmark) { + if (bookmark == null) { + props.unsetBmk(); + } else { + props.setBmk(bookmark); + } + } + + public XDDFExtensionList getExtensionList() { + if (props.isSetExtLst()) { + return new XDDFExtensionList(props.getExtLst()); + } else { + return null; + } + } + + public void setExtensionList(XDDFExtensionList list) { + if (list == null) { + props.unsetExtLst(); + } else { + props.setExtLst(list.getXmlObject()); + } + } + + public XDDFEffectContainer getEffectContainer() { + if (props.isSetEffectDag()) { + return new XDDFEffectContainer(props.getEffectDag()); + } else { + return null; + } + } + + public void setEffectContainer(XDDFEffectContainer container) { + if (container == null) { + props.unsetEffectDag(); + } else { + props.setEffectDag(container.getXmlObject()); + } + } + + public XDDFEffectList getEffectList() { + if (props.isSetEffectLst()) { + return new XDDFEffectList(props.getEffectLst()); + } else { + return null; + } + } + + public void setEffectList(XDDFEffectList list) { + if (list == null) { + props.unsetEffectLst(); + } else { + props.setEffectLst(list.getXmlObject()); + } + } +} Copied: poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFShapeAutoFit.java (from r1839252, poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFTextBody.java) URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFShapeAutoFit.java?p2=poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFShapeAutoFit.java&p1=poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFTextBody.java&r1=1839252&r2=1839255&rev=1839255&view=diff ============================================================================== --- poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFTextBody.java (original) +++ poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFShapeAutoFit.java Sun Aug 26 21:18:54 2018 @@ -19,23 +19,33 @@ package org.apache.poi.xddf.usermodel.te import org.apache.poi.util.Beta; import org.apache.poi.util.Internal; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextShapeAutofit; @Beta -public class XDDFTextBody { - private CTTextBody body; +public class XDDFShapeAutoFit implements XDDFAutoFit { + private CTTextShapeAutofit autofit; - public XDDFTextBody() { - this(CTTextBody.Factory.newInstance()); + public XDDFShapeAutoFit() { + this(CTTextShapeAutofit.Factory.newInstance()); } @Internal - public XDDFTextBody(CTTextBody body) { - this.body = body; + protected XDDFShapeAutoFit(CTTextShapeAutofit autofit) { + this.autofit = autofit; } @Internal - public CTTextBody getXmlObject() { - return body; + protected CTTextShapeAutofit getXmlObject() { + return autofit; + } + + @Override + public int getFontScale() { + return 100_000; + } + + @Override + public int getLineSpaceReduction() { + return 0; } } Copied: poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFSpacing.java (from r1839252, poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFTextBody.java) URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFSpacing.java?p2=poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFSpacing.java&p1=poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFTextBody.java&r1=1839252&r2=1839255&rev=1839255&view=diff ============================================================================== --- poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFTextBody.java (original) +++ poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFSpacing.java Sun Aug 26 21:18:54 2018 @@ -19,23 +19,26 @@ package org.apache.poi.xddf.usermodel.te import org.apache.poi.util.Beta; import org.apache.poi.util.Internal; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextSpacing; @Beta -public class XDDFTextBody { - private CTTextBody body; - - public XDDFTextBody() { - this(CTTextBody.Factory.newInstance()); +public abstract class XDDFSpacing { + public static enum Kind { + PERCENT, + POINTS; } + protected CTTextSpacing spacing; + @Internal - public XDDFTextBody(CTTextBody body) { - this.body = body; + protected XDDFSpacing(CTTextSpacing spacing) { + this.spacing = spacing; } + public abstract Kind getType(); + @Internal - public CTTextBody getXmlObject() { - return body; + protected CTTextSpacing getXmlObject() { + return spacing; } } Copied: poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFSpacingPercent.java (from r1839252, poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFTextBody.java) URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFSpacingPercent.java?p2=poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFSpacingPercent.java&p1=poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFTextBody.java&r1=1839252&r2=1839255&rev=1839255&view=diff ============================================================================== --- poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFTextBody.java (original) +++ poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFSpacingPercent.java Sun Aug 26 21:18:54 2018 @@ -19,23 +19,38 @@ package org.apache.poi.xddf.usermodel.te import org.apache.poi.util.Beta; import org.apache.poi.util.Internal; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextSpacing; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextSpacingPercent; @Beta -public class XDDFTextBody { - private CTTextBody body; +public class XDDFSpacingPercent extends XDDFSpacing { + private CTTextSpacingPercent percent; + private Double scale; - public XDDFTextBody() { - this(CTTextBody.Factory.newInstance()); + public XDDFSpacingPercent(double value) { + this(CTTextSpacing.Factory.newInstance(), CTTextSpacingPercent.Factory.newInstance(), null); + spacing.unsetSpcPts(); + spacing.setSpcPct(percent); + setPercent(value); } @Internal - public XDDFTextBody(CTTextBody body) { - this.body = body; + protected XDDFSpacingPercent(CTTextSpacing parent, CTTextSpacingPercent percent, Double scale) { + super(parent); + this.percent = percent; + this.scale = (scale == null) ? 0.001 : scale * 0.001; } - @Internal - public CTTextBody getXmlObject() { - return body; + @Override + public Kind getType() { + return Kind.PERCENT; + } + + public double getPercent() { + return percent.getVal() * scale; + } + + public void setPercent(double value) { + percent.setVal((int)(1000 * value)); } } Copied: poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFSpacingPoints.java (from r1839252, poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFTextBody.java) URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFSpacingPoints.java?p2=poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFSpacingPoints.java&p1=poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFTextBody.java&r1=1839252&r2=1839255&rev=1839255&view=diff ============================================================================== --- poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFTextBody.java (original) +++ poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFSpacingPoints.java Sun Aug 26 21:18:54 2018 @@ -19,23 +19,36 @@ package org.apache.poi.xddf.usermodel.te import org.apache.poi.util.Beta; import org.apache.poi.util.Internal; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextSpacing; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextSpacingPoint; @Beta -public class XDDFTextBody { - private CTTextBody body; +public class XDDFSpacingPoints extends XDDFSpacing { + private CTTextSpacingPoint points; - public XDDFTextBody() { - this(CTTextBody.Factory.newInstance()); + public XDDFSpacingPoints(double value) { + this(CTTextSpacing.Factory.newInstance(), CTTextSpacingPoint.Factory.newInstance()); + spacing.unsetSpcPct(); + spacing.setSpcPts(points); + setPoints(value); } @Internal - public XDDFTextBody(CTTextBody body) { - this.body = body; + protected XDDFSpacingPoints(CTTextSpacing parent, CTTextSpacingPoint points) { + super(parent); + this.points = points; } - @Internal - public CTTextBody getXmlObject() { - return body; + @Override + public Kind getType() { + return Kind.POINTS; + } + + public double getPoints() { + return points.getVal() * 0.01; + } + + public void setPoints(double value) { + points.setVal((int)(100 * value)); } } Copied: poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFTabStop.java (from r1839252, poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFTextBody.java) URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFTabStop.java?p2=poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFTabStop.java&p1=poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFTextBody.java&r1=1839252&r2=1839255&rev=1839255&view=diff ============================================================================== --- poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFTextBody.java (original) +++ poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFTabStop.java Sun Aug 26 21:18:54 2018 @@ -19,23 +19,52 @@ package org.apache.poi.xddf.usermodel.te import org.apache.poi.util.Beta; import org.apache.poi.util.Internal; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody; +import org.apache.poi.util.Units; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextTabStop; @Beta -public class XDDFTextBody { - private CTTextBody body; +public class XDDFTabStop { + private CTTextTabStop stop; - public XDDFTextBody() { - this(CTTextBody.Factory.newInstance()); + @Internal + protected XDDFTabStop(CTTextTabStop stop) { + this.stop = stop; } @Internal - public XDDFTextBody(CTTextBody body) { - this.body = body; + protected CTTextTabStop getXmlObject() { + return stop; } - @Internal - public CTTextBody getXmlObject() { - return body; + public TabAlignment getAlignment() { + if (stop.isSetAlgn()) { + return TabAlignment.valueOf(stop.getAlgn()); + } else { + return null; + } + } + + public void setAlignment(TabAlignment align) { + if (align == null) { + stop.unsetAlgn(); + } else { + stop.setAlgn(align.underlying); + } + } + + public Double getPosition() { + if (stop.isSetPos()) { + return Units.toPoints(stop.getPos()); + } else { + return null; + } + } + + public void setPosition(Double position) { + if (position == null) { + stop.unsetPos(); + } else { + stop.setPos(Units.toEMU(position)); + } } } Modified: poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFTextBody.java URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFTextBody.java?rev=1839255&r1=1839254&r2=1839255&view=diff ============================================================================== --- poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFTextBody.java (original) +++ poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFTextBody.java Sun Aug 26 21:18:54 2018 @@ -17,25 +17,350 @@ package org.apache.poi.xddf.usermodel.text; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.function.Function; +import java.util.stream.Collectors; + import org.apache.poi.util.Beta; import org.apache.poi.util.Internal; import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextListStyle; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties; @Beta public class XDDFTextBody { - private CTTextBody body; + private CTTextBody _body; + private TextContainer _parent; - public XDDFTextBody() { - this(CTTextBody.Factory.newInstance()); + public XDDFTextBody(TextContainer parent) { + this(parent, CTTextBody.Factory.newInstance()); + this._body.addNewBodyPr(); } @Internal - public XDDFTextBody(CTTextBody body) { - this.body = body; + public XDDFTextBody(TextContainer parent, CTTextBody body) { + this._parent = parent; + this._body = body; } @Internal public CTTextBody getXmlObject() { - return body; + return _body; + } + + public TextContainer getParentShape() { + return _parent; + } + + public XDDFTextParagraph addNewParagraph() { + return new XDDFTextParagraph(_body.addNewP(), this); + } + + public XDDFTextParagraph insertNewParagraph(int index) { + return new XDDFTextParagraph(_body.insertNewP(index), this); + } + + public void removeParagraph(int index) { + _body.removeP(index); + } + + public XDDFTextParagraph getParagraph(int index) { + return new XDDFTextParagraph(_body.getPArray(index), this); + } + + public List<XDDFTextParagraph> getParagraphs() { + return Collections.unmodifiableList(_body + .getPList() + .stream() + .map(ds -> new XDDFTextParagraph(ds, this)) + .collect(Collectors.toList())); + } + + public XDDFBodyProperties getBodyProperties() { + return new XDDFBodyProperties(_body.getBodyPr()); + } + + public void setBodyProperties(XDDFBodyProperties properties) { + if (properties == null) { + _body.addNewBodyPr(); + } else { + _body.setBodyPr(properties.getXmlObject()); + } + } + + public XDDFParagraphProperties getDefaultProperties() { + if (_body.isSetLstStyle() && _body.getLstStyle().isSetDefPPr()) { + return new XDDFParagraphProperties(_body.getLstStyle().getDefPPr()); + } else { + return null; + } + } + + public void setDefaultProperties(XDDFParagraphProperties properties) { + if (properties == null) { + if (_body.isSetLstStyle()) { + _body.getLstStyle().unsetDefPPr(); + } + } else { + CTTextListStyle style = _body.isSetLstStyle() ? _body.getLstStyle() : _body.addNewLstStyle(); + style.setDefPPr(properties.getXmlObject()); + } + } + + public XDDFParagraphProperties getLevel1Properties() { + if (_body.isSetLstStyle() && _body.getLstStyle().isSetLvl1PPr()) { + return new XDDFParagraphProperties(_body.getLstStyle().getLvl1PPr()); + } else { + return null; + } + } + + public void setLevel1Properties(XDDFParagraphProperties properties) { + if (properties == null) { + if (_body.isSetLstStyle()) { + _body.getLstStyle().unsetLvl1PPr(); + } + } else { + CTTextListStyle style = _body.isSetLstStyle() ? _body.getLstStyle() : _body.addNewLstStyle(); + style.setLvl1PPr(properties.getXmlObject()); + } + } + + public XDDFParagraphProperties getLevel2Properties() { + if (_body.isSetLstStyle() && _body.getLstStyle().isSetLvl2PPr()) { + return new XDDFParagraphProperties(_body.getLstStyle().getLvl2PPr()); + } else { + return null; + } + } + + public void setLevel2Properties(XDDFParagraphProperties properties) { + if (properties == null) { + if (_body.isSetLstStyle()) { + _body.getLstStyle().unsetLvl2PPr(); + } + } else { + CTTextListStyle style = _body.isSetLstStyle() ? _body.getLstStyle() : _body.addNewLstStyle(); + style.setLvl2PPr(properties.getXmlObject()); + } + } + + public XDDFParagraphProperties getLevel3Properties() { + if (_body.isSetLstStyle() && _body.getLstStyle().isSetLvl3PPr()) { + return new XDDFParagraphProperties(_body.getLstStyle().getLvl3PPr()); + } else { + return null; + } + } + + public void setLevel3Properties(XDDFParagraphProperties properties) { + if (properties == null) { + if (_body.isSetLstStyle()) { + _body.getLstStyle().unsetLvl3PPr(); + } + } else { + CTTextListStyle style = _body.isSetLstStyle() ? _body.getLstStyle() : _body.addNewLstStyle(); + style.setLvl3PPr(properties.getXmlObject()); + } + } + + public XDDFParagraphProperties getLevel4Properties() { + if (_body.isSetLstStyle() && _body.getLstStyle().isSetLvl4PPr()) { + return new XDDFParagraphProperties(_body.getLstStyle().getLvl4PPr()); + } else { + return null; + } + } + + public void setLevel4Properties(XDDFParagraphProperties properties) { + if (properties == null) { + if (_body.isSetLstStyle()) { + _body.getLstStyle().unsetLvl4PPr(); + } + } else { + CTTextListStyle style = _body.isSetLstStyle() ? _body.getLstStyle() : _body.addNewLstStyle(); + style.setLvl4PPr(properties.getXmlObject()); + } + } + + public XDDFParagraphProperties getLevel5Properties() { + if (_body.isSetLstStyle() && _body.getLstStyle().isSetLvl5PPr()) { + return new XDDFParagraphProperties(_body.getLstStyle().getLvl5PPr()); + } else { + return null; + } + } + + public void setLevel5Properties(XDDFParagraphProperties properties) { + if (properties == null) { + if (_body.isSetLstStyle()) { + _body.getLstStyle().unsetLvl5PPr(); + } + } else { + CTTextListStyle style = _body.isSetLstStyle() ? _body.getLstStyle() : _body.addNewLstStyle(); + style.setLvl5PPr(properties.getXmlObject()); + } + } + + public XDDFParagraphProperties getLevel6Properties() { + if (_body.isSetLstStyle() && _body.getLstStyle().isSetLvl6PPr()) { + return new XDDFParagraphProperties(_body.getLstStyle().getLvl6PPr()); + } else { + return null; + } + } + + public void setLevel6Properties(XDDFParagraphProperties properties) { + if (properties == null) { + if (_body.isSetLstStyle()) { + _body.getLstStyle().unsetLvl6PPr(); + } + } else { + CTTextListStyle style = _body.isSetLstStyle() ? _body.getLstStyle() : _body.addNewLstStyle(); + style.setLvl6PPr(properties.getXmlObject()); + } + } + + public XDDFParagraphProperties getLevel7Properties() { + if (_body.isSetLstStyle() && _body.getLstStyle().isSetLvl7PPr()) { + return new XDDFParagraphProperties(_body.getLstStyle().getLvl7PPr()); + } else { + return null; + } + } + + public void setLevel7Properties(XDDFParagraphProperties properties) { + if (properties == null) { + if (_body.isSetLstStyle()) { + _body.getLstStyle().unsetLvl7PPr(); + } + } else { + CTTextListStyle style = _body.isSetLstStyle() ? _body.getLstStyle() : _body.addNewLstStyle(); + style.setLvl7PPr(properties.getXmlObject()); + } + } + + public XDDFParagraphProperties getLevel8Properties() { + if (_body.isSetLstStyle() && _body.getLstStyle().isSetLvl8PPr()) { + return new XDDFParagraphProperties(_body.getLstStyle().getLvl8PPr()); + } else { + return null; + } + } + + public void setLevel8Properties(XDDFParagraphProperties properties) { + if (properties == null) { + if (_body.isSetLstStyle()) { + _body.getLstStyle().unsetLvl8PPr(); + } + } else { + CTTextListStyle style = _body.isSetLstStyle() ? _body.getLstStyle() : _body.addNewLstStyle(); + style.setLvl8PPr(properties.getXmlObject()); + } + } + + public XDDFParagraphProperties getLevel9Properties() { + if (_body.isSetLstStyle() && _body.getLstStyle().isSetLvl9PPr()) { + return new XDDFParagraphProperties(_body.getLstStyle().getLvl9PPr()); + } else { + return null; + } + } + + public void setLevel9Properties(XDDFParagraphProperties properties) { + if (properties == null) { + if (_body.isSetLstStyle()) { + _body.getLstStyle().unsetLvl9PPr(); + } + } else { + CTTextListStyle style = _body.isSetLstStyle() ? _body.getLstStyle() : _body.addNewLstStyle(); + style.setLvl9PPr(properties.getXmlObject()); + } + } + + @Internal + protected <R> Optional<R> findDefinedParagraphProperty(Function<CTTextParagraphProperties, Boolean> isSet, + Function<CTTextParagraphProperties, R> getter, int level) { + if (_body.isSetLstStyle() && level >= 0) { + CTTextListStyle list = _body.getLstStyle(); + CTTextParagraphProperties props = level == 0 ? list.getDefPPr() : retrieveProperties(list, level); + if (props != null && isSet.apply(props)) { + return Optional.of(getter.apply(props)); + } else { + return findDefinedParagraphProperty(isSet, getter, level - 1); + } + } else { + return _parent.findDefinedParagraphProperty(isSet, getter); + } + } + + @Internal + protected <R> Optional<R> findDefinedRunProperty(Function<CTTextCharacterProperties, Boolean> isSet, + Function<CTTextCharacterProperties, R> getter, int level) { + if (_body.isSetLstStyle() && level >= 0) { + CTTextListStyle list = _body.getLstStyle(); + CTTextParagraphProperties props = level == 0 ? list.getDefPPr() : retrieveProperties(list, level); + if (props != null && props.isSetDefRPr() && isSet.apply(props.getDefRPr())) { + return Optional.of(getter.apply(props.getDefRPr())); + } else { + return findDefinedRunProperty(isSet, getter, level - 1); + } + } else { + return _parent.findDefinedRunProperty(isSet, getter); + } + } + + private CTTextParagraphProperties retrieveProperties(CTTextListStyle list, int level) { + switch(level) { + case 1: if (list.isSetLvl1PPr()) { + return list.getLvl1PPr(); + } else { + return null; + } + case 2: if (list.isSetLvl2PPr()) { + return list.getLvl2PPr(); + } else { + return null; + } + case 3: if (list.isSetLvl3PPr()) { + return list.getLvl3PPr(); + } else { + return null; + } + case 4: if (list.isSetLvl4PPr()) { + return list.getLvl4PPr(); + } else { + return null; + } + case 5: if (list.isSetLvl5PPr()) { + return list.getLvl5PPr(); + } else { + return null; + } + case 6: if (list.isSetLvl6PPr()) { + return list.getLvl6PPr(); + } else { + return null; + } + case 7: if (list.isSetLvl7PPr()) { + return list.getLvl7PPr(); + } else { + return null; + } + case 8: if (list.isSetLvl8PPr()) { + return list.getLvl8PPr(); + } else { + return null; + } + case 9: if (list.isSetLvl9PPr()) { + return list.getLvl9PPr(); + } else { + return null; + } + default: return null; + } } } Added: poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFTextParagraph.java URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFTextParagraph.java?rev=1839255&view=auto ============================================================================== --- poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFTextParagraph.java (added) +++ poi/trunk/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFTextParagraph.java Sun Aug 26 21:18:54 2018 @@ -0,0 +1,723 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.xddf.usermodel.text; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Optional; +import java.util.function.Function; + +import org.apache.poi.util.Beta; +import org.apache.poi.util.Internal; +import org.apache.poi.util.LocaleUtil; +import org.apache.poi.util.Units; +import org.apache.poi.xddf.usermodel.XDDFColor; +import org.apache.xmlbeans.QNameSet; +import org.apache.xmlbeans.XmlObject; +import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextField; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextLineBreak; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextSpacing; + +/** + * Represents a paragraph of text within the containing text body. + * The paragraph is the highest level text separation mechanism. + */ +@Beta +public class XDDFTextParagraph { + private XDDFTextBody _parent; + private XDDFParagraphProperties _properties; + private final CTTextParagraph _p; + private final ArrayList<XDDFTextRun> _runs; + + @Internal + protected XDDFTextParagraph(CTTextParagraph paragraph, XDDFTextBody parent) { + this._p = paragraph; + this._parent = parent; + + final int count = paragraph.sizeOfBrArray() + + paragraph.sizeOfFldArray() + + paragraph.sizeOfRArray(); + this._runs = new ArrayList<>(count); + + for (XmlObject xo : _p.selectChildren(QNameSet.ALL)) { + if (xo instanceof CTTextLineBreak) { + _runs.add(new XDDFTextRun((CTTextLineBreak) xo, this)); + } else if (xo instanceof CTTextField) { + _runs.add(new XDDFTextRun((CTTextField) xo, this)); + } else if (xo instanceof CTRegularTextRun) { + _runs.add(new XDDFTextRun((CTRegularTextRun) xo, this)); + } + } + } + + public String getText() { + StringBuilder out = new StringBuilder(); + for (XDDFTextRun r : _runs) { + out.append(r.getText()); + } + return out.toString(); + } + + public XDDFTextBody getParentBody() { + return _parent; + } + + public List<XDDFTextRun> getTextRuns(){ + return _runs; + } + + public Iterator<XDDFTextRun> iterator(){ + return _runs.iterator(); + } + + /** + * Append a line break. + * + * @return text run representing this line break ('\n'). + */ + public XDDFTextRun appendLineBreak(){ + CTTextLineBreak br = _p.addNewBr(); + // by default, line break has the font properties of the last text run + for (int i = _runs.size() - 1; i <= 0; i--){ + CTTextCharacterProperties prevProps = _runs.get(i).getProperties(); + // let's find one that is not undefined + if (prevProps != null) { + br.setRPr((CTTextCharacterProperties) prevProps.copy()); + break; + } + } + XDDFTextRun run = new XDDFTextRun(br, this); + _runs.add(run); + return run; + } + + /** + * Append a new text field. + * + * @return the new text field. + */ + public XDDFTextRun appendField(String id, String type, String text){ + CTTextField f = _p.addNewFld(); + f.setId(id); + f.setType(type); + f.setT(text); + CTTextCharacterProperties rPr = f.addNewRPr(); + rPr.setLang(LocaleUtil.getUserLocale().toLanguageTag()); + XDDFTextRun run = new XDDFTextRun(f, this); + _runs.add(run); + return run; + } + + /** + * Append a new run of text. + * + * @return the new run of text. + */ + public XDDFTextRun appendRegularRun(String text){ + CTRegularTextRun r = _p.addNewR(); + r.setT(text); + CTTextCharacterProperties rPr = r.addNewRPr(); + rPr.setLang(LocaleUtil.getUserLocale().toLanguageTag()); + XDDFTextRun run = new XDDFTextRun(r, this); + _runs.add(run); + return run; + } + + /** + * Returns the alignment that is applied to the paragraph. + * + * If this attribute is omitted, then a value of left is implied. + * @return alignment that is applied to the paragraph + */ + public TextAlignment getTextAlignment() { + return findDefinedParagraphProperty(props -> props.isSetAlgn(), props -> props.getAlgn()) + .map(align -> TextAlignment.valueOf(align)) + .orElse(null); + } + + /** + * Specifies the alignment that is to be applied to the paragraph. + * Possible values for this include left, right, centered, justified and distributed, + * + * @param align text alignment + */ + public void setTextAlignment(TextAlignment align) { + if (align != null || _p.isSetPPr()) { + getOrCreateProperties().setTextAlignment(align); + } + } + + /** + * Returns where vertically on a line of text the actual words are positioned. This deals + * with vertical placement of the characters with respect to the baselines. + * + * If this attribute is omitted, then a value of baseline is implied. + * @return alignment that is applied to the paragraph + */ + public FontAlignment getFontAlignment() { + return findDefinedParagraphProperty(props -> props.isSetFontAlgn(), props -> props.getFontAlgn()) + .map(align -> FontAlignment.valueOf(align)) + .orElse(null); + } + + /** + * Determines where vertically on a line of text the actual words are positioned. This deals + * with vertical placement of the characters with respect to the baselines. For instance + * having text anchored to the top baseline, anchored to the bottom baseline, centered in + * between, etc. + * + * @param align text font alignment + */ + public void setFontAlignment(FontAlignment align) { + if (align != null || _p.isSetPPr()) { + getOrCreateProperties().setFontAlignment(align); + } + } + + /** + * + * @return the indentation, in points, applied to the first line of text in the paragraph. + */ + public Double getIndentation() { + return findDefinedParagraphProperty(props -> props.isSetIndent(), props -> props.getIndent()) + .map(emu -> Units.toPoints(emu)) + .orElse(null); + } + + /** + * Specifies the indentation size that will be applied to the first line of text in the paragraph. + * + * @param points the indentation in points. + * The value <code>null</code> unsets the indentation for this paragraph. + * <dl> + * <dt>Minimum inclusive =</dt><dd>-4032</dd> + * <dt>Maximum inclusive =</dt><dd>4032</dd> + * </dt> + */ + public void setIndentation(Double points) { + if (points != null || _p.isSetPPr()) { + getOrCreateProperties().setIndentation(points);; + } + } + + /** + * + * @return the left margin, in points, of the paragraph. + */ + public Double getMarginLeft() { + return findDefinedParagraphProperty(props -> props.isSetMarL(), props -> props.getMarL()) + .map(emu -> Units.toPoints(emu)) + .orElse(null); + } + + /** + * Specifies the left margin of the paragraph. This is specified in addition to the text body + * inset and applies only to this text paragraph. That is the text body inset and the LeftMargin + * attributes are additive with respect to the text position. + * + * @param points the margin in points. + * The value <code>null</code> unsets the left margin for this paragraph. + * <dl> + * <dt>Minimum inclusive =</dt><dd>0</dd> + * <dt>Maximum inclusive =</dt><dd>4032</dd> + * </dt> + */ + public void setMarginLeft(Double points) { + if (points != null || _p.isSetPPr()) { + getOrCreateProperties().setMarginLeft(points); + } + } + + /** + * + * @return the right margin, in points, of the paragraph. + */ + public Double getMarginRight() { + return findDefinedParagraphProperty(props -> props.isSetMarR(), props -> props.getMarR()) + .map(emu -> Units.toPoints(emu)) + .orElse(null); + } + + /** + * Specifies the right margin of the paragraph. This is specified in addition to the text body + * inset and applies only to this text paragraph. That is the text body inset and the RightMargin + * attributes are additive with respect to the text position. + * + * @param points the margin in points. + * The value <code>null</code> unsets the right margin for this paragraph. + * <dl> + * <dt>Minimum inclusive =</dt><dd>0</dd> + * <dt>Maximum inclusive =</dt><dd>4032</dd> + * </dt> + */ + public void setMarginRight(Double points) { + if (points != null || _p.isSetPPr()) { + getOrCreateProperties().setMarginRight(points); + } + } + + /** + * + * @return the default size for a tab character within this paragraph in points. + */ + public Double getDefaultTabSize() { + return findDefinedParagraphProperty(props -> props.isSetDefTabSz(), props -> props.getDefTabSz()) + .map(emu -> Units.toPoints(emu)) + .orElse(null); + } + + /** + * Specifies the default size for a tab character within this paragraph. + * + * @param points the default tab size in points. + * The value <code>null</code> unsets the default tab size for this paragraph. + */ + public void setDefaultTabSize(Double points) { + if (points != null || _p.isSetPPr()) { + getOrCreateProperties().setDefaultTabSize(points); + } + } + + /** + * Returns the vertical line spacing that is to be used within a paragraph. + * This may be specified in two different ways, percentage spacing or font points spacing: + * <p> + * If line spacing is a percentage of normal line height, result is instance of XDDFSpacingPercent. + * If line spacing is expressed in points, result is instance of XDDFSpacingPoints. + * </p> + * + * @return the vertical line spacing. + */ + public XDDFSpacing getLineSpacing() { + return findDefinedParagraphProperty(props -> props.isSetLnSpc(), props -> props.getLnSpc()) + .map(spacing -> extractSpacing(spacing)) + .orElse(null); + + } + + /** + * This element specifies the vertical line spacing that is to be used within a paragraph. + * This may be specified in two different ways, percentage spacing or font points spacing: + * <p> + * If spacing is instance of XDDFSpacingPercent, then line spacing is a percentage of normal line height. + * If spacing is instance of XDDFSpacingPoints, then line spacing is expressed in points. + * </p> + * Examples: + * <pre><code> + * // spacing will be 120% of the size of the largest text on each line + * paragraph.setLineSpacing(new XDDFSpacingPercent(120)); + * + * // spacing will be 200% of the size of the largest text on each line + * paragraph.setLineSpacing(new XDDFSpacingPercent(200)); + * + * // spacing will be 48 points + * paragraph.setLineSpacing(new XDDFSpacingPoints(48.0)); + * </code></pre> + * + * @param linespacing the vertical line spacing + */ + public void setLineSpacing(XDDFSpacing linespacing) { + if (linespacing != null || _p.isSetPPr()) { + getOrCreateProperties().setLineSpacing(linespacing); + } + } + + /** + * The amount of vertical white space before the paragraph. + * This may be specified in two different ways, percentage spacing or font points spacing: + * <p> + * If spacing is a percentage of normal line height, result is instance of XDDFSpacingPercent. + * If spacing is expressed in points, result is instance of XDDFSpacingPoints. + * </p> + * + * @return the vertical white space before the paragraph. + */ + public XDDFSpacing getSpaceBefore() { + return findDefinedParagraphProperty(props -> props.isSetSpcBef(), props -> props.getSpcBef()) + .map(spacing -> extractSpacing(spacing)) + .orElse(null); + } + + /** + * Set the amount of vertical white space that will be present before the paragraph. + * This may be specified in two different ways, percentage spacing or font points spacing: + * <p> + * If spacing is instance of XDDFSpacingPercent, then spacing is a percentage of normal line height. + * If spacing is instance of XDDFSpacingPoints, then spacing is expressed in points. + * </p> + * Examples: + * <pre><code> + * // The paragraph will be formatted to have a spacing before the paragraph text. + * // The spacing will be 200% of the size of the largest text on each line + * paragraph.setSpaceBefore(new XDDFSpacingPercent(200)); + * + * // The spacing will be a size of 48 points + * paragraph.setSpaceBefore(new XDDFSpacingPoints(48.0)); + * </code></pre> + * + * @param spaceBefore the vertical white space before the paragraph. + */ + public void setSpaceBefore(XDDFSpacing spaceBefore) { + if (spaceBefore != null || _p.isSetPPr()) { + getOrCreateProperties().setSpaceBefore(spaceBefore); + } + } + + /** + * The amount of vertical white space after the paragraph. + * This may be specified in two different ways, percentage spacing or font points spacing: + * <p> + * If spacing is a percentage of normal line height, result is instance of XDDFSpacingPercent. + * If spacing is expressed in points, result is instance of XDDFSpacingPoints. + * </p> + * + * @return the vertical white space after the paragraph. + */ + public XDDFSpacing getSpaceAfter() { + return findDefinedParagraphProperty(props -> props.isSetSpcAft(), props -> props.getSpcAft()) + .map(spacing -> extractSpacing(spacing)) + .orElse(null); + } + + /** + * Set the amount of vertical white space that will be present after the paragraph. + * This may be specified in two different ways, percentage spacing or font points spacing: + * <p> + * If spacing is instance of XDDFSpacingPercent, then spacing is a percentage of normal line height. + * If spacing is instance of XDDFSpacingPoints, then spacing is expressed in points. + * </p> + * Examples: + * <pre><code> + * // The paragraph will be formatted to have a spacing after the paragraph text. + * // The spacing will be 200% of the size of the largest text on each line + * paragraph.setSpaceAfter(new XDDFSpacingPercent(200)); + * + * // The spacing will be a size of 48 points + * paragraph.setSpaceAfter(new XDDFSpacingPoints(48.0)); + * </code></pre> + * + * @param spaceAfter the vertical white space after the paragraph. + */ + public void setSpaceAfter(XDDFSpacing spaceAfter) { + if (spaceAfter != null || _p.isSetPPr()) { + getOrCreateProperties().setSpaceAfter(spaceAfter); + } + } + + /** + * + * @return the color of bullet characters within a given paragraph. + * A <code>null</code> value means to use the text font color. + */ + public XDDFColor getBulletColor(){ + return findDefinedParagraphProperty( + props -> props.isSetBuClr() || props.isSetBuClrTx(), + props -> new XDDFParagraphBulletProperties(props).getBulletColor() + ).orElse(null); + } + + /** + * Set the color to be used on bullet characters within a given paragraph. + * + * @param color the bullet color + */ + public void setBulletColor(XDDFColor color) { + if (color != null || _p.isSetPPr()) { + getOrCreateBulletProperties().setBulletColor(color); + } + } + + /** + * Specifies the color to be used on bullet characters has to follow text color within a given paragraph. + */ + public void setBulletColorFollowText() { + getOrCreateBulletProperties().setBulletColorFollowText(); + } + + /** + * + * @return the font of bullet characters within a given paragraph. + * A <code>null</code> value means to use the text font font. + */ + public XDDFFont getBulletFont(){ + return findDefinedParagraphProperty( + props -> props.isSetBuFont() || props.isSetBuFontTx(), + props -> new XDDFParagraphBulletProperties(props).getBulletFont() + ).orElse(null); + } + + /** + * Set the font to be used on bullet characters within a given paragraph. + * + * @param font the bullet font + */ + public void setBulletFont(XDDFFont font) { + if (font != null || _p.isSetPPr()) { + getOrCreateBulletProperties().setBulletFont(font); + } + } + + /** + * Specifies the font to be used on bullet characters has to follow text font within a given paragraph. + */ + public void setBulletFontFollowText() { + getOrCreateBulletProperties().setBulletFontFollowText(); + } + + /** + * Returns the bullet size that is to be used within a paragraph. + * This may be specified in three different ways, follows text size, percentage size and font points size: + * <p> + * If returned value is instance of XDDFBulletSizeFollowText, then bullet size is text size; + * If returned value is instance of XDDFBulletSizePercent, then bullet size is a percentage of the font size; + * If returned value is instance of XDDFBulletSizePoints, then bullet size is specified in points. + * </p> + * + * @return the bullet size + */ + public XDDFBulletSize getBulletSize(){ + return findDefinedParagraphProperty( + props -> props.isSetBuSzPct() || props.isSetBuSzPts() || props.isSetBuSzTx(), + props -> new XDDFParagraphBulletProperties(props).getBulletSize() + ).orElse(null); + } + + /** + * Sets the bullet size that is to be used within a paragraph. + * This may be specified in three different ways, follows text size, percentage size and font points size: + * <p> + * If given value is instance of XDDFBulletSizeFollowText, then bullet size is text size; + * If given value is instance of XDDFBulletSizePercent, then bullet size is a percentage of the font size; + * If given value is instance of XDDFBulletSizePoints, then bullet size is specified in points. + * </p> + * + * @param size the bullet size specification + */ + public void setBulletSize(XDDFBulletSize size) { + if (size != null || _p.isSetPPr()) { + getOrCreateBulletProperties().setBulletSize(size); + } + } + + public XDDFBulletStyle getBulletStyle(){ + return findDefinedParagraphProperty( + props -> props.isSetBuAutoNum() || props.isSetBuBlip() || props.isSetBuChar() || props.isSetBuNone(), + props -> new XDDFParagraphBulletProperties(props).getBulletStyle() + ).orElse(null); + } + + public void setBulletStyle(XDDFBulletStyle style) { + if (style != null || _p.isSetPPr()) { + getOrCreateBulletProperties().setBulletStyle(style); + } + } + + public boolean hasEastAsianLineBreak() { + return findDefinedParagraphProperty(props -> props.isSetEaLnBrk(), props -> props.getEaLnBrk()) + .orElse(false); + } + + public void setEastAsianLineBreak(Boolean value) { + if (value != null || _p.isSetPPr()) { + getOrCreateProperties().setEastAsianLineBreak(value); + } + } + + public boolean hasLatinLineBreak() { + return findDefinedParagraphProperty(props -> props.isSetLatinLnBrk(), props -> props.getLatinLnBrk()) + .orElse(false); + } + + public void setLatinLineBreak(Boolean value) { + if (value != null || _p.isSetPPr()) { + getOrCreateProperties().setLatinLineBreak(value); + } + } + + public boolean hasHangingPunctuation() { + return findDefinedParagraphProperty(props -> props.isSetHangingPunct(), props -> props.getHangingPunct()) + .orElse(false); + } + + public void setHangingPunctuation(Boolean value) { + if (value != null || _p.isSetPPr()) { + getOrCreateProperties().setHangingPunctuation(value); + } + } + + public boolean isRightToLeft() { + return findDefinedParagraphProperty(props -> props.isSetRtl(), props -> props.getRtl()) + .orElse(false); + } + + public void setRightToLeft(Boolean value) { + if (value != null || _p.isSetPPr()) { + getOrCreateProperties().setRightToLeft(value); + } + } + + public XDDFTabStop addTabStop() { + return getOrCreateProperties().addTabStop(); + } + + public XDDFTabStop insertTabStop(int index) { + return getOrCreateProperties().insertTabStop(index); + } + + public void removeTabStop(int index) { + if (_p.isSetPPr()) { + getProperties().removeTabStop(index); + } + } + + public XDDFTabStop getTabStop(int index) { + if (_p.isSetPPr()) { + return getProperties().getTabStop(index); + } else { + return null; + } + } + + public List<XDDFTabStop> getTabStops() { + if (_p.isSetPPr()) { + return getProperties().getTabStops(); + } else { + return Collections.emptyList(); + } + } + + public int countTabStops() { + if (_p.isSetPPr()) { + return getProperties().countTabStops(); + } else { + return 0; + } + } + + public XDDFParagraphBulletProperties getOrCreateBulletProperties() { + return getOrCreateProperties().getBulletProperties(); + } + + public XDDFParagraphBulletProperties getBulletProperties() { + if (_p.isSetPPr()) { + return getProperties().getBulletProperties(); + } else { + return null; + } + } + + public XDDFRunProperties getDefaultRunProperties() { + if (_p.isSetPPr()) { + return getProperties().getDefaultRunProperties(); + } else { + return null; + } + } + + public void setDefaultRunProperties(XDDFRunProperties properties) { + if (properties != null || _p.isSetPPr()) { + getOrCreateProperties().setDefaultRunProperties(properties); + } + } + + public XDDFRunProperties getAfterLastRunProperties() { + if (_p.isSetEndParaRPr()) { + return new XDDFRunProperties(_p.getEndParaRPr()); + } else { + return null; + } + } + + public void setAfterLastRunProperties(XDDFRunProperties properties) { + if (properties == null) { + _p.unsetEndParaRPr(); + } else { + _p.setEndParaRPr(properties.getXmlObject()); + } + } + + private XDDFSpacing extractSpacing(CTTextSpacing spacing) { + if (spacing.isSetSpcPct()) { + double scale = 1 - _parent.getBodyProperties().getAutoFit().getLineSpaceReduction() / 100_000.0; + return new XDDFSpacingPercent(spacing, spacing.getSpcPct(), scale); + } else if (spacing.isSetSpcPts()) { + return new XDDFSpacingPoints(spacing, spacing.getSpcPts()); + } + return null; + } + + private XDDFParagraphProperties getProperties() { + if (_properties == null) { + _properties = new XDDFParagraphProperties(_p.getPPr()); + } + return _properties; + } + + private XDDFParagraphProperties getOrCreateProperties() { + if (!_p.isSetPPr()) { + _properties = new XDDFParagraphProperties(_p.addNewPPr()); + } + return getProperties(); + } + + protected <R> Optional<R> findDefinedParagraphProperty(Function<CTTextParagraphProperties, Boolean> isSet, + Function<CTTextParagraphProperties, R> getter) { + if (_p.isSetPPr()) { + int level = _p.getPPr().isSetLvl() ? 1 + _p.getPPr().getLvl() : 0; + return findDefinedParagraphProperty(isSet, getter, level); + } else { + return _parent.findDefinedParagraphProperty(isSet, getter, 0); + } + } + + private <R> Optional<R> findDefinedParagraphProperty(Function<CTTextParagraphProperties, Boolean> isSet, + Function<CTTextParagraphProperties, R> getter, int level) { + final CTTextParagraphProperties props = _p.getPPr(); + if (props != null && isSet.apply(props)) { + return Optional.ofNullable(getter.apply(props)); + } else { + return _parent.findDefinedParagraphProperty(isSet, getter, level); + } + } + + protected <R> Optional<R> findDefinedRunProperty(Function<CTTextCharacterProperties, Boolean> isSet, + Function<CTTextCharacterProperties, R> getter) { + if (_p.isSetPPr()) { + int level = _p.getPPr().isSetLvl() ? 1 + _p.getPPr().getLvl() : 0; + return findDefinedRunProperty(isSet, getter, level); + } else { + return _parent.findDefinedRunProperty(isSet, getter, 0); + } + } + + private <R> Optional<R> findDefinedRunProperty(Function<CTTextCharacterProperties, Boolean> isSet, + Function<CTTextCharacterProperties, R> getter, int level) { + final CTTextCharacterProperties props = _p.getPPr().isSetDefRPr() ? _p.getPPr().getDefRPr() : null; + if (props != null && isSet.apply(props)) { + return Optional.ofNullable(getter.apply(props)); + } else { + return _parent.findDefinedRunProperty(isSet, getter, level); + } + } +} --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@poi.apache.org For additional commands, e-mail: commits-h...@poi.apache.org