LCOV - code coverage report
Current view: top level - sw/source/core/docnode - ndtbl.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 792 2355 33.6 %
Date: 2015-06-13 12:38:46 Functions: 38 88 43.2 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11