diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/Picture.java b/src/scratchpad/src/org/apache/poi/hslf/model/Picture.java index 1e8dbcc25..ed642791f 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/Picture.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/Picture.java @@ -197,6 +197,7 @@ public class Picture extends SimpleShape { * By default set the orininal image size */ protected void afterInsert(Sheet sh){ + super.afterInsert(sh); java.awt.Rectangle anchor = getAnchor(); if (anchor.equals(new java.awt.Rectangle())){ setDefaultSize(); diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java b/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java index 9ac61dbff..2aed43f47 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java @@ -18,10 +18,11 @@ package org.apache.poi.hslf.model; import org.apache.poi.ddf.*; import org.apache.poi.hslf.record.ColorSchemeAtom; +import org.apache.poi.hslf.record.PPDrawing; import org.apache.poi.util.POILogger; import org.apache.poi.util.POILogFactory; -import java.util.Iterator; +import java.util.*; import java.awt.*; import java.awt.geom.Rectangle2D; @@ -324,7 +325,58 @@ public abstract class Shape { * @param sh - owning shape */ protected void afterInsert(Sheet sh){ + PPDrawing ppdrawing = sh.getPPDrawing(); + EscherContainerRecord dgContainer = (EscherContainerRecord) ppdrawing.getEscherRecords()[0]; + + EscherDgRecord dg = (EscherDgRecord) Shape.getEscherChild(dgContainer, EscherDgRecord.RECORD_ID); + + int id = allocateShapeId(dg); + setShapeId(id); + } + + /** + * Allocates new shape id for the new drawing group id. + * + * @param dg EscherDgRecord of the sheet that owns the shape being created + * + * @return a new shape id. + */ + protected int allocateShapeId(EscherDgRecord dg) + { + EscherDggRecord dgg = _sheet.getSlideShow().getDocumentRecord().getPPDrawingGroup().getEscherDggRecord(); + if(dgg == null){ + logger.log(POILogger.ERROR, "EscherDggRecord not found"); + return 0; + } + + dgg.setNumShapesSaved( dgg.getNumShapesSaved() + 1 ); + + // Add to existing cluster if space available + for (int i = 0; i < dgg.getFileIdClusters().length; i++) + { + EscherDggRecord.FileIdCluster c = dgg.getFileIdClusters()[i]; + if (c.getDrawingGroupId() == dg.getDrawingGroupId() && c.getNumShapeIdsUsed() != 1024) + { + int result = c.getNumShapeIdsUsed() + (1024 * (i+1)); + c.incrementShapeId(); + dg.setNumShapes( dg.getNumShapes() + 1 ); + dg.setLastMSOSPID( result ); + if (result >= dgg.getShapeIdMax()) + dgg.setShapeIdMax( result + 1 ); + return result; + } + } + + // Create new cluster + dgg.addCluster( dg.getDrawingGroupId(), 0 ); + dgg.getFileIdClusters()[dgg.getFileIdClusters().length-1].incrementShapeId(); + dg.setNumShapes( dg.getNumShapes() + 1 ); + int result = (1024 * dgg.getFileIdClusters().length); + dg.setLastMSOSPID( result ); + if (result >= dgg.getShapeIdMax()) + dgg.setShapeIdMax( result + 1 ); + return result; } /** @@ -353,6 +405,24 @@ public abstract class Shape { return new Color(tmp.getBlue(), tmp.getGreen(), tmp.getRed(), alpha); } + /** + * @return id for the shape. + */ + public int getShapeId(){ + EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID); + return spRecord == null ? 0 : spRecord.getShapeId(); + } + + /** + * Sets shape ID + * + * @param id of the shape + */ + public void setShapeId(int id){ + EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID); + if(spRecord != null) spRecord.setShapeId(id); + } + /** * Fill properties of this shape * diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java b/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java index 2a1785bd1..d9c8903d5 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java @@ -247,14 +247,6 @@ public abstract class Sheet { EscherContainerRecord spgr = (EscherContainerRecord) Shape.getEscherChild(dgContainer, EscherContainerRecord.SPGR_CONTAINER); spgr.addChildRecord(shape.getSpContainer()); - EscherDgRecord dg = (EscherDgRecord) Shape.getEscherChild(dgContainer, EscherDgRecord.RECORD_ID); - dg.setNumShapes(dg.getNumShapes() + 1); - - int shapeId = dg.getLastMSOSPID()+1; - dg.setLastMSOSPID(shapeId); - - EscherSpRecord sp = shape.getSpContainer().getChildById(EscherSpRecord.RECORD_ID); - if(sp != null) sp.setShapeId(shapeId); shape.setSheet(this); shape.afterInsert(this); diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/Table.java b/src/scratchpad/src/org/apache/poi/hslf/model/Table.java index dd4a6a33f..43dab58af 100755 --- a/src/scratchpad/src/org/apache/poi/hslf/model/Table.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/Table.java @@ -112,6 +112,8 @@ public class Table extends ShapeGroup { } protected void afterInsert(Sheet sh){ + super.afterInsert(sh); + EscherContainerRecord spCont = (EscherContainerRecord) getSpContainer().getChild(0); List lst = spCont.getChildRecords(); EscherOptRecord opt = (EscherOptRecord)lst.get(lst.size()-2); diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/TextShape.java b/src/scratchpad/src/org/apache/poi/hslf/model/TextShape.java index 24c312637..7249817be 100755 --- a/src/scratchpad/src/org/apache/poi/hslf/model/TextShape.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/TextShape.java @@ -184,6 +184,8 @@ public abstract class TextShape extends SimpleShape { * @param sh the sheet we are adding to */ protected void afterInsert(Sheet sh){ + super.afterInsert(sh); + EscherTextboxWrapper _txtbox = getEscherTextboxWrapper(); if(_txtbox != null){ PPDrawing ppdrawing = sh.getPPDrawing(); diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawingGroup.java b/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawingGroup.java index 8d25ce214..c7de1fccd 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawingGroup.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawingGroup.java @@ -37,6 +37,8 @@ public class PPDrawingGroup extends RecordAtom { private byte[] _header; private EscherContainerRecord dggContainer; + //cached dgg + private EscherDggRecord dgg; protected PPDrawingGroup(byte[] source, int start, int len) { // Get the header @@ -116,4 +118,17 @@ public class PPDrawingGroup extends RecordAtom { public EscherContainerRecord getDggContainer(){ return dggContainer; } + + public EscherDggRecord getEscherDggRecord(){ + if(dgg == null){ + for(Iterator it = dggContainer.getChildRecords().iterator(); it.hasNext();){ + EscherRecord r = (EscherRecord) it.next(); + if(r instanceof EscherDggRecord){ + dgg = (EscherDggRecord)r; + break; + } + } + } + return dgg; + } } diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java index c2e081ee5..511ef7f74 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java @@ -307,4 +307,22 @@ public class TestShapes extends TestCase { sl = ppt.getSlides()[0]; assertEquals("expected 0 shaped in " + file, 0, sl.getShapes().length); } + + public void testShapeId() throws IOException { + SlideShow ppt = new SlideShow(); + Slide slide = ppt.createSlide(); + Shape shape; + + shape = new Line(); + assertEquals(0, shape.getShapeId()); + slide.addShape(shape); + assertTrue(shape.getShapeId() > 0); + + int shapeId = shape.getShapeId(); + + shape = new Line(); + assertEquals(0, shape.getShapeId()); + slide.addShape(shape); + assertEquals(shapeId + 1, shape.getShapeId()); + } }