LCOV - code coverage report
Current view: top level - sw/source/core/undo - untbl.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 261 1593 16.4 %
Date: 2014-11-03 Functions: 38 130 29.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <vector>
      21             : 
      22             : #include <boost/shared_ptr.hpp>
      23             : 
      24             : #include <UndoTable.hxx>
      25             : #include <UndoRedline.hxx>
      26             : #include <UndoDelete.hxx>
      27             : #include <UndoSplitMove.hxx>
      28             : #include <UndoCore.hxx>
      29             : #include <fesh.hxx>
      30             : #include <hintids.hxx>
      31             : #include <hints.hxx>
      32             : #include <editeng/formatbreakitem.hxx>
      33             : #include <fmtornt.hxx>
      34             : #include <fmtpdsc.hxx>
      35             : #include <doc.hxx>
      36             : #include <docredln.hxx>
      37             : #include <IDocumentUndoRedo.hxx>
      38             : #include <IDocumentChartDataProviderAccess.hxx>
      39             : #include <IDocumentRedlineAccess.hxx>
      40             : #include <IDocumentFieldsAccess.hxx>
      41             : #include <IDocumentStylePoolAccess.hxx>
      42             : #include <editsh.hxx>
      43             : #include <docary.hxx>
      44             : #include <ndtxt.hxx>
      45             : #include <swtable.hxx>
      46             : #include <pam.hxx>
      47             : #include <cntfrm.hxx>
      48             : #include <tblsel.hxx>
      49             : #include <swundo.hxx>
      50             : #include <rolbck.hxx>
      51             : #include <ddefld.hxx>
      52             : #include <tabcol.hxx>
      53             : #include <tabfrm.hxx>
      54             : #include <rowfrm.hxx>
      55             : #include <cellfrm.hxx>
      56             : #include <swcache.hxx>
      57             : #include <tblafmt.hxx>
      58             : #include <poolfmt.hxx>
      59             : #include <mvsave.hxx>
      60             : #include <cellatr.hxx>
      61             : #include <swtblfmt.hxx>
      62             : #include <swddetbl.hxx>
      63             : #include <redline.hxx>
      64             : #include <node2lay.hxx>
      65             : #include <tblrwcl.hxx>
      66             : #include <fmtanchr.hxx>
      67             : #include <comcore.hrc>
      68             : #include <unochart.hxx>
      69             : #include <switerator.hxx>
      70             : 
      71             : #ifdef DBG_UTIL
      72             : #define CHECK_TABLE(t) (t).CheckConsistency();
      73             : #else
      74             : #define CHECK_TABLE(t)
      75             : #endif
      76             : 
      77             : #ifdef DBG_UTIL
      78             :     #define _DEBUG_REDLINE( pDoc ) sw_DebugRedline( pDoc );
      79             : #else
      80             :     #define _DEBUG_REDLINE( pDoc )
      81             : #endif
      82             : 
      83             : typedef std::vector<boost::shared_ptr<SfxItemSet> > SfxItemSets;
      84             : 
      85           2 : class SwUndoSaveSections : public boost::ptr_vector<SwUndoSaveSection> {
      86             : public:
      87           2 :     SwUndoSaveSections(size_type n) : boost::ptr_vector<SwUndoSaveSection>(n) {}
      88             : };
      89             : 
      90           4 : class SwUndoMoves : public boost::ptr_vector<SwUndoMove> {};
      91             : 
      92             : struct SwTblToTxtSave;
      93           0 : class SwTblToTxtSaves : public boost::ptr_vector<SwTblToTxtSave> {
      94             : public:
      95           0 :     SwTblToTxtSaves(size_type n) : boost::ptr_vector<SwTblToTxtSave>(n) {}
      96             : };
      97             : 
      98             : struct _UndoTblCpyTbl_Entry
      99             : {
     100             :     sal_uLong nBoxIdx, nOffset;
     101             :     SfxItemSet* pBoxNumAttr;
     102             :     SwUndo* pUndo;
     103             : 
     104             :     // Was the last paragraph of the new and the first paragraph of the old content joined?
     105             :     bool bJoin; // For redlining only
     106             : 
     107             :     _UndoTblCpyTbl_Entry( const SwTableBox& rBox );
     108             :     ~_UndoTblCpyTbl_Entry();
     109             : };
     110           0 : class _UndoTblCpyTbl_Entries : public boost::ptr_vector<_UndoTblCpyTbl_Entry> {};
     111             : 
     112             : class _SaveBox;
     113             : class _SaveLine;
     114             : 
     115             : class _SaveTable
     116             : {
     117             :     friend class _SaveBox;
     118             :     friend class _SaveLine;
     119             :     SfxItemSet aTblSet;
     120             :     _SaveLine* pLine;
     121             :     const SwTable* pSwTable;
     122             :     SfxItemSets aSets;
     123             :     SwFrmFmts aFrmFmts;
     124             :     sal_uInt16 nLineCount;
     125             :     bool bModifyBox : 1;
     126             :     bool bSaveFormula : 1;
     127             :     bool bNewModel : 1;
     128             : 
     129             : public:
     130             :     _SaveTable( const SwTable& rTbl, sal_uInt16 nLnCnt = USHRT_MAX,
     131             :                 bool bSaveFml = true );
     132             :     ~_SaveTable();
     133             : 
     134             :     sal_uInt16 AddFmt( SwFrmFmt* pFmt, bool bIsLine );
     135             :     void NewFrmFmt( const SwTableLine* , const SwTableBox*, sal_uInt16 nFmtPos,
     136             :                     SwFrmFmt* pOldFmt );
     137             : 
     138             :     void RestoreAttr( SwTable& rTbl, bool bModifyBox = false );
     139             :     void SaveCntntAttrs( SwDoc* pDoc );
     140             :     void CreateNew( SwTable& rTbl, bool bCreateFrms = true,
     141             :                     bool bRestoreChart = true );
     142           0 :     bool IsNewModel() const { return bNewModel; }
     143             : };
     144             : 
     145             : class _SaveLine
     146             : {
     147             :     friend class _SaveTable;
     148             :     friend class _SaveBox;
     149             : 
     150             :     _SaveLine* pNext;
     151             :     _SaveBox* pBox;
     152             :     sal_uInt16 nItemSet;
     153             : 
     154             : public:
     155             :     _SaveLine( _SaveLine* pPrev, const SwTableLine& rLine, _SaveTable& rSTbl );
     156             :     ~_SaveLine();
     157             : 
     158             :     void RestoreAttr( SwTableLine& rLine, _SaveTable& rSTbl );
     159             :     void SaveCntntAttrs( SwDoc* pDoc );
     160             : 
     161             :     void CreateNew( SwTable& rTbl, SwTableBox& rParent, _SaveTable& rSTbl  );
     162             : };
     163             : 
     164             : class _SaveBox
     165             : {
     166             :     friend class _SaveLine;
     167             : 
     168             :     _SaveBox* pNext;
     169             :     sal_uLong nSttNode;
     170             :     long nRowSpan;
     171             :     sal_uInt16 nItemSet;
     172             :     union
     173             :     {
     174             :         SfxItemSets* pCntntAttrs;
     175             :         _SaveLine* pLine;
     176             :     } Ptrs;
     177             : 
     178             : public:
     179             :     _SaveBox( _SaveBox* pPrev, const SwTableBox& rBox, _SaveTable& rSTbl );
     180             :     ~_SaveBox();
     181             : 
     182             :     void RestoreAttr( SwTableBox& rBox, _SaveTable& rSTbl );
     183             :     void SaveCntntAttrs( SwDoc* pDoc );
     184             : 
     185             :     void CreateNew( SwTable& rTbl, SwTableLine& rParent, _SaveTable& rSTbl );
     186             : };
     187             : 
     188             : #if OSL_DEBUG_LEVEL > 0
     189             : #include "shellio.hxx"
     190             : void CheckTable( const SwTable& );
     191             : #define CHECKTABLE(t) CheckTable( t );
     192             : #else
     193             : #define CHECKTABLE(t)
     194             : #endif
     195             : 
     196             : /* #130880: Crash in undo of table to text when the table has (freshly) merged cells
     197             : The order of cell content nodes in the nodes array is not given by the recursive table structure.
     198             : The algorithmn must not rely on this even it holds for a fresh loaded table in odt file format.
     199             : So we need to remember not only the start node position but the end node position as well.
     200             : */
     201             : 
     202             : struct SwTblToTxtSave
     203             : {
     204             :     sal_uLong m_nSttNd;
     205             :     sal_uLong m_nEndNd;
     206             :     sal_Int32 m_nCntnt;
     207             :     SwHistory* m_pHstry;
     208             :     // metadata references for first and last paragraph in cell
     209             :     ::boost::shared_ptr< ::sfx2::MetadatableUndo > m_pMetadataUndoStart;
     210             :     ::boost::shared_ptr< ::sfx2::MetadatableUndo > m_pMetadataUndoEnd;
     211             : 
     212             :     SwTblToTxtSave( SwDoc& rDoc, sal_uLong nNd, sal_uLong nEndIdx, sal_Int32 nCntnt );
     213           0 :     ~SwTblToTxtSave() { delete m_pHstry; }
     214             : };
     215             : 
     216             : sal_uInt16 aSave_BoxCntntSet[] = {
     217             :     RES_CHRATR_COLOR, RES_CHRATR_CROSSEDOUT,
     218             :     RES_CHRATR_FONT, RES_CHRATR_FONTSIZE,
     219             :     RES_CHRATR_POSTURE, RES_CHRATR_POSTURE,
     220             :     RES_CHRATR_SHADOWED, RES_CHRATR_WEIGHT,
     221             :     RES_PARATR_ADJUST, RES_PARATR_ADJUST,
     222             :     0 };
     223             : 
     224         102 : SwUndoInsTbl::SwUndoInsTbl( const SwPosition& rPos, sal_uInt16 nCl, sal_uInt16 nRw,
     225             :                             sal_uInt16 nAdj, const SwInsertTableOptions& rInsTblOpts,
     226             :                             const SwTableAutoFmt* pTAFmt,
     227             :                             const std::vector<sal_uInt16> *pColArr,
     228             :                             const OUString & rName)
     229             :     : SwUndo( UNDO_INSTABLE ),
     230             :     aInsTblOpts( rInsTblOpts ), pDDEFldType( 0 ), pColWidth( 0 ), pRedlData( 0 ), pAutoFmt( 0 ),
     231         102 :     nSttNode( rPos.nNode.GetIndex() ), nRows( nRw ), nCols( nCl ), nAdjust( nAdj )
     232             : {
     233         102 :     if( pColArr )
     234             :     {
     235           0 :         pColWidth = new std::vector<sal_uInt16>(*pColArr);
     236             :     }
     237         102 :     if( pTAFmt )
     238           0 :         pAutoFmt = new SwTableAutoFmt( *pTAFmt );
     239             : 
     240             :     // consider redline
     241         102 :     SwDoc& rDoc = *rPos.nNode.GetNode().GetDoc();
     242         102 :     if( rDoc.getIDocumentRedlineAccess().IsRedlineOn() )
     243             :     {
     244           0 :         pRedlData = new SwRedlineData( nsRedlineType_t::REDLINE_INSERT, rDoc.getIDocumentRedlineAccess().GetRedlineAuthor() );
     245           0 :         SetRedlineMode( rDoc.getIDocumentRedlineAccess().GetRedlineMode() );
     246             :     }
     247             : 
     248         102 :     sTblNm = rName;
     249         102 : }
     250             : 
     251         306 : SwUndoInsTbl::~SwUndoInsTbl()
     252             : {
     253         102 :     delete pDDEFldType;
     254         102 :     delete pColWidth;
     255         102 :     delete pRedlData;
     256         102 :     delete pAutoFmt;
     257         204 : }
     258             : 
     259           2 : void SwUndoInsTbl::UndoImpl(::sw::UndoRedoContext & rContext)
     260             : {
     261           2 :     SwDoc & rDoc = rContext.GetDoc();
     262           2 :     SwNodeIndex aIdx( rDoc.GetNodes(), nSttNode );
     263             : 
     264           2 :     SwTableNode* pTblNd = aIdx.GetNode().GetTableNode();
     265             :     OSL_ENSURE( pTblNd, "no TableNode" );
     266           2 :     pTblNd->DelFrms();
     267             : 
     268           2 :     if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ))
     269           0 :         rDoc.getIDocumentRedlineAccess().DeleteRedline( *pTblNd, true, USHRT_MAX );
     270           2 :     RemoveIdxFromSection( rDoc, nSttNode );
     271             : 
     272             :     // move hard page breaks into next node
     273           2 :     SwCntntNode* pNextNd = rDoc.GetNodes()[ pTblNd->EndOfSectionIndex()+1 ]->GetCntntNode();
     274           2 :     if( pNextNd )
     275             :     {
     276           2 :         SwFrmFmt* pTableFmt = pTblNd->GetTable().GetFrmFmt();
     277             :         const SfxPoolItem *pItem;
     278             : 
     279           2 :         if( SfxItemState::SET == pTableFmt->GetItemState( RES_PAGEDESC,
     280           2 :             false, &pItem ) )
     281           0 :             pNextNd->SetAttr( *pItem );
     282             : 
     283           2 :         if( SfxItemState::SET == pTableFmt->GetItemState( RES_BREAK,
     284           2 :             false, &pItem ) )
     285           0 :             pNextNd->SetAttr( *pItem );
     286             :     }
     287             : 
     288           2 :     sTblNm = pTblNd->GetTable().GetFrmFmt()->GetName();
     289           2 :     if( pTblNd->GetTable().IsA( TYPE( SwDDETable )) )
     290           0 :         pDDEFldType = (SwDDEFieldType*)((SwDDETable&)pTblNd->GetTable()).
     291           0 :                                         GetDDEFldType()->Copy();
     292             : 
     293           6 :     rDoc.GetNodes().Delete( aIdx, pTblNd->EndOfSectionIndex() -
     294           6 :                                 aIdx.GetIndex() + 1 );
     295             : 
     296           2 :     SwPaM & rPam( rContext.GetCursorSupplier().CreateNewShellCursor() );
     297           2 :     rPam.DeleteMark();
     298           2 :     rPam.GetPoint()->nNode = aIdx;
     299           2 :     rPam.GetPoint()->nContent.Assign( rPam.GetCntntNode(), 0 );
     300           2 : }
     301             : 
     302           0 : void SwUndoInsTbl::RedoImpl(::sw::UndoRedoContext & rContext)
     303             : {
     304           0 :     SwDoc & rDoc = rContext.GetDoc();
     305             : 
     306           0 :     SwPosition const aPos(SwNodeIndex(rDoc.GetNodes(), nSttNode));
     307             :     const SwTable* pTbl = rDoc.InsertTable( aInsTblOpts, aPos, nRows, nCols,
     308             :                                             nAdjust,
     309           0 :                                             pAutoFmt, pColWidth );
     310           0 :     ((SwFrmFmt*)pTbl->GetFrmFmt())->SetName( sTblNm );
     311           0 :     SwTableNode* pTblNode = (SwTableNode*)rDoc.GetNodes()[nSttNode]->GetTableNode();
     312             : 
     313           0 :     if( pDDEFldType )
     314             :     {
     315           0 :         SwDDEFieldType* pNewType = (SwDDEFieldType*)rDoc.getIDocumentFieldsAccess().InsertFldType(
     316           0 :                                                             *pDDEFldType);
     317           0 :         SwDDETable* pDDETbl = new SwDDETable( pTblNode->GetTable(), pNewType );
     318           0 :         pTblNode->SetNewTable( pDDETbl );
     319           0 :         delete pDDEFldType, pDDEFldType = 0;
     320             :     }
     321             : 
     322           0 :     if( (pRedlData && IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() )) ||
     323           0 :         ( !( nsRedlineMode_t::REDLINE_IGNORE & GetRedlineMode() ) &&
     324           0 :             !rDoc.getIDocumentRedlineAccess().GetRedlineTbl().empty() ))
     325             :     {
     326           0 :         SwPaM aPam( *pTblNode->EndOfSectionNode(), *pTblNode, 1 );
     327           0 :         SwCntntNode* pCNd = aPam.GetCntntNode( false );
     328           0 :         if( pCNd )
     329           0 :             aPam.GetMark()->nContent.Assign( pCNd, 0 );
     330             : 
     331           0 :         if( pRedlData && IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ) )
     332             :         {
     333           0 :             RedlineMode_t eOld = rDoc.getIDocumentRedlineAccess().GetRedlineMode();
     334           0 :             rDoc.getIDocumentRedlineAccess().SetRedlineMode_intern((RedlineMode_t)(eOld & ~nsRedlineMode_t::REDLINE_IGNORE));
     335             : 
     336           0 :             rDoc.getIDocumentRedlineAccess().AppendRedline( new SwRangeRedline( *pRedlData, aPam ), true);
     337           0 :             rDoc.getIDocumentRedlineAccess().SetRedlineMode_intern( eOld );
     338             :         }
     339             :         else
     340           0 :             rDoc.getIDocumentRedlineAccess().SplitRedline( aPam );
     341           0 :     }
     342           0 : }
     343             : 
     344           0 : void SwUndoInsTbl::RepeatImpl(::sw::RepeatContext & rContext)
     345             : {
     346           0 :     rContext.GetDoc().InsertTable(
     347           0 :             aInsTblOpts, *rContext.GetRepeatPaM().GetPoint(),
     348           0 :             nRows, nCols, nAdjust, pAutoFmt, pColWidth );
     349           0 : }
     350             : 
     351         102 : SwRewriter SwUndoInsTbl::GetRewriter() const
     352             : {
     353         102 :     SwRewriter aRewriter;
     354             : 
     355         102 :     aRewriter.AddRule(UndoArg1, SW_RES(STR_START_QUOTE));
     356         102 :     aRewriter.AddRule(UndoArg2, sTblNm);
     357         102 :     aRewriter.AddRule(UndoArg3, SW_RES(STR_END_QUOTE));
     358             : 
     359         102 :     return aRewriter;
     360             : }
     361             : 
     362           0 : SwTblToTxtSave::SwTblToTxtSave( SwDoc& rDoc, sal_uLong nNd, sal_uLong nEndIdx, sal_Int32 nCnt )
     363           0 :     : m_nSttNd( nNd ), m_nEndNd( nEndIdx), m_nCntnt( nCnt ), m_pHstry( 0 )
     364             : {
     365             :     // keep attributes of the joined node
     366           0 :     SwTxtNode* pNd = rDoc.GetNodes()[ nNd ]->GetTxtNode();
     367           0 :     if( pNd )
     368             :     {
     369           0 :         m_pHstry = new SwHistory;
     370             : 
     371           0 :         m_pHstry->Add( pNd->GetTxtColl(), nNd, ND_TEXTNODE );
     372           0 :         if ( pNd->GetpSwpHints() )
     373             :         {
     374             :             m_pHstry->CopyAttr( pNd->GetpSwpHints(), nNd, 0,
     375           0 :                         pNd->GetTxt().getLength(), false );
     376             :         }
     377           0 :         if( pNd->HasSwAttrSet() )
     378           0 :             m_pHstry->CopyFmtAttr( *pNd->GetpSwAttrSet(), nNd );
     379             : 
     380           0 :         if( !m_pHstry->Count() )
     381           0 :             delete m_pHstry, m_pHstry = 0;
     382             : 
     383             :         // METADATA: store
     384           0 :         m_pMetadataUndoStart = pNd->CreateUndo();
     385             :     }
     386             : 
     387             :     // we also need to store the metadata reference of the _last_ paragraph
     388             :     // we subtract 1 to account for the removed cell start/end node pair
     389             :     // (after SectionUp, the end of the range points to the node after the cell)
     390           0 :     if ( nEndIdx - 1 > nNd )
     391             :     {
     392           0 :         SwTxtNode* pLastNode( rDoc.GetNodes()[ nEndIdx - 1 ]->GetTxtNode() );
     393           0 :         if( pLastNode )
     394             :         {
     395             :             // METADATA: store
     396           0 :             m_pMetadataUndoEnd = pLastNode->CreateUndo();
     397             :         }
     398             :     }
     399           0 : }
     400             : 
     401           0 : SwUndoTblToTxt::SwUndoTblToTxt( const SwTable& rTbl, sal_Unicode cCh )
     402             :     : SwUndo( UNDO_TABLETOTEXT ),
     403           0 :     sTblNm( rTbl.GetFrmFmt()->GetName() ), pDDEFldType( 0 ), pHistory( 0 ),
     404             :     nSttNd( 0 ), nEndNd( 0 ),
     405           0 :     cTrenner( cCh ), nHdlnRpt( rTbl.GetRowsToRepeat() )
     406             : {
     407           0 :     pTblSave = new _SaveTable( rTbl );
     408           0 :     pBoxSaves = new SwTblToTxtSaves( (SwTblToTxtSaves::size_type)rTbl.GetTabSortBoxes().size() );
     409             : 
     410           0 :     if( rTbl.IsA( TYPE( SwDDETable ) ) )
     411           0 :         pDDEFldType = (SwDDEFieldType*)((SwDDETable&)rTbl).GetDDEFldType()->Copy();
     412             : 
     413           0 :     bCheckNumFmt = rTbl.GetFrmFmt()->GetDoc()->IsInsTblFormatNum();
     414             : 
     415           0 :     pHistory = new SwHistory;
     416           0 :     const SwTableNode* pTblNd = rTbl.GetTableNode();
     417           0 :     sal_uLong nTblStt = pTblNd->GetIndex(), nTblEnd = pTblNd->EndOfSectionIndex();
     418             : 
     419           0 :     const SwFrmFmts& rFrmFmtTbl = *pTblNd->GetDoc()->GetSpzFrmFmts();
     420           0 :     for( size_t n = 0; n < rFrmFmtTbl.size(); ++n )
     421             :     {
     422           0 :         SwFrmFmt* pFmt = rFrmFmtTbl[ n ];
     423           0 :         SwFmtAnchor const*const pAnchor = &pFmt->GetAnchor();
     424           0 :         SwPosition const*const pAPos = pAnchor->GetCntntAnchor();
     425           0 :         if (pAPos &&
     426           0 :             ((FLY_AT_CHAR == pAnchor->GetAnchorId()) ||
     427           0 :              (FLY_AT_PARA == pAnchor->GetAnchorId())) &&
     428           0 :             nTblStt <= pAPos->nNode.GetIndex() &&
     429           0 :             pAPos->nNode.GetIndex() < nTblEnd )
     430             :         {
     431           0 :             pHistory->Add( *pFmt );
     432             :         }
     433             :     }
     434             : 
     435           0 :     if( !pHistory->Count() )
     436           0 :         delete pHistory, pHistory = 0;
     437           0 : }
     438             : 
     439           0 : SwUndoTblToTxt::~SwUndoTblToTxt()
     440             : {
     441           0 :     delete pDDEFldType;
     442           0 :     delete pTblSave;
     443           0 :     delete pBoxSaves;
     444           0 :     delete pHistory;
     445           0 : }
     446             : 
     447           0 : void SwUndoTblToTxt::UndoImpl(::sw::UndoRedoContext & rContext)
     448             : {
     449           0 :     SwDoc & rDoc = rContext.GetDoc();
     450           0 :     SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());
     451             : 
     452           0 :     SwNodeIndex aFrmIdx( rDoc.GetNodes(), nSttNd );
     453           0 :     SwNodeIndex aEndIdx( rDoc.GetNodes(), nEndNd );
     454             : 
     455           0 :     pPam->GetPoint()->nNode = aFrmIdx;
     456           0 :     pPam->SetMark();
     457           0 :     pPam->GetPoint()->nNode = aEndIdx;
     458           0 :     rDoc.DelNumRules( *pPam );
     459           0 :     pPam->DeleteMark();
     460             : 
     461             :     // now collect all Uppers
     462           0 :     SwNode2Layout aNode2Layout( aFrmIdx.GetNode() );
     463             : 
     464             :     // create TableNode structure
     465           0 :     SwTableNode* pTblNd = rDoc.GetNodes().UndoTableToText( nSttNd, nEndNd, *pBoxSaves );
     466           0 :     pTblNd->GetTable().SetTableModel( pTblSave->IsNewModel() );
     467           0 :     SwTableFmt* pTableFmt = rDoc.MakeTblFrmFmt( sTblNm, rDoc.GetDfltFrmFmt() );
     468           0 :     pTblNd->GetTable().RegisterToFormat( *pTableFmt );
     469           0 :     pTblNd->GetTable().SetRowsToRepeat( nHdlnRpt );
     470             : 
     471             :     // create old table structure
     472           0 :     pTblSave->CreateNew( pTblNd->GetTable() );
     473             : 
     474           0 :     if( pDDEFldType )
     475             :     {
     476           0 :         SwDDEFieldType* pNewType = (SwDDEFieldType*)rDoc.getIDocumentFieldsAccess().InsertFldType(
     477           0 :                                                             *pDDEFldType);
     478           0 :         SwDDETable* pDDETbl = new SwDDETable( pTblNd->GetTable(), pNewType );
     479           0 :         pTblNd->SetNewTable( pDDETbl, false );
     480           0 :         delete pDDEFldType, pDDEFldType = 0;
     481             :     }
     482             : 
     483           0 :     if( bCheckNumFmt )
     484             :     {
     485           0 :         SwTableSortBoxes& rBxs = pTblNd->GetTable().GetTabSortBoxes();
     486           0 :         for (size_t nBoxes = rBxs.size(); nBoxes; )
     487             :         {
     488           0 :             rDoc.ChkBoxNumFmt( *rBxs[ --nBoxes ], false );
     489             :         }
     490             :     }
     491             : 
     492           0 :     if( pHistory )
     493             :     {
     494           0 :         sal_uInt16 nTmpEnd = pHistory->GetTmpEnd();
     495           0 :         pHistory->TmpRollback( &rDoc, 0 );
     496           0 :         pHistory->SetTmpEnd( nTmpEnd );
     497             :     }
     498             : 
     499           0 :     aNode2Layout.RestoreUpperFrms( rDoc.GetNodes(),
     500           0 :                                    pTblNd->GetIndex(), pTblNd->GetIndex()+1 );
     501             : 
     502             :     // Is a table selection requested?
     503           0 :     pPam->DeleteMark();
     504           0 :     pPam->GetPoint()->nNode = *pTblNd->EndOfSectionNode();
     505           0 :     pPam->SetMark();
     506           0 :     pPam->GetPoint()->nNode = *pPam->GetNode().StartOfSectionNode();
     507           0 :     pPam->Move( fnMoveForward, fnGoCntnt );
     508           0 :     pPam->Exchange();
     509           0 :     pPam->Move( fnMoveBackward, fnGoCntnt );
     510             : 
     511           0 :     ClearFEShellTabCols();
     512           0 : }
     513             : 
     514             : // located in untbl.cxx and only an Undo object is allowed to call it
     515           0 : SwTableNode* SwNodes::UndoTableToText( sal_uLong nSttNd, sal_uLong nEndNd,
     516             :                                 const SwTblToTxtSaves& rSavedData )
     517             : {
     518           0 :     SwNodeIndex aSttIdx( *this, nSttNd );
     519           0 :     SwNodeIndex aEndIdx( *this, nEndNd+1 );
     520             : 
     521           0 :     SwTableNode * pTblNd = new SwTableNode( aSttIdx );
     522           0 :     SwEndNode* pEndNd = new SwEndNode( aEndIdx, *pTblNd  );
     523             : 
     524           0 :     aEndIdx = *pEndNd;
     525             : 
     526             :     /* Set pTblNd as start of section for all nodes in [nSttNd, nEndNd].
     527             :        Delete all Frames attached to the nodes in that range. */
     528             :     SwNode* pNd;
     529             :     {
     530           0 :         sal_uLong n, nTmpEnd = aEndIdx.GetIndex();
     531           0 :         for( n = pTblNd->GetIndex() + 1; n < nTmpEnd; ++n )
     532             :         {
     533           0 :             if( ( pNd = (*this)[ n ] )->IsCntntNode() )
     534           0 :                 ((SwCntntNode*)pNd)->DelFrms();
     535           0 :             pNd->pStartOfSection = pTblNd;
     536             :         }
     537             :     }
     538             : 
     539             :     // than create table structure partially. First a single line that contains
     540             :     // all boxes. The correct structure is than taken from SaveStruct.
     541           0 :     SwTableBoxFmt* pBoxFmt = GetDoc()->MakeTableBoxFmt();
     542           0 :     SwTableLineFmt* pLineFmt = GetDoc()->MakeTableLineFmt();
     543           0 :     SwTableLine* pLine = new SwTableLine( pLineFmt, rSavedData.size(), 0 );
     544           0 :     pTblNd->GetTable().GetTabLines().insert( pTblNd->GetTable().GetTabLines().begin(), pLine );
     545             : 
     546           0 :     const boost::shared_ptr<sw::mark::CntntIdxStore> pCntntStore(sw::mark::CntntIdxStore::Create());
     547           0 :     for( size_t n = rSavedData.size(); n; )
     548             :     {
     549           0 :         const SwTblToTxtSave* pSave = &rSavedData[ --n ];
     550             :         // if the start node was merged with last from prev. cell,
     551             :         // subtract 1 from index to get the merged paragraph, and split that
     552           0 :         aSttIdx = pSave->m_nSttNd - ( ( SAL_MAX_INT32 != pSave->m_nCntnt ) ? 1 : 0);
     553           0 :         SwTxtNode* pTxtNd = aSttIdx.GetNode().GetTxtNode();
     554             : 
     555           0 :         if( SAL_MAX_INT32 != pSave->m_nCntnt )
     556             :         {
     557             :             // split at ContentPosition, delete previous char (= separator)
     558             :             OSL_ENSURE( pTxtNd, "Where is my TextNode?" );
     559           0 :             SwIndex aCntPos( pTxtNd, pSave->m_nCntnt - 1 );
     560             : 
     561           0 :             pTxtNd->EraseText( aCntPos, 1 );
     562             :             SwCntntNode* pNewNd = pTxtNd->SplitCntntNode(
     563           0 :                                         SwPosition( aSttIdx, aCntPos ));
     564           0 :             if( !pCntntStore->Empty() )
     565           0 :                 pCntntStore->Restore( *pNewNd, pSave->m_nCntnt, pSave->m_nCntnt + 1 );
     566             :         }
     567             :         else
     568             :         {
     569           0 :             pCntntStore->Clear();
     570           0 :             if( pTxtNd )
     571           0 :                 pCntntStore->Save( GetDoc(), aSttIdx.GetIndex(), pTxtNd->GetTxt().getLength() );
     572             :         }
     573             : 
     574           0 :         if( pTxtNd )
     575             :         {
     576             :             // METADATA: restore
     577           0 :             pTxtNd->GetTxtNode()->RestoreMetadata(pSave->m_pMetadataUndoStart);
     578           0 :             if( pTxtNd->HasSwAttrSet() )
     579           0 :                 pTxtNd->ResetAllAttr();
     580             : 
     581           0 :             if( pTxtNd->GetpSwpHints() )
     582           0 :                 pTxtNd->ClearSwpHintsArr( false );
     583             :         }
     584             : 
     585           0 :         if( pSave->m_pHstry )
     586             :         {
     587           0 :             sal_uInt16 nTmpEnd = pSave->m_pHstry->GetTmpEnd();
     588           0 :             pSave->m_pHstry->TmpRollback( GetDoc(), 0 );
     589           0 :             pSave->m_pHstry->SetTmpEnd( nTmpEnd );
     590             :         }
     591             : 
     592             :         // METADATA: restore
     593             :         // end points to node after cell
     594           0 :         if ( pSave->m_nEndNd - 1 > pSave->m_nSttNd )
     595             :         {
     596           0 :             SwTxtNode* pLastNode = (*this)[ pSave->m_nEndNd - 1 ]->GetTxtNode();
     597           0 :             if (pLastNode)
     598             :             {
     599           0 :                 pLastNode->RestoreMetadata(pSave->m_pMetadataUndoEnd);
     600             :             }
     601             :         }
     602             : 
     603           0 :         aEndIdx = pSave->m_nEndNd;
     604             :         SwStartNode* pSttNd = new SwStartNode( aSttIdx, ND_STARTNODE,
     605           0 :                                                 SwTableBoxStartNode );
     606           0 :         pSttNd->pStartOfSection = pTblNd;
     607           0 :         new SwEndNode( aEndIdx, *pSttNd );
     608             : 
     609           0 :         for( sal_uLong i = aSttIdx.GetIndex(); i < aEndIdx.GetIndex()-1; ++i )
     610             :         {
     611           0 :             pNd = (*this)[ i ];
     612           0 :             pNd->pStartOfSection = pSttNd;
     613           0 :             if( pNd->IsStartNode() )
     614           0 :                 i = pNd->EndOfSectionIndex();
     615             :         }
     616             : 
     617           0 :         SwTableBox* pBox = new SwTableBox( pBoxFmt, *pSttNd, pLine );
     618           0 :         pLine->GetTabBoxes().insert( pLine->GetTabBoxes().begin(), pBox );
     619             :     }
     620           0 :     return pTblNd;
     621             : }
     622             : 
     623           0 : void SwUndoTblToTxt::RedoImpl(::sw::UndoRedoContext & rContext)
     624             : {
     625           0 :     SwDoc & rDoc = rContext.GetDoc();
     626           0 :     SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());
     627             : 
     628           0 :     pPam->GetPoint()->nNode = nSttNd;
     629           0 :     pPam->GetPoint()->nContent.Assign( 0, 0 );
     630           0 :     SwNodeIndex aSaveIdx( pPam->GetPoint()->nNode, -1 );
     631             : 
     632           0 :     pPam->SetMark();            // log off all indices
     633           0 :     pPam->DeleteMark();
     634             : 
     635           0 :     SwTableNode* pTblNd = pPam->GetNode().GetTableNode();
     636             :     OSL_ENSURE( pTblNd, "Could not find any TableNode" );
     637             : 
     638           0 :     if( pTblNd->GetTable().IsA( TYPE( SwDDETable )) )
     639           0 :         pDDEFldType = (SwDDEFieldType*)((SwDDETable&)pTblNd->GetTable()).
     640           0 :                                                 GetDDEFldType()->Copy();
     641             : 
     642           0 :     rDoc.TableToText( pTblNd, cTrenner );
     643             : 
     644           0 :     ++aSaveIdx;
     645           0 :     SwCntntNode* pCNd = aSaveIdx.GetNode().GetCntntNode();
     646           0 :     if( !pCNd && 0 == ( pCNd = rDoc.GetNodes().GoNext( &aSaveIdx ) ) &&
     647           0 :         0 == ( pCNd = rDoc.GetNodes().GoPrevious( &aSaveIdx )) )
     648             :     {
     649             :         OSL_FAIL( "Where is the TextNode now?" );
     650             :     }
     651             : 
     652           0 :     pPam->GetPoint()->nNode = aSaveIdx;
     653           0 :     pPam->GetPoint()->nContent.Assign( pCNd, 0 );
     654             : 
     655           0 :     pPam->SetMark();            // log off all indices
     656           0 :     pPam->DeleteMark();
     657           0 : }
     658             : 
     659           0 : void SwUndoTblToTxt::RepeatImpl(::sw::RepeatContext & rContext)
     660             : {
     661           0 :     SwPaM *const pPam = & rContext.GetRepeatPaM();
     662           0 :     SwTableNode *const pTblNd = pPam->GetNode().FindTableNode();
     663           0 :     if( pTblNd )
     664             :     {
     665             :         // move cursor out of table
     666           0 :         pPam->GetPoint()->nNode = *pTblNd->EndOfSectionNode();
     667           0 :         pPam->Move( fnMoveForward, fnGoCntnt );
     668           0 :         pPam->SetMark();
     669           0 :         pPam->DeleteMark();
     670             : 
     671           0 :         rContext.GetDoc().TableToText( pTblNd, cTrenner );
     672             :     }
     673           0 : }
     674             : 
     675           0 : void SwUndoTblToTxt::SetRange( const SwNodeRange& rRg )
     676             : {
     677           0 :     nSttNd = rRg.aStart.GetIndex();
     678           0 :     nEndNd = rRg.aEnd.GetIndex();
     679           0 : }
     680             : 
     681           0 : void SwUndoTblToTxt::AddBoxPos( SwDoc& rDoc, sal_uLong nNdIdx, sal_uLong nEndIdx, sal_Int32 nCntntIdx )
     682             : {
     683           0 :     SwTblToTxtSave* pNew = new SwTblToTxtSave( rDoc, nNdIdx, nEndIdx, nCntntIdx );
     684           0 :     pBoxSaves->push_back( pNew );
     685           0 : }
     686             : 
     687           0 : SwUndoTxtToTbl::SwUndoTxtToTbl( const SwPaM& rRg,
     688             :                                 const SwInsertTableOptions& rInsTblOpts,
     689             :                                 sal_Unicode cCh, sal_uInt16 nAdj,
     690             :                                 const SwTableAutoFmt* pAFmt )
     691             :     : SwUndo( UNDO_TEXTTOTABLE ), SwUndRng( rRg ), aInsTblOpts( rInsTblOpts ),
     692             :       pDelBoxes( 0 ), pAutoFmt( 0 ),
     693           0 :       pHistory( 0 ), cTrenner( cCh ), nAdjust( nAdj )
     694             : {
     695           0 :     if( pAFmt )
     696           0 :         pAutoFmt = new SwTableAutoFmt( *pAFmt );
     697             : 
     698           0 :     const SwPosition* pEnd = rRg.End();
     699           0 :     SwNodes& rNds = rRg.GetDoc()->GetNodes();
     700           0 :     bSplitEnd = pEnd->nContent.GetIndex() && ( pEnd->nContent.GetIndex()
     701           0 :                         != pEnd->nNode.GetNode().GetCntntNode()->Len() ||
     702           0 :                 pEnd->nNode.GetIndex() >= rNds.GetEndOfContent().GetIndex()-1 );
     703           0 : }
     704             : 
     705           0 : SwUndoTxtToTbl::~SwUndoTxtToTbl()
     706             : {
     707           0 :     delete pDelBoxes;
     708           0 :     delete pAutoFmt;
     709           0 : }
     710             : 
     711           0 : void SwUndoTxtToTbl::UndoImpl(::sw::UndoRedoContext & rContext)
     712             : {
     713           0 :     SwDoc & rDoc = rContext.GetDoc();
     714             : 
     715           0 :     sal_uLong nTblNd = nSttNode;
     716           0 :     if( nSttCntnt )
     717           0 :         ++nTblNd;       // Node was splitted previously
     718           0 :     SwNodeIndex aIdx( rDoc.GetNodes(), nTblNd );
     719           0 :     SwTableNode *const pTNd = aIdx.GetNode().GetTableNode();
     720             :     OSL_ENSURE( pTNd, "Could not find a TableNode" );
     721             : 
     722           0 :     RemoveIdxFromSection( rDoc, nTblNd );
     723             : 
     724           0 :     sTblNm = pTNd->GetTable().GetFrmFmt()->GetName();
     725             : 
     726           0 :     if( pHistory )
     727             :     {
     728           0 :         pHistory->TmpRollback( &rDoc, 0 );
     729           0 :         pHistory->SetTmpEnd( pHistory->Count() );
     730             :     }
     731             : 
     732           0 :     if( pDelBoxes )
     733             :     {
     734           0 :         pTNd->DelFrms();
     735           0 :         SwTable& rTbl = pTNd->GetTable();
     736           0 :         for( size_t n = pDelBoxes->size(); n; )
     737             :         {
     738           0 :             SwTableBox* pBox = rTbl.GetTblBox( (*pDelBoxes)[ --n ] );
     739           0 :             if( pBox )
     740           0 :                 ::_DeleteBox( rTbl, pBox, 0, false, false );
     741             :             else {
     742             :                 OSL_ENSURE( false, "Where is my box?" );
     743             :             }
     744             :         }
     745             :     }
     746             : 
     747           0 :     SwNodeIndex aEndIdx( *pTNd->EndOfSectionNode() );
     748           0 :     rDoc.TableToText( pTNd, 0x0b == cTrenner ? 0x09 : cTrenner );
     749             : 
     750             :     // join again at start?
     751           0 :     SwPaM aPam(rDoc.GetNodes().GetEndOfContent());
     752           0 :     SwPosition *const pPos = aPam.GetPoint();
     753           0 :     if( nSttCntnt )
     754             :     {
     755           0 :         pPos->nNode = nTblNd;
     756           0 :         pPos->nContent.Assign(pPos->nNode.GetNode().GetCntntNode(), 0);
     757           0 :         if (aPam.Move(fnMoveBackward, fnGoCntnt))
     758             :         {
     759           0 :             SwNodeIndex & rIdx = aPam.GetPoint()->nNode;
     760             : 
     761             :             // than move, relatively, the Crsr/etc. again
     762           0 :             RemoveIdxRel( rIdx.GetIndex()+1, *pPos );
     763             : 
     764           0 :             rIdx.GetNode().GetCntntNode()->JoinNext();
     765             :         }
     766             :     }
     767             : 
     768             :     // join again at end?
     769           0 :     if( bSplitEnd )
     770             :     {
     771           0 :         SwNodeIndex& rIdx = pPos->nNode;
     772           0 :         rIdx = nEndNode;
     773           0 :         SwTxtNode* pTxtNd = rIdx.GetNode().GetTxtNode();
     774           0 :         if( pTxtNd && pTxtNd->CanJoinNext() )
     775             :         {
     776           0 :             aPam.GetMark()->nContent.Assign( 0, 0 );
     777           0 :             aPam.GetPoint()->nContent.Assign( 0, 0 );
     778             : 
     779             :             // than move, relatively, the Crsr/etc. again
     780           0 :             pPos->nContent.Assign(pTxtNd, pTxtNd->GetTxt().getLength());
     781           0 :             RemoveIdxRel( nEndNode + 1, *pPos );
     782             : 
     783           0 :             pTxtNd->JoinNext();
     784             :         }
     785             :     }
     786             : 
     787           0 :     AddUndoRedoPaM(rContext);
     788           0 : }
     789             : 
     790           0 : void SwUndoTxtToTbl::RedoImpl(::sw::UndoRedoContext & rContext)
     791             : {
     792           0 :     SwPaM & rPam( AddUndoRedoPaM(rContext) );
     793           0 :     RemoveIdxFromRange(rPam, false);
     794           0 :     SetPaM(rPam);
     795             : 
     796           0 :     SwTable const*const pTable = rContext.GetDoc().TextToTable(
     797           0 :                 aInsTblOpts, rPam, cTrenner, nAdjust, pAutoFmt );
     798           0 :     ((SwFrmFmt*)pTable->GetFrmFmt())->SetName( sTblNm );
     799           0 : }
     800             : 
     801           0 : void SwUndoTxtToTbl::RepeatImpl(::sw::RepeatContext & rContext)
     802             : {
     803             :     // no Table In Table
     804           0 :     if (!rContext.GetRepeatPaM().GetNode().FindTableNode())
     805             :     {
     806           0 :         rContext.GetDoc().TextToTable( aInsTblOpts, rContext.GetRepeatPaM(),
     807             :                                         cTrenner, nAdjust,
     808           0 :                                         pAutoFmt );
     809             :     }
     810           0 : }
     811             : 
     812           0 : void SwUndoTxtToTbl::AddFillBox( const SwTableBox& rBox )
     813             : {
     814           0 :     if( !pDelBoxes )
     815           0 :         pDelBoxes = new std::vector<sal_uLong>;
     816           0 :     pDelBoxes->push_back( rBox.GetSttIdx() );
     817           0 : }
     818             : 
     819           0 : SwHistory& SwUndoTxtToTbl::GetHistory()
     820             : {
     821           0 :     if( !pHistory )
     822           0 :         pHistory = new SwHistory;
     823           0 :     return *pHistory;
     824             : }
     825             : 
     826           2 : SwUndoTblHeadline::SwUndoTblHeadline( const SwTable& rTbl, sal_uInt16 nOldHdl,
     827             :                                       sal_uInt16 nNewHdl )
     828             :     : SwUndo( UNDO_TABLEHEADLINE ),
     829             :     nOldHeadline( nOldHdl ),
     830           2 :     nNewHeadline( nNewHdl )
     831             : {
     832             :     OSL_ENSURE( !rTbl.GetTabSortBoxes().empty(), "Table without content" );
     833           2 :     const SwStartNode *pSttNd = rTbl.GetTabSortBoxes()[ 0 ]->GetSttNd();
     834             :     OSL_ENSURE( pSttNd, "Box without content" );
     835             : 
     836           2 :     nTblNd = pSttNd->StartOfSectionIndex();
     837           2 : }
     838             : 
     839           0 : void SwUndoTblHeadline::UndoImpl(::sw::UndoRedoContext & rContext)
     840             : {
     841           0 :     SwDoc & rDoc = rContext.GetDoc();
     842           0 :     SwTableNode* pTNd = rDoc.GetNodes()[ nTblNd ]->GetTableNode();
     843             :     OSL_ENSURE( pTNd, "could not find any TableNode" );
     844             : 
     845           0 :     rDoc.SetRowsToRepeat( pTNd->GetTable(), nOldHeadline );
     846           0 : }
     847             : 
     848           0 : void SwUndoTblHeadline::RedoImpl(::sw::UndoRedoContext & rContext)
     849             : {
     850           0 :     SwDoc & rDoc = rContext.GetDoc();
     851             : 
     852           0 :     SwTableNode* pTNd = rDoc.GetNodes()[ nTblNd ]->GetTableNode();
     853             :     OSL_ENSURE( pTNd, "could not find any TableNode" );
     854             : 
     855           0 :     rDoc.SetRowsToRepeat( pTNd->GetTable(), nNewHeadline );
     856           0 : }
     857             : 
     858           0 : void SwUndoTblHeadline::RepeatImpl(::sw::RepeatContext & rContext)
     859             : {
     860             :     SwTableNode *const pTblNd =
     861           0 :         rContext.GetRepeatPaM().GetNode().FindTableNode();
     862           0 :     if( pTblNd )
     863             :     {
     864           0 :         rContext.GetDoc().SetRowsToRepeat( pTblNd->GetTable(), nNewHeadline );
     865             :     }
     866           0 : }
     867             : 
     868          32 : _SaveTable::_SaveTable( const SwTable& rTbl, sal_uInt16 nLnCnt, bool bSaveFml )
     869          32 :     : aTblSet( *rTbl.GetFrmFmt()->GetAttrSet().GetPool(), aTableSetRange ),
     870          32 :     pSwTable( &rTbl ), nLineCount( nLnCnt ), bSaveFormula( bSaveFml )
     871             : {
     872          32 :     bModifyBox = false;
     873          32 :     bNewModel = rTbl.IsNewModel();
     874          32 :     aTblSet.Put( rTbl.GetFrmFmt()->GetAttrSet() );
     875          32 :     pLine = new _SaveLine( 0, *rTbl.GetTabLines()[ 0 ], *this );
     876             : 
     877          32 :     _SaveLine* pLn = pLine;
     878          32 :     if( USHRT_MAX == nLnCnt )
     879          32 :         nLnCnt = rTbl.GetTabLines().size();
     880         106 :     for( sal_uInt16 n = 1; n < nLnCnt; ++n )
     881          74 :         pLn = new _SaveLine( pLn, *rTbl.GetTabLines()[ n ], *this );
     882             : 
     883          32 :     aFrmFmts.clear();
     884          32 :     pSwTable = 0;
     885          32 : }
     886             : 
     887          64 : _SaveTable::~_SaveTable()
     888             : {
     889          32 :     delete pLine;
     890          32 : }
     891             : 
     892         336 : sal_uInt16 _SaveTable::AddFmt( SwFrmFmt* pFmt, bool bIsLine )
     893             : {
     894         336 :     sal_uInt16 nRet = aFrmFmts.GetPos( pFmt );
     895         336 :     if( USHRT_MAX == nRet )
     896             :     {
     897             :         // Create copy of ItemSet
     898         202 :         boost::shared_ptr<SfxItemSet> pSet( new SfxItemSet( *pFmt->GetAttrSet().GetPool(),
     899         202 :             bIsLine ? aTableLineSetRange : aTableBoxSetRange ) );
     900         202 :         pSet->Put( pFmt->GetAttrSet() );
     901             :         // When a formula is set, never save the value. It possibly must be
     902             :         // recalculated.
     903             :         // Save formulas always in plain text.
     904             :         const SfxPoolItem* pItem;
     905         202 :         if( SfxItemState::SET == pSet->GetItemState( RES_BOXATR_FORMULA, true, &pItem ))
     906             :         {
     907           0 :             pSet->ClearItem( RES_BOXATR_VALUE );
     908           0 :             if( pSwTable && bSaveFormula )
     909             :             {
     910           0 :                 SwTableFmlUpdate aMsgHnt( pSwTable );
     911           0 :                 aMsgHnt.eFlags = TBL_BOXNAME;
     912           0 :                 ((SwTblBoxFormula*)pItem)->ChgDefinedIn( pFmt );
     913           0 :                 ((SwTblBoxFormula*)pItem)->ChangeState( &aMsgHnt );
     914           0 :                 ((SwTblBoxFormula*)pItem)->ChgDefinedIn( 0 );
     915             :             }
     916             :         }
     917         202 :         nRet = aSets.size();
     918         202 :         aSets.push_back( pSet );
     919         202 :         aFrmFmts.insert( aFrmFmts.begin() + nRet, pFmt );
     920             :     }
     921         336 :     return nRet;
     922             : }
     923             : 
     924           0 : void _SaveTable::RestoreAttr( SwTable& rTbl, bool bMdfyBox )
     925             : {
     926           0 :     bModifyBox = bMdfyBox;
     927             : 
     928             :     // first, get back attributes of TableFrmFormat
     929           0 :     SwFrmFmt* pFmt = rTbl.GetFrmFmt();
     930           0 :     SfxItemSet& rFmtSet  = (SfxItemSet&)pFmt->GetAttrSet();
     931           0 :     rFmtSet.ClearItem();
     932           0 :     rFmtSet.Put( aTblSet );
     933             : 
     934           0 :     if( pFmt->IsInCache() )
     935             :     {
     936           0 :         SwFrm::GetCache().Delete( pFmt );
     937           0 :         pFmt->SetInCache( false );
     938             :     }
     939             : 
     940             :     // for safety, invalidate all TableFrames
     941           0 :     SwIterator<SwTabFrm,SwFmt> aIter( *pFmt );
     942           0 :     for( SwTabFrm* pLast = aIter.First(); pLast; pLast = aIter.Next() )
     943           0 :         if( pLast->GetTable() == &rTbl )
     944             :         {
     945           0 :             pLast->InvalidateAll();
     946           0 :             pLast->SetCompletePaint();
     947             :         }
     948             : 
     949             :     // fill FrmFmts with defaults (0)
     950           0 :     pFmt = 0;
     951           0 :     for( size_t n = aSets.size(); n; --n )
     952           0 :         aFrmFmts.push_back( pFmt );
     953             : 
     954           0 :     const size_t nLnCnt = ( USHRT_MAX == nLineCount )
     955           0 :         ? rTbl.GetTabLines().size()
     956           0 :         : nLineCount;
     957             : 
     958           0 :     _SaveLine* pLn = pLine;
     959           0 :     for( size_t n = 0; n < nLnCnt; ++n, pLn = pLn->pNext )
     960             :     {
     961           0 :         if( !pLn )
     962             :         {
     963             :             OSL_ENSURE( false, "Number of lines changed" );
     964           0 :             break;
     965             :         }
     966             : 
     967           0 :         pLn->RestoreAttr( *rTbl.GetTabLines()[ n ], *this );
     968             :     }
     969             : 
     970           0 :     aFrmFmts.clear();
     971           0 :     bModifyBox = false;
     972           0 : }
     973             : 
     974           0 : void _SaveTable::SaveCntntAttrs( SwDoc* pDoc )
     975             : {
     976           0 :     pLine->SaveCntntAttrs( pDoc );
     977           0 : }
     978             : 
     979           0 : void _SaveTable::CreateNew( SwTable& rTbl, bool bCreateFrms,
     980             :                             bool bRestoreChart )
     981             : {
     982           0 :     _FndBox aTmpBox( 0, 0 );
     983           0 :     aTmpBox.DelFrms( rTbl );
     984             : 
     985             :     // first, get back attributes of TableFrmFormat
     986           0 :     SwFrmFmt* pFmt = rTbl.GetFrmFmt();
     987           0 :     SfxItemSet& rFmtSet  = (SfxItemSet&)pFmt->GetAttrSet();
     988           0 :     rFmtSet.ClearItem();
     989           0 :     rFmtSet.Put( aTblSet );
     990             : 
     991           0 :     if( pFmt->IsInCache() )
     992             :     {
     993           0 :         SwFrm::GetCache().Delete( pFmt );
     994           0 :         pFmt->SetInCache( false );
     995             :     }
     996             : 
     997             :     // SwTableBox must have a format
     998           0 :     SwTableBox aParent( (SwTableBoxFmt*)pFmt, rTbl.GetTabLines().size(), 0 );
     999             : 
    1000             :     // fill FrmFmts with defaults (0)
    1001           0 :     pFmt = 0;
    1002           0 :     for( size_t n = aSets.size(); n; --n )
    1003           0 :         aFrmFmts.push_back( pFmt );
    1004             : 
    1005           0 :     pLine->CreateNew( rTbl, aParent, *this );
    1006           0 :     aFrmFmts.clear();
    1007             : 
    1008             :     // add new lines, delete old ones
    1009           0 :     const size_t nOldLines = ( USHRT_MAX == nLineCount )
    1010           0 :         ? rTbl.GetTabLines().size()
    1011           0 :         : nLineCount;
    1012             : 
    1013           0 :     SwDoc *pDoc = rTbl.GetFrmFmt()->GetDoc();
    1014           0 :     SwChartDataProvider *pPCD = pDoc->getIDocumentChartDataProviderAccess().GetChartDataProvider();
    1015           0 :     size_t n = 0;
    1016           0 :     for( ; n < aParent.GetTabLines().size(); ++n )
    1017             :     {
    1018           0 :         SwTableLine* pLn = aParent.GetTabLines()[ n ];
    1019           0 :         pLn->SetUpper( 0 );
    1020           0 :         if( n < nOldLines )
    1021             :         {
    1022           0 :             SwTableLine* pOld = rTbl.GetTabLines()[ n ];
    1023             : 
    1024             :             // TL_CHART2: notify chart about boxes to be removed
    1025           0 :             const SwTableBoxes &rBoxes = pOld->GetTabBoxes();
    1026           0 :             const size_t nBoxes = rBoxes.size();
    1027           0 :             for (size_t k = 0; k < nBoxes;  ++k)
    1028             :             {
    1029           0 :                 SwTableBox *pBox = rBoxes[k];
    1030           0 :                 if (pPCD)
    1031           0 :                     pPCD->DeleteBox( &rTbl, *pBox );
    1032             :             }
    1033             : 
    1034           0 :             rTbl.GetTabLines()[n] = pLn;
    1035           0 :             delete pOld;
    1036             :         }
    1037             :         else
    1038           0 :             rTbl.GetTabLines().insert( rTbl.GetTabLines().begin() + n, pLn );
    1039             :     }
    1040             : 
    1041           0 :     if( n < nOldLines )
    1042             :     {
    1043             :         // remove remaining lines...
    1044           0 :         for (size_t k1 = 0; k1 < nOldLines - n; ++k1)
    1045             :         {
    1046           0 :             const SwTableBoxes &rBoxes = rTbl.GetTabLines()[n + k1]->GetTabBoxes();
    1047           0 :             const size_t nBoxes = rBoxes.size();
    1048           0 :             for (size_t k2 = 0; k2 < nBoxes; ++k2)
    1049             :             {
    1050           0 :                 SwTableBox *pBox = rBoxes[k2];
    1051             :                 // TL_CHART2: notify chart about boxes to be removed
    1052           0 :                 if (pPCD)
    1053           0 :                     pPCD->DeleteBox( &rTbl, *pBox );
    1054             :             }
    1055             :         }
    1056             : 
    1057             : #ifdef _MSC_VER
    1058             : // MSVC 2012 appears very confused and rambles about a declaration of "n" below
    1059             : #pragma warning (push, 1)
    1060             : #pragma warning (disable: 4258)
    1061             : #endif
    1062           0 :         for( SwTableLines::const_iterator it = rTbl.GetTabLines().begin() + n;
    1063           0 :              it != rTbl.GetTabLines().begin() + nOldLines; ++it )
    1064           0 :             delete *it;
    1065           0 :         rTbl.GetTabLines().erase( rTbl.GetTabLines().begin() + n, rTbl.GetTabLines().begin() + nOldLines );
    1066             : #ifdef _MSC_VER
    1067             : #pragma warning (pop)
    1068             : #endif
    1069             :     }
    1070             : 
    1071           0 :     aParent.GetTabLines().erase( aParent.GetTabLines().begin(), aParent.GetTabLines().begin() + n );
    1072             : 
    1073           0 :     if( bCreateFrms )
    1074           0 :         aTmpBox.MakeFrms( rTbl );
    1075           0 :     if( bRestoreChart )
    1076             :     {
    1077             :         // TL_CHART2: need to inform chart of probably changed cell names
    1078           0 :         pDoc->UpdateCharts( rTbl.GetFrmFmt()->GetName() );
    1079           0 :     }
    1080           0 : }
    1081             : 
    1082           0 : void _SaveTable::NewFrmFmt( const SwTableLine* pTblLn, const SwTableBox* pTblBx,
    1083             :                             sal_uInt16 nFmtPos, SwFrmFmt* pOldFmt )
    1084             : {
    1085           0 :     SwDoc* pDoc = pOldFmt->GetDoc();
    1086             : 
    1087           0 :     SwFrmFmt* pFmt = aFrmFmts[ nFmtPos ];
    1088           0 :     if( !pFmt )
    1089             :     {
    1090           0 :         if( pTblLn )
    1091           0 :             pFmt = pDoc->MakeTableLineFmt();
    1092             :         else
    1093           0 :             pFmt = pDoc->MakeTableBoxFmt();
    1094           0 :         pFmt->SetFmtAttr( *aSets[ nFmtPos ] );
    1095           0 :         aFrmFmts[nFmtPos] = pFmt;
    1096             :     }
    1097             : 
    1098             :     // first re-assign Frms
    1099           0 :     SwIterator<SwTabFrm,SwFmt> aIter( *pOldFmt );
    1100           0 :     for( SwFrm* pLast = aIter.First(); pLast; pLast = aIter.Next() )
    1101             :     {
    1102           0 :         if( pTblLn ? ((SwRowFrm*)pLast)->GetTabLine() == pTblLn
    1103           0 :                     : ((SwCellFrm*)pLast)->GetTabBox() == pTblBx )
    1104             :         {
    1105           0 :             pLast->RegisterToFormat(*pFmt);
    1106           0 :             pLast->InvalidateAll();
    1107           0 :             pLast->ReinitializeFrmSizeAttrFlags();
    1108           0 :             if ( !pTblLn )
    1109             :             {
    1110           0 :                 ((SwCellFrm*)pLast)->SetDerivedVert( false );
    1111           0 :                 ((SwCellFrm*)pLast)->CheckDirChange();
    1112             :             }
    1113             :         }
    1114             :     }
    1115             : 
    1116             :     // than re-assign myself
    1117           0 :     if ( pTblLn )
    1118           0 :         const_cast<SwTableLine*>(pTblLn)->RegisterToFormat( *pFmt );
    1119           0 :     else if ( pTblBx )
    1120           0 :         const_cast<SwTableBox*>(pTblBx)->RegisterToFormat( *pFmt );
    1121             : 
    1122           0 :     if( bModifyBox && !pTblLn )
    1123             :     {
    1124           0 :         const SfxPoolItem& rOld = pOldFmt->GetFmtAttr( RES_BOXATR_FORMAT ),
    1125           0 :                          & rNew = pFmt->GetFmtAttr( RES_BOXATR_FORMAT );
    1126           0 :         if( rOld != rNew )
    1127           0 :             pFmt->ModifyNotification( (SfxPoolItem*)&rOld, (SfxPoolItem*)&rNew );
    1128             :     }
    1129             : 
    1130           0 :     if( !pOldFmt->GetDepends() )
    1131           0 :         delete pOldFmt;
    1132           0 : }
    1133             : 
    1134         106 : _SaveLine::_SaveLine( _SaveLine* pPrev, const SwTableLine& rLine, _SaveTable& rSTbl )
    1135         106 :     : pNext( 0 )
    1136             : {
    1137         106 :     if( pPrev )
    1138          74 :         pPrev->pNext = this;
    1139             : 
    1140         106 :     nItemSet = rSTbl.AddFmt( rLine.GetFrmFmt(), true );
    1141             : 
    1142         106 :     pBox = new _SaveBox( 0, *rLine.GetTabBoxes()[ 0 ], rSTbl );
    1143         106 :     _SaveBox* pBx = pBox;
    1144         230 :     for( size_t n = 1; n < rLine.GetTabBoxes().size(); ++n )
    1145         124 :         pBx = new _SaveBox( pBx, *rLine.GetTabBoxes()[ n ], rSTbl );
    1146         106 : }
    1147             : 
    1148         106 : _SaveLine::~_SaveLine()
    1149             : {
    1150         106 :     delete pBox;
    1151         106 :     delete pNext;
    1152         106 : }
    1153             : 
    1154           0 : void _SaveLine::RestoreAttr( SwTableLine& rLine, _SaveTable& rSTbl )
    1155             : {
    1156           0 :     rSTbl.NewFrmFmt( &rLine, 0, nItemSet, rLine.GetFrmFmt() );
    1157             : 
    1158           0 :     _SaveBox* pBx = pBox;
    1159           0 :     for( size_t n = 0; n < rLine.GetTabBoxes().size(); ++n, pBx = pBx->pNext )
    1160             :     {
    1161           0 :         if( !pBx )
    1162             :         {
    1163             :             OSL_ENSURE( false, "Number of boxes changed" );
    1164           0 :             break;
    1165             :         }
    1166           0 :         pBx->RestoreAttr( *rLine.GetTabBoxes()[ n ], rSTbl );
    1167             :     }
    1168           0 : }
    1169             : 
    1170           0 : void _SaveLine::SaveCntntAttrs( SwDoc* pDoc )
    1171             : {
    1172           0 :     pBox->SaveCntntAttrs( pDoc );
    1173           0 :     if( pNext )
    1174           0 :         pNext->SaveCntntAttrs( pDoc );
    1175           0 : }
    1176             : 
    1177           0 : void _SaveLine::CreateNew( SwTable& rTbl, SwTableBox& rParent, _SaveTable& rSTbl )
    1178             : {
    1179           0 :     SwTableLineFmt* pFmt = (SwTableLineFmt*)rSTbl.aFrmFmts[ nItemSet ];
    1180           0 :     if( !pFmt )
    1181             :     {
    1182           0 :         SwDoc* pDoc = rTbl.GetFrmFmt()->GetDoc();
    1183           0 :         pFmt = pDoc->MakeTableLineFmt();
    1184           0 :         pFmt->SetFmtAttr( *rSTbl.aSets[ nItemSet ] );
    1185           0 :         rSTbl.aFrmFmts[ nItemSet ] = pFmt;
    1186             :     }
    1187           0 :     SwTableLine* pNew = new SwTableLine( pFmt, 1, &rParent );
    1188             : 
    1189           0 :     rParent.GetTabLines().push_back( pNew );
    1190             : 
    1191             :     // HB, #127868# robustness: in some cases - which I
    1192             :     // cannot reproduce nor see from the code - pNew seems
    1193             :     // to be set to NULL in C40_INSERT.
    1194             :     OSL_ENSURE(pNew, "Table line just created set to NULL in C40_INSERT");
    1195             : 
    1196           0 :     if (pNew)
    1197             :     {
    1198           0 :         pBox->CreateNew( rTbl, *pNew, rSTbl );
    1199             :     }
    1200             : 
    1201           0 :     if( pNext )
    1202           0 :         pNext->CreateNew( rTbl, rParent, rSTbl );
    1203           0 : }
    1204             : 
    1205         230 : _SaveBox::_SaveBox( _SaveBox* pPrev, const SwTableBox& rBox, _SaveTable& rSTbl )
    1206         230 :     : pNext( 0 ), nSttNode( ULONG_MAX ), nRowSpan(0)
    1207             : {
    1208         230 :     Ptrs.pLine = 0;
    1209             : 
    1210         230 :     if( pPrev )
    1211         124 :         pPrev->pNext = this;
    1212             : 
    1213         230 :     nItemSet = rSTbl.AddFmt( rBox.GetFrmFmt(), false );
    1214             : 
    1215         230 :     if( rBox.GetSttNd() )
    1216             :     {
    1217         230 :         nSttNode = rBox.GetSttIdx();
    1218         230 :         nRowSpan = rBox.getRowSpan();
    1219             :     }
    1220             :     else
    1221             :     {
    1222           0 :         Ptrs.pLine = new _SaveLine( 0, *rBox.GetTabLines()[ 0 ], rSTbl );
    1223             : 
    1224           0 :         _SaveLine* pLn = Ptrs.pLine;
    1225           0 :         for( size_t n = 1; n < rBox.GetTabLines().size(); ++n )
    1226           0 :             pLn = new _SaveLine( pLn, *rBox.GetTabLines()[ n ], rSTbl );
    1227             :     }
    1228         230 : }
    1229             : 
    1230         230 : _SaveBox::~_SaveBox()
    1231             : {
    1232         230 :     if( ULONG_MAX == nSttNode )     // no EndBox
    1233           0 :         delete Ptrs.pLine;
    1234             :     else
    1235         230 :         delete Ptrs.pCntntAttrs;
    1236         230 :     delete pNext;
    1237         230 : }
    1238             : 
    1239           0 : void _SaveBox::RestoreAttr( SwTableBox& rBox, _SaveTable& rSTbl )
    1240             : {
    1241           0 :     rSTbl.NewFrmFmt( 0, &rBox, nItemSet, rBox.GetFrmFmt() );
    1242             : 
    1243           0 :     if( ULONG_MAX == nSttNode )     // no EndBox
    1244             :     {
    1245           0 :         if( !rBox.GetTabLines().size() )
    1246             :         {
    1247             :             OSL_ENSURE( false, "Number of lines changed" );
    1248             :         }
    1249             :         else
    1250             :         {
    1251           0 :             _SaveLine* pLn = Ptrs.pLine;
    1252           0 :             for( size_t n = 0; n < rBox.GetTabLines().size(); ++n, pLn = pLn->pNext )
    1253             :             {
    1254           0 :                 if( !pLn )
    1255             :                 {
    1256             :                     OSL_ENSURE( false, "Number of lines changed" );
    1257           0 :                     break;
    1258             :                 }
    1259             : 
    1260           0 :                 pLn->RestoreAttr( *rBox.GetTabLines()[ n ], rSTbl );
    1261             :             }
    1262             :         }
    1263             :     }
    1264           0 :     else if( rBox.GetSttNd() && rBox.GetSttIdx() == nSttNode )
    1265             :     {
    1266           0 :         if( Ptrs.pCntntAttrs )
    1267             :         {
    1268           0 :             SwNodes& rNds = rBox.GetFrmFmt()->GetDoc()->GetNodes();
    1269           0 :             sal_uInt16 nSet = 0;
    1270           0 :             sal_uLong nEnd = rBox.GetSttNd()->EndOfSectionIndex();
    1271           0 :             for( sal_uLong n = nSttNode + 1; n < nEnd; ++n )
    1272             :             {
    1273           0 :                 SwCntntNode* pCNd = rNds[ n ]->GetCntntNode();
    1274           0 :                 if( pCNd )
    1275             :                 {
    1276           0 :                     boost::shared_ptr<SfxItemSet> pSet( (*Ptrs.pCntntAttrs)[ nSet++ ] );
    1277           0 :                     if( pSet )
    1278             :                     {
    1279           0 :                         sal_uInt16 *pRstAttr = aSave_BoxCntntSet;
    1280           0 :                         while( *pRstAttr )
    1281             :                         {
    1282           0 :                             pCNd->ResetAttr( *pRstAttr, *(pRstAttr+1) );
    1283           0 :                             pRstAttr += 2;
    1284             :                         }
    1285           0 :                         pCNd->SetAttr( *pSet );
    1286             :                     }
    1287             :                     else
    1288           0 :                         pCNd->ResetAllAttr();
    1289             :                 }
    1290             :             }
    1291             :         }
    1292             :     }
    1293             :     else
    1294             :     {
    1295             :         OSL_ENSURE( false, "Box not anymore at the same node" );
    1296             :     }
    1297           0 : }
    1298             : 
    1299           0 : void _SaveBox::SaveCntntAttrs( SwDoc* pDoc )
    1300             : {
    1301           0 :     if( ULONG_MAX == nSttNode )     // no EndBox
    1302             :     {
    1303             :         // continue in current line
    1304           0 :         Ptrs.pLine->SaveCntntAttrs( pDoc );
    1305             :     }
    1306             :     else
    1307             :     {
    1308           0 :         sal_uLong nEnd = pDoc->GetNodes()[ nSttNode ]->EndOfSectionIndex();
    1309           0 :         Ptrs.pCntntAttrs = new SfxItemSets( (sal_uInt8)(nEnd - nSttNode - 1 ) );
    1310           0 :         for( sal_uLong n = nSttNode + 1; n < nEnd; ++n )
    1311             :         {
    1312           0 :             SwCntntNode* pCNd = pDoc->GetNodes()[ n ]->GetCntntNode();
    1313           0 :             if( pCNd )
    1314             :             {
    1315           0 :                 boost::shared_ptr<SfxItemSet> pSet;
    1316           0 :                 if( pCNd->HasSwAttrSet() )
    1317             :                 {
    1318           0 :                     pSet.reset( new SfxItemSet( pDoc->GetAttrPool(),
    1319           0 :                                             aSave_BoxCntntSet ) );
    1320           0 :                     pSet->Put( *pCNd->GetpSwAttrSet() );
    1321             :                 }
    1322             : 
    1323           0 :                 Ptrs.pCntntAttrs->push_back( pSet );
    1324             :             }
    1325             :         }
    1326             :     }
    1327           0 :     if( pNext )
    1328           0 :         pNext->SaveCntntAttrs( pDoc );
    1329           0 : }
    1330             : 
    1331           0 : void _SaveBox::CreateNew( SwTable& rTbl, SwTableLine& rParent, _SaveTable& rSTbl )
    1332             : {
    1333           0 :     SwTableBoxFmt* pFmt = (SwTableBoxFmt*)rSTbl.aFrmFmts[ nItemSet ];
    1334           0 :     if( !pFmt )
    1335             :     {
    1336           0 :         SwDoc* pDoc = rTbl.GetFrmFmt()->GetDoc();
    1337           0 :         pFmt = pDoc->MakeTableBoxFmt();
    1338           0 :         pFmt->SetFmtAttr( *rSTbl.aSets[ nItemSet ] );
    1339           0 :         rSTbl.aFrmFmts[nItemSet] = pFmt;
    1340             :     }
    1341             : 
    1342           0 :     if( ULONG_MAX == nSttNode )     // no EndBox
    1343             :     {
    1344           0 :         SwTableBox* pNew = new SwTableBox( pFmt, 1, &rParent );
    1345           0 :         rParent.GetTabBoxes().push_back( pNew );
    1346             : 
    1347           0 :         Ptrs.pLine->CreateNew( rTbl, *pNew, rSTbl );
    1348             :     }
    1349             :     else
    1350             :     {
    1351             :         // search box for StartNode in old table
    1352           0 :         SwTableBox* pBox = rTbl.GetTblBox( nSttNode );
    1353             :         OSL_ENSURE( pBox, "Where is my TableBox?" );
    1354             : 
    1355           0 :         SwFrmFmt* pOld = pBox->GetFrmFmt();
    1356           0 :         pBox->RegisterToFormat( *pFmt );
    1357           0 :         if( !pOld->GetDepends() )
    1358           0 :             delete pOld;
    1359             : 
    1360           0 :         pBox->setRowSpan( nRowSpan );
    1361             : 
    1362           0 :         SwTableBoxes* pTBoxes = &pBox->GetUpper()->GetTabBoxes();
    1363           0 :         pTBoxes->erase( std::find( pTBoxes->begin(), pTBoxes->end(), pBox ) );
    1364             : 
    1365           0 :         pBox->SetUpper( &rParent );
    1366           0 :         pTBoxes = &rParent.GetTabBoxes();
    1367           0 :         pTBoxes->push_back( pBox );
    1368             :     }
    1369             : 
    1370           0 :     if( pNext )
    1371           0 :         pNext->CreateNew( rTbl, rParent, rSTbl );
    1372           0 : }
    1373             : 
    1374             : // UndoObject for attribute changes on table
    1375          18 : SwUndoAttrTbl::SwUndoAttrTbl( const SwTableNode& rTblNd, bool bClearTabCols )
    1376             :     : SwUndo( UNDO_TABLE_ATTR ),
    1377          18 :     nSttNode( rTblNd.GetIndex() )
    1378             : {
    1379          18 :     bClearTabCol = bClearTabCols;
    1380          18 :     pSaveTbl = new _SaveTable( rTblNd.GetTable() );
    1381          18 : }
    1382             : 
    1383          54 : SwUndoAttrTbl::~SwUndoAttrTbl()
    1384             : {
    1385          18 :     delete pSaveTbl;
    1386          36 : }
    1387             : 
    1388           0 : void SwUndoAttrTbl::UndoImpl(::sw::UndoRedoContext & rContext)
    1389             : {
    1390           0 :     SwDoc & rDoc = rContext.GetDoc();
    1391           0 :     SwTableNode* pTblNd = rDoc.GetNodes()[ nSttNode ]->GetTableNode();
    1392             :     OSL_ENSURE( pTblNd, "no TableNode" );
    1393             : 
    1394           0 :     if (pTblNd)
    1395             :     {
    1396           0 :         _SaveTable* pOrig = new _SaveTable( pTblNd->GetTable() );
    1397           0 :         pSaveTbl->RestoreAttr( pTblNd->GetTable() );
    1398           0 :         delete pSaveTbl;
    1399           0 :         pSaveTbl = pOrig;
    1400             :     }
    1401             : 
    1402           0 :     if( bClearTabCol )
    1403           0 :         ClearFEShellTabCols();
    1404           0 : }
    1405             : 
    1406           0 : void SwUndoAttrTbl::RedoImpl(::sw::UndoRedoContext & rContext)
    1407             : {
    1408           0 :     UndoImpl(rContext);
    1409           0 : }
    1410             : 
    1411             : // UndoObject for AutoFormat on Table
    1412           0 : SwUndoTblAutoFmt::SwUndoTblAutoFmt( const SwTableNode& rTblNd,
    1413             :                                     const SwTableAutoFmt& rAFmt )
    1414             :     : SwUndo( UNDO_TABLE_AUTOFMT ),
    1415           0 :     nSttNode( rTblNd.GetIndex() ),
    1416             :     bSaveCntntAttr( false )
    1417           0 :     , m_nRepeatHeading(rTblNd.GetTable().GetRowsToRepeat())
    1418             : {
    1419           0 :     pSaveTbl = new _SaveTable( rTblNd.GetTable() );
    1420             : 
    1421           0 :     if( rAFmt.IsFont() || rAFmt.IsJustify() )
    1422             :     {
    1423             :         // than also go over the ContentNodes of the EndBoxes and collect
    1424             :         // all paragraph attributes
    1425           0 :         pSaveTbl->SaveCntntAttrs( (SwDoc*)rTblNd.GetDoc() );
    1426           0 :         bSaveCntntAttr = true;
    1427             :     }
    1428           0 : }
    1429             : 
    1430           0 : SwUndoTblAutoFmt::~SwUndoTblAutoFmt()
    1431             : {
    1432           0 :     delete pSaveTbl;
    1433           0 : }
    1434             : 
    1435           0 : void SwUndoTblAutoFmt::SaveBoxCntnt( const SwTableBox& rBox )
    1436             : {
    1437           0 :     ::boost::shared_ptr<SwUndoTblNumFmt> const p(new SwUndoTblNumFmt(rBox));
    1438           0 :     m_Undos.push_back(p);
    1439           0 : }
    1440             : 
    1441             : void
    1442           0 : SwUndoTblAutoFmt::UndoRedo(bool const bUndo, ::sw::UndoRedoContext & rContext)
    1443             : {
    1444           0 :     SwDoc & rDoc = rContext.GetDoc();
    1445           0 :     SwTableNode* pTblNd = rDoc.GetNodes()[ nSttNode ]->GetTableNode();
    1446             :     OSL_ENSURE( pTblNd, "no TableNode" );
    1447             : 
    1448           0 :     SwTable& table = pTblNd->GetTable();
    1449           0 :     _SaveTable* pOrig = new _SaveTable( table );
    1450             :     // than go also over the ContentNodes of the EndBoxes and collect
    1451             :     // all paragraph attributes
    1452           0 :     if( bSaveCntntAttr )
    1453           0 :         pOrig->SaveCntntAttrs( &rDoc );
    1454             : 
    1455           0 :     if (bUndo)
    1456             :     {
    1457           0 :         for (size_t n = m_Undos.size(); 0 < n; --n)
    1458             :         {
    1459           0 :             m_Undos.at(n-1)->UndoImpl(rContext);
    1460             :         }
    1461             : 
    1462           0 :         table.SetRowsToRepeat(m_nRepeatHeading);
    1463             :     }
    1464             : 
    1465           0 :     pSaveTbl->RestoreAttr( pTblNd->GetTable(), !bUndo );
    1466           0 :     delete pSaveTbl;
    1467           0 :     pSaveTbl = pOrig;
    1468           0 : }
    1469             : 
    1470           0 : void SwUndoTblAutoFmt::UndoImpl(::sw::UndoRedoContext & rContext)
    1471             : {
    1472           0 :     UndoRedo(true, rContext);
    1473           0 : }
    1474             : 
    1475           0 : void SwUndoTblAutoFmt::RedoImpl(::sw::UndoRedoContext & rContext)
    1476             : {
    1477           0 :     UndoRedo(false, rContext);
    1478           0 : }
    1479             : 
    1480          12 : SwUndoTblNdsChg::SwUndoTblNdsChg( SwUndoId nAction,
    1481             :                                     const SwSelBoxes& rBoxes,
    1482             :                                     const SwTableNode& rTblNd,
    1483             :                                     long nMn, long nMx,
    1484             :                                     sal_uInt16 nCnt, bool bFlg, bool bSmHght )
    1485             :     : SwUndo( nAction ),
    1486             :     nMin( nMn ), nMax( nMx ),
    1487          12 :     nSttNode( rTblNd.GetIndex() ), nCurrBox( 0 ),
    1488             :     nCount( nCnt ), nRelDiff( 0 ), nAbsDiff( 0 ),
    1489             :     nSetColType( USHRT_MAX ),
    1490             :     bFlag( bFlg ),
    1491          24 :     bSameHeight( bSmHght )
    1492             : {
    1493          12 :     const SwTable& rTbl = rTblNd.GetTable();
    1494          12 :     pSaveTbl = new _SaveTable( rTbl );
    1495             : 
    1496             :     // and remember selection
    1497          12 :     ReNewBoxes( rBoxes );
    1498          12 : }
    1499             : 
    1500           0 : SwUndoTblNdsChg::SwUndoTblNdsChg( SwUndoId nAction,
    1501             :                                     const SwSelBoxes& rBoxes,
    1502             :                                     const SwTableNode& rTblNd )
    1503             :     : SwUndo( nAction ),
    1504             :     nMin( 0 ), nMax( 0 ),
    1505           0 :     nSttNode( rTblNd.GetIndex() ), nCurrBox( 0 ),
    1506             :     nCount( 0 ), nRelDiff( 0 ), nAbsDiff( 0 ),
    1507             :     nSetColType( USHRT_MAX ),
    1508             :     bFlag( false ),
    1509           0 :     bSameHeight( false )
    1510             : {
    1511           0 :     const SwTable& rTbl = rTblNd.GetTable();
    1512           0 :     pSaveTbl = new _SaveTable( rTbl );
    1513             : 
    1514             :     // and remember selection
    1515           0 :     ReNewBoxes( rBoxes );
    1516           0 : }
    1517             : 
    1518          14 : void SwUndoTblNdsChg::ReNewBoxes( const SwSelBoxes& rBoxes )
    1519             : {
    1520          14 :     if (rBoxes.size() != m_Boxes.size())
    1521             :     {
    1522          12 :         m_Boxes.clear();
    1523          34 :         for (size_t n = 0; n < rBoxes.size(); ++n)
    1524             :         {
    1525          22 :             m_Boxes.insert( rBoxes[n]->GetSttIdx() );
    1526             :         }
    1527             :     }
    1528          14 : }
    1529             : 
    1530          36 : SwUndoTblNdsChg::~SwUndoTblNdsChg()
    1531             : {
    1532          12 :     delete pSaveTbl;
    1533          24 : }
    1534             : 
    1535           8 : void SwUndoTblNdsChg::SaveNewBoxes( const SwTableNode& rTblNd,
    1536             :                                     const SwTableSortBoxes& rOld )
    1537             : {
    1538           8 :     const SwTable& rTbl = rTblNd.GetTable();
    1539           8 :     const SwTableSortBoxes& rTblBoxes = rTbl.GetTabSortBoxes();
    1540             : 
    1541             :     OSL_ENSURE( ! IsDelBox(), "wrong Action" );
    1542           8 :     pNewSttNds.reset( new std::set<_BoxMove> );
    1543             : 
    1544           8 :     size_t i = 0;
    1545          37 :     for (size_t  n = 0; n < rOld.size(); ++i)
    1546             :     {
    1547          29 :         if( rOld[ n ] == rTblBoxes[ i ] )
    1548          20 :             ++n;
    1549             :         else
    1550             :             // new box: insert sorted
    1551           9 :             pNewSttNds->insert( _BoxMove(rTblBoxes[ i ]->GetSttIdx()) );
    1552             :     }
    1553             : 
    1554          15 :     for( ; i < rTblBoxes.size(); ++i )
    1555             :         // new box: insert sorted
    1556           7 :         pNewSttNds->insert( _BoxMove(rTblBoxes[ i ]->GetSttIdx()) );
    1557           8 : }
    1558             : 
    1559           0 : static SwTableLine* lcl_FindTableLine( const SwTable& rTable,
    1560             :                                 const SwTableBox& rBox )
    1561             : {
    1562           0 :     SwTableLine* pRet = NULL;
    1563             :     // i63949: For nested cells we have to take nLineNo - 1, too, not 0!
    1564           0 :     const SwTableLines &rTableLines = ( rBox.GetUpper()->GetUpper() != NULL ) ?
    1565           0 :                                   rBox.GetUpper()->GetUpper()->GetTabLines()
    1566           0 :                                 : rTable.GetTabLines();
    1567           0 :     const SwTableLine* pLine = rBox.GetUpper();
    1568           0 :     sal_uInt16 nLineNo = rTableLines.GetPos( pLine );
    1569           0 :     pRet = rTableLines[nLineNo - 1];
    1570             : 
    1571           0 :     return pRet;
    1572             : }
    1573             : 
    1574           4 : static const SwTableLines& lcl_FindParentLines( const SwTable& rTable,
    1575             :                                        const SwTableBox& rBox )
    1576             : {
    1577             :     const SwTableLines& rRet =
    1578           4 :         ( rBox.GetUpper()->GetUpper() != NULL ) ?
    1579           0 :             rBox.GetUpper()->GetUpper()->GetTabLines() :
    1580           4 :             rTable.GetTabLines();
    1581             : 
    1582           4 :     return rRet;
    1583             : }
    1584             : 
    1585           2 : void SwUndoTblNdsChg::SaveNewBoxes( const SwTableNode& rTblNd,
    1586             :                                     const SwTableSortBoxes& rOld,
    1587             :                                     const SwSelBoxes& rBoxes,
    1588             :                                     const std::vector<sal_uLong> &rNodeCnts )
    1589             : {
    1590           2 :     const SwTable& rTbl = rTblNd.GetTable();
    1591           2 :     const SwTableSortBoxes& rTblBoxes = rTbl.GetTabSortBoxes();
    1592             : 
    1593             :     OSL_ENSURE( ! IsDelBox(), "wrong Action" );
    1594           2 :     pNewSttNds.reset( new std::set<_BoxMove> );
    1595             : 
    1596             :     OSL_ENSURE( rTbl.IsNewModel() || rOld.size() + nCount * rBoxes.size() == rTblBoxes.size(),
    1597             :         "unexpected boxes" );
    1598             :     OSL_ENSURE( rOld.size() <= rTblBoxes.size(), "more unexpected boxes" );
    1599           6 :     for (size_t n = 0, i = 0; i < rTblBoxes.size(); ++i)
    1600             :     {
    1601           8 :         if( ( n < rOld.size() ) &&
    1602           4 :             ( rOld[ n ] == rTblBoxes[ i ] ) )
    1603             :         {
    1604             :             // box already known? Then nothing to be done.
    1605           2 :             ++n;
    1606             :         }
    1607             :         else
    1608             :         {
    1609             :             // new box found: insert (obey sort order)
    1610           2 :             const SwTableBox* pBox = rTblBoxes[ i ];
    1611             : 
    1612             :             // find the source box. It must be one in rBoxes.
    1613             :             // We found the right one if it's in the same column as pBox.
    1614             :             // No, if more than one selected cell in the same column has been splitted,
    1615             :             // we have to look for the nearest one (i65201)!
    1616           2 :             const SwTableBox* pSourceBox = NULL;
    1617           2 :             const SwTableBox* pCheckBox = NULL;
    1618           2 :             const SwTableLine* pBoxLine = pBox->GetUpper();
    1619           2 :             sal_uInt16 nLineDiff = lcl_FindParentLines(rTbl,*pBox).GetPos(pBoxLine);
    1620           2 :             sal_uInt16 nLineNo = 0;
    1621           4 :             for (size_t j = 0; j < rBoxes.size(); ++j)
    1622             :             {
    1623           2 :                 pCheckBox = rBoxes[j];
    1624           2 :                 if( pCheckBox->GetUpper()->GetUpper() == pBox->GetUpper()->GetUpper() )
    1625             :                 {
    1626           2 :                     const SwTableLine* pCheckLine = pCheckBox->GetUpper();
    1627           2 :                     sal_uInt16 nCheckLine = lcl_FindParentLines( rTbl, *pCheckBox ).
    1628           2 :                     GetPos( pCheckLine );
    1629           2 :                     if( ( !pSourceBox || nCheckLine > nLineNo ) && nCheckLine < nLineDiff )
    1630             :                     {
    1631           2 :                         nLineNo = nCheckLine;
    1632           2 :                         pSourceBox = pCheckBox;
    1633             :                     }
    1634             :                 }
    1635             :             }
    1636             : 
    1637             :             // find the line number difference
    1638             :             // (to help determine bNodesMoved flag below)
    1639           2 :             nLineDiff = nLineDiff - nLineNo;
    1640             :             OSL_ENSURE( pSourceBox, "Splitted source box not found!" );
    1641             :             // find out how many nodes the source box used to have
    1642             :             // (to help determine bNodesMoved flag below)
    1643           2 :             size_t nNdsPos = 0;
    1644           4 :             while( rBoxes[ nNdsPos ] != pSourceBox )
    1645           0 :                 ++nNdsPos;
    1646           2 :             sal_uLong nNodes = rNodeCnts[ nNdsPos ];
    1647             : 
    1648             :             // When a new table cell is created, it either gets a new
    1649             :             // node, or it gets node(s) from elsewhere. The undo must
    1650             :             // know, of course, and thus we must determine here just
    1651             :             // where pBox's nodes are from:
    1652             :             // If 1) the source box has lost nodes, and
    1653             :             //    2) we're in the node range that got nodes
    1654             :             // then pBox received nodes from elsewhere.
    1655             :             // If bNodesMoved is set for pBox the undo must move the
    1656             :             // boxes back, otherwise it must delete them.
    1657           2 :             bool bNodesMoved = pSourceBox &&
    1658           4 :                 ( nNodes != ( pSourceBox->GetSttNd()->EndOfSectionIndex() -
    1659           2 :                               pSourceBox->GetSttIdx() ) )
    1660           2 :                 && ( nNodes - 1 > nLineDiff );
    1661           2 :             pNewSttNds->insert( _BoxMove(pBox->GetSttIdx(), bNodesMoved) );
    1662             :         }
    1663             :     }
    1664           2 : }
    1665             : 
    1666           4 : void SwUndoTblNdsChg::SaveSection( SwStartNode* pSttNd )
    1667             : {
    1668             :     OSL_ENSURE( IsDelBox(), "wrong Action" );
    1669           4 :     if( pDelSects.get() == NULL )
    1670           2 :         pDelSects.reset( new SwUndoSaveSections( 10 ) );
    1671             : 
    1672           4 :     SwTableNode* pTblNd = pSttNd->FindTableNode();
    1673           4 :     SwUndoSaveSection* pSave = new SwUndoSaveSection;
    1674           4 :     pSave->SaveSection( pSttNd->GetDoc(), SwNodeIndex( *pSttNd ));
    1675             : 
    1676           4 :     pDelSects->push_back( pSave );
    1677           4 :     nSttNode = pTblNd->GetIndex();
    1678           4 : }
    1679             : 
    1680           0 : void SwUndoTblNdsChg::UndoImpl(::sw::UndoRedoContext & rContext)
    1681             : {
    1682           0 :     SwDoc & rDoc = rContext.GetDoc();
    1683           0 :     SwNodeIndex aIdx( rDoc.GetNodes(), nSttNode );
    1684             : 
    1685           0 :     SwTableNode *const pTblNd = aIdx.GetNode().GetTableNode();
    1686             :     OSL_ENSURE( pTblNd, "no TableNode" );
    1687             : 
    1688           0 :     SwTableFmlUpdate aMsgHnt( &pTblNd->GetTable() );
    1689           0 :     aMsgHnt.eFlags = TBL_BOXPTR;
    1690           0 :     rDoc.getIDocumentFieldsAccess().UpdateTblFlds( &aMsgHnt );
    1691             : 
    1692             :     CHECK_TABLE( pTblNd->GetTable() )
    1693             : 
    1694           0 :     _FndBox aTmpBox( 0, 0 );
    1695             :     // ? TL_CHART2: notification or locking of controller required ?
    1696             : 
    1697           0 :     SwChartDataProvider *pPCD = rDoc.getIDocumentChartDataProviderAccess().GetChartDataProvider();
    1698           0 :     SwSelBoxes aDelBoxes;
    1699           0 :     std::vector< std::pair<SwTableBox *, sal_uLong> > aDelNodes;
    1700           0 :     if( IsDelBox() )
    1701             :     {
    1702             :         // Trick: add missing boxes in any line, they will be connected
    1703             :         // correctly when calling CreateNew
    1704           0 :         SwTableBox* pCpyBox = pTblNd->GetTable().GetTabSortBoxes()[0];
    1705           0 :         SwTableBoxes& rLnBoxes = pCpyBox->GetUpper()->GetTabBoxes();
    1706             : 
    1707             :         // restore sections
    1708           0 :         for( size_t n = pDelSects->size(); n; )
    1709             :         {
    1710           0 :             SwUndoSaveSection* pSave = &(*pDelSects)[ --n ];
    1711           0 :             pSave->RestoreSection( &rDoc, &aIdx, SwTableBoxStartNode );
    1712           0 :             if( pSave->GetHistory() )
    1713           0 :                 pSave->GetHistory()->Rollback( &rDoc );
    1714             :             SwTableBox* pBox = new SwTableBox( (SwTableBoxFmt*)pCpyBox->GetFrmFmt(), aIdx,
    1715           0 :                                                 pCpyBox->GetUpper() );
    1716           0 :             rLnBoxes.push_back( pBox );
    1717             :         }
    1718           0 :         pDelSects->clear();
    1719             :     }
    1720           0 :     else if( !pNewSttNds->empty() )
    1721             :     {
    1722             :         // Then the nodes have be moved and not deleted!
    1723             :         // But for that we need a temp array.
    1724           0 :         std::vector<_BoxMove> aTmp( pNewSttNds->begin(), pNewSttNds->end() );
    1725             : 
    1726             :         // backwards
    1727           0 :         for (size_t n = aTmp.size(); n > 0 ; )
    1728             :         {
    1729           0 :             --n;
    1730             :             // delete box from table structure
    1731           0 :             sal_uLong nIdx = aTmp[n].index;
    1732           0 :             SwTableBox* pBox = pTblNd->GetTable().GetTblBox( nIdx );
    1733             :             OSL_ENSURE( pBox, "Where is my TableBox?" );
    1734             : 
    1735             :             // TL_CHART2: notify chart about box to be removed
    1736           0 :             if (pPCD)
    1737           0 :                 pPCD->DeleteBox( &pTblNd->GetTable(), *pBox );
    1738             : 
    1739             :             // insert _before_ deleting the section - otherwise the box
    1740             :             // has no start node so all boxes sort equal in SwSelBoxes
    1741           0 :             aDelBoxes.insert(pBox);
    1742             : 
    1743           0 :             if( aTmp[n].hasMoved )
    1744             :             {
    1745           0 :                 SwNodeRange aRg( *pBox->GetSttNd(), 1,
    1746           0 :                             *pBox->GetSttNd()->EndOfSectionNode() );
    1747             : 
    1748           0 :                 SwTableLine* pLine = lcl_FindTableLine( pTblNd->GetTable(), *pBox );
    1749           0 :                 SwNodeIndex aInsPos( *(pLine->GetTabBoxes()[0]->GetSttNd()), 2 );
    1750             : 
    1751             :                 // adjust all StartNode indices
    1752           0 :                 size_t i = n;
    1753           0 :                 sal_uLong nSttIdx = aInsPos.GetIndex() - 2,
    1754           0 :                        nNdCnt = aRg.aEnd.GetIndex() - aRg.aStart.GetIndex();
    1755           0 :                 while( i && aTmp[ --i ].index > nSttIdx )
    1756           0 :                     aTmp[ i ].index += nNdCnt;
    1757             : 
    1758             :                 // first delete box
    1759           0 :                 delete pBox;
    1760             :                 // than move nodes
    1761           0 :                 rDoc.GetNodes()._MoveNodes( aRg, rDoc.GetNodes(), aInsPos, false );
    1762             :             }
    1763             :             else
    1764             :             {
    1765           0 :                 aDelNodes.push_back(std::make_pair(pBox, nIdx));
    1766             :             }
    1767           0 :         }
    1768             :     }
    1769             :     else
    1770             :     {
    1771             :         // Remove nodes from nodes array (backwards!)
    1772           0 :         std::set<_BoxMove>::reverse_iterator it;
    1773           0 :         for( it = pNewSttNds->rbegin(); it != pNewSttNds->rend(); ++it )
    1774             :         {
    1775           0 :             sal_uLong nIdx = (*it).index;
    1776           0 :             SwTableBox* pBox = pTblNd->GetTable().GetTblBox( nIdx );
    1777             :             OSL_ENSURE( pBox, "Where's my table box?" );
    1778             :             // TL_CHART2: notify chart about box to be removed
    1779           0 :             if (pPCD)
    1780           0 :                 pPCD->DeleteBox( &pTblNd->GetTable(), *pBox );
    1781           0 :             aDelBoxes.insert(pBox);
    1782           0 :             aDelNodes.push_back(std::make_pair(pBox, nIdx));
    1783             :         }
    1784             :     }
    1785             : 
    1786             :     // fdo#57197: before deleting the SwTableBoxes, delete the SwTabFrms
    1787           0 :     aTmpBox.SetTableLines(aDelBoxes, pTblNd->GetTable());
    1788           0 :     aTmpBox.DelFrms(pTblNd->GetTable());
    1789             : 
    1790             :     // do this _after_ deleting Frms because disposing SwAccessible requires
    1791             :     // connection to the nodes, see SwAccessibleChild::IsAccessible()
    1792           0 :     for (size_t i = 0; i < aDelNodes.size(); ++i)
    1793             :     {
    1794             :         // first disconnect box from node, otherwise ~SwTableBox would
    1795             :         // access pBox->pSttNd, deleted by DeleteSection
    1796           0 :         aDelNodes[i].first->RemoveFromTable();
    1797           0 :         rDoc.getIDocumentContentOperations().DeleteSection(rDoc.GetNodes()[ aDelNodes[i].second ]);
    1798             :     }
    1799             : 
    1800             :     // Remove boxes from table structure
    1801           0 :     for( size_t n = 0; n < aDelBoxes.size(); ++n )
    1802             :     {
    1803           0 :         SwTableBox* pCurrBox = aDelBoxes[n];
    1804           0 :         SwTableBoxes* pTBoxes = &pCurrBox->GetUpper()->GetTabBoxes();
    1805           0 :         pTBoxes->erase( std::find( pTBoxes->begin(), pTBoxes->end(), pCurrBox ) );
    1806           0 :         delete pCurrBox;
    1807             :     }
    1808             : 
    1809           0 :     pSaveTbl->CreateNew( pTblNd->GetTable(), true, false );
    1810             : 
    1811             :     // TL_CHART2: need to inform chart of probably changed cell names
    1812           0 :     rDoc.UpdateCharts( pTblNd->GetTable().GetFrmFmt()->GetName() );
    1813             : 
    1814           0 :     if( IsDelBox() )
    1815           0 :         nSttNode = pTblNd->GetIndex();
    1816           0 :     ClearFEShellTabCols();
    1817             :     CHECK_TABLE( pTblNd->GetTable() )
    1818           0 : }
    1819             : 
    1820           0 : void SwUndoTblNdsChg::RedoImpl(::sw::UndoRedoContext & rContext)
    1821             : {
    1822           0 :     SwDoc & rDoc = rContext.GetDoc();
    1823             : 
    1824           0 :     SwTableNode* pTblNd = rDoc.GetNodes()[ nSttNode ]->GetTableNode();
    1825             :     OSL_ENSURE( pTblNd, "no TableNode" );
    1826             :     CHECK_TABLE( pTblNd->GetTable() )
    1827             : 
    1828           0 :     SwSelBoxes aSelBoxes;
    1829           0 :     for (std::set<sal_uLong>::iterator it = m_Boxes.begin();
    1830           0 :             it != m_Boxes.end(); ++it)
    1831             :     {
    1832           0 :         SwTableBox* pBox = pTblNd->GetTable().GetTblBox( *it );
    1833           0 :         aSelBoxes.insert( pBox );
    1834             :     }
    1835             : 
    1836             :     // create SelBoxes and call InsertCell/-Row/SplitTbl
    1837           0 :     switch( GetId() )
    1838             :     {
    1839             :     case UNDO_TABLE_INSCOL:
    1840           0 :         if( USHRT_MAX == nSetColType )
    1841           0 :             rDoc.InsertCol( aSelBoxes, nCount, bFlag );
    1842             :         else
    1843             :         {
    1844           0 :             SwTableBox* pBox = pTblNd->GetTable().GetTblBox( nCurrBox );
    1845             :             rDoc.SetColRowWidthHeight( *pBox, nSetColType, nAbsDiff,
    1846           0 :                                         nRelDiff );
    1847             :         }
    1848           0 :         break;
    1849             : 
    1850             :     case UNDO_TABLE_INSROW:
    1851           0 :         if( USHRT_MAX == nSetColType )
    1852           0 :             rDoc.InsertRow( aSelBoxes, nCount, bFlag );
    1853             :         else
    1854             :         {
    1855           0 :             SwTable& rTbl = pTblNd->GetTable();
    1856           0 :             SwTableBox* pBox = rTbl.GetTblBox( nCurrBox );
    1857           0 :             TblChgMode eOldMode = rTbl.GetTblChgMode();
    1858           0 :             rTbl.SetTblChgMode( (TblChgMode)nCount );
    1859           0 :             rDoc.SetColRowWidthHeight( *pBox, nSetColType, nAbsDiff, nRelDiff );
    1860           0 :             rTbl.SetTblChgMode( eOldMode );
    1861             :         }
    1862           0 :         break;
    1863             : 
    1864             :     case UNDO_TABLE_SPLIT:
    1865           0 :         rDoc.SplitTbl( aSelBoxes, bFlag, nCount, bSameHeight );
    1866           0 :         break;
    1867             :     case UNDO_TABLE_DELBOX:
    1868             :     case UNDO_ROW_DELETE:
    1869             :     case UNDO_COL_DELETE:
    1870           0 :         if( USHRT_MAX == nSetColType )
    1871             :         {
    1872           0 :             SwTableFmlUpdate aMsgHnt( &pTblNd->GetTable() );
    1873           0 :             aMsgHnt.eFlags = TBL_BOXPTR;
    1874           0 :             rDoc.getIDocumentFieldsAccess().UpdateTblFlds( &aMsgHnt );
    1875           0 :             SwTable &rTable = pTblNd->GetTable();
    1876           0 :             if( nMax > nMin && rTable.IsNewModel() )
    1877           0 :                 rTable.PrepareDeleteCol( nMin, nMax );
    1878           0 :             rTable.DeleteSel( &rDoc, aSelBoxes, 0, this, true, true );
    1879             :         }
    1880             :         else
    1881             :         {
    1882           0 :             SwTable& rTbl = pTblNd->GetTable();
    1883             : 
    1884           0 :             SwTableFmlUpdate aMsgHnt( &rTbl );
    1885           0 :             aMsgHnt.eFlags = TBL_BOXPTR;
    1886           0 :             rDoc.getIDocumentFieldsAccess().UpdateTblFlds( &aMsgHnt );
    1887             : 
    1888           0 :             SwTableBox* pBox = rTbl.GetTblBox( nCurrBox );
    1889           0 :             TblChgMode eOldMode = rTbl.GetTblChgMode();
    1890           0 :             rTbl.SetTblChgMode( (TblChgMode)nCount );
    1891             : 
    1892             :             // need the SaveSections!
    1893           0 :             rDoc.GetIDocumentUndoRedo().DoUndo( true );
    1894           0 :             SwUndoTblNdsChg* pUndo = 0;
    1895             : 
    1896           0 :             switch( nSetColType & 0xff )
    1897             :             {
    1898             :             case nsTblChgWidthHeightType::WH_COL_LEFT:
    1899             :             case nsTblChgWidthHeightType::WH_COL_RIGHT:
    1900             :             case nsTblChgWidthHeightType::WH_CELL_LEFT:
    1901             :             case nsTblChgWidthHeightType::WH_CELL_RIGHT:
    1902             :                  rTbl.SetColWidth( *pBox, nSetColType, nAbsDiff,
    1903           0 :                                     nRelDiff, (SwUndo**)&pUndo );
    1904           0 :                 break;
    1905             :             case nsTblChgWidthHeightType::WH_ROW_TOP:
    1906             :             case nsTblChgWidthHeightType::WH_ROW_BOTTOM:
    1907             :             case nsTblChgWidthHeightType::WH_CELL_TOP:
    1908             :             case nsTblChgWidthHeightType::WH_CELL_BOTTOM:
    1909             :                 rTbl.SetRowHeight( *pBox, nSetColType, nAbsDiff,
    1910           0 :                                     nRelDiff, (SwUndo**)&pUndo );
    1911           0 :                 break;
    1912             :             }
    1913             : 
    1914           0 :             if( pUndo )
    1915             :             {
    1916           0 :                 pDelSects->transfer( pDelSects->begin(), *pUndo->pDelSects.get() );
    1917           0 :                 delete pUndo;
    1918             :             }
    1919           0 :             rDoc.GetIDocumentUndoRedo().DoUndo( false );
    1920             : 
    1921           0 :             rTbl.SetTblChgMode( eOldMode );
    1922             :         }
    1923           0 :         nSttNode = pTblNd->GetIndex();
    1924           0 :         break;
    1925             :     default:
    1926             :         ;
    1927             :     }
    1928           0 :     ClearFEShellTabCols();
    1929             :     CHECK_TABLE( pTblNd->GetTable() )
    1930           0 : }
    1931             : 
    1932           2 : SwUndoTblMerge::SwUndoTblMerge( const SwPaM& rTblSel )
    1933           2 :     : SwUndo( UNDO_TABLE_MERGE ), SwUndRng( rTblSel ), pHistory( 0 )
    1934             : {
    1935           2 :     const SwTableNode* pTblNd = rTblSel.GetNode().FindTableNode();
    1936             :     OSL_ENSURE( pTblNd, "Where is the TableNode?" );
    1937           2 :     pSaveTbl = new _SaveTable( pTblNd->GetTable() );
    1938           2 :     pMoves = new SwUndoMoves;
    1939           2 :     nTblNode = pTblNd->GetIndex();
    1940           2 : }
    1941             : 
    1942           6 : SwUndoTblMerge::~SwUndoTblMerge()
    1943             : {
    1944           2 :     delete pSaveTbl;
    1945           2 :     delete pMoves;
    1946           2 :     delete pHistory;
    1947           4 : }
    1948             : 
    1949           0 : void SwUndoTblMerge::UndoImpl(::sw::UndoRedoContext & rContext)
    1950             : {
    1951           0 :     SwDoc & rDoc = rContext.GetDoc();
    1952           0 :     SwNodeIndex aIdx( rDoc.GetNodes(), nTblNode );
    1953             : 
    1954           0 :     SwTableNode *const pTblNd = aIdx.GetNode().GetTableNode();
    1955             :     OSL_ENSURE( pTblNd, "no TableNode" );
    1956             : 
    1957           0 :     SwTableFmlUpdate aMsgHnt( &pTblNd->GetTable() );
    1958           0 :     aMsgHnt.eFlags = TBL_BOXPTR;
    1959           0 :     rDoc.getIDocumentFieldsAccess().UpdateTblFlds( &aMsgHnt );
    1960             : 
    1961           0 :     _FndBox aTmpBox( 0, 0 );
    1962             :     // ? TL_CHART2: notification or locking of controller required ?
    1963             : 
    1964             :     // 1. restore deleted boxes:
    1965             :     // Trick: add missing boxes in any line, they will be connected
    1966             :     // correctly when calling CreateNew
    1967           0 :     SwTableBox *pBox, *pCpyBox = pTblNd->GetTable().GetTabSortBoxes()[0];
    1968           0 :     SwTableBoxes& rLnBoxes = pCpyBox->GetUpper()->GetTabBoxes();
    1969             : 
    1970             : CHECKTABLE(pTblNd->GetTable())
    1971             : 
    1972           0 :     SwSelBoxes aSelBoxes;
    1973           0 :     SwTxtFmtColl* pColl = rDoc.getIDocumentStylePoolAccess().GetTxtCollFromPool( RES_POOLCOLL_STANDARD );
    1974             : 
    1975           0 :     std::set<sal_uLong>::iterator it;
    1976           0 :     for (it = m_Boxes.begin(); it != m_Boxes.end(); ++it)
    1977             :     {
    1978           0 :         aIdx = *it;
    1979           0 :         SwStartNode* pSttNd = rDoc.GetNodes().MakeTextSection( aIdx,
    1980           0 :                                             SwTableBoxStartNode, pColl );
    1981             :         pBox = new SwTableBox( (SwTableBoxFmt*)pCpyBox->GetFrmFmt(), *pSttNd,
    1982           0 :                                 pCpyBox->GetUpper() );
    1983           0 :         rLnBoxes.push_back( pBox );
    1984             : 
    1985           0 :         aSelBoxes.insert( pBox );
    1986             :     }
    1987             : 
    1988             : CHECKTABLE(pTblNd->GetTable())
    1989             : 
    1990           0 :     SwChartDataProvider *pPCD = rDoc.getIDocumentChartDataProviderAccess().GetChartDataProvider();
    1991             :     // 2. deleted the inserted boxes
    1992             :     // delete nodes (from last to first)
    1993           0 :     for( size_t n = aNewSttNds.size(); n; )
    1994             :     {
    1995             :         // remove box from table structure
    1996           0 :         sal_uLong nIdx = aNewSttNds[ --n ];
    1997             : 
    1998           0 :         if( !nIdx && n )
    1999             :         {
    2000           0 :             nIdx = aNewSttNds[ --n ];
    2001           0 :             pBox = pTblNd->GetTable().GetTblBox( nIdx );
    2002             :             OSL_ENSURE( pBox, "Where is my TableBox?" );
    2003             : 
    2004           0 :             if( !pSaveTbl->IsNewModel() )
    2005           0 :                 rDoc.GetNodes().MakeTxtNode( SwNodeIndex(
    2006           0 :                     *pBox->GetSttNd()->EndOfSectionNode() ), pColl );
    2007             : 
    2008             :             // this was the separator -> restore moved ones
    2009           0 :             for( size_t i = pMoves->size(); i; )
    2010             :             {
    2011           0 :                 SwTxtNode* pTxtNd = 0;
    2012           0 :                 sal_Int32 nDelPos = 0;
    2013           0 :                 SwUndoMove* pUndo = &(*pMoves)[ --i ];
    2014           0 :                 if( !pUndo->IsMoveRange() )
    2015             :                 {
    2016           0 :                     pTxtNd = rDoc.GetNodes()[ pUndo->GetDestSttNode() ]->GetTxtNode();
    2017           0 :                     nDelPos = pUndo->GetDestSttCntnt() - 1;
    2018             :                 }
    2019           0 :                 pUndo->UndoImpl(rContext);
    2020           0 :                 if( pUndo->IsMoveRange() )
    2021             :                 {
    2022             :                     // delete the unnecessary node
    2023           0 :                     aIdx = pUndo->GetEndNode();
    2024           0 :                     SwCntntNode *pCNd = aIdx.GetNode().GetCntntNode();
    2025           0 :                     if( pCNd )
    2026             :                     {
    2027           0 :                         SwNodeIndex aTmp( aIdx, -1 );
    2028           0 :                         SwCntntNode *pMove = aTmp.GetNode().GetCntntNode();
    2029           0 :                         if( pMove )
    2030           0 :                             pCNd->MoveTo( *pMove );
    2031             :                     }
    2032           0 :                     rDoc.GetNodes().Delete( aIdx, 1 );
    2033             :                 }
    2034           0 :                 else if( pTxtNd )
    2035             :                 {
    2036             :                     // also delete not needed attributes
    2037           0 :                     SwIndex aTmpIdx( pTxtNd, nDelPos );
    2038           0 :                     if( pTxtNd->GetpSwpHints() && pTxtNd->GetpSwpHints()->Count() )
    2039           0 :                         pTxtNd->RstTxtAttr( aTmpIdx, pTxtNd->GetTxt().getLength() - nDelPos + 1 );
    2040             :                     // delete separator
    2041           0 :                     pTxtNd->EraseText( aTmpIdx, 1 );
    2042             :                 }
    2043             :             }
    2044           0 :             nIdx = pBox->GetSttIdx();
    2045             :         }
    2046             :         else
    2047           0 :             pBox = pTblNd->GetTable().GetTblBox( nIdx );
    2048             : 
    2049           0 :         if( !pSaveTbl->IsNewModel() )
    2050             :         {
    2051             :             // TL_CHART2: notify chart about box to be removed
    2052           0 :             if (pPCD)
    2053           0 :                 pPCD->DeleteBox( &pTblNd->GetTable(), *pBox );
    2054             : 
    2055           0 :             SwTableBoxes* pTBoxes = &pBox->GetUpper()->GetTabBoxes();
    2056           0 :             pTBoxes->erase( std::find(pTBoxes->begin(), pTBoxes->end(), pBox ) );
    2057             : 
    2058             :             // delete indices from section
    2059             :             {
    2060           0 :                 SwNodeIndex aTmpIdx( *pBox->GetSttNd() );
    2061             :                 rDoc.CorrAbs( SwNodeIndex( aTmpIdx, 1 ),
    2062           0 :                             SwNodeIndex( *aTmpIdx.GetNode().EndOfSectionNode() ),
    2063           0 :                             SwPosition( aTmpIdx, SwIndex( 0, 0 )), true );
    2064             :             }
    2065             : 
    2066           0 :             delete pBox;
    2067           0 :             rDoc.getIDocumentContentOperations().DeleteSection( rDoc.GetNodes()[ nIdx ] );
    2068             :         }
    2069             :     }
    2070             : CHECKTABLE(pTblNd->GetTable())
    2071             : 
    2072           0 :     pSaveTbl->CreateNew( pTblNd->GetTable(), true, false );
    2073             : 
    2074             :     // TL_CHART2: need to inform chart of probably changed cell names
    2075           0 :     rDoc.UpdateCharts( pTblNd->GetTable().GetFrmFmt()->GetName() );
    2076             : 
    2077           0 :     if( pHistory )
    2078             :     {
    2079           0 :         pHistory->TmpRollback( &rDoc, 0 );
    2080           0 :         pHistory->SetTmpEnd( pHistory->Count() );
    2081             :     }
    2082           0 :     SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());
    2083           0 :     pPam->DeleteMark();
    2084           0 :     pPam->GetPoint()->nNode = nSttNode;
    2085           0 :     pPam->GetPoint()->nContent.Assign( pPam->GetCntntNode(), nSttCntnt );
    2086           0 :     pPam->SetMark();
    2087           0 :     pPam->DeleteMark();
    2088             : 
    2089             : CHECKTABLE(pTblNd->GetTable())
    2090           0 :     ClearFEShellTabCols();
    2091           0 : }
    2092             : 
    2093           0 : void SwUndoTblMerge::RedoImpl(::sw::UndoRedoContext & rContext)
    2094             : {
    2095           0 :     SwDoc & rDoc = rContext.GetDoc();
    2096           0 :     SwPaM & rPam( AddUndoRedoPaM(rContext) );
    2097           0 :     rDoc.MergeTbl(rPam);
    2098           0 : }
    2099             : 
    2100           0 : void SwUndoTblMerge::MoveBoxCntnt( SwDoc* pDoc, SwNodeRange& rRg, SwNodeIndex& rPos )
    2101             : {
    2102           0 :     SwNodeIndex aTmp( rRg.aStart, -1 ), aTmp2( rPos, -1 );
    2103           0 :     SwUndoMove* pUndo = new SwUndoMove( pDoc, rRg, rPos );
    2104           0 :     ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo());
    2105           0 :     pDoc->getIDocumentContentOperations().MoveNodeRange( rRg, rPos, (pSaveTbl->IsNewModel()) ?
    2106             :         IDocumentContentOperations::DOC_NO_DELFRMS :
    2107           0 :         IDocumentContentOperations::DOC_MOVEDEFAULT );
    2108           0 :     ++aTmp;
    2109           0 :     ++aTmp2;
    2110           0 :     pUndo->SetDestRange( aTmp2, rPos, aTmp );
    2111             : 
    2112           0 :     pMoves->push_back( pUndo );
    2113           0 : }
    2114             : 
    2115           2 : void SwUndoTblMerge::SetSelBoxes( const SwSelBoxes& rBoxes )
    2116             : {
    2117             :     // memorize selection
    2118           8 :     for (size_t n = 0; n < rBoxes.size(); ++n)
    2119             :     {
    2120           6 :         m_Boxes.insert(rBoxes[n]->GetSttIdx());
    2121             :     }
    2122             : 
    2123             :     // as separator for inserts of new boxes after shifting
    2124           2 :     aNewSttNds.push_back( (sal_uLong)0 );
    2125             : 
    2126             :     // The new table model does not delete overlapped cells (by row span),
    2127             :     // so the rBoxes array might be empty even some cells have been merged.
    2128           2 :     if( !rBoxes.empty() )
    2129           2 :         nTblNode = rBoxes[ 0 ]->GetSttNd()->FindTableNode()->GetIndex();
    2130           2 : }
    2131             : 
    2132           0 : void SwUndoTblMerge::SaveCollection( const SwTableBox& rBox )
    2133             : {
    2134           0 :     if( !pHistory )
    2135           0 :         pHistory = new SwHistory;
    2136             : 
    2137           0 :     SwNodeIndex aIdx( *rBox.GetSttNd(), 1 );
    2138           0 :     SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
    2139           0 :     if( !pCNd )
    2140           0 :         pCNd = aIdx.GetNodes().GoNext( &aIdx );
    2141             : 
    2142           0 :     pHistory->Add( pCNd->GetFmtColl(), aIdx.GetIndex(), pCNd->GetNodeType());
    2143           0 :     if( pCNd->HasSwAttrSet() )
    2144           0 :         pHistory->CopyFmtAttr( *pCNd->GetpSwAttrSet(), aIdx.GetIndex() );
    2145           0 : }
    2146             : 
    2147         146 : SwUndoTblNumFmt::SwUndoTblNumFmt( const SwTableBox& rBox,
    2148             :                                     const SfxItemSet* pNewSet )
    2149             :     : SwUndo(UNDO_TBLNUMFMT)
    2150             :     , pBoxSet(0)
    2151             :     , pHistory(0)
    2152             :     , nFmtIdx(NUMBERFORMAT_TEXT)
    2153             :     , nNewFmtIdx(0)
    2154             :     , fNum(0.0)
    2155             :     , fNewNum(0.0)
    2156             :     , bNewFmt(false)
    2157             :     , bNewFml(false)
    2158         146 :     , bNewValue(false)
    2159             : {
    2160         146 :     nNode = rBox.GetSttIdx();
    2161             : 
    2162         146 :     nNdPos = rBox.IsValidNumTxtNd( 0 == pNewSet );
    2163         146 :     SwDoc* pDoc = rBox.GetFrmFmt()->GetDoc();
    2164             : 
    2165         146 :     if( ULONG_MAX != nNdPos )
    2166             :     {
    2167         146 :         SwTxtNode* pTNd = pDoc->GetNodes()[ nNdPos ]->GetTxtNode();
    2168             : 
    2169         146 :         pHistory = new SwHistory;
    2170         146 :         SwRegHistory aRHst( *rBox.GetSttNd(), pHistory );
    2171             :         // always save all text atttibutes because of possibly overlapping
    2172             :         // areas of on/off
    2173             :         pHistory->CopyAttr( pTNd->GetpSwpHints(), nNdPos, 0,
    2174         146 :                             pTNd->GetTxt().getLength(), true );
    2175             : 
    2176         146 :         if( pTNd->HasSwAttrSet() )
    2177          80 :             pHistory->CopyFmtAttr( *pTNd->GetpSwAttrSet(), nNdPos );
    2178             : 
    2179         146 :         aStr = pTNd->GetTxt();
    2180         146 :         if( pTNd->GetpSwpHints() )
    2181          40 :             pTNd->GetpSwpHints()->DeRegister();
    2182             :     }
    2183             : 
    2184         146 :     pBoxSet = new SfxItemSet( pDoc->GetAttrPool(), aTableBoxSetRange );
    2185         146 :     pBoxSet->Put( rBox.GetFrmFmt()->GetAttrSet() );
    2186             : 
    2187         146 :     if( pNewSet )
    2188             :     {
    2189             :         const SfxPoolItem* pItem;
    2190         144 :         if( SfxItemState::SET == pNewSet->GetItemState( RES_BOXATR_FORMAT,
    2191         144 :                 false, &pItem ))
    2192             :         {
    2193         134 :             bNewFmt = true;
    2194         134 :             nNewFmtIdx = ((SwTblBoxNumFormat*)pItem)->GetValue();
    2195             :         }
    2196         144 :         if( SfxItemState::SET == pNewSet->GetItemState( RES_BOXATR_FORMULA,
    2197         144 :                 false, &pItem ))
    2198             :         {
    2199           0 :             bNewFml = true;
    2200           0 :             aNewFml = ((SwTblBoxFormula*)pItem)->GetFormula();
    2201             :         }
    2202         144 :         if( SfxItemState::SET == pNewSet->GetItemState( RES_BOXATR_VALUE,
    2203         144 :                 false, &pItem ))
    2204             :         {
    2205         144 :             bNewValue = true;
    2206         144 :             fNewNum = ((SwTblBoxValue*)pItem)->GetValue();
    2207             :         }
    2208             :     }
    2209             : 
    2210             :     // is a history needed at all?
    2211         146 :     if( pHistory && !pHistory->Count() )
    2212          66 :         DELETEZ( pHistory );
    2213         146 : }
    2214             : 
    2215         438 : SwUndoTblNumFmt::~SwUndoTblNumFmt()
    2216             : {
    2217         146 :     delete pHistory;
    2218         146 :     delete pBoxSet;
    2219         292 : }
    2220             : 
    2221           0 : void SwUndoTblNumFmt::UndoImpl(::sw::UndoRedoContext & rContext)
    2222             : {
    2223             :     OSL_ENSURE( pBoxSet, "Where's the stored item set?" );
    2224             : 
    2225           0 :     SwDoc & rDoc = rContext.GetDoc();
    2226           0 :     SwStartNode* pSttNd = rDoc.GetNodes()[ nNode ]->
    2227           0 :                             FindSttNodeByType( SwTableBoxStartNode );
    2228             :     OSL_ENSURE( pSttNd, "without StartNode no TableBox" );
    2229           0 :     SwTableBox* pBox = pSttNd->FindTableNode()->GetTable().GetTblBox(
    2230           0 :                                     pSttNd->GetIndex() );
    2231             :     OSL_ENSURE( pBox, "found no TableBox" );
    2232             : 
    2233           0 :     SwTableBoxFmt* pFmt = rDoc.MakeTableBoxFmt();
    2234           0 :     pFmt->SetFmtAttr( *pBoxSet );
    2235           0 :     pBox->ChgFrmFmt( pFmt );
    2236             : 
    2237           0 :     if( ULONG_MAX == nNdPos )
    2238           0 :         return;
    2239             : 
    2240           0 :     SwTxtNode* pTxtNd = rDoc.GetNodes()[ nNdPos ]->GetTxtNode();
    2241             :     // If more than one node was deleted than all "node" attributes were also
    2242             :     // saved
    2243           0 :     if( pTxtNd->HasSwAttrSet() )
    2244           0 :         pTxtNd->ResetAllAttr();
    2245             : 
    2246           0 :     if( pTxtNd->GetpSwpHints() && !aStr.isEmpty() )
    2247           0 :         pTxtNd->ClearSwpHintsArr( true );
    2248             : 
    2249             :     // ChgTextToNum(..) only acts when the strings are different. We need to do
    2250             :     // the same here.
    2251           0 :     if( pTxtNd->GetTxt() != aStr )
    2252             :     {
    2253           0 :         rDoc.getIDocumentRedlineAccess().DeleteRedline( *( pBox->GetSttNd() ), false, USHRT_MAX );
    2254             : 
    2255           0 :         SwIndex aIdx( pTxtNd, 0 );
    2256           0 :         if( !aStr.isEmpty() )
    2257             :         {
    2258           0 :             pTxtNd->EraseText( aIdx );
    2259             :             pTxtNd->InsertText( aStr, aIdx,
    2260           0 :                 IDocumentContentOperations::INS_NOHINTEXPAND );
    2261           0 :         }
    2262             :     }
    2263             : 
    2264           0 :     if( pHistory )
    2265             :     {
    2266           0 :         sal_uInt16 nTmpEnd = pHistory->GetTmpEnd();
    2267           0 :         pHistory->TmpRollback( &rDoc, 0 );
    2268           0 :         pHistory->SetTmpEnd( nTmpEnd );
    2269             :     }
    2270             : 
    2271           0 :     SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());
    2272           0 :     pPam->DeleteMark();
    2273           0 :     pPam->GetPoint()->nNode = nNode + 1;
    2274           0 :     pPam->GetPoint()->nContent.Assign( pTxtNd, 0 );
    2275             : }
    2276             : 
    2277             : /** switch the RedlineMode on the given document, using
    2278             :  * SetRedlineMode_intern. This class set the mode in the constructor,
    2279             :  * and changes it back in the destructor, i.e. it uses the
    2280             :  * initialization-is-resource-acquisition idiom.
    2281             :  */
    2282             : class RedlineModeInternGuard
    2283             : {
    2284             :     SwDoc& mrDoc;
    2285             :     RedlineMode_t meOldRedlineMode;
    2286             : 
    2287             : public:
    2288             :     RedlineModeInternGuard(
    2289             :         SwDoc& rDoc,                      // change mode of this document
    2290             :         RedlineMode_t eNewRedlineMode,    // new redline mode
    2291             :         RedlineMode_t eRedlineModeMask  = (RedlineMode_t)(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_IGNORE /*change only bits set in this mask*/));
    2292             : 
    2293             :     ~RedlineModeInternGuard();
    2294             : };
    2295             : 
    2296           0 : RedlineModeInternGuard::RedlineModeInternGuard(
    2297             :     SwDoc& rDoc,
    2298             :     RedlineMode_t eNewRedlineMode,
    2299             :     RedlineMode_t eRedlineModeMask )
    2300             :     : mrDoc( rDoc ),
    2301           0 :       meOldRedlineMode( rDoc.getIDocumentRedlineAccess().GetRedlineMode() )
    2302             : {
    2303           0 :     mrDoc.getIDocumentRedlineAccess().SetRedlineMode_intern((RedlineMode_t)( ( meOldRedlineMode & ~eRedlineModeMask ) |
    2304           0 :                                      ( eNewRedlineMode & eRedlineModeMask ) ));
    2305           0 : }
    2306             : 
    2307           0 : RedlineModeInternGuard::~RedlineModeInternGuard()
    2308             : {
    2309           0 :     mrDoc.getIDocumentRedlineAccess().SetRedlineMode_intern( meOldRedlineMode );
    2310           0 : }
    2311             : 
    2312           0 : void SwUndoTblNumFmt::RedoImpl(::sw::UndoRedoContext & rContext)
    2313             : {
    2314             :     // Could the box be changed?
    2315           0 :     if( !pBoxSet )
    2316           0 :         return ;
    2317             : 
    2318           0 :     SwDoc & rDoc = rContext.GetDoc();
    2319           0 :     SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());
    2320             : 
    2321           0 :     pPam->DeleteMark();
    2322           0 :     pPam->GetPoint()->nNode = nNode;
    2323             : 
    2324           0 :     SwNode * pNd = & pPam->GetPoint()->nNode.GetNode();
    2325           0 :     SwStartNode* pSttNd = pNd->FindSttNodeByType( SwTableBoxStartNode );
    2326             :     assert(pSttNd && "without StartNode no TableBox");
    2327           0 :     SwTableBox* pBox = pSttNd->FindTableNode()->GetTable().GetTblBox(
    2328           0 :                                     pSttNd->GetIndex() );
    2329             :     OSL_ENSURE( pBox, "found no TableBox" );
    2330             : 
    2331           0 :     SwFrmFmt* pBoxFmt = pBox->ClaimFrmFmt();
    2332           0 :     if( bNewFmt || bNewFml || bNewValue )
    2333             :     {
    2334           0 :         SfxItemSet aBoxSet( rDoc.GetAttrPool(),
    2335           0 :                                 RES_BOXATR_FORMAT, RES_BOXATR_VALUE );
    2336             : 
    2337             :         // Resetting attributes is not enough. In addition, take care that the
    2338             :         // text will be also formatted correctly.
    2339           0 :         pBoxFmt->LockModify();
    2340             : 
    2341           0 :         if( bNewFml )
    2342           0 :             aBoxSet.Put( SwTblBoxFormula( aNewFml ));
    2343             :         else
    2344           0 :             pBoxFmt->ResetFmtAttr( RES_BOXATR_FORMULA );
    2345           0 :         if( bNewFmt )
    2346           0 :             aBoxSet.Put( SwTblBoxNumFormat( nNewFmtIdx ));
    2347             :         else
    2348           0 :             pBoxFmt->ResetFmtAttr( RES_BOXATR_FORMAT );
    2349           0 :         if( bNewValue )
    2350           0 :             aBoxSet.Put( SwTblBoxValue( fNewNum ));
    2351             :         else
    2352           0 :             pBoxFmt->ResetFmtAttr( RES_BOXATR_VALUE );
    2353           0 :         pBoxFmt->UnlockModify();
    2354             : 
    2355             :         // dvo: When redlining is (was) enabled, setting the attribute
    2356             :         // will also change the cell content. To allow this, the
    2357             :         // REDLINE_IGNORE flag must be removed during Redo. #108450#
    2358           0 :         RedlineModeInternGuard aGuard( rDoc, nsRedlineMode_t::REDLINE_NONE, nsRedlineMode_t::REDLINE_IGNORE );
    2359           0 :         pBoxFmt->SetFmtAttr( aBoxSet );
    2360             :     }
    2361           0 :     else if( NUMBERFORMAT_TEXT != nFmtIdx )
    2362             :     {
    2363           0 :         SfxItemSet aBoxSet( rDoc.GetAttrPool(),
    2364           0 :                             RES_BOXATR_FORMAT, RES_BOXATR_VALUE );
    2365             : 
    2366           0 :         aBoxSet.Put( SwTblBoxNumFormat( nFmtIdx ));
    2367           0 :         aBoxSet.Put( SwTblBoxValue( fNum ));
    2368             : 
    2369             :         // Resetting attributes is not enough. In addition, take care that the
    2370             :         // text will be also formatted correctly.
    2371           0 :         pBoxFmt->LockModify();
    2372           0 :         pBoxFmt->ResetFmtAttr( RES_BOXATR_FORMULA );
    2373           0 :         pBoxFmt->UnlockModify();
    2374             : 
    2375             :         // dvo: When redlining is (was) enabled, setting the attribute
    2376             :         // will also change the cell content. To allow this, the
    2377             :         // REDLINE_IGNORE flag must be removed during Redo. #108450#
    2378           0 :         RedlineModeInternGuard aGuard( rDoc, nsRedlineMode_t::REDLINE_NONE, nsRedlineMode_t::REDLINE_IGNORE );
    2379           0 :         pBoxFmt->SetFmtAttr( aBoxSet );
    2380             :     }
    2381             :     else
    2382             :     {
    2383             :         // it's no number
    2384             : 
    2385             :         // Resetting attributes is not enough. In addition, take care that the
    2386             :         // text will be also formatted correctly.
    2387           0 :         pBoxFmt->SetFmtAttr( *GetDfltAttr( RES_BOXATR_FORMAT ));
    2388             : 
    2389           0 :         pBoxFmt->ResetFmtAttr( RES_BOXATR_FORMAT, RES_BOXATR_VALUE );
    2390             :     }
    2391             : 
    2392           0 :     if( bNewFml )
    2393             :     {
    2394             :         // No matter what was set, an update of the table is always a good idea
    2395           0 :         SwTableFmlUpdate aTblUpdate( &pSttNd->FindTableNode()->GetTable() );
    2396           0 :         rDoc.getIDocumentFieldsAccess().UpdateTblFlds( &aTblUpdate );
    2397             :     }
    2398             : 
    2399           0 :     if( !pNd->IsCntntNode() )
    2400           0 :         pNd = rDoc.GetNodes().GoNext( &pPam->GetPoint()->nNode );
    2401           0 :     pPam->GetPoint()->nContent.Assign( (SwCntntNode*)pNd, 0 );
    2402             : }
    2403             : 
    2404           0 : void SwUndoTblNumFmt::SetBox( const SwTableBox& rBox )
    2405             : {
    2406           0 :     nNode = rBox.GetSttIdx();
    2407           0 : }
    2408             : 
    2409           0 : _UndoTblCpyTbl_Entry::_UndoTblCpyTbl_Entry( const SwTableBox& rBox )
    2410           0 :     : nBoxIdx( rBox.GetSttIdx() ), nOffset( 0 ),
    2411           0 :     pBoxNumAttr( 0 ), pUndo( 0 ), bJoin( false )
    2412             : {
    2413           0 : }
    2414             : 
    2415           0 : _UndoTblCpyTbl_Entry::~_UndoTblCpyTbl_Entry()
    2416             : {
    2417           0 :     delete pUndo;
    2418           0 :     delete pBoxNumAttr;
    2419           0 : }
    2420             : 
    2421           0 : SwUndoTblCpyTbl::SwUndoTblCpyTbl()
    2422           0 :     : SwUndo( UNDO_TBLCPYTBL ), pInsRowUndo( 0 )
    2423             : {
    2424           0 :     pArr = new _UndoTblCpyTbl_Entries;
    2425           0 : }
    2426             : 
    2427           0 : SwUndoTblCpyTbl::~SwUndoTblCpyTbl()
    2428             : {
    2429           0 :     delete pArr;
    2430           0 :     delete pInsRowUndo;
    2431           0 : }
    2432             : 
    2433           0 : void SwUndoTblCpyTbl::UndoImpl(::sw::UndoRedoContext & rContext)
    2434             : {
    2435           0 :     SwDoc & rDoc = rContext.GetDoc();
    2436             :     _DEBUG_REDLINE( &rDoc )
    2437             : 
    2438           0 :     SwTableNode* pTblNd = 0;
    2439           0 :     for( size_t n = pArr->size(); n; )
    2440             :     {
    2441           0 :         _UndoTblCpyTbl_Entry* pEntry = &(*pArr)[ --n ];
    2442           0 :         sal_uLong nSttPos = pEntry->nBoxIdx + pEntry->nOffset;
    2443           0 :         SwStartNode* pSNd = rDoc.GetNodes()[ nSttPos ]->StartOfSectionNode();
    2444           0 :         if( !pTblNd )
    2445           0 :             pTblNd = pSNd->FindTableNode();
    2446             : 
    2447           0 :         SwTableBox& rBox = *pTblNd->GetTable().GetTblBox( nSttPos );
    2448             : 
    2449           0 :         SwNodeIndex aInsIdx( *rBox.GetSttNd(), 1 );
    2450           0 :         rDoc.GetNodes().MakeTxtNode( aInsIdx, (SwTxtFmtColl*)rDoc.GetDfltTxtFmtColl() );
    2451             : 
    2452             :         // b62341295: Redline for copying tables
    2453           0 :         const SwNode *pEndNode = rBox.GetSttNd()->EndOfSectionNode();
    2454           0 :         SwPaM aPam( aInsIdx.GetNode(), *pEndNode );
    2455           0 :         SwUndoDelete* pUndo = 0;
    2456             : 
    2457           0 :         if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ) )
    2458             :         {
    2459           0 :             bool bDeleteCompleteParagraph = false;
    2460           0 :             bool bShiftPam = false;
    2461             :             // There are a couple of different situations to consider during redlining
    2462           0 :             if( pEntry->pUndo )
    2463             :             {
    2464             :                 SwUndoDelete *const pUndoDelete =
    2465           0 :                     dynamic_cast<SwUndoDelete*>(pEntry->pUndo);
    2466             :                 SwUndoRedlineDelete *const pUndoRedlineDelete =
    2467           0 :                     dynamic_cast<SwUndoRedlineDelete*>(pEntry->pUndo);
    2468             :                 OSL_ASSERT(pUndoDelete || pUndoRedlineDelete);
    2469           0 :                 if (pUndoRedlineDelete)
    2470             :                 {
    2471             :                     // The old content was not empty or he has been merged with the new content
    2472           0 :                     bDeleteCompleteParagraph = !pEntry->bJoin; // bJoin is set when merged
    2473             :                     // Set aTmpIdx to the beginning fo the old content
    2474             :                     SwNodeIndex aTmpIdx( *pEndNode,
    2475           0 :                             pUndoRedlineDelete->NodeDiff()-1 );
    2476           0 :                     SwTxtNode *pTxt = aTmpIdx.GetNode().GetTxtNode();
    2477           0 :                     if( pTxt )
    2478             :                     {
    2479           0 :                         aPam.GetPoint()->nNode = *pTxt;
    2480           0 :                         aPam.GetPoint()->nContent.Assign( pTxt,
    2481           0 :                                 pUndoRedlineDelete->ContentStart() );
    2482             :                     }
    2483             :                     else
    2484           0 :                         *aPam.GetPoint() = SwPosition( aTmpIdx );
    2485             :                 }
    2486           0 :                 else if (pUndoDelete && pUndoDelete->IsDelFullPara())
    2487             :                 {
    2488             :                     // When the old content was an empty paragraph, but could not be joined
    2489             :                     // with the new content (e.g. because of a section or table)
    2490             :                     // We "save" the aPam.Point, we go one step backwards (because later on the
    2491             :                     // empty paragraph will be inserted by the undo) and set the "ShiftPam-flag
    2492             :                     // for step forward later on.
    2493           0 :                     bDeleteCompleteParagraph = true;
    2494           0 :                     bShiftPam = true;
    2495           0 :                     SwNodeIndex aTmpIdx( *pEndNode, -1 );
    2496           0 :                     SwTxtNode *pTxt = aTmpIdx.GetNode().GetTxtNode();
    2497           0 :                     if( pTxt )
    2498             :                     {
    2499           0 :                         aPam.GetPoint()->nNode = *pTxt;
    2500           0 :                         aPam.GetPoint()->nContent.Assign( pTxt, 0 );
    2501             :                     }
    2502             :                     else
    2503           0 :                         *aPam.GetPoint() = SwPosition( aTmpIdx );
    2504             :                 }
    2505             :             }
    2506           0 :             rDoc.getIDocumentRedlineAccess().DeleteRedline( aPam, true, USHRT_MAX );
    2507             : 
    2508           0 :             if( pEntry->pUndo )
    2509             :             {
    2510           0 :                 pEntry->pUndo->UndoImpl(rContext);
    2511           0 :                 delete pEntry->pUndo;
    2512           0 :                 pEntry->pUndo = 0;
    2513             :             }
    2514           0 :             if( bShiftPam )
    2515             :             {
    2516             :                 // The aPam.Point is at the moment at the last position of the new content and has to be
    2517             :                 // moved to the first position of the old content for the SwUndoDelete operation
    2518           0 :                 SwNodeIndex aTmpIdx( aPam.GetPoint()->nNode, 1 );
    2519           0 :                 SwTxtNode *pTxt = aTmpIdx.GetNode().GetTxtNode();
    2520           0 :                 if( pTxt )
    2521             :                 {
    2522           0 :                     aPam.GetPoint()->nNode = *pTxt;
    2523           0 :                     aPam.GetPoint()->nContent.Assign( pTxt, 0 );
    2524             :                 }
    2525             :                 else
    2526           0 :                     *aPam.GetPoint() = SwPosition( aTmpIdx );
    2527             :             }
    2528           0 :             pUndo = new SwUndoDelete( aPam, bDeleteCompleteParagraph, true );
    2529             :         }
    2530             :         else
    2531             :         {
    2532           0 :             pUndo = new SwUndoDelete( aPam, true );
    2533           0 :             if( pEntry->pUndo )
    2534             :             {
    2535           0 :                 pEntry->pUndo->UndoImpl(rContext);
    2536           0 :                 delete pEntry->pUndo;
    2537           0 :                 pEntry->pUndo = 0;
    2538             :             }
    2539             :         }
    2540           0 :         pEntry->pUndo = pUndo;
    2541             : 
    2542           0 :         aInsIdx = rBox.GetSttIdx() + 1;
    2543           0 :         rDoc.GetNodes().Delete( aInsIdx, 1 );
    2544             : 
    2545           0 :         SfxItemSet aTmpSet( rDoc.GetAttrPool(), RES_BOXATR_FORMAT, RES_BOXATR_VALUE,
    2546           0 :                                                 RES_VERT_ORIENT, RES_VERT_ORIENT, 0 );
    2547           0 :         aTmpSet.Put( rBox.GetFrmFmt()->GetAttrSet() );
    2548           0 :         if( aTmpSet.Count() )
    2549             :         {
    2550           0 :             SwFrmFmt* pBoxFmt = rBox.ClaimFrmFmt();
    2551           0 :             pBoxFmt->ResetFmtAttr( RES_BOXATR_FORMAT, RES_BOXATR_VALUE );
    2552           0 :             pBoxFmt->ResetFmtAttr( RES_VERT_ORIENT );
    2553             :         }
    2554             : 
    2555           0 :         if( pEntry->pBoxNumAttr )
    2556             :         {
    2557           0 :             rBox.ClaimFrmFmt()->SetFmtAttr( *pEntry->pBoxNumAttr );
    2558           0 :             delete pEntry->pBoxNumAttr, pEntry->pBoxNumAttr = 0;
    2559             :         }
    2560             : 
    2561           0 :         if( aTmpSet.Count() )
    2562             :         {
    2563           0 :             pEntry->pBoxNumAttr = new SfxItemSet( rDoc.GetAttrPool(),
    2564             :                                     RES_BOXATR_FORMAT, RES_BOXATR_VALUE,
    2565           0 :                                     RES_VERT_ORIENT, RES_VERT_ORIENT, 0 );
    2566           0 :             pEntry->pBoxNumAttr->Put( aTmpSet );
    2567             :         }
    2568             : 
    2569           0 :         pEntry->nOffset = rBox.GetSttIdx() - pEntry->nBoxIdx;
    2570           0 :     }
    2571             : 
    2572           0 :     if( pInsRowUndo )
    2573             :     {
    2574           0 :         pInsRowUndo->UndoImpl(rContext);
    2575             :     }
    2576             :     _DEBUG_REDLINE( &rDoc )
    2577           0 : }
    2578             : 
    2579           0 : void SwUndoTblCpyTbl::RedoImpl(::sw::UndoRedoContext & rContext)
    2580             : {
    2581           0 :     SwDoc & rDoc = rContext.GetDoc();
    2582             :     _DEBUG_REDLINE( &rDoc )
    2583             : 
    2584           0 :     if( pInsRowUndo )
    2585             :     {
    2586           0 :         pInsRowUndo->RedoImpl(rContext);
    2587             :     }
    2588             : 
    2589           0 :     SwTableNode* pTblNd = 0;
    2590           0 :     for( size_t n = 0; n < pArr->size(); ++n )
    2591             :     {
    2592           0 :         _UndoTblCpyTbl_Entry* pEntry = &(*pArr)[ n ];
    2593           0 :         sal_uLong nSttPos = pEntry->nBoxIdx + pEntry->nOffset;
    2594           0 :         SwStartNode* pSNd = rDoc.GetNodes()[ nSttPos ]->StartOfSectionNode();
    2595           0 :         if( !pTblNd )
    2596           0 :             pTblNd = pSNd->FindTableNode();
    2597             : 
    2598           0 :         SwTableBox& rBox = *pTblNd->GetTable().GetTblBox( nSttPos );
    2599             : 
    2600           0 :         SwNodeIndex aInsIdx( *rBox.GetSttNd(), 1 );
    2601             : 
    2602             :         // b62341295: Redline for copying tables - Start.
    2603           0 :         rDoc.GetNodes().MakeTxtNode( aInsIdx, (SwTxtFmtColl*)rDoc.GetDfltTxtFmtColl() );
    2604           0 :         SwPaM aPam( aInsIdx.GetNode(), *rBox.GetSttNd()->EndOfSectionNode());
    2605           0 :         SwUndo* pUndo = IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ) ? 0 : new SwUndoDelete( aPam, true );
    2606           0 :         if( pEntry->pUndo )
    2607             :         {
    2608           0 :             pEntry->pUndo->UndoImpl(rContext);
    2609           0 :             if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ) )
    2610             :             {
    2611             :                 // PrepareRedline has to be called with the beginning of the old content
    2612             :                 // When new and old content has been joined, the rIter.pAktPam has been set
    2613             :                 // by the Undo operation to this point.
    2614             :                 // Otherwise aInsIdx has been moved during the Undo operation
    2615           0 :                 if( pEntry->bJoin )
    2616             :                 {
    2617             :                     SwPaM const& rLastPam =
    2618           0 :                         rContext.GetCursorSupplier().GetCurrentShellCursor();
    2619           0 :                     pUndo = PrepareRedline( &rDoc, rBox, *rLastPam.GetPoint(),
    2620           0 :                                             pEntry->bJoin, true );
    2621             :                 }
    2622             :                 else
    2623             :                 {
    2624           0 :                     SwPosition aTmpPos( aInsIdx );
    2625           0 :                     pUndo = PrepareRedline( &rDoc, rBox, aTmpPos, pEntry->bJoin, true );
    2626             :                 }
    2627             :             }
    2628           0 :             delete pEntry->pUndo;
    2629           0 :             pEntry->pUndo = 0;
    2630             :         }
    2631           0 :         pEntry->pUndo = pUndo;
    2632             :         // b62341295: Redline for copying tables - End.
    2633             : 
    2634           0 :         aInsIdx = rBox.GetSttIdx() + 1;
    2635           0 :         rDoc.GetNodes().Delete( aInsIdx, 1 );
    2636             : 
    2637           0 :         SfxItemSet aTmpSet( rDoc.GetAttrPool(), RES_BOXATR_FORMAT, RES_BOXATR_VALUE,
    2638           0 :                                                 RES_VERT_ORIENT, RES_VERT_ORIENT, 0 );
    2639           0 :         aTmpSet.Put( rBox.GetFrmFmt()->GetAttrSet() );
    2640           0 :         if( aTmpSet.Count() )
    2641             :         {
    2642           0 :             SwFrmFmt* pBoxFmt = rBox.ClaimFrmFmt();
    2643           0 :             pBoxFmt->ResetFmtAttr( RES_BOXATR_FORMAT, RES_BOXATR_VALUE );
    2644           0 :             pBoxFmt->ResetFmtAttr( RES_VERT_ORIENT );
    2645             :         }
    2646           0 :         if( pEntry->pBoxNumAttr )
    2647             :         {
    2648           0 :             rBox.ClaimFrmFmt()->SetFmtAttr( *pEntry->pBoxNumAttr );
    2649           0 :             delete pEntry->pBoxNumAttr, pEntry->pBoxNumAttr = 0;
    2650             :         }
    2651             : 
    2652           0 :         if( aTmpSet.Count() )
    2653             :         {
    2654           0 :             pEntry->pBoxNumAttr = new SfxItemSet( rDoc.GetAttrPool(),
    2655             :                                     RES_BOXATR_FORMAT, RES_BOXATR_VALUE,
    2656           0 :                                     RES_VERT_ORIENT, RES_VERT_ORIENT, 0 );
    2657           0 :             pEntry->pBoxNumAttr->Put( aTmpSet );
    2658             :         }
    2659             : 
    2660           0 :         pEntry->nOffset = rBox.GetSttIdx() - pEntry->nBoxIdx;
    2661           0 :     }
    2662             :     _DEBUG_REDLINE( &rDoc )
    2663           0 : }
    2664             : 
    2665           0 : void SwUndoTblCpyTbl::AddBoxBefore( const SwTableBox& rBox, bool bDelCntnt )
    2666             : {
    2667           0 :     if( !pArr->empty() && !bDelCntnt )
    2668           0 :         return;
    2669             : 
    2670           0 :     _UndoTblCpyTbl_Entry* pEntry = new _UndoTblCpyTbl_Entry( rBox );
    2671           0 :     pArr->push_back( pEntry );
    2672             : 
    2673           0 :     SwDoc* pDoc = rBox.GetFrmFmt()->GetDoc();
    2674             :     _DEBUG_REDLINE( pDoc )
    2675           0 :     if( bDelCntnt )
    2676             :     {
    2677           0 :         SwNodeIndex aInsIdx( *rBox.GetSttNd(), 1 );
    2678           0 :         pDoc->GetNodes().MakeTxtNode( aInsIdx, (SwTxtFmtColl*)pDoc->GetDfltTxtFmtColl() );
    2679           0 :         SwPaM aPam( aInsIdx.GetNode(), *rBox.GetSttNd()->EndOfSectionNode() );
    2680             : 
    2681           0 :         if( !pDoc->getIDocumentRedlineAccess().IsRedlineOn() )
    2682           0 :             pEntry->pUndo = new SwUndoDelete( aPam, true );
    2683             :     }
    2684             : 
    2685           0 :     pEntry->pBoxNumAttr = new SfxItemSet( pDoc->GetAttrPool(),
    2686             :                                     RES_BOXATR_FORMAT, RES_BOXATR_VALUE,
    2687           0 :                                     RES_VERT_ORIENT, RES_VERT_ORIENT, 0 );
    2688           0 :     pEntry->pBoxNumAttr->Put( rBox.GetFrmFmt()->GetAttrSet() );
    2689           0 :     if( !pEntry->pBoxNumAttr->Count() )
    2690           0 :         delete pEntry->pBoxNumAttr, pEntry->pBoxNumAttr = 0;
    2691             :     _DEBUG_REDLINE( pDoc )
    2692             : }
    2693             : 
    2694           0 : void SwUndoTblCpyTbl::AddBoxAfter( const SwTableBox& rBox, const SwNodeIndex& rIdx, bool bDelCntnt )
    2695             : {
    2696           0 :     _UndoTblCpyTbl_Entry* pEntry = &(*pArr).back();
    2697             : 
    2698             :     // If the content was deleted than remove also the temporarily created node
    2699           0 :     if( bDelCntnt )
    2700             :     {
    2701           0 :         SwDoc* pDoc = rBox.GetFrmFmt()->GetDoc();
    2702             :         _DEBUG_REDLINE( pDoc )
    2703             : 
    2704           0 :         if( pDoc->getIDocumentRedlineAccess().IsRedlineOn() )
    2705             :         {
    2706           0 :             SwPosition aTmpPos( rIdx );
    2707           0 :             pEntry->pUndo = PrepareRedline( pDoc, rBox, aTmpPos, pEntry->bJoin, false );
    2708             :         }
    2709           0 :         SwNodeIndex aDelIdx( *rBox.GetSttNd(), 1 );
    2710           0 :         rBox.GetFrmFmt()->GetDoc()->GetNodes().Delete( aDelIdx, 1 );
    2711             :         _DEBUG_REDLINE( pDoc )
    2712             :     }
    2713             : 
    2714           0 :     pEntry->nOffset = rBox.GetSttIdx() - pEntry->nBoxIdx;
    2715           0 : }
    2716             : 
    2717             : // PrepareRedline is called from AddBoxAfter() and from Redo() in slightly different situations.
    2718             : // bRedo is set by calling from Redo()
    2719             : // rJoin is false by calling from AddBoxAfter() and will be set if the old and new content has
    2720             : // been merged.
    2721             : // rJoin is true if Redo() is calling and the content has already been merged
    2722             : 
    2723           0 : SwUndo* SwUndoTblCpyTbl::PrepareRedline( SwDoc* pDoc, const SwTableBox& rBox,
    2724             :     const SwPosition& rPos, bool& rJoin, bool bRedo )
    2725             : {
    2726           0 :     SwUndo *pUndo = 0;
    2727             :     // b62341295: Redline for copying tables
    2728             :     // What's to do?
    2729             :     // Mark the cell content before rIdx as insertion,
    2730             :     // mark the cell content behind rIdx as deletion
    2731             :     // merge text nodes at rIdx if possible
    2732           0 :     RedlineMode_t eOld = pDoc->getIDocumentRedlineAccess().GetRedlineMode();
    2733           0 :     pDoc->getIDocumentRedlineAccess().SetRedlineMode_intern((RedlineMode_t)( ( eOld | nsRedlineMode_t::REDLINE_DONTCOMBINE_REDLINES ) &
    2734           0 :                                      ~nsRedlineMode_t::REDLINE_IGNORE ));
    2735           0 :     SwPosition aInsertEnd( rPos );
    2736             :     SwTxtNode* pTxt;
    2737           0 :     if( !rJoin )
    2738             :     {
    2739             :         // If the content is not merged, the end of the insertion is at the end of the node
    2740             :         // _before_ the given position rPos
    2741           0 :         --aInsertEnd.nNode;
    2742           0 :         pTxt = aInsertEnd.nNode.GetNode().GetTxtNode();
    2743           0 :         if( pTxt )
    2744             :         {
    2745           0 :             aInsertEnd.nContent.Assign(pTxt, pTxt->GetTxt().getLength());
    2746           0 :             if( !bRedo && rPos.nNode.GetNode().GetTxtNode() )
    2747             :             {   // Try to merge, if not called by Redo()
    2748           0 :                 rJoin = true;
    2749           0 :                 pTxt->JoinNext();
    2750             :             }
    2751             :         }
    2752             :         else
    2753           0 :             aInsertEnd.nContent = SwIndex( 0 );
    2754             :     }
    2755             :     // For joined (merged) contents the start of deletion and end of insertion are identical
    2756             :     // otherwise adjacent nodes.
    2757           0 :     SwPosition aDeleteStart( rJoin ? aInsertEnd : rPos );
    2758           0 :     if( !rJoin )
    2759             :     {
    2760           0 :         pTxt = aDeleteStart.nNode.GetNode().GetTxtNode();
    2761           0 :         if( pTxt )
    2762           0 :             aDeleteStart.nContent.Assign( pTxt, 0 );
    2763             :     }
    2764           0 :     SwPosition aCellEnd( SwNodeIndex( *rBox.GetSttNd()->EndOfSectionNode(), -1 ) );
    2765           0 :     pTxt = aCellEnd.nNode.GetNode().GetTxtNode();
    2766           0 :     if( pTxt )
    2767           0 :         aCellEnd.nContent.Assign(pTxt, pTxt->GetTxt().getLength());
    2768           0 :     if( aDeleteStart != aCellEnd )
    2769             :     {   // If the old (deleted) part is not empty, here we are...
    2770           0 :         SwPaM aDeletePam( aDeleteStart, aCellEnd );
    2771           0 :         pUndo = new SwUndoRedlineDelete( aDeletePam, UNDO_DELETE );
    2772           0 :         pDoc->getIDocumentRedlineAccess().AppendRedline( new SwRangeRedline( nsRedlineType_t::REDLINE_DELETE, aDeletePam ), true );
    2773             :     }
    2774           0 :     else if( !rJoin ) // If the old part is empty and joined, we are finished
    2775             :     {   // if it is not joined, we have to delete this empty paragraph
    2776           0 :         aCellEnd = SwPosition(
    2777           0 :             SwNodeIndex( *rBox.GetSttNd()->EndOfSectionNode() ));
    2778           0 :         SwPaM aTmpPam( aDeleteStart, aCellEnd );
    2779           0 :         pUndo = new SwUndoDelete( aTmpPam, true );
    2780             :     }
    2781           0 :     SwPosition aCellStart( SwNodeIndex( *rBox.GetSttNd(), 2 ) );
    2782           0 :     pTxt = aCellStart.nNode.GetNode().GetTxtNode();
    2783           0 :     if( pTxt )
    2784           0 :         aCellStart.nContent.Assign( pTxt, 0 );
    2785           0 :     if( aCellStart != aInsertEnd ) // An empty insertion will not been marked
    2786             :     {
    2787           0 :         SwPaM aTmpPam( aCellStart, aInsertEnd );
    2788           0 :         pDoc->getIDocumentRedlineAccess().AppendRedline( new SwRangeRedline( nsRedlineType_t::REDLINE_INSERT, aTmpPam ), true );
    2789             :     }
    2790             : 
    2791           0 :     pDoc->getIDocumentRedlineAccess().SetRedlineMode_intern( eOld );
    2792           0 :     return pUndo;
    2793             : }
    2794             : 
    2795           0 : bool SwUndoTblCpyTbl::InsertRow( SwTable& rTbl, const SwSelBoxes& rBoxes,
    2796             :                                 sal_uInt16 nCnt )
    2797             : {
    2798           0 :     SwTableNode* pTblNd = (SwTableNode*)rTbl.GetTabSortBoxes()[0]->
    2799           0 :                                 GetSttNd()->FindTableNode();
    2800             : 
    2801             :     pInsRowUndo = new SwUndoTblNdsChg( UNDO_TABLE_INSROW, rBoxes, *pTblNd,
    2802           0 :                                        0, 0, nCnt, true, false );
    2803           0 :     SwTableSortBoxes aTmpLst( rTbl.GetTabSortBoxes() );
    2804             : 
    2805           0 :     bool bRet = rTbl.InsertRow( rTbl.GetFrmFmt()->GetDoc(), rBoxes, nCnt, true );
    2806           0 :     if( bRet )
    2807           0 :         pInsRowUndo->SaveNewBoxes( *pTblNd, aTmpLst );
    2808             :     else
    2809           0 :         delete pInsRowUndo, pInsRowUndo = 0;
    2810           0 :     return bRet;
    2811             : }
    2812             : 
    2813           0 : bool SwUndoTblCpyTbl::IsEmpty() const
    2814             : {
    2815           0 :     return !pInsRowUndo && pArr->empty();
    2816             : }
    2817             : 
    2818           0 : SwUndoCpyTbl::SwUndoCpyTbl()
    2819           0 :     : SwUndo( UNDO_CPYTBL ), pDel( 0 ), nTblNode( 0 )
    2820             : {
    2821           0 : }
    2822             : 
    2823           0 : SwUndoCpyTbl::~SwUndoCpyTbl()
    2824             : {
    2825           0 :     delete pDel;
    2826           0 : }
    2827             : 
    2828           0 : void SwUndoCpyTbl::UndoImpl(::sw::UndoRedoContext & rContext)
    2829             : {
    2830           0 :     SwDoc & rDoc = rContext.GetDoc();
    2831           0 :     SwTableNode* pTNd = rDoc.GetNodes()[ nTblNode ]->GetTableNode();
    2832             : 
    2833             :     // move hard page breaks into next node
    2834           0 :     SwCntntNode* pNextNd = rDoc.GetNodes()[ pTNd->EndOfSectionIndex()+1 ]->GetCntntNode();
    2835           0 :     if( pNextNd )
    2836             :     {
    2837           0 :         SwFrmFmt* pTableFmt = pTNd->GetTable().GetFrmFmt();
    2838             :         const SfxPoolItem *pItem;
    2839             : 
    2840           0 :         if( SfxItemState::SET == pTableFmt->GetItemState( RES_PAGEDESC,
    2841           0 :             false, &pItem ) )
    2842           0 :             pNextNd->SetAttr( *pItem );
    2843             : 
    2844           0 :         if( SfxItemState::SET == pTableFmt->GetItemState( RES_BREAK,
    2845           0 :             false, &pItem ) )
    2846           0 :             pNextNd->SetAttr( *pItem );
    2847             :     }
    2848             : 
    2849           0 :     SwPaM aPam( *pTNd, *pTNd->EndOfSectionNode(), 0 , 1 );
    2850           0 :     pDel = new SwUndoDelete( aPam, true );
    2851           0 : }
    2852             : 
    2853           0 : void SwUndoCpyTbl::RedoImpl(::sw::UndoRedoContext & rContext)
    2854             : {
    2855           0 :     pDel->UndoImpl(rContext);
    2856           0 :     delete pDel, pDel = 0;
    2857           0 : }
    2858             : 
    2859           0 : SwUndoSplitTbl::SwUndoSplitTbl( const SwTableNode& rTblNd,
    2860             :     SwSaveRowSpan* pRowSp, sal_uInt16 eMode, bool bNewSize )
    2861             :     : SwUndo( UNDO_SPLIT_TABLE ),
    2862           0 :     nTblNode( rTblNd.GetIndex() ), nOffset( 0 ), mpSaveRowSpan( pRowSp ), pSavTbl( 0 ),
    2863           0 :     pHistory( 0 ), nMode( eMode ), nFmlEnd( 0 ), bCalcNewSize( bNewSize )
    2864             : {
    2865           0 :     switch( nMode )
    2866             :     {
    2867             :     case HEADLINE_BOXATRCOLLCOPY:
    2868           0 :             pHistory = new SwHistory;
    2869             :             // no break
    2870             :     case HEADLINE_BORDERCOPY:
    2871             :     case HEADLINE_BOXATTRCOPY:
    2872           0 :         pSavTbl = new _SaveTable( rTblNd.GetTable(), 1, false );
    2873           0 :         break;
    2874             :     }
    2875           0 : }
    2876             : 
    2877           0 : SwUndoSplitTbl::~SwUndoSplitTbl()
    2878             : {
    2879           0 :     delete pSavTbl;
    2880           0 :     delete pHistory;
    2881           0 :     delete mpSaveRowSpan;
    2882           0 : }
    2883             : 
    2884           0 : void SwUndoSplitTbl::UndoImpl(::sw::UndoRedoContext & rContext)
    2885             : {
    2886           0 :     SwDoc *const pDoc = & rContext.GetDoc();
    2887           0 :     SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());
    2888             : 
    2889           0 :     SwNodeIndex& rIdx = pPam->GetPoint()->nNode;
    2890           0 :     rIdx = nTblNode + nOffset;
    2891           0 :     pPam->GetPoint()->nContent.Assign(rIdx.GetNode().GetCntntNode(), 0);
    2892             :     assert(rIdx.GetNode().GetCntntNode()->Len() == 0); // empty para inserted
    2893             : 
    2894             :     {
    2895             :         // avoid asserts from ~SwIndexReg
    2896           0 :         SwNodeIndex const idx(pDoc->GetNodes(), nTblNode + nOffset);
    2897             :         {
    2898           0 :             SwPaM pam(idx);
    2899           0 :             pam.Move(fnMoveBackward, fnGoCntnt);
    2900           0 :             ::PaMCorrAbs(*pPam, *pam.GetPoint());
    2901             :         }
    2902             : 
    2903             :         // remove implicitly created paragraph again
    2904           0 :         pDoc->GetNodes().Delete( idx, 1 );
    2905             :     }
    2906             : 
    2907           0 :     rIdx = nTblNode + nOffset;
    2908           0 :     SwTableNode* pTblNd = rIdx.GetNode().GetTableNode();
    2909           0 :     SwTable& rTbl = pTblNd->GetTable();
    2910             : 
    2911           0 :     SwTableFmlUpdate aMsgHnt( &rTbl );
    2912           0 :     aMsgHnt.eFlags = TBL_BOXPTR;
    2913           0 :     pDoc->getIDocumentFieldsAccess().UpdateTblFlds( &aMsgHnt );
    2914             : 
    2915           0 :     switch( nMode )
    2916             :     {
    2917             :     case HEADLINE_BOXATRCOLLCOPY:
    2918           0 :         if( pHistory )
    2919           0 :             pHistory->TmpRollback( pDoc, nFmlEnd );
    2920             :         // no break
    2921             :     case HEADLINE_BOXATTRCOPY:
    2922             :     case HEADLINE_BORDERCOPY:
    2923             :         {
    2924           0 :             pSavTbl->CreateNew( rTbl, false );
    2925           0 :             pSavTbl->RestoreAttr( rTbl );
    2926             :         }
    2927           0 :         break;
    2928             : 
    2929             :     case HEADLINE_CNTNTCOPY:
    2930             :         // the created first line has to be removed again
    2931             :         {
    2932           0 :             SwSelBoxes aSelBoxes;
    2933           0 :             SwTableBox* pBox = rTbl.GetTblBox( nTblNode + nOffset + 1 );
    2934           0 :             rTbl.SelLineFromBox( pBox, aSelBoxes, true );
    2935           0 :             _FndBox aTmpBox( 0, 0 );
    2936           0 :             aTmpBox.SetTableLines( aSelBoxes, rTbl );
    2937           0 :             aTmpBox.DelFrms( rTbl );
    2938           0 :             rTbl.DeleteSel( pDoc, aSelBoxes, 0, 0, false, false );
    2939             :         }
    2940           0 :         break;
    2941             :     }
    2942             : 
    2943           0 :     pDoc->GetNodes().MergeTable( rIdx );
    2944             : 
    2945           0 :     if( pHistory )
    2946             :     {
    2947           0 :         pHistory->TmpRollback( pDoc, 0 );
    2948           0 :         pHistory->SetTmpEnd( pHistory->Count() );
    2949             :     }
    2950           0 :     if( mpSaveRowSpan )
    2951             :     {
    2952           0 :         pTblNd = rIdx.GetNode().FindTableNode();
    2953           0 :         if( pTblNd )
    2954           0 :             pTblNd->GetTable().RestoreRowSpan( *mpSaveRowSpan );
    2955             :     }
    2956           0 :     ClearFEShellTabCols();
    2957           0 : }
    2958             : 
    2959           0 : void SwUndoSplitTbl::RedoImpl(::sw::UndoRedoContext & rContext)
    2960             : {
    2961           0 :     SwDoc *const pDoc = & rContext.GetDoc();
    2962           0 :     SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());
    2963             : 
    2964           0 :     pPam->DeleteMark();
    2965           0 :     pPam->GetPoint()->nNode = nTblNode;
    2966           0 :     pDoc->SplitTable( *pPam->GetPoint(), nMode, bCalcNewSize );
    2967             : 
    2968           0 :     ClearFEShellTabCols();
    2969           0 : }
    2970             : 
    2971           0 : void SwUndoSplitTbl::RepeatImpl(::sw::RepeatContext & rContext)
    2972             : {
    2973           0 :     SwPaM *const pPam = & rContext.GetRepeatPaM();
    2974           0 :     SwDoc *const pDoc = & rContext.GetDoc();
    2975             : 
    2976           0 :     pDoc->SplitTable( *pPam->GetPoint(), nMode, bCalcNewSize );
    2977           0 :     ClearFEShellTabCols();
    2978           0 : }
    2979             : 
    2980           0 : void SwUndoSplitTbl::SaveFormula( SwHistory& rHistory )
    2981             : {
    2982           0 :     if( !pHistory )
    2983           0 :         pHistory = new SwHistory;
    2984             : 
    2985           0 :     nFmlEnd = rHistory.Count();
    2986           0 :     pHistory->Move( 0, &rHistory );
    2987           0 : }
    2988             : 
    2989           0 : SwUndoMergeTbl::SwUndoMergeTbl( const SwTableNode& rTblNd,
    2990             :                                 const SwTableNode& rDelTblNd,
    2991             :                                 bool bWithPrv, sal_uInt16 nMd )
    2992             :     : SwUndo( UNDO_MERGE_TABLE ), pSavTbl( 0 ),
    2993           0 :     pHistory( 0 ), nMode( nMd ), bWithPrev( bWithPrv )
    2994             : {
    2995             :     // memorize end node of the last table cell that'll stay in position
    2996           0 :     if( bWithPrev )
    2997           0 :         nTblNode = rDelTblNd.EndOfSectionIndex() - 1;
    2998             :     else
    2999           0 :         nTblNode = rTblNd.EndOfSectionIndex() - 1;
    3000             : 
    3001           0 :     aName = rDelTblNd.GetTable().GetFrmFmt()->GetName();
    3002           0 :     pSavTbl = new _SaveTable( rDelTblNd.GetTable() );
    3003             : 
    3004           0 :     pSavHdl = bWithPrev ? new _SaveTable( rTblNd.GetTable(), 1 ) : 0;
    3005           0 : }
    3006             : 
    3007           0 : SwUndoMergeTbl::~SwUndoMergeTbl()
    3008             : {
    3009           0 :     delete pSavTbl;
    3010           0 :     delete pSavHdl;
    3011           0 :     delete pHistory;
    3012           0 : }
    3013             : 
    3014           0 : void SwUndoMergeTbl::UndoImpl(::sw::UndoRedoContext & rContext)
    3015             : {
    3016           0 :     SwDoc *const pDoc = & rContext.GetDoc();
    3017           0 :     SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());
    3018             : 
    3019           0 :     pPam->DeleteMark();
    3020           0 :     SwNodeIndex& rIdx = pPam->GetPoint()->nNode;
    3021           0 :     rIdx = nTblNode;
    3022             : 
    3023           0 :     SwTableNode* pTblNd = rIdx.GetNode().FindTableNode();
    3024           0 :     SwTable* pTbl = &pTblNd->GetTable();
    3025             : 
    3026           0 :     SwTableFmlUpdate aMsgHnt( pTbl );
    3027           0 :     aMsgHnt.eFlags = TBL_BOXPTR;
    3028           0 :     pDoc->getIDocumentFieldsAccess().UpdateTblFlds( &aMsgHnt );
    3029             : 
    3030             :     // get lines for layout update
    3031           0 :     _FndBox aFndBox( 0, 0 );
    3032           0 :     aFndBox.SetTableLines( *pTbl );
    3033           0 :     aFndBox.DelFrms( *pTbl );
    3034             :     // ? TL_CHART2: notification or locking of controller required ?
    3035             : 
    3036           0 :     SwTableNode* pNew = pDoc->GetNodes().SplitTable( rIdx, true, false );
    3037             : 
    3038             :     // update layout
    3039           0 :     aFndBox.MakeFrms( *pTbl );
    3040             :     // ? TL_CHART2: notification or locking of controller required ?
    3041             : 
    3042           0 :     if( bWithPrev )
    3043             :     {
    3044             :         // move name
    3045           0 :         pNew->GetTable().GetFrmFmt()->SetName( pTbl->GetFrmFmt()->GetName() );
    3046           0 :         pSavHdl->RestoreAttr( pNew->GetTable() );
    3047             :     }
    3048             :     else
    3049           0 :         pTbl = &pNew->GetTable();
    3050             : 
    3051           0 :     pTbl->GetFrmFmt()->SetName( aName );
    3052           0 :     pSavTbl->RestoreAttr( *pTbl );
    3053             : 
    3054           0 :     if( pHistory )
    3055             :     {
    3056           0 :         pHistory->TmpRollback( pDoc, 0 );
    3057           0 :         pHistory->SetTmpEnd( pHistory->Count() );
    3058             :     }
    3059             : 
    3060             :     // create frames for the new table
    3061           0 :     SwNodeIndex aTmpIdx( *pNew );
    3062           0 :     pNew->MakeFrms( &aTmpIdx );
    3063             : 
    3064             :     // position cursor somewhere in content
    3065           0 :     SwCntntNode* pCNd = pDoc->GetNodes().GoNext( &rIdx );
    3066           0 :     pPam->GetPoint()->nContent.Assign( pCNd, 0 );
    3067             : 
    3068           0 :     ClearFEShellTabCols();
    3069             : 
    3070             :     // TL_CHART2: need to inform chart of probably changed cell names
    3071           0 :     SwChartDataProvider *pPCD = pDoc->getIDocumentChartDataProviderAccess().GetChartDataProvider();
    3072           0 :     if (pPCD)
    3073             :     {
    3074           0 :         pDoc->UpdateCharts( pTbl->GetFrmFmt()->GetName() );
    3075           0 :         pDoc->UpdateCharts( pNew->GetTable().GetFrmFmt()->GetName() );
    3076           0 :     }
    3077           0 : }
    3078             : 
    3079           0 : void SwUndoMergeTbl::RedoImpl(::sw::UndoRedoContext & rContext)
    3080             : {
    3081           0 :     SwDoc *const pDoc = & rContext.GetDoc();
    3082           0 :     SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());
    3083             : 
    3084           0 :     pPam->DeleteMark();
    3085           0 :     pPam->GetPoint()->nNode = nTblNode;
    3086           0 :     if( bWithPrev )
    3087           0 :         pPam->GetPoint()->nNode = nTblNode + 3;
    3088             :     else
    3089           0 :         pPam->GetPoint()->nNode = nTblNode;
    3090             : 
    3091           0 :     pDoc->MergeTable( *pPam->GetPoint(), bWithPrev, nMode );
    3092             : 
    3093           0 :     ClearFEShellTabCols();
    3094           0 : }
    3095             : 
    3096           0 : void SwUndoMergeTbl::RepeatImpl(::sw::RepeatContext & rContext)
    3097             : {
    3098           0 :     SwDoc *const pDoc = & rContext.GetDoc();
    3099           0 :     SwPaM *const pPam = & rContext.GetRepeatPaM();
    3100             : 
    3101           0 :     pDoc->MergeTable( *pPam->GetPoint(), bWithPrev, nMode );
    3102           0 :     ClearFEShellTabCols();
    3103           0 : }
    3104             : 
    3105           0 : void SwUndoMergeTbl::SaveFormula( SwHistory& rHistory )
    3106             : {
    3107           0 :     if( !pHistory )
    3108           0 :         pHistory = new SwHistory;
    3109           0 :     pHistory->Move( 0, &rHistory );
    3110           0 : }
    3111             : 
    3112         172 : void InsertSort( std::vector<sal_uInt16>& rArr, sal_uInt16 nIdx, sal_uInt16* pInsPos )
    3113             : {
    3114         172 :     size_t nO = rArr.size();
    3115         172 :     size_t nU = 0;
    3116         172 :     if( nO > 0 )
    3117             :     {
    3118         128 :         nO--;
    3119         514 :         while( nU <= nO )
    3120             :         {
    3121         258 :             const size_t nM = nU + ( nO - nU ) / 2;
    3122         258 :             if ( rArr[nM] == nIdx )
    3123             :             {
    3124             :                 OSL_FAIL( "Index already exists. This should never happen." );
    3125         172 :                 return;
    3126             :             }
    3127         258 :             if( rArr[nM] < nIdx )
    3128         128 :                 nU = nM + 1;
    3129         130 :             else if( nM == 0 )
    3130           0 :                 break;
    3131             :             else
    3132         130 :                 nO = nM - 1;
    3133             :         }
    3134             :     }
    3135         172 :     rArr.insert( rArr.begin() + nU, nIdx );
    3136         172 :     if( pInsPos )
    3137           0 :         *pInsPos = nU;
    3138         270 : }
    3139             : 
    3140             : #if OSL_DEBUG_LEVEL > 0
    3141             : void CheckTable( const SwTable& rTbl )
    3142             : {
    3143             :     const SwNodes& rNds = rTbl.GetFrmFmt()->GetDoc()->GetNodes();
    3144             :     const SwTableSortBoxes& rSrtArr = rTbl.GetTabSortBoxes();
    3145             :     for (size_t n = 0; n < rSrtArr.size(); ++n)
    3146             :     {
    3147             :         const SwTableBox* pBox = rSrtArr[ n ];
    3148             :         const SwNode* pNd = pBox->GetSttNd();
    3149             :         OSL_ENSURE( rNds[ pBox->GetSttIdx() ] == pNd, "Box with wrong StartNode"  );
    3150             :     }
    3151             : }
    3152             : #endif
    3153             : 
    3154             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10