sw/inc/IDocumentRedlineAccess.hxx | 2 sw/inc/doc.hxx | 2 sw/inc/docary.hxx | 7 + sw/inc/node.hxx | 3 sw/source/core/doc/docredln.cxx | 178 ++++++++++++++++++++++++++++++++++++++ sw/source/core/doc/tblrwcl.cxx | 19 +++- sw/source/core/docnode/ndtbl.cxx | 11 ++ sw/source/core/docnode/nodes.cxx | 12 ++ 8 files changed, 231 insertions(+), 3 deletions(-)
New commits: commit 7f4f5cd71c6ccd24186fea3aafe7fcbe95630ad6 Author: Adam Co <rattles2...@gmail.com> Date: Sun Mar 23 13:19:15 2014 +0200 Remove table-related redlines when table,row,cell removed A table, a row or a cell might have redlines objects attached to it. This patch makes sure than when a table\row\cell are removed - any redlines that are attached to them are removed from the 'SwExtraRedlineTbl' object. This is to prevent any 'orphaned' redline objects. Conflicts: sw/source/core/doc/docredln.cxx Reviewed on: https://gerrit.libreoffice.org/8726 Change-Id: I992e3fb4aadeb891ffd472b5d638d337a8609c01 diff --git a/sw/inc/IDocumentRedlineAccess.hxx b/sw/inc/IDocumentRedlineAccess.hxx index 48320be..2700a31 100644 --- a/sw/inc/IDocumentRedlineAccess.hxx +++ b/sw/inc/IDocumentRedlineAccess.hxx @@ -134,6 +134,8 @@ public: virtual const SwRedlineTbl& GetRedlineTbl() const = 0; virtual const SwExtraRedlineTbl& GetExtraRedlineTbl() const = 0; + virtual SwExtraRedlineTbl& GetExtraRedlineTbl() = 0; + virtual bool HasExtraRedlineTbl() const = 0; virtual bool IsInRedlines(const SwNode& rNode) const = 0; diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx index 324e4a1..5911905 100644 --- a/sw/inc/doc.hxx +++ b/sw/inc/doc.hxx @@ -760,6 +760,8 @@ public: virtual bool IsInRedlines(const SwNode& rNode) const; virtual const SwRedlineTbl& GetRedlineTbl() const; virtual const SwExtraRedlineTbl& GetExtraRedlineTbl() const; + virtual SwExtraRedlineTbl& GetExtraRedlineTbl(); + virtual bool HasExtraRedlineTbl() const; virtual bool AppendRedline(/*[in]*/SwRangeRedline* pPtr, /*[in]*/bool bCallDelete); virtual bool AppendTableRowRedline(/*[in]*/SwTableRowRedline* pPtr, /*[in]*/bool bCallDelete); virtual bool AppendTableCellRedline(/*[in]*/SwTableCellRedline* pPtr, /*[in]*/bool bCallDelete); diff --git a/sw/inc/docary.hxx b/sw/inc/docary.hxx index b9c6f95..4c717e7 100644 --- a/sw/inc/docary.hxx +++ b/sw/inc/docary.hxx @@ -39,6 +39,9 @@ class SwUnoCrsr; class SwOLENode; class SwTxtFmtColl; class SwGrfFmtColl; +class SwTable; +class SwTableLine; +class SwTableBox; namespace com { namespace sun { namespace star { namespace i18n { struct ForbiddenCharacters; ///< comes from the I18N UNO interface @@ -204,6 +207,10 @@ public: sal_uInt16 GetSize() const { return m_aExtraRedlines.size(); } SwExtraRedline* GetRedline( sal_uInt16 uIndex ) const { return m_aExtraRedlines.operator[]( uIndex ); } bool IsEmpty() const { return m_aExtraRedlines.empty(); } + + bool DeleteAllTableRedlines( SwDoc* pDoc, const SwTable& rTable, bool bSaveInUndo, sal_uInt16 nRedlineTypeToDelete ); + bool DeleteTableRowRedline ( SwDoc* pDoc, const SwTableLine& rTableLine, bool bSaveInUndo, sal_uInt16 nRedlineTypeToDelete ); + bool DeleteTableCellRedline( SwDoc* pDoc, const SwTableBox& rTableBox, bool bSaveInUndo, sal_uInt16 nRedlineTypeToDelete ); }; class SwUnoCrsrTbl : public std::set<SwUnoCrsr*> { diff --git a/sw/inc/node.hxx b/sw/inc/node.hxx index d1aa67a..033a28f 100644 --- a/sw/inc/node.hxx +++ b/sw/inc/node.hxx @@ -515,6 +515,9 @@ public: SwTableNode* MakeCopy( SwDoc*, const SwNodeIndex& ) const; void SetNewTable( SwTable* , sal_Bool bNewFrames=sal_True ); + // Removes redline objects that relate to this table from the 'Extra Redlines' table + void RemoveRedlines(); + private: /// Private constructor because copying is never allowed!! SwTableNode( const SwTableNode & rNode ); diff --git a/sw/source/core/doc/docredln.cxx b/sw/source/core/doc/docredln.cxx index 1f63587..c804ce5 100644 --- a/sw/source/core/doc/docredln.cxx +++ b/sw/source/core/doc/docredln.cxx @@ -222,6 +222,16 @@ SwExtraRedlineTbl::~SwExtraRedlineTbl() DeleteAndDestroyAll(); } +SwExtraRedlineTbl& SwDoc::GetExtraRedlineTbl() +{ + return *mpExtraRedlineTbl; +} + +bool SwDoc::HasExtraRedlineTbl() const +{ + return mpExtraRedlineTbl ? true : false; +} + bool SwDoc::IsRedlineMove() const { return mbIsRedlineMove; @@ -1498,6 +1508,174 @@ sal_uInt16 SwDoc::GetRedlinePos( const SwNode& rNd, sal_uInt16 nType ) const // To-Do - add 'SwExtraRedlineTbl' also ? } +bool SwExtraRedlineTbl::DeleteAllTableRedlines( SwDoc* pDoc, const SwTable& rTable, bool bSaveInUndo, sal_uInt16 nRedlineTypeToDelete ) +{ + if( nsRedlineMode_t::REDLINE_IGNOREDELETE_REDLINES & pDoc->GetRedlineMode() ) + return false; + + bool bChg = false; + + if (bSaveInUndo && pDoc->GetIDocumentUndoRedo().DoesUndo()) + { + // To-Do - Add 'Undo' support for deleting 'Table Cell' redlines + /* + SwUndoRedline* pUndo = new SwUndoRedline( UNDO_REDLINE, rRange ); + if( pUndo->GetRedlSaveCount() ) + { + GetIDocumentUndoRedo().AppendUndo(pUndo); + } + else + delete pUndo; + */ + } + + for(sal_uInt16 nCurRedlinePos = 0; nCurRedlinePos < GetSize(); ++nCurRedlinePos ) + { + SwExtraRedline* pExtraRedline = GetRedline(nCurRedlinePos); + const SwTableCellRedline* pTableCellRedline = dynamic_cast<const SwTableCellRedline*>(pExtraRedline); + if (pTableCellRedline) + { + const SwTableBox *pRedTabBox = &pTableCellRedline->GetTableBox(); + const SwTable& pRedTable = pRedTabBox->GetSttNd()->FindTableNode()->GetTable(); + if ( &pRedTable == &rTable ) + { + // Redline for this table + const SwRedlineData& aRedlineData = pTableCellRedline->GetRedlineData(); + sal_uInt16 nRedlineType = aRedlineData.GetType(); + + // Check if this redline object type should be deleted + if( USHRT_MAX != nRedlineTypeToDelete && nRedlineTypeToDelete != nRedlineType ) + continue; + + DeleteAndDestroy( nCurRedlinePos ); + bChg = true; + } + } + else + { + const SwTableRowRedline* pTableRowRedline = dynamic_cast<const SwTableRowRedline*>(pExtraRedline); + if (pTableRowRedline) + { + const SwTableLine *pRedTabLine = &pTableRowRedline->GetTableLine(); + const SwTableBoxes &pRedTabBoxes = pRedTabLine->GetTabBoxes(); + const SwTable& pRedTable = pRedTabBoxes[0]->GetSttNd()->FindTableNode()->GetTable(); + if ( &pRedTable == &rTable ) + { + // Redline for this table + const SwRedlineData& aRedlineData = pTableRowRedline->GetRedlineData(); + sal_uInt16 nRedlineType = aRedlineData.GetType(); + + // Check if this redline object type should be deleted + if( USHRT_MAX != nRedlineTypeToDelete && nRedlineTypeToDelete != nRedlineType ) + continue; + + DeleteAndDestroy( nCurRedlinePos ); + bChg = true; + } + } + } + } + + if( bChg ) + pDoc->SetModified(); + + return bChg; +} + +bool SwExtraRedlineTbl::DeleteTableRowRedline( SwDoc* pDoc, const SwTableLine& rTableLine, bool bSaveInUndo, sal_uInt16 nRedlineTypeToDelete ) +{ + if( nsRedlineMode_t::REDLINE_IGNOREDELETE_REDLINES & pDoc->GetRedlineMode() ) + return false; + + bool bChg = false; + + if (bSaveInUndo && pDoc->GetIDocumentUndoRedo().DoesUndo()) + { + // To-Do - Add 'Undo' support for deleting 'Table Cell' redlines + /* + SwUndoRedline* pUndo = new SwUndoRedline( UNDO_REDLINE, rRange ); + if( pUndo->GetRedlSaveCount() ) + { + GetIDocumentUndoRedo().AppendUndo(pUndo); + } + else + delete pUndo; + */ + } + + for(sal_uInt16 nCurRedlinePos = 0; nCurRedlinePos < GetSize(); ++nCurRedlinePos ) + { + SwExtraRedline* pExtraRedline = GetRedline(nCurRedlinePos); + const SwTableRowRedline* pTableRowRedline = dynamic_cast<const SwTableRowRedline*>(pExtraRedline); + const SwTableLine *pRedTabLine = pTableRowRedline ? &pTableRowRedline->GetTableLine() : NULL; + if ( pRedTabLine == &rTableLine ) + { + // Redline for this table row + const SwRedlineData& aRedlineData = pTableRowRedline->GetRedlineData(); + sal_uInt16 nRedlineType = aRedlineData.GetType(); + + // Check if this redline object type should be deleted + if( USHRT_MAX != nRedlineTypeToDelete && nRedlineTypeToDelete != nRedlineType ) + continue; + + DeleteAndDestroy( nCurRedlinePos ); + bChg = true; + } + } + + if( bChg ) + pDoc->SetModified(); + + return bChg; +} + +bool SwExtraRedlineTbl::DeleteTableCellRedline( SwDoc* pDoc, const SwTableBox& rTableBox, bool bSaveInUndo, sal_uInt16 nRedlineTypeToDelete ) +{ + if( nsRedlineMode_t::REDLINE_IGNOREDELETE_REDLINES & pDoc->GetRedlineMode() ) + return false; + + bool bChg = false; + + if (bSaveInUndo && pDoc->GetIDocumentUndoRedo().DoesUndo()) + { + // To-Do - Add 'Undo' support for deleting 'Table Cell' redlines + /* + SwUndoRedline* pUndo = new SwUndoRedline( UNDO_REDLINE, rRange ); + if( pUndo->GetRedlSaveCount() ) + { + GetIDocumentUndoRedo().AppendUndo(pUndo); + } + else + delete pUndo; + */ + } + + for(sal_uInt16 nCurRedlinePos = 0; nCurRedlinePos < GetSize(); ++nCurRedlinePos ) + { + SwExtraRedline* pExtraRedline = GetRedline(nCurRedlinePos); + const SwTableCellRedline* pTableCellRedline = dynamic_cast<const SwTableCellRedline*>(pExtraRedline); + const SwTableBox *pRedTabBox = pTableCellRedline ? &pTableCellRedline->GetTableBox() : NULL; + if ( pRedTabBox == &rTableBox ) + { + // Redline for this table cell + const SwRedlineData& aRedlineData = pTableCellRedline->GetRedlineData(); + sal_uInt16 nRedlineType = aRedlineData.GetType(); + + // Check if this redline object type should be deleted + if( USHRT_MAX != nRedlineTypeToDelete && nRedlineTypeToDelete != nRedlineType ) + continue; + + DeleteAndDestroy( nCurRedlinePos ); + bChg = true; + } + } + + if( bChg ) + pDoc->SetModified(); + + return bChg; +} + const SwRangeRedline* SwDoc::GetRedline( const SwPosition& rPos, sal_uInt16* pFndPos ) const { diff --git a/sw/source/core/doc/tblrwcl.cxx b/sw/source/core/doc/tblrwcl.cxx index 9270ea4..90a7e72 100644 --- a/sw/source/core/doc/tblrwcl.cxx +++ b/sw/source/core/doc/tblrwcl.cxx @@ -53,6 +53,7 @@ #include <boost/scoped_ptr.hpp> #include <boost/foreach.hpp> #include <switerator.hxx> +#include <docary.hxx> using namespace com::sun::star; using namespace com::sun::star::uno; @@ -773,6 +774,10 @@ void _DeleteBox( SwTable& rTbl, SwTableBox* pBox, SwUndo* pUndo, SwStartNode* pSttNd = (SwStartNode*)pBox->GetSttNd(); if( pShareFmts ) pShareFmts->RemoveFormat( *rTblBoxes[ nDelPos ]->GetFrmFmt() ); + + // Before deleting the 'Table Box' from memory - delete any redlines attached to it + if ( rTbl.GetFrmFmt()->GetDoc()->HasExtraRedlineTbl() ) + rTbl.GetFrmFmt()->GetDoc()->GetExtraRedlineTbl().DeleteTableCellRedline( rTbl.GetFrmFmt()->GetDoc(), *(rTblBoxes[nDelPos]), true, USHRT_MAX ); delete rTblBoxes[nDelPos]; rTblBoxes.erase( rTblBoxes.begin() + nDelPos ); @@ -821,7 +826,12 @@ void _DeleteBox( SwTable& rTbl, SwTableBox* pBox, SwUndo* pUndo, nDelPos = rTbl.GetTabLines().GetPos( pLine ); if( pShareFmts ) pShareFmts->RemoveFormat( *rTbl.GetTabLines()[ nDelPos ]->GetFrmFmt() ); - delete rTbl.GetTabLines()[ nDelPos ]; + + SwTableLine* pTabLineToDelete = rTbl.GetTabLines()[ nDelPos ]; + // Before deleting the 'Table Line' from memory - delete any redlines attached to it + if ( rTbl.GetFrmFmt()->GetDoc()->HasExtraRedlineTbl() ) + rTbl.GetFrmFmt()->GetDoc()->GetExtraRedlineTbl().DeleteTableRowRedline( rTbl.GetFrmFmt()->GetDoc(), *pTabLineToDelete, true, USHRT_MAX ); + delete pTabLineToDelete; rTbl.GetTabLines().erase( rTbl.GetTabLines().begin() + nDelPos ); break; // we cannot delete more } @@ -831,7 +841,12 @@ void _DeleteBox( SwTable& rTbl, SwTableBox* pBox, SwUndo* pUndo, nDelPos = pBox->GetTabLines().GetPos( pLine ); if( pShareFmts ) pShareFmts->RemoveFormat( *pBox->GetTabLines()[ nDelPos ]->GetFrmFmt() ); - delete pBox->GetTabLines()[ nDelPos ]; + + SwTableLine* pTabLineToDelete = pBox->GetTabLines()[ nDelPos ]; + // Before deleting the 'Table Line' from memory - delete any redlines attached to it + if ( rTbl.GetFrmFmt()->GetDoc()->HasExtraRedlineTbl() ) + rTbl.GetFrmFmt()->GetDoc()->GetExtraRedlineTbl().DeleteTableRowRedline( rTbl.GetFrmFmt()->GetDoc(), *pTabLineToDelete, true, USHRT_MAX ); + delete pTabLineToDelete; pBox->GetTabLines().erase( pBox->GetTabLines().begin() + nDelPos ); } while( pBox->GetTabLines().empty() ); } diff --git a/sw/source/core/docnode/ndtbl.cxx b/sw/source/core/docnode/ndtbl.cxx index 4f66a68..9223c7d 100644 --- a/sw/source/core/docnode/ndtbl.cxx +++ b/sw/source/core/docnode/ndtbl.cxx @@ -2453,6 +2453,17 @@ void SwTableNode::SetNewTable( SwTable* pNewTable, sal_Bool bNewFrames ) } } +void SwTableNode::RemoveRedlines() +{ + SwDoc* pDoc = GetDoc(); + if (pDoc) + { + SwTable& rTbl = GetTable(); + if ( pDoc->HasExtraRedlineTbl() ) + pDoc->GetExtraRedlineTbl().DeleteAllTableRedlines( pDoc, rTbl, true, USHRT_MAX ); + } +} + void SwDoc::GetTabCols( SwTabCols &rFill, const SwCursor* pCrsr, const SwCellFrm* pBoxFrm ) const { diff --git a/sw/source/core/docnode/nodes.cxx b/sw/source/core/docnode/nodes.cxx index 30c83fe..2bb922d 100644 --- a/sw/source/core/docnode/nodes.cxx +++ b/sw/source/core/docnode/nodes.cxx @@ -2228,12 +2228,22 @@ void SwNodes::RemoveNode( sal_uLong nDelPos, sal_uLong nSz, sal_Bool bDel ) { for (sal_uLong nCnt = 0; nCnt < nSz; nCnt++) { - SwTxtNode * pTxtNd = ((*this)[ nDelPos + nCnt ])->GetTxtNode(); + SwNode* pNode = ((*this)[ nDelPos + nCnt ]); + SwTxtNode * pTxtNd = pNode->GetTxtNode(); if (pTxtNd) { pTxtNd->RemoveFromList(); } + SwTableNode* pTableNode = pNode->GetTableNode(); + if (pTableNode) + { + // The node that is deleted is a table node. + // Need to make sure that all the redlines that are + // related to this table are removed from the + // 'Extra Redlines' array + pTableNode->RemoveRedlines(); + } } } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits