]> source.dussan.org Git - poi.git/commitdiff
implemented work with existing shape groups and polygons
authorEvgeniy Berlog <berlog@apache.org>
Sun, 1 Jul 2012 09:38:08 +0000 (09:38 +0000)
committerEvgeniy Berlog <berlog@apache.org>
Sun, 1 Jul 2012 09:38:08 +0000 (09:38 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/branches/gsoc2012@1355866 13f79535-47bb-0310-9956-ffa450edef68

16 files changed:
src/java/org/apache/poi/ddf/EscherSpRecord.java
src/java/org/apache/poi/hssf/model/PolygonShape.java
src/java/org/apache/poi/hssf/usermodel/HSSFComment.java
src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java
src/java/org/apache/poi/hssf/usermodel/HSSFPolygon.java
src/java/org/apache/poi/hssf/usermodel/HSSFShape.java
src/java/org/apache/poi/hssf/usermodel/HSSFShapeFactory.java
src/java/org/apache/poi/hssf/usermodel/HSSFShapeGroup.java
src/java/org/apache/poi/hssf/usermodel/HSSFSimpleShape.java
src/java/org/apache/poi/hssf/usermodel/HSSFTextbox.java
src/testcases/org/apache/poi/hssf/model/HSSFTestModelHelper.java
src/testcases/org/apache/poi/hssf/model/TestDrawingAggregate.java
src/testcases/org/apache/poi/hssf/usermodel/HSSFTestHelper.java
src/testcases/org/apache/poi/hssf/usermodel/TestPolygon.java [new file with mode: 0644]
src/testcases/org/apache/poi/hssf/usermodel/TestShapeGroup.java [new file with mode: 0644]
test-data/spreadsheet/drawings.xls

index 11a893f466bc6d4dcda680acd015cd4b0f2b8e9e..7d4dd5cfba88c9aa5cf31b3a4118575441502086 100644 (file)
@@ -119,7 +119,7 @@ public class EscherSpRecord
     public String toXml(String tab) {
         StringBuilder builder = new StringBuilder();
         builder.append(tab).append(formatXmlRecordHeader(getClass().getSimpleName(), HexDump.toHex(getRecordId()), HexDump.toHex(getVersion()), HexDump.toHex(getInstance())))
-                .append(tab).append("\t").append("<ShapeType>").append(HexDump.toHex(getShapeType())).append("</ShapeType>\n")
+                .append(tab).append("\t").append("<ShapeType>0x").append(HexDump.toHex(getShapeType())).append("</ShapeType>\n")
                 .append(tab).append("\t").append("<ShapeId>").append(field_1_shapeId).append("</ShapeId>\n")
                 .append(tab).append("\t").append("<Flags>").append(decodeFlags(field_2_flags) + " (0x" + HexDump.toHex(field_2_flags) + ")").append("</Flags>\n");
         builder.append(tab).append("</").append(getClass().getSimpleName()).append(">\n");
index 02308bf48c6637b3b5668af92ced06304407119b..22212c88d2a51c8c92dec019736674e7f8e04f3d 100644 (file)
@@ -63,7 +63,7 @@ public class PolygonShape
         spContainer.setRecordId( EscherContainerRecord.SP_CONTAINER );
         spContainer.setOptions( (short) 0x000F );
         sp.setRecordId( EscherSpRecord.RECORD_ID );
-        sp.setOptions( (short) ( ( EscherAggregate.ST_DONUT << 4 ) | 0x2 ) );
+        sp.setOptions( (short) ( ( EscherAggregate.ST_NOT_PRIMATIVE << 4 ) | 0x2 ) );
         sp.setShapeId( shapeId );
         if (hssfShape.getParent() == null)
             sp.setFlags( EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HASSHAPETYPE );
index 23a792f365e6d2c7cf847ba5bf7f41c767787a20..add7e327288b9b31ab855eba85cb22483f2ab972 100644 (file)
@@ -38,11 +38,6 @@ public class HSSFComment extends HSSFTextbox implements Comment {
       * It seems like HSSFRow should manage a collection of local HSSFComments
       */
 
-    private boolean _visible;
-    private int _row;
-    private int _col;
-    private String _author;
-
     private NoteRecord _note;
 
     public HSSFComment(EscherContainerRecord spContainer, ObjRecord objRecord, TextObjectRecord textObjectRecord, NoteRecord _note) {
index bc3eebc1b374b4537211b13e90c11fa94105d43d..675c7d7f86a2df009392cf02745a100a8b84ca42 100644 (file)
@@ -73,6 +73,7 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
         HSSFShapeGroup group = new HSSFShapeGroup(null, anchor);
         group.anchor = anchor;
         addShape(group);
+        onCreate(group);
         return group;
     }
 
@@ -132,6 +133,7 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
         HSSFPolygon shape = new HSSFPolygon(null, anchor);
         shape.anchor = anchor;
         addShape(shape);
+        onCreate(shape);
         return shape;
     }
 
index 33f17d7e4808aa669d350432cdb9623d897318cf..8d561a0ff1253de2cdb98b9f5496ebea3918d911 100644 (file)
 
 package org.apache.poi.hssf.usermodel;
 
-import org.apache.poi.ddf.EscherContainerRecord;
-import org.apache.poi.ddf.EscherOptRecord;
+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.util.LittleEndian;
 
 /**
  * @author Glen Stampoultzis  (glens at superlinksoftware.com)
  */
-public class HSSFPolygon
-        extends HSSFShape
-{
-    int[] xPoints;
-    int[] yPoints;
-    int drawAreaWidth = 100;
-    int drawAreaHeight = 100;
-
-    HSSFPolygon( HSSFShape parent, HSSFAnchor anchor )
-    {
-        super( parent, anchor );
+public class HSSFPolygon  extends HSSFShape {
+
+    public final static short OBJECT_TYPE_MICROSOFT_OFFICE_DRAWING = 0x1E;
+
+    public HSSFPolygon(EscherContainerRecord spContainer, ObjRecord objRecord) {
+        super(spContainer, objRecord);
     }
 
-    @Override
+    HSSFPolygon(HSSFShape parent, HSSFAnchor anchor) {
+        super(parent, anchor);
+    }
+
+    /**
+     * Generates the shape records for this shape.
+     */
     protected EscherContainerRecord createSpContainer() {
         EscherContainerRecord spContainer = new EscherContainerRecord();
-        spContainer.setRecordId( EscherContainerRecord.SP_CONTAINER );
-        spContainer.setOptions( (short) 0x000F );
-        EscherOptRecord optRecord = new EscherOptRecord();
-        optRecord.setRecordId(EscherOptRecord.RECORD_ID);
-        spContainer.addChildRecord(optRecord);
+        EscherSpRecord sp = new EscherSpRecord();
+        EscherOptRecord opt = new EscherOptRecord();
+        EscherClientDataRecord clientData = new EscherClientDataRecord();
+
+        spContainer.setRecordId(EscherContainerRecord.SP_CONTAINER);
+        spContainer.setOptions((short) 0x000F);
+        sp.setRecordId(EscherSpRecord.RECORD_ID);
+        sp.setOptions((short) ((EscherAggregate.ST_NOT_PRIMATIVE << 4) | 0x2));
+        if (getParent() == null) {
+            sp.setFlags(EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HASSHAPETYPE);
+        } else {
+            sp.setFlags(EscherSpRecord.FLAG_CHILD | EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HASSHAPETYPE);
+        }
+        opt.setRecordId(EscherOptRecord.RECORD_ID);
+        opt.setEscherProperty(new EscherSimpleProperty(EscherProperties.TRANSFORM__ROTATION, false, false, 0));
+        opt.setEscherProperty(new EscherSimpleProperty(EscherProperties.GEOMETRY__RIGHT, false, false, 100));
+        opt.setEscherProperty(new EscherSimpleProperty(EscherProperties.GEOMETRY__BOTTOM, false, false, 100));
+        opt.setEscherProperty(new EscherShapePathProperty(EscherProperties.GEOMETRY__SHAPEPATH, EscherShapePathProperty.COMPLEX));
+
+        opt.setEscherProperty(new EscherSimpleProperty(EscherProperties.GEOMETRY__FILLOK, false, false, 0x00010001));
+        opt.setEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINESTARTARROWHEAD, false, false, 0x0));
+        opt.setEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEENDARROWHEAD, false, false, 0x0));
+        opt.setEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEENDCAPSTYLE, false, false, 0x0));
+
+        opt.setEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEDASHING, LINESTYLE_SOLID));
+        opt.setEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEWIDTH, LINEWIDTH_DEFAULT));
+        opt.setEscherProperty(new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, FILL__FILLCOLOR_DEFAULT));
+        opt.setEscherProperty(new EscherRGBProperty(EscherProperties.LINESTYLE__COLOR, LINESTYLE__COLOR_DEFAULT));
+        opt.setEscherProperty(new EscherBoolProperty(EscherProperties.FILL__NOFILLHITTEST, 0x0));
+
+        EscherRecord anchor = getAnchor().getEscherAnchor();
+        clientData.setRecordId(EscherClientDataRecord.RECORD_ID);
+        clientData.setOptions((short) 0x0000);
+
+        spContainer.addChildRecord(sp);
+        spContainer.addChildRecord(opt);
+        spContainer.addChildRecord(anchor);
+        spContainer.addChildRecord(clientData);
+
         return spContainer;
     }
 
-    @Override
+    /**
+     * Creates the low level OBJ record for this shape.
+     */
     protected ObjRecord createObjRecord() {
-        return null;
-    }
-
-    public int[] getXPoints()
-    {
-        return xPoints;
+        ObjRecord obj = new ObjRecord();
+        CommonObjectDataSubRecord c = new CommonObjectDataSubRecord();
+        c.setObjectType(OBJECT_TYPE_MICROSOFT_OFFICE_DRAWING);
+        c.setLocked(true);
+        c.setPrintable(true);
+        c.setAutofill(true);
+        c.setAutoline(true);
+        EndSubRecord e = new EndSubRecord();
+        obj.addSubRecord(c);
+        obj.addSubRecord(e);
+        return obj;
     }
 
-    public int[] getYPoints()
-    {
-        return yPoints;
+    public int[] getXPoints() {
+        EscherArrayProperty verticesProp = _optRecord.lookup(EscherProperties.GEOMETRY__VERTICES);
+        if (null == verticesProp){
+            return new int[]{};
+        }
+        int []array = new int[verticesProp.getNumberOfElementsInArray()-1];
+        for (int i=0; i< verticesProp.getNumberOfElementsInArray()-1; i++){
+            byte[] property = verticesProp.getElement(i);
+            short x = LittleEndian.getShort(property, 0);
+            array[i] = x;
+        }
+        return array;
     }
 
-    public void setPoints(int[] xPoints, int[] yPoints)
-    {
-        this.xPoints = cloneArray(xPoints);
-        this.yPoints = cloneArray(yPoints);
+    public int[] getYPoints() {
+        EscherArrayProperty verticesProp = _optRecord.lookup(EscherProperties.GEOMETRY__VERTICES);
+        if (null == verticesProp){
+            return new int[]{};
+        }
+        int []array = new int[verticesProp.getNumberOfElementsInArray()-1];
+        for (int i=0; i< verticesProp.getNumberOfElementsInArray()-1; i++){
+            byte[] property = verticesProp.getElement(i);
+            short x = LittleEndian.getShort(property, 2);
+            array[i] = x;
+        }
+        return array;
     }
 
-    private int[] cloneArray( int[] a )
-    {
-        int[] result = new int[a.length];
-        for ( int i = 0; i < a.length; i++ )
-            result[i] = a[i];
-
-        return result;
+    public void setPoints(int[] xPoints, int[] yPoints) {
+        if (xPoints.length != yPoints.length){
+            System.out.println("xPoint.length must be equal to yPoints.length");
+            return;
+        }
+        if (xPoints.length == 0){
+            System.out.println("HSSFPolygon must have at least one point");
+        }
+        EscherArrayProperty verticesProp = new EscherArrayProperty(EscherProperties.GEOMETRY__VERTICES, false, new byte[0] );
+        verticesProp.setNumberOfElementsInArray(xPoints.length+1);
+        verticesProp.setNumberOfElementsInMemory(xPoints.length+1);
+        verticesProp.setSizeOfElements(0xFFF0);
+        for (int i = 0; i < xPoints.length; i++)
+        {
+            byte[] data = new byte[4];
+            LittleEndian.putShort(data, 0, (short)xPoints[i]);
+            LittleEndian.putShort(data, 2, (short)yPoints[i]);
+            verticesProp.setElement(i, data);
+        }
+        int point = xPoints.length;
+        byte[] data = new byte[4];
+        LittleEndian.putShort(data, 0, (short)xPoints[0]);
+        LittleEndian.putShort(data, 2, (short)yPoints[0]);
+        verticesProp.setElement(point, data);
+        setPropertyValue(verticesProp);
+
+        EscherArrayProperty segmentsProp = new EscherArrayProperty(EscherProperties.GEOMETRY__SEGMENTINFO, false, null );
+        segmentsProp.setSizeOfElements(0x0002);
+        segmentsProp.setNumberOfElementsInArray(xPoints.length * 2 + 4);
+        segmentsProp.setNumberOfElementsInMemory(xPoints.length * 2 + 4);
+        segmentsProp.setElement(0, new byte[] { (byte)0x00, (byte)0x40 } );
+        segmentsProp.setElement(1, new byte[] { (byte)0x00, (byte)0xAC } );
+        for (int i = 0; i < xPoints.length; i++)
+        {
+            segmentsProp.setElement(2 + i * 2, new byte[] { (byte)0x01, (byte)0x00 } );
+            segmentsProp.setElement(3 + i * 2, new byte[] { (byte)0x00, (byte)0xAC } );
+        }
+        segmentsProp.setElement(segmentsProp.getNumberOfElementsInArray() - 2, new byte[] { (byte)0x01, (byte)0x60 } );
+        segmentsProp.setElement(segmentsProp.getNumberOfElementsInArray() - 1, new byte[] { (byte)0x00, (byte)0x80 } );
+        setPropertyValue(segmentsProp);
     }
 
     /**
      * Defines the width and height of the points in the polygon
+     *
      * @param width
      * @param height
      */
-    public void setPolygonDrawArea( int width, int height )
-    {
-        this.drawAreaWidth = width;
-        this.drawAreaHeight = height;
+    public void setPolygonDrawArea(int width, int height) {
+        setPropertyValue(new EscherSimpleProperty(EscherProperties.GEOMETRY__RIGHT, width));
+        setPropertyValue(new EscherSimpleProperty(EscherProperties.GEOMETRY__BOTTOM, height));
     }
 
-    public int getDrawAreaWidth()
-    {
-        return drawAreaWidth;
+    public int getDrawAreaWidth() {
+        EscherSimpleProperty property = _optRecord.lookup(EscherProperties.GEOMETRY__RIGHT);
+        return property == null ? 100: property.getPropertyValue();
     }
 
-    public int getDrawAreaHeight()
-    {
-        return drawAreaHeight;
+    public int getDrawAreaHeight() {
+        EscherSimpleProperty property = _optRecord.lookup(EscherProperties.GEOMETRY__BOTTOM);
+        return property == null ? 100: property.getPropertyValue();
     }
 
-
+    @Override
+    void afterInsert(HSSFPatriarch patriarch) {
+        EscherAggregate agg = patriarch._getBoundAggregate();
+        agg.associateShapeToObjRecord(_escherContainer.getChildById(EscherClientDataRecord.RECORD_ID), getObjRecord());
+    }
 }
index 9c2775373f79f1f9efb6060db212fa9d7728b9be..09bf271fc5c0d59c6fa90612cfe7ad3d35af55b9 100644 (file)
@@ -72,7 +72,6 @@ public abstract class HSSFShape {
         this.anchor = anchor;
         this._escherContainer = createSpContainer();
         _optRecord = _escherContainer.getChildById(EscherOptRecord.RECORD_ID);
-        addStandardOptions(_optRecord);
         _objRecord = createObjRecord();
 
     }
@@ -87,14 +86,6 @@ public abstract class HSSFShape {
         CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) _objRecord.getSubRecords().get(0);
         cod.setObjectId((short) (shapeId-1024));
     }
-
-    private void addStandardOptions(EscherOptRecord optRecord){
-        setPropertyValue(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEDASHING, LINESTYLE_SOLID));
-        setPropertyValue(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEWIDTH, LINEWIDTH_DEFAULT));
-        setPropertyValue(new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, FILL__FILLCOLOR_DEFAULT));
-        setPropertyValue(new EscherRGBProperty(EscherProperties.LINESTYLE__COLOR, LINESTYLE__COLOR_DEFAULT));
-        setPropertyValue(new EscherBoolProperty(EscherProperties.FILL__NOFILLHITTEST, 0x0));
-    }
     
     int getShapeId(){
         return ((EscherSpRecord)_escherContainer.getChildById(EscherSpRecord.RECORD_ID)).getShapeId();
index 5358f4868fd0f91a7c5270168fc8bf05e2ed8832..1ee53171b6117238b32f30c9942fafb66f0b388d 100644 (file)
 \r
 package org.apache.poi.hssf.usermodel;\r
 \r
-import org.apache.poi.ddf.EscherClientDataRecord;\r
-import org.apache.poi.ddf.EscherContainerRecord;\r
-import org.apache.poi.ddf.EscherRecord;\r
-import org.apache.poi.ddf.EscherSpRecord;\r
-import org.apache.poi.ddf.EscherSpgrRecord;\r
-import org.apache.poi.ddf.EscherTextboxRecord;\r
+import org.apache.poi.ddf.*;\r
 import org.apache.poi.hssf.model.TextboxShape;\r
 import org.apache.poi.hssf.record.CommonObjectDataSubRecord;\r
 import org.apache.poi.hssf.record.EscherAggregate;\r
@@ -124,6 +119,15 @@ public class HSSFShapeFactory {
                 case CommonObjectDataSubRecord.OBJECT_TYPE_RECTANGLE:\r
                     shape = new HSSFSimpleShape(container, objRecord);\r
                     break;\r
+                case CommonObjectDataSubRecord.OBJECT_TYPE_MICROSOFT_OFFICE_DRAWING:\r
+                    EscherOptRecord optRecord = container.getChildById(EscherOptRecord.RECORD_ID);\r
+                    EscherProperty property = optRecord.lookup(EscherProperties.GEOMETRY__VERTICES);\r
+                    if (null != property){\r
+                        shape = new HSSFPolygon(container, objRecord);    \r
+                    } else {\r
+                        shape = new HSSFSimpleShape(container, objRecord);\r
+                    }\r
+                    break;\r
                 case CommonObjectDataSubRecord.OBJECT_TYPE_TEXT:\r
                     shape = new HSSFTextbox(container, objRecord, txtRecord);\r
                     break;\r
index d98471e33a3cc5dd749754362ff1578040fb8c82..eb023e0cae75eb67fe04ed630fb64a3b663f16af 100644 (file)
@@ -19,8 +19,7 @@ package org.apache.poi.hssf.usermodel;
 
 import org.apache.poi.ddf.*;
 import org.apache.poi.hssf.model.TextboxShape;
-import org.apache.poi.hssf.record.EscherAggregate;
-import org.apache.poi.hssf.record.ObjRecord;
+import org.apache.poi.hssf.record.*;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -32,10 +31,7 @@ import java.util.Iterator;
  *
  * @author Glen Stampoultzis (glens at apache.org)
  */
-public class HSSFShapeGroup
-        extends HSSFShape
-        implements HSSFShapeContainer
-{
+public class HSSFShapeGroup extends HSSFShape implements HSSFShapeContainer {
     List<HSSFShape> shapes = new ArrayList<HSSFShape>();
     private EscherSpgrRecord _spgrRecord;
 
@@ -45,24 +41,22 @@ public class HSSFShapeGroup
         // read internal and external coordinates from spgrContainer
         EscherContainerRecord spContainer = spgrContainer.getChildContainers().get(0);
         _spgrRecord = (EscherSpgrRecord) spContainer.getChild(0);
-        for(EscherRecord ch : spContainer.getChildRecords()){
-            switch(ch.getRecordId()) {
+        for (EscherRecord ch : spContainer.getChildRecords()) {
+            switch (ch.getRecordId()) {
                 case EscherSpgrRecord.RECORD_ID:
                     break;
                 case EscherClientAnchorRecord.RECORD_ID:
-                    anchor = new HSSFClientAnchor((EscherClientAnchorRecord)ch);
+                    anchor = new HSSFClientAnchor((EscherClientAnchorRecord) ch);
                     break;
                 case EscherChildAnchorRecord.RECORD_ID:
-                    anchor = new HSSFChildAnchor((EscherChildAnchorRecord)ch);
+                    anchor = new HSSFChildAnchor((EscherChildAnchorRecord) ch);
                     break;
             }
         }
-
     }
 
-    public HSSFShapeGroup( HSSFShape parent, HSSFAnchor anchor )
-    {
-        super( parent, anchor );
+    public HSSFShapeGroup(HSSFShape parent, HSSFAnchor anchor) {
+        super(parent, anchor);
         _spgrRecord = new EscherSpgrRecord();
         _spgrRecord.setRectX1(0);
         _spgrRecord.setRectX2(1023);
@@ -72,104 +66,169 @@ public class HSSFShapeGroup
 
     @Override
     protected EscherContainerRecord createSpContainer() {
+        EscherContainerRecord spgrContainer = new EscherContainerRecord();
         EscherContainerRecord spContainer = new EscherContainerRecord();
-        spContainer.setRecordId( EscherContainerRecord.SP_CONTAINER );
-        spContainer.setOptions( (short) 0x000F );
-        EscherOptRecord optRecord = new EscherOptRecord();
-        optRecord.setRecordId(EscherOptRecord.RECORD_ID);
-        spContainer.addChildRecord(optRecord);
-        return spContainer;
+        EscherSpgrRecord spgr = new EscherSpgrRecord();
+        EscherSpRecord sp = new EscherSpRecord();
+        EscherOptRecord opt = new EscherOptRecord();
+        EscherRecord anchor;
+        EscherClientDataRecord clientData = new EscherClientDataRecord();
+
+        spgrContainer.setRecordId(EscherContainerRecord.SPGR_CONTAINER);
+        spgrContainer.setOptions((short) 0x000F);
+        spContainer.setRecordId(EscherContainerRecord.SP_CONTAINER);
+        spContainer.setOptions((short) 0x000F);
+        spgr.setRecordId(EscherSpgrRecord.RECORD_ID);
+        spgr.setOptions((short) 0x0001);
+        spgr.setRectX1(0);
+        spgr.setRectY1(0);
+        spgr.setRectX2(1023);
+        spgr.setRectY2(255);
+        sp.setRecordId(EscherSpRecord.RECORD_ID);
+        sp.setOptions((short) 0x0002);
+        if (getAnchor() instanceof HSSFClientAnchor) {
+            sp.setFlags(EscherSpRecord.FLAG_GROUP | EscherSpRecord.FLAG_HAVEANCHOR);
+        } else {
+            sp.setFlags(EscherSpRecord.FLAG_GROUP | EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_CHILD);
+        }
+        opt.setRecordId(EscherOptRecord.RECORD_ID);
+        opt.setOptions((short) 0x0023);
+        opt.addEscherProperty(new EscherBoolProperty(EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 0x00040004));
+        opt.addEscherProperty(new EscherBoolProperty(EscherProperties.GROUPSHAPE__PRINT, 0x00080000));
+
+        anchor = getAnchor().getEscherAnchor();
+        clientData.setRecordId(EscherClientDataRecord.RECORD_ID);
+        clientData.setOptions((short) 0x0000);
+
+        spgrContainer.addChildRecord(spContainer);
+        spContainer.addChildRecord(spgr);
+        spContainer.addChildRecord(sp);
+        spContainer.addChildRecord(opt);
+        spContainer.addChildRecord(anchor);
+        spContainer.addChildRecord(clientData);
+        return spgrContainer;
     }
 
     @Override
     protected ObjRecord createObjRecord() {
-        return null;  //To change body of implemented methods use File | Settings | File Templates.
+        ObjRecord obj = new ObjRecord();
+        CommonObjectDataSubRecord cmo = new CommonObjectDataSubRecord();
+        cmo.setObjectType(CommonObjectDataSubRecord.OBJECT_TYPE_GROUP);
+        cmo.setLocked(true);
+        cmo.setPrintable(true);
+        cmo.setAutofill(true);
+        cmo.setAutoline(true);
+        GroupMarkerSubRecord gmo = new GroupMarkerSubRecord();
+        EndSubRecord end = new EndSubRecord();
+        obj.addSubRecord(cmo);
+        obj.addSubRecord(gmo);
+        obj.addSubRecord(end);
+        return obj;
+    }
+
+    private void onCreate(HSSFShape shape){
+        if(_patriarch != null && _patriarch._getBoundAggregate().getPatriarch() == null){
+            EscherContainerRecord spContainer = shape.getEscherContainer();
+            int shapeId = _patriarch.newShapeId();
+            shape.setShapeId(shapeId);
+            _escherContainer.addChildRecord(spContainer);
+            shape.afterInsert(_patriarch);
+        }
     }
 
     /**
      * Create another group under this group.
-     * @param anchor    the position of the new group.
-     * @return  the group
+     *
+     * @param anchor the position of the new group.
+     * @return the group
      */
-    public HSSFShapeGroup createGroup(HSSFChildAnchor anchor)
-    {
+    public HSSFShapeGroup createGroup(HSSFChildAnchor anchor) {
         HSSFShapeGroup group = new HSSFShapeGroup(this, anchor);
+        group.parent = this;
         group.anchor = anchor;
         shapes.add(group);
+        onCreate(group);
         return group;
     }
 
-    public void addShape(HSSFShape shape){
+    public void addShape(HSSFShape shape) {
         shape._patriarch = this._patriarch;
+        shape.parent = this;
         shapes.add(shape);
     }
 
-    public void addTextBox(TextboxShape textboxShape){
+    public void addTextBox(TextboxShape textboxShape) {
 //        HSSFTextbox shape = new HSSFTextbox(this, textboxShape.geanchor);
 //        shapes.add(textboxShape);
     }
 
     /**
      * Create a new simple shape under this group.
-     * @param anchor    the position of the shape.
-     * @return  the shape
+     *
+     * @param anchor the position of the shape.
+     * @return the shape
      */
-    public HSSFSimpleShape createShape(HSSFChildAnchor anchor)
-    {
+    public HSSFSimpleShape createShape(HSSFChildAnchor anchor) {
         HSSFSimpleShape shape = new HSSFSimpleShape(this, anchor);
+        shape.parent = this;
         shape.anchor = anchor;
         shapes.add(shape);
+        onCreate(shape);
         return shape;
     }
 
     /**
      * Create a new textbox under this group.
-     * @param anchor    the position of the shape.
-     * @return  the textbox
+     *
+     * @param anchor the position of the shape.
+     * @return the textbox
      */
-    public HSSFTextbox createTextbox(HSSFChildAnchor anchor)
-    {
+    public HSSFTextbox createTextbox(HSSFChildAnchor anchor) {
         HSSFTextbox shape = new HSSFTextbox(this, anchor);
+        shape.parent = this;
         shape.anchor = anchor;
         shapes.add(shape);
+        onCreate(shape);
         return shape;
     }
 
     /**
      * Creates a polygon
      *
-     * @param anchor    the client anchor describes how this group is attached
-     *                  to the sheet.
-     * @return  the newly created shape.
+     * @param anchor the client anchor describes how this group is attached
+     *               to the sheet.
+     * @return the newly created shape.
      */
-    public HSSFPolygon createPolygon(HSSFChildAnchor anchor)
-    {
+    public HSSFPolygon createPolygon(HSSFChildAnchor anchor) {
         HSSFPolygon shape = new HSSFPolygon(this, anchor);
+        shape.parent = this;
         shape.anchor = anchor;
         shapes.add(shape);
+        onCreate(shape);
         return shape;
     }
 
     /**
      * Creates a picture.
      *
-     * @param anchor    the client anchor describes how this group is attached
-     *                  to the sheet.
-     * @return  the newly created shape.
+     * @param anchor the client anchor describes how this group is attached
+     *               to the sheet.
+     * @return the newly created shape.
      */
-    public HSSFPicture createPicture(HSSFChildAnchor anchor, int pictureIndex)
-    {
-      HSSFPicture shape = new HSSFPicture(this, anchor);
-      shape.anchor = anchor;
-      shape.setPictureIndex( pictureIndex );
-      shapes.add(shape);
-      return shape;
+    public HSSFPicture createPicture(HSSFChildAnchor anchor, int pictureIndex) {
+        HSSFPicture shape = new HSSFPicture(this, anchor);
+        shape.parent = this;
+        shape.anchor = anchor;
+        shape.setPictureIndex(pictureIndex);
+        shapes.add(shape);
+        onCreate(shape);
+        return shape;
     }
+
     /**
      * Return all children contained by this shape.
      */
-    public List<HSSFShape> getChildren()
-    {
+    public List<HSSFShape> getChildren() {
         return shapes;
     }
 
@@ -177,8 +236,7 @@ public class HSSFShapeGroup
      * Sets the coordinate space of this group.  All children are constrained
      * to these coordinates.
      */
-    public void setCoordinates( int x1, int y1, int x2, int y2 )
-    {
+    public void setCoordinates(int x1, int y1, int x2, int y2) {
         _spgrRecord.setRectX1(x1);
         _spgrRecord.setRectX2(x2);
         _spgrRecord.setRectY1(y1);
@@ -188,46 +246,62 @@ public class HSSFShapeGroup
     /**
      * The top left x coordinate of this group.
      */
-    public int getX1()
-    {
+    public int getX1() {
         return _spgrRecord.getRectX1();
     }
 
     /**
      * The top left y coordinate of this group.
      */
-    public int getY1()
-    {
+    public int getY1() {
         return _spgrRecord.getRectY1();
     }
 
     /**
      * The bottom right x coordinate of this group.
      */
-    public int getX2()
-    {
+    public int getX2() {
         return _spgrRecord.getRectX2();
     }
 
     /**
      * The bottom right y coordinate of this group.
      */
-    public int getY2()
-    {
+    public int getY2() {
         return _spgrRecord.getRectY2();
     }
 
     /**
      * Count of all children and their childrens children.
      */
-    public int countOfAllChildren()
-    {
+    public int countOfAllChildren() {
         int count = shapes.size();
-        for ( Iterator iterator = shapes.iterator(); iterator.hasNext(); )
-        {
+        for (Iterator iterator = shapes.iterator(); iterator.hasNext(); ) {
             HSSFShape shape = (HSSFShape) iterator.next();
             count += shape.countOfAllChildren();
         }
         return count;
     }
+
+    @Override
+    void afterInsert(HSSFPatriarch patriarch){
+        EscherAggregate agg = patriarch._getBoundAggregate();
+        EscherContainerRecord containerRecord = _escherContainer.getChildById(EscherContainerRecord.SP_CONTAINER);
+        agg.associateShapeToObjRecord(containerRecord.getChildById(EscherClientDataRecord.RECORD_ID), getObjRecord());
+    }
+
+    @Override
+    void setShapeId(int shapeId){
+        EscherContainerRecord containerRecord = _escherContainer.getChildById(EscherContainerRecord.SP_CONTAINER);
+        EscherSpRecord spRecord = containerRecord.getChildById(EscherSpRecord.RECORD_ID);
+        spRecord.setShapeId(shapeId);
+        CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) _objRecord.getSubRecords().get(0);
+        cod.setObjectId((short) (shapeId-1024));
+    }
+
+    @Override
+    int getShapeId(){
+        EscherContainerRecord containerRecord = _escherContainer.getChildById(EscherContainerRecord.SP_CONTAINER);
+        return ((EscherSpRecord)containerRecord.getChildById(EscherSpRecord.RECORD_ID)).getShapeId();
+    }
 }
index 2b64faaa5abef9348870490e48fc9b2eb067cdd7..62b9d6a8e0def364e856b561a62d1792255d2176 100644 (file)
@@ -32,8 +32,7 @@ import java.util.Map;
  *
  * @author Glen Stampoultzis (glens at apache.org)
  */
-public class HSSFSimpleShape
-    extends HSSFShape
+public class HSSFSimpleShape extends HSSFShape
 {
     // The commented out ones haven't been tested yet or aren't supported
     // by HSSFSimpleShape.
@@ -93,6 +92,11 @@ public class HSSFSimpleShape
         clientData.setOptions( (short) 0x0000 );
 
         EscherOptRecord optRecord = new EscherOptRecord();
+        optRecord.setEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEDASHING, LINESTYLE_SOLID));
+        optRecord.setEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEWIDTH, LINEWIDTH_DEFAULT));
+        optRecord.setEscherProperty(new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, FILL__FILLCOLOR_DEFAULT));
+        optRecord.setEscherProperty(new EscherRGBProperty(EscherProperties.LINESTYLE__COLOR, LINESTYLE__COLOR_DEFAULT));
+        optRecord.setEscherProperty(new EscherBoolProperty(EscherProperties.FILL__NOFILLHITTEST, 0x0));
         optRecord.setRecordId( EscherOptRecord.RECORD_ID );
 
         spContainer.addChildRecord(sp);
index 42385a87ed0de7ccac1efa67087bdef406463564..1ed70f86a675f30ccc00b482796a886f3c75122b 100644 (file)
@@ -118,6 +118,12 @@ public class HSSFTextbox extends HSSFSimpleShape {
         opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.TEXT__TEXTTOP, 0));
         opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.TEXT__TEXTBOTTOM, 0));
 
+        opt.setEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEDASHING, LINESTYLE_SOLID));
+        opt.setEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEWIDTH, LINEWIDTH_DEFAULT));
+        opt.setEscherProperty(new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, FILL__FILLCOLOR_DEFAULT));
+        opt.setEscherProperty(new EscherRGBProperty(EscherProperties.LINESTYLE__COLOR, LINESTYLE__COLOR_DEFAULT));
+        opt.setEscherProperty(new EscherBoolProperty(EscherProperties.FILL__NOFILLHITTEST, 0x0));
+
 
         EscherRecord anchor = getAnchor().getEscherAnchor();
         clientData.setRecordId(EscherClientDataRecord.RECORD_ID);
index 507561e7e4e7831ebf1ebc072ef1a54798e2c82c..bc22d17a97c74a3d75daa4b9070fc4318ac55628 100644 (file)
@@ -1,6 +1,7 @@
 package org.apache.poi.hssf.model;\r
 \r
 import org.apache.poi.hssf.usermodel.HSSFComment;\r
+import org.apache.poi.hssf.usermodel.HSSFPolygon;\r
 import org.apache.poi.hssf.usermodel.HSSFTextbox;\r
 \r
 /**\r
@@ -15,4 +16,8 @@ public class HSSFTestModelHelper {
     public static CommentShape createCommentShape(int shapeId, HSSFComment comment){\r
         return new CommentShape(comment, shapeId);\r
     }\r
+\r
+    public static PolygonShape createPolygonShape(int shapeId, HSSFPolygon polygon){\r
+        return new PolygonShape(polygon, shapeId);\r
+    }\r
 }\r
index 18572d6ec1f2c2996683fc09c2b5eb85d9ebc302..1f058c06daa981295b26e4bb908bb08e839e68ba 100644 (file)
@@ -201,7 +201,7 @@ public class TestDrawingAggregate extends TestCase {
 \r
         HSSFPatriarch drawing = sheet.createDrawingPatriarch();\r
         EscherAggregate agg1 = HSSFTestHelper.getEscherAggregate(drawing);\r
-        callConvertPatriarch(agg1);\r
+        HSSFTestHelper.callConvertPatriarch(agg1);\r
         agg1.setPatriarch(null);\r
         \r
         agg.setPatriarch(null);\r
@@ -213,20 +213,7 @@ public class TestDrawingAggregate extends TestCase {
         assertTrue(Arrays.equals(aggS, agg1S));\r
     }\r
 \r
-    private static void callConvertPatriarch(EscherAggregate agg) {\r
-        Method method = null;\r
-        try {\r
-            method = agg.getClass().getDeclaredMethod("convertPatriarch", HSSFPatriarch.class);\r
-            method.setAccessible(true);\r
-            method.invoke(agg, agg.getPatriarch());\r
-        } catch (IllegalAccessException e) {\r
-            e.printStackTrace();\r
-        } catch (NoSuchMethodException e) {\r
-            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.\r
-        } catch (InvocationTargetException e) {\r
-            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.\r
-        }\r
-    }\r
+\r
 \r
     /**\r
      * when reading incomplete data ensure that the serialized bytes\r
index 9b2273c59080a66ec63a8c65570b8c07f146b840..214121d9402ee9e1e053c11f5873a50cb17fd37e 100644 (file)
 ==================================================================== */
 
 package org.apache.poi.hssf.usermodel;
+import org.apache.poi.ddf.EscherContainerRecord;
+import org.apache.poi.ddf.EscherDggRecord;
 import org.apache.poi.ddf.EscherOptRecord;
+import org.apache.poi.hssf.model.DrawingManager2;
 import org.apache.poi.hssf.model.InternalSheet;
 import org.apache.poi.hssf.model.InternalWorkbook;
 import org.apache.poi.hssf.record.EscherAggregate;
 
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Map;
+
 /**
  * Helper class for HSSF tests that aren't within the
  *  HSSF UserModel package, but need to do internal
  *  UserModel things.
  */
 public class HSSFTestHelper {
+
+    private static class MockDrawingManager extends DrawingManager2 {
+//
+//        public MockDrawingManager(EscherDggRecord dgg) {
+//            super(dgg);
+//        }
+
+        public MockDrawingManager (){
+            super(null);
+        }
+
+        @Override
+        public int allocateShapeId(short drawingGroupId) {
+            return 0; //Mock value
+        }
+    }
        /**
         * Lets non UserModel tests at the low level Workbook
         */
@@ -52,4 +75,34 @@ public class HSSFTestHelper {
     public static EscherOptRecord getOptRecord(HSSFShape shape){
         return shape._optRecord;
     }
+
+    public static void convertHSSFGroup(HSSFShapeGroup shape, EscherContainerRecord escherParent, Map shapeToObj){
+        Class clazz = EscherAggregate.class;
+        try {
+            Method method = clazz.getDeclaredMethod("convertGroup", HSSFShapeGroup.class, EscherContainerRecord.class, Map.class);
+            method.setAccessible(true);
+            method.invoke(new EscherAggregate(new MockDrawingManager()), shape, escherParent, shapeToObj);
+        } catch (NoSuchMethodException e) {
+            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
+        } catch (InvocationTargetException e) {
+            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
+        } catch (IllegalAccessException e) {
+            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
+        }
+    }
+
+    public static void callConvertPatriarch(EscherAggregate agg) {
+        Method method = null;
+        try {
+            method = agg.getClass().getDeclaredMethod("convertPatriarch", HSSFPatriarch.class);
+            method.setAccessible(true);
+            method.invoke(agg, agg.getPatriarch());
+        } catch (IllegalAccessException e) {
+            e.printStackTrace();
+        } catch (NoSuchMethodException e) {
+            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
+        } catch (InvocationTargetException e) {
+            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
+        }
+    }
 }
diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestPolygon.java b/src/testcases/org/apache/poi/hssf/usermodel/TestPolygon.java
new file mode 100644 (file)
index 0000000..7c83a0d
--- /dev/null
@@ -0,0 +1,231 @@
+package org.apache.poi.hssf.usermodel;\r
+\r
+import junit.framework.TestCase;\r
+import org.apache.poi.ddf.EscherArrayProperty;\r
+import org.apache.poi.ddf.EscherOptRecord;\r
+import org.apache.poi.ddf.EscherProperties;\r
+import org.apache.poi.ddf.EscherSpRecord;\r
+import org.apache.poi.hssf.HSSFTestDataSamples;\r
+import org.apache.poi.hssf.model.HSSFTestModelHelper;\r
+import org.apache.poi.hssf.model.PolygonShape;\r
+import org.apache.poi.hssf.record.ObjRecord;\r
+\r
+import java.io.IOException;\r
+import java.util.Arrays;\r
+\r
+/**\r
+ * @author Evgeniy Berlog\r
+ * @date 28.06.12\r
+ */\r
+public class TestPolygon extends TestCase{\r
+\r
+    public void testResultEqualsToAbstractShape() throws IOException {\r
+        HSSFWorkbook wb = new HSSFWorkbook();\r
+        HSSFSheet sh = wb.createSheet();\r
+        HSSFPatriarch patriarch = sh.createDrawingPatriarch();\r
+\r
+        HSSFPolygon polygon = patriarch.createPolygon(new HSSFClientAnchor());\r
+        polygon.setPolygonDrawArea( 100, 100 );\r
+        polygon.setPoints( new int[]{0, 90, 50}, new int[]{5, 5, 44} );\r
+        PolygonShape polygonShape = HSSFTestModelHelper.createPolygonShape(1024, polygon);\r
+        polygon.setShapeId(1024);\r
+\r
+        assertEquals(polygon.getEscherContainer().getChildRecords().size(), 4);\r
+        assertEquals(polygonShape.getSpContainer().getChildRecords().size(), 4);\r
+\r
+        //sp record\r
+        byte[] expected = polygonShape.getSpContainer().getChild(0).serialize();\r
+        byte[] actual = polygon.getEscherContainer().getChild(0).serialize();\r
+\r
+        assertEquals(expected.length, actual.length);\r
+        assertTrue(Arrays.equals(expected, actual));\r
+\r
+        expected = polygonShape.getSpContainer().getChild(2).serialize();\r
+        actual = polygon.getEscherContainer().getChild(2).serialize();\r
+\r
+        assertEquals(expected.length, actual.length);\r
+        assertTrue(Arrays.equals(expected, actual));\r
+\r
+        expected = polygonShape.getSpContainer().getChild(3).serialize();\r
+        actual = polygon.getEscherContainer().getChild(3).serialize();\r
+\r
+        assertEquals(expected.length, actual.length);\r
+        assertTrue(Arrays.equals(expected, actual));\r
+\r
+        ObjRecord obj = polygon.getObjRecord();\r
+        ObjRecord objShape = polygonShape.getObjRecord();\r
+\r
+        expected = obj.serialize();\r
+        actual = objShape.serialize();\r
+\r
+        assertEquals(expected.length, actual.length);\r
+        assertTrue(Arrays.equals(expected, actual));\r
+    }\r
+\r
+    public void testPolygonPoints(){\r
+        HSSFWorkbook wb = new HSSFWorkbook();\r
+        HSSFSheet sh = wb.createSheet();\r
+        HSSFPatriarch patriarch = sh.createDrawingPatriarch();\r
+\r
+        HSSFPolygon polygon = patriarch.createPolygon(new HSSFClientAnchor());\r
+        polygon.setPolygonDrawArea( 100, 100 );\r
+        polygon.setPoints( new int[]{0, 90, 50, 90}, new int[]{5, 5, 44, 88} );\r
+\r
+        PolygonShape polygonShape = HSSFTestModelHelper.createPolygonShape(0, polygon);\r
+\r
+        EscherArrayProperty verticesProp1 = polygon._optRecord.lookup(EscherProperties.GEOMETRY__VERTICES);\r
+        EscherArrayProperty verticesProp2 = ((EscherOptRecord)polygonShape.getSpContainer().getChildById(EscherOptRecord.RECORD_ID))\r
+                .lookup(EscherProperties.GEOMETRY__VERTICES);\r
+\r
+        assertEquals(verticesProp1.getNumberOfElementsInArray(), verticesProp2.getNumberOfElementsInArray());\r
+        assertEquals(verticesProp1.toXml(""), verticesProp2.toXml(""));\r
+        \r
+        polygon.setPoints(new int[]{1,2,3}, new int[] {4,5,6});\r
+        assertTrue(Arrays.equals(polygon.getXPoints(), new int[]{1, 2, 3}));\r
+        assertTrue(Arrays.equals(polygon.getYPoints(), new int[]{4, 5, 6}));\r
+\r
+        polygonShape = HSSFTestModelHelper.createPolygonShape(0, polygon);\r
+        verticesProp1 = polygon._optRecord.lookup(EscherProperties.GEOMETRY__VERTICES);\r
+        verticesProp2 = ((EscherOptRecord)polygonShape.getSpContainer().getChildById(EscherOptRecord.RECORD_ID))\r
+                .lookup(EscherProperties.GEOMETRY__VERTICES);\r
+\r
+        assertEquals(verticesProp1.getNumberOfElementsInArray(), verticesProp2.getNumberOfElementsInArray());\r
+        assertEquals(verticesProp1.toXml(""), verticesProp2.toXml(""));\r
+    }\r
+\r
+    public void testSetGetProperties(){\r
+        HSSFWorkbook wb = new HSSFWorkbook();\r
+        HSSFSheet sh = wb.createSheet();\r
+        HSSFPatriarch patriarch = sh.createDrawingPatriarch();\r
+\r
+        HSSFPolygon polygon = patriarch.createPolygon(new HSSFClientAnchor());\r
+        polygon.setPolygonDrawArea( 102, 101 );\r
+        polygon.setPoints( new int[]{1,2,3}, new int[]{4,5,6} );\r
+\r
+        assertTrue(Arrays.equals(polygon.getXPoints(), new int[]{1,2,3}));\r
+        assertTrue(Arrays.equals(polygon.getYPoints(), new int[]{4, 5, 6}));\r
+        assertEquals(polygon.getDrawAreaHeight(), 101);\r
+        assertEquals(polygon.getDrawAreaWidth(), 102);\r
+\r
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
+        sh = wb.getSheetAt(0);\r
+        patriarch = sh.getDrawingPatriarch();\r
+\r
+        polygon = (HSSFPolygon) patriarch.getChildren().get(0);\r
+        assertTrue(Arrays.equals(polygon.getXPoints(), new int[]{1, 2, 3}));\r
+        assertTrue(Arrays.equals(polygon.getYPoints(), new int[]{4, 5, 6}));\r
+        assertEquals(polygon.getDrawAreaHeight(), 101);\r
+        assertEquals(polygon.getDrawAreaWidth(), 102);\r
+\r
+        polygon.setPolygonDrawArea( 1021, 1011 );\r
+        polygon.setPoints( new int[]{11,21,31}, new int[]{41,51,61} );\r
+\r
+        assertTrue(Arrays.equals(polygon.getXPoints(), new int[]{11, 21, 31}));\r
+        assertTrue(Arrays.equals(polygon.getYPoints(), new int[]{41, 51, 61}));\r
+        assertEquals(polygon.getDrawAreaHeight(), 1011);\r
+        assertEquals(polygon.getDrawAreaWidth(), 1021);\r
+\r
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
+        sh = wb.getSheetAt(0);\r
+        patriarch = sh.getDrawingPatriarch();\r
+\r
+        polygon = (HSSFPolygon) patriarch.getChildren().get(0);\r
+\r
+        assertTrue(Arrays.equals(polygon.getXPoints(), new int[]{11, 21, 31}));\r
+        assertTrue(Arrays.equals(polygon.getYPoints(), new int[]{41, 51, 61}));\r
+        assertEquals(polygon.getDrawAreaHeight(), 1011);\r
+        assertEquals(polygon.getDrawAreaWidth(), 1021);\r
+    }\r
+\r
+    public void testAddToExistingFile(){\r
+        HSSFWorkbook wb = new HSSFWorkbook();\r
+        HSSFSheet sh = wb.createSheet();\r
+        HSSFPatriarch patriarch = sh.createDrawingPatriarch();\r
+\r
+        HSSFPolygon polygon = patriarch.createPolygon(new HSSFClientAnchor());\r
+        polygon.setPolygonDrawArea( 102, 101 );\r
+        polygon.setPoints( new int[]{1,2,3}, new int[]{4,5,6} );\r
+\r
+        HSSFPolygon polygon1 = patriarch.createPolygon(new HSSFClientAnchor());\r
+        polygon1.setPolygonDrawArea( 103, 104 );\r
+        polygon1.setPoints( new int[]{11,12,13}, new int[]{14,15,16} );\r
+\r
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
+        sh = wb.getSheetAt(0);\r
+        patriarch = sh.getDrawingPatriarch();\r
+\r
+        assertEquals(patriarch.getChildren().size(), 2);\r
+\r
+        HSSFPolygon polygon2 = patriarch.createPolygon(new HSSFClientAnchor());\r
+        polygon2.setPolygonDrawArea( 203, 204 );\r
+        polygon2.setPoints( new int[]{21,22,23}, new int[]{24,25,26} );\r
+\r
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
+        sh = wb.getSheetAt(0);\r
+        patriarch = sh.getDrawingPatriarch();\r
+\r
+        assertEquals(patriarch.getChildren().size(), 3);\r
+\r
+        polygon = (HSSFPolygon) patriarch.getChildren().get(0);\r
+        polygon1 = (HSSFPolygon) patriarch.getChildren().get(1);\r
+        polygon2 = (HSSFPolygon) patriarch.getChildren().get(2);\r
+\r
+        assertTrue(Arrays.equals(polygon.getXPoints(), new int[]{1, 2, 3}));\r
+        assertTrue(Arrays.equals(polygon.getYPoints(), new int[]{4,5,6}));\r
+        assertEquals(polygon.getDrawAreaHeight(), 101);\r
+        assertEquals(polygon.getDrawAreaWidth(), 102);\r
+\r
+        assertTrue(Arrays.equals(polygon1.getXPoints(), new int[]{11,12,13}));\r
+        assertTrue(Arrays.equals(polygon1.getYPoints(), new int[]{14,15,16}));\r
+        assertEquals(polygon1.getDrawAreaHeight(), 104);\r
+        assertEquals(polygon1.getDrawAreaWidth(), 103);\r
+\r
+        assertTrue(Arrays.equals(polygon2.getXPoints(), new int[]{21,22,23}));\r
+        assertTrue(Arrays.equals(polygon2.getYPoints(), new int[]{24,25,26}));\r
+        assertEquals(polygon2.getDrawAreaHeight(), 204);\r
+        assertEquals(polygon2.getDrawAreaWidth(), 203);\r
+    }\r
+\r
+    public void testExistingFile() throws IOException {\r
+        HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls");\r
+        HSSFSheet sheet = wb.getSheet("polygon");\r
+        HSSFPatriarch drawing = sheet.getDrawingPatriarch();\r
+        assertEquals(1, drawing.getChildren().size());\r
+\r
+        HSSFPolygon polygon = (HSSFPolygon) drawing.getChildren().get(0);\r
+        assertEquals(polygon.getDrawAreaHeight(), 2466975);\r
+        assertEquals(polygon.getDrawAreaWidth(), 3686175);\r
+        assertTrue(Arrays.equals(polygon.getXPoints(), new int[]{0, 0, 31479, 16159, 19676, 20502}));\r
+        assertTrue(Arrays.equals(polygon.getYPoints(), new int[]{0, 0, 36, 56, 34, 18}));\r
+    }\r
+\r
+    public void testPolygonType(){\r
+        HSSFWorkbook wb = new HSSFWorkbook();\r
+        HSSFSheet sh = wb.createSheet();\r
+        HSSFPatriarch patriarch = sh.createDrawingPatriarch();\r
+\r
+        HSSFPolygon polygon = patriarch.createPolygon(new HSSFClientAnchor());\r
+        polygon.setPolygonDrawArea( 102, 101 );\r
+        polygon.setPoints( new int[]{1,2,3}, new int[]{4,5,6} );\r
+\r
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
+        sh = wb.getSheetAt(0);\r
+        patriarch = sh.getDrawingPatriarch();\r
+\r
+        HSSFPolygon polygon1 = patriarch.createPolygon(new HSSFClientAnchor());\r
+        polygon1.setPolygonDrawArea( 102, 101 );\r
+        polygon1.setPoints( new int[]{1,2,3}, new int[]{4,5,6} );\r
+\r
+        EscherSpRecord spRecord = polygon1.getEscherContainer().getChildById(EscherSpRecord.RECORD_ID);\r
+\r
+        spRecord.setShapeType((short)77/**RANDOM**/);\r
+\r
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
+        sh = wb.getSheetAt(0);\r
+        patriarch = sh.getDrawingPatriarch();\r
+\r
+        assertEquals(patriarch.getChildren().size(), 2);\r
+        assertTrue(patriarch.getChildren().get(0) instanceof HSSFPolygon);\r
+        assertTrue(patriarch.getChildren().get(1) instanceof HSSFPolygon);\r
+    }\r
+}\r
diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestShapeGroup.java b/src/testcases/org/apache/poi/hssf/usermodel/TestShapeGroup.java
new file mode 100644 (file)
index 0000000..bdbf25f
--- /dev/null
@@ -0,0 +1,225 @@
+package org.apache.poi.hssf.usermodel;\r
+\r
+import junit.framework.TestCase;\r
+import org.apache.poi.ddf.EscherContainerRecord;\r
+import org.apache.poi.hssf.HSSFTestDataSamples;\r
+import org.apache.poi.hssf.record.ObjRecord;\r
+\r
+import java.util.Arrays;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+/**\r
+ * @author Evgeniy Berlog\r
+ * @date 29.06.12\r
+ */\r
+public class TestShapeGroup extends TestCase{\r
+\r
+    public void testResultEqualsToAbstractShape() {\r
+        HSSFWorkbook wb = new HSSFWorkbook();\r
+        HSSFSheet sheet = wb.createSheet();\r
+        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();\r
+        HSSFShapeGroup group = patriarch.createGroup(new HSSFClientAnchor());\r
+\r
+        EscherContainerRecord container = new EscherContainerRecord();\r
+        Map shapeToObj = new HashMap();\r
+        HSSFTestHelper.convertHSSFGroup(group, container, shapeToObj);\r
+\r
+        byte [] actual = group.getEscherContainer().serialize();\r
+        byte [] expected = container.getChild(0).serialize();\r
+\r
+        assertEquals(actual.length, expected.length);\r
+        assertTrue(Arrays.equals(actual, expected));\r
+\r
+        actual = group.getObjRecord().serialize();\r
+        expected = ((ObjRecord)shapeToObj.values().toArray()[0]).serialize();\r
+\r
+        assertEquals(actual.length, expected.length);\r
+        assertTrue(Arrays.equals(actual, expected));\r
+    }\r
+\r
+    public void testSetGetCoordinates(){\r
+        HSSFWorkbook wb = new HSSFWorkbook();\r
+        HSSFSheet sh = wb.createSheet();\r
+        HSSFPatriarch patriarch = sh.createDrawingPatriarch();\r
+        HSSFShapeGroup group = patriarch.createGroup(new HSSFClientAnchor());\r
+        assertEquals(group.getX1(), 0);\r
+        assertEquals(group.getY1(), 0);\r
+        assertEquals(group.getX2(), 1023);\r
+        assertEquals(group.getY2(), 255);\r
+\r
+        group.setCoordinates(1,2,3,4);\r
+\r
+        assertEquals(group.getX1(), 1);\r
+        assertEquals(group.getY1(), 2);\r
+        assertEquals(group.getX2(), 3);\r
+        assertEquals(group.getY2(), 4);\r
+\r
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
+        sh = wb.getSheetAt(0);\r
+        patriarch = sh.getDrawingPatriarch();\r
+\r
+        group = (HSSFShapeGroup) patriarch.getChildren().get(0);\r
+        assertEquals(group.getX1(), 1);\r
+        assertEquals(group.getY1(), 2);\r
+        assertEquals(group.getX2(), 3);\r
+        assertEquals(group.getY2(), 4);\r
+    }\r
+\r
+    public void testAddToExistingFile(){\r
+        HSSFWorkbook wb = new HSSFWorkbook();\r
+        HSSFSheet sh = wb.createSheet();\r
+        HSSFPatriarch patriarch = sh.createDrawingPatriarch();\r
+        HSSFShapeGroup group1 = patriarch.createGroup(new HSSFClientAnchor());\r
+        HSSFShapeGroup group2 = patriarch.createGroup(new HSSFClientAnchor());\r
+\r
+        group1.setCoordinates(1,2,3,4);\r
+        group2.setCoordinates(5,6,7,8);\r
+\r
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
+        sh = wb.getSheetAt(0);\r
+        patriarch = sh.getDrawingPatriarch();\r
+\r
+        assertEquals(patriarch.getChildren().size(), 2);\r
+\r
+        HSSFShapeGroup group3 = patriarch.createGroup(new HSSFClientAnchor());\r
+        group3.setCoordinates(9,10,11,12);\r
+\r
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
+        sh = wb.getSheetAt(0);\r
+        patriarch = sh.getDrawingPatriarch();\r
+\r
+        assertEquals(patriarch.getChildren().size(), 3);\r
+    }\r
+\r
+    public void testModify() throws Exception {\r
+        HSSFWorkbook wb = new HSSFWorkbook();\r
+\r
+        // create a sheet with a text box\r
+        HSSFSheet sheet = wb.createSheet();\r
+        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();\r
+\r
+        HSSFShapeGroup group1 = patriarch.createGroup(new\r
+                HSSFClientAnchor(0,0,0,0,\r
+                (short)0, 0, (short)15, 25));\r
+        group1.setCoordinates(0, 0, 792, 612);\r
+\r
+        HSSFTextbox textbox1 = group1.createTextbox(new\r
+                HSSFChildAnchor(100, 100, 300, 300));\r
+        HSSFRichTextString rt1 = new HSSFRichTextString("Hello, World!");\r
+        textbox1.setString(rt1);\r
+\r
+        // write, read back and check that our text box is there\r
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
+        sheet = wb.getSheetAt(0);\r
+        patriarch = sheet.getDrawingPatriarch();\r
+        assertEquals(1, patriarch.getChildren().size());\r
+\r
+        group1 = (HSSFShapeGroup)patriarch.getChildren().get(0);\r
+        assertEquals(1, group1.getChildren().size());\r
+        textbox1 = (HSSFTextbox)group1.getChildren().get(0);\r
+        assertEquals("Hello, World!", textbox1.getString().getString());\r
+\r
+        // modify anchor\r
+        assertEquals(new HSSFChildAnchor(100, 100, 300, 300),\r
+                textbox1.getAnchor());\r
+        HSSFChildAnchor newAnchor = new HSSFChildAnchor(200,200, 400, 400);\r
+        textbox1.setAnchor(newAnchor);\r
+        // modify text\r
+        textbox1.setString(new HSSFRichTextString("Hello, World! (modified)"));\r
+\r
+        // add a new text box\r
+        HSSFTextbox textbox2 = group1.createTextbox(new\r
+                HSSFChildAnchor(400, 400, 600, 600));\r
+        HSSFRichTextString rt2 = new HSSFRichTextString("Hello, World-2");\r
+        textbox2.setString(rt2);\r
+        assertEquals(2, group1.getChildren().size());\r
+\r
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
+        sheet = wb.getSheetAt(0);\r
+        patriarch = sheet.getDrawingPatriarch();\r
+        assertEquals(1, patriarch.getChildren().size());\r
+\r
+        group1 = (HSSFShapeGroup)patriarch.getChildren().get(0);\r
+        assertEquals(2, group1.getChildren().size());\r
+        textbox1 = (HSSFTextbox)group1.getChildren().get(0);\r
+        assertEquals("Hello, World! (modified)",\r
+                textbox1.getString().getString());\r
+        assertEquals(new HSSFChildAnchor(200,200, 400, 400),\r
+                textbox1.getAnchor());\r
+\r
+        textbox2 = (HSSFTextbox)group1.getChildren().get(1);\r
+        assertEquals("Hello, World-2", textbox2.getString().getString());\r
+        assertEquals(new HSSFChildAnchor(400, 400, 600, 600),\r
+                textbox2.getAnchor());\r
+\r
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
+        sheet = wb.getSheetAt(0);\r
+        patriarch = sheet.getDrawingPatriarch();\r
+        group1 = (HSSFShapeGroup)patriarch.getChildren().get(0);\r
+        textbox1 = (HSSFTextbox)group1.getChildren().get(0);\r
+        textbox2 = (HSSFTextbox)group1.getChildren().get(1);\r
+        HSSFTextbox textbox3 = group1.createTextbox(new\r
+                HSSFChildAnchor(400,200, 600, 400));\r
+        HSSFRichTextString rt3 = new HSSFRichTextString("Hello, World-3");\r
+        textbox3.setString(rt3);\r
+    }\r
+\r
+    public void testAddShapesToGroup(){\r
+        HSSFWorkbook wb = new HSSFWorkbook();\r
+\r
+        // create a sheet with a text box\r
+        HSSFSheet sheet = wb.createSheet();\r
+        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();\r
+\r
+        HSSFShapeGroup group = patriarch.createGroup(new HSSFClientAnchor());\r
+        int index = wb.addPicture(new byte[]{1,2,3}, HSSFWorkbook.PICTURE_TYPE_JPEG);\r
+        group.createPicture(new HSSFChildAnchor(), index);\r
+        HSSFPolygon polygon = group.createPolygon(new HSSFChildAnchor());\r
+        polygon.setPoints(new int[]{1,100, 1}, new int[]{1, 50, 100});\r
+        group.createTextbox(new HSSFChildAnchor());\r
+        group.createShape(new HSSFChildAnchor());\r
+\r
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
+        sheet = wb.getSheetAt(0);\r
+        patriarch = sheet.getDrawingPatriarch();\r
+        assertEquals(1, patriarch.getChildren().size());\r
+\r
+        assertTrue(patriarch.getChildren().get(0) instanceof HSSFShapeGroup);\r
+        group = (HSSFShapeGroup) patriarch.getChildren().get(0);\r
+\r
+        assertEquals(group.getChildren().size(), 4);\r
+\r
+        assertTrue(group.getChildren().get(0) instanceof HSSFPicture);\r
+        assertTrue(group.getChildren().get(1) instanceof HSSFPolygon);\r
+        assertTrue(group.getChildren().get(2) instanceof HSSFTextbox);\r
+        assertTrue(group.getChildren().get(3) instanceof HSSFSimpleShape);\r
+\r
+        HSSFShapeGroup group2 = patriarch.createGroup(new HSSFClientAnchor());\r
+\r
+        index = wb.addPicture(new byte[]{2,2,2}, HSSFWorkbook.PICTURE_TYPE_JPEG);\r
+        group2.createPicture(new HSSFChildAnchor(), index);\r
+        polygon = group2.createPolygon(new HSSFChildAnchor());\r
+        polygon.setPoints(new int[]{1,100, 1}, new int[]{1, 50, 100});\r
+        group2.createTextbox(new HSSFChildAnchor());\r
+        group2.createShape(new HSSFChildAnchor());\r
+        group2.createShape(new HSSFChildAnchor());\r
+\r
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
+        sheet = wb.getSheetAt(0);\r
+        patriarch = sheet.getDrawingPatriarch();\r
+        assertEquals(2, patriarch.getChildren().size());\r
+\r
+        group = (HSSFShapeGroup) patriarch.getChildren().get(1);\r
+\r
+        assertEquals(group.getChildren().size(), 5);\r
+\r
+        assertTrue(group.getChildren().get(0) instanceof HSSFPicture);\r
+        assertTrue(group.getChildren().get(1) instanceof HSSFPolygon);\r
+        assertTrue(group.getChildren().get(2) instanceof HSSFTextbox);\r
+        assertTrue(group.getChildren().get(3) instanceof HSSFSimpleShape);\r
+        assertTrue(group.getChildren().get(4) instanceof HSSFSimpleShape);\r
+\r
+        group.getShapeId();\r
+    }\r
+}\r
index 24684cb6ccc0880829ab8de111fe6263a07ebcad..9700c91086f0b771299ce855063de7b2e1c19bcd 100644 (file)
Binary files a/test-data/spreadsheet/drawings.xls and b/test-data/spreadsheet/drawings.xls differ