diff options
author | Armin Le Grand (allotropia) <armin.le.grand.extern@allotropia.de> | 2024-01-10 20:07:47 +0100 |
---|---|---|
committer | Armin Le Grand <Armin.Le.Grand@me.com> | 2024-01-12 12:15:54 +0100 |
commit | ae7807c889c19145f89cec40afac82eee191837c (patch) | |
tree | e31e4a541555f3618e8173e24b79c5186d840607 /sc/source/filter/xml | |
parent | 8f215fab5593070556e903121cc195660e16105c (diff) |
ITEM: No longer register Items at Pool
The issue is that the flag RegisteredAtPool
at the SfxPoolItem is Pool-dependent: It marks that
the Item is registeres at *one* Pool/Model. This
makes it Pool-dependent. Due to this there is no way
to share Items that need to be registered globally/
in multiple Pools/Models what is one of the goals
for optimal sharing.
We can also not live without having access to all
Items associated with the Pool, due to mechanisms
in place like the Surrogate stuff.
This again is used for two purposes:
(1) Access all Items associated with one Pool/Model,
at least that is the assumption. This is not valid
since it gets corrupted with a single ItemSet/Holder
used that does not host model data, e.g. an open
Dialog or the Sidebar (or...). But works in
principle.
(2) Access extra-Items that are held nowhere and
are created using DirectPutItemInPool, e.g. infos
for a Dialog. These would need a instance/place to
host them, the Pool is (ab)used for that.
Both are 'compromizes' (to not use a more bad word)
and should not exist. (1) should iterate over the
Model and do actions. There are even places that
use (1) to *change* Items, by casting them to
non-const, even RefCounted ones, so having no control
over what all might be changed doing so. Since we
talk about ca. 100+ places there is no way to get
away from this - I can imagine how this happened:
The 'poolable' attr traditionally needed for the old
binary format was one day 'used' to not need to
iterate over the Model, an API was added to access
and this usage was copied. Sigh..
It is even used when ODF is loaded: E.g. the
FillStyle is imported from XML, interpreted, and
put into an ItemSet. Then it gets set at the
XShape using UNO API and a *name* -> that name and
the Surrogate mechanism is used to find and set the
FillStyle at the Model Object. The FillStyle could
probably just be set using UNO API and the data
directly.
The association between Model/Pool and Item is
created by the object hosting the Item, these are
ItemSets and ItemHolders. Thus it is possible to
register these at the Pool. This allows to iterate
and collect the Items associated with the Pool
and keep the Surrogate mechanism alive.
This is the main change done here. It limits
the registrations to Items for which (at the Pool)
the NeedsPoolRegistration is set, also
Item-independent. Speed is okay, I saw no big
changes in my tests here. The registration is
just pointers, no ownership or RefCounting needed
here.
The advantage is that Items get closer to be
shared office-wide, they can be referenced by
multiple ItemSets (RefCnt) associated with
different Pools/Models.
NOTE: This is not true for SfxSetItems, these are
and will stay Pool-dependent due to their need
to a Pool in the contained ItemSet.
Note that we have ca. six deivations of SfxSetItem,
but ca. 500+ Item derivations, so not too bad.
For the usages of Surrogates to change existing,
RefCounted Items: These can now at least be
changed - if they show up to be problematic - to
iterate over the registered ItemSets and change
Items there the correct way: Set a changed one
at the ItemSet. That also allows Objects to
*react* on ItemChanges, there is no way to do
that with the existing 'compromize'...
UnitTests show that this already works well for
SC and SD, but SW has still some issues. I will
put this to gerrit now, but there will be
additional work.
A involved problem is the current DefaultItem
handling and the state the Pool implementation
is in. E.g. StaticDefaults are not really static,
Pools hard-delete the DefaultItems (forcing the
RefCnt to zero to not have the destructor
complain) and other quirks. Looking at that
right now, hoping to get this change done without
having to change that too much.
I thought about adapting PoolItemTest to this,
but it is only related to DirectPutItemInPool
which is mostly gone and hopefully completely
soon.
Nonetheless I adapted that mechanism to use a
list of SfxPoolItemHolder at the Pool. That makes
it safe and abandons the need for indirect
garbage collection removal at the Pool.
Change-Id: Ib47f21dafa989202930919eace5f7e9c5632ce96
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161896
Tested-by: Jenkins
Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
Diffstat (limited to 'sc/source/filter/xml')
-rw-r--r-- | sc/source/filter/xml/xmlexprt.cxx | 4 | ||||
-rw-r--r-- | sc/source/filter/xml/xmlfonte.cxx | 8 |
2 files changed, 9 insertions, 3 deletions
diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx index 9da5da65b7e6..4ec6ab6cdbb6 100644 --- a/sc/source/filter/xml/xmlexprt.cxx +++ b/sc/source/filter/xml/xmlexprt.cxx @@ -5329,7 +5329,9 @@ XMLNumberFormatAttributesExportHelper* ScXMLExport::GetNumberFormatAttributesExp void ScXMLExport::CollectUserDefinedNamespaces(const SfxItemPool* pPool, sal_uInt16 nAttrib) { - for (const SfxPoolItem* pItem : pPool->GetItemSurrogates(nAttrib)) + ItemSurrogates aSurrogates; + pPool->GetItemSurrogates(aSurrogates, nAttrib); + for (const SfxPoolItem* pItem : aSurrogates) { const SvXMLAttrContainerItem *pUnknown(static_cast<const SvXMLAttrContainerItem *>(pItem)); if( pUnknown->GetAttrCount() > 0 ) diff --git a/sc/source/filter/xml/xmlfonte.cxx b/sc/source/filter/xml/xmlfonte.cxx index ab8e42f4ce60..f6951eddb0b8 100644 --- a/sc/source/filter/xml/xmlfonte.cxx +++ b/sc/source/filter/xml/xmlfonte.cxx @@ -59,7 +59,9 @@ void ScXMLFontAutoStylePool_Impl::AddFontItems(const sal_uInt16* pWhichIds, sal_ pFont->GetFamily(), pFont->GetPitch(), pFont->GetCharSet() ); } - for (const SfxPoolItem* pItem : pItemPool->GetItemSurrogates( nWhichId )) + ItemSurrogates aSurrogates; + pItemPool->GetItemSurrogates( aSurrogates, nWhichId ); + for (const SfxPoolItem* pItem : aSurrogates) { const SvxFontItem *pFont(static_cast<const SvxFontItem *>(pItem)); Add( pFont->GetFamilyName(), pFont->GetStyleName(), @@ -111,7 +113,9 @@ ScXMLFontAutoStylePool_Impl::ScXMLFontAutoStylePool_Impl(ScXMLExport& rExportP, for (sal_uInt16 nPageWhichId : aPageWhichIds) { - for (const SfxPoolItem* pItem : rPagePool.GetItemSurrogates( nPageWhichId )) + ItemSurrogates aSurrogates; + rPagePool.GetItemSurrogates( aSurrogates, nPageWhichId ); + for (const SfxPoolItem* pItem : aSurrogates) { const ScPageHFItem* pPageItem = static_cast<const ScPageHFItem*>(pItem); const EditTextObject* pLeftArea(pPageItem->GetLeftArea()); |