Kaydet (Commit) ea607135 authored tarafından Samuel Mehrbrodt's avatar Samuel Mehrbrodt Kaydeden (comit) Eike Rathke

Improve performance when looking for draw objects anchored to cells

Look for a whole column at once so we don't have to iterate all draw objects
for every cell, but only once per column.

Follow-up for 3a2a430a

Change-Id: Ic8740fca7d595528785b432c1cedf4fad4f13ba1
Reviewed-on: https://gerrit.libreoffice.org/48416Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarEike Rathke <erack@redhat.com>
üst 3341c752
...@@ -182,8 +182,8 @@ public: ...@@ -182,8 +182,8 @@ public:
static void SetCellAnchoredFromPosition( SdrObject &rObj, const ScDocument &rDoc, SCTAB nTab ); static void SetCellAnchoredFromPosition( SdrObject &rObj, const ScDocument &rDoc, SCTAB nTab );
static void UpdateCellAnchorFromPositionEnd( const SdrObject &rObj, ScDrawObjData &rAnchor, const ScDocument &rDoc, SCTAB nTab, bool bUseLogicRect = true ); static void UpdateCellAnchorFromPositionEnd( const SdrObject &rObj, ScDrawObjData &rAnchor, const ScDocument &rDoc, SCTAB nTab, bool bUseLogicRect = true );
static ScAnchorType GetAnchorType( const SdrObject& ); static ScAnchorType GetAnchorType( const SdrObject& );
std::vector<SdrObject*> GetObjectsAnchoredToCell(const ScAddress& rPos); std::map<SCROW, std::vector<SdrObject*>> GetObjectsAnchoredToRange(SCTAB nTab, SCCOL nCol, SCROW nStartRow, SCROW nEndRow);
bool HasObjectsAnchoredInRange(ScRange& rRange); bool HasObjectsAnchoredInRange(ScRange& rRange);
void MoveObject(SdrObject* pObj, ScAddress& rNewPosition); void MoveObject(SdrObject* pObj, ScAddress& rNewPosition);
// positions for detektive lines // positions for detektive lines
......
...@@ -1921,8 +1921,9 @@ void Test::testSortImages() ...@@ -1921,8 +1921,9 @@ void Test::testSortImages()
ScAddress aCellPos(1, 1, 0); ScAddress aCellPos(1, 1, 0);
pDrawLayer->MoveObject(pObj, aCellPos); pDrawLayer->MoveObject(pObj, aCellPos);
std::vector<SdrObject*> pObjects = pDrawLayer->GetObjectsAnchoredToCell(aCellPos); std::map<SCROW, std::vector<SdrObject*>> pRowObjects
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pObjects.size()); = pDrawLayer->GetObjectsAnchoredToRange(aCellPos.Tab(), aCellPos.Col(), aCellPos.Row(), aCellPos.Row());
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pRowObjects[aCellPos.Row()].size());
ScSortParam aSortData; ScSortParam aSortData;
aSortData.nCol1 = 0; aSortData.nCol1 = 0;
...@@ -1940,8 +1941,9 @@ void Test::testSortImages() ...@@ -1940,8 +1941,9 @@ void Test::testSortImages()
// check that note is also moved after sorting // check that note is also moved after sorting
aCellPos = ScAddress(1, 0, 0); aCellPos = ScAddress(1, 0, 0);
pObjects = pDrawLayer->GetObjectsAnchoredToCell(aCellPos); pRowObjects
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pObjects.size()); = pDrawLayer->GetObjectsAnchoredToRange(aCellPos.Tab(), aCellPos.Col(), aCellPos.Row(), aCellPos.Row());
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pRowObjects[aCellPos.Row()].size());
m_pDoc->DeleteTab(0); m_pDoc->DeleteTab(0);
} }
......
...@@ -1091,16 +1091,18 @@ void ScColumn::Swap( ScColumn& rOther, SCROW nRow1, SCROW nRow2, bool bPattern ) ...@@ -1091,16 +1091,18 @@ void ScColumn::Swap( ScColumn& rOther, SCROW nRow1, SCROW nRow2, bool bPattern )
ScDrawLayer* pDrawLayer = GetDoc()->GetDrawLayer(); ScDrawLayer* pDrawLayer = GetDoc()->GetDrawLayer();
if (pDrawLayer) if (pDrawLayer)
{ {
std::map<SCROW, std::vector<SdrObject*>> aThisColRowDrawObjects
= pDrawLayer->GetObjectsAnchoredToRange(GetTab(), GetCol(), nRow1, nRow2);
std::map<SCROW, std::vector<SdrObject*>> aOtherColRowDrawObjects
= pDrawLayer->GetObjectsAnchoredToRange(GetTab(), rOther.GetCol(), nRow1, nRow2);
for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow) for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
{ {
ScAddress aThisCellPos(GetCol(), nRow, GetTab()); std::vector<SdrObject*>& rThisCellDrawObjects = aThisColRowDrawObjects[nRow];
ScAddress aOtherCellPos(rOther.GetCol(), nRow, GetTab()); if (!rThisCellDrawObjects.empty())
std::vector<SdrObject*> pThisColObjects = pDrawLayer->GetObjectsAnchoredToCell(aThisCellPos); UpdateDrawObjectsForRow(rThisCellDrawObjects, rOther.GetCol(), nRow);
std::vector<SdrObject*> pOtherColObjects = pDrawLayer->GetObjectsAnchoredToCell(aOtherCellPos); std::vector<SdrObject*>& rOtherCellDrawObjects = aOtherColRowDrawObjects[nRow];
if (!pThisColObjects.empty()) if (!rOtherCellDrawObjects.empty())
UpdateDrawObjectsForRow(pThisColObjects, rOther.GetCol(), nRow); rOther.UpdateDrawObjectsForRow(rOtherCellDrawObjects, GetCol(), nRow);
if (!pOtherColObjects.empty())
rOther.UpdateDrawObjectsForRow(pOtherColObjects, GetCol(), nRow);
} }
} }
......
...@@ -1994,27 +1994,28 @@ ScAnchorType ScDrawLayer::GetAnchorType( const SdrObject &rObj ) ...@@ -1994,27 +1994,28 @@ ScAnchorType ScDrawLayer::GetAnchorType( const SdrObject &rObj )
return ScDrawLayer::GetObjData(const_cast<SdrObject*>(&rObj)) ? SCA_CELL : SCA_PAGE; return ScDrawLayer::GetObjData(const_cast<SdrObject*>(&rObj)) ? SCA_CELL : SCA_PAGE;
} }
std::vector<SdrObject*> ScDrawLayer::GetObjectsAnchoredToCell(const ScAddress& rCell) std::map<SCROW, std::vector<SdrObject*>>
ScDrawLayer::GetObjectsAnchoredToRange(SCTAB nTab, SCCOL nCol, SCROW nStartRow, SCROW nEndRow)
{ {
SdrPage* pPage = GetPage(static_cast<sal_uInt16>(rCell.Tab())); SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
if (!pPage || pPage->GetObjCount() < 1) if (!pPage || pPage->GetObjCount() < 1)
return std::vector<SdrObject*>(); return std::map<SCROW, std::vector<SdrObject*>>();
std::vector<SdrObject*> pObjects; std::map<SCROW, std::vector<SdrObject*>> aRowObjects;
SdrObjListIter aIter( *pPage, SdrIterMode::Flat ); SdrObjListIter aIter( *pPage, SdrIterMode::Flat );
SdrObject* pObject = aIter.Next(); SdrObject* pObject = aIter.Next();
ScDrawObjData* pObjData; ScRange aRange( nCol, nStartRow, nTab, nCol, nEndRow, nTab);
while (pObject) while (pObject)
{ {
if (!dynamic_cast<SdrCaptionObj*>(pObject)) // Caption objects are handled differently if (!dynamic_cast<SdrCaptionObj*>(pObject)) // Caption objects are handled differently
{ {
pObjData = GetObjData(pObject); ScDrawObjData* pObjData = GetObjData(pObject);
if (pObjData && pObjData->maStart == rCell) // Object is anchored to this cell if (pObjData && aRange.In(pObjData->maStart))
pObjects.push_back(pObject); aRowObjects[pObjData->maStart.Row()].push_back(pObject);
} }
pObject = aIter.Next(); pObject = aIter.Next();
} }
return pObjects; return aRowObjects;
} }
bool ScDrawLayer::HasObjectsAnchoredInRange(ScRange& rRange) bool ScDrawLayer::HasObjectsAnchoredInRange(ScRange& rRange)
......
...@@ -433,6 +433,13 @@ void initDataRows( ...@@ -433,6 +433,13 @@ void initDataRows(
sc::ColumnBlockConstPosition aBlockPos; sc::ColumnBlockConstPosition aBlockPos;
rCol.InitBlockPosition(aBlockPos); rCol.InitBlockPosition(aBlockPos);
std::map<SCROW, std::vector<SdrObject*>> aRowDrawObjects;
ScDrawLayer* pDrawLayer = rTab.GetDoc().GetDrawLayer();
if (pDrawLayer)
aRowDrawObjects = pDrawLayer->GetObjectsAnchoredToRange(rTab.GetTab(), nCol, nRow1, nRow2);
else
SAL_WARN("sc", "Could not retrieve anchored images, no DrawLayer available");
for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow) for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
{ {
ScSortInfoArray::Row& rRow = *rRows[nRow-nRow1]; ScSortInfoArray::Row& rRow = *rRows[nRow-nRow1];
...@@ -440,17 +447,8 @@ void initDataRows( ...@@ -440,17 +447,8 @@ void initDataRows(
rCell.maCell = rCol.GetCellValue(aBlockPos, nRow); rCell.maCell = rCol.GetCellValue(aBlockPos, nRow);
rCell.mpAttr = rCol.GetCellTextAttr(aBlockPos, nRow); rCell.mpAttr = rCol.GetCellTextAttr(aBlockPos, nRow);
rCell.mpNote = rCol.GetCellNote(aBlockPos, nRow); rCell.mpNote = rCol.GetCellNote(aBlockPos, nRow);
ScDrawLayer* pDrawLayer = rTab.GetDoc().GetDrawLayer();
if (pDrawLayer) if (pDrawLayer)
{ rCell.maDrawObjects = aRowDrawObjects[nRow];
ScAddress aCellPos(nCol, nRow, rTab.GetTab());
std::vector<SdrObject*> pObjects = pDrawLayer->GetObjectsAnchoredToCell(aCellPos);
rCell.maDrawObjects = pObjects;
}
else
{
SAL_WARN("sc", "Could not retrieve anchored images, no DrawLayer available");
}
if (!bUniformPattern && bPattern) if (!bUniformPattern && bPattern)
rCell.mpPattern = rCol.GetPattern(nRow); rCell.mpPattern = rCol.GetPattern(nRow);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment