sc/Library_sc.mk | 1 sc/inc/Sparkline.hxx | 42 ++++++++++++++++++++++++++++++++- sc/inc/SparklineCell.hxx | 47 ++++++++++++++++++++++++++++++++++++++ sc/inc/column.hxx | 4 +-- sc/inc/document.hxx | 2 + sc/inc/mtvelements.hxx | 6 ++-- sc/inc/table.hxx | 9 +++++++ sc/source/core/data/Sparkline.cxx | 22 ----------------- sc/source/core/data/column2.cxx | 8 +++--- sc/source/core/data/document.cxx | 32 ++++++++++++++++--------- sc/source/core/data/table2.cxx | 36 +++++++++++++++++++++++++++++ 11 files changed, 163 insertions(+), 46 deletions(-)
New commits: commit aa66f2fe9b92f77d8f64f073607db069a8e08f45 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> AuthorDate: Wed Mar 2 17:44:08 2022 +0900 Commit: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> CommitDate: Wed Mar 2 17:44:08 2022 +0900 sc: refactor sparkline struture to store a list of sparklines We need to access a list of sparklines and sparkline groups for a sheet. To preven going through all the columns of a sheet, we need to store all the created sparklines in a list. For this it is necessary to change the model structrue a bit. A cell now has a container that stores a shared_ptr to the sparkline instead of storing the sparkline directly. With this we can store a list of weak_ptr to the sparklines in a list (vector), which can be accessed at any time and is quite fast. This is needed by the OOXML export. Change-Id: Iaca0a41e20912775f072ea6e8cab9c44367d6f30 diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk index 11449217edd9..62ab22a797c4 100644 --- a/sc/Library_sc.mk +++ b/sc/Library_sc.mk @@ -185,7 +185,6 @@ $(eval $(call gb_Library_add_exception_objects,sc,\ sc/source/core/data/sheetevents \ sc/source/core/data/simpleformulacalc \ sc/source/core/data/sortparam \ - sc/source/core/data/Sparkline \ sc/source/core/data/stlpool \ sc/source/core/data/stlsheet \ sc/source/core/data/subtotalparam \ diff --git a/sc/inc/Sparkline.hxx b/sc/inc/Sparkline.hxx index 8969fa3bfd3e..89ca26ec62df 100644 --- a/sc/inc/Sparkline.hxx +++ b/sc/inc/Sparkline.hxx @@ -19,22 +19,60 @@ namespace sc { class SC_DLLPUBLIC Sparkline { -private: ScRangeList m_aInputRange; std::shared_ptr<SparklineGroup> m_pSparklineGroup; public: - Sparkline(std::shared_ptr<SparklineGroup>& pSparklineGroup); + Sparkline(std::shared_ptr<SparklineGroup> const& pSparklineGroup) + : m_pSparklineGroup(pSparklineGroup) + { + } Sparkline(const Sparkline&) = delete; Sparkline& operator=(const Sparkline&) = delete; void setInputRange(ScRangeList const& rInputRange) { m_aInputRange = rInputRange; } + ScRangeList const& getInputRange() { return m_aInputRange; } std::shared_ptr<SparklineGroup> const& getSparklineGroup() { return m_pSparklineGroup; } }; +class SC_DLLPUBLIC SparklineList +{ +private: + std::vector<std::weak_ptr<Sparkline>> m_pSparklines; + +public: + SparklineList() {} + + void addSparkline(std::shared_ptr<Sparkline> const& pSparkline) + { + m_pSparklines.push_back(pSparkline); + } + + std::vector<std::shared_ptr<Sparkline>> getSparklines() + { + std::vector<std::shared_ptr<Sparkline>> toReturn; + + std::vector<std::weak_ptr<Sparkline>>::iterator aIter; + for (aIter = m_pSparklines.begin(); aIter != m_pSparklines.end();) + { + if (auto aSparkline = aIter->lock()) + { + toReturn.push_back(aSparkline); + aIter++; + } + else + { + aIter = m_pSparklines.erase(aIter); + } + } + + return toReturn; + } +}; + } // end sc /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/inc/SparklineCell.hxx b/sc/inc/SparklineCell.hxx new file mode 100644 index 000000000000..0aca857170c9 --- /dev/null +++ b/sc/inc/SparklineCell.hxx @@ -0,0 +1,47 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + */ + +#pragma once + +#include "scdllapi.h" +#include "Sparkline.hxx" +#include <memory> + +namespace sc +{ +class SC_DLLPUBLIC SparklineCell +{ +private: + std::shared_ptr<Sparkline> m_pSparkline; + +public: + SparklineCell(std::shared_ptr<Sparkline> const& pSparkline) + : m_pSparkline(pSparkline) + { + } + + SparklineCell(const SparklineCell&) = delete; + SparklineCell& operator=(const SparklineCell&) = delete; + + void setInputRange(ScRangeList const& rInputRange) { m_pSparkline->setInputRange(rInputRange); } + + ScRangeList const& getInputRange() { return m_pSparkline->getInputRange(); } + + std::shared_ptr<SparklineGroup> const& getSparklineGroup() + { + return m_pSparkline->getSparklineGroup(); + } + + std::shared_ptr<Sparkline> const& getSparkline() { return m_pSparkline; } +}; + +} // end sc + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index 4c711b9944dc..17e0d61f79c4 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -617,8 +617,8 @@ public: void BroadcastRows( SCROW nStartRow, SCROW nEndRow, SfxHintId nHint ); // Spaklines - sc::Sparkline* GetSparkline(SCROW nRow); - void SetSparkline(SCROW nRow, std::unique_ptr<sc::Sparkline> pSparkline); + sc::SparklineCell* GetSparklineCell(SCROW nRow); + void CreateSparklineCell(SCROW nRow, std::shared_ptr<sc::Sparkline> const& pSparkline); // cell notes ScPostIt* GetCellNote( SCROW nRow ); diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index d0ef2006846e..84ee8184d2e9 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -103,6 +103,7 @@ class ColumnIterator; class ExternalDataMapper; class Sparkline; class SparklineGroup; +class SparklineList; } @@ -1240,6 +1241,7 @@ public: /** Spaklines */ SC_DLLPUBLIC sc::Sparkline* GetSparkline(ScAddress const & rPosition); SC_DLLPUBLIC sc::Sparkline* CreateSparkline(ScAddress const & rPosition, std::shared_ptr<sc::SparklineGroup> & pSparklineGroup); + SC_DLLPUBLIC sc::SparklineList* GetSparklineList(SCTAB nTab); /** Notes **/ SC_DLLPUBLIC ScPostIt* GetNote(const ScAddress& rPos); diff --git a/sc/inc/mtvelements.hxx b/sc/inc/mtvelements.hxx index 979a09c641db..c60a8832c8df 100644 --- a/sc/inc/mtvelements.hxx +++ b/sc/inc/mtvelements.hxx @@ -15,7 +15,7 @@ #include <editeng/editobj.hxx> #include "calcmacros.hxx" #include "postit.hxx" -#include "Sparkline.hxx" +#include "SparklineCell.hxx" #include "celltextattr.hxx" #if DEBUG_COLUMN_STORAGE @@ -59,7 +59,7 @@ const mdds::mtv::element_t element_type_uint16 = mdds::mtv::element_type_uint16; /// Custom element blocks. -typedef mdds::mtv::noncopyable_managed_element_block<element_type_sparkline, sc::Sparkline> sparkline_block; +typedef mdds::mtv::noncopyable_managed_element_block<element_type_sparkline, sc::SparklineCell> sparkline_block; typedef mdds::mtv::noncopyable_managed_element_block<element_type_cellnote, ScPostIt> cellnote_block; typedef mdds::mtv::noncopyable_managed_element_block<element_type_broadcaster, SvtBroadcaster> broadcaster_block; typedef mdds::mtv::default_element_block<element_type_celltextattr, CellTextAttr> celltextattr_block; @@ -77,7 +77,7 @@ typedef mdds::mtv::uint16_element_block uint16_block; /// For example sc types like sc::CellTextAttr, ScFormulaCell in global namespace. namespace sc { MDDS_MTV_DEFINE_ELEMENT_CALLBACKS(CellTextAttr, element_type_celltextattr, CellTextAttr(), celltextattr_block) -MDDS_MTV_DEFINE_ELEMENT_CALLBACKS_PTR(Sparkline, sc::element_type_sparkline, nullptr, sc::sparkline_block) +MDDS_MTV_DEFINE_ELEMENT_CALLBACKS_PTR(SparklineCell, sc::element_type_sparkline, nullptr, sc::sparkline_block) } /// These need to be in global namespace just like their respective types are. diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx index 30c92cd87520..534da038bf54 100644 --- a/sc/inc/table.hxx +++ b/sc/inc/table.hxx @@ -227,6 +227,7 @@ private: mutable std::unique_ptr<ScRangeName> mpRangeName; std::unique_ptr<ScConditionalFormatList> mpCondFormatList; + sc::SparklineList maSparklineList; ScAddress maLOKFreezeCell; @@ -472,6 +473,14 @@ public: void GetFirstDataPos(SCCOL& rCol, SCROW& rRow) const; void GetLastDataPos(SCCOL& rCol, SCROW& rRow) const; + // Sparklines + + sc::Sparkline* GetSparkline(SCCOL nCol, SCROW nRow); + sc::Sparkline* CreateSparkline(SCCOL nCol, SCROW nRow, std::shared_ptr<sc::SparklineGroup> & pSparklineGroup); + + sc::SparklineList& GetSparklineList(); + + // Notes / Comments std::unique_ptr<ScPostIt> ReleaseNote( SCCOL nCol, SCROW nRow ); ScPostIt* GetNote( SCCOL nCol, SCROW nRow ); void SetNote( SCCOL nCol, SCROW nRow, std::unique_ptr<ScPostIt> pNote ); diff --git a/sc/source/core/data/Sparkline.cxx b/sc/source/core/data/Sparkline.cxx deleted file mode 100644 index 301fda820ff2..000000000000 --- a/sc/source/core/data/Sparkline.cxx +++ /dev/null @@ -1,22 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - */ - -#include <memory> -#include <Sparkline.hxx> - -namespace sc -{ -Sparkline::Sparkline(std::shared_ptr<SparklineGroup>& pSparklineGroup) - : m_pSparklineGroup(pSparklineGroup) -{ -} -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx index 9eb661e49d9d..d391c4baaeae 100644 --- a/sc/source/core/data/column2.cxx +++ b/sc/source/core/data/column2.cxx @@ -1977,14 +1977,14 @@ void ScColumn::PrepareBroadcastersForDestruction() } } -sc::Sparkline* ScColumn::GetSparkline(SCROW nRow) +sc::SparklineCell* ScColumn::GetSparklineCell(SCROW nRow) { - return maSparklines.get<sc::Sparkline*>(nRow); + return maSparklines.get<sc::SparklineCell*>(nRow); } -void ScColumn::SetSparkline(SCROW nRow, std::unique_ptr<sc::Sparkline> pSparkline) +void ScColumn::CreateSparklineCell(SCROW nRow, std::shared_ptr<sc::Sparkline> const& pSparkline) { - maSparklines.set(nRow, pSparkline.release()); + maSparklines.set(nRow, new sc::SparklineCell(pSparkline)); } ScPostIt* ScColumn::GetCellNote(SCROW nRow) diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index 7f1eeab2d12a..88b1d7ce12b9 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -6513,33 +6513,41 @@ bool ScDocument::IsInVBAMode() const return false; } +// Sparklines sc::Sparkline* ScDocument::GetSparkline(ScAddress const& rPosition) { SCTAB nTab = rPosition.Tab(); - SCCOL nCol = rPosition.Col(); - if (ValidTab(nTab) && nTab < SCTAB(maTabs.size()) && - nCol < maTabs[nTab]->GetAllocatedColumnsCount()) + if (ValidTab(nTab) && nTab < SCTAB(maTabs.size())) { - SCROW nRow = rPosition.Row(); - return maTabs[nTab]->aCol[nCol].GetSparkline(nRow); + return maTabs[nTab]->GetSparkline(rPosition.Col(), rPosition.Row()); } return nullptr; } sc::Sparkline* ScDocument::CreateSparkline(ScAddress const & rPosition, std::shared_ptr<sc::SparklineGroup> & pSparklineGroup) { - std::unique_ptr<sc::Sparkline> pSparkline(new sc::Sparkline(pSparklineGroup)); - sc::Sparkline* pCreated = pSparkline.get(); - SCTAB nTab = rPosition.Tab(); - SCCOL nCol = rPosition.Col(); - SCROW nRow = rPosition.Row(); - maTabs[nTab]->CreateColumnIfNotExists(nCol).SetSparkline(nRow, std::move(pSparkline)); - return pCreated; + if (ValidTab(nTab) && nTab < SCTAB(maTabs.size())) + { + return maTabs[nTab]->CreateSparkline(rPosition.Col(), rPosition.Row(), pSparklineGroup); + } + + return nullptr; +} + +sc::SparklineList* ScDocument::GetSparklineList(SCTAB nTab) +{ + if (ValidTab(nTab) && nTab < SCTAB(maTabs.size())) + { + return &maTabs[nTab]->GetSparklineList(); + } + return nullptr; } +// Notes + ScPostIt* ScDocument::GetNote(const ScAddress& rPos) { return GetNote(rPos.Col(), rPos.Row(), rPos.Tab()); diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index e0753b15d252..3770a75fd012 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -1809,6 +1809,42 @@ ScFormulaCell* ScTable::GetFormulaCell( SCCOL nCol, SCROW nRow ) return aCol[nCol].GetFormulaCell(nRow); } +// Sparklines + +sc::Sparkline* ScTable::GetSparkline(SCCOL nCol, SCROW nRow) +{ + if (!ValidCol(nCol) || nCol >= GetAllocatedColumnsCount()) + return nullptr; + + sc::SparklineCell* pSparklineCell = aCol[nCol].GetSparklineCell(nRow); + if (!pSparklineCell) + return nullptr; + + std::shared_ptr<sc::Sparkline> pSparkline(pSparklineCell->getSparkline()); + assert(pSparkline); + + return pSparkline.get(); +} + +sc::Sparkline* ScTable::CreateSparkline(SCCOL nCol, SCROW nRow, std::shared_ptr<sc::SparklineGroup>& pSparklineGroup) +{ + if (!ValidCol(nCol)) + return nullptr; + + ScColumn& rColumn = CreateColumnIfNotExists(nCol); + + std::shared_ptr<sc::Sparkline> pSparkline(new sc::Sparkline(pSparklineGroup)); + rColumn.CreateSparklineCell(nRow, pSparkline); + return pSparkline.get(); +} + +sc::SparklineList& ScTable::GetSparklineList() +{ + return maSparklineList; +} + +// Notes + std::unique_ptr<ScPostIt> ScTable::ReleaseNote( SCCOL nCol, SCROW nRow ) { if (!ValidCol(nCol) || nCol >= GetAllocatedColumnsCount())