diff options
author | Evgeniy Berlog <berlog@apache.org> | 2012-06-26 11:21:13 +0000 |
---|---|---|
committer | Evgeniy Berlog <berlog@apache.org> | 2012-06-26 11:21:13 +0000 |
commit | b57fa5b4d0621d11b3f324387cebad89cd046eb8 (patch) | |
tree | 524b19e1706364f051f084db7c0158847b39eeec /src | |
parent | 7efc80c3e8945546bb7fa4fa019e9f6449e5b55b (diff) | |
download | poi-b57fa5b4d0621d11b3f324387cebad89cd046eb8.tar.gz poi-b57fa5b4d0621d11b3f324387cebad89cd046eb8.zip |
implemented creating shapes in existing files
git-svn-id: https://svn.apache.org/repos/asf/poi/branches/gsoc2012@1353960 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
15 files changed, 592 insertions, 103 deletions
diff --git a/src/java/org/apache/poi/hssf/record/EscherAggregate.java b/src/java/org/apache/poi/hssf/record/EscherAggregate.java index fb16037a37..ee75870bb8 100644 --- a/src/java/org/apache/poi/hssf/record/EscherAggregate.java +++ b/src/java/org/apache/poi/hssf/record/EscherAggregate.java @@ -323,6 +323,10 @@ public final class EscherAggregate extends AbstractEscherHolderRecord { this.drawingManager = drawingManager; } + public DrawingManager2 getDrawingManager() { + return drawingManager; + } + /** * @return Returns the current sid. */ @@ -628,7 +632,7 @@ public final class EscherAggregate extends AbstractEscherHolderRecord { /** * Associates an escher record to an OBJ record or a TXO record. */ - public Object associateShapeToObjRecord(EscherRecord r, ObjRecord objRecord) { + public Object associateShapeToObjRecord(EscherRecord r, Record objRecord) { return shapeToObj.put(r, objRecord); } @@ -1039,9 +1043,9 @@ public final class EscherAggregate extends AbstractEscherHolderRecord { EscherDgRecord dg = new EscherDgRecord(); dg.setRecordId( EscherDgRecord.RECORD_ID ); short dgId = 1; - dg.setOptions( (short) ( dgId << 4 ) ); - dg.setNumShapes( 1 ); - dg.setLastMSOSPID( 1024 ); + dg.setOptions((short) (dgId << 4)); + dg.setNumShapes(1); + dg.setLastMSOSPID(1024); drawingGroupId = dg.getDrawingGroupId(); spgrContainer.setRecordId(EscherContainerRecord.SPGR_CONTAINER); spgrContainer.setOptions((short) 0x000F); diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFComment.java b/src/java/org/apache/poi/hssf/usermodel/HSSFComment.java index 2216971e68..f949e59fb0 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFComment.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFComment.java @@ -66,7 +66,7 @@ public class HSSFComment extends HSSFTextbox implements Comment { } protected HSSFComment(NoteRecord note, TextObjectRecord txo) { - this((HSSFShape) null, (HSSFAnchor) null); + this(null, new HSSFClientAnchor()); _txo = txo; _note = note; } @@ -185,7 +185,7 @@ public class HSSFComment extends HSSFTextbox implements Comment { /** * Returns the underlying Text record */ - protected TextObjectRecord getTextObjectRecord() { + public TextObjectRecord getTextObjectRecord() { return _txo; } } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java b/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java index 71549bbf31..137086d9b8 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java @@ -21,12 +21,8 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import org.apache.poi.ddf.EscherComplexProperty; -import org.apache.poi.ddf.EscherContainerRecord; -import org.apache.poi.ddf.EscherOptRecord; -import org.apache.poi.ddf.EscherProperty; -import org.apache.poi.ddf.EscherBSERecord; -import org.apache.poi.ddf.EscherSpgrRecord; +import org.apache.poi.ddf.*; +import org.apache.poi.hssf.model.DrawingManager2; import org.apache.poi.hssf.record.EscherAggregate; import org.apache.poi.ss.usermodel.Chart; import org.apache.poi.util.StringUtil; @@ -93,6 +89,8 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing { HSSFSimpleShape shape = new HSSFSimpleShape(null, anchor); shape.anchor = anchor; addShape(shape); + //open existing file + onCreate(shape); return shape; } @@ -109,6 +107,8 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing { shape.setPictureIndex( pictureIndex ); shape.anchor = anchor; addShape(shape); + //open existing file + onCreate(shape); EscherBSERecord bse = _sheet.getWorkbook().getWorkbook().getBSERecord(pictureIndex); bse.setRef(bse.getRef() + 1); @@ -147,6 +147,7 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing { HSSFTextbox shape = new HSSFTextbox(null, anchor); shape.anchor = anchor; addShape(shape); + onCreate(shape); return shape; } @@ -200,6 +201,20 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing { _shapes.add(shape); } + private void onCreate(HSSFShape shape){ + if(_boundAggregate.getPatriarch() == null){ + EscherContainerRecord spgrContainer = + _boundAggregate.getEscherContainer().getChildContainers().get(0); + + EscherContainerRecord spContainer = shape.getEscherContainer(); + int shapeId = newShapeId(); + shape.setShapeId(shapeId); + + spgrContainer.addChildRecord(spContainer); + shape.afterInsert(this); + } + } + /** * Total count of all children and their children's children. */ @@ -222,6 +237,17 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing { _y2 = y2; } + int newShapeId() { + if (_boundAggregate.getEscherContainer() == null){ + throw new IllegalStateException("We can use this method for only existing files"); + } + DrawingManager2 dm = _boundAggregate.getDrawingManager(); + EscherDgRecord dg = + _boundAggregate.getEscherContainer().getChildById(EscherDgRecord.RECORD_ID); + short drawingGroupId = dg.getDrawingGroupId(); + return dm.allocateShapeId(drawingGroupId, dg); + } + /** * Does this HSSFPatriarch contain a chart? * (Technically a reference to a chart, since they diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFPolygon.java b/src/java/org/apache/poi/hssf/usermodel/HSSFPolygon.java index 6027fb8be7..c6dc9d7f0a 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFPolygon.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFPolygon.java @@ -17,6 +17,9 @@ package org.apache.poi.hssf.usermodel; +import org.apache.poi.ddf.EscherContainerRecord; +import org.apache.poi.hssf.record.ObjRecord; + /** * @author Glen Stampoultzis (glens at superlinksoftware.com) */ @@ -33,6 +36,16 @@ public class HSSFPolygon super( parent, anchor ); } + @Override + protected EscherContainerRecord createSpContainer() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + protected ObjRecord createObjRecord() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + public int[] getXPoints() { return xPoints; diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFShape.java b/src/java/org/apache/poi/hssf/usermodel/HSSFShape.java index 33dfd68643..975453ad01 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFShape.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFShape.java @@ -18,6 +18,7 @@ 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; /** @@ -71,6 +72,7 @@ public abstract class HSSFShape { this.anchor = anchor; this._escherContainer = new EscherContainerRecord(); _optRecord = new EscherOptRecord(); + _optRecord.setRecordId( EscherOptRecord.RECORD_ID ); _optRecord.addEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEDASHING, LINESTYLE_SOLID)); _optRecord.addEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEWIDTH, LINEWIDTH_DEFAULT)); _optRecord.addEscherProperty(new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, FILL__FILLCOLOR_DEFAULT)); @@ -78,6 +80,24 @@ public abstract class HSSFShape { _optRecord.addEscherProperty(new EscherBoolProperty(EscherProperties.FILL__NOFILLHITTEST, 0x0)); } + protected abstract EscherContainerRecord createSpContainer(); + + protected abstract ObjRecord createObjRecord(); + + 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)); + } + + int getShapeId(){ + return ((EscherSpRecord)_escherContainer.getChildById(EscherSpRecord.RECORD_ID)).getShapeId(); + } + + void afterInsert(HSSFPatriarch patriarch){ + } + public EscherContainerRecord getEscherContainer() { return _escherContainer; } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFShapeFactory.java b/src/java/org/apache/poi/hssf/usermodel/HSSFShapeFactory.java index 68f410d173..5c1be44b4d 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFShapeFactory.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFShapeFactory.java @@ -115,19 +115,37 @@ public class HSSFShapeFactory { break;
}
}
- if (null != objRecord){
- HSSFShape shape = shapeCreator.createNewShape(spRecord.getShapeType(), container, objRecord);
- out.addShape(shape);
+ CommonObjectDataSubRecord cmo = (CommonObjectDataSubRecord) objRecord.getSubRecords().get(0);
+ HSSFShape shape = null;
+ switch (cmo.getObjectType()) {
+ case CommonObjectDataSubRecord.OBJECT_TYPE_PICTURE:
+ shape = new HSSFPicture(container, objRecord);
+ break;
+ case CommonObjectDataSubRecord.OBJECT_TYPE_RECTANGLE:
+ shape = new HSSFSimpleShape(container, objRecord);
+ break;
+ case CommonObjectDataSubRecord.OBJECT_TYPE_TEXT:
+ shape = new HSSFTextbox(container, objRecord, txtRecord);
+ break;
+ default:
+ shape = new HSSFSimpleShape(container, objRecord);
}
- if (null != txtRecord){
- //TODO resolve textbox
-// TextboxShape shape = new TextboxShape(container, txtRecord);
-// out.a
+ if (null != shape){
+ out.addShape(shape);
}
-//
-// //TODO decide what shape to create based on ObjRecord / EscherSpRecord
-// HSSFShape shape = new HSSFUnknownShape(container, objRecord);
-// out.addShape(shape);
+// if (null != objRecord){
+// HSSFShape shape = shapeCreator.createNewShape(spRecord.getShapeType(), container, objRecord);
+// out.addShape(shape);
+// }
+// if (null != txtRecord){
+// //TODO resolve textbox
+//// TextboxShape shape = new TextboxShape(container, txtRecord);
+//// out.a
+// }
+////
+//// //TODO decide what shape to create based on ObjRecord / EscherSpRecord
+//// HSSFShape shape = new HSSFUnknownShape(container, objRecord);
+//// out.addShape(shape);
}
}
}
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFShapeGroup.java b/src/java/org/apache/poi/hssf/usermodel/HSSFShapeGroup.java index b3209467ae..96b39daceb 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFShapeGroup.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFShapeGroup.java @@ -74,6 +74,16 @@ public class HSSFShapeGroup _spgrRecord.setRectY2(255); } + @Override + protected EscherContainerRecord createSpContainer() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + protected ObjRecord createObjRecord() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + /** * Create another group under this group. * @param anchor the position of the new group. diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFSimpleShape.java b/src/java/org/apache/poi/hssf/usermodel/HSSFSimpleShape.java index 6e0df0fd54..e7b2c718c6 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFSimpleShape.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFSimpleShape.java @@ -19,7 +19,13 @@ 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.usermodel.drawing.HSSFShapeType; + +import java.util.HashMap; +import java.util.Map; /** * Represents a simple shape such as a line, rectangle or oval. @@ -56,17 +62,69 @@ public class HSSFSimpleShape int shapeType = OBJECT_TYPE_LINE; + private static final Map <Short, Short> objTypeToShapeType = new HashMap<Short, Short>(); + + static { + objTypeToShapeType.put(OBJECT_TYPE_RECTANGLE, HSSFShapeType.RECTANGLE.getType()); + objTypeToShapeType.put(OBJECT_TYPE_PICTURE, HSSFShapeType.PICTURE.getType()); + objTypeToShapeType.put(OBJECT_TYPE_LINE, HSSFShapeType.LINE.getType()); + } + public HSSFSimpleShape(EscherContainerRecord spContainer, ObjRecord objRecord) { super(spContainer, objRecord); - CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) objRecord.getSubRecords().get(0); - setShapeType(cod.getObjectType()); } public HSSFSimpleShape( HSSFShape parent, HSSFAnchor anchor) { super( parent, anchor ); + _escherContainer = createSpContainer(); + _objRecord = createObjRecord(); + setShapeType(OBJECT_TYPE_LINE); + } + + @Override + protected EscherContainerRecord createSpContainer() { + EscherContainerRecord spContainer = new EscherContainerRecord(); + spContainer.setRecordId( EscherContainerRecord.SP_CONTAINER ); + spContainer.setOptions( (short) 0x000F ); + + EscherSpRecord sp = new EscherSpRecord(); + sp.setRecordId( EscherSpRecord.RECORD_ID ); + sp.setFlags( EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HASSHAPETYPE ); + + EscherClientDataRecord clientData = new EscherClientDataRecord(); + clientData.setRecordId( EscherClientDataRecord.RECORD_ID ); + clientData.setOptions( (short) 0x0000 ); + + spContainer.addChildRecord(sp); + spContainer.addChildRecord(_optRecord); + spContainer.addChildRecord(anchor.getEscherAnchor()); + spContainer.addChildRecord(clientData); + return spContainer; } + @Override + protected ObjRecord createObjRecord() { + ObjRecord obj = new ObjRecord(); + CommonObjectDataSubRecord c = new CommonObjectDataSubRecord(); + c.setLocked(true); + c.setPrintable(true); + c.setAutofill(true); + c.setAutoline(true); + EndSubRecord e = new EndSubRecord(); + + obj.addSubRecord(c); + obj.addSubRecord(e); + return obj; + } + + @Override + void afterInsert(HSSFPatriarch patriarch){ + EscherAggregate agg = patriarch._getBoundAggregate(); + agg.associateShapeToObjRecord(_escherContainer.getChildById(EscherClientDataRecord.RECORD_ID), getObjRecord()); + } + + /** * Gets the shape type. * @return One of the OBJECT_TYPE_* constants. @@ -77,7 +135,10 @@ public class HSSFSimpleShape * @see #OBJECT_TYPE_PICTURE * @see #OBJECT_TYPE_COMMENT */ - public int getShapeType() { return shapeType; } + public int getShapeType() { + CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) _objRecord.getSubRecords().get(0); + return cod.getObjectType(); + } /** * Sets the shape types. @@ -90,6 +151,14 @@ public class HSSFSimpleShape * @see #OBJECT_TYPE_PICTURE * @see #OBJECT_TYPE_COMMENT */ - public void setShapeType( int shapeType ){ this.shapeType = shapeType; } - + public void setShapeType( int shapeType ){ + CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) _objRecord.getSubRecords().get(0); + cod.setObjectType((short) shapeType); + EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID); + if (null == objTypeToShapeType.get((short)shapeType)){ + System.out.println("Unknown shape type: "+shapeType); + return; + } + spRecord.setShapeType(objTypeToShapeType.get((short)shapeType)); + } } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFTextbox.java b/src/java/org/apache/poi/hssf/usermodel/HSSFTextbox.java index 2548bf5114..00dfe9590c 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFTextbox.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFTextbox.java @@ -17,6 +17,8 @@ package org.apache.poi.hssf.usermodel; +import org.apache.poi.ddf.*; +import org.apache.poi.hssf.record.*; import org.apache.poi.ss.usermodel.RichTextString; /** @@ -24,163 +26,233 @@ import org.apache.poi.ss.usermodel.RichTextString; * * @author Glen Stampoultzis (glens at apache.org) */ -public class HSSFTextbox - extends HSSFSimpleShape -{ - public final static short OBJECT_TYPE_TEXT = 6; +public class HSSFTextbox extends HSSFSimpleShape { + public final static short OBJECT_TYPE_TEXT = 6; /** * How to align text horizontally */ - public final static short HORIZONTAL_ALIGNMENT_LEFT = 1; - public final static short HORIZONTAL_ALIGNMENT_CENTERED = 2; - public final static short HORIZONTAL_ALIGNMENT_RIGHT = 3; - public final static short HORIZONTAL_ALIGNMENT_JUSTIFIED = 4; - public final static short HORIZONTAL_ALIGNMENT_DISTRIBUTED = 7; + public final static short HORIZONTAL_ALIGNMENT_LEFT = 1; + public final static short HORIZONTAL_ALIGNMENT_CENTERED = 2; + public final static short HORIZONTAL_ALIGNMENT_RIGHT = 3; + public final static short HORIZONTAL_ALIGNMENT_JUSTIFIED = 4; + public final static short HORIZONTAL_ALIGNMENT_DISTRIBUTED = 7; /** * How to align text vertically */ - public final static short VERTICAL_ALIGNMENT_TOP = 1; - public final static short VERTICAL_ALIGNMENT_CENTER = 2; - public final static short VERTICAL_ALIGNMENT_BOTTOM = 3; - public final static short VERTICAL_ALIGNMENT_JUSTIFY = 4; - public final static short VERTICAL_ALIGNMENT_DISTRIBUTED= 7; + public final static short VERTICAL_ALIGNMENT_TOP = 1; + public final static short VERTICAL_ALIGNMENT_CENTER = 2; + public final static short VERTICAL_ALIGNMENT_BOTTOM = 3; + public final static short VERTICAL_ALIGNMENT_JUSTIFY = 4; + public final static short VERTICAL_ALIGNMENT_DISTRIBUTED = 7; int marginLeft, marginRight, marginTop, marginBottom; short halign, valign; + private TextObjectRecord _textObjectRecord; + + public HSSFTextbox(EscherContainerRecord spContainer, ObjRecord objRecord, TextObjectRecord textObjectRecord) { + super(spContainer, objRecord); + this._textObjectRecord = textObjectRecord; + } + HSSFRichTextString string = new HSSFRichTextString(""); /** * Construct a new textbox with the given parent and anchor. + * * @param parent - * @param anchor One of HSSFClientAnchor or HSSFChildAnchor + * @param anchor One of HSSFClientAnchor or HSSFChildAnchor */ - public HSSFTextbox( HSSFShape parent, HSSFAnchor anchor ) - { - super( parent, anchor ); - setShapeType(OBJECT_TYPE_TEXT); + public HSSFTextbox(HSSFShape parent, HSSFAnchor anchor) { + super(parent, anchor); + _textObjectRecord = createTextObjRecord(); + setHorizontalAlignment(HORIZONTAL_ALIGNMENT_LEFT); + setVerticalAlignment(VERTICAL_ALIGNMENT_TOP); + setString(new HSSFRichTextString("")); + + } + + protected TextObjectRecord createTextObjRecord(){ + TextObjectRecord obj = new TextObjectRecord(); + obj.setTextLocked(true); + obj.setTextOrientation(TextObjectRecord.TEXT_ORIENTATION_NONE); + return obj; + } + + @Override + protected ObjRecord createObjRecord() { + ObjRecord obj = new ObjRecord(); + CommonObjectDataSubRecord c = new CommonObjectDataSubRecord(); + c.setObjectType(OBJECT_TYPE_TEXT); + c.setLocked( true ); + c.setPrintable( true ); + c.setAutofill( true ); + c.setAutoline( true ); + EndSubRecord e = new EndSubRecord(); + obj.addSubRecord( c ); + obj.addSubRecord( e ); + return obj; + } + + @Override + protected EscherContainerRecord createSpContainer() { + EscherContainerRecord spContainer = new EscherContainerRecord(); + EscherSpRecord sp = new EscherSpRecord(); + EscherOptRecord opt = new EscherOptRecord(); + EscherClientDataRecord clientData = new EscherClientDataRecord(); + EscherTextboxRecord escherTextbox = new EscherTextboxRecord(); + + spContainer.setRecordId(EscherContainerRecord.SP_CONTAINER); + spContainer.setOptions((short) 0x000F); + sp.setRecordId(EscherSpRecord.RECORD_ID); + sp.setOptions((short) ((EscherAggregate.ST_TEXTBOX << 4) | 0x2)); - halign = HORIZONTAL_ALIGNMENT_LEFT; - valign = VERTICAL_ALIGNMENT_TOP; + sp.setFlags(EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HASSHAPETYPE); + opt.setRecordId(EscherOptRecord.RECORD_ID); + opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.TEXT__TEXTID, 0)); + opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.TEXT__TEXTLEFT, getMarginLeft())); + opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.TEXT__TEXTRIGHT, getMarginRight())); + opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.TEXT__TEXTBOTTOM, getMarginBottom())); + opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.TEXT__TEXTTOP, getMarginTop())); + + opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.TEXT__WRAPTEXT, 0)); + opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.TEXT__ANCHORTEXT, 0)); + opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.GROUPSHAPE__PRINT, 0x00080000)); + + EscherRecord anchor = getAnchor().getEscherAnchor(); + clientData.setRecordId(EscherClientDataRecord.RECORD_ID); + clientData.setOptions((short) 0x0000); + escherTextbox.setRecordId(EscherTextboxRecord.RECORD_ID); + escherTextbox.setOptions((short) 0x0000); + + spContainer.addChildRecord(sp); + spContainer.addChildRecord(opt); + spContainer.addChildRecord(anchor); + spContainer.addChildRecord(clientData); + spContainer.addChildRecord(escherTextbox); + + return spContainer; + } + + @Override + void afterInsert(HSSFPatriarch patriarch){ + EscherAggregate agg = patriarch._getBoundAggregate(); + agg.associateShapeToObjRecord(_escherContainer.getChildById(EscherClientDataRecord.RECORD_ID), getObjRecord()); + agg.associateShapeToObjRecord(_escherContainer.getChildById(EscherTextboxRecord.RECORD_ID), getTextObjectRecord()); } /** - * @return the rich text string for this textbox. + * @return the rich text string for this textbox. */ - public HSSFRichTextString getString() - { - return string; + public HSSFRichTextString getString() { + return _textObjectRecord.getStr(); } /** - * @param string Sets the rich text string used by this object. + * @param string Sets the rich text string used by this object. */ - public void setString( RichTextString string ) - { - HSSFRichTextString rtr = (HSSFRichTextString)string; - + public void setString(RichTextString string) { + HSSFRichTextString rtr = (HSSFRichTextString) string; // If font is not set we must set the default one - if (rtr.numFormattingRuns() == 0) rtr.applyFont((short)0); - - this.string = rtr; + if (rtr.numFormattingRuns() == 0) rtr.applyFont((short) 0); + _textObjectRecord.setStr(rtr); } /** - * @return Returns the left margin within the textbox. + * @return Returns the left margin within the textbox. */ - public int getMarginLeft() - { - return marginLeft; + public int getMarginLeft() { + EscherSimpleProperty property = _optRecord.lookup(EscherProperties.TEXT__TEXTLEFT); + return property == null ? 0: property.getPropertyValue(); } /** * Sets the left margin within the textbox. */ - public void setMarginLeft( int marginLeft ) - { - this.marginLeft = marginLeft; + public void setMarginLeft(int marginLeft) { + setPropertyValue(new EscherSimpleProperty(EscherProperties.TEXT__TEXTLEFT, marginLeft)); } /** - * @return returns the right margin within the textbox. + * @return returns the right margin within the textbox. */ - public int getMarginRight() - { - return marginRight; + public int getMarginRight() { + EscherSimpleProperty property = _optRecord.lookup(EscherProperties.TEXT__TEXTRIGHT); + return property == null ? 0: property.getPropertyValue(); } /** * Sets the right margin within the textbox. */ - public void setMarginRight( int marginRight ) - { - this.marginRight = marginRight; + public void setMarginRight(int marginRight) { + setPropertyValue(new EscherSimpleProperty(EscherProperties.TEXT__TEXTRIGHT, marginRight)); } /** - * @return returns the top margin within the textbox. + * @return returns the top margin within the textbox. */ - public int getMarginTop() - { - return marginTop; + public int getMarginTop() { + EscherSimpleProperty property = _optRecord.lookup(EscherProperties.TEXT__TEXTTOP); + return property == null ? 0: property.getPropertyValue(); } /** * Sets the top margin within the textbox. */ - public void setMarginTop( int marginTop ) - { - this.marginTop = marginTop; + public void setMarginTop(int marginTop) { + setPropertyValue(new EscherSimpleProperty(EscherProperties.TEXT__TEXTTOP, marginTop)); } /** * Gets the bottom margin within the textbox. */ - public int getMarginBottom() - { - return marginBottom; + public int getMarginBottom() { + EscherSimpleProperty property = _optRecord.lookup(EscherProperties.TEXT__TEXTBOTTOM); + return property == null ? 0: property.getPropertyValue(); } /** * Sets the bottom margin within the textbox. */ - public void setMarginBottom( int marginBottom ) - { - this.marginBottom = marginBottom; + public void setMarginBottom(int marginBottom) { + setPropertyValue(new EscherSimpleProperty(EscherProperties.TEXT__TEXTBOTTOM, marginBottom)); } /** * Gets the horizontal alignment. */ - public short getHorizontalAlignment() - { - return halign; + public short getHorizontalAlignment() { + return (short) _textObjectRecord.getHorizontalTextAlignment(); } /** * Sets the horizontal alignment. */ - public void setHorizontalAlignment( short align ) - { - this.halign = align; + public void setHorizontalAlignment(short align) { + _textObjectRecord.setHorizontalTextAlignment(align); } /** * Gets the vertical alignment. */ - public short getVerticalAlignment() - { - return valign; + public short getVerticalAlignment() { + return (short) _textObjectRecord.getVerticalTextAlignment(); } /** * Sets the vertical alignment. */ - public void setVerticalAlignment( short align ) - { - this.valign = align; + public void setVerticalAlignment(short align) { + _textObjectRecord.setVerticalTextAlignment(align); } + + public TextObjectRecord getTextObjectRecord() { + return _textObjectRecord; + } + + @Override + public void setShapeType(int shapeType) {/**DO NOTHING**/} } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFUnknownShape.java b/src/java/org/apache/poi/hssf/usermodel/HSSFUnknownShape.java index d4cac9be9a..406dfe7219 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFUnknownShape.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFUnknownShape.java @@ -30,4 +30,14 @@ public class HSSFUnknownShape extends HSSFShape { public HSSFUnknownShape(EscherRecord spContainer, ObjRecord objRecord) {
super((EscherContainerRecord) spContainer, objRecord);
}
+
+ @Override
+ protected EscherContainerRecord createSpContainer() {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ @Override
+ protected ObjRecord createObjRecord() {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
}
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 c63a08b7e5..2e2b64eeb4 100644 --- a/src/java/org/apache/poi/hssf/usermodel/drawing/HSSFShapeType.java +++ b/src/java/org/apache/poi/hssf/usermodel/drawing/HSSFShapeType.java @@ -2,6 +2,7 @@ package org.apache.poi.hssf.usermodel.drawing; import org.apache.poi.hssf.usermodel.HSSFPicture;
import org.apache.poi.hssf.usermodel.HSSFSimpleShape;
+import org.apache.poi.hssf.usermodel.HSSFTextbox;
/**
* @author Evgeniy Berlog
@@ -11,16 +12,18 @@ 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),
+ LINE((short)0x14, HSSFSimpleShape.class, HSSFSimpleShape.OBJECT_TYPE_LINE),
+ TEXT((short)202, HSSFTextbox.class, HSSFTextbox.OBJECT_TYPE_TEXT),
ROUND_RECTANGLE((short)0x2, null, null);
private Short type;
private Class shape;
- private Short objectId;
+ private Short objectType;
- private HSSFShapeType(Short type, Class shape, Short objectId) {
+ private HSSFShapeType(Short type, Class shape, Short objectType) {
this.type = type;
this.shape = shape;
- this.objectId = objectId;
+ this.objectType = objectType;
}
public Short getType() {
@@ -30,4 +33,8 @@ public enum HSSFShapeType { public Class getShape() {
return shape;
}
+
+ public Short getObjectType() {
+ return objectType;
+ }
}
diff --git a/src/testcases/org/apache/poi/hssf/model/HSSFTestModelHelper.java b/src/testcases/org/apache/poi/hssf/model/HSSFTestModelHelper.java new file mode 100644 index 0000000000..cca8f2d635 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/model/HSSFTestModelHelper.java @@ -0,0 +1,13 @@ +package org.apache.poi.hssf.model;
+
+import org.apache.poi.hssf.usermodel.HSSFTextbox;
+
+/**
+ * @author Evgeniy Berlog
+ * @date 25.06.12
+ */
+public class HSSFTestModelHelper {
+ public static TextboxShape createTextboxShape(int shapeId, HSSFTextbox textbox){
+ return new TextboxShape(textbox, shapeId);
+ }
+}
diff --git a/src/testcases/org/apache/poi/hssf/model/TestDrawingShapes.java b/src/testcases/org/apache/poi/hssf/model/TestDrawingShapes.java index 097d5d01ee..1beeabe94b 100644 --- a/src/testcases/org/apache/poi/hssf/model/TestDrawingShapes.java +++ b/src/testcases/org/apache/poi/hssf/model/TestDrawingShapes.java @@ -251,4 +251,41 @@ public class TestDrawingShapes extends TestCase{ ((EscherContainerRecord)spgrContainer.getChild(2)).getChildById(EscherSpRecord.RECORD_ID);
assertEquals(1026, sp2.getShapeId());
}
+
+ /**
+ * Test get new id for shapes from existing file
+ * File already have for 1 shape on each sheet, because document must contain EscherDgRecord for each sheet
+ */
+ public void testAllocateNewIds(){
+ HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("empty.xls");
+ HSSFSheet sheet = wb.getSheetAt(0);
+ HSSFPatriarch patriarch = sheet.getDrawingPatriarch();
+
+ /**
+ * 2048 - main SpContainer id
+ * 2049 - existing shape id
+ */
+ assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 2050);
+ assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 2051);
+ assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 2052);
+
+ sheet = wb.getSheetAt(1);
+ patriarch = sheet.getDrawingPatriarch();
+
+ /**
+ * 3072 - main SpContainer id
+ * 3073 - existing shape id
+ */
+ assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 3074);
+ assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 3075);
+ assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 3076);
+
+
+ sheet = wb.getSheetAt(2);
+ patriarch = sheet.getDrawingPatriarch();
+
+ assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 1026);
+ assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 1027);
+ assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 1028);
+ }
}
diff --git a/src/testcases/org/apache/poi/hssf/usermodel/HSSFTestHelper.java b/src/testcases/org/apache/poi/hssf/usermodel/HSSFTestHelper.java index 2d6b14b79a..496139eaab 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/HSSFTestHelper.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/HSSFTestHelper.java @@ -43,4 +43,8 @@ public class HSSFTestHelper { public static EscherAggregate getEscherAggregate(HSSFPatriarch patriarch){ return patriarch._getBoundAggregate(); } + + public static int allocateNewShapeId(HSSFPatriarch patriarch){ + return patriarch.newShapeId(); + } } diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestText.java b/src/testcases/org/apache/poi/hssf/usermodel/TestText.java new file mode 100644 index 0000000000..213c5be674 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestText.java @@ -0,0 +1,186 @@ +package org.apache.poi.hssf.usermodel;
+
+import junit.framework.TestCase;
+import org.apache.poi.hssf.HSSFTestDataSamples;
+import org.apache.poi.hssf.model.HSSFTestModelHelper;
+import org.apache.poi.hssf.model.TextboxShape;
+import org.apache.poi.hssf.record.CommonObjectDataSubRecord;
+import org.apache.poi.hssf.record.ObjRecord;
+import org.apache.poi.hssf.record.TextObjectRecord;
+
+import java.util.Arrays;
+
+/**
+ * @author Evgeniy Berlog
+ * @date 25.06.12
+ */
+public class TestText extends TestCase {
+
+ public void testResultEqualsToAbstractShape() {
+ HSSFWorkbook wb = new HSSFWorkbook();
+ HSSFSheet sh = wb.createSheet();
+ HSSFPatriarch patriarch = sh.createDrawingPatriarch();
+ HSSFTextbox textbox = patriarch.createTextbox(new HSSFClientAnchor());
+ TextboxShape textboxShape = HSSFTestModelHelper.createTextboxShape(0, textbox);
+
+ assertEquals(textbox.getEscherContainer().getChildRecords().size(), 5);
+ assertEquals(textboxShape.getSpContainer().getChildRecords().size(), 5);
+
+ //sp record
+ byte[] expected = textboxShape.getSpContainer().getChild(0).serialize();
+ byte[] actual = textbox.getEscherContainer().getChild(0).serialize();
+
+ assertEquals(expected.length, actual.length);
+ assertTrue(Arrays.equals(expected, actual));
+
+ expected = textboxShape.getSpContainer().getChild(2).serialize();
+ actual = textbox.getEscherContainer().getChild(2).serialize();
+
+ assertEquals(expected.length, actual.length);
+ assertTrue(Arrays.equals(expected, actual));
+
+ expected = textboxShape.getSpContainer().getChild(3).serialize();
+ actual = textbox.getEscherContainer().getChild(3).serialize();
+
+ assertEquals(expected.length, actual.length);
+ assertTrue(Arrays.equals(expected, actual));
+
+ expected = textboxShape.getSpContainer().getChild(4).serialize();
+ actual = textbox.getEscherContainer().getChild(4).serialize();
+
+ assertEquals(expected.length, actual.length);
+ assertTrue(Arrays.equals(expected, actual));
+
+ ObjRecord obj = textbox.getObjRecord();
+ ((CommonObjectDataSubRecord) obj.getSubRecords().get(0)).setObjectId(-1024);
+ ObjRecord objShape = textboxShape.getObjRecord();
+
+ expected = obj.serialize();
+ actual = objShape.serialize();
+
+ assertEquals(expected.length, actual.length);
+ assertTrue(Arrays.equals(expected, actual));
+
+ TextObjectRecord tor = textbox.getTextObjectRecord();
+ TextObjectRecord torShape = textboxShape.getTextObjectRecord();
+
+ expected = tor.serialize();
+ actual = torShape.serialize();
+
+ assertEquals(expected.length, actual.length);
+ assertTrue(Arrays.equals(expected, actual));
+ }
+
+ public void testAddTextToExistingFile() {
+ HSSFWorkbook wb = new HSSFWorkbook();
+ HSSFSheet sh = wb.createSheet();
+ HSSFPatriarch patriarch = sh.createDrawingPatriarch();
+ HSSFTextbox textbox = patriarch.createTextbox(new HSSFClientAnchor());
+ textbox.setString(new HSSFRichTextString("just for test"));
+ HSSFTextbox textbox2 = patriarch.createTextbox(new HSSFClientAnchor());
+ textbox2.setString(new HSSFRichTextString("just for test2"));
+
+ assertEquals(patriarch.getChildren().size(), 2);
+
+ wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
+ sh = wb.getSheetAt(0);
+ patriarch = sh.getDrawingPatriarch();
+
+ assertEquals(patriarch.getChildren().size(), 2);
+ HSSFTextbox text3 = patriarch.createTextbox(new HSSFClientAnchor());
+ text3.setString(new HSSFRichTextString("text3"));
+ assertEquals(patriarch.getChildren().size(), 3);
+
+ wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
+ sh = wb.getSheetAt(0);
+ patriarch = sh.getDrawingPatriarch();
+
+ assertEquals(patriarch.getChildren().size(), 3);
+ assertEquals(((HSSFTextbox) patriarch.getChildren().get(0)).getString().getString(), "just for test");
+ assertEquals(((HSSFTextbox) patriarch.getChildren().get(1)).getString().getString(), "just for test2");
+ assertEquals(((HSSFTextbox) patriarch.getChildren().get(2)).getString().getString(), "text3");
+ }
+
+ public void testSetGetProperties() {
+ HSSFWorkbook wb = new HSSFWorkbook();
+ HSSFSheet sh = wb.createSheet();
+ HSSFPatriarch patriarch = sh.createDrawingPatriarch();
+ HSSFTextbox textbox = patriarch.createTextbox(new HSSFClientAnchor());
+ textbox.setString(new HSSFRichTextString("test"));
+ assertEquals(textbox.getString().getString(), "test");
+
+ textbox.setHorizontalAlignment((short) 5);
+ assertEquals(textbox.getHorizontalAlignment(), 5);
+
+ textbox.setVerticalAlignment((short) 6);
+ assertEquals(textbox.getVerticalAlignment(), (short) 6);
+
+ textbox.setMarginBottom(7);
+ assertEquals(textbox.getMarginBottom(), 7);
+
+ textbox.setMarginLeft(8);
+ assertEquals(textbox.getMarginLeft(), 8);
+
+ textbox.setMarginRight(9);
+ assertEquals(textbox.getMarginRight(), 9);
+
+ textbox.setMarginTop(10);
+ assertEquals(textbox.getMarginTop(), 10);
+
+ wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
+ sh = wb.getSheetAt(0);
+ patriarch = sh.getDrawingPatriarch();
+ textbox = (HSSFTextbox) patriarch.getChildren().get(0);
+ assertEquals(textbox.getString().getString(), "test");
+ assertEquals(textbox.getHorizontalAlignment(), 5);
+ assertEquals(textbox.getVerticalAlignment(), (short) 6);
+ assertEquals(textbox.getMarginBottom(), 7);
+ assertEquals(textbox.getMarginLeft(), 8);
+ assertEquals(textbox.getMarginRight(), 9);
+ assertEquals(textbox.getMarginTop(), 10);
+
+ textbox.setString(new HSSFRichTextString("test1"));
+ textbox.setHorizontalAlignment(HSSFTextbox.HORIZONTAL_ALIGNMENT_CENTERED);
+ textbox.setVerticalAlignment(HSSFTextbox.VERTICAL_ALIGNMENT_TOP);
+ textbox.setMarginBottom(71);
+ textbox.setMarginLeft(81);
+ textbox.setMarginRight(91);
+ textbox.setMarginTop(101);
+
+ assertEquals(textbox.getString().getString(), "test1");
+ assertEquals(textbox.getHorizontalAlignment(), HSSFTextbox.HORIZONTAL_ALIGNMENT_CENTERED);
+ assertEquals(textbox.getVerticalAlignment(), HSSFTextbox.VERTICAL_ALIGNMENT_TOP);
+ assertEquals(textbox.getMarginBottom(), 71);
+ assertEquals(textbox.getMarginLeft(), 81);
+ assertEquals(textbox.getMarginRight(), 91);
+ assertEquals(textbox.getMarginTop(), 101);
+
+ wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
+ sh = wb.getSheetAt(0);
+ patriarch = sh.getDrawingPatriarch();
+ textbox = (HSSFTextbox) patriarch.getChildren().get(0);
+
+ assertEquals(textbox.getString().getString(), "test1");
+ assertEquals(textbox.getHorizontalAlignment(), HSSFTextbox.HORIZONTAL_ALIGNMENT_CENTERED);
+ assertEquals(textbox.getVerticalAlignment(), HSSFTextbox.VERTICAL_ALIGNMENT_TOP);
+ assertEquals(textbox.getMarginBottom(), 71);
+ assertEquals(textbox.getMarginLeft(), 81);
+ assertEquals(textbox.getMarginRight(), 91);
+ assertEquals(textbox.getMarginTop(), 101);
+ }
+
+ public void testExistingFileWithText(){
+ HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls");
+ HSSFSheet sheet = wb.getSheet("text");
+ HSSFPatriarch drawing = sheet.getDrawingPatriarch();
+ assertEquals(1, drawing.getChildren().size());
+ HSSFTextbox textbox = (HSSFTextbox) drawing.getChildren().get(0);
+ assertEquals(textbox.getHorizontalAlignment(), HSSFTextbox.HORIZONTAL_ALIGNMENT_LEFT);
+ assertEquals(textbox.getVerticalAlignment(), HSSFTextbox.VERTICAL_ALIGNMENT_TOP);
+ assertEquals(textbox.getMarginTop(), 0);
+ assertEquals(textbox.getMarginBottom(), 3600000);
+ assertEquals(textbox.getMarginLeft(), 3600000);
+ assertEquals(textbox.getMarginRight(), 0);
+ assertEquals(textbox.getString().getString(), "teeeeesssstttt");
+ }
+}
|