[Libreoffice-commits] core.git: Branch 'libreoffice-5-1' - formula/source include/formula reportdesign/source sc/inc sc/qa sc/source

Eike Rathke erack at redhat.com
Fri Dec 18 14:34:40 PST 2015


 formula/source/ui/dlg/formula.cxx         |   32 ++++++++++++++++++------------
 include/formula/IFunctionDescription.hxx  |    2 -
 reportdesign/source/ui/dlg/Formula.cxx    |    2 -
 reportdesign/source/ui/inc/Formula.hxx    |    2 -
 sc/inc/simpleformulacalc.hxx              |    6 +++--
 sc/qa/unit/ucalc.cxx                      |    4 +--
 sc/source/core/data/simpleformulacalc.cxx |   16 ++++++++-------
 sc/source/ui/app/inputhdl.cxx             |    4 +--
 sc/source/ui/formdlg/formula.cxx          |    8 ++++---
 sc/source/ui/inc/formula.hxx              |    2 -
 10 files changed, 46 insertions(+), 32 deletions(-)

New commits:
commit 9a9bf646cfc388324df017fb0b9e0f6ad71acabd
Author: Eike Rathke <erack at redhat.com>
Date:   Fri Dec 18 23:22:24 2015 +0100

    Formula Wizard: evaluating expressions always in matrix context is wrong
    
    Change-Id: I276f7bbf2bd6fa7c67d8691634ad9d79e4a08b1c
    (cherry picked from commit dc89367a5622748dd7c37b89ac300a663b8b98e9)

diff --git a/formula/source/ui/dlg/formula.cxx b/formula/source/ui/dlg/formula.cxx
index bb4f46d..0d0a646 100644
--- a/formula/source/ui/dlg/formula.cxx
+++ b/formula/source/ui/dlg/formula.cxx
@@ -77,9 +77,9 @@ public:
         RefInputStartBefore( RefEdit* pEdit, RefButton* pButton );
     void            RefInputStartAfter( RefEdit* pEdit, RefButton* pButton );
     void            RefInputDoneAfter( bool bForced );
-    bool        CalcValue( const OUString& rStrExp, OUString& rStrResult );
-    bool        CalcStruct( const OUString& rStrExp);
-    void            UpdateValues();
+    bool            CalcValue( const OUString& rStrExp, OUString& rStrResult, bool bForceMatrixFormula = false );
+    bool            CalcStruct( const OUString& rStrExp, bool bForceRecalcStruct = false );
+    void            UpdateValues( bool bForceRecalcStruct = false );
     void            DeleteArgs();
     sal_Int32       GetFunctionPos(sal_Int32 nPos);
     void            ClearAllParas();
@@ -568,7 +568,7 @@ sal_Int32 FormulaDlg_Impl::GetFunctionPos(sal_Int32 nPos)
     return nFuncPos;
 }
 
-bool FormulaDlg_Impl::CalcValue( const OUString& rStrExp, OUString& rStrResult )
+bool FormulaDlg_Impl::CalcValue( const OUString& rStrExp, OUString& rStrResult, bool bForceMatrixFormula )
 {
     bool bResult = true;
 
@@ -578,7 +578,7 @@ bool FormulaDlg_Impl::CalcValue( const OUString& rStrExp, OUString& rStrResult )
 
         if ( !Application::AnyInput( VclInputFlags::KEYBOARD ) )
         {
-            bResult = m_pHelper->calculateValue(rStrExp,rStrResult);
+            bResult = m_pHelper->calculateValue( rStrExp, rStrResult, bForceMatrixFormula || m_pBtnMatrix->IsChecked());
         }
         else
             bResult = false;
@@ -587,7 +587,7 @@ bool FormulaDlg_Impl::CalcValue( const OUString& rStrExp, OUString& rStrResult )
     return bResult;
 }
 
-void FormulaDlg_Impl::UpdateValues()
+void FormulaDlg_Impl::UpdateValues( bool bForceRecalcStruct )
 {
     OUString aStrResult;
     if ( CalcValue( pFuncDesc->getFormula( m_aArguments ), aStrResult ) )
@@ -603,15 +603,15 @@ void FormulaDlg_Impl::UpdateValues()
         aStrResult.clear();
         m_pWndFormResult->SetText( aStrResult );
     }
-    CalcStruct(pMEdit->GetText());
+    CalcStruct( pMEdit->GetText(), bForceRecalcStruct);
 }
 
-bool FormulaDlg_Impl::CalcStruct( const OUString& rStrExp)
+bool FormulaDlg_Impl::CalcStruct( const OUString& rStrExp, bool bForceRecalcStruct )
 {
     bool bResult = true;
     sal_Int32 nLength = rStrExp.getLength();
 
-    if ( !rStrExp.isEmpty() && aOldFormula!=rStrExp && bStructUpdate)
+    if ( !rStrExp.isEmpty() && (bForceRecalcStruct || aOldFormula != rStrExp) && bStructUpdate)
     {
         // Only calculate the value when there isn't any more keyboard input:
 
@@ -733,10 +733,17 @@ void FormulaDlg_Impl::MakeTree(StructPage* _pTree,SvTreeListEntry* pParent,Formu
                 }
                 else if (eOp==ocPush)
                 {
+                    // Interpret range reference in matrix context to resolve
+                    // as array elements.
+                    /* TODO: this should depend on parameter classification, if
+                     * a scalar value is expected matrix should not be forced.
+                     * */
+                    bool bForceMatrix = (!m_pBtnMatrix->IsChecked() &&
+                            (_pToken->GetType() == svDoubleRef || _pToken->GetType() == svExternalDoubleRef));
                     OUString aCellResult;
-                    OUString aEquals(" = ");
-                    if (CalcValue( "=" + aResult, aCellResult) && aCellResult != aResult) // cell is a formula, print subformula
-                        _pTree->InsertEntry(aResult + aEquals + aCellResult,pParent,STRUCT_END,0,_pToken);
+                    if (CalcValue( "=" + aResult, aCellResult, bForceMatrix) && aCellResult != aResult)
+                        // Cell is a formula, print subformula.
+                        _pTree->InsertEntry(aResult + " = " + aCellResult, pParent,STRUCT_END,0,_pToken);
                     else
                         _pTree->InsertEntry(aResult,pParent,STRUCT_END,0,_pToken);
                 }
@@ -1607,6 +1614,7 @@ IMPL_LINK_NOARG_TYPED(FormulaDlg_Impl, StructSelHdl, StructPage&, void)
 IMPL_LINK_NOARG_TYPED(FormulaDlg_Impl, MatrixHdl, Button*, void)
 {
     bUserMatrixFlag=true;
+    UpdateValues(true);
 }
 
 IMPL_LINK_NOARG_TYPED(FormulaDlg_Impl, FuncSelHdl, FuncPage&, void)
diff --git a/include/formula/IFunctionDescription.hxx b/include/formula/IFunctionDescription.hxx
index 0d93429f..ab24a71 100644
--- a/include/formula/IFunctionDescription.hxx
+++ b/include/formula/IFunctionDescription.hxx
@@ -123,7 +123,7 @@ namespace formula
         virtual void setSelection(sal_Int32 _nStart, sal_Int32 _nEnd) = 0;
 
         virtual FormEditData* getFormEditData() const = 0;
-        virtual bool calculateValue(const OUString& _sExpression, OUString& _rResult) = 0;
+        virtual bool calculateValue(const OUString& _sExpression, OUString& _rResult, bool bMatrixFormula) = 0;
 
         virtual void switchBack() = 0;
 
diff --git a/reportdesign/source/ui/dlg/Formula.cxx b/reportdesign/source/ui/dlg/Formula.cxx
index dd1b33f..03f4a7a 100644
--- a/reportdesign/source/ui/dlg/Formula.cxx
+++ b/reportdesign/source/ui/dlg/Formula.cxx
@@ -107,7 +107,7 @@ void FormulaDialog::dispose()
 
 //                          Funktionen fuer rechte Seite
 
-bool FormulaDialog::calculateValue( const OUString& rStrExp, OUString& rStrResult )
+bool FormulaDialog::calculateValue( const OUString& rStrExp, OUString& rStrResult, bool /*bMatrixFormula*/ )
 {
     rStrResult = rStrExp;
     return false;
diff --git a/reportdesign/source/ui/inc/Formula.hxx b/reportdesign/source/ui/inc/Formula.hxx
index 227df6b..60b1d56 100644
--- a/reportdesign/source/ui/inc/Formula.hxx
+++ b/reportdesign/source/ui/inc/Formula.hxx
@@ -73,7 +73,7 @@ public:
     // IFormulaEditorHelper
     virtual void notifyChange() override;
     virtual void fill() override;
-    virtual bool calculateValue(const OUString& _sExpression, OUString& _rResult) override;
+    virtual bool calculateValue(const OUString& _sExpression, OUString& _rResult, bool bMatrixFormula) override;
     virtual void doClose(bool _bOk) override;
     virtual void insertEntryToLRUList(const formula::IFunctionDescription*  pDesc) override;
     virtual void showReference(const OUString& _sFormula) override;
diff --git a/sc/inc/simpleformulacalc.hxx b/sc/inc/simpleformulacalc.hxx
index 081823d..fef4fe9 100644
--- a/sc/inc/simpleformulacalc.hxx
+++ b/sc/inc/simpleformulacalc.hxx
@@ -31,13 +31,15 @@ private:
     ScDocument* mpDoc;
     ScFormulaResult maResult;
     formula::FormulaGrammar::Grammar maGram;
-    bool bIsMatrix;
+    bool mbMatrixResult;
     OUString maMatrixFormulaResult;
     bool mbLimitString;
+    bool mbMatrixFormula;
 
 public:
     ScSimpleFormulaCalculator(ScDocument* pDoc, const ScAddress& rAddr,
-            const OUString& rFormula, formula::FormulaGrammar::Grammar eGram = formula::FormulaGrammar::GRAM_DEFAULT);
+            const OUString& rFormula, bool bMatrixFormula,
+            formula::FormulaGrammar::Grammar eGram = formula::FormulaGrammar::GRAM_DEFAULT);
     ~ScSimpleFormulaCalculator();
 
     void Calculate();
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index bf22802..337a4ef 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -6584,7 +6584,7 @@ void Test::testFormulaWizardSubformula()
     m_pDoc->SetString(ScAddress(1,1,0), "=1/0");        // B2
     m_pDoc->SetString(ScAddress(1,2,0), "=gibberish");  // B3
 
-    ScSimpleFormulaCalculator pFCell1( m_pDoc, ScAddress(0,0,0), "=B1:B3" );
+    ScSimpleFormulaCalculator pFCell1( m_pDoc, ScAddress(0,0,0), "=B1:B3", true );
     sal_uInt16 nErrCode = pFCell1.GetErrCode();
     CPPUNIT_ASSERT( nErrCode == 0 || pFCell1.IsMatrix() );
     CPPUNIT_ASSERT_EQUAL( OUString("{1;#DIV/0!;#NAME?}"), pFCell1.GetString().getString() );
@@ -6592,7 +6592,7 @@ void Test::testFormulaWizardSubformula()
     m_pDoc->SetString(ScAddress(1,0,0), "=NA()");       // B1
     m_pDoc->SetString(ScAddress(1,1,0), "2");           // B2
     m_pDoc->SetString(ScAddress(1,2,0), "=1+2");        // B3
-    ScSimpleFormulaCalculator pFCell2( m_pDoc, ScAddress(0,0,0), "=B1:B3" );
+    ScSimpleFormulaCalculator pFCell2( m_pDoc, ScAddress(0,0,0), "=B1:B3", true );
     nErrCode = pFCell2.GetErrCode();
     CPPUNIT_ASSERT( nErrCode == 0 || pFCell2.IsMatrix() );
     CPPUNIT_ASSERT_EQUAL( OUString("{#N/A;2;3}"), pFCell2.GetString().getString() );
diff --git a/sc/source/core/data/simpleformulacalc.cxx b/sc/source/core/data/simpleformulacalc.cxx
index 7d2efe2..49b3459 100644
--- a/sc/source/core/data/simpleformulacalc.cxx
+++ b/sc/source/core/data/simpleformulacalc.cxx
@@ -16,15 +16,16 @@
 #define DISPLAY_LEN 15
 
 ScSimpleFormulaCalculator::ScSimpleFormulaCalculator( ScDocument* pDoc, const ScAddress& rAddr,
-        const OUString& rFormula, formula::FormulaGrammar::Grammar eGram )
+        const OUString& rFormula, bool bMatrixFormula, formula::FormulaGrammar::Grammar eGram )
     : mnFormatType(0)
     , mnFormatIndex(0)
     , mbCalculated(false)
     , maAddr(rAddr)
     , mpDoc(pDoc)
     , maGram(eGram)
-    , bIsMatrix(false)
+    , mbMatrixResult(false)
     , mbLimitString(false)
+    , mbMatrixFormula(bMatrixFormula)
 {
     // compile already here
     ScCompiler aComp(mpDoc, maAddr);
@@ -45,7 +46,8 @@ void ScSimpleFormulaCalculator::Calculate()
 
     mbCalculated = true;
     ScInterpreter aInt(nullptr, mpDoc, maAddr, *mpCode.get());
-    aInt.AssertFormulaMatrix();
+    if (mbMatrixFormula)
+        aInt.AssertFormulaMatrix();
 
     formula::StackVar aIntType = aInt.Interpret();
     if ( aIntType == formula::svMatrixCell )
@@ -55,7 +57,7 @@ void ScSimpleFormulaCalculator::Calculate()
         OUStringBuffer aStr;
         aComp.CreateStringFromToken(aStr, aInt.GetResultToken().get());
 
-        bIsMatrix = true;
+        mbMatrixResult = true;
 
         if (mbLimitString)
         {
@@ -82,7 +84,7 @@ bool ScSimpleFormulaCalculator::IsValue()
 {
     Calculate();
 
-    if (bIsMatrix)
+    if (mbMatrixResult)
         return false;
 
     return maResult.IsValue();
@@ -90,7 +92,7 @@ bool ScSimpleFormulaCalculator::IsValue()
 
 bool ScSimpleFormulaCalculator::IsMatrix()
 {
-    return bIsMatrix;
+    return mbMatrixResult;
 }
 
 sal_uInt16 ScSimpleFormulaCalculator::GetErrCode()
@@ -118,7 +120,7 @@ svl::SharedString ScSimpleFormulaCalculator::GetString()
 {
     Calculate();
 
-    if (bIsMatrix)
+    if (mbMatrixResult)
         return maMatrixFormulaResult;
 
     if ((!mpCode->GetCodeError() || mpCode->GetCodeError() == errDoubleRef) &&
diff --git a/sc/source/ui/app/inputhdl.cxx b/sc/source/ui/app/inputhdl.cxx
index 4138bad..a464c34 100644
--- a/sc/source/ui/app/inputhdl.cxx
+++ b/sc/source/ui/app/inputhdl.cxx
@@ -1246,7 +1246,7 @@ static OUString lcl_Calculate( const OUString& rFormula, ScDocument* pDoc, const
     if(rFormula.isEmpty())
         return OUString();
 
-    std::unique_ptr<ScSimpleFormulaCalculator> pCalc( new ScSimpleFormulaCalculator( pDoc, rPos, rFormula ) );
+    std::unique_ptr<ScSimpleFormulaCalculator> pCalc( new ScSimpleFormulaCalculator( pDoc, rPos, rFormula, false ) );
 
     // FIXME: HACK! In order to not get a #REF! for ColRowNames, if a name is actually inserted as a Range
     // into the whole Formula, but is interpreted as a single cell reference when displaying it on its own
@@ -1261,7 +1261,7 @@ static OUString lcl_Calculate( const OUString& rFormula, ScDocument* pDoc, const
             aBraced.append('(');
             aBraced.append(rFormula);
             aBraced.append(')');
-            pCalc.reset( new ScSimpleFormulaCalculator( pDoc, rPos, aBraced.makeStringAndClear() ) );
+            pCalc.reset( new ScSimpleFormulaCalculator( pDoc, rPos, aBraced.makeStringAndClear(), false ) );
         }
         else
             bColRowName = false;
diff --git a/sc/source/ui/formdlg/formula.cxx b/sc/source/ui/formdlg/formula.cxx
index e4d466e..5692bbc 100644
--- a/sc/source/ui/formdlg/formula.cxx
+++ b/sc/source/ui/formdlg/formula.cxx
@@ -301,9 +301,10 @@ bool ScFormulaDlg::Close()
 
 //                          functions for right side
 
-bool ScFormulaDlg::calculateValue( const OUString& rStrExp, OUString& rStrResult )
+bool ScFormulaDlg::calculateValue( const OUString& rStrExp, OUString& rStrResult, bool bMatrixFormula )
 {
-    std::unique_ptr<ScSimpleFormulaCalculator> pFCell(new ScSimpleFormulaCalculator(m_pDoc, m_CursorPos, rStrExp));
+    std::unique_ptr<ScSimpleFormulaCalculator> pFCell( new ScSimpleFormulaCalculator(
+                m_pDoc, m_CursorPos, rStrExp, bMatrixFormula));
     pFCell->SetLimitString(true);
 
     // HACK! to avoid neither #REF! from ColRowNames
@@ -320,7 +321,8 @@ bool ScFormulaDlg::calculateValue( const OUString& rStrExp, OUString& rStrResult
             aBraced.append('(');
             aBraced.append(rStrExp);
             aBraced.append(')');
-            pFCell.reset(new ScSimpleFormulaCalculator(m_pDoc, m_CursorPos, aBraced.makeStringAndClear()));
+            pFCell.reset( new ScSimpleFormulaCalculator(
+                        m_pDoc, m_CursorPos, aBraced.makeStringAndClear(), bMatrixFormula));
             pFCell->SetLimitString(true);
         }
         else
diff --git a/sc/source/ui/inc/formula.hxx b/sc/source/ui/inc/formula.hxx
index 3ebdb61..60613b7 100644
--- a/sc/source/ui/inc/formula.hxx
+++ b/sc/source/ui/inc/formula.hxx
@@ -59,7 +59,7 @@ public:
     // IFormulaEditorHelper
     virtual void notifyChange() override;
     virtual void fill() override;
-    virtual bool calculateValue(const OUString& _sExpression, OUString& _rResult) override;
+    virtual bool calculateValue(const OUString& _sExpression, OUString& _rResult, bool bMatrixFormula) override;
     virtual void doClose(bool _bOk) override;
     virtual void insertEntryToLRUList(const formula::IFunctionDescription*  pDesc) override;
     virtual void showReference(const OUString& _sFormula) override;


More information about the Libreoffice-commits mailing list