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