[Libreoffice-commits] core.git: formula/source include/formula sc/inc sc/source

Eike Rathke erack at redhat.com
Tue Jun 23 04:20:07 PDT 2015


 formula/source/core/api/token.cxx |    6 +++
 include/formula/tokenarray.hxx    |    4 ++
 sc/inc/compiler.hxx               |    2 -
 sc/inc/tokenarray.hxx             |    4 --
 sc/source/core/tool/compiler.cxx  |   58 +++++++++++++++++++++++++++++---------
 sc/source/core/tool/rangenam.cxx  |    9 +++++
 sc/source/core/tool/token.cxx     |   19 +++++-------
 7 files changed, 72 insertions(+), 30 deletions(-)

New commits:
commit 80aafaf79306ea82cd24f10f200908addccaf34f
Author: Eike Rathke <erack at redhat.com>
Date:   Tue Jun 23 13:02:01 2015 +0200

    in OOXML save references of named expressions with col,row=0,0 base position
    
    Saving relative references of named expressions to OOXML never worked,
    upon reload they pointed to a different position offset by the value of
    the original base position. This at least saves positive relative
    references correctly, while generating #REF! for negative offsets which
    is slightly better than having them point to a wrong location and
    silently calculate different values..
    
    Also, this is a prerequisite for TableRef ThisRow references in named
    expressions to be saved correctly in A1 notation, which results in a
    relative row 0 value.
    
    Change-Id: I3734f910794ceab4b9224b214ad11c64d1d18e67

diff --git a/formula/source/core/api/token.cxx b/formula/source/core/api/token.cxx
index e098a49..ac95b8d 100644
--- a/formula/source/core/api/token.cxx
+++ b/formula/source/core/api/token.cxx
@@ -706,7 +706,8 @@ FormulaTokenArray::FormulaTokenArray() :
     nIndex(0),
     nError(0),
     nMode(ScRecalcMode::NORMAL),
-    bHyperLink(false)
+    bHyperLink(false),
+    mbFromRangeName(false)
 {
 }
 
@@ -728,6 +729,7 @@ void FormulaTokenArray::Assign( const FormulaTokenArray& r )
     nError = r.nError;
     nMode  = r.nMode;
     bHyperLink = r.bHyperLink;
+    mbFromRangeName = r.mbFromRangeName;
     pCode  = NULL;
     pRPN   = NULL;
     FormulaToken** pp;
@@ -780,6 +782,7 @@ FormulaTokenArray* FormulaTokenArray::Clone() const
     p->nMode = nMode;
     p->nError = nError;
     p->bHyperLink = bHyperLink;
+    p->mbFromRangeName = mbFromRangeName;
     FormulaToken** pp;
     if( nLen )
     {
@@ -837,6 +840,7 @@ void FormulaTokenArray::Clear()
     pCode = NULL; pRPN = NULL;
     nError = nLen = nIndex = nRPN = 0;
     bHyperLink = false;
+    mbFromRangeName = false;
     ClearRecalcMode();
 }
 
diff --git a/include/formula/tokenarray.hxx b/include/formula/tokenarray.hxx
index 1050047..58bb092 100644
--- a/include/formula/tokenarray.hxx
+++ b/include/formula/tokenarray.hxx
@@ -115,6 +115,7 @@ protected:
     sal_uInt16          nError;                 // Error code
     ScRecalcMode    nMode;                  // Flags to indicate when to recalc this code
     bool            bHyperLink;             // If HYPERLINK() occurs in the formula.
+    bool            mbFromRangeName;        // If this array originates from a named expression
 
 protected:
     void                    Assign( const FormulaTokenArray& );
@@ -164,6 +165,9 @@ public:
     virtual ~FormulaTokenArray();
     FormulaTokenArray* Clone() const;    /// True copy!
 
+    void SetFromRangeName( bool b ) { mbFromRangeName = b; }
+    bool IsFromRangeName() const { return mbFromRangeName; }
+
     void Clear();
     void DelRPN();
     FormulaToken* First() { nIndex = 0; return Next(); }
diff --git a/sc/inc/compiler.hxx b/sc/inc/compiler.hxx
index 8c6b373..2dfa2f7 100644
--- a/sc/inc/compiler.hxx
+++ b/sc/inc/compiler.hxx
@@ -218,7 +218,7 @@ public:
             formula::FormulaGrammar::Grammar eGram,
             const ScAddress& rPos,
             const OUString& rErrRef, const std::vector<OUString>& rTabNames,
-            const ScComplexRefData& rRef, bool bSingleRef ) const = 0;
+            const ScComplexRefData& rRef, bool bSingleRef, bool bFromRangeName ) const = 0;
 
         virtual ::com::sun::star::i18n::ParseResult
                     parseAnyToken( const OUString& rFormula,
diff --git a/sc/inc/tokenarray.hxx b/sc/inc/tokenarray.hxx
index b36936a..0d3fa02 100644
--- a/sc/inc/tokenarray.hxx
+++ b/sc/inc/tokenarray.hxx
@@ -52,7 +52,6 @@ class SC_DLLPUBLIC ScTokenArray : public formula::FormulaTokenArray
 
     size_t mnHashValue;
     ScFormulaVectorState meVectorState;
-    bool mbFromRangeName;
 
 public:
     ScTokenArray();
@@ -70,9 +69,6 @@ public:
 
     ScFormulaVectorState GetVectorState() const { return meVectorState;}
 
-    void SetFromRangeName( bool b ) { mbFromRangeName = b; }
-    bool IsFromRangeName() const { return mbFromRangeName; }
-
     /**
      * If the array contains at least one relative row reference or named
      * expression, it's variant. Otherwise invariant.
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index 30bd1e2..125abb4 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -800,12 +800,13 @@ struct ConventionOOO_A1 : public Convention_A1
             MakeRowStr(rBuffer, rAbsRef.Row());
     }
 
-    void makeRefStr( OUStringBuffer&   rBuffer,
+    virtual void makeRefStr( OUStringBuffer&   rBuffer,
                      formula::FormulaGrammar::Grammar /*eGram*/,
                      const ScAddress& rPos,
                      const OUString& rErrRef, const std::vector<OUString>& rTabNames,
                      const ScComplexRefData& rRef,
-                     bool bSingleRef ) const SAL_OVERRIDE
+                     bool bSingleRef,
+                     bool /*bFromRangeName*/ ) const SAL_OVERRIDE
     {
         ScComplexRefData aRef( rRef );
         // In case absolute/relative positions weren't separately available:
@@ -952,12 +953,14 @@ struct ConventionOOO_A1 : public Convention_A1
 struct ConventionOOO_A1_ODF : public ConventionOOO_A1
 {
     ConventionOOO_A1_ODF() : ConventionOOO_A1 (FormulaGrammar::CONV_ODF) { }
-    void makeRefStr( OUStringBuffer&   rBuffer,
+
+    virtual void makeRefStr( OUStringBuffer&   rBuffer,
                      formula::FormulaGrammar::Grammar eGram,
                      const ScAddress& rPos,
                      const OUString& rErrRef, const std::vector<OUString>& rTabNames,
                      const ScComplexRefData& rRef,
-                     bool bSingleRef ) const SAL_OVERRIDE
+                     bool bSingleRef,
+                     bool /*bFromRangeName*/ ) const SAL_OVERRIDE
     {
         rBuffer.append('[');
         ScComplexRefData aRef( rRef );
@@ -1197,12 +1200,13 @@ struct ConventionXL_A1 : public Convention_A1, public ConventionXL
         MakeRowStr(rBuf, rAbs.Row());
     }
 
-    void makeRefStr( OUStringBuffer&   rBuf,
+    virtual void makeRefStr( OUStringBuffer&   rBuf,
                      formula::FormulaGrammar::Grammar /*eGram*/,
                      const ScAddress& rPos,
                      const OUString& /*rErrRef*/, const std::vector<OUString>& rTabNames,
                      const ScComplexRefData& rRef,
-                     bool bSingleRef ) const SAL_OVERRIDE
+                     bool bSingleRef,
+                     bool /*bFromRangeName*/ ) const SAL_OVERRIDE
     {
         ScComplexRefData aRef( rRef );
 
@@ -1338,6 +1342,32 @@ struct ConventionXL_OOX : public ConventionXL_A1
 {
     ConventionXL_OOX() : ConventionXL_A1( FormulaGrammar::CONV_XL_OOX ) { }
 
+    virtual void makeRefStr( OUStringBuffer&   rBuf,
+                     formula::FormulaGrammar::Grammar eGram,
+                     const ScAddress& rPos,
+                     const OUString& rErrRef, const std::vector<OUString>& rTabNames,
+                     const ScComplexRefData& rRef,
+                     bool bSingleRef,
+                     bool bFromRangeName ) const SAL_OVERRIDE
+    {
+        // In OOXML relative references in named expressions are relative to
+        // column 0 and row 0. Relative sheet references don't exist.
+        ScAddress aPos( rPos );
+        if (bFromRangeName)
+        {
+            // XXX NOTE: by decrementing the reference position we may end up
+            // with resolved references with negative values. There's no proper
+            // way to solve that or wrap them around without sheet dimensions
+            // that are stored along. That, or blindly assume fixed dimensions
+            // here and in import.
+            /* TODO: maybe do that blind fixed dimensions wrap? */
+            aPos.SetCol(0);
+            aPos.SetRow(0);
+        }
+
+        ConventionXL_A1::makeRefStr( rBuf, eGram, aPos, rErrRef, rTabNames, rRef, bSingleRef, bFromRangeName);
+    }
+
     virtual OUString makeExternalNameStr( sal_uInt16 nFileId, const OUString& /*rFile*/,
             const OUString& rName ) const SAL_OVERRIDE
     {
@@ -1442,12 +1472,14 @@ r1c1_add_row( OUStringBuffer &rBuf, const ScSingleRefData& rRef, const ScAddress
 struct ConventionXL_R1C1 : public ScCompiler::Convention, public ConventionXL
 {
     ConventionXL_R1C1() : ScCompiler::Convention( FormulaGrammar::CONV_XL_R1C1 ) { }
-    void makeRefStr( OUStringBuffer&   rBuf,
+
+    virtual void makeRefStr( OUStringBuffer&   rBuf,
                      formula::FormulaGrammar::Grammar /*eGram*/,
                      const ScAddress& rPos,
                      const OUString& /*rErrRef*/, const std::vector<OUString>& rTabNames,
                      const ScComplexRefData& rRef,
-                     bool bSingleRef ) const SAL_OVERRIDE
+                     bool bSingleRef,
+                     bool /*bFromRangeName*/ ) const SAL_OVERRIDE
     {
         ScRange aAbsRef = rRef.toAbs(rPos);
         ScComplexRefData aRef( rRef );
@@ -4575,7 +4607,7 @@ void ScCompiler::CreateStringFromSingleRef( OUStringBuffer& rBuffer, const Formu
         {
             rBuffer.append(ScGlobal::GetRscString(STR_NO_NAME_REF));
             pConv->makeRefStr(rBuffer, meGrammar, aPos, aErrRef,
-                              GetSetupTabNames(), aRef, true);
+                              GetSetupTabNames(), aRef, true, (pArr && pArr->IsFromRangeName()));
         }
     }
     else if (pArr && (p = pArr->PeekPrevNoSpaces()) && p->GetOpCode() == ocTableRefOpen)
@@ -4587,14 +4619,14 @@ void ScCompiler::CreateStringFromSingleRef( OUStringBuffer& rBuffer, const Formu
     }
     else
         pConv->makeRefStr(rBuffer, meGrammar, aPos, aErrRef,
-                          GetSetupTabNames(), aRef, true);
+                          GetSetupTabNames(), aRef, true, (pArr && pArr->IsFromRangeName()));
 }
 
 void ScCompiler::CreateStringFromDoubleRef( OUStringBuffer& rBuffer, const FormulaToken* _pTokenP ) const
 {
     OUString aErrRef = GetCurrentOpCodeMap()->getSymbol(ocErrRef);
     pConv->makeRefStr(rBuffer, meGrammar, aPos, aErrRef, GetSetupTabNames(),
-                      *_pTokenP->GetDoubleRef(), false);
+                      *_pTokenP->GetDoubleRef(), false, (pArr && pArr->IsFromRangeName()));
 }
 
 void ScCompiler::CreateStringFromIndex( OUStringBuffer& rBuffer, const FormulaToken* _pTokenP ) const
@@ -5214,7 +5246,7 @@ bool ScCompiler::HandleTableRef()
                     {
                         aRefData.SetRowRel( true);
                         if (!bCol1RelName)
-                            bCol1RelName = static_cast<ScTokenArray*>(pArr)->IsFromRangeName();
+                            bCol1RelName = pArr->IsFromRangeName();
                     }
                     aRefData.SetRelName( bCol1RelName);
                     aRefData.SetFlag3D( true);
@@ -5242,7 +5274,7 @@ bool ScCompiler::HandleTableRef()
                         aRefData.Ref1.SetRowRel( true);
                         aRefData.Ref2.SetRowRel( true);
                         if (!bRelName)
-                            bRelName = static_cast<ScTokenArray*>(pArr)->IsFromRangeName();
+                            bRelName = pArr->IsFromRangeName();
                     }
                     aRefData.Ref1.SetRelName( bRelName);
                     aRefData.Ref2.SetRelName( bRelName);
diff --git a/sc/source/core/tool/rangenam.cxx b/sc/source/core/tool/rangenam.cxx
index 616ec8f..4235ef7 100644
--- a/sc/source/core/tool/rangenam.cxx
+++ b/sc/source/core/tool/rangenam.cxx
@@ -73,6 +73,7 @@ ScRangeData::ScRangeData( ScDocument* pDok,
         // to ensure same behavior if unnecessary copying is left out.
 
         pCode = new ScTokenArray();
+        pCode->SetFromRangeName(true);
     }
 }
 
@@ -93,6 +94,7 @@ ScRangeData::ScRangeData( ScDocument* pDok,
                 mnMaxRow    (-1),
                 mnMaxCol    (-1)
 {
+    pCode->SetFromRangeName(true);
     InitCode();
 }
 
@@ -115,6 +117,7 @@ ScRangeData::ScRangeData( ScDocument* pDok,
     aRefData.InitAddress( rTarget );
     aRefData.SetFlag3D( true );
     pCode->AddSingleReference( aRefData );
+    pCode->SetFromRangeName(true);
     ScCompiler aComp( pDoc, aPos, *pCode );
     aComp.SetGrammar(pDoc->GetGrammar());
     aComp.CompileTokenArray();
@@ -134,7 +137,9 @@ ScRangeData::ScRangeData(const ScRangeData& rScRangeData, ScDocument* pDocument)
     bModified   (rScRangeData.bModified),
     mnMaxRow    (rScRangeData.mnMaxRow),
     mnMaxCol    (rScRangeData.mnMaxCol)
-{}
+{
+    pCode->SetFromRangeName(true);
+}
 
 ScRangeData::~ScRangeData()
 {
@@ -158,6 +163,7 @@ void ScRangeData::CompileRangeData( const OUString& rSymbol, bool bSetError )
     ScTokenArray* pNewCode = aComp.CompileString( rSymbol );
     boost::scoped_ptr<ScTokenArray> pOldCode( pCode);     // old pCode will be deleted
     pCode = pNewCode;
+    pCode->SetFromRangeName(true);
     if( !pCode->GetCodeError() )
     {
         pCode->Reset();
@@ -618,6 +624,7 @@ void ScRangeData::SetCode( ScTokenArray& rArr )
 {
     boost::scoped_ptr<ScTokenArray> pOldCode( pCode); // old pCode will be deleted
     pCode = new ScTokenArray( rArr );
+    pCode->SetFromRangeName(true);
     InitCode();
 }
 
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 914787d..c2a9f5b 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -1743,16 +1743,14 @@ bool ScTokenArray::IsValidReference( ScRange& rRange, const ScAddress& rPos ) co
 ScTokenArray::ScTokenArray() :
     FormulaTokenArray(),
     mnHashValue(0),
-    meVectorState(FormulaVectorEnabled),
-    mbFromRangeName(false)
+    meVectorState(FormulaVectorEnabled)
 {
 }
 
 ScTokenArray::ScTokenArray( const ScTokenArray& rArr ) :
     FormulaTokenArray(rArr),
     mnHashValue(rArr.mnHashValue),
-    meVectorState(rArr.meVectorState),
-    mbFromRangeName(rArr.mbFromRangeName)
+    meVectorState(rArr.meVectorState)
 {
 }
 
@@ -1764,7 +1762,6 @@ ScTokenArray& ScTokenArray::operator=( const ScTokenArray& rArr )
 {
     Clear();
     Assign( rArr );
-    mbFromRangeName = rArr.mbFromRangeName;
     return *this;
 }
 
@@ -1772,7 +1769,6 @@ void ScTokenArray::ClearScTokenArray()
 {
     Clear();
     meVectorState = FormulaVectorEnabled;
-    mbFromRangeName = false;
 }
 
 ScTokenArray* ScTokenArray::Clone() const
@@ -4207,7 +4203,8 @@ void appendString( OUStringBuffer& rBuf, const OUString& rStr )
     rBuf.append('"');
 }
 
-void appendTokenByType( sc::TokenStringContext& rCxt, OUStringBuffer& rBuf, const FormulaToken& rToken, const ScAddress& rPos )
+void appendTokenByType( sc::TokenStringContext& rCxt, OUStringBuffer& rBuf, const FormulaToken& rToken,\
+        const ScAddress& rPos, bool bFromRangeName )
 {
     if (rToken.IsExternalRef())
     {
@@ -4275,7 +4272,8 @@ void appendTokenByType( sc::TokenStringContext& rCxt, OUStringBuffer& rBuf, cons
                 ScComplexRefData aRef;
                 aRef.Ref1 = rRef;
                 aRef.Ref2 = rRef;
-                rCxt.mpRefConv->makeRefStr(rBuf, rCxt.meGram, rPos, rCxt.maErrRef, rCxt.maTabNames, aRef, true);
+                rCxt.mpRefConv->makeRefStr(rBuf, rCxt.meGram, rPos, rCxt.maErrRef, rCxt.maTabNames, aRef, true,
+                        bFromRangeName);
             }
             else
                 rBuf.append(rCxt.maErrRef);
@@ -4286,7 +4284,8 @@ void appendTokenByType( sc::TokenStringContext& rCxt, OUStringBuffer& rBuf, cons
             if (rCxt.mpRefConv)
             {
                 const ScComplexRefData& rRef = *rToken.GetDoubleRef();
-                rCxt.mpRefConv->makeRefStr(rBuf, rCxt.meGram, rPos, rCxt.maErrRef, rCxt.maTabNames, rRef, false);
+                rCxt.mpRefConv->makeRefStr(rBuf, rCxt.meGram, rPos, rCxt.maErrRef, rCxt.maTabNames, rRef, false,
+                        bFromRangeName);
             }
             else
                 rBuf.append(rCxt.maErrRef);
@@ -4490,7 +4489,7 @@ OUString ScTokenArray::CreateString( sc::TokenStringContext& rCxt, const ScAddre
             aBuf.append(rCxt.mxOpCodeMap->getSymbol(eOp));
 
         if (bCheckType)
-            appendTokenByType(rCxt, aBuf, *pToken, rPos);
+            appendTokenByType(rCxt, aBuf, *pToken, rPos, IsFromRangeName());
     }
 
     return aBuf.makeStringAndClear();


More information about the Libreoffice-commits mailing list