sc/Library_sc.mk | 1 sc/inc/Sparkline.hxx | 46 ++++++++++++++++++++++++++++++++++++++ sc/inc/SparklineGroup.hxx | 30 ++++++++++++++++++++++++ sc/inc/column.hxx | 10 +++++++- sc/inc/document.hxx | 7 +++++ sc/inc/mtvelements.hxx | 16 ++++++++++--- sc/source/core/data/Sparkline.cxx | 22 ++++++++++++++++++ sc/source/core/data/column.cxx | 5 ++++ sc/source/core/data/column2.cxx | 10 ++++++++ sc/source/core/data/column3.cxx | 3 ++ sc/source/core/data/document.cxx | 27 ++++++++++++++++++++++ 11 files changed, 173 insertions(+), 4 deletions(-)
New commits: commit e51784458bc46411d739877707f7952dd6808fa2 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> AuthorDate: Wed Feb 23 09:52:50 2022 +0900 Commit: Tomaž Vajngerl <qui...@gmail.com> CommitDate: Tue Mar 8 10:09:14 2022 +0100 sc: add Sparkline to the model as a column multi_type_vector This adds a Sparkline class and a SparklineGroup class. The Sparkline class is added to a cell, and the SparklineGroup is referenced by the Sparkline, so multiple Sparklines can share the same properties. Change-Id: Id309ded34bfa7a35c1be43f7c0543d88594e66ff Reviewed-on: https://gerrit.libreoffice.org/c/core/+/131162 Tested-by: Tomaž Vajngerl <qui...@gmail.com> Reviewed-by: Tomaž Vajngerl <qui...@gmail.com> diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk index 62ab22a797c4..11449217edd9 100644 --- a/sc/Library_sc.mk +++ b/sc/Library_sc.mk @@ -185,6 +185,7 @@ $(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 new file mode 100644 index 000000000000..c8bb4d1baa22 --- /dev/null +++ b/sc/inc/Sparkline.hxx @@ -0,0 +1,46 @@ +/* -*- 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 "SparklineGroup.hxx" +#include "rangelst.hxx" +#include <memory> + +namespace sc +{ +/** Sparkline data, used for rendering the content of a cell + * + * Contains the input range of the data that is being drawn and a reference + * to the SparklineGroup, which inclues common properties of multiple + * sparklines. + */ +class SC_DLLPUBLIC Sparkline +{ +private: + ScRangeList m_aInputRange; + std::shared_ptr<SparklineGroup> m_pSparklineGroup; + +public: + Sparkline(std::shared_ptr<SparklineGroup>& 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; } +}; + +} // end sc + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/inc/SparklineGroup.hxx b/sc/inc/SparklineGroup.hxx new file mode 100644 index 000000000000..6d98e1b2dcbf --- /dev/null +++ b/sc/inc/SparklineGroup.hxx @@ -0,0 +1,30 @@ +/* -*- 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 <optional> + +namespace sc +{ +/** Common properties for a group of sparklines */ +class SC_DLLPUBLIC SparklineGroup +{ +public: + SparklineGroup() {} + + SparklineGroup(const SparklineGroup&) = delete; + SparklineGroup& operator=(const SparklineGroup&) = delete; +}; + +} // end sc + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index 55cf70e09d7f..503cbaebddb1 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -65,6 +65,7 @@ class CompileFormulaContext; struct SetFormulaDirtyContext; enum class MatrixEdge; class ColumnIterator; +class Sparkline; } @@ -99,7 +100,7 @@ struct ScInterpreterContext; struct ScNeededSizeOptions { - const ScPatternAttr* pPattern; + const ScPatternAttr* pPattern; bool bFormula; bool bSkipMerged; bool bGetFont; @@ -173,6 +174,9 @@ class ScColumn : protected ScColumnData // Cell values. sc::CellStoreType maCells; + // Sparklines + sc::SparklineStoreType maSparklines; + size_t mnBlkCountFormula; SCCOL nCol; @@ -640,6 +644,10 @@ public: void BroadcastCells( const std::vector<SCROW>& rRows, SfxHintId nHint ); void BroadcastRows( SCROW nStartRow, SCROW nEndRow, SfxHintId nHint ); + // Spaklines + sc::Sparkline* GetSparkline(SCROW nRow); + void SetSparkline(SCROW nRow, std::unique_ptr<sc::Sparkline> pSparkline); + // cell notes ScPostIt* GetCellNote( SCROW nRow ); const ScPostIt* GetCellNote( SCROW nRow ) const; diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index bca8c4bea5f5..8870e607638d 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -101,6 +101,8 @@ class UpdatedRangeNames; class TableColumnBlockPositionSet; class ColumnIterator; class ExternalDataMapper; +class Sparkline; +class SparklineGroup; } @@ -1241,6 +1243,10 @@ public: */ sc::MultiDataCellState HasMultipleDataCells( const ScRange& rRange ) const; + /** Spaklines */ + SC_DLLPUBLIC sc::Sparkline* GetSparkline(ScAddress const & rPosition); + SC_DLLPUBLIC sc::Sparkline* CreateSparkline(ScAddress const & rPosition, std::shared_ptr<sc::SparklineGroup> & pSparklineGroup); + /** Notes **/ SC_DLLPUBLIC ScPostIt* GetNote(const ScAddress& rPos); SC_DLLPUBLIC ScPostIt* GetNote(SCCOL nCol, SCROW nRow, SCTAB nTab); @@ -1272,6 +1278,7 @@ public: SC_DLLPUBLIC void GetAllNoteEntries( std::vector<sc::NoteEntry>& rNotes ) const; SC_DLLPUBLIC void GetAllNoteEntries( SCTAB nTab, std::vector<sc::NoteEntry>& rNotes ) const; void GetNotesInRange( const ScRangeList& rRange, std::vector<sc::NoteEntry>& rNotes ) const; + bool ContainsNotesInRange( const ScRangeList& rRange ) const; SC_DLLPUBLIC void SetDrawPageSize(SCTAB nTab); diff --git a/sc/inc/mtvelements.hxx b/sc/inc/mtvelements.hxx index c74e1bc7d91b..6de0f3e7ec23 100644 --- a/sc/inc/mtvelements.hxx +++ b/sc/inc/mtvelements.hxx @@ -15,6 +15,7 @@ #include <editeng/editobj.hxx> #include "calcmacros.hxx" #include "postit.hxx" +#include "Sparkline.hxx" #include "celltextattr.hxx" #if DEBUG_COLUMN_STORAGE @@ -49,6 +50,7 @@ const mdds::mtv::element_t element_type_edittext = mdds::mtv::element_type_user_ const mdds::mtv::element_t element_type_formula = mdds::mtv::element_type_user_start + 4; const mdds::mtv::element_t element_type_cellnote = mdds::mtv::element_type_user_start + 5; +const mdds::mtv::element_t element_type_sparkline = mdds::mtv::element_type_user_start + 6; /// Mapped standard element types (for convenience). const mdds::mtv::element_t element_type_numeric = mdds::mtv::element_type_double; @@ -57,6 +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_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; @@ -68,8 +71,13 @@ typedef mdds::mtv::noncopyable_managed_element_block<element_type_formula, ScFor typedef mdds::mtv::double_element_block numeric_block; typedef mdds::mtv::uint16_element_block uint16_block; -/// This needs to be in the same namespace as CellTextAttr. +} // end sc namespace + +/// CAUTION! The following defines must be in the same namespace as the respective type. +/// 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) } /// These need to be in global namespace just like their respective types are. @@ -79,9 +87,7 @@ MDDS_MTV_DEFINE_ELEMENT_CALLBACKS_PTR(ScFormulaCell, sc::element_type_formula, n MDDS_MTV_DEFINE_ELEMENT_CALLBACKS_PTR(EditTextObject, sc::element_type_edittext, nullptr, sc::edittext_block) namespace svl { - MDDS_MTV_DEFINE_ELEMENT_CALLBACKS(SharedString, sc::element_type_string, SharedString(), sc::string_block) - } namespace sc { @@ -110,6 +116,10 @@ struct CellStoreTrait static constexpr mdds::mtv::lu_factor_t loop_unrolling = mdds::mtv::lu_factor_t::lu16; }; +/// Sparkline container +typedef mdds::mtv::custom_block_func1<sc::sparkline_block> CSparklineFunction; +typedef mdds::mtv::soa::multi_type_vector<CSparklineFunction> SparklineStoreType; + /// Cell note container typedef mdds::mtv::custom_block_func1<sc::cellnote_block> CNoteFunc; typedef mdds::mtv::soa::multi_type_vector<CNoteFunc> CellNoteStoreType; diff --git a/sc/source/core/data/Sparkline.cxx b/sc/source/core/data/Sparkline.cxx new file mode 100644 index 000000000000..301fda820ff2 --- /dev/null +++ b/sc/source/core/data/Sparkline.cxx @@ -0,0 +1,22 @@ +/* -*- 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/column.cxx b/sc/source/core/data/column.cxx index 0598a24858e0..d75d9885fba6 100644 --- a/sc/source/core/data/column.cxx +++ b/sc/source/core/data/column.cxx @@ -84,6 +84,7 @@ ScColumn::ScColumn(ScSheetLimits const & rSheetLimits) : maCellNotes(rSheetLimits.GetMaxRowCount()), maBroadcasters(rSheetLimits.GetMaxRowCount()), maCells(sc::CellStoreEvent(this)), + maSparklines(rSheetLimits.GetMaxRowCount()), mnBlkCountFormula(0), nCol( 0 ), nTab( 0 ), @@ -776,6 +777,9 @@ void ScColumn::InsertRow( SCROW nStartRow, SCSIZE nSize ) maCellNotes.insert_empty(nStartRow, nSize); maCellNotes.resize(GetDoc().GetMaxRowCount()); + maSparklines.insert_empty(nStartRow, nSize); + maSparklines.resize(GetDoc().GetSheetLimits().GetMaxRowCount()); + maBroadcasters.insert_empty(nStartRow, nSize); maBroadcasters.resize(GetDoc().GetMaxRowCount()); @@ -1872,6 +1876,7 @@ void ScColumn::SwapCol(ScColumn& rCol) maCells.swap(rCol.maCells); maCellTextAttrs.swap(rCol.maCellTextAttrs); maCellNotes.swap(rCol.maCellNotes); + maSparklines.swap(rCol.maSparklines); // Swap all CellStoreEvent mdds event_func related. maCells.event_handler().swap(rCol.maCells.event_handler()); diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx index bf1b43d10f39..3eabc08a387c 100644 --- a/sc/source/core/data/column2.cxx +++ b/sc/source/core/data/column2.cxx @@ -1970,6 +1970,16 @@ void ScColumn::PrepareBroadcastersForDestruction() } } +sc::Sparkline* ScColumn::GetSparkline(SCROW nRow) +{ + return maSparklines.get<sc::Sparkline*>(nRow); +} + +void ScColumn::SetSparkline(SCROW nRow, std::unique_ptr<sc::Sparkline> pSparkline) +{ + maSparklines.set(nRow, pSparkline.release()); +} + namespace { struct BroadcasterNoListenersPredicate diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx index 31903287cd48..8d38fa54ea45 100644 --- a/sc/source/core/data/column3.cxx +++ b/sc/source/core/data/column3.cxx @@ -150,6 +150,7 @@ void ScColumn::Delete( SCROW nRow ) DeleteContent(nRow, false); maCellTextAttrs.set_empty(nRow, nRow); maCellNotes.set_empty(nRow, nRow); + maSparklines.set_empty(nRow, nRow); Broadcast(nRow); CellStorageModified(); @@ -167,6 +168,8 @@ void ScColumn::FreeAll() maCellTextAttrs.resize(maxRowCount); maCellNotes.clear(); maCellNotes.resize(maxRowCount); + maSparklines.clear(); + maSparklines.resize(maxRowCount); CellStorageModified(); } diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index 5973bf913366..3ec08575a713 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -6514,6 +6514,33 @@ bool ScDocument::IsInVBAMode() const return false; } +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()) + { + SCROW nRow = rPosition.Row(); + return maTabs[nTab]->aCol[nCol].GetSparkline(nRow); + } + 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; +} + ScPostIt* ScDocument::GetNote(const ScAddress& rPos) { return GetNote(rPos.Col(), rPos.Row(), rPos.Tab());