123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871 |
- /* ====================================================================
- 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.xssf.usermodel;
-
-
- import org.apache.poi.util.Internal;
- import org.apache.poi.util.Units;
- import org.apache.poi.xssf.usermodel.TextAlign;
- import org.apache.poi.xssf.model.ParagraphPropertyFetcher;
- import org.apache.xmlbeans.XmlObject;
- import org.openxmlformats.schemas.drawingml.x2006.main.*;
- import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShape;
-
- import java.awt.Color;
- import java.util.ArrayList;
- import java.util.Iterator;
- import java.util.List;
-
- /**
- * Represents a paragraph of text within the containing text body.
- * The paragraph is the highest level text separation mechanism.
- */
- public class XSSFTextParagraph implements Iterable<XSSFTextRun>{
- private final CTTextParagraph _p;
- private final CTShape _shape;
- private final List<XSSFTextRun> _runs;
-
- XSSFTextParagraph(CTTextParagraph p, CTShape ctShape){
- _p = p;
- _shape = ctShape;
- _runs = new ArrayList<XSSFTextRun>();
-
- for(XmlObject ch : _p.selectPath("*")){
- if(ch instanceof CTRegularTextRun){
- CTRegularTextRun r = (CTRegularTextRun)ch;
- _runs.add(new XSSFTextRun(r, this));
- } else if (ch instanceof CTTextLineBreak){
- CTTextLineBreak br = (CTTextLineBreak)ch;
- CTRegularTextRun r = CTRegularTextRun.Factory.newInstance();
- r.setRPr(br.getRPr());
- r.setT("\n");
- _runs.add(new XSSFTextRun(r, this));
- } else if (ch instanceof CTTextField){
- CTTextField f = (CTTextField)ch;
- CTRegularTextRun r = CTRegularTextRun.Factory.newInstance();
- r.setRPr(f.getRPr());
- r.setT(f.getT());
- _runs.add(new XSSFTextRun(r, this));
- }
- }
- }
-
- public String getText(){
- StringBuilder out = new StringBuilder();
- for (XSSFTextRun r : _runs) {
- out.append(r.getText());
- }
- return out.toString();
- }
-
- @Internal
- public CTTextParagraph getXmlObject(){
- return _p;
- }
-
- @Internal
- public CTShape getParentShape(){
- return _shape;
- }
-
- public List<XSSFTextRun> getTextRuns(){
- return _runs;
- }
-
- public Iterator<XSSFTextRun> iterator(){
- return _runs.iterator();
- }
-
- /**
- * Add a new run of text
- *
- * @return a new run of text
- */
- public XSSFTextRun addNewTextRun(){
- CTRegularTextRun r = _p.addNewR();
- CTTextCharacterProperties rPr = r.addNewRPr();
- rPr.setLang("en-US");
- XSSFTextRun run = new XSSFTextRun(r, this);
- _runs.add(run);
- return run;
- }
-
- /**
- * Insert a line break
- *
- * @return text run representing this line break ('\n')
- */
- public XSSFTextRun addLineBreak(){
- CTTextLineBreak br = _p.addNewBr();
- CTTextCharacterProperties brProps = br.addNewRPr();
- if(_runs.size() > 0){
- // by default line break has the font size of the last text run
- CTTextCharacterProperties prevRun = _runs.get(_runs.size() - 1).getRPr();
- brProps.set(prevRun);
- }
- CTRegularTextRun r = CTRegularTextRun.Factory.newInstance();
- r.setRPr(brProps);
- r.setT("\n");
- XSSFTextRun run = new XSSFLineBreak(r, this, brProps);
- _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 TextAlign getTextAlign(){
- ParagraphPropertyFetcher<TextAlign> fetcher = new ParagraphPropertyFetcher<TextAlign>(getLevel()){
- public boolean fetch(CTTextParagraphProperties props){
- if(props.isSetAlgn()){
- TextAlign val = TextAlign.values()[props.getAlgn().intValue() - 1];
- setValue(val);
- return true;
- }
- return false;
- }
- };
- fetchParagraphProperty(fetcher);
- return fetcher.getValue() == null ? TextAlign.LEFT : fetcher.getValue();
- }
-
- /**
- * Specifies the alignment that is to be applied to the paragraph.
- * Possible values for this include left, right, centered, justified and distributed,
- * see {@link org.apache.poi.xssf.usermodel.TextAlign}.
- *
- * @param align text align
- */
- public void setTextAlign(TextAlign align){
- CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
- if(align == null) {
- if(pr.isSetAlgn()) pr.unsetAlgn();
- } else {
- pr.setAlgn(STTextAlignType.Enum.forInt(align.ordinal() + 1));
- }
- }
-
- /**
- * 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 TextFontAlign getTextFontAlign(){
- ParagraphPropertyFetcher<TextFontAlign> fetcher = new ParagraphPropertyFetcher<TextFontAlign>(getLevel()){
- public boolean fetch(CTTextParagraphProperties props){
- if(props.isSetFontAlgn()){
- TextFontAlign val = TextFontAlign.values()[props.getFontAlgn().intValue() - 1];
- setValue(val);
- return true;
- }
- return false;
- }
- };
- fetchParagraphProperty(fetcher);
- return fetcher.getValue() == null ? TextFontAlign.BASELINE : fetcher.getValue();
- }
-
- /**
- * 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 align
- */
- public void setTextFontAlign(TextFontAlign align){
- CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
- if(align == null) {
- if(pr.isSetFontAlgn()) pr.unsetFontAlgn();
- } else {
- pr.setFontAlgn(STTextFontAlignType.Enum.forInt(align.ordinal() + 1));
- }
- }
-
- /**
- * @return the font to be used on bullet characters within a given paragraph
- */
- public String getBulletFont(){
- ParagraphPropertyFetcher<String> fetcher = new ParagraphPropertyFetcher<String>(getLevel()){
- public boolean fetch(CTTextParagraphProperties props){
- if(props.isSetBuFont()){
- setValue(props.getBuFont().getTypeface());
- return true;
- }
- return false;
- }
- };
- fetchParagraphProperty(fetcher);
- return fetcher.getValue();
- }
-
- public void setBulletFont(String typeface){
- CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
- CTTextFont font = pr.isSetBuFont() ? pr.getBuFont() : pr.addNewBuFont();
- font.setTypeface(typeface);
- }
-
- /**
- * @return the character to be used in place of the standard bullet point
- */
- public String getBulletCharacter(){
- ParagraphPropertyFetcher<String> fetcher = new ParagraphPropertyFetcher<String>(getLevel()){
- public boolean fetch(CTTextParagraphProperties props){
- if(props.isSetBuChar()){
- setValue(props.getBuChar().getChar());
- return true;
- }
- return false;
- }
- };
- fetchParagraphProperty(fetcher);
- return fetcher.getValue();
- }
-
- public void setBulletCharacter(String str){
- CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
- CTTextCharBullet c = pr.isSetBuChar() ? pr.getBuChar() : pr.addNewBuChar();
- c.setChar(str);
- }
-
- /**
- *
- * @return the color of bullet characters within a given paragraph.
- * A <code>null</code> value means to use the text font color.
- */
- public Color getBulletFontColor(){
- ParagraphPropertyFetcher<Color> fetcher = new ParagraphPropertyFetcher<Color>(getLevel()){
- public boolean fetch(CTTextParagraphProperties props){
- if(props.isSetBuClr()){
- if(props.getBuClr().isSetSrgbClr()){
- CTSRgbColor clr = props.getBuClr().getSrgbClr();
- byte[] rgb = clr.getVal();
- setValue(new Color(0xFF & rgb[0], 0xFF & rgb[1], 0xFF & rgb[2]));
- return true;
- }
- }
- return false;
- }
- };
- fetchParagraphProperty(fetcher);
- return fetcher.getValue();
- }
-
- /**
- * Set the color to be used on bullet characters within a given paragraph.
- *
- * @param color the bullet color
- */
- public void setBulletFontColor(Color color){
- CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
- CTColor c = pr.isSetBuClr() ? pr.getBuClr() : pr.addNewBuClr();
- CTSRgbColor clr = c.isSetSrgbClr() ? c.getSrgbClr() : c.addNewSrgbClr();
- clr.setVal(new byte[]{(byte) color.getRed(), (byte) color.getGreen(), (byte) color.getBlue()});
- }
-
- /**
- * Returns the bullet size that is to be used within a paragraph.
- * This may be specified in two different ways, percentage spacing and font point spacing:
- * <p>
- * If bulletSize >= 0, then bulletSize is a percentage of the font size.
- * If bulletSize < 0, then it specifies the size in points
- * </p>
- *
- * @return the bullet size
- */
- public double getBulletFontSize(){
- ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){
- public boolean fetch(CTTextParagraphProperties props){
- if(props.isSetBuSzPct()){
- setValue(props.getBuSzPct().getVal() * 0.001);
- return true;
- }
- if(props.isSetBuSzPts()){
- setValue( - props.getBuSzPts().getVal() * 0.01);
- return true;
- }
- return false;
- }
- };
- fetchParagraphProperty(fetcher);
- return fetcher.getValue() == null ? 100 : fetcher.getValue();
- }
-
- /**
- * Sets the bullet size that is to be used within a paragraph.
- * This may be specified in two different ways, percentage spacing and font point spacing:
- * <p>
- * If bulletSize >= 0, then bulletSize is a percentage of the font size.
- * If bulletSize < 0, then it specifies the size in points
- * </p>
- */
- public void setBulletFontSize(double bulletSize){
- CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
-
- if(bulletSize >= 0) {
- // percentage
- CTTextBulletSizePercent pt = pr.isSetBuSzPct() ? pr.getBuSzPct() : pr.addNewBuSzPct();
- pt.setVal((int)(bulletSize*1000));
- // unset points if percentage is now set
- if(pr.isSetBuSzPts()) pr.unsetBuSzPts();
- } else {
- // points
- CTTextBulletSizePoint pt = pr.isSetBuSzPts() ? pr.getBuSzPts() : pr.addNewBuSzPts();
- pt.setVal((int)(-bulletSize*100));
- // unset percentage if points is now set
- if(pr.isSetBuSzPct()) pr.unsetBuSzPct();
- }
- }
-
- /**
- * Specifies the indent size that will be applied to the first line of text in the paragraph.
- *
- * @param value the indent in points, -1 to unset indent and use the default of 0.
- */
- public void setIndent(double value){
- CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
- if(value == -1) {
- if(pr.isSetIndent()) pr.unsetIndent();
- } else {
- pr.setIndent(Units.toEMU(value));
- }
- }
-
- /**
- *
- * @return the indent applied to the first line of text in the paragraph.
- */
- public double getIndent(){
- ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){
- public boolean fetch(CTTextParagraphProperties props){
- if(props.isSetIndent()){
- setValue(Units.toPoints(props.getIndent()));
- return true;
- }
- return false;
- }
- };
- fetchParagraphProperty(fetcher);
-
- return fetcher.getValue() == null ? 0 : fetcher.getValue();
- }
-
-
-
- /**
- * 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 value the left margin of the paragraph, -1 to clear the margin and use the default of 0.
- */
- public void setLeftMargin(double value){
- CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
- if(value == -1) {
- if(pr.isSetMarL()) pr.unsetMarL();
- } else {
- pr.setMarL(Units.toEMU(value));
- }
-
- }
-
- /**
- *
- * @return the left margin of the paragraph
- */
- public double getLeftMargin(){
- ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){
- public boolean fetch(CTTextParagraphProperties props){
- if(props.isSetMarL()){
- double val = Units.toPoints(props.getMarL());
- setValue(val);
- return true;
- }
- return false;
- }
- };
- fetchParagraphProperty(fetcher);
- // if the marL attribute is omitted, then a value of 347663 is implied
- return fetcher.getValue() == null ? 0 : fetcher.getValue();
- }
-
- /**
- * 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 marR
- * attributes are additive with respect to the text position.
- *
- * @param value the right margin of the paragraph, -1 to clear the margin and use the default of 0.
- */
- public void setRightMargin(double value){
- CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
- if(value == -1) {
- if(pr.isSetMarR()) pr.unsetMarR();
- } else {
- pr.setMarR(Units.toEMU(value));
- }
-
- }
-
- /**
- *
- * @return the right margin of the paragraph
- */
- public double getRightMargin(){
- ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){
- public boolean fetch(CTTextParagraphProperties props){
- if(props.isSetMarR()){
- double val = Units.toPoints(props.getMarR());
- setValue(val);
- return true;
- }
- return false;
- }
- };
- fetchParagraphProperty(fetcher);
- // if the marL attribute is omitted, then a value of 347663 is implied
- return fetcher.getValue() == null ? 0 : fetcher.getValue();
- }
-
- /**
- *
- * @return the default size for a tab character within this paragraph in points
- */
- public double getDefaultTabSize(){
- ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){
- public boolean fetch(CTTextParagraphProperties props){
- if(props.isSetDefTabSz()){
- double val = Units.toPoints(props.getDefTabSz());
- setValue(val);
- return true;
- }
- return false;
- }
- };
- fetchParagraphProperty(fetcher);
- return fetcher.getValue() == null ? 0 : fetcher.getValue();
- }
-
- public double getTabStop(final int idx){
- ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){
- public boolean fetch(CTTextParagraphProperties props){
- if(props.isSetTabLst()){
- CTTextTabStopList tabStops = props.getTabLst();
- if(idx < tabStops.sizeOfTabArray() ) {
- CTTextTabStop ts = tabStops.getTabArray(idx);
- double val = Units.toPoints(ts.getPos());
- setValue(val);
- return true;
- }
- }
- return false;
- }
- };
- fetchParagraphProperty(fetcher);
- return fetcher.getValue() == null ? 0. : fetcher.getValue();
- }
- /**
- * Add a single tab stop to be used on a line of text when there are one or more tab characters
- * present within the text.
- *
- * @param value the position of the tab stop relative to the left margin
- */
- public void addTabStop(double value){
- CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
- CTTextTabStopList tabStops = pr.isSetTabLst() ? pr.getTabLst() : pr.addNewTabLst();
- tabStops.addNewTab().setPos(Units.toEMU(value));
- }
-
- /**
- * 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 and font point spacing:
- * <p>
- * If linespacing >= 0, then linespacing is a percentage of normal line height
- * If linespacing < 0, the absolute value of linespacing is the spacing in points
- * </p>
- * Examples:
- * <pre><code>
- * // spacing will be 120% of the size of the largest text on each line
- * paragraph.setLineSpacing(120);
- *
- * // spacing will be 200% of the size of the largest text on each line
- * paragraph.setLineSpacing(200);
- *
- * // spacing will be 48 points
- * paragraph.setLineSpacing(-48.0);
- * </code></pre>
- *
- * @param linespacing the vertical line spacing
- */
- public void setLineSpacing(double linespacing){
- CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
- CTTextSpacing spc = CTTextSpacing.Factory.newInstance();
- if(linespacing >= 0) spc.addNewSpcPct().setVal((int)(linespacing*1000));
- else spc.addNewSpcPts().setVal((int)(-linespacing*100));
- pr.setLnSpc(spc);
- }
-
- /**
- * Returns the vertical line spacing that is to be used within a paragraph.
- * This may be specified in two different ways, percentage spacing and font point spacing:
- * <p>
- * If linespacing >= 0, then linespacing is a percentage of normal line height.
- * If linespacing < 0, the absolute value of linespacing is the spacing in points
- * </p>
- *
- * @return the vertical line spacing.
- */
- public double getLineSpacing(){
- ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){
- public boolean fetch(CTTextParagraphProperties props){
- if(props.isSetLnSpc()){
- CTTextSpacing spc = props.getLnSpc();
-
- if(spc.isSetSpcPct()) setValue( spc.getSpcPct().getVal()*0.001 );
- else if (spc.isSetSpcPts()) setValue( -spc.getSpcPts().getVal()*0.01 );
- return true;
- }
- return false;
- }
- };
- fetchParagraphProperty(fetcher);
-
- double lnSpc = fetcher.getValue() == null ? 100 : fetcher.getValue();
- if(lnSpc > 0) {
- // check if the percentage value is scaled
- CTTextNormalAutofit normAutofit = _shape.getTxBody().getBodyPr().getNormAutofit();
- if(normAutofit != null) {
- double scale = 1 - (double)normAutofit.getLnSpcReduction() / 100000;
- lnSpc *= scale;
- }
- }
-
- return lnSpc;
- }
-
- /**
- * Set the amount of vertical white space that will be present before the paragraph.
- * This space is specified in either percentage or points:
- * <p>
- * If spaceBefore >= 0, then space is a percentage of normal line height.
- * If spaceBefore < 0, the absolute value of linespacing is the spacing 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(200);
- *
- * // The spacing will be a size of 48 points
- * paragraph.setSpaceBefore(-48.0);
- * </code></pre>
- *
- * @param spaceBefore the vertical white space before the paragraph.
- */
- public void setSpaceBefore(double spaceBefore){
- CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
- CTTextSpacing spc = CTTextSpacing.Factory.newInstance();
- if(spaceBefore >= 0) spc.addNewSpcPct().setVal((int)(spaceBefore*1000));
- else spc.addNewSpcPts().setVal((int)(-spaceBefore*100));
- pr.setSpcBef(spc);
- }
-
- /**
- * The amount of vertical white space before the paragraph
- * This may be specified in two different ways, percentage spacing and font point spacing:
- * <p>
- * If spaceBefore >= 0, then space is a percentage of normal line height.
- * If spaceBefore < 0, the absolute value of linespacing is the spacing in points
- * </p>
- *
- * @return the vertical white space before the paragraph
- */
- public double getSpaceBefore(){
- ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){
- public boolean fetch(CTTextParagraphProperties props){
- if(props.isSetSpcBef()){
- CTTextSpacing spc = props.getSpcBef();
-
- if(spc.isSetSpcPct()) setValue( spc.getSpcPct().getVal()*0.001 );
- else if (spc.isSetSpcPts()) setValue( -spc.getSpcPts().getVal()*0.01 );
- return true;
- }
- return false;
- }
- };
- fetchParagraphProperty(fetcher);
-
- double spcBef = fetcher.getValue() == null ? 0 : fetcher.getValue();
- return spcBef;
- }
-
- /**
- * Set the amount of vertical white space that will be present after the paragraph.
- * This space is specified in either percentage or points:
- * <p>
- * If spaceAfter >= 0, then space is a percentage of normal line height.
- * If spaceAfter < 0, the absolute value of linespacing is the spacing 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(200);
- *
- * // The spacing will be a size of 48 points
- * paragraph.setSpaceAfter(-48.0);
- * </code></pre>
- *
- * @param spaceAfter the vertical white space after the paragraph.
- */
- public void setSpaceAfter(double spaceAfter){
- CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
- CTTextSpacing spc = CTTextSpacing.Factory.newInstance();
- if(spaceAfter >= 0) spc.addNewSpcPct().setVal((int)(spaceAfter*1000));
- else spc.addNewSpcPts().setVal((int)(-spaceAfter*100));
- pr.setSpcAft(spc);
- }
-
- /**
- * The amount of vertical white space after the paragraph
- * This may be specified in two different ways, percentage spacing and font point spacing:
- * <p>
- * If spaceBefore >= 0, then space is a percentage of normal line height.
- * If spaceBefore < 0, the absolute value of linespacing is the spacing in points
- * </p>
- *
- * @return the vertical white space after the paragraph
- */
- public double getSpaceAfter(){
- ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){
- public boolean fetch(CTTextParagraphProperties props){
- if(props.isSetSpcAft()){
- CTTextSpacing spc = props.getSpcAft();
-
- if(spc.isSetSpcPct()) setValue( spc.getSpcPct().getVal()*0.001 );
- else if (spc.isSetSpcPts()) setValue( -spc.getSpcPts().getVal()*0.01 );
- return true;
- }
- return false;
- }
- };
- fetchParagraphProperty(fetcher);
- return fetcher.getValue() == null ? 0 : fetcher.getValue();
- }
-
- /**
- * Specifies the particular level text properties that this paragraph will follow.
- * The value for this attribute formats the text according to the corresponding level
- * paragraph properties defined in the list of styles associated with the body of text
- * that this paragraph belongs to (therefore in the parent shape).
- * <p>
- * Note that the closest properties object to the text is used, therefore if there is
- * a conflict between the text paragraph properties and the list style properties for
- * this level then the text paragraph properties will take precedence.
- * </p>
- *
- * @param level the level (0 ... 4)
- */
- public void setLevel(int level){
- CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
-
- pr.setLvl(level);
- }
-
- /**
- * Returns the level of text properties that this paragraph will follow.
- *
- * @return the text level of this paragraph (0-based). Default is 0.
- */
- public int getLevel(){
- CTTextParagraphProperties pr = _p.getPPr();
- if(pr == null) return 0;
-
- return pr.getLvl();
- }
-
-
- /**
- * Returns whether this paragraph has bullets
- */
- public boolean isBullet() {
- ParagraphPropertyFetcher<Boolean> fetcher = new ParagraphPropertyFetcher<Boolean>(getLevel()){
- public boolean fetch(CTTextParagraphProperties props){
- if (props.isSetBuNone()) {
- setValue(false);
- return true;
- }
- if (props.isSetBuFont()) {
- if (props.isSetBuChar() || props.isSetBuAutoNum()) {
- setValue(true);
- return true;
- } else {
- // Excel treats text with buFont but no char/autonum
- // as not bulleted
- // Possibly the font is just used if bullets turned on again?
- }
- }
- return false;
- }
- };
- fetchParagraphProperty(fetcher);
- return fetcher.getValue() == null ? false : fetcher.getValue();
- }
-
- /**
- * Set or unset this paragraph as a bullet point
- *
- * @param flag whether text in this paragraph has bullets
- */
- public void setBullet(boolean flag) {
- if(isBullet() == flag) return;
-
- CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
- if(!flag) {
- pr.addNewBuNone();
-
- if(pr.isSetBuAutoNum()) pr.unsetBuAutoNum();
- if(pr.isSetBuBlip()) pr.unsetBuBlip();
- if(pr.isSetBuChar()) pr.unsetBuChar();
- if(pr.isSetBuClr()) pr.unsetBuClr();
- if(pr.isSetBuClrTx()) pr.unsetBuClrTx();
- if(pr.isSetBuFont()) pr.unsetBuFont();
- if(pr.isSetBuFontTx()) pr.unsetBuFontTx();
- if(pr.isSetBuSzPct()) pr.unsetBuSzPct();
- if(pr.isSetBuSzPts()) pr.unsetBuSzPts();
- if(pr.isSetBuSzTx()) pr.unsetBuSzTx();
- } else {
- if(pr.isSetBuNone()) pr.unsetBuNone();
- if(!pr.isSetBuFont()) pr.addNewBuFont().setTypeface("Arial");
- if(!pr.isSetBuAutoNum()) pr.addNewBuChar().setChar("\u2022");
- }
- }
-
- /**
- * Set this paragraph as an automatic numbered bullet point
- *
- * @param scheme type of auto-numbering
- * @param startAt the number that will start number for a given sequence of automatically
- * numbered bullets (1-based).
- */
- public void setBullet(ListAutoNumber scheme, int startAt) {
- if(startAt < 1) throw new IllegalArgumentException("Start Number must be greater or equal that 1") ;
- CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
- CTTextAutonumberBullet lst = pr.isSetBuAutoNum() ? pr.getBuAutoNum() : pr.addNewBuAutoNum();
- lst.setType(STTextAutonumberScheme.Enum.forInt(scheme.ordinal() + 1));
- lst.setStartAt(startAt);
-
- if(!pr.isSetBuFont()) pr.addNewBuFont().setTypeface("Arial");
- if(pr.isSetBuNone()) pr.unsetBuNone();
- // remove these elements if present as it results in invalid content when opening in Excel.
- if(pr.isSetBuBlip()) pr.unsetBuBlip();
- if(pr.isSetBuChar()) pr.unsetBuChar();
- }
-
- /**
- * Set this paragraph as an automatic numbered bullet point
- *
- * @param scheme type of auto-numbering
- */
- public void setBullet(ListAutoNumber scheme) {
- CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
- CTTextAutonumberBullet lst = pr.isSetBuAutoNum() ? pr.getBuAutoNum() : pr.addNewBuAutoNum();
- lst.setType(STTextAutonumberScheme.Enum.forInt(scheme.ordinal() + 1));
-
- if(!pr.isSetBuFont()) pr.addNewBuFont().setTypeface("Arial");
- if(pr.isSetBuNone()) pr.unsetBuNone();
- // remove these elements if present as it results in invalid content when opening in Excel.
- if(pr.isSetBuBlip()) pr.unsetBuBlip();
- if(pr.isSetBuChar()) pr.unsetBuChar();
- }
-
- /**
- * Returns whether this paragraph has automatic numbered bullets
- */
- public boolean isBulletAutoNumber() {
- ParagraphPropertyFetcher<Boolean> fetcher = new ParagraphPropertyFetcher<Boolean>(getLevel()){
- public boolean fetch(CTTextParagraphProperties props){
- if(props.isSetBuAutoNum()) {
- setValue(true);
- return true;
- }
- return false;
- }
- };
- fetchParagraphProperty(fetcher);
- return fetcher.getValue() == null ? false : fetcher.getValue();
- }
-
- /**
- * Returns the starting number if this paragraph has automatic numbered bullets, otherwise returns 0
- */
- public int getBulletAutoNumberStart() {
- ParagraphPropertyFetcher<Integer> fetcher = new ParagraphPropertyFetcher<Integer>(getLevel()){
- public boolean fetch(CTTextParagraphProperties props){
- if(props.isSetBuAutoNum() && props.getBuAutoNum().isSetStartAt()) {
- setValue(props.getBuAutoNum().getStartAt());
- return true;
- }
- return false;
- }
- };
- fetchParagraphProperty(fetcher);
- return fetcher.getValue() == null ? 0 : fetcher.getValue();
- }
-
- /**
- * Returns the auto number scheme if this paragraph has automatic numbered bullets, otherwise returns ListAutoNumber.ARABIC_PLAIN
- */
- public ListAutoNumber getBulletAutoNumberScheme() {
- ParagraphPropertyFetcher<ListAutoNumber> fetcher = new ParagraphPropertyFetcher<ListAutoNumber>(getLevel()){
- public boolean fetch(CTTextParagraphProperties props){
- if(props.isSetBuAutoNum()) {
- setValue(ListAutoNumber.values()[props.getBuAutoNum().getType().intValue() - 1]);
- return true;
- }
- return false;
- }
- };
- fetchParagraphProperty(fetcher);
-
- // Note: documentation does not define a default, return ListAutoNumber.ARABIC_PLAIN (1,2,3...)
- return fetcher.getValue() == null ? ListAutoNumber.ARABIC_PLAIN : fetcher.getValue();
- }
-
-
- @SuppressWarnings("rawtypes")
- private boolean fetchParagraphProperty(ParagraphPropertyFetcher visitor){
- boolean ok = false;
-
- if(_p.isSetPPr()) ok = visitor.fetch(_p.getPPr());
-
- if(!ok) {
- ok = visitor.fetch(_shape);
- }
-
- return ok;
- }
-
- @Override
- public String toString(){
- return "[" + getClass() + "]" + getText();
- }
- }
|