LCOV - code coverage report
Current view: top level - sw/source/core/docnode - ndtbl.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 767 2336 32.8 %
Date: 2014-11-03 Functions: 38 88 43.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 <com/sun/star/chart2/XChartDocument.hpp>
      21             : #include <fesh.hxx>
      22             : #include <hintids.hxx>
      23             : #include <editeng/lrspitem.hxx>
      24             : #include <editeng/formatbreakitem.hxx>
      25             : #include <editeng/protitem.hxx>
      26             : #include <editeng/boxitem.hxx>
      27             : #include <svl/stritem.hxx>
      28             : #include <editeng/shaditem.hxx>
      29             : #include <fmtfsize.hxx>
      30             : #include <fmtornt.hxx>
      31             : #include <fmtfordr.hxx>
      32             : #include <fmtpdsc.hxx>
      33             : #include <fmtanchr.hxx>
      34             : #include <fmtlsplt.hxx>
      35             : #include <frmatr.hxx>
      36             : #include <charatr.hxx>
      37             : #include <cellfrm.hxx>
      38             : #include <pagefrm.hxx>
      39             : #include <tabcol.hxx>
      40             : #include <doc.hxx>
      41             : #include <IDocumentUndoRedo.hxx>
      42             : #include <UndoManager.hxx>
      43             : #include <DocumentSettingManager.hxx>
      44             : #include <IDocumentChartDataProviderAccess.hxx>
      45             : #include <IDocumentRedlineAccess.hxx>
      46             : #include <IDocumentStylePoolAccess.hxx>
      47             : #include <IDocumentFieldsAccess.hxx>
      48             : #include <IDocumentLayoutAccess.hxx>
      49             : #include <IDocumentState.hxx>
      50             : #include <cntfrm.hxx>
      51             : #include <pam.hxx>
      52             : #include <swcrsr.hxx>
      53             : #include <viscrs.hxx>
      54             : #include <swtable.hxx>
      55             : #include <swundo.hxx>
      56             : #include <tblsel.hxx>
      57             : #include <fldbas.hxx>
      58             : #include <poolfmt.hxx>
      59             : #include <tabfrm.hxx>
      60             : #include <UndoCore.hxx>
      61             : #include <UndoRedline.hxx>
      62             : #include <UndoDelete.hxx>
      63             : #include <UndoNumbering.hxx>
      64             : #include <UndoTable.hxx>
      65             : #include <hints.hxx>
      66             : #include <tblafmt.hxx>
      67             : #include <swcache.hxx>
      68             : #include <ddefld.hxx>
      69             : #include <frminf.hxx>
      70             : #include <cellatr.hxx>
      71             : #include <swtblfmt.hxx>
      72             : #include <swddetbl.hxx>
      73             : #include <mvsave.hxx>
      74             : #include <docary.hxx>
      75             : #include <redline.hxx>
      76             : #include <rolbck.hxx>
      77             : #include <tblrwcl.hxx>
      78             : #include <editsh.hxx>
      79             : #include <txtfrm.hxx>
      80             : #include <ftnfrm.hxx>
      81             : #include <section.hxx>
      82             : #include <frmtool.hxx>
      83             : #include <node2lay.hxx>
      84             : #include <comcore.hrc>
      85             : #include "docsh.hxx"
      86             : #include <unochart.hxx>
      87             : #include <node.hxx>
      88             : #include <ndtxt.hxx>
      89             : #include <cstdlib>
      90             : #include <map>
      91             : #include <algorithm>
      92             : #include <rootfrm.hxx>
      93             : #include <fldupde.hxx>
      94             : #include <switerator.hxx>
      95             : #include <o3tl/numeric.hxx>
      96             : #include <boost/foreach.hpp>
      97             : 
      98             : #ifdef DBG_UTIL
      99             : #define CHECK_TABLE(t) (t).CheckConsistency();
     100             : #else
     101             : #define CHECK_TABLE(t)
     102             : #endif
     103             : 
     104             : using ::editeng::SvxBorderLine;
     105             : using namespace ::com::sun::star;
     106             : 
     107             : const sal_Unicode T2T_PARA = 0x0a;
     108             : 
     109         382 : static void lcl_SetDfltBoxAttr( SwFrmFmt& rFmt, sal_uInt8 nId )
     110             : {
     111         382 :     bool bTop = false, bBottom = false, bLeft = false, bRight = false;
     112         382 :     switch ( nId )
     113             :     {
     114          70 :     case 0: bTop = bBottom = bLeft = true;          break;
     115         172 :     case 1: bTop = bBottom = bLeft = bRight = true; break;
     116          70 :     case 2: bBottom = bLeft = true;                 break;
     117          70 :     case 3: bBottom = bLeft = bRight = true;        break;
     118             :     }
     119             : 
     120         382 :     const bool bHTML = rFmt.getIDocumentSettingAccess()->get(IDocumentSettingAccess::HTML_MODE);
     121         382 :     Color aCol( bHTML ? COL_GRAY : COL_BLACK );
     122         382 :     SvxBorderLine aLine( &aCol, DEF_LINE_WIDTH_0 );
     123         382 :     if ( bHTML )
     124             :     {
     125           0 :         aLine.SetBorderLineStyle(table::BorderLineStyle::DOUBLE);
     126           0 :         aLine.SetWidth( DEF_LINE_WIDTH_0 );
     127             :     }
     128         382 :     SvxBoxItem aBox(RES_BOX); aBox.SetDistance( 55 );
     129         382 :     if ( bTop )
     130         242 :         aBox.SetLine( &aLine, BOX_LINE_TOP );
     131         382 :     if ( bBottom )
     132         382 :         aBox.SetLine( &aLine, BOX_LINE_BOTTOM );
     133         382 :     if ( bLeft )
     134         382 :         aBox.SetLine( &aLine, BOX_LINE_LEFT );
     135         382 :     if ( bRight )
     136         242 :         aBox.SetLine( &aLine, BOX_LINE_RIGHT );
     137         382 :     rFmt.SetFmtAttr( aBox );
     138         382 : }
     139             : 
     140             : typedef std::map<SwFrmFmt *, SwTableBoxFmt *> DfltBoxAttrMap_t;
     141             : typedef std::vector<DfltBoxAttrMap_t *> DfltBoxAttrList_t;
     142             : 
     143             : static void
     144           0 : lcl_SetDfltBoxAttr(SwTableBox& rBox, DfltBoxAttrList_t & rBoxFmtArr,
     145             :         sal_uInt8 const nId, SwTableAutoFmt const*const pAutoFmt = 0)
     146             : {
     147           0 :     DfltBoxAttrMap_t * pMap = rBoxFmtArr[ nId ];
     148           0 :     if (!pMap)
     149             :     {
     150           0 :         pMap = new DfltBoxAttrMap_t;
     151           0 :         rBoxFmtArr[ nId ] = pMap;
     152             :     }
     153             : 
     154           0 :     SwTableBoxFmt* pNewTableBoxFmt = 0;
     155           0 :     SwFrmFmt* pBoxFrmFmt = rBox.GetFrmFmt();
     156           0 :     DfltBoxAttrMap_t::iterator const iter(pMap->find(pBoxFrmFmt));
     157           0 :     if (pMap->end() != iter)
     158             :     {
     159           0 :         pNewTableBoxFmt = iter->second;
     160             :     }
     161             :     else
     162             :     {
     163           0 :         SwDoc* pDoc = pBoxFrmFmt->GetDoc();
     164             :         // format does not exist, so create it
     165           0 :         pNewTableBoxFmt = pDoc->MakeTableBoxFmt();
     166           0 :         pNewTableBoxFmt->SetFmtAttr( pBoxFrmFmt->GetAttrSet().Get( RES_FRM_SIZE ) );
     167             : 
     168           0 :         if( pAutoFmt )
     169           0 :             pAutoFmt->UpdateToSet( nId, (SfxItemSet&)pNewTableBoxFmt->GetAttrSet(),
     170             :                                     SwTableAutoFmt::UPDATE_BOX,
     171           0 :                                     pDoc->GetNumberFormatter( true ) );
     172             :         else
     173           0 :             ::lcl_SetDfltBoxAttr( *pNewTableBoxFmt, nId );
     174             : 
     175           0 :         (*pMap)[pBoxFrmFmt] = pNewTableBoxFmt;
     176             :     }
     177           0 :     rBox.ChgFrmFmt( pNewTableBoxFmt );
     178           0 : }
     179             : 
     180        1032 : static SwTableBoxFmt *lcl_CreateDfltBoxFmt( SwDoc &rDoc, std::vector<SwTableBoxFmt*> &rBoxFmtArr,
     181             :                                     sal_uInt16 nCols, sal_uInt8 nId )
     182             : {
     183        1032 :     if ( !rBoxFmtArr[nId] )
     184             :     {
     185         382 :         SwTableBoxFmt* pBoxFmt = rDoc.MakeTableBoxFmt();
     186         382 :         if( USHRT_MAX != nCols )
     187             :             pBoxFmt->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE,
     188         382 :                                             USHRT_MAX / nCols, 0 ));
     189         382 :         ::lcl_SetDfltBoxAttr( *pBoxFmt, nId );
     190         382 :         rBoxFmtArr[ nId ] = pBoxFmt;
     191             :     }
     192        1032 :     return rBoxFmtArr[nId];
     193             : }
     194             : 
     195           0 : static SwTableBoxFmt *lcl_CreateAFmtBoxFmt( SwDoc &rDoc, std::vector<SwTableBoxFmt*> &rBoxFmtArr,
     196             :                                     const SwTableAutoFmt& rAutoFmt,
     197             :                                     sal_uInt16 nCols, sal_uInt8 nId )
     198             : {
     199           0 :     if( !rBoxFmtArr[nId] )
     200             :     {
     201           0 :         SwTableBoxFmt* pBoxFmt = rDoc.MakeTableBoxFmt();
     202           0 :         rAutoFmt.UpdateToSet( nId, (SfxItemSet&)pBoxFmt->GetAttrSet(),
     203             :                                 SwTableAutoFmt::UPDATE_BOX,
     204           0 :                                 rDoc.GetNumberFormatter( true ) );
     205           0 :         if( USHRT_MAX != nCols )
     206             :             pBoxFmt->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE,
     207           0 :                                             USHRT_MAX / nCols, 0 ));
     208           0 :         rBoxFmtArr[ nId ] = pBoxFmt;
     209             :     }
     210           0 :     return rBoxFmtArr[nId];
     211             : }
     212             : 
     213         295 : SwTableNode* SwDoc::IsIdxInTbl(const SwNodeIndex& rIdx)
     214             : {
     215         295 :     SwTableNode* pTableNd = 0;
     216         295 :     sal_uLong nIndex = rIdx.GetIndex();
     217         544 :     do {
     218         592 :         SwNode* pNd = (SwNode*)GetNodes()[ nIndex ]->StartOfSectionNode();
     219         592 :         if( 0 != ( pTableNd = pNd->GetTableNode() ) )
     220          48 :             break;
     221             : 
     222         544 :         nIndex = pNd->GetIndex();
     223             :     } while ( nIndex );
     224         295 :     return pTableNd;
     225             : }
     226             : 
     227             : /**
     228             :  * Insert a new Box before the InsPos
     229             :  */
     230         122 : bool SwNodes::InsBoxen( SwTableNode* pTblNd,
     231             :                         SwTableLine* pLine,
     232             :                         SwTableBoxFmt* pBoxFmt,
     233             :                         SwTxtFmtColl* pTxtColl,
     234             :                         const SfxItemSet* pAutoAttr,
     235             :                         sal_uInt16 nInsPos,
     236             :                         sal_uInt16 nCnt )
     237             : {
     238         122 :     if( !nCnt )
     239           0 :         return false;
     240             :     OSL_ENSURE( pLine, "No valid Line" );
     241             : 
     242             :     // Move Index after the Line's last Box
     243         122 :     sal_uLong nIdxPos = 0;
     244         122 :     SwTableBox *pPrvBox = 0, *pNxtBox = 0;
     245         122 :     if( !pLine->GetTabBoxes().empty() )
     246             :     {
     247         114 :         if( nInsPos < pLine->GetTabBoxes().size() )
     248             :         {
     249           0 :             if( 0 == (pPrvBox = pLine->FindPreviousBox( pTblNd->GetTable(),
     250           0 :                             pLine->GetTabBoxes()[ nInsPos ] )))
     251           0 :                 pPrvBox = pLine->FindPreviousBox( pTblNd->GetTable() );
     252             :         }
     253             :         else
     254             :         {
     255         114 :             if( 0 == (pNxtBox = pLine->FindNextBox( pTblNd->GetTable(),
     256         114 :                             pLine->GetTabBoxes().back() )))
     257          38 :                 pNxtBox = pLine->FindNextBox( pTblNd->GetTable() );
     258             :         }
     259             :     }
     260           8 :     else if( 0 == ( pNxtBox = pLine->FindNextBox( pTblNd->GetTable() )))
     261           4 :         pPrvBox = pLine->FindPreviousBox( pTblNd->GetTable() );
     262             : 
     263         122 :     if( !pPrvBox && !pNxtBox )
     264             :     {
     265          38 :         bool bSetIdxPos = true;
     266          38 :         if( pTblNd->GetTable().GetTabLines().size() && !nInsPos )
     267             :         {
     268           0 :             const SwTableLine* pTblLn = pLine;
     269           0 :             while( pTblLn->GetUpper() )
     270           0 :                 pTblLn = pTblLn->GetUpper()->GetUpper();
     271             : 
     272           0 :             if( pTblNd->GetTable().GetTabLines()[ 0 ] == pTblLn )
     273             :             {
     274             :                 // Before the Table's first Box
     275           0 :                 while( ( pNxtBox = pLine->GetTabBoxes()[0])->GetTabLines().size() )
     276           0 :                     pLine = pNxtBox->GetTabLines()[0];
     277           0 :                 nIdxPos = pNxtBox->GetSttIdx();
     278           0 :                 bSetIdxPos = false;
     279             :             }
     280             :         }
     281          38 :         if( bSetIdxPos )
     282             :             // Tables without content or at the end; move before the End
     283          38 :             nIdxPos = pTblNd->EndOfSectionIndex();
     284             :     }
     285          84 :     else if( pNxtBox ) // There is a successor
     286          80 :         nIdxPos = pNxtBox->GetSttIdx();
     287             :     else // There is a predecessor
     288           4 :         nIdxPos = pPrvBox->GetSttNd()->EndOfSectionIndex() + 1;
     289             : 
     290         122 :     SwNodeIndex aEndIdx( *this, nIdxPos );
     291         666 :     for( sal_uInt16 n = 0; n < nCnt; ++n )
     292             :     {
     293             :         SwStartNode* pSttNd = new SwStartNode( aEndIdx, ND_STARTNODE,
     294         544 :                                                 SwTableBoxStartNode );
     295         544 :         pSttNd->pStartOfSection = pTblNd;
     296         544 :         new SwEndNode( aEndIdx, *pSttNd );
     297             : 
     298         544 :         pPrvBox = new SwTableBox( pBoxFmt, *pSttNd, pLine );
     299             : 
     300         544 :         SwTableBoxes & rTabBoxes = pLine->GetTabBoxes();
     301         544 :         sal_uInt16 nRealInsPos = nInsPos + n;
     302         544 :         if (nRealInsPos > rTabBoxes.size())
     303           0 :             nRealInsPos = rTabBoxes.size();
     304             : 
     305         544 :         rTabBoxes.insert( rTabBoxes.begin() + nRealInsPos, pPrvBox );
     306             : 
     307        1088 :         if( ! pTxtColl->IsAssignedToListLevelOfOutlineStyle()
     308             : //FEATURE::CONDCOLL
     309         544 :             && RES_CONDTXTFMTCOLL != pTxtColl->Which()
     310             : //FEATURE::CONDCOLL
     311             :         )
     312         544 :             new SwTxtNode( SwNodeIndex( *pSttNd->EndOfSectionNode() ),
     313         544 :                                 pTxtColl, pAutoAttr );
     314             :         else
     315             :         {
     316             :             // Handle Outline numbering correctly!
     317             :             SwTxtNode* pTNd = new SwTxtNode(
     318           0 :                             SwNodeIndex( *pSttNd->EndOfSectionNode() ),
     319           0 :                             (SwTxtFmtColl*)GetDoc()->GetDfltTxtFmtColl(),
     320           0 :                             pAutoAttr );
     321           0 :             pTNd->ChgFmtColl( pTxtColl );
     322             :         }
     323             :     }
     324         122 :     return true;
     325             : }
     326             : 
     327             : /**
     328             :  * Insert a new Table
     329             :  */
     330         314 : const SwTable* SwDoc::InsertTable( const SwInsertTableOptions& rInsTblOpts,
     331             :                                    const SwPosition& rPos, sal_uInt16 nRows,
     332             :                                    sal_uInt16 nCols, sal_Int16 eAdjust,
     333             :                                    const SwTableAutoFmt* pTAFmt,
     334             :                                    const std::vector<sal_uInt16> *pColArr,
     335             :                                    bool bCalledFromShell,
     336             :                                    bool bNewModel )
     337             : {
     338             :     OSL_ENSURE( nRows, "Table without line?" );
     339             :     OSL_ENSURE( nCols, "Table without rows?" );
     340             : 
     341             :     {
     342             :         // Do not copy into Footnotes!
     343         314 :         if( rPos.nNode < GetNodes().GetEndOfInserts().GetIndex() &&
     344           0 :             rPos.nNode >= GetNodes().GetEndOfInserts().StartOfSectionIndex() )
     345           0 :             return 0;
     346             : 
     347             :         // If the ColumnArray has a wrong count, ignore it!
     348         314 :         if( pColArr &&
     349           0 :             (size_t)(nCols + ( text::HoriOrientation::NONE == eAdjust ? 2 : 1 )) != pColArr->size() )
     350           0 :             pColArr = 0;
     351             :     }
     352             : 
     353         314 :     OUString aTblName = GetUniqueTblName();
     354             : 
     355         314 :     if( GetIDocumentUndoRedo().DoesUndo() )
     356             :     {
     357         102 :         GetIDocumentUndoRedo().AppendUndo(
     358             :             new SwUndoInsTbl( rPos, nCols, nRows, static_cast<sal_uInt16>(eAdjust),
     359             :                                       rInsTblOpts, pTAFmt, pColArr,
     360         102 :                                       aTblName));
     361             :     }
     362             : 
     363             :     // Start with inserting the Nodes and get the AutoFormat for the Table
     364         314 :     SwTxtFmtColl *pBodyColl = getIDocumentStylePoolAccess().GetTxtCollFromPool( RES_POOLCOLL_TABLE ),
     365         314 :                  *pHeadColl = pBodyColl;
     366             : 
     367         314 :     bool bDfltBorders = 0 != ( rInsTblOpts.mnInsMode & tabopts::DEFAULT_BORDER );
     368             : 
     369         314 :     if( (rInsTblOpts.mnInsMode & tabopts::HEADLINE) && (1 != nRows || !bDfltBorders) )
     370         212 :         pHeadColl = getIDocumentStylePoolAccess().GetTxtCollFromPool( RES_POOLCOLL_TABLE_HDLN );
     371             : 
     372             :     const sal_uInt16 nRowsToRepeat =
     373         314 :             tabopts::HEADLINE == (rInsTblOpts.mnInsMode & tabopts::HEADLINE) ?
     374             :             rInsTblOpts.mnRowsToRepeat :
     375         314 :             0;
     376             : 
     377             :     /* Save content node to extract FRAMEDIR from. */
     378         314 :     const SwCntntNode * pCntntNd = rPos.nNode.GetNode().GetCntntNode();
     379             : 
     380             :     /* If we are called from a shell pass the attrset from
     381             :         pCntntNd (aka the node the table is inserted at) thus causing
     382             :         SwNodes::InsertTable to propagate an adjust item if
     383             :         necessary. */
     384         314 :     SwTableNode *pTblNd = GetNodes().InsertTable(
     385             :         rPos.nNode,
     386             :         nCols,
     387             :         pBodyColl,
     388             :         nRows,
     389             :         nRowsToRepeat,
     390             :         pHeadColl,
     391         628 :         bCalledFromShell ? &pCntntNd->GetSwAttrSet() : 0 );
     392             : 
     393             :     // Create the Box/Line/Table construct
     394         314 :     SwTableLineFmt* pLineFmt = MakeTableLineFmt();
     395         314 :     SwTableFmt* pTableFmt = MakeTblFrmFmt( aTblName, GetDfltFrmFmt() );
     396             : 
     397             :     /* If the node to insert the table at is a context node and has a
     398             :        non-default FRAMEDIR propagate it to the table. */
     399         314 :     if (pCntntNd)
     400             :     {
     401         314 :         const SwAttrSet & aNdSet = pCntntNd->GetSwAttrSet();
     402         314 :         const SfxPoolItem *pItem = NULL;
     403             : 
     404         628 :         if (SfxItemState::SET == aNdSet.GetItemState( RES_FRAMEDIR, true, &pItem )
     405         314 :             && pItem != NULL)
     406             :         {
     407         152 :             pTableFmt->SetFmtAttr( *pItem );
     408             :         }
     409             :     }
     410             : 
     411             :     // Set Orientation at the Table's Fmt
     412         314 :     pTableFmt->SetFmtAttr( SwFmtHoriOrient( 0, eAdjust ) );
     413             :     // All lines use the left-to-right Fill-Order!
     414         314 :     pLineFmt->SetFmtAttr( SwFmtFillOrder( ATT_LEFT_TO_RIGHT ));
     415             : 
     416             :     // Set USHRT_MAX as the Table's default SSize
     417         314 :     SwTwips nWidth = USHRT_MAX;
     418         314 :     if( pColArr )
     419             :     {
     420           0 :         sal_uInt16 nSttPos = pColArr->front();
     421           0 :         sal_uInt16 nLastPos = pColArr->back();
     422           0 :         if( text::HoriOrientation::NONE == eAdjust )
     423             :         {
     424           0 :             sal_uInt16 nFrmWidth = nLastPos;
     425           0 :             nLastPos = (*pColArr)[ pColArr->size()-2 ];
     426           0 :             pTableFmt->SetFmtAttr( SvxLRSpaceItem( nSttPos, nFrmWidth - nLastPos, 0, 0, RES_LR_SPACE ) );
     427             :         }
     428           0 :         nWidth = nLastPos - nSttPos;
     429             :     }
     430         314 :     else if( nCols )
     431             :     {
     432         314 :         nWidth /= nCols;
     433         314 :         nWidth *= nCols; // to avoid rounding problems
     434             :     }
     435         314 :     pTableFmt->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE, nWidth ));
     436         314 :     if( !(rInsTblOpts.mnInsMode & tabopts::SPLIT_LAYOUT) )
     437           0 :         pTableFmt->SetFmtAttr( SwFmtLayoutSplit( false ));
     438             : 
     439             :     // Move the hard PageDesc/PageBreak Attributes if needed
     440         628 :     SwCntntNode* pNextNd = GetNodes()[ pTblNd->EndOfSectionIndex()+1 ]
     441         628 :                             ->GetCntntNode();
     442         314 :     if( pNextNd && pNextNd->HasSwAttrSet() )
     443             :     {
     444          34 :         const SfxItemSet* pNdSet = pNextNd->GetpSwAttrSet();
     445             :         const SfxPoolItem *pItem;
     446          34 :         if( SfxItemState::SET == pNdSet->GetItemState( RES_PAGEDESC, false,
     447          34 :             &pItem ) )
     448             :         {
     449           2 :             pTableFmt->SetFmtAttr( *pItem );
     450           2 :             pNextNd->ResetAttr( RES_PAGEDESC );
     451           2 :             pNdSet = pNextNd->GetpSwAttrSet();
     452             :         }
     453          68 :         if( pNdSet && SfxItemState::SET == pNdSet->GetItemState( RES_BREAK, false,
     454          34 :              &pItem ) )
     455             :         {
     456           0 :             pTableFmt->SetFmtAttr( *pItem );
     457           0 :             pNextNd->ResetAttr( RES_BREAK );
     458             :         }
     459             :     }
     460             : 
     461         314 :     SwTable * pNdTbl = &pTblNd->GetTable();
     462         314 :     pNdTbl->RegisterToFormat( *pTableFmt );
     463             : 
     464         314 :     pNdTbl->SetRowsToRepeat( nRowsToRepeat );
     465         314 :     pNdTbl->SetTableModel( bNewModel );
     466             : 
     467         628 :     std::vector<SwTableBoxFmt*> aBoxFmtArr;
     468         314 :     SwTableBoxFmt* pBoxFmt = 0;
     469         314 :     if( !bDfltBorders && !pTAFmt )
     470             :     {
     471         142 :         pBoxFmt = MakeTableBoxFmt();
     472         142 :         pBoxFmt->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE, USHRT_MAX / nCols, 0 ));
     473             :     }
     474             :     else
     475             :     {
     476         172 :         const sal_uInt16 nBoxArrLen = pTAFmt ? 16 : 4;
     477         172 :         aBoxFmtArr.resize( nBoxArrLen, NULL );
     478             :     }
     479         628 :     SfxItemSet aCharSet( GetAttrPool(), RES_CHRATR_BEGIN, RES_PARATR_LIST_END-1 );
     480             : 
     481         628 :     SwNodeIndex aNdIdx( *pTblNd, 1 ); // Set to StartNode of first Box
     482         314 :     SwTableLines& rLines = pNdTbl->GetTabLines();
     483        1284 :     for( sal_uInt16 n = 0; n < nRows; ++n )
     484             :     {
     485         970 :         SwTableLine* pLine = new SwTableLine( pLineFmt, nCols, 0 );
     486         970 :         rLines.insert( rLines.begin() + n, pLine );
     487         970 :         SwTableBoxes& rBoxes = pLine->GetTabBoxes();
     488        3392 :         for( sal_uInt16 i = 0; i < nCols; ++i )
     489             :         {
     490             :             SwTableBoxFmt *pBoxF;
     491        2422 :             if( pTAFmt )
     492             :             {
     493           0 :                 sal_uInt8 nId = static_cast<sal_uInt8>(!n ? 0 : (( n+1 == nRows )
     494           0 :                                         ? 12 : (4 * (1 + ((n-1) & 1 )))));
     495             :                 nId = nId + static_cast<sal_uInt8>( !i ? 0 :
     496           0 :                             ( i+1 == nCols ? 3 : (1 + ((i-1) & 1))));
     497             :                 pBoxF = ::lcl_CreateAFmtBoxFmt( *this, aBoxFmtArr, *pTAFmt,
     498           0 :                                                 nCols, nId );
     499             : 
     500             :                 // Set the Paragraph/Character Attributes if needed
     501           0 :                 if( pTAFmt->IsFont() || pTAFmt->IsJustify() )
     502             :                 {
     503           0 :                     aCharSet.ClearItem();
     504             :                     pTAFmt->UpdateToSet( nId, aCharSet,
     505           0 :                                         SwTableAutoFmt::UPDATE_CHAR, 0 );
     506           0 :                     if( aCharSet.Count() )
     507           0 :                         GetNodes()[ aNdIdx.GetIndex()+1 ]->GetCntntNode()->
     508           0 :                             SetAttr( aCharSet );
     509             :                 }
     510             :             }
     511        2422 :             else if( bDfltBorders )
     512             :             {
     513        1032 :                 sal_uInt8 nBoxId = (i < nCols - 1 ? 0 : 1) + (n ? 2 : 0 );
     514        1032 :                 pBoxF = ::lcl_CreateDfltBoxFmt( *this, aBoxFmtArr, nCols, nBoxId);
     515             :             }
     516             :             else
     517        1390 :                 pBoxF = pBoxFmt;
     518             : 
     519             :             // For AutoFormat on input: the columns are set when inserting the Table
     520             :             // The Array contains the columns positions and not their widths!
     521        2422 :             if( pColArr )
     522             :             {
     523           0 :                 nWidth = (*pColArr)[ i + 1 ] - (*pColArr)[ i ];
     524           0 :                 if( pBoxF->GetFrmSize().GetWidth() != nWidth )
     525             :                 {
     526           0 :                     if( pBoxF->GetDepends() ) // Create new Format
     527             :                     {
     528           0 :                         SwTableBoxFmt *pNewFmt = MakeTableBoxFmt();
     529           0 :                         *pNewFmt = *pBoxF;
     530           0 :                         pBoxF = pNewFmt;
     531             :                     }
     532           0 :                     pBoxF->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE, nWidth ));
     533             :                 }
     534             :             }
     535             : 
     536        2422 :             SwTableBox *pBox = new SwTableBox( pBoxF, aNdIdx, pLine);
     537        2422 :             rBoxes.insert( rBoxes.begin() + i, pBox );
     538        2422 :             aNdIdx += 3; // StartNode, TextNode, EndNode  == 3 Nodes
     539             :         }
     540             :     }
     541             :     // Insert Frms
     542         314 :     GetNodes().GoNext( &aNdIdx ); // Go to the next ContentNode
     543         314 :     pTblNd->MakeFrms( &aNdIdx );
     544             : 
     545             :     // To-Do - add 'SwExtraRedlineTbl' also ?
     546         314 :     if( getIDocumentRedlineAccess().IsRedlineOn() || (!getIDocumentRedlineAccess().IsIgnoreRedline() && !getIDocumentRedlineAccess().GetRedlineTbl().empty() ))
     547             :     {
     548           0 :         SwPaM aPam( *pTblNd->EndOfSectionNode(), *pTblNd, 1 );
     549           0 :         if( getIDocumentRedlineAccess().IsRedlineOn() )
     550           0 :             getIDocumentRedlineAccess().AppendRedline( new SwRangeRedline( nsRedlineType_t::REDLINE_INSERT, aPam ), true);
     551             :         else
     552           0 :             getIDocumentRedlineAccess().SplitRedline( aPam );
     553             :     }
     554             : 
     555         314 :     getIDocumentState().SetModified();
     556             :     CHECK_TABLE( *pNdTbl );
     557         628 :     return pNdTbl;
     558             : }
     559             : 
     560         314 : SwTableNode* SwNodes::InsertTable( const SwNodeIndex& rNdIdx,
     561             :                                    sal_uInt16 nBoxes,
     562             :                                    SwTxtFmtColl* pCntntTxtColl,
     563             :                                    sal_uInt16 nLines,
     564             :                                    sal_uInt16 nRepeat,
     565             :                                    SwTxtFmtColl* pHeadlineTxtColl,
     566             :                                    const SwAttrSet * pAttrSet)
     567             : {
     568         314 :     if( !nBoxes )
     569           0 :         return 0;
     570             : 
     571             :     // If Lines is given, create the Matrix from Lines and Boxes
     572         314 :     if( !pHeadlineTxtColl || !nLines )
     573           0 :         pHeadlineTxtColl = pCntntTxtColl;
     574             : 
     575         314 :     SwTableNode * pTblNd = new SwTableNode( rNdIdx );
     576         314 :     SwEndNode* pEndNd = new SwEndNode( rNdIdx, *pTblNd );
     577             : 
     578         314 :     if( !nLines ) // For the for loop
     579           0 :         ++nLines;
     580             : 
     581         314 :     SwNodeIndex aIdx( *pEndNd );
     582         314 :     SwTxtFmtColl* pTxtColl = pHeadlineTxtColl;
     583        1284 :     for( sal_uInt16 nL = 0; nL < nLines; ++nL )
     584             :     {
     585        3392 :         for( sal_uInt16 nB = 0; nB < nBoxes; ++nB )
     586             :         {
     587             :             SwStartNode* pSttNd = new SwStartNode( aIdx, ND_STARTNODE,
     588        2422 :                                                     SwTableBoxStartNode );
     589        2422 :             pSttNd->pStartOfSection = pTblNd;
     590             : 
     591        2422 :             SwTxtNode * pTmpNd = new SwTxtNode( aIdx, pTxtColl );
     592             : 
     593             :             // #i60422# Propagate some more attributes.
     594        2422 :             const SfxPoolItem* pItem = NULL;
     595        2422 :             if ( NULL != pAttrSet )
     596             :             {
     597             :                 static const sal_uInt16 aPropagateItems[] = {
     598             :                     RES_PARATR_ADJUST,
     599             :                     RES_CHRATR_FONT, RES_CHRATR_FONTSIZE,
     600             :                     RES_CHRATR_CJK_FONT, RES_CHRATR_CJK_FONTSIZE,
     601             :                     RES_CHRATR_CTL_FONT, RES_CHRATR_CTL_FONTSIZE, 0 };
     602             : 
     603           0 :                 const sal_uInt16* pIdx = aPropagateItems;
     604           0 :                 while ( *pIdx != 0 )
     605             :                 {
     606           0 :                     if ( SfxItemState::SET != pTmpNd->GetSwAttrSet().GetItemState( *pIdx ) &&
     607           0 :                          SfxItemState::SET == pAttrSet->GetItemState( *pIdx, true, &pItem ) )
     608           0 :                         static_cast<SwCntntNode *>(pTmpNd)->SetAttr(*pItem);
     609           0 :                     ++pIdx;
     610             :                 }
     611             :             }
     612             : 
     613        2422 :             new SwEndNode( aIdx, *pSttNd );
     614             :         }
     615         970 :         if ( nL + 1 >= nRepeat )
     616         970 :             pTxtColl = pCntntTxtColl;
     617             :     }
     618         314 :     return pTblNd;
     619             : }
     620             : 
     621             : /**
     622             :  * Text to Table
     623             :  */
     624           0 : const SwTable* SwDoc::TextToTable( const SwInsertTableOptions& rInsTblOpts,
     625             :                                    const SwPaM& rRange, sal_Unicode cCh,
     626             :                                    sal_Int16 eAdjust,
     627             :                                    const SwTableAutoFmt* pTAFmt )
     628             : {
     629             :     // See if the selection contains a Table
     630           0 :     const SwPosition *pStt = rRange.Start(), *pEnd = rRange.End();
     631             :     {
     632           0 :         sal_uLong nCnt = pStt->nNode.GetIndex();
     633           0 :         for( ; nCnt <= pEnd->nNode.GetIndex(); ++nCnt )
     634           0 :             if( !GetNodes()[ nCnt ]->IsTxtNode() )
     635           0 :                 return 0;
     636             :     }
     637             : 
     638             :     // Save first node in the selection if it is a context node
     639           0 :     SwCntntNode * pSttCntntNd = pStt->nNode.GetNode().GetCntntNode();
     640             : 
     641           0 :     SwPaM aOriginal( *pStt, *pEnd );
     642           0 :     pStt = aOriginal.GetMark();
     643           0 :     pEnd = aOriginal.GetPoint();
     644             : 
     645           0 :     SwUndoTxtToTbl* pUndo = 0;
     646           0 :     if( GetIDocumentUndoRedo().DoesUndo() )
     647             :     {
     648           0 :         GetIDocumentUndoRedo().StartUndo( UNDO_TEXTTOTABLE, NULL );
     649             :         pUndo = new SwUndoTxtToTbl( aOriginal, rInsTblOpts, cCh,
     650           0 :                     static_cast<sal_uInt16>(eAdjust), pTAFmt );
     651           0 :         GetIDocumentUndoRedo().AppendUndo( pUndo );
     652             : 
     653             :         // Do not add splitting the TextNode to the Undo history
     654           0 :         GetIDocumentUndoRedo().DoUndo( false );
     655             :     }
     656             : 
     657           0 :     ::PaMCorrAbs( aOriginal, *pEnd );
     658             : 
     659             :     // Make sure that the range is on Node Edges
     660           0 :     SwNodeRange aRg( pStt->nNode, pEnd->nNode );
     661           0 :     if( pStt->nContent.GetIndex() )
     662           0 :         getIDocumentContentOperations().SplitNode( *pStt, false );
     663             : 
     664           0 :     bool bEndCntnt = 0 != pEnd->nContent.GetIndex();
     665             : 
     666             :     // Do not split at the End of a Line (except at the End of the Doc)
     667           0 :     if( bEndCntnt )
     668             :     {
     669           0 :         if( pEnd->nNode.GetNode().GetCntntNode()->Len() != pEnd->nContent.GetIndex()
     670           0 :             || pEnd->nNode.GetIndex() >= GetNodes().GetEndOfContent().GetIndex()-1 )
     671             :         {
     672           0 :             getIDocumentContentOperations().SplitNode( *pEnd, false );
     673           0 :             ((SwNodeIndex&)pEnd->nNode)--;
     674             :             ((SwIndex&)pEnd->nContent).Assign(
     675           0 :                                 pEnd->nNode.GetNode().GetCntntNode(), 0 );
     676             :             // A Node and at the End?
     677           0 :             if( pStt->nNode.GetIndex() >= pEnd->nNode.GetIndex() )
     678           0 :                 aRg.aStart--;
     679             :         }
     680             :         else
     681           0 :             aRg.aEnd++;
     682             :     }
     683             : 
     684           0 :     if( aRg.aEnd.GetIndex() == aRg.aStart.GetIndex() )
     685             :     {
     686             :         OSL_FAIL( "empty range" );
     687           0 :         aRg.aEnd++;
     688             :     }
     689             : 
     690             :     // We always use Upper to insert the Table
     691           0 :     SwNode2Layout aNode2Layout( aRg.aStart.GetNode() );
     692             : 
     693           0 :     GetIDocumentUndoRedo().DoUndo( 0 != pUndo );
     694             : 
     695             :     // Create the Box/Line/Table construct
     696           0 :     SwTableBoxFmt* pBoxFmt = MakeTableBoxFmt();
     697           0 :     SwTableLineFmt* pLineFmt = MakeTableLineFmt();
     698           0 :     SwTableFmt* pTableFmt = MakeTblFrmFmt( GetUniqueTblName(), GetDfltFrmFmt() );
     699             : 
     700             :     // All Lines have a left-to-right Fill Order
     701           0 :     pLineFmt->SetFmtAttr( SwFmtFillOrder( ATT_LEFT_TO_RIGHT ));
     702             :     // The Table's SSize is USHRT_MAX
     703           0 :     pTableFmt->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE, USHRT_MAX ));
     704           0 :     if( !(rInsTblOpts.mnInsMode & tabopts::SPLIT_LAYOUT) )
     705           0 :         pTableFmt->SetFmtAttr( SwFmtLayoutSplit( false ));
     706             : 
     707             :     /* If the first node in the selection is a context node and if it
     708             :        has an item FRAMEDIR set (no default) propagate the item to the
     709             :        replacing table. */
     710           0 :     if (pSttCntntNd)
     711             :     {
     712           0 :         const SwAttrSet & aNdSet = pSttCntntNd->GetSwAttrSet();
     713           0 :         const SfxPoolItem *pItem = NULL;
     714             : 
     715           0 :         if (SfxItemState::SET == aNdSet.GetItemState( RES_FRAMEDIR, true, &pItem )
     716           0 :             && pItem != NULL)
     717             :         {
     718           0 :             pTableFmt->SetFmtAttr( *pItem );
     719             :         }
     720             :     }
     721             : 
     722           0 :     SwTableNode* pTblNd = GetNodes().TextToTable(
     723             :             aRg, cCh, pTableFmt, pLineFmt, pBoxFmt,
     724           0 :             getIDocumentStylePoolAccess().GetTxtCollFromPool( RES_POOLCOLL_STANDARD ), pUndo );
     725             : 
     726           0 :     SwTable * pNdTbl = &pTblNd->GetTable();
     727             :     OSL_ENSURE( pNdTbl, "No Table Node created" );
     728             : 
     729             :     const sal_uInt16 nRowsToRepeat =
     730           0 :             tabopts::HEADLINE == (rInsTblOpts.mnInsMode & tabopts::HEADLINE) ?
     731             :             rInsTblOpts.mnRowsToRepeat :
     732           0 :             0;
     733           0 :     pNdTbl->SetRowsToRepeat( nRowsToRepeat );
     734             : 
     735           0 :     bool bUseBoxFmt = false;
     736           0 :     if( !pBoxFmt->GetDepends() )
     737             :     {
     738             :         // The Box's Formats already have the right size, we must only set
     739             :         // the right Border/AutoFmt.
     740           0 :         bUseBoxFmt = true;
     741           0 :         pTableFmt->SetFmtAttr( pBoxFmt->GetFrmSize() );
     742           0 :         delete pBoxFmt;
     743           0 :         eAdjust = text::HoriOrientation::NONE;
     744             :     }
     745             : 
     746             :     // Set Orientation in the Table's Fmt
     747           0 :     pTableFmt->SetFmtAttr( SwFmtHoriOrient( 0, eAdjust ) );
     748           0 :     pNdTbl->RegisterToFormat( *pTableFmt );
     749             : 
     750           0 :     if( pTAFmt || ( rInsTblOpts.mnInsMode & tabopts::DEFAULT_BORDER) )
     751             :     {
     752           0 :         sal_uInt8 nBoxArrLen = pTAFmt ? 16 : 4;
     753           0 :         boost::scoped_ptr< DfltBoxAttrList_t > aBoxFmtArr1;
     754           0 :         boost::scoped_ptr< std::vector<SwTableBoxFmt*> > aBoxFmtArr2;
     755           0 :         if( bUseBoxFmt )
     756             :         {
     757           0 :             aBoxFmtArr1.reset(new DfltBoxAttrList_t( nBoxArrLen, NULL ));
     758             :         }
     759             :         else
     760             :         {
     761           0 :             aBoxFmtArr2.reset(new std::vector<SwTableBoxFmt*>( nBoxArrLen, NULL ));
     762             :         }
     763             : 
     764           0 :         SfxItemSet aCharSet( GetAttrPool(), RES_CHRATR_BEGIN, RES_PARATR_LIST_END-1 );
     765             : 
     766           0 :         SwHistory* pHistory = pUndo ? &pUndo->GetHistory() : 0;
     767             : 
     768           0 :         SwTableBoxFmt *pBoxF = 0;
     769           0 :         SwTableLines& rLines = pNdTbl->GetTabLines();
     770           0 :         sal_uInt16 nRows = rLines.size();
     771           0 :         for( sal_uInt16 n = 0; n < nRows; ++n )
     772             :         {
     773           0 :             SwTableBoxes& rBoxes = rLines[ n ]->GetTabBoxes();
     774           0 :             sal_uInt16 nCols = rBoxes.size();
     775           0 :             for( sal_uInt16 i = 0; i < nCols; ++i )
     776             :             {
     777           0 :                 SwTableBox* pBox = rBoxes[ i ];
     778           0 :                 bool bChgSz = false;
     779             : 
     780           0 :                 if( pTAFmt )
     781             :                 {
     782           0 :                     sal_uInt8 nId = static_cast<sal_uInt8>(!n ? 0 : (( n+1 == nRows )
     783           0 :                                             ? 12 : (4 * (1 + ((n-1) & 1 )))));
     784             :                     nId = nId + static_cast<sal_uInt8>(!i ? 0 :
     785           0 :                                 ( i+1 == nCols ? 3 : (1 + ((i-1) & 1))));
     786           0 :                     if( bUseBoxFmt )
     787           0 :                         ::lcl_SetDfltBoxAttr( *pBox, *aBoxFmtArr1, nId, pTAFmt );
     788             :                     else
     789             :                     {
     790           0 :                         bChgSz = 0 == (*aBoxFmtArr2)[ nId ];
     791           0 :                         pBoxF = ::lcl_CreateAFmtBoxFmt( *this, *aBoxFmtArr2,
     792           0 :                                                 *pTAFmt, USHRT_MAX, nId );
     793             :                     }
     794             : 
     795             :                     // Set Paragraph/Character Attributes if needed
     796           0 :                     if( pTAFmt->IsFont() || pTAFmt->IsJustify() )
     797             :                     {
     798           0 :                         aCharSet.ClearItem();
     799             :                         pTAFmt->UpdateToSet( nId, aCharSet,
     800           0 :                                             SwTableAutoFmt::UPDATE_CHAR, 0 );
     801           0 :                         if( aCharSet.Count() )
     802             :                         {
     803           0 :                             sal_uLong nSttNd = pBox->GetSttIdx()+1;
     804           0 :                             sal_uLong nEndNd = pBox->GetSttNd()->EndOfSectionIndex();
     805           0 :                             for( ; nSttNd < nEndNd; ++nSttNd )
     806             :                             {
     807           0 :                                 SwCntntNode* pNd = GetNodes()[ nSttNd ]->GetCntntNode();
     808           0 :                                 if( pNd )
     809             :                                 {
     810           0 :                                     if( pHistory )
     811             :                                     {
     812           0 :                                         SwRegHistory aReg( pNd, *pNd, pHistory );
     813           0 :                                         pNd->SetAttr( aCharSet );
     814             :                                     }
     815             :                                     else
     816           0 :                                         pNd->SetAttr( aCharSet );
     817             :                                 }
     818             :                             }
     819             :                         }
     820             :                     }
     821             :                 }
     822             :                 else
     823             :                 {
     824           0 :                     sal_uInt8 nId = (i < nCols - 1 ? 0 : 1) + (n ? 2 : 0 );
     825           0 :                     if( bUseBoxFmt )
     826           0 :                         ::lcl_SetDfltBoxAttr( *pBox, *aBoxFmtArr1, nId );
     827             :                     else
     828             :                     {
     829           0 :                         bChgSz = 0 == (*aBoxFmtArr2)[ nId ];
     830           0 :                         pBoxF = ::lcl_CreateDfltBoxFmt( *this, *aBoxFmtArr2,
     831           0 :                                                         USHRT_MAX, nId );
     832             :                     }
     833             :                 }
     834             : 
     835           0 :                 if( !bUseBoxFmt )
     836             :                 {
     837           0 :                     if( bChgSz )
     838           0 :                         pBoxF->SetFmtAttr( pBox->GetFrmFmt()->GetFrmSize() );
     839           0 :                     pBox->ChgFrmFmt( pBoxF );
     840             :                 }
     841             :             }
     842             :         }
     843             : 
     844           0 :         if( bUseBoxFmt )
     845             :         {
     846           0 :             for( sal_uInt8 i = 0; i < nBoxArrLen; ++i )
     847             :             {
     848           0 :                 delete (*aBoxFmtArr1)[ i ];
     849             :             }
     850           0 :         }
     851             :     }
     852             : 
     853             :     // Check the boxes for numbers
     854           0 :     if( IsInsTblFormatNum() )
     855             :     {
     856           0 :         for (size_t nBoxes = pNdTbl->GetTabSortBoxes().size(); nBoxes; )
     857             :         {
     858           0 :             ChkBoxNumFmt( *pNdTbl->GetTabSortBoxes()[ --nBoxes ], false );
     859             :         }
     860             :     }
     861             : 
     862           0 :     sal_uLong nIdx = pTblNd->GetIndex();
     863           0 :     aNode2Layout.RestoreUpperFrms( GetNodes(), nIdx, nIdx + 1 );
     864             : 
     865             :     {
     866           0 :         SwPaM& rTmp = (SwPaM&)rRange; // Point always at the Start
     867           0 :         rTmp.DeleteMark();
     868           0 :         rTmp.GetPoint()->nNode = *pTblNd;
     869           0 :         SwCntntNode* pCNd = GetNodes().GoNext( &rTmp.GetPoint()->nNode );
     870           0 :         rTmp.GetPoint()->nContent.Assign( pCNd, 0 );
     871             :     }
     872             : 
     873           0 :     if( pUndo )
     874             :     {
     875           0 :         GetIDocumentUndoRedo().EndUndo( UNDO_TEXTTOTABLE, NULL );
     876             :     }
     877             : 
     878           0 :     getIDocumentState().SetModified();
     879           0 :     getIDocumentFieldsAccess().SetFieldsDirty(true, NULL, 0);
     880           0 :     return pNdTbl;
     881             : }
     882             : 
     883       18778 : static void lcl_RemoveBreaks(SwCntntNode & rNode, SwTableFmt *const pTableFmt)
     884             : {
     885             :     // delete old layout frames, new ones need to be created...
     886       18778 :     rNode.DelFrms();
     887             : 
     888       18778 :     if (!rNode.IsTxtNode())
     889             :     {
     890       18778 :         return;
     891             :     }
     892             : 
     893       18778 :     SwTxtNode & rTxtNode = static_cast<SwTxtNode&>(rNode);
     894             :     // remove PageBreaks/PageDesc/ColBreak
     895       18778 :     SfxItemSet const* pSet = rTxtNode.GetpSwAttrSet();
     896       18778 :     if (pSet)
     897             :     {
     898             :         const SfxPoolItem* pItem;
     899       13450 :         if (SfxItemState::SET == pSet->GetItemState(RES_BREAK, false, &pItem))
     900             :         {
     901           0 :             if (pTableFmt)
     902             :             {
     903           0 :                 pTableFmt->SetFmtAttr(*pItem);
     904             :             }
     905           0 :             rTxtNode.ResetAttr(RES_BREAK);
     906           0 :             pSet = rTxtNode.GetpSwAttrSet();
     907             :         }
     908             : 
     909       13450 :         if (pSet
     910       13450 :             && (SfxItemState::SET == pSet->GetItemState(RES_PAGEDESC, false, &pItem))
     911       13450 :             && static_cast<SwFmtPageDesc const*>(pItem)->GetPageDesc())
     912             :         {
     913           0 :             if (pTableFmt)
     914             :             {
     915           0 :                 pTableFmt->SetFmtAttr(*pItem);
     916             :             }
     917           0 :             rTxtNode.ResetAttr(RES_PAGEDESC);
     918             :         }
     919             :     }
     920             : }
     921             : 
     922             : /**
     923             :  * balance lines in table, insert empty boxes so all lines have the size
     924             :  */
     925             : static void
     926           0 : lcl_BalanceTable(SwTable & rTable, size_t const nMaxBoxes,
     927             :     SwTableNode & rTblNd, SwTableBoxFmt & rBoxFmt, SwTxtFmtColl & rTxtColl,
     928             :     SwUndoTxtToTbl *const pUndo, std::vector<sal_uInt16> *const pPositions)
     929             : {
     930           0 :     for (size_t n = 0; n < rTable.GetTabLines().size(); ++n)
     931             :     {
     932           0 :         SwTableLine *const pCurrLine = rTable.GetTabLines()[ n ];
     933           0 :         size_t const nBoxes = pCurrLine->GetTabBoxes().size();
     934           0 :         if (nMaxBoxes != nBoxes)
     935             :         {
     936           0 :             rTblNd.GetNodes().InsBoxen(&rTblNd, pCurrLine, &rBoxFmt, &rTxtColl,
     937           0 :                     0, nBoxes, nMaxBoxes - nBoxes);
     938             : 
     939           0 :             if (pUndo)
     940             :             {
     941           0 :                 for (size_t i = nBoxes; i < nMaxBoxes; ++i)
     942             :                 {
     943           0 :                     pUndo->AddFillBox( *pCurrLine->GetTabBoxes()[i] );
     944             :                 }
     945             :             }
     946             : 
     947             :             // if the first line is missing boxes, the width array is useless!
     948           0 :             if (!n && pPositions)
     949             :             {
     950           0 :                 pPositions->clear();
     951             :             }
     952             :         }
     953             :     }
     954           0 : }
     955             : 
     956             : static void
     957           0 : lcl_SetTableBoxWidths(SwTable & rTable, size_t const nMaxBoxes,
     958             :         SwTableBoxFmt & rBoxFmt, SwDoc & rDoc,
     959             :         std::vector<sal_uInt16> *const pPositions)
     960             : {
     961           0 :     if (pPositions && !pPositions->empty())
     962             :     {
     963           0 :         SwTableLines& rLns = rTable.GetTabLines();
     964           0 :         sal_uInt16 nLastPos = 0;
     965           0 :         for (size_t n = 0; n < pPositions->size(); ++n)
     966             :         {
     967           0 :             SwTableBoxFmt *pNewFmt = rDoc.MakeTableBoxFmt();
     968             :             pNewFmt->SetFmtAttr(
     969           0 :                     SwFmtFrmSize(ATT_VAR_SIZE, (*pPositions)[n] - nLastPos));
     970           0 :             for (size_t nTmpLine = 0; nTmpLine < rLns.size(); ++nTmpLine)
     971             :             {
     972             :                 // Have to do an Add here, because the BoxFormat
     973             :                 // is still needed by the caller
     974           0 :                 pNewFmt->Add( rLns[ nTmpLine ]->GetTabBoxes()[ n ] );
     975             :             }
     976             : 
     977           0 :             nLastPos = (*pPositions)[ n ];
     978             :         }
     979             : 
     980             :         // propagate size upwards from format, so the table gets the right size
     981             :         SAL_WARN_IF(rBoxFmt.GetDepends(), "sw.core",
     982             :                 "who is still registered in the format?");
     983           0 :         rBoxFmt.SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE, nLastPos ));
     984             :     }
     985             :     else
     986             :     {
     987           0 :         size_t nWidth = nMaxBoxes ? USHRT_MAX / nMaxBoxes : USHRT_MAX;
     988           0 :         rBoxFmt.SetFmtAttr(SwFmtFrmSize(ATT_VAR_SIZE, nWidth));
     989             :     }
     990           0 : }
     991             : 
     992           0 : SwTableNode* SwNodes::TextToTable( const SwNodeRange& rRange, sal_Unicode cCh,
     993             :                                     SwTableFmt* pTblFmt,
     994             :                                     SwTableLineFmt* pLineFmt,
     995             :                                     SwTableBoxFmt* pBoxFmt,
     996             :                                     SwTxtFmtColl* pTxtColl,
     997             :                                     SwUndoTxtToTbl* pUndo )
     998             : {
     999           0 :     if( rRange.aStart >= rRange.aEnd )
    1000           0 :         return 0;
    1001             : 
    1002           0 :     SwTableNode * pTblNd = new SwTableNode( rRange.aStart );
    1003           0 :     new SwEndNode( rRange.aEnd, *pTblNd );
    1004             : 
    1005           0 :     SwDoc* pDoc = GetDoc();
    1006           0 :     std::vector<sal_uInt16> aPosArr;
    1007           0 :     SwTable * pTable = &pTblNd->GetTable();
    1008             :     SwTableLine* pLine;
    1009             :     SwTableBox* pBox;
    1010           0 :     sal_uInt16 nBoxes, nLines, nMaxBoxes = 0;
    1011             : 
    1012           0 :     SwNodeIndex aSttIdx( *pTblNd, 1 );
    1013           0 :     SwNodeIndex aEndIdx( rRange.aEnd, -1 );
    1014           0 :     for( nLines = 0, nBoxes = 0;
    1015           0 :         aSttIdx.GetIndex() < aEndIdx.GetIndex();
    1016             :         aSttIdx += 2, nLines++, nBoxes = 0 )
    1017             :     {
    1018           0 :         SwTxtNode* pTxtNd = aSttIdx.GetNode().GetTxtNode();
    1019             :         OSL_ENSURE( pTxtNd, "Only add TextNodes to the Table" );
    1020             : 
    1021           0 :         if( !nLines && 0x0b == cCh )
    1022             :         {
    1023           0 :             cCh = 0x09;
    1024             : 
    1025             :             // Get the separator's position from the first Node, in order for the Boxes to be set accordingly
    1026           0 :             SwTxtFrmInfo aFInfo( (SwTxtFrm*)pTxtNd->getLayoutFrm( pTxtNd->GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout() ) );
    1027           0 :             if( aFInfo.IsOneLine() ) // only makes sense in this case
    1028             :             {
    1029           0 :                 OUString const& rTxt(pTxtNd->GetTxt());
    1030           0 :                 for (sal_Int32 nChPos = 0; nChPos < rTxt.getLength(); ++nChPos)
    1031             :                 {
    1032           0 :                     if (rTxt[nChPos] == cCh)
    1033             :                     {
    1034             :                         aPosArr.push_back( static_cast<sal_uInt16>(
    1035           0 :                                         aFInfo.GetCharPos( nChPos+1, false )) );
    1036             :                     }
    1037             :                 }
    1038             : 
    1039             :                 aPosArr.push_back(
    1040           0 :                                 static_cast<sal_uInt16>(aFInfo.GetFrm()->IsVertical() ?
    1041           0 :                                 aFInfo.GetFrm()->Prt().Bottom() :
    1042           0 :                                 aFInfo.GetFrm()->Prt().Right()) );
    1043             : 
    1044             :             }
    1045             :         }
    1046             : 
    1047           0 :         lcl_RemoveBreaks(*pTxtNd, (0 == nLines) ? pTblFmt : 0);
    1048             : 
    1049             :         // Set the TableNode as StartNode for all TextNodes in the Table
    1050           0 :         pTxtNd->pStartOfSection = pTblNd;
    1051             : 
    1052           0 :         pLine = new SwTableLine( pLineFmt, 1, 0 );
    1053           0 :         pTable->GetTabLines().insert( pTable->GetTabLines().begin() + nLines, pLine );
    1054             : 
    1055             :         SwStartNode* pSttNd;
    1056           0 :         SwPosition aCntPos( aSttIdx, SwIndex( pTxtNd ));
    1057             : 
    1058           0 :         const boost::shared_ptr< sw::mark::CntntIdxStore> pCntntStore(sw::mark::CntntIdxStore::Create());
    1059           0 :         pCntntStore->Save( pDoc, aSttIdx.GetIndex(), pTxtNd->GetTxt().getLength() );
    1060             : 
    1061           0 :         if( T2T_PARA != cCh )
    1062             :         {
    1063           0 :             for (sal_Int32 nChPos = 0; nChPos < pTxtNd->GetTxt().getLength();)
    1064             :             {
    1065           0 :                 if (pTxtNd->GetTxt()[nChPos] == cCh)
    1066             :                 {
    1067           0 :                     aCntPos.nContent = nChPos;
    1068           0 :                     SwCntntNode* pNewNd = pTxtNd->SplitCntntNode( aCntPos );
    1069             : 
    1070           0 :                     if( !pCntntStore->Empty() )
    1071           0 :                         pCntntStore->Restore( *pNewNd, nChPos, nChPos + 1 );
    1072             : 
    1073             :                     // Delete separator and correct search string
    1074           0 :                     pTxtNd->EraseText( aCntPos.nContent, 1 );
    1075           0 :                     nChPos = 0;
    1076             : 
    1077             :                     // Set the TableNode as StartNode for all TextNodes in the Table
    1078           0 :                     const SwNodeIndex aTmpIdx( aCntPos.nNode, -1 );
    1079             :                     pSttNd = new SwStartNode( aTmpIdx, ND_STARTNODE,
    1080           0 :                                                 SwTableBoxStartNode );
    1081           0 :                     new SwEndNode( aCntPos.nNode, *pSttNd );
    1082           0 :                     pNewNd->pStartOfSection = pSttNd;
    1083             : 
    1084             :                     // Assign Section to the Box
    1085           0 :                     pBox = new SwTableBox( pBoxFmt, *pSttNd, pLine );
    1086           0 :                     pLine->GetTabBoxes().insert( pLine->GetTabBoxes().begin() + nBoxes++, pBox );
    1087             :                 }
    1088             :                 else
    1089             :                 {
    1090           0 :                     ++nChPos;
    1091             :                 }
    1092             :             }
    1093             :         }
    1094             : 
    1095             :         // Now for the last substring
    1096           0 :         if( !pCntntStore->Empty())
    1097           0 :             pCntntStore->Restore( *pTxtNd, pTxtNd->GetTxt().getLength(), pTxtNd->GetTxt().getLength()+1 );
    1098             : 
    1099           0 :         pSttNd = new SwStartNode( aCntPos.nNode, ND_STARTNODE, SwTableBoxStartNode );
    1100           0 :         const SwNodeIndex aTmpIdx( aCntPos.nNode, 1 );
    1101           0 :         new SwEndNode( aTmpIdx, *pSttNd  );
    1102           0 :         pTxtNd->pStartOfSection = pSttNd;
    1103             : 
    1104           0 :         pBox = new SwTableBox( pBoxFmt, *pSttNd, pLine );
    1105           0 :         pLine->GetTabBoxes().insert( pLine->GetTabBoxes().begin() + nBoxes++, pBox );
    1106           0 :         if( nMaxBoxes < nBoxes )
    1107           0 :             nMaxBoxes = nBoxes;
    1108           0 :     }
    1109             : 
    1110             :     lcl_BalanceTable(*pTable, nMaxBoxes, *pTblNd, *pBoxFmt, *pTxtColl,
    1111           0 :             pUndo, &aPosArr);
    1112           0 :     lcl_SetTableBoxWidths(*pTable, nMaxBoxes, *pBoxFmt, *pDoc, &aPosArr);
    1113             : 
    1114           0 :     return pTblNd;
    1115             : }
    1116             : 
    1117        1062 : const SwTable* SwDoc::TextToTable( const std::vector< std::vector<SwNodeRange> >& rTableNodes )
    1118             : {
    1119        1062 :     if (rTableNodes.empty())
    1120           0 :         return NULL;
    1121             : 
    1122        1062 :     const std::vector<SwNodeRange>& rFirstRange = *rTableNodes.begin();
    1123             : 
    1124        1062 :     if (rFirstRange.empty())
    1125           0 :         return NULL;
    1126             : 
    1127        1062 :     const std::vector<SwNodeRange>& rLastRange = *rTableNodes.rbegin();
    1128             : 
    1129        1062 :     if (rLastRange.empty())
    1130           0 :         return NULL;
    1131             : 
    1132             :     /* Save first node in the selection if it is a content node. */
    1133        1062 :     SwCntntNode * pSttCntntNd = rFirstRange.begin()->aStart.GetNode().GetCntntNode();
    1134             : 
    1135        1062 :     const SwNodeRange& rStartRange = *rFirstRange.begin();
    1136        1062 :     const SwNodeRange& rEndRange = *rLastRange.rbegin();
    1137             : 
    1138             :     //!!! not necessarily TextNodes !!!
    1139        1062 :     SwPaM aOriginal( rStartRange.aStart, rEndRange.aEnd );
    1140        1062 :     const SwPosition *pStt = aOriginal.GetMark();
    1141        1062 :     const SwPosition *pEnd = aOriginal.GetPoint();
    1142             : 
    1143        1062 :     bool const bUndo(GetIDocumentUndoRedo().DoesUndo());
    1144        1062 :     if (bUndo)
    1145             :     {
    1146             :         // Do not add splitting the TextNode to the Undo history
    1147           0 :         GetIDocumentUndoRedo().DoUndo(false);
    1148             :     }
    1149             : 
    1150        1062 :     ::PaMCorrAbs( aOriginal, *pEnd );
    1151             : 
    1152             :     // make sure that the range is on Node Edges
    1153        2124 :     SwNodeRange aRg( pStt->nNode, pEnd->nNode );
    1154        1062 :     if( pStt->nContent.GetIndex() )
    1155           0 :         getIDocumentContentOperations().SplitNode( *pStt, false );
    1156             : 
    1157        1062 :     bool bEndCntnt = 0 != pEnd->nContent.GetIndex();
    1158             : 
    1159             :     // Do not split at the End of a Line (except at the End of the Doc)
    1160        1062 :     if( bEndCntnt )
    1161             :     {
    1162           0 :         if( pEnd->nNode.GetNode().GetCntntNode()->Len() != pEnd->nContent.GetIndex()
    1163           0 :             || pEnd->nNode.GetIndex() >= GetNodes().GetEndOfContent().GetIndex()-1 )
    1164             :         {
    1165           0 :             getIDocumentContentOperations().SplitNode( *pEnd, false );
    1166           0 :             ((SwNodeIndex&)pEnd->nNode)--;
    1167             :             ((SwIndex&)pEnd->nContent).Assign(
    1168           0 :                                 pEnd->nNode.GetNode().GetCntntNode(), 0 );
    1169             :             // A Node and at the End?
    1170           0 :             if( pStt->nNode.GetIndex() >= pEnd->nNode.GetIndex() )
    1171           0 :                 aRg.aStart--;
    1172             :         }
    1173             :         else
    1174           0 :             aRg.aEnd++;
    1175             :     }
    1176             : 
    1177        1062 :     if( aRg.aEnd.GetIndex() == aRg.aStart.GetIndex() )
    1178             :     {
    1179             :         OSL_FAIL( "empty range" );
    1180         140 :         aRg.aEnd++;
    1181             :     }
    1182             : 
    1183             :     // We always use Upper to insert the Table
    1184        2124 :     SwNode2Layout aNode2Layout( aRg.aStart.GetNode() );
    1185             : 
    1186        1062 :     GetIDocumentUndoRedo().DoUndo(bUndo);
    1187             : 
    1188             :     // Create the Box/Line/Table construct
    1189        1062 :     SwTableBoxFmt* pBoxFmt = MakeTableBoxFmt();
    1190        1062 :     SwTableLineFmt* pLineFmt = MakeTableLineFmt();
    1191        1062 :     SwTableFmt* pTableFmt = MakeTblFrmFmt( GetUniqueTblName(), GetDfltFrmFmt() );
    1192             : 
    1193             :     // All Lines have a left-to-right Fill Order
    1194        1062 :     pLineFmt->SetFmtAttr( SwFmtFillOrder( ATT_LEFT_TO_RIGHT ));
    1195             :     // The Table's SSize is USHRT_MAX
    1196        1062 :     pTableFmt->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE, USHRT_MAX ));
    1197             : 
    1198             :     /* If the first node in the selection is a context node and if it
    1199             :        has an item FRAMEDIR set (no default) propagate the item to the
    1200             :        replacing table. */
    1201        1062 :     if (pSttCntntNd)
    1202             :     {
    1203        1038 :         const SwAttrSet & aNdSet = pSttCntntNd->GetSwAttrSet();
    1204        1038 :         const SfxPoolItem *pItem = NULL;
    1205             : 
    1206        2076 :         if (SfxItemState::SET == aNdSet.GetItemState( RES_FRAMEDIR, true, &pItem )
    1207        1038 :             && pItem != NULL)
    1208             :         {
    1209         938 :             pTableFmt->SetFmtAttr( *pItem );
    1210             :         }
    1211             :     }
    1212             : 
    1213        1062 :     SwTableNode* pTblNd = GetNodes().TextToTable(
    1214             :             rTableNodes, pTableFmt, pLineFmt, pBoxFmt,
    1215        2124 :             getIDocumentStylePoolAccess().GetTxtCollFromPool( RES_POOLCOLL_STANDARD )/*, pUndo*/ );
    1216             : 
    1217        1062 :     SwTable * pNdTbl = &pTblNd->GetTable();
    1218             :     OSL_ENSURE( pNdTbl, "No Table Node created"  );
    1219        1062 :     pNdTbl->RegisterToFormat( *pTableFmt );
    1220             : 
    1221        1062 :     if( !pBoxFmt->GetDepends() )
    1222             :     {
    1223             :         // The Box's Formats already have the right size, we must only set
    1224             :         // the right Border/AutoFmt.
    1225           0 :         pTableFmt->SetFmtAttr( pBoxFmt->GetFrmSize() );
    1226           0 :         delete pBoxFmt;
    1227             :     }
    1228             : 
    1229        1062 :     sal_uLong nIdx = pTblNd->GetIndex();
    1230        1062 :     aNode2Layout.RestoreUpperFrms( GetNodes(), nIdx, nIdx + 1 );
    1231             : 
    1232        1062 :     getIDocumentState().SetModified();
    1233        1062 :     getIDocumentFieldsAccess().SetFieldsDirty( true, NULL, 0 );
    1234        2124 :     return pNdTbl;
    1235             : }
    1236             : 
    1237       14940 : SwNodeRange * SwNodes::ExpandRangeForTableBox(const SwNodeRange & rRange)
    1238             : {
    1239       14940 :     SwNodeRange * pResult = NULL;
    1240       14940 :     bool bChanged = false;
    1241             : 
    1242       14940 :     SwNodeIndex aNewStart = rRange.aStart;
    1243       29880 :     SwNodeIndex aNewEnd = rRange.aEnd;
    1244             : 
    1245       29880 :     SwNodeIndex aEndIndex = rRange.aEnd;
    1246       29880 :     SwNodeIndex aIndex = rRange.aStart;
    1247             : 
    1248       32048 :     while (aIndex < aEndIndex)
    1249             :     {
    1250        2168 :         SwNode& rNode = aIndex.GetNode();
    1251             : 
    1252        2168 :         if (rNode.IsStartNode())
    1253             :         {
    1254             :             // advance aIndex to the end node of this start node
    1255         222 :             SwNode * pEndNode = rNode.EndOfSectionNode();
    1256         222 :             aIndex = *pEndNode;
    1257             : 
    1258         222 :             if (aIndex > aNewEnd)
    1259             :             {
    1260           0 :                 aNewEnd = aIndex;
    1261           0 :                 bChanged = true;
    1262             :             }
    1263             :         }
    1264        1946 :         else if (rNode.IsEndNode())
    1265             :         {
    1266         116 :             SwNode * pStartNode = rNode.StartOfSectionNode();
    1267         116 :             SwNodeIndex aStartIndex = *pStartNode;
    1268             : 
    1269         116 :             if (aStartIndex < aNewStart)
    1270             :             {
    1271         116 :                 aNewStart = aStartIndex;
    1272         116 :                 bChanged = true;
    1273         116 :             }
    1274             :         }
    1275             : 
    1276        2168 :         if (aIndex < aEndIndex)
    1277        2168 :             ++aIndex;
    1278             :     }
    1279             : 
    1280       14940 :     SwNode * pNode = &aIndex.GetNode();
    1281       29880 :     while (pNode->IsEndNode())
    1282             :     {
    1283           0 :         SwNode * pStartNode = pNode->StartOfSectionNode();
    1284           0 :         SwNodeIndex aStartIndex(*pStartNode);
    1285           0 :         aNewStart = aStartIndex;
    1286           0 :         aNewEnd = aIndex;
    1287           0 :         bChanged = true;
    1288             : 
    1289           0 :         ++aIndex;
    1290           0 :         pNode = &aIndex.GetNode();
    1291           0 :     }
    1292             : 
    1293       14940 :     if (bChanged)
    1294          58 :         pResult = new SwNodeRange(aNewStart, aNewEnd);
    1295             : 
    1296       29880 :     return pResult;
    1297             : }
    1298             : 
    1299             : static void
    1300        1062 : lcl_SetTableBoxWidths2(SwTable & rTable, size_t const nMaxBoxes,
    1301             :         SwTableBoxFmt & rBoxFmt, SwDoc & rDoc)
    1302             : {
    1303             :     // rhbz#820283, fdo#55462: set default box widths so table width is covered
    1304        1062 :     SwTableLines & rLines = rTable.GetTabLines();
    1305        6424 :     for (size_t nTmpLine = 0; nTmpLine < rLines.size(); ++nTmpLine)
    1306             :     {
    1307        5362 :         SwTableBoxes & rBoxes = rLines[nTmpLine]->GetTabBoxes();
    1308        5362 :         size_t const nMissing = nMaxBoxes - rBoxes.size();
    1309        5362 :         if (nMissing)
    1310             :         {
    1311             :             // default width for box at the end of an incomplete line
    1312         332 :             SwTableBoxFmt *const pNewFmt = rDoc.MakeTableBoxFmt();
    1313         332 :             size_t nWidth = nMaxBoxes ? USHRT_MAX / nMaxBoxes : USHRT_MAX;
    1314             :             pNewFmt->SetFmtAttr( SwFmtFrmSize(ATT_VAR_SIZE,
    1315         332 :                         nWidth * (nMissing + 1)) );
    1316         332 :             pNewFmt->Add(rBoxes.back());
    1317             :         }
    1318             :     }
    1319        1062 :     size_t nWidth = nMaxBoxes ? USHRT_MAX / nMaxBoxes : USHRT_MAX;
    1320             :     // default width for all boxes not at the end of an incomplete line
    1321        1062 :     rBoxFmt.SetFmtAttr(SwFmtFrmSize(ATT_VAR_SIZE, nWidth));
    1322        1062 : }
    1323             : 
    1324        1062 : SwTableNode* SwNodes::TextToTable( const SwNodes::TableRanges_t & rTableNodes,
    1325             :                                     SwTableFmt* pTblFmt,
    1326             :                                     SwTableLineFmt* pLineFmt,
    1327             :                                     SwTableBoxFmt* pBoxFmt,
    1328             :                                     SwTxtFmtColl* /*pTxtColl*/  /*, SwUndo... pUndo*/  )
    1329             : {
    1330        1062 :     if( !rTableNodes.size() )
    1331           0 :         return 0;
    1332             : 
    1333        1062 :     SwTableNode * pTblNd = new SwTableNode( rTableNodes.begin()->begin()->aStart );
    1334             :     //insert the end node after the last text node
    1335        1062 :    SwNodeIndex aInsertIndex( rTableNodes.rbegin()->rbegin()->aEnd );
    1336        1062 :    ++aInsertIndex;
    1337             : 
    1338             :    //!! owner ship will be transferred in c-tor to SwNodes array.
    1339             :    //!! Thus no real problem here...
    1340        1062 :    new SwEndNode( aInsertIndex, *pTblNd );
    1341             : 
    1342             : #if OSL_DEBUG_LEVEL > 1
    1343             :     const SwNodeRange& rStartRange = *rTableNodes.begin()->begin();
    1344             :     const SwNodeRange& rEndRange = *rTableNodes.rbegin()->rbegin();
    1345             :     (void) rStartRange;
    1346             :     (void) rEndRange;
    1347             : #endif
    1348             : 
    1349        1062 :     SwDoc* pDoc = GetDoc();
    1350        1062 :     SwTable * pTable = &pTblNd->GetTable();
    1351             :     SwTableLine* pLine;
    1352             :     SwTableBox* pBox;
    1353        1062 :     sal_uInt16 nBoxes, nLines, nMaxBoxes = 0;
    1354             : 
    1355        2124 :     SwNodeIndex aNodeIndex = rTableNodes.begin()->begin()->aStart;
    1356             :     // delete frames of all contained content nodes
    1357       24180 :     for( nLines = 0; aNodeIndex <= rTableNodes.rbegin()->rbegin()->aEnd; ++aNodeIndex,++nLines )
    1358             :     {
    1359       23118 :         SwNode& rNode = aNodeIndex.GetNode();
    1360       23118 :         if( rNode.IsCntntNode() )
    1361             :         {
    1362             :             lcl_RemoveBreaks(static_cast<SwCntntNode&>(rNode),
    1363       18778 :                     (0 == nLines) ? pTblFmt : 0);
    1364             :         }
    1365             :     }
    1366             : 
    1367        1062 :     std::vector<std::vector < SwNodeRange > >::const_iterator aRowIter = rTableNodes.begin();
    1368       19272 :     for( nLines = 0, nBoxes = 0;
    1369       12848 :         aRowIter != rTableNodes.end();
    1370             :         ++aRowIter, nLines++, nBoxes = 0 )
    1371             :     {
    1372        5362 :         pLine = new SwTableLine( pLineFmt, 1, 0 );
    1373        5362 :         pTable->GetTabLines().insert( pTable->GetTabLines().begin() + nLines, pLine );
    1374             : 
    1375        5362 :         std::vector< SwNodeRange >::const_iterator aCellIter = aRowIter->begin();
    1376             : 
    1377       20302 :         for( ; aCellIter != aRowIter->end(); ++aCellIter )
    1378             :         {
    1379       14940 :                 const SwNodeIndex aTmpIdx( aCellIter->aStart, 0 );
    1380             : 
    1381       29880 :                SwNodeIndex aCellEndIdx(aCellIter->aEnd);
    1382       14940 :                ++aCellEndIdx;
    1383             :                SwStartNode* pSttNd = new SwStartNode( aTmpIdx, ND_STARTNODE,
    1384       14940 :                                             SwTableBoxStartNode );
    1385             : 
    1386             :                 // Quotation of http://nabble.documentfoundation.org/Some-strange-lines-by-taking-a-look-at-the-bt-of-fdo-51916-tp3994561p3994639.html
    1387             :                 // SwNode's constructor adds itself to the same SwNodes array as the other node (pSttNd).
    1388             :                 // So this statement is only executed for the side-effect.
    1389       14940 :                 new SwEndNode( aCellEndIdx, *pSttNd );
    1390             : 
    1391             :                 //set the start node on all node of the current cell
    1392       29880 :                 SwNodeIndex aCellNodeIdx = aCellIter->aStart;
    1393       31700 :                 for(;aCellNodeIdx <= aCellIter->aEnd; ++aCellNodeIdx )
    1394             :                 {
    1395       16760 :                     aCellNodeIdx.GetNode().pStartOfSection = pSttNd;
    1396             :                     //skip start/end node pairs
    1397       16760 :                     if( aCellNodeIdx.GetNode().IsStartNode() )
    1398          96 :                         aCellNodeIdx = SwNodeIndex( *aCellNodeIdx.GetNode().EndOfSectionNode() );
    1399             :                 }
    1400             : 
    1401             :                 // assign Section to the Box
    1402       14940 :                 pBox = new SwTableBox( pBoxFmt, *pSttNd, pLine );
    1403       14940 :                 pLine->GetTabBoxes().insert( pLine->GetTabBoxes().begin() + nBoxes++, pBox );
    1404       14940 :         }
    1405        5362 :         if( nMaxBoxes < nBoxes )
    1406        1140 :             nMaxBoxes = nBoxes;
    1407             :     }
    1408             : 
    1409        1062 :     lcl_SetTableBoxWidths2(*pTable, nMaxBoxes, *pBoxFmt, *pDoc);
    1410             : 
    1411        2124 :     return pTblNd;
    1412             : }
    1413             : 
    1414             : /**
    1415             :  * Table to Text
    1416             :  */
    1417           0 : bool SwDoc::TableToText( const SwTableNode* pTblNd, sal_Unicode cCh )
    1418             : {
    1419           0 :     if( !pTblNd )
    1420           0 :         return false;
    1421             : 
    1422             :     // #i34471#
    1423             :     // If this is trigged by SwUndoTblToTxt::Repeat() nobody ever deleted
    1424             :     // the table cursor.
    1425           0 :     SwEditShell* pESh = GetEditShell();
    1426           0 :     if( pESh && pESh->IsTableMode() )
    1427           0 :         pESh->ClearMark();
    1428             : 
    1429           0 :     SwNodeRange aRg( *pTblNd, 0, *pTblNd->EndOfSectionNode() );
    1430           0 :     SwUndoTblToTxt* pUndo = 0;
    1431           0 :     SwNodeRange* pUndoRg = 0;
    1432           0 :     if (GetIDocumentUndoRedo().DoesUndo())
    1433             :     {
    1434           0 :         GetIDocumentUndoRedo().ClearRedo();
    1435           0 :         pUndoRg = new SwNodeRange( aRg.aStart, -1, aRg.aEnd, +1 );
    1436           0 :         pUndo = new SwUndoTblToTxt( pTblNd->GetTable(), cCh );
    1437             :     }
    1438             : 
    1439           0 :     SwTableFmlUpdate aMsgHnt( &pTblNd->GetTable() );
    1440           0 :     aMsgHnt.eFlags = TBL_BOXNAME;
    1441           0 :     getIDocumentFieldsAccess().UpdateTblFlds( &aMsgHnt );
    1442             : 
    1443           0 :     bool bRet = GetNodes().TableToText( aRg, cCh, pUndo );
    1444           0 :     if( pUndoRg )
    1445             :     {
    1446           0 :         pUndoRg->aStart++;
    1447           0 :         pUndoRg->aEnd--;
    1448           0 :         pUndo->SetRange( *pUndoRg );
    1449           0 :         GetIDocumentUndoRedo().AppendUndo(pUndo);
    1450           0 :         delete pUndoRg;
    1451             :     }
    1452             : 
    1453           0 :     if( bRet )
    1454           0 :         getIDocumentState().SetModified();
    1455             : 
    1456           0 :     return bRet;
    1457             : }
    1458             : 
    1459             : /**
    1460             :  * Use the ForEach method from PtrArray to recreate Text from a Table.
    1461             :  * The Boxes can also contain Lines!
    1462             :  */
    1463             : struct _DelTabPara
    1464             : {
    1465             :     SwTxtNode* pLastNd;
    1466             :     SwNodes& rNds;
    1467             :     SwUndoTblToTxt* pUndo;
    1468             :     sal_Unicode cCh;
    1469             : 
    1470           0 :     _DelTabPara( SwNodes& rNodes, sal_Unicode cChar, SwUndoTblToTxt* pU ) :
    1471           0 :         pLastNd(0), rNds( rNodes ), pUndo( pU ), cCh( cChar ) {}
    1472           0 :     _DelTabPara( const _DelTabPara& rPara ) :
    1473             :         pLastNd(rPara.pLastNd), rNds( rPara.rNds ),
    1474           0 :         pUndo( rPara.pUndo ), cCh( rPara.cCh ) {}
    1475             : };
    1476             : 
    1477             : // Forward declare so that the Lines and Boxes can use recursion
    1478             : static void lcl_DelBox( SwTableBox* pBox, _DelTabPara* pDelPara );
    1479             : 
    1480           0 : static void lcl_DelLine( SwTableLine* pLine, _DelTabPara* pPara )
    1481             : {
    1482             :     assert(pPara && "The parameters are missing!");
    1483           0 :     _DelTabPara aPara( *pPara );
    1484           0 :     for( SwTableBoxes::iterator it = pLine->GetTabBoxes().begin();
    1485           0 :              it != pLine->GetTabBoxes().end(); ++it)
    1486           0 :         lcl_DelBox(*it, &aPara );
    1487           0 :     if( pLine->GetUpper() ) // Is there a parent Box?
    1488             :         // Return the last TextNode
    1489           0 :         pPara->pLastNd = aPara.pLastNd;
    1490           0 : }
    1491             : 
    1492           0 : static void lcl_DelBox( SwTableBox* pBox, _DelTabPara* pDelPara )
    1493             : {
    1494             :     assert(pDelPara && "The parameters are missing");
    1495             : 
    1496             :     // Delete the Box's Lines
    1497           0 :     if( !pBox->GetTabLines().empty() )
    1498             :     {
    1499           0 :         BOOST_FOREACH( SwTableLine* pLine, pBox->GetTabLines() )
    1500           0 :             lcl_DelLine( pLine, pDelPara );
    1501             :     }
    1502             :     else
    1503             :     {
    1504           0 :         SwDoc* pDoc = pDelPara->rNds.GetDoc();
    1505           0 :         SwNodeRange aDelRg( *pBox->GetSttNd(), 0,
    1506           0 :                             *pBox->GetSttNd()->EndOfSectionNode() );
    1507             :         // Delete the Section
    1508           0 :         pDelPara->rNds.SectionUp( &aDelRg );
    1509             :         const SwTxtNode* pCurTxtNd;
    1510           0 :         if( T2T_PARA != pDelPara->cCh && pDelPara->pLastNd &&
    1511           0 :             0 != ( pCurTxtNd = aDelRg.aStart.GetNode().GetTxtNode() ))
    1512             :         {
    1513             :             // Join the current text node with the last from the previous box if possible
    1514           0 :             sal_uLong nNdIdx = aDelRg.aStart.GetIndex();
    1515           0 :             aDelRg.aStart--;
    1516           0 :             if( pDelPara->pLastNd == &aDelRg.aStart.GetNode() )
    1517             :             {
    1518             :                 // Inserting the separator
    1519             :                 SwIndex aCntIdx( pDelPara->pLastNd,
    1520           0 :                         pDelPara->pLastNd->GetTxt().getLength());
    1521             :                 pDelPara->pLastNd->InsertText( OUString(pDelPara->cCh), aCntIdx,
    1522           0 :                     IDocumentContentOperations::INS_EMPTYEXPAND );
    1523           0 :                 if( pDelPara->pUndo )
    1524             :                     pDelPara->pUndo->AddBoxPos( *pDoc, nNdIdx, aDelRg.aEnd.GetIndex(),
    1525           0 :                                                 aCntIdx.GetIndex() );
    1526             : 
    1527           0 :                 const boost::shared_ptr<sw::mark::CntntIdxStore> pCntntStore(sw::mark::CntntIdxStore::Create());
    1528           0 :                 const sal_Int32 nOldTxtLen = aCntIdx.GetIndex();
    1529           0 :                 pCntntStore->Save( pDoc, nNdIdx, pCurTxtNd->GetTxt().getLength() );
    1530             : 
    1531           0 :                 pDelPara->pLastNd->JoinNext();
    1532             : 
    1533           0 :                 if( !pCntntStore->Empty() )
    1534           0 :                     pCntntStore->Restore( pDoc, pDelPara->pLastNd->GetIndex(), nOldTxtLen );
    1535             :             }
    1536           0 :             else if( pDelPara->pUndo )
    1537             :             {
    1538           0 :                 aDelRg.aStart++;
    1539           0 :                 pDelPara->pUndo->AddBoxPos( *pDoc, nNdIdx, aDelRg.aEnd.GetIndex() );
    1540             :             }
    1541             :         }
    1542           0 :         else if( pDelPara->pUndo )
    1543           0 :             pDelPara->pUndo->AddBoxPos( *pDoc, aDelRg.aStart.GetIndex(), aDelRg.aEnd.GetIndex() );
    1544           0 :         aDelRg.aEnd--;
    1545           0 :         pDelPara->pLastNd = aDelRg.aEnd.GetNode().GetTxtNode();
    1546             : 
    1547             :         // Do not take over the NumberFormatting's adjustment
    1548           0 :         if( pDelPara->pLastNd && pDelPara->pLastNd->HasSwAttrSet() )
    1549           0 :             pDelPara->pLastNd->ResetAttr( RES_PARATR_ADJUST );
    1550             :     }
    1551           0 : }
    1552             : 
    1553           0 : bool SwNodes::TableToText( const SwNodeRange& rRange, sal_Unicode cCh,
    1554             :                             SwUndoTblToTxt* pUndo )
    1555             : {
    1556             :     // Is a Table selected?
    1557             :     SwTableNode* pTblNd;
    1558           0 :     if( rRange.aStart.GetIndex() >= rRange.aEnd.GetIndex() ||
    1559           0 :         0 == ( pTblNd = rRange.aStart.GetNode().GetTableNode()) ||
    1560           0 :         &rRange.aEnd.GetNode() != pTblNd->EndOfSectionNode() )
    1561           0 :         return false;
    1562             : 
    1563             :     // If the Table was alone in a Section, create the Frames via the Table's Upper
    1564           0 :     SwNode2Layout* pNode2Layout = 0;
    1565           0 :     SwNodeIndex aFrmIdx( rRange.aStart );
    1566           0 :     SwNode* pFrmNd = FindPrvNxtFrmNode( aFrmIdx, &rRange.aEnd.GetNode() );
    1567           0 :     if( !pFrmNd )
    1568             :         // Collect all Uppers
    1569           0 :         pNode2Layout = new SwNode2Layout( *pTblNd );
    1570             : 
    1571             :     // Delete the Frames
    1572           0 :     pTblNd->DelFrms();
    1573             : 
    1574             :     // "Delete" the Table and merge all Lines/Boxes
    1575           0 :     _DelTabPara aDelPara( *this, cCh, pUndo );
    1576           0 :     BOOST_FOREACH( SwTableLine *pLine, pTblNd->pTable->GetTabLines() )
    1577           0 :         lcl_DelLine( pLine, &aDelPara );
    1578             : 
    1579             :     // We just created a TextNode with fitting separator for every TableLine.
    1580             :     // Now we only need to delete the TableSection and create the Frames for the
    1581             :     // new TextNode.
    1582           0 :     SwNodeRange aDelRg( rRange.aStart, rRange.aEnd );
    1583             : 
    1584             :     // If the Table has PageDesc/Break Attributes, carry them over to the
    1585             :     // first Text Node
    1586             :     {
    1587             :         // What about UNDO?
    1588           0 :         const SfxItemSet& rTblSet = pTblNd->pTable->GetFrmFmt()->GetAttrSet();
    1589             :         const SfxPoolItem *pBreak, *pDesc;
    1590           0 :         if( SfxItemState::SET != rTblSet.GetItemState( RES_PAGEDESC, false, &pDesc ))
    1591           0 :             pDesc = 0;
    1592           0 :         if( SfxItemState::SET != rTblSet.GetItemState( RES_BREAK, false, &pBreak ))
    1593           0 :             pBreak = 0;
    1594             : 
    1595           0 :         if( pBreak || pDesc )
    1596             :         {
    1597           0 :             SwNodeIndex aIdx( *pTblNd  );
    1598           0 :             SwCntntNode* pCNd = GoNext( &aIdx );
    1599           0 :             if( pBreak )
    1600           0 :                 pCNd->SetAttr( *pBreak );
    1601           0 :             if( pDesc )
    1602           0 :                 pCNd->SetAttr( *pDesc );
    1603             :         }
    1604             :     }
    1605             : 
    1606           0 :     SectionUp( &aDelRg ); // Delete this Section and by that the Table
    1607             :     // #i28006#
    1608           0 :     sal_uLong nStt = aDelRg.aStart.GetIndex(), nEnd = aDelRg.aEnd.GetIndex();
    1609           0 :     if( !pFrmNd )
    1610             :     {
    1611             :         pNode2Layout->RestoreUpperFrms( *this,
    1612           0 :                         aDelRg.aStart.GetIndex(), aDelRg.aEnd.GetIndex() );
    1613           0 :         delete pNode2Layout;
    1614             :     }
    1615             :     else
    1616             :     {
    1617             :         SwCntntNode *pCNd;
    1618             :         SwSectionNode *pSNd;
    1619           0 :         while( aDelRg.aStart.GetIndex() < nEnd )
    1620             :         {
    1621           0 :             if( 0 != ( pCNd = aDelRg.aStart.GetNode().GetCntntNode()))
    1622             :             {
    1623           0 :                 if( pFrmNd->IsCntntNode() )
    1624           0 :                     ((SwCntntNode*)pFrmNd)->MakeFrms( *pCNd );
    1625           0 :                 else if( pFrmNd->IsTableNode() )
    1626           0 :                     ((SwTableNode*)pFrmNd)->MakeFrms( aDelRg.aStart );
    1627           0 :                 else if( pFrmNd->IsSectionNode() )
    1628           0 :                     ((SwSectionNode*)pFrmNd)->MakeFrms( aDelRg.aStart );
    1629           0 :                 pFrmNd = pCNd;
    1630             :             }
    1631           0 :             else if( 0 != ( pSNd = aDelRg.aStart.GetNode().GetSectionNode()))
    1632             :             {
    1633           0 :                 if( !pSNd->GetSection().IsHidden() && !pSNd->IsCntntHidden() )
    1634             :                 {
    1635           0 :                     pSNd->MakeFrms( &aFrmIdx, &aDelRg.aEnd );
    1636           0 :                     pFrmNd = pSNd;
    1637           0 :                     break;
    1638             :                 }
    1639           0 :                 aDelRg.aStart = *pSNd->EndOfSectionNode();
    1640             :             }
    1641           0 :             aDelRg.aStart++;
    1642             :         }
    1643             :     }
    1644             : 
    1645             :     // #i28006# Fly frames have to be restored even if the table was
    1646             :     // #alone in the section
    1647           0 :     const SwFrmFmts& rFlyArr = *GetDoc()->GetSpzFrmFmts();
    1648           0 :     for( sal_uInt16 n = 0; n < rFlyArr.size(); ++n )
    1649             :     {
    1650           0 :         SwFrmFmt *const pFmt = (SwFrmFmt*)rFlyArr[n];
    1651           0 :         const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
    1652           0 :         SwPosition const*const pAPos = rAnchor.GetCntntAnchor();
    1653           0 :         if (pAPos &&
    1654           0 :             ((FLY_AT_PARA == rAnchor.GetAnchorId()) ||
    1655           0 :              (FLY_AT_CHAR == rAnchor.GetAnchorId())) &&
    1656           0 :             nStt <= pAPos->nNode.GetIndex() &&
    1657           0 :             pAPos->nNode.GetIndex() < nEnd )
    1658             :         {
    1659           0 :             pFmt->MakeFrms();
    1660             :         }
    1661             :     }
    1662             : 
    1663           0 :     return true;
    1664             : }
    1665             : 
    1666             : /**
    1667             :  * Inserting Columns/Rows
    1668             :  */
    1669           0 : bool SwDoc::InsertCol( const SwCursor& rCursor, sal_uInt16 nCnt, bool bBehind )
    1670             : {
    1671           0 :     if( !::CheckSplitCells( rCursor, nCnt + 1, nsSwTblSearchType::TBLSEARCH_COL ) )
    1672           0 :         return false;
    1673             : 
    1674             :     // Find the Boxes via the Layout
    1675           0 :     SwSelBoxes aBoxes;
    1676           0 :     ::GetTblSel( rCursor, aBoxes, nsSwTblSearchType::TBLSEARCH_COL );
    1677             : 
    1678           0 :     bool bRet = false;
    1679           0 :     if( !aBoxes.empty() )
    1680           0 :         bRet = InsertCol( aBoxes, nCnt, bBehind );
    1681           0 :     return bRet;
    1682             : }
    1683             : 
    1684           0 : bool SwDoc::InsertCol( const SwSelBoxes& rBoxes, sal_uInt16 nCnt, bool bBehind )
    1685             : {
    1686             :     OSL_ENSURE( !rBoxes.empty(), "No valid Box list" );
    1687           0 :     SwTableNode* pTblNd = (SwTableNode*)rBoxes[0]->GetSttNd()->FindTableNode();
    1688           0 :     if( !pTblNd )
    1689           0 :         return false;
    1690             : 
    1691           0 :     SwTable& rTbl = pTblNd->GetTable();
    1692           0 :     if( rTbl.ISA( SwDDETable ))
    1693           0 :         return false;
    1694             : 
    1695           0 :     SwTableSortBoxes aTmpLst;
    1696           0 :     SwUndoTblNdsChg* pUndo = 0;
    1697           0 :     if (GetIDocumentUndoRedo().DoesUndo())
    1698             :     {
    1699             :         pUndo = new SwUndoTblNdsChg( UNDO_TABLE_INSCOL, rBoxes, *pTblNd,
    1700           0 :                                      0, 0, nCnt, bBehind, false );
    1701           0 :         aTmpLst.insert( rTbl.GetTabSortBoxes() );
    1702             :     }
    1703             : 
    1704           0 :     bool bRet(false);
    1705             :     {
    1706           0 :         ::sw::UndoGuard const undoGuard(GetIDocumentUndoRedo());
    1707             : 
    1708           0 :         SwTableFmlUpdate aMsgHnt( &rTbl );
    1709           0 :         aMsgHnt.eFlags = TBL_BOXPTR;
    1710           0 :         getIDocumentFieldsAccess().UpdateTblFlds( &aMsgHnt );
    1711             : 
    1712           0 :         bRet = rTbl.InsertCol( this, rBoxes, nCnt, bBehind );
    1713           0 :         if (bRet)
    1714             :         {
    1715           0 :             getIDocumentState().SetModified();
    1716           0 :             ::ClearFEShellTabCols();
    1717           0 :             getIDocumentFieldsAccess().SetFieldsDirty( true, NULL, 0 );
    1718           0 :         }
    1719             :     }
    1720             : 
    1721           0 :     if( pUndo )
    1722             :     {
    1723           0 :         if( bRet )
    1724             :         {
    1725           0 :             pUndo->SaveNewBoxes( *pTblNd, aTmpLst );
    1726           0 :             GetIDocumentUndoRedo().AppendUndo( pUndo );
    1727             :         }
    1728             :         else
    1729           0 :             delete pUndo;
    1730             :     }
    1731           0 :     return bRet;
    1732             : }
    1733             : 
    1734           2 : bool SwDoc::InsertRow( const SwCursor& rCursor, sal_uInt16 nCnt, bool bBehind )
    1735             : {
    1736             :     // Find the Boxes via the Layout
    1737           2 :     SwSelBoxes aBoxes;
    1738           2 :     GetTblSel( rCursor, aBoxes, nsSwTblSearchType::TBLSEARCH_ROW );
    1739             : 
    1740           2 :     bool bRet = false;
    1741           2 :     if( !aBoxes.empty() )
    1742           2 :         bRet = InsertRow( aBoxes, nCnt, bBehind );
    1743           2 :     return bRet;
    1744             : }
    1745             : 
    1746           6 : bool SwDoc::InsertRow( const SwSelBoxes& rBoxes, sal_uInt16 nCnt, bool bBehind )
    1747             : {
    1748             :     OSL_ENSURE( !rBoxes.empty(), "No valid Box list" );
    1749           6 :     SwTableNode* pTblNd = (SwTableNode*)rBoxes[0]->GetSttNd()->FindTableNode();
    1750           6 :     if( !pTblNd )
    1751           0 :         return false;
    1752             : 
    1753           6 :     SwTable& rTbl = pTblNd->GetTable();
    1754           6 :     if( rTbl.ISA( SwDDETable ))
    1755           0 :         return false;
    1756             : 
    1757           6 :     SwTableSortBoxes aTmpLst;
    1758           6 :     SwUndoTblNdsChg* pUndo = 0;
    1759           6 :     if (GetIDocumentUndoRedo().DoesUndo())
    1760             :     {
    1761             :         pUndo = new SwUndoTblNdsChg( UNDO_TABLE_INSROW,rBoxes, *pTblNd,
    1762           6 :                                      0, 0, nCnt, bBehind, false );
    1763           6 :         aTmpLst.insert( rTbl.GetTabSortBoxes() );
    1764             :     }
    1765             : 
    1766           6 :     bool bRet(false);
    1767             :     {
    1768           6 :         ::sw::UndoGuard const undoGuard(GetIDocumentUndoRedo());
    1769             : 
    1770          12 :         SwTableFmlUpdate aMsgHnt( &rTbl );
    1771           6 :         aMsgHnt.eFlags = TBL_BOXPTR;
    1772           6 :         getIDocumentFieldsAccess().UpdateTblFlds( &aMsgHnt );
    1773             : 
    1774           6 :         bRet = rTbl.InsertRow( this, rBoxes, nCnt, bBehind );
    1775           6 :         if (bRet)
    1776             :         {
    1777           6 :             getIDocumentState().SetModified();
    1778           6 :             ::ClearFEShellTabCols();
    1779           6 :             getIDocumentFieldsAccess().SetFieldsDirty( true, NULL, 0 );
    1780           6 :         }
    1781             :     }
    1782             : 
    1783           6 :     if( pUndo )
    1784             :     {
    1785           6 :         if( bRet )
    1786             :         {
    1787           6 :             pUndo->SaveNewBoxes( *pTblNd, aTmpLst );
    1788           6 :             GetIDocumentUndoRedo().AppendUndo( pUndo );
    1789             :         }
    1790             :         else
    1791           0 :             delete pUndo;
    1792             :     }
    1793           6 :     return bRet;
    1794             : 
    1795             : }
    1796             : 
    1797             : /**
    1798             :  * Deleting Columns/Rows
    1799             :  */
    1800           2 : bool SwDoc::DeleteRow( const SwCursor& rCursor )
    1801             : {
    1802             :     // Find the Boxes via the Layout
    1803           2 :     SwSelBoxes aBoxes;
    1804           2 :     GetTblSel( rCursor, aBoxes, nsSwTblSearchType::TBLSEARCH_ROW );
    1805           2 :     if( ::HasProtectedCells( aBoxes ))
    1806           0 :         return false;
    1807             : 
    1808             :     // Remove the Crsr from the to-be-deleted Section.
    1809             :     // The Cursor is placed after the table, except for
    1810             :     //  - when there's another Line, we place it in that one
    1811             :     //  - when a Line preceeds it, we place it in that one
    1812             :     {
    1813           2 :         SwTableNode* pTblNd = rCursor.GetNode().FindTableNode();
    1814             : 
    1815           2 :         if( pTblNd->GetTable().ISA( SwDDETable ))
    1816           0 :             return false;
    1817             : 
    1818             :         // Find all Boxes/Lines
    1819           2 :         _FndBox aFndBox( 0, 0 );
    1820             :         {
    1821           2 :             _FndPara aPara( aBoxes, &aFndBox );
    1822           2 :             ForEach_FndLineCopyCol( pTblNd->GetTable().GetTabLines(), &aPara );
    1823             :         }
    1824             : 
    1825           2 :         if( !aFndBox.GetLines().size() )
    1826           0 :             return false;
    1827             : 
    1828           2 :         SwEditShell* pESh = GetEditShell();
    1829           2 :         if( pESh )
    1830             :         {
    1831           2 :             pESh->KillPams();
    1832             :             // FIXME: Actually we should be interating over all Shells!
    1833             :         }
    1834             : 
    1835           2 :         _FndBox* pFndBox = &aFndBox;
    1836           6 :         while( 1 == pFndBox->GetLines().size() &&
    1837           2 :                 1 == pFndBox->GetLines().front().GetBoxes().size() )
    1838             :         {
    1839           0 :             _FndBox *const pTmp = & pFndBox->GetLines().front().GetBoxes()[0];
    1840           0 :             if( pTmp->GetBox()->GetSttNd() )
    1841           0 :                 break; // Else it gets too far
    1842           0 :             pFndBox = pTmp;
    1843             :         }
    1844             : 
    1845           2 :         SwTableLine* pDelLine = pFndBox->GetLines().back().GetLine();
    1846           2 :         SwTableBox* pDelBox = pDelLine->GetTabBoxes().back();
    1847           4 :         while( !pDelBox->GetSttNd() )
    1848             :         {
    1849           0 :             SwTableLine* pLn = pDelBox->GetTabLines()[
    1850           0 :                         pDelBox->GetTabLines().size()-1 ];
    1851           0 :             pDelBox = pLn->GetTabBoxes().back();
    1852             :         }
    1853           2 :         SwTableBox* pNextBox = pDelLine->FindNextBox( pTblNd->GetTable(),
    1854           2 :                                                         pDelBox, true );
    1855           6 :         while( pNextBox &&
    1856           2 :                 pNextBox->GetFrmFmt()->GetProtect().IsCntntProtected() )
    1857           0 :             pNextBox = pNextBox->FindNextBox( pTblNd->GetTable(), pNextBox );
    1858             : 
    1859           2 :         if( !pNextBox ) // No succeeding Boxes? Then take the preceeding one
    1860             :         {
    1861           0 :             pDelLine = pFndBox->GetLines().front().GetLine();
    1862           0 :             pDelBox = pDelLine->GetTabBoxes()[ 0 ];
    1863           0 :             while( !pDelBox->GetSttNd() )
    1864           0 :                 pDelBox = pDelBox->GetTabLines()[0]->GetTabBoxes()[0];
    1865           0 :             pNextBox = pDelLine->FindPreviousBox( pTblNd->GetTable(),
    1866           0 :                                                         pDelBox, true );
    1867           0 :             while( pNextBox &&
    1868           0 :                     pNextBox->GetFrmFmt()->GetProtect().IsCntntProtected() )
    1869           0 :                 pNextBox = pNextBox->FindPreviousBox( pTblNd->GetTable(), pNextBox );
    1870             :         }
    1871             : 
    1872             :         sal_uLong nIdx;
    1873           2 :         if( pNextBox ) // Place the Cursor here
    1874           2 :             nIdx = pNextBox->GetSttIdx() + 1;
    1875             :         else // Else after the Table
    1876           0 :             nIdx = pTblNd->EndOfSectionIndex() + 1;
    1877             : 
    1878           4 :         SwNodeIndex aIdx( GetNodes(), nIdx );
    1879           2 :         SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
    1880           2 :         if( !pCNd )
    1881           0 :             pCNd = GetNodes().GoNext( &aIdx );
    1882             : 
    1883           2 :         if( pCNd )
    1884             :         {
    1885             :             // Change the Shell's Cursor or the one passed?
    1886           2 :             SwPaM* pPam = (SwPaM*)&rCursor;
    1887           2 :             pPam->GetPoint()->nNode = aIdx;
    1888           2 :             pPam->GetPoint()->nContent.Assign( pCNd, 0 );
    1889           2 :             pPam->SetMark(); // Both want a part of it
    1890           2 :             pPam->DeleteMark();
    1891           2 :         }
    1892             :     }
    1893             : 
    1894             :     // Thus delete the Rows
    1895           4 :     GetIDocumentUndoRedo().StartUndo(UNDO_ROW_DELETE, NULL);
    1896           2 :     bool bResult = DeleteRowCol( aBoxes );
    1897           2 :     GetIDocumentUndoRedo().EndUndo(UNDO_ROW_DELETE, NULL);
    1898             : 
    1899           2 :     return bResult;
    1900             : }
    1901             : 
    1902           0 : bool SwDoc::DeleteCol( const SwCursor& rCursor )
    1903             : {
    1904             :     // Find the Boxes via the Layout
    1905           0 :     SwSelBoxes aBoxes;
    1906           0 :     GetTblSel( rCursor, aBoxes, nsSwTblSearchType::TBLSEARCH_COL );
    1907           0 :     if( ::HasProtectedCells( aBoxes ))
    1908           0 :         return false;
    1909             : 
    1910             :     // The Cursors need to be removed from the to-be-deleted range.
    1911             :     // Always place them after/on top of the Table; they are always set
    1912             :     // to the old position via the document position.
    1913           0 :     SwEditShell* pESh = GetEditShell();
    1914           0 :     if( pESh )
    1915             :     {
    1916           0 :         const SwNode* pNd = rCursor.GetNode().FindTableBoxStartNode();
    1917           0 :         pESh->ParkCrsr( SwNodeIndex( *pNd ) );
    1918             :     }
    1919             : 
    1920             :     // Thus delete the Columns
    1921           0 :     GetIDocumentUndoRedo().StartUndo(UNDO_COL_DELETE, NULL);
    1922           0 :     bool bResult = DeleteRowCol( aBoxes, true );
    1923           0 :     GetIDocumentUndoRedo().EndUndo(UNDO_COL_DELETE, NULL);
    1924             : 
    1925           0 :     return bResult;
    1926             : }
    1927             : 
    1928          10 : bool SwDoc::DeleteRowCol( const SwSelBoxes& rBoxes, bool bColumn )
    1929             : {
    1930          10 :     if( ::HasProtectedCells( rBoxes ))
    1931           0 :         return false;
    1932             : 
    1933             :     OSL_ENSURE( !rBoxes.empty(), "No valid Box list" );
    1934          10 :     SwTableNode* pTblNd = (SwTableNode*)rBoxes[0]->GetSttNd()->FindTableNode();
    1935          10 :     if( !pTblNd )
    1936           0 :         return false;
    1937             : 
    1938          10 :     if( pTblNd->GetTable().ISA( SwDDETable ))
    1939           0 :         return false;
    1940             : 
    1941          10 :     ::ClearFEShellTabCols();
    1942          10 :     SwSelBoxes aSelBoxes( rBoxes );
    1943          10 :     SwTable &rTable = pTblNd->GetTable();
    1944          10 :     long nMin = 0;
    1945          10 :     long nMax = 0;
    1946          10 :     if( rTable.IsNewModel() )
    1947             :     {
    1948          10 :         if( bColumn )
    1949           0 :             rTable.ExpandColumnSelection( aSelBoxes, nMin, nMax );
    1950             :         else
    1951          10 :             rTable.FindSuperfluousRows( aSelBoxes );
    1952             :     }
    1953             : 
    1954             :     // Are we deleting the whole Table?
    1955          10 :     const sal_uLong nTmpIdx1 = pTblNd->GetIndex();
    1956          10 :     const sal_uLong nTmpIdx2 = aSelBoxes.back()->GetSttNd()->EndOfSectionIndex() + 1;
    1957          28 :     if( pTblNd->GetTable().GetTabSortBoxes().size() == aSelBoxes.size() &&
    1958          18 :         aSelBoxes[0]->GetSttIdx()-1 == nTmpIdx1 &&
    1959           8 :         nTmpIdx2 == pTblNd->EndOfSectionIndex() )
    1960             :     {
    1961           8 :         bool bNewTxtNd = false;
    1962             :         // Is it alone in a FlyFrame?
    1963           8 :         SwNodeIndex aIdx( *pTblNd, -1 );
    1964           8 :         const SwStartNode* pSttNd = aIdx.GetNode().GetStartNode();
    1965           8 :         if( pSttNd )
    1966             :         {
    1967           8 :             const sal_uLong nTblEnd = pTblNd->EndOfSectionIndex() + 1;
    1968           8 :             const sal_uLong nSectEnd = pSttNd->EndOfSectionIndex();
    1969           8 :             if( nTblEnd == nSectEnd )
    1970             :             {
    1971           0 :                 if( SwFlyStartNode == pSttNd->GetStartNodeType() )
    1972             :                 {
    1973           0 :                     SwFrmFmt* pFmt = pSttNd->GetFlyFmt();
    1974           0 :                     if( pFmt )
    1975             :                     {
    1976             :                         // That's the FlyFormat we're looking for
    1977           0 :                         getIDocumentLayoutAccess().DelLayoutFmt( pFmt );
    1978           0 :                         return true;
    1979             :                     }
    1980             :                 }
    1981             :                 // No Fly? Thus Header or Footer: always leave a TextNode
    1982             :                 // We can forget about Undo then!
    1983           0 :                 bNewTxtNd = true;
    1984             :             }
    1985             :         }
    1986             : 
    1987             :         // No Fly? Then it is a Header or Footer, so keep always a TextNode
    1988           8 :         ++aIdx;
    1989           8 :         if (GetIDocumentUndoRedo().DoesUndo())
    1990             :         {
    1991           8 :             GetIDocumentUndoRedo().ClearRedo();
    1992           8 :             SwPaM aPaM( *pTblNd->EndOfSectionNode(), aIdx.GetNode() );
    1993             : 
    1994           8 :             if( bNewTxtNd )
    1995             :             {
    1996           0 :                 const SwNodeIndex aTmpIdx( *pTblNd->EndOfSectionNode(), 1 );
    1997           0 :                 GetNodes().MakeTxtNode( aTmpIdx,
    1998           0 :                             getIDocumentStylePoolAccess().GetTxtCollFromPool( RES_POOLCOLL_STANDARD ) );
    1999             :             }
    2000             : 
    2001             :             // Save the cursors (UNO and otherwise)
    2002          16 :             SwPaM aSavePaM( SwNodeIndex( *pTblNd->EndOfSectionNode() ) );
    2003           8 :             if( ! aSavePaM.Move( fnMoveForward, fnGoNode ) )
    2004             :             {
    2005           0 :                 *aSavePaM.GetMark() = SwPosition( *pTblNd );
    2006           0 :                 aSavePaM.Move( fnMoveBackward, fnGoNode );
    2007             :             }
    2008             :             {
    2009           8 :                 SwPaM const tmpPaM(*pTblNd, *pTblNd->EndOfSectionNode());
    2010           8 :                 ::PaMCorrAbs(tmpPaM, *aSavePaM.GetMark());
    2011             :             }
    2012             : 
    2013             :             // Move hard PageBreaks to the succeeding Node
    2014           8 :             bool bSavePageBreak = false, bSavePageDesc = false;
    2015           8 :             sal_uLong nNextNd = pTblNd->EndOfSectionIndex()+1;
    2016           8 :             SwCntntNode* pNextNd = GetNodes()[ nNextNd ]->GetCntntNode();
    2017           8 :             if( pNextNd )
    2018             :             {
    2019             :                 {
    2020           8 :                     SwFrmFmt* pTableFmt = pTblNd->GetTable().GetFrmFmt();
    2021             :                     const SfxPoolItem *pItem;
    2022           8 :                     if( SfxItemState::SET == pTableFmt->GetItemState( RES_PAGEDESC,
    2023           8 :                         false, &pItem ) )
    2024             :                     {
    2025           0 :                         pNextNd->SetAttr( *pItem );
    2026           0 :                         bSavePageDesc = true;
    2027             :                     }
    2028             : 
    2029           8 :                     if( SfxItemState::SET == pTableFmt->GetItemState( RES_BREAK,
    2030           8 :                         false, &pItem ) )
    2031             :                     {
    2032           0 :                         pNextNd->SetAttr( *pItem );
    2033           0 :                         bSavePageBreak = true;
    2034             :                     }
    2035             :                 }
    2036             :             }
    2037           8 :             SwUndoDelete* pUndo = new SwUndoDelete( aPaM );
    2038           8 :             if( bNewTxtNd )
    2039           0 :                 pUndo->SetTblDelLastNd();
    2040           8 :             pUndo->SetPgBrkFlags( bSavePageBreak, bSavePageDesc );
    2041           8 :             pUndo->SetTableName(pTblNd->GetTable().GetFrmFmt()->GetName());
    2042          16 :             GetIDocumentUndoRedo().AppendUndo( pUndo );
    2043             :         }
    2044             :         else
    2045             :         {
    2046           0 :             if( bNewTxtNd )
    2047             :             {
    2048           0 :                 const SwNodeIndex aTmpIdx( *pTblNd->EndOfSectionNode(), 1 );
    2049           0 :                 GetNodes().MakeTxtNode( aTmpIdx,
    2050           0 :                             getIDocumentStylePoolAccess().GetTxtCollFromPool( RES_POOLCOLL_STANDARD ) );
    2051             :             }
    2052             : 
    2053             :             // Save the cursors (UNO and otherwise)
    2054           0 :             SwPaM aSavePaM( SwNodeIndex( *pTblNd->EndOfSectionNode() ) );
    2055           0 :             if( ! aSavePaM.Move( fnMoveForward, fnGoNode ) )
    2056             :             {
    2057           0 :                 *aSavePaM.GetMark() = SwPosition( *pTblNd );
    2058           0 :                 aSavePaM.Move( fnMoveBackward, fnGoNode );
    2059             :             }
    2060             :             {
    2061           0 :                 SwPaM const tmpPaM(*pTblNd, *pTblNd->EndOfSectionNode());
    2062           0 :                 ::PaMCorrAbs(tmpPaM, *aSavePaM.GetMark());
    2063             :             }
    2064             : 
    2065             :             // Move hard PageBreaks to the succeeding Node
    2066           0 :             SwCntntNode* pNextNd = GetNodes()[ pTblNd->EndOfSectionIndex()+1 ]->GetCntntNode();
    2067           0 :             if( pNextNd )
    2068             :             {
    2069           0 :                 SwFrmFmt* pTableFmt = pTblNd->GetTable().GetFrmFmt();
    2070             :                 const SfxPoolItem *pItem;
    2071           0 :                 if( SfxItemState::SET == pTableFmt->GetItemState( RES_PAGEDESC,
    2072           0 :                     false, &pItem ) )
    2073           0 :                     pNextNd->SetAttr( *pItem );
    2074             : 
    2075           0 :                 if( SfxItemState::SET == pTableFmt->GetItemState( RES_BREAK,
    2076           0 :                     false, &pItem ) )
    2077           0 :                     pNextNd->SetAttr( *pItem );
    2078             :             }
    2079             : 
    2080           0 :             pTblNd->DelFrms();
    2081           0 :             getIDocumentContentOperations().DeleteSection( pTblNd );
    2082             :         }
    2083           8 :         getIDocumentState().SetModified();
    2084           8 :         getIDocumentFieldsAccess().SetFieldsDirty( true, NULL, 0 );
    2085           8 :         return true;
    2086             :     }
    2087             : 
    2088           2 :     SwUndoTblNdsChg* pUndo = 0;
    2089           2 :     if (GetIDocumentUndoRedo().DoesUndo())
    2090             :     {
    2091             :         pUndo = new SwUndoTblNdsChg( UNDO_TABLE_DELBOX, aSelBoxes, *pTblNd,
    2092           2 :                                      nMin, nMax, 0, false, false );
    2093             :     }
    2094             : 
    2095           2 :     bool bRet(false);
    2096             :     {
    2097           2 :         ::sw::UndoGuard const undoGuard(GetIDocumentUndoRedo());
    2098             : 
    2099           4 :         SwTableFmlUpdate aMsgHnt( &pTblNd->GetTable() );
    2100           2 :         aMsgHnt.eFlags = TBL_BOXPTR;
    2101           2 :         getIDocumentFieldsAccess().UpdateTblFlds( &aMsgHnt );
    2102             : 
    2103           2 :         if (rTable.IsNewModel())
    2104             :         {
    2105           2 :             if (bColumn)
    2106           0 :                 rTable.PrepareDeleteCol( nMin, nMax );
    2107           2 :             rTable.FindSuperfluousRows( aSelBoxes );
    2108           2 :             if (pUndo)
    2109           2 :                 pUndo->ReNewBoxes( aSelBoxes );
    2110             :         }
    2111           2 :         bRet = rTable.DeleteSel( this, aSelBoxes, 0, pUndo, true, true );
    2112           2 :         if (bRet)
    2113             :         {
    2114           2 :             getIDocumentState().SetModified();
    2115           2 :             getIDocumentFieldsAccess().SetFieldsDirty( true, NULL, 0 );
    2116           2 :         }
    2117             :     }
    2118             : 
    2119           2 :     if( pUndo )
    2120             :     {
    2121           2 :         if( bRet )
    2122             :         {
    2123           2 :             GetIDocumentUndoRedo().AppendUndo( pUndo );
    2124             :         }
    2125             :         else
    2126           0 :             delete pUndo;
    2127             :     }
    2128             : 
    2129           2 :     return bRet;
    2130             : }
    2131             : 
    2132             : /**
    2133             :  * Split up/merge Boxes in the Table
    2134             :  */
    2135           4 : bool SwDoc::SplitTbl( const SwSelBoxes& rBoxes, bool bVert, sal_uInt16 nCnt,
    2136             :                       bool bSameHeight )
    2137             : {
    2138             :     OSL_ENSURE( !rBoxes.empty() && nCnt, "No valid Box list" );
    2139           4 :     SwTableNode* pTblNd = (SwTableNode*)rBoxes[0]->GetSttNd()->FindTableNode();
    2140           4 :     if( !pTblNd )
    2141           0 :         return false;
    2142             : 
    2143           4 :     SwTable& rTbl = pTblNd->GetTable();
    2144           4 :     if( rTbl.ISA( SwDDETable ))
    2145           0 :         return false;
    2146             : 
    2147           4 :     std::vector<sal_uLong> aNdsCnts;
    2148           8 :     SwTableSortBoxes aTmpLst;
    2149           4 :     SwUndoTblNdsChg* pUndo = 0;
    2150           4 :     if (GetIDocumentUndoRedo().DoesUndo())
    2151             :     {
    2152             :         pUndo = new SwUndoTblNdsChg( UNDO_TABLE_SPLIT, rBoxes, *pTblNd, 0, 0,
    2153           4 :                                      nCnt, bVert, bSameHeight );
    2154             : 
    2155           4 :         aTmpLst.insert( rTbl.GetTabSortBoxes() );
    2156           4 :         if( !bVert )
    2157             :         {
    2158           4 :             for (size_t n = 0; n < rBoxes.size(); ++n)
    2159             :             {
    2160           2 :                 const SwStartNode* pSttNd = rBoxes[ n ]->GetSttNd();
    2161           4 :                 aNdsCnts.push_back( pSttNd->EndOfSectionIndex() -
    2162           4 :                                     pSttNd->GetIndex() );
    2163             :             }
    2164             :         }
    2165             :     }
    2166             : 
    2167           4 :     bool bRet(false);
    2168             :     {
    2169           4 :         ::sw::UndoGuard const undoGuard(GetIDocumentUndoRedo());
    2170             : 
    2171           8 :         SwTableFmlUpdate aMsgHnt( &rTbl );
    2172           4 :         aMsgHnt.eFlags = TBL_BOXPTR;
    2173           4 :         getIDocumentFieldsAccess().UpdateTblFlds( &aMsgHnt );
    2174             : 
    2175           4 :         if (bVert)
    2176           2 :             bRet = rTbl.SplitCol( this, rBoxes, nCnt );
    2177             :         else
    2178           2 :             bRet = rTbl.SplitRow( this, rBoxes, nCnt, bSameHeight );
    2179             : 
    2180           4 :         if (bRet)
    2181             :         {
    2182           4 :             getIDocumentState().SetModified();
    2183           4 :             getIDocumentFieldsAccess().SetFieldsDirty( true, NULL, 0 );
    2184           4 :         }
    2185             :     }
    2186             : 
    2187           4 :     if( pUndo )
    2188             :     {
    2189           4 :         if( bRet )
    2190             :         {
    2191           4 :             if( bVert )
    2192           2 :                 pUndo->SaveNewBoxes( *pTblNd, aTmpLst );
    2193             :             else
    2194           2 :                 pUndo->SaveNewBoxes( *pTblNd, aTmpLst, rBoxes, aNdsCnts );
    2195           4 :             GetIDocumentUndoRedo().AppendUndo( pUndo );
    2196             :         }
    2197             :         else
    2198           0 :             delete pUndo;
    2199             :     }
    2200             : 
    2201           8 :     return bRet;
    2202             : }
    2203             : 
    2204           6 : sal_uInt16 SwDoc::MergeTbl( SwPaM& rPam )
    2205             : {
    2206             :     // Check if the current cursor's Point/Mark are inside a Table
    2207           6 :     SwTableNode* pTblNd = rPam.GetNode().FindTableNode();
    2208           6 :     if( !pTblNd )
    2209           0 :         return TBLMERGE_NOSELECTION;
    2210           6 :     SwTable& rTable = pTblNd->GetTable();
    2211           6 :     if( rTable.ISA(SwDDETable) )
    2212           0 :         return TBLMERGE_NOSELECTION;
    2213           6 :     sal_uInt16 nRet = TBLMERGE_NOSELECTION;
    2214           6 :     if( !rTable.IsNewModel() )
    2215             :     {
    2216           0 :         nRet =::CheckMergeSel( rPam );
    2217           0 :         if( TBLMERGE_OK != nRet )
    2218           0 :             return nRet;
    2219           0 :         nRet = TBLMERGE_NOSELECTION;
    2220             :     }
    2221             : 
    2222             :     // #i33394#
    2223           6 :     GetIDocumentUndoRedo().StartUndo( UNDO_TABLE_MERGE, NULL );
    2224             : 
    2225           6 :     RedlineMode_t eOld = getIDocumentRedlineAccess().GetRedlineMode();
    2226           6 :     getIDocumentRedlineAccess().SetRedlineMode_intern((RedlineMode_t)(eOld | nsRedlineMode_t::REDLINE_IGNORE));
    2227             : 
    2228           6 :     SwUndoTblMerge *const pUndo( (GetIDocumentUndoRedo().DoesUndo())
    2229           2 :         ?   new SwUndoTblMerge( rPam )
    2230           8 :         :   0 );
    2231             : 
    2232             :     // Find the Boxes via the Layout
    2233           6 :     SwSelBoxes aBoxes;
    2234          12 :     SwSelBoxes aMerged;
    2235             :     SwTableBox* pMergeBox;
    2236             : 
    2237           6 :     if( !rTable.PrepareMerge( rPam, aBoxes, aMerged, &pMergeBox, pUndo ) )
    2238             :     {   // No cells found to merge
    2239           0 :         getIDocumentRedlineAccess().SetRedlineMode_intern( eOld );
    2240           0 :         if( pUndo )
    2241             :         {
    2242           0 :             delete pUndo;
    2243           0 :             SwUndoId nLastUndoId(UNDO_EMPTY);
    2244           0 :             if (GetIDocumentUndoRedo().GetLastUndoInfo(0, & nLastUndoId)
    2245           0 :                 && (UNDO_REDLINE == nLastUndoId))
    2246             :             {
    2247             :                 // FIXME: why is this horrible cleanup necessary?
    2248             :                 SwUndoRedline *const pU = dynamic_cast<SwUndoRedline*>(
    2249           0 :                         GetUndoManager().RemoveLastUndo());
    2250           0 :                 if (pU && pU->GetRedlSaveCount())
    2251             :                 {
    2252           0 :                     SwEditShell *const pEditShell(GetEditShell());
    2253             :                     OSL_ASSERT(pEditShell);
    2254           0 :                     ::sw::UndoRedoContext context(*this, *pEditShell);
    2255           0 :                     static_cast<SfxUndoAction *>(pU)->UndoWithContext(context);
    2256             :                 }
    2257           0 :                 delete pU;
    2258             :             }
    2259             :         }
    2260             :     }
    2261             :     else
    2262             :     {
    2263             :         // The PaMs need to be removed from the to-be-deleted range. Thus always place
    2264             :         // them at the end of/on top of the Table; it's always set to the old position via
    2265             :         // the Document Position.
    2266             :         // For a start remember an index for the temporary position, because we cannot
    2267             :         // access it after GetMergeSel
    2268             :         {
    2269           6 :             rPam.DeleteMark();
    2270           6 :             rPam.GetPoint()->nNode = *pMergeBox->GetSttNd();
    2271           6 :             rPam.GetPoint()->nContent.Assign( 0, 0 );
    2272           6 :             rPam.SetMark();
    2273           6 :             rPam.DeleteMark();
    2274             : 
    2275           6 :             SwPaM* pTmp = &rPam;
    2276          12 :             while( &rPam != ( pTmp = (SwPaM*)pTmp->GetNext() ))
    2277           0 :                 for( int i = 0; i < 2; ++i )
    2278           0 :                     pTmp->GetBound( (bool)i ) = *rPam.GetPoint();
    2279             :         }
    2280             : 
    2281             :         // Merge them
    2282           6 :         SwTableFmlUpdate aMsgHnt( &pTblNd->GetTable() );
    2283           6 :         aMsgHnt.eFlags = TBL_BOXPTR;
    2284           6 :         getIDocumentFieldsAccess().UpdateTblFlds( &aMsgHnt );
    2285             : 
    2286           6 :         if( pTblNd->GetTable().Merge( this, aBoxes, aMerged, pMergeBox, pUndo ))
    2287             :         {
    2288           6 :             nRet = TBLMERGE_OK;
    2289           6 :             getIDocumentState().SetModified();
    2290           6 :             getIDocumentFieldsAccess().SetFieldsDirty( true, NULL, 0 );
    2291           6 :             if( pUndo )
    2292             :             {
    2293           2 :                 GetIDocumentUndoRedo().AppendUndo( pUndo );
    2294             :             }
    2295             :         }
    2296             :         else
    2297           0 :             delete pUndo;
    2298             : 
    2299           6 :         rPam.GetPoint()->nNode = *pMergeBox->GetSttNd();
    2300           6 :         rPam.Move();
    2301             : 
    2302           6 :         ::ClearFEShellTabCols();
    2303           6 :         getIDocumentRedlineAccess().SetRedlineMode_intern( eOld );
    2304             :     }
    2305           6 :     GetIDocumentUndoRedo().EndUndo( UNDO_TABLE_MERGE, NULL );
    2306          12 :     return nRet;
    2307             : }
    2308             : 
    2309        1816 : SwTableNode::SwTableNode( const SwNodeIndex& rIdx )
    2310        1816 :     : SwStartNode( rIdx, ND_TABLENODE )
    2311             : {
    2312        1816 :     pTable = new SwTable( 0 );
    2313        1816 : }
    2314             : 
    2315        5442 : SwTableNode::~SwTableNode()
    2316             : {
    2317             :     // Notify UNO wrappers
    2318        1814 :     SwFrmFmt* pTblFmt = GetTable().GetFrmFmt();
    2319             :     SwPtrMsgPoolItem aMsgHint( RES_REMOVE_UNO_OBJECT,
    2320        1814 :                                 pTblFmt );
    2321        1814 :     pTblFmt->ModifyNotification( &aMsgHint, &aMsgHint );
    2322        1814 :     DelFrms();
    2323        1814 :     delete pTable;
    2324        3628 : }
    2325             : 
    2326        1312 : SwTabFrm *SwTableNode::MakeFrm( SwFrm* pSib )
    2327             : {
    2328        1312 :     return new SwTabFrm( *pTable, pSib );
    2329             : }
    2330             : 
    2331             : /**
    2332             :  * Creates all Views from the Document for the preceeding Node. The resulting ContentFrames
    2333             :  * are added to the corresponding Layout.
    2334             :  */
    2335          10 : void SwTableNode::MakeFrms(const SwNodeIndex & rIdx )
    2336             : {
    2337          10 :     if( !GetTable().GetFrmFmt()->GetDepends()) // Do we actually have Frame?
    2338          10 :         return;
    2339             : 
    2340             :     SwFrm *pFrm, *pNew;
    2341          10 :     SwCntntNode * pNode = rIdx.GetNode().GetCntntNode();
    2342             : 
    2343             :     OSL_ENSURE( pNode, "No ContentNode or CopyNode and new Node is identical");
    2344             : 
    2345          10 :     bool bBefore = rIdx < GetIndex();
    2346             : 
    2347          10 :     SwNode2Layout aNode2Layout( *this, rIdx.GetIndex() );
    2348             : 
    2349          26 :     while( 0 != (pFrm = aNode2Layout.NextFrm()) )
    2350             :     {
    2351           6 :         pNew = pNode->MakeFrm( pFrm );
    2352             :         // Will the Node receive Frames before or after?
    2353           6 :         if ( bBefore )
    2354             :             // The new one preceeds me
    2355           6 :             pNew->Paste( pFrm->GetUpper(), pFrm );
    2356             :         else
    2357             :             // The new one succeeds me
    2358           0 :             pNew->Paste( pFrm->GetUpper(), pFrm->GetNext() );
    2359          10 :     }
    2360             : }
    2361             : 
    2362             : /**
    2363             :  * Create a TblFrm for every Shell and insert before the corresponding CntntFrm.
    2364             :  */
    2365         788 : void SwTableNode::MakeFrms( SwNodeIndex* pIdxBehind )
    2366             : {
    2367             :     OSL_ENSURE( pIdxBehind, "No Index" );
    2368         788 :     *pIdxBehind = *this;
    2369         788 :     SwNode *pNd = GetNodes().FindPrvNxtFrmNode( *pIdxBehind, EndOfSectionNode() );
    2370         788 :     if( !pNd )
    2371        1426 :         return ;
    2372             : 
    2373         150 :     SwFrm *pFrm( 0L );
    2374         150 :     SwLayoutFrm *pUpper( 0L );
    2375         150 :     SwNode2Layout aNode2Layout( *pNd, GetIndex() );
    2376         434 :     while( 0 != (pUpper = aNode2Layout.UpperFrm( pFrm, *this )) )
    2377             :     {
    2378         134 :         SwTabFrm* pNew = MakeFrm( pUpper );
    2379         134 :         pNew->Paste( pUpper, pFrm );
    2380             :         // #i27138#
    2381             :         // notify accessibility paragraphs objects about changed
    2382             :         // CONTENT_FLOWS_FROM/_TO relation.
    2383             :         // Relation CONTENT_FLOWS_FROM for next paragraph will change
    2384             :         // and relation CONTENT_FLOWS_TO for previous paragraph will change.
    2385             :         {
    2386         134 :             SwViewShell* pViewShell( pNew->getRootFrm()->GetCurrShell() );
    2387         268 :             if ( pViewShell && pViewShell->GetLayout() &&
    2388         134 :                  pViewShell->GetLayout()->IsAnyShellAccessible() )
    2389             :             {
    2390             :                 pViewShell->InvalidateAccessibleParaFlowRelation(
    2391           0 :                             dynamic_cast<SwTxtFrm*>(pNew->FindNextCnt( true )),
    2392           0 :                             dynamic_cast<SwTxtFrm*>(pNew->FindPrevCnt( true )) );
    2393             :             }
    2394             :         }
    2395         134 :         ((SwTabFrm*)pNew)->RegistFlys();
    2396         150 :     }
    2397             : }
    2398             : 
    2399        2472 : void SwTableNode::DelFrms()
    2400             : {
    2401             :     /* For a start, cut out and delete the TabFrms (which will also delete the Columns and Rows)
    2402             :        The TabFrms are attached to the FrmFmt of the SwTable.
    2403             :        We need to delete them in a more cumbersome way, for the Master to also delete the Follows. */
    2404             : 
    2405        2472 :     SwIterator<SwTabFrm,SwFmt> aIter( *(pTable->GetFrmFmt()) );
    2406        2472 :     SwTabFrm *pFrm = aIter.First();
    2407        4996 :     while ( pFrm )
    2408             :     {
    2409          52 :         bool bAgain = false;
    2410             :         {
    2411          52 :             if ( !pFrm->IsFollow() )
    2412             :             {
    2413         104 :                 while ( pFrm->HasFollow() )
    2414           0 :                     pFrm->JoinAndDelFollows();
    2415             :                 // #i27138#
    2416             :                 // notify accessibility paragraphs objects about changed
    2417             :                 // CONTENT_FLOWS_FROM/_TO relation.
    2418             :                 // Relation CONTENT_FLOWS_FROM for current next paragraph will change
    2419             :                 // and relation CONTENT_FLOWS_TO for current previous paragraph will change.
    2420             :                 {
    2421          52 :                     SwViewShell* pViewShell( pFrm->getRootFrm()->GetCurrShell() );
    2422         104 :                     if ( pViewShell && pViewShell->GetLayout() &&
    2423          52 :                          pViewShell->GetLayout()->IsAnyShellAccessible() )
    2424             :                     {
    2425             :                         pViewShell->InvalidateAccessibleParaFlowRelation(
    2426           0 :                             dynamic_cast<SwTxtFrm*>(pFrm->FindNextCnt( true )),
    2427           0 :                             dynamic_cast<SwTxtFrm*>(pFrm->FindPrevCnt( true )) );
    2428             :                     }
    2429             :                 }
    2430          52 :                 pFrm->Cut();
    2431          52 :                 delete pFrm;
    2432          52 :                 bAgain = true;
    2433             :             }
    2434             :         }
    2435          52 :         pFrm = bAgain ? aIter.First() : aIter.Next();
    2436        2472 :     }
    2437        2472 : }
    2438             : 
    2439           0 : void SwTableNode::SetNewTable( SwTable* pNewTable, bool bNewFrames )
    2440             : {
    2441           0 :     DelFrms();
    2442           0 :     delete pTable;
    2443           0 :     pTable = pNewTable;
    2444           0 :     if( bNewFrames )
    2445             :     {
    2446           0 :         SwNodeIndex aIdx( *EndOfSectionNode());
    2447           0 :         GetNodes().GoNext( &aIdx );
    2448           0 :         MakeFrms( &aIdx );
    2449             :     }
    2450           0 : }
    2451             : 
    2452        1826 : void SwTableNode::RemoveRedlines()
    2453             : {
    2454        1826 :     SwDoc* pDoc = GetDoc();
    2455        1826 :     if (pDoc)
    2456             :     {
    2457        1826 :         SwTable& rTbl = GetTable();
    2458        1826 :         if ( pDoc->getIDocumentRedlineAccess().HasExtraRedlineTbl() )
    2459        1826 :             pDoc->getIDocumentRedlineAccess().GetExtraRedlineTbl().DeleteAllTableRedlines( pDoc, rTbl, true, USHRT_MAX );
    2460             :     }
    2461        1826 : }
    2462             : 
    2463           2 : void SwDoc::GetTabCols( SwTabCols &rFill, const SwCursor* pCrsr,
    2464             :                         const SwCellFrm* pBoxFrm ) const
    2465             : {
    2466           2 :     const SwTableBox* pBox = 0;
    2467           2 :     SwTabFrm *pTab = 0;
    2468             : 
    2469           2 :     if( pBoxFrm )
    2470             :     {
    2471           2 :         pTab = ((SwFrm*)pBoxFrm)->ImplFindTabFrm();
    2472           2 :         pBox = pBoxFrm->GetTabBox();
    2473             :     }
    2474           0 :     else if( pCrsr )
    2475             :     {
    2476           0 :         const SwCntntNode* pCNd = pCrsr->GetCntntNode();
    2477           0 :         if( !pCNd )
    2478           0 :             return ;
    2479             : 
    2480           0 :         Point aPt;
    2481           0 :         const SwShellCrsr *pShCrsr = dynamic_cast<const SwShellCrsr*>(pCrsr);
    2482           0 :         if( pShCrsr )
    2483           0 :             aPt = pShCrsr->GetPtPos();
    2484             : 
    2485           0 :         const SwFrm* pTmpFrm = pCNd->getLayoutFrm( pCNd->GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout(), &aPt, 0, false );
    2486           0 :         do {
    2487           0 :             pTmpFrm = pTmpFrm->GetUpper();
    2488           0 :         } while ( !pTmpFrm->IsCellFrm() );
    2489             : 
    2490           0 :         pBoxFrm = (SwCellFrm*)pTmpFrm;
    2491           0 :         pTab = ((SwFrm*)pBoxFrm)->ImplFindTabFrm();
    2492           0 :         pBox = pBoxFrm->GetTabBox();
    2493             :     }
    2494           0 :     else if( !pCrsr && !pBoxFrm )
    2495             :     {
    2496             :         OSL_ENSURE( false, "One of them needs to be specified!" );
    2497           0 :         return ;
    2498             :     }
    2499             : 
    2500             :     // Set fixed points, LeftMin in Document coordinates, all others relative
    2501           2 :     SWRECTFN( pTab )
    2502           2 :     const SwPageFrm* pPage = pTab->FindPageFrm();
    2503           4 :     const sal_uLong nLeftMin = (pTab->Frm().*fnRect->fnGetLeft)() -
    2504           4 :                            (pPage->Frm().*fnRect->fnGetLeft)();
    2505           4 :     const sal_uLong nRightMax = (pTab->Frm().*fnRect->fnGetRight)() -
    2506           4 :                             (pPage->Frm().*fnRect->fnGetLeft)();
    2507             : 
    2508           2 :     rFill.SetLeftMin ( nLeftMin );
    2509           2 :     rFill.SetLeft    ( (pTab->Prt().*fnRect->fnGetLeft)() );
    2510           2 :     rFill.SetRight   ( (pTab->Prt().*fnRect->fnGetRight)());
    2511           2 :     rFill.SetRightMax( nRightMax - nLeftMin );
    2512             : 
    2513           2 :     pTab->GetTable()->GetTabCols( rFill, pBox );
    2514             : }
    2515             : 
    2516             : // Here are some little helpers used in SwDoc::GetTabRows
    2517             : 
    2518             : #define ROWFUZZY 25
    2519             : 
    2520             : struct FuzzyCompare
    2521             : {
    2522             :     bool operator() ( long s1, long s2 ) const;
    2523             : };
    2524             : 
    2525          60 : bool FuzzyCompare::operator() ( long s1, long s2 ) const
    2526             : {
    2527          60 :     return ( s1 < s2 && std::abs( s1 - s2 ) > ROWFUZZY );
    2528             : }
    2529             : 
    2530           6 : static bool lcl_IsFrmInColumn( const SwCellFrm& rFrm, SwSelBoxes& rBoxes )
    2531             : {
    2532           8 :     for (size_t i = 0; i < rBoxes.size(); ++i)
    2533             :     {
    2534           8 :         if ( rFrm.GetTabBox() == rBoxes[ i ] )
    2535           6 :             return true;
    2536             :     }
    2537             : 
    2538           0 :     return false;
    2539             : }
    2540             : 
    2541           2 : void SwDoc::GetTabRows( SwTabCols &rFill, const SwCursor* ,
    2542             :                         const SwCellFrm* pBoxFrm ) const
    2543             : {
    2544             :     OSL_ENSURE( pBoxFrm, "GetTabRows called without pBoxFrm" );
    2545             : 
    2546             :     // Make code robust:
    2547           2 :     if ( !pBoxFrm )
    2548           0 :         return;
    2549             : 
    2550             :     // #i39552# Collection of the boxes of the current
    2551             :     // column has to be done at the beginning of this function, because
    2552             :     // the table may be formatted in ::GetTblSel.
    2553           2 :     SwDeletionChecker aDelCheck( pBoxFrm );
    2554             : 
    2555           2 :     SwSelBoxes aBoxes;
    2556           2 :     const SwCntntFrm* pCntnt = ::GetCellCntnt( *pBoxFrm );
    2557           2 :     if ( pCntnt && pCntnt->IsTxtFrm() )
    2558             :     {
    2559           2 :         const SwPosition aPos( *((SwTxtFrm*)pCntnt)->GetTxtNode() );
    2560           4 :         const SwCursor aTmpCrsr( aPos, 0, false );
    2561           4 :         ::GetTblSel( aTmpCrsr, aBoxes, nsSwTblSearchType::TBLSEARCH_COL );
    2562             :     }
    2563             : 
    2564             :     // Make code robust:
    2565           2 :     if ( aDelCheck.HasBeenDeleted() )
    2566             :     {
    2567             :         OSL_FAIL( "Current box has been deleted during GetTabRows()" );
    2568           0 :         return;
    2569             :     }
    2570             : 
    2571             :     // Make code robust:
    2572           2 :     const SwTabFrm* pTab = pBoxFrm->FindTabFrm();
    2573             :     OSL_ENSURE( pTab, "GetTabRows called without a table" );
    2574           2 :     if ( !pTab )
    2575           0 :         return;
    2576             : 
    2577           2 :     const SwFrm* pFrm = pTab->GetNextLayoutLeaf();
    2578             : 
    2579             :     // Set fixed points, LeftMin in Document coordinates, all others relative
    2580           2 :     SWRECTFN( pTab )
    2581           2 :     const SwPageFrm* pPage = pTab->FindPageFrm();
    2582             :     const long nLeftMin  = ( bVert ?
    2583           0 :                              pTab->GetPrtLeft() - pPage->Frm().Left() :
    2584           2 :                              pTab->GetPrtTop() - pPage->Frm().Top() );
    2585           2 :     const long nLeft     = bVert ? LONG_MAX : 0;
    2586           2 :     const long nRight    = (pTab->Prt().*fnRect->fnGetHeight)();
    2587           2 :     const long nRightMax = bVert ? nRight : LONG_MAX;
    2588             : 
    2589           2 :     rFill.SetLeftMin( nLeftMin );
    2590           2 :     rFill.SetLeft( nLeft );
    2591           2 :     rFill.SetRight( nRight );
    2592           2 :     rFill.SetRightMax( nRightMax );
    2593             : 
    2594             :     typedef std::map< long, std::pair< long, long >, FuzzyCompare > BoundaryMap;
    2595           4 :     BoundaryMap aBoundaries;
    2596           2 :     BoundaryMap::iterator aIter;
    2597           2 :     std::pair< long, long > aPair;
    2598             : 
    2599             :     typedef std::map< long, bool > HiddenMap;
    2600           4 :     HiddenMap aHidden;
    2601           2 :     HiddenMap::iterator aHiddenIter;
    2602             : 
    2603          12 :     while ( pFrm && pTab->IsAnLower( pFrm ) )
    2604             :     {
    2605           8 :         if ( pFrm->IsCellFrm() && pFrm->FindTabFrm() == pTab )
    2606             :         {
    2607             :             // upper and lower borders of current cell frame:
    2608           8 :             long nUpperBorder = (pFrm->Frm().*fnRect->fnGetTop)();
    2609           8 :             long nLowerBorder = (pFrm->Frm().*fnRect->fnGetBottom)();
    2610             : 
    2611             :             // get boundaries for nUpperBorder:
    2612           8 :             aIter = aBoundaries.find( nUpperBorder );
    2613           8 :             if ( aIter == aBoundaries.end() )
    2614             :             {
    2615           2 :                 aPair.first = nUpperBorder; aPair.second = LONG_MAX;
    2616           2 :                 aBoundaries[ nUpperBorder ] = aPair;
    2617             :             }
    2618             : 
    2619             :             // get boundaries for nLowerBorder:
    2620           8 :             aIter = aBoundaries.find( nLowerBorder );
    2621           8 :             if ( aIter == aBoundaries.end() )
    2622             :             {
    2623           4 :                 aPair.first = nUpperBorder; aPair.second = LONG_MAX;
    2624             :             }
    2625             :             else
    2626             :             {
    2627           4 :                 nLowerBorder = (*aIter).first;
    2628           4 :                 long nNewLowerBorderUpperBoundary = std::max( (*aIter).second.first, nUpperBorder );
    2629           4 :                 aPair.first = nNewLowerBorderUpperBoundary; aPair.second = LONG_MAX;
    2630             :             }
    2631           8 :             aBoundaries[ nLowerBorder ] = aPair;
    2632             : 
    2633             :             // calculate hidden flags for entry nUpperBorder/nLowerBorder:
    2634           8 :             long nTmpVal = nUpperBorder;
    2635          24 :             for ( sal_uInt8 i = 0; i < 2; ++i )
    2636             :             {
    2637          16 :                 aHiddenIter = aHidden.find( nTmpVal );
    2638          16 :                 if ( aHiddenIter == aHidden.end() )
    2639           6 :                     aHidden[ nTmpVal ] = !lcl_IsFrmInColumn( *((SwCellFrm*)pFrm), aBoxes );
    2640             :                 else
    2641             :                 {
    2642          10 :                     if ( aHidden[ nTmpVal ] &&
    2643           0 :                          lcl_IsFrmInColumn( *((SwCellFrm*)pFrm), aBoxes ) )
    2644           0 :                         aHidden[ nTmpVal ] = false;
    2645             :                 }
    2646          16 :                 nTmpVal = nLowerBorder;
    2647             :             }
    2648             :         }
    2649             : 
    2650           8 :         pFrm = pFrm->GetNextLayoutLeaf();
    2651             :     }
    2652             : 
    2653             :     // transfer calculated values from BoundaryMap and HiddenMap into rFill:
    2654           2 :     size_t nIdx = 0;
    2655           8 :     for ( aIter = aBoundaries.begin(); aIter != aBoundaries.end(); ++aIter )
    2656             :     {
    2657           6 :         const long nTabTop = (pTab->*fnRect->fnGetPrtTop)();
    2658           6 :         const long nKey = (*fnRect->fnYDiff)( (*aIter).first, nTabTop );
    2659           6 :         const std::pair< long, long > aTmpPair = (*aIter).second;
    2660           6 :         const long nFirst = (*fnRect->fnYDiff)( aTmpPair.first, nTabTop );
    2661           6 :         const long nSecond = aTmpPair.second;
    2662             : 
    2663           6 :         aHiddenIter = aHidden.find( (*aIter).first );
    2664           6 :         const bool bHidden = aHiddenIter != aHidden.end() && (*aHiddenIter).second;
    2665           6 :         rFill.Insert( nKey, nFirst, nSecond, bHidden, nIdx++ );
    2666             :     }
    2667             : 
    2668             :     // delete first and last entry
    2669             :     OSL_ENSURE( rFill.Count(), "Deleting from empty vector. Fasten your seatbelts!" );
    2670             :     // #i60818# There may be only one entry in rFill. Make
    2671             :     // code robust by checking count of rFill.
    2672           2 :     if ( rFill.Count() ) rFill.Remove( 0, 1 );
    2673           2 :     if ( rFill.Count() ) rFill.Remove( rFill.Count() - 1 , 1 );
    2674           4 :     rFill.SetLastRowAllowedToChange( !pTab->HasFollowFlowLine() );
    2675             : }
    2676             : 
    2677           0 : void SwDoc::SetTabCols( const SwTabCols &rNew, bool bCurRowOnly,
    2678             :                         const SwCursor* pCrsr, const SwCellFrm* pBoxFrm )
    2679             : {
    2680           0 :     const SwTableBox* pBox = 0;
    2681           0 :     SwTabFrm *pTab = 0;
    2682             : 
    2683           0 :     if( pBoxFrm )
    2684             :     {
    2685           0 :         pTab = ((SwFrm*)pBoxFrm)->ImplFindTabFrm();
    2686           0 :         pBox = pBoxFrm->GetTabBox();
    2687             :     }
    2688           0 :     else if( pCrsr )
    2689             :     {
    2690           0 :         const SwCntntNode* pCNd = pCrsr->GetCntntNode();
    2691           0 :         if( !pCNd )
    2692           0 :             return ;
    2693             : 
    2694           0 :         Point aPt;
    2695           0 :         const SwShellCrsr *pShCrsr = dynamic_cast<const SwShellCrsr*>(pCrsr);
    2696           0 :         if( pShCrsr )
    2697           0 :             aPt = pShCrsr->GetPtPos();
    2698             : 
    2699           0 :         const SwFrm* pTmpFrm = pCNd->getLayoutFrm( pCNd->GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout(), &aPt, 0, false );
    2700           0 :         do {
    2701           0 :             pTmpFrm = pTmpFrm->GetUpper();
    2702           0 :         } while ( !pTmpFrm->IsCellFrm() );
    2703             : 
    2704           0 :         pBoxFrm = (SwCellFrm*)pTmpFrm;
    2705           0 :         pTab = ((SwFrm*)pBoxFrm)->ImplFindTabFrm();
    2706           0 :         pBox = pBoxFrm->GetTabBox();
    2707             :     }
    2708           0 :     else if( !pCrsr && !pBoxFrm )
    2709             :     {
    2710             :         OSL_ENSURE( false, "One of them needs to be specified!" );
    2711           0 :         return ;
    2712             :     }
    2713             : 
    2714             :     // If the Table is still using relative values (USHRT_MAX)
    2715             :     // we need to switch to absolute ones.
    2716           0 :     SwTable& rTab = *pTab->GetTable();
    2717           0 :     const SwFmtFrmSize& rTblFrmSz = rTab.GetFrmFmt()->GetFrmSize();
    2718           0 :     SWRECTFN( pTab )
    2719             :     // #i17174# - With fix for #i9040# the shadow size is taken
    2720             :     // from the table width. Thus, add its left and right size to current table
    2721             :     // printing area width in order to get the correct table size attribute.
    2722           0 :     SwTwips nPrtWidth = (pTab->Prt().*fnRect->fnGetWidth)();
    2723             :     {
    2724           0 :         SvxShadowItem aShadow( rTab.GetFrmFmt()->GetShadow() );
    2725           0 :         nPrtWidth += aShadow.CalcShadowSpace( SHADOW_LEFT ) +
    2726           0 :                      aShadow.CalcShadowSpace( SHADOW_RIGHT );
    2727             :     }
    2728           0 :     if( nPrtWidth != rTblFrmSz.GetWidth() )
    2729             :     {
    2730           0 :         SwFmtFrmSize aSz( rTblFrmSz );
    2731           0 :         aSz.SetWidth( nPrtWidth );
    2732           0 :         rTab.GetFrmFmt()->SetFmtAttr( aSz );
    2733             :     }
    2734             : 
    2735           0 :     SwTabCols aOld( rNew.Count() );
    2736             : 
    2737           0 :     const SwPageFrm* pPage = pTab->FindPageFrm();
    2738           0 :     const sal_uLong nLeftMin = (pTab->Frm().*fnRect->fnGetLeft)() -
    2739           0 :                            (pPage->Frm().*fnRect->fnGetLeft)();
    2740           0 :     const sal_uLong nRightMax = (pTab->Frm().*fnRect->fnGetRight)() -
    2741           0 :                             (pPage->Frm().*fnRect->fnGetLeft)();
    2742             : 
    2743             :     // Set fixed points, LeftMin in Document coordinates, all others relative
    2744           0 :     aOld.SetLeftMin ( nLeftMin );
    2745           0 :     aOld.SetLeft    ( (pTab->Prt().*fnRect->fnGetLeft)() );
    2746           0 :     aOld.SetRight   ( (pTab->Prt().*fnRect->fnGetRight)());
    2747           0 :     aOld.SetRightMax( nRightMax - nLeftMin );
    2748             : 
    2749           0 :     rTab.GetTabCols( aOld, pBox );
    2750           0 :     SetTabCols(rTab, rNew, aOld, pBox, bCurRowOnly );
    2751             : }
    2752             : 
    2753           0 : void SwDoc::SetTabRows( const SwTabCols &rNew, bool bCurColOnly, const SwCursor*,
    2754             :                         const SwCellFrm* pBoxFrm )
    2755             : {
    2756             :     SwTabFrm *pTab;
    2757             : 
    2758             :     OSL_ENSURE( pBoxFrm, "SetTabRows called without pBoxFrm" );
    2759             : 
    2760           0 :     pTab = ((SwFrm*)pBoxFrm)->ImplFindTabFrm();
    2761             : 
    2762             :     // If the Table is still using relative values (USHRT_MAX)
    2763             :     // we need to switch to absolute ones.
    2764           0 :     SWRECTFN( pTab )
    2765           0 :     SwTabCols aOld( rNew.Count() );
    2766             : 
    2767             :     // Set fixed points, LeftMin in Document coordinates, all others relative
    2768           0 :     const SwPageFrm* pPage = pTab->FindPageFrm();
    2769             : 
    2770           0 :     aOld.SetRight( (pTab->Prt().*fnRect->fnGetHeight)() );
    2771             :     long nLeftMin;
    2772           0 :     if ( bVert )
    2773             :     {
    2774           0 :         nLeftMin = pTab->GetPrtLeft() - pPage->Frm().Left();
    2775           0 :         aOld.SetLeft    ( LONG_MAX );
    2776           0 :         aOld.SetRightMax( aOld.GetRight() );
    2777             : 
    2778             :     }
    2779             :     else
    2780             :     {
    2781           0 :         nLeftMin = pTab->GetPrtTop() - pPage->Frm().Top();
    2782           0 :         aOld.SetLeft    ( 0 );
    2783           0 :         aOld.SetRightMax( LONG_MAX );
    2784             :     }
    2785           0 :     aOld.SetLeftMin ( nLeftMin );
    2786             : 
    2787           0 :     GetTabRows( aOld, 0, pBoxFrm );
    2788             : 
    2789           0 :     GetIDocumentUndoRedo().StartUndo( UNDO_TABLE_ATTR, NULL );
    2790             : 
    2791             :     // check for differences between aOld and rNew:
    2792           0 :     const size_t nCount = rNew.Count();
    2793           0 :     const SwTable* pTable = pTab->GetTable();
    2794             :     OSL_ENSURE( pTable, "My colleague told me, this couldn't happen" );
    2795             : 
    2796           0 :     for ( size_t i = 0; i <= nCount; ++i )
    2797             :     {
    2798           0 :         const size_t nIdxStt = bVert ? nCount - i : i - 1;
    2799           0 :         const size_t nIdxEnd = bVert ? nCount - i - 1 : i;
    2800             : 
    2801           0 :         const long nOldRowStart = i == 0  ? 0 : aOld[ nIdxStt ];
    2802           0 :         const long nOldRowEnd =   i == nCount ? aOld.GetRight() : aOld[ nIdxEnd ];
    2803           0 :         const long nOldRowHeight = nOldRowEnd - nOldRowStart;
    2804             : 
    2805           0 :         const long nNewRowStart = i == 0  ? 0 : rNew[ nIdxStt ];
    2806           0 :         const long nNewRowEnd =   i == nCount ? rNew.GetRight() : rNew[ nIdxEnd ];
    2807           0 :         const long nNewRowHeight = nNewRowEnd - nNewRowStart;
    2808             : 
    2809           0 :         const long nDiff = nNewRowHeight - nOldRowHeight;
    2810           0 :         if ( std::abs( nDiff ) >= ROWFUZZY )
    2811             :         {
    2812             :             // For the old table model pTxtFrm and pLine will be set for every box.
    2813             :             // For the new table model pTxtFrm will be set if the box is not covered,
    2814             :             // but the pLine will be set if the box is not an overlapping box
    2815             :             // In the new table model the row height can be adjusted,
    2816             :             // when both variables are set.
    2817           0 :             SwTxtFrm* pTxtFrm = 0;
    2818           0 :             const SwTableLine* pLine = 0;
    2819             : 
    2820             :             // Iterate over all SwCellFrms with Bottom = nOldPos
    2821           0 :             const SwFrm* pFrm = pTab->GetNextLayoutLeaf();
    2822           0 :             while ( pFrm && pTab->IsAnLower( pFrm ) )
    2823             :             {
    2824           0 :                 if ( pFrm->IsCellFrm() && pFrm->FindTabFrm() == pTab )
    2825             :                 {
    2826           0 :                     const long nLowerBorder = (pFrm->Frm().*fnRect->fnGetBottom)();
    2827           0 :                     const sal_uLong nTabTop = (pTab->*fnRect->fnGetPrtTop)();
    2828           0 :                     if ( std::abs( (*fnRect->fnYInc)( nTabTop, nOldRowEnd ) - nLowerBorder ) <= ROWFUZZY )
    2829             :                     {
    2830           0 :                         if ( !bCurColOnly || pFrm == pBoxFrm )
    2831             :                         {
    2832           0 :                             const SwFrm* pCntnt = ::GetCellCntnt( static_cast<const SwCellFrm&>(*pFrm) );
    2833             : 
    2834           0 :                             if ( pCntnt && pCntnt->IsTxtFrm() )
    2835             :                             {
    2836           0 :                                 const SwTableBox* pBox = ((SwCellFrm*)pFrm)->GetTabBox();
    2837           0 :                                 const long nRowSpan = pBox->getRowSpan();
    2838           0 :                                 if( nRowSpan > 0 ) // Not overlapped
    2839           0 :                                     pTxtFrm = (SwTxtFrm*)pCntnt;
    2840           0 :                                 if( nRowSpan < 2 ) // Not overlapping for row height
    2841           0 :                                     pLine = pBox->GetUpper();
    2842           0 :                                 if( pLine && pTxtFrm ) // always for old table model
    2843             :                                 {
    2844             :                                     // The new row height must not to be calculated from a overlapping box
    2845           0 :                                     SwFmtFrmSize aNew( pLine->GetFrmFmt()->GetFrmSize() );
    2846           0 :                                     const long nNewSize = (pFrm->Frm().*fnRect->fnGetHeight)() + nDiff;
    2847           0 :                                     if( nNewSize != aNew.GetHeight() )
    2848             :                                     {
    2849           0 :                                         aNew.SetHeight( nNewSize );
    2850           0 :                                         if ( ATT_VAR_SIZE == aNew.GetHeightSizeType() )
    2851           0 :                                             aNew.SetHeightSizeType( ATT_MIN_SIZE );
    2852             :                                         // This position must not be in an overlapped box
    2853           0 :                                         const SwPosition aPos( *((SwTxtFrm*)pCntnt)->GetTxtNode() );
    2854           0 :                                         const SwCursor aTmpCrsr( aPos, 0, false );
    2855           0 :                                         SetRowHeight( aTmpCrsr, aNew );
    2856             :                                         // For the new table model we're done, for the old one
    2857             :                                         // there might be another (sub)row to adjust...
    2858           0 :                                         if( pTable->IsNewModel() )
    2859           0 :                                             break;
    2860             :                                     }
    2861           0 :                                     pLine = 0;
    2862             :                                 }
    2863             :                             }
    2864             :                         }
    2865             :                     }
    2866             :                 }
    2867           0 :                 pFrm = pFrm->GetNextLayoutLeaf();
    2868             :             }
    2869             :         }
    2870             :     }
    2871             : 
    2872           0 :     GetIDocumentUndoRedo().EndUndo( UNDO_TABLE_ATTR, NULL );
    2873             : 
    2874           0 :     ::ClearFEShellTabCols();
    2875           0 : }
    2876             : 
    2877             : /**
    2878             :  * Direct access for UNO
    2879             :  */
    2880        4600 : void SwDoc::SetTabCols(SwTable& rTab, const SwTabCols &rNew, const SwTabCols &rOld,
    2881             :                                 const SwTableBox *pStart, bool bCurRowOnly )
    2882             : {
    2883        4600 :     if (GetIDocumentUndoRedo().DoesUndo())
    2884             :     {
    2885           0 :         GetIDocumentUndoRedo().AppendUndo(
    2886           0 :             new SwUndoAttrTbl( *rTab.GetTableNode(), true ));
    2887             :     }
    2888        4600 :     rTab.SetTabCols( rNew, rOld, pStart, bCurRowOnly );
    2889        4600 :       ::ClearFEShellTabCols();
    2890        4600 :     getIDocumentState().SetModified();
    2891        4600 : }
    2892             : 
    2893        1064 : void SwDoc::SetRowsToRepeat( SwTable &rTable, sal_uInt16 nSet )
    2894             : {
    2895        1064 :     if( nSet == rTable.GetRowsToRepeat() )
    2896        1064 :         return;
    2897             : 
    2898        1064 :     if (GetIDocumentUndoRedo().DoesUndo())
    2899             :     {
    2900           2 :         GetIDocumentUndoRedo().AppendUndo(
    2901           2 :             new SwUndoTblHeadline(rTable, rTable.GetRowsToRepeat(), nSet) );
    2902             :     }
    2903             : 
    2904        1064 :     SwMsgPoolItem aChg( RES_TBLHEADLINECHG );
    2905        1064 :     rTable.SetRowsToRepeat( nSet );
    2906        1064 :     rTable.GetFrmFmt()->ModifyNotification( &aChg, &aChg );
    2907        1064 :     getIDocumentState().SetModified();
    2908             : }
    2909             : 
    2910           0 : void SwCollectTblLineBoxes::AddToUndoHistory( const SwCntntNode& rNd )
    2911             : {
    2912           0 :     if( pHst )
    2913           0 :         pHst->Add( rNd.GetFmtColl(), rNd.GetIndex(), ND_TEXTNODE );
    2914           0 : }
    2915             : 
    2916           0 : void SwCollectTblLineBoxes::AddBox( const SwTableBox& rBox )
    2917             : {
    2918           0 :     aPosArr.push_back(nWidth);
    2919           0 :     SwTableBox* p = (SwTableBox*)&rBox;
    2920           0 :     m_Boxes.push_back(p);
    2921           0 :     nWidth = nWidth + (sal_uInt16)rBox.GetFrmFmt()->GetFrmSize().GetWidth();
    2922           0 : }
    2923             : 
    2924           0 : const SwTableBox* SwCollectTblLineBoxes::GetBoxOfPos( const SwTableBox& rBox )
    2925             : {
    2926           0 :     const SwTableBox* pRet = 0;
    2927             :     sal_uInt16 n;
    2928             : 
    2929           0 :     if( !aPosArr.empty() )
    2930             :     {
    2931           0 :         for( n = 0; n < aPosArr.size(); ++n )
    2932           0 :             if( aPosArr[ n ] == nWidth )
    2933           0 :                 break;
    2934           0 :             else if( aPosArr[ n ] > nWidth )
    2935             :             {
    2936           0 :                 if( n )
    2937           0 :                     --n;
    2938           0 :                 break;
    2939             :             }
    2940             : 
    2941           0 :         if( n >= aPosArr.size() )
    2942           0 :             --n;
    2943             : 
    2944           0 :         nWidth = nWidth + (sal_uInt16)rBox.GetFrmFmt()->GetFrmSize().GetWidth();
    2945           0 :         pRet = m_Boxes[ n ];
    2946             :     }
    2947           0 :     return pRet;
    2948             : }
    2949             : 
    2950           0 : bool SwCollectTblLineBoxes::Resize( sal_uInt16 nOffset, sal_uInt16 nOldWidth )
    2951             : {
    2952             :     size_t n;
    2953             : 
    2954           0 :     if( !aPosArr.empty() )
    2955             :     {
    2956           0 :         for( n = 0; n < aPosArr.size(); ++n )
    2957             :         {
    2958           0 :             if( aPosArr[ n ] == nOffset )
    2959           0 :                 break;
    2960           0 :             else if( aPosArr[ n ] > nOffset )
    2961             :             {
    2962           0 :                 if( n )
    2963           0 :                     --n;
    2964           0 :                 break;
    2965             :             }
    2966             :         }
    2967             : 
    2968           0 :         aPosArr.erase( aPosArr.begin(), aPosArr.begin() + n );
    2969           0 :         m_Boxes.erase(m_Boxes.begin(), m_Boxes.begin() + n);
    2970             : 
    2971           0 :         size_t nArrSize = aPosArr.size();
    2972           0 :         if (nArrSize)
    2973             :         {
    2974           0 :             if (nOldWidth == 0)
    2975           0 :                 throw o3tl::divide_by_zero();
    2976             : 
    2977             :             // Adapt the positions to the new Size
    2978           0 :             for( n = 0; n < nArrSize; ++n )
    2979             :             {
    2980           0 :                 sal_uLong nSize = nWidth;
    2981           0 :                 nSize *= ( aPosArr[ n ] - nOffset );
    2982           0 :                 nSize /= nOldWidth;
    2983           0 :                 aPosArr[ n ] = sal_uInt16( nSize );
    2984             :             }
    2985             :         }
    2986             :     }
    2987           0 :     return !aPosArr.empty();
    2988             : }
    2989             : 
    2990           0 : bool sw_Line_CollectBox( const SwTableLine*& rpLine, void* pPara )
    2991             : {
    2992           0 :     SwCollectTblLineBoxes* pSplPara = (SwCollectTblLineBoxes*)pPara;
    2993           0 :     if( pSplPara->IsGetValues() )
    2994           0 :         for( SwTableBoxes::iterator it = ((SwTableLine*)rpLine)->GetTabBoxes().begin();
    2995           0 :                  it != ((SwTableLine*)rpLine)->GetTabBoxes().end(); ++it)
    2996           0 :             sw_Box_CollectBox(*it, pSplPara );
    2997             :     else
    2998           0 :         for( SwTableBoxes::iterator it = ((SwTableLine*)rpLine)->GetTabBoxes().begin();
    2999           0 :                  it != ((SwTableLine*)rpLine)->GetTabBoxes().end(); ++it)
    3000           0 :             sw_BoxSetSplitBoxFmts(*it, pSplPara );
    3001           0 :     return true;
    3002             : }
    3003             : 
    3004           0 : void sw_Box_CollectBox( const SwTableBox* pBox, SwCollectTblLineBoxes* pSplPara )
    3005             : {
    3006           0 :     sal_uInt16 nLen = pBox->GetTabLines().size();
    3007           0 :     if( nLen )
    3008             :     {
    3009             :         // Continue with the actual Line
    3010           0 :         if( pSplPara->IsGetFromTop() )
    3011           0 :             nLen = 0;
    3012             :         else
    3013           0 :             --nLen;
    3014             : 
    3015           0 :         const SwTableLine* pLn = pBox->GetTabLines()[ nLen ];
    3016           0 :         sw_Line_CollectBox( pLn, pSplPara );
    3017             :     }
    3018             :     else
    3019           0 :         pSplPara->AddBox( *pBox );
    3020           0 : }
    3021             : 
    3022           0 : void sw_BoxSetSplitBoxFmts( SwTableBox* pBox, SwCollectTblLineBoxes* pSplPara )
    3023             : {
    3024           0 :     sal_uInt16 nLen = pBox->GetTabLines().size();
    3025           0 :     if( nLen )
    3026             :     {
    3027             :         // Continue with the actual Line
    3028           0 :         if( pSplPara->IsGetFromTop() )
    3029           0 :             nLen = 0;
    3030             :         else
    3031           0 :             --nLen;
    3032             : 
    3033           0 :         const SwTableLine* pLn = pBox->GetTabLines()[ nLen ];
    3034           0 :         sw_Line_CollectBox( pLn, pSplPara );
    3035             :     }
    3036             :     else
    3037             :     {
    3038           0 :         const SwTableBox* pSrcBox = pSplPara->GetBoxOfPos( *pBox );
    3039           0 :         SwFrmFmt* pFmt = pSrcBox->GetFrmFmt();
    3040             : 
    3041           0 :         if( HEADLINE_BORDERCOPY == pSplPara->GetMode() )
    3042             :         {
    3043           0 :             const SvxBoxItem& rBoxItem = pBox->GetFrmFmt()->GetBox();
    3044           0 :             if( !rBoxItem.GetTop() )
    3045             :             {
    3046           0 :                 SvxBoxItem aNew( rBoxItem );
    3047           0 :                 aNew.SetLine( pFmt->GetBox().GetBottom(), BOX_LINE_TOP );
    3048           0 :                 if( aNew != rBoxItem )
    3049           0 :                     pBox->ClaimFrmFmt()->SetFmtAttr( aNew );
    3050             :             }
    3051             :         }
    3052             :         else
    3053             :         {
    3054             : sal_uInt16 aTableSplitBoxSetRange[] = {
    3055             :     RES_LR_SPACE,       RES_UL_SPACE,
    3056             :     RES_BACKGROUND,     RES_SHADOW,
    3057             :     RES_PROTECT,        RES_PROTECT,
    3058             :     RES_VERT_ORIENT,    RES_VERT_ORIENT,
    3059           0 :     0 };
    3060             : 
    3061           0 :             SfxItemSet aTmpSet( pFmt->GetDoc()->GetAttrPool(),
    3062           0 :                                 aTableSplitBoxSetRange );
    3063           0 :             aTmpSet.Put( pFmt->GetAttrSet() );
    3064           0 :             if( aTmpSet.Count() )
    3065           0 :                 pBox->ClaimFrmFmt()->SetFmtAttr( aTmpSet );
    3066             : 
    3067           0 :             if( HEADLINE_BOXATRCOLLCOPY == pSplPara->GetMode() )
    3068             :             {
    3069           0 :                 SwNodeIndex aIdx( *pSrcBox->GetSttNd(), 1 );
    3070           0 :                 SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
    3071           0 :                 if( !pCNd )
    3072           0 :                     pCNd = aIdx.GetNodes().GoNext( &aIdx );
    3073           0 :                 aIdx = *pBox->GetSttNd();
    3074           0 :                 SwCntntNode* pDNd = aIdx.GetNodes().GoNext( &aIdx );
    3075             : 
    3076             :                 // If the Node is alone in the Section
    3077           0 :                 if( 2 == pDNd->EndOfSectionIndex() -
    3078           0 :                         pDNd->StartOfSectionIndex() )
    3079             :                 {
    3080           0 :                     pSplPara->AddToUndoHistory( *pDNd );
    3081           0 :                     pDNd->ChgFmtColl( pCNd->GetFmtColl() );
    3082           0 :                 }
    3083             :             }
    3084             : 
    3085             :             // note conditional template
    3086           0 :             pBox->GetSttNd()->CheckSectionCondColl();
    3087             :         }
    3088             :     }
    3089           0 : }
    3090             : 
    3091             : /**
    3092             :  * Splits a Table in the top-level Line which contains the Index.
    3093             :  * All succeeding top-level Lines go into a new Table/Node.
    3094             :  *
    3095             :  * @param bCalcNewSize true
    3096             :  *                     Calculate the new Size for both from the
    3097             :  *                     Boxes' Max; but only if Size is using absolute
    3098             :  *                     values (USHRT_MAX)
    3099             :  */
    3100           0 : bool SwDoc::SplitTable( const SwPosition& rPos, sal_uInt16 eHdlnMode,
    3101             :                         bool bCalcNewSize )
    3102             : {
    3103           0 :     SwNode* pNd = &rPos.nNode.GetNode();
    3104           0 :     SwTableNode* pTNd = pNd->FindTableNode();
    3105           0 :     if( !pTNd || pNd->IsTableNode() )
    3106           0 :         return false;
    3107             : 
    3108           0 :     if( pTNd->GetTable().ISA( SwDDETable ))
    3109           0 :         return false;
    3110             : 
    3111           0 :     SwTable& rTbl = pTNd->GetTable();
    3112           0 :     rTbl.SetHTMLTableLayout( 0 ); // Delete HTML Layout
    3113             : 
    3114           0 :     SwTableFmlUpdate aMsgHnt( &rTbl );
    3115             : 
    3116           0 :     SwHistory aHistory;
    3117           0 :     if (GetIDocumentUndoRedo().DoesUndo())
    3118             :     {
    3119           0 :         aMsgHnt.pHistory = &aHistory;
    3120             :     }
    3121             : 
    3122             :     {
    3123           0 :         sal_uLong nSttIdx = pNd->FindTableBoxStartNode()->GetIndex();
    3124             : 
    3125             :         // Find top-level Line
    3126           0 :         SwTableBox* pBox = rTbl.GetTblBox( nSttIdx );
    3127           0 :         if( pBox )
    3128             :         {
    3129           0 :             SwTableLine* pLine = pBox->GetUpper();
    3130           0 :             while( pLine->GetUpper() )
    3131           0 :                 pLine = pLine->GetUpper()->GetUpper();
    3132             : 
    3133             :             // pLine contains the top-level Line now
    3134           0 :             aMsgHnt.nSplitLine = rTbl.GetTabLines().GetPos( pLine );
    3135             :         }
    3136             : 
    3137           0 :         OUString sNewTblNm( GetUniqueTblName() );
    3138           0 :         aMsgHnt.DATA.pNewTblNm = &sNewTblNm;
    3139           0 :         aMsgHnt.eFlags = TBL_SPLITTBL;
    3140           0 :         getIDocumentFieldsAccess().UpdateTblFlds( &aMsgHnt );
    3141             :     }
    3142             : 
    3143             :     // Find Lines for the Layout update
    3144           0 :     _FndBox aFndBox( 0, 0 );
    3145           0 :     aFndBox.SetTableLines( rTbl );
    3146           0 :     aFndBox.DelFrms( rTbl );
    3147             : 
    3148           0 :     SwTableNode* pNew = GetNodes().SplitTable( rPos.nNode, false, bCalcNewSize );
    3149             : 
    3150           0 :     if( pNew )
    3151             :     {
    3152           0 :         SwSaveRowSpan* pSaveRowSp = pNew->GetTable().CleanUpTopRowSpan( rTbl.GetTabLines().size() );
    3153           0 :         SwUndoSplitTbl* pUndo = 0;
    3154           0 :         if (GetIDocumentUndoRedo().DoesUndo())
    3155             :         {
    3156             :             pUndo = new SwUndoSplitTbl(
    3157           0 :                         *pNew, pSaveRowSp, eHdlnMode, bCalcNewSize);
    3158           0 :             GetIDocumentUndoRedo().AppendUndo(pUndo);
    3159           0 :             if( aHistory.Count() )
    3160           0 :                 pUndo->SaveFormula( aHistory );
    3161             :         }
    3162             : 
    3163           0 :         switch( eHdlnMode )
    3164             :         {
    3165             :         // Set the lower Border of the preceeding Line to
    3166             :         // the upper Border of the current one
    3167             :         case HEADLINE_BORDERCOPY:
    3168             :             {
    3169           0 :                 SwCollectTblLineBoxes aPara( false, eHdlnMode );
    3170           0 :                 SwTableLine* pLn = rTbl.GetTabLines()[
    3171           0 :                             rTbl.GetTabLines().size() - 1 ];
    3172           0 :                 for( SwTableBoxes::iterator it = pLn->GetTabBoxes().begin();
    3173           0 :                          it != pLn->GetTabBoxes().end(); ++it)
    3174           0 :                     sw_Box_CollectBox(*it, &aPara );
    3175             : 
    3176           0 :                 aPara.SetValues( true );
    3177           0 :                 pLn = pNew->GetTable().GetTabLines()[ 0 ];
    3178           0 :                 for( SwTableBoxes::iterator it = pLn->GetTabBoxes().begin();
    3179           0 :                          it != pLn->GetTabBoxes().end(); ++it)
    3180           0 :                     sw_BoxSetSplitBoxFmts(*it, &aPara );
    3181             : 
    3182             :                 // Switch off repeating Header
    3183           0 :                 pNew->GetTable().SetRowsToRepeat( 0 );
    3184             :             }
    3185           0 :             break;
    3186             : 
    3187             :         // Take over the Attributes of the first Line to the new one
    3188             :         case HEADLINE_BOXATTRCOPY:
    3189             :         case HEADLINE_BOXATRCOLLCOPY:
    3190             :             {
    3191           0 :                 SwHistory* pHst = 0;
    3192           0 :                 if( HEADLINE_BOXATRCOLLCOPY == eHdlnMode && pUndo )
    3193           0 :                     pHst = pUndo->GetHistory();
    3194             : 
    3195           0 :                 SwCollectTblLineBoxes aPara( true, eHdlnMode, pHst );
    3196           0 :                 SwTableLine* pLn = rTbl.GetTabLines()[ 0 ];
    3197           0 :                 for( SwTableBoxes::iterator it = pLn->GetTabBoxes().begin();
    3198           0 :                          it != pLn->GetTabBoxes().end(); ++it)
    3199           0 :                     sw_Box_CollectBox(*it, &aPara );
    3200             : 
    3201           0 :                 aPara.SetValues( true );
    3202           0 :                 pLn = pNew->GetTable().GetTabLines()[ 0 ];
    3203           0 :                 for( SwTableBoxes::iterator it = pLn->GetTabBoxes().begin();
    3204           0 :                          it != pLn->GetTabBoxes().end(); ++it)
    3205           0 :                     sw_BoxSetSplitBoxFmts(*it, &aPara );
    3206             :             }
    3207           0 :             break;
    3208             : 
    3209             :         case HEADLINE_CNTNTCOPY:
    3210           0 :             rTbl.CopyHeadlineIntoTable( *pNew );
    3211           0 :             if( pUndo )
    3212           0 :                 pUndo->SetTblNodeOffset( pNew->GetIndex() );
    3213           0 :             break;
    3214             : 
    3215             :         case HEADLINE_NONE:
    3216             :             // Switch off repeating the Header
    3217           0 :             pNew->GetTable().SetRowsToRepeat( 0 );
    3218           0 :             break;
    3219             :         }
    3220             : 
    3221             :         // And insert Frms
    3222           0 :         SwNodeIndex aNdIdx( *pNew->EndOfSectionNode() );
    3223           0 :         GetNodes().GoNext( &aNdIdx ); // To the next ContentNode
    3224           0 :         pNew->MakeFrms( &aNdIdx );
    3225             : 
    3226             :         // Insert a paragraph between the Table
    3227           0 :         GetNodes().MakeTxtNode( SwNodeIndex( *pNew ),
    3228           0 :                                 getIDocumentStylePoolAccess().GetTxtCollFromPool( RES_POOLCOLL_TEXT ) );
    3229             :     }
    3230             : 
    3231             :     // Update Layout
    3232           0 :     aFndBox.MakeFrms( rTbl );
    3233             : 
    3234             :     // TL_CHART2: need to inform chart of probably changed cell names
    3235           0 :     UpdateCharts( rTbl.GetFrmFmt()->GetName() );
    3236             : 
    3237           0 :     getIDocumentFieldsAccess().SetFieldsDirty( true, NULL, 0 );
    3238             : 
    3239           0 :     return 0 != pNew;
    3240             : }
    3241             : 
    3242           0 : static bool lcl_ChgTblSize( SwTable& rTbl )
    3243             : {
    3244             :     // The Attribute must not be set via the Modify or else all Boxes are
    3245             :     // set back to 0.
    3246             :     // So lock the Format.
    3247           0 :     SwFrmFmt* pFmt = rTbl.GetFrmFmt();
    3248           0 :     SwFmtFrmSize aTblMaxSz( pFmt->GetFrmSize() );
    3249             : 
    3250           0 :     if( USHRT_MAX == aTblMaxSz.GetWidth() )
    3251           0 :         return false;
    3252             : 
    3253           0 :     bool bLocked = pFmt->IsModifyLocked();
    3254           0 :     pFmt->LockModify();
    3255             : 
    3256           0 :     aTblMaxSz.SetWidth( 0 );
    3257             : 
    3258           0 :     SwTableLines& rLns = rTbl.GetTabLines();
    3259           0 :     for( sal_uInt16 nLns = 0; nLns < rLns.size(); ++nLns )
    3260             :     {
    3261           0 :         SwTwips nMaxLnWidth = 0;
    3262           0 :         SwTableBoxes& rBoxes = rLns[ nLns ]->GetTabBoxes();
    3263           0 :         for( sal_uInt16 nBox = 0; nBox < rBoxes.size(); ++nBox )
    3264           0 :             nMaxLnWidth += rBoxes[nBox]->GetFrmFmt()->GetFrmSize().GetWidth();
    3265             : 
    3266           0 :         if( nMaxLnWidth > aTblMaxSz.GetWidth() )
    3267           0 :             aTblMaxSz.SetWidth( nMaxLnWidth );
    3268             :     }
    3269           0 :     pFmt->SetFmtAttr( aTblMaxSz );
    3270           0 :     if( !bLocked ) // Release the Lock if appropriate
    3271           0 :         pFmt->UnlockModify();
    3272             : 
    3273           0 :     return true;
    3274             : }
    3275             : 
    3276           0 : class _SplitTable_Para
    3277             : {
    3278             :     std::map<SwFrmFmt*, SwFrmFmt*> aSrcDestMap;
    3279             :     SwTableNode* pNewTblNd;
    3280             :     SwTable& rOldTbl;
    3281             : 
    3282             : public:
    3283           0 :     _SplitTable_Para( SwTableNode* pNew, SwTable& rOld )
    3284           0 :         : aSrcDestMap(), pNewTblNd( pNew ), rOldTbl( rOld )
    3285           0 :     {}
    3286           0 :     SwFrmFmt* GetDestFmt( SwFrmFmt* pSrcFmt ) const
    3287             :     {
    3288           0 :         std::map<SwFrmFmt*, SwFrmFmt*>::const_iterator it = aSrcDestMap.find( pSrcFmt );
    3289           0 :         return it == aSrcDestMap.end() ? NULL : it->second;
    3290             :     }
    3291             : 
    3292           0 :     void InsertSrcDest( SwFrmFmt* pSrcFmt, SwFrmFmt* pDestFmt )
    3293           0 :             { aSrcDestMap[ pSrcFmt ] = pDestFmt; }
    3294             : 
    3295           0 :     void ChgBox( SwTableBox* pBox )
    3296             :     {
    3297           0 :         rOldTbl.GetTabSortBoxes().erase( pBox );
    3298           0 :         pNewTblNd->GetTable().GetTabSortBoxes().insert( pBox );
    3299           0 :     }
    3300             : };
    3301             : 
    3302             : static void lcl_SplitTable_CpyBox( SwTableBox* pBox, _SplitTable_Para* pPara );
    3303             : 
    3304           0 : static void lcl_SplitTable_CpyLine( SwTableLine* pLn, _SplitTable_Para* pPara )
    3305             : {
    3306           0 :     SwFrmFmt *pSrcFmt = pLn->GetFrmFmt();
    3307           0 :     SwTableLineFmt* pDestFmt = (SwTableLineFmt*) pPara->GetDestFmt( pSrcFmt );
    3308           0 :     if( pDestFmt == NULL )
    3309             :     {
    3310           0 :         pPara->InsertSrcDest( pSrcFmt, pLn->ClaimFrmFmt() );
    3311             :     }
    3312             :     else
    3313           0 :         pLn->ChgFrmFmt( pDestFmt );
    3314             : 
    3315           0 :     for( SwTableBoxes::iterator it = pLn->GetTabBoxes().begin();
    3316           0 :              it != pLn->GetTabBoxes().end(); ++it)
    3317           0 :         lcl_SplitTable_CpyBox(*it, pPara );
    3318           0 : }
    3319             : 
    3320           0 : static void lcl_SplitTable_CpyBox( SwTableBox* pBox, _SplitTable_Para* pPara )
    3321             : {
    3322           0 :     SwFrmFmt *pSrcFmt = pBox->GetFrmFmt();
    3323           0 :     SwTableBoxFmt* pDestFmt = (SwTableBoxFmt*)pPara->GetDestFmt( pSrcFmt );
    3324           0 :     if( pDestFmt == NULL )
    3325             :     {
    3326           0 :         pPara->InsertSrcDest( pSrcFmt, pBox->ClaimFrmFmt() );
    3327             :     }
    3328             :     else
    3329           0 :         pBox->ChgFrmFmt( pDestFmt );
    3330             : 
    3331           0 :     if( pBox->GetSttNd() )
    3332           0 :         pPara->ChgBox( pBox );
    3333             :     else
    3334           0 :         BOOST_FOREACH( SwTableLine* pLine, pBox->GetTabLines() )
    3335           0 :             lcl_SplitTable_CpyLine( pLine, pPara );
    3336           0 : }
    3337             : 
    3338           0 : SwTableNode* SwNodes::SplitTable( const SwNodeIndex& rPos, bool bAfter,
    3339             :                                     bool bCalcNewSize )
    3340             : {
    3341           0 :     SwNode* pNd = &rPos.GetNode();
    3342           0 :     SwTableNode* pTNd = pNd->FindTableNode();
    3343           0 :     if( !pTNd || pNd->IsTableNode() )
    3344           0 :         return 0;
    3345             : 
    3346           0 :     sal_uLong nSttIdx = pNd->FindTableBoxStartNode()->GetIndex();
    3347             : 
    3348             :     // Find this Box/top-level line
    3349           0 :     SwTable& rTbl = pTNd->GetTable();
    3350           0 :     SwTableBox* pBox = rTbl.GetTblBox( nSttIdx );
    3351           0 :     if( !pBox )
    3352           0 :         return 0;
    3353             : 
    3354           0 :     SwTableLine* pLine = pBox->GetUpper();
    3355           0 :     while( pLine->GetUpper() )
    3356           0 :         pLine = pLine->GetUpper()->GetUpper();
    3357             : 
    3358             :     // pLine now contains the top-level line
    3359           0 :     sal_uInt16 nLinePos = rTbl.GetTabLines().GetPos( pLine );
    3360           0 :     if( USHRT_MAX == nLinePos ||
    3361           0 :         ( bAfter ? ++nLinePos >= rTbl.GetTabLines().size() : !nLinePos ))
    3362           0 :         return 0; // Not found or last Line!
    3363             : 
    3364             :     // Find the first Box of the succeeding Line
    3365           0 :     SwTableLine* pNextLine = rTbl.GetTabLines()[ nLinePos ];
    3366           0 :     pBox = pNextLine->GetTabBoxes()[0];
    3367           0 :     while( !pBox->GetSttNd() )
    3368           0 :         pBox = pBox->GetTabLines()[0]->GetTabBoxes()[0];
    3369             : 
    3370             :     // Insert an EndNode and TableNode into the Nodes Array
    3371             :     SwTableNode * pNewTblNd;
    3372             :     {
    3373           0 :         SwEndNode* pOldTblEndNd = (SwEndNode*)pTNd->EndOfSectionNode()->GetEndNode();
    3374             :         OSL_ENSURE( pOldTblEndNd, "Where is the EndNode?" );
    3375             : 
    3376           0 :         SwNodeIndex aIdx( *pBox->GetSttNd() );
    3377           0 :         new SwEndNode( aIdx, *pTNd );
    3378           0 :         pNewTblNd = new SwTableNode( aIdx );
    3379           0 :         pNewTblNd->GetTable().SetTableModel( rTbl.IsNewModel() );
    3380             : 
    3381           0 :         pOldTblEndNd->pStartOfSection = pNewTblNd;
    3382           0 :         pNewTblNd->pEndOfSection = pOldTblEndNd;
    3383             : 
    3384           0 :         SwNode* pBoxNd = aIdx.GetNode().GetStartNode();
    3385           0 :         do {
    3386             :             OSL_ENSURE( pBoxNd->IsStartNode(), "This needs to be a StartNode!" );
    3387           0 :             pBoxNd->pStartOfSection = pNewTblNd;
    3388           0 :             pBoxNd = (*this)[ pBoxNd->EndOfSectionIndex() + 1 ];
    3389           0 :         } while( pBoxNd != pOldTblEndNd );
    3390             :     }
    3391             : 
    3392             :     {
    3393             :         // Move the Lines
    3394           0 :         SwTable& rNewTbl = pNewTblNd->GetTable();
    3395           0 :         rNewTbl.GetTabLines().insert( rNewTbl.GetTabLines().begin(),
    3396           0 :                       rTbl.GetTabLines().begin() + nLinePos, rTbl.GetTabLines().end() );
    3397             : 
    3398             :         /* From the back (bottom right) to the front (top left) deregister all Boxes from the
    3399             :            Chart Data Provider. The Modify event is triggered in the calling function.
    3400             :          TL_CHART2: */
    3401           0 :         SwChartDataProvider *pPCD = rTbl.GetFrmFmt()->getIDocumentChartDataProviderAccess()->GetChartDataProvider();
    3402           0 :         if( pPCD )
    3403             :         {
    3404           0 :             for (sal_uInt16 k = nLinePos;  k < rTbl.GetTabLines().size();  ++k)
    3405             :             {
    3406           0 :                 sal_uInt16 nLineIdx = (rTbl.GetTabLines().size() - 1) - k + nLinePos;
    3407           0 :                 sal_uInt16 nBoxCnt = rTbl.GetTabLines()[ nLineIdx ]->GetTabBoxes().size();
    3408           0 :                 for (sal_uInt16 j = 0;  j < nBoxCnt;  ++j)
    3409             :                 {
    3410           0 :                     sal_uInt16 nIdx = nBoxCnt - 1 - j;
    3411           0 :                     pPCD->DeleteBox( &rTbl, *rTbl.GetTabLines()[ nLineIdx ]->GetTabBoxes()[nIdx] );
    3412             :                 }
    3413             :             }
    3414             :         }
    3415             : 
    3416             :         // Delete
    3417           0 :         sal_uInt16 nDeleted = rTbl.GetTabLines().size() - nLinePos;
    3418           0 :         rTbl.GetTabLines().erase( rTbl.GetTabLines().begin() + nLinePos, rTbl.GetTabLines().end() );
    3419             : 
    3420             :         // Move the affected Boxes. Make the Formats unique and correct the StartNodes
    3421           0 :         _SplitTable_Para aPara( pNewTblNd, rTbl );
    3422           0 :         BOOST_FOREACH( SwTableLine* pNewLine, rNewTbl.GetTabLines() )
    3423           0 :             lcl_SplitTable_CpyLine( pNewLine, &aPara );
    3424           0 :         rTbl.CleanUpBottomRowSpan( nDeleted );
    3425             :     }
    3426             : 
    3427             :     {
    3428             :         // Copy the Table FrmFormat
    3429           0 :         SwFrmFmt* pOldTblFmt = rTbl.GetFrmFmt();
    3430             :         SwFrmFmt* pNewTblFmt = pOldTblFmt->GetDoc()->MakeTblFrmFmt(
    3431             :                                 pOldTblFmt->GetDoc()->GetUniqueTblName(),
    3432           0 :                                 pOldTblFmt->GetDoc()->GetDfltFrmFmt() );
    3433             : 
    3434           0 :         *pNewTblFmt = *pOldTblFmt;
    3435           0 :         pNewTblNd->GetTable().RegisterToFormat( *pNewTblFmt );
    3436             : 
    3437             :         // Calculate a new Size?
    3438             :         // lcl_ChgTblSize: Only execute the second call if the first call was
    3439             :         // successful, thus has an absolute Size
    3440           0 :         if( bCalcNewSize && lcl_ChgTblSize( rTbl ) )
    3441           0 :             lcl_ChgTblSize( pNewTblNd->GetTable() );
    3442             :     }
    3443             : 
    3444             :     // TL_CHART2: need to inform chart of probably changed cell names
    3445           0 :     rTbl.UpdateCharts();
    3446             : 
    3447           0 :     return pNewTblNd; // That's it!
    3448             : }
    3449             : 
    3450             : /**
    3451             :  * rPos needs to be in the Table that remains
    3452             :  *
    3453             :  * @param bWithPrev  merge the current Table with the preceeding
    3454             :  *                   or succeeding one
    3455             :  */
    3456           0 : bool SwDoc::MergeTable( const SwPosition& rPos, bool bWithPrev, sal_uInt16 nMode )
    3457             : {
    3458           0 :     SwTableNode* pTblNd = rPos.nNode.GetNode().FindTableNode(), *pDelTblNd;
    3459           0 :     if( !pTblNd )
    3460           0 :         return false;
    3461             : 
    3462           0 :     SwNodes& rNds = GetNodes();
    3463           0 :     if( bWithPrev )
    3464           0 :         pDelTblNd = rNds[ pTblNd->GetIndex() - 1 ]->FindTableNode();
    3465             :     else
    3466           0 :         pDelTblNd = rNds[ pTblNd->EndOfSectionIndex() + 1 ]->GetTableNode();
    3467           0 :     if( !pDelTblNd )
    3468           0 :         return false;
    3469             : 
    3470           0 :     if( pTblNd->GetTable().ISA( SwDDETable ) ||
    3471           0 :         pDelTblNd->GetTable().ISA( SwDDETable ))
    3472           0 :         return false;
    3473             : 
    3474             :     // Delete HTML Layout
    3475           0 :     pTblNd->GetTable().SetHTMLTableLayout( 0 );
    3476           0 :     pDelTblNd->GetTable().SetHTMLTableLayout( 0 );
    3477             : 
    3478             :     // Both Tables are present; we can start
    3479           0 :     SwUndoMergeTbl* pUndo = 0;
    3480           0 :     SwHistory* pHistory = 0;
    3481           0 :     if (GetIDocumentUndoRedo().DoesUndo())
    3482             :     {
    3483           0 :         pUndo = new SwUndoMergeTbl( *pTblNd, *pDelTblNd, bWithPrev, nMode );
    3484           0 :         GetIDocumentUndoRedo().AppendUndo(pUndo);
    3485           0 :         pHistory = new SwHistory;
    3486             :     }
    3487             : 
    3488             :     // Adapt all "TableFormulas"
    3489           0 :     SwTableFmlUpdate aMsgHnt( &pTblNd->GetTable() );
    3490           0 :     aMsgHnt.DATA.pDelTbl = &pDelTblNd->GetTable();
    3491           0 :     aMsgHnt.eFlags = TBL_MERGETBL;
    3492           0 :     aMsgHnt.pHistory = pHistory;
    3493           0 :     getIDocumentFieldsAccess().UpdateTblFlds( &aMsgHnt );
    3494             : 
    3495             :     // The actual merge
    3496           0 :     SwNodeIndex aIdx( bWithPrev ? *pTblNd : *pDelTblNd );
    3497           0 :     bool bRet = rNds.MergeTable( aIdx, !bWithPrev, nMode, pHistory );
    3498             : 
    3499           0 :     if( pHistory )
    3500             :     {
    3501           0 :         if( pHistory->Count() )
    3502           0 :             pUndo->SaveFormula( *pHistory );
    3503           0 :         delete pHistory;
    3504             :     }
    3505           0 :     if( bRet )
    3506             :     {
    3507           0 :         getIDocumentState().SetModified();
    3508           0 :         getIDocumentFieldsAccess().SetFieldsDirty( true, NULL, 0 );
    3509             :     }
    3510           0 :     return bRet;
    3511             : }
    3512             : 
    3513           0 : bool SwNodes::MergeTable( const SwNodeIndex& rPos, bool bWithPrev,
    3514             :                             sal_uInt16 nMode, SwHistory* )
    3515             : {
    3516           0 :     SwTableNode* pDelTblNd = rPos.GetNode().GetTableNode();
    3517             :     OSL_ENSURE( pDelTblNd, "Where did the TableNode go?" );
    3518             : 
    3519           0 :     SwTableNode* pTblNd = (*this)[ rPos.GetIndex() - 1]->FindTableNode();
    3520             :     OSL_ENSURE( pTblNd, "Where did the TableNode go?" );
    3521             : 
    3522           0 :     if( !pDelTblNd || !pTblNd )
    3523           0 :         return false;
    3524             : 
    3525           0 :     pDelTblNd->DelFrms();
    3526             : 
    3527           0 :     SwTable& rDelTbl = pDelTblNd->GetTable();
    3528           0 :     SwTable& rTbl = pTblNd->GetTable();
    3529             : 
    3530             :     // Find Lines for the Layout update
    3531           0 :     _FndBox aFndBox( 0, 0 );
    3532           0 :     aFndBox.SetTableLines( rTbl );
    3533           0 :     aFndBox.DelFrms( rTbl );
    3534             : 
    3535             :     // TL_CHART2:
    3536             :     // tell the charts about the table to be deleted and have them use their own data
    3537           0 :     GetDoc()->getIDocumentChartDataProviderAccess().CreateChartInternalDataProviders( &rDelTbl );
    3538             : 
    3539             :     // Sync the TableFormat's Width
    3540             :     {
    3541           0 :         const SwFmtFrmSize& rTblSz = rTbl.GetFrmFmt()->GetFrmSize();
    3542           0 :         const SwFmtFrmSize& rDelTblSz = rDelTbl.GetFrmFmt()->GetFrmSize();
    3543           0 :         if( rTblSz != rDelTblSz )
    3544             :         {
    3545             :             // The needs correction
    3546           0 :             if( bWithPrev )
    3547           0 :                 rDelTbl.GetFrmFmt()->SetFmtAttr( rTblSz );
    3548             :             else
    3549           0 :                 rTbl.GetFrmFmt()->SetFmtAttr( rDelTblSz );
    3550             :         }
    3551             :     }
    3552             : 
    3553           0 :     if( !bWithPrev )
    3554             :     {
    3555             :         // Transfer all Attributes of the succeeding Table to the preceeding one
    3556             :         // We do this, because the succeeding one is deleted when deleting the Node
    3557           0 :         rTbl.SetRowsToRepeat( rDelTbl.GetRowsToRepeat() );
    3558           0 :         rTbl.SetTblChgMode( rDelTbl.GetTblChgMode() );
    3559             : 
    3560           0 :         rTbl.GetFrmFmt()->LockModify();
    3561           0 :         *rTbl.GetFrmFmt() = *rDelTbl.GetFrmFmt();
    3562             :         // Also switch the Name
    3563           0 :         rTbl.GetFrmFmt()->SetName( rDelTbl.GetFrmFmt()->GetName() );
    3564           0 :         rTbl.GetFrmFmt()->UnlockModify();
    3565             :     }
    3566             : 
    3567             :     // Move the Lines and Boxes
    3568           0 :     sal_uInt16 nOldSize = rTbl.GetTabLines().size();
    3569           0 :     rTbl.GetTabLines().insert( rTbl.GetTabLines().begin() + nOldSize,
    3570           0 :                                rDelTbl.GetTabLines().begin(), rDelTbl.GetTabLines().end() );
    3571           0 :     rDelTbl.GetTabLines().clear();
    3572             : 
    3573           0 :     rTbl.GetTabSortBoxes().insert( rDelTbl.GetTabSortBoxes() );
    3574           0 :     rDelTbl.GetTabSortBoxes().clear();
    3575             : 
    3576             :     // The preceeding Table always remains, while the succeeding one is deleted
    3577           0 :     SwEndNode* pTblEndNd = pDelTblNd->EndOfSectionNode();
    3578           0 :     pTblNd->pEndOfSection = pTblEndNd;
    3579             : 
    3580           0 :     SwNodeIndex aIdx( *pDelTblNd, 1 );
    3581             : 
    3582           0 :     SwNode* pBoxNd = aIdx.GetNode().GetStartNode();
    3583           0 :     do {
    3584             :         OSL_ENSURE( pBoxNd->IsStartNode(), "This needs to be a StartNode!" );
    3585           0 :         pBoxNd->pStartOfSection = pTblNd;
    3586           0 :         pBoxNd = (*this)[ pBoxNd->EndOfSectionIndex() + 1 ];
    3587             :     } while( pBoxNd != pTblEndNd );
    3588           0 :     pBoxNd->pStartOfSection = pTblNd;
    3589             : 
    3590           0 :     aIdx -= 2;
    3591           0 :     DelNodes( aIdx, 2 );
    3592             : 
    3593             :     // tweak the conditional styles at the first inserted Line
    3594           0 :     const SwTableLine* pFirstLn = rTbl.GetTabLines()[ nOldSize ];
    3595             :     if( 1 == nMode )
    3596             :     {
    3597             :         // Set Header Template in the Line and save in the History
    3598             :         // if needed for Undo!
    3599             :     }
    3600           0 :     sw_LineSetHeadCondColl( pFirstLn );
    3601             : 
    3602             :     // Clean up the Borders
    3603           0 :     if( nOldSize )
    3604             :     {
    3605           0 :         _SwGCLineBorder aPara( rTbl );
    3606           0 :         aPara.nLinePos = --nOldSize;
    3607           0 :         pFirstLn = rTbl.GetTabLines()[ nOldSize ];
    3608           0 :         sw_GC_Line_Border( pFirstLn, &aPara );
    3609             :     }
    3610             : 
    3611             :     // Update Layout
    3612           0 :     aFndBox.MakeFrms( rTbl );
    3613             : 
    3614           0 :     return true;
    3615             : }
    3616             : 
    3617             : // Use the PtrArray's ForEach method
    3618             : struct _SetAFmtTabPara
    3619             : {
    3620             :     SwTableAutoFmt& rTblFmt;
    3621             :     SwUndoTblAutoFmt* pUndo;
    3622             :     sal_uInt16 nEndBox, nCurBox;
    3623             :     sal_uInt8 nAFmtLine, nAFmtBox;
    3624             : 
    3625           0 :     _SetAFmtTabPara( const SwTableAutoFmt& rNew )
    3626             :         : rTblFmt( (SwTableAutoFmt&)rNew ), pUndo( 0 ),
    3627           0 :         nEndBox( 0 ), nCurBox( 0 ), nAFmtLine( 0 ), nAFmtBox( 0 )
    3628           0 :     {}
    3629             : };
    3630             : 
    3631             : // Forward declare so that the Lines and Boxes can use recursion
    3632             : static bool lcl_SetAFmtBox(_FndBox &, _SetAFmtTabPara *pSetPara);
    3633             : static bool lcl_SetAFmtLine(_FndLine &, _SetAFmtTabPara *pPara);
    3634             : 
    3635           0 : static bool lcl_SetAFmtLine(_FndLine & rLine, _SetAFmtTabPara *pPara)
    3636             : {
    3637           0 :     for (_FndBoxes::iterator it = rLine.GetBoxes().begin();
    3638           0 :          it != rLine.GetBoxes().end(); ++it)
    3639             :     {
    3640           0 :         lcl_SetAFmtBox(*it, pPara);
    3641             :     }
    3642           0 :     return true;
    3643             : }
    3644             : 
    3645           0 : static bool lcl_SetAFmtBox( _FndBox & rBox, _SetAFmtTabPara *pSetPara )
    3646             : {
    3647           0 :     if (!rBox.GetUpper()->GetUpper()) // Box on first level?
    3648             :     {
    3649           0 :         if( !pSetPara->nCurBox )
    3650           0 :             pSetPara->nAFmtBox = 0;
    3651           0 :         else if( pSetPara->nCurBox == pSetPara->nEndBox )
    3652           0 :             pSetPara->nAFmtBox = 3;
    3653             :         else
    3654           0 :             pSetPara->nAFmtBox = (sal_uInt8)(1 + ((pSetPara->nCurBox-1) & 1));
    3655             :     }
    3656             : 
    3657           0 :     if (rBox.GetBox()->GetSttNd())
    3658             :     {
    3659           0 :         SwTableBox* pSetBox = static_cast<SwTableBox*>(rBox.GetBox());
    3660           0 :         SwDoc* pDoc = pSetBox->GetFrmFmt()->GetDoc();
    3661           0 :         SfxItemSet aCharSet( pDoc->GetAttrPool(), RES_CHRATR_BEGIN, RES_PARATR_LIST_END-1 );
    3662           0 :         SfxItemSet aBoxSet( pDoc->GetAttrPool(), aTableBoxSetRange );
    3663           0 :         sal_uInt8 nPos = pSetPara->nAFmtLine * 4 + pSetPara->nAFmtBox;
    3664             :         pSetPara->rTblFmt.UpdateToSet( nPos, aCharSet,
    3665           0 :                                         SwTableAutoFmt::UPDATE_CHAR, 0 );
    3666             :         pSetPara->rTblFmt.UpdateToSet( nPos, aBoxSet,
    3667             :                                         SwTableAutoFmt::UPDATE_BOX,
    3668           0 :                                         pDoc->GetNumberFormatter( true ) );
    3669           0 :         if( aCharSet.Count() )
    3670             :         {
    3671           0 :             sal_uLong nSttNd = pSetBox->GetSttIdx()+1;
    3672           0 :             sal_uLong nEndNd = pSetBox->GetSttNd()->EndOfSectionIndex();
    3673           0 :             for( ; nSttNd < nEndNd; ++nSttNd )
    3674             :             {
    3675           0 :                 SwCntntNode* pNd = pDoc->GetNodes()[ nSttNd ]->GetCntntNode();
    3676           0 :                 if( pNd )
    3677           0 :                     pNd->SetAttr( aCharSet );
    3678             :             }
    3679             :         }
    3680             : 
    3681           0 :         if( aBoxSet.Count() )
    3682             :         {
    3683           0 :             if( pSetPara->pUndo &&
    3684           0 :                 SfxItemState::SET == aBoxSet.GetItemState( RES_BOXATR_FORMAT ))
    3685           0 :                 pSetPara->pUndo->SaveBoxCntnt( *pSetBox );
    3686             : 
    3687           0 :             pSetBox->ClaimFrmFmt()->SetFmtAttr( aBoxSet );
    3688           0 :         }
    3689             :     }
    3690             :     else
    3691           0 :         BOOST_FOREACH( _FndLine& rFndLine, rBox.GetLines() )
    3692           0 :             lcl_SetAFmtLine( rFndLine, pSetPara );
    3693             : 
    3694           0 :     if (!rBox.GetUpper()->GetUpper()) // a BaseLine
    3695           0 :         ++pSetPara->nCurBox;
    3696           0 :     return true;
    3697             : }
    3698             : 
    3699             : /**
    3700             :  * AutoFormat for the Table/TableSelection
    3701             :  */
    3702           0 : bool SwDoc::SetTableAutoFmt( const SwSelBoxes& rBoxes, const SwTableAutoFmt& rNew )
    3703             : {
    3704             :     OSL_ENSURE( !rBoxes.empty(), "No valid Box list" );
    3705           0 :     SwTableNode* pTblNd = (SwTableNode*)rBoxes[0]->GetSttNd()->FindTableNode();
    3706           0 :     if( !pTblNd )
    3707           0 :         return false;
    3708             : 
    3709             :     // Find all Boxes/Lines
    3710           0 :     _FndBox aFndBox( 0, 0 );
    3711             :     {
    3712           0 :         _FndPara aPara( rBoxes, &aFndBox );
    3713           0 :         ForEach_FndLineCopyCol( pTblNd->GetTable().GetTabLines(), &aPara );
    3714             :     }
    3715           0 :     if( aFndBox.GetLines().empty() )
    3716           0 :         return false;
    3717             : 
    3718           0 :     SwTable &table = pTblNd->GetTable();
    3719           0 :     table.SetHTMLTableLayout( 0 );
    3720             : 
    3721           0 :     _FndBox* pFndBox = &aFndBox;
    3722           0 :     while( 1 == pFndBox->GetLines().size() &&
    3723           0 :             1 == pFndBox->GetLines().front().GetBoxes().size() )
    3724             :     {
    3725           0 :         pFndBox = &pFndBox->GetLines().front().GetBoxes()[0];
    3726             :     }
    3727             : 
    3728           0 :     if( pFndBox->GetLines().empty() ) // One too far? (only one sel. Box)
    3729           0 :         pFndBox = pFndBox->GetUpper()->GetUpper();
    3730             : 
    3731             :     // Disable Undo, but first store parameters
    3732           0 :     SwUndoTblAutoFmt* pUndo = 0;
    3733           0 :     bool const bUndo(GetIDocumentUndoRedo().DoesUndo());
    3734           0 :     if (bUndo)
    3735             :     {
    3736           0 :         pUndo = new SwUndoTblAutoFmt( *pTblNd, rNew );
    3737           0 :         GetIDocumentUndoRedo().AppendUndo(pUndo);
    3738           0 :         GetIDocumentUndoRedo().DoUndo(false);
    3739             :     }
    3740             : 
    3741           0 :     rNew.RestoreTableProperties(table);
    3742             : 
    3743           0 :     _SetAFmtTabPara aPara( rNew );
    3744           0 :     _FndLines& rFLns = pFndBox->GetLines();
    3745             :     _FndLine* pLine;
    3746             : 
    3747           0 :     for( sal_uInt16 n = 0; n < rFLns.size(); ++n )
    3748             :     {
    3749           0 :         pLine = &rFLns[n];
    3750             : 
    3751             :         // Set Upper to 0 (thus simulate BaseLine)
    3752           0 :         _FndBox* pSaveBox = pLine->GetUpper();
    3753           0 :         pLine->SetUpper( 0 );
    3754             : 
    3755           0 :         if( !n )
    3756           0 :             aPara.nAFmtLine = 0;
    3757           0 :         else if (static_cast<size_t>(n+1) == rFLns.size())
    3758           0 :             aPara.nAFmtLine = 3;
    3759             :         else
    3760           0 :             aPara.nAFmtLine = (sal_uInt8)(1 + ((n-1) & 1 ));
    3761             : 
    3762           0 :         aPara.nAFmtBox = 0;
    3763           0 :         aPara.nCurBox = 0;
    3764           0 :         aPara.nEndBox = pLine->GetBoxes().size()-1;
    3765           0 :         aPara.pUndo = pUndo;
    3766           0 :         for (_FndBoxes::iterator it = pLine->GetBoxes().begin();
    3767           0 :              it != pLine->GetBoxes().end(); ++it)
    3768             :         {
    3769           0 :             lcl_SetAFmtBox(*it, &aPara);
    3770             :         }
    3771             : 
    3772           0 :         pLine->SetUpper( pSaveBox );
    3773             :     }
    3774             : 
    3775           0 :     if( pUndo )
    3776             :     {
    3777           0 :         GetIDocumentUndoRedo().DoUndo(bUndo);
    3778             :     }
    3779             : 
    3780           0 :     getIDocumentState().SetModified();
    3781           0 :     getIDocumentFieldsAccess().SetFieldsDirty( true, NULL, 0 );
    3782             : 
    3783           0 :     return true;
    3784             : }
    3785             : 
    3786             : /**
    3787             :  * Find out who has the Attributes
    3788             :  */
    3789           0 : bool SwDoc::GetTableAutoFmt( const SwSelBoxes& rBoxes, SwTableAutoFmt& rGet )
    3790             : {
    3791             :     OSL_ENSURE( !rBoxes.empty(), "No valid Box list" );
    3792           0 :     SwTableNode* pTblNd = (SwTableNode*)rBoxes[0]->GetSttNd()->FindTableNode();
    3793           0 :     if( !pTblNd )
    3794           0 :         return false;
    3795             : 
    3796             :     // Find all Boxes/Lines
    3797           0 :     _FndBox aFndBox( 0, 0 );
    3798             :     {
    3799           0 :         _FndPara aPara( rBoxes, &aFndBox );
    3800           0 :         ForEach_FndLineCopyCol( pTblNd->GetTable().GetTabLines(), &aPara );
    3801             :     }
    3802           0 :     if( aFndBox.GetLines().empty() )
    3803           0 :         return false;
    3804             : 
    3805             :     // Store table properties
    3806           0 :     SwTable &table = pTblNd->GetTable();
    3807           0 :     rGet.StoreTableProperties(table);
    3808             : 
    3809           0 :     _FndBox* pFndBox = &aFndBox;
    3810           0 :     while( 1 == pFndBox->GetLines().size() &&
    3811           0 :             1 == pFndBox->GetLines().front().GetBoxes().size() )
    3812             :     {
    3813           0 :         pFndBox = &pFndBox->GetLines().front().GetBoxes()[0];
    3814             :     }
    3815             : 
    3816           0 :     if( pFndBox->GetLines().empty() ) // One too far? (only one sel. Box)
    3817           0 :         pFndBox = pFndBox->GetUpper()->GetUpper();
    3818             : 
    3819           0 :     _FndLines& rFLns = pFndBox->GetLines();
    3820             : 
    3821             :     sal_uInt16 aLnArr[4];
    3822           0 :     aLnArr[0] = 0;
    3823           0 :     aLnArr[1] = 1 < rFLns.size() ? 1 : 0;
    3824           0 :     aLnArr[2] = 2 < rFLns.size() ? 2 : aLnArr[1];
    3825           0 :     aLnArr[3] = rFLns.size() - 1;
    3826             : 
    3827           0 :     for( sal_uInt8 nLine = 0; nLine < 4; ++nLine )
    3828             :     {
    3829           0 :         _FndLine& rLine = rFLns[ aLnArr[ nLine ] ];
    3830             : 
    3831             :         sal_uInt16 aBoxArr[4];
    3832           0 :         aBoxArr[0] = 0;
    3833           0 :         aBoxArr[1] = 1 < rLine.GetBoxes().size() ? 1 : 0;
    3834           0 :         aBoxArr[2] = 2 < rLine.GetBoxes().size() ? 2 : aBoxArr[1];
    3835           0 :         aBoxArr[3] = rLine.GetBoxes().size() - 1;
    3836             : 
    3837           0 :         for( sal_uInt8 nBox = 0; nBox < 4; ++nBox )
    3838             :         {
    3839           0 :             SwTableBox* pFBox = rLine.GetBoxes()[ aBoxArr[ nBox ] ].GetBox();
    3840             :             // Always apply to the first ones
    3841           0 :             while( !pFBox->GetSttNd() )
    3842           0 :                 pFBox = pFBox->GetTabLines()[0]->GetTabBoxes()[0];
    3843             : 
    3844           0 :             sal_uInt8 nPos = nLine * 4 + nBox;
    3845           0 :             SwNodeIndex aIdx( *pFBox->GetSttNd(), 1 );
    3846           0 :             SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
    3847           0 :             if( !pCNd )
    3848           0 :                 pCNd = GetNodes().GoNext( &aIdx );
    3849             : 
    3850           0 :             if( pCNd )
    3851           0 :                 rGet.UpdateFromSet( nPos, pCNd->GetSwAttrSet(),
    3852           0 :                                     SwTableAutoFmt::UPDATE_CHAR, 0 );
    3853           0 :             rGet.UpdateFromSet( nPos, pFBox->GetFrmFmt()->GetAttrSet(),
    3854             :                                 SwTableAutoFmt::UPDATE_BOX,
    3855           0 :                                 GetNumberFormatter( true ) );
    3856           0 :         }
    3857             :     }
    3858             : 
    3859           0 :     return true;
    3860             : }
    3861             : 
    3862        1752 : OUString SwDoc::GetUniqueTblName() const
    3863             : {
    3864        1752 :     ResId aId( STR_TABLE_DEFNAME, *pSwResMgr );
    3865        1752 :     const OUString aName( aId );
    3866             : 
    3867        1752 :     sal_uInt16 nNum, nTmp, nFlagSize = ( mpTblFrmFmtTbl->size() / 8 ) +2;
    3868             :     sal_uInt16 n;
    3869             : 
    3870        1752 :     sal_uInt8* pSetFlags = new sal_uInt8[ nFlagSize ];
    3871        1752 :     memset( pSetFlags, 0, nFlagSize );
    3872             : 
    3873        4634 :     for( n = 0; n < mpTblFrmFmtTbl->size(); ++n )
    3874             :     {
    3875        2882 :         const SwFrmFmt* pFmt = (*mpTblFrmFmtTbl)[ n ];
    3876       11520 :         if( !pFmt->IsDefault() && IsUsed( *pFmt )  &&
    3877       11504 :             pFmt->GetName().startsWith( aName ) )
    3878             :         {
    3879             :             // Get number and set the Flag
    3880        2848 :             const sal_Int32 nNmLen = aName.getLength();
    3881        2848 :             nNum = static_cast<sal_uInt16>(pFmt->GetName().copy( nNmLen ).toInt32());
    3882        2848 :             if( nNum-- && nNum < mpTblFrmFmtTbl->size() )
    3883        2716 :                 pSetFlags[ nNum / 8 ] |= (0x01 << ( nNum & 0x07 ));
    3884             :         }
    3885             :     }
    3886             : 
    3887             :     // All numbers are flagged properly, thus calculate the right number
    3888        1752 :     nNum = mpTblFrmFmtTbl->size();
    3889        1834 :     for( n = 0; n < nFlagSize; ++n )
    3890        1834 :         if( 0xff != ( nTmp = pSetFlags[ n ] ))
    3891             :         {
    3892             :             // Calculate the number
    3893        1752 :             nNum = n * 8;
    3894        5508 :             while( nTmp & 1 )
    3895        2004 :                 ++nNum, nTmp >>= 1;
    3896        1752 :             break;
    3897             :         }
    3898             : 
    3899        1752 :     delete [] pSetFlags;
    3900        1752 :     return aName + OUString::number( ++nNum );
    3901             : }
    3902             : 
    3903         148 : SwTableFmt* SwDoc::FindTblFmtByName( const OUString& rName, bool bAll ) const
    3904             : {
    3905         148 :     const SwFmt* pRet = 0;
    3906         148 :     if( bAll )
    3907           4 :         pRet = FindFmtByName( *mpTblFrmFmtTbl, rName );
    3908             :     else
    3909             :     {
    3910             :         // Only the ones set in the Doc
    3911         324 :         for( sal_uInt16 n = 0; n < mpTblFrmFmtTbl->size(); ++n )
    3912             :         {
    3913         222 :             const SwFrmFmt* pFmt = (*mpTblFrmFmtTbl)[ n ];
    3914         888 :             if( !pFmt->IsDefault() && IsUsed( *pFmt ) &&
    3915         888 :                 pFmt->GetName() == rName )
    3916             :             {
    3917          42 :                 pRet = pFmt;
    3918          42 :                 break;
    3919             :             }
    3920             :         }
    3921             :     }
    3922         148 :     return (SwTableFmt*)pRet;
    3923             : }
    3924             : 
    3925           0 : bool SwDoc::SetColRowWidthHeight( SwTableBox& rAktBox, sal_uInt16 eType,
    3926             :                                     SwTwips nAbsDiff, SwTwips nRelDiff )
    3927             : {
    3928           0 :     SwTableNode* pTblNd = (SwTableNode*)rAktBox.GetSttNd()->FindTableNode();
    3929           0 :     SwUndo* pUndo = 0;
    3930             : 
    3931           0 :     if( nsTblChgWidthHeightType::WH_FLAG_INSDEL & eType && pTblNd->GetTable().ISA( SwDDETable ))
    3932           0 :         return false;
    3933             : 
    3934           0 :     SwTableFmlUpdate aMsgHnt( &pTblNd->GetTable() );
    3935           0 :     aMsgHnt.eFlags = TBL_BOXPTR;
    3936           0 :     getIDocumentFieldsAccess().UpdateTblFlds( &aMsgHnt );
    3937             : 
    3938           0 :     bool const bUndo(GetIDocumentUndoRedo().DoesUndo());
    3939           0 :     bool bRet = false;
    3940           0 :     switch( eType & 0xff )
    3941             :     {
    3942             :     case nsTblChgWidthHeightType::WH_COL_LEFT:
    3943             :     case nsTblChgWidthHeightType::WH_COL_RIGHT:
    3944             :     case nsTblChgWidthHeightType::WH_CELL_LEFT:
    3945             :     case nsTblChgWidthHeightType::WH_CELL_RIGHT:
    3946             :         {
    3947           0 :              bRet = pTblNd->GetTable().SetColWidth( rAktBox,
    3948             :                                 eType, nAbsDiff, nRelDiff,
    3949           0 :                                 (bUndo) ? &pUndo : 0 );
    3950             :         }
    3951           0 :         break;
    3952             :     case nsTblChgWidthHeightType::WH_ROW_TOP:
    3953             :     case nsTblChgWidthHeightType::WH_ROW_BOTTOM:
    3954             :     case nsTblChgWidthHeightType::WH_CELL_TOP:
    3955             :     case nsTblChgWidthHeightType::WH_CELL_BOTTOM:
    3956           0 :         bRet = pTblNd->GetTable().SetRowHeight( rAktBox,
    3957             :                             eType, nAbsDiff, nRelDiff,
    3958           0 :                             (bUndo) ? &pUndo : 0 );
    3959           0 :         break;
    3960             :     }
    3961             : 
    3962           0 :     GetIDocumentUndoRedo().DoUndo(bUndo); // SetColWidth can turn it off
    3963           0 :     if( pUndo )
    3964             :     {
    3965           0 :         GetIDocumentUndoRedo().AppendUndo( pUndo );
    3966             :     }
    3967             : 
    3968           0 :     if( bRet )
    3969             :     {
    3970           0 :         getIDocumentState().SetModified();
    3971           0 :         if( nsTblChgWidthHeightType::WH_FLAG_INSDEL & eType )
    3972           0 :             getIDocumentFieldsAccess().SetFieldsDirty( true, NULL, 0 );
    3973             :     }
    3974           0 :     return bRet;
    3975             : }
    3976             : 
    3977           0 : void SwDoc::ChkBoxNumFmt( SwTableBox& rBox, bool bCallUpdate )
    3978             : {
    3979             :     // Optimization: If the Box says it's Text, it remains Text
    3980           0 :     const SfxPoolItem* pNumFmtItem = 0;
    3981           0 :     if( SfxItemState::SET == rBox.GetFrmFmt()->GetItemState( RES_BOXATR_FORMAT,
    3982           0 :         false, &pNumFmtItem ) && GetNumberFormatter()->IsTextFormat(
    3983           0 :             ((SwTblBoxNumFormat*)pNumFmtItem)->GetValue() ))
    3984           0 :         return ;
    3985             : 
    3986           0 :     SwUndoTblNumFmt* pUndo = 0;
    3987             : 
    3988             :     bool bIsEmptyTxtNd;
    3989           0 :     bool bChgd = true;
    3990             :     sal_uInt32 nFmtIdx;
    3991             :     double fNumber;
    3992           0 :     if( rBox.HasNumCntnt( fNumber, nFmtIdx, bIsEmptyTxtNd ) )
    3993             :     {
    3994           0 :         if( !rBox.IsNumberChanged() )
    3995           0 :             bChgd = false;
    3996             :         else
    3997             :         {
    3998           0 :             if (GetIDocumentUndoRedo().DoesUndo())
    3999             :             {
    4000           0 :                 GetIDocumentUndoRedo().StartUndo( UNDO_TABLE_AUTOFMT, NULL );
    4001           0 :                 pUndo = new SwUndoTblNumFmt( rBox );
    4002           0 :                 pUndo->SetNumFmt( nFmtIdx, fNumber );
    4003             :             }
    4004             : 
    4005           0 :             SwTableBoxFmt* pBoxFmt = (SwTableBoxFmt*)rBox.GetFrmFmt();
    4006           0 :             SfxItemSet aBoxSet( GetAttrPool(), RES_BOXATR_FORMAT, RES_BOXATR_VALUE );
    4007             : 
    4008           0 :             bool bLockModify = true;
    4009           0 :             bool bSetNumberFormat = false;
    4010           0 :             const bool bForceNumberFormat = IsInsTblFormatNum() && IsInsTblChangeNumFormat();
    4011             : 
    4012             :             // if the user forced a number format in this cell previously,
    4013             :             // keep it, unless the user set that she wants the full number
    4014             :             // format recognition
    4015           0 :             if( pNumFmtItem && !bForceNumberFormat )
    4016             :             {
    4017           0 :                 sal_uLong nOldNumFmt = ((SwTblBoxNumFormat*)pNumFmtItem)->GetValue();
    4018           0 :                 SvNumberFormatter* pNumFmtr = GetNumberFormatter();
    4019             : 
    4020           0 :                 short nFmtType = pNumFmtr->GetType( nFmtIdx );
    4021           0 :                 if( nFmtType == pNumFmtr->GetType( nOldNumFmt ) || NUMBERFORMAT_NUMBER == nFmtType )
    4022             :                 {
    4023             :                     // Current and specified NumFormat match
    4024             :                     // -> keep old Format
    4025           0 :                     nFmtIdx = nOldNumFmt;
    4026           0 :                     bSetNumberFormat = true;
    4027             :                 }
    4028             :                 else
    4029             :                 {
    4030             :                     // Current and specified NumFormat do not match
    4031             :                     // -> insert as Text
    4032           0 :                     bLockModify = bSetNumberFormat = false;
    4033             :                 }
    4034             :             }
    4035             : 
    4036           0 :             if( bSetNumberFormat || bForceNumberFormat )
    4037             :             {
    4038           0 :                 pBoxFmt = (SwTableBoxFmt*)rBox.ClaimFrmFmt();
    4039             : 
    4040           0 :                 aBoxSet.Put( SwTblBoxValue( fNumber ));
    4041           0 :                 aBoxSet.Put( SwTblBoxNumFormat( nFmtIdx ));
    4042             :             }
    4043             : 
    4044             :             // It's not enough to only reset the Formula.
    4045             :             // Make sure that the Text is formatted accordingly
    4046           0 :             if( !bSetNumberFormat && !bIsEmptyTxtNd && pNumFmtItem )
    4047             :             {
    4048             :                 // Just resetting Attributes is not enough
    4049             :                 // Make sure that the Text is formatted accordingly
    4050           0 :                 pBoxFmt->SetFmtAttr( *GetDfltAttr( RES_BOXATR_FORMAT ));
    4051             :             }
    4052             : 
    4053           0 :             if( bLockModify ) pBoxFmt->LockModify();
    4054           0 :             pBoxFmt->ResetFmtAttr( RES_BOXATR_FORMAT, RES_BOXATR_VALUE );
    4055           0 :             if( bLockModify ) pBoxFmt->UnlockModify();
    4056             : 
    4057           0 :             if( bSetNumberFormat )
    4058           0 :                 pBoxFmt->SetFmtAttr( aBoxSet );
    4059             :         }
    4060             :     }
    4061             :     else
    4062             :     {
    4063             :         // It's not a number
    4064           0 :         const SfxPoolItem* pValueItem = 0, *pFmtItem = 0;
    4065           0 :         SwTableBoxFmt* pBoxFmt = (SwTableBoxFmt*)rBox.GetFrmFmt();
    4066           0 :         if( SfxItemState::SET == pBoxFmt->GetItemState( RES_BOXATR_FORMAT,
    4067           0 :                 false, &pFmtItem ) ||
    4068             :             SfxItemState::SET == pBoxFmt->GetItemState( RES_BOXATR_VALUE,
    4069           0 :                 false, &pValueItem ))
    4070             :         {
    4071           0 :             if (GetIDocumentUndoRedo().DoesUndo())
    4072             :             {
    4073           0 :                 GetIDocumentUndoRedo().StartUndo( UNDO_TABLE_AUTOFMT, NULL );
    4074           0 :                 pUndo = new SwUndoTblNumFmt( rBox );
    4075             :             }
    4076             : 
    4077           0 :             pBoxFmt = (SwTableBoxFmt*)rBox.ClaimFrmFmt();
    4078             : 
    4079             :             // Remove all number formats
    4080           0 :             sal_uInt16 nWhich1 = RES_BOXATR_FORMULA;
    4081           0 :             if( !bIsEmptyTxtNd )
    4082             :             {
    4083           0 :                 nWhich1 = RES_BOXATR_FORMAT;
    4084             : 
    4085             :                 // Just resetting Attributes is not enough
    4086             :                 // Make sure that the Text is formatted accordingly
    4087           0 :                 pBoxFmt->SetFmtAttr( *GetDfltAttr( nWhich1 ));
    4088             :             }
    4089           0 :             pBoxFmt->ResetFmtAttr( nWhich1, RES_BOXATR_VALUE );
    4090             :         }
    4091             :         else
    4092           0 :             bChgd = false;
    4093             :     }
    4094             : 
    4095           0 :     if( bChgd )
    4096             :     {
    4097           0 :         if( pUndo )
    4098             :         {
    4099           0 :             pUndo->SetBox( rBox );
    4100           0 :             GetIDocumentUndoRedo().AppendUndo(pUndo);
    4101           0 :             GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
    4102             :         }
    4103             : 
    4104           0 :         const SwTableNode* pTblNd = rBox.GetSttNd()->FindTableNode();
    4105           0 :         if( bCallUpdate )
    4106             :         {
    4107           0 :             SwTableFmlUpdate aTblUpdate( &pTblNd->GetTable() );
    4108           0 :             getIDocumentFieldsAccess().UpdateTblFlds( &aTblUpdate );
    4109             : 
    4110             :             // TL_CHART2: update charts (when cursor leaves cell and
    4111             :             // automatic update is enabled)
    4112           0 :             if (AUTOUPD_FIELD_AND_CHARTS == GetDocumentSettingManager().getFieldUpdateFlags(true))
    4113           0 :                 pTblNd->GetTable().UpdateCharts();
    4114             :         }
    4115           0 :         getIDocumentState().SetModified();
    4116             :     }
    4117             : }
    4118             : 
    4119         144 : void SwDoc::SetTblBoxFormulaAttrs( SwTableBox& rBox, const SfxItemSet& rSet )
    4120             : {
    4121         144 :     if (GetIDocumentUndoRedo().DoesUndo())
    4122             :     {
    4123         144 :         GetIDocumentUndoRedo().AppendUndo( new SwUndoTblNumFmt(rBox, &rSet) );
    4124             :     }
    4125             : 
    4126         144 :     SwFrmFmt* pBoxFmt = rBox.ClaimFrmFmt();
    4127         144 :     if( SfxItemState::SET == rSet.GetItemState( RES_BOXATR_FORMULA ))
    4128             :     {
    4129           0 :         pBoxFmt->LockModify();
    4130           0 :         pBoxFmt->ResetFmtAttr( RES_BOXATR_VALUE );
    4131           0 :         pBoxFmt->UnlockModify();
    4132             :     }
    4133         144 :     else if( SfxItemState::SET == rSet.GetItemState( RES_BOXATR_VALUE ))
    4134             :     {
    4135         144 :         pBoxFmt->LockModify();
    4136         144 :         pBoxFmt->ResetFmtAttr( RES_BOXATR_FORMULA );
    4137         144 :         pBoxFmt->UnlockModify();
    4138             :     }
    4139         144 :     pBoxFmt->SetFmtAttr( rSet );
    4140         144 :     getIDocumentState().SetModified();
    4141         144 : }
    4142             : 
    4143          10 : void SwDoc::ClearLineNumAttrs( SwPosition & rPos )
    4144             : {
    4145          10 :     SwPaM aPam(rPos);
    4146          10 :     aPam.Move(fnMoveBackward);
    4147          10 :     SwCntntNode *pNode = aPam.GetCntntNode();
    4148          10 :     if ( 0 == pNode )
    4149          10 :         return ;
    4150          10 :     if( pNode->IsTxtNode() )
    4151             :     {
    4152          10 :         SwTxtNode * pTxtNode = pNode->GetTxtNode();
    4153          20 :         if (pTxtNode && pTxtNode->IsNumbered()
    4154          10 :             && pTxtNode->GetTxt().isEmpty())
    4155             :         {
    4156           0 :             const SfxPoolItem* pFmtItem = 0;
    4157           0 :             SfxItemSet rSet( const_cast<SwAttrPool&>(pTxtNode->GetDoc()->GetAttrPool()),
    4158             :                         RES_PARATR_BEGIN, RES_PARATR_END - 1,
    4159           0 :                         0);
    4160           0 :             pTxtNode->SwCntntNode::GetAttr( rSet );
    4161           0 :             if ( SfxItemState::SET == rSet.GetItemState( RES_PARATR_NUMRULE , false , &pFmtItem ) )
    4162             :             {
    4163             :                 SwUndoDelNum * pUndo;
    4164           0 :                 if( GetIDocumentUndoRedo().DoesUndo() )
    4165             :                 {
    4166           0 :                     GetIDocumentUndoRedo().ClearRedo();
    4167           0 :                     GetIDocumentUndoRedo().AppendUndo( pUndo = new SwUndoDelNum( aPam ) );
    4168             :                 }
    4169             :                 else
    4170           0 :                     pUndo = 0;
    4171           0 :                 SwRegHistory aRegH( pUndo ? pUndo->GetHistory() : 0 );
    4172           0 :                 aRegH.RegisterInModify( pTxtNode , *pTxtNode );
    4173           0 :                 if ( pUndo )
    4174           0 :                     pUndo->AddNode( *pTxtNode , false );
    4175           0 :                 SfxStringItem * pNewItem = (SfxStringItem*)pFmtItem->Clone();
    4176           0 :                 pNewItem->SetValue(OUString());
    4177           0 :                 rSet.Put( *pNewItem );
    4178           0 :                 pTxtNode->SetAttr( rSet );
    4179           0 :                 delete pNewItem;
    4180           0 :             }
    4181             :         }
    4182          10 :     }
    4183             : }
    4184             : 
    4185        6856 : void SwDoc::ClearBoxNumAttrs( const SwNodeIndex& rNode )
    4186             : {
    4187             :     SwStartNode* pSttNd;
    4188       13712 :     if( 0 != ( pSttNd = rNode.GetNode().
    4189        7888 :                                 FindSttNodeByType( SwTableBoxStartNode )) &&
    4190        1032 :         2 == pSttNd->EndOfSectionIndex() - pSttNd->GetIndex() )
    4191             :     {
    4192         974 :         SwTableBox* pBox = pSttNd->FindTableNode()->GetTable().
    4193        1948 :                             GetTblBox( pSttNd->GetIndex() );
    4194             : 
    4195         974 :         const SfxPoolItem* pFmtItem = 0;
    4196         974 :         const SfxItemSet& rSet = pBox->GetFrmFmt()->GetAttrSet();
    4197        2920 :         if( SfxItemState::SET == rSet.GetItemState( RES_BOXATR_FORMAT, false, &pFmtItem ) ||
    4198        1946 :             SfxItemState::SET == rSet.GetItemState( RES_BOXATR_FORMULA, false ) ||
    4199         972 :             SfxItemState::SET == rSet.GetItemState( RES_BOXATR_VALUE, false ))
    4200             :         {
    4201           2 :             if (GetIDocumentUndoRedo().DoesUndo())
    4202             :             {
    4203           2 :                 GetIDocumentUndoRedo().AppendUndo(new SwUndoTblNumFmt(*pBox));
    4204             :             }
    4205             : 
    4206           2 :             SwFrmFmt* pBoxFmt = pBox->ClaimFrmFmt();
    4207             : 
    4208             :             // Keep TextFormats!
    4209           2 :             sal_uInt16 nWhich1 = RES_BOXATR_FORMAT;
    4210           4 :             if( pFmtItem && GetNumberFormatter()->IsTextFormat(
    4211           2 :                     ((SwTblBoxNumFormat*)pFmtItem)->GetValue() ))
    4212           0 :                 nWhich1 = RES_BOXATR_FORMULA;
    4213             :             else
    4214             :                 // Just resetting Attributes is not enough
    4215             :                 // Make sure that the Text is formatted accordingly
    4216           2 :                 pBoxFmt->SetFmtAttr( *GetDfltAttr( RES_BOXATR_FORMAT ));
    4217             : 
    4218           2 :             pBoxFmt->ResetFmtAttr( nWhich1, RES_BOXATR_VALUE );
    4219           2 :             getIDocumentState().SetModified();
    4220             :         }
    4221             :     }
    4222        6856 : }
    4223             : 
    4224             : /**
    4225             :  * Copies a Table from the same or another Doc into itself
    4226             :  * We create a new Table or an existing one is filled with the Content.
    4227             :  * We either fill in the Content from a certain Box or a certain TblSelection
    4228             :  *
    4229             :  * This method is called by edglss.cxx/fecopy.cxx
    4230             :  */
    4231           0 : bool SwDoc::InsCopyOfTbl( SwPosition& rInsPos, const SwSelBoxes& rBoxes,
    4232             :                         const SwTable* pCpyTbl, bool bCpyName, bool bCorrPos )
    4233             : {
    4234             :     bool bRet;
    4235             : 
    4236             :     const SwTableNode* pSrcTblNd = pCpyTbl
    4237             :             ? pCpyTbl->GetTableNode()
    4238           0 :             : rBoxes[ 0 ]->GetSttNd()->FindTableNode();
    4239             : 
    4240           0 :     SwTableNode * pInsTblNd = rInsPos.nNode.GetNode().FindTableNode();
    4241             : 
    4242           0 :     bool const bUndo( GetIDocumentUndoRedo().DoesUndo() );
    4243           0 :     if( !pCpyTbl && !pInsTblNd )
    4244             :     {
    4245           0 :         SwUndoCpyTbl* pUndo = 0;
    4246           0 :         if (bUndo)
    4247             :         {
    4248           0 :             GetIDocumentUndoRedo().ClearRedo();
    4249           0 :             pUndo = new SwUndoCpyTbl;
    4250             :         }
    4251             : 
    4252             :         {
    4253           0 :             ::sw::UndoGuard const undoGuard(GetIDocumentUndoRedo());
    4254           0 :             bRet = pSrcTblNd->GetTable().MakeCopy( this, rInsPos, rBoxes,
    4255           0 :                                                 true, bCpyName );
    4256             :         }
    4257             : 
    4258           0 :         if( pUndo )
    4259             :         {
    4260           0 :             if( !bRet )
    4261             :             {
    4262           0 :                 delete pUndo;
    4263           0 :                 pUndo = 0;
    4264             :             }
    4265             :             else
    4266             :             {
    4267           0 :                 pInsTblNd = GetNodes()[ rInsPos.nNode.GetIndex() - 1 ]->FindTableNode();
    4268             : 
    4269           0 :                 pUndo->SetTableSttIdx( pInsTblNd->GetIndex() );
    4270           0 :                 GetIDocumentUndoRedo().AppendUndo( pUndo );
    4271             :             }
    4272           0 :         }
    4273             :     }
    4274             :     else
    4275             :     {
    4276           0 :         RedlineMode_t eOld = getIDocumentRedlineAccess().GetRedlineMode();
    4277           0 :         if( getIDocumentRedlineAccess().IsRedlineOn() )
    4278           0 :       getIDocumentRedlineAccess().SetRedlineMode( (RedlineMode_t)(nsRedlineMode_t::REDLINE_ON |
    4279             :                                   nsRedlineMode_t::REDLINE_SHOW_INSERT |
    4280           0 :                                   nsRedlineMode_t::REDLINE_SHOW_DELETE));
    4281             : 
    4282           0 :         SwUndoTblCpyTbl* pUndo = 0;
    4283           0 :         if (bUndo)
    4284             :         {
    4285           0 :             GetIDocumentUndoRedo().ClearRedo();
    4286           0 :             pUndo = new SwUndoTblCpyTbl;
    4287           0 :             GetIDocumentUndoRedo().DoUndo(false);
    4288             :         }
    4289             : 
    4290           0 :         SwDoc* pCpyDoc = (SwDoc*)pSrcTblNd->GetDoc();
    4291           0 :         bool bDelCpyDoc = pCpyDoc == this;
    4292             : 
    4293           0 :         if( bDelCpyDoc )
    4294             :         {
    4295             :             // Copy the Table into a temporary Doc
    4296           0 :             pCpyDoc = new SwDoc;
    4297           0 :             pCpyDoc->acquire();
    4298             : 
    4299           0 :             SwPosition aPos( SwNodeIndex( pCpyDoc->GetNodes().GetEndOfContent() ));
    4300           0 :             if( !pSrcTblNd->GetTable().MakeCopy( pCpyDoc, aPos, rBoxes, true, true ))
    4301             :             {
    4302           0 :                 if( pCpyDoc->release() == 0 )
    4303           0 :                     delete pCpyDoc;
    4304             : 
    4305           0 :                 if( pUndo )
    4306             :                 {
    4307           0 :                     GetIDocumentUndoRedo().DoUndo(bUndo);
    4308           0 :                     delete pUndo;
    4309           0 :                     pUndo = 0;
    4310             :                 }
    4311           0 :                 return false;
    4312             :             }
    4313           0 :             aPos.nNode -= 1; // Set to the Table's EndNode
    4314           0 :             pSrcTblNd = aPos.nNode.GetNode().FindTableNode();
    4315             :         }
    4316             : 
    4317           0 :         const SwStartNode* pSttNd = rInsPos.nNode.GetNode().FindTableBoxStartNode();
    4318             : 
    4319           0 :         rInsPos.nContent.Assign( 0, 0 );
    4320             : 
    4321             :         // no complex into complex, but copy into or from new model is welcome
    4322           0 :         if( ( !pSrcTblNd->GetTable().IsTblComplex() || pInsTblNd->GetTable().IsNewModel() )
    4323           0 :             && ( bDelCpyDoc || !rBoxes.empty() ) )
    4324             :         {
    4325             :             // Copy the Table "relatively"
    4326             :             const SwSelBoxes* pBoxes;
    4327           0 :             SwSelBoxes aBoxes;
    4328             : 
    4329           0 :             if( bDelCpyDoc )
    4330             :             {
    4331           0 :                 SwTableBox* pBox = pInsTblNd->GetTable().GetTblBox(
    4332           0 :                                         pSttNd->GetIndex() );
    4333             :                 OSL_ENSURE( pBox, "Box is not in this Table" );
    4334           0 :                 aBoxes.insert( pBox );
    4335           0 :                 pBoxes = &aBoxes;
    4336             :             }
    4337             :             else
    4338           0 :                 pBoxes = &rBoxes;
    4339             : 
    4340             :             // Copy Table to the selected Lines
    4341           0 :             bRet = pInsTblNd->GetTable().InsTable( pSrcTblNd->GetTable(),
    4342           0 :                                                         *pBoxes, pUndo );
    4343             :         }
    4344             :         else
    4345             :         {
    4346           0 :             SwNodeIndex aNdIdx( *pSttNd, 1 );
    4347           0 :             bRet = pInsTblNd->GetTable().InsTable( pSrcTblNd->GetTable(),
    4348           0 :                                                     aNdIdx, pUndo );
    4349             :         }
    4350             : 
    4351           0 :         if( bDelCpyDoc )
    4352             :         {
    4353           0 :             if( pCpyDoc->release() == 0 )
    4354           0 :                 delete pCpyDoc;
    4355             :         }
    4356             : 
    4357           0 :         if( pUndo )
    4358             :         {
    4359             :             // If the Table could not be copied, delete the Undo object
    4360           0 :             GetIDocumentUndoRedo().DoUndo(bUndo);
    4361           0 :             if( !bRet && pUndo->IsEmpty() )
    4362           0 :                 delete pUndo;
    4363             :             else
    4364             :             {
    4365           0 :                 GetIDocumentUndoRedo().AppendUndo(pUndo);
    4366             :             }
    4367             :         }
    4368             : 
    4369           0 :         if( bCorrPos )
    4370             :         {
    4371           0 :             rInsPos.nNode = *pSttNd;
    4372           0 :             rInsPos.nContent.Assign( GetNodes().GoNext( &rInsPos.nNode ), 0 );
    4373             :         }
    4374           0 :         getIDocumentRedlineAccess().SetRedlineMode( eOld );
    4375             :     }
    4376             : 
    4377           0 :     if( bRet )
    4378             :     {
    4379           0 :         getIDocumentState().SetModified();
    4380           0 :         getIDocumentFieldsAccess().SetFieldsDirty( true, NULL, 0 );
    4381             :     }
    4382           0 :     return bRet;
    4383             : }
    4384             : 
    4385           0 : bool SwDoc::_UnProtectTblCells( SwTable& rTbl )
    4386             : {
    4387           0 :     bool bChgd = false;
    4388           0 :     SwUndoAttrTbl *const pUndo = (GetIDocumentUndoRedo().DoesUndo())
    4389           0 :         ?   new SwUndoAttrTbl( *rTbl.GetTableNode() )
    4390           0 :         :   0;
    4391             : 
    4392           0 :     SwTableSortBoxes& rSrtBox = rTbl.GetTabSortBoxes();
    4393           0 :     for (size_t i = rSrtBox.size(); i; )
    4394             :     {
    4395           0 :         SwFrmFmt *pBoxFmt = rSrtBox[ --i ]->GetFrmFmt();
    4396           0 :         if( pBoxFmt->GetProtect().IsCntntProtected() )
    4397             :         {
    4398           0 :             pBoxFmt->ResetFmtAttr( RES_PROTECT );
    4399           0 :             bChgd = true;
    4400             :         }
    4401             :     }
    4402             : 
    4403           0 :     if( pUndo )
    4404             :     {
    4405           0 :         if( bChgd )
    4406             :         {
    4407           0 :             GetIDocumentUndoRedo().AppendUndo( pUndo );
    4408             :         }
    4409             :         else
    4410           0 :             delete pUndo;
    4411             :     }
    4412           0 :     return bChgd;
    4413             : }
    4414             : 
    4415           0 : bool SwDoc::UnProtectCells( const OUString& rName )
    4416             : {
    4417           0 :     bool bChgd = false;
    4418           0 :     SwTableFmt* pFmt = FindTblFmtByName( rName );
    4419           0 :     if( pFmt )
    4420             :     {
    4421           0 :         bChgd = _UnProtectTblCells( *SwTable::FindTable( pFmt ) );
    4422           0 :         if( bChgd )
    4423           0 :             getIDocumentState().SetModified();
    4424             :     }
    4425             : 
    4426           0 :     return bChgd;
    4427             : }
    4428             : 
    4429           0 : bool SwDoc::UnProtectCells( const SwSelBoxes& rBoxes )
    4430             : {
    4431           0 :     bool bChgd = false;
    4432           0 :     if( !rBoxes.empty() )
    4433             :     {
    4434           0 :         SwUndoAttrTbl *const pUndo = (GetIDocumentUndoRedo().DoesUndo())
    4435           0 :                 ? new SwUndoAttrTbl( *rBoxes[0]->GetSttNd()->FindTableNode() )
    4436           0 :                 : 0;
    4437             : 
    4438           0 :         std::map<SwFrmFmt*, SwTableBoxFmt*> aFmtsMap;
    4439           0 :         for (size_t i = rBoxes.size(); i; )
    4440             :         {
    4441           0 :             SwTableBox* pBox = rBoxes[ --i ];
    4442           0 :             SwFrmFmt* pBoxFmt = pBox->GetFrmFmt();
    4443           0 :             if( pBoxFmt->GetProtect().IsCntntProtected() )
    4444             :             {
    4445             :                 std::map<SwFrmFmt*, SwTableBoxFmt*>::const_iterator const it =
    4446           0 :                     aFmtsMap.find(pBoxFmt);
    4447           0 :                 if (aFmtsMap.end() != it)
    4448           0 :                     pBox->ChgFrmFmt(it->second);
    4449             :                 else
    4450             :                 {
    4451             :                     SwTableBoxFmt *const pNewBoxFmt(
    4452           0 :                         static_cast<SwTableBoxFmt*>(pBox->ClaimFrmFmt()));
    4453           0 :                     pNewBoxFmt->ResetFmtAttr( RES_PROTECT );
    4454           0 :                     aFmtsMap.insert(std::make_pair(pBoxFmt, pNewBoxFmt));
    4455             :                 }
    4456           0 :                 bChgd = true;
    4457             :             }
    4458             :         }
    4459             : 
    4460           0 :         if( pUndo )
    4461             :         {
    4462           0 :             if( bChgd )
    4463             :             {
    4464           0 :                 GetIDocumentUndoRedo().AppendUndo( pUndo );
    4465             :             }
    4466             :             else
    4467           0 :                 delete pUndo;
    4468           0 :         }
    4469             :     }
    4470           0 :     return bChgd;
    4471             : }
    4472             : 
    4473           0 : bool SwDoc::UnProtectTbls( const SwPaM& rPam )
    4474             : {
    4475           0 :     GetIDocumentUndoRedo().StartUndo(UNDO_EMPTY, NULL);
    4476             : 
    4477           0 :     bool bChgd = false, bHasSel = rPam.HasMark() ||
    4478           0 :                                     rPam.GetNext() != (SwPaM*)&rPam;
    4479           0 :     SwFrmFmts& rFmts = *GetTblFrmFmts();
    4480             :     SwTable* pTbl;
    4481             :     const SwTableNode* pTblNd;
    4482           0 :     for( sal_uInt16 n = rFmts.size(); n ; )
    4483           0 :         if( 0 != (pTbl = SwTable::FindTable( rFmts[ --n ] )) &&
    4484           0 :             0 != (pTblNd = pTbl->GetTableNode() ) &&
    4485           0 :             pTblNd->GetNodes().IsDocNodes() )
    4486             :         {
    4487           0 :             sal_uLong nTblIdx = pTblNd->GetIndex();
    4488             : 
    4489             :             // Check whether the Table is within the Selection
    4490           0 :             if( bHasSel )
    4491             :             {
    4492           0 :                 bool bFound = false;
    4493           0 :                 SwPaM* pTmp = (SwPaM*)&rPam;
    4494           0 :                 do {
    4495           0 :                     const SwPosition *pStt = pTmp->Start(),
    4496           0 :                                     *pEnd = pTmp->End();
    4497           0 :                     bFound = pStt->nNode.GetIndex() < nTblIdx &&
    4498           0 :                             nTblIdx < pEnd->nNode.GetIndex();
    4499             : 
    4500           0 :                 } while( !bFound && &rPam != ( pTmp = (SwPaM*)pTmp->GetNext() ) );
    4501           0 :                 if( !bFound )
    4502           0 :                     continue; // Continue searching
    4503             :             }
    4504             : 
    4505             :             // Lift the protection
    4506           0 :             bChgd |= _UnProtectTblCells( *pTbl );
    4507             :         }
    4508             : 
    4509           0 :     GetIDocumentUndoRedo().EndUndo(UNDO_EMPTY, NULL);
    4510           0 :     if( bChgd )
    4511           0 :         getIDocumentState().SetModified();
    4512             : 
    4513           0 :     return bChgd;
    4514             : }
    4515             : 
    4516           0 : bool SwDoc::HasTblAnyProtection( const SwPosition* pPos,
    4517             :                                  const OUString* pTblName,
    4518             :                                  bool* pFullTblProtection )
    4519             : {
    4520           0 :     bool bHasProtection = false;
    4521           0 :     SwTable* pTbl = 0;
    4522           0 :     if( pTblName )
    4523           0 :         pTbl = SwTable::FindTable( FindTblFmtByName( *pTblName ) );
    4524           0 :     else if( pPos )
    4525             :     {
    4526           0 :         SwTableNode* pTblNd = pPos->nNode.GetNode().FindTableNode();
    4527           0 :         if( pTblNd )
    4528           0 :             pTbl = &pTblNd->GetTable();
    4529             :     }
    4530             : 
    4531           0 :     if( pTbl )
    4532             :     {
    4533           0 :         SwTableSortBoxes& rSrtBox = pTbl->GetTabSortBoxes();
    4534           0 :         for (size_t i = rSrtBox.size(); i; )
    4535             :         {
    4536           0 :             SwFrmFmt *pBoxFmt = rSrtBox[ --i ]->GetFrmFmt();
    4537           0 :             if( pBoxFmt->GetProtect().IsCntntProtected() )
    4538             :             {
    4539           0 :                 if( !bHasProtection )
    4540             :                 {
    4541           0 :                     bHasProtection = true;
    4542           0 :                     if( !pFullTblProtection )
    4543           0 :                         break;
    4544           0 :                     *pFullTblProtection = true;
    4545             :                 }
    4546             :             }
    4547           0 :             else if( bHasProtection && pFullTblProtection )
    4548             :             {
    4549           0 :                 *pFullTblProtection = false;
    4550           0 :                 break;
    4551             :             }
    4552             :         }
    4553             :     }
    4554           0 :     return bHasProtection;
    4555         270 : }
    4556             : 
    4557             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10