From 67f3ce3a9df2bc62db5602dd84975047c1137b92 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Thu, 9 Oct 2014 16:21:59 +0100 Subject: fdo#81633: Add a hidden configuration option to toggle ref update on sort. This option is defaulted to off for 4.3 for back-compatibility. Reviewed-on: https://gerrit.libreoffice.org/11902 Reviewed-by: Muthu Subramanian K Reviewed-by: Eike Rathke Tested-by: Eike Rathke Signed-off-by: Andras Timar Conflicts: sc/inc/inputopt.hxx sc/qa/unit/ucalc.cxx sc/source/core/tool/inputopt.cxx Change-Id: I5ac686e96742df40f7d8ba5ffec23806db2988a6 (cherry picked from commit c357fb2dbdc54d9ee8471ce4e9f9381e74a6deed) Signed-off-by: Andras Timar --- sc/source/core/data/documen3.cxx | 5 +- sc/source/core/data/table3.cxx | 115 ++++++++++++++++++++++----------------- sc/source/core/tool/inputopt.cxx | 34 ++++++++---- 3 files changed, 91 insertions(+), 63 deletions(-) (limited to 'sc/source/core') diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx index 75514fd18056..10c30f6ee4fb 100644 --- a/sc/source/core/data/documen3.cxx +++ b/sc/source/core/data/documen3.cxx @@ -1355,13 +1355,14 @@ bool ScDocument::UpdateOutlineRow( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, b } void ScDocument::Sort( - SCTAB nTab, const ScSortParam& rSortParam, bool bKeepQuery, ScProgress* pProgress, sc::ReorderParam* pUndo ) + SCTAB nTab, const ScSortParam& rSortParam, bool bKeepQuery, bool bUpdateRefs, + ScProgress* pProgress, sc::ReorderParam* pUndo ) { if ( ValidTab(nTab) && nTab < static_cast(maTabs.size()) && maTabs[nTab] ) { bool bOldEnableIdle = IsIdleEnabled(); EnableIdle(false); - maTabs[nTab]->Sort(rSortParam, bKeepQuery, pProgress, pUndo); + maTabs[nTab]->Sort(rSortParam, bKeepQuery, bUpdateRefs, pProgress, pUndo); EnableIdle(bOldEnableIdle); } } diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx index 946416da19fe..589a9b1fb83e 100644 --- a/sc/source/core/data/table3.cxx +++ b/sc/source/core/data/table3.cxx @@ -261,6 +261,7 @@ private: std::vector maOrderIndices; bool mbKeepQuery; + bool mbUpdateRefs; public: ScSortInfoArray( sal_uInt16 nSorts, SCCOLROW nInd1, SCCOLROW nInd2 ) : @@ -308,6 +309,10 @@ public: bool IsKeepQuery() const { return mbKeepQuery; } + void SetUpdateRefs( bool b ) { mbUpdateRefs = b; } + + bool IsUpdateRefs() const { return mbUpdateRefs; } + /** * Call this only during normal sorting, not from reordering. */ @@ -471,6 +476,7 @@ ScSortInfoArray* ScTable::CreateSortInfoArray( const sc::ReorderParam& rParam ) pArray = new ScSortInfoArray(0, nRow1, nRow2); pArray->SetKeepQuery(rParam.mbHiddenFiltered); + pArray->SetUpdateRefs(rParam.mbUpdateRefs); initDataRows( *pArray, *this, aCol, nCol1, nRow1, nCol2, nRow2, @@ -483,19 +489,22 @@ ScSortInfoArray* ScTable::CreateSortInfoArray( const sc::ReorderParam& rParam ) pArray = new ScSortInfoArray(0, nCol1, nCol2); pArray->SetKeepQuery(rParam.mbHiddenFiltered); + pArray->SetUpdateRefs(rParam.mbUpdateRefs); } return pArray; } ScSortInfoArray* ScTable::CreateSortInfoArray( - const ScSortParam& rSortParam, SCCOLROW nInd1, SCCOLROW nInd2, bool bKeepQuery ) + const ScSortParam& rSortParam, SCCOLROW nInd1, SCCOLROW nInd2, + bool bKeepQuery, bool bUpdateRefs ) { sal_uInt16 nUsedSorts = 1; while ( nUsedSorts < rSortParam.GetSortKeyCount() && rSortParam.maKeyState[nUsedSorts].bDoSort ) nUsedSorts++; ScSortInfoArray* pArray = new ScSortInfoArray( nUsedSorts, nInd1, nInd2 ); pArray->SetKeepQuery(bKeepQuery); + pArray->SetUpdateRefs(bUpdateRefs); if ( rSortParam.bByRow ) { @@ -737,16 +746,19 @@ void ScTable::SortReorderByColumn( } } - for (SCCOL nCol = nStart; nCol <= nLast; ++nCol) - aCol[nCol].CollectListeners(aListeners, nRow1, nRow2); + if (pArray->IsUpdateRefs()) + { + for (SCCOL nCol = nStart; nCol <= nLast; ++nCol) + aCol[nCol].CollectListeners(aListeners, nRow1, nRow2); - // Remove any duplicate listener entries and notify all listeners - // afterward. We must ensure that we notify each unique listener only - // once. - std::sort(aListeners.begin(), aListeners.end()); - aListeners.erase(std::unique(aListeners.begin(), aListeners.end()), aListeners.end()); - ColReorderNotifier aFunc(aColMap, nTab, nRow1, nRow2); - std::for_each(aListeners.begin(), aListeners.end(), aFunc); + // Remove any duplicate listener entries and notify all listeners + // afterward. We must ensure that we notify each unique listener only + // once. + std::sort(aListeners.begin(), aListeners.end()); + aListeners.erase(std::unique(aListeners.begin(), aListeners.end()), aListeners.end()); + ColReorderNotifier aFunc(aColMap, nTab, nRow1, nRow2); + std::for_each(aListeners.begin(), aListeners.end(), aFunc); + } // Re-start area listeners on the reordered columns. { @@ -1001,39 +1013,51 @@ void ScTable::SortReorderByRow( } } - // Collect listeners of cell broadcasters. - for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol) - aCol[nCol].CollectListeners(aListeners, nRow1, nRow2); + if (pArray->IsUpdateRefs()) + { + // Collect listeners of cell broadcasters. + for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol) + aCol[nCol].CollectListeners(aListeners, nRow1, nRow2); - // Remove any duplicate listener entries. We must ensure that we notify - // each unique listener only once. - std::sort(aListeners.begin(), aListeners.end()); - aListeners.erase(std::unique(aListeners.begin(), aListeners.end()), aListeners.end()); + // Remove any duplicate listener entries. We must ensure that we notify + // each unique listener only once. + std::sort(aListeners.begin(), aListeners.end()); + aListeners.erase(std::unique(aListeners.begin(), aListeners.end()), aListeners.end()); - // Collect positions of all shared formula cells outside the sorted range, - // and make them unshared before notifying them. - sc::RefQueryFormulaGroup aFormulaGroupPos; - aFormulaGroupPos.setSkipRange(ScRange(nCol1, nRow1, nTab, nCol2, nRow2, nTab)); + // Collect positions of all shared formula cells outside the sorted range, + // and make them unshared before notifying them. + sc::RefQueryFormulaGroup aFormulaGroupPos; + aFormulaGroupPos.setSkipRange(ScRange(nCol1, nRow1, nTab, nCol2, nRow2, nTab)); - std::for_each(aListeners.begin(), aListeners.end(), FormulaGroupPosCollector(aFormulaGroupPos)); - const sc::RefQueryFormulaGroup::TabsType& rGroupTabs = aFormulaGroupPos.getAllPositions(); - sc::RefQueryFormulaGroup::TabsType::const_iterator itGroupTab = rGroupTabs.begin(), itGroupTabEnd = rGroupTabs.end(); - for (; itGroupTab != itGroupTabEnd; ++itGroupTab) - { - const sc::RefQueryFormulaGroup::ColsType& rCols = itGroupTab->second; - sc::RefQueryFormulaGroup::ColsType::const_iterator itCol = rCols.begin(), itColEnd = rCols.end(); - for (; itCol != itColEnd; ++itCol) + std::for_each(aListeners.begin(), aListeners.end(), FormulaGroupPosCollector(aFormulaGroupPos)); + const sc::RefQueryFormulaGroup::TabsType& rGroupTabs = aFormulaGroupPos.getAllPositions(); + sc::RefQueryFormulaGroup::TabsType::const_iterator itGroupTab = rGroupTabs.begin(), itGroupTabEnd = rGroupTabs.end(); + for (; itGroupTab != itGroupTabEnd; ++itGroupTab) + { + const sc::RefQueryFormulaGroup::ColsType& rCols = itGroupTab->second; + sc::RefQueryFormulaGroup::ColsType::const_iterator itCol = rCols.begin(), itColEnd = rCols.end(); + for (; itCol != itColEnd; ++itCol) + { + const sc::RefQueryFormulaGroup::ColType& rCol = itCol->second; + std::vector aBounds(rCol); + pDocument->UnshareFormulaCells(itGroupTab->first, itCol->first, aBounds); + } + } + + // Notify the listeners. + RowReorderNotifier aFunc(aRowMap, nTab, nCol1, nCol2); + std::for_each(aListeners.begin(), aListeners.end(), aFunc); + + // Re-group formulas in affected columns. + for (itGroupTab = rGroupTabs.begin(); itGroupTab != itGroupTabEnd; ++itGroupTab) { - const sc::RefQueryFormulaGroup::ColType& rCol = itCol->second; - std::vector aBounds(rCol); - pDocument->UnshareFormulaCells(itGroupTab->first, itCol->first, aBounds); + const sc::RefQueryFormulaGroup::ColsType& rCols = itGroupTab->second; + sc::RefQueryFormulaGroup::ColsType::const_iterator itCol = rCols.begin(), itColEnd = rCols.end(); + for (; itCol != itColEnd; ++itCol) + pDocument->RegroupFormulaCells(itGroupTab->first, itCol->first); } } - // Notify the listeners. - RowReorderNotifier aFunc(aRowMap, nTab, nCol1, nCol2); - std::for_each(aListeners.begin(), aListeners.end(), aFunc); - // Re-start area listeners on the reordered rows. { std::vector::iterator it = aAreaListeners.begin(), itEnd = aAreaListeners.end(); @@ -1050,15 +1074,6 @@ void ScTable::SortReorderByRow( } } - // Re-group formulas in affected columns. - for (itGroupTab = rGroupTabs.begin(); itGroupTab != itGroupTabEnd; ++itGroupTab) - { - const sc::RefQueryFormulaGroup::ColsType& rCols = itGroupTab->second; - sc::RefQueryFormulaGroup::ColsType::const_iterator itCol = rCols.begin(), itColEnd = rCols.end(); - for (; itCol != itColEnd; ++itCol) - pDocument->RegroupFormulaCells(itGroupTab->first, itCol->first); - } - // Re-group columns in the sorted range too. for (SCCOL i = nCol1; i <= nCol2; ++i) aCol[i].RegroupFormulaCells(); @@ -1281,7 +1296,8 @@ void ScTable::DecoladeRow( ScSortInfoArray* pArray, SCROW nRow1, SCROW nRow2 ) } void ScTable::Sort( - const ScSortParam& rSortParam, bool bKeepQuery, ScProgress* pProgress, sc::ReorderParam* pUndo ) + const ScSortParam& rSortParam, bool bKeepQuery, bool bUpdateRefs, + ScProgress* pProgress, sc::ReorderParam* pUndo ) { aSortParam = rSortParam; InitSortCollator( rSortParam ); @@ -1293,6 +1309,7 @@ void ScTable::Sort( pUndo->mbByRow = rSortParam.bByRow; pUndo->mbPattern = rSortParam.bIncludePattern; pUndo->mbHiddenFiltered = bKeepQuery; + pUndo->mbUpdateRefs = bUpdateRefs; } if (rSortParam.bByRow) @@ -1308,7 +1325,7 @@ void ScTable::Sort( if(pProgress) pProgress->SetState( 0, nLastRow-nRow1 ); - boost::scoped_ptr pArray(CreateSortInfoArray(aSortParam, nRow1, nLastRow, bKeepQuery)); + boost::scoped_ptr pArray(CreateSortInfoArray(aSortParam, nRow1, nLastRow, bKeepQuery, bUpdateRefs)); if ( nLastRow - nRow1 > 255 ) DecoladeRow(pArray.get(), nRow1, nLastRow); @@ -1337,7 +1354,7 @@ void ScTable::Sort( if(pProgress) pProgress->SetState( 0, nLastCol-nCol1 ); - boost::scoped_ptr pArray(CreateSortInfoArray(aSortParam, nCol1, nLastCol, bKeepQuery)); + boost::scoped_ptr pArray(CreateSortInfoArray(aSortParam, nCol1, nLastCol, bKeepQuery, bUpdateRefs)); QuickSort(pArray.get(), nCol1, nLastCol); SortReorderByColumn(pArray.get(), aSortParam.nRow1, aSortParam.nRow2, aSortParam.bIncludePattern, pProgress); @@ -2369,7 +2386,7 @@ void ScTable::TopTenQuery( ScQueryParam& rParam ) bSortCollatorInitialized = true; InitSortCollator( aLocalSortParam ); } - boost::scoped_ptr pArray(CreateSortInfoArray(aSortParam, nRow1, rParam.nRow2, bGlobalKeepQuery)); + boost::scoped_ptr pArray(CreateSortInfoArray(aSortParam, nRow1, rParam.nRow2, bGlobalKeepQuery, false)); DecoladeRow( pArray.get(), nRow1, rParam.nRow2 ); QuickSort( pArray.get(), nRow1, rParam.nRow2 ); ScSortInfo** ppInfo = pArray->GetFirstArray(); diff --git a/sc/source/core/tool/inputopt.cxx b/sc/source/core/tool/inputopt.cxx index e36cd8550e06..756bf9d7108a 100644 --- a/sc/source/core/tool/inputopt.cxx +++ b/sc/source/core/tool/inputopt.cxx @@ -55,6 +55,7 @@ void ScInputOptions::SetDefaults() bExtendFormat = false; bRangeFinder = sal_True; bExpandRefs = false; + mbSortRefUpdate = sal_True; bMarkHeader = sal_True; bUseTabCol = false; bTextWysiwyg = false; @@ -70,6 +71,7 @@ const ScInputOptions& ScInputOptions::operator=( const ScInputOptions& rCpy ) bExtendFormat = rCpy.bExtendFormat; bRangeFinder = rCpy.bRangeFinder; bExpandRefs = rCpy.bExpandRefs; + mbSortRefUpdate = rCpy.mbSortRefUpdate; bMarkHeader = rCpy.bMarkHeader; bUseTabCol = rCpy.bUseTabCol; bTextWysiwyg = rCpy.bTextWysiwyg; @@ -83,18 +85,19 @@ const ScInputOptions& ScInputOptions::operator=( const ScInputOptions& rCpy ) #define CFGPATH_INPUT "Office.Calc/Input" -#define SCINPUTOPT_MOVEDIR 0 -#define SCINPUTOPT_MOVESEL 1 -#define SCINPUTOPT_EDTEREDIT 2 -#define SCINPUTOPT_EXTENDFMT 3 -#define SCINPUTOPT_RANGEFIND 4 -#define SCINPUTOPT_EXPANDREFS 5 -#define SCINPUTOPT_MARKHEADER 6 -#define SCINPUTOPT_USETABCOL 7 -#define SCINPUTOPT_TEXTWYSIWYG 8 -#define SCINPUTOPT_REPLCELLSWARN 9 -#define SCINPUTOPT_LEGACY_CELL_SELECTION 10 -#define SCINPUTOPT_COUNT 11 +#define SCINPUTOPT_MOVEDIR 0 +#define SCINPUTOPT_MOVESEL 1 +#define SCINPUTOPT_EDTEREDIT 2 +#define SCINPUTOPT_EXTENDFMT 3 +#define SCINPUTOPT_RANGEFIND 4 +#define SCINPUTOPT_EXPANDREFS 5 +#define SCINPUTOPT_SORT_REF_UPDATE 6 +#define SCINPUTOPT_MARKHEADER 7 +#define SCINPUTOPT_USETABCOL 8 +#define SCINPUTOPT_TEXTWYSIWYG 9 +#define SCINPUTOPT_REPLCELLSWARN 10 +#define SCINPUTOPT_LEGACY_CELL_SELECTION 11 +#define SCINPUTOPT_COUNT 12 Sequence ScInputCfg::GetPropertyNames() { @@ -106,6 +109,7 @@ Sequence ScInputCfg::GetPropertyNames() "ExpandFormatting", // SCINPUTOPT_EXTENDFMT "ShowReference", // SCINPUTOPT_RANGEFIND "ExpandReference", // SCINPUTOPT_EXPANDREFS + "UpdateReferenceOnSort", // SCINPUTOPT_SORT_REF_UPDATE "HighlightSelection", // SCINPUTOPT_MARKHEADER "UseTabCol", // SCINPUTOPT_USETABCOL "UsePrinterMetrics", // SCINPUTOPT_TEXTWYSIWYG @@ -157,6 +161,9 @@ ScInputCfg::ScInputCfg() : case SCINPUTOPT_EXPANDREFS: SetExpandRefs( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); break; + case SCINPUTOPT_SORT_REF_UPDATE: + SetSortRefUpdate(ScUnoHelpFunctions::GetBoolFromAny(pValues[nProp])); + break; case SCINPUTOPT_MARKHEADER: SetMarkHeader( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); break; @@ -206,6 +213,9 @@ void ScInputCfg::Commit() case SCINPUTOPT_EXPANDREFS: ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], GetExpandRefs() ); break; + case SCINPUTOPT_SORT_REF_UPDATE: + ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], GetSortRefUpdate() ); + break; case SCINPUTOPT_MARKHEADER: ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], GetMarkHeader() ); break; -- cgit v1.2.3