]> source.dussan.org Git - poi.git/commitdiff
implemented cloning of shapes
authorEvgeniy Berlog <berlog@apache.org>
Thu, 19 Jul 2012 19:02:43 +0000 (19:02 +0000)
committerEvgeniy Berlog <berlog@apache.org>
Thu, 19 Jul 2012 19:02:43 +0000 (19:02 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/branches/gsoc2012@1363479 13f79535-47bb-0310-9956-ffa450edef68

23 files changed:
src/java/org/apache/poi/hssf/model/InternalSheet.java
src/java/org/apache/poi/hssf/record/EscherAggregate.java
src/java/org/apache/poi/hssf/usermodel/HSSFCombobox.java
src/java/org/apache/poi/hssf/usermodel/HSSFComment.java
src/java/org/apache/poi/hssf/usermodel/HSSFObjectData.java
src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java
src/java/org/apache/poi/hssf/usermodel/HSSFPicture.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/HSSFSheet.java
src/java/org/apache/poi/hssf/usermodel/HSSFSimpleShape.java
src/java/org/apache/poi/hssf/usermodel/HSSFTextbox.java
src/java/org/apache/poi/hssf/usermodel/HSSFUnknownShape.java
src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
src/testcases/org/apache/poi/hssf/model/TestDrawingAggregate.java
src/testcases/org/apache/poi/hssf/model/TestDrawingShapes.java
src/testcases/org/apache/poi/hssf/usermodel/HSSFTestHelper.java
src/testcases/org/apache/poi/hssf/usermodel/TestCloneSheet.java
src/testcases/org/apache/poi/hssf/usermodel/TestComment.java
src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.java
src/testcases/org/apache/poi/hssf/usermodel/TestShapeGroup.java

index 09d8e4b80389a4ee3051d9704d25716ac95c9ac6..ce8e5a9bb3e18c8223d3243e35d9f38f13c3adc2 100644 (file)
@@ -354,9 +354,9 @@ public final class InternalSheet {
                 // EscherAggregate is used only as a container for SODRAWING and OBJ record combinations
                 // So, if the container is empty, there is no reason to clone this record
                 // See https://issues.apache.org/bugzilla/show_bug.cgi?id=49529
-                if (0 == rb.getRecordSize()){
+//                if (0 == rb.getRecordSize()){
                     continue;
-                }
+//                }
             }
             Record rec = (Record) ((Record) rb).clone();
             clonedRecords.add(rec);
index 7079cf7dc103e6d5bf61112d410bdb06ffb51cc7..30a815acbb65e4f8c5e0717410c0fcdd09fe9164 100644 (file)
@@ -22,27 +22,16 @@ import java.io.IOException;
 import java.util.*;
 
 import org.apache.poi.ddf.DefaultEscherRecordFactory;
-import org.apache.poi.ddf.EscherBoolProperty;
-import org.apache.poi.ddf.EscherChildAnchorRecord;
-import org.apache.poi.ddf.EscherClientAnchorRecord;
 import org.apache.poi.ddf.EscherClientDataRecord;
 import org.apache.poi.ddf.EscherContainerRecord;
 import org.apache.poi.ddf.EscherDgRecord;
-import org.apache.poi.ddf.EscherDggRecord;
-import org.apache.poi.ddf.EscherOptRecord;
-import org.apache.poi.ddf.EscherProperties;
 import org.apache.poi.ddf.EscherRecord;
 import org.apache.poi.ddf.EscherRecordFactory;
 import org.apache.poi.ddf.EscherSerializationListener;
-import org.apache.poi.ddf.EscherSimpleProperty;
 import org.apache.poi.ddf.EscherSpRecord;
 import org.apache.poi.ddf.EscherSpgrRecord;
 import org.apache.poi.ddf.EscherTextboxRecord;
-import org.apache.poi.hssf.model.AbstractShape;
-import org.apache.poi.hssf.model.CommentShape;
-import org.apache.poi.hssf.model.ConvertAnchor;
 import org.apache.poi.hssf.model.DrawingManager2;
-import org.apache.poi.hssf.model.TextboxShape;
 import org.apache.poi.hssf.usermodel.*;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
@@ -313,8 +302,6 @@ public final class EscherAggregate extends AbstractEscherHolderRecord {
      * Maps shape container objects to their {@link TextObjectRecord} or {@link ObjRecord}
      */
     private final Map<EscherRecord, Record> shapeToObj = new HashMap<EscherRecord, Record>();
-    private DrawingManager2 drawingManager;
-    private short drawingGroupId;
 
     /**
      * list of "tail" records that need to be serialized after all drawing group records
@@ -326,11 +313,6 @@ public final class EscherAggregate extends AbstractEscherHolderRecord {
     }
 
     public EscherAggregate(DrawingManager2 drawingManager) {
-        this.drawingManager = drawingManager;
-    }
-
-    public DrawingManager2 getDrawingManager() {
-        return drawingManager;
     }
 
     /**
@@ -458,8 +440,6 @@ public final class EscherAggregate extends AbstractEscherHolderRecord {
         // replace drawing block with the created EscherAggregate
         records.subList(locFirstDrawingRecord, locLastDrawingRecord).clear();
         records.add(locFirstDrawingRecord, agg);
-
-
         return agg;
     }
 
@@ -472,14 +452,11 @@ public final class EscherAggregate extends AbstractEscherHolderRecord {
      * @return The number of bytes serialized.
      */
     public int serialize(int offset, byte[] data) {
-        convertUserModelToRecords();
-
         // Determine buffer size
         List records = getEscherRecords();
         int size = getEscherRecordSize(records);
         byte[] buffer = new byte[size];
 
-
         // Serialize escher records into one big data structure and keep note of ending offsets.
         final List spEndingOffsets = new ArrayList();
         final List shapes = new ArrayList();
@@ -594,8 +571,6 @@ public final class EscherAggregate extends AbstractEscherHolderRecord {
     }
 
     public int getRecordSize() {
-        // TODO - convert this to RecordAggregate
-        convertUserModelToRecords();
         // To determine size of aggregate record we have to know size of each DrawingRecord because if DrawingRecord
         // is split into several continue records we have to add header size to total EscherAggregate size
         int continueRecordsHeadersSize = 0;
@@ -657,249 +632,6 @@ public final class EscherAggregate extends AbstractEscherHolderRecord {
         shapeToObj.remove(rec);
     }
 
-    public HSSFPatriarch getPatriarch() {
-        return patriarch;
-    }
-
-    public void setPatriarch(HSSFPatriarch patriarch) {
-        this.patriarch = patriarch;
-    }
-
-    /**
-     * Converts the Records into UserModel
-     * objects on the bound HSSFPatriarch
-     */
-    public void convertRecordsToUserModel() {
-        if (patriarch == null) {
-            throw new IllegalStateException("Must call setPatriarch() first");
-        }
-
-        // The top level container ought to have
-        //  the DgRecord and the container of one container
-        //  per shape group (patriach overall first)
-        EscherContainerRecord topContainer = getEscherContainer();
-        if (topContainer == null) {
-            return;
-        }
-        topContainer = topContainer.getChildContainers().get(0);
-
-        List tcc = topContainer.getChildContainers();
-        if (tcc.size() == 0) {
-            throw new IllegalStateException("No child escher containers at the point that should hold the patriach data, and one container per top level shape!");
-        }
-
-        // First up, get the patriach position
-        // This is in the first EscherSpgrRecord, in
-        //  the first container, with a EscherSRecord too
-        EscherContainerRecord patriachContainer =
-                (EscherContainerRecord) tcc.get(0);
-        EscherSpgrRecord spgr = null;
-        for (Iterator<EscherRecord> it = patriachContainer.getChildIterator(); it.hasNext(); ) {
-            EscherRecord r = it.next();
-            if (r instanceof EscherSpgrRecord) {
-                spgr = (EscherSpgrRecord) r;
-                break;
-            }
-        }
-        if (spgr != null) {
-            patriarch.setCoordinates(
-                    spgr.getRectX1(), spgr.getRectY1(),
-                    spgr.getRectX2(), spgr.getRectY2()
-            );
-        }
-
-        convertRecordsToUserModelRecursive(tcc, patriarch, null);
-
-        // Now, clear any trace of what records make up
-        //  the patriarch
-        // Otherwise, everything will go horribly wrong
-        //  when we try to write out again....
-//             clearEscherRecords();
-        drawingManager.getDgg().setFileIdClusters(new EscherDggRecord.FileIdCluster[0]);
-
-        // TODO: Support converting our records
-        // back into shapes
-        // log.log(POILogger.WARN, "Not processing objects into Patriarch!");
-    }
-
-    private static void convertRecordsToUserModelRecursive(List tcc, HSSFShapeContainer container, HSSFShape parent) {
-        // Now process the containers for each group
-        //  and objects
-        for (int i = 1; i < tcc.size(); i++) {
-            EscherContainerRecord shapeContainer = (EscherContainerRecord) tcc.get(i);
-
-            // Could be a group, or a base object
-            if (shapeContainer.getRecordId() == EscherContainerRecord.SPGR_CONTAINER) {
-                // Group
-                final int shapeChildren = shapeContainer.getChildRecords().size();
-                if (shapeChildren > 0) {
-                    HSSFShapeGroup group = new HSSFShapeGroup(parent, new HSSFClientAnchor());
-                    addToParentOrContainer(group, container, parent);
-
-                    EscherContainerRecord groupContainer = (EscherContainerRecord) shapeContainer.getChild(0);
-                    convertRecordsToUserModel(groupContainer, group);
-
-                    if (shapeChildren > 1) {
-                        convertRecordsToUserModelRecursive(shapeContainer.getChildRecords(), container, group);
-                    }
-                } else {
-                    log.log(POILogger.WARN,
-                            "Found drawing group without children.");
-                }
-
-            } else if (shapeContainer.getRecordId() == EscherContainerRecord.SP_CONTAINER) {
-                EscherSpRecord spRecord = shapeContainer
-                        .getChildById(EscherSpRecord.RECORD_ID);
-                int type = spRecord.getShapeType();
-
-                switch (type) {
-                    case ST_TEXTBOX:
-                        HSSFTextbox box = new HSSFTextbox(parent,
-                                new HSSFClientAnchor());
-                        addToParentOrContainer(box, container, parent);
-
-                        convertRecordsToUserModel(shapeContainer, box);
-                        break;
-                    case ST_PICTUREFRAME:
-                        // Duplicated from
-                        // org.apache.poi.hslf.model.Picture.getPictureIndex()
-                        EscherOptRecord opt = (EscherOptRecord) getEscherChild(
-                                shapeContainer, EscherOptRecord.RECORD_ID);
-                        EscherSimpleProperty prop = (EscherSimpleProperty) opt.lookup(
-                                EscherProperties.BLIP__BLIPTODISPLAY);
-                        if (prop == null) {
-                            log.log(POILogger.WARN,
-                                    "Picture index for picture shape not found.");
-                        } else {
-                            int pictureIndex = prop.getPropertyValue();
-
-                            EscherClientAnchorRecord anchorRecord = (EscherClientAnchorRecord) getEscherChild(
-                                    shapeContainer,
-                                    EscherClientAnchorRecord.RECORD_ID);
-
-                            EscherChildAnchorRecord childRecord = (EscherChildAnchorRecord) getEscherChild(
-                                    shapeContainer,
-                                    EscherChildAnchorRecord.RECORD_ID);
-
-                            if (anchorRecord != null && childRecord != null) {
-                                log.log(POILogger.WARN, "Picture with both CLIENT and CHILD anchor: " + type);
-                            }
-
-                            HSSFAnchor anchor;
-                            if (anchorRecord != null) {
-                                anchor = toClientAnchor(anchorRecord);
-                            } else {
-                                anchor = toChildAnchor(childRecord);
-                            }
-
-                            HSSFPicture picture = new HSSFPicture(parent, anchor);
-                            picture.setPictureIndex(pictureIndex);
-
-                            addToParentOrContainer(picture, container, parent);
-                        }
-                        break;
-                    default:
-                        final HSSFSimpleShape shape = new HSSFSimpleShape(parent,
-                                new HSSFClientAnchor());
-                        addToParentOrContainer(shape, container, parent);
-                        convertRecordsToUserModel(shapeContainer, shape);
-
-                        log.log(POILogger.WARN, "Unhandled shape type: "
-                                + type);
-                        break;
-                }
-            } else {
-                log.log(POILogger.WARN, "Unexpected record id of shape group.");
-            }
-
-        }
-    }
-
-    private static void addToParentOrContainer(HSSFShape shape, HSSFShapeContainer container, HSSFShape parent) {
-
-        if (parent instanceof HSSFShapeGroup)
-            ((HSSFShapeGroup) parent).addShape(shape);
-        else if (container instanceof HSSFPatriarch)
-            ((HSSFPatriarch) container).addShape(shape);
-        else
-            container.getChildren().add(shape);
-    }
-
-    public static HSSFClientAnchor toClientAnchor(EscherClientAnchorRecord anchorRecord) {
-        HSSFClientAnchor anchor = new HSSFClientAnchor();
-        anchor.setAnchorType(anchorRecord.getFlag());
-        anchor.setCol1(anchorRecord.getCol1());
-        anchor.setCol2(anchorRecord.getCol2());
-        anchor.setDx1(anchorRecord.getDx1());
-        anchor.setDx2(anchorRecord.getDx2());
-        anchor.setDy1(anchorRecord.getDy1());
-        anchor.setDy2(anchorRecord.getDy2());
-        anchor.setRow1(anchorRecord.getRow1());
-        anchor.setRow2(anchorRecord.getRow2());
-        return anchor;
-    }
-
-    public static HSSFChildAnchor toChildAnchor(EscherChildAnchorRecord anchorRecord) {
-        HSSFChildAnchor anchor = new HSSFChildAnchor();
-//        anchor.setAnchorType(anchorRecord.getFlag());
-//        anchor.setCol1( anchorRecord.getCol1() );
-//        anchor.setCol2( anchorRecord.getCol2() );
-        anchor.setDx1(anchorRecord.getDx1());
-        anchor.setDx2(anchorRecord.getDx2());
-        anchor.setDy1(anchorRecord.getDy1());
-        anchor.setDy2(anchorRecord.getDy2());
-//        anchor.setRow1( anchorRecord.getRow1() );
-//        anchor.setRow2( anchorRecord.getRow2() );
-        return anchor;
-    }
-
-    private static void convertRecordsToUserModel(EscherContainerRecord shapeContainer, Object model) {
-        for (Iterator<EscherRecord> it = shapeContainer.getChildIterator(); it.hasNext(); ) {
-            EscherRecord r = it.next();
-            if (r instanceof EscherSpgrRecord) {
-                // This may be overriden by a later EscherClientAnchorRecord
-                EscherSpgrRecord spgr = (EscherSpgrRecord) r;
-
-                if (model instanceof HSSFShapeGroup) {
-                    HSSFShapeGroup g = (HSSFShapeGroup) model;
-                    g.setCoordinates(
-                            spgr.getRectX1(), spgr.getRectY1(),
-                            spgr.getRectX2(), spgr.getRectY2()
-                    );
-                } else {
-                    throw new IllegalStateException("Got top level anchor but not processing a group");
-                }
-            } else if (r instanceof EscherClientAnchorRecord) {
-                EscherClientAnchorRecord car = (EscherClientAnchorRecord) r;
-
-                if (model instanceof HSSFShape) {
-                    HSSFShape g = (HSSFShape) model;
-                    g.getAnchor().setDx1(car.getDx1());
-                    g.getAnchor().setDx2(car.getDx2());
-                    g.getAnchor().setDy1(car.getDy1());
-                    g.getAnchor().setDy2(car.getDy2());
-                } else {
-                    throw new IllegalStateException("Got top level anchor but not processing a group or shape");
-                }
-            } else if (r instanceof EscherTextboxRecord) {
-                EscherTextboxRecord tbr = (EscherTextboxRecord) r;
-
-                // Also need to find the TextObjectRecord too
-                // TODO
-            } else if (r instanceof EscherSpRecord) {
-                // Use flags if needed
-                final EscherSpRecord spr = (EscherSpRecord) r;
-                if (model instanceof HSSFShape) {
-                    final HSSFShape s = (HSSFShape) model;
-                }
-            } else if (r instanceof EscherOptRecord) {
-                // Use properties if needed
-            } else {
-                //System.err.println(r);
-            }
-        }
-    }
-
     public void clear() {
         clearEscherRecords();
         shapeToObj.clear();
@@ -916,133 +648,6 @@ public final class EscherAggregate extends AbstractEscherHolderRecord {
         return sid(records, loc) == ObjRecord.sid || sid(records, loc) == TextObjectRecord.sid;
     }
 
-    private void convertUserModelToRecords() {
-        if (patriarch != null) {
-            shapeToObj.clear();
-            tailRec.clear();
-            clearEscherRecords();
-            if (patriarch.getChildren().size() != 0) {
-                convertPatriarch(patriarch);
-                EscherContainerRecord dgContainer = (EscherContainerRecord) getEscherRecord(0);
-                EscherContainerRecord spgrContainer = null;
-                Iterator<EscherRecord> iter = dgContainer.getChildIterator();
-                while (iter.hasNext()) {
-                    EscherRecord child = iter.next();
-                    if (child.getRecordId() == EscherContainerRecord.SPGR_CONTAINER) {
-                        spgrContainer = (EscherContainerRecord) child;
-                    }
-                }
-                convertShapes(patriarch, spgrContainer, shapeToObj);
-
-                patriarch = null;
-            }
-        }
-    }
-
-    private void convertShapes(HSSFShapeContainer parent, EscherContainerRecord escherParent, Map shapeToObj) {
-        if (escherParent == null) throw new IllegalArgumentException("Parent record required");
-
-        List shapes = parent.getChildren();
-        for (Iterator iterator = shapes.iterator(); iterator.hasNext(); ) {
-            HSSFShape shape = (HSSFShape) iterator.next();
-            if (shape instanceof HSSFShapeGroup) {
-                convertGroup((HSSFShapeGroup) shape, escherParent, shapeToObj);
-            } else {
-                AbstractShape shapeModel = AbstractShape.createShape(
-                        shape,
-                        drawingManager.allocateShapeId(drawingGroupId));
-                shapeToObj.put(findClientData(shapeModel.getSpContainer()), shapeModel.getObjRecord());
-                if (shapeModel instanceof TextboxShape) {
-                    EscherRecord escherTextbox = ((TextboxShape) shapeModel).getEscherTextbox();
-                    shapeToObj.put(escherTextbox, ((TextboxShape) shapeModel).getTextObjectRecord());
-                    //                                 escherParent.addChildRecord(escherTextbox);
-
-                    if (shapeModel instanceof CommentShape) {
-                        CommentShape comment = (CommentShape) shapeModel;
-                        tailRec.put(comment.getNoteRecord().getShapeId(), comment.getNoteRecord());
-                    }
-
-                }
-                escherParent.addChildRecord(shapeModel.getSpContainer());
-            }
-        }
-//             drawingManager.newCluster( (short)1 );
-//             drawingManager.newCluster( (short)2 );
-
-    }
-
-    private void convertGroup(HSSFShapeGroup shape, EscherContainerRecord escherParent, Map shapeToObj) {
-        EscherContainerRecord spgrContainer = new EscherContainerRecord();
-        EscherContainerRecord spContainer = new EscherContainerRecord();
-        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(shape.getX1());
-        spgr.setRectY1(shape.getY1());
-        spgr.setRectX2(shape.getX2());
-        spgr.setRectY2(shape.getY2());
-        sp.setRecordId(EscherSpRecord.RECORD_ID);
-        sp.setOptions((short) 0x0002);
-        int shapeId = drawingManager.allocateShapeId(drawingGroupId);
-        sp.setShapeId(shapeId);
-        if (shape.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 = ConvertAnchor.createAnchor(shape.getAnchor());
-//             clientAnchor.setCol1( ( (HSSFClientAnchor) shape.getAnchor() ).getCol1() );
-//             clientAnchor.setRow1( (short) ( (HSSFClientAnchor) shape.getAnchor() ).getRow1() );
-//             clientAnchor.setDx1( (short) shape.getAnchor().getDx1() );
-//             clientAnchor.setDy1( (short) shape.getAnchor().getDy1() );
-//             clientAnchor.setCol2( ( (HSSFClientAnchor) shape.getAnchor() ).getCol2() );
-//             clientAnchor.setRow2( (short) ( (HSSFClientAnchor) shape.getAnchor() ).getRow2() );
-//             clientAnchor.setDx2( (short) shape.getAnchor().getDx2() );
-//             clientAnchor.setDy2( (short) shape.getAnchor().getDy2() );
-        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);
-
-        ObjRecord obj = new ObjRecord();
-        CommonObjectDataSubRecord cmo = new CommonObjectDataSubRecord();
-        cmo.setObjectType(CommonObjectDataSubRecord.OBJECT_TYPE_GROUP);
-        cmo.setObjectId(shapeId);
-        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);
-        shapeToObj.put(clientData, obj);
-
-        escherParent.addChildRecord(spgrContainer);
-
-        convertShapes(shape, spgrContainer, shapeToObj);
-
-    }
-
     private EscherRecord findClientData(EscherContainerRecord spContainer) {
         for (Iterator<EscherRecord> iterator = spContainer.getChildIterator(); iterator.hasNext(); ) {
             EscherRecord r = iterator.next();
@@ -1067,7 +672,6 @@ public final class EscherAggregate extends AbstractEscherHolderRecord {
         dg.setOptions((short) (dgId << 4));
         dg.setNumShapes(0);
         dg.setLastMSOSPID(1024);
-        drawingGroupId = dg.getDrawingGroupId();
         spgrContainer.setRecordId(EscherContainerRecord.SPGR_CONTAINER);
         spgrContainer.setOptions((short) 0x000F);
         spContainer1.setRecordId(EscherContainerRecord.SP_CONTAINER);
@@ -1105,46 +709,6 @@ public final class EscherAggregate extends AbstractEscherHolderRecord {
         sp.setShapeId(shapeId);
     }
 
-    private void convertPatriarch(HSSFPatriarch patriarch) {
-        EscherContainerRecord dgContainer = new EscherContainerRecord();
-        EscherDgRecord dg;
-        EscherContainerRecord spgrContainer = new EscherContainerRecord();
-        EscherContainerRecord spContainer1 = new EscherContainerRecord();
-        EscherSpgrRecord spgr = new EscherSpgrRecord();
-        EscherSpRecord sp1 = new EscherSpRecord();
-
-        dgContainer.setRecordId(EscherContainerRecord.DG_CONTAINER);
-        dgContainer.setOptions((short) 0x000F);
-        dg = drawingManager.createDgRecord();
-        drawingGroupId = dg.getDrawingGroupId();
-//             dg.setOptions( (short) ( drawingId << 4 ) );
-//             dg.setNumShapes( getNumberOfShapes( patriarch ) );
-//             dg.setLastMSOSPID( 0 );  // populated after all shape id's are assigned.
-        spgrContainer.setRecordId(EscherContainerRecord.SPGR_CONTAINER);
-        spgrContainer.setOptions((short) 0x000F);
-        spContainer1.setRecordId(EscherContainerRecord.SP_CONTAINER);
-        spContainer1.setOptions((short) 0x000F);
-        spgr.setRecordId(EscherSpgrRecord.RECORD_ID);
-        spgr.setOptions((short) 0x0001);    // version
-        spgr.setRectX1(patriarch.getX1());
-        spgr.setRectY1(patriarch.getY1());
-        spgr.setRectX2(patriarch.getX2());
-        spgr.setRectY2(patriarch.getY2());
-        sp1.setRecordId(EscherSpRecord.RECORD_ID);
-        sp1.setOptions((short) 0x0002);
-        sp1.setShapeId(drawingManager.allocateShapeId(dg.getDrawingGroupId()));
-        sp1.setFlags(EscherSpRecord.FLAG_GROUP | EscherSpRecord.FLAG_PATRIARCH);
-
-        dgContainer.addChildRecord(dg);
-        dgContainer.addChildRecord(spgrContainer);
-        spgrContainer.addChildRecord(spContainer1);
-        spContainer1.addChildRecord(spgr);
-        spContainer1.addChildRecord(sp1);
-
-        addEscherRecord(dgContainer);
-    }
-
-
     private static short sid(List records, int loc) {
         return ((Record) records.get(loc)).getSid();
     }
index 4b13278f0cbc710384e16217b9cf0f145dc81cac..184a6d320131dfbb7cea67ff45e5792bf0773c55 100644 (file)
@@ -18,6 +18,11 @@ public class HSSFCombobox extends HSSFSimpleShape {
         super.setShapeType(OBJECT_TYPE_COMBO_BOX);\r
     }\r
 \r
+    @Override\r
+    protected TextObjectRecord createTextObjRecord() {\r
+        return null;\r
+    }\r
+\r
     @Override\r
     protected EscherContainerRecord createSpContainer() {\r
         EscherContainerRecord spContainer = new EscherContainerRecord();\r
index ea8ae3c7e7dc32ba094a0f7243b70da2052831b5..8bafa3b50728b72ecf14ee6723116b3559769058 100644 (file)
@@ -70,7 +70,7 @@ public class HSSFComment extends HSSFTextbox implements Comment {
     @Override
     void afterInsert(HSSFPatriarch patriarch) {
         super.afterInsert(patriarch);
-        _patriarch._getBoundAggregate().addTailRecord(getNoteRecord());
+        patriarch._getBoundAggregate().addTailRecord(getNoteRecord());
     }
 
     @Override
@@ -113,8 +113,8 @@ public class HSSFComment extends HSSFTextbox implements Comment {
     void setShapeId(int shapeId) {
         super.setShapeId(shapeId);
         CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) getObjRecord().getSubRecords().get(0);
-        cod.setObjectId((short) (shapeId));
-        _note.setShapeId(shapeId);
+        cod.setObjectId((short) (shapeId % 1024));
+        _note.setShapeId(shapeId % 1024);
     }
 
     /**
@@ -214,4 +214,15 @@ public class HSSFComment extends HSSFTextbox implements Comment {
         patriarch._getBoundAggregate().removeShapeToObjRecord(getEscherContainer().getChildById(EscherTextboxRecord.RECORD_ID));
         patriarch._getBoundAggregate().removeTailRecord(getNoteRecord());
     }
+
+    @Override
+    public HSSFShape cloneShape() {
+        TextObjectRecord txo = (TextObjectRecord) getTextObjectRecord().cloneViaReserialise();
+        EscherContainerRecord spContainer = new EscherContainerRecord();
+        byte [] inSp = getEscherContainer().serialize();
+        spContainer.fillFields(inSp, 0, new DefaultEscherRecordFactory());
+        ObjRecord obj = (ObjRecord) getObjRecord().cloneViaReserialise();
+        NoteRecord note = (NoteRecord) getNoteRecord().cloneViaReserialise();
+        return new HSSFComment(spContainer, obj, txo, note);
+    }
 }
index efb19331b06437292f34dc589259cc071255719b..565c89e78c96190646893e682462cfb3eeeb1e83 100644 (file)
@@ -21,22 +21,20 @@ package org.apache.poi.hssf.usermodel;
 import java.io.IOException;
 import java.util.Iterator;
 
-import org.apache.poi.ddf.EscherContainerRecord;
-import org.apache.poi.hssf.record.EmbeddedObjectRefSubRecord;
-import org.apache.poi.hssf.record.ObjRecord;
-import org.apache.poi.hssf.record.SubRecord;
+import org.apache.poi.ddf.*;
+import org.apache.poi.hssf.record.*;
 import org.apache.poi.poifs.filesystem.DirectoryEntry;
 import org.apache.poi.poifs.filesystem.Entry;
 import org.apache.poi.util.HexDump;
 
 /**
  * Represents binary object (i.e. OLE) data stored in the file.  Eg. A GIF, JPEG etc...
- *
+ * <p/>
  * Right now, 13, july, 2012 can not be created from scratch
  *
  * @author Daniel Noll
  */
-public final class HSSFObjectData extends HSSFShape{
+public final class HSSFObjectData extends HSSFShape {
     /**
      * Reference to the filesystem root, required for retrieving the object data.
      */
@@ -56,7 +54,7 @@ public final class HSSFObjectData extends HSSFShape{
 
     /**
      * Gets the object data. Only call for ones that have
-     *  data though. See {@link #hasDirectoryEntry()}
+     * data though. See {@link #hasDirectoryEntry()}
      *
      * @return the object data as an OLE2 directory.
      * @throws IOException if there was an error reading the data.
@@ -76,8 +74,8 @@ public final class HSSFObjectData extends HSSFShape{
 
     /**
      * Returns the data portion, for an ObjectData
-     *  that doesn't have an associated POIFS Directory
-     *  Entry
+     * that doesn't have an associated POIFS Directory
+     * Entry
      */
     public byte[] getObjectData() {
         return findObjectRecord().getObjectData();
@@ -85,7 +83,7 @@ public final class HSSFObjectData extends HSSFShape{
 
     /**
      * Does this ObjectData have an associated POIFS
-     *  Directory Entry?
+     * Directory Entry?
      * (Not all do, those that don't have a data portion)
      */
     public boolean hasDirectoryEntry() {
@@ -98,7 +96,7 @@ public final class HSSFObjectData extends HSSFShape{
 
     /**
      * Finds the EmbeddedObjectRefSubRecord, or throws an
-     *  Exception if there wasn't one
+     * Exception if there wasn't one
      */
     protected EmbeddedObjectRefSubRecord findObjectRecord() {
         Iterator<SubRecord> subRecordIter = getObjRecord().getSubRecords().iterator();
@@ -106,7 +104,7 @@ public final class HSSFObjectData extends HSSFShape{
         while (subRecordIter.hasNext()) {
             Object subRecord = subRecordIter.next();
             if (subRecord instanceof EmbeddedObjectRefSubRecord) {
-                return (EmbeddedObjectRefSubRecord)subRecord;
+                return (EmbeddedObjectRefSubRecord) subRecord;
             }
         }
 
@@ -130,6 +128,39 @@ public final class HSSFObjectData extends HSSFShape{
 
     @Override
     void afterInsert(HSSFPatriarch patriarch) {
-        throw new IllegalStateException("HSSFObjectData cannot be created from scratch");
+        EscherAggregate agg = patriarch._getBoundAggregate();
+        agg.associateShapeToObjRecord(getEscherContainer().getChildById(EscherClientDataRecord.RECORD_ID), getObjRecord());
+        EscherBSERecord bse =
+                patriarch._sheet.getWorkbook().getWorkbook().getBSERecord(getPictureIndex());
+        bse.setRef(bse.getRef() + 1);
+    }
+
+    @Override
+    public HSSFShape cloneShape() {
+        EscherContainerRecord spContainer = new EscherContainerRecord();
+        byte[] inSp = getEscherContainer().serialize();
+        spContainer.fillFields(inSp, 0, new DefaultEscherRecordFactory());
+        ObjRecord obj = (ObjRecord) getObjRecord().cloneViaReserialise();
+        return new HSSFObjectData(spContainer, obj, _root);
+    }
+
+    public int getPictureIndex() {
+        EscherSimpleProperty property = getOptRecord().lookup(EscherProperties.BLIP__BLIPTODISPLAY);
+        if (null == property) {
+            return -1;
+        }
+        return property.getPropertyValue();
+    }
+
+    public void setPictureIndex(int pictureIndex) {
+        setPropertyValue(new EscherSimpleProperty(EscherProperties.BLIP__BLIPTODISPLAY, false, true, pictureIndex));
+    }
+
+    @Override
+    void setShapeId(int shapeId) {
+        EscherSpRecord spRecord = getEscherContainer().getChildById(EscherSpRecord.RECORD_ID);
+        spRecord.setShapeId(shapeId);
+        CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) getObjRecord().getSubRecords().get(0);
+        cod.setObjectId((short) (shapeId % 1024));
     }
 }
index 221dfc475a6d5bba3c7bc02e4cbde6401c0c2680..96d12adaa7f306bf08db2a51604fd0cf260b0cef 100644 (file)
@@ -38,10 +38,6 @@ import org.apache.poi.ss.usermodel.ClientAnchor;
  */
 public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
     private final List<HSSFShape> _shapes = new ArrayList<HSSFShape>();
-//    private int _x1 = 0;
-//    private int _y1  = 0 ;
-//    private int _x2 = 1023;
-//    private int _y2 = 255;
 
     private final EscherSpgrRecord _spgrRecord;
     private final EscherContainerRecord _mainSpgrContainer;
@@ -49,19 +45,19 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
     /**
      * The EscherAggregate we have been bound to.
      * (This will handle writing us out into records,
-     *  and building up our shapes from the records)
+     * and building up our shapes from the records)
      */
     private EscherAggregate _boundAggregate;
-       final HSSFSheet _sheet; // TODO make private
+    final HSSFSheet _sheet; // TODO make private
 
     /**
      * Creates the patriarch.
      *
      * @param sheet the sheet this patriarch is stored in.
      */
-    HSSFPatriarch(HSSFSheet sheet, EscherAggregate boundAggregate){
+    HSSFPatriarch(HSSFSheet sheet, EscherAggregate boundAggregate) {
         _sheet = sheet;
-               _boundAggregate = boundAggregate;
+        _boundAggregate = boundAggregate;
         _mainSpgrContainer = _boundAggregate.getEscherContainer().getChildContainers().get(0);
         EscherContainerRecord spContainer = (EscherContainerRecord) _boundAggregate.getEscherContainer()
                 .getChildContainers().get(0).getChild(0);
@@ -69,17 +65,36 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
         buildShapeTree();
     }
 
+    static HSSFPatriarch createPatriarch(HSSFPatriarch patriarch, HSSFSheet sheet){
+        HSSFPatriarch newPatriarch = new HSSFPatriarch(sheet, new EscherAggregate());
+        newPatriarch.afterCreate();
+
+        for (HSSFShape shape: patriarch.getChildren()){
+            HSSFShape newShape;
+            if (shape instanceof HSSFShapeGroup){
+                newShape = ((HSSFShapeGroup)shape).cloneShape(newPatriarch);
+            } else {
+                newShape = shape.cloneShape();
+            }
+            newPatriarch.onCreate(newShape);
+            newPatriarch.addShape(newShape);
+        }
+
+        return newPatriarch;
+    }
+
     /**
      * remove first level shapes
+     *
      * @param shape to be removed
      */
-    public void removeShape(HSSFShape shape){
+    public void removeShape(HSSFShape shape) {
         _mainSpgrContainer.removeChildRecord(shape.getEscherContainer());
         shape.afterRemove(this);
         _shapes.remove(shape);
     }
 
-    public void afterCreate(){
+    void afterCreate() {
         DrawingManager2 drawingManager = _sheet.getWorkbook().getWorkbook().getDrawingManager();
         short dgId = drawingManager.findNewDrawingGroupId();
         _boundAggregate.setDgId(dgId);
@@ -90,12 +105,11 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
     /**
      * Creates a new group record stored under this patriarch.
      *
-     * @param anchor    the client anchor describes how this group is attached
-     *                  to the sheet.
-     * @return  the newly created group.
+     * @param anchor the client anchor describes how this group is attached
+     *               to the sheet.
+     * @return the newly created group.
      */
-    public HSSFShapeGroup createGroup(HSSFClientAnchor anchor)
-    {
+    public HSSFShapeGroup createGroup(HSSFClientAnchor anchor) {
         HSSFShapeGroup group = new HSSFShapeGroup(null, anchor);
         addShape(group);
         onCreate(group);
@@ -106,21 +120,20 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
      * Creates a simple shape.  This includes such shapes as lines, rectangles,
      * and ovals.
      *
-     * @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 HSSFSimpleShape createSimpleShape(HSSFClientAnchor anchor)
-    {
+    public HSSFSimpleShape createSimpleShape(HSSFClientAnchor anchor) {
         HSSFSimpleShape shape = new HSSFSimpleShape(null, anchor);
         addShape(shape);
         //open existing file
         onCreate(shape);
         EscherSpRecord sp = shape.getEscherContainer().getChildById(EscherSpRecord.RECORD_ID);
-        if (shape.anchor.isHorizontallyFlipped()){
+        if (shape.anchor.isHorizontallyFlipped()) {
             sp.setFlags(sp.getFlags() | EscherSpRecord.FLAG_FLIPHORIZ);
         }
-        if (shape.anchor.isVerticallyFlipped()){
+        if (shape.anchor.isVerticallyFlipped()) {
             sp.setFlags(sp.getFlags() | EscherSpRecord.FLAG_FLIPVERT);
         }
         return shape;
@@ -129,42 +142,39 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
     /**
      * 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(HSSFClientAnchor anchor, int pictureIndex)
-    {
+    public HSSFPicture createPicture(HSSFClientAnchor anchor, int pictureIndex) {
         HSSFPicture shape = new HSSFPicture(null, anchor);
-        shape.setPictureIndex( pictureIndex );
+        shape.setPictureIndex(pictureIndex);
         addShape(shape);
         //open existing file
         onCreate(shape);
 
         EscherSpRecord sp = shape.getEscherContainer().getChildById(EscherSpRecord.RECORD_ID);
-        if (shape.anchor.isHorizontallyFlipped()){
+        if (shape.anchor.isHorizontallyFlipped()) {
             sp.setFlags(sp.getFlags() | EscherSpRecord.FLAG_FLIPHORIZ);
         }
-        if (shape.anchor.isVerticallyFlipped()){
+        if (shape.anchor.isVerticallyFlipped()) {
             sp.setFlags(sp.getFlags() | EscherSpRecord.FLAG_FLIPVERT);
         }
         return shape;
     }
 
-    public HSSFPicture createPicture(ClientAnchor anchor, int pictureIndex)
-    {
-        return createPicture((HSSFClientAnchor)anchor, pictureIndex);
+    public HSSFPicture createPicture(ClientAnchor anchor, int pictureIndex) {
+        return createPicture((HSSFClientAnchor) anchor, pictureIndex);
     }
 
     /**
      * 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(HSSFClientAnchor anchor)
-    {
+    public HSSFPolygon createPolygon(HSSFClientAnchor anchor) {
         HSSFPolygon shape = new HSSFPolygon(null, anchor);
         addShape(shape);
         onCreate(shape);
@@ -174,12 +184,11 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
     /**
      * Constructs a textbox under the patriarch.
      *
-     * @param anchor    the client anchor describes how this group is attached
-     *                  to the sheet.
-     * @return      the newly created textbox.
+     * @param anchor the client anchor describes how this group is attached
+     *               to the sheet.
+     * @return the newly created textbox.
      */
-    public HSSFTextbox createTextbox(HSSFClientAnchor anchor)
-    {
+    public HSSFTextbox createTextbox(HSSFClientAnchor anchor) {
         HSSFTextbox shape = new HSSFTextbox(null, anchor);
         addShape(shape);
         onCreate(shape);
@@ -189,12 +198,11 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
     /**
      * Constructs a cell comment.
      *
-     * @param anchor    the client anchor describes how this comment is attached
-     *                  to the sheet.
-     * @return      the newly created comment.
+     * @param anchor the client anchor describes how this comment is attached
+     *               to the sheet.
+     * @return the newly created comment.
      */
-   public HSSFComment createComment(HSSFAnchor anchor)
-    {
+    public HSSFComment createComment(HSSFAnchor anchor) {
         HSSFComment shape = new HSSFComment(null, anchor);
         addShape(shape);
         onCreate(shape);
@@ -206,23 +214,21 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
      *
      * @see org.apache.poi.hssf.usermodel.HSSFSheet#setAutoFilter(org.apache.poi.ss.util.CellRangeAddress)
      */
-     HSSFSimpleShape createComboBox(HSSFAnchor anchor)
-     {
-         HSSFCombobox shape = new HSSFCombobox(null, anchor);
-         addShape(shape);
-         onCreate(shape);
-         return shape;
-     }
+    HSSFSimpleShape createComboBox(HSSFAnchor anchor) {
+        HSSFCombobox shape = new HSSFCombobox(null, anchor);
+        addShape(shape);
+        onCreate(shape);
+        return shape;
+    }
 
     public HSSFComment createCellComment(ClientAnchor anchor) {
-        return createComment((HSSFAnchor)anchor);
+        return createComment((HSSFAnchor) anchor);
     }
 
     /**
      * Returns a list of all shapes contained by the patriarch.
      */
-    public List<HSSFShape> getChildren()
-    {
+    public List<HSSFShape> getChildren() {
         return _shapes;
     }
 
@@ -230,23 +236,21 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
      * add a shape to this drawing
      */
     @Internal
-    public void addShape(HSSFShape shape){
+    public void addShape(HSSFShape shape) {
         shape._patriarch = this;
         _shapes.add(shape);
     }
 
-    private void onCreate(HSSFShape shape){
-        if(_boundAggregate.getPatriarch() == null){
-            EscherContainerRecord spgrContainer =
-                    _boundAggregate.getEscherContainer().getChildContainers().get(0);
+    private void onCreate(HSSFShape shape) {
+        EscherContainerRecord spgrContainer =
+                _boundAggregate.getEscherContainer().getChildContainers().get(0);
 
-            EscherContainerRecord spContainer = shape.getEscherContainer();
-            int shapeId = newShapeId();
-            shape.setShapeId(shapeId);
+        EscherContainerRecord spContainer = shape.getEscherContainer();
+        int shapeId = newShapeId();
+        shape.setShapeId(shapeId);
 
-            spgrContainer.addChildRecord(spContainer);
-            shape.afterInsert(this);
-        }
+        spgrContainer.addChildRecord(spContainer);
+        shape.afterInsert(this);
     }
 
     /**
@@ -254,17 +258,18 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
      */
     public int countOfAllChildren() {
         int count = _shapes.size();
-        for (Iterator<HSSFShape> iterator = _shapes.iterator(); iterator.hasNext();) {
+        for (Iterator<HSSFShape> iterator = _shapes.iterator(); iterator.hasNext(); ) {
             HSSFShape shape = iterator.next();
             count += shape.countOfAllChildren();
         }
         return count;
     }
+
     /**
      * 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.setRectY1(y1);
         _spgrRecord.setRectY2(y2);
         _spgrRecord.setRectX1(x1);
@@ -282,28 +287,28 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
     /**
      * Does this HSSFPatriarch contain a chart?
      * (Technically a reference to a chart, since they
-     *  get stored in a different block of records)
+     * get stored in a different block of records)
      * FIXME - detect chart in all cases (only seems
-     *  to work on some charts so far)
+     * to work on some charts so far)
      */
     public boolean containsChart() {
         // TODO - support charts properly in usermodel
 
         // We're looking for a EscherOptRecord
         EscherOptRecord optRecord = (EscherOptRecord)
-            _boundAggregate.findFirstWithId(EscherOptRecord.RECORD_ID);
-        if(optRecord == null) {
+                _boundAggregate.findFirstWithId(EscherOptRecord.RECORD_ID);
+        if (optRecord == null) {
             // No opt record, can't have chart
             return false;
         }
 
-        for(Iterator<EscherProperty> it = optRecord.getEscherProperties().iterator(); it.hasNext();) {
+        for (Iterator<EscherProperty> it = optRecord.getEscherProperties().iterator(); it.hasNext(); ) {
             EscherProperty prop = it.next();
-            if(prop.getPropertyNumber() == 896 && prop.isComplex()) {
-                EscherComplexProperty cp = (EscherComplexProperty)prop;
+            if (prop.getPropertyNumber() == 896 && prop.isComplex()) {
+                EscherComplexProperty cp = (EscherComplexProperty) prop;
                 String str = StringUtil.getFromUnicodeLE(cp.getComplexData());
 
-                if(str.equals("Chart 1\0")) {
+                if (str.equals("Chart 1\0")) {
                     return true;
                 }
             }
@@ -315,32 +320,28 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
     /**
      * 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();
     }
 
@@ -365,26 +366,26 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
      * @param row2 the row (0 based) of the second cell.
      * @return the newly created client anchor
      */
-    public HSSFClientAnchor createAnchor(int dx1, int dy1, int dx2, int dy2, int col1, int row1, int col2, int row2){
-        return new HSSFClientAnchor(dx1, dy1, dx2, dy2, (short)col1, row1, (short)col2, row2);
+    public HSSFClientAnchor createAnchor(int dx1, int dy1, int dx2, int dy2, int col1, int row1, int col2, int row2) {
+        return new HSSFClientAnchor(dx1, dy1, dx2, dy2, (short) col1, row1, (short) col2, row2);
     }
 
-       public Chart createChart(ClientAnchor anchor) {
-               throw new RuntimeException("NotImplemented");
-       }
+    public Chart createChart(ClientAnchor anchor) {
+        throw new RuntimeException("NotImplemented");
+    }
 
 
-    void buildShapeTree(){
+    void buildShapeTree() {
         EscherContainerRecord dgContainer = _boundAggregate.getEscherContainer();
-        if (dgContainer == null){
+        if (dgContainer == null) {
             return;
         }
         EscherContainerRecord spgrConrainer = dgContainer.getChildContainers().get(0);
         List<EscherContainerRecord> spgrChildren = spgrConrainer.getChildContainers();
 
-        for(int i = 0; i < spgrChildren.size(); i++){
+        for (int i = 0; i < spgrChildren.size(); i++) {
             EscherContainerRecord spContainer = spgrChildren.get(i);
-            if (i == 0){
+            if (i == 0) {
                 continue;
             } else {
                 HSSFShapeFactory.createShapeTree(spContainer, _boundAggregate, this, _sheet.getWorkbook().getRootDirectory());
index 6e5d98cf5565254ff7ab06a474f81b20b3986f61..6bc713366d392450d3a5668879736568aa78c9b4 100644 (file)
@@ -22,6 +22,7 @@ import java.io.ByteArrayInputStream;
 import java.io.UnsupportedEncodingException;
 
 import org.apache.poi.ddf.*;
+import org.apache.poi.hssf.record.EscherAggregate;
 import org.apache.poi.hssf.record.ObjRecord;
 import org.apache.poi.ss.usermodel.Picture;
 import org.apache.poi.ss.util.ImageUtils;
@@ -88,6 +89,7 @@ public final class HSSFPicture extends HSSFSimpleShape implements Picture {
         EscherOptRecord opt = spContainer.getChildById(EscherOptRecord.RECORD_ID);
         removeEscherProperty(opt, EscherProperties.LINESTYLE__LINEDASHING);
         removeEscherProperty(opt, EscherProperties.LINESTYLE__NOLINEDRAWDASH);
+        spContainer.removeChildRecord(spContainer.getChildById(EscherTextboxRecord.RECORD_ID));
         return spContainer;
     }
 
@@ -250,7 +252,8 @@ public final class HSSFPicture extends HSSFSimpleShape implements Picture {
 
     @Override
     void afterInsert(HSSFPatriarch patriarch) {
-        super.afterInsert(patriarch);
+        EscherAggregate agg = patriarch._getBoundAggregate();
+        agg.associateShapeToObjRecord(getEscherContainer().getChildById(EscherClientDataRecord.RECORD_ID), getObjRecord());
         EscherBSERecord bse =
                 patriarch._sheet.getWorkbook().getWorkbook().getBSERecord(getPictureIndex());
         bse.setRef(bse.getRef() + 1);
@@ -285,4 +288,13 @@ public final class HSSFPicture extends HSSFSimpleShape implements Picture {
     public void setShapeType(int shapeType) {
         throw new IllegalStateException("Shape type can not be changed in "+this.getClass().getSimpleName());
     }
+
+    @Override
+    public HSSFShape cloneShape() {
+        EscherContainerRecord spContainer = new EscherContainerRecord();
+        byte [] inSp = getEscherContainer().serialize();
+        spContainer.fillFields(inSp, 0, new DefaultEscherRecordFactory());
+        ObjRecord obj = (ObjRecord) getObjRecord().cloneViaReserialise();
+        return new HSSFPicture(spContainer, obj);
+    }
 }
index 079ae744ae8ba309789a8994bb0af02eea620963..e145b9fe50ff50b16e1a81053e5ef574eb7472e6 100644 (file)
 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.record.*;
 import org.apache.poi.util.LittleEndian;
 
 /**
  * @author Glen Stampoultzis  (glens at superlinksoftware.com)
  */
-public class HSSFPolygon  extends HSSFShape {
+public class HSSFPolygon  extends HSSFSimpleShape {
 
     public final static short OBJECT_TYPE_MICROSOFT_OFFICE_DRAWING = 0x1E;
 
+    public HSSFPolygon(EscherContainerRecord spContainer, ObjRecord objRecord, TextObjectRecord _textObjectRecord) {
+        super(spContainer, objRecord, _textObjectRecord);
+    }
+
     public HSSFPolygon(EscherContainerRecord spContainer, ObjRecord objRecord) {
         super(spContainer, objRecord);
     }
@@ -39,6 +40,11 @@ public class HSSFPolygon  extends HSSFShape {
         super(parent, anchor);
     }
 
+    @Override
+    protected TextObjectRecord createTextObjRecord() {
+        return null;
+    }
+
     /**
      * Generates the shape records for this shape.
      */
@@ -200,10 +206,4 @@ public class HSSFPolygon  extends HSSFShape {
         EscherSimpleProperty property = getOptRecord().lookup(EscherProperties.GEOMETRY__BOTTOM);
         return property == null ? 100: property.getPropertyValue();
     }
-
-    @Override
-    void afterInsert(HSSFPatriarch patriarch) {
-        EscherAggregate agg = patriarch._getBoundAggregate();
-        agg.associateShapeToObjRecord(getEscherContainer().getChildById(EscherClientDataRecord.RECORD_ID), getObjRecord());
-    }
 }
index 4e01aa63eab04adaacb07bf1b50d69004de0ce53..137ead3c7527c0e65a541ad8bde1a361d52e92cc 100644 (file)
@@ -302,4 +302,6 @@ public abstract class HSSFShape {
     public int countOfAllChildren() {
         return 1;
     }
+
+    public abstract HSSFShape cloneShape();
 }
index 5d2c9bb61962e013ff9bbe23103cbb2e16f4bf6c..178bdf5fe9763f01abc52a1dee53af98c5219faf 100644 (file)
@@ -74,8 +74,12 @@ public class HSSFShapeFactory {
 \r
     public static void createShapeTree(EscherContainerRecord container, EscherAggregate agg, HSSFShapeContainer out, DirectoryNode root) {\r
         if (container.getRecordId() == EscherContainerRecord.SPGR_CONTAINER) {\r
-            HSSFShapeGroup group = new HSSFShapeGroup(container,\r
-                    null /* shape containers don't have a associated Obj record*/);\r
+            ObjRecord obj = null;\r
+            EscherClientDataRecord clientData = ((EscherContainerRecord)container.getChild(0)).getChildById(EscherClientDataRecord.RECORD_ID);\r
+            if (null != clientData){\r
+                obj = (ObjRecord) agg.getShapeToObjMapping().get(clientData);\r
+            }\r
+            HSSFShapeGroup group = new HSSFShapeGroup(container, obj);\r
             List<EscherContainerRecord> children = container.getChildContainers();\r
             // skip the first child record, it is group descriptor\r
             for (int i = 0; i < children.size(); i++) {\r
@@ -130,7 +134,7 @@ public class HSSFShapeFactory {
                     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
+                        shape = new HSSFPolygon(container, objRecord, txtRecord);\r
                     } else {\r
                         shape = new HSSFSimpleShape(container, objRecord);\r
                     }\r
index 32471f517603dd39093ac54124afaf9c8fda6677..548b45b75d8391849fcf77f588bbe2eaa22f68cb 100644 (file)
@@ -127,13 +127,18 @@ public class HSSFShapeGroup extends HSSFShape implements HSSFShapeContainer {
     }
 
     private void onCreate(HSSFShape shape){
-        if(_patriarch != null && _patriarch._getBoundAggregate().getPatriarch() == null){
+        if(_patriarch != null){
             EscherContainerRecord spContainer = shape.getEscherContainer();
             int shapeId = _patriarch.newShapeId();
             shape.setShapeId(shapeId);
             getEscherContainer().addChildRecord(spContainer);
             shape.afterInsert(_patriarch);
-            EscherSpRecord sp = shape.getEscherContainer().getChildById(EscherSpRecord.RECORD_ID);
+            EscherSpRecord sp;
+            if (shape instanceof HSSFShapeGroup){
+                sp = shape.getEscherContainer().getChildContainers().get(0).getChildById(EscherSpRecord.RECORD_ID);
+            } else {
+                sp = shape.getEscherContainer().getChildById(EscherSpRecord.RECORD_ID);
+            }
             sp.setFlags(sp.getFlags() | EscherSpRecord.FLAG_CHILD);
         }
     }
@@ -312,7 +317,7 @@ public class HSSFShapeGroup extends HSSFShape implements HSSFShapeContainer {
         EscherSpRecord spRecord = containerRecord.getChildById(EscherSpRecord.RECORD_ID);
         spRecord.setShapeId(shapeId);
         CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) getObjRecord().getSubRecords().get(0);
-        cod.setObjectId((short) (shapeId));
+        cod.setObjectId((short) (shapeId % 1024));
     }
 
     @Override
@@ -320,4 +325,39 @@ public class HSSFShapeGroup extends HSSFShape implements HSSFShapeContainer {
         EscherContainerRecord containerRecord = getEscherContainer().getChildById(EscherContainerRecord.SP_CONTAINER);
         return ((EscherSpRecord)containerRecord.getChildById(EscherSpRecord.RECORD_ID)).getShapeId();
     }
+
+    @Override
+    public HSSFShape cloneShape() {
+        throw new IllegalStateException("Use method cloneShape(HSSFPatriarch patriarch)");
+    }
+
+    public HSSFShape cloneShape(HSSFPatriarch patriarch) {
+        EscherContainerRecord spgrContainer = new EscherContainerRecord();
+        spgrContainer.setRecordId(EscherContainerRecord.SPGR_CONTAINER);
+        spgrContainer.setOptions((short) 0x000F);
+        EscherContainerRecord spContainer = new EscherContainerRecord();
+        byte [] inSp = getEscherContainer().getChildById(EscherContainerRecord.SP_CONTAINER).serialize();
+        spContainer.fillFields(inSp, 0, new DefaultEscherRecordFactory());
+
+        spgrContainer.addChildRecord(spContainer);
+        ObjRecord obj = null;
+        if (null != getObjRecord()){
+            obj = (ObjRecord) getObjRecord().cloneViaReserialise();
+        }
+
+        HSSFShapeGroup group = new HSSFShapeGroup(spgrContainer, obj);
+        group._patriarch = patriarch;
+
+        for (HSSFShape shape: getChildren()){
+            HSSFShape newShape;
+            if (shape instanceof HSSFShapeGroup){
+                newShape = ((HSSFShapeGroup)shape).cloneShape(patriarch);
+            } else {
+                newShape = shape.cloneShape();
+            }
+            group.addShape(newShape);
+            group.onCreate(newShape);
+        }
+        return group;
+    }
 }
index f294946008bb633dffe94b67c70d052f1804243b..afe4cf99d803969fed81908dde5075d34c3622cb 100644 (file)
@@ -115,7 +115,15 @@ public final class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet {
     }
 
     HSSFSheet cloneSheet(HSSFWorkbook workbook) {
-      return new HSSFSheet(workbook, _sheet.cloneSheet());
+        this.getDrawingPatriarch();/**Aggregate drawing records**/
+        HSSFSheet sheet = new HSSFSheet(workbook, _sheet.cloneSheet());
+        if (getDrawingPatriarch() != null){
+            int insertPos = sheet._sheet.findFirstRecordLocBySid(WindowTwoRecord.sid);
+            HSSFPatriarch patr = HSSFPatriarch.createPatriarch(this.getDrawingPatriarch(), sheet);
+            sheet._sheet.getRecords().add(insertPos, patr._getBoundAggregate());
+            sheet._patriarch = patr;
+        }
+        return sheet;
     }
 
     /**
index 28153d2d45bb6165fc937269702e525552554a12..eb2e865e76f48c8922db7d469ab4591df5e252cf 100644 (file)
@@ -68,14 +68,13 @@ public class HSSFSimpleShape extends HSSFShape
         objTypeToShapeType.put(OBJECT_TYPE_OVAL, HSSFShapeType.OVAL.getType());
     }
 
-    public HSSFSimpleShape(EscherContainerRecord spContainer, ObjRecord objRecord, TextObjectRecord _textObjectRecord) {
+    public HSSFSimpleShape(EscherContainerRecord spContainer, ObjRecord objRecord, TextObjectRecord textObjectRecord) {
         super(spContainer, objRecord);
-        this._textObjectRecord = _textObjectRecord == null ? createTextObjRecord() : _textObjectRecord;
+        this._textObjectRecord = textObjectRecord;
     }
 
     public HSSFSimpleShape(EscherContainerRecord spContainer, ObjRecord objRecord) {
         super(spContainer, objRecord);
-        this._textObjectRecord = createTextObjRecord();
     }
 
     public HSSFSimpleShape( HSSFShape parent, HSSFAnchor anchor)
@@ -92,6 +91,7 @@ public class HSSFSimpleShape extends HSSFShape
         TextObjectRecord obj = new TextObjectRecord();
         obj.setTextLocked(true);
         obj.setTextOrientation(TextObjectRecord.TEXT_ORIENTATION_NONE);
+        obj.setStr(new HSSFRichTextString(""));
         return obj;
     }
 
@@ -123,10 +123,15 @@ public class HSSFSimpleShape extends HSSFShape
         optRecord.setEscherProperty(new EscherBoolProperty( EscherProperties.GROUPSHAPE__PRINT, 0x080000));
         optRecord.setRecordId( EscherOptRecord.RECORD_ID );
 
+        EscherTextboxRecord escherTextbox = new EscherTextboxRecord();
+        escherTextbox.setRecordId(EscherTextboxRecord.RECORD_ID);
+        escherTextbox.setOptions((short) 0x0000);
+
         spContainer.addChildRecord(sp);
         spContainer.addChildRecord(optRecord);
         spContainer.addChildRecord(anchor.getEscherAnchor());
         spContainer.addChildRecord(clientData);
+        spContainer.addChildRecord(escherTextbox);
         return spContainer;
     }
 
@@ -167,21 +172,6 @@ public class HSSFSimpleShape extends HSSFShape
         HSSFRichTextString rtr = (HSSFRichTextString) string;
         // If font is not set we must set the default one
         if (rtr.numFormattingRuns() == 0) rtr.applyFont((short) 0);
-        EscherTextboxRecord textbox = getEscherContainer().getChildById(EscherTextboxRecord.RECORD_ID);
-        if (string.getString()!= null && !string.getString().equals("")){
-            if (null == textbox){
-                EscherTextboxRecord escherTextbox = new EscherTextboxRecord();
-                escherTextbox.setRecordId(EscherTextboxRecord.RECORD_ID);
-                escherTextbox.setOptions((short) 0x0000);
-                getEscherContainer().addChildRecord(escherTextbox);
-                _patriarch._getBoundAggregate().associateShapeToObjRecord(getEscherContainer().getChildById(EscherTextboxRecord.RECORD_ID), getTextObjectRecord());
-            }
-        } else {
-            if (null != textbox){
-                getEscherContainer().removeChildRecord(textbox);
-                _patriarch._getBoundAggregate().removeShapeToObjRecord(textbox);
-            }
-        }
         _textObjectRecord.setStr(rtr);
     }
 
@@ -189,6 +179,24 @@ public class HSSFSimpleShape extends HSSFShape
     void afterInsert(HSSFPatriarch patriarch){
         EscherAggregate agg = patriarch._getBoundAggregate();
         agg.associateShapeToObjRecord(getEscherContainer().getChildById(EscherClientDataRecord.RECORD_ID), getObjRecord());
+
+        //used only when clone shapes
+        if (null != getTextObjectRecord()){
+            agg.associateShapeToObjRecord(getEscherContainer().getChildById(EscherTextboxRecord.RECORD_ID), getTextObjectRecord());
+        }
+    }
+
+    @Override
+    public HSSFShape cloneShape() {
+        TextObjectRecord txo = null;
+        EscherContainerRecord spContainer = new EscherContainerRecord();
+        byte [] inSp = getEscherContainer().serialize();
+        spContainer.fillFields(inSp, 0, new DefaultEscherRecordFactory());
+        ObjRecord obj = (ObjRecord) getObjRecord().cloneViaReserialise();
+        if (getTextObjectRecord() != null && getString() != null && !"".equals(getString().getString())){
+            txo = (TextObjectRecord) getTextObjectRecord().cloneViaReserialise();
+        }
+        return new HSSFSimpleShape(spContainer, obj, txo);
     }
 
 
index af39d59784f13c696c7b22e4c49baba932c96619..cfbbd9797c17e7670ed3d9f033b317180865598e 100644 (file)
@@ -235,4 +235,14 @@ public class HSSFTextbox extends HSSFSimpleShape {
     public void setShapeType(int shapeType) {
         throw new IllegalStateException("Shape type can not be changed in "+this.getClass().getSimpleName());
     }
+
+    @Override
+    public HSSFShape cloneShape() {
+        TextObjectRecord txo = (TextObjectRecord) getTextObjectRecord().cloneViaReserialise();
+        EscherContainerRecord spContainer = new EscherContainerRecord();
+        byte [] inSp = getEscherContainer().serialize();
+        spContainer.fillFields(inSp, 0, new DefaultEscherRecordFactory());
+        ObjRecord obj = (ObjRecord) getObjRecord().cloneViaReserialise();
+        return new HSSFTextbox(spContainer, obj, txo);
+    }
 }
index 827a5c34ac2d40e863756c0adfffab8ad628232a..75d33c6c659e9a71baa56c10457a0866dc446bb3 100644 (file)
@@ -48,4 +48,9 @@ public class HSSFUnknownShape extends HSSFShape {
     @Override\r
     void afterInsert(HSSFPatriarch patriarch) {\r
     }\r
+\r
+    @Override\r
+    public HSSFShape cloneShape() {\r
+        return null;\r
+    }\r
 }\r
index 332289e109685b18960df624e24c547ffbdc50c6..cc6e40c2713d67aec30398a3b7294b26e51d85e0 100644 (file)
@@ -701,7 +701,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
             names.add(newName);
         }
         // TODO - maybe same logic required for other/all built-in name records
-        workbook.cloneDrawings(clonedSheet.getSheet());
+//        workbook.cloneDrawings(clonedSheet.getSheet());
 
         return clonedSheet;
     }
index b49721251857620e7bf82a3435d01990143ad3ba..9de806cfc7e3cb52ae103fe934dfd7939f8be768 100644 (file)
@@ -194,46 +194,6 @@ public class TestDrawingAggregate extends TestCase {
         }\r
     }\r
 \r
-    public void testBuildBaseTree(){\r
-        HSSFWorkbook wb = new HSSFWorkbook();\r
-        HSSFSheet sheet = wb.createSheet();\r
-        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();\r
-        EscherAggregate agg = HSSFTestHelper.getEscherAggregate(patriarch);\r
-        EscherAggregate agg1 = new EscherAggregate(new HSSFTestHelper.MockDrawingManager());\r
-        EscherSpgrRecord spgr = new EscherSpgrRecord();\r
-        spgr.setRectY1(0);\r
-        spgr.setRectY2(255);\r
-        spgr.setRectX1(0);\r
-        spgr.setRectX2(1023);\r
-        EscherContainerRecord spContainer = new EscherContainerRecord();\r
-        spContainer.addChildRecord(spgr);\r
-        EscherContainerRecord spgrContainer = new EscherContainerRecord();\r
-        spgrContainer.addChildRecord(spContainer);\r
-        EscherContainerRecord dgContainer = new EscherContainerRecord();\r
-        dgContainer.addChildRecord(spgrContainer);\r
-        agg1.addEscherRecord(dgContainer);\r
-        agg1.setPatriarch(HSSFTestHelper.createTestPatriarch(sheet, agg1));\r
-        agg1.clear();\r
-        HSSFTestHelper.callConvertPatriarch(agg1);\r
-        agg1.setPatriarch(null);\r
-\r
-        agg.setPatriarch(null);\r
-//\r
-        EscherSpRecord sp = (EscherSpRecord) agg.getEscherContainer().getChildContainers().get(0).getChild(0).getChild(1);\r
-        sp.setShapeId(1025);\r
-        EscherDgRecord dg = (EscherDgRecord) agg.getEscherContainer().getChild(0);\r
-        dg.setNumShapes(1);\r
-        dg.setOptions((short) (1 << 4));\r
-\r
-        byte[] aggS = agg.serialize();\r
-        byte []agg1S = agg1.serialize();\r
-\r
-        assertEquals(aggS.length, agg1S.length);\r
-        assertTrue(Arrays.equals(aggS, agg1S));\r
-    }\r
-\r
-\r
-\r
     /**\r
      * when reading incomplete data ensure that the serialized bytes\r
      match the source\r
index dd8882764f345954426e0243c4cd7f803115bfe5..e57a1b437242c1efd432e8786f93a2f266ee48f3 100644 (file)
@@ -352,8 +352,7 @@ public class TestDrawingShapes extends TestCase {
         shape.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);\r
 \r
         EscherAggregate agg = HSSFTestHelper.getEscherAggregate(patriarch);\r
-        assertNull(shape.getEscherContainer().getChildById(EscherTextboxRecord.RECORD_ID));\r
-        assertEquals(agg.getShapeToObjMapping().size(), 1);\r
+        assertEquals(agg.getShapeToObjMapping().size(), 2);\r
 \r
         wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
         sheet = wb.getSheetAt(0);\r
@@ -362,8 +361,7 @@ public class TestDrawingShapes extends TestCase {
         shape = (HSSFSimpleShape) patriarch.getChildren().get(0);\r
 \r
         agg = HSSFTestHelper.getEscherAggregate(patriarch);\r
-        assertNull(shape.getEscherContainer().getChildById(EscherTextboxRecord.RECORD_ID));\r
-        assertEquals(agg.getShapeToObjMapping().size(), 1);\r
+        assertEquals(agg.getShapeToObjMapping().size(), 2);\r
 \r
         shape.setString(new HSSFRichTextString("string1"));\r
         assertEquals(shape.getString().getString(), "string1");\r
index 50ff1dc50c97843dc64c8751af39ddd06cae2fa2..465f7746b0491e60807d4ae354f8be08acacdf9b 100644 (file)
@@ -101,21 +101,6 @@ public class HSSFTestHelper {
         }
     }
 
-    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();
-        } catch (InvocationTargetException e) {
-            e.printStackTrace();
-        }
-    }
-
     public static void setShapeId(HSSFShape shape, int id){
         shape.setShapeId(id);
     }
index 1f276b77656b8995f403047845c2dcf7908eb7d8..10acaa5e9f042566aa1a4f260bc3e7cb1b1d73c9 100644 (file)
@@ -19,8 +19,14 @@ package org.apache.poi.hssf.usermodel;
 
 import junit.framework.TestCase;
 
+import org.apache.poi.ddf.EscherDgRecord;
+import org.apache.poi.ddf.EscherSpRecord;
+import org.apache.poi.hssf.record.EscherAggregate;
 import org.apache.poi.ss.util.CellRangeAddress;
 
+import java.io.IOException;
+import java.util.Arrays;
+
 /**
  * Test the ability to clone a sheet.
  *  If adding new records that belong to a sheet (as opposed to a book)
@@ -55,4 +61,74 @@ public final class TestCloneSheet extends TestCase {
 
                assertTrue("Row 3 still should be broken", clone.isRowBroken(3));
        }
+    
+    public void testCloneSheetWithoutDrawings(){
+        HSSFWorkbook b = new HSSFWorkbook();
+        HSSFSheet s = b.createSheet("Test");
+        HSSFSheet s2 = s.cloneSheet(b);
+        
+        assertNull(s.getDrawingPatriarch());
+        assertNull(s2.getDrawingPatriarch());
+        assertEquals(HSSFTestHelper.getSheetForTest(s).getRecords().size(), HSSFTestHelper.getSheetForTest(s2).getRecords().size());
+    }
+    
+    public void testCloneSheetWithEmptyDrawingAggregate(){
+        HSSFWorkbook b = new HSSFWorkbook();
+        HSSFSheet s = b.createSheet("Test");
+        HSSFPatriarch patriarch = s.createDrawingPatriarch();
+
+        EscherAggregate agg1 = patriarch._getBoundAggregate();
+
+        HSSFSheet s2 = s.cloneSheet(b);
+
+        patriarch = s2.getDrawingPatriarch();
+
+        EscherAggregate agg2 = patriarch._getBoundAggregate();
+
+        EscherSpRecord sp1 = (EscherSpRecord) agg1.getEscherContainer().getChild(1).getChild(0).getChild(1);
+        EscherSpRecord sp2 = (EscherSpRecord) agg2.getEscherContainer().getChild(1).getChild(0).getChild(1);
+
+        assertEquals(sp1.getShapeId(), 1024);
+        assertEquals(sp2.getShapeId(), 2048);
+
+        EscherDgRecord dg = (EscherDgRecord) agg2.getEscherContainer().getChild(0);
+
+        assertEquals(dg.getLastMSOSPID(), 2048);
+        assertEquals(dg.getInstance(), 0x2);
+
+        //everything except id and DgRecord.lastMSOSPID and DgRecord.Instance must be the same
+
+        sp2.setShapeId(1024);
+        dg.setLastMSOSPID(1024);
+        dg.setInstance((short) 0x1);
+
+        assertEquals(agg1.serialize().length, agg2.serialize().length);
+        assertEquals(agg1.toXml(""), agg2.toXml(""));
+        assertTrue(Arrays.equals(agg1.serialize(), agg2.serialize()));
+    }
+    
+    public void testCloneComment() throws IOException {
+        HSSFWorkbook wb = new HSSFWorkbook();
+        HSSFSheet sh = wb.createSheet();
+        HSSFPatriarch p = sh.createDrawingPatriarch();
+        HSSFComment c = p.createComment(new HSSFClientAnchor(0,0,100,100, (short) 0,0,(short)5,5));
+        c.setColumn(1);
+        c.setRow(2);
+        c.setString(new HSSFRichTextString("qwertyuio"));
+        
+        HSSFSheet sh2 = wb.cloneSheet(0);
+        HSSFPatriarch p2 = sh2.getDrawingPatriarch();
+        HSSFComment c2 = (HSSFComment) p2.getChildren().get(0);
+        
+        assertTrue(Arrays.equals(c2.getTextObjectRecord().serialize(), c.getTextObjectRecord().serialize()));
+        assertTrue(Arrays.equals(c2.getObjRecord().serialize(), c.getObjRecord().serialize()));
+        assertTrue(Arrays.equals(c2.getNoteRecord().serialize(), c.getNoteRecord().serialize()));
+
+
+        //everything except spRecord.shapeId must be the same
+        assertFalse(Arrays.equals(c2.getEscherContainer().serialize(), c.getEscherContainer().serialize()));
+        EscherSpRecord sp = (EscherSpRecord) c2.getEscherContainer().getChild(0);
+        sp.setShapeId(1025);
+        assertTrue(Arrays.equals(c2.getEscherContainer().serialize(), c.getEscherContainer().serialize()));
+    }
 }
index b098c197376b34bde8f42b041e2effaf212fc35d..cbf49bb5e3d0c8ada957354dfd4b8fc10da73c32 100644 (file)
@@ -58,6 +58,8 @@ public class TestComment extends TestCase {
 \r
         ObjRecord obj = comment.getObjRecord();\r
         ObjRecord objShape = commentShape.getObjRecord();\r
+        /**shapeId = 1025 % 1024**/\r
+        ((CommonObjectDataSubRecord)objShape.getSubRecords().get(0)).setObjectId(1);\r
 \r
         expected = obj.serialize();\r
         actual = objShape.serialize();\r
@@ -76,6 +78,7 @@ public class TestComment extends TestCase {
 \r
         NoteRecord note = comment.getNoteRecord();\r
         NoteRecord noteShape = commentShape.getNoteRecord();\r
+        noteShape.setShapeId(1);\r
 \r
         expected = note.serialize();\r
         actual = noteShape.serialize();\r
@@ -225,17 +228,17 @@ public class TestComment extends TestCase {
         comment.setShapeId(2024);\r
         /**\r
          * SpRecord.id == shapeId\r
-         * ObjRecord.id == shapeId - 1024\r
-         * NoteRecord.id == ObjectRecord.id == shapeId - 1024\r
+         * ObjRecord.id == shapeId % 1024\r
+         * NoteRecord.id == ObjectRecord.id == shapeId % 1024\r
          */\r
 \r
         assertEquals(comment.getShapeId(), 2024);\r
 \r
         CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) comment.getObjRecord().getSubRecords().get(0);\r
-        assertEquals(cod.getObjectId(), 2024);\r
+        assertEquals(cod.getObjectId(), 1000);\r
         EscherSpRecord spRecord = (EscherSpRecord) comment.getEscherContainer().getChild(0);\r
         assertEquals(spRecord.getShapeId(), 2024);\r
         assertEquals(comment.getShapeId(), 2024);\r
-        assertEquals(comment.getNoteRecord().getShapeId(), 2024);\r
+        assertEquals(comment.getNoteRecord().getShapeId(), 1000);\r
     }\r
 }\r
index 1abf1026ed7d274a1701ca566cb6f51e75deafe2..d05f04877126c57862c26daac83817aa318c6042 100644 (file)
@@ -808,8 +808,8 @@ public final class TestHSSFSheet extends BaseTestSheet {
         HSSFSheet sheet2 = wb2.getSheetAt(1);
 
         //check that id of the drawing group was updated
-        EscherDgRecord dg1 = (EscherDgRecord)sheet1.getDrawingEscherAggregate().findFirstWithId(EscherDgRecord.RECORD_ID);
-        EscherDgRecord dg2 = (EscherDgRecord)sheet2.getDrawingEscherAggregate().findFirstWithId(EscherDgRecord.RECORD_ID);
+        EscherDgRecord dg1 = (EscherDgRecord)sheet1.getDrawingPatriarch()._getBoundAggregate().findFirstWithId(EscherDgRecord.RECORD_ID);
+        EscherDgRecord dg2 = (EscherDgRecord)sheet2.getDrawingPatriarch()._getBoundAggregate().findFirstWithId(EscherDgRecord.RECORD_ID);
         int dg_id_1 = dg1.getOptions() >> 4;
         int dg_id_2 = dg2.getOptions() >> 4;
         assertEquals(dg_id_1 + 1, dg_id_2);
index 5eb93f6e3e586efe6b2539b528168f8977ab2b00..f0ce3f28011c762d7daf27bd9b695881a3771416 100644 (file)
@@ -17,29 +17,6 @@ import java.util.Map;
  */\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