sw/inc/tox.hxx | 21 +++++++-- sw/source/core/doc/doctxm.cxx | 87 +++++++++++++---------------------------- sw/source/core/tox/tox.cxx | 82 +++++++++++++++++++++++++------------- sw/source/core/undo/rolbck.cxx | 2 4 files changed, 99 insertions(+), 93 deletions(-)
New commits: commit 69d903c59729deb9f9824929bb31e4256f09025b Author: Bjoern Michaelsen <bjoern.michael...@libreoffice.org> AuthorDate: Sun Jul 5 15:24:43 2020 +0200 Commit: Bjoern Michaelsen <bjoern.michael...@libreoffice.org> CommitDate: Fri Aug 7 17:28:14 2020 +0200 SwTOXBaseSection::UpdateMarks: SwIterator no more ... Change-Id: Ib4b9e9bc47e6789d61dbe6187a870b986ed491f6 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/98138 Tested-by: Jenkins Reviewed-by: Bjoern Michaelsen <bjoern.michael...@libreoffice.org> diff --git a/sw/inc/tox.hxx b/sw/inc/tox.hxx index 475a48830a7f..232ca6f47acc 100644 --- a/sw/inc/tox.hxx +++ b/sw/inc/tox.hxx @@ -24,6 +24,7 @@ #include <i18nlangtag/lang.h> #include <svl/poolitem.hxx> +#include <svl/listener.hxx> #include <editeng/svxenum.hxx> #include "swtypes.hxx" @@ -43,6 +44,7 @@ class SwDoc; class SwRootFrame; class SwContentFrame; + typedef std::vector<SwTOXMark*> SwTOXMarks; namespace sw { @@ -62,6 +64,11 @@ namespace sw { , m_isReadOnlyAvailable(isReadOnlyAvailable) {} }; + struct CollectTextTOXMarksForLayoutHint final : SfxHint { + std::vector<std::reference_wrapper<SwTextTOXMark>>& m_rMarks; + const SwRootFrame* m_pLayout; + CollectTextTOXMarksForLayoutHint(std::vector<std::reference_wrapper<SwTextTOXMark>>& rMarks, const SwRootFrame* pLayout) : m_rMarks(rMarks), m_pLayout(pLayout) {} + }; } // Entry of content index, alphabetical index or user defined index @@ -73,10 +80,12 @@ extern const OUString S_PAGE_DELI; class SW_DLLPUBLIC SwTOXMark final : public SfxPoolItem , public sw::BroadcastingModify + , public SvtListener { friend void InitCore(); friend class SwTextTOXMark; + const SwTOXType* m_pType; OUString m_aAltText; // Text of caption is different. OUString m_aPrimaryKey; OUString m_aSecondaryKey; @@ -90,15 +99,15 @@ class SW_DLLPUBLIC SwTOXMark final sal_uInt16 m_nLevel; OUString m_aBookmarkName; - OUString m_aEntryTypeName; // stored specific entry type name for INDEX field \f - bool m_bAutoGenerated : 1; // generated using a concordance file - bool m_bMainEntry : 1; // main entry emphasized by character style + OUString m_aEntryTypeName; // stored specific entry type name for INDEX field \f + bool m_bAutoGenerated; // generated using a concordance file + bool m_bMainEntry; // main entry emphasized by character style css::uno::WeakReference<css::text::XDocumentIndexMark> m_wXDocumentIndexMark; SwTOXMark(); // to create the default attribute in InitCore - virtual void SwClientNotify(const SwModify& rModify, const SfxHint& rHint) override; + virtual void Notify(const SfxHint& rHint) override; public: @@ -180,6 +189,8 @@ public: const_cast<SwTOXType*>(this)->GetNotifier().Broadcast(sw::FindContentFrameHint(pContentFrame, rDoc, rLayout, isReadOnlyAvailable)); return pContentFrame; } + void CollectTextTOXMarksForLayout(std::vector<std::reference_wrapper<SwTextTOXMark>>& rMarks, const SwRootFrame* pLayout) const + { const_cast<SwTOXType*>(this)->GetNotifier().Broadcast(sw::CollectTextTOXMarksForLayoutHint(rMarks, pLayout)); } private: @@ -564,7 +575,7 @@ inline const OUString& SwTOXMark::GetEntryTypeName() const { return m_aEntryTypeName; } inline const SwTOXType* SwTOXMark::GetTOXType() const - { return static_cast<const SwTOXType*>(GetRegisteredIn()); } + { return m_pType; } inline bool SwTOXMark::IsAlternativeText() const { return !m_aAltText.isEmpty(); } diff --git a/sw/source/core/doc/doctxm.cxx b/sw/source/core/doc/doctxm.cxx index d5857479f6fe..b3eba9df2dbd 100644 --- a/sw/source/core/doc/doctxm.cxx +++ b/sw/source/core/doc/doctxm.cxx @@ -771,11 +771,8 @@ void SwTOXBaseSection::Update(const SfxItemSet* pAttr, SwRootFrame const*const pLayout, const bool _bNewTOX) { - if (!SwTOXBase::GetRegisteredIn()->HasWriterListeners() || - !GetFormat()) - { + if (!GetFormat()) return; - } SwSectionNode const*const pSectNd(GetFormat()->GetSectionNode()); if (nullptr == pSectNd || !pSectNd->GetNodes().IsDocNodes() || @@ -1198,69 +1195,41 @@ void SwTOXBaseSection::SwClientNotify(const SwModify& rModify, const SfxHint& rH } /// Create from Marks -void SwTOXBaseSection::UpdateMarks( const SwTOXInternational& rIntl, - const SwTextNode* pOwnChapterNode, - SwRootFrame const*const pLayout) +void SwTOXBaseSection::UpdateMarks(const SwTOXInternational& rIntl, + const SwTextNode* pOwnChapterNode, + SwRootFrame const*const pLayout) { - const SwTOXType* pType = static_cast<SwTOXType*>( SwTOXBase::GetRegisteredIn() ); - if( !pType->HasWriterListeners() ) - return; - - SwDoc* pDoc = GetFormat()->GetDoc(); - TOXTypes eTOXTyp = GetTOXType()->GetType(); - SwIterator<SwTOXMark,SwTOXType> aIter( *pType ); - - for (SwTOXMark* pMark = aIter.First(); pMark; pMark = aIter.Next()) + const auto pType = static_cast<SwTOXType*>(SwTOXBase::GetRegisteredIn()); + auto pShell = GetFormat()->GetDoc()->GetDocShell(); + const TOXTypes eTOXTyp = GetTOXType()->GetType(); + std::vector<std::reference_wrapper<SwTextTOXMark>> vMarks; + pType->CollectTextTOXMarksForLayout(vMarks, pLayout); + for(auto& rMark: vMarks) { - ::SetProgressState( 0, pDoc->GetDocShell() ); - - if (pMark->GetTOXType()->GetType() == eTOXTyp) + ::SetProgressState(0, pShell); + auto& rNode = rMark.get().GetTextNode(); + if(IsFromChapter() && ::lcl_FindChapterNode(rNode, pLayout) != pOwnChapterNode) + continue; + auto rTOXMark = rMark.get().GetTOXMark(); + if(TOX_INDEX == eTOXTyp) { - SwTextTOXMark *const pTextMark(pMark->GetTextTOXMark()); - if (nullptr == pTextMark) - continue; - const SwTextNode* pTOXSrc = pTextMark->GetpTextNd(); - // Only insert TOXMarks from the Doc, not from the - // UNDO. - - // If selected use marks from the same chapter only - if( pTOXSrc->GetNodes().IsDocNodes() && - pTOXSrc->GetText().getLength() && pTOXSrc->HasWriterListeners() && - pTOXSrc->getLayoutFrame( pDoc->getIDocumentLayoutAccess().GetCurrentLayout() ) && - (!IsFromChapter() || ::lcl_FindChapterNode(*pTOXSrc, pLayout) == pOwnChapterNode) && - !pTOXSrc->IsHiddenByParaField() && - !SwScriptInfo::IsInHiddenRange(*pTOXSrc, pTextMark->GetStart()) && - (!pLayout || !pLayout->IsHideRedlines() - || !sw::IsMarkHintHidden(*pLayout, *pTOXSrc, *pTextMark))) + // index entry mark + assert(g_pBreakIt); + lang::Locale aLocale = g_pBreakIt->GetLocale(rNode.GetLang(rMark.get().GetStart())); + InsertSorted(MakeSwTOXSortTabBase<SwTOXIndex>(pLayout, rNode, &rMark.get(), GetOptions(), FORM_ENTRY, rIntl, aLocale)); + if(GetOptions() & SwTOIOptions::KeyAsEntry && !rTOXMark.GetPrimaryKey().isEmpty()) { - if(TOX_INDEX == eTOXTyp) + InsertSorted(MakeSwTOXSortTabBase<SwTOXIndex>(pLayout, rNode, &rMark.get(), GetOptions(), FORM_PRIMARY_KEY, rIntl, aLocale)); + if (!rTOXMark.GetSecondaryKey().isEmpty()) { - // index entry mark - assert(g_pBreakIt); - lang::Locale aLocale = g_pBreakIt->GetLocale(pTOXSrc->GetLang(pTextMark->GetStart())); - - InsertSorted(MakeSwTOXSortTabBase<SwTOXIndex>(pLayout, *pTOXSrc, pTextMark, - GetOptions(), FORM_ENTRY, rIntl, aLocale )); - if(GetOptions() & SwTOIOptions::KeyAsEntry && - !pTextMark->GetTOXMark().GetPrimaryKey().isEmpty()) - { - InsertSorted(MakeSwTOXSortTabBase<SwTOXIndex>(pLayout, *pTOXSrc, pTextMark, - GetOptions(), FORM_PRIMARY_KEY, rIntl, aLocale )); - if (!pTextMark->GetTOXMark().GetSecondaryKey().isEmpty()) - { - InsertSorted(MakeSwTOXSortTabBase<SwTOXIndex>(pLayout, *pTOXSrc, pTextMark, - GetOptions(), FORM_SECONDARY_KEY, rIntl, aLocale )); - } - } - } - else if( TOX_USER == eTOXTyp || - pMark->GetLevel() <= GetLevel()) - { // table of content mark - // also used for user marks - InsertSorted(MakeSwTOXSortTabBase<SwTOXContent>(pLayout, *pTOXSrc, pTextMark, rIntl)); + InsertSorted(MakeSwTOXSortTabBase<SwTOXIndex>(pLayout, rNode, &rMark.get(), GetOptions(), FORM_SECONDARY_KEY, rIntl, aLocale)); } } } + else if(TOX_USER == eTOXTyp || rTOXMark.GetLevel() <= GetLevel()) + { // table of content mark, also used for user marks + InsertSorted(MakeSwTOXSortTabBase<SwTOXContent>(pLayout, rNode, &rMark.get(), rIntl)); + } } } diff --git a/sw/source/core/tox/tox.cxx b/sw/source/core/tox/tox.cxx index 9e7919a3ca1b..b9203a5c630e 100644 --- a/sw/source/core/tox/tox.cxx +++ b/sw/source/core/tox/tox.cxx @@ -17,18 +17,21 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ -#include <hintids.hxx> -#include <swtypes.hxx> -#include <ndtxt.hxx> -#include <txttxmrk.hxx> -#include <tox.hxx> -#include <strings.hrc> +#include <calbck.hxx> #include <doc.hxx> #include <docary.hxx> -#include <paratr.hxx> #include <editeng/tstpitem.hxx> +#include <hintids.hxx> #include <hints.hxx> -#include <calbck.hxx> +#include <ndtxt.hxx> +#include <paratr.hxx> +#include <rootfrm.hxx> +#include <scriptinfo.hxx> +#include <strings.hrc> +#include <swtypes.hxx> +#include <tox.hxx> +#include <txtfrm.hxx> +#include <txttxmrk.hxx> #include <optional> #include <sal/log.hxx> @@ -47,7 +50,6 @@ const OUString S_PAGE_DELI(", "); namespace { - void lcl_FillAuthPattern(SwFormTokens &rAuthTokens, sal_uInt16 nTypeId) { rAuthTokens.reserve(9); // Worst case: Start+Sep1+Auth+3*(Sep2+Auth) @@ -86,30 +88,34 @@ void lcl_FillAuthPattern(SwFormTokens &rAuthTokens, sal_uInt16 nTypeId) // <- #i21237# } } - } - /// pool default constructor SwTOXMark::SwTOXMark() - : SfxPoolItem( RES_TXTATR_TOXMARK ) - , m_pTextAttr( nullptr ), m_nLevel( 0 ) + : SfxPoolItem(RES_TXTATR_TOXMARK) + , m_pType(nullptr) + , m_pTextAttr(nullptr) + , m_nLevel(0) , m_bAutoGenerated(false) , m_bMainEntry(false) -{ } +{ +} -SwTOXMark::SwTOXMark(const SwTOXType* pTyp) - : SfxPoolItem(RES_TXTATR_TOXMARK ) - , m_pTextAttr( nullptr ) - , m_nLevel( 0 ) +SwTOXMark::SwTOXMark(const SwTOXType* pType) + : SfxPoolItem(RES_TXTATR_TOXMARK) + , m_pType(pType) + , m_pTextAttr(nullptr) + , m_nLevel(0) , m_bAutoGenerated(false) , m_bMainEntry(false) -{ - const_cast<SwTOXType*>(pTyp)->Add(this); +{ + StartListening(const_cast<SwTOXType*>(m_pType)->GetNotifier()); } SwTOXMark::SwTOXMark(const SwTOXMark& rCopy) : SfxPoolItem(RES_TXTATR_TOXMARK) + , SvtListener() + , m_pType(rCopy.m_pType) , m_aPrimaryKey(rCopy.m_aPrimaryKey) , m_aSecondaryKey(rCopy.m_aSecondaryKey) , m_aTextReading(rCopy.m_aTextReading) @@ -120,8 +126,8 @@ SwTOXMark::SwTOXMark(const SwTOXMark& rCopy) , m_bAutoGenerated(rCopy.m_bAutoGenerated) , m_bMainEntry(rCopy.m_bMainEntry) { - if (auto pRegister = const_cast<SwTOXMark&>(rCopy).GetRegisteredIn()) - pRegister->Add(this); + if(m_pType) + StartListening(const_cast<SwTOXType*>(m_pType)->GetNotifier()); // Copy AlternativString m_aAltText = rCopy.m_aAltText; } @@ -132,13 +138,15 @@ SwTOXMark::~SwTOXMark() void SwTOXMark::RegisterToTOXType(SwTOXType& rType) { - rType.Add(this); + SvtListener::EndListeningAll(); + m_pType = &rType; + StartListening(rType.GetNotifier()); } bool SwTOXMark::operator==( const SfxPoolItem& rAttr ) const { assert(SfxPoolItem::operator==(rAttr)); - return GetRegisteredIn() == static_cast<const SwTOXMark&>(rAttr).GetRegisteredIn(); + return m_pType == static_cast<const SwTOXMark&>(rAttr).m_pType; } SwTOXMark* SwTOXMark::Clone( SfxItemPool* ) const @@ -146,7 +154,7 @@ SwTOXMark* SwTOXMark::Clone( SfxItemPool* ) const return new SwTOXMark( *this ); } -void SwTOXMark::SwClientNotify(const SwModify&, const SfxHint& rHint) +void SwTOXMark::Notify(const SfxHint& rHint) { if (auto pLegacyHint = dynamic_cast<const sw::LegacyModifyHint*>(&rHint)) { @@ -157,6 +165,23 @@ void SwTOXMark::SwClientNotify(const SwModify&, const SfxHint& rHint) { if(GetTextTOXMark()) pCollectHint->m_rMarks.push_back(this); + } else if (auto pCollectLayoutHint = dynamic_cast<const sw::CollectTextTOXMarksForLayoutHint*>(&rHint)) + { + if(!GetTextTOXMark()) + return; + auto& rTextMark = *GetTextTOXMark(); + auto& rNode = rTextMark.GetTextNode(); + auto pLayout = pCollectLayoutHint->m_pLayout; + // Check basic sanity and that it is part of our layout and not in undo + if(!rNode.GetNodes().IsDocNodes() || !rNode.GetText().getLength() || !rNode.HasWriterListeners() || !rNode.getLayoutFrame(pLayout)) + return; + // Check for being hidden + if(rNode.IsHiddenByParaField() || SwScriptInfo::IsInHiddenRange(rNode, rTextMark.GetStart())) + return; + // Xhwxk for being hidden by hidden redlines + if(pLayout && pLayout->IsHideRedlines() && sw::IsMarkHintHidden(*pLayout, rNode, rTextMark)) + return; + pCollectLayoutHint->m_rMarks.push_back(rTextMark); } } @@ -190,14 +215,15 @@ OUString SwTOXMark::GetText(SwRootFrame const*const pLayout) const SwTOXType::SwTOXType(TOXTypes eTyp, const OUString& rName) : m_aName(rName) , m_eType(eTyp) -{ } +{ +} SwTOXType::SwTOXType(const SwTOXType& rCopy) : m_aName(rCopy.m_aName) , m_eType(rCopy.m_eType) { - if (auto pRegister = const_cast<SwTOXType&>(rCopy).GetRegisteredIn()) - pRegister->Add(this); + if (auto pRegisteredIn = const_cast<SwTOXType&>(rCopy).GetRegisteredIn()) + pRegisteredIn->Add(this); } static const char* STR_POOLCOLL_TOX_ARY[] = diff --git a/sw/source/core/undo/rolbck.cxx b/sw/source/core/undo/rolbck.cxx index dbc6675f568b..aac710f7aee5 100644 --- a/sw/source/core/undo/rolbck.cxx +++ b/sw/source/core/undo/rolbck.cxx @@ -373,7 +373,7 @@ SwHistorySetTOXMark::SwHistorySetTOXMark( const SwTextTOXMark* pTextHt, sal_uLon , m_nStart( pTextHt->GetStart() ) , m_nEnd( pTextHt->GetAnyEnd() ) { - m_TOXMark.EndListeningAll(); + static_cast<SvtListener*>(&m_TOXMark)->EndListeningAll(); } void SwHistorySetTOXMark::SetInDoc( SwDoc* pDoc, bool ) _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits