formula/source/core/api/token.cxx   |    5 ++++-
 include/formula/tokenarray.hxx      |   11 +++++++++++
 sc/source/core/data/formulacell.cxx |    5 ++++-
 sc/source/core/tool/compiler.cxx    |   26 ++++++++++++++++++++------
 sc/source/core/tool/token.cxx       |    1 +
 5 files changed, 40 insertions(+), 8 deletions(-)

New commits:
commit aed5e42680caf49068a3f463b571621ef0d87f86
Author: Kohei Yoshida <kohei.yosh...@collabora.com>
Date:   Mon Oct 17 23:19:23 2016 -0400

    tdf#93894: Prohibit grouping when certain token types are present.
    
    For instance, column / row label tokens don't work correctly in
    grouped cells with the current implementation.
    
    Change-Id: Idf86312ef15fbfd4382aa90ee6d131c671a80683

diff --git a/formula/source/core/api/token.cxx 
b/formula/source/core/api/token.cxx
index 034b0d6..9808d40 100644
--- a/formula/source/core/api/token.cxx
+++ b/formula/source/core/api/token.cxx
@@ -712,7 +712,8 @@ FormulaTokenArray::FormulaTokenArray() :
     nError(0),
     nMode(ScRecalcMode::NORMAL),
     bHyperLink(false),
-    mbFromRangeName(false)
+    mbFromRangeName(false),
+    mbShareable(true)
 {
 }
 
@@ -735,6 +736,7 @@ void FormulaTokenArray::Assign( const FormulaTokenArray& r )
     nMode  = r.nMode;
     bHyperLink = r.bHyperLink;
     mbFromRangeName = r.mbFromRangeName;
+    mbShareable = r.mbShareable;
     pCode  = nullptr;
     pRPN   = nullptr;
     FormulaToken** pp;
@@ -846,6 +848,7 @@ void FormulaTokenArray::Clear()
     nError = nLen = nIndex = nRPN = 0;
     bHyperLink = false;
     mbFromRangeName = false;
+    mbShareable = true;
     ClearRecalcMode();
 }
 
diff --git a/include/formula/tokenarray.hxx b/include/formula/tokenarray.hxx
index 1735d00..71bacbb 100644
--- a/include/formula/tokenarray.hxx
+++ b/include/formula/tokenarray.hxx
@@ -116,6 +116,7 @@ protected:
     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
+    bool            mbShareable;            // Whether or not it can be shared 
with adjacent cells.
 
 protected:
     void                    Assign( const FormulaTokenArray& );
@@ -180,6 +181,16 @@ public:
     void SetFromRangeName( bool b ) { mbFromRangeName = b; }
     bool IsFromRangeName() const { return mbFromRangeName; }
 
+    void SetShareable( bool b ) { mbShareable = b; }
+
+    /**
+     * Check if this token array is shareable between multiple adjacent
+     * formula cells. Certain tokens may not function correctly when shared.
+     *
+     * @return true if the token array is shareable, false otherwise.
+     */
+    bool IsShareable() const { return mbShareable; }
+
     void Clear();
     void DelRPN();
     FormulaToken* First() { nIndex = 0; return Next(); }
diff --git a/sc/source/core/data/formulacell.cxx 
b/sc/source/core/data/formulacell.cxx
index 2e6f549..e262e8f 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -1342,7 +1342,7 @@ void ScFormulaCell::CompileXML( 
sc::CompileFormulaContext& rCxt, ScProgress& rPr
         ScAddress aPreviousCell( aPos );
         aPreviousCell.IncRow( -1 );
         ScFormulaCell *pPreviousCell = pDocument->GetFormulaCell( 
aPreviousCell );
-        if( pPreviousCell )
+        if (pPreviousCell && pPreviousCell->GetCode()->IsShareable())
         {
             // Now try to convert to a string quickly ...
             ScCompiler aBackComp( rCxt, aPos, *(pPreviousCell->pCode) );
@@ -3804,6 +3804,9 @@ ScFormulaCell::CompareState 
ScFormulaCell::CompareByTokenArray( ScFormulaCell& r
     if ( GetHash() != rOther.GetHash() )
         return NotEqual;
 
+    if (!pCode->IsShareable() || !rOther.pCode->IsShareable())
+        return NotEqual;
+
     FormulaToken **pThis = pCode->GetCode();
     sal_uInt16     nThisLen = pCode->GetCodeLen();
     FormulaToken **pOther = rOther.pCode->GetCode();
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index 595059d..9132bbd 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -4288,6 +4288,12 @@ ScTokenArray* ScCompiler::CompileString( const OUString& 
rFormula )
                     --nFunction;
             }
             break;
+            case ocColRowName:
+            case ocColRowNameAuto:
+                // The current implementation of column / row labels doesn't
+                // function correctly in grouped cells.
+                aArr.SetShareable(false);
+            break;
             default:
             break;
         }
@@ -5137,8 +5143,10 @@ bool ScCompiler::HandleColRowName()
             {
                 ScSingleRefData aRefData;
                 aRefData.InitAddress( aRange.aStart );
-                aRefData.SetColRel( true );
-                aRefData.SetRowRel( true );
+                if ( bColName )
+                    aRefData.SetColRel( true );
+                else
+                    aRefData.SetRowRel( true );
                 aRefData.SetAddress(aRange.aStart, aPos);
                 pNew->AddSingleReference( aRefData );
             }
@@ -5146,10 +5154,16 @@ bool ScCompiler::HandleColRowName()
             {
                 ScComplexRefData aRefData;
                 aRefData.InitRange( aRange );
-                aRefData.Ref1.SetColRel( true );
-                aRefData.Ref2.SetColRel( true );
-                aRefData.Ref1.SetRowRel( true );
-                aRefData.Ref2.SetRowRel( true );
+                if ( bColName )
+                {
+                    aRefData.Ref1.SetColRel( true );
+                    aRefData.Ref2.SetColRel( true );
+                }
+                else
+                {
+                    aRefData.Ref1.SetRowRel( true );
+                    aRefData.Ref2.SetRowRel( true );
+                }
                 aRefData.SetRange(aRange, aPos);
                 if ( bInList )
                     pNew->AddDoubleReference( aRefData );
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 0ba6c52..fef9f48 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -1789,6 +1789,7 @@ ScTokenArray* ScTokenArray::Clone() const
     p->mnHashValue = mnHashValue;
     p->meVectorState = meVectorState;
     p->mbFromRangeName = mbFromRangeName;
+    p->mbShareable = mbShareable;
 
     FormulaToken** pp;
     if( nLen )
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to