diff options
Diffstat (limited to 'sw/source/core/undo/untbl.cxx')
-rw-r--r-- | sw/source/core/undo/untbl.cxx | 799 |
1 files changed, 426 insertions, 373 deletions
diff --git a/sw/source/core/undo/untbl.cxx b/sw/source/core/undo/untbl.cxx index a07d8cb7df69..5c5c88f74c24 100644 --- a/sw/source/core/undo/untbl.cxx +++ b/sw/source/core/undo/untbl.cxx @@ -17,12 +17,15 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <libxml/xmlwriter.h> + #include <UndoTable.hxx> #include <UndoRedline.hxx> #include <UndoDelete.hxx> #include <UndoSplitMove.hxx> #include <UndoCore.hxx> #include <fesh.hxx> +#include <fmtpdsc.hxx> #include <hintids.hxx> #include <hints.hxx> #include <doc.hxx> @@ -32,6 +35,8 @@ #include <IDocumentRedlineAccess.hxx> #include <IDocumentFieldsAccess.hxx> #include <IDocumentStylePoolAccess.hxx> +#include <IDocumentLayoutAccess.hxx> +#include <rootfrm.hxx> #include <editsh.hxx> #include <docary.hxx> #include <ndtxt.hxx> @@ -42,9 +47,6 @@ #include <rolbck.hxx> #include <ddefld.hxx> #include <tabfrm.hxx> -#include <rowfrm.hxx> -#include <cellfrm.hxx> -#include <swcache.hxx> #include <tblafmt.hxx> #include <poolfmt.hxx> #include <mvsave.hxx> @@ -59,6 +61,9 @@ #include <unochart.hxx> #include <calbck.hxx> #include <frameformats.hxx> +#include <editeng/formatbreakitem.hxx> +#include <osl/diagnose.h> +#include <docsh.hxx> #include <memory> #include <utility> @@ -80,7 +85,7 @@ typedef std::vector<std::shared_ptr<SfxItemSet> > SfxItemSets; struct UndoTableCpyTable_Entry { - sal_uLong nBoxIdx, nOffset; + SwNodeOffset nBoxIdx, nOffset; std::unique_ptr<SfxItemSet> pBoxNumAttr; std::unique_ptr<SwUndo> pUndo; @@ -88,6 +93,8 @@ struct UndoTableCpyTable_Entry bool bJoin; // For redlining only explicit UndoTableCpyTable_Entry( const SwTableBox& rBox ); + + void dumpAsXml(xmlTextWriterPtr pWriter) const; }; namespace { @@ -143,9 +150,9 @@ class SaveLine friend SaveTable; friend class SaveBox; - SaveLine* pNext; - SaveBox* pBox; - sal_uInt16 nItemSet; + SaveLine* m_pNext; + SaveBox* m_pBox; + sal_uInt16 m_nItemSet; SaveLine(const SaveLine&) = delete; SaveLine& operator=(const SaveLine&) = delete; @@ -164,15 +171,15 @@ class SaveBox { friend class SaveLine; - SaveBox* pNext; - sal_uLong nSttNode; - sal_Int32 nRowSpan; - sal_uInt16 nItemSet; + SaveBox* m_pNext; + SwNodeOffset m_nStartNode; + sal_Int32 m_nRowSpan; + sal_uInt16 m_nItemSet; union { SfxItemSets* pContentAttrs; SaveLine* pLine; - } Ptrs; + } m_Ptrs; public: SaveBox( SaveBox* pPrev, const SwTableBox& rBox, SaveTable& rSTable ); @@ -201,15 +208,15 @@ So we need to remember not only the start node position but the end node positio struct SwTableToTextSave { - sal_uLong m_nSttNd; - sal_uLong m_nEndNd; + SwNodeOffset m_nSttNd; + SwNodeOffset m_nEndNd; sal_Int32 m_nContent; std::unique_ptr<SwHistory> m_pHstry; // metadata references for first and last paragraph in cell std::shared_ptr< ::sfx2::MetadatableUndo > m_pMetadataUndoStart; std::shared_ptr< ::sfx2::MetadatableUndo > m_pMetadataUndoEnd; - SwTableToTextSave( SwDoc& rDoc, sal_uLong nNd, sal_uLong nEndIdx, sal_Int32 nContent ); + SwTableToTextSave( SwDoc& rDoc, SwNodeOffset nNd, SwNodeOffset nEndIdx, sal_Int32 nContent ); private: SwTableToTextSave(const SwTableToTextSave&) = delete; @@ -217,13 +224,12 @@ private: }; -sal_uInt16 const aSave_BoxContentSet[] = { +WhichRangesContainer const aSave_BoxContentSet(svl::Items< RES_CHRATR_COLOR, RES_CHRATR_CROSSEDOUT, RES_CHRATR_FONT, RES_CHRATR_FONTSIZE, RES_CHRATR_POSTURE, RES_CHRATR_POSTURE, RES_CHRATR_SHADOWED, RES_CHRATR_WEIGHT, - RES_PARATR_ADJUST, RES_PARATR_ADJUST, - 0 }; + RES_PARATR_ADJUST, RES_PARATR_ADJUST>); SwUndoInsTable::SwUndoInsTable( const SwPosition& rPos, sal_uInt16 nCl, sal_uInt16 nRw, sal_uInt16 nAdj, const SwInsertTableOptions& rInsTableOpts, @@ -232,17 +238,17 @@ SwUndoInsTable::SwUndoInsTable( const SwPosition& rPos, sal_uInt16 nCl, sal_uInt const OUString & rName) : SwUndo( SwUndoId::INSTABLE, &rPos.GetDoc() ), m_aInsTableOptions( rInsTableOpts ), - m_nStartNode( rPos.nNode.GetIndex() ), m_nRows( nRw ), m_nColumns( nCl ), m_nAdjust( nAdj ) + m_nStartNode( rPos.GetNodeIndex() ), m_nRows( nRw ), m_nColumns( nCl ), m_nAdjust( nAdj ) { if( pColArr ) { - m_pColumnWidth.reset( new std::vector<sal_uInt16>(*pColArr) ); + m_oColumnWidth.emplace( *pColArr ); } if( pTAFormat ) m_pAutoFormat.reset( new SwTableAutoFormat( *pTAFormat ) ); // consider redline - SwDoc& rDoc = rPos.nNode.GetNode().GetDoc(); + SwDoc& rDoc = rPos.GetNode().GetDoc(); if( rDoc.getIDocumentRedlineAccess().IsRedlineOn() ) { m_pRedlineData.reset( new SwRedlineData( RedlineType::Insert, rDoc.getIDocumentRedlineAccess().GetRedlineAuthor() ) ); @@ -255,7 +261,7 @@ SwUndoInsTable::SwUndoInsTable( const SwPosition& rPos, sal_uInt16 nCl, sal_uInt SwUndoInsTable::~SwUndoInsTable() { m_pDDEFieldType.reset(); - m_pColumnWidth.reset(); + m_oColumnWidth.reset(); m_pRedlineData.reset(); m_pAutoFormat.reset(); } @@ -266,7 +272,14 @@ void SwUndoInsTable::UndoImpl(::sw::UndoRedoContext & rContext) SwNodeIndex aIdx( rDoc.GetNodes(), m_nStartNode ); SwTableNode* pTableNd = aIdx.GetNode().GetTableNode(); - OSL_ENSURE( pTableNd, "no TableNode" ); + // tdf#159025 skip undo if SwTableNode is a nullptr + // I don't know what causes the SwTableNode to be a nullptr in the + // case of tdf#159025, but at least stop the crashing by skipping + // this undo request. + SAL_WARN_IF( !pTableNd, "sw.core", "no TableNode" ); + if( !pTableNd ) + return; + pTableNd->DelFrames(); if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineFlags() )) @@ -278,15 +291,16 @@ void SwUndoInsTable::UndoImpl(::sw::UndoRedoContext & rContext) if( pNextNd ) { SwFrameFormat* pTableFormat = pTableNd->GetTable().GetFrameFormat(); - const SfxPoolItem *pItem; - if( SfxItemState::SET == pTableFormat->GetItemState( RES_PAGEDESC, - false, &pItem ) ) + if( const SwFormatPageDesc* pItem = pTableFormat->GetItemIfSet( RES_PAGEDESC, + false ) ) pNextNd->SetAttr( *pItem ); - if( SfxItemState::SET == pTableFormat->GetItemState( RES_BREAK, - false, &pItem ) ) + if( const SvxFormatBreakItem* pItem = pTableFormat->GetItemIfSet( RES_BREAK, + false ) ) pNextNd->SetAttr( *pItem ); + + ::sw::NotifyTableCollapsedParagraph(pNextNd, nullptr); } m_sTableName = pTableNd->GetTable().GetFrameFormat()->GetName(); @@ -298,20 +312,27 @@ void SwUndoInsTable::UndoImpl(::sw::UndoRedoContext & rContext) SwPaM & rPam( rContext.GetCursorSupplier().CreateNewShellCursor() ); rPam.DeleteMark(); - rPam.GetPoint()->nNode = aIdx; - rPam.GetPoint()->nContent.Assign( rPam.GetContentNode(), 0 ); + rPam.GetPoint()->Assign(aIdx); } void SwUndoInsTable::RedoImpl(::sw::UndoRedoContext & rContext) { SwDoc & rDoc = rContext.GetDoc(); - SwPosition const aPos(SwNodeIndex(rDoc.GetNodes(), m_nStartNode)); + SwEditShell *const pEditShell(rDoc.GetEditShell()); + OSL_ENSURE(pEditShell, "SwUndoInsTable::RedoImpl needs a SwEditShell!"); + if (!pEditShell) + { + throw uno::RuntimeException(); + } + + SwPosition const aPos(rDoc.GetNodes(), m_nStartNode); const SwTable* pTable = rDoc.InsertTable( m_aInsTableOptions, aPos, m_nRows, m_nColumns, m_nAdjust, - m_pAutoFormat.get(), m_pColumnWidth.get() ); - rDoc.GetEditShell()->MoveTable( GotoPrevTable, fnTableStart ); - static_cast<SwFrameFormat*>(pTable->GetFrameFormat())->SetName( m_sTableName ); + m_pAutoFormat.get(), + m_oColumnWidth ? &*m_oColumnWidth : nullptr ); + pEditShell->MoveTable( GotoPrevTable, fnTableStart ); + static_cast<SwFrameFormat*>(pTable->GetFrameFormat())->SetFormatName( m_sTableName ); SwTableNode* pTableNode = rDoc.GetNodes()[m_nStartNode]->GetTableNode(); if( m_pDDEFieldType ) @@ -328,10 +349,7 @@ void SwUndoInsTable::RedoImpl(::sw::UndoRedoContext & rContext) !rDoc.getIDocumentRedlineAccess().GetRedlineTable().empty() ))) return; - SwPaM aPam( *pTableNode->EndOfSectionNode(), *pTableNode, 1 ); - SwContentNode* pCNd = aPam.GetContentNode( false ); - if( pCNd ) - aPam.GetMark()->nContent.Assign( pCNd, 0 ); + SwPaM aPam( *pTableNode->EndOfSectionNode(), *pTableNode, SwNodeOffset(1) ); if( m_pRedlineData && IDocumentRedlineAccess::IsRedlineOn( GetRedlineFlags() ) ) { @@ -349,7 +367,8 @@ void SwUndoInsTable::RepeatImpl(::sw::RepeatContext & rContext) { rContext.GetDoc().InsertTable( m_aInsTableOptions, *rContext.GetRepeatPaM().GetPoint(), - m_nRows, m_nColumns, m_nAdjust, m_pAutoFormat.get(), m_pColumnWidth.get() ); + m_nRows, m_nColumns, m_nAdjust, m_pAutoFormat.get(), + m_oColumnWidth ? &*m_oColumnWidth : nullptr ); } SwRewriter SwUndoInsTable::GetRewriter() const @@ -363,7 +382,7 @@ SwRewriter SwUndoInsTable::GetRewriter() const return aRewriter; } -SwTableToTextSave::SwTableToTextSave( SwDoc& rDoc, sal_uLong nNd, sal_uLong nEndIdx, sal_Int32 nCnt ) +SwTableToTextSave::SwTableToTextSave( SwDoc& rDoc, SwNodeOffset nNd, SwNodeOffset nEndIdx, sal_Int32 nCnt ) : m_nSttNd( nNd ), m_nEndNd( nEndIdx), m_nContent( nCnt ) { // keep attributes of the joined node @@ -372,7 +391,7 @@ SwTableToTextSave::SwTableToTextSave( SwDoc& rDoc, sal_uLong nNd, sal_uLong nEnd { m_pHstry.reset( new SwHistory ); - m_pHstry->Add( pNd->GetTextColl(), nNd, SwNodeType::Text ); + m_pHstry->AddColl(pNd->GetTextColl(), nNd, SwNodeType::Text); if ( pNd->GetpSwpHints() ) { m_pHstry->CopyAttr( pNd->GetpSwpHints(), nNd, 0, @@ -420,19 +439,17 @@ SwUndoTableToText::SwUndoTableToText( const SwTable& rTable, sal_Unicode cCh ) m_pHistory.reset(new SwHistory); const SwTableNode* pTableNd = rTable.GetTableNode(); - sal_uLong nTableStt = pTableNd->GetIndex(), nTableEnd = pTableNd->EndOfSectionIndex(); + SwNodeOffset nTableStt = pTableNd->GetIndex(), nTableEnd = pTableNd->EndOfSectionIndex(); - const SwFrameFormats& rFrameFormatTable = *pTableNd->GetDoc().GetSpzFrameFormats(); - for( size_t n = 0; n < rFrameFormatTable.size(); ++n ) + for(sw::SpzFrameFormat* pFormat: *pTableNd->GetDoc().GetSpzFrameFormats()) { - SwFrameFormat* pFormat = rFrameFormatTable[ n ]; SwFormatAnchor const*const pAnchor = &pFormat->GetAnchor(); - SwPosition const*const pAPos = pAnchor->GetContentAnchor(); - if (pAPos && + SwNode const*const pAnchorNode = pAnchor->GetAnchorNode(); + if (pAnchorNode && ((RndStdIds::FLY_AT_CHAR == pAnchor->GetAnchorId()) || (RndStdIds::FLY_AT_PARA == pAnchor->GetAnchorId())) && - nTableStt <= pAPos->nNode.GetIndex() && - pAPos->nNode.GetIndex() < nTableEnd ) + nTableStt <= pAnchorNode->GetIndex() && + pAnchorNode->GetIndex() < nTableEnd ) { m_pHistory->AddChangeFlyAnchor(*pFormat); } @@ -460,9 +477,9 @@ void SwUndoTableToText::UndoImpl(::sw::UndoRedoContext & rContext) SwNodeIndex aFrameIdx( rDoc.GetNodes(), m_nStartNode ); SwNodeIndex aEndIdx( rDoc.GetNodes(), m_nEndNode ); - pPam->GetPoint()->nNode = aFrameIdx; + pPam->GetPoint()->Assign( aFrameIdx ); pPam->SetMark(); - pPam->GetPoint()->nNode = aEndIdx; + pPam->GetPoint()->Assign( aEndIdx ); rDoc.DelNumRules( *pPam ); pPam->DeleteMark(); @@ -509,9 +526,9 @@ void SwUndoTableToText::UndoImpl(::sw::UndoRedoContext & rContext) // Is a table selection requested? pPam->DeleteMark(); - pPam->GetPoint()->nNode = *pTableNd->EndOfSectionNode(); + pPam->GetPoint()->Assign( *pTableNd->EndOfSectionNode() ); pPam->SetMark(); - pPam->GetPoint()->nNode = *pPam->GetNode().StartOfSectionNode(); + pPam->GetPoint()->Assign( *pPam->GetPointNode().StartOfSectionNode() ); pPam->Move( fnMoveForward, GoInContent ); pPam->Exchange(); pPam->Move( fnMoveBackward, GoInContent ); @@ -520,14 +537,14 @@ void SwUndoTableToText::UndoImpl(::sw::UndoRedoContext & rContext) } // located in untbl.cxx and only an Undo object is allowed to call it -SwTableNode* SwNodes::UndoTableToText( sal_uLong nSttNd, sal_uLong nEndNd, +SwTableNode* SwNodes::UndoTableToText( SwNodeOffset nSttNd, SwNodeOffset nEndNd, const SwTableToTextSaves& rSavedData ) { SwNodeIndex aSttIdx( *this, nSttNd ); SwNodeIndex aEndIdx( *this, nEndNd+1 ); - SwTableNode * pTableNd = new SwTableNode( aSttIdx ); - SwEndNode* pEndNd = new SwEndNode( aEndIdx, *pTableNd ); + SwTableNode * pTableNd = new SwTableNode( aSttIdx.GetNode() ); + SwEndNode* pEndNd = new SwEndNode( aEndIdx.GetNode(), *pTableNd ); aEndIdx = *pEndNd; @@ -535,11 +552,16 @@ SwTableNode* SwNodes::UndoTableToText( sal_uLong nSttNd, sal_uLong nEndNd, Delete all Frames attached to the nodes in that range. */ SwNode* pNd; { - sal_uLong n, nTmpEnd = aEndIdx.GetIndex(); + SwNodeOffset n, nTmpEnd = aEndIdx.GetIndex(); for( n = pTableNd->GetIndex() + 1; n < nTmpEnd; ++n ) { - if( ( pNd = (*this)[ n ] )->IsContentNode() ) + pNd = (*this)[n]; + if (pNd->IsContentNode()) + { static_cast<SwContentNode*>(pNd)->DelFrames(nullptr); + } + // tdf#147938 reset merge flag in nodes + pNd->SetRedlineMergeFlag(SwNode::Merge::None); pNd->m_pStartOfSection = pTableNd; } } @@ -551,7 +573,6 @@ SwTableNode* SwNodes::UndoTableToText( sal_uLong nSttNd, sal_uLong nEndNd, SwTableLine* pLine = new SwTableLine( pLineFormat, rSavedData.size(), nullptr ); pTableNd->GetTable().GetTabLines().insert( pTableNd->GetTable().GetTabLines().begin(), pLine ); - const std::shared_ptr<sw::mark::ContentIdxStore> pContentStore(sw::mark::ContentIdxStore::Create()); for( size_t n = rSavedData.size(); n; ) { const SwTableToTextSave *const pSave = rSavedData[ --n ].get(); @@ -564,12 +585,15 @@ SwTableNode* SwNodes::UndoTableToText( sal_uLong nSttNd, sal_uLong nEndNd, { // split at ContentPosition, delete previous char (= separator) OSL_ENSURE( pTextNd, "Where is my TextNode?" ); - SwIndex aCntPos( pTextNd, pSave->m_nContent - 1 ); + SwContentIndex aCntPos( pTextNd, pSave->m_nContent - 1 ); + + const std::shared_ptr<sw::mark::ContentIdxStore> pContentStore(sw::mark::ContentIdxStore::Create()); + pContentStore->Save(GetDoc(), aSttIdx.GetIndex(), aCntPos.GetIndex()); pTextNd->EraseText( aCntPos, 1 ); - std::function<void (SwTextNode *, sw::mark::RestoreMode)> restoreFunc( - [&](SwTextNode *const pNewNode, sw::mark::RestoreMode const eMode) + std::function<void (SwTextNode *, sw::mark::RestoreMode, bool)> restoreFunc( + [&](SwTextNode *const pNewNode, sw::mark::RestoreMode const eMode, bool) { if (!pContentStore->Empty()) { @@ -579,14 +603,6 @@ SwTableNode* SwNodes::UndoTableToText( sal_uLong nSttNd, sal_uLong nEndNd, pTextNd->SplitContentNode( SwPosition(aSttIdx, aCntPos), &restoreFunc); } - else - { - pContentStore->Clear(); - if( pTextNd ) - { - pContentStore->Save(GetDoc(), aSttIdx.GetIndex(), SAL_MAX_INT32); - } - } if( pTextNd ) { @@ -618,12 +634,12 @@ SwTableNode* SwNodes::UndoTableToText( sal_uLong nSttNd, sal_uLong nEndNd, } aEndIdx = pSave->m_nEndNd; - SwStartNode* pSttNd = new SwStartNode( aSttIdx, SwNodeType::Start, + SwStartNode* pSttNd = new SwStartNode( aSttIdx.GetNode(), SwNodeType::Start, SwTableBoxStartNode ); pSttNd->m_pStartOfSection = pTableNd; - new SwEndNode( aEndIdx, *pSttNd ); + new SwEndNode( aEndIdx.GetNode(), *pSttNd ); - for( sal_uLong i = aSttIdx.GetIndex(); i < aEndIdx.GetIndex()-1; ++i ) + for( SwNodeOffset i = aSttIdx.GetIndex(); i < aEndIdx.GetIndex()-1; ++i ) { pNd = (*this)[ i ]; pNd->m_pStartOfSection = pSttNd; @@ -642,14 +658,13 @@ void SwUndoTableToText::RedoImpl(::sw::UndoRedoContext & rContext) SwDoc & rDoc = rContext.GetDoc(); SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor()); - pPam->GetPoint()->nNode = m_nStartNode; - pPam->GetPoint()->nContent.Assign( nullptr, 0 ); - SwNodeIndex aSaveIdx( pPam->GetPoint()->nNode, -1 ); + pPam->GetPoint()->Assign( m_nStartNode ); + SwNodeIndex aSaveIdx( pPam->GetPoint()->GetNode(), -1 ); pPam->SetMark(); // log off all indices pPam->DeleteMark(); - SwTableNode* pTableNd = pPam->GetNode().GetTableNode(); + SwTableNode* pTableNd = pPam->GetPointNode().GetTableNode(); OSL_ENSURE( pTableNd, "Could not find any TableNode" ); if( auto pDDETable = dynamic_cast<const SwDDETable *>(&pTableNd->GetTable()) ) @@ -659,14 +674,13 @@ void SwUndoTableToText::RedoImpl(::sw::UndoRedoContext & rContext) ++aSaveIdx; SwContentNode* pCNd = aSaveIdx.GetNode().GetContentNode(); - if( !pCNd && nullptr == ( pCNd = rDoc.GetNodes().GoNext( &aSaveIdx ) ) && + if( !pCNd && nullptr == ( pCNd = SwNodes::GoNext( &aSaveIdx ) ) && nullptr == ( pCNd = SwNodes::GoPrevious( &aSaveIdx )) ) { OSL_FAIL( "Where is the TextNode now?" ); } - pPam->GetPoint()->nNode = aSaveIdx; - pPam->GetPoint()->nContent.Assign( pCNd, 0 ); + pPam->GetPoint()->Assign( aSaveIdx ); pPam->SetMark(); // log off all indices pPam->DeleteMark(); @@ -675,11 +689,11 @@ void SwUndoTableToText::RedoImpl(::sw::UndoRedoContext & rContext) void SwUndoTableToText::RepeatImpl(::sw::RepeatContext & rContext) { SwPaM *const pPam = & rContext.GetRepeatPaM(); - SwTableNode *const pTableNd = pPam->GetNode().FindTableNode(); + SwTableNode *const pTableNd = pPam->GetPointNode().FindTableNode(); if( pTableNd ) { // move cursor out of table - pPam->GetPoint()->nNode = *pTableNd->EndOfSectionNode(); + pPam->GetPoint()->Assign( *pTableNd->EndOfSectionNode() ); pPam->Move( fnMoveForward, GoInContent ); pPam->SetMark(); pPam->DeleteMark(); @@ -694,7 +708,7 @@ void SwUndoTableToText::SetRange( const SwNodeRange& rRg ) m_nEndNode = rRg.aEnd.GetIndex(); } -void SwUndoTableToText::AddBoxPos( SwDoc& rDoc, sal_uLong nNdIdx, sal_uLong nEndIdx, sal_Int32 nContentIdx ) +void SwUndoTableToText::AddBoxPos( SwDoc& rDoc, SwNodeOffset nNdIdx, SwNodeOffset nEndIdx, sal_Int32 nContentIdx ) { m_vBoxSaves.push_back(std::make_unique<SwTableToTextSave>(rDoc, nNdIdx, nEndIdx, nContentIdx)); } @@ -711,9 +725,9 @@ SwUndoTextToTable::SwUndoTextToTable( const SwPaM& rRg, const SwPosition* pEnd = rRg.End(); SwNodes& rNds = rRg.GetDoc().GetNodes(); - m_bSplitEnd = pEnd->nContent.GetIndex() && ( pEnd->nContent.GetIndex() - != pEnd->nNode.GetNode().GetContentNode()->Len() || - pEnd->nNode.GetIndex() >= rNds.GetEndOfContent().GetIndex()-1 ); + m_bSplitEnd = pEnd->GetContentIndex() && ( pEnd->GetContentIndex() + != pEnd->GetNode().GetContentNode()->Len() || + pEnd->GetNodeIndex() >= rNds.GetEndOfContent().GetIndex()-1 ); } SwUndoTextToTable::~SwUndoTextToTable() @@ -725,7 +739,7 @@ void SwUndoTextToTable::UndoImpl(::sw::UndoRedoContext & rContext) { SwDoc & rDoc = rContext.GetDoc(); - sal_uLong nTableNd = m_nSttNode; + SwNodeOffset nTableNd = m_nSttNode; if( m_nSttContent ) ++nTableNd; // Node was split previously SwNodeIndex aIdx( rDoc.GetNodes(), nTableNd ); @@ -760,37 +774,32 @@ void SwUndoTextToTable::UndoImpl(::sw::UndoRedoContext & rContext) rDoc.TableToText( pTNd, 0x0b == m_cSeparator ? 0x09 : m_cSeparator ); // join again at start? - SwPaM aPam(rDoc.GetNodes().GetEndOfContent()); - SwPosition *const pPos = aPam.GetPoint(); if( m_nSttContent ) { - pPos->nNode = nTableNd; - pPos->nContent.Assign(pPos->nNode.GetNode().GetContentNode(), 0); + SwPaM aPam(rDoc.GetNodes(), nTableNd); if (aPam.Move(fnMoveBackward, GoInContent)) { - SwNodeIndex & rIdx = aPam.GetPoint()->nNode; + SwNode & rIdx = aPam.GetPoint()->GetNode(); // than move, relatively, the Cursor/etc. again - RemoveIdxRel( rIdx.GetIndex()+1, *pPos ); + RemoveIdxRel( rIdx.GetIndex()+1, *aPam.GetPoint() ); - rIdx.GetNode().GetContentNode()->JoinNext(); + rIdx.GetContentNode()->JoinNext(); } } // join again at end? if( m_bSplitEnd ) { - SwNodeIndex& rIdx = pPos->nNode; - rIdx = m_nEndNode; - SwTextNode* pTextNd = rIdx.GetNode().GetTextNode(); + SwPosition aEndPos( rDoc.GetNodes(), m_nEndNode ); + SwTextNode* pTextNd = aEndPos.GetNode().GetTextNode(); if( pTextNd && pTextNd->CanJoinNext() ) { - aPam.GetMark()->nContent.Assign( nullptr, 0 ); - aPam.GetPoint()->nContent.Assign( nullptr, 0 ); + aEndPos.nContent.Assign( nullptr, 0 ); // than move, relatively, the Cursor/etc. again - pPos->nContent.Assign(pTextNd, pTextNd->GetText().getLength()); - RemoveIdxRel( m_nEndNode + 1, *pPos ); + aEndPos.SetContent(pTextNd->GetText().getLength()); + RemoveIdxRel( m_nEndNode + 1, aEndPos ); pTextNd->JoinNext(); } @@ -807,13 +816,13 @@ void SwUndoTextToTable::RedoImpl(::sw::UndoRedoContext & rContext) SwTable const*const pTable = rContext.GetDoc().TextToTable( m_aInsertTableOpts, rPam, m_cSeparator, m_nAdjust, m_pAutoFormat.get() ); - static_cast<SwFrameFormat*>(pTable->GetFrameFormat())->SetName( m_sTableName ); + static_cast<SwFrameFormat*>(pTable->GetFrameFormat())->SetFormatName( m_sTableName ); } void SwUndoTextToTable::RepeatImpl(::sw::RepeatContext & rContext) { // no Table In Table - if (!rContext.GetRepeatPaM().GetNode().FindTableNode()) + if (!rContext.GetRepeatPaM().GetPointNode().FindTableNode()) { rContext.GetDoc().TextToTable( m_aInsertTableOpts, rContext.GetRepeatPaM(), m_cSeparator, m_nAdjust, @@ -868,7 +877,7 @@ void SwUndoTableHeadline::RedoImpl(::sw::UndoRedoContext & rContext) void SwUndoTableHeadline::RepeatImpl(::sw::RepeatContext & rContext) { SwTableNode *const pTableNd = - rContext.GetRepeatPaM().GetNode().FindTableNode(); + rContext.GetRepeatPaM().GetPointNode().FindTableNode(); if( pTableNd ) { rContext.GetDoc().SetRowsToRepeat( pTableNd->GetTable(), m_nNewHeadline ); @@ -906,51 +915,57 @@ sal_uInt16 SaveTable::AddFormat( SwFrameFormat* pFormat, bool bIsLine ) // When a formula is set, never save the value. It possibly must be // recalculated. // Save formulas always in plain text. - const SfxPoolItem* pItem; - if( SfxItemState::SET == pSet->GetItemState( RES_BOXATR_FORMULA, true, &pItem )) + if( const SwTableBoxFormula* pItem = pSet->GetItemIfSet( RES_BOXATR_FORMULA )) { pSet->ClearItem( RES_BOXATR_VALUE ); if (m_pSwTable && m_bSaveFormula) { - SwTableFormulaUpdate aMsgHint(m_pSwTable); - aMsgHint.m_eFlags = TBL_BOXNAME; - SwTableBoxFormula* pFormulaItem = const_cast<SwTableBoxFormula*>(static_cast<const SwTableBoxFormula*>(pItem)); - pFormulaItem->ChgDefinedIn( pFormat ); - pFormulaItem->ChangeState( &aMsgHint ); - pFormulaItem->ChgDefinedIn( nullptr ); + const_cast<SwTable*>(m_pSwTable)->SwitchFormulasToExternalRepresentation(); + SwTableBoxFormula* pFormulaItem = const_cast<SwTableBoxFormula*>(pItem); + pFormulaItem->ChgDefinedIn(pFormat); + pFormulaItem->ToRelBoxNm(m_pSwTable); + pFormulaItem->ChgDefinedIn(nullptr); } } nRet = m_aSets.size(); m_aSets.push_back(pSet); m_aFrameFormats.insert(m_aFrameFormats.begin() + nRet, pFormat); } - return static_cast<sal_uInt16>(nRet); + return o3tl::narrowing<sal_uInt16>(nRet); } void SaveTable::RestoreAttr( SwTable& rTable, bool bMdfyBox ) { m_bModifyBox = bMdfyBox; + FndBox_ aTmpBox( nullptr, nullptr ); + bool bHideChanges = rTable.GetFrameFormat()->GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout()->IsHideRedlines(); + // TODO delete/make frames only at changing line attribute TextChangesOnly (RES_PRINT) to true again + if ( bHideChanges ) + aTmpBox.DelFrames( rTable ); + // first, get back attributes of TableFrameFormat SwFrameFormat* pFormat = rTable.GetFrameFormat(); SfxItemSet& rFormatSet = const_cast<SfxItemSet&>(static_cast<SfxItemSet const &>(pFormat->GetAttrSet())); rFormatSet.ClearItem(); rFormatSet.Put(m_aTableSet); - if( pFormat->IsInCache() ) - { - SwFrame::GetCache().Delete( pFormat ); - pFormat->SetInCache( false ); - } + pFormat->InvalidateInSwCache(RES_ATTRSET_CHG); + + // table without table frame + bool bHiddenTable = true; // for safety, invalidate all TableFrames SwIterator<SwTabFrame,SwFormat> aIter( *pFormat ); for( SwTabFrame* pLast = aIter.First(); pLast; pLast = aIter.Next() ) + { if( pLast->GetTable() == &rTable ) { pLast->InvalidateAll(); pLast->SetCompletePaint(); + bHiddenTable = false; } + } // fill FrameFormats with defaults (0) pFormat = nullptr; @@ -962,7 +977,7 @@ void SaveTable::RestoreAttr( SwTable& rTable, bool bMdfyBox ) : m_nLineCount; SaveLine* pLn = m_pLine.get(); - for( size_t n = 0; n < nLnCnt; ++n, pLn = pLn->pNext ) + for (size_t n = 0; n < nLnCnt; ++n, pLn = pLn->m_pNext) { if( !pLn ) { @@ -975,6 +990,20 @@ void SaveTable::RestoreAttr( SwTable& rTable, bool bMdfyBox ) m_aFrameFormats.clear(); m_bModifyBox = false; + + if ( bHideChanges ) + { + if ( bHiddenTable ) + { + SwTableNode* pTableNode = rTable.GetTableNode(); + pTableNode->DelFrames(); + pTableNode->MakeOwnFrames(); + } + else + { + aTmpBox.MakeFrames( rTable ); + } + } } void SaveTable::SaveContentAttrs( SwDoc* pDoc ) @@ -994,11 +1023,7 @@ void SaveTable::CreateNew( SwTable& rTable, bool bCreateFrames, rFormatSet.ClearItem(); rFormatSet.Put(m_aTableSet); - if( pFormat->IsInCache() ) - { - SwFrame::GetCache().Delete( pFormat ); - pFormat->SetInCache( false ); - } + pFormat->InvalidateInSwCache(RES_ATTRSET_CHG); // SwTableBox must have a format - the SwTableBox takes ownership of it SwTableBoxFormat *const pNewFormat(pFormat->GetDoc()->MakeTableBoxFormat()); @@ -1106,32 +1131,32 @@ void SaveTable::NewFrameFormatForBox(const SwTableBox& rTableBx, sal_uInt16 nFor KillEmptyFrameFormat(*pOldFormat); } -SaveLine::SaveLine( SaveLine* pPrev, const SwTableLine& rLine, SaveTable& rSTable ) - : pNext( nullptr ) +SaveLine::SaveLine(SaveLine* pPrev, const SwTableLine& rLine, SaveTable& rSTable) + : m_pNext(nullptr) { if( pPrev ) - pPrev->pNext = this; + pPrev->m_pNext = this; - nItemSet = rSTable.AddFormat( rLine.GetFrameFormat(), true ); + m_nItemSet = rSTable.AddFormat(rLine.GetFrameFormat(), true); - pBox = new SaveBox( nullptr, *rLine.GetTabBoxes()[ 0 ], rSTable ); - SaveBox* pBx = pBox; + m_pBox = new SaveBox(nullptr, *rLine.GetTabBoxes()[0], rSTable); + SaveBox* pBx = m_pBox; for( size_t n = 1; n < rLine.GetTabBoxes().size(); ++n ) pBx = new SaveBox( pBx, *rLine.GetTabBoxes()[ n ], rSTable ); } SaveLine::~SaveLine() { - delete pBox; - delete pNext; + delete m_pBox; + delete m_pNext; } void SaveLine::RestoreAttr( SwTableLine& rLine, SaveTable& rSTable ) { - rSTable.NewFrameFormatForLine( rLine, nItemSet, rLine.GetFrameFormat() ); + rSTable.NewFrameFormatForLine(rLine, m_nItemSet, rLine.GetFrameFormat()); - SaveBox* pBx = pBox; - for( size_t n = 0; n < rLine.GetTabBoxes().size(); ++n, pBx = pBx->pNext ) + SaveBox* pBx = m_pBox; + for (size_t n = 0; n < rLine.GetTabBoxes().size(); ++n, pBx = pBx->m_pNext) { if( !pBx ) { @@ -1144,51 +1169,54 @@ void SaveLine::RestoreAttr( SwTableLine& rLine, SaveTable& rSTable ) void SaveLine::SaveContentAttrs( SwDoc* pDoc ) { - pBox->SaveContentAttrs( pDoc ); - if( pNext ) - pNext->SaveContentAttrs( pDoc ); + m_pBox->SaveContentAttrs(pDoc); + if (m_pNext) + m_pNext->SaveContentAttrs(pDoc); } void SaveLine::CreateNew( SwTable& rTable, SwTableBox& rParent, SaveTable& rSTable ) { - SwTableLineFormat* pFormat = static_cast<SwTableLineFormat*>(rSTable.m_aFrameFormats[ nItemSet ]); + SwTableLineFormat* pFormat + = static_cast<SwTableLineFormat*>(rSTable.m_aFrameFormats[m_nItemSet]); if( !pFormat ) { SwDoc* pDoc = rTable.GetFrameFormat()->GetDoc(); pFormat = pDoc->MakeTableLineFormat(); - pFormat->SetFormatAttr(*rSTable.m_aSets[nItemSet]); - rSTable.m_aFrameFormats[nItemSet] = pFormat; + pFormat->SetFormatAttr(*rSTable.m_aSets[m_nItemSet]); + rSTable.m_aFrameFormats[m_nItemSet] = pFormat; } SwTableLine* pNew = new SwTableLine( pFormat, 1, &rParent ); rParent.GetTabLines().push_back( pNew ); - pBox->CreateNew( rTable, *pNew, rSTable ); + m_pBox->CreateNew(rTable, *pNew, rSTable); - if( pNext ) - pNext->CreateNew( rTable, rParent, rSTable ); + if (m_pNext) + m_pNext->CreateNew(rTable, rParent, rSTable); } -SaveBox::SaveBox( SaveBox* pPrev, const SwTableBox& rBox, SaveTable& rSTable ) - : pNext( nullptr ), nSttNode( ULONG_MAX ), nRowSpan(0) +SaveBox::SaveBox(SaveBox* pPrev, const SwTableBox& rBox, SaveTable& rSTable) + : m_pNext(nullptr) + , m_nStartNode(NODE_OFFSET_MAX) + , m_nRowSpan(0) { - Ptrs.pLine = nullptr; + m_Ptrs.pLine = nullptr; if( pPrev ) - pPrev->pNext = this; + pPrev->m_pNext = this; - nItemSet = rSTable.AddFormat( rBox.GetFrameFormat(), false ); + m_nItemSet = rSTable.AddFormat(rBox.GetFrameFormat(), false); if( rBox.GetSttNd() ) { - nSttNode = rBox.GetSttIdx(); - nRowSpan = rBox.getRowSpan(); + m_nStartNode = rBox.GetSttIdx(); + m_nRowSpan = rBox.getRowSpan(); } else { - Ptrs.pLine = new SaveLine( nullptr, *rBox.GetTabLines()[ 0 ], rSTable ); + m_Ptrs.pLine = new SaveLine(nullptr, *rBox.GetTabLines()[0], rSTable); - SaveLine* pLn = Ptrs.pLine; + SaveLine* pLn = m_Ptrs.pLine; for( size_t n = 1; n < rBox.GetTabLines().size(); ++n ) pLn = new SaveLine( pLn, *rBox.GetTabLines()[ n ], rSTable ); } @@ -1196,18 +1224,18 @@ SaveBox::SaveBox( SaveBox* pPrev, const SwTableBox& rBox, SaveTable& rSTable ) SaveBox::~SaveBox() { - if( ULONG_MAX == nSttNode ) // no EndBox - delete Ptrs.pLine; + if (NODE_OFFSET_MAX == m_nStartNode) // no EndBox + delete m_Ptrs.pLine; else - delete Ptrs.pContentAttrs; - delete pNext; + delete m_Ptrs.pContentAttrs; + delete m_pNext; } void SaveBox::RestoreAttr( SwTableBox& rBox, SaveTable& rSTable ) { - rSTable.NewFrameFormatForBox( rBox, nItemSet, rBox.GetFrameFormat() ); + rSTable.NewFrameFormatForBox(rBox, m_nItemSet, rBox.GetFrameFormat()); - if( ULONG_MAX == nSttNode ) // no EndBox + if (NODE_OFFSET_MAX == m_nStartNode) // no EndBox { if( rBox.GetTabLines().empty() ) { @@ -1215,8 +1243,8 @@ void SaveBox::RestoreAttr( SwTableBox& rBox, SaveTable& rSTable ) } else { - SaveLine* pLn = Ptrs.pLine; - for( size_t n = 0; n < rBox.GetTabLines().size(); ++n, pLn = pLn->pNext ) + SaveLine* pLn = m_Ptrs.pLine; + for (size_t n = 0; n < rBox.GetTabLines().size(); ++n, pLn = pLn->m_pNext) { if( !pLn ) { @@ -1228,27 +1256,23 @@ void SaveBox::RestoreAttr( SwTableBox& rBox, SaveTable& rSTable ) } } } - else if( rBox.GetSttNd() && rBox.GetSttIdx() == nSttNode ) + else if (rBox.GetSttNd() && rBox.GetSttIdx() == m_nStartNode) { - if( Ptrs.pContentAttrs ) + if (m_Ptrs.pContentAttrs) { SwNodes& rNds = rBox.GetFrameFormat()->GetDoc()->GetNodes(); sal_uInt16 nSet = 0; - sal_uLong nEnd = rBox.GetSttNd()->EndOfSectionIndex(); - for( sal_uLong n = nSttNode + 1; n < nEnd; ++n ) + SwNodeOffset nEnd = rBox.GetSttNd()->EndOfSectionIndex(); + for (SwNodeOffset n = m_nStartNode + 1; n < nEnd; ++n) { SwContentNode* pCNd = rNds[ n ]->GetContentNode(); if( pCNd ) { - std::shared_ptr<SfxItemSet> pSet( (*Ptrs.pContentAttrs)[ nSet++ ] ); + std::shared_ptr<SfxItemSet> pSet((*m_Ptrs.pContentAttrs)[nSet++]); if( pSet ) { - sal_uInt16 const *pRstAttr = aSave_BoxContentSet; - while( *pRstAttr ) - { - pCNd->ResetAttr( *pRstAttr, *(pRstAttr+1) ); - pRstAttr += 2; - } + for( const WhichPair& rPair : aSave_BoxContentSet ) + pCNd->ResetAttr( rPair.first, rPair.second ); pCNd->SetAttr( *pSet ); } else @@ -1265,16 +1289,16 @@ void SaveBox::RestoreAttr( SwTableBox& rBox, SaveTable& rSTable ) void SaveBox::SaveContentAttrs( SwDoc* pDoc ) { - if( ULONG_MAX == nSttNode ) // no EndBox + if (NODE_OFFSET_MAX == m_nStartNode) // no EndBox { // continue in current line - Ptrs.pLine->SaveContentAttrs( pDoc ); + m_Ptrs.pLine->SaveContentAttrs(pDoc); } else { - sal_uLong nEnd = pDoc->GetNodes()[ nSttNode ]->EndOfSectionIndex(); - Ptrs.pContentAttrs = new SfxItemSets; - for( sal_uLong n = nSttNode + 1; n < nEnd; ++n ) + SwNodeOffset nEnd = pDoc->GetNodes()[m_nStartNode]->EndOfSectionIndex(); + m_Ptrs.pContentAttrs = new SfxItemSets; + for (SwNodeOffset n = m_nStartNode + 1; n < nEnd; ++n) { SwContentNode* pCNd = pDoc->GetNodes()[ n ]->GetContentNode(); if( pCNd ) @@ -1287,36 +1311,36 @@ void SaveBox::SaveContentAttrs( SwDoc* pDoc ) pSet->Put( *pCNd->GetpSwAttrSet() ); } - Ptrs.pContentAttrs->push_back( pSet ); + m_Ptrs.pContentAttrs->push_back(pSet); } } } - if( pNext ) - pNext->SaveContentAttrs( pDoc ); + if (m_pNext) + m_pNext->SaveContentAttrs(pDoc); } void SaveBox::CreateNew( SwTable& rTable, SwTableLine& rParent, SaveTable& rSTable ) { - SwTableBoxFormat* pFormat = static_cast<SwTableBoxFormat*>(rSTable.m_aFrameFormats[ nItemSet ]); + SwTableBoxFormat* pFormat = static_cast<SwTableBoxFormat*>(rSTable.m_aFrameFormats[m_nItemSet]); if( !pFormat ) { SwDoc* pDoc = rTable.GetFrameFormat()->GetDoc(); pFormat = pDoc->MakeTableBoxFormat(); - pFormat->SetFormatAttr(*rSTable.m_aSets[nItemSet]); - rSTable.m_aFrameFormats[nItemSet] = pFormat; + pFormat->SetFormatAttr(*rSTable.m_aSets[m_nItemSet]); + rSTable.m_aFrameFormats[m_nItemSet] = pFormat; } - if( ULONG_MAX == nSttNode ) // no EndBox + if (NODE_OFFSET_MAX == m_nStartNode) // no EndBox { SwTableBox* pNew = new SwTableBox( pFormat, 1, &rParent ); rParent.GetTabBoxes().push_back( pNew ); - Ptrs.pLine->CreateNew( rTable, *pNew, rSTable ); + m_Ptrs.pLine->CreateNew(rTable, *pNew, rSTable); } else { // search box for StartNode in old table - SwTableBox* pBox = rTable.GetTableBox( nSttNode ); + SwTableBox* pBox = rTable.GetTableBox(m_nStartNode); if (pBox) { SwFrameFormat* pOld = pBox->GetFrameFormat(); @@ -1324,7 +1348,7 @@ void SaveBox::CreateNew( SwTable& rTable, SwTableLine& rParent, SaveTable& rSTab if( !pOld->HasWriterListeners() ) delete pOld; - pBox->setRowSpan( nRowSpan ); + pBox->setRowSpan(m_nRowSpan); SwTableBoxes* pTBoxes = &pBox->GetUpper()->GetTabBoxes(); pTBoxes->erase( std::find( pTBoxes->begin(), pTBoxes->end(), pBox ) ); @@ -1335,8 +1359,8 @@ void SaveBox::CreateNew( SwTable& rTable, SwTableLine& rParent, SaveTable& rSTab } } - if( pNext ) - pNext->CreateNew( rTable, rParent, rSTable ); + if (m_pNext) + m_pNext->CreateNew(rTable, rParent, rSTable); } // UndoObject for attribute changes on table @@ -1491,7 +1515,7 @@ void SwUndoTableNdsChg::SaveNewBoxes( const SwTableNode& rTableNd, const SwTableSortBoxes& rTableBoxes = rTable.GetTabSortBoxes(); OSL_ENSURE( ! IsDelBox(), "wrong Action" ); - m_pNewSttNds.reset( new std::set<BoxMove> ); + m_xNewSttNds.emplace(); size_t i = 0; for (size_t n = 0; n < rOld.size(); ++i) @@ -1500,12 +1524,12 @@ void SwUndoTableNdsChg::SaveNewBoxes( const SwTableNode& rTableNd, ++n; else // new box: insert sorted - m_pNewSttNds->insert( BoxMove(rTableBoxes[ i ]->GetSttIdx()) ); + m_xNewSttNds->insert( BoxMove(rTableBoxes[ i ]->GetSttIdx()) ); } for( ; i < rTableBoxes.size(); ++i ) // new box: insert sorted - m_pNewSttNds->insert( BoxMove(rTableBoxes[ i ]->GetSttIdx()) ); + m_xNewSttNds->insert( BoxMove(rTableBoxes[ i ]->GetSttIdx()) ); } static SwTableLine* lcl_FindTableLine( const SwTable& rTable, @@ -1537,13 +1561,13 @@ static const SwTableLines& lcl_FindParentLines( const SwTable& rTable, void SwUndoTableNdsChg::SaveNewBoxes( const SwTableNode& rTableNd, const SwTableSortBoxes& rOld, const SwSelBoxes& rBoxes, - const std::vector<sal_uLong> &rNodeCnts ) + const std::vector<SwNodeOffset> &rNodeCnts ) { const SwTable& rTable = rTableNd.GetTable(); const SwTableSortBoxes& rTableBoxes = rTable.GetTabSortBoxes(); OSL_ENSURE( ! IsDelBox(), "wrong Action" ); - m_pNewSttNds.reset( new std::set<BoxMove> ); + m_xNewSttNds.emplace(); OSL_ENSURE( rTable.IsNewModel() || rOld.size() + m_nCount * rBoxes.size() == rTableBoxes.size(), "unexpected boxes" ); @@ -1595,7 +1619,7 @@ void SwUndoTableNdsChg::SaveNewBoxes( const SwTableNode& rTableNd, size_t nNdsPos = 0; while( rBoxes[ nNdsPos ] != pSourceBox ) ++nNdsPos; - sal_uLong nNodes = rNodeCnts[ nNdsPos ]; + SwNodeOffset nNodes = rNodeCnts[ nNdsPos ]; // When a new table cell is created, it either gets a new // node, or it gets node(s) from elsewhere. The undo must @@ -1609,8 +1633,8 @@ void SwUndoTableNdsChg::SaveNewBoxes( const SwTableNode& rTableNd, bool bNodesMoved = pSourceBox && ( nNodes != ( pSourceBox->GetSttNd()->EndOfSectionIndex() - pSourceBox->GetSttIdx() ) ) - && ( nNodes - 1 > nLineDiff ); - m_pNewSttNds->insert( BoxMove(pBox->GetSttIdx(), bNodesMoved) ); + && ( nNodes - 1 > SwNodeOffset(nLineDiff) ); + m_xNewSttNds->insert( BoxMove(pBox->GetSttIdx(), bNodesMoved) ); } } } @@ -1636,10 +1660,7 @@ void SwUndoTableNdsChg::UndoImpl(::sw::UndoRedoContext & rContext) SwTableNode *const pTableNd = aIdx.GetNode().GetTableNode(); OSL_ENSURE( pTableNd, "no TableNode" ); - - SwTableFormulaUpdate aMsgHint( &pTableNd->GetTable() ); - aMsgHint.m_eFlags = TBL_BOXPTR; - rDoc.getIDocumentFieldsAccess().UpdateTableFields( &aMsgHint ); + pTableNd->GetTable().SwitchFormulasToInternalRepresentation(); CHECK_TABLE( pTableNd->GetTable() ) @@ -1648,7 +1669,7 @@ void SwUndoTableNdsChg::UndoImpl(::sw::UndoRedoContext & rContext) SwChartDataProvider *pPCD = rDoc.getIDocumentChartDataProviderAccess().GetChartDataProvider(); SwSelBoxes aDelBoxes; - std::vector< std::pair<SwTableBox *, sal_uLong> > aDelNodes; + std::vector< std::pair<SwTableBox *, SwNodeOffset> > aDelNodes; if( IsDelBox() ) { // Trick: add missing boxes in any line, they will be connected @@ -1669,18 +1690,18 @@ void SwUndoTableNdsChg::UndoImpl(::sw::UndoRedoContext & rContext) } m_pDelSects->clear(); } - else if( !m_pNewSttNds->empty() ) + else if( !m_xNewSttNds->empty() ) { // Then the nodes have be moved and not deleted! // But for that we need a temp array. - std::vector<BoxMove> aTmp( m_pNewSttNds->begin(), m_pNewSttNds->end() ); + std::vector<BoxMove> aTmp( m_xNewSttNds->begin(), m_xNewSttNds->end() ); // backwards for (size_t n = aTmp.size(); n > 0 ; ) { --n; // delete box from table structure - sal_uLong nIdx = aTmp[n].index; + SwNodeOffset nIdx = aTmp[n].index; SwTableBox* pBox = pTableNd->GetTable().GetTableBox( nIdx ); OSL_ENSURE( pBox, "Where is my TableBox?" ); @@ -1694,7 +1715,7 @@ void SwUndoTableNdsChg::UndoImpl(::sw::UndoRedoContext & rContext) if( aTmp[n].hasMoved ) { - SwNodeRange aRg( *pBox->GetSttNd(), 1, + SwNodeRange aRg( *pBox->GetSttNd(), SwNodeOffset(1), *pBox->GetSttNd()->EndOfSectionNode() ); SwTableLine* pLine = lcl_FindTableLine( pTableNd->GetTable(), *pBox ); @@ -1702,7 +1723,7 @@ void SwUndoTableNdsChg::UndoImpl(::sw::UndoRedoContext & rContext) // adjust all StartNode indices size_t i = n; - sal_uLong nSttIdx = aInsPos.GetIndex() - 2, + SwNodeOffset nSttIdx = aInsPos.GetIndex() - 2, nNdCnt = aRg.aEnd.GetIndex() - aRg.aStart.GetIndex(); while( i && aTmp[ --i ].index > nSttIdx ) aTmp[ i ].index += nNdCnt; @@ -1710,7 +1731,7 @@ void SwUndoTableNdsChg::UndoImpl(::sw::UndoRedoContext & rContext) // first delete box delete pBox; // than move nodes - rDoc.GetNodes().MoveNodes( aRg, rDoc.GetNodes(), aInsPos, false ); + rDoc.GetNodes().MoveNodes( aRg, rDoc.GetNodes(), aInsPos.GetNode(), false ); } else { @@ -1722,9 +1743,9 @@ void SwUndoTableNdsChg::UndoImpl(::sw::UndoRedoContext & rContext) { // Remove nodes from nodes array (backwards!) std::set<BoxMove>::reverse_iterator it; - for( it = m_pNewSttNds->rbegin(); it != m_pNewSttNds->rend(); ++it ) + for( it = m_xNewSttNds->rbegin(); it != m_xNewSttNds->rend(); ++it ) { - sal_uLong nIdx = (*it).index; + SwNodeOffset nIdx = (*it).index; SwTableBox* pBox = pTableNd->GetTable().GetTableBox( nIdx ); OSL_ENSURE( pBox, "Where's my table box?" ); // TL_CHART2: notify chart about box to be removed @@ -1741,7 +1762,7 @@ void SwUndoTableNdsChg::UndoImpl(::sw::UndoRedoContext & rContext) // do this _after_ deleting Frames because disposing SwAccessible requires // connection to the nodes, see SwAccessibleChild::IsAccessible() - for (const std::pair<SwTableBox *, sal_uLong> & rDelNode : aDelNodes) + for (const std::pair<SwTableBox *, SwNodeOffset> & rDelNode : aDelNodes) { // first disconnect box from node, otherwise ~SwTableBox would // access pBox->pSttNd, deleted by DeleteSection @@ -1762,7 +1783,8 @@ void SwUndoTableNdsChg::UndoImpl(::sw::UndoRedoContext & rContext) // TL_CHART2: need to inform chart of probably changed cell names rDoc.UpdateCharts( pTableNd->GetTable().GetFrameFormat()->GetName() ); - + if (SwFEShell* pFEShell = rDoc.GetDocShell()->GetFEShell()) + pFEShell->UpdateTableStyleFormatting(pTableNd); if( IsDelBox() ) m_nSttNode = pTableNd->GetIndex(); ClearFEShellTabCols(rDoc, nullptr); @@ -1802,10 +1824,8 @@ void SwUndoTableNdsChg::RedoImpl(::sw::UndoRedoContext & rContext) case SwUndoId::ROW_DELETE: case SwUndoId::COL_DELETE: { - SwTableFormulaUpdate aMsgHint( &pTableNd->GetTable() ); - aMsgHint.m_eFlags = TBL_BOXPTR; - rDoc.getIDocumentFieldsAccess().UpdateTableFields( &aMsgHint ); SwTable &rTable = pTableNd->GetTable(); + rTable.SwitchFormulasToInternalRepresentation(); if( m_nMax > m_nMin && rTable.IsNewModel() ) rTable.PrepareDeleteCol( m_nMin, m_nMax ); rTable.DeleteSel( &rDoc, aSelBoxes, nullptr, this, true, true ); @@ -1822,7 +1842,7 @@ void SwUndoTableNdsChg::RedoImpl(::sw::UndoRedoContext & rContext) SwUndoTableMerge::SwUndoTableMerge( const SwPaM& rTableSel ) : SwUndo( SwUndoId::TABLE_MERGE, &rTableSel.GetDoc() ), SwUndRng( rTableSel ) { - const SwTableNode* pTableNd = rTableSel.GetNode().FindTableNode(); + const SwTableNode* pTableNd = rTableSel.GetPointNode().FindTableNode(); OSL_ENSURE( pTableNd, "Where is the TableNode?" ); m_pSaveTable.reset( new SaveTable( pTableNd->GetTable() ) ); m_nTableNode = pTableNd->GetIndex(); @@ -1843,9 +1863,7 @@ void SwUndoTableMerge::UndoImpl(::sw::UndoRedoContext & rContext) SwTableNode *const pTableNd = aIdx.GetNode().GetTableNode(); OSL_ENSURE( pTableNd, "no TableNode" ); - SwTableFormulaUpdate aMsgHint( &pTableNd->GetTable() ); - aMsgHint.m_eFlags = TBL_BOXPTR; - rDoc.getIDocumentFieldsAccess().UpdateTableFields( &aMsgHint ); + pTableNd->GetTable().SwitchFormulasToInternalRepresentation(); // ? TL_CHART2: notification or locking of controller required ? @@ -1863,7 +1881,7 @@ void SwUndoTableMerge::UndoImpl(::sw::UndoRedoContext & rContext) for (const auto& rBox : m_Boxes) { aIdx = rBox; - SwStartNode* pSttNd = rDoc.GetNodes().MakeTextSection( aIdx, + SwStartNode* pSttNd = rDoc.GetNodes().MakeTextSection( aIdx.GetNode(), SwTableBoxStartNode, pColl ); pBox = new SwTableBox( static_cast<SwTableBoxFormat*>(pCpyBox->GetFrameFormat()), *pSttNd, pCpyBox->GetUpper() ); @@ -1880,7 +1898,7 @@ void SwUndoTableMerge::UndoImpl(::sw::UndoRedoContext & rContext) for( size_t n = m_aNewStartNodes.size(); n; ) { // remove box from table structure - sal_uLong nIdx = m_aNewStartNodes[ --n ]; + SwNodeOffset nIdx = m_aNewStartNodes[ --n ]; if( !nIdx && n ) { @@ -1889,8 +1907,8 @@ void SwUndoTableMerge::UndoImpl(::sw::UndoRedoContext & rContext) OSL_ENSURE( pBox, "Where is my TableBox?" ); if( !m_pSaveTable->IsNewModel() ) - rDoc.GetNodes().MakeTextNode( SwNodeIndex( - *pBox->GetSttNd()->EndOfSectionNode() ), pColl ); + rDoc.GetNodes().MakeTextNode( + const_cast<SwEndNode&>(*pBox->GetSttNd()->EndOfSectionNode()), pColl ); // this was the separator -> restore moved ones for (size_t i = m_vMoves.size(); i; ) @@ -1921,9 +1939,9 @@ void SwUndoTableMerge::UndoImpl(::sw::UndoRedoContext & rContext) else if( pTextNd ) { // also delete not needed attributes - SwIndex aTmpIdx( pTextNd, nDelPos ); + SwContentIndex aTmpIdx( pTextNd, nDelPos ); if( pTextNd->GetpSwpHints() && pTextNd->GetpSwpHints()->Count() ) - pTextNd->RstTextAttr( aTmpIdx, pTextNd->GetText().getLength() - nDelPos + 1 ); + pTextNd->RstTextAttr( nDelPos, pTextNd->GetText().getLength() - nDelPos + 1 ); // delete separator pTextNd->EraseText( aTmpIdx, 1 ); } @@ -1947,7 +1965,7 @@ void SwUndoTableMerge::UndoImpl(::sw::UndoRedoContext & rContext) SwNodeIndex aTmpIdx( *pBox->GetSttNd() ); SwDoc::CorrAbs( SwNodeIndex( aTmpIdx, 1 ), SwNodeIndex( *aTmpIdx.GetNode().EndOfSectionNode() ), - SwPosition( aTmpIdx, SwIndex( nullptr, 0 )), true ); + SwPosition( aTmpIdx, nullptr, 0 ), true ); } delete pBox; @@ -1968,8 +1986,7 @@ void SwUndoTableMerge::UndoImpl(::sw::UndoRedoContext & rContext) } SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor()); pPam->DeleteMark(); - pPam->GetPoint()->nNode = m_nSttNode; - pPam->GetPoint()->nContent.Assign( pPam->GetContentNode(), m_nSttContent ); + pPam->GetPoint()->Assign(m_nSttNode, m_nSttContent ); pPam->SetMark(); pPam->DeleteMark(); @@ -1984,7 +2001,7 @@ void SwUndoTableMerge::RedoImpl(::sw::UndoRedoContext & rContext) rDoc.MergeTable(rPam); } -void SwUndoTableMerge::MoveBoxContent( SwDoc& rDoc, SwNodeRange& rRg, SwNodeIndex& rPos ) +void SwUndoTableMerge::MoveBoxContent( SwDoc& rDoc, SwNodeRange& rRg, SwNode& rPos ) { SwNodeIndex aTmp( rRg.aStart, -1 ), aTmp2( rPos, -1 ); std::unique_ptr<SwUndoMove> pUndo(new SwUndoMove( rDoc, rRg, rPos )); @@ -1994,7 +2011,7 @@ void SwUndoTableMerge::MoveBoxContent( SwDoc& rDoc, SwNodeRange& rRg, SwNodeInde SwMoveFlags::DEFAULT ); ++aTmp; ++aTmp2; - pUndo->SetDestRange( aTmp2, rPos, aTmp ); + pUndo->SetDestRange( aTmp2.GetNode(), rPos, aTmp ); m_vMoves.push_back(std::move(pUndo)); } @@ -2008,7 +2025,7 @@ void SwUndoTableMerge::SetSelBoxes( const SwSelBoxes& rBoxes ) } // as separator for inserts of new boxes after shifting - m_aNewStartNodes.push_back( sal_uLong(0) ); + m_aNewStartNodes.push_back( SwNodeOffset(0) ); // The new table model does not delete overlapped cells (by row span), // so the rBoxes array might be empty even some cells have been merged. @@ -2024,9 +2041,9 @@ void SwUndoTableMerge::SaveCollection( const SwTableBox& rBox ) SwNodeIndex aIdx( *rBox.GetSttNd(), 1 ); SwContentNode* pCNd = aIdx.GetNode().GetContentNode(); if( !pCNd ) - pCNd = aIdx.GetNodes().GoNext( &aIdx ); + pCNd = SwNodes::GoNext(&aIdx); - m_pHistory->Add( pCNd->GetFormatColl(), aIdx.GetIndex(), pCNd->GetNodeType()); + m_pHistory->AddColl(pCNd->GetFormatColl(), aIdx.GetIndex(), pCNd->GetNodeType()); if( pCNd->HasSwAttrSet() ) m_pHistory->CopyFormatAttr( *pCNd->GetpSwAttrSet(), aIdx.GetIndex() ); } @@ -2047,13 +2064,13 @@ SwUndoTableNumFormat::SwUndoTableNumFormat( const SwTableBox& rBox, m_nNodePos = rBox.IsValidNumTextNd( nullptr == pNewSet ); SwDoc* pDoc = rBox.GetFrameFormat()->GetDoc(); - if( ULONG_MAX != m_nNodePos ) + if( NODE_OFFSET_MAX != m_nNodePos ) { SwTextNode* pTNd = pDoc->GetNodes()[ m_nNodePos ]->GetTextNode(); m_pHistory.reset(new SwHistory); SwRegHistory aRHst( *rBox.GetSttNd(), m_pHistory.get() ); - // always save all text atttibutes because of possibly overlapping + // always save all text attributes because of possibly overlapping // areas of on/off m_pHistory->CopyAttr( pTNd->GetpSwpHints(), m_nNodePos, 0, pTNd->GetText().getLength(), true ); @@ -2071,24 +2088,23 @@ SwUndoTableNumFormat::SwUndoTableNumFormat( const SwTableBox& rBox, if( pNewSet ) { - const SfxPoolItem* pItem; - if( SfxItemState::SET == pNewSet->GetItemState( RES_BOXATR_FORMAT, - false, &pItem )) + if( const SwTableBoxNumFormat* pItem = pNewSet->GetItemIfSet( RES_BOXATR_FORMAT, + false )) { m_bNewFormat = true; - m_nNewFormatIdx = static_cast<const SwTableBoxNumFormat*>(pItem)->GetValue(); + m_nNewFormatIdx = pItem->GetValue(); } - if( SfxItemState::SET == pNewSet->GetItemState( RES_BOXATR_FORMULA, - false, &pItem )) + if( const SwTableBoxFormula* pItem = pNewSet->GetItemIfSet( RES_BOXATR_FORMULA, + false )) { m_bNewFormula = true; - m_aNewFormula = static_cast<const SwTableBoxFormula*>(pItem)->GetFormula(); + m_aNewFormula = pItem->GetFormula(); } - if( SfxItemState::SET == pNewSet->GetItemState( RES_BOXATR_VALUE, - false, &pItem )) + if( const SwTableBoxValue* pItem = pNewSet->GetItemIfSet( RES_BOXATR_VALUE, + false )) { m_bNewValue = true; - m_fNewNum = static_cast<const SwTableBoxValue*>(pItem)->GetValue(); + m_fNewNum = pItem->GetValue(); } } @@ -2121,7 +2137,7 @@ void SwUndoTableNumFormat::UndoImpl(::sw::UndoRedoContext & rContext) pFormat->SetFormatAttr( *m_pBoxSet ); pBox->ChgFrameFormat( pFormat ); - if( ULONG_MAX == m_nNodePos ) + if( NODE_OFFSET_MAX == m_nNodePos ) return; SwTextNode* pTextNd = rDoc.GetNodes()[ m_nNodePos ]->GetTextNode(); @@ -2139,7 +2155,7 @@ void SwUndoTableNumFormat::UndoImpl(::sw::UndoRedoContext & rContext) { rDoc.getIDocumentRedlineAccess().DeleteRedline( *( pBox->GetSttNd() ), false, RedlineType::Any ); - SwIndex aIdx( pTextNd, 0 ); + SwContentIndex aIdx( pTextNd, 0 ); if( !m_aStr.isEmpty() ) { pTextNd->EraseText( aIdx ); @@ -2157,8 +2173,7 @@ void SwUndoTableNumFormat::UndoImpl(::sw::UndoRedoContext & rContext) SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor()); pPam->DeleteMark(); - pPam->GetPoint()->nNode = m_nNode + 1; - pPam->GetPoint()->nContent.Assign( pTextNd, 0 ); + pPam->GetPoint()->Assign( m_nNode + 1 ); } namespace { @@ -2210,9 +2225,9 @@ void SwUndoTableNumFormat::RedoImpl(::sw::UndoRedoContext & rContext) SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor()); pPam->DeleteMark(); - pPam->GetPoint()->nNode = m_nNode; + pPam->GetPoint()->Assign( m_nNode ); - SwNode * pNd = & pPam->GetPoint()->nNode.GetNode(); + SwNode * pNd = & pPam->GetPoint()->GetNode(); SwStartNode* pSttNd = pNd->FindSttNodeByType( SwTableBoxStartNode ); assert(pSttNd && "without StartNode no TableBox"); SwTableBox* pBox = pSttNd->FindTableNode()->GetTable().GetTableBox( @@ -2222,8 +2237,7 @@ void SwUndoTableNumFormat::RedoImpl(::sw::UndoRedoContext & rContext) SwFrameFormat* pBoxFormat = pBox->ClaimFrameFormat(); if( m_bNewFormat || m_bNewFormula || m_bNewValue ) { - SfxItemSet aBoxSet( rDoc.GetAttrPool(), - svl::Items<RES_BOXATR_FORMAT, RES_BOXATR_VALUE>{} ); + SfxItemSetFixed<RES_BOXATR_FORMAT, RES_BOXATR_VALUE> aBoxSet( rDoc.GetAttrPool() ); // Resetting attributes is not enough. In addition, take care that the // text will be also formatted correctly. @@ -2251,8 +2265,7 @@ void SwUndoTableNumFormat::RedoImpl(::sw::UndoRedoContext & rContext) } else if( getSwDefaultTextFormat() != m_nFormatIdx ) { - SfxItemSet aBoxSet( rDoc.GetAttrPool(), - svl::Items<RES_BOXATR_FORMAT, RES_BOXATR_VALUE>{} ); + SfxItemSetFixed<RES_BOXATR_FORMAT, RES_BOXATR_VALUE> aBoxSet( rDoc.GetAttrPool() ); aBoxSet.Put( SwTableBoxNumFormat( m_nFormatIdx )); aBoxSet.Put( SwTableBoxValue( m_fNum )); @@ -2283,13 +2296,11 @@ void SwUndoTableNumFormat::RedoImpl(::sw::UndoRedoContext & rContext) if( m_bNewFormula ) { // No matter what was set, an update of the table is always a good idea - SwTableFormulaUpdate aTableUpdate( &pSttNd->FindTableNode()->GetTable() ); - rDoc.getIDocumentFieldsAccess().UpdateTableFields( &aTableUpdate ); + rDoc.getIDocumentFieldsAccess().UpdateTableFields(&pSttNd->FindTableNode()->GetTable()); } if( !pNd->IsContentNode() ) - pNd = rDoc.GetNodes().GoNext( &pPam->GetPoint()->nNode ); - pPam->GetPoint()->nContent.Assign( static_cast<SwContentNode*>(pNd), 0 ); + pNd = SwNodes::GoNext(pPam->GetPoint()); } void SwUndoTableNumFormat::SetBox( const SwTableBox& rBox ) @@ -2303,6 +2314,42 @@ UndoTableCpyTable_Entry::UndoTableCpyTable_Entry( const SwTableBox& rBox ) { } +void UndoTableCpyTable_Entry::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("UndoTableCpyTable_Entry")); + + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("nBoxIdx")); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), + BAD_CAST(OString::number(sal_Int32(nBoxIdx)).getStr())); + (void)xmlTextWriterEndElement(pWriter); + + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("nOffset")); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), + BAD_CAST(OString::number(sal_Int32(nOffset)).getStr())); + (void)xmlTextWriterEndElement(pWriter); + + if (pBoxNumAttr) + { + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("pBoxNumAttr")); + pBoxNumAttr->dumpAsXml(pWriter); + (void)xmlTextWriterEndElement(pWriter); + } + + if (pUndo) + { + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("pUndo")); + pUndo->dumpAsXml(pWriter); + (void)xmlTextWriterEndElement(pWriter); + } + + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("bJoin")); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), + BAD_CAST(OString::boolean(bJoin).getStr())); + (void)xmlTextWriterEndElement(pWriter); + + (void)xmlTextWriterEndElement(pWriter); +} + SwUndoTableCpyTable::SwUndoTableCpyTable(const SwDoc& rDoc) : SwUndo( SwUndoId::TBLCPYTBL, &rDoc ) { @@ -2323,15 +2370,23 @@ void SwUndoTableCpyTable::UndoImpl(::sw::UndoRedoContext & rContext) for (size_t n = m_vArr.size(); n; ) { UndoTableCpyTable_Entry *const pEntry = m_vArr[ --n ].get(); - sal_uLong nSttPos = pEntry->nBoxIdx + pEntry->nOffset; + SwNodeOffset nSttPos = pEntry->nBoxIdx + pEntry->nOffset; SwStartNode* pSNd = rDoc.GetNodes()[ nSttPos ]->StartOfSectionNode(); if( !pTableNd ) pTableNd = pSNd->FindTableNode(); - SwTableBox& rBox = *pTableNd->GetTable().GetTableBox( nSttPos ); + SwTableBox* pBox = pTableNd->GetTable().GetTableBox( nSttPos ); + if (!pBox) + { + SAL_WARN("sw.core", + "SwUndoTableCpyTable::UndoImpl: invalid start node index for table box"); + continue; + } + + SwTableBox& rBox = *pBox; SwNodeIndex aInsIdx( *rBox.GetSttNd(), 1 ); - rDoc.GetNodes().MakeTextNode( aInsIdx, rDoc.GetDfltTextFormatColl() ); + rDoc.GetNodes().MakeTextNode( aInsIdx.GetNode(), rDoc.GetDfltTextFormatColl() ); // b62341295: Redline for copying tables const SwNode *pEndNode = rBox.GetSttNd()->EndOfSectionNode(); @@ -2360,12 +2415,11 @@ void SwUndoTableCpyTable::UndoImpl(::sw::UndoRedoContext & rContext) SwTextNode *pText = aTmpIdx.GetNode().GetTextNode(); if( pText ) { - aPam.GetPoint()->nNode = *pText; - aPam.GetPoint()->nContent.Assign( pText, + aPam.GetPoint()->Assign(*pText, pUndoRedlineDelete->ContentStart() ); } else - *aPam.GetPoint() = SwPosition( aTmpIdx ); + aPam.GetPoint()->Assign( aTmpIdx ); } else if (pUndoDelete && pUndoDelete->IsDelFullPara()) { @@ -2376,15 +2430,7 @@ void SwUndoTableCpyTable::UndoImpl(::sw::UndoRedoContext & rContext) // for step forward later on. bDeleteCompleteParagraph = true; bShiftPam = true; - SwNodeIndex aTmpIdx( *pEndNode, -1 ); - SwTextNode *pText = aTmpIdx.GetNode().GetTextNode(); - if( pText ) - { - aPam.GetPoint()->nNode = *pText; - aPam.GetPoint()->nContent.Assign( pText, 0 ); - } - else - *aPam.GetPoint() = SwPosition( aTmpIdx ); + aPam.GetPoint()->Assign(*pEndNode, SwNodeOffset(-1)); } } rDoc.getIDocumentRedlineAccess().DeleteRedline( aPam, true, RedlineType::Any ); @@ -2398,21 +2444,13 @@ void SwUndoTableCpyTable::UndoImpl(::sw::UndoRedoContext & rContext) { // The aPam.Point is at the moment at the last position of the new content and has to be // moved to the first position of the old content for the SwUndoDelete operation - SwNodeIndex aTmpIdx( aPam.GetPoint()->nNode, 1 ); - SwTextNode *pText = aTmpIdx.GetNode().GetTextNode(); - if( pText ) - { - aPam.GetPoint()->nNode = *pText; - aPam.GetPoint()->nContent.Assign( pText, 0 ); - } - else - *aPam.GetPoint() = SwPosition( aTmpIdx ); + aPam.GetPoint()->Assign(aPam.GetPoint()->GetNode(), SwNodeOffset(1)); } - pUndo = std::make_unique<SwUndoDelete>( aPam, bDeleteCompleteParagraph, true ); + pUndo = std::make_unique<SwUndoDelete>(aPam, SwDeleteFlags::Default, bDeleteCompleteParagraph, true); } else { - pUndo = std::make_unique<SwUndoDelete>( aPam, true ); + pUndo = std::make_unique<SwUndoDelete>(aPam, SwDeleteFlags::Default, true); if( pEntry->pUndo ) { pEntry->pUndo->UndoImpl(rContext); @@ -2424,11 +2462,10 @@ void SwUndoTableCpyTable::UndoImpl(::sw::UndoRedoContext & rContext) aInsIdx = rBox.GetSttIdx() + 1; rDoc.GetNodes().Delete( aInsIdx ); - SfxItemSet aTmpSet( - rDoc.GetAttrPool(), - svl::Items< + SfxItemSetFixed< RES_VERT_ORIENT, RES_VERT_ORIENT, - RES_BOXATR_FORMAT, RES_BOXATR_VALUE>{}); + RES_BOXATR_FORMAT, RES_BOXATR_VALUE> + aTmpSet(rDoc.GetAttrPool()); aTmpSet.Put( rBox.GetFrameFormat()->GetAttrSet() ); if( aTmpSet.Count() ) { @@ -2445,11 +2482,9 @@ void SwUndoTableCpyTable::UndoImpl(::sw::UndoRedoContext & rContext) if( aTmpSet.Count() ) { - pEntry->pBoxNumAttr = std::make_unique<SfxItemSet>( - rDoc.GetAttrPool(), - svl::Items< + pEntry->pBoxNumAttr = std::make_unique<SfxItemSetFixed< RES_VERT_ORIENT, RES_VERT_ORIENT, - RES_BOXATR_FORMAT, RES_BOXATR_VALUE>{}); + RES_BOXATR_FORMAT, RES_BOXATR_VALUE>>(rDoc.GetAttrPool()); pEntry->pBoxNumAttr->Put( aTmpSet ); } @@ -2477,7 +2512,7 @@ void SwUndoTableCpyTable::RedoImpl(::sw::UndoRedoContext & rContext) for (size_t n = 0; n < m_vArr.size(); ++n) { UndoTableCpyTable_Entry *const pEntry = m_vArr[ n ].get(); - sal_uLong nSttPos = pEntry->nBoxIdx + pEntry->nOffset; + SwNodeOffset nSttPos = pEntry->nBoxIdx + pEntry->nOffset; SwStartNode* pSNd = rDoc.GetNodes()[ nSttPos ]->StartOfSectionNode(); if( !pTableNd ) pTableNd = pSNd->FindTableNode(); @@ -2487,9 +2522,11 @@ void SwUndoTableCpyTable::RedoImpl(::sw::UndoRedoContext & rContext) SwNodeIndex aInsIdx( *rBox.GetSttNd(), 1 ); // b62341295: Redline for copying tables - Start. - rDoc.GetNodes().MakeTextNode( aInsIdx, rDoc.GetDfltTextFormatColl() ); + rDoc.GetNodes().MakeTextNode( aInsIdx.GetNode(), rDoc.GetDfltTextFormatColl() ); SwPaM aPam( aInsIdx.GetNode(), *rBox.GetSttNd()->EndOfSectionNode()); - std::unique_ptr<SwUndo> pUndo = IDocumentRedlineAccess::IsRedlineOn( GetRedlineFlags() ) ? nullptr : std::make_unique<SwUndoDelete>( aPam, true ); + std::unique_ptr<SwUndo> pUndo(IDocumentRedlineAccess::IsRedlineOn(GetRedlineFlags()) + ? nullptr + : std::make_unique<SwUndoDelete>(aPam, SwDeleteFlags::Default, true)); if( pEntry->pUndo ) { pEntry->pUndo->UndoImpl(rContext); @@ -2501,7 +2538,7 @@ void SwUndoTableCpyTable::RedoImpl(::sw::UndoRedoContext & rContext) // Otherwise aInsIdx has been moved during the Undo operation if( pEntry->bJoin ) { - SwPaM const& rLastPam = + SwPaM& rLastPam = rContext.GetCursorSupplier().GetCurrentShellCursor(); pUndo = PrepareRedline( &rDoc, rBox, *rLastPam.GetPoint(), pEntry->bJoin, true ); @@ -2520,11 +2557,9 @@ void SwUndoTableCpyTable::RedoImpl(::sw::UndoRedoContext & rContext) aInsIdx = rBox.GetSttIdx() + 1; rDoc.GetNodes().Delete( aInsIdx ); - SfxItemSet aTmpSet( - rDoc.GetAttrPool(), - svl::Items< + SfxItemSetFixed< RES_VERT_ORIENT, RES_VERT_ORIENT, - RES_BOXATR_FORMAT, RES_BOXATR_VALUE>{}); + RES_BOXATR_FORMAT, RES_BOXATR_VALUE> aTmpSet(rDoc.GetAttrPool()); aTmpSet.Put( rBox.GetFrameFormat()->GetAttrSet() ); if( aTmpSet.Count() ) { @@ -2540,11 +2575,9 @@ void SwUndoTableCpyTable::RedoImpl(::sw::UndoRedoContext & rContext) if( aTmpSet.Count() ) { - pEntry->pBoxNumAttr = std::make_unique<SfxItemSet>( - rDoc.GetAttrPool(), - svl::Items< + pEntry->pBoxNumAttr = std::make_unique<SfxItemSetFixed< RES_VERT_ORIENT, RES_VERT_ORIENT, - RES_BOXATR_FORMAT, RES_BOXATR_VALUE>{}); + RES_BOXATR_FORMAT, RES_BOXATR_VALUE>>(rDoc.GetAttrPool()); pEntry->pBoxNumAttr->Put( aTmpSet ); } @@ -2566,18 +2599,22 @@ void SwUndoTableCpyTable::AddBoxBefore( const SwTableBox& rBox, bool bDelContent if( bDelContent ) { SwNodeIndex aInsIdx( *rBox.GetSttNd(), 1 ); - pDoc->GetNodes().MakeTextNode( aInsIdx, pDoc->GetDfltTextFormatColl() ); + SwTextNode *const pNewNode(pDoc->GetNodes().MakeTextNode(aInsIdx.GetNode(), pDoc->GetDfltTextFormatColl())); SwPaM aPam( aInsIdx.GetNode(), *rBox.GetSttNd()->EndOfSectionNode() ); if( !pDoc->getIDocumentRedlineAccess().IsRedlineOn() ) - pEntry->pUndo = std::make_unique<SwUndoDelete>( aPam, true ); + { + { // move cursors to new node which precedes aPam + SwPosition const pos(*pNewNode, 0); + ::PaMCorrAbs(aPam, pos); + } + pEntry->pUndo = std::make_unique<SwUndoDelete>(aPam, SwDeleteFlags::Default, true); + } } - pEntry->pBoxNumAttr = std::make_unique<SfxItemSet>( - pDoc->GetAttrPool(), - svl::Items< + pEntry->pBoxNumAttr = std::make_unique<SfxItemSetFixed< RES_VERT_ORIENT, RES_VERT_ORIENT, - RES_BOXATR_FORMAT, RES_BOXATR_VALUE>{}); + RES_BOXATR_FORMAT, RES_BOXATR_VALUE>>(pDoc->GetAttrPool()); pEntry->pBoxNumAttr->Put( rBox.GetFrameFormat()->GetAttrSet() ); if( !pEntry->pBoxNumAttr->Count() ) { @@ -2596,6 +2633,13 @@ void SwUndoTableCpyTable::AddBoxAfter( const SwTableBox& rBox, const SwNodeIndex SwDoc* pDoc = rBox.GetFrameFormat()->GetDoc(); DEBUG_REDLINE( pDoc ) + { // move cursors to first node which was inserted + SwPaM pam(SwNodeIndex(*rBox.GetSttNd(), 1)); + assert(pam.GetPoint()->GetNode().IsTextNode()); + pam.SetMark(); + pam.Move(fnMoveForward, GoInContent); + ::PaMCorrAbs(pam, *pam.GetPoint()); + } if( pDoc->getIDocumentRedlineAccess().IsRedlineOn() ) { SwPosition aTmpPos( rIdx ); @@ -2616,7 +2660,7 @@ void SwUndoTableCpyTable::AddBoxAfter( const SwTableBox& rBox, const SwNodeIndex // rJoin is true if Redo() is calling and the content has already been merged std::unique_ptr<SwUndo> SwUndoTableCpyTable::PrepareRedline( SwDoc* pDoc, const SwTableBox& rBox, - const SwPosition& rPos, bool& rJoin, bool bRedo ) + SwPosition& rPos, bool& rJoin, bool bRedo ) { std::unique_ptr<SwUndo> pUndo; // b62341295: Redline for copying tables @@ -2632,14 +2676,18 @@ std::unique_ptr<SwUndo> SwUndoTableCpyTable::PrepareRedline( SwDoc* pDoc, const { // If the content is not merged, the end of the insertion is at the end of the node // _before_ the given position rPos - --aInsertEnd.nNode; - pText = aInsertEnd.nNode.GetNode().GetTextNode(); + aInsertEnd.Adjust(SwNodeOffset(-1)); + pText = aInsertEnd.GetNode().GetTextNode(); if( pText ) { - aInsertEnd.nContent.Assign(pText, pText->GetText().getLength()); - if( !bRedo && rPos.nNode.GetNode().GetTextNode() ) + aInsertEnd.SetContent(pText->GetText().getLength()); + if( !bRedo && rPos.GetNode().GetTextNode() ) { // Try to merge, if not called by Redo() rJoin = true; + + // Park this somewhere else so nothing points to the to-be-deleted node. + rPos.nContent.Assign(pText, 0); + pText->JoinNext(); } } @@ -2651,14 +2699,14 @@ std::unique_ptr<SwUndo> SwUndoTableCpyTable::PrepareRedline( SwDoc* pDoc, const SwPosition aDeleteStart( rJoin ? aInsertEnd : rPos ); if( !rJoin ) { - pText = aDeleteStart.nNode.GetNode().GetTextNode(); + pText = aDeleteStart.GetNode().GetTextNode(); if( pText ) - aDeleteStart.nContent.Assign( pText, 0 ); + aDeleteStart.SetContent( 0 ); } - SwPosition aCellEnd( SwNodeIndex( *rBox.GetSttNd()->EndOfSectionNode(), -1 ) ); - pText = aCellEnd.nNode.GetNode().GetTextNode(); + SwPosition aCellEnd( *rBox.GetSttNd()->EndOfSectionNode(), SwNodeOffset(-1) ); + pText = aCellEnd.GetNode().GetTextNode(); if( pText ) - aCellEnd.nContent.Assign(pText, pText->GetText().getLength()); + aCellEnd.SetContent(pText->GetText().getLength()); if( aDeleteStart != aCellEnd ) { // If the old (deleted) part is not empty, here we are... SwPaM aDeletePam( aDeleteStart, aCellEnd ); @@ -2667,15 +2715,14 @@ std::unique_ptr<SwUndo> SwUndoTableCpyTable::PrepareRedline( SwDoc* pDoc, const } else if( !rJoin ) // If the old part is empty and joined, we are finished { // if it is not joined, we have to delete this empty paragraph - aCellEnd = SwPosition( - SwNodeIndex( *rBox.GetSttNd()->EndOfSectionNode() )); + aCellEnd.Assign(*rBox.GetSttNd()->EndOfSectionNode()); SwPaM aTmpPam( aDeleteStart, aCellEnd ); - pUndo = std::make_unique<SwUndoDelete>( aTmpPam, true ); + pUndo = std::make_unique<SwUndoDelete>(aTmpPam, SwDeleteFlags::Default, true); } - SwPosition aCellStart( SwNodeIndex( *rBox.GetSttNd(), 2 ) ); - pText = aCellStart.nNode.GetNode().GetTextNode(); + SwPosition aCellStart( *rBox.GetSttNd(), SwNodeOffset(2) ); + pText = aCellStart.GetNode().GetTextNode(); if( pText ) - aCellStart.nContent.Assign( pText, 0 ); + aCellStart.SetContent( 0 ); if( aCellStart != aInsertEnd ) // An empty insertion will not been marked { SwPaM aTmpPam( aCellStart, aInsertEnd ); @@ -2706,6 +2753,23 @@ bool SwUndoTableCpyTable::InsertRow( SwTable& rTable, const SwSelBoxes& rBoxes, return bRet; } +void SwUndoTableCpyTable::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwUndoTableCpyTable")); + + for (const auto& pEntry : m_vArr) + { + pEntry->dumpAsXml(pWriter); + } + + if (m_pInsRowUndo) + { + m_pInsRowUndo->dumpAsXml(pWriter); + } + + (void)xmlTextWriterEndElement(pWriter); +} + bool SwUndoTableCpyTable::IsEmpty() const { return !m_pInsRowUndo && m_vArr.empty(); @@ -2730,19 +2794,18 @@ void SwUndoCpyTable::UndoImpl(::sw::UndoRedoContext & rContext) if( pNextNd ) { SwFrameFormat* pTableFormat = pTNd->GetTable().GetFrameFormat(); - const SfxPoolItem *pItem; - if( SfxItemState::SET == pTableFormat->GetItemState( RES_PAGEDESC, - false, &pItem ) ) + if( const SwFormatPageDesc* pItem = pTableFormat->GetItemIfSet( RES_PAGEDESC, + false ) ) pNextNd->SetAttr( *pItem ); - if( SfxItemState::SET == pTableFormat->GetItemState( RES_BREAK, - false, &pItem ) ) + if( const SvxFormatBreakItem* pItem = pTableFormat->GetItemIfSet( RES_BREAK, + false ) ) pNextNd->SetAttr( *pItem ); } - SwPaM aPam( *pTNd, *pTNd->EndOfSectionNode(), 0 , 1 ); - m_pDelete.reset( new SwUndoDelete( aPam, true ) ); + SwPaM aPam( *pTNd, *pTNd->EndOfSectionNode(), SwNodeOffset(0) , SwNodeOffset(1) ); + m_pDelete.reset(new SwUndoDelete(aPam, SwDeleteFlags::Default, true)); } void SwUndoCpyTable::RedoImpl(::sw::UndoRedoContext & rContext) @@ -2782,13 +2845,12 @@ void SwUndoSplitTable::UndoImpl(::sw::UndoRedoContext & rContext) SwDoc *const pDoc = & rContext.GetDoc(); SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor()); - SwNodeIndex& rIdx = pPam->GetPoint()->nNode; - rIdx = m_nTableNode + m_nOffset; - pPam->GetPoint()->nContent.Assign(rIdx.GetNode().GetContentNode(), 0); - assert(rIdx.GetNode().GetContentNode()->Len() == 0); // empty para inserted + SwPosition& rPtPos = *pPam->GetPoint(); + rPtPos.Assign( m_nTableNode + m_nOffset ); + assert(rPtPos.GetNode().GetContentNode()->Len() == 0); // empty para inserted { - // avoid asserts from ~SwIndexReg + // avoid asserts from ~SwContentIndexReg SwNodeIndex const idx(pDoc->GetNodes(), m_nTableNode + m_nOffset); { SwPaM pam(idx); @@ -2800,13 +2862,10 @@ void SwUndoSplitTable::UndoImpl(::sw::UndoRedoContext & rContext) pDoc->GetNodes().Delete( idx ); } - rIdx = m_nTableNode + m_nOffset; - SwTableNode* pTableNd = rIdx.GetNode().GetTableNode(); + rPtPos.Assign( m_nTableNode + m_nOffset ); + SwTableNode* pTableNd = rPtPos.GetNode().GetTableNode(); SwTable& rTable = pTableNd->GetTable(); - - SwTableFormulaUpdate aMsgHint( &rTable ); - aMsgHint.m_eFlags = TBL_BOXPTR; - pDoc->getIDocumentFieldsAccess().UpdateTableFields( &aMsgHint ); + rTable.SwitchFormulasToInternalRepresentation(); switch( m_nMode ) { @@ -2837,7 +2896,7 @@ void SwUndoSplitTable::UndoImpl(::sw::UndoRedoContext & rContext) default: break; } - pDoc->GetNodes().MergeTable( rIdx ); + pDoc->GetNodes().MergeTable( rPtPos.GetNode() ); if( m_pHistory ) { @@ -2846,7 +2905,7 @@ void SwUndoSplitTable::UndoImpl(::sw::UndoRedoContext & rContext) } if( mpSaveRowSpan ) { - pTableNd = rIdx.GetNode().FindTableNode(); + pTableNd = rPtPos.GetNode().FindTableNode(); if( pTableNd ) pTableNd->GetTable().RestoreRowSpan( *mpSaveRowSpan ); } @@ -2859,7 +2918,7 @@ void SwUndoSplitTable::RedoImpl(::sw::UndoRedoContext & rContext) SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor()); pPam->DeleteMark(); - pPam->GetPoint()->nNode = m_nTableNode; + pPam->GetPoint()->Assign( m_nTableNode ); pDoc->SplitTable( *pPam->GetPoint(), m_nMode, m_bCalcNewSize ); ClearFEShellTabCols(*pDoc, nullptr); @@ -2885,9 +2944,9 @@ void SwUndoSplitTable::SaveFormula( SwHistory& rHistory ) SwUndoMergeTable::SwUndoMergeTable( const SwTableNode& rTableNd, const SwTableNode& rDelTableNd, - bool bWithPrv, sal_uInt16 nMd ) + bool bWithPrv ) : SwUndo( SwUndoId::MERGE_TABLE, &rTableNd.GetDoc() ), - m_nMode( nMd ), m_bWithPrev( bWithPrv ) + m_bWithPrev( bWithPrv ) { // memorize end node of the last table cell that'll stay in position if( m_bWithPrev ) @@ -2915,15 +2974,12 @@ void SwUndoMergeTable::UndoImpl(::sw::UndoRedoContext & rContext) SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor()); pPam->DeleteMark(); - SwNodeIndex& rIdx = pPam->GetPoint()->nNode; - rIdx = m_nTableNode; + SwPosition& rPtPos = *pPam->GetPoint(); + rPtPos.Assign( m_nTableNode); - SwTableNode* pTableNd = rIdx.GetNode().FindTableNode(); + SwTableNode* pTableNd = rPtPos.GetNode().FindTableNode(); SwTable* pTable = &pTableNd->GetTable(); - - SwTableFormulaUpdate aMsgHint( pTable ); - aMsgHint.m_eFlags = TBL_BOXPTR; - pDoc->getIDocumentFieldsAccess().UpdateTableFields( &aMsgHint ); + pTable->SwitchFormulasToInternalRepresentation(); // get lines for layout update FndBox_ aFndBox( nullptr, nullptr ); @@ -2931,7 +2987,7 @@ void SwUndoMergeTable::UndoImpl(::sw::UndoRedoContext & rContext) aFndBox.DelFrames( *pTable ); // ? TL_CHART2: notification or locking of controller required ? - SwTableNode* pNew = pDoc->GetNodes().SplitTable( rIdx ); + SwTableNode* pNew = pDoc->GetNodes().SplitTable( rPtPos.GetNode() ); // update layout aFndBox.MakeFrames( *pTable ); @@ -2940,13 +2996,13 @@ void SwUndoMergeTable::UndoImpl(::sw::UndoRedoContext & rContext) if( m_bWithPrev ) { // move name - pNew->GetTable().GetFrameFormat()->SetName( pTable->GetFrameFormat()->GetName() ); + pNew->GetTable().GetFrameFormat()->SetFormatName( pTable->GetFrameFormat()->GetName() ); m_pSaveHdl->RestoreAttr( pNew->GetTable() ); } else pTable = &pNew->GetTable(); - pTable->GetFrameFormat()->SetName( m_aName ); + pTable->GetFrameFormat()->SetFormatName( m_aName ); m_pSaveTable->RestoreAttr( *pTable ); if( m_pHistory ) @@ -2956,12 +3012,10 @@ void SwUndoMergeTable::UndoImpl(::sw::UndoRedoContext & rContext) } // create frames for the new table - SwNodeIndex aTmpIdx( *pNew ); - pNew->MakeOwnFrames(&aTmpIdx); + pNew->MakeOwnFrames(); // position cursor somewhere in content - SwContentNode* pCNd = pDoc->GetNodes().GoNext( &rIdx ); - pPam->GetPoint()->nContent.Assign( pCNd, 0 ); + SwNodes::GoNext(&rPtPos); ClearFEShellTabCols(*pDoc, nullptr); @@ -2980,13 +3034,12 @@ void SwUndoMergeTable::RedoImpl(::sw::UndoRedoContext & rContext) SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor()); pPam->DeleteMark(); - pPam->GetPoint()->nNode = m_nTableNode; if( m_bWithPrev ) - pPam->GetPoint()->nNode = m_nTableNode + 3; + pPam->GetPoint()->Assign( m_nTableNode + 3 ); else - pPam->GetPoint()->nNode = m_nTableNode; + pPam->GetPoint()->Assign( m_nTableNode ); - pDoc->MergeTable( *pPam->GetPoint(), m_bWithPrev, m_nMode ); + pDoc->MergeTable( *pPam->GetPoint(), m_bWithPrev ); ClearFEShellTabCols(*pDoc, nullptr); } @@ -2996,7 +3049,7 @@ void SwUndoMergeTable::RepeatImpl(::sw::RepeatContext & rContext) SwDoc *const pDoc = & rContext.GetDoc(); SwPaM *const pPam = & rContext.GetRepeatPaM(); - pDoc->MergeTable( *pPam->GetPoint(), m_bWithPrev, m_nMode ); + pDoc->MergeTable( *pPam->GetPoint(), m_bWithPrev ); ClearFEShellTabCols(*pDoc, nullptr); } @@ -3047,9 +3100,9 @@ void CheckTable( const SwTable& rTable ) } #endif -SwUndoTableStyleMake::SwUndoTableStyleMake(const OUString& rName, const SwDoc& rDoc) +SwUndoTableStyleMake::SwUndoTableStyleMake(OUString aName, const SwDoc& rDoc) : SwUndo(SwUndoId::TBLSTYLE_CREATE, &rDoc), - m_sName(rName) + m_sName(std::move(aName)) { } SwUndoTableStyleMake::~SwUndoTableStyleMake() @@ -3080,10 +3133,10 @@ SwRewriter SwUndoTableStyleMake::GetRewriter() const return aResult; } -SwUndoTableStyleDelete::SwUndoTableStyleDelete(std::unique_ptr<SwTableAutoFormat> pAutoFormat, const std::vector<SwTable*>& rAffectedTables, const SwDoc& rDoc) +SwUndoTableStyleDelete::SwUndoTableStyleDelete(std::unique_ptr<SwTableAutoFormat> pAutoFormat, std::vector<SwTable*>&& rAffectedTables, const SwDoc& rDoc) : SwUndo(SwUndoId::TBLSTYLE_DELETE, &rDoc), m_pAutoFormat(std::move(pAutoFormat)), - m_rAffectedTables(rAffectedTables) + m_rAffectedTables(std::move(rAffectedTables)) { } SwUndoTableStyleDelete::~SwUndoTableStyleDelete() |