diff --git a/src/java/org/apache/poi/ddf/EscherClientAnchorRecord.java b/src/java/org/apache/poi/ddf/EscherClientAnchorRecord.java index fbca0fb87..ffc9170c4 100644 --- a/src/java/org/apache/poi/ddf/EscherClientAnchorRecord.java +++ b/src/java/org/apache/poi/ddf/EscherClientAnchorRecord.java @@ -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; diff --git a/src/java/org/apache/poi/ddf/EscherRGBProperty.java b/src/java/org/apache/poi/ddf/EscherRGBProperty.java index 5d23addfb..e28b97b50 100644 --- a/src/java/org/apache/poi/ddf/EscherRGBProperty.java +++ b/src/java/org/apache/poi/ddf/EscherRGBProperty.java @@ -38,6 +38,10 @@ public class EscherRGBProperty return propertyValue; } + public void setRgbColor(int color){ + this.propertyValue = color; + } + public byte getRed() { return (byte) ( propertyValue & 0xFF ); diff --git a/src/java/org/apache/poi/ddf/EscherSimpleProperty.java b/src/java/org/apache/poi/ddf/EscherSimpleProperty.java index 78fb64203..efc392dcf 100644 --- a/src/java/org/apache/poi/ddf/EscherSimpleProperty.java +++ b/src/java/org/apache/poi/ddf/EscherSimpleProperty.java @@ -80,6 +80,10 @@ public class EscherSimpleProperty extends EscherProperty return propertyValue; } + public void setPropertyValue(int propertyValue) { + this.propertyValue = propertyValue; + } + /** * Returns true if one escher property is equal to another. */ diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFAnchor.java b/src/java/org/apache/poi/hssf/usermodel/HSSFAnchor.java index 6a8780610..2fe36130c 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFAnchor.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFAnchor.java @@ -18,40 +18,64 @@ 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() - { + 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; +// throw new IllegalArgumentException("continer must have anchor record"); + } + } + + public abstract int getDx1(); + + public abstract void setDx1(int dx1); + + public abstract int getDy1(); + + public abstract void setDy1(int dy1); + + public abstract int getDy2(); + + public abstract void setDy2(int dy2); + + public abstract int getDx2(); + + public abstract void setDx2(int dx2); public abstract boolean isHorizontallyFlipped(); + public abstract boolean isVerticallyFlipped(); + + public abstract EscherRecord getEscherAnchor(); + + protected abstract void createEscherAnchor(); } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFChildAnchor.java b/src/java/org/apache/poi/hssf/usermodel/HSSFChildAnchor.java index ccd0e620c..38c4f5f0e 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFChildAnchor.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFChildAnchor.java @@ -19,39 +19,100 @@ package org.apache.poi.hssf.usermodel; import org.apache.poi.ddf.EscherChildAnchorRecord; +import org.apache.poi.ddf.EscherRecord; public final class HSSFChildAnchor extends HSSFAnchor { - private EscherChildAnchorRecord escherChildAnchorRecord; + private EscherChildAnchorRecord _escherChildAnchor; public HSSFChildAnchor(EscherChildAnchorRecord escherChildAnchorRecord) { - this.escherChildAnchorRecord = escherChildAnchorRecord; + this._escherChildAnchor = escherChildAnchorRecord; } - public HSSFChildAnchor() - { + public HSSFChildAnchor() { + _escherChildAnchor = new EscherChildAnchorRecord(); } - public HSSFChildAnchor( int dx1, int dy1, int dx2, int dy2 ) - { - super( dx1, dy1, dx2, dy2 ); + public HSSFChildAnchor(int dx1, int dy1, int dx2, int dy2) { + super(dx1, dy1, dx2, dy2); } - public void setAnchor(int dx1, int dy1, int dx2, int dy2) - { - this.dx1 = dx1; - this.dy1 = dy1; - this.dx2 = dx2; - this.dy2 = dy2; + @Override + public int getDx1() { + return _escherChildAnchor.getDx1(); } - public boolean isHorizontallyFlipped() - { - return dx1 > dx2; + @Override + public void setDx1(int dx1) { + _escherChildAnchor.setDx1(dx1); } - public boolean isVerticallyFlipped() - { - return dy1 > dy2; + @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); + } + + public void setAnchor(int dx1, int dy1, int dx2, int dy2) { + setDx1(dx1); + setDy1(dy1); + setDx2(dx2); + setDy2(dy2); + } + + public boolean isHorizontallyFlipped() { + return getDx1() > getDx2(); + } + + public boolean isVerticallyFlipped() { + return getDy1() > getDy2(); + } + + @Override + public 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(); } } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFClientAnchor.java b/src/java/org/apache/poi/hssf/usermodel/HSSFClientAnchor.java index a040144c2..49e20a42f 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFClientAnchor.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFClientAnchor.java @@ -18,9 +18,9 @@ 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. @@ -28,42 +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 escherClientAnchorRecord; + private EscherClientAnchorRecord _escherClientAnchor; public HSSFClientAnchor(EscherClientAnchorRecord escherClientAnchorRecord) { - this.escherClientAnchorRecord = escherClientAnchorRecord; - //TODO set properties or read properties from EscherRecord ? + 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"); @@ -74,35 +66,30 @@ 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(col1); + setCol2(col2); + setRow1(row1); + setRow2(row2); } /** * 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); @@ -111,8 +98,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(); @@ -120,55 +106,48 @@ public final class HSSFClientAnchor extends HSSFAnchor implements ClientAnchor { return row.getHeightInPoints(); } - public short getCol1() - { - return col1; + public short getCol1() { + return _escherClientAnchor.getCol1(); } - public void setCol1( short col1 ) - { + 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; + public void setCol1(int col1) { + setCol1((short) col1); } - public void setCol2( short col2 ) - { + public short getCol2() { + return _escherClientAnchor.getCol2(); + } + + public void setCol2(short col2) { checkRange(col2, 0, 255, "col2"); - this.col2 = col2; + _escherClientAnchor.setCol2(col2); } - public void setCol2( int col2 ){ - setCol2((short)col2); + public void setCol2(int col2) { + setCol2((short) col2); } - public int getRow1() - { - return row1; + public int getRow1() { + return _escherClientAnchor.getRow1(); } - public void setRow1( int row1 ) - { + 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; + public int getRow2() { + return _escherClientAnchor.getRow2(); } - public void setRow2( int row2 ) - { + public void setRow2(int row2) { checkRange(row2, 0, 256 * 256, "row2"); - this.row2 = row2; + _escherClientAnchor.setRow2(Integer.valueOf(row2).shortValue()); } /** @@ -179,79 +158,139 @@ 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. + * @return true if the anchor goes from right to left. */ - public boolean isHorizontallyFlipped() - { - if (col1 == col2) { - return dx1 > dx2; + public boolean isHorizontallyFlipped() { + if (getCol1() == getCol2()) { + return getDx1() > getDx2(); } - return col1 > col2; + return getCol1() > getCol2(); } /** - * @return true if the anchor goes from bottom to top. + * @return true if the anchor goes from bottom to top. */ - public boolean isVerticallyFlipped() - { - if (row1 == row2) { - return dy1 > dy2; + public boolean isVerticallyFlipped() { + if (getRow1() == getRow2()) { + return getDy1() > getDy2(); } - return row1 > row2; + return getRow1() > getRow2(); + } + + @Override + public EscherRecord getEscherAnchor() { + return _escherClientAnchor; + } + + @Override + protected void createEscherAnchor() { + _escherClientAnchor = new EscherClientAnchorRecord(); } /** * Gets the anchor type - *
+ *
* 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 - *+ *
* 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) { +// if (0 != anchorType && 2 != anchorType && 3 != anchorType){ +// throw new IllegalArgumentException("Anchor type of shape can take only such values: 0, 2, 3"); +// } + _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()); + } } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFComment.java b/src/java/org/apache/poi/hssf/usermodel/HSSFComment.java index 225e6da0e..2216971e6 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFComment.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFComment.java @@ -57,7 +57,7 @@ public class HSSFComment extends HSSFTextbox implements Comment { setShapeType(OBJECT_TYPE_COMMENT); //default color for comments - _fillColor = 0x08000050; + setFillColor(0x08000050); //by default comments are hidden _visible = false; diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFPicture.java b/src/java/org/apache/poi/hssf/usermodel/HSSFPicture.java index d4a7205c7..5aeb40b18 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFPicture.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFPicture.java @@ -145,8 +145,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 +160,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,8 +177,8 @@ 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; } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFRectangle.java b/src/java/org/apache/poi/hssf/usermodel/HSSFRectangle.java deleted file mode 100644 index 0a0468c14..000000000 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFRectangle.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.apache.poi.hssf.usermodel; - -import org.apache.poi.ddf.EscherContainerRecord; -import org.apache.poi.hssf.record.ObjRecord; - -/** - * @author Evgeniy Berlog - * @date 08.06.12 - */ -public class HSSFRectangle extends HSSFShape{ - - public HSSFRectangle(EscherContainerRecord spContainer, ObjRecord objRecord) { - super(spContainer, objRecord); - } -} diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFShape.java b/src/java/org/apache/poi/hssf/usermodel/HSSFShape.java index 7ffdfdb9b..c9bf922cb 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFShape.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFShape.java @@ -17,7 +17,7 @@ package org.apache.poi.hssf.usermodel; -import org.apache.poi.ddf.EscherContainerRecord; +import org.apache.poi.ddf.*; import org.apache.poi.hssf.record.ObjRecord; /** @@ -28,6 +28,8 @@ import org.apache.poi.hssf.record.ObjRecord; 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 int LINESTYLE_SOLID = 0; // Solid (continuous) pen public static final int LINESTYLE_DASHSYS = 1; // PS_DASH system dash style @@ -45,50 +47,53 @@ public abstract class HSSFShape { // TODO - make all these fields 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; + HSSFPatriarch _patriarch; - private EscherContainerRecord spContainer; - private ObjRecord objRecord; + protected EscherContainerRecord _escherContainer; + protected ObjRecord _objRecord; + protected final EscherOptRecord _optRecord; - public HSSFShape(EscherContainerRecord spContainer, ObjRecord objRecord){ - this.spContainer = spContainer; - this.objRecord = 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. */ - public HSSFShape( HSSFShape parent, HSSFAnchor anchor ) - { + public HSSFShape(HSSFShape parent, HSSFAnchor anchor) { this.parent = parent; this.anchor = anchor; + this._escherContainer = new EscherContainerRecord(); + _optRecord = new EscherOptRecord(); + _optRecord.addEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEDASHING, LINESTYLE_SOLID)); + _optRecord.addEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEWIDTH, LINEWIDTH_DEFAULT)); + _optRecord.addEscherProperty(new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, FILL__FILLCOLOR_DEFAULT)); + _optRecord.addEscherProperty(new EscherRGBProperty(EscherProperties.LINESTYLE__COLOR, LINESTYLE__COLOR_DEFAULT)); + _optRecord.addEscherProperty(new EscherBoolProperty(EscherProperties.FILL__NOFILLHITTEST, 0x0)); } - public EscherContainerRecord getSpContainer() { - return spContainer; + public EscherContainerRecord getEscherContainer() { + return _escherContainer; } public ObjRecord getObjRecord() { - return objRecord; + return _objRecord; } /** * 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; } @@ -96,26 +101,29 @@ 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) { + 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) { + _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) { + _escherContainer.removeChildRecord(anch); + } } - else - { - if ( anchor instanceof HSSFClientAnchor ) - throw new IllegalArgumentException( "Must use child anchors for shapes attached to groups." ); - } - + _escherContainer.addChildRecord(anchor.getEscherAnchor()); this.anchor = anchor; } @@ -123,92 +131,141 @@ 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; + EscherRGBProperty rgbProperty = _optRecord.lookup(EscherProperties.LINESTYLE__COLOR); + if (null == rgbProperty) { + rgbProperty = new EscherRGBProperty(EscherProperties.LINESTYLE__COLOR, lineStyleColor); + _optRecord.addEscherProperty(rgbProperty); + } else { + rgbProperty.setRgbColor(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; + EscherRGBProperty rgbProperty = _optRecord.lookup(EscherProperties.LINESTYLE__COLOR); + if (null == rgbProperty) { + rgbProperty = new EscherRGBProperty(EscherProperties.LINESTYLE__COLOR, lineStyleColor); + _optRecord.addEscherProperty(rgbProperty); + } else { + rgbProperty.setRgbColor(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; + EscherRGBProperty rgbProperty = _optRecord.lookup(EscherProperties.FILL__FILLCOLOR); + if (null == rgbProperty) { + rgbProperty = new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, fillColor); + _optRecord.addEscherProperty(rgbProperty); + } else { + rgbProperty.setRgbColor(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; + EscherRGBProperty rgbProperty = _optRecord.lookup(EscherProperties.FILL__FILLCOLOR); + if (null == rgbProperty) { + rgbProperty = new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, fillColor); + _optRecord.addEscherProperty(rgbProperty); + } else { + rgbProperty.setRgbColor(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.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; + EscherSimpleProperty property = _optRecord.lookup(EscherProperties.LINESTYLE__LINEWIDTH); + if (null == property) { + property = new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEWIDTH, lineWidth); + _optRecord.addEscherProperty(property); + } else { + property.setPropertyValue(lineWidth); + } } /** * @return One of the constants in LINESTYLE_* */ public int getLineStyle() { - return _lineStyle; + EscherSimpleProperty property = _optRecord.lookup(EscherProperties.LINESTYLE__LINEDASHING); + if (null == property){ + return -1; + } + 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; + EscherSimpleProperty property = _optRecord.lookup(EscherProperties.LINESTYLE__LINEDASHING); + if (null == property) { + property = new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEDASHING, lineStyle); + _optRecord.addEscherProperty(property); + } else { + property.setPropertyValue(lineStyle); + } } /** * @returntrue
if this shape is not filled with a color.
*/
public boolean isNoFill() {
- return _noFill;
+ EscherBoolProperty property = _optRecord.lookup(EscherProperties.FILL__NOFILLHITTEST);
+ return property.isTrue();
}
/**
* Sets whether this shape is filled or transparent.
*/
public void setNoFill(boolean noFill) {
- _noFill = noFill;
+ EscherBoolProperty property = _optRecord.lookup(EscherProperties.FILL__NOFILLHITTEST);
+ if (null == property) {
+ property = new EscherBoolProperty(EscherProperties.FILL__NOFILLHITTEST, noFill ? 1 : 0);
+ _optRecord.addEscherProperty(property);
+ } else {
+ property.setPropertyValue(noFill ? 1 : 0);
+ }
}
/**
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFShapeFactory.java b/src/java/org/apache/poi/hssf/usermodel/HSSFShapeFactory.java
index 4a10a8d07..68f410d17 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFShapeFactory.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFShapeFactory.java
@@ -39,25 +39,25 @@ import java.util.List;
import java.util.Map;
/**
- * @author evgeniy
+ * @author Evgeniy Berlog
* date: 05.06.12
*/
public class HSSFShapeFactory {
- private static final Map