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