sc/inc/column.hxx               |    5 +--
 sc/source/core/data/column3.cxx |   66 +++++++++++++++++++++++++++++++---------
 2 files changed, 55 insertions(+), 16 deletions(-)

New commits:
commit e7d0785a7d2a07e64dc58dee4f1b072a72e32aa5
Author:     Dennis Francis <dennis.fran...@collabora.com>
AuthorDate: Tue Mar 26 16:50:44 2019 +0530
Commit:     Eike Rathke <er...@redhat.com>
CommitDate: Thu Mar 28 22:43:28 2019 +0100

    tdf#120660: Populate rNewSharedRows even if no FC...
    
    at specified position. At least in case of ScUndoPaste, during
    undo operation, the content from changed area in main-document
    is removed before actual undo-paste, so when cloned formula-cell
    from undo-doc is inserted to main-doc, there is no "old" cell
    to detach, so "rNewSharedRows" is not populated which is needed
    for proper re-establishment of listeners if there are formula/
    formula-groups adjacent to insertion position.
    
    Change-Id: Id2bfb65a2a7a5abb03effbdcc4405015fddc401c
    Next: fix the vector version of this case and write unit tests.
    Reviewed-on: https://gerrit.libreoffice.org/69737
    Tested-by: Jenkins
    Reviewed-by: Eike Rathke <er...@redhat.com>

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 15eb10b70238..b836fabef770 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -702,9 +702,10 @@ public:
     bool        ReservePatternCount( SCSIZE nReserve );
 private:
 
-    sc::CellStoreType::iterator GetPositionToInsert( SCROW nRow, 
std::vector<SCROW>& rNewSharedRows );
+    sc::CellStoreType::iterator GetPositionToInsert( SCROW nRow, 
std::vector<SCROW>& rNewSharedRows,
+                                                     bool bInsertFormula );
     sc::CellStoreType::iterator GetPositionToInsert( const 
sc::CellStoreType::iterator& it, SCROW nRow,
-                                                     std::vector<SCROW>& 
rNewSharedRows );
+                                                     std::vector<SCROW>& 
rNewSharedRows, bool bInsertFormula );
 
     void AttachNewFormulaCell(
         const sc::CellStoreType::iterator& itPos, SCROW nRow, ScFormulaCell& 
rCell,
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 14c1c1424237..8e728cbe2916 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -256,9 +256,10 @@ void ScColumn::DeleteRow( SCROW nStartRow, SCSIZE nSize, 
std::vector<ScAddress>*
     CellStorageModified();
 }
 
-sc::CellStoreType::iterator ScColumn::GetPositionToInsert( SCROW nRow, 
std::vector<SCROW>& rNewSharedRows )
+sc::CellStoreType::iterator ScColumn::GetPositionToInsert( SCROW nRow, 
std::vector<SCROW>& rNewSharedRows,
+        bool bInsertFormula )
 {
-    return GetPositionToInsert(maCells.begin(), nRow, rNewSharedRows);
+    return GetPositionToInsert(maCells.begin(), nRow, rNewSharedRows, 
bInsertFormula);
 }
 
 void ScColumn::JoinNewFormulaCell(
@@ -534,17 +535,54 @@ void ScColumn::DetachFormulaCells( 
sc::EndListeningContext& rCxt, SCROW nRow1, S
     sc::ProcessFormula(it, maCells, nRow1, nRow2, aFunc);
 }
 
-sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const 
sc::CellStoreType::iterator& it, SCROW nRow,
+static void lcl_AddFormulaGroupBoundaries(const 
sc::CellStoreType::position_type& rPos,
         std::vector<SCROW>& rNewSharedRows )
 {
+    sc::CellStoreType::iterator itRet = rPos.first;
+    if (itRet->type != sc::element_type_formula)
+        return;
+
+    ScFormulaCell& rFC = *sc::formula_block::at(*itRet->data, rPos.second);
+    if ( rFC.IsShared() )
+    {
+        const SCROW nSharedTopRow = rFC.GetSharedTopRow();
+        const SCROW nSharedLength = rFC.GetSharedLength();
+        rNewSharedRows.push_back( nSharedTopRow);
+        rNewSharedRows.push_back( nSharedTopRow + nSharedLength - 1);
+    }
+    else
+    {
+        const SCROW nRow = rFC.aPos.Row();
+        rNewSharedRows.push_back( nRow);
+        rNewSharedRows.push_back( nRow);
+    }
+}
+
+sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const 
sc::CellStoreType::iterator& it, SCROW nRow,
+        std::vector<SCROW>& rNewSharedRows, bool bInsertFormula )
+{
     // 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);
         DetachFormulaCell(aPos, rCell, rNewSharedRows);
     }
+    else if (bInsertFormula && !GetDoc()->IsClipOrUndo())
+    {
+        if (nRow > 0)
+        {
+            sc::CellStoreType::position_type aPosBefore = 
maCells.position(maCells.begin(), nRow-1);
+            lcl_AddFormulaGroupBoundaries(aPosBefore, rNewSharedRows);
+        }
+        if (nRow < MAXROW)
+        {
+            sc::CellStoreType::position_type aPosAfter = 
maCells.position(maCells.begin(), nRow+1);
+            lcl_AddFormulaGroupBoundaries(aPosAfter, rNewSharedRows);
+        }
+    }
 
     return itRet;
 }
@@ -2085,7 +2123,7 @@ void ScColumn::SetEditText( SCROW nRow, 
std::unique_ptr<EditTextObject> pEditTex
 {
     pEditText->NormalizeString(GetDoc()->GetSharedStringPool());
     std::vector<SCROW> aNewSharedRows;
-    sc::CellStoreType::iterator it = GetPositionToInsert(nRow, aNewSharedRows);
+    sc::CellStoreType::iterator it = GetPositionToInsert(nRow, aNewSharedRows, 
false);
     maCells.set(it, nRow, pEditText.release());
     maCellTextAttrs.set(nRow, sc::CellTextAttr());
     CellStorageModified();
@@ -2099,7 +2137,7 @@ void ScColumn::SetEditText( sc::ColumnBlockPosition& 
rBlockPos, SCROW nRow, std:
 {
     pEditText->NormalizeString(GetDoc()->GetSharedStringPool());
     std::vector<SCROW> aNewSharedRows;
-    rBlockPos.miCellPos = GetPositionToInsert(rBlockPos.miCellPos, nRow, 
aNewSharedRows);
+    rBlockPos.miCellPos = GetPositionToInsert(rBlockPos.miCellPos, nRow, 
aNewSharedRows, false);
     rBlockPos.miCellPos = maCells.set(rBlockPos.miCellPos, nRow, 
pEditText.release());
     rBlockPos.miCellTextAttrPos = maCellTextAttrs.set(
         rBlockPos.miCellTextAttrPos, nRow, sc::CellTextAttr());
@@ -2148,7 +2186,7 @@ void ScColumn::SetFormula( SCROW nRow, const 
ScTokenArray& rArray, formula::Form
     ScAddress aPos(nCol, nRow, nTab);
 
     std::vector<SCROW> aNewSharedRows;
-    sc::CellStoreType::iterator it = GetPositionToInsert(nRow, aNewSharedRows);
+    sc::CellStoreType::iterator it = GetPositionToInsert(nRow, aNewSharedRows, 
true);
     ScFormulaCell* pCell = new ScFormulaCell(GetDoc(), aPos, rArray, eGram);
     sal_uInt32 nCellFormat = 
GetNumberFormat(GetDoc()->GetNonThreadedContext(), nRow);
     if( (nCellFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0)
@@ -2166,7 +2204,7 @@ void ScColumn::SetFormula( SCROW nRow, const OUString& 
rFormula, formula::Formul
     ScAddress aPos(nCol, nRow, nTab);
 
     std::vector<SCROW> aNewSharedRows;
-    sc::CellStoreType::iterator it = GetPositionToInsert(nRow, aNewSharedRows);
+    sc::CellStoreType::iterator it = GetPositionToInsert(nRow, aNewSharedRows, 
true);
     ScFormulaCell* pCell = new ScFormulaCell(GetDoc(), aPos, rFormula, eGram);
     sal_uInt32 nCellFormat = 
GetNumberFormat(GetDoc()->GetNonThreadedContext(), nRow);
     if( (nCellFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0)
@@ -2184,7 +2222,7 @@ ScFormulaCell* ScColumn::SetFormulaCell(
     bool bInheritNumFormatIfNeeded )
 {
     std::vector<SCROW> aNewSharedRows;
-    sc::CellStoreType::iterator it = GetPositionToInsert(nRow, aNewSharedRows);
+    sc::CellStoreType::iterator it = GetPositionToInsert(nRow, aNewSharedRows, 
true);
     sal_uInt32 nCellFormat = 
GetNumberFormat(GetDoc()->GetNonThreadedContext(), nRow);
     if( (nCellFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0 && 
bInheritNumFormatIfNeeded )
         pCell->SetNeedNumberFormat(true);
@@ -2204,7 +2242,7 @@ void ScColumn::SetFormulaCell(
     bool bInheritNumFormatIfNeeded )
 {
     std::vector<SCROW> aNewSharedRows;
-    rBlockPos.miCellPos = GetPositionToInsert(rBlockPos.miCellPos, nRow, 
aNewSharedRows);
+    rBlockPos.miCellPos = GetPositionToInsert(rBlockPos.miCellPos, nRow, 
aNewSharedRows, true);
     sal_uInt32 nCellFormat = 
GetNumberFormat(GetDoc()->GetNonThreadedContext(), nRow);
     if( (nCellFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0 && 
bInheritNumFormatIfNeeded )
         pCell->SetNeedNumberFormat(true);
@@ -2689,7 +2727,7 @@ void ScColumn::SetError( SCROW nRow, const FormulaError 
nError)
     pCell->SetErrCode(nError);
 
     std::vector<SCROW> aNewSharedRows;
-    sc::CellStoreType::iterator it = GetPositionToInsert(nRow, aNewSharedRows);
+    sc::CellStoreType::iterator it = GetPositionToInsert(nRow, aNewSharedRows, 
true);
     it = maCells.set(it, nRow, pCell);
     maCellTextAttrs.set(nRow, sc::CellTextAttr());
 
@@ -2716,7 +2754,7 @@ void ScColumn::SetRawString( SCROW nRow, const 
svl::SharedString& rStr )
         return;
 
     std::vector<SCROW> aNewSharedRows;
-    sc::CellStoreType::iterator it = GetPositionToInsert(nRow, aNewSharedRows);
+    sc::CellStoreType::iterator it = GetPositionToInsert(nRow, aNewSharedRows, 
false);
     maCells.set(it, nRow, rStr);
     maCellTextAttrs.set(nRow, sc::CellTextAttr());
 
@@ -2734,7 +2772,7 @@ void ScColumn::SetRawString(
         return;
 
     std::vector<SCROW> aNewSharedRows;
-    rBlockPos.miCellPos = GetPositionToInsert(rBlockPos.miCellPos, nRow, 
aNewSharedRows);
+    rBlockPos.miCellPos = GetPositionToInsert(rBlockPos.miCellPos, nRow, 
aNewSharedRows, false);
     rBlockPos.miCellPos = maCells.set(rBlockPos.miCellPos, nRow, rStr);
     rBlockPos.miCellTextAttrPos = maCellTextAttrs.set(
         rBlockPos.miCellTextAttrPos, nRow, sc::CellTextAttr());
@@ -2753,7 +2791,7 @@ void ScColumn::SetValue( SCROW nRow, double fVal )
         return;
 
     std::vector<SCROW> aNewSharedRows;
-    sc::CellStoreType::iterator it = GetPositionToInsert(nRow, aNewSharedRows);
+    sc::CellStoreType::iterator it = GetPositionToInsert(nRow, aNewSharedRows, 
false);
     maCells.set(it, nRow, fVal);
     maCellTextAttrs.set(nRow, sc::CellTextAttr());
 
@@ -2771,7 +2809,7 @@ void ScColumn::SetValue(
         return;
 
     std::vector<SCROW> aNewSharedRows;
-    rBlockPos.miCellPos = GetPositionToInsert(rBlockPos.miCellPos, nRow, 
aNewSharedRows);
+    rBlockPos.miCellPos = GetPositionToInsert(rBlockPos.miCellPos, nRow, 
aNewSharedRows, false);
     rBlockPos.miCellPos = maCells.set(rBlockPos.miCellPos, nRow, fVal);
     rBlockPos.miCellTextAttrPos = maCellTextAttrs.set(
         rBlockPos.miCellTextAttrPos, nRow, sc::CellTextAttr());
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to