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

Generated by: LCOV version 1.10