include/svl/itempool.hxx | 2 include/svl/poolitem.hxx | 3 sc/inc/attarray.hxx | 54 +-- sc/inc/column.hxx | 26 - sc/inc/docpool.hxx | 6 sc/inc/document.hxx | 16 sc/inc/global.hxx | 2 sc/inc/patattr.hxx | 132 +++++--- sc/inc/poolcach.hxx | 28 - sc/inc/scitems.hxx | 80 ++-- sc/inc/table.hxx | 4 sc/qa/unit/subsequent_export_test.cxx | 2 sc/qa/unit/subsequent_export_test4.cxx | 4 sc/qa/unit/subsequent_filters_test2.cxx | 4 sc/qa/unit/ucalc.cxx | 28 - sc/qa/unit/ucalc_DocumentThemes.cxx | 2 sc/qa/unit/ucalc_copypaste.cxx | 10 sc/qa/unit/ucalc_formula.cxx | 3 sc/source/core/data/attarray.cxx | 422 +++++++++++--------------- sc/source/core/data/column.cxx | 71 ++-- sc/source/core/data/column2.cxx | 21 - sc/source/core/data/column3.cxx | 6 sc/source/core/data/column4.cxx | 18 - sc/source/core/data/dociter.cxx | 8 sc/source/core/data/docpool.cxx | 69 ---- sc/source/core/data/documen2.cxx | 18 + sc/source/core/data/documen4.cxx | 3 sc/source/core/data/document.cxx | 57 --- sc/source/core/data/document10.cxx | 4 sc/source/core/data/drwlayer.cxx | 2 sc/source/core/data/fillinfo.cxx | 4 sc/source/core/data/global.cxx | 18 - sc/source/core/data/patattr.cxx | 340 +++++++++++++++++--- sc/source/core/data/poolcach.cxx | 85 +---- sc/source/core/data/stlpool.cxx | 3 sc/source/core/data/table2.cxx | 39 +- sc/source/core/data/table3.cxx | 48 +- sc/source/core/data/table4.cxx | 6 sc/source/core/data/validat.cxx | 2 sc/source/core/tool/ddelink.cxx | 4 sc/source/core/tool/editutil.cxx | 3 sc/source/core/tool/interpr1.cxx | 2 sc/source/filter/dif/difimp.cxx | 2 sc/source/filter/excel/xehelper.cxx | 8 sc/source/filter/excel/xestyle.cxx | 5 sc/source/filter/excel/xicontent.cxx | 2 sc/source/filter/excel/xistyle.cxx | 10 sc/source/filter/inc/xistyle.hxx | 2 sc/source/filter/lotus/lotattr.cxx | 4 sc/source/filter/lotus/op.cxx | 2 sc/source/filter/oox/sheetdatabuffer.cxx | 7 sc/source/filter/oox/stylesbuffer.cxx | 14 sc/source/filter/orcus/interface.cxx | 8 sc/source/filter/qpro/qprostyle.cxx | 2 sc/source/filter/rtf/eeimpars.cxx | 7 sc/source/filter/xml/xmlcelli.cxx | 2 sc/source/filter/xml/xmlimprt.cxx | 4 sc/source/ui/Accessibility/AccessibleText.cxx | 24 + sc/source/ui/app/inputhdl.cxx | 4 sc/source/ui/app/scmod.cxx | 3 sc/source/ui/cctrl/dpcontrol.cxx | 2 sc/source/ui/docshell/arealink.cxx | 2 sc/source/ui/docshell/dbdocimp.cxx | 2 sc/source/ui/docshell/docfunc.cxx | 6 sc/source/ui/docshell/docsh.cxx | 2 sc/source/ui/docshell/docsh2.cxx | 2 sc/source/ui/docshell/docsh3.cxx | 6 sc/source/ui/docshell/docsh5.cxx | 4 sc/source/ui/docshell/docsh6.cxx | 4 sc/source/ui/docshell/docsh8.cxx | 2 sc/source/ui/docshell/impex.cxx | 2 sc/source/ui/inc/undoblk.hxx | 7 sc/source/ui/inc/undocell.hxx | 8 sc/source/ui/pagedlg/scuitphfedit.cxx | 10 sc/source/ui/undo/undoblk.cxx | 4 sc/source/ui/undo/undoblk3.cxx | 34 -- sc/source/ui/undo/undocell.cxx | 27 - sc/source/ui/undo/undostyl.cxx | 2 sc/source/ui/unoobj/cellsuno.cxx | 14 sc/source/ui/unoobj/docuno.cxx | 3 sc/source/ui/unoobj/funcuno.cxx | 2 sc/source/ui/unoobj/styleuno.cxx | 4 sc/source/ui/unoobj/textuno.cxx | 29 + sc/source/ui/vba/vbarange.cxx | 3 sc/source/ui/view/dbfunc3.cxx | 2 sc/source/ui/view/formatsh.cxx | 8 sc/source/ui/view/gridwin4.cxx | 5 sc/source/ui/view/output2.cxx | 8 sc/source/ui/view/preview.cxx | 3 sc/source/ui/view/printfun.cxx | 7 sc/source/ui/view/spelleng.cxx | 14 sc/source/ui/view/tabvwsha.cxx | 8 sc/source/ui/view/viewfun2.cxx | 4 sc/source/ui/view/viewfunc.cxx | 19 - svl/source/items/itempool.cxx | 22 - svl/source/items/itemset.cxx | 41 -- svl/source/items/poolitem.cxx | 1 97 files changed, 1085 insertions(+), 1007 deletions(-)
New commits: commit 2e1f9da8a6359c8909e087a92239aefd4851b116 Author: Armin Le Grand (allotropia) <armin.le.grand.ext...@allotropia.de> AuthorDate: Sat Dec 23 15:52:06 2023 +0100 Commit: Armin Le Grand <armin.le.gr...@me.com> CommitDate: Thu Dec 28 19:38:15 2023 +0100 Decouple ScPatternAttr from SfxItemPool ScPatternAttr is traditionally derived from SfxPoolItem (or better: SfxSetItem) and held in the ScDocumentPool as Item. This is only because of 'using' the 'poolable' functionality of the Item/ItemSet/ItemPool mechanism. Lots of hacks were added to sc and Item/ItemSet/ ItemPool to make that 'work' which shows already that this relationship is not optimal. It uses DirectPutItemInPool/DirectRemoveItemFromPool to do so, also with massive overhead to do that (and with not much success). The RefCnt in the SfxPoolItem that is used for this never worked reliably, so the SfxItemPool was (ab)used as garbage collector (all Items added and never removed get deleted at last for good when the Pool goes down). For this reasons and to be able to further get ItemSets modernized I changed this. I did two big changes here: (1) No longer derive ScPatternAttr from SfxItemSet/ SfxSetItem, no longer hold as SfxPoolItem (2) Add tooling to reliably control the lifetime of ScPatternAttr instances and ther uniqueness/ reusage for memory reasons It is now a regular non-derived class. The SfxItemSet formally derived from SfxSetItem is now a member. The RefCnt is now also a member (so independent from size/data type of SfxPoolItem). All in all it's pretty much the same size as before. To support handling it I created a CellAttributeHelper that is at/owned by ScDocument and takes over tooling to handle the ScPatternAttr. It supports to guarantee the uniqueness of incarnated ScPatternAttr instances for a ScDocument by providing helpers like registerAndCheck and doUnregister. It hosts the default CellAttribute/ ScPatternAttr. That default handling was anyways not using the standard default-handling of Items/Pools. I adapted whole SC to use that mainly by replacing calls to DirectPutItemInPool with registerAndCheck and DirectRemoveItemFromPool with doUnregister, BUT: This was not sufficient, the RefCnt kept to be broken. For that reason I decided to also do (2) in this change: I added a CellAttributeHolder that owns/regulates the lifetime of a single ScPatternAttr. Originally it also contained the CellAttributeHolder, but after some thoughts I decided that this is not needed - if there is no ScPatternAttr set, no CellAttributeHolder is needed for safe cleanup at destruction of the helper. So I moved/added the CellAttributeHolder to ScPatternAttr where it belongs more naturally anyways. The big plus is that CellAttributeHolder is just one ptr, so not bigger than having a simple ScPatternAttr*. That way, e.g. ScAttrEntry in ScAttrArray did not 'grow' at all. In principle all places where a ScPatternAttr* is used can now be replaced by using a CellAttributeHolder, except for construction. It is capable to be initialized with either ScPatternAttr instances from the heap (it creates a copy that then gets RefCounted) or allocated (it supports ownership change at construction time). Note that ScAttrEntry started to get more a C++ class in that change, it has a constructor. I did not change the SCROW member, but that should also be done. Also made registerAndCheck/doUnregister private in CellAttributeHelper and exclusively used by CellAttributeHolder. That way the RefCnt works, and a lot of code gets much simpler (check ScItemPoolCache, it's now straightforward) and safer and ~ScPatternAttr() uses now a hard assert(!isRegistered()); which shows that RefCnt works now (the 1st time?). There can be done more (see ToDo section below) but I myself will concentrate on getting ItemSets forward. This decoupling makes both involved mechanisms more safe, less complex and more stable. It also opens up possibilities to further optimize ScPatternAttr in SC without further hacking Item/ItemSet/ItemPool stuff. NOTE: ScPatternAttr *should* be renamed to 'CellAttribute' which describes what it is. The experiencd devs may know what it does, but it is a hindrance for understanding for attacting new devs. I already used now names like CellAttributeHelper/CellAttributeHolder etc., but abstained from renaming ScPatternAttr, see ToDo list below. SfxItemSet discussion: ScPatternAttr still contains a SfxItemSet, or better, a SfxSetItem. For that reason it still depends on access to an SfxItemPool (so there is acces in CellAttributeHelper). This is in principle not needed - no Item (in the range [ATTR_PATTERN_START .. ATTR_PATTERN_END]) needs that. In principle ScPatternAttr could now do it's own handling of those needed Items, however this might be done (linear array, hash-by-WhichID, ...). The Items get translated to and from this to the rest of the office anyways. Note that *merging* of SfxItemSets is *still* needed what means to have WhichID slots in SfxItemState::DONTCARE, see note in ScPatternAttr::ScPatternAttr about that. And there is also the Surrogates stuff which would have to be checked. The other extreme is to use SfxItemSet *more*, e.g. directly derive from SfxItemSet what would make stuff easier, maybe even get back to using the 'regular' Items like all office, I doubt that that would be much slower, so why...? Also possible is to remove that range of Items exclusively used by ScPatternAttr from ScDocumentPool *completely* and create an own Pool for them, owned by CellAttributeHelper. That Pool might even be static global, so all SC Docs could share all those Items - maybe even the ScPatternAttr themselves (except the default per document). That would remove the dependency of ScPatternAttr from a Pool completely. ToDo-List: - rename ScPatternAttr to CellAttribute or similar - use SfxItemSetFixed with range [ATTR_PATTERN_START .. ATTR_PATTERN_END] instead of regular SfxItemSet (if the copy-construtor works now...?) - maybe create own/separate Pool for exclusive Items - make ScAttrEntry more a C++ class by moving SCROW to the private section, add get/set methods and adapt SC Had to add some more usages of CellAttributeHolder to the SC Sort mechanism, there were situations where the sorted ScPatternAttr were replaced in the Table, but the 'sorted' ones were just ScPatternAttr*, thus deleting the valid ones in the Table already. Using CellAttributeHolder makes this safe, too. Added a small, one-entry cache to CellAttributeHelper to buffer the last found buffered ScPattrnAttr. It has a HitRate of ca. 5-6% and brings the UnitTest testSheetCellRangeProperties from 0m48,710s to 0m37,556s. Not too massive, but erery bit counts :-) Also shows that after that change optimizations in the now split functionality is possible and easy. Change-Id: I268a7b2a943ce5ddfe3c75b5e648c0f6b0cedb85 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161244 Tested-by: Jenkins Reviewed-by: Armin Le Grand <armin.le.gr...@me.com> diff --git a/include/svl/itempool.hxx b/include/svl/itempool.hxx index f5949f1700c8..2e6c5a9a38d3 100644 --- a/include/svl/itempool.hxx +++ b/include/svl/itempool.hxx @@ -247,8 +247,6 @@ public: protected: const SfxPoolItem& DirectPutItemInPoolImpl( const SfxPoolItem&, sal_uInt16 nWhich = 0, bool bPassingOwnership = false ); - virtual void newItem_Callback(const SfxPoolItem& rItem) const; - virtual bool newItem_UseDirect(const SfxPoolItem& rItem) const; private: const SfxItemPool& operator=(const SfxItemPool &) = delete; diff --git a/include/svl/poolitem.hxx b/include/svl/poolitem.hxx index af993096e655..ce65d63709cf 100644 --- a/include/svl/poolitem.hxx +++ b/include/svl/poolitem.hxx @@ -134,7 +134,6 @@ class SVL_DLLPUBLIC SfxPoolItem bool m_bStaticDefault : 1; // bit 1 bool m_bPoolDefault : 1; // bit 2 bool m_bRegisteredAtPool : 1; // bit 3 - bool m_bExceptionalSCItem : 1; // bit 4 bool m_bIsSetItem : 1; // bit 5 protected: @@ -155,7 +154,6 @@ protected: void setStaticDefault() { m_bStaticDefault = true; } void setPoolDefault() { m_bPoolDefault = true; } void setRegisteredAtPool(bool bNew) { m_bRegisteredAtPool = bNew; } - void setExceptionalSCItem() { m_bExceptionalSCItem = true; } void setIsSetItem() { m_bIsSetItem = true; } public: @@ -174,7 +172,6 @@ public: bool isStaticDefault() const { return m_bStaticDefault; } bool isPoolDefault() const { return m_bPoolDefault; } bool isRegisteredAtPool() const { return m_bRegisteredAtPool; } - bool isExceptionalSCItem() const { return m_bExceptionalSCItem; } bool isSetItem() const { return m_bIsSetItem; } // version that allows nullptrs diff --git a/sc/inc/attarray.hxx b/sc/inc/attarray.hxx index a7e1c08a9f49..c1f9195e6445 100644 --- a/sc/inc/attarray.hxx +++ b/sc/inc/attarray.hxx @@ -67,24 +67,38 @@ struct ScLineFlags struct ScMergePatternState { std::optional<SfxItemSet> pItemSet; - const ScPatternAttr* pOld1; ///< existing objects, temporary - const ScPatternAttr* pOld2; + CellAttributeHolder aOld1; ///< existing objects, temporary + CellAttributeHolder aOld2; bool mbValidPatternId; sal_uInt64 mnPatternId; - ScMergePatternState() : pOld1(nullptr), pOld2(nullptr), + ScMergePatternState() : aOld1(), aOld2(), mbValidPatternId(true), mnPatternId(0) {} }; // we store an array of these where the pattern applies to all rows up till nEndRow -struct ScAttrEntry +class ScAttrEntry { + CellAttributeHolder aPattern; + +public: + ScAttrEntry() + : aPattern() + , nEndRow(0) + {} + SCROW nEndRow; - const ScPatternAttr* pPattern; + + const CellAttributeHolder& getCellAttributeHolder() const { return aPattern; } + void setCellAttributeHolder(const CellAttributeHolder& rNew) { aPattern = rNew; } + + const ScPatternAttr* getScPatternAttr() const { return aPattern.getScPatternAttr(); } + void setScPatternAttr(const ScPatternAttr* pNew, bool bPassingOwnership = false) { aPattern.setScPatternAttr(pNew, bPassingOwnership); } + bool operator==( const ScAttrEntry& other ) const { - return nEndRow == other.nEndRow && SfxPoolItem::areSame(pPattern, other.pPattern); + return nEndRow == other.nEndRow && CellAttributeHolder::areSame(&aPattern, &other.aPattern); } }; @@ -125,7 +139,7 @@ public: #if DEBUG_SC_TESTATTRARRAY void TestData() const; #endif - void Reset( const ScPatternAttr* pPattern); + void Reset(const CellAttributeHolder& rPattern); bool Concat(SCSIZE nPos); const ScPatternAttr* GetPattern( SCROW nRow ) const; @@ -144,18 +158,12 @@ public: void ApplyBlockFrame(const SvxBoxItem& rLineOuter, const SvxBoxInfoItem* pLineInner, SCROW nStartRow, SCROW nEndRow, bool bLeft, SCCOL nDistRight); - void SetPattern( SCROW nRow, const ScPatternAttr* pPattern, bool bPutToPool = false ) - { SetPatternAreaImpl(nRow, nRow, pPattern, bPutToPool, nullptr, /*bPassingOwnership*/false); } - const ScPatternAttr* SetPattern( SCROW nRow, std::unique_ptr<ScPatternAttr> pPattern, bool bPutToPool = false ) - { return SetPatternAreaImpl(nRow, nRow, pPattern.release(), bPutToPool, nullptr, /*bPassingOwnership*/true); } - void SetPatternArea( SCROW nStartRow, SCROW nEndRow, std::unique_ptr<ScPatternAttr> pPattern, - bool bPutToPool = false, ScEditDataArray* pDataArray = nullptr) - { SetPatternAreaImpl(nStartRow, nEndRow, pPattern.release(), bPutToPool, pDataArray, /*bPassingOwnership*/true); } - void SetPatternArea( SCROW nStartRow, SCROW nEndRow, const ScPatternAttr* pPattern, - bool bPutToPool = false, ScEditDataArray* pDataArray = nullptr) - { SetPatternAreaImpl(nStartRow, nEndRow, pPattern, bPutToPool, pDataArray, /*bPassingOwnership*/false); } + void SetPattern( SCROW nRow, const CellAttributeHolder& rPattern ) + { SetPatternAreaImpl(nRow, nRow, rPattern, nullptr); } + void SetPatternArea( SCROW nStartRow, SCROW nEndRow, const CellAttributeHolder& rPattern, ScEditDataArray* pDataArray = nullptr) + { SetPatternAreaImpl(nStartRow, nEndRow, rPattern, pDataArray); } void ApplyStyleArea( SCROW nStartRow, SCROW nEndRow, const ScStyleSheet& rStyle ); - void ApplyCacheArea( SCROW nStartRow, SCROW nEndRow, ScItemPoolCache* pCache, + void ApplyCacheArea( SCROW nStartRow, SCROW nEndRow, ScItemPoolCache& rCache, ScEditDataArray* pDataArray = nullptr, bool* const pIsChanged = nullptr ); void SetAttrEntries(std::vector<ScAttrEntry> && vNewData); void ApplyLineStyleArea( SCROW nStartRow, SCROW nEndRow, @@ -196,8 +204,7 @@ public: void FindStyleSheet( const SfxStyleSheetBase* pStyleSheet, ScFlatBoolRowSegments& rUsedRows, bool bReset ); bool IsStyleSheetUsed( const ScStyleSheet& rStyle ) const; - void SetPatternAreaSafe( SCROW nStartRow, SCROW nEndRow, - const ScPatternAttr* pWantedPattern, bool bDefault ); + void SetPatternAreaSafe( SCROW nStartRow, SCROW nEndRow, const CellAttributeHolder& rWantedPattern ); void CopyAreaSafe( SCROW nStartRow, SCROW nEndRow, tools::Long nDy, ScAttrArray& rAttrArray ); bool IsEmpty() const; @@ -227,9 +234,8 @@ public: SCSIZE Count( SCROW nRow1, SCROW nRow2 ) const; private: - const ScPatternAttr* SetPatternAreaImpl( SCROW nStartRow, SCROW nEndRow, const ScPatternAttr* pPattern, - bool bPutToPool = false, ScEditDataArray* pDataArray = nullptr, - bool bPassingPatternOwnership = false ); + const ScPatternAttr* SetPatternAreaImpl( + SCROW nStartRow, SCROW nEndRow, const CellAttributeHolder& rPattern, ScEditDataArray* pDataArray = nullptr); }; // Iterator for attributes @@ -287,7 +293,7 @@ inline const ScPatternAttr* ScAttrIterator::Next( SCROW& rTop, SCROW& rBottom ) { rTop = nRow; rBottom = std::min( pArray->mvData[nPos].nEndRow, nEndRow ); - pRet = pArray->mvData[nPos].pPattern; + pRet = pArray->mvData[nPos].getScPatternAttr(); nRow = rBottom + 1; ++nPos; } diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index 914199be25b5..87273f0f83ba 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -100,7 +100,8 @@ struct ScInterpreterContext; struct ScNeededSizeOptions { - const ScPatternAttr* pPattern; + CellAttributeHolder aPattern; + bool bFormula; bool bSkipMerged; bool bGetFont; @@ -144,7 +145,7 @@ public: const ScPatternAttr* GetPattern( SCROW nRow ) const; const ScPatternAttr* GetMostUsedPattern( SCROW nStartRow, SCROW nEndRow ) const; - SCROW ApplySelectionCache( ScItemPoolCache* pCache, const ScMarkData& rMark, ScEditDataArray* pDataArray, bool* const pIsChanged, + SCROW ApplySelectionCache( ScItemPoolCache& rCache, const ScMarkData& rMark, ScEditDataArray* pDataArray, bool* const pIsChanged, SCCOL nCol ); void ApplyPatternArea( SCROW nStartRow, SCROW nEndRow, const ScPatternAttr& rPatAttr, ScEditDataArray* pDataArray = nullptr, @@ -541,9 +542,9 @@ public: void ApplyAttr( SCROW nRow, const SfxPoolItem& rAttr ); void ApplyPattern( SCROW nRow, const ScPatternAttr& rPatAttr ); - const ScPatternAttr* SetPattern( SCROW nRow, std::unique_ptr<ScPatternAttr> ); - void SetPattern( SCROW nRow, const ScPatternAttr& ); - void SetPatternArea( SCROW nStartRow, SCROW nEndRow, const ScPatternAttr& ); + void SetPattern( SCROW nRow, const CellAttributeHolder& rHolder ); + void SetPattern( SCROW nRow, const ScPatternAttr& rPattern ); + void SetPatternArea( SCROW nStartRow, SCROW nEndRow, const CellAttributeHolder& ); void ApplyPatternIfNumberformatIncompatible( const ScRange& rRange, const ScPatternAttr& rPattern, SvNumFormatType nNewType ); @@ -575,7 +576,7 @@ public: void RemoveProtected( SCROW nStartRow, SCROW nEndRow ); - SCROW ApplySelectionCache( ScItemPoolCache* pCache, const ScMarkData& rMark, ScEditDataArray* pDataArray, bool* const pIsChanged ); + SCROW ApplySelectionCache( ScItemPoolCache& rCache, const ScMarkData& rMark, ScEditDataArray* pDataArray, bool* const pIsChanged ); void DeleteSelection( InsertDeleteFlags nDelFlag, const ScMarkData& rMark, bool bBroadcast ); void ClearSelectionItems( const sal_uInt16* pWhich, const ScMarkData& rMark ); @@ -1031,20 +1032,19 @@ inline void ScColumn::ClearItems( SCROW nStartRow, SCROW nEndRow, const sal_uInt pAttrArray->ClearItems( nStartRow, nEndRow, pWhich ); } -inline const ScPatternAttr* ScColumn::SetPattern( SCROW nRow, std::unique_ptr<ScPatternAttr> pPatAttr ) +inline void ScColumn::SetPattern( SCROW nRow, const CellAttributeHolder& rHolder ) { - return pAttrArray->SetPattern( nRow, std::move(pPatAttr), true/*bPutToPool*/ ); + return pAttrArray->SetPattern( nRow, rHolder ); } -inline void ScColumn::SetPattern( SCROW nRow, const ScPatternAttr& rPatAttr ) +inline void ScColumn::SetPattern( SCROW nRow, const ScPatternAttr& rPattern ) { - pAttrArray->SetPattern( nRow, &rPatAttr, true/*bPutToPool*/ ); + pAttrArray->SetPattern( nRow, CellAttributeHolder(&rPattern) ); } -inline void ScColumn::SetPatternArea( SCROW nStartRow, SCROW nEndRow, - const ScPatternAttr& rPatAttr ) +inline void ScColumn::SetPatternArea( SCROW nStartRow, SCROW nEndRow, const CellAttributeHolder& rHolder ) { - pAttrArray->SetPatternArea( nStartRow, nEndRow, &rPatAttr, true/*bPutToPool*/ ); + pAttrArray->SetPatternArea( nStartRow, nEndRow, rHolder ); } inline void ScColumnData::SetAttrEntries(std::vector<ScAttrEntry> && vNewData) diff --git a/sc/inc/docpool.hxx b/sc/inc/docpool.hxx index c73d034f2fb2..614e3d4229b8 100644 --- a/sc/inc/docpool.hxx +++ b/sc/inc/docpool.hxx @@ -29,7 +29,6 @@ class ScDocument; class SC_DLLPUBLIC ScDocumentPool final : public SfxItemPool { std::vector<SfxPoolItem*> mvPoolDefaults; - sal_uInt64 mnCurrentMaxKey; public: ScDocumentPool(); @@ -40,15 +39,10 @@ public: virtual rtl::Reference<SfxItemPool> Clone() const override; virtual MapUnit GetMetric( sal_uInt16 nWhich ) const override; - void StyleDeleted( const ScStyleSheet* pStyle ); // delete templates(?) in organizer - void CellStyleCreated( std::u16string_view rName, const ScDocument& rDoc ); virtual bool GetPresentation( const SfxPoolItem& rItem, MapUnit ePresentationMetric, OUString& rText, const IntlWrapper& rIntl ) const override; -private: - virtual void newItem_Callback(const SfxPoolItem& rItem) const override; - virtual bool newItem_UseDirect(const SfxPoolItem& rItem) const override; }; /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index 11b65e9262c0..d94b0ef4fb53 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -355,6 +355,14 @@ public: ETERNAL /// no new listeners are setup, no broadcast/notify }; +private: + // needs to be shared to allow the bIsClip/bIsUndo mechanism to + // do the right thing (SCDOCMODE_CLIP, SCDOCMODE_UNDO) + mutable std::shared_ptr<CellAttributeHelper> mpCellAttributeHelper; + +public: + SC_DLLPUBLIC CellAttributeHelper& getCellAttributeHelper() const; + private: rtl::Reference<ScPoolHelper> mxPoolHelper; @@ -1939,8 +1947,8 @@ public: SCTAB nTab, ScMF nFlags ); SC_DLLPUBLIC void SetPattern( const ScAddress&, const ScPatternAttr& rAttr ); - SC_DLLPUBLIC const ScPatternAttr* SetPattern( SCCOL nCol, SCROW nRow, SCTAB nTab, std::unique_ptr<ScPatternAttr> pAttr ); - SC_DLLPUBLIC const ScPatternAttr* SetPattern( const ScAddress& rPos, std::unique_ptr<ScPatternAttr> pAttr ); + SC_DLLPUBLIC void SetPattern( SCCOL nCol, SCROW nRow, SCTAB nTab, const CellAttributeHolder& rHolder ); + SC_DLLPUBLIC void SetPattern( const ScAddress& rPos, const CellAttributeHolder& rHolder ); SC_DLLPUBLIC void SetPattern( SCCOL nCol, SCROW nRow, SCTAB nTab, const ScPatternAttr& rAttr ); void AutoFormat( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, @@ -2090,7 +2098,6 @@ public: void StripHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2, SCTAB nTab ); void ExtendHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2, SCTAB nTab ); - SC_DLLPUBLIC ScPatternAttr* GetDefPattern() const; SC_DLLPUBLIC ScDocumentPool* GetPool(); SC_DLLPUBLIC ScStyleSheetPool* GetStyleSheetPool() const; void GetUnprotectedCells( ScRangeList& rRange, SCTAB nTab ) const; @@ -2142,9 +2149,6 @@ public: SCCOL nEndCol, SCROW nEndRow, SCTAB nTab, bool bHiddenAsZero = true ) const; SC_DLLPUBLIC ScRange GetRange( SCTAB nTab, const tools::Rectangle& rMMRect, bool bHiddenAsZero = true ) const; - void UpdStlShtPtrsFrmNms(); - void StylesToNames(); - SC_DLLPUBLIC void CopyStdStylesFrom( const ScDocument& rSrcDoc ); static sal_uInt16 GetSrcVersion() { return nSrcVer; } diff --git a/sc/inc/global.hxx b/sc/inc/global.hxx index fe7b8bb407b2..1539858434bc 100644 --- a/sc/inc/global.hxx +++ b/sc/inc/global.hxx @@ -603,7 +603,7 @@ public: static void InitAddIns(); SC_DLLPUBLIC static void Clear(); // at the end of the program - static void InitTextHeight(const SfxItemPool* pPool); + static void InitTextHeight(SfxItemPool& rPool); static SvxBrushItem* GetEmptyBrushItem() { return xEmptyBrushItem.get(); } static SvxBrushItem* GetButtonBrushItem(); diff --git a/sc/inc/patattr.hxx b/sc/inc/patattr.hxx index d6536551f965..361ed40cd25b 100644 --- a/sc/inc/patattr.hxx +++ b/sc/inc/patattr.hxx @@ -21,13 +21,14 @@ #include <optional> -#include <svl/setitem.hxx> #include <svl/itemset.hxx> #include <svl/languageoptions.hxx> #include <tools/degree.hxx> #include <editeng/svxenum.hxx> #include "scdllapi.h" #include "fonthelper.hxx" +#include "scitems.hxx" +#include <unordered_set> namespace vcl { class Font; } namespace model { class ComplexColor; } @@ -50,43 +51,106 @@ enum class ScAutoFontColorMode IgnoreAll ///< like DISPLAY, but ignore stored font and background colors }; -class SC_DLLPUBLIC ScPatternAttr final : public SfxSetItem +class ScPatternAttr; + +class SC_DLLPUBLIC CellAttributeHelper final { - std::optional<OUString> pName; - mutable std::optional<bool> mxVisible; - ScStyleSheet* pStyle; - sal_uInt64 mnPAKey; + friend class CellAttributeHolder; + + SfxItemPool& mrSfxItemPool; + mutable ScPatternAttr* mpDefaultCellAttribute; + mutable std::unordered_set<const ScPatternAttr*> maRegisteredCellAttributes; + mutable const ScPatternAttr* mpLastHit; + mutable sal_uInt64 mnCurrentMaxKey; + + // only to be used from CellAttributeHolder, so private + const ScPatternAttr* registerAndCheck(const ScPatternAttr& rCandidate, bool bPassingOwnership) const; + void doUnregister(const ScPatternAttr& rCandidate); + public: - ScPatternAttr(SfxItemSet&& pItemSet, const OUString& rStyleName); - ScPatternAttr(SfxItemSet&& pItemSet); - ScPatternAttr(SfxItemPool* pItemPool); - ScPatternAttr(const ScPatternAttr& rPatternAttr); + explicit CellAttributeHelper(SfxItemPool& rSfxItemPool); + ~CellAttributeHelper(); + + const ScPatternAttr& getDefaultCellAttribute() const; + SfxItemPool& GetPool() const { return mrSfxItemPool; } - virtual ScPatternAttr* Clone( SfxItemPool *pPool = nullptr ) const override; + void CellStyleDeleted(const ScStyleSheet& rStyle); + void CellStyleCreated(ScDocument& rDoc, std::u16string_view rName); + void UpdateAllStyleSheets(ScDocument& rDoc); + void AllStylesToNames(); +}; - virtual bool operator==(const SfxPoolItem& rCmp) const override; +class SC_DLLPUBLIC CellAttributeHolder final +{ + const ScPatternAttr* mpScPatternAttr; - const SfxPoolItem& GetItem( sal_uInt16 nWhichP ) const - { return GetItemSet().Get(nWhichP); } - template<class T> const T& GetItem( TypedWhichId<T> nWhich ) const - { return static_cast<const T&>(GetItem(sal_uInt16(nWhich))); } +public: + CellAttributeHolder(const ScPatternAttr* pScPatternAttr = nullptr, bool bPassingOwnership = false); + CellAttributeHolder(const CellAttributeHolder& rHolder); + ~CellAttributeHolder(); - static const SfxPoolItem& GetItem( sal_uInt16 nWhich, const SfxItemSet& rItemSet, const SfxItemSet* pCondSet ); - template<class T> static const T& GetItem( TypedWhichId<T> nWhich, const SfxItemSet& rItemSet, const SfxItemSet* pCondSet ) - { return static_cast<const T&>(GetItem(sal_uInt16(nWhich), rItemSet, pCondSet)); } + const CellAttributeHolder& operator=(const CellAttributeHolder& rHolder); + bool operator==(const CellAttributeHolder& rHolder) const; - const SfxPoolItem& GetItem( sal_uInt16 nWhich, const SfxItemSet* pCondSet ) const; - template<class T> const T& GetItem( TypedWhichId<T> nWhich, const SfxItemSet* pCondSet ) const - { return static_cast<const T&>(GetItem(sal_uInt16(nWhich), pCondSet)); } + const ScPatternAttr* getScPatternAttr() const { return mpScPatternAttr; } + void setScPatternAttr(const ScPatternAttr* pNew, bool bPassingOwnership = false); - /// @param pWhich are no ranges, but single IDs, 0-terminated - bool HasItemsSet( const sal_uInt16* pWhich ) const; - void ClearItems( const sal_uInt16* pWhich ); + bool operator!() const { return nullptr == mpScPatternAttr; } + explicit operator bool() const { return nullptr != mpScPatternAttr; } - void DeleteUnchanged( const ScPatternAttr* pOldAttrs ); + // version that allows nullptrs + static bool areSame(const CellAttributeHolder* p1, const CellAttributeHolder* p2); +}; + +class SC_DLLPUBLIC ScPatternAttr final +{ + friend class CellAttributeHelper; + + SfxItemSet maLocalSfxItemSet; + std::optional<OUString> pName; + mutable std::optional<bool> mxVisible; + ScStyleSheet* pStyle; + CellAttributeHelper* pCellAttributeHelper; + sal_uInt64 mnPAKey; + mutable size_t mnRefCount; +#ifdef DBG_UTIL + sal_uInt32 m_nSerialNumber; + bool m_bDeleted; +#endif + +public: + ScPatternAttr(CellAttributeHelper& rHelper, const SfxItemSet* pItemSet = nullptr, const OUString* pStyleName = nullptr); + ScPatternAttr(const ScPatternAttr& rPatternAttr); + ~ScPatternAttr(); + + virtual bool operator==(const ScPatternAttr& rCmp) const; + + // version that allows nullptrs + static bool areSame(const ScPatternAttr* pItem1, const ScPatternAttr* pItem2); + bool isRegistered() const { return 0 != mnRefCount; } + bool isDefault() const { return this == &pCellAttributeHelper->getDefaultCellAttribute(); } + CellAttributeHelper& getCellAttributeHelper() const { return *pCellAttributeHelper; } + + const SfxItemSet& GetItemSet() const { return maLocalSfxItemSet; } + SfxItemSet& GetItemSet() { return maLocalSfxItemSet; } + + const SfxPoolItem& GetItem(sal_uInt16 nWhichP) const { return maLocalSfxItemSet.Get(nWhichP); } + template<class T> const T& GetItem( TypedWhichId<T> nWhich ) const + { return static_cast<const T&>(GetItem(sal_uInt16(nWhich))); } + static const SfxPoolItem& GetItem(sal_uInt16 nWhich, const SfxItemSet& rItemSet, const SfxItemSet* pCondSet); + template<class T> static const T& GetItem(TypedWhichId<T> nWhich, const SfxItemSet& rItemSet, const SfxItemSet* pCondSet) + { return static_cast<const T&>(GetItem(sal_uInt16(nWhich), rItemSet, pCondSet)); } + const SfxPoolItem& GetItem( sal_uInt16 nWhich, const SfxItemSet* pCondSet ) const; + template<class T> const T& GetItem(TypedWhichId<T> nWhich, const SfxItemSet* pCondSet) const + { return static_cast<const T&>(GetItem(sal_uInt16(nWhich), pCondSet)); } + + /// @param pWhich are no ranges, but single IDs, 0-terminated + bool HasItemsSet( const sal_uInt16* pWhich ) const; + void ClearItems( const sal_uInt16* pWhich ); + void DeleteUnchanged( const ScPatternAttr* pOldAttrs ); static SvxCellOrientation GetCellOrientation( const SfxItemSet& rItemSet, const SfxItemSet* pCondSet ); - SvxCellOrientation GetCellOrientation( const SfxItemSet* pCondSet = nullptr ) const; + SvxCellOrientation GetCellOrientation( const SfxItemSet* pCondSet = nullptr ) const; /** Static helper function to fill a font object from the passed item set. */ static void fillFontOnly(vcl::Font& rFont, const SfxItemSet& rItemSet, @@ -119,7 +183,7 @@ public: const Color* pBackConfigColor = nullptr, const Color* pTextConfigColor = nullptr) const { - fillColor(rComplexColor, GetItemSet(), eAutoMode, pCondSet, pBackConfigColor, pTextConfigColor); + fillColor(rComplexColor, maLocalSfxItemSet, eAutoMode, pCondSet, pBackConfigColor, pTextConfigColor); } void fillFontOnly(vcl::Font& rFont, @@ -128,7 +192,7 @@ public: const SfxItemSet* pCondSet = nullptr, SvtScriptType nScript = SvtScriptType::NONE) const { - fillFontOnly(rFont, GetItemSet(), pOutDev, pScale, pCondSet, nScript); + fillFontOnly(rFont, maLocalSfxItemSet, pOutDev, pScale, pCondSet, nScript); } /** Fills a font object from the own item set. */ @@ -140,7 +204,7 @@ public: const Color* pBackConfigColor = nullptr, const Color* pTextConfigColor = nullptr) const { - fillFont(rFont, GetItemSet(), eAutoMode, pOutDev, pScale, pCondSet, nScript, pBackConfigColor, pTextConfigColor); + fillFont(rFont, maLocalSfxItemSet, eAutoMode, pOutDev, pScale, pCondSet, nScript, pBackConfigColor, pTextConfigColor); } /** Converts all Calc items contained in rSrcSet to edit engine items and puts them into rEditSet. */ @@ -155,7 +219,7 @@ public: void FillEditParaItems( SfxItemSet* pSet ) const; - ScPatternAttr* PutInPool( ScDocument* pDestDoc, ScDocument* pSrcDoc ) const; + CellAttributeHolder MigrateToDocument( ScDocument* pDestDoc, ScDocument* pSrcDoc ) const; void SetStyleSheet(ScStyleSheet* pNewStyle, bool bClearDirectFormat = true); const ScStyleSheet* GetStyleSheet() const { return pStyle; } @@ -180,12 +244,6 @@ public: void SetPAKey(sal_uInt64 nKey); sal_uInt64 GetPAKey() const; - // TODO: tdf#135215: This is a band-aid to detect changes and invalidate the hash, - // a proper way would be probably to override SfxItemSet::Changed(), but 6cb400f41df0dd10 - // hardcoded SfxSetItem to contain SfxItemSet. - SfxItemSet& GetItemSet() { mxVisible.reset(); return SfxSetItem::GetItemSet(); } - using SfxSetItem::GetItemSet; - private: bool CalcVisible() const; }; diff --git a/sc/inc/poolcach.hxx b/sc/inc/poolcach.hxx index 6e3c3deda916..5b9057b7faf3 100644 --- a/sc/inc/poolcach.hxx +++ b/sc/inc/poolcach.hxx @@ -19,35 +19,33 @@ #pragma once #include "scdllapi.h" +#include "patattr.hxx" #include <vector> -class SfxItemPool; +class CellAttributeHelper; class SfxItemSet; class SfxPoolItem; -class ScPatternAttr; class ScItemPoolCache { struct SfxItemModifyImpl { - const ScPatternAttr *pOrigItem; - ScPatternAttr *pPoolItem; + const CellAttributeHolder aOriginal; + const CellAttributeHolder aModified; + SfxItemModifyImpl(const CellAttributeHolder& a, const CellAttributeHolder &b) : aOriginal(a), aModified(b) {} }; - SfxItemPool *pPool; - std::vector<SfxItemModifyImpl> - m_aCache; - const SfxItemSet *pSetToPut; - const SfxPoolItem *pItemToPut; + CellAttributeHelper& rHelper; + std::vector<SfxItemModifyImpl> m_aCache; + const SfxItemSet* pSetToPut; + const SfxPoolItemHolder aItemToPut; public: - ScItemPoolCache( SfxItemPool *pPool, - const SfxPoolItem *pPutItem ); - ScItemPoolCache( SfxItemPool *pPool, - const SfxItemSet *pPutSet ); - ~ScItemPoolCache(); + ScItemPoolCache( CellAttributeHelper& rHelper, const SfxPoolItem& rPutItem ); + ScItemPoolCache( CellAttributeHelper& rHelper, const SfxItemSet& rPutSet ); + ~ScItemPoolCache(); - const ScPatternAttr& ApplyTo( const ScPatternAttr& rSetItem ); + const CellAttributeHolder& ApplyTo( const CellAttributeHolder& rSetItem ); }; /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/inc/scitems.hxx b/sc/inc/scitems.hxx index dd91e2f63a3c..538624e4c5cb 100644 --- a/sc/inc/scitems.hxx +++ b/sc/inc/scitems.hxx @@ -162,48 +162,46 @@ constexpr TypedWhichId<ScCondFormatItem> ATTR_CONDITIONAL (154); constexpr TypedWhichId<SfxStringItem> ATTR_HYPERLINK (155); constexpr sal_uInt16 ATTR_PATTERN_END(155); // end cell-attribute-pattern - -constexpr TypedWhichId<ScPatternAttr> ATTR_PATTERN (156); // page attributes -constexpr TypedWhichId<SvxLRSpaceItem> ATTR_LRSPACE (157); // editor: PageDesc-TabPage -constexpr TypedWhichId<SvxULSpaceItem> ATTR_ULSPACE (158); -constexpr TypedWhichId<SvxPageItem> ATTR_PAGE (159); -constexpr TypedWhichId<SvxPaperBinItem> ATTR_PAGE_PAPERBIN (160); -constexpr TypedWhichId<SvxSizeItem> ATTR_PAGE_SIZE (161); -constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_HORCENTER (162); -constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_VERCENTER (163); - -constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_ON (164); // editor: header/footer-page -constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_DYNAMIC (165); -constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_SHARED (166); -constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_SHARED_FIRST (167); - -constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_NOTES (168); // editor: table -constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_GRID (169); -constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_HEADERS (170); -constexpr TypedWhichId<ScViewObjectModeItem> ATTR_PAGE_CHARTS (171); -constexpr TypedWhichId<ScViewObjectModeItem> ATTR_PAGE_OBJECTS (172); -constexpr TypedWhichId<ScViewObjectModeItem> ATTR_PAGE_DRAWINGS (173); -constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_TOPDOWN (174); -constexpr TypedWhichId<SfxUInt16Item> ATTR_PAGE_SCALE (175); -constexpr TypedWhichId<SfxUInt16Item> ATTR_PAGE_SCALETOPAGES (176); -constexpr TypedWhichId<SfxUInt16Item> ATTR_PAGE_FIRSTPAGENO (177); - -constexpr TypedWhichId<ScPageHFItem> ATTR_PAGE_HEADERLEFT (178); // contents of header/ -constexpr TypedWhichId<ScPageHFItem> ATTR_PAGE_FOOTERLEFT (179); // footer (left) -constexpr TypedWhichId<ScPageHFItem> ATTR_PAGE_HEADERRIGHT (180); // contents of header/ -constexpr TypedWhichId<ScPageHFItem> ATTR_PAGE_FOOTERRIGHT (181); // footer (right) -constexpr TypedWhichId<ScPageHFItem> ATTR_PAGE_HEADERFIRST (182); // contents of header/ -constexpr TypedWhichId<ScPageHFItem> ATTR_PAGE_FOOTERFIRST (183); // footer (first page) -constexpr TypedWhichId<SvxSetItem> ATTR_PAGE_HEADERSET (184); // the corresponding sets -constexpr TypedWhichId<SvxSetItem> ATTR_PAGE_FOOTERSET (185); - -constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_FORMULAS (186); -constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_NULLVALS (187); - -constexpr TypedWhichId<ScPageScaleToItem> ATTR_PAGE_SCALETO (188); // #i8868# scale printout to width/height - -constexpr TypedWhichId<SfxBoolItem> ATTR_HIDDEN (189); +constexpr TypedWhichId<SvxLRSpaceItem> ATTR_LRSPACE (156); // editor: PageDesc-TabPage +constexpr TypedWhichId<SvxULSpaceItem> ATTR_ULSPACE (157); +constexpr TypedWhichId<SvxPageItem> ATTR_PAGE (158); +constexpr TypedWhichId<SvxPaperBinItem> ATTR_PAGE_PAPERBIN (159); +constexpr TypedWhichId<SvxSizeItem> ATTR_PAGE_SIZE (160); +constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_HORCENTER (161); +constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_VERCENTER (162); + +constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_ON (163); // editor: header/footer-page +constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_DYNAMIC (164); +constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_SHARED (165); +constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_SHARED_FIRST (166); + +constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_NOTES (167); // editor: table +constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_GRID (168); +constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_HEADERS (169); +constexpr TypedWhichId<ScViewObjectModeItem> ATTR_PAGE_CHARTS (170); +constexpr TypedWhichId<ScViewObjectModeItem> ATTR_PAGE_OBJECTS (171); +constexpr TypedWhichId<ScViewObjectModeItem> ATTR_PAGE_DRAWINGS (172); +constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_TOPDOWN (173); +constexpr TypedWhichId<SfxUInt16Item> ATTR_PAGE_SCALE (174); +constexpr TypedWhichId<SfxUInt16Item> ATTR_PAGE_SCALETOPAGES (175); +constexpr TypedWhichId<SfxUInt16Item> ATTR_PAGE_FIRSTPAGENO (176); + +constexpr TypedWhichId<ScPageHFItem> ATTR_PAGE_HEADERLEFT (177); // contents of header/ +constexpr TypedWhichId<ScPageHFItem> ATTR_PAGE_FOOTERLEFT (178); // footer (left) +constexpr TypedWhichId<ScPageHFItem> ATTR_PAGE_HEADERRIGHT (179); // contents of header/ +constexpr TypedWhichId<ScPageHFItem> ATTR_PAGE_FOOTERRIGHT (180); // footer (right) +constexpr TypedWhichId<ScPageHFItem> ATTR_PAGE_HEADERFIRST (181); // contents of header/ +constexpr TypedWhichId<ScPageHFItem> ATTR_PAGE_FOOTERFIRST (182); // footer (first page) +constexpr TypedWhichId<SvxSetItem> ATTR_PAGE_HEADERSET (183); // the corresponding sets +constexpr TypedWhichId<SvxSetItem> ATTR_PAGE_FOOTERSET (184); + +constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_FORMULAS (185); +constexpr TypedWhichId<SfxBoolItem> ATTR_PAGE_NULLVALS (186); + +constexpr TypedWhichId<ScPageScaleToItem> ATTR_PAGE_SCALETO (187); // #i8868# scale printout to width/height + +constexpr TypedWhichId<SfxBoolItem> ATTR_HIDDEN (188); constexpr sal_uInt16 ATTR_ENDINDEX(ATTR_HIDDEN); // end of pool-range diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx index 3b47a52c0ab8..72e78b195986 100644 --- a/sc/inc/table.hxx +++ b/sc/inc/table.hxx @@ -780,7 +780,7 @@ public: void SetAttrEntries( SCCOL nStartCol, SCCOL nEndCol, std::vector<ScAttrEntry> && vNewData); void SetPattern( const ScAddress& rPos, const ScPatternAttr& rAttr ); - const ScPatternAttr* SetPattern( SCCOL nCol, SCROW nRow, std::unique_ptr<ScPatternAttr> ); + void SetPattern( SCCOL nCol, SCROW nRow, const CellAttributeHolder& rHolder ); void SetPattern( SCCOL nCol, SCROW nRow, const ScPatternAttr& rAttr ); void ApplyPatternIfNumberformatIncompatible( const ScRange& rRange, const ScPatternAttr& rPattern, SvNumFormatType nNewType ); @@ -810,7 +810,7 @@ public: bool ApplyFlags( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, ScMF nFlags ); bool RemoveFlags( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, ScMF nFlags ); - void ApplySelectionCache( ScItemPoolCache* pCache, const ScMarkData& rMark, ScEditDataArray* pDataArray = nullptr, bool* const pIsChanged = nullptr ); + void ApplySelectionCache( ScItemPoolCache& rCache, const ScMarkData& rMark, ScEditDataArray* pDataArray = nullptr, bool* const pIsChanged = nullptr ); void DeleteSelection( InsertDeleteFlags nDelFlag, const ScMarkData& rMark, bool bBroadcast = true ); void ClearSelectionItems( const sal_uInt16* pWhich, const ScMarkData& rMark ); diff --git a/sc/qa/unit/subsequent_export_test.cxx b/sc/qa/unit/subsequent_export_test.cxx index 30600191d54a..4fc83ab7df9f 100644 --- a/sc/qa/unit/subsequent_export_test.cxx +++ b/sc/qa/unit/subsequent_export_test.cxx @@ -1740,7 +1740,7 @@ CPPUNIT_TEST_FIXTURE(ScExportTest, testRichTextExportODS) pEditText = pDoc->GetEditText(ScAddress(1, 8, 0)); CPPUNIT_ASSERT_MESSAGE("Incorrect B9 value.", aCheckFunc.checkB9(pEditText)); - ScPatternAttr aCellFontColor(pDoc->GetPool()); + ScPatternAttr aCellFontColor(pDoc->getCellAttributeHelper()); aCellFontColor.GetItemSet().Put(SvxColorItem(COL_BLUE, ATTR_FONT_COLOR)); // Set font color of B10 to blue. pDoc->ApplyPattern(1, 9, 0, aCellFontColor); diff --git a/sc/qa/unit/subsequent_export_test4.cxx b/sc/qa/unit/subsequent_export_test4.cxx index 95c7057aef2d..41d76cc9698d 100644 --- a/sc/qa/unit/subsequent_export_test4.cxx +++ b/sc/qa/unit/subsequent_export_test4.cxx @@ -223,7 +223,7 @@ CPPUNIT_TEST_FIXTURE(ScExportTest4, testTdf143979) sal_uInt32 nFormat; SvNumberFormatter* pFormatter = pDoc->GetFormatTable(); pFormatter->PutEntry(aCode, nCheckPos, nType, nFormat); - ScPatternAttr aNewAttrs(pDoc->GetPool()); + ScPatternAttr aNewAttrs(pDoc->getCellAttributeHelper()); SfxItemSet& rSet = aNewAttrs.GetItemSet(); rSet.Put(SfxUInt32Item(ATTR_VALUE_FORMAT, nFormat)); pDoc->ApplyPattern(0, 0, 0, aNewAttrs); @@ -1418,7 +1418,7 @@ CPPUNIT_TEST_FIXTURE(ScExportTest4, testWholeRowBold) ScDocument* pDoc = getScDoc(); // Make entire second row bold. - ScPatternAttr boldAttr(pDoc->GetPool()); + ScPatternAttr boldAttr(pDoc->getCellAttributeHelper()); boldAttr.GetItemSet().Put(SvxWeightItem(WEIGHT_BOLD, ATTR_FONT_WEIGHT)); pDoc->ApplyPatternAreaTab(0, 1, pDoc->MaxCol(), 1, 0, boldAttr); } diff --git a/sc/qa/unit/subsequent_filters_test2.cxx b/sc/qa/unit/subsequent_filters_test2.cxx index 22339c010e8f..31dae9282166 100644 --- a/sc/qa/unit/subsequent_filters_test2.cxx +++ b/sc/qa/unit/subsequent_filters_test2.cxx @@ -1637,10 +1637,10 @@ CPPUNIT_TEST_FIXTURE(ScFiltersTest2, testBackColorFilter) createScDoc(); ScDocument* pDoc = getScDoc(); - ScPatternAttr aPattern1(pDoc->GetPool()); + ScPatternAttr aPattern1(pDoc->getCellAttributeHelper()); aPattern1.GetItemSet().Put(SvxBrushItem(aBackColor1, ATTR_BACKGROUND)); - ScPatternAttr aPattern2(pDoc->GetPool()); + ScPatternAttr aPattern2(pDoc->getCellAttributeHelper()); aPattern2.GetItemSet().Put(SvxBrushItem(aBackColor2, ATTR_BACKGROUND)); // Apply the pattern to cell A1:A2 diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx index c75742eabdfc..370f2d1f5c80 100644 --- a/sc/qa/unit/ucalc.cxx +++ b/sc/qa/unit/ucalc.cxx @@ -1187,7 +1187,7 @@ CPPUNIT_TEST_FIXTURE(Test, testHorizontalAttrIterator) m_pDoc->InsertTab(0, "Test"); // Set the background color of B2:C3,D2,E3,C4:D4,B5:D5 to blue - ScPatternAttr aCellBackColor(m_pDoc->GetPool()); + ScPatternAttr aCellBackColor(m_pDoc->getCellAttributeHelper()); aCellBackColor.GetItemSet().Put(SvxBrushItem(COL_BLUE, ATTR_BACKGROUND)); m_pDoc->ApplyPatternAreaTab(1, 1, 2, 2, 0, aCellBackColor); m_pDoc->ApplyPatternAreaTab(3, 1, 3, 1, 0, aCellBackColor); @@ -1210,7 +1210,7 @@ CPPUNIT_TEST_FIXTURE(Test, testHorizontalAttrIterator) size_t nCheckPos = 0; for (const ScPatternAttr* pAttr = aIter.GetNext(nCol1, nCol2, nRow); pAttr; pAttr = aIter.GetNext(nCol1, nCol2, nRow)) { - if (SfxPoolItem::areSame( pAttr, m_pDoc->GetDefPattern())) + if (pAttr->isDefault()) continue; CPPUNIT_ASSERT_MESSAGE("Iteration longer than expected.", nCheckPos < nCheckLen); CPPUNIT_ASSERT_EQUAL(aChecks[nCheckPos][0], static_cast<int>(nCol1)); @@ -1235,7 +1235,7 @@ CPPUNIT_TEST_FIXTURE(Test, testIteratorsUnallocatedColumnsAttributes) CPPUNIT_ASSERT_EQUAL(allocatedColsCount, m_pDoc->GetAllocatedColumnsCount(0)); // Make entire second row and third row bold. - ScPatternAttr boldAttr(m_pDoc->GetPool()); + ScPatternAttr boldAttr(m_pDoc->getCellAttributeHelper()); boldAttr.GetItemSet().Put(SvxWeightItem(WEIGHT_BOLD, ATTR_FONT_WEIGHT)); m_pDoc->ApplyPatternAreaTab(0, 1, m_pDoc->MaxCol(), 2, 0, boldAttr); @@ -1293,15 +1293,15 @@ CPPUNIT_TEST_FIXTURE(Test, testIteratorsDefPattern) // Set cells as bold, default allocated, bold, default unallocated. SCCOL firstCol = 100; SCCOL lastCol = 103; - ScPatternAttr boldAttr(m_pDoc->GetPool()); + ScPatternAttr boldAttr(m_pDoc->getCellAttributeHelper()); boldAttr.GetItemSet().Put(SvxWeightItem(WEIGHT_BOLD, ATTR_FONT_WEIGHT)); m_pDoc->ApplyPattern(100, 0, 0, boldAttr); m_pDoc->ApplyPattern(102, 0, 0, boldAttr); CPPUNIT_ASSERT_EQUAL(SCCOL(102 + 1), m_pDoc->GetAllocatedColumnsCount(0)); const ScPatternAttr* pattern = m_pDoc->GetPattern(100, 0, 0); - const ScPatternAttr* defPattern = m_pDoc->GetDefPattern(); - CPPUNIT_ASSERT(!SfxPoolItem::areSame(pattern, defPattern)); + const ScPatternAttr* defPattern(&m_pDoc->getCellAttributeHelper().getDefaultCellAttribute()); //GetDefPattern(); + CPPUNIT_ASSERT(!ScPatternAttr::areSame(pattern, defPattern)); CPPUNIT_ASSERT_EQUAL(pattern, m_pDoc->GetPattern(102, 0, 0)); CPPUNIT_ASSERT_EQUAL(defPattern, m_pDoc->GetPattern(101, 0, 0)); CPPUNIT_ASSERT_EQUAL(defPattern, m_pDoc->GetPattern(103, 0, 0)); @@ -3481,7 +3481,7 @@ CPPUNIT_TEST_FIXTURE(Test, testAutoFilterTimeValue) // Apply the "hour:minute:second" format to A2:A3. SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable(); sal_uInt32 nFormat = pFormatter->GetFormatIndex(NF_TIME_HH_MMSS, LANGUAGE_ENGLISH_US); - ScPatternAttr aNewAttrs(m_pDoc->GetPool()); + ScPatternAttr aNewAttrs(m_pDoc->getCellAttributeHelper()); SfxItemSet& rSet = aNewAttrs.GetItemSet(); rSet.Put(SfxUInt32Item(ATTR_VALUE_FORMAT, nFormat)); @@ -3634,7 +3634,7 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf76441) SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable(); pFormatter->PutEntry( aCode, nCheckPos, nType, nFormat ); - ScPatternAttr aNewAttrs(m_pDoc->GetPool()); + ScPatternAttr aNewAttrs(m_pDoc->getCellAttributeHelper()); SfxItemSet& rSet = aNewAttrs.GetItemSet(); rSet.Put(SfxUInt32Item(ATTR_VALUE_FORMAT, nFormat)); { @@ -3672,7 +3672,7 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf76836) SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable(); pFormatter->PutEntry( aCode, nCheckPos, nType, nFormat ); - ScPatternAttr aNewAttrs(m_pDoc->GetPool()); + ScPatternAttr aNewAttrs(m_pDoc->getCellAttributeHelper()); SfxItemSet& rSet = aNewAttrs.GetItemSet(); rSet.Put(SfxUInt32Item(ATTR_VALUE_FORMAT, nFormat)); @@ -3705,7 +3705,7 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf142186) SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable(); pFormatter->PutEntry( aCode, nCheckPos, nType, nFormat ); - ScPatternAttr aNewAttrs(m_pDoc->GetPool()); + ScPatternAttr aNewAttrs(m_pDoc->getCellAttributeHelper()); SfxItemSet& rSet = aNewAttrs.GetItemSet(); rSet.Put(SfxUInt32Item(ATTR_VALUE_FORMAT, nFormat)); { @@ -3759,7 +3759,7 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf126342) SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable(); pFormatter->PutEntry( aCode, nCheckPos, nType, nFormat ); - ScPatternAttr aNewAttrs(m_pDoc->GetPool()); + ScPatternAttr aNewAttrs(m_pDoc->getCellAttributeHelper()); SfxItemSet& rSet = aNewAttrs.GetItemSet(); rSet.Put(SfxUInt32Item(ATTR_VALUE_FORMAT, nFormat)); m_pDoc->ApplyPattern(0, 0, 0, aNewAttrs); @@ -3892,7 +3892,7 @@ CPPUNIT_TEST_FIXTURE(Test, testDateFilterContains) // Set the fields as dates. SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable(); sal_uInt32 nFormat = pFormatter->GetFormatIndex(NF_DATE_DIN_YYMMDD, LANGUAGE_ENGLISH_US); - ScPatternAttr aNewAttrs(m_pDoc->GetPool()); + ScPatternAttr aNewAttrs(m_pDoc->getCellAttributeHelper()); SfxItemSet& rSet = aNewAttrs.GetItemSet(); rSet.Put(SfxUInt32Item(ATTR_VALUE_FORMAT, nFormat)); m_pDoc->ApplyPatternAreaTab(0, 1, 0, 5, 0, aNewAttrs); // apply it to A1:A6 @@ -6657,7 +6657,7 @@ CPPUNIT_TEST_FIXTURE(Test, testProtectedSheetEditByRow) { // Remove protected flags from rows 2-5. - ScPatternAttr aAttr(m_pDoc->GetPool()); + ScPatternAttr aAttr(m_pDoc->getCellAttributeHelper()); aAttr.GetItemSet().Put(ScProtectionAttr(false)); m_pDoc->ApplyPatternAreaTab(0, 1, m_pDoc->MaxCol(), 4, 0, aAttr); @@ -6733,7 +6733,7 @@ CPPUNIT_TEST_FIXTURE(Test, testProtectedSheetEditByColumn) { // Remove protected flags from columns B to E. - ScPatternAttr aAttr(m_pDoc->GetPool()); + ScPatternAttr aAttr(m_pDoc->getCellAttributeHelper()); aAttr.GetItemSet().Put(ScProtectionAttr(false)); m_pDoc->ApplyPatternAreaTab(1, 0, 4, m_pDoc->MaxRow(), 0, aAttr); diff --git a/sc/qa/unit/ucalc_DocumentThemes.cxx b/sc/qa/unit/ucalc_DocumentThemes.cxx index d0bd29052c16..2a05badedc65 100644 --- a/sc/qa/unit/ucalc_DocumentThemes.cxx +++ b/sc/qa/unit/ucalc_DocumentThemes.cxx @@ -57,7 +57,7 @@ CPPUNIT_TEST_FIXTURE(DocumentThemesTest, testChangeTheme) auto eBackgroundThemeType = model::ThemeColorType::Accent5; auto eCellTextThemeType = model::ThemeColorType::Accent2; - ScPatternAttr aNewPattern(m_pDoc->GetPool()); + ScPatternAttr aNewPattern(m_pDoc->getCellAttributeHelper()); { model::ComplexColor aComplexColor; aComplexColor.setThemeColor(eBackgroundThemeType); diff --git a/sc/qa/unit/ucalc_copypaste.cxx b/sc/qa/unit/ucalc_copypaste.cxx index bec9bb499b94..b673ad7de3a1 100644 --- a/sc/qa/unit/ucalc_copypaste.cxx +++ b/sc/qa/unit/ucalc_copypaste.cxx @@ -1609,7 +1609,7 @@ void TestCopyPaste::executeCopyPasteSpecial(const SCTAB srcSheet, const SCTAB de m_pDoc->SetString(10, 17, srcSheet, "=SUM(Range_aCa5_aCa10)"); // add patterns - ScPatternAttr aCellBlueColor(m_pDoc->GetPool()); + ScPatternAttr aCellBlueColor(m_pDoc->getCellAttributeHelper()); aCellBlueColor.GetItemSet().Put(SvxBrushItem(COL_BLUE, ATTR_BACKGROUND)); m_pDoc->ApplyPatternAreaTab(1, 2, 1, 4, srcSheet, aCellBlueColor); @@ -1624,12 +1624,12 @@ void TestCopyPaste::executeCopyPasteSpecial(const SCTAB srcSheet, const SCTAB de CPPUNIT_ASSERT_MESSAGE("SrcSheet.B6 has no pattern", !pItem); // row 2 on empty cell - ScPatternAttr aCellGreenColor(m_pDoc->GetPool()); + ScPatternAttr aCellGreenColor(m_pDoc->getCellAttributeHelper()); aCellGreenColor.GetItemSet().Put(SvxBrushItem(COL_GREEN, ATTR_BACKGROUND)); m_pDoc->ApplyPatternAreaTab(5, 4, 5, 4, srcSheet, aCellGreenColor); // row 4 for multi range row selection - ScPatternAttr aCellRedColor(m_pDoc->GetPool()); + ScPatternAttr aCellRedColor(m_pDoc->getCellAttributeHelper()); aCellRedColor.GetItemSet().Put(SvxBrushItem(COL_RED, ATTR_BACKGROUND)); m_pDoc->ApplyPatternAreaTab(3, 6, 4, 6, srcSheet, aCellRedColor); @@ -9345,7 +9345,7 @@ CPPUNIT_TEST_FIXTURE(TestCopyPaste, testCopyPasteSkipEmpty) m_pDoc->SetString(ScAddress(1, 4, 0), "E"); // Set the background color of B1:B5 to blue. - ScPatternAttr aCellBackColor(m_pDoc->GetPool()); + ScPatternAttr aCellBackColor(m_pDoc->getCellAttributeHelper()); aCellBackColor.GetItemSet().Put(SvxBrushItem(COL_BLUE, ATTR_BACKGROUND)); m_pDoc->ApplyPatternAreaTab(1, 0, 1, 4, 0, aCellBackColor); @@ -10723,7 +10723,7 @@ CPPUNIT_TEST_FIXTURE(TestCopyPaste, testUndoBackgroundColor) m_pDoc->SetValue(ScAddress(3, 4, 0), 3.0); // D5 // Add patterns - ScPatternAttr aCellBlueColor(m_pDoc->GetPool()); + ScPatternAttr aCellBlueColor(m_pDoc->getCellAttributeHelper()); aCellBlueColor.GetItemSet().Put(SvxBrushItem(COL_BLUE, ATTR_BACKGROUND)); m_pDoc->ApplyPatternAreaTab(0, 3, m_pDoc->MaxCol(), 3, 0, aCellBlueColor); diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx index feb0e8fef22a..105c7e4a772d 100644 --- a/sc/qa/unit/ucalc_formula.cxx +++ b/sc/qa/unit/ucalc_formula.cxx @@ -4257,8 +4257,7 @@ CPPUNIT_TEST_FIXTURE(TestFormula, testFormulaRefUpdateValidity) sal_uInt32 nIndex = m_pDoc->AddValidationEntry(aData); SfxUInt32Item aItem(ATTR_VALIDDATA, nIndex); - ScPatternAttr aNewAttrs( - SfxItemSet(*m_pDoc->GetPool(), svl::Items<ATTR_PATTERN_START, ATTR_PATTERN_END>)); + ScPatternAttr aNewAttrs(m_pDoc->getCellAttributeHelper()); aNewAttrs.GetItemSet().Put(aItem); m_pDoc->ApplyPattern(0, 1, 0, aNewAttrs); diff --git a/sc/source/core/data/attarray.cxx b/sc/source/core/data/attarray.cxx index 7124e78be37e..4b9bbc7a4e2c 100644 --- a/sc/source/core/data/attarray.cxx +++ b/sc/source/core/data/attarray.cxx @@ -62,11 +62,11 @@ ScAttrArray::ScAttrArray( SCCOL nNewCol, SCTAB nNewTab, ScDocument& rDoc, ScAttr for ( size_t nIdx = 0; nIdx < pDefaultColAttrArray->mvData.size(); ++nIdx ) { mvData[nIdx].nEndRow = pDefaultColAttrArray->mvData[nIdx].nEndRow; - ScPatternAttr aNewPattern( *(pDefaultColAttrArray->mvData[nIdx].pPattern) ); - mvData[nIdx].pPattern = &rDocument.GetPool()->DirectPutItemInPool( aNewPattern ); + mvData[nIdx].setScPatternAttr(pDefaultColAttrArray->mvData[nIdx].getScPatternAttr()); bool bNumFormatChanged = false; if ( ScGlobal::CheckWidthInvalidate( bNumFormatChanged, - mvData[nIdx].pPattern->GetItemSet(), rDocument.GetDefPattern()->GetItemSet() ) ) + mvData[nIdx].getScPatternAttr()->GetItemSet(), + rDocument.getCellAttributeHelper().getDefaultCellAttribute().GetItemSet() ) ) { aAdrStart.SetRow( nIdx ? mvData[nIdx-1].nEndRow+1 : 0 ); aAdrEnd.SetRow( mvData[nIdx].nEndRow ); @@ -80,10 +80,6 @@ ScAttrArray::~ScAttrArray() #if DEBUG_SC_TESTATTRARRAY TestData(); #endif - - ScDocumentPool* pDocPool = rDocument.GetPool(); - for (auto const & rEntry : mvData) - pDocPool->DirectRemoveItemFromPool(*rEntry.pPattern); } #if DEBUG_SC_TESTATTRARRAY @@ -97,8 +93,6 @@ void ScAttrArray::TestData() const if (nPos > 0) if (mvData[nPos].pPattern == mvData[nPos-1].pPattern || mvData[nPos].nRow <= mvData[nPos-1].nRow) ++nErr; - if (mvData[nPos].pPattern->Which() != ATTR_PATTERN) - ++nErr; } if ( nPos && mvData[nPos-1].nRow != rDocument.MaxRow() ) ++nErr; @@ -116,19 +110,22 @@ void ScAttrArray::SetDefaultIfNotInit( SCSIZE nNeeded ) mvData.reserve( nNewLimit ); mvData.emplace_back(); mvData[0].nEndRow = rDocument.MaxRow(); - mvData[0].pPattern = rDocument.GetDefPattern(); // no put + mvData[0].setScPatternAttr(&rDocument.getCellAttributeHelper().getDefaultCellAttribute()); // no put } -void ScAttrArray::Reset( const ScPatternAttr* pPattern ) +void ScAttrArray::Reset(const CellAttributeHolder& rPattern) { - ScDocumentPool* pDocPool = rDocument.GetPool(); + const ScPatternAttr* pPattern(rPattern.getScPatternAttr()); + if (nullptr == pPattern) + return; + ScAddress aAdrStart( nCol, 0, nTab ); ScAddress aAdrEnd ( nCol, 0, nTab ); for (SCSIZE i=0; i<mvData.size(); i++) { // ensure that attributing changes text width of cell - const ScPatternAttr* pOldPattern = mvData[i].pPattern; + const ScPatternAttr* pOldPattern(mvData[i].getScPatternAttr()); if ( nCol != -1 ) { bool bNumFormatChanged; @@ -140,16 +137,14 @@ void ScAttrArray::Reset( const ScPatternAttr* pPattern ) rDocument.InvalidateTextWidth( &aAdrStart, &aAdrEnd, bNumFormatChanged ); } } - pDocPool->DirectRemoveItemFromPool(*pOldPattern); } mvData.resize(0); rDocument.SetStreamValid(nTab, false); mvData.resize(1); - const ScPatternAttr* pNewPattern = &pDocPool->DirectPutItemInPool(*pPattern); mvData[0].nEndRow = rDocument.MaxRow(); - mvData[0].pPattern = pNewPattern; + mvData[0].setScPatternAttr(pPattern); } bool ScAttrArray::Concat(SCSIZE nPos) @@ -159,10 +154,9 @@ bool ScAttrArray::Concat(SCSIZE nPos) { if (nPos > 0) { - if (SfxPoolItem::areSame(mvData[nPos - 1].pPattern, mvData[nPos].pPattern)) + if (ScPatternAttr::areSame(mvData[nPos - 1].getScPatternAttr(), mvData[nPos].getScPatternAttr())) { mvData[nPos - 1].nEndRow = mvData[nPos].nEndRow; - rDocument.GetPool()->DirectRemoveItemFromPool(*mvData[nPos].pPattern); mvData.erase(mvData.begin() + nPos); nPos--; bRet = true; @@ -170,10 +164,9 @@ bool ScAttrArray::Concat(SCSIZE nPos) } if (nPos + 1 < mvData.size()) { - if (SfxPoolItem::areSame(mvData[nPos + 1].pPattern, mvData[nPos].pPattern)) + if (ScPatternAttr::areSame(mvData[nPos + 1].getScPatternAttr(), mvData[nPos].getScPatternAttr())) { mvData[nPos].nEndRow = mvData[nPos + 1].nEndRow; - rDocument.GetPool()->DirectRemoveItemFromPool(*mvData[nPos].pPattern); mvData.erase(mvData.begin() + nPos + 1); bRet = true; } @@ -246,11 +239,11 @@ const ScPatternAttr* ScAttrArray::GetPattern( SCROW nRow ) const { if ( !rDocument.ValidRow(nRow) ) return nullptr; - return rDocument.GetDefPattern(); + return &rDocument.getCellAttributeHelper().getDefaultCellAttribute(); } SCSIZE i; if (Search( nRow, i )) - return mvData[i].pPattern; + return mvData[i].getScPatternAttr(); else return nullptr; } @@ -264,7 +257,7 @@ const ScPatternAttr* ScAttrArray::GetPatternRange( SCROW& rStartRow, return nullptr; rStartRow = 0; rEndRow = rDocument.MaxRow(); - return rDocument.GetDefPattern(); + return &rDocument.getCellAttributeHelper().getDefaultCellAttribute(); } SCSIZE nIndex; if ( Search( nRow, nIndex ) ) @@ -274,7 +267,7 @@ const ScPatternAttr* ScAttrArray::GetPatternRange( SCROW& rStartRow, else rStartRow = 0; rEndRow = mvData[nIndex].nEndRow; - return mvData[nIndex].pPattern; + return mvData[nIndex].getScPatternAttr(); } return nullptr; } @@ -296,7 +289,7 @@ void ScAttrArray::AddCondFormat( SCROW nStartRow, SCROW nEndRow, sal_uInt32 nInd // changed to create pNewPattern only if needed, else use already // existing pPattern. This shows by example how to avoid that special - // handling of ATTR_PATTERN/ScPatternAttr in SC and massive + // handling of ScPatternAttr in SC and massive // incarnations/destructions of that Item (which contains an ItemSet) std::unique_ptr<ScPatternAttr> pNewPattern; if(pPattern) @@ -329,16 +322,16 @@ void ScAttrArray::AddCondFormat( SCROW nStartRow, SCROW nEndRow, sal_uInt32 nInd } else { - pNewPattern.reset( new ScPatternAttr( rDocument.GetPool() ) ); + pNewPattern.reset( new ScPatternAttr( rDocument.getCellAttributeHelper() ) ); ScCondFormatItem aItem(nIndex); pNewPattern->GetItemSet().Put( aItem ); nTempEndRow = nEndRow; } if (pNewPattern) - SetPatternArea( nTempStartRow, nTempEndRow, std::move(pNewPattern), true ); + SetPatternArea( nTempStartRow, nTempEndRow, CellAttributeHolder(pNewPattern.release(), true) ); else - SetPatternArea( nTempStartRow, nTempEndRow, pPattern, true ); + SetPatternArea( nTempStartRow, nTempEndRow, CellAttributeHolder(pPattern) ); nTempStartRow = nTempEndRow + 1; } @@ -370,12 +363,12 @@ void ScAttrArray::RemoveCondFormat( SCROW nStartRow, SCROW nEndRow, sal_uInt32 n nTempEndRow = std::min<SCROW>( nPatternEndRow, nEndRow ); if (const ScCondFormatItem* pItem = pPattern->GetItemSet().GetItemIfSet( ATTR_CONDITIONAL )) { - auto pPatternAttr = std::make_unique<ScPatternAttr>( *pPattern ); if (nIndex == 0) { ScCondFormatItem aItem; - pPatternAttr->GetItemSet().Put( aItem ); - SetPatternArea( nTempStartRow, nTempEndRow, std::move(pPatternAttr), true ); + ScPatternAttr* pTemp(new ScPatternAttr(*pPattern)); + pTemp->GetItemSet().Put( aItem ); + SetPatternArea( nTempStartRow, nTempEndRow, CellAttributeHolder(pTemp, true) ); } else { @@ -386,8 +379,9 @@ void ScAttrArray::RemoveCondFormat( SCROW nStartRow, SCROW nEndRow, sal_uInt32 n ScCondFormatIndexes aNewCondFormatData(rCondFormatData); aNewCondFormatData.erase_at(std::distance(rCondFormatData.begin(), itr)); ScCondFormatItem aItem( std::move(aNewCondFormatData) ); - pPatternAttr->GetItemSet().Put( aItem ); - SetPatternArea( nTempStartRow, nTempEndRow, std::move(pPatternAttr), true ); + ScPatternAttr* pTemp(new ScPatternAttr(*pPattern)); + pTemp->GetItemSet().Put( aItem ); + SetPatternArea( nTempStartRow, nTempEndRow, CellAttributeHolder(pTemp, true) ); } } } @@ -441,7 +435,7 @@ bool ScAttrArray::Reserve( SCSIZE nReserve ) mvData.reserve(nReserve); mvData.emplace_back(); mvData[0].nEndRow = rDocument.MaxRow(); - mvData[0].pPattern = rDocument.GetDefPattern(); // no put + mvData[0].setScPatternAttr(&rDocument.getCellAttributeHelper().getDefaultCellAttribute()); // no put return true; } catch (std::bad_alloc const &) { return false; @@ -460,20 +454,17 @@ bool ScAttrArray::Reserve( SCSIZE nReserve ) return false; } -const ScPatternAttr* ScAttrArray::SetPatternAreaImpl(SCROW nStartRow, SCROW nEndRow, const ScPatternAttr* pPattern, - bool bPutToPool, ScEditDataArray* pDataArray, bool bPassingOwnership ) +const ScPatternAttr* ScAttrArray::SetPatternAreaImpl( + SCROW nStartRow, SCROW nEndRow, const CellAttributeHolder& rPattern, ScEditDataArray* pDataArray) { + const ScPatternAttr* pPattern(rPattern.getScPatternAttr()); + if (nullptr == pPattern) + return nullptr; + if (rDocument.ValidRow(nStartRow) && rDocument.ValidRow(nEndRow)) { - if (bPutToPool) - { - if (bPassingOwnership) - pPattern = &rDocument.GetPool()->DirectPutItemInPool(std::unique_ptr<ScPatternAttr>(const_cast<ScPatternAttr*>(pPattern))); - else - pPattern = &rDocument.GetPool()->DirectPutItemInPool(*pPattern); - } if ((nStartRow == 0) && (nEndRow == rDocument.MaxRow())) - Reset(pPattern); + Reset(rPattern); else { SCSIZE nNeeded = mvData.size() + 2; @@ -507,7 +498,7 @@ const ScPatternAttr* ScAttrArray::SetPatternAreaImpl(SCROW nStartRow, SCROW nEnd if ( nCol != -1 && !bIsLoading ) { const SfxItemSet& rNewSet = pPattern->GetItemSet(); - const SfxItemSet& rOldSet = mvData[nx].pPattern->GetItemSet(); + const SfxItemSet& rOldSet = mvData[nx].getScPatternAttr()->GetItemSet(); bool bNumFormatChanged; if ( ScGlobal::CheckWidthInvalidate( bNumFormatChanged, rNewSet, rOldSet ) ) @@ -529,7 +520,7 @@ const ScPatternAttr* ScAttrArray::SetPatternAreaImpl(SCROW nStartRow, SCROW nEnd if ( nStartRow > 0 ) { nInsert = rDocument.MaxRow() + 1; - if ( !SfxPoolItem::areSame(mvData[ni].pPattern, pPattern ) ) + if ( !ScPatternAttr::areSame(mvData[ni].getScPatternAttr(), pPattern ) ) { if ( ni == 0 || (mvData[ni-1].nEndRow < nStartRow - 1) ) { // may be a split or a simple insert or just a shrink, @@ -542,7 +533,7 @@ const ScPatternAttr* ScAttrArray::SetPatternAreaImpl(SCROW nStartRow, SCROW nEnd else if (mvData[ni - 1].nEndRow == nStartRow - 1) nInsert = ni; } - if ( ni > 0 && SfxPoolItem::areSame(mvData[ni-1].pPattern, pPattern) ) + if ( ni > 0 && ScPatternAttr::areSame(mvData[ni-1].getScPatternAttr(), pPattern) ) { // combine mvData[ni-1].nEndRow = nEndRow; nInsert = rDocument.MaxRow() + 1; @@ -557,11 +548,11 @@ const ScPatternAttr* ScAttrArray::SetPatternAreaImpl(SCROW nStartRow, SCROW nEnd nj++; if ( !bSplit ) { - if ( nj < mvData.size() && SfxPoolItem::areSame(mvData[nj].pPattern, pPattern ) ) + if ( nj < mvData.size() && ScPatternAttr::areSame(mvData[nj].getScPatternAttr(), pPattern ) ) { // combine if ( ni > 0 ) { - if ( SfxPoolItem::areSame(mvData[ni-1].pPattern, pPattern ) ) + if ( ScPatternAttr::areSame(mvData[ni-1].getScPatternAttr(), pPattern ) ) { // adjacent entries mvData[ni-1].nEndRow = mvData[nj].nEndRow; nj++; @@ -575,21 +566,12 @@ const ScPatternAttr* ScAttrArray::SetPatternAreaImpl(SCROW nStartRow, SCROW nEnd else if ( ni > 0 && ni == nInsert ) mvData[ni-1].nEndRow = nStartRow - 1; // shrink } - ScDocumentPool* pDocPool = rDocument.GetPool(); - if ( bSplit ) - { // duplicate split entry in pool - pDocPool->DirectPutItemInPool( *mvData[ni-1].pPattern ); - } if ( ni < nj ) { // remove middle entries - for ( SCSIZE nk=ni; nk<nj; nk++) - { // remove entries from pool - pDocPool->DirectRemoveItemFromPool( *mvData[nk].pPattern ); - } if ( !bCombined ) { // replace one entry mvData[ni].nEndRow = nEndRow; - mvData[ni].pPattern = pPattern; + mvData[ni].setScPatternAttr(pPattern); ni++; nInsert = rDocument.MaxRow() + 1; } @@ -614,7 +596,7 @@ const ScPatternAttr* ScAttrArray::SetPatternAreaImpl(SCROW nStartRow, SCROW nEnd if ( nInsert ) mvData[nInsert-1].nEndRow = nStartRow - 1; mvData[nInsert].nEndRow = nEndRow; - mvData[nInsert].pPattern = pPattern; + mvData[nInsert].setScPatternAttr(pPattern); // Remove character attributes from these cells if the pattern // is applied during normal session. @@ -651,7 +633,7 @@ void ScAttrArray::ApplyStyleArea( SCROW nStartRow, SCROW nEndRow, const ScStyleS do { - const ScPatternAttr* pOldPattern = mvData[nPos].pPattern; + const ScPatternAttr* pOldPattern = mvData[nPos].getScPatternAttr(); std::unique_ptr<ScPatternAttr> pNewPattern(new ScPatternAttr(*pOldPattern)); pNewPattern->SetStyleSheet(const_cast<ScStyleSheet*>(&rStyle)); SCROW nY1 = nStart; @@ -668,7 +650,7 @@ void ScAttrArray::ApplyStyleArea( SCROW nStartRow, SCROW nEndRow, const ScStyleS { if (nY1 < nStartRow) nY1=nStartRow; if (nY2 > nEndRow) nY2=nEndRow; - SetPatternArea( nY1, nY2, std::move(pNewPattern), true ); + SetPatternArea( nY1, nY2, CellAttributeHolder(pNewPattern.release(), true) ); Search( nStart, nPos ); } else @@ -690,8 +672,7 @@ void ScAttrArray::ApplyStyleArea( SCROW nStartRow, SCROW nEndRow, const ScStyleS } } - rDocument.GetPool()->DirectRemoveItemFromPool(*mvData[nPos].pPattern); - mvData[nPos].pPattern = &rDocument.GetPool()->DirectPutItemInPool(*pNewPattern); + mvData[nPos].setScPatternAttr(pNewPattern.release(), true); if (Concat(nPos)) Search(nStart, nPos); else @@ -746,7 +727,7 @@ void ScAttrArray::ApplyLineStyleArea( SCROW nStartRow, SCROW nEndRow, do { - const ScPatternAttr* pOldPattern = mvData[nPos].pPattern; + const ScPatternAttr* pOldPattern = mvData[nPos].getScPatternAttr(); const SfxItemSet& rOldSet = pOldPattern->GetItemSet(); const SvxBoxItem* pBoxItem = rOldSet.GetItemIfSet( ATTR_BORDER ); const SvxLineItem* pTLBRItem = rOldSet.GetItemIfSet( ATTR_BORDER_TLBR ); @@ -821,15 +802,13 @@ void ScAttrArray::ApplyLineStyleArea( SCROW nStartRow, SCROW nEndRow, { if (nY1 < nStartRow) nY1=nStartRow; if (nY2 > nEndRow) nY2=nEndRow; - SetPatternArea( nY1, nY2, std::move(pNewPattern), true ); + SetPatternArea( nY1, nY2, CellAttributeHolder(pNewPattern.release(), true) ); Search( nStart, nPos ); } else { // remove from pool ? - rDocument.GetPool()->DirectRemoveItemFromPool(*mvData[nPos].pPattern); - mvData[nPos].pPattern = - &rDocument.GetPool()->DirectPutItemInPool(std::move(pNewPattern)); + mvData[nPos].setScPatternAttr(pNewPattern.release(), true); if (Concat(nPos)) Search(nStart, nPos); @@ -846,7 +825,7 @@ void ScAttrArray::ApplyLineStyleArea( SCROW nStartRow, SCROW nEndRow, while ((nStart <= nEndRow) && (nPos < mvData.size())); } -void ScAttrArray::ApplyCacheArea( SCROW nStartRow, SCROW nEndRow, ScItemPoolCache* pCache, ScEditDataArray* pDataArray, bool* const pIsChanged ) +void ScAttrArray::ApplyCacheArea( SCROW nStartRow, SCROW nEndRow, ScItemPoolCache& rCache, ScEditDataArray* pDataArray, bool* const pIsChanged ) { #if DEBUG_SC_TESTATTRARRAY TestData(); @@ -869,9 +848,10 @@ void ScAttrArray::ApplyCacheArea( SCROW nStartRow, SCROW nEndRow, ScItemPoolCach do { - const ScPatternAttr& rOldPattern = *mvData[nPos].pPattern; - const ScPatternAttr& rNewPattern = pCache->ApplyTo( rOldPattern ); - if (!SfxPoolItem::areSame(rNewPattern, rOldPattern)) + const CellAttributeHolder& rOldPattern(mvData[nPos].getCellAttributeHolder()); + const CellAttributeHolder& rNewPattern(rCache.ApplyTo( rOldPattern )); + + if (!CellAttributeHolder::areSame(&rNewPattern, &rOldPattern)) { SCROW nY1 = nStart; SCROW nY2 = mvData[nPos].nEndRow; @@ -884,7 +864,7 @@ void ScAttrArray::ApplyCacheArea( SCROW nStartRow, SCROW nEndRow, ScItemPoolCach { if (nY1 < nStartRow) nY1=nStartRow; if (nY2 > nEndRow) nY2=nEndRow; - SetPatternArea( nY1, nY2, &rNewPattern, false, pDataArray ); + SetPatternArea( nY1, nY2, rNewPattern, pDataArray ); Search( nStart, nPos ); } else @@ -893,8 +873,8 @@ void ScAttrArray::ApplyCacheArea( SCROW nStartRow, SCROW nEndRow, ScItemPoolCach { // ensure attributing changes text-width of cell - const SfxItemSet& rNewSet = rNewPattern.GetItemSet(); - const SfxItemSet& rOldSet = rOldPattern.GetItemSet(); + const SfxItemSet& rNewSet = rNewPattern.getScPatternAttr()->GetItemSet(); + const SfxItemSet& rOldSet = rOldPattern.getScPatternAttr()->GetItemSet(); bool bNumFormatChanged; if ( ScGlobal::CheckWidthInvalidate( bNumFormatChanged, @@ -906,8 +886,7 @@ void ScAttrArray::ApplyCacheArea( SCROW nStartRow, SCROW nEndRow, ScItemPoolCach } } - rDocument.GetPool()->DirectRemoveItemFromPool(*mvData[nPos].pPattern); - mvData[nPos].pPattern = &rNewPattern; + mvData[nPos].setCellAttributeHolder(rNewPattern); if (Concat(nPos)) Search(nStart, nPos); else @@ -931,10 +910,6 @@ void ScAttrArray::ApplyCacheArea( SCROW nStartRow, SCROW nEndRow, ScItemPoolCach void ScAttrArray::SetAttrEntries(std::vector<ScAttrEntry> && vNewData) { - ScDocumentPool* pDocPool = rDocument.GetPool(); - for (auto const & rEntry : mvData) - pDocPool->DirectRemoveItemFromPool(*rEntry.pPattern); - mvData = std::move(vNewData); #ifdef DBG_UTIL @@ -1000,12 +975,12 @@ void ScAttrArray::MergePatternArea( SCROW nStartRow, SCROW nEndRow, do { // similar patterns must not be repeated - const ScPatternAttr* pPattern = nullptr; + const ScPatternAttr* pPattern(&rDocument.getCellAttributeHelper().getDefaultCellAttribute()); if ( !mvData.empty() ) - pPattern = mvData[nPos].pPattern; - else - pPattern = rDocument.GetDefPattern(); - if ( !SfxPoolItem::areSame(pPattern, rState.pOld1) && !SfxPoolItem::areSame(pPattern, rState.pOld2) ) + pPattern = mvData[nPos].getScPatternAttr(); + + if ( !ScPatternAttr::areSame(pPattern, rState.aOld1.getScPatternAttr()) + && !ScPatternAttr::areSame(pPattern, rState.aOld2.getScPatternAttr()) ) { const SfxItemSet& rThisSet = pPattern->GetItemSet(); if (rState.pItemSet) @@ -1024,8 +999,8 @@ void ScAttrArray::MergePatternArea( SCROW nStartRow, SCROW nEndRow, rState.mnPatternId = pPattern->GetPAKey(); } - rState.pOld2 = rState.pOld1; - rState.pOld1 = pPattern; + rState.aOld2 = rState.aOld1; + rState.aOld1 = pPattern; } if ( !mvData.empty() ) @@ -1156,7 +1131,7 @@ void ScAttrArray::MergeBlockFrame( SvxBoxItem* pLineOuter, SvxBoxInfoItem* pLine Search( nEndRow-1, nEndIndex ); for (SCSIZE i=nStartIndex; i<=nEndIndex; i++) { - pPattern = mvData[i].pPattern; + pPattern = mvData[i].getScPatternAttr(); lcl_MergeToFrame( pLineOuter, pLineInner, rFlags, pPattern, bLeft, nDistRight, false, nEndRow - std::min( mvData[i].nEndRow, static_cast<SCROW>(nEndRow-1) ) ); // nDistBottom here always > 0 @@ -1167,7 +1142,7 @@ void ScAttrArray::MergeBlockFrame( SvxBoxItem* pLineOuter, SvxBoxInfoItem* pLine } else { - lcl_MergeToFrame( pLineOuter, pLineInner, rFlags, rDocument.GetDefPattern(), bLeft, nDistRight, true, 0 ); + lcl_MergeToFrame( pLineOuter, pLineInner, rFlags, &rDocument.getCellAttributeHelper().getDefaultCellAttribute(), bLeft, nDistRight, true, 0 ); } } @@ -1237,8 +1212,8 @@ bool ScAttrArray::ApplyFrame( const SvxBoxItem& rBoxItem, } else { - ScItemPoolCache aCache( rDocument.GetPool(), &aNewFrame ); - ApplyCacheArea( nStartRow, nEndRow, &aCache ); + ScItemPoolCache aCache( rDocument.getCellAttributeHelper(), aNewFrame ); + ApplyCacheArea( nStartRow, nEndRow, aCache ); return true; } @@ -1410,7 +1385,7 @@ bool ScAttrArray::HasAttrib( SCROW nRow1, SCROW nRow2, HasAttrFlags nMask ) cons { if (mvData.empty()) { - return HasAttrib_Impl(rDocument.GetDefPattern(), nMask, 0, rDocument.MaxRow(), 0); + return HasAttrib_Impl(&rDocument.getCellAttributeHelper().getDefaultCellAttribute(), nMask, 0, rDocument.MaxRow(), 0); } SCSIZE nStartIndex; @@ -1424,7 +1399,7 @@ bool ScAttrArray::HasAttrib( SCROW nRow1, SCROW nRow2, HasAttrFlags nMask ) cons for (SCSIZE i=nStartIndex; i<=nEndIndex && !bFound; i++) { - const ScPatternAttr* pPattern = mvData[i].pPattern; + const ScPatternAttr* pPattern = mvData[i].getScPatternAttr(); bFound = HasAttrib_Impl(pPattern, nMask, nRow1, nRow2, i); } @@ -1439,7 +1414,7 @@ bool ScAttrArray::HasAttrib( SCROW nRow, HasAttrFlags nMask, SCROW* nStartRow, S *nStartRow = 0; if( nEndRow ) *nEndRow = rDocument.MaxRow(); - return HasAttrib_Impl(rDocument.GetDefPattern(), nMask, 0, rDocument.MaxRow(), 0); + return HasAttrib_Impl(&rDocument.getCellAttributeHelper().getDefaultCellAttribute(), nMask, 0, rDocument.MaxRow(), 0); } SCSIZE nIndex; @@ -1448,7 +1423,7 @@ bool ScAttrArray::HasAttrib( SCROW nRow, HasAttrFlags nMask, SCROW* nStartRow, S *nStartRow = nIndex > 0 ? mvData[nIndex-1].nEndRow+1 : 0; if( nEndRow ) *nEndRow = mvData[nIndex].nEndRow; - const ScPatternAttr* pPattern = mvData[nIndex].pPattern; + const ScPatternAttr* pPattern = mvData[nIndex].getScPatternAttr(); return HasAttrib_Impl(pPattern, nMask, nRow, nRow, nIndex); } @@ -1458,12 +1433,12 @@ bool ScAttrArray::IsMerged( SCROW nRow ) const { SCSIZE nIndex; Search(nRow, nIndex); - const ScMergeAttr& rItem = mvData[nIndex].pPattern->GetItem(ATTR_MERGE); + const ScMergeAttr& rItem = mvData[nIndex].getScPatternAttr()->GetItem(ATTR_MERGE); return rItem.IsMerged(); } - return rDocument.GetDefPattern()->GetItem(ATTR_MERGE).IsMerged(); + return rDocument.getCellAttributeHelper().getDefaultCellAttribute().GetItem(ATTR_MERGE).IsMerged(); } /** @@ -1485,7 +1460,7 @@ bool ScAttrArray::ExtendMerge( SCCOL nThisCol, SCROW nStartRow, SCROW nEndRow, for (SCSIZE i=nStartIndex; i<=nEndIndex; i++) { - pPattern = mvData[i].pPattern; + pPattern = mvData[i].getScPatternAttr(); pItem = &pPattern->GetItem( ATTR_MERGE ); SCCOL nCountX = pItem->GetColMerge(); SCROW nCountY = pItem->GetRowMerge(); @@ -1541,7 +1516,7 @@ void ScAttrArray::RemoveAreaMerge(SCROW nStartRow, SCROW nEndRow) if (nThisEnd > nEndRow) nThisEnd = nEndRow; - pPattern = mvData[nIndex].pPattern; + pPattern = mvData[nIndex].getScPatternAttr(); pItem = &pPattern->GetItem( ATTR_MERGE ); SCCOL nCountX = pItem->GetColMerge(); SCROW nCountY = pItem->GetRowMerge(); @@ -1560,7 +1535,7 @@ void ScAttrArray::RemoveAreaMerge(SCROW nStartRow, SCROW nEndRow) for (SCROW nThisRow = nThisStart; nThisRow <= nThisEnd; nThisRow++) rDocument.ApplyAttr( nThisCol, nThisRow, nTab, *pAttr ); - ScPatternAttr aNewPattern( rDocument.GetPool() ); + ScPatternAttr aNewPattern( rDocument.getCellAttributeHelper() ); SfxItemSet* pSet = &aNewPattern.GetItemSet(); pSet->Put( *pFlagAttr ); rDocument.ApplyPatternAreaTab( nThisCol, nThisStart, nMergeEndCol, nMergeEndRow, @@ -1577,51 +1552,40 @@ void ScAttrArray::RemoveAreaMerge(SCROW nStartRow, SCROW nEndRow) } } -void ScAttrArray::SetPatternAreaSafe( SCROW nStartRow, SCROW nEndRow, - const ScPatternAttr* pWantedPattern, bool bDefault ) +void ScAttrArray::SetPatternAreaSafe(SCROW nStartRow, SCROW nEndRow, const CellAttributeHolder& rWantedPattern) { SetDefaultIfNotInit(); - const ScPatternAttr* pOldPattern; - const ScMergeFlagAttr* pItem; + const ScMergeFlagAttr* pItem; SCSIZE nIndex; SCROW nRow; SCROW nThisRow; - bool bFirstUse = true; Search( nStartRow, nIndex ); nThisRow = (nIndex>0) ? mvData[nIndex-1].nEndRow+1 : 0; while ( nThisRow <= nEndRow ) { - pOldPattern = mvData[nIndex].pPattern; - if (!SfxPoolItem::areSame(pOldPattern, pWantedPattern)) // FIXME: else-branch? + const CellAttributeHolder& rOldPattern(mvData[nIndex].getCellAttributeHolder()); + if (!CellAttributeHolder::areSame(&rOldPattern, &rWantedPattern)) // FIXME: else-branch? { if (nThisRow < nStartRow) nThisRow = nStartRow; nRow = mvData[nIndex].nEndRow; SCROW nAttrRow = std::min( nRow, nEndRow ); - pItem = &pOldPattern->GetItem( ATTR_MERGE_FLAG ); + pItem = &rOldPattern.getScPatternAttr()->GetItem( ATTR_MERGE_FLAG ); if (pItem->IsOverlapped() || pItem->HasAutoFilter()) { // default-constructing a ScPatternAttr for DeleteArea doesn't work // because it would have no cell style information. - // Instead, the document's GetDefPattern is copied. Since it is passed as + // Instead, the document's getCellAttributeHelper().getDefaultCellAttribute() is copied. Since it is passed as // pWantedPattern, no special treatment of default is needed here anymore. - std::unique_ptr<ScPatternAttr> pNewPattern(new ScPatternAttr( *pWantedPattern )); + ScPatternAttr* pNewPattern(new ScPatternAttr(*rWantedPattern.getScPatternAttr())); pNewPattern->GetItemSet().Put( *pItem ); - SetPatternArea( nThisRow, nAttrRow, std::move(pNewPattern), true ); + SetPatternArea( nThisRow, nAttrRow, CellAttributeHolder(pNewPattern, true) ); } else { - if ( !bDefault ) - { - if (bFirstUse) - bFirstUse = false; - else - // it's in the pool - rDocument.GetPool()->DirectPutItemInPool( *pWantedPattern ); - } - SetPatternArea( nThisRow, nAttrRow, pWantedPattern ); + SetPatternArea(nThisRow, nAttrRow, rWantedPattern); } Search( nThisRow, nIndex ); // data changed @@ -1649,15 +1613,15 @@ bool ScAttrArray::ApplyFlags( SCROW nStartRow, SCROW nEndRow, ScMF nFlags ) while ( nThisRow <= nEndRow ) { - pOldPattern = mvData[nIndex].pPattern; + pOldPattern = mvData[nIndex].getScPatternAttr(); nOldValue = pOldPattern->GetItem( ATTR_MERGE_FLAG ).GetValue(); if ( (nOldValue | nFlags) != nOldValue ) { nRow = mvData[nIndex].nEndRow; SCROW nAttrRow = std::min( nRow, nEndRow ); - auto pNewPattern = std::make_unique<ScPatternAttr>(*pOldPattern); + ScPatternAttr* pNewPattern(new ScPatternAttr(*pOldPattern)); pNewPattern->GetItemSet().Put( ScMergeFlagAttr( nOldValue | nFlags ) ); - SetPatternArea( nThisRow, nAttrRow, std::move(pNewPattern), true ); + SetPatternArea( nThisRow, nAttrRow, CellAttributeHolder(pNewPattern, true) ); Search( nThisRow, nIndex ); // data changed bChanged = true; } @@ -1686,15 +1650,15 @@ bool ScAttrArray::RemoveFlags( SCROW nStartRow, SCROW nEndRow, ScMF nFlags ) while ( nThisRow <= nEndRow ) { - pOldPattern = mvData[nIndex].pPattern; + pOldPattern = mvData[nIndex].getScPatternAttr(); nOldValue = pOldPattern->GetItem( ATTR_MERGE_FLAG ).GetValue(); if ( (nOldValue & ~nFlags) != nOldValue ) { nRow = mvData[nIndex].nEndRow; SCROW nAttrRow = std::min( nRow, nEndRow ); - auto pNewPattern = std::make_unique<ScPatternAttr>(*pOldPattern); + ScPatternAttr* pNewPattern(new ScPatternAttr(*pOldPattern)); pNewPattern->GetItemSet().Put( ScMergeFlagAttr( nOldValue & ~nFlags ) ); - SetPatternArea( nThisRow, nAttrRow, std::move(pNewPattern), true ); + SetPatternArea( nThisRow, nAttrRow, CellAttributeHolder(pNewPattern, true) ); Search( nThisRow, nIndex ); // data changed bChanged = true; } @@ -1719,15 +1683,15 @@ void ScAttrArray::ClearItems( SCROW nStartRow, SCROW nEndRow, const sal_uInt16* while ( nThisRow <= nEndRow ) { - const ScPatternAttr* pOldPattern = mvData[nIndex].pPattern; + const ScPatternAttr* pOldPattern = mvData[nIndex].getScPatternAttr(); if ( pOldPattern->HasItemsSet( pWhich ) ) { - auto pNewPattern = std::make_unique<ScPatternAttr>(*pOldPattern); + ScPatternAttr* pNewPattern(new ScPatternAttr(*pOldPattern)); pNewPattern->ClearItems( pWhich ); nRow = mvData[nIndex].nEndRow; SCROW nAttrRow = std::min( nRow, nEndRow ); - SetPatternArea( nThisRow, nAttrRow, std::move(pNewPattern), true ); + SetPatternArea( nThisRow, nAttrRow, CellAttributeHolder(pNewPattern, true) ); Search( nThisRow, nIndex ); // data changed } @@ -1746,7 +1710,7 @@ void ScAttrArray::ChangeIndent( SCROW nStartRow, SCROW nEndRow, bool bIncrement while ( nThisStart <= nEndRow ) { - const ScPatternAttr* pOldPattern = mvData[nIndex].pPattern; + const ScPatternAttr* pOldPattern = mvData[nIndex].getScPatternAttr(); const SfxItemSet& rOldSet = pOldPattern->GetItemSet(); const SvxHorJustifyItem* pItem; @@ -1782,12 +1746,12 @@ void ScAttrArray::ChangeIndent( SCROW nStartRow, SCROW nEndRow, bool bIncrement { SCROW nThisEnd = mvData[nIndex].nEndRow; SCROW nAttrRow = std::min( nThisEnd, nEndRow ); - auto pNewPattern = std::make_unique<ScPatternAttr>(*pOldPattern); + ScPatternAttr* pNewPattern(new ScPatternAttr(*pOldPattern)); pNewPattern->GetItemSet().Put( ScIndentItem( nNewValue ) ); if ( bNeedJust ) pNewPattern->GetItemSet().Put( SvxHorJustifyItem( SvxCellHorJustify::Left, ATTR_HOR_JUSTIFY ) ); - SetPatternArea( nThisStart, nAttrRow, std::move(pNewPattern), true ); + SetPatternArea( nThisStart, nAttrRow, CellAttributeHolder(pNewPattern, true) ); nThisStart = nThisEnd + 1; Search( nThisStart, nIndex ); // data changed @@ -1815,8 +1779,7 @@ SCROW ScAttrArray::GetNextUnprotected( SCROW nRow, bool bUp ) const SCSIZE nIndex; Search(nRow, nIndex); - while (mvData[nIndex].pPattern-> - GetItem(ATTR_PROTECTION).GetProtection()) + while (mvData[nIndex].getScPatternAttr()->GetItem(ATTR_PROTECTION).GetProtection()) { if (bUp) { @@ -1845,20 +1808,19 @@ void ScAttrArray::FindStyleSheet( const SfxStyleSheetBase* pStyleSheet, ScFlatBo while (nPos < mvData.size()) { SCROW nEnd = mvData[nPos].nEndRow; - if (mvData[nPos].pPattern->GetStyleSheet() == pStyleSheet) + if (mvData[nPos].getScPatternAttr()->GetStyleSheet() == pStyleSheet) { rUsedRows.setTrue(nStart, nEnd); if (bReset) { - ScPatternAttr aNewPattern(*mvData[nPos].pPattern); - rDocument.GetPool()->DirectRemoveItemFromPool(*mvData[nPos].pPattern); - aNewPattern.SetStyleSheet( static_cast<ScStyleSheet*>( + ScPatternAttr* pNewPattern(new ScPatternAttr(*mvData[nPos].getScPatternAttr())); + pNewPattern->SetStyleSheet( static_cast<ScStyleSheet*>( rDocument.GetStyleSheetPool()-> Find( ScResId(STR_STYLENAME_STANDARD), SfxStyleFamily::Para, SfxStyleSearchBits::Auto | SfxStyleSearchBits::ScStandard ) ) ); - mvData[nPos].pPattern = &rDocument.GetPool()->DirectPutItemInPool(aNewPattern); + mvData[nPos].setScPatternAttr(pNewPattern, true); if (Concat(nPos)) { @@ -1876,7 +1838,7 @@ bool ScAttrArray::IsStyleSheetUsed( const ScStyleSheet& rStyle ) const { if ( mvData.empty() ) { - const ScStyleSheet* pStyle = rDocument.GetDefPattern()->GetStyleSheet(); + const ScStyleSheet* pStyle = rDocument.getCellAttributeHelper().getDefaultCellAttribute().GetStyleSheet(); if ( pStyle ) { pStyle->SetUsage( ScStyleSheet::Usage::USED ); @@ -1891,7 +1853,7 @@ bool ScAttrArray::IsStyleSheetUsed( const ScStyleSheet& rStyle ) const while ( nPos < mvData.size() ) { - const ScStyleSheet* pStyle = mvData[nPos].pPattern->GetStyleSheet(); + const ScStyleSheet* pStyle = mvData[nPos].getScPatternAttr()->GetStyleSheet(); if ( pStyle ) { pStyle->SetUsage( ScStyleSheet::Usage::USED ); @@ -1913,7 +1875,7 @@ bool ScAttrArray::IsEmpty() const if (mvData.size() == 1) { - return SfxPoolItem::areSame(mvData[0].pPattern, rDocument.GetDefPattern()); + return mvData[0].getScPatternAttr()->isDefault(); } else return false; @@ -1931,14 +1893,14 @@ bool ScAttrArray::GetFirstVisibleAttr( SCROW& rFirstRow ) const // Entries at the end are not skipped, GetFirstVisibleAttr may be larger than GetLastVisibleAttr. SCSIZE nVisStart = 1; - while ( nVisStart < mvData.size() && mvData[nVisStart].pPattern->IsVisibleEqual(*mvData[nVisStart-1].pPattern) ) + while ( nVisStart < mvData.size() && mvData[nVisStart].getScPatternAttr()->IsVisibleEqual(*mvData[nVisStart-1].getScPatternAttr()) ) ++nVisStart; if ( nVisStart >= mvData.size() || mvData[nVisStart-1].nEndRow > 0 ) // more than 1 row? nStart = nVisStart; while ( nStart < mvData.size() && !bFound ) { - if ( mvData[nStart].pPattern->IsVisible() ) + if ( mvData[nStart].getScPatternAttr()->IsVisible() ) { rFirstRow = nStart ? ( mvData[nStart-1].nEndRow + 1 ) : 0; bFound = true; @@ -1995,7 +1957,7 @@ bool ScAttrArray::GetLastVisibleAttr( SCROW& rLastRow, SCROW nLastData, bool bSk // find range of visually equal formats SCSIZE nEndPos = nPos; while ( nEndPos < mvData.size()-1 && - mvData[nEndPos].pPattern->IsVisibleEqual(*mvData[nEndPos+1].pPattern)) + mvData[nEndPos].getScPatternAttr()->IsVisibleEqual(*mvData[nEndPos+1].getScPatternAttr())) ++nEndPos; SCROW nAttrStartRow = ( nPos > 0 ) ? ( mvData[nPos-1].nEndRow + 1) : 0; if ( nAttrStartRow <= nLastData ) @@ -2003,7 +1965,7 @@ bool ScAttrArray::GetLastVisibleAttr( SCROW& rLastRow, SCROW nLastData, bool bSk SCROW nAttrSize = mvData[nEndPos].nEndRow + 1 - nAttrStartRow; if ( nAttrSize >= SC_VISATTR_STOP ) break; // while, ignore this range and below - else if ( mvData[nEndPos].pPattern->IsVisible() ) + else if ( mvData[nEndPos].getScPatternAttr()->IsVisible() ) { rLastRow = mvData[nEndPos].nEndRow; bFound = true; @@ -2013,8 +1975,8 @@ bool ScAttrArray::GetLastVisibleAttr( SCROW& rLastRow, SCROW nLastData, bool bSk } else { - if ((nPos > 0 && mvData[nPos-1].pPattern->IsVisible()) - || (nPos > 1 && !mvData[nPos-1].pPattern->IsVisibleEqual(*mvData[nPos-2].pPattern))) + if ((nPos > 0 && mvData[nPos-1].getScPatternAttr()->IsVisible()) + || (nPos > 1 && !mvData[nPos-1].getScPatternAttr()->IsVisibleEqual(*mvData[nPos-2].getScPatternAttr()))) { rLastRow = mvData[nPos-1].nEndRow; return true; @@ -2027,7 +1989,7 @@ bool ScAttrArray::GetLastVisibleAttr( SCROW& rLastRow, SCROW nLastData, bool bSk bool ScAttrArray::HasVisibleAttrIn( SCROW nStartRow, SCROW nEndRow ) const { if ( mvData.empty() ) - return rDocument.GetDefPattern()->IsVisible(); + return rDocument.getCellAttributeHelper().getDefaultCellAttribute().IsVisible(); SCSIZE nIndex; Search( nStartRow, nIndex ); @@ -2035,7 +1997,7 @@ bool ScAttrArray::HasVisibleAttrIn( SCROW nStartRow, SCROW nEndRow ) const bool bFound = false; while ( nIndex < mvData.size() && nThisStart <= nEndRow && !bFound ) { - if ( mvData[nIndex].pPattern->IsVisible() ) + if ( mvData[nIndex].getScPatternAttr()->IsVisible() ) bFound = true; nThisStart = mvData[nIndex].nEndRow + 1; @@ -2050,9 +2012,9 @@ bool ScAttrArray::IsVisibleEqual( const ScAttrArray& rOther, { if ( mvData.empty() && rOther.mvData.empty() ) { - const ScPatternAttr* pDefPattern1 = rDocument.GetDefPattern(); - const ScPatternAttr* pDefPattern2 = rOther.rDocument.GetDefPattern(); - return ( SfxPoolItem::areSame(pDefPattern1, pDefPattern2) || pDefPattern1->IsVisibleEqual( *pDefPattern2 ) ); + const ScPatternAttr* pDefPattern1(&rDocument.getCellAttributeHelper().getDefaultCellAttribute()); + const ScPatternAttr* pDefPattern2(&rOther.rDocument.getCellAttributeHelper().getDefaultCellAttribute()); + return ( ScPatternAttr::areSame(pDefPattern1, pDefPattern2) || pDefPattern1->IsVisibleEqual( *pDefPattern2 ) ); } { @@ -2062,13 +2024,13 @@ bool ScAttrArray::IsVisibleEqual( const ScAttrArray& rOther, if ( mvData.empty() && !rOther.mvData.empty() ) { pNonDefault = &rOther; - pDefPattern = rDocument.GetDefPattern(); + pDefPattern = &rDocument.getCellAttributeHelper().getDefaultCellAttribute(); bDefNonDefCase = true; } else if ( !mvData.empty() && rOther.mvData.empty() ) { pNonDefault = this; - pDefPattern = rOther.rDocument.GetDefPattern(); + pDefPattern = &rOther.rDocument.getCellAttributeHelper().getDefaultCellAttribute(); bDefNonDefCase = true; } @@ -2081,9 +2043,8 @@ bool ScAttrArray::IsVisibleEqual( const ScAttrArray& rOther, while ( nPos < pNonDefault->Count() && bEqual ) { - const ScPatternAttr* pNonDefPattern = pNonDefault->mvData[nPos].pPattern; - bEqual = ( SfxPoolItem::areSame(pNonDefPattern, pDefPattern) || - pNonDefPattern->IsVisibleEqual( *pDefPattern ) ); + const ScPatternAttr* pNonDefPattern = pNonDefault->mvData[nPos].getScPatternAttr(); + bEqual = ScPatternAttr::areSame(pNonDefPattern, pDefPattern) || pNonDefPattern->IsVisibleEqual( *pDefPattern ); if ( pNonDefault->mvData[nPos].nEndRow >= nEndRow ) break; ++nPos; @@ -2105,10 +2066,9 @@ bool ScAttrArray::IsVisibleEqual( const ScAttrArray& rOther, { SCROW nThisRow = mvData[nThisPos].nEndRow; SCROW nOtherRow = rOther.mvData[nOtherPos].nEndRow; - const ScPatternAttr* pThisPattern = mvData[nThisPos].pPattern; - const ScPatternAttr* pOtherPattern = rOther.mvData[nOtherPos].pPattern; - bEqual = ( SfxPoolItem::areSame(pThisPattern, pOtherPattern) || - pThisPattern->IsVisibleEqual(*pOtherPattern) ); + const ScPatternAttr* pThisPattern = mvData[nThisPos].getScPatternAttr(); + const ScPatternAttr* pOtherPattern = rOther.mvData[nOtherPos].getScPatternAttr(); + bEqual = ( ScPatternAttr::areSame(pThisPattern, pOtherPattern) || pThisPattern->IsVisibleEqual(*pOtherPattern) ); if ( nThisRow >= nOtherRow ) { @@ -2130,9 +2090,9 @@ bool ScAttrArray::IsAllEqual( const ScAttrArray& rOther, SCROW nStartRow, SCROW // summarised with IsVisibleEqual if ( mvData.empty() && rOther.mvData.empty() ) { - const ScPatternAttr* pDefPattern1 = rDocument.GetDefPattern(); - const ScPatternAttr* pDefPattern2 = rOther.rDocument.GetDefPattern(); - return SfxPoolItem::areSame(pDefPattern1, pDefPattern2); + const ScPatternAttr* pDefPattern1(&rDocument.getCellAttributeHelper().getDefaultCellAttribute()); + const ScPatternAttr* pDefPattern2(&rOther.rDocument.getCellAttributeHelper().getDefaultCellAttribute()); + return ScPatternAttr::areSame(pDefPattern1, pDefPattern2); } { @@ -2142,13 +2102,13 @@ bool ScAttrArray::IsAllEqual( const ScAttrArray& rOther, SCROW nStartRow, SCROW if ( mvData.empty() && !rOther.mvData.empty() ) { pNonDefault = &rOther; - pDefPattern = rDocument.GetDefPattern(); + pDefPattern = &rDocument.getCellAttributeHelper().getDefaultCellAttribute(); bDefNonDefCase = true; } else if ( !mvData.empty() && rOther.mvData.empty() ) { pNonDefault = this; - pDefPattern = rOther.rDocument.GetDefPattern(); + pDefPattern = &rOther.rDocument.getCellAttributeHelper().getDefaultCellAttribute(); bDefNonDefCase = true; } @@ -2161,8 +2121,8 @@ bool ScAttrArray::IsAllEqual( const ScAttrArray& rOther, SCROW nStartRow, SCROW while ( nPos < pNonDefault->Count() && bEqual ) { - const ScPatternAttr* pNonDefPattern = pNonDefault->mvData[nPos].pPattern; - bEqual = SfxPoolItem::areSame( pNonDefPattern, pDefPattern ); + const ScPatternAttr* pNonDefPattern = pNonDefault->mvData[nPos].getScPatternAttr(); + bEqual = ScPatternAttr::areSame( pNonDefPattern, pDefPattern ); -e ... etc. - the rest is truncated