diff options
author | Adam Co <rattles2013@gmail.com> | 2014-03-23 13:19:15 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2014-03-23 15:40:57 +0100 |
commit | 7f4f5cd71c6ccd24186fea3aafe7fcbe95630ad6 (patch) | |
tree | b6c481238c4068b941d98d33cdac92823781d38b /sw | |
parent | 31b76e83d70718c95ac7913469629ea2c0294bfe (diff) |
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
Diffstat (limited to 'sw')
-rw-r--r-- | sw/inc/IDocumentRedlineAccess.hxx | 2 | ||||
-rw-r--r-- | sw/inc/doc.hxx | 2 | ||||
-rw-r--r-- | sw/inc/docary.hxx | 7 | ||||
-rw-r--r-- | sw/inc/node.hxx | 3 | ||||
-rw-r--r-- | sw/source/core/doc/docredln.cxx | 178 | ||||
-rw-r--r-- | sw/source/core/doc/tblrwcl.cxx | 19 | ||||
-rw-r--r-- | sw/source/core/docnode/ndtbl.cxx | 11 | ||||
-rw-r--r-- | sw/source/core/docnode/nodes.cxx | 12 |
8 files changed, 231 insertions, 3 deletions
diff --git a/sw/inc/IDocumentRedlineAccess.hxx b/sw/inc/IDocumentRedlineAccess.hxx index 48320be8374a..2700a3116ef9 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 324e4a1b4948..59119052e7fb 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 b9c6f956b33d..4c717e735d58 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 d1aa67a105ca..033a28f9402a 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 1f63587d40f9..c804ce505442 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 9270ea449131..90a7e721db68 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 4f66a68d79cb..9223c7d76caf 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 30c83fe3b655..2bb922d13cbd 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(); + } } } |