[Libreoffice-commits] core.git: Branch 'feature/formula-core-rework' - 232 commits - accessibility/bridge accessibility/source android/Bootstrap android/experimental basctl/source bin/distro-install-sdk bin/lo-commit-stat bin/lo-xlate-lang boost/boost_1_44_0-gcc4.8.patch cairo/cairo cairo/UnpackedTarball_cairo.mk chart2/source config_host/config_features.h.in config_host.mk.in configure.ac connectivity/Library_postgresql-sdbc-impl.mk connectivity/source cui/source dbaccess/source dictionaries download.lst editeng/source external/Package_msvc_dlls.mk filter/source filter/uiconfig forms/source framework/source helpcontent2 i18npool/source icon-themes/galaxy include/connectivity include/editeng include/filter include/oox include/sfx2 include/svl include/svx include/unotools include/vcl instsetoo_native/util libmwaw/libmwaw-0.1.9.patch.1 libmwaw/libmwaw-infinite-loop.patch.1 libmwaw/UnpackedTarball_libmwaw.mk librelogo/source lpsolve/lp_solve_5.5.patch mdds/0001-Avoid-crash-when-_GLIBCXX_DEBU G-is-defined.patch mdds/0001-Combine-these-two-calls.-There-is-no-reason-why-they.patch mdds/0001-Fix-it-here-too.patch mdds/0001-Workaround-for-an-old-gcc-bug.patch mdds/0001-Workaround-for-gcc-bug.patch mdds/mdds_0.7.0_unreachable_warning.patch.1 mdds/UnpackedTarball_mdds.mk nss/ExternalProject_nss.mk nss/nss.patch odk/config odk/docs odk/settings offapi/com offapi/UnoApi_offapi.mk officecfg/registry oox/source package/inc reportdesign/source RepositoryExternal.mk rsc/source sal/osl sal/qa sal/rtl sal/workben sc/AllLangResTarget_sc.mk sc/CppunitTest_sc_ucalc.mk sc/inc sc/Library_sc.mk sc/Module_sc.mk sc/qa sc/source sc/uiconfig sc/UIConfig_scalc.mk sdext/source sd/source sfx2/source slideshow/source solenv/bin solenv/gbuild starmath/inc starmath/source svgio/inc svgio/source svl/source svtools/source svx/source sw/inc sw/qa sw/source toolkit/source translations ucb/source udkapi/com unotools/source unoxml/source vcl/aqua vcl/generic vcl/ios vcl/source vcl/unx vcl/workben w izards/com writerfilter/CppunitTest_writerfilter_rtftok.mk writerfilter/source xmloff/source

Kohei Yoshida kohei.yoshida at gmail.com
Thu Jun 27 12:50:33 PDT 2013


Rebased ref, commits from common ancestor:
commit 7ae43cdd7f3e21656541db63d3b657160f1a4fac
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Thu Jun 27 15:38:34 2013 -0400

    Turn off column debug and remove warnings.
    
    Change-Id: Ic7dd79c1e420e87dcaff4126d60763ff8cbe9344

diff --git a/sc/inc/mtvelements.hxx b/sc/inc/mtvelements.hxx
index 2c58997..0ebf8be 100644
--- a/sc/inc/mtvelements.hxx
+++ b/sc/inc/mtvelements.hxx
@@ -15,7 +15,7 @@
 #include "svl/broadcast.hxx"
 #include "editeng/editobj.hxx"
 
-#define DEBUG_COLUMN_STORAGE 1
+#define DEBUG_COLUMN_STORAGE 0
 
 #if DEBUG_COLUMN_STORAGE
 #ifdef NDEBUG
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 7205672..3704c6d 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -1532,15 +1532,15 @@ void ScColumn::RegroupFormulaCells()
 {
 }
 
-void ScColumn::RegroupFormulaCells( SCROW nRow )
+void ScColumn::RegroupFormulaCells( SCROW /*nRow*/ )
 {
 }
 
-void ScColumn::RegroupFormulaCells( SCROW nRow1, SCROW nRow2 )
+void ScColumn::RegroupFormulaCells( SCROW /*nRow1*/, SCROW /*nRow2*/ )
 {
 }
 
-void ScColumn::FormulaCellsUndecided( SCROW nRow1, SCROW nRow2 )
+void ScColumn::FormulaCellsUndecided( SCROW /*nRow1*/, SCROW /*nRow2*/ )
 {
 }
 
commit d6824709d29505e79a86c85c2b127c5e3f6ff416
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Thu Jun 27 15:12:10 2013 -0400

    Rename a variable to something more meaningful.
    
    Change-Id: I860e5301e3fec3f06f318b28787f71b63dbaf0ab

diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 5d471c4..2ade13b 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -2100,7 +2100,7 @@ bool ScFormulaCell::UpdateReference(
     if (pUndoDoc)
         pOldCode.reset(pCode->Clone());
 
-    ScRangeData* pRangeData = NULL;
+    ScRangeData* pSharedCode = NULL;
     bool bValChanged = false;
     bool bRangeModified = false;    // any range, not only shared formula
     bool bRefSizeChanged = false;
@@ -2110,7 +2110,7 @@ bool ScFormulaCell::UpdateReference(
         // Update cell or range references.
         ScCompiler aComp(pDocument, aPos, *pCode);
         aComp.SetGrammar(pDocument->GetGrammar());
-        pRangeData = aComp.UpdateReference(eUpdateRefMode, aOldPos, rRange,
+        pSharedCode = aComp.UpdateReference(eUpdateRefMode, aOldPos, rRange,
                                          nDx, nDy, nDz,
                                          bValChanged, bRefSizeChanged);
         bRangeModified = aComp.HasModifiedRange();
@@ -2215,7 +2215,7 @@ bool ScFormulaCell::UpdateReference(
         bHasRelName = HasRelNameReference();
         // Reference changed and new listening needed?
         // Except in Insert/Delete without specialties.
-        bNewListening = (bRangeModified || pRangeData || bColRowNameCompile
+        bNewListening = (bRangeModified || pSharedCode || bColRowNameCompile
                 || (bValChanged && (eUpdateRefMode != URM_INSDEL ||
                         bInDeleteUndo || bRefSizeChanged)) ||
                 (bHasRelName && eUpdateRefMode != URM_COPY))
@@ -2231,14 +2231,14 @@ bool ScFormulaCell::UpdateReference(
 
     bool bNeedDirty = false;
     // NeedDirty for changes except for Copy and Move/Insert without RelNames
-    if ( bRangeModified || pRangeData || bColRowNameCompile ||
+    if ( bRangeModified || pSharedCode || bColRowNameCompile ||
             (bValChanged && eUpdateRefMode != URM_COPY &&
              (eUpdateRefMode != URM_MOVE || bHasRelName) &&
              (!bIsInsert || bHasRelName || bInDeleteUndo ||
               bRefSizeChanged)) || bOnRefMove)
         bNeedDirty = true;
 
-    if (pUndoDoc && (bValChanged || pRangeData || bOnRefMove))
+    if (pUndoDoc && (bValChanged || pSharedCode || bOnRefMove))
     {
         // Copy the cell to aUndoPos, which is its current position in the document,
         // so this works when UpdateReference is called before moving the cells
@@ -2258,13 +2258,13 @@ bool ScFormulaCell::UpdateReference(
 
     bValChanged = false;
 
-    if ( pRangeData )
+    if ( pSharedCode )
     {   // Replace shared formula with own formula
         pDocument->RemoveFromFormulaTree( this );   // update formula count
         delete pCode;
-        pCode = pRangeData->GetCode()->Clone();
+        pCode = pSharedCode->GetCode()->Clone();
         // #i18937# #i110008# call MoveRelWrap, but with the old position
-        ScCompiler::MoveRelWrap(*pCode, pDocument, aOldPos, pRangeData->GetMaxCol(), pRangeData->GetMaxRow());
+        ScCompiler::MoveRelWrap(*pCode, pDocument, aOldPos, pSharedCode->GetMaxCol(), pSharedCode->GetMaxRow());
         ScCompiler aComp2(pDocument, aPos, *pCode);
         aComp2.SetGrammar(pDocument->GetGrammar());
         aComp2.UpdateSharedFormulaReference( eUpdateRefMode, aOldPos, rRange,
@@ -2297,7 +2297,7 @@ bool ScFormulaCell::UpdateReference(
         }
     }
 
-    if ( bNeedDirty && (!(eUpdateRefMode == URM_INSDEL && bHasRelName) || pRangeData) )
+    if ( bNeedDirty && (!(eUpdateRefMode == URM_INSDEL && bHasRelName) || pSharedCode) )
     {   // Cut off references, invalid or similar?
         sc::AutoCalcSwitch(*pDocument, false);
         SetDirty();
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index db84612..bdce061 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -4222,25 +4222,25 @@ ScRangeData* ScCompiler::UpdateReference(UpdateRefMode eUpdateRefMode,
             }
         }
         // Check for SharedFormulas.
-        ScRangeData* pRangeData = NULL;
+        ScRangeData* pSharedCode = NULL;
         pArr->Reset();
-        for( FormulaToken* j = pArr->GetNextName(); j && !pRangeData;
+        for( FormulaToken* j = pArr->GetNextName(); j && !pSharedCode;
              j = pArr->GetNextName() )
         {
             if( j->GetOpCode() == ocName )
             {
                 ScRangeData* pName = GetRangeData( *j);
                 if (pName && pName->HasType(RT_SHARED))
-                    pRangeData = pName;
+                    pSharedCode = pName;
             }
         }
         // Check SharedFormulas for wraps.
-        if (pRangeData)
+        if (pSharedCode)
         {
-            ScRangeData* pName = pRangeData;
-            pRangeData = NULL;
+            ScRangeData* pName = pSharedCode;
+            pSharedCode = NULL;
             pArr->Reset();
-            for( t = static_cast<ScToken*>(pArr->GetNextReferenceRPN()); t && !pRangeData;
+            for( t = static_cast<ScToken*>(pArr->GetNextReferenceRPN()); t && !pSharedCode;
                  t = static_cast<ScToken*>(pArr->GetNextReferenceRPN()) )
             {
                 bool bRelName = (t->GetType() == svSingleRef ?
@@ -4257,16 +4257,16 @@ ScRangeData* ScCompiler::UpdateReference(UpdateRefMode eUpdateRefMode,
                     // wrapped it. Replace SharedFormula.
                     if (!bValid)
                     {
-                        pRangeData = pName;
+                        pSharedCode = pName;
                         rChanged = true;
                     }
                 }
             }
         }
-        return pRangeData;
+        return pSharedCode;
     }
 
-    ScRangeData* pRangeData = NULL;
+    ScRangeData* pSharedCode = NULL;
     ScToken* t;
     pArr->Reset();
     while( (t = static_cast<ScToken*>(pArr->GetNextReferenceOrName())) != NULL )
@@ -4276,7 +4276,7 @@ ScRangeData* ScCompiler::UpdateReference(UpdateRefMode eUpdateRefMode,
             ScRangeData* pName = GetRangeData( *t);
             if (pName && pName->HasType(RT_SHAREDMOD))
             {
-                pRangeData = pName;     // maybe need a replacement of shared with own code
+                pSharedCode = pName;     // maybe need a replacement of shared with own code
                 rChanged = true;
             }
         }
@@ -4373,7 +4373,7 @@ ScRangeData* ScCompiler::UpdateReference(UpdateRefMode eUpdateRefMode,
         }
     }
 
-    return pRangeData;
+    return pSharedCode;
 }
 
 bool ScCompiler::UpdateNameReference(UpdateRefMode eUpdateRefMode,
commit ff5d891b480a0bb3b6cee950d9ea41387fd16392
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Thu Jun 27 14:57:32 2013 -0400

    Some attempt to clean ScFormulaCell::UpdateReference() a bit.
    
    This method is still a monster, however...
    
    Change-Id: I4aaa2d20c8ae6132a75c7c92c0a1b58882d8a261

diff --git a/sc/inc/formulacell.hxx b/sc/inc/formulacell.hxx
index b724d02..1f9b960 100644
--- a/sc/inc/formulacell.hxx
+++ b/sc/inc/formulacell.hxx
@@ -176,11 +176,10 @@ public:
     bool            HasRelNameReference() const;
     bool            HasColRowName() const;
 
-    bool            UpdateReference(UpdateRefMode eUpdateRefMode,
-                                    const ScRange& r,
-                                    SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
-                                    ScDocument* pUndoDoc = NULL,
-                                    const ScAddress* pUndoCellPos = NULL );
+    bool UpdateReference(
+        UpdateRefMode eUpdateRefMode, const ScRange& rRange,
+        SCsCOL nDx, SCsROW nDy, SCsTAB nDz, ScDocument* pUndoDoc = NULL,
+        const ScAddress* pUndoCellPos = NULL );
 
     void            TransposeReference();
     void            UpdateTranspose( const ScRange& rSource, const ScAddress& rDest,
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index a3ab73d..5d471c4 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -46,8 +46,10 @@
 #include "formulagroup.hxx"
 #include "listenercontext.hxx"
 #include "types.hxx"
+#include "scopetools.hxx"
 
 #include <boost/bind.hpp>
+#include <boost/scoped_ptr.hpp>
 
 using namespace formula;
 
@@ -2039,15 +2041,14 @@ bool ScFormulaCell::HasColRowName() const
     return (pCode->GetNextColRowName() != NULL);
 }
 
-bool ScFormulaCell::UpdateReference(UpdateRefMode eUpdateRefMode,
-                                    const ScRange& r,
-                                    SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
-                                    ScDocument* pUndoDoc, const ScAddress* pUndoCellPos )
+bool ScFormulaCell::UpdateReference(
+    UpdateRefMode eUpdateRefMode, const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
+    ScDocument* pUndoDoc, const ScAddress* pUndoCellPos )
 {
     bool bCellStateChanged = false;
 
-    SCCOL nCol1 = r.aStart.Col();
-    SCROW nRow1 = r.aStart.Row();
+    SCCOL nCol1 = rRange.aStart.Col();
+    SCROW nRow1 = rRange.aStart.Row();
     SCCOL nCol = aPos.Col();
     SCROW nRow = aPos.Row();
     SCTAB nTab = aPos.Tab();
@@ -2055,15 +2056,21 @@ bool ScFormulaCell::UpdateReference(UpdateRefMode eUpdateRefMode,
     if ( pUndoCellPos )
         aUndoPos = *pUndoCellPos;
     ScAddress aOldPos( aPos );
-    bool bIsInsert = (eUpdateRefMode == URM_INSDEL &&
-                nDx >= 0 && nDy >= 0 && nDz >= 0);
-    if (eUpdateRefMode == URM_INSDEL && r.In( aPos ))
+    bool bIsInsert = (eUpdateRefMode == URM_INSDEL && nDx >= 0 && nDy >= 0 && nDz >= 0);
+
+    if (eUpdateRefMode == URM_INSDEL && rRange.In(aPos))
     {
+        // This formula cell itself is being shifted during cell range
+        // insertion or deletion. Update its position.
         aPos.Move(nDx, nDy, nDz);
         bCellStateChanged = aPos != aOldPos;
     }
-    else if ( r.In( aPos ) )
+    else if (rRange.In(aPos))
     {
+        // The cell is being moved or copied to a new position. I guess the
+        // position has been updated prior to this call?  Determine
+        // its original position before the move which will be used to adjust
+        // relative references later.
         aOldPos.Set( nCol - nDx, nRow - nDy, nTab - nDz );
     }
 
@@ -2072,6 +2079,7 @@ bool ScFormulaCell::UpdateReference(UpdateRefMode eUpdateRefMode,
     bool bOnRefMove = false;
     if ( !pDocument->IsClipOrUndo() )
     {
+        // Check presence of any references or column row names.
         pCode->Reset();
         bHasRefs = (pCode->GetNextReferenceRPN() != NULL);
         if ( !bHasRefs || eUpdateRefMode == URM_COPY )
@@ -2082,218 +2090,219 @@ bool ScFormulaCell::UpdateReference(UpdateRefMode eUpdateRefMode,
         }
         bOnRefMove = pCode->IsRecalcModeOnRefMove();
     }
-    if( bHasRefs || bOnRefMove )
+
+    if (!bHasRefs && !bOnRefMove)
+        // This formula cell contains no references, nor needs recalculating
+        // on reference update. Bail out.
+        return bCellStateChanged;
+
+    boost::scoped_ptr<ScTokenArray> pOldCode;
+    if (pUndoDoc)
+        pOldCode.reset(pCode->Clone());
+
+    ScRangeData* pRangeData = NULL;
+    bool bValChanged = false;
+    bool bRangeModified = false;    // any range, not only shared formula
+    bool bRefSizeChanged = false;
+
+    if (bHasRefs)
     {
-        ScTokenArray* pOld = pUndoDoc ? pCode->Clone() : NULL;
-        ScRangeData* pRangeData;
-        bool bValChanged = false;
-        bool bRangeModified = false;    // any range, not only shared formula
-        bool bRefSizeChanged = false;
-        if ( bHasRefs )
-        {
-            ScCompiler aComp(pDocument, aPos, *pCode);
-            aComp.SetGrammar(pDocument->GetGrammar());
-            pRangeData = aComp.UpdateReference(eUpdateRefMode, aOldPos, r,
-                                             nDx, nDy, nDz,
-                                             bValChanged, bRefSizeChanged);
-            bRangeModified = aComp.HasModifiedRange();
-        }
-        else
-        {
-            bValChanged = false;
-            pRangeData = NULL;
-            bRangeModified = false;
-            bRefSizeChanged = false;
-        }
+        // Update cell or range references.
+        ScCompiler aComp(pDocument, aPos, *pCode);
+        aComp.SetGrammar(pDocument->GetGrammar());
+        pRangeData = aComp.UpdateReference(eUpdateRefMode, aOldPos, rRange,
+                                         nDx, nDy, nDz,
+                                         bValChanged, bRefSizeChanged);
+        bRangeModified = aComp.HasModifiedRange();
+    }
+
+    bCellStateChanged |= bValChanged;
 
-        bCellStateChanged |= bValChanged;
+    if (bOnRefMove)
+        // Cell may reference itself, e.g. ocColumn, ocRow without parameter
+        bOnRefMove = (bValChanged || (aPos != aOldPos));
 
-        if ( bOnRefMove )
-            bOnRefMove = (bValChanged || (aPos != aOldPos));
-            // Cell may reference itself, e.g. ocColumn, ocRow without parameter
+    bool bColRowNameCompile = false;
+    bool bHasRelName = false;
+    bool bNewListening = false;
+    bool bInDeleteUndo = false;
 
-        bool bColRowNameCompile, bHasRelName, bNewListening, bInDeleteUndo;
-        if ( bHasRefs )
+    if (bHasRefs)
+    {
+        // Upon Insert ColRowNames have to be recompiled in case the
+        // insertion occurs right in front of the range.
+        bColRowNameCompile =
+            (eUpdateRefMode == URM_INSDEL && (nDx > 0 || nDy > 0));
+
+        if ( bColRowNameCompile )
         {
-            // Upon Insert ColRowNames have to be recompiled in case the
-            // insertion occurs right in front of the range.
-            bColRowNameCompile =
-                (eUpdateRefMode == URM_INSDEL && (nDx > 0 || nDy > 0));
-            if ( bColRowNameCompile )
+            bColRowNameCompile = false;
+            ScToken* t;
+            ScRangePairList* pColList = pDocument->GetColNameRanges();
+            ScRangePairList* pRowList = pDocument->GetRowNameRanges();
+            pCode->Reset();
+            while ( !bColRowNameCompile && (t = static_cast<ScToken*>(pCode->GetNextColRowName())) != NULL )
             {
-                bColRowNameCompile = false;
-                ScToken* t;
-                ScRangePairList* pColList = pDocument->GetColNameRanges();
-                ScRangePairList* pRowList = pDocument->GetRowNameRanges();
-                pCode->Reset();
-                while ( !bColRowNameCompile && (t = static_cast<ScToken*>(pCode->GetNextColRowName())) != NULL )
-                {
-                    ScSingleRefData& rRef = t->GetSingleRef();
-                    if ( nDy > 0 && rRef.IsColRel() )
-                    {   // ColName
-                        rRef.CalcAbsIfRel( aPos );
-                        ScAddress aAdr( rRef.nCol, rRef.nRow, rRef.nTab );
-                        ScRangePair* pR = pColList->Find( aAdr );
-                        if ( pR )
-                        {   // defined
-                            if ( pR->GetRange(1).aStart.Row() == nRow1 )
-                                bColRowNameCompile = true;
-                        }
-                        else
-                        {   // on the fly
-                            if ( rRef.nRow + 1 == nRow1 )
-                                bColRowNameCompile = true;
-                        }
+                ScSingleRefData& rRef = t->GetSingleRef();
+                if ( nDy > 0 && rRef.IsColRel() )
+                {   // ColName
+                    rRef.CalcAbsIfRel( aPos );
+                    ScAddress aAdr( rRef.nCol, rRef.nRow, rRef.nTab );
+                    ScRangePair* pR = pColList->Find( aAdr );
+                    if ( pR )
+                    {   // defined
+                        if ( pR->GetRange(1).aStart.Row() == nRow1 )
+                            bColRowNameCompile = true;
                     }
-                    if ( nDx > 0 && rRef.IsRowRel() )
-                    {   // RowName
-                        rRef.CalcAbsIfRel( aPos );
-                        ScAddress aAdr( rRef.nCol, rRef.nRow, rRef.nTab );
-                        ScRangePair* pR = pRowList->Find( aAdr );
-                        if ( pR )
-                        {   // defined
-                            if ( pR->GetRange(1).aStart.Col() == nCol1 )
-                                bColRowNameCompile = true;
-                        }
-                        else
-                        {   // on the fly
-                            if ( rRef.nCol + 1 == nCol1 )
-                                bColRowNameCompile = true;
-                        }
+                    else
+                    {   // on the fly
+                        if ( rRef.nRow + 1 == nRow1 )
+                            bColRowNameCompile = true;
+                    }
+                }
+                if ( nDx > 0 && rRef.IsRowRel() )
+                {   // RowName
+                    rRef.CalcAbsIfRel( aPos );
+                    ScAddress aAdr( rRef.nCol, rRef.nRow, rRef.nTab );
+                    ScRangePair* pR = pRowList->Find( aAdr );
+                    if ( pR )
+                    {   // defined
+                        if ( pR->GetRange(1).aStart.Col() == nCol1 )
+                            bColRowNameCompile = true;
+                    }
+                    else
+                    {   // on the fly
+                        if ( rRef.nCol + 1 == nCol1 )
+                            bColRowNameCompile = true;
                     }
                 }
             }
-            else if ( eUpdateRefMode == URM_MOVE )
-            {   // Recomplie for Move/D&D when ColRowName was moved or this Cell
-                // points to one and was moved.
-                bColRowNameCompile = bCompile;      // Possibly from Copy ctor
-                if ( !bColRowNameCompile )
+        }
+        else if ( eUpdateRefMode == URM_MOVE )
+        {   // Recomplie for Move/D&D when ColRowName was moved or this Cell
+            // points to one and was moved.
+            bColRowNameCompile = bCompile;      // Possibly from Copy ctor
+            if ( !bColRowNameCompile )
+            {
+                bool bMoved = (aPos != aOldPos);
+                pCode->Reset();
+                ScToken* t = static_cast<ScToken*>(pCode->GetNextColRowName());
+                if ( t && bMoved )
+                    bColRowNameCompile = true;
+                while ( t && !bColRowNameCompile )
                 {
-                    bool bMoved = (aPos != aOldPos);
-                    pCode->Reset();
-                    ScToken* t = static_cast<ScToken*>(pCode->GetNextColRowName());
-                    if ( t && bMoved )
-                        bColRowNameCompile = true;
-                    while ( t && !bColRowNameCompile )
+                    ScSingleRefData& rRef = t->GetSingleRef();
+                    rRef.CalcAbsIfRel( aPos );
+                    if ( rRef.Valid() )
                     {
-                        ScSingleRefData& rRef = t->GetSingleRef();
-                        rRef.CalcAbsIfRel( aPos );
-                        if ( rRef.Valid() )
-                        {
-                            ScAddress aAdr( rRef.nCol, rRef.nRow, rRef.nTab );
-                            if ( r.In( aAdr ) )
-                                bColRowNameCompile = true;
-                        }
-                        t = static_cast<ScToken*>(pCode->GetNextColRowName());
+                        ScAddress aAdr( rRef.nCol, rRef.nRow, rRef.nTab );
+                        if ( rRange.In( aAdr ) )
+                            bColRowNameCompile = true;
                     }
+                    t = static_cast<ScToken*>(pCode->GetNextColRowName());
                 }
             }
-            else if ( eUpdateRefMode == URM_COPY && bHasColRowNames && bValChanged )
-            {
-                bColRowNameCompile = true;
-            }
-            ScChangeTrack* pChangeTrack = pDocument->GetChangeTrack();
-            if ( pChangeTrack && pChangeTrack->IsInDeleteUndo() )
-                bInDeleteUndo = true;
-            else
-                bInDeleteUndo = false;
-            // RelNameRefs are always moved
-            bHasRelName = HasRelNameReference();
-            // Reference changed and new listening needed?
-            // Except in Insert/Delete without specialties.
-            bNewListening = (bRangeModified || pRangeData || bColRowNameCompile
-                    || (bValChanged && (eUpdateRefMode != URM_INSDEL ||
-                            bInDeleteUndo || bRefSizeChanged)) ||
-                    (bHasRelName && eUpdateRefMode != URM_COPY))
-                // #i36299# Don't duplicate action during cut&paste / drag&drop
-                // on a cell in the range moved, start/end listeners is done
-                // via ScDocument::DeleteArea() and ScDocument::CopyFromClip().
-                && !(eUpdateRefMode == URM_MOVE &&
-                        pDocument->IsInsertingFromOtherDoc() && r.In(aPos));
-            if ( bNewListening )
-                EndListeningTo( pDocument, pOld, aOldPos );
         }
-        else
+        else if ( eUpdateRefMode == URM_COPY && bHasColRowNames && bValChanged )
         {
-            bColRowNameCompile = bHasRelName = bNewListening = bInDeleteUndo =
-                false;
+            bColRowNameCompile = true;
         }
 
-        bool bNeedDirty = false;
-        // NeedDirty for changes except for Copy and Move/Insert without RelNames
-        if ( bRangeModified || pRangeData || bColRowNameCompile ||
-                (bValChanged && eUpdateRefMode != URM_COPY &&
-                 (eUpdateRefMode != URM_MOVE || bHasRelName) &&
-                 (!bIsInsert || bHasRelName || bInDeleteUndo ||
-                  bRefSizeChanged)) || bOnRefMove)
-            bNeedDirty = true;
-        else
-            bNeedDirty = false;
-        if (pUndoDoc && (bValChanged || pRangeData || bOnRefMove))
-        {
-            // Copy the cell to aUndoPos, which is its current position in the document,
-            // so this works when UpdateReference is called before moving the cells
-            // (InsertCells/DeleteCells - aPos is changed above) as well as when UpdateReference
-            // is called after moving the cells (MoveBlock/PasteFromClip - aOldPos is changed).
+        ScChangeTrack* pChangeTrack = pDocument->GetChangeTrack();
+        bInDeleteUndo = (pChangeTrack && pChangeTrack->IsInDeleteUndo());
 
-            // If there is already a formula cell in the undo document, don't overwrite it,
-            // the first (oldest) is the important cell.
-            if ( pUndoDoc->GetCellType( aUndoPos ) != CELLTYPE_FORMULA )
-            {
-                ScFormulaCell* pFCell = new ScFormulaCell( pUndoDoc, aUndoPos,
-                        pOld, eTempGrammar, cMatrixFlag );
-                pFCell->aResult.SetToken( NULL);  // to recognize it as changed later (Cut/Paste!)
-                pUndoDoc->SetFormulaCell(aUndoPos, pFCell);
-            }
-        }
-        bValChanged = false;
-        if ( pRangeData )
-        {   // Replace shared formula with own formula
-            pDocument->RemoveFromFormulaTree( this );   // update formula count
-            delete pCode;
-            pCode = pRangeData->GetCode()->Clone();
-            // #i18937# #i110008# call MoveRelWrap, but with the old position
-            ScCompiler::MoveRelWrap(*pCode, pDocument, aOldPos, pRangeData->GetMaxCol(), pRangeData->GetMaxRow());
-            ScCompiler aComp2(pDocument, aPos, *pCode);
-            aComp2.SetGrammar(pDocument->GetGrammar());
-            aComp2.UpdateSharedFormulaReference( eUpdateRefMode, aOldPos, r,
-                nDx, nDy, nDz );
-            bValChanged = true;
-            bNeedDirty = true;
-        }
-        if ( ( bCompile = (bCompile || bValChanged || bRangeModified || bColRowNameCompile) ) != 0 )
+        // RelNameRefs are always moved
+        bHasRelName = HasRelNameReference();
+        // Reference changed and new listening needed?
+        // Except in Insert/Delete without specialties.
+        bNewListening = (bRangeModified || pRangeData || bColRowNameCompile
+                || (bValChanged && (eUpdateRefMode != URM_INSDEL ||
+                        bInDeleteUndo || bRefSizeChanged)) ||
+                (bHasRelName && eUpdateRefMode != URM_COPY))
+            // #i36299# Don't duplicate action during cut&paste / drag&drop
+            // on a cell in the range moved, start/end listeners is done
+            // via ScDocument::DeleteArea() and ScDocument::CopyFromClip().
+            && !(eUpdateRefMode == URM_MOVE &&
+                    pDocument->IsInsertingFromOtherDoc() && rRange.In(aPos));
+
+        if ( bNewListening )
+            EndListeningTo(pDocument, pOldCode.get(), aOldPos);
+    }
+
+    bool bNeedDirty = false;
+    // NeedDirty for changes except for Copy and Move/Insert without RelNames
+    if ( bRangeModified || pRangeData || bColRowNameCompile ||
+            (bValChanged && eUpdateRefMode != URM_COPY &&
+             (eUpdateRefMode != URM_MOVE || bHasRelName) &&
+             (!bIsInsert || bHasRelName || bInDeleteUndo ||
+              bRefSizeChanged)) || bOnRefMove)
+        bNeedDirty = true;
+
+    if (pUndoDoc && (bValChanged || pRangeData || bOnRefMove))
+    {
+        // Copy the cell to aUndoPos, which is its current position in the document,
+        // so this works when UpdateReference is called before moving the cells
+        // (InsertCells/DeleteCells - aPos is changed above) as well as when UpdateReference
+        // is called after moving the cells (MoveBlock/PasteFromClip - aOldPos is changed).
+
+        // If there is already a formula cell in the undo document, don't overwrite it,
+        // the first (oldest) is the important cell.
+        if ( pUndoDoc->GetCellType( aUndoPos ) != CELLTYPE_FORMULA )
         {
-            CompileTokenArray( bNewListening ); // no Listening
-            bNeedDirty = true;
+            ScFormulaCell* pFCell = new ScFormulaCell( pUndoDoc, aUndoPos,
+                    pOldCode.get(), eTempGrammar, cMatrixFlag );
+            pFCell->aResult.SetToken( NULL);  // to recognize it as changed later (Cut/Paste!)
+            pUndoDoc->SetFormulaCell(aUndoPos, pFCell);
         }
-        if ( !bInDeleteUndo )
-        {   // In ChangeTrack Delete-Reject listeners are established in
-            // InsertCol/InsertRow
-            if ( bNewListening )
+    }
+
+    bValChanged = false;
+
+    if ( pRangeData )
+    {   // Replace shared formula with own formula
+        pDocument->RemoveFromFormulaTree( this );   // update formula count
+        delete pCode;
+        pCode = pRangeData->GetCode()->Clone();
+        // #i18937# #i110008# call MoveRelWrap, but with the old position
+        ScCompiler::MoveRelWrap(*pCode, pDocument, aOldPos, pRangeData->GetMaxCol(), pRangeData->GetMaxRow());
+        ScCompiler aComp2(pDocument, aPos, *pCode);
+        aComp2.SetGrammar(pDocument->GetGrammar());
+        aComp2.UpdateSharedFormulaReference( eUpdateRefMode, aOldPos, rRange,
+            nDx, nDy, nDz );
+        bValChanged = true;
+        bNeedDirty = true;
+    }
+
+    if ( ( bCompile = (bCompile || bValChanged || bRangeModified || bColRowNameCompile) ) != 0 )
+    {
+        CompileTokenArray( bNewListening ); // no Listening
+        bNeedDirty = true;
+    }
+
+    if ( !bInDeleteUndo )
+    {   // In ChangeTrack Delete-Reject listeners are established in
+        // InsertCol/InsertRow
+        if ( bNewListening )
+        {
+            if ( eUpdateRefMode == URM_INSDEL )
             {
-                if ( eUpdateRefMode == URM_INSDEL )
-                {
-                    // Inserts/Deletes re-establish listeners after all
-                    // UpdateReference calls.
-                    // All replaced shared formula listeners have to be
-                    // established after an Insert or Delete. Do nothing here.
-                    SetNeedsListening( true);
-                }
-                else
-                    StartListeningTo( pDocument );
+                // Inserts/Deletes re-establish listeners after all
+                // UpdateReference calls.
+                // All replaced shared formula listeners have to be
+                // established after an Insert or Delete. Do nothing here.
+                SetNeedsListening( true);
             }
+            else
+                StartListeningTo( pDocument );
         }
-        if ( bNeedDirty && (!(eUpdateRefMode == URM_INSDEL && bHasRelName) || pRangeData) )
-        {   // Cut off references, invalid or similar?
-            bool bOldAutoCalc = pDocument->GetAutoCalc();
-            // No Interpret in SubMinimalRecalc because of eventual wrong reference
-            pDocument->SetAutoCalc( false );
-            SetDirty();
-            pDocument->SetAutoCalc( bOldAutoCalc );
-        }
+    }
 
-        delete pOld;
+    if ( bNeedDirty && (!(eUpdateRefMode == URM_INSDEL && bHasRelName) || pRangeData) )
+    {   // Cut off references, invalid or similar?
+        sc::AutoCalcSwitch(*pDocument, false);
+        SetDirty();
     }
+
     return bCellStateChanged;
 }
 
commit b5e8b51f8643eb7576335ca01d7bffa2462e62f5
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Thu Jun 27 14:03:27 2013 -0400

    Reduce indentation to a sane level.
    
    Change-Id: I2940ca21f8cee0d780e58cfcda50705be61568d9

diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index ca8be5e..db84612 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -4265,126 +4265,115 @@ ScRangeData* ScCompiler::UpdateReference(UpdateRefMode eUpdateRefMode,
         }
         return pRangeData;
     }
-    else
+
+    ScRangeData* pRangeData = NULL;
+    ScToken* t;
+    pArr->Reset();
+    while( (t = static_cast<ScToken*>(pArr->GetNextReferenceOrName())) != NULL )
     {
-        ScRangeData* pRangeData = NULL;
-        ScToken* t;
-        pArr->Reset();
-        while( (t = static_cast<ScToken*>(pArr->GetNextReferenceOrName())) != NULL )
+        if( t->GetOpCode() == ocName )
         {
-            if( t->GetOpCode() == ocName )
+            ScRangeData* pName = GetRangeData( *t);
+            if (pName && pName->HasType(RT_SHAREDMOD))
             {
-                ScRangeData* pName = GetRangeData( *t);
-                if (pName && pName->HasType(RT_SHAREDMOD))
-                {
-                    pRangeData = pName;     // maybe need a replacement of shared with own code
-                    rChanged = true;
-                }
-            }
-            else if( t->GetType() != svIndex )  // it may be a DB area!!!
-            {
-                t->CalcAbsIfRel( rOldPos );
-                switch (t->GetType())
-                {
-                    case svExternalSingleRef:
-                    case svExternalDoubleRef:
-                        // External references never change their positioning
-                        // nor point to parts that will be removed or expanded.
-                        // In fact, calling ScRefUpdate::Update() for URM_MOVE
-                        // may have negative side effects. Simply adapt
-                        // relative references to the new position.
-                        t->CalcRelFromAbs( aPos);
-                        break;
-                    case svSingleRef:
-                        {
-                            if ( ScRefUpdate::Update( pDoc, eUpdateRefMode,
-                                        aPos, r, nDx, nDy, nDz,
-                                        SingleDoubleRefModifier(
-                                            t->GetSingleRef()).Ref())
-                                    != UR_NOTHING)
-                                rChanged = true;
-                        }
-                        break;
-                    default:
-                        {
-                            ScComplexRefData& rRef = t->GetDoubleRef();
-                            SCCOL nCols = rRef.Ref2.nCol - rRef.Ref1.nCol;
-                            SCROW nRows = rRef.Ref2.nRow - rRef.Ref1.nRow;
-                            SCTAB nTabs = rRef.Ref2.nTab - rRef.Ref1.nTab;
-                            if ( ScRefUpdate::Update( pDoc, eUpdateRefMode,
-                                        aPos, r, nDx, nDy, nDz,
-                                        t->GetDoubleRef()) != UR_NOTHING)
-                            {
-                                rChanged = true;
-                                if (rRef.Ref2.nCol - rRef.Ref1.nCol != nCols ||
-                                        rRef.Ref2.nRow - rRef.Ref1.nRow != nRows ||
-                                        rRef.Ref2.nTab - rRef.Ref1.nTab != nTabs)
-                                    rRefSizeChanged = true;
-                            }
-                        }
-                }
+                pRangeData = pName;     // maybe need a replacement of shared with own code
+                rChanged = true;
             }
         }
-        pArr->Reset();
-        while ( (t = static_cast<ScToken*>(pArr->GetNextReferenceRPN())) != NULL )
+        else if( t->GetType() != svIndex )  // it may be a DB area!!!
         {
-            if ( t->GetRef() != 1 )
+            t->CalcAbsIfRel( rOldPos );
+            switch (t->GetType())
             {
-            }
-            else
-            {   // if nRefCnt>1 it's already updated in token code
-                if ( t->GetType() == svSingleRef )
+                case svExternalSingleRef:
+                case svExternalDoubleRef:
+                    // External references never change their positioning
+                    // nor point to parts that will be removed or expanded.
+                    // In fact, calling ScRefUpdate::Update() for URM_MOVE
+                    // may have negative side effects. Simply adapt
+                    // relative references to the new position.
+                    t->CalcRelFromAbs( aPos);
+                    break;
+                case svSingleRef:
                 {
-                    ScSingleRefData& rRef = t->GetSingleRef();
-                    SingleDoubleRefModifier aMod( rRef );
-                    if ( rRef.IsRelName() )
-                    {
-                        ScRefUpdate::MoveRelWrap( pDoc, aPos, MAXCOL, MAXROW, aMod.Ref() );
+                    if ( ScRefUpdate::Update( pDoc, eUpdateRefMode,
+                                aPos, r, nDx, nDy, nDz,
+                                SingleDoubleRefModifier(
+                                    t->GetSingleRef()).Ref())
+                            != UR_NOTHING)
                         rChanged = true;
-                    }
-                    else
-                    {
-                        aMod.Ref().CalcAbsIfRel( rOldPos );
-                        if ( ScRefUpdate::Update( pDoc, eUpdateRefMode, aPos,
-                                    r, nDx, nDy, nDz, aMod.Ref() )
-                                != UR_NOTHING
-                            )
-                            rChanged = true;
-                    }
                 }
-                else
+                break;
+                default:
                 {
                     ScComplexRefData& rRef = t->GetDoubleRef();
                     SCCOL nCols = rRef.Ref2.nCol - rRef.Ref1.nCol;
                     SCROW nRows = rRef.Ref2.nRow - rRef.Ref1.nRow;
                     SCTAB nTabs = rRef.Ref2.nTab - rRef.Ref1.nTab;
-                    if ( rRef.Ref1.IsRelName() || rRef.Ref2.IsRelName() )
+                    if ( ScRefUpdate::Update( pDoc, eUpdateRefMode,
+                                aPos, r, nDx, nDy, nDz,
+                                t->GetDoubleRef()) != UR_NOTHING)
                     {
-                        ScRefUpdate::MoveRelWrap( pDoc, aPos, MAXCOL, MAXROW, rRef );
                         rChanged = true;
-                    }
-                    else
-                    {
-                        if ( ScRefUpdate::Update( pDoc, eUpdateRefMode, aPos,
-                                    r, nDx, nDy, nDz, rRef )
-                                != UR_NOTHING
-                            )
-                        {
-                            rChanged = true;
-                            if (rRef.Ref2.nCol - rRef.Ref1.nCol != nCols ||
-                                    rRef.Ref2.nRow - rRef.Ref1.nRow != nRows ||
-                                    rRef.Ref2.nTab - rRef.Ref1.nTab != nTabs)
-                            {
-                                rRefSizeChanged = true;
-                            }
-                        }
+                        if (rRef.Ref2.nCol - rRef.Ref1.nCol != nCols ||
+                                rRef.Ref2.nRow - rRef.Ref1.nRow != nRows ||
+                                rRef.Ref2.nTab - rRef.Ref1.nTab != nTabs)
+                            rRefSizeChanged = true;
                     }
                 }
             }
         }
+    }
+    pArr->Reset();
+    while ( (t = static_cast<ScToken*>(pArr->GetNextReferenceRPN())) != NULL )
+    {
+        if (t->GetRef() != 1)
+            continue;
 
-        return pRangeData;
+        if ( t->GetType() == svSingleRef )
+        {
+            ScSingleRefData& rRef = t->GetSingleRef();
+            SingleDoubleRefModifier aMod( rRef );
+            if ( rRef.IsRelName() )
+            {
+                ScRefUpdate::MoveRelWrap( pDoc, aPos, MAXCOL, MAXROW, aMod.Ref() );
+                rChanged = true;
+            }
+            else
+            {
+                aMod.Ref().CalcAbsIfRel( rOldPos );
+                if ( ScRefUpdate::Update( pDoc, eUpdateRefMode, aPos,
+                            r, nDx, nDy, nDz, aMod.Ref() )
+                        != UR_NOTHING
+                    )
+                    rChanged = true;
+            }
+        }
+        else
+        {
+            ScComplexRefData& rRef = t->GetDoubleRef();
+            SCCOL nCols = rRef.Ref2.nCol - rRef.Ref1.nCol;
+            SCROW nRows = rRef.Ref2.nRow - rRef.Ref1.nRow;
+            SCTAB nTabs = rRef.Ref2.nTab - rRef.Ref1.nTab;
+            if ( rRef.Ref1.IsRelName() || rRef.Ref2.IsRelName() )
+            {
+                ScRefUpdate::MoveRelWrap( pDoc, aPos, MAXCOL, MAXROW, rRef );
+                rChanged = true;
+            }
+            else if (ScRefUpdate::Update(pDoc, eUpdateRefMode, aPos, r, nDx, nDy, nDz, rRef) != UR_NOTHING)
+            {
+                rChanged = true;
+                if (rRef.Ref2.nCol - rRef.Ref1.nCol != nCols ||
+                        rRef.Ref2.nRow - rRef.Ref1.nRow != nRows ||
+                        rRef.Ref2.nTab - rRef.Ref1.nTab != nTabs)
+                {
+                    rRefSizeChanged = true;
+                }
+            }
+        }
     }
+
+    return pRangeData;
 }
 
 bool ScCompiler::UpdateNameReference(UpdateRefMode eUpdateRefMode,
commit c8ed4d86bbdde79ea28c59742eac702f9622d57a
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Thu Jun 27 13:52:50 2013 -0400

    Remove this old attempt of shared formula code.
    
    We'll devise a brand-new solution for this.
    
    Change-Id: Ib4e04b3ce0b5d1ab511aecfab35f81e43dd4edf9

diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 81cd26d..a3ab73d 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -2055,7 +2055,6 @@ bool ScFormulaCell::UpdateReference(UpdateRefMode eUpdateRefMode,
     if ( pUndoCellPos )
         aUndoPos = *pUndoCellPos;
     ScAddress aOldPos( aPos );
-//  bool bPosChanged = false;           // if this cell was moved
     bool bIsInsert = (eUpdateRefMode == URM_INSDEL &&
                 nDx >= 0 && nDy >= 0 && nDz >= 0);
     if (eUpdateRefMode == URM_INSDEL && r.In( aPos ))
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index d0ef4ad..ca8be5e 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -4267,14 +4267,6 @@ ScRangeData* ScCompiler::UpdateReference(UpdateRefMode eUpdateRefMode,
     }
     else
     {
-/*
- * Set SC_PRESERVE_SHARED_FORMULAS_IF_POSSIBLE to 1 if we wanted to preserve as
- * many shared formulas as possible instead of replacing them with direct code.
- * Note that this may produce shared formula usage Excel doesn't understand,
- * which would have to be adapted for in the export filter. Advisable as a long
- * term goal, since it could decrease memory footprint.
- */
-#define SC_PRESERVE_SHARED_FORMULAS_IF_POSSIBLE 0
         ScRangeData* pRangeData = NULL;
         ScToken* t;
         pArr->Reset();
@@ -4286,9 +4278,7 @@ ScRangeData* ScCompiler::UpdateReference(UpdateRefMode eUpdateRefMode,
                 if (pName && pName->HasType(RT_SHAREDMOD))
                 {
                     pRangeData = pName;     // maybe need a replacement of shared with own code
-#if ! SC_PRESERVE_SHARED_FORMULAS_IF_POSSIBLE
                     rChanged = true;
-#endif
                 }
             }
             else if( t->GetType() != svIndex )  // it may be a DB area!!!
@@ -4335,24 +4325,11 @@ ScRangeData* ScCompiler::UpdateReference(UpdateRefMode eUpdateRefMode,
                 }
             }
         }
-#if SC_PRESERVE_SHARED_FORMULAS_IF_POSSIBLE
-        bool bEasyShared, bPosInRange;
-        if ( !pRangeData )
-            bEasyShared = bPosInRange = false;
-        else
-        {
-            bEasyShared = true;
-            bPosInRange = r.In( eUpdateRefMode == URM_MOVE ? aPos : rOldPos );
-        }
-#endif
         pArr->Reset();
         while ( (t = static_cast<ScToken*>(pArr->GetNextReferenceRPN())) != NULL )
         {
             if ( t->GetRef() != 1 )
             {
-#if SC_PRESERVE_SHARED_FORMULAS_IF_POSSIBLE
-                bEasyShared = false;
-#endif
             }
             else
             {   // if nRefCnt>1 it's already updated in token code
@@ -4374,15 +4351,6 @@ ScRangeData* ScCompiler::UpdateReference(UpdateRefMode eUpdateRefMode,
                             )
                             rChanged = true;
                     }
-#if SC_PRESERVE_SHARED_FORMULAS_IF_POSSIBLE
-                    if ( bEasyShared )
-                    {
-                        const ScSingleRefData& rSRD = aMod.Ref().Ref1;
-                        ScAddress aRef( rSRD.nCol, rSRD.nRow, rSRD.nTab );
-                        if ( r.In( aRef ) != bPosInRange )
-                            bEasyShared = false;
-                    }
-#endif
                 }
                 else
                 {
@@ -4408,35 +4376,13 @@ ScRangeData* ScCompiler::UpdateReference(UpdateRefMode eUpdateRefMode,
                                     rRef.Ref2.nTab - rRef.Ref1.nTab != nTabs)
                             {
                                 rRefSizeChanged = true;
-#if SC_PRESERVE_SHARED_FORMULAS_IF_POSSIBLE
-                                bEasyShared = false;
-#endif
                             }
                         }
                     }
-#if SC_PRESERVE_SHARED_FORMULAS_IF_POSSIBLE
-                    if ( bEasyShared )
-                    {
-                        ScRange aRef( rRef.Ref1.nCol, rRef.Ref1.nRow,
-                                rRef.Ref1.nTab, rRef.Ref2.nCol, rRef.Ref2.nRow,
-                                rRef.Ref2.nTab );
-                        if ( r.In( aRef ) != bPosInRange )
-                            bEasyShared = false;
-                    }
-#endif
                 }
             }
         }
-#if SC_PRESERVE_SHARED_FORMULAS_IF_POSSIBLE
-        if ( pRangeData )
-        {
-            if ( bEasyShared )
-                pRangeData = 0;
-            else
-                rChanged = true;
-        }
-#endif
-#undef SC_PRESERVE_SHARED_FORMULAS_IF_POSSIBLE
+
         return pRangeData;
     }
 }
commit d14e48591f2ede07626bfa8adde403d762a28d18
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Thu Jun 27 11:44:22 2013 -0400

    A little more detail in the method documentation.
    
    Change-Id: I0f25a8e660ff98d89965ff3428873dec43dbeda1

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index d38762a..b119d3d 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -312,11 +312,15 @@ public:
      * Update reference addresses in formula cell in response to mass cell
      * movement.
      *
-     * @param eUpdateRefMode update mode - insert/delete, copy, move,
-     *                       reorder...
-     * @param rRange range of cells that are about to be moved or copied.
-     *               (TODO: find out what this range means for the reorder
-     *               mode).
+     * @param eUpdateRefMode update mode - insert/delete, copy, or move. The
+     *                       reorder mode (which corresponds with the
+     *                       reordering of sheets) is not used with this
+     *                       method.
+     *
+     * @param rRange range of cells that are about to be moved for
+     *               insert/delete/move modes. For copy mode, it's the
+     *               destination range of cells that are about to be copied.
+     *
      * @param nDx moved by how many cells in the column direction.
      * @param nDy moved by how many cells in the row direction.
      * @param nDz moved by how many sheets in the sheet direction.
commit bac886b75f3ce94178ba1751fc85cd4f2c5a9d0f
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Thu Jun 27 11:29:46 2013 -0400

    ScColumn::UpdateReference to take ScRange as a parameter.
    
    To reduce the number of parameters by 5.  Also add *some* description
    of this method esp what the range means when updating formula references.
    
    Change-Id: Iccde58d6ecde6f0c09c111cf9b4f551ce392effb

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 1c04e5d..d38762a 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -308,10 +308,27 @@ public:
 
     void        ResetChanged( SCROW nStartRow, SCROW nEndRow );
 
-    bool        UpdateReference( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
-                                     SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
-                                     SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
-                                     ScDocument* pUndoDoc = NULL );
+    /**
+     * Update reference addresses in formula cell in response to mass cell
+     * movement.
+     *
+     * @param eUpdateRefMode update mode - insert/delete, copy, move,
+     *                       reorder...
+     * @param rRange range of cells that are about to be moved or copied.
+     *               (TODO: find out what this range means for the reorder
+     *               mode).
+     * @param nDx moved by how many cells in the column direction.
+     * @param nDy moved by how many cells in the row direction.
+     * @param nDz moved by how many sheets in the sheet direction.
+     * @param pUndoDoc undo document instance.
+     *
+     * @return true if reference of at least one formula cell has been
+     *         updated, false otherwise.
+     */
+    bool UpdateReference(
+        UpdateRefMode eUpdateRefMode, const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
+        ScDocument* pUndoDoc = NULL );
+
     void UpdateInsertTab(SCTAB nInsPos, SCTAB nNewSheets = 1);
     void UpdateInsertTabOnlyCells(SCTAB nInsPos, SCTAB nNewSheets = 1);
     void UpdateDeleteTab(SCTAB nDelPos, bool bIsMove, ScColumn* pRefUndo = NULL, SCTAB nSheets = 1);
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 8c53a69..9f75ad8 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1992,9 +1992,8 @@ void ScColumn::CopyScenarioFrom( const ScColumn& rSrcCol )
             //  UpdateUsed not needed, already done in TestCopyScenario (obsolete comment ?)
 
             SCsTAB nDz = nTab - rSrcCol.nTab;
-            UpdateReference(URM_COPY, nCol, nStart, nTab,
-                                      nCol, nEnd,   nTab,
-                                      0, 0, nDz, NULL);
+            UpdateReference(
+                URM_COPY, ScRange(nCol, nStart, nTab, nCol, nEnd, nTab), 0, 0, nDz, NULL);
             UpdateCompile();
         }
 
@@ -2023,9 +2022,9 @@ void ScColumn::CopyScenarioTo( ScColumn& rDestCol ) const
             //  UpdateUsed not needed, is already done in TestCopyScenario (obsolete comment ?)
 
             SCsTAB nDz = rDestCol.nTab - nTab;
-            rDestCol.UpdateReference(URM_COPY, rDestCol.nCol, nStart, rDestCol.nTab,
-                                               rDestCol.nCol, nEnd,   rDestCol.nTab,
-                                               0, 0, nDz, NULL);
+            rDestCol.UpdateReference(
+                URM_COPY, ScRange(rDestCol.nCol, nStart, rDestCol.nTab, rDestCol.nCol, nEnd, rDestCol.nTab),
+                0, 0, nDz, NULL);
             rDestCol.UpdateCompile();
         }
 
@@ -2221,21 +2220,19 @@ public:
 
 }
 
-bool ScColumn::UpdateReference( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
-             SCCOL nCol2, SCROW nRow2, SCTAB nTab2, SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
-             ScDocument* pUndoDoc )
+bool ScColumn::UpdateReference(
+    UpdateRefMode eUpdateRefMode, const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
+    ScDocument* pUndoDoc )
 {
-    ScRange aRange(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
-
     if (eUpdateRefMode == URM_COPY)
     {
-        UpdateRefOnCopy aHandler(aRange, nDx, nDy, nDz, pUndoDoc);
-        FormulaCellsUndecided(nRow1, nRow2);
-        sc::ProcessBlock(maCells.begin(), maCells, aHandler, nRow1, nRow2);
+        UpdateRefOnCopy aHandler(rRange, nDx, nDy, nDz, pUndoDoc);
+        FormulaCellsUndecided(rRange.aStart.Row(), rRange.aEnd.Row());
+        sc::ProcessBlock(maCells.begin(), maCells, aHandler, rRange.aStart.Row(), rRange.aEnd.Row());
         return aHandler.isUpdated();
     }
 
-    UpdateRefOnNonCopy aHandler(nCol, nTab, aRange, nDx, nDy, nDz, eUpdateRefMode, pUndoDoc);
+    UpdateRefOnNonCopy aHandler(nCol, nTab, rRange, nDx, nDy, nDz, eUpdateRefMode, pUndoDoc);
     FormulaCellsUndecided(0, MAXROW);
     sc::ProcessFormula(maCells, aHandler);
     return aHandler.isUpdated();
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index be6f4ae..2d90fa9 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -1463,16 +1463,14 @@ void ScTable::UpdateReference( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW
         iMax = MAXCOL;
     }
 
+    ScRange aRange(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
+
     // Named expressions need to be updated before formulas acessing them.
     if (mpRangeName)
-    {
-        ScRange aRange( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );;
         mpRangeName->UpdateReference( eUpdateRefMode, aRange, nDx, nDy, nDz, true );
-    }
 
     for ( ; i<=iMax; i++)
-        bUpdated |= aCol[i].UpdateReference(
-            eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz, pUndoDoc );
+        bUpdated |= aCol[i].UpdateReference(eUpdateRefMode, aRange, nDx, nDy, nDz, pUndoDoc);
 
     if ( bIncludeDraw )
         UpdateDrawRef( eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz, bUpdateNoteCaptionPos );
commit cfc732b858befd0f9102cb0161e9afde424dcecf
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Jun 26 23:06:02 2013 -0400

    No need to increment formula row positions in InsertRow().
    
    UpdateReference() which gets called before InsertRow() moves the formula
    positions.
    
    Change-Id: I6d00607a1a1b4463f69bb58610f6ba41871e4475

diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 36c3628..c66f3c0 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -237,6 +237,7 @@ public:
     void testUpdateReference();
     void testSearchCells();
     void testSharedFormulas();
+    void testFormulaPosition();
 
     /**
      * Make sure the sheet streams are invalidated properly.
@@ -354,6 +355,7 @@ public:
     CPPUNIT_TEST(testUpdateReference);
     CPPUNIT_TEST(testSearchCells);
     CPPUNIT_TEST(testSharedFormulas);
+    CPPUNIT_TEST(testFormulaPosition);
     CPPUNIT_TEST(testJumpToPrecedentsDependents);
     CPPUNIT_TEST(testSetBackgroundColor);
     CPPUNIT_TEST(testRenameTable);
@@ -6405,6 +6407,76 @@ void Test::testSharedFormulas()
 
 namespace {
 
+bool checkFormulaPosition(ScDocument& rDoc, const ScAddress& rPos)
+{
+    OUString aStr;
+    rPos.Format(aStr, SCA_VALID);
+    const ScFormulaCell* pFC = rDoc.GetFormulaCell(rPos);
+    if (!pFC)
+    {
+        cerr << "Formula cell expected at " << aStr << " but not found." << endl;
+        return false;
+    }
+
+    if (pFC->aPos != rPos)
+    {
+        OUString aStr2;
+        pFC->aPos.Format(aStr2, SCA_VALID);
+        cerr << "Formula cell at " << aStr << " has incorrect position of " << aStr2 << endl;
+        return false;
+    }
+
+    return true;
+}
+
+void checkFormulaPositions(ScDocument& rDoc, const ScAddress& rPos, const SCROW* pRows, size_t nRowCount)
+{
+    ScAddress aPos = rPos;
+    for (size_t i = 0; i < nRowCount; ++i)
+    {
+        SCROW nRow = pRows[i];
+        aPos.SetRow(nRow);
+
+        if (!checkFormulaPosition(rDoc, aPos))
+        {
+            OUString aStr;
+            aPos.Format(aStr, SCA_VALID);
+            std::ostringstream os;
+            os << "Formula cell position failed at " << aStr;
+            CPPUNIT_FAIL(os.str().c_str());
+        }
+    }
+}
+
+}
+
+void Test::testFormulaPosition()
+{
+    m_pDoc->InsertTab(0, "Test");
+
+    ScAddress aPos(0,0,0); // A1
+    m_pDoc->SetString(aPos, "=ROW()");
+    aPos.IncRow(); // A2
+    m_pDoc->SetString(aPos, "=ROW()");
+    aPos.SetRow(3); // A4;
+    m_pDoc->SetString(aPos, "=ROW()");
+
+    {
+        SCROW aRows[] = { 0, 1, 3 };
+        checkFormulaPositions(*m_pDoc, aPos, aRows, SAL_N_ELEMENTS(aRows));
+    }
+
+    m_pDoc->InsertRow(0,0,0,0,1,5); // Insert 5 rows at A2.
+    {
+        SCROW aRows[] = { 0, 6, 8 };
+        checkFormulaPositions(*m_pDoc, aPos, aRows, SAL_N_ELEMENTS(aRows));
+    }
+
+    m_pDoc->DeleteTab(0);
+}
+
+namespace {
+
 bool hasRange(const std::vector<ScTokenRef>& rRefTokens, const ScRange& rRange)
 {
     std::vector<ScTokenRef>::const_iterator it = rRefTokens.begin(), itEnd = rRefTokens.end();
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 39bfd2f..8c53a69 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1233,43 +1233,9 @@ void ScColumn::InsertRow( SCROW nStartRow, SCSIZE nSize )
     maCellTextAttrs.insert_empty(nStartRow, nSize);
     maCellTextAttrs.resize(MAXROWCOUNT);
 
-    sc::CellStoreType::position_type aPos = maCells.position(nStartRow);
-    sc::CellStoreType::iterator it = maCells.insert_empty(aPos.first, nStartRow, nSize);
+    maCells.insert_empty(nStartRow, nSize);
     maCells.resize(MAXROWCOUNT);
 
-    sc::AutoCalcSwitch aSwitch(*pDocument, false);
-
-    // Get the position of the first affected cell.
-    aPos = maCells.position(it, nStartRow+nSize);
-    it = aPos.first;
-
-    // Update the positions of all affected formula cells.
-    if (it->type == sc::element_type_formula)
-    {
-        sc::formula_block::iterator itf = sc::formula_block::begin(*it->data);
-        sc::formula_block::iterator itfEnd = sc::formula_block::end(*it->data);
-        std::advance(itf, aPos.second);
-        for (; itf != itfEnd; ++itf)
-        {
-            ScFormulaCell& rCell = **itf;
-            rCell.aPos.IncRow(nSize);
-        }
-    }
-
-    for (++it; it != maCells.end(); ++it)
-    {
-        if (it->type != sc::element_type_formula)
-            continue;
-
-        sc::formula_block::iterator itf = sc::formula_block::begin(*it->data);
-        sc::formula_block::iterator itfEnd = sc::formula_block::end(*it->data);
-        for (; itf != itfEnd; ++itf)
-        {
-            ScFormulaCell* pCell = *itf;
-            pCell->aPos.IncRow(nSize);
-        }
-    }
-
     CellStorageModified();
 
     // We *probably* don't need to broadcast here since the parent call seems
commit b5a195e65cd5de06e17e5a7aeb69024f8f8761c9
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Jun 26 21:50:38 2013 -0400

    More on shared formula cell handling.
    
    Change-Id: Ifb0feff8c7016e3cadfa219ea6421852112ca189

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 78011ad..1c04e5d 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -476,6 +476,13 @@ public:
     void UnshareFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const;
 
     /**
+     * Split existing shared formula range at specified position. The cell at
+     * specified position becomes the top cell of the lower shared formula
+     * range after this call.
+     */
+    void SplitFormulaCellGroup( const sc::CellStoreType::position_type& aPos ) const;
+
+    /**
      * Regroup formula cells for the entire column.
      */
     void RegroupFormulaCells();
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 5286965..36c3628 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -6369,6 +6369,37 @@ void Test::testSharedFormulas()
     CPPUNIT_ASSERT_EQUAL(12, pFC->GetSharedTopRow());
     CPPUNIT_ASSERT_EQUAL(4, pFC->GetSharedLength());
 
+    // Extend B13:B16 to B13:B20.
+    aPos.SetRow(16); // B17
+    m_pDoc->SetString(aPos, "=A17*2");
+    aPos.IncRow();
+    m_pDoc->SetString(aPos, "=A18*2");
+    aPos.IncRow();
+    m_pDoc->SetString(aPos, "=A19*2");
+    aPos.IncRow();
+    m_pDoc->SetString(aPos, "=A20*2");
+    pFC = m_pDoc->GetFormulaCell(aPos);
+    CPPUNIT_ASSERT_MESSAGE("This cell is expected to be a shared formula cell.", pFC && pFC->IsShared());
+    CPPUNIT_ASSERT_EQUAL(12, pFC->GetSharedTopRow());
+    CPPUNIT_ASSERT_EQUAL(8, pFC->GetSharedLength());
+
+#if 0
+    // Insert empty rows at B16 to split B13:B20 into B13:B15 and B21:B25.
+    m_pDoc->InsertRow(1, 0, 1, 0, 15, 5);
+
+    aPos.SetRow(12); // B13
+    pFC = m_pDoc->GetFormulaCell(aPos);
+    CPPUNIT_ASSERT_MESSAGE("This cell is expected to be a shared formula cell.", pFC && pFC->IsShared());
+    CPPUNIT_ASSERT_EQUAL(12, pFC->GetSharedTopRow());
+    CPPUNIT_ASSERT_EQUAL(3, pFC->GetSharedLength());
+
+    aPos.SetRow(23); // B24
+    pFC = m_pDoc->GetFormulaCell(aPos);
+    CPPUNIT_ASSERT_MESSAGE("This cell is expected to be a shared formula cell.", pFC && pFC->IsShared());
+    CPPUNIT_ASSERT_EQUAL(20, pFC->GetSharedTopRow());
+    CPPUNIT_ASSERT_EQUAL(5, pFC->GetSharedLength());
+#endif
+
     m_pDoc->DeleteTab(0);
 }
 
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 1e08708..39bfd2f 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1233,10 +1233,7 @@ void ScColumn::InsertRow( SCROW nStartRow, SCSIZE nSize )
     maCellTextAttrs.insert_empty(nStartRow, nSize);
     maCellTextAttrs.resize(MAXROWCOUNT);
 
-    // Check if this insertion will split an existing formula block.
     sc::CellStoreType::position_type aPos = maCells.position(nStartRow);
-    bool bSplitFormulaBlock = aPos.second != 0;
-
     sc::CellStoreType::iterator it = maCells.insert_empty(aPos.first, nStartRow, nSize);
     maCells.resize(MAXROWCOUNT);
 
@@ -1254,8 +1251,8 @@ void ScColumn::InsertRow( SCROW nStartRow, SCSIZE nSize )
         std::advance(itf, aPos.second);
         for (; itf != itfEnd; ++itf)
         {
-            ScFormulaCell* pCell = *itf;
-            pCell->aPos.IncRow(nSize);
+            ScFormulaCell& rCell = **itf;
+            rCell.aPos.IncRow(nSize);
         }
     }
 
@@ -1273,9 +1270,6 @@ void ScColumn::InsertRow( SCROW nStartRow, SCSIZE nSize )
         }
     }
 
-    if (bSplitFormulaBlock)
-        RegroupFormulaCells(nStartRow, nStartRow+nSize-1);
-
     CellStorageModified();
 
     // We *probably* don't need to broadcast here since the parent call seems
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index bfb5590..ee200f5 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -429,7 +429,7 @@ void ScColumn::UnshareFormulaCell(
 #if DEBUG_COLUMN_STORAGE
             if (aPos.second+1 >= aPos.first->size)
             {
-                cerr << "ScColumn::GetPositionToInsert: There is no next formula cell but there should be!" << endl;
+                cerr << "ScColumn::UnshareFormulaCell: There is no next formula cell but there should be!" << endl;
                 cerr.flush();
                 abort();
             }
@@ -454,7 +454,7 @@ void ScColumn::UnshareFormulaCell(
 #if DEBUG_COLUMN_STORAGE
             if (aPos.second == 0)
             {
-                cerr << "ScColumn::GetPositionToInsert: There is no previous formula cell but there should be!" << endl;
+                cerr << "ScColumn::UnshareFormulaCell: There is no previous formula cell but there should be!" << endl;
                 cerr.flush();
                 abort();
             }
@@ -482,7 +482,7 @@ void ScColumn::UnshareFormulaCell(
 #if DEBUG_COLUMN_STORAGE
         if (xGroup2->mnStart + xGroup2->mnLength > it->position + it->size)
         {
-            cerr << "ScColumn::GetPositionToInsert: Shared formula region goes beyond the formula block. Not good." << endl;
+            cerr << "ScColumn::UnshareFormulaCell: Shared formula region goes beyond the formula block. Not good." << endl;
             cerr.flush();
             abort();
         }
@@ -501,6 +501,56 @@ void ScColumn::UnshareFormulaCell(
     rCell.SetCellGroup(xNone);
 }
 
+void ScColumn::SplitFormulaCellGroup( const sc::CellStoreType::position_type& aPos ) const
+{
+    SCROW nRow = aPos.first->position + aPos.second;
+
+    if (aPos.first->type != sc::element_type_formula)
+        // Not a formula cell block.
+        return;
+
+    if (aPos.second == 0)
+        // Split position coincides with the block border. Nothing to do.
+        return;
+
+    sc::formula_block::iterator it = sc::formula_block::begin(*aPos.first->data);
+    std::advance(it, aPos.second);
+    ScFormulaCell& rTop = **it;
+    if (!rTop.IsShared())
+        // Not a shared formula.
+        return;
+
+    if (nRow == rTop.GetSharedTopRow())
+        // Already the top cell of a shared group.
+        return;
+
+    ScFormulaCellGroupRef xGroup = rTop.GetCellGroup();
+
+    ScFormulaCellGroupRef xGroup2(new ScFormulaCellGroup);
+    xGroup2->mbInvariant = xGroup->mbInvariant;
+    xGroup2->mnStart = nRow;
+    xGroup2->mnLength = xGroup->mnStart + xGroup->mnLength - nRow;
+
+    xGroup->mnLength = nRow - xGroup->mnStart;
+
+    // Apply the lower group object to the lower cells.
+#if DEBUG_COLUMN_STORAGE
+        if (xGroup2->mnStart + xGroup2->mnLength > aPos.first->position + aPos.first->size)
+        {
+            cerr << "ScColumn::SplitFormulaCellGroup: Shared formula region goes beyond the formula block. Not good." << endl;
+            cerr.flush();
+            abort();
+        }
+#endif
+    sc::formula_block::iterator itEnd = it;
+    std::advance(itEnd, xGroup2->mnLength);
+    for (; it != itEnd; ++it)
+    {
+        ScFormulaCell& rCell = **it;
+        rCell.SetCellGroup(xGroup2);
+    }
+}
+
 sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreType::iterator& it, SCROW nRow )
 {
     // See if we are overwriting an existing formula cell.
commit ab030f75deafad4aab33ac47bfb36dd252e3515e
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Jun 26 19:16:45 2013 -0400

    Handle formula cells in SwapCell().
    
    Change-Id: I9ddc69793e70bd399b93ce472a38060b1a946ff9

diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index e29a8a6..1e08708 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1129,26 +1129,43 @@ void updateRefInFormulaCell( ScFormulaCell& rCell, SCCOL nCol, SCTAB nTab, SCCOL
 
 void ScColumn::SwapCell( SCROW nRow, ScColumn& rCol)
 {
-    ScFormulaCell* pCell1 = maCells.get<ScFormulaCell*>(nRow);
-    ScFormulaCell* pCell2 = rCol.maCells.get<ScFormulaCell*>(nRow);
-    if (pCell1)
-        updateRefInFormulaCell(*pCell1, rCol.nCol, nTab, rCol.nCol - nCol);
+    sc::CellStoreType::position_type aPos1 = maCells.position(nRow);
+    sc::CellStoreType::position_type aPos2 = rCol.maCells.position(nRow);
 
-    if (pCell2)
-        updateRefInFormulaCell(*pCell2, nCol, nTab, nCol - rCol.nCol);
+    if (aPos1.first->type == sc::element_type_formula)
+    {
+        ScFormulaCell& rCell = *sc::formula_block::at(*aPos1.first->data, aPos1.second);
+        updateRefInFormulaCell(rCell, rCol.nCol, nTab, rCol.nCol - nCol);
+        UnshareFormulaCell(aPos1, rCell);
+    }
+
+    if (aPos2.first->type == sc::element_type_formula)
+    {
+        ScFormulaCell& rCell = *sc::formula_block::at(*aPos2.first->data, aPos2.second);
+        updateRefInFormulaCell(rCell, nCol, nTab, nCol - rCol.nCol);
+        UnshareFormulaCell(aPos2, rCell);
+    }
 
     maCells.swap(nRow, nRow, rCol.maCells, nRow);
     maCellTextAttrs.swap(nRow, nRow, rCol.maCellTextAttrs, nRow);
 
-    CellStorageModified();
-    rCol.CellStorageModified();
+    aPos1 = maCells.position(nRow);
+    aPos2 = rCol.maCells.position(nRow);
 
-    if (pCell1 || pCell2)
+    if (aPos1.first->type == sc::element_type_formula)
     {
-        // At least one of the two cells is a formula cell. Regroup them.
-        RegroupFormulaCells(nRow);
-        rCol.RegroupFormulaCells(nRow);
+        ScFormulaCell& rCell = *sc::formula_block::at(*aPos1.first->data, aPos1.second);
+        JoinNewFormulaCell(aPos1, rCell);
     }
+
+    if (aPos2.first->type == sc::element_type_formula)
+    {
+        ScFormulaCell& rCell = *sc::formula_block::at(*aPos2.first->data, aPos2.second);
+        rCol.JoinNewFormulaCell(aPos2, rCell);
+    }
+
+    CellStorageModified();
+    rCol.CellStorageModified();
 }
 
 
commit a8153482ad4f918f3501aed34c3131e970592575
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Jun 26 18:59:57 2013 -0400

    Proper handling of formula cells in SwapRow().
    
    Change-Id: Id295160b69cc5cb40cd9e0403928dac8b0e58807

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index a9aae2c..78011ad 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -147,8 +147,7 @@ public:
     const sc::CellTextAttrStoreType& GetCellAttrStore() const { return maCellTextAttrs; }
 
     ScRefCellValue GetCellValue( SCROW nRow ) const;
-    ScRefCellValue GetCellValue( sc::CellStoreType::const_iterator& itPos, SCROW nRow ) const;
-    ScRefCellValue GetCellValue( sc::CellStoreType::const_iterator& itPos, size_t nOffset ) const;
+    ScRefCellValue GetCellValue( const sc::CellStoreType::const_iterator& itPos, size_t nOffset ) const;
 
     void        Delete( SCROW nRow );
     void        FreeAll();
@@ -468,6 +467,12 @@ public:
 
     void JoinNewFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const;
 
+    /**
+     * Detouch a formula cell that's about to be deleted, or removed from
+     * document storage (if that ever happens).
+     */
+    void DetouchFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const;
+
     void UnshareFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const;
 
     /**
@@ -497,6 +502,7 @@ private:
     sc::CellStoreType::iterator GetPositionToInsert( SCROW nRow );
     sc::CellStoreType::iterator GetPositionToInsert( const sc::CellStoreType::iterator& it, SCROW nRow );
     void ActivateNewFormulaCell( const sc::CellStoreType::iterator& itPos, SCROW nRow, ScFormulaCell& rCell );
+    void ActivateNewFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell );
     void BroadcastNewCell( SCROW nRow );
     bool UpdateScriptType( sc::CellTextAttr& rAttr, SCROW nRow );
 
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 9bf8dac..e29a8a6 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -763,17 +763,7 @@ ScRefCellValue ScColumn::GetCellValue( SCROW nRow ) const
     return GetCellValue(aPos.first, aPos.second);
 }
 
-ScRefCellValue ScColumn::GetCellValue( sc::CellStoreType::const_iterator& itPos, SCROW nRow ) const
-{
-    std::pair<sc::CellStoreType::const_iterator,size_t> aPos = maCells.position(itPos, nRow);
-    itPos = aPos.first;
-    if (aPos.first == maCells.end())
-        return ScRefCellValue();
-
-    return GetCellValue(itPos, aPos.second);
-}
-
-ScRefCellValue ScColumn::GetCellValue( sc::CellStoreType::const_iterator& itPos, size_t nOffset ) const
+ScRefCellValue ScColumn::GetCellValue( const sc::CellStoreType::const_iterator& itPos, size_t nOffset ) const
 {
     ScRefCellValue aVal; // Defaults to empty cell.
     switch (itPos->type)
@@ -820,8 +810,6 @@ ScFormulaCell* cloneFormulaCell(ScDocument* pDoc, const ScAddress& rNewPos, ScFo
 
 void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
 {
-    typedef std::pair<sc::CellStoreType::iterator,size_t> CellPosType;
-
     if (nRow1 == nRow2)
         // Nothing to swap.
         return;
@@ -832,11 +820,11 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
 
     // Broadcasters (if exist) should NOT be swapped.
 
-    CellPosType aPos1 = maCells.position(nRow1);
+    sc::CellStoreType::position_type aPos1 = maCells.position(nRow1);
     if (aPos1.first == maCells.end())
         return;
 
-    CellPosType aPos2 = maCells.position(aPos1.first, nRow2);
+    sc::CellStoreType::position_type aPos2 = maCells.position(aPos1.first, nRow2);
     if (aPos2.first == maCells.end())
         return;
 
@@ -881,13 +869,15 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
                 // TODO: Find out a way to adjust references without cloning new instances.
                 boost::scoped_ptr<ScFormulaCell> pOld1(*itf1);
                 boost::scoped_ptr<ScFormulaCell> pOld2(*itf2);
+                DetouchFormulaCell(aPos1, **itf1);
+                DetouchFormulaCell(aPos2, **itf2);
                 ScFormulaCell* pNew1 = cloneFormulaCell(pDocument, ScAddress(nCol, nRow1, nTab), *pOld2);
                 ScFormulaCell* pNew2 = cloneFormulaCell(pDocument, ScAddress(nCol, nRow2, nTab), *pOld1);
                 *itf1 = pNew1;
                 *itf2 = pNew2;
 
-                RegroupFormulaCells(nRow1);
-                RegroupFormulaCells(nRow2);
+                ActivateNewFormulaCell(aPos1, *pNew1);
+                ActivateNewFormulaCell(aPos2, *pNew2);
             }
             break;
             default:
@@ -902,10 +892,10 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
 
     // The two cells are of different types.
 
-    sc::CellStoreType::const_iterator cit = it1;
-    ScRefCellValue aCell1 = GetCellValue(cit, nRow1);
-    cit = it2;
-    ScRefCellValue aCell2 = GetCellValue(cit, nRow2);
+    ScRefCellValue aCell1 = GetCellValue(aPos1.first, aPos1.second);
+    ScRefCellValue aCell2 = GetCellValue(aPos2.first, aPos2.second);
+
+    // Make sure to put cells in row 1 first then row 2!
 
     if (aCell1.meType == CELLTYPE_NONE)
     {
@@ -929,11 +919,12 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
             break;
             case CELLTYPE_FORMULA:
             {
+                // cell 1 is empty and cell 2 is a formula cell.
                 ScFormulaCell* pNew = cloneFormulaCell(pDocument, ScAddress(nCol, nRow1, nTab), *aCell2.mpFormula);
+                DetouchFormulaCell(aPos2, *aCell2.mpFormula);
                 it1 = maCells.set(it1, nRow1, pNew);
                 maCells.set_empty(it1, nRow2, nRow2); // original formula cell gets deleted.
-
-                RegroupFormulaCells(nRow2);
+                ActivateNewFormulaCell(it1, nRow1, *pNew);
             }
             break;
             default:
@@ -972,12 +963,12 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
             break;
             case CELLTYPE_FORMULA:
             {
+                // cell 1 is a formula cell and cell 2 is empty.
                 ScFormulaCell* pNew = cloneFormulaCell(pDocument, ScAddress(nCol, nRow2, nTab), *aCell1.mpFormula);
+                DetouchFormulaCell(aPos1, *aCell1.mpFormula);
                 it1 = maCells.set_empty(it1, nRow1, nRow1); // original formula cell is gone.
-                maCells.set(it1, nRow2, pNew);
-
-                RegroupFormulaCells(nRow1);
-                RegroupFormulaCells(nRow2);
+                it1 = maCells.set(it1, nRow2, pNew);
+                ActivateNewFormulaCell(it1, nRow2, *pNew);
             }
             break;
             default:
@@ -1009,8 +1000,10 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
                 break;
                 case CELLTYPE_FORMULA:
                 {
+                    DetouchFormulaCell(aPos2, *aCell2.mpFormula);
                     ScFormulaCell* pNew = cloneFormulaCell(pDocument, ScAddress(nCol, nRow1, nTab), *aCell2.mpFormula);
                     it1 = maCells.set(it1, nRow1, pNew);
+                    ActivateNewFormulaCell(it1, nRow1, *pNew);
                     // The old formula cell will get overwritten below.
                 }
                 break;
@@ -1040,8 +1033,10 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
                 case CELLTYPE_FORMULA:
                 {
                     // cell 1 - string, cell 2 - formula
+                    DetouchFormulaCell(aPos2, *aCell2.mpFormula);
                     ScFormulaCell* pNew = cloneFormulaCell(pDocument, ScAddress(nCol, nRow1, nTab), *aCell2.mpFormula);
                     it1 = maCells.set(it1, nRow1, pNew);
+                    ActivateNewFormulaCell(it1, nRow1, *pNew);
                     // Old formula cell will get overwritten below.
                 }
                 break;
@@ -1067,8 +1062,10 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
                 break;
                 case CELLTYPE_FORMULA:
                 {
+                    DetouchFormulaCell(aPos2, *aCell2.mpFormula);
                     ScFormulaCell* pNew = cloneFormulaCell(pDocument, ScAddress(nCol, nRow1, nTab), *aCell2.mpFormula);
                     it1 = maCells.set(it1, nRow1, pNew);
+                    ActivateNewFormulaCell(it1, nRow1, *pNew);
                     // Old formula cell will get overwritten below.
                 }
                 break;
@@ -1081,6 +1078,8 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
         break;
         case CELLTYPE_FORMULA:
         {
+            // cell 1 is a formula cell and cell 2 is not.
+            DetouchFormulaCell(aPos1, *aCell1.mpFormula);
             ScFormulaCell* pNew = cloneFormulaCell(pDocument, ScAddress(nCol, nRow2, nTab), *aCell1.mpFormula);
             switch (aCell2.meType)
             {
@@ -1101,7 +1100,8 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
                     ;
             }
 
-            maCells.set(it1, nRow2, pNew);
+            it1 = maCells.set(it1, nRow2, pNew);
+            ActivateNewFormulaCell(it1, nRow2, *pNew);
         }
         break;
         default:
@@ -1109,8 +1109,6 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
     }
 
     SwapCellTextAttrs(nRow1, nRow2);
-    RegroupFormulaCells(nRow1);
-    RegroupFormulaCells(nRow2);
     CellStorageModified();
     BroadcastCells(aRows);
 }
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index b106ed6..bfb5590 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -398,6 +398,17 @@ void ScColumn::JoinNewFormulaCell(
     }
 }
 
+void ScColumn::DetouchFormulaCell(
+    const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const
+{
+    if (!pDocument->IsClipOrUndo())
+        // Have the dying formula cell stop listening.
+        rCell.EndListeningTo(pDocument);
+
+    if (rCell.IsShared())
+        UnshareFormulaCell(aPos, rCell);
+}
+
 void ScColumn::UnshareFormulaCell(
     const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const
 {
@@ -498,12 +509,7 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreTy
     if (itRet->type == sc::element_type_formula)
     {
         ScFormulaCell& rCell = *sc::formula_block::at(*itRet->data, aPos.second);
-        if (!pDocument->IsClipOrUndo())
-            // Have the dying formula cell stop listening.
-            rCell.EndListeningTo(pDocument);
-
-        if (rCell.IsShared())
-            UnshareFormulaCell(aPos, rCell);
+        DetouchFormulaCell(aPos, rCell);
     }
 
     return itRet;
@@ -512,9 +518,13 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreTy
 void ScColumn::ActivateNewFormulaCell(
     const sc::CellStoreType::iterator& itPos, SCROW nRow, ScFormulaCell& rCell )
 {
-    // See if this new formula cell can join an existing shared formula group.
-    sc::CellStoreType::position_type aPos = maCells.position(itPos, nRow);
+    ActivateNewFormulaCell(maCells.position(itPos, nRow), rCell);
+}
 
+void ScColumn::ActivateNewFormulaCell(
+    const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell )
+{
+    // See if this new formula cell can join an existing shared formula group.
     JoinNewFormulaCell(aPos, rCell);
 
     // When we insert from the Clipboard we still have wrong (old) References!
commit 85ce60d4c43d35b9673ed22f4a4adaa4928349be
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Jun 26 18:06:04 2013 -0400

    Make this a member method too.
    
    Change-Id: Ib1b16ce5a7a36560b04d4d57b585fdcf2a2b294d

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index d691e49..a9aae2c 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -466,6 +466,8 @@ public:
 
     void InterpretDirtyCells( SCROW nRow1, SCROW nRow2 );
 
+    void JoinNewFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const;
+
     void UnshareFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const;
 
     /**
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index b9d1309..b106ed6 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -327,6 +327,77 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( SCROW nRow )
     return GetPositionToInsert(maCells.begin(), nRow);
 }
 
+namespace {
+
+void joinFormulaCells(SCROW nRow, ScFormulaCell& rCell1, ScFormulaCell& rCell2)
+{
+    ScFormulaCell::CompareState eState = rCell1.CompareByTokenArray(rCell2);
+    if (eState == ScFormulaCell::NotEqual)
+        return;
+
+    // Formula tokens equal those of the previous formula cell.
+    ScFormulaCellGroupRef xGroup1 = rCell1.GetCellGroup();
+    ScFormulaCellGroupRef xGroup2 = rCell2.GetCellGroup();
+    if (xGroup1)
+    {
+        if (xGroup2)
+        {
+            // Both cell1 and cell2 are shared. Merge them together.
+            xGroup1->mnLength += xGroup2->mnLength;
+            rCell2.SetCellGroup(xGroup1);
+        }
+        else
+        {
+            // cell1 is shared but cell2 is not.
+            rCell2.SetCellGroup(xGroup1);
+            ++xGroup1->mnLength;
+        }
+    }
+    else
+    {
+        if (xGroup2)
+        {
+            // cell1 is not shared, but cell2 is already shared.
+            rCell1.SetCellGroup(xGroup2);
+            xGroup2->mnStart = nRow;
+            ++xGroup2->mnLength;
+        }
+        else
+        {
+            // neither cells are shared.
+            xGroup1.reset(new ScFormulaCellGroup);
+            xGroup1->mnStart = nRow;
+            xGroup1->mbInvariant = (eState == ScFormulaCell::EqualInvariant);
+            xGroup1->mnLength = 2;
+
+            rCell1.SetCellGroup(xGroup1);
+            rCell2.SetCellGroup(xGroup1);
+        }
+    }
+}
+
+}
+
+void ScColumn::JoinNewFormulaCell(
+    const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const
+{
+    SCROW nRow = aPos.first->position + aPos.second;
+
+    // Check the previous row position for possible grouping.
+    if (aPos.first->type == sc::element_type_formula && aPos.second > 0)
+    {
+        ScFormulaCell& rPrev = *sc::formula_block::at(*aPos.first->data, aPos.second-1);
+        joinFormulaCells(nRow-1, rPrev, rCell);
+    }
+
+    // Check the next row position for possible grouping.
+    if (aPos.first->type == sc::element_type_formula && aPos.second+1 < aPos.first->size)
+    {
+        ScFormulaCell& rNext = *sc::formula_block::at(*aPos.first->data, aPos.second+1);
+        joinFormulaCells(nRow, rCell, rNext);
+    }
+}
+
 void ScColumn::UnshareFormulaCell(
     const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const
 {
@@ -438,76 +509,13 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreTy
     return itRet;
 }
 
-namespace {
-
-void joinFormulaCells(SCROW nRow, ScFormulaCell& rCell1, ScFormulaCell& rCell2)
-{
-    ScFormulaCell::CompareState eState = rCell1.CompareByTokenArray(rCell2);
-    if (eState == ScFormulaCell::NotEqual)
-        return;
-
-    // Formula tokens equal those of the previous formula cell.
-    ScFormulaCellGroupRef xGroup1 = rCell1.GetCellGroup();
-    ScFormulaCellGroupRef xGroup2 = rCell2.GetCellGroup();
-    if (xGroup1)
-    {
-        if (xGroup2)
-        {
-            // Both cell1 and cell2 are shared. Merge them together.
-            xGroup1->mnLength += xGroup2->mnLength;
-            rCell2.SetCellGroup(xGroup1);
-        }
-        else
-        {
-            // cell1 is shared but cell2 is not.
-            rCell2.SetCellGroup(xGroup1);
-            ++xGroup1->mnLength;
-        }
-    }
-    else
-    {
-        if (xGroup2)
-        {
-            // cell1 is not shared, but cell2 is already shared.
-            rCell1.SetCellGroup(xGroup2);
-            xGroup2->mnStart = nRow;
-            ++xGroup2->mnLength;
-        }
-        else
-        {
-            // neither cells are shared.
-            xGroup1.reset(new ScFormulaCellGroup);
-            xGroup1->mnStart = nRow;
-            xGroup1->mbInvariant = (eState == ScFormulaCell::EqualInvariant);
-            xGroup1->mnLength = 2;
-
-            rCell1.SetCellGroup(xGroup1);
-            rCell2.SetCellGroup(xGroup1);
-        }
-    }
-}
-
-}
-
 void ScColumn::ActivateNewFormulaCell(
     const sc::CellStoreType::iterator& itPos, SCROW nRow, ScFormulaCell& rCell )
 {
     // See if this new formula cell can join an existing shared formula group.
     sc::CellStoreType::position_type aPos = maCells.position(itPos, nRow);
 
-    // Check the previous row position for possible grouping.
-    if (aPos.first->type == sc::element_type_formula && aPos.second > 0)
-    {
-        ScFormulaCell& rPrev = *sc::formula_block::at(*aPos.first->data, aPos.second-1);
-        joinFormulaCells(nRow-1, rPrev, rCell);
-    }
-
-    // Check the next row position for possible grouping.
-    if (aPos.first->type == sc::element_type_formula && aPos.second+1 < aPos.first->size)
-    {
-        ScFormulaCell& rNext = *sc::formula_block::at(*aPos.first->data, aPos.second+1);
-        joinFormulaCells(nRow, rCell, rNext);
-    }
+    JoinNewFormulaCell(aPos, rCell);
 
     // When we insert from the Clipboard we still have wrong (old) References!
     // First they are rewired in CopyBlockFromClip via UpdateReference and the
commit a37a2c3b28b51abf1c54c49efd03329f8b3cc1ae
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Jun 26 17:57:34 2013 -0400

    Make this a member method of ScColumn.
    
    Change-Id: I5d0a573d277338ddef60fdd58bfb1f5ba7fc695e

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 44946c4..d691e49 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -466,6 +466,8 @@ public:
 
     void InterpretDirtyCells( SCROW nRow1, SCROW nRow2 );
 
+    void UnshareFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const;
+
     /**
      * Regroup formula cells for the entire column.
      */
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 216b318..b9d1309 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -327,13 +327,13 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( SCROW nRow )
     return GetPositionToInsert(maCells.begin(), nRow);
 }
 
-namespace {
-
-/**
- * Re-group a shared formula cell that's being overwritten.
- */
-void adjustSharedFormulaCell(const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell)
+void ScColumn::UnshareFormulaCell(
+    const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const
 {
+    if (!rCell.IsShared())
+        return;
+
+    ScFormulaCellGroupRef xNone;
     sc::CellStoreType::iterator it = aPos.first;
 
     // This formula cell is shared. Adjust the shared group.
@@ -352,7 +352,6 @@ void adjustSharedFormulaCell(const sc::CellStoreType::position_type& aPos, ScFor
                 abort();
             }
 #endif
-            ScFormulaCellGroupRef xNone;
             ScFormulaCell& rNext = *sc::formula_block::at(*it->data, aPos.second+1);
             rNext.SetCellGroup(xNone);
         }
@@ -378,7 +377,6 @@ void adjustSharedFormulaCell(const sc::CellStoreType::position_type& aPos, ScFor
                 abort();
             }
 #endif
-            ScFormulaCellGroupRef xNone;
             ScFormulaCell& rPrev = *sc::formula_block::at(*it->data, aPos.second-1);
             rPrev.SetCellGroup(xNone);
         }
@@ -417,8 +415,8 @@ void adjustSharedFormulaCell(const sc::CellStoreType::position_type& aPos, ScFor
             rCell2.SetCellGroup(xGroup2);
         }
     }
-}
 
+    rCell.SetCellGroup(xNone);
 }
 
 sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreType::iterator& it, SCROW nRow )
@@ -434,7 +432,7 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreTy
             rCell.EndListeningTo(pDocument);
 
         if (rCell.IsShared())
-            adjustSharedFormulaCell(aPos, rCell);
+            UnshareFormulaCell(aPos, rCell);
     }
 
     return itRet;
commit 2b300a9e90f40f8b890d6de522aa1ea8e7c0d74a
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Jun 26 17:43:18 2013 -0400

    We don't need this formula group vector.
    
    Change-Id: I96f3b19a5bb0d761b7abd943df6a2e48cfcbf9bd

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 322d7a6..44946c4 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -110,8 +110,6 @@ class ScColumn
     SCCOL           nCol;
     SCTAB           nTab;
 
-    std::vector<ScFormulaCellGroupRef> maFnGroups;
-
     ScAttrArray*          pAttrArray;
     ScDocument*           pDocument;
     bool mbDirtyGroups;     /// formula groups are dirty.
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 6cb19db..216b318 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -2713,11 +2713,9 @@ public:
 
 class GroupFormulaCells
 {
-    std::vector<ScFormulaCellGroupRef>& mrFnGroups;
     ScFormulaCellGroupRef mxNone;
 
 public:
-    GroupFormulaCells(std::vector<ScFormulaCellGroupRef>& rFnGroups) : mrFnGroups(rFnGroups) {}
 
     void operator() (sc::CellStoreType::value_type& node)
     {
@@ -2755,8 +2753,6 @@ public:
                 xGroup->mbInvariant = (eCompState == ScFormulaCell::EqualInvariant);
                 xGroup->mnLength = 2;
 
-                mrFnGroups.push_back(xGroup);
-
                 pCur->SetCellGroup(xGroup);
                 pPrev->SetCellGroup(xGroup);
             }
@@ -2783,10 +2779,9 @@ void ScColumn::RebuildFormulaGroups()
     ScFormulaCellGroupRef xNone;
     CellGroupSetter aFunc(xNone);
     sc::ProcessFormula(maCells, aFunc);
-    maFnGroups.clear();
 
     // re-build formula groups.
-    std::for_each(maCells.begin(), maCells.end(), GroupFormulaCells(maFnGroups));
+    std::for_each(maCells.begin(), maCells.end(), GroupFormulaCells());
 
     mbDirtyGroups = false;
 }
commit 58d309f141621840047d5ee587a0adc8017289bf
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Jun 26 17:37:23 2013 -0400

    Extract this code block into an own function.
    
    Change-Id: I6abe520ad6392e4f9163434b73f3b3ab88a71297

diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index cc422bc..6cb19db 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -327,103 +327,115 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( SCROW nRow )
     return GetPositionToInsert(maCells.begin(), nRow);
 }
 
-sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreType::iterator& it, SCROW nRow )
+namespace {
+
+/**
+ * Re-group a shared formula cell that's being overwritten.
+ */
+void adjustSharedFormulaCell(const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell)
 {
-    // See if we are overwriting an existing formula cell.
-    sc::CellStoreType::position_type aRet = maCells.position(it, nRow);
-    sc::CellStoreType::iterator itRet = aRet.first;
-    if (itRet->type == sc::element_type_formula)
-    {
-        ScFormulaCell& rCell = *sc::formula_block::at(*itRet->data, aRet.second);
-        if (!pDocument->IsClipOrUndo())
-            // Have the dying formula cell stop listening.
-            rCell.EndListeningTo(pDocument);
+    sc::CellStoreType::iterator it = aPos.first;
 
-        if (rCell.IsShared())
+    // This formula cell is shared. Adjust the shared group.
+    if (rCell.aPos.Row() == rCell.GetSharedTopRow())
+    {
+        // Top of the shared range.
+        ScFormulaCellGroupRef xGroup = rCell.GetCellGroup();
+        if (xGroup->mnLength == 2)
         {
-            // This formula cell is shared. Adjust the shared group.
-            if (rCell.aPos.Row() == rCell.GetSharedTopRow())
-            {
-                // Top of the shared range.
-                ScFormulaCellGroupRef xGroup = rCell.GetCellGroup();
-                if (xGroup->mnLength == 2)
-                {
-                    // Group consists only only two cells. Mark the second one non-shared.
+            // Group consists only only two cells. Mark the second one non-shared.
 #if DEBUG_COLUMN_STORAGE
-                    if (aRet.second+1 >= aRet.first->size)
-                    {
-                        cerr << "ScColumn::GetPositionToInsert: There is no next formula cell but there should be!" << endl;
-                        cerr.flush();
-                        abort();
-                    }
-#endif
-                    ScFormulaCellGroupRef xNone;
-                    ScFormulaCell& rNext = *sc::formula_block::at(*itRet->data, aRet.second+1);
-                    rNext.SetCellGroup(xNone);
-                }
-                else
-                {
-                    // Move the top cell to the next formula cell down.
-                    --xGroup->mnLength;
-                    ++xGroup->mnStart;
-                }
-            }
-            else if (rCell.aPos.Row() == rCell.GetSharedTopRow() + rCell.GetSharedLength() - 1)
+            if (aPos.second+1 >= aPos.first->size)
             {
-                // Bottom of the shared range.
-                ScFormulaCellGroupRef xGroup = rCell.GetCellGroup();
-                if (xGroup->mnLength == 2)
-                {
-                    // Mark the top cell non-shared.
-#if DEBUG_COLUMN_STORAGE
-                    if (aRet.second == 0)
-                    {
-                        cerr << "ScColumn::GetPositionToInsert: There is no previous formula cell but there should be!" << endl;
-                        cerr.flush();
-                        abort();
-                    }
-#endif
-                    ScFormulaCellGroupRef xNone;
-                    ScFormulaCell& rPrev = *sc::formula_block::at(*itRet->data, aRet.second-1);
-                    rPrev.SetCellGroup(xNone);
-                }
-                else
-                {
-                    // Just shortern the shared range length by one.
-                    --xGroup->mnLength;
-                }
+                cerr << "ScColumn::GetPositionToInsert: There is no next formula cell but there should be!" << endl;
+                cerr.flush();
+                abort();
             }
-            else
+#endif
+            ScFormulaCellGroupRef xNone;
+            ScFormulaCell& rNext = *sc::formula_block::at(*it->data, aPos.second+1);
+            rNext.SetCellGroup(xNone);
+        }
+        else
+        {
+            // Move the top cell to the next formula cell down.
+            --xGroup->mnLength;
+            ++xGroup->mnStart;
+        }
+    }
+    else if (rCell.aPos.Row() == rCell.GetSharedTopRow() + rCell.GetSharedLength() - 1)
+    {
+        // Bottom of the shared range.
+        ScFormulaCellGroupRef xGroup = rCell.GetCellGroup();
+        if (xGroup->mnLength == 2)
+        {
+            // Mark the top cell non-shared.
+#if DEBUG_COLUMN_STORAGE
+            if (aPos.second == 0)
             {
-                // In the middle of the shared range. Split it into two groups.
-                ScFormulaCellGroupRef xGroup = rCell.GetCellGroup();
-                SCROW nEndRow = xGroup->mnStart + xGroup->mnLength - 1;
-                xGroup->mnLength = rCell.aPos.Row() - xGroup->mnStart; // Shorten the top group.
-
-                ScFormulaCellGroupRef xGroup2(new ScFormulaCellGroup);
-                xGroup2->mnStart = rCell.aPos.Row() + 1;
-                xGroup2->mnLength = nEndRow - rCell.aPos.Row();
-                xGroup2->mbInvariant = xGroup->mbInvariant;
+                cerr << "ScColumn::GetPositionToInsert: There is no previous formula cell but there should be!" << endl;
+                cerr.flush();
+                abort();
+            }
+#endif
+            ScFormulaCellGroupRef xNone;
+            ScFormulaCell& rPrev = *sc::formula_block::at(*it->data, aPos.second-1);
+            rPrev.SetCellGroup(xNone);
+        }
+        else
+        {
+            // Just shortern the shared range length by one.
+            --xGroup->mnLength;
+        }
+    }
+    else
+    {
+        // In the middle of the shared range. Split it into two groups.
+        ScFormulaCellGroupRef xGroup = rCell.GetCellGroup();
+        SCROW nEndRow = xGroup->mnStart + xGroup->mnLength - 1;
+        xGroup->mnLength = rCell.aPos.Row() - xGroup->mnStart; // Shorten the top group.
+
+        ScFormulaCellGroupRef xGroup2(new ScFormulaCellGroup);
+        xGroup2->mnStart = rCell.aPos.Row() + 1;
+        xGroup2->mnLength = nEndRow - rCell.aPos.Row();
+        xGroup2->mbInvariant = xGroup->mbInvariant;
 #if DEBUG_COLUMN_STORAGE
-                if (xGroup2->mnStart + xGroup2->mnLength > itRet->position + itRet->size)
-                {
-                    cerr << "ScColumn::GetPositionToInsert: Shared formula region goes beyond the formula block. Not good." << endl;
-                    cerr.flush();
-                    abort();
-                }
+        if (xGroup2->mnStart + xGroup2->mnLength > it->position + it->size)
+        {
+            cerr << "ScColumn::GetPositionToInsert: Shared formula region goes beyond the formula block. Not good." << endl;
+            cerr.flush();
+            abort();
+        }
 #endif
-                sc::formula_block::iterator itCell = sc::formula_block::begin(*itRet->data);
-                std::advance(itCell, aRet.second+1);
-                sc::formula_block::iterator itCellEnd = itCell;
-                std::advance(itCellEnd, xGroup2->mnLength);
-                for (; itCell != itCellEnd; ++itCell)
-                {
-                    ScFormulaCell& rCell2 = **itCell;
-                    rCell2.SetCellGroup(xGroup2);
-                }
-            }
+        sc::formula_block::iterator itCell = sc::formula_block::begin(*it->data);
+        std::advance(itCell, aPos.second+1);
+        sc::formula_block::iterator itCellEnd = itCell;
+        std::advance(itCellEnd, xGroup2->mnLength);
+        for (; itCell != itCellEnd; ++itCell)
+        {
+            ScFormulaCell& rCell2 = **itCell;
+            rCell2.SetCellGroup(xGroup2);
         }
     }
+}
+
+}
+
+sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreType::iterator& it, SCROW nRow )
+{
+    // See if we are overwriting an existing formula cell.
+    sc::CellStoreType::position_type aPos = maCells.position(it, nRow);
+    sc::CellStoreType::iterator itRet = aPos.first;
+    if (itRet->type == sc::element_type_formula)
+    {
+        ScFormulaCell& rCell = *sc::formula_block::at(*itRet->data, aPos.second);
+        if (!pDocument->IsClipOrUndo())
+            // Have the dying formula cell stop listening.
+            rCell.EndListeningTo(pDocument);
+
+        if (rCell.IsShared())
+            adjustSharedFormulaCell(aPos, rCell);
+    }
 
     return itRet;
 }
commit 13822d7a7a9c30248f4f58d4768a6b2acddade2e
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Jun 26 15:56:46 2013 -0400

    Don't forget to transfer this too when splitting group.
    
    Change-Id: I3337504f6b95f273106e809da90d089cd76d8bdb

diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index c66e9d5e..cc422bc 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -403,6 +403,7 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreTy
                 ScFormulaCellGroupRef xGroup2(new ScFormulaCellGroup);
                 xGroup2->mnStart = rCell.aPos.Row() + 1;
                 xGroup2->mnLength = nEndRow - rCell.aPos.Row();
+                xGroup2->mbInvariant = xGroup->mbInvariant;
 #if DEBUG_COLUMN_STORAGE
                 if (xGroup2->mnStart + xGroup2->mnLength > itRet->position + itRet->size)
                 {

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list