merge GSoC code with trunk
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1371663 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
commit
c91082dc80
@ -632,6 +632,7 @@ under the License.
|
||||
<syspropertyset refid="junit.properties"/>
|
||||
<jvmarg value="${poi.test.locale}"/>
|
||||
<jvmarg value="-ea"/>
|
||||
<jvmarg value="-Xmx256m"/>
|
||||
<formatter type="plain"/>
|
||||
<batchtest todir="${main.reports.test}">
|
||||
<fileset dir="${main.src.test}">
|
||||
|
@ -16,10 +16,7 @@
|
||||
==================================================================== */
|
||||
package org.apache.poi.ddf;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
import org.apache.poi.util.HexDump;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
@ -139,6 +136,33 @@ public abstract class AbstractEscherOptRecord extends EscherRecord
|
||||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an escher property. If a property with given propId already
|
||||
exists it is replaced.
|
||||
*
|
||||
* @param value the property to set.
|
||||
*/
|
||||
public void setEscherProperty(EscherProperty value){
|
||||
for ( Iterator<EscherProperty> iterator =
|
||||
properties.iterator(); iterator.hasNext(); ) {
|
||||
EscherProperty prop = iterator.next();
|
||||
if (prop.getId() == value.getId()){
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
properties.add( value );
|
||||
sortProperties();
|
||||
}
|
||||
|
||||
public void removeEscherProperty(int num){
|
||||
for ( Iterator<EscherProperty> iterator = getEscherProperties().iterator(); iterator.hasNext(); ) {
|
||||
EscherProperty prop = iterator.next();
|
||||
if (prop.getPropertyNumber() == num){
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the string representation of this record.
|
||||
*/
|
||||
|
@ -65,8 +65,7 @@ public class DefaultEscherRecordFactory implements EscherRecordFactory {
|
||||
// However, EscherTextboxRecord are containers of records for the
|
||||
// host application, not of other Escher records, so treat them
|
||||
// differently
|
||||
if ( ( options & (short) 0x000F ) == (short) 0x000F
|
||||
&& recordId != EscherTextboxRecord.RECORD_ID ) {
|
||||
if (isContainer(options, recordId)) {
|
||||
EscherContainerRecord r = new EscherContainerRecord();
|
||||
r.setRecordId( recordId );
|
||||
r.setOptions( options );
|
||||
@ -145,4 +144,17 @@ public class DefaultEscherRecordFactory implements EscherRecordFactory {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static boolean isContainer(short options, short recordId){
|
||||
if(recordId >= EscherContainerRecord.DGG_CONTAINER && recordId
|
||||
<= EscherContainerRecord.SOLVER_CONTAINER){
|
||||
return true;
|
||||
} else {
|
||||
if (recordId == EscherTextboxRecord.RECORD_ID) {
|
||||
return false;
|
||||
} else {
|
||||
return ( options & (short) 0x000F ) == (short) 0x000F;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -62,6 +62,9 @@ public final class EscherArrayProperty extends EscherComplexProperty {
|
||||
}
|
||||
|
||||
public int getNumberOfElementsInArray() {
|
||||
if (emptyComplexPart){
|
||||
return 0;
|
||||
}
|
||||
return LittleEndian.getUShort(_complexData, 0);
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ public class EscherBoolProperty
|
||||
public String toXml(String tab){
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(tab).append("<").append(getClass().getSimpleName()).append(" id=\"0x").append(HexDump.toHex(getId()))
|
||||
.append("\" name=\"").append(getName()).append("\" blipId=\"")
|
||||
.append("\" name=\"").append(getName()).append("\" simpleValue=\"").append(getPropertyValue()).append("\" blipId=\"")
|
||||
.append(isBlipId()).append("\" value=\"").append(isTrue()).append("\"").append("/>\n");
|
||||
return builder.toString();
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
@ -38,6 +37,14 @@ public class EscherClientAnchorRecord
|
||||
public static final short RECORD_ID = (short) 0xF010;
|
||||
public static final String RECORD_DESCRIPTION = "MsofbtClientAnchor";
|
||||
|
||||
/**
|
||||
* bit[0] - fMove (1 bit): A bit that specifies whether the shape will be kept intact when the cells are moved.
|
||||
* bit[1] - fSize (1 bit): A bit that specifies whether the shape will be kept intact when the cells are resized. If fMove is 1, the value MUST be 1.
|
||||
* bit[2-4] - reserved, MUST be 0 and MUST be ignored
|
||||
* bit[5-15]- Undefined and MUST be ignored.
|
||||
*
|
||||
* it can take values: 0, 2, 3
|
||||
*/
|
||||
private short field_1_flag;
|
||||
private short field_2_col1;
|
||||
private short field_3_dx1;
|
||||
|
@ -25,6 +25,8 @@ import java.util.NoSuchElementException;
|
||||
|
||||
import org.apache.poi.util.HexDump;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
|
||||
/**
|
||||
* Escher container records store other escher records as children.
|
||||
@ -42,6 +44,32 @@ public final class EscherContainerRecord extends EscherRecord {
|
||||
public static final short SP_CONTAINER = (short)0xF004;
|
||||
public static final short SOLVER_CONTAINER = (short)0xF005;
|
||||
|
||||
private static POILogger log = POILogFactory.getLogger(EscherContainerRecord.class);
|
||||
|
||||
/**
|
||||
* in case if document contains any charts we have such document structure:
|
||||
* BOF
|
||||
* ...
|
||||
* DrawingRecord
|
||||
* ...
|
||||
* ObjRecord|TxtObjRecord
|
||||
* ...
|
||||
* EOF
|
||||
* ...
|
||||
* BOF(Chart begin)
|
||||
* ...
|
||||
* DrawingRecord
|
||||
* ...
|
||||
* ObjRecord|TxtObjRecord
|
||||
* ...
|
||||
* EOF
|
||||
* So, when we call EscherAggregate.createAggregate() we have not all needed data.
|
||||
* When we got warning "WARNING: " + bytesRemaining + " bytes remaining but no space left"
|
||||
* we should save value of bytesRemaining
|
||||
* and add it to container size when we serialize it
|
||||
*/
|
||||
private int _remainingLength;
|
||||
|
||||
private final List<EscherRecord> _childRecords = new ArrayList<EscherRecord>();
|
||||
|
||||
public int fillFields(byte[] data, int pOffset, EscherRecordFactory recordFactory) {
|
||||
@ -56,7 +84,8 @@ public final class EscherContainerRecord extends EscherRecord {
|
||||
bytesRemaining -= childBytesWritten;
|
||||
addChildRecord(child);
|
||||
if (offset >= data.length && bytesRemaining > 0) {
|
||||
System.out.println("WARNING: " + bytesRemaining + " bytes remaining but no space left");
|
||||
_remainingLength = bytesRemaining;
|
||||
log.log(POILogger.WARN, "Not enough Escher data: " + bytesRemaining + " bytes remaining but no space left");
|
||||
}
|
||||
}
|
||||
return bytesWritten;
|
||||
@ -74,6 +103,7 @@ public final class EscherContainerRecord extends EscherRecord {
|
||||
EscherRecord r = iterator.next();
|
||||
remainingBytes += r.getRecordSize();
|
||||
}
|
||||
remainingBytes += _remainingLength;
|
||||
LittleEndian.putInt(data, offset+4, remainingBytes);
|
||||
int pos = offset+8;
|
||||
iterator = _childRecords.iterator();
|
||||
|
@ -311,7 +311,7 @@ public abstract class EscherRecord {
|
||||
protected String formatXmlRecordHeader(String className, String recordId, String version, String instance){
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("<").append(className).append(" recordId=\"0x").append(recordId).append("\" version=\"0x")
|
||||
.append(version).append("\" instance=\"0x").append(instance).append("\">\n");
|
||||
.append(version).append("\" instance=\"0x").append(instance).append("\" size=\"").append(getRecordSize()).append("\">\n");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
|
@ -119,7 +119,7 @@ public class EscherSpRecord
|
||||
public String toXml(String tab) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(tab).append(formatXmlRecordHeader(getClass().getSimpleName(), HexDump.toHex(getRecordId()), HexDump.toHex(getVersion()), HexDump.toHex(getInstance())))
|
||||
.append(tab).append("\t").append("<ShapeType>").append(HexDump.toHex(getShapeType())).append("</ShapeType>\n")
|
||||
.append(tab).append("\t").append("<ShapeType>0x").append(HexDump.toHex(getShapeType())).append("</ShapeType>\n")
|
||||
.append(tab).append("\t").append("<ShapeId>").append(field_1_shapeId).append("</ShapeId>\n")
|
||||
.append(tab).append("\t").append("<Flags>").append(decodeFlags(field_2_flags) + " (0x" + HexDump.toHex(field_2_flags) + ")").append("</Flags>\n");
|
||||
builder.append(tab).append("</").append(getClass().getSimpleName()).append(">\n");
|
||||
|
63
src/java/org/apache/poi/hssf/dev/ReSave.java
Executable file
63
src/java/org/apache/poi/hssf/dev/ReSave.java
Executable file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.poi.hssf.dev;
|
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFPatriarch;
|
||||
import org.apache.poi.hssf.usermodel.HSSFShape;
|
||||
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
|
||||
/**
|
||||
* Utility to test that POI produces readable output
|
||||
* after re-saving xls files.
|
||||
*
|
||||
* Usage: ReSave [-dg] input.xls
|
||||
* -dg initialize drawings, causes to re-build escher aggregates in all sheets
|
||||
*/
|
||||
public class ReSave {
|
||||
public static void main(String[] args) throws Exception {
|
||||
boolean initDrawing = false;
|
||||
for(String arg : args) {
|
||||
if(arg.equals("-dg")) initDrawing = true;
|
||||
else {
|
||||
System.out.print("reading " + arg + "...");
|
||||
FileInputStream is = new FileInputStream(arg);
|
||||
HSSFWorkbook wb = new HSSFWorkbook(is);
|
||||
is.close();
|
||||
System.out.println("done");
|
||||
|
||||
for(int i = 0; i < wb.getNumberOfSheets(); i++){
|
||||
HSSFSheet sheet = wb.getSheetAt(i);
|
||||
if(initDrawing) {
|
||||
HSSFPatriarch dg = sheet.getDrawingPatriarch();
|
||||
}
|
||||
}
|
||||
|
||||
String outputFile = arg.replace(".xls", "-saved.xls");
|
||||
System.out.print("saving to " + outputFile + "...");
|
||||
FileOutputStream out = new FileOutputStream(outputFile);
|
||||
wb.write(out);
|
||||
out.close();
|
||||
System.out.println("done");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -26,6 +26,7 @@ import org.apache.poi.hssf.usermodel.*;
|
||||
*
|
||||
* @author Glen Stampoultzis (glens at apache.org)
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class AbstractShape
|
||||
{
|
||||
/**
|
||||
|
@ -27,6 +27,7 @@ import org.apache.poi.hssf.usermodel.*;
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
@Deprecated
|
||||
public class ComboboxShape
|
||||
extends AbstractShape {
|
||||
private EscherContainerRecord spContainer;
|
||||
|
@ -39,6 +39,7 @@ import org.apache.poi.hssf.usermodel.HSSFShape;
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
@Deprecated
|
||||
public final class CommentShape extends TextboxShape {
|
||||
|
||||
private NoteRecord _note;
|
||||
|
@ -112,7 +112,7 @@ public class DrawingManager2
|
||||
/**
|
||||
* Finds the next available (1 based) drawing group id
|
||||
*/
|
||||
short findNewDrawingGroupId()
|
||||
public short findNewDrawingGroupId()
|
||||
{
|
||||
short dgId = 1;
|
||||
while ( drawingGroupExists( dgId ) )
|
||||
@ -147,4 +147,7 @@ public class DrawingManager2
|
||||
return dgg;
|
||||
}
|
||||
|
||||
public void incrementDrawingsSaved(){
|
||||
dgg.setDrawingsSaved(dgg.getDrawingsSaved()+1);
|
||||
}
|
||||
}
|
||||
|
@ -21,43 +21,7 @@ import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.poi.hssf.record.BOFRecord;
|
||||
import org.apache.poi.hssf.record.CFHeaderRecord;
|
||||
import org.apache.poi.hssf.record.CalcCountRecord;
|
||||
import org.apache.poi.hssf.record.CalcModeRecord;
|
||||
import org.apache.poi.hssf.record.CellValueRecordInterface;
|
||||
import org.apache.poi.hssf.record.ColumnInfoRecord;
|
||||
import org.apache.poi.hssf.record.DVALRecord;
|
||||
import org.apache.poi.hssf.record.DefaultColWidthRecord;
|
||||
import org.apache.poi.hssf.record.DefaultRowHeightRecord;
|
||||
import org.apache.poi.hssf.record.DeltaRecord;
|
||||
import org.apache.poi.hssf.record.DimensionsRecord;
|
||||
import org.apache.poi.hssf.record.DrawingRecord;
|
||||
import org.apache.poi.hssf.record.EOFRecord;
|
||||
import org.apache.poi.hssf.record.EscherAggregate;
|
||||
import org.apache.poi.hssf.record.FeatHdrRecord;
|
||||
import org.apache.poi.hssf.record.FeatRecord;
|
||||
import org.apache.poi.hssf.record.GridsetRecord;
|
||||
import org.apache.poi.hssf.record.GutsRecord;
|
||||
import org.apache.poi.hssf.record.IndexRecord;
|
||||
import org.apache.poi.hssf.record.IterationRecord;
|
||||
import org.apache.poi.hssf.record.MergeCellsRecord;
|
||||
import org.apache.poi.hssf.record.NoteRecord;
|
||||
import org.apache.poi.hssf.record.ObjRecord;
|
||||
import org.apache.poi.hssf.record.PaneRecord;
|
||||
import org.apache.poi.hssf.record.PrintGridlinesRecord;
|
||||
import org.apache.poi.hssf.record.PrintHeadersRecord;
|
||||
import org.apache.poi.hssf.record.Record;
|
||||
import org.apache.poi.hssf.record.RecordBase;
|
||||
import org.apache.poi.hssf.record.RefModeRecord;
|
||||
import org.apache.poi.hssf.record.RowRecord;
|
||||
import org.apache.poi.hssf.record.SCLRecord;
|
||||
import org.apache.poi.hssf.record.SaveRecalcRecord;
|
||||
import org.apache.poi.hssf.record.SelectionRecord;
|
||||
import org.apache.poi.hssf.record.TextObjectRecord;
|
||||
import org.apache.poi.hssf.record.UncalcedRecord;
|
||||
import org.apache.poi.hssf.record.WSBoolRecord;
|
||||
import org.apache.poi.hssf.record.WindowTwoRecord;
|
||||
import org.apache.poi.hssf.record.*;
|
||||
import org.apache.poi.hssf.record.aggregates.ChartSubstreamRecordAggregate;
|
||||
import org.apache.poi.hssf.record.aggregates.ColumnInfoRecordsAggregate;
|
||||
import org.apache.poi.hssf.record.aggregates.ConditionalFormattingTable;
|
||||
@ -387,12 +351,10 @@ public final class InternalSheet {
|
||||
continue;
|
||||
}
|
||||
if (rb instanceof EscherAggregate){
|
||||
// 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()){
|
||||
continue;
|
||||
}
|
||||
/**
|
||||
* this record will be removed after reading actual data from EscherAggregate
|
||||
*/
|
||||
rb = new DrawingRecord();
|
||||
}
|
||||
Record rec = (Record) ((Record) rb).clone();
|
||||
clonedRecords.add(rec);
|
||||
@ -1523,6 +1485,7 @@ public final class InternalSheet {
|
||||
* if none currently exist
|
||||
* @param drawingManager The DrawingManager2 for our workbook
|
||||
* @param createIfMissing Should one be created if missing?
|
||||
* @return location of EscherAggregate record. if no EscherAggregate record is found return -1
|
||||
*/
|
||||
public int aggregateDrawingRecords(DrawingManager2 drawingManager, boolean createIfMissing) {
|
||||
int loc = findFirstRecordLocBySid(DrawingRecord.sid);
|
||||
@ -1533,7 +1496,7 @@ public final class InternalSheet {
|
||||
return -1;
|
||||
}
|
||||
|
||||
EscherAggregate aggregate = new EscherAggregate( drawingManager );
|
||||
EscherAggregate aggregate = new EscherAggregate();
|
||||
loc = findFirstRecordLocBySid(EscherAggregate.sid);
|
||||
if (loc == -1) {
|
||||
loc = findFirstRecordLocBySid( WindowTwoRecord.sid );
|
||||
@ -1544,23 +1507,10 @@ public final class InternalSheet {
|
||||
return loc;
|
||||
}
|
||||
List<RecordBase> records = getRecords();
|
||||
EscherAggregate r = EscherAggregate.createAggregate( records, loc, drawingManager );
|
||||
int startloc = loc;
|
||||
while ( loc + 1 < records.size()
|
||||
&& records.get( loc ) instanceof DrawingRecord
|
||||
&& (records.get( loc + 1 ) instanceof ObjRecord ||
|
||||
records.get( loc + 1 ) instanceof TextObjectRecord) )
|
||||
{
|
||||
loc += 2;
|
||||
if (records.get( loc ) instanceof NoteRecord) loc ++;
|
||||
}
|
||||
|
||||
int endloc = loc-1;
|
||||
for(int i = 0; i < (endloc - startloc + 1); i++)
|
||||
records.remove(startloc);
|
||||
records.add(startloc, r);
|
||||
EscherAggregate.createAggregate( records, loc, drawingManager );
|
||||
|
||||
return startloc;
|
||||
return loc;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -27,6 +27,7 @@ import org.apache.poi.hssf.usermodel.*;
|
||||
*
|
||||
* @author Glen Stampoultzis (glens at apache.org)
|
||||
*/
|
||||
@Deprecated
|
||||
public class LineShape
|
||||
extends AbstractShape
|
||||
{
|
||||
|
@ -27,6 +27,7 @@ import org.apache.poi.hssf.usermodel.HSSFShape;
|
||||
import org.apache.poi.hssf.usermodel.HSSFPolygon;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
@Deprecated
|
||||
public class PolygonShape
|
||||
extends AbstractShape
|
||||
{
|
||||
@ -63,7 +64,7 @@ public class PolygonShape
|
||||
spContainer.setRecordId( EscherContainerRecord.SP_CONTAINER );
|
||||
spContainer.setOptions( (short) 0x000F );
|
||||
sp.setRecordId( EscherSpRecord.RECORD_ID );
|
||||
sp.setOptions( (short) ( ( EscherAggregate.ST_DONUT << 4 ) | 0x2 ) );
|
||||
sp.setOptions( (short) ( ( EscherAggregate.ST_NOT_PRIMATIVE << 4 ) | 0x2 ) );
|
||||
sp.setShapeId( shapeId );
|
||||
if (hssfShape.getParent() == null)
|
||||
sp.setFlags( EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HASSHAPETYPE );
|
||||
|
@ -25,6 +25,7 @@ import org.apache.poi.hssf.record.EndSubRecord;
|
||||
import org.apache.poi.hssf.usermodel.HSSFSimpleShape;
|
||||
import org.apache.poi.hssf.usermodel.HSSFShape;
|
||||
|
||||
@Deprecated
|
||||
public class SimpleFilledShape
|
||||
extends AbstractShape
|
||||
{
|
||||
|
@ -28,6 +28,7 @@ import org.apache.poi.hssf.usermodel.*;
|
||||
*
|
||||
* @author Glen Stampoultzis (glens at apache.org)
|
||||
*/
|
||||
@Deprecated
|
||||
public class TextboxShape
|
||||
extends AbstractShape
|
||||
{
|
||||
|
@ -20,24 +20,24 @@ package org.apache.poi.hssf.record;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
/**
|
||||
* DrawingRecord (0x00EC)<p/>
|
||||
*
|
||||
*/
|
||||
public final class DrawingRecord extends StandardRecord {
|
||||
public static final short sid = 0x00EC;
|
||||
|
||||
private static final byte[] EMPTY_BYTE_ARRAY = { };
|
||||
private static final byte[] EMPTY_BYTE_ARRAY = {};
|
||||
|
||||
private byte[] recordData;
|
||||
private byte[] contd;
|
||||
|
||||
public DrawingRecord() {
|
||||
recordData = EMPTY_BYTE_ARRAY;
|
||||
recordData = EMPTY_BYTE_ARRAY;
|
||||
}
|
||||
|
||||
public DrawingRecord(RecordInputStream in) {
|
||||
recordData = in.readRemainder();
|
||||
recordData = in.readRemainder();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void processContinueRecord(byte[] record) {
|
||||
//don't merge continue record with the drawing record, it must be serialized separately
|
||||
contd = record;
|
||||
@ -46,6 +46,7 @@ public final class DrawingRecord extends StandardRecord {
|
||||
public void serialize(LittleEndianOutput out) {
|
||||
out.write(recordData);
|
||||
}
|
||||
|
||||
protected int getDataSize() {
|
||||
return recordData.length;
|
||||
}
|
||||
@ -54,32 +55,39 @@ public final class DrawingRecord extends StandardRecord {
|
||||
return sid;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public byte[] getData() {
|
||||
if(contd != null) {
|
||||
byte[] newBuffer = new byte[ recordData.length + contd.length ];
|
||||
System.arraycopy( recordData, 0, newBuffer, 0, recordData.length );
|
||||
System.arraycopy( contd, 0, newBuffer, recordData.length, contd.length);
|
||||
return newBuffer;
|
||||
}
|
||||
return recordData;
|
||||
}
|
||||
|
||||
public byte[] getRecordData(){
|
||||
return recordData;
|
||||
}
|
||||
|
||||
public void setData(byte[] thedata) {
|
||||
if (thedata == null) {
|
||||
throw new IllegalArgumentException("data must not be null");
|
||||
}
|
||||
if (thedata == null) {
|
||||
throw new IllegalArgumentException("data must not be null");
|
||||
}
|
||||
recordData = thedata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cloning of drawing records must be executed through HSSFPatriarch, because all id's must be changed
|
||||
* @return cloned drawing records
|
||||
*/
|
||||
public Object clone() {
|
||||
DrawingRecord rec = new DrawingRecord();
|
||||
|
||||
rec.recordData = recordData.clone();
|
||||
if (contd != null) {
|
||||
// TODO - this code probably never executes
|
||||
rec.contd = contd.clone();
|
||||
}
|
||||
|
||||
return rec;
|
||||
DrawingRecord rec = new DrawingRecord();
|
||||
rec.recordData = recordData.clone();
|
||||
if (contd != null) {
|
||||
// TODO - this code probably never executes
|
||||
rec.contd = contd.clone();
|
||||
}
|
||||
|
||||
return rec;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DrawingRecord["+recordData.length+"]";
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -338,14 +338,14 @@ public final class RecordFactoryInputStream {
|
||||
}
|
||||
if (_lastRecord instanceof DrawingGroupRecord) {
|
||||
((DrawingGroupRecord) _lastRecord).processContinueRecord(contRec.getData());
|
||||
return null;
|
||||
}
|
||||
if (_lastRecord instanceof DrawingRecord) {
|
||||
((DrawingRecord) _lastRecord).processContinueRecord(contRec.getData());
|
||||
return null;
|
||||
}
|
||||
if (_lastRecord instanceof UnknownRecord) {
|
||||
//Gracefully handle records that we don't know about,
|
||||
return null;
|
||||
}
|
||||
if (_lastRecord instanceof DrawingRecord) {
|
||||
// ((DrawingRecord) _lastRecord).appendContinueRecord(contRec.getData());
|
||||
return contRec;
|
||||
}
|
||||
if (_lastRecord instanceof UnknownRecord) {
|
||||
//Gracefully handle records that we don't know about,
|
||||
//that happen to be continued
|
||||
return record;
|
||||
}
|
||||
|
@ -286,9 +286,9 @@ public final class PageSettingsBlock extends RecordAggregate {
|
||||
pls.visitContainedRecords(rv);
|
||||
}
|
||||
visitIfPresent(_printSetup, rv);
|
||||
visitIfPresent(_bitmap, rv);
|
||||
visitIfPresent(_printSize, rv);
|
||||
visitIfPresent(_headerFooter, rv);
|
||||
visitIfPresent(_bitmap, rv);
|
||||
}
|
||||
private static void visitIfPresent(Record r, RecordVisitor rv) {
|
||||
if (r != null) {
|
||||
|
@ -349,6 +349,7 @@ public class EscherGraphics
|
||||
shape.setLineStyle(HSSFShape.LINESTYLE_NONE);
|
||||
shape.setFillColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue());
|
||||
shape.setLineStyleColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue());
|
||||
shape.setNoFill(false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -18,40 +18,96 @@
|
||||
package org.apache.poi.hssf.usermodel;
|
||||
|
||||
|
||||
import org.apache.poi.ddf.EscherChildAnchorRecord;
|
||||
import org.apache.poi.ddf.EscherClientAnchorRecord;
|
||||
import org.apache.poi.ddf.EscherContainerRecord;
|
||||
import org.apache.poi.ddf.EscherRecord;
|
||||
|
||||
/**
|
||||
* An anchor is what specifics the position of a shape within a client object
|
||||
* or within another containing shape.
|
||||
*
|
||||
* @author Glen Stampoultzis (glens at apache.org)
|
||||
*/
|
||||
public abstract class HSSFAnchor
|
||||
{
|
||||
int dx1;
|
||||
int dy1;
|
||||
int dx2;
|
||||
int dy2;
|
||||
public abstract class HSSFAnchor {
|
||||
|
||||
public HSSFAnchor()
|
||||
{
|
||||
protected boolean _isHorizontallyFlipped = false;
|
||||
protected boolean _isVerticallyFlipped = false;
|
||||
|
||||
public HSSFAnchor() {
|
||||
createEscherAnchor();
|
||||
}
|
||||
|
||||
public HSSFAnchor( int dx1, int dy1, int dx2, int dy2 )
|
||||
{
|
||||
this.dx1 = dx1;
|
||||
this.dy1 = dy1;
|
||||
this.dx2 = dx2;
|
||||
this.dy2 = dy2;
|
||||
public HSSFAnchor(int dx1, int dy1, int dx2, int dy2) {
|
||||
createEscherAnchor();
|
||||
setDx1(dx1);
|
||||
setDy1(dy1);
|
||||
setDx2(dx2);
|
||||
setDy2(dy2);
|
||||
}
|
||||
|
||||
public int getDx1(){ return dx1; }
|
||||
public void setDx1( int dx1 ){ this.dx1 = dx1; }
|
||||
public int getDy1(){ return dy1; }
|
||||
public void setDy1( int dy1 ){ this.dy1 = dy1; }
|
||||
public int getDy2(){ return dy2; }
|
||||
public void setDy2( int dy2 ){ this.dy2 = dy2; }
|
||||
public int getDx2(){ return dx2; }
|
||||
public void setDx2( int dx2 ){ this.dx2 = dx2; }
|
||||
public static HSSFAnchor createAnchorFromEscher(EscherContainerRecord container){
|
||||
if (null != container.getChildById(EscherChildAnchorRecord.RECORD_ID)){
|
||||
return new HSSFChildAnchor((EscherChildAnchorRecord) container.getChildById(EscherChildAnchorRecord.RECORD_ID));
|
||||
} else {
|
||||
if (null != container.getChildById(EscherClientAnchorRecord.RECORD_ID)){
|
||||
return new HSSFClientAnchor((EscherClientAnchorRecord) container.getChildById(EscherClientAnchorRecord.RECORD_ID));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return x coordinate of the left up corner
|
||||
*/
|
||||
public abstract int getDx1();
|
||||
|
||||
/**
|
||||
* @param dx1 x coordinate of the left up corner
|
||||
*/
|
||||
public abstract void setDx1(int dx1);
|
||||
|
||||
/**
|
||||
* @return y coordinate of the left up corner
|
||||
*/
|
||||
public abstract int getDy1();
|
||||
|
||||
/**
|
||||
* @param dy1 y coordinate of the left up corner
|
||||
*/
|
||||
public abstract void setDy1(int dy1);
|
||||
|
||||
/**
|
||||
* @return y coordinate of the right down corner
|
||||
*/
|
||||
public abstract int getDy2();
|
||||
|
||||
/**
|
||||
* @param dy2 y coordinate of the right down corner
|
||||
*/
|
||||
public abstract void setDy2(int dy2);
|
||||
|
||||
/**
|
||||
* @return x coordinate of the right down corner
|
||||
*/
|
||||
public abstract int getDx2();
|
||||
|
||||
/**
|
||||
* @param dx2 x coordinate of the right down corner
|
||||
*/
|
||||
public abstract void setDx2(int dx2);
|
||||
|
||||
/**
|
||||
* @return whether this shape is horizontally flipped
|
||||
*/
|
||||
public abstract boolean isHorizontallyFlipped();
|
||||
|
||||
/**
|
||||
* @return whether this shape is vertically flipped
|
||||
*/
|
||||
public abstract boolean isVerticallyFlipped();
|
||||
|
||||
protected abstract EscherRecord getEscherAnchor();
|
||||
|
||||
protected abstract void createEscherAnchor();
|
||||
}
|
||||
|
@ -1021,7 +1021,7 @@ public class HSSFCell implements Cell {
|
||||
*/
|
||||
public HSSFComment getCellComment(){
|
||||
if (_comment == null) {
|
||||
_comment = findCellComment(_sheet.getSheet(), _record.getRow(), _record.getColumn());
|
||||
_comment = _sheet.findCellComment(_record.getRow(), _record.getColumn());
|
||||
}
|
||||
return _comment;
|
||||
}
|
||||
@ -1033,98 +1033,12 @@ public class HSSFCell implements Cell {
|
||||
* all comments after performing this action!
|
||||
*/
|
||||
public void removeCellComment() {
|
||||
HSSFComment comment = findCellComment(_sheet.getSheet(), _record.getRow(), _record.getColumn());
|
||||
HSSFComment comment = _sheet.findCellComment(_record.getRow(), _record.getColumn());
|
||||
_comment = null;
|
||||
|
||||
if(comment == null) {
|
||||
// Nothing to do
|
||||
if (null == comment){
|
||||
return;
|
||||
}
|
||||
|
||||
// Zap the underlying NoteRecord
|
||||
List<RecordBase> sheetRecords = _sheet.getSheet().getRecords();
|
||||
sheetRecords.remove(comment.getNoteRecord());
|
||||
|
||||
// If we have a TextObjectRecord, is should
|
||||
// be proceeed by:
|
||||
// MSODRAWING with container
|
||||
// OBJ
|
||||
// MSODRAWING with EscherTextboxRecord
|
||||
if(comment.getTextObjectRecord() != null) {
|
||||
TextObjectRecord txo = comment.getTextObjectRecord();
|
||||
int txoAt = sheetRecords.indexOf(txo);
|
||||
|
||||
if(sheetRecords.get(txoAt-3) instanceof DrawingRecord &&
|
||||
sheetRecords.get(txoAt-2) instanceof ObjRecord &&
|
||||
sheetRecords.get(txoAt-1) instanceof DrawingRecord) {
|
||||
// Zap these, in reverse order
|
||||
sheetRecords.remove(txoAt-1);
|
||||
sheetRecords.remove(txoAt-2);
|
||||
sheetRecords.remove(txoAt-3);
|
||||
} else {
|
||||
throw new IllegalStateException("Found the wrong records before the TextObjectRecord, can't remove comment");
|
||||
}
|
||||
|
||||
// Now remove the text record
|
||||
sheetRecords.remove(txo);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cell comment finder.
|
||||
* Returns cell comment for the specified sheet, row and column.
|
||||
*
|
||||
* @return cell comment or <code>null</code> if not found
|
||||
*/
|
||||
protected static HSSFComment findCellComment(InternalSheet sheet, int row, int column) {
|
||||
// TODO - optimise this code by searching backwards, find NoteRecord first, quit if not found. Find one TXO by id
|
||||
HSSFComment comment = null;
|
||||
Map<Integer, TextObjectRecord> noteTxo =
|
||||
new HashMap<Integer, TextObjectRecord>();
|
||||
int i = 0;
|
||||
for (Iterator<RecordBase> it = sheet.getRecords().iterator(); it.hasNext();) {
|
||||
RecordBase rec = it.next();
|
||||
if (rec instanceof NoteRecord) {
|
||||
NoteRecord note = (NoteRecord) rec;
|
||||
if (note.getRow() == row && note.getColumn() == column) {
|
||||
if(i < noteTxo.size()) {
|
||||
TextObjectRecord txo = noteTxo.get(note.getShapeId());
|
||||
if(txo != null){
|
||||
comment = new HSSFComment(note, txo);
|
||||
comment.setRow(note.getRow());
|
||||
comment.setColumn(note.getColumn());
|
||||
comment.setAuthor(note.getAuthor());
|
||||
comment.setVisible(note.getFlags() == NoteRecord.NOTE_VISIBLE);
|
||||
comment.setString(txo.getStr());
|
||||
} else{
|
||||
log.log(POILogger.WARN, "Failed to match NoteRecord and TextObjectRecord, row: " + row + ", column: " + column);
|
||||
}
|
||||
} else {
|
||||
log.log(POILogger.WARN, "Failed to match NoteRecord and TextObjectRecord, row: " + row + ", column: " + column);
|
||||
}
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
} else if (rec instanceof ObjRecord) {
|
||||
ObjRecord obj = (ObjRecord) rec;
|
||||
SubRecord sub = obj.getSubRecords().get(0);
|
||||
if (sub instanceof CommonObjectDataSubRecord) {
|
||||
CommonObjectDataSubRecord cmo = (CommonObjectDataSubRecord) sub;
|
||||
if (cmo.getObjectType() == CommonObjectDataSubRecord.OBJECT_TYPE_COMMENT) {
|
||||
//map ObjectId and corresponding TextObjectRecord,
|
||||
//it will be used to match NoteRecord and TextObjectRecord
|
||||
while (it.hasNext()) {
|
||||
rec = it.next();
|
||||
if (rec instanceof TextObjectRecord) {
|
||||
noteTxo.put(cmo.getObjectId(), (TextObjectRecord) rec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return comment;
|
||||
_sheet.getDrawingPatriarch().removeShape(comment);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -18,31 +18,126 @@
|
||||
package org.apache.poi.hssf.usermodel;
|
||||
|
||||
|
||||
import org.apache.poi.ddf.EscherChildAnchorRecord;
|
||||
import org.apache.poi.ddf.EscherRecord;
|
||||
|
||||
public final class HSSFChildAnchor extends HSSFAnchor {
|
||||
public HSSFChildAnchor()
|
||||
{
|
||||
|
||||
private EscherChildAnchorRecord _escherChildAnchor;
|
||||
|
||||
/**
|
||||
* create anchor from existing file
|
||||
* @param escherChildAnchorRecord
|
||||
*/
|
||||
public HSSFChildAnchor(EscherChildAnchorRecord escherChildAnchorRecord) {
|
||||
this._escherChildAnchor = escherChildAnchorRecord;
|
||||
}
|
||||
|
||||
public HSSFChildAnchor( int dx1, int dy1, int dx2, int dy2 )
|
||||
{
|
||||
super( dx1, dy1, dx2, dy2 );
|
||||
public HSSFChildAnchor() {
|
||||
_escherChildAnchor = new EscherChildAnchorRecord();
|
||||
}
|
||||
|
||||
public void setAnchor(int dx1, int dy1, int dx2, int dy2)
|
||||
{
|
||||
this.dx1 = dx1;
|
||||
this.dy1 = dy1;
|
||||
this.dx2 = dx2;
|
||||
this.dy2 = dy2;
|
||||
/**
|
||||
* create anchor from scratch
|
||||
* @param dx1 x coordinate of the left up corner
|
||||
* @param dy1 y coordinate of the left up corner
|
||||
* @param dx2 x coordinate of the right down corner
|
||||
* @param dy2 y coordinate of the right down corner
|
||||
*/
|
||||
public HSSFChildAnchor(int dx1, int dy1, int dx2, int dy2) {
|
||||
super(Math.min(dx1, dx2), Math.min(dy1, dy2), Math.max(dx1, dx2), Math.max(dy1, dy2));
|
||||
if (dx1 > dx2){
|
||||
_isHorizontallyFlipped = true;
|
||||
}
|
||||
if (dy1 > dy2){
|
||||
_isVerticallyFlipped = true;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isHorizontallyFlipped()
|
||||
{
|
||||
return dx1 > dx2;
|
||||
@Override
|
||||
public int getDx1() {
|
||||
return _escherChildAnchor.getDx1();
|
||||
}
|
||||
|
||||
public boolean isVerticallyFlipped()
|
||||
{
|
||||
return dy1 > dy2;
|
||||
@Override
|
||||
public void setDx1(int dx1) {
|
||||
_escherChildAnchor.setDx1(dx1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDy1() {
|
||||
return _escherChildAnchor.getDy1();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDy1(int dy1) {
|
||||
_escherChildAnchor.setDy1(dy1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDy2() {
|
||||
return _escherChildAnchor.getDy2();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDy2(int dy2) {
|
||||
_escherChildAnchor.setDy2(dy2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDx2() {
|
||||
return _escherChildAnchor.getDx2();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDx2(int dx2) {
|
||||
_escherChildAnchor.setDx2(dx2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param dx1 x coordinate of the left up corner
|
||||
* @param dy1 y coordinate of the left up corner
|
||||
* @param dx2 x coordinate of the right down corner
|
||||
* @param dy2 y coordinate of the right down corner
|
||||
*/
|
||||
public void setAnchor(int dx1, int dy1, int dx2, int dy2) {
|
||||
setDx1(Math.min(dx1, dx2));
|
||||
setDy1(Math.min(dy1, dy2));
|
||||
setDx2(Math.max(dx1, dx2));
|
||||
setDy2(Math.max(dy1, dy2));
|
||||
}
|
||||
|
||||
|
||||
public boolean isHorizontallyFlipped() {
|
||||
return _isHorizontallyFlipped;
|
||||
}
|
||||
|
||||
|
||||
public boolean isVerticallyFlipped() {
|
||||
return _isVerticallyFlipped;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EscherRecord getEscherAnchor() {
|
||||
return _escherChildAnchor;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createEscherAnchor() {
|
||||
_escherChildAnchor = new EscherChildAnchorRecord();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (obj == this)
|
||||
return true;
|
||||
if (obj.getClass() != getClass())
|
||||
return false;
|
||||
HSSFChildAnchor anchor = (HSSFChildAnchor) obj;
|
||||
|
||||
return anchor.getDx1() == getDx1() && anchor.getDx2() == getDx2() && anchor.getDy1() == getDy1()
|
||||
&& anchor.getDy2() == getDy2();
|
||||
}
|
||||
}
|
||||
|
@ -17,9 +17,10 @@
|
||||
|
||||
package org.apache.poi.hssf.usermodel;
|
||||
|
||||
import org.apache.poi.ddf.EscherClientAnchorRecord;
|
||||
import org.apache.poi.ddf.EscherRecord;
|
||||
import org.apache.poi.ss.usermodel.ClientAnchor;
|
||||
|
||||
|
||||
/**
|
||||
* A client anchor is attached to an excel worksheet. It anchors against a
|
||||
* top-left and buttom-right cell.
|
||||
@ -27,35 +28,34 @@ import org.apache.poi.ss.usermodel.ClientAnchor;
|
||||
* @author Glen Stampoultzis (glens at apache.org)
|
||||
*/
|
||||
public final class HSSFClientAnchor extends HSSFAnchor implements ClientAnchor {
|
||||
short col1;
|
||||
int row1;
|
||||
short col2;
|
||||
int row2;
|
||||
int anchorType;
|
||||
|
||||
private EscherClientAnchorRecord _escherClientAnchor;
|
||||
|
||||
public HSSFClientAnchor(EscherClientAnchorRecord escherClientAnchorRecord) {
|
||||
this._escherClientAnchor = escherClientAnchorRecord;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new client anchor and defaults all the anchor positions to 0.
|
||||
*/
|
||||
public HSSFClientAnchor()
|
||||
{
|
||||
public HSSFClientAnchor() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new client anchor and sets the top-left and bottom-right
|
||||
* coordinates of the anchor.
|
||||
*
|
||||
* @param dx1 the x coordinate within the first cell.
|
||||
* @param dy1 the y coordinate within the first cell.
|
||||
* @param dx2 the x coordinate within the second cell.
|
||||
* @param dy2 the y coordinate within the second cell.
|
||||
* @param col1 the column (0 based) of the first cell.
|
||||
* @param row1 the row (0 based) of the first cell.
|
||||
* @param col2 the column (0 based) of the second cell.
|
||||
* @param row2 the row (0 based) of the second cell.
|
||||
* @param dx1 the x coordinate within the first cell.
|
||||
* @param dy1 the y coordinate within the first cell.
|
||||
* @param dx2 the x coordinate within the second cell.
|
||||
* @param dy2 the y coordinate within the second cell.
|
||||
* @param col1 the column (0 based) of the first cell.
|
||||
* @param row1 the row (0 based) of the first cell.
|
||||
* @param col2 the column (0 based) of the second cell.
|
||||
* @param row2 the row (0 based) of the second cell.
|
||||
*/
|
||||
public HSSFClientAnchor( int dx1, int dy1, int dx2, int dy2, short col1, int row1, short col2, int row2 )
|
||||
{
|
||||
super( dx1, dy1, dx2, dy2 );
|
||||
public HSSFClientAnchor(int dx1, int dy1, int dx2, int dy2, short col1, int row1, short col2, int row2) {
|
||||
super(dx1, dy1, dx2, dy2);
|
||||
|
||||
checkRange(dx1, 0, 1023, "dx1");
|
||||
checkRange(dx2, 0, 1023, "dx2");
|
||||
@ -66,35 +66,37 @@ public final class HSSFClientAnchor extends HSSFAnchor implements ClientAnchor {
|
||||
checkRange(row1, 0, 255 * 256, "row1");
|
||||
checkRange(row2, 0, 255 * 256, "row2");
|
||||
|
||||
this.col1 = col1;
|
||||
this.row1 = row1;
|
||||
this.col2 = col2;
|
||||
this.row2 = row2;
|
||||
setCol1((short) Math.min(col1, col2));
|
||||
setCol2((short) Math.max(col1, col2));
|
||||
setRow1((short) Math.min(row1, row2));
|
||||
setRow2((short) Math.max(row1, row2));
|
||||
|
||||
if (col1 > col2){
|
||||
_isHorizontallyFlipped = true;
|
||||
}
|
||||
if (row1 > row2){
|
||||
_isVerticallyFlipped = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the height of a client anchor in points.
|
||||
*
|
||||
* @param sheet the sheet the anchor will be attached to
|
||||
* @return the shape height.
|
||||
* @param sheet the sheet the anchor will be attached to
|
||||
* @return the shape height.
|
||||
*/
|
||||
public float getAnchorHeightInPoints(HSSFSheet sheet )
|
||||
{
|
||||
public float getAnchorHeightInPoints(HSSFSheet sheet) {
|
||||
int y1 = getDy1();
|
||||
int y2 = getDy2();
|
||||
int row1 = Math.min( getRow1(), getRow2() );
|
||||
int row2 = Math.max( getRow1(), getRow2() );
|
||||
int row1 = Math.min(getRow1(), getRow2());
|
||||
int row2 = Math.max(getRow1(), getRow2());
|
||||
|
||||
float points = 0;
|
||||
if (row1 == row2)
|
||||
{
|
||||
if (row1 == row2) {
|
||||
points = ((y2 - y1) / 256.0f) * getRowHeightInPoints(sheet, row2);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
points += ((256.0f - y1) / 256.0f) * getRowHeightInPoints(sheet, row1);
|
||||
for (int i = row1 + 1; i < row2; i++)
|
||||
{
|
||||
for (int i = row1 + 1; i < row2; i++) {
|
||||
points += getRowHeightInPoints(sheet, i);
|
||||
}
|
||||
points += (y2 / 256.0f) * getRowHeightInPoints(sheet, row2);
|
||||
@ -103,8 +105,7 @@ public final class HSSFClientAnchor extends HSSFAnchor implements ClientAnchor {
|
||||
return points;
|
||||
}
|
||||
|
||||
private float getRowHeightInPoints(HSSFSheet sheet, int rowNum)
|
||||
{
|
||||
private float getRowHeightInPoints(HSSFSheet sheet, int rowNum) {
|
||||
HSSFRow row = sheet.getRow(rowNum);
|
||||
if (row == null) {
|
||||
return sheet.getDefaultRowHeightInPoints();
|
||||
@ -112,55 +113,78 @@ public final class HSSFClientAnchor extends HSSFAnchor implements ClientAnchor {
|
||||
return row.getHeightInPoints();
|
||||
}
|
||||
|
||||
public short getCol1()
|
||||
{
|
||||
return col1;
|
||||
/**
|
||||
* @return the column(0 based) of the first cell.
|
||||
*/
|
||||
public short getCol1() {
|
||||
return _escherClientAnchor.getCol1();
|
||||
}
|
||||
|
||||
public void setCol1( short col1 )
|
||||
{
|
||||
/**
|
||||
* @param col1 the column(0 based) of the first cell.
|
||||
*/
|
||||
public void setCol1(short col1) {
|
||||
checkRange(col1, 0, 255, "col1");
|
||||
this.col1 = col1;
|
||||
}
|
||||
public void setCol1( int col1 ){
|
||||
setCol1((short)col1);
|
||||
_escherClientAnchor.setCol1(col1);
|
||||
}
|
||||
|
||||
public short getCol2()
|
||||
{
|
||||
return col2;
|
||||
/**
|
||||
* @param col1 0-based column of the first cell.
|
||||
*/
|
||||
public void setCol1(int col1) {
|
||||
setCol1((short) col1);
|
||||
}
|
||||
|
||||
public void setCol2( short col2 )
|
||||
{
|
||||
/**
|
||||
* @return the column(0 based) of the first cell.
|
||||
*/
|
||||
public short getCol2() {
|
||||
return _escherClientAnchor.getCol2();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param col2 the column(0 based) of the second cell.
|
||||
*/
|
||||
public void setCol2(short col2) {
|
||||
checkRange(col2, 0, 255, "col2");
|
||||
this.col2 = col2;
|
||||
_escherClientAnchor.setCol2(col2);
|
||||
}
|
||||
|
||||
public void setCol2( int col2 ){
|
||||
setCol2((short)col2);
|
||||
/**
|
||||
* @param col2 the column(0 based) of the second cell.
|
||||
*/
|
||||
public void setCol2(int col2) {
|
||||
setCol2((short) col2);
|
||||
}
|
||||
|
||||
public int getRow1()
|
||||
{
|
||||
return row1;
|
||||
/**
|
||||
* @return the row(0 based) of the first cell.
|
||||
*/
|
||||
public int getRow1() {
|
||||
return _escherClientAnchor.getRow1();
|
||||
}
|
||||
|
||||
public void setRow1( int row1 )
|
||||
{
|
||||
/**
|
||||
* @param row1 0-based row of the first cell.
|
||||
*/
|
||||
public void setRow1(int row1) {
|
||||
checkRange(row1, 0, 256 * 256, "row1");
|
||||
this.row1 = row1;
|
||||
_escherClientAnchor.setRow1(Integer.valueOf(row1).shortValue());
|
||||
}
|
||||
|
||||
public int getRow2()
|
||||
{
|
||||
return row2;
|
||||
/**
|
||||
* @return the row(0 based) of the second cell.
|
||||
*/
|
||||
public int getRow2() {
|
||||
return _escherClientAnchor.getRow2();
|
||||
}
|
||||
|
||||
public void setRow2( int row2 )
|
||||
{
|
||||
/**
|
||||
* @return the row(0 based) of the second cell.
|
||||
*/
|
||||
public void setRow2(int row2) {
|
||||
checkRange(row2, 0, 256 * 256, "row2");
|
||||
this.row2 = row2;
|
||||
_escherClientAnchor.setRow2(Integer.valueOf(row2).shortValue());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -171,79 +195,124 @@ public final class HSSFClientAnchor extends HSSFAnchor implements ClientAnchor {
|
||||
* @param y1 the y coordinate within the first cell.
|
||||
* @param x2 the x coordinate within the second cell.
|
||||
* @param y2 the y coordinate within the second cell.
|
||||
* @param col1 the column (0 based) of the first cell.
|
||||
* @param row1 the row (0 based) of the first cell.
|
||||
* @param col2 the column (0 based) of the second cell.
|
||||
* @param row2 the row (0 based) of the second cell.
|
||||
* @param col1 the column (0 based) of the first cell.
|
||||
* @param row1 the row (0 based) of the first cell.
|
||||
* @param col2 the column (0 based) of the second cell.
|
||||
* @param row2 the row (0 based) of the second cell.
|
||||
*/
|
||||
public void setAnchor( short col1, int row1, int x1, int y1, short col2, int row2, int x2, int y2 )
|
||||
{
|
||||
checkRange(dx1, 0, 1023, "dx1");
|
||||
checkRange(dx2, 0, 1023, "dx2");
|
||||
checkRange(dy1, 0, 255, "dy1");
|
||||
checkRange(dy2, 0, 255, "dy2");
|
||||
checkRange(col1, 0, 255, "col1");
|
||||
checkRange(col2, 0, 255, "col2");
|
||||
checkRange(row1, 0, 255 * 256, "row1");
|
||||
checkRange(row2, 0, 255 * 256, "row2");
|
||||
public void setAnchor(short col1, int row1, int x1, int y1, short col2, int row2, int x2, int y2) {
|
||||
checkRange(getDx1(), 0, 1023, "dx1");
|
||||
checkRange(getDx2(), 0, 1023, "dx2");
|
||||
checkRange(getDy1(), 0, 255, "dy1");
|
||||
checkRange(getDy2(), 0, 255, "dy2");
|
||||
checkRange(getCol1(), 0, 255, "col1");
|
||||
checkRange(getCol2(), 0, 255, "col2");
|
||||
checkRange(getRow1(), 0, 255 * 256, "row1");
|
||||
checkRange(getRow2(), 0, 255 * 256, "row2");
|
||||
|
||||
this.col1 = col1;
|
||||
this.row1 = row1;
|
||||
this.dx1 = x1;
|
||||
this.dy1 = y1;
|
||||
this.col2 = col2;
|
||||
this.row2 = row2;
|
||||
this.dx2 = x2;
|
||||
this.dy2 = y2;
|
||||
setCol1(col1);
|
||||
setRow1(row1);
|
||||
setDx1(x1);
|
||||
setDy1(y1);
|
||||
setCol2(col2);
|
||||
setRow2(row2);
|
||||
setDx2(x2);
|
||||
setDy2(y2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the anchor goes from right to left.
|
||||
*/
|
||||
public boolean isHorizontallyFlipped()
|
||||
{
|
||||
if (col1 == col2) {
|
||||
return dx1 > dx2;
|
||||
}
|
||||
return col1 > col2;
|
||||
public boolean isHorizontallyFlipped() {
|
||||
return _isHorizontallyFlipped;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the anchor goes from bottom to top.
|
||||
*/
|
||||
public boolean isVerticallyFlipped()
|
||||
{
|
||||
if (row1 == row2) {
|
||||
return dy1 > dy2;
|
||||
}
|
||||
return row1 > row2;
|
||||
public boolean isVerticallyFlipped() {
|
||||
return _isVerticallyFlipped;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EscherRecord getEscherAnchor() {
|
||||
return _escherClientAnchor;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createEscherAnchor() {
|
||||
_escherClientAnchor = new EscherClientAnchorRecord();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the anchor type
|
||||
* <p>
|
||||
* <p/>
|
||||
* 0 = Move and size with Cells, 2 = Move but don't size with cells, 3 = Don't move or size with cells.
|
||||
*/
|
||||
public int getAnchorType()
|
||||
{
|
||||
return anchorType;
|
||||
public int getAnchorType() {
|
||||
return _escherClientAnchor.getFlag();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the anchor type
|
||||
* <p>
|
||||
* <p/>
|
||||
* 0 = Move and size with Cells, 2 = Move but don't size with cells, 3 = Don't move or size with cells.
|
||||
*/
|
||||
public void setAnchorType( int anchorType )
|
||||
{
|
||||
this.anchorType = anchorType;
|
||||
public void setAnchorType(int anchorType) {
|
||||
_escherClientAnchor.setFlag(Integer.valueOf(anchorType).shortValue());
|
||||
}
|
||||
|
||||
private void checkRange( int value, int minRange, int maxRange, String varName )
|
||||
{
|
||||
private void checkRange(int value, int minRange, int maxRange, String varName) {
|
||||
if (value < minRange || value > maxRange)
|
||||
throw new IllegalArgumentException(varName + " must be between " + minRange + " and " + maxRange);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (obj == this)
|
||||
return true;
|
||||
if (obj.getClass() != getClass())
|
||||
return false;
|
||||
HSSFClientAnchor anchor = (HSSFClientAnchor) obj;
|
||||
|
||||
return anchor.getCol1() == getCol1() && anchor.getCol2() == getCol2() && anchor.getDx1() == getDx1()
|
||||
&& anchor.getDx2() == getDx2() && anchor.getDy1() == getDy1() && anchor.getDy2() == getDy2()
|
||||
&& anchor.getRow1() == getRow1() && anchor.getRow2() == getRow2() && anchor.getAnchorType() == getAnchorType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDx1() {
|
||||
return _escherClientAnchor.getDx1();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDx1(int dx1) {
|
||||
_escherClientAnchor.setDx1(Integer.valueOf(dx1).shortValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDy1() {
|
||||
return _escherClientAnchor.getDy1();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDy1(int dy1) {
|
||||
_escherClientAnchor.setDy1(Integer.valueOf(dy1).shortValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDy2() {
|
||||
return _escherClientAnchor.getDy2();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDy2(int dy2) {
|
||||
_escherClientAnchor.setDy2(Integer.valueOf(dy2).shortValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDx2() {
|
||||
return _escherClientAnchor.getDx2();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDx2(int dx2) {
|
||||
_escherClientAnchor.setDx2(Integer.valueOf(dx2).shortValue());
|
||||
}
|
||||
}
|
||||
|
101
src/java/org/apache/poi/hssf/usermodel/HSSFCombobox.java
Normal file
101
src/java/org/apache/poi/hssf/usermodel/HSSFCombobox.java
Normal file
@ -0,0 +1,101 @@
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.hssf.usermodel;
|
||||
|
||||
import org.apache.poi.ddf.*;
|
||||
import org.apache.poi.hssf.record.*;
|
||||
|
||||
/**
|
||||
* @author Evgeniy Berlog
|
||||
* @date 12.07.12
|
||||
*/
|
||||
public class HSSFCombobox extends HSSFSimpleShape {
|
||||
|
||||
public HSSFCombobox(EscherContainerRecord spContainer, ObjRecord objRecord) {
|
||||
super(spContainer, objRecord);
|
||||
}
|
||||
|
||||
public HSSFCombobox(HSSFShape parent, HSSFAnchor anchor) {
|
||||
super(parent, anchor);
|
||||
super.setShapeType(OBJECT_TYPE_COMBO_BOX);
|
||||
CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) getObjRecord().getSubRecords().get(0);
|
||||
cod.setObjectType(CommonObjectDataSubRecord.OBJECT_TYPE_COMBO_BOX);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TextObjectRecord createTextObjRecord() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EscherContainerRecord createSpContainer() {
|
||||
EscherContainerRecord spContainer = new EscherContainerRecord();
|
||||
EscherSpRecord sp = new EscherSpRecord();
|
||||
EscherOptRecord opt = new EscherOptRecord();
|
||||
EscherClientDataRecord clientData = new EscherClientDataRecord();
|
||||
|
||||
spContainer.setRecordId(EscherContainerRecord.SP_CONTAINER);
|
||||
spContainer.setOptions((short) 0x000F);
|
||||
sp.setRecordId(EscherSpRecord.RECORD_ID);
|
||||
sp.setOptions((short) ((EscherAggregate.ST_HOSTCONTROL << 4) | 0x2));
|
||||
|
||||
sp.setFlags(EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HASSHAPETYPE);
|
||||
opt.setRecordId(EscherOptRecord.RECORD_ID);
|
||||
opt.addEscherProperty(new EscherBoolProperty(EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 17039620));
|
||||
opt.addEscherProperty(new EscherBoolProperty(EscherProperties.TEXT__SIZE_TEXT_TO_FIT_SHAPE, 0x00080008));
|
||||
opt.addEscherProperty(new EscherBoolProperty(EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x00080000));
|
||||
opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.GROUPSHAPE__PRINT, 0x00020000));
|
||||
|
||||
HSSFClientAnchor userAnchor = (HSSFClientAnchor) getAnchor();
|
||||
userAnchor.setAnchorType(1);
|
||||
EscherRecord anchor = userAnchor.getEscherAnchor();
|
||||
clientData.setRecordId(EscherClientDataRecord.RECORD_ID);
|
||||
clientData.setOptions((short) 0x0000);
|
||||
|
||||
spContainer.addChildRecord(sp);
|
||||
spContainer.addChildRecord(opt);
|
||||
spContainer.addChildRecord(anchor);
|
||||
spContainer.addChildRecord(clientData);
|
||||
|
||||
return spContainer;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ObjRecord createObjRecord() {
|
||||
ObjRecord obj = new ObjRecord();
|
||||
CommonObjectDataSubRecord c = new CommonObjectDataSubRecord();
|
||||
c.setObjectType(HSSFSimpleShape.OBJECT_TYPE_COMBO_BOX);
|
||||
c.setLocked(true);
|
||||
c.setPrintable(false);
|
||||
c.setAutofill(true);
|
||||
c.setAutoline(false);
|
||||
FtCblsSubRecord f = new FtCblsSubRecord();
|
||||
LbsDataSubRecord l = LbsDataSubRecord.newAutoFilterInstance();
|
||||
EndSubRecord e = new EndSubRecord();
|
||||
obj.addSubRecord(c);
|
||||
obj.addSubRecord(f);
|
||||
obj.addSubRecord(l);
|
||||
obj.addSubRecord(e);
|
||||
return obj;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setShapeType(int shapeType) {
|
||||
throw new IllegalStateException("Shape type can not be changed in "+this.getClass().getSimpleName());
|
||||
}
|
||||
}
|
@ -16,10 +16,9 @@
|
||||
==================================================================== */
|
||||
package org.apache.poi.hssf.usermodel;
|
||||
|
||||
import org.apache.poi.hssf.record.NoteRecord;
|
||||
import org.apache.poi.hssf.record.TextObjectRecord;
|
||||
import org.apache.poi.ddf.*;
|
||||
import org.apache.poi.hssf.record.*;
|
||||
import org.apache.poi.ss.usermodel.Comment;
|
||||
import org.apache.poi.ss.usermodel.RichTextString;
|
||||
|
||||
/**
|
||||
* Represents a cell comment - a sticky note associated with a cell.
|
||||
@ -28,59 +27,108 @@ import org.apache.poi.ss.usermodel.RichTextString;
|
||||
*/
|
||||
public class HSSFComment extends HSSFTextbox implements Comment {
|
||||
|
||||
/*
|
||||
* TODO - make HSSFComment more consistent when created vs read from file.
|
||||
* Currently HSSFComment has two main forms (corresponding to the two constructors). There
|
||||
* are certain operations that only work on comment objects in one of the forms (e.g. deleting
|
||||
* comments).
|
||||
* POI is also deficient in its management of RowRecord fields firstCol and lastCol. Those
|
||||
* fields are supposed to take comments into account, but POI does not do this yet (feb 2009).
|
||||
* It seems like HSSFRow should manage a collection of local HSSFComments
|
||||
*/
|
||||
|
||||
private boolean _visible;
|
||||
private int _row;
|
||||
private int _col;
|
||||
private String _author;
|
||||
private final static int FILL_TYPE_SOLID = 0;
|
||||
private final static int FILL_TYPE_PICTURE = 3;
|
||||
|
||||
/*
|
||||
* TODO - make HSSFComment more consistent when created vs read from file.
|
||||
* Currently HSSFComment has two main forms (corresponding to the two constructors). There
|
||||
* are certain operations that only work on comment objects in one of the forms (e.g. deleting
|
||||
* comments).
|
||||
* POI is also deficient in its management of RowRecord fields firstCol and lastCol. Those
|
||||
* fields are supposed to take comments into account, but POI does not do this yet (feb 2009).
|
||||
* It seems like HSSFRow should manage a collection of local HSSFComments
|
||||
*/
|
||||
|
||||
private NoteRecord _note;
|
||||
private TextObjectRecord _txo;
|
||||
|
||||
public HSSFComment(EscherContainerRecord spContainer, ObjRecord objRecord, TextObjectRecord textObjectRecord, NoteRecord _note) {
|
||||
super(spContainer, objRecord, textObjectRecord);
|
||||
this._note = _note;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new comment with the given parent and anchor.
|
||||
*
|
||||
* @param parent
|
||||
* @param anchor defines position of this anchor in the sheet
|
||||
* @param anchor defines position of this anchor in the sheet
|
||||
*/
|
||||
public HSSFComment(HSSFShape parent, HSSFAnchor anchor) {
|
||||
super(parent, anchor);
|
||||
setShapeType(OBJECT_TYPE_COMMENT);
|
||||
|
||||
_note = createNoteRecord();
|
||||
//default color for comments
|
||||
_fillColor = 0x08000050;
|
||||
setFillColor(0x08000050);
|
||||
|
||||
//by default comments are hidden
|
||||
_visible = false;
|
||||
|
||||
_author = "";
|
||||
setVisible(false);
|
||||
setAuthor("");
|
||||
CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) getObjRecord().getSubRecords().get(0);
|
||||
cod.setObjectType(CommonObjectDataSubRecord.OBJECT_TYPE_COMMENT);
|
||||
}
|
||||
|
||||
protected HSSFComment(NoteRecord note, TextObjectRecord txo) {
|
||||
this((HSSFShape) null, (HSSFAnchor) null);
|
||||
_txo = txo;
|
||||
this(null, new HSSFClientAnchor());
|
||||
_note = note;
|
||||
}
|
||||
|
||||
@Override
|
||||
void afterInsert(HSSFPatriarch patriarch) {
|
||||
super.afterInsert(patriarch);
|
||||
patriarch._getBoundAggregate().addTailRecord(getNoteRecord());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EscherContainerRecord createSpContainer() {
|
||||
EscherContainerRecord spContainer = super.createSpContainer();
|
||||
EscherOptRecord opt = spContainer.getChildById(EscherOptRecord.RECORD_ID);
|
||||
opt.removeEscherProperty(EscherProperties.TEXT__TEXTLEFT);
|
||||
opt.removeEscherProperty(EscherProperties.TEXT__TEXTRIGHT);
|
||||
opt.removeEscherProperty(EscherProperties.TEXT__TEXTTOP);
|
||||
opt.removeEscherProperty(EscherProperties.TEXT__TEXTBOTTOM);
|
||||
opt.setEscherProperty(new EscherSimpleProperty(EscherProperties.GROUPSHAPE__PRINT, false, false, 655362));
|
||||
return spContainer;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ObjRecord createObjRecord() {
|
||||
ObjRecord obj = new ObjRecord();
|
||||
CommonObjectDataSubRecord c = new CommonObjectDataSubRecord();
|
||||
c.setObjectType(OBJECT_TYPE_COMMENT);
|
||||
c.setLocked(true);
|
||||
c.setPrintable(true);
|
||||
c.setAutofill(false);
|
||||
c.setAutoline(true);
|
||||
|
||||
NoteStructureSubRecord u = new NoteStructureSubRecord();
|
||||
EndSubRecord e = new EndSubRecord();
|
||||
obj.addSubRecord(c);
|
||||
obj.addSubRecord(u);
|
||||
obj.addSubRecord(e);
|
||||
return obj;
|
||||
}
|
||||
|
||||
private NoteRecord createNoteRecord(){
|
||||
NoteRecord note = new NoteRecord();
|
||||
note.setFlags(NoteRecord.NOTE_HIDDEN);
|
||||
note.setAuthor("");
|
||||
return note;
|
||||
}
|
||||
|
||||
@Override
|
||||
void setShapeId(int shapeId) {
|
||||
super.setShapeId(shapeId);
|
||||
CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) getObjRecord().getSubRecords().get(0);
|
||||
cod.setObjectId((short) (shapeId % 1024));
|
||||
_note.setShapeId(shapeId % 1024);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this comment is visible.
|
||||
*
|
||||
* @param visible <code>true</code> if the comment is visible, <code>false</code> otherwise
|
||||
*/
|
||||
public void setVisible(boolean visible){
|
||||
if(_note != null) {
|
||||
_note.setFlags(visible ? NoteRecord.NOTE_VISIBLE : NoteRecord.NOTE_HIDDEN);
|
||||
}
|
||||
_visible = visible;
|
||||
public void setVisible(boolean visible) {
|
||||
_note.setFlags(visible ? NoteRecord.NOTE_VISIBLE : NoteRecord.NOTE_HIDDEN);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -89,7 +137,7 @@ public class HSSFComment extends HSSFTextbox implements Comment {
|
||||
* @return <code>true</code> if the comment is visible, <code>false</code> otherwise
|
||||
*/
|
||||
public boolean isVisible() {
|
||||
return _visible;
|
||||
return _note.getFlags() == NoteRecord.NOTE_VISIBLE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -98,7 +146,7 @@ public class HSSFComment extends HSSFTextbox implements Comment {
|
||||
* @return the 0-based row of the cell that contains the comment
|
||||
*/
|
||||
public int getRow() {
|
||||
return _row;
|
||||
return _note.getRow();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -107,10 +155,7 @@ public class HSSFComment extends HSSFTextbox implements Comment {
|
||||
* @param row the 0-based row of the cell that contains the comment
|
||||
*/
|
||||
public void setRow(int row) {
|
||||
if(_note != null) {
|
||||
_note.setRow(row);
|
||||
}
|
||||
_row = row;
|
||||
_note.setRow(row);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -118,8 +163,8 @@ public class HSSFComment extends HSSFTextbox implements Comment {
|
||||
*
|
||||
* @return the 0-based column of the cell that contains the comment
|
||||
*/
|
||||
public int getColumn(){
|
||||
return _col;
|
||||
public int getColumn() {
|
||||
return _note.getColumn();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -128,17 +173,15 @@ public class HSSFComment extends HSSFTextbox implements Comment {
|
||||
* @param col the 0-based column of the cell that contains the comment
|
||||
*/
|
||||
public void setColumn(int col) {
|
||||
if(_note != null) {
|
||||
_note.setColumn(col);
|
||||
}
|
||||
_col = col;
|
||||
_note.setColumn(col);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated (Nov 2009) use {@link HSSFComment#setColumn(int)} }
|
||||
*/
|
||||
@Deprecated
|
||||
public void setColumn(short col) {
|
||||
setColumn((int)col);
|
||||
setColumn((int) col);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -147,7 +190,7 @@ public class HSSFComment extends HSSFTextbox implements Comment {
|
||||
* @return the name of the original author of the comment
|
||||
*/
|
||||
public String getAuthor() {
|
||||
return _author;
|
||||
return _note.getAuthor();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -155,37 +198,57 @@ public class HSSFComment extends HSSFTextbox implements Comment {
|
||||
*
|
||||
* @param author the name of the original author of the comment
|
||||
*/
|
||||
public void setAuthor(String author){
|
||||
if(_note != null) _note.setAuthor(author);
|
||||
this._author = author;
|
||||
public void setAuthor(String author) {
|
||||
if (_note != null) _note.setAuthor(author);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the rich text string used by this comment.
|
||||
*
|
||||
* @param string Sets the rich text string used by this object.
|
||||
*/
|
||||
public void setString(RichTextString string) {
|
||||
HSSFRichTextString hstring = (HSSFRichTextString) string;
|
||||
//if font is not set we must set the default one
|
||||
if (hstring.numFormattingRuns() == 0) hstring.applyFont((short)0);
|
||||
|
||||
if (_txo != null) {
|
||||
_txo.setStr(hstring);
|
||||
}
|
||||
super.setString(string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the underlying Note record
|
||||
*/
|
||||
protected NoteRecord getNoteRecord() {
|
||||
return _note;
|
||||
}
|
||||
/**
|
||||
* Returns the underlying Text record
|
||||
*/
|
||||
protected TextObjectRecord getTextObjectRecord() {
|
||||
return _txo;
|
||||
}
|
||||
return _note;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setShapeType(int shapeType) {
|
||||
throw new IllegalStateException("Shape type can not be changed in "+this.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
public void afterRemove(HSSFPatriarch patriarch){
|
||||
super.afterRemove(patriarch);
|
||||
patriarch._getBoundAggregate().removeTailRecord(getNoteRecord());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected 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);
|
||||
}
|
||||
|
||||
public void setBackgroundImage(int pictureIndex){
|
||||
setPropertyValue(new EscherSimpleProperty( EscherProperties.FILL__PATTERNTEXTURE, false, true, pictureIndex));
|
||||
setPropertyValue(new EscherSimpleProperty( EscherProperties.FILL__FILLTYPE, false, false, FILL_TYPE_PICTURE));
|
||||
EscherBSERecord bse = getPatriarch().getSheet().getWorkbook().getWorkbook().getBSERecord(pictureIndex);
|
||||
bse.setRef(bse.getRef() + 1);
|
||||
}
|
||||
|
||||
public void resetBackgroundImage(){
|
||||
EscherSimpleProperty property = getOptRecord().lookup(EscherProperties.FILL__PATTERNTEXTURE);
|
||||
if (null != property){
|
||||
EscherBSERecord bse = getPatriarch().getSheet().getWorkbook().getWorkbook().getBSERecord(property.getPropertyValue());
|
||||
bse.setRef(bse.getRef() - 1);
|
||||
getOptRecord().removeEscherProperty(EscherProperties.FILL__PATTERNTEXTURE);
|
||||
}
|
||||
setPropertyValue(new EscherSimpleProperty( EscherProperties.FILL__FILLTYPE, false, false, FILL_TYPE_SOLID));
|
||||
}
|
||||
|
||||
public int getBackgroundImageId(){
|
||||
EscherSimpleProperty property = getOptRecord().lookup(EscherProperties.FILL__PATTERNTEXTURE);
|
||||
return property == null ? 0 : property.getPropertyValue();
|
||||
}
|
||||
}
|
||||
|
@ -21,39 +21,28 @@ package org.apache.poi.hssf.usermodel;
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
|
||||
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 {
|
||||
/**
|
||||
* Underlying object record ultimately containing a reference to the object.
|
||||
*/
|
||||
private final ObjRecord _record;
|
||||
|
||||
public final class HSSFObjectData extends HSSFPicture {
|
||||
/**
|
||||
* Reference to the filesystem root, required for retrieving the object data.
|
||||
*/
|
||||
private final DirectoryEntry _root;
|
||||
|
||||
/**
|
||||
* Constructs object data by wrapping a lower level object record.
|
||||
*
|
||||
* @param record the low-level object record.
|
||||
* @param root the root of the filesystem, required for retrieving the object data.
|
||||
*/
|
||||
public HSSFObjectData(ObjRecord record, DirectoryEntry root)
|
||||
{
|
||||
_record = record;
|
||||
_root = root;
|
||||
public HSSFObjectData(EscherContainerRecord spContainer, ObjRecord objRecord, DirectoryEntry _root) {
|
||||
super(spContainer, objRecord);
|
||||
this._root = _root;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -65,7 +54,7 @@ public final class HSSFObjectData {
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@ -85,8 +74,8 @@ public final class HSSFObjectData {
|
||||
|
||||
/**
|
||||
* 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();
|
||||
@ -94,7 +83,7 @@ public final class HSSFObjectData {
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
@ -107,18 +96,51 @@ public final class HSSFObjectData {
|
||||
|
||||
/**
|
||||
* Finds the EmbeddedObjectRefSubRecord, or throws an
|
||||
* Exception if there wasn't one
|
||||
* Exception if there wasn't one
|
||||
*/
|
||||
protected EmbeddedObjectRefSubRecord findObjectRecord() {
|
||||
Iterator<SubRecord> subRecordIter = _record.getSubRecords().iterator();
|
||||
Iterator<SubRecord> subRecordIter = getObjRecord().getSubRecords().iterator();
|
||||
|
||||
while (subRecordIter.hasNext()) {
|
||||
Object subRecord = subRecordIter.next();
|
||||
if (subRecord instanceof EmbeddedObjectRefSubRecord) {
|
||||
return (EmbeddedObjectRefSubRecord)subRecord;
|
||||
return (EmbeddedObjectRefSubRecord) subRecord;
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalStateException("Object data does not contain a reference to an embedded object OLE2 directory");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EscherContainerRecord createSpContainer() {
|
||||
throw new IllegalStateException("HSSFObjectData cannot be created from scratch");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ObjRecord createObjRecord() {
|
||||
throw new IllegalStateException("HSSFObjectData cannot be created from scratch");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void afterRemove(HSSFPatriarch patriarch) {
|
||||
throw new IllegalStateException("HSSFObjectData cannot be created from scratch");
|
||||
}
|
||||
|
||||
@Override
|
||||
void afterInsert(HSSFPatriarch patriarch) {
|
||||
EscherAggregate agg = patriarch._getBoundAggregate();
|
||||
agg.associateShapeToObjRecord(getEscherContainer().getChildById(EscherClientDataRecord.RECORD_ID), getObjRecord());
|
||||
EscherBSERecord bse =
|
||||
patriarch.getSheet().getWorkbook().getWorkbook().getBSERecord(getPictureIndex());
|
||||
bse.setRef(bse.getRef() + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected 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);
|
||||
}
|
||||
}
|
||||
|
@ -18,13 +18,12 @@
|
||||
package org.apache.poi.hssf.usermodel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.poi.ddf.EscherComplexProperty;
|
||||
import org.apache.poi.ddf.EscherOptRecord;
|
||||
import org.apache.poi.ddf.EscherProperty;
|
||||
import org.apache.poi.ddf.EscherBSERecord;
|
||||
import org.apache.poi.ddf.*;
|
||||
import org.apache.poi.hssf.model.DrawingManager2;
|
||||
import org.apache.poi.hssf.record.EscherAggregate;
|
||||
import org.apache.poi.ss.usermodel.Chart;
|
||||
import org.apache.poi.util.StringUtil;
|
||||
@ -40,41 +39,89 @@ 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;
|
||||
|
||||
/**
|
||||
* 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
|
||||
private final HSSFSheet _sheet;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
_spgrRecord = spContainer.getChildById(EscherSpgrRecord.RECORD_ID);
|
||||
buildShapeTree();
|
||||
}
|
||||
|
||||
/**
|
||||
* used to clone patriarch
|
||||
*
|
||||
* create patriarch from existing one
|
||||
* @param patriarch - copy all the shapes from this patriarch to new one
|
||||
* @param sheet where must be located new patriarch
|
||||
* @return new patriarch with copies of all shapes from the existing patriarch
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param shape to be removed
|
||||
* @return true of shape is removed
|
||||
*/
|
||||
public boolean removeShape(HSSFShape shape) {
|
||||
boolean isRemoved = _mainSpgrContainer.removeChildRecord(shape.getEscherContainer());
|
||||
if (isRemoved){
|
||||
shape.afterRemove(this);
|
||||
_shapes.remove(shape);
|
||||
}
|
||||
return isRemoved;
|
||||
}
|
||||
|
||||
void afterCreate() {
|
||||
DrawingManager2 drawingManager = _sheet.getWorkbook().getWorkbook().getDrawingManager();
|
||||
short dgId = drawingManager.findNewDrawingGroupId();
|
||||
_boundAggregate.setDgId(dgId);
|
||||
_boundAggregate.setMainSpRecordId(newShapeId());
|
||||
drawingManager.incrementDrawingsSaved();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
group.anchor = anchor;
|
||||
addShape(group);
|
||||
onCreate(group);
|
||||
return group;
|
||||
}
|
||||
|
||||
@ -82,84 +129,86 @@ 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);
|
||||
shape.anchor = anchor;
|
||||
addShape(shape);
|
||||
//open existing file
|
||||
onCreate(shape);
|
||||
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.anchor = anchor;
|
||||
shape.setPictureIndex(pictureIndex);
|
||||
addShape(shape);
|
||||
|
||||
EscherBSERecord bse = _sheet.getWorkbook().getWorkbook().getBSERecord(pictureIndex);
|
||||
bse.setRef(bse.getRef() + 1);
|
||||
//open existing file
|
||||
onCreate(shape);
|
||||
return shape;
|
||||
}
|
||||
|
||||
public HSSFPicture createPicture(ClientAnchor anchor, int pictureIndex)
|
||||
{
|
||||
return createPicture((HSSFClientAnchor)anchor, pictureIndex);
|
||||
/**
|
||||
*
|
||||
* @param anchor the client anchor describes how this picture is
|
||||
* attached to the sheet.
|
||||
* @param pictureIndex the index of the picture in the workbook collection
|
||||
* of pictures.
|
||||
*
|
||||
* @return newly created shape
|
||||
*/
|
||||
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);
|
||||
shape.anchor = anchor;
|
||||
addShape(shape);
|
||||
onCreate(shape);
|
||||
return 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);
|
||||
shape.anchor = anchor;
|
||||
addShape(shape);
|
||||
onCreate(shape);
|
||||
return 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);
|
||||
shape.anchor = anchor;
|
||||
addShape(shape);
|
||||
onCreate(shape);
|
||||
return shape;
|
||||
}
|
||||
|
||||
@ -168,83 +217,116 @@ 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)
|
||||
{
|
||||
HSSFSimpleShape shape = new HSSFSimpleShape(null, anchor);
|
||||
shape.setShapeType(HSSFSimpleShape.OBJECT_TYPE_COMBO_BOX);
|
||||
shape.anchor = anchor;
|
||||
addShape(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.
|
||||
* Returns a unmodifiable list of all shapes contained by the patriarch.
|
||||
*/
|
||||
public List<HSSFShape> getChildren()
|
||||
{
|
||||
return _shapes;
|
||||
public List<HSSFShape> getChildren() {
|
||||
return Collections.unmodifiableList(_shapes);
|
||||
}
|
||||
|
||||
/**
|
||||
* add a shape to this drawing
|
||||
*/
|
||||
@Internal
|
||||
public void addShape(HSSFShape shape){
|
||||
shape._patriarch = this;
|
||||
public void addShape(HSSFShape shape) {
|
||||
shape.setPatriarch(this);
|
||||
_shapes.add(shape);
|
||||
}
|
||||
|
||||
private void onCreate(HSSFShape shape) {
|
||||
EscherContainerRecord spgrContainer =
|
||||
_boundAggregate.getEscherContainer().getChildContainers().get(0);
|
||||
|
||||
EscherContainerRecord spContainer = shape.getEscherContainer();
|
||||
int shapeId = newShapeId();
|
||||
shape.setShapeId(shapeId);
|
||||
|
||||
spgrContainer.addChildRecord(spContainer);
|
||||
shape.afterInsert(this);
|
||||
setFlipFlags(shape);
|
||||
}
|
||||
|
||||
/**
|
||||
* Total count of all children and their children's children.
|
||||
* @return count of shapes including shapes inside shape groups
|
||||
*/
|
||||
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){
|
||||
_x1 = x1;
|
||||
_y1 = y1;
|
||||
_x2 = x2;
|
||||
_y2 = y2;
|
||||
public void setCoordinates(int x1, int y1, int x2, int y2) {
|
||||
_spgrRecord.setRectY1(y1);
|
||||
_spgrRecord.setRectY2(y2);
|
||||
_spgrRecord.setRectX1(x1);
|
||||
_spgrRecord.setRectX2(x2);
|
||||
}
|
||||
|
||||
/**
|
||||
* remove all shapes inside patriarch
|
||||
*/
|
||||
public void clear() {
|
||||
ArrayList <HSSFShape> copy = new ArrayList<HSSFShape>(_shapes);
|
||||
for (HSSFShape shape: copy){
|
||||
removeShape(shape);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return new unique shapeId
|
||||
*/
|
||||
int newShapeId() {
|
||||
DrawingManager2 dm = _sheet.getWorkbook().getWorkbook().getDrawingManager();
|
||||
EscherDgRecord dg =
|
||||
_boundAggregate.getEscherContainer().getChildById(EscherDgRecord.RECORD_ID);
|
||||
short drawingGroupId = dg.getDrawingGroupId();
|
||||
return dm.allocateShapeId(drawingGroupId, dg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this HSSFPatriarch contain a chart?
|
||||
* (Technically a reference to a chart, since they
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
@ -254,35 +336,31 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
|
||||
}
|
||||
|
||||
/**
|
||||
* The top left x coordinate of this group.
|
||||
* @return x coordinate of the left up corner
|
||||
*/
|
||||
public int getX1()
|
||||
{
|
||||
return _x1;
|
||||
public int getX1() {
|
||||
return _spgrRecord.getRectX1();
|
||||
}
|
||||
|
||||
/**
|
||||
* The top left y coordinate of this group.
|
||||
* @return y coordinate of the left up corner
|
||||
*/
|
||||
public int getY1()
|
||||
{
|
||||
return _y1;
|
||||
public int getY1() {
|
||||
return _spgrRecord.getRectY1();
|
||||
}
|
||||
|
||||
/**
|
||||
* The bottom right x coordinate of this group.
|
||||
* @return x coordinate of the right down corner
|
||||
*/
|
||||
public int getX2()
|
||||
{
|
||||
return _x2;
|
||||
public int getX2() {
|
||||
return _spgrRecord.getRectX2();
|
||||
}
|
||||
|
||||
/**
|
||||
* The bottom right y coordinate of this group.
|
||||
* @return y coordinate of the right down corner
|
||||
*/
|
||||
public int getY2()
|
||||
{
|
||||
return _y2;
|
||||
public int getY2() {
|
||||
return _spgrRecord.getRectY2();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -306,12 +384,51 @@ 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");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* create shape tree from existing escher records tree
|
||||
*/
|
||||
void buildShapeTree() {
|
||||
EscherContainerRecord dgContainer = _boundAggregate.getEscherContainer();
|
||||
if (dgContainer == null) {
|
||||
return;
|
||||
}
|
||||
EscherContainerRecord spgrConrainer = dgContainer.getChildContainers().get(0);
|
||||
List<EscherContainerRecord> spgrChildren = spgrConrainer.getChildContainers();
|
||||
|
||||
for (int i = 0; i < spgrChildren.size(); i++) {
|
||||
EscherContainerRecord spContainer = spgrChildren.get(i);
|
||||
if (i == 0) {
|
||||
continue;
|
||||
} else {
|
||||
HSSFShapeFactory.createShapeTree(spContainer, _boundAggregate, this, _sheet.getWorkbook().getRootDirectory());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setFlipFlags(HSSFShape shape){
|
||||
EscherSpRecord sp = shape.getEscherContainer().getChildById(EscherSpRecord.RECORD_ID);
|
||||
if (shape.getAnchor().isHorizontallyFlipped()) {
|
||||
sp.setFlags(sp.getFlags() | EscherSpRecord.FLAG_FLIPHORIZ);
|
||||
}
|
||||
if (shape.getAnchor().isVerticallyFlipped()) {
|
||||
sp.setFlags(sp.getFlags() | EscherSpRecord.FLAG_FLIPVERT);
|
||||
}
|
||||
}
|
||||
|
||||
public Iterator<HSSFShape> iterator() {
|
||||
return _shapes.iterator();
|
||||
}
|
||||
|
||||
protected HSSFSheet getSheet() {
|
||||
return _sheet;
|
||||
}
|
||||
}
|
||||
|
@ -19,9 +19,12 @@ package org.apache.poi.hssf.usermodel;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import org.apache.poi.ddf.EscherBSERecord;
|
||||
import org.apache.poi.ddf.EscherBlipRecord;
|
||||
import org.apache.poi.ddf.*;
|
||||
import org.apache.poi.hssf.record.CommonObjectDataSubRecord;
|
||||
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;
|
||||
import org.apache.poi.hssf.model.InternalWorkbook;
|
||||
@ -32,7 +35,7 @@ import org.apache.poi.hssf.model.InternalWorkbook;
|
||||
* @author Glen Stampoultzis
|
||||
* @author Yegor Kozlov (yegor at apache.org)
|
||||
*/
|
||||
public final class HSSFPicture extends HSSFSimpleShape implements Picture {
|
||||
public class HSSFPicture extends HSSFSimpleShape implements Picture {
|
||||
public static final int PICTURE_TYPE_EMF = HSSFWorkbook.PICTURE_TYPE_EMF; // Windows Enhanced Metafile
|
||||
public static final int PICTURE_TYPE_WMF = HSSFWorkbook.PICTURE_TYPE_WMF; // Windows Metafile
|
||||
public static final int PICTURE_TYPE_PICT = HSSFWorkbook.PICTURE_TYPE_PICT; // Macintosh PICT
|
||||
@ -54,7 +57,9 @@ public final class HSSFPicture extends HSSFSimpleShape implements Picture {
|
||||
*/
|
||||
private static final int PX_ROW = 15;
|
||||
|
||||
private int _pictureIndex;
|
||||
public HSSFPicture(EscherContainerRecord spContainer, ObjRecord objRecord) {
|
||||
super(spContainer, objRecord);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a picture object.
|
||||
@ -62,17 +67,33 @@ public final class HSSFPicture extends HSSFSimpleShape implements Picture {
|
||||
public HSSFPicture( HSSFShape parent, HSSFAnchor anchor )
|
||||
{
|
||||
super( parent, anchor );
|
||||
setShapeType(OBJECT_TYPE_PICTURE);
|
||||
super.setShapeType(OBJECT_TYPE_PICTURE);
|
||||
CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) getObjRecord().getSubRecords().get(0);
|
||||
cod.setObjectType(CommonObjectDataSubRecord.OBJECT_TYPE_PICTURE);
|
||||
}
|
||||
|
||||
public int getPictureIndex()
|
||||
{
|
||||
return _pictureIndex;
|
||||
EscherSimpleProperty property = getOptRecord().lookup(EscherProperties.BLIP__BLIPTODISPLAY);
|
||||
if (null == property){
|
||||
return -1;
|
||||
}
|
||||
return property.getPropertyValue();
|
||||
}
|
||||
|
||||
public void setPictureIndex( int pictureIndex )
|
||||
{
|
||||
this._pictureIndex = pictureIndex;
|
||||
setPropertyValue(new EscherSimpleProperty( EscherProperties.BLIP__BLIPTODISPLAY, false, true, pictureIndex));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EscherContainerRecord createSpContainer() {
|
||||
EscherContainerRecord spContainer = super.createSpContainer();
|
||||
EscherOptRecord opt = spContainer.getChildById(EscherOptRecord.RECORD_ID);
|
||||
opt.removeEscherProperty(EscherProperties.LINESTYLE__LINEDASHING);
|
||||
opt.removeEscherProperty(EscherProperties.LINESTYLE__NOLINEDRAWDASH);
|
||||
spContainer.removeChildRecord(spContainer.getChildById(EscherTextboxRecord.RECORD_ID));
|
||||
return spContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -145,8 +166,8 @@ public final class HSSFPicture extends HSSFSimpleShape implements Picture {
|
||||
float w = 0;
|
||||
|
||||
//space in the leftmost cell
|
||||
w += getColumnWidthInPixels(anchor.col1)*(1 - (float)anchor.dx1/1024);
|
||||
short col2 = (short)(anchor.col1 + 1);
|
||||
w += getColumnWidthInPixels(anchor.getCol1())*(1 - (float)anchor.getDx1()/1024);
|
||||
short col2 = (short)(anchor.getCol1() + 1);
|
||||
int dx2 = 0;
|
||||
|
||||
while(w < scaledWidth){
|
||||
@ -160,12 +181,12 @@ public final class HSSFPicture extends HSSFSimpleShape implements Picture {
|
||||
double delta = w - scaledWidth;
|
||||
dx2 = (int)((cw-delta)/cw*1024);
|
||||
}
|
||||
anchor.col2 = col2;
|
||||
anchor.dx2 = dx2;
|
||||
anchor.setCol2(col2);
|
||||
anchor.setDx2(dx2);
|
||||
|
||||
float h = 0;
|
||||
h += (1 - (float)anchor.dy1/256)* getRowHeightInPixels(anchor.row1);
|
||||
int row2 = anchor.row1 + 1;
|
||||
h += (1 - (float)anchor.getDy1()/256)* getRowHeightInPixels(anchor.getRow1());
|
||||
int row2 = anchor.getRow1() + 1;
|
||||
int dy2 = 0;
|
||||
|
||||
while(h < scaledHeight){
|
||||
@ -177,15 +198,15 @@ public final class HSSFPicture extends HSSFSimpleShape implements Picture {
|
||||
double delta = h - scaledHeight;
|
||||
dy2 = (int)((ch-delta)/ch*256);
|
||||
}
|
||||
anchor.row2 = row2;
|
||||
anchor.dy2 = dy2;
|
||||
anchor.setRow2(row2);
|
||||
anchor.setDy2(dy2);
|
||||
|
||||
return anchor;
|
||||
}
|
||||
|
||||
private float getColumnWidthInPixels(int column){
|
||||
|
||||
int cw = _patriarch._sheet.getColumnWidth(column);
|
||||
int cw = getPatriarch().getSheet().getColumnWidth(column);
|
||||
float px = getPixelWidth(column);
|
||||
|
||||
return cw/px;
|
||||
@ -193,18 +214,18 @@ public final class HSSFPicture extends HSSFSimpleShape implements Picture {
|
||||
|
||||
private float getRowHeightInPixels(int i){
|
||||
|
||||
HSSFRow row = _patriarch._sheet.getRow(i);
|
||||
HSSFRow row = getPatriarch().getSheet().getRow(i);
|
||||
float height;
|
||||
if(row != null) height = row.getHeight();
|
||||
else height = _patriarch._sheet.getDefaultRowHeight();
|
||||
else height = getPatriarch().getSheet().getDefaultRowHeight();
|
||||
|
||||
return height/PX_ROW;
|
||||
}
|
||||
|
||||
private float getPixelWidth(int column){
|
||||
|
||||
int def = _patriarch._sheet.getDefaultColumnWidth()*256;
|
||||
int cw = _patriarch._sheet.getColumnWidth(column);
|
||||
int def = getPatriarch().getSheet().getDefaultColumnWidth()*256;
|
||||
int cw = getPatriarch().getSheet().getColumnWidth(column);
|
||||
|
||||
return cw == def ? PX_DEFAULT : PX_MODIFIED;
|
||||
}
|
||||
@ -215,7 +236,7 @@ public final class HSSFPicture extends HSSFSimpleShape implements Picture {
|
||||
* @return image dimension
|
||||
*/
|
||||
public Dimension getImageDimension(){
|
||||
EscherBSERecord bse = _patriarch._sheet._book.getBSERecord(_pictureIndex);
|
||||
EscherBSERecord bse = getPatriarch().getSheet()._book.getBSERecord(getPictureIndex());
|
||||
byte[] data = bse.getBlipRecord().getPicturedata();
|
||||
int type = bse.getBlipTypeWin32();
|
||||
return ImageUtils.getImageDimension(new ByteArrayInputStream(data), type);
|
||||
@ -227,8 +248,56 @@ public final class HSSFPicture extends HSSFSimpleShape implements Picture {
|
||||
* @return picture data for this shape
|
||||
*/
|
||||
public HSSFPictureData getPictureData(){
|
||||
InternalWorkbook iwb = _patriarch._sheet.getWorkbook().getWorkbook();
|
||||
EscherBlipRecord blipRecord = iwb.getBSERecord(_pictureIndex).getBlipRecord();
|
||||
InternalWorkbook iwb = getPatriarch().getSheet().getWorkbook().getWorkbook();
|
||||
EscherBlipRecord blipRecord = iwb.getBSERecord(getPictureIndex()).getBlipRecord();
|
||||
return new HSSFPictureData(blipRecord);
|
||||
}
|
||||
|
||||
@Override
|
||||
void afterInsert(HSSFPatriarch patriarch) {
|
||||
EscherAggregate agg = patriarch._getBoundAggregate();
|
||||
agg.associateShapeToObjRecord(getEscherContainer().getChildById(EscherClientDataRecord.RECORD_ID), getObjRecord());
|
||||
EscherBSERecord bse =
|
||||
patriarch.getSheet().getWorkbook().getWorkbook().getBSERecord(getPictureIndex());
|
||||
bse.setRef(bse.getRef() + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* The color applied to the lines of this shape.
|
||||
*/
|
||||
public String getFileName() {
|
||||
EscherComplexProperty propFile = (EscherComplexProperty) getOptRecord().lookup(
|
||||
EscherProperties.BLIP__BLIPFILENAME);
|
||||
try {
|
||||
if (null == propFile){
|
||||
return "";
|
||||
}
|
||||
return new String(propFile.getComplexData(), "UTF-16LE").trim();
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public void setFileName(String data){
|
||||
try {
|
||||
EscherComplexProperty prop = new EscherComplexProperty(EscherProperties.BLIP__BLIPFILENAME, true, data.getBytes("UTF-16LE"));
|
||||
setPropertyValue(prop);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
System.out.println("Unsupported encoding: UTF-16LE");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setShapeType(int shapeType) {
|
||||
throw new IllegalStateException("Shape type can not be changed in "+this.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected 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);
|
||||
}
|
||||
}
|
||||
|
@ -17,45 +17,184 @@
|
||||
|
||||
package org.apache.poi.hssf.usermodel;
|
||||
|
||||
import org.apache.poi.ddf.*;
|
||||
import org.apache.poi.hssf.record.*;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
/**
|
||||
* @author Glen Stampoultzis (glens at superlinksoftware.com)
|
||||
*/
|
||||
public class HSSFPolygon
|
||||
extends HSSFShape
|
||||
{
|
||||
int[] xPoints;
|
||||
int[] yPoints;
|
||||
int drawAreaWidth = 100;
|
||||
int drawAreaHeight = 100;
|
||||
public class HSSFPolygon extends HSSFSimpleShape {
|
||||
|
||||
HSSFPolygon( HSSFShape parent, HSSFAnchor anchor )
|
||||
{
|
||||
super( parent, anchor );
|
||||
public final static short OBJECT_TYPE_MICROSOFT_OFFICE_DRAWING = 0x1E;
|
||||
|
||||
public HSSFPolygon(EscherContainerRecord spContainer, ObjRecord objRecord, TextObjectRecord _textObjectRecord) {
|
||||
super(spContainer, objRecord, _textObjectRecord);
|
||||
}
|
||||
|
||||
public int[] getXPoints()
|
||||
{
|
||||
return xPoints;
|
||||
public HSSFPolygon(EscherContainerRecord spContainer, ObjRecord objRecord) {
|
||||
super(spContainer, objRecord);
|
||||
}
|
||||
|
||||
public int[] getYPoints()
|
||||
{
|
||||
return yPoints;
|
||||
HSSFPolygon(HSSFShape parent, HSSFAnchor anchor) {
|
||||
super(parent, anchor);
|
||||
}
|
||||
|
||||
public void setPoints(int[] xPoints, int[] yPoints)
|
||||
{
|
||||
this.xPoints = cloneArray(xPoints);
|
||||
this.yPoints = cloneArray(yPoints);
|
||||
@Override
|
||||
protected TextObjectRecord createTextObjRecord() {
|
||||
return null;
|
||||
}
|
||||
|
||||
private int[] cloneArray( int[] a )
|
||||
{
|
||||
int[] result = new int[a.length];
|
||||
for ( int i = 0; i < a.length; i++ )
|
||||
result[i] = a[i];
|
||||
/**
|
||||
* Generates the shape records for this shape.
|
||||
*/
|
||||
protected EscherContainerRecord createSpContainer() {
|
||||
EscherContainerRecord spContainer = new EscherContainerRecord();
|
||||
EscherSpRecord sp = new EscherSpRecord();
|
||||
EscherOptRecord opt = new EscherOptRecord();
|
||||
EscherClientDataRecord clientData = new EscherClientDataRecord();
|
||||
|
||||
return result;
|
||||
spContainer.setRecordId(EscherContainerRecord.SP_CONTAINER);
|
||||
spContainer.setOptions((short) 0x000F);
|
||||
sp.setRecordId(EscherSpRecord.RECORD_ID);
|
||||
sp.setOptions((short) ((EscherAggregate.ST_NOT_PRIMATIVE << 4) | 0x2));
|
||||
if (getParent() == null) {
|
||||
sp.setFlags(EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HASSHAPETYPE);
|
||||
} else {
|
||||
sp.setFlags(EscherSpRecord.FLAG_CHILD | EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HASSHAPETYPE);
|
||||
}
|
||||
opt.setRecordId(EscherOptRecord.RECORD_ID);
|
||||
opt.setEscherProperty(new EscherSimpleProperty(EscherProperties.TRANSFORM__ROTATION, false, false, 0));
|
||||
opt.setEscherProperty(new EscherSimpleProperty(EscherProperties.GEOMETRY__RIGHT, false, false, 100));
|
||||
opt.setEscherProperty(new EscherSimpleProperty(EscherProperties.GEOMETRY__BOTTOM, false, false, 100));
|
||||
opt.setEscherProperty(new EscherShapePathProperty(EscherProperties.GEOMETRY__SHAPEPATH, EscherShapePathProperty.COMPLEX));
|
||||
|
||||
opt.setEscherProperty(new EscherSimpleProperty(EscherProperties.GEOMETRY__FILLOK, false, false, 0x00010001));
|
||||
opt.setEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINESTARTARROWHEAD, false, false, 0x0));
|
||||
opt.setEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEENDARROWHEAD, false, false, 0x0));
|
||||
opt.setEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEENDCAPSTYLE, false, false, 0x0));
|
||||
|
||||
opt.setEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEDASHING, LINESTYLE_SOLID));
|
||||
opt.setEscherProperty( new EscherBoolProperty( EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x00080008));
|
||||
opt.setEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEWIDTH, LINEWIDTH_DEFAULT));
|
||||
opt.setEscherProperty(new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, FILL__FILLCOLOR_DEFAULT));
|
||||
opt.setEscherProperty(new EscherRGBProperty(EscherProperties.LINESTYLE__COLOR, LINESTYLE__COLOR_DEFAULT));
|
||||
opt.setEscherProperty(new EscherBoolProperty(EscherProperties.FILL__NOFILLHITTEST, 1));
|
||||
|
||||
opt.setEscherProperty(new EscherBoolProperty( EscherProperties.GROUPSHAPE__PRINT, 0x080000));
|
||||
|
||||
EscherRecord anchor = getAnchor().getEscherAnchor();
|
||||
clientData.setRecordId(EscherClientDataRecord.RECORD_ID);
|
||||
clientData.setOptions((short) 0x0000);
|
||||
|
||||
spContainer.addChildRecord(sp);
|
||||
spContainer.addChildRecord(opt);
|
||||
spContainer.addChildRecord(anchor);
|
||||
spContainer.addChildRecord(clientData);
|
||||
|
||||
return spContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the low level OBJ record for this shape.
|
||||
*/
|
||||
protected ObjRecord createObjRecord() {
|
||||
ObjRecord obj = new ObjRecord();
|
||||
CommonObjectDataSubRecord c = new CommonObjectDataSubRecord();
|
||||
c.setObjectType(OBJECT_TYPE_MICROSOFT_OFFICE_DRAWING);
|
||||
c.setLocked(true);
|
||||
c.setPrintable(true);
|
||||
c.setAutofill(true);
|
||||
c.setAutoline(true);
|
||||
EndSubRecord e = new EndSubRecord();
|
||||
obj.addSubRecord(c);
|
||||
obj.addSubRecord(e);
|
||||
return obj;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void afterRemove(HSSFPatriarch patriarch) {
|
||||
patriarch._getBoundAggregate().removeShapeToObjRecord(getEscherContainer().getChildById(EscherClientDataRecord.RECORD_ID));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array of x coordinates
|
||||
*/
|
||||
public int[] getXPoints() {
|
||||
EscherArrayProperty verticesProp = getOptRecord().lookup(EscherProperties.GEOMETRY__VERTICES);
|
||||
if (null == verticesProp){
|
||||
return new int[]{};
|
||||
}
|
||||
int []array = new int[verticesProp.getNumberOfElementsInArray()-1];
|
||||
for (int i=0; i< verticesProp.getNumberOfElementsInArray()-1; i++){
|
||||
byte[] property = verticesProp.getElement(i);
|
||||
short x = LittleEndian.getShort(property, 0);
|
||||
array[i] = x;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array of y coordinates
|
||||
*/
|
||||
public int[] getYPoints() {
|
||||
EscherArrayProperty verticesProp = getOptRecord().lookup(EscherProperties.GEOMETRY__VERTICES);
|
||||
if (null == verticesProp){
|
||||
return new int[]{};
|
||||
}
|
||||
int []array = new int[verticesProp.getNumberOfElementsInArray()-1];
|
||||
for (int i=0; i< verticesProp.getNumberOfElementsInArray()-1; i++){
|
||||
byte[] property = verticesProp.getElement(i);
|
||||
short x = LittleEndian.getShort(property, 2);
|
||||
array[i] = x;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param xPoints - array of x coordinates
|
||||
* @param yPoints - array of y coordinates
|
||||
*/
|
||||
public void setPoints(int[] xPoints, int[] yPoints) {
|
||||
if (xPoints.length != yPoints.length){
|
||||
System.out.println("xPoint.length must be equal to yPoints.length");
|
||||
return;
|
||||
}
|
||||
if (xPoints.length == 0){
|
||||
System.out.println("HSSFPolygon must have at least one point");
|
||||
}
|
||||
EscherArrayProperty verticesProp = new EscherArrayProperty(EscherProperties.GEOMETRY__VERTICES, false, new byte[0] );
|
||||
verticesProp.setNumberOfElementsInArray(xPoints.length+1);
|
||||
verticesProp.setNumberOfElementsInMemory(xPoints.length+1);
|
||||
verticesProp.setSizeOfElements(0xFFF0);
|
||||
for (int i = 0; i < xPoints.length; i++)
|
||||
{
|
||||
byte[] data = new byte[4];
|
||||
LittleEndian.putShort(data, 0, (short)xPoints[i]);
|
||||
LittleEndian.putShort(data, 2, (short)yPoints[i]);
|
||||
verticesProp.setElement(i, data);
|
||||
}
|
||||
int point = xPoints.length;
|
||||
byte[] data = new byte[4];
|
||||
LittleEndian.putShort(data, 0, (short)xPoints[0]);
|
||||
LittleEndian.putShort(data, 2, (short)yPoints[0]);
|
||||
verticesProp.setElement(point, data);
|
||||
setPropertyValue(verticesProp);
|
||||
|
||||
EscherArrayProperty segmentsProp = new EscherArrayProperty(EscherProperties.GEOMETRY__SEGMENTINFO, false, null );
|
||||
segmentsProp.setSizeOfElements(0x0002);
|
||||
segmentsProp.setNumberOfElementsInArray(xPoints.length * 2 + 4);
|
||||
segmentsProp.setNumberOfElementsInMemory(xPoints.length * 2 + 4);
|
||||
segmentsProp.setElement(0, new byte[] { (byte)0x00, (byte)0x40 } );
|
||||
segmentsProp.setElement(1, new byte[] { (byte)0x00, (byte)0xAC } );
|
||||
for (int i = 0; i < xPoints.length; i++)
|
||||
{
|
||||
segmentsProp.setElement(2 + i * 2, new byte[] { (byte)0x01, (byte)0x00 } );
|
||||
segmentsProp.setElement(3 + i * 2, new byte[] { (byte)0x00, (byte)0xAC } );
|
||||
}
|
||||
segmentsProp.setElement(segmentsProp.getNumberOfElementsInArray() - 2, new byte[] { (byte)0x01, (byte)0x60 } );
|
||||
segmentsProp.setElement(segmentsProp.getNumberOfElementsInArray() - 1, new byte[] { (byte)0x00, (byte)0x80 } );
|
||||
setPropertyValue(segmentsProp);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -63,21 +202,24 @@ public class HSSFPolygon
|
||||
* @param width
|
||||
* @param height
|
||||
*/
|
||||
public void setPolygonDrawArea( int width, int height )
|
||||
{
|
||||
this.drawAreaWidth = width;
|
||||
this.drawAreaHeight = height;
|
||||
public void setPolygonDrawArea(int width, int height) {
|
||||
setPropertyValue(new EscherSimpleProperty(EscherProperties.GEOMETRY__RIGHT, width));
|
||||
setPropertyValue(new EscherSimpleProperty(EscherProperties.GEOMETRY__BOTTOM, height));
|
||||
}
|
||||
|
||||
public int getDrawAreaWidth()
|
||||
{
|
||||
return drawAreaWidth;
|
||||
/**
|
||||
* @return shape width
|
||||
*/
|
||||
public int getDrawAreaWidth() {
|
||||
EscherSimpleProperty property = getOptRecord().lookup(EscherProperties.GEOMETRY__RIGHT);
|
||||
return property == null ? 100: property.getPropertyValue();
|
||||
}
|
||||
|
||||
public int getDrawAreaHeight()
|
||||
{
|
||||
return drawAreaHeight;
|
||||
/**
|
||||
* @return shape height
|
||||
*/
|
||||
public int getDrawAreaHeight() {
|
||||
EscherSimpleProperty property = getOptRecord().lookup(EscherProperties.GEOMETRY__BOTTOM);
|
||||
return property == null ? 100: property.getPropertyValue();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -17,6 +17,15 @@
|
||||
|
||||
package org.apache.poi.hssf.usermodel;
|
||||
|
||||
import org.apache.poi.ddf.*;
|
||||
import org.apache.poi.hssf.record.CommonObjectDataSubRecord;
|
||||
import org.apache.poi.hssf.record.ObjRecord;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* An abstract shape.
|
||||
*
|
||||
@ -25,6 +34,9 @@ package org.apache.poi.hssf.usermodel;
|
||||
public abstract class HSSFShape {
|
||||
public static final int LINEWIDTH_ONE_PT = 12700;
|
||||
public static final int LINEWIDTH_DEFAULT = 9525;
|
||||
public static final int LINESTYLE__COLOR_DEFAULT = 0x08000040;
|
||||
public static final int FILL__FILLCOLOR_DEFAULT = 0x08000009;
|
||||
public static final boolean NO_FILL_DEFAULT = true;
|
||||
|
||||
public static final int LINESTYLE_SOLID = 0; // Solid (continuous) pen
|
||||
public static final int LINESTYLE_DASHSYS = 1; // PS_DASH system dash style
|
||||
@ -39,38 +51,98 @@ public abstract class HSSFShape {
|
||||
public static final int LINESTYLE_LONGDASHDOTDOTGEL = 10; // long dash short dash short dash
|
||||
public static final int LINESTYLE_NONE = -1;
|
||||
|
||||
public static final int LINESTYLE_DEFAULT = LINESTYLE_NONE;
|
||||
|
||||
// TODO - make all these fields private
|
||||
final HSSFShape parent;
|
||||
private HSSFShape parent;
|
||||
HSSFAnchor anchor;
|
||||
HSSFPatriarch _patriarch;
|
||||
private int _lineStyleColor = 0x08000040;
|
||||
int _fillColor = 0x08000009;
|
||||
private int _lineWidth = LINEWIDTH_DEFAULT; // 12700 = 1pt
|
||||
private int _lineStyle = LINESTYLE_SOLID;
|
||||
private boolean _noFill = false;
|
||||
private HSSFPatriarch _patriarch;
|
||||
|
||||
private final EscherContainerRecord _escherContainer;
|
||||
private final ObjRecord _objRecord;
|
||||
private final EscherOptRecord _optRecord;
|
||||
|
||||
public final static int NO_FILLHITTEST_TRUE = 0x00110000;
|
||||
public final static int NO_FILLHITTEST_FALSE = 0x00010000;
|
||||
|
||||
/**
|
||||
* creates shapes from existing file
|
||||
* @param spContainer
|
||||
* @param objRecord
|
||||
*/
|
||||
public HSSFShape(EscherContainerRecord spContainer, ObjRecord objRecord) {
|
||||
this._escherContainer = spContainer;
|
||||
this._objRecord = objRecord;
|
||||
this._optRecord = spContainer.getChildById(EscherOptRecord.RECORD_ID);
|
||||
this.anchor = HSSFAnchor.createAnchorFromEscher(spContainer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new shape with the specified parent and anchor.
|
||||
*/
|
||||
HSSFShape( HSSFShape parent, HSSFAnchor anchor )
|
||||
{
|
||||
public HSSFShape(HSSFShape parent, HSSFAnchor anchor) {
|
||||
this.parent = parent;
|
||||
this.anchor = anchor;
|
||||
this._escherContainer = createSpContainer();
|
||||
_optRecord = _escherContainer.getChildById(EscherOptRecord.RECORD_ID);
|
||||
_objRecord = createObjRecord();
|
||||
|
||||
}
|
||||
|
||||
protected abstract EscherContainerRecord createSpContainer();
|
||||
|
||||
protected abstract ObjRecord createObjRecord();
|
||||
|
||||
/**
|
||||
* remove escher container from the patriarch.escherAggregate
|
||||
* remove obj, textObj and note records if it's necessary
|
||||
* in case of ShapeGroup remove all contained shapes
|
||||
* @param patriarch
|
||||
*/
|
||||
protected abstract void afterRemove(HSSFPatriarch patriarch);
|
||||
|
||||
/**
|
||||
* @param shapeId - global shapeId which must be set to EscherSpRecord
|
||||
*/
|
||||
void setShapeId(int shapeId){
|
||||
EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID);
|
||||
spRecord.setShapeId(shapeId);
|
||||
CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) _objRecord.getSubRecords().get(0);
|
||||
cod.setObjectId((short) (shapeId%1024));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return global shapeId(from EscherSpRecord)
|
||||
*/
|
||||
int getShapeId(){
|
||||
return ((EscherSpRecord)_escherContainer.getChildById(EscherSpRecord.RECORD_ID)).getShapeId();
|
||||
}
|
||||
|
||||
abstract void afterInsert(HSSFPatriarch patriarch);
|
||||
|
||||
protected EscherContainerRecord getEscherContainer() {
|
||||
return _escherContainer;
|
||||
}
|
||||
|
||||
protected ObjRecord getObjRecord() {
|
||||
return _objRecord;
|
||||
}
|
||||
|
||||
protected EscherOptRecord getOptRecord() {
|
||||
return _optRecord;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the parent shape.
|
||||
*/
|
||||
public HSSFShape getParent()
|
||||
{
|
||||
public HSSFShape getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the anchor that is used by this shape.
|
||||
* @return the anchor that is used by this shape.
|
||||
*/
|
||||
public HSSFAnchor getAnchor()
|
||||
{
|
||||
public HSSFAnchor getAnchor() {
|
||||
return anchor;
|
||||
}
|
||||
|
||||
@ -78,26 +150,49 @@ public abstract class HSSFShape {
|
||||
* Sets a particular anchor. A top-level shape must have an anchor of
|
||||
* HSSFClientAnchor. A child anchor must have an anchor of HSSFChildAnchor
|
||||
*
|
||||
* @param anchor the anchor to use.
|
||||
* @throws IllegalArgumentException when the wrong anchor is used for
|
||||
* this particular shape.
|
||||
*
|
||||
* @param anchor the anchor to use.
|
||||
* @throws IllegalArgumentException when the wrong anchor is used for
|
||||
* this particular shape.
|
||||
* @see HSSFChildAnchor
|
||||
* @see HSSFClientAnchor
|
||||
*/
|
||||
public void setAnchor( HSSFAnchor anchor )
|
||||
{
|
||||
if ( parent == null )
|
||||
{
|
||||
if ( anchor instanceof HSSFChildAnchor )
|
||||
throw new IllegalArgumentException( "Must use client anchors for shapes directly attached to sheet." );
|
||||
public void setAnchor(HSSFAnchor anchor) {
|
||||
int i = 0;
|
||||
int recordId = -1;
|
||||
if (parent == null) {
|
||||
if (anchor instanceof HSSFChildAnchor)
|
||||
throw new IllegalArgumentException("Must use client anchors for shapes directly attached to sheet.");
|
||||
EscherClientAnchorRecord anch = _escherContainer.getChildById(EscherClientAnchorRecord.RECORD_ID);
|
||||
if (null != anch) {
|
||||
for (i=0; i< _escherContainer.getChildRecords().size(); i++){
|
||||
if (_escherContainer.getChild(i).getRecordId() == EscherClientAnchorRecord.RECORD_ID){
|
||||
if (i != _escherContainer.getChildRecords().size() -1){
|
||||
recordId = _escherContainer.getChild(i+1).getRecordId();
|
||||
}
|
||||
}
|
||||
}
|
||||
_escherContainer.removeChildRecord(anch);
|
||||
}
|
||||
} else {
|
||||
if (anchor instanceof HSSFClientAnchor)
|
||||
throw new IllegalArgumentException("Must use child anchors for shapes attached to groups.");
|
||||
EscherChildAnchorRecord anch = _escherContainer.getChildById(EscherChildAnchorRecord.RECORD_ID);
|
||||
if (null != anch) {
|
||||
for (i=0; i< _escherContainer.getChildRecords().size(); i++){
|
||||
if (_escherContainer.getChild(i).getRecordId() == EscherChildAnchorRecord.RECORD_ID){
|
||||
if (i != _escherContainer.getChildRecords().size() -1){
|
||||
recordId = _escherContainer.getChild(i+1).getRecordId();
|
||||
}
|
||||
}
|
||||
}
|
||||
_escherContainer.removeChildRecord(anch);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( anchor instanceof HSSFClientAnchor )
|
||||
throw new IllegalArgumentException( "Must use child anchors for shapes attached to groups." );
|
||||
if (-1 == recordId){
|
||||
_escherContainer.addChildRecord(anchor.getEscherAnchor());
|
||||
} else {
|
||||
_escherContainer.addChildBefore(anchor.getEscherAnchor(), recordId);
|
||||
}
|
||||
|
||||
this.anchor = anchor;
|
||||
}
|
||||
|
||||
@ -105,92 +200,181 @@ public abstract class HSSFShape {
|
||||
* The color applied to the lines of this shape.
|
||||
*/
|
||||
public int getLineStyleColor() {
|
||||
return _lineStyleColor;
|
||||
EscherRGBProperty rgbProperty = _optRecord.lookup(EscherProperties.LINESTYLE__COLOR);
|
||||
return rgbProperty == null ? LINESTYLE__COLOR_DEFAULT : rgbProperty.getRgbColor();
|
||||
}
|
||||
|
||||
/**
|
||||
* The color applied to the lines of this shape.
|
||||
*/
|
||||
public void setLineStyleColor(int lineStyleColor) {
|
||||
_lineStyleColor = lineStyleColor;
|
||||
setPropertyValue(new EscherRGBProperty(EscherProperties.LINESTYLE__COLOR, lineStyleColor));
|
||||
}
|
||||
|
||||
/**
|
||||
* The color applied to the lines of this shape.
|
||||
*/
|
||||
public void setLineStyleColor(int red, int green, int blue) {
|
||||
this._lineStyleColor = ((blue) << 16) | ((green) << 8) | red;
|
||||
int lineStyleColor = ((blue) << 16) | ((green) << 8) | red;
|
||||
setPropertyValue(new EscherRGBProperty(EscherProperties.LINESTYLE__COLOR, lineStyleColor));
|
||||
}
|
||||
|
||||
/**
|
||||
* The color used to fill this shape.
|
||||
*/
|
||||
public int getFillColor()
|
||||
{
|
||||
return _fillColor;
|
||||
public int getFillColor() {
|
||||
EscherRGBProperty rgbProperty = _optRecord.lookup(EscherProperties.FILL__FILLCOLOR);
|
||||
return rgbProperty == null ? FILL__FILLCOLOR_DEFAULT : rgbProperty.getRgbColor();
|
||||
}
|
||||
|
||||
/**
|
||||
* The color used to fill this shape.
|
||||
*/
|
||||
public void setFillColor(int fillColor) {
|
||||
_fillColor = fillColor;
|
||||
setPropertyValue(new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, fillColor));
|
||||
}
|
||||
|
||||
/**
|
||||
* The color used to fill this shape.
|
||||
*/
|
||||
public void setFillColor( int red, int green, int blue )
|
||||
{
|
||||
this._fillColor = ((blue) << 16) | ((green) << 8) | red;
|
||||
public void setFillColor(int red, int green, int blue) {
|
||||
int fillColor = ((blue) << 16) | ((green) << 8) | red;
|
||||
setPropertyValue(new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, fillColor));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return returns with width of the line in EMUs. 12700 = 1 pt.
|
||||
* @return returns with width of the line in EMUs. 12700 = 1 pt.
|
||||
*/
|
||||
public int getLineWidth() {
|
||||
return _lineWidth;
|
||||
EscherSimpleProperty property = _optRecord.lookup(EscherProperties.LINESTYLE__LINEWIDTH);
|
||||
return property == null ? LINEWIDTH_DEFAULT: property.getPropertyValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the width of the line. 12700 = 1 pt.
|
||||
*
|
||||
* @param lineWidth width in EMU's. 12700EMU's = 1 pt
|
||||
*
|
||||
* @see HSSFShape#LINEWIDTH_ONE_PT
|
||||
*/
|
||||
public void setLineWidth(int lineWidth) {
|
||||
_lineWidth = lineWidth;
|
||||
setPropertyValue(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEWIDTH, lineWidth));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return One of the constants in LINESTYLE_*
|
||||
*/
|
||||
public int getLineStyle() {
|
||||
return _lineStyle;
|
||||
EscherSimpleProperty property = _optRecord.lookup(EscherProperties.LINESTYLE__LINEDASHING);
|
||||
if (null == property){
|
||||
return LINESTYLE_DEFAULT;
|
||||
}
|
||||
return property.getPropertyValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the line style.
|
||||
*
|
||||
* @param lineStyle One of the constants in LINESTYLE_*
|
||||
* @param lineStyle One of the constants in LINESTYLE_*
|
||||
*/
|
||||
public void setLineStyle(int lineStyle) {
|
||||
_lineStyle = lineStyle;
|
||||
setPropertyValue(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEDASHING, lineStyle));
|
||||
if (getLineStyle() != HSSFShape.LINESTYLE_SOLID) {
|
||||
setPropertyValue(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEENDCAPSTYLE, 0));
|
||||
if (getLineStyle() == HSSFShape.LINESTYLE_NONE){
|
||||
setPropertyValue(new EscherBoolProperty( EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x00080000));
|
||||
} else {
|
||||
setPropertyValue( new EscherBoolProperty( EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x00080008));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <code>true</code> if this shape is not filled with a color.
|
||||
*/
|
||||
public boolean isNoFill() {
|
||||
return _noFill;
|
||||
EscherBoolProperty property = _optRecord.lookup(EscherProperties.FILL__NOFILLHITTEST);
|
||||
return property == null ? NO_FILL_DEFAULT : property.getPropertyValue() == NO_FILLHITTEST_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this shape is filled or transparent.
|
||||
* @param noFill sets whether this shape is filled or transparent.
|
||||
*/
|
||||
public void setNoFill(boolean noFill) {
|
||||
_noFill = noFill;
|
||||
setPropertyValue(new EscherBoolProperty(EscherProperties.FILL__NOFILLHITTEST, noFill ? NO_FILLHITTEST_TRUE : NO_FILLHITTEST_FALSE));
|
||||
}
|
||||
|
||||
protected void setPropertyValue(EscherProperty property){
|
||||
_optRecord.setEscherProperty(property);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value specifies whether this shape is vertically flipped.
|
||||
*/
|
||||
public void setFlipVertical(boolean value){
|
||||
EscherSpRecord sp = getEscherContainer().getChildById(EscherSpRecord.RECORD_ID);
|
||||
if (value){
|
||||
sp.setFlags(sp.getFlags() | EscherSpRecord.FLAG_FLIPVERT);
|
||||
} else {
|
||||
sp.setFlags(sp.getFlags() & (Integer.MAX_VALUE - EscherSpRecord.FLAG_FLIPVERT));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value specifies whether this shape is horizontally flipped.
|
||||
*/
|
||||
public void setFlipHorizontal(boolean value){
|
||||
EscherSpRecord sp = getEscherContainer().getChildById(EscherSpRecord.RECORD_ID);
|
||||
if (value){
|
||||
sp.setFlags(sp.getFlags() | EscherSpRecord.FLAG_FLIPHORIZ);
|
||||
} else {
|
||||
sp.setFlags(sp.getFlags() & (Integer.MAX_VALUE - EscherSpRecord.FLAG_FLIPHORIZ));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether this shape is vertically flipped.
|
||||
*/
|
||||
public boolean isFlipVertical(){
|
||||
EscherSpRecord sp = getEscherContainer().getChildById(EscherSpRecord.RECORD_ID);
|
||||
return (sp.getFlags() & EscherSpRecord.FLAG_FLIPVERT) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether this shape is horizontally flipped.
|
||||
*/
|
||||
public boolean isFlipHorizontal(){
|
||||
EscherSpRecord sp = getEscherContainer().getChildById(EscherSpRecord.RECORD_ID);
|
||||
return (sp.getFlags() & EscherSpRecord.FLAG_FLIPHORIZ) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the rotation, in degrees, that is applied to a shape.
|
||||
*/
|
||||
public int getRotationDegree(){
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
EscherSimpleProperty property = getOptRecord().lookup(EscherProperties.TRANSFORM__ROTATION);
|
||||
if (null == property){
|
||||
return 0;
|
||||
}
|
||||
try {
|
||||
LittleEndian.putInt(property.getPropertyValue(), bos);
|
||||
return LittleEndian.getShort(bos.toByteArray(), 2);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* specifies the rotation, in degrees, that is applied to a shape.
|
||||
* Positive values specify rotation in the clockwise direction.
|
||||
* Negative values specify rotation in the counterclockwise direction.
|
||||
* Rotation occurs around the center of the shape.
|
||||
* The default value for this property is 0x00000000
|
||||
* @param value
|
||||
*/
|
||||
public void setRotationDegree(short value){
|
||||
setPropertyValue(new EscherSimpleProperty(EscherProperties.TRANSFORM__ROTATION , (value << 16)));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -199,4 +383,18 @@ public abstract class HSSFShape {
|
||||
public int countOfAllChildren() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
protected abstract HSSFShape cloneShape();
|
||||
|
||||
protected void setPatriarch(HSSFPatriarch _patriarch) {
|
||||
this._patriarch = _patriarch;
|
||||
}
|
||||
|
||||
public HSSFPatriarch getPatriarch() {
|
||||
return _patriarch;
|
||||
}
|
||||
|
||||
protected void setParent(HSSFShape parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
}
|
||||
|
@ -24,11 +24,50 @@ import java.util.List;
|
||||
*
|
||||
* @author Glen Stampoultzis (glens at apache.org)
|
||||
*/
|
||||
public interface HSSFShapeContainer
|
||||
public interface HSSFShapeContainer extends Iterable<HSSFShape>
|
||||
{
|
||||
/**
|
||||
* @return Any children contained by this shape.
|
||||
*/
|
||||
List getChildren();
|
||||
List<HSSFShape> getChildren();
|
||||
|
||||
/**
|
||||
* add shape to the list of child records
|
||||
* @param shape
|
||||
*/
|
||||
public void addShape(HSSFShape shape);
|
||||
|
||||
/**
|
||||
* set coordinates of this group relative to the parent
|
||||
*/
|
||||
void setCoordinates( int x1, int y1, int x2, int y2 );
|
||||
|
||||
void clear();
|
||||
|
||||
/**
|
||||
*@return The top left x coordinate of this group.
|
||||
*/
|
||||
public int getX1();
|
||||
|
||||
/**
|
||||
*@return The top left y coordinate of this group.
|
||||
*/
|
||||
public int getY1();
|
||||
|
||||
/**
|
||||
*@return The bottom right x coordinate of this group.
|
||||
*/
|
||||
public int getX2();
|
||||
|
||||
/**
|
||||
* @return The bottom right y coordinate of this group.
|
||||
*/
|
||||
public int getY2();
|
||||
|
||||
/**
|
||||
* remove first level shapes
|
||||
* @param shape to be removed
|
||||
* @return true if shape is removed else return false
|
||||
*/
|
||||
public boolean removeShape(HSSFShape shape);
|
||||
}
|
||||
|
131
src/java/org/apache/poi/hssf/usermodel/HSSFShapeFactory.java
Normal file
131
src/java/org/apache/poi/hssf/usermodel/HSSFShapeFactory.java
Normal file
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.poi.hssf.usermodel;
|
||||
|
||||
import org.apache.poi.ddf.*;
|
||||
import org.apache.poi.hssf.record.*;
|
||||
import org.apache.poi.poifs.filesystem.DirectoryNode;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Evgeniy Berlog
|
||||
* date: 05.06.12
|
||||
*/
|
||||
public class HSSFShapeFactory {
|
||||
|
||||
private final static short OBJECT_TYPE_LINE = 1;
|
||||
private final static short OBJECT_TYPE_RECTANGLE = 2;
|
||||
private final static short OBJECT_TYPE_OVAL = 3;
|
||||
private final static short OBJECT_TYPE_ARC = 4;
|
||||
private final static short OBJECT_TYPE_PICTURE = 8;
|
||||
|
||||
/**
|
||||
* build shape tree from escher container
|
||||
* @param container root escher container from which escher records must be taken
|
||||
* @param agg - EscherAggregate
|
||||
* @param out - shape container to which shapes must be added
|
||||
* @param root - node to create HSSFObjectData shapes
|
||||
*/
|
||||
public static void createShapeTree(EscherContainerRecord container, EscherAggregate agg, HSSFShapeContainer out, DirectoryNode root) {
|
||||
if (container.getRecordId() == EscherContainerRecord.SPGR_CONTAINER) {
|
||||
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++) {
|
||||
EscherContainerRecord spContainer = children.get(i);
|
||||
if (i != 0) {
|
||||
createShapeTree(spContainer, agg, group, root);
|
||||
}
|
||||
}
|
||||
out.addShape(group);
|
||||
} else if (container.getRecordId() == EscherContainerRecord.SP_CONTAINER) {
|
||||
Map<EscherRecord, Record> shapeToObj = agg.getShapeToObjMapping();
|
||||
ObjRecord objRecord = null;
|
||||
TextObjectRecord txtRecord = null;
|
||||
|
||||
for (EscherRecord record : container.getChildRecords()) {
|
||||
switch (record.getRecordId()) {
|
||||
case EscherClientDataRecord.RECORD_ID:
|
||||
objRecord = (ObjRecord) shapeToObj.get(record);
|
||||
break;
|
||||
case EscherTextboxRecord.RECORD_ID:
|
||||
txtRecord = (TextObjectRecord) shapeToObj.get(record);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isEmbeddedObject(objRecord)) {
|
||||
HSSFObjectData objectData = new HSSFObjectData(container, objRecord, root);
|
||||
out.addShape(objectData);
|
||||
return;
|
||||
}
|
||||
CommonObjectDataSubRecord cmo = (CommonObjectDataSubRecord) objRecord.getSubRecords().get(0);
|
||||
HSSFShape shape;
|
||||
switch (cmo.getObjectType()) {
|
||||
case CommonObjectDataSubRecord.OBJECT_TYPE_PICTURE:
|
||||
shape = new HSSFPicture(container, objRecord);
|
||||
break;
|
||||
case CommonObjectDataSubRecord.OBJECT_TYPE_RECTANGLE:
|
||||
shape = new HSSFSimpleShape(container, objRecord, txtRecord);
|
||||
break;
|
||||
case CommonObjectDataSubRecord.OBJECT_TYPE_LINE:
|
||||
shape = new HSSFSimpleShape(container, objRecord);
|
||||
break;
|
||||
case CommonObjectDataSubRecord.OBJECT_TYPE_COMBO_BOX:
|
||||
shape = new HSSFCombobox(container, objRecord);
|
||||
break;
|
||||
case CommonObjectDataSubRecord.OBJECT_TYPE_MICROSOFT_OFFICE_DRAWING:
|
||||
EscherOptRecord optRecord = container.getChildById(EscherOptRecord.RECORD_ID);
|
||||
EscherProperty property = optRecord.lookup(EscherProperties.GEOMETRY__VERTICES);
|
||||
if (null != property) {
|
||||
shape = new HSSFPolygon(container, objRecord, txtRecord);
|
||||
} else {
|
||||
shape = new HSSFSimpleShape(container, objRecord, txtRecord);
|
||||
}
|
||||
break;
|
||||
case CommonObjectDataSubRecord.OBJECT_TYPE_TEXT:
|
||||
shape = new HSSFTextbox(container, objRecord, txtRecord);
|
||||
break;
|
||||
case CommonObjectDataSubRecord.OBJECT_TYPE_COMMENT:
|
||||
shape = new HSSFComment(container, objRecord, txtRecord, agg.getNoteRecordByObj(objRecord));
|
||||
break;
|
||||
default:
|
||||
shape = new HSSFSimpleShape(container, objRecord, txtRecord);
|
||||
}
|
||||
out.addShape(shape);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isEmbeddedObject(ObjRecord obj) {
|
||||
Iterator<SubRecord> subRecordIter = obj.getSubRecords().iterator();
|
||||
while (subRecordIter.hasNext()) {
|
||||
SubRecord sub = subRecordIter.next();
|
||||
if (sub instanceof EmbeddedObjectRefSubRecord) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -17,7 +17,11 @@
|
||||
|
||||
package org.apache.poi.hssf.usermodel;
|
||||
|
||||
import org.apache.poi.ddf.*;
|
||||
import org.apache.poi.hssf.record.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Iterator;
|
||||
|
||||
@ -27,159 +31,357 @@ import java.util.Iterator;
|
||||
*
|
||||
* @author Glen Stampoultzis (glens at apache.org)
|
||||
*/
|
||||
public class HSSFShapeGroup
|
||||
extends HSSFShape
|
||||
implements HSSFShapeContainer
|
||||
{
|
||||
List<HSSFShape> shapes = new ArrayList<HSSFShape>();
|
||||
int x1 = 0;
|
||||
int y1 = 0 ;
|
||||
int x2 = 1023;
|
||||
int y2 = 255;
|
||||
public class HSSFShapeGroup extends HSSFShape implements HSSFShapeContainer {
|
||||
private final List<HSSFShape> shapes = new ArrayList<HSSFShape>();
|
||||
private EscherSpgrRecord _spgrRecord;
|
||||
|
||||
public HSSFShapeGroup(EscherContainerRecord spgrContainer, ObjRecord objRecord) {
|
||||
super(spgrContainer, objRecord);
|
||||
|
||||
public HSSFShapeGroup( HSSFShape parent, HSSFAnchor anchor )
|
||||
{
|
||||
super( parent, anchor );
|
||||
// read internal and external coordinates from spgrContainer
|
||||
EscherContainerRecord spContainer = spgrContainer.getChildContainers().get(0);
|
||||
_spgrRecord = (EscherSpgrRecord) spContainer.getChild(0);
|
||||
for (EscherRecord ch : spContainer.getChildRecords()) {
|
||||
switch (ch.getRecordId()) {
|
||||
case EscherSpgrRecord.RECORD_ID:
|
||||
break;
|
||||
case EscherClientAnchorRecord.RECORD_ID:
|
||||
anchor = new HSSFClientAnchor((EscherClientAnchorRecord) ch);
|
||||
break;
|
||||
case EscherChildAnchorRecord.RECORD_ID:
|
||||
anchor = new HSSFChildAnchor((EscherChildAnchorRecord) ch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public HSSFShapeGroup(HSSFShape parent, HSSFAnchor anchor) {
|
||||
super(parent, anchor);
|
||||
_spgrRecord = ((EscherContainerRecord)getEscherContainer().getChild(0)).getChildById(EscherSpgrRecord.RECORD_ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EscherContainerRecord createSpContainer() {
|
||||
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(0);
|
||||
spgr.setRectY1(0);
|
||||
spgr.setRectX2(1023);
|
||||
spgr.setRectY2(255);
|
||||
sp.setRecordId(EscherSpRecord.RECORD_ID);
|
||||
sp.setOptions((short) 0x0002);
|
||||
if (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 = getAnchor().getEscherAnchor();
|
||||
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);
|
||||
return spgrContainer;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ObjRecord createObjRecord() {
|
||||
ObjRecord obj = new ObjRecord();
|
||||
CommonObjectDataSubRecord cmo = new CommonObjectDataSubRecord();
|
||||
cmo.setObjectType(CommonObjectDataSubRecord.OBJECT_TYPE_GROUP);
|
||||
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);
|
||||
return obj;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void afterRemove(HSSFPatriarch patriarch) {
|
||||
patriarch._getBoundAggregate().removeShapeToObjRecord(getEscherContainer().getChildContainers().get(0)
|
||||
.getChildById(EscherClientDataRecord.RECORD_ID));
|
||||
for ( int i=0; i<shapes.size(); i++ ) {
|
||||
HSSFShape shape = shapes.get(i);
|
||||
removeShape(shape);
|
||||
shape.afterRemove(getPatriarch());
|
||||
}
|
||||
shapes.clear();
|
||||
}
|
||||
|
||||
private void onCreate(HSSFShape shape){
|
||||
if(getPatriarch() != null){
|
||||
EscherContainerRecord spContainer = shape.getEscherContainer();
|
||||
int shapeId = getPatriarch().newShapeId();
|
||||
shape.setShapeId(shapeId);
|
||||
getEscherContainer().addChildRecord(spContainer);
|
||||
shape.afterInsert(getPatriarch());
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create another group under this group.
|
||||
* @param anchor the position of the new group.
|
||||
* @return the group
|
||||
*
|
||||
* @param anchor the position of the new group.
|
||||
* @return the group
|
||||
*/
|
||||
public HSSFShapeGroup createGroup(HSSFChildAnchor anchor)
|
||||
{
|
||||
public HSSFShapeGroup createGroup(HSSFChildAnchor anchor) {
|
||||
HSSFShapeGroup group = new HSSFShapeGroup(this, anchor);
|
||||
group.anchor = anchor;
|
||||
group.setParent(this);
|
||||
group.setAnchor(anchor);
|
||||
shapes.add(group);
|
||||
onCreate(group);
|
||||
return group;
|
||||
}
|
||||
|
||||
public void addShape(HSSFShape shape){
|
||||
shape._patriarch = this._patriarch;
|
||||
public void addShape(HSSFShape shape) {
|
||||
shape.setPatriarch(this.getPatriarch());
|
||||
shape.setParent(this);
|
||||
shapes.add(shape);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new simple shape under this group.
|
||||
* @param anchor the position of the shape.
|
||||
* @return the shape
|
||||
*
|
||||
* @param anchor the position of the shape.
|
||||
* @return the shape
|
||||
*/
|
||||
public HSSFSimpleShape createShape(HSSFChildAnchor anchor)
|
||||
{
|
||||
public HSSFSimpleShape createShape(HSSFChildAnchor anchor) {
|
||||
HSSFSimpleShape shape = new HSSFSimpleShape(this, anchor);
|
||||
shape.anchor = anchor;
|
||||
shape.setParent(this);
|
||||
shape.setAnchor(anchor);
|
||||
shapes.add(shape);
|
||||
onCreate(shape);
|
||||
EscherSpRecord sp = shape.getEscherContainer().getChildById(EscherSpRecord.RECORD_ID);
|
||||
if (shape.getAnchor().isHorizontallyFlipped()){
|
||||
sp.setFlags(sp.getFlags() | EscherSpRecord.FLAG_FLIPHORIZ);
|
||||
}
|
||||
if (shape.getAnchor().isVerticallyFlipped()){
|
||||
sp.setFlags(sp.getFlags() | EscherSpRecord.FLAG_FLIPVERT);
|
||||
}
|
||||
return shape;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new textbox under this group.
|
||||
* @param anchor the position of the shape.
|
||||
* @return the textbox
|
||||
*
|
||||
* @param anchor the position of the shape.
|
||||
* @return the textbox
|
||||
*/
|
||||
public HSSFTextbox createTextbox(HSSFChildAnchor anchor)
|
||||
{
|
||||
public HSSFTextbox createTextbox(HSSFChildAnchor anchor) {
|
||||
HSSFTextbox shape = new HSSFTextbox(this, anchor);
|
||||
shape.anchor = anchor;
|
||||
shape.setParent(this);
|
||||
shape.setAnchor(anchor);
|
||||
shapes.add(shape);
|
||||
onCreate(shape);
|
||||
return shape;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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(HSSFChildAnchor anchor)
|
||||
{
|
||||
public HSSFPolygon createPolygon(HSSFChildAnchor anchor) {
|
||||
HSSFPolygon shape = new HSSFPolygon(this, anchor);
|
||||
shape.anchor = anchor;
|
||||
shape.setParent(this);
|
||||
shape.setAnchor(anchor);
|
||||
shapes.add(shape);
|
||||
onCreate(shape);
|
||||
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(HSSFChildAnchor anchor, int pictureIndex)
|
||||
{
|
||||
HSSFPicture shape = new HSSFPicture(this, anchor);
|
||||
shape.anchor = anchor;
|
||||
shape.setPictureIndex( pictureIndex );
|
||||
shapes.add(shape);
|
||||
return shape;
|
||||
public HSSFPicture createPicture(HSSFChildAnchor anchor, int pictureIndex) {
|
||||
HSSFPicture shape = new HSSFPicture(this, anchor);
|
||||
shape.setParent(this);
|
||||
shape.setAnchor(anchor);
|
||||
shape.setPictureIndex(pictureIndex);
|
||||
shapes.add(shape);
|
||||
onCreate(shape);
|
||||
EscherSpRecord sp = shape.getEscherContainer().getChildById(EscherSpRecord.RECORD_ID);
|
||||
if (shape.getAnchor().isHorizontallyFlipped()){
|
||||
sp.setFlags(sp.getFlags() | EscherSpRecord.FLAG_FLIPHORIZ);
|
||||
}
|
||||
if (shape.getAnchor().isVerticallyFlipped()){
|
||||
sp.setFlags(sp.getFlags() | EscherSpRecord.FLAG_FLIPVERT);
|
||||
}
|
||||
return shape;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all children contained by this shape.
|
||||
*/
|
||||
public List<HSSFShape> getChildren()
|
||||
{
|
||||
return shapes;
|
||||
public List<HSSFShape> getChildren() {
|
||||
return Collections.unmodifiableList(shapes);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 )
|
||||
{
|
||||
this.x1 = x1;
|
||||
this.y1 = y1;
|
||||
this.x2 = x2;
|
||||
this.y2 = y2;
|
||||
public void setCoordinates(int x1, int y1, int x2, int y2) {
|
||||
_spgrRecord.setRectX1(x1);
|
||||
_spgrRecord.setRectX2(x2);
|
||||
_spgrRecord.setRectY1(y1);
|
||||
_spgrRecord.setRectY2(y2);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
ArrayList <HSSFShape> copy = new ArrayList<HSSFShape>(shapes);
|
||||
for (HSSFShape shape: copy){
|
||||
removeShape(shape);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The top left x coordinate of this group.
|
||||
*/
|
||||
public int getX1()
|
||||
{
|
||||
return x1;
|
||||
public int getX1() {
|
||||
return _spgrRecord.getRectX1();
|
||||
}
|
||||
|
||||
/**
|
||||
* The top left y coordinate of this group.
|
||||
*/
|
||||
public int getY1()
|
||||
{
|
||||
return y1;
|
||||
public int getY1() {
|
||||
return _spgrRecord.getRectY1();
|
||||
}
|
||||
|
||||
/**
|
||||
* The bottom right x coordinate of this group.
|
||||
*/
|
||||
public int getX2()
|
||||
{
|
||||
return x2;
|
||||
public int getX2() {
|
||||
return _spgrRecord.getRectX2();
|
||||
}
|
||||
|
||||
/**
|
||||
* The bottom right y coordinate of this group.
|
||||
*/
|
||||
public int getY2()
|
||||
{
|
||||
return y2;
|
||||
public int getY2() {
|
||||
return _spgrRecord.getRectY2();
|
||||
}
|
||||
|
||||
/**
|
||||
* Count of all children and their childrens children.
|
||||
*/
|
||||
public int countOfAllChildren()
|
||||
{
|
||||
public int countOfAllChildren() {
|
||||
int count = shapes.size();
|
||||
for ( Iterator iterator = shapes.iterator(); iterator.hasNext(); )
|
||||
{
|
||||
for (Iterator iterator = shapes.iterator(); iterator.hasNext(); ) {
|
||||
HSSFShape shape = (HSSFShape) iterator.next();
|
||||
count += shape.countOfAllChildren();
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
void afterInsert(HSSFPatriarch patriarch){
|
||||
EscherAggregate agg = patriarch._getBoundAggregate();
|
||||
EscherContainerRecord containerRecord = getEscherContainer().getChildById(EscherContainerRecord.SP_CONTAINER);
|
||||
agg.associateShapeToObjRecord(containerRecord.getChildById(EscherClientDataRecord.RECORD_ID), getObjRecord());
|
||||
}
|
||||
|
||||
@Override
|
||||
void setShapeId(int shapeId){
|
||||
EscherContainerRecord containerRecord = getEscherContainer().getChildById(EscherContainerRecord.SP_CONTAINER);
|
||||
EscherSpRecord spRecord = containerRecord.getChildById(EscherSpRecord.RECORD_ID);
|
||||
spRecord.setShapeId(shapeId);
|
||||
CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) getObjRecord().getSubRecords().get(0);
|
||||
cod.setObjectId((short) (shapeId % 1024));
|
||||
}
|
||||
|
||||
@Override
|
||||
int getShapeId(){
|
||||
EscherContainerRecord containerRecord = getEscherContainer().getChildById(EscherContainerRecord.SP_CONTAINER);
|
||||
return ((EscherSpRecord)containerRecord.getChildById(EscherSpRecord.RECORD_ID)).getShapeId();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HSSFShape cloneShape() {
|
||||
throw new IllegalStateException("Use method cloneShape(HSSFPatriarch patriarch)");
|
||||
}
|
||||
|
||||
protected HSSFShape cloneShape(HSSFPatriarch patriarch) {
|
||||
EscherContainerRecord spgrContainer = new EscherContainerRecord();
|
||||
spgrContainer.setRecordId(EscherContainerRecord.SPGR_CONTAINER);
|
||||
spgrContainer.setOptions((short) 0x000F);
|
||||
EscherContainerRecord spContainer = new EscherContainerRecord();
|
||||
EscherContainerRecord cont = getEscherContainer().getChildById(EscherContainerRecord.SP_CONTAINER);
|
||||
byte [] inSp = cont.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.setPatriarch(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;
|
||||
}
|
||||
|
||||
public boolean removeShape(HSSFShape shape) {
|
||||
boolean isRemoved = getEscherContainer().removeChildRecord(shape.getEscherContainer());
|
||||
if (isRemoved){
|
||||
shape.afterRemove(this.getPatriarch());
|
||||
shapes.remove(shape);
|
||||
}
|
||||
return isRemoved;
|
||||
}
|
||||
|
||||
public Iterator<HSSFShape> iterator() {
|
||||
return shapes.iterator();
|
||||
}
|
||||
}
|
||||
|
224
src/java/org/apache/poi/hssf/usermodel/HSSFShapeTypes.java
Normal file
224
src/java/org/apache/poi/hssf/usermodel/HSSFShapeTypes.java
Normal file
@ -0,0 +1,224 @@
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.hssf.usermodel;
|
||||
|
||||
public interface HSSFShapeTypes {
|
||||
public static final int NotPrimitive = 0;
|
||||
public static final int Rectangle = 1;
|
||||
public static final int RoundRectangle = 2;
|
||||
public static final int Ellipse = 3;
|
||||
public static final int Diamond = 4;
|
||||
public static final int IsocelesTriangle = 5;
|
||||
public static final int RightTriangle = 6;
|
||||
public static final int Parallelogram = 7;
|
||||
public static final int Trapezoid = 8;
|
||||
public static final int Hexagon = 9;
|
||||
public static final int Octagon = 10;
|
||||
public static final int Plus = 11;
|
||||
public static final int Star = 12;
|
||||
public static final int Arrow = 13;
|
||||
public static final int ThickArrow = 14;
|
||||
public static final int HomePlate = 15;
|
||||
public static final int Cube = 16;
|
||||
public static final int Balloon = 17;
|
||||
public static final int Seal = 18;
|
||||
public static final int Arc = 19;
|
||||
public static final int Line = 20;
|
||||
public static final int Plaque = 21;
|
||||
public static final int Can = 22;
|
||||
public static final int Donut = 23;
|
||||
public static final int TextSimple = 24;
|
||||
public static final int TextOctagon = 25;
|
||||
public static final int TextHexagon = 26;
|
||||
public static final int TextCurve = 27;
|
||||
public static final int TextWave = 28;
|
||||
public static final int TextRing = 29;
|
||||
public static final int TextOnCurve = 30;
|
||||
public static final int TextOnRing = 31;
|
||||
public static final int StraightConnector1 = 32;
|
||||
public static final int BentConnector2 = 33;
|
||||
public static final int BentConnector3 = 34;
|
||||
public static final int BentConnector4 = 35;
|
||||
public static final int BentConnector5 = 36;
|
||||
public static final int CurvedConnector2 = 37;
|
||||
public static final int CurvedConnector3 = 38;
|
||||
public static final int CurvedConnector4 = 39;
|
||||
public static final int CurvedConnector5 = 40;
|
||||
public static final int Callout1 = 41;
|
||||
public static final int Callout2 = 42;
|
||||
public static final int Callout3 = 43;
|
||||
public static final int AccentCallout1 = 44;
|
||||
public static final int AccentCallout2 = 45;
|
||||
public static final int AccentCallout3 = 46;
|
||||
public static final int BorderCallout1 = 47;
|
||||
public static final int BorderCallout2 = 48;
|
||||
public static final int BorderCallout3 = 49;
|
||||
public static final int AccentBorderCallout1 = 50;
|
||||
public static final int AccentBorderCallout2 = 51;
|
||||
public static final int AccentBorderCallout3 = 52;
|
||||
public static final int Ribbon = 53;
|
||||
public static final int Ribbon2 = 54;
|
||||
public static final int Chevron = 55;
|
||||
public static final int Pentagon = 56;
|
||||
public static final int NoSmoking = 57;
|
||||
public static final int Star8 = 58;
|
||||
public static final int Star16 = 59;
|
||||
public static final int Star32 = 60;
|
||||
public static final int WedgeRectCallout = 61;
|
||||
public static final int WedgeRRectCallout = 62;
|
||||
public static final int WedgeEllipseCallout = 63;
|
||||
public static final int Wave = 64;
|
||||
public static final int FoldedCorner = 65;
|
||||
public static final int LeftArrow = 66;
|
||||
public static final int DownArrow = 67;
|
||||
public static final int UpArrow = 68;
|
||||
public static final int LeftRightArrow = 69;
|
||||
public static final int UpDownArrow = 70;
|
||||
public static final int IrregularSeal1 = 71;
|
||||
public static final int IrregularSeal2 = 72;
|
||||
public static final int LightningBolt = 73;
|
||||
public static final int Heart = 74;
|
||||
public static final int PictureFrame = 75;
|
||||
public static final int QuadArrow = 76;
|
||||
public static final int LeftArrowCallout = 77;
|
||||
public static final int RightArrowCallout = 78;
|
||||
public static final int UpArrowCallout = 79;
|
||||
public static final int DownArrowCallout = 80;
|
||||
public static final int LeftRightArrowCallout = 81;
|
||||
public static final int UpDownArrowCallout = 82;
|
||||
public static final int QuadArrowCallout = 83;
|
||||
public static final int Bevel = 84;
|
||||
public static final int LeftBracket = 85;
|
||||
public static final int RightBracket = 86;
|
||||
public static final int LeftBrace = 87;
|
||||
public static final int RightBrace = 88;
|
||||
public static final int LeftUpArrow = 89;
|
||||
public static final int BentUpArrow = 90;
|
||||
public static final int BentArrow = 91;
|
||||
public static final int Star24 = 92;
|
||||
public static final int StripedRightArrow = 93;
|
||||
public static final int NotchedRightArrow = 94;
|
||||
public static final int BlockArc = 95;
|
||||
public static final int SmileyFace = 96;
|
||||
public static final int VerticalScroll = 97;
|
||||
public static final int HorizontalScroll = 98;
|
||||
public static final int CircularArrow = 99;
|
||||
public static final int NotchedCircularArrow = 100;
|
||||
public static final int UturnArrow = 101;
|
||||
public static final int CurvedRightArrow = 102;
|
||||
public static final int CurvedLeftArrow = 103;
|
||||
public static final int CurvedUpArrow = 104;
|
||||
public static final int CurvedDownArrow = 105;
|
||||
public static final int CloudCallout = 106;
|
||||
public static final int EllipseRibbon = 107;
|
||||
public static final int EllipseRibbon2 = 108;
|
||||
public static final int FlowChartProcess = 109;
|
||||
public static final int FlowChartDecision = 110;
|
||||
public static final int FlowChartInputOutput = 111;
|
||||
public static final int FlowChartPredefinedProcess = 112;
|
||||
public static final int FlowChartInternalStorage = 113;
|
||||
public static final int FlowChartDocument = 114;
|
||||
public static final int FlowChartMultidocument = 115;
|
||||
public static final int FlowChartTerminator = 116;
|
||||
public static final int FlowChartPreparation = 117;
|
||||
public static final int FlowChartManualInput = 118;
|
||||
public static final int FlowChartManualOperation = 119;
|
||||
public static final int FlowChartConnector = 120;
|
||||
public static final int FlowChartPunchedCard = 121;
|
||||
public static final int FlowChartPunchedTape = 122;
|
||||
public static final int FlowChartSummingJunction = 123;
|
||||
public static final int FlowChartOr = 124;
|
||||
public static final int FlowChartCollate = 125;
|
||||
public static final int FlowChartSort = 126;
|
||||
public static final int FlowChartExtract = 127;
|
||||
public static final int FlowChartMerge = 128;
|
||||
public static final int FlowChartOfflineStorage = 129;
|
||||
public static final int FlowChartOnlineStorage = 130;
|
||||
public static final int FlowChartMagneticTape = 131;
|
||||
public static final int FlowChartMagneticDisk = 132;
|
||||
public static final int FlowChartMagneticDrum = 133;
|
||||
public static final int FlowChartDisplay = 134;
|
||||
public static final int FlowChartDelay = 135;
|
||||
public static final int TextPlainText = 136;
|
||||
public static final int TextStop = 137;
|
||||
public static final int TextTriangle = 138;
|
||||
public static final int TextTriangleInverted = 139;
|
||||
public static final int TextChevron = 140;
|
||||
public static final int TextChevronInverted = 141;
|
||||
public static final int TextRingInside = 142;
|
||||
public static final int TextRingOutside = 143;
|
||||
public static final int TextArchUpCurve = 144;
|
||||
public static final int TextArchDownCurve = 145;
|
||||
public static final int TextCircleCurve = 146;
|
||||
public static final int TextButtonCurve = 147;
|
||||
public static final int TextArchUpPour = 148;
|
||||
public static final int TextArchDownPour = 149;
|
||||
public static final int TextCirclePour = 150;
|
||||
public static final int TextButtonPour = 151;
|
||||
public static final int TextCurveUp = 152;
|
||||
public static final int TextCurveDown = 153;
|
||||
public static final int TextCascadeUp = 154;
|
||||
public static final int TextCascadeDown = 155;
|
||||
public static final int TextWave1 = 156;
|
||||
public static final int TextWave2 = 157;
|
||||
public static final int TextWave3 = 158;
|
||||
public static final int TextWave4 = 159;
|
||||
public static final int TextInflate = 160;
|
||||
public static final int TextDeflate = 161;
|
||||
public static final int TextInflateBottom = 162;
|
||||
public static final int TextDeflateBottom = 163;
|
||||
public static final int TextInflateTop = 164;
|
||||
public static final int TextDeflateTop = 165;
|
||||
public static final int TextDeflateInflate = 166;
|
||||
public static final int TextDeflateInflateDeflate = 167;
|
||||
public static final int TextFadeRight = 168;
|
||||
public static final int TextFadeLeft = 169;
|
||||
public static final int TextFadeUp = 170;
|
||||
public static final int TextFadeDown = 171;
|
||||
public static final int TextSlantUp = 172;
|
||||
public static final int TextSlantDown = 173;
|
||||
public static final int TextCanUp = 174;
|
||||
public static final int TextCanDown = 175;
|
||||
public static final int FlowChartAlternateProcess = 176;
|
||||
public static final int FlowChartOffpageConnector = 177;
|
||||
public static final int Callout90 = 178;
|
||||
public static final int AccentCallout90 = 179;
|
||||
public static final int BorderCallout90 = 180;
|
||||
public static final int AccentBorderCallout90 = 181;
|
||||
public static final int LeftRightUpArrow = 182;
|
||||
public static final int Sun = 183;
|
||||
public static final int Moon = 184;
|
||||
public static final int BracketPair = 185;
|
||||
public static final int BracePair = 186;
|
||||
public static final int Star4 = 187;
|
||||
public static final int DoubleWave = 188;
|
||||
public static final int ActionButtonBlank = 189;
|
||||
public static final int ActionButtonHome = 190;
|
||||
public static final int ActionButtonHelp = 191;
|
||||
public static final int ActionButtonInformation = 192;
|
||||
public static final int ActionButtonForwardNext = 193;
|
||||
public static final int ActionButtonBackPrevious = 194;
|
||||
public static final int ActionButtonEnd = 195;
|
||||
public static final int ActionButtonBeginning = 196;
|
||||
public static final int ActionButtonReturn = 197;
|
||||
public static final int ActionButtonDocument = 198;
|
||||
public static final int ActionButtonSound = 199;
|
||||
public static final int ActionButtonMovie = 200;
|
||||
public static final int HostControl = 201;
|
||||
public static final int TextBox = 202;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -17,25 +17,29 @@
|
||||
|
||||
package org.apache.poi.hssf.usermodel;
|
||||
|
||||
import org.apache.poi.ddf.*;
|
||||
import org.apache.poi.hssf.record.*;
|
||||
import org.apache.poi.ss.usermodel.RichTextString;
|
||||
|
||||
/**
|
||||
* Represents a simple shape such as a line, rectangle or oval.
|
||||
*
|
||||
* @author Glen Stampoultzis (glens at apache.org)
|
||||
*/
|
||||
public class HSSFSimpleShape
|
||||
extends HSSFShape
|
||||
public class HSSFSimpleShape extends HSSFShape
|
||||
{
|
||||
// The commented out ones haven't been tested yet or aren't supported
|
||||
// by HSSFSimpleShape.
|
||||
|
||||
public final static short OBJECT_TYPE_LINE = 1;
|
||||
public final static short OBJECT_TYPE_RECTANGLE = 2;
|
||||
public final static short OBJECT_TYPE_OVAL = 3;
|
||||
// public final static short OBJECT_TYPE_ARC = 4;
|
||||
// public final static short OBJECT_TYPE_CHART = 5;
|
||||
public final static short OBJECT_TYPE_LINE = HSSFShapeTypes.Line;
|
||||
public final static short OBJECT_TYPE_RECTANGLE = HSSFShapeTypes.Rectangle;
|
||||
public final static short OBJECT_TYPE_OVAL = HSSFShapeTypes.Ellipse;
|
||||
public final static short OBJECT_TYPE_ARC = HSSFShapeTypes.Arc;
|
||||
// public final static short OBJECT_TYPE_CHART = 5;
|
||||
// public final static short OBJECT_TYPE_TEXT = 6;
|
||||
// public final static short OBJECT_TYPE_BUTTON = 7;
|
||||
public final static short OBJECT_TYPE_PICTURE = 8;
|
||||
public final static short OBJECT_TYPE_PICTURE = HSSFShapeTypes.PictureFrame;
|
||||
|
||||
// public final static short OBJECT_TYPE_POLYGON = 9;
|
||||
// public final static short OBJECT_TYPE_CHECKBOX = 11;
|
||||
// public final static short OBJECT_TYPE_OPTION_BUTTON = 12;
|
||||
@ -46,17 +50,156 @@ public class HSSFSimpleShape
|
||||
// public final static short OBJECT_TYPE_SCROLL_BAR = 17;
|
||||
// public final static short OBJECT_TYPE_LIST_BOX = 18;
|
||||
// public final static short OBJECT_TYPE_GROUP_BOX = 19;
|
||||
public final static short OBJECT_TYPE_COMBO_BOX = 20;
|
||||
public final static short OBJECT_TYPE_COMMENT = 25;
|
||||
// public final static short OBJECT_TYPE_MICROSOFT_OFFICE_DRAWING = 30;
|
||||
public final static short OBJECT_TYPE_COMBO_BOX = HSSFShapeTypes.HostControl;
|
||||
public final static short OBJECT_TYPE_COMMENT = HSSFShapeTypes.TextBox;
|
||||
public final static short OBJECT_TYPE_MICROSOFT_OFFICE_DRAWING = 30;
|
||||
|
||||
int shapeType = OBJECT_TYPE_LINE;
|
||||
public final static int WRAP_SQUARE = 0;
|
||||
public final static int WRAP_BY_POINTS = 1;
|
||||
public final static int WRAP_NONE = 2;
|
||||
|
||||
public HSSFSimpleShape( HSSFShape parent, HSSFAnchor anchor )
|
||||
private TextObjectRecord _textObjectRecord;
|
||||
|
||||
public HSSFSimpleShape(EscherContainerRecord spContainer, ObjRecord objRecord, TextObjectRecord textObjectRecord) {
|
||||
super(spContainer, objRecord);
|
||||
this._textObjectRecord = textObjectRecord;
|
||||
}
|
||||
|
||||
public HSSFSimpleShape(EscherContainerRecord spContainer, ObjRecord objRecord) {
|
||||
super(spContainer, objRecord);
|
||||
}
|
||||
|
||||
public HSSFSimpleShape( HSSFShape parent, HSSFAnchor anchor)
|
||||
{
|
||||
super( parent, anchor );
|
||||
_textObjectRecord = createTextObjRecord();
|
||||
}
|
||||
|
||||
protected TextObjectRecord getTextObjectRecord() {
|
||||
return _textObjectRecord;
|
||||
}
|
||||
|
||||
protected TextObjectRecord createTextObjRecord(){
|
||||
TextObjectRecord obj = new TextObjectRecord();
|
||||
obj.setHorizontalTextAlignment(2);
|
||||
obj.setVerticalTextAlignment(2);
|
||||
obj.setTextLocked(true);
|
||||
obj.setTextOrientation(TextObjectRecord.TEXT_ORIENTATION_NONE);
|
||||
obj.setStr(new HSSFRichTextString(""));
|
||||
return obj;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EscherContainerRecord createSpContainer() {
|
||||
EscherContainerRecord spContainer = new EscherContainerRecord();
|
||||
spContainer.setRecordId( EscherContainerRecord.SP_CONTAINER );
|
||||
spContainer.setOptions( (short) 0x000F );
|
||||
|
||||
EscherSpRecord sp = new EscherSpRecord();
|
||||
sp.setRecordId( EscherSpRecord.RECORD_ID );
|
||||
sp.setFlags( EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HASSHAPETYPE );
|
||||
sp.setVersion((short) 0x2);
|
||||
|
||||
EscherClientDataRecord clientData = new EscherClientDataRecord();
|
||||
clientData.setRecordId( EscherClientDataRecord.RECORD_ID );
|
||||
clientData.setOptions( (short) (0x0000) );
|
||||
|
||||
EscherOptRecord optRecord = new EscherOptRecord();
|
||||
optRecord.setEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEDASHING, LINESTYLE_SOLID));
|
||||
optRecord.setEscherProperty( new EscherBoolProperty( EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x00080008));
|
||||
// optRecord.setEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEWIDTH, LINEWIDTH_DEFAULT));
|
||||
optRecord.setEscherProperty(new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, FILL__FILLCOLOR_DEFAULT));
|
||||
optRecord.setEscherProperty(new EscherRGBProperty(EscherProperties.LINESTYLE__COLOR, LINESTYLE__COLOR_DEFAULT));
|
||||
optRecord.setEscherProperty(new EscherBoolProperty(EscherProperties.FILL__NOFILLHITTEST, NO_FILLHITTEST_FALSE));
|
||||
optRecord.setEscherProperty( new EscherBoolProperty( EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x00080008));
|
||||
|
||||
optRecord.setEscherProperty( new EscherShapePathProperty( EscherProperties.GEOMETRY__SHAPEPATH, EscherShapePathProperty.COMPLEX ) );
|
||||
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(getAnchor().getEscherAnchor());
|
||||
spContainer.addChildRecord(clientData);
|
||||
spContainer.addChildRecord(escherTextbox);
|
||||
return spContainer;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ObjRecord createObjRecord() {
|
||||
ObjRecord obj = new ObjRecord();
|
||||
CommonObjectDataSubRecord c = new CommonObjectDataSubRecord();
|
||||
c.setLocked(true);
|
||||
c.setPrintable(true);
|
||||
c.setAutofill(true);
|
||||
c.setAutoline(true);
|
||||
EndSubRecord e = new EndSubRecord();
|
||||
|
||||
obj.addSubRecord(c);
|
||||
obj.addSubRecord(e);
|
||||
return obj;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void afterRemove(HSSFPatriarch patriarch) {
|
||||
patriarch._getBoundAggregate().removeShapeToObjRecord(getEscherContainer().getChildById(EscherClientDataRecord.RECORD_ID));
|
||||
if (null != getEscherContainer().getChildById(EscherTextboxRecord.RECORD_ID)){
|
||||
patriarch._getBoundAggregate().removeShapeToObjRecord(getEscherContainer().getChildById(EscherTextboxRecord.RECORD_ID));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the rich text string for this textbox.
|
||||
*/
|
||||
public HSSFRichTextString getString() {
|
||||
return _textObjectRecord.getStr();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string Sets the rich text string used by this object.
|
||||
*/
|
||||
public void setString(RichTextString string) {
|
||||
//TODO add other shape types which can not contain text
|
||||
if (getShapeType() == 0 || getShapeType() == OBJECT_TYPE_LINE){
|
||||
throw new IllegalStateException("Cannot set text for shape type: "+getShapeType());
|
||||
}
|
||||
HSSFRichTextString rtr = (HSSFRichTextString) string;
|
||||
// If font is not set we must set the default one
|
||||
if (rtr.numFormattingRuns() == 0) rtr.applyFont((short) 0);
|
||||
_textObjectRecord.setStr(rtr);
|
||||
if (string.getString() != null){
|
||||
setPropertyValue(new EscherSimpleProperty(EscherProperties.TEXT__TEXTID, string.getString().hashCode()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void afterInsert(HSSFPatriarch patriarch){
|
||||
EscherAggregate agg = patriarch._getBoundAggregate();
|
||||
agg.associateShapeToObjRecord(getEscherContainer().getChildById(EscherClientDataRecord.RECORD_ID), getObjRecord());
|
||||
|
||||
if (null != getTextObjectRecord()){
|
||||
agg.associateShapeToObjRecord(getEscherContainer().getChildById(EscherTextboxRecord.RECORD_ID), getTextObjectRecord());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected 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 && null != getString().getString()){
|
||||
txo = (TextObjectRecord) getTextObjectRecord().cloneViaReserialise();
|
||||
}
|
||||
return new HSSFSimpleShape(spContainer, obj, txo);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the shape type.
|
||||
* @return One of the OBJECT_TYPE_* constants.
|
||||
@ -67,19 +210,28 @@ public class HSSFSimpleShape
|
||||
* @see #OBJECT_TYPE_PICTURE
|
||||
* @see #OBJECT_TYPE_COMMENT
|
||||
*/
|
||||
public int getShapeType() { return shapeType; }
|
||||
public int getShapeType() {
|
||||
EscherSpRecord spRecord = getEscherContainer().getChildById(EscherSpRecord.RECORD_ID);
|
||||
return spRecord.getShapeType();
|
||||
}
|
||||
|
||||
public int getWrapText(){
|
||||
EscherSimpleProperty property = getOptRecord().lookup(EscherProperties.TEXT__WRAPTEXT);
|
||||
return null == property ? WRAP_SQUARE : property.getPropertyValue();
|
||||
}
|
||||
|
||||
public void setWrapText(int value){
|
||||
setPropertyValue(new EscherSimpleProperty(EscherProperties.TEXT__WRAPTEXT, false, false, value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the shape types.
|
||||
*
|
||||
* @param shapeType One of the OBJECT_TYPE_* constants.
|
||||
*
|
||||
* @see #OBJECT_TYPE_LINE
|
||||
* @see #OBJECT_TYPE_OVAL
|
||||
* @see #OBJECT_TYPE_RECTANGLE
|
||||
* @see #OBJECT_TYPE_PICTURE
|
||||
* @see #OBJECT_TYPE_COMMENT
|
||||
* @see HSSFShapeTypes
|
||||
* @param value - shapeType
|
||||
*/
|
||||
public void setShapeType( int shapeType ){ this.shapeType = shapeType; }
|
||||
|
||||
public void setShapeType(int value){
|
||||
CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) getObjRecord().getSubRecords().get(0);
|
||||
cod.setObjectType(OBJECT_TYPE_MICROSOFT_OFFICE_DRAWING);
|
||||
EscherSpRecord spRecord = getEscherContainer().getChildById(EscherSpRecord.RECORD_ID);
|
||||
spRecord.setShapeType((short) value);
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,8 @@
|
||||
|
||||
package org.apache.poi.hssf.usermodel;
|
||||
|
||||
import org.apache.poi.ddf.*;
|
||||
import org.apache.poi.hssf.record.*;
|
||||
import org.apache.poi.ss.usermodel.RichTextString;
|
||||
|
||||
/**
|
||||
@ -24,163 +26,222 @@ import org.apache.poi.ss.usermodel.RichTextString;
|
||||
*
|
||||
* @author Glen Stampoultzis (glens at apache.org)
|
||||
*/
|
||||
public class HSSFTextbox
|
||||
extends HSSFSimpleShape
|
||||
{
|
||||
public final static short OBJECT_TYPE_TEXT = 6;
|
||||
public class HSSFTextbox extends HSSFSimpleShape {
|
||||
public final static short OBJECT_TYPE_TEXT = 6;
|
||||
|
||||
/**
|
||||
* How to align text horizontally
|
||||
*/
|
||||
public final static short HORIZONTAL_ALIGNMENT_LEFT = 1;
|
||||
public final static short HORIZONTAL_ALIGNMENT_CENTERED = 2;
|
||||
public final static short HORIZONTAL_ALIGNMENT_RIGHT = 3;
|
||||
public final static short HORIZONTAL_ALIGNMENT_JUSTIFIED = 4;
|
||||
public final static short HORIZONTAL_ALIGNMENT_DISTRIBUTED = 7;
|
||||
public final static short HORIZONTAL_ALIGNMENT_LEFT = 1;
|
||||
public final static short HORIZONTAL_ALIGNMENT_CENTERED = 2;
|
||||
public final static short HORIZONTAL_ALIGNMENT_RIGHT = 3;
|
||||
public final static short HORIZONTAL_ALIGNMENT_JUSTIFIED = 4;
|
||||
public final static short HORIZONTAL_ALIGNMENT_DISTRIBUTED = 7;
|
||||
|
||||
/**
|
||||
* How to align text vertically
|
||||
*/
|
||||
public final static short VERTICAL_ALIGNMENT_TOP = 1;
|
||||
public final static short VERTICAL_ALIGNMENT_CENTER = 2;
|
||||
public final static short VERTICAL_ALIGNMENT_BOTTOM = 3;
|
||||
public final static short VERTICAL_ALIGNMENT_JUSTIFY = 4;
|
||||
public final static short VERTICAL_ALIGNMENT_DISTRIBUTED= 7;
|
||||
public final static short VERTICAL_ALIGNMENT_TOP = 1;
|
||||
public final static short VERTICAL_ALIGNMENT_CENTER = 2;
|
||||
public final static short VERTICAL_ALIGNMENT_BOTTOM = 3;
|
||||
public final static short VERTICAL_ALIGNMENT_JUSTIFY = 4;
|
||||
public final static short VERTICAL_ALIGNMENT_DISTRIBUTED = 7;
|
||||
|
||||
|
||||
int marginLeft, marginRight, marginTop, marginBottom;
|
||||
short halign, valign;
|
||||
public HSSFTextbox(EscherContainerRecord spContainer, ObjRecord objRecord, TextObjectRecord textObjectRecord) {
|
||||
super(spContainer, objRecord, textObjectRecord);
|
||||
}
|
||||
|
||||
HSSFRichTextString string = new HSSFRichTextString("");
|
||||
|
||||
/**
|
||||
* Construct a new textbox with the given parent and anchor.
|
||||
*
|
||||
* @param parent
|
||||
* @param anchor One of HSSFClientAnchor or HSSFChildAnchor
|
||||
* @param anchor One of HSSFClientAnchor or HSSFChildAnchor
|
||||
*/
|
||||
public HSSFTextbox( HSSFShape parent, HSSFAnchor anchor )
|
||||
{
|
||||
super( parent, anchor );
|
||||
setShapeType(OBJECT_TYPE_TEXT);
|
||||
public HSSFTextbox(HSSFShape parent, HSSFAnchor anchor) {
|
||||
super(parent, anchor);
|
||||
setHorizontalAlignment(HORIZONTAL_ALIGNMENT_LEFT);
|
||||
setVerticalAlignment(VERTICAL_ALIGNMENT_TOP);
|
||||
setString(new HSSFRichTextString(""));
|
||||
}
|
||||
|
||||
halign = HORIZONTAL_ALIGNMENT_LEFT;
|
||||
valign = VERTICAL_ALIGNMENT_TOP;
|
||||
@Override
|
||||
protected ObjRecord createObjRecord() {
|
||||
ObjRecord obj = new ObjRecord();
|
||||
CommonObjectDataSubRecord c = new CommonObjectDataSubRecord();
|
||||
c.setObjectType(HSSFTextbox.OBJECT_TYPE_TEXT);
|
||||
c.setLocked(true);
|
||||
c.setPrintable(true);
|
||||
c.setAutofill(true);
|
||||
c.setAutoline(true);
|
||||
EndSubRecord e = new EndSubRecord();
|
||||
obj.addSubRecord(c);
|
||||
obj.addSubRecord(e);
|
||||
return obj;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EscherContainerRecord createSpContainer() {
|
||||
EscherContainerRecord spContainer = new EscherContainerRecord();
|
||||
EscherSpRecord sp = new EscherSpRecord();
|
||||
EscherOptRecord opt = new EscherOptRecord();
|
||||
EscherClientDataRecord clientData = new EscherClientDataRecord();
|
||||
EscherTextboxRecord escherTextbox = new EscherTextboxRecord();
|
||||
|
||||
spContainer.setRecordId(EscherContainerRecord.SP_CONTAINER);
|
||||
spContainer.setOptions((short) 0x000F);
|
||||
sp.setRecordId(EscherSpRecord.RECORD_ID);
|
||||
sp.setOptions((short) ((EscherAggregate.ST_TEXTBOX << 4) | 0x2));
|
||||
|
||||
sp.setFlags(EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HASSHAPETYPE);
|
||||
opt.setRecordId(EscherOptRecord.RECORD_ID);
|
||||
opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.TEXT__TEXTID, 0));
|
||||
opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.TEXT__WRAPTEXT, 0));
|
||||
opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.TEXT__ANCHORTEXT, 0));
|
||||
opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.GROUPSHAPE__PRINT, 0x00080000));
|
||||
|
||||
opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.TEXT__TEXTLEFT, 0));
|
||||
opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.TEXT__TEXTRIGHT, 0));
|
||||
opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.TEXT__TEXTTOP, 0));
|
||||
opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.TEXT__TEXTBOTTOM, 0));
|
||||
|
||||
opt.setEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEDASHING, LINESTYLE_SOLID));
|
||||
opt.setEscherProperty(new EscherBoolProperty(EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x00080008));
|
||||
opt.setEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEWIDTH, LINEWIDTH_DEFAULT));
|
||||
opt.setEscherProperty(new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, FILL__FILLCOLOR_DEFAULT));
|
||||
opt.setEscherProperty(new EscherRGBProperty(EscherProperties.LINESTYLE__COLOR, LINESTYLE__COLOR_DEFAULT));
|
||||
opt.setEscherProperty(new EscherBoolProperty(EscherProperties.FILL__NOFILLHITTEST, NO_FILLHITTEST_FALSE));
|
||||
opt.setEscherProperty(new EscherBoolProperty(EscherProperties.GROUPSHAPE__PRINT, 0x080000));
|
||||
|
||||
EscherRecord anchor = getAnchor().getEscherAnchor();
|
||||
clientData.setRecordId(EscherClientDataRecord.RECORD_ID);
|
||||
clientData.setOptions((short) 0x0000);
|
||||
escherTextbox.setRecordId(EscherTextboxRecord.RECORD_ID);
|
||||
escherTextbox.setOptions((short) 0x0000);
|
||||
|
||||
spContainer.addChildRecord(sp);
|
||||
spContainer.addChildRecord(opt);
|
||||
spContainer.addChildRecord(anchor);
|
||||
spContainer.addChildRecord(clientData);
|
||||
spContainer.addChildRecord(escherTextbox);
|
||||
|
||||
return spContainer;
|
||||
}
|
||||
|
||||
@Override
|
||||
void afterInsert(HSSFPatriarch patriarch) {
|
||||
EscherAggregate agg = patriarch._getBoundAggregate();
|
||||
agg.associateShapeToObjRecord(getEscherContainer().getChildById(EscherClientDataRecord.RECORD_ID), getObjRecord());
|
||||
agg.associateShapeToObjRecord(getEscherContainer().getChildById(EscherTextboxRecord.RECORD_ID), getTextObjectRecord());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the rich text string for this textbox.
|
||||
* @return Returns the left margin within the textbox.
|
||||
*/
|
||||
public HSSFRichTextString getString()
|
||||
{
|
||||
return string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string Sets the rich text string used by this object.
|
||||
*/
|
||||
public void setString( RichTextString string )
|
||||
{
|
||||
HSSFRichTextString rtr = (HSSFRichTextString)string;
|
||||
|
||||
// If font is not set we must set the default one
|
||||
if (rtr.numFormattingRuns() == 0) rtr.applyFont((short)0);
|
||||
|
||||
this.string = rtr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the left margin within the textbox.
|
||||
*/
|
||||
public int getMarginLeft()
|
||||
{
|
||||
return marginLeft;
|
||||
public int getMarginLeft() {
|
||||
EscherSimpleProperty property = getOptRecord().lookup(EscherProperties.TEXT__TEXTLEFT);
|
||||
return property == null ? 0 : property.getPropertyValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the left margin within the textbox.
|
||||
*/
|
||||
public void setMarginLeft( int marginLeft )
|
||||
{
|
||||
this.marginLeft = marginLeft;
|
||||
public void setMarginLeft(int marginLeft) {
|
||||
setPropertyValue(new EscherSimpleProperty(EscherProperties.TEXT__TEXTLEFT, marginLeft));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return returns the right margin within the textbox.
|
||||
* @return returns the right margin within the textbox.
|
||||
*/
|
||||
public int getMarginRight()
|
||||
{
|
||||
return marginRight;
|
||||
public int getMarginRight() {
|
||||
EscherSimpleProperty property = getOptRecord().lookup(EscherProperties.TEXT__TEXTRIGHT);
|
||||
return property == null ? 0 : property.getPropertyValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the right margin within the textbox.
|
||||
*/
|
||||
public void setMarginRight( int marginRight )
|
||||
{
|
||||
this.marginRight = marginRight;
|
||||
public void setMarginRight(int marginRight) {
|
||||
setPropertyValue(new EscherSimpleProperty(EscherProperties.TEXT__TEXTRIGHT, marginRight));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return returns the top margin within the textbox.
|
||||
* @return returns the top margin within the textbox.
|
||||
*/
|
||||
public int getMarginTop()
|
||||
{
|
||||
return marginTop;
|
||||
public int getMarginTop() {
|
||||
EscherSimpleProperty property = getOptRecord().lookup(EscherProperties.TEXT__TEXTTOP);
|
||||
return property == null ? 0 : property.getPropertyValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the top margin within the textbox.
|
||||
*/
|
||||
public void setMarginTop( int marginTop )
|
||||
{
|
||||
this.marginTop = marginTop;
|
||||
public void setMarginTop(int marginTop) {
|
||||
setPropertyValue(new EscherSimpleProperty(EscherProperties.TEXT__TEXTTOP, marginTop));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bottom margin within the textbox.
|
||||
*/
|
||||
public int getMarginBottom()
|
||||
{
|
||||
return marginBottom;
|
||||
public int getMarginBottom() {
|
||||
EscherSimpleProperty property = getOptRecord().lookup(EscherProperties.TEXT__TEXTBOTTOM);
|
||||
return property == null ? 0 : property.getPropertyValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the bottom margin within the textbox.
|
||||
*/
|
||||
public void setMarginBottom( int marginBottom )
|
||||
{
|
||||
this.marginBottom = marginBottom;
|
||||
public void setMarginBottom(int marginBottom) {
|
||||
setPropertyValue(new EscherSimpleProperty(EscherProperties.TEXT__TEXTBOTTOM, marginBottom));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the horizontal alignment.
|
||||
*/
|
||||
public short getHorizontalAlignment()
|
||||
{
|
||||
return halign;
|
||||
public short getHorizontalAlignment() {
|
||||
return (short) getTextObjectRecord().getHorizontalTextAlignment();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the horizontal alignment.
|
||||
*/
|
||||
public void setHorizontalAlignment( short align )
|
||||
{
|
||||
this.halign = align;
|
||||
public void setHorizontalAlignment(short align) {
|
||||
getTextObjectRecord().setHorizontalTextAlignment(align);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the vertical alignment.
|
||||
*/
|
||||
public short getVerticalAlignment()
|
||||
{
|
||||
return valign;
|
||||
public short getVerticalAlignment() {
|
||||
return (short) getTextObjectRecord().getVerticalTextAlignment();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the vertical alignment.
|
||||
*/
|
||||
public void setVerticalAlignment( short align )
|
||||
{
|
||||
this.valign = align;
|
||||
public void setVerticalAlignment(short align) {
|
||||
getTextObjectRecord().setVerticalTextAlignment(align);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setShapeType(int shapeType) {
|
||||
throw new IllegalStateException("Shape type can not be changed in " + this.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected 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
|
||||
protected void afterRemove(HSSFPatriarch patriarch) {
|
||||
patriarch._getBoundAggregate().removeShapeToObjRecord(getEscherContainer().getChildById(EscherClientDataRecord.RECORD_ID));
|
||||
patriarch._getBoundAggregate().removeShapeToObjRecord(getEscherContainer().getChildById(EscherTextboxRecord.RECORD_ID));
|
||||
}
|
||||
}
|
||||
|
@ -696,7 +696,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;
|
||||
}
|
||||
@ -1606,7 +1606,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
|
||||
r.setUid( uid );
|
||||
r.setTag( (short) 0xFF );
|
||||
r.setSize( pictureData.length + 25 );
|
||||
r.setRef( 1 );
|
||||
r.setRef( 0 );
|
||||
r.setOffset( 0 );
|
||||
r.setBlipRecord( blipRecord );
|
||||
|
||||
@ -1698,7 +1698,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
|
||||
List<HSSFObjectData> objects = new ArrayList<HSSFObjectData>();
|
||||
for (int i = 0; i < getNumberOfSheets(); i++)
|
||||
{
|
||||
getAllEmbeddedObjects(getSheetAt(i).getSheet().getRecords(), objects);
|
||||
getAllEmbeddedObjects(getSheetAt(i), objects);
|
||||
}
|
||||
return objects;
|
||||
}
|
||||
@ -1706,27 +1706,20 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
|
||||
/**
|
||||
* Gets all embedded OLE2 objects from the Workbook.
|
||||
*
|
||||
* @param records the list of records to search.
|
||||
* @param sheet embedded object attached to
|
||||
* @param objects the list of embedded objects to populate.
|
||||
*/
|
||||
private void getAllEmbeddedObjects(List<RecordBase> records, List<HSSFObjectData> objects)
|
||||
private void getAllEmbeddedObjects(HSSFSheet sheet, List<HSSFObjectData> objects)
|
||||
{
|
||||
for (RecordBase obj : records) {
|
||||
if (obj instanceof ObjRecord)
|
||||
{
|
||||
// TODO: More convenient way of determining if there is stored binary.
|
||||
// TODO: Link to the data stored in the other stream.
|
||||
Iterator<SubRecord> subRecordIter = ((ObjRecord) obj).getSubRecords().iterator();
|
||||
while (subRecordIter.hasNext())
|
||||
{
|
||||
SubRecord sub = subRecordIter.next();
|
||||
if (sub instanceof EmbeddedObjectRefSubRecord)
|
||||
{
|
||||
objects.add(new HSSFObjectData((ObjRecord) obj, directory));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
HSSFPatriarch patriarch = sheet.getDrawingPatriarch();
|
||||
if (null == patriarch){
|
||||
return;
|
||||
}
|
||||
for (HSSFShape shape: patriarch.getChildren()){
|
||||
if (shape instanceof HSSFObjectData){
|
||||
objects.add((HSSFObjectData) shape);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public HSSFCreationHelper getCreationHelper() {
|
||||
@ -1800,4 +1793,8 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
|
||||
public boolean changeExternalReference(String oldUrl, String newUrl) {
|
||||
return workbook.changeExternalReference(oldUrl, newUrl);
|
||||
}
|
||||
|
||||
public DirectoryNode getRootDirectory(){
|
||||
return directory;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,40 @@
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.hssf.model;
|
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFComment;
|
||||
import org.apache.poi.hssf.usermodel.HSSFPolygon;
|
||||
import org.apache.poi.hssf.usermodel.HSSFTextbox;
|
||||
|
||||
/**
|
||||
* @author Evgeniy Berlog
|
||||
* @date 25.06.12
|
||||
*/
|
||||
public class HSSFTestModelHelper {
|
||||
public static TextboxShape createTextboxShape(int shapeId, HSSFTextbox textbox){
|
||||
return new TextboxShape(textbox, shapeId);
|
||||
}
|
||||
|
||||
public static CommentShape createCommentShape(int shapeId, HSSFComment comment){
|
||||
return new CommentShape(comment, shapeId);
|
||||
}
|
||||
|
||||
public static PolygonShape createPolygonShape(int shapeId, HSSFPolygon polygon){
|
||||
return new PolygonShape(polygon, shapeId);
|
||||
}
|
||||
}
|
2265
src/testcases/org/apache/poi/hssf/model/TestDrawingAggregate.java
Normal file
2265
src/testcases/org/apache/poi/hssf/model/TestDrawingAggregate.java
Normal file
File diff suppressed because it is too large
Load Diff
665
src/testcases/org/apache/poi/hssf/model/TestDrawingShapes.java
Normal file
665
src/testcases/org/apache/poi/hssf/model/TestDrawingShapes.java
Normal file
@ -0,0 +1,665 @@
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.hssf.model;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.apache.poi.ddf.*;
|
||||
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||
import org.apache.poi.hssf.record.CommonObjectDataSubRecord;
|
||||
import org.apache.poi.hssf.record.EscherAggregate;
|
||||
import org.apache.poi.hssf.record.ObjRecord;
|
||||
import org.apache.poi.hssf.usermodel.*;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
import org.apache.poi.util.HexDump;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Evgeniy Berlog
|
||||
* date: 12.06.12
|
||||
*/
|
||||
public class TestDrawingShapes extends TestCase {
|
||||
|
||||
/**
|
||||
* HSSFShape tree bust be built correctly
|
||||
* Check file with such records structure:
|
||||
* -patriarch
|
||||
* --shape
|
||||
* --group
|
||||
* ---group
|
||||
* ----shape
|
||||
* ----shape
|
||||
* ---shape
|
||||
* ---group
|
||||
* ----shape
|
||||
* ----shape
|
||||
*/
|
||||
public void testDrawingGroups() {
|
||||
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls");
|
||||
HSSFSheet sheet = wb.getSheet("groups");
|
||||
HSSFPatriarch patriarch = sheet.getDrawingPatriarch();
|
||||
assertEquals(patriarch.getChildren().size(), 2);
|
||||
HSSFShapeGroup group = (HSSFShapeGroup) patriarch.getChildren().get(1);
|
||||
assertEquals(3, group.getChildren().size());
|
||||
HSSFShapeGroup group1 = (HSSFShapeGroup) group.getChildren().get(0);
|
||||
assertEquals(2, group1.getChildren().size());
|
||||
group1 = (HSSFShapeGroup) group.getChildren().get(2);
|
||||
assertEquals(2, group1.getChildren().size());
|
||||
}
|
||||
|
||||
public void testHSSFShapeCompatibility() {
|
||||
HSSFSimpleShape shape = new HSSFSimpleShape(null, new HSSFClientAnchor());
|
||||
shape.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
|
||||
assertEquals(0x08000040, shape.getLineStyleColor());
|
||||
assertEquals(0x08000009, shape.getFillColor());
|
||||
assertEquals(HSSFShape.LINEWIDTH_DEFAULT, shape.getLineWidth());
|
||||
assertEquals(HSSFShape.LINESTYLE_SOLID, shape.getLineStyle());
|
||||
assertFalse(shape.isNoFill());
|
||||
|
||||
AbstractShape sp = AbstractShape.createShape(shape, 1);
|
||||
EscherContainerRecord spContainer = sp.getSpContainer();
|
||||
EscherOptRecord opt =
|
||||
spContainer.getChildById(EscherOptRecord.RECORD_ID);
|
||||
|
||||
assertEquals(7, opt.getEscherProperties().size());
|
||||
assertEquals(true,
|
||||
((EscherBoolProperty) opt.lookup(EscherProperties.TEXT__SIZE_TEXT_TO_FIT_SHAPE)).isTrue());
|
||||
assertEquals(0x00000004,
|
||||
((EscherSimpleProperty) opt.lookup(EscherProperties.GEOMETRY__SHAPEPATH)).getPropertyValue());
|
||||
assertEquals(0x08000009,
|
||||
((EscherSimpleProperty) opt.lookup(EscherProperties.FILL__FILLCOLOR)).getPropertyValue());
|
||||
assertEquals(true,
|
||||
((EscherBoolProperty) opt.lookup(EscherProperties.FILL__NOFILLHITTEST)).isTrue());
|
||||
assertEquals(0x08000040,
|
||||
((EscherSimpleProperty) opt.lookup(EscherProperties.LINESTYLE__COLOR)).getPropertyValue());
|
||||
assertEquals(true,
|
||||
((EscherBoolProperty) opt.lookup(EscherProperties.LINESTYLE__NOLINEDRAWDASH)).isTrue());
|
||||
assertEquals(true,
|
||||
((EscherBoolProperty) opt.lookup(EscherProperties.GROUPSHAPE__PRINT)).isTrue());
|
||||
}
|
||||
|
||||
public void testDefaultPictureSettings() {
|
||||
HSSFPicture picture = new HSSFPicture(null, new HSSFClientAnchor());
|
||||
assertEquals(picture.getLineWidth(), HSSFShape.LINEWIDTH_DEFAULT);
|
||||
assertEquals(picture.getFillColor(), HSSFShape.FILL__FILLCOLOR_DEFAULT);
|
||||
assertEquals(picture.getLineStyle(), HSSFShape.LINESTYLE_NONE);
|
||||
assertEquals(picture.getLineStyleColor(), HSSFShape.LINESTYLE__COLOR_DEFAULT);
|
||||
assertEquals(picture.isNoFill(), false);
|
||||
assertEquals(picture.getPictureIndex(), -1);//not set yet
|
||||
}
|
||||
|
||||
/**
|
||||
* No NullPointerException should appear
|
||||
*/
|
||||
public void testDefaultSettingsWithEmptyContainer() {
|
||||
EscherContainerRecord container = new EscherContainerRecord();
|
||||
EscherOptRecord opt = new EscherOptRecord();
|
||||
opt.setRecordId(EscherOptRecord.RECORD_ID);
|
||||
container.addChildRecord(opt);
|
||||
ObjRecord obj = new ObjRecord();
|
||||
CommonObjectDataSubRecord cod = new CommonObjectDataSubRecord();
|
||||
cod.setObjectType(HSSFSimpleShape.OBJECT_TYPE_PICTURE);
|
||||
obj.addSubRecord(cod);
|
||||
HSSFPicture picture = new HSSFPicture(container, obj);
|
||||
|
||||
assertEquals(picture.getLineWidth(), HSSFShape.LINEWIDTH_DEFAULT);
|
||||
assertEquals(picture.getFillColor(), HSSFShape.FILL__FILLCOLOR_DEFAULT);
|
||||
assertEquals(picture.getLineStyle(), HSSFShape.LINESTYLE_DEFAULT);
|
||||
assertEquals(picture.getLineStyleColor(), HSSFShape.LINESTYLE__COLOR_DEFAULT);
|
||||
assertEquals(picture.isNoFill(), HSSFShape.NO_FILL_DEFAULT);
|
||||
assertEquals(picture.getPictureIndex(), -1);//not set yet
|
||||
}
|
||||
|
||||
/**
|
||||
* create a rectangle, save the workbook, read back and verify that all shape properties are there
|
||||
*/
|
||||
public void testReadWriteRectangle() throws IOException {
|
||||
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sheet = wb.createSheet();
|
||||
|
||||
HSSFPatriarch drawing = sheet.createDrawingPatriarch();
|
||||
HSSFClientAnchor anchor = new HSSFClientAnchor(10, 10, 50, 50, (short) 2, 2, (short) 4, 4);
|
||||
anchor.setAnchorType(2);
|
||||
assertEquals(anchor.getAnchorType(), 2);
|
||||
|
||||
HSSFSimpleShape rectangle = drawing.createSimpleShape(anchor);
|
||||
rectangle.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);
|
||||
rectangle.setLineWidth(10000);
|
||||
rectangle.setFillColor(777);
|
||||
assertEquals(rectangle.getFillColor(), 777);
|
||||
assertEquals(10000, rectangle.getLineWidth());
|
||||
rectangle.setLineStyle(10);
|
||||
assertEquals(10, rectangle.getLineStyle());
|
||||
assertEquals(rectangle.getWrapText(), HSSFSimpleShape.WRAP_SQUARE);
|
||||
rectangle.setLineStyleColor(1111);
|
||||
rectangle.setNoFill(true);
|
||||
rectangle.setWrapText(HSSFSimpleShape.WRAP_NONE);
|
||||
rectangle.setString(new HSSFRichTextString("teeeest"));
|
||||
assertEquals(rectangle.getLineStyleColor(), 1111);
|
||||
assertEquals(((EscherSimpleProperty)((EscherOptRecord)HSSFTestHelper.getEscherContainer(rectangle).getChildById(EscherOptRecord.RECORD_ID))
|
||||
.lookup(EscherProperties.TEXT__TEXTID)).getPropertyValue(), "teeeest".hashCode());
|
||||
assertEquals(rectangle.isNoFill(), true);
|
||||
assertEquals(rectangle.getWrapText(), HSSFSimpleShape.WRAP_NONE);
|
||||
assertEquals(rectangle.getString().getString(), "teeeest");
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sheet = wb.getSheetAt(0);
|
||||
drawing = sheet.getDrawingPatriarch();
|
||||
assertEquals(1, drawing.getChildren().size());
|
||||
|
||||
HSSFSimpleShape rectangle2 =
|
||||
(HSSFSimpleShape) drawing.getChildren().get(0);
|
||||
assertEquals(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE,
|
||||
rectangle2.getShapeType());
|
||||
assertEquals(10000, rectangle2.getLineWidth());
|
||||
assertEquals(10, rectangle2.getLineStyle());
|
||||
assertEquals(anchor, rectangle2.getAnchor());
|
||||
assertEquals(rectangle2.getLineStyleColor(), 1111);
|
||||
assertEquals(rectangle2.getFillColor(), 777);
|
||||
assertEquals(rectangle2.isNoFill(), true);
|
||||
assertEquals(rectangle2.getString().getString(), "teeeest");
|
||||
assertEquals(rectangle.getWrapText(), HSSFSimpleShape.WRAP_NONE);
|
||||
|
||||
rectangle2.setFillColor(3333);
|
||||
rectangle2.setLineStyle(9);
|
||||
rectangle2.setLineStyleColor(4444);
|
||||
rectangle2.setNoFill(false);
|
||||
rectangle2.setLineWidth(77);
|
||||
rectangle2.getAnchor().setDx1(2);
|
||||
rectangle2.getAnchor().setDx2(3);
|
||||
rectangle2.getAnchor().setDy1(4);
|
||||
rectangle2.getAnchor().setDy2(5);
|
||||
rectangle.setWrapText(HSSFSimpleShape.WRAP_BY_POINTS);
|
||||
rectangle2.setString(new HSSFRichTextString("test22"));
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sheet = wb.getSheetAt(0);
|
||||
drawing = sheet.getDrawingPatriarch();
|
||||
assertEquals(1, drawing.getChildren().size());
|
||||
rectangle2 = (HSSFSimpleShape) drawing.getChildren().get(0);
|
||||
assertEquals(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE, rectangle2.getShapeType());
|
||||
assertEquals(rectangle.getWrapText(), HSSFSimpleShape.WRAP_BY_POINTS);
|
||||
assertEquals(77, rectangle2.getLineWidth());
|
||||
assertEquals(9, rectangle2.getLineStyle());
|
||||
assertEquals(rectangle2.getLineStyleColor(), 4444);
|
||||
assertEquals(rectangle2.getFillColor(), 3333);
|
||||
assertEquals(rectangle2.getAnchor().getDx1(), 2);
|
||||
assertEquals(rectangle2.getAnchor().getDx2(), 3);
|
||||
assertEquals(rectangle2.getAnchor().getDy1(), 4);
|
||||
assertEquals(rectangle2.getAnchor().getDy2(), 5);
|
||||
assertEquals(rectangle2.isNoFill(), false);
|
||||
assertEquals(rectangle2.getString().getString(), "test22");
|
||||
|
||||
HSSFSimpleShape rect3 = drawing.createSimpleShape(new HSSFClientAnchor());
|
||||
rect3.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
|
||||
drawing = wb.getSheetAt(0).getDrawingPatriarch();
|
||||
assertEquals(drawing.getChildren().size(), 2);
|
||||
}
|
||||
|
||||
public void testReadExistingImage() {
|
||||
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls");
|
||||
HSSFSheet sheet = wb.getSheet("pictures");
|
||||
HSSFPatriarch drawing = sheet.getDrawingPatriarch();
|
||||
assertEquals(1, drawing.getChildren().size());
|
||||
HSSFPicture picture = (HSSFPicture) drawing.getChildren().get(0);
|
||||
|
||||
assertEquals(picture.getPictureIndex(), 2);
|
||||
assertEquals(picture.getLineStyleColor(), HSSFShape.LINESTYLE__COLOR_DEFAULT);
|
||||
assertEquals(picture.getFillColor(), 0x5DC943);
|
||||
assertEquals(picture.getLineWidth(), HSSFShape.LINEWIDTH_DEFAULT);
|
||||
assertEquals(picture.getLineStyle(), HSSFShape.LINESTYLE_DEFAULT);
|
||||
assertEquals(picture.isNoFill(), false);
|
||||
|
||||
picture.setPictureIndex(2);
|
||||
assertEquals(picture.getPictureIndex(), 2);
|
||||
}
|
||||
|
||||
|
||||
/* assert shape properties when reading shapes from a existing workbook */
|
||||
public void testReadExistingRectangle() {
|
||||
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls");
|
||||
HSSFSheet sheet = wb.getSheet("rectangles");
|
||||
HSSFPatriarch drawing = sheet.getDrawingPatriarch();
|
||||
assertEquals(1, drawing.getChildren().size());
|
||||
|
||||
HSSFSimpleShape shape = (HSSFSimpleShape) drawing.getChildren().get(0);
|
||||
assertEquals(shape.isNoFill(), false);
|
||||
assertEquals(shape.getLineStyle(), HSSFShape.LINESTYLE_DASHDOTGEL);
|
||||
assertEquals(shape.getLineStyleColor(), 0x616161);
|
||||
assertEquals(HexDump.toHex(shape.getFillColor()), shape.getFillColor(), 0x2CE03D);
|
||||
assertEquals(shape.getLineWidth(), HSSFShape.LINEWIDTH_ONE_PT * 2);
|
||||
assertEquals(shape.getString().getString(), "POItest");
|
||||
assertEquals(shape.getRotationDegree(), 27);
|
||||
}
|
||||
|
||||
public void testShapeIds() {
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sheet1 = wb.createSheet();
|
||||
HSSFPatriarch patriarch1 = sheet1.createDrawingPatriarch();
|
||||
for (int i = 0; i < 2; i++) {
|
||||
patriarch1.createSimpleShape(new HSSFClientAnchor());
|
||||
}
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sheet1 = wb.getSheetAt(0);
|
||||
patriarch1 = sheet1.getDrawingPatriarch();
|
||||
|
||||
EscherAggregate agg1 = HSSFTestHelper.getEscherAggregate(patriarch1);
|
||||
// last shape ID cached in EscherDgRecord
|
||||
EscherDgRecord dg1 =
|
||||
agg1.getEscherContainer().getChildById(EscherDgRecord.RECORD_ID);
|
||||
assertEquals(1026, dg1.getLastMSOSPID());
|
||||
|
||||
// iterate over shapes and check shapeId
|
||||
EscherContainerRecord spgrContainer =
|
||||
agg1.getEscherContainer().getChildContainers().get(0);
|
||||
// root spContainer + 2 spContainers for shapes
|
||||
assertEquals(3, spgrContainer.getChildRecords().size());
|
||||
|
||||
EscherSpRecord sp0 =
|
||||
((EscherContainerRecord) spgrContainer.getChild(0)).getChildById(EscherSpRecord.RECORD_ID);
|
||||
assertEquals(1024, sp0.getShapeId());
|
||||
|
||||
EscherSpRecord sp1 =
|
||||
((EscherContainerRecord) spgrContainer.getChild(1)).getChildById(EscherSpRecord.RECORD_ID);
|
||||
assertEquals(1025, sp1.getShapeId());
|
||||
|
||||
EscherSpRecord sp2 =
|
||||
((EscherContainerRecord) spgrContainer.getChild(2)).getChildById(EscherSpRecord.RECORD_ID);
|
||||
assertEquals(1026, sp2.getShapeId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get new id for shapes from existing file
|
||||
* File already have for 1 shape on each sheet, because document must contain EscherDgRecord for each sheet
|
||||
*/
|
||||
public void testAllocateNewIds() {
|
||||
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("empty.xls");
|
||||
HSSFSheet sheet = wb.getSheetAt(0);
|
||||
HSSFPatriarch patriarch = sheet.getDrawingPatriarch();
|
||||
|
||||
/**
|
||||
* 2048 - main SpContainer id
|
||||
* 2049 - existing shape id
|
||||
*/
|
||||
assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 2050);
|
||||
assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 2051);
|
||||
assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 2052);
|
||||
|
||||
sheet = wb.getSheetAt(1);
|
||||
patriarch = sheet.getDrawingPatriarch();
|
||||
|
||||
/**
|
||||
* 3072 - main SpContainer id
|
||||
* 3073 - existing shape id
|
||||
*/
|
||||
assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 3074);
|
||||
assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 3075);
|
||||
assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 3076);
|
||||
|
||||
|
||||
sheet = wb.getSheetAt(2);
|
||||
patriarch = sheet.getDrawingPatriarch();
|
||||
|
||||
assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 1026);
|
||||
assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 1027);
|
||||
assertEquals(HSSFTestHelper.allocateNewShapeId(patriarch), 1028);
|
||||
}
|
||||
|
||||
public void testOpt() throws Exception {
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
|
||||
// create a sheet with a text box
|
||||
HSSFSheet sheet = wb.createSheet();
|
||||
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
|
||||
|
||||
HSSFTextbox textbox = patriarch.createTextbox(new HSSFClientAnchor());
|
||||
EscherOptRecord opt1 = HSSFTestHelper.getOptRecord(textbox);
|
||||
EscherOptRecord opt2 = HSSFTestHelper.getEscherContainer(textbox).getChildById(EscherOptRecord.RECORD_ID);
|
||||
assertSame(opt1, opt2);
|
||||
}
|
||||
|
||||
public void testCorrectOrderInOptRecord(){
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sheet = wb.createSheet();
|
||||
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
|
||||
|
||||
HSSFTextbox textbox = patriarch.createTextbox(new HSSFClientAnchor());
|
||||
EscherOptRecord opt = HSSFTestHelper.getOptRecord(textbox);
|
||||
|
||||
String opt1Str = opt.toXml();
|
||||
|
||||
textbox.setFillColor(textbox.getFillColor());
|
||||
EscherContainerRecord container = HSSFTestHelper.getEscherContainer(textbox);
|
||||
EscherOptRecord optRecord = container.getChildById(EscherOptRecord.RECORD_ID);
|
||||
assertEquals(opt1Str, optRecord.toXml());
|
||||
textbox.setLineStyle(textbox.getLineStyle());
|
||||
assertEquals(opt1Str, optRecord.toXml());
|
||||
textbox.setLineWidth(textbox.getLineWidth());
|
||||
assertEquals(opt1Str, optRecord.toXml());
|
||||
textbox.setLineStyleColor(textbox.getLineStyleColor());
|
||||
assertEquals(opt1Str, optRecord.toXml());
|
||||
}
|
||||
|
||||
public void testDgRecordNumShapes(){
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sheet = wb.createSheet();
|
||||
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
|
||||
|
||||
EscherAggregate aggregate = HSSFTestHelper.getEscherAggregate(patriarch);
|
||||
EscherDgRecord dgRecord = (EscherDgRecord) aggregate.getEscherRecord(0).getChild(0);
|
||||
assertEquals(dgRecord.getNumShapes(), 1);
|
||||
}
|
||||
|
||||
public void testTextForSimpleShape(){
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sheet = wb.createSheet();
|
||||
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
|
||||
|
||||
HSSFSimpleShape shape = patriarch.createSimpleShape(new HSSFClientAnchor());
|
||||
shape.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);
|
||||
|
||||
EscherAggregate agg = HSSFTestHelper.getEscherAggregate(patriarch);
|
||||
assertEquals(agg.getShapeToObjMapping().size(), 2);
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sheet = wb.getSheetAt(0);
|
||||
patriarch = sheet.getDrawingPatriarch();
|
||||
|
||||
shape = (HSSFSimpleShape) patriarch.getChildren().get(0);
|
||||
|
||||
agg = HSSFTestHelper.getEscherAggregate(patriarch);
|
||||
assertEquals(agg.getShapeToObjMapping().size(), 2);
|
||||
|
||||
shape.setString(new HSSFRichTextString("string1"));
|
||||
assertEquals(shape.getString().getString(), "string1");
|
||||
|
||||
assertNotNull(HSSFTestHelper.getEscherContainer(shape).getChildById(EscherTextboxRecord.RECORD_ID));
|
||||
assertEquals(agg.getShapeToObjMapping().size(), 2);
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sheet = wb.getSheetAt(0);
|
||||
patriarch = sheet.getDrawingPatriarch();
|
||||
|
||||
shape = (HSSFSimpleShape) patriarch.getChildren().get(0);
|
||||
|
||||
assertNotNull(HSSFTestHelper.getTextObjRecord(shape));
|
||||
assertEquals(shape.getString().getString(), "string1");
|
||||
assertNotNull(HSSFTestHelper.getEscherContainer(shape).getChildById(EscherTextboxRecord.RECORD_ID));
|
||||
assertEquals(agg.getShapeToObjMapping().size(), 2);
|
||||
}
|
||||
|
||||
public void testRemoveShapes(){
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sheet = wb.createSheet();
|
||||
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
|
||||
|
||||
HSSFSimpleShape rectangle = patriarch.createSimpleShape(new HSSFClientAnchor());
|
||||
rectangle.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);
|
||||
|
||||
int idx = wb.addPicture(new byte[]{1,2,3}, Workbook.PICTURE_TYPE_JPEG);
|
||||
patriarch.createPicture(new HSSFClientAnchor(), idx);
|
||||
|
||||
patriarch.createCellComment(new HSSFClientAnchor());
|
||||
|
||||
HSSFPolygon polygon = patriarch.createPolygon(new HSSFClientAnchor());
|
||||
polygon.setPoints(new int[]{1,2}, new int[]{2,3});
|
||||
|
||||
patriarch.createTextbox(new HSSFClientAnchor());
|
||||
|
||||
HSSFShapeGroup group = patriarch.createGroup(new HSSFClientAnchor());
|
||||
group.createTextbox(new HSSFChildAnchor());
|
||||
group.createPicture(new HSSFChildAnchor(), idx);
|
||||
|
||||
assertEquals(patriarch.getChildren().size(), 6);
|
||||
assertEquals(group.getChildren().size(), 2);
|
||||
|
||||
assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 12);
|
||||
assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sheet = wb.getSheetAt(0);
|
||||
patriarch = sheet.getDrawingPatriarch();
|
||||
|
||||
assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 12);
|
||||
assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);
|
||||
|
||||
assertEquals(patriarch.getChildren().size(), 6);
|
||||
|
||||
group = (HSSFShapeGroup) patriarch.getChildren().get(5);
|
||||
group.removeShape(group.getChildren().get(0));
|
||||
|
||||
assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 10);
|
||||
assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sheet = wb.getSheetAt(0);
|
||||
patriarch = sheet.getDrawingPatriarch();
|
||||
|
||||
assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 10);
|
||||
assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);
|
||||
|
||||
group = (HSSFShapeGroup) patriarch.getChildren().get(5);
|
||||
patriarch.removeShape(group);
|
||||
|
||||
assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 8);
|
||||
assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sheet = wb.getSheetAt(0);
|
||||
patriarch = sheet.getDrawingPatriarch();
|
||||
|
||||
assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 8);
|
||||
assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);
|
||||
assertEquals(patriarch.getChildren().size(), 5);
|
||||
|
||||
HSSFShape shape = patriarch.getChildren().get(0);
|
||||
patriarch.removeShape(shape);
|
||||
|
||||
assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 6);
|
||||
assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);
|
||||
assertEquals(patriarch.getChildren().size(), 4);
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sheet = wb.getSheetAt(0);
|
||||
patriarch = sheet.getDrawingPatriarch();
|
||||
|
||||
assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 6);
|
||||
assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);
|
||||
assertEquals(patriarch.getChildren().size(), 4);
|
||||
|
||||
HSSFPicture picture = (HSSFPicture) patriarch.getChildren().get(0);
|
||||
patriarch.removeShape(picture);
|
||||
|
||||
assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 5);
|
||||
assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);
|
||||
assertEquals(patriarch.getChildren().size(), 3);
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sheet = wb.getSheetAt(0);
|
||||
patriarch = sheet.getDrawingPatriarch();
|
||||
|
||||
assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 5);
|
||||
assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 1);
|
||||
assertEquals(patriarch.getChildren().size(), 3);
|
||||
|
||||
HSSFComment comment = (HSSFComment) patriarch.getChildren().get(0);
|
||||
patriarch.removeShape(comment);
|
||||
|
||||
assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 3);
|
||||
assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 0);
|
||||
assertEquals(patriarch.getChildren().size(), 2);
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sheet = wb.getSheetAt(0);
|
||||
patriarch = sheet.getDrawingPatriarch();
|
||||
|
||||
assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 3);
|
||||
assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 0);
|
||||
assertEquals(patriarch.getChildren().size(), 2);
|
||||
|
||||
polygon = (HSSFPolygon) patriarch.getChildren().get(0);
|
||||
patriarch.removeShape(polygon);
|
||||
|
||||
assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 2);
|
||||
assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 0);
|
||||
assertEquals(patriarch.getChildren().size(), 1);
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sheet = wb.getSheetAt(0);
|
||||
patriarch = sheet.getDrawingPatriarch();
|
||||
|
||||
assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 2);
|
||||
assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 0);
|
||||
assertEquals(patriarch.getChildren().size(), 1);
|
||||
|
||||
HSSFTextbox textbox = (HSSFTextbox) patriarch.getChildren().get(0);
|
||||
patriarch.removeShape(textbox);
|
||||
|
||||
assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 0);
|
||||
assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 0);
|
||||
assertEquals(patriarch.getChildren().size(), 0);
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sheet = wb.getSheetAt(0);
|
||||
patriarch = sheet.getDrawingPatriarch();
|
||||
|
||||
assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getShapeToObjMapping().size(), 0);
|
||||
assertEquals(HSSFTestHelper.getEscherAggregate(patriarch).getTailRecords().size(), 0);
|
||||
assertEquals(patriarch.getChildren().size(), 0);
|
||||
}
|
||||
|
||||
public void testShapeFlip(){
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sheet = wb.createSheet();
|
||||
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
|
||||
|
||||
HSSFSimpleShape rectangle = patriarch.createSimpleShape(new HSSFClientAnchor());
|
||||
rectangle.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);
|
||||
|
||||
assertEquals(rectangle.isFlipVertical(), false);
|
||||
assertEquals(rectangle.isFlipHorizontal(), false);
|
||||
|
||||
rectangle.setFlipVertical(true);
|
||||
assertEquals(rectangle.isFlipVertical(), true);
|
||||
rectangle.setFlipHorizontal(true);
|
||||
assertEquals(rectangle.isFlipHorizontal(), true);
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sheet = wb.getSheetAt(0);
|
||||
patriarch = sheet.getDrawingPatriarch();
|
||||
|
||||
rectangle = (HSSFSimpleShape) patriarch.getChildren().get(0);
|
||||
|
||||
assertEquals(rectangle.isFlipHorizontal(), true);
|
||||
rectangle.setFlipHorizontal(false);
|
||||
assertEquals(rectangle.isFlipHorizontal(), false);
|
||||
|
||||
assertEquals(rectangle.isFlipVertical(), true);
|
||||
rectangle.setFlipVertical(false);
|
||||
assertEquals(rectangle.isFlipVertical(), false);
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sheet = wb.getSheetAt(0);
|
||||
patriarch = sheet.getDrawingPatriarch();
|
||||
|
||||
rectangle = (HSSFSimpleShape) patriarch.getChildren().get(0);
|
||||
|
||||
assertEquals(rectangle.isFlipVertical(), false);
|
||||
assertEquals(rectangle.isFlipHorizontal(), false);
|
||||
}
|
||||
|
||||
public void testRotation() {
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sheet = wb.createSheet();
|
||||
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
|
||||
|
||||
HSSFSimpleShape rectangle = patriarch.createSimpleShape(new HSSFClientAnchor(0,0,100,100, (short) 0,0,(short)5,5));
|
||||
rectangle.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);
|
||||
|
||||
assertEquals(rectangle.getRotationDegree(), 0);
|
||||
rectangle.setRotationDegree((short) 45);
|
||||
assertEquals(rectangle.getRotationDegree(), 45);
|
||||
rectangle.setFlipHorizontal(true);
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sheet = wb.getSheetAt(0);
|
||||
patriarch = sheet.getDrawingPatriarch();
|
||||
rectangle = (HSSFSimpleShape) patriarch.getChildren().get(0);
|
||||
assertEquals(rectangle.getRotationDegree(), 45);
|
||||
rectangle.setRotationDegree((short) 30);
|
||||
assertEquals(rectangle.getRotationDegree(), 30);
|
||||
|
||||
patriarch.setCoordinates(0, 0, 10, 10);
|
||||
rectangle.setString(new HSSFRichTextString("1234"));
|
||||
}
|
||||
|
||||
public void testShapeContainerImplementsIterable(){
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sheet = wb.createSheet();
|
||||
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
|
||||
|
||||
patriarch.createSimpleShape(new HSSFClientAnchor());
|
||||
patriarch.createSimpleShape(new HSSFClientAnchor());
|
||||
|
||||
int i=2;
|
||||
|
||||
for (HSSFShape shape: patriarch){
|
||||
i--;
|
||||
}
|
||||
assertEquals(i, 0);
|
||||
}
|
||||
|
||||
public void testClearShapesForPatriarch(){
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sheet = wb.createSheet();
|
||||
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
|
||||
|
||||
patriarch.createSimpleShape(new HSSFClientAnchor());
|
||||
patriarch.createSimpleShape(new HSSFClientAnchor());
|
||||
patriarch.createCellComment(new HSSFClientAnchor());
|
||||
|
||||
EscherAggregate agg = HSSFTestHelper.getEscherAggregate(patriarch);
|
||||
|
||||
assertEquals(agg.getShapeToObjMapping().size(), 6);
|
||||
assertEquals(agg.getTailRecords().size(), 1);
|
||||
assertEquals(patriarch.getChildren().size(), 3);
|
||||
|
||||
patriarch.clear();
|
||||
|
||||
assertEquals(agg.getShapeToObjMapping().size(), 0);
|
||||
assertEquals(agg.getTailRecords().size(), 0);
|
||||
assertEquals(patriarch.getChildren().size(), 0);
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sheet = wb.getSheetAt(0);
|
||||
patriarch = sheet.getDrawingPatriarch();
|
||||
|
||||
assertEquals(agg.getShapeToObjMapping().size(), 0);
|
||||
assertEquals(agg.getTailRecords().size(), 0);
|
||||
assertEquals(patriarch.getChildren().size(), 0);
|
||||
}
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.hssf.model;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.apache.poi.ddf.DefaultEscherRecordFactory;
|
||||
import org.apache.poi.ddf.EscherContainerRecord;
|
||||
import org.apache.poi.ddf.EscherTextboxRecord;
|
||||
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||
import org.apache.poi.hssf.record.EscherAggregate;
|
||||
import org.apache.poi.hssf.record.Record;
|
||||
import org.apache.poi.hssf.record.RecordBase;
|
||||
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||
import org.apache.poi.hssf.usermodel.HSSFTestHelper;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* @author Evgeniy Berlog
|
||||
* @date 18.06.12
|
||||
*/
|
||||
public class TestEscherRecordFactory extends TestCase{
|
||||
|
||||
private static byte[] toByteArray(List<RecordBase> records) {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
for (RecordBase rb : records) {
|
||||
Record r = (Record) rb;
|
||||
try {
|
||||
out.write(r.serialize());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
||||
public void testDetectContainer() {
|
||||
Random rnd = new Random();
|
||||
assertEquals(true, DefaultEscherRecordFactory.isContainer((short) 0x0, EscherContainerRecord.DG_CONTAINER));
|
||||
assertEquals(true, DefaultEscherRecordFactory.isContainer((short) 0x0, EscherContainerRecord.SOLVER_CONTAINER));
|
||||
assertEquals(true, DefaultEscherRecordFactory.isContainer((short) 0x0, EscherContainerRecord.SP_CONTAINER));
|
||||
assertEquals(true, DefaultEscherRecordFactory.isContainer((short) 0x0, EscherContainerRecord.DGG_CONTAINER));
|
||||
assertEquals(true, DefaultEscherRecordFactory.isContainer((short) 0x0, EscherContainerRecord.BSTORE_CONTAINER));
|
||||
assertEquals(true, DefaultEscherRecordFactory.isContainer((short) 0x0, EscherContainerRecord.SPGR_CONTAINER));
|
||||
|
||||
for (Short i=EscherContainerRecord.DGG_CONTAINER; i<= EscherContainerRecord.SOLVER_CONTAINER; i++){
|
||||
assertEquals(true, DefaultEscherRecordFactory.isContainer(Integer.valueOf(rnd.nextInt(Short.MAX_VALUE)).shortValue(), i));
|
||||
}
|
||||
|
||||
assertEquals(false, DefaultEscherRecordFactory.isContainer((short) 0x0, Integer.valueOf(EscherContainerRecord.DGG_CONTAINER-1).shortValue()));
|
||||
assertEquals(false, DefaultEscherRecordFactory.isContainer((short) 0x0, Integer.valueOf(EscherContainerRecord.SOLVER_CONTAINER+1).shortValue()));
|
||||
|
||||
assertEquals(true, DefaultEscherRecordFactory.isContainer((short) 0x000F, Integer.valueOf(EscherContainerRecord.DGG_CONTAINER-1).shortValue()));
|
||||
assertEquals(true, DefaultEscherRecordFactory.isContainer((short) 0xFFFF, Integer.valueOf(EscherContainerRecord.DGG_CONTAINER-1).shortValue()));
|
||||
assertEquals(false, DefaultEscherRecordFactory.isContainer((short) 0x000C, Integer.valueOf(EscherContainerRecord.DGG_CONTAINER-1).shortValue()));
|
||||
assertEquals(false, DefaultEscherRecordFactory.isContainer((short) 0xCCCC, Integer.valueOf(EscherContainerRecord.DGG_CONTAINER-1).shortValue()));
|
||||
assertEquals(false, DefaultEscherRecordFactory.isContainer((short) 0x000F, EscherTextboxRecord.RECORD_ID));
|
||||
assertEquals(false, DefaultEscherRecordFactory.isContainer((short) 0xCCCC, EscherTextboxRecord.RECORD_ID));
|
||||
}
|
||||
|
||||
public void testDgContainerMustBeRootOfHSSFSheetEscherRecords() throws IOException {
|
||||
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("47251.xls");
|
||||
HSSFSheet sh = wb.getSheetAt(0);
|
||||
InternalSheet ish = HSSFTestHelper.getSheetForTest(sh);
|
||||
List<RecordBase> records = ish.getRecords();
|
||||
// records to be aggregated
|
||||
List<RecordBase> dgRecords = records.subList(19, 23);
|
||||
byte[] dgBytes = toByteArray(dgRecords);
|
||||
sh.getDrawingPatriarch();
|
||||
EscherAggregate agg = (EscherAggregate) ish.findFirstRecordBySid(EscherAggregate.sid);
|
||||
assertEquals(true, agg.getEscherRecords().get(0) instanceof EscherContainerRecord);
|
||||
assertEquals(EscherContainerRecord.DG_CONTAINER, agg.getEscherRecords().get(0).getRecordId());
|
||||
assertEquals((short) 0x0, agg.getEscherRecords().get(0).getOptions());
|
||||
agg = (EscherAggregate) ish.findFirstRecordBySid(EscherAggregate.sid);
|
||||
byte[] dgBytesAfterSave = agg.serialize();
|
||||
assertEquals("different size of drawing data before and after save", dgBytes.length, dgBytesAfterSave.length);
|
||||
assertTrue("drawing data before and after save is different", Arrays.equals(dgBytes, dgBytesAfterSave));
|
||||
}
|
||||
}
|
428
src/testcases/org/apache/poi/hssf/model/TestHSSFAnchor.java
Normal file
428
src/testcases/org/apache/poi/hssf/model/TestHSSFAnchor.java
Normal file
@ -0,0 +1,428 @@
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.hssf.model;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.apache.poi.ddf.*;
|
||||
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||
import org.apache.poi.hssf.usermodel.*;
|
||||
import org.apache.poi.util.HexDump;
|
||||
|
||||
/**
|
||||
* @author Evgeniy Berlog
|
||||
* @date 12.06.12
|
||||
*/
|
||||
public class TestHSSFAnchor extends TestCase {
|
||||
|
||||
public void testDefaultValues(){
|
||||
HSSFClientAnchor clientAnchor = new HSSFClientAnchor();
|
||||
assertEquals(clientAnchor.getAnchorType(), 0);
|
||||
assertEquals(clientAnchor.getCol1(), 0);
|
||||
assertEquals(clientAnchor.getCol2(), 0);
|
||||
assertEquals(clientAnchor.getDx1(), 0);
|
||||
assertEquals(clientAnchor.getDx2(), 0);
|
||||
assertEquals(clientAnchor.getDy1(), 0);
|
||||
assertEquals(clientAnchor.getDy2(), 0);
|
||||
assertEquals(clientAnchor.getRow1(), 0);
|
||||
assertEquals(clientAnchor.getRow2(), 0);
|
||||
|
||||
clientAnchor = new HSSFClientAnchor(new EscherClientAnchorRecord());
|
||||
assertEquals(clientAnchor.getAnchorType(), 0);
|
||||
assertEquals(clientAnchor.getCol1(), 0);
|
||||
assertEquals(clientAnchor.getCol2(), 0);
|
||||
assertEquals(clientAnchor.getDx1(), 0);
|
||||
assertEquals(clientAnchor.getDx2(), 0);
|
||||
assertEquals(clientAnchor.getDy1(), 0);
|
||||
assertEquals(clientAnchor.getDy2(), 0);
|
||||
assertEquals(clientAnchor.getRow1(), 0);
|
||||
assertEquals(clientAnchor.getRow2(), 0);
|
||||
|
||||
HSSFChildAnchor childAnchor = new HSSFChildAnchor();
|
||||
assertEquals(childAnchor.getDx1(), 0);
|
||||
assertEquals(childAnchor.getDx2(), 0);
|
||||
assertEquals(childAnchor.getDy1(), 0);
|
||||
assertEquals(childAnchor.getDy2(), 0);
|
||||
|
||||
childAnchor = new HSSFChildAnchor(new EscherChildAnchorRecord());
|
||||
assertEquals(childAnchor.getDx1(), 0);
|
||||
assertEquals(childAnchor.getDx2(), 0);
|
||||
assertEquals(childAnchor.getDy1(), 0);
|
||||
assertEquals(childAnchor.getDy2(), 0);
|
||||
}
|
||||
|
||||
public void testCorrectOrderInSpContainer(){
|
||||
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls");
|
||||
HSSFSheet sheet = wb.getSheet("pictures");
|
||||
HSSFPatriarch drawing = sheet.getDrawingPatriarch();
|
||||
|
||||
HSSFSimpleShape rectangle = (HSSFSimpleShape) drawing.getChildren().get(0);
|
||||
|
||||
assertEquals(HSSFTestHelper.getEscherContainer(rectangle).getChild(0).getRecordId(), EscherSpRecord.RECORD_ID);
|
||||
assertEquals(HSSFTestHelper.getEscherContainer(rectangle).getChild(1).getRecordId(), EscherOptRecord.RECORD_ID);
|
||||
assertEquals(HSSFTestHelper.getEscherContainer(rectangle).getChild(2).getRecordId(), EscherClientAnchorRecord.RECORD_ID);
|
||||
assertEquals(HSSFTestHelper.getEscherContainer(rectangle).getChild(3).getRecordId(), EscherClientDataRecord.RECORD_ID);
|
||||
|
||||
rectangle.setAnchor(new HSSFClientAnchor());
|
||||
|
||||
assertEquals(HSSFTestHelper.getEscherContainer(rectangle).getChild(0).getRecordId(), EscherSpRecord.RECORD_ID);
|
||||
assertEquals(HSSFTestHelper.getEscherContainer(rectangle).getChild(1).getRecordId(), EscherOptRecord.RECORD_ID);
|
||||
assertEquals(HSSFTestHelper.getEscherContainer(rectangle).getChild(2).getRecordId(), EscherClientAnchorRecord.RECORD_ID);
|
||||
assertEquals(HSSFTestHelper.getEscherContainer(rectangle).getChild(3).getRecordId(), EscherClientDataRecord.RECORD_ID);
|
||||
}
|
||||
|
||||
public void testCreateClientAnchorFromContainer(){
|
||||
EscherContainerRecord container = new EscherContainerRecord();
|
||||
EscherClientAnchorRecord escher = new EscherClientAnchorRecord();
|
||||
escher.setFlag((short) 3);
|
||||
escher.setCol1((short)11);
|
||||
escher.setCol2((short)12);
|
||||
escher.setRow1((short)13);
|
||||
escher.setRow2((short) 14);
|
||||
escher.setDx1((short) 15);
|
||||
escher.setDx2((short) 16);
|
||||
escher.setDy1((short) 17);
|
||||
escher.setDy2((short) 18);
|
||||
container.addChildRecord(escher);
|
||||
|
||||
HSSFClientAnchor anchor = (HSSFClientAnchor) HSSFAnchor.createAnchorFromEscher(container);
|
||||
assertEquals(anchor.getCol1(), 11);
|
||||
assertEquals(escher.getCol1(), 11);
|
||||
assertEquals(anchor.getCol2(), 12);
|
||||
assertEquals(escher.getCol2(), 12);
|
||||
assertEquals(anchor.getRow1(), 13);
|
||||
assertEquals(escher.getRow1(), 13);
|
||||
assertEquals(anchor.getRow2(), 14);
|
||||
assertEquals(escher.getRow2(), 14);
|
||||
assertEquals(anchor.getDx1(), 15);
|
||||
assertEquals(escher.getDx1(), 15);
|
||||
assertEquals(anchor.getDx2(), 16);
|
||||
assertEquals(escher.getDx2(), 16);
|
||||
assertEquals(anchor.getDy1(), 17);
|
||||
assertEquals(escher.getDy1(), 17);
|
||||
assertEquals(anchor.getDy2(), 18);
|
||||
assertEquals(escher.getDy2(), 18);
|
||||
}
|
||||
|
||||
public void testCreateChildAnchorFromContainer(){
|
||||
EscherContainerRecord container = new EscherContainerRecord();
|
||||
EscherChildAnchorRecord escher = new EscherChildAnchorRecord();
|
||||
escher.setDx1((short) 15);
|
||||
escher.setDx2((short) 16);
|
||||
escher.setDy1((short) 17);
|
||||
escher.setDy2((short) 18);
|
||||
container.addChildRecord(escher);
|
||||
|
||||
HSSFChildAnchor anchor = (HSSFChildAnchor) HSSFAnchor.createAnchorFromEscher(container);
|
||||
assertEquals(anchor.getDx1(), 15);
|
||||
assertEquals(escher.getDx1(), 15);
|
||||
assertEquals(anchor.getDx2(), 16);
|
||||
assertEquals(escher.getDx2(), 16);
|
||||
assertEquals(anchor.getDy1(), 17);
|
||||
assertEquals(escher.getDy1(), 17);
|
||||
assertEquals(anchor.getDy2(), 18);
|
||||
assertEquals(escher.getDy2(), 18);
|
||||
}
|
||||
|
||||
public void testShapeEscherMustHaveAnchorRecord(){
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sheet = wb.createSheet();
|
||||
|
||||
HSSFPatriarch drawing = sheet.createDrawingPatriarch();
|
||||
HSSFClientAnchor anchor = new HSSFClientAnchor(10, 10, 200, 200, (short)2, 2, (short)15, 15);
|
||||
anchor.setAnchorType(2);
|
||||
|
||||
HSSFSimpleShape rectangle = drawing.createSimpleShape(anchor);
|
||||
rectangle.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);
|
||||
|
||||
rectangle.setAnchor(anchor);
|
||||
|
||||
assertNotNull(HSSFTestHelper.getEscherAnchor(anchor));
|
||||
assertNotNull(HSSFTestHelper.getEscherContainer(rectangle));
|
||||
assertTrue(HSSFTestHelper.getEscherAnchor(anchor).equals(HSSFTestHelper.getEscherContainer(rectangle).getChildById(EscherClientAnchorRecord.RECORD_ID)));
|
||||
}
|
||||
|
||||
public void testClientAnchorFromEscher(){
|
||||
EscherClientAnchorRecord escher = new EscherClientAnchorRecord();
|
||||
escher.setCol1((short)11);
|
||||
escher.setCol2((short)12);
|
||||
escher.setRow1((short)13);
|
||||
escher.setRow2((short) 14);
|
||||
escher.setDx1((short) 15);
|
||||
escher.setDx2((short) 16);
|
||||
escher.setDy1((short) 17);
|
||||
escher.setDy2((short) 18);
|
||||
|
||||
HSSFClientAnchor anchor = new HSSFClientAnchor(escher);
|
||||
assertEquals(anchor.getCol1(), 11);
|
||||
assertEquals(escher.getCol1(), 11);
|
||||
assertEquals(anchor.getCol2(), 12);
|
||||
assertEquals(escher.getCol2(), 12);
|
||||
assertEquals(anchor.getRow1(), 13);
|
||||
assertEquals(escher.getRow1(), 13);
|
||||
assertEquals(anchor.getRow2(), 14);
|
||||
assertEquals(escher.getRow2(), 14);
|
||||
assertEquals(anchor.getDx1(), 15);
|
||||
assertEquals(escher.getDx1(), 15);
|
||||
assertEquals(anchor.getDx2(), 16);
|
||||
assertEquals(escher.getDx2(), 16);
|
||||
assertEquals(anchor.getDy1(), 17);
|
||||
assertEquals(escher.getDy1(), 17);
|
||||
assertEquals(anchor.getDy2(), 18);
|
||||
assertEquals(escher.getDy2(), 18);
|
||||
}
|
||||
|
||||
public void testClientAnchorFromScratch(){
|
||||
HSSFClientAnchor anchor = new HSSFClientAnchor();
|
||||
EscherClientAnchorRecord escher = (EscherClientAnchorRecord) HSSFTestHelper.getEscherAnchor(anchor);
|
||||
anchor.setAnchor((short)11, 12, 13, 14, (short)15, 16, 17, 18);
|
||||
|
||||
assertEquals(anchor.getCol1(), 11);
|
||||
assertEquals(escher.getCol1(), 11);
|
||||
assertEquals(anchor.getCol2(), 15);
|
||||
assertEquals(escher.getCol2(), 15);
|
||||
assertEquals(anchor.getRow1(), 12);
|
||||
assertEquals(escher.getRow1(), 12);
|
||||
assertEquals(anchor.getRow2(), 16);
|
||||
assertEquals(escher.getRow2(), 16);
|
||||
assertEquals(anchor.getDx1(), 13);
|
||||
assertEquals(escher.getDx1(), 13);
|
||||
assertEquals(anchor.getDx2(), 17);
|
||||
assertEquals(escher.getDx2(), 17);
|
||||
assertEquals(anchor.getDy1(), 14);
|
||||
assertEquals(escher.getDy1(), 14);
|
||||
assertEquals(anchor.getDy2(), 18);
|
||||
assertEquals(escher.getDy2(), 18);
|
||||
|
||||
anchor.setCol1(111);
|
||||
assertEquals(anchor.getCol1(), 111);
|
||||
assertEquals(escher.getCol1(), 111);
|
||||
anchor.setCol2(112);
|
||||
assertEquals(anchor.getCol2(), 112);
|
||||
assertEquals(escher.getCol2(), 112);
|
||||
anchor.setRow1(113);
|
||||
assertEquals(anchor.getRow1(), 113);
|
||||
assertEquals(escher.getRow1(), 113);
|
||||
anchor.setRow2(114);
|
||||
assertEquals(anchor.getRow2(), 114);
|
||||
assertEquals(escher.getRow2(), 114);
|
||||
anchor.setDx1(115);
|
||||
assertEquals(anchor.getDx1(), 115);
|
||||
assertEquals(escher.getDx1(), 115);
|
||||
anchor.setDx2(116);
|
||||
assertEquals(anchor.getDx2(), 116);
|
||||
assertEquals(escher.getDx2(), 116);
|
||||
anchor.setDy1(117);
|
||||
assertEquals(anchor.getDy1(), 117);
|
||||
assertEquals(escher.getDy1(), 117);
|
||||
anchor.setDy2(118);
|
||||
assertEquals(anchor.getDy2(), 118);
|
||||
assertEquals(escher.getDy2(), 118);
|
||||
}
|
||||
|
||||
public void testChildAnchorFromEscher(){
|
||||
EscherChildAnchorRecord escher = new EscherChildAnchorRecord();
|
||||
escher.setDx1((short) 15);
|
||||
escher.setDx2((short) 16);
|
||||
escher.setDy1((short) 17);
|
||||
escher.setDy2((short) 18);
|
||||
|
||||
HSSFChildAnchor anchor = new HSSFChildAnchor(escher);
|
||||
assertEquals(anchor.getDx1(), 15);
|
||||
assertEquals(escher.getDx1(), 15);
|
||||
assertEquals(anchor.getDx2(), 16);
|
||||
assertEquals(escher.getDx2(), 16);
|
||||
assertEquals(anchor.getDy1(), 17);
|
||||
assertEquals(escher.getDy1(), 17);
|
||||
assertEquals(anchor.getDy2(), 18);
|
||||
assertEquals(escher.getDy2(), 18);
|
||||
}
|
||||
|
||||
public void testChildAnchorFromScratch(){
|
||||
HSSFChildAnchor anchor = new HSSFChildAnchor();
|
||||
EscherChildAnchorRecord escher = (EscherChildAnchorRecord) HSSFTestHelper.getEscherAnchor(anchor);
|
||||
anchor.setAnchor(11, 12, 13, 14);
|
||||
|
||||
assertEquals(anchor.getDx1(), 11);
|
||||
assertEquals(escher.getDx1(), 11);
|
||||
assertEquals(anchor.getDx2(), 13);
|
||||
assertEquals(escher.getDx2(), 13);
|
||||
assertEquals(anchor.getDy1(), 12);
|
||||
assertEquals(escher.getDy1(), 12);
|
||||
assertEquals(anchor.getDy2(), 14);
|
||||
assertEquals(escher.getDy2(), 14);
|
||||
|
||||
anchor.setDx1(115);
|
||||
assertEquals(anchor.getDx1(), 115);
|
||||
assertEquals(escher.getDx1(), 115);
|
||||
anchor.setDx2(116);
|
||||
assertEquals(anchor.getDx2(), 116);
|
||||
assertEquals(escher.getDx2(), 116);
|
||||
anchor.setDy1(117);
|
||||
assertEquals(anchor.getDy1(), 117);
|
||||
assertEquals(escher.getDy1(), 117);
|
||||
anchor.setDy2(118);
|
||||
assertEquals(anchor.getDy2(), 118);
|
||||
assertEquals(escher.getDy2(), 118);
|
||||
}
|
||||
|
||||
public void testEqualsToSelf(){
|
||||
HSSFClientAnchor clientAnchor = new HSSFClientAnchor(0, 1, 2, 3, (short)4, 5, (short)6, 7);
|
||||
assertEquals(clientAnchor, clientAnchor);
|
||||
|
||||
HSSFChildAnchor childAnchor = new HSSFChildAnchor(0, 1, 2, 3);
|
||||
assertEquals(childAnchor, childAnchor);
|
||||
}
|
||||
|
||||
public void testPassIncompatibleTypeIsFalse(){
|
||||
HSSFClientAnchor clientAnchor = new HSSFClientAnchor(0, 1, 2, 3, (short)4, 5, (short)6, 7);
|
||||
assertNotSame(clientAnchor, "wrongType");
|
||||
|
||||
HSSFChildAnchor childAnchor = new HSSFChildAnchor(0, 1, 2, 3);
|
||||
assertNotSame(childAnchor, "wrongType");
|
||||
}
|
||||
|
||||
public void testNullReferenceIsFalse() {
|
||||
HSSFClientAnchor clientAnchor = new HSSFClientAnchor(0, 1, 2, 3, (short)4, 5, (short)6, 7);
|
||||
assertFalse("Passing null to equals should return false", clientAnchor.equals(null));
|
||||
|
||||
HSSFChildAnchor childAnchor = new HSSFChildAnchor(0, 1, 2, 3);
|
||||
assertFalse("Passing null to equals should return false", childAnchor.equals(null));
|
||||
}
|
||||
|
||||
public void testEqualsIsReflexiveIsSymmetric() {
|
||||
HSSFClientAnchor clientAnchor1 = new HSSFClientAnchor(0, 1, 2, 3, (short)4, 5, (short)6, 7);
|
||||
HSSFClientAnchor clientAnchor2 = new HSSFClientAnchor(0, 1, 2, 3, (short)4, 5, (short)6, 7);
|
||||
|
||||
assertTrue(clientAnchor1.equals(clientAnchor2));
|
||||
assertTrue(clientAnchor1.equals(clientAnchor2));
|
||||
|
||||
HSSFChildAnchor childAnchor1 = new HSSFChildAnchor(0, 1, 2, 3);
|
||||
HSSFChildAnchor childAnchor2 = new HSSFChildAnchor(0, 1, 2, 3);
|
||||
|
||||
assertTrue(childAnchor1.equals(childAnchor2));
|
||||
assertTrue(childAnchor2.equals(childAnchor1));
|
||||
}
|
||||
|
||||
public void testEqualsValues(){
|
||||
HSSFClientAnchor clientAnchor1 = new HSSFClientAnchor(0, 1, 2, 3, (short)4, 5, (short)6, 7);
|
||||
HSSFClientAnchor clientAnchor2 = new HSSFClientAnchor(0, 1, 2, 3, (short)4, 5, (short)6, 7);
|
||||
assertEquals(clientAnchor1, clientAnchor2);
|
||||
|
||||
clientAnchor2.setDx1(10);
|
||||
assertNotSame(clientAnchor1, clientAnchor2);
|
||||
clientAnchor2.setDx1(0);
|
||||
assertEquals(clientAnchor1, clientAnchor2);
|
||||
|
||||
clientAnchor2.setDy1(10);
|
||||
assertNotSame(clientAnchor1, clientAnchor2);
|
||||
clientAnchor2.setDy1(1);
|
||||
assertEquals(clientAnchor1, clientAnchor2);
|
||||
|
||||
clientAnchor2.setDx2(10);
|
||||
assertNotSame(clientAnchor1, clientAnchor2);
|
||||
clientAnchor2.setDx2(2);
|
||||
assertEquals(clientAnchor1, clientAnchor2);
|
||||
|
||||
clientAnchor2.setDy2(10);
|
||||
assertNotSame(clientAnchor1, clientAnchor2);
|
||||
clientAnchor2.setDy2(3);
|
||||
assertEquals(clientAnchor1, clientAnchor2);
|
||||
|
||||
clientAnchor2.setCol1(10);
|
||||
assertNotSame(clientAnchor1, clientAnchor2);
|
||||
clientAnchor2.setCol1(4);
|
||||
assertEquals(clientAnchor1, clientAnchor2);
|
||||
|
||||
clientAnchor2.setRow1(10);
|
||||
assertNotSame(clientAnchor1, clientAnchor2);
|
||||
clientAnchor2.setRow1(5);
|
||||
assertEquals(clientAnchor1, clientAnchor2);
|
||||
|
||||
clientAnchor2.setCol2(10);
|
||||
assertNotSame(clientAnchor1, clientAnchor2);
|
||||
clientAnchor2.setCol2(6);
|
||||
assertEquals(clientAnchor1, clientAnchor2);
|
||||
|
||||
clientAnchor2.setRow2(10);
|
||||
assertNotSame(clientAnchor1, clientAnchor2);
|
||||
clientAnchor2.setRow2(7);
|
||||
assertEquals(clientAnchor1, clientAnchor2);
|
||||
|
||||
clientAnchor2.setAnchorType(3);
|
||||
assertNotSame(clientAnchor1, clientAnchor2);
|
||||
clientAnchor2.setAnchorType(0);
|
||||
assertEquals(clientAnchor1, clientAnchor2);
|
||||
|
||||
HSSFChildAnchor childAnchor1 = new HSSFChildAnchor(0, 1, 2, 3);
|
||||
HSSFChildAnchor childAnchor2 = new HSSFChildAnchor(0, 1, 2, 3);
|
||||
|
||||
childAnchor1.setDx1(10);
|
||||
assertNotSame(childAnchor1, childAnchor2);
|
||||
childAnchor1.setDx1(0);
|
||||
assertEquals(childAnchor1, childAnchor2);
|
||||
|
||||
childAnchor2.setDy1(10);
|
||||
assertNotSame(childAnchor1, childAnchor2);
|
||||
childAnchor2.setDy1(1);
|
||||
assertEquals(childAnchor1, childAnchor2);
|
||||
|
||||
childAnchor2.setDx2(10);
|
||||
assertNotSame(childAnchor1, childAnchor2);
|
||||
childAnchor2.setDx2(2);
|
||||
assertEquals(childAnchor1, childAnchor2);
|
||||
|
||||
childAnchor2.setDy2(10);
|
||||
assertNotSame(childAnchor1, childAnchor2);
|
||||
childAnchor2.setDy2(3);
|
||||
assertEquals(childAnchor1, childAnchor2);
|
||||
}
|
||||
|
||||
public void testFlipped(){
|
||||
HSSFChildAnchor child = new HSSFChildAnchor(2,2,1,1);
|
||||
assertEquals(child.isHorizontallyFlipped(), true);
|
||||
assertEquals(child.isVerticallyFlipped(), true);
|
||||
assertEquals(child.getDx1(), 1);
|
||||
assertEquals(child.getDx2(), 2);
|
||||
assertEquals(child.getDy1(), 1);
|
||||
assertEquals(child.getDy2(), 2);
|
||||
|
||||
child = new HSSFChildAnchor(3,3,4,4);
|
||||
assertEquals(child.isHorizontallyFlipped(), false);
|
||||
assertEquals(child.isVerticallyFlipped(), false);
|
||||
assertEquals(child.getDx1(), 3);
|
||||
assertEquals(child.getDx2(), 4);
|
||||
assertEquals(child.getDy1(), 3);
|
||||
assertEquals(child.getDy2(), 4);
|
||||
|
||||
HSSFClientAnchor client = new HSSFClientAnchor(1,1,1,1, (short)4,4,(short)3,3);
|
||||
assertEquals(client.isVerticallyFlipped(), true);
|
||||
assertEquals(client.isHorizontallyFlipped(), true);
|
||||
assertEquals(client.getCol1(), 3);
|
||||
assertEquals(client.getCol2(), 4);
|
||||
assertEquals(client.getRow1(), 3);
|
||||
assertEquals(client.getRow2(), 4);
|
||||
|
||||
client = new HSSFClientAnchor(1,1,1,1, (short)5,5,(short)6,6);
|
||||
assertEquals(client.isVerticallyFlipped(), false);
|
||||
assertEquals(client.isHorizontallyFlipped(), false);
|
||||
assertEquals(client.getCol1(), 5);
|
||||
assertEquals(client.getCol2(), 6);
|
||||
assertEquals(client.getRow1(), 5);
|
||||
assertEquals(client.getRow2(), 6);
|
||||
}
|
||||
}
|
@ -49,17 +49,12 @@ public final class TestDrawingRecord extends TestCase {
|
||||
out.write(cn.serialize());
|
||||
|
||||
List<Record> rec = RecordFactory.createRecords(new ByteArrayInputStream(out.toByteArray()));
|
||||
assertEquals(1, rec.size());
|
||||
assertEquals(2, rec.size());
|
||||
assertTrue(rec.get(0) instanceof DrawingRecord);
|
||||
assertTrue(rec.get(1) instanceof ContinueRecord);
|
||||
|
||||
//DrawingRecord.getData() should return concatenated data1 and data2
|
||||
byte[] tmp = new byte[data1.length + data2.length];
|
||||
System.arraycopy(data1, 0, tmp, 0, data1.length);
|
||||
System.arraycopy(data2, 0, tmp, data1.length, data2.length);
|
||||
|
||||
DrawingRecord dg2 = (DrawingRecord)rec.get(0);
|
||||
assertEquals(data1.length + data2.length, dg2.getData().length);
|
||||
assertTrue(Arrays.equals(tmp, dg2.getData()));
|
||||
assertTrue(Arrays.equals(data1, ((DrawingRecord)rec.get(0)).getData()));
|
||||
assertTrue(Arrays.equals(data2, ((ContinueRecord)rec.get(1)).getData()));
|
||||
|
||||
}
|
||||
|
||||
|
@ -16,8 +16,18 @@
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.hssf.usermodel;
|
||||
import org.apache.poi.ddf.*;
|
||||
import org.apache.poi.hssf.model.DrawingManager2;
|
||||
import org.apache.poi.hssf.model.InternalSheet;
|
||||
import org.apache.poi.hssf.model.InternalWorkbook;
|
||||
import org.apache.poi.hssf.record.EscherAggregate;
|
||||
import org.apache.poi.hssf.record.ObjRecord;
|
||||
import org.apache.poi.hssf.record.TextObjectRecord;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Helper class for HSSF tests that aren't within the
|
||||
@ -25,6 +35,33 @@ import org.apache.poi.hssf.model.InternalWorkbook;
|
||||
* UserModel things.
|
||||
*/
|
||||
public class HSSFTestHelper {
|
||||
|
||||
public static class MockDrawingManager extends DrawingManager2 {
|
||||
|
||||
public MockDrawingManager (){
|
||||
super(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int allocateShapeId(short drawingGroupId) {
|
||||
return 1025; //Mock value
|
||||
}
|
||||
|
||||
@Override
|
||||
public int allocateShapeId(short drawingGroupId, EscherDgRecord dg) {
|
||||
return 1025;
|
||||
}
|
||||
|
||||
public EscherDgRecord createDgRecord()
|
||||
{
|
||||
EscherDgRecord dg = new EscherDgRecord();
|
||||
dg.setRecordId( EscherDgRecord.RECORD_ID );
|
||||
dg.setOptions( (short) (16) );
|
||||
dg.setNumShapes( 1 );
|
||||
dg.setLastMSOSPID( 1024 );
|
||||
return dg;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Lets non UserModel tests at the low level Workbook
|
||||
*/
|
||||
@ -34,4 +71,55 @@ public class HSSFTestHelper {
|
||||
public static InternalSheet getSheetForTest(HSSFSheet sheet) {
|
||||
return sheet.getSheet();
|
||||
}
|
||||
|
||||
public static HSSFPatriarch createTestPatriarch(HSSFSheet sheet, EscherAggregate agg){
|
||||
return new HSSFPatriarch(sheet, agg);
|
||||
}
|
||||
|
||||
public static EscherAggregate getEscherAggregate(HSSFPatriarch patriarch){
|
||||
return patriarch._getBoundAggregate();
|
||||
}
|
||||
|
||||
public static int allocateNewShapeId(HSSFPatriarch patriarch){
|
||||
return patriarch.newShapeId();
|
||||
}
|
||||
|
||||
public static EscherOptRecord getOptRecord(HSSFShape shape){
|
||||
return shape.getOptRecord();
|
||||
}
|
||||
|
||||
public static void convertHSSFGroup(HSSFShapeGroup shape, EscherContainerRecord escherParent, Map shapeToObj){
|
||||
Class clazz = EscherAggregate.class;
|
||||
try {
|
||||
Method method = clazz.getDeclaredMethod("convertGroup", HSSFShapeGroup.class, EscherContainerRecord.class, Map.class);
|
||||
method.setAccessible(true);
|
||||
method.invoke(new EscherAggregate(new MockDrawingManager()), shape, escherParent, shapeToObj);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void setShapeId(HSSFShape shape, int id){
|
||||
shape.setShapeId(id);
|
||||
}
|
||||
|
||||
public static EscherContainerRecord getEscherContainer(HSSFShape shape){
|
||||
return shape.getEscherContainer();
|
||||
}
|
||||
|
||||
public static TextObjectRecord getTextObjRecord(HSSFSimpleShape shape){
|
||||
return shape.getTextObjectRecord();
|
||||
}
|
||||
|
||||
public static ObjRecord getObjRecord(HSSFShape shape){
|
||||
return shape.getObjRecord();
|
||||
}
|
||||
|
||||
public static EscherRecord getEscherAnchor(HSSFAnchor anchor){
|
||||
return anchor.getEscherAnchor();
|
||||
}
|
||||
}
|
||||
|
@ -24,9 +24,12 @@ import org.apache.poi.hssf.HSSFITestDataProvider;
|
||||
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||
import org.apache.poi.hssf.OldExcelFormatException;
|
||||
import org.apache.poi.hssf.extractor.ExcelExtractor;
|
||||
import org.apache.poi.hssf.model.InternalSheet;
|
||||
import org.apache.poi.hssf.model.InternalWorkbook;
|
||||
import org.apache.poi.hssf.record.*;
|
||||
import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate;
|
||||
import org.apache.poi.hssf.record.aggregates.PageSettingsBlock;
|
||||
import org.apache.poi.hssf.record.aggregates.RecordAggregate;
|
||||
import org.apache.poi.hssf.record.common.UnicodeString;
|
||||
import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
|
||||
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||
@ -2238,4 +2241,31 @@ if(1==2) {
|
||||
// make sure we are still readable
|
||||
writeOutAndReadBack(workbook);
|
||||
}
|
||||
|
||||
public void test51675(){
|
||||
final List<Short> list = new ArrayList<Short>();
|
||||
HSSFWorkbook workbook = openSample("51675.xls");
|
||||
HSSFSheet sh = workbook.getSheetAt(0);
|
||||
InternalSheet ish = HSSFTestHelper.getSheetForTest(sh);
|
||||
PageSettingsBlock psb = (PageSettingsBlock) ish.getRecords().get(13);
|
||||
psb.visitContainedRecords(new RecordAggregate.RecordVisitor() {
|
||||
public void visitRecord(Record r) {
|
||||
list.add(r.getSid());
|
||||
}
|
||||
});
|
||||
assertTrue(list.get(list.size()-1).intValue() == UnknownRecord.BITMAP_00E9);
|
||||
assertTrue(list.get(list.size()-2).intValue() == UnknownRecord.HEADER_FOOTER_089C);
|
||||
}
|
||||
|
||||
public void test52272(){
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sh = wb.createSheet();
|
||||
HSSFPatriarch p = sh.createDrawingPatriarch();
|
||||
|
||||
HSSFSimpleShape s = p.createSimpleShape(new HSSFClientAnchor());
|
||||
s.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
|
||||
|
||||
HSSFSheet sh2 = wb.cloneSheet(0);
|
||||
assertNotNull(sh2.getDrawingPatriarch());
|
||||
}
|
||||
}
|
||||
|
@ -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()));
|
||||
}
|
||||
}
|
||||
|
268
src/testcases/org/apache/poi/hssf/usermodel/TestComment.java
Normal file
268
src/testcases/org/apache/poi/hssf/usermodel/TestComment.java
Normal file
@ -0,0 +1,268 @@
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.hssf.usermodel;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.apache.poi.ddf.EscherSpRecord;
|
||||
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||
import org.apache.poi.hssf.model.CommentShape;
|
||||
import org.apache.poi.hssf.model.HSSFTestModelHelper;
|
||||
import org.apache.poi.hssf.record.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author Evgeniy Berlog
|
||||
* @date 26.06.12
|
||||
*/
|
||||
public class TestComment extends TestCase {
|
||||
|
||||
public void testResultEqualsToAbstractShape() {
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sh = wb.createSheet();
|
||||
HSSFPatriarch patriarch = sh.createDrawingPatriarch();
|
||||
|
||||
HSSFComment comment = patriarch.createCellComment(new HSSFClientAnchor());
|
||||
HSSFRow row = sh.createRow(0);
|
||||
HSSFCell cell = row.createCell(0);
|
||||
cell.setCellComment(comment);
|
||||
|
||||
CommentShape commentShape = HSSFTestModelHelper.createCommentShape(1025, comment);
|
||||
|
||||
assertEquals(comment.getEscherContainer().getChildRecords().size(), 5);
|
||||
assertEquals(commentShape.getSpContainer().getChildRecords().size(), 5);
|
||||
|
||||
//sp record
|
||||
byte[] expected = commentShape.getSpContainer().getChild(0).serialize();
|
||||
byte[] actual = comment.getEscherContainer().getChild(0).serialize();
|
||||
|
||||
assertEquals(expected.length, actual.length);
|
||||
assertTrue(Arrays.equals(expected, actual));
|
||||
|
||||
expected = commentShape.getSpContainer().getChild(2).serialize();
|
||||
actual = comment.getEscherContainer().getChild(2).serialize();
|
||||
|
||||
assertEquals(expected.length, actual.length);
|
||||
assertTrue(Arrays.equals(expected, actual));
|
||||
|
||||
expected = commentShape.getSpContainer().getChild(3).serialize();
|
||||
actual = comment.getEscherContainer().getChild(3).serialize();
|
||||
|
||||
assertEquals(expected.length, actual.length);
|
||||
assertTrue(Arrays.equals(expected, actual));
|
||||
|
||||
expected = commentShape.getSpContainer().getChild(4).serialize();
|
||||
actual = comment.getEscherContainer().getChild(4).serialize();
|
||||
|
||||
assertEquals(expected.length, actual.length);
|
||||
assertTrue(Arrays.equals(expected, actual));
|
||||
|
||||
ObjRecord obj = comment.getObjRecord();
|
||||
ObjRecord objShape = commentShape.getObjRecord();
|
||||
/**shapeId = 1025 % 1024**/
|
||||
((CommonObjectDataSubRecord)objShape.getSubRecords().get(0)).setObjectId(1);
|
||||
|
||||
expected = obj.serialize();
|
||||
actual = objShape.serialize();
|
||||
|
||||
TextObjectRecord tor = comment.getTextObjectRecord();
|
||||
TextObjectRecord torShape = commentShape.getTextObjectRecord();
|
||||
|
||||
expected = tor.serialize();
|
||||
actual = torShape.serialize();
|
||||
|
||||
assertEquals(expected.length, actual.length);
|
||||
assertTrue(Arrays.equals(expected, actual));
|
||||
|
||||
NoteRecord note = comment.getNoteRecord();
|
||||
NoteRecord noteShape = commentShape.getNoteRecord();
|
||||
noteShape.setShapeId(1);
|
||||
|
||||
expected = note.serialize();
|
||||
actual = noteShape.serialize();
|
||||
|
||||
assertEquals(expected.length, actual.length);
|
||||
assertTrue(Arrays.equals(expected, actual));
|
||||
}
|
||||
|
||||
public void testAddToExistingFile() {
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sh = wb.createSheet();
|
||||
HSSFPatriarch patriarch = sh.createDrawingPatriarch();
|
||||
int idx = wb.addPicture(new byte[]{1,2,3}, HSSFWorkbook.PICTURE_TYPE_PNG);
|
||||
|
||||
HSSFComment comment = patriarch.createCellComment(new HSSFClientAnchor());
|
||||
comment.setString(new HSSFRichTextString("comment1"));
|
||||
comment = patriarch.createCellComment(new HSSFClientAnchor(0,0,100,100,(short)0,0,(short)10,10));
|
||||
comment.setString(new HSSFRichTextString("comment2"));
|
||||
comment.setBackgroundImage(idx);
|
||||
assertEquals(comment.getBackgroundImageId(), idx);
|
||||
|
||||
assertEquals(patriarch.getChildren().size(), 2);
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sh = wb.getSheetAt(0);
|
||||
patriarch = sh.getDrawingPatriarch();
|
||||
|
||||
comment = (HSSFComment) patriarch.getChildren().get(1);
|
||||
assertEquals(comment.getBackgroundImageId(), idx);
|
||||
comment.resetBackgroundImage();
|
||||
assertEquals(comment.getBackgroundImageId(), 0);
|
||||
|
||||
assertEquals(patriarch.getChildren().size(), 2);
|
||||
comment = patriarch.createCellComment(new HSSFClientAnchor());
|
||||
comment.setString(new HSSFRichTextString("comment3"));
|
||||
|
||||
assertEquals(patriarch.getChildren().size(), 3);
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sh = wb.getSheetAt(0);
|
||||
patriarch = sh.getDrawingPatriarch();
|
||||
comment = (HSSFComment) patriarch.getChildren().get(1);
|
||||
assertEquals(comment.getBackgroundImageId(), 0);
|
||||
assertEquals(patriarch.getChildren().size(), 3);
|
||||
assertEquals(((HSSFComment) patriarch.getChildren().get(0)).getString().getString(), "comment1");
|
||||
assertEquals(((HSSFComment) patriarch.getChildren().get(1)).getString().getString(), "comment2");
|
||||
assertEquals(((HSSFComment) patriarch.getChildren().get(2)).getString().getString(), "comment3");
|
||||
}
|
||||
|
||||
public void testSetGetProperties() throws IOException {
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sh = wb.createSheet();
|
||||
HSSFPatriarch patriarch = sh.createDrawingPatriarch();
|
||||
|
||||
HSSFComment comment = patriarch.createCellComment(new HSSFClientAnchor());
|
||||
comment.setString(new HSSFRichTextString("comment1"));
|
||||
assertEquals(comment.getString().getString(), "comment1");
|
||||
|
||||
comment.setAuthor("poi");
|
||||
assertEquals(comment.getAuthor(), "poi");
|
||||
|
||||
comment.setColumn(3);
|
||||
assertEquals(comment.getColumn(), 3);
|
||||
|
||||
comment.setRow(4);
|
||||
assertEquals(comment.getRow(), 4);
|
||||
|
||||
comment.setVisible(false);
|
||||
assertEquals(comment.isVisible(), false);
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sh = wb.getSheetAt(0);
|
||||
patriarch = sh.getDrawingPatriarch();
|
||||
|
||||
comment = (HSSFComment) patriarch.getChildren().get(0);
|
||||
|
||||
assertEquals(comment.getString().getString(), "comment1");
|
||||
assertEquals("poi", comment.getAuthor());
|
||||
assertEquals(comment.getColumn(), 3);
|
||||
assertEquals(comment.getRow(), 4);
|
||||
assertEquals(comment.isVisible(), false);
|
||||
|
||||
comment.setString(new HSSFRichTextString("comment12"));
|
||||
comment.setAuthor("poi2");
|
||||
comment.setColumn(32);
|
||||
comment.setRow(42);
|
||||
comment.setVisible(true);
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sh = wb.getSheetAt(0);
|
||||
patriarch = sh.getDrawingPatriarch();
|
||||
comment = (HSSFComment) patriarch.getChildren().get(0);
|
||||
|
||||
assertEquals(comment.getString().getString(), "comment12");
|
||||
assertEquals("poi2", comment.getAuthor());
|
||||
assertEquals(comment.getColumn(), 32);
|
||||
assertEquals(comment.getRow(), 42);
|
||||
assertEquals(comment.isVisible(), true);
|
||||
}
|
||||
|
||||
public void testExistingFileWithComment(){
|
||||
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls");
|
||||
HSSFSheet sheet = wb.getSheet("comments");
|
||||
HSSFPatriarch drawing = sheet.getDrawingPatriarch();
|
||||
assertEquals(1, drawing.getChildren().size());
|
||||
HSSFComment comment = (HSSFComment) drawing.getChildren().get(0);
|
||||
assertEquals(comment.getAuthor(), "evgeniy");
|
||||
assertEquals(comment.getString().getString(), "evgeniy:\npoi test");
|
||||
assertEquals(comment.getColumn(), 1);
|
||||
assertEquals(comment.getRow(), 2);
|
||||
}
|
||||
|
||||
public void testFindComments(){
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sh = wb.createSheet();
|
||||
HSSFPatriarch patriarch = sh.createDrawingPatriarch();
|
||||
|
||||
HSSFComment comment = patriarch.createCellComment(new HSSFClientAnchor());
|
||||
HSSFRow row = sh.createRow(5);
|
||||
HSSFCell cell = row.createCell(4);
|
||||
cell.setCellComment(comment);
|
||||
|
||||
HSSFTestModelHelper.createCommentShape(0, comment);
|
||||
|
||||
assertNotNull(sh.findCellComment(5, 4));
|
||||
assertNull(sh.findCellComment(5, 5));
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sh = wb.getSheetAt(0);
|
||||
|
||||
assertNotNull(sh.findCellComment(5, 4));
|
||||
assertNull(sh.findCellComment(5, 5));
|
||||
}
|
||||
|
||||
public void testInitState(){
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sh = wb.createSheet();
|
||||
HSSFPatriarch patriarch = sh.createDrawingPatriarch();
|
||||
|
||||
EscherAggregate agg = HSSFTestHelper.getEscherAggregate(patriarch);
|
||||
assertEquals(agg.getTailRecords().size(), 0);
|
||||
|
||||
HSSFComment comment = patriarch.createCellComment(new HSSFClientAnchor());
|
||||
assertEquals(agg.getTailRecords().size(), 1);
|
||||
|
||||
HSSFSimpleShape shape = patriarch.createSimpleShape(new HSSFClientAnchor());
|
||||
|
||||
assertEquals(comment.getOptRecord().getEscherProperties().size(), 10);
|
||||
}
|
||||
|
||||
public void testShapeId(){
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sh = wb.createSheet();
|
||||
HSSFPatriarch patriarch = sh.createDrawingPatriarch();
|
||||
|
||||
HSSFComment comment = patriarch.createCellComment(new HSSFClientAnchor());
|
||||
|
||||
comment.setShapeId(2024);
|
||||
/**
|
||||
* SpRecord.id == shapeId
|
||||
* 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(), 1000);
|
||||
EscherSpRecord spRecord = (EscherSpRecord) comment.getEscherContainer().getChild(0);
|
||||
assertEquals(spRecord.getShapeId(), 2024);
|
||||
assertEquals(comment.getShapeId(), 2024);
|
||||
assertEquals(comment.getNoteRecord().getShapeId(), 1000);
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.hssf.usermodel;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Evgeniy Berlog
|
||||
* @date 13.07.12
|
||||
*/
|
||||
public class TestEmbeddedObjects extends TestCase{
|
||||
|
||||
public void testReadExistingObject() throws IOException {
|
||||
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls");
|
||||
List<HSSFObjectData> list = wb.getAllEmbeddedObjects();
|
||||
assertEquals(list.size(), 1);
|
||||
HSSFObjectData obj = list.get(0);
|
||||
assertNotNull(obj.getObjectData());
|
||||
assertNotNull(obj.getDirectory());
|
||||
assertNotNull(obj.getOLE2ClassName());
|
||||
}
|
||||
}
|
@ -32,7 +32,7 @@ public final class TestHSSFComment extends BaseTestCellComment {
|
||||
}
|
||||
|
||||
public void testDefaultShapeType() {
|
||||
HSSFComment comment = new HSSFComment((HSSFShape)null, (HSSFAnchor)null);
|
||||
HSSFComment comment = new HSSFComment((HSSFShape)null, new HSSFClientAnchor());
|
||||
assertEquals(HSSFSimpleShape.OBJECT_TYPE_COMMENT, comment.getShapeType());
|
||||
}
|
||||
|
||||
|
@ -17,8 +17,10 @@
|
||||
|
||||
package org.apache.poi.hssf.usermodel;
|
||||
|
||||
import org.apache.poi.ddf.EscherBSERecord;
|
||||
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||
import org.apache.poi.hssf.HSSFITestDataProvider;
|
||||
import org.apache.poi.hssf.model.InternalSheet;
|
||||
import org.apache.poi.ss.usermodel.BaseTestPicture;
|
||||
import org.apache.poi.ss.usermodel.PictureData;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
@ -149,4 +151,63 @@ public final class TestHSSFPicture extends BaseTestPicture {
|
||||
assertTrue(Arrays.equals(data4, ((HSSFPicture)dr.getChildren().get(3)).getPictureData().getData()));
|
||||
}
|
||||
|
||||
public void testBSEPictureRef(){
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
|
||||
HSSFSheet sh = wb.createSheet("Pictures");
|
||||
HSSFPatriarch dr = sh.createDrawingPatriarch();
|
||||
HSSFClientAnchor anchor = new HSSFClientAnchor();
|
||||
|
||||
InternalSheet ish = HSSFTestHelper.getSheetForTest(sh);
|
||||
|
||||
//register a picture
|
||||
byte[] data1 = new byte[]{1, 2, 3};
|
||||
int idx1 = wb.addPicture(data1, Workbook.PICTURE_TYPE_JPEG);
|
||||
assertEquals(1, idx1);
|
||||
HSSFPicture p1 = dr.createPicture(anchor, idx1);
|
||||
|
||||
EscherBSERecord bse = wb.getWorkbook().getBSERecord(idx1);
|
||||
|
||||
assertEquals(bse.getRef(), 1);
|
||||
dr.createPicture(new HSSFClientAnchor(), idx1);
|
||||
assertEquals(bse.getRef(), 2);
|
||||
|
||||
HSSFShapeGroup gr = dr.createGroup(new HSSFClientAnchor());
|
||||
gr.createPicture(new HSSFChildAnchor(), idx1);
|
||||
assertEquals(bse.getRef(), 3);
|
||||
}
|
||||
|
||||
public void testReadExistingImage(){
|
||||
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls");
|
||||
HSSFSheet sheet = wb.getSheet("picture");
|
||||
HSSFPatriarch drawing = sheet.getDrawingPatriarch();
|
||||
assertEquals(1, drawing.getChildren().size());
|
||||
|
||||
HSSFPicture picture = (HSSFPicture) drawing.getChildren().get(0);
|
||||
assertEquals(picture.getFileName(), "test");
|
||||
}
|
||||
|
||||
public void testSetGetProperties(){
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
|
||||
HSSFSheet sh = wb.createSheet("Pictures");
|
||||
HSSFPatriarch dr = sh.createDrawingPatriarch();
|
||||
HSSFClientAnchor anchor = new HSSFClientAnchor();
|
||||
|
||||
//register a picture
|
||||
byte[] data1 = new byte[]{1, 2, 3};
|
||||
int idx1 = wb.addPicture(data1, Workbook.PICTURE_TYPE_JPEG);
|
||||
HSSFPicture p1 = dr.createPicture(anchor, idx1);
|
||||
|
||||
assertEquals(p1.getFileName(), "");
|
||||
p1.setFileName("aaa");
|
||||
assertEquals(p1.getFileName(), "aaa");
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sh = wb.getSheet("Pictures");
|
||||
dr = sh.getDrawingPatriarch();
|
||||
|
||||
p1 = (HSSFPicture) dr.getChildren().get(0);
|
||||
assertEquals(p1.getFileName(), "aaa");
|
||||
}
|
||||
}
|
||||
|
@ -824,8 +824,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);
|
||||
|
@ -0,0 +1,57 @@
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.hssf.usermodel;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.apache.poi.ddf.EscherDgRecord;
|
||||
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||
import org.apache.poi.hssf.record.EscherAggregate;
|
||||
|
||||
/**
|
||||
* @author Evgeniy Berlog
|
||||
* @date 01.08.12
|
||||
*/
|
||||
public class TestPatriarch extends TestCase {
|
||||
|
||||
public void testGetPatriarch(){
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sh = wb.createSheet();
|
||||
assertNull(sh.getDrawingPatriarch());
|
||||
|
||||
HSSFPatriarch patriarch = sh.createDrawingPatriarch();
|
||||
assertNotNull(patriarch);
|
||||
patriarch.createSimpleShape(new HSSFClientAnchor());
|
||||
patriarch.createSimpleShape(new HSSFClientAnchor());
|
||||
|
||||
assertSame(patriarch, sh.getDrawingPatriarch());
|
||||
|
||||
EscherAggregate agg = patriarch._getBoundAggregate();
|
||||
|
||||
EscherDgRecord dg = agg.getEscherContainer().getChildById(EscherDgRecord.RECORD_ID);
|
||||
int lastId = dg.getLastMSOSPID();
|
||||
|
||||
assertSame(patriarch, sh.createDrawingPatriarch());
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sh = wb.getSheetAt(0);
|
||||
patriarch = sh.createDrawingPatriarch();
|
||||
dg = patriarch._getBoundAggregate().getEscherContainer().getChildById(EscherDgRecord.RECORD_ID);
|
||||
|
||||
assertEquals(lastId, dg.getLastMSOSPID());
|
||||
}
|
||||
}
|
248
src/testcases/org/apache/poi/hssf/usermodel/TestPolygon.java
Normal file
248
src/testcases/org/apache/poi/hssf/usermodel/TestPolygon.java
Normal file
@ -0,0 +1,248 @@
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.hssf.usermodel;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.apache.poi.ddf.EscherArrayProperty;
|
||||
import org.apache.poi.ddf.EscherOptRecord;
|
||||
import org.apache.poi.ddf.EscherProperties;
|
||||
import org.apache.poi.ddf.EscherSpRecord;
|
||||
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||
import org.apache.poi.hssf.model.HSSFTestModelHelper;
|
||||
import org.apache.poi.hssf.model.PolygonShape;
|
||||
import org.apache.poi.hssf.record.ObjRecord;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author Evgeniy Berlog
|
||||
* @date 28.06.12
|
||||
*/
|
||||
public class TestPolygon extends TestCase{
|
||||
|
||||
public void testResultEqualsToAbstractShape() throws IOException {
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sh = wb.createSheet();
|
||||
HSSFPatriarch patriarch = sh.createDrawingPatriarch();
|
||||
|
||||
HSSFPolygon polygon = patriarch.createPolygon(new HSSFClientAnchor());
|
||||
polygon.setPolygonDrawArea( 100, 100 );
|
||||
polygon.setPoints( new int[]{0, 90, 50}, new int[]{5, 5, 44} );
|
||||
PolygonShape polygonShape = HSSFTestModelHelper.createPolygonShape(1024, polygon);
|
||||
polygon.setShapeId(1024);
|
||||
|
||||
assertEquals(polygon.getEscherContainer().getChildRecords().size(), 4);
|
||||
assertEquals(polygonShape.getSpContainer().getChildRecords().size(), 4);
|
||||
|
||||
//sp record
|
||||
byte[] expected = polygonShape.getSpContainer().getChild(0).serialize();
|
||||
byte[] actual = polygon.getEscherContainer().getChild(0).serialize();
|
||||
|
||||
assertEquals(expected.length, actual.length);
|
||||
assertTrue(Arrays.equals(expected, actual));
|
||||
|
||||
expected = polygonShape.getSpContainer().getChild(2).serialize();
|
||||
actual = polygon.getEscherContainer().getChild(2).serialize();
|
||||
|
||||
assertEquals(expected.length, actual.length);
|
||||
assertTrue(Arrays.equals(expected, actual));
|
||||
|
||||
expected = polygonShape.getSpContainer().getChild(3).serialize();
|
||||
actual = polygon.getEscherContainer().getChild(3).serialize();
|
||||
|
||||
assertEquals(expected.length, actual.length);
|
||||
assertTrue(Arrays.equals(expected, actual));
|
||||
|
||||
ObjRecord obj = polygon.getObjRecord();
|
||||
ObjRecord objShape = polygonShape.getObjRecord();
|
||||
|
||||
expected = obj.serialize();
|
||||
actual = objShape.serialize();
|
||||
|
||||
assertEquals(expected.length, actual.length);
|
||||
assertTrue(Arrays.equals(expected, actual));
|
||||
}
|
||||
|
||||
public void testPolygonPoints(){
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sh = wb.createSheet();
|
||||
HSSFPatriarch patriarch = sh.createDrawingPatriarch();
|
||||
|
||||
HSSFPolygon polygon = patriarch.createPolygon(new HSSFClientAnchor());
|
||||
polygon.setPolygonDrawArea( 100, 100 );
|
||||
polygon.setPoints( new int[]{0, 90, 50, 90}, new int[]{5, 5, 44, 88} );
|
||||
|
||||
PolygonShape polygonShape = HSSFTestModelHelper.createPolygonShape(0, polygon);
|
||||
|
||||
EscherArrayProperty verticesProp1 = polygon.getOptRecord().lookup(EscherProperties.GEOMETRY__VERTICES);
|
||||
EscherArrayProperty verticesProp2 = ((EscherOptRecord)polygonShape.getSpContainer().getChildById(EscherOptRecord.RECORD_ID))
|
||||
.lookup(EscherProperties.GEOMETRY__VERTICES);
|
||||
|
||||
assertEquals(verticesProp1.getNumberOfElementsInArray(), verticesProp2.getNumberOfElementsInArray());
|
||||
assertEquals(verticesProp1.toXml(""), verticesProp2.toXml(""));
|
||||
|
||||
polygon.setPoints(new int[]{1,2,3}, new int[] {4,5,6});
|
||||
assertTrue(Arrays.equals(polygon.getXPoints(), new int[]{1, 2, 3}));
|
||||
assertTrue(Arrays.equals(polygon.getYPoints(), new int[]{4, 5, 6}));
|
||||
|
||||
polygonShape = HSSFTestModelHelper.createPolygonShape(0, polygon);
|
||||
verticesProp1 = polygon.getOptRecord().lookup(EscherProperties.GEOMETRY__VERTICES);
|
||||
verticesProp2 = ((EscherOptRecord)polygonShape.getSpContainer().getChildById(EscherOptRecord.RECORD_ID))
|
||||
.lookup(EscherProperties.GEOMETRY__VERTICES);
|
||||
|
||||
assertEquals(verticesProp1.getNumberOfElementsInArray(), verticesProp2.getNumberOfElementsInArray());
|
||||
assertEquals(verticesProp1.toXml(""), verticesProp2.toXml(""));
|
||||
}
|
||||
|
||||
public void testSetGetProperties(){
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sh = wb.createSheet();
|
||||
HSSFPatriarch patriarch = sh.createDrawingPatriarch();
|
||||
|
||||
HSSFPolygon polygon = patriarch.createPolygon(new HSSFClientAnchor());
|
||||
polygon.setPolygonDrawArea( 102, 101 );
|
||||
polygon.setPoints( new int[]{1,2,3}, new int[]{4,5,6} );
|
||||
|
||||
assertTrue(Arrays.equals(polygon.getXPoints(), new int[]{1,2,3}));
|
||||
assertTrue(Arrays.equals(polygon.getYPoints(), new int[]{4, 5, 6}));
|
||||
assertEquals(polygon.getDrawAreaHeight(), 101);
|
||||
assertEquals(polygon.getDrawAreaWidth(), 102);
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sh = wb.getSheetAt(0);
|
||||
patriarch = sh.getDrawingPatriarch();
|
||||
|
||||
polygon = (HSSFPolygon) patriarch.getChildren().get(0);
|
||||
assertTrue(Arrays.equals(polygon.getXPoints(), new int[]{1, 2, 3}));
|
||||
assertTrue(Arrays.equals(polygon.getYPoints(), new int[]{4, 5, 6}));
|
||||
assertEquals(polygon.getDrawAreaHeight(), 101);
|
||||
assertEquals(polygon.getDrawAreaWidth(), 102);
|
||||
|
||||
polygon.setPolygonDrawArea( 1021, 1011 );
|
||||
polygon.setPoints( new int[]{11,21,31}, new int[]{41,51,61} );
|
||||
|
||||
assertTrue(Arrays.equals(polygon.getXPoints(), new int[]{11, 21, 31}));
|
||||
assertTrue(Arrays.equals(polygon.getYPoints(), new int[]{41, 51, 61}));
|
||||
assertEquals(polygon.getDrawAreaHeight(), 1011);
|
||||
assertEquals(polygon.getDrawAreaWidth(), 1021);
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sh = wb.getSheetAt(0);
|
||||
patriarch = sh.getDrawingPatriarch();
|
||||
|
||||
polygon = (HSSFPolygon) patriarch.getChildren().get(0);
|
||||
|
||||
assertTrue(Arrays.equals(polygon.getXPoints(), new int[]{11, 21, 31}));
|
||||
assertTrue(Arrays.equals(polygon.getYPoints(), new int[]{41, 51, 61}));
|
||||
assertEquals(polygon.getDrawAreaHeight(), 1011);
|
||||
assertEquals(polygon.getDrawAreaWidth(), 1021);
|
||||
}
|
||||
|
||||
public void testAddToExistingFile(){
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sh = wb.createSheet();
|
||||
HSSFPatriarch patriarch = sh.createDrawingPatriarch();
|
||||
|
||||
HSSFPolygon polygon = patriarch.createPolygon(new HSSFClientAnchor());
|
||||
polygon.setPolygonDrawArea( 102, 101 );
|
||||
polygon.setPoints( new int[]{1,2,3}, new int[]{4,5,6} );
|
||||
|
||||
HSSFPolygon polygon1 = patriarch.createPolygon(new HSSFClientAnchor());
|
||||
polygon1.setPolygonDrawArea( 103, 104 );
|
||||
polygon1.setPoints( new int[]{11,12,13}, new int[]{14,15,16} );
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sh = wb.getSheetAt(0);
|
||||
patriarch = sh.getDrawingPatriarch();
|
||||
|
||||
assertEquals(patriarch.getChildren().size(), 2);
|
||||
|
||||
HSSFPolygon polygon2 = patriarch.createPolygon(new HSSFClientAnchor());
|
||||
polygon2.setPolygonDrawArea( 203, 204 );
|
||||
polygon2.setPoints( new int[]{21,22,23}, new int[]{24,25,26} );
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sh = wb.getSheetAt(0);
|
||||
patriarch = sh.getDrawingPatriarch();
|
||||
|
||||
assertEquals(patriarch.getChildren().size(), 3);
|
||||
|
||||
polygon = (HSSFPolygon) patriarch.getChildren().get(0);
|
||||
polygon1 = (HSSFPolygon) patriarch.getChildren().get(1);
|
||||
polygon2 = (HSSFPolygon) patriarch.getChildren().get(2);
|
||||
|
||||
assertTrue(Arrays.equals(polygon.getXPoints(), new int[]{1, 2, 3}));
|
||||
assertTrue(Arrays.equals(polygon.getYPoints(), new int[]{4,5,6}));
|
||||
assertEquals(polygon.getDrawAreaHeight(), 101);
|
||||
assertEquals(polygon.getDrawAreaWidth(), 102);
|
||||
|
||||
assertTrue(Arrays.equals(polygon1.getXPoints(), new int[]{11,12,13}));
|
||||
assertTrue(Arrays.equals(polygon1.getYPoints(), new int[]{14,15,16}));
|
||||
assertEquals(polygon1.getDrawAreaHeight(), 104);
|
||||
assertEquals(polygon1.getDrawAreaWidth(), 103);
|
||||
|
||||
assertTrue(Arrays.equals(polygon2.getXPoints(), new int[]{21,22,23}));
|
||||
assertTrue(Arrays.equals(polygon2.getYPoints(), new int[]{24,25,26}));
|
||||
assertEquals(polygon2.getDrawAreaHeight(), 204);
|
||||
assertEquals(polygon2.getDrawAreaWidth(), 203);
|
||||
}
|
||||
|
||||
public void testExistingFile() throws IOException {
|
||||
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls");
|
||||
HSSFSheet sheet = wb.getSheet("polygon");
|
||||
HSSFPatriarch drawing = sheet.getDrawingPatriarch();
|
||||
assertEquals(1, drawing.getChildren().size());
|
||||
|
||||
HSSFPolygon polygon = (HSSFPolygon) drawing.getChildren().get(0);
|
||||
assertEquals(polygon.getDrawAreaHeight(), 2466975);
|
||||
assertEquals(polygon.getDrawAreaWidth(), 3686175);
|
||||
assertTrue(Arrays.equals(polygon.getXPoints(), new int[]{0, 0, 31479, 16159, 19676, 20502}));
|
||||
assertTrue(Arrays.equals(polygon.getYPoints(), new int[]{0, 0, 36, 56, 34, 18}));
|
||||
}
|
||||
|
||||
public void testPolygonType(){
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sh = wb.createSheet();
|
||||
HSSFPatriarch patriarch = sh.createDrawingPatriarch();
|
||||
|
||||
HSSFPolygon polygon = patriarch.createPolygon(new HSSFClientAnchor());
|
||||
polygon.setPolygonDrawArea( 102, 101 );
|
||||
polygon.setPoints( new int[]{1,2,3}, new int[]{4,5,6} );
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sh = wb.getSheetAt(0);
|
||||
patriarch = sh.getDrawingPatriarch();
|
||||
|
||||
HSSFPolygon polygon1 = patriarch.createPolygon(new HSSFClientAnchor());
|
||||
polygon1.setPolygonDrawArea( 102, 101 );
|
||||
polygon1.setPoints( new int[]{1,2,3}, new int[]{4,5,6} );
|
||||
|
||||
EscherSpRecord spRecord = polygon1.getEscherContainer().getChildById(EscherSpRecord.RECORD_ID);
|
||||
|
||||
spRecord.setShapeType((short)77/**RANDOM**/);
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sh = wb.getSheetAt(0);
|
||||
patriarch = sh.getDrawingPatriarch();
|
||||
|
||||
assertEquals(patriarch.getChildren().size(), 2);
|
||||
assertTrue(patriarch.getChildren().get(0) instanceof HSSFPolygon);
|
||||
assertTrue(patriarch.getChildren().get(1) instanceof HSSFPolygon);
|
||||
}
|
||||
}
|
279
src/testcases/org/apache/poi/hssf/usermodel/TestShapeGroup.java
Normal file
279
src/testcases/org/apache/poi/hssf/usermodel/TestShapeGroup.java
Normal file
@ -0,0 +1,279 @@
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.hssf.usermodel;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.apache.poi.ddf.EscherContainerRecord;
|
||||
import org.apache.poi.ddf.EscherSpgrRecord;
|
||||
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||
import org.apache.poi.hssf.record.EscherAggregate;
|
||||
import org.apache.poi.hssf.record.ObjRecord;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Evgeniy Berlog
|
||||
* @date 29.06.12
|
||||
*/
|
||||
public class TestShapeGroup extends TestCase{
|
||||
|
||||
public void testSetGetCoordinates(){
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sh = wb.createSheet();
|
||||
HSSFPatriarch patriarch = sh.createDrawingPatriarch();
|
||||
HSSFShapeGroup group = patriarch.createGroup(new HSSFClientAnchor());
|
||||
assertEquals(group.getX1(), 0);
|
||||
assertEquals(group.getY1(), 0);
|
||||
assertEquals(group.getX2(), 1023);
|
||||
assertEquals(group.getY2(), 255);
|
||||
|
||||
group.setCoordinates(1,2,3,4);
|
||||
|
||||
assertEquals(group.getX1(), 1);
|
||||
assertEquals(group.getY1(), 2);
|
||||
assertEquals(group.getX2(), 3);
|
||||
assertEquals(group.getY2(), 4);
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sh = wb.getSheetAt(0);
|
||||
patriarch = sh.getDrawingPatriarch();
|
||||
|
||||
group = (HSSFShapeGroup) patriarch.getChildren().get(0);
|
||||
assertEquals(group.getX1(), 1);
|
||||
assertEquals(group.getY1(), 2);
|
||||
assertEquals(group.getX2(), 3);
|
||||
assertEquals(group.getY2(), 4);
|
||||
}
|
||||
|
||||
public void testAddToExistingFile(){
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sh = wb.createSheet();
|
||||
HSSFPatriarch patriarch = sh.createDrawingPatriarch();
|
||||
HSSFShapeGroup group1 = patriarch.createGroup(new HSSFClientAnchor());
|
||||
HSSFShapeGroup group2 = patriarch.createGroup(new HSSFClientAnchor());
|
||||
|
||||
group1.setCoordinates(1,2,3,4);
|
||||
group2.setCoordinates(5,6,7,8);
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sh = wb.getSheetAt(0);
|
||||
patriarch = sh.getDrawingPatriarch();
|
||||
|
||||
assertEquals(patriarch.getChildren().size(), 2);
|
||||
|
||||
HSSFShapeGroup group3 = patriarch.createGroup(new HSSFClientAnchor());
|
||||
group3.setCoordinates(9,10,11,12);
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sh = wb.getSheetAt(0);
|
||||
patriarch = sh.getDrawingPatriarch();
|
||||
|
||||
assertEquals(patriarch.getChildren().size(), 3);
|
||||
}
|
||||
|
||||
public void testModify() throws Exception {
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
|
||||
// create a sheet with a text box
|
||||
HSSFSheet sheet = wb.createSheet();
|
||||
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
|
||||
|
||||
HSSFShapeGroup group1 = patriarch.createGroup(new
|
||||
HSSFClientAnchor(0,0,0,0,
|
||||
(short)0, 0, (short)15, 25));
|
||||
group1.setCoordinates(0, 0, 792, 612);
|
||||
|
||||
HSSFTextbox textbox1 = group1.createTextbox(new
|
||||
HSSFChildAnchor(100, 100, 300, 300));
|
||||
HSSFRichTextString rt1 = new HSSFRichTextString("Hello, World!");
|
||||
textbox1.setString(rt1);
|
||||
|
||||
// write, read back and check that our text box is there
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sheet = wb.getSheetAt(0);
|
||||
patriarch = sheet.getDrawingPatriarch();
|
||||
assertEquals(1, patriarch.getChildren().size());
|
||||
|
||||
group1 = (HSSFShapeGroup)patriarch.getChildren().get(0);
|
||||
assertEquals(1, group1.getChildren().size());
|
||||
textbox1 = (HSSFTextbox)group1.getChildren().get(0);
|
||||
assertEquals("Hello, World!", textbox1.getString().getString());
|
||||
|
||||
// modify anchor
|
||||
assertEquals(new HSSFChildAnchor(100, 100, 300, 300),
|
||||
textbox1.getAnchor());
|
||||
HSSFChildAnchor newAnchor = new HSSFChildAnchor(200,200, 400, 400);
|
||||
textbox1.setAnchor(newAnchor);
|
||||
// modify text
|
||||
textbox1.setString(new HSSFRichTextString("Hello, World! (modified)"));
|
||||
|
||||
// add a new text box
|
||||
HSSFTextbox textbox2 = group1.createTextbox(new
|
||||
HSSFChildAnchor(400, 400, 600, 600));
|
||||
HSSFRichTextString rt2 = new HSSFRichTextString("Hello, World-2");
|
||||
textbox2.setString(rt2);
|
||||
assertEquals(2, group1.getChildren().size());
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sheet = wb.getSheetAt(0);
|
||||
patriarch = sheet.getDrawingPatriarch();
|
||||
assertEquals(1, patriarch.getChildren().size());
|
||||
|
||||
group1 = (HSSFShapeGroup)patriarch.getChildren().get(0);
|
||||
assertEquals(2, group1.getChildren().size());
|
||||
textbox1 = (HSSFTextbox)group1.getChildren().get(0);
|
||||
assertEquals("Hello, World! (modified)",
|
||||
textbox1.getString().getString());
|
||||
assertEquals(new HSSFChildAnchor(200,200, 400, 400),
|
||||
textbox1.getAnchor());
|
||||
|
||||
textbox2 = (HSSFTextbox)group1.getChildren().get(1);
|
||||
assertEquals("Hello, World-2", textbox2.getString().getString());
|
||||
assertEquals(new HSSFChildAnchor(400, 400, 600, 600),
|
||||
textbox2.getAnchor());
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sheet = wb.getSheetAt(0);
|
||||
patriarch = sheet.getDrawingPatriarch();
|
||||
group1 = (HSSFShapeGroup)patriarch.getChildren().get(0);
|
||||
textbox1 = (HSSFTextbox)group1.getChildren().get(0);
|
||||
textbox2 = (HSSFTextbox)group1.getChildren().get(1);
|
||||
HSSFTextbox textbox3 = group1.createTextbox(new
|
||||
HSSFChildAnchor(400,200, 600, 400));
|
||||
HSSFRichTextString rt3 = new HSSFRichTextString("Hello, World-3");
|
||||
textbox3.setString(rt3);
|
||||
}
|
||||
|
||||
public void testAddShapesToGroup(){
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
|
||||
// create a sheet with a text box
|
||||
HSSFSheet sheet = wb.createSheet();
|
||||
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
|
||||
|
||||
HSSFShapeGroup group = patriarch.createGroup(new HSSFClientAnchor());
|
||||
int index = wb.addPicture(new byte[]{1,2,3}, HSSFWorkbook.PICTURE_TYPE_JPEG);
|
||||
group.createPicture(new HSSFChildAnchor(), index);
|
||||
HSSFPolygon polygon = group.createPolygon(new HSSFChildAnchor());
|
||||
polygon.setPoints(new int[]{1,100, 1}, new int[]{1, 50, 100});
|
||||
group.createTextbox(new HSSFChildAnchor());
|
||||
group.createShape(new HSSFChildAnchor());
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sheet = wb.getSheetAt(0);
|
||||
patriarch = sheet.getDrawingPatriarch();
|
||||
assertEquals(1, patriarch.getChildren().size());
|
||||
|
||||
assertTrue(patriarch.getChildren().get(0) instanceof HSSFShapeGroup);
|
||||
group = (HSSFShapeGroup) patriarch.getChildren().get(0);
|
||||
|
||||
assertEquals(group.getChildren().size(), 4);
|
||||
|
||||
assertTrue(group.getChildren().get(0) instanceof HSSFPicture);
|
||||
assertTrue(group.getChildren().get(1) instanceof HSSFPolygon);
|
||||
assertTrue(group.getChildren().get(2) instanceof HSSFTextbox);
|
||||
assertTrue(group.getChildren().get(3) instanceof HSSFSimpleShape);
|
||||
|
||||
HSSFShapeGroup group2 = patriarch.createGroup(new HSSFClientAnchor());
|
||||
|
||||
index = wb.addPicture(new byte[]{2,2,2}, HSSFWorkbook.PICTURE_TYPE_JPEG);
|
||||
group2.createPicture(new HSSFChildAnchor(), index);
|
||||
polygon = group2.createPolygon(new HSSFChildAnchor());
|
||||
polygon.setPoints(new int[]{1,100, 1}, new int[]{1, 50, 100});
|
||||
group2.createTextbox(new HSSFChildAnchor());
|
||||
group2.createShape(new HSSFChildAnchor());
|
||||
group2.createShape(new HSSFChildAnchor());
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sheet = wb.getSheetAt(0);
|
||||
patriarch = sheet.getDrawingPatriarch();
|
||||
assertEquals(2, patriarch.getChildren().size());
|
||||
|
||||
group = (HSSFShapeGroup) patriarch.getChildren().get(1);
|
||||
|
||||
assertEquals(group.getChildren().size(), 5);
|
||||
|
||||
assertTrue(group.getChildren().get(0) instanceof HSSFPicture);
|
||||
assertTrue(group.getChildren().get(1) instanceof HSSFPolygon);
|
||||
assertTrue(group.getChildren().get(2) instanceof HSSFTextbox);
|
||||
assertTrue(group.getChildren().get(3) instanceof HSSFSimpleShape);
|
||||
assertTrue(group.getChildren().get(4) instanceof HSSFSimpleShape);
|
||||
|
||||
group.getShapeId();
|
||||
}
|
||||
|
||||
public void testSpgrRecord(){
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
|
||||
// create a sheet with a text box
|
||||
HSSFSheet sheet = wb.createSheet();
|
||||
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
|
||||
|
||||
HSSFShapeGroup group = patriarch.createGroup(new HSSFClientAnchor());
|
||||
assertSame(((EscherContainerRecord)group.getEscherContainer().getChild(0)).getChildById(EscherSpgrRecord.RECORD_ID), getSpgrRecord(group));
|
||||
}
|
||||
|
||||
private static EscherSpgrRecord getSpgrRecord(HSSFShapeGroup group) {
|
||||
Field spgrField = null;
|
||||
try {
|
||||
spgrField = group.getClass().getDeclaredField("_spgrRecord");
|
||||
spgrField.setAccessible(true);
|
||||
return (EscherSpgrRecord) spgrField.get(group);
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void testClearShapes(){
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sheet = wb.createSheet();
|
||||
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
|
||||
HSSFShapeGroup group = patriarch.createGroup(new HSSFClientAnchor());
|
||||
|
||||
group.createShape(new HSSFChildAnchor());
|
||||
group.createShape(new HSSFChildAnchor());
|
||||
|
||||
EscherAggregate agg = HSSFTestHelper.getEscherAggregate(patriarch);
|
||||
|
||||
assertEquals(agg.getShapeToObjMapping().size(), 5);
|
||||
assertEquals(agg.getTailRecords().size(), 0);
|
||||
assertEquals(group.getChildren().size(), 2);
|
||||
|
||||
group.clear();
|
||||
|
||||
assertEquals(agg.getShapeToObjMapping().size(), 1);
|
||||
assertEquals(agg.getTailRecords().size(), 0);
|
||||
assertEquals(group.getChildren().size(), 0);
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sheet = wb.getSheetAt(0);
|
||||
patriarch = sheet.getDrawingPatriarch();
|
||||
|
||||
group = (HSSFShapeGroup) patriarch.getChildren().get(0);
|
||||
|
||||
assertEquals(agg.getShapeToObjMapping().size(), 1);
|
||||
assertEquals(agg.getTailRecords().size(), 0);
|
||||
assertEquals(group.getChildren().size(), 0);
|
||||
}
|
||||
}
|
199
src/testcases/org/apache/poi/hssf/usermodel/TestText.java
Normal file
199
src/testcases/org/apache/poi/hssf/usermodel/TestText.java
Normal file
@ -0,0 +1,199 @@
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.hssf.usermodel;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||
import org.apache.poi.hssf.model.HSSFTestModelHelper;
|
||||
import org.apache.poi.hssf.model.TextboxShape;
|
||||
import org.apache.poi.hssf.record.CommonObjectDataSubRecord;
|
||||
import org.apache.poi.hssf.record.ObjRecord;
|
||||
import org.apache.poi.hssf.record.TextObjectRecord;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author Evgeniy Berlog
|
||||
* @date 25.06.12
|
||||
*/
|
||||
public class TestText extends TestCase {
|
||||
|
||||
public void testResultEqualsToAbstractShape() {
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sh = wb.createSheet();
|
||||
HSSFPatriarch patriarch = sh.createDrawingPatriarch();
|
||||
HSSFTextbox textbox = patriarch.createTextbox(new HSSFClientAnchor());
|
||||
TextboxShape textboxShape = HSSFTestModelHelper.createTextboxShape(1025, textbox);
|
||||
|
||||
assertEquals(textbox.getEscherContainer().getChildRecords().size(), 5);
|
||||
assertEquals(textboxShape.getSpContainer().getChildRecords().size(), 5);
|
||||
|
||||
//sp record
|
||||
byte[] expected = textboxShape.getSpContainer().getChild(0).serialize();
|
||||
byte[] actual = textbox.getEscherContainer().getChild(0).serialize();
|
||||
|
||||
assertEquals(expected.length, actual.length);
|
||||
assertTrue(Arrays.equals(expected, actual));
|
||||
|
||||
expected = textboxShape.getSpContainer().getChild(2).serialize();
|
||||
actual = textbox.getEscherContainer().getChild(2).serialize();
|
||||
|
||||
assertEquals(expected.length, actual.length);
|
||||
assertTrue(Arrays.equals(expected, actual));
|
||||
|
||||
expected = textboxShape.getSpContainer().getChild(3).serialize();
|
||||
actual = textbox.getEscherContainer().getChild(3).serialize();
|
||||
|
||||
assertEquals(expected.length, actual.length);
|
||||
assertTrue(Arrays.equals(expected, actual));
|
||||
|
||||
expected = textboxShape.getSpContainer().getChild(4).serialize();
|
||||
actual = textbox.getEscherContainer().getChild(4).serialize();
|
||||
|
||||
assertEquals(expected.length, actual.length);
|
||||
assertTrue(Arrays.equals(expected, actual));
|
||||
|
||||
ObjRecord obj = textbox.getObjRecord();
|
||||
ObjRecord objShape = textboxShape.getObjRecord();
|
||||
|
||||
expected = obj.serialize();
|
||||
actual = objShape.serialize();
|
||||
|
||||
TextObjectRecord tor = textbox.getTextObjectRecord();
|
||||
TextObjectRecord torShape = textboxShape.getTextObjectRecord();
|
||||
|
||||
expected = tor.serialize();
|
||||
actual = torShape.serialize();
|
||||
|
||||
assertEquals(expected.length, actual.length);
|
||||
assertTrue(Arrays.equals(expected, actual));
|
||||
}
|
||||
|
||||
public void testAddTextToExistingFile() {
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sh = wb.createSheet();
|
||||
HSSFPatriarch patriarch = sh.createDrawingPatriarch();
|
||||
HSSFTextbox textbox = patriarch.createTextbox(new HSSFClientAnchor());
|
||||
textbox.setString(new HSSFRichTextString("just for test"));
|
||||
HSSFTextbox textbox2 = patriarch.createTextbox(new HSSFClientAnchor());
|
||||
textbox2.setString(new HSSFRichTextString("just for test2"));
|
||||
|
||||
assertEquals(patriarch.getChildren().size(), 2);
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sh = wb.getSheetAt(0);
|
||||
patriarch = sh.getDrawingPatriarch();
|
||||
|
||||
assertEquals(patriarch.getChildren().size(), 2);
|
||||
HSSFTextbox text3 = patriarch.createTextbox(new HSSFClientAnchor());
|
||||
text3.setString(new HSSFRichTextString("text3"));
|
||||
assertEquals(patriarch.getChildren().size(), 3);
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sh = wb.getSheetAt(0);
|
||||
patriarch = sh.getDrawingPatriarch();
|
||||
|
||||
assertEquals(patriarch.getChildren().size(), 3);
|
||||
assertEquals(((HSSFTextbox) patriarch.getChildren().get(0)).getString().getString(), "just for test");
|
||||
assertEquals(((HSSFTextbox) patriarch.getChildren().get(1)).getString().getString(), "just for test2");
|
||||
assertEquals(((HSSFTextbox) patriarch.getChildren().get(2)).getString().getString(), "text3");
|
||||
}
|
||||
|
||||
public void testSetGetProperties() {
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sh = wb.createSheet();
|
||||
HSSFPatriarch patriarch = sh.createDrawingPatriarch();
|
||||
HSSFTextbox textbox = patriarch.createTextbox(new HSSFClientAnchor());
|
||||
textbox.setString(new HSSFRichTextString("test"));
|
||||
assertEquals(textbox.getString().getString(), "test");
|
||||
|
||||
textbox.setHorizontalAlignment((short) 5);
|
||||
assertEquals(textbox.getHorizontalAlignment(), 5);
|
||||
|
||||
textbox.setVerticalAlignment((short) 6);
|
||||
assertEquals(textbox.getVerticalAlignment(), (short) 6);
|
||||
|
||||
textbox.setMarginBottom(7);
|
||||
assertEquals(textbox.getMarginBottom(), 7);
|
||||
|
||||
textbox.setMarginLeft(8);
|
||||
assertEquals(textbox.getMarginLeft(), 8);
|
||||
|
||||
textbox.setMarginRight(9);
|
||||
assertEquals(textbox.getMarginRight(), 9);
|
||||
|
||||
textbox.setMarginTop(10);
|
||||
assertEquals(textbox.getMarginTop(), 10);
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sh = wb.getSheetAt(0);
|
||||
patriarch = sh.getDrawingPatriarch();
|
||||
textbox = (HSSFTextbox) patriarch.getChildren().get(0);
|
||||
assertEquals(textbox.getString().getString(), "test");
|
||||
assertEquals(textbox.getHorizontalAlignment(), 5);
|
||||
assertEquals(textbox.getVerticalAlignment(), (short) 6);
|
||||
assertEquals(textbox.getMarginBottom(), 7);
|
||||
assertEquals(textbox.getMarginLeft(), 8);
|
||||
assertEquals(textbox.getMarginRight(), 9);
|
||||
assertEquals(textbox.getMarginTop(), 10);
|
||||
|
||||
textbox.setString(new HSSFRichTextString("test1"));
|
||||
textbox.setHorizontalAlignment(HSSFTextbox.HORIZONTAL_ALIGNMENT_CENTERED);
|
||||
textbox.setVerticalAlignment(HSSFTextbox.VERTICAL_ALIGNMENT_TOP);
|
||||
textbox.setMarginBottom(71);
|
||||
textbox.setMarginLeft(81);
|
||||
textbox.setMarginRight(91);
|
||||
textbox.setMarginTop(101);
|
||||
|
||||
assertEquals(textbox.getString().getString(), "test1");
|
||||
assertEquals(textbox.getHorizontalAlignment(), HSSFTextbox.HORIZONTAL_ALIGNMENT_CENTERED);
|
||||
assertEquals(textbox.getVerticalAlignment(), HSSFTextbox.VERTICAL_ALIGNMENT_TOP);
|
||||
assertEquals(textbox.getMarginBottom(), 71);
|
||||
assertEquals(textbox.getMarginLeft(), 81);
|
||||
assertEquals(textbox.getMarginRight(), 91);
|
||||
assertEquals(textbox.getMarginTop(), 101);
|
||||
|
||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
sh = wb.getSheetAt(0);
|
||||
patriarch = sh.getDrawingPatriarch();
|
||||
textbox = (HSSFTextbox) patriarch.getChildren().get(0);
|
||||
|
||||
assertEquals(textbox.getString().getString(), "test1");
|
||||
assertEquals(textbox.getHorizontalAlignment(), HSSFTextbox.HORIZONTAL_ALIGNMENT_CENTERED);
|
||||
assertEquals(textbox.getVerticalAlignment(), HSSFTextbox.VERTICAL_ALIGNMENT_TOP);
|
||||
assertEquals(textbox.getMarginBottom(), 71);
|
||||
assertEquals(textbox.getMarginLeft(), 81);
|
||||
assertEquals(textbox.getMarginRight(), 91);
|
||||
assertEquals(textbox.getMarginTop(), 101);
|
||||
}
|
||||
|
||||
public void testExistingFileWithText(){
|
||||
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls");
|
||||
HSSFSheet sheet = wb.getSheet("text");
|
||||
HSSFPatriarch drawing = sheet.getDrawingPatriarch();
|
||||
assertEquals(1, drawing.getChildren().size());
|
||||
HSSFTextbox textbox = (HSSFTextbox) drawing.getChildren().get(0);
|
||||
assertEquals(textbox.getHorizontalAlignment(), HSSFTextbox.HORIZONTAL_ALIGNMENT_LEFT);
|
||||
assertEquals(textbox.getVerticalAlignment(), HSSFTextbox.VERTICAL_ALIGNMENT_TOP);
|
||||
assertEquals(textbox.getMarginTop(), 0);
|
||||
assertEquals(textbox.getMarginBottom(), 3600000);
|
||||
assertEquals(textbox.getMarginLeft(), 3600000);
|
||||
assertEquals(textbox.getMarginRight(), 0);
|
||||
assertEquals(textbox.getString().getString(), "teeeeesssstttt");
|
||||
}
|
||||
}
|
BIN
test-data/spreadsheet/45129.xls
Executable file
BIN
test-data/spreadsheet/45129.xls
Executable file
Binary file not shown.
BIN
test-data/spreadsheet/51675.xls
Normal file
BIN
test-data/spreadsheet/51675.xls
Normal file
Binary file not shown.
BIN
test-data/spreadsheet/DrawingAndComments.xls
Executable file
BIN
test-data/spreadsheet/DrawingAndComments.xls
Executable file
Binary file not shown.
BIN
test-data/spreadsheet/DrawingContinue.xls
Executable file
BIN
test-data/spreadsheet/DrawingContinue.xls
Executable file
Binary file not shown.
BIN
test-data/spreadsheet/SolverContainerAfterSPGR.xls
Executable file
BIN
test-data/spreadsheet/SolverContainerAfterSPGR.xls
Executable file
Binary file not shown.
BIN
test-data/spreadsheet/dg-text.xls
Executable file
BIN
test-data/spreadsheet/dg-text.xls
Executable file
Binary file not shown.
BIN
test-data/spreadsheet/drawings.xls
Normal file
BIN
test-data/spreadsheet/drawings.xls
Normal file
Binary file not shown.
BIN
test-data/spreadsheet/empty.xls
Normal file
BIN
test-data/spreadsheet/empty.xls
Normal file
Binary file not shown.
BIN
test-data/spreadsheet/text.xls
Normal file
BIN
test-data/spreadsheet/text.xls
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user