]> source.dussan.org Git - poi.git/commitdiff
#60625 - Rendering issue with background and shape overlayed by image
authorAndreas Beeker <kiwiwings@apache.org>
Wed, 8 Feb 2017 01:12:22 +0000 (01:12 +0000)
committerAndreas Beeker <kiwiwings@apache.org>
Wed, 8 Feb 2017 01:12:22 +0000 (01:12 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1782096 13f79535-47bb-0310-9956-ffa450edef68

47 files changed:
src/java/org/apache/poi/sl/draw/DrawMasterSheet.java
src/java/org/apache/poi/sl/draw/DrawShape.java
src/java/org/apache/poi/sl/draw/DrawSheet.java
src/java/org/apache/poi/sl/draw/DrawSlide.java
src/java/org/apache/poi/sl/draw/DrawTextParagraph.java
src/java/org/apache/poi/sl/draw/DrawTextShape.java
src/java/org/apache/poi/sl/draw/Drawable.java
src/java/org/apache/poi/sl/usermodel/Placeholder.java
src/java/org/apache/poi/sl/usermodel/Slide.java
src/java/org/apache/poi/sl/usermodel/TextRun.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFLineBreak.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPropertiesDelegate.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideLayout.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableCell.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/XSLFTheme.java
src/ooxml/testcases/org/apache/poi/xslf/TestXSLFSlideShow.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXMLSlideShow.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFAutoShape.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFHyperlink.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFShape.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSlide.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTheme.java
src/scratchpad/src/org/apache/poi/hslf/model/HeadersFooters.java
src/scratchpad/src/org/apache/poi/hslf/record/OEPlaceholderAtom.java
src/scratchpad/src/org/apache/poi/hslf/record/SlideAtom.java
src/scratchpad/src/org/apache/poi/hslf/record/SlideAtomLayout.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java
src/scratchpad/src/org/apache/poi/hslf/record/TextBytesAtom.java
src/scratchpad/src/org/apache/poi/hslf/record/TextCharsAtom.java
src/scratchpad/src/org/apache/poi/hslf/record/TextHeaderAtom.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSheet.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlide.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideMaster.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTitleMaster.java
src/scratchpad/testcases/org/apache/poi/hslf/record/TestSlideAtom.java
src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java
src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestCounts.java

index 3bcedbe850c979ee12010d63fac4b14ac850b4b1..a39cf7d68e3475becc796e9915406e4c068678e8 100644 (file)
 \r
 package org.apache.poi.sl.draw;\r
 \r
-import org.apache.poi.sl.usermodel.*;\r
+import java.awt.Graphics2D;\r
+\r
+import org.apache.poi.sl.usermodel.MasterSheet;\r
+import org.apache.poi.sl.usermodel.Placeholder;\r
+import org.apache.poi.sl.usermodel.Shape;\r
+import org.apache.poi.sl.usermodel.SimpleShape;\r
+import org.apache.poi.sl.usermodel.Slide;\r
 \r
 \r
 public class DrawMasterSheet extends DrawSheet {\r
@@ -33,12 +39,15 @@ public class DrawMasterSheet extends DrawSheet {
      * for instance, slide masters and layouts don't display placeholders\r
      */\r
     @Override\r
-    protected boolean canDraw(Shape<?,?> shape) {\r
+    protected boolean canDraw(Graphics2D graphics, Shape<?,?> shape) {\r
         if (shape instanceof SimpleShape) {\r
+            // in XSLF, slidenumber and date shapes aren't marked as placeholders opposed to HSLF\r
             Placeholder ph = ((SimpleShape<?,?>)shape).getPlaceholder();\r
-            return ph == null;\r
-        } else {\r
-            return true;\r
+            if (ph != null) {\r
+                Slide<?,?> slide = (Slide<?,?>)graphics.getRenderingHint(Drawable.CURRENT_SLIDE);\r
+                return slide.getDisplayPlaceholder(ph);\r
+            }\r
         }\r
+        return true;\r
     }\r
 }\r
index b7b0915c1829db378dfd50707ad5d912b7bb292a..bb1f490bf6898feda7ba206a12b9f6c00b305766 100644 (file)
@@ -38,18 +38,34 @@ public class DrawShape implements Drawable {
         this.shape = shape;\r
     }\r
 \r
+    /**\r
+     * Sometimes it's necessary to distinguish between XSLF/HSLF for the rendering.\r
+     * Use this method on the shape to determine, if we work on the BIFF implementation\r
+     *\r
+     * @param shape the shape to render\r
+     * @return {@code true} if HSLF implementation is used\r
+     */\r
+    protected static boolean isHSLF(Shape<?,?> shape) {\r
+        return shape.getClass().getCanonicalName().toLowerCase(Locale.ROOT).contains("hslf");\r
+    }\r
+    \r
     /**\r
      * Apply 2-D transforms before drawing this shape. This includes rotation and flipping.\r
      *\r
      * @param graphics the graphics whos transform matrix will be modified\r
      */\r
+    @Override\r
     public void applyTransform(Graphics2D graphics) {\r
-        if (!(shape instanceof PlaceableShape)) return;\r
+        if (!(shape instanceof PlaceableShape)) {\r
+            return;\r
+        }\r
 \r
         PlaceableShape<?,?> ps = (PlaceableShape<?,?>)shape;\r
-        final boolean isHSLF = ps.getClass().getCanonicalName().toLowerCase(Locale.ROOT).contains("hslf");\r
+        final boolean isHSLF = isHSLF(shape);\r
         AffineTransform tx = (AffineTransform)graphics.getRenderingHint(Drawable.GROUP_TRANSFORM);\r
-        if (tx == null) tx = new AffineTransform();\r
+        if (tx == null) {\r
+            tx = new AffineTransform();\r
+        }\r
         final Rectangle2D anchor = tx.createTransformedShape(ps.getAnchor()).getBounds2D();\r
 \r
         char cmds[] = isHSLF ? new char[]{ 'h','v','r' } : new char[]{ 'r','h','v' };\r
@@ -81,7 +97,9 @@ public class DrawShape implements Drawable {
 \r
                     // normalize rotation\r
                     rotation %= 360.;\r
-                    if (rotation < 0) rotation += 360.;\r
+                    if (rotation < 0) {\r
+                        rotation += 360.;\r
+                    }\r
 \r
                     int quadrant = (((int)rotation+45)/90)%4;\r
                     double scaleX = 1.0, scaleY = 1.0;\r
@@ -148,9 +166,11 @@ public class DrawShape implements Drawable {
         return (dim2 == 0.) ? 1 : dim1/dim2;\r
     }\r
 \r
+    @Override\r
     public void draw(Graphics2D graphics) {\r
     }\r
 \r
+    @Override\r
     public void drawContent(Graphics2D graphics) {\r
     }\r
 \r
@@ -176,7 +196,10 @@ public class DrawShape implements Drawable {
     \r
     protected static BasicStroke getStroke(StrokeStyle strokeStyle) {\r
         float lineWidth = (float) strokeStyle.getLineWidth();\r
-        if (lineWidth == 0.0f) lineWidth = 0.25f; // Both PowerPoint and OOo draw zero-length lines as 0.25pt\r
+        if (lineWidth == 0.0f) {\r
+            // Both PowerPoint and OOo draw zero-length lines as 0.25pt\r
+            lineWidth = 0.25f;\r
+        }\r
 \r
         LineDash lineDash = strokeStyle.getLineDash();\r
         if (lineDash == null) {\r
@@ -194,7 +217,9 @@ public class DrawShape implements Drawable {
         }\r
 \r
         LineCap lineCapE = strokeStyle.getLineCap();\r
-        if (lineCapE == null) lineCapE = LineCap.FLAT;\r
+        if (lineCapE == null) {\r
+            lineCapE = LineCap.FLAT;\r
+        }\r
         int lineCap;\r
         switch (lineCapE) {\r
             case ROUND:\r
index dbe82ea6c8b321851830fbf2d5d0223b3e8c3592..5c8d76abeb0ec58f68f8c330cb9d6aff80a63429 100644 (file)
 \r
 package org.apache.poi.sl.draw;\r
 \r
-import java.awt.Dimension;\r
 import java.awt.Color;\r
+import java.awt.Dimension;\r
 import java.awt.Graphics2D;\r
-\r
 import java.awt.geom.AffineTransform;\r
 \r
-import org.apache.poi.sl.usermodel.*;\r
+import org.apache.poi.sl.usermodel.MasterSheet;\r
+import org.apache.poi.sl.usermodel.Shape;\r
+import org.apache.poi.sl.usermodel.Sheet;\r
 \r
 \r
 public class DrawSheet implements Drawable {\r
@@ -34,6 +35,7 @@ public class DrawSheet implements Drawable {
         this.sheet = sheet;\r
     }\r
     \r
+    @Override\r
     public void draw(Graphics2D graphics) {\r
         Dimension dim = sheet.getSlideShow().getPageSize();\r
         Color whiteTrans = new Color(1f,1f,1f,0f);\r
@@ -51,7 +53,9 @@ public class DrawSheet implements Drawable {
         graphics.setRenderingHint(Drawable.GROUP_TRANSFORM, new AffineTransform());\r
 \r
         for (Shape<?,?> shape : sheet.getShapes()) {\r
-            if(!canDraw(shape)) continue;\r
+            if(!canDraw(graphics, shape)) {\r
+                continue;\r
+            }\r
             \r
             // remember the initial transform and restore it after we are done with drawing\r
             AffineTransform at = graphics.getTransform();\r
@@ -73,9 +77,11 @@ public class DrawSheet implements Drawable {
         }\r
     }\r
 \r
+    @Override\r
     public void applyTransform(Graphics2D context) {\r
     }\r
 \r
+    @Override\r
     public void drawContent(Graphics2D context) {\r
     }\r
 \r
@@ -85,7 +91,7 @@ public class DrawSheet implements Drawable {
      * Subclasses can override it and skip certain shapes from drawings,\r
      * for instance, slide masters and layouts don't display placeholders\r
      */\r
-    protected boolean canDraw(Shape<?,?> shape){\r
+    protected boolean canDraw(Graphics2D graphics, Shape<?,?> shape){\r
         return true;\r
     }\r
 }\r
index ae4baa27fbf062c144b05b12c4a6b80f3fd99426..2320e907a654b2d8dc9a95923a2449213c5b3254 100644 (file)
@@ -29,6 +29,8 @@ public class DrawSlide extends DrawSheet {
     }\r
     \r
     public void draw(Graphics2D graphics) {\r
+        graphics.setRenderingHint(Drawable.CURRENT_SLIDE, this.sheet);\r
+        \r
         Background<?,?> bg = sheet.getBackground();\r
         if(bg != null) {\r
             DrawFactory drawFact = DrawFactory.getInstance(graphics);\r
@@ -37,5 +39,6 @@ public class DrawSlide extends DrawSheet {
         }\r
 \r
         super.draw(graphics);\r
+        graphics.setRenderingHint(Drawable.CURRENT_SLIDE, null);\r
     }\r
 }\r
index b1fbd9b0671316a9ad59ca1af5c22e5664436ac0..f2b24b0ff2a590a0eaf2916e4b6cd03125661882 100644 (file)
@@ -41,10 +41,12 @@ import org.apache.poi.sl.usermodel.PaintStyle;
 import org.apache.poi.sl.usermodel.PlaceableShape;\r
 import org.apache.poi.sl.usermodel.ShapeContainer;\r
 import org.apache.poi.sl.usermodel.Sheet;\r
+import org.apache.poi.sl.usermodel.Slide;\r
 import org.apache.poi.sl.usermodel.TextParagraph;\r
 import org.apache.poi.sl.usermodel.TextParagraph.BulletStyle;\r
 import org.apache.poi.sl.usermodel.TextParagraph.TextAlign;\r
 import org.apache.poi.sl.usermodel.TextRun;\r
+import org.apache.poi.sl.usermodel.TextRun.FieldType;\r
 import org.apache.poi.sl.usermodel.TextRun.TextCap;\r
 import org.apache.poi.sl.usermodel.TextShape;\r
 import org.apache.poi.sl.usermodel.TextShape.TextDirection;\r
@@ -82,6 +84,7 @@ public class DrawTextParagraph implements Drawable {
         /**\r
          * Resolves instances being deserialized to the predefined constants.\r
          */\r
+        @Override\r
         protected Object readResolve() throws InvalidObjectException {\r
             if (HYPERLINK_HREF.getName().equals(getName())) {\r
                 return HYPERLINK_HREF;\r
@@ -116,8 +119,11 @@ public class DrawTextParagraph implements Drawable {
         autoNbrIdx = index;\r
     }\r
 \r
+    @Override\r
     public void draw(Graphics2D graphics){\r
-        if (lines.isEmpty()) return;\r
+        if (lines.isEmpty()) {\r
+            return;\r
+        }\r
 \r
         double penY = y;\r
 \r
@@ -144,7 +150,9 @@ public class DrawTextParagraph implements Drawable {
 \r
         //The vertical line spacing\r
         Double spacing = paragraph.getLineSpacing();\r
-        if (spacing == null) spacing = 100d;\r
+        if (spacing == null) {\r
+            spacing = 100d;\r
+        }\r
 \r
         for(DrawTextFragment line : lines){\r
             double penX;\r
@@ -176,7 +184,9 @@ public class DrawTextParagraph implements Drawable {
             double rightInset = insets.right;\r
 \r
             TextAlign ta = paragraph.getTextAlign();\r
-            if (ta == null) ta = TextAlign.LEFT;\r
+            if (ta == null) {\r
+                ta = TextAlign.LEFT;\r
+            }\r
             switch (ta) {\r
                 case CENTER:\r
                     penX += (anchor.getWidth() - line.getWidth() - leftInset - rightInset - leftMargin) / 2;\r
@@ -217,9 +227,11 @@ public class DrawTextParagraph implements Drawable {
         return (lines.isEmpty() || rawText.trim().isEmpty());\r
     }\r
 \r
+    @Override\r
     public void applyTransform(Graphics2D graphics) {\r
     }\r
 \r
+    @Override\r
     public void drawContent(Graphics2D graphics) {\r
     }\r
 \r
@@ -243,10 +255,14 @@ public class DrawTextParagraph implements Drawable {
 \r
             double wrappingWidth = getWrappingWidth(lines.size() == 0, graphics) + 1; // add a pixel to compensate rounding errors\r
             // shape width can be smaller that the sum of insets (this was proved by a test file)\r
-            if(wrappingWidth < 0) wrappingWidth = 1;\r
+            if(wrappingWidth < 0) {\r
+                wrappingWidth = 1;\r
+            }\r
 \r
             int nextBreak = text.indexOf("\n", startIndex + 1);\r
-            if (nextBreak == -1) nextBreak = it.getEndIndex();\r
+            if (nextBreak == -1) {\r
+                nextBreak = it.getEndIndex();\r
+            }\r
 \r
             TextLayout layout = measurer.nextLayout((float)wrappingWidth, nextBreak, true);\r
             if (layout == null) {\r
@@ -279,7 +295,9 @@ public class DrawTextParagraph implements Drawable {
 \r
             maxLineHeight = Math.max(maxLineHeight, line.getHeight());\r
 \r
-            if(endIndex == it.getEndIndex()) break;\r
+            if(endIndex == it.getEndIndex()) {\r
+                break;\r
+            }\r
         }\r
 \r
         rawText = text.toString();\r
@@ -287,7 +305,9 @@ public class DrawTextParagraph implements Drawable {
 \r
     protected DrawTextFragment getBullet(Graphics2D graphics, AttributedCharacterIterator firstLineAttr) {\r
         BulletStyle bulletStyle = paragraph.getBulletStyle();\r
-        if (bulletStyle == null) return null;\r
+        if (bulletStyle == null) {\r
+            return null;\r
+        }\r
 \r
         String buCharacter;\r
         AutoNumberingScheme ans = bulletStyle.getAutoNumberingScheme();\r
@@ -296,10 +316,14 @@ public class DrawTextParagraph implements Drawable {
         } else {\r
             buCharacter = bulletStyle.getBulletCharacter();\r
         }\r
-        if (buCharacter == null) return null;\r
+        if (buCharacter == null) {\r
+            return null;\r
+        }\r
 \r
         String buFont = bulletStyle.getBulletFont();\r
-        if (buFont == null) buFont = paragraph.getDefaultFontFamily();\r
+        if (buFont == null) {\r
+            buFont = paragraph.getDefaultFontFamily();\r
+        }\r
         assert(buFont != null);\r
 \r
         PlaceableShape<?,?> ps = getParagraphShape();\r
@@ -313,9 +337,14 @@ public class DrawTextParagraph implements Drawable {
 \r
         float fontSize = (Float)firstLineAttr.getAttribute(TextAttribute.SIZE);\r
         Double buSz = bulletStyle.getBulletFontSize();\r
-        if (buSz == null) buSz = 100d;\r
-        if (buSz > 0) fontSize *= buSz* 0.01;\r
-        else fontSize = (float)-buSz;\r
+        if (buSz == null) {\r
+            buSz = 100d;\r
+        }\r
+        if (buSz > 0) {\r
+            fontSize *= buSz* 0.01;\r
+        } else {\r
+            fontSize = (float)-buSz;\r
+        }\r
 \r
 \r
         AttributedString str = new AttributedString(mapFontCharset(buCharacter,buFont));\r
@@ -328,7 +357,11 @@ public class DrawTextParagraph implements Drawable {
         return fact.getTextFragment(layout, str);\r
     }\r
 \r
-    protected String getRenderableText(TextRun tr) {\r
+    protected String getRenderableText(Graphics2D graphics, TextRun tr) {\r
+        if (tr.getFieldType() == FieldType.SLIDE_NUMBER) {\r
+            Slide<?,?> slide = (Slide<?,?>)graphics.getRenderingHint(Drawable.CURRENT_SLIDE);\r
+            return (slide == null) ? "" : Integer.toString(slide.getSlideNumber()); \r
+        }\r
         StringBuilder buf = new StringBuilder();\r
         TextCap cap = tr.getTextCap();\r
         String tabs = null;\r
@@ -364,18 +397,24 @@ public class DrawTextParagraph implements Drawable {
     private String tab2space(TextRun tr) {\r
         AttributedString string = new AttributedString(" ");\r
         String fontFamily = tr.getFontFamily();\r
-        if (fontFamily == null) fontFamily = "Lucida Sans";\r
+        if (fontFamily == null) {\r
+            fontFamily = "Lucida Sans";\r
+        }\r
         string.addAttribute(TextAttribute.FAMILY, fontFamily);\r
 \r
         Double fs = tr.getFontSize();\r
-        if (fs == null) fs = 12d;\r
+        if (fs == null) {\r
+            fs = 12d;\r
+        }\r
         string.addAttribute(TextAttribute.SIZE, fs.floatValue());\r
 \r
         TextLayout l = new TextLayout(string.getIterator(), new FontRenderContext(null, true, true));\r
         double wspace = l.getAdvance();\r
 \r
         Double tabSz = paragraph.getDefaultTabSize();\r
-        if (tabSz == null) tabSz = wspace*4;\r
+        if (tabSz == null) {\r
+            tabSz = wspace*4;\r
+        }\r
 \r
         int numSpaces = (int)Math.ceil(tabSz / wspace);\r
         StringBuilder buf = new StringBuilder();\r
@@ -449,10 +488,13 @@ public class DrawTextParagraph implements Drawable {
             }\r
             if (firstLine && !isHSLF()) {\r
                 if (bullet != null){\r
-                    if (indent > 0) width -= indent;\r
+                    if (indent > 0) {\r
+                        width -= indent;\r
+                    }\r
                 } else {\r
-                    if (indent > 0) width -= indent; // first line indentation\r
-                    else if (indent < 0) { // hanging indentation: the first line start at the left margin\r
+                    if (indent > 0) {\r
+                        width -= indent; // first line indentation\r
+                    } else if (indent < 0) { // hanging indentation: the first line start at the left margin\r
                         width += leftMargin;\r
                     }\r
                 }\r
@@ -480,25 +522,36 @@ public class DrawTextParagraph implements Drawable {
     @SuppressWarnings("rawtypes")\r
     private PlaceableShape<?,?> getParagraphShape() {\r
         return new PlaceableShape(){\r
+            @Override\r
             public ShapeContainer<?,?> getParent() { return null; }\r
+            @Override\r
             public Rectangle2D getAnchor() { return paragraph.getParentShape().getAnchor(); }\r
+            @Override\r
             public void setAnchor(Rectangle2D anchor) {}\r
+            @Override\r
             public double getRotation() { return 0; }\r
+            @Override\r
             public void setRotation(double theta) {}\r
+            @Override\r
             public void setFlipHorizontal(boolean flip) {}\r
+            @Override\r
             public void setFlipVertical(boolean flip) {}\r
+            @Override\r
             public boolean getFlipHorizontal() { return false; }\r
+            @Override\r
             public boolean getFlipVertical() { return false; }\r
+            @Override\r
             public Sheet<?,?> getSheet() { return paragraph.getParentShape().getSheet(); }\r
         };\r
     }\r
 \r
     protected AttributedString getAttributedString(Graphics2D graphics, StringBuilder text){\r
         List<AttributedStringData> attList = new ArrayList<AttributedStringData>();\r
-        if (text == null) text = new StringBuilder();\r
+        if (text == null) {\r
+            text = new StringBuilder();\r
+        }\r
 \r
         PlaceableShape<?,?> ps = getParagraphShape();\r
-\r
         DrawFontManager fontHandler = (DrawFontManager)graphics.getRenderingHint(Drawable.FONT_HANDLER);\r
         @SuppressWarnings("unchecked")\r
         Map<String,String> fontMap = (Map<String,String>)graphics.getRenderingHint(Drawable.FONT_MAP);\r
@@ -506,9 +559,11 @@ public class DrawTextParagraph implements Drawable {
         Map<String,String> fallbackMap = (Map<String,String>)graphics.getRenderingHint(Drawable.FONT_FALLBACK);\r
 \r
         for (TextRun run : paragraph){\r
-            String runText = getRenderableText(run);\r
+            String runText = getRenderableText(graphics, run);\r
             // skip empty runs\r
-            if (runText.isEmpty()) continue;\r
+            if (runText.isEmpty()) {\r
+                continue;\r
+            }\r
 \r
             // user can pass an custom object to convert fonts\r
             String mappedFont = run.getFontFamily();\r
@@ -633,8 +688,11 @@ public class DrawTextParagraph implements Drawable {
         return string;\r
     }\r
 \r
+    /**\r
+     * @return {@code true} if the HSLF implementation is used\r
+     */\r
     protected boolean isHSLF() {\r
-        return paragraph.getClass().getName().contains("HSLF");\r
+        return DrawShape.isHSLF(paragraph.getParentShape());\r
     }\r
 \r
     /**\r
index 3a1d8faeeaa0d4e2883f4eaa90f09693dba50ba3..45819624bb76e860c9e8bb4c713d385e83ea8e56 100644 (file)
@@ -138,6 +138,7 @@ public class DrawTextShape extends DrawSimpleShape {
 \r
         double y0 = y;\r
         //noinspection RedundantCast\r
+        @SuppressWarnings("cast")\r
         Iterator<? extends TextParagraph<?,?,? extends TextRun>> paragraphs =\r
             (Iterator<? extends TextParagraph<?,?,? extends TextRun>>) getShape().iterator();\r
         \r
index 7df8533b5629d0fc83a7718c991df5ec2afd2ce9..cc85dde90523a0be5ad11c8071835826a738d515 100644 (file)
@@ -130,6 +130,12 @@ public interface Drawable {
     DrawableHint GSAVE = new DrawableHint(10);\r
     DrawableHint GRESTORE = new DrawableHint(11);\r
     \r
+    /**\r
+     * The Common SL Draw API works sometimes cascading, but there are places\r
+     * where the current slide context need to be evaluated, e.g. when slide numbers\r
+     * are printed. In this situation we need to have a way to access the current slide\r
+     */\r
+    DrawableHint CURRENT_SLIDE = new DrawableHint(12);\r
     \r
     \r
     /**\r
index a3bc9c7c88900a8c2762e870ecf8be34623ae6bd..e546e8bee21491a9d4ea735260ededa5088cf03e 100644 (file)
@@ -114,12 +114,30 @@ public enum Placeholder {
         this.ooxmlId = ooxmlId;\r
     }\r
     \r
-    public static Placeholder lookupNative(int nativeId) {\r
+    public static Placeholder lookupNativeSlide(int nativeId) {\r
+        return lookupNative(nativeId, 0);\r
+    }\r
+\r
+    public static Placeholder lookupNativeSlideMaster(int nativeId) {\r
+        return lookupNative(nativeId, 1);\r
+    }\r
+\r
+    public static Placeholder lookupNativeNotes(int nativeId) {\r
+        return lookupNative(nativeId, 2);\r
+    }\r
+\r
+    public static Placeholder lookupNativeNotesMaster(int nativeId) {\r
+        return lookupNative(nativeId, 3);\r
+    }\r
+\r
+    \r
+    private static Placeholder lookupNative(int nativeId, int type) {\r
         for (Placeholder ph : values()) {\r
-            if (ph.nativeSlideId == nativeId ||\r
-                ph.nativeSlideMasterId == nativeId || \r
-                ph.nativeNotesId == nativeId ||\r
-                ph.nativeNotesMasterId == nativeId\r
+            if (\r
+                type == 0 && ph.nativeSlideId == nativeId ||\r
+                type == 1 && ph.nativeSlideMasterId == nativeId || \r
+                type == 2 && ph.nativeNotesId == nativeId ||\r
+                type == 3 && ph.nativeNotesMasterId == nativeId\r
             ) {\r
                 return ph;\r
             }\r
index dae2f42e674e57c34f3674a58fa7a5561db24eff..1f77ba6e5d10ae3cc8ec6db8bb3d1c1cf8c92c2a 100644 (file)
@@ -43,4 +43,14 @@ public interface Slide<
      */
     String getTitle();
 
+    /**
+     * In XSLF, slidenumber and date shapes aren't marked as placeholders
+     * whereas in HSLF they are activated via a HeadersFooter configuration.
+     * This method is used to generalize that handling.
+     *
+     * @param placeholder
+     * @return {@code true} if the placeholder should be displayed/rendered
+     * @since POI 3.16-beta2
+     */
+    boolean getDisplayPlaceholder(Placeholder placeholder);
 }
index 014d3036b3b7afe0bd7b0dda4eba2ce91262c665..32b9c9933d08264fa54d9c420453a04d74f0ed06 100644 (file)
@@ -20,6 +20,7 @@ package org.apache.poi.sl.usermodel;
 import java.awt.Color;
 
 import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
+import org.apache.poi.util.Internal;
 
 /**
  * Some text.
@@ -30,6 +31,10 @@ public interface TextRun {
         SMALL,
         ALL
     }
+    
+    enum FieldType {
+        SLIDE_NUMBER, DATE_TIME
+    }
 
     String getRawText();
     void setText(String text);
@@ -176,4 +181,12 @@ public interface TextRun {
      * @since POI 3.14-Beta2
      */
     Hyperlink<?,?> createHyperlink();
+    
+    /**
+     * Experimental method to determine the field type, e.g. slide number
+     *
+     * @return the field type or {@code null} if text run is not a field
+     */
+    @Internal
+    FieldType getFieldType();
 }
index bdbc461f4b8db057b2e035109b91965fdce99fe2..934c0e3eec14343fc574da586b843a536d7d1a63 100644 (file)
 \r
 package org.apache.poi.xslf.usermodel;\r
 \r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextLineBreak;\r
 \r
 class XSLFLineBreak extends XSLFTextRun {\r
-    private final CTTextCharacterProperties _brProps;\r
-\r
-    XSLFLineBreak(CTRegularTextRun r, XSLFTextParagraph p, CTTextCharacterProperties brProps){\r
+    protected XSLFLineBreak(CTTextLineBreak r, XSLFTextParagraph p) {\r
         super(r, p);\r
-        _brProps = brProps;\r
-    }\r
-\r
-    @Override\r
-    protected CTTextCharacterProperties getRPr(boolean create){\r
-        return _brProps;\r
     }\r
 \r
     public void setText(String text){\r
index f6e5ad0a95574b4aafbac1cc9fc3533fa2a637c9..a15d90cc4d38ed0163f39002a36d7e1d8a26a4a8 100644 (file)
@@ -1341,106 +1341,138 @@ import org.openxmlformats.schemas.presentationml.x2006.main.CTBackgroundProperti
             this.props = props;
         }
 
+        @Override
         public CTNoFillProperties getNoFill() {
             return isSetNoFill() ? (CTNoFillProperties)props : null;
         }
 
+        @Override
         public boolean isSetNoFill() {
             return (props instanceof CTNoFillProperties);
         }
 
+        @Override
         public void setNoFill(CTNoFillProperties noFill) {}
 
+        @Override
         public CTNoFillProperties addNewNoFill() {
             return null;
         }
 
+        @Override
         public void unsetNoFill() {}
 
+        @Override
         public CTSolidColorFillProperties getSolidFill() {
             return isSetSolidFill() ? (CTSolidColorFillProperties)props : null;
         }
 
+        @Override
         public boolean isSetSolidFill() {
             return (props instanceof CTSolidColorFillProperties);
         }
 
+        @Override
         public void setSolidFill(CTSolidColorFillProperties solidFill) {}
 
+        @Override
         public CTSolidColorFillProperties addNewSolidFill() {
             return null;
         }
 
+        @Override
         public void unsetSolidFill() {}
 
+        @Override
         public CTGradientFillProperties getGradFill() {
             return isSetGradFill() ? (CTGradientFillProperties)props : null;
         }
 
+        @Override
         public boolean isSetGradFill() {
             return (props instanceof CTGradientFillProperties);
         }
 
+        @Override
         public void setGradFill(CTGradientFillProperties gradFill) {}
 
+        @Override
         public CTGradientFillProperties addNewGradFill() {
             return null;
         }
 
+        @Override
         public void unsetGradFill() {}
 
+        @Override
         public CTBlipFillProperties getBlipFill() {
             return isSetBlipFill() ? (CTBlipFillProperties)props : null;
         }
 
+        @Override
         public boolean isSetBlipFill() {
             return (props instanceof CTBlipFillProperties);
         }
 
+        @Override
         public void setBlipFill(CTBlipFillProperties blipFill) {}
 
+        @Override
         public CTBlipFillProperties addNewBlipFill() {
             return null;
         }
 
+        @Override
         public void unsetBlipFill() {}
 
+        @Override
         public CTPatternFillProperties getPattFill() {
             return isSetPattFill() ? (CTPatternFillProperties)props : null;
         }
 
+        @Override
         public boolean isSetPattFill() {
             return (props instanceof CTPatternFillProperties);
         }
 
+        @Override
         public void setPattFill(CTPatternFillProperties pattFill) {}
 
+        @Override
         public CTPatternFillProperties addNewPattFill() {
             return null;
         }
 
+        @Override
         public void unsetPattFill() {}
 
+        @Override
         public CTGroupFillProperties getGrpFill() {
             return isSetGrpFill() ? (CTGroupFillProperties)props : null;
         }
 
+        @Override
         public boolean isSetGrpFill() {
             return (props instanceof CTGroupFillProperties);
         }
 
+        @Override
         public void setGrpFill(CTGroupFillProperties grpFill) {}
 
+        @Override
         public CTGroupFillProperties addNewGrpFill() {
             return null;
         }
 
+        @Override
         public void unsetGrpFill() {}
 
+        @Override
         public boolean isSetMatrixStyle() {
             return false;
         }
 
+        @Override
         public CTStyleMatrixReference getMatrixStyle() {
             return null;
         }
index 70df3f806ab7a0360fc4cb9c16360342d06ea3f2..d73dcc8c0a53e893f0b0a9b6c1870f1a9ded371e 100644 (file)
@@ -32,6 +32,7 @@ import org.apache.poi.openxml4j.opc.PackageRelationship;
 import org.apache.poi.sl.draw.DrawFactory;\r
 import org.apache.poi.sl.draw.DrawPaint;\r
 import org.apache.poi.sl.usermodel.ColorStyle;\r
+import org.apache.poi.sl.usermodel.MasterSheet;\r
 import org.apache.poi.sl.usermodel.PaintStyle;\r
 import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint;\r
 import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint;\r
@@ -57,6 +58,7 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillPropertie
 import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrix;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrixReference;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.STPathShadeType;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.STSchemeColorVal;\r
 import org.openxmlformats.schemas.presentationml.x2006.main.CTApplicationNonVisualDrawingProps;\r
 import org.openxmlformats.schemas.presentationml.x2006.main.CTBackgroundProperties;\r
 import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;\r
@@ -150,6 +152,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
     \r
     protected PaintStyle getFillPaint() {\r
         final XSLFTheme theme = getSheet().getTheme();\r
+        final boolean hasPlaceholder = getPlaceholder() != null;\r
         PropertyFetcher<PaintStyle> fetcher = new PropertyFetcher<PaintStyle>() {\r
             public boolean fetch(XSLFShape shape) {\r
                 XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(shape.getShapeProperties());\r
@@ -163,7 +166,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
                 }\r
                 \r
                 PackagePart pp = shape.getSheet().getPackagePart();\r
-                PaintStyle paint = selectPaint(fp, null, pp, theme);\r
+                PaintStyle paint = selectPaint(fp, null, pp, theme, hasPlaceholder);\r
                 if (paint != null) {\r
                     setValue(paint);\r
                     return true;\r
@@ -172,7 +175,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
                 CTShapeStyle style = shape.getSpStyle();\r
                 if (style != null) {\r
                     fp = XSLFPropertiesDelegate.getFillDelegate(style.getFillRef());\r
-                    paint = selectPaint(fp, null, pp, theme);\r
+                    paint = selectPaint(fp, null, pp, theme, hasPlaceholder);\r
                 }\r
                 if (paint != null) {\r
                     setValue(paint);\r
@@ -230,6 +233,9 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
         if (cur.toChild(namespace, nodename)) {\r
             child = (T)cur.getObject();\r
         }\r
+        if (cur.toChild("http://schemas.openxmlformats.org/drawingml/2006/main", nodename)) {\r
+            child = (T)cur.getObject();\r
+        }\r
         cur.dispose();\r
         return child;\r
     }\r
@@ -290,61 +296,71 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
     }\r
 \r
     /**\r
-     * Walk up the inheritance tree and fetch shape properties.\r
+     * Walk up the inheritance tree and fetch shape properties.<p>\r
      *\r
-     * The following order of inheritance is assumed:\r
-     * <p>\r
-     * slide <-- slideLayout <-- slideMaster\r
-     * </p>\r
+     * The following order of inheritance is assumed:<p>\r
+     * <ol>\r
+     * <li>slide\r
+     * <li>slideLayout\r
+     * <li>slideMaster\r
+     * </ol>\r
+     * \r
+     * Currently themes and their defaults aren't correctly handled\r
      *\r
      * @param visitor the object that collects the desired property\r
      * @return true if the property was fetched\r
      */\r
     protected boolean fetchShapeProperty(PropertyFetcher<?> visitor) {\r
-        boolean ok = visitor.fetch(this);\r
+        // try shape properties in slide\r
+        if (visitor.fetch(this)) {\r
+            return true;\r
+        }\r
 \r
-        XSLFSimpleShape masterShape;\r
-        XSLFSheet masterSheet = (XSLFSheet)getSheet().getMasterSheet();\r
         CTPlaceholder ph = getCTPlaceholder();\r
-\r
-        if (masterSheet != null && ph != null) {\r
-            if (!ok) {\r
-                masterShape = masterSheet.getPlaceholder(ph);\r
-                if (masterShape != null) {\r
-                    ok = visitor.fetch(masterShape);\r
-                }\r
+        if (ph == null) {\r
+            return false;\r
+        }\r
+        MasterSheet<XSLFShape,XSLFTextParagraph> sm = getSheet().getMasterSheet();\r
+        \r
+        // try slide layout\r
+        if (sm instanceof XSLFSlideLayout) {\r
+            XSLFSlideLayout slideLayout = (XSLFSlideLayout)sm;\r
+            XSLFSimpleShape placeholderShape = slideLayout.getPlaceholder(ph);\r
+            if (placeholderShape != null && visitor.fetch(placeholderShape)) {\r
+                return true;\r
             }\r
-\r
-            // try slide master\r
-            if (!ok ) {\r
-                int textType;\r
-                if ( !ph.isSetType()) textType = STPlaceholderType.INT_BODY;\r
-                else {\r
-                    switch (ph.getType().intValue()) {\r
-                        case STPlaceholderType.INT_TITLE:\r
-                        case STPlaceholderType.INT_CTR_TITLE:\r
-                            textType = STPlaceholderType.INT_TITLE;\r
-                            break;\r
-                        case STPlaceholderType.INT_FTR:\r
-                        case STPlaceholderType.INT_SLD_NUM:\r
-                        case STPlaceholderType.INT_DT:\r
-                            textType = ph.getType().intValue();\r
-                            break;\r
-                        default:\r
-                            textType = STPlaceholderType.INT_BODY;\r
-                            break;\r
-                    }\r
-                }\r
-                XSLFSheet master = (XSLFSheet)masterSheet.getMasterSheet();\r
-                if (master != null) {\r
-                    masterShape = master.getPlaceholderByType(textType);\r
-                    if (masterShape != null) {\r
-                        ok = visitor.fetch(masterShape);\r
-                    }\r
-                }\r
+            sm = slideLayout.getMasterSheet();\r
+        }\r
+        \r
+        // try slide master\r
+        if (sm instanceof XSLFSlideMaster) {\r
+            XSLFSlideMaster master = (XSLFSlideMaster)sm;\r
+            int textType = getPlaceholderType(ph);\r
+            XSLFSimpleShape masterShape = master.getPlaceholderByType(textType);\r
+            if (masterShape != null && visitor.fetch(masterShape)) {\r
+                return true;\r
             }\r
         }\r
-        return ok;\r
+        \r
+        return false;\r
+    }\r
+    \r
+    private static int getPlaceholderType(CTPlaceholder ph) {\r
+        if ( !ph.isSetType()) {\r
+            return STPlaceholderType.INT_BODY;\r
+        }\r
+        \r
+        switch (ph.getType().intValue()) {\r
+            case STPlaceholderType.INT_TITLE:\r
+            case STPlaceholderType.INT_CTR_TITLE:\r
+                return STPlaceholderType.INT_TITLE;\r
+            case STPlaceholderType.INT_FTR:\r
+            case STPlaceholderType.INT_SLD_NUM:\r
+            case STPlaceholderType.INT_DT:\r
+                return ph.getType().intValue();\r
+            default:\r
+                return STPlaceholderType.INT_BODY;\r
+        }\r
     }\r
 \r
     /**\r
@@ -358,7 +374,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
      *\r
      * @return  the applied Paint or null if none was applied\r
      */\r
-    protected static PaintStyle selectPaint(XSLFFillProperties fp, final CTSchemeColor phClr, final PackagePart parentPart, final XSLFTheme theme) {\r
+    protected static PaintStyle selectPaint(XSLFFillProperties fp, final CTSchemeColor phClr, final PackagePart parentPart, final XSLFTheme theme, boolean hasPlaceholder) {\r
         if (fp == null || fp.isSetNoFill()) {\r
             return null;\r
         } else if (fp.isSetSolidFill()) {\r
@@ -368,15 +384,23 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
         } else if (fp.isSetGradFill()) {\r
             return selectPaint(fp.getGradFill(), phClr, theme);\r
         } else if (fp.isSetMatrixStyle()) {\r
-            return selectPaint(fp.getMatrixStyle(), theme, fp.isLineStyle());\r
+            return selectPaint(fp.getMatrixStyle(), theme, fp.isLineStyle(), hasPlaceholder);\r
         } else {\r
             return null;\r
         }\r
     }\r
 \r
     protected static PaintStyle selectPaint(CTSolidColorFillProperties solidFill, CTSchemeColor phClr, final XSLFTheme theme) {\r
-        if (phClr == null && solidFill.isSetSchemeClr()) {\r
-            phClr = solidFill.getSchemeClr();\r
+        if (solidFill.isSetSchemeClr()) {\r
+               // if there's a reference to the placeholder color,\r
+               // stop evaluating further and let the caller select\r
+               // the next style inheritance level\r
+            if (STSchemeColorVal.PH_CLR.equals(solidFill.getSchemeClr().getVal())) {\r
+                return null;\r
+            }\r
+            if (phClr == null) {\r
+                phClr = solidFill.getSchemeClr();\r
+            }\r
         }\r
         final XSLFColor c = new XSLFColor(solidFill, theme, phClr);\r
         return DrawPaint.createSolidPaint(c.getColorStyle());\r
@@ -483,7 +507,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
         };        \r
     }\r
     \r
-    protected static PaintStyle selectPaint(CTStyleMatrixReference fillRef, final XSLFTheme theme, boolean isLineStyle) {\r
+    protected static PaintStyle selectPaint(CTStyleMatrixReference fillRef, final XSLFTheme theme, boolean isLineStyle, boolean hasPlaceholder) {\r
         if (fillRef == null) return null;\r
         \r
         // The idx attribute refers to the index of a fill style or\r
@@ -492,7 +516,6 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
         // values 1-999 refer to the index of a fill style within the fillStyleLst element\r
         // values 1001 and above refer to the index of a background fill style within the bgFillStyleLst element.\r
         int idx = (int)fillRef.getIdx();\r
-        CTSchemeColor phClr = fillRef.getSchemeClr();\r
         CTStyleMatrix matrix = theme.getXmlObject().getThemeElements().getFmtScheme();\r
         final XmlObject styleLst;\r
         int childIdx;\r
@@ -511,8 +534,16 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
             fp = XSLFPropertiesDelegate.getFillDelegate(cur.getObject());\r
         }\r
         cur.dispose();\r
-        \r
-        return selectPaint(fp, phClr, theme.getPackagePart(), theme);\r
+            \r
+        CTSchemeColor phClr = fillRef.getSchemeClr();\r
+        PaintStyle res =  selectPaint(fp, phClr, theme.getPackagePart(), theme, hasPlaceholder);\r
+        // check for empty placeholder value\r
+        // see http://officeopenxml.com/prSlide-color.php - "Color Placeholders within Themes"\r
+        if (res != null || hasPlaceholder) {\r
+            return res;\r
+        }\r
+        XSLFColor col = new XSLFColor(fillRef, theme, phClr);\r
+        return DrawPaint.createSolidPaint(col.getColorStyle());\r
     }\r
     \r
     @Override\r
index ce058f15a0039380c43d22680fd9023a26716d33..5d1d23191c7fd01c4cefbb41aa23e66a60cd4c3b 100644 (file)
@@ -121,6 +121,7 @@ public abstract class XSLFSimpleShape extends XSLFShape
 
     protected CTTransform2D getXfrm(boolean create) {
         PropertyFetcher<CTTransform2D> fetcher = new PropertyFetcher<CTTransform2D>() {
+            @Override
             public boolean fetch(XSLFShape shape) {
                 XmlObject xo = shape.getShapeProperties();
                 if (xo instanceof CTShapeProperties && ((CTShapeProperties)xo).isSetXfrm()) {
@@ -234,20 +235,32 @@ public abstract class XSLFSimpleShape extends XSLFShape
      */
     CTLineProperties getDefaultLineProperties() {
         CTShapeStyle style = getSpStyle();
-        if (style == null) return null;
+        if (style == null) {
+            return null;
+        }
         CTStyleMatrixReference lnRef = style.getLnRef();
-        if (lnRef == null) return null;
+        if (lnRef == null) {
+            return null;
+        }
         // 1-based index of a line style within the style matrix
         int idx = (int)lnRef.getIdx();
 
         XSLFTheme theme = getSheet().getTheme();
-        if (theme == null) return null;
+        if (theme == null) {
+            return null;
+        }
         CTBaseStyles styles = theme.getXmlObject().getThemeElements();
-        if (styles == null) return null;
+        if (styles == null) {
+            return null;
+        }
         CTStyleMatrix styleMatrix = styles.getFmtScheme();
-        if (styleMatrix == null) return null;
+        if (styleMatrix == null) {
+            return null;
+        }
         CTLineStyleList lineStyles = styleMatrix.getLnStyleLst();
-        if (lineStyles == null || lineStyles.sizeOfLnArray() < idx) return null;
+        if (lineStyles == null || lineStyles.sizeOfLnArray() < idx) {
+            return null;
+        }
 
         return lineStyles.getLnArray(idx - 1);
     }
@@ -301,12 +314,14 @@ public abstract class XSLFSimpleShape extends XSLFShape
     protected PaintStyle getLinePaint() {
         XSLFSheet sheet = getSheet();
         final XSLFTheme theme = sheet.getTheme();
+        final boolean hasPlaceholder = getPlaceholder() != null;
         PropertyFetcher<PaintStyle> fetcher = new PropertyFetcher<PaintStyle>() {
+            @Override
             public boolean fetch(XSLFShape shape) {
                 CTLineProperties spPr = getLn(shape, false);
                 XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(spPr);
                 PackagePart pp = shape.getSheet().getPackagePart();
-                PaintStyle paint = selectPaint(fp, null, pp, theme);
+                PaintStyle paint = selectPaint(fp, null, pp, theme, hasPlaceholder);
                 if (paint != null) {
                     setValue(paint);
                     return true;
@@ -315,7 +330,7 @@ public abstract class XSLFSimpleShape extends XSLFShape
                 CTShapeStyle style = shape.getSpStyle();
                 if (style != null) {
                     fp = XSLFPropertiesDelegate.getFillDelegate(style.getLnRef());
-                    paint = selectPaint(fp, null, pp, theme);
+                    paint = selectPaint(fp, null, pp, theme, hasPlaceholder);
                 }
                 if (paint != null) {
                     setValue(paint);
@@ -327,11 +342,15 @@ public abstract class XSLFSimpleShape extends XSLFShape
         fetchShapeProperty(fetcher);
 
         PaintStyle paint = fetcher.getValue();
-        if (paint != null) return paint;
+        if (paint != null) {
+            return paint;
+        }
 
         // line color was not found, check if it is defined in the theme
         CTShapeStyle style = getSpStyle();
-        if (style == null) return null;
+        if (style == null) {
+            return null;
+        }
 
         // get a reference to a line style within the style matrix.
         CTStyleMatrixReference lnRef = style.getLnRef();
@@ -341,7 +360,7 @@ public abstract class XSLFSimpleShape extends XSLFShape
             CTLineProperties props = theme.getXmlObject().getThemeElements().getFmtScheme().getLnStyleLst().getLnArray(idx - 1);
             XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(props);
             PackagePart pp = sheet.getPackagePart();
-            paint = selectPaint(fp, phClr, pp, theme);
+            paint = selectPaint(fp, phClr, pp, theme, hasPlaceholder);
         }
 
         return paint;
@@ -387,6 +406,7 @@ public abstract class XSLFSimpleShape extends XSLFShape
      */
     public double getLineWidth() {
         PropertyFetcher<Double> fetcher = new PropertyFetcher<Double>() {
+            @Override
             public boolean fetch(XSLFShape shape) {
                 CTLineProperties ln = getLn(shape, false);
                 if (ln != null) {
@@ -409,7 +429,9 @@ public abstract class XSLFSimpleShape extends XSLFShape
         if (fetcher.getValue() == null) {
             CTLineProperties defaultLn = getDefaultLineProperties();
             if (defaultLn != null) {
-                if (defaultLn.isSetW()) lineWidth = Units.toPoints(defaultLn.getW());
+                if (defaultLn.isSetW()) {
+                    lineWidth = Units.toPoints(defaultLn.getW());
+                }
             }
         } else {
             lineWidth = fetcher.getValue();
@@ -460,6 +482,7 @@ public abstract class XSLFSimpleShape extends XSLFShape
      */
     public LineCompound getLineCompound() {
         PropertyFetcher<Integer> fetcher = new PropertyFetcher<Integer>() {
+            @Override
             public boolean fetch(XSLFShape shape) {
                 CTLineProperties ln = getLn(shape, false);
                 if (ln != null) {
@@ -522,6 +545,7 @@ public abstract class XSLFSimpleShape extends XSLFShape
     public LineDash getLineDash() {
 
         PropertyFetcher<LineDash> fetcher = new PropertyFetcher<LineDash>() {
+            @Override
             public boolean fetch(XSLFShape shape) {
                 CTLineProperties ln = getLn(shape, false);
                 if (ln == null || !ln.isSetPrstDash()) {
@@ -569,6 +593,7 @@ public abstract class XSLFSimpleShape extends XSLFShape
      */
     public LineCap getLineCap() {
         PropertyFetcher<LineCap> fetcher = new PropertyFetcher<LineCap>() {
+            @Override
             public boolean fetch(XSLFShape shape) {
                 CTLineProperties ln = getLn(shape, false);
                 if (ln != null && ln.isSetCap()) {
@@ -640,8 +665,10 @@ public abstract class XSLFSimpleShape extends XSLFShape
     /**
      * @return shadow of this shape or null if shadow is disabled
      */
+    @Override
     public XSLFShadow getShadow() {
         PropertyFetcher<CTOuterShadowEffect> fetcher = new PropertyFetcher<CTOuterShadowEffect>() {
+            @Override
             public boolean fetch(XSLFShape shape) {
                 XSLFEffectProperties ep = XSLFPropertiesDelegate.getEffectDelegate(shape.getShapeProperties());
                 if (ep != null && ep.isSetEffectLst()) {
@@ -675,6 +702,7 @@ public abstract class XSLFSimpleShape extends XSLFShape
      *
      * @return definition of the shape geometry
      */
+    @Override
     public CustomGeometry getGeometry() {
         XSLFGeometryProperties gp = XSLFPropertiesDelegate.getGeometryDelegate(getShapeProperties());
         
@@ -949,6 +977,7 @@ public abstract class XSLFSimpleShape extends XSLFShape
         return ph != null;
     }
 
+    @Override
     public Guide getAdjustValue(String name) {
         XSLFGeometryProperties gp = XSLFPropertiesDelegate.getGeometryDelegate(getShapeProperties());
         
@@ -963,28 +992,35 @@ public abstract class XSLFSimpleShape extends XSLFShape
         return null;
     }
 
+    @Override
     public LineDecoration getLineDecoration() {
         return new LineDecoration() {
+            @Override
             public DecorationShape getHeadShape() {
                 return getLineHeadDecoration();
             }
 
+            @Override
             public DecorationSize getHeadWidth() {
                 return getLineHeadWidth();
             }
 
+            @Override
             public DecorationSize getHeadLength() {
                 return getLineHeadLength();
             }
 
+            @Override
             public DecorationShape getTailShape() {
                 return getLineTailDecoration();
             }
 
+            @Override
             public DecorationSize getTailWidth() {
                 return getLineTailWidth();
             }
 
+            @Override
             public DecorationSize getTailLength() {
                 return getLineTailLength();
             }
@@ -996,32 +1032,40 @@ public abstract class XSLFSimpleShape extends XSLFShape
      *
      * @return either Color or GradientPaint or TexturePaint or null
      */
+    @Override
     public FillStyle getFillStyle() {
         return new FillStyle() {
+            @Override
             public PaintStyle getPaint() {
                 return XSLFSimpleShape.this.getFillPaint();
             }
         };
     }
 
+    @Override
     public StrokeStyle getStrokeStyle() {
         return new StrokeStyle() {
+            @Override
             public PaintStyle getPaint() {
                 return XSLFSimpleShape.this.getLinePaint();
             }
 
+            @Override
             public LineCap getLineCap() {
                 return XSLFSimpleShape.this.getLineCap();
             }
 
+            @Override
             public LineDash getLineDash() {
                 return XSLFSimpleShape.this.getLineDash();
             }
 
+            @Override
             public double getLineWidth() {
                 return XSLFSimpleShape.this.getLineWidth();
             }
 
+            @Override
             public LineCompound getLineCompound() {
                 return XSLFSimpleShape.this.getLineCompound();
             }
index 140921aa3366d28d6afcf667a8fe24ae9c4b4034..dcd96426170c7779f1ca5e35a70f5431364431c0 100644 (file)
@@ -207,7 +207,7 @@ implements Slide<XSLFShape,XSLFTextParagraph> {
 
     @Override
     public boolean getFollowMasterGraphics(){
-        return _slide.isSetShowMasterSp() && _slide.getShowMasterSp();
+        return _slide.getShowMasterSp();
     }
 
     /**
@@ -306,4 +306,9 @@ implements Slide<XSLFShape,XSLFTextParagraph> {
         Drawable draw = drawFact.getDrawable(this);
         draw.draw(graphics);
     }
+
+    @Override
+    public boolean getDisplayPlaceholder(Placeholder placeholder) {
+        return false;
+    }
 }
index 704d09ea9422e1dacbc490c7420a476e12610c18..b4e53f4feb46e29874408489585cfc4a42856fff 100644 (file)
@@ -104,7 +104,7 @@ implements MasterSheet<XSLFShape,XSLFTextParagraph> {
 
     @Override
     public boolean getFollowMasterGraphics() {
-        return _layout.isSetShowMasterSp() && _layout.getShowMasterSp();
+        return _layout.getShowMasterSp();
     }
 
     /**
index 7b13e5842a252ce629ed99cfffcc58f7480c5b9b..7c7cceac51e812aa5b1a8044adb89a39084d3946 100644 (file)
@@ -145,7 +145,9 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
         }\r
 \r
         CTTableCellProperties pr = getCellProperties(create);\r
-        if (pr == null) return null;\r
+        if (pr == null) {\r
+            return null;\r
+        }\r
 \r
         switch (edge) {\r
             case bottom:\r
@@ -164,7 +166,9 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
     @Override\r
     public void removeBorder(BorderEdge edge) {\r
         CTTableCellProperties pr = getCellProperties(false);\r
-        if (pr == null) return;\r
+        if (pr == null) {\r
+            return;\r
+        }\r
         switch (edge) {\r
             case bottom:\r
                 if (pr.isSetLnB()) {\r
@@ -195,22 +199,27 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
     public StrokeStyle getBorderStyle(final BorderEdge edge) {\r
         final Double width = getBorderWidth(edge);\r
         return (width == null) ? null : new StrokeStyle() {\r
+            @Override\r
             public PaintStyle getPaint() {\r
                 return DrawPaint.createSolidPaint(getBorderColor(edge));\r
             }\r
 \r
+            @Override\r
             public LineCap getLineCap() {\r
                 return getBorderCap(edge);\r
             }\r
 \r
+            @Override\r
             public LineDash getLineDash() {\r
                 return getBorderDash(edge);\r
             }\r
 \r
+            @Override\r
             public LineCompound getLineCompound() {\r
                 return getBorderCompound(edge);\r
             }\r
 \r
+            @Override\r
             public double getLineWidth() {\r
                 return width;\r
             }\r
@@ -306,7 +315,9 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
 \r
     public Color getBorderColor(BorderEdge edge) {\r
         CTLineProperties ln = getCTLine(edge, false);\r
-        if (ln == null || ln.isSetNoFill() || !ln.isSetSolidFill()) return null;\r
+        if (ln == null || ln.isSetNoFill() || !ln.isSetSolidFill()) {\r
+            return null;\r
+        }\r
 \r
         CTSolidColorFillProperties fill = ln.getSolidFill();\r
         XSLFColor c = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr());\r
@@ -381,7 +392,9 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
     public void setFillColor(Color color) {\r
         CTTableCellProperties spPr = getCellProperties(true);\r
         if (color == null) {\r
-            if(spPr.isSetSolidFill()) spPr.unsetSolidFill();\r
+            if(spPr.isSetSolidFill()) {\r
+                spPr.unsetSolidFill();\r
+            }\r
         } else {\r
             CTSolidColorFillProperties fill = spPr.isSetSolidFill() ? spPr.getSolidFill() : spPr.addNewSolidFill();\r
             XSLFColor c = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr());\r
@@ -409,10 +422,11 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
     public PaintStyle getFillPaint() {\r
         XSLFSheet sheet = getSheet();\r
         XSLFTheme theme = sheet.getTheme();\r
+        final boolean hasPlaceholder = getPlaceholder() != null;\r
         XmlObject props = getCellProperties(false);\r
         XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(props);\r
         if (fp != null) {\r
-            PaintStyle paint = selectPaint(fp, null, sheet.getPackagePart(), theme);\r
+            PaintStyle paint = selectPaint(fp, null, sheet.getPackagePart(), theme, hasPlaceholder);\r
             if (paint != null) {\r
                 return paint;\r
             }\r
@@ -438,7 +452,7 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
         \r
         fp = XSLFPropertiesDelegate.getFillDelegate(props);\r
         if (fp != null)  {\r
-            PaintStyle paint = XSLFShape.selectPaint(fp, null, slideShow.getPackagePart(), theme);\r
+            PaintStyle paint = XSLFShape.selectPaint(fp, null, slideShow.getPackagePart(), theme, hasPlaceholder);\r
             if (paint != null) {\r
                 return paint;\r
             }\r
index 38c298275b1576ab69b1f7c4d9dcb1e79e4e76eb..0944d542ee1695545ddbd7902491e58cdd027163 100644 (file)
@@ -72,23 +72,20 @@ public class XSLFTextParagraph implements TextParagraph<XSLFShape,XSLFTextParagr
         _runs = new ArrayList<XSLFTextRun>();
         _shape = shape;
 
-        for(XmlObject ch : _p.selectPath("*")){
-            if(ch instanceof CTRegularTextRun){
-                CTRegularTextRun r = (CTRegularTextRun)ch;
-                _runs.add(newTextRun(r));
-            } else if (ch instanceof CTTextLineBreak){
-                CTTextLineBreak br = (CTTextLineBreak)ch;
-                CTRegularTextRun r = CTRegularTextRun.Factory.newInstance();
-                r.setRPr(br.getRPr());
-                r.setT("\n");
-                _runs.add(newTextRun(r));
-            } else if (ch instanceof CTTextField){
-                CTTextField f = (CTTextField)ch;
-                CTRegularTextRun r = CTRegularTextRun.Factory.newInstance();
-                r.setRPr(f.getRPr());
-                r.setT(f.getT());
-                _runs.add(newTextRun(r));
+        XmlCursor c = _p.newCursor();
+        try {
+            if (c.toFirstChild()) {
+                do {
+                    XmlObject r = c.getObject();
+                    if (r instanceof CTTextLineBreak) {
+                        _runs.add(new XSLFLineBreak((CTTextLineBreak)r, this));
+                    } else if (r instanceof CTRegularTextRun || r instanceof CTTextField) {
+                        _runs.add(new XSLFTextRun(r, this));
+                    }
+                } while (c.toNextSibling());
             }
+        } finally {
+            c.dispose();
         }
     }
 
@@ -147,17 +144,13 @@ public class XSLFTextParagraph implements TextParagraph<XSLFShape,XSLFTextParagr
      * @return text run representing this line break ('\n')
      */
     public XSLFTextRun addLineBreak(){
-        CTTextLineBreak br = _p.addNewBr();
-        CTTextCharacterProperties brProps = br.addNewRPr();
+        XSLFLineBreak run = new XSLFLineBreak(_p.addNewBr(), this);
+        CTTextCharacterProperties brProps = run.getRPr(true);
         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(true);
             brProps.set(prevRun);
         }
-        CTRegularTextRun r = CTRegularTextRun.Factory.newInstance();
-        r.setRPr(brProps);
-        r.setT("\n");
-        XSLFTextRun run = new XSLFLineBreak(r, this, brProps);
         _runs.add(run);
         return run;
     }
index b0bbd4557036afc9d7736e4899ff2e077cac5b97..7bf2a6c6effd21b6141f2102257c21b7a44bcfdd 100644 (file)
@@ -18,6 +18,7 @@ package org.apache.poi.xslf.usermodel;
 \r
 import java.awt.Color;\r
 \r
+import org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException;\r
 import org.apache.poi.openxml4j.opc.PackagePart;\r
 import org.apache.poi.sl.draw.DrawPaint;\r
 import org.apache.poi.sl.usermodel.PaintStyle;\r
@@ -26,13 +27,16 @@ import org.apache.poi.sl.usermodel.TextRun;
 import org.apache.poi.util.Beta;\r
 import org.apache.poi.xslf.model.CharacterPropertyFetcher;\r
 import org.apache.poi.xslf.usermodel.XSLFPropertiesDelegate.XSLFFillProperties;\r
+import org.apache.xmlbeans.XmlObject;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.CTHyperlink;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeStyle;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextField;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTextFont;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextLineBreak;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTextNormalAutofit;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.STTextStrikeType;\r
@@ -45,12 +49,15 @@ import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
  */\r
 @Beta\r
 public class XSLFTextRun implements TextRun {\r
-    private final CTRegularTextRun _r;\r
+    private final XmlObject _r;\r
     private final XSLFTextParagraph _p;\r
 \r
-    protected XSLFTextRun(CTRegularTextRun r, XSLFTextParagraph p){\r
+    protected XSLFTextRun(XmlObject r, XSLFTextParagraph p){\r
         _r = r;\r
         _p = p;\r
+        if (!(r instanceof CTRegularTextRun || r instanceof CTTextLineBreak || r instanceof CTTextField)) {\r
+            throw new OpenXML4JRuntimeException("unsupported text run of type "+r.getClass());\r
+        }\r
     }\r
 \r
     XSLFTextParagraph getParentParagraph(){\r
@@ -58,11 +65,28 @@ public class XSLFTextRun implements TextRun {
     }\r
 \r
     public String getRawText(){\r
-        return _r.getT();\r
+        if (_r instanceof CTTextField) {\r
+            return ((CTTextField)_r).getT();\r
+        } else if (_r instanceof CTTextLineBreak) {\r
+            return "\n";\r
+        }\r
+        return ((CTRegularTextRun)_r).getT();\r
     }\r
 \r
     String getRenderableText(){\r
-        String txt = _r.getT();\r
+        if (_r instanceof CTTextField) {\r
+            CTTextField tf = (CTTextField)_r;\r
+            XSLFSheet sheet = _p.getParentShape().getSheet();\r
+            if ("slidenum".equals(tf.getType()) && sheet instanceof XSLFSlide) {\r
+                return Integer.toString(((XSLFSlide)sheet).getSlideNumber());\r
+            }\r
+            return tf.getT();\r
+        } else if (_r instanceof CTTextLineBreak) {\r
+            return "\n";\r
+        }\r
+        \r
+        \r
+        String txt = ((CTRegularTextRun)_r).getT();\r
         TextCap cap = getTextCap();\r
         StringBuffer buf = new StringBuffer();\r
         for(int i = 0; i < txt.length(); i++) {\r
@@ -88,10 +112,24 @@ public class XSLFTextRun implements TextRun {
     }\r
 \r
     public void setText(String text){\r
-        _r.setT(text);\r
+        if (_r instanceof CTTextField) {\r
+            ((CTTextField)_r).setT(text);\r
+        } else if (_r instanceof CTTextLineBreak) {\r
+            // ignored\r
+            return;\r
+        } else {\r
+            ((CTRegularTextRun)_r).setT(text);\r
+        }\r
     }\r
 \r
-    public CTRegularTextRun getXmlObject(){\r
+    /**\r
+     * Return the text run xmlbeans object.\r
+     * Depending on the type of text run, this can be {@link CTTextField},\r
+     * {@link CTTextLineBreak} or usually a {@link CTRegularTextRun}\r
+     *\r
+     * @return the xmlbeans object\r
+     */\r
+    public XmlObject getXmlObject(){\r
         return _r;\r
     }\r
 \r
@@ -117,6 +155,7 @@ public class XSLFTextRun implements TextRun {
 \r
     @Override\r
     public PaintStyle getFontColor(){\r
+        final boolean hasPlaceholder = getParentParagraph().getParentShape().getPlaceholder() != null;\r
         CharacterPropertyFetcher<PaintStyle> fetcher = new CharacterPropertyFetcher<PaintStyle>(_p.getIndentLevel()){\r
             public boolean fetch(CTTextCharacterProperties props){\r
                 if (props == null) {\r
@@ -134,7 +173,7 @@ public class XSLFTextRun implements TextRun {
                 XSLFSheet sheet = shape.getSheet();\r
                 PackagePart pp = sheet.getPackagePart();\r
                 XSLFTheme theme = sheet.getTheme();\r
-                PaintStyle ps = XSLFShape.selectPaint(fp, phClr, pp, theme);\r
+                PaintStyle ps = XSLFShape.selectPaint(fp, phClr, pp, theme, hasPlaceholder);\r
                 \r
                 if (ps != null)  {\r
                     setValue(ps);\r
@@ -459,13 +498,29 @@ public class XSLFTextRun implements TextRun {
      * @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
+        if (_r instanceof CTTextField) {\r
+            CTTextField tf = (CTTextField)_r;\r
+            if (tf.isSetRPr()) {\r
+                return tf.getRPr();\r
+            } else if (create) {\r
+                return tf.addNewRPr();\r
+            }\r
+        } else if (_r instanceof CTTextLineBreak) {\r
+            CTTextLineBreak tlb = (CTTextLineBreak)_r;\r
+            if (tlb.isSetRPr()) {\r
+                return tlb.getRPr();\r
+            } else if (create) {\r
+                return tlb.addNewRPr();\r
+            }\r
         } else {\r
-            return null;\r
+            CTRegularTextRun tr = (CTRegularTextRun)_r;\r
+            if (tr.isSetRPr()) {\r
+                return tr.getRPr();\r
+            } else if (create) {\r
+                return tr.addNewRPr();\r
+            }\r
         }\r
+        return null;\r
     }\r
 \r
     @Override\r
@@ -476,15 +531,17 @@ public class XSLFTextRun implements TextRun {
     @Override\r
     public XSLFHyperlink createHyperlink(){\r
         XSLFHyperlink hl = getHyperlink();\r
-        if (hl == null) {\r
-            hl = new XSLFHyperlink(_r.getRPr().addNewHlinkClick(), _p.getParentShape().getSheet());\r
+        if (hl != null) {\r
+            return hl;\r
         }\r
-        return hl;\r
+\r
+        CTTextCharacterProperties rPr = getRPr(true);\r
+        return new XSLFHyperlink(rPr.addNewHlinkClick(), _p.getParentShape().getSheet());\r
     }\r
 \r
     @Override\r
     public XSLFHyperlink getHyperlink(){\r
-        CTTextCharacterProperties rPr = _r.getRPr();\r
+        CTTextCharacterProperties rPr = getRPr(false);\r
         if (rPr == null) { \r
             return null;\r
         }\r
@@ -498,33 +555,33 @@ public class XSLFTextRun implements TextRun {
     private boolean fetchCharacterProperty(CharacterPropertyFetcher<?> fetcher){\r
         XSLFTextShape shape = _p.getParentShape();\r
         XSLFSheet sheet = shape.getSheet();\r
-        boolean ok = false;\r
 \r
-        if (_r.isSetRPr()) ok = fetcher.fetch(getRPr(false));\r
-        if (ok) return true;\r
+        CTTextCharacterProperties rPr = getRPr(false);\r
+        if (rPr != null && fetcher.fetch(rPr)) {\r
+            return true;\r
+        }\r
         \r
-        ok = shape.fetchShapeProperty(fetcher);\r
-        if (ok) return true;\r
+        if (shape.fetchShapeProperty(fetcher)) {\r
+            return true;\r
+        }\r
         \r
         CTPlaceholder ph = shape.getCTPlaceholder();\r
         if (ph == null){\r
             // if it is a plain text box then take defaults from presentation.xml\r
             @SuppressWarnings("resource")\r
             XMLSlideShow ppt = sheet.getSlideShow();\r
+            // TODO: determine master shape\r
             CTTextParagraphProperties themeProps = ppt.getDefaultParagraphStyle(_p.getIndentLevel());\r
-            if (themeProps != null) {\r
-                // TODO: determine master shape\r
-                ok = fetcher.fetch(themeProps);\r
+            if (themeProps != null && fetcher.fetch(themeProps)) {\r
+                return true;\r
             }\r
         }\r
-        if (ok) return true;\r
 \r
+        // TODO: determine master shape\r
         CTTextParagraphProperties defaultProps =  _p.getDefaultMasterStyle();\r
-        if(defaultProps != null) {\r
-            // TODO: determine master shape\r
-            ok = fetcher.fetch(defaultProps);\r
+        if(defaultProps != null && fetcher.fetch(defaultProps)) {\r
+            return true;\r
         }\r
-        if (ok) return true;\r
 \r
         return false;\r
     }\r
@@ -557,4 +614,16 @@ public class XSLFTextRun implements TextRun {
         boolean strike = r.isStrikethrough();\r
         if(strike != isStrikethrough()) setStrikethrough(strike);\r
     }\r
+    \r
+    \r
+    @Override\r
+    public FieldType getFieldType() {\r
+        if (_r instanceof CTTextField) {\r
+            CTTextField tf = (CTTextField)_r;\r
+            if ("slidenum".equals(tf.getType())) {\r
+                return FieldType.SLIDE_NUMBER;\r
+            }\r
+        }\r
+        return null;\r
+    }\r
 }\r
index 809f745c42bc110ccd383580f2390860d325b824..d3bd3a847c6bd26a1c97903c872d90f521c63f8f 100644 (file)
@@ -169,5 +169,4 @@ public class XSLFTheme extends POIXMLDocumentPart {
         }
         return null;
     }
-
 }
index 95dd57d15489b34ca1e26cb4ccd1092d1472f1b7..31b116f9498b000329b3b5b1bdc08996bba74f25 100644 (file)
@@ -108,7 +108,8 @@ public class TestXSLFSlideShow {
                // And again for the master
                CTSlideMasterIdListEntry[] masters = xml.getSlideMasterReferences().getSldMasterIdArray();
                
-               assertEquals(2147483648l, masters[0].getId());
+               // see SlideAtom.USES_MASTER_SLIDE_ID
+               assertEquals(0x80000000L, masters[0].getId());
                assertEquals("rId1", masters[0].getId2());
                assertNotNull(xml.getSlideMaster(masters[0]));
                
index 0e58d410c3218a7a25b227b9448c203a887730d6..3ef1988b287f8f8b93766816ac057112198821a4 100644 (file)
@@ -105,7 +105,8 @@ public class TestXMLSlideShow extends BaseTestSlideShow {
       // Next up look for the slide master
       CTSlideMasterIdListEntry[] masters = xml.getCTPresentation().getSldMasterIdLst().getSldMasterIdArray();
 
-      assertEquals(2147483648l, masters[0].getId());
+      // see SlideAtom.USES_MASTER_SLIDE_ID
+      assertEquals(0x80000000L, masters[0].getId());
       assertEquals("rId1", masters[0].getId2());
       assertNotNull(xml.getSlideMasters().get(0));
 
index 798dc472aa93345d363f1d9039228ebe3a3784aa..3104cbb6776c42c9b3367ea6f18a34c79b5f8a67 100644 (file)
 ==================================================================== */\r
 package org.apache.poi.xslf.usermodel;\r
 \r
-import static org.junit.Assert.*;\r
+import static org.junit.Assert.assertEquals;\r
+import static org.junit.Assert.assertFalse;\r
+import static org.junit.Assert.assertNotNull;\r
+import static org.junit.Assert.assertNull;\r
+import static org.junit.Assert.assertSame;\r
+import static org.junit.Assert.assertTrue;\r
 \r
 import java.io.IOException;\r
 \r
-import org.apache.poi.sl.usermodel.*;\r
+import org.apache.poi.sl.usermodel.ShapeType;\r
 import org.apache.poi.sl.usermodel.TextParagraph.TextAlign;\r
 import org.apache.poi.sl.usermodel.TextShape.TextAutofit;\r
 import org.apache.poi.sl.usermodel.TextShape.TextDirection;\r
+import org.apache.poi.sl.usermodel.VerticalAlignment;\r
 import org.apache.poi.util.Units;\r
 import org.junit.Test;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.STTextStrikeType;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.STTextUnderlineType;\r
 \r
-/**\r
- * @author Yegor Kozlov\r
- */\r
 public class TestXSLFAutoShape {\r
     @Test\r
     public void testTextBodyProperies() throws IOException {\r
@@ -222,56 +226,58 @@ public class TestXSLFAutoShape {
         assertEquals(1, shape.getTextParagraphs().size());\r
         assertEquals(0, p.getTextRuns().size());\r
         XSLFTextRun r = p.addNewTextRun();\r
+        CTTextCharacterProperties rPr = r.getRPr(false);\r
+        assertNotNull(rPr);\r
         assertEquals(1, p.getTextRuns().size());\r
         assertSame(r, p.getTextRuns().get(0));\r
 \r
+        \r
         assertEquals(18.0, r.getFontSize(), 0); // default font size for text boxes\r
-        assertFalse(r.getXmlObject().getRPr().isSetSz());\r
+        assertFalse(rPr.isSetSz());\r
         r.setFontSize(10.0);\r
-        assertTrue(r.getXmlObject().isSetRPr());\r
-        assertEquals(1000, r.getXmlObject().getRPr().getSz());\r
+        assertEquals(1000, rPr.getSz());\r
         r.setFontSize(12.5);\r
-        assertEquals(1250, r.getXmlObject().getRPr().getSz());\r
+        assertEquals(1250, rPr.getSz());\r
         r.setFontSize(null);\r
-        assertFalse(r.getXmlObject().getRPr().isSetSz());\r
+        assertFalse(rPr.isSetSz());\r
 \r
-        assertFalse(r.getXmlObject().getRPr().isSetLatin());\r
+        assertFalse(rPr.isSetLatin());\r
         assertEquals("Calibri", r.getFontFamily()); // comes from the slide master\r
         r.setFontFamily(null);\r
         assertEquals("Calibri", r.getFontFamily()); // comes from the slide master\r
         r.setFontFamily("Arial");\r
         assertEquals("Arial", r.getFontFamily());\r
-        assertEquals("Arial", r.getXmlObject().getRPr().getLatin().getTypeface());\r
+        assertEquals("Arial", rPr.getLatin().getTypeface());\r
         r.setFontFamily("Symbol");\r
         assertEquals("Symbol", r.getFontFamily());\r
-        assertEquals("Symbol", r.getXmlObject().getRPr().getLatin().getTypeface());\r
+        assertEquals("Symbol", rPr.getLatin().getTypeface());\r
         r.setFontFamily(null);\r
         assertEquals("Calibri", r.getFontFamily()); // comes from the slide master\r
-        assertFalse(r.getXmlObject().getRPr().isSetLatin());\r
+        assertFalse(rPr.isSetLatin());\r
 \r
         assertFalse(r.isStrikethrough());\r
-        assertFalse(r.getXmlObject().getRPr().isSetStrike());\r
+        assertFalse(rPr.isSetStrike());\r
         r.setStrikethrough(true);\r
         assertTrue(r.isStrikethrough());\r
-        assertEquals(STTextStrikeType.SNG_STRIKE, r.getXmlObject().getRPr().getStrike());\r
+        assertEquals(STTextStrikeType.SNG_STRIKE, rPr.getStrike());\r
 \r
         assertFalse(r.isBold());\r
-        assertFalse(r.getXmlObject().getRPr().isSetB());\r
+        assertFalse(rPr.isSetB());\r
         r.setBold(true);\r
         assertTrue(r.isBold());\r
-        assertEquals(true, r.getXmlObject().getRPr().getB());\r
+        assertEquals(true, rPr.getB());\r
 \r
         assertFalse(r.isItalic());\r
-        assertFalse(r.getXmlObject().getRPr().isSetI());\r
+        assertFalse(rPr.isSetI());\r
         r.setItalic(true);\r
         assertTrue(r.isItalic());\r
-        assertEquals(true, r.getXmlObject().getRPr().getI());\r
+        assertEquals(true, rPr.getI());\r
 \r
         assertFalse(r.isUnderlined());\r
-        assertFalse(r.getXmlObject().getRPr().isSetU());\r
+        assertFalse(rPr.isSetU());\r
         r.setUnderlined(true);\r
         assertTrue(r.isUnderlined());\r
-        assertEquals(STTextUnderlineType.SNG, r.getXmlObject().getRPr().getU());\r
+        assertEquals(STTextUnderlineType.SNG, rPr.getU());\r
 \r
         r.setText("Apache");\r
         assertEquals("Apache", r.getRawText());\r
index 0ff02d0853c04acea06a933044075627ba0a5dd9..a705bfbbe22f7e2d49ad0f287146f8653d329e4b 100644 (file)
@@ -123,10 +123,11 @@ public class TestXSLFHyperlink {
         XSLFTextBox tb3 = sl3.createTextBox();\r
         tb3.setAnchor(anchor);\r
         tb3.setText("text1 ");\r
-        XSLFTextRun r3 = tb3.appendText("lin\u000bk", false);\r
+        tb3.appendText("lin\u000bk", false);\r
         tb3.appendText(" text2", false);\r
-        XSLFHyperlink hl3 = r3.createHyperlink();\r
-        hl3.linkToSlide(slide1);\r
+        List<XSLFTextRun> tb3runs = tb3.getTextParagraphs().get(0).getTextRuns();\r
+        tb3runs.get(1).createHyperlink().linkToSlide(slide1); // "lin"\r
+        tb3runs.get(3).createHyperlink().linkToSlide(slide1); // "k"\r
         XSLFTextBox tb4 = ppt1.createSlide().createTextBox();\r
         tb4.setAnchor(anchor);\r
         XSLFTextRun r4 = tb4.setText("page4");\r
@@ -155,6 +156,8 @@ public class TestXSLFHyperlink {
         assertEquals(HyperlinkType.DOCUMENT, hl2.getTypeEnum());\r
 \r
         tb3 = (XSLFTextBox)slides.get(2).getShapes().get(0);\r
+        XSLFHyperlink hl3 = tb3.getTextParagraphs().get(0).getTextRuns().get(1).getHyperlink();\r
+        assertNotNull(hl3);\r
         hl3 = tb3.getTextParagraphs().get(0).getTextRuns().get(3).getHyperlink();\r
         assertNotNull(hl3);\r
         assertEquals("/ppt/slides/slide1.xml", hl3.getAddress());\r
index fa561178936229a52e0fdf7b5648d31daf7f0fa3..403ccb67909444861bcfb139d8c18a187c6bedb8 100644 (file)
 ==================================================================== */\r
 package org.apache.poi.xslf.usermodel;\r
 \r
-import static org.junit.Assert.*;\r
+import static org.junit.Assert.assertEquals;\r
+import static org.junit.Assert.assertSame;\r
+import static org.junit.Assert.assertTrue;\r
+\r
+import java.io.IOException;\r
+import java.util.List;\r
 \r
 import org.apache.poi.xslf.XSLFTestDataSamples;\r
 import org.junit.Test;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.STTextUnderlineType;\r
 \r
-import java.io.IOException;\r
-import java.util.List;\r
-\r
-/**\r
- * @author Yegor Kozlov\r
- */\r
 public class TestXSLFShape {\r
 \r
     @Test\r
@@ -63,7 +62,7 @@ public class TestXSLFShape {
         assertEquals("PPTX ", r2.get(0).getRawText());\r
         assertEquals("Title", r2.get(1).getRawText());\r
         // Title is underlined\r
-        assertEquals(STTextUnderlineType.SNG, r2.get(1).getXmlObject().getRPr().getU());\r
+        assertEquals(STTextUnderlineType.SNG, r2.get(1).getRPr(false).getU());\r
 \r
 \r
         assertTrue(shapes2.get(1) instanceof XSLFAutoShape);\r
@@ -78,7 +77,7 @@ public class TestXSLFShape {
         assertEquals(1, paragraphs2.get(1).getTextRuns().size());\r
 \r
         assertEquals("Subtitle", paragraphs2.get(0).getTextRuns().get(0).getRawText());\r
-        assertTrue(paragraphs2.get(0).getTextRuns().get(0).getXmlObject().getRPr().getB());\r
+        assertTrue(paragraphs2.get(0).getTextRuns().get(0).getRPr(false).getB());\r
         assertEquals("And second line", paragraphs2.get(1).getTextRuns().get(0).getRawText());\r
         \r
         ppt.close();\r
index 0af1347abaa18b5380bb9030d35c47704fc5d873..fad3f82a005374a105ebf640e702c2e198bfe16e 100644 (file)
@@ -111,7 +111,7 @@ public class TestXSLFSlide {
         assertEquals(0, ppt.getSlides().size());\r
 \r
         XSLFSlide slide = ppt.createSlide();\r
-        assertFalse(slide.getFollowMasterGraphics());\r
+        assertTrue(slide.getFollowMasterGraphics());\r
         slide.setFollowMasterGraphics(false);\r
         assertFalse(slide.getFollowMasterGraphics());\r
         slide.setFollowMasterGraphics(true);\r
index 771fd9d915101cd149c647014afd989aa2f26ff3..13024e6fdb62701f86a74a373d680c2c75756bfe 100644 (file)
@@ -714,7 +714,7 @@ public class TestXSLFTextShape {
 \r
         // level 5: text properties are defined in the text run\r
         CTTextParagraphProperties lv5PPr = paragraph.getXmlObject().addNewPPr();\r
-        CTTextCharacterProperties lv5CPr = textRun.getXmlObject().getRPr();\r
+        CTTextCharacterProperties lv5CPr = textRun.getRPr(false);\r
         lv5CPr.setSz(3600);\r
         assertEquals(36.0, textRun.getFontSize(), 0);\r
         lv5CPr.addNewLatin().setTypeface("Calibri");\r
@@ -899,11 +899,11 @@ public class TestXSLFTextShape {
 \r
         // level 5: text properties are defined in the text run\r
         lv1PPr = p1.getXmlObject().isSetPPr() ? p1.getXmlObject().getPPr() : p1.getXmlObject().addNewPPr();\r
-        lv1CPr = r1.getXmlObject().getRPr();\r
+        lv1CPr = r1.getRPr(false);\r
         lv2PPr = p2.getXmlObject().isSetPPr() ? p2.getXmlObject().getPPr() : p2.getXmlObject().addNewPPr();\r
-        lv2CPr = r2.getXmlObject().getRPr();\r
+        lv2CPr = r2.getRPr(false);\r
         lv3PPr = p3.getXmlObject().isSetPPr() ? p3.getXmlObject().getPPr() : p3.getXmlObject().addNewPPr();\r
-        lv3CPr = r3.getXmlObject().getRPr();\r
+        lv3CPr = r3.getRPr(false);\r
 \r
         lv1CPr.setSz(3600);\r
         assertEquals(36.0, r1.getFontSize(), 0);\r
index 912ecc0f3dd7cfabbc8dd9b4fd5f20f95e30dda8..a181e4f8ff5694b7b0f87a492823e4a76a455cff 100644 (file)
 package org.apache.poi.xslf.usermodel;\r
 \r
 import static org.apache.poi.sl.TestCommonSL.sameColor;\r
-import static org.junit.Assert.*;\r
+import static org.junit.Assert.assertEquals;\r
+import static org.junit.Assert.assertFalse;\r
+import static org.junit.Assert.assertNull;\r
+import static org.junit.Assert.assertTrue;\r
 \r
 import java.awt.Color;\r
 import java.util.List;\r
 \r
-import org.apache.poi.sl.usermodel.*;\r
+import org.apache.poi.sl.usermodel.PaintStyle;\r
 import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint;\r
 import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;\r
 import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint;\r
@@ -54,7 +57,9 @@ public class TestXSLFTheme {
 \r
     private XSLFShape getShape(XSLFSheet sheet, String name){\r
         for(XSLFShape sh : sheet.getShapes()){\r
-            if(sh.getShapeName().equals(name)) return sh;\r
+            if(sh.getShapeName().equals(name)) {\r
+                return sh;\r
+            }\r
         }\r
         throw new IllegalArgumentException("Shape not found: " + name);\r
     }\r
@@ -99,7 +104,7 @@ public class TestXSLFTheme {
         assertTrue(sameColor(new Color(148, 198, 0), run2.getFontColor()));\r
         assertNull(sh2.getFillColor());  // no fill\r
 \r
-        assertFalse(slide.getSlideLayout().getFollowMasterGraphics());\r
+        assertTrue(slide.getSlideLayout().getFollowMasterGraphics());\r
     }\r
 \r
     void slide5(XSLFSlide slide){\r
@@ -113,7 +118,7 @@ public class TestXSLFTheme {
         // font size is 40pt and scale factor is 90%\r
         assertEquals(36.0, run2.getFontSize(), 0);\r
 \r
-        assertFalse(slide.getSlideLayout().getFollowMasterGraphics());\r
+        assertTrue(slide.getSlideLayout().getFollowMasterGraphics());\r
     }\r
 \r
     void slide6(XSLFSlide slide){\r
index 9bfa5f3254747f7dd43ec0bd0141227154f8e417..ab96c7dbe6e3480a22e39c038a05a4ae762a63e3 100644 (file)
@@ -21,13 +21,14 @@ import org.apache.poi.hslf.record.CString;
 import org.apache.poi.hslf.record.Document;
 import org.apache.poi.hslf.record.HeadersFootersAtom;
 import org.apache.poi.hslf.record.HeadersFootersContainer;
-import org.apache.poi.hslf.record.OEPlaceholderAtom;
 import org.apache.poi.hslf.record.Record;
 import org.apache.poi.hslf.record.RecordTypes;
 import org.apache.poi.hslf.record.SheetContainer;
 import org.apache.poi.hslf.usermodel.HSLFSheet;
+import org.apache.poi.hslf.usermodel.HSLFSimpleShape;
 import org.apache.poi.hslf.usermodel.HSLFSlideShow;
 import org.apache.poi.hslf.usermodel.HSLFTextShape;
+import org.apache.poi.sl.usermodel.Placeholder;
 
 /**
  * Header / Footer settings.
@@ -87,7 +88,7 @@ public final class HeadersFooters {
      */
     public String getHeaderText(){
         CString cs = _container == null ? null : _container.getHeaderAtom();
-        return getPlaceholderText(OEPlaceholderAtom.MasterHeader, cs);
+        return getPlaceholderText(Placeholder.HEADER, cs);
     }
 
     /**
@@ -112,7 +113,7 @@ public final class HeadersFooters {
      */
     public String getFooterText(){
         CString cs = _container == null ? null : _container.getFooterAtom();
-        return getPlaceholderText(OEPlaceholderAtom.MasterFooter, cs);
+        return getPlaceholderText(Placeholder.FOOTER, cs);
     }
 
     /**
@@ -137,7 +138,7 @@ public final class HeadersFooters {
      */
     public String getDateTimeText(){
         CString cs = _container == null ? null : _container.getUserDateAtom();
-        return getPlaceholderText(OEPlaceholderAtom.MasterDate, cs);
+        return getPlaceholderText(Placeholder.DATETIME, cs);
     }
 
     /**
@@ -160,7 +161,7 @@ public final class HeadersFooters {
      * whether the footer text is displayed.
      */
     public boolean isFooterVisible(){
-        return isVisible(HeadersFootersAtom.fHasFooter, OEPlaceholderAtom.MasterFooter);
+        return isVisible(HeadersFootersAtom.fHasFooter, Placeholder.FOOTER);
     }
 
     /**
@@ -174,7 +175,7 @@ public final class HeadersFooters {
      * whether the header text is displayed.
      */
     public boolean isHeaderVisible(){
-        return isVisible(HeadersFootersAtom.fHasHeader, OEPlaceholderAtom.MasterHeader);
+        return isVisible(HeadersFootersAtom.fHasHeader, Placeholder.HEADER);
     }
 
     /**
@@ -188,7 +189,7 @@ public final class HeadersFooters {
      * whether the date is displayed in the footer.
      */
     public boolean isDateTimeVisible(){
-        return isVisible(HeadersFootersAtom.fHasDate, OEPlaceholderAtom.MasterDate);
+        return isVisible(HeadersFootersAtom.fHasDate, Placeholder.DATETIME);
     }
 
     /**
@@ -202,7 +203,7 @@ public final class HeadersFooters {
      * whether the custom user date is used instead of today's date.
      */
     public boolean isUserDateVisible(){
-        return isVisible(HeadersFootersAtom.fHasUserDate, OEPlaceholderAtom.MasterDate);
+        return isVisible(HeadersFootersAtom.fHasUserDate, Placeholder.DATETIME);
     }
 
     /**
@@ -216,7 +217,7 @@ public final class HeadersFooters {
      * whether the slide number is displayed in the footer.
      */
     public boolean isSlideNumberVisible(){
-        return isVisible(HeadersFootersAtom.fHasSlideNumber, OEPlaceholderAtom.MasterSlideNumber);
+        return isVisible(HeadersFootersAtom.fHasSlideNumber, Placeholder.SLIDE_NUMBER);
     }
 
     /**
@@ -244,31 +245,29 @@ public final class HeadersFooters {
         _container.getHeadersFootersAtom().setFormatId(formatId);
     }
 
-    private boolean isVisible(int flag, int placeholderId){
+    private boolean isVisible(int flag, Placeholder placeholderId){
         boolean visible;
         if(_ppt2007){
-            HSLFTextShape placeholder = _sheet.getPlaceholder(placeholderId);
-            visible = placeholder != null && placeholder.getText() != null;
+            HSLFSimpleShape ss = _sheet.getPlaceholder(placeholderId);
+            visible = ss instanceof HSLFTextShape && ((HSLFTextShape)ss).getText() != null;
         } else {
             visible = _container.getHeadersFootersAtom().getFlag(flag);
         }
         return visible;
     }
 
-    private String getPlaceholderText(int placeholderId, CString cs){
-        String text = null;
+    private String getPlaceholderText(Placeholder ph, CString cs) {
+        String text;
         if (_ppt2007) {
-            HSLFTextShape placeholder = _sheet.getPlaceholder(placeholderId);
-            if (placeholder != null) {
-                text = placeholder.getText();
-            }
+            HSLFSimpleShape ss = _sheet.getPlaceholder(ph);
+            text = (ss instanceof HSLFTextShape) ? ((HSLFTextShape)ss).getText() : null;
 
             // default text in master placeholders is not visible
             if("*".equals(text)) {
                 text = null;
             }
         } else {
-            text = cs == null ? null : cs.getText();
+            text = (cs == null) ? null : cs.getText();
         }
         return text;
     }
index 54d5d8622118213e73868363fcc489e0f9a8d3a0..3bdea4e4b2e5d2de36854eb1ddb26fe67228e8dd 100644 (file)
 
 package org.apache.poi.hslf.record;
 
-import org.apache.poi.util.LittleEndian;
 import java.io.IOException;
 import java.io.OutputStream;
 
+import org.apache.poi.sl.usermodel.Placeholder;
+import org.apache.poi.util.LittleEndian;
+
 /**
- * OEPlaceholderAtom (3011).
- * <p>
- *  An atom record that specifies whether a shape is a placeholder shape.
- * </p>
+ * OEPlaceholderAtom (3011).<p>
+ * 
+ * An atom record that specifies whether a shape is a placeholder shape.
  *
- * @author Yegor Kozlov
+ * @see Placeholder
  */
 
 public final class OEPlaceholderAtom extends RecordAtom{
@@ -47,155 +48,6 @@ public final class OEPlaceholderAtom extends RecordAtom{
      */
     public static final int PLACEHOLDER_QUARTSIZE = 2;
 
-    /**
-     * MUST NOT be used for this field.
-     */
-    public static final byte None = 0;
-
-    /**
-     * The corresponding shape contains the master title text.
-     * The corresponding slide MUST be a main master slide.
-     */
-    public static final byte MasterTitle = 1;
-
-    /**
-     * The corresponding shape contains the master body text.
-     * The corresponding slide MUST be a main master slide.
-     */
-    public static final byte MasterBody = 2;
-
-    /**
-     * The corresponding shape contains the master center title text.
-     * The corresponding slide MUST be a title master slide.
-     */
-    public static final byte MasterCenteredTitle = 3;
-
-    /**
-     * The corresponding shape contains the master sub-title text.
-     * The corresponding slide MUST be a title master slide.
-     */
-    public static final byte MasterSubTitle = 4;
-
-    /**
-     * The corresponding shape contains the shared properties for slide image shapes.
-     * The corresponding slide MUST be a notes master slide.
-     */
-    public static final byte MasterNotesSlideImage = 5;
-
-    /**
-     * The corresponding shape contains the master body text.
-     * The corresponding slide MUST be a notes master slide.
-     */
-    public static final byte MasterNotesBody = 6;
-
-    /**
-     * The corresponding shape contains the date text field.
-     * The corresponding slide MUST be a main master slide, title master slide, notes master slide, or handout master slide.
-     */
-    public static final byte MasterDate = 7;
-
-    /**
-     * The corresponding shape contains a slide number text field.
-     * The corresponding slide MUST be a main master slide, title master slide, notes master slide, or handout master slide.
-     */
-    public static final byte MasterSlideNumber = 8;
-
-    /**
-     * The corresponding shape contains a footer text field.
-     * The corresponding slide MUST be a main master slide, title master slide, notes master slide, or handout master slide.
-     */
-    public static final byte MasterFooter = 9;
-
-    /**
-     * The corresponding shape contains a header text field.
-     * The corresponding slide must be a notes master slide or handout master slide.
-     */
-    public static final byte MasterHeader = 10;
-
-    /**
-     * The corresponding shape contains a presentation slide image.
-     * The corresponding slide MUST be a notes slide.
-     */
-    public static final byte NotesSlideImage = 11;
-
-    /**
-     * The corresponding shape contains the notes text.
-     * The corresponding slide MUST be a notes slide.
-     */
-    public static final byte NotesBody = 12;
-
-    /**
-     *  The corresponding shape contains the title text.
-     *  The corresponding slide MUST be a presentation slide.
-     */
-    public static final byte Title = 13;
-
-    /**
-     * The corresponding shape contains the body text.
-     * The corresponding slide MUST be a presentation slide.
-     */
-    public static final byte Body = 14;
-
-    /**
-     * The corresponding shape contains the title text.
-     * The corresponding slide MUST be a presentation slide.
-     */
-    public static final byte CenteredTitle = 15;
-
-    /**
-     * The corresponding shape contains the sub-title text.
-     * The corresponding slide MUST be a presentation slide.
-     */
-    public static final byte Subtitle = 16;
-
-    /**
-     * The corresponding shape contains the title text with vertical text flow.
-     * The corresponding slide MUST be a presentation slide.
-     */
-    public static final byte VerticalTextTitle = 17;
-
-    /**
-     * The corresponding shape contains the body text with vertical text flow.
-     * The corresponding slide MUST be a presentation slide.
-     */
-    public static final byte VerticalTextBody = 18;
-
-    /**
-     *  The corresponding shape contains a generic object.
-     *  The corresponding slide MUST be a presentation slide.
-     */
-    public static final byte Object = 19;
-
-    /**
-     * The corresponding shape contains a chart object.
-     * The corresponding slide MUST be a presentation slide.
-     */
-    public static final byte Graph = 20;
-
-    /**
-     * The corresponding shape contains a table object.
-     * The corresponding slide MUST be a presentation slide.
-     */
-    public static final byte Table = 21;
-
-    /**
-     * The corresponding shape contains a clipart object.
-     * The corresponding slide MUST be a presentation slide.
-     */
-    public static final byte ClipArt = 22;
-
-    /**
-     * The corresponding shape contains an organization chart object.
-     * The corresponding slide MUST be a presentation slide.
-     */
-    public static final byte OrganizationChart = 23;
-
-    /**
-     * The corresponding shape contains a media object.
-     * The corresponding slide MUST be a presentation slide.
-     */
-    public static final byte MediaClip = 24;
-
        private byte[] _header;
 
     private int placementId;
@@ -205,7 +57,7 @@ public final class OEPlaceholderAtom extends RecordAtom{
 
 
     /**
-     * Create a new instance of <code>OEPlaceholderAtom</code>
+     * Create a new instance of {@code OEPlaceholderAtom}
      */
     public OEPlaceholderAtom(){
         _header = new byte[8];
@@ -219,7 +71,7 @@ public final class OEPlaceholderAtom extends RecordAtom{
     }
 
     /**
-     * Build an instance of <code>OEPlaceholderAtom</code> from on-disk data
+     * Build an instance of {@code OEPlaceholderAtom} from on-disk data
      */
        protected OEPlaceholderAtom(byte[] source, int start, int len) {
                _header = new byte[8];
@@ -236,15 +88,15 @@ public final class OEPlaceholderAtom extends RecordAtom{
     /**
      * @return type of this record {@link RecordTypes#OEPlaceholderAtom}.
      */
-       public long getRecordType() { return RecordTypes.OEPlaceholderAtom.typeID; }
+       @Override
+    public long getRecordType() { return RecordTypes.OEPlaceholderAtom.typeID; }
 
     /**
-     * Returns the placement Id.
-     * <p>
+     * Returns the placement Id.<p>
+     * 
      * The placement Id is a number assigned to the placeholder. It goes from -1 to the number of placeholders.
      * It SHOULD be unique among all PlacholderAtom records contained in the corresponding slide.
      * The value 0xFFFFFFFF specifies that the corresponding shape is not a placeholder shape.
-     * </p>
      *
      * @return the placement Id.
      */
@@ -253,12 +105,11 @@ public final class OEPlaceholderAtom extends RecordAtom{
     }
 
     /**
-     * Sets the placement Id.
-     * <p>
+     * Sets the placement Id.<p>
+     *
      * The placement Id is a number assigned to the placeholder. It goes from -1 to the number of placeholders.
      * It SHOULD be unique among all PlacholderAtom records contained in the corresponding slide.
      * The value 0xFFFFFFFF specifies that the corresponding shape is not a placeholder shape.
-     * </p>
      *
      * @param id the placement Id.
      */
@@ -267,12 +118,10 @@ public final class OEPlaceholderAtom extends RecordAtom{
     }
 
     /**
-     * Returns the placeholder Id.
+     * Returns the placeholder Id.<p>
      *
-     * <p>
      * placeholder Id specifies the type of the placeholder shape.
      * The value MUST be one of the static constants defined in this class
-     * </p>
      *
      * @return the placeholder Id.
      */
@@ -281,12 +130,11 @@ public final class OEPlaceholderAtom extends RecordAtom{
     }
 
     /**
-     * Sets the placeholder Id.
+     * Sets the placeholder Id.<p>
      *
-     * <p>
      * placeholder Id specifies the type of the placeholder shape.
      * The value MUST be one of the static constants defined in this class
-     * </p>
+     *
      * @param id the placeholder Id.
      */
     public void setPlaceholderId(byte id){
@@ -314,10 +162,10 @@ public final class OEPlaceholderAtom extends RecordAtom{
     }
 
        /**
-        * Write the contents of the record back, so it can be written
-        *  to disk
+        * Write the contents of the record back, so it can be written to disk
         */
-       public void writeOut(OutputStream out) throws IOException {
+       @Override
+    public void writeOut(OutputStream out) throws IOException {
                out.write(_header);
 
         byte[] recdata = new byte[8];
index 16be0c6a808d60dcd2957cde4434d584c5cb7d78..9d553740bfc8b64088e4c47127cb7a999b966c99 100644 (file)
@@ -20,23 +20,21 @@ package org.apache.poi.hslf.record;
 import java.io.IOException;
 import java.io.OutputStream;
 
-import org.apache.poi.hslf.exceptions.HSLFException;
+import org.apache.poi.hslf.record.SlideAtomLayout.SlideLayoutType;
 import org.apache.poi.util.LittleEndian;
 
 /**
  * A Slide Atom (type 1007). Holds information on the parent Slide, what
- *  Master Slide it uses, what Notes is attached to it, that sort of thing.
- *  It also has a SSlideLayoutAtom embeded in it, but without the Atom header
- *
- * @author Nick Burch
+ * Master Slide it uses, what Notes is attached to it, that sort of thing.
+ * It also has a SSlideLayoutAtom embedded in it, but without the Atom header
  */
 
-public final class SlideAtom extends RecordAtom
-{
-       private byte[] _header;
+public final class SlideAtom extends RecordAtom {
+    public static final int USES_MASTER_SLIDE_ID  =  0x80000000;
+    // private static final int MASTER_SLIDE_ID      =  0x00000000;
+
+    private byte[] _header;
        private static long _type = 1007l;
-       public static final int MASTER_SLIDE_ID = 0;
-       public static final int USES_MASTER_SLIDE_ID = -2147483648;
 
        private int masterID;
        private int notesID;
@@ -44,7 +42,7 @@ public final class SlideAtom extends RecordAtom
        private boolean followMasterObjects;
        private boolean followMasterScheme;
        private boolean followMasterBackground;
-       private SSlideLayoutAtom layoutAtom;
+       private SlideAtomLayout layoutAtom;
        private byte[] reserved;
 
 
@@ -54,8 +52,8 @@ public final class SlideAtom extends RecordAtom
     public void setMasterID(int id) { masterID = id; }
        /** Get the ID of the notes for this slide. 0 if doesn't have one */
        public int getNotesID()  { return notesID; }
-       /** Get the embeded SSlideLayoutAtom */
-       public SSlideLayoutAtom getSSlideLayoutAtom() { return layoutAtom; }
+       /** Get the embedded SSlideLayoutAtom */
+       public SlideAtomLayout getSSlideLayoutAtom() { return layoutAtom; }
 
        /** Change the ID of the notes for this slide. 0 if it no longer has one */
        public void setNotesID(int id) { notesID = id; }
@@ -85,7 +83,7 @@ public final class SlideAtom extends RecordAtom
                byte[] SSlideLayoutAtomData = new byte[12];
                System.arraycopy(source,start+8,SSlideLayoutAtomData,0,12);
                // Use them to build up the SSlideLayoutAtom
-               layoutAtom = new SSlideLayoutAtom(SSlideLayoutAtomData);
+               layoutAtom = new SlideAtomLayout(SSlideLayoutAtomData);
 
                // Get the IDs of the master and notes
                masterID = LittleEndian.getInt(source,start+12+8);
@@ -125,13 +123,13 @@ public final class SlideAtom extends RecordAtom
                LittleEndian.putInt(_header, 4, 24);
 
                byte[] ssdate = new byte[12];
-               layoutAtom = new SSlideLayoutAtom(ssdate);
-               layoutAtom.setGeometryType(SSlideLayoutAtom.BLANK_SLIDE);
+               layoutAtom = new SlideAtomLayout(ssdate);
+               layoutAtom.setGeometryType(SlideLayoutType.BLANK_SLIDE);
 
                followMasterObjects = true;
                followMasterScheme = true;
                followMasterBackground = true;
-               masterID = -2147483648;
+               masterID = USES_MASTER_SLIDE_ID; // -2147483648;
                notesID = 0;
                reserved = new byte[2];
        }
@@ -168,70 +166,4 @@ public final class SlideAtom extends RecordAtom
                // Reserved data
                out.write(reserved);
        }
-
-
-       /**
-        * Holds the geometry of the Slide, and the ID of the placeholders
-        *  on the slide.
-        * (Embeded inside SlideAtom is a SSlideLayoutAtom, without the
-        *  usual record header. Since it's a fixed size and tied to
-        *  the SlideAtom, we'll hold it here.)
-        */
-       public static class SSlideLayoutAtom {
-               // The different kinds of geometry
-               public static final int TITLE_SLIDE = 0;
-               public static final int TITLE_BODY_SLIDE = 1;
-               public static final int TITLE_MASTER_SLIDE = 2;
-               public static final int MASTER_SLIDE = 3;
-               public static final int MASTER_NOTES = 4;
-               public static final int NOTES_TITLE_BODY = 5;
-               public static final int HANDOUT = 6; // Only header, footer and date placeholders
-               public static final int TITLE_ONLY = 7;
-               public static final int TITLE_2_COLUMN_BODY = 8;
-               public static final int TITLE_2_ROW_BODY = 9;
-               public static final int TITLE_2_COLUNM_RIGHT_2_ROW_BODY = 10;
-               public static final int TITLE_2_COLUNM_LEFT_2_ROW_BODY = 11;
-               public static final int TITLE_2_ROW_BOTTOM_2_COLUMN_BODY = 12;
-               public static final int TITLE_2_ROW_TOP_2_COLUMN_BODY = 13;
-               public static final int FOUR_OBJECTS = 14;
-               public static final int BIG_OBJECT = 15;
-               public static final int BLANK_SLIDE = 16;
-               public static final int VERTICAL_TITLE_BODY_LEFT = 17;
-               public static final int VERTICAL_TITLE_2_ROW_BODY_LEFT = 17;
-
-               /** What geometry type we are */
-               private int geometry;
-               /** What placeholder IDs we have */
-               private byte[] placeholderIDs;
-
-               /** Retrieve the geometry type */
-               public int getGeometryType() { return geometry; }
-               /** Set the geometry type */
-               public void setGeometryType(int geom) { geometry = geom; }
-
-               /**
-                * Create a new Embeded SSlideLayoutAtom, from 12 bytes of data
-                */
-               public SSlideLayoutAtom(byte[] data) {
-                       if(data.length != 12) {
-                               throw new HSLFException("SSlideLayoutAtom created with byte array not 12 bytes long - was " + data.length + " bytes in size");
-                       }
-
-                       // Grab out our data
-                       geometry = LittleEndian.getInt(data,0);
-                       placeholderIDs = new byte[8];
-                       System.arraycopy(data,4,placeholderIDs,0,8);
-               }
-
-               /**
-                * Write the contents of the record back, so it can be written
-                *  to disk. Skips the record header
-                */
-               public void writeOut(OutputStream out) throws IOException {
-                       // Write the geometry
-                       writeLittleEndian(geometry,out);
-                       // Write the placeholder IDs
-                       out.write(placeholderIDs);
-               }
-       }
 }
diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/SlideAtomLayout.java b/src/scratchpad/src/org/apache/poi/hslf/record/SlideAtomLayout.java
new file mode 100644 (file)
index 0000000..c6bd795
--- /dev/null
@@ -0,0 +1,133 @@
+/* ====================================================================
+   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.record;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.poi.hslf.exceptions.HSLFException;
+import org.apache.poi.util.Internal;
+import org.apache.poi.util.LittleEndian;
+
+/**
+ * Holds the geometry of the Slide, and the ID of the placeholders on the slide.
+ * Embedded inside a SlideAtom is a SlideAtomLayout, without the usual record header.
+ * Since it's a fixed size and tied to the SlideAtom, we'll hold it here.<p>
+ * 
+ * This might eventually merged with the XSLF counterpart
+ */
+@Internal
+public class SlideAtomLayout {
+    // The different kinds of geometry
+    public enum SlideLayoutType {
+        /** One title and one subtitle placeholder shapes. */
+        TITLE_SLIDE(0x0000),
+        /** Presentation slide or main master slide layout with one title and one body placeholder shape. */
+        TITLE_BODY(0x0001),
+        /** Title master slide layout with one title and one subtitle placeholder shape. */
+        MASTER_TITLE(0x0002),
+        /** ??? (not documented in spec) */
+        MASTER_SLIDE(0x0003),
+        /** ??? (not documented in spec) */
+        MASTER_NOTES(0x0004),
+        /** ??? (not documented in spec) */
+        NOTES_TITLE_BODY(0x0005),
+        /** Only header, footer and date placeholders */
+        HANDOUT(0x0006),
+        /** Presentation slide layout with one title placeholder shape. */
+        TITLE_ONLY(0x0007),
+        /** Presentation slide layout with one title and two body placeholder shapes stacked horizontally. */
+        TWO_COLUMNS(0x0008),
+        /** Presentation slide layout with one title and two body placeholder shapes stacked vertically. */
+        TWO_ROWS(0x0009),
+        /** Presentation slide layout with one title and three body placeholder shapes split into two columns. The right column has two rows. */
+        COLUMN_TWO_ROWS(0x000A),
+        /** Presentation slide layout with one title and three body placeholder shapes split into two columns. The left column has two rows. */
+        TWO_ROWS_COLUMN(0x000B),
+        /** ??? (not documented in spec) */
+        TITLE_2_ROW_BOTTOM_2_COLUMN_BODY(0x000C),
+        /** Presentation slide layout with one title and three body placeholder shapes split into two rows. The top row has two columns. */
+        TWO_COLUMNS_ROW(0x000D),
+        /** Presentation slide layout with one title and four body placeholder shapes. */
+        FOUR_OBJECTS(0x000E),
+        /** Presentation slide layout with one body placeholder shape. */
+        BIG_OBJECT(0x000F),
+        /** Presentation slide layout with no placeholder shape. */
+        BLANK_SLIDE(0x0010),
+        /** Presentation slide layout with a vertical title placeholder shape on the right and a body placeholder shape on the left. */
+        VERTICAL_TITLE_BODY(0x0011),
+        /** Presentation slide layout with a vertical title placeholder shape on the right and two body placeholder shapes in two columns on the left. */
+        VERTICAL_TWO_ROWS(0x0012);
+
+        private int nativeId;
+        SlideLayoutType(int nativeId) {
+            this.nativeId = nativeId;
+        }
+        
+        public int getNativeId() {
+            return nativeId;
+        }
+
+        public static SlideLayoutType forNativeID(int nativeId) {
+            for (SlideLayoutType ans : values()) {
+                if (ans.nativeId == nativeId) {
+                    return ans;
+                }
+            }
+            return null;
+        }
+    }
+
+    /** What geometry type we are */
+    private SlideLayoutType geometry;
+    /** What placeholder IDs we have */
+    private byte[] placeholderIDs;
+
+    /** Retrieve the geometry type */
+    public SlideLayoutType getGeometryType() { return geometry; }
+    /** Set the geometry type */
+    public void setGeometryType(SlideLayoutType geom) { geometry = geom; }
+
+    /**
+     * Create a new Embedded SSlideLayoutAtom, from 12 bytes of data
+     */
+    public SlideAtomLayout(byte[] data) {
+        if(data.length != 12) {
+            throw new HSLFException("SSlideLayoutAtom created with byte array not 12 bytes long - was " + data.length + " bytes in size");
+        }
+
+        // Grab out our data
+        geometry = SlideLayoutType.forNativeID(LittleEndian.getInt(data,0));
+        placeholderIDs = new byte[8];
+        System.arraycopy(data,4,placeholderIDs,0,8);
+    }
+
+    /**
+     * Write the contents of the record back, so it can be written
+     *  to disk. Skips the record header
+     */
+    public void writeOut(OutputStream out) throws IOException {
+        // Write the geometry
+        byte[] buf = new byte[4];
+        LittleEndian.putInt(buf, 0, geometry.getNativeId());
+        out.write(buf);
+        // Write the placeholder IDs
+        out.write(placeholderIDs);
+    }
+
+}
index 238385b684e56d3f53a259cc65adb18faff5a084..5291eb2fe32317e3bc414732f2af46506c5df5eb 100644 (file)
@@ -42,15 +42,11 @@ import org.apache.poi.util.POILogger;
  *  the style applies to, and what style elements make up the style (another
  *  list, this time of TextProps). Each TextProp has a value, which somehow
  *  encapsulates a property of the style
- *
- * @author Nick Burch
- * @author Yegor Kozlov
  */
 
-public final class StyleTextPropAtom extends RecordAtom
-{
+public final class StyleTextPropAtom extends RecordAtom {
+    public static final long _type = RecordTypes.StyleTextPropAtom.typeID;
     private byte[] _header;
-    private static final long _type = RecordTypes.StyleTextPropAtom.typeID;
     private byte[] reserved;
 
     private byte[] rawContents; // Holds the contents between write-outs
index 43a5abf8aa059cb37033f329e5c56f6409f65ac6..0badc3e31dc3749d8b9c1d12f873086539540f41 100644 (file)
 
 package org.apache.poi.hslf.record;
 
+import java.io.IOException;
+import java.io.OutputStream;
+
 import org.apache.poi.util.HexDump;
 import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.StringUtil;
-import java.io.IOException;
-import java.io.OutputStream;
 
 /**
  * A TextBytesAtom (type 4008). Holds text in ascii form (unknown
  *  code page, for now assumed to be the default of
  *  org.apache.poi.util.StringUtil, which is the Excel default).
  * The trailing return character is always stripped from this
- *
- * @author Nick Burch
  */
 
-public final class TextBytesAtom extends RecordAtom
-{
+public final class TextBytesAtom extends RecordAtom {
+    public static final long _type = RecordTypes.TextBytesAtom.typeID;
        private byte[] _header;
-       private static long _type = RecordTypes.TextBytesAtom.typeID;
 
        /** The bytes that make up the text */
        private byte[] _text;
@@ -87,13 +85,15 @@ public final class TextBytesAtom extends RecordAtom
        /**
         * We are of type 4008
         */
-       public long getRecordType() { return _type; }
+       @Override
+    public long getRecordType() { return _type; }
 
        /**
         * Write the contents of the record back, so it can be written
         *  to disk
         */
-       public void writeOut(OutputStream out) throws IOException {
+       @Override
+    public void writeOut(OutputStream out) throws IOException {
                // Header - size or type unchanged
                out.write(_header);
 
@@ -105,7 +105,8 @@ public final class TextBytesAtom extends RecordAtom
         * dump debug info; use getText() to return a string
         * representation of the atom
         */
-       public String toString() {
+       @Override
+    public String toString() {
         StringBuffer out = new StringBuffer();
         out.append( "TextBytesAtom:\n");
                out.append( HexDump.dump(_text, 0, 0) );
index 3449250ada792fdef7b2e822b881d11712b616f2..fa8ff836d137a14161a7073f37607b9488645c0c 100644 (file)
 
 package org.apache.poi.hslf.record;
 
+import java.io.IOException;
+import java.io.OutputStream;
+
 import org.apache.poi.util.HexDump;
 import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.StringUtil;
-import java.io.IOException;
-import java.io.OutputStream;
 
 /**
  * A TextCharsAtom (type 4000). Holds text in byte swapped unicode form.
  * The trailing return character is always stripped from this
- *
- * @author Nick Burch
  */
 
-public final class TextCharsAtom extends RecordAtom
-{
+public final class TextCharsAtom extends RecordAtom {
+    public static final long _type = RecordTypes.TextCharsAtom.typeID;
        private byte[] _header;
-       private static long _type = RecordTypes.TextCharsAtom.typeID;
 
        /** The bytes that make up the text */
        private byte[] _text;
@@ -83,13 +81,15 @@ public final class TextCharsAtom extends RecordAtom
        /**
         * We are of type 4000
         */
-       public long getRecordType() { return _type; }
+       @Override
+    public long getRecordType() { return _type; }
 
        /**
         * Write the contents of the record back, so it can be written
         *  to disk
         */
-       public void writeOut(OutputStream out) throws IOException {
+       @Override
+    public void writeOut(OutputStream out) throws IOException {
                // Header - size or type unchanged
                out.write(_header);
 
@@ -101,7 +101,8 @@ public final class TextCharsAtom extends RecordAtom
         * dump debug info; use getText() to return a string
         * representation of the atom
         */
-       public String toString() {
+       @Override
+    public String toString() {
         StringBuffer out = new StringBuffer();
         out.append( "TextCharsAtom:\n");
                out.append( HexDump.dump(_text, 0, 0) );
index 2d4f41bddc80bcffc7222d9e9f49466e100cd7be..05c61a667db066a2baf49eb84fe6bc598d718a98 100644 (file)
@@ -27,14 +27,11 @@ import org.apache.poi.util.LittleEndian;
  * A TextHeaderAtom  (type 3999). Holds information on what kind of
  *  text is contained in the TextBytesAtom / TextCharsAtom that follows
  *  straight after
- *
- * @author Nick Burch
  */
 
-public final class TextHeaderAtom extends RecordAtom implements ParentAwareRecord
-{
+public final class TextHeaderAtom extends RecordAtom implements ParentAwareRecord {
+    public static final long _type = RecordTypes.TextHeaderAtom.typeID;
        private byte[] _header;
-       private static long _type = RecordTypes.TextHeaderAtom.typeID;
        private RecordContainer parentRecord;
 
        public static final int TITLE_TYPE = 0;
index 5bfd3bbc9cf3d04538e11027eabeebab5059b92d..cc41706347cd7c54b739e61cab716ca81abf0d4e 100644 (file)
@@ -30,15 +30,14 @@ 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;
 import org.apache.poi.hslf.record.PPDrawing;
 import org.apache.poi.hslf.record.RecordContainer;
 import org.apache.poi.hslf.record.RecordTypes;
-import org.apache.poi.hslf.record.RoundTripHFPlaceholder12;
 import org.apache.poi.hslf.record.SheetContainer;
 import org.apache.poi.sl.draw.DrawFactory;
 import org.apache.poi.sl.draw.Drawable;
 import org.apache.poi.sl.usermodel.PictureData;
+import org.apache.poi.sl.usermodel.Placeholder;
 import org.apache.poi.sl.usermodel.ShapeType;
 import org.apache.poi.sl.usermodel.Sheet;
 import org.apache.poi.util.Internal;
@@ -108,6 +107,7 @@ public abstract class HSLFSheet implements HSLFShapeContainer, Sheet<HSLFShape,H
     /**
      * Fetch the SlideShow we're attached to
      */
+    @Override
     public HSLFSlideShow getSlideShow() {
         return _slideShow;
     }
@@ -131,7 +131,9 @@ public abstract class HSLFSheet implements HSLFShapeContainer, Sheet<HSLFShape,H
         
         _slideShow = ss;
         List<List<HSLFTextParagraph>> trs = getTextParagraphs();
-        if (trs == null) return;
+        if (trs == null) {
+            return;
+        }
         for (List<HSLFTextParagraph> ltp : trs) {
             HSLFTextParagraph.supplySheet(ltp, this);
             HSLFTextParagraph.applyHyperlinks(ltp);
@@ -192,6 +194,7 @@ public abstract class HSLFSheet implements HSLFShapeContainer, Sheet<HSLFShape,H
      *
      * @param shape - the Shape to add
      */
+    @Override
     public void addShape(HSLFShape shape) {
         PPDrawing ppdrawing = getPPDrawing();
 
@@ -226,8 +229,9 @@ public abstract class HSLFSheet implements HSLFShapeContainer, Sheet<HSLFShape,H
                 c.incrementShapeId();
                 dg.setNumShapes( dg.getNumShapes() + 1 );
                 dg.setLastMSOSPID( result );
-                if (result >= dgg.getShapeIdMax())
+                if (result >= dgg.getShapeIdMax()) {
                     dgg.setShapeIdMax( result + 1 );
+                }
                 return result;
             }
         }
@@ -238,8 +242,9 @@ public abstract class HSLFSheet implements HSLFShapeContainer, Sheet<HSLFShape,H
         dg.setNumShapes( dg.getNumShapes() + 1 );
         int result = (1024 * dgg.getFileIdClusters().length);
         dg.setLastMSOSPID( result );
-        if (result >= dgg.getShapeIdMax())
+        if (result >= dgg.getShapeIdMax()) {
             dgg.setShapeIdMax( result + 1 );
+        }
         return result;
     }
 
@@ -249,6 +254,7 @@ public abstract class HSLFSheet implements HSLFShapeContainer, Sheet<HSLFShape,H
      * @param shape shape to be removed from this sheet, if present.
      * @return <tt>true</tt> if the shape was deleted.
      */
+    @Override
     public boolean removeShape(HSLFShape shape) {
         PPDrawing ppdrawing = getPPDrawing();
 
@@ -274,6 +280,7 @@ public abstract class HSLFSheet implements HSLFShapeContainer, Sheet<HSLFShape,H
     /**
      * Return the master sheet .
      */
+    @Override
     public abstract HSLFMasterSheet getMasterSheet();
 
     /**
@@ -288,6 +295,7 @@ public abstract class HSLFSheet implements HSLFShapeContainer, Sheet<HSLFShape,H
      *
      * @return the background shape for this sheet.
      */
+    @Override
     public HSLFBackground getBackground() {
         if (_background == null) {
             PPDrawing ppdrawing = getPPDrawing();
@@ -335,26 +343,17 @@ public abstract class HSLFSheet implements HSLFShapeContainer, Sheet<HSLFShape,H
     }
 
     /**
-     * Search text placeholer by its type
+     * Search placeholder by its type
      *
      * @param type  type of placeholder to search. See {@link org.apache.poi.hslf.record.OEPlaceholderAtom}
-     * @return  <code>TextShape</code> or <code>null</code>
+     * @return  {@code SimpleShape} or {@code null}
      */
-    public HSLFTextShape getPlaceholder(int type){
+    public HSLFSimpleShape getPlaceholder(Placeholder type){
         for (HSLFShape shape : getShapes()) {
-            if(shape instanceof HSLFTextShape){
-                HSLFTextShape tx = (HSLFTextShape)shape;
-                int placeholderId = 0;
-                OEPlaceholderAtom oep = tx.getPlaceholderAtom();
-                if(oep != null) {
-                    placeholderId = oep.getPlaceholderId();
-                } else {
-                    //special case for files saved in Office 2007
-                    RoundTripHFPlaceholder12 hldr = tx.getClientDataRecord(RecordTypes.RoundTripHFPlaceholder12.typeID);
-                    if(hldr != null) placeholderId = hldr.getPlaceholderId();
-                }
-                if(placeholderId == type){
-                    return tx;
+            if (shape instanceof HSLFSimpleShape) {
+                HSLFSimpleShape ss = (HSLFSimpleShape)shape;
+                if (type == ss.getPlaceholder()) {
+                    return ss;
                 }
             }
         }
@@ -382,7 +381,9 @@ public abstract class HSLFSheet implements HSLFShapeContainer, Sheet<HSLFShape,H
                     progBinaryTag.findFirstOfType(
                             RecordTypes.CString.typeID
                 );
-                if(binaryTag != null) tag = binaryTag.getText();
+                if(binaryTag != null) {
+                    tag = binaryTag.getText();
+                }
             }
         }
 
@@ -390,6 +391,7 @@ public abstract class HSLFSheet implements HSLFShapeContainer, Sheet<HSLFShape,H
 
     }
 
+    @Override
     public Iterator<HSLFShape> iterator() {
         return getShapes().iterator();
     }
@@ -400,6 +402,7 @@ public abstract class HSLFSheet implements HSLFShapeContainer, Sheet<HSLFShape,H
      * Sheets that support the notion of master (slide, slideLayout) should override it and
      * check this setting
      */
+    @Override
     public boolean getFollowMasterGraphics() {
         return false;
     }
index 8618dbeb0ead4ba7053056815e52a3a472106718..dd98a017bf04dcff60e62a3bb4a4f0671d6c1b00 100644 (file)
@@ -42,6 +42,7 @@ import org.apache.poi.sl.draw.geom.PresetGeometries;
 import org.apache.poi.sl.usermodel.LineDecoration;
 import org.apache.poi.sl.usermodel.LineDecoration.DecorationShape;
 import org.apache.poi.sl.usermodel.LineDecoration.DecorationSize;
+import org.apache.poi.sl.usermodel.MasterSheet;
 import org.apache.poi.sl.usermodel.PaintStyle;
 import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
 import org.apache.poi.sl.usermodel.Placeholder;
@@ -546,13 +547,40 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H
         if (clRecords == null) {
             return null;
         }
+        int phSource;
+        HSLFSheet sheet = getSheet();
+        if (sheet instanceof HSLFSlideMaster) {
+            phSource = 1;
+        } else if (sheet instanceof HSLFNotes) {
+            phSource = 2;
+        } else if (sheet instanceof MasterSheet) {
+            // notes master aren't yet supported ...
+            phSource = 3;
+        } else {
+            phSource = 0;
+        }
+        
         for (Record r : clRecords) {
+            int phId;
             if (r instanceof OEPlaceholderAtom) {
-                OEPlaceholderAtom oep = (OEPlaceholderAtom)r;
-                return Placeholder.lookupNative(oep.getPlaceholderId());
+                phId = ((OEPlaceholderAtom)r).getPlaceholderId();
             } else if (r instanceof RoundTripHFPlaceholder12) {
-                RoundTripHFPlaceholder12 rtp = (RoundTripHFPlaceholder12)r;
-                return Placeholder.lookupNative(rtp.getPlaceholderId());
+                //special case for files saved in Office 2007
+                phId = ((RoundTripHFPlaceholder12)r).getPlaceholderId();
+            } else {
+                continue;
+            }
+
+            switch (phSource) {
+            case 0:
+                return Placeholder.lookupNativeSlide(phId);
+            default:
+            case 1:
+                return Placeholder.lookupNativeSlideMaster(phId);
+            case 2:
+                return Placeholder.lookupNativeNotes(phId);
+            case 3:
+                return Placeholder.lookupNativeNotesMaster(phId);
             }
         }
 
index a37b7abbca2eb44ba1a4f2631f02536d0b96c22c..2a3e4fae1bf5e48348edb81ac007d55bd80452a9 100644 (file)
@@ -36,6 +36,7 @@ import org.apache.poi.hslf.record.RecordContainer;
 import org.apache.poi.hslf.record.RecordTypes;
 import org.apache.poi.hslf.record.SSSlideInfoAtom;
 import org.apache.poi.hslf.record.SlideAtom;
+import org.apache.poi.hslf.record.SlideAtomLayout.SlideLayoutType;
 import org.apache.poi.hslf.record.SlideListWithText.SlideAtomsSet;
 import org.apache.poi.hslf.record.StyleTextProp9Atom;
 import org.apache.poi.hslf.record.TextHeaderAtom;
@@ -501,4 +502,27 @@ public final class HSLFSlide extends HSLFSheet implements Slide<HSLFShape,HSLFTe
     public boolean getFollowMasterGraphics() {
         return getFollowMasterObjects();
     }
+
+    @Override
+    public boolean getDisplayPlaceholder(Placeholder placeholder) {
+        HeadersFooters hf = getHeadersFooters();
+        SlideLayoutType slt =  getSlideRecord().getSlideAtom().getSSlideLayoutAtom().getGeometryType();
+        boolean isTitle =
+            (slt == SlideLayoutType.TITLE_SLIDE || slt == SlideLayoutType.TITLE_ONLY || slt == SlideLayoutType.MASTER_TITLE);
+        if (hf != null) {
+            switch (placeholder) {
+            case DATETIME:
+                return hf.isDateTimeVisible() && !isTitle;
+            case SLIDE_NUMBER:
+                return hf.isSlideNumberVisible() && !isTitle;
+            case HEADER:
+                return hf.isHeaderVisible() && !isTitle;
+            case FOOTER:
+                return hf.isFooterVisible() && !isTitle;
+            default:
+                break;    
+            }
+        }
+        return false;
+    }
 }
index 9b5668ffee18eb1f8b46628ab7119f2e9e4ba328..7919dc2c06b2071b8059dc9b7484ad96374e543d 100644 (file)
@@ -23,7 +23,9 @@ 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.hslf.record.MainMaster;
+import org.apache.poi.hslf.record.TextHeaderAtom;
+import org.apache.poi.hslf.record.TxMasterStyleAtom;
 import org.apache.poi.util.Internal;
 
 /**
@@ -49,13 +51,16 @@ public final class HSLFSlideMaster extends HSLFMasterSheet {
         super(record, sheetNo);
 
         for (List<HSLFTextParagraph> l : HSLFTextParagraph.findTextParagraphs(getPPDrawing(), this)) {
-            if (!_paragraphs.contains(l)) _paragraphs.add(l);
+            if (!_paragraphs.contains(l)) {
+                _paragraphs.add(l);
+            }
         }
     }
 
     /**
      * Returns an array of all the TextRuns found
      */
+    @Override
     public List<List<HSLFTextParagraph>> getTextParagraphs() {
         return _paragraphs;
     }
@@ -63,6 +68,7 @@ public final class HSLFSlideMaster extends HSLFMasterSheet {
     /**
      * Returns <code>null</code> since SlideMasters doen't have master sheet.
      */
+    @Override
     public HSLFMasterSheet getMasterSheet() {
         return null;
     }
@@ -71,8 +77,11 @@ public final class HSLFSlideMaster extends HSLFMasterSheet {
      * Pickup a style attribute from the master.
      * This is the "workhorse" which returns the default style attributes.
      */
+    @Override
     public TextProp getStyleAttribute(int txtype, int level, String name, boolean isCharacter) {
-        if (_txmaster.length <= txtype) return null;
+        if (_txmaster.length <= txtype) {
+            return null;
+        }
         TxMasterStyleAtom t = _txmaster[txtype];
         List<TextPropCollection> styles = isCharacter ? t.getCharacterStyles() : t.getParagraphStyles();
         
@@ -81,7 +90,9 @@ public final class HSLFSlideMaster extends HSLFMasterSheet {
             prop = styles.get(i).findByName(name);
         }
 
-        if (prop != null) return prop;
+        if (prop != null) {
+            return prop;
+        }
         
         switch (txtype) {
             case TextHeaderAtom.CENTRE_BODY_TYPE:
@@ -146,6 +157,7 @@ public final class HSLFSlideMaster extends HSLFMasterSheet {
         }
     }
 
+    @Override
     protected void onAddTextShape(HSLFTextShape shape) {
         List<HSLFTextParagraph> runs = shape.getTextParagraphs();
         _paragraphs.add(runs);
index 60232d50a7176cd4d428e9c80f52937f5dbc9d2c..afe5d71264a86a2c0d6e06068b08d1ca967db768 100644 (file)
@@ -36,14 +36,35 @@ import org.apache.poi.hslf.model.textproperties.TextPFException9;
 import org.apache.poi.hslf.model.textproperties.TextProp;\r
 import org.apache.poi.hslf.model.textproperties.TextPropCollection;\r
 import org.apache.poi.hslf.model.textproperties.TextPropCollection.TextPropType;\r
-import org.apache.poi.hslf.record.*;\r
+import org.apache.poi.hslf.record.ColorSchemeAtom;\r
+import org.apache.poi.hslf.record.EscherTextboxWrapper;\r
+import org.apache.poi.hslf.record.FontCollection;\r
+import org.apache.poi.hslf.record.InteractiveInfo;\r
+import org.apache.poi.hslf.record.MasterTextPropAtom;\r
+import org.apache.poi.hslf.record.OutlineTextRefAtom;\r
+import org.apache.poi.hslf.record.PPDrawing;\r
+import org.apache.poi.hslf.record.Record;\r
+import org.apache.poi.hslf.record.RecordContainer;\r
+import org.apache.poi.hslf.record.RecordTypes;\r
+import org.apache.poi.hslf.record.RoundTripHFPlaceholder12;\r
+import org.apache.poi.hslf.record.SlideListWithText;\r
+import org.apache.poi.hslf.record.SlidePersistAtom;\r
+import org.apache.poi.hslf.record.StyleTextProp9Atom;\r
+import org.apache.poi.hslf.record.StyleTextPropAtom;\r
+import org.apache.poi.hslf.record.TextBytesAtom;\r
+import org.apache.poi.hslf.record.TextCharsAtom;\r
+import org.apache.poi.hslf.record.TextHeaderAtom;\r
+import org.apache.poi.hslf.record.TextRulerAtom;\r
+import org.apache.poi.hslf.record.TextSpecInfoAtom;\r
+import org.apache.poi.hslf.record.TxInteractiveInfoAtom;\r
 import org.apache.poi.sl.draw.DrawPaint;\r
 import org.apache.poi.sl.usermodel.AutoNumberingScheme;\r
+import org.apache.poi.sl.usermodel.MasterSheet;\r
 import org.apache.poi.sl.usermodel.PaintStyle;\r
 import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;\r
+import org.apache.poi.sl.usermodel.Placeholder;\r
 import org.apache.poi.sl.usermodel.TextParagraph;\r
 import org.apache.poi.util.Internal;\r
-import org.apache.poi.util.LocaleUtil;\r
 import org.apache.poi.util.POILogFactory;\r
 import org.apache.poi.util.POILogger;\r
 import org.apache.poi.util.StringUtil;\r
@@ -53,8 +74,6 @@ import org.apache.poi.util.Units;
  * This class represents a run of text in a powerpoint document. That\r
  *  run could be text on a sheet, or text in a note.\r
  *  It is only a very basic class for now\r
- *\r
- * @author Nick Burch\r
  */\r
 \r
 public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFTextParagraph,HSLFTextRun> {\r
@@ -74,6 +93,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
     private TextBytesAtom _byteAtom;\r
     private TextCharsAtom _charAtom;\r
     private TextPropCollection _paragraphStyle = new TextPropCollection(1, TextPropType.paragraph);\r
+    private TextPropCollection _masterStyle;\r
 \r
     protected TextRulerAtom _ruler;\r
     protected final List<HSLFTextRun> _runs = new ArrayList<HSLFTextRun>();\r
@@ -139,7 +159,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
     public void setParagraphStyle(TextPropCollection paragraphStyle) {\r
         _paragraphStyle.copy(paragraphStyle);\r
     }\r
-\r
+    \r
     /**\r
      * Setting a master style reference\r
      *\r
@@ -148,8 +168,8 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
      * @since POI 3.14-Beta1\r
      */\r
     @Internal\r
-    /* package */ void setMasterStyleReference(TextPropCollection paragraphStyle) {\r
-        _paragraphStyle = paragraphStyle;\r
+    /* package */ void setMasterStyleReference(TextPropCollection masterStyle) {\r
+        _masterStyle = masterStyle;\r
     }\r
 \r
     /**\r
@@ -321,8 +341,8 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
 \r
     @Override\r
     public Double getLeftMargin() {\r
-        TextProp val = getPropVal(_paragraphStyle, "text.offset", this);\r
-        return (val == null) ? null : Units.masterToPoints(val.getValue());\r
+        TextProp tp = getPropVal(_paragraphStyle, _masterStyle, "text.offset");\r
+        return (tp == null) ? null : Units.masterToPoints(tp.getValue());\r
     }\r
 \r
     @Override\r
@@ -344,8 +364,8 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
 \r
     @Override\r
     public Double getIndent() {\r
-        TextProp val = getPropVal(_paragraphStyle, "bullet.offset", this);\r
-        return (val == null) ? null : Units.masterToPoints(val.getValue());\r
+        TextProp tp = getPropVal(_paragraphStyle, _masterStyle, "bullet.offset");\r
+        return (tp == null) ? null : Units.masterToPoints(tp.getValue());\r
     }\r
 \r
     @Override\r
@@ -393,7 +413,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
 \r
     @Override\r
     public TextAlign getTextAlign() {\r
-        TextProp tp = getPropVal(_paragraphStyle, "alignment", this);\r
+        TextProp tp = getPropVal(_paragraphStyle, _masterStyle, "alignment");\r
         if (tp == null) {\r
             return null;\r
         }\r
@@ -411,7 +431,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
 \r
     @Override\r
     public FontAlign getFontAlign() {\r
-        TextProp tp = getPropVal(_paragraphStyle, FontAlignmentProp.NAME, this);\r
+        TextProp tp = getPropVal(_paragraphStyle, _masterStyle, FontAlignmentProp.NAME);\r
         if (tp == null) {\r
             return null;\r
         }\r
@@ -577,7 +597,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
      * Returns the bullet character\r
      */\r
     public Character getBulletChar() {\r
-        TextProp tp = getPropVal(_paragraphStyle, "bullet.char", this);\r
+        TextProp tp = getPropVal(_paragraphStyle, _masterStyle, "bullet.char");\r
         return (tp == null) ? null : (char)tp.getValue();\r
     }\r
 \r
@@ -608,7 +628,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
      * Returns the bullet color\r
      */\r
     public Color getBulletColor() {\r
-        TextProp tp = getPropVal(_paragraphStyle, "bullet.color", this);\r
+        TextProp tp = getPropVal(_paragraphStyle, _masterStyle, "bullet.color");\r
         boolean hasColor = getFlag(ParagraphFlagsTextProp.BULLET_HARDCOLOR_IDX);\r
         if (tp == null || !hasColor) {\r
             // if bullet color is undefined, return color of first run\r
@@ -632,8 +652,9 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
      */\r
     public void setBulletFont(String typeface) {\r
         if (typeface == null) {\r
-            setPropVal(_paragraphStyle, "bullet.font", null);\r
+            setPropVal(_paragraphStyle, _masterStyle, "bullet.font", null);\r
             setFlag(ParagraphFlagsTextProp.BULLET_HARDFONT_IDX, false);\r
+            return;\r
         }\r
 \r
         FontCollection fc = getSheet().getSlideShow().getFontCollection();\r
@@ -647,7 +668,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
      * Returns the bullet font\r
      */\r
     public String getBulletFont() {\r
-        TextProp tp = getPropVal(_paragraphStyle, "bullet.font", this);\r
+        TextProp tp = getPropVal(_paragraphStyle, _masterStyle, "bullet.font");\r
         boolean hasFont = getFlag(ParagraphFlagsTextProp.BULLET_HARDFONT_IDX);\r
         if (tp == null || !hasFont) {\r
             return getDefaultFontFamily();\r
@@ -694,7 +715,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
     }\r
 \r
     private Double getPctOrPoints(String propName) {\r
-        TextProp tp = getPropVal(_paragraphStyle, propName, this);\r
+        TextProp tp = getPropVal(_paragraphStyle, _masterStyle, propName);\r
         if (tp == null) {\r
             return null;\r
         }\r
@@ -711,7 +732,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
     }\r
 \r
     private boolean getFlag(int index) {\r
-        BitMaskTextProp tp = (BitMaskTextProp)getPropVal(_paragraphStyle, ParagraphFlagsTextProp.NAME, this);\r
+        BitMaskTextProp tp = (BitMaskTextProp)getPropVal(_paragraphStyle, _masterStyle, ParagraphFlagsTextProp.NAME);\r
         return (tp == null) ? false : tp.getSubValue(index);\r
     }\r
 \r
@@ -729,7 +750,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
      * The propName can be a comma-separated list, in case multiple equivalent values\r
      * are queried\r
      */\r
-    protected static TextProp getPropVal(TextPropCollection props, String propName, HSLFTextParagraph paragraph) {\r
+    protected TextProp getPropVal(TextPropCollection props, TextPropCollection masterProps, String propName) {\r
         String propNames[] = propName.split(",");\r
         for (String pn : propNames) {\r
             TextProp prop = props.findByName(pn);\r
@@ -740,41 +761,52 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
             // Font properties (maybe other too???) can have an index of -1\r
             // so we check the master for this font index then\r
             if (pn.contains("font") && prop.getValue() == -1) {\r
-                return getMasterPropVal(props, pn, paragraph);\r
+                return getMasterPropVal(props, masterProps, pn);\r
             }\r
             \r
             return prop;\r
         }\r
         \r
-        return getMasterPropVal(props, propName, paragraph);\r
+        return getMasterPropVal(props, masterProps, propName);\r
     }\r
     \r
-    private static TextProp getMasterPropVal(TextPropCollection props, String propName, HSLFTextParagraph paragraph) {\r
-        String propNames[] = propName.split(",");\r
-        \r
-        BitMaskTextProp maskProp = (BitMaskTextProp) props.findByName(ParagraphFlagsTextProp.NAME);\r
-        boolean hardAttribute = (maskProp != null && maskProp.getValue() == 0);\r
-        if (hardAttribute) {\r
-            return null;\r
-        }\r
+    private TextProp getMasterPropVal(TextPropCollection props, TextPropCollection masterProps, String propName) {\r
+        boolean isChar = props.getTextPropType() == TextPropType.character;\r
 \r
-        HSLFSheet sheet = paragraph.getSheet();\r
-        int txtype = paragraph.getRunType();\r
-        HSLFMasterSheet master = sheet.getMasterSheet();\r
-        if (master == null) {\r
-            logger.log(POILogger.WARN, "MasterSheet is not available");\r
-            return null;\r
+        // check if we can delegate to master for the property\r
+        if (!isChar) {\r
+            BitMaskTextProp maskProp = (BitMaskTextProp) props.findByName(ParagraphFlagsTextProp.NAME);\r
+            boolean hardAttribute = (maskProp != null && maskProp.getValue() == 0);\r
+            if (hardAttribute) {\r
+                return null;\r
+            }\r
         }\r
 \r
-        boolean isChar = props.getTextPropType() == TextPropType.character;\r
+        String propNames[] = propName.split(",");\r
+        if (masterProps == null) { \r
+            HSLFSheet sheet = getSheet();\r
+            int txtype = getRunType();\r
+            HSLFMasterSheet master = sheet.getMasterSheet();\r
+            if (master == null) {\r
+                logger.log(POILogger.WARN, "MasterSheet is not available");\r
+                return null;\r
+            }\r
 \r
-        for (String pn : propNames) {\r
-            TextProp prop = master.getStyleAttribute(txtype, paragraph.getIndentLevel(), pn, isChar);\r
-            if (prop != null) {\r
-                return prop;\r
+            for (String pn : propNames) {\r
+                TextProp prop = master.getStyleAttribute(txtype, getIndentLevel(), pn, isChar);\r
+                if (prop != null) {\r
+                    return prop;\r
+                }\r
+            }\r
+        } else {\r
+            for (String pn : propNames) {\r
+                TextProp prop = masterProps.findByName(pn);\r
+                if (prop != null) {\r
+                    return prop;\r
+                }\r
             }\r
         }\r
-\r
+        \r
         return null;\r
     }\r
 \r
@@ -786,14 +818,19 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
      * @param name the name of the TextProp to fetch/add\r
      * @param val the value, null if unset\r
      */\r
-    protected static void setPropVal(TextPropCollection props, String name, Integer val) {\r
+    protected void setPropVal(TextPropCollection props, TextPropCollection masterProps, String name, Integer val) {\r
+        TextPropCollection pc = props;\r
+        if (getSheet() instanceof MasterSheet && masterProps != null) {\r
+            pc = masterProps;\r
+        }\r
+        \r
         if (val == null) {\r
-            props.removeByName(name);\r
+            pc.removeByName(name);\r
             return;\r
         }\r
 \r
         // Fetch / Add the TextProp\r
-        TextProp tp = props.addWithName(name);\r
+        TextProp tp = pc.addWithName(name);\r
         tp.setValue(val);\r
     }\r
 \r
@@ -1517,38 +1554,6 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
         }\r
     }\r
 \r
-    protected static List<HSLFTextParagraph> createEmptyParagraph() {\r
-        EscherTextboxWrapper wrapper = new EscherTextboxWrapper();\r
-        return createEmptyParagraph(wrapper);\r
-    }\r
-\r
-    protected static List<HSLFTextParagraph> createEmptyParagraph(EscherTextboxWrapper wrapper) {\r
-        TextHeaderAtom tha = new TextHeaderAtom();\r
-        tha.setParentRecord(wrapper);\r
-        wrapper.appendChildRecord(tha);\r
-\r
-        TextBytesAtom tba = new TextBytesAtom();\r
-        tba.setText("".getBytes(LocaleUtil.CHARSET_1252));\r
-        wrapper.appendChildRecord(tba);\r
-\r
-        StyleTextPropAtom sta = new StyleTextPropAtom(1);\r
-        TextPropCollection paraStyle = sta.addParagraphTextPropCollection(1);\r
-        TextPropCollection charStyle = sta.addCharacterTextPropCollection(1);\r
-        wrapper.appendChildRecord(sta);\r
-\r
-        List<HSLFTextParagraph> paragraphs = new ArrayList<HSLFTextParagraph>(1);\r
-        HSLFTextParagraph htp = new HSLFTextParagraph(tha, tba, null, paragraphs);\r
-        htp.setParagraphStyle(paraStyle);\r
-        paragraphs.add(htp);\r
-\r
-        HSLFTextRun htr = new HSLFTextRun(htp);\r
-        htr.setCharacterStyle(charStyle);\r
-        htr.setText("");\r
-        htp.addTextRun(htr);\r
-\r
-        return paragraphs;\r
-    }\r
-\r
     public EscherTextboxWrapper getTextboxWrapper() {\r
         return (EscherTextboxWrapper) _headerAtom.getParentRecord();\r
     }\r
@@ -1583,7 +1588,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
      * @param val The value to set for the TextProp\r
      */\r
     public void setParagraphTextPropVal(String propName, Integer val) {\r
-        setPropVal(_paragraphStyle, propName, val);\r
+        setPropVal(_paragraphStyle, _masterStyle, propName, val);\r
         setDirty();\r
     }\r
 \r
@@ -1624,21 +1629,19 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
      */\r
     @Override\r
     public boolean isHeaderOrFooter() {\r
-        HSLFShape s = getParentShape();\r
+        HSLFTextShape s = getParentShape();\r
         if (s == null) {\r
             return false;\r
         }\r
-        RoundTripHFPlaceholder12 hfPl = s.getClientDataRecord(RecordTypes.RoundTripHFPlaceholder12.typeID);\r
-        if (hfPl == null) {\r
+        Placeholder ph = s.getPlaceholder();\r
+        if (ph == null) {\r
             return false;\r
         }\r
-\r
-        int plId = hfPl.getPlaceholderId();\r
-        switch (plId) {\r
-            case OEPlaceholderAtom.MasterDate:\r
-            case OEPlaceholderAtom.MasterSlideNumber:\r
-            case OEPlaceholderAtom.MasterFooter:\r
-            case OEPlaceholderAtom.MasterHeader:\r
+        switch (ph) {\r
+            case DATETIME:\r
+            case SLIDE_NUMBER:\r
+            case FOOTER:\r
+            case HEADER:\r
                 return true;\r
             default:\r
                 return false;\r
index 427e2d2c5e3aebcc04873e3db6538cb70c609c5a..fb0b60e44a4d4120b572ad135806571a202800a3 100644 (file)
@@ -17,8 +17,6 @@
 
 package org.apache.poi.hslf.usermodel;
 
-import static org.apache.poi.hslf.usermodel.HSLFTextParagraph.getPropVal;
-
 import java.awt.Color;
 
 import org.apache.poi.hslf.exceptions.HSLFException;
@@ -30,6 +28,7 @@ import org.apache.poi.hslf.model.textproperties.TextPropCollection.TextPropType;
 import org.apache.poi.sl.draw.DrawPaint;
 import org.apache.poi.sl.usermodel.PaintStyle;
 import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
+import org.apache.poi.sl.usermodel.Placeholder;
 import org.apache.poi.sl.usermodel.TextRun;
 import org.apache.poi.util.Internal;
 import org.apache.poi.util.POILogFactory;
@@ -54,6 +53,8 @@ public final class HSLFTextRun implements TextRun {
         * Note - we may share these styles with other RichTextRuns
         */
        private TextPropCollection characterStyle = new TextPropCollection(1, TextPropType.character);
+       
+       private TextPropCollection masterStyle;
 
        /**
         * Create a new wrapper around a rich text string
@@ -80,8 +81,8 @@ public final class HSLFTextRun implements TextRun {
      * @since POI 3.14-Beta1
      */
        @Internal
-    /* package */ void setMasterStyleReference(TextPropCollection characterStyle) {
-        this.characterStyle = characterStyle;
+    /* package */ void setMasterStyleReference(TextPropCollection masterStyle) {
+        this.masterStyle = masterStyle;
     }
  
        
@@ -105,14 +106,16 @@ public final class HSLFTextRun implements TextRun {
        /**
         * Fetch the text, in raw storage form
         */
-       public String getRawText() {
+       @Override
+    public String getRawText() {
                return _runText;
        }
 
        /**
         * Change the text
         */
-       public void setText(String text) {
+       @Override
+    public void setText(String text) {
            if (text == null) {
                throw new HSLFException("text must not be null");
            }
@@ -137,7 +140,9 @@ public final class HSLFTextRun implements TextRun {
        }
 
        protected boolean getFlag(int index) {
-           if (characterStyle == null) return false;
+           if (characterStyle == null) {
+            return false;
+        }
 
                BitMaskTextProp prop = (BitMaskTextProp)characterStyle.findByName(CharFlagsTextProp.NAME);
 
@@ -175,8 +180,8 @@ public final class HSLFTextRun implements TextRun {
         * @param val The value to set for the TextProp
         */
        public void setCharTextPropVal(String propName, Integer val) {
-           HSLFTextParagraph.setPropVal(characterStyle, propName, val);
-           parentParagraph.setDirty();
+           getTextParagraph().setPropVal(characterStyle, masterStyle, propName, val);
+           getTextParagraph().setDirty();
        }
 
 
@@ -256,7 +261,7 @@ public final class HSLFTextRun implements TextRun {
         * @return the percentage of the font size. If the value is positive, it is superscript, otherwise it is subscript
         */
        public int getSuperscript() {
-               TextProp tp = getPropVal(characterStyle, "superscript", parentParagraph);
+               TextProp tp = getTextParagraph().getPropVal(characterStyle, masterStyle, "superscript");
                return tp == null ? 0 : tp.getValue();
        }
 
@@ -271,7 +276,7 @@ public final class HSLFTextRun implements TextRun {
 
     @Override
        public Double getFontSize() {
-        TextProp tp = getPropVal(characterStyle, "font.size", parentParagraph);
+        TextProp tp = getTextParagraph().getPropVal(characterStyle, masterStyle, "font.size");
         return tp == null ? null : (double)tp.getValue();
        }
 
@@ -286,7 +291,7 @@ public final class HSLFTextRun implements TextRun {
         * Gets the font index
         */
        public int getFontIndex() {
-        TextProp tp = getPropVal(characterStyle, "font.index", parentParagraph);
+        TextProp tp = getTextParagraph().getPropVal(characterStyle, masterStyle, "font.index");
         return tp == null ? -1 : tp.getValue();
        }
 
@@ -320,7 +325,7 @@ public final class HSLFTextRun implements TextRun {
                if (sheet == null || slideShow == null) {
                        return _fontFamily;
                }
-        TextProp tp = getPropVal(characterStyle, "font.index,asian.font.index,ansi.font.index,symbol.font.index", parentParagraph);
+        TextProp tp = getTextParagraph().getPropVal(characterStyle, masterStyle, "font.index,asian.font.index,ansi.font.index,symbol.font.index");
         if (tp == null) { return null; }
                return slideShow.getFontCollection().getFontWithId(tp.getValue());
        }
@@ -330,8 +335,10 @@ public final class HSLFTextRun implements TextRun {
         */
        @Override
        public SolidPaint getFontColor() {
-               TextProp tp = getPropVal(characterStyle, "font.color", parentParagraph);
-               if (tp == null) return null;
+               TextProp tp = getTextParagraph().getPropVal(characterStyle, masterStyle, "font.color");
+               if (tp == null) {
+            return null;
+        }
                Color color = HSLFTextParagraph.getColorFromColorIndexStruct(tp.getValue(), parentParagraph.getSheet());
                SolidPaint ps = DrawPaint.createSolidPaint(color);
                return ps;
@@ -374,6 +381,7 @@ public final class HSLFTextRun implements TextRun {
         return parentParagraph;
     }
     
+    @Override
     public TextCap getTextCap() {
         return TextCap.NONE;
     }
@@ -388,6 +396,7 @@ public final class HSLFTextRun implements TextRun {
         return getSuperscript() > 0;
     }
 
+    @Override
     public byte getPitchAndFamily() {
         return 0;
     }
@@ -414,4 +423,20 @@ public final class HSLFTextRun implements TextRun {
         }
         return link;
     }
+    
+    @Override
+    public FieldType getFieldType() {
+        Placeholder ph = getTextParagraph().getParentShape().getPlaceholder();
+        if (ph != null) {
+            switch (ph) {
+            case SLIDE_NUMBER:
+                return FieldType.SLIDE_NUMBER;
+            case DATETIME:
+                return FieldType.DATE_TIME;
+            default:
+                break;
+            }
+        }
+        return null;
+    }
 }
index 2af4c078875ed1fd71d6d6ecd643f009d1ab9bd8..4992d1bd45428bc52edc8af583f630cd0e5732be 100644 (file)
@@ -20,7 +20,6 @@ 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;
@@ -34,10 +33,14 @@ 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.model.textproperties.TextPropCollection;
 import org.apache.poi.hslf.record.EscherTextboxWrapper;
 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.StyleTextPropAtom;
+import org.apache.poi.hslf.record.TextBytesAtom;
+import org.apache.poi.hslf.record.TextCharsAtom;
 import org.apache.poi.hslf.record.TextHeaderAtom;
 import org.apache.poi.sl.draw.DrawFactory;
 import org.apache.poi.sl.draw.DrawTextShape;
@@ -71,12 +74,12 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
         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;
@@ -86,7 +89,9 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
 
         static HSLFTextAnchor fromNativeId(int nativeId) {
             for (HSLFTextAnchor ta : values()) {
-                if (ta.nativeId == nativeId) return ta;
+                if (ta.nativeId == nativeId) {
+                    return ta;
+                }
             }
             return null;
         }
@@ -125,13 +130,13 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
     /**
      * TextRun object which holds actual text and format data
      */
-    protected List<HSLFTextParagraph> _paragraphs = new ArrayList<HSLFTextParagraph>();
+    private List<HSLFTextParagraph> _paragraphs = new ArrayList<HSLFTextParagraph>();
 
     /**
      * Escher container which holds text attributes such as
-     * TextHeaderAtom, TextBytesAtom ot TextCharsAtom, StyleTextPropAtom etc.
+     * TextHeaderAtom, TextBytesAtom or TextCharsAtom, StyleTextPropAtom etc.
      */
-    protected EscherTextboxWrapper _txtbox;
+    private EscherTextboxWrapper _txtbox;
 
     /**
      * This setting is used for supporting a deprecated alignment
@@ -140,11 +145,6 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
      */
 //    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.
      *
@@ -222,10 +222,14 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
     }
 
     protected EscherTextboxWrapper getEscherTextboxWrapper(){
-        if(_txtbox != null) return _txtbox;
+        if(_txtbox != null) {
+            return _txtbox;
+        }
 
         EscherTextboxRecord textRecord = getEscherChild(EscherTextboxRecord.RECORD_ID);
-        if (textRecord == null) return null;
+        if (textRecord == null) {
+            return null;
+        }
 
         HSLFSheet sheet = getSheet();
         if (sheet != null) {
@@ -248,6 +252,66 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
         return _txtbox;
     }
 
+    private void createEmptyParagraph() {
+        TextHeaderAtom tha = (TextHeaderAtom)_txtbox.findFirstOfType(TextHeaderAtom._type);
+        if (tha == null) {
+            tha = new TextHeaderAtom();
+            tha.setParentRecord(_txtbox);
+            _txtbox.appendChildRecord(tha);
+        }
+
+        TextBytesAtom tba = (TextBytesAtom)_txtbox.findFirstOfType(TextBytesAtom._type);
+        TextCharsAtom tca = (TextCharsAtom)_txtbox.findFirstOfType(TextCharsAtom._type);
+        if (tba == null && tca == null) {
+            tba = new TextBytesAtom();
+             tba.setText(new byte[0]);
+             _txtbox.appendChildRecord(tba);
+        }
+
+        final String text = ((tba != null) ? tba.getText() : tca.getText());
+        
+        StyleTextPropAtom sta = (StyleTextPropAtom)_txtbox.findFirstOfType(StyleTextPropAtom._type);
+        TextPropCollection paraStyle = null, charStyle = null;
+        if (sta == null) {
+            int parSiz = text.length();
+            sta = new StyleTextPropAtom(parSiz+1);
+            if (_paragraphs.isEmpty()) {
+                paraStyle = sta.addParagraphTextPropCollection(parSiz+1);
+                charStyle = sta.addCharacterTextPropCollection(parSiz+1);
+            } else {
+                for (HSLFTextParagraph htp : _paragraphs) {
+                    int runsLen = 0;
+                    for (HSLFTextRun htr : htp.getTextRuns()) {
+                        runsLen += htr.getLength();
+                        charStyle = sta.addCharacterTextPropCollection(htr.getLength());
+                        htr.setCharacterStyle(charStyle);
+                    }
+                    paraStyle = sta.addParagraphTextPropCollection(runsLen);
+                    htp.setParagraphStyle(paraStyle);
+                }
+                assert (paraStyle != null && charStyle != null);
+            }
+            _txtbox.appendChildRecord(sta);
+        } else {
+            paraStyle = sta.getParagraphStyles().get(0);
+            charStyle = sta.getCharacterStyles().get(0);
+        }
+
+        if (_paragraphs.isEmpty()) {
+            HSLFTextParagraph htp = new HSLFTextParagraph(tha, tba, tca, _paragraphs);
+            htp.setParagraphStyle(paraStyle);
+            htp.setParentShape(this);
+            _paragraphs.add(htp);
+    
+            HSLFTextRun htr = new HSLFTextRun(htp);
+            htr.setCharacterStyle(charStyle);
+            htr.setText(text);
+            htp.addTextRun(htr);
+        }
+    }
+
+
+    
     /**
      * Adjust the size of the shape so it encompasses the text inside it.
      *
@@ -276,7 +340,9 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
     */
     public int getRunType() {
         getEscherTextboxWrapper();
-        if (_txtbox == null) return -1;
+        if (_txtbox == null) {
+            return -1;
+        }
         List<HSLFTextParagraph> paras = HSLFTextParagraph.findTextParagraphs(_txtbox, getSheet());
         return (paras.isEmpty()) ? -1 : paras.get(0).getRunType();
     }
@@ -289,7 +355,9 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
     */
     public void setRunType(int type) {
         getEscherTextboxWrapper();
-        if (_txtbox == null) return;
+        if (_txtbox == null) {
+            return;
+        }
         List<HSLFTextParagraph> paras = HSLFTextParagraph.findTextParagraphs(_txtbox, getSheet());
         if (!paras.isEmpty()) {
             paras.get(0).setRunType(type);
@@ -562,19 +630,23 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
 
     @Override
     public List<HSLFTextParagraph> getTextParagraphs(){
-        if (!_paragraphs.isEmpty()) return _paragraphs;
+        if (!_paragraphs.isEmpty()) {
+            return _paragraphs;
+        }
 
         _txtbox = getEscherTextboxWrapper();
         if (_txtbox == null) {
-            _paragraphs.addAll(HSLFTextParagraph.createEmptyParagraph());
-            _txtbox = _paragraphs.get(0).getTextboxWrapper();
+            _txtbox = new EscherTextboxWrapper();
+            createEmptyParagraph();
         } else {
-            _paragraphs = HSLFTextParagraph.findTextParagraphs(_txtbox, getSheet());
-            if (_paragraphs == null) {
+            List<HSLFTextParagraph> pList = HSLFTextParagraph.findTextParagraphs(_txtbox, getSheet());
+            if (pList == null) {
                 // there are actually TextBoxRecords without extra data - see #54722
-                _paragraphs = HSLFTextParagraph.createEmptyParagraph(_txtbox);
+                createEmptyParagraph();
+            } else {
+                _paragraphs = pList;
             }
-
+        
             if (_paragraphs.isEmpty()) {
                 LOG.log(POILogger.WARN, "TextRecord didn't contained any text lines");
             }
@@ -587,6 +659,7 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
         return _paragraphs;
     }
 
+
     @Override
     public void setSheet(HSLFSheet sheet) {
         super.setSheet(sheet);
@@ -611,26 +684,30 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
     /**
      * 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
+     * {@link Placeholder#HEADER} or {@link Placeholder#FOOTER}, 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);
     }
-    
+
     @Override
     public boolean isPlaceholder() {
         OEPlaceholderAtom oep = getPlaceholderAtom();
-        if (oep != null) return true;
+        if (oep != null) {
+            return true;
+        }
 
         //special case for files saved in Office 2007
         RoundTripHFPlaceholder12 hldr = getHFPlaceholderAtom();
-        if (hldr != null) return true;
+        if (hldr != null) {
+            return true;
+        }
 
         return false;
     }
@@ -710,7 +787,7 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
         }
         setEscherProperty(opt, EscherProperties.TEXT__TEXTFLOW, msotxfl);
     }
-    
+
     @Override
     public Double getTextRotation() {
         // see 2.4.6 MSOCDIR
@@ -718,7 +795,7 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
         EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.TEXT__FONTROTATION);
         return (prop == null) ? null : (90. * prop.getPropertyValue());
     }
-    
+
     @Override
     public void setTextRotation(Double rotation) {
         AbstractEscherOptRecord opt = getEscherOptRecord();
@@ -729,7 +806,7 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
             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
@@ -751,7 +828,7 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
         List<HSLFTextParagraph> paras = getTextParagraphs();
         HSLFTextRun htr = HSLFTextParagraph.appendText(paras, text, newParagraph);
         setTextId(getRawText().hashCode());
-        return htr; 
+        return htr;
     }
 
     @Override
index b1e38d977b13fd653a78a96eb1417ab8ddcb36fb..2dfd3b05b66e822fb6c0c1af13c19b74c4420ebb 100644 (file)
@@ -25,8 +25,6 @@ import org.apache.poi.hslf.record.SlideAtom;
 
 /**
  * Title masters define the design template for slides with a Title Slide layout.
- *
- * @author Yegor Kozlov
  */
 public final class HSLFTitleMaster extends HSLFMasterSheet {
     private final List<List<HSLFTextParagraph>> _paragraphs = new ArrayList<List<HSLFTextParagraph>>();
@@ -39,13 +37,16 @@ public final class HSLFTitleMaster extends HSLFMasterSheet {
         super(record, sheetNo);
 
         for (List<HSLFTextParagraph> l : HSLFTextParagraph.findTextParagraphs(getPPDrawing(), this)) {
-            if (!_paragraphs.contains(l)) _paragraphs.add(l);
+            if (!_paragraphs.contains(l)) {
+                _paragraphs.add(l);
+            }
         }
     }
 
     /**
      * Returns an array of all the TextRuns found
      */
+    @Override
     public List<List<HSLFTextParagraph>> getTextParagraphs() {
         return _paragraphs;
     }
@@ -53,20 +54,23 @@ public final class HSLFTitleMaster extends HSLFMasterSheet {
     /**
      * Delegate the call to the underlying slide master.
      */
+    @Override
     public TextProp getStyleAttribute(int txtype, int level, String name, boolean isCharacter) {
         HSLFMasterSheet master = getMasterSheet();
-        return master == null ? null : master.getStyleAttribute(txtype, level, name, isCharacter);
+        return (master == null) ? null : master.getStyleAttribute(txtype, level, name, isCharacter);
     }
 
     /**
      * Returns the slide master for this title master.
      */
+    @Override
     public HSLFMasterSheet getMasterSheet(){
-        List<HSLFSlideMaster> master = getSlideShow().getSlideMasters();
         SlideAtom sa = ((org.apache.poi.hslf.record.Slide)getSheetContainer()).getSlideAtom();
         int masterId = sa.getMasterID();
-        for (HSLFSlideMaster sm : master) {
-            if (masterId == sm._getSheetNumber()) return sm;
+        for (HSLFSlideMaster sm : getSlideShow().getSlideMasters()) {
+            if (masterId == sm._getSheetNumber()) {
+                return sm;
+            }
         }
         return null;
     }
index 7e6137ba47626aa50fa36f4336b649a15c1d58d6..c32d37bd652e96091bf9743e9931a75c5967db18 100644 (file)
 
 package org.apache.poi.hslf.record;
 
-import java.io.ByteArrayInputStream;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
 import java.io.ByteArrayOutputStream;
+import java.io.IOException;
 
-import org.apache.poi.hslf.record.SlideAtom.SSlideLayoutAtom;
+import org.apache.poi.hslf.HSLFTestDataSamples;
+import org.apache.poi.hslf.record.SlideAtomLayout.SlideLayoutType;
+import org.apache.poi.hslf.usermodel.HSLFSlide;
 import org.apache.poi.hslf.usermodel.HSLFSlideShow;
-
-import junit.framework.TestCase;
+import org.junit.Test;
 
 /**
  * Tests that SlideAtom works properly
- *
- * @author Nick Burch (nick at torchbox dot com)
  */
-public final class TestSlideAtom extends TestCase {
+public final class TestSlideAtom {
        // From a real file
-       private final byte[] data_a = new byte[] { 1, 0, 0xEF-256, 3, 0x18, 0, 0, 0,
+       private static final byte[] data_a = new byte[] { 1, 0, 0xEF-256, 3, 0x18, 0, 0, 0,
                0, 0, 0, 0, 0x0F, 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80-256,
                0, 1, 0, 0, 7, 0, 0x0C, 0x30 };
 
-    public void testRecordType() {
+       @Test
+       public void testRecordType() {
                SlideAtom sa = new SlideAtom(data_a, 0, data_a.length);
                assertEquals(1007l, sa.getRecordType());
        }
+       
+    @Test
        public void testFlags() {
                SlideAtom sa = new SlideAtom(data_a, 0, data_a.length);
 
                // First 12 bytes are a SSlideLayoutAtom, checked elsewhere
 
                // Check the IDs
-               assertEquals(0x80000000, sa.getMasterID());
+               assertEquals(SlideAtom.USES_MASTER_SLIDE_ID, sa.getMasterID());
                assertEquals(256, sa.getNotesID());
 
                // Check the flags
@@ -54,39 +61,37 @@ public final class TestSlideAtom extends TestCase {
                assertEquals(true, sa.getFollowMasterScheme());
                assertEquals(true, sa.getFollowMasterBackground());
        }
-       public void testSSlideLayoutAtom() {
+
+    @Test
+    public void testSSlideLayoutAtom() {
                SlideAtom sa = new SlideAtom(data_a, 0, data_a.length);
-               SSlideLayoutAtom ssla = sa.getSSlideLayoutAtom();
+               SlideAtomLayout ssla = sa.getSSlideLayoutAtom();
 
-               assertEquals(0, ssla.getGeometryType());
+               assertEquals(SlideLayoutType.TITLE_SLIDE, ssla.getGeometryType());
 
-               // Should also check the placehold IDs at some point
+               // Should also check the placeholder IDs at some point
        }
 
-       public void testWrite() throws Exception {
+    @Test
+       public void testWrite() throws IOException {
                SlideAtom sa = new SlideAtom(data_a, 0, data_a.length);
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                sa.writeOut(baos);
-               byte[] b = baos.toByteArray();
-
-               assertEquals(data_a.length, b.length);
-               for(int i=0; i<data_a.length; i++) {
-                       assertEquals(data_a[i],b[i]);
-               }
+               assertArrayEquals(data_a, baos.toByteArray());
        }
        
-       public void testSSSlideInfoAtom() throws Exception {
-               HSLFSlideShow ss = new HSLFSlideShow();
-               org.apache.poi.hslf.usermodel.HSLFSlide slide1 = ss.createSlide(), slide2 = ss.createSlide();
+    @Test
+       public void testSSSlideInfoAtom() throws IOException {
+               HSLFSlideShow ss1 = new HSLFSlideShow();
+               HSLFSlide slide1 = ss1.createSlide(), slide2 = ss1.createSlide();
                slide2.setHidden(true);
 
-               ByteArrayOutputStream bos = new ByteArrayOutputStream(4096);
-               ss.write(bos);
-               ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
-               ss = new HSLFSlideShow(bis);
-               slide1 = ss.getSlides().get(0);
-               slide2 = ss.getSlides().get(1);
+               HSLFSlideShow ss2 = HSLFTestDataSamples.writeOutAndReadBack(ss1);
+               slide1 = ss2.getSlides().get(0);
+               slide2 = ss2.getSlides().get(1);
                assertFalse(slide1.getHidden());
                assertTrue(slide2.getHidden());
+               ss2.close();
+               ss1.close();
        }
 }
index 8b340079d3e487e6e2e894e4afd6455d611ae09d..df99363dcc2dda866114ba80265e12fe8e06f5f3 100644 (file)
@@ -38,6 +38,7 @@ import java.io.OutputStream;
 import java.io.PrintStream;
 import java.text.AttributedCharacterIterator;
 import java.text.AttributedCharacterIterator.Attribute;
+import java.text.CharacterIterator;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.HashMap;
@@ -466,12 +467,16 @@ public final class TestBugs {
         // get slides
         for (HSLFSlide slide : ppt.getSlides()) {
             for (HSLFShape shape : slide.getShapes()) {
-                if (!(shape instanceof HSLFTextBox)) continue;
+                if (!(shape instanceof HSLFTextBox)) {
+                    continue;
+                }
                 HSLFTextBox tb = (HSLFTextBox) shape;
                 // work with TextBox
                 String str = tb.getText();
 
-                if (!str.contains("$$DATE$$")) continue;
+                if (!str.contains("$$DATE$$")) {
+                    continue;
+                }
                 str = str.replace("$$DATE$$", new Date().toString());
                 tb.setText(str);
 
@@ -512,7 +517,9 @@ public final class TestBugs {
 
         int tha = 0;
         for (Record r : s1.getSlideRecords()) {
-            if (r instanceof TextHeaderAtom) tha++;
+            if (r instanceof TextHeaderAtom) {
+                tha++;
+            }
         }
         assertEquals(2, tha);
 
@@ -525,7 +532,9 @@ public final class TestBugs {
         // Will have skipped the empty one
         int str = 0;
         for (List<HSLFTextParagraph> tr : _slides.get(0).getTextParagraphs()) {
-            if (! tr.get(0).isDrawingBased()) str++;
+            if (! tr.get(0).isDrawingBased()) {
+                str++;
+            }
         }
         assertEquals(2, str);
         
@@ -758,7 +767,7 @@ public final class TestBugs {
     public void bug47904() throws IOException {
         HSLFSlideShow ppt1 = new HSLFSlideShow();
         HSLFSlideMaster sm = ppt1.getSlideMasters().get(0);
-        HSLFAutoShape as = (HSLFAutoShape)sm.getShapes().get(0);
+        HSLFAutoShape as = (HSLFAutoShape)sm.getPlaceholder(Placeholder.TITLE);
         HSLFTextParagraph tp = as.getTextParagraphs().get(0);
         HSLFTextRun tr = tp.getTextRuns().get(0);
         tr.setFontFamily("Tahoma");
@@ -766,8 +775,9 @@ public final class TestBugs {
         tr.setFontSize(44.);
         tr.setFontColor(Color.red);
         tp.setTextAlign(TextAlign.RIGHT);
-        ppt1.createSlide().addTitle().setText("foobaa");
-        
+        HSLFTextBox tb = ppt1.createSlide().addTitle();
+        tb.setText("foobaa");
+
         HSLFSlideShow ppt2 = HSLFTestDataSamples.writeOutAndReadBack(ppt1);
         ppt1.close();
         
@@ -877,7 +887,7 @@ public final class TestBugs {
                 StringBuffer sb = new StringBuffer();
                 
                 for (char c = iterator.first();
-                        c != AttributedCharacterIterator.DONE;
+                        c != CharacterIterator.DONE;
                         c = iterator.next()) {
                     sb.append(c);
                     attributes = iterator.getAttributes();
index a52cee4129fc9095d4d590427598f6f8e13b39d8..baed0386d3ff80bd55f2b840239bd99f44eb02fb 100644 (file)
 package org.apache.poi.hslf.usermodel;
 
 
-import java.util.List;
+import static org.junit.Assert.assertEquals;
 
-import junit.framework.TestCase;
+import java.io.IOException;
+import java.util.List;
 
-import org.apache.poi.POIDataSamples;
+import org.apache.poi.hslf.HSLFTestDataSamples;
+import org.junit.Test;
 
 /**
  * Tests that SlideShow returns the right number of Sheets and MetaSheets
- *
- * @author Nick Burch (nick at torchbox dot com)
  */
-public final class TestCounts extends TestCase {
-       // SlideShow primed on the test data
-       private final HSLFSlideShow ss;
-
-       public TestCounts() throws Exception {
-        POIDataSamples slTests = POIDataSamples.getSlideShowInstance();
-               HSLFSlideShowImpl hss = new HSLFSlideShowImpl(slTests.openResourceAsStream("basic_test_ppt_file.ppt"));
-               ss = new HSLFSlideShow(hss);
-       }
-
-       public void testSheetsCount() {
-               List<HSLFSlide> slides = ss.getSlides();
+public final class TestCounts {
+    @Test
+       public void testSheetsCount() throws IOException {
+           HSLFSlideShow ppt = HSLFTestDataSamples.getSlideShow("basic_test_ppt_file.ppt");
+           
+               List<HSLFSlide> slides = ppt.getSlides();
                // Two sheets - master sheet is separate
                assertEquals(2, slides.size());
 
@@ -55,10 +49,15 @@ public final class TestCounts extends TestCase {
                // These are slides 1+2 -> 256+257
                assertEquals(256, slides.get(0)._getSheetNumber());
                assertEquals(257, slides.get(1)._getSheetNumber());
+               
+               ppt.close();
        }
 
-       public void testNotesCount() {
-               List<HSLFNotes> notes = ss.getNotes();
+    @Test
+    public void testNotesCount() throws IOException {
+        HSLFSlideShow ppt = HSLFTestDataSamples.getSlideShow("basic_test_ppt_file.ppt");
+        
+               List<HSLFNotes> notes = ppt.getNotes();
                // Two sheets -> two notes
                // Note: there are also notes on the slide master
                //assertEquals(3, notes.length); // When we do slide masters
@@ -74,5 +73,7 @@ public final class TestCounts extends TestCase {
                // They happen to go between the two slides in Ref terms
                assertEquals(5, notes.get(0)._getSheetRefId());
                assertEquals(7, notes.get(1)._getSheetRefId());
+               
+               ppt.close();
        }
 }