You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by be...@apache.org on 2012/06/26 13:21:16 UTC

svn commit: r1353960 - in /poi/branches/gsoc2012: src/java/org/apache/poi/hssf/record/ src/java/org/apache/poi/hssf/usermodel/ src/java/org/apache/poi/hssf/usermodel/drawing/ src/testcases/org/apache/poi/hssf/model/ src/testcases/org/apache/poi/hssf/us...

Author: berlog
Date: Tue Jun 26 11:21:13 2012
New Revision: 1353960

URL: http://svn.apache.org/viewvc?rev=1353960&view=rev
Log:
implemented creating shapes in existing files

Added:
    poi/branches/gsoc2012/src/testcases/org/apache/poi/hssf/model/HSSFTestModelHelper.java
    poi/branches/gsoc2012/src/testcases/org/apache/poi/hssf/usermodel/TestText.java
    poi/branches/gsoc2012/test-data/spreadsheet/empty.xls   (with props)
Modified:
    poi/branches/gsoc2012/src/java/org/apache/poi/hssf/record/EscherAggregate.java
    poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFComment.java
    poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java
    poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFPolygon.java
    poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFShape.java
    poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFShapeFactory.java
    poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFShapeGroup.java
    poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFSimpleShape.java
    poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFTextbox.java
    poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFUnknownShape.java
    poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/drawing/HSSFShapeType.java
    poi/branches/gsoc2012/src/testcases/org/apache/poi/hssf/model/TestDrawingShapes.java
    poi/branches/gsoc2012/src/testcases/org/apache/poi/hssf/usermodel/HSSFTestHelper.java
    poi/branches/gsoc2012/test-data/spreadsheet/drawings.xls

Modified: poi/branches/gsoc2012/src/java/org/apache/poi/hssf/record/EscherAggregate.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/java/org/apache/poi/hssf/record/EscherAggregate.java?rev=1353960&r1=1353959&r2=1353960&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/java/org/apache/poi/hssf/record/EscherAggregate.java (original)
+++ poi/branches/gsoc2012/src/java/org/apache/poi/hssf/record/EscherAggregate.java Tue Jun 26 11:21:13 2012
@@ -323,6 +323,10 @@ public final class EscherAggregate exten
         this.drawingManager = drawingManager;
     }
 
+    public DrawingManager2 getDrawingManager() {
+        return drawingManager;
+    }
+
     /**
      * @return Returns the current sid.
      */
@@ -628,7 +632,7 @@ public final class EscherAggregate exten
     /**
      * Associates an escher record to an OBJ record or a TXO record.
      */
-    public Object associateShapeToObjRecord(EscherRecord r, ObjRecord objRecord) {
+    public Object associateShapeToObjRecord(EscherRecord r, Record objRecord) {
         return shapeToObj.put(r, objRecord);
     }
 
@@ -1039,9 +1043,9 @@ public final class EscherAggregate exten
         EscherDgRecord dg = new EscherDgRecord();
         dg.setRecordId( EscherDgRecord.RECORD_ID );
         short dgId = 1;
-        dg.setOptions( (short) ( dgId << 4 ) );
-        dg.setNumShapes( 1 );
-        dg.setLastMSOSPID( 1024 );
+        dg.setOptions((short) (dgId << 4));
+        dg.setNumShapes(1);
+        dg.setLastMSOSPID(1024);
         drawingGroupId = dg.getDrawingGroupId();
         spgrContainer.setRecordId(EscherContainerRecord.SPGR_CONTAINER);
         spgrContainer.setOptions((short) 0x000F);

Modified: poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFComment.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFComment.java?rev=1353960&r1=1353959&r2=1353960&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFComment.java (original)
+++ poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFComment.java Tue Jun 26 11:21:13 2012
@@ -66,7 +66,7 @@ public class HSSFComment extends HSSFTex
     }
 
     protected HSSFComment(NoteRecord note, TextObjectRecord txo) {
-        this((HSSFShape) null, (HSSFAnchor) null);
+        this(null, new HSSFClientAnchor());
         _txo = txo;
         _note = note;
     }
@@ -185,7 +185,7 @@ public class HSSFComment extends HSSFTex
     /**
      * Returns the underlying Text record
      */
-    protected TextObjectRecord getTextObjectRecord() {
+    public TextObjectRecord getTextObjectRecord() {
 	    return _txo;
 	}
 }

Modified: poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java?rev=1353960&r1=1353959&r2=1353960&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java (original)
+++ poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java Tue Jun 26 11:21:13 2012
@@ -21,12 +21,8 @@ import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 
-import org.apache.poi.ddf.EscherComplexProperty;
-import org.apache.poi.ddf.EscherContainerRecord;
-import org.apache.poi.ddf.EscherOptRecord;
-import org.apache.poi.ddf.EscherProperty;
-import org.apache.poi.ddf.EscherBSERecord;
-import org.apache.poi.ddf.EscherSpgrRecord;
+import org.apache.poi.ddf.*;
+import org.apache.poi.hssf.model.DrawingManager2;
 import org.apache.poi.hssf.record.EscherAggregate;
 import org.apache.poi.ss.usermodel.Chart;
 import org.apache.poi.util.StringUtil;
@@ -93,6 +89,8 @@ public final class HSSFPatriarch impleme
         HSSFSimpleShape shape = new HSSFSimpleShape(null, anchor);
         shape.anchor = anchor;
         addShape(shape);
+        //open existing file
+        onCreate(shape);
         return shape;
     }
 
@@ -109,6 +107,8 @@ public final class HSSFPatriarch impleme
         shape.setPictureIndex( pictureIndex );
         shape.anchor = anchor;
         addShape(shape);
+        //open existing file
+        onCreate(shape);
 
         EscherBSERecord bse = _sheet.getWorkbook().getWorkbook().getBSERecord(pictureIndex);
         bse.setRef(bse.getRef() + 1);
@@ -147,6 +147,7 @@ public final class HSSFPatriarch impleme
         HSSFTextbox shape = new HSSFTextbox(null, anchor);
         shape.anchor = anchor;
         addShape(shape);
+        onCreate(shape);
         return shape;
     }
 
@@ -200,6 +201,20 @@ public final class HSSFPatriarch impleme
         _shapes.add(shape);
     }
 
+    private void onCreate(HSSFShape shape){
+        if(_boundAggregate.getPatriarch() == null){
+            EscherContainerRecord spgrContainer =
+                    _boundAggregate.getEscherContainer().getChildContainers().get(0);
+
+            EscherContainerRecord spContainer = shape.getEscherContainer();
+            int shapeId = newShapeId();
+            shape.setShapeId(shapeId);
+
+            spgrContainer.addChildRecord(spContainer);
+            shape.afterInsert(this);
+        }
+    }
+
     /**
      * Total count of all children and their children's children.
      */
@@ -222,6 +237,17 @@ public final class HSSFPatriarch impleme
         _y2 = y2;
     }
 
+    int newShapeId() {
+        if (_boundAggregate.getEscherContainer() == null){
+            throw new IllegalStateException("We can use this method for only existing files");
+        }
+        DrawingManager2 dm = _boundAggregate.getDrawingManager();
+        EscherDgRecord dg =
+                _boundAggregate.getEscherContainer().getChildById(EscherDgRecord.RECORD_ID);
+        short drawingGroupId = dg.getDrawingGroupId();
+        return dm.allocateShapeId(drawingGroupId, dg);
+    }
+
     /**
      * Does this HSSFPatriarch contain a chart?
      * (Technically a reference to a chart, since they

Modified: poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFPolygon.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFPolygon.java?rev=1353960&r1=1353959&r2=1353960&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFPolygon.java (original)
+++ poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFPolygon.java Tue Jun 26 11:21:13 2012
@@ -17,6 +17,9 @@
 
 package org.apache.poi.hssf.usermodel;
 
+import org.apache.poi.ddf.EscherContainerRecord;
+import org.apache.poi.hssf.record.ObjRecord;
+
 /**
  * @author Glen Stampoultzis  (glens at superlinksoftware.com)
  */
@@ -33,6 +36,16 @@ public class HSSFPolygon
         super( parent, anchor );
     }
 
+    @Override
+    protected EscherContainerRecord createSpContainer() {
+        return null;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    protected ObjRecord createObjRecord() {
+        return null;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
     public int[] getXPoints()
     {
         return xPoints;

Modified: poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFShape.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFShape.java?rev=1353960&r1=1353959&r2=1353960&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFShape.java (original)
+++ poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFShape.java Tue Jun 26 11:21:13 2012
@@ -18,6 +18,7 @@
 package org.apache.poi.hssf.usermodel;
 
 import org.apache.poi.ddf.*;
+import org.apache.poi.hssf.record.CommonObjectDataSubRecord;
 import org.apache.poi.hssf.record.ObjRecord;
 
 /**
@@ -71,6 +72,7 @@ public abstract class HSSFShape {
         this.anchor = anchor;
         this._escherContainer = new EscherContainerRecord();
         _optRecord = new EscherOptRecord();
+        _optRecord.setRecordId( EscherOptRecord.RECORD_ID );
         _optRecord.addEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEDASHING, LINESTYLE_SOLID));
         _optRecord.addEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEWIDTH, LINEWIDTH_DEFAULT));
         _optRecord.addEscherProperty(new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, FILL__FILLCOLOR_DEFAULT));
@@ -78,6 +80,24 @@ public abstract class HSSFShape {
         _optRecord.addEscherProperty(new EscherBoolProperty(EscherProperties.FILL__NOFILLHITTEST, 0x0));
     }
 
+    protected abstract EscherContainerRecord createSpContainer();
+
+    protected abstract ObjRecord createObjRecord();
+
+    void setShapeId(int shapeId){
+        EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID);
+        spRecord.setShapeId(shapeId);
+        CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) _objRecord.getSubRecords().get(0);
+        cod.setObjectId((short) (shapeId-1024));
+    }
+    
+    int getShapeId(){
+        return ((EscherSpRecord)_escherContainer.getChildById(EscherSpRecord.RECORD_ID)).getShapeId();
+    }
+
+    void afterInsert(HSSFPatriarch patriarch){
+    }
+
     public EscherContainerRecord getEscherContainer() {
         return _escherContainer;
     }

Modified: poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFShapeFactory.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFShapeFactory.java?rev=1353960&r1=1353959&r2=1353960&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFShapeFactory.java (original)
+++ poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFShapeFactory.java Tue Jun 26 11:21:13 2012
@@ -115,19 +115,37 @@ public class HSSFShapeFactory {
                         break;
                 }
             }
-            if (null != objRecord){
-                HSSFShape shape = shapeCreator.createNewShape(spRecord.getShapeType(), container, objRecord);
-                out.addShape(shape);
+            CommonObjectDataSubRecord cmo = (CommonObjectDataSubRecord) objRecord.getSubRecords().get(0);
+            HSSFShape shape = null;
+            switch (cmo.getObjectType()) {
+                case CommonObjectDataSubRecord.OBJECT_TYPE_PICTURE:
+                    shape = new HSSFPicture(container, objRecord);
+                    break;
+                case CommonObjectDataSubRecord.OBJECT_TYPE_RECTANGLE:
+                    shape = new HSSFSimpleShape(container, objRecord);
+                    break;
+                case CommonObjectDataSubRecord.OBJECT_TYPE_TEXT:
+                    shape = new HSSFTextbox(container, objRecord, txtRecord);
+                    break;
+                default:
+                    shape = new HSSFSimpleShape(container, objRecord);
             }
-            if (null != txtRecord){
-                //TODO resolve textbox
-//                TextboxShape shape = new TextboxShape(container, txtRecord);
-//                out.a
+            if (null != shape){
+                out.addShape(shape);
             }
-//
-//            //TODO decide what shape to create based on ObjRecord / EscherSpRecord
-//            HSSFShape shape = new HSSFUnknownShape(container, objRecord);
-//            out.addShape(shape);
+//            if (null != objRecord){
+//                HSSFShape shape = shapeCreator.createNewShape(spRecord.getShapeType(), container, objRecord);
+//                out.addShape(shape);
+//            }
+//            if (null != txtRecord){
+//                //TODO resolve textbox
+////                TextboxShape shape = new TextboxShape(container, txtRecord);
+////                out.a
+//            }
+////
+////            //TODO decide what shape to create based on ObjRecord / EscherSpRecord
+////            HSSFShape shape = new HSSFUnknownShape(container, objRecord);
+////            out.addShape(shape);
         }
     }
 }

Modified: poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFShapeGroup.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFShapeGroup.java?rev=1353960&r1=1353959&r2=1353960&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFShapeGroup.java (original)
+++ poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFShapeGroup.java Tue Jun 26 11:21:13 2012
@@ -74,6 +74,16 @@ public class HSSFShapeGroup
         _spgrRecord.setRectY2(255);
     }
 
+    @Override
+    protected EscherContainerRecord createSpContainer() {
+        return null;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    protected ObjRecord createObjRecord() {
+        return null;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
     /**
      * Create another group under this group.
      * @param anchor    the position of the new group.

Modified: poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFSimpleShape.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFSimpleShape.java?rev=1353960&r1=1353959&r2=1353960&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFSimpleShape.java (original)
+++ poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFSimpleShape.java Tue Jun 26 11:21:13 2012
@@ -19,7 +19,13 @@ package org.apache.poi.hssf.usermodel;
 
 import org.apache.poi.ddf.*;
 import org.apache.poi.hssf.record.CommonObjectDataSubRecord;
+import org.apache.poi.hssf.record.EndSubRecord;
+import org.apache.poi.hssf.record.EscherAggregate;
 import org.apache.poi.hssf.record.ObjRecord;
+import org.apache.poi.hssf.usermodel.drawing.HSSFShapeType;
+
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  * Represents a simple shape such as a line, rectangle or oval.
@@ -56,17 +62,69 @@ public class HSSFSimpleShape
 
     int shapeType = OBJECT_TYPE_LINE;
 
+    private static final Map <Short, Short> objTypeToShapeType = new HashMap<Short, Short>();
+
+    static {
+        objTypeToShapeType.put(OBJECT_TYPE_RECTANGLE, HSSFShapeType.RECTANGLE.getType());
+        objTypeToShapeType.put(OBJECT_TYPE_PICTURE, HSSFShapeType.PICTURE.getType());
+        objTypeToShapeType.put(OBJECT_TYPE_LINE, HSSFShapeType.LINE.getType());
+    }
+
     public HSSFSimpleShape(EscherContainerRecord spContainer, ObjRecord objRecord) {
         super(spContainer, objRecord);
-        CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) objRecord.getSubRecords().get(0);
-        setShapeType(cod.getObjectType());
     }
 
     public HSSFSimpleShape( HSSFShape parent, HSSFAnchor anchor)
     {
         super( parent, anchor );
+        _escherContainer = createSpContainer();
+        _objRecord = createObjRecord();
+        setShapeType(OBJECT_TYPE_LINE);
+    }
+
+    @Override
+    protected EscherContainerRecord createSpContainer() {
+        EscherContainerRecord spContainer = new EscherContainerRecord();
+        spContainer.setRecordId( EscherContainerRecord.SP_CONTAINER );
+        spContainer.setOptions( (short) 0x000F );
+
+        EscherSpRecord sp = new EscherSpRecord();
+        sp.setRecordId( EscherSpRecord.RECORD_ID );
+        sp.setFlags( EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HASSHAPETYPE );
+
+        EscherClientDataRecord clientData = new EscherClientDataRecord();
+        clientData.setRecordId( EscherClientDataRecord.RECORD_ID );
+        clientData.setOptions( (short) 0x0000 );
+
+        spContainer.addChildRecord(sp);
+        spContainer.addChildRecord(_optRecord);
+        spContainer.addChildRecord(anchor.getEscherAnchor());
+        spContainer.addChildRecord(clientData);
+        return spContainer;
+    }
+
+    @Override
+    protected ObjRecord createObjRecord() {
+        ObjRecord obj = new ObjRecord();
+        CommonObjectDataSubRecord c = new CommonObjectDataSubRecord();
+        c.setLocked(true);
+        c.setPrintable(true);
+        c.setAutofill(true);
+        c.setAutoline(true);
+        EndSubRecord e = new EndSubRecord();
+
+        obj.addSubRecord(c);
+        obj.addSubRecord(e);
+        return obj;
+    }
+
+    @Override
+    void afterInsert(HSSFPatriarch patriarch){
+        EscherAggregate agg = patriarch._getBoundAggregate();
+        agg.associateShapeToObjRecord(_escherContainer.getChildById(EscherClientDataRecord.RECORD_ID), getObjRecord());
     }
 
+
     /**
      * Gets the shape type.
      * @return  One of the OBJECT_TYPE_* constants.
@@ -77,7 +135,10 @@ public class HSSFSimpleShape
      * @see #OBJECT_TYPE_PICTURE
      * @see #OBJECT_TYPE_COMMENT
      */
-    public int getShapeType() { return shapeType; }
+    public int getShapeType() {
+        CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) _objRecord.getSubRecords().get(0);
+        return cod.getObjectType();
+    }
 
     /**
      * Sets the shape types.
@@ -90,6 +151,14 @@ public class HSSFSimpleShape
      * @see #OBJECT_TYPE_PICTURE
      * @see #OBJECT_TYPE_COMMENT
      */
-    public void setShapeType( int shapeType ){ this.shapeType = shapeType; }
-
+    public void setShapeType( int shapeType ){
+        CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) _objRecord.getSubRecords().get(0);
+        cod.setObjectType((short) shapeType);
+        EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID);
+        if (null == objTypeToShapeType.get((short)shapeType)){
+            System.out.println("Unknown shape type: "+shapeType);
+            return;
+        }
+        spRecord.setShapeType(objTypeToShapeType.get((short)shapeType));
+    }
 }

Modified: poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFTextbox.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFTextbox.java?rev=1353960&r1=1353959&r2=1353960&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFTextbox.java (original)
+++ poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFTextbox.java Tue Jun 26 11:21:13 2012
@@ -17,6 +17,8 @@
 
 package org.apache.poi.hssf.usermodel;
 
+import org.apache.poi.ddf.*;
+import org.apache.poi.hssf.record.*;
 import org.apache.poi.ss.usermodel.RichTextString;
 
 /**
@@ -24,163 +26,233 @@ import org.apache.poi.ss.usermodel.RichT
  *
  * @author Glen Stampoultzis (glens at apache.org)
  */
-public class HSSFTextbox
-        extends HSSFSimpleShape
-{
-    public final static short       OBJECT_TYPE_TEXT               = 6;
+public class HSSFTextbox extends HSSFSimpleShape {
+    public final static short OBJECT_TYPE_TEXT = 6;
 
     /**
      * How to align text horizontally
      */
-    public final static short  HORIZONTAL_ALIGNMENT_LEFT = 1;
-    public final static short  HORIZONTAL_ALIGNMENT_CENTERED = 2;
-    public final static short  HORIZONTAL_ALIGNMENT_RIGHT = 3;
-    public final static short  HORIZONTAL_ALIGNMENT_JUSTIFIED = 4;
-    public final static short  HORIZONTAL_ALIGNMENT_DISTRIBUTED = 7;
+    public final static short HORIZONTAL_ALIGNMENT_LEFT = 1;
+    public final static short HORIZONTAL_ALIGNMENT_CENTERED = 2;
+    public final static short HORIZONTAL_ALIGNMENT_RIGHT = 3;
+    public final static short HORIZONTAL_ALIGNMENT_JUSTIFIED = 4;
+    public final static short HORIZONTAL_ALIGNMENT_DISTRIBUTED = 7;
 
     /**
      * How to align text vertically
      */
-    public final static short  VERTICAL_ALIGNMENT_TOP    = 1;
-    public final static short  VERTICAL_ALIGNMENT_CENTER = 2;
-    public final static short  VERTICAL_ALIGNMENT_BOTTOM = 3;
-    public final static short  VERTICAL_ALIGNMENT_JUSTIFY = 4;
-    public final static short  VERTICAL_ALIGNMENT_DISTRIBUTED= 7;
+    public final static short VERTICAL_ALIGNMENT_TOP = 1;
+    public final static short VERTICAL_ALIGNMENT_CENTER = 2;
+    public final static short VERTICAL_ALIGNMENT_BOTTOM = 3;
+    public final static short VERTICAL_ALIGNMENT_JUSTIFY = 4;
+    public final static short VERTICAL_ALIGNMENT_DISTRIBUTED = 7;
 
 
     int marginLeft, marginRight, marginTop, marginBottom;
     short halign, valign;
 
+    private TextObjectRecord _textObjectRecord;
+
+    public HSSFTextbox(EscherContainerRecord spContainer, ObjRecord objRecord, TextObjectRecord textObjectRecord) {
+        super(spContainer, objRecord);
+        this._textObjectRecord = textObjectRecord;
+    }
+
     HSSFRichTextString string = new HSSFRichTextString("");
 
     /**
      * Construct a new textbox with the given parent and anchor.
+     *
      * @param parent
-     * @param anchor  One of HSSFClientAnchor or HSSFChildAnchor
+     * @param anchor One of HSSFClientAnchor or HSSFChildAnchor
      */
-    public HSSFTextbox( HSSFShape parent, HSSFAnchor anchor )
-    {
-        super( parent, anchor );
-        setShapeType(OBJECT_TYPE_TEXT);
+    public HSSFTextbox(HSSFShape parent, HSSFAnchor anchor) {
+        super(parent, anchor);
+        _textObjectRecord = createTextObjRecord();
+        setHorizontalAlignment(HORIZONTAL_ALIGNMENT_LEFT);
+        setVerticalAlignment(VERTICAL_ALIGNMENT_TOP);
+        setString(new HSSFRichTextString(""));
+
+    }
+
+    protected TextObjectRecord createTextObjRecord(){
+        TextObjectRecord obj = new TextObjectRecord();
+        obj.setTextLocked(true);
+        obj.setTextOrientation(TextObjectRecord.TEXT_ORIENTATION_NONE);
+        return obj;
+    }
+
+    @Override
+    protected ObjRecord createObjRecord() {
+        ObjRecord obj = new ObjRecord();
+        CommonObjectDataSubRecord c = new CommonObjectDataSubRecord();
+        c.setObjectType(OBJECT_TYPE_TEXT);
+        c.setLocked( true );
+        c.setPrintable( true );
+        c.setAutofill( true );
+        c.setAutoline( true );
+        EndSubRecord e = new EndSubRecord();
+        obj.addSubRecord( c );
+        obj.addSubRecord( e );
+        return obj;
+    }
+
+    @Override
+    protected EscherContainerRecord createSpContainer() {
+        EscherContainerRecord spContainer = new EscherContainerRecord();
+        EscherSpRecord sp = new EscherSpRecord();
+        EscherOptRecord opt = new EscherOptRecord();
+        EscherClientDataRecord clientData = new EscherClientDataRecord();
+        EscherTextboxRecord escherTextbox = new EscherTextboxRecord();
+
+        spContainer.setRecordId(EscherContainerRecord.SP_CONTAINER);
+        spContainer.setOptions((short) 0x000F);
+        sp.setRecordId(EscherSpRecord.RECORD_ID);
+        sp.setOptions((short) ((EscherAggregate.ST_TEXTBOX << 4) | 0x2));
 
-        halign = HORIZONTAL_ALIGNMENT_LEFT;
-        valign = VERTICAL_ALIGNMENT_TOP;
+        sp.setFlags(EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HASSHAPETYPE);
+        opt.setRecordId(EscherOptRecord.RECORD_ID);
+        opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.TEXT__TEXTID, 0));
+        opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.TEXT__TEXTLEFT, getMarginLeft()));
+        opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.TEXT__TEXTRIGHT, getMarginRight()));
+        opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.TEXT__TEXTBOTTOM, getMarginBottom()));
+        opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.TEXT__TEXTTOP, getMarginTop()));
+
+        opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.TEXT__WRAPTEXT, 0));
+        opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.TEXT__ANCHORTEXT, 0));
+        opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.GROUPSHAPE__PRINT, 0x00080000));
+
+        EscherRecord anchor = getAnchor().getEscherAnchor();
+        clientData.setRecordId(EscherClientDataRecord.RECORD_ID);
+        clientData.setOptions((short) 0x0000);
+        escherTextbox.setRecordId(EscherTextboxRecord.RECORD_ID);
+        escherTextbox.setOptions((short) 0x0000);
+
+        spContainer.addChildRecord(sp);
+        spContainer.addChildRecord(opt);
+        spContainer.addChildRecord(anchor);
+        spContainer.addChildRecord(clientData);
+        spContainer.addChildRecord(escherTextbox);
+
+        return spContainer;
+    }
+
+    @Override
+    void afterInsert(HSSFPatriarch patriarch){
+        EscherAggregate agg = patriarch._getBoundAggregate();
+        agg.associateShapeToObjRecord(_escherContainer.getChildById(EscherClientDataRecord.RECORD_ID), getObjRecord());
+        agg.associateShapeToObjRecord(_escherContainer.getChildById(EscherTextboxRecord.RECORD_ID), getTextObjectRecord());
     }
 
     /**
-     * @return  the rich text string for this textbox.
+     * @return the rich text string for this textbox.
      */
-    public HSSFRichTextString getString()
-    {
-        return string;
+    public HSSFRichTextString getString() {
+        return _textObjectRecord.getStr();
     }
 
     /**
-     * @param string    Sets the rich text string used by this object.
+     * @param string Sets the rich text string used by this object.
      */
-    public void setString( RichTextString string )
-    {
-        HSSFRichTextString rtr = (HSSFRichTextString)string;
-
+    public void setString(RichTextString string) {
+        HSSFRichTextString rtr = (HSSFRichTextString) string;
         // If font is not set we must set the default one
-        if (rtr.numFormattingRuns() == 0) rtr.applyFont((short)0);
-
-        this.string = rtr;
+        if (rtr.numFormattingRuns() == 0) rtr.applyFont((short) 0);
+        _textObjectRecord.setStr(rtr);
     }
 
     /**
-     * @return  Returns the left margin within the textbox.
+     * @return Returns the left margin within the textbox.
      */
-    public int getMarginLeft()
-    {
-        return marginLeft;
+    public int getMarginLeft() {
+        EscherSimpleProperty property = _optRecord.lookup(EscherProperties.TEXT__TEXTLEFT);
+        return property == null ? 0: property.getPropertyValue();
     }
 
     /**
      * Sets the left margin within the textbox.
      */
-    public void setMarginLeft( int marginLeft )
-    {
-        this.marginLeft = marginLeft;
+    public void setMarginLeft(int marginLeft) {
+        setPropertyValue(new EscherSimpleProperty(EscherProperties.TEXT__TEXTLEFT, marginLeft));
     }
 
     /**
-     * @return    returns the right margin within the textbox.
+     * @return returns the right margin within the textbox.
      */
-    public int getMarginRight()
-    {
-        return marginRight;
+    public int getMarginRight() {
+        EscherSimpleProperty property = _optRecord.lookup(EscherProperties.TEXT__TEXTRIGHT);
+        return property == null ? 0: property.getPropertyValue();
     }
 
     /**
      * Sets the right margin within the textbox.
      */
-    public void setMarginRight( int marginRight )
-    {
-        this.marginRight = marginRight;
+    public void setMarginRight(int marginRight) {
+        setPropertyValue(new EscherSimpleProperty(EscherProperties.TEXT__TEXTRIGHT, marginRight));
     }
 
     /**
-     * @return  returns the top margin within the textbox.
+     * @return returns the top margin within the textbox.
      */
-    public int getMarginTop()
-    {
-        return marginTop;
+    public int getMarginTop() {
+        EscherSimpleProperty property = _optRecord.lookup(EscherProperties.TEXT__TEXTTOP);
+        return property == null ? 0: property.getPropertyValue();
     }
 
     /**
      * Sets the top margin within the textbox.
      */
-    public void setMarginTop( int marginTop )
-    {
-        this.marginTop = marginTop;
+    public void setMarginTop(int marginTop) {
+        setPropertyValue(new EscherSimpleProperty(EscherProperties.TEXT__TEXTTOP, marginTop));
     }
 
     /**
      * Gets the bottom margin within the textbox.
      */
-    public int getMarginBottom()
-    {
-        return marginBottom;
+    public int getMarginBottom() {
+        EscherSimpleProperty property = _optRecord.lookup(EscherProperties.TEXT__TEXTBOTTOM);
+        return property == null ? 0: property.getPropertyValue();
     }
 
     /**
      * Sets the bottom margin within the textbox.
      */
-    public void setMarginBottom( int marginBottom )
-    {
-        this.marginBottom = marginBottom;
+    public void setMarginBottom(int marginBottom) {
+        setPropertyValue(new EscherSimpleProperty(EscherProperties.TEXT__TEXTBOTTOM, marginBottom));
     }
 
     /**
      * Gets the horizontal alignment.
      */
-    public short getHorizontalAlignment()
-    {
-        return halign;
+    public short getHorizontalAlignment() {
+        return (short) _textObjectRecord.getHorizontalTextAlignment();
     }
 
     /**
      * Sets the horizontal alignment.
      */
-    public void setHorizontalAlignment( short align )
-    {
-        this.halign = align;
+    public void setHorizontalAlignment(short align) {
+        _textObjectRecord.setHorizontalTextAlignment(align);
     }
 
     /**
      * Gets the vertical alignment.
      */
-    public short getVerticalAlignment()
-    {
-        return valign;
+    public short getVerticalAlignment() {
+        return (short) _textObjectRecord.getVerticalTextAlignment();
     }
 
     /**
      * Sets the vertical alignment.
      */
-    public void setVerticalAlignment( short align )
-    {
-        this.valign = align;
+    public void setVerticalAlignment(short align) {
+        _textObjectRecord.setVerticalTextAlignment(align);
     }
+
+    public TextObjectRecord getTextObjectRecord() {
+        return _textObjectRecord;
+    }
+
+    @Override
+    public void setShapeType(int shapeType) {/**DO NOTHING**/}
 }

Modified: poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFUnknownShape.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFUnknownShape.java?rev=1353960&r1=1353959&r2=1353960&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFUnknownShape.java (original)
+++ poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFUnknownShape.java Tue Jun 26 11:21:13 2012
@@ -30,4 +30,14 @@ public class HSSFUnknownShape extends HS
     public HSSFUnknownShape(EscherRecord spContainer, ObjRecord objRecord) {
         super((EscherContainerRecord) spContainer, objRecord);
     }
+
+    @Override
+    protected EscherContainerRecord createSpContainer() {
+        return null;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    protected ObjRecord createObjRecord() {
+        return null;  //To change body of implemented methods use File | Settings | File Templates.
+    }
 }

Modified: poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/drawing/HSSFShapeType.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/drawing/HSSFShapeType.java?rev=1353960&r1=1353959&r2=1353960&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/drawing/HSSFShapeType.java (original)
+++ poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/drawing/HSSFShapeType.java Tue Jun 26 11:21:13 2012
@@ -2,6 +2,7 @@ package org.apache.poi.hssf.usermodel.dr
 
 import org.apache.poi.hssf.usermodel.HSSFPicture;
 import org.apache.poi.hssf.usermodel.HSSFSimpleShape;
+import org.apache.poi.hssf.usermodel.HSSFTextbox;
 
 /**
  * @author Evgeniy Berlog
@@ -11,16 +12,18 @@ public enum HSSFShapeType {
     NOT_PRIMITIVE((short)0x0, null, (short)0),
     RECTANGLE((short)0x1, HSSFSimpleShape.class, HSSFSimpleShape.OBJECT_TYPE_RECTANGLE),
     PICTURE((short)0x004B, HSSFPicture.class, HSSFSimpleShape.OBJECT_TYPE_PICTURE),
+    LINE((short)0x14, HSSFSimpleShape.class, HSSFSimpleShape.OBJECT_TYPE_LINE),
+    TEXT((short)202, HSSFTextbox.class, HSSFTextbox.OBJECT_TYPE_TEXT),
     ROUND_RECTANGLE((short)0x2, null, null);
 
     private Short type;
     private Class shape;
-    private Short objectId;
+    private Short objectType;
 
-    private HSSFShapeType(Short type, Class shape, Short objectId) {
+    private HSSFShapeType(Short type, Class shape, Short objectType) {
         this.type = type;
         this.shape = shape;
-        this.objectId = objectId;
+        this.objectType = objectType;
     }
 
     public Short getType() {
@@ -30,4 +33,8 @@ public enum HSSFShapeType {
     public Class getShape() {
         return shape;
     }
+
+    public Short getObjectType() {
+        return objectType;
+    }
 }

Added: poi/branches/gsoc2012/src/testcases/org/apache/poi/hssf/model/HSSFTestModelHelper.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/testcases/org/apache/poi/hssf/model/HSSFTestModelHelper.java?rev=1353960&view=auto
==============================================================================
--- poi/branches/gsoc2012/src/testcases/org/apache/poi/hssf/model/HSSFTestModelHelper.java (added)
+++ poi/branches/gsoc2012/src/testcases/org/apache/poi/hssf/model/HSSFTestModelHelper.java Tue Jun 26 11:21:13 2012
@@ -0,0 +1,13 @@
+package org.apache.poi.hssf.model;
+
+import org.apache.poi.hssf.usermodel.HSSFTextbox;
+
+/**
+ * @author Evgeniy Berlog
+ * @date 25.06.12
+ */
+public class HSSFTestModelHelper {
+    public static TextboxShape createTextboxShape(int shapeId, HSSFTextbox textbox){
+        return new TextboxShape(textbox, shapeId);
+    }
+}

Modified: poi/branches/gsoc2012/src/testcases/org/apache/poi/hssf/model/TestDrawingShapes.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/testcases/org/apache/poi/hssf/model/TestDrawingShapes.java?rev=1353960&r1=1353959&r2=1353960&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/testcases/org/apache/poi/hssf/model/TestDrawingShapes.java (original)
+++ poi/branches/gsoc2012/src/testcases/org/apache/poi/hssf/model/TestDrawingShapes.java Tue Jun 26 11:21:13 2012
@@ -251,4 +251,41 @@ public class TestDrawingShapes extends T
                 ((EscherContainerRecord)spgrContainer.getChild(2)).getChildById(EscherSpRecord.RECORD_ID);
         assertEquals(1026, sp2.getShapeId());
     }
+
+    /**
+     * Test get new id for shapes from existing file
+     * File already have for 1 shape on each sheet, because document must contain EscherDgRecord for each sheet
+     */
+    public void testAllocateNewIds(){
+        HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("empty.xls");
+        HSSFSheet sheet = wb.getSheetAt(0);
+        HSSFPatriarch patriarch = sheet.getDrawingPatriarch();
+
+        /**
+         * 2048 - main SpContainer id
+         * 2049 - existing shape id
+         */
+        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 2050);
+        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 2051);
+        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 2052);
+
+        sheet = wb.getSheetAt(1);
+        patriarch = sheet.getDrawingPatriarch();
+
+        /**
+         * 3072 - main SpContainer id
+         * 3073 - existing shape id
+         */
+        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 3074);
+        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 3075);
+        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 3076);
+
+
+        sheet = wb.getSheetAt(2);
+        patriarch = sheet.getDrawingPatriarch();
+
+        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 1026);
+        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 1027);
+        assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 1028);
+    }
 }

Modified: poi/branches/gsoc2012/src/testcases/org/apache/poi/hssf/usermodel/HSSFTestHelper.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/testcases/org/apache/poi/hssf/usermodel/HSSFTestHelper.java?rev=1353960&r1=1353959&r2=1353960&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/testcases/org/apache/poi/hssf/usermodel/HSSFTestHelper.java (original)
+++ poi/branches/gsoc2012/src/testcases/org/apache/poi/hssf/usermodel/HSSFTestHelper.java Tue Jun 26 11:21:13 2012
@@ -43,4 +43,8 @@ public class HSSFTestHelper {
     public static EscherAggregate getEscherAggregate(HSSFPatriarch patriarch){
         return patriarch._getBoundAggregate();
     }
+
+    public static int allocateNewShapeId(HSSFPatriarch patriarch){
+        return patriarch.newShapeId();
+    }
 }

Added: poi/branches/gsoc2012/src/testcases/org/apache/poi/hssf/usermodel/TestText.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/testcases/org/apache/poi/hssf/usermodel/TestText.java?rev=1353960&view=auto
==============================================================================
--- poi/branches/gsoc2012/src/testcases/org/apache/poi/hssf/usermodel/TestText.java (added)
+++ poi/branches/gsoc2012/src/testcases/org/apache/poi/hssf/usermodel/TestText.java Tue Jun 26 11:21:13 2012
@@ -0,0 +1,186 @@
+package org.apache.poi.hssf.usermodel;
+
+import junit.framework.TestCase;
+import org.apache.poi.hssf.HSSFTestDataSamples;
+import org.apache.poi.hssf.model.HSSFTestModelHelper;
+import org.apache.poi.hssf.model.TextboxShape;
+import org.apache.poi.hssf.record.CommonObjectDataSubRecord;
+import org.apache.poi.hssf.record.ObjRecord;
+import org.apache.poi.hssf.record.TextObjectRecord;
+
+import java.util.Arrays;
+
+/**
+ * @author Evgeniy Berlog
+ * @date 25.06.12
+ */
+public class TestText extends TestCase {
+
+    public void testResultEqualsToAbstractShape() {
+        HSSFWorkbook wb = new HSSFWorkbook();
+        HSSFSheet sh = wb.createSheet();
+        HSSFPatriarch patriarch = sh.createDrawingPatriarch();
+        HSSFTextbox textbox = patriarch.createTextbox(new HSSFClientAnchor());
+        TextboxShape textboxShape = HSSFTestModelHelper.createTextboxShape(0, textbox);
+
+        assertEquals(textbox.getEscherContainer().getChildRecords().size(), 5);
+        assertEquals(textboxShape.getSpContainer().getChildRecords().size(), 5);
+
+        //sp record
+        byte[] expected = textboxShape.getSpContainer().getChild(0).serialize();
+        byte[] actual = textbox.getEscherContainer().getChild(0).serialize();
+
+        assertEquals(expected.length, actual.length);
+        assertTrue(Arrays.equals(expected, actual));
+
+        expected = textboxShape.getSpContainer().getChild(2).serialize();
+        actual = textbox.getEscherContainer().getChild(2).serialize();
+
+        assertEquals(expected.length, actual.length);
+        assertTrue(Arrays.equals(expected, actual));
+
+        expected = textboxShape.getSpContainer().getChild(3).serialize();
+        actual = textbox.getEscherContainer().getChild(3).serialize();
+
+        assertEquals(expected.length, actual.length);
+        assertTrue(Arrays.equals(expected, actual));
+
+        expected = textboxShape.getSpContainer().getChild(4).serialize();
+        actual = textbox.getEscherContainer().getChild(4).serialize();
+
+        assertEquals(expected.length, actual.length);
+        assertTrue(Arrays.equals(expected, actual));
+
+        ObjRecord obj = textbox.getObjRecord();
+        ((CommonObjectDataSubRecord) obj.getSubRecords().get(0)).setObjectId(-1024);
+        ObjRecord objShape = textboxShape.getObjRecord();
+
+        expected = obj.serialize();
+        actual = objShape.serialize();
+
+        assertEquals(expected.length, actual.length);
+        assertTrue(Arrays.equals(expected, actual));
+
+        TextObjectRecord tor = textbox.getTextObjectRecord();
+        TextObjectRecord torShape = textboxShape.getTextObjectRecord();
+
+        expected = tor.serialize();
+        actual = torShape.serialize();
+
+        assertEquals(expected.length, actual.length);
+        assertTrue(Arrays.equals(expected, actual));
+    }
+
+    public void testAddTextToExistingFile() {
+        HSSFWorkbook wb = new HSSFWorkbook();
+        HSSFSheet sh = wb.createSheet();
+        HSSFPatriarch patriarch = sh.createDrawingPatriarch();
+        HSSFTextbox textbox = patriarch.createTextbox(new HSSFClientAnchor());
+        textbox.setString(new HSSFRichTextString("just for test"));
+        HSSFTextbox textbox2 = patriarch.createTextbox(new HSSFClientAnchor());
+        textbox2.setString(new HSSFRichTextString("just for test2"));
+
+        assertEquals(patriarch.getChildren().size(), 2);
+
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
+        sh = wb.getSheetAt(0);
+        patriarch = sh.getDrawingPatriarch();
+
+        assertEquals(patriarch.getChildren().size(), 2);
+        HSSFTextbox text3 = patriarch.createTextbox(new HSSFClientAnchor());
+        text3.setString(new HSSFRichTextString("text3"));
+        assertEquals(patriarch.getChildren().size(), 3);
+
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
+        sh = wb.getSheetAt(0);
+        patriarch = sh.getDrawingPatriarch();
+
+        assertEquals(patriarch.getChildren().size(), 3);
+        assertEquals(((HSSFTextbox) patriarch.getChildren().get(0)).getString().getString(), "just for test");
+        assertEquals(((HSSFTextbox) patriarch.getChildren().get(1)).getString().getString(), "just for test2");
+        assertEquals(((HSSFTextbox) patriarch.getChildren().get(2)).getString().getString(), "text3");
+    }
+
+    public void testSetGetProperties() {
+        HSSFWorkbook wb = new HSSFWorkbook();
+        HSSFSheet sh = wb.createSheet();
+        HSSFPatriarch patriarch = sh.createDrawingPatriarch();
+        HSSFTextbox textbox = patriarch.createTextbox(new HSSFClientAnchor());
+        textbox.setString(new HSSFRichTextString("test"));
+        assertEquals(textbox.getString().getString(), "test");
+
+        textbox.setHorizontalAlignment((short) 5);
+        assertEquals(textbox.getHorizontalAlignment(), 5);
+
+        textbox.setVerticalAlignment((short) 6);
+        assertEquals(textbox.getVerticalAlignment(), (short) 6);
+
+        textbox.setMarginBottom(7);
+        assertEquals(textbox.getMarginBottom(), 7);
+
+        textbox.setMarginLeft(8);
+        assertEquals(textbox.getMarginLeft(), 8);
+
+        textbox.setMarginRight(9);
+        assertEquals(textbox.getMarginRight(), 9);
+
+        textbox.setMarginTop(10);
+        assertEquals(textbox.getMarginTop(), 10);
+
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
+        sh = wb.getSheetAt(0);
+        patriarch = sh.getDrawingPatriarch();
+        textbox = (HSSFTextbox) patriarch.getChildren().get(0);
+        assertEquals(textbox.getString().getString(), "test");
+        assertEquals(textbox.getHorizontalAlignment(), 5);
+        assertEquals(textbox.getVerticalAlignment(), (short) 6);
+        assertEquals(textbox.getMarginBottom(), 7);
+        assertEquals(textbox.getMarginLeft(), 8);
+        assertEquals(textbox.getMarginRight(), 9);
+        assertEquals(textbox.getMarginTop(), 10);
+
+        textbox.setString(new HSSFRichTextString("test1"));
+        textbox.setHorizontalAlignment(HSSFTextbox.HORIZONTAL_ALIGNMENT_CENTERED);
+        textbox.setVerticalAlignment(HSSFTextbox.VERTICAL_ALIGNMENT_TOP);
+        textbox.setMarginBottom(71);
+        textbox.setMarginLeft(81);
+        textbox.setMarginRight(91);
+        textbox.setMarginTop(101);
+
+        assertEquals(textbox.getString().getString(), "test1");
+        assertEquals(textbox.getHorizontalAlignment(), HSSFTextbox.HORIZONTAL_ALIGNMENT_CENTERED);
+        assertEquals(textbox.getVerticalAlignment(), HSSFTextbox.VERTICAL_ALIGNMENT_TOP);
+        assertEquals(textbox.getMarginBottom(), 71);
+        assertEquals(textbox.getMarginLeft(), 81);
+        assertEquals(textbox.getMarginRight(), 91);
+        assertEquals(textbox.getMarginTop(), 101);
+
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
+        sh = wb.getSheetAt(0);
+        patriarch = sh.getDrawingPatriarch();
+        textbox = (HSSFTextbox) patriarch.getChildren().get(0);
+
+        assertEquals(textbox.getString().getString(), "test1");
+        assertEquals(textbox.getHorizontalAlignment(), HSSFTextbox.HORIZONTAL_ALIGNMENT_CENTERED);
+        assertEquals(textbox.getVerticalAlignment(), HSSFTextbox.VERTICAL_ALIGNMENT_TOP);
+        assertEquals(textbox.getMarginBottom(), 71);
+        assertEquals(textbox.getMarginLeft(), 81);
+        assertEquals(textbox.getMarginRight(), 91);
+        assertEquals(textbox.getMarginTop(), 101);
+    }
+
+    public void testExistingFileWithText(){
+        HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls");
+        HSSFSheet sheet = wb.getSheet("text");
+        HSSFPatriarch drawing = sheet.getDrawingPatriarch();
+        assertEquals(1, drawing.getChildren().size());
+        HSSFTextbox textbox = (HSSFTextbox) drawing.getChildren().get(0);
+        assertEquals(textbox.getHorizontalAlignment(), HSSFTextbox.HORIZONTAL_ALIGNMENT_LEFT);
+        assertEquals(textbox.getVerticalAlignment(), HSSFTextbox.VERTICAL_ALIGNMENT_TOP);
+        assertEquals(textbox.getMarginTop(), 0);
+        assertEquals(textbox.getMarginBottom(), 3600000);
+        assertEquals(textbox.getMarginLeft(), 3600000);
+        assertEquals(textbox.getMarginRight(), 0);
+        assertEquals(textbox.getString().getString(), "teeeeesssstttt");
+    }
+}

Modified: poi/branches/gsoc2012/test-data/spreadsheet/drawings.xls
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/test-data/spreadsheet/drawings.xls?rev=1353960&r1=1353959&r2=1353960&view=diff
==============================================================================
Binary files - no diff available.

Added: poi/branches/gsoc2012/test-data/spreadsheet/empty.xls
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/test-data/spreadsheet/empty.xls?rev=1353960&view=auto
==============================================================================
Binary file - no diff available.

Propchange: poi/branches/gsoc2012/test-data/spreadsheet/empty.xls
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org