Author: nick
Date: Mon May  8 09:43:11 2006
New Revision: 405092

URL: http://svn.apache.org/viewcvs?rev=405092&view=rev
Log:
Fixes from Yegor, from bug #39395

Added:
    
jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Placeholder.java
    
jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/OEPlaceholderAtom.java
    
jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/OutlineTextRefAtom.java
Removed:
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Ellipse.java
    
jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Rectangle.java
Modified:
    jakarta/poi/trunk/src/documentation/content/xdocs/hslf/how-to-shapes.xml
    jakarta/poi/trunk/src/documentation/content/xdocs/hslf/hslf_shapes.gif
    
jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java
    
jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Slide.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java
    
jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java
    
jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/RichTextRun.java
    
jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java

Modified: 
jakarta/poi/trunk/src/documentation/content/xdocs/hslf/how-to-shapes.xml
URL: 
http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/documentation/content/xdocs/hslf/how-to-shapes.xml?rev=405092&r1=405091&r2=405092&view=diff
==============================================================================
--- jakarta/poi/trunk/src/documentation/content/xdocs/hslf/how-to-shapes.xml 
(original)
+++ jakarta/poi/trunk/src/documentation/content/xdocs/hslf/how-to-shapes.xml 
Mon May  8 09:43:11 2006
@@ -18,6 +18,7 @@
                     <li><link href="#GetShapes">How to get shapes contained in 
a particular slide</link></li>
                     <li><link href="#Shapes">Drawing a shape on a 
slide</link></li>
                     <li><link href="#Pictures">How to add/retrieve 
pictures</link></li>
+                    <li><link href="#SlideTitle">How to set slide 
title</link></li>
                 </ul>
             </section>
             <section><title>Features</title>
@@ -62,7 +63,7 @@
                     The following pictute shows the class tree of HSLF shapes:
                   </p>
                   <p>
-                    <img src="hslf_shapes.gif" alt="Class Tree of HSLF Shapes" 
width="611" height="285"/>
+                    <img src="hslf_shapes.gif" alt="Class Tree of HSLF Shapes" 
width="611" height="412"/>
                   </p>
                   <p>
                     The following fragment demonstrates how to iterate over 
shapes for each slide.
@@ -209,6 +210,28 @@
 
                     </source>
                 </section>
+                <anchor id="SlideTitle"/>
+                <section><title>How to set slide title</title>
+                    <source>
+    SlideShow ppt = new SlideShow();
+    Slide slide = ppt.createSlide();
+    TextBox title = slide.addTitle();
+    title.setText("Hello, World!");
+    
+    //save changes 
+    FileOutputStream out = new FileOutputStream("slideshow.ppt");
+    wb.write(out);
+    out.close();
+                  </source>
+                  <p>
+                    Below is the equivalent code in PowerPoint VBA:
+                  </p>  
+                  <source>
+    Set myDocument = ActivePresentation.Slides(1)
+    myDocument.Shapes.AddTitle.TextFrame.TextRange.Text = "Hello, World!"
+                  </source>
+                </section>
+                  
             </section>
         </section>
     </body>

Modified: jakarta/poi/trunk/src/documentation/content/xdocs/hslf/hslf_shapes.gif
URL: 
http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/documentation/content/xdocs/hslf/hslf_shapes.gif?rev=405092&r1=405091&r2=405092&view=diff
==============================================================================
Binary files - no diff available.

Modified: 
jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java
URL: 
http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java?rev=405092&r1=405091&r2=405092&view=diff
==============================================================================
--- 
jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java
 (original)
+++ 
jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java
 Mon May  8 09:43:11 2006
@@ -151,7 +151,7 @@
          if (font != null){
              txt.setFontSize(font.getSize());
              txt.setFontName(font.getName());
-             //if(getColor() != null) txt.setFontColor(getColor());
+             if(getColor() != null) txt.setFontColor(getColor());
              if (font.isBold()) txt.setBold(true);
              if (font.isItalic()) txt.setItalic(true);
          }

Added: 
jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Placeholder.java
URL: 
http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Placeholder.java?rev=405092&view=auto
==============================================================================
--- 
jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Placeholder.java 
(added)
+++ 
jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Placeholder.java 
Mon May  8 09:43:11 2006
@@ -0,0 +1,97 @@
+/* ====================================================================
+   Copyright 2002-2004   Apache Software Foundation
+
+   Licensed 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.model;
+
+import org.apache.poi.ddf.*;
+import org.apache.poi.hslf.record.OEPlaceholderAtom;
+
+import java.util.List;
+import java.io.ByteArrayOutputStream;
+
+/**
+ * Represents a Placeholder in PowerPoint.
+ *
+ * @author Yegor Kozlov
+ */
+public class Placeholder extends TextBox {
+
+    protected Placeholder(EscherContainerRecord escherRecord, Shape parent){
+        super(escherRecord, parent);
+    }
+
+    public Placeholder(Shape parent){
+        super(parent);
+    }
+
+    public Placeholder(){
+        super();
+    }
+
+    /**
+     * Create a new Placeholder and initialize internal structures
+     *
+     * @return the created <code>EscherContainerRecord</code> which holds 
shape data
+     */
+    protected EscherContainerRecord createSpContainer(boolean isChild){
+        EscherContainerRecord spcont = super.createSpContainer(isChild);
+
+        EscherSpRecord spRecord = 
spcont.getChildById(EscherSpRecord.RECORD_ID);
+        spRecord.setFlags(EscherSpRecord.FLAG_HAVEANCHOR | 
EscherSpRecord.FLAG_HAVEMASTER);
+
+        EscherClientDataRecord cldata = new EscherClientDataRecord();
+        cldata.setOptions((short)15);
+
+        EscherOptRecord opt = (EscherOptRecord)getEscherChild(spcont, 
EscherOptRecord.RECORD_ID);
+
+        //Placeholders can't be grouped
+        setEscherProperty(opt, 
EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 262144);
+
+        //OEPlaceholderAtom tells powerpoint that this shape is a placeholder
+        //
+        OEPlaceholderAtom oep = new OEPlaceholderAtom();
+        /**
+         * Extarct from MSDN:
+         *
+         * There is a special case when the placeholder does not have a 
position in the layout.
+         * This occurs when the user has moved the placeholder from its 
original position.
+         * In this case the placeholder ID is -1.
+         */
+        oep.setPlacementId(-1);
+
+        oep.setPlaceholderId(OEPlaceholderAtom.Body);
+
+        //convert hslf into ddf record
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        try {
+            oep.writeOut(out);
+        } catch(Exception e){
+            throw new RuntimeException(e);
+        }
+        cldata.setRemainingData(out.toByteArray());
+
+        //append placeholder container before EscherTextboxRecord
+        List lst = spcont.getChildRecords();
+        for (int i = 0; i < lst.size(); i++) {
+              EscherRecord rec = (EscherRecord)lst.get(i);
+              if(rec.getRecordId() == EscherTextboxRecord.RECORD_ID){
+                  lst.add(i++, cldata);
+              }
+        }
+
+        return spcont;
+    }
+}

Modified: 
jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java
URL: 
http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java?rev=405092&r1=405091&r2=405092&view=diff
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java 
(original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java 
Mon May  8 09:43:11 2006
@@ -113,8 +113,26 @@
     }
 
     /**
+     * @return type of the shape.
+     * @see org.apache.poi.hslf.record.RecordTypes
+     */
+    public int getShapeType(){
+        EscherSpRecord spRecord = 
_escherContainer.getChildById(EscherSpRecord.RECORD_ID);
+        return spRecord.getOptions() >> 4;
+    }
+
+    /**
+     * @param type type of the shape.
+     * @see org.apache.poi.hslf.record.RecordTypes
+     */
+    public void setShapeType(int type){
+        EscherSpRecord spRecord = 
_escherContainer.getChildById(EscherSpRecord.RECORD_ID);
+        spRecord.setOptions((short)(type << 4 | 0x2));
+    }
+
+    /**
      * Returns the anchor (the bounding box rectangle) of this shape.
-     * All coordinates are expressed in Master units (576 dpi).
+     * All coordinates are expressed in points (72 dpi).
      *
      * @return the anchor of this shape
      */
@@ -143,7 +161,7 @@
 
     /**
      * Sets the anchor (the bounding box rectangle) of this shape.
-     * All coordinates should be expressed in poitns (72 dpi).
+     * All coordinates should be expressed in points (72 dpi).
      *
      * @param anchor new anchor
      */

Modified: 
jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java
URL: 
http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java?rev=405092&r1=405091&r2=405092&view=diff
==============================================================================
--- 
jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java
 (original)
+++ 
jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java
 Mon May  8 09:43:11 2006
@@ -15,8 +15,7 @@
 ==================================================================== */
 package org.apache.poi.hslf.model;
 
-import org.apache.poi.ddf.EscherSpRecord;
-import org.apache.poi.ddf.EscherContainerRecord;
+import org.apache.poi.ddf.*;
 
 /**
  * Create a <code>Shape</code> object depending on its type
@@ -38,11 +37,18 @@
 
         int type = spRecord.getOptions() >> 4;
         switch (type){
+            case ShapeTypes.Rectangle:
+                EscherTextboxRecord txtbox = 
(EscherTextboxRecord)Shape.getEscherChild(spContainer, 
EscherTextboxRecord.RECORD_ID);
+                if (txtbox == null) shape = new AutoShape(spContainer, parent);
+                else{
+                    if(Shape.getEscherChild(spContainer, 
EscherClientDataRecord.RECORD_ID) != null )
+                        shape = new Placeholder(spContainer, parent);
+                    else
+                        shape = new TextBox(spContainer, parent);
+                }
+                break;
             case ShapeTypes.TextBox:
                 shape = new TextBox(spContainer, parent);
-                break;
-            case ShapeTypes.Rectangle:
-                shape = new Rectangle(spContainer, parent);
                 break;
             case ShapeTypes.PictureFrame:
                 shape = new Picture(spContainer, parent);

Modified: 
jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Slide.java
URL: 
http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Slide.java?rev=405092&r1=405091&r2=405092&view=diff
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Slide.java 
(original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Slide.java 
Mon May  8 09:43:11 2006
@@ -23,6 +23,7 @@
 
 import org.apache.poi.hslf.record.PPDrawing;
 import org.apache.poi.hslf.record.SlideAtom;
+import org.apache.poi.hslf.record.TextHeaderAtom;
 import org.apache.poi.hslf.record.SlideListWithText.SlideAtomsSet;
 
 /**
@@ -117,6 +118,21 @@
                sa.setNotesID(notes._getSheetNumber());
        }
   }
+  
+  /**
+   * Create a <code>TextBox</code> object that represents the slide's title.
+   *
+   * @return <code>TextBox</code> object that represents the slide's title.
+   */
+  public TextBox addTitle() {
+         Placeholder pl = new Placeholder();
+         pl.setShapeType(ShapeTypes.Rectangle);
+         pl.setTextType(TextHeaderAtom.TITLE_TYPE);
+         pl.setText("Click to edit title");
+         pl.setAnchor(new java.awt.Rectangle(54, 48, 612, 90));
+         addShape(pl);
+         return pl;
+  }
 
 
   // Accesser methods follow
@@ -133,7 +149,7 @@
   public int _getSheetRefId() { return _refSheetNo; }
   /**
    * Returns the (internal, SlideIdentifier based) sheet number
-   * @see getSlideNumber()
+   * @see #getSlideNumber()
    */
   public int _getSheetNumber() { return _sheetNo; }
   
@@ -152,5 +168,14 @@
    */
   public Notes getNotesSheet() { return _notes; }
   
+  /**
+   * Returns the PPDrawing associated with this slide, or null if there isn't 
one
+   */
   protected PPDrawing getPPDrawing() { return _slide.getPPDrawing(); }
+  
+  /**
+   * @return set of records inside <code>SlideListWithtext</code> container
+   *  which hold text data for this slide (typically for placeholders).
+   */
+  protected SlideAtomsSet getSlideAtomsSet() { return _atomSet;  }
 } 

Modified: 
jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java
URL: 
http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java?rev=405092&r1=405091&r2=405092&view=diff
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java 
(original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java 
Mon May  8 09:43:11 2006
@@ -85,6 +85,8 @@
      */
     protected EscherTextboxWrapper _txtbox;
 
+    private String _fontname;
+
     /**
      * Create a TextBox object and initialize it from the supplied Record 
container.
      * 
@@ -96,17 +98,6 @@
 
         EscherTextboxRecord textbox = 
(EscherTextboxRecord)Shape.getEscherChild(_escherContainer, 
EscherTextboxRecord.RECORD_ID);
         _txtbox = new EscherTextboxWrapper(textbox);
-        
-        // Find our TextRun
-        Vector v = new Vector();
-        Sheet.findTextRuns(_txtbox.getChildRecords(), v);
-        
-        // We should just have one
-        if(v.size() == 1) {
-               _txtrun = (TextRun)v.get(0);
-        } else {
-               throw new IllegalStateException("A TextBox should have one 
TextRun's worth of records in it, found " + v.size());
-        }
     }
 
     /**
@@ -206,6 +197,7 @@
         } catch (IOException e){
             throw new RuntimeException(e);
         }
+        if(getAnchor().equals(new java.awt.Rectangle())) resizeToFitText();
     }
 
     /**
@@ -214,7 +206,7 @@
      *
      * @return  the bounds of this <code>TextFrame</code>.
      */
-    protected Dimension getTextSize(){
+    protected Dimension getTextDimensions(){
         FontRenderContext frc = new FontRenderContext(null, true, true);
         RichTextRun rt = _txtrun.getRichTextRuns()[0];
         int size = rt.getFontSize();
@@ -229,9 +221,9 @@
 
         TextLayout layout = new TextLayout(getText(), font, frc);
         int width = Math.round(layout.getAdvance());
-        width += getMarginLeft() + getMarginRight();
+        width += getMarginLeft() + getMarginRight() + 2;
         int height = Math.round(layout.getAscent());
-        height += getMarginTop() + getMarginBottom();
+        height += getMarginTop() + getMarginBottom() + 12;
         return new Dimension(width, height);
     }
 
@@ -239,7 +231,7 @@
      * Adjust the size of the TextBox so it encompasses the text inside it.
      */
     public void resizeToFitText(){
-        Dimension size = getTextSize();
+        Dimension size = getTextDimensions();
         java.awt.Rectangle anchor = getAnchor();
         anchor.setSize(size);
         setAnchor(anchor);
@@ -449,6 +441,17 @@
     }
 
     /**
+     *
+     * @return  the size of the font applied to this text shape
+     */
+    public Color getFontColor(){
+        RichTextRun rt = _txtrun.getRichTextRuns()[0];
+        Color color = new Color(rt.getFontColor());
+        //in PowerPont RGB bytes are swapped,
+        return new Color(color.getBlue(), color.getGreen(), color.getRed(), 
255);
+    }
+
+    /**
      * Set whether to use bold or not
      *
      * @param bold  <code>true</code>   if the text should be bold, 
<code>false</code>  otherwise
@@ -484,8 +487,92 @@
      * @param name  the name of the font to be applied to this text shape
      */
     public void setFontName(String name){
+        if (_sheet == null) {
+            //we can't set font since slideshow is not assigned yet
+            _fontname = name;
+        } else{
         RichTextRun rt = _txtrun.getRichTextRuns()[0];
         rt.setFontName(name);
     }
+    }
+
+    /**
+     * Sets the font color
+     * @param color  the font color
+     */
+    public void setFontColor(Color color){
+        //in PowerPont RGB bytes are swapped,
+        int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 
254).getRGB();
+        RichTextRun rt = _txtrun.getRichTextRuns()[0];
+        rt.setFontColor(rgb);
+    }
+
+    /**
+     * Set type of the text.
+     * Must be one of the static constants defined in 
<code>TextHeaderAtom</code>
+     *
+     * @param type type of the text
+     */
+    public void setTextType(int type){
+        _txtrun._headerAtom.setTextType(type);
+    }
     
+    public void setSheet(Sheet sheet){
+        _sheet = sheet;
+
+        //initialize _txtrun object.
+        //we can't do it in the constructor because the sheet is not assigned 
yet
+        if(_txtrun == null) initTextRun();
+
+        RichTextRun[] rt = _txtrun.getRichTextRuns();
+        for (int i = 0; i < rt.length; i++) {
+            rt[i].supplySlideShow(_sheet.getSlideShow());
+        }
+        if (_fontname != null) {
+            setFontName(_fontname);
+            _fontname = null;
+        }
+
+    }
+
+    private void initTextRun(){
+
+        TextHeaderAtom tha = null;
+        TextCharsAtom tca = null;
+        TextBytesAtom tba = null;
+        StyleTextPropAtom sta = null;
+        OutlineTextRefAtom ota = null;
+        Record[] child = _txtbox.getChildRecords();
+        for (int i = 0; i < child.length; i++) {
+            if (child[i] instanceof TextHeaderAtom) tha = 
(TextHeaderAtom)child[i];
+            else if (child[i] instanceof TextBytesAtom) tba = 
(TextBytesAtom)child[i];
+            else if (child[i] instanceof StyleTextPropAtom) sta = 
(StyleTextPropAtom)child[i];
+            else if (child[i] instanceof OutlineTextRefAtom) ota = 
(OutlineTextRefAtom)child[i];
+            else if (child[i] instanceof TextCharsAtom) tca = 
(TextCharsAtom)child[i];
+        }
+
+        if (ota != null){
+            //TextHeaderAtom, TextBytesAtom and  StyleTextPropAtom are stored 
outside of  EscherContainerRecord
+            int idx = ota.getTextIndex();
+            Slide sl = (Slide)getSheet();
+            Record[] rec = sl.getSlideAtomsSet().getSlideRecords();
+            for (int i = 0, j = 0; i < rec.length; i++) {
+                if(rec[i].getRecordType() == 
RecordTypes.TextHeaderAtom.typeID){
+                    if(j++ == idx) { //we found j-th  TextHeaderAtom, read the 
text data
+                        for (int k = i; k < rec.length; k++) {
+                            if (rec[k] instanceof TextHeaderAtom) {
+                                if (tha != null) break;
+                                else tha = (TextHeaderAtom)rec[k];
+                            }
+                            else if (rec[k] instanceof TextBytesAtom) tba = 
(TextBytesAtom)rec[k];
+                            else if (rec[k] instanceof TextCharsAtom) tca = 
(TextCharsAtom)rec[k];
+                            else if (rec[k] instanceof StyleTextPropAtom) sta 
= (StyleTextPropAtom)rec[k];
+                        }
+                    }
+                }
+            }
+        }
+        if(tba != null) _txtrun = new TextRun(tha,tba,sta);
+        else if (tca != null) _txtrun = new TextRun(tha,tca,sta);
+    }
 }

Added: 
jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/OEPlaceholderAtom.java
URL: 
http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/OEPlaceholderAtom.java?rev=405092&view=auto
==============================================================================
--- 
jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/OEPlaceholderAtom.java
 (added)
+++ 
jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/OEPlaceholderAtom.java
 Mon May  8 09:43:11 2006
@@ -0,0 +1,200 @@
+
+/* ====================================================================
+   Copyright 2002-2004   Apache Software Foundation
+
+   Licensed 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 org.apache.poi.util.LittleEndian;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * OEPlaceholderAtom (3011).
+ * <p>
+ *  Atom that describes the placeholder.
+ * </p>
+ *
+ * @author Yegor Kozlov
+ */
+
+public class OEPlaceholderAtom extends RecordAtom{
+
+    public static final int PLACEHOLDER_FULLSIZE = 0;
+    public static final int PLACEHOLDER_HALFSIZE = 1;
+    public static final int PLACEHOLDER_QUARTSIZE = 2;
+
+    public static final byte None = 0;
+
+    public static final byte MasterTitle = 1;
+
+    public static final byte MasterBody = 2;
+
+    public static final byte MasterCenteredTitle = 3;
+
+    public static final byte MasterNotesSlideImage = 4;
+
+    public static final byte MasterNotesBodyImage = 5;
+
+    public static final byte MasterDate = 6;
+
+    public static final byte MasterSlideNumber = 7;
+
+    public static final byte MasterFooter = 8;
+
+    public static final byte MasterHeader = 9;
+
+    public static final byte MasterSubtitle = 10;
+
+    public static final byte GenericTextObject = 11;
+
+    public static final byte Title = 12;
+
+    public static final byte Body = 13;
+
+    public static final byte NotesBody = 14;
+
+    public static final byte CenteredTitle = 15;
+
+    public static final byte Subtitle = 16;
+
+    public static final byte VerticalTextTitle = 17;
+
+    public static final byte VerticalTextBody = 18;
+
+    public static final byte NotesSlideImage = 19;
+
+    public static final byte Object = 20;
+
+    public static final byte Graph = 21;
+
+    public static final byte Table = 22;
+
+    public static final byte ClipArt = 23;
+
+    public static final byte OrganizationChart = 24;
+
+    public static final byte MediaClip = 25;
+
+       private byte[] _header;
+
+    private int placementId;
+    private int placeholderId;
+    private int placeholderSize;
+
+
+    /**
+     * Create a new instance of <code>OEPlaceholderAtom</code>
+     */
+    public OEPlaceholderAtom(){
+        _header = new byte[8];
+        LittleEndian.putUShort(_header, 0, 0);
+        LittleEndian.putUShort(_header, 2, (int)getRecordType());
+        LittleEndian.putInt(_header, 4, 8);
+
+        placementId = 0;
+        placeholderId = 0;
+        placeholderSize = 0;
+    }
+
+    /**
+     * Build an instance of <code>OEPlaceholderAtom</code> from on-disk data
+     */
+       protected OEPlaceholderAtom(byte[] source, int start, int len) {
+               _header = new byte[8];
+               System.arraycopy(source,start,_header,0,8);
+
+        placementId = LittleEndian.getInt(source, start);
+        placeholderId = LittleEndian.getUnsignedByte(source, start+4);
+        placeholderSize = LittleEndian.getUnsignedByte(source, start+5);
+       }
+
+    /**
+     * @return type of this record [EMAIL PROTECTED] 
RecordTypes#OEPlaceholderAtom}.
+     */
+       public long getRecordType() { return 
RecordTypes.OEPlaceholderAtom.typeID; }
+
+    /**
+     * Returns the placement Id.
+     *
+     * @return the placement Id.
+     */
+    public int getPlacementId(){
+        return placementId;
+    }
+
+    /**
+     * Sets the placement Id.
+     *
+     * @param id the placement Id.
+     */
+   public void setPlacementId(int id){
+        placementId = id;
+    }
+
+    /**
+     * Returns the placeholder Id.
+     *
+     * @return the placeholder Id.
+     */
+    public int getPlaceholderId(){
+        return placeholderId;
+    }
+
+    /**
+     * Sets the placeholder Id.
+     *
+     * @param id the placeholder Id.
+     */
+    public void setPlaceholderId(byte id){
+        placeholderId = id;
+    }
+
+    /**
+     * Returns the placeholder size.
+     * Must be one of the PLACEHOLDER_* static constants defined in this class.
+     *
+     * @return the placeholder size.
+     */
+    public int getPlaceholderSize(){
+        return placeholderSize;
+    }
+
+    /**
+     * Sets the placeholder size.
+     * Must be one of the PLACEHOLDER_* static constants defined in this class.
+     *
+     * @param size the placeholder size.
+     */
+     public void setPlaceholderSize(byte size){
+        placeholderSize = size;
+    }
+
+       /**
+        * Write the contents of the record back, so it can be written
+        *  to disk
+        */
+       public void writeOut(OutputStream out) throws IOException {
+               out.write(_header);
+
+        byte[] recdata = new byte[8];
+        LittleEndian.putInt(recdata, 0, placementId);
+        recdata[4] = (byte)placeholderId;
+        recdata[5] = (byte)placeholderSize;
+
+        out.write(recdata);
+       }
+}

Added: 
jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/OutlineTextRefAtom.java
URL: 
http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/OutlineTextRefAtom.java?rev=405092&view=auto
==============================================================================
--- 
jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/OutlineTextRefAtom.java
 (added)
+++ 
jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/OutlineTextRefAtom.java
 Mon May  8 09:43:11 2006
@@ -0,0 +1,107 @@
+/* ====================================================================
+   Copyright 2002-2004   Apache Software Foundation
+
+   Licensed 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 org.apache.poi.util.LittleEndian;
+
+import java.io.OutputStream;
+import java.io.IOException;
+
+/**
+ * OEPlaceholderAtom (3998).
+ * <br>
+ * What MSDN says about  <code>OutlineTextRefAtom</code>:
+ * <p>
+ * Appears in a slide to indicate a text that is already contained in the 
document,
+ * in a SlideListWithText containter. Sometimes slide texts are not contained
+ * within the slide container to be able to delay loading a slide and still 
display
+ * the title and body text in outline view.
+ * </p>
+ *
+ * @author Yegor Kozlov
+ */
+
+public class OutlineTextRefAtom extends RecordAtom {
+    /**
+     * record header
+     */
+    private byte[] _header;
+
+    /**
+     * the text's index within the SlideListWithText (0 for title, 1..n for 
the nth body)
+     */
+    private int _index;
+
+    /**
+     * Build an instance of <code>OutlineTextRefAtom</code> from on-disk data
+     */
+    protected OutlineTextRefAtom(byte[] source, int start, int len) {
+        // Get the header
+        _header = new byte[8];
+        System.arraycopy(source,start,_header,0,8);
+
+        // Grab the record data
+        _index = LittleEndian.getInt(source, start+8);
+    }
+
+    /**
+     * Create a new instance of <code>FontEntityAtom</code>
+     */
+    protected OutlineTextRefAtom() {
+        _index = 0;
+
+        _header = new byte[8];
+        LittleEndian.putUShort(_header, 0, 0);
+        LittleEndian.putUShort(_header, 2, (int)getRecordType());
+        LittleEndian.putInt(_header, 4, 4);
+    }
+
+    public long getRecordType() {
+        return RecordTypes.OutlineTextRefAtom.typeID;
+    }
+
+    /**
+     * Write the contents of the record back, so it can be written to disk
+     */
+    public void writeOut(OutputStream out) throws IOException {
+        out.write(_header);
+
+        byte[] recdata = new byte[4];
+        LittleEndian.putInt(recdata, 0, _index);
+        out.write(recdata);
+    }
+
+    /**
+     * Sets text's index within the SlideListWithText container
+     * (0 for title, 1..n for the nth body).
+     *
+     * @param idx 0-based text's index
+     */
+    public void setTextIndex(int idx){
+        _index = idx;
+    }
+
+    /**
+     * Return text's index within the SlideListWithText container
+     * (0 for title, 1..n for the nth body).
+     *
+     * @return idx text's index
+     */
+    public int getTextIndex(){
+        return _index;
+    }
+
+}

Modified: 
jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java
URL: 
http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java?rev=405092&r1=405091&r2=405092&view=diff
==============================================================================
--- 
jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java
 (original)
+++ 
jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java
 Mon May  8 09:43:11 2006
@@ -76,10 +76,10 @@
     public static final Type ColorSchemeAtom = new 
Type(2032,ColorSchemeAtom.class);
     public static final Type ExObjRefAtom = new Type(3009,null);
     public static final Type OEShapeAtom = new Type(3009,null);
-    public static final Type OEPlaceholderAtom = new Type(3011,null);
+    public static final Type OEPlaceholderAtom = new 
Type(3011,OEPlaceholderAtom.class);
     public static final Type GPopublicintAtom = new Type(3024,null);
     public static final Type GRatioAtom = new Type(3031,null);
-    public static final Type OutlineTextRefAtom = new Type(3998,null);
+    public static final Type OutlineTextRefAtom = new 
Type(3998,OutlineTextRefAtom.class);
     public static final Type TextHeaderAtom = new 
Type(3999,TextHeaderAtom.class);
     public static final Type TextCharsAtom = new 
Type(4000,TextCharsAtom.class);
     public static final Type StyleTextPropAtom = new 
Type(4001,StyleTextPropAtom.class);

Modified: 
jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/RichTextRun.java
URL: 
http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/RichTextRun.java?rev=405092&r1=405091&r2=405092&view=diff
==============================================================================
--- 
jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/RichTextRun.java
 (original)
+++ 
jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/RichTextRun.java
 Mon May  8 09:43:11 2006
@@ -93,7 +93,7 @@
        /**
         * Supply the SlideShow we belong to
         */
-       protected void supplySlideShow(SlideShow ss) {
+       public void supplySlideShow(SlideShow ss) {
                slideShow = ss;
        }
        
@@ -279,6 +279,21 @@
                int fontIdx = getCharTextPropVal("font.index");
                if(fontIdx == -1) { return null; }
                return slideShow.getFontCollection().getFontWithId(fontIdx);
+       }
+       
+       /**
+        * @return font color as RGB value
+        * @see java.awt.Color
+        */
+       public int getFontColor() {
+               return getCharTextPropVal("font.color");
+       }
+       /**
+        * Sets color of the text, as a RGB value
+        * @see java.awt.Color
+        */
+       public void setFontColor(int rgb) {
+               setCharTextPropVal("font.color", rgb);
        }
        
        

Modified: 
jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java
URL: 
http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java?rev=405092&r1=405091&r2=405092&view=diff
==============================================================================
--- 
jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java
 (original)
+++ 
jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java
 Mon May  8 09:43:11 2006
@@ -25,6 +25,7 @@
 import java.io.ByteArrayOutputStream;
 import java.io.ByteArrayInputStream;
 import java.io.FileOutputStream;
+import java.util.ArrayList;
 
 /**
  * Test drawing shapes via Graphics2D
@@ -132,10 +133,12 @@
         // Create a new textbox, and give it lots of properties
         TextBox txtbox = new TextBox();
         txtbox.setText(val);
+        txtbox.setFontName("Arial");
         txtbox.setFontSize(42);
         txtbox.setBold(true);
         txtbox.setItalic(true);
         txtbox.setUnderline(false);
+        txtbox.setFontColor(Color.red);
         sl.addShape(txtbox);
 
         // Check it before save
@@ -145,6 +148,8 @@
         assertTrue(rt.isBold());
         assertTrue(rt.isItalic());
         assertFalse(rt.isUnderlined());
+        assertEquals("Arial", rt.getFontName());
+        assertEquals(Color.red, txtbox.getFontColor());
 
         // Serialize and read again
         ByteArrayOutputStream out = new ByteArrayOutputStream();
@@ -162,50 +167,44 @@
         assertTrue(rt.isBold());
         assertTrue(rt.isItalic());
         assertFalse(rt.isUnderlined());
+        assertEquals("Arial", rt.getFontName());
+        assertEquals(Color.red, txtbox.getFontColor());
     }
 
     /**
-     * Verify that we can add TextBox shapes to a slide
-     * and set some of the style attributes, with a unicode string
+     * If you iterate over text shapes in a slide and collect them in a set
+     * it must be the same as returned by Slide.getTextRuns().
      */
-    public void testTextBoxWriteChars() throws Exception {
-        ppt = new SlideShow();
-        Slide sl = ppt.createSlide();
-        RichTextRun rt;
-
-        String val = "Hello, World! (With some \u1234 and \uffee unicode in 
it)";
-
-        // Create a new textbox, and give it lots of properties
-        TextBox txtbox = new TextBox();
-        txtbox.setText(val);
-        txtbox.setFontSize(42);
-        txtbox.setBold(true);
-        txtbox.setUnderline(false);
-        sl.addShape(txtbox);
-
-        // Check it before save
-        rt = txtbox.getRichTextRuns()[0];
-        assertEquals(val, rt.getText());
-        assertEquals(42, rt.getFontSize());
-        assertTrue(rt.isBold());
-        assertFalse(rt.isItalic());
-        assertFalse(rt.isUnderlined());
-
-        // Serialize and read again
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        ppt.write(out);
-        out.close();
-
-        ppt = new SlideShow(new HSLFSlideShow(new 
ByteArrayInputStream(out.toByteArray())));
+    public void testTextBoxSet() throws Exception {
+        textBoxSet("/with_textbox.ppt");
+        textBoxSet("/basic_test_ppt_file.ppt");
+        textBoxSet("/next_test_ppt_file.ppt");
+        textBoxSet("/Single_Coloured_Page.ppt");
+        textBoxSet("/Single_Coloured_Page_With_Fonts_and_Alignments.ppt");
+        textBoxSet("/incorrect_slide_order.ppt");
+    }
 
-        txtbox = (TextBox)sl.getShapes()[0];
-        rt = txtbox.getRichTextRuns()[0];
+    private void textBoxSet(String filename) throws Exception {
+        String dirname = System.getProperty("HSLF.testdata.path");
+        SlideShow ppt = new SlideShow(new HSLFSlideShow(dirname + filename));
+        Slide[] sl = ppt.getSlides();
+        for (int k = 0; k < sl.length; k++) {
+            ArrayList lst1 = new ArrayList();
+            TextRun[] txt = sl[k].getTextRuns();
+            for (int i = 0; i < txt.length; i++) {
+                lst1.add(txt[i].getText());
+            }
 
-        // Check after save
-        assertEquals(val, rt.getText());
-        assertEquals(42, rt.getFontSize());
-        assertTrue(rt.isBold());
-        assertFalse(rt.isItalic());
-        assertFalse(rt.isUnderlined());
+            ArrayList lst2 = new ArrayList();
+            Shape[] sh = sl[k].getShapes();
+            for (int i = 0; i < sh.length; i++) {
+                if (sh[i] instanceof TextBox){
+                    TextBox tbox = (TextBox)sh[i];
+                    lst2.add(tbox.getText());
+                }
+            }
+            assertTrue(lst1.containsAll(lst2));
+            assertTrue(lst2.containsAll(lst1));
+        }
     }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
Mailing List:    http://jakarta.apache.org/site/mail2.html#poi
The Apache Jakarta POI Project: http://jakarta.apache.org/poi/

Reply via email to