From b38caa4cee44ad5c4e26a441ac18a121057e7300 Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Tue, 15 Jan 2008 16:31:29 +0000 Subject: [PATCH] Some more updates to the records->usermodel support for hssf shapes. Still not enough there to be useful to pretty much anyone, but at least there's now a framework in place that people can use if they want to support more, and some tests git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@612148 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/ddf/EscherContainerRecord.java | 68 +++++- .../poi/hssf/model/DrawingManager2.java | 13 +- .../poi/hssf/record/EscherAggregate.java | 129 +++++++++++ .../poi/hssf/usermodel/HSSFPatriarch.java | 6 + .../poi/hssf/usermodel/HSSFShapeGroup.java | 5 +- .../apache/poi/hssf/usermodel/HSSFSheet.java | 16 +- .../poi/ddf/TestEscherContainerRecord.java | 48 +++- .../hssf/usermodel/TestEscherGraphics.java | 216 +++++++++++++++++- .../poi/hssf/usermodel/TestHSSFWorkbook.java | 14 ++ 9 files changed, 483 insertions(+), 32 deletions(-) diff --git a/src/java/org/apache/poi/ddf/EscherContainerRecord.java b/src/java/org/apache/poi/ddf/EscherContainerRecord.java index 05ee6b096f..fc1442be94 100644 --- a/src/java/org/apache/poi/ddf/EscherContainerRecord.java +++ b/src/java/org/apache/poi/ddf/EscherContainerRecord.java @@ -100,11 +100,47 @@ public class EscherContainerRecord extends EscherRecord } return 8 + childRecordsSize; } + + /** + * Do any of our (top level) children have the + * given recordId? + */ + public boolean hasChildOfType(short recordId) { + for ( Iterator iterator = getChildRecords().iterator(); iterator.hasNext(); ) + { + EscherRecord r = (EscherRecord) iterator.next(); + if(r.getRecordId() == recordId) { + return true; + } + } + return false; + } + /** + * Returns a list of all the child (escher) records + * of the container. + */ public List getChildRecords() { return childRecords; } + + /** + * Returns all of our children which are also + * EscherContainers (may be 0, 1, or vary rarely + * 2 or 3) + */ + public List getChildContainers() { + List containers = new ArrayList(); + for ( Iterator iterator = getChildRecords().iterator(); iterator.hasNext(); ) + { + EscherRecord r = (EscherRecord) iterator.next(); + if(r instanceof EscherContainerRecord) { + containers.add(r); + } + } + return containers; + } public void setChildRecords( List childRecords ) { @@ -148,6 +184,10 @@ public class EscherContainerRecord extends EscherRecord } public String toString() + { + return toString(""); + } + public String toString(String indent) { String nl = System.getProperty( "line.separator" ); @@ -155,20 +195,32 @@ public class EscherContainerRecord extends EscherRecord if ( getChildRecords().size() > 0 ) { children.append( " children: " + nl ); + + int count = 0; for ( Iterator iterator = getChildRecords().iterator(); iterator.hasNext(); ) { + String newIndent = indent + " "; + EscherRecord record = (EscherRecord) iterator.next(); - children.append( record.toString() ); -// children.append( nl ); + children.append(newIndent + "Child " + count + ":\n"); + + if(record instanceof EscherContainerRecord) { + EscherContainerRecord ecr = (EscherContainerRecord)record; + children.append( ecr.toString(newIndent)); + } else { + children.append( record.toString() ); + } + count++; } } - return getClass().getName() + " (" + getRecordName() + "):" + nl + - " isContainer: " + isContainerRecord() + nl + - " options: 0x" + HexDump.toHex( getOptions() ) + nl + - " recordId: 0x" + HexDump.toHex( getRecordId() ) + nl + - " numchildren: " + getChildRecords().size() + nl + - children.toString(); + return + indent + getClass().getName() + " (" + getRecordName() + "):" + nl + + indent + " isContainer: " + isContainerRecord() + nl + + indent + " options: 0x" + HexDump.toHex( getOptions() ) + nl + + indent + " recordId: 0x" + HexDump.toHex( getRecordId() ) + nl + + indent + " numchildren: " + getChildRecords().size() + nl + + indent + children.toString(); } diff --git a/src/java/org/apache/poi/hssf/model/DrawingManager2.java b/src/java/org/apache/poi/hssf/model/DrawingManager2.java index f14d62ff31..dee95fb4fc 100644 --- a/src/java/org/apache/poi/hssf/model/DrawingManager2.java +++ b/src/java/org/apache/poi/hssf/model/DrawingManager2.java @@ -39,6 +39,13 @@ public class DrawingManager2 { this.dgg = dgg; } + + /** + * Clears the cached list of drawing groups + */ + public void clearDrawingGroups() { + drawingGroups.clear(); + } public EscherDgRecord createDgRecord() { @@ -93,9 +100,13 @@ public class DrawingManager2 } //////////// Non-public methods ///////////// + + /** + * Finds the next available (1 based) drawing group id + */ short findNewDrawingGroupId() { - short dgId = 1; + short dgId = 1; while ( drawingGroupExists( dgId ) ) dgId++; return dgId; diff --git a/src/java/org/apache/poi/hssf/record/EscherAggregate.java b/src/java/org/apache/poi/hssf/record/EscherAggregate.java index 4f5d18c239..d62b59adbb 100644 --- a/src/java/org/apache/poi/hssf/record/EscherAggregate.java +++ b/src/java/org/apache/poi/hssf/record/EscherAggregate.java @@ -24,6 +24,8 @@ import org.apache.poi.hssf.model.TextboxShape; import org.apache.poi.hssf.model.DrawingManager2; import org.apache.poi.hssf.model.ConvertAnchor; import org.apache.poi.hssf.model.CommentShape; +import org.apache.poi.util.POILogFactory; +import org.apache.poi.util.POILogger; import java.util.*; @@ -47,6 +49,7 @@ import java.util.*; public class EscherAggregate extends AbstractEscherHolderRecord { public static final short sid = 9876; + private static POILogger log = POILogFactory.getLogger(EscherAggregate.class); public static final short ST_MIN = (short) 0; public static final short ST_NOT_PRIMATIVE = ST_MIN; @@ -533,8 +536,134 @@ public class EscherAggregate extends AbstractEscherHolderRecord 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 = + (EscherContainerRecord)getEscherContainer(); + if(topContainer == null) { + return; + } + topContainer = (EscherContainerRecord) + 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 it = patriachContainer.getChildRecords().iterator(); it.hasNext();) { + EscherRecord r = (EscherRecord)it.next(); + if(r instanceof EscherSpgrRecord) { + spgr = (EscherSpgrRecord)r; + break; + } + } + if(spgr != null) { + patriarch.setCoordinates( + spgr.getRectX1(), spgr.getRectY1(), + spgr.getRectX2(), spgr.getRectY2() + ); + } + + // Now process the containers for each group + // and objects + for(int i=1; i