123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857 |
- /* ====================================================================
- 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.hslf.usermodel;
-
- import static org.apache.poi.hslf.record.RecordTypes.OEPlaceholderAtom;
- import static org.apache.poi.hslf.record.RecordTypes.RoundTripHFPlaceholder12;
-
- import java.awt.font.FontRenderContext;
- import java.awt.geom.Rectangle2D;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.Iterator;
- import java.util.List;
-
- import org.apache.poi.ddf.AbstractEscherOptRecord;
- import org.apache.poi.ddf.EscherContainerRecord;
- import org.apache.poi.ddf.EscherProperties;
- import org.apache.poi.ddf.EscherSimpleProperty;
- import org.apache.poi.ddf.EscherTextboxRecord;
- import org.apache.poi.hslf.exceptions.HSLFException;
- import org.apache.poi.hslf.model.HSLFMetroShape;
- import org.apache.poi.hslf.record.EscherTextboxWrapper;
- import org.apache.poi.hslf.record.InteractiveInfo;
- import org.apache.poi.hslf.record.InteractiveInfoAtom;
- import org.apache.poi.hslf.record.OEPlaceholderAtom;
- import org.apache.poi.hslf.record.PPDrawing;
- import org.apache.poi.hslf.record.RoundTripHFPlaceholder12;
- import org.apache.poi.hslf.record.TextHeaderAtom;
- import org.apache.poi.hslf.record.TxInteractiveInfoAtom;
- import org.apache.poi.sl.draw.DrawFactory;
- import org.apache.poi.sl.draw.DrawTextShape;
- import org.apache.poi.sl.usermodel.Insets2D;
- import org.apache.poi.sl.usermodel.Placeholder;
- import org.apache.poi.sl.usermodel.ShapeContainer;
- import org.apache.poi.sl.usermodel.TextShape;
- import org.apache.poi.sl.usermodel.VerticalAlignment;
- import org.apache.poi.util.POILogger;
- import org.apache.poi.util.Units;
-
- /**
- * A common superclass of all shapes that can hold text.
- */
- public abstract class HSLFTextShape extends HSLFSimpleShape
- implements TextShape<HSLFShape,HSLFTextParagraph> {
-
- /**
- * How to anchor the text
- */
- private enum HSLFTextAnchor {
- TOP (0, VerticalAlignment.TOP, false, false),
- MIDDLE (1, VerticalAlignment.MIDDLE, false, false),
- BOTTOM (2, VerticalAlignment.BOTTOM, false, false),
- TOP_CENTER (3, VerticalAlignment.TOP, true, false),
- MIDDLE_CENTER (4, VerticalAlignment.MIDDLE, true, null),
- BOTTOM_CENTER (5, VerticalAlignment.BOTTOM, true, false),
- TOP_BASELINE (6, VerticalAlignment.TOP, false, true),
- BOTTOM_BASELINE (7, VerticalAlignment.BOTTOM, false, true),
- TOP_CENTER_BASELINE (8, VerticalAlignment.TOP, true, true),
- BOTTOM_CENTER_BASELINE(9, VerticalAlignment.BOTTOM, true, true);
-
- public final int nativeId;
- public final VerticalAlignment vAlign;
- public final boolean centered;
- public final Boolean baseline;
-
- HSLFTextAnchor(int nativeId, VerticalAlignment vAlign, boolean centered, Boolean baseline) {
- this.nativeId = nativeId;
- this.vAlign = vAlign;
- this.centered = centered;
- this.baseline = baseline;
- }
-
- static HSLFTextAnchor fromNativeId(int nativeId) {
- for (HSLFTextAnchor ta : values()) {
- if (ta.nativeId == nativeId) return ta;
- }
- return null;
- }
- }
-
- /**
- * Specifies that a line of text will continue on subsequent lines instead
- * of extending into or beyond a margin.
- * Office Excel 2007, Excel 2010, PowerPoint 97, and PowerPoint 2010 read
- * and use this value properly but do not write it.
- */
- public static final int WrapSquare = 0;
- /**
- * Specifies a wrapping rule that is equivalent to that of WrapSquare
- * Excel 97, Excel 2000, Excel 2002, and Office Excel 2003 use this value.
- * All other product versions listed at the beginning of this appendix ignore this value.
- */
- public static final int WrapByPoints = 1;
- /**
- * Specifies that a line of text will extend into or beyond a margin instead
- * of continuing on subsequent lines.
- * Excel 97, Word 97, Excel 2000, Word 2000, Excel 2002,
- * and Office Excel 2003 do not use this value.
- */
- public static final int WrapNone = 2;
- /**
- * Specifies a wrapping rule that is undefined and MUST be ignored.
- */
- public static final int WrapTopBottom = 3;
- /**
- * Specifies a wrapping rule that is undefined and MUST be ignored.
- */
- public static final int WrapThrough = 4;
-
-
- /**
- * TextRun object which holds actual text and format data
- */
- protected List<HSLFTextParagraph> _paragraphs = new ArrayList<HSLFTextParagraph>();
-
- /**
- * Escher container which holds text attributes such as
- * TextHeaderAtom, TextBytesAtom ot TextCharsAtom, StyleTextPropAtom etc.
- */
- protected EscherTextboxWrapper _txtbox;
-
- /**
- * This setting is used for supporting a deprecated alignment
- *
- * @see <a href=""></a>
- */
- // boolean alignToBaseline = false;
-
- /**
- * Used to calculate text bounds
- */
- protected static final FontRenderContext _frc = new FontRenderContext(null, true, true);
-
- /**
- * Create a TextBox object and initialize it from the supplied Record container.
- *
- * @param escherRecord <code>EscherSpContainer</code> container which holds information about this shape
- * @param parent the parent of the shape
- */
- protected HSLFTextShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape,HSLFTextParagraph> parent){
- super(escherRecord, parent);
- }
-
- /**
- * Create a new TextBox. This constructor is used when a new shape is created.
- *
- * @param parent the parent of this Shape. For example, if this text box is a cell
- * in a table then the parent is Table.
- */
- public HSLFTextShape(ShapeContainer<HSLFShape,HSLFTextParagraph> parent){
- super(null, parent);
- _escherContainer = createSpContainer(parent instanceof HSLFGroupShape);
- }
-
- /**
- * Create a new TextBox. This constructor is used when a new shape is created.
- *
- */
- public HSLFTextShape(){
- this(null);
- }
-
- /**
- * Set default properties for the TextRun.
- * Depending on the text and shape type the defaults are different:
- * TextBox: align=left, valign=top
- * AutoShape: align=center, valign=middle
- *
- */
- protected void setDefaultTextProperties(HSLFTextParagraph _txtrun){
-
- }
-
- /**
- * When a textbox is added to a sheet we need to tell upper-level
- * <code>PPDrawing</code> about it.
- *
- * @param sh the sheet we are adding to
- */
- protected void afterInsert(HSLFSheet sh){
- super.afterInsert(sh);
-
- storeText();
-
- EscherTextboxWrapper thisTxtbox = getEscherTextboxWrapper();
- if(thisTxtbox != null){
- _escherContainer.addChildRecord(thisTxtbox.getEscherRecord());
-
- PPDrawing ppdrawing = sh.getPPDrawing();
- ppdrawing.addTextboxWrapper(thisTxtbox);
- // Ensure the escher layer knows about the added records
- try {
- thisTxtbox.writeOut(null);
- } catch (IOException e){
- throw new HSLFException(e);
- }
- boolean isInitialAnchor = getAnchor().equals(new Rectangle2D.Double());
- boolean isFilledTxt = !"".equals(getText());
- if (isInitialAnchor && isFilledTxt) {
- resizeToFitText();
- }
- }
- for (HSLFTextParagraph htp : _paragraphs) {
- htp.setShapeId(getShapeId());
- }
- sh.onAddTextShape(this);
- }
-
- protected EscherTextboxWrapper getEscherTextboxWrapper(){
- if(_txtbox != null) return _txtbox;
-
- EscherTextboxRecord textRecord = getEscherChild(EscherTextboxRecord.RECORD_ID);
- if (textRecord == null) return null;
-
- HSLFSheet sheet = getSheet();
- if (sheet != null) {
- PPDrawing drawing = sheet.getPPDrawing();
- if (drawing != null) {
- EscherTextboxWrapper wrappers[] = drawing.getTextboxWrappers();
- if (wrappers != null) {
- for (EscherTextboxWrapper w : wrappers) {
- // check for object identity
- if (textRecord == w.getEscherRecord()) {
- _txtbox = w;
- return _txtbox;
- }
- }
- }
- }
- }
-
- _txtbox = new EscherTextboxWrapper(textRecord);
- return _txtbox;
- }
-
- /**
- * Adjust the size of the shape so it encompasses the text inside it.
- *
- * @return a <code>Rectangle2D</code> that is the bounds of this shape.
- */
- public Rectangle2D resizeToFitText(){
- Rectangle2D anchor = getAnchor();
- if(anchor.getWidth() == 0.) {
- logger.log(POILogger.WARN, "Width of shape wasn't set. Defaulting to 200px");
- anchor.setRect(anchor.getX(), anchor.getY(), 200., anchor.getHeight());
- setAnchor(anchor);
- }
- double height = getTextHeight();
- height += 1; // add a pixel to compensate rounding errors
-
- anchor.setRect(anchor.getX(), anchor.getY(), anchor.getWidth(), height);
- setAnchor(anchor);
-
- return anchor;
- }
-
- /**
- * Returns the type of the text, from the TextHeaderAtom.
- * Possible values can be seen from TextHeaderAtom
- * @see org.apache.poi.hslf.record.TextHeaderAtom
- */
- public int getRunType() {
- getEscherTextboxWrapper();
- if (_txtbox == null) return -1;
- List<HSLFTextParagraph> paras = HSLFTextParagraph.findTextParagraphs(_txtbox, getSheet());
- return (paras.isEmpty()) ? -1 : paras.get(0).getRunType();
- }
-
- /**
- * Changes the type of the text. Values should be taken
- * from TextHeaderAtom. No checking is done to ensure you
- * set this to a valid value!
- * @see org.apache.poi.hslf.record.TextHeaderAtom
- */
- public void setRunType(int type) {
- getEscherTextboxWrapper();
- if (_txtbox == null) return;
- List<HSLFTextParagraph> paras = HSLFTextParagraph.findTextParagraphs(_txtbox, getSheet());
- if (!paras.isEmpty()) {
- paras.get(0).setRunType(type);
- }
- }
-
- /**
- * Returns the type of vertical alignment for the text.
- * One of the <code>Anchor*</code> constants defined in this class.
- *
- * @return the type of alignment
- */
- /* package */ HSLFTextAnchor getAlignment(){
- AbstractEscherOptRecord opt = getEscherOptRecord();
- EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.TEXT__ANCHORTEXT);
- HSLFTextAnchor align = HSLFTextAnchor.TOP;
- if (prop == null){
- /**
- * If vertical alignment was not found in the shape properties then try to
- * fetch the master shape and search for the align property there.
- */
- int type = getRunType();
- HSLFSheet sh = getSheet();
- HSLFMasterSheet master = (sh != null) ? sh.getMasterSheet() : null;
- HSLFTextShape masterShape = (master != null) ? master.getPlaceholderByTextType(type) : null;
- if (masterShape != null && type != TextHeaderAtom.OTHER_TYPE) {
- align = masterShape.getAlignment();
- } else {
- //not found in the master sheet. Use the hardcoded defaults.
- switch (type){
- case TextHeaderAtom.TITLE_TYPE:
- case TextHeaderAtom.CENTER_TITLE_TYPE:
- align = HSLFTextAnchor.MIDDLE;
- break;
- default:
- align = HSLFTextAnchor.TOP;
- break;
- }
- }
- } else {
- align = HSLFTextAnchor.fromNativeId(prop.getPropertyValue());
- }
-
- if (align == null) {
- align = HSLFTextAnchor.TOP;
- }
-
- return align;
- }
-
- /**
- * Sets the type of alignment for the text.
- * One of the <code>Anchor*</code> constants defined in this class.
- *
- * @param isCentered horizontal centered?
- * @param vAlign vertical alignment
- * @param baseline aligned to baseline?
- */
- /* package */ void setAlignment(Boolean isCentered, VerticalAlignment vAlign, boolean baseline) {
- for (HSLFTextAnchor hta : HSLFTextAnchor.values()) {
- if (
- (hta.centered == (isCentered != null && isCentered)) &&
- (hta.vAlign == vAlign) &&
- (hta.baseline == null || hta.baseline == baseline)
- ) {
- setEscherProperty(EscherProperties.TEXT__ANCHORTEXT, hta.nativeId);
- break;
- }
- }
- }
-
- /**
- * @return true, if vertical alignment is relative to baseline
- * this is only used for older versions less equals Office 2003
- */
- public boolean isAlignToBaseline() {
- return getAlignment().baseline;
- }
-
- /**
- * Sets the vertical alignment relative to the baseline
- *
- * @param alignToBaseline if true, vertical alignment is relative to baseline
- */
- public void setAlignToBaseline(boolean alignToBaseline) {
- setAlignment(isHorizontalCentered(), getVerticalAlignment(), alignToBaseline);
- }
-
- @Override
- public boolean isHorizontalCentered() {
- return getAlignment().centered;
- }
-
- @Override
- public void setHorizontalCentered(Boolean isCentered) {
- setAlignment(isCentered, getVerticalAlignment(), getAlignment().baseline);
- }
-
- @Override
- public VerticalAlignment getVerticalAlignment() {
- return getAlignment().vAlign;
- }
-
- @Override
- public void setVerticalAlignment(VerticalAlignment vAlign) {
- setAlignment(isHorizontalCentered(), vAlign, getAlignment().baseline);
- }
-
- /**
- * Returns the distance (in points) between the bottom of the text frame
- * and the bottom of the inscribed rectangle of the shape that contains the text.
- * Default value is 1/20 inch.
- *
- * @return the botom margin
- */
- public double getBottomInset(){
- return getInset(EscherProperties.TEXT__TEXTBOTTOM, .05);
- }
-
- /**
- * Sets the botom margin.
- * @see #getBottomInset()
- *
- * @param margin the bottom margin
- */
- public void setBottomInset(double margin){
- setInset(EscherProperties.TEXT__TEXTBOTTOM, margin);
- }
-
- /**
- * Returns the distance (in points) between the left edge of the text frame
- * and the left edge of the inscribed rectangle of the shape that contains
- * the text.
- * Default value is 1/10 inch.
- *
- * @return the left margin
- */
- public double getLeftInset(){
- return getInset(EscherProperties.TEXT__TEXTLEFT, .1);
- }
-
- /**
- * Sets the left margin.
- * @see #getLeftInset()
- *
- * @param margin the left margin
- */
- public void setLeftInset(double margin){
- setInset(EscherProperties.TEXT__TEXTLEFT, margin);
- }
-
- /**
- * Returns the distance (in points) between the right edge of the
- * text frame and the right edge of the inscribed rectangle of the shape
- * that contains the text.
- * Default value is 1/10 inch.
- *
- * @return the right margin
- */
- public double getRightInset(){
- return getInset(EscherProperties.TEXT__TEXTRIGHT, .1);
- }
-
- /**
- * Sets the right margin.
- * @see #getRightInset()
- *
- * @param margin the right margin
- */
- public void setRightInset(double margin){
- setInset(EscherProperties.TEXT__TEXTRIGHT, margin);
- }
-
- /**
- * Returns the distance (in points) between the top of the text frame
- * and the top of the inscribed rectangle of the shape that contains the text.
- * Default value is 1/20 inch.
- *
- * @return the top margin
- */
- public double getTopInset(){
- return getInset(EscherProperties.TEXT__TEXTTOP, .05);
- }
-
- /**
- * Sets the top margin.
- * @see #getTopInset()
- *
- * @param margin the top margin
- */
- public void setTopInset(double margin){
- setInset(EscherProperties.TEXT__TEXTTOP, margin);
- }
-
- /**
- * Returns the distance (in points) between the edge of the text frame
- * and the edge of the inscribed rectangle of the shape that contains the text.
- * Default value is 1/20 inch.
- *
- * @param propId the id of the inset edge
- * @return the inset in points
- */
- private double getInset(short propId, double defaultInch) {
- AbstractEscherOptRecord opt = getEscherOptRecord();
- EscherSimpleProperty prop = getEscherProperty(opt, propId);
- int val = prop == null ? (int)(Units.toEMU(Units.POINT_DPI)*defaultInch) : prop.getPropertyValue();
- return Units.toPoints(val);
- }
-
- /**
- * @param propId the id of the inset edge
- * @param margin the inset in points
- */
- private void setInset(short propId, double margin){
- setEscherProperty(propId, Units.toEMU(margin));
- }
-
- /**
- * Returns the value indicating word wrap.
- *
- * @return the value indicating word wrap.
- * Must be one of the <code>Wrap*</code> constants defined in this class.
- *
- * @see <a href="https://msdn.microsoft.com/en-us/library/dd948168(v=office.12).aspx">MSOWRAPMODE</a>
- */
- public int getWordWrapEx() {
- AbstractEscherOptRecord opt = getEscherOptRecord();
- EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.TEXT__WRAPTEXT);
- return prop == null ? WrapSquare : prop.getPropertyValue();
- }
-
- /**
- * Specifies how the text should be wrapped
- *
- * @param wrap the value indicating how the text should be wrapped.
- * Must be one of the <code>Wrap*</code> constants defined in this class.
- */
- public void setWordWrapEx(int wrap){
- setEscherProperty(EscherProperties.TEXT__WRAPTEXT, wrap);
- }
-
- @Override
- public boolean getWordWrap(){
- int ww = getWordWrapEx();
- return (ww != WrapNone);
- }
-
- @Override
- public void setWordWrap(boolean wrap) {
- setWordWrapEx(wrap ? WrapSquare : WrapNone);
- }
-
- /**
- * @return id for the text.
- */
- public int getTextId(){
- AbstractEscherOptRecord opt = getEscherOptRecord();
- EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.TEXT__TEXTID);
- return prop == null ? 0 : prop.getPropertyValue();
- }
-
- /**
- * Sets text ID
- *
- * @param id of the text
- */
- public void setTextId(int id){
- setEscherProperty(EscherProperties.TEXT__TEXTID, id);
- }
-
- @Override
- public List<HSLFTextParagraph> getTextParagraphs(){
- if (!_paragraphs.isEmpty()) return _paragraphs;
-
- _txtbox = getEscherTextboxWrapper();
- if (_txtbox == null) {
- _paragraphs.addAll(HSLFTextParagraph.createEmptyParagraph());
- _txtbox = _paragraphs.get(0).getTextboxWrapper();
- } else {
- _paragraphs = HSLFTextParagraph.findTextParagraphs(_txtbox, getSheet());
- if (_paragraphs == null) {
- // there are actually TextBoxRecords without extra data - see #54722
- _paragraphs = HSLFTextParagraph.createEmptyParagraph(_txtbox);
- }
-
- if (_paragraphs.isEmpty()) {
- logger.log(POILogger.WARN, "TextRecord didn't contained any text lines");
- }
- }
-
- for (HSLFTextParagraph p : _paragraphs) {
- p.setParentShape(this);
- }
-
- return _paragraphs;
- }
-
- public void setSheet(HSLFSheet sheet) {
- _sheet = sheet;
-
- // Initialize _txtrun object.
- // (We can't do it in the constructor because the sheet
- // is not assigned then, it's only built once we have
- // all the records)
- List<HSLFTextParagraph> ltp = getTextParagraphs();
- HSLFTextParagraph.supplySheet(ltp, sheet);
- }
-
- /**
- * Return {@link OEPlaceholderAtom}, the atom that describes a placeholder.
- *
- * @return {@link OEPlaceholderAtom} or {@code null} if not found
- */
- public OEPlaceholderAtom getPlaceholderAtom(){
- return getClientDataRecord(OEPlaceholderAtom.typeID);
- }
-
- /**
- * Return {@link RoundTripHFPlaceholder12}, the atom that describes a header/footer placeholder.
- * Compare the {@link RoundTripHFPlaceholder12#getPlaceholderId()} with
- * {@link OEPlaceholderAtom#MasterHeader} or {@link OEPlaceholderAtom#MasterFooter}, to find out
- * what kind of placeholder this is.
- *
- * @return {@link RoundTripHFPlaceholder12} or {@code null} if not found
- *
- * @since POI 3.14-Beta2
- */
- public RoundTripHFPlaceholder12 getHFPlaceholderAtom() {
- // special case for files saved in Office 2007
- return getClientDataRecord(RoundTripHFPlaceholder12.typeID);
- }
-
- /**
- *
- * Assigns a hyperlink to this text shape
- *
- * @param linkId id of the hyperlink, @see org.apache.poi.hslf.usermodel.SlideShow#addHyperlink(Hyperlink)
- * @param beginIndex the beginning index, inclusive.
- * @param endIndex the ending index, exclusive.
- * @see org.apache.poi.hslf.usermodel.HSLFSlideShow#addHyperlink(HSLFHyperlink)
- */
- public void setHyperlink(int linkId, int beginIndex, int endIndex){
- //TODO validate beginIndex and endIndex and throw IllegalArgumentException
-
- InteractiveInfo info = new InteractiveInfo();
- InteractiveInfoAtom infoAtom = info.getInteractiveInfoAtom();
- infoAtom.setAction(org.apache.poi.hslf.record.InteractiveInfoAtom.ACTION_HYPERLINK);
- infoAtom.setHyperlinkType(org.apache.poi.hslf.record.InteractiveInfoAtom.LINK_Url);
- infoAtom.setHyperlinkID(linkId);
-
- _txtbox.appendChildRecord(info);
-
- TxInteractiveInfoAtom txiatom = new TxInteractiveInfoAtom();
- txiatom.setStartIndex(beginIndex);
- txiatom.setEndIndex(endIndex);
- _txtbox.appendChildRecord(txiatom);
-
- }
-
- @Override
- public boolean isPlaceholder() {
- OEPlaceholderAtom oep = getPlaceholderAtom();
- if (oep != null) return true;
-
- //special case for files saved in Office 2007
- RoundTripHFPlaceholder12 hldr = getHFPlaceholderAtom();
- if (hldr != null) return true;
-
- return false;
- }
-
-
- @Override
- public Iterator<HSLFTextParagraph> iterator() {
- return _paragraphs.iterator();
- }
-
- @Override
- public Insets2D getInsets() {
- Insets2D insets = new Insets2D(getTopInset(), getLeftInset(), getBottomInset(), getRightInset());
- return insets;
- }
-
- @Override
- public void setInsets(Insets2D insets) {
- setTopInset(insets.top);
- setLeftInset(insets.left);
- setBottomInset(insets.bottom);
- setRightInset(insets.right);
- }
-
- @Override
- public double getTextHeight(){
- DrawFactory drawFact = DrawFactory.getInstance(null);
- DrawTextShape dts = drawFact.getDrawable(this);
- return dts.getTextHeight();
- }
-
- @Override
- public TextDirection getTextDirection() {
- // TODO: determine vertical text setting
- // see 2.3.22.10 Geometry Text Boolean Properties
- return TextDirection.HORIZONTAL;
- }
-
- @Override
- public void setTextDirection(TextDirection orientation) {
- // TODO: determine vertical text setting
- // see 2.3.22.10 Geometry Text Boolean Properties / gtextFVertical [MS-ODRAW]
- }
-
- @Override
- public Double getTextRotation() {
- // see 2.4.6 MSOCDIR
- AbstractEscherOptRecord opt = getEscherOptRecord();
- EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.TEXT__FONTROTATION);
- return (prop == null) ? null : (90. * prop.getPropertyValue());
- }
-
- @Override
- public void setTextRotation(Double rotation) {
- AbstractEscherOptRecord opt = getEscherOptRecord();
- if (rotation == null) {
- opt.removeEscherProperty(EscherProperties.TEXT__FONTROTATION);
- } else {
- int rot = (int)(Math.round(rotation / 90.) % 4L);
- setEscherProperty(EscherProperties.TEXT__FONTROTATION, rot);
- }
- }
-
- /**
- * Returns the raw text content of the shape. This hasn't had any
- * changes applied to it, and so is probably unlikely to print
- * out nicely.
- */
- public String getRawText() {
- return HSLFTextParagraph.getRawText(getTextParagraphs());
- }
-
- /**
- * Returns the text contained in this text frame, which has been made safe
- * for printing and other use.
- *
- * @return the text string for this textbox.
- */
- public String getText() {
- String rawText = getRawText();
- return HSLFTextParagraph.toExternalString(rawText, getRunType());
- }
-
-
- // Update methods follow
-
- /**
- * Adds the supplied text onto the end of the TextParagraphs,
- * creating a new RichTextRun for it to sit in.
- *
- * @param text the text string used by this object.
- */
- public HSLFTextRun appendText(String text, boolean newParagraph) {
- // init paragraphs
- List<HSLFTextParagraph> paras = getTextParagraphs();
- return HSLFTextParagraph.appendText(paras, text, newParagraph);
- }
-
- @Override
- public HSLFTextRun setText(String text) {
- // init paragraphs
- List<HSLFTextParagraph> paras = getTextParagraphs();
- HSLFTextRun htr = HSLFTextParagraph.setText(paras, text);
- setTextId(text.hashCode());
- return htr;
- }
-
- /**
- * Saves the modified paragraphs/textrun to the records.
- * Also updates the styles to the correct text length.
- */
- protected void storeText() {
- List<HSLFTextParagraph> paras = getTextParagraphs();
- HSLFTextParagraph.storeText(paras);
- }
- // Accesser methods follow
-
- /**
- * Returns the array of all hyperlinks in this text run
- *
- * @return the array of all hyperlinks in this text run or <code>null</code>
- * if not found.
- */
- public List<HSLFHyperlink> getHyperlinks() {
- return HSLFHyperlink.find(this);
- }
-
- @Override
- public void setTextPlaceholder(TextPlaceholder placeholder) {
- // TOOD: check for correct placeholder handling - see org.apache.poi.hslf.model.Placeholder
- Placeholder ph = null;
- int runType;
- switch (placeholder) {
- default:
- case BODY:
- runType = TextHeaderAtom.BODY_TYPE;
- ph = Placeholder.BODY;
- break;
- case TITLE:
- runType = TextHeaderAtom.TITLE_TYPE;
- ph = Placeholder.TITLE;
- break;
- case CENTER_BODY:
- runType = TextHeaderAtom.CENTRE_BODY_TYPE;
- ph = Placeholder.BODY;
- break;
- case CENTER_TITLE:
- runType = TextHeaderAtom.CENTER_TITLE_TYPE;
- ph = Placeholder.TITLE;
- break;
- case HALF_BODY:
- runType = TextHeaderAtom.HALF_BODY_TYPE;
- ph = Placeholder.BODY;
- break;
- case QUARTER_BODY:
- runType = TextHeaderAtom.QUARTER_BODY_TYPE;
- ph = Placeholder.BODY;
- break;
- case NOTES:
- runType = TextHeaderAtom.NOTES_TYPE;
- break;
- case OTHER:
- runType = TextHeaderAtom.OTHER_TYPE;
- break;
- }
- setRunType(runType);
- if (ph != null) {
- setPlaceholder(ph);
- }
- }
-
- @Override
- public TextPlaceholder getTextPlaceholder() {
- switch (getRunType()) {
- default:
- case TextHeaderAtom.BODY_TYPE: return TextPlaceholder.BODY;
- case TextHeaderAtom.TITLE_TYPE: return TextPlaceholder.TITLE;
- case TextHeaderAtom.NOTES_TYPE: return TextPlaceholder.NOTES;
- case TextHeaderAtom.OTHER_TYPE: return TextPlaceholder.OTHER;
- case TextHeaderAtom.CENTRE_BODY_TYPE: return TextPlaceholder.CENTER_BODY;
- case TextHeaderAtom.CENTER_TITLE_TYPE: return TextPlaceholder.CENTER_TITLE;
- case TextHeaderAtom.HALF_BODY_TYPE: return TextPlaceholder.HALF_BODY;
- case TextHeaderAtom.QUARTER_BODY_TYPE: return TextPlaceholder.QUARTER_BODY;
- }
- }
-
-
- /**
- * Get alternative representation of text shape stored as metro blob escher property.
- * The returned shape is the first shape in stored group shape of the metro blob
- *
- * @return null, if there's no alternative representation, otherwise the text shape
- */
- public TextShape<?,?> getMetroShape() {
- HSLFMetroShape<TextShape<?,?>> mbs = new HSLFMetroShape<TextShape<?,?>>(this);
- return mbs.getShape();
- }
- }
|