git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@642878 13f79535-47bb-0310-9956-ffa450edef68tags/REL_3_0_3_BETA1
@@ -26,6 +26,7 @@ | |||
<!-- in strict alphabetical order --> | |||
<person id="AO" name="Andrew C. Oliver" email="acoliver2@users.sourceforge.net"/> | |||
<person id="GJS" name="Glen Stampoultzis" email="user@poi.apache.org"/> | |||
<person id="JM" name="Josh Micich" email="josh@apache.org"/> | |||
<person id="MJ" name="Marc Johnson" email="mjohnson@apache.org"/> | |||
<person id="NKB" name="Nicola Ken Barozzi" email="barozzi@nicolaken.com"/> | |||
<person id="NB" name="Nick Burch" email="nick@torchbox.com"/> | |||
@@ -36,6 +37,7 @@ | |||
<!-- Don't forget to update status.xml too! --> | |||
<release version="3.0.3-beta1" date="2008-04-??"> | |||
<action dev="POI-DEVELOPERS" type="add">30311 - More work on Conditional Formatting</action> | |||
<action dev="POI-DEVELOPERS" type="add">Move the Formula Evaluator code out of scratchpad</action> | |||
<action dev="POI-DEVELOPERS" type="add">Move the missing record aware eventusermodel code out of scratchpad</action> | |||
<action dev="POI-DEVELOPERS" type="add">44652 / 44603 - Improved handling of Pictures in Word Documents</action> |
@@ -22,6 +22,7 @@ | |||
<!-- in strict alphabetical order --> | |||
<person id="AO" name="Andrew C. Oliver" email="acoliver2@users.sourceforge.net"/> | |||
<person id="GJS" name="Glen Stampoultzis" email="user@poi.apache.org"/> | |||
<person id="JM" name="Josh Micich" email="josh@apache.org"/> | |||
<person id="MJ" name="Marc Johnson" email="mjohnson@apache.org"/> | |||
<person id="NKB" name="Nicola Ken Barozzi" email="barozzi@nicolaken.com"/> | |||
<person id="NB" name="Nick Burch" email="nick@torchbox.com"/> | |||
@@ -33,6 +34,7 @@ | |||
<!-- Don't forget to update changes.xml too! --> | |||
<changes> | |||
<release version="3.0.3-beta1" date="2008-04-??"> | |||
<action dev="POI-DEVELOPERS" type="add">30311 - More work on Conditional Formatting</action> | |||
<action dev="POI-DEVELOPERS" type="add">Move the Formula Evaluator code out of scratchpad</action> | |||
<action dev="POI-DEVELOPERS" type="add">Move the missing record aware eventusermodel code out of scratchpad</action> | |||
<action dev="POI-DEVELOPERS" type="add">44652 / 44603 - Improved handling of Pictures in Word Documents</action> |
@@ -15,18 +15,10 @@ | |||
limitations under the License. | |||
==================================================================== */ | |||
/* | |||
* ConditionalFormattingHeaderRecord.java | |||
* | |||
* Created on January 17, 2008, 3:05 AM | |||
*/ | |||
package org.apache.poi.hssf.record; | |||
import java.util.ArrayList; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import org.apache.poi.hssf.record.cf.CellRange; | |||
import org.apache.poi.hssf.util.Region; | |||
import org.apache.poi.util.LittleEndian; | |||
/** | |||
@@ -34,19 +26,27 @@ import org.apache.poi.util.LittleEndian; | |||
* | |||
* @author Dmitriy Kumshayev | |||
*/ | |||
public class CFHeaderRecord extends Record | |||
public final class CFHeaderRecord extends Record | |||
{ | |||
public static final short sid = 0x1B0; | |||
private static final CellRange[] EMPTY_CELL_RANGE_ARRAY = { }; | |||
private int field_1_numcf; | |||
private int field_2_need_recalculation; | |||
private CellRange field_3_enclosing_cell_range; | |||
private List field_4_cell_ranges; | |||
private CellRange[] field_4_cell_ranges; | |||
/** Creates new CFHeaderRecord */ | |||
public CFHeaderRecord() | |||
{ | |||
field_4_cell_ranges = new ArrayList(5); | |||
field_4_cell_ranges = EMPTY_CELL_RANGE_ARRAY; | |||
} | |||
public CFHeaderRecord(Region[] regions) | |||
{ | |||
CellRange[] unmergedRanges = CellRange.convertRegionsToCellRanges(regions); | |||
CellRange[] mergeCellRanges = CellRange.mergeCellRanges(unmergedRanges); | |||
setCellRanges(mergeCellRanges); | |||
} | |||
public CFHeaderRecord(RecordInputStream in) | |||
@@ -60,11 +60,12 @@ public class CFHeaderRecord extends Record | |||
field_2_need_recalculation = in.readShort(); | |||
field_3_enclosing_cell_range = new CellRange(in.readShort(),in.readShort(),in.readShort(),in.readShort()); | |||
int numCellRanges = in.readShort(); | |||
field_4_cell_ranges = new ArrayList(5); | |||
CellRange[] crs = new CellRange[numCellRanges]; | |||
for( int i=0; i<numCellRanges; i++) | |||
{ | |||
field_4_cell_ranges.add(new CellRange(in.readShort(),in.readShort(),in.readShort(),in.readShort())); | |||
crs[i] = new CellRange(in.readShort(),in.readShort(),in.readShort(),in.readShort()); | |||
} | |||
field_4_cell_ranges = crs; | |||
} | |||
public int getNumberOfConditionalFormats() | |||
@@ -101,28 +102,24 @@ public class CFHeaderRecord extends Record | |||
* modify the enclosing cell range accordingly. | |||
* @param List cellRanges - list of CellRange objects | |||
*/ | |||
public void setCellRanges( List cellRanges ) | |||
public void setCellRanges(CellRange[] cellRanges) | |||
{ | |||
field_4_cell_ranges.clear(); | |||
if(cellRanges!=null) | |||
if(cellRanges == null) | |||
{ | |||
field_3_enclosing_cell_range=null; | |||
for( int i=0; i<cellRanges.size(); i++) | |||
{ | |||
field_4_cell_ranges.add(cellRanges.get(i)); | |||
recalculateEnclosingRange((CellRange)cellRanges.get(i)); | |||
} | |||
throw new IllegalArgumentException("cellRanges must not be null"); | |||
} | |||
} | |||
private void recalculateEnclosingRange(CellRange cellRange) | |||
{ | |||
field_3_enclosing_cell_range = cellRange.createEnclosingCellRange(field_3_enclosing_cell_range); | |||
field_4_cell_ranges = (CellRange[]) cellRanges.clone(); | |||
CellRange enclosingRange = null; | |||
for (int i = 0; i < cellRanges.length; i++) | |||
{ | |||
enclosingRange = cellRanges[i].createEnclosingCellRange(enclosingRange); | |||
} | |||
field_3_enclosing_cell_range=enclosingRange; | |||
} | |||
public List getCellRanges() | |||
public CellRange[] getCellRanges() | |||
{ | |||
return field_4_cell_ranges; | |||
return (CellRange[]) field_4_cell_ranges.clone(); | |||
} | |||
public String toString() | |||
@@ -130,16 +127,16 @@ public class CFHeaderRecord extends Record | |||
StringBuffer buffer = new StringBuffer(); | |||
buffer.append("[CFHEADER]\n"); | |||
buffer.append(" .id = ").append(Integer.toHexString(sid)).append("\n"); | |||
buffer.append(" .numCF = ").append(getNumberOfConditionalFormats()).append("\n"); | |||
buffer.append(" .needRecalc = ").append(getNeedRecalculation()).append("\n"); | |||
buffer.append(" .enclosingCellRange= ").append(getEnclosingCellRange()).append("\n"); | |||
if( field_4_cell_ranges.size()>0) | |||
buffer.append(" .id = ").append(Integer.toHexString(sid)).append("\n"); | |||
buffer.append(" .numCF = ").append(getNumberOfConditionalFormats()).append("\n"); | |||
buffer.append(" .needRecalc = ").append(getNeedRecalculation()).append("\n"); | |||
buffer.append(" .enclosingCellRange= ").append(getEnclosingCellRange()).append("\n"); | |||
if( field_4_cell_ranges.length>0) | |||
{ | |||
buffer.append(" .cfranges=["); | |||
for( int i=0; i<field_4_cell_ranges.size(); i++) | |||
buffer.append(" .cfranges=["); | |||
for( int i=0; i<field_4_cell_ranges.length; i++) | |||
{ | |||
buffer.append(i==0?"":",").append(field_4_cell_ranges.get(i)); | |||
buffer.append(i==0?"":",").append(field_4_cell_ranges[i].toString()); | |||
} | |||
buffer.append("]\n"); | |||
} | |||
@@ -163,24 +160,21 @@ public class CFHeaderRecord extends Record | |||
LittleEndian.putShort(data, 10 + offset, (short) field_3_enclosing_cell_range.getLastRow()); | |||
LittleEndian.putShort(data, 12 + offset, (short) field_3_enclosing_cell_range.getFirstColumn()); | |||
LittleEndian.putShort(data, 14 + offset, (short) field_3_enclosing_cell_range.getLastColumn()); | |||
LittleEndian.putShort(data, 16 + offset, (short) field_4_cell_ranges.size()); | |||
for( int i=0 ; i!=field_4_cell_ranges.size(); i++) | |||
LittleEndian.putShort(data, 16 + offset, (short) field_4_cell_ranges.length); | |||
for( int i=0 ; i!=field_4_cell_ranges.length; i++) | |||
{ | |||
LittleEndian.putShort(data, 18 + 0 + 8 * i + offset, | |||
(short) ((CellRange) field_4_cell_ranges.get(i)).getFirstRow()); | |||
LittleEndian.putShort(data, 18 + 2 + 8 * i + offset, | |||
(short) ((CellRange) field_4_cell_ranges.get(i)).getLastRow()); | |||
LittleEndian.putShort(data, 18 + 4 + 8 * i + offset, | |||
(short) ((CellRange) field_4_cell_ranges.get(i)).getFirstColumn()); | |||
LittleEndian.putShort(data, 18 + 6 + 8 * i + offset, | |||
(short) ((CellRange) field_4_cell_ranges.get(i)).getLastColumn()); | |||
CellRange cr = field_4_cell_ranges[i]; | |||
LittleEndian.putShort(data, 18 + 0 + 8 * i + offset, (short) cr.getFirstRow()); | |||
LittleEndian.putShort(data, 18 + 2 + 8 * i + offset, (short) cr.getLastRow()); | |||
LittleEndian.putShort(data, 18 + 4 + 8 * i + offset, (short) cr.getFirstColumn()); | |||
LittleEndian.putShort(data, 18 + 6 + 8 * i + offset, (short) cr.getLastColumn()); | |||
} | |||
return getRecordSize(); | |||
} | |||
public int getRecordSize() | |||
{ | |||
return 18+8*field_4_cell_ranges.size(); | |||
return 18+8*field_4_cell_ranges.length; | |||
} | |||
/** | |||
@@ -204,20 +198,17 @@ public class CFHeaderRecord extends Record | |||
return sid; | |||
} | |||
public Object clone() | |||
{ | |||
CFHeaderRecord rec = new CFHeaderRecord(); | |||
rec.field_1_numcf = field_1_numcf; | |||
rec.field_2_need_recalculation = field_2_need_recalculation; | |||
rec.field_3_enclosing_cell_range = field_3_enclosing_cell_range; | |||
rec.field_4_cell_ranges = new ArrayList(field_4_cell_ranges.size()); | |||
Iterator iterator = field_4_cell_ranges.iterator(); | |||
while (iterator.hasNext()) | |||
{ | |||
CellRange oldRange = (CellRange)iterator.next(); | |||
rec.field_4_cell_ranges.add(oldRange.cloneCellRange()); | |||
} | |||
return rec; | |||
} | |||
public Object clone() | |||
{ | |||
CFHeaderRecord result = new CFHeaderRecord(); | |||
result.field_1_numcf = field_1_numcf; | |||
result.field_2_need_recalculation = field_2_need_recalculation; | |||
result.field_3_enclosing_cell_range = field_3_enclosing_cell_range; | |||
CellRange[] crs = new CellRange[field_4_cell_ranges.length]; | |||
for (int i = 0; i < crs.length; i++) { | |||
crs[i] = field_4_cell_ranges[i].cloneCellRange(); | |||
} | |||
result.field_4_cell_ranges = crs; | |||
return result; | |||
} | |||
} |
@@ -24,6 +24,7 @@ import org.apache.poi.hssf.record.CFHeaderRecord; | |||
import org.apache.poi.hssf.record.CFRuleRecord; | |||
import org.apache.poi.hssf.record.Record; | |||
import org.apache.poi.hssf.record.RecordInputStream; | |||
import org.apache.poi.hssf.util.Region; | |||
import org.apache.poi.util.POILogFactory; | |||
import org.apache.poi.util.POILogger; | |||
@@ -37,19 +38,38 @@ import org.apache.poi.util.POILogger; | |||
*/ | |||
public final class CFRecordsAggregate extends Record | |||
{ | |||
/** Excel allows up to 3 conditional formating rules */ | |||
private static final int MAX_CONDTIONAL_FORMAT_RULES = 3; | |||
public final static short sid = -2008; // not a real BIFF record | |||
private static POILogger log = POILogFactory.getLogger(CFRecordsAggregate.class); | |||
private static POILogger log = POILogFactory.getLogger(CFRecordsAggregate.class); | |||
private CFHeaderRecord header; | |||
private final CFHeaderRecord header; | |||
// List of CFRuleRecord objects | |||
/** List of CFRuleRecord objects */ | |||
private final List rules; | |||
public CFRecordsAggregate() | |||
{ | |||
header = null; | |||
rules = new ArrayList(3); | |||
private CFRecordsAggregate(CFHeaderRecord pHeader, CFRuleRecord[] pRules) { | |||
if(pHeader == null) { | |||
throw new IllegalArgumentException("header must not be null"); | |||
} | |||
if(pRules == null) { | |||
throw new IllegalArgumentException("rules must not be null"); | |||
} | |||
if(pRules.length > MAX_CONDTIONAL_FORMAT_RULES) { | |||
throw new IllegalArgumentException("No more than " | |||
+ MAX_CONDTIONAL_FORMAT_RULES + " rules may be specified"); | |||
} | |||
header = pHeader; | |||
rules = new ArrayList(3); | |||
for (int i = 0; i < pRules.length; i++) { | |||
rules.add(pRules[i]); | |||
} | |||
} | |||
public CFRecordsAggregate(Region[] regions, CFRuleRecord[] rules) { | |||
this(new CFHeaderRecord(regions), rules); | |||
} | |||
/** | |||
@@ -60,42 +80,46 @@ public final class CFRecordsAggregate extends Record | |||
*/ | |||
public static CFRecordsAggregate createCFAggregate(List recs, int pOffset) | |||
{ | |||
Record rec = ( Record ) recs.get(pOffset); | |||
if (rec.getSid() != CFHeaderRecord.sid) { | |||
throw new IllegalStateException("next record sid was " + rec.getSid() | |||
+ " instead of " + CFHeaderRecord.sid + " as expected"); | |||
} | |||
int offset = pOffset; | |||
CFRecordsAggregate cfRecords = new CFRecordsAggregate(); | |||
ArrayList records = new ArrayList(4); | |||
Record rec = ( Record ) recs.get(offset++); | |||
CFHeaderRecord header = (CFHeaderRecord)rec; | |||
int nRules = header.getNumberOfConditionalFormats(); | |||
if (rec.getSid() == CFHeaderRecord.sid) | |||
{ | |||
records.add(rec); | |||
cfRecords.header = (CFHeaderRecord)rec; | |||
int nRules = cfRecords.header.getNumberOfConditionalFormats(); | |||
int rulesCount = 0; | |||
while( offset<recs.size() && | |||
(rec = (Record)recs.get(offset++)).getSid() == CFRuleRecord.sid && | |||
rec instanceof CFRuleRecord && | |||
rulesCount++ < nRules | |||
) | |||
{ | |||
records.add(rec); | |||
cfRecords.rules.add(rec); | |||
CFRuleRecord[] rules = new CFRuleRecord[nRules]; | |||
int offset = pOffset; | |||
int countFound = 0; | |||
while (countFound < rules.length) { | |||
offset++; | |||
if(offset>=recs.size()) { | |||
break; | |||
} | |||
rec = (Record)recs.get(offset); | |||
if(rec instanceof CFRuleRecord) { | |||
rules[countFound] = (CFRuleRecord) rec; | |||
countFound++; | |||
} else { | |||
break; | |||
} | |||
} | |||
if (nRules != cfRecords.rules.size()) | |||
if (countFound < nRules) | |||
{ // TODO -(MAR-2008) can this ever happen? write junit | |||
if (log.check(POILogger.DEBUG)) | |||
{ | |||
if (log.check(POILogger.DEBUG)) | |||
{ | |||
log.log(POILogger.DEBUG, "Expected " + nRules + " Conditional Formats, " | |||
+ "but found " + cfRecords.rules.size() + " rules"); | |||
} | |||
cfRecords.header.setNumberOfConditionalFormats(nRules); | |||
log.log(POILogger.DEBUG, "Expected " + nRules + " Conditional Formats, " | |||
+ "but found " + countFound + " rules"); | |||
} | |||
header.setNumberOfConditionalFormats(nRules); | |||
CFRuleRecord[] lessRules = new CFRuleRecord[countFound]; | |||
System.arraycopy(rules, 0, lessRules, 0, countFound); | |||
rules = lessRules; | |||
} | |||
return cfRecords; | |||
return new CFRecordsAggregate(header, rules); | |||
} | |||
/** | |||
@@ -104,22 +128,17 @@ public final class CFRecordsAggregate extends Record | |||
*/ | |||
public CFRecordsAggregate cloneCFAggregate() | |||
{ | |||
ArrayList records = new ArrayList(this.rules.size()+1); | |||
records.add(this.header.clone()); | |||
for (int i=0; i<this.rules.size();i++) | |||
{ | |||
Record rec = (Record)((Record)this.rules.get(i)).clone(); | |||
records.add(rec); | |||
} | |||
return createCFAggregate(records, 0); | |||
CFRuleRecord[] newRecs = new CFRuleRecord[rules.size()]; | |||
for (int i = 0; i < newRecs.length; i++) { | |||
newRecs[i] = (CFRuleRecord) getRule(i).clone(); | |||
} | |||
return new CFRecordsAggregate((CFHeaderRecord) header.clone(), newRecs); | |||
} | |||
/** You never fill an aggregate */ | |||
protected void fillFields(RecordInputStream in) | |||
{ | |||
// You never fill an aggregate record | |||
} | |||
public short getSid() | |||
@@ -139,17 +158,14 @@ public final class CFRecordsAggregate extends Record | |||
public int serialize(int offset, byte[] data) | |||
{ | |||
int pos = offset; | |||
if( header != null && rules.size()>0 ) | |||
{ | |||
header.setNumberOfConditionalFormats(rules.size()); | |||
int nRules = rules.size(); | |||
header.setNumberOfConditionalFormats(nRules); | |||
pos += (( Record ) header).serialize(pos, data); | |||
int pos = offset; | |||
for(Iterator itr = rules.iterator(); itr.hasNext();) | |||
{ | |||
pos += (( Record ) itr.next()).serialize(pos, data); | |||
} | |||
pos += header.serialize(pos, data); | |||
for(int i=0; i< nRules; i++) { | |||
pos += getRule(i).serialize(pos, data); | |||
} | |||
return pos - offset; | |||
} | |||
@@ -160,19 +176,37 @@ public final class CFRecordsAggregate extends Record | |||
} | |||
/** | |||
* @return the header | |||
* @return the header. Never <code>null</code>. | |||
*/ | |||
public CFHeaderRecord getHeader() | |||
{ | |||
return header; | |||
} | |||
/** | |||
* @return the rules | |||
*/ | |||
public List getRules() | |||
{ | |||
return rules; | |||
private void checkRuleIndex(int idx) { | |||
if(idx < 0 || idx >= rules.size()) { | |||
throw new IllegalArgumentException("Bad rule record index (" + idx | |||
+ ") nRules=" + rules.size()); | |||
} | |||
} | |||
public CFRuleRecord getRule(int idx) { | |||
checkRuleIndex(idx); | |||
return (CFRuleRecord) rules.get(idx); | |||
} | |||
public void setRule(int idx, CFRuleRecord r) { | |||
checkRuleIndex(idx); | |||
rules.set(idx, r); | |||
} | |||
public void addRule(CFRuleRecord r) { | |||
if(rules.size() >= MAX_CONDTIONAL_FORMAT_RULES) { | |||
throw new IllegalStateException("Cannot have more than " | |||
+ MAX_CONDTIONAL_FORMAT_RULES + " conditional format rules"); | |||
} | |||
rules.add(r); | |||
header.setNumberOfConditionalFormats(rules.size()); | |||
} | |||
public int getNumberOfRules() { | |||
return rules.size(); | |||
} | |||
/** |
@@ -17,79 +17,127 @@ | |||
package org.apache.poi.hssf.record.cf; | |||
import java.util.ArrayList; | |||
import java.util.Arrays; | |||
import java.util.List; | |||
import org.apache.poi.hssf.util.Region; | |||
/** | |||
* CellRange.java | |||
* Created on January 22, 2008, 10:05 PM | |||
* | |||
* @author Dmitriy Kumshayev | |||
*/ | |||
public class CellRange | |||
public final class CellRange | |||
{ | |||
private int field_1_first_row; | |||
private int field_2_last_row; | |||
private short field_3_first_column; | |||
private short field_4_last_column; | |||
public CellRange(int firstRow, int lastRow, short firstColumn, short lastColumn) | |||
{ | |||
this.field_1_first_row = firstRow; | |||
this.field_2_last_row = lastRow; | |||
this.field_3_first_column = firstColumn; | |||
this.field_4_last_column = lastColumn; | |||
validateRegion(); | |||
} | |||
private void validateRegion() | |||
{ | |||
if( field_1_first_row < 0 || | |||
field_2_last_row < -1 || | |||
field_3_first_column < 0 || | |||
field_4_last_column < -1 || | |||
field_2_last_row>=0 && field_2_last_row<field_1_first_row || | |||
field_4_last_column>=0 && field_4_last_column<field_3_first_column | |||
) | |||
{ | |||
throw new IllegalArgumentException("Invalid cell region "+toString()); | |||
} | |||
} | |||
public int getFirstRow() | |||
/** | |||
* max index for both row and column<p/> | |||
* | |||
* Note - this value converts to <tt>-1</tt> when cast to a <tt>short</tt> | |||
*/ | |||
private static final int MAX_INDEX = Integer.MAX_VALUE; | |||
private static final Region[] EMPTY_REGION_ARRAY = { }; | |||
private int _firstRow; | |||
private int _lastRow; | |||
private int _firstColumn; | |||
private int _lastColumn; | |||
/** | |||
* | |||
* @param firstRow | |||
* @param lastRow pass <tt>-1</tt> for full column ranges | |||
* @param firstColumn | |||
* @param lastColumn pass <tt>-1</tt> for full row ranges | |||
*/ | |||
public CellRange(int firstRow, int lastRow, int firstColumn, int lastColumn) | |||
{ | |||
return field_1_first_row; | |||
if(!isValid(firstRow, lastRow, firstColumn, lastColumn)) { | |||
throw new IllegalArgumentException("invalid cell range (" + firstRow + ", " + lastRow | |||
+ ", " + firstColumn + ", " + lastColumn + ")"); | |||
} | |||
_firstRow = firstRow; | |||
_lastRow = convertM1ToMax(lastRow); | |||
_firstColumn = firstColumn; | |||
_lastColumn = convertM1ToMax(lastColumn); | |||
} | |||
private void setFirstRow(int firstRow) | |||
{ | |||
this.field_1_first_row = firstRow; | |||
private static int convertM1ToMax(int lastIx) { | |||
if(lastIx < 0) { | |||
return MAX_INDEX; | |||
} | |||
return lastIx; | |||
} | |||
public int getLastRow() | |||
{ | |||
return field_2_last_row; | |||
private static int convertMaxToM1(int lastIx) { | |||
if(lastIx == MAX_INDEX) { | |||
return -1; | |||
} | |||
return lastIx; | |||
} | |||
public boolean isFullColumnRange() { | |||
return _firstColumn == 0 && _lastColumn == MAX_INDEX; | |||
} | |||
public boolean isFullRowRange() { | |||
return _firstRow == 0 && _lastRow == MAX_INDEX; | |||
} | |||
public CellRange(Region r) { | |||
this(r.getRowFrom(), r.getRowTo(), r.getColumnFrom(), r.getColumnTo()); | |||
} | |||
private void setLastRow(int lastRow) | |||
private static boolean isValid(int firstRow, int lastRow, int firstColumn, int lastColumn) | |||
{ | |||
this.field_2_last_row = lastRow; | |||
if(lastRow == -1) { | |||
if(firstRow !=0) { | |||
return false; | |||
} | |||
} | |||
if(firstRow < 0 || lastRow < -1) { | |||
return false; | |||
} | |||
if(lastColumn == -1) { | |||
if(firstColumn !=0) { | |||
return false; | |||
} | |||
} | |||
if(firstColumn < 0 || lastColumn < -1) { | |||
return false; | |||
} | |||
return true; | |||
} | |||
public short getFirstColumn() | |||
public int getFirstRow() | |||
{ | |||
return field_3_first_column; | |||
return _firstRow; | |||
} | |||
private void setFirstColumn(short firstColumn) | |||
/** | |||
* @return <tt>-1</tt> for whole column ranges | |||
*/ | |||
public int getLastRow() | |||
{ | |||
this.field_3_first_column = firstColumn; | |||
return convertMaxToM1(_lastRow); | |||
} | |||
public short getLastColumn() | |||
public int getFirstColumn() | |||
{ | |||
return field_4_last_column; | |||
return _firstColumn; | |||
} | |||
private void setLastColumn(short lastColumn) | |||
/** | |||
* @return <tt>-1</tt> for whole row ranges | |||
*/ | |||
public int getLastColumn() | |||
{ | |||
this.field_4_last_column = lastColumn; | |||
return convertMaxToM1(_lastColumn); | |||
} | |||
public static final int NO_INTERSECTION = 1; | |||
public static final int OVERLAP = 2; | |||
/** first range is within the second range */ | |||
public static final int INSIDE = 3; | |||
/** first range encloses or is equal to the second */ | |||
public static final int ENCLOSES = 4; | |||
/** | |||
@@ -101,30 +149,31 @@ public class CellRange | |||
* NO_INTERSECTION - the specified range is outside of this range;<br/> | |||
* OVERLAP - both ranges partially overlap;<br/> | |||
* INSIDE - the specified range is inside of this one<br/> | |||
* ENCLOSES - the specified range encloses this range<br/> | |||
* ENCLOSES - the specified range encloses (possibly exactly the same as) this range<br/> | |||
*/ | |||
public int intersect(CellRange another ) | |||
{ | |||
int firstRow = another.getFirstRow(); | |||
int lastRow = another.getLastRow(); | |||
short firstCol = another.getFirstColumn(); | |||
short lastCol = another.getLastColumn(); | |||
int firstRow = another.getFirstRow(); | |||
int lastRow = another.getLastRow(); | |||
int firstCol = another.getFirstColumn(); | |||
int lastCol = another.getLastColumn(); | |||
if | |||
( | |||
gt(this.getFirstRow(),lastRow) || | |||
lt(this.getLastRow(),firstRow) || | |||
gt(this.getFirstColumn(),lastCol) || | |||
lt(this.getLastColumn(),firstCol) | |||
gt(getFirstRow(),lastRow) || | |||
lt(getLastRow(),firstRow) || | |||
gt(getFirstColumn(),lastCol) || | |||
lt(getLastColumn(),firstCol) | |||
) | |||
{ | |||
return NO_INTERSECTION; | |||
} | |||
else if( this.contains(another) ) | |||
else if( contains(another) ) | |||
{ | |||
return INSIDE; | |||
} | |||
else if( another.contains(this) ) | |||
else if( another.contains(this)) | |||
{ | |||
return ENCLOSES; | |||
} | |||
@@ -134,7 +183,234 @@ public class CellRange | |||
} | |||
} | |||
/** | |||
* Do all possible cell merges between cells of the list so that:<br> | |||
* <li>if a cell range is completely inside of another cell range, it gets removed from the list | |||
* <li>if two cells have a shared border, merge them into one bigger cell range | |||
* @param cellRangeList | |||
* @return updated List of cell ranges | |||
*/ | |||
public static CellRange[] mergeCellRanges(CellRange[] cellRanges) { | |||
if(cellRanges.length < 1) { | |||
return cellRanges; | |||
} | |||
List temp = mergeCellRanges(Arrays.asList(cellRanges)); | |||
return toArray(temp); | |||
} | |||
private static List mergeCellRanges(List cellRangeList) | |||
{ | |||
while(cellRangeList.size() > 1) | |||
{ | |||
boolean somethingGotMerged = false; | |||
for( int i=0; i<cellRangeList.size(); i++) | |||
{ | |||
CellRange range1 = (CellRange)cellRangeList.get(i); | |||
for( int j=i+1; j<cellRangeList.size(); j++) | |||
{ | |||
CellRange range2 = (CellRange)cellRangeList.get(j); | |||
CellRange[] mergeResult = mergeRanges(range1, range2); | |||
if(mergeResult == null) { | |||
continue; | |||
} | |||
somethingGotMerged = true; | |||
// overwrite range1 with first result | |||
cellRangeList.set(i, mergeResult[0]); | |||
// remove range2 | |||
cellRangeList.remove(j--); | |||
// add any extra results beyond the first | |||
for(int k=1; k<mergeResult.length; k++) { | |||
j++; | |||
cellRangeList.add(j, mergeResult[k]); | |||
} | |||
} | |||
} | |||
if(!somethingGotMerged) { | |||
break; | |||
} | |||
} | |||
return cellRangeList; | |||
} | |||
/** | |||
* @return the new range(s) to replace the supplied ones. <code>null</code> if no merge is possible | |||
*/ | |||
private static CellRange[] mergeRanges(CellRange range1, CellRange range2) { | |||
int x = range1.intersect(range2); | |||
switch(x) | |||
{ | |||
case CellRange.NO_INTERSECTION: | |||
if( range1.hasExactSharedBorder(range2)) | |||
{ | |||
return new CellRange[] { range1.createEnclosingCellRange(range2), }; | |||
} | |||
// else - No intersection and no shared border: do nothing | |||
return null; | |||
case CellRange.OVERLAP: | |||
return resolveRangeOverlap(range1, range2); | |||
case CellRange.INSIDE: | |||
// Remove range2, since it is completely inside of range1 | |||
return new CellRange[] { range1, }; | |||
case CellRange.ENCLOSES: | |||
// range2 encloses range1, so replace it with the enclosing one | |||
return new CellRange[] { range2, }; | |||
} | |||
throw new RuntimeException("unexpected intersection result (" + x + ")"); | |||
} | |||
// TODO - write junit test for this | |||
static CellRange[] resolveRangeOverlap(CellRange rangeA, CellRange rangeB) { | |||
if(rangeA.isFullColumnRange()) { | |||
if(rangeB.isFullRowRange()) { | |||
// Excel seems to leave these unresolved | |||
return null; | |||
} | |||
return rangeA.sliceUp(rangeB); | |||
} | |||
if(rangeA.isFullRowRange()) { | |||
if(rangeB.isFullColumnRange()) { | |||
// Excel seems to leave these unresolved | |||
return null; | |||
} | |||
return rangeA.sliceUp(rangeB); | |||
} | |||
if(rangeB.isFullColumnRange()) { | |||
return rangeB.sliceUp(rangeA); | |||
} | |||
if(rangeB.isFullRowRange()) { | |||
return rangeB.sliceUp(rangeA); | |||
} | |||
return rangeA.sliceUp(rangeB); | |||
} | |||
/** | |||
* @param range never a full row or full column range | |||
* @return an array including <b>this</b> <tt>CellRange</tt> and all parts of <tt>range</tt> | |||
* outside of this range | |||
*/ | |||
private CellRange[] sliceUp(CellRange range) { | |||
List temp = new ArrayList(); | |||
// Chop up range horizontally and vertically | |||
temp.add(range); | |||
if(!isFullColumnRange()) { | |||
temp = cutHorizontally(_firstRow, temp); | |||
temp = cutHorizontally(_lastRow+1, temp); | |||
} | |||
if(!isFullRowRange()) { | |||
temp = cutVertically(_firstColumn, temp); | |||
temp = cutVertically(_lastColumn+1, temp); | |||
} | |||
CellRange[] crParts = toArray(temp); | |||
// form result array | |||
temp.clear(); | |||
temp.add(this); | |||
for (int i = 0; i < crParts.length; i++) { | |||
CellRange crPart = crParts[i]; | |||
// only include parts that are not enclosed by this | |||
if(intersect(crPart) != ENCLOSES) { | |||
temp.add(crPart); | |||
} | |||
} | |||
return toArray(temp); | |||
} | |||
private static List cutHorizontally(int cutRow, List input) { | |||
List result = new ArrayList(); | |||
CellRange[] crs = toArray(input); | |||
for (int i = 0; i < crs.length; i++) { | |||
CellRange cr = crs[i]; | |||
if(cr._firstRow < cutRow && cutRow < cr._lastRow) { | |||
result.add(new CellRange(cr._firstRow, cutRow, cr._firstColumn, cr._lastColumn)); | |||
result.add(new CellRange(cutRow+1, cr._lastRow, cr._firstColumn, cr._lastColumn)); | |||
} else { | |||
result.add(cr); | |||
} | |||
} | |||
return result; | |||
} | |||
private static List cutVertically(int cutColumn, List input) { | |||
List result = new ArrayList(); | |||
CellRange[] crs = toArray(input); | |||
for (int i = 0; i < crs.length; i++) { | |||
CellRange cr = crs[i]; | |||
if(cr._firstColumn < cutColumn && cutColumn < cr._lastColumn) { | |||
result.add(new CellRange(cr._firstRow, cr._lastRow, cr._firstColumn, cutColumn)); | |||
result.add(new CellRange(cr._firstRow, cr._lastRow, cutColumn+1, cr._lastColumn)); | |||
} else { | |||
result.add(cr); | |||
} | |||
} | |||
return result; | |||
} | |||
private static CellRange[] toArray(List temp) { | |||
CellRange[] result = new CellRange[temp.size()]; | |||
temp.toArray(result); | |||
return result; | |||
} | |||
/** | |||
* Convert array of regions to a List of CellRange objects | |||
* | |||
* @param regions | |||
* @return List of CellRange objects | |||
*/ | |||
public static CellRange[] convertRegionsToCellRanges(Region[] regions) | |||
{ | |||
CellRange[] result = new CellRange[regions.length]; | |||
for( int i=0; i<regions.length; i++) | |||
{ | |||
result[i] = new CellRange(regions[i]); | |||
} | |||
return result; | |||
} | |||
/** | |||
* Convert a List of CellRange objects to an array of regions | |||
* | |||
* @param List of CellRange objects | |||
* @return regions | |||
*/ | |||
public static Region[] convertCellRangesToRegions(CellRange[] cellRanges) | |||
{ | |||
int size = cellRanges.length; | |||
if(size < 1) { | |||
return EMPTY_REGION_ARRAY; | |||
} | |||
Region[] result = new Region[size]; | |||
for (int i = 0; i != size; i++) | |||
{ | |||
result[i] = cellRanges[i].convertToRegion(); | |||
} | |||
return result; | |||
} | |||
private Region convertToRegion() { | |||
int lastRow = convertMaxToM1(_lastRow); | |||
int lastColumn = convertMaxToM1(_lastColumn); | |||
return new Region(_firstRow, (short)_firstColumn, lastRow, (short)lastColumn); | |||
} | |||
/** | |||
* Check if the specified range is located inside of this cell range. | |||
* | |||
@@ -145,44 +421,52 @@ public class CellRange | |||
{ | |||
int firstRow = range.getFirstRow(); | |||
int lastRow = range.getLastRow(); | |||
short firstCol = range.getFirstColumn(); | |||
short lastCol = range.getLastColumn(); | |||
return le(this.getFirstRow(), firstRow) && ge(this.getLastRow(), lastRow) | |||
&& le(this.getFirstColumn(), firstCol) && ge(this.getLastColumn(), lastCol); | |||
int firstCol = range.getFirstColumn(); | |||
int lastCol = range.getLastColumn(); | |||
return le(getFirstRow(), firstRow) && ge(getLastRow(), lastRow) | |||
&& le(getFirstColumn(), firstCol) && ge(getLastColumn(), lastCol); | |||
} | |||
public boolean contains(int row, short column) | |||
{ | |||
return le(this.getFirstRow(), row) && ge(this.getLastRow(), row) | |||
&& le(this.getFirstColumn(), column) && ge(this.getLastColumn(), column); | |||
return le(getFirstRow(), row) && ge(getLastRow(), row) | |||
&& le(getFirstColumn(), column) && ge(getLastColumn(), column); | |||
} | |||
/** | |||
* Check if the specified cell range has a shared border with the current range. | |||
* | |||
* @return true if the ranges have a shared border. | |||
*/ | |||
public boolean hasSharedBorder(CellRange range) | |||
* Check if the specified cell range has a shared border with the current range. | |||
* | |||
* @return <code>true</code> if the ranges have a complete shared border (i.e. | |||
* the two ranges together make a simple rectangular region. | |||
*/ | |||
public boolean hasExactSharedBorder(CellRange range) | |||
{ | |||
int firstRow = range.getFirstRow(); | |||
int lastRow = range.getLastRow(); | |||
short firstCol = range.getFirstColumn(); | |||
short lastCol = range.getLastColumn(); | |||
return | |||
(this.getFirstRow()>0 && this.getFirstRow() - 1 == lastRow || firstRow>0 &&this.getLastRow() == firstRow -1)&& | |||
(this.getFirstColumn() == firstCol) && | |||
(this.getLastColumn() == lastCol) || | |||
(this.getFirstColumn()>0 && this.getFirstColumn() - 1 == lastCol || firstCol>0 && this.getLastColumn() == firstCol -1) && | |||
(this.getFirstRow() == firstRow) && | |||
(this.getLastRow() == lastRow) | |||
; | |||
int oFirstRow = range._firstRow; | |||
int oLastRow = range._lastRow; | |||
int oFirstCol = range._firstColumn; | |||
int oLastCol = range._lastColumn; | |||
if (_firstRow > 0 && _firstRow-1 == oLastRow || | |||
oFirstRow > 0 && oFirstRow-1 == _lastRow) { | |||
// ranges have a horizontal border in common | |||
// make sure columns are identical: | |||
return _firstColumn == oFirstCol && _lastColumn == oLastCol; | |||
} | |||
if (_firstColumn>0 && _firstColumn - 1 == oLastCol || | |||
oFirstCol>0 && _lastColumn == oFirstCol -1) { | |||
// ranges have a vertical border in common | |||
// make sure rows are identical: | |||
return _firstRow == oFirstRow && _lastRow == oLastRow; | |||
} | |||
return false; | |||
} | |||
/** | |||
* Create an enclosing CellRange for the two cell ranges. | |||
* | |||
* @return enclosing CellRange | |||
*/ | |||
/** | |||
* Create an enclosing CellRange for the two cell ranges. | |||
* | |||
* @return enclosing CellRange | |||
*/ | |||
public CellRange createEnclosingCellRange(CellRange range) | |||
{ | |||
if( range == null) | |||
@@ -206,18 +490,6 @@ public class CellRange | |||
{ | |||
return new CellRange(getFirstRow(),getLastRow(),getFirstColumn(),getLastColumn()); | |||
} | |||
/** | |||
* Copy data from antother cell range to this cell range | |||
* @param cr - another cell range | |||
*/ | |||
public void setCellRange(CellRange cr) | |||
{ | |||
setFirstRow(cr.getFirstRow()); | |||
setLastRow(cr.getLastRow()); | |||
setFirstColumn(cr.getFirstColumn()); | |||
setLastColumn(cr.getLastColumn()); | |||
} | |||
/** | |||
* @return true if a < b | |||
@@ -253,7 +525,7 @@ public class CellRange | |||
public String toString() | |||
{ | |||
return "("+this.getFirstRow()+","+this.getLastRow()+","+this.getFirstColumn()+","+this.getLastColumn()+")"; | |||
return "("+getFirstRow()+","+getLastRow()+","+getFirstColumn()+","+getLastColumn()+")"; | |||
} | |||
} |
@@ -26,103 +26,167 @@ import org.apache.poi.hssf.record.cf.BorderFormatting; | |||
* @author Dmitriy Kumshayev | |||
* | |||
*/ | |||
public class HSSFBorderFormatting | |||
public final class HSSFBorderFormatting | |||
{ | |||
/** | |||
* No border | |||
*/ | |||
/** No border */ | |||
public final static short BORDER_NONE = BorderFormatting.BORDER_NONE; | |||
/** Thin border */ | |||
public final static short BORDER_THIN = BorderFormatting.BORDER_THIN; | |||
/** Medium border */ | |||
public final static short BORDER_MEDIUM = BorderFormatting.BORDER_MEDIUM; | |||
/** dash border */ | |||
public final static short BORDER_DASHED = BorderFormatting.BORDER_DASHED; | |||
/** dot border */ | |||
public final static short BORDER_HAIR = BorderFormatting.BORDER_HAIR; | |||
/** Thick border */ | |||
public final static short BORDER_THICK = BorderFormatting.BORDER_THICK; | |||
/** double-line border */ | |||
public final static short BORDER_DOUBLE = BorderFormatting.BORDER_DOUBLE; | |||
/** hair-line border */ | |||
public final static short BORDER_DOTTED = BorderFormatting.BORDER_DOTTED; | |||
/** Medium dashed border */ | |||
public final static short BORDER_MEDIUM_DASHED = BorderFormatting.BORDER_MEDIUM_DASHED; | |||
/** dash-dot border */ | |||
public final static short BORDER_DASH_DOT = BorderFormatting.BORDER_DASH_DOT; | |||
/** medium dash-dot border */ | |||
public final static short BORDER_MEDIUM_DASH_DOT = BorderFormatting.BORDER_MEDIUM_DASH_DOT; | |||
/** dash-dot-dot border */ | |||
public final static short BORDER_DASH_DOT_DOT = BorderFormatting.BORDER_DASH_DOT_DOT; | |||
/** medium dash-dot-dot border */ | |||
public final static short BORDER_MEDIUM_DASH_DOT_DOT = BorderFormatting.BORDER_MEDIUM_DASH_DOT_DOT; | |||
/** slanted dash-dot border */ | |||
public final static short BORDER_SLANTED_DASH_DOT = BorderFormatting.BORDER_SLANTED_DASH_DOT; | |||
public final static short BORDER_NONE = BorderFormatting.BORDER_NONE; | |||
/** | |||
* Thin border | |||
*/ | |||
public final static short BORDER_THIN = BorderFormatting.BORDER_THIN; | |||
/** | |||
* Medium border | |||
*/ | |||
private final BorderFormatting borderFormatting; | |||
public HSSFBorderFormatting() | |||
{ | |||
borderFormatting = new BorderFormatting(); | |||
} | |||
public final static short BORDER_MEDIUM = BorderFormatting.BORDER_MEDIUM; | |||
protected BorderFormatting getBorderFormattingBlock() | |||
{ | |||
return borderFormatting; | |||
} | |||
/** | |||
* dash border | |||
*/ | |||
public short getBorderBottom() | |||
{ | |||
return borderFormatting.getBorderBottom(); | |||
} | |||
public final static short BORDER_DASHED = BorderFormatting.BORDER_DASHED; | |||
public short getBorderDiagonal() | |||
{ | |||
return borderFormatting.getBorderDiagonal(); | |||
} | |||
/** | |||
* dot border | |||
*/ | |||
public short getBorderLeft() | |||
{ | |||
return borderFormatting.getBorderLeft(); | |||
} | |||
public final static short BORDER_HAIR = BorderFormatting.BORDER_HAIR; | |||
public short getBorderRight() | |||
{ | |||
return borderFormatting.getBorderRight(); | |||
} | |||
/** | |||
* Thick border | |||
*/ | |||
public short getBorderTop() | |||
{ | |||
return borderFormatting.getBorderTop(); | |||
} | |||
public final static short BORDER_THICK = BorderFormatting.BORDER_THICK; | |||
public short getBottomBorderColor() | |||
{ | |||
return borderFormatting.getBottomBorderColor(); | |||
} | |||
/** | |||
* double-line border | |||
*/ | |||
public short getDiagonalBorderColor() | |||
{ | |||
return borderFormatting.getDiagonalBorderColor(); | |||
} | |||
public final static short BORDER_DOUBLE = BorderFormatting.BORDER_DOUBLE; | |||
public short getLeftBorderColor() | |||
{ | |||
return borderFormatting.getLeftBorderColor(); | |||
} | |||
/** | |||
* hair-line border | |||
*/ | |||
public short getRightBorderColor() | |||
{ | |||
return borderFormatting.getRightBorderColor(); | |||
} | |||
public final static short BORDER_DOTTED = BorderFormatting.BORDER_DOTTED; | |||
public short getTopBorderColor() | |||
{ | |||
return borderFormatting.getTopBorderColor(); | |||
} | |||
/** | |||
* Medium dashed border | |||
*/ | |||
public boolean isBackwardDiagonalOn() | |||
{ | |||
return borderFormatting.isBackwardDiagonalOn(); | |||
} | |||
public final static short BORDER_MEDIUM_DASHED = BorderFormatting.BORDER_MEDIUM_DASHED; | |||
public boolean isForwardDiagonalOn() | |||
{ | |||
return borderFormatting.isForwardDiagonalOn(); | |||
} | |||
/** | |||
* dash-dot border | |||
*/ | |||
public void setBackwardDiagonalOn(boolean on) | |||
{ | |||
borderFormatting.setBackwardDiagonalOn(on); | |||
} | |||
public final static short BORDER_DASH_DOT = BorderFormatting.BORDER_DASH_DOT; | |||
public void setBorderBottom(short border) | |||
{ | |||
borderFormatting.setBorderBottom(border); | |||
} | |||
/** | |||
* medium dash-dot border | |||
*/ | |||
public void setBorderDiagonal(short border) | |||
{ | |||
borderFormatting.setBorderDiagonal(border); | |||
} | |||
public final static short BORDER_MEDIUM_DASH_DOT = BorderFormatting.BORDER_MEDIUM_DASH_DOT; | |||
public void setBorderLeft(short border) | |||
{ | |||
borderFormatting.setBorderLeft(border); | |||
} | |||
/** | |||
* dash-dot-dot border | |||
*/ | |||
public void setBorderRight(short border) | |||
{ | |||
borderFormatting.setBorderRight(border); | |||
} | |||
public final static short BORDER_DASH_DOT_DOT = BorderFormatting.BORDER_DASH_DOT_DOT; | |||
public void setBorderTop(short border) | |||
{ | |||
borderFormatting.setBorderTop(border); | |||
} | |||
/** | |||
* medium dash-dot-dot border | |||
*/ | |||
public void setBottomBorderColor(short color) | |||
{ | |||
borderFormatting.setBottomBorderColor(color); | |||
} | |||
public final static short BORDER_MEDIUM_DASH_DOT_DOT = BorderFormatting.BORDER_MEDIUM_DASH_DOT_DOT; | |||
public void setDiagonalBorderColor(short color) | |||
{ | |||
borderFormatting.setDiagonalBorderColor(color); | |||
} | |||
/** | |||
* slanted dash-dot border | |||
*/ | |||
public void setForwardDiagonalOn(boolean on) | |||
{ | |||
borderFormatting.setForwardDiagonalOn(on); | |||
} | |||
public final static short BORDER_SLANTED_DASH_DOT = BorderFormatting.BORDER_SLANTED_DASH_DOT; | |||
public void setLeftBorderColor(short color) | |||
{ | |||
borderFormatting.setLeftBorderColor(color); | |||
} | |||
private BorderFormatting borderFormatting; | |||
public HSSFBorderFormatting() | |||
public void setRightBorderColor(short color) | |||
{ | |||
borderFormatting = new BorderFormatting(); | |||
borderFormatting.setRightBorderColor(color); | |||
} | |||
protected BorderFormatting getBorderFormattingBlock() | |||
public void setTopBorderColor(short color) | |||
{ | |||
return borderFormatting; | |||
borderFormatting.setTopBorderColor(color); | |||
} | |||
} |
@@ -16,9 +16,7 @@ | |||
==================================================================== */ | |||
package org.apache.poi.hssf.usermodel; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import org.apache.poi.hssf.model.Workbook; | |||
import org.apache.poi.hssf.record.CFHeaderRecord; | |||
import org.apache.poi.hssf.record.CFRuleRecord; | |||
import org.apache.poi.hssf.record.aggregates.CFRecordsAggregate; | |||
@@ -86,13 +84,9 @@ import org.apache.poi.hssf.util.Region; | |||
*/ | |||
public final class HSSFConditionalFormatting | |||
{ | |||
private final HSSFSheet sheet; | |||
private final Workbook workbook; | |||
private final CFRecordsAggregate cfAggregate; | |||
HSSFConditionalFormatting(HSSFSheet sheet) { | |||
this(sheet, new CFRecordsAggregate()); | |||
} | |||
HSSFConditionalFormatting(HSSFSheet sheet, CFRecordsAggregate cfAggregate) | |||
{ | |||
if(sheet == null) { | |||
@@ -101,36 +95,25 @@ public final class HSSFConditionalFormatting | |||
if(cfAggregate == null) { | |||
throw new IllegalArgumentException("cfAggregate must not be null"); | |||
} | |||
this.sheet = sheet; | |||
workbook = sheet.workbook.getWorkbook(); | |||
this.cfAggregate = cfAggregate; | |||
} | |||
CFRecordsAggregate getCFRecordsAggregate() { | |||
return cfAggregate; | |||
} | |||
public void setFormattingRegions(Region[] regions) | |||
{ | |||
if( regions != null) | |||
{ | |||
CFHeaderRecord header = cfAggregate.getHeader(); | |||
header.setCellRanges(mergeCellRanges(toCellRangeList(regions))); | |||
} | |||
} | |||
/** | |||
* @return array of <tt>Region</tt>s. never <code>null</code> | |||
* @return array of <tt>Region</tt>s. never <code>null</code> | |||
*/ | |||
public Region[] getFormattingRegions() | |||
{ | |||
CFHeaderRecord cfh = cfAggregate.getHeader(); | |||
List cellRanges = cfh.getCellRanges(); | |||
return toRegionArray(cellRanges); | |||
CellRange[] cellRanges = cfh.getCellRanges(); | |||
return CellRange.convertCellRangesToRegions(cellRanges); | |||
} | |||
/** | |||
* set a Conditional Formatting rule at position idx. | |||
* Replaces an existing Conditional Formatting rule at position idx. | |||
* Excel allows to create up to 3 Conditional Formatting rules. | |||
* This method can be useful to modify existing Conditional Formatting rules. | |||
* | |||
@@ -139,11 +122,7 @@ public final class HSSFConditionalFormatting | |||
*/ | |||
public void setRule(int idx, HSSFConditionalFormattingRule cfRule) | |||
{ | |||
if (idx < 0 || idx > 2) { | |||
throw new IllegalArgumentException("idx must be between 0 and 2 but was (" | |||
+ idx + ")"); | |||
} | |||
cfAggregate.getRules().set(idx, cfRule); | |||
cfAggregate.setRule(idx, cfRule.getCfRuleRecord()); | |||
} | |||
/** | |||
@@ -153,136 +132,24 @@ public final class HSSFConditionalFormatting | |||
*/ | |||
public void addRule(HSSFConditionalFormattingRule cfRule) | |||
{ | |||
cfAggregate.getRules().add(cfRule); | |||
cfAggregate.addRule(cfRule.getCfRuleRecord()); | |||
} | |||
/** | |||
* get a Conditional Formatting rule at position idx. | |||
* @param idx | |||
* @return a Conditional Formatting rule at position idx. | |||
* @return the Conditional Formatting rule at position idx. | |||
*/ | |||
public HSSFConditionalFormattingRule getRule(int idx) | |||
{ | |||
CFRuleRecord ruleRecord = (CFRuleRecord)cfAggregate.getRules().get(idx); | |||
return new HSSFConditionalFormattingRule(sheet.workbook, ruleRecord); | |||
CFRuleRecord ruleRecord = cfAggregate.getRule(idx); | |||
return new HSSFConditionalFormattingRule(workbook, ruleRecord); | |||
} | |||
/** | |||
* @return number of Conditional Formatting rules. | |||
*/ | |||
public int getNumbOfRules() | |||
public int getNumberOfRules() | |||
{ | |||
return cfAggregate.getRules().size(); | |||
} | |||
/** | |||
* Do all possible cell merges between cells of the list so that:<br> | |||
* <li>if a cell range is completely inside of another cell range, it gets removed from the list | |||
* <li>if two cells have a shared border, merge them into one bigger cell range | |||
* @param cellRangeList | |||
* @return updated List of cell ranges | |||
*/ | |||
private static List mergeCellRanges(List cellRangeList) | |||
{ | |||
boolean merged = false; | |||
do | |||
{ | |||
merged = false; | |||
if( cellRangeList.size()>1 ) | |||
{ | |||
for( int i=0; i<cellRangeList.size(); i++) | |||
{ | |||
CellRange range1 = (CellRange)cellRangeList.get(i); | |||
for( int j=i+1; j<cellRangeList.size(); j++) | |||
{ | |||
CellRange range2 = (CellRange)cellRangeList.get(j); | |||
switch(range1.intersect(range2)) | |||
{ | |||
case CellRange.NO_INTERSECTION: | |||
{ | |||
if( range1.hasSharedBorder(range2)) | |||
{ | |||
cellRangeList.set(i, range1.createEnclosingCellRange(range2)); | |||
cellRangeList.remove(j--); | |||
merged = true; | |||
} | |||
else | |||
{ | |||
// No intersection and no shared border: do nothing | |||
} | |||
break; | |||
} | |||
case CellRange.OVERLAP: | |||
{ | |||
// TODO split and re-merge the intersected area | |||
break; | |||
} | |||
case CellRange.INSIDE: | |||
{ | |||
// Remove range2, since it is completely inside of range1 | |||
cellRangeList.remove(j--); | |||
merged = true; | |||
break; | |||
} | |||
case CellRange.ENCLOSES: | |||
{ | |||
// range2 encloses range1, so replace it with the enclosing one | |||
cellRangeList.set(i, range2); | |||
cellRangeList.remove(j--); | |||
merged = true; | |||
break; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
while( merged ); | |||
return cellRangeList; | |||
} | |||
/** | |||
* Convert a List of CellRange objects to an array of regions | |||
* | |||
* @param List of CellRange objects | |||
* @return regions | |||
*/ | |||
private static Region[] toRegionArray(List cellRanges) | |||
{ | |||
int size = cellRanges.size(); | |||
Region[] regions = new Region[size]; | |||
for (int i = 0; i != size; i++) | |||
{ | |||
CellRange cr = (CellRange) cellRanges.get(i); | |||
regions[i] = new Region(cr.getFirstRow(), cr.getFirstColumn(), | |||
cr.getLastRow(), cr.getLastColumn()); | |||
} | |||
return regions; | |||
} | |||
/** | |||
* Convert array of regions to a List of CellRange objects | |||
* | |||
* @param regions | |||
* @return List of CellRange objects | |||
*/ | |||
private static List toCellRangeList(Region[] regions) | |||
{ | |||
List cellRangeList = new ArrayList(); | |||
for( int i=0; i<regions.length; i++) | |||
{ | |||
Region r = regions[i]; | |||
CellRange cr = new CellRange(r.getRowFrom(), r.getRowTo(), r.getColumnFrom(), r | |||
.getColumnTo()); | |||
cellRangeList.add(cr); | |||
} | |||
return cellRangeList; | |||
return cfAggregate.getNumberOfRules(); | |||
} | |||
public String toString() |
@@ -18,231 +18,105 @@ | |||
package org.apache.poi.hssf.usermodel; | |||
import java.util.List; | |||
import java.util.Stack; | |||
import org.apache.poi.hssf.model.FormulaParser; | |||
import org.apache.poi.hssf.model.Workbook; | |||
import org.apache.poi.hssf.record.CFRuleRecord; | |||
import org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator; | |||
import org.apache.poi.hssf.record.cf.BorderFormatting; | |||
import org.apache.poi.hssf.record.cf.FontFormatting; | |||
import org.apache.poi.hssf.record.cf.PatternFormatting; | |||
import org.apache.poi.hssf.record.formula.Ptg; | |||
/** | |||
* | |||
* High level representation of Conditional Format | |||
* High level representation of Conditional Formatting Rule. | |||
* It allows to specify formula based conditions for the Conditional Formatting | |||
* and the formatting settings such as font, border and pattern. | |||
* | |||
* @author Dmitriy Kumshayev | |||
*/ | |||
public class HSSFConditionalFormattingRule | |||
public final class HSSFConditionalFormattingRule | |||
{ | |||
public static final byte CELL_COMPARISON = CFRuleRecord.CONDITION_TYPE_CELL_VALUE_IS; | |||
public static final byte FORMULA = CFRuleRecord.CONDITION_TYPE_FORMULA; | |||
private static final byte CELL_COMPARISON = CFRuleRecord.CONDITION_TYPE_CELL_VALUE_IS; | |||
public static final byte COMPARISON_OPERATOR_NO_COMPARISON = CFRuleRecord.COMPARISON_OPERATOR_NO_COMPARISON; | |||
public static final byte COMPARISON_OPERATOR_BETWEEN = CFRuleRecord.COMPARISON_OPERATOR_BETWEEN; | |||
public static final byte COMPARISON_OPERATOR_NOT_BETWEEN = CFRuleRecord.COMPARISON_OPERATOR_NOT_BETWEEN; | |||
public static final byte COMPARISON_OPERATOR_EQUAL = CFRuleRecord.COMPARISON_OPERATOR_EQUAL; | |||
public static final byte COMPARISON_OPERATOR_NOT_EQUAL = CFRuleRecord.COMPARISON_OPERATOR_NOT_EQUAL; | |||
public static final byte COMPARISON_OPERATOR_GT = CFRuleRecord.COMPARISON_OPERATOR_GT; | |||
public static final byte COMPARISON_OPERATOR_LT = CFRuleRecord.COMPARISON_OPERATOR_LT; | |||
public static final byte COMPARISON_OPERATOR_GE = CFRuleRecord.COMPARISON_OPERATOR_GE; | |||
public static final byte COMPARISON_OPERATOR_LE = CFRuleRecord.COMPARISON_OPERATOR_LE; | |||
private CFRuleRecord cfRuleRecord; | |||
private HSSFWorkbook workbook; | |||
protected HSSFConditionalFormattingRule(HSSFWorkbook workbook) | |||
{ | |||
this.workbook = workbook; | |||
this.cfRuleRecord = new CFRuleRecord(); | |||
} | |||
protected HSSFConditionalFormattingRule(HSSFWorkbook workbook, CFRuleRecord cfRuleRecord) | |||
{ | |||
this.workbook = workbook; | |||
this.cfRuleRecord = cfRuleRecord; | |||
} | |||
private final CFRuleRecord cfRuleRecord; | |||
private final Workbook workbook; | |||
/** | |||
* Keep Font Formatting unchanged for this Conditional Formatting Rule | |||
*/ | |||
public void setFontFormattingUnchanged() | |||
{ | |||
cfRuleRecord.setFontFormattingUnchanged(); | |||
} | |||
/** | |||
* Keep Border Formatting unchanged for this Conditional Formatting Rule | |||
*/ | |||
public void setBorderFormattingUnchanged() | |||
{ | |||
cfRuleRecord.setBorderFormattingUnchanged(); | |||
HSSFConditionalFormattingRule(Workbook pWorkbook, CFRuleRecord pRuleRecord) { | |||
workbook = pWorkbook; | |||
cfRuleRecord = pRuleRecord; | |||
} | |||
/** | |||
* Keep Pattern Formatting unchanged for this Conditional Formatting Rule | |||
*/ | |||
public void setPatternFormattingUnchanged() | |||
{ | |||
cfRuleRecord.setPatternFormattingUnchanged(); | |||
HSSFConditionalFormattingRule(Workbook pWorkbook, CFRuleRecord pRuleRecord, | |||
HSSFFontFormatting fontFmt, HSSFBorderFormatting bordFmt, HSSFPatternFormatting patternFmt) { | |||
this(pWorkbook, pRuleRecord); | |||
setFontFormatting(fontFmt); | |||
setBorderFormatting(bordFmt); | |||
setPatternFormatting(patternFmt); | |||
} | |||
public void setFontFormatting(HSSFFontFormatting fontFormatting) | |||
{ | |||
if( fontFormatting!=null ) | |||
{ | |||
cfRuleRecord.setFontFormatting(fontFormatting.getFontFormattingBlock()); | |||
} | |||
else | |||
{ | |||
setFontFormattingUnchanged(); | |||
} | |||
} | |||
public void setBorderFormatting(HSSFBorderFormatting borderFormatting) | |||
CFRuleRecord getCfRuleRecord() | |||
{ | |||
if( borderFormatting != null ) | |||
{ | |||
cfRuleRecord.setBorderFormatting(borderFormatting.getBorderFormattingBlock()); | |||
} | |||
else | |||
{ | |||
setBorderFormattingUnchanged(); | |||
} | |||
} | |||
public void setPatternFormatting(HSSFPatternFormatting patternFormatting) | |||
{ | |||
if( patternFormatting != null) | |||
{ | |||
cfRuleRecord.setPatternFormatting(patternFormatting.getPatternFormattingBlock()); | |||
} | |||
else | |||
{ | |||
setPatternFormattingUnchanged(); | |||
} | |||
return cfRuleRecord; | |||
} | |||
public void setCellComparisonCondition(byte comparisonOperation, String formula1, String formula2) | |||
{ | |||
cfRuleRecord.setConditionType(CELL_COMPARISON); | |||
cfRuleRecord.setComparisonOperation(comparisonOperation); | |||
// Formula 1 | |||
setFormula1(formula1); | |||
// Formula 2 | |||
setFormula1(formula2); | |||
} | |||
public void setFormulaCondition(String formula) | |||
/** | |||
* @param fontFmt pass <code>null</code> to signify 'font unchanged' | |||
*/ | |||
public void setFontFormatting(HSSFFontFormatting fontFmt) | |||
{ | |||
cfRuleRecord.setConditionType(FORMULA); | |||
// Formula 1 | |||
setFormula1(formula); | |||
FontFormatting block = fontFmt==null ? null : fontFmt.getFontFormattingBlock(); | |||
cfRuleRecord.setFontFormatting(block); | |||
} | |||
public void setFormula1(String formula) | |||
/** | |||
* @param borderFmt pass <code>null</code> to signify 'border unchanged' | |||
*/ | |||
public void setBorderFormatting(HSSFBorderFormatting borderFmt) | |||
{ | |||
// Formula 1 | |||
if( formula != null) | |||
{ | |||
Stack parsedExpression = parseFormula(formula); | |||
if( parsedExpression != null ) | |||
{ | |||
cfRuleRecord.setParsedExpression1(parsedExpression); | |||
} | |||
else | |||
{ | |||
cfRuleRecord.setParsedExpression1(null); | |||
} | |||
} | |||
else | |||
{ | |||
cfRuleRecord.setParsedExpression1(null); | |||
} | |||
BorderFormatting block = borderFmt==null ? null : borderFmt.getBorderFormattingBlock(); | |||
cfRuleRecord.setBorderFormatting(block); | |||
} | |||
public void setFormula2(String formula) | |||
/** | |||
* @param patternFmt pass <code>null</code> to signify 'pattern unchanged' | |||
*/ | |||
public void setPatternFormatting(HSSFPatternFormatting patternFmt) | |||
{ | |||
// Formula 2 | |||
if( formula != null) | |||
{ | |||
Stack parsedExpression = parseFormula(formula); | |||
if( parsedExpression != null ) | |||
{ | |||
cfRuleRecord.setParsedExpression2(parsedExpression); | |||
} | |||
else | |||
{ | |||
cfRuleRecord.setParsedExpression2(null); | |||
} | |||
} | |||
else | |||
{ | |||
cfRuleRecord.setParsedExpression2(null); | |||
} | |||
PatternFormatting block = patternFmt==null ? null : patternFmt.getPatternFormattingBlock(); | |||
cfRuleRecord.setPatternFormatting(block); | |||
} | |||
public String getFormula1() | |||
{ | |||
return toFormulaString(cfRuleRecord.getParsedExpression1()); | |||
return toFormulaString(cfRuleRecord.getParsedExpression1()); | |||
} | |||
public String getFormula2() | |||
{ | |||
byte conditionType = cfRuleRecord.getConditionType(); | |||
switch(conditionType) | |||
{ | |||
case CELL_COMPARISON: | |||
if (conditionType == CELL_COMPARISON) { | |||
byte comparisonOperation = cfRuleRecord.getComparisonOperation(); | |||
switch(comparisonOperation) | |||
{ | |||
byte comparisonOperation = cfRuleRecord.getComparisonOperation(); | |||
switch(comparisonOperation) | |||
{ | |||
case COMPARISON_OPERATOR_BETWEEN: | |||
case COMPARISON_OPERATOR_NOT_BETWEEN: | |||
return toFormulaString(cfRuleRecord.getParsedExpression2()); | |||
} | |||
case ComparisonOperator.BETWEEN: | |||
case ComparisonOperator.NOT_BETWEEN: | |||
return toFormulaString(cfRuleRecord.getParsedExpression2()); | |||
} | |||
} | |||
return null; | |||
} | |||
private String toFormulaString(List parsedExpression) | |||
private String toFormulaString(Ptg[] parsedExpression) | |||
{ | |||
String formula = null; | |||
if(parsedExpression!=null) | |||
{ | |||
formula = FormulaParser.toFormulaString(workbook.getWorkbook(),parsedExpression); | |||
formula = FormulaParser.toFormulaString(workbook, parsedExpression); | |||
} | |||
return formula; | |||
} | |||
private Stack parseFormula(String formula2) | |||
{ | |||
FormulaParser parser = | |||
new FormulaParser(formula2, workbook.getWorkbook()); | |||
parser.parse(); | |||
Stack parsedExpression = convertToTokenStack(parser.getRPNPtg()); | |||
parsedExpression = convertToTokenStack(parser.getRPNPtg()); | |||
return parsedExpression; | |||
} | |||
private static Stack convertToTokenStack(Ptg[] ptgs) | |||
{ | |||
if( ptgs != null) | |||
{ | |||
Stack parsedExpression = new Stack(); | |||
// fill the Ptg Stack with Ptgs of new formula | |||
for (int k = 0; k < ptgs.length; k++) | |||
{ | |||
parsedExpression.push(ptgs[ k ]); | |||
} | |||
return parsedExpression; | |||
} | |||
else | |||
{ | |||
return null; | |||
} | |||
} | |||
} |
@@ -1090,8 +1090,8 @@ public final class HSSFSheet { | |||
* @param leftcol the left column to show in desktop window pane | |||
*/ | |||
public void showInPane(short toprow, short leftcol){ | |||
this.sheet.setTopRow((short)toprow); | |||
this.sheet.setLeftCol((short)leftcol); | |||
this.sheet.setTopRow(toprow); | |||
this.sheet.setLeftCol(leftcol); | |||
} | |||
/** | |||
@@ -1438,7 +1438,7 @@ public final class HSSFSheet { | |||
int i = 0; | |||
while (iterator.hasNext()) { | |||
PageBreakRecord.Break breakItem = (PageBreakRecord.Break)iterator.next(); | |||
returnValue[i++] = (int)breakItem.main; | |||
returnValue[i++] = breakItem.main; | |||
} | |||
return returnValue; | |||
} | |||
@@ -1806,7 +1806,7 @@ public final class HSSFSheet { | |||
* | |||
* @return cell comment or <code>null</code> if not found | |||
*/ | |||
public HSSFComment getCellComment(int row, int column){ | |||
public HSSFComment getCellComment(int row, int column) { | |||
// Don't call findCellComment directly, otherwise | |||
// two calls to this method will result in two | |||
// new HSSFComment instances, which is bad | |||
@@ -1830,25 +1830,26 @@ public final class HSSFSheet { | |||
* with a cell comparison operator and | |||
* formatting rules such as font format, border format and pattern format | |||
* | |||
* @param comparisonOperation - one of the following values: <p> | |||
* <li>{@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_BETWEEN}</li> | |||
* <li>{@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_NOT_BETWEEN}</li> | |||
* <li>{@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_EQUAL}</li> | |||
* <li>{@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_NOT_EQUAL}</li> | |||
* <li>{@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_GT}</li> | |||
* <li>{@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_LT}</li> | |||
* <li>{@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_GE}</li> | |||
* <li>{@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_LE}</li> | |||
* @param comparisonOperation - a constant value from | |||
* <tt>{@link HSSFConditionalFormattingRule.ComparisonOperator}</tt>: <p> | |||
* <ul> | |||
* <li>BETWEEN</li> | |||
* <li>NOT_BETWEEN</li> | |||
* <li>EQUAL</li> | |||
* <li>NOT_EQUAL</li> | |||
* <li>GT</li> | |||
* <li>LT</li> | |||
* <li>GE</li> | |||
* <li>LE</li> | |||
* </ul> | |||
* </p> | |||
* @param formula1 - formula for the valued, compared with the cell | |||
* @param formula2 - second formula (only used with | |||
* {@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_BETWEEN}) and | |||
* {@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_NOT_BETWEEN} operations) | |||
* @param fontFmt - font formatting rules | |||
* @param bordFmt - border formatting rules | |||
* @param patternFmt - pattern formatting rules | |||
* @return | |||
* | |||
* @param fontFmt - font formatting rules (may be <code>null</code>) | |||
* @param bordFmt - border formatting rules (may be <code>null</code>) | |||
* @param patternFmt - pattern formatting rules (may be <code>null</code>) | |||
*/ | |||
public HSSFConditionalFormattingRule createConditionalFormattingRule( | |||
byte comparisonOperation, | |||
@@ -1856,14 +1857,11 @@ public final class HSSFSheet { | |||
String formula2, | |||
HSSFFontFormatting fontFmt, | |||
HSSFBorderFormatting bordFmt, | |||
HSSFPatternFormatting patternFmt) | |||
{ | |||
HSSFConditionalFormattingRule cf = new HSSFConditionalFormattingRule(workbook); | |||
cf.setFontFormatting(fontFmt); | |||
cf.setBorderFormatting(bordFmt); | |||
cf.setPatternFormatting(patternFmt); | |||
cf.setCellComparisonCondition(comparisonOperation, formula1, formula2); | |||
return cf; | |||
HSSFPatternFormatting patternFmt) { | |||
Workbook wb = workbook.getWorkbook(); | |||
CFRuleRecord rr = CFRuleRecord.create(wb, comparisonOperation, formula1, formula2); | |||
return new HSSFConditionalFormattingRule(wb, rr, fontFmt, bordFmt, patternFmt); | |||
} | |||
/** | |||
@@ -1872,38 +1870,19 @@ public final class HSSFSheet { | |||
* | |||
* The formatting rules are applied by Excel when the value of the formula not equal to 0. | |||
* | |||
* @param comparisonOperation - one of the following values: <p> | |||
* <li>{@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_BETWEEN}</li> | |||
* <li>{@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_NOT_BETWEEN}</li> | |||
* <li>{@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_EQUAL}</li> | |||
* <li>{@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_NOT_EQUAL}</li> | |||
* <li>{@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_GT}</li> | |||
* <li>{@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_LT}</li> | |||
* <li>{@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_GE}</li> | |||
* <li>{@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_LE}</li> | |||
* </p> | |||
* @param formula1 - formula for the valued, compared with the cell | |||
* @param formula2 - second formula (only used with | |||
* {@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_BETWEEN}) and | |||
* {@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_NOT_BETWEEN} operations) | |||
* @param fontFmt - font formatting rules | |||
* @param bordFmt - border formatting rules | |||
* @param patternFmt - pattern formatting rules | |||
* @return | |||
* | |||
* @param formula - formula for the valued, compared with the cell | |||
* @param fontFmt - font formatting rules (may be <code>null</code>) | |||
* @param bordFmt - border formatting rules (may be <code>null</code>) | |||
* @param patternFmt - pattern formatting rules (may be <code>null</code>) | |||
*/ | |||
public HSSFConditionalFormattingRule createConditionalFormattingRule( | |||
String formula, | |||
HSSFFontFormatting fontFmt, | |||
HSSFBorderFormatting bordFmt, | |||
HSSFPatternFormatting patternFmt) | |||
{ | |||
HSSFConditionalFormattingRule cf = new HSSFConditionalFormattingRule(workbook); | |||
cf.setFontFormatting(fontFmt); | |||
cf.setBorderFormatting(bordFmt); | |||
cf.setPatternFormatting(patternFmt); | |||
cf.setFormulaCondition(formula); | |||
return cf; | |||
HSSFPatternFormatting patternFmt) { | |||
Workbook wb = workbook.getWorkbook(); | |||
CFRuleRecord rr = CFRuleRecord.create(wb, formula); | |||
return new HSSFConditionalFormattingRule(wb, rr, fontFmt, bordFmt, patternFmt); | |||
} | |||
/** | |||
@@ -1918,8 +1897,7 @@ public final class HSSFSheet { | |||
* @param cf HSSFConditionalFormatting object | |||
* @return index of the new Conditional Formatting object | |||
*/ | |||
public int addConditionalFormatting( HSSFConditionalFormatting cf ) | |||
{ | |||
public int addConditionalFormatting( HSSFConditionalFormatting cf ) { | |||
CFRecordsAggregate cfraClone = cf.getCFRecordsAggregate().cloneCFAggregate(); | |||
return sheet.addConditionalFormatting(cfraClone); | |||
@@ -1929,46 +1907,46 @@ public final class HSSFSheet { | |||
* Allows to add a new Conditional Formatting set to the sheet. | |||
* | |||
* @param regions - list of rectangular regions to apply conditional formatting rules | |||
* @param cfRules - set of up to three conditional formatting rules | |||
* @param hcfRules - set of up to three conditional formatting rules | |||
* | |||
* @return index of the newly created Conditional Formatting object | |||
*/ | |||
public int addConditionalFormatting( Region [] regions, HSSFConditionalFormattingRule [] cfRules ) | |||
{ | |||
HSSFConditionalFormatting cf = new HSSFConditionalFormatting(this); | |||
cf.setFormattingRegions(regions); | |||
if( cfRules != null ) | |||
{ | |||
for( int i=0; i!= cfRules.length; i++ ) | |||
{ | |||
cf.addRule(cfRules[i]); | |||
} | |||
} | |||
return sheet.addConditionalFormatting(cf.getCFRecordsAggregate()); | |||
public int addConditionalFormatting(Region [] regions, HSSFConditionalFormattingRule [] hcfRules) { | |||
if (regions == null) { | |||
throw new IllegalArgumentException("regions must not be null"); | |||
} | |||
if (hcfRules == null) { | |||
throw new IllegalArgumentException("hcfRules must not be null"); | |||
} | |||
CFRuleRecord[] rules = new CFRuleRecord[hcfRules.length]; | |||
for (int i = 0; i != hcfRules.length; i++) { | |||
rules[i] = hcfRules[i].getCfRuleRecord(); | |||
} | |||
CFRecordsAggregate cfra = new CFRecordsAggregate(regions, rules); | |||
return sheet.addConditionalFormatting(cfra); | |||
} | |||
/** | |||
* gets Conditional Formatting object at a particular index | |||
* @param index of the Conditional Formatting object to fetch | |||
* | |||
* @param index | |||
* of the Conditional Formatting object to fetch | |||
* @return Conditional Formatting object | |||
*/ | |||
public HSSFConditionalFormatting getConditionalFormattingAt(int index) | |||
{ | |||
public HSSFConditionalFormatting getConditionalFormattingAt(int index) { | |||
CFRecordsAggregate cf = sheet.getCFRecordsAggregateAt(index); | |||
if( cf != null ) | |||
{ | |||
return new HSSFConditionalFormatting(this,cf); | |||
if (cf == null) { | |||
return null; | |||
} | |||
return null; | |||
return new HSSFConditionalFormatting(this,cf); | |||
} | |||
/** | |||
* @return number of Conditional Formatting objects of the sheet | |||
*/ | |||
public int getNumConditionalFormattings() | |||
{ | |||
public int getNumConditionalFormattings() { | |||
return sheet.getNumConditionalFormattings(); | |||
} | |||
@@ -1976,8 +1954,7 @@ public final class HSSFSheet { | |||
* removes a Conditional Formatting object by index | |||
* @param index of a Conditional Formatting object to remove | |||
*/ | |||
public void removeConditionalFormatting(int index) | |||
{ | |||
public void removeConditionalFormatting(int index) { | |||
sheet.removeConditionalFormatting(index); | |||
} | |||
} |
@@ -17,6 +17,7 @@ | |||
package org.apache.poi.hssf.record; | |||
import org.apache.poi.hssf.record.aggregates.AllRecordAggregateTests; | |||
import org.apache.poi.hssf.record.formula.AllFormulaTests; | |||
import junit.framework.Test; | |||
@@ -33,6 +34,7 @@ public final class AllRecordTests { | |||
TestSuite result = new TestSuite(AllRecordTests.class.getName()); | |||
result.addTest(AllFormulaTests.suite()); | |||
result.addTest(AllRecordAggregateTests.suite()); | |||
result.addTestSuite(TestAreaFormatRecord.class); | |||
result.addTestSuite(TestAreaRecord.class); | |||
@@ -45,6 +47,8 @@ public final class AllRecordTests { | |||
result.addTestSuite(TestBarRecord.class); | |||
result.addTestSuite(TestBoundSheetRecord.class); | |||
result.addTestSuite(TestCategorySeriesAxisRecord.class); | |||
result.addTestSuite(TestCFHeaderRecord.class); | |||
result.addTestSuite(TestCFRuleRecord.class); | |||
result.addTestSuite(TestChartRecord.class); | |||
result.addTestSuite(TestChartTitleFormatRecord.class); | |||
result.addTestSuite(TestCommonObjectDataSubRecord.class); |
@@ -17,9 +17,6 @@ | |||
package org.apache.poi.hssf.record; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import junit.framework.TestCase; | |||
import org.apache.poi.hssf.record.cf.CellRange; | |||
@@ -30,116 +27,114 @@ import org.apache.poi.hssf.record.cf.CellRange; | |||
* | |||
* @author Dmitriy Kumshayev | |||
*/ | |||
public class TestCFHeaderRecord | |||
extends TestCase | |||
public final class TestCFHeaderRecord extends TestCase | |||
{ | |||
public TestCFHeaderRecord(String name) | |||
{ | |||
super(name); | |||
} | |||
public void testCreateCFHeaderRecord () | |||
{ | |||
CFHeaderRecord record = new CFHeaderRecord(); | |||
CellRange[] ranges = { | |||
new CellRange(0,-1,5,5), | |||
new CellRange(0,-1,6,6), | |||
new CellRange(0,1,0,1), | |||
new CellRange(0,1,2,3), | |||
new CellRange(2,3,0,1), | |||
new CellRange(2,3,2,3), | |||
}; | |||
record.setCellRanges(ranges); | |||
ranges = record.getCellRanges(); | |||
assertEquals(6,ranges.length); | |||
CellRange enclosingCellRange = record.getEnclosingCellRange(); | |||
assertEquals(0, enclosingCellRange.getFirstRow()); | |||
assertEquals(-1, enclosingCellRange.getLastRow()); | |||
assertEquals(0, enclosingCellRange.getFirstColumn()); | |||
assertEquals(6, enclosingCellRange.getLastColumn()); | |||
record.setNeedRecalculation(true); | |||
assertTrue(record.getNeedRecalculation()); | |||
record.setNeedRecalculation(false); | |||
assertFalse(record.getNeedRecalculation()); | |||
} | |||
public void testSerialization() { | |||
byte[] recordData = new byte[] | |||
{ | |||
(byte)0x03, (byte)0x00, | |||
(byte)0x01, (byte)0x00, | |||
(byte)0x00, (byte)0x00, | |||
(byte)0x03, (byte)0x00, | |||
(byte)0x00, (byte)0x00, | |||
(byte)0x03, (byte)0x00, | |||
(byte)0x04, (byte)0x00, | |||
(byte)0x00, (byte)0x00, | |||
(byte)0x01, (byte)0x00, | |||
(byte)0x00, (byte)0x00, | |||
(byte)0x01, (byte)0x00, | |||
(byte)0x00, (byte)0x00, | |||
(byte)0x01, (byte)0x00, | |||
(byte)0x02, (byte)0x00, | |||
(byte)0x03, (byte)0x00, | |||
(byte)0x02, (byte)0x00, | |||
(byte)0x03, (byte)0x00, | |||
(byte)0x00, (byte)0x00, | |||
(byte)0x01, (byte)0x00, | |||
(byte)0x02, (byte)0x00, | |||
(byte)0x03, (byte)0x00, | |||
(byte)0x02, (byte)0x00, | |||
(byte)0x03, (byte)0x00, | |||
}; | |||
CFHeaderRecord record = new CFHeaderRecord(new TestcaseRecordInputStream(CFHeaderRecord.sid, (short)recordData.length, recordData)); | |||
assertEquals("#CFRULES", 3, record.getNumberOfConditionalFormats()); | |||
assertTrue(record.getNeedRecalculation()); | |||
CellRange enclosingCellRange = record.getEnclosingCellRange(); | |||
assertEquals(0, enclosingCellRange.getFirstRow()); | |||
assertEquals(3, enclosingCellRange.getLastRow()); | |||
assertEquals(0, enclosingCellRange.getFirstColumn()); | |||
assertEquals(3, enclosingCellRange.getLastColumn()); | |||
CellRange[] ranges = record.getCellRanges(); | |||
CellRange range0 = ranges[0]; | |||
assertEquals(0, range0.getFirstRow()); | |||
assertEquals(1, range0.getLastRow()); | |||
assertEquals(0, range0.getFirstColumn()); | |||
assertEquals(1, range0.getLastColumn()); | |||
CellRange range1 = ranges[1]; | |||
assertEquals(0, range1.getFirstRow()); | |||
assertEquals(1, range1.getLastRow()); | |||
assertEquals(2, range1.getFirstColumn()); | |||
assertEquals(3, range1.getLastColumn()); | |||
CellRange range2 = ranges[2]; | |||
assertEquals(2, range2.getFirstRow()); | |||
assertEquals(3, range2.getLastRow()); | |||
assertEquals(0, range2.getFirstColumn()); | |||
assertEquals(1, range2.getLastColumn()); | |||
CellRange range3 = ranges[3]; | |||
assertEquals(2, range3.getFirstRow()); | |||
assertEquals(3, range3.getLastRow()); | |||
assertEquals(2, range3.getFirstColumn()); | |||
assertEquals(3, range3.getLastColumn()); | |||
assertEquals(recordData.length+4, record.getRecordSize()); | |||
public void testCreateCFHeaderRecord () | |||
{ | |||
CFHeaderRecord record = new CFHeaderRecord(); | |||
List ranges = new ArrayList(); | |||
ranges.add(new CellRange(0,-1,(short)5,(short)5)); | |||
ranges.add(new CellRange(0,-1,(short)6,(short)6)); | |||
ranges.add(new CellRange(0,1,(short)0,(short)1)); | |||
ranges.add(new CellRange(0,1,(short)2,(short)3)); | |||
ranges.add(new CellRange(2,3,(short)0,(short)1)); | |||
ranges.add(new CellRange(2,3,(short)2,(short)3)); | |||
record.setCellRanges(ranges); | |||
ranges = record.getCellRanges(); | |||
assertEquals(6,ranges.size()); | |||
CellRange enclosingCellRange = record.getEnclosingCellRange(); | |||
assertEquals(0, enclosingCellRange.getFirstRow()); | |||
assertEquals(-1, enclosingCellRange.getLastRow()); | |||
assertEquals(0, enclosingCellRange.getFirstColumn()); | |||
assertEquals(6, enclosingCellRange.getLastColumn()); | |||
record.setNeedRecalculation(true); | |||
assertTrue(record.getNeedRecalculation()); | |||
record.setNeedRecalculation(false); | |||
assertFalse(record.getNeedRecalculation()); | |||
} | |||
public void testSerialization() { | |||
byte[] recordData = new byte[] | |||
{ | |||
(byte)0x03, (byte)0x00, | |||
(byte)0x01, (byte)0x00, | |||
(byte)0x00, (byte)0x00, | |||
(byte)0x03, (byte)0x00, | |||
(byte)0x00, (byte)0x00, | |||
(byte)0x03, (byte)0x00, | |||
(byte)0x04, (byte)0x00, | |||
(byte)0x00, (byte)0x00, | |||
(byte)0x01, (byte)0x00, | |||
(byte)0x00, (byte)0x00, | |||
(byte)0x01, (byte)0x00, | |||
(byte)0x00, (byte)0x00, | |||
(byte)0x01, (byte)0x00, | |||
(byte)0x02, (byte)0x00, | |||
(byte)0x03, (byte)0x00, | |||
(byte)0x02, (byte)0x00, | |||
(byte)0x03, (byte)0x00, | |||
(byte)0x00, (byte)0x00, | |||
(byte)0x01, (byte)0x00, | |||
(byte)0x02, (byte)0x00, | |||
(byte)0x03, (byte)0x00, | |||
(byte)0x02, (byte)0x00, | |||
(byte)0x03, (byte)0x00, | |||
}; | |||
CFHeaderRecord record = new CFHeaderRecord(new TestcaseRecordInputStream(CFHeaderRecord.sid, (short)recordData.length, recordData)); | |||
assertEquals("#CFRULES", 3, record.getNumberOfConditionalFormats()); | |||
assertTrue(record.getNeedRecalculation()); | |||
CellRange enclosingCellRange = record.getEnclosingCellRange(); | |||
assertEquals(0, enclosingCellRange.getFirstRow()); | |||
assertEquals(3, enclosingCellRange.getLastRow()); | |||
assertEquals(0, enclosingCellRange.getFirstColumn()); | |||
assertEquals(3, enclosingCellRange.getLastColumn()); | |||
List ranges = record.getCellRanges(); | |||
assertEquals(0, ((CellRange)ranges.get(0)).getFirstRow()); | |||
assertEquals(1, ((CellRange)ranges.get(0)).getLastRow()); | |||
assertEquals(0, ((CellRange)ranges.get(0)).getFirstColumn()); | |||
assertEquals(1, ((CellRange)ranges.get(0)).getLastColumn()); | |||
assertEquals(0, ((CellRange)ranges.get(1)).getFirstRow()); | |||
assertEquals(1, ((CellRange)ranges.get(1)).getLastRow()); | |||
assertEquals(2, ((CellRange)ranges.get(1)).getFirstColumn()); | |||
assertEquals(3, ((CellRange)ranges.get(1)).getLastColumn()); | |||
assertEquals(2, ((CellRange)ranges.get(2)).getFirstRow()); | |||
assertEquals(3, ((CellRange)ranges.get(2)).getLastRow()); | |||
assertEquals(0, ((CellRange)ranges.get(2)).getFirstColumn()); | |||
assertEquals(1, ((CellRange)ranges.get(2)).getLastColumn()); | |||
assertEquals(2, ((CellRange)ranges.get(3)).getFirstRow()); | |||
assertEquals(3, ((CellRange)ranges.get(3)).getLastRow()); | |||
assertEquals(2, ((CellRange)ranges.get(3)).getFirstColumn()); | |||
assertEquals(3, ((CellRange)ranges.get(3)).getLastColumn()); | |||
assertEquals(recordData.length+4, record.getRecordSize()); | |||
byte[] output = record.serialize(); | |||
assertEquals("Output size", recordData.length+4, output.length); //includes sid+recordlength | |||
for (int i = 0; i < recordData.length;i++) | |||
{ | |||
assertEquals("CFHeaderRecord doesn't match", recordData[i], output[i+4]); | |||
} | |||
} | |||
public static void main(String[] ignored_args) | |||
} | |||
public static void main(String[] ignored_args) | |||
{ | |||
System.out.println("Testing org.apache.poi.hssf.record.CFHeaderRecord"); | |||
junit.textui.TestRunner.run(TestCFHeaderRecord.class); | |||
} | |||
} |
@@ -19,109 +19,107 @@ package org.apache.poi.hssf.record; | |||
import junit.framework.TestCase; | |||
import org.apache.poi.hssf.model.Workbook; | |||
import org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator; | |||
import org.apache.poi.hssf.record.cf.BorderFormatting; | |||
import org.apache.poi.hssf.record.cf.FontFormatting; | |||
import org.apache.poi.hssf.record.cf.PatternFormatting; | |||
import org.apache.poi.hssf.util.HSSFColor; | |||
import org.apache.poi.util.LittleEndian; | |||
/** | |||
* Tests the serialization and deserialization of the TestCFRuleRecord | |||
* class works correctly. | |||
* class works correctly. | |||
* | |||
* @author Dmitriy Kumshayev | |||
*/ | |||
public class TestCFRuleRecord | |||
extends TestCase | |||
public final class TestCFRuleRecord extends TestCase | |||
{ | |||
public TestCFRuleRecord(String name) | |||
{ | |||
super(name); | |||
} | |||
public void testCreateCFRuleRecord () | |||
{ | |||
CFRuleRecord record = new CFRuleRecord(); | |||
testCFRuleRecord(record); | |||
// Serialize | |||
byte [] serializedRecord = record.serialize(); | |||
// Strip header | |||
byte [] recordData = new byte[serializedRecord.length-4]; | |||
System.arraycopy(serializedRecord, 4, recordData, 0, recordData.length); | |||
// Deserialize | |||
record = new CFRuleRecord(new TestcaseRecordInputStream(CFRuleRecord.sid, (short)recordData.length, recordData)); | |||
// Serialize again | |||
public void testCreateCFRuleRecord () | |||
{ | |||
Workbook workbook = Workbook.createWorkbook(); | |||
CFRuleRecord record = CFRuleRecord.create(workbook, "7"); | |||
testCFRuleRecord(record); | |||
// Serialize | |||
byte [] serializedRecord = record.serialize(); | |||
// Strip header | |||
byte [] recordData = new byte[serializedRecord.length-4]; | |||
System.arraycopy(serializedRecord, 4, recordData, 0, recordData.length); | |||
// Deserialize | |||
record = new CFRuleRecord(new TestcaseRecordInputStream(CFRuleRecord.sid, (short)recordData.length, recordData)); | |||
// Serialize again | |||
byte[] output = record.serialize(); | |||
// Compare | |||
assertEquals("Output size", recordData.length+4, output.length); //includes sid+recordlength | |||
for (int i = 0; i < recordData.length;i++) | |||
{ | |||
assertEquals("CFRuleRecord doesn't match", recordData[i], output[i+4]); | |||
} | |||
} | |||
} | |||
private void testCFRuleRecord(CFRuleRecord record) | |||
{ | |||
FontFormatting fontFormatting = new FontFormatting(); | |||
testFontFormattingAccessors(fontFormatting); | |||
assertFalse(record.containsFontFormattingBlock()); | |||
record.setFontFormatting(fontFormatting); | |||
assertTrue(record.containsFontFormattingBlock()); | |||
BorderFormatting borderFormatting = new BorderFormatting(); | |||
testBorderFormattingAccessors(borderFormatting); | |||
assertFalse(record.containsBorderFormattingBlock()); | |||
record.setBorderFormatting(borderFormatting); | |||
assertTrue(record.containsBorderFormattingBlock()); | |||
assertFalse(record.isLeftBorderModified()); | |||
record.setLeftBorderModified(true); | |||
assertTrue(record.isLeftBorderModified()); | |||
assertFalse(record.isRightBorderModified()); | |||
record.setRightBorderModified(true); | |||
assertTrue(record.isRightBorderModified()); | |||
assertFalse(record.isTopBorderModified()); | |||
record.setTopBorderModified(true); | |||
assertTrue(record.isTopBorderModified()); | |||
assertFalse(record.isBottomBorderModified()); | |||
record.setBottomBorderModified(true); | |||
assertTrue(record.isBottomBorderModified()); | |||
assertFalse(record.isTopLeftBottomRightBorderModified()); | |||
record.setTopLeftBottomRightBorderModified(true); | |||
assertTrue(record.isTopLeftBottomRightBorderModified()); | |||
assertFalse(record.isBottomLeftTopRightBorderModified()); | |||
record.setBottomLeftTopRightBorderModified(true); | |||
assertTrue(record.isBottomLeftTopRightBorderModified()); | |||
PatternFormatting patternFormatting = new PatternFormatting(); | |||
testPatternFormattingAccessors(patternFormatting); | |||
assertFalse(record.containsPatternFormattingBlock()); | |||
record.setPatternFormatting(patternFormatting); | |||
assertTrue(record.containsPatternFormattingBlock()); | |||
assertFalse(record.isPatternBackgroundColorModified()); | |||
record.setPatternBackgroundColorModified(true); | |||
assertTrue(record.isPatternBackgroundColorModified()); | |||
assertFalse(record.isPatternColorModified()); | |||
record.setPatternColorModified(true); | |||
assertTrue(record.isPatternColorModified()); | |||
assertFalse(record.isPatternStyleModified()); | |||
record.setPatternStyleModified(true); | |||
assertTrue(record.isPatternStyleModified()); | |||
testFontFormattingAccessors(fontFormatting); | |||
assertFalse(record.containsFontFormattingBlock()); | |||
record.setFontFormatting(fontFormatting); | |||
assertTrue(record.containsFontFormattingBlock()); | |||
BorderFormatting borderFormatting = new BorderFormatting(); | |||
testBorderFormattingAccessors(borderFormatting); | |||
assertFalse(record.containsBorderFormattingBlock()); | |||
record.setBorderFormatting(borderFormatting); | |||
assertTrue(record.containsBorderFormattingBlock()); | |||
assertFalse(record.isLeftBorderModified()); | |||
record.setLeftBorderModified(true); | |||
assertTrue(record.isLeftBorderModified()); | |||
assertFalse(record.isRightBorderModified()); | |||
record.setRightBorderModified(true); | |||
assertTrue(record.isRightBorderModified()); | |||
assertFalse(record.isTopBorderModified()); | |||
record.setTopBorderModified(true); | |||
assertTrue(record.isTopBorderModified()); | |||
assertFalse(record.isBottomBorderModified()); | |||
record.setBottomBorderModified(true); | |||
assertTrue(record.isBottomBorderModified()); | |||
assertFalse(record.isTopLeftBottomRightBorderModified()); | |||
record.setTopLeftBottomRightBorderModified(true); | |||
assertTrue(record.isTopLeftBottomRightBorderModified()); | |||
assertFalse(record.isBottomLeftTopRightBorderModified()); | |||
record.setBottomLeftTopRightBorderModified(true); | |||
assertTrue(record.isBottomLeftTopRightBorderModified()); | |||
PatternFormatting patternFormatting = new PatternFormatting(); | |||
testPatternFormattingAccessors(patternFormatting); | |||
assertFalse(record.containsPatternFormattingBlock()); | |||
record.setPatternFormatting(patternFormatting); | |||
assertTrue(record.containsPatternFormattingBlock()); | |||
assertFalse(record.isPatternBackgroundColorModified()); | |||
record.setPatternBackgroundColorModified(true); | |||
assertTrue(record.isPatternBackgroundColorModified()); | |||
assertFalse(record.isPatternColorModified()); | |||
record.setPatternColorModified(true); | |||
assertTrue(record.isPatternColorModified()); | |||
assertFalse(record.isPatternStyleModified()); | |||
record.setPatternStyleModified(true); | |||
assertTrue(record.isPatternStyleModified()); | |||
} | |||
private void testPatternFormattingAccessors(PatternFormatting patternFormatting) | |||
@@ -131,10 +129,9 @@ public class TestCFRuleRecord | |||
patternFormatting.setFillForegroundColor(HSSFColor.INDIGO.index); | |||
assertEquals(HSSFColor.INDIGO.index,patternFormatting.getFillForegroundColor()); | |||
patternFormatting.setFillPattern(PatternFormatting.DIAMONDS); | |||
assertEquals(PatternFormatting.DIAMONDS,patternFormatting.getFillPattern()); | |||
} | |||
private void testBorderFormattingAccessors(BorderFormatting borderFormatting) | |||
@@ -143,13 +140,13 @@ public class TestCFRuleRecord | |||
assertFalse(borderFormatting.isBackwardDiagonalOn()); | |||
borderFormatting.setBackwardDiagonalOn(true); | |||
assertTrue(borderFormatting.isBackwardDiagonalOn()); | |||
borderFormatting.setBorderBottom(BorderFormatting.BORDER_DOTTED); | |||
assertEquals(BorderFormatting.BORDER_DOTTED, borderFormatting.getBorderBottom()); | |||
borderFormatting.setBorderDiagonal(BorderFormatting.BORDER_MEDIUM); | |||
assertEquals(BorderFormatting.BORDER_MEDIUM, borderFormatting.getBorderDiagonal()); | |||
borderFormatting.setBorderLeft(BorderFormatting.BORDER_MEDIUM_DASH_DOT_DOT); | |||
assertEquals(BorderFormatting.BORDER_MEDIUM_DASH_DOT_DOT, borderFormatting.getBorderLeft()); | |||
@@ -178,119 +175,137 @@ public class TestCFRuleRecord | |||
borderFormatting.setTopBorderColor(HSSFColor.GOLD.index); | |||
assertEquals(HSSFColor.GOLD.index, borderFormatting.getTopBorderColor()); | |||
} | |||
private void testFontFormattingAccessors(FontFormatting fontFormatting) | |||
{ | |||
// Check for defaults | |||
assertFalse(fontFormatting.isEscapementTypeModified()); | |||
assertFalse(fontFormatting.isFontCancellationModified()); | |||
assertFalse(fontFormatting.isFontCondenseModified()); | |||
assertFalse(fontFormatting.isFontOutlineModified()); | |||
assertFalse(fontFormatting.isFontShadowModified()); | |||
assertFalse(fontFormatting.isFontStyleModified()); | |||
assertFalse(fontFormatting.isUnderlineTypeModified()); | |||
assertFalse(fontFormatting.isBold()); | |||
assertFalse(fontFormatting.isCondenseOn()); | |||
assertFalse(fontFormatting.isItalic()); | |||
assertFalse(fontFormatting.isOutlineOn()); | |||
assertFalse(fontFormatting.isShadowOn()); | |||
assertFalse(fontFormatting.isStruckout()); | |||
assertEquals(0, fontFormatting.getEscapementType()); | |||
assertEquals(-1, fontFormatting.getFontColorIndex()); | |||
assertEquals(-1, fontFormatting.getFontHeight()); | |||
assertEquals(400, fontFormatting.getFontWeight()); | |||
assertEquals(0, fontFormatting.getUnderlineType()); | |||
fontFormatting.setBold(true); | |||
assertTrue(fontFormatting.isBold()); | |||
fontFormatting.setBold(false); | |||
assertFalse(fontFormatting.isBold()); | |||
fontFormatting.setCondense(true); | |||
assertTrue(fontFormatting.isCondenseOn()); | |||
fontFormatting.setCondense(false); | |||
assertFalse(fontFormatting.isCondenseOn()); | |||
fontFormatting.setEscapementType(FontFormatting.SS_SUB); | |||
assertEquals(FontFormatting.SS_SUB, fontFormatting.getEscapementType()); | |||
fontFormatting.setEscapementType(FontFormatting.SS_SUPER); | |||
assertEquals(FontFormatting.SS_SUPER, fontFormatting.getEscapementType()); | |||
fontFormatting.setEscapementType(FontFormatting.SS_NONE); | |||
assertEquals(FontFormatting.SS_NONE, fontFormatting.getEscapementType()); | |||
fontFormatting.setEscapementTypeModified(false); | |||
assertFalse(fontFormatting.isEscapementTypeModified()); | |||
fontFormatting.setEscapementTypeModified(true); | |||
assertTrue(fontFormatting.isEscapementTypeModified()); | |||
fontFormatting.setFontCancellationModified(false); | |||
assertFalse(fontFormatting.isFontCancellationModified()); | |||
fontFormatting.setFontCancellationModified(true); | |||
assertTrue(fontFormatting.isFontCancellationModified()); | |||
fontFormatting.setFontColorIndex((short)10); | |||
assertEquals(10,fontFormatting.getFontColorIndex()); | |||
fontFormatting.setFontCondenseModified(false); | |||
assertFalse(fontFormatting.isFontCondenseModified()); | |||
fontFormatting.setFontCondenseModified(true); | |||
assertTrue(fontFormatting.isFontCondenseModified()); | |||
fontFormatting.setFontHeight((short)100); | |||
assertEquals(100,fontFormatting.getFontHeight()); | |||
fontFormatting.setFontOutlineModified(false); | |||
assertFalse(fontFormatting.isFontOutlineModified()); | |||
fontFormatting.setFontOutlineModified(true); | |||
assertTrue(fontFormatting.isFontOutlineModified()); | |||
fontFormatting.setFontShadowModified(false); | |||
assertFalse(fontFormatting.isFontShadowModified()); | |||
fontFormatting.setFontShadowModified(true); | |||
assertTrue(fontFormatting.isFontShadowModified()); | |||
fontFormatting.setFontStyleModified(false); | |||
assertFalse(fontFormatting.isFontStyleModified()); | |||
fontFormatting.setFontStyleModified(true); | |||
assertTrue(fontFormatting.isFontStyleModified()); | |||
fontFormatting.setItalic(false); | |||
assertFalse(fontFormatting.isItalic()); | |||
fontFormatting.setItalic(true); | |||
assertTrue(fontFormatting.isItalic()); | |||
fontFormatting.setOutline(false); | |||
assertFalse(fontFormatting.isOutlineOn()); | |||
fontFormatting.setOutline(true); | |||
assertTrue(fontFormatting.isOutlineOn()); | |||
fontFormatting.setShadow(false); | |||
assertFalse(fontFormatting.isShadowOn()); | |||
fontFormatting.setShadow(true); | |||
assertTrue(fontFormatting.isShadowOn()); | |||
fontFormatting.setStrikeout(false); | |||
assertFalse(fontFormatting.isStruckout()); | |||
fontFormatting.setStrikeout(true); | |||
assertTrue(fontFormatting.isStruckout()); | |||
fontFormatting.setUnderlineType(FontFormatting.U_DOUBLE_ACCOUNTING); | |||
assertEquals(FontFormatting.U_DOUBLE_ACCOUNTING, fontFormatting.getUnderlineType()); | |||
fontFormatting.setUnderlineTypeModified(false); | |||
assertFalse(fontFormatting.isUnderlineTypeModified()); | |||
fontFormatting.setUnderlineTypeModified(true); | |||
assertTrue(fontFormatting.isUnderlineTypeModified()); | |||
assertFalse(fontFormatting.isEscapementTypeModified()); | |||
assertFalse(fontFormatting.isFontCancellationModified()); | |||
assertFalse(fontFormatting.isFontCondenseModified()); | |||
assertFalse(fontFormatting.isFontOutlineModified()); | |||
assertFalse(fontFormatting.isFontShadowModified()); | |||
assertFalse(fontFormatting.isFontStyleModified()); | |||
assertFalse(fontFormatting.isUnderlineTypeModified()); | |||
assertFalse(fontFormatting.isBold()); | |||
assertFalse(fontFormatting.isCondenseOn()); | |||
assertFalse(fontFormatting.isItalic()); | |||
assertFalse(fontFormatting.isOutlineOn()); | |||
assertFalse(fontFormatting.isShadowOn()); | |||
assertFalse(fontFormatting.isStruckout()); | |||
assertEquals(0, fontFormatting.getEscapementType()); | |||
assertEquals(-1, fontFormatting.getFontColorIndex()); | |||
assertEquals(-1, fontFormatting.getFontHeight()); | |||
assertEquals(400, fontFormatting.getFontWeight()); | |||
assertEquals(0, fontFormatting.getUnderlineType()); | |||
fontFormatting.setBold(true); | |||
assertTrue(fontFormatting.isBold()); | |||
fontFormatting.setBold(false); | |||
assertFalse(fontFormatting.isBold()); | |||
fontFormatting.setCondense(true); | |||
assertTrue(fontFormatting.isCondenseOn()); | |||
fontFormatting.setCondense(false); | |||
assertFalse(fontFormatting.isCondenseOn()); | |||
fontFormatting.setEscapementType(FontFormatting.SS_SUB); | |||
assertEquals(FontFormatting.SS_SUB, fontFormatting.getEscapementType()); | |||
fontFormatting.setEscapementType(FontFormatting.SS_SUPER); | |||
assertEquals(FontFormatting.SS_SUPER, fontFormatting.getEscapementType()); | |||
fontFormatting.setEscapementType(FontFormatting.SS_NONE); | |||
assertEquals(FontFormatting.SS_NONE, fontFormatting.getEscapementType()); | |||
fontFormatting.setEscapementTypeModified(false); | |||
assertFalse(fontFormatting.isEscapementTypeModified()); | |||
fontFormatting.setEscapementTypeModified(true); | |||
assertTrue(fontFormatting.isEscapementTypeModified()); | |||
fontFormatting.setFontCancellationModified(false); | |||
assertFalse(fontFormatting.isFontCancellationModified()); | |||
fontFormatting.setFontCancellationModified(true); | |||
assertTrue(fontFormatting.isFontCancellationModified()); | |||
fontFormatting.setFontColorIndex((short)10); | |||
assertEquals(10,fontFormatting.getFontColorIndex()); | |||
fontFormatting.setFontCondenseModified(false); | |||
assertFalse(fontFormatting.isFontCondenseModified()); | |||
fontFormatting.setFontCondenseModified(true); | |||
assertTrue(fontFormatting.isFontCondenseModified()); | |||
fontFormatting.setFontHeight((short)100); | |||
assertEquals(100,fontFormatting.getFontHeight()); | |||
fontFormatting.setFontOutlineModified(false); | |||
assertFalse(fontFormatting.isFontOutlineModified()); | |||
fontFormatting.setFontOutlineModified(true); | |||
assertTrue(fontFormatting.isFontOutlineModified()); | |||
fontFormatting.setFontShadowModified(false); | |||
assertFalse(fontFormatting.isFontShadowModified()); | |||
fontFormatting.setFontShadowModified(true); | |||
assertTrue(fontFormatting.isFontShadowModified()); | |||
fontFormatting.setFontStyleModified(false); | |||
assertFalse(fontFormatting.isFontStyleModified()); | |||
fontFormatting.setFontStyleModified(true); | |||
assertTrue(fontFormatting.isFontStyleModified()); | |||
fontFormatting.setItalic(false); | |||
assertFalse(fontFormatting.isItalic()); | |||
fontFormatting.setItalic(true); | |||
assertTrue(fontFormatting.isItalic()); | |||
fontFormatting.setOutline(false); | |||
assertFalse(fontFormatting.isOutlineOn()); | |||
fontFormatting.setOutline(true); | |||
assertTrue(fontFormatting.isOutlineOn()); | |||
fontFormatting.setShadow(false); | |||
assertFalse(fontFormatting.isShadowOn()); | |||
fontFormatting.setShadow(true); | |||
assertTrue(fontFormatting.isShadowOn()); | |||
fontFormatting.setStrikeout(false); | |||
assertFalse(fontFormatting.isStruckout()); | |||
fontFormatting.setStrikeout(true); | |||
assertTrue(fontFormatting.isStruckout()); | |||
fontFormatting.setUnderlineType(FontFormatting.U_DOUBLE_ACCOUNTING); | |||
assertEquals(FontFormatting.U_DOUBLE_ACCOUNTING, fontFormatting.getUnderlineType()); | |||
fontFormatting.setUnderlineTypeModified(false); | |||
assertFalse(fontFormatting.isUnderlineTypeModified()); | |||
fontFormatting.setUnderlineTypeModified(true); | |||
assertTrue(fontFormatting.isUnderlineTypeModified()); | |||
} | |||
public static void main(String[] ignored_args) | |||
public void testWrite() { | |||
Workbook workbook = Workbook.createWorkbook(); | |||
CFRuleRecord rr = CFRuleRecord.create(workbook, ComparisonOperator.BETWEEN, "5", "10"); | |||
PatternFormatting patternFormatting = new PatternFormatting(); | |||
patternFormatting.setFillPattern(PatternFormatting.BRICKS); | |||
rr.setPatternFormatting(patternFormatting); | |||
byte[] data = rr.serialize(); | |||
assertEquals(26, data.length); | |||
assertEquals(3, LittleEndian.getShort(data, 6)); | |||
assertEquals(3, LittleEndian.getShort(data, 8)); | |||
int flags = LittleEndian.getInt(data, 10); | |||
assertEquals("unused flags should be 111", 0x00380000, flags & 0x00380000); | |||
assertEquals("undocumented flags should be 0000", 0, flags & 0x03C00000); // Otherwise Excel gets unhappy | |||
assertEquals(0xA03FFFFF, flags); | |||
} | |||
public static void main(String[] ignored_args) | |||
{ | |||
System.out.println("Testing org.apache.poi.hssf.record.CFRuleRecord"); | |||
junit.textui.TestRunner.run(TestCFRuleRecord.class); | |||
} | |||
} |
@@ -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.record.aggregates; | |||
import junit.framework.Test; | |||
import junit.framework.TestSuite; | |||
/** | |||
* Collects all tests for package <tt>org.apache.poi.hssf.record.aggregates</tt>. | |||
* | |||
* @author Josh Micich | |||
*/ | |||
public final class AllRecordAggregateTests { | |||
public static Test suite() { | |||
TestSuite result = new TestSuite(AllRecordAggregateTests.class.getName()); | |||
result.addTestSuite(TestCFRecordsAggregate.class); | |||
result.addTestSuite(TestColumnInfoRecordsAggregate.class); | |||
result.addTestSuite(TestFormulaRecordAggregate.class); | |||
result.addTestSuite(TestRowRecordsAggregate.class); | |||
result.addTestSuite(TestValueRecordsAggregate.class); | |||
return result; | |||
} | |||
} |
@@ -24,9 +24,11 @@ import java.util.List; | |||
import junit.framework.TestCase; | |||
import org.apache.poi.hssf.model.Workbook; | |||
import org.apache.poi.hssf.record.CFHeaderRecord; | |||
import org.apache.poi.hssf.record.CFRuleRecord; | |||
import org.apache.poi.hssf.record.RecordFactory; | |||
import org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator; | |||
import org.apache.poi.hssf.record.cf.CellRange; | |||
/** | |||
@@ -35,77 +37,71 @@ import org.apache.poi.hssf.record.cf.CellRange; | |||
* | |||
* @author Dmitriy Kumshayev | |||
*/ | |||
public class TestCFRecordsAggregate | |||
extends TestCase | |||
public final class TestCFRecordsAggregate extends TestCase | |||
{ | |||
public TestCFRecordsAggregate(String name) | |||
{ | |||
super(name); | |||
} | |||
public void testCFRecordsAggregate() | |||
{ | |||
CFRecordsAggregate record = new CFRecordsAggregate(); | |||
List recs = new ArrayList(); | |||
CFHeaderRecord header = new CFHeaderRecord(); | |||
CFRuleRecord rule1 = new CFRuleRecord(); | |||
CFRuleRecord rule2 = new CFRuleRecord(); | |||
CFRuleRecord rule3 = new CFRuleRecord(); | |||
header.setNumberOfConditionalFormats(3); | |||
CellRange range1 = new CellRange(0,1,(short)0,(short)0); | |||
CellRange range2 = new CellRange(0,1,(short)2,(short)2); | |||
List cellRanges = new ArrayList(); | |||
cellRanges.add(range1); | |||
cellRanges.add(range2); | |||
header.setCellRanges(cellRanges); | |||
recs.add(header); | |||
recs.add(rule1); | |||
recs.add(rule2); | |||
recs.add(rule3); | |||
record = CFRecordsAggregate.createCFAggregate(recs, 0); | |||
// Serialize | |||
byte [] serializedRecord = record.serialize(); | |||
InputStream in = new ByteArrayInputStream(serializedRecord); | |||
//Parse | |||
recs = RecordFactory.createRecords(in); | |||
// Verify | |||
assertNotNull(recs); | |||
assertEquals(4, recs.size()); | |||
header = (CFHeaderRecord)recs.get(0); | |||
rule1 = (CFRuleRecord)recs.get(1); | |||
rule2 = (CFRuleRecord)recs.get(2); | |||
rule3 = (CFRuleRecord)recs.get(3); | |||
cellRanges = header.getCellRanges(); | |||
assertEquals(2, cellRanges.size()); | |||
assertEquals(3, header.getNumberOfConditionalFormats()); | |||
record = CFRecordsAggregate.createCFAggregate(recs, 0); | |||
record = record.cloneCFAggregate(); | |||
assertNotNull(record.getHeader()); | |||
assertEquals(3,record.getRules().size()); | |||
header = record.getHeader(); | |||
rule1 = (CFRuleRecord)record.getRules().get(0); | |||
rule2 = (CFRuleRecord)record.getRules().get(1); | |||
rule3 = (CFRuleRecord)record.getRules().get(2); | |||
cellRanges = header.getCellRanges(); | |||
assertEquals(2, cellRanges.size()); | |||
assertEquals(3, header.getNumberOfConditionalFormats()); | |||
} | |||
public static void main(String[] ignored_args) | |||
public void testCFRecordsAggregate() | |||
{ | |||
Workbook workbook = Workbook.createWorkbook(); | |||
List recs = new ArrayList(); | |||
CFHeaderRecord header = new CFHeaderRecord(); | |||
CFRuleRecord rule1 = CFRuleRecord.create(workbook, "7"); | |||
CFRuleRecord rule2 = CFRuleRecord.create(workbook, ComparisonOperator.BETWEEN, "2", "5"); | |||
CFRuleRecord rule3 = CFRuleRecord.create(workbook, ComparisonOperator.GE, "100", null); | |||
header.setNumberOfConditionalFormats(3); | |||
CellRange[] cellRanges = { | |||
new CellRange(0,1,0,0), | |||
new CellRange(0,1,2,2), | |||
}; | |||
header.setCellRanges(cellRanges); | |||
recs.add(header); | |||
recs.add(rule1); | |||
recs.add(rule2); | |||
recs.add(rule3); | |||
CFRecordsAggregate record; | |||
record = CFRecordsAggregate.createCFAggregate(recs, 0); | |||
// Serialize | |||
byte [] serializedRecord = record.serialize(); | |||
InputStream in = new ByteArrayInputStream(serializedRecord); | |||
//Parse | |||
recs = RecordFactory.createRecords(in); | |||
// Verify | |||
assertNotNull(recs); | |||
assertEquals(4, recs.size()); | |||
header = (CFHeaderRecord)recs.get(0); | |||
rule1 = (CFRuleRecord)recs.get(1); | |||
rule2 = (CFRuleRecord)recs.get(2); | |||
rule3 = (CFRuleRecord)recs.get(3); | |||
cellRanges = header.getCellRanges(); | |||
assertEquals(2, cellRanges.length); | |||
assertEquals(3, header.getNumberOfConditionalFormats()); | |||
record = CFRecordsAggregate.createCFAggregate(recs, 0); | |||
record = record.cloneCFAggregate(); | |||
assertNotNull(record.getHeader()); | |||
assertEquals(3,record.getNumberOfRules()); | |||
header = record.getHeader(); | |||
rule1 = record.getRule(0); | |||
rule2 = record.getRule(1); | |||
rule3 = record.getRule(2); | |||
cellRanges = header.getCellRanges(); | |||
assertEquals(2, cellRanges.length); | |||
assertEquals(3, header.getNumberOfConditionalFormats()); | |||
} | |||
public static void main(String[] ignored_args) | |||
{ | |||
System.out.println("Testing org.apache.poi.hssf.record.aggregates.CFRecordsAggregate"); | |||
junit.textui.TestRunner.run(TestCFRecordsAggregate.class); | |||
} | |||
} |
@@ -24,13 +24,13 @@ import junit.framework.TestCase; | |||
*/ | |||
public class TestCellRange extends TestCase | |||
{ | |||
private static final CellRange biggest = new CellRange(0, -1,(short) 0,(short)-1); | |||
private static final CellRange tenthColumn = new CellRange(0, -1,(short)10,(short)10); | |||
private static final CellRange tenthRow = new CellRange(10,10,(short) 0,(short)-1); | |||
private static final CellRange box10x10 = new CellRange(0, 10,(short) 0,(short)10); | |||
private static final CellRange box9x9 = new CellRange(0, 9,(short) 0,(short) 9); | |||
private static final CellRange box10to20c = new CellRange(0, 10,(short)10,(short)20); | |||
private static final CellRange oneCell = new CellRange(10,10,(short)10,(short)10); | |||
private static final CellRange biggest = new CellRange( 0, -1, 0,-1); | |||
private static final CellRange tenthColumn = new CellRange( 0, -1,10,10); | |||
private static final CellRange tenthRow = new CellRange(10, 10, 0,-1); | |||
private static final CellRange box10x10 = new CellRange( 0, 10, 0,10); | |||
private static final CellRange box9x9 = new CellRange( 0, 9, 0, 9); | |||
private static final CellRange box10to20c = new CellRange( 0, 10,10,20); | |||
private static final CellRange oneCell = new CellRange(10, 10,10,10); | |||
boolean [][] contanis = new boolean[][] | |||
{ | |||
@@ -61,62 +61,62 @@ public class TestCellRange extends TestCase | |||
} | |||
} | |||
} | |||
private static final CellRange col1 = new CellRange(0, -1,(short) 1,(short)1); | |||
private static final CellRange col2 = new CellRange(0, -1,(short) 2,(short)2); | |||
private static final CellRange row1 = new CellRange(1, 1,(short) 0,(short)-1); | |||
private static final CellRange row2 = new CellRange(2, 2,(short) 0,(short)-1); | |||
private static final CellRange box0 = new CellRange( 0, 2,(short) 0,(short)2); | |||
private static final CellRange box1 = new CellRange( 0, 1,(short) 0,(short)1); | |||
private static final CellRange box2 = new CellRange( 0, 1,(short) 2,(short)3); | |||
private static final CellRange box3 = new CellRange( 2, 3,(short) 0,(short)1); | |||
private static final CellRange box4 = new CellRange( 2, 3,(short) 2,(short)3); | |||
private static final CellRange box5 = new CellRange( 1, 3,(short) 1,(short)3); | |||
private static final CellRange col1 = new CellRange( 0, -1, 1,1); | |||
private static final CellRange col2 = new CellRange( 0, -1, 2,2); | |||
private static final CellRange row1 = new CellRange( 1, 1, 0,-1); | |||
private static final CellRange row2 = new CellRange( 2, 2, 0,-1); | |||
private static final CellRange box0 = new CellRange( 0, 2, 0,2); | |||
private static final CellRange box1 = new CellRange( 0, 1, 0,1); | |||
private static final CellRange box2 = new CellRange( 0, 1, 2,3); | |||
private static final CellRange box3 = new CellRange( 2, 3, 0,1); | |||
private static final CellRange box4 = new CellRange( 2, 3, 2,3); | |||
private static final CellRange box5 = new CellRange( 1, 3, 1,3); | |||
public void testHasSharedBorderMethod() | |||
{ | |||
assertFalse(col1.hasSharedBorder(col1)); | |||
assertFalse(col2.hasSharedBorder(col2)); | |||
assertTrue(col1.hasSharedBorder(col2)); | |||
assertTrue(col2.hasSharedBorder(col1)); | |||
assertFalse(col1.hasExactSharedBorder(col1)); | |||
assertFalse(col2.hasExactSharedBorder(col2)); | |||
assertTrue(col1.hasExactSharedBorder(col2)); | |||
assertTrue(col2.hasExactSharedBorder(col1)); | |||
assertFalse(row1.hasSharedBorder(row1)); | |||
assertFalse(row2.hasSharedBorder(row2)); | |||
assertTrue(row1.hasSharedBorder(row2)); | |||
assertTrue(row2.hasSharedBorder(row1)); | |||
assertFalse(row1.hasExactSharedBorder(row1)); | |||
assertFalse(row2.hasExactSharedBorder(row2)); | |||
assertTrue(row1.hasExactSharedBorder(row2)); | |||
assertTrue(row2.hasExactSharedBorder(row1)); | |||
assertFalse(row1.hasSharedBorder(col1)); | |||
assertFalse(row1.hasSharedBorder(col2)); | |||
assertFalse(col1.hasSharedBorder(row1)); | |||
assertFalse(col2.hasSharedBorder(row1)); | |||
assertFalse(row2.hasSharedBorder(col1)); | |||
assertFalse(row2.hasSharedBorder(col2)); | |||
assertFalse(col1.hasSharedBorder(row2)); | |||
assertFalse(col2.hasSharedBorder(row2)); | |||
assertTrue(col2.hasSharedBorder(col1)); | |||
assertFalse(row1.hasExactSharedBorder(col1)); | |||
assertFalse(row1.hasExactSharedBorder(col2)); | |||
assertFalse(col1.hasExactSharedBorder(row1)); | |||
assertFalse(col2.hasExactSharedBorder(row1)); | |||
assertFalse(row2.hasExactSharedBorder(col1)); | |||
assertFalse(row2.hasExactSharedBorder(col2)); | |||
assertFalse(col1.hasExactSharedBorder(row2)); | |||
assertFalse(col2.hasExactSharedBorder(row2)); | |||
assertTrue(col2.hasExactSharedBorder(col1)); | |||
assertFalse(box1.hasSharedBorder(box1)); | |||
assertTrue(box1.hasSharedBorder(box2)); | |||
assertTrue(box1.hasSharedBorder(box3)); | |||
assertFalse(box1.hasSharedBorder(box4)); | |||
assertFalse(box1.hasExactSharedBorder(box1)); | |||
assertTrue(box1.hasExactSharedBorder(box2)); | |||
assertTrue(box1.hasExactSharedBorder(box3)); | |||
assertFalse(box1.hasExactSharedBorder(box4)); | |||
assertTrue(box2.hasSharedBorder(box1)); | |||
assertFalse(box2.hasSharedBorder(box2)); | |||
assertFalse(box2.hasSharedBorder(box3)); | |||
assertTrue(box2.hasSharedBorder(box4)); | |||
assertTrue(box2.hasExactSharedBorder(box1)); | |||
assertFalse(box2.hasExactSharedBorder(box2)); | |||
assertFalse(box2.hasExactSharedBorder(box3)); | |||
assertTrue(box2.hasExactSharedBorder(box4)); | |||
assertTrue(box3.hasSharedBorder(box1)); | |||
assertFalse(box3.hasSharedBorder(box2)); | |||
assertFalse(box3.hasSharedBorder(box3)); | |||
assertTrue(box3.hasSharedBorder(box4)); | |||
assertTrue(box3.hasExactSharedBorder(box1)); | |||
assertFalse(box3.hasExactSharedBorder(box2)); | |||
assertFalse(box3.hasExactSharedBorder(box3)); | |||
assertTrue(box3.hasExactSharedBorder(box4)); | |||
assertFalse(box4.hasSharedBorder(box1)); | |||
assertTrue(box4.hasSharedBorder(box2)); | |||
assertTrue(box4.hasSharedBorder(box3)); | |||
assertFalse(box4.hasSharedBorder(box4)); | |||
assertFalse(box4.hasExactSharedBorder(box1)); | |||
assertTrue(box4.hasExactSharedBorder(box2)); | |||
assertTrue(box4.hasExactSharedBorder(box3)); | |||
assertFalse(box4.hasExactSharedBorder(box4)); | |||
} | |||
public void testIntersectMethod() | |||
{ | |||
assertEquals( CellRange.OVERLAP,box0.intersect(box5)); | |||
@@ -135,5 +135,4 @@ public class TestCellRange extends TestCase | |||
assertEquals(CellRange.INSIDE,tenthColumn.intersect(tenthColumn)); | |||
assertEquals(CellRange.INSIDE,tenthRow.intersect(tenthRow)); | |||
} | |||
} |
@@ -0,0 +1,203 @@ | |||
/* ==================================================================== | |||
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 java.io.ByteArrayInputStream; | |||
import java.io.ByteArrayOutputStream; | |||
import java.io.FileInputStream; | |||
import java.io.FileOutputStream; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.io.OutputStream; | |||
import junit.framework.TestCase; | |||
import org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator; | |||
import org.apache.poi.hssf.util.HSSFColor; | |||
import org.apache.poi.hssf.util.Region; | |||
/** | |||
* | |||
* @author Dmitriy Kumshayev | |||
*/ | |||
public final class TestHSSFConfditionalFormatting extends TestCase | |||
{ | |||
public void XtestLastAndFirstColumns() | |||
{ | |||
HSSFWorkbook workbook = new HSSFWorkbook(); | |||
HSSFSheet sheet = workbook.createSheet(); | |||
String formula = "7"; | |||
HSSFFontFormatting fontFmt = new HSSFFontFormatting(); | |||
fontFmt.setFontStyle(true, false); | |||
HSSFBorderFormatting bordFmt = new HSSFBorderFormatting(); | |||
bordFmt.setBorderBottom(HSSFBorderFormatting.BORDER_THIN); | |||
bordFmt.setBorderTop(HSSFBorderFormatting.BORDER_THICK); | |||
bordFmt.setBorderLeft(HSSFBorderFormatting.BORDER_DASHED); | |||
bordFmt.setBorderRight(HSSFBorderFormatting.BORDER_DOTTED); | |||
HSSFPatternFormatting patternFmt = new HSSFPatternFormatting(); | |||
patternFmt.setFillBackgroundColor(HSSFColor.RED.index); | |||
HSSFConditionalFormattingRule [] cfRules = | |||
{ | |||
sheet.createConditionalFormattingRule(formula, fontFmt, bordFmt, patternFmt), | |||
sheet.createConditionalFormattingRule(ComparisonOperator.BETWEEN, "1", "2", fontFmt, bordFmt, patternFmt) | |||
}; | |||
short col = 1; | |||
Region [] regions = | |||
{ | |||
new Region(0,col,-1,col) | |||
}; | |||
sheet.addConditionalFormatting(regions, cfRules); | |||
sheet.addConditionalFormatting(regions, cfRules); | |||
// Verification | |||
assertEquals(2, sheet.getNumConditionalFormattings()); | |||
sheet.removeConditionalFormatting(1); | |||
assertEquals(1, sheet.getNumConditionalFormattings()); | |||
HSSFConditionalFormatting cf = sheet.getConditionalFormattingAt(0); | |||
assertNotNull(cf); | |||
regions = cf.getFormattingRegions(); | |||
assertNotNull(regions); | |||
assertEquals(1, regions.length); | |||
Region r = regions[0]; | |||
assertEquals(1, r.getColumnFrom()); | |||
assertEquals(1, r.getColumnTo()); | |||
assertEquals(0, r.getRowFrom()); | |||
assertEquals(-1, r.getRowTo()); | |||
assertEquals(2, cf.getNumberOfRules()); | |||
HSSFConditionalFormattingRule rule1 = cf.getRule(0); | |||
assertEquals("7",rule1.getFormula1()); | |||
assertNull(rule1.getFormula2()); | |||
HSSFConditionalFormattingRule rule2 = cf.getRule(1); | |||
assertEquals("2",rule2.getFormula2()); | |||
assertEquals("1",rule2.getFormula1()); | |||
} | |||
public void XtestOutput() { | |||
HSSFWorkbook wb = new HSSFWorkbook(); | |||
HSSFSheet sheet = wb.createSheet(); | |||
String formula = "7"; | |||
HSSFFontFormatting fontFmt = new HSSFFontFormatting(); | |||
fontFmt.setFontStyle(true, false); | |||
HSSFBorderFormatting bordFmt = new HSSFBorderFormatting(); | |||
bordFmt.setBorderBottom(HSSFBorderFormatting.BORDER_THIN); | |||
bordFmt.setBorderTop(HSSFBorderFormatting.BORDER_THICK); | |||
bordFmt.setBorderLeft(HSSFBorderFormatting.BORDER_DASHED); | |||
bordFmt.setBorderRight(HSSFBorderFormatting.BORDER_DOTTED); | |||
HSSFPatternFormatting patternFmt = new HSSFPatternFormatting(); | |||
patternFmt.setFillBackgroundColor(HSSFColor.RED.index); | |||
HSSFConditionalFormattingRule [] cfRules = | |||
{ | |||
sheet.createConditionalFormattingRule(formula, fontFmt, bordFmt, patternFmt), | |||
sheet.createConditionalFormattingRule(ComparisonOperator.BETWEEN, "1", "2", fontFmt, bordFmt, patternFmt) | |||
}; | |||
short col = 1; | |||
Region [] regions = | |||
{ | |||
new Region(0,col,-1,col) | |||
}; | |||
sheet.addConditionalFormatting(regions, cfRules); | |||
try { | |||
OutputStream os = new FileOutputStream("C:/josh/temp/cfExample.xls"); | |||
wb.write(os); | |||
os.close(); | |||
} catch (IOException e) { | |||
throw new RuntimeException(e); | |||
} | |||
} | |||
public void testReadWrite() { | |||
HSSFWorkbook wb; | |||
try { | |||
InputStream is = new FileInputStream("C:/josh/temp/cfEx.xls"); | |||
wb = new HSSFWorkbook(is); | |||
} catch (IOException e) { | |||
throw new RuntimeException(e); | |||
} | |||
HSSFSheet sheet = wb.getSheetAt(0); | |||
int nCFs = sheet.getNumConditionalFormattings(); | |||
HSSFConditionalFormatting cf = sheet.getConditionalFormattingAt(0); | |||
Region[] regions = cf.getFormattingRegions(); | |||
sheet.removeConditionalFormatting(0); | |||
HSSFFontFormatting fontFmt = new HSSFFontFormatting(); | |||
fontFmt.setFontStyle(false, true); | |||
HSSFConditionalFormattingRule rule1 = cf.getRule(0); | |||
HSSFConditionalFormattingRule rule = sheet.createConditionalFormattingRule(ComparisonOperator.BETWEEN, "5", "10", fontFmt, null, null); | |||
byte[] rawRecord1 = rule1.getCfRuleRecord().getFontFormatting().getRawRecord(); | |||
for (int i = 0; i < rawRecord1.length; i++) { | |||
System.out.print(rawRecord1[i] + ","); | |||
} | |||
System.out.println(); | |||
byte[] rawRecord = fontFmt.getFontFormattingBlock().getRawRecord(); | |||
for (int i = 0; i < rawRecord.length; i++) { | |||
System.out.print(rawRecord[i]+ ","); | |||
} | |||
System.out.println(); | |||
rule.getCfRuleRecord().setFontFormatting(rule1.getCfRuleRecord().getFontFormatting()); | |||
sheet.addConditionalFormatting(regions, new HSSFConditionalFormattingRule[] { rule, }); | |||
HSSFWorkbook wb2; | |||
if(false) try { | |||
ByteArrayOutputStream baos = new ByteArrayOutputStream(); | |||
wb.write(baos); | |||
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); | |||
wb2 = new HSSFWorkbook(bais); | |||
} catch (IOException e) { | |||
throw new RuntimeException(e); | |||
} | |||
try { | |||
OutputStream os = new FileOutputStream("C:/josh/temp/cfEx3.xls"); | |||
wb.write(os); | |||
os.close(); | |||
} catch (IOException e) { | |||
throw new RuntimeException(e); | |||
} | |||
} | |||
} |