sw/inc/doc.hxx | 6 ++++++ sw/source/core/bastyp/init.cxx | 4 ++-- sw/source/core/doc/doc.cxx | 39 +++++++++++++++++++++++++++++++++++++++ sw/source/core/doc/docfmt.cxx | 9 +++------ sw/source/filter/xml/xmlexp.cxx | 19 ++++++++++++++++--- 5 files changed, 66 insertions(+), 11 deletions(-)
New commits: commit 01ab23b13297c9d7b091dfbe2850cd343fcd3e0e Author: Noel Grandin <noelgran...@gmail.com> AuthorDate: Thu Sep 19 19:53:53 2024 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Fri Sep 20 07:52:02 2024 +0200 dont use GetItemSurrogates for gathering SvxTabStopItem which is very expensive these days Change-Id: Iae80c9d677fd1db8606a6a3f9462fe16b110a540 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173682 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx index c11f23dcf6f6..0e16a9607e34 100644 --- a/sw/inc/doc.hxx +++ b/sw/inc/doc.hxx @@ -1458,6 +1458,9 @@ public: /// Iterate over all RES_TXTATR_UNKNOWN_CONTAINER SvXMLAttrContainerItem, if the function returns false, iteration is stopped SW_DLLPUBLIC void ForEachTxtAtrContainerItem(const std::function<bool(const SvXMLAttrContainerItem&)>& ) const; + /// Iterate over all RES_PARATR_TABSTOP SvxTabStopItem, if the function returns false, iteration is stopped + SW_DLLPUBLIC void ForEachParaAtrTabStopItem(const std::function<bool(const SvxTabStopItem&)>& ) const; + // Call into intransparent Basic; expect possible Return String. void ExecMacro( const SvxMacro& rMacro, OUString* pRet, SbxArray* pArgs ); diff --git a/sw/source/core/bastyp/init.cxx b/sw/source/core/bastyp/init.cxx index b5b409705f1a..9c1fb0bb62c5 100644 --- a/sw/source/core/bastyp/init.cxx +++ b/sw/source/core/bastyp/init.cxx @@ -358,7 +358,7 @@ ItemInfoPackage& getItemInfoPackageSwAttributes() { RES_PARATR_SPLIT, new SvxFormatSplitItem( true, RES_PARATR_SPLIT ), SID_ATTR_PARA_SPLIT, SFX_ITEMINFOFLAG_NONE }, { RES_PARATR_ORPHANS, new SvxOrphansItem( 0, RES_PARATR_ORPHANS ), SID_ATTR_PARA_ORPHANS, SFX_ITEMINFOFLAG_NONE }, { RES_PARATR_WIDOWS, new SvxWidowsItem( 0, RES_PARATR_WIDOWS ), SID_ATTR_PARA_WIDOWS, SFX_ITEMINFOFLAG_NONE }, - { RES_PARATR_TABSTOP, new SvxTabStopItem( 1, SVX_TAB_DEFDIST, SvxTabAdjust::Default, RES_PARATR_TABSTOP ), SID_ATTR_TABSTOP, SFX_ITEMINFOFLAG_SUPPORT_SURROGATE }, + { RES_PARATR_TABSTOP, new SvxTabStopItem( 1, SVX_TAB_DEFDIST, SvxTabAdjust::Default, RES_PARATR_TABSTOP ), SID_ATTR_TABSTOP, SFX_ITEMINFOFLAG_NONE }, // for this at the Item GetMaxHyphens() = 0 was called, do this now on-demand at construction time // it will get added in constructor below once for LO runtime as static default diff --git a/sw/source/core/doc/doc.cxx b/sw/source/core/doc/doc.cxx index 2be295986df3..1f2db1ab6668 100644 --- a/sw/source/core/doc/doc.cxx +++ b/sw/source/core/doc/doc.cxx @@ -1521,6 +1521,18 @@ void SwDoc::ForEachTxtAtrContainerItem(const std::function<bool(const SvXMLAttrC } } +/// Iterate over all RES_PARATR_TABSTOP SvXMLAttrContainerItem, if the function returns false, iteration is stopped +void SwDoc::ForEachParaAtrTabStopItem(const std::function<bool(const SvxTabStopItem&)>& rFunc ) const +{ + for(SwCharFormat* pFormat : *GetCharFormats()) + { + const SwAttrSet& rAttrSet = pFormat->GetAttrSet(); + if (const SvxTabStopItem* pItem = rAttrSet.GetItemIfSet(RES_PARATR_TABSTOP)) + if (!rFunc(*pItem)) + return; + } +} + void SwDoc::Summary(SwDoc& rExtDoc, sal_uInt8 nLevel, sal_uInt8 nPara, bool bImpress) { const SwOutlineNodes& rOutNds = GetNodes().GetOutLineNds(); diff --git a/sw/source/core/doc/docfmt.cxx b/sw/source/core/doc/docfmt.cxx index 75ccf557810e..b7f8d4ba7791 100644 --- a/sw/source/core/doc/docfmt.cxx +++ b/sw/source/core/doc/docfmt.cxx @@ -636,18 +636,15 @@ void SwDoc::SetDefault( const SfxItemSet& rSet ) nOldWidth = aOld.Get(RES_PARATR_TABSTOP)[ 0 ].GetTabPos(); bool bChg = false; - ItemSurrogates aSurrogates; - GetAttrPool().GetItemSurrogates(aSurrogates, RES_PARATR_TABSTOP); - for (const SfxPoolItem* pItem2 : aSurrogates) - { + ForEachParaAtrTabStopItem([&bChg, &nOldWidth, &nNewWidth](const SvxTabStopItem& rTabStopItem) -> bool { // pItem2 and thus pTabStopItem is a evtl. shared & RefCounted // Item and *should* not be changed that way. lcl_SetNewDefTabStops // seems to change pTabStopItem (!). This may need to be changed // to use iterateItemSurrogates and a defined write cycle. - const auto & rTabStopItem = static_cast<const SvxTabStopItem&>(*pItem2); bChg |= lcl_SetNewDefTabStops( nOldWidth, nNewWidth, const_cast<SvxTabStopItem&>(rTabStopItem) ); - } + return true; + }); aNew.ClearItem( RES_PARATR_TABSTOP ); aOld.ClearItem( RES_PARATR_TABSTOP ); commit 1442dc4ee12251eed04e51eb324a34dc4b7973c3 Author: Noel Grandin <noelgran...@gmail.com> AuthorDate: Thu Sep 19 19:11:52 2024 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Fri Sep 20 07:51:54 2024 +0200 dont use GetItemSurrogates for gathering SvXMLAttrContainerItem which is very expensive these days Change-Id: Idf133fc0532f12d297c0f44a3aad48b6eaa2206a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173680 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx index 83c64f06409b..c11f23dcf6f6 100644 --- a/sw/inc/doc.hxx +++ b/sw/inc/doc.hxx @@ -1455,6 +1455,9 @@ public: /// Iterate over all RES_CHRATR_BACKGROUND SvxBrushItem, if the function returns false, iteration is stopped SW_DLLPUBLIC void ForEachCharacterBrushItem(const std::function<bool(const SvxBrushItem&)>& ) const; + /// Iterate over all RES_TXTATR_UNKNOWN_CONTAINER SvXMLAttrContainerItem, if the function returns false, iteration is stopped + SW_DLLPUBLIC void ForEachTxtAtrContainerItem(const std::function<bool(const SvXMLAttrContainerItem&)>& ) const; + // Call into intransparent Basic; expect possible Return String. void ExecMacro( const SvxMacro& rMacro, OUString* pRet, SbxArray* pArgs ); diff --git a/sw/source/core/bastyp/init.cxx b/sw/source/core/bastyp/init.cxx index 0920842909e4..b5b409705f1a 100644 --- a/sw/source/core/bastyp/init.cxx +++ b/sw/source/core/bastyp/init.cxx @@ -344,7 +344,7 @@ ItemInfoPackage& getItemInfoPackageSwAttributes() { RES_TXTATR_CHARFMT, new SwFormatCharFormat( nullptr ), 0, SFX_ITEMINFOFLAG_NONE }, { RES_TXTATR_CJK_RUBY, new SwFormatRuby( OUString() ), SID_ATTR_CHAR_CJK_RUBY, SFX_ITEMINFOFLAG_NONE }, - { RES_TXTATR_UNKNOWN_CONTAINER, new SvXMLAttrContainerItem( RES_TXTATR_UNKNOWN_CONTAINER ), 0, SFX_ITEMINFOFLAG_SUPPORT_SURROGATE }, + { RES_TXTATR_UNKNOWN_CONTAINER, new SvXMLAttrContainerItem( RES_TXTATR_UNKNOWN_CONTAINER ), 0, SFX_ITEMINFOFLAG_NONE }, { RES_TXTATR_INPUTFIELD, createSwFormatFieldForItemInfoPackage( RES_TXTATR_INPUTFIELD ), 0, SFX_ITEMINFOFLAG_NONE }, { RES_TXTATR_CONTENTCONTROL, new SwFormatContentControl( RES_TXTATR_CONTENTCONTROL ), 0, SFX_ITEMINFOFLAG_NONE }, { RES_TXTATR_FIELD, createSwFormatFieldForItemInfoPackage( RES_TXTATR_FIELD ), 0, SFX_ITEMINFOFLAG_NONE }, diff --git a/sw/source/core/doc/doc.cxx b/sw/source/core/doc/doc.cxx index 58bb026e1c7e..2be295986df3 100644 --- a/sw/source/core/doc/doc.cxx +++ b/sw/source/core/doc/doc.cxx @@ -53,6 +53,7 @@ #include <editeng/pbinitem.hxx> #include <editeng/udlnitem.hxx> #include <editeng/colritem.hxx> +#include <editeng/xmlcnitm.hxx> #include <unotools/localedatawrapper.hxx> #include <officecfg/Office/Writer.hxx> @@ -1494,6 +1495,32 @@ void SwDoc::ForEachCharacterBrushItem( const std::function<bool(const SvxBrushIt } } +/// Iterate over all RES_TXTATR_UNKNOWN_CONTAINER SvXMLAttrContainerItem, if the function returns false, iteration is stopped +void SwDoc::ForEachTxtAtrContainerItem(const std::function<bool(const SvXMLAttrContainerItem&)>& rFunc ) const +{ + SwNodeOffset nCount = GetNodes().Count(); + for (SwNodeOffset i(0); i < nCount; ++i) + { + SwNode* pNode = GetNodes()[i]; + if (!pNode->IsTextNode()) + continue; + SwTextNode* pTextNode = pNode->GetTextNode(); + if (!pTextNode->HasHints()) + continue; + SwpHints& rHints = pTextNode->GetSwpHints(); + for (size_t j = 0; j < rHints.Count(); ++j) + { + const SwTextAttr* pTextAttr = rHints.Get(j); + if (pTextAttr->Which() != RES_TXTATR_AUTOFMT) + continue; + const SwFormatAutoFormat& rFmt = pTextAttr->GetAutoFormat(); + if (const SvXMLAttrContainerItem* pItem = rFmt.GetStyleHandle()->GetItemIfSet(RES_TXTATR_UNKNOWN_CONTAINER)) + if (!rFunc(*pItem)) + return; + } + } +} + void SwDoc::Summary(SwDoc& rExtDoc, sal_uInt8 nLevel, sal_uInt8 nPara, bool bImpress) { const SwOutlineNodes& rOutNds = GetNodes().GetOutLineNds(); diff --git a/sw/source/filter/xml/xmlexp.cxx b/sw/source/filter/xml/xmlexp.cxx index 07bc30f98939..0d9e89979bdf 100644 --- a/sw/source/filter/xml/xmlexp.cxx +++ b/sw/source/filter/xml/xmlexp.cxx @@ -135,14 +135,27 @@ ErrCode SwXMLExport::exportDoc( enum XMLTokenEnum eClass ) GetTextParagraphExport()->SetBlockMode( m_bBlock ); + pDoc->ForEachTxtAtrContainerItem([this](const SvXMLAttrContainerItem& rUnknown) -> bool { + if( rUnknown.GetAttrCount() > 0 ) + { + sal_uInt16 nIdx = rUnknown.GetFirstNamespaceIndex(); + while( USHRT_MAX != nIdx ) + { + GetNamespaceMap_().Add( rUnknown.GetPrefix( nIdx ), + rUnknown.GetNamespace( nIdx ) ); + nIdx = rUnknown.GetNextNamespaceIndex( nIdx ); + } + } + return true; + }); + const SfxItemPool& rPool = pDoc->GetAttrPool(); - sal_uInt16 aWhichIds[5] = { RES_UNKNOWNATR_CONTAINER, - RES_TXTATR_UNKNOWN_CONTAINER, + sal_uInt16 aWhichIds[4] = { RES_UNKNOWNATR_CONTAINER, SDRATTR_XMLATTRIBUTES, EE_PARA_XMLATTRIBS, EE_CHAR_XMLATTRIBS }; - const int nWhichIds = rPool.GetSecondaryPool() ? 5 : 2; + const int nWhichIds = rPool.GetSecondaryPool() ? 4 : 1; for( int j=0; j < nWhichIds; ++j ) { const sal_uInt16 nWhichId = aWhichIds[j];