LibreOffice Module sw (master)  1
tblrwcl.cxx
Go to the documentation of this file.
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 <memory>
21 #include <com/sun/star/text/HoriOrientation.hpp>
22 #include <osl/diagnose.h>
23 #include <svl/numformat.hxx>
24 #include <hintids.hxx>
25 
26 #include <editeng/lrspitem.hxx>
27 #include <editeng/boxitem.hxx>
28 #include <tools/fract.hxx>
29 #include <fmtfsize.hxx>
30 #include <fmtornt.hxx>
31 #include <doc.hxx>
38 #include <docsh.hxx>
39 #include <fesh.hxx>
40 #include <tabfrm.hxx>
41 #include <frmatr.hxx>
42 #include <frmtool.hxx>
43 #include <pam.hxx>
44 #include <swtable.hxx>
45 #include <tblsel.hxx>
46 #include <fldbas.hxx>
47 #include <rowfrm.hxx>
48 #include <ddefld.hxx>
49 #include <hints.hxx>
50 #include <UndoTable.hxx>
51 #include <cellatr.hxx>
52 #include <mvsave.hxx>
53 #include <swtblfmt.hxx>
54 #include <swddetbl.hxx>
55 #include <poolfmt.hxx>
56 #include <tblrwcl.hxx>
57 #include <unochart.hxx>
58 #include <o3tl/numeric.hxx>
59 #include <calbck.hxx>
60 #include <docary.hxx>
61 
62 using namespace com::sun::star;
63 using namespace com::sun::star::uno;
64 
65 #define COLFUZZY 20
66 #define ROWFUZZY 10
67 
68 #ifdef DBG_UTIL
69 #define CHECK_TABLE(t) (t).CheckConsistency();
70 #else
71 #define CHECK_TABLE(t)
72 #endif
73 
74 namespace {
75 
76 // In order to set the Frame Formats for the Boxes, it's enough to look
77 // up the current one in the array. If it's already there return the new one.
78 struct CpyTabFrame
79 {
80  SwFrameFormat* pFrameFormat;
81  SwTableBoxFormat *pNewFrameFormat;
82 
83  explicit CpyTabFrame(SwFrameFormat* pCurrentFrameFormat) : pNewFrameFormat( nullptr )
84  { pFrameFormat = pCurrentFrameFormat; }
85 
86  bool operator==( const CpyTabFrame& rCpyTabFrame ) const
87  { return pFrameFormat == rCpyTabFrame.pFrameFormat; }
88  bool operator<( const CpyTabFrame& rCpyTabFrame ) const
89  { return pFrameFormat < rCpyTabFrame.pFrameFormat; }
90 };
91 
92 struct CR_SetBoxWidth
93 {
94  SwShareBoxFormats aShareFormats;
95  SwTableNode* pTableNd;
96  SwTwips nDiff, nSide, nMaxSize, nLowerDiff;
97  TableChgMode nMode;
98  bool bBigger, bLeft;
99 
100  CR_SetBoxWidth( TableChgWidthHeightType eType, SwTwips nDif, SwTwips nSid,
101  SwTwips nMax, SwTableNode* pTNd )
102  : pTableNd( pTNd ),
103  nDiff( nDif ), nSide( nSid ), nMaxSize( nMax ), nLowerDiff( 0 )
104  {
107  bBigger = bool(eType & TableChgWidthHeightType::BiggerMode );
108  nMode = pTableNd->GetTable().GetTableChgMode();
109  }
110  CR_SetBoxWidth( const CR_SetBoxWidth& rCpy )
111  : pTableNd( rCpy.pTableNd ),
112  nDiff( rCpy.nDiff ), nSide( rCpy.nSide ),
113  nMaxSize( rCpy.nMaxSize ), nLowerDiff( 0 ),
114  nMode( rCpy.nMode ),
115  bBigger( rCpy.bBigger ), bLeft( rCpy.bLeft )
116  {
117  }
118 
119  void LoopClear()
120  {
121  nLowerDiff = 0;
122  }
123 };
124 
125 }
126 
127 static bool lcl_SetSelBoxWidth( SwTableLine* pLine, CR_SetBoxWidth& rParam,
128  SwTwips nDist, bool bCheck );
129 static bool lcl_SetOtherBoxWidth( SwTableLine* pLine, CR_SetBoxWidth& rParam,
130  SwTwips nDist, bool bCheck );
131 
132 typedef bool (*FN_lcl_SetBoxWidth)(SwTableLine*, CR_SetBoxWidth&, SwTwips, bool );
133 
134 #ifdef DBG_UTIL
135 
136 #define CHECKBOXWIDTH \
137  { \
138  SwTwips nSize = GetFrameFormat()->GetFrameSize().GetWidth(); \
139  for (size_t nTmp = 0; nTmp < m_aLines.size(); ++nTmp) \
140  ::CheckBoxWidth( *m_aLines[ nTmp ], nSize ); \
141  }
142 
143 #define CHECKTABLELAYOUT \
144  { \
145  for ( size_t i = 0; i < GetTabLines().size(); ++i ) \
146  { \
147  SwFrameFormat* pFormat = GetTabLines()[i]->GetFrameFormat(); \
148  SwIterator<SwRowFrame,SwFormat> aIter( *pFormat ); \
149  for (SwRowFrame* pFrame=aIter.First(); pFrame; pFrame=aIter.Next())\
150  { \
151  if ( pFrame->GetTabLine() == GetTabLines()[i] ) \
152  { \
153  OSL_ENSURE( pFrame->GetUpper()->IsTabFrame(), \
154  "Table layout does not match table structure" ); \
155  } \
156  } \
157  } \
158  }
159 
160 #else
161 
162 #define CHECKBOXWIDTH
163 #define CHECKTABLELAYOUT
164 
165 #endif // DBG_UTIL
166 
167 namespace {
168 
169 struct CR_SetLineHeight
170 {
171  SwTableNode* pTableNd;
172  SwTwips nMaxSpace, nMaxHeight;
173  TableChgMode nMode;
174  bool bBigger;
175 
176  CR_SetLineHeight( TableChgWidthHeightType eType, SwTableNode* pTNd )
177  : pTableNd( pTNd ),
178  nMaxSpace( 0 ), nMaxHeight( 0 )
179  {
180  bBigger = bool(eType & TableChgWidthHeightType::BiggerMode );
181  nMode = pTableNd->GetTable().GetTableChgMode();
182  }
183  CR_SetLineHeight( const CR_SetLineHeight& rCpy )
184  : pTableNd( rCpy.pTableNd ),
185  nMaxSpace( rCpy.nMaxSpace ), nMaxHeight( rCpy.nMaxHeight ),
186  nMode( rCpy.nMode ),
187  bBigger( rCpy.bBigger )
188  {}
189 };
190 
191 }
192 
193 static bool lcl_SetSelLineHeight( SwTableLine* pLine, const CR_SetLineHeight& rParam,
194  SwTwips nDist, bool bCheck );
195 static bool lcl_SetOtherLineHeight( SwTableLine* pLine, const CR_SetLineHeight& rParam,
196  SwTwips nDist, bool bCheck );
197 
198 typedef bool (*FN_lcl_SetLineHeight)(SwTableLine*, CR_SetLineHeight&, SwTwips, bool );
199 
201 
202 namespace {
203 
204 struct CpyPara
205 {
206  std::shared_ptr< std::vector< std::vector< sal_uLong > > > pWidths;
207  SwDoc& rDoc;
208  SwTableNode* pTableNd;
209  CpyTabFrames& rTabFrameArr;
210  SwTableLine* pInsLine;
211  SwTableBox* pInsBox;
212  sal_uLong nOldSize, nNewSize; // in order to correct the size attributes
213  sal_uLong nMinLeft, nMaxRight;
214  sal_uInt16 nCpyCnt, nInsPos;
215  sal_uInt16 nLnIdx, nBoxIdx;
216  sal_uInt8 nDelBorderFlag;
217  bool bCpyContent;
218 
219  CpyPara( SwTableNode* pNd, sal_uInt16 nCopies, CpyTabFrames& rFrameArr )
220  : rDoc( pNd->GetDoc() ), pTableNd( pNd ), rTabFrameArr(rFrameArr),
221  pInsLine(nullptr), pInsBox(nullptr), nOldSize(0), nNewSize(0),
222  nMinLeft(ULONG_MAX), nMaxRight(0),
223  nCpyCnt(nCopies), nInsPos(0),
224  nLnIdx(0), nBoxIdx(0),
225  nDelBorderFlag(0), bCpyContent( true )
226  {}
227  CpyPara( const CpyPara& rPara, SwTableLine* pLine )
228  : pWidths( rPara.pWidths ), rDoc(rPara.rDoc), pTableNd(rPara.pTableNd),
229  rTabFrameArr(rPara.rTabFrameArr), pInsLine(pLine), pInsBox(rPara.pInsBox),
230  nOldSize(0), nNewSize(rPara.nNewSize), nMinLeft( rPara.nMinLeft ),
231  nMaxRight( rPara.nMaxRight ), nCpyCnt(rPara.nCpyCnt), nInsPos(0),
232  nLnIdx( rPara.nLnIdx), nBoxIdx( rPara.nBoxIdx ),
233  nDelBorderFlag( rPara.nDelBorderFlag ), bCpyContent( rPara.bCpyContent )
234  {}
235  CpyPara( const CpyPara& rPara, SwTableBox* pBox )
236  : pWidths( rPara.pWidths ), rDoc(rPara.rDoc), pTableNd(rPara.pTableNd),
237  rTabFrameArr(rPara.rTabFrameArr), pInsLine(rPara.pInsLine), pInsBox(pBox),
238  nOldSize(rPara.nOldSize), nNewSize(rPara.nNewSize),
239  nMinLeft( rPara.nMinLeft ), nMaxRight( rPara.nMaxRight ),
240  nCpyCnt(rPara.nCpyCnt), nInsPos(0), nLnIdx(rPara.nLnIdx), nBoxIdx(rPara.nBoxIdx),
241  nDelBorderFlag( rPara.nDelBorderFlag ), bCpyContent( rPara.bCpyContent )
242  {}
243 };
244 
245 }
246 
247 static SwTableLine* lcl_CopyRow(FndLine_ & rFndLine, CpyPara *const pCpyPara);
248 
249 static void lcl_CopyCol( FndBox_ & rFndBox, CpyPara *const pCpyPara)
250 {
251  // Look up the Frame Format in the Frame Format Array
252  SwTableBox* pBox = rFndBox.GetBox();
253  CpyTabFrame aFindFrame(pBox->GetFrameFormat());
254 
255  if( pCpyPara->nCpyCnt )
256  {
257  sal_uInt16 nFndPos;
258  CpyTabFrames::const_iterator itFind = pCpyPara->rTabFrameArr.lower_bound( aFindFrame );
259  nFndPos = itFind - pCpyPara->rTabFrameArr.begin();
260  if( itFind == pCpyPara->rTabFrameArr.end() || !(*itFind == aFindFrame) )
261  {
262  // For nested copying, also save the new Format as an old one.
263  SwTableBoxFormat* pNewFormat = static_cast<SwTableBoxFormat*>(pBox->ClaimFrameFormat());
264 
265  // Find the selected Boxes in the Line:
266  FndLine_ const* pCmpLine = nullptr;
267  SwFormatFrameSize aFrameSz( pNewFormat->GetFrameSize() );
268 
269  bool bDiffCount = false;
270  if( !pBox->GetTabLines().empty() )
271  {
272  pCmpLine = rFndBox.GetLines().front().get();
273  if ( pCmpLine->GetBoxes().size() != pCmpLine->GetLine()->GetTabBoxes().size() )
274  bDiffCount = true;
275  }
276 
277  if( bDiffCount )
278  {
279  // The first Line should be enough
280  FndBoxes_t const& rFndBoxes = pCmpLine->GetBoxes();
281  tools::Long nSz = 0;
282  for( auto n = rFndBoxes.size(); n; )
283  {
284  nSz += rFndBoxes[--n]->GetBox()->
285  GetFrameFormat()->GetFrameSize().GetWidth();
286  }
287  aFrameSz.SetWidth( aFrameSz.GetWidth() -
288  nSz / ( pCpyPara->nCpyCnt + 1 ) );
289  pNewFormat->SetFormatAttr( aFrameSz );
290  aFrameSz.SetWidth( nSz / ( pCpyPara->nCpyCnt + 1 ) );
291 
292  // Create a new Format for the new Box, specifying its size.
293  aFindFrame.pNewFrameFormat = reinterpret_cast<SwTableBoxFormat*>(pNewFormat->GetDoc()->
294  MakeTableLineFormat());
295  *aFindFrame.pNewFrameFormat = *pNewFormat;
296  aFindFrame.pNewFrameFormat->SetFormatAttr( aFrameSz );
297  }
298  else
299  {
300  aFrameSz.SetWidth( aFrameSz.GetWidth() / ( pCpyPara->nCpyCnt + 1 ) );
301  pNewFormat->SetFormatAttr( aFrameSz );
302 
303  aFindFrame.pNewFrameFormat = pNewFormat;
304  pCpyPara->rTabFrameArr.insert( aFindFrame );
305  aFindFrame.pFrameFormat = pNewFormat;
306  pCpyPara->rTabFrameArr.insert( aFindFrame );
307  }
308  }
309  else
310  {
311  aFindFrame = pCpyPara->rTabFrameArr[ nFndPos ];
312  pBox->ChgFrameFormat( aFindFrame.pNewFrameFormat );
313  }
314  }
315  else
316  {
317  CpyTabFrames::const_iterator itFind = pCpyPara->rTabFrameArr.find( aFindFrame );
318  if( pCpyPara->nDelBorderFlag &&
319  itFind != pCpyPara->rTabFrameArr.end() )
320  aFindFrame = *itFind;
321  else
322  aFindFrame.pNewFrameFormat = static_cast<SwTableBoxFormat*>(pBox->GetFrameFormat());
323  }
324 
325  if (!rFndBox.GetLines().empty())
326  {
327  pBox = new SwTableBox( aFindFrame.pNewFrameFormat,
328  rFndBox.GetLines().size(), pCpyPara->pInsLine );
329  pCpyPara->pInsLine->GetTabBoxes().insert( pCpyPara->pInsLine->GetTabBoxes().begin() + pCpyPara->nInsPos++, pBox );
330  CpyPara aPara( *pCpyPara, pBox );
331  aPara.nDelBorderFlag &= 7;
332 
333  for (auto const& pFndLine : rFndBox.GetLines())
334  {
335  lcl_CopyRow(*pFndLine, &aPara);
336  }
337  }
338  else
339  {
340  ::InsTableBox( pCpyPara->rDoc, pCpyPara->pTableNd, pCpyPara->pInsLine,
341  aFindFrame.pNewFrameFormat, pBox, pCpyPara->nInsPos++ );
342 
343  const FndBoxes_t& rFndBxs = rFndBox.GetUpper()->GetBoxes();
344  if( 8 > pCpyPara->nDelBorderFlag
345  ? pCpyPara->nDelBorderFlag != 0
346  : &rFndBox == rFndBxs[rFndBxs.size() - 1].get())
347  {
348  const SvxBoxItem& rBoxItem = pBox->GetFrameFormat()->GetBox();
349  if( 8 > pCpyPara->nDelBorderFlag
350  ? rBoxItem.GetTop()
351  : rBoxItem.GetRight() )
352  {
353  aFindFrame.pFrameFormat = pBox->GetFrameFormat();
354 
355  SvxBoxItem aNew( rBoxItem );
356  if( 8 > pCpyPara->nDelBorderFlag )
357  aNew.SetLine( nullptr, SvxBoxItemLine::TOP );
358  else
359  aNew.SetLine( nullptr, SvxBoxItemLine::RIGHT );
360 
361  if( 1 == pCpyPara->nDelBorderFlag ||
362  8 == pCpyPara->nDelBorderFlag )
363  {
364  // For all Boxes that delete TopBorderLine, we copy after that
365  pBox = pCpyPara->pInsLine->GetTabBoxes()[
366  pCpyPara->nInsPos - 1 ];
367  }
368 
369  aFindFrame.pNewFrameFormat = static_cast<SwTableBoxFormat*>(pBox->GetFrameFormat());
370 
371  // Else we copy before that and the first Line keeps the TopLine
372  // and we remove it at the original
373  pBox->ClaimFrameFormat()->SetFormatAttr( aNew );
374 
375  if( !pCpyPara->nCpyCnt )
376  pCpyPara->rTabFrameArr.insert( aFindFrame );
377  }
378  }
379  }
380 }
381 
382 static SwTableLine* lcl_CopyRow(FndLine_& rFndLine, CpyPara *const pCpyPara)
383 {
384  SwTableLine* pNewLine = new SwTableLine(
385  static_cast<SwTableLineFormat*>(rFndLine.GetLine()->GetFrameFormat()),
386  rFndLine.GetBoxes().size(), pCpyPara->pInsBox );
387  if( pCpyPara->pInsBox )
388  {
389  SwTableLines& rLines = pCpyPara->pInsBox->GetTabLines();
390  rLines.insert( rLines.begin() + pCpyPara->nInsPos++, pNewLine );
391  }
392  else
393  {
394  SwTableLines& rLines = pCpyPara->pTableNd->GetTable().GetTabLines();
395  rLines.insert( rLines.begin() + pCpyPara->nInsPos++, pNewLine );
396  }
397 
398  CpyPara aPara( *pCpyPara, pNewLine );
399  for (auto const& it : rFndLine.GetBoxes())
400  {
401  lcl_CopyCol(*it, &aPara);
402  }
403 
404  pCpyPara->nDelBorderFlag &= 0xf8;
405 
406  return pNewLine;
407 }
408 
409 static void lcl_InsCol( FndLine_* pFndLn, CpyPara& rCpyPara, sal_uInt16 nCpyCnt,
410  bool bBehind )
411 {
412  // Bug 29124: Not only copy in the BaseLines. If possible, we go down as far as possible
413  FndBox_* pFBox;
414  if( 1 == pFndLn->GetBoxes().size() &&
415  !( pFBox = pFndLn->GetBoxes()[0].get() )->GetBox()->GetSttNd() )
416  {
417  // A Box with multiple Lines, so insert into these Lines
418  for (auto &rpLine : pFBox->GetLines())
419  {
420  lcl_InsCol( rpLine.get(), rCpyPara, nCpyCnt, bBehind );
421  }
422  }
423  else
424  {
425  rCpyPara.pInsLine = pFndLn->GetLine();
426  SwTableBox* pBox = pFndLn->GetBoxes()[ bBehind ?
427  pFndLn->GetBoxes().size()-1 : 0 ]->GetBox();
428  rCpyPara.nInsPos = pFndLn->GetLine()->GetBoxPos( pBox );
429  if( bBehind )
430  ++rCpyPara.nInsPos;
431 
432  for( sal_uInt16 n = 0; n < nCpyCnt; ++n )
433  {
434  if( n + 1 == nCpyCnt && bBehind )
435  rCpyPara.nDelBorderFlag = 9;
436  else
437  rCpyPara.nDelBorderFlag = 8;
438  for (auto const& it : pFndLn->GetBoxes())
439  {
440  lcl_CopyCol(*it, &rCpyPara);
441  }
442  }
443  }
444 }
445 
447 {
449  for( SwRowFrame* pFrame = aIter.First(); pFrame; pFrame = aIter.Next() )
450  if( pFrame->GetTabLine() == &rLine )
451  return pFrame;
452  return nullptr;
453 }
454 
455 bool SwTable::InsertCol( SwDoc& rDoc, const SwSelBoxes& rBoxes, sal_uInt16 nCnt, bool bBehind )
456 {
457  OSL_ENSURE( !rBoxes.empty() && nCnt, "No valid Box List" );
458  SwTableNode* pTableNd = const_cast<SwTableNode*>(rBoxes[0]->GetSttNd()->FindTableNode());
459  if( !pTableNd )
460  return false;
461 
462  bool bRes = true;
463  if( IsNewModel() )
464  bRes = NewInsertCol( rDoc, rBoxes, nCnt, bBehind );
465  else
466  {
467  // Find all Boxes/Lines
468  FndBox_ aFndBox( nullptr, nullptr );
469  {
470  FndPara aPara( rBoxes, &aFndBox );
471  ForEach_FndLineCopyCol( GetTabLines(), &aPara );
472  }
473  if( aFndBox.GetLines().empty() )
474  return false;
475 
476  SetHTMLTableLayout(std::shared_ptr<SwHTMLTableLayout>()); // Delete HTML Layout
477 
478  // Find Lines for the layout update
479  aFndBox.SetTableLines( *this );
480  aFndBox.DelFrames( *this );
481 
482  // TL_CHART2: nothing to be done since chart2 currently does not want to
483  // get notified about new rows/cols.
484 
485  CpyTabFrames aTabFrameArr;
486  CpyPara aCpyPara( pTableNd, nCnt, aTabFrameArr );
487 
488  for (auto & rpLine : aFndBox.GetLines())
489  {
490  lcl_InsCol( rpLine.get(), aCpyPara, nCnt, bBehind );
491  }
492 
493  // clean up this Line's structure once again, generally all of them
494  GCLines();
495 
496  // Update Layout
497  aFndBox.MakeFrames( *this );
498 
501  bRes = true;
502  }
503 
505  if (pPCD && nCnt)
506  pPCD->AddRowCols( *this, rBoxes, nCnt, bBehind );
507  rDoc.UpdateCharts( GetFrameFormat()->GetName() );
508 
510 
511  return bRes;
512 }
513 
514 bool SwTable::InsertRow_( SwDoc* pDoc, const SwSelBoxes& rBoxes,
515  sal_uInt16 nCnt, bool bBehind )
516 {
517  OSL_ENSURE( pDoc && !rBoxes.empty() && nCnt, "No valid Box List" );
518  SwTableNode* pTableNd = const_cast<SwTableNode*>(rBoxes[0]->GetSttNd()->FindTableNode());
519  if( !pTableNd )
520  return false;
521 
522  // Find all Boxes/Lines
523  FndBox_ aFndBox( nullptr, nullptr );
524  {
525  FndPara aPara( rBoxes, &aFndBox );
526  ForEach_FndLineCopyCol( GetTabLines(), &aPara );
527  }
528  if( aFndBox.GetLines().empty() )
529  return false;
530 
531  SetHTMLTableLayout(std::shared_ptr<SwHTMLTableLayout>()); // Delete HTML Layout
532 
533  FndBox_* pFndBox = &aFndBox;
534  {
535  FndLine_* pFndLine;
536  while( 1 == pFndBox->GetLines().size() )
537  {
538  pFndLine = pFndBox->GetLines()[0].get();
539  if( 1 != pFndLine->GetBoxes().size() )
540  break;
541  // Don't go down too far! One Line with Box needs to remain!
542  FndBox_ *const pTmpBox = pFndLine->GetBoxes().front().get();
543  if( !pTmpBox->GetLines().empty() )
544  pFndBox = pTmpBox;
545  else
546  break;
547  }
548  }
549 
550  // Find Lines for the layout update
551  const bool bLayout = !IsNewModel() &&
552  nullptr != SwIterator<SwTabFrame,SwFormat>( *GetFrameFormat() ).First();
553 
554  if ( bLayout )
555  {
556  aFndBox.SetTableLines( *this );
557  if( pFndBox != &aFndBox )
558  aFndBox.DelFrames( *this );
559  // TL_CHART2: nothing to be done since chart2 currently does not want to
560  // get notified about new rows/cols.
561  }
562 
563  CpyTabFrames aTabFrameArr;
564  CpyPara aCpyPara( pTableNd, 0, aTabFrameArr );
565 
566  SwTableLine* pLine = pFndBox->GetLines()[ bBehind ?
567  pFndBox->GetLines().size()-1 : 0 ]->GetLine();
568  if( &aFndBox == pFndBox )
569  aCpyPara.nInsPos = GetTabLines().GetPos( pLine );
570  else
571  {
572  aCpyPara.pInsBox = pFndBox->GetBox();
573  aCpyPara.nInsPos = pFndBox->GetBox()->GetTabLines().GetPos( pLine );
574  }
575 
576  if( bBehind )
577  {
578  ++aCpyPara.nInsPos;
579  aCpyPara.nDelBorderFlag = 1;
580  }
581  else
582  aCpyPara.nDelBorderFlag = 2;
583 
584  for( sal_uInt16 nCpyCnt = 0; nCpyCnt < nCnt; ++nCpyCnt )
585  {
586  if( bBehind )
587  aCpyPara.nDelBorderFlag = 1;
588  for (auto & rpFndLine : pFndBox->GetLines())
589  {
590  SwTableLine* pNewTableLine = lcl_CopyRow( *rpFndLine, &aCpyPara );
591 
592  // tracked insertion of empty table line
593  if ( pDoc->getIDocumentRedlineAccess().IsRedlineOn() )
594  {
595  SvxPrintItem aSetTracking(RES_PRINT, false);
596  SwPosition aPos(*pNewTableLine->GetTabBoxes()[0]->GetSttNd());
597  SwCursor aCursor( aPos, nullptr );
598  SwNodeIndex aInsPos(*pNewTableLine->GetTabBoxes()[0]->GetSttNd(), 1 );
599  SwPaM aPaM(aInsPos);
601  OUStringChar(CH_TXT_TRACKED_DUMMY_CHAR) );
602  pDoc->SetRowNotTracked( aCursor, aSetTracking );
603  }
604  }
605  }
606 
607  // clean up this Line's structure once again, generally all of them
608  if( !pDoc->IsInReading() )
609  GCLines();
610 
611  // Update Layout
612  if ( bLayout )
613  {
614  if( pFndBox != &aFndBox )
615  aFndBox.MakeFrames( *this );
616  else
617  aFndBox.MakeNewFrames( *this, nCnt, bBehind );
618  }
619 
622 
624  if (pPCD && nCnt)
625  pPCD->AddRowCols( *this, rBoxes, nCnt, bBehind );
626  pDoc->UpdateCharts( GetFrameFormat()->GetName() );
627 
628  pDoc->GetDocShell()->GetFEShell()->UpdateTableStyleFormatting(pTableNd);
629 
630  return true;
631 }
632 
633 static void lcl_LastBoxSetWidth( SwTableBoxes &rBoxes, const tools::Long nOffset,
634  bool bFirst, SwShareBoxFormats& rShareFormats );
635 
636 static void lcl_LastBoxSetWidthLine( SwTableLines &rLines, const tools::Long nOffset,
637  bool bFirst, SwShareBoxFormats& rShareFormats )
638 {
639  for ( auto pLine : rLines )
640  ::lcl_LastBoxSetWidth( pLine->GetTabBoxes(), nOffset, bFirst, rShareFormats );
641 }
642 
643 static void lcl_LastBoxSetWidth( SwTableBoxes &rBoxes, const tools::Long nOffset,
644  bool bFirst, SwShareBoxFormats& rShareFormats )
645 {
646  SwTableBox& rBox = *(bFirst ? rBoxes.front() : rBoxes.back());
647  if( !rBox.GetSttNd() )
648  ::lcl_LastBoxSetWidthLine( rBox.GetTabLines(), nOffset,
649  bFirst, rShareFormats );
650 
651  // Adapt the Box
652  const SwFrameFormat *pBoxFormat = rBox.GetFrameFormat();
653  SwFormatFrameSize aNew( pBoxFormat->GetFrameSize() );
654  aNew.SetWidth( aNew.GetWidth() + nOffset );
655  SwFrameFormat *pFormat = rShareFormats.GetFormat( *pBoxFormat, aNew );
656  if( pFormat )
657  rBox.ChgFrameFormat( static_cast<SwTableBoxFormat*>(pFormat) );
658  else
659  {
660  pFormat = rBox.ClaimFrameFormat();
661 
662  pFormat->LockModify();
663  pFormat->SetFormatAttr( aNew );
664  pFormat->UnlockModify();
665 
666  rShareFormats.AddFormat( *pBoxFormat, *pFormat );
667  }
668 }
669 
670 void DeleteBox_( SwTable& rTable, SwTableBox* pBox, SwUndo* pUndo,
671  bool bCalcNewSize, const bool bCorrBorder,
672  SwShareBoxFormats* pShareFormats )
673 {
674  do {
675  SwTwips nBoxSz = bCalcNewSize ?
676  pBox->GetFrameFormat()->GetFrameSize().GetWidth() : 0;
677  SwTableLine* pLine = pBox->GetUpper();
678  SwTableBoxes& rTableBoxes = pLine->GetTabBoxes();
679  sal_uInt16 nDelPos = pLine->GetBoxPos( pBox );
680  SwTableBox* pUpperBox = pBox->GetUpper()->GetUpper();
681 
682  // Special treatment for the border:
683  if( bCorrBorder && 1 < rTableBoxes.size() )
684  {
685  const SvxBoxItem& rBoxItem = pBox->GetFrameFormat()->GetBox();
686 
687  if( rBoxItem.GetLeft() || rBoxItem.GetRight() )
688  {
689  bool bChgd = false;
690 
691  // JP 02.04.97: 1st part for Bug 36271
692  // First the left/right edges
693  if( nDelPos + 1 < o3tl::narrowing<sal_uInt16>(rTableBoxes.size()) )
694  {
695  SwTableBox* pNxtBox = rTableBoxes[ nDelPos + 1 ];
696  const SvxBoxItem& rNxtBoxItem = pNxtBox->GetFrameFormat()->GetBox();
697 
698  SwTableBox* pPrvBox = nDelPos ? rTableBoxes[ nDelPos - 1 ] : nullptr;
699 
700  if( pNxtBox->GetSttNd() && !rNxtBoxItem.GetLeft() &&
701  ( !pPrvBox || !pPrvBox->GetFrameFormat()->GetBox().GetRight()) )
702  {
703  SvxBoxItem aTmp( rNxtBoxItem );
704  aTmp.SetLine( rBoxItem.GetLeft() ? rBoxItem.GetLeft()
705  : rBoxItem.GetRight(),
706  SvxBoxItemLine::LEFT );
707  if( pShareFormats )
708  pShareFormats->SetAttr( *pNxtBox, aTmp );
709  else
710  pNxtBox->ClaimFrameFormat()->SetFormatAttr( aTmp );
711  bChgd = true;
712  }
713  }
714  if( !bChgd && nDelPos )
715  {
716  SwTableBox* pPrvBox = rTableBoxes[ nDelPos - 1 ];
717  const SvxBoxItem& rPrvBoxItem = pPrvBox->GetFrameFormat()->GetBox();
718 
719  SwTableBox* pNxtBox = nDelPos + 1 < o3tl::narrowing<sal_uInt16>(rTableBoxes.size())
720  ? rTableBoxes[ nDelPos + 1 ] : nullptr;
721 
722  if( pPrvBox->GetSttNd() && !rPrvBoxItem.GetRight() &&
723  ( !pNxtBox || !pNxtBox->GetFrameFormat()->GetBox().GetLeft()) )
724  {
725  SvxBoxItem aTmp( rPrvBoxItem );
726  aTmp.SetLine( rBoxItem.GetLeft() ? rBoxItem.GetLeft()
727  : rBoxItem.GetRight(),
728  SvxBoxItemLine::RIGHT );
729  if( pShareFormats )
730  pShareFormats->SetAttr( *pPrvBox, aTmp );
731  else
732  pPrvBox->ClaimFrameFormat()->SetFormatAttr( aTmp );
733  }
734  }
735  }
736  }
737 
738  // Delete the Box first, then the Nodes!
739  SwStartNode* pSttNd = const_cast<SwStartNode*>(pBox->GetSttNd());
740  if( pShareFormats )
741  pShareFormats->RemoveFormat( *rTableBoxes[ nDelPos ]->GetFrameFormat() );
742 
743  // Before deleting the 'Table Box' from memory - delete any redlines attached to it
744  rTable.GetFrameFormat()->GetDoc()->getIDocumentRedlineAccess().GetExtraRedlineTable().DeleteTableCellRedline( rTable.GetFrameFormat()->GetDoc(), *(rTableBoxes[nDelPos]), true, RedlineType::Any );
745  delete rTableBoxes[nDelPos];
746  rTableBoxes.erase( rTableBoxes.begin() + nDelPos );
747 
748  if( pSttNd )
749  {
750  // Has the UndoObject been prepared to save the Section?
751  if( pUndo && pUndo->IsDelBox() )
752  static_cast<SwUndoTableNdsChg*>(pUndo)->SaveSection( pSttNd );
753  else
754  pSttNd->GetDoc().getIDocumentContentOperations().DeleteSection( pSttNd );
755  }
756 
757  // Also delete the Line?
758  if( !rTableBoxes.empty() )
759  {
760  // Then adapt the Frame-SSize
761  bool bLastBox = nDelPos == rTableBoxes.size();
762  if( bLastBox )
763  --nDelPos;
764  pBox = rTableBoxes[nDelPos];
765  if( bCalcNewSize )
766  {
767  SwFormatFrameSize aNew( pBox->GetFrameFormat()->GetFrameSize() );
768  aNew.SetWidth( aNew.GetWidth() + nBoxSz );
769  if( pShareFormats )
770  pShareFormats->SetSize( *pBox, aNew );
771  else
772  pBox->ClaimFrameFormat()->SetFormatAttr( aNew );
773 
774  if( !pBox->GetSttNd() )
775  {
776  // We need to this recursively in all Lines in all Cells!
777  SwShareBoxFormats aShareFormats;
778  ::lcl_LastBoxSetWidthLine( pBox->GetTabLines(), nBoxSz,
779  !bLastBox,
780  pShareFormats ? *pShareFormats
781  : aShareFormats );
782  }
783  }
784  break; // Stop deleting
785  }
786  // Delete the Line from the Table/Box
787  if( !pUpperBox )
788  {
789  // Also delete the Line from the Table
790  nDelPos = rTable.GetTabLines().GetPos( pLine );
791  if( pShareFormats )
792  pShareFormats->RemoveFormat( *rTable.GetTabLines()[ nDelPos ]->GetFrameFormat() );
793 
794  SwTableLine* pTabLineToDelete = rTable.GetTabLines()[ nDelPos ];
795  // Before deleting the 'Table Line' from memory - delete any redlines attached to it
796  rTable.GetFrameFormat()->GetDoc()->getIDocumentRedlineAccess().GetExtraRedlineTable().DeleteTableRowRedline( rTable.GetFrameFormat()->GetDoc(), *pTabLineToDelete, true, RedlineType::Any );
797  delete pTabLineToDelete;
798  rTable.GetTabLines().erase( rTable.GetTabLines().begin() + nDelPos );
799  break; // we cannot delete more
800  }
801 
802  // finally also delete the Line
803  pBox = pUpperBox;
804  nDelPos = pBox->GetTabLines().GetPos( pLine );
805  if( pShareFormats )
806  pShareFormats->RemoveFormat( *pBox->GetTabLines()[ nDelPos ]->GetFrameFormat() );
807 
808  SwTableLine* pTabLineToDelete = pBox->GetTabLines()[ nDelPos ];
809  // Before deleting the 'Table Line' from memory - delete any redlines attached to it
810  rTable.GetFrameFormat()->GetDoc()->getIDocumentRedlineAccess().GetExtraRedlineTable().DeleteTableRowRedline( rTable.GetFrameFormat()->GetDoc(), *pTabLineToDelete, true, RedlineType::Any );
811  delete pTabLineToDelete;
812  pBox->GetTabLines().erase( pBox->GetTabLines().begin() + nDelPos );
813  } while( pBox->GetTabLines().empty() );
814 }
815 
816 static SwTableBox*
818  SwTwips nBoxStt, SwTwips nBoxWidth,
819  sal_uInt16 nLinePos, bool bNxt,
820  SwSelBoxes* pAllDelBoxes, size_t *const pCurPos)
821 {
822  SwTableBox* pFndBox = nullptr;
823  do {
824  if( bNxt )
825  ++nLinePos;
826  else
827  --nLinePos;
828  SwTableLine* pLine = rTableLns[ nLinePos ];
829  SwTwips nFndBoxWidth = 0;
830  SwTwips nFndWidth = nBoxStt + nBoxWidth;
831 
832  pFndBox = pLine->GetTabBoxes()[ 0 ];
833  for( auto pBox : pLine->GetTabBoxes() )
834  {
835  if ( nFndWidth <= 0 )
836  {
837  break;
838  }
839  pFndBox = pBox;
840  nFndBoxWidth = pFndBox->GetFrameFormat()->GetFrameSize().GetWidth();
841  nFndWidth -= nFndBoxWidth;
842  }
843 
844  // Find the first ContentBox
845  while( !pFndBox->GetSttNd() )
846  {
847  const SwTableLines& rLowLns = pFndBox->GetTabLines();
848  if( bNxt )
849  pFndBox = rLowLns.front()->GetTabBoxes().front();
850  else
851  pFndBox = rLowLns.back()->GetTabBoxes().front();
852  }
853 
854  if( std::abs( nFndWidth ) > COLFUZZY ||
855  std::abs( nBoxWidth - nFndBoxWidth ) > COLFUZZY )
856  pFndBox = nullptr;
857  else if( pAllDelBoxes )
858  {
859  // If the predecessor will also be deleted, there's nothing to do
860  SwSelBoxes::const_iterator aFndIt = pAllDelBoxes->find( pFndBox);
861  if( aFndIt == pAllDelBoxes->end() )
862  break;
863  size_t const nFndPos = aFndIt - pAllDelBoxes->begin() ;
864 
865  // else, we keep on searching.
866  // We do not need to recheck the Box, however
867  pFndBox = nullptr;
868  if( nFndPos <= *pCurPos )
869  --*pCurPos;
870  pAllDelBoxes->erase( pAllDelBoxes->begin() + nFndPos );
871  }
872  } while( bNxt ? ( nLinePos + 1 < o3tl::narrowing<sal_uInt16>(rTableLns.size()) ) : nLinePos != 0 );
873  return pFndBox;
874 }
875 
876 static void
878  SwShareBoxFormats& rShareFormats,
879  SwSelBoxes* pAllDelBoxes = nullptr,
880  size_t *const pCurPos = nullptr )
881 {
882 //JP 16.04.97: 2. part for Bug 36271
883  const SwTableLine* pLine = rBox.GetUpper();
884  const SwTableBoxes& rTableBoxes = pLine->GetTabBoxes();
885  const SwTableBox* pUpperBox = &rBox;
886  sal_uInt16 nDelPos = pLine->GetBoxPos( pUpperBox );
887  pUpperBox = rBox.GetUpper()->GetUpper();
888  const SvxBoxItem& rBoxItem = rBox.GetFrameFormat()->GetBox();
889 
890  // then the top/bottom edges
891  if( !rBoxItem.GetTop() && !rBoxItem.GetBottom() )
892  return;
893 
894  bool bChgd = false;
895  const SwTableLines* pTableLns;
896  if( pUpperBox )
897  pTableLns = &pUpperBox->GetTabLines();
898  else
899  pTableLns = &rTable.GetTabLines();
900 
901  sal_uInt16 nLnPos = pTableLns->GetPos( pLine );
902 
903  // Calculate the attribute position of the top-be-deleted Box and then
904  // search in the top/bottom Line of the respective counterparts.
905  SwTwips nBoxStt = 0;
906  for( sal_uInt16 n = 0; n < nDelPos; ++n )
907  nBoxStt += rTableBoxes[ n ]->GetFrameFormat()->GetFrameSize().GetWidth();
908  SwTwips nBoxWidth = rBox.GetFrameFormat()->GetFrameSize().GetWidth();
909 
910  SwTableBox *pPrvBox = nullptr, *pNxtBox = nullptr;
911  if( nLnPos ) // Predecessor?
912  pPrvBox = ::lcl_FndNxtPrvDelBox( *pTableLns, nBoxStt, nBoxWidth,
913  nLnPos, false, pAllDelBoxes, pCurPos );
914 
915  if( nLnPos + 1 < o3tl::narrowing<sal_uInt16>(pTableLns->size()) ) // Successor?
916  pNxtBox = ::lcl_FndNxtPrvDelBox( *pTableLns, nBoxStt, nBoxWidth,
917  nLnPos, true, pAllDelBoxes, pCurPos );
918 
919  if( pNxtBox && pNxtBox->GetSttNd() )
920  {
921  const SvxBoxItem& rNxtBoxItem = pNxtBox->GetFrameFormat()->GetBox();
922  if( !rNxtBoxItem.GetTop() && ( !pPrvBox ||
923  !pPrvBox->GetFrameFormat()->GetBox().GetBottom()) )
924  {
925  SvxBoxItem aTmp( rNxtBoxItem );
926  aTmp.SetLine( rBoxItem.GetTop() ? rBoxItem.GetTop()
927  : rBoxItem.GetBottom(),
928  SvxBoxItemLine::TOP );
929  rShareFormats.SetAttr( *pNxtBox, aTmp );
930  bChgd = true;
931  }
932  }
933  if( !(!bChgd && pPrvBox && pPrvBox->GetSttNd()) )
934  return;
935 
936  const SvxBoxItem& rPrvBoxItem = pPrvBox->GetFrameFormat()->GetBox();
937  if( !rPrvBoxItem.GetTop() && ( !pNxtBox ||
938  !pNxtBox->GetFrameFormat()->GetBox().GetTop()) )
939  {
940  SvxBoxItem aTmp( rPrvBoxItem );
941  aTmp.SetLine( rBoxItem.GetTop() ? rBoxItem.GetTop()
942  : rBoxItem.GetBottom(),
943  SvxBoxItemLine::BOTTOM );
944  rShareFormats.SetAttr( *pPrvBox, aTmp );
945  }
946 
947 }
948 
950  SwDoc* pDoc
951  ,
952  const SwSelBoxes& rBoxes,
953  const SwSelBoxes* pMerged, SwUndo* pUndo,
954  const bool bDelMakeFrames, const bool bCorrBorder )
955 {
956  OSL_ENSURE( pDoc, "No doc?" );
957  SwTableNode* pTableNd = nullptr;
958  if( !rBoxes.empty() )
959  {
960  pTableNd = const_cast<SwTableNode*>(rBoxes[0]->GetSttNd()->FindTableNode());
961  if( !pTableNd )
962  return false;
963  }
964 
965  SetHTMLTableLayout(std::shared_ptr<SwHTMLTableLayout>()); // Delete HTML Layout
966 
967  // Find Lines for the Layout update
968  FndBox_ aFndBox( nullptr, nullptr );
969  if ( bDelMakeFrames )
970  {
971  if( pMerged && !pMerged->empty() )
972  aFndBox.SetTableLines( *pMerged, *this );
973  else if( !rBoxes.empty() )
974  aFndBox.SetTableLines( rBoxes, *this );
975  aFndBox.DelFrames( *this );
976  }
977 
978  SwShareBoxFormats aShareFormats;
979 
980  // First switch the Border, then delete
981  if( bCorrBorder )
982  {
983  SwSelBoxes aBoxes( rBoxes );
984  for (size_t n = 0; n < aBoxes.size(); ++n)
985  {
986  ::lcl_SaveUpperLowerBorder( *this, *rBoxes[ n ], aShareFormats,
987  &aBoxes, &n );
988  }
989  }
990 
991  PrepareDelBoxes( rBoxes );
992 
994  // Delete boxes from last to first
995  for (size_t n = 0; n < rBoxes.size(); ++n)
996  {
997  size_t const nIdx = rBoxes.size() - 1 - n;
998 
999  // First adapt the data-sequence for chart if necessary
1000  // (needed to move the implementation cursor properly to its new
1001  // position which can't be done properly if the cell is already gone)
1002  if (pPCD && pTableNd)
1003  pPCD->DeleteBox( &pTableNd->GetTable(), *rBoxes[nIdx] );
1004 
1005  // ... then delete the boxes
1006  DeleteBox_( *this, rBoxes[nIdx], pUndo, true, bCorrBorder, &aShareFormats );
1007  }
1008 
1009  // then clean up the structure of all Lines
1010  GCLines();
1011 
1012  if( bDelMakeFrames && aFndBox.AreLinesToRestore( *this ) )
1013  aFndBox.MakeFrames( *this );
1014 
1015  // TL_CHART2: now inform chart that sth has changed
1016  pDoc->UpdateCharts( GetFrameFormat()->GetName() );
1017 
1019  CHECK_TABLE( *this );
1020 
1021  return true;
1022 }
1023 
1024 bool SwTable::OldSplitRow( SwDoc& rDoc, const SwSelBoxes& rBoxes, sal_uInt16 nCnt,
1025  bool bSameHeight )
1026 {
1027  OSL_ENSURE( !rBoxes.empty() && nCnt, "No valid values" );
1028  SwTableNode* pTableNd = const_cast<SwTableNode*>(rBoxes[0]->GetSttNd()->FindTableNode());
1029  if( !pTableNd )
1030  return false;
1031 
1032  // TL_CHART2: splitting/merging of a number of cells or rows will usually make
1033  // the table too complex to be handled with chart.
1034  // Thus we tell the charts to use their own data provider and forget about this table
1036 
1037  SetHTMLTableLayout(std::shared_ptr<SwHTMLTableLayout>()); // Delete HTML Layout
1038 
1039  // If the rows should get the same (min) height, we first have
1040  // to store the old row heights before deleting the frames
1041  std::unique_ptr<tools::Long[]> pRowHeights;
1042  if ( bSameHeight )
1043  {
1044  pRowHeights.reset(new tools::Long[ rBoxes.size() ]);
1045  for (size_t n = 0; n < rBoxes.size(); ++n)
1046  {
1047  SwTableBox* pSelBox = rBoxes[n];
1048  const SwRowFrame* pRow = GetRowFrame( *pSelBox->GetUpper() );
1049  OSL_ENSURE( pRow, "Where is the SwTableLine's Frame?" );
1050  SwRectFnSet aRectFnSet(pRow);
1051  pRowHeights[ n ] = aRectFnSet.GetHeight(pRow->getFrameArea());
1052  }
1053  }
1054 
1055  // Find Lines for the Layout update
1056  FndBox_ aFndBox( nullptr, nullptr );
1057  aFndBox.SetTableLines( rBoxes, *this );
1058  aFndBox.DelFrames( *this );
1059 
1060  for (size_t n = 0; n < rBoxes.size(); ++n)
1061  {
1062  SwTableBox* pSelBox = rBoxes[n];
1063  OSL_ENSURE( pSelBox, "Box is not within the Table" );
1064 
1065  // Insert nCnt new Lines into the Box
1066  SwTableLine* pInsLine = pSelBox->GetUpper();
1067  SwTableBoxFormat* pFrameFormat = static_cast<SwTableBoxFormat*>(pSelBox->GetFrameFormat());
1068 
1069  // Respect the Line's height, reset if needed
1070  SwFormatFrameSize aFSz( pInsLine->GetFrameFormat()->GetFrameSize() );
1071  if ( bSameHeight && SwFrameSize::Variable == aFSz.GetHeightSizeType() )
1073 
1074  bool bChgLineSz = 0 != aFSz.GetHeight() || bSameHeight;
1075  if ( bChgLineSz )
1076  aFSz.SetHeight( ( bSameHeight ? pRowHeights[ n ] : aFSz.GetHeight() ) /
1077  (nCnt + 1) );
1078 
1079  SwTableBox* pNewBox = new SwTableBox( pFrameFormat, nCnt, pInsLine );
1080  sal_uInt16 nBoxPos = pInsLine->GetBoxPos( pSelBox );
1081  pInsLine->GetTabBoxes()[nBoxPos] = pNewBox; // overwrite old one
1082 
1083  // Delete background/border attribute
1084  SwTableBox* pLastBox = pSelBox; // To distribute the TextNodes!
1085  // If Areas are contained in the Box, it stays as is
1086  // !! If this is changed we need to adapt the Undo, too !!!
1087  bool bMoveNodes = true;
1088  {
1089  SwNodeOffset nSttNd = pLastBox->GetSttIdx() + 1,
1090  nEndNd = pLastBox->GetSttNd()->EndOfSectionIndex();
1091  while( nSttNd < nEndNd )
1092  if( !rDoc.GetNodes()[ nSttNd++ ]->IsTextNode() )
1093  {
1094  bMoveNodes = false;
1095  break;
1096  }
1097  }
1098 
1099  SwTableBoxFormat* pCpyBoxFrameFormat = static_cast<SwTableBoxFormat*>(pSelBox->GetFrameFormat());
1100  bool bChkBorder = nullptr != pCpyBoxFrameFormat->GetBox().GetTop();
1101  if( bChkBorder )
1102  pCpyBoxFrameFormat = static_cast<SwTableBoxFormat*>(pSelBox->ClaimFrameFormat());
1103 
1104  for( sal_uInt16 i = 0; i <= nCnt; ++i )
1105  {
1106  // Create a new Line in the new Box
1107  SwTableLine* pNewLine = new SwTableLine(
1108  static_cast<SwTableLineFormat*>(pInsLine->GetFrameFormat()), 1, pNewBox );
1109  if( bChgLineSz )
1110  {
1111  pNewLine->ClaimFrameFormat()->SetFormatAttr( aFSz );
1112  }
1113 
1114  pNewBox->GetTabLines().insert( pNewBox->GetTabLines().begin() + i, pNewLine );
1115  // then a new Box in the Line
1116  if( !i ) // hang up the original Box
1117  {
1118  pSelBox->SetUpper( pNewLine );
1119  pNewLine->GetTabBoxes().insert( pNewLine->GetTabBoxes().begin(), pSelBox );
1120  }
1121  else
1122  {
1123  ::InsTableBox( rDoc, pTableNd, pNewLine, pCpyBoxFrameFormat,
1124  pLastBox, 0 );
1125 
1126  if( bChkBorder )
1127  {
1128  pCpyBoxFrameFormat = static_cast<SwTableBoxFormat*>(pNewLine->GetTabBoxes()[ 0 ]->ClaimFrameFormat());
1129  SvxBoxItem aTmp( pCpyBoxFrameFormat->GetBox() );
1130  aTmp.SetLine( nullptr, SvxBoxItemLine::TOP );
1131  pCpyBoxFrameFormat->SetFormatAttr( aTmp );
1132  bChkBorder = false;
1133  }
1134 
1135  if( bMoveNodes )
1136  {
1137  const SwNode* pEndNd = pLastBox->GetSttNd()->EndOfSectionNode();
1138  if( pLastBox->GetSttIdx()+SwNodeOffset(2) != pEndNd->GetIndex() )
1139  {
1140  // Move TextNodes
1141  SwNodeRange aRg( *pLastBox->GetSttNd(), SwNodeOffset(+2), *pEndNd );
1142  pLastBox = pNewLine->GetTabBoxes()[0]; // reset
1143  SwNodeIndex aInsPos( *pLastBox->GetSttNd(), 1 );
1144  rDoc.GetNodes().MoveNodes(aRg, rDoc.GetNodes(), aInsPos, false);
1145  rDoc.GetNodes().Delete( aInsPos ); // delete the empty one
1146  }
1147  }
1148  }
1149  }
1150  // In Boxes with Lines, we can only have Size/Fillorder
1151  pFrameFormat = static_cast<SwTableBoxFormat*>(pNewBox->ClaimFrameFormat());
1152  pFrameFormat->ResetFormatAttr( RES_LR_SPACE, RES_FRMATR_END - 1 );
1153  pFrameFormat->ResetFormatAttr( RES_BOXATR_BEGIN, RES_BOXATR_END - 1 );
1154  }
1155 
1156  pRowHeights.reset();
1157 
1158  GCLines();
1159 
1160  aFndBox.MakeFrames( *this );
1161 
1164  return true;
1165 }
1166 
1167 bool SwTable::SplitCol(SwDoc& rDoc, const SwSelBoxes& rBoxes, sal_uInt16 nCnt)
1168 {
1169  OSL_ENSURE( !rBoxes.empty() && nCnt, "No valid values" );
1170  SwTableNode* pTableNd = const_cast<SwTableNode*>(rBoxes[0]->GetSttNd()->FindTableNode());
1171  if( !pTableNd )
1172  return false;
1173 
1174  // TL_CHART2: splitting/merging of a number of cells or rows will usually make
1175  // the table too complex to be handled with chart.
1176  // Thus we tell the charts to use their own data provider and forget about this table
1178 
1179  SetHTMLTableLayout(std::shared_ptr<SwHTMLTableLayout>()); // Delete HTML Layout
1180  SwSelBoxes aSelBoxes(rBoxes);
1181  ExpandSelection( aSelBoxes );
1182 
1183  // Find Lines for the Layout update
1184  FndBox_ aFndBox( nullptr, nullptr );
1185  aFndBox.SetTableLines( aSelBoxes, *this );
1186  aFndBox.DelFrames( *this );
1187 
1188  CpyTabFrames aFrameArr;
1189  std::vector<SwTableBoxFormat*> aLastBoxArr;
1190  for (size_t n = 0; n < aSelBoxes.size(); ++n)
1191  {
1192  SwTableBox* pSelBox = aSelBoxes[n];
1193  OSL_ENSURE( pSelBox, "Box is not in the table" );
1194 
1195  // We don't want to split small table cells into very very small cells
1196  if( pSelBox->GetFrameFormat()->GetFrameSize().GetWidth()/( nCnt + 1 ) < 10 )
1197  continue;
1198 
1199  // Then split the nCnt Box up into nCnt Boxes
1200  SwTableLine* pInsLine = pSelBox->GetUpper();
1201  sal_uInt16 nBoxPos = pInsLine->GetBoxPos( pSelBox );
1202 
1203  // Find the Frame Format in the Frame Format Array
1204  SwTableBoxFormat* pLastBoxFormat;
1205  CpyTabFrame aFindFrame( static_cast<SwTableBoxFormat*>(pSelBox->GetFrameFormat()) );
1206  CpyTabFrames::const_iterator itFind = aFrameArr.lower_bound( aFindFrame );
1207  const size_t nFndPos = itFind - aFrameArr.begin();
1208  if( itFind == aFrameArr.end() || !(*itFind == aFindFrame) )
1209  {
1210  // Change the FrameFormat
1211  aFindFrame.pNewFrameFormat = static_cast<SwTableBoxFormat*>(pSelBox->ClaimFrameFormat());
1212  SwTwips nBoxSz = aFindFrame.pNewFrameFormat->GetFrameSize().GetWidth();
1213  SwTwips nNewBoxSz = nBoxSz / ( nCnt + 1 );
1214  aFindFrame.pNewFrameFormat->SetFormatAttr( SwFormatFrameSize( SwFrameSize::Variable,
1215  nNewBoxSz, 0 ) );
1216  aFrameArr.insert( aFindFrame );
1217 
1218  pLastBoxFormat = aFindFrame.pNewFrameFormat;
1219  if( nBoxSz != ( nNewBoxSz * (nCnt + 1)))
1220  {
1221  // We have a remainder, so we need to define an own Format
1222  // for the last Box.
1223  pLastBoxFormat = new SwTableBoxFormat( *aFindFrame.pNewFrameFormat );
1225  nBoxSz - ( nNewBoxSz * nCnt ), 0 ) );
1226  }
1227  aLastBoxArr.insert( aLastBoxArr.begin() + nFndPos, pLastBoxFormat );
1228  }
1229  else
1230  {
1231  aFindFrame = aFrameArr[ nFndPos ];
1232  pSelBox->ChgFrameFormat( aFindFrame.pNewFrameFormat );
1233  pLastBoxFormat = aLastBoxArr[ nFndPos ];
1234  }
1235 
1236  // Insert the Boxes at the Position
1237  for( sal_uInt16 i = 1; i < nCnt; ++i )
1238  ::InsTableBox( rDoc, pTableNd, pInsLine, aFindFrame.pNewFrameFormat,
1239  pSelBox, nBoxPos + i ); // insert after
1240 
1241  ::InsTableBox( rDoc, pTableNd, pInsLine, pLastBoxFormat,
1242  pSelBox, nBoxPos + nCnt ); // insert after
1243 
1244  // Special treatment for the Border:
1245  const SvxBoxItem& aSelBoxItem = aFindFrame.pNewFrameFormat->GetBox();
1246  if( aSelBoxItem.GetRight() )
1247  {
1248  pInsLine->GetTabBoxes()[ nBoxPos + nCnt ]->ClaimFrameFormat();
1249 
1250  SvxBoxItem aTmp( aSelBoxItem );
1251  aTmp.SetLine( nullptr, SvxBoxItemLine::RIGHT );
1252  aFindFrame.pNewFrameFormat->SetFormatAttr( aTmp );
1253 
1254  // Remove the Format from the "cache"
1255  for( auto i = aFrameArr.size(); i; )
1256  {
1257  const CpyTabFrame& rCTF = aFrameArr[ --i ];
1258  if( rCTF.pNewFrameFormat == aFindFrame.pNewFrameFormat ||
1259  rCTF.pFrameFormat == aFindFrame.pNewFrameFormat )
1260  {
1261  aFrameArr.erase( aFrameArr.begin() + i );
1262  aLastBoxArr.erase( aLastBoxArr.begin() + i );
1263  }
1264  }
1265  }
1266  }
1267 
1268  // Update Layout
1269  aFndBox.MakeFrames( *this );
1270 
1273  return true;
1274 }
1275 
1276 /*
1277  * >> MERGE <<
1278  * Algorithm:
1279  * If we only have one Line in the FndBox_, take this Line and test
1280  * the Box count:
1281  * If we have more than one Box, we merge on Box level, meaning
1282  * the new Box will be as wide as the old ones.
1283  * All Lines that are above/under the Area, are inserted into
1284  * the Box as Line + Box.
1285  * All Lines that come before/after the Area, are inserted into
1286  * the Boxes Left/Right.
1287  *
1288  * >> MERGE <<
1289  */
1290 static void lcl_CpyLines( sal_uInt16 nStt, sal_uInt16 nEnd,
1291  SwTableLines& rLines,
1292  SwTableBox* pInsBox,
1293  sal_uInt16 nPos = USHRT_MAX )
1294 {
1295  for( sal_uInt16 n = nStt; n < nEnd; ++n )
1296  rLines[n]->SetUpper( pInsBox );
1297  if( USHRT_MAX == nPos )
1298  nPos = pInsBox->GetTabLines().size();
1299  pInsBox->GetTabLines().insert( pInsBox->GetTabLines().begin() + nPos,
1300  rLines.begin() + nStt, rLines.begin() + nEnd );
1301  rLines.erase( rLines.begin() + nStt, rLines.begin() + nEnd );
1302 }
1303 
1304 static void lcl_CpyBoxes( sal_uInt16 nStt, sal_uInt16 nEnd,
1305  SwTableBoxes& rBoxes,
1306  SwTableLine* pInsLine )
1307 {
1308  for( sal_uInt16 n = nStt; n < nEnd; ++n )
1309  rBoxes[n]->SetUpper( pInsLine );
1310  sal_uInt16 nPos = pInsLine->GetTabBoxes().size();
1311  pInsLine->GetTabBoxes().insert( pInsLine->GetTabBoxes().begin() + nPos,
1312  rBoxes.begin() + nStt, rBoxes.begin() + nEnd );
1313  rBoxes.erase( rBoxes.begin() + nStt, rBoxes.begin() + nEnd );
1314 }
1315 
1316 static void lcl_CalcWidth( SwTableBox* pBox )
1317 {
1318  // Assertion: Every Line in the Box is as large
1319  SwFrameFormat* pFormat = pBox->ClaimFrameFormat();
1320  OSL_ENSURE( pBox->GetTabLines().size(), "Box does not have any Lines" );
1321 
1322  SwTableLine* pLine = pBox->GetTabLines()[0];
1323  OSL_ENSURE( pLine, "Box is not within a Line" );
1324 
1325  tools::Long nWidth = 0;
1326  for( auto pTabBox : pLine->GetTabBoxes() )
1327  nWidth += pTabBox->GetFrameFormat()->GetFrameSize().GetWidth();
1328 
1329  pFormat->SetFormatAttr( SwFormatFrameSize( SwFrameSize::Variable, nWidth, 0 ));
1330 
1331  // Boxes with Lines can only have Size/Fillorder
1332  pFormat->ResetFormatAttr( RES_LR_SPACE, RES_FRMATR_END - 1 );
1334 }
1335 
1336 namespace {
1337 
1338 struct InsULPara
1339 {
1340  SwTableNode* pTableNd;
1341  SwTableLine* pInsLine;
1342  SwTableBox* pInsBox;
1343  bool bUL_LR : 1; // Upper-Lower(true) or Left-Right(false) ?
1344  bool bUL : 1; // Upper-Left(true) or Lower-Right(false) ?
1345 
1346  SwTableBox* pLeftBox;
1347 
1348  InsULPara( SwTableNode* pTNd,
1349  SwTableBox* pLeft,
1350  SwTableLine* pLine )
1351  : pTableNd( pTNd ), pInsLine( pLine ), pInsBox( nullptr ),
1352  pLeftBox( pLeft )
1353  { bUL_LR = true; bUL = true; }
1354 
1355  void SetLeft( SwTableBox* pBox )
1356  { bUL_LR = false; bUL = true; if( pBox ) pInsBox = pBox; }
1357  void SetRight( SwTableBox* pBox )
1358  { bUL_LR = false; bUL = false; if( pBox ) pInsBox = pBox; }
1359  void SetLower( SwTableLine* pLine )
1360  { bUL_LR = true; bUL = false; if( pLine ) pInsLine = pLine; }
1361 };
1362 
1363 }
1364 
1365 static void lcl_Merge_MoveLine(FndLine_ & rFndLine, InsULPara *const pULPara);
1366 
1367 static void lcl_Merge_MoveBox(FndBox_ & rFndBox, InsULPara *const pULPara)
1368 {
1369  SwTableBoxes* pBoxes;
1370 
1371  sal_uInt16 nStt = 0, nEnd = rFndBox.GetLines().size();
1372  sal_uInt16 nInsPos = USHRT_MAX;
1373  if( !pULPara->bUL_LR ) // Left/Right
1374  {
1375  sal_uInt16 nPos;
1376  SwTableBox* pFndTableBox = rFndBox.GetBox();
1377  pBoxes = &pFndTableBox->GetUpper()->GetTabBoxes();
1378  if( pULPara->bUL ) // Left ?
1379  {
1380  // if there are Boxes before it, move them
1381  nPos = pFndTableBox->GetUpper()->GetBoxPos( pFndTableBox );
1382  if( 0 != nPos )
1383  lcl_CpyBoxes( 0, nPos, *pBoxes, pULPara->pInsLine );
1384  }
1385  else // Right
1386  {
1387  // if there are Boxes behind it, move them
1388  nPos = pFndTableBox->GetUpper()->GetBoxPos( pFndTableBox );
1389  if( nPos +1 < o3tl::narrowing<sal_uInt16>(pBoxes->size()) )
1390  {
1391  nInsPos = pULPara->pInsLine->GetTabBoxes().size();
1392  lcl_CpyBoxes( nPos+1, pBoxes->size(),
1393  *pBoxes, pULPara->pInsLine );
1394  }
1395  }
1396  }
1397  // Upper/Lower and still deeper?
1398  else if (!rFndBox.GetLines().empty())
1399  {
1400  // Only search the Line from which we need to move
1401  nStt = pULPara->bUL ? 0 : rFndBox.GetLines().size()-1;
1402  nEnd = nStt+1;
1403  }
1404 
1405  pBoxes = &pULPara->pInsLine->GetTabBoxes();
1406 
1407  // Is there still a level to step down to?
1408  if (rFndBox.GetBox()->GetTabLines().empty())
1409  return;
1410 
1411  SwTableBox* pBox = new SwTableBox(
1412  static_cast<SwTableBoxFormat*>(rFndBox.GetBox()->GetFrameFormat()),
1413  0, pULPara->pInsLine );
1414  InsULPara aPara( *pULPara );
1415  aPara.pInsBox = pBox;
1416  for (FndLines_t::iterator it = rFndBox.GetLines().begin() + nStt;
1417  it != rFndBox.GetLines().begin() + nEnd; ++it )
1418  {
1419  lcl_Merge_MoveLine(**it, &aPara);
1420  }
1421  if( !pBox->GetTabLines().empty() )
1422  {
1423  if( USHRT_MAX == nInsPos )
1424  nInsPos = pBoxes->size();
1425  pBoxes->insert( pBoxes->begin() + nInsPos, pBox );
1426  lcl_CalcWidth( pBox ); // calculate the Box's width
1427  }
1428  else
1429  delete pBox;
1430 }
1431 
1432 static void lcl_Merge_MoveLine(FndLine_& rFndLine, InsULPara *const pULPara)
1433 {
1434  SwTableLines* pLines;
1435 
1436  sal_uInt16 nStt = 0, nEnd = rFndLine.GetBoxes().size();
1437  sal_uInt16 nInsPos = USHRT_MAX;
1438  if( pULPara->bUL_LR ) // UpperLower ?
1439  {
1440  sal_uInt16 nPos;
1441  SwTableLine* pFndLn = rFndLine.GetLine();
1442  pLines = pFndLn->GetUpper() ?
1443  &pFndLn->GetUpper()->GetTabLines() :
1444  &pULPara->pTableNd->GetTable().GetTabLines();
1445 
1446  SwTableBox* pLBx = rFndLine.GetBoxes().front()->GetBox();
1447  SwTableBox* pRBx = rFndLine.GetBoxes().back()->GetBox();
1448  sal_uInt16 nLeft = pFndLn->GetBoxPos( pLBx );
1449  sal_uInt16 nRight = pFndLn->GetBoxPos( pRBx );
1450 
1451  if( !nLeft || nRight == pFndLn->GetTabBoxes().size() )
1452  {
1453  if( pULPara->bUL ) // Upper ?
1454  {
1455  // If there are Lines before it, move them
1456  nPos = pLines->GetPos( pFndLn );
1457  if( 0 != nPos )
1458  lcl_CpyLines( 0, nPos, *pLines, pULPara->pInsBox );
1459  }
1460  else
1461  // If there are Lines after it, move them
1462  if( (nPos = pLines->GetPos( pFndLn )) + 1 < o3tl::narrowing<sal_uInt16>(pLines->size()) )
1463  {
1464  nInsPos = pULPara->pInsBox->GetTabLines().size();
1465  lcl_CpyLines( nPos+1, pLines->size(), *pLines,
1466  pULPara->pInsBox );
1467  }
1468  }
1469  else
1470  {
1471  // There are still Boxes on the left side, so put the Left-
1472  // and Merge-Box into one Box and Line, insert before/after
1473  // a Line with a Box, into which the upper/lower Lines are
1474  // inserted
1475  SwTableLine* pInsLine = pULPara->pLeftBox->GetUpper();
1476  SwTableBox* pLMBox = new SwTableBox(
1477  static_cast<SwTableBoxFormat*>(pULPara->pLeftBox->GetFrameFormat()), 0, pInsLine );
1478  SwTableLine* pLMLn = new SwTableLine(
1479  static_cast<SwTableLineFormat*>(pInsLine->GetFrameFormat()), 2, pLMBox );
1481 
1482  pLMBox->GetTabLines().insert( pLMBox->GetTabLines().begin(), pLMLn );
1483 
1484  lcl_CpyBoxes( 0, 2, pInsLine->GetTabBoxes(), pLMLn );
1485 
1486  pInsLine->GetTabBoxes().insert( pInsLine->GetTabBoxes().begin(), pLMBox );
1487 
1488  if( pULPara->bUL ) // Upper ?
1489  {
1490  // If there are Lines before it, move them
1491  nPos = pLines->GetPos( pFndLn );
1492  if( 0 != nPos )
1493  lcl_CpyLines( 0, nPos, *pLines, pLMBox, 0 );
1494  }
1495  else
1496  // If there are Lines after it, move them
1497  if( (nPos = pLines->GetPos( pFndLn )) + 1 < o3tl::narrowing<sal_uInt16>(pLines->size()) )
1498  lcl_CpyLines( nPos+1, pLines->size(), *pLines,
1499  pLMBox );
1500  lcl_CalcWidth( pLMBox ); // calculate the Box's width
1501  }
1502  }
1503  // Left/Right
1504  else
1505  {
1506  // Find only the Line from which we need to move
1507  nStt = pULPara->bUL ? 0 : rFndLine.GetBoxes().size()-1;
1508  nEnd = nStt+1;
1509  }
1510  pLines = &pULPara->pInsBox->GetTabLines();
1511 
1512  SwTableLine* pNewLine = new SwTableLine(
1513  static_cast<SwTableLineFormat*>(rFndLine.GetLine()->GetFrameFormat()), 0, pULPara->pInsBox );
1514  InsULPara aPara( *pULPara ); // copying
1515  aPara.pInsLine = pNewLine;
1516  FndBoxes_t & rLineBoxes = rFndLine.GetBoxes();
1517  for (FndBoxes_t::iterator it = rLineBoxes.begin() + nStt;
1518  it != rLineBoxes.begin() + nEnd; ++it)
1519  {
1520  lcl_Merge_MoveBox(**it, &aPara);
1521  }
1522 
1523  if( !pNewLine->GetTabBoxes().empty() )
1524  {
1525  if( USHRT_MAX == nInsPos )
1526  nInsPos = pLines->size();
1527  pLines->insert( pLines->begin() + nInsPos, pNewLine );
1528  }
1529  else
1530  delete pNewLine;
1531 }
1532 
1533 static void lcl_BoxSetHeadCondColl( const SwTableBox* pBox );
1534 
1535 bool SwTable::OldMerge( SwDoc* pDoc, const SwSelBoxes& rBoxes,
1536  SwTableBox* pMergeBox, SwUndoTableMerge* pUndo )
1537 {
1538  OSL_ENSURE( !rBoxes.empty() && pMergeBox, "no valid values" );
1539  SwTableNode* pTableNd = const_cast<SwTableNode*>(rBoxes[0]->GetSttNd()->FindTableNode());
1540  if( !pTableNd )
1541  return false;
1542 
1543  // Find all Boxes/Lines
1544  FndBox_ aFndBox( nullptr, nullptr );
1545  {
1546  FndPara aPara( rBoxes, &aFndBox );
1547  ForEach_FndLineCopyCol( GetTabLines(), &aPara );
1548  }
1549  if( aFndBox.GetLines().empty() )
1550  return false;
1551 
1552  // TL_CHART2: splitting/merging of a number of cells or rows will usually make
1553  // the table too complex to be handled with chart.
1554  // Thus we tell the charts to use their own data provider and forget about this table
1556 
1557  SetHTMLTableLayout(std::shared_ptr<SwHTMLTableLayout>()); // Delete HTML Layout
1558 
1559  if( pUndo )
1560  pUndo->SetSelBoxes( rBoxes );
1561 
1562  // Find Lines for the Layout update
1563  aFndBox.SetTableLines( *this );
1564  aFndBox.DelFrames( *this );
1565 
1566  FndBox_* pFndBox = &aFndBox;
1567  while( 1 == pFndBox->GetLines().size() &&
1568  1 == pFndBox->GetLines().front()->GetBoxes().size() )
1569  {
1570  pFndBox = pFndBox->GetLines().front()->GetBoxes().front().get();
1571  }
1572 
1573  SwTableLine* pInsLine = new SwTableLine(
1574  static_cast<SwTableLineFormat*>(pFndBox->GetLines().front()->GetLine()->GetFrameFormat()), 0,
1575  !pFndBox->GetUpper() ? nullptr : pFndBox->GetBox() );
1577 
1578  // Add the new Line
1579  SwTableLines* pLines = pFndBox->GetUpper() ?
1580  &pFndBox->GetBox()->GetTabLines() : &GetTabLines();
1581 
1582  SwTableLine* pNewLine = pFndBox->GetLines().front()->GetLine();
1583  sal_uInt16 nInsPos = pLines->GetPos( pNewLine );
1584  pLines->insert( pLines->begin() + nInsPos, pInsLine );
1585 
1586  SwTableBox* pLeftBox = new SwTableBox( static_cast<SwTableBoxFormat*>(pMergeBox->GetFrameFormat()), 0, pInsLine );
1587  SwTableBox* pRightBox = new SwTableBox( static_cast<SwTableBoxFormat*>(pMergeBox->GetFrameFormat()), 0, pInsLine );
1588  pMergeBox->SetUpper( pInsLine );
1589  pInsLine->GetTabBoxes().insert( pInsLine->GetTabBoxes().begin(), pLeftBox );
1590  pLeftBox->ClaimFrameFormat();
1591  pInsLine->GetTabBoxes().insert( pInsLine->GetTabBoxes().begin() + 1, pMergeBox);
1592  pInsLine->GetTabBoxes().insert( pInsLine->GetTabBoxes().begin() + 2, pRightBox );
1593  pRightBox->ClaimFrameFormat();
1594 
1595  // This contains all Lines that are above the selected Area,
1596  // thus they form a Upper/Lower Line
1597  InsULPara aPara( pTableNd, pLeftBox, pInsLine );
1598 
1599  // Move the overlapping upper/lower Lines of the selected Area
1600  for (auto & it : pFndBox->GetLines().front()->GetBoxes())
1601  {
1602  lcl_Merge_MoveBox(*it, &aPara);
1603  }
1604  aPara.SetLower( pInsLine );
1605  const auto nEnd = pFndBox->GetLines().size()-1;
1606  for (auto & it : pFndBox->GetLines()[nEnd]->GetBoxes())
1607  {
1608  lcl_Merge_MoveBox(*it, &aPara);
1609  }
1610 
1611  // Move the Boxes extending into the selected Area from left/right
1612  aPara.SetLeft( pLeftBox );
1613  for (auto & rpFndLine : pFndBox->GetLines())
1614  {
1615  lcl_Merge_MoveLine( *rpFndLine, &aPara );
1616  }
1617 
1618  aPara.SetRight( pRightBox );
1619  for (auto & rpFndLine : pFndBox->GetLines())
1620  {
1621  lcl_Merge_MoveLine( *rpFndLine, &aPara );
1622  }
1623 
1624  if( pLeftBox->GetTabLines().empty() )
1625  DeleteBox_( *this, pLeftBox, nullptr, false, false );
1626  else
1627  {
1628  lcl_CalcWidth( pLeftBox ); // calculate the Box's width
1629  if( pUndo && pLeftBox->GetSttNd() )
1630  pUndo->AddNewBox( pLeftBox->GetSttIdx() );
1631  }
1632  if( pRightBox->GetTabLines().empty() )
1633  DeleteBox_( *this, pRightBox, nullptr, false, false );
1634  else
1635  {
1636  lcl_CalcWidth( pRightBox ); // calculate the Box's width
1637  if( pUndo && pRightBox->GetSttNd() )
1638  pUndo->AddNewBox( pRightBox->GetSttIdx() );
1639  }
1640 
1641  DeleteSel( pDoc, rBoxes, nullptr, nullptr, false, false );
1642 
1643  // Clean up this Line's structure once again, generally all of them
1644  GCLines();
1645 
1646  for( const auto& rpBox : GetTabLines()[0]->GetTabBoxes() )
1647  lcl_BoxSetHeadCondColl(rpBox);
1648 
1649  aFndBox.MakeFrames( *this );
1650 
1653 
1654  return true;
1655 }
1656 
1657 static void lcl_CheckRowSpan( SwTable &rTable )
1658 {
1659  const tools::Long nLineCount = static_cast<tools::Long>(rTable.GetTabLines().size());
1660  tools::Long nMaxSpan = nLineCount;
1661  tools::Long nMinSpan = 1;
1662  while( nMaxSpan )
1663  {
1664  SwTableLine* pLine = rTable.GetTabLines()[ nLineCount - nMaxSpan ];
1665  for( auto pBox : pLine->GetTabBoxes() )
1666  {
1667  sal_Int32 nRowSpan = pBox->getRowSpan();
1668  if( nRowSpan > nMaxSpan )
1669  pBox->setRowSpan( nMaxSpan );
1670  else if( nRowSpan < nMinSpan )
1671  pBox->setRowSpan( nMinSpan > 0 ? nMaxSpan : nMinSpan );
1672  }
1673  --nMaxSpan;
1674  nMinSpan = -nMaxSpan;
1675  }
1676 }
1677 
1678 static sal_uInt16 lcl_GetBoxOffset( const FndBox_& rBox )
1679 {
1680  // Find the first Box
1681  const FndBox_* pFirstBox = &rBox;
1682  while (!pFirstBox->GetLines().empty())
1683  {
1684  pFirstBox = pFirstBox->GetLines().front()->GetBoxes().front().get();
1685  }
1686 
1687  sal_uInt16 nRet = 0;
1688  // Calculate the position relative to above via the Lines
1689  const SwTableBox* pBox = pFirstBox->GetBox();
1690  do {
1691  const SwTableBoxes& rBoxes = pBox->GetUpper()->GetTabBoxes();
1692  for( auto pCmp : rBoxes )
1693  {
1694  if (pBox==pCmp)
1695  break;
1696  nRet = nRet + o3tl::narrowing<sal_uInt16>(pCmp->GetFrameFormat()->GetFrameSize().GetWidth());
1697  }
1698  pBox = pBox->GetUpper()->GetUpper();
1699  } while( pBox );
1700  return nRet;
1701 }
1702 
1703 static sal_uInt16 lcl_GetLineWidth( const FndLine_& rLine )
1704 {
1705  sal_uInt16 nRet = 0;
1706  for( auto n = rLine.GetBoxes().size(); n; )
1707  {
1708  nRet = nRet + o3tl::narrowing<sal_uInt16>(rLine.GetBoxes()[--n]->GetBox()
1709  ->GetFrameFormat()->GetFrameSize().GetWidth());
1710  }
1711  return nRet;
1712 }
1713 
1714 static void lcl_CalcNewWidths(const FndLines_t& rFndLines, CpyPara& rPara)
1715 {
1716  rPara.pWidths.reset();
1717  const size_t nLineCount = rFndLines.size();
1718  if( nLineCount )
1719  {
1720  rPara.pWidths = std::make_shared< std::vector< std::vector< sal_uLong > > >
1721  ( nLineCount );
1722  // First we collect information about the left/right borders of all
1723  // selected cells
1724  for( size_t nLine = 0; nLine < nLineCount; ++nLine )
1725  {
1726  std::vector< sal_uLong > &rWidth = (*rPara.pWidths)[ nLine ];
1727  const FndLine_ *pFndLine = rFndLines[ nLine ].get();
1728  if( pFndLine && !pFndLine->GetBoxes().empty() )
1729  {
1730  const SwTableLine *pLine = pFndLine->GetLine();
1731  if( pLine && !pLine->GetTabBoxes().empty() )
1732  {
1733  size_t nBoxCount = pLine->GetTabBoxes().size();
1734  sal_uLong nPos = 0;
1735  // The first selected box...
1736  const SwTableBox *const pSel =
1737  pFndLine->GetBoxes().front()->GetBox();
1738  size_t nBox = 0;
1739  // Sum up the width of all boxes before the first selected box
1740  while( nBox < nBoxCount )
1741  {
1742  SwTableBox* pBox = pLine->GetTabBoxes()[nBox++];
1743  if( pBox != pSel )
1744  nPos += pBox->GetFrameFormat()->GetFrameSize().GetWidth();
1745  else
1746  break;
1747  }
1748  // nPos is now the left border of the first selected box
1749  if( rPara.nMinLeft > nPos )
1750  rPara.nMinLeft = nPos;
1751  nBoxCount = pFndLine->GetBoxes().size();
1752  rWidth = std::vector< sal_uLong >( nBoxCount+2 );
1753  rWidth[ 0 ] = nPos;
1754  // Add now the widths of all selected boxes and store
1755  // the positions in the vector
1756  for( nBox = 0; nBox < nBoxCount; )
1757  {
1758  nPos += pFndLine->GetBoxes()[nBox]
1759  ->GetBox()->GetFrameFormat()->GetFrameSize().GetWidth();
1760  rWidth[ ++nBox ] = nPos;
1761  }
1762  // nPos: The right border of the last selected box
1763  if( rPara.nMaxRight < nPos )
1764  rPara.nMaxRight = nPos;
1765  if( nPos <= rWidth[ 0 ] )
1766  rWidth.clear();
1767  }
1768  }
1769  }
1770  }
1771  // Second step: calculate the new widths for the copied cells
1772  sal_uLong nSelSize = rPara.nMaxRight - rPara.nMinLeft;
1773  if( !nSelSize )
1774  return;
1775 
1776  for( size_t nLine = 0; nLine < nLineCount; ++nLine )
1777  {
1778  std::vector< sal_uLong > &rWidth = (*rPara.pWidths)[ nLine ];
1779  const size_t nCount = rWidth.size();
1780  if( nCount > 2 )
1781  {
1782  rWidth[ nCount - 1 ] = rPara.nMaxRight;
1783  sal_uLong nLastPos = 0;
1784  for( size_t nBox = 0; nBox < nCount; ++nBox )
1785  {
1786  sal_uInt64 nNextPos = rWidth[ nBox ];
1787  nNextPos -= rPara.nMinLeft;
1788  nNextPos *= rPara.nNewSize;
1789  nNextPos /= nSelSize;
1790  rWidth[ nBox ] = static_cast<sal_uLong>(nNextPos - nLastPos);
1791  nLastPos = static_cast<sal_uLong>(nNextPos);
1792  }
1793  }
1794  }
1795 }
1796 
1797 static void
1798 lcl_CopyLineToDoc(FndLine_ const& rpFndLn, CpyPara *const pCpyPara);
1799 
1800 static void lcl_CopyBoxToDoc(FndBox_ const& rFndBox, CpyPara *const pCpyPara)
1801 {
1802  // Calculation of new size
1803  sal_uLong nRealSize;
1804  sal_uLong nDummy1 = 0;
1805  sal_uLong nDummy2 = 0;
1806  if( pCpyPara->pTableNd->GetTable().IsNewModel() )
1807  {
1808  if( pCpyPara->nBoxIdx == 1 )
1809  nDummy1 = (*pCpyPara->pWidths)[pCpyPara->nLnIdx][0];
1810  nRealSize = (*pCpyPara->pWidths)[pCpyPara->nLnIdx][pCpyPara->nBoxIdx++];
1811  if( pCpyPara->nBoxIdx == (*pCpyPara->pWidths)[pCpyPara->nLnIdx].size()-1 )
1812  nDummy2 = (*pCpyPara->pWidths)[pCpyPara->nLnIdx][pCpyPara->nBoxIdx];
1813  }
1814  else
1815  {
1816  nRealSize = pCpyPara->nNewSize;
1817  nRealSize *= rFndBox.GetBox()->GetFrameFormat()->GetFrameSize().GetWidth();
1818  if (pCpyPara->nOldSize == 0)
1819  throw o3tl::divide_by_zero();
1820  nRealSize /= pCpyPara->nOldSize;
1821  }
1822 
1823  sal_uLong nSize;
1824  bool bDummy = nDummy1 > 0;
1825  if( bDummy )
1826  nSize = nDummy1;
1827  else
1828  {
1829  nSize = nRealSize;
1830  nRealSize = 0;
1831  }
1832  do
1833  {
1834  // Find the Frame Format in the list of all Frame Formats
1835  CpyTabFrame aFindFrame(static_cast<SwTableBoxFormat*>(rFndBox.GetBox()->GetFrameFormat()));
1836 
1837  std::shared_ptr<SwFormatFrameSize> aFrameSz(std::make_shared<SwFormatFrameSize>());
1838  CpyTabFrames::const_iterator itFind = pCpyPara->rTabFrameArr.lower_bound( aFindFrame );
1839  const CpyTabFrames::size_type nFndPos = itFind - pCpyPara->rTabFrameArr.begin();
1840 
1841  // It *is* sometimes cool to have multiple tests/if's and assignments
1842  // in a single statement, and it is technically possible. But it is definitely
1843  // not simply readable - where from my POV reading code is done 1000 times
1844  // more often than writing it. Thus I dismantled the expression in smaller
1845  // chunks to keep it handy/understandable/changeable (hopefully without error)
1846  // The original for reference:
1847  // if( itFind == pCpyPara->rTabFrameArr.end() || !(*itFind == aFindFrame) ||
1848  // ( aFrameSz = ( aFindFrame = pCpyPara->rTabFrameArr[ nFndPos ]).pNewFrameFormat->
1849  // GetFrameSize()).GetWidth() != static_cast<SwTwips>(nSize) )
1850 
1851  bool DoCopyIt(itFind == pCpyPara->rTabFrameArr.end());
1852 
1853  if(!DoCopyIt)
1854  {
1855  DoCopyIt = !(*itFind == aFindFrame);
1856  }
1857 
1858  if(!DoCopyIt)
1859  {
1860  aFindFrame = pCpyPara->rTabFrameArr[ nFndPos ];
1861  aFrameSz.reset(aFindFrame.pNewFrameFormat->GetFrameSize().Clone());
1862  DoCopyIt = aFrameSz->GetWidth() != static_cast<SwTwips>(nSize);
1863  }
1864 
1865  if(DoCopyIt)
1866  {
1867  // It doesn't exist yet, so copy it
1868  aFindFrame.pNewFrameFormat = pCpyPara->rDoc.MakeTableBoxFormat();
1869  aFindFrame.pNewFrameFormat->CopyAttrs( *rFndBox.GetBox()->GetFrameFormat() );
1870  if( !pCpyPara->bCpyContent )
1871  aFindFrame.pNewFrameFormat->ResetFormatAttr( RES_BOXATR_FORMULA, RES_BOXATR_VALUE );
1872  aFrameSz->SetWidth( nSize );
1873  aFindFrame.pNewFrameFormat->SetFormatAttr( *aFrameSz );
1874  pCpyPara->rTabFrameArr.insert( aFindFrame );
1875  }
1876 
1877  SwTableBox* pBox;
1878  if (!rFndBox.GetLines().empty())
1879  {
1880  pBox = new SwTableBox( aFindFrame.pNewFrameFormat,
1881  rFndBox.GetLines().size(), pCpyPara->pInsLine );
1882  pCpyPara->pInsLine->GetTabBoxes().insert( pCpyPara->pInsLine->GetTabBoxes().begin() + pCpyPara->nInsPos++, pBox );
1883  CpyPara aPara( *pCpyPara, pBox );
1884  aPara.nNewSize = nSize; // get the size
1885  for (auto const& rpFndLine : rFndBox.GetLines())
1886  {
1887  lcl_CopyLineToDoc( *rpFndLine, &aPara );
1888  }
1889  }
1890  else
1891  {
1892  // Create an empty Box
1893  pCpyPara->rDoc.GetNodes().InsBoxen( pCpyPara->pTableNd, pCpyPara->pInsLine,
1894  aFindFrame.pNewFrameFormat,
1895  pCpyPara->rDoc.GetDfltTextFormatColl(),
1896  nullptr, pCpyPara->nInsPos );
1897  pBox = pCpyPara->pInsLine->GetTabBoxes()[ pCpyPara->nInsPos ];
1898  if( bDummy )
1899  pBox->setDummyFlag( true );
1900  else if( pCpyPara->bCpyContent )
1901  {
1902  // Copy the content into this empty Box
1903  pBox->setRowSpan(rFndBox.GetBox()->getRowSpan());
1904 
1905  // We can also copy formulas and values, if we copy the content
1906  {
1907  SfxItemSetFixed<RES_BOXATR_FORMAT, RES_BOXATR_VALUE> aBoxAttrSet( pCpyPara->rDoc.GetAttrPool() );
1908  aBoxAttrSet.Put(rFndBox.GetBox()->GetFrameFormat()->GetAttrSet());
1909  if( aBoxAttrSet.Count() )
1910  {
1911  const SwTableBoxNumFormat* pItem;
1912  SvNumberFormatter* pN = pCpyPara->rDoc.GetNumberFormatter( false );
1913  if( pN && pN->HasMergeFormatTable() && (pItem = aBoxAttrSet.
1914  GetItemIfSet( RES_BOXATR_FORMAT, false )) )
1915  {
1916  sal_uLong nOldIdx = pItem->GetValue();
1917  sal_uLong nNewIdx = pN->GetMergeFormatIndex( nOldIdx );
1918  if( nNewIdx != nOldIdx )
1919  aBoxAttrSet.Put( SwTableBoxNumFormat( nNewIdx ));
1920  }
1921  pBox->ClaimFrameFormat()->SetFormatAttr( aBoxAttrSet );
1922  }
1923  }
1924  SwDoc* pFromDoc = rFndBox.GetBox()->GetFrameFormat()->GetDoc();
1925  SwNodeRange aCpyRg( *rFndBox.GetBox()->GetSttNd(), SwNodeOffset(1),
1926  *rFndBox.GetBox()->GetSttNd()->EndOfSectionNode() );
1927  SwNodeIndex aInsIdx( *pBox->GetSttNd(), 1 );
1928 
1929  pFromDoc->GetDocumentContentOperationsManager().CopyWithFlyInFly(aCpyRg, aInsIdx, nullptr, false);
1930  // Delete the initial TextNode
1931  pCpyPara->rDoc.GetNodes().Delete( aInsIdx );
1932  }
1933  ++pCpyPara->nInsPos;
1934  }
1935  if( nRealSize )
1936  {
1937  bDummy = false;
1938  nSize = nRealSize;
1939  nRealSize = 0;
1940  }
1941  else
1942  {
1943  bDummy = true;
1944  nSize = nDummy2;
1945  nDummy2 = 0;
1946  }
1947  }
1948  while( nSize );
1949 }
1950 
1951 static void
1952 lcl_CopyLineToDoc(const FndLine_& rFndLine, CpyPara *const pCpyPara)
1953 {
1954  // Find the Frame Format in the list of all Frame Formats
1955  CpyTabFrame aFindFrame( rFndLine.GetLine()->GetFrameFormat() );
1956  CpyTabFrames::const_iterator itFind = pCpyPara->rTabFrameArr.find( aFindFrame );
1957  if( itFind == pCpyPara->rTabFrameArr.end() )
1958  {
1959  // It doesn't exist yet, so copy it
1960  aFindFrame.pNewFrameFormat = reinterpret_cast<SwTableBoxFormat*>(pCpyPara->rDoc.MakeTableLineFormat());
1961  aFindFrame.pNewFrameFormat->CopyAttrs( *rFndLine.GetLine()->GetFrameFormat() );
1962  pCpyPara->rTabFrameArr.insert( aFindFrame );
1963  }
1964  else
1965  aFindFrame = *itFind;
1966 
1967  SwTableLine* pNewLine = new SwTableLine( reinterpret_cast<SwTableLineFormat*>(aFindFrame.pNewFrameFormat),
1968  rFndLine.GetBoxes().size(), pCpyPara->pInsBox );
1969  if( pCpyPara->pInsBox )
1970  {
1971  SwTableLines& rLines = pCpyPara->pInsBox->GetTabLines();
1972  rLines.insert( rLines.begin() + pCpyPara->nInsPos++, pNewLine );
1973  }
1974  else
1975  {
1976  SwTableLines& rLines = pCpyPara->pTableNd->GetTable().GetTabLines();
1977  rLines.insert( rLines.begin() + pCpyPara->nInsPos++, pNewLine);
1978  }
1979 
1980  CpyPara aPara( *pCpyPara, pNewLine );
1981 
1982  if( pCpyPara->pTableNd->GetTable().IsNewModel() )
1983  {
1984  aPara.nOldSize = 0; // will not be used
1985  aPara.nBoxIdx = 1;
1986  }
1987  else if( rFndLine.GetBoxes().size() ==
1988  rFndLine.GetLine()->GetTabBoxes().size() )
1989  {
1990  // Get the Parent's size
1991  const SwFrameFormat* pFormat;
1992 
1993  if( rFndLine.GetLine()->GetUpper() )
1994  pFormat = rFndLine.GetLine()->GetUpper()->GetFrameFormat();
1995  else
1996  pFormat = pCpyPara->pTableNd->GetTable().GetFrameFormat();
1997  aPara.nOldSize = pFormat->GetFrameSize().GetWidth();
1998  }
1999  else
2000  // Calculate it
2001  for (auto &rpBox : rFndLine.GetBoxes())
2002  {
2003  aPara.nOldSize += rpBox->GetBox()->GetFrameFormat()->GetFrameSize().GetWidth();
2004  }
2005 
2006  const FndBoxes_t& rBoxes = rFndLine.GetBoxes();
2007  for (auto const& it : rBoxes)
2008  {
2009  lcl_CopyBoxToDoc(*it, &aPara);
2010  }
2011  if( pCpyPara->pTableNd->GetTable().IsNewModel() )
2012  ++pCpyPara->nLnIdx;
2013 }
2014 
2016 {
2017  // Find all Boxes/Lines
2018  SwSelBoxes aSelBoxes;
2019  SwTableBox* pBox = GetTabSortBoxes()[ 0 ];
2020  pBox = GetTableBox( pBox->GetSttNd()->StartOfSectionNode()->GetIndex() + 1 );
2021  SelLineFromBox( pBox, aSelBoxes );
2022 
2023  FndBox_ aFndBox( nullptr, nullptr );
2024  {
2025  FndPara aPara( aSelBoxes, &aFndBox );
2026  ForEach_FndLineCopyCol( GetTabLines(), &aPara );
2027  }
2028  if( aFndBox.GetLines().empty() )
2029  return;
2030 
2031  {
2032  // Convert Table formulas to their relative representation
2033  SwTableFormulaUpdate aMsgHint( this );
2034  aMsgHint.m_eFlags = TBL_RELBOXNAME;
2035  GetFrameFormat()->GetDoc()->getIDocumentFieldsAccess().UpdateTableFields( &aMsgHint );
2036  }
2037 
2038  CpyTabFrames aCpyFormat;
2039  CpyPara aPara( &rTableNd, 1, aCpyFormat );
2040  aPara.nNewSize = aPara.nOldSize = rTableNd.GetTable().GetFrameFormat()->GetFrameSize().GetWidth();
2041  // Copy
2042  if( IsNewModel() )
2043  lcl_CalcNewWidths( aFndBox.GetLines(), aPara );
2044  for (const auto & rpFndLine : aFndBox.GetLines())
2045  {
2046  lcl_CopyLineToDoc( *rpFndLine, &aPara );
2047  }
2048  if( rTableNd.GetTable().IsNewModel() )
2049  { // The copied line must not contain any row span attributes > 1
2050  SwTableLine* pLine = rTableNd.GetTable().GetTabLines()[0];
2051  OSL_ENSURE( !pLine->GetTabBoxes().empty(), "Empty Table Line" );
2052  for( auto pTableBox : pLine->GetTabBoxes() )
2053  {
2054  OSL_ENSURE( pTableBox, "Missing Table Box" );
2055  pTableBox->setRowSpan( 1 );
2056  }
2057  }
2058 }
2059 
2060 bool SwTable::MakeCopy( SwDoc& rInsDoc, const SwPosition& rPos,
2061  const SwSelBoxes& rSelBoxes,
2062  bool bCpyName, const OUString& rStyleName ) const
2063 {
2064  // Find all Boxes/Lines
2065  FndBox_ aFndBox( nullptr, nullptr );
2066  {
2067  FndPara aPara( rSelBoxes, &aFndBox );
2068  ForEach_FndLineCopyCol( const_cast<SwTableLines&>(GetTabLines()), &aPara );
2069  }
2070  if( aFndBox.GetLines().empty() )
2071  return false;
2072 
2073  // First copy the PoolTemplates for the Table, so that the Tables are
2074  // actually copied and have valid values.
2075  SwDoc* pSrcDoc = GetFrameFormat()->GetDoc();
2076  if( pSrcDoc != &rInsDoc )
2077  {
2080  }
2081 
2082  SwTable* pNewTable = const_cast<SwTable*>(rInsDoc.InsertTable(
2084  rPos, 1, 1, GetFrameFormat()->GetHoriOrient().GetHoriOrient(),
2085  nullptr, nullptr, false, IsNewModel() ));
2086  if( !pNewTable )
2087  return false;
2088 
2089  SwNodeIndex aIdx( rPos.nNode, -1 );
2090  SwTableNode* pTableNd = aIdx.GetNode().FindTableNode();
2091  ++aIdx;
2092  OSL_ENSURE( pTableNd, "Where is the TableNode now?" );
2093 
2094  pTableNd->GetTable().SetRowsToRepeat( GetRowsToRepeat() );
2095 
2096  pNewTable->SetTableStyleName(pTableNd->GetTable().GetTableStyleName());
2097 
2098  pTableNd->GetTable().SetTableStyleName(rStyleName);
2099  if( auto pSwDDETable = dynamic_cast<const SwDDETable*>(this) )
2100  {
2101  // A DDE-Table is being copied
2102  // Does the new Document actually have it's FieldType?
2103  SwFieldType* pFieldType = rInsDoc.getIDocumentFieldsAccess().InsertFieldType(
2104  *pSwDDETable->GetDDEFieldType() );
2105  OSL_ENSURE( pFieldType, "unknown FieldType" );
2106 
2107  // Change the Table Pointer at the Node
2108  pNewTable = new SwDDETable( *pNewTable,
2109  static_cast<SwDDEFieldType*>(pFieldType) );
2110  pTableNd->SetNewTable( std::unique_ptr<SwTable>(pNewTable), false );
2111  }
2112 
2113  pNewTable->GetFrameFormat()->CopyAttrs( *GetFrameFormat() );
2114  pNewTable->SetTableChgMode( GetTableChgMode() );
2115 
2116  // Destroy the already created Frames
2117  pTableNd->DelFrames();
2118 
2119  {
2120  // Convert the Table formulas to their relative representation
2121  SwTableFormulaUpdate aMsgHint( this );
2122  aMsgHint.m_eFlags = TBL_RELBOXNAME;
2123  pSrcDoc->getIDocumentFieldsAccess().UpdateTableFields( &aMsgHint );
2124  }
2125 
2126  SwTableNumFormatMerge aTNFM(*pSrcDoc, rInsDoc);
2127 
2128  // Also copy Names or enforce a new unique one
2129  if( bCpyName )
2130  pNewTable->GetFrameFormat()->SetName( GetFrameFormat()->GetName() );
2131 
2132  CpyTabFrames aCpyFormat;
2133  CpyPara aPara( pTableNd, 1, aCpyFormat );
2134  aPara.nNewSize = aPara.nOldSize = GetFrameFormat()->GetFrameSize().GetWidth();
2135 
2136  if( IsNewModel() )
2137  lcl_CalcNewWidths( aFndBox.GetLines(), aPara );
2138  // Copy
2139  for (const auto & rpFndLine : aFndBox.GetLines())
2140  {
2141  lcl_CopyLineToDoc( *rpFndLine, &aPara );
2142  }
2143 
2144  // Set the "right" margin above/below
2145  {
2146  FndLine_* pFndLn = aFndBox.GetLines().front().get();
2147  SwTableLine* pLn = pFndLn->GetLine();
2148  const SwTableLine* pTmp = pLn;
2149  sal_uInt16 nLnPos = GetTabLines().GetPos( pTmp );
2150  if( USHRT_MAX != nLnPos && nLnPos )
2151  {
2152  // There is a Line before it
2154 
2155  pLn = GetTabLines()[ nLnPos - 1 ];
2156  for( const auto& rpBox : pLn->GetTabBoxes() )
2157  sw_Box_CollectBox( rpBox, &aLnPara );
2158 
2159  if( aLnPara.Resize( lcl_GetBoxOffset( aFndBox ),
2160  lcl_GetLineWidth( *pFndLn )) )
2161  {
2162  aLnPara.SetValues( true );
2163  pLn = pNewTable->GetTabLines()[ 0 ];
2164  for( const auto& rpBox : pLn->GetTabBoxes() )
2165  sw_BoxSetSplitBoxFormats(rpBox, &aLnPara );
2166  }
2167  }
2168 
2169  pFndLn = aFndBox.GetLines().back().get();
2170  pLn = pFndLn->GetLine();
2171  pTmp = pLn;
2172  nLnPos = GetTabLines().GetPos( pTmp );
2173  if( nLnPos < GetTabLines().size() - 1 )
2174  {
2175  // There is a Line following it
2177 
2178  pLn = GetTabLines()[ nLnPos + 1 ];
2179  for( const auto& rpBox : pLn->GetTabBoxes() )
2180  sw_Box_CollectBox( rpBox, &aLnPara );
2181 
2182  if( aLnPara.Resize( lcl_GetBoxOffset( aFndBox ),
2183  lcl_GetLineWidth( *pFndLn )) )
2184  {
2185  aLnPara.SetValues( false );
2186  pLn = pNewTable->GetTabLines().back();
2187  for( const auto& rpBox : pLn->GetTabBoxes() )
2188  sw_BoxSetSplitBoxFormats(rpBox, &aLnPara );
2189  }
2190  }
2191  }
2192 
2193  // We need to delete the initial Box
2194  DeleteBox_( *pNewTable, pNewTable->GetTabLines().back()->GetTabBoxes()[0],
2195  nullptr, false, false );
2196 
2197  if( pNewTable->IsNewModel() )
2198  lcl_CheckRowSpan( *pNewTable );
2199  // Clean up
2200  pNewTable->GCLines();
2201 
2202  pTableNd->MakeOwnFrames( &aIdx ); // re-generate the Frames
2203 
2205 
2206  return true;
2207 }
2208 
2209 // Find the next Box with content from this Line
2211  const SwTableBox* pSrchBox, bool bOvrTableLns ) const
2212 {
2213  const SwTableLine* pLine = this; // for M800
2214  SwTableBox* pBox;
2215  sal_uInt16 nFndPos;
2216  if( !GetTabBoxes().empty() && pSrchBox )
2217  {
2218  nFndPos = GetBoxPos( pSrchBox );
2219  if( USHRT_MAX != nFndPos &&
2220  nFndPos + 1 != o3tl::narrowing<sal_uInt16>(GetTabBoxes().size()) )
2221  {
2222  pBox = GetTabBoxes()[ nFndPos + 1 ];
2223  while( !pBox->GetTabLines().empty() )
2224  pBox = pBox->GetTabLines().front()->GetTabBoxes()[0];
2225  return pBox;
2226  }
2227  }
2228 
2229  if( GetUpper() )
2230  {
2231  nFndPos = GetUpper()->GetTabLines().GetPos( pLine );
2232  OSL_ENSURE( USHRT_MAX != nFndPos, "Line is not in the Table" );
2233  // Is there another Line?
2234  if( nFndPos+1 >= o3tl::narrowing<sal_uInt16>(GetUpper()->GetTabLines().size()) )
2235  return GetUpper()->GetUpper()->FindNextBox( rTable, GetUpper(), bOvrTableLns );
2236  pLine = GetUpper()->GetTabLines()[nFndPos+1];
2237  }
2238  else if( bOvrTableLns ) // Over a Table's the "BaseLines"??
2239  {
2240  // Search for the next Line in the Table
2241  nFndPos = rTable.GetTabLines().GetPos( pLine );
2242  if( nFndPos + 1 >= o3tl::narrowing<sal_uInt16>(rTable.GetTabLines().size()) )
2243  return nullptr; // there are no more Boxes
2244 
2245  pLine = rTable.GetTabLines()[ nFndPos+1 ];
2246  }
2247  else
2248  return nullptr;
2249 
2250  if( !pLine->GetTabBoxes().empty() )
2251  {
2252  pBox = pLine->GetTabBoxes().front();
2253  while( !pBox->GetTabLines().empty() )
2254  pBox = pBox->GetTabLines().front()->GetTabBoxes().front();
2255  return pBox;
2256  }
2257  return pLine->FindNextBox( rTable, nullptr, bOvrTableLns );
2258 }
2259 
2260 // Find the previous Box from this Line
2262  const SwTableBox* pSrchBox, bool bOvrTableLns ) const
2263 {
2264  const SwTableLine* pLine = this; // for M800
2265  SwTableBox* pBox;
2266  sal_uInt16 nFndPos;
2267  if( !GetTabBoxes().empty() && pSrchBox )
2268  {
2269  nFndPos = GetBoxPos( pSrchBox );
2270  if( USHRT_MAX != nFndPos && nFndPos )
2271  {
2272  pBox = GetTabBoxes()[ nFndPos - 1 ];
2273  while( !pBox->GetTabLines().empty() )
2274  {
2275  pLine = pBox->GetTabLines().back();
2276  pBox = pLine->GetTabBoxes().back();
2277  }
2278  return pBox;
2279  }
2280  }
2281 
2282  if( GetUpper() )
2283  {
2284  nFndPos = GetUpper()->GetTabLines().GetPos( pLine );
2285  OSL_ENSURE( USHRT_MAX != nFndPos, "Line is not in the Table" );
2286  // Is there another Line?
2287  if( !nFndPos )
2288  return GetUpper()->GetUpper()->FindPreviousBox( rTable, GetUpper(), bOvrTableLns );
2289  pLine = GetUpper()->GetTabLines()[nFndPos-1];
2290  }
2291  else if( bOvrTableLns ) // Over a Table's the "BaseLines"??
2292  {
2293  // Search for the next Line in the Table
2294  nFndPos = rTable.GetTabLines().GetPos( pLine );
2295  if( !nFndPos )
2296  return nullptr; // there are no more Boxes
2297 
2298  pLine = rTable.GetTabLines()[ nFndPos-1 ];
2299  }
2300  else
2301  return nullptr;
2302 
2303  if( !pLine->GetTabBoxes().empty() )
2304  {
2305  pBox = pLine->GetTabBoxes().back();
2306  while( !pBox->GetTabLines().empty() )
2307  {
2308  pLine = pBox->GetTabLines().back();
2309  pBox = pLine->GetTabBoxes().back();
2310  }
2311  return pBox;
2312  }
2313  return pLine->FindPreviousBox( rTable, nullptr, bOvrTableLns );
2314 }
2315 
2316 // Find the next Box with content from this Line
2318  const SwTableBox* pSrchBox, bool bOvrTableLns ) const
2319 {
2320  if( !pSrchBox && GetTabLines().empty() )
2321  return const_cast<SwTableBox*>(this);
2322  return GetUpper()->FindNextBox( rTable, pSrchBox ? pSrchBox : this,
2323  bOvrTableLns );
2324 
2325 }
2326 
2327 // Find the next Box with content from this Line
2329  const SwTableBox* pSrchBox ) const
2330 {
2331  if( !pSrchBox && GetTabLines().empty() )
2332  return const_cast<SwTableBox*>(this);
2333  return GetUpper()->FindPreviousBox( rTable, pSrchBox ? pSrchBox : this );
2334 }
2335 
2336 static void lcl_BoxSetHeadCondColl( const SwTableBox* pBox )
2337 {
2338  // We need to adapt the paragraphs with conditional templates in the HeadLine
2339  const SwStartNode* pSttNd = pBox->GetSttNd();
2340  if( pSttNd )
2341  pSttNd->CheckSectionCondColl();
2342  else
2343  for( const SwTableLine* pLine : pBox->GetTabLines() )
2344  sw_LineSetHeadCondColl( pLine );
2345 }
2346 
2348 {
2349  for( const SwTableBox* pBox : pLine->GetTabBoxes() )
2350  lcl_BoxSetHeadCondColl(pBox);
2351 }
2352 
2353 static SwTwips lcl_GetDistance( SwTableBox* pBox, bool bLeft )
2354 {
2355  bool bFirst = true;
2356  SwTwips nRet = 0;
2357  SwTableLine* pLine;
2358  while( pBox )
2359  {
2360  pLine = pBox->GetUpper();
2361  if( !pLine )
2362  break;
2363  sal_uInt16 nStt = 0, nPos = pLine->GetBoxPos( pBox );
2364 
2365  if( bFirst && !bLeft )
2366  ++nPos;
2367  bFirst = false;
2368 
2369  while( nStt < nPos )
2370  nRet += pLine->GetTabBoxes()[ nStt++ ]->GetFrameFormat()
2371  ->GetFrameSize().GetWidth();
2372  pBox = pLine->GetUpper();
2373  }
2374  return nRet;
2375 }
2376 
2377 static bool lcl_SetSelBoxWidth( SwTableLine* pLine, CR_SetBoxWidth& rParam,
2378  SwTwips nDist, bool bCheck )
2379 {
2380  SwTableBoxes& rBoxes = pLine->GetTabBoxes();
2381  for( auto pBox : rBoxes )
2382  {
2383  SwFrameFormat* pFormat = pBox->GetFrameFormat();
2384  const SwFormatFrameSize& rSz = pFormat->GetFrameSize();
2385  SwTwips nWidth = rSz.GetWidth();
2386  bool bGreaterBox = false;
2387 
2388  if( bCheck )
2389  {
2390  for( auto pLn : pBox->GetTabLines() )
2391  if( !::lcl_SetSelBoxWidth( pLn, rParam, nDist, true ))
2392  return false;
2393 
2394  // Collect all "ContentBoxes"
2395  bGreaterBox = (TableChgMode::FixedWidthChangeAbs != rParam.nMode)
2396  && ((nDist + (rParam.bLeft ? 0 : nWidth)) >= rParam.nSide);
2397  if (bGreaterBox
2398  || (!rParam.bBigger
2399  && (std::abs(nDist + ((rParam.nMode != TableChgMode::FixedWidthChangeAbs && rParam.bLeft) ? 0 : nWidth) - rParam.nSide) < COLFUZZY)))
2400  {
2401  SwTwips nLowerDiff;
2402  if( bGreaterBox && TableChgMode::FixedWidthChangeProp == rParam.nMode )
2403  {
2404  // The "other Boxes" have been adapted, so change by this value
2405  nLowerDiff = (nDist + ( rParam.bLeft ? 0 : nWidth ) ) - rParam.nSide;
2406  nLowerDiff *= rParam.nDiff;
2407  nLowerDiff /= rParam.nMaxSize;
2408  nLowerDiff = rParam.nDiff - nLowerDiff;
2409  }
2410  else
2411  nLowerDiff = rParam.nDiff;
2412 
2413  if( nWidth < nLowerDiff || nWidth - nLowerDiff < MINLAY )
2414  return false;
2415  }
2416  }
2417  else
2418  {
2419  SwTwips nLowerDiff = 0, nOldLower = rParam.nLowerDiff;
2420  for( auto pLn : pBox->GetTabLines() )
2421  {
2422  rParam.nLowerDiff = 0;
2423  lcl_SetSelBoxWidth( pLn, rParam, nDist, false );
2424 
2425  if( nLowerDiff < rParam.nLowerDiff )
2426  nLowerDiff = rParam.nLowerDiff;
2427  }
2428  rParam.nLowerDiff = nOldLower;
2429 
2430  if( nLowerDiff ||
2431  (bGreaterBox = !nOldLower && TableChgMode::FixedWidthChangeAbs != rParam.nMode &&
2432  ( nDist + ( rParam.bLeft ? 0 : nWidth ) ) >= rParam.nSide) ||
2433  ( std::abs( nDist + ( (rParam.nMode != TableChgMode::FixedWidthChangeAbs && rParam.bLeft) ? 0 : nWidth )
2434  - rParam.nSide ) < COLFUZZY ))
2435  {
2436  // This column contains the Cursor - so decrease/increase
2437  SwFormatFrameSize aNew( rSz );
2438 
2439  if( !nLowerDiff )
2440  {
2441  if( bGreaterBox && TableChgMode::FixedWidthChangeProp == rParam.nMode )
2442  {
2443  // The "other Boxes" have been adapted, so change by this value
2444  nLowerDiff = (nDist + ( rParam.bLeft ? 0 : nWidth ) ) - rParam.nSide;
2445  nLowerDiff *= rParam.nDiff;
2446  nLowerDiff /= rParam.nMaxSize;
2447  nLowerDiff = rParam.nDiff - nLowerDiff;
2448  }
2449  else
2450  nLowerDiff = rParam.nDiff;
2451  }
2452 
2453  rParam.nLowerDiff += nLowerDiff;
2454 
2455  if( rParam.bBigger )
2456  aNew.SetWidth( nWidth + nLowerDiff );
2457  else
2458  aNew.SetWidth( nWidth - nLowerDiff );
2459  rParam.aShareFormats.SetSize( *pBox, aNew );
2460  break;
2461  }
2462  }
2463 
2464  if( rParam.bLeft && rParam.nMode != TableChgMode::FixedWidthChangeAbs && nDist >= rParam.nSide )
2465  break;
2466 
2467  nDist += nWidth;
2468 
2469  // If it gets bigger, then that's it
2470  if( ( TableChgMode::FixedWidthChangeAbs == rParam.nMode || !rParam.bLeft ) &&
2471  nDist >= rParam.nSide )
2472  break;
2473  }
2474  return true;
2475 }
2476 
2477 static bool lcl_SetOtherBoxWidth( SwTableLine* pLine, CR_SetBoxWidth& rParam,
2478  SwTwips nDist, bool bCheck )
2479 {
2480  SwTableBoxes& rBoxes = pLine->GetTabBoxes();
2481  for( auto pBox : rBoxes )
2482  {
2483  SwFrameFormat* pFormat = pBox->GetFrameFormat();
2484  const SwFormatFrameSize& rSz = pFormat->GetFrameSize();
2485  SwTwips nWidth = rSz.GetWidth();
2486 
2487  if( bCheck )
2488  {
2489  for( auto pLn : pBox->GetTabLines() )
2490  if( !::lcl_SetOtherBoxWidth( pLn, rParam, nDist, true ))
2491  return false;
2492 
2493  if( rParam.bBigger && ( TableChgMode::FixedWidthChangeAbs == rParam.nMode
2494  ? std::abs( nDist - rParam.nSide ) < COLFUZZY
2495  : ( rParam.bLeft ? nDist < rParam.nSide - COLFUZZY
2496  : nDist >= rParam.nSide - COLFUZZY )) )
2497  {
2498  SwTwips nDiff;
2499  if( TableChgMode::FixedWidthChangeProp == rParam.nMode ) // Table fixed, proportional
2500  {
2501  // calculate relative
2502  nDiff = nWidth;
2503  nDiff *= rParam.nDiff;
2504  nDiff /= rParam.nMaxSize;
2505  }
2506  else
2507  nDiff = rParam.nDiff;
2508 
2509  if( nWidth < nDiff || nWidth - nDiff < MINLAY )
2510  return false;
2511  }
2512  }
2513  else
2514  {
2515  SwTwips nLowerDiff = 0, nOldLower = rParam.nLowerDiff;
2516  for( auto pLn : pBox->GetTabLines() )
2517  {
2518  rParam.nLowerDiff = 0;
2519  lcl_SetOtherBoxWidth( pLn, rParam, nDist, false );
2520 
2521  if( nLowerDiff < rParam.nLowerDiff )
2522  nLowerDiff = rParam.nLowerDiff;
2523  }
2524  rParam.nLowerDiff = nOldLower;
2525 
2526  if( nLowerDiff ||
2527  ( TableChgMode::FixedWidthChangeAbs == rParam.nMode
2528  ? std::abs( nDist - rParam.nSide ) < COLFUZZY
2529  : ( rParam.bLeft ? nDist < rParam.nSide - COLFUZZY
2530  : nDist >= rParam.nSide - COLFUZZY)
2531  ) )
2532  {
2533  SwFormatFrameSize aNew( rSz );
2534 
2535  if( !nLowerDiff )
2536  {
2537  if( TableChgMode::FixedWidthChangeProp == rParam.nMode ) // Table fixed, proportional
2538  {
2539  // calculate relative
2540  nLowerDiff = nWidth;
2541  nLowerDiff *= rParam.nDiff;
2542  nLowerDiff /= rParam.nMaxSize;
2543  }
2544  else
2545  nLowerDiff = rParam.nDiff;
2546  }
2547 
2548  rParam.nLowerDiff += nLowerDiff;
2549 
2550  if( rParam.bBigger )
2551  aNew.SetWidth( nWidth - nLowerDiff );
2552  else
2553  aNew.SetWidth( nWidth + nLowerDiff );
2554 
2555  rParam.aShareFormats.SetSize( *pBox, aNew );
2556  }
2557  }
2558 
2559  nDist += nWidth;
2560  if( ( TableChgMode::FixedWidthChangeAbs == rParam.nMode || rParam.bLeft ) &&
2561  nDist > rParam.nSide )
2562  break;
2563  }
2564  return true;
2565 }
2566 
2567 static void lcl_AjustLines( SwTableLine* pLine, CR_SetBoxWidth& rParam )
2568 {
2569  SwTableBoxes& rBoxes = pLine->GetTabBoxes();
2570  for( auto pBox : rBoxes )
2571  {
2572  SwFormatFrameSize aSz( pBox->GetFrameFormat()->GetFrameSize() );
2573  SwTwips nWidth = aSz.GetWidth();
2574  nWidth *= rParam.nDiff;
2575  nWidth /= rParam.nMaxSize;
2576  aSz.SetWidth( nWidth );
2577  rParam.aShareFormats.SetSize( *pBox, aSz );
2578 
2579  for( auto pLn : pBox->GetTabLines() )
2580  ::lcl_AjustLines( pLn, rParam );
2581  }
2582 }
2583 
2584 #ifdef DBG_UTIL
2585 void CheckBoxWidth( const SwTableLine& rLine, SwTwips nSize )
2586 {
2587  const SwTableBoxes& rBoxes = rLine.GetTabBoxes();
2588 
2589  SwTwips nCurrentSize = 0;
2590  // See if the tables have a correct width
2591  for (const SwTableBox* pBox : rBoxes)
2592  {
2593  const SwTwips nBoxW = pBox->GetFrameFormat()->GetFrameSize().GetWidth();
2594  nCurrentSize += nBoxW;
2595 
2596  for( auto pLn : pBox->GetTabLines() )
2597  CheckBoxWidth( *pLn, nBoxW );
2598  }
2599 
2600  if (sal::static_int_cast< tools::ULong >(std::abs(nCurrentSize - nSize)) >
2601  (COLFUZZY * rBoxes.size()))
2602  {
2603  OSL_FAIL( "Line's Boxes are too small or too large" );
2604  }
2605 }
2606 #endif
2607 
2609  SwTwips nAbsDiff, SwTwips nRelDiff, std::unique_ptr<SwUndo>* ppUndo )
2610 {
2611  SetHTMLTableLayout(std::shared_ptr<SwHTMLTableLayout>()); // Delete HTML Layout
2612 
2613  const SwFormatFrameSize& rSz = GetFrameFormat()->GetFrameSize();
2614  const SvxLRSpaceItem& rLR = GetFrameFormat()->GetLRSpace();
2615 
2616  bool bBigger,
2617  bRet = false,
2618  bLeft = TableChgWidthHeightType::ColLeft == extractPosition( eType ) ||
2620 
2621  // Get the current Box's edge
2622  // Only needed for manipulating the width
2623  const SwTwips nDist = ::lcl_GetDistance( &rCurrentBox, bLeft );
2624  SwTwips nDistStt = 0;
2625  CR_SetBoxWidth aParam( eType, nRelDiff, nDist,
2626  bLeft ? nDist : rSz.GetWidth() - nDist,
2627  const_cast<SwTableNode*>(rCurrentBox.GetSttNd()->FindTableNode()) );
2628  bBigger = aParam.bBigger;
2629 
2630  FN_lcl_SetBoxWidth fnSelBox, fnOtherBox;
2631  fnSelBox = lcl_SetSelBoxWidth;
2632  fnOtherBox = lcl_SetOtherBoxWidth;
2633 
2634  switch( extractPosition(eType) )
2635  {
2638  if( TableChgMode::VarWidthChangeAbs == m_eTableChgMode )
2639  {
2640  // First test if we have room at all
2641  bool bChgLRSpace = true;
2642  if( bBigger )
2643  {
2644  if( GetFrameFormat()->getIDocumentSettingAccess().get(DocumentSettingId::BROWSE_MODE) &&
2645  !rSz.GetWidthPercent() )
2646  {
2647  // silence -Wsign-compare on Android with the static cast
2648  bRet = rSz.GetWidth() < static_cast<unsigned short>(USHRT_MAX) - nRelDiff;
2649  bChgLRSpace = bLeft ? rLR.GetLeft() >= nAbsDiff
2650  : rLR.GetRight() >= nAbsDiff;
2651  }
2652  else
2653  bRet = bLeft ? rLR.GetLeft() >= nAbsDiff
2654  : rLR.GetRight() >= nAbsDiff;
2655 
2656  if( !bRet )
2657  {
2658  // Then call itself recursively; only with another mode (proportional)
2659  TableChgMode eOld = m_eTableChgMode;
2660  m_eTableChgMode = TableChgMode::FixedWidthChangeProp;
2661 
2662  bRet = SetColWidth( rCurrentBox, eType, nAbsDiff, nRelDiff,
2663  ppUndo );
2664  m_eTableChgMode = eOld;
2665  return bRet;
2666  }
2667  }
2668  else
2669  {
2670  bRet = true;
2671  for( auto const & n: m_aLines )
2672  {
2673  aParam.LoopClear();
2674  if( !(*fnSelBox)( n, aParam, nDistStt, true ))
2675  {
2676  bRet = false;
2677  break;
2678  }
2679  }
2680  }
2681 
2682  if( bRet )
2683  {
2684  if( ppUndo )
2685  ppUndo->reset(new SwUndoAttrTable( *aParam.pTableNd, true ));
2686 
2687  tools::Long nFrameWidth = LONG_MAX;
2688  LockModify();
2689  SwFormatFrameSize aSz( rSz );
2690  SvxLRSpaceItem aLR( rLR );
2691  if( bBigger )
2692  {
2693  // If the Table does not have any room to grow, we need to create some!
2694  // silence -Wsign-compare on Android with the static cast
2695  if( aSz.GetWidth() + nRelDiff > static_cast<unsigned short>(USHRT_MAX) )
2696  {
2697  // Break down to USHRT_MAX / 2
2698  CR_SetBoxWidth aTmpPara( TableChgWidthHeightType::ColLeft, aSz.GetWidth() / 2,
2699  0, aSz.GetWidth(), aParam.pTableNd );
2700  for( size_t nLn = 0; nLn < m_aLines.size(); ++nLn )
2701  ::lcl_AjustLines( m_aLines[ nLn ], aTmpPara );
2702  aSz.SetWidth( aSz.GetWidth() / 2 );
2703  aParam.nDiff = nRelDiff /= 2;
2704  aParam.nSide /= 2;
2705  aParam.nMaxSize /= 2;
2706  }
2707 
2708  if( bLeft )
2709  aLR.SetLeft( sal_uInt16( aLR.GetLeft() - nAbsDiff ) );
2710  else
2711  aLR.SetRight( sal_uInt16( aLR.GetRight() - nAbsDiff ) );
2712  }
2713  else if( bLeft )
2714  aLR.SetLeft( sal_uInt16( aLR.GetLeft() + nAbsDiff ) );
2715  else
2716  aLR.SetRight( sal_uInt16( aLR.GetRight() + nAbsDiff ) );
2717 
2718  if( bChgLRSpace )
2719  GetFrameFormat()->SetFormatAttr( aLR );
2720  const SwFormatHoriOrient& rHOri = GetFrameFormat()->GetHoriOrient();
2721  if( text::HoriOrientation::FULL == rHOri.GetHoriOrient() ||
2722  (text::HoriOrientation::LEFT == rHOri.GetHoriOrient() && aLR.GetLeft()) ||
2723  (text::HoriOrientation::RIGHT == rHOri.GetHoriOrient() && aLR.GetRight()))
2724  {
2725  SwFormatHoriOrient aHOri( rHOri );
2727  GetFrameFormat()->SetFormatAttr( aHOri );
2728 
2729  // If the Table happens to contain relative values (USHORT_MAX),
2730  // we need to convert them to absolute ones now.
2731  // Bug 61494
2732  if( GetFrameFormat()->getIDocumentSettingAccess().get(DocumentSettingId::BROWSE_MODE) &&
2733  !rSz.GetWidthPercent() )
2734  {
2735  SwTabFrame* pTabFrame = SwIterator<SwTabFrame,SwFormat>( *GetFrameFormat() ).First();
2736  if( pTabFrame &&
2737  pTabFrame->getFramePrintArea().Width() != rSz.GetWidth() )
2738  {
2739  nFrameWidth = pTabFrame->getFramePrintArea().Width();
2740  if( bBigger )
2741  nFrameWidth += nAbsDiff;
2742  else
2743  nFrameWidth -= nAbsDiff;
2744  }
2745  }
2746  }
2747 
2748  if( bBigger )
2749  aSz.SetWidth( aSz.GetWidth() + nRelDiff );
2750  else
2751  aSz.SetWidth( aSz.GetWidth() - nRelDiff );
2752 
2753  if( rSz.GetWidthPercent() )
2754  aSz.SetWidthPercent( static_cast<sal_uInt8>(( aSz.GetWidth() * 100 ) /
2755  ( aSz.GetWidth() + aLR.GetRight() + aLR.GetLeft())));
2756 
2757  GetFrameFormat()->SetFormatAttr( aSz );
2758 
2759  UnlockModify();
2760 
2761  for( sal_uInt16 n = m_aLines.size(); n; )
2762  {
2763  --n;
2764  aParam.LoopClear();
2765  (*fnSelBox)( m_aLines[ n ], aParam, nDistStt, false );
2766  }
2767 
2768  // If the Table happens to contain relative values (USHORT_MAX),
2769  // we need to convert them to absolute ones now.
2770  // Bug 61494
2771  if( LONG_MAX != nFrameWidth )
2772  {
2773  SwFormatFrameSize aAbsSz( aSz );
2774  aAbsSz.SetWidth( nFrameWidth );
2775  GetFrameFormat()->SetFormatAttr( aAbsSz );
2776  }
2777  }
2778  }
2779  else if( bLeft ? nDist != 0 : std::abs( rSz.GetWidth() - nDist ) > COLFUZZY )
2780  {
2781  bRet = true;
2782  if( bLeft && TableChgMode::FixedWidthChangeAbs == m_eTableChgMode )
2783  aParam.bBigger = !bBigger;
2784 
2785  // First test if we have room at all
2786  if( aParam.bBigger )
2787  {
2788  for( auto const & n: m_aLines )
2789  {
2790  aParam.LoopClear();
2791  if( !(*fnOtherBox)( n, aParam, 0, true ))
2792  {
2793  bRet = false;
2794  break;
2795  }
2796  }
2797  }
2798  else
2799  {
2800  for( auto const & n: m_aLines )
2801  {
2802  aParam.LoopClear();
2803  if( !(*fnSelBox)( n, aParam, nDistStt, true ))
2804  {
2805  bRet = false;
2806  break;
2807  }
2808  }
2809  }
2810 
2811  // If true, set it
2812  if( bRet )
2813  {
2814  CR_SetBoxWidth aParam1( aParam );
2815  if( ppUndo )
2816  ppUndo->reset(new SwUndoAttrTable( *aParam.pTableNd, true ));
2817 
2818  if( TableChgMode::FixedWidthChangeAbs != m_eTableChgMode && bLeft )
2819  {
2820  for( sal_uInt16 n = m_aLines.size(); n; )
2821  {
2822  --n;
2823  aParam.LoopClear();
2824  aParam1.LoopClear();
2825  (*fnSelBox)( m_aLines[ n ], aParam, nDistStt, false );
2826  (*fnOtherBox)( m_aLines[ n ], aParam1, nDistStt, false );
2827  }
2828  }
2829  else
2830  {
2831  for( sal_uInt16 n = m_aLines.size(); n; )
2832  {
2833  --n;
2834  aParam.LoopClear();
2835  aParam1.LoopClear();
2836  (*fnOtherBox)( m_aLines[ n ], aParam1, nDistStt, false );
2837  (*fnSelBox)( m_aLines[ n ], aParam, nDistStt, false );
2838  }
2839  }
2840  }
2841  }
2842  break;
2843 
2846  if( TableChgMode::VarWidthChangeAbs == m_eTableChgMode )
2847  {
2848  // Then call itself recursively; only with another mode (proportional)
2849  TableChgMode eOld = m_eTableChgMode;
2850  m_eTableChgMode = TableChgMode::FixedWidthChangeAbs;
2851 
2852  bRet = SetColWidth( rCurrentBox, eType, nAbsDiff, nRelDiff,
2853  ppUndo );
2854  m_eTableChgMode = eOld;
2855  return bRet;
2856  }
2857  else if( bLeft ? nDist != 0 : (rSz.GetWidth() - nDist) > COLFUZZY )
2858  {
2859  if( bLeft && TableChgMode::FixedWidthChangeAbs == m_eTableChgMode )
2860  aParam.bBigger = !bBigger;
2861 
2862  // First, see if there is enough room at all
2863  SwTableBox* pBox = &rCurrentBox;
2864  SwTableLine* pLine = rCurrentBox.GetUpper();
2865  while( pLine->GetUpper() )
2866  {
2867  const SwTableBoxes::size_type nPos = pLine->GetBoxPos( pBox );
2868  if( bLeft ? nPos != 0 : nPos + 1 != pLine->GetTabBoxes().size() )
2869  break;
2870 
2871  pBox = pLine->GetUpper();
2872  pLine = pBox->GetUpper();
2873  }
2874 
2875  if( pLine->GetUpper() )
2876  {
2877  // We need to correct the distance once again!
2878  aParam.nSide -= ::lcl_GetDistance( pLine->GetUpper(), true );
2879 
2880  if( bLeft )
2881  aParam.nMaxSize = aParam.nSide;
2882  else
2883  aParam.nMaxSize = pLine->GetUpper()->GetFrameFormat()->
2884  GetFrameSize().GetWidth() - aParam.nSide;
2885  }
2886 
2887  // First, see if there is enough room at all
2888  FN_lcl_SetBoxWidth fnTmp = aParam.bBigger ? fnOtherBox : fnSelBox;
2889  bRet = (*fnTmp)( pLine, aParam, nDistStt, true );
2890 
2891  // If true, set it
2892  if( bRet )
2893  {
2894  CR_SetBoxWidth aParam1( aParam );
2895  if( ppUndo )
2896  ppUndo->reset(new SwUndoAttrTable( *aParam.pTableNd, true ));
2897 
2898  if( TableChgMode::FixedWidthChangeAbs != m_eTableChgMode && bLeft )
2899  {
2900  (*fnSelBox)( pLine, aParam, nDistStt, false );
2901  (*fnOtherBox)( pLine, aParam1, nDistStt, false );
2902  }
2903  else
2904  {
2905  (*fnOtherBox)( pLine, aParam1, nDistStt, false );
2906  (*fnSelBox)( pLine, aParam, nDistStt, false );
2907  }
2908  }
2909  }
2910  break;
2911  default: break;
2912  }
2913 
2914 #if defined DBG_UTIL
2915  if( bRet )
2916  {
2919  }
2920 #endif
2921 
2922  return bRet;
2923 }
2924 
2925 static void SetLineHeight( SwTableLine& rLine, SwTwips nOldHeight, SwTwips nNewHeight,
2926  bool bMinSize )
2927 {
2928  SwLayoutFrame* pLineFrame = GetRowFrame( rLine );
2929  OSL_ENSURE( pLineFrame, "Where is the Frame from the SwTableLine?" );
2930 
2931  SwFrameFormat* pFormat = rLine.ClaimFrameFormat();
2932 
2933  SwTwips nMyNewH, nMyOldH = pLineFrame->getFrameArea().Height();
2934  if( !nOldHeight ) // the BaseLine and absolute
2935  nMyNewH = nMyOldH + nNewHeight;
2936  else
2937  {
2938  // Calculate as exactly as possible
2939  Fraction aTmp( nMyOldH );
2940  aTmp *= Fraction( nNewHeight, nOldHeight );
2941  aTmp += Fraction( 1, 2 ); // round up if needed
2942  nMyNewH = tools::Long(aTmp);
2943  }
2944 
2946  if( !bMinSize &&
2947  ( nMyOldH - nMyNewH ) > ( CalcRowRstHeight( pLineFrame ) + ROWFUZZY ))
2948  eSize = SwFrameSize::Fixed;
2949 
2950  pFormat->SetFormatAttr( SwFormatFrameSize( eSize, 0, nMyNewH ) );
2951 
2952  // First adapt all internal ones
2953  for( auto pBox : rLine.GetTabBoxes() )
2954  {
2955  for( auto pLine : pBox->GetTabLines() )
2956  SetLineHeight( *pLine, nMyOldH, nMyNewH, bMinSize );
2957  }
2958 }
2959 
2960 static bool lcl_SetSelLineHeight( SwTableLine* pLine, const CR_SetLineHeight& rParam,
2961  SwTwips nDist, bool bCheck )
2962 {
2963  bool bRet = true;
2964  if( !bCheck )
2965  {
2966  // Set line height
2967  SetLineHeight( *pLine, 0, rParam.bBigger ? nDist : -nDist,
2968  rParam.bBigger );
2969  }
2970  else if( !rParam.bBigger )
2971  {
2972  // Calculate the new relative size by means of the old one
2973  SwLayoutFrame* pLineFrame = GetRowFrame( *pLine );
2974  OSL_ENSURE( pLineFrame, "Where is the Frame from the SwTableLine?" );
2975  SwTwips nRstHeight = CalcRowRstHeight( pLineFrame );
2976  if( (nRstHeight + ROWFUZZY) < nDist )
2977  bRet = false;
2978  }
2979  return bRet;
2980 }
2981 
2982 static bool lcl_SetOtherLineHeight( SwTableLine* pLine, const CR_SetLineHeight& rParam,
2983  SwTwips nDist, bool bCheck )
2984 {
2985  bool bRet = true;
2986  if( bCheck )
2987  {
2988  if( rParam.bBigger )
2989  {
2990  // Calculate the new relative size by means of the old one
2991  SwLayoutFrame* pLineFrame = GetRowFrame( *pLine );
2992  OSL_ENSURE( pLineFrame, "Where is the Frame from the SwTableLine?" );
2993 
2994  if( TableChgMode::FixedWidthChangeProp == rParam.nMode )
2995  {
2996  nDist *= pLineFrame->getFrameArea().Height();
2997  nDist /= rParam.nMaxHeight;
2998  }
2999  bRet = nDist <= CalcRowRstHeight( pLineFrame );
3000  }
3001  }
3002  else
3003  {
3004  // Set line height
3005  // pLine is the following/preceding, thus adjust it
3006  if( TableChgMode::FixedWidthChangeProp == rParam.nMode )
3007  {
3008  SwLayoutFrame* pLineFrame = GetRowFrame( *pLine );
3009  OSL_ENSURE( pLineFrame, "Where is the Frame from the SwTableLine??" );
3010 
3011  // Calculate the new relative size by means of the old one
3012  // If the selected Box get bigger, adjust via the max space else
3013  // via the max height.
3014  if( (true) )
3015  {
3016  nDist *= pLineFrame->getFrameArea().Height();
3017  nDist /= rParam.nMaxHeight;
3018  }
3019  else
3020  {
3021  // Calculate the new relative size by means of the old one
3022  nDist *= CalcRowRstHeight( pLineFrame );
3023  nDist /= rParam.nMaxSpace;
3024  }
3025  }
3026  SetLineHeight( *pLine, 0, rParam.bBigger ? -nDist : nDist,
3027  !rParam.bBigger );
3028  }
3029  return bRet;
3030 }
3031 
3033  SwTwips nAbsDiff, SwTwips nRelDiff, std::unique_ptr<SwUndo>* ppUndo )
3034 {
3035  SwTableLine* pLine = rCurrentBox.GetUpper();
3036 
3037  SwTableLine* pBaseLine = pLine;
3038  while( pBaseLine->GetUpper() )
3039  pBaseLine = pBaseLine->GetUpper()->GetUpper();
3040 
3041  bool bBigger,
3042  bRet = false,
3044  sal_uInt16 nBaseLinePos = GetTabLines().GetPos( pBaseLine );
3045 
3046  CR_SetLineHeight aParam( eType,
3047  const_cast<SwTableNode*>(rCurrentBox.GetSttNd()->FindTableNode()) );
3048  bBigger = aParam.bBigger;
3049 
3050  SwTableLines* pLines = &m_aLines;
3051 
3052  // How do we get to the height?
3053  switch( extractPosition(eType) )
3054  {
3057  if( pLine == pBaseLine )
3058  break; // it doesn't work then!
3059 
3060  // Is a nested Line (Box!)
3061  pLines = &pLine->GetUpper()->GetTabLines();
3062  nBaseLinePos = pLines->GetPos( pLine );
3063  [[fallthrough]];
3064 
3066  {
3067  if( TableChgMode::VarWidthChangeAbs == m_eTableChgMode )
3068  {
3069  // First test if we have room at all
3070  if( bBigger )
3071  bRet = true;
3072  else
3073  bRet = lcl_SetSelLineHeight( (*pLines)[ nBaseLinePos ], aParam,
3074  nAbsDiff, true );
3075 
3076  if( bRet )
3077  {
3078  if( ppUndo )
3079  ppUndo->reset(new SwUndoAttrTable( *aParam.pTableNd, true ));
3080 
3081  lcl_SetSelLineHeight( (*pLines)[ nBaseLinePos ], aParam,
3082  nAbsDiff, false );
3083  }
3084  }
3085  else
3086  {
3087  bRet = true;
3090  if( bTop )
3091  {
3092  nStt = 0;
3093  nEnd = nBaseLinePos;
3094  }
3095  else
3096  {
3097  nStt = nBaseLinePos + 1;
3098  nEnd = pLines->size();
3099  }
3100 
3101  // Get the current Lines' height
3102  if( TableChgMode::FixedWidthChangeProp == m_eTableChgMode )
3103  {
3104  for( auto n = nStt; n < nEnd; ++n )
3105  {
3106  SwLayoutFrame* pLineFrame = GetRowFrame( *(*pLines)[ n ] );
3107  OSL_ENSURE( pLineFrame, "Where is the Frame from the SwTableLine??" );
3108  aParam.nMaxSpace += CalcRowRstHeight( pLineFrame );
3109  aParam.nMaxHeight += pLineFrame->getFrameArea().Height();
3110  }
3111  if( bBigger && aParam.nMaxSpace < nAbsDiff )
3112  bRet = false;
3113  }
3114  else
3115  {
3116  if( bTop ? nEnd != 0 : nStt < nEnd )
3117  {
3118  if( bTop )
3119  nStt = nEnd - 1;
3120  else
3121  nEnd = nStt + 1;
3122  }
3123  else
3124  bRet = false;
3125  }
3126 
3127  if( bRet )
3128  {
3129  if( bBigger )
3130  {
3131  for( auto n = nStt; n < nEnd; ++n )
3132  {
3133  if( !lcl_SetOtherLineHeight( (*pLines)[ n ], aParam,
3134  nAbsDiff, true ))
3135  {
3136  bRet = false;
3137  break;
3138  }
3139  }
3140  }
3141  else
3142  bRet = lcl_SetSelLineHeight( (*pLines)[ nBaseLinePos ], aParam,
3143  nAbsDiff, true );
3144  }
3145 
3146  if( bRet )
3147  {
3148  // Adjust
3149  if( ppUndo )
3150  ppUndo->reset(new SwUndoAttrTable( *aParam.pTableNd, true ));
3151 
3152  CR_SetLineHeight aParam1( aParam );
3153 
3154  if( bTop )
3155  {
3156  lcl_SetSelLineHeight( (*pLines)[ nBaseLinePos ], aParam,
3157  nAbsDiff, false );
3158  for( auto n = nStt; n < nEnd; ++n )
3159  lcl_SetOtherLineHeight( (*pLines)[ n ], aParam1,
3160  nAbsDiff, false );
3161  }
3162  else
3163  {
3164  for( auto n = nStt; n < nEnd; ++n )
3165  lcl_SetOtherLineHeight( (*pLines)[ n ], aParam1,
3166  nAbsDiff, false );
3167  lcl_SetSelLineHeight( (*pLines)[ nBaseLinePos ], aParam,
3168  nAbsDiff, false );
3169  }
3170  }
3171  else
3172  {
3173  // Then call itself recursively; only with another mode (proportional)
3174  TableChgMode eOld = m_eTableChgMode;
3175  m_eTableChgMode = TableChgMode::VarWidthChangeAbs;
3176 
3177  bRet = SetRowHeight( rCurrentBox, eType, nAbsDiff,
3178  nRelDiff, ppUndo );
3179 
3180  m_eTableChgMode = eOld;
3181  }
3182  }
3183  }
3184  break;
3185  default: break;
3186  }
3187 
3189 
3190  return bRet;
3191 }
3192 
3194 {
3195  SwFrameFormat *pRet = nullptr, *pTmp;
3196  for( auto n = m_aNewFormats.size(); n; )
3197  if( ( pTmp = m_aNewFormats[ --n ])->GetFrameSize().GetWidth()
3198  == nWidth )
3199  {
3200  pRet = pTmp;
3201  break;
3202  }
3203  return pRet;
3204 }
3205 
3207 {
3208  const SfxPoolItem* pItem;
3209  sal_uInt16 nWhich = rItem.Which();
3210  SwFrameFormat *pRet = nullptr, *pTmp;
3211  const SfxPoolItem& rFrameSz = m_pOldFormat->GetFormatAttr( RES_FRM_SIZE, false );
3212  for( auto n = m_aNewFormats.size(); n; )
3213  if( SfxItemState::SET == ( pTmp = m_aNewFormats[ --n ])->
3214  GetItemState( nWhich, false, &pItem ) && *pItem == rItem &&
3215  pTmp->GetFormatAttr( RES_FRM_SIZE, false ) == rFrameSz )
3216  {
3217  pRet = pTmp;
3218  break;
3219  }
3220  return pRet;
3221 }
3222 
3224 {
3225  m_aNewFormats.push_back( &rNew );
3226 }
3227 
3229 {
3230  // returns true, if we can delete
3231  if( m_pOldFormat == &rFormat )
3232  return true;
3233 
3234  std::vector<SwFrameFormat*>::iterator it = std::find( m_aNewFormats.begin(), m_aNewFormats.end(), &rFormat );
3235  if( m_aNewFormats.end() != it )
3236  m_aNewFormats.erase( it );
3237  return m_aNewFormats.empty();
3238 }
3239 
3241 {
3242 }
3243 
3245 {
3246  sal_uInt16 nPos;
3247  return Seek_Entry( rFormat, &nPos )
3248  ? m_ShareArr[ nPos ].GetFormat(nWidth)
3249  : nullptr;
3250 }
3252  const SfxPoolItem& rItem ) const
3253 {
3254  sal_uInt16 nPos;
3255  return Seek_Entry( rFormat, &nPos )
3256  ? m_ShareArr[ nPos ].GetFormat(rItem)
3257  : nullptr;
3258 }
3259 
3261 {
3262  sal_uInt16 nPos;
3263  if( !Seek_Entry( rOld, &nPos ))
3264  {
3265  SwShareBoxFormat aEntry(rOld);
3266  aEntry.AddFormat( rNew );
3267  m_ShareArr.insert(m_ShareArr.begin() + nPos, aEntry);
3268  }
3269  else
3270  m_ShareArr[ nPos ].AddFormat(rNew);
3271 }
3272 
3274  SwFrameFormat& rFormat )
3275 {
3276  SwClient aCl;
3277  SwFrameFormat* pOld = nullptr;
3278  if( pBox )
3279  {
3280  pOld = pBox->GetFrameFormat();
3281  pOld->Add( &aCl );
3282  pBox->ChgFrameFormat( static_cast<SwTableBoxFormat*>(&rFormat) );
3283  }
3284  else if( pLn )
3285  {
3286  pOld = pLn->GetFrameFormat();
3287  pOld->Add( &aCl );
3288  pLn->ChgFrameFormat( static_cast<SwTableLineFormat*>(&rFormat) );
3289  }
3290  if( pOld && pOld->HasOnlyOneListener() )
3291  {
3292  RemoveFormat( *pOld );
3293  delete pOld;
3294  }
3295 }
3296 
3298 {
3299  SwFrameFormat *pBoxFormat = rBox.GetFrameFormat(),
3300  *pRet = GetFormat( *pBoxFormat, rSz.GetWidth() );
3301  if( pRet )
3302  ChangeFrameFormat( &rBox, nullptr, *pRet );
3303  else
3304  {
3305  pRet = rBox.ClaimFrameFormat();
3306  pRet->SetFormatAttr( rSz );
3307  AddFormat( *pBoxFormat, *pRet );
3308  }
3309 }
3310 
3312 {
3313  SwFrameFormat *pBoxFormat = rBox.GetFrameFormat(),
3314  *pRet = GetFormat( *pBoxFormat, rItem );
3315  if( pRet )
3316  ChangeFrameFormat( &rBox, nullptr, *pRet );
3317  else
3318  {
3319  pRet = rBox.ClaimFrameFormat();
3320  pRet->SetFormatAttr( rItem );
3321  AddFormat( *pBoxFormat, *pRet );
3322  }
3323 }
3324 
3326 {
3327  SwFrameFormat *pLineFormat = rLine.GetFrameFormat(),
3328  *pRet = GetFormat( *pLineFormat, rItem );
3329  if( pRet )
3330  ChangeFrameFormat( nullptr, &rLine, *pRet );
3331  else
3332  {
3333  pRet = rLine.ClaimFrameFormat();
3334  pRet->SetFormatAttr( rItem );
3335  AddFormat( *pLineFormat, *pRet );
3336  }
3337 }
3338 
3340 {
3341  for (auto i = m_ShareArr.size(); i; )
3342  {
3343  if (m_ShareArr[ --i ].RemoveFormat(rFormat))
3344  {
3345  m_ShareArr.erase( m_ShareArr.begin() + i );
3346  }
3347  }
3348 }
3349 
3350 bool SwShareBoxFormats::Seek_Entry( const SwFrameFormat& rFormat, sal_uInt16* pPos ) const
3351 {
3352  sal_uIntPtr nIdx = reinterpret_cast<sal_uIntPtr>(&rFormat);
3353  auto nO = m_ShareArr.size();
3354  decltype(nO) nU = 0;
3355  if( nO > 0 )
3356  {
3357  nO--;
3358  while( nU <= nO )
3359  {
3360  const auto nM = nU + ( nO - nU ) / 2;
3361  sal_uIntPtr nFormat = reinterpret_cast<sal_uIntPtr>(&m_ShareArr[ nM ].GetOldFormat());
3362  if( nFormat == nIdx )
3363  {
3364  if( pPos )
3365  *pPos = nM;
3366  return true;
3367  }
3368  else if( nFormat < nIdx )
3369  nU = nM + 1;
3370  else if( nM == 0 )
3371  {
3372  if( pPos )
3373  *pPos = nU;
3374  return false;
3375  }
3376  else
3377  nO = nM - 1;
3378  }
3379  }
3380  if( pPos )
3381  *pPos = nU;
3382  return false;
3383 }
3384 
3385 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void AddRowCols(const SwTable &rTable, const SwSelBoxes &rBoxes, sal_uInt16 nLines, bool bBehind)
SwChartDataProvider::AddRowCols tries to notify charts of added columns or rows and extends the value...
Definition: unochart.cxx:1552
Instances of SwFields and those derived from it occur 0 to n times.
Definition: fldbas.hxx:241
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:694
Starts a section of nodes in the document model.
Definition: node.hxx:313
std::vector< SwTableLine * >::size_type size_type
Definition: swtable.hxx:68
const FndLines_t & GetLines() const
Definition: tblsel.hxx:173
tools::Long GetWidth() const
const SwTableLine * GetLine() const
Definition: tblsel.hxx:205
const_iterator lower_bound(const Value &x) const
void Add(SwClient *pDepend)
Definition: calbck.cxx:172
void SetRight(const tools::Long nR, const sal_uInt16 nProp=100)
SwNodeOffset EndOfSectionIndex() const
Definition: node.hxx:689
void SetRowsToRepeat(sal_uInt16 nNumOfRows)
Definition: swtable.hxx:197
Marks a position in the document model.
Definition: pam.hxx:36
static SwTwips lcl_GetDistance(SwTableBox *pBox, bool bLeft)
Definition: tblrwcl.cxx:2353
constexpr TypedWhichId< SvxPrintItem > RES_PRINT(98)
void DelFrames(SwRootFrame const *pLayout=nullptr)
Method deletes all views of document for the node.
Definition: ndtbl.cxx:2439
static void lcl_CopyLineToDoc(FndLine_ const &rpFndLn, CpyPara *const pCpyPara)
constexpr TypedWhichId< SwTableBoxNumFormat > RES_BOXATR_FORMAT(RES_BOXATR_BEGIN)
void AddNewBox(SwNodeOffset nSttNdIdx)
Definition: UndoTable.hxx:233
SwDocShell * GetDocShell()
Definition: doc.hxx:1351
static void lcl_CopyCol(FndBox_ &rFndBox, CpyPara *const pCpyPara)
Definition: tblrwcl.cxx:249
static void lcl_CpyLines(sal_uInt16 nStt, sal_uInt16 nEnd, SwTableLines &rLines, SwTableBox *pInsBox, sal_uInt16 nPos=USHRT_MAX)
Definition: tblrwcl.cxx:1290
static void lcl_LastBoxSetWidth(SwTableBoxes &rBoxes, const tools::Long nOffset, bool bFirst, SwShareBoxFormats &rShareFormats)
Definition: tblrwcl.cxx:643
SwNodeIndex nNode
Definition: pam.hxx:38
constexpr TypedWhichId< SwFormatFrameSize > RES_FRM_SIZE(89)
sal_uIntPtr sal_uLong
#define ROWFUZZY
Definition: tblrwcl.cxx:66
long Long
tools::Long GetRight() const
const SwRect & getFramePrintArea() const
Definition: frame.hxx:180
#define MINLAY
Definition: swtypes.hxx:62
bool AreLinesToRestore(const SwTable &rTable) const
Definition: tblsel.cxx:2552
SwTabFrame is one table in the document layout, containing rows (which contain cells).
Definition: tabfrm.hxx:46
virtual void CreateChartInternalDataProviders(const SwTable *pTable)=0
calls createInternalDataProvider for all charts using the specified table
SwFrameFormat * GetFormat(tools::Long nWidth) const
Definition: tblrwcl.cxx:3193
sal_Int64 n
Definition: doc.hxx:187
constexpr sal_uInt16 RES_FRMATR_END(133)
SwFrameFormat * ClaimFrameFormat()
Definition: swtable.cxx:1483
constexpr sal_uInt16 RES_BOXATR_END(153)
void setDummyFlag(bool bDummy)
Definition: swtable.cxx:92
void DelFrames(SwTable &rTable)
Definition: tblsel.cxx:2169
bool OldSplitRow(SwDoc &, const SwSelBoxes &, sal_uInt16, bool)
Definition: tblrwcl.cxx:1024
TableChgWidthHeightType
Definition: tblenum.hxx:26
const_iterator find(const Value &x) const
SwTableLine is one table row in the document model.
Definition: swtable.hxx:357
SwNode & GetNode() const
Definition: ndindex.hxx:128
SwFrameFormat * GetFormat(const SwFrameFormat &rFormat, tools::Long nWidth) const
Definition: tblrwcl.cxx:3244
static sal_uInt16 lcl_GetLineWidth(const FndLine_ &rLine)
Definition: tblrwcl.cxx:1703
iterator begin()
Definition: swtable.hxx:77
void CheckSectionCondColl() const
Call ChkCondcoll to all ContentNodes of section.
Definition: node.cxx:975
constexpr TypedWhichId< SwTableBoxValue > RES_BOXATR_VALUE(152)
const editeng::SvxBorderLine * GetRight() const
SwNodeOffset abs(const SwNodeOffset &a)
Definition: nodeoffset.hxx:34
SwTableLine * front() const
Definition: swtable.hxx:81
IDocumentContentOperations const & getIDocumentContentOperations() const
Definition: doc.cxx:315
bool OldMerge(SwDoc *, const SwSelBoxes &, SwTableBox *, SwUndoTableMerge *)
Definition: tblrwcl.cxx:1535
SwTableFormat * GetFrameFormat()
Definition: swtable.hxx:204
void SetValues(bool bFlag)
Definition: tblrwcl.hxx:96
Value in Var-direction gives minimum (can be exceeded but not be less).
static bool lcl_SetOtherLineHeight(SwTableLine *pLine, const CR_SetLineHeight &rParam, SwTwips nDist, bool bCheck)
Definition: tblrwcl.cxx:2982
SwNodeOffset GetSttIdx() const
Definition: swtable.cxx:2051
size_type size() const
Definition: swtable.hxx:76
void ForEach_FndLineCopyCol(SwTableLines &rLines, FndPara *pFndPara)
This creates a structure mirroring the SwTable structure that contains all rows and non-leaf boxes (a...
Definition: tblsel.cxx:2101
const SvxBoxItem & GetBox(bool=true) const
Definition: frmatr.hxx:84
sal_Int32 getRowSpan() const
Definition: swtable.cxx:77
SwTableBox * FindNextBox(const SwTable &, const SwTableBox *=nullptr, bool bOvrTableLns=true) const
Definition: tblrwcl.cxx:2210
SwTableLine * back() const
Definition: swtable.hxx:82
IDocumentFieldsAccess const & getIDocumentFieldsAccess() const
Definition: doc.cxx:357
void ChgFrameFormat(SwTableLineFormat *pNewFormat)
Definition: swtable.cxx:1516
void SetHoriOrient(sal_Int16 eNew)
Definition: fmtornt.hxx:89
bool UpdateTableStyleFormatting(SwTableNode *pTableNode=nullptr, bool bResetDirect=false, OUString const *pStyleName=nullptr)
Update the direct formatting according to the current table style.
Definition: fetab.cxx:1279
const SwRect & getFrameArea() const
Definition: frame.hxx:179
void AddFormat(SwFrameFormat &rFormat)
Definition: tblrwcl.cxx:3223
static void lcl_CheckRowSpan(SwTable &rTable)
Definition: tblrwcl.cxx:1657
void sw_LineSetHeadCondColl(const SwTableLine *pLine)
Definition: tblrwcl.cxx:2347
IDocumentStylePoolAccess const & getIDocumentStylePoolAccess() const
Definition: doc.cxx:426
static void SetLineHeight(SwTableLine &rLine, SwTwips nOldHeight, SwTwips nNewHeight, bool bMinSize)
Definition: tblrwcl.cxx:2925
static bool IsRedlineOn(const RedlineFlags eM)
int nCount
virtual void UpdateTableFields(SfxPoolItem *pHt)=0
static void lcl_Merge_MoveBox(FndBox_ &rFndBox, InsULPara *const pULPara)
Definition: tblrwcl.cxx:1367
virtual void SetName(const OUString &rNewName, bool bBroadcast=false) override
Definition: atrfrm.cxx:2561
void Width(tools::Long nNew)
Definition: swrect.hxx:189
const FndBoxes_t & GetBoxes() const
Definition: tblsel.hxx:203
iterator insert(iterator aIt, SwTableLine *pLine)
Definition: swtable.hxx:86
SwTextFormatColl * CopyTextColl(const SwTextFormatColl &rColl)
copy TextNodes
Definition: docfmt.cxx:1175
void CopyHeadlineIntoTable(SwTableNode &rTableNd)
Definition: tblrwcl.cxx:2015
const SwTable & GetTable() const
Definition: node.hxx:506
virtual void DeleteSection(SwNode *pNode)=0
Delete section containing the node.
static void lcl_Merge_MoveLine(FndLine_ &rFndLine, InsULPara *const pULPara)
Definition: tblrwcl.cxx:1432
o3tl::sorted_vector< CpyTabFrame > CpyTabFrames
Definition: tblrwcl.cxx:200
const OUString & GetTableStyleName() const
Return the table style name of this table.
Definition: swtable.hxx:191
virtual OUString GetName() const override
bool Seek_Entry(const SwFrameFormat &rFormat, sal_uInt16 *pPos) const
Definition: tblrwcl.cxx:3350
SwTableBox * FindPreviousBox(const SwTable &, const SwTableBox *) const
Definition: tblrwcl.cxx:2328
static void lcl_CalcWidth(SwTableBox *pBox)
Definition: tblrwcl.cxx:1316
void UpdateCharts(const OUString &rName) const
Definition: docchart.cxx:141
bool HasOnlyOneListener() const
Definition: calbck.hxx:203
bool SplitCol(SwDoc &rDoc, const SwSelBoxes &rBoxes, sal_uInt16 nCnt)
Definition: tblrwcl.cxx:1167
size_type size() const
void sw_BoxSetSplitBoxFormats(SwTableBox *pBox, SwCollectTableLineBoxes *pSplPara)
Definition: ndtbl.cxx:3045
void MakeFrames(SwTable &rTable)
Definition: tblsel.cxx:2330
static void lcl_CpyBoxes(sal_uInt16 nStt, sal_uInt16 nEnd, SwTableBoxes &rBoxes, SwTableLine *pInsLine)
Definition: tblrwcl.cxx:1304
static void lcl_LastBoxSetWidthLine(SwTableLines &rLines, const tools::Long nOffset, bool bFirst, SwShareBoxFormats &rShareFormats)
Definition: tblrwcl.cxx:636
DocumentType eType
Class for SplitTable Collects the uppermost or lowermost Lines of a Box from a Line in an array...
Definition: tblrwcl.hxx:60
void InsTableBox(SwDoc &rDoc, SwTableNode *pTableNd, SwTableLine *pLine, SwTableBoxFormat *pBoxFrameFormat, SwTableBox *pBox, sal_uInt16 nInsPos, sal_uInt16 nCnt=1)
Definition: swtable.cxx:132
#define CHECKTABLELAYOUT
Definition: tblrwcl.cxx:143
Table of Contents - heading.
Definition: poolfmt.hxx:342
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:137
const editeng::SvxBorderLine * GetTop() const
virtual bool InsertString(const SwPaM &rRg, const OUString &, const SwInsertFlags nInsertMode=SwInsertFlags::EMPTYEXPAND)=0
Insert string into existing text node at position rRg.Point().
void SetSize(SwTableBox &rBox, const SwFormatFrameSize &rSz)
Definition: tblrwcl.cxx:3297
#define CH_TXT_TRACKED_DUMMY_CHAR
Definition: hintids.hxx:190
bool SetColWidth(SwTableBox &rCurrentBox, TableChgWidthHeightType eType, SwTwips nAbsDiff, SwTwips nRelDiff, std::unique_ptr< SwUndo > *ppUndo)
Definition: tblrwcl.cxx:2608
Style of a layout element.
Definition: frmfmt.hxx:59
bool(* FN_lcl_SetBoxWidth)(SwTableLine *, CR_SetBoxWidth &, SwTwips, bool)
Definition: tblrwcl.cxx:132
virtual const SwExtraRedlineTable & GetExtraRedlineTable() const =0
const editeng::SvxBorderLine * GetLeft() const
static SwRowFrame * GetRowFrame(SwTableLine &rLine)
Definition: tblrwcl.cxx:446
void SetTableLines(const SwSelBoxes &rBoxes, const SwTable &rTable)
Definition: tblsel.cxx:2107
int i
void RemoveFormat(const SwFrameFormat &rFormat)
Definition: tblrwcl.cxx:3339
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:133
SwDoc & GetDoc()
Definition: node.hxx:213
bool empty() const
Definition: swtable.hxx:75
bool DeleteSel(SwDoc *, const SwSelBoxes &rBoxes, const SwSelBoxes *pMerged, SwUndo *pUndo, const bool bDelMakeFrames, const bool bCorrBorder)
Definition: tblrwcl.cxx:949
void CheckBoxWidth(const SwTableLine &rLine, SwTwips nSize)
Definition: tblrwcl.cxx:2585
virtual SwChartDataProvider * GetChartDataProvider(bool bCreate=false) const =0
returns or creates the data-provider for chart
static SwTableLine * lcl_CopyRow(FndLine_ &rFndLine, CpyPara *const pCpyPara)
Definition: tblrwcl.cxx:382
::sw::DocumentContentOperationsManager const & GetDocumentContentOperationsManager() const
Definition: doc.cxx:325
void AddFormat(const SwFrameFormat &rOld, SwFrameFormat &rNew)
Definition: tblrwcl.cxx:3260
static void lcl_BoxSetHeadCondColl(const SwTableBox *pBox)
Definition: tblrwcl.cxx:2336
SwNodeOffset GetIndex() const
Definition: node.hxx:292
tools::Long GetHeight(const SwRect &rRect) const
Definition: frame.hxx:1381
void SetSelBoxes(const SwSelBoxes &rBoxes)
Definition: untbl.cxx:2024
tools::Long GetLeft() const
bool DeleteTableRowRedline(SwDoc *pDoc, const SwTableLine &rTableLine, bool bSaveInUndo, RedlineType nRedlineTypeToDelete)
Definition: docredln.cxx:187
static bool lcl_SetSelLineHeight(SwTableLine *pLine, const CR_SetLineHeight &rParam, SwTwips nDist, bool bCheck)
Definition: tblrwcl.cxx:2960
static SwTableBox * lcl_FndNxtPrvDelBox(const SwTableLines &rTableLns, SwTwips nBoxStt, SwTwips nBoxWidth, sal_uInt16 nLinePos, bool bNxt, SwSelBoxes *pAllDelBoxes, size_t *const pCurPos)
Definition: tblrwcl.cxx:817
void UnlockModify()
Definition: calbck.hxx:209
sal_Int16 GetHoriOrient() const
Definition: fmtornt.hxx:87
void LockModify()
Definition: calbck.hxx:208
SwFrameFormat * GetFrameFormat()
Definition: swtable.hxx:380
bool SetRowHeight(SwTableBox &rCurrentBox, TableChgWidthHeightType eType, SwTwips nAbsDiff, SwTwips nRelDiff, std::unique_ptr< SwUndo > *ppUndo)
Definition: tblrwcl.cxx:3032
size
void MakeOwnFrames(SwNodeIndex *pIdxBehind)
Creates the frms for the table node (i.e. the TabFrames).
Definition: ndtbl.cxx:2396
constexpr sal_uInt16 RES_BOXATR_BEGIN(RES_GRFATR_END)
SwFrameSize
Definition: fmtfsize.hxx:35
Marks a node in the document model.
Definition: ndindex.hxx:30
SwFrameFormat * GetFrameFormat()
Definition: swtable.hxx:457
const_iterator end() const
bool HasMergeFormatTable() const
bool empty() const
static bool lcl_SetSelBoxWidth(SwTableLine *pLine, CR_SetBoxWidth &rParam, SwTwips nDist, bool bCheck)
Definition: tblrwcl.cxx:2377
#define CHECK_TABLE(t)
Definition: tblrwcl.cxx:69
const SwDoc * GetDoc() const
The document is set in SwAttrPool now, therefore you always can access it.
Definition: format.hxx:139
sal_uInt8 GetWidthPercent() const
Definition: fmtfsize.hxx:91
IDocumentChartDataProviderAccess const & getIDocumentChartDataProviderAccess() const
Definition: doc.cxx:227
SwTableBox * FindPreviousBox(const SwTable &, const SwTableBox *=nullptr, bool bOvrTableLns=true) const
Definition: tblrwcl.cxx:2261
sal_uInt16 GetBoxPos(const SwTableBox *pBox) const
Definition: swtable.hxx:370
bool IsInReading() const
Definition: doc.hxx:953
Frame cannot be moved in Var-direction.
SwTableLines & GetTabLines()
Definition: swtable.hxx:201
tools::Long SwTwips
Definition: swtypes.hxx:51
static void lcl_AjustLines(SwTableLine *pLine, CR_SetBoxWidth &rParam)
Definition: tblrwcl.cxx:2567
const long LONG_MAX
SwTable is one table in the document model, containing rows (which contain cells).
Definition: swtable.hxx:112
virtual SotClipboardFormatId GetFormat(const TransferableDataHelper &aHelper) override
void SetWidth(tools::Long n)
SwTableLines & GetTabLines()
Definition: swtable.hxx:450
static sal_uInt16 lcl_GetBoxOffset(const FndBox_ &rBox)
Definition: tblrwcl.cxx:1678
const_iterator begin() const
#define COLFUZZY
Definition: tblrwcl.cxx:65
virtual bool SetFormatAttr(const SfxPoolItem &rAttr)
Definition: format.cxx:448
void SetTableChgMode(TableChgMode eMode)
Definition: swtable.hxx:334
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
void MakeNewFrames(SwTable &rTable, const sal_uInt16 nNumber, const bool bBehind)
Definition: tblsel.cxx:2412
SwTableBoxes & GetTabBoxes()
Definition: swtable.hxx:368
static void lcl_InsCol(FndLine_ *pFndLn, CpyPara &rCpyPara, sal_uInt16 nCpyCnt, bool bBehind)
Definition: tblrwcl.cxx:409
virtual bool ResetFormatAttr(sal_uInt16 nWhich1, sal_uInt16 nWhich2=0)
Definition: format.cxx:619
std::vector< SwTableBox * > SwTableBoxes
Definition: swtable.hxx:105
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:335
static void lcl_SaveUpperLowerBorder(SwTable &rTable, const SwTableBox &rBox, SwShareBoxFormats &rShareFormats, SwSelBoxes *pAllDelBoxes=nullptr, size_t *const pCurPos=nullptr)
Definition: tblrwcl.cxx:877
std::vector< std::unique_ptr< FndBox_ > > FndBoxes_t
Definition: tblsel.hxx:152
void sw_Box_CollectBox(const SwTableBox *pBox, SwCollectTableLineBoxes *pSplPara)
Definition: ndtbl.cxx:3027
const SwStartNode * GetSttNd() const
Definition: swtable.hxx:471
static void lcl_CopyBoxToDoc(FndBox_ const &rFndBox, CpyPara *const pCpyPara)
Definition: tblrwcl.cxx:1800
bool operator<(TypeDescription const &left, TypeDescription const &right)
void ChgFrameFormat(SwTableBoxFormat *pNewFormat, bool bNeedToReregister=true)
Definition: swtable.cxx:1939
void GCLines()
Definition: gctable.cxx:452
bool(* FN_lcl_SetLineHeight)(SwTableLine *, CR_SetLineHeight &, SwTwips, bool)
Definition: tblrwcl.cxx:198
void SetLeft(const tools::Long nL, const sal_uInt16 nProp=100)
void CopyAttrs(const SwFormat &)
Copy attributes even among documents.
Definition: format.cxx:172
void ChangeFrameFormat(SwTableBox *pBox, SwTableLine *pLn, SwFrameFormat &rFormat)
Definition: tblrwcl.cxx:3273
unsigned char sal_uInt8
void CopyWithFlyInFly(const SwNodeRange &rRg, const SwNodeIndex &rInsPos, const std::pair< const SwPaM &, const SwPosition & > *pCopiedPaM=nullptr, bool bMakeNewFrames=true, bool bDelRedlines=true, bool bCopyFlyAtFly=false, SwCopyFlags flags=SwCopyFlags::Default) const
note: rRg/rInsPos exclude a partially selected start text node; pCopiedPaM includes a partially selec...
sal_uInt32 GetMergeFormatIndex(sal_uInt32 nOldFmt) const
virtual SwFieldType * InsertFieldType(const SwFieldType &)=0
void SetWidthPercent(sal_uInt8 n)
Definition: fmtfsize.hxx:95
void SetTableStyleName(const OUString &rName)
Set the new table style name for this table.
Definition: swtable.hxx:194
const SwTableBox * GetBox() const
Definition: tblsel.hxx:175
bool InsertCol(SwDoc &, const SwSelBoxes &rBoxes, sal_uInt16 nCnt, bool bBehind)
Definition: tblrwcl.cxx:455
SwNodes & GetNodes()
Definition: doc.hxx:408
virtual SwTextFormatColl * GetTextCollFromPool(sal_uInt16 nId, bool bRegardLanguage=true)=0
Return "Auto-Collection with ID.
void SetRowNotTracked(const SwCursor &rCursor, const SvxPrintItem &rNotTracked, bool bAll=false)
rNotTracked = false means that the row was deleted or inserted with its tracked cell content bAll: de...
Definition: ndtbl1.cxx:565
constexpr TypedWhichId< SwTableBoxFormula > RES_BOXATR_FORMULA(151)
static bool lcl_SetOtherBoxWidth(SwTableLine *pLine, CR_SetBoxWidth &rParam, SwTwips nDist, bool bCheck)
Definition: tblrwcl.cxx:2477
SwTableBox is one table cell in the document model.
Definition: swtable.hxx:418
void SetAttr(SwTableBox &rBox, const SfxPoolItem &rItem)
Definition: tblrwcl.cxx:3311
void Delete(const SwNodeIndex &rPos, SwNodeOffset nNodes=SwNodeOffset(1))
delete nodes
Definition: nodes.cxx:1085
constexpr TableChgWidthHeightType extractPosition(TableChgWidthHeightType e)
Definition: tblenum.hxx:43
constexpr TypedWhichId< SvxLRSpaceItem > RES_LR_SPACE(91)
o3tl::strong_int< sal_Int32, struct Tag_SwNodeOffset > SwNodeOffset
Definition: nodeoffset.hxx:16
bool Resize(sal_uInt16 nOffset, sal_uInt16 nWidth)
Definition: ndtbl.cxx:2976
SwFrameFormat * ClaimFrameFormat()
Definition: swtable.cxx:1903
SvxBoxItem & rBoxItem
#define CHECKBOXWIDTH
Definition: tblrwcl.cxx:136
const SwFormatFrameSize & GetFrameSize(bool=true) const
Definition: fmtfsize.hxx:104
SwFEShell * GetFEShell()
For Core - it knows the DocShell but not the WrtShell!
Definition: docsh.cxx:1225
std::vector< std::unique_ptr< FndLine_ > > FndLines_t
Definition: tblsel.hxx:155
SwTableNode * FindTableNode()
Search table node, in which it is.
Definition: node.cxx:358
SwTableBox * GetUpper()
Definition: swtable.hxx:376
bool RemoveFormat(const SwFrameFormat &rFormat)
Definition: tblrwcl.cxx:3228
void DeleteBox_(SwTable &rTable, SwTableBox *pBox, SwUndo *pUndo, bool bCalcNewSize, const bool bCorrBorder, SwShareBoxFormats *pShareFormats)
Definition: tblrwcl.cxx:670
void SetUpper(SwTableLine *pNew)
Definition: swtable.hxx:455
sal_uInt32 GetValue() const
SwTableBox * FindNextBox(const SwTable &, const SwTableBox *, bool bOvrTableLns=true) const
Definition: tblrwcl.cxx:2317
static void lcl_CalcNewWidths(const FndLines_t &rFndLines, CpyPara &rPara)
Definition: tblrwcl.cxx:1714
void setRowSpan(sal_Int32 nNewRowSpan)
Definition: swtable.cxx:82
sal_uInt16 GetPos(const SwTableLine *pBox) const
Definition: swtable.hxx:98
TableChgMode
Definition: tblenum.hxx:47
A layout frame is a frame that contains other frames (m_pLower), e.g. SwPageFrame or SwTabFrame...
Definition: layfrm.hxx:35
bool DeleteTableCellRedline(SwDoc *pDoc, const SwTableBox &rTableBox, bool bSaveInUndo, RedlineType nRedlineTypeToDelete)
Definition: docredln.cxx:231
const SwAttrSet & GetAttrSet() const
For querying the attribute array.
Definition: format.hxx:136
TableFormulaUpdateFlags m_eFlags
Definition: hints.hxx:270
Frame is variable in Var-direction.
const FndLine_ * GetUpper() const
Definition: tblsel.hxx:177
void SetNewTable(std::unique_ptr< SwTable >, bool bNewFrames=true)
Definition: ndtbl.cxx:2484
std::pair< const_iterator, bool > insert(Value &&x)
void DeleteBox(const SwTable *pTable, const SwTableBox &rBox)
Definition: unochart.cxx:1451
std::vector< Value >::size_type size_type
Subgroup table.
Definition: poolfmt.hxx:341
bool IsNewModel() const
Definition: swtable.hxx:188
SwTableLine * GetUpper()
Definition: swtable.hxx:453
const SwTable * InsertTable(const SwInsertTableOptions &rInsTableOpts, const SwPosition &rPos, sal_uInt16 nRows, sal_uInt16 nCols, sal_Int16 eAdjust, const SwTableAutoFormat *pTAFormat=nullptr, const std::vector< sal_uInt16 > *pColArr=nullptr, bool bCalledFromShell=false, bool bNewModel=true)
Insert new table at position.
Definition: ndtbl.cxx:343
void SetHeightSizeType(SwFrameSize eSize)
Definition: fmtfsize.hxx:81
void Height(tools::Long nNew)
Definition: swrect.hxx:193
bool operator==(const ScCsvLayoutData &rData1, const ScCsvLayoutData &rData2)
bool InsertRow_(SwDoc *, const SwSelBoxes &, sal_uInt16 nCnt, bool bBehind)
Definition: tblrwcl.cxx:514
const editeng::SvxBorderLine * GetBottom() const
bool IsDelBox() const
Definition: undobj.cxx:182
TableChgMode GetTableChgMode() const
Definition: swtable.hxx:333
sal_uInt16 Which() const
bool MakeCopy(SwDoc &, const SwPosition &, const SwSelBoxes &, bool bCpyName=false, const OUString &rStyleName="") const
Definition: tblrwcl.cxx:2060
sal_uInt16 nPos
iterator erase(iterator aIt)
Definition: swtable.hxx:84
std::vector< Value >::const_iterator const_iterator
size_type erase(const Value &x)
SwRowFrame is one table row in the document layout.
Definition: rowfrm.hxx:28
bool MoveNodes(const SwNodeRange &, SwNodes &rNodes, const SwNodeIndex &, bool bNewFrames=true)
move the node pointer
Definition: nodes.cxx:409
bool m_bDetectedRangeSegmentation false
void SetLine(const editeng::SvxBorderLine *pNew, SvxBoxItemLine nLine)
SwTwips CalcRowRstHeight(SwLayoutFrame *pRow)
Definition: frmtool.cxx:3712
Base class of the Writer document model elements.
Definition: node.hxx:81