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