From f0ed3cbbaba4945e4973a61650f96dc648170bff Mon Sep 17 00:00:00 2001 From: Andreas Beeker Date: Mon, 30 Nov 2015 23:34:30 +0000 Subject: [PATCH] - #47904 - Update text styles in HSLF MasterSlide - common sl unification for TextParagraph.setTextAlign git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1717351 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/hslf/examples/TableDemo.java | 2 +- .../poi/sl/usermodel/TextParagraph.java | 16 ++++- .../poi/xslf/usermodel/XSLFTextParagraph.java | 20 ++---- .../textproperties/TextPropCollection.java | 28 ++++++-- .../poi/hslf/record/TxMasterStyleAtom.java | 65 ++++++++++++------- .../apache/poi/hslf/usermodel/HSLFSheet.java | 11 +++- .../poi/hslf/usermodel/HSLFSlideMaster.java | 51 +++++++++++---- .../poi/hslf/usermodel/HSLFSlideShow.java | 18 +++++ .../poi/hslf/usermodel/HSLFTextParagraph.java | 37 ++++++----- .../poi/hslf/usermodel/HSLFTextRun.java | 18 ++++- .../apache/poi/hslf/usermodel/TestBugs.java | 39 +++++++++-- .../poi/hslf/usermodel/TestNumberedList3.java | 13 +++- 12 files changed, 228 insertions(+), 90 deletions(-) diff --git a/src/examples/src/org/apache/poi/hslf/examples/TableDemo.java b/src/examples/src/org/apache/poi/hslf/examples/TableDemo.java index 817541ee8..e4ad98dc1 100644 --- a/src/examples/src/org/apache/poi/hslf/examples/TableDemo.java +++ b/src/examples/src/org/apache/poi/hslf/examples/TableDemo.java @@ -105,7 +105,7 @@ public final class TableDemo { } else { rt.getTextParagraph().setBullet(true); rt.setFontSize(12d); - rt.getTextParagraph().setAlignment(TextAlign.LEFT); + rt.getTextParagraph().setTextAlign(TextAlign.LEFT); cell.setHorizontalCentered(false); } cell.setVerticalAlignment(VerticalAlignment.MIDDLE); diff --git a/src/java/org/apache/poi/sl/usermodel/TextParagraph.java b/src/java/org/apache/poi/sl/usermodel/TextParagraph.java index a0f67bd61..61c06a9e4 100644 --- a/src/java/org/apache/poi/sl/usermodel/TextParagraph.java +++ b/src/java/org/apache/poi/sl/usermodel/TextParagraph.java @@ -312,11 +312,21 @@ public interface TextParagraph< /** * 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 + * If this attribute is omitted, then null is returned. + * User code can imply the value {@link org.apache.poi.sl.usermodel.TextParagraph.TextAlign#LEFT} then. + * + * @return alignment that is applied to the paragraph */ TextAlign getTextAlign(); - + + /** + * 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.sl.usermodel.TextParagraph.TextAlign}. + * + * @param align text align + */ + void setTextAlign(TextAlign align); /** * Returns the font alignment that is applied to the paragraph. diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java index 31df98787..3172c162c 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java @@ -163,14 +163,7 @@ public class XSLFTextParagraph implements TextParagraph fetcher = new ParagraphPropertyFetcher(getIndentLevel()){ public boolean fetch(CTTextParagraphProperties props){ @@ -186,14 +179,8 @@ public class XSLFTextParagraph implements TextParagraph -1) { diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/TxMasterStyleAtom.java b/src/scratchpad/src/org/apache/poi/hslf/record/TxMasterStyleAtom.java index a93069ff5..2d9541e1b 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/TxMasterStyleAtom.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/TxMasterStyleAtom.java @@ -17,14 +17,17 @@ package org.apache.poi.hslf.record; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; +import org.apache.poi.hslf.exceptions.HSLFException; import org.apache.poi.hslf.model.textproperties.TextPropCollection; import org.apache.poi.hslf.model.textproperties.TextPropCollection.TextPropType; import org.apache.poi.util.LittleEndian; +import org.apache.poi.util.LittleEndianOutputStream; /** * TxMasterStyleAtom atom (4003). @@ -140,7 +143,7 @@ public final class TxMasterStyleAtom extends RecordAtom { paragraphStyles = new ArrayList(levels); charStyles = new ArrayList(levels); - for(short j = 0; j < levels; j++) { + for(short i = 0; i < levels; i++) { TextPropCollection prprops = new TextPropCollection(0, TextPropType.paragraph); // getParagraphProps(type, j) if (type >= TextHeaderAtom.CENTRE_BODY_TYPE) { // Fetch the 2 byte value, that is safe to ignore for some types of text @@ -163,32 +166,44 @@ public final class TxMasterStyleAtom extends RecordAtom { pos += chprops.buildTextPropList( head, _data, pos); charStyles.add(chprops); } - } /** - * Paragraph properties for the specified text type and - * indent level - * Depending on the level and type, it may be our special - * ones, or the standard StyleTextPropAtom ones + * Updates the rawdata from the modified paragraph/character styles + * + * @since 3.14-beta1 */ -// protected TextProp[] getParagraphProps(int type, int level){ -// return StyleTextPropAtom.paragraphTextPropTypes; -// return (level != 0 || type >= MAX_INDENT) -// ? StyleTextPropAtom.paragraphTextPropTypes -// : paragraphSpecialPropTypes; -// } - - /** - * Character properties for the specified text type and - * indent level. - * Depending on the level and type, it may be our special - * ones, or the standard StyleTextPropAtom ones - */ -// protected TextProp[] getCharacterProps(int type, int level){ -// return StyleTextPropAtom.characterTextPropTypes; -// return (level != 0 || type >= MAX_INDENT) -// ? StyleTextPropAtom.characterTextPropTypes -// : characterSpecialPropTypes; -// } + public void updateStyles() { + int type = getTextType(); + + try { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + LittleEndianOutputStream leos = new LittleEndianOutputStream(bos); + int levels = paragraphStyles.size(); + leos.writeShort(levels); + + TextPropCollection prdummy = new TextPropCollection(0, TextPropType.paragraph); + TextPropCollection chdummy = new TextPropCollection(0, TextPropType.character); + + for (int i=0; i= TextHeaderAtom.CENTRE_BODY_TYPE) { + leos.writeShort(prdummy.getIndentLevel()); + } + + // Indent level is not written for master styles + prdummy.setIndentLevel((short)-1); + prdummy.writeOut(bos, true); + chdummy.writeOut(bos, true); + } + + _data = bos.toByteArray(); + leos.close(); + + LittleEndian.putInt(_header, 4, _data.length); + } catch (IOException e) { + throw new HSLFException("error in updating master style properties", e); + } + } } diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSheet.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSheet.java index 35ab5f204..e80070e6c 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSheet.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSheet.java @@ -27,6 +27,7 @@ import org.apache.poi.ddf.EscherContainerRecord; import org.apache.poi.ddf.EscherDgRecord; import org.apache.poi.ddf.EscherDggRecord; import org.apache.poi.ddf.EscherRecord; +import org.apache.poi.hslf.exceptions.HSLFException; import org.apache.poi.hslf.record.CString; import org.apache.poi.hslf.record.ColorSchemeAtom; import org.apache.poi.hslf.record.OEPlaceholderAtom; @@ -40,6 +41,7 @@ import org.apache.poi.sl.draw.Drawable; import org.apache.poi.sl.usermodel.PictureData; import org.apache.poi.sl.usermodel.ShapeType; import org.apache.poi.sl.usermodel.Sheet; +import org.apache.poi.util.Internal; /** * This class defines the common format of "Sheets" in a powerpoint @@ -119,9 +121,14 @@ public abstract class HSLFSheet implements HSLFShapeContainer, Sheet> trs = getTextParagraphs(); if (trs == null) return; diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideMaster.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideMaster.java index 346dab745..1e89b69a9 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideMaster.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideMaster.java @@ -20,9 +20,11 @@ package org.apache.poi.hslf.usermodel; import java.util.ArrayList; import java.util.List; +import org.apache.poi.hslf.exceptions.HSLFException; import org.apache.poi.hslf.model.textproperties.TextProp; import org.apache.poi.hslf.model.textproperties.TextPropCollection; import org.apache.poi.hslf.record.*; +import org.apache.poi.util.Internal; /** * SlideMaster determines the graphics, layout, and formatting for all the slides in a given presentation. @@ -73,7 +75,7 @@ public final class HSLFSlideMaster extends HSLFMasterSheet { /** * Pickup a style attribute from the master. - * This is the "workhorse" which returns the default style attrubutes. + * This is the "workhorse" which returns the default style attributes. */ public TextProp getStyleAttribute(int txtype, int level, String name, boolean isCharacter) { if (_txmaster.length <= txtype) return null; @@ -102,25 +104,50 @@ public final class HSLFSlideMaster extends HSLFMasterSheet { return getStyleAttribute(txtype, level, name, isCharacter); } - + /** * Assign SlideShow for this slide master. - * (Used interanlly) */ - public void setSlideShow(HSLFSlideShow ss) { + @Internal + @Override + protected void setSlideShow(HSLFSlideShow ss) { super.setSlideShow(ss); //after the slide show is assigned collect all available style records - if (_txmaster == null) { - _txmaster = new TxMasterStyleAtom[9]; + assert (_txmaster == null); + _txmaster = new TxMasterStyleAtom[9]; - TxMasterStyleAtom txdoc = getSlideShow().getDocumentRecord().getEnvironment().getTxMasterStyleAtom(); - _txmaster[txdoc.getTextType()] = txdoc; + TxMasterStyleAtom txdoc = getSlideShow().getDocumentRecord().getEnvironment().getTxMasterStyleAtom(); + _txmaster[txdoc.getTextType()] = txdoc; - TxMasterStyleAtom[] txrec = ((MainMaster)getSheetContainer()).getTxMasterStyleAtoms(); - for (int i = 0; i < txrec.length; i++) { - int txType = txrec[i].getTextType(); - if(_txmaster[txType] == null) _txmaster[txType] = txrec[i]; + TxMasterStyleAtom[] txrec = ((MainMaster)getSheetContainer()).getTxMasterStyleAtoms(); + for (int i = 0; i < txrec.length; i++) { + int txType = txrec[i].getTextType(); + if (txType < _txmaster.length && _txmaster[txType] == null) { + _txmaster[txType] = txrec[i]; + } + } + + for (List paras : getTextParagraphs()) { + for (HSLFTextParagraph htp : paras) { + int txType = htp.getRunType(); + if (txType >= _txmaster.length || _txmaster[txType] == null) { + throw new HSLFException("Master styles not initialized"); + } + + int level = htp.getIndentLevel(); + + List charStyles = _txmaster[txType].getCharacterStyles(); + List paragraphStyles = _txmaster[txType].getParagraphStyles(); + if (charStyles == null || paragraphStyles == null || + charStyles.size() <= level || paragraphStyles.size() <= level) { + throw new HSLFException("Master styles not initialized"); + } + + htp.setMasterStyleReference(paragraphStyles.get(level)); + for (HSLFTextRun htr : htp.getTextRuns()) { + htr.setMasterStyleReference(charStyles.get(level)); + } } } } diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java index 0ba0fd87e..33cdbf966 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java @@ -68,6 +68,7 @@ import org.apache.poi.hslf.record.RecordTypes; import org.apache.poi.hslf.record.SlideListWithText; import org.apache.poi.hslf.record.SlideListWithText.SlideAtomsSet; import org.apache.poi.hslf.record.SlidePersistAtom; +import org.apache.poi.hslf.record.TxMasterStyleAtom; import org.apache.poi.hslf.record.UserEditAtom; import org.apache.poi.poifs.filesystem.DirectoryNode; import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; @@ -475,6 +476,23 @@ public final class HSLFSlideShow implements SlideShow paras : sl.getTextParagraphs()) { + for (HSLFTextParagraph p : paras) { + isDirty |= p.isDirty(); + } + } + if (isDirty) { + for (TxMasterStyleAtom sa : sl.getTxMasterStyleAtoms()) { + if (sa != null) { + // not all master style atoms are set - index 3 is typically null + sa.updateStyles(); + } + } + } + } _hslfSlideShow.write(out); } diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java index 4fd78369c..da6e16454 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java @@ -60,6 +60,7 @@ import org.apache.poi.sl.usermodel.AutoNumberingScheme; import org.apache.poi.sl.usermodel.PaintStyle; import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; import org.apache.poi.sl.usermodel.TextParagraph; +import org.apache.poi.util.Internal; import org.apache.poi.util.LocaleUtil; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; @@ -90,7 +91,7 @@ public final class HSLFTextParagraph implements TextParagraph _runs = new ArrayList(); @@ -151,6 +152,18 @@ public final class HSLFTextParagraph implements TextParagraph= ant.length) return null; + if (ant == null || level == -1 || level >= ant.length) return null; return ant[level].getAutoNumberScheme(); } @@ -1224,7 +1233,7 @@ public final class HSLFTextParagraph implements TextParagraph runs = para.getTextRuns(); trun = runs.get(runIdx); - int len = trun.getLength(); + final int len = trun.getLength(); if (ccRun + len <= ccStyle) { ccRun += len; @@ -1239,11 +1248,8 @@ public final class HSLFTextParagraph implements TextParagraph