From 8572d4b71c8a19311459870f2a2ab213020acfd9 Mon Sep 17 00:00:00 2001
From: Greg Woolsey formula ref + range top-left + current cell range offset
formula ref + current cell ref* @param ptgs * @param target cell within the region to use. * @param region containing the cell @@ -854,22 +859,11 @@ public final class WorkbookEvaluator { throw new IllegalArgumentException(target + " is not within " + region); } - return adjustRegionRelativeReference(ptgs, target.getRow() - region.getFirstRow(), target.getCol() - region.getFirstColumn()); - } - - /** - * Adjust the formula relative cell references by a given delta - * @param ptgs - * @param deltaRow target row offset from the top left cell of a region - * @param deltaColumn target column offset from the top left cell of a region - * @return true if any Ptg references were shifted - * @throws IndexOutOfBoundsException if the resulting shifted row/column indexes are over the document format limits - * @throws IllegalArgumentException if either of the deltas are negative, as the assumption is we are shifting formulas - * relative to the top left cell of a region. - */ - protected boolean adjustRegionRelativeReference(Ptg[] ptgs, int deltaRow, int deltaColumn) { - if (deltaRow < 0) throw new IllegalArgumentException("offset row must be positive"); - if (deltaColumn < 0) throw new IllegalArgumentException("offset column must be positive"); + //return adjustRegionRelativeReference(ptgs, target.getRow() - region.getFirstRow(), target.getCol() - region.getFirstColumn()); + + int deltaRow = target.getRow(); + int deltaColumn = target.getCol(); + boolean shifted = false; for (Ptg ptg : ptgs) { // base class for cell reference "things" diff --git a/src/java/org/apache/poi/ss/usermodel/ConditionalFormattingRule.java b/src/java/org/apache/poi/ss/usermodel/ConditionalFormattingRule.java index b008dd566e..2f19d9e3e5 100644 --- a/src/java/org/apache/poi/ss/usermodel/ConditionalFormattingRule.java +++ b/src/java/org/apache/poi/ss/usermodel/ConditionalFormattingRule.java @@ -152,6 +152,13 @@ public interface ConditionalFormattingRule extends DifferentialStyleProvider { */ String getFormula2(); + /** + * XSSF rules store textual condition values as an attribute and also as a formula that needs shifting. Using the attribute is simpler/faster. + * HSSF rules don't have this and return null. We can fall back on the formula for those (AFAIK). + * @return condition text if it exists, or null + */ + String getText(); + /** * The priority of the rule, if defined, otherwise 0. *
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConditionalFormattingRule.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConditionalFormattingRule.java
index f3904406ea..2384f85e42 100644
--- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConditionalFormattingRule.java
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConditionalFormattingRule.java
@@ -417,6 +417,10 @@ public class XSSFConditionalFormattingRule implements ConditionalFormattingRule
return _cfRule.sizeOfFormulaArray() == 2 ? _cfRule.getFormulaArray(1) : null;
}
+ public String getText() {
+ return _cfRule.getText();
+ }
+
/**
* Conditional format rules don't define stripes, so always 0
* @see org.apache.poi.ss.usermodel.DifferentialStyleProvider#getStripeSize()
diff --git a/src/ooxml/testcases/org/apache/poi/ss/usermodel/ConditionalFormattingEvalTest.java b/src/ooxml/testcases/org/apache/poi/ss/usermodel/ConditionalFormattingEvalTest.java
index d54ba60c87..3b1155fe73 100644
--- a/src/ooxml/testcases/org/apache/poi/ss/usermodel/ConditionalFormattingEvalTest.java
+++ b/src/ooxml/testcases/org/apache/poi/ss/usermodel/ConditionalFormattingEvalTest.java
@@ -23,6 +23,7 @@ import java.util.List;
import org.apache.poi.ss.formula.ConditionalFormattingEvaluator;
import org.apache.poi.ss.formula.EvaluationConditionalFormatRule;
+import org.apache.poi.ss.formula.eval.NotImplementedException;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.XSSFTestDataSamples;
import org.apache.poi.xssf.usermodel.XSSFColor;
@@ -130,6 +131,64 @@ public class ConditionalFormattingEvalTest {
assertEquals("wrong bg color for " + ref, "FFFFFF00", getColor(rules.get(0).getRule().getPatternFormatting().getFillBackgroundColorColor()));
}
+ @Test
+ public void testRepeatedEval() throws Exception {
+ wb = XSSFTestDataSamples.openSampleWorkbook("test_conditional_formatting.xlsx");
+ formulaEval = new XSSFFormulaEvaluator(wb);
+ cfe = new ConditionalFormattingEvaluator(wb, formulaEval);
+
+ sheet = wb.getSheetAt(0);
+ try {
+ getRulesFor(2, 1);
+ fail("Got rules when an unsupported function error was expected.");
+ } catch (NotImplementedException e) {
+ // expected
+ }
+
+ try {
+ getRulesFor(2, 1);
+ fail("Got rules the second time when an unsupported function error was expected.");
+ } catch (NotImplementedException e) {
+ // expected
+ }
+
+ }
+
+ @Test
+ public void testCellValueIsWrongType() throws Exception {
+ wb = XSSFTestDataSamples.openSampleWorkbook("conditional_formatting_cell_is.xlsx");
+ formulaEval = new XSSFFormulaEvaluator(wb);
+ cfe = new ConditionalFormattingEvaluator(wb, formulaEval);
+
+ sheet = wb.getSheetAt(1);
+
+ assertEquals("wrong # of matching rules", 1, getRulesFor(3, 1).size());
+ }
+
+ @Test
+ public void testRangeCondition() throws Exception {
+ wb = XSSFTestDataSamples.openSampleWorkbook("conditional_formatting_multiple_ranges.xlsx");
+ formulaEval = new XSSFFormulaEvaluator(wb);
+ cfe = new ConditionalFormattingEvaluator(wb, formulaEval);
+
+ sheet = wb.getSheetAt(0);
+
+ assertEquals("wrong # of matching rules", 0, getRulesFor(0, 0).size());
+ assertEquals("wrong # of matching rules", 0, getRulesFor(1, 0).size());
+ assertEquals("wrong # of matching rules", 0, getRulesFor(2, 0).size());
+ assertEquals("wrong # of matching rules", 1, getRulesFor(3, 0).size());
+ assertEquals("wrong # of matching rules", 0, getRulesFor(0, 1).size());
+ assertEquals("wrong # of matching rules", 0, getRulesFor(1, 1).size());
+ assertEquals("wrong # of matching rules", 1, getRulesFor(2, 1).size());
+ assertEquals("wrong # of matching rules", 1, getRulesFor(3, 1).size());
+ assertEquals("wrong # of matching rules", 1, getRulesFor(0, 3).size());
+ assertEquals("wrong # of matching rules", 0, getRulesFor(1, 3).size());
+ assertEquals("wrong # of matching rules", 1, getRulesFor(2, 3).size());
+ assertEquals("wrong # of matching rules", 0, getRulesFor(0, 6).size());
+ assertEquals("wrong # of matching rules", 0, getRulesFor(3, 6).size());
+ assertEquals("wrong # of matching rules", 0, getRulesFor(2, 6).size());
+ }
+
private List CDBQmIU6oRMtFwRME*`&Wqa#A15brCg{QdF 2f*JLjZkCjrYEPmpXqOe2UTz9QPB$v~vDit0Gu7C$7>*=$nsKpmCs2kc&
z25&5=S8PRctFcxaLc4e_e2Pe}+sDbjhDDa~3Yx0V^2=S&%LIP
zrNVswyj2431y=xbPNNjk_4r^3e(P%8#HP;t?w^)39LIe^0s{Iw@-3o240|rzs_Zx6
z=R3hDFuq6?%O(3e!oeciVwBg;!sudIfbp|zN6r2psF}XNz!@GJ-NU5ek;oA--i&sJ
zlaV7hyq3f4qn(^{%(RAlaYPUbQIBo6eNU|!1g~7rfF)8JJ}HR98zo46IG7xi6TrfJ
z7*MfvHAt6-d%-Xa4Aj8ESJ&=>b4&4@1-++Gg}Q!Xr;o~-#1A&?06t|+9sCF5_FsZP
zTYY=ZIsB7J68AWMJ$qN%d{bNFjxW0!Ub6GOJ9nHL$`_-v`99(pT*^qIwvtLMQta7a
zI_S(WAt#h(GTNvE!<{1b_VK-@u!!0|!YbbAd(e{a8Hmsko>mDBY-q0Rx
zP(Q
MVXcD
zjXrn-y
C;4-)
z@^V+7E-%|XC-3;o+G0bv2{QN5Q{C_9Q`P)#A0BTLw_*Cr*E&O=FMZ_QZ*Q%*5N9O@
zcjsf`-MpT6=jHPLpO?9yo02mDaQJZ;&PP;yZgw>ohebHXOhe!&{AY|&2#j7i5H{K}
zkD?|3)pQ7rJ8jD@o0TXe{a_tD-Np_ZKWAGBl47exY5~`cqueyDTz{c*CLQkV@T9JS
z%O7!Ff(eN?)e0wI
2cl-sUm&^WF>r=nCVWR6ri99(lQJ@3sU
ztLvw^AH{N*IisXnMdn&T$XZj8XI>CktOy~FKKB!d*3#W2(#9Jn6Qc-0dc@Qou`g>{
z7;h87v)T}N^CwW*8Sw`tI)&J5fepMg1kl8<-j!V=JLeH%d#bAkkRP-)m%rxhl@h-D
zXWCH3K5TBA1%qZ7EzwXl^(}(%g{OHAb7Y34o9lhJZ$5wicDNm
Ibr*z<{ifB@d)2@#MYS9(rWln{7vW1
z*>nrn`%QeV3E(%xqn0eU#|@aT(-Vc7{H}T?Z0NC<;bg_Yf{*3SMqogiOAa%URz%uX~J75@cVgnD)zK?DIkIwtc#wSA;7R1Q>pz8fYg_ceZzh%9V?uk++Y0
z>rJGkmutjBVEpSLKHk%-Wcr|>ZI^G72>9U}A2V12*aV-kkIWrZdNh=|BoXitPgBsb
z%MRx$
<#6@<14
z<#?R%#m=!~%hJg)ZP@-`Ad2=NoMy4PQxPc77Od~)s!S~76YXr|heKngl
z?!W#X0u$LsFO1YJFoN)Kf-NZ+j>AUqB~3lx4+WmYr$*u@Rr&8QV=Le8=4jBmu|js#
zc_{^wO@S9v)qRBDW?|+#SVYxc%YvK;qx9|z6dd910zO~w2&iWKo8%~}Tj3IldwmjO?g}=3
z#wWR+q?mUMMIi(IHG$%Li3vXx7kEu=@UZ;zAKLo&F2W5Qx(T