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  sal_uLong 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()+2 != pEndNd->GetIndex() )
1139  {
1140  // Move TextNodes
1141  SwNodeRange aRg( *pLastBox->GetSttNd(), +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 SfxPoolItem* pItem;
1912  SvNumberFormatter* pN = pCpyPara->rDoc.GetNumberFormatter( false );
1913  if( pN && pN->HasMergeFormatTable() && SfxItemState::SET == aBoxAttrSet.
1914  GetItemState( RES_BOXATR_FORMAT, false, &pItem ) )
1915  {
1916  sal_uLong nOldIdx = static_cast<const SwTableBoxNumFormat*>(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(), 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  std::unique_ptr<FndBox_> xFndBox; // for insertion/deletion
2617  bool bBigger,
2618  bRet = false,
2619  bLeft = TableChgWidthHeightType::ColLeft == extractPosition( eType ) ||
2621 
2622  // Get the current Box's edge
2623  // Only needed for manipulating the width
2624  const SwTwips nDist = ::lcl_GetDistance( &rCurrentBox, bLeft );
2625  SwTwips nDistStt = 0;
2626  CR_SetBoxWidth aParam( eType, nRelDiff, nDist,
2627  bLeft ? nDist : rSz.GetWidth() - nDist,
2628  const_cast<SwTableNode*>(rCurrentBox.GetSttNd()->FindTableNode()) );
2629  bBigger = aParam.bBigger;
2630 
2631  FN_lcl_SetBoxWidth fnSelBox, fnOtherBox;
2632  fnSelBox = lcl_SetSelBoxWidth;
2633  fnOtherBox = lcl_SetOtherBoxWidth;
2634 
2635  switch( extractPosition(eType) )
2636  {
2639  if( TableChgMode::VarWidthChangeAbs == m_eTableChgMode )
2640  {
2641  // First test if we have room at all
2642  bool bChgLRSpace = true;
2643  if( bBigger )
2644  {
2645  if( GetFrameFormat()->getIDocumentSettingAccess().get(DocumentSettingId::BROWSE_MODE) &&
2646  !rSz.GetWidthPercent() )
2647  {
2648  // silence -Wsign-compare on Android with the static cast
2649  bRet = rSz.GetWidth() < static_cast<unsigned short>(USHRT_MAX) - nRelDiff;
2650  bChgLRSpace = bLeft ? rLR.GetLeft() >= nAbsDiff
2651  : rLR.GetRight() >= nAbsDiff;
2652  }
2653  else
2654  bRet = bLeft ? rLR.GetLeft() >= nAbsDiff
2655  : rLR.GetRight() >= nAbsDiff;
2656 
2657  if( !bRet )
2658  {
2659  // Then call itself recursively; only with another mode (proportional)
2660  TableChgMode eOld = m_eTableChgMode;
2661  m_eTableChgMode = TableChgMode::FixedWidthChangeProp;
2662 
2663  bRet = SetColWidth( rCurrentBox, eType, nAbsDiff, nRelDiff,
2664  ppUndo );
2665  m_eTableChgMode = eOld;
2666  return bRet;
2667  }
2668  }
2669  else
2670  {
2671  bRet = true;
2672  for( auto const & n: m_aLines )
2673  {
2674  aParam.LoopClear();
2675  if( !(*fnSelBox)( n, aParam, nDistStt, true ))
2676  {
2677  bRet = false;
2678  break;
2679  }
2680  }
2681  }
2682 
2683  if( bRet )
2684  {
2685  if( ppUndo )
2686  ppUndo->reset(new SwUndoAttrTable( *aParam.pTableNd, true ));
2687 
2688  tools::Long nFrameWidth = LONG_MAX;
2689  LockModify();
2690  SwFormatFrameSize aSz( rSz );
2691  SvxLRSpaceItem aLR( rLR );
2692  if( bBigger )
2693  {
2694  // If the Table does not have any room to grow, we need to create some!
2695  // silence -Wsign-compare on Android with the static cast
2696  if( aSz.GetWidth() + nRelDiff > static_cast<unsigned short>(USHRT_MAX) )
2697  {
2698  // Break down to USHRT_MAX / 2
2699  CR_SetBoxWidth aTmpPara( TableChgWidthHeightType::ColLeft, aSz.GetWidth() / 2,
2700  0, aSz.GetWidth(), aParam.pTableNd );
2701  for( size_t nLn = 0; nLn < m_aLines.size(); ++nLn )
2702  ::lcl_AjustLines( m_aLines[ nLn ], aTmpPara );
2703  aSz.SetWidth( aSz.GetWidth() / 2 );
2704  aParam.nDiff = nRelDiff /= 2;
2705  aParam.nSide /= 2;
2706  aParam.nMaxSize /= 2;
2707  }
2708 
2709  if( bLeft )
2710  aLR.SetLeft( sal_uInt16( aLR.GetLeft() - nAbsDiff ) );
2711  else
2712  aLR.SetRight( sal_uInt16( aLR.GetRight() - nAbsDiff ) );
2713  }
2714  else if( bLeft )
2715  aLR.SetLeft( sal_uInt16( aLR.GetLeft() + nAbsDiff ) );
2716  else
2717  aLR.SetRight( sal_uInt16( aLR.GetRight() + nAbsDiff ) );
2718 
2719  if( bChgLRSpace )
2720  GetFrameFormat()->SetFormatAttr( aLR );
2721  const SwFormatHoriOrient& rHOri = GetFrameFormat()->GetHoriOrient();
2722  if( text::HoriOrientation::FULL == rHOri.GetHoriOrient() ||
2723  (text::HoriOrientation::LEFT == rHOri.GetHoriOrient() && aLR.GetLeft()) ||
2724  (text::HoriOrientation::RIGHT == rHOri.GetHoriOrient() && aLR.GetRight()))
2725  {
2726  SwFormatHoriOrient aHOri( rHOri );
2728  GetFrameFormat()->SetFormatAttr( aHOri );
2729 
2730  // If the Table happens to contain relative values (USHORT_MAX),
2731  // we need to convert them to absolute ones now.
2732  // Bug 61494
2733  if( GetFrameFormat()->getIDocumentSettingAccess().get(DocumentSettingId::BROWSE_MODE) &&
2734  !rSz.GetWidthPercent() )
2735  {
2736  SwTabFrame* pTabFrame = SwIterator<SwTabFrame,SwFormat>( *GetFrameFormat() ).First();
2737  if( pTabFrame &&
2738  pTabFrame->getFramePrintArea().Width() != rSz.GetWidth() )
2739  {
2740  nFrameWidth = pTabFrame->getFramePrintArea().Width();
2741  if( bBigger )
2742  nFrameWidth += nAbsDiff;
2743  else
2744  nFrameWidth -= nAbsDiff;
2745  }
2746  }
2747  }
2748 
2749  if( bBigger )
2750  aSz.SetWidth( aSz.GetWidth() + nRelDiff );
2751  else
2752  aSz.SetWidth( aSz.GetWidth() - nRelDiff );
2753 
2754  if( rSz.GetWidthPercent() )
2755  aSz.SetWidthPercent( static_cast<sal_uInt8>(( aSz.GetWidth() * 100 ) /
2756  ( aSz.GetWidth() + aLR.GetRight() + aLR.GetLeft())));
2757 
2758  GetFrameFormat()->SetFormatAttr( aSz );
2759 
2760  UnlockModify();
2761 
2762  for( sal_uInt16 n = m_aLines.size(); n; )
2763  {
2764  --n;
2765  aParam.LoopClear();
2766  (*fnSelBox)( m_aLines[ n ], aParam, nDistStt, false );
2767  }
2768 
2769  // If the Table happens to contain relative values (USHORT_MAX),
2770  // we need to convert them to absolute ones now.
2771  // Bug 61494
2772  if( LONG_MAX != nFrameWidth )
2773  {
2774  SwFormatFrameSize aAbsSz( aSz );
2775  aAbsSz.SetWidth( nFrameWidth );
2776  GetFrameFormat()->SetFormatAttr( aAbsSz );
2777  }
2778  }
2779  }
2780  else if( bLeft ? nDist != 0 : std::abs( rSz.GetWidth() - nDist ) > COLFUZZY )
2781  {
2782  bRet = true;
2783  if( bLeft && TableChgMode::FixedWidthChangeAbs == m_eTableChgMode )
2784  aParam.bBigger = !bBigger;
2785 
2786  // First test if we have room at all
2787  if( aParam.bBigger )
2788  {
2789  for( auto const & n: m_aLines )
2790  {
2791  aParam.LoopClear();
2792  if( !(*fnOtherBox)( n, aParam, 0, true ))
2793  {
2794  bRet = false;
2795  break;
2796  }
2797  }
2798  }
2799  else
2800  {
2801  for( auto const & n: m_aLines )
2802  {
2803  aParam.LoopClear();
2804  if( !(*fnSelBox)( n, aParam, nDistStt, true ))
2805  {
2806  bRet = false;
2807  break;
2808  }
2809  }
2810  }
2811 
2812  // If true, set it
2813  if( bRet )
2814  {
2815  CR_SetBoxWidth aParam1( aParam );
2816  if( ppUndo )
2817  ppUndo->reset(new SwUndoAttrTable( *aParam.pTableNd, true ));
2818 
2819  if( TableChgMode::FixedWidthChangeAbs != m_eTableChgMode && bLeft )
2820  {
2821  for( sal_uInt16 n = m_aLines.size(); n; )
2822  {
2823  --n;
2824  aParam.LoopClear();
2825  aParam1.LoopClear();
2826  (*fnSelBox)( m_aLines[ n ], aParam, nDistStt, false );
2827  (*fnOtherBox)( m_aLines[ n ], aParam1, nDistStt, false );
2828  }
2829  }
2830  else
2831  {
2832  for( sal_uInt16 n = m_aLines.size(); n; )
2833  {
2834  --n;
2835  aParam.LoopClear();
2836  aParam1.LoopClear();
2837  (*fnOtherBox)( m_aLines[ n ], aParam1, nDistStt, false );
2838  (*fnSelBox)( m_aLines[ n ], aParam, nDistStt, false );
2839  }
2840  }
2841  }
2842  }
2843  break;
2844 
2847  if( TableChgMode::VarWidthChangeAbs == m_eTableChgMode )
2848  {
2849  // Then call itself recursively; only with another mode (proportional)
2850  TableChgMode eOld = m_eTableChgMode;
2851  m_eTableChgMode = TableChgMode::FixedWidthChangeAbs;
2852 
2853  bRet = SetColWidth( rCurrentBox, eType, nAbsDiff, nRelDiff,
2854  ppUndo );
2855  m_eTableChgMode = eOld;
2856  return bRet;
2857  }
2858  else if( bLeft ? nDist != 0 : (rSz.GetWidth() - nDist) > COLFUZZY )
2859  {
2860  if( bLeft && TableChgMode::FixedWidthChangeAbs == m_eTableChgMode )
2861  aParam.bBigger = !bBigger;
2862 
2863  // First, see if there is enough room at all
2864  SwTableBox* pBox = &rCurrentBox;
2865  SwTableLine* pLine = rCurrentBox.GetUpper();
2866  while( pLine->GetUpper() )
2867  {
2868  const SwTableBoxes::size_type nPos = pLine->GetBoxPos( pBox );
2869  if( bLeft ? nPos != 0 : nPos + 1 != pLine->GetTabBoxes().size() )
2870  break;
2871 
2872  pBox = pLine->GetUpper();
2873  pLine = pBox->GetUpper();
2874  }
2875 
2876  if( pLine->GetUpper() )
2877  {
2878  // We need to correct the distance once again!
2879  aParam.nSide -= ::lcl_GetDistance( pLine->GetUpper(), true );
2880 
2881  if( bLeft )
2882  aParam.nMaxSize = aParam.nSide;
2883  else
2884  aParam.nMaxSize = pLine->GetUpper()->GetFrameFormat()->
2885  GetFrameSize().GetWidth() - aParam.nSide;
2886  }
2887 
2888  // First, see if there is enough room at all
2889  FN_lcl_SetBoxWidth fnTmp = aParam.bBigger ? fnOtherBox : fnSelBox;
2890  bRet = (*fnTmp)( pLine, aParam, nDistStt, true );
2891 
2892  // If true, set it
2893  if( bRet )
2894  {
2895  CR_SetBoxWidth aParam1( aParam );
2896  if( ppUndo )
2897  ppUndo->reset(new SwUndoAttrTable( *aParam.pTableNd, true ));
2898 
2899  if( TableChgMode::FixedWidthChangeAbs != m_eTableChgMode && bLeft )
2900  {
2901  (*fnSelBox)( pLine, aParam, nDistStt, false );
2902  (*fnOtherBox)( pLine, aParam1, nDistStt, false );
2903  }
2904  else
2905  {
2906  (*fnOtherBox)( pLine, aParam1, nDistStt, false );
2907  (*fnSelBox)( pLine, aParam, nDistStt, false );
2908  }
2909  }
2910  }
2911  break;
2912  default: break;
2913  }
2914 
2915  if( xFndBox )
2916  {
2917  // Clean up the structure of all Lines
2918  GCLines();
2919 
2920  // Update Layout
2921  if( !bBigger || xFndBox->AreLinesToRestore( *this ) )
2922  xFndBox->MakeFrames( *this );
2923 
2924  // TL_CHART2: it is currently unclear if sth has to be done here.
2925  // The function name hints that nothing needs to be done, on the other
2926  // hand there is a case where sth gets deleted. :-(
2927 
2928  xFndBox.reset();
2929  }
2930 
2931 #if defined DBG_UTIL
2932  if( bRet )
2933  {
2936  }
2937 #endif
2938 
2939  return bRet;
2940 }
2941 
2942 static void SetLineHeight( SwTableLine& rLine, SwTwips nOldHeight, SwTwips nNewHeight,
2943  bool bMinSize )
2944 {
2945  SwLayoutFrame* pLineFrame = GetRowFrame( rLine );
2946  OSL_ENSURE( pLineFrame, "Where is the Frame from the SwTableLine?" );
2947 
2948  SwFrameFormat* pFormat = rLine.ClaimFrameFormat();
2949 
2950  SwTwips nMyNewH, nMyOldH = pLineFrame->getFrameArea().Height();
2951  if( !nOldHeight ) // the BaseLine and absolute
2952  nMyNewH = nMyOldH + nNewHeight;
2953  else
2954  {
2955  // Calculate as exactly as possible
2956  Fraction aTmp( nMyOldH );
2957  aTmp *= Fraction( nNewHeight, nOldHeight );
2958  aTmp += Fraction( 1, 2 ); // round up if needed
2959  nMyNewH = tools::Long(aTmp);
2960  }
2961 
2963  if( !bMinSize &&
2964  ( nMyOldH - nMyNewH ) > ( CalcRowRstHeight( pLineFrame ) + ROWFUZZY ))
2965  eSize = SwFrameSize::Fixed;
2966 
2967  pFormat->SetFormatAttr( SwFormatFrameSize( eSize, 0, nMyNewH ) );
2968 
2969  // First adapt all internal ones
2970  for( auto pBox : rLine.GetTabBoxes() )
2971  {
2972  for( auto pLine : pBox->GetTabLines() )
2973  SetLineHeight( *pLine, nMyOldH, nMyNewH, bMinSize );
2974  }
2975 }
2976 
2977 static bool lcl_SetSelLineHeight( SwTableLine* pLine, const CR_SetLineHeight& rParam,
2978  SwTwips nDist, bool bCheck )
2979 {
2980  bool bRet = true;
2981  if( !bCheck )
2982  {
2983  // Set line height
2984  SetLineHeight( *pLine, 0, rParam.bBigger ? nDist : -nDist,
2985  rParam.bBigger );
2986  }
2987  else if( !rParam.bBigger )
2988  {
2989  // Calculate the new relative size by means of the old one
2990  SwLayoutFrame* pLineFrame = GetRowFrame( *pLine );
2991  OSL_ENSURE( pLineFrame, "Where is the Frame from the SwTableLine?" );
2992  SwTwips nRstHeight = CalcRowRstHeight( pLineFrame );
2993  if( (nRstHeight + ROWFUZZY) < nDist )
2994  bRet = false;
2995  }
2996  return bRet;
2997 }
2998 
2999 static bool lcl_SetOtherLineHeight( SwTableLine* pLine, const CR_SetLineHeight& rParam,
3000  SwTwips nDist, bool bCheck )
3001 {
3002  bool bRet = true;
3003  if( bCheck )
3004  {
3005  if( rParam.bBigger )
3006  {
3007  // Calculate the new relative size by means of the old one
3008  SwLayoutFrame* pLineFrame = GetRowFrame( *pLine );
3009  OSL_ENSURE( pLineFrame, "Where is the Frame from the SwTableLine?" );
3010 
3011  if( TableChgMode::FixedWidthChangeProp == rParam.nMode )
3012  {
3013  nDist *= pLineFrame->getFrameArea().Height();
3014  nDist /= rParam.nMaxHeight;
3015  }
3016  bRet = nDist <= CalcRowRstHeight( pLineFrame );
3017  }
3018  }
3019  else
3020  {
3021  // Set line height
3022  // pLine is the following/preceding, thus adjust it
3023  if( TableChgMode::FixedWidthChangeProp == rParam.nMode )
3024  {
3025  SwLayoutFrame* pLineFrame = GetRowFrame( *pLine );
3026  OSL_ENSURE( pLineFrame, "Where is the Frame from the SwTableLine??" );
3027 
3028  // Calculate the new relative size by means of the old one
3029  // If the selected Box get bigger, adjust via the max space else
3030  // via the max height.
3031  if( (true) )
3032  {
3033  nDist *= pLineFrame->getFrameArea().Height();
3034  nDist /= rParam.nMaxHeight;
3035  }
3036  else
3037  {
3038  // Calculate the new relative size by means of the old one
3039  nDist *= CalcRowRstHeight( pLineFrame );
3040  nDist /= rParam.nMaxSpace;
3041  }
3042  }
3043  SetLineHeight( *pLine, 0, rParam.bBigger ? -nDist : nDist,
3044  !rParam.bBigger );
3045  }
3046  return bRet;
3047 }
3048 
3050  SwTwips nAbsDiff, SwTwips nRelDiff, std::unique_ptr<SwUndo>* ppUndo )
3051 {
3052  SwTableLine* pLine = rCurrentBox.GetUpper();
3053 
3054  SwTableLine* pBaseLine = pLine;
3055  while( pBaseLine->GetUpper() )
3056  pBaseLine = pBaseLine->GetUpper()->GetUpper();
3057 
3058  std::unique_ptr<FndBox_> xFndBox; // for insertion/deletion
3059  bool bBigger,
3060  bRet = false,
3062  sal_uInt16 nBaseLinePos = GetTabLines().GetPos( pBaseLine );
3063 
3064  CR_SetLineHeight aParam( eType,
3065  const_cast<SwTableNode*>(rCurrentBox.GetSttNd()->FindTableNode()) );
3066  bBigger = aParam.bBigger;
3067 
3068  SwTableLines* pLines = &m_aLines;
3069 
3070  // How do we get to the height?
3071  switch( extractPosition(eType) )
3072  {
3075  if( pLine == pBaseLine )
3076  break; // it doesn't work then!
3077 
3078  // Is a nested Line (Box!)
3079  pLines = &pLine->GetUpper()->GetTabLines();
3080  nBaseLinePos = pLines->GetPos( pLine );
3081  [[fallthrough]];
3082 
3084  {
3085  if( TableChgMode::VarWidthChangeAbs == m_eTableChgMode )
3086  {
3087  // First test if we have room at all
3088  if( bBigger )
3089  bRet = true;
3090  else
3091  bRet = lcl_SetSelLineHeight( (*pLines)[ nBaseLinePos ], aParam,
3092  nAbsDiff, true );
3093 
3094  if( bRet )
3095  {
3096  if( ppUndo )
3097  ppUndo->reset(new SwUndoAttrTable( *aParam.pTableNd, true ));
3098 
3099  lcl_SetSelLineHeight( (*pLines)[ nBaseLinePos ], aParam,
3100  nAbsDiff, false );
3101  }
3102  }
3103  else
3104  {
3105  bRet = true;
3108  if( bTop )
3109  {
3110  nStt = 0;
3111  nEnd = nBaseLinePos;
3112  }
3113  else
3114  {
3115  nStt = nBaseLinePos + 1;
3116  nEnd = pLines->size();
3117  }
3118 
3119  // Get the current Lines' height
3120  if( TableChgMode::FixedWidthChangeProp == m_eTableChgMode )
3121  {
3122  for( auto n = nStt; n < nEnd; ++n )
3123  {
3124  SwLayoutFrame* pLineFrame = GetRowFrame( *(*pLines)[ n ] );
3125  OSL_ENSURE( pLineFrame, "Where is the Frame from the SwTableLine??" );
3126  aParam.nMaxSpace += CalcRowRstHeight( pLineFrame );
3127  aParam.nMaxHeight += pLineFrame->getFrameArea().Height();
3128  }
3129  if( bBigger && aParam.nMaxSpace < nAbsDiff )
3130  bRet = false;
3131  }
3132  else
3133  {
3134  if( bTop ? nEnd != 0 : nStt < nEnd )
3135  {
3136  if( bTop )
3137  nStt = nEnd - 1;
3138  else
3139  nEnd = nStt + 1;
3140  }
3141  else
3142  bRet = false;
3143  }
3144 
3145  if( bRet )
3146  {
3147  if( bBigger )
3148  {
3149  for( auto n = nStt; n < nEnd; ++n )
3150  {
3151  if( !lcl_SetOtherLineHeight( (*pLines)[ n ], aParam,
3152  nAbsDiff, true ))
3153  {
3154  bRet = false;
3155  break;
3156  }
3157  }
3158  }
3159  else
3160  bRet = lcl_SetSelLineHeight( (*pLines)[ nBaseLinePos ], aParam,
3161  nAbsDiff, true );
3162  }
3163 
3164  if( bRet )
3165  {
3166  // Adjust
3167  if( ppUndo )
3168  ppUndo->reset(new SwUndoAttrTable( *aParam.pTableNd, true ));
3169 
3170  CR_SetLineHeight aParam1( aParam );
3171 
3172  if( bTop )
3173  {
3174  lcl_SetSelLineHeight( (*pLines)[ nBaseLinePos ], aParam,
3175  nAbsDiff, false );
3176  for( auto n = nStt; n < nEnd; ++n )
3177  lcl_SetOtherLineHeight( (*pLines)[ n ], aParam1,
3178  nAbsDiff, false );
3179  }
3180  else
3181  {
3182  for( auto n = nStt; n < nEnd; ++n )
3183  lcl_SetOtherLineHeight( (*pLines)[ n ], aParam1,
3184  nAbsDiff, false );
3185  lcl_SetSelLineHeight( (*pLines)[ nBaseLinePos ], aParam,
3186  nAbsDiff, false );
3187  }
3188  }
3189  else
3190  {
3191  // Then call itself recursively; only with another mode (proportional)
3192  TableChgMode eOld = m_eTableChgMode;
3193  m_eTableChgMode = TableChgMode::VarWidthChangeAbs;
3194 
3195  bRet = SetRowHeight( rCurrentBox, eType, nAbsDiff,
3196  nRelDiff, ppUndo );
3197 
3198  m_eTableChgMode = eOld;
3199  xFndBox.reset();
3200  }
3201  }
3202  }
3203  break;
3204  default: break;
3205  }
3206 
3207  if( xFndBox )
3208  {
3209  // then clean up the structure of all Lines
3210  GCLines();
3211 
3212  // Update Layout
3213  if( bBigger || xFndBox->AreLinesToRestore( *this ) )
3214  xFndBox->MakeFrames( *this );
3215 
3216  // TL_CHART2: it is currently unclear if sth has to be done here.
3217 
3218  xFndBox.reset();
3219  }
3220 
3222 
3223  return bRet;
3224 }
3225 
3227 {
3228  SwFrameFormat *pRet = nullptr, *pTmp;
3229  for( auto n = m_aNewFormats.size(); n; )
3230  if( ( pTmp = m_aNewFormats[ --n ])->GetFrameSize().GetWidth()
3231  == nWidth )
3232  {
3233  pRet = pTmp;
3234  break;
3235  }
3236  return pRet;
3237 }
3238 
3240 {
3241  const SfxPoolItem* pItem;
3242  sal_uInt16 nWhich = rItem.Which();
3243  SwFrameFormat *pRet = nullptr, *pTmp;
3244  const SfxPoolItem& rFrameSz = m_pOldFormat->GetFormatAttr( RES_FRM_SIZE, false );
3245  for( auto n = m_aNewFormats.size(); n; )
3246  if( SfxItemState::SET == ( pTmp = m_aNewFormats[ --n ])->
3247  GetItemState( nWhich, false, &pItem ) && *pItem == rItem &&
3248  pTmp->GetFormatAttr( RES_FRM_SIZE, false ) == rFrameSz )
3249  {
3250  pRet = pTmp;
3251  break;
3252  }
3253  return pRet;
3254 }
3255 
3257 {
3258  m_aNewFormats.push_back( &rNew );
3259 }
3260 
3262 {
3263  // returns true, if we can delete
3264  if( m_pOldFormat == &rFormat )
3265  return true;
3266 
3267  std::vector<SwFrameFormat*>::iterator it = std::find( m_aNewFormats.begin(), m_aNewFormats.end(), &rFormat );
3268  if( m_aNewFormats.end() != it )
3269  m_aNewFormats.erase( it );
3270  return m_aNewFormats.empty();
3271 }
3272 
3274 {
3275 }
3276 
3278 {
3279  sal_uInt16 nPos;
3280  return Seek_Entry( rFormat, &nPos )
3281  ? m_ShareArr[ nPos ].GetFormat(nWidth)
3282  : nullptr;
3283 }
3285  const SfxPoolItem& rItem ) const
3286 {
3287  sal_uInt16 nPos;
3288  return Seek_Entry( rFormat, &nPos )
3289  ? m_ShareArr[ nPos ].GetFormat(rItem)
3290  : nullptr;
3291 }
3292 
3294 {
3295  sal_uInt16 nPos;
3296  if( !Seek_Entry( rOld, &nPos ))
3297  {
3298  SwShareBoxFormat aEntry(rOld);
3299  aEntry.AddFormat( rNew );
3300  m_ShareArr.insert(m_ShareArr.begin() + nPos, aEntry);
3301  }
3302  else
3303  m_ShareArr[ nPos ].AddFormat(rNew);
3304 }
3305 
3307  SwFrameFormat& rFormat )
3308 {
3309  SwClient aCl;
3310  SwFrameFormat* pOld = nullptr;
3311  if( pBox )
3312  {
3313  pOld = pBox->GetFrameFormat();
3314  pOld->Add( &aCl );
3315  pBox->ChgFrameFormat( static_cast<SwTableBoxFormat*>(&rFormat) );
3316  }
3317  else if( pLn )
3318  {
3319  pOld = pLn->GetFrameFormat();
3320  pOld->Add( &aCl );
3321  pLn->ChgFrameFormat( static_cast<SwTableLineFormat*>(&rFormat) );
3322  }
3323  if( pOld && pOld->HasOnlyOneListener() )
3324  {
3325  RemoveFormat( *pOld );
3326  delete pOld;
3327  }
3328 }
3329 
3331 {
3332  SwFrameFormat *pBoxFormat = rBox.GetFrameFormat(),
3333  *pRet = GetFormat( *pBoxFormat, rSz.GetWidth() );
3334  if( pRet )
3335  ChangeFrameFormat( &rBox, nullptr, *pRet );
3336  else
3337  {
3338  pRet = rBox.ClaimFrameFormat();
3339  pRet->SetFormatAttr( rSz );
3340  AddFormat( *pBoxFormat, *pRet );
3341  }
3342 }
3343 
3345 {
3346  SwFrameFormat *pBoxFormat = rBox.GetFrameFormat(),
3347  *pRet = GetFormat( *pBoxFormat, rItem );
3348  if( pRet )
3349  ChangeFrameFormat( &rBox, nullptr, *pRet );
3350  else
3351  {
3352  pRet = rBox.ClaimFrameFormat();
3353  pRet->SetFormatAttr( rItem );
3354  AddFormat( *pBoxFormat, *pRet );
3355  }
3356 }
3357 
3359 {
3360  SwFrameFormat *pLineFormat = rLine.GetFrameFormat(),
3361  *pRet = GetFormat( *pLineFormat, rItem );
3362  if( pRet )
3363  ChangeFrameFormat( nullptr, &rLine, *pRet );
3364  else
3365  {
3366  pRet = rLine.ClaimFrameFormat();
3367  pRet->SetFormatAttr( rItem );
3368  AddFormat( *pLineFormat, *pRet );
3369  }
3370 }
3371 
3373 {
3374  for (auto i = m_ShareArr.size(); i; )
3375  {
3376  if (m_ShareArr[ --i ].RemoveFormat(rFormat))
3377  {
3378  m_ShareArr.erase( m_ShareArr.begin() + i );
3379  }
3380  }
3381 }
3382 
3383 bool SwShareBoxFormats::Seek_Entry( const SwFrameFormat& rFormat, sal_uInt16* pPos ) const
3384 {
3385  sal_uIntPtr nIdx = reinterpret_cast<sal_uIntPtr>(&rFormat);
3386  auto nO = m_ShareArr.size();
3387  decltype(nO) nU = 0;
3388  if( nO > 0 )
3389  {
3390  nO--;
3391  while( nU <= nO )
3392  {
3393  const auto nM = nU + ( nO - nU ) / 2;
3394  sal_uIntPtr nFormat = reinterpret_cast<sal_uIntPtr>(&m_ShareArr[ nM ].GetOldFormat());
3395  if( nFormat == nIdx )
3396  {
3397  if( pPos )
3398  *pPos = nM;
3399  return true;
3400  }
3401  else if( nFormat < nIdx )
3402  nU = nM + 1;
3403  else if( nM == 0 )
3404  {
3405  if( pPos )
3406  *pPos = nU;
3407  return false;
3408  }
3409  else
3410  nO = nM - 1;
3411  }
3412  }
3413  if( pPos )
3414  *pPos = nU;
3415  return false;
3416 }
3417 
3418 /* 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:1550
Instances of SwFields and those derived from it occur 0 to n times.
Definition: fldbas.hxx:240
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:683
Starts a section of nodes in the document model.
Definition: node.hxx:312
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
sal_uLong GetIndex() const
Definition: node.hxx:291
void Add(SwClient *pDepend)
Definition: calbck.cxx:173
void SetRight(const tools::Long nR, const sal_uInt16 nProp=100)
void SetRowsToRepeat(sal_uInt16 nNumOfRows)
Definition: swtable.hxx:197
Marks a position in the document model.
Definition: pam.hxx:35
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:2446
static void lcl_CopyLineToDoc(FndLine_ const &rpFndLn, CpyPara *const pCpyPara)
constexpr TypedWhichId< SwTableBoxNumFormat > RES_BOXATR_FORMAT(RES_BOXATR_BEGIN)
sal_uLong GetSttIdx() const
Definition: swtable.cxx:1911
SwDocShell * GetDocShell()
Definition: doc.hxx:1352
std::string GetValue
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:37
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:181
#define MINLAY
Definition: swtypes.hxx:63
bool AreLinesToRestore(const SwTable &rTable) const
Definition: tblsel.cxx:2546
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:3226
sal_Int64 n
Definition: doc.hxx:188
constexpr sal_uInt16 RES_FRMATR_END(133)
SwFrameFormat * ClaimFrameFormat()
Definition: swtable.cxx:1473
constexpr sal_uInt16 RES_BOXATR_END(153)
void setDummyFlag(bool bDummy)
Definition: swtable.cxx:91
void DelFrames(SwTable &rTable)
Definition: tblsel.cxx:2172
bool OldSplitRow(SwDoc &, const SwSelBoxes &, sal_uInt16, bool)
Definition: tblrwcl.cxx:1024
TableChgWidthHeightType
Definition: tblenum.hxx:25
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:119
SwFrameFormat * GetFormat(const SwFrameFormat &rFormat, tools::Long nWidth) const
Definition: tblrwcl.cxx:3277
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
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:97
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:2999
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:2104
const SvxBoxItem & GetBox(bool=true) const
Definition: frmatr.hxx:84
sal_Int32 getRowSpan() const
Definition: swtable.cxx:76
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 Delete(const SwNodeIndex &rPos, sal_uLong nNodes=1)
delete nodes
Definition: nodes.cxx:1078
void ChgFrameFormat(SwTableLineFormat *pNewFormat)
Definition: swtable.cxx:1506
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:1231
const SwRect & getFrameArea() const
Definition: frame.hxx:180
void AddFormat(SwFrameFormat &rFormat)
Definition: tblrwcl.cxx:3256
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:2942
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:2570
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:1177
void CopyHeadlineIntoTable(SwTableNode &rTableNd)
Definition: tblrwcl.cxx:2015
const SwTable & GetTable() const
Definition: node.hxx:499
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
bool Seek_Entry(const SwFrameFormat &rFormat, sal_uInt16 *pPos) const
Definition: tblrwcl.cxx:3383
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:120
bool HasOnlyOneListener() const
Definition: calbck.hxx:204
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:3027
void MakeFrames(SwTable &rTable)
Definition: tblsel.cxx:2333
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:61
void InsTableBox(SwDoc &rDoc, SwTableNode *pTableNd, SwTableLine *pLine, SwTableBoxFormat *pBoxFrameFormat, SwTableBox *pBox, sal_uInt16 nInsPos, sal_uInt16 nCnt=1)
Definition: swtable.cxx:131
#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:136
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:3330
#define CH_TXT_TRACKED_DUMMY_CHAR
Definition: hintids.hxx:187
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:2110
int i
void RemoveFormat(const SwFrameFormat &rFormat)
Definition: tblrwcl.cxx:3372
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:132
SwDoc & GetDoc()
Definition: node.hxx:212
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:3293
static void lcl_BoxSetHeadCondColl(const SwTableBox *pBox)
Definition: tblrwcl.cxx:2336
tools::Long GetHeight(const SwRect &rRect) const
Definition: frame.hxx:1383
void SetSelBoxes(const SwSelBoxes &rBoxes)
Definition: untbl.cxx:1997
tools::Long GetLeft() const
bool DeleteTableRowRedline(SwDoc *pDoc, const SwTableLine &rTableLine, bool bSaveInUndo, RedlineType nRedlineTypeToDelete)
Definition: docredln.cxx:209
static bool lcl_SetSelLineHeight(SwTableLine *pLine, const CR_SetLineHeight &rParam, SwTwips nDist, bool bCheck)
Definition: tblrwcl.cxx:2977
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:210
sal_Int16 GetHoriOrient() const
Definition: fmtornt.hxx:87
void LockModify()
Definition: calbck.hxx:209
SwFrameFormat * GetFrameFormat()
Definition: swtable.hxx:379
bool SetRowHeight(SwTableBox &rCurrentBox, TableChgWidthHeightType eType, SwTwips nAbsDiff, SwTwips nRelDiff, std::unique_ptr< SwUndo > *ppUndo)
Definition: tblrwcl.cxx:3049
size
void MakeOwnFrames(SwNodeIndex *pIdxBehind)
Creates the frms for the table node (i.e. the TabFrames).
Definition: ndtbl.cxx:2405
constexpr sal_uInt16 RES_BOXATR_BEGIN(RES_GRFATR_END)
SwFrameSize
Definition: fmtfsize.hxx:35
Marks a node in the document model.
Definition: ndindex.hxx:31
SwFrameFormat * GetFrameFormat()
Definition: swtable.hxx:444
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:123
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:369
bool IsInReading() const
Definition: doc.hxx:954
Frame cannot be moved in Var-direction.
SwTableLines & GetTabLines()
Definition: swtable.hxx:201
tools::Long SwTwips
Definition: swtypes.hxx:52
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
void SetWidth(tools::Long n)
SwTableLines & GetTabLines()
Definition: swtable.hxx:437
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:450
void SetTableChgMode(TableChgMode eMode)
Definition: swtable.hxx:334
sal_uLong EndOfSectionIndex() const
Definition: node.hxx:678
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
void MakeNewFrames(SwTable &rTable, const sal_uInt16 nNumber, const bool bBehind)
Definition: tblsel.cxx:2406
SwTableBoxes & GetTabBoxes()
Definition: swtable.hxx:367
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:624
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:3009
const SwStartNode * GetSttNd() const
Definition: swtable.hxx:458
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:1799
void GCLines()
Definition: gctable.cxx:454
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:174
void ChangeFrameFormat(SwTableBox *pBox, SwTableLine *pLn, SwFrameFormat &rFormat)
Definition: tblrwcl.cxx:3306
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:409
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:543
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:405
void SetAttr(SwTableBox &rBox, const SfxPoolItem &rItem)
Definition: tblrwcl.cxx:3344
constexpr TableChgWidthHeightType extractPosition(TableChgWidthHeightType e)
Definition: tblenum.hxx:42
constexpr TypedWhichId< SvxLRSpaceItem > RES_LR_SPACE(91)
bool Resize(sal_uInt16 nOffset, sal_uInt16 nWidth)
Definition: ndtbl.cxx:2958
SwFrameFormat * ClaimFrameFormat()
Definition: swtable.cxx:1763
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:1213
std::vector< std::unique_ptr< FndLine_ > > FndLines_t
Definition: tblsel.hxx:155
SwTableNode * FindTableNode()
Search table node, in which it is.
Definition: node.cxx:357
SwTableBox * GetUpper()
Definition: swtable.hxx:375
bool RemoveFormat(const SwFrameFormat &rFormat)
Definition: tblrwcl.cxx:3261
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:442
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:81
sal_uInt16 GetPos(const SwTableLine *pBox) const
Definition: swtable.hxx:98
TableChgMode
Definition: tblenum.hxx:46
A layout frame is a frame that contains other frames (m_pLower), e.g. SwPageFrame or SwTabFrame...
Definition: layfrm.hxx:35
void AddNewBox(sal_uLong nSttNdIdx)
Definition: UndoTable.hxx:232
bool DeleteTableCellRedline(SwDoc *pDoc, const SwTableBox &rTableBox, bool bSaveInUndo, RedlineType nRedlineTypeToDelete)
Definition: docredln.cxx:253
const SwAttrSet & GetAttrSet() const
For querying the attribute array.
Definition: format.hxx:120
TableFormulaUpdateFlags m_eFlags
Definition: hints.hxx:268
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:2489
std::pair< const_iterator, bool > insert(Value &&x)
void DeleteBox(const SwTable *pTable, const SwTableBox &rBox)
Definition: unochart.cxx:1449
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:440
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:338
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:184
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:400
void SetLine(const editeng::SvxBorderLine *pNew, SvxBoxItemLine nLine)
SwTwips CalcRowRstHeight(SwLayoutFrame *pRow)
Definition: frmtool.cxx:3680
Base class of the Writer document model elements.
Definition: node.hxx:80