]> source.dussan.org Git - poi.git/commitdiff
Regression fix for XSLF
authorAndreas Beeker <kiwiwings@apache.org>
Sun, 5 Jun 2016 01:04:58 +0000 (01:04 +0000)
committerAndreas Beeker <kiwiwings@apache.org>
Sun, 5 Jun 2016 01:04:58 +0000 (01:04 +0000)
- master style was always overridden, because of r1745100
- AIOOB in TextDirection mapping

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1746858 13f79535-47bb-0310-9956-ffa450edef68

src/ooxml/java/org/apache/poi/xslf/model/CharacterPropertyFetcher.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFLineBreak.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTable.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextRun.java
test-data/slideshow/table_test2.pptx [new file with mode: 0644]

index c20f94259bcda27a9c37a2c21de2324c964275d9..3358a727749321cf17d842b68299d2f58bf711fa 100644 (file)
@@ -22,17 +22,13 @@ package org.apache.poi.xslf.model;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties;\r
 \r
-/**\r
- *\r
- * @author Yegor Kozlov\r
- */\r
 public abstract class CharacterPropertyFetcher<T> extends ParagraphPropertyFetcher<T> {\r
     public CharacterPropertyFetcher(int level) {\r
         super(level);\r
     }\r
 \r
     public boolean fetch(CTTextParagraphProperties props) {\r
-        if (props.isSetDefRPr()) {\r
+        if (props != null && props.isSetDefRPr()) {\r
             return fetch(props.getDefRPr());\r
         }\r
 \r
index 3f5d50ab83952f10723cd470dcd85727d6cbbd8b..bdbc461f4b8db057b2e035109b91965fdce99fe2 100644 (file)
@@ -22,9 +22,6 @@ package org.apache.poi.xslf.usermodel;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;\r
 \r
-/**\r
- * @author Yegor Kozlov\r
- */\r
 class XSLFLineBreak extends XSLFTextRun {\r
     private final CTTextCharacterProperties _brProps;\r
 \r
@@ -34,7 +31,7 @@ class XSLFLineBreak extends XSLFTextRun {
     }\r
 \r
     @Override\r
-    protected CTTextCharacterProperties getRPr(){\r
+    protected CTTextCharacterProperties getRPr(boolean create){\r
         return _brProps;\r
     }\r
 \r
index b2a8b3314b823228cf5b37c8e21b56eb8e30029b..e276a8a52cd696164f01c6f085cacb316a6b2694 100644 (file)
@@ -151,7 +151,7 @@ public class XSLFTextParagraph implements TextParagraph<XSLFShape,XSLFTextParagr
         CTTextCharacterProperties brProps = br.addNewRPr();\r
         if(_runs.size() > 0){\r
             // by default line break has the font size of the last text run\r
-            CTTextCharacterProperties prevRun = _runs.get(_runs.size() - 1).getRPr();\r
+            CTTextCharacterProperties prevRun = _runs.get(_runs.size() - 1).getRPr(true);\r
             brProps.set(prevRun);\r
         }\r
         CTRegularTextRun r = CTRegularTextRun.Factory.newInstance();\r
@@ -1043,7 +1043,15 @@ public class XSLFTextParagraph implements TextParagraph<XSLFShape,XSLFTextParagr
         }\r
         if (!_runs.isEmpty()) {\r
             int size = _runs.size();\r
-            thisP.setEndParaRPr(_runs.get(size-1).getRPr());\r
+            XSLFTextRun lastRun = _runs.get(size-1);\r
+            CTTextCharacterProperties cpOther = lastRun.getRPr(false);\r
+            if (cpOther != null) {\r
+                if (thisP.isSetEndParaRPr()) {\r
+                    thisP.unsetEndParaRPr();\r
+                }\r
+                CTTextCharacterProperties cp = thisP.addNewEndParaRPr();\r
+                cp.set(cpOther);\r
+            }\r
             for (int i=size; i>0; i--) {\r
                 thisP.removeR(i-1);\r
             }\r
index c374c4016bebf3b1704d720e30b57853b4b9189f..3c4f5936e3d3b5f6dc72187710ee67de851776e4 100644 (file)
@@ -96,7 +96,7 @@ public class XSLFTextRun implements TextRun {
         SolidPaint sp = (SolidPaint)color;\r
         Color c = DrawPaint.applyColorTransform(sp.getSolidColor());\r
         \r
-        CTTextCharacterProperties rPr = getRPr();\r
+        CTTextCharacterProperties rPr = getRPr(true);\r
         CTSolidColorFillProperties fill = rPr.isSetSolidFill() ? rPr.getSolidFill() : rPr.addNewSolidFill();\r
         \r
         XSLFColor col = new XSLFColor(fill, getParentParagraph().getParentShape().getSheet().getTheme(), fill.getSchemeClr());\r
@@ -107,17 +107,19 @@ public class XSLFTextRun implements TextRun {
     public PaintStyle getFontColor(){\r
         CharacterPropertyFetcher<PaintStyle> fetcher = new CharacterPropertyFetcher<PaintStyle>(_p.getIndentLevel()){\r
             public boolean fetch(CTTextCharacterProperties props){\r
-                XSLFShape shape = _p.getParentShape();\r
-                CTShapeStyle style = shape.getSpStyle();\r
-                CTSchemeColor phClr = null;\r
-                if (style != null && style.getFontRef() != null) {\r
-                    phClr = style.getFontRef().getSchemeClr();\r
-                }\r
-\r
-                PaintStyle ps = shape.getPaint(props, phClr);\r
-                if (ps != null)  {\r
-                    setValue(ps);\r
-                    return true;\r
+                if (props != null) {\r
+                    XSLFShape shape = _p.getParentShape();\r
+                    CTShapeStyle style = shape.getSpStyle();\r
+                    CTSchemeColor phClr = null;\r
+                    if (style != null && style.getFontRef() != null) {\r
+                        phClr = style.getFontRef().getSchemeClr();\r
+                    }\r
+    \r
+                    PaintStyle ps = shape.getPaint(props, phClr);\r
+                    if (ps != null)  {\r
+                        setValue(ps);\r
+                        return true;\r
+                    }\r
                 }\r
                 \r
                 return false;\r
@@ -129,7 +131,7 @@ public class XSLFTextRun implements TextRun {
 \r
     @Override\r
     public void setFontSize(Double fontSize){\r
-        CTTextCharacterProperties rPr = getRPr();\r
+        CTTextCharacterProperties rPr = getRPr(true);\r
         if(fontSize == null) {\r
             if (rPr.isSetSz()) rPr.unsetSz();\r
         } else {\r
@@ -149,7 +151,7 @@ public class XSLFTextRun implements TextRun {
 \r
         CharacterPropertyFetcher<Double> fetcher = new CharacterPropertyFetcher<Double>(_p.getIndentLevel()){\r
             public boolean fetch(CTTextCharacterProperties props){\r
-                if(props.isSetSz()){\r
+                if (props != null && props.isSetSz()) {\r
                     setValue(props.getSz()*0.01);\r
                     return true;\r
                 }\r
@@ -169,7 +171,7 @@ public class XSLFTextRun implements TextRun {
 \r
         CharacterPropertyFetcher<Double> fetcher = new CharacterPropertyFetcher<Double>(_p.getIndentLevel()){\r
             public boolean fetch(CTTextCharacterProperties props){\r
-                if(props.isSetSpc()){\r
+                if (props != null && props.isSetSpc()) {\r
                     setValue(props.getSpc()*0.01);\r
                     return true;\r
                 }\r
@@ -190,7 +192,7 @@ public class XSLFTextRun implements TextRun {
      * @param spc  character spacing in points.\r
      */\r
     public void setCharacterSpacing(double spc){\r
-        CTTextCharacterProperties rPr = getRPr();\r
+        CTTextCharacterProperties rPr = getRPr(true);\r
         if(spc == 0.0) {\r
             if(rPr.isSetSpc()) rPr.unsetSpc();\r
         } else {\r
@@ -204,7 +206,7 @@ public class XSLFTextRun implements TextRun {
     }\r
 \r
     public void setFontFamily(String typeface, byte charset, byte pictAndFamily, boolean isSymbol){\r
-        CTTextCharacterProperties rPr = getRPr();\r
+        CTTextCharacterProperties rPr = getRPr(true);\r
 \r
         if(typeface == null){\r
             if(rPr.isSetLatin()) rPr.unsetLatin();\r
@@ -229,16 +231,18 @@ public class XSLFTextRun implements TextRun {
 \r
         CharacterPropertyFetcher<String> visitor = new CharacterPropertyFetcher<String>(_p.getIndentLevel()){\r
             public boolean fetch(CTTextCharacterProperties props){\r
-                CTTextFont font = props.getLatin();\r
-                if(font != null){\r
-                    String typeface = font.getTypeface();\r
-                    if("+mj-lt".equals(typeface)) {\r
-                        typeface = theme.getMajorFont();\r
-                    } else if ("+mn-lt".equals(typeface)){\r
-                        typeface = theme.getMinorFont();\r
+                if (props != null) {\r
+                    CTTextFont font = props.getLatin();\r
+                    if (font != null) {\r
+                        String typeface = font.getTypeface();\r
+                        if("+mj-lt".equals(typeface)) {\r
+                            typeface = theme.getMajorFont();\r
+                        } else if ("+mn-lt".equals(typeface)){\r
+                            typeface = theme.getMinorFont();\r
+                        }\r
+                        setValue(typeface);\r
+                        return true;\r
                     }\r
-                    setValue(typeface);\r
-                    return true;\r
                 }\r
                 return false;\r
             }\r
@@ -253,10 +257,12 @@ public class XSLFTextRun implements TextRun {
 \r
         CharacterPropertyFetcher<Byte> visitor = new CharacterPropertyFetcher<Byte>(_p.getIndentLevel()){\r
             public boolean fetch(CTTextCharacterProperties props){\r
-                CTTextFont font = props.getLatin();\r
-                if(font != null){\r
-                    setValue(font.getPitchFamily());\r
-                    return true;\r
+                if (props != null) {\r
+                    CTTextFont font = props.getLatin();\r
+                    if (font != null) {\r
+                        setValue(font.getPitchFamily());\r
+                        return true;\r
+                    }\r
                 }\r
                 return false;\r
             }\r
@@ -268,14 +274,14 @@ public class XSLFTextRun implements TextRun {
 \r
     @Override\r
     public void setStrikethrough(boolean strike) {\r
-        getRPr().setStrike(strike ? STTextStrikeType.SNG_STRIKE : STTextStrikeType.NO_STRIKE);\r
+        getRPr(true).setStrike(strike ? STTextStrikeType.SNG_STRIKE : STTextStrikeType.NO_STRIKE);\r
     }\r
 \r
     @Override\r
     public boolean isStrikethrough() {\r
         CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){\r
             public boolean fetch(CTTextCharacterProperties props){\r
-                if(props.isSetStrike()){\r
+                if(props != null && props.isSetStrike()) {\r
                     setValue(props.getStrike() != STTextStrikeType.NO_STRIKE);\r
                     return true;\r
                 }\r
@@ -290,7 +296,7 @@ public class XSLFTextRun implements TextRun {
     public boolean isSuperscript() {\r
         CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){\r
             public boolean fetch(CTTextCharacterProperties props){\r
-                if(props.isSetBaseline()){\r
+                if (props != null && props.isSetBaseline()) {\r
                     setValue(props.getBaseline() > 0);\r
                     return true;\r
                 }\r
@@ -311,7 +317,7 @@ public class XSLFTextRun implements TextRun {
      * @param baselineOffset\r
      */\r
     public void setBaselineOffset(double baselineOffset){\r
-       getRPr().setBaseline((int) baselineOffset * 1000);\r
+       getRPr(true).setBaseline((int) baselineOffset * 1000);\r
     }\r
 \r
     /**\r
@@ -338,7 +344,7 @@ public class XSLFTextRun implements TextRun {
     public boolean isSubscript() {\r
         CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){\r
             public boolean fetch(CTTextCharacterProperties props){\r
-                if(props.isSetBaseline()){\r
+                if (props != null && props.isSetBaseline()) {\r
                     setValue(props.getBaseline() < 0);\r
                     return true;\r
                 }\r
@@ -355,7 +361,7 @@ public class XSLFTextRun implements TextRun {
     public TextCap getTextCap() {\r
         CharacterPropertyFetcher<TextCap> fetcher = new CharacterPropertyFetcher<TextCap>(_p.getIndentLevel()){\r
             public boolean fetch(CTTextCharacterProperties props){\r
-                if(props.isSetCap()){\r
+                if (props != null && props.isSetCap()) {\r
                     int idx = props.getCap().intValue() - 1;\r
                     setValue(TextCap.values()[idx]);\r
                     return true;\r
@@ -369,14 +375,14 @@ public class XSLFTextRun implements TextRun {
 \r
     @Override\r
     public void setBold(boolean bold){\r
-        getRPr().setB(bold);\r
+        getRPr(true).setB(bold);\r
     }\r
 \r
     @Override\r
     public boolean isBold(){\r
         CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){\r
             public boolean fetch(CTTextCharacterProperties props){\r
-                if(props.isSetB()){\r
+                if (props != null && props.isSetB()) {\r
                     setValue(props.getB());\r
                     return true;\r
                 }\r
@@ -389,14 +395,14 @@ public class XSLFTextRun implements TextRun {
 \r
     @Override\r
     public void setItalic(boolean italic){\r
-        getRPr().setI(italic);\r
+        getRPr(true).setI(italic);\r
     }\r
 \r
     @Override\r
     public boolean isItalic(){\r
         CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){\r
             public boolean fetch(CTTextCharacterProperties props){\r
-                if(props.isSetI()){\r
+                if (props != null && props.isSetI()) {\r
                     setValue(props.getI());\r
                     return true;\r
                 }\r
@@ -409,14 +415,14 @@ public class XSLFTextRun implements TextRun {
 \r
     @Override\r
     public void setUnderlined(boolean underline) {\r
-        getRPr().setU(underline ? STTextUnderlineType.SNG : STTextUnderlineType.NONE);\r
+        getRPr(true).setU(underline ? STTextUnderlineType.SNG : STTextUnderlineType.NONE);\r
     }\r
 \r
     @Override\r
     public boolean isUnderlined(){\r
         CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){\r
             public boolean fetch(CTTextCharacterProperties props){\r
-                if(props.isSetU()){\r
+                if (props != null && props.isSetU()) {\r
                     setValue(props.getU() != STTextUnderlineType.NONE);\r
                     return true;\r
                 }\r
@@ -427,8 +433,20 @@ public class XSLFTextRun implements TextRun {
         return fetcher.getValue() == null ? false : fetcher.getValue();\r
     }\r
 \r
-    protected CTTextCharacterProperties getRPr(){\r
-        return _r.isSetRPr() ? _r.getRPr() : _r.addNewRPr();\r
+    /**\r
+     * Return the character properties\r
+     *\r
+     * @param create if true, create an empty character properties object if it doesn't exist\r
+     * @return the character properties or null if create was false and the properties haven't exist\r
+     */\r
+    protected CTTextCharacterProperties getRPr(boolean create) {\r
+        if (_r.isSetRPr()) {\r
+            return _r.getRPr();\r
+        } else if (create) {\r
+            return _r.addNewRPr();\r
+        } else {\r
+            return null;\r
+        }\r
     }\r
 \r
     @Override\r
@@ -463,7 +481,7 @@ public class XSLFTextRun implements TextRun {
         XSLFSheet sheet = shape.getSheet();\r
         boolean ok = false;\r
 \r
-        if (_r.isSetRPr()) ok = fetcher.fetch(getRPr());\r
+        if (_r.isSetRPr()) ok = fetcher.fetch(getRPr(false));\r
         if (ok) return true;\r
         \r
         ok = shape.fetchShapeProperty(fetcher);\r
index a4400d21ba6ac58254fb4f6e324ff21ed97f63bc..91b0869b89cd02d3a115eccc1a443481f07b8423 100644 (file)
@@ -112,8 +112,8 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
         if (text == null) return null;
 
         // copy properties from last paragraph / textrun or paragraph end marker
-        CTTextParagraphProperties pPr = null;
-        CTTextCharacterProperties rPr = null;
+        CTTextParagraphProperties otherPPr = null;
+        CTTextCharacterProperties otherRPr = null;
 
         boolean firstPara;
         XSLFTextParagraph para;
@@ -124,25 +124,33 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
             firstPara = !newParagraph;
             para = _paragraphs.get(_paragraphs.size()-1);
             CTTextParagraph ctp = para.getXmlObject();
-            pPr = ctp.getPPr();
+            otherPPr = ctp.getPPr();
             List<XSLFTextRun> runs = para.getTextRuns();
             if (!runs.isEmpty()) {
                 XSLFTextRun r0 = runs.get(runs.size()-1);
-                rPr = r0.getXmlObject().getRPr();
-            } else if (ctp.isSetEndParaRPr()) {
-                rPr = ctp.getEndParaRPr();
+                otherRPr = r0.getRPr(false);
+                if (otherRPr == null) {
+                    otherRPr = ctp.getEndParaRPr();
+                }
             }
+            // don't copy endParaRPr to the run in case there aren't any other runs
+            // this is the case when setText() was called initially
+            // otherwise the master style will be overridden/ignored
         }
 
         XSLFTextRun run = null;
         for (String lineTxt : text.split("\\r\\n?|\\n")) {
             if (!firstPara) {
-                if (para != null && para.getXmlObject().isSetEndParaRPr()) {
-                    para.getXmlObject().unsetEndParaRPr();
+                if (para != null) {
+                    CTTextParagraph ctp = para.getXmlObject();
+                    CTTextCharacterProperties unexpectedRPr = ctp.getEndParaRPr();
+                    if (unexpectedRPr != null && unexpectedRPr != otherRPr) {
+                        ctp.unsetEndParaRPr();
+                    }
                 }
                 para = addNewTextParagraph();
-                if (pPr != null) {
-                    para.getXmlObject().setPPr(pPr);
+                if (otherPPr != null) {
+                    para.getXmlObject().setPPr(otherPPr);
                 }
             }
             boolean firstRun = true;
@@ -152,8 +160,8 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
                 }
                 run = para.addNewTextRun();
                 run.setText(runText);
-                if (rPr != null) {
-                    run.getXmlObject().setRPr(rPr);
+                if (otherRPr != null) {
+                    run.getRPr(true).set(otherRPr);
                 }
                 firstRun = false;
             }
@@ -261,8 +269,21 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
         CTTextBodyProperties bodyPr = getTextBodyPr();
         if (bodyPr != null) {
             STTextVerticalType.Enum val = bodyPr.getVert();
-            if(val != null){
-                return TextDirection.values()[val.intValue() - 1];
+            if(val != null) {
+                switch (val.intValue()) {
+                    default:
+                    case STTextVerticalType.INT_HORZ:
+                        return TextDirection.HORIZONTAL;
+                    case STTextVerticalType.INT_EA_VERT:
+                    case STTextVerticalType.INT_MONGOLIAN_VERT:
+                    case STTextVerticalType.INT_VERT:
+                        return TextDirection.VERTICAL;
+                    case STTextVerticalType.INT_VERT_270:
+                        return TextDirection.VERTICAL_270;
+                    case STTextVerticalType.INT_WORD_ART_VERT_RTL:
+                    case STTextVerticalType.INT_WORD_ART_VERT:
+                        return TextDirection.STACKED;
+                }
             }
         }
         return TextDirection.HORIZONTAL;
index a58fb603a4db666656d897af29d3238ca91fca0a..9b6dd3d597aeb5a042226cdc15fd6425383809a5 100644 (file)
@@ -34,9 +34,6 @@ import org.junit.Test;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTableCell;\r
 import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame;\r
 \r
-/**\r
- * @author Yegor Kozlov\r
- */\r
 public class TestXSLFTable {\r
     @Test\r
     public void testRead() throws IOException {\r
@@ -82,8 +79,8 @@ public class TestXSLFTable {
 \r
     @Test\r
     public void testCreate() throws IOException {\r
-        XMLSlideShow ppt = new XMLSlideShow();\r
-        XSLFSlide slide = ppt.createSlide();\r
+        XMLSlideShow ppt1 = new XMLSlideShow();\r
+        XSLFSlide slide = ppt1.createSlide();\r
 \r
         XSLFTable tbl = slide.createTable();\r
         assertNotNull(tbl.getCTTable());\r
@@ -145,7 +142,17 @@ public class TestXSLFTable {
         cell1.setVerticalAlignment(null);\r
         assertEquals(VerticalAlignment.TOP, cell1.getVerticalAlignment());\r
         \r
-        ppt.close();\r
+        XMLSlideShow ppt2 = XSLFTestDataSamples.writeOutAndReadBack(ppt1);\r
+        ppt1.close();\r
+\r
+        slide = ppt2.getSlides().get(0);\r
+        tbl = (XSLFTable)slide.getShapes().get(0);\r
+        assertEquals(2, tbl.getNumberOfColumns());\r
+        assertEquals(1, tbl.getNumberOfRows());\r
+        assertEquals("POI", tbl.getCell(0, 0).getText());\r
+        assertEquals("Apache", tbl.getCell(0, 1).getText());\r
+        \r
+        ppt2.close();\r
     }\r
     \r
     @Test\r
index a3d2c50e889704cd6198e1a2c1ef4e59bb2af5c6..5b2fa7b2acf8e53e1a2da6e9500a1c7ff65934b5 100644 (file)
@@ -40,7 +40,7 @@ public class TestXSLFTextRun {
         XSLFTextShape sh = slide.createAutoShape();\r
 \r
         XSLFTextRun r = sh.addNewTextParagraph().addNewTextRun();\r
-        assertEquals("en-US", r.getRPr().getLang());\r
+        assertEquals("en-US", r.getRPr(true).getLang());\r
 \r
         assertEquals(0., r.getCharacterSpacing(), 0);\r
         r.setCharacterSpacing(3);\r
@@ -49,7 +49,7 @@ public class TestXSLFTextRun {
         assertEquals(-3., r.getCharacterSpacing(), 0);\r
         r.setCharacterSpacing(0);\r
         assertEquals(0., r.getCharacterSpacing(), 0);\r
-        assertFalse(r.getRPr().isSetSpc());\r
+        assertFalse(r.getRPr(true).isSetSpc());\r
 \r
         assertTrue(sameColor(Color.black, r.getFontColor()));\r
         r.setFontColor(Color.red);\r
diff --git a/test-data/slideshow/table_test2.pptx b/test-data/slideshow/table_test2.pptx
new file mode 100644 (file)
index 0000000..6250717
Binary files /dev/null and b/test-data/slideshow/table_test2.pptx differ