summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Ni <benjaminniri@hotmail.com>2015-06-07 16:21:54 +0100
committerjan iversen <jani@documentfoundation.org>2016-01-05 11:53:13 +0000
commitc01bcbc88522c5f86820105a45e2e5593ae01501 (patch)
tree02eceec0281e9b7f0d6dd8a25a0041298372b191
parentf193b1869159377aaa28844790a098cc127b5c5e (diff)
Time wraparound validation feature
Change-Id: I49305167b1062dbe8158fdb446859138ba283da2 Reviewed-on: https://gerrit.libreoffice.org/16136 Tested-by: Jenkins <ci@libreoffice.org> Tested-by: jan iversen <jani@documentfoundation.org> Reviewed-by: jan iversen <jani@documentfoundation.org>
-rw-r--r--sc/inc/conditio.hxx2
-rw-r--r--sc/qa/unit/ucalc.cxx26
-rw-r--r--sc/qa/unit/ucalc.hxx2
-rw-r--r--sc/source/core/data/validat.cxx49
4 files changed, 78 insertions, 1 deletions
diff --git a/sc/inc/conditio.hxx b/sc/inc/conditio.hxx
index d33ecc6fd8aa..69f8ddd9b739 100644
--- a/sc/inc/conditio.hxx
+++ b/sc/inc/conditio.hxx
@@ -154,10 +154,12 @@ public:
class SC_DLLPUBLIC ScConditionEntry : public ScFormatEntry
{
// stored data:
+protected:
ScConditionMode eOp;
sal_uInt16 nOptions;
double nVal1; // input or calculated
double nVal2;
+private:
OUString aStrVal1; // input or calculated
OUString aStrVal2;
OUString aStrNmsp1; // namespace to be used on (re)compilation, e.g. in XML import
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index ccb361942419..7d836b1d13ce 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -45,6 +45,7 @@
#include "interpre.hxx"
#include "columniterator.hxx"
#include "types.hxx"
+#include "validat.hxx"
#include "conditio.hxx"
#include "colorscale.hxx"
#include "fillinfo.hxx"
@@ -5690,6 +5691,31 @@ void Test::testCondFormatInsertRow()
m_pDoc->DeleteTab(0);
}
+void Test::testValidity()
+{
+ m_pDoc->InsertTab(0, "Test");
+
+ m_pDoc->SetValue( 0, 0, 0, 22.0/24.0 );
+ m_pDoc->SetValue( 2, 0, 0, 23.0/24.0 );
+ m_pDoc->SetValue( 4, 0, 0, 24.0/24.0 );
+
+ // invalid between 2300-0100 hrs
+ ScValidationData* pData0 = new ScValidationData( SC_VALID_TIME, SC_COND_NOTBETWEEN,
+ OUString::number(23.0/24.0), OUString::number(1.0/24.0), m_pDoc, ScAddress(0,0,0) );
+ ScValidationData* pData1 = new ScValidationData( SC_VALID_TIME, SC_COND_NOTBETWEEN,
+ OUString::number(23.0/24.0), OUString::number(1.0/24.0), m_pDoc, ScAddress(2,0,0) );
+ ScValidationData* pData2 = new ScValidationData( SC_VALID_TIME, SC_COND_NOTBETWEEN,
+ OUString::number(23.0/24.0), OUString::number(1.0/24.0), m_pDoc, ScAddress(4,0,0) );
+
+ ScRefCellValue aCell;
+ aCell.assign(*m_pDoc, ScAddress(0,0,0));
+ CPPUNIT_ASSERT( pData0->IsDataValid( aCell, ScAddress(0,0,0) ) );
+ aCell.assign(*m_pDoc, ScAddress(2,0,0));
+ CPPUNIT_ASSERT( !pData1->IsDataValid( aCell, ScAddress(2,0,0) ) );
+ aCell.assign(*m_pDoc, ScAddress(4,0,0));
+ CPPUNIT_ASSERT( !pData2->IsDataValid( aCell, ScAddress(4,0,0) ) );
+}
+
void Test::testCondFormatInsertDeleteSheets()
{
m_pDoc->InsertTab(0, "Test");
diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx
index b3e5bf396504..608531127d59 100644
--- a/sc/qa/unit/ucalc.hxx
+++ b/sc/qa/unit/ucalc.hxx
@@ -433,6 +433,7 @@ public:
void testCondFormatINSDEL();
void testCondFormatInsertRow();
void testCondFormatInsertCol();
+ void testValidity();
void testCondFormatInsertDeleteSheets();
void testCondCopyPaste();
void testCondCopyPasteSingleCell(); //e.g. fdo#82503
@@ -669,6 +670,7 @@ public:
CPPUNIT_TEST(testCondFormatINSDEL);
CPPUNIT_TEST(testCondFormatInsertRow);
CPPUNIT_TEST(testCondFormatInsertCol);
+ CPPUNIT_TEST(testValidity);
CPPUNIT_TEST(testCondFormatInsertDeleteSheets);
CPPUNIT_TEST(testCondCopyPaste);
CPPUNIT_TEST(testCondCopyPasteSingleCell);
diff --git a/sc/source/core/data/validat.cxx b/sc/source/core/data/validat.cxx
index 437434a3f221..c4c4ba66875e 100644
--- a/sc/source/core/data/validat.cxx
+++ b/sc/source/core/data/validat.cxx
@@ -543,7 +543,54 @@ bool ScValidationData::IsDataValid( ScRefCellValue& rCell, const ScAddress& rPos
OSL_FAIL("not yet done");
break;
}
-
+ if (eDataMode == SC_VALID_TIME) {
+ // consider only time portion (i.e. decimal)
+ double nComp1 = (nVal1 - floor(nVal1));
+ double nComp2 = (nVal2 - floor(nVal2));
+ double nInVal = (nVal - floor(nVal ));
+ switch (eOp)
+ {
+ case SC_COND_NONE:
+ break; // Always sal_False
+ case SC_COND_EQUAL:
+ bOk = ::rtl::math::approxEqual( nInVal, nComp1 );
+ break;
+ case SC_COND_NOTEQUAL:
+ bOk = !::rtl::math::approxEqual( nInVal, nComp1 );
+ break;
+ case SC_COND_GREATER:
+ bOk = ( nInVal > nComp1 ) && !::rtl::math::approxEqual( nInVal, nComp1 );
+ break;
+ case SC_COND_EQGREATER:
+ bOk = ( nInVal >= nComp1 ) || ::rtl::math::approxEqual( nInVal, nComp1 );
+ break;
+ case SC_COND_LESS:
+ bOk = ( nInVal < nComp1 ) && !::rtl::math::approxEqual( nInVal, nComp1 );
+ break;
+ case SC_COND_EQLESS:
+ bOk = ( nInVal <= nComp1 ) || ::rtl::math::approxEqual( nInVal, nComp1 );
+ break;
+ case SC_COND_BETWEEN:
+ if (nComp2 < nComp1) // time wraparound
+ bOk = ( nInVal >= nComp1 || nInVal <= nComp2 ) ||
+ ::rtl::math::approxEqual( nInVal, nComp1 ) || ::rtl::math::approxEqual( nInVal, nComp2 );
+ else
+ bOk = ( nInVal >= nComp1 && nInVal <= nComp2 ) ||
+ ::rtl::math::approxEqual( nInVal, nComp1 ) || ::rtl::math::approxEqual( nInVal, nComp2 );
+ break;
+ case SC_COND_NOTBETWEEN:
+ if (nComp2 < nComp1) // time wraparound
+ bOk = ( nInVal < nComp1 && nInVal > nComp2 ) &&
+ !::rtl::math::approxEqual( nInVal, nComp1 ) && !::rtl::math::approxEqual( nInVal, nComp2 );
+ else
+ bOk = ( nInVal < nComp1 || nInVal > nComp2 ) &&
+ !::rtl::math::approxEqual( nInVal, nComp1 ) && !::rtl::math::approxEqual( nInVal, nComp2 );
+ break;
+ default:
+ SAL_WARN("sc", "unknown operation at ScValidationData::IsDataValid()");
+ break;
+ }
+ }
return bOk;
}