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