From: Evgeniy Berlog Date: Fri, 22 Jun 2012 09:37:17 +0000 (+0000) Subject: added support for HSSFPicture in HSSFShapeFactory, fixed bugs, added tests X-Git-Tag: 3.10-beta1~161^2~21 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=7efc80c3e8945546bb7fa4fa019e9f6449e5b55b;p=poi.git added support for HSSFPicture in HSSFShapeFactory, fixed bugs, added tests git-svn-id: https://svn.apache.org/repos/asf/poi/branches/gsoc2012@1352818 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/src/java/org/apache/poi/ddf/EscherRGBProperty.java b/src/java/org/apache/poi/ddf/EscherRGBProperty.java index e28b97b500..5d23addfb5 100644 --- a/src/java/org/apache/poi/ddf/EscherRGBProperty.java +++ b/src/java/org/apache/poi/ddf/EscherRGBProperty.java @@ -38,10 +38,6 @@ public class EscherRGBProperty return propertyValue; } - public void setRgbColor(int color){ - this.propertyValue = color; - } - public byte getRed() { return (byte) ( propertyValue & 0xFF ); diff --git a/src/java/org/apache/poi/ddf/EscherSimpleProperty.java b/src/java/org/apache/poi/ddf/EscherSimpleProperty.java index efc392dcfa..78fb642034 100644 --- a/src/java/org/apache/poi/ddf/EscherSimpleProperty.java +++ b/src/java/org/apache/poi/ddf/EscherSimpleProperty.java @@ -80,10 +80,6 @@ public class EscherSimpleProperty extends EscherProperty return propertyValue; } - public void setPropertyValue(int propertyValue) { - this.propertyValue = propertyValue; - } - /** * Returns true if one escher property is equal to another. */ diff --git a/src/java/org/apache/poi/hssf/record/EscherAggregate.java b/src/java/org/apache/poi/hssf/record/EscherAggregate.java index f1b470398f..fb16037a37 100644 --- a/src/java/org/apache/poi/hssf/record/EscherAggregate.java +++ b/src/java/org/apache/poi/hssf/record/EscherAggregate.java @@ -315,6 +315,10 @@ public final class EscherAggregate extends AbstractEscherHolderRecord { */ private List tailRec = new ArrayList(); + public EscherAggregate() { + buildBaseTree(); + } + public EscherAggregate(DrawingManager2 drawingManager) { this.drawingManager = drawingManager; } @@ -634,7 +638,6 @@ public final class EscherAggregate extends AbstractEscherHolderRecord { public void setPatriarch(HSSFPatriarch patriarch) { this.patriarch = patriarch; - convertPatriarch(patriarch); } /** @@ -1025,6 +1028,43 @@ public final class EscherAggregate extends AbstractEscherHolderRecord { throw new IllegalArgumentException("Can not find client data record"); } + private void buildBaseTree(){ + EscherContainerRecord dgContainer = new EscherContainerRecord(); + 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); + EscherDgRecord dg = new EscherDgRecord(); + dg.setRecordId( EscherDgRecord.RECORD_ID ); + short dgId = 1; + dg.setOptions( (short) ( dgId << 4 ) ); + dg.setNumShapes( 1 ); + dg.setLastMSOSPID( 1024 ); + drawingGroupId = dg.getDrawingGroupId(); + 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(0); + spgr.setRectY1(0); + spgr.setRectX2(1023); + spgr.setRectY2(255); + sp1.setRecordId(EscherSpRecord.RECORD_ID); + sp1.setOptions((short) 0x0002); + sp1.setShapeId(1024); + 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 void convertPatriarch(HSSFPatriarch patriarch) { EscherContainerRecord dgContainer = new EscherContainerRecord(); EscherDgRecord dg; diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFPicture.java b/src/java/org/apache/poi/hssf/usermodel/HSSFPicture.java index 5aeb40b188..985bb8f177 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFPicture.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFPicture.java @@ -20,8 +20,8 @@ package org.apache.poi.hssf.usermodel; import java.awt.Dimension; import java.io.ByteArrayInputStream; -import org.apache.poi.ddf.EscherBSERecord; -import org.apache.poi.ddf.EscherBlipRecord; +import org.apache.poi.ddf.*; +import org.apache.poi.hssf.record.ObjRecord; import org.apache.poi.ss.usermodel.Picture; import org.apache.poi.ss.util.ImageUtils; import org.apache.poi.hssf.model.InternalWorkbook; @@ -54,7 +54,9 @@ public final class HSSFPicture extends HSSFSimpleShape implements Picture { */ private static final int PX_ROW = 15; - private int _pictureIndex; + public HSSFPicture(EscherContainerRecord spContainer, ObjRecord objRecord) { + super(spContainer, objRecord); + } /** * Constructs a picture object. @@ -67,12 +69,16 @@ public final class HSSFPicture extends HSSFSimpleShape implements Picture { public int getPictureIndex() { - return _pictureIndex; + EscherSimpleProperty property = _optRecord.lookup(EscherProperties.BLIP__BLIPTODISPLAY); + if (null == property){ + return -1; + } + return property.getPropertyValue(); } public void setPictureIndex( int pictureIndex ) { - this._pictureIndex = pictureIndex; + setPropertyValue(new EscherSimpleProperty( EscherProperties.BLIP__BLIPTODISPLAY, false, true, pictureIndex)); } /** @@ -215,7 +221,7 @@ public final class HSSFPicture extends HSSFSimpleShape implements Picture { * @return image dimension */ public Dimension getImageDimension(){ - EscherBSERecord bse = _patriarch._sheet._book.getBSERecord(_pictureIndex); + EscherBSERecord bse = _patriarch._sheet._book.getBSERecord(getPictureIndex()); byte[] data = bse.getBlipRecord().getPicturedata(); int type = bse.getBlipTypeWin32(); return ImageUtils.getImageDimension(new ByteArrayInputStream(data), type); @@ -228,7 +234,7 @@ public final class HSSFPicture extends HSSFSimpleShape implements Picture { */ public HSSFPictureData getPictureData(){ InternalWorkbook iwb = _patriarch._sheet.getWorkbook().getWorkbook(); - EscherBlipRecord blipRecord = iwb.getBSERecord(_pictureIndex).getBlipRecord(); + EscherBlipRecord blipRecord = iwb.getBSERecord(getPictureIndex()).getBlipRecord(); return new HSSFPictureData(blipRecord); } } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFShape.java b/src/java/org/apache/poi/hssf/usermodel/HSSFShape.java index c9bf922cb7..33dfd68643 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFShape.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFShape.java @@ -30,6 +30,7 @@ public abstract class HSSFShape { public static final int LINEWIDTH_DEFAULT = 9525; public static final int LINESTYLE__COLOR_DEFAULT = 0x08000040; public static final int FILL__FILLCOLOR_DEFAULT = 0x08000009; + public static final boolean NO_FILL_DEFAULT = true; public static final int LINESTYLE_SOLID = 0; // Solid (continuous) pen public static final int LINESTYLE_DASHSYS = 1; // PS_DASH system dash style @@ -44,6 +45,8 @@ public abstract class HSSFShape { public static final int LINESTYLE_LONGDASHDOTDOTGEL = 10; // long dash short dash short dash public static final int LINESTYLE_NONE = -1; + public static final int LINESTYLE_DEFAULT = LINESTYLE_NONE; + // TODO - make all these fields private HSSFShape parent; HSSFAnchor anchor; @@ -108,11 +111,20 @@ public abstract class HSSFShape { * @see HSSFClientAnchor */ public void setAnchor(HSSFAnchor anchor) { + int i = 0; + int recordId = -1; if (parent == null) { if (anchor instanceof HSSFChildAnchor) throw new IllegalArgumentException("Must use client anchors for shapes directly attached to sheet."); EscherClientAnchorRecord anch = _escherContainer.getChildById(EscherClientAnchorRecord.RECORD_ID); if (null != anch) { + for (i=0; i< _escherContainer.getChildRecords().size(); i++){ + if (_escherContainer.getChild(i).getRecordId() == EscherClientAnchorRecord.RECORD_ID){ + if (i != _escherContainer.getChildRecords().size() -1){ + recordId = _escherContainer.getChild(i+1).getRecordId(); + } + } + } _escherContainer.removeChildRecord(anch); } } else { @@ -120,10 +132,21 @@ public abstract class HSSFShape { throw new IllegalArgumentException("Must use child anchors for shapes attached to groups."); EscherChildAnchorRecord anch = _escherContainer.getChildById(EscherChildAnchorRecord.RECORD_ID); if (null != anch) { + for (i=0; i< _escherContainer.getChildRecords().size(); i++){ + if (_escherContainer.getChild(i).getRecordId() == EscherChildAnchorRecord.RECORD_ID){ + if (i != _escherContainer.getChildRecords().size() -1){ + recordId = _escherContainer.getChild(i+1).getRecordId(); + } + } + } _escherContainer.removeChildRecord(anch); } } - _escherContainer.addChildRecord(anchor.getEscherAnchor()); + if (-1 == recordId){ + _escherContainer.addChildRecord(anchor.getEscherAnchor()); + } else { + _escherContainer.addChildBefore(anchor.getEscherAnchor(), recordId); + } this.anchor = anchor; } @@ -139,13 +162,7 @@ public abstract class HSSFShape { * The color applied to the lines of this shape. */ public void setLineStyleColor(int lineStyleColor) { - EscherRGBProperty rgbProperty = _optRecord.lookup(EscherProperties.LINESTYLE__COLOR); - if (null == rgbProperty) { - rgbProperty = new EscherRGBProperty(EscherProperties.LINESTYLE__COLOR, lineStyleColor); - _optRecord.addEscherProperty(rgbProperty); - } else { - rgbProperty.setRgbColor(lineStyleColor); - } + setPropertyValue(new EscherRGBProperty(EscherProperties.LINESTYLE__COLOR, lineStyleColor)); } /** @@ -153,13 +170,7 @@ public abstract class HSSFShape { */ public void setLineStyleColor(int red, int green, int blue) { int lineStyleColor = ((blue) << 16) | ((green) << 8) | red; - EscherRGBProperty rgbProperty = _optRecord.lookup(EscherProperties.LINESTYLE__COLOR); - if (null == rgbProperty) { - rgbProperty = new EscherRGBProperty(EscherProperties.LINESTYLE__COLOR, lineStyleColor); - _optRecord.addEscherProperty(rgbProperty); - } else { - rgbProperty.setRgbColor(lineStyleColor); - } + setPropertyValue(new EscherRGBProperty(EscherProperties.LINESTYLE__COLOR, lineStyleColor)); } /** @@ -174,13 +185,7 @@ public abstract class HSSFShape { * The color used to fill this shape. */ public void setFillColor(int fillColor) { - EscherRGBProperty rgbProperty = _optRecord.lookup(EscherProperties.FILL__FILLCOLOR); - if (null == rgbProperty) { - rgbProperty = new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, fillColor); - _optRecord.addEscherProperty(rgbProperty); - } else { - rgbProperty.setRgbColor(fillColor); - } + setPropertyValue(new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, fillColor)); } /** @@ -188,13 +193,7 @@ public abstract class HSSFShape { */ public void setFillColor(int red, int green, int blue) { int fillColor = ((blue) << 16) | ((green) << 8) | red; - EscherRGBProperty rgbProperty = _optRecord.lookup(EscherProperties.FILL__FILLCOLOR); - if (null == rgbProperty) { - rgbProperty = new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, fillColor); - _optRecord.addEscherProperty(rgbProperty); - } else { - rgbProperty.setRgbColor(fillColor); - } + setPropertyValue(new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, fillColor)); } /** @@ -202,7 +201,7 @@ public abstract class HSSFShape { */ public int getLineWidth() { EscherSimpleProperty property = _optRecord.lookup(EscherProperties.LINESTYLE__LINEWIDTH); - return property.getPropertyValue(); + return property == null ? LINEWIDTH_DEFAULT: property.getPropertyValue(); } /** @@ -212,13 +211,7 @@ public abstract class HSSFShape { * @see HSSFShape#LINEWIDTH_ONE_PT */ public void setLineWidth(int lineWidth) { - EscherSimpleProperty property = _optRecord.lookup(EscherProperties.LINESTYLE__LINEWIDTH); - if (null == property) { - property = new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEWIDTH, lineWidth); - _optRecord.addEscherProperty(property); - } else { - property.setPropertyValue(lineWidth); - } + setPropertyValue(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEWIDTH, lineWidth)); } /** @@ -227,7 +220,7 @@ public abstract class HSSFShape { public int getLineStyle() { EscherSimpleProperty property = _optRecord.lookup(EscherProperties.LINESTYLE__LINEDASHING); if (null == property){ - return -1; + return LINESTYLE_DEFAULT; } return property.getPropertyValue(); } @@ -238,13 +231,7 @@ public abstract class HSSFShape { * @param lineStyle One of the constants in LINESTYLE_* */ public void setLineStyle(int lineStyle) { - EscherSimpleProperty property = _optRecord.lookup(EscherProperties.LINESTYLE__LINEDASHING); - if (null == property) { - property = new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEDASHING, lineStyle); - _optRecord.addEscherProperty(property); - } else { - property.setPropertyValue(lineStyle); - } + setPropertyValue(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEDASHING, lineStyle)); } /** @@ -252,19 +239,29 @@ public abstract class HSSFShape { */ public boolean isNoFill() { EscherBoolProperty property = _optRecord.lookup(EscherProperties.FILL__NOFILLHITTEST); - return property.isTrue(); + return property == null ? NO_FILL_DEFAULT : property.isTrue(); } /** * Sets whether this shape is filled or transparent. */ public void setNoFill(boolean noFill) { - EscherBoolProperty property = _optRecord.lookup(EscherProperties.FILL__NOFILLHITTEST); - if (null == property) { - property = new EscherBoolProperty(EscherProperties.FILL__NOFILLHITTEST, noFill ? 1 : 0); + setPropertyValue(new EscherBoolProperty(EscherProperties.FILL__NOFILLHITTEST, noFill ? 1 : 0)); + } + + protected void setPropertyValue(EscherProperty property){ + if (null == _optRecord.lookup(property.getId())){ _optRecord.addEscherProperty(property); } else { - property.setPropertyValue(noFill ? 1 : 0); + int i=0; + for (EscherProperty prop: _optRecord.getEscherProperties()){ + if (prop.getId() == property.getId()){ + _optRecord.getEscherProperties().remove(i); + break; + } + i++; + } + _optRecord.addEscherProperty(property); } } diff --git a/src/java/org/apache/poi/hssf/usermodel/drawing/HSSFShapeType.java b/src/java/org/apache/poi/hssf/usermodel/drawing/HSSFShapeType.java index 29741c90f8..c63a08b7e5 100644 --- a/src/java/org/apache/poi/hssf/usermodel/drawing/HSSFShapeType.java +++ b/src/java/org/apache/poi/hssf/usermodel/drawing/HSSFShapeType.java @@ -1,5 +1,6 @@ package org.apache.poi.hssf.usermodel.drawing; +import org.apache.poi.hssf.usermodel.HSSFPicture; import org.apache.poi.hssf.usermodel.HSSFSimpleShape; /** @@ -9,6 +10,7 @@ import org.apache.poi.hssf.usermodel.HSSFSimpleShape; public enum HSSFShapeType { NOT_PRIMITIVE((short)0x0, null, (short)0), RECTANGLE((short)0x1, HSSFSimpleShape.class, HSSFSimpleShape.OBJECT_TYPE_RECTANGLE), + PICTURE((short)0x004B, HSSFPicture.class, HSSFSimpleShape.OBJECT_TYPE_PICTURE), ROUND_RECTANGLE((short)0x2, null, null); private Short type; diff --git a/src/testcases/org/apache/poi/hssf/model/TestDrawingAggregate.java b/src/testcases/org/apache/poi/hssf/model/TestDrawingAggregate.java index 43cdd8b856..18572d6ec1 100644 --- a/src/testcases/org/apache/poi/hssf/model/TestDrawingAggregate.java +++ b/src/testcases/org/apache/poi/hssf/model/TestDrawingAggregate.java @@ -43,6 +43,8 @@ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FilenameFilter; import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -192,6 +194,40 @@ public class TestDrawingAggregate extends TestCase { } } + public void testBuildBaseTree(){ + EscherAggregate agg = new EscherAggregate(); + HSSFWorkbook wb = new HSSFWorkbook(); + HSSFSheet sheet = wb.createSheet(); + + HSSFPatriarch drawing = sheet.createDrawingPatriarch(); + EscherAggregate agg1 = HSSFTestHelper.getEscherAggregate(drawing); + callConvertPatriarch(agg1); + agg1.setPatriarch(null); + + agg.setPatriarch(null); + + byte[] aggS = agg.serialize(); + byte []agg1S = agg1.serialize(); + + assertEquals(aggS.length, agg1S.length); + assertTrue(Arrays.equals(aggS, agg1S)); + } + + private 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. + } + } + /** * when reading incomplete data ensure that the serialized bytes match the source diff --git a/src/testcases/org/apache/poi/hssf/model/TestDrawingShapes.java b/src/testcases/org/apache/poi/hssf/model/TestDrawingShapes.java index f276cba391..097d5d01ee 100644 --- a/src/testcases/org/apache/poi/hssf/model/TestDrawingShapes.java +++ b/src/testcases/org/apache/poi/hssf/model/TestDrawingShapes.java @@ -3,6 +3,9 @@ package org.apache.poi.hssf.model; import junit.framework.TestCase; import org.apache.poi.ddf.*; import org.apache.poi.hssf.HSSFTestDataSamples; +import org.apache.poi.hssf.record.CommonObjectDataSubRecord; +import org.apache.poi.hssf.record.EscherAggregate; +import org.apache.poi.hssf.record.ObjRecord; import org.apache.poi.hssf.usermodel.*; import org.apache.poi.util.HexDump; @@ -72,6 +75,38 @@ public class TestDrawingShapes extends TestCase{ assertEquals(true, ((EscherBoolProperty)opt.lookup(EscherProperties.GROUPSHAPE__PRINT)).isTrue()); } + + public void testDefaultPictureSettings(){ + HSSFPicture picture = new HSSFPicture(null, new HSSFClientAnchor()); + assertEquals(picture.getLineWidth(), HSSFShape.LINEWIDTH_DEFAULT); + assertEquals(picture.getFillColor(), HSSFShape.FILL__FILLCOLOR_DEFAULT); + assertEquals(picture.getLineStyle(), HSSFShape.LINESTYLE_SOLID); + assertEquals(picture.getLineStyleColor(), HSSFShape.LINESTYLE__COLOR_DEFAULT); + assertEquals(picture.isNoFill(), false); + assertEquals(picture.getPictureIndex(), -1);//not set yet + } + + /** + * No NullPointerException should appear + */ + public void testDefaultSettingsWithEmptyContainer(){ + EscherContainerRecord container = new EscherContainerRecord(); + EscherOptRecord opt = new EscherOptRecord(); + opt.setRecordId(EscherOptRecord.RECORD_ID); + container.addChildRecord(opt); + ObjRecord obj = new ObjRecord(); + CommonObjectDataSubRecord cod = new CommonObjectDataSubRecord(); + cod.setObjectType(HSSFSimpleShape.OBJECT_TYPE_PICTURE); + obj.addSubRecord(cod); + HSSFPicture picture = new HSSFPicture(container, obj); + + assertEquals(picture.getLineWidth(), HSSFShape.LINEWIDTH_DEFAULT); + assertEquals(picture.getFillColor(), HSSFShape.FILL__FILLCOLOR_DEFAULT); + assertEquals(picture.getLineStyle(), HSSFShape.LINESTYLE_DEFAULT); + assertEquals(picture.getLineStyleColor(), HSSFShape.LINESTYLE__COLOR_DEFAULT); + assertEquals(picture.isNoFill(), HSSFShape.NO_FILL_DEFAULT); + assertEquals(picture.getPictureIndex(), -1);//not set yet + } /** * create a rectangle, save the workbook, read back and verify that all shape properties are there */ @@ -139,6 +174,28 @@ public class TestDrawingShapes extends TestCase{ assertEquals(rectangle2.getAnchor().getDy1(), 4); assertEquals(rectangle2.getAnchor().getDy2(), 5); assertEquals(rectangle2.isNoFill(), false); + + HSSFSimpleShape rect3 = drawing.createSimpleShape(new HSSFClientAnchor()); + rect3.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE); + wb = HSSFTestDataSamples.writeOutAndReadBack(wb); + + drawing = wb.getSheetAt(0).getDrawingPatriarch(); + assertEquals(drawing.getChildren().size(), 2); + } + + public void testReadExistingImage(){ + HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls"); + HSSFSheet sheet = wb.getSheet("pictures"); + HSSFPatriarch drawing = sheet.getDrawingPatriarch(); + assertEquals(1, drawing.getChildren().size()); + HSSFPicture picture = (HSSFPicture) drawing.getChildren().get(0); + + assertEquals(picture.getPictureIndex(), 1); + assertEquals(picture.getLineStyleColor(), HSSFShape.LINESTYLE__COLOR_DEFAULT); + assertEquals(picture.getFillColor(), 0x5DC943); + assertEquals(picture.getLineWidth(), HSSFShape.LINEWIDTH_DEFAULT); + assertEquals(picture.getLineStyle(), HSSFShape.LINESTYLE_DEFAULT); + assertEquals(picture.isNoFill(), true); } @@ -157,4 +214,41 @@ public class TestDrawingShapes extends TestCase{ assertEquals(shape.getLineWidth(), HSSFShape.LINEWIDTH_ONE_PT*2); } } + + public void testShapeIds() { + HSSFWorkbook wb = new HSSFWorkbook(); + HSSFSheet sheet1 = wb.createSheet(); + HSSFPatriarch patriarch1 = sheet1.createDrawingPatriarch(); + for(int i = 0; i < 2; i++) { + patriarch1.createSimpleShape(new HSSFClientAnchor()); + } + + wb = HSSFTestDataSamples.writeOutAndReadBack(wb); + sheet1 = wb.getSheetAt(0); + patriarch1 = sheet1.getDrawingPatriarch(); + + EscherAggregate agg1 = HSSFTestHelper.getEscherAggregate(patriarch1); + // last shape ID cached in EscherDgRecord + EscherDgRecord dg1 = + agg1.getEscherContainer().getChildById(EscherDgRecord.RECORD_ID); + assertEquals(1026, dg1.getLastMSOSPID()); + + // iterate over shapes and check shapeId + EscherContainerRecord spgrContainer = + agg1.getEscherContainer().getChildContainers().get(0); + // root spContainer + 2 spContainers for shapes + assertEquals(3, spgrContainer.getChildRecords().size()); + + EscherSpRecord sp0 = + ((EscherContainerRecord)spgrContainer.getChild(0)).getChildById(EscherSpRecord.RECORD_ID); + assertEquals(1024, sp0.getShapeId()); + + EscherSpRecord sp1 = + ((EscherContainerRecord)spgrContainer.getChild(1)).getChildById(EscherSpRecord.RECORD_ID); + assertEquals(1025, sp1.getShapeId()); + + EscherSpRecord sp2 = + ((EscherContainerRecord)spgrContainer.getChild(2)).getChildById(EscherSpRecord.RECORD_ID); + assertEquals(1026, sp2.getShapeId()); + } } diff --git a/src/testcases/org/apache/poi/hssf/model/TestHSSFAnchor.java b/src/testcases/org/apache/poi/hssf/model/TestHSSFAnchor.java index ef90f01f40..248247266a 100644 --- a/src/testcases/org/apache/poi/hssf/model/TestHSSFAnchor.java +++ b/src/testcases/org/apache/poi/hssf/model/TestHSSFAnchor.java @@ -1,10 +1,10 @@ package org.apache.poi.hssf.model; import junit.framework.TestCase; -import org.apache.poi.ddf.EscherChildAnchorRecord; -import org.apache.poi.ddf.EscherClientAnchorRecord; -import org.apache.poi.ddf.EscherContainerRecord; +import org.apache.poi.ddf.*; +import org.apache.poi.hssf.HSSFTestDataSamples; import org.apache.poi.hssf.usermodel.*; +import org.apache.poi.util.HexDump; /** * @author Evgeniy Berlog @@ -12,6 +12,63 @@ import org.apache.poi.hssf.usermodel.*; */ public class TestHSSFAnchor extends TestCase { + public void testDefaultValues(){ + HSSFClientAnchor clientAnchor = new HSSFClientAnchor(); + assertEquals(clientAnchor.getAnchorType(), 0); + assertEquals(clientAnchor.getCol1(), 0); + assertEquals(clientAnchor.getCol2(), 0); + assertEquals(clientAnchor.getDx1(), 0); + assertEquals(clientAnchor.getDx2(), 0); + assertEquals(clientAnchor.getDy1(), 0); + assertEquals(clientAnchor.getDy2(), 0); + assertEquals(clientAnchor.getRow1(), 0); + assertEquals(clientAnchor.getRow2(), 0); + + clientAnchor = new HSSFClientAnchor(new EscherClientAnchorRecord()); + assertEquals(clientAnchor.getAnchorType(), 0); + assertEquals(clientAnchor.getCol1(), 0); + assertEquals(clientAnchor.getCol2(), 0); + assertEquals(clientAnchor.getDx1(), 0); + assertEquals(clientAnchor.getDx2(), 0); + assertEquals(clientAnchor.getDy1(), 0); + assertEquals(clientAnchor.getDy2(), 0); + assertEquals(clientAnchor.getRow1(), 0); + assertEquals(clientAnchor.getRow2(), 0); + + HSSFChildAnchor childAnchor = new HSSFChildAnchor(); + assertEquals(childAnchor.getDx1(), 0); + assertEquals(childAnchor.getDx2(), 0); + assertEquals(childAnchor.getDy1(), 0); + assertEquals(childAnchor.getDy2(), 0); + + childAnchor = new HSSFChildAnchor(new EscherChildAnchorRecord()); + assertEquals(childAnchor.getDx1(), 0); + assertEquals(childAnchor.getDx2(), 0); + assertEquals(childAnchor.getDy1(), 0); + assertEquals(childAnchor.getDy2(), 0); + } + + public void testCorrectOrderInSpContainer(){ + HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls"); + HSSFSheet sheet = wb.getSheet("pictures"); + HSSFPatriarch drawing = sheet.getDrawingPatriarch(); + + HSSFSimpleShape rectangle = (HSSFSimpleShape) drawing.getChildren().get(0); + rectangle.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE); + + assertEquals(rectangle.getEscherContainer().getChild(0).getRecordId(), EscherSpRecord.RECORD_ID); + assertEquals(rectangle.getEscherContainer().getChild(1).getRecordId(), EscherOptRecord.RECORD_ID); + assertEquals(" " + HexDump.toHex(rectangle.getEscherContainer().getChild(2).getRecordId()) + " ", rectangle.getEscherContainer().getChild(2).getRecordId(), EscherClientAnchorRecord.RECORD_ID); + assertEquals(rectangle.getEscherContainer().getChild(3).getRecordId(), EscherClientDataRecord.RECORD_ID); + + rectangle.setAnchor(new HSSFClientAnchor()); + + assertEquals(rectangle.getEscherContainer().getChild(0).getRecordId(), EscherSpRecord.RECORD_ID); + assertEquals(rectangle.getEscherContainer().getChild(1).getRecordId(), EscherOptRecord.RECORD_ID); + assertEquals(" " + HexDump.toHex(rectangle.getEscherContainer().getChild(2).getRecordId()) + " ", rectangle.getEscherContainer().getChild(2).getRecordId(), EscherClientAnchorRecord.RECORD_ID); + assertEquals(rectangle.getEscherContainer().getChild(3).getRecordId(), EscherClientDataRecord.RECORD_ID); + } + public void testCreateClientAnchorFromContainer(){ EscherContainerRecord container = new EscherContainerRecord(); EscherClientAnchorRecord escher = new EscherClientAnchorRecord(); @@ -206,4 +263,116 @@ public class TestHSSFAnchor extends TestCase { assertEquals(anchor.getDy2(), 118); assertEquals(escher.getDy2(), 118); } + + public void testEqualsToSelf(){ + HSSFClientAnchor clientAnchor = new HSSFClientAnchor(0, 1, 2, 3, (short)4, 5, (short)6, 7); + assertEquals(clientAnchor, clientAnchor); + + HSSFChildAnchor childAnchor = new HSSFChildAnchor(0, 1, 2, 3); + assertEquals(childAnchor, childAnchor); + } + + public void testPassIncompatibleTypeIsFalse(){ + HSSFClientAnchor clientAnchor = new HSSFClientAnchor(0, 1, 2, 3, (short)4, 5, (short)6, 7); + assertNotSame(clientAnchor, "wrongType"); + + HSSFChildAnchor childAnchor = new HSSFChildAnchor(0, 1, 2, 3); + assertNotSame(childAnchor, "wrongType"); + } + + public void testNullReferenceIsFalse() { + HSSFClientAnchor clientAnchor = new HSSFClientAnchor(0, 1, 2, 3, (short)4, 5, (short)6, 7); + assertFalse("Passing null to equals should return false", clientAnchor.equals(null)); + + HSSFChildAnchor childAnchor = new HSSFChildAnchor(0, 1, 2, 3); + assertFalse("Passing null to equals should return false", childAnchor.equals(null)); + } + + public void testEqualsIsReflexiveIsSymmetric() { + HSSFClientAnchor clientAnchor1 = new HSSFClientAnchor(0, 1, 2, 3, (short)4, 5, (short)6, 7); + HSSFClientAnchor clientAnchor2 = new HSSFClientAnchor(0, 1, 2, 3, (short)4, 5, (short)6, 7); + + assertTrue(clientAnchor1.equals(clientAnchor2)); + assertTrue(clientAnchor1.equals(clientAnchor2)); + + HSSFChildAnchor childAnchor1 = new HSSFChildAnchor(0, 1, 2, 3); + HSSFChildAnchor childAnchor2 = new HSSFChildAnchor(0, 1, 2, 3); + + assertTrue(childAnchor1.equals(childAnchor2)); + assertTrue(childAnchor2.equals(childAnchor1)); + } + + public void testEqualsValues(){ + HSSFClientAnchor clientAnchor1 = new HSSFClientAnchor(0, 1, 2, 3, (short)4, 5, (short)6, 7); + HSSFClientAnchor clientAnchor2 = new HSSFClientAnchor(0, 1, 2, 3, (short)4, 5, (short)6, 7); + assertEquals(clientAnchor1, clientAnchor2); + + clientAnchor2.setDx1(10); + assertNotSame(clientAnchor1, clientAnchor2); + clientAnchor2.setDx1(0); + assertEquals(clientAnchor1, clientAnchor2); + + clientAnchor2.setDy1(10); + assertNotSame(clientAnchor1, clientAnchor2); + clientAnchor2.setDy1(1); + assertEquals(clientAnchor1, clientAnchor2); + + clientAnchor2.setDx2(10); + assertNotSame(clientAnchor1, clientAnchor2); + clientAnchor2.setDx2(2); + assertEquals(clientAnchor1, clientAnchor2); + + clientAnchor2.setDy2(10); + assertNotSame(clientAnchor1, clientAnchor2); + clientAnchor2.setDy2(3); + assertEquals(clientAnchor1, clientAnchor2); + + clientAnchor2.setCol1(10); + assertNotSame(clientAnchor1, clientAnchor2); + clientAnchor2.setCol1(4); + assertEquals(clientAnchor1, clientAnchor2); + + clientAnchor2.setRow1(10); + assertNotSame(clientAnchor1, clientAnchor2); + clientAnchor2.setRow1(5); + assertEquals(clientAnchor1, clientAnchor2); + + clientAnchor2.setCol2(10); + assertNotSame(clientAnchor1, clientAnchor2); + clientAnchor2.setCol2(6); + assertEquals(clientAnchor1, clientAnchor2); + + clientAnchor2.setRow2(10); + assertNotSame(clientAnchor1, clientAnchor2); + clientAnchor2.setRow2(7); + assertEquals(clientAnchor1, clientAnchor2); + + clientAnchor2.setAnchorType(3); + assertNotSame(clientAnchor1, clientAnchor2); + clientAnchor2.setAnchorType(0); + assertEquals(clientAnchor1, clientAnchor2); + + HSSFChildAnchor childAnchor1 = new HSSFChildAnchor(0, 1, 2, 3); + HSSFChildAnchor childAnchor2 = new HSSFChildAnchor(0, 1, 2, 3); + + childAnchor1.setDx1(10); + assertNotSame(childAnchor1, childAnchor2); + childAnchor1.setDx1(0); + assertEquals(childAnchor1, childAnchor2); + + childAnchor2.setDy1(10); + assertNotSame(childAnchor1, childAnchor2); + childAnchor2.setDy1(1); + assertEquals(childAnchor1, childAnchor2); + + childAnchor2.setDx2(10); + assertNotSame(childAnchor1, childAnchor2); + childAnchor2.setDx2(2); + assertEquals(childAnchor1, childAnchor2); + + childAnchor2.setDy2(10); + assertNotSame(childAnchor1, childAnchor2); + childAnchor2.setDy2(3); + assertEquals(childAnchor1, childAnchor2); + } } diff --git a/test-data/spreadsheet/drawings.xls b/test-data/spreadsheet/drawings.xls index ccbcc8cb4a..27de3b575d 100644 Binary files a/test-data/spreadsheet/drawings.xls and b/test-data/spreadsheet/drawings.xls differ