implemented cloning of shapes
git-svn-id: https://svn.apache.org/repos/asf/poi/branches/gsoc2012@1363479 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
57f0fe06b9
commit
426ef18c61
@ -354,9 +354,9 @@ public final class InternalSheet {
|
||||
// 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);
|
||||
|
@ -22,27 +22,16 @@ import java.io.IOException;
|
||||
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;
|
||||
@ -313,8 +302,6 @@ public final class EscherAggregate extends AbstractEscherHolderRecord {
|
||||
* 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
|
||||
@ -326,11 +313,6 @@ public final class EscherAggregate extends AbstractEscherHolderRecord {
|
||||
}
|
||||
|
||||
public EscherAggregate(DrawingManager2 drawingManager) {
|
||||
this.drawingManager = drawingManager;
|
||||
}
|
||||
|
||||
public DrawingManager2 getDrawingManager() {
|
||||
return drawingManager;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -458,8 +440,6 @@ public final class EscherAggregate extends AbstractEscherHolderRecord {
|
||||
// replace drawing block with the created EscherAggregate
|
||||
records.subList(locFirstDrawingRecord, locLastDrawingRecord).clear();
|
||||
records.add(locFirstDrawingRecord, agg);
|
||||
|
||||
|
||||
return agg;
|
||||
}
|
||||
|
||||
@ -472,14 +452,11 @@ public final class EscherAggregate extends AbstractEscherHolderRecord {
|
||||
* @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();
|
||||
@ -594,8 +571,6 @@ public final class EscherAggregate extends AbstractEscherHolderRecord {
|
||||
}
|
||||
|
||||
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;
|
||||
@ -657,249 +632,6 @@ public final class EscherAggregate extends AbstractEscherHolderRecord {
|
||||
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();
|
||||
@ -916,133 +648,6 @@ public final class EscherAggregate extends AbstractEscherHolderRecord {
|
||||
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();
|
||||
@ -1067,7 +672,6 @@ public final class EscherAggregate extends AbstractEscherHolderRecord {
|
||||
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);
|
||||
@ -1105,46 +709,6 @@ public final class EscherAggregate extends AbstractEscherHolderRecord {
|
||||
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();
|
||||
}
|
||||
|
@ -18,6 +18,11 @@ public class HSSFCombobox extends HSSFSimpleShape {
|
||||
super.setShapeType(OBJECT_TYPE_COMBO_BOX);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TextObjectRecord createTextObjRecord() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EscherContainerRecord createSpContainer() {
|
||||
EscherContainerRecord spContainer = new EscherContainerRecord();
|
||||
|
@ -70,7 +70,7 @@ public class HSSFComment extends HSSFTextbox implements Comment {
|
||||
@Override
|
||||
void afterInsert(HSSFPatriarch patriarch) {
|
||||
super.afterInsert(patriarch);
|
||||
_patriarch._getBoundAggregate().addTailRecord(getNoteRecord());
|
||||
patriarch._getBoundAggregate().addTailRecord(getNoteRecord());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -113,8 +113,8 @@ public class HSSFComment extends HSSFTextbox implements Comment {
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -214,4 +214,15 @@ public class HSSFComment extends HSSFTextbox implements Comment {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -21,22 +21,20 @@ package org.apache.poi.hssf.usermodel;
|
||||
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.
|
||||
*/
|
||||
@ -56,7 +54,7 @@ public final class HSSFObjectData extends HSSFShape{
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@ -76,8 +74,8 @@ public final class HSSFObjectData extends HSSFShape{
|
||||
|
||||
/**
|
||||
* 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();
|
||||
@ -85,7 +83,7 @@ public final class HSSFObjectData extends HSSFShape{
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
@ -98,7 +96,7 @@ public final class HSSFObjectData extends HSSFShape{
|
||||
|
||||
/**
|
||||
* 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();
|
||||
@ -106,7 +104,7 @@ public final class HSSFObjectData extends HSSFShape{
|
||||
while (subRecordIter.hasNext()) {
|
||||
Object subRecord = subRecordIter.next();
|
||||
if (subRecord instanceof EmbeddedObjectRefSubRecord) {
|
||||
return (EmbeddedObjectRefSubRecord)subRecord;
|
||||
return (EmbeddedObjectRefSubRecord) subRecord;
|
||||
}
|
||||
}
|
||||
|
||||
@ -130,6 +128,39 @@ public final class HSSFObjectData extends HSSFShape{
|
||||
|
||||
@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));
|
||||
}
|
||||
}
|
||||
|
@ -38,10 +38,6 @@ import org.apache.poi.ss.usermodel.ClientAnchor;
|
||||
*/
|
||||
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;
|
||||
@ -49,19 +45,19 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
|
||||
/**
|
||||
* 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);
|
||||
@ -69,17 +65,36 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
|
||||
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);
|
||||
@ -90,12 +105,11 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
|
||||
/**
|
||||
* 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);
|
||||
@ -106,21 +120,20 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
|
||||
* 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;
|
||||
@ -129,42 +142,39 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
|
||||
/**
|
||||
* 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);
|
||||
@ -174,12 +184,11 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
|
||||
/**
|
||||
* 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);
|
||||
@ -189,12 +198,11 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
|
||||
/**
|
||||
* 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);
|
||||
@ -206,23 +214,21 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
|
||||
@ -230,23 +236,21 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -254,17 +258,18 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
|
||||
*/
|
||||
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);
|
||||
@ -282,28 +287,28 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
@ -315,32 +320,28 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
|
||||
@ -365,26 +366,26 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
|
||||
* @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());
|
||||
|
@ -22,6 +22,7 @@ import java.io.ByteArrayInputStream;
|
||||
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;
|
||||
@ -88,6 +89,7 @@ public final class HSSFPicture extends HSSFSimpleShape implements Picture {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -250,7 +252,8 @@ public final class HSSFPicture extends HSSFSimpleShape implements Picture {
|
||||
|
||||
@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);
|
||||
@ -285,4 +288,13 @@ public final class HSSFPicture extends HSSFSimpleShape implements Picture {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -18,19 +18,20 @@
|
||||
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);
|
||||
}
|
||||
@ -39,6 +40,11 @@ public class HSSFPolygon extends HSSFShape {
|
||||
super(parent, anchor);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TextObjectRecord createTextObjRecord() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the shape records for this shape.
|
||||
*/
|
||||
@ -200,10 +206,4 @@ public class HSSFPolygon extends HSSFShape {
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
@ -302,4 +302,6 @@ public abstract class HSSFShape {
|
||||
public int countOfAllChildren() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public abstract HSSFShape cloneShape();
|
||||
}
|
||||
|
@ -74,8 +74,12 @@ public class HSSFShapeFactory {
|
||||
|
||||
public static void createShapeTree(EscherContainerRecord container, EscherAggregate agg, HSSFShapeContainer out, DirectoryNode root) {
|
||||
if (container.getRecordId() == EscherContainerRecord.SPGR_CONTAINER) {
|
||||
HSSFShapeGroup group = new HSSFShapeGroup(container,
|
||||
null /* shape containers don't have a associated Obj record*/);
|
||||
ObjRecord obj = null;
|
||||
EscherClientDataRecord clientData = ((EscherContainerRecord)container.getChild(0)).getChildById(EscherClientDataRecord.RECORD_ID);
|
||||
if (null != clientData){
|
||||
obj = (ObjRecord) agg.getShapeToObjMapping().get(clientData);
|
||||
}
|
||||
HSSFShapeGroup group = new HSSFShapeGroup(container, obj);
|
||||
List<EscherContainerRecord> children = container.getChildContainers();
|
||||
// skip the first child record, it is group descriptor
|
||||
for (int i = 0; i < children.size(); i++) {
|
||||
@ -130,7 +134,7 @@ public class HSSFShapeFactory {
|
||||
EscherOptRecord optRecord = container.getChildById(EscherOptRecord.RECORD_ID);
|
||||
EscherProperty property = optRecord.lookup(EscherProperties.GEOMETRY__VERTICES);
|
||||
if (null != property) {
|
||||
shape = new HSSFPolygon(container, objRecord);
|
||||
shape = new HSSFPolygon(container, objRecord, txtRecord);
|
||||
} else {
|
||||
shape = new HSSFSimpleShape(container, objRecord);
|
||||
}
|
||||
|
@ -127,13 +127,18 @@ public class HSSFShapeGroup extends HSSFShape implements HSSFShapeContainer {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -312,7 +317,7 @@ public class HSSFShapeGroup extends HSSFShape implements HSSFShapeContainer {
|
||||
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
|
||||
@ -320,4 +325,39 @@ public class HSSFShapeGroup extends HSSFShape implements HSSFShapeContainer {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -115,7 +115,15 @@ public final class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet {
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -68,14 +68,13 @@ public class HSSFSimpleShape extends HSSFShape
|
||||
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)
|
||||
@ -92,6 +91,7 @@ public class HSSFSimpleShape extends HSSFShape
|
||||
TextObjectRecord obj = new TextObjectRecord();
|
||||
obj.setTextLocked(true);
|
||||
obj.setTextOrientation(TextObjectRecord.TEXT_ORIENTATION_NONE);
|
||||
obj.setStr(new HSSFRichTextString(""));
|
||||
return obj;
|
||||
}
|
||||
|
||||
@ -123,10 +123,15 @@ public class HSSFSimpleShape extends HSSFShape
|
||||
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;
|
||||
}
|
||||
|
||||
@ -167,21 +172,6 @@ public class HSSFSimpleShape extends HSSFShape
|
||||
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);
|
||||
}
|
||||
|
||||
@ -189,6 +179,24 @@ public class HSSFSimpleShape extends HSSFShape
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -235,4 +235,14 @@ public class HSSFTextbox extends HSSFSimpleShape {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -48,4 +48,9 @@ public class HSSFUnknownShape extends HSSFShape {
|
||||
@Override
|
||||
void afterInsert(HSSFPatriarch patriarch) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public HSSFShape cloneShape() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -701,7 +701,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
|
||||
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;
|
||||
}
|
||||
|
@ -194,46 +194,6 @@ public class TestDrawingAggregate extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public void testBuildBaseTree(){
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sheet = wb.createSheet();
|
||||
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
|
||||
EscherAggregate agg = HSSFTestHelper.getEscherAggregate(patriarch);
|
||||
EscherAggregate agg1 = new EscherAggregate(new HSSFTestHelper.MockDrawingManager());
|
||||
EscherSpgrRecord spgr = new EscherSpgrRecord();
|
||||
spgr.setRectY1(0);
|
||||
spgr.setRectY2(255);
|
||||
spgr.setRectX1(0);
|
||||
spgr.setRectX2(1023);
|
||||
EscherContainerRecord spContainer = new EscherContainerRecord();
|
||||
spContainer.addChildRecord(spgr);
|
||||
EscherContainerRecord spgrContainer = new EscherContainerRecord();
|
||||
spgrContainer.addChildRecord(spContainer);
|
||||
EscherContainerRecord dgContainer = new EscherContainerRecord();
|
||||
dgContainer.addChildRecord(spgrContainer);
|
||||
agg1.addEscherRecord(dgContainer);
|
||||
agg1.setPatriarch(HSSFTestHelper.createTestPatriarch(sheet, agg1));
|
||||
agg1.clear();
|
||||
HSSFTestHelper.callConvertPatriarch(agg1);
|
||||
agg1.setPatriarch(null);
|
||||
|
||||
agg.setPatriarch(null);
|
||||
//
|
||||
EscherSpRecord sp = (EscherSpRecord) agg.getEscherContainer().getChildContainers().get(0).getChild(0).getChild(1);
|
||||
sp.setShapeId(1025);
|
||||
EscherDgRecord dg = (EscherDgRecord) agg.getEscherContainer().getChild(0);
|
||||
dg.setNumShapes(1);
|
||||
dg.setOptions((short) (1 << 4));
|
||||
|
||||
byte[] aggS = agg.serialize();
|
||||
byte []agg1S = agg1.serialize();
|
||||
|
||||
assertEquals(aggS.length, agg1S.length);
|
||||
assertTrue(Arrays.equals(aggS, agg1S));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* when reading incomplete data ensure that the serialized bytes
|
||||
match the source
|
||||
|
@ -352,8 +352,7 @@ public class TestDrawingShapes extends TestCase {
|
||||
shape.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);
|
||||
|
||||
EscherAggregate agg = HSSFTestHelper.getEscherAggregate(patriarch);
|
||||
assertNull(shape.getEscherContainer().getChildById(EscherTextboxRecord.RECORD_ID));
|
||||
assertEquals(agg.getShapeToObjMapping().size(), 1);
|
||||
assertEquals(agg.getShapeToObjMapping().size(), 2);
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sheet = wb.getSheetAt(0);
|
||||
@ -362,8 +361,7 @@ public class TestDrawingShapes extends TestCase {
|
||||
shape = (HSSFSimpleShape) patriarch.getChildren().get(0);
|
||||
|
||||
agg = HSSFTestHelper.getEscherAggregate(patriarch);
|
||||
assertNull(shape.getEscherContainer().getChildById(EscherTextboxRecord.RECORD_ID));
|
||||
assertEquals(agg.getShapeToObjMapping().size(), 1);
|
||||
assertEquals(agg.getShapeToObjMapping().size(), 2);
|
||||
|
||||
shape.setString(new HSSFRichTextString("string1"));
|
||||
assertEquals(shape.getString().getString(), "string1");
|
||||
|
@ -101,21 +101,6 @@ public class HSSFTestHelper {
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -19,8 +19,14 @@ package org.apache.poi.hssf.usermodel;
|
||||
|
||||
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)
|
||||
@ -55,4 +61,74 @@ public final class TestCloneSheet extends TestCase {
|
||||
|
||||
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()));
|
||||
}
|
||||
}
|
||||
|
@ -58,6 +58,8 @@ public class TestComment extends TestCase {
|
||||
|
||||
ObjRecord obj = comment.getObjRecord();
|
||||
ObjRecord objShape = commentShape.getObjRecord();
|
||||
/**shapeId = 1025 % 1024**/
|
||||
((CommonObjectDataSubRecord)objShape.getSubRecords().get(0)).setObjectId(1);
|
||||
|
||||
expected = obj.serialize();
|
||||
actual = objShape.serialize();
|
||||
@ -76,6 +78,7 @@ public class TestComment extends TestCase {
|
||||
|
||||
NoteRecord note = comment.getNoteRecord();
|
||||
NoteRecord noteShape = commentShape.getNoteRecord();
|
||||
noteShape.setShapeId(1);
|
||||
|
||||
expected = note.serialize();
|
||||
actual = noteShape.serialize();
|
||||
@ -225,17 +228,17 @@ public class TestComment extends TestCase {
|
||||
comment.setShapeId(2024);
|
||||
/**
|
||||
* SpRecord.id == shapeId
|
||||
* ObjRecord.id == shapeId - 1024
|
||||
* NoteRecord.id == ObjectRecord.id == shapeId - 1024
|
||||
* ObjRecord.id == shapeId % 1024
|
||||
* NoteRecord.id == ObjectRecord.id == shapeId % 1024
|
||||
*/
|
||||
|
||||
assertEquals(comment.getShapeId(), 2024);
|
||||
|
||||
CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) comment.getObjRecord().getSubRecords().get(0);
|
||||
assertEquals(cod.getObjectId(), 2024);
|
||||
assertEquals(cod.getObjectId(), 1000);
|
||||
EscherSpRecord spRecord = (EscherSpRecord) comment.getEscherContainer().getChild(0);
|
||||
assertEquals(spRecord.getShapeId(), 2024);
|
||||
assertEquals(comment.getShapeId(), 2024);
|
||||
assertEquals(comment.getNoteRecord().getShapeId(), 2024);
|
||||
assertEquals(comment.getNoteRecord().getShapeId(), 1000);
|
||||
}
|
||||
}
|
||||
|
@ -808,8 +808,8 @@ public final class TestHSSFSheet extends BaseTestSheet {
|
||||
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);
|
||||
|
@ -17,29 +17,6 @@ import java.util.Map;
|
||||
*/
|
||||
public class TestShapeGroup extends TestCase{
|
||||
|
||||
public void testResultEqualsToAbstractShape() {
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sheet = wb.createSheet();
|
||||
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
|
||||
HSSFShapeGroup group = patriarch.createGroup(new HSSFClientAnchor());
|
||||
|
||||
EscherContainerRecord container = new EscherContainerRecord();
|
||||
Map shapeToObj = new HashMap();
|
||||
HSSFTestHelper.convertHSSFGroup(group, container, shapeToObj);
|
||||
|
||||
byte [] actual = group.getEscherContainer().serialize();
|
||||
byte [] expected = container.getChild(0).serialize();
|
||||
|
||||
assertEquals(actual.length, expected.length);
|
||||
assertTrue(Arrays.equals(actual, expected));
|
||||
|
||||
actual = group.getObjRecord().serialize();
|
||||
expected = ((ObjRecord)shapeToObj.values().toArray()[0]).serialize();
|
||||
|
||||
assertEquals(actual.length, expected.length);
|
||||
assertTrue(Arrays.equals(actual, expected));
|
||||
}
|
||||
|
||||
public void testSetGetCoordinates(){
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sh = wb.createSheet();
|
||||
|
Loading…
Reference in New Issue
Block a user