]> source.dussan.org Git - poi.git/commitdiff
support for text bullets
authorYegor Kozlov <yegor@apache.org>
Mon, 28 May 2007 09:45:09 +0000 (09:45 +0000)
committerYegor Kozlov <yegor@apache.org>
Mon, 28 May 2007 09:45:09 +0000 (09:45 +0000)
git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@542179 13f79535-47bb-0310-9956-ffa450edef68

src/documentation/content/xdocs/hslf/how-to-shapes.xml
src/scratchpad/examples/src/org/apache/poi/hslf/examples/BulletsDemo.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hslf/model/textproperties/CharFlagsTextProp.java
src/scratchpad/src/org/apache/poi/hslf/model/textproperties/ParagraphFlagsTextProp.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java
src/scratchpad/src/org/apache/poi/hslf/record/TxMasterStyleAtom.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/RichTextRun.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java
src/scratchpad/testcases/org/apache/poi/hslf/data/bullets.ppt [new file with mode: 0644]
src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestRichTextRun.java

index fd3d6c3bb6c00cb034c339a66e2c0622cb338472..74e921f8fe192d3ba22f615431dbf644333f4c1a 100644 (file)
@@ -37,6 +37,7 @@
                     <li><link href="#Pictures">How to work with pictures</link></li>
                     <li><link href="#SlideTitle">How to set slide title</link></li>
                     <li><link href="#Fill">How to work with slide/shape background</link></li>
+                    <li><link href="#Bullets">How to create bulleted lists</link></li>
                 </ul>
             </section>
             <section><title>Features</title>
         slide.addShape(shape);
                   </source>
                 </section>
+                <anchor id="Bullets"/>
+                <section><title>How to create bulleted lists</title>
+                    <source>
+        SlideShow ppt = new SlideShow();
+
+        Slide slide = ppt.createSlide();
+
+        TextBox shape = new TextBox();
+        RichTextRun rt = shape.getTextRun().getRichTextRuns()[0];
+        shape.setText(
+                "January\r" +
+                "February\r" +
+                "March\r" +
+                "April");
+        rt.setFontSize(42);
+        rt.setBullet(true);
+        rt.setBulletOffset(0);  //bullet offset
+        rt.setTextOffset(50);   //text offset (should be greater than bullet offset)
+        rt.setBulletChar('\u263A'); //bullet character
+        slide.addShape(shape);
+
+        shape.setAnchor(new java.awt.Rectangle(50, 50, 500, 300));  //position of the text box in the slide
+        slide.addShape(shape);
+
+        FileOutputStream out = new FileOutputStream("bullets.ppt");
+        ppt.write(out);
+        out.close();
+                  </source>
+                </section>
                   
             </section>
         </section>
diff --git a/src/scratchpad/examples/src/org/apache/poi/hslf/examples/BulletsDemo.java b/src/scratchpad/examples/src/org/apache/poi/hslf/examples/BulletsDemo.java
new file mode 100644 (file)
index 0000000..a455971
--- /dev/null
@@ -0,0 +1,62 @@
+\r
+/* ====================================================================\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to You under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+==================================================================== */\r
+package org.apache.poi.hslf.examples;\r
+\r
+import org.apache.poi.hslf.usermodel.SlideShow;\r
+import org.apache.poi.hslf.usermodel.RichTextRun;\r
+import org.apache.poi.hslf.model.Slide;\r
+import org.apache.poi.hslf.model.TextBox;\r
+\r
+import java.io.FileOutputStream;\r
+\r
+/**\r
+ * How to create a single-level bulleted list\r
+ * and change some of the bullet attributes\r
+ *\r
+ * @author Yegor Kozlov\r
+ */\r
+public class BulletsDemo {\r
+\r
+    public static void main(String[] args) throws Exception {\r
+\r
+        SlideShow ppt = new SlideShow();\r
+\r
+        Slide slide = ppt.createSlide();\r
+\r
+        TextBox shape = new TextBox();\r
+        RichTextRun rt = shape.getTextRun().getRichTextRuns()[0];\r
+        shape.setText(\r
+                "January\r" +\r
+                "February\r" +\r
+                "March\r" +\r
+                "April");\r
+        rt.setFontSize(42);\r
+        rt.setBullet(true);\r
+        rt.setBulletOffset(0);  //bullet offset\r
+        rt.setTextOffset(50);   //text offset (should be greater than bullet offset)\r
+        rt.setBulletChar('\u263A'); //bullet character\r
+        slide.addShape(shape);\r
+\r
+        shape.setAnchor(new java.awt.Rectangle(50, 50, 500, 300));  //position of the text box in the slide\r
+        slide.addShape(shape);\r
+\r
+        FileOutputStream out = new FileOutputStream("bullets.ppt");\r
+        ppt.write(out);\r
+        out.close();\r
+   }\r
+}\r
index 9466194a9116ea4130b19ffca76ad006a26dbdbb..a78c2c27e531d813aab91fe00a1b075f68221f31 100644 (file)
@@ -32,8 +32,9 @@ public class CharFlagsTextProp extends BitMaskTextProp {
        public static final int ENABLE_NUMBERING_1_IDX = 11;
        public static final int ENABLE_NUMBERING_2_IDX = 12;
 
+    public static String NAME = "char_flags";
        public CharFlagsTextProp() {
-               super(2,0xffff, "char_flags", new String[] {
+               super(2,0xffff, NAME, new String[] {
                                "bold",          // 0x0001
                                "italic",        // 0x0002
                                "underline",     // 0x0004
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/ParagraphFlagsTextProp.java b/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/ParagraphFlagsTextProp.java
new file mode 100644 (file)
index 0000000..0ea21b2
--- /dev/null
@@ -0,0 +1,41 @@
+/* ====================================================================\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to You under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+==================================================================== */\r
+\r
+package org.apache.poi.hslf.model.textproperties;\r
+\r
+/** \r
+ * Definition for the common paragraph text property bitset.\r
+ *\r
+ * @author Yegor Kozlov\r
+ */\r
+public class ParagraphFlagsTextProp extends BitMaskTextProp {\r
+       public static final int BULLET_IDX = 0;\r
+       public static final int BULLET_HARDFONT_IDX = 1;\r
+       public static final int BULLET_HARDCOLOR_IDX = 2;\r
+       public static final int BULLET_HARDSIZE_IDX = 4;\r
+\r
+    public static String NAME = "paragraph_flags";\r
+\r
+       public ParagraphFlagsTextProp() {\r
+               super(2,  0xF, NAME, new String[] {\r
+                                       "bullet",\r
+                    "bullet.hardfont",\r
+                                       "bullet.hardcolor",\r
+                    "bullet.hardsize"}\r
+               );\r
+       }\r
+}
\ No newline at end of file
index 41fbb698b61b5ff4990a9b9721f7d5e0c5431a6e..32f8b2bd03789b6c38a05b052573e3cf0db68049 100644 (file)
 
 package org.apache.poi.hslf.record;
 
-import org.apache.poi.hslf.model.textproperties.AlignmentTextProp;
-import org.apache.poi.hslf.model.textproperties.BitMaskTextProp;
-import org.apache.poi.hslf.model.textproperties.CharFlagsTextProp;
-import org.apache.poi.hslf.model.textproperties.TextProp;
-import org.apache.poi.hslf.model.textproperties.TextPropCollection;
+import org.apache.poi.hslf.model.textproperties.*;
 import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.POILogger;
 
@@ -95,18 +91,15 @@ public class StyleTextPropAtom extends RecordAtom
 
        /** All the different kinds of paragraph properties we might handle */
        public static TextProp[] paragraphTextPropTypes = new TextProp[] {
-                               new BitMaskTextProp(2,  0xF, "paragraph_flags", new String[] {
-                                       "bullet", "bullet.hardfont", 
-                                       "bullet.hardcolor", "bullet.hardsize"}
-                               ),
+                               new ParagraphFlagsTextProp(),
                 new TextProp(2, 0x80, "bullet.char"),
                                new TextProp(2, 0x10, "bullet.font"),
                                new TextProp(4, 0x20, "bullet.color"),
                                new TextProp(2, 0x40, "bullet.size"),
                 new AlignmentTextProp(),
-                new TextProp(2, 0x400, "bullet.offset"),
-                               new TextProp(2, 0x200, "para_unknown_2"),
                 new TextProp(2, 0x100, "text.offset"),
+                               new TextProp(2, 0x200, "para_unknown_2"),
+                new TextProp(2, 0x400, "bullet.offset"),
                                new TextProp(2, 0x1000, "linespacing"),
                                new TextProp(2, 0x2000, "spacebefore"),
                                new TextProp(2, 0x4000, "spaceafter"),
index 12c8c1f6e23da844419dd1d53cc843783085258f..c3025fb4be581ed972ed1a9b61811710184cbc99 100644 (file)
@@ -23,10 +23,7 @@ import org.apache.poi.util.LittleEndian;
 import java.io.OutputStream;
 import java.io.IOException;
 
-import org.apache.poi.hslf.model.textproperties.BitMaskTextProp;
-import org.apache.poi.hslf.model.textproperties.CharFlagsTextProp;
-import org.apache.poi.hslf.model.textproperties.TextProp;
-import org.apache.poi.hslf.model.textproperties.TextPropCollection;
+import org.apache.poi.hslf.model.textproperties.*;
 
 /**
  * TxMasterStyleAtom atom (4003).
@@ -177,10 +174,7 @@ public class TxMasterStyleAtom extends RecordAtom {
             return StyleTextPropAtom.paragraphTextPropTypes;
         } else {
             return new TextProp[] {
-                    new BitMaskTextProp(2,  0xF, "paragraph_flags", new String[] {
-                        "bullet", "bullet.hardfont",
-                        "bullet.hardcolor", "bullet.hardsize"}
-                    ),
+                    new ParagraphFlagsTextProp(),
                     new TextProp(2, 0x80, "bullet.char"),
                     new TextProp(2, 0x10, "bullet.font"),
                     new TextProp(2, 0x40, "bullet.size"),
index a9028cfab2d9259fd616d5b0db5775a3a1c56484..0ee01b9a96e7af19ea2bc01aee60129969cc4978 100644 (file)
 
 package org.apache.poi.hslf.usermodel;
 
-import org.apache.poi.hslf.model.TextRun;
-import org.apache.poi.hslf.model.Sheet;
-import org.apache.poi.hslf.model.SlideMaster;
-import org.apache.poi.hslf.model.MasterSheet;
-import org.apache.poi.hslf.model.textproperties.CharFlagsTextProp;
-import org.apache.poi.hslf.model.textproperties.TextProp;
-import org.apache.poi.hslf.model.textproperties.TextPropCollection;
-import org.apache.poi.hslf.model.textproperties.BitMaskTextProp;
+import org.apache.poi.hslf.model.*;
+import org.apache.poi.hslf.model.Shape;
+import org.apache.poi.hslf.model.textproperties.*;
 import org.apache.poi.hslf.record.ColorSchemeAtom;
+import org.apache.poi.hslf.exceptions.HSLFException;
 
 import java.awt.*;
 
+
 /**
  * Represents a run of text, all with the same style
  * 
@@ -164,36 +161,63 @@ public class RichTextRun
         *  text property won't be set if there's no CharFlagsTextProp.
         */
        private boolean isCharFlagsTextPropVal(int index) {
-        CharFlagsTextProp cftp = null;
-        if (characterStyle != null){
-            cftp = (CharFlagsTextProp)characterStyle.findByName("char_flags");
+               return getFlag(true, index);
+       }
+
+    private boolean getFlag(boolean isCharacter, int index) {
+        TextPropCollection props;
+        String propname;
+        if (isCharacter){
+            props = characterStyle;
+            propname = CharFlagsTextProp.NAME;
+        } else {
+            props = paragraphStyle;
+            propname = ParagraphFlagsTextProp.NAME;
+        }
+
+        BitMaskTextProp prop = null;
+        if (props != null){
+            prop = (BitMaskTextProp)props.findByName(propname);
         }
-        if (cftp == null){
+        if (prop == null){
             Sheet sheet = parentRun.getSheet();
             int txtype = parentRun.getRunType();
             MasterSheet master = sheet.getMasterSheet();
             if (master != null)
-                cftp = (CharFlagsTextProp)master.getStyleAttribute(txtype, getIndentLevel(), "char_flags", true);
+                prop = (BitMaskTextProp)master.getStyleAttribute(txtype, getIndentLevel(), propname, isCharacter);
         }
 
-               return cftp == null ? false : cftp.getSubValue(index);
-       }
+        return prop == null ? false : prop.getSubValue(index);
+    }
 
        /**
         * Set the value of the given flag in the CharFlagsTextProp, adding
         *  it if required. 
         */
        private void setCharFlagsTextPropVal(int index, boolean value) {
+        setFlag(true, index, value);
+       }
+
+    private void setFlag(boolean isCharacter, int index, boolean value) {
+        TextPropCollection props;
+        String propname;
+        if (isCharacter){
+            props = characterStyle;
+            propname = CharFlagsTextProp.NAME;
+        } else {
+            props = paragraphStyle;
+            propname = ParagraphFlagsTextProp.NAME;
+        }
+
                // Ensure we have the StyleTextProp atom we're going to need
-               if(characterStyle == null) {
+               if(props == null) {
                        parentRun.ensureStyleAtomPresent();
-                       // characterStyle will now be defined
+            props = isCharacter ? characterStyle : paragraphStyle;
                }
-               
-               CharFlagsTextProp cftp = (CharFlagsTextProp)
-                       fetchOrAddTextProp(characterStyle, "char_flags");
-               cftp.setSubValue(value,index);
-       }
+
+               BitMaskTextProp prop = (BitMaskTextProp) fetchOrAddTextProp(props, propname);
+               prop.setSubValue(value,index);
+    }
 
        /**
         * Returns the named TextProp, either by fetching it (if it exists) or adding it
@@ -396,7 +420,62 @@ public class RichTextRun
     public int getIndentLevel() {
         return paragraphStyle == null ? 0 : paragraphStyle.getReservedField();
     }
-       
+
+    /**
+     * Sets whether this rich text run has bullets
+     */
+    public void setBullet(boolean flag) {
+        setFlag(false, ParagraphFlagsTextProp.BULLET_IDX, flag);
+    }
+
+    /**
+     * Returns whether this rich text run has bullets
+     */
+    public boolean isBullet() {
+        return getFlag(false, ParagraphFlagsTextProp.BULLET_IDX);
+    }
+
+    /**
+     * Sets the bullet character
+     */
+    public void setBulletChar(char c) {
+        setParaTextPropVal("bullet.char", c);
+    }
+
+    /**
+     * Returns the bullet character
+     */
+    public char getBulletChar() {
+        return (char)getParaTextPropVal("bullet.char");
+    }
+
+    /**
+     * Sets the bullet offset
+     */
+    public void setBulletOffset(int offset) {
+        setParaTextPropVal("bullet.offset", offset*Shape.MASTER_DPI/Shape.POINT_DPI);
+    }
+
+    /**
+     * Returns the bullet offset
+     */
+    public int getBulletOffset() {
+        return getParaTextPropVal("bullet.offset")*Shape.POINT_DPI/Shape.MASTER_DPI;
+    }
+
+    /**
+     * Sets the text offset
+     */
+    public void setTextOffset(int offset) {
+        setParaTextPropVal("text.offset", offset*Shape.MASTER_DPI/Shape.POINT_DPI);
+    }
+
+    /**
+     * Returns the text offset
+     */
+    public int getTextOffset() {
+        return getParaTextPropVal("text.offset")*Shape.POINT_DPI/Shape.MASTER_DPI;
+    }
        // --------------- Internal HSLF methods, not intended for end-user use! -------
        
        /**
index e77f9ff13e72b55afd79f2c8320cafd5230b323a..4f4e9e96d899ef7f2b0b8f88070f85c531a5a369 100644 (file)
@@ -119,7 +119,14 @@ public class SlideShow
   public SlideShow() throws IOException {
        this(new HSLFSlideShow());
   }
-  
+
+    /**
+     * Constructs a Powerpoint document from an input stream.
+     */
+    public SlideShow(InputStream inputStream) throws IOException {
+      this(new HSLFSlideShow(inputStream));
+    }
+
   /**
    * Find the records that are parent-aware, and tell them
    *  who their parent is
diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/data/bullets.ppt b/src/scratchpad/testcases/org/apache/poi/hslf/data/bullets.ppt
new file mode 100644 (file)
index 0000000..be2f8bb
Binary files /dev/null and b/src/scratchpad/testcases/org/apache/poi/hslf/data/bullets.ppt differ
index 6f4e128c8b8d77af95c9745cbc976c51eb774603..2450c66c08c1a910c9dcef4820a54fcec95b878c 100644 (file)
 */
 package org.apache.poi.hslf.usermodel;
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.FileInputStream;
-import java.io.File;
+import java.io.*;
+import java.awt.*;
 
 import org.apache.poi.hslf.HSLFSlideShow;
-import org.apache.poi.hslf.model.Slide;
-import org.apache.poi.hslf.model.TextRun;
-import org.apache.poi.hslf.model.SlideMaster;
+import org.apache.poi.hslf.model.*;
 import org.apache.poi.hslf.record.Record;
 import org.apache.poi.hslf.record.SlideListWithText;
 
@@ -458,4 +454,99 @@ if(false) {
             }
         }
     }
+
+    public void testReadParagraphStyles() throws Exception {
+        FileInputStream is = new FileInputStream(new File(System.getProperty("HSLF.testdata.path"), "bullets.ppt"));
+        SlideShow ppt = new SlideShow(is);
+        is.close();
+        assertTrue("No Exceptions while reading file", true);
+
+        RichTextRun rt;
+        TextRun[] txt;
+        Slide[] slide = ppt.getSlides();
+        assertEquals(2, slide.length);
+
+        txt = slide[0].getTextRuns();
+        assertEquals(2, txt.length);
+
+        assertEquals("Title text", txt[0].getRawText());
+        assertEquals(1, txt[0].getRichTextRuns().length);
+        rt = txt[0].getRichTextRuns()[0];
+        assertFalse(rt.isBullet());
+
+        assertEquals(
+                "This is a text placeholder that \r" +
+                "follows the design pattern\r" +
+                "Defined in the slide master\r" +
+                "and has bullets by default", txt[1].getRawText());
+        assertEquals(1, txt[1].getRichTextRuns().length);
+        rt = txt[1].getRichTextRuns()[0];
+        assertEquals('\u2022', rt.getBulletChar());
+        assertTrue(rt.isBullet());
+
+
+        txt = slide[1].getTextRuns();
+        assertEquals(2, txt.length);
+
+        assertEquals(
+                "I\92m a text box\r" +
+                "With bullets\r" +
+                "That follow the design pattern\r" +
+                "From the slide master", txt[0].getRawText());
+        assertEquals(1, txt[0].getRichTextRuns().length);
+        rt = txt[0].getRichTextRuns()[0];
+        assertTrue(rt.isBullet());
+        assertEquals('\u2022', rt.getBulletChar());
+
+        assertEquals(
+                "I\92m a text box with user-defined\r" +
+                "bullet character", txt[1].getRawText());
+        assertEquals(1, txt[1].getRichTextRuns().length);
+        rt = txt[1].getRichTextRuns()[0];
+        assertTrue(rt.isBullet());
+        assertEquals('\u263A', rt.getBulletChar());
+    }
+
+    public void testSetParagraphStyles() throws Exception {
+        SlideShow ppt = new SlideShow();
+
+        Slide slide = ppt.createSlide();
+
+        TextBox shape = new TextBox();
+        RichTextRun rt = shape.getTextRun().getRichTextRuns()[0];
+        shape.setText(
+                "Hello, World!\r" +
+                "This should be\r" +
+                "Multiline text");
+        rt.setFontSize(42);
+        rt.setBullet(true);
+        rt.setTextOffset(50);
+        rt.setBulletOffset(0);
+        rt.setBulletChar('\u263A');
+        slide.addShape(shape);
+
+        assertEquals(42, rt.getFontSize());
+        assertEquals(true, rt.isBullet());
+        assertEquals(50, rt.getTextOffset());
+        assertEquals(0, rt.getBulletOffset());
+        assertEquals('\u263A', rt.getBulletChar());
+
+        shape.setAnchor(new java.awt.Rectangle(50, 50, 500, 300));
+        slide.addShape(shape);
+
+        //serialize and read again
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        ppt.write(out);
+        out.close();
+
+        ppt = new SlideShow(new ByteArrayInputStream(out.toByteArray()));
+        slide = ppt.getSlides()[0];
+        shape = (TextBox)slide.getShapes()[0];
+        rt = shape.getTextRun().getRichTextRuns()[0];
+        assertEquals(42, rt.getFontSize());
+        assertEquals(true, rt.isBullet());
+        assertEquals(50, rt.getTextOffset());
+        assertEquals(0, rt.getBulletOffset());
+        assertEquals('\u263A', rt.getBulletChar());
+    }
 }