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

Generated by: LCOV version 1.10