// EscherAggregate is used only as a container for SODRAWING and OBJ record combinations
// So, if the container is empty, there is no reason to clone this record
// See https://issues.apache.org/bugzilla/show_bug.cgi?id=49529
- if (0 == rb.getRecordSize()){
+// if (0 == rb.getRecordSize()){
continue;
- }
+// }
}
Record rec = (Record) ((Record) rb).clone();
clonedRecords.add(rec);
import java.util.*;
import org.apache.poi.ddf.DefaultEscherRecordFactory;
-import org.apache.poi.ddf.EscherBoolProperty;
-import org.apache.poi.ddf.EscherChildAnchorRecord;
-import org.apache.poi.ddf.EscherClientAnchorRecord;
import org.apache.poi.ddf.EscherClientDataRecord;
import org.apache.poi.ddf.EscherContainerRecord;
import org.apache.poi.ddf.EscherDgRecord;
-import org.apache.poi.ddf.EscherDggRecord;
-import org.apache.poi.ddf.EscherOptRecord;
-import org.apache.poi.ddf.EscherProperties;
import org.apache.poi.ddf.EscherRecord;
import org.apache.poi.ddf.EscherRecordFactory;
import org.apache.poi.ddf.EscherSerializationListener;
-import org.apache.poi.ddf.EscherSimpleProperty;
import org.apache.poi.ddf.EscherSpRecord;
import org.apache.poi.ddf.EscherSpgrRecord;
import org.apache.poi.ddf.EscherTextboxRecord;
-import org.apache.poi.hssf.model.AbstractShape;
-import org.apache.poi.hssf.model.CommentShape;
-import org.apache.poi.hssf.model.ConvertAnchor;
import org.apache.poi.hssf.model.DrawingManager2;
-import org.apache.poi.hssf.model.TextboxShape;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
* Maps shape container objects to their {@link TextObjectRecord} or {@link ObjRecord}
*/
private final Map<EscherRecord, Record> shapeToObj = new HashMap<EscherRecord, Record>();
- private DrawingManager2 drawingManager;
- private short drawingGroupId;
/**
* list of "tail" records that need to be serialized after all drawing group records
}
public EscherAggregate(DrawingManager2 drawingManager) {
- this.drawingManager = drawingManager;
- }
-
- public DrawingManager2 getDrawingManager() {
- return drawingManager;
}
/**
// replace drawing block with the created EscherAggregate
records.subList(locFirstDrawingRecord, locLastDrawingRecord).clear();
records.add(locFirstDrawingRecord, agg);
-
-
return agg;
}
* @return The number of bytes serialized.
*/
public int serialize(int offset, byte[] data) {
- convertUserModelToRecords();
-
// Determine buffer size
List records = getEscherRecords();
int size = getEscherRecordSize(records);
byte[] buffer = new byte[size];
-
// Serialize escher records into one big data structure and keep note of ending offsets.
final List spEndingOffsets = new ArrayList();
final List shapes = new ArrayList();
}
public int getRecordSize() {
- // TODO - convert this to RecordAggregate
- convertUserModelToRecords();
// To determine size of aggregate record we have to know size of each DrawingRecord because if DrawingRecord
// is split into several continue records we have to add header size to total EscherAggregate size
int continueRecordsHeadersSize = 0;
shapeToObj.remove(rec);
}
- public HSSFPatriarch getPatriarch() {
- return patriarch;
- }
-
- public void setPatriarch(HSSFPatriarch patriarch) {
- this.patriarch = patriarch;
- }
-
- /**
- * Converts the Records into UserModel
- * objects on the bound HSSFPatriarch
- */
- public void convertRecordsToUserModel() {
- if (patriarch == null) {
- throw new IllegalStateException("Must call setPatriarch() first");
- }
-
- // The top level container ought to have
- // the DgRecord and the container of one container
- // per shape group (patriach overall first)
- EscherContainerRecord topContainer = getEscherContainer();
- if (topContainer == null) {
- return;
- }
- topContainer = topContainer.getChildContainers().get(0);
-
- List tcc = topContainer.getChildContainers();
- if (tcc.size() == 0) {
- throw new IllegalStateException("No child escher containers at the point that should hold the patriach data, and one container per top level shape!");
- }
-
- // First up, get the patriach position
- // This is in the first EscherSpgrRecord, in
- // the first container, with a EscherSRecord too
- EscherContainerRecord patriachContainer =
- (EscherContainerRecord) tcc.get(0);
- EscherSpgrRecord spgr = null;
- for (Iterator<EscherRecord> it = patriachContainer.getChildIterator(); it.hasNext(); ) {
- EscherRecord r = it.next();
- if (r instanceof EscherSpgrRecord) {
- spgr = (EscherSpgrRecord) r;
- break;
- }
- }
- if (spgr != null) {
- patriarch.setCoordinates(
- spgr.getRectX1(), spgr.getRectY1(),
- spgr.getRectX2(), spgr.getRectY2()
- );
- }
-
- convertRecordsToUserModelRecursive(tcc, patriarch, null);
-
- // Now, clear any trace of what records make up
- // the patriarch
- // Otherwise, everything will go horribly wrong
- // when we try to write out again....
-// clearEscherRecords();
- drawingManager.getDgg().setFileIdClusters(new EscherDggRecord.FileIdCluster[0]);
-
- // TODO: Support converting our records
- // back into shapes
- // log.log(POILogger.WARN, "Not processing objects into Patriarch!");
- }
-
- private static void convertRecordsToUserModelRecursive(List tcc, HSSFShapeContainer container, HSSFShape parent) {
- // Now process the containers for each group
- // and objects
- for (int i = 1; i < tcc.size(); i++) {
- EscherContainerRecord shapeContainer = (EscherContainerRecord) tcc.get(i);
-
- // Could be a group, or a base object
- if (shapeContainer.getRecordId() == EscherContainerRecord.SPGR_CONTAINER) {
- // Group
- final int shapeChildren = shapeContainer.getChildRecords().size();
- if (shapeChildren > 0) {
- HSSFShapeGroup group = new HSSFShapeGroup(parent, new HSSFClientAnchor());
- addToParentOrContainer(group, container, parent);
-
- EscherContainerRecord groupContainer = (EscherContainerRecord) shapeContainer.getChild(0);
- convertRecordsToUserModel(groupContainer, group);
-
- if (shapeChildren > 1) {
- convertRecordsToUserModelRecursive(shapeContainer.getChildRecords(), container, group);
- }
- } else {
- log.log(POILogger.WARN,
- "Found drawing group without children.");
- }
-
- } else if (shapeContainer.getRecordId() == EscherContainerRecord.SP_CONTAINER) {
- EscherSpRecord spRecord = shapeContainer
- .getChildById(EscherSpRecord.RECORD_ID);
- int type = spRecord.getShapeType();
-
- switch (type) {
- case ST_TEXTBOX:
- HSSFTextbox box = new HSSFTextbox(parent,
- new HSSFClientAnchor());
- addToParentOrContainer(box, container, parent);
-
- convertRecordsToUserModel(shapeContainer, box);
- break;
- case ST_PICTUREFRAME:
- // Duplicated from
- // org.apache.poi.hslf.model.Picture.getPictureIndex()
- EscherOptRecord opt = (EscherOptRecord) getEscherChild(
- shapeContainer, EscherOptRecord.RECORD_ID);
- EscherSimpleProperty prop = (EscherSimpleProperty) opt.lookup(
- EscherProperties.BLIP__BLIPTODISPLAY);
- if (prop == null) {
- log.log(POILogger.WARN,
- "Picture index for picture shape not found.");
- } else {
- int pictureIndex = prop.getPropertyValue();
-
- EscherClientAnchorRecord anchorRecord = (EscherClientAnchorRecord) getEscherChild(
- shapeContainer,
- EscherClientAnchorRecord.RECORD_ID);
-
- EscherChildAnchorRecord childRecord = (EscherChildAnchorRecord) getEscherChild(
- shapeContainer,
- EscherChildAnchorRecord.RECORD_ID);
-
- if (anchorRecord != null && childRecord != null) {
- log.log(POILogger.WARN, "Picture with both CLIENT and CHILD anchor: " + type);
- }
-
- HSSFAnchor anchor;
- if (anchorRecord != null) {
- anchor = toClientAnchor(anchorRecord);
- } else {
- anchor = toChildAnchor(childRecord);
- }
-
- HSSFPicture picture = new HSSFPicture(parent, anchor);
- picture.setPictureIndex(pictureIndex);
-
- addToParentOrContainer(picture, container, parent);
- }
- break;
- default:
- final HSSFSimpleShape shape = new HSSFSimpleShape(parent,
- new HSSFClientAnchor());
- addToParentOrContainer(shape, container, parent);
- convertRecordsToUserModel(shapeContainer, shape);
-
- log.log(POILogger.WARN, "Unhandled shape type: "
- + type);
- break;
- }
- } else {
- log.log(POILogger.WARN, "Unexpected record id of shape group.");
- }
-
- }
- }
-
- private static void addToParentOrContainer(HSSFShape shape, HSSFShapeContainer container, HSSFShape parent) {
-
- if (parent instanceof HSSFShapeGroup)
- ((HSSFShapeGroup) parent).addShape(shape);
- else if (container instanceof HSSFPatriarch)
- ((HSSFPatriarch) container).addShape(shape);
- else
- container.getChildren().add(shape);
- }
-
- public static HSSFClientAnchor toClientAnchor(EscherClientAnchorRecord anchorRecord) {
- HSSFClientAnchor anchor = new HSSFClientAnchor();
- anchor.setAnchorType(anchorRecord.getFlag());
- anchor.setCol1(anchorRecord.getCol1());
- anchor.setCol2(anchorRecord.getCol2());
- anchor.setDx1(anchorRecord.getDx1());
- anchor.setDx2(anchorRecord.getDx2());
- anchor.setDy1(anchorRecord.getDy1());
- anchor.setDy2(anchorRecord.getDy2());
- anchor.setRow1(anchorRecord.getRow1());
- anchor.setRow2(anchorRecord.getRow2());
- return anchor;
- }
-
- public static HSSFChildAnchor toChildAnchor(EscherChildAnchorRecord anchorRecord) {
- HSSFChildAnchor anchor = new HSSFChildAnchor();
-// anchor.setAnchorType(anchorRecord.getFlag());
-// anchor.setCol1( anchorRecord.getCol1() );
-// anchor.setCol2( anchorRecord.getCol2() );
- anchor.setDx1(anchorRecord.getDx1());
- anchor.setDx2(anchorRecord.getDx2());
- anchor.setDy1(anchorRecord.getDy1());
- anchor.setDy2(anchorRecord.getDy2());
-// anchor.setRow1( anchorRecord.getRow1() );
-// anchor.setRow2( anchorRecord.getRow2() );
- return anchor;
- }
-
- private static void convertRecordsToUserModel(EscherContainerRecord shapeContainer, Object model) {
- for (Iterator<EscherRecord> it = shapeContainer.getChildIterator(); it.hasNext(); ) {
- EscherRecord r = it.next();
- if (r instanceof EscherSpgrRecord) {
- // This may be overriden by a later EscherClientAnchorRecord
- EscherSpgrRecord spgr = (EscherSpgrRecord) r;
-
- if (model instanceof HSSFShapeGroup) {
- HSSFShapeGroup g = (HSSFShapeGroup) model;
- g.setCoordinates(
- spgr.getRectX1(), spgr.getRectY1(),
- spgr.getRectX2(), spgr.getRectY2()
- );
- } else {
- throw new IllegalStateException("Got top level anchor but not processing a group");
- }
- } else if (r instanceof EscherClientAnchorRecord) {
- EscherClientAnchorRecord car = (EscherClientAnchorRecord) r;
-
- if (model instanceof HSSFShape) {
- HSSFShape g = (HSSFShape) model;
- g.getAnchor().setDx1(car.getDx1());
- g.getAnchor().setDx2(car.getDx2());
- g.getAnchor().setDy1(car.getDy1());
- g.getAnchor().setDy2(car.getDy2());
- } else {
- throw new IllegalStateException("Got top level anchor but not processing a group or shape");
- }
- } else if (r instanceof EscherTextboxRecord) {
- EscherTextboxRecord tbr = (EscherTextboxRecord) r;
-
- // Also need to find the TextObjectRecord too
- // TODO
- } else if (r instanceof EscherSpRecord) {
- // Use flags if needed
- final EscherSpRecord spr = (EscherSpRecord) r;
- if (model instanceof HSSFShape) {
- final HSSFShape s = (HSSFShape) model;
- }
- } else if (r instanceof EscherOptRecord) {
- // Use properties if needed
- } else {
- //System.err.println(r);
- }
- }
- }
-
public void clear() {
clearEscherRecords();
shapeToObj.clear();
return sid(records, loc) == ObjRecord.sid || sid(records, loc) == TextObjectRecord.sid;
}
- private void convertUserModelToRecords() {
- if (patriarch != null) {
- shapeToObj.clear();
- tailRec.clear();
- clearEscherRecords();
- if (patriarch.getChildren().size() != 0) {
- convertPatriarch(patriarch);
- EscherContainerRecord dgContainer = (EscherContainerRecord) getEscherRecord(0);
- EscherContainerRecord spgrContainer = null;
- Iterator<EscherRecord> iter = dgContainer.getChildIterator();
- while (iter.hasNext()) {
- EscherRecord child = iter.next();
- if (child.getRecordId() == EscherContainerRecord.SPGR_CONTAINER) {
- spgrContainer = (EscherContainerRecord) child;
- }
- }
- convertShapes(patriarch, spgrContainer, shapeToObj);
-
- patriarch = null;
- }
- }
- }
-
- private void convertShapes(HSSFShapeContainer parent, EscherContainerRecord escherParent, Map shapeToObj) {
- if (escherParent == null) throw new IllegalArgumentException("Parent record required");
-
- List shapes = parent.getChildren();
- for (Iterator iterator = shapes.iterator(); iterator.hasNext(); ) {
- HSSFShape shape = (HSSFShape) iterator.next();
- if (shape instanceof HSSFShapeGroup) {
- convertGroup((HSSFShapeGroup) shape, escherParent, shapeToObj);
- } else {
- AbstractShape shapeModel = AbstractShape.createShape(
- shape,
- drawingManager.allocateShapeId(drawingGroupId));
- shapeToObj.put(findClientData(shapeModel.getSpContainer()), shapeModel.getObjRecord());
- if (shapeModel instanceof TextboxShape) {
- EscherRecord escherTextbox = ((TextboxShape) shapeModel).getEscherTextbox();
- shapeToObj.put(escherTextbox, ((TextboxShape) shapeModel).getTextObjectRecord());
- // escherParent.addChildRecord(escherTextbox);
-
- if (shapeModel instanceof CommentShape) {
- CommentShape comment = (CommentShape) shapeModel;
- tailRec.put(comment.getNoteRecord().getShapeId(), comment.getNoteRecord());
- }
-
- }
- escherParent.addChildRecord(shapeModel.getSpContainer());
- }
- }
-// drawingManager.newCluster( (short)1 );
-// drawingManager.newCluster( (short)2 );
-
- }
-
- private void convertGroup(HSSFShapeGroup shape, EscherContainerRecord escherParent, Map shapeToObj) {
- 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(shape.getX1());
- spgr.setRectY1(shape.getY1());
- spgr.setRectX2(shape.getX2());
- spgr.setRectY2(shape.getY2());
- sp.setRecordId(EscherSpRecord.RECORD_ID);
- sp.setOptions((short) 0x0002);
- int shapeId = drawingManager.allocateShapeId(drawingGroupId);
- sp.setShapeId(shapeId);
- if (shape.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 = ConvertAnchor.createAnchor(shape.getAnchor());
-// clientAnchor.setCol1( ( (HSSFClientAnchor) shape.getAnchor() ).getCol1() );
-// clientAnchor.setRow1( (short) ( (HSSFClientAnchor) shape.getAnchor() ).getRow1() );
-// clientAnchor.setDx1( (short) shape.getAnchor().getDx1() );
-// clientAnchor.setDy1( (short) shape.getAnchor().getDy1() );
-// clientAnchor.setCol2( ( (HSSFClientAnchor) shape.getAnchor() ).getCol2() );
-// clientAnchor.setRow2( (short) ( (HSSFClientAnchor) shape.getAnchor() ).getRow2() );
-// clientAnchor.setDx2( (short) shape.getAnchor().getDx2() );
-// clientAnchor.setDy2( (short) shape.getAnchor().getDy2() );
- 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);
-
- ObjRecord obj = new ObjRecord();
- CommonObjectDataSubRecord cmo = new CommonObjectDataSubRecord();
- cmo.setObjectType(CommonObjectDataSubRecord.OBJECT_TYPE_GROUP);
- cmo.setObjectId(shapeId);
- 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);
- shapeToObj.put(clientData, obj);
-
- escherParent.addChildRecord(spgrContainer);
-
- convertShapes(shape, spgrContainer, shapeToObj);
-
- }
-
private EscherRecord findClientData(EscherContainerRecord spContainer) {
for (Iterator<EscherRecord> iterator = spContainer.getChildIterator(); iterator.hasNext(); ) {
EscherRecord r = iterator.next();
dg.setOptions((short) (dgId << 4));
dg.setNumShapes(0);
dg.setLastMSOSPID(1024);
- drawingGroupId = dg.getDrawingGroupId();
spgrContainer.setRecordId(EscherContainerRecord.SPGR_CONTAINER);
spgrContainer.setOptions((short) 0x000F);
spContainer1.setRecordId(EscherContainerRecord.SP_CONTAINER);
sp.setShapeId(shapeId);
}
- private void convertPatriarch(HSSFPatriarch patriarch) {
- EscherContainerRecord dgContainer = new EscherContainerRecord();
- EscherDgRecord dg;
- EscherContainerRecord spgrContainer = new EscherContainerRecord();
- EscherContainerRecord spContainer1 = new EscherContainerRecord();
- EscherSpgrRecord spgr = new EscherSpgrRecord();
- EscherSpRecord sp1 = new EscherSpRecord();
-
- dgContainer.setRecordId(EscherContainerRecord.DG_CONTAINER);
- dgContainer.setOptions((short) 0x000F);
- dg = drawingManager.createDgRecord();
- drawingGroupId = dg.getDrawingGroupId();
-// dg.setOptions( (short) ( drawingId << 4 ) );
-// dg.setNumShapes( getNumberOfShapes( patriarch ) );
-// dg.setLastMSOSPID( 0 ); // populated after all shape id's are assigned.
- spgrContainer.setRecordId(EscherContainerRecord.SPGR_CONTAINER);
- spgrContainer.setOptions((short) 0x000F);
- spContainer1.setRecordId(EscherContainerRecord.SP_CONTAINER);
- spContainer1.setOptions((short) 0x000F);
- spgr.setRecordId(EscherSpgrRecord.RECORD_ID);
- spgr.setOptions((short) 0x0001); // version
- spgr.setRectX1(patriarch.getX1());
- spgr.setRectY1(patriarch.getY1());
- spgr.setRectX2(patriarch.getX2());
- spgr.setRectY2(patriarch.getY2());
- sp1.setRecordId(EscherSpRecord.RECORD_ID);
- sp1.setOptions((short) 0x0002);
- sp1.setShapeId(drawingManager.allocateShapeId(dg.getDrawingGroupId()));
- sp1.setFlags(EscherSpRecord.FLAG_GROUP | EscherSpRecord.FLAG_PATRIARCH);
-
- dgContainer.addChildRecord(dg);
- dgContainer.addChildRecord(spgrContainer);
- spgrContainer.addChildRecord(spContainer1);
- spContainer1.addChildRecord(spgr);
- spContainer1.addChildRecord(sp1);
-
- addEscherRecord(dgContainer);
- }
-
-
private static short sid(List records, int loc) {
return ((Record) records.get(loc)).getSid();
}
super.setShapeType(OBJECT_TYPE_COMBO_BOX);\r
}\r
\r
+ @Override\r
+ protected TextObjectRecord createTextObjRecord() {\r
+ return null;\r
+ }\r
+\r
@Override\r
protected EscherContainerRecord createSpContainer() {\r
EscherContainerRecord spContainer = new EscherContainerRecord();\r
@Override
void afterInsert(HSSFPatriarch patriarch) {
super.afterInsert(patriarch);
- _patriarch._getBoundAggregate().addTailRecord(getNoteRecord());
+ patriarch._getBoundAggregate().addTailRecord(getNoteRecord());
}
@Override
void setShapeId(int shapeId) {
super.setShapeId(shapeId);
CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) getObjRecord().getSubRecords().get(0);
- cod.setObjectId((short) (shapeId));
- _note.setShapeId(shapeId);
+ cod.setObjectId((short) (shapeId % 1024));
+ _note.setShapeId(shapeId % 1024);
}
/**
patriarch._getBoundAggregate().removeShapeToObjRecord(getEscherContainer().getChildById(EscherTextboxRecord.RECORD_ID));
patriarch._getBoundAggregate().removeTailRecord(getNoteRecord());
}
+
+ @Override
+ public HSSFShape cloneShape() {
+ TextObjectRecord txo = (TextObjectRecord) getTextObjectRecord().cloneViaReserialise();
+ EscherContainerRecord spContainer = new EscherContainerRecord();
+ byte [] inSp = getEscherContainer().serialize();
+ spContainer.fillFields(inSp, 0, new DefaultEscherRecordFactory());
+ ObjRecord obj = (ObjRecord) getObjRecord().cloneViaReserialise();
+ NoteRecord note = (NoteRecord) getNoteRecord().cloneViaReserialise();
+ return new HSSFComment(spContainer, obj, txo, note);
+ }
}
import java.io.IOException;
import java.util.Iterator;
-import org.apache.poi.ddf.EscherContainerRecord;
-import org.apache.poi.hssf.record.EmbeddedObjectRefSubRecord;
-import org.apache.poi.hssf.record.ObjRecord;
-import org.apache.poi.hssf.record.SubRecord;
+import org.apache.poi.ddf.*;
+import org.apache.poi.hssf.record.*;
import org.apache.poi.poifs.filesystem.DirectoryEntry;
import org.apache.poi.poifs.filesystem.Entry;
import org.apache.poi.util.HexDump;
/**
* Represents binary object (i.e. OLE) data stored in the file. Eg. A GIF, JPEG etc...
- *
+ * <p/>
* Right now, 13, july, 2012 can not be created from scratch
*
* @author Daniel Noll
*/
-public final class HSSFObjectData extends HSSFShape{
+public final class HSSFObjectData extends HSSFShape {
/**
* Reference to the filesystem root, required for retrieving the object data.
*/
/**
* Gets the object data. Only call for ones that have
- * data though. See {@link #hasDirectoryEntry()}
+ * data though. See {@link #hasDirectoryEntry()}
*
* @return the object data as an OLE2 directory.
* @throws IOException if there was an error reading the data.
/**
* Returns the data portion, for an ObjectData
- * that doesn't have an associated POIFS Directory
- * Entry
+ * that doesn't have an associated POIFS Directory
+ * Entry
*/
public byte[] getObjectData() {
return findObjectRecord().getObjectData();
/**
* Does this ObjectData have an associated POIFS
- * Directory Entry?
+ * Directory Entry?
* (Not all do, those that don't have a data portion)
*/
public boolean hasDirectoryEntry() {
/**
* Finds the EmbeddedObjectRefSubRecord, or throws an
- * Exception if there wasn't one
+ * Exception if there wasn't one
*/
protected EmbeddedObjectRefSubRecord findObjectRecord() {
Iterator<SubRecord> subRecordIter = getObjRecord().getSubRecords().iterator();
while (subRecordIter.hasNext()) {
Object subRecord = subRecordIter.next();
if (subRecord instanceof EmbeddedObjectRefSubRecord) {
- return (EmbeddedObjectRefSubRecord)subRecord;
+ return (EmbeddedObjectRefSubRecord) subRecord;
}
}
@Override
void afterInsert(HSSFPatriarch patriarch) {
- throw new IllegalStateException("HSSFObjectData cannot be created from scratch");
+ EscherAggregate agg = patriarch._getBoundAggregate();
+ agg.associateShapeToObjRecord(getEscherContainer().getChildById(EscherClientDataRecord.RECORD_ID), getObjRecord());
+ EscherBSERecord bse =
+ patriarch._sheet.getWorkbook().getWorkbook().getBSERecord(getPictureIndex());
+ bse.setRef(bse.getRef() + 1);
+ }
+
+ @Override
+ public HSSFShape cloneShape() {
+ EscherContainerRecord spContainer = new EscherContainerRecord();
+ byte[] inSp = getEscherContainer().serialize();
+ spContainer.fillFields(inSp, 0, new DefaultEscherRecordFactory());
+ ObjRecord obj = (ObjRecord) getObjRecord().cloneViaReserialise();
+ return new HSSFObjectData(spContainer, obj, _root);
+ }
+
+ public int getPictureIndex() {
+ EscherSimpleProperty property = getOptRecord().lookup(EscherProperties.BLIP__BLIPTODISPLAY);
+ if (null == property) {
+ return -1;
+ }
+ return property.getPropertyValue();
+ }
+
+ public void setPictureIndex(int pictureIndex) {
+ setPropertyValue(new EscherSimpleProperty(EscherProperties.BLIP__BLIPTODISPLAY, false, true, pictureIndex));
+ }
+
+ @Override
+ void setShapeId(int shapeId) {
+ EscherSpRecord spRecord = getEscherContainer().getChildById(EscherSpRecord.RECORD_ID);
+ spRecord.setShapeId(shapeId);
+ CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) getObjRecord().getSubRecords().get(0);
+ cod.setObjectId((short) (shapeId % 1024));
}
}
*/
public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
private final List<HSSFShape> _shapes = new ArrayList<HSSFShape>();
-// private int _x1 = 0;
-// private int _y1 = 0 ;
-// private int _x2 = 1023;
-// private int _y2 = 255;
private final EscherSpgrRecord _spgrRecord;
private final EscherContainerRecord _mainSpgrContainer;
/**
* The EscherAggregate we have been bound to.
* (This will handle writing us out into records,
- * and building up our shapes from the records)
+ * and building up our shapes from the records)
*/
private EscherAggregate _boundAggregate;
- final HSSFSheet _sheet; // TODO make private
+ final HSSFSheet _sheet; // TODO make private
/**
* Creates the patriarch.
*
* @param sheet the sheet this patriarch is stored in.
*/
- HSSFPatriarch(HSSFSheet sheet, EscherAggregate boundAggregate){
+ HSSFPatriarch(HSSFSheet sheet, EscherAggregate boundAggregate) {
_sheet = sheet;
- _boundAggregate = boundAggregate;
+ _boundAggregate = boundAggregate;
_mainSpgrContainer = _boundAggregate.getEscherContainer().getChildContainers().get(0);
EscherContainerRecord spContainer = (EscherContainerRecord) _boundAggregate.getEscherContainer()
.getChildContainers().get(0).getChild(0);
buildShapeTree();
}
+ static HSSFPatriarch createPatriarch(HSSFPatriarch patriarch, HSSFSheet sheet){
+ HSSFPatriarch newPatriarch = new HSSFPatriarch(sheet, new EscherAggregate());
+ newPatriarch.afterCreate();
+
+ for (HSSFShape shape: patriarch.getChildren()){
+ HSSFShape newShape;
+ if (shape instanceof HSSFShapeGroup){
+ newShape = ((HSSFShapeGroup)shape).cloneShape(newPatriarch);
+ } else {
+ newShape = shape.cloneShape();
+ }
+ newPatriarch.onCreate(newShape);
+ newPatriarch.addShape(newShape);
+ }
+
+ return newPatriarch;
+ }
+
/**
* remove first level shapes
+ *
* @param shape to be removed
*/
- public void removeShape(HSSFShape shape){
+ public void removeShape(HSSFShape shape) {
_mainSpgrContainer.removeChildRecord(shape.getEscherContainer());
shape.afterRemove(this);
_shapes.remove(shape);
}
- public void afterCreate(){
+ void afterCreate() {
DrawingManager2 drawingManager = _sheet.getWorkbook().getWorkbook().getDrawingManager();
short dgId = drawingManager.findNewDrawingGroupId();
_boundAggregate.setDgId(dgId);
/**
* Creates a new group record stored under this patriarch.
*
- * @param anchor the client anchor describes how this group is attached
- * to the sheet.
- * @return the newly created group.
+ * @param anchor the client anchor describes how this group is attached
+ * to the sheet.
+ * @return the newly created group.
*/
- public HSSFShapeGroup createGroup(HSSFClientAnchor anchor)
- {
+ public HSSFShapeGroup createGroup(HSSFClientAnchor anchor) {
HSSFShapeGroup group = new HSSFShapeGroup(null, anchor);
addShape(group);
onCreate(group);
* Creates a simple shape. This includes such shapes as lines, rectangles,
* and ovals.
*
- * @param anchor the client anchor describes how this group is attached
- * to the sheet.
- * @return the newly created shape.
+ * @param anchor the client anchor describes how this group is attached
+ * to the sheet.
+ * @return the newly created shape.
*/
- public HSSFSimpleShape createSimpleShape(HSSFClientAnchor anchor)
- {
+ public HSSFSimpleShape createSimpleShape(HSSFClientAnchor anchor) {
HSSFSimpleShape shape = new HSSFSimpleShape(null, anchor);
addShape(shape);
//open existing file
onCreate(shape);
EscherSpRecord sp = shape.getEscherContainer().getChildById(EscherSpRecord.RECORD_ID);
- if (shape.anchor.isHorizontallyFlipped()){
+ if (shape.anchor.isHorizontallyFlipped()) {
sp.setFlags(sp.getFlags() | EscherSpRecord.FLAG_FLIPHORIZ);
}
- if (shape.anchor.isVerticallyFlipped()){
+ if (shape.anchor.isVerticallyFlipped()) {
sp.setFlags(sp.getFlags() | EscherSpRecord.FLAG_FLIPVERT);
}
return shape;
/**
* Creates a picture.
*
- * @param anchor the client anchor describes how this group is attached
- * to the sheet.
- * @return the newly created shape.
+ * @param anchor the client anchor describes how this group is attached
+ * to the sheet.
+ * @return the newly created shape.
*/
- public HSSFPicture createPicture(HSSFClientAnchor anchor, int pictureIndex)
- {
+ public HSSFPicture createPicture(HSSFClientAnchor anchor, int pictureIndex) {
HSSFPicture shape = new HSSFPicture(null, anchor);
- shape.setPictureIndex( pictureIndex );
+ shape.setPictureIndex(pictureIndex);
addShape(shape);
//open existing file
onCreate(shape);
EscherSpRecord sp = shape.getEscherContainer().getChildById(EscherSpRecord.RECORD_ID);
- if (shape.anchor.isHorizontallyFlipped()){
+ if (shape.anchor.isHorizontallyFlipped()) {
sp.setFlags(sp.getFlags() | EscherSpRecord.FLAG_FLIPHORIZ);
}
- if (shape.anchor.isVerticallyFlipped()){
+ if (shape.anchor.isVerticallyFlipped()) {
sp.setFlags(sp.getFlags() | EscherSpRecord.FLAG_FLIPVERT);
}
return shape;
}
- public HSSFPicture createPicture(ClientAnchor anchor, int pictureIndex)
- {
- return createPicture((HSSFClientAnchor)anchor, pictureIndex);
+ public HSSFPicture createPicture(ClientAnchor anchor, int pictureIndex) {
+ return createPicture((HSSFClientAnchor) anchor, pictureIndex);
}
/**
* Creates a polygon
*
- * @param anchor the client anchor describes how this group is attached
- * to the sheet.
- * @return the newly created shape.
+ * @param anchor the client anchor describes how this group is attached
+ * to the sheet.
+ * @return the newly created shape.
*/
- public HSSFPolygon createPolygon(HSSFClientAnchor anchor)
- {
+ public HSSFPolygon createPolygon(HSSFClientAnchor anchor) {
HSSFPolygon shape = new HSSFPolygon(null, anchor);
addShape(shape);
onCreate(shape);
/**
* Constructs a textbox under the patriarch.
*
- * @param anchor the client anchor describes how this group is attached
- * to the sheet.
- * @return the newly created textbox.
+ * @param anchor the client anchor describes how this group is attached
+ * to the sheet.
+ * @return the newly created textbox.
*/
- public HSSFTextbox createTextbox(HSSFClientAnchor anchor)
- {
+ public HSSFTextbox createTextbox(HSSFClientAnchor anchor) {
HSSFTextbox shape = new HSSFTextbox(null, anchor);
addShape(shape);
onCreate(shape);
/**
* Constructs a cell comment.
*
- * @param anchor the client anchor describes how this comment is attached
- * to the sheet.
- * @return the newly created comment.
+ * @param anchor the client anchor describes how this comment is attached
+ * to the sheet.
+ * @return the newly created comment.
*/
- public HSSFComment createComment(HSSFAnchor anchor)
- {
+ public HSSFComment createComment(HSSFAnchor anchor) {
HSSFComment shape = new HSSFComment(null, anchor);
addShape(shape);
onCreate(shape);
*
* @see org.apache.poi.hssf.usermodel.HSSFSheet#setAutoFilter(org.apache.poi.ss.util.CellRangeAddress)
*/
- HSSFSimpleShape createComboBox(HSSFAnchor anchor)
- {
- HSSFCombobox shape = new HSSFCombobox(null, anchor);
- addShape(shape);
- onCreate(shape);
- return shape;
- }
+ HSSFSimpleShape createComboBox(HSSFAnchor anchor) {
+ HSSFCombobox shape = new HSSFCombobox(null, anchor);
+ addShape(shape);
+ onCreate(shape);
+ return shape;
+ }
public HSSFComment createCellComment(ClientAnchor anchor) {
- return createComment((HSSFAnchor)anchor);
+ return createComment((HSSFAnchor) anchor);
}
/**
* Returns a list of all shapes contained by the patriarch.
*/
- public List<HSSFShape> getChildren()
- {
+ public List<HSSFShape> getChildren() {
return _shapes;
}
* add a shape to this drawing
*/
@Internal
- public void addShape(HSSFShape shape){
+ public void addShape(HSSFShape shape) {
shape._patriarch = this;
_shapes.add(shape);
}
- private void onCreate(HSSFShape shape){
- if(_boundAggregate.getPatriarch() == null){
- EscherContainerRecord spgrContainer =
- _boundAggregate.getEscherContainer().getChildContainers().get(0);
+ private void onCreate(HSSFShape shape) {
+ EscherContainerRecord spgrContainer =
+ _boundAggregate.getEscherContainer().getChildContainers().get(0);
- EscherContainerRecord spContainer = shape.getEscherContainer();
- int shapeId = newShapeId();
- shape.setShapeId(shapeId);
+ EscherContainerRecord spContainer = shape.getEscherContainer();
+ int shapeId = newShapeId();
+ shape.setShapeId(shapeId);
- spgrContainer.addChildRecord(spContainer);
- shape.afterInsert(this);
- }
+ spgrContainer.addChildRecord(spContainer);
+ shape.afterInsert(this);
}
/**
*/
public int countOfAllChildren() {
int count = _shapes.size();
- for (Iterator<HSSFShape> iterator = _shapes.iterator(); iterator.hasNext();) {
+ for (Iterator<HSSFShape> iterator = _shapes.iterator(); iterator.hasNext(); ) {
HSSFShape shape = iterator.next();
count += shape.countOfAllChildren();
}
return count;
}
+
/**
* 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){
+ public void setCoordinates(int x1, int y1, int x2, int y2) {
_spgrRecord.setRectY1(y1);
_spgrRecord.setRectY2(y2);
_spgrRecord.setRectX1(x1);
/**
* Does this HSSFPatriarch contain a chart?
* (Technically a reference to a chart, since they
- * get stored in a different block of records)
+ * get stored in a different block of records)
* FIXME - detect chart in all cases (only seems
- * to work on some charts so far)
+ * to work on some charts so far)
*/
public boolean containsChart() {
// TODO - support charts properly in usermodel
// We're looking for a EscherOptRecord
EscherOptRecord optRecord = (EscherOptRecord)
- _boundAggregate.findFirstWithId(EscherOptRecord.RECORD_ID);
- if(optRecord == null) {
+ _boundAggregate.findFirstWithId(EscherOptRecord.RECORD_ID);
+ if (optRecord == null) {
// No opt record, can't have chart
return false;
}
- for(Iterator<EscherProperty> it = optRecord.getEscherProperties().iterator(); it.hasNext();) {
+ for (Iterator<EscherProperty> it = optRecord.getEscherProperties().iterator(); it.hasNext(); ) {
EscherProperty prop = it.next();
- if(prop.getPropertyNumber() == 896 && prop.isComplex()) {
- EscherComplexProperty cp = (EscherComplexProperty)prop;
+ if (prop.getPropertyNumber() == 896 && prop.isComplex()) {
+ EscherComplexProperty cp = (EscherComplexProperty) prop;
String str = StringUtil.getFromUnicodeLE(cp.getComplexData());
- if(str.equals("Chart 1\0")) {
+ if (str.equals("Chart 1\0")) {
return true;
}
}
/**
* The top left x coordinate of this group.
*/
- public int getX1()
- {
+ public int getX1() {
return _spgrRecord.getRectX1();
}
/**
* The top left y coordinate of this group.
*/
- public int getY1()
- {
+ public int getY1() {
return _spgrRecord.getRectY1();
}
/**
* The bottom right x coordinate of this group.
*/
- public int getX2()
- {
+ public int getX2() {
return _spgrRecord.getRectX2();
}
/**
* The bottom right y coordinate of this group.
*/
- public int getY2()
- {
+ public int getY2() {
return _spgrRecord.getRectY2();
}
* @param row2 the row (0 based) of the second cell.
* @return the newly created client anchor
*/
- public HSSFClientAnchor createAnchor(int dx1, int dy1, int dx2, int dy2, int col1, int row1, int col2, int row2){
- return new HSSFClientAnchor(dx1, dy1, dx2, dy2, (short)col1, row1, (short)col2, row2);
+ public HSSFClientAnchor createAnchor(int dx1, int dy1, int dx2, int dy2, int col1, int row1, int col2, int row2) {
+ return new HSSFClientAnchor(dx1, dy1, dx2, dy2, (short) col1, row1, (short) col2, row2);
}
- public Chart createChart(ClientAnchor anchor) {
- throw new RuntimeException("NotImplemented");
- }
+ public Chart createChart(ClientAnchor anchor) {
+ throw new RuntimeException("NotImplemented");
+ }
- void buildShapeTree(){
+ void buildShapeTree() {
EscherContainerRecord dgContainer = _boundAggregate.getEscherContainer();
- if (dgContainer == null){
+ if (dgContainer == null) {
return;
}
EscherContainerRecord spgrConrainer = dgContainer.getChildContainers().get(0);
List<EscherContainerRecord> spgrChildren = spgrConrainer.getChildContainers();
- for(int i = 0; i < spgrChildren.size(); i++){
+ for (int i = 0; i < spgrChildren.size(); i++) {
EscherContainerRecord spContainer = spgrChildren.get(i);
- if (i == 0){
+ if (i == 0) {
continue;
} else {
HSSFShapeFactory.createShapeTree(spContainer, _boundAggregate, this, _sheet.getWorkbook().getRootDirectory());
import java.io.UnsupportedEncodingException;
import org.apache.poi.ddf.*;
+import org.apache.poi.hssf.record.EscherAggregate;
import org.apache.poi.hssf.record.ObjRecord;
import org.apache.poi.ss.usermodel.Picture;
import org.apache.poi.ss.util.ImageUtils;
EscherOptRecord opt = spContainer.getChildById(EscherOptRecord.RECORD_ID);
removeEscherProperty(opt, EscherProperties.LINESTYLE__LINEDASHING);
removeEscherProperty(opt, EscherProperties.LINESTYLE__NOLINEDRAWDASH);
+ spContainer.removeChildRecord(spContainer.getChildById(EscherTextboxRecord.RECORD_ID));
return spContainer;
}
@Override
void afterInsert(HSSFPatriarch patriarch) {
- super.afterInsert(patriarch);
+ EscherAggregate agg = patriarch._getBoundAggregate();
+ agg.associateShapeToObjRecord(getEscherContainer().getChildById(EscherClientDataRecord.RECORD_ID), getObjRecord());
EscherBSERecord bse =
patriarch._sheet.getWorkbook().getWorkbook().getBSERecord(getPictureIndex());
bse.setRef(bse.getRef() + 1);
public void setShapeType(int shapeType) {
throw new IllegalStateException("Shape type can not be changed in "+this.getClass().getSimpleName());
}
+
+ @Override
+ public HSSFShape cloneShape() {
+ EscherContainerRecord spContainer = new EscherContainerRecord();
+ byte [] inSp = getEscherContainer().serialize();
+ spContainer.fillFields(inSp, 0, new DefaultEscherRecordFactory());
+ ObjRecord obj = (ObjRecord) getObjRecord().cloneViaReserialise();
+ return new HSSFPicture(spContainer, obj);
+ }
}
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.record.*;
import org.apache.poi.util.LittleEndian;
/**
* @author Glen Stampoultzis (glens at superlinksoftware.com)
*/
-public class HSSFPolygon extends HSSFShape {
+public class HSSFPolygon extends HSSFSimpleShape {
public final static short OBJECT_TYPE_MICROSOFT_OFFICE_DRAWING = 0x1E;
+ public HSSFPolygon(EscherContainerRecord spContainer, ObjRecord objRecord, TextObjectRecord _textObjectRecord) {
+ super(spContainer, objRecord, _textObjectRecord);
+ }
+
public HSSFPolygon(EscherContainerRecord spContainer, ObjRecord objRecord) {
super(spContainer, objRecord);
}
super(parent, anchor);
}
+ @Override
+ protected TextObjectRecord createTextObjRecord() {
+ return null;
+ }
+
/**
* Generates the shape records for this shape.
*/
EscherSimpleProperty property = getOptRecord().lookup(EscherProperties.GEOMETRY__BOTTOM);
return property == null ? 100: property.getPropertyValue();
}
-
- @Override
- void afterInsert(HSSFPatriarch patriarch) {
- EscherAggregate agg = patriarch._getBoundAggregate();
- agg.associateShapeToObjRecord(getEscherContainer().getChildById(EscherClientDataRecord.RECORD_ID), getObjRecord());
- }
}
public int countOfAllChildren() {
return 1;
}
+
+ public abstract HSSFShape cloneShape();
}
\r
public static void createShapeTree(EscherContainerRecord container, EscherAggregate agg, HSSFShapeContainer out, DirectoryNode root) {\r
if (container.getRecordId() == EscherContainerRecord.SPGR_CONTAINER) {\r
- HSSFShapeGroup group = new HSSFShapeGroup(container,\r
- null /* shape containers don't have a associated Obj record*/);\r
+ ObjRecord obj = null;\r
+ EscherClientDataRecord clientData = ((EscherContainerRecord)container.getChild(0)).getChildById(EscherClientDataRecord.RECORD_ID);\r
+ if (null != clientData){\r
+ obj = (ObjRecord) agg.getShapeToObjMapping().get(clientData);\r
+ }\r
+ HSSFShapeGroup group = new HSSFShapeGroup(container, obj);\r
List<EscherContainerRecord> children = container.getChildContainers();\r
// skip the first child record, it is group descriptor\r
for (int i = 0; i < children.size(); i++) {\r
EscherOptRecord optRecord = container.getChildById(EscherOptRecord.RECORD_ID);\r
EscherProperty property = optRecord.lookup(EscherProperties.GEOMETRY__VERTICES);\r
if (null != property) {\r
- shape = new HSSFPolygon(container, objRecord);\r
+ shape = new HSSFPolygon(container, objRecord, txtRecord);\r
} else {\r
shape = new HSSFSimpleShape(container, objRecord);\r
}\r
}
private void onCreate(HSSFShape shape){
- if(_patriarch != null && _patriarch._getBoundAggregate().getPatriarch() == null){
+ if(_patriarch != null){
EscherContainerRecord spContainer = shape.getEscherContainer();
int shapeId = _patriarch.newShapeId();
shape.setShapeId(shapeId);
getEscherContainer().addChildRecord(spContainer);
shape.afterInsert(_patriarch);
- EscherSpRecord sp = shape.getEscherContainer().getChildById(EscherSpRecord.RECORD_ID);
+ EscherSpRecord sp;
+ if (shape instanceof HSSFShapeGroup){
+ sp = shape.getEscherContainer().getChildContainers().get(0).getChildById(EscherSpRecord.RECORD_ID);
+ } else {
+ sp = shape.getEscherContainer().getChildById(EscherSpRecord.RECORD_ID);
+ }
sp.setFlags(sp.getFlags() | EscherSpRecord.FLAG_CHILD);
}
}
EscherSpRecord spRecord = containerRecord.getChildById(EscherSpRecord.RECORD_ID);
spRecord.setShapeId(shapeId);
CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) getObjRecord().getSubRecords().get(0);
- cod.setObjectId((short) (shapeId));
+ cod.setObjectId((short) (shapeId % 1024));
}
@Override
EscherContainerRecord containerRecord = getEscherContainer().getChildById(EscherContainerRecord.SP_CONTAINER);
return ((EscherSpRecord)containerRecord.getChildById(EscherSpRecord.RECORD_ID)).getShapeId();
}
+
+ @Override
+ public HSSFShape cloneShape() {
+ throw new IllegalStateException("Use method cloneShape(HSSFPatriarch patriarch)");
+ }
+
+ public HSSFShape cloneShape(HSSFPatriarch patriarch) {
+ EscherContainerRecord spgrContainer = new EscherContainerRecord();
+ spgrContainer.setRecordId(EscherContainerRecord.SPGR_CONTAINER);
+ spgrContainer.setOptions((short) 0x000F);
+ EscherContainerRecord spContainer = new EscherContainerRecord();
+ byte [] inSp = getEscherContainer().getChildById(EscherContainerRecord.SP_CONTAINER).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._patriarch = 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;
+ }
}
}
HSSFSheet cloneSheet(HSSFWorkbook workbook) {
- return new HSSFSheet(workbook, _sheet.cloneSheet());
+ this.getDrawingPatriarch();/**Aggregate drawing records**/
+ HSSFSheet sheet = new HSSFSheet(workbook, _sheet.cloneSheet());
+ if (getDrawingPatriarch() != null){
+ int insertPos = sheet._sheet.findFirstRecordLocBySid(WindowTwoRecord.sid);
+ HSSFPatriarch patr = HSSFPatriarch.createPatriarch(this.getDrawingPatriarch(), sheet);
+ sheet._sheet.getRecords().add(insertPos, patr._getBoundAggregate());
+ sheet._patriarch = patr;
+ }
+ return sheet;
}
/**
objTypeToShapeType.put(OBJECT_TYPE_OVAL, HSSFShapeType.OVAL.getType());
}
- public HSSFSimpleShape(EscherContainerRecord spContainer, ObjRecord objRecord, TextObjectRecord _textObjectRecord) {
+ public HSSFSimpleShape(EscherContainerRecord spContainer, ObjRecord objRecord, TextObjectRecord textObjectRecord) {
super(spContainer, objRecord);
- this._textObjectRecord = _textObjectRecord == null ? createTextObjRecord() : _textObjectRecord;
+ this._textObjectRecord = textObjectRecord;
}
public HSSFSimpleShape(EscherContainerRecord spContainer, ObjRecord objRecord) {
super(spContainer, objRecord);
- this._textObjectRecord = createTextObjRecord();
}
public HSSFSimpleShape( HSSFShape parent, HSSFAnchor anchor)
TextObjectRecord obj = new TextObjectRecord();
obj.setTextLocked(true);
obj.setTextOrientation(TextObjectRecord.TEXT_ORIENTATION_NONE);
+ obj.setStr(new HSSFRichTextString(""));
return obj;
}
optRecord.setEscherProperty(new EscherBoolProperty( EscherProperties.GROUPSHAPE__PRINT, 0x080000));
optRecord.setRecordId( EscherOptRecord.RECORD_ID );
+ EscherTextboxRecord escherTextbox = new EscherTextboxRecord();
+ escherTextbox.setRecordId(EscherTextboxRecord.RECORD_ID);
+ escherTextbox.setOptions((short) 0x0000);
+
spContainer.addChildRecord(sp);
spContainer.addChildRecord(optRecord);
spContainer.addChildRecord(anchor.getEscherAnchor());
spContainer.addChildRecord(clientData);
+ spContainer.addChildRecord(escherTextbox);
return spContainer;
}
HSSFRichTextString rtr = (HSSFRichTextString) string;
// If font is not set we must set the default one
if (rtr.numFormattingRuns() == 0) rtr.applyFont((short) 0);
- EscherTextboxRecord textbox = getEscherContainer().getChildById(EscherTextboxRecord.RECORD_ID);
- if (string.getString()!= null && !string.getString().equals("")){
- if (null == textbox){
- EscherTextboxRecord escherTextbox = new EscherTextboxRecord();
- escherTextbox.setRecordId(EscherTextboxRecord.RECORD_ID);
- escherTextbox.setOptions((short) 0x0000);
- getEscherContainer().addChildRecord(escherTextbox);
- _patriarch._getBoundAggregate().associateShapeToObjRecord(getEscherContainer().getChildById(EscherTextboxRecord.RECORD_ID), getTextObjectRecord());
- }
- } else {
- if (null != textbox){
- getEscherContainer().removeChildRecord(textbox);
- _patriarch._getBoundAggregate().removeShapeToObjRecord(textbox);
- }
- }
_textObjectRecord.setStr(rtr);
}
void afterInsert(HSSFPatriarch patriarch){
EscherAggregate agg = patriarch._getBoundAggregate();
agg.associateShapeToObjRecord(getEscherContainer().getChildById(EscherClientDataRecord.RECORD_ID), getObjRecord());
+
+ //used only when clone shapes
+ if (null != getTextObjectRecord()){
+ agg.associateShapeToObjRecord(getEscherContainer().getChildById(EscherTextboxRecord.RECORD_ID), getTextObjectRecord());
+ }
+ }
+
+ @Override
+ public HSSFShape cloneShape() {
+ TextObjectRecord txo = null;
+ EscherContainerRecord spContainer = new EscherContainerRecord();
+ byte [] inSp = getEscherContainer().serialize();
+ spContainer.fillFields(inSp, 0, new DefaultEscherRecordFactory());
+ ObjRecord obj = (ObjRecord) getObjRecord().cloneViaReserialise();
+ if (getTextObjectRecord() != null && getString() != null && !"".equals(getString().getString())){
+ txo = (TextObjectRecord) getTextObjectRecord().cloneViaReserialise();
+ }
+ return new HSSFSimpleShape(spContainer, obj, txo);
}
public void setShapeType(int shapeType) {
throw new IllegalStateException("Shape type can not be changed in "+this.getClass().getSimpleName());
}
+
+ @Override
+ public HSSFShape cloneShape() {
+ TextObjectRecord txo = (TextObjectRecord) getTextObjectRecord().cloneViaReserialise();
+ EscherContainerRecord spContainer = new EscherContainerRecord();
+ byte [] inSp = getEscherContainer().serialize();
+ spContainer.fillFields(inSp, 0, new DefaultEscherRecordFactory());
+ ObjRecord obj = (ObjRecord) getObjRecord().cloneViaReserialise();
+ return new HSSFTextbox(spContainer, obj, txo);
+ }
}
@Override\r
void afterInsert(HSSFPatriarch patriarch) {\r
}\r
+\r
+ @Override\r
+ public HSSFShape cloneShape() {\r
+ return null;\r
+ }\r
}\r
names.add(newName);
}
// TODO - maybe same logic required for other/all built-in name records
- workbook.cloneDrawings(clonedSheet.getSheet());
+// workbook.cloneDrawings(clonedSheet.getSheet());
return clonedSheet;
}
}\r
}\r
\r
- public void testBuildBaseTree(){\r
- HSSFWorkbook wb = new HSSFWorkbook();\r
- HSSFSheet sheet = wb.createSheet();\r
- HSSFPatriarch patriarch = sheet.createDrawingPatriarch();\r
- EscherAggregate agg = HSSFTestHelper.getEscherAggregate(patriarch);\r
- EscherAggregate agg1 = new EscherAggregate(new HSSFTestHelper.MockDrawingManager());\r
- EscherSpgrRecord spgr = new EscherSpgrRecord();\r
- spgr.setRectY1(0);\r
- spgr.setRectY2(255);\r
- spgr.setRectX1(0);\r
- spgr.setRectX2(1023);\r
- EscherContainerRecord spContainer = new EscherContainerRecord();\r
- spContainer.addChildRecord(spgr);\r
- EscherContainerRecord spgrContainer = new EscherContainerRecord();\r
- spgrContainer.addChildRecord(spContainer);\r
- EscherContainerRecord dgContainer = new EscherContainerRecord();\r
- dgContainer.addChildRecord(spgrContainer);\r
- agg1.addEscherRecord(dgContainer);\r
- agg1.setPatriarch(HSSFTestHelper.createTestPatriarch(sheet, agg1));\r
- agg1.clear();\r
- HSSFTestHelper.callConvertPatriarch(agg1);\r
- agg1.setPatriarch(null);\r
-\r
- agg.setPatriarch(null);\r
-//\r
- EscherSpRecord sp = (EscherSpRecord) agg.getEscherContainer().getChildContainers().get(0).getChild(0).getChild(1);\r
- sp.setShapeId(1025);\r
- EscherDgRecord dg = (EscherDgRecord) agg.getEscherContainer().getChild(0);\r
- dg.setNumShapes(1);\r
- dg.setOptions((short) (1 << 4));\r
-\r
- byte[] aggS = agg.serialize();\r
- byte []agg1S = agg1.serialize();\r
-\r
- assertEquals(aggS.length, agg1S.length);\r
- assertTrue(Arrays.equals(aggS, agg1S));\r
- }\r
-\r
-\r
-\r
/**\r
* when reading incomplete data ensure that the serialized bytes\r
match the source\r
shape.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);\r
\r
EscherAggregate agg = HSSFTestHelper.getEscherAggregate(patriarch);\r
- assertNull(shape.getEscherContainer().getChildById(EscherTextboxRecord.RECORD_ID));\r
- assertEquals(agg.getShapeToObjMapping().size(), 1);\r
+ assertEquals(agg.getShapeToObjMapping().size(), 2);\r
\r
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);\r
sheet = wb.getSheetAt(0);\r
shape = (HSSFSimpleShape) patriarch.getChildren().get(0);\r
\r
agg = HSSFTestHelper.getEscherAggregate(patriarch);\r
- assertNull(shape.getEscherContainer().getChildById(EscherTextboxRecord.RECORD_ID));\r
- assertEquals(agg.getShapeToObjMapping().size(), 1);\r
+ assertEquals(agg.getShapeToObjMapping().size(), 2);\r
\r
shape.setString(new HSSFRichTextString("string1"));\r
assertEquals(shape.getString().getString(), "string1");\r
}
}
- public static void callConvertPatriarch(EscherAggregate agg) {
- Method method = null;
- try {
- method = agg.getClass().getDeclaredMethod("convertPatriarch", HSSFPatriarch.class);
- method.setAccessible(true);
- method.invoke(agg, agg.getPatriarch());
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- } catch (NoSuchMethodException e) {
- e.printStackTrace();
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- }
- }
-
public static void setShapeId(HSSFShape shape, int id){
shape.setShapeId(id);
}
import junit.framework.TestCase;
+import org.apache.poi.ddf.EscherDgRecord;
+import org.apache.poi.ddf.EscherSpRecord;
+import org.apache.poi.hssf.record.EscherAggregate;
import org.apache.poi.ss.util.CellRangeAddress;
+import java.io.IOException;
+import java.util.Arrays;
+
/**
* Test the ability to clone a sheet.
* If adding new records that belong to a sheet (as opposed to a book)
assertTrue("Row 3 still should be broken", clone.isRowBroken(3));
}
+
+ public void testCloneSheetWithoutDrawings(){
+ HSSFWorkbook b = new HSSFWorkbook();
+ HSSFSheet s = b.createSheet("Test");
+ HSSFSheet s2 = s.cloneSheet(b);
+
+ assertNull(s.getDrawingPatriarch());
+ assertNull(s2.getDrawingPatriarch());
+ assertEquals(HSSFTestHelper.getSheetForTest(s).getRecords().size(), HSSFTestHelper.getSheetForTest(s2).getRecords().size());
+ }
+
+ public void testCloneSheetWithEmptyDrawingAggregate(){
+ HSSFWorkbook b = new HSSFWorkbook();
+ HSSFSheet s = b.createSheet("Test");
+ HSSFPatriarch patriarch = s.createDrawingPatriarch();
+
+ EscherAggregate agg1 = patriarch._getBoundAggregate();
+
+ HSSFSheet s2 = s.cloneSheet(b);
+
+ patriarch = s2.getDrawingPatriarch();
+
+ EscherAggregate agg2 = patriarch._getBoundAggregate();
+
+ EscherSpRecord sp1 = (EscherSpRecord) agg1.getEscherContainer().getChild(1).getChild(0).getChild(1);
+ EscherSpRecord sp2 = (EscherSpRecord) agg2.getEscherContainer().getChild(1).getChild(0).getChild(1);
+
+ assertEquals(sp1.getShapeId(), 1024);
+ assertEquals(sp2.getShapeId(), 2048);
+
+ EscherDgRecord dg = (EscherDgRecord) agg2.getEscherContainer().getChild(0);
+
+ assertEquals(dg.getLastMSOSPID(), 2048);
+ assertEquals(dg.getInstance(), 0x2);
+
+ //everything except id and DgRecord.lastMSOSPID and DgRecord.Instance must be the same
+
+ sp2.setShapeId(1024);
+ dg.setLastMSOSPID(1024);
+ dg.setInstance((short) 0x1);
+
+ assertEquals(agg1.serialize().length, agg2.serialize().length);
+ assertEquals(agg1.toXml(""), agg2.toXml(""));
+ assertTrue(Arrays.equals(agg1.serialize(), agg2.serialize()));
+ }
+
+ public void testCloneComment() throws IOException {
+ HSSFWorkbook wb = new HSSFWorkbook();
+ HSSFSheet sh = wb.createSheet();
+ HSSFPatriarch p = sh.createDrawingPatriarch();
+ HSSFComment c = p.createComment(new HSSFClientAnchor(0,0,100,100, (short) 0,0,(short)5,5));
+ c.setColumn(1);
+ c.setRow(2);
+ c.setString(new HSSFRichTextString("qwertyuio"));
+
+ HSSFSheet sh2 = wb.cloneSheet(0);
+ HSSFPatriarch p2 = sh2.getDrawingPatriarch();
+ HSSFComment c2 = (HSSFComment) p2.getChildren().get(0);
+
+ assertTrue(Arrays.equals(c2.getTextObjectRecord().serialize(), c.getTextObjectRecord().serialize()));
+ assertTrue(Arrays.equals(c2.getObjRecord().serialize(), c.getObjRecord().serialize()));
+ assertTrue(Arrays.equals(c2.getNoteRecord().serialize(), c.getNoteRecord().serialize()));
+
+
+ //everything except spRecord.shapeId must be the same
+ assertFalse(Arrays.equals(c2.getEscherContainer().serialize(), c.getEscherContainer().serialize()));
+ EscherSpRecord sp = (EscherSpRecord) c2.getEscherContainer().getChild(0);
+ sp.setShapeId(1025);
+ assertTrue(Arrays.equals(c2.getEscherContainer().serialize(), c.getEscherContainer().serialize()));
+ }
}
\r
ObjRecord obj = comment.getObjRecord();\r
ObjRecord objShape = commentShape.getObjRecord();\r
+ /**shapeId = 1025 % 1024**/\r
+ ((CommonObjectDataSubRecord)objShape.getSubRecords().get(0)).setObjectId(1);\r
\r
expected = obj.serialize();\r
actual = objShape.serialize();\r
\r
NoteRecord note = comment.getNoteRecord();\r
NoteRecord noteShape = commentShape.getNoteRecord();\r
+ noteShape.setShapeId(1);\r
\r
expected = note.serialize();\r
actual = noteShape.serialize();\r
comment.setShapeId(2024);\r
/**\r
* SpRecord.id == shapeId\r
- * ObjRecord.id == shapeId - 1024\r
- * NoteRecord.id == ObjectRecord.id == shapeId - 1024\r
+ * ObjRecord.id == shapeId % 1024\r
+ * NoteRecord.id == ObjectRecord.id == shapeId % 1024\r
*/\r
\r
assertEquals(comment.getShapeId(), 2024);\r
\r
CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) comment.getObjRecord().getSubRecords().get(0);\r
- assertEquals(cod.getObjectId(), 2024);\r
+ assertEquals(cod.getObjectId(), 1000);\r
EscherSpRecord spRecord = (EscherSpRecord) comment.getEscherContainer().getChild(0);\r
assertEquals(spRecord.getShapeId(), 2024);\r
assertEquals(comment.getShapeId(), 2024);\r
- assertEquals(comment.getNoteRecord().getShapeId(), 2024);\r
+ assertEquals(comment.getNoteRecord().getShapeId(), 1000);\r
}\r
}\r
HSSFSheet sheet2 = wb2.getSheetAt(1);
//check that id of the drawing group was updated
- EscherDgRecord dg1 = (EscherDgRecord)sheet1.getDrawingEscherAggregate().findFirstWithId(EscherDgRecord.RECORD_ID);
- EscherDgRecord dg2 = (EscherDgRecord)sheet2.getDrawingEscherAggregate().findFirstWithId(EscherDgRecord.RECORD_ID);
+ EscherDgRecord dg1 = (EscherDgRecord)sheet1.getDrawingPatriarch()._getBoundAggregate().findFirstWithId(EscherDgRecord.RECORD_ID);
+ EscherDgRecord dg2 = (EscherDgRecord)sheet2.getDrawingPatriarch()._getBoundAggregate().findFirstWithId(EscherDgRecord.RECORD_ID);
int dg_id_1 = dg1.getOptions() >> 4;
int dg_id_2 = dg2.getOptions() >> 4;
assertEquals(dg_id_1 + 1, dg_id_2);
*/\r
public class TestShapeGroup extends TestCase{\r
\r
- public void testResultEqualsToAbstractShape() {\r
- HSSFWorkbook wb = new HSSFWorkbook();\r
- HSSFSheet sheet = wb.createSheet();\r
- HSSFPatriarch patriarch = sheet.createDrawingPatriarch();\r
- HSSFShapeGroup group = patriarch.createGroup(new HSSFClientAnchor());\r
-\r
- EscherContainerRecord container = new EscherContainerRecord();\r
- Map shapeToObj = new HashMap();\r
- HSSFTestHelper.convertHSSFGroup(group, container, shapeToObj);\r
-\r
- byte [] actual = group.getEscherContainer().serialize();\r
- byte [] expected = container.getChild(0).serialize();\r
-\r
- assertEquals(actual.length, expected.length);\r
- assertTrue(Arrays.equals(actual, expected));\r
-\r
- actual = group.getObjRecord().serialize();\r
- expected = ((ObjRecord)shapeToObj.values().toArray()[0]).serialize();\r
-\r
- assertEquals(actual.length, expected.length);\r
- assertTrue(Arrays.equals(actual, expected));\r
- }\r
-\r
public void testSetGetCoordinates(){\r
HSSFWorkbook wb = new HSSFWorkbook();\r
HSSFSheet sh = wb.createSheet();\r