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();
 

Reply via email to