implemented creating shapes in existing files

git-svn-id: https://svn.apache.org/repos/asf/poi/branches/gsoc2012@1353960 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Evgeniy Berlog 2012-06-26 11:21:13 +00:00
parent f6a678adc9
commit b1f3eb6ca0
17 changed files with 592 additions and 103 deletions

View File

@ -323,6 +323,10 @@ public final class EscherAggregate extends AbstractEscherHolderRecord {
this.drawingManager = drawingManager; this.drawingManager = drawingManager;
} }
public DrawingManager2 getDrawingManager() {
return drawingManager;
}
/** /**
* @return Returns the current sid. * @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. * 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); return shapeToObj.put(r, objRecord);
} }
@ -1039,9 +1043,9 @@ public final class EscherAggregate extends AbstractEscherHolderRecord {
EscherDgRecord dg = new EscherDgRecord(); EscherDgRecord dg = new EscherDgRecord();
dg.setRecordId( EscherDgRecord.RECORD_ID ); dg.setRecordId( EscherDgRecord.RECORD_ID );
short dgId = 1; short dgId = 1;
dg.setOptions( (short) ( dgId << 4 ) ); dg.setOptions((short) (dgId << 4));
dg.setNumShapes( 1 ); dg.setNumShapes(1);
dg.setLastMSOSPID( 1024 ); dg.setLastMSOSPID(1024);
drawingGroupId = dg.getDrawingGroupId(); drawingGroupId = dg.getDrawingGroupId();
spgrContainer.setRecordId(EscherContainerRecord.SPGR_CONTAINER); spgrContainer.setRecordId(EscherContainerRecord.SPGR_CONTAINER);
spgrContainer.setOptions((short) 0x000F); spgrContainer.setOptions((short) 0x000F);

View File

@ -66,7 +66,7 @@ public class HSSFComment extends HSSFTextbox implements Comment {
} }
protected HSSFComment(NoteRecord note, TextObjectRecord txo) { protected HSSFComment(NoteRecord note, TextObjectRecord txo) {
this((HSSFShape) null, (HSSFAnchor) null); this(null, new HSSFClientAnchor());
_txo = txo; _txo = txo;
_note = note; _note = note;
} }
@ -185,7 +185,7 @@ public class HSSFComment extends HSSFTextbox implements Comment {
/** /**
* Returns the underlying Text record * Returns the underlying Text record
*/ */
protected TextObjectRecord getTextObjectRecord() { public TextObjectRecord getTextObjectRecord() {
return _txo; return _txo;
} }
} }

View File

@ -21,12 +21,8 @@ import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import org.apache.poi.ddf.EscherComplexProperty; import org.apache.poi.ddf.*;
import org.apache.poi.ddf.EscherContainerRecord; import org.apache.poi.hssf.model.DrawingManager2;
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.hssf.record.EscherAggregate; import org.apache.poi.hssf.record.EscherAggregate;
import org.apache.poi.ss.usermodel.Chart; import org.apache.poi.ss.usermodel.Chart;
import org.apache.poi.util.StringUtil; import org.apache.poi.util.StringUtil;
@ -93,6 +89,8 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
HSSFSimpleShape shape = new HSSFSimpleShape(null, anchor); HSSFSimpleShape shape = new HSSFSimpleShape(null, anchor);
shape.anchor = anchor; shape.anchor = anchor;
addShape(shape); addShape(shape);
//open existing file
onCreate(shape);
return shape; return shape;
} }
@ -109,6 +107,8 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
shape.setPictureIndex( pictureIndex ); shape.setPictureIndex( pictureIndex );
shape.anchor = anchor; shape.anchor = anchor;
addShape(shape); addShape(shape);
//open existing file
onCreate(shape);
EscherBSERecord bse = _sheet.getWorkbook().getWorkbook().getBSERecord(pictureIndex); EscherBSERecord bse = _sheet.getWorkbook().getWorkbook().getBSERecord(pictureIndex);
bse.setRef(bse.getRef() + 1); bse.setRef(bse.getRef() + 1);
@ -147,6 +147,7 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
HSSFTextbox shape = new HSSFTextbox(null, anchor); HSSFTextbox shape = new HSSFTextbox(null, anchor);
shape.anchor = anchor; shape.anchor = anchor;
addShape(shape); addShape(shape);
onCreate(shape);
return shape; return shape;
} }
@ -200,6 +201,20 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
_shapes.add(shape); _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. * Total count of all children and their children's children.
*/ */
@ -222,6 +237,17 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
_y2 = y2; _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? * Does this HSSFPatriarch contain a chart?
* (Technically a reference to a chart, since they * (Technically a reference to a chart, since they

View File

@ -17,6 +17,9 @@
package org.apache.poi.hssf.usermodel; 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) * @author Glen Stampoultzis (glens at superlinksoftware.com)
*/ */
@ -33,6 +36,16 @@ public class HSSFPolygon
super( parent, anchor ); 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() public int[] getXPoints()
{ {
return xPoints; return xPoints;

View File

@ -18,6 +18,7 @@
package org.apache.poi.hssf.usermodel; package org.apache.poi.hssf.usermodel;
import org.apache.poi.ddf.*; import org.apache.poi.ddf.*;
import org.apache.poi.hssf.record.CommonObjectDataSubRecord;
import org.apache.poi.hssf.record.ObjRecord; import org.apache.poi.hssf.record.ObjRecord;
/** /**
@ -71,6 +72,7 @@ public abstract class HSSFShape {
this.anchor = anchor; this.anchor = anchor;
this._escherContainer = new EscherContainerRecord(); this._escherContainer = new EscherContainerRecord();
_optRecord = new EscherOptRecord(); _optRecord = new EscherOptRecord();
_optRecord.setRecordId( EscherOptRecord.RECORD_ID );
_optRecord.addEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEDASHING, LINESTYLE_SOLID)); _optRecord.addEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEDASHING, LINESTYLE_SOLID));
_optRecord.addEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEWIDTH, LINEWIDTH_DEFAULT)); _optRecord.addEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEWIDTH, LINEWIDTH_DEFAULT));
_optRecord.addEscherProperty(new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, FILL__FILLCOLOR_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)); _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() { public EscherContainerRecord getEscherContainer() {
return _escherContainer; return _escherContainer;
} }

View File

@ -115,19 +115,37 @@ public class HSSFShapeFactory {
break; break;
} }
} }
if (null != objRecord){ CommonObjectDataSubRecord cmo = (CommonObjectDataSubRecord) objRecord.getSubRecords().get(0);
HSSFShape shape = shapeCreator.createNewShape(spRecord.getShapeType(), container, objRecord); 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 != shape){
out.addShape(shape); out.addShape(shape);
} }
if (null != txtRecord){ // if (null != objRecord){
//TODO resolve textbox // HSSFShape shape = shapeCreator.createNewShape(spRecord.getShapeType(), container, objRecord);
// TextboxShape shape = new TextboxShape(container, txtRecord); // out.addShape(shape);
// out.a // }
} // if (null != txtRecord){
// // //TODO resolve textbox
// //TODO decide what shape to create based on ObjRecord / EscherSpRecord //// TextboxShape shape = new TextboxShape(container, txtRecord);
// HSSFShape shape = new HSSFUnknownShape(container, objRecord); //// out.a
// out.addShape(shape); // }
////
//// //TODO decide what shape to create based on ObjRecord / EscherSpRecord
//// HSSFShape shape = new HSSFUnknownShape(container, objRecord);
//// out.addShape(shape);
} }
} }
} }

View File

@ -74,6 +74,16 @@ public class HSSFShapeGroup
_spgrRecord.setRectY2(255); _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. * Create another group under this group.
* @param anchor the position of the new group. * @param anchor the position of the new group.

View File

@ -19,7 +19,13 @@ package org.apache.poi.hssf.usermodel;
import org.apache.poi.ddf.*; import org.apache.poi.ddf.*;
import org.apache.poi.hssf.record.CommonObjectDataSubRecord; import org.apache.poi.hssf.record.CommonObjectDataSubRecord;
import org.apache.poi.hssf.record.EndSubRecord;
import org.apache.poi.hssf.record.EscherAggregate;
import org.apache.poi.hssf.record.ObjRecord; import org.apache.poi.hssf.record.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. * Represents a simple shape such as a line, rectangle or oval.
@ -56,17 +62,69 @@ public class HSSFSimpleShape
int shapeType = OBJECT_TYPE_LINE; 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) { public HSSFSimpleShape(EscherContainerRecord spContainer, ObjRecord objRecord) {
super(spContainer, objRecord); super(spContainer, objRecord);
CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) objRecord.getSubRecords().get(0);
setShapeType(cod.getObjectType());
} }
public HSSFSimpleShape( HSSFShape parent, HSSFAnchor anchor) public HSSFSimpleShape( HSSFShape parent, HSSFAnchor anchor)
{ {
super( parent, 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. * Gets the shape type.
* @return One of the OBJECT_TYPE_* constants. * @return One of the OBJECT_TYPE_* constants.
@ -77,7 +135,10 @@ public class HSSFSimpleShape
* @see #OBJECT_TYPE_PICTURE * @see #OBJECT_TYPE_PICTURE
* @see #OBJECT_TYPE_COMMENT * @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. * Sets the shape types.
@ -90,6 +151,14 @@ public class HSSFSimpleShape
* @see #OBJECT_TYPE_PICTURE * @see #OBJECT_TYPE_PICTURE
* @see #OBJECT_TYPE_COMMENT * @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));
}
} }

View File

@ -17,6 +17,8 @@
package org.apache.poi.hssf.usermodel; package org.apache.poi.hssf.usermodel;
import org.apache.poi.ddf.*;
import org.apache.poi.hssf.record.*;
import org.apache.poi.ss.usermodel.RichTextString; 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) * @author Glen Stampoultzis (glens at apache.org)
*/ */
public class HSSFTextbox public class HSSFTextbox extends HSSFSimpleShape {
extends HSSFSimpleShape public final static short OBJECT_TYPE_TEXT = 6;
{
public final static short OBJECT_TYPE_TEXT = 6;
/** /**
* How to align text horizontally * How to align text horizontally
*/ */
public final static short HORIZONTAL_ALIGNMENT_LEFT = 1; public final static short HORIZONTAL_ALIGNMENT_LEFT = 1;
public final static short HORIZONTAL_ALIGNMENT_CENTERED = 2; public final static short HORIZONTAL_ALIGNMENT_CENTERED = 2;
public final static short HORIZONTAL_ALIGNMENT_RIGHT = 3; public final static short HORIZONTAL_ALIGNMENT_RIGHT = 3;
public final static short HORIZONTAL_ALIGNMENT_JUSTIFIED = 4; public final static short HORIZONTAL_ALIGNMENT_JUSTIFIED = 4;
public final static short HORIZONTAL_ALIGNMENT_DISTRIBUTED = 7; public final static short HORIZONTAL_ALIGNMENT_DISTRIBUTED = 7;
/** /**
* How to align text vertically * How to align text vertically
*/ */
public final static short VERTICAL_ALIGNMENT_TOP = 1; public final static short VERTICAL_ALIGNMENT_TOP = 1;
public final static short VERTICAL_ALIGNMENT_CENTER = 2; public final static short VERTICAL_ALIGNMENT_CENTER = 2;
public final static short VERTICAL_ALIGNMENT_BOTTOM = 3; public final static short VERTICAL_ALIGNMENT_BOTTOM = 3;
public final static short VERTICAL_ALIGNMENT_JUSTIFY = 4; public final static short VERTICAL_ALIGNMENT_JUSTIFY = 4;
public final static short VERTICAL_ALIGNMENT_DISTRIBUTED= 7; public final static short VERTICAL_ALIGNMENT_DISTRIBUTED = 7;
int marginLeft, marginRight, marginTop, marginBottom; int marginLeft, marginRight, marginTop, marginBottom;
short halign, valign; short halign, valign;
private TextObjectRecord _textObjectRecord;
public HSSFTextbox(EscherContainerRecord spContainer, ObjRecord objRecord, TextObjectRecord textObjectRecord) {
super(spContainer, objRecord);
this._textObjectRecord = textObjectRecord;
}
HSSFRichTextString string = new HSSFRichTextString(""); HSSFRichTextString string = new HSSFRichTextString("");
/** /**
* Construct a new textbox with the given parent and anchor. * Construct a new textbox with the given parent and anchor.
*
* @param parent * @param parent
* @param anchor One of HSSFClientAnchor or HSSFChildAnchor * @param anchor One of HSSFClientAnchor or HSSFChildAnchor
*/ */
public HSSFTextbox( HSSFShape parent, HSSFAnchor anchor ) public HSSFTextbox(HSSFShape parent, HSSFAnchor anchor) {
{ super(parent, anchor);
super( parent, anchor ); _textObjectRecord = createTextObjRecord();
setShapeType(OBJECT_TYPE_TEXT); setHorizontalAlignment(HORIZONTAL_ALIGNMENT_LEFT);
setVerticalAlignment(VERTICAL_ALIGNMENT_TOP);
setString(new HSSFRichTextString(""));
halign = HORIZONTAL_ALIGNMENT_LEFT; }
valign = VERTICAL_ALIGNMENT_TOP;
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));
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() public HSSFRichTextString getString() {
{ return _textObjectRecord.getStr();
return string;
} }
/** /**
* @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 ) public void setString(RichTextString string) {
{ HSSFRichTextString rtr = (HSSFRichTextString) string;
HSSFRichTextString rtr = (HSSFRichTextString)string;
// If font is not set we must set the default one // If font is not set we must set the default one
if (rtr.numFormattingRuns() == 0) rtr.applyFont((short)0); if (rtr.numFormattingRuns() == 0) rtr.applyFont((short) 0);
_textObjectRecord.setStr(rtr);
this.string = rtr;
} }
/** /**
* @return Returns the left margin within the textbox. * @return Returns the left margin within the textbox.
*/ */
public int getMarginLeft() public int getMarginLeft() {
{ EscherSimpleProperty property = _optRecord.lookup(EscherProperties.TEXT__TEXTLEFT);
return marginLeft; return property == null ? 0: property.getPropertyValue();
} }
/** /**
* Sets the left margin within the textbox. * Sets the left margin within the textbox.
*/ */
public void setMarginLeft( int marginLeft ) public void setMarginLeft(int marginLeft) {
{ setPropertyValue(new EscherSimpleProperty(EscherProperties.TEXT__TEXTLEFT, marginLeft));
this.marginLeft = marginLeft;
} }
/** /**
* @return returns the right margin within the textbox. * @return returns the right margin within the textbox.
*/ */
public int getMarginRight() public int getMarginRight() {
{ EscherSimpleProperty property = _optRecord.lookup(EscherProperties.TEXT__TEXTRIGHT);
return marginRight; return property == null ? 0: property.getPropertyValue();
} }
/** /**
* Sets the right margin within the textbox. * Sets the right margin within the textbox.
*/ */
public void setMarginRight( int marginRight ) public void setMarginRight(int marginRight) {
{ setPropertyValue(new EscherSimpleProperty(EscherProperties.TEXT__TEXTRIGHT, marginRight));
this.marginRight = marginRight;
} }
/** /**
* @return returns the top margin within the textbox. * @return returns the top margin within the textbox.
*/ */
public int getMarginTop() public int getMarginTop() {
{ EscherSimpleProperty property = _optRecord.lookup(EscherProperties.TEXT__TEXTTOP);
return marginTop; return property == null ? 0: property.getPropertyValue();
} }
/** /**
* Sets the top margin within the textbox. * Sets the top margin within the textbox.
*/ */
public void setMarginTop( int marginTop ) public void setMarginTop(int marginTop) {
{ setPropertyValue(new EscherSimpleProperty(EscherProperties.TEXT__TEXTTOP, marginTop));
this.marginTop = marginTop;
} }
/** /**
* Gets the bottom margin within the textbox. * Gets the bottom margin within the textbox.
*/ */
public int getMarginBottom() public int getMarginBottom() {
{ EscherSimpleProperty property = _optRecord.lookup(EscherProperties.TEXT__TEXTBOTTOM);
return marginBottom; return property == null ? 0: property.getPropertyValue();
} }
/** /**
* Sets the bottom margin within the textbox. * Sets the bottom margin within the textbox.
*/ */
public void setMarginBottom( int marginBottom ) public void setMarginBottom(int marginBottom) {
{ setPropertyValue(new EscherSimpleProperty(EscherProperties.TEXT__TEXTBOTTOM, marginBottom));
this.marginBottom = marginBottom;
} }
/** /**
* Gets the horizontal alignment. * Gets the horizontal alignment.
*/ */
public short getHorizontalAlignment() public short getHorizontalAlignment() {
{ return (short) _textObjectRecord.getHorizontalTextAlignment();
return halign;
} }
/** /**
* Sets the horizontal alignment. * Sets the horizontal alignment.
*/ */
public void setHorizontalAlignment( short align ) public void setHorizontalAlignment(short align) {
{ _textObjectRecord.setHorizontalTextAlignment(align);
this.halign = align;
} }
/** /**
* Gets the vertical alignment. * Gets the vertical alignment.
*/ */
public short getVerticalAlignment() public short getVerticalAlignment() {
{ return (short) _textObjectRecord.getVerticalTextAlignment();
return valign;
} }
/** /**
* Sets the vertical alignment. * Sets the vertical alignment.
*/ */
public void setVerticalAlignment( short align ) public void setVerticalAlignment(short align) {
{ _textObjectRecord.setVerticalTextAlignment(align);
this.valign = align;
} }
public TextObjectRecord getTextObjectRecord() {
return _textObjectRecord;
}
@Override
public void setShapeType(int shapeType) {/**DO NOTHING**/}
} }

View File

@ -30,4 +30,14 @@ public class HSSFUnknownShape extends HSSFShape {
public HSSFUnknownShape(EscherRecord spContainer, ObjRecord objRecord) { public HSSFUnknownShape(EscherRecord spContainer, ObjRecord objRecord) {
super((EscherContainerRecord) spContainer, 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.
}
} }

View File

@ -2,6 +2,7 @@ package org.apache.poi.hssf.usermodel.drawing;
import org.apache.poi.hssf.usermodel.HSSFPicture; import org.apache.poi.hssf.usermodel.HSSFPicture;
import org.apache.poi.hssf.usermodel.HSSFSimpleShape; import org.apache.poi.hssf.usermodel.HSSFSimpleShape;
import org.apache.poi.hssf.usermodel.HSSFTextbox;
/** /**
* @author Evgeniy Berlog * @author Evgeniy Berlog
@ -11,16 +12,18 @@ public enum HSSFShapeType {
NOT_PRIMITIVE((short)0x0, null, (short)0), NOT_PRIMITIVE((short)0x0, null, (short)0),
RECTANGLE((short)0x1, HSSFSimpleShape.class, HSSFSimpleShape.OBJECT_TYPE_RECTANGLE), RECTANGLE((short)0x1, HSSFSimpleShape.class, HSSFSimpleShape.OBJECT_TYPE_RECTANGLE),
PICTURE((short)0x004B, HSSFPicture.class, HSSFSimpleShape.OBJECT_TYPE_PICTURE), 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); ROUND_RECTANGLE((short)0x2, null, null);
private Short type; private Short type;
private Class shape; 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.type = type;
this.shape = shape; this.shape = shape;
this.objectId = objectId; this.objectType = objectType;
} }
public Short getType() { public Short getType() {
@ -30,4 +33,8 @@ public enum HSSFShapeType {
public Class getShape() { public Class getShape() {
return shape; return shape;
} }
public Short getObjectType() {
return objectType;
}
} }

View File

@ -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);
}
}

View File

@ -251,4 +251,41 @@ public class TestDrawingShapes extends TestCase{
((EscherContainerRecord)spgrContainer.getChild(2)).getChildById(EscherSpRecord.RECORD_ID); ((EscherContainerRecord)spgrContainer.getChild(2)).getChildById(EscherSpRecord.RECORD_ID);
assertEquals(1026, sp2.getShapeId()); 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);
}
} }

View File

@ -43,4 +43,8 @@ public class HSSFTestHelper {
public static EscherAggregate getEscherAggregate(HSSFPatriarch patriarch){ public static EscherAggregate getEscherAggregate(HSSFPatriarch patriarch){
return patriarch._getBoundAggregate(); return patriarch._getBoundAggregate();
} }
public static int allocateNewShapeId(HSSFPatriarch patriarch){
return patriarch.newShapeId();
}
} }

View File

@ -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");
}
}

Binary file not shown.

Binary file not shown.