[Libreoffice-commits] core.git: Branch 'private/kohei/calc-sort-fix' - sc/inc sc/source
Kohei Yoshida
kohei.yoshida at collabora.com
Tue Apr 22 12:30:46 PDT 2014
sc/inc/column.hxx | 1
sc/inc/document.hxx | 1
sc/inc/table.hxx | 1
sc/source/core/data/column4.cxx | 104 +++++++++++++++++++++++++++++++++++++
sc/source/core/data/document10.cxx | 9 +++
sc/source/core/data/table7.cxx | 9 +++
sc/source/ui/docshell/dbdocfun.cxx | 9 ++-
7 files changed, 133 insertions(+), 1 deletion(-)
New commits:
commit ed7b45b436b62abc3a56f977399d8da431a23b74
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Tue Apr 22 15:28:49 2014 -0400
Update script types of all cells in sort range ahead of time.
To ensure that there is no SC_SCRIPTTYPE_UNKNOWN in the sort range,
the presence of which would slow down during AdjustRowHeight().
This only adds a tiny overhead (0.3 second) and cuts the duration of
AdjustRowHeight() from 15 seconds to 5 seconds.
Change-Id: I145e901225ef1136f53c6f682ffed3902099859c
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 94795d3..02ec925 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -499,6 +499,7 @@ public:
sc::CellStoreType::iterator itr);
void SetScriptType( SCROW nRow, sal_uInt8 nType );
+ void UpdateScriptTypes( SCROW nRow1, SCROW nRow2 );
size_t GetFormulaHash( SCROW nRow ) const;
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 582d086..df8d0bb 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -2062,6 +2062,7 @@ public:
sal_uInt8 GetScriptType( const ScAddress& rPos ) const;
void SetScriptType( const ScAddress& rPos, sal_uInt8 nType );
+ void UpdateScriptTypes( const ScAddress& rPos, SCCOL nColSize, SCROW nRowSize );
size_t GetFormulaHash( const ScAddress& rPos ) const;
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 34059f7..6715448 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -864,6 +864,7 @@ public:
sal_uInt8 GetScriptType( SCCOL nCol, SCROW nRow ) const;
void SetScriptType( SCCOL nCol, SCROW nRow, sal_uInt8 nType );
+ void UpdateScriptTypes( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
sal_uInt8 GetRangeScriptType( sc::ColumnBlockPosition& rBlockPos, SCCOL nCol, SCROW nRow1, SCROW nRow2 );
diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
index 2698f0b..cad94e5 100644
--- a/sc/source/core/data/column4.cxx
+++ b/sc/source/core/data/column4.cxx
@@ -25,6 +25,9 @@
#include <conditio.hxx>
#include <formulagroup.hxx>
#include <tokenarray.hxx>
+#include <globalnames.hxx>
+#include <scitems.hxx>
+#include <cellform.hxx>
#include <svl/sharedstringpool.hxx>
@@ -721,4 +724,105 @@ void ScColumn::PostprocessRangeNameUpdate( sc::CompileFormulaContext& rCompileCx
std::for_each(aGroups.begin(), aGroups.end(), aFunc);
}
+namespace {
+
+class ScriptTypeUpdater
+{
+ ScColumn& mrCol;
+ sc::CellTextAttrStoreType& mrTextAttrs;
+ sc::CellTextAttrStoreType::iterator miPosAttr;
+ ScConditionalFormatList* mpCFList;
+ SvNumberFormatter* mpFormatter;
+ ScAddress maPos;
+ bool mbUpdated;
+
+private:
+ void updateScriptType( size_t nRow, ScRefCellValue& rCell )
+ {
+ sc::CellTextAttrStoreType::position_type aAttrPos = mrTextAttrs.position(miPosAttr, nRow);
+ miPosAttr = aAttrPos.first;
+
+ if (aAttrPos.first->type != sc::element_type_celltextattr)
+ return;
+
+ sc::CellTextAttr& rAttr = sc::celltextattr_block::at(*aAttrPos.first->data, aAttrPos.second);
+ if (rAttr.mnScriptType != SC_SCRIPTTYPE_UNKNOWN)
+ // Script type already deteremined. Skip it.
+ return;
+
+ const ScPatternAttr* pPat = mrCol.GetPattern(nRow);
+ if (!pPat)
+ // In theory this should never return NULL. But let's be safe.
+ return;
+
+ const SfxItemSet* pCondSet = NULL;
+ if (mpCFList)
+ {
+ maPos.SetRow(nRow);
+ const ScCondFormatItem& rItem =
+ static_cast<const ScCondFormatItem&>(pPat->GetItem(ATTR_CONDITIONAL));
+ const std::vector<sal_uInt32>& rData = rItem.GetCondFormatData();
+ pCondSet = mrCol.GetDoc().GetCondResult(rCell, maPos, *mpCFList, rData);
+ }
+
+ OUString aStr;
+ Color* pColor;
+ sal_uLong nFormat = pPat->GetNumberFormat(mpFormatter, pCondSet);
+ ScCellFormat::GetString(rCell, nFormat, aStr, &pColor, *mpFormatter, &mrCol.GetDoc());
+
+ rAttr.mnScriptType = mrCol.GetDoc().GetStringScriptType(aStr);
+ mbUpdated = true;
+ }
+
+public:
+ ScriptTypeUpdater( ScColumn& rCol ) :
+ mrCol(rCol),
+ mrTextAttrs(rCol.GetCellAttrStore()),
+ miPosAttr(mrTextAttrs.begin()),
+ mpCFList(rCol.GetDoc().GetCondFormList(rCol.GetTab())),
+ mpFormatter(rCol.GetDoc().GetFormatTable()),
+ maPos(rCol.GetCol(), 0, rCol.GetTab()),
+ mbUpdated(false)
+ {}
+
+ void operator() ( size_t nRow, double fVal )
+ {
+ ScRefCellValue aCell(fVal);
+ updateScriptType(nRow, aCell);
+ }
+
+ void operator() ( size_t nRow, const svl::SharedString& rStr )
+ {
+ ScRefCellValue aCell(&rStr);
+ updateScriptType(nRow, aCell);
+ }
+
+ void operator() ( size_t nRow, const EditTextObject* pText )
+ {
+ ScRefCellValue aCell(pText);
+ updateScriptType(nRow, aCell);
+ }
+
+ void operator() ( size_t nRow, const ScFormulaCell* pCell )
+ {
+ ScRefCellValue aCell(const_cast<ScFormulaCell*>(pCell));
+ updateScriptType(nRow, aCell);
+ }
+
+ bool isUpdated() const { return mbUpdated; }
+};
+
+}
+
+void ScColumn::UpdateScriptTypes( SCROW nRow1, SCROW nRow2 )
+{
+ if (!ValidRow(nRow1) || !ValidRow(nRow2) || nRow1 > nRow2)
+ return;
+
+ ScriptTypeUpdater aFunc(*this);
+ sc::ParseAllNonEmpty(maCells.begin(), maCells, nRow1, nRow2, aFunc);
+ if (aFunc.isUpdated())
+ CellStorageModified();
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/document10.cxx b/sc/source/core/data/document10.cxx
index a04e8f9..abf5297 100644
--- a/sc/source/core/data/document10.cxx
+++ b/sc/source/core/data/document10.cxx
@@ -270,4 +270,13 @@ void ScDocument::SharePooledResources( ScDocument* pSrcDoc )
mpCellStringPool = pSrcDoc->mpCellStringPool;
}
+void ScDocument::UpdateScriptTypes( const ScAddress& rPos, SCCOL nColSize, SCROW nRowSize )
+{
+ ScTable* pTab = FetchTable(rPos.Tab());
+ if (!pTab)
+ return;
+
+ pTab->UpdateScriptTypes(rPos.Col(), rPos.Row(), rPos.Col()+nColSize-1, rPos.Row()+nRowSize-1);
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/table7.cxx b/sc/source/core/data/table7.cxx
index 928c109..eeb4643 100644
--- a/sc/source/core/data/table7.cxx
+++ b/sc/source/core/data/table7.cxx
@@ -101,4 +101,13 @@ void ScTable::PostprocessRangeNameUpdate( sc::CompileFormulaContext& rCompileCxt
aCol[i].PostprocessRangeNameUpdate(rCompileCxt);
}
+void ScTable::UpdateScriptTypes( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
+{
+ if (!ValidCol(nCol1) || !ValidCol(nCol2) || nCol1 > nCol2)
+ return;
+
+ for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
+ aCol[nCol].UpdateScriptTypes(nRow1, nRow2);
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx
index 364f9bb..936f601 100644
--- a/sc/source/ui/docshell/dbdocfun.cxx
+++ b/sc/source/ui/docshell/dbdocfun.cxx
@@ -490,6 +490,14 @@ bool ScDBDocFunc::Sort( SCTAB nTab, const ScSortParam& rSortParam,
WaitObject aWait( rDocShell.GetActiveDialogParent() );
+ // Calculate the script types for all cells in the sort range beforehand.
+ // This will speed up the row height adjustment that takes place after the
+ // sort.
+ pDoc->UpdateScriptTypes(
+ ScAddress(rSortParam.nCol1,rSortParam.nRow1,nTab),
+ rSortParam.nCol2-rSortParam.nCol1+1,
+ rSortParam.nRow2-rSortParam.nRow1+1);
+
sal_Bool bRepeatQuery = false; // bestehenden Filter wiederholen?
ScQueryParam aQueryParam;
pDBData->GetQueryParam( aQueryParam );
@@ -651,7 +659,6 @@ bool ScDBDocFunc::Sort( SCTAB nTab, const ScSortParam& rSortParam,
rDocShell.PostPaint(ScRange(nStartX, nStartY, nTab, nEndX, nEndY, nTab), nPaint);
}
- // AdjustRowHeight( aLocalParam.nRow1, aLocalParam.nRow2, bPaint );
rDocShell.AdjustRowHeight( aLocalParam.nRow1, aLocalParam.nRow2, nTab );
// #i59745# set collected drawing undo actions at sorting undo action
More information about the Libreoffice-commits
mailing list