sw/inc/doc.hxx                       |    3 
 sw/source/core/inc/UndoAttribute.hxx |   11 -
 sw/source/core/undo/unattr.cxx       |  197 +++++++++++++++--------------------
 3 files changed, 97 insertions(+), 114 deletions(-)

New commits:
commit db257d6605143813e0b75ffa878a18810c8b3412
Author:     Vasily Melenchuk <vasily.melenc...@cib.de>
AuthorDate: Thu Aug 15 12:08:06 2019 +0300
Commit:     Thorsten Behrens <thorsten.behr...@cib.de>
CommitDate: Wed Aug 21 00:24:58 2019 +0200

    sw undo/redo: avoid usage of pointers as a style references
    
    Style can be created on previous undo steps and so after undo/redo
    pointer can became invalid. Style name as a reference looks like
    a good alternative to pointers.
    
    Change-Id: Ia099a717eaec1f1a23296b2c1273b8c1983a2b96
    Reviewed-on: https://gerrit.libreoffice.org/77495
    Tested-by: Jenkins
    Reviewed-by: Thorsten Behrens <thorsten.behr...@cib.de>
    (cherry picked from commit 09228fabe88f3457105cf26d83c003719a793114)
    Reviewed-on: https://gerrit.libreoffice.org/77782

diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index 1e78ee0aea40..f70e4704cfac 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -336,7 +336,6 @@ private:
                         FNCopyFormat fnCopyFormat, SwFormat& rDfltFormat );
     void CopyPageDescHeaderFooterImpl( bool bCpyHeader,
                                 const SwFrameFormat& rSrcFormat, 
SwFrameFormat& rDestFormat );
-    static SwFormat* FindFormatByName( const SwFormatsBase& rFormatArr, const 
OUString& rName );
 
     SwDoc( const SwDoc &) = delete;
 
@@ -753,6 +752,8 @@ public:
     // Remove all language dependencies from all existing formats
     void RemoveAllFormatLanguageDependencies();
 
+    static SwFormat* FindFormatByName(const SwFormatsBase& rFormatArr, const 
OUString& rName);
+
     SwFrameFormat  *MakeFrameFormat(const OUString &rFormatName, SwFrameFormat 
*pDerivedFrom,
                           bool bBroadcast = false, bool bAuto = true);
     void       DelFrameFormat( SwFrameFormat *pFormat, bool bBroadcast = false 
);
diff --git a/sw/source/core/inc/UndoAttribute.hxx 
b/sw/source/core/inc/UndoAttribute.hxx
index 288eabe20765..cc73197fd7c6 100644
--- a/sw/source/core/inc/UndoAttribute.hxx
+++ b/sw/source/core/inc/UndoAttribute.hxx
@@ -85,14 +85,13 @@ public:
 class SwUndoFormatAttr : public SwUndo
 {
     friend class SwUndoDefaultAttr;
-    SwFormat * m_pFormat;
+    OUString m_sFormatName;
     std::unique_ptr<SfxItemSet> m_pOldSet;      // old attributes
     sal_uLong m_nNodeIndex;
     const sal_uInt16 m_nFormatWhich;
     const bool m_bSaveDrawPt;
 
-    bool IsFormatInDoc( SwDoc* );   //is the attribute format still in the Doc?
-    void SaveFlyAnchor( bool bSaveDrawPt = false );
+    void SaveFlyAnchor( const SwFormat * pFormat, bool bSaveDrawPt = false );
     // #i35443# - Add return value, type <bool>.
     // Return value indicates, if anchor attribute is restored.
     // Notes: - If anchor attribute is restored, all other existing attributes
@@ -103,7 +102,7 @@ class SwUndoFormatAttr : public SwUndo
     //          This situation occurs for undo of styles.
     bool RestoreFlyAnchor(::sw::UndoRedoContext & rContext);
     // --> OD 2008-02-27 #refactorlists# - removed <rAffectedItemSet>
-    void Init();
+    void Init( const SwFormat & rFormat );
 
 public:
     // register at the Format and save old attributes
@@ -123,8 +122,8 @@ public:
 
     virtual SwRewriter GetRewriter() const override;
 
-    void PutAttr( const SfxPoolItem& rItem );
-    SwFormat* GetFormat( SwDoc& rDoc );   // checks if it is still in the Doc!
+    void PutAttr( const SfxPoolItem& rItem, const SwDoc& rDoc );
+    SwFormat* GetFormat( const SwDoc& rDoc );   // checks if it is still in 
the Doc!
 };
 
 // --> OD 2008-02-12 #newlistlevelattrs#
diff --git a/sw/source/core/undo/unattr.cxx b/sw/source/core/undo/unattr.cxx
index a8245c7a45bc..9edd72ac00f6 100644
--- a/sw/source/core/undo/unattr.cxx
+++ b/sw/source/core/undo/unattr.cxx
@@ -71,9 +71,10 @@ void SwUndoFormatAttrHelper::Modify( const SfxPoolItem* 
pOld, const SfxPoolItem*
         if ( pOld->Which() == RES_OBJECTDYING ) {
             CheckRegistration( pOld );
         } else if ( pNew ) {
+            const SwDoc& rDoc = 
*static_cast<SwFormat*>(GetRegisteredInNonConst())->GetDoc();
             if( POOLATTR_END >= pOld->Which() ) {
                 if ( GetUndo() ) {
-                    m_pUndo->PutAttr( *pOld );
+                    m_pUndo->PutAttr( *pOld, rDoc );
                 } else {
                     m_pUndo.reset( new SwUndoFormatAttr( *pOld,
                                                       
*static_cast<SwFormat*>(GetRegisteredInNonConst()), m_bSaveDrawPt ) );
@@ -84,7 +85,7 @@ void SwUndoFormatAttrHelper::Modify( const SfxPoolItem* pOld, 
const SfxPoolItem*
                         *static_cast<const SwAttrSetChg*>(pOld)->GetChgSet() );
                     const SfxPoolItem* pItem = aIter.GetCurItem();
                     while ( pItem ) {
-                        m_pUndo->PutAttr( *pItem );
+                        m_pUndo->PutAttr( *pItem, rDoc );
                         if( aIter.IsAtEnd() )
                             break;
                         pItem = aIter.NextItem();
@@ -103,50 +104,50 @@ SwUndoFormatAttr::SwUndoFormatAttr( const SfxItemSet& 
rOldSet,
                               SwFormat& rChgFormat,
                               bool bSaveDrawPt )
     : SwUndo( SwUndoId::INSFMTATTR, rChgFormat.GetDoc() )
-    , m_pFormat( &rChgFormat )
+    , m_sFormatName ( rChgFormat.GetName() )
     // #i56253#
     , m_pOldSet( new SfxItemSet( rOldSet ) )
     , m_nNodeIndex( 0 )
     , m_nFormatWhich( rChgFormat.Which() )
     , m_bSaveDrawPt( bSaveDrawPt )
 {
-    Init();
+    Init( rChgFormat );
 }
 
 SwUndoFormatAttr::SwUndoFormatAttr( const SfxPoolItem& rItem, SwFormat& 
rChgFormat,
                               bool bSaveDrawPt )
     : SwUndo( SwUndoId::INSFMTATTR, rChgFormat.GetDoc() )
-    , m_pFormat( &rChgFormat )
-    , m_pOldSet( m_pFormat->GetAttrSet().Clone( false ) )
+    , m_sFormatName(rChgFormat.GetName())
+    , m_pOldSet( rChgFormat.GetAttrSet().Clone( false ) )
     , m_nNodeIndex( 0 )
     , m_nFormatWhich( rChgFormat.Which() )
     , m_bSaveDrawPt( bSaveDrawPt )
 {
     m_pOldSet->Put( rItem );
-    Init();
+    Init( rChgFormat );
 }
 
-void SwUndoFormatAttr::Init()
+void SwUndoFormatAttr::Init( const SwFormat & rFormat )
 {
     // tdf#126017 never save SwNodeIndex, it will go stale
     m_pOldSet->ClearItem(RES_CNTNT);
     // treat change of anchor specially
     if ( SfxItemState::SET == m_pOldSet->GetItemState( RES_ANCHOR, false )) {
-        SaveFlyAnchor( m_bSaveDrawPt );
+        SaveFlyAnchor( &rFormat, m_bSaveDrawPt );
     } else if ( RES_FRMFMT == m_nFormatWhich ) {
-        SwDoc* pDoc = m_pFormat->GetDoc();
-        if (pDoc->GetTableFrameFormats()->ContainsFormat(dynamic_cast<const 
SwFrameFormat&>(*m_pFormat)))
+        const SwDoc* pDoc = rFormat.GetDoc();
+        if (pDoc->GetTableFrameFormats()->ContainsFormat(dynamic_cast<const 
SwFrameFormat&>(rFormat)))
         {
             // Table Format: save table position, table formats are volatile!
-            SwTable * pTable = SwIterator<SwTable,SwFormat>( *m_pFormat 
).First();
+            SwTable * pTable = SwIterator<SwTable,SwFormat>( rFormat ).First();
             if ( pTable ) {
                 m_nNodeIndex = pTable->GetTabSortBoxes()[ 0 ]->GetSttNd()
                                ->FindTableNode()->GetIndex();
             }
-        } else if (pDoc->GetSections().ContainsFormat(m_pFormat)) {
-            m_nNodeIndex = m_pFormat->GetContent().GetContentIdx()->GetIndex();
-        } else if ( dynamic_cast< SwTableBoxFormat* >( m_pFormat ) !=  nullptr 
) {
-            SwTableBox * pTableBox = SwIterator<SwTableBox,SwFormat>( 
*m_pFormat ).First();
+        } else if (pDoc->GetSections().ContainsFormat(&rFormat)) {
+            m_nNodeIndex = rFormat.GetContent().GetContentIdx()->GetIndex();
+        } else if ( dynamic_cast< const SwTableBoxFormat* >( &rFormat ) !=  
nullptr ) {
+            SwTableBox * pTableBox = SwIterator<SwTableBox,SwFormat>( rFormat 
).First();
             if ( pTableBox ) {
                 m_nNodeIndex = pTableBox->GetSttIdx();
             }
@@ -163,7 +164,11 @@ void SwUndoFormatAttr::UndoImpl(::sw::UndoRedoContext & 
rContext)
     // OD 2004-10-26 #i35443#
     // Important note: <Undo(..)> also called by <ReDo(..)>
 
-    if (!m_pOldSet || !m_pFormat || !IsFormatInDoc(&rContext.GetDoc()))
+    if (!m_pOldSet)
+        return;
+
+    SwFormat * pFormat = GetFormat(rContext.GetDoc());
+    if (!pFormat)
         return;
 
     // #i35443# - If anchor attribute has been successful
@@ -175,7 +180,7 @@ void SwUndoFormatAttr::UndoImpl(::sw::UndoRedoContext & 
rContext)
         if ( bAnchorAttrRestored ) {
             // Anchor attribute successful restored.
             // Thus, keep anchor position for redo
-            SaveFlyAnchor();
+            SaveFlyAnchor(pFormat);
         } else {
             // Anchor attribute not restored due to invalid anchor position.
             // Thus, delete anchor attribute.
@@ -184,8 +189,8 @@ void SwUndoFormatAttr::UndoImpl(::sw::UndoRedoContext & 
rContext)
     }
 
     if ( !bAnchorAttrRestored ) {
-        SwUndoFormatAttrHelper aTmp( *m_pFormat, m_bSaveDrawPt );
-        m_pFormat->SetFormatAttr( *m_pOldSet );
+        SwUndoFormatAttrHelper aTmp( *pFormat, m_bSaveDrawPt );
+        pFormat->SetFormatAttr( *m_pOldSet );
         if ( aTmp.GetUndo() ) {
             // transfer ownership of helper object's old set
             m_pOldSet = std::move(aTmp.GetUndo()->m_pOldSet);
@@ -194,93 +199,67 @@ void SwUndoFormatAttr::UndoImpl(::sw::UndoRedoContext & 
rContext)
         }
 
         if ( RES_FLYFRMFMT == m_nFormatWhich || RES_DRAWFRMFMT == 
m_nFormatWhich ) {
-            rContext.SetSelections(static_cast<SwFrameFormat*>(m_pFormat), 
nullptr);
+            rContext.SetSelections(static_cast<SwFrameFormat*>(pFormat), 
nullptr);
         }
     }
 }
 
-bool SwUndoFormatAttr::IsFormatInDoc( SwDoc* pDoc )
+// Check if it is still in Doc
+SwFormat* SwUndoFormatAttr::GetFormat( const SwDoc& rDoc )
 {
-    // search for the Format in the Document; if it does not exist any more,
-    // the attribute is not restored!
-    bool isAlive(false);
-    switch ( m_nFormatWhich )
+    switch (m_nFormatWhich)
     {
-        case RES_TXTFMTCOLL:
-        case RES_CONDTXTFMTCOLL:
-            isAlive = pDoc->GetTextFormatColls()->IsAlive(
-                    static_cast<const SwTextFormatColl *>(m_pFormat));
-            break;
+    case RES_TXTFMTCOLL:
+    case RES_CONDTXTFMTCOLL:
+        return rDoc.FindTextFormatCollByName(m_sFormatName);
 
-        case RES_GRFFMTCOLL:
-            isAlive = pDoc->GetGrfFormatColls()->IsAlive(
-                    static_cast<const SwGrfFormatColl*>(m_pFormat));
-            break;
+    case RES_GRFFMTCOLL:
+        return SwDoc::FindFormatByName(*rDoc.GetGrfFormatColls(), 
m_sFormatName);
 
-        case RES_CHRFMT:
-            isAlive = pDoc->GetCharFormats()->IsAlive(
-                    static_cast<const SwCharFormat *>(m_pFormat));
-            break;
+    case RES_CHRFMT:
+        return rDoc.FindCharFormatByName(m_sFormatName);
 
-        case RES_FRMFMT:
-            if ( m_nNodeIndex && (m_nNodeIndex < pDoc->GetNodes().Count()) )
+    case RES_FRMFMT:
+        if (m_nNodeIndex && (m_nNodeIndex < rDoc.GetNodes().Count()))
+        {
+            SwNode* pNd = rDoc.GetNodes()[m_nNodeIndex];
+            if (pNd->IsTableNode())
             {
-                SwNode* pNd = pDoc->GetNodes()[ m_nNodeIndex ];
-                if ( pNd->IsTableNode() )
-                {
-                    m_pFormat =
-                        
static_cast<SwTableNode*>(pNd)->GetTable().GetFrameFormat();
-                    isAlive = true;
-                    break;
-                }
-                else if ( pNd->IsSectionNode() )
-                {
-                    m_pFormat =
-                        
static_cast<SwSectionNode*>(pNd)->GetSection().GetFormat();
-                    isAlive = true;
-                    break;
-                }
-                else if ( pNd->IsStartNode() && (SwTableBoxStartNode ==
-                    static_cast< SwStartNode* >(pNd)->GetStartNodeType()) )
+                return 
static_cast<SwTableNode*>(pNd)->GetTable().GetFrameFormat();
+            }
+            else if (pNd->IsSectionNode())
+            {
+                return 
static_cast<SwSectionNode*>(pNd)->GetSection().GetFormat();
+            }
+            else if (pNd->IsStartNode() && (SwTableBoxStartNode ==
+                static_cast<SwStartNode*>(pNd)->GetStartNodeType()))
+            {
+                SwTableNode* pTableNode = pNd->FindTableNode();
+                if (pTableNode)
                 {
-                    SwTableNode* pTableNode = pNd->FindTableNode();
-                    if ( pTableNode )
+                    SwTableBox* pBox = 
pTableNode->GetTable().GetTableBox(m_nNodeIndex);
+                    if (pBox)
                     {
-                        SwTableBox* pBox =
-                            pTableNode->GetTable().GetTableBox( m_nNodeIndex );
-                        if ( pBox )
-                        {
-                            m_pFormat = pBox->GetFrameFormat();
-                            isAlive = true;
-                            break;
-                        }
+                        return pBox->GetFrameFormat();
                     }
                 }
             }
-            [[fallthrough]];
-        case RES_DRAWFRMFMT:
-        case RES_FLYFRMFMT:
-            if (pDoc->GetSpzFrameFormats()->IsAlive(static_cast<const 
SwFrameFormat *>(m_pFormat))
-                || pDoc->GetFrameFormats()->IsAlive(static_cast<const 
SwFrameFormat *>(m_pFormat)))
-            {
-                isAlive = true;
-            }
-            break;
-    }
-
-    if (!isAlive)
-    {
-        // Format does not exist; reset
-        m_pFormat = nullptr;
+        }
+        [[fallthrough]];
+    case RES_DRAWFRMFMT:
+    case RES_FLYFRMFMT:
+        {
+            SwFormat * pFormat = 
SwDoc::FindFormatByName(*rDoc.GetSpzFrameFormats(), m_sFormatName);
+            if (pFormat)
+                return pFormat;
+            pFormat = SwDoc::FindFormatByName(*rDoc.GetFrameFormats(), 
m_sFormatName);
+            if (pFormat)
+                return pFormat;
+        }
+        break;
     }
 
-    return nullptr != m_pFormat;
-}
-
-// Check if it is still in Doc
-SwFormat* SwUndoFormatAttr::GetFormat( SwDoc& rDoc )
-{
-    return m_pFormat && IsFormatInDoc( &rDoc ) ? m_pFormat : nullptr;
+    return nullptr;
 }
 
 void SwUndoFormatAttr::RedoImpl(::sw::UndoRedoContext & rContext)
@@ -297,12 +276,16 @@ void SwUndoFormatAttr::RepeatImpl(::sw::RepeatContext & 
rContext)
 
     SwDoc & rDoc(rContext.GetDoc());
 
+    SwFormat * pFormat = GetFormat(rDoc);
+    if (!pFormat)
+        return;
+
     switch ( m_nFormatWhich ) {
     case RES_GRFFMTCOLL: {
         SwNoTextNode *const pNd =
             rContext.GetRepeatPaM().GetNode().GetNoTextNode();
         if( pNd ) {
-            rDoc.SetAttr( m_pFormat->GetAttrSet(), *pNd->GetFormatColl() );
+            rDoc.SetAttr( pFormat->GetAttrSet(), *pNd->GetFormatColl() );
         }
     }
     break;
@@ -313,7 +296,7 @@ void SwUndoFormatAttr::RepeatImpl(::sw::RepeatContext & 
rContext)
         SwTextNode *const pNd =
             rContext.GetRepeatPaM().GetNode().GetTextNode();
         if( pNd ) {
-            rDoc.SetAttr( m_pFormat->GetAttrSet(), *pNd->GetFormatColl() );
+            rDoc.SetAttr( pFormat->GetAttrSet(), *pNd->GetFormatColl() );
         }
     }
     break;
@@ -327,14 +310,14 @@ void SwUndoFormatAttr::RepeatImpl(::sw::RepeatContext & 
rContext)
         if( pFly ) {
             // Bug 43672: do not set all attributes!
             if (SfxItemState::SET ==
-                m_pFormat->GetAttrSet().GetItemState( RES_CNTNT )) {
-                SfxItemSet aTmpSet( m_pFormat->GetAttrSet() );
+                pFormat->GetAttrSet().GetItemState( RES_CNTNT )) {
+                SfxItemSet aTmpSet( pFormat->GetAttrSet() );
                 aTmpSet.ClearItem( RES_CNTNT );
                 if( aTmpSet.Count() ) {
                     rDoc.SetAttr( aTmpSet, *pFly );
                 }
             } else {
-                rDoc.SetAttr( m_pFormat->GetAttrSet(), *pFly );
+                rDoc.SetAttr( pFormat->GetAttrSet(), *pFly );
             }
         }
         break;
@@ -346,31 +329,31 @@ SwRewriter SwUndoFormatAttr::GetRewriter() const
 {
     SwRewriter aRewriter;
 
-    if (m_pFormat) {
-        aRewriter.AddRule(UndoArg1, m_pFormat->GetName());
-    }
+    aRewriter.AddRule(UndoArg1, m_sFormatName);
 
     return aRewriter;
 }
 
-void SwUndoFormatAttr::PutAttr( const SfxPoolItem& rItem )
+void SwUndoFormatAttr::PutAttr( const SfxPoolItem& rItem, const SwDoc& rDoc )
 {
     if (RES_CNTNT == rItem.Which())
     {
         return; // tdf#126017 never save SwNodeIndex, it will go stale
     }
     m_pOldSet->Put( rItem );
-    if ( RES_ANCHOR == rItem.Which() ) {
-        SaveFlyAnchor( m_bSaveDrawPt );
+    if ( RES_ANCHOR == rItem.Which() )
+    {
+        SwFormat * pFormat = GetFormat( rDoc );
+        SaveFlyAnchor( pFormat, m_bSaveDrawPt );
     }
 }
 
-void SwUndoFormatAttr::SaveFlyAnchor( bool bSvDrwPt )
+void SwUndoFormatAttr::SaveFlyAnchor( const SwFormat * pFormat, bool bSvDrwPt )
 {
     // Format is valid, otherwise you would not reach this point here
     if( bSvDrwPt ) {
-        if ( RES_DRAWFRMFMT == m_pFormat->Which() ) {
-            Point aPt( static_cast<SwFrameFormat*>(m_pFormat)->FindSdrObject()
+        if ( RES_DRAWFRMFMT == pFormat->Which() ) {
+            Point aPt( static_cast<const 
SwFrameFormat*>(pFormat)->FindSdrObject()
                        ->GetRelativePos() );
             // store old value as attribute, to keep SwUndoFormatAttr small
             m_pOldSet->Put( SwFormatFrameSize( ATT_VAR_SIZE, aPt.X(), aPt.Y() 
) );
@@ -407,7 +390,7 @@ void SwUndoFormatAttr::SaveFlyAnchor( bool bSvDrwPt )
 bool SwUndoFormatAttr::RestoreFlyAnchor(::sw::UndoRedoContext & rContext)
 {
     SwDoc *const pDoc = & rContext.GetDoc();
-    SwFrameFormat* pFrameFormat = static_cast<SwFrameFormat*>(m_pFormat);
+    SwFrameFormat* pFrameFormat = static_cast<SwFrameFormat*>( GetFormat( 
*pDoc ) );
     const SwFormatAnchor& rAnchor =
         m_pOldSet->Get( RES_ANCHOR, false );
 
@@ -481,8 +464,8 @@ bool 
SwUndoFormatAttr::RestoreFlyAnchor(::sw::UndoRedoContext & rContext)
 
     {
         m_pOldSet->Put( aNewAnchor );
-        SwUndoFormatAttrHelper aTmp( *m_pFormat, m_bSaveDrawPt );
-        m_pFormat->SetFormatAttr( *m_pOldSet );
+        SwUndoFormatAttrHelper aTmp( *pFrameFormat, m_bSaveDrawPt );
+        pFrameFormat->SetFormatAttr( *m_pOldSet );
         if ( aTmp.GetUndo() ) {
             m_nNodeIndex = aTmp.GetUndo()->m_nNodeIndex;
             // transfer ownership of helper object's old set
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to