summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@collabora.com>2014-03-22 09:47:11 -0400
committerEike Rathke <erack@redhat.com>2014-03-25 10:19:16 +0000
commit572fdb94ecf3dfea6a6f787398efa4e4c54b4718 (patch)
tree9fb6464b1169b6dc2da1b746aa1799b93f76079e
parent10b44dc538935ab8d61fb11601e16be8d7742fc4 (diff)
fdo#76470: Avoid joining new formula cells individually.
Instead, insert the formula cells in the group first, then only try to join the top and bottom cells afterward. Otherwise the grouping would get messed up and a problem would ensue. (cherry picked from commit 474b2ea601f7fa2f1fbeae0f169ff5b8abc965be) Conflicts: sc/inc/column.hxx Change-Id: I4fdd5326c029032a636d8225b5fb16cbde427c7d Reviewed-on: https://gerrit.libreoffice.org/8716 Reviewed-by: Eike Rathke <erack@redhat.com> Tested-by: Eike Rathke <erack@redhat.com>
-rw-r--r--sc/inc/column.hxx3
-rw-r--r--sc/inc/document.hxx2
-rw-r--r--sc/inc/table.hxx2
-rw-r--r--sc/source/core/data/column.cxx21
-rw-r--r--sc/source/core/data/column3.cxx69
-rw-r--r--sc/source/core/data/documen2.cxx12
-rw-r--r--sc/source/core/data/table2.cxx8
7 files changed, 113 insertions, 4 deletions
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index e6a69e15ea4a..33a1bf7ff64d 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -291,6 +291,8 @@ public:
ScFormulaCell* SetFormulaCell( SCROW nRow, ScFormulaCell* pCell );
ScFormulaCell* SetFormulaCell( sc::ColumnBlockPosition& rBlockPos, SCROW nRow, ScFormulaCell* pCell );
+ bool SetFormulaCells( SCROW nRow, std::vector<ScFormulaCell*>& rCells );
+
svl::SharedString GetSharedString( SCROW nRow ) const;
void SetRawString( SCROW nRow, const OUString& rStr, bool bBroadcast = true );
@@ -555,6 +557,7 @@ private:
sc::CellStoreType::iterator GetPositionToInsert( const sc::CellStoreType::iterator& it, SCROW nRow );
void ActivateNewFormulaCell( const sc::CellStoreType::iterator& itPos, SCROW nRow, ScFormulaCell& rCell, bool bJoin = true );
void ActivateNewFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell, bool bJoin = true );
+ void AttachNewFormulaCells( const sc::CellStoreType::position_type& aPos, size_t nLength );
void BroadcastNewCell( SCROW nRow );
bool UpdateScriptType( sc::CellTextAttr& rAttr, SCROW nRow, sc::CellStoreType::iterator& itr );
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 04ffa47268ac..809689bca86f 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -839,6 +839,8 @@ public:
*/
SC_DLLPUBLIC ScFormulaCell* SetFormulaCell( const ScAddress& rPos, ScFormulaCell* pCell );
+ bool SetFormulaCells( const ScAddress& rPos, std::vector<ScFormulaCell*>& rCells );
+
SC_DLLPUBLIC void InsertMatrixFormula(SCCOL nCol1, SCROW nRow1,
SCCOL nCol2, SCROW nRow2,
const ScMarkData& rMark,
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index eda54721c39d..77e5996064b0 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -345,6 +345,8 @@ public:
*/
ScFormulaCell* SetFormulaCell( SCCOL nCol, SCROW nRow, ScFormulaCell* pCell );
+ bool SetFormulaCells( SCCOL nCol, SCROW nRow, std::vector<ScFormulaCell*>& rCells );
+
svl::SharedString GetSharedString( SCCOL nCol, SCROW nRow ) const;
void SetValue( SCCOL nCol, SCROW nRow, const double& rVal );
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 7914fdfced9d..7a448fd4683f 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -43,6 +43,7 @@
#include "refupdatecontext.hxx"
#include <listenercontext.hxx>
#include <refhint.hxx>
+#include <stlalgorithm.hxx>
#include <svl/poolcach.hxx>
#include <svl/zforlist.hxx>
@@ -2553,21 +2554,33 @@ class UpdateRefOnNonCopy : std::unary_function<FormulaGroup, void>
void fillUndoDoc( const ScAddress& rOldPos, SCROW nLength, const ScTokenArray& rOldCode )
{
- if (!mpUndoDoc)
+ if (!mpUndoDoc || nLength <= 0)
return;
// Insert the old formula group into the undo document.
ScAddress aUndoPos = rOldPos;
ScFormulaCell* pFC = new ScFormulaCell(mpUndoDoc, aUndoPos, rOldCode.Clone());
- ScFormulaCellGroupRef xGroup = pFC->CreateCellGroup(nLength, false);
- mpUndoDoc->SetFormulaCell(aUndoPos, pFC);
+ if (nLength == 1)
+ {
+ mpUndoDoc->SetFormulaCell(aUndoPos, pFC);
+ return;
+ }
+
+ std::vector<ScFormulaCell*> aCells;
+ aCells.reserve(nLength);
+ ScFormulaCellGroupRef xGroup = pFC->CreateCellGroup(nLength, false);
+ aCells.push_back(pFC);
aUndoPos.IncRow();
for (SCROW i = 1; i < nLength; ++i, aUndoPos.IncRow())
{
pFC = new ScFormulaCell(mpUndoDoc, aUndoPos, xGroup);
- mpUndoDoc->SetFormulaCell(aUndoPos, pFC);
+ aCells.push_back(pFC);
}
+
+ if (!mpUndoDoc->SetFormulaCells(rOldPos, aCells))
+ // Insertion failed. Delete all formula cells.
+ std::for_each(aCells.begin(), aCells.end(), ScDeleteObjectByPtr<ScFormulaCell>());
}
public:
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 75ad544c1d38..d47893f0ba1b 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -46,6 +46,7 @@
#include "scopetools.hxx"
#include "editutil.hxx"
#include "sharedformula.hxx"
+#include <listenercontext.hxx>
#include <com/sun/star/i18n/LocaleDataItem.hpp>
@@ -413,6 +414,40 @@ void ScColumn::ActivateNewFormulaCell(
}
}
+void ScColumn::AttachNewFormulaCells( const sc::CellStoreType::position_type& aPos, size_t nLength )
+{
+ // Make sure the whole length consists of formula cells.
+ if (aPos.first->type != sc::element_type_formula)
+ return;
+
+ if (aPos.first->size < aPos.second + nLength)
+ // Block is shorter than specified length.
+ return;
+
+ // Join the top and bottom cells only.
+ ScFormulaCell* pCell = sc::formula_block::at(*aPos.first->data, aPos.second);
+ JoinNewFormulaCell(aPos, *pCell);
+
+ sc::CellStoreType::position_type aPosLast = aPos;
+ aPosLast.second += nLength - 1;
+ pCell = sc::formula_block::at(*aPosLast.first->data, aPosLast.second);
+ JoinNewFormulaCell(aPosLast, *pCell);
+
+ if (!pDocument->IsClipOrUndo() && !pDocument->IsInsertingFromOtherDoc())
+ {
+ sc::StartListeningContext aCxt(*pDocument);
+ ScFormulaCell** pp = &sc::formula_block::at(*aPos.first->data, aPos.second);
+ ScFormulaCell** ppEnd = pp + nLength;
+ for (; pp != ppEnd; ++pp)
+ {
+ pCell = *pp;
+ pCell->StartListeningTo(aCxt);
+ if (!pDocument->IsCalcingAfterLoad())
+ pCell->SetDirty();
+ }
+ }
+}
+
void ScColumn::BroadcastNewCell( SCROW nRow )
{
// When we insert from the Clipboard we still have wrong (old) References!
@@ -1805,6 +1840,40 @@ ScFormulaCell* ScColumn::SetFormulaCell( sc::ColumnBlockPosition& rBlockPos, SCR
return pCell;
}
+bool ScColumn::SetFormulaCells( SCROW nRow, std::vector<ScFormulaCell*>& rCells )
+{
+ if (!ValidRow(nRow))
+ return false;
+
+ SCROW nEndRow = nRow + rCells.size() - 1;
+ if (!ValidRow(nEndRow))
+ return false;
+
+ sc::CellStoreType::position_type aPos = maCells.position(nRow);
+
+ // Detach all formula cells that will be overwritten.
+ DetachFormulaCells(aPos, rCells.size());
+
+ for (size_t i = 0, n = rCells.size(); i < n; ++i)
+ {
+ SCROW nThisRow = nRow + i;
+ sal_uInt32 nFmt = GetNumberFormat(nThisRow);
+ if ((nFmt % SV_COUNTRY_LANGUAGE_OFFSET) == 0)
+ rCells[i]->SetNeedNumberFormat(true);
+ }
+
+ std::vector<sc::CellTextAttr> aDefaults(rCells.size(), sc::CellTextAttr());
+ maCellTextAttrs.set(nRow, aDefaults.begin(), aDefaults.end());
+
+ sc::CellStoreType::iterator it = maCells.set(aPos.first, nRow, rCells.begin(), rCells.end());
+
+ CellStorageModified();
+
+ AttachNewFormulaCells(aPos, rCells.size());
+
+ return true;
+}
+
svl::SharedString ScColumn::GetSharedString( SCROW nRow ) const
{
sc::CellStoreType::const_position_type aPos = maCells.position(nRow);
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index 1a57cc824da2..daa4e2ae9bb7 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -1118,6 +1118,18 @@ ScFormulaCell* ScDocument::SetFormulaCell( const ScAddress& rPos, ScFormulaCell*
return maTabs[rPos.Tab()]->SetFormulaCell(rPos.Col(), rPos.Row(), pCell);
}
+bool ScDocument::SetFormulaCells( const ScAddress& rPos, std::vector<ScFormulaCell*>& rCells )
+{
+ if (rCells.empty())
+ return false;
+
+ ScTable* pTab = FetchTable(rPos.Tab());
+ if (!pTab)
+ return false;
+
+ return pTab->SetFormulaCells(rPos.Col(), rPos.Row(), rCells);
+}
+
void ScDocument::SetConsolidateDlgData( const ScConsolidateParam* pData )
{
delete pConsolidateDlgData;
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index b0fba9c50b27..2835496a4df0 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1384,6 +1384,14 @@ ScFormulaCell* ScTable::SetFormulaCell( SCCOL nCol, SCROW nRow, ScFormulaCell* p
return aCol[nCol].SetFormulaCell(nRow, pCell);
}
+bool ScTable::SetFormulaCells( SCCOL nCol, SCROW nRow, std::vector<ScFormulaCell*>& rCells )
+{
+ if (!ValidCol(nCol))
+ return false;
+
+ return aCol[nCol].SetFormulaCells(nRow, rCells);
+}
+
svl::SharedString ScTable::GetSharedString( SCCOL nCol, SCROW nRow ) const
{
if (!ValidColRow(nCol, nRow))