sw/inc/doc.hxx | 2 - sw/source/core/doc/docfmt.cxx | 8 ++++-- sw/source/core/inc/UndoAttribute.hxx | 8 +++--- sw/source/core/undo/unattr.cxx | 42 +++++++++++++++++++++++------------ sw/source/uibase/app/docstyle.cxx | 15 ++++++------ 5 files changed, 46 insertions(+), 29 deletions(-)
New commits: commit 6cc71f3eef4e5108e44ab6c1943def1d3a0f707a Author: Maxim Monastirsky <momonas...@gmail.com> AuthorDate: Wed Jun 21 07:30:53 2023 +0300 Commit: Maxim Monastirsky <momonas...@gmail.com> CommitDate: Fri Jun 23 08:31:13 2023 +0200 tdf#103064 Fix reset to parent style handling If the style ends up empty, it still needs modification broadcasting if it used to be non-empty. So let's just trust the pool notification for when to notify clients. And given that broadcasting happens now always after EnsureStyleHierarchy, I assume that the explicit broadcasting in SetParent is no longer needed. Also added broadcasting to the undo of a reset. And the undo actions were combined, so we don't get separate notifications for each reset attribute. Change-Id: Ia2895fe346ef337cc0b4fe5dc4275f5b2dc60cd7 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153478 Tested-by: Jenkins Reviewed-by: Maxim Monastirsky <momonas...@gmail.com> diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx index c729e0b2a983..c709db694d07 100644 --- a/sw/inc/doc.hxx +++ b/sw/inc/doc.hxx @@ -729,7 +729,7 @@ public: void SetAttr( const SfxItemSet&, SwFormat& ); // method to reset a certain attribute at the given format - void ResetAttrAtFormat( const sal_uInt16 nWhichId, + void ResetAttrAtFormat( const std::vector<sal_uInt16>& rIds, SwFormat& rChangedFormat ); /** Set attribute as new default attribute in current document. diff --git a/sw/source/core/doc/docfmt.cxx b/sw/source/core/doc/docfmt.cxx index 8ed9c4c9d249..3a503407c90f 100644 --- a/sw/source/core/doc/docfmt.cxx +++ b/sw/source/core/doc/docfmt.cxx @@ -498,14 +498,16 @@ void SwDoc::SetAttr( const SfxItemSet& rSet, SwFormat& rFormat ) getIDocumentState().SetModified(); } -void SwDoc::ResetAttrAtFormat( const sal_uInt16 nWhichId, +void SwDoc::ResetAttrAtFormat( const std::vector<sal_uInt16>& rIds, SwFormat& rChangedFormat ) { std::unique_ptr<SwUndo> pUndo; if (GetIDocumentUndoRedo().DoesUndo()) - pUndo.reset(new SwUndoFormatResetAttr( rChangedFormat, nWhichId )); + pUndo.reset(new SwUndoFormatResetAttr( rChangedFormat, rIds )); - const bool bAttrReset = rChangedFormat.ResetFormatAttr( nWhichId ); + bool bAttrReset = false; + for (const auto& nWhichId : rIds) + bAttrReset = rChangedFormat.ResetFormatAttr(nWhichId) || bAttrReset; if ( bAttrReset ) { diff --git a/sw/source/core/inc/UndoAttribute.hxx b/sw/source/core/inc/UndoAttribute.hxx index 7fbbb5b522cd..f6905cafc6cf 100644 --- a/sw/source/core/inc/UndoAttribute.hxx +++ b/sw/source/core/inc/UndoAttribute.hxx @@ -132,7 +132,7 @@ class SwUndoFormatResetAttr final : public SwUndo { public: SwUndoFormatResetAttr( SwFormat& rChangedFormat, - const sal_uInt16 nWhichId ); + const std::vector<sal_uInt16>& rIds ); virtual ~SwUndoFormatResetAttr() override; virtual void UndoImpl( ::sw::UndoRedoContext & ) override; @@ -141,10 +141,10 @@ class SwUndoFormatResetAttr final : public SwUndo private: // format at which a certain attribute is reset. SwFormat * const m_pChangedFormat; - // which ID of the reset attribute - const sal_uInt16 m_nWhichId; // old attribute which has been reset - needed for undo. - std::unique_ptr<SfxPoolItem> m_pOldItem; + SfxItemSet m_aSet; + + void BroadcastStyleChange(); }; class SwUndoDontExpandFormat final : public SwUndo diff --git a/sw/source/core/undo/unattr.cxx b/sw/source/core/undo/unattr.cxx index acc1503ee35c..66ccb4073bc3 100644 --- a/sw/source/core/undo/unattr.cxx +++ b/sw/source/core/undo/unattr.cxx @@ -233,7 +233,7 @@ void SwUndoFormatAttr::UndoImpl(::sw::UndoRedoContext & rContext) else if (RES_CHRFMT == m_nFormatWhich) nFamily = SfxStyleFamily::Char; - if (pFormat && nFamily != SfxStyleFamily::None) + if (m_oOldSet && m_oOldSet->Count() > 0 && nFamily != SfxStyleFamily::None) rContext.GetDoc().BroadcastStyleOperation(pFormat->GetName(), nFamily, SfxHintId::StyleSheetModified); } @@ -549,14 +549,16 @@ bool SwUndoFormatAttr::RestoreFlyAnchor(::sw::UndoRedoContext & rContext) } SwUndoFormatResetAttr::SwUndoFormatResetAttr( SwFormat& rChangedFormat, - const sal_uInt16 nWhichId ) + const std::vector<sal_uInt16>& rIds ) : SwUndo( SwUndoId::RESETATTR, rChangedFormat.GetDoc() ) , m_pChangedFormat( &rChangedFormat ) - , m_nWhichId( nWhichId ) + , m_aSet(*rChangedFormat.GetAttrSet().GetPool()) { - const SfxPoolItem* pItem = nullptr; - if (rChangedFormat.GetItemState(nWhichId, false, &pItem ) == SfxItemState::SET && pItem) { - m_pOldItem.reset( pItem->Clone() ); + for (const auto& nWhichId : rIds) + { + const SfxPoolItem* pItem = nullptr; + if (rChangedFormat.GetItemState(nWhichId, false, &pItem ) == SfxItemState::SET && pItem) + m_aSet.Put(*pItem); } } @@ -566,18 +568,30 @@ SwUndoFormatResetAttr::~SwUndoFormatResetAttr() void SwUndoFormatResetAttr::UndoImpl(::sw::UndoRedoContext &) { - if (m_pOldItem) - { - m_pChangedFormat->SetFormatAttr( *m_pOldItem ); - } + m_pChangedFormat->SetFormatAttr(m_aSet); + BroadcastStyleChange(); } void SwUndoFormatResetAttr::RedoImpl(::sw::UndoRedoContext &) { - if (m_pOldItem) - { - m_pChangedFormat->ResetFormatAttr( m_nWhichId ); - } + SfxItemIter aIter(m_aSet); + for (auto pItem = aIter.GetCurItem(); pItem; pItem = aIter.NextItem()) + m_pChangedFormat->ResetFormatAttr(pItem->Which()); + BroadcastStyleChange(); +} + +void SwUndoFormatResetAttr::BroadcastStyleChange() +{ + auto nWhich = m_pChangedFormat->Which(); + SfxStyleFamily nFamily = SfxStyleFamily::None; + + if (RES_TXTFMTCOLL == nWhich || RES_CONDTXTFMTCOLL == nWhich) + nFamily = SfxStyleFamily::Para; + else if (RES_CHRFMT == nWhich) + nFamily = SfxStyleFamily::Char; + + if (nFamily != SfxStyleFamily::None) + m_pChangedFormat->GetDoc()->BroadcastStyleOperation(m_pChangedFormat->GetName(), nFamily, SfxHintId::StyleSheetModified); } SwUndoResetAttr::SwUndoResetAttr( const SwPaM& rRange, sal_uInt16 nFormatId ) diff --git a/sw/source/uibase/app/docstyle.cxx b/sw/source/uibase/app/docstyle.cxx index 8f8e9eb94c19..e50c087d23fc 100644 --- a/sw/source/uibase/app/docstyle.cxx +++ b/sw/source/uibase/app/docstyle.cxx @@ -109,7 +109,6 @@ public: { auto pStyle = m_pPool->Find(rName, nFamily); pSet->SetParent(pStyle ? &pStyle->GetItemSet() : nullptr); - Broadcast(SfxHint(SfxHintId::DataChanged)); return true; } return false; @@ -154,6 +153,7 @@ public: pStyleSheet->SetName(pDocStyleSheet->GetName()); pStyleSheet->GetItemSet().ClearItem(); EnsureStyleHierarchy(pDocStyleSheet->GetName(), pDocStyleSheet->GetFamily()); + static_cast<SfxStyleSheet*>(pStyleSheet)->Broadcast(SfxHint(SfxHintId::DataChanged)); } else if (nId == SfxHintId::StyleSheetErased) Remove(pStyleSheet); @@ -248,8 +248,6 @@ public: if (oLRSpaceItem) rItemSet.Put(*oLRSpaceItem); } - - static_cast<SfxStyleSheet*>(pDestSheet)->Broadcast(SfxHint(SfxHintId::DataChanged)); } }; @@ -1648,6 +1646,7 @@ void SwDocStyleSheet::SetItemSet( const SfxItemSet& rSet, const bool bBroadcast, } SwFormat* pFormat = nullptr; + std::vector<sal_uInt16> aWhichIdsToReset; std::unique_ptr<SwPageDesc> pNewDsc; size_t nPgDscPos = 0; @@ -1726,14 +1725,14 @@ void SwDocStyleSheet::SetItemSet( const SfxItemSet& rSet, const bool bBroadcast, rSet.GetItemState(RES_MARGIN_FIRSTLINE, false) != SfxItemState::SET && m_pColl->GetItemState(RES_MARGIN_FIRSTLINE, false) == SfxItemState::SET) { - m_rDoc.ResetAttrAtFormat(RES_MARGIN_FIRSTLINE, *m_pColl); + aWhichIdsToReset.emplace_back(RES_MARGIN_FIRSTLINE); } if ( bResetIndentAttrsAtParagraphStyle && rSet.GetItemState( RES_PARATR_NUMRULE, false ) == SfxItemState::SET && rSet.GetItemState(RES_MARGIN_TEXTLEFT, false) != SfxItemState::SET && m_pColl->GetItemState(RES_MARGIN_TEXTLEFT, false) == SfxItemState::SET) { - m_rDoc.ResetAttrAtFormat(RES_MARGIN_TEXTLEFT, *m_pColl); + aWhichIdsToReset.emplace_back(RES_MARGIN_TEXTLEFT); } // #i56252: If a standard numbering style is assigned to a standard paragraph style @@ -1863,12 +1862,14 @@ void SwDocStyleSheet::SetItemSet( const SfxItemSet& rSet, const bool bBroadcast, { // use method <SwDoc::ResetAttrAtFormat(..)> in order to // create an Undo object for the attribute reset. - m_rDoc.ResetAttrAtFormat( rSet.GetWhichByPos(aIter.GetCurPos()), - *pFormat ); + aWhichIdsToReset.emplace_back(rSet.GetWhichByPos(aIter.GetCurPos())); } pItem = aIter.NextItem(); } while (pItem); + + m_rDoc.ResetAttrAtFormat(aWhichIdsToReset, *pFormat); + SfxItemSet aSet(rSet); aSet.ClearInvalidItems();