Rebased ref, commits from common ancestor: commit 77971aa38eca3a52d559bfa5b9f7344e7e710d2b Author: Andrzej Hunt <andr...@ahunt.org> Date: Mon Jun 1 18:10:29 2015 +0100
Add tests for output unit verification. Change-Id: Ia273a64fdbb5e1fe57f41679e9d77e0df78987de diff --git a/sc/qa/unit/units.cxx b/sc/qa/unit/units.cxx index 4e9c2f9..e2ad7cc 100644 --- a/sc/qa/unit/units.cxx +++ b/sc/qa/unit/units.cxx @@ -205,6 +205,14 @@ void UnitsTest::testUnitVerification() { setNumberFormatUnit(address, "m"); mpDoc->SetValue(address, 1); + // 6th column: header annotation for output verification + address = ScAddress(5, 0, 0); + mpDoc->SetString(address, "foobar [cm]"); + + // 7th column: another header annotation + address = ScAddress(6, 0, 0); + mpDoc->SetString(address, "foobar (cm/s)"); + ScFormulaCell* pCell; ScTokenArray* pTokens; @@ -359,6 +367,52 @@ void UnitsTest::testUnitVerification() { pTokens = pCell->GetCode(); CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc) == FormulaStatus::ERROR_INPUT_INCOMPATIBLE); } + + + // Test output unit verification (i.e. using header annotations) + + // header in [cm], cell with cm + address = ScAddress(5, 1, 0); + mpDoc->SetFormula(address, "=A1"); + pCell = mpDoc->GetFormulaCell(address); + pTokens = pCell->GetCode(); + CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc) == FormulaStatus::VERIFIED); + + + // header in [cm], cell with 100*cm + address.IncRow(); + mpDoc->SetFormula(address, "=100*A1"); + pCell = mpDoc->GetFormulaCell(address); + pTokens = pCell->GetCode(); + CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc) == FormulaStatus::ERROR_OUTPUT_SCALING); + + // header in [cm], cell with kg + address.IncRow(); + mpDoc->SetFormula(address, "=B1"); + pCell = mpDoc->GetFormulaCell(address); + pTokens = pCell->GetCode(); + CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc) == FormulaStatus::ERROR_OUTPUT_INCOMPATIBLE); + + // header in [cm], cell with m + address.IncRow(); + mpDoc->SetFormula(address, "=E1"); + pCell = mpDoc->GetFormulaCell(address); + pTokens = pCell->GetCode(); + CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc) == FormulaStatus::ERROR_OUTPUT_SCALING); + + // header in [cm], cell with 100*m + address.IncRow(); + mpDoc->SetFormula(address, "=100*E1"); + pCell = mpDoc->GetFormulaCell(address); + pTokens = pCell->GetCode(); + CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc) == FormulaStatus::VERIFIED); + + // header in (cm/s), formula resulting in cm/s + address = ScAddress(6, 1, 0); + mpDoc->SetFormula(address, "=A1/C1"); + pCell = mpDoc->GetFormulaCell(address); + pTokens = pCell->GetCode(); + CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc) == FormulaStatus::VERIFIED); } void UnitsTest::testUnitFromFormatStringExtraction() { commit 80c15be131e8bcb9063fd93a5aa2d32a36c8c72b Author: Andrzej Hunt <andr...@ahunt.org> Date: Mon Jun 1 17:53:48 2015 +0100 Return status for formula errors Returning a status (instead of a boolean) means we will be able to print better error messages for the user in future. Change-Id: I0b08913267fedb5735112acc7427156e07e32b31 diff --git a/sc/inc/units.hxx b/sc/inc/units.hxx index b428d40..411fb84 100644 --- a/sc/inc/units.hxx +++ b/sc/inc/units.hxx @@ -38,11 +38,26 @@ struct RangeUnits { bool compatible; }; +/** + * The unit correctness status for a formula. + * UNKNOWN denotes that the units could not be verified + * (this can occur if e.g. an unsupported operator or formula + * is used). + */ +enum class FormulaStatus { + VERIFIED, + UNKNOWN, + ERROR_INPUT_SCALING, + ERROR_INPUT_INCOMPATIBLE, + ERROR_OUTPUT_SCALING, + ERROR_OUTPUT_INCOMPATIBLE +}; + class Units { public: static ::boost::shared_ptr< Units > GetUnits(); - virtual bool verifyFormula(ScTokenArray* pArray, const ScAddress& rFormulaAddress, ScDocument* pDoc) = 0; + virtual FormulaStatus verifyFormula(ScTokenArray* pArray, const ScAddress& rFormulaAddress, ScDocument* pDoc) = 0; /* * Split the input into value and unit, where rInput == rValue + rUnit. diff --git a/sc/qa/unit/units.cxx b/sc/qa/unit/units.cxx index b35cd40..4e9c2f9 100644 --- a/sc/qa/unit/units.cxx +++ b/sc/qa/unit/units.cxx @@ -213,65 +213,65 @@ void UnitsTest::testUnitVerification() { mpDoc->SetFormula(address, "=A1+A2"); pCell = mpDoc->GetFormulaCell(address); pTokens = pCell->GetCode(); - CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc)); + CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc) == FormulaStatus::VERIFIED); - // Test that addition of different units fails + // Test that addition of different units fails - incompatible types address = ScAddress(0, 6, 0); mpDoc->SetFormula(address, "=A1+B1"); pCell = mpDoc->GetFormulaCell(address); pTokens = pCell->GetCode(); - CPPUNIT_ASSERT(!mpUnitsImpl->verifyFormula(pTokens, address, mpDoc)); + CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc) == FormulaStatus::ERROR_INPUT_INCOMPATIBLE); // Test that addition and multiplication works (i.e. kg*s+kg*s) address = ScAddress(0, 7, 0); mpDoc->SetFormula(address, "=A1*B1+A2*B2"); pCell = mpDoc->GetFormulaCell(address); pTokens = pCell->GetCode(); - CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc)); + CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc) == FormulaStatus::VERIFIED); // Test another combination (i.e. cm/s+'cm/s') address = ScAddress(0, 8, 0); mpDoc->SetFormula(address, "=A1/C1+D1"); pCell = mpDoc->GetFormulaCell(address); pTokens = pCell->GetCode(); - CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc)); + CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc) == FormulaStatus::VERIFIED); // Test that another combination fails (cm*kg/s+'cm/s') address = ScAddress(0, 9, 0); mpDoc->SetFormula(address, "=A1*B1/C1+D1"); pCell = mpDoc->GetFormulaCell(address); pTokens = pCell->GetCode(); - CPPUNIT_ASSERT(!mpUnitsImpl->verifyFormula(pTokens, address, mpDoc)); + CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc) == FormulaStatus::ERROR_INPUT_INCOMPATIBLE); // Test that addition of scaled units works (cm + 100*m) address = ScAddress(0, 10, 0); mpDoc->SetFormula(address, "=A1+100*E1"); pCell = mpDoc->GetFormulaCell(address); pTokens = pCell->GetCode(); - CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc)); + CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc) == FormulaStatus::VERIFIED); // 10cm + 100*1m = 110cm - CPPUNIT_ASSERT(mpDoc->GetValue(address) == 110); + CPPUNIT_ASSERT_EQUAL(mpDoc->GetValue(address), 110.0); // But addition of them unscaled fails (cm + m) address = ScAddress(0, 11, 0); mpDoc->SetFormula(address, "=A1+E1"); pCell = mpDoc->GetFormulaCell(address); pTokens = pCell->GetCode(); - CPPUNIT_ASSERT(!mpUnitsImpl->verifyFormula(pTokens, address, mpDoc)); + CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc) == FormulaStatus::ERROR_INPUT_SCALING); // As does wrong scaling (cm+m/50) address = ScAddress(0, 12, 0); mpDoc->SetFormula(address, "=A1+E1/50"); pCell = mpDoc->GetFormulaCell(address); pTokens = pCell->GetCode(); - CPPUNIT_ASSERT(!mpUnitsImpl->verifyFormula(pTokens, address, mpDoc)); + CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc) == FormulaStatus::ERROR_INPUT_SCALING); // And scaling doesn't help when adding incompatible units (kg + 100*m) address = ScAddress(0, 13, 0); mpDoc->SetFormula(address, "=B1+100*E1"); pCell = mpDoc->GetFormulaCell(address); pTokens = pCell->GetCode(); - CPPUNIT_ASSERT(!mpUnitsImpl->verifyFormula(pTokens, address, mpDoc)); + CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc) == FormulaStatus::ERROR_INPUT_INCOMPATIBLE); // Test Ranges: // SUM("kg") @@ -279,49 +279,49 @@ void UnitsTest::testUnitVerification() { mpDoc->SetFormula(address, "=SUM(B1:B3)"); pCell = mpDoc->GetFormulaCell(address); pTokens = pCell->GetCode(); - CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc)); + CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc) == FormulaStatus::VERIFIED); // SUM("cm"&"kg") address.IncRow(); mpDoc->SetFormula(address, "=SUM(A1:B3)"); pCell = mpDoc->GetFormulaCell(address); pTokens = pCell->GetCode(); - CPPUNIT_ASSERT(!mpUnitsImpl->verifyFormula(pTokens, address, mpDoc)); + CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc) == FormulaStatus::ERROR_INPUT_INCOMPATIBLE); // SUM("cm"&"kg") - multiple ranges address.IncRow(); mpDoc->SetFormula(address, "=SUM(A1:A3,B1:B3)"); pCell = mpDoc->GetFormulaCell(address); pTokens = pCell->GetCode(); - CPPUNIT_ASSERT(!mpUnitsImpl->verifyFormula(pTokens, address, mpDoc)); + CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc) == FormulaStatus::ERROR_INPUT_INCOMPATIBLE); // SUM("cm")+SUM("kg") address.IncRow(); mpDoc->SetFormula(address, "=SUM(A1:A3)+SUM(B1:B3)"); pCell = mpDoc->GetFormulaCell(address); pTokens = pCell->GetCode(); - CPPUNIT_ASSERT(!mpUnitsImpl->verifyFormula(pTokens, address, mpDoc)); + CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc) == FormulaStatus::ERROR_INPUT_INCOMPATIBLE); // SUM("cm")/SUM("s")+SUM("cm/s") address.IncRow(); mpDoc->SetFormula(address, "=SUM(A1:A3)/SUM(C1:C3)+SUM(D1:D3)"); pCell = mpDoc->GetFormulaCell(address); pTokens = pCell->GetCode(); - CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc)); + CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc) == FormulaStatus::VERIFIED); // PRODUCT("cm/","s")+"cm" address.IncRow(); mpDoc->SetFormula(address, "=PRODUCT(C1:D1)+A1"); pCell = mpDoc->GetFormulaCell(address); pTokens = pCell->GetCode(); - CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc)); + CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc) == FormulaStatus::VERIFIED); // PRODUCT("cm/","s")+"kg" address.IncRow(); mpDoc->SetFormula(address, "=PRODUCT(C1:D1)+B1"); pCell = mpDoc->GetFormulaCell(address); pTokens = pCell->GetCode(); - CPPUNIT_ASSERT(!mpUnitsImpl->verifyFormula(pTokens, address, mpDoc)); + CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc) == FormulaStatus::ERROR_INPUT_INCOMPATIBLE); // Test that multiple arguments of mixed types work too // Adding multiple cells from one column is ok @@ -329,7 +329,7 @@ void UnitsTest::testUnitVerification() { mpDoc->SetFormula(address, "=SUM(A1,A2:A3)"); pCell = mpDoc->GetFormulaCell(address); pTokens = pCell->GetCode(); - CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc)); + CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc) == FormulaStatus::VERIFIED); // But mixing the columns fails because of mixed units // (This test is primarily to ensure that we can handle arbitrary numbers @@ -338,7 +338,7 @@ void UnitsTest::testUnitVerification() { mpDoc->SetFormula(address, "=SUM(A1,A2:A3,B1:B3,C1,C2,C3)"); pCell = mpDoc->GetFormulaCell(address); pTokens = pCell->GetCode(); - CPPUNIT_ASSERT(!mpUnitsImpl->verifyFormula(pTokens, address, mpDoc)); + CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc) == FormulaStatus::ERROR_INPUT_INCOMPATIBLE); // Do a quick sanity check for all the other supported functions // The following all expect identically united inputs, and should @@ -350,14 +350,14 @@ void UnitsTest::testUnitVerification() { mpDoc->SetFormula(address, "=" + aFunc + "(A1:A2)+A3"); pCell = mpDoc->GetFormulaCell(address); pTokens = pCell->GetCode(); - CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc)); + CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc) == FormulaStatus::VERIFIED); // FOO(cm) + kg address.IncRow(); mpDoc->SetFormula(address, "=" + aFunc + "(A1:A2)+B3"); pCell = mpDoc->GetFormulaCell(address); pTokens = pCell->GetCode(); - CPPUNIT_ASSERT(!mpUnitsImpl->verifyFormula(pTokens, address, mpDoc)); + CPPUNIT_ASSERT(mpUnitsImpl->verifyFormula(pTokens, address, mpDoc) == FormulaStatus::ERROR_INPUT_INCOMPATIBLE); } } diff --git a/sc/source/core/units/unitsimpl.cxx b/sc/source/core/units/unitsimpl.cxx index 567265b..84d5c0e 100644 --- a/sc/source/core/units/unitsimpl.cxx +++ b/sc/source/core/units/unitsimpl.cxx @@ -105,7 +105,7 @@ UnitsResult UnitsImpl::getOutputUnitsForOpCode(stack< RAUSItem >& rStack, const switch (aOpCode) { case ocNot: if (!pUnit.isDimensionless()) { - return { UnitsStatus::UNITS_INVALID, boost::none }; + return { UnitsStatus::UNITS_INVALID_INCOMPATIBLE, boost::none }; } // We just keep the same unit (in this case no unit) so can // fall through. @@ -147,10 +147,12 @@ UnitsResult UnitsImpl::getOutputUnitsForOpCode(stack< RAUSItem >& rStack, const // The two units are identical, hence we can return either. pOut = pFirstUnit; SAL_INFO("sc.units", "verified equality for unit " << pFirstUnit); + } else if (pFirstUnit.areConvertibleTo(pSecondUnit)) { + return { UnitsStatus::UNITS_INVALID_SCALING, boost::none }; } else { - return { UnitsStatus::UNITS_INVALID, boost::none }; - // TODO: notify/link UI. + return { UnitsStatus::UNITS_INVALID_INCOMPATIBLE, boost::none }; } + break; case ocMul: pOut = pFirstUnit * pSecondUnit; @@ -213,8 +215,13 @@ UnitsResult UnitsImpl::getOutputUnitsForOpCode(stack< RAUSItem >& rStack, const aFirstUnit = aUnitsStack.top(); } else { UtUnit aCurrentUnit(aUnitsStack.top()); + if (aFirstUnit.get() != aCurrentUnit) { - return { UnitsStatus::UNITS_INVALID, boost::none }; + if (aFirstUnit.get().areConvertibleTo(aCurrentUnit)) { + return { UnitsStatus::UNITS_INVALID_SCALING, boost::none }; + } else { + return { UnitsStatus::UNITS_INVALID_INCOMPATIBLE, boost::none }; + } } } aUnitsStack.pop(); @@ -226,8 +233,13 @@ UnitsResult UnitsImpl::getOutputUnitsForOpCode(stack< RAUSItem >& rStack, const aFirstUnit = getUnitForCell(aIt.GetPos(), pDoc); } else { UtUnit aCurrentUnit = getUnitForCell(aIt.GetPos(), pDoc); + if (aFirstUnit.get() != aCurrentUnit) { - return { UnitsStatus::UNITS_INVALID, boost::none }; + if (aFirstUnit.get().areConvertibleTo(aCurrentUnit)) { + return { UnitsStatus::UNITS_INVALID_SCALING, boost::none }; + } else { + return { UnitsStatus::UNITS_INVALID_INCOMPATIBLE, boost::none }; + } } } } while (aIt.next()); @@ -510,8 +522,7 @@ HeaderUnitDescriptor UnitsImpl::findHeaderUnitForCell(const ScAddress& rCellAddr return { false, UtUnit(), boost::optional< ScAddress >(), "", -1 }; } -// getUnitForRef: check format -> if not in format, use more complicated method? (Format overrides header definition) -bool UnitsImpl::verifyFormula(ScTokenArray* pArray, const ScAddress& rFormulaAddress, ScDocument* pDoc) { +FormulaStatus UnitsImpl::verifyFormula(ScTokenArray* pArray, const ScAddress& rFormulaAddress, ScDocument* pDoc) { #if DEBUG_FORMULA_COMPILER pArray->Dump(); #endif @@ -532,7 +543,7 @@ bool UnitsImpl::verifyFormula(ScTokenArray* pArray, const ScAddress& rFormulaAdd // unparseable formulas? // (or even have a "can't be verified" state too?) // see below for more.x - return false; + return FormulaStatus::UNKNOWN; } aStack.push( { RAUSItemType::UNITS, aUnit } ); @@ -551,11 +562,13 @@ bool UnitsImpl::verifyFormula(ScTokenArray* pArray, const ScAddress& rFormulaAdd UnitsResult aResult = getOutputUnitsForOpCode(aStack, pToken, pDoc); switch (aResult.status) { - case UnitsStatus::UNITS_INVALID: - return false; + case UnitsStatus::UNITS_INVALID_SCALING: + return FormulaStatus::ERROR_INPUT_SCALING; + case UnitsStatus::UNITS_INVALID_INCOMPATIBLE: + return FormulaStatus::ERROR_INPUT_INCOMPATIBLE; case UnitsStatus::UNITS_UNKNOWN: // Unsupported hence we stop processing. - return true; + return FormulaStatus::UNKNOWN; case UnitsStatus::UNITS_VALID: assert(aResult.units); // ensure that we have the optional unit assert(aResult.units->isValid()); @@ -583,26 +596,30 @@ bool UnitsImpl::verifyFormula(ScTokenArray* pArray, const ScAddress& rFormulaAdd // was correct. // TODO: maybe we should have a "unverified" return state instead? SAL_WARN("sc.units", "Unrecognised token type " << pToken->GetType()); - return true; + return FormulaStatus::UNKNOWN; } } if (aStack.size() != 1) { SAL_WARN("sc.units", "Wrong number of units on stack, should be 1, actual number: " << aStack.size()); - return false; + return FormulaStatus::UNKNOWN; } else if (aStack.top().type != RAUSItemType::UNITS) { SAL_WARN("sc.units", "End of verification: item on stack does not contain units"); - return false; + return FormulaStatus::UNKNOWN; } HeaderUnitDescriptor aHeader = findHeaderUnitForCell(rFormulaAddress, pDoc); UtUnit aResultUnit = boost::get< UtUnit>(aStack.top().item); if (aHeader.valid && aHeader.unit != aResultUnit) { - return false; + if (aHeader.unit.areConvertibleTo(aResultUnit)) { + return FormulaStatus::ERROR_OUTPUT_SCALING; + } else { + return FormulaStatus::ERROR_OUTPUT_INCOMPATIBLE; + } } - return true; + return FormulaStatus::VERIFIED; } bool IsDigit(sal_Unicode c) { diff --git a/sc/source/core/units/unitsimpl.hxx b/sc/source/core/units/unitsimpl.hxx index 176a34d..b0fb137 100644 --- a/sc/source/core/units/unitsimpl.hxx +++ b/sc/source/core/units/unitsimpl.hxx @@ -45,7 +45,8 @@ namespace test { enum class UnitsStatus { UNITS_VALID, UNITS_UNKNOWN, - UNITS_INVALID + UNITS_INVALID_SCALING, + UNITS_INVALID_INCOMPATIBLE }; /** @@ -91,7 +92,7 @@ public: UnitsImpl(); virtual ~UnitsImpl(); - virtual bool verifyFormula(ScTokenArray* pArray, const ScAddress& rFormulaAddress, ScDocument* pDoc) SAL_OVERRIDE; + virtual FormulaStatus verifyFormula(ScTokenArray* pArray, const ScAddress& rFormulaAddress, ScDocument* pDoc) SAL_OVERRIDE; virtual bool splitUnitsFromInputString(const OUString& rInput, OUString& rValue, OUString& rUnit) SAL_OVERRIDE; virtual bool isCellConversionRecommended(const ScAddress& rCellAddress, ScDocument* pDoc, diff --git a/sc/source/ui/inc/viewfunc.hxx b/sc/source/ui/inc/viewfunc.hxx index a6b36b8..5574fcf 100644 --- a/sc/source/ui/inc/viewfunc.hxx +++ b/sc/source/ui/inc/viewfunc.hxx @@ -58,6 +58,10 @@ namespace sc { struct ColRowSpan; +namespace units { +enum class FormulaStatus; +} + } namespace com { namespace sun { namespace star { namespace datatransfer { class XTransferable; } } } } @@ -373,7 +377,9 @@ private: void CopyAutoSpellData( FillDir eDir, SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, sal_uLong nCount ); - void NotifyUnitErrorInFormula( const ScAddress& rAddress, ScDocument* pDoc ); + void NotifyUnitErrorInFormula( const ScAddress& rAddress, + ScDocument* pDoc, + const sc::units::FormulaStatus& rStatus); DECL_LINK( EditUnitErrorFormulaHandler, PushButton* ); void NotifyUnitConversionRecommended( const ScAddress& rCellAddress, diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx index b156587..b9a08c3 100644 --- a/sc/source/ui/view/viewfunc.cxx +++ b/sc/source/ui/view/viewfunc.cxx @@ -84,6 +84,8 @@ #include <boost/scoped_ptr.hpp> #include <boost/shared_ptr.hpp> +using namespace sc::units; + static void lcl_PostRepaintCondFormat( const ScConditionalFormat *pCondFmt, ScDocShell *pDocSh ) { if( pCondFmt ) @@ -467,8 +469,9 @@ void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, SCTAB nTab, } #ifdef ENABLE_CALC_UNITVERIFICATION - boost::shared_ptr< sc::units::Units > pUnits = sc::units::Units::GetUnits(); - if ( pUnits->verifyFormula( pArr, aPos, pDoc ) ) + boost::shared_ptr< Units > pUnits = Units::GetUnits(); + FormulaStatus aStatus = pUnits->verifyFormula( pArr, aPos, pDoc ); + if ( aStatus == FormulaStatus::VERIFIED || aStatus == FormulaStatus::UNKNOWN ) { SAL_INFO( "sc.units", "verification successful" ); @@ -484,7 +487,7 @@ void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, SCTAB nTab, else { SAL_INFO( "sc.units", "verification failed" ); - NotifyUnitErrorInFormula( aPos, pDoc ); + NotifyUnitErrorInFormula( aPos, pDoc, aStatus ); } #endif } while ( bAgain ); @@ -580,7 +583,7 @@ void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, SCTAB nTab, } #ifdef ENABLE_CALC_UNITVERIFICATION - boost::shared_ptr< sc::units::Units > pUnits = sc::units::Units::GetUnits(); + boost::shared_ptr< Units > pUnits = Units::GetUnits(); OUString sHeaderUnit, sCellUnit; ScAddress aHeaderAddress; @@ -2838,8 +2841,10 @@ void ScViewFunc::UpdateSelectionArea( const ScMarkData& rSel, ScPatternAttr* pAt pTabViewShell->AdjustBlockHeight(false, const_cast<ScMarkData*>(&rSel)); } -void ScViewFunc::NotifyUnitErrorInFormula( const ScAddress& rAddress, ScDocument* pDoc ) +void ScViewFunc::NotifyUnitErrorInFormula( const ScAddress& rAddress, ScDocument* pDoc, const FormulaStatus& rStatus ) { + (void) rStatus; + SfxViewFrame* pViewFrame = GetViewData().GetViewShell()->GetFrame(); // We use the cell address as the infobar id to allow us to easily get back to the @@ -2967,7 +2972,7 @@ IMPL_LINK( ScViewFunc, UnitConversionRecommendedHandler, UnitConversionPushButto // Do conversion first, and only then remove the infobar as we need data from the infobar // (specifically from the pushbutton) to do the conversion. #ifdef ENABLE_CALC_UNITVERIFICATION - boost::shared_ptr< sc::units::Units > pUnits = sc::units::Units::GetUnits(); + boost::shared_ptr< Units > pUnits = Units::GetUnits(); ScDocShellModificator aModificator( *pButton->mpDocSh ); commit 1172fbb2707c5c9d08f4ae2dc9584000c2a13246 Author: Andrzej Hunt <andr...@ahunt.org> Date: Mon Jun 1 17:51:48 2015 +0100 Invalid formulas can't have unit correctness verified. Formulas that can't be processed will already be treated as invalid, we shouldn't additionally complain about unit verification in this case. Change-Id: I0556bf76b6e2343cdf27ec53669e6fd78da9280b diff --git a/sc/source/core/units/unitsimpl.cxx b/sc/source/core/units/unitsimpl.cxx index e764aad..567265b 100644 --- a/sc/source/core/units/unitsimpl.cxx +++ b/sc/source/core/units/unitsimpl.cxx @@ -95,10 +95,7 @@ UnitsResult UnitsImpl::getOutputUnitsForOpCode(stack< RAUSItem >& rStack, const if (nOpCode >= SC_OPCODE_START_UN_OP && nOpCode < SC_OPCODE_STOP_UN_OP) { - if (rStack.size() == 0) { - SAL_WARN("sc.units", "Single item opcode failed (no stack items, or range used)"); - return { UnitsStatus::UNITS_INVALID, boost::none }; - } else if (rStack.top().type != RAUSItemType::UNITS) { + if ((rStack.size() == 0) || (rStack.top().type != RAUSItemType::UNITS)) { return { UnitsStatus::UNITS_UNKNOWN, boost::none }; } @@ -129,12 +126,7 @@ UnitsResult UnitsImpl::getOutputUnitsForOpCode(stack< RAUSItem >& rStack, const } else if (nOpCode >= SC_OPCODE_START_BIN_OP && nOpCode < SC_OPCODE_STOP_BIN_OP) { - if (rStack.size() < 2) { - SAL_WARN("sc.units", "less than two items on stack when attempting binary operation"); - return { UnitsStatus::UNITS_INVALID, boost::none }; - } - - if (rStack.top().type != RAUSItemType::UNITS) { + if ((rStack.size() < 2) || (rStack.top().type != RAUSItemType::UNITS)) { return { UnitsStatus::UNITS_UNKNOWN, boost::none }; } UtUnit pSecondUnit = boost::get<UtUnit>(rStack.top().item); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits