Bug Summary

File:home/maarten/src/libreoffice/core/sw/source/core/doc/tblrwcl.cxx
Warning:line 3018, column 23
Division by zero

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name tblrwcl.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /usr/include/libxml2 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D SW_DLLIMPLEMENTATION -D SWUI_DLL_NAME="libswuilo.so" -D SYSTEM_LIBXML -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/sw/source/core/inc -I /home/maarten/src/libreoffice/core/sw/source/filter/inc -I /home/maarten/src/libreoffice/core/sw/source/uibase/inc -I /home/maarten/src/libreoffice/core/sw/inc -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/sw/sdi -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/sw/generated -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/oovbaapi/normal -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/sw/source/core/doc/tblrwcl.cxx

/home/maarten/src/libreoffice/core/sw/source/core/doc/tblrwcl.cxx

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

/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx

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#ifndef INCLUDED_O3TL_TYPED_FLAGS_SET_HXX
21#define INCLUDED_O3TL_TYPED_FLAGS_SET_HXX
22
23#include <sal/config.h>
24
25#include <cassert>
26#include <type_traits>
27
28#include <o3tl/underlyingenumvalue.hxx>
29#include <sal/types.h>
30
31namespace o3tl {
32
33namespace detail {
34
35template<typename T> constexpr
36typename std::enable_if<std::is_signed<T>::value, bool>::type isNonNegative(
37 T value)
38{
39 return value >= 0;
40}
41
42template<typename T> constexpr
43typename std::enable_if<std::is_unsigned<T>::value, bool>::type isNonNegative(T)
44{
45 return true;
46}
47
48}
49
50template<typename T> struct typed_flags {};
51
52/// Mark a (scoped) enumeration as a set of bit flags, with accompanying
53/// operations.
54///
55/// template<>
56/// struct o3tl::typed_flags<TheE>: o3tl::is_typed_flags<TheE, TheM> {};
57///
58/// All relevant values must be non-negative. (Typically, the enumeration's
59/// underlying type will either be fixed and unsigned, or it will be unfixed---
60/// and can thus default to a signed type---and all enumerators will have non-
61/// negative values.)
62///
63/// \param E the enumeration type.
64/// \param M the all-bits-set value for the bit flags.
65template<typename E, typename std::underlying_type<E>::type M>
66struct is_typed_flags {
67 static_assert(
68 M >= 0, "is_typed_flags expects only non-negative bit values");
69
70 typedef E Self;
71
72 class Wrap {
73 public:
74 typedef is_typed_flags Unwrapped;
75
76 explicit constexpr Wrap(typename std::underlying_type<E>::type value):
77 value_(value)
78 {
79 assert(detail::isNonNegative(value))(static_cast <bool> (detail::isNonNegative(value)) ? void
(0) : __assert_fail ("detail::isNonNegative(value)", "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 79, __extension__ __PRETTY_FUNCTION__))
;
80 assert((static_cast <bool> (static_cast<typename std::underlying_type
<E>::type>(~0) == M || (value & ~M) == 0) ? void
(0) : __assert_fail ("static_cast<typename std::underlying_type<E>::type>(~0) == M || (value & ~M) == 0"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 84, __extension__ __PRETTY_FUNCTION__))
81 static_cast<typename std::underlying_type<E>::type>(~0) == M(static_cast <bool> (static_cast<typename std::underlying_type
<E>::type>(~0) == M || (value & ~M) == 0) ? void
(0) : __assert_fail ("static_cast<typename std::underlying_type<E>::type>(~0) == M || (value & ~M) == 0"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 84, __extension__ __PRETTY_FUNCTION__))
82 // avoid "operands don't affect result" warnings when M(static_cast <bool> (static_cast<typename std::underlying_type
<E>::type>(~0) == M || (value & ~M) == 0) ? void
(0) : __assert_fail ("static_cast<typename std::underlying_type<E>::type>(~0) == M || (value & ~M) == 0"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 84, __extension__ __PRETTY_FUNCTION__))
83 // covers all bits of the underlying type(static_cast <bool> (static_cast<typename std::underlying_type
<E>::type>(~0) == M || (value & ~M) == 0) ? void
(0) : __assert_fail ("static_cast<typename std::underlying_type<E>::type>(~0) == M || (value & ~M) == 0"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 84, __extension__ __PRETTY_FUNCTION__))
84 || (value & ~M) == 0)(static_cast <bool> (static_cast<typename std::underlying_type
<E>::type>(~0) == M || (value & ~M) == 0) ? void
(0) : __assert_fail ("static_cast<typename std::underlying_type<E>::type>(~0) == M || (value & ~M) == 0"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 84, __extension__ __PRETTY_FUNCTION__))
;
85 }
86
87 constexpr operator E() const { return static_cast<E>(value_); }
88
89 explicit constexpr operator typename std::underlying_type<E>::type()
90 const
91 { return value_; }
92
93 explicit constexpr operator bool() const { return value_ != 0; }
6
Assuming field 'value_' is equal to 0
7
Returning zero, which participates in a condition later
94
95 private:
96 typename std::underlying_type<E>::type value_;
97 };
98
99 static typename std::underlying_type<E>::type const mask = M;
100};
101
102}
103
104template<typename E>
105constexpr typename o3tl::typed_flags<E>::Wrap operator ~(E rhs) {
106 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 108, __extension__ __PRETTY_FUNCTION__))
107 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 108, __extension__ __PRETTY_FUNCTION__))
108 o3tl::underlyingEnumValue(rhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 108, __extension__ __PRETTY_FUNCTION__))
;
109 return static_cast<typename o3tl::typed_flags<E>::Wrap>(
110 o3tl::typed_flags<E>::mask
111 & ~o3tl::underlyingEnumValue(rhs));
112}
113
114template<typename E> constexpr typename o3tl::typed_flags<E>::Wrap operator ~(
115 typename o3tl::typed_flags<E>::Wrap rhs)
116{
117 return static_cast<typename o3tl::typed_flags<E>::Wrap>(
118 o3tl::typed_flags<E>::mask
119 & ~o3tl::underlyingEnumValue<E>(rhs));
120}
121
122template<typename E> constexpr typename o3tl::typed_flags<E>::Wrap operator ^(
123 E lhs, E rhs)
124{
125 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 127, __extension__ __PRETTY_FUNCTION__))
126 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 127, __extension__ __PRETTY_FUNCTION__))
127 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 127, __extension__ __PRETTY_FUNCTION__))
;
128 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 130, __extension__ __PRETTY_FUNCTION__))
129 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 130, __extension__ __PRETTY_FUNCTION__))
130 o3tl::underlyingEnumValue(rhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 130, __extension__ __PRETTY_FUNCTION__))
;
131 return static_cast<typename o3tl::typed_flags<E>::Wrap>(
132 o3tl::underlyingEnumValue(lhs)
133 ^ o3tl::underlyingEnumValue(rhs));
134}
135
136template<typename E> constexpr typename o3tl::typed_flags<E>::Wrap operator ^(
137 E lhs, typename o3tl::typed_flags<E>::Wrap rhs)
138{
139 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 141, __extension__ __PRETTY_FUNCTION__))
140 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 141, __extension__ __PRETTY_FUNCTION__))
141 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 141, __extension__ __PRETTY_FUNCTION__))
;
142 return static_cast<typename o3tl::typed_flags<E>::Wrap>(
143 o3tl::underlyingEnumValue(lhs)
144 ^ o3tl::underlyingEnumValue<E>(rhs));
145}
146
147template<typename E> constexpr typename o3tl::typed_flags<E>::Wrap operator ^(
148 typename o3tl::typed_flags<E>::Wrap lhs, E rhs)
149{
150 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 152, __extension__ __PRETTY_FUNCTION__))
151 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 152, __extension__ __PRETTY_FUNCTION__))
152 o3tl::underlyingEnumValue(rhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 152, __extension__ __PRETTY_FUNCTION__))
;
153 return static_cast<typename o3tl::typed_flags<E>::Wrap>(
154 o3tl::underlyingEnumValue<E>(lhs)
155 ^ o3tl::underlyingEnumValue(rhs));
156}
157
158template<typename W> constexpr
159typename o3tl::typed_flags<typename W::Unwrapped::Self>::Wrap operator ^(
160 W lhs, W rhs)
161{
162 return static_cast<W>(
163 o3tl::underlyingEnumValue<typename W::Unwrapped::Self>(lhs)
164 ^ o3tl::underlyingEnumValue<typename W::Unwrapped::Self>(rhs));
165}
166
167template<typename E>
168constexpr typename o3tl::typed_flags<E>::Wrap operator &(E lhs, E rhs) {
169 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 171, __extension__ __PRETTY_FUNCTION__))
170 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 171, __extension__ __PRETTY_FUNCTION__))
171 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 171, __extension__ __PRETTY_FUNCTION__))
;
172 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 174, __extension__ __PRETTY_FUNCTION__))
173 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 174, __extension__ __PRETTY_FUNCTION__))
174 o3tl::underlyingEnumValue(rhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 174, __extension__ __PRETTY_FUNCTION__))
;
175 return static_cast<typename o3tl::typed_flags<E>::Wrap>(
176 o3tl::underlyingEnumValue(lhs)
177 & o3tl::underlyingEnumValue(rhs));
178}
179
180template<typename E> constexpr typename o3tl::typed_flags<E>::Wrap operator &(
181 E lhs, typename o3tl::typed_flags<E>::Wrap rhs)
182{
183 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 185, __extension__ __PRETTY_FUNCTION__))
184 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 185, __extension__ __PRETTY_FUNCTION__))
185 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 185, __extension__ __PRETTY_FUNCTION__))
;
186 return static_cast<typename o3tl::typed_flags<E>::Wrap>(
187 o3tl::underlyingEnumValue(lhs)
188 & o3tl::underlyingEnumValue<E>(rhs));
189}
190
191template<typename E> constexpr typename o3tl::typed_flags<E>::Wrap operator &(
192 typename o3tl::typed_flags<E>::Wrap lhs, E rhs)
193{
194 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 196, __extension__ __PRETTY_FUNCTION__))
195 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 196, __extension__ __PRETTY_FUNCTION__))
196 o3tl::underlyingEnumValue(rhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 196, __extension__ __PRETTY_FUNCTION__))
;
197 return static_cast<typename o3tl::typed_flags<E>::Wrap>(
198 o3tl::underlyingEnumValue<E>(lhs)
199 & o3tl::underlyingEnumValue(rhs));
200}
201
202template<typename W> constexpr
203typename o3tl::typed_flags<typename W::Unwrapped::Self>::Wrap operator &(
204 W lhs, W rhs)
205{
206 return static_cast<W>(
207 o3tl::underlyingEnumValue<typename W::Unwrapped::Self>(lhs)
208 & o3tl::underlyingEnumValue<typename W::Unwrapped::Self>(rhs));
209}
210
211template<typename E>
212constexpr typename o3tl::typed_flags<E>::Wrap operator |(E lhs, E rhs) {
213 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 215, __extension__ __PRETTY_FUNCTION__))
214 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 215, __extension__ __PRETTY_FUNCTION__))
215 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 215, __extension__ __PRETTY_FUNCTION__))
;
216 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 218, __extension__ __PRETTY_FUNCTION__))
217 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 218, __extension__ __PRETTY_FUNCTION__))
218 o3tl::underlyingEnumValue(rhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 218, __extension__ __PRETTY_FUNCTION__))
;
219 return static_cast<typename o3tl::typed_flags<E>::Wrap>(
220 o3tl::underlyingEnumValue(lhs)
221 | o3tl::underlyingEnumValue(rhs));
222}
223
224template<typename E> constexpr typename o3tl::typed_flags<E>::Wrap operator |(
225 E lhs, typename o3tl::typed_flags<E>::Wrap rhs)
226{
227 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 229, __extension__ __PRETTY_FUNCTION__))
228 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 229, __extension__ __PRETTY_FUNCTION__))
229 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 229, __extension__ __PRETTY_FUNCTION__))
;
230 return static_cast<typename o3tl::typed_flags<E>::Wrap>(
231 o3tl::underlyingEnumValue(lhs)
232 | o3tl::underlyingEnumValue<E>(rhs));
233}
234
235template<typename E> constexpr typename o3tl::typed_flags<E>::Wrap operator |(
236 typename o3tl::typed_flags<E>::Wrap lhs, E rhs)
237{
238 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 240, __extension__ __PRETTY_FUNCTION__))
239 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 240, __extension__ __PRETTY_FUNCTION__))
240 o3tl::underlyingEnumValue(rhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 240, __extension__ __PRETTY_FUNCTION__))
;
241 return static_cast<typename o3tl::typed_flags<E>::Wrap>(
242 o3tl::underlyingEnumValue<E>(lhs)
243 | o3tl::underlyingEnumValue(rhs));
244}
245
246template<typename W> constexpr
247typename o3tl::typed_flags<typename W::Unwrapped::Self>::Wrap operator |(
248 W lhs, W rhs)
249{
250 return static_cast<W>(
251 o3tl::underlyingEnumValue<typename W::Unwrapped::Self>(lhs)
252 | o3tl::underlyingEnumValue<typename W::Unwrapped::Self>(rhs));
253}
254
255template<typename E>
256inline typename o3tl::typed_flags<E>::Self operator &=(E & lhs, E rhs) {
257 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 259, __extension__ __PRETTY_FUNCTION__))
258 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 259, __extension__ __PRETTY_FUNCTION__))
259 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 259, __extension__ __PRETTY_FUNCTION__))
;
260 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 262, __extension__ __PRETTY_FUNCTION__))
261 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 262, __extension__ __PRETTY_FUNCTION__))
262 o3tl::underlyingEnumValue(rhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 262, __extension__ __PRETTY_FUNCTION__))
;
263 lhs = lhs & rhs;
264 return lhs;
265}
266
267template<typename E>
268inline typename o3tl::typed_flags<E>::Self operator &=(
269 E & lhs, typename o3tl::typed_flags<E>::Wrap rhs)
270{
271 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 273, __extension__ __PRETTY_FUNCTION__))
272 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 273, __extension__ __PRETTY_FUNCTION__))
273 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 273, __extension__ __PRETTY_FUNCTION__))
;
274 lhs = lhs & rhs;
275 return lhs;
276}
277
278template<typename E>
279inline typename o3tl::typed_flags<E>::Self operator |=(E & lhs, E rhs) {
280 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 282, __extension__ __PRETTY_FUNCTION__))
281 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 282, __extension__ __PRETTY_FUNCTION__))
282 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 282, __extension__ __PRETTY_FUNCTION__))
;
283 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 285, __extension__ __PRETTY_FUNCTION__))
284 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 285, __extension__ __PRETTY_FUNCTION__))
285 o3tl::underlyingEnumValue(rhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 285, __extension__ __PRETTY_FUNCTION__))
;
286 lhs = lhs | rhs;
287 return lhs;
288}
289
290template<typename E>
291inline typename o3tl::typed_flags<E>::Self operator |=(
292 E & lhs, typename o3tl::typed_flags<E>::Wrap rhs)
293{
294 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 296, __extension__ __PRETTY_FUNCTION__))
295 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 296, __extension__ __PRETTY_FUNCTION__))
296 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 296, __extension__ __PRETTY_FUNCTION__))
;
297 lhs = lhs | rhs;
298 return lhs;
299}
300
301template<typename E>
302inline typename o3tl::typed_flags<E>::Self operator ^=(E & lhs, E rhs) {
303 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 305, __extension__ __PRETTY_FUNCTION__))
304 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 305, __extension__ __PRETTY_FUNCTION__))
305 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 305, __extension__ __PRETTY_FUNCTION__))
;
306 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 308, __extension__ __PRETTY_FUNCTION__))
307 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 308, __extension__ __PRETTY_FUNCTION__))
308 o3tl::underlyingEnumValue(rhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(rhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(rhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 308, __extension__ __PRETTY_FUNCTION__))
;
309 lhs = lhs ^ rhs;
310 return lhs;
311}
312
313template<typename E>
314inline typename o3tl::typed_flags<E>::Self operator ^=(
315 E & lhs, typename o3tl::typed_flags<E>::Wrap rhs)
316{
317 assert((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 319, __extension__ __PRETTY_FUNCTION__))
318 o3tl::detail::isNonNegative((static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 319, __extension__ __PRETTY_FUNCTION__))
319 o3tl::underlyingEnumValue(lhs)))(static_cast <bool> (o3tl::detail::isNonNegative( o3tl::
underlyingEnumValue(lhs))) ? void (0) : __assert_fail ("o3tl::detail::isNonNegative( o3tl::underlyingEnumValue(lhs))"
, "/home/maarten/src/libreoffice/core/include/o3tl/typed_flags_set.hxx"
, 319, __extension__ __PRETTY_FUNCTION__))
;
320 lhs = lhs ^ rhs;
321 return lhs;
322}
323
324#endif /* INCLUDED_O3TL_TYPED_FLAGS_SET_HXX */
325
326/* vim:set shiftwidth=4 softtabstop=4 expandtab: */