Return-Path: X-Original-To: apmail-poi-commits-archive@minotaur.apache.org Delivered-To: apmail-poi-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 148F8CB09 for ; Fri, 10 Aug 2012 11:31:35 +0000 (UTC) Received: (qmail 89276 invoked by uid 500); 10 Aug 2012 11:31:34 -0000 Delivered-To: apmail-poi-commits-archive@poi.apache.org Received: (qmail 89179 invoked by uid 500); 10 Aug 2012 11:31:33 -0000 Mailing-List: contact commits-help@poi.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@poi.apache.org Delivered-To: mailing list commits@poi.apache.org Received: (qmail 89152 invoked by uid 99); 10 Aug 2012 11:31:33 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 10 Aug 2012 11:31:33 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED,T_FRT_STOCK2 X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 10 Aug 2012 11:31:30 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 5BA9B23889E1 for ; Fri, 10 Aug 2012 11:30:47 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1371663 [4/6] - in /poi/trunk: ./ src/java/org/apache/poi/ddf/ src/java/org/apache/poi/hssf/dev/ src/java/org/apache/poi/hssf/model/ src/java/org/apache/poi/hssf/record/ src/java/org/apache/poi/hssf/record/aggregates/ src/java/org/apache/p... Date: Fri, 10 Aug 2012 11:30:44 -0000 To: commits@poi.apache.org From: yegor@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120810113047.5BA9B23889E1@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Modified: poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFShape.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFShape.java?rev=1371663&r1=1371662&r2=1371663&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFShape.java (original) +++ poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFShape.java Fri Aug 10 11:30:42 2012 @@ -17,6 +17,15 @@ package org.apache.poi.hssf.usermodel; +import org.apache.poi.ddf.*; +import org.apache.poi.hssf.record.CommonObjectDataSubRecord; +import org.apache.poi.hssf.record.ObjRecord; +import org.apache.poi.util.LittleEndian; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Iterator; + /** * An abstract shape. * @@ -25,6 +34,9 @@ package org.apache.poi.hssf.usermodel; public abstract class HSSFShape { public static final int LINEWIDTH_ONE_PT = 12700; 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 @@ -39,38 +51,98 @@ 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 - final HSSFShape parent; + private HSSFShape parent; HSSFAnchor anchor; - HSSFPatriarch _patriarch; - private int _lineStyleColor = 0x08000040; - int _fillColor = 0x08000009; - private int _lineWidth = LINEWIDTH_DEFAULT; // 12700 = 1pt - private int _lineStyle = LINESTYLE_SOLID; - private boolean _noFill = false; + private HSSFPatriarch _patriarch; + + private final EscherContainerRecord _escherContainer; + private final ObjRecord _objRecord; + private final EscherOptRecord _optRecord; + + public final static int NO_FILLHITTEST_TRUE = 0x00110000; + public final static int NO_FILLHITTEST_FALSE = 0x00010000; + + /** + * creates shapes from existing file + * @param spContainer + * @param objRecord + */ + public HSSFShape(EscherContainerRecord spContainer, ObjRecord objRecord) { + this._escherContainer = spContainer; + this._objRecord = objRecord; + this._optRecord = spContainer.getChildById(EscherOptRecord.RECORD_ID); + this.anchor = HSSFAnchor.createAnchorFromEscher(spContainer); + } /** * Create a new shape with the specified parent and anchor. */ - HSSFShape( HSSFShape parent, HSSFAnchor anchor ) - { + public HSSFShape(HSSFShape parent, HSSFAnchor anchor) { this.parent = parent; this.anchor = anchor; + this._escherContainer = createSpContainer(); + _optRecord = _escherContainer.getChildById(EscherOptRecord.RECORD_ID); + _objRecord = createObjRecord(); + + } + + protected abstract EscherContainerRecord createSpContainer(); + + protected abstract ObjRecord createObjRecord(); + + /** + * remove escher container from the patriarch.escherAggregate + * remove obj, textObj and note records if it's necessary + * in case of ShapeGroup remove all contained shapes + * @param patriarch + */ + protected abstract void afterRemove(HSSFPatriarch patriarch); + + /** + * @param shapeId - global shapeId which must be set to EscherSpRecord + */ + void setShapeId(int shapeId){ + EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID); + spRecord.setShapeId(shapeId); + CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) _objRecord.getSubRecords().get(0); + cod.setObjectId((short) (shapeId%1024)); + } + + /** + * @return global shapeId(from EscherSpRecord) + */ + int getShapeId(){ + return ((EscherSpRecord)_escherContainer.getChildById(EscherSpRecord.RECORD_ID)).getShapeId(); + } + + abstract void afterInsert(HSSFPatriarch patriarch); + + protected EscherContainerRecord getEscherContainer() { + return _escherContainer; + } + + protected ObjRecord getObjRecord() { + return _objRecord; + } + + protected EscherOptRecord getOptRecord() { + return _optRecord; } /** * Gets the parent shape. */ - public HSSFShape getParent() - { + public HSSFShape getParent() { return parent; } /** - * @return the anchor that is used by this shape. + * @return the anchor that is used by this shape. */ - public HSSFAnchor getAnchor() - { + public HSSFAnchor getAnchor() { return anchor; } @@ -78,26 +150,49 @@ public abstract class HSSFShape { * Sets a particular anchor. A top-level shape must have an anchor of * HSSFClientAnchor. A child anchor must have an anchor of HSSFChildAnchor * - * @param anchor the anchor to use. - * @throws IllegalArgumentException when the wrong anchor is used for - * this particular shape. - * + * @param anchor the anchor to use. + * @throws IllegalArgumentException when the wrong anchor is used for + * this particular shape. * @see HSSFChildAnchor * @see HSSFClientAnchor */ - public void setAnchor( HSSFAnchor anchor ) - { - if ( parent == null ) - { - if ( anchor instanceof HSSFChildAnchor ) - throw new IllegalArgumentException( "Must use client anchors for shapes directly attached to sheet." ); - } - else - { - if ( anchor instanceof HSSFClientAnchor ) - throw new IllegalArgumentException( "Must use child anchors for shapes attached to groups." ); + 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 { + if (anchor instanceof HSSFClientAnchor) + 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); + } + } + if (-1 == recordId){ + _escherContainer.addChildRecord(anchor.getEscherAnchor()); + } else { + _escherContainer.addChildBefore(anchor.getEscherAnchor(), recordId); } - this.anchor = anchor; } @@ -105,92 +200,181 @@ public abstract class HSSFShape { * The color applied to the lines of this shape. */ public int getLineStyleColor() { - return _lineStyleColor; + EscherRGBProperty rgbProperty = _optRecord.lookup(EscherProperties.LINESTYLE__COLOR); + return rgbProperty == null ? LINESTYLE__COLOR_DEFAULT : rgbProperty.getRgbColor(); } /** * The color applied to the lines of this shape. */ public void setLineStyleColor(int lineStyleColor) { - _lineStyleColor = lineStyleColor; + setPropertyValue(new EscherRGBProperty(EscherProperties.LINESTYLE__COLOR, lineStyleColor)); } /** * The color applied to the lines of this shape. */ public void setLineStyleColor(int red, int green, int blue) { - this._lineStyleColor = ((blue) << 16) | ((green) << 8) | red; + int lineStyleColor = ((blue) << 16) | ((green) << 8) | red; + setPropertyValue(new EscherRGBProperty(EscherProperties.LINESTYLE__COLOR, lineStyleColor)); } /** * The color used to fill this shape. */ - public int getFillColor() - { - return _fillColor; + public int getFillColor() { + EscherRGBProperty rgbProperty = _optRecord.lookup(EscherProperties.FILL__FILLCOLOR); + return rgbProperty == null ? FILL__FILLCOLOR_DEFAULT : rgbProperty.getRgbColor(); } /** * The color used to fill this shape. */ public void setFillColor(int fillColor) { - _fillColor = fillColor; + setPropertyValue(new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, fillColor)); } /** * The color used to fill this shape. */ - public void setFillColor( int red, int green, int blue ) - { - this._fillColor = ((blue) << 16) | ((green) << 8) | red; + public void setFillColor(int red, int green, int blue) { + int fillColor = ((blue) << 16) | ((green) << 8) | red; + setPropertyValue(new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, fillColor)); } /** - * @return returns with width of the line in EMUs. 12700 = 1 pt. + * @return returns with width of the line in EMUs. 12700 = 1 pt. */ public int getLineWidth() { - return _lineWidth; + EscherSimpleProperty property = _optRecord.lookup(EscherProperties.LINESTYLE__LINEWIDTH); + return property == null ? LINEWIDTH_DEFAULT: property.getPropertyValue(); } /** * Sets the width of the line. 12700 = 1 pt. * * @param lineWidth width in EMU's. 12700EMU's = 1 pt - * * @see HSSFShape#LINEWIDTH_ONE_PT */ public void setLineWidth(int lineWidth) { - _lineWidth = lineWidth; + setPropertyValue(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEWIDTH, lineWidth)); } /** * @return One of the constants in LINESTYLE_* */ public int getLineStyle() { - return _lineStyle; + EscherSimpleProperty property = _optRecord.lookup(EscherProperties.LINESTYLE__LINEDASHING); + if (null == property){ + return LINESTYLE_DEFAULT; + } + return property.getPropertyValue(); } /** * Sets the line style. * - * @param lineStyle One of the constants in LINESTYLE_* + * @param lineStyle One of the constants in LINESTYLE_* */ public void setLineStyle(int lineStyle) { - _lineStyle = lineStyle; + setPropertyValue(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEDASHING, lineStyle)); + if (getLineStyle() != HSSFShape.LINESTYLE_SOLID) { + setPropertyValue(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEENDCAPSTYLE, 0)); + if (getLineStyle() == HSSFShape.LINESTYLE_NONE){ + setPropertyValue(new EscherBoolProperty( EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x00080000)); + } else { + setPropertyValue( new EscherBoolProperty( EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x00080008)); + } + } } /** * @return true if this shape is not filled with a color. */ public boolean isNoFill() { - return _noFill; + EscherBoolProperty property = _optRecord.lookup(EscherProperties.FILL__NOFILLHITTEST); + return property == null ? NO_FILL_DEFAULT : property.getPropertyValue() == NO_FILLHITTEST_TRUE; } /** - * Sets whether this shape is filled or transparent. + * @param noFill sets whether this shape is filled or transparent. */ public void setNoFill(boolean noFill) { - _noFill = noFill; + setPropertyValue(new EscherBoolProperty(EscherProperties.FILL__NOFILLHITTEST, noFill ? NO_FILLHITTEST_TRUE : NO_FILLHITTEST_FALSE)); + } + + protected void setPropertyValue(EscherProperty property){ + _optRecord.setEscherProperty(property); + } + + /** + * @param value specifies whether this shape is vertically flipped. + */ + public void setFlipVertical(boolean value){ + EscherSpRecord sp = getEscherContainer().getChildById(EscherSpRecord.RECORD_ID); + if (value){ + sp.setFlags(sp.getFlags() | EscherSpRecord.FLAG_FLIPVERT); + } else { + sp.setFlags(sp.getFlags() & (Integer.MAX_VALUE - EscherSpRecord.FLAG_FLIPVERT)); + } + } + + /** + * @param value specifies whether this shape is horizontally flipped. + */ + public void setFlipHorizontal(boolean value){ + EscherSpRecord sp = getEscherContainer().getChildById(EscherSpRecord.RECORD_ID); + if (value){ + sp.setFlags(sp.getFlags() | EscherSpRecord.FLAG_FLIPHORIZ); + } else { + sp.setFlags(sp.getFlags() & (Integer.MAX_VALUE - EscherSpRecord.FLAG_FLIPHORIZ)); + } + } + + /** + * @return whether this shape is vertically flipped. + */ + public boolean isFlipVertical(){ + EscherSpRecord sp = getEscherContainer().getChildById(EscherSpRecord.RECORD_ID); + return (sp.getFlags() & EscherSpRecord.FLAG_FLIPVERT) != 0; + } + + /** + * @return whether this shape is horizontally flipped. + */ + public boolean isFlipHorizontal(){ + EscherSpRecord sp = getEscherContainer().getChildById(EscherSpRecord.RECORD_ID); + return (sp.getFlags() & EscherSpRecord.FLAG_FLIPHORIZ) != 0; + } + + /** + * @return the rotation, in degrees, that is applied to a shape. + */ + public int getRotationDegree(){ + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + EscherSimpleProperty property = getOptRecord().lookup(EscherProperties.TRANSFORM__ROTATION); + if (null == property){ + return 0; + } + try { + LittleEndian.putInt(property.getPropertyValue(), bos); + return LittleEndian.getShort(bos.toByteArray(), 2); + } catch (IOException e) { + e.printStackTrace(); + return 0; + } + } + + /** + * specifies the rotation, in degrees, that is applied to a shape. + * Positive values specify rotation in the clockwise direction. + * Negative values specify rotation in the counterclockwise direction. + * Rotation occurs around the center of the shape. + * The default value for this property is 0x00000000 + * @param value + */ + public void setRotationDegree(short value){ + setPropertyValue(new EscherSimpleProperty(EscherProperties.TRANSFORM__ROTATION , (value << 16))); } /** @@ -199,4 +383,18 @@ public abstract class HSSFShape { public int countOfAllChildren() { return 1; } + + protected abstract HSSFShape cloneShape(); + + protected void setPatriarch(HSSFPatriarch _patriarch) { + this._patriarch = _patriarch; + } + + public HSSFPatriarch getPatriarch() { + return _patriarch; + } + + protected void setParent(HSSFShape parent) { + this.parent = parent; + } } Modified: poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFShapeContainer.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFShapeContainer.java?rev=1371663&r1=1371662&r2=1371663&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFShapeContainer.java (original) +++ poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFShapeContainer.java Fri Aug 10 11:30:42 2012 @@ -24,11 +24,50 @@ import java.util.List; * * @author Glen Stampoultzis (glens at apache.org) */ -public interface HSSFShapeContainer +public interface HSSFShapeContainer extends Iterable { /** * @return Any children contained by this shape. */ - List getChildren(); + List getChildren(); + /** + * add shape to the list of child records + * @param shape + */ + public void addShape(HSSFShape shape); + + /** + * set coordinates of this group relative to the parent + */ + void setCoordinates( int x1, int y1, int x2, int y2 ); + + void clear(); + + /** + *@return The top left x coordinate of this group. + */ + public int getX1(); + + /** + *@return The top left y coordinate of this group. + */ + public int getY1(); + + /** + *@return The bottom right x coordinate of this group. + */ + public int getX2(); + + /** + * @return The bottom right y coordinate of this group. + */ + public int getY2(); + + /** + * remove first level shapes + * @param shape to be removed + * @return true if shape is removed else return false + */ + public boolean removeShape(HSSFShape shape); } Modified: poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFShapeGroup.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFShapeGroup.java?rev=1371663&r1=1371662&r2=1371663&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFShapeGroup.java (original) +++ poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFShapeGroup.java Fri Aug 10 11:30:42 2012 @@ -17,7 +17,11 @@ package org.apache.poi.hssf.usermodel; +import org.apache.poi.ddf.*; +import org.apache.poi.hssf.record.*; + import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Iterator; @@ -27,159 +31,357 @@ import java.util.Iterator; * * @author Glen Stampoultzis (glens at apache.org) */ -public class HSSFShapeGroup - extends HSSFShape - implements HSSFShapeContainer -{ - List shapes = new ArrayList(); - int x1 = 0; - int y1 = 0 ; - int x2 = 1023; - int y2 = 255; +public class HSSFShapeGroup extends HSSFShape implements HSSFShapeContainer { + private final List shapes = new ArrayList(); + private EscherSpgrRecord _spgrRecord; + + public HSSFShapeGroup(EscherContainerRecord spgrContainer, ObjRecord objRecord) { + super(spgrContainer, objRecord); + + // read internal and external coordinates from spgrContainer + EscherContainerRecord spContainer = spgrContainer.getChildContainers().get(0); + _spgrRecord = (EscherSpgrRecord) spContainer.getChild(0); + for (EscherRecord ch : spContainer.getChildRecords()) { + switch (ch.getRecordId()) { + case EscherSpgrRecord.RECORD_ID: + break; + case EscherClientAnchorRecord.RECORD_ID: + anchor = new HSSFClientAnchor((EscherClientAnchorRecord) ch); + break; + case EscherChildAnchorRecord.RECORD_ID: + anchor = new HSSFChildAnchor((EscherChildAnchorRecord) ch); + break; + } + } + } + public HSSFShapeGroup(HSSFShape parent, HSSFAnchor anchor) { + super(parent, anchor); + _spgrRecord = ((EscherContainerRecord)getEscherContainer().getChild(0)).getChildById(EscherSpgrRecord.RECORD_ID); + } + + @Override + protected EscherContainerRecord createSpContainer() { + 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(0); + spgr.setRectY1(0); + spgr.setRectX2(1023); + spgr.setRectY2(255); + sp.setRecordId(EscherSpRecord.RECORD_ID); + sp.setOptions((short) 0x0002); + if (getAnchor() instanceof HSSFClientAnchor) { + sp.setFlags(EscherSpRecord.FLAG_GROUP | EscherSpRecord.FLAG_HAVEANCHOR); + } else { + sp.setFlags(EscherSpRecord.FLAG_GROUP | EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_CHILD); + } + opt.setRecordId(EscherOptRecord.RECORD_ID); + opt.setOptions((short) 0x0023); + opt.addEscherProperty(new EscherBoolProperty(EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 0x00040004)); + opt.addEscherProperty(new EscherBoolProperty(EscherProperties.GROUPSHAPE__PRINT, 0x00080000)); + + anchor = getAnchor().getEscherAnchor(); + clientData.setRecordId(EscherClientDataRecord.RECORD_ID); + clientData.setOptions((short) 0x0000); + + spgrContainer.addChildRecord(spContainer); + spContainer.addChildRecord(spgr); + spContainer.addChildRecord(sp); + spContainer.addChildRecord(opt); + spContainer.addChildRecord(anchor); + spContainer.addChildRecord(clientData); + return spgrContainer; + } + + @Override + protected ObjRecord createObjRecord() { + ObjRecord obj = new ObjRecord(); + CommonObjectDataSubRecord cmo = new CommonObjectDataSubRecord(); + cmo.setObjectType(CommonObjectDataSubRecord.OBJECT_TYPE_GROUP); + cmo.setLocked(true); + cmo.setPrintable(true); + cmo.setAutofill(true); + cmo.setAutoline(true); + GroupMarkerSubRecord gmo = new GroupMarkerSubRecord(); + EndSubRecord end = new EndSubRecord(); + obj.addSubRecord(cmo); + obj.addSubRecord(gmo); + obj.addSubRecord(end); + return obj; + } + + @Override + protected void afterRemove(HSSFPatriarch patriarch) { + patriarch._getBoundAggregate().removeShapeToObjRecord(getEscherContainer().getChildContainers().get(0) + .getChildById(EscherClientDataRecord.RECORD_ID)); + for ( int i=0; i getChildren() - { - return shapes; + public List getChildren() { + return Collections.unmodifiableList(shapes); } /** * 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 ) - { - this.x1 = x1; - this.y1 = y1; - this.x2 = x2; - this.y2 = y2; + public void setCoordinates(int x1, int y1, int x2, int y2) { + _spgrRecord.setRectX1(x1); + _spgrRecord.setRectX2(x2); + _spgrRecord.setRectY1(y1); + _spgrRecord.setRectY2(y2); + } + + public void clear() { + ArrayList copy = new ArrayList(shapes); + for (HSSFShape shape: copy){ + removeShape(shape); + } } /** * The top left x coordinate of this group. */ - public int getX1() - { - return x1; + public int getX1() { + return _spgrRecord.getRectX1(); } /** * The top left y coordinate of this group. */ - public int getY1() - { - return y1; + public int getY1() { + return _spgrRecord.getRectY1(); } /** * The bottom right x coordinate of this group. */ - public int getX2() - { - return x2; + public int getX2() { + return _spgrRecord.getRectX2(); } /** * The bottom right y coordinate of this group. */ - public int getY2() - { - return y2; + public int getY2() { + return _spgrRecord.getRectY2(); } /** * Count of all children and their childrens children. */ - public int countOfAllChildren() - { + public int countOfAllChildren() { int count = shapes.size(); - for ( Iterator iterator = shapes.iterator(); iterator.hasNext(); ) - { + for (Iterator iterator = shapes.iterator(); iterator.hasNext(); ) { HSSFShape shape = (HSSFShape) iterator.next(); count += shape.countOfAllChildren(); } return count; } + + @Override + void afterInsert(HSSFPatriarch patriarch){ + EscherAggregate agg = patriarch._getBoundAggregate(); + EscherContainerRecord containerRecord = getEscherContainer().getChildById(EscherContainerRecord.SP_CONTAINER); + agg.associateShapeToObjRecord(containerRecord.getChildById(EscherClientDataRecord.RECORD_ID), getObjRecord()); + } + + @Override + void setShapeId(int shapeId){ + EscherContainerRecord containerRecord = getEscherContainer().getChildById(EscherContainerRecord.SP_CONTAINER); + EscherSpRecord spRecord = containerRecord.getChildById(EscherSpRecord.RECORD_ID); + spRecord.setShapeId(shapeId); + CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) getObjRecord().getSubRecords().get(0); + cod.setObjectId((short) (shapeId % 1024)); + } + + @Override + int getShapeId(){ + EscherContainerRecord containerRecord = getEscherContainer().getChildById(EscherContainerRecord.SP_CONTAINER); + return ((EscherSpRecord)containerRecord.getChildById(EscherSpRecord.RECORD_ID)).getShapeId(); + } + + @Override + protected HSSFShape cloneShape() { + throw new IllegalStateException("Use method cloneShape(HSSFPatriarch patriarch)"); + } + + protected HSSFShape cloneShape(HSSFPatriarch patriarch) { + EscherContainerRecord spgrContainer = new EscherContainerRecord(); + spgrContainer.setRecordId(EscherContainerRecord.SPGR_CONTAINER); + spgrContainer.setOptions((short) 0x000F); + EscherContainerRecord spContainer = new EscherContainerRecord(); + EscherContainerRecord cont = getEscherContainer().getChildById(EscherContainerRecord.SP_CONTAINER); + byte [] inSp = cont.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.setPatriarch(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; + } + + public boolean removeShape(HSSFShape shape) { + boolean isRemoved = getEscherContainer().removeChildRecord(shape.getEscherContainer()); + if (isRemoved){ + shape.afterRemove(this.getPatriarch()); + shapes.remove(shape); + } + return isRemoved; + } + + public Iterator iterator() { + return shapes.iterator(); + } } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org For additional commands, e-mail: commits-help@poi.apache.org