File: | home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx |
Warning: | line 1803, column 17 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 <svx/svdpage.hxx> | ||||||
21 | #include <editeng/brushitem.hxx> | ||||||
22 | #include <editeng/shaditem.hxx> | ||||||
23 | #include <editeng/ulspitem.hxx> | ||||||
24 | #include <editeng/boxitem.hxx> | ||||||
25 | #include <editeng/lspcitem.hxx> | ||||||
26 | #include <editeng/fhgtitem.hxx> | ||||||
27 | #include <sal/log.hxx> | ||||||
28 | |||||||
29 | #include <drawdoc.hxx> | ||||||
30 | #include <fmtornt.hxx> | ||||||
31 | #include <fmthdft.hxx> | ||||||
32 | #include <fmtfsize.hxx> | ||||||
33 | #include <fmtsrnd.hxx> | ||||||
34 | #include <docary.hxx> | ||||||
35 | #include <lineinfo.hxx> | ||||||
36 | #include <swmodule.hxx> | ||||||
37 | #include <pagefrm.hxx> | ||||||
38 | #include <colfrm.hxx> | ||||||
39 | #include <fesh.hxx> | ||||||
40 | #include <viewimp.hxx> | ||||||
41 | #include <viewopt.hxx> | ||||||
42 | #include <dflyobj.hxx> | ||||||
43 | #include <dcontact.hxx> | ||||||
44 | #include <frmatr.hxx> | ||||||
45 | #include <frmtool.hxx> | ||||||
46 | #include <tabfrm.hxx> | ||||||
47 | #include <rowfrm.hxx> | ||||||
48 | #include <ftnfrm.hxx> | ||||||
49 | #include <txtfrm.hxx> | ||||||
50 | #include <notxtfrm.hxx> | ||||||
51 | #include <flyfrms.hxx> | ||||||
52 | #include <layact.hxx> | ||||||
53 | #include <pagedesc.hxx> | ||||||
54 | #include <section.hxx> | ||||||
55 | #include <sectfrm.hxx> | ||||||
56 | #include <node2lay.hxx> | ||||||
57 | #include <ndole.hxx> | ||||||
58 | #include <hints.hxx> | ||||||
59 | #include "layhelp.hxx" | ||||||
60 | #include <laycache.hxx> | ||||||
61 | #include <rootfrm.hxx> | ||||||
62 | #include <paratr.hxx> | ||||||
63 | #include <redline.hxx> | ||||||
64 | #include <sortedobjs.hxx> | ||||||
65 | #include <objectformatter.hxx> | ||||||
66 | #include <calbck.hxx> | ||||||
67 | #include <ndtxt.hxx> | ||||||
68 | #include <undobj.hxx> | ||||||
69 | #include <DocumentSettingManager.hxx> | ||||||
70 | #include <IDocumentDrawModelAccess.hxx> | ||||||
71 | #include <IDocumentTimerAccess.hxx> | ||||||
72 | #include <IDocumentRedlineAccess.hxx> | ||||||
73 | #include <IDocumentFieldsAccess.hxx> | ||||||
74 | #include <IDocumentState.hxx> | ||||||
75 | #include <frameformats.hxx> | ||||||
76 | #include <boost/circular_buffer.hpp> | ||||||
77 | #include <svx/sdr/attribute/sdrallfillattributeshelper.hxx> | ||||||
78 | |||||||
79 | using namespace ::com::sun::star; | ||||||
80 | |||||||
81 | bool bObjsDirect = true; | ||||||
82 | bool bDontCreateObjects = false; | ||||||
83 | bool bSetCompletePaintOnInvalidate = false; | ||||||
84 | |||||||
85 | sal_uInt8 StackHack::nCnt = 0; | ||||||
86 | bool StackHack::bLocked = false; | ||||||
87 | |||||||
88 | SwFrameNotify::SwFrameNotify( SwFrame *pF ) : | ||||||
89 | mpFrame( pF ), | ||||||
90 | maFrame( pF->getFrameArea() ), | ||||||
91 | maPrt( pF->getFramePrintArea() ), | ||||||
92 | mbInvaKeep( false ), | ||||||
93 | mbValidSize( pF->isFrameAreaSizeValid() ) | ||||||
94 | { | ||||||
95 | if ( pF->IsTextFrame() ) | ||||||
96 | { | ||||||
97 | mnFlyAnchorOfst = static_cast<SwTextFrame*>(pF)->GetBaseOffsetForFly( true ); | ||||||
98 | mnFlyAnchorOfstNoWrap = static_cast<SwTextFrame*>(pF)->GetBaseOffsetForFly( false ); | ||||||
99 | } | ||||||
100 | else | ||||||
101 | { | ||||||
102 | mnFlyAnchorOfst = 0; | ||||||
103 | mnFlyAnchorOfstNoWrap = 0; | ||||||
104 | } | ||||||
105 | |||||||
106 | mbHadFollow = pF->IsContentFrame() && static_cast<SwContentFrame*>(pF)->GetFollow(); | ||||||
107 | } | ||||||
108 | |||||||
109 | SwFrameNotify::~SwFrameNotify() COVERITY_NOEXCEPT_FALSE | ||||||
110 | { | ||||||
111 | SwRectFnSet aRectFnSet(mpFrame); | ||||||
112 | const bool bAbsP = aRectFnSet.PosDiff(maFrame, mpFrame->getFrameArea()); | ||||||
113 | const bool bChgWidth = | ||||||
114 | aRectFnSet.GetWidth(maFrame) != aRectFnSet.GetWidth(mpFrame->getFrameArea()); | ||||||
115 | const bool bChgHeight = | ||||||
116 | aRectFnSet.GetHeight(maFrame)!=aRectFnSet.GetHeight(mpFrame->getFrameArea()); | ||||||
117 | const bool bChgFlyBasePos = mpFrame->IsTextFrame() && | ||||||
118 | ( ( mnFlyAnchorOfst != static_cast<SwTextFrame*>(mpFrame)->GetBaseOffsetForFly( true ) ) || | ||||||
119 | ( mnFlyAnchorOfstNoWrap != static_cast<SwTextFrame*>(mpFrame)->GetBaseOffsetForFly( false ) ) ); | ||||||
120 | |||||||
121 | if ( mpFrame->IsFlowFrame() && !mpFrame->IsInFootnote() ) | ||||||
122 | { | ||||||
123 | SwFlowFrame *pFlow = SwFlowFrame::CastFlowFrame( mpFrame ); | ||||||
124 | |||||||
125 | if ( !pFlow->IsFollow() ) | ||||||
126 | { | ||||||
127 | if ( !mpFrame->GetIndPrev() ) | ||||||
128 | { | ||||||
129 | if ( mbInvaKeep ) | ||||||
130 | { | ||||||
131 | SwFrame *pPre = mpFrame->FindPrev(); | ||||||
132 | if ( pPre && pPre->IsFlowFrame() ) | ||||||
133 | { | ||||||
134 | // 1. pPre wants to keep with me: | ||||||
135 | bool bInvalidPrePos = SwFlowFrame::CastFlowFrame(pPre)->IsKeep(pPre->GetAttrSet()->GetKeep(), pPre->GetBreakItem()) | ||||||
136 | && pPre->GetIndPrev(); | ||||||
137 | |||||||
138 | // 2. pPre is a table and the last row wants to keep with me: | ||||||
139 | if ( !bInvalidPrePos && pPre->IsTabFrame() ) | ||||||
140 | { | ||||||
141 | SwTabFrame* pPreTab = static_cast<SwTabFrame*>(pPre); | ||||||
142 | if ( pPreTab->GetFormat()->GetDoc()->GetDocumentSettingManager().get(DocumentSettingId::TABLE_ROW_KEEP) ) | ||||||
143 | { | ||||||
144 | SwRowFrame* pLastRow = static_cast<SwRowFrame*>(pPreTab->GetLastLower()); | ||||||
145 | if ( pLastRow && pLastRow->ShouldRowKeepWithNext() ) | ||||||
146 | bInvalidPrePos = true; | ||||||
147 | } | ||||||
148 | } | ||||||
149 | |||||||
150 | if ( bInvalidPrePos ) | ||||||
151 | pPre->InvalidatePos(); | ||||||
152 | } | ||||||
153 | } | ||||||
154 | } | ||||||
155 | else if ( !pFlow->HasFollow() ) | ||||||
156 | { | ||||||
157 | long nOldHeight = aRectFnSet.GetHeight(maFrame); | ||||||
158 | long nNewHeight = aRectFnSet.GetHeight(mpFrame->getFrameArea()); | ||||||
159 | if( (nOldHeight > nNewHeight) || (!nOldHeight && nNewHeight) ) | ||||||
160 | pFlow->CheckKeep(); | ||||||
161 | } | ||||||
162 | } | ||||||
163 | } | ||||||
164 | |||||||
165 | if ( bAbsP ) | ||||||
166 | { | ||||||
167 | mpFrame->SetCompletePaint(); | ||||||
168 | |||||||
169 | SwFrame* pNxt = mpFrame->GetIndNext(); | ||||||
170 | // #121888# - skip empty section frames | ||||||
171 | while ( pNxt && | ||||||
172 | pNxt->IsSctFrame() && !static_cast<SwSectionFrame*>(pNxt)->GetSection() ) | ||||||
173 | { | ||||||
174 | pNxt = pNxt->GetIndNext(); | ||||||
175 | } | ||||||
176 | |||||||
177 | if ( pNxt ) | ||||||
178 | pNxt->InvalidatePos(); | ||||||
179 | else | ||||||
180 | { | ||||||
181 | // #104100# - correct condition for setting retouche | ||||||
182 | // flag for vertical layout. | ||||||
183 | if( mpFrame->IsRetoucheFrame() && | ||||||
184 | aRectFnSet.TopDist( maFrame, aRectFnSet.GetTop(mpFrame->getFrameArea()) ) > 0 ) | ||||||
185 | { | ||||||
186 | mpFrame->SetRetouche(); | ||||||
187 | } | ||||||
188 | |||||||
189 | // A fresh follow frame does not have to be invalidated, because | ||||||
190 | // it is already formatted: | ||||||
191 | if ( mbHadFollow || !mpFrame->IsContentFrame() || !static_cast<SwContentFrame*>(mpFrame)->GetFollow() ) | ||||||
192 | { | ||||||
193 | if ( !mpFrame->IsTabFrame() || !static_cast<SwTabFrame*>(mpFrame)->GetFollow() ) | ||||||
194 | mpFrame->InvalidateNextPos(); | ||||||
195 | } | ||||||
196 | } | ||||||
197 | } | ||||||
198 | |||||||
199 | //For each resize of the background graphics is a repaint necessary. | ||||||
200 | const bool bPrtWidth = | ||||||
201 | aRectFnSet.GetWidth(maPrt) != aRectFnSet.GetWidth(mpFrame->getFramePrintArea()); | ||||||
202 | const bool bPrtHeight = | ||||||
203 | aRectFnSet.GetHeight(maPrt)!=aRectFnSet.GetHeight(mpFrame->getFramePrintArea()); | ||||||
204 | if ( bPrtWidth || bPrtHeight ) | ||||||
205 | { | ||||||
206 | bool bUseNewFillProperties(false); | ||||||
207 | if (mpFrame->supportsFullDrawingLayerFillAttributeSet()) | ||||||
208 | { | ||||||
209 | drawinglayer::attribute::SdrAllFillAttributesHelperPtr aFillAttributes(mpFrame->getSdrAllFillAttributesHelper()); | ||||||
210 | if(aFillAttributes && aFillAttributes->isUsed()) | ||||||
211 | { | ||||||
212 | bUseNewFillProperties = true; | ||||||
213 | // use SetCompletePaint if needed | ||||||
214 | if(aFillAttributes->needCompleteRepaint()) | ||||||
215 | { | ||||||
216 | mpFrame->SetCompletePaint(); | ||||||
217 | } | ||||||
218 | } | ||||||
219 | } | ||||||
220 | if (!bUseNewFillProperties) | ||||||
221 | { | ||||||
222 | const SvxGraphicPosition ePos = mpFrame->GetAttrSet()->GetBackground().GetGraphicPos(); | ||||||
223 | if(GPOS_NONE != ePos && GPOS_TILED != ePos) | ||||||
224 | mpFrame->SetCompletePaint(); | ||||||
225 | } | ||||||
226 | } | ||||||
227 | else | ||||||
228 | { | ||||||
229 | // #97597# - consider case that *only* margins between | ||||||
230 | // frame and printing area has changed. Then, frame has to be repainted, | ||||||
231 | // in order to force paint of the margin areas. | ||||||
232 | if ( !bAbsP && (bChgWidth || bChgHeight) ) | ||||||
233 | { | ||||||
234 | mpFrame->SetCompletePaint(); | ||||||
235 | } | ||||||
236 | } | ||||||
237 | |||||||
238 | const bool bPrtP = aRectFnSet.PosDiff( maPrt, mpFrame->getFramePrintArea() ); | ||||||
239 | if ( bAbsP || bPrtP || bChgWidth || bChgHeight || | ||||||
240 | bPrtWidth || bPrtHeight || bChgFlyBasePos ) | ||||||
241 | { | ||||||
242 | if( mpFrame->IsAccessibleFrame() ) | ||||||
243 | { | ||||||
244 | SwRootFrame *pRootFrame = mpFrame->getRootFrame(); | ||||||
245 | if( pRootFrame && pRootFrame->IsAnyShellAccessible() && | ||||||
246 | pRootFrame->GetCurrShell() ) | ||||||
247 | { | ||||||
248 | pRootFrame->GetCurrShell()->Imp()->MoveAccessibleFrame( mpFrame, maFrame ); | ||||||
249 | } | ||||||
250 | } | ||||||
251 | |||||||
252 | // Notification of anchored objects | ||||||
253 | if ( mpFrame->GetDrawObjs() ) | ||||||
254 | { | ||||||
255 | const SwSortedObjs &rObjs = *mpFrame->GetDrawObjs(); | ||||||
256 | SwPageFrame* pPageFrame = nullptr; | ||||||
257 | for (SwAnchoredObject* pObj : rObjs) | ||||||
258 | { | ||||||
259 | // OD 2004-03-31 #i26791# - no general distinction between | ||||||
260 | // Writer fly frames and drawing objects | ||||||
261 | bool bNotify = false; | ||||||
262 | bool bNotifySize = false; | ||||||
263 | SwContact* pContact = ::GetUserCall( pObj->GetDrawObj() ); | ||||||
264 | const bool bAnchoredAsChar = pContact->ObjAnchoredAsChar(); | ||||||
265 | if ( !bAnchoredAsChar ) | ||||||
266 | { | ||||||
267 | // Notify object, which aren't anchored as-character: | ||||||
268 | |||||||
269 | // always notify objects, if frame position has changed | ||||||
270 | // or if the object is to-page|to-fly anchored. | ||||||
271 | if ( bAbsP || | ||||||
272 | pContact->ObjAnchoredAtPage() || | ||||||
273 | pContact->ObjAnchoredAtFly() ) | ||||||
274 | { | ||||||
275 | bNotify = true; | ||||||
276 | |||||||
277 | // assure that to-fly anchored Writer fly frames are | ||||||
278 | // registered at the correct page frame, if frame | ||||||
279 | // position has changed. | ||||||
280 | if ( bAbsP && pContact->ObjAnchoredAtFly() && | ||||||
281 | dynamic_cast<const SwFlyFrame*>( pObj) != nullptr ) | ||||||
282 | { | ||||||
283 | // determine to-fly anchored Writer fly frame | ||||||
284 | SwFlyFrame* pFlyFrame = static_cast<SwFlyFrame*>(pObj); | ||||||
285 | // determine page frame of to-fly anchored | ||||||
286 | // Writer fly frame | ||||||
287 | SwPageFrame* pFlyPageFrame = pFlyFrame->FindPageFrame(); | ||||||
288 | // determine page frame, if needed. | ||||||
289 | if ( !pPageFrame ) | ||||||
290 | { | ||||||
291 | pPageFrame = mpFrame->FindPageFrame(); | ||||||
292 | } | ||||||
293 | if ( pPageFrame != pFlyPageFrame ) | ||||||
294 | { | ||||||
295 | OSL_ENSURE( pFlyPageFrame, "~SwFrameNotify: Fly from Nowhere" )do { if (true && (!(pFlyPageFrame))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "295" ": "), "%s", "~SwFrameNotify: Fly from Nowhere"); } } while (false); | ||||||
296 | if( pFlyPageFrame ) | ||||||
297 | pFlyPageFrame->MoveFly( pFlyFrame, pPageFrame ); | ||||||
298 | else | ||||||
299 | pPageFrame->AppendFlyToPage( pFlyFrame ); | ||||||
300 | } | ||||||
301 | } | ||||||
302 | } | ||||||
303 | // otherwise the objects are notified in dependence to | ||||||
304 | // its positioning and alignment | ||||||
305 | else | ||||||
306 | { | ||||||
307 | const SwFormatVertOrient& rVert = | ||||||
308 | pContact->GetFormat()->GetVertOrient(); | ||||||
309 | if ( ( rVert.GetVertOrient() == text::VertOrientation::CENTER || | ||||||
310 | rVert.GetVertOrient() == text::VertOrientation::BOTTOM || | ||||||
311 | rVert.GetRelationOrient() == text::RelOrientation::PRINT_AREA ) && | ||||||
312 | ( bChgHeight || bPrtHeight ) ) | ||||||
313 | { | ||||||
314 | bNotify = true; | ||||||
315 | } | ||||||
316 | if ( !bNotify ) | ||||||
317 | { | ||||||
318 | const SwFormatHoriOrient& rHori = | ||||||
319 | pContact->GetFormat()->GetHoriOrient(); | ||||||
320 | if ( ( rHori.GetHoriOrient() != text::HoriOrientation::NONE || | ||||||
321 | rHori.GetRelationOrient()== text::RelOrientation::PRINT_AREA || | ||||||
322 | rHori.GetRelationOrient()== text::RelOrientation::FRAME ) && | ||||||
323 | ( bChgWidth || bPrtWidth || bChgFlyBasePos ) ) | ||||||
324 | { | ||||||
325 | bNotify = true; | ||||||
326 | } | ||||||
327 | } | ||||||
328 | } | ||||||
329 | } | ||||||
330 | else if ( bPrtWidth ) | ||||||
331 | { | ||||||
332 | // Notify as-character anchored objects, if printing area | ||||||
333 | // width has changed. | ||||||
334 | bNotify = true; | ||||||
335 | bNotifySize = true; | ||||||
336 | } | ||||||
337 | |||||||
338 | // perform notification via the corresponding invalidations | ||||||
339 | if ( bNotify ) | ||||||
340 | { | ||||||
341 | if ( dynamic_cast<const SwFlyFrame*>( pObj) != nullptr ) | ||||||
342 | { | ||||||
343 | SwFlyFrame* pFlyFrame = static_cast<SwFlyFrame*>(pObj); | ||||||
344 | if ( bNotifySize ) | ||||||
345 | pFlyFrame->InvalidateSize_(); | ||||||
346 | // #115759# - no invalidation of | ||||||
347 | // position for as-character anchored objects. | ||||||
348 | if ( !bAnchoredAsChar ) | ||||||
349 | { | ||||||
350 | pFlyFrame->InvalidatePos_(); | ||||||
351 | } | ||||||
352 | pFlyFrame->Invalidate_(); | ||||||
353 | } | ||||||
354 | else if ( dynamic_cast<const SwAnchoredDrawObject*>( pObj) != nullptr ) | ||||||
355 | { | ||||||
356 | // #115759# - no invalidation of | ||||||
357 | // position for as-character anchored objects. | ||||||
358 | if ( !bAnchoredAsChar ) | ||||||
359 | { | ||||||
360 | pObj->InvalidateObjPos(); | ||||||
361 | } | ||||||
362 | } | ||||||
363 | else | ||||||
364 | { | ||||||
365 | OSL_FAIL( "<SwContentNotify::~SwContentNotify()> - unknown anchored object type." )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "365" ": "), "%s", "<SwContentNotify::~SwContentNotify()> - unknown anchored object type." ); } } while (false); | ||||||
366 | } | ||||||
367 | } | ||||||
368 | } | ||||||
369 | } | ||||||
370 | } | ||||||
371 | else if( mpFrame->IsTextFrame() && mbValidSize != mpFrame->isFrameAreaSizeValid() ) | ||||||
372 | { | ||||||
373 | SwRootFrame *pRootFrame = mpFrame->getRootFrame(); | ||||||
374 | if( pRootFrame && pRootFrame->IsAnyShellAccessible() && | ||||||
375 | pRootFrame->GetCurrShell() ) | ||||||
376 | { | ||||||
377 | pRootFrame->GetCurrShell()->Imp()->InvalidateAccessibleFrameContent( mpFrame ); | ||||||
378 | } | ||||||
379 | } | ||||||
380 | |||||||
381 | // #i9046# Automatic frame width | ||||||
382 | SwFlyFrame* pFly = nullptr; | ||||||
383 | // #i35879# Do not trust the inf flags. pFrame does not | ||||||
384 | // necessarily have to have an upper! | ||||||
385 | if ( mpFrame->IsFlyFrame() || nullptr == ( pFly = mpFrame->ImplFindFlyFrame() )) | ||||||
386 | return; | ||||||
387 | |||||||
388 | // #i61999# | ||||||
389 | // no invalidation of columned Writer fly frames, because automatic | ||||||
390 | // width doesn't make sense for such Writer fly frames. | ||||||
391 | if ( !pFly->Lower() || pFly->Lower()->IsColumnFrame() ) | ||||||
392 | return; | ||||||
393 | |||||||
394 | const SwFormatFrameSize &rFrameSz = pFly->GetFormat()->GetFrameSize(); | ||||||
395 | |||||||
396 | // This could be optimized. Basically the fly frame only has to | ||||||
397 | // be invalidated, if the first line of pFrame (if pFrame is a content | ||||||
398 | // frame, for other frame types it's the print area) has changed its | ||||||
399 | // size and pFrame was responsible for the current width of pFly. On | ||||||
400 | // the other hand, this is only rarely used and re-calculation of | ||||||
401 | // the fly frame does not cause too much trouble. So we keep it this | ||||||
402 | // way: | ||||||
403 | if ( SwFrameSize::Fixed != rFrameSz.GetWidthSizeType() ) | ||||||
404 | { | ||||||
405 | // #i50668#, #i50998# - invalidation of position | ||||||
406 | // of as-character anchored fly frames not needed and can cause | ||||||
407 | // layout loops | ||||||
408 | if ( dynamic_cast<const SwFlyInContentFrame*>( pFly) == nullptr ) | ||||||
409 | { | ||||||
410 | pFly->InvalidatePos(); | ||||||
411 | } | ||||||
412 | pFly->InvalidateSize(); | ||||||
413 | } | ||||||
414 | } | ||||||
415 | |||||||
416 | SwLayNotify::SwLayNotify( SwLayoutFrame *pLayFrame ) : | ||||||
417 | SwFrameNotify( pLayFrame ), | ||||||
418 | m_bLowersComplete( false ) | ||||||
419 | { | ||||||
420 | } | ||||||
421 | |||||||
422 | // OD 2004-05-11 #i28701# - local method to invalidate the position of all | ||||||
423 | // frames inclusive its floating screen objects, which are lowers of the given | ||||||
424 | // layout frame | ||||||
425 | static void lcl_InvalidatePosOfLowers( SwLayoutFrame& _rLayoutFrame ) | ||||||
426 | { | ||||||
427 | if( _rLayoutFrame.IsFlyFrame() && _rLayoutFrame.GetDrawObjs() ) | ||||||
428 | { | ||||||
429 | _rLayoutFrame.InvalidateObjs( false ); | ||||||
430 | } | ||||||
431 | |||||||
432 | SwFrame* pLowerFrame = _rLayoutFrame.Lower(); | ||||||
433 | while ( pLowerFrame ) | ||||||
434 | { | ||||||
435 | pLowerFrame->InvalidatePos(); | ||||||
436 | if ( pLowerFrame->IsTextFrame() ) | ||||||
437 | { | ||||||
438 | static_cast<SwTextFrame*>(pLowerFrame)->Prepare( PrepareHint::FramePositionChanged ); | ||||||
439 | } | ||||||
440 | else if ( pLowerFrame->IsTabFrame() ) | ||||||
441 | { | ||||||
442 | pLowerFrame->InvalidatePrt(); | ||||||
443 | } | ||||||
444 | |||||||
445 | pLowerFrame->InvalidateObjs( false ); | ||||||
446 | |||||||
447 | pLowerFrame = pLowerFrame->GetNext(); | ||||||
448 | } | ||||||
449 | } | ||||||
450 | |||||||
451 | SwLayNotify::~SwLayNotify() | ||||||
452 | { | ||||||
453 | SwLayoutFrame *pLay = static_cast<SwLayoutFrame*>(mpFrame); | ||||||
454 | SwRectFnSet aRectFnSet(pLay); | ||||||
455 | bool bNotify = false; | ||||||
456 | if ( pLay->getFramePrintArea().SSize() != maPrt.SSize() ) | ||||||
457 | { | ||||||
458 | if ( !IsLowersComplete() ) | ||||||
459 | { | ||||||
460 | bool bInvaPercent; | ||||||
461 | |||||||
462 | if ( pLay->IsRowFrame() ) | ||||||
463 | { | ||||||
464 | bInvaPercent = true; | ||||||
465 | long nNew = aRectFnSet.GetHeight(pLay->getFramePrintArea()); | ||||||
466 | if( nNew != aRectFnSet.GetHeight(maPrt) ) | ||||||
467 | static_cast<SwRowFrame*>(pLay)->AdjustCells( nNew, true); | ||||||
468 | if( aRectFnSet.GetWidth(pLay->getFramePrintArea()) | ||||||
469 | != aRectFnSet.GetWidth(maPrt) ) | ||||||
470 | static_cast<SwRowFrame*>(pLay)->AdjustCells( 0, false ); | ||||||
471 | } | ||||||
472 | else | ||||||
473 | { | ||||||
474 | //Proportional adoption of the internal. | ||||||
475 | //1. If the formatted is no Fly | ||||||
476 | //2. If he contains no columns | ||||||
477 | //3. If the Fly has a fixed height and the columns | ||||||
478 | // are next to be. | ||||||
479 | // Hoehe danebenliegen. | ||||||
480 | //4. Never at SectionFrames. | ||||||
481 | bool bLow; | ||||||
482 | if( pLay->IsFlyFrame() ) | ||||||
483 | { | ||||||
484 | if ( pLay->Lower() ) | ||||||
485 | { | ||||||
486 | bLow = !pLay->Lower()->IsColumnFrame() || | ||||||
487 | aRectFnSet.GetHeight(pLay->Lower()->getFrameArea()) | ||||||
488 | != aRectFnSet.GetHeight(pLay->getFramePrintArea()); | ||||||
489 | } | ||||||
490 | else | ||||||
491 | bLow = false; | ||||||
492 | } | ||||||
493 | else if( pLay->IsSctFrame() ) | ||||||
494 | { | ||||||
495 | if ( pLay->Lower() ) | ||||||
496 | { | ||||||
497 | if( pLay->Lower()->IsColumnFrame() && pLay->Lower()->GetNext() ) | ||||||
498 | bLow = pLay->Lower()->getFrameArea().Height() != pLay->getFramePrintArea().Height(); | ||||||
499 | else | ||||||
500 | bLow = pLay->getFramePrintArea().Width() != maPrt.Width(); | ||||||
501 | } | ||||||
502 | else | ||||||
503 | bLow = false; | ||||||
504 | } | ||||||
505 | else if( pLay->IsFooterFrame() && !pLay->HasFixSize() ) | ||||||
506 | bLow = pLay->getFramePrintArea().Width() != maPrt.Width(); | ||||||
507 | else | ||||||
508 | bLow = true; | ||||||
509 | bInvaPercent = bLow; | ||||||
510 | if ( bLow ) | ||||||
511 | { | ||||||
512 | pLay->ChgLowersProp( maPrt.SSize() ); | ||||||
513 | } | ||||||
514 | // If the PrtArea has been extended, it might be possible that the chain of parts | ||||||
515 | // can take another frame. As a result, the "possible right one" needs to be | ||||||
516 | // invalidated. This only pays off if this or its Uppers are moveable sections. | ||||||
517 | // A PrtArea has been extended if width or height are larger than before. | ||||||
518 | if ( (pLay->getFramePrintArea().Height() > maPrt.Height() || | ||||||
519 | pLay->getFramePrintArea().Width() > maPrt.Width()) && | ||||||
520 | (pLay->IsMoveable() || pLay->IsFlyFrame()) ) | ||||||
521 | { | ||||||
522 | SwFrame *pTmpFrame = pLay->Lower(); | ||||||
523 | if ( pTmpFrame && pTmpFrame->IsFlowFrame() ) | ||||||
524 | { | ||||||
525 | while ( pTmpFrame->GetNext() ) | ||||||
526 | pTmpFrame = pTmpFrame->GetNext(); | ||||||
527 | pTmpFrame->InvalidateNextPos(); | ||||||
528 | } | ||||||
529 | } | ||||||
530 | } | ||||||
531 | bNotify = true; | ||||||
532 | //EXPENSIVE!! But how we do it more elegant? | ||||||
533 | if( bInvaPercent ) | ||||||
534 | pLay->InvaPercentLowers( pLay->getFramePrintArea().Height() - maPrt.Height() ); | ||||||
535 | } | ||||||
536 | if ( pLay->IsTabFrame() ) | ||||||
537 | //So that _only_ the shadow is drawn while resizing. | ||||||
538 | static_cast<SwTabFrame*>(pLay)->SetComplete(); | ||||||
539 | else | ||||||
540 | { | ||||||
541 | const SwViewShell *pSh = pLay->getRootFrame()->GetCurrShell(); | ||||||
542 | if( !( pSh && pSh->GetViewOptions()->getBrowseMode() ) || | ||||||
543 | !(pLay->GetType() & (SwFrameType::Body | SwFrameType::Page)) ) | ||||||
544 | //Thereby the subordinates are retouched clean. | ||||||
545 | //Example problem: Take the Flys with the handles and downsize. | ||||||
546 | //Not for body and page, otherwise it flickers when loading HTML. | ||||||
547 | pLay->SetCompletePaint(); | ||||||
548 | } | ||||||
549 | } | ||||||
550 | //Notify Lower if the position has changed. | ||||||
551 | const bool bPrtPos = aRectFnSet.PosDiff( maPrt, pLay->getFramePrintArea() ); | ||||||
552 | const bool bPos = bPrtPos || aRectFnSet.PosDiff( maFrame, pLay->getFrameArea() ); | ||||||
553 | const bool bSize = pLay->getFrameArea().SSize() != maFrame.SSize(); | ||||||
554 | |||||||
555 | if ( bPos && pLay->Lower() && !IsLowersComplete() ) | ||||||
556 | { | ||||||
557 | pLay->Lower()->InvalidatePos(); | ||||||
558 | SwFootnoteFrame* pFtnFrame = pLay->Lower()->IsFootnoteFrame() ? | ||||||
559 | static_cast<SwFootnoteFrame*>(pLay->Lower()) : nullptr; | ||||||
560 | SwFrame* pFtnLower = pFtnFrame ? pFtnFrame->Lower() : nullptr; | ||||||
561 | if (pFtnLower) | ||||||
562 | pFtnLower->InvalidatePos(); | ||||||
563 | } | ||||||
564 | |||||||
565 | if ( bPrtPos ) | ||||||
566 | pLay->SetCompletePaint(); | ||||||
567 | |||||||
568 | //Inform the Follower if the SSize has changed. | ||||||
569 | if ( bSize ) | ||||||
570 | { | ||||||
571 | if( pLay->GetNext() ) | ||||||
572 | { | ||||||
573 | if ( pLay->GetNext()->IsLayoutFrame() ) | ||||||
574 | pLay->GetNext()->InvalidatePos_(); | ||||||
575 | else | ||||||
576 | pLay->GetNext()->InvalidatePos(); | ||||||
577 | } | ||||||
578 | else if( pLay->IsSctFrame() ) | ||||||
579 | pLay->InvalidateNextPos(); | ||||||
580 | } | ||||||
581 | if ( !IsLowersComplete() && | ||||||
582 | !(pLay->GetType()&(SwFrameType::Fly|SwFrameType::Section) && | ||||||
583 | pLay->Lower() && pLay->Lower()->IsColumnFrame()) && | ||||||
584 | (bPos || bNotify) && | ||||||
585 | !(pLay->GetType() & (SwFrameType::Row|SwFrameType::Tab|SwFrameType::FtnCont|SwFrameType::Page|SwFrameType::Root))) | ||||||
586 | { | ||||||
587 | // #i44016# - force unlock of position of lower objects. | ||||||
588 | // #i43913# - no unlock of position of objects, | ||||||
589 | // if <pLay> is a cell frame, and its table frame resp. its parent table | ||||||
590 | // frame is locked. | ||||||
591 | // #i47458# - force unlock of position of lower objects, | ||||||
592 | // only if position of layout frame has changed. | ||||||
593 | bool bUnlockPosOfObjs( bPos ); | ||||||
594 | if ( bUnlockPosOfObjs && pLay->IsCellFrame() ) | ||||||
595 | { | ||||||
596 | SwTabFrame* pTabFrame( pLay->FindTabFrame() ); | ||||||
597 | if ( pTabFrame && | ||||||
598 | ( pTabFrame->IsJoinLocked() || | ||||||
599 | ( pTabFrame->IsFollow() && | ||||||
600 | pTabFrame->FindMaster()->IsJoinLocked() ) ) ) | ||||||
601 | { | ||||||
602 | bUnlockPosOfObjs = false; | ||||||
603 | } | ||||||
604 | } | ||||||
605 | // #i49383# - check for footnote frame, if unlock | ||||||
606 | // of position of lower objects is allowed. | ||||||
607 | else if ( bUnlockPosOfObjs && pLay->IsFootnoteFrame() ) | ||||||
608 | { | ||||||
609 | bUnlockPosOfObjs = static_cast<SwFootnoteFrame*>(pLay)->IsUnlockPosOfLowerObjs(); | ||||||
610 | } | ||||||
611 | // #i51303# - no unlock of object positions for sections | ||||||
612 | else if ( bUnlockPosOfObjs && pLay->IsSctFrame() ) | ||||||
613 | { | ||||||
614 | bUnlockPosOfObjs = false; | ||||||
615 | } | ||||||
616 | pLay->NotifyLowerObjs( bUnlockPosOfObjs ); | ||||||
617 | } | ||||||
618 | if ( bPos && pLay->IsFootnoteFrame() && pLay->Lower() ) | ||||||
619 | { | ||||||
620 | // OD 2004-05-11 #i28701# | ||||||
621 | ::lcl_InvalidatePosOfLowers( *pLay ); | ||||||
622 | } | ||||||
623 | if( ( bPos || bSize ) && pLay->IsFlyFrame() && static_cast<SwFlyFrame*>(pLay)->GetAnchorFrame() | ||||||
624 | && static_cast<SwFlyFrame*>(pLay)->GetAnchorFrame()->IsFlyFrame() ) | ||||||
625 | static_cast<SwFlyFrame*>(pLay)->AnchorFrame()->InvalidateSize(); | ||||||
626 | } | ||||||
627 | |||||||
628 | SwFlyNotify::SwFlyNotify( SwFlyFrame *pFlyFrame ) : | ||||||
629 | SwLayNotify( pFlyFrame ), | ||||||
630 | // #115759# - keep correct page frame - the page frame | ||||||
631 | // the Writer fly frame is currently registered at. | ||||||
632 | pOldPage( pFlyFrame->GetPageFrame() ), | ||||||
633 | aFrameAndSpace( pFlyFrame->GetObjRectWithSpaces() ) | ||||||
634 | { | ||||||
635 | } | ||||||
636 | |||||||
637 | SwFlyNotify::~SwFlyNotify() | ||||||
638 | { | ||||||
639 | SwFlyFrame *pFly = static_cast<SwFlyFrame*>(mpFrame); | ||||||
640 | if ( pFly->IsNotifyBack() ) | ||||||
641 | { | ||||||
642 | SwViewShell *pSh = pFly->getRootFrame()->GetCurrShell(); | ||||||
643 | SwViewShellImp *pImp = pSh ? pSh->Imp() : nullptr; | ||||||
644 | if ( !pImp || !pImp->IsAction() || !pImp->GetLayAction().IsAgain() ) | ||||||
645 | { | ||||||
646 | //If in the LayAction the IsAgain is set it can be | ||||||
647 | //that the old page is destroyed in the meantime! | ||||||
648 | ::Notify( pFly, pOldPage, aFrameAndSpace, &maPrt ); | ||||||
649 | // #i35640# - additional notify anchor text frame, | ||||||
650 | // if Writer fly frame has changed its page | ||||||
651 | if ( pFly->GetAnchorFrame()->IsTextFrame() && | ||||||
652 | pFly->GetPageFrame() != pOldPage ) | ||||||
653 | { | ||||||
654 | pFly->AnchorFrame()->Prepare( PrepareHint::FlyFrameLeave ); | ||||||
655 | } | ||||||
656 | } | ||||||
657 | pFly->ResetNotifyBack(); | ||||||
658 | } | ||||||
659 | |||||||
660 | //Have the size or the position changed, | ||||||
661 | //so should the view know this. | ||||||
662 | SwRectFnSet aRectFnSet(pFly); | ||||||
663 | const bool bPosChgd = aRectFnSet.PosDiff( maFrame, pFly->getFrameArea() ); | ||||||
664 | const bool bFrameChgd = pFly->getFrameArea().SSize() != maFrame.SSize(); | ||||||
665 | const bool bPrtChgd = maPrt != pFly->getFramePrintArea(); | ||||||
666 | if ( bPosChgd || bFrameChgd || bPrtChgd ) | ||||||
667 | { | ||||||
668 | pFly->NotifyDrawObj(); | ||||||
669 | } | ||||||
670 | if ( bPosChgd && maFrame.Pos().X() != FAR_AWAY(((sal_Int32) 0x7FFFFFFF) - 20000) ) | ||||||
671 | { | ||||||
672 | // OD 2004-05-10 #i28701# - no direct move of lower Writer fly frames. | ||||||
673 | // reason: New positioning and alignment (e.g. to-paragraph anchored, | ||||||
674 | // but aligned at page) are introduced. | ||||||
675 | // <SwLayNotify::~SwLayNotify()> takes care of invalidation of lower | ||||||
676 | // floating screen objects by calling method <SwLayoutFrame::NotifyLowerObjs()>. | ||||||
677 | |||||||
678 | if ( pFly->IsFlyAtContentFrame() ) | ||||||
679 | { | ||||||
680 | SwFrame *pNxt = pFly->AnchorFrame()->FindNext(); | ||||||
681 | if ( pNxt ) | ||||||
682 | { | ||||||
683 | pNxt->InvalidatePos(); | ||||||
684 | } | ||||||
685 | } | ||||||
686 | |||||||
687 | // #i26945# - notify anchor. | ||||||
688 | // Needed for negative positioned Writer fly frames | ||||||
689 | if ( pFly->GetAnchorFrame()->IsTextFrame() ) | ||||||
690 | { | ||||||
691 | pFly->AnchorFrame()->Prepare( PrepareHint::FlyFrameLeave ); | ||||||
692 | } | ||||||
693 | } | ||||||
694 | |||||||
695 | // OD 2004-05-13 #i28701# | ||||||
696 | // #i45180# - no adjustment of layout process flags and | ||||||
697 | // further notifications/invalidations, if format is called by grow/shrink | ||||||
698 | if ( !(pFly->ConsiderObjWrapInfluenceOnObjPos() && | ||||||
699 | ( dynamic_cast<const SwFlyFreeFrame*>( pFly) == nullptr || | ||||||
700 | !static_cast<SwFlyFreeFrame*>(pFly)->IsNoMoveOnCheckClip() )) ) | ||||||
701 | return; | ||||||
702 | |||||||
703 | // #i54138# - suppress restart of the layout process | ||||||
704 | // on changed frame height. | ||||||
705 | // Note: It doesn't seem to be necessary and can cause layout loops. | ||||||
706 | if ( bPosChgd ) | ||||||
707 | { | ||||||
708 | // indicate a restart of the layout process | ||||||
709 | pFly->SetRestartLayoutProcess( true ); | ||||||
710 | } | ||||||
711 | else | ||||||
712 | { | ||||||
713 | // lock position | ||||||
714 | pFly->LockPosition(); | ||||||
715 | } | ||||||
716 | |||||||
717 | if ( pFly->ConsiderForTextWrap() ) | ||||||
718 | return; | ||||||
719 | |||||||
720 | // indicate that object has to be considered for text wrap | ||||||
721 | pFly->SetConsiderForTextWrap( true ); | ||||||
722 | // invalidate 'background' in order to allow its 'background' | ||||||
723 | // to wrap around it. | ||||||
724 | pFly->NotifyBackground( pFly->GetPageFrame(), | ||||||
725 | pFly->GetObjRectWithSpaces(), | ||||||
726 | PrepareHint::FlyFrameArrive ); | ||||||
727 | // invalidate position of anchor frame in order to force | ||||||
728 | // a re-format of the anchor frame, which also causes a | ||||||
729 | // re-format of the invalid previous frames of the anchor frame. | ||||||
730 | pFly->AnchorFrame()->InvalidatePos(); | ||||||
731 | } | ||||||
732 | |||||||
733 | SwContentNotify::SwContentNotify( SwContentFrame *pContentFrame ) : | ||||||
734 | SwFrameNotify( pContentFrame ), | ||||||
735 | // OD 08.01.2004 #i11859# | ||||||
736 | mbChkHeightOfLastLine( false ), | ||||||
737 | mnHeightOfLastLine( 0 ), | ||||||
738 | // OD 2004-02-26 #i25029# | ||||||
739 | mbInvalidatePrevPrtArea( false ), | ||||||
740 | mbBordersJoinedWithPrev( false ) | ||||||
741 | { | ||||||
742 | // OD 08.01.2004 #i11859# | ||||||
743 | if ( !pContentFrame->IsTextFrame() ) | ||||||
744 | return; | ||||||
745 | |||||||
746 | SwTextFrame* pTextFrame = static_cast<SwTextFrame*>(pContentFrame); | ||||||
747 | if (!pTextFrame->GetDoc().getIDocumentSettingAccess().get(DocumentSettingId::OLD_LINE_SPACING)) | ||||||
748 | { | ||||||
749 | const SvxLineSpacingItem &rSpace = pTextFrame->GetAttrSet()->GetLineSpacing(); | ||||||
750 | if ( rSpace.GetInterLineSpaceRule() == SvxInterLineSpaceRule::Prop ) | ||||||
751 | { | ||||||
752 | mbChkHeightOfLastLine = true; | ||||||
753 | mnHeightOfLastLine = pTextFrame->GetHeightOfLastLine(); | ||||||
754 | } | ||||||
755 | } | ||||||
756 | } | ||||||
757 | |||||||
758 | SwContentNotify::~SwContentNotify() | ||||||
759 | { | ||||||
760 | SwContentFrame *pCnt = static_cast<SwContentFrame*>(mpFrame); | ||||||
761 | if ( bSetCompletePaintOnInvalidate ) | ||||||
762 | pCnt->SetCompletePaint(); | ||||||
763 | |||||||
764 | SwRectFnSet aRectFnSet(pCnt); | ||||||
765 | if ( pCnt->IsInTab() && ( aRectFnSet.PosDiff( pCnt->getFrameArea(), maFrame ) || | ||||||
766 | pCnt->getFrameArea().SSize() != maFrame.SSize())) | ||||||
767 | { | ||||||
768 | SwLayoutFrame* pCell = pCnt->GetUpper(); | ||||||
769 | while( !pCell->IsCellFrame() && pCell->GetUpper() ) | ||||||
770 | pCell = pCell->GetUpper(); | ||||||
771 | OSL_ENSURE( pCell->IsCellFrame(), "Where's my cell?" )do { if (true && (!(pCell->IsCellFrame()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "771" ": "), "%s", "Where's my cell?"); } } while (false ); | ||||||
772 | if ( text::VertOrientation::NONE != pCell->GetFormat()->GetVertOrient().GetVertOrient() ) | ||||||
773 | pCell->InvalidatePrt(); //for the vertical align. | ||||||
774 | } | ||||||
775 | |||||||
776 | // OD 2004-02-26 #i25029# | ||||||
777 | if ( mbInvalidatePrevPrtArea && mbBordersJoinedWithPrev && | ||||||
778 | pCnt->IsTextFrame() && | ||||||
779 | !pCnt->IsFollow() && !pCnt->GetIndPrev() ) | ||||||
780 | { | ||||||
781 | // determine previous frame | ||||||
782 | SwFrame* pPrevFrame = pCnt->FindPrev(); | ||||||
783 | // skip empty section frames and hidden text frames | ||||||
784 | { | ||||||
785 | while ( pPrevFrame && | ||||||
786 | ( ( pPrevFrame->IsSctFrame() && | ||||||
787 | !static_cast<SwSectionFrame*>(pPrevFrame)->GetSection() ) || | ||||||
788 | ( pPrevFrame->IsTextFrame() && | ||||||
789 | static_cast<SwTextFrame*>(pPrevFrame)->IsHiddenNow() ) ) ) | ||||||
790 | { | ||||||
791 | pPrevFrame = pPrevFrame->FindPrev(); | ||||||
792 | } | ||||||
793 | } | ||||||
794 | |||||||
795 | // Invalidate printing area of found previous frame | ||||||
796 | if ( pPrevFrame ) | ||||||
797 | { | ||||||
798 | if ( pPrevFrame->IsSctFrame() ) | ||||||
799 | { | ||||||
800 | if ( pCnt->IsInSct() ) | ||||||
801 | { | ||||||
802 | // Note: found previous frame is a section frame and | ||||||
803 | // <pCnt> is also inside a section. | ||||||
804 | // Thus due to <mbBordersJoinedWithPrev>, | ||||||
805 | // <pCnt> had joined its borders/shadow with the | ||||||
806 | // last content of the found section. | ||||||
807 | // Invalidate printing area of last content in found section. | ||||||
808 | SwFrame* pLstContentOfSctFrame = | ||||||
809 | static_cast<SwSectionFrame*>(pPrevFrame)->FindLastContent(); | ||||||
810 | if ( pLstContentOfSctFrame ) | ||||||
811 | { | ||||||
812 | pLstContentOfSctFrame->InvalidatePrt(); | ||||||
813 | } | ||||||
814 | } | ||||||
815 | } | ||||||
816 | else | ||||||
817 | { | ||||||
818 | pPrevFrame->InvalidatePrt(); | ||||||
819 | } | ||||||
820 | } | ||||||
821 | } | ||||||
822 | |||||||
823 | const bool bFirst = aRectFnSet.GetWidth(maFrame) == 0; | ||||||
824 | |||||||
825 | if ( pCnt->IsNoTextFrame() ) | ||||||
826 | { | ||||||
827 | //Active PlugIn's or OLE-Objects should know something of the change | ||||||
828 | //thereby they move their window appropriate. | ||||||
829 | SwViewShell *pSh = pCnt->getRootFrame()->GetCurrShell(); | ||||||
830 | if ( pSh ) | ||||||
831 | { | ||||||
832 | SwOLENode *const pNd(static_cast<SwNoTextFrame*>(pCnt)->GetNode()->GetOLENode()); | ||||||
833 | if (nullptr != pNd && | ||||||
834 | (pNd->GetOLEObj().IsOleRef() || | ||||||
835 | pNd->IsOLESizeInvalid()) ) | ||||||
836 | { | ||||||
837 | const bool bNoTextFramePrtAreaChanged = | ||||||
838 | ( maPrt.SSize().Width() != 0 && | ||||||
839 | maPrt.SSize().Height() != 0 ) && | ||||||
840 | maPrt.SSize() != pCnt->getFramePrintArea().SSize(); | ||||||
841 | OSL_ENSURE( pCnt->IsInFly(), "OLE not in FlyFrame" )do { if (true && (!(pCnt->IsInFly()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "841" ": "), "%s", "OLE not in FlyFrame"); } } while (false ); | ||||||
842 | SwFlyFrame *pFly = pCnt->FindFlyFrame(); | ||||||
843 | svt::EmbeddedObjectRef& xObj = pNd->GetOLEObj().GetObject(); | ||||||
844 | SwFEShell *pFESh = nullptr; | ||||||
845 | for(SwViewShell& rCurrentShell : pSh->GetRingContainer()) | ||||||
846 | { if ( dynamic_cast<const SwCursorShell*>( &rCurrentShell) != nullptr ) | ||||||
847 | { | ||||||
848 | pFESh = static_cast<SwFEShell*>(&rCurrentShell); | ||||||
849 | // #108369#: Here used to be the condition if (!bFirst). | ||||||
850 | // I think this should mean "do not call CalcAndSetScale" | ||||||
851 | // if the frame is formatted for the first time. | ||||||
852 | // Unfortunately this is not valid anymore since the | ||||||
853 | // SwNoTextFrame already gets a width during CalcLowerPreps. | ||||||
854 | // Nevertheless, the indention of !bFirst seemed to be | ||||||
855 | // to assure that the OLE objects have already been notified | ||||||
856 | // if necessary before calling CalcAndSetScale. | ||||||
857 | // So I replaced !bFirst by !IsOLESizeInvalid. There is | ||||||
858 | // one additional problem specific to the word import: | ||||||
859 | // The layout is calculated _before_ calling PrtOLENotify, | ||||||
860 | // and the OLE objects are not invalidated during import. | ||||||
861 | // Therefore I added the condition !IsUpdateExpField, | ||||||
862 | // have a look at the occurrence of CalcLayout in | ||||||
863 | // uiview/view.cxx. | ||||||
864 | if ( !pNd->IsOLESizeInvalid() && | ||||||
865 | !pSh->GetDoc()->getIDocumentState().IsUpdateExpField() ) | ||||||
866 | pFESh->CalcAndSetScale( xObj, | ||||||
867 | &pFly->getFramePrintArea(), &pFly->getFrameArea(), | ||||||
868 | bNoTextFramePrtAreaChanged ); | ||||||
869 | } | ||||||
870 | } | ||||||
871 | |||||||
872 | if ( pFESh && pNd->IsOLESizeInvalid() ) | ||||||
873 | { | ||||||
874 | pNd->SetOLESizeInvalid( false ); | ||||||
875 | pFESh->CalcAndSetScale( xObj ); // create client | ||||||
876 | } | ||||||
877 | } | ||||||
878 | // ditto animated graphics | ||||||
879 | if ( getFrameArea().HasArea() && static_cast<SwNoTextFrame*>(pCnt)->HasAnimation() ) | ||||||
880 | { | ||||||
881 | static_cast<SwNoTextFrame*>(pCnt)->StopAnimation(); | ||||||
882 | pSh->InvalidateWindows( getFrameArea() ); | ||||||
883 | } | ||||||
884 | } | ||||||
885 | } | ||||||
886 | |||||||
887 | if ( bFirst ) | ||||||
888 | { | ||||||
889 | pCnt->SetRetouche(); //fix(13870) | ||||||
890 | |||||||
891 | SwDoc& rDoc = pCnt->IsTextFrame() | ||||||
892 | ? static_cast<SwTextFrame*>(pCnt)->GetDoc() | ||||||
893 | : static_cast<SwNoTextFrame*>(pCnt)->GetNode()->GetDoc(); | ||||||
894 | if ( !rDoc.GetSpzFrameFormats()->empty() && | ||||||
895 | rDoc.DoesContainAtPageObjWithContentAnchor() && !rDoc.getIDocumentState().IsNewDoc() ) | ||||||
896 | { | ||||||
897 | // If certain import filters for foreign file format import | ||||||
898 | // AT_PAGE anchored objects, the corresponding page number is | ||||||
899 | // typically not known. In this case the content position is | ||||||
900 | // stored at which the anchored object is found in the | ||||||
901 | // imported document. | ||||||
902 | // When this content is formatted it is the time at which | ||||||
903 | // the page is known. Thus, this data can be corrected now. | ||||||
904 | |||||||
905 | const SwPageFrame *pPage = nullptr; | ||||||
906 | SwFrameFormats *pTable = rDoc.GetSpzFrameFormats(); | ||||||
907 | |||||||
908 | for ( size_t i = 0; i < pTable->size(); ++i ) | ||||||
909 | { | ||||||
910 | SwFrameFormat *pFormat = (*pTable)[i]; | ||||||
911 | const SwFormatAnchor &rAnch = pFormat->GetAnchor(); | ||||||
912 | if ( RndStdIds::FLY_AT_PAGE != rAnch.GetAnchorId() || | ||||||
913 | rAnch.GetContentAnchor() == nullptr ) | ||||||
914 | { | ||||||
915 | continue; | ||||||
916 | } | ||||||
917 | |||||||
918 | if (FrameContainsNode(*pCnt, rAnch.GetContentAnchor()->nNode.GetIndex())) | ||||||
919 | { | ||||||
920 | OSL_FAIL( "<SwContentNotify::~SwContentNotify()> - to page anchored object with content position." )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "920" ": "), "%s", "<SwContentNotify::~SwContentNotify()> - to page anchored object with content position." ); } } while (false); | ||||||
921 | if ( !pPage ) | ||||||
922 | { | ||||||
923 | pPage = pCnt->FindPageFrame(); | ||||||
924 | } | ||||||
925 | SwFormatAnchor aAnch( rAnch ); | ||||||
926 | aAnch.SetAnchor( nullptr ); | ||||||
927 | aAnch.SetPageNum( pPage->GetPhyPageNum() ); | ||||||
928 | pFormat->SetFormatAttr( aAnch ); | ||||||
929 | if ( RES_DRAWFRMFMT != pFormat->Which() ) | ||||||
930 | { | ||||||
931 | pFormat->MakeFrames(); | ||||||
932 | } | ||||||
933 | } | ||||||
934 | } | ||||||
935 | } | ||||||
936 | } | ||||||
937 | |||||||
938 | // OD 12.01.2004 #i11859# - invalidate printing area of following frame, | ||||||
939 | // if height of last line has changed. | ||||||
940 | if ( pCnt->IsTextFrame() && mbChkHeightOfLastLine ) | ||||||
941 | { | ||||||
942 | if ( mnHeightOfLastLine != static_cast<SwTextFrame*>(pCnt)->GetHeightOfLastLine() ) | ||||||
943 | { | ||||||
944 | pCnt->InvalidateNextPrtArea(); | ||||||
945 | } | ||||||
946 | } | ||||||
947 | |||||||
948 | // #i44049# | ||||||
949 | if ( pCnt->IsTextFrame() && aRectFnSet.PosDiff( maFrame, pCnt->getFrameArea() ) ) | ||||||
950 | { | ||||||
951 | pCnt->InvalidateObjs(); | ||||||
952 | } | ||||||
953 | |||||||
954 | // #i43255# - move code to invalidate at-character | ||||||
955 | // anchored objects due to a change of its anchor character from | ||||||
956 | // method <SwTextFrame::Format(..)>. | ||||||
957 | if ( !pCnt->IsTextFrame() ) | ||||||
958 | return; | ||||||
959 | |||||||
960 | SwTextFrame* pMasterFrame = pCnt->IsFollow() | ||||||
961 | ? static_cast<SwTextFrame*>(pCnt)->FindMaster() | ||||||
962 | : static_cast<SwTextFrame*>(pCnt); | ||||||
963 | if ( pMasterFrame && !pMasterFrame->IsFlyLock() && | ||||||
964 | pMasterFrame->GetDrawObjs() ) | ||||||
965 | { | ||||||
966 | SwSortedObjs* pObjs = pMasterFrame->GetDrawObjs(); | ||||||
967 | for (SwAnchoredObject* pAnchoredObj : *pObjs) | ||||||
968 | { | ||||||
969 | if ( pAnchoredObj->GetFrameFormat().GetAnchor().GetAnchorId() | ||||||
970 | == RndStdIds::FLY_AT_CHAR ) | ||||||
971 | { | ||||||
972 | pAnchoredObj->CheckCharRectAndTopOfLine( !pMasterFrame->IsEmpty() ); | ||||||
973 | } | ||||||
974 | } | ||||||
975 | } | ||||||
976 | } | ||||||
977 | |||||||
978 | // note this *cannot* be static because it's a friend | ||||||
979 | void AppendObj(SwFrame *const pFrame, SwPageFrame *const pPage, SwFrameFormat *const pFormat, const SwFormatAnchor & rAnch) | ||||||
980 | { | ||||||
981 | const bool bFlyAtFly = rAnch.GetAnchorId() == RndStdIds::FLY_AT_FLY; // LAYER_IMPL | ||||||
982 | //Is a frame or a SdrObject described? | ||||||
983 | const bool bSdrObj = RES_DRAWFRMFMT == pFormat->Which(); | ||||||
984 | // OD 23.06.2003 #108784# - append also drawing objects anchored | ||||||
985 | // as character. | ||||||
986 | const bool bDrawObjInContent = bSdrObj && | ||||||
987 | (rAnch.GetAnchorId() == RndStdIds::FLY_AS_CHAR); | ||||||
988 | |||||||
989 | if( !(bFlyAtFly || | ||||||
990 | (rAnch.GetAnchorId() == RndStdIds::FLY_AT_PARA) || | ||||||
991 | (rAnch.GetAnchorId() == RndStdIds::FLY_AT_CHAR) || | ||||||
992 | bDrawObjInContent) ) | ||||||
993 | return; | ||||||
994 | |||||||
995 | SdrObject* pSdrObj = nullptr; | ||||||
996 | if ( bSdrObj && nullptr == (pSdrObj = pFormat->FindSdrObject()) ) | ||||||
997 | { | ||||||
998 | OSL_ENSURE( !bSdrObj, "DrawObject not found." )do { if (true && (!(!bSdrObj))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "998" ": "), "%s", "DrawObject not found."); } } while ( false); | ||||||
999 | pFormat->GetDoc()->DelFrameFormat( pFormat ); | ||||||
1000 | return; | ||||||
1001 | } | ||||||
1002 | if ( pSdrObj ) | ||||||
1003 | { | ||||||
1004 | if ( !pSdrObj->getSdrPageFromSdrObject() ) | ||||||
1005 | { | ||||||
1006 | pFormat->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0)-> | ||||||
1007 | InsertObject(pSdrObj, pSdrObj->GetOrdNumDirect()); | ||||||
1008 | } | ||||||
1009 | |||||||
1010 | SwDrawContact* pNew = | ||||||
1011 | static_cast<SwDrawContact*>(GetUserCall( pSdrObj )); | ||||||
1012 | if ( !pNew->GetAnchorFrame() ) | ||||||
1013 | { | ||||||
1014 | pFrame->AppendDrawObj( *(pNew->GetAnchoredObj( nullptr )) ); | ||||||
1015 | } | ||||||
1016 | // OD 19.06.2003 #108784# - add 'virtual' drawing object, | ||||||
1017 | // if necessary. But control objects have to be excluded. | ||||||
1018 | else if ( !::CheckControlLayer( pSdrObj ) && | ||||||
1019 | pNew->GetAnchorFrame() != pFrame && | ||||||
1020 | !pNew->GetDrawObjectByAnchorFrame( *pFrame ) ) | ||||||
1021 | { | ||||||
1022 | SwDrawVirtObj* pDrawVirtObj = pNew->AddVirtObj(); | ||||||
1023 | pFrame->AppendDrawObj( *(pNew->GetAnchoredObj( pDrawVirtObj )) ); | ||||||
1024 | |||||||
1025 | pDrawVirtObj->ActionChanged(); | ||||||
1026 | } | ||||||
1027 | } | ||||||
1028 | else | ||||||
1029 | { | ||||||
1030 | SwFlyFrame *pFly; | ||||||
1031 | if( bFlyAtFly ) | ||||||
1032 | pFly = new SwFlyLayFrame( static_cast<SwFlyFrameFormat*>(pFormat), pFrame, pFrame ); | ||||||
1033 | else | ||||||
1034 | pFly = new SwFlyAtContentFrame( static_cast<SwFlyFrameFormat*>(pFormat), pFrame, pFrame ); | ||||||
1035 | pFly->Lock(); | ||||||
1036 | pFrame->AppendFly( pFly ); | ||||||
1037 | pFly->Unlock(); | ||||||
1038 | if ( pPage ) | ||||||
1039 | ::RegistFlys( pPage, pFly ); | ||||||
1040 | } | ||||||
1041 | } | ||||||
1042 | |||||||
1043 | static bool IsShown(sal_uLong const nIndex, | ||||||
1044 | const SwFormatAnchor & rAnch, | ||||||
1045 | std::vector<sw::Extent>::const_iterator const*const pIter, | ||||||
1046 | std::vector<sw::Extent>::const_iterator const*const pEnd, | ||||||
1047 | SwTextNode const*const pFirstNode, SwTextNode const*const pLastNode) | ||||||
1048 | { | ||||||
1049 | assert(!pIter || *pIter == *pEnd || (*pIter)->pNode->GetIndex() == nIndex)(static_cast <bool> (!pIter || *pIter == *pEnd || (*pIter )->pNode->GetIndex() == nIndex) ? void (0) : __assert_fail ("!pIter || *pIter == *pEnd || (*pIter)->pNode->GetIndex() == nIndex" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1049, __extension__ __PRETTY_FUNCTION__)); | ||||||
1050 | SwPosition const& rAnchor(*rAnch.GetContentAnchor()); | ||||||
1051 | if (rAnchor.nNode.GetIndex() != nIndex) | ||||||
1052 | { | ||||||
1053 | return false; | ||||||
1054 | } | ||||||
1055 | if (rAnch.GetAnchorId() == RndStdIds::FLY_AT_PARA) | ||||||
1056 | { | ||||||
1057 | return pIter == nullptr // not merged | ||||||
1058 | || pIter != pEnd // at least one char visible in node | ||||||
1059 | || !IsSelectFrameAnchoredAtPara(rAnchor, | ||||||
1060 | SwPosition(const_cast<SwTextNode&>(*pFirstNode), 0), | ||||||
1061 | SwPosition(const_cast<SwTextNode&>(*pLastNode), pLastNode->Len())); | ||||||
1062 | } | ||||||
1063 | if (pIter) | ||||||
1064 | { | ||||||
1065 | // note: frames are not sorted by anchor position. | ||||||
1066 | assert(pEnd)(static_cast <bool> (pEnd) ? void (0) : __assert_fail ( "pEnd", "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1066, __extension__ __PRETTY_FUNCTION__)); | ||||||
1067 | assert(pFirstNode)(static_cast <bool> (pFirstNode) ? void (0) : __assert_fail ("pFirstNode", "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1067, __extension__ __PRETTY_FUNCTION__)); | ||||||
1068 | assert(pLastNode)(static_cast <bool> (pLastNode) ? void (0) : __assert_fail ("pLastNode", "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1068, __extension__ __PRETTY_FUNCTION__)); | ||||||
1069 | assert(rAnch.GetAnchorId() != RndStdIds::FLY_AT_FLY)(static_cast <bool> (rAnch.GetAnchorId() != RndStdIds:: FLY_AT_FLY) ? void (0) : __assert_fail ("rAnch.GetAnchorId() != RndStdIds::FLY_AT_FLY" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1069, __extension__ __PRETTY_FUNCTION__)); | ||||||
1070 | for (auto iter = *pIter; iter != *pEnd; ++iter) | ||||||
1071 | { | ||||||
1072 | assert(iter->nStart != iter->nEnd)(static_cast <bool> (iter->nStart != iter->nEnd) ? void (0) : __assert_fail ("iter->nStart != iter->nEnd" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1072, __extension__ __PRETTY_FUNCTION__)); // TODO possible? | ||||||
1073 | assert(iter->pNode->GetIndex() == nIndex)(static_cast <bool> (iter->pNode->GetIndex() == nIndex ) ? void (0) : __assert_fail ("iter->pNode->GetIndex() == nIndex" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1073, __extension__ __PRETTY_FUNCTION__)); | ||||||
1074 | if (rAnchor.nContent.GetIndex() < iter->nStart) | ||||||
1075 | { | ||||||
1076 | return false; | ||||||
1077 | } | ||||||
1078 | if (rAnch.GetAnchorId() == RndStdIds::FLY_AT_CHAR) | ||||||
1079 | { | ||||||
1080 | // if there is an extent then obviously the node was not | ||||||
1081 | // deleted fully... | ||||||
1082 | // show if start <= pos <= end | ||||||
1083 | // *or* if first-node/0 *and* not StartOfSection | ||||||
1084 | // *or* if last-node/Len *and* not EndOfSection | ||||||
1085 | |||||||
1086 | // first determine the extent to compare to, then | ||||||
1087 | // construct start/end positions for the deletion *before* the | ||||||
1088 | // extent and compare once. | ||||||
1089 | // the interesting corner cases are on the edge of the extent! | ||||||
1090 | // no need to check for > the last extent because those | ||||||
1091 | // are never visible. | ||||||
1092 | if (rAnchor.nContent.GetIndex() <= iter->nEnd) | ||||||
1093 | { | ||||||
1094 | if (iter->nStart == 0) | ||||||
1095 | { | ||||||
1096 | return true; | ||||||
1097 | } | ||||||
1098 | else | ||||||
1099 | { | ||||||
1100 | SwPosition const start( | ||||||
1101 | const_cast<SwTextNode&>( | ||||||
1102 | iter == *pIter | ||||||
1103 | ? *pFirstNode // simplification | ||||||
1104 | : *iter->pNode), | ||||||
1105 | iter == *pIter // first extent? | ||||||
1106 | ? iter->pNode == pFirstNode | ||||||
1107 | ? 0 // at start of 1st node | ||||||
1108 | : pFirstNode->Len() // previous node; simplification but should get right result | ||||||
1109 | : (iter-1)->nEnd); // previous extent | ||||||
1110 | SwPosition const end(*iter->pNode, iter->nStart); | ||||||
1111 | return !IsDestroyFrameAnchoredAtChar(rAnchor, start, end); | ||||||
1112 | } | ||||||
1113 | } | ||||||
1114 | else if (iter == *pEnd - 1) // special case: after last extent | ||||||
1115 | { | ||||||
1116 | if (iter->nEnd == iter->pNode->Len()) | ||||||
1117 | { | ||||||
1118 | return true; // special case: end of node | ||||||
1119 | } | ||||||
1120 | else | ||||||
1121 | { | ||||||
1122 | SwPosition const start(*iter->pNode, iter->nEnd); | ||||||
1123 | SwPosition const end( | ||||||
1124 | const_cast<SwTextNode&>(*pLastNode), // simplification | ||||||
1125 | iter->pNode == pLastNode | ||||||
1126 | ? iter->pNode->Len() | ||||||
1127 | : 0); | ||||||
1128 | return !IsDestroyFrameAnchoredAtChar(rAnchor, start, end); | ||||||
1129 | } | ||||||
1130 | } | ||||||
1131 | } | ||||||
1132 | else | ||||||
1133 | { | ||||||
1134 | assert(rAnch.GetAnchorId() == RndStdIds::FLY_AS_CHAR)(static_cast <bool> (rAnch.GetAnchorId() == RndStdIds:: FLY_AS_CHAR) ? void (0) : __assert_fail ("rAnch.GetAnchorId() == RndStdIds::FLY_AS_CHAR" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1134, __extension__ __PRETTY_FUNCTION__)); | ||||||
1135 | // for AS_CHAR obviously must be < | ||||||
1136 | if (rAnchor.nContent.GetIndex() < iter->nEnd) | ||||||
1137 | { | ||||||
1138 | return true; | ||||||
1139 | } | ||||||
1140 | } | ||||||
1141 | } | ||||||
1142 | return false; | ||||||
1143 | } | ||||||
1144 | else | ||||||
1145 | { | ||||||
1146 | return true; | ||||||
1147 | } | ||||||
1148 | } | ||||||
1149 | |||||||
1150 | void RemoveHiddenObjsOfNode(SwTextNode const& rNode, | ||||||
1151 | std::vector<sw::Extent>::const_iterator const*const pIter, | ||||||
1152 | std::vector<sw::Extent>::const_iterator const*const pEnd, | ||||||
1153 | SwTextNode const*const pFirstNode, SwTextNode const*const pLastNode) | ||||||
1154 | { | ||||||
1155 | std::vector<SwFrameFormat*> const*const pFlys(rNode.GetAnchoredFlys()); | ||||||
1156 | if (!pFlys) | ||||||
1157 | { | ||||||
1158 | return; | ||||||
1159 | } | ||||||
1160 | for (SwFrameFormat * pFrameFormat : *pFlys) | ||||||
1161 | { | ||||||
1162 | SwFormatAnchor const& rAnchor = pFrameFormat->GetAnchor(); | ||||||
1163 | if (rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR | ||||||
1164 | || (rAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR | ||||||
1165 | && RES_DRAWFRMFMT == pFrameFormat->Which())) | ||||||
1166 | { | ||||||
1167 | assert(rAnchor.GetContentAnchor()->nNode.GetIndex() == rNode.GetIndex())(static_cast <bool> (rAnchor.GetContentAnchor()->nNode .GetIndex() == rNode.GetIndex()) ? void (0) : __assert_fail ( "rAnchor.GetContentAnchor()->nNode.GetIndex() == rNode.GetIndex()" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1167, __extension__ __PRETTY_FUNCTION__)); | ||||||
1168 | if (!IsShown(rNode.GetIndex(), rAnchor, pIter, pEnd, pFirstNode, pLastNode)) | ||||||
1169 | { | ||||||
1170 | pFrameFormat->DelFrames(); | ||||||
1171 | } | ||||||
1172 | } | ||||||
1173 | } | ||||||
1174 | } | ||||||
1175 | |||||||
1176 | void AppendObjsOfNode(SwFrameFormats const*const pTable, sal_uLong const nIndex, | ||||||
1177 | SwFrame *const pFrame, SwPageFrame *const pPage, SwDoc *const pDoc, | ||||||
1178 | std::vector<sw::Extent>::const_iterator const*const pIter, | ||||||
1179 | std::vector<sw::Extent>::const_iterator const*const pEnd, | ||||||
1180 | SwTextNode const*const pFirstNode, SwTextNode const*const pLastNode) | ||||||
1181 | { | ||||||
1182 | #if OSL_DEBUG_LEVEL1 > 0 | ||||||
1183 | std::vector<SwFrameFormat*> checkFormats; | ||||||
1184 | for ( size_t i = 0; i < pTable->size(); ++i ) | ||||||
1185 | { | ||||||
1186 | SwFrameFormat *pFormat = (*pTable)[i]; | ||||||
1187 | const SwFormatAnchor &rAnch = pFormat->GetAnchor(); | ||||||
1188 | if ( rAnch.GetContentAnchor() && | ||||||
1189 | IsShown(nIndex, rAnch, pIter, pEnd, pFirstNode, pLastNode)) | ||||||
1190 | { | ||||||
1191 | checkFormats.push_back( pFormat ); | ||||||
1192 | } | ||||||
1193 | } | ||||||
1194 | #else | ||||||
1195 | (void)pTable; | ||||||
1196 | #endif | ||||||
1197 | |||||||
1198 | SwNode const& rNode(*pDoc->GetNodes()[nIndex]); | ||||||
1199 | std::vector<SwFrameFormat*> const*const pFlys(rNode.GetAnchoredFlys()); | ||||||
1200 | for (size_t it = 0; pFlys && it != pFlys->size(); ) | ||||||
1201 | { | ||||||
1202 | SwFrameFormat *const pFormat = (*pFlys)[it]; | ||||||
1203 | const SwFormatAnchor &rAnch = pFormat->GetAnchor(); | ||||||
1204 | if ( rAnch.GetContentAnchor() && | ||||||
1205 | IsShown(nIndex, rAnch, pIter, pEnd, pFirstNode, pLastNode)) | ||||||
1206 | { | ||||||
1207 | #if OSL_DEBUG_LEVEL1 > 0 | ||||||
1208 | std::vector<SwFrameFormat*>::iterator checkPos = std::find( checkFormats.begin(), checkFormats.end(), pFormat ); | ||||||
1209 | assert( checkPos != checkFormats.end())(static_cast <bool> (checkPos != checkFormats.end()) ? void (0) : __assert_fail ("checkPos != checkFormats.end()", "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1209, __extension__ __PRETTY_FUNCTION__)); | ||||||
1210 | checkFormats.erase( checkPos ); | ||||||
1211 | #endif | ||||||
1212 | AppendObj(pFrame, pPage, pFormat, rAnch); | ||||||
1213 | } | ||||||
1214 | ++it; | ||||||
1215 | } | ||||||
1216 | |||||||
1217 | #if OSL_DEBUG_LEVEL1 > 0 | ||||||
1218 | assert( checkFormats.empty())(static_cast <bool> (checkFormats.empty()) ? void (0) : __assert_fail ("checkFormats.empty()", "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1218, __extension__ __PRETTY_FUNCTION__)); | ||||||
1219 | #endif | ||||||
1220 | } | ||||||
1221 | |||||||
1222 | |||||||
1223 | void AppendObjs(const SwFrameFormats *const pTable, sal_uLong const nIndex, | ||||||
1224 | SwFrame *const pFrame, SwPageFrame *const pPage, SwDoc *const pDoc) | ||||||
1225 | { | ||||||
1226 | if (pFrame->IsTextFrame()) | ||||||
1227 | { | ||||||
1228 | SwTextFrame const*const pTextFrame(static_cast<SwTextFrame const*>(pFrame)); | ||||||
1229 | if (sw::MergedPara const*const pMerged = pTextFrame->GetMergedPara()) | ||||||
1230 | { | ||||||
1231 | std::vector<sw::Extent>::const_iterator iterFirst(pMerged->extents.begin()); | ||||||
1232 | std::vector<sw::Extent>::const_iterator iter(iterFirst); | ||||||
1233 | SwTextNode const* pNode(pMerged->pFirstNode); | ||||||
1234 | for ( ; ; ++iter) | ||||||
1235 | { | ||||||
1236 | if (iter == pMerged->extents.end() | ||||||
1237 | || iter->pNode != pNode) | ||||||
1238 | { | ||||||
1239 | AppendObjsOfNode(pTable, pNode->GetIndex(), pFrame, pPage, pDoc, | ||||||
1240 | &iterFirst, &iter, pMerged->pFirstNode, pMerged->pLastNode); | ||||||
1241 | sal_uLong const until = iter == pMerged->extents.end() | ||||||
1242 | ? pMerged->pLastNode->GetIndex() + 1 | ||||||
1243 | : iter->pNode->GetIndex(); | ||||||
1244 | for (sal_uLong i = pNode->GetIndex() + 1; i < until; ++i) | ||||||
1245 | { | ||||||
1246 | // let's show at-para flys on nodes that contain start/end of | ||||||
1247 | // redline too, even if there's no text there | ||||||
1248 | SwNode const*const pTmp(pNode->GetNodes()[i]); | ||||||
1249 | if (pTmp->GetRedlineMergeFlag() == SwNode::Merge::NonFirst) | ||||||
1250 | { | ||||||
1251 | AppendObjsOfNode(pTable, pTmp->GetIndex(), pFrame, pPage, pDoc, &iter, &iter, pMerged->pFirstNode, pMerged->pLastNode); | ||||||
1252 | } | ||||||
1253 | } | ||||||
1254 | if (iter == pMerged->extents.end()) | ||||||
1255 | { | ||||||
1256 | break; | ||||||
1257 | } | ||||||
1258 | pNode = iter->pNode; | ||||||
1259 | iterFirst = iter; | ||||||
1260 | } | ||||||
1261 | } | ||||||
1262 | } | ||||||
1263 | else | ||||||
1264 | { | ||||||
1265 | return AppendObjsOfNode(pTable, nIndex, pFrame, pPage, pDoc, nullptr, nullptr, nullptr, nullptr); | ||||||
1266 | } | ||||||
1267 | } | ||||||
1268 | else | ||||||
1269 | { | ||||||
1270 | return AppendObjsOfNode(pTable, nIndex, pFrame, pPage, pDoc, nullptr, nullptr, nullptr, nullptr); | ||||||
1271 | } | ||||||
1272 | } | ||||||
1273 | |||||||
1274 | bool IsAnchoredObjShown(SwTextFrame const& rFrame, SwFormatAnchor const& rAnchor) | ||||||
1275 | { | ||||||
1276 | assert(rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA ||(static_cast <bool> (rAnchor.GetAnchorId() == RndStdIds ::FLY_AT_PARA || rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR || rAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR) ? void ( 0) : __assert_fail ("rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA || rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR || rAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1278, __extension__ __PRETTY_FUNCTION__)) | ||||||
1277 | rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR ||(static_cast <bool> (rAnchor.GetAnchorId() == RndStdIds ::FLY_AT_PARA || rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR || rAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR) ? void ( 0) : __assert_fail ("rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA || rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR || rAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1278, __extension__ __PRETTY_FUNCTION__)) | ||||||
1278 | rAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR)(static_cast <bool> (rAnchor.GetAnchorId() == RndStdIds ::FLY_AT_PARA || rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR || rAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR) ? void ( 0) : __assert_fail ("rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA || rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR || rAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1278, __extension__ __PRETTY_FUNCTION__)); | ||||||
1279 | bool ret(true); | ||||||
1280 | if (auto const pMergedPara = rFrame.GetMergedPara()) | ||||||
1281 | { | ||||||
1282 | ret = false; | ||||||
1283 | auto const pAnchor(rAnchor.GetContentAnchor()); | ||||||
1284 | auto iterFirst(pMergedPara->extents.cbegin()); | ||||||
1285 | if (iterFirst == pMergedPara->extents.end() | ||||||
1286 | && (rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA | ||||||
1287 | || rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR)) | ||||||
1288 | { | ||||||
1289 | ret = (&pAnchor->nNode.GetNode() == pMergedPara->pFirstNode | ||||||
1290 | && (rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA | ||||||
1291 | || pAnchor->nContent == 0)) | ||||||
1292 | || (&pAnchor->nNode.GetNode() == pMergedPara->pLastNode | ||||||
1293 | && (rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA | ||||||
1294 | || pAnchor->nContent == pMergedPara->pLastNode->Len())); | ||||||
1295 | } | ||||||
1296 | auto iter(iterFirst); | ||||||
1297 | SwTextNode const* pNode(pMergedPara->pFirstNode); | ||||||
1298 | for ( ; ; ++iter) | ||||||
1299 | { | ||||||
1300 | if (iter == pMergedPara->extents.end() | ||||||
1301 | || iter->pNode != pNode) | ||||||
1302 | { | ||||||
1303 | assert(pNode->GetRedlineMergeFlag() != SwNode::Merge::Hidden)(static_cast <bool> (pNode->GetRedlineMergeFlag() != SwNode::Merge::Hidden) ? void (0) : __assert_fail ("pNode->GetRedlineMergeFlag() != SwNode::Merge::Hidden" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1303, __extension__ __PRETTY_FUNCTION__)); | ||||||
1304 | if (pNode == &pAnchor->nNode.GetNode()) | ||||||
1305 | { | ||||||
1306 | ret = IsShown(pNode->GetIndex(), rAnchor, &iterFirst, &iter, | ||||||
1307 | pMergedPara->pFirstNode, pMergedPara->pLastNode); | ||||||
1308 | break; | ||||||
1309 | } | ||||||
1310 | if (iter == pMergedPara->extents.end()) | ||||||
1311 | { | ||||||
1312 | break; | ||||||
1313 | } | ||||||
1314 | pNode = iter->pNode; | ||||||
1315 | if (pAnchor->nNode.GetIndex() < pNode->GetIndex()) | ||||||
1316 | { | ||||||
1317 | break; | ||||||
1318 | } | ||||||
1319 | iterFirst = iter; | ||||||
1320 | } | ||||||
1321 | } | ||||||
1322 | } | ||||||
1323 | return ret; | ||||||
1324 | } | ||||||
1325 | |||||||
1326 | void AppendAllObjs(const SwFrameFormats* pTable, const SwFrame* pSib) | ||||||
1327 | { | ||||||
1328 | //Connecting of all Objects, which are described in the SpzTable with the | ||||||
1329 | //layout. | ||||||
1330 | |||||||
1331 | boost::circular_buffer<SwFrameFormat*> vFormatsToConnect(pTable->size()); | ||||||
1332 | for(const auto& pFormat : *pTable) | ||||||
1333 | { | ||||||
1334 | const auto& rAnch = pFormat->GetAnchor(); | ||||||
1335 | // Formats can still remain, because we neither use character bound | ||||||
1336 | // frames nor objects which are anchored to character bounds. | ||||||
1337 | if ((rAnch.GetAnchorId() != RndStdIds::FLY_AT_PAGE) && (rAnch.GetAnchorId() != RndStdIds::FLY_AS_CHAR)) | ||||||
1338 | { | ||||||
1339 | auto pContentAnchor = rAnch.GetContentAnchor(); | ||||||
1340 | // formats in header/footer have no dependencies | ||||||
1341 | if(pContentAnchor && pFormat->GetDoc()->IsInHeaderFooter(pContentAnchor->nNode)) | ||||||
1342 | pFormat->MakeFrames(); | ||||||
1343 | else | ||||||
1344 | vFormatsToConnect.push_back(pFormat); | ||||||
1345 | } | ||||||
1346 | } | ||||||
1347 | const SwRootFrame* pRoot = pSib ? pSib->getRootFrame() : nullptr; | ||||||
1348 | const SwFrameFormat* pFirstRequeued(nullptr); | ||||||
1349 | while(!vFormatsToConnect.empty()) | ||||||
1350 | { | ||||||
1351 | auto& pFormat = vFormatsToConnect.front(); | ||||||
1352 | bool isConnected(false); | ||||||
1353 | pFormat->CallSwClientNotify(sw::GetObjectConnectedHint(isConnected, pRoot)); | ||||||
1354 | if(!isConnected) | ||||||
1355 | { | ||||||
1356 | pFormat->MakeFrames(); | ||||||
1357 | pFormat->CallSwClientNotify(sw::GetObjectConnectedHint(isConnected, pRoot)); | ||||||
1358 | } | ||||||
1359 | // do this *before* push_back! the circular_buffer can be "full"! | ||||||
1360 | vFormatsToConnect.pop_front(); | ||||||
1361 | if (!isConnected) | ||||||
1362 | { | ||||||
1363 | if(pFirstRequeued == pFormat) | ||||||
1364 | // If nothing happens anymore we can stop. | ||||||
1365 | break; | ||||||
1366 | if(!pFirstRequeued) | ||||||
1367 | pFirstRequeued = pFormat; | ||||||
1368 | assert(!vFormatsToConnect.full())(static_cast <bool> (!vFormatsToConnect.full()) ? void ( 0) : __assert_fail ("!vFormatsToConnect.full()", "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1368, __extension__ __PRETTY_FUNCTION__)); | ||||||
1369 | vFormatsToConnect.push_back(pFormat); | ||||||
1370 | } | ||||||
1371 | else | ||||||
1372 | { | ||||||
1373 | pFirstRequeued = nullptr; | ||||||
1374 | } | ||||||
1375 | } | ||||||
1376 | } | ||||||
1377 | |||||||
1378 | namespace sw { | ||||||
1379 | |||||||
1380 | void RecreateStartTextFrames(SwTextNode & rNode) | ||||||
1381 | { | ||||||
1382 | std::vector<SwTextFrame*> frames; | ||||||
1383 | SwIterator<SwTextFrame, SwTextNode, sw::IteratorMode::UnwrapMulti> aIter(rNode); | ||||||
1384 | for (SwTextFrame* pFrame = aIter.First(); pFrame; pFrame = aIter.Next()) | ||||||
1385 | { | ||||||
1386 | if (pFrame->getRootFrame()->IsHideRedlines()) | ||||||
1387 | { | ||||||
1388 | frames.push_back(pFrame); | ||||||
1389 | } | ||||||
1390 | } | ||||||
1391 | auto eMode(sw::FrameMode::Existing); | ||||||
1392 | for (SwTextFrame * pFrame : frames) | ||||||
1393 | { | ||||||
1394 | // SplitNode could have moved the original frame to the start node | ||||||
1395 | // & created a new one on end, or could have created new frame on | ||||||
1396 | // start node... grab start node's frame and recreate MergedPara. | ||||||
1397 | SwTextNode & rFirstNode(pFrame->GetMergedPara() | ||||||
1398 | ? *pFrame->GetMergedPara()->pFirstNode | ||||||
1399 | : rNode); | ||||||
1400 | assert(rFirstNode.GetIndex() <= rNode.GetIndex())(static_cast <bool> (rFirstNode.GetIndex() <= rNode. GetIndex()) ? void (0) : __assert_fail ("rFirstNode.GetIndex() <= rNode.GetIndex()" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1400, __extension__ __PRETTY_FUNCTION__)); | ||||||
1401 | // clear old one first to avoid DelFrames confusing updates & asserts... | ||||||
1402 | pFrame->SetMergedPara(nullptr); | ||||||
1403 | pFrame->SetMergedPara(sw::CheckParaRedlineMerge( | ||||||
1404 | *pFrame, rFirstNode, eMode)); | ||||||
1405 | eMode = sw::FrameMode::New; // Existing is not idempotent! | ||||||
1406 | // note: this may or may not delete frames on the end node | ||||||
1407 | } | ||||||
1408 | } | ||||||
1409 | |||||||
1410 | } // namespace sw | ||||||
1411 | |||||||
1412 | /** local method to set 'working' position for newly inserted frames | ||||||
1413 | |||||||
1414 | OD 12.08.2003 #i17969# | ||||||
1415 | */ | ||||||
1416 | static void lcl_SetPos( SwFrame& _rNewFrame, | ||||||
1417 | const SwLayoutFrame& _rLayFrame ) | ||||||
1418 | { | ||||||
1419 | SwRectFnSet aRectFnSet(&_rLayFrame); | ||||||
1420 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(_rNewFrame); | ||||||
1421 | aRectFnSet.SetPos( aFrm, aRectFnSet.GetPos(_rLayFrame.getFrameArea()) ); | ||||||
1422 | |||||||
1423 | // move position by one SwTwip in text flow direction in order to get | ||||||
1424 | // notifications for a new calculated position after its formatting. | ||||||
1425 | if ( aRectFnSet.IsVert() ) | ||||||
1426 | { | ||||||
1427 | aFrm.Pos().AdjustX( -1 ); | ||||||
1428 | } | ||||||
1429 | else | ||||||
1430 | { | ||||||
1431 | aFrm.Pos().AdjustY(1 ); | ||||||
1432 | } | ||||||
1433 | } | ||||||
1434 | |||||||
1435 | void InsertCnt_( SwLayoutFrame *pLay, SwDoc *pDoc, | ||||||
1436 | sal_uLong nIndex, bool bPages, sal_uLong nEndIndex, | ||||||
1437 | SwFrame *pPrv, sw::FrameMode const eMode ) | ||||||
1438 | { | ||||||
1439 | pDoc->getIDocumentTimerAccess().BlockIdling(); | ||||||
1440 | SwRootFrame* pLayout = pLay->getRootFrame(); | ||||||
| |||||||
1441 | const bool bOldCallbackActionEnabled = pLayout && pLayout->IsCallbackActionEnabled(); | ||||||
1442 | if( bOldCallbackActionEnabled
| ||||||
1443 | pLayout->SetCallbackActionEnabled( false ); | ||||||
1444 | |||||||
1445 | //In the generation of the Layout bPages=true will be handed over. | ||||||
1446 | //Then will be new pages generated all x paragraphs already times in advance. | ||||||
1447 | //On breaks and/or pagedescriptorchanges the corresponding will be generated | ||||||
1448 | //immediately. | ||||||
1449 | //The advantage is, that on one hand already a nearly realistic number of | ||||||
1450 | //pages are created, but above all there are no almost endless long chain | ||||||
1451 | //of paragraphs, which must be moved expensively until it reaches a tolerable | ||||||
1452 | //reduced level. | ||||||
1453 | //We'd like to think that 20 Paragraphs fit on one page. | ||||||
1454 | //So that it does not become in extreme situations so violent we calculate depending | ||||||
1455 | //on the node something to it. | ||||||
1456 | //If in the DocStatistic a usable given pagenumber | ||||||
1457 | //(Will be cared for while writing), so it will be presumed that this will be | ||||||
1458 | //number of pages. | ||||||
1459 | const bool bStartPercent = bPages && !nEndIndex; | ||||||
1460 | |||||||
1461 | SwPageFrame *pPage = pLay->FindPageFrame(); | ||||||
1462 | const SwFrameFormats *pTable = pDoc->GetSpzFrameFormats(); | ||||||
1463 | SwFrame *pFrame = nullptr; | ||||||
1464 | std::unique_ptr<SwActualSection> pActualSection; | ||||||
1465 | std::unique_ptr<SwLayHelper> pPageMaker; | ||||||
1466 | |||||||
1467 | //If the layout will be created (bPages == true) we do head on the progress | ||||||
1468 | //Flys and DrawObjects are not connected immediately, this | ||||||
1469 | //happens only at the end of the function. | ||||||
1470 | if ( bPages
| ||||||
1471 | { | ||||||
1472 | // Attention: the SwLayHelper class uses references to the content-, | ||||||
1473 | // page-, layout-frame etc. and may change them! | ||||||
1474 | pPageMaker.reset(new SwLayHelper( pDoc, pFrame, pPrv, pPage, pLay, | ||||||
1475 | pActualSection, nIndex, 0 == nEndIndex )); | ||||||
1476 | if( bStartPercent ) | ||||||
1477 | { | ||||||
1478 | const sal_uLong nPageCount = pPageMaker->CalcPageCount(); | ||||||
1479 | if( nPageCount ) | ||||||
1480 | bObjsDirect = false; | ||||||
1481 | } | ||||||
1482 | } | ||||||
1483 | else | ||||||
1484 | pPageMaker = nullptr; | ||||||
1485 | |||||||
1486 | if( pLay->IsInSct() && | ||||||
1487 | ( pLay->IsSctFrame() || pLay->GetUpper() ) ) // Hereby will newbies | ||||||
1488 | // be intercepted, of which flags could not determined yet, | ||||||
1489 | // for e.g. while inserting a table | ||||||
1490 | { | ||||||
1491 | SwSectionFrame* pSct = pLay->FindSctFrame(); | ||||||
1492 | // If content will be inserted in a footnote, which in a column area, | ||||||
1493 | // the column area it is not allowed to be broken up. | ||||||
1494 | // Only if in the inner of the footnote lies an area, is this a candidate | ||||||
1495 | // for pActualSection. | ||||||
1496 | // The same applies for areas in tables, if inside the table will be | ||||||
1497 | // something inserted, it's only allowed to break up areas, which | ||||||
1498 | // lies in the inside also. | ||||||
1499 | if( ( !pLay->IsInFootnote() || pSct->IsInFootnote() ) && | ||||||
1500 | ( !pLay->IsInTab() || pSct->IsInTab() ) ) | ||||||
1501 | { | ||||||
1502 | pActualSection.reset(new SwActualSection(nullptr, pSct, pSct->GetSection()->GetFormat()->GetSectionNode())); | ||||||
1503 | // tdf#132236 for SwUndoDelete: find outer sections whose start | ||||||
1504 | // nodes aren't contained in the range but whose end nodes are, | ||||||
1505 | // because section frames may need to be created for them | ||||||
1506 | SwActualSection * pUpperSection(pActualSection.get()); | ||||||
1507 | while (pUpperSection->GetSectionNode()->EndOfSectionIndex() < nEndIndex) | ||||||
1508 | { | ||||||
1509 | SwStartNode *const pStart(pUpperSection->GetSectionNode()->StartOfSectionNode()); | ||||||
1510 | if (!pStart->IsSectionNode()) | ||||||
1511 | { | ||||||
1512 | break; | ||||||
1513 | } | ||||||
1514 | // note: these don't have a section frame, check it in EndNode case! | ||||||
1515 | auto const pTmp(new SwActualSection(nullptr, nullptr, static_cast<SwSectionNode*>(pStart))); | ||||||
1516 | pUpperSection->SetUpper(pTmp); | ||||||
1517 | pUpperSection = pTmp; | ||||||
1518 | } | ||||||
1519 | OSL_ENSURE( !pLay->Lower() || !pLay->Lower()->IsColumnFrame(),do { if (true && (!(!pLay->Lower() || !pLay->Lower ()->IsColumnFrame()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "1520" ": "), "%s", "InsertCnt_: Wrong Call"); } } while (false) | ||||||
1520 | "InsertCnt_: Wrong Call" )do { if (true && (!(!pLay->Lower() || !pLay->Lower ()->IsColumnFrame()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "1520" ": "), "%s", "InsertCnt_: Wrong Call"); } } while (false); | ||||||
1521 | } | ||||||
1522 | } | ||||||
1523 | |||||||
1524 | //If a section is "open", the pActualSection points to an SwActualSection. | ||||||
1525 | //If the page breaks, for "open" sections a follow will created. | ||||||
1526 | //For nested sections (which have, however, not a nested layout), | ||||||
1527 | //the SwActualSection class has a member, which points to an upper(section). | ||||||
1528 | //When the "inner" section finishes, the upper will used instead. | ||||||
1529 | |||||||
1530 | // Do not consider the end node. The caller (Section/MakeFrames()) has to | ||||||
1531 | // ensure that the end of this range is positioned before EndIndex! | ||||||
1532 | for ( ; nEndIndex == 0 || nIndex < nEndIndex; ++nIndex) | ||||||
1533 | { | ||||||
1534 | SwNode *pNd = pDoc->GetNodes()[nIndex]; | ||||||
1535 | if ( pNd->IsContentNode() ) | ||||||
1536 | { | ||||||
1537 | SwContentNode* pNode = static_cast<SwContentNode*>(pNd); | ||||||
1538 | if (pLayout->IsHideRedlines() && !pNd->IsCreateFrameWhenHidingRedlines()) | ||||||
1539 | { | ||||||
1540 | if (pNd->IsTextNode() | ||||||
1541 | && pNd->GetRedlineMergeFlag() == SwNode::Merge::NonFirst) | ||||||
1542 | { // must have a frame already | ||||||
1543 | assert(static_cast<SwTextFrame*>(pNode->getLayoutFrame(pLayout))->GetMergedPara())(static_cast <bool> (static_cast<SwTextFrame*>(pNode ->getLayoutFrame(pLayout))->GetMergedPara()) ? void (0) : __assert_fail ("static_cast<SwTextFrame*>(pNode->getLayoutFrame(pLayout))->GetMergedPara()" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1543, __extension__ __PRETTY_FUNCTION__)); | ||||||
1544 | } | ||||||
1545 | continue; // skip it | ||||||
1546 | } | ||||||
1547 | pFrame = pNode->IsTextNode() | ||||||
1548 | ? sw::MakeTextFrame(*pNode->GetTextNode(), pLay, eMode) | ||||||
1549 | : pNode->MakeFrame(pLay); | ||||||
1550 | if( pPageMaker ) | ||||||
1551 | pPageMaker->CheckInsert( nIndex ); | ||||||
1552 | |||||||
1553 | pFrame->InsertBehind( pLay, pPrv ); | ||||||
1554 | // #i27138# | ||||||
1555 | // notify accessibility paragraphs objects about changed | ||||||
1556 | // CONTENT_FLOWS_FROM/_TO relation. | ||||||
1557 | // Relation CONTENT_FLOWS_FROM for next paragraph will change | ||||||
1558 | // and relation CONTENT_FLOWS_TO for previous paragraph will change. | ||||||
1559 | if ( pFrame->IsTextFrame() ) | ||||||
1560 | { | ||||||
1561 | SwViewShell* pViewShell( pFrame->getRootFrame()->GetCurrShell() ); | ||||||
1562 | // no notification, if <SwViewShell> is in construction | ||||||
1563 | if ( pViewShell && !pViewShell->IsInConstructor() && | ||||||
1564 | pViewShell->GetLayout() && | ||||||
1565 | pViewShell->GetLayout()->IsAnyShellAccessible() && | ||||||
1566 | pFrame->FindPageFrame() != nullptr) | ||||||
1567 | { | ||||||
1568 | pViewShell->InvalidateAccessibleParaFlowRelation( | ||||||
1569 | dynamic_cast<SwTextFrame*>(pFrame->FindNextCnt( true )), | ||||||
1570 | dynamic_cast<SwTextFrame*>(pFrame->FindPrevCnt()) ); | ||||||
1571 | // #i68958# | ||||||
1572 | // The information flags of the text frame are validated | ||||||
1573 | // in methods <FindNextCnt(..)> and <FindPrevCnt(..)>. | ||||||
1574 | // The information flags have to be invalidated, because | ||||||
1575 | // it is possible, that the one of its upper frames | ||||||
1576 | // isn't inserted into the layout. | ||||||
1577 | pFrame->InvalidateInfFlags(); | ||||||
1578 | } | ||||||
1579 | } | ||||||
1580 | // OD 12.08.2003 #i17969# - consider horizontal/vertical layout | ||||||
1581 | // for setting position at newly inserted frame | ||||||
1582 | lcl_SetPos( *pFrame, *pLay ); | ||||||
1583 | pPrv = pFrame; | ||||||
1584 | |||||||
1585 | if ( !pTable->empty() && bObjsDirect && !bDontCreateObjects ) | ||||||
1586 | AppendObjs( pTable, nIndex, pFrame, pPage, pDoc ); | ||||||
1587 | } | ||||||
1588 | else if ( pNd->IsTableNode() ) | ||||||
1589 | { //Should we have encountered a table? | ||||||
1590 | SwTableNode *pTableNode = static_cast<SwTableNode*>(pNd); | ||||||
1591 | if (pLayout->IsHideRedlines()) | ||||||
1592 | { | ||||||
1593 | // in the problematic case, there can be only 1 redline... | ||||||
1594 | SwPosition const tmp(*pNd); | ||||||
1595 | SwRangeRedline const*const pRedline( | ||||||
1596 | pDoc->getIDocumentRedlineAccess().GetRedline(tmp, nullptr)); | ||||||
1597 | // pathology: redline that starts on a TableNode; cannot | ||||||
1598 | // be created in UI but by import filters... | ||||||
1599 | if (pRedline | ||||||
1600 | && pRedline->GetType() == RedlineType::Delete | ||||||
1601 | && &pRedline->Start()->nNode.GetNode() == pNd) | ||||||
1602 | { | ||||||
1603 | SAL_WARN("sw.pageframe", "skipping table frame creation on bizarre redline")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.pageframe")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break ; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "skipping table frame creation on bizarre redline" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.pageframe" ), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "1603" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "skipping table frame creation on bizarre redline" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "skipping table frame creation on bizarre redline"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.pageframe" ), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "1603" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "skipping table frame creation on bizarre redline" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.pageframe" ), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "1603" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "skipping table frame creation on bizarre redline" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "skipping table frame creation on bizarre redline"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.pageframe" ), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "1603" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
1604 | while (true) | ||||||
1605 | { | ||||||
1606 | pTableNode->GetNodes()[nIndex]->SetRedlineMergeFlag(SwNode::Merge::Hidden); | ||||||
1607 | if (nIndex == pTableNode->EndOfSectionIndex()) | ||||||
1608 | { | ||||||
1609 | break; | ||||||
1610 | } | ||||||
1611 | ++nIndex; | ||||||
1612 | } | ||||||
1613 | continue; | ||||||
1614 | } | ||||||
1615 | } | ||||||
1616 | if (pLayout->IsHideRedlines() && !pNd->IsCreateFrameWhenHidingRedlines()) | ||||||
1617 | { | ||||||
1618 | assert(pNd->GetRedlineMergeFlag() == SwNode::Merge::Hidden)(static_cast <bool> (pNd->GetRedlineMergeFlag() == SwNode ::Merge::Hidden) ? void (0) : __assert_fail ("pNd->GetRedlineMergeFlag() == SwNode::Merge::Hidden" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1618, __extension__ __PRETTY_FUNCTION__)); | ||||||
1619 | nIndex = pTableNode->EndOfSectionIndex(); | ||||||
1620 | continue; // skip it | ||||||
1621 | } | ||||||
1622 | |||||||
1623 | // #108116# loading may produce table structures that GCLines | ||||||
1624 | // needs to clean up. To keep table formulas correct, change | ||||||
1625 | // all table formulas to internal (BOXPTR) representation. | ||||||
1626 | SwTableFormulaUpdate aMsgHint( &pTableNode->GetTable() ); | ||||||
1627 | aMsgHint.m_eFlags = TBL_BOXPTR; | ||||||
1628 | pDoc->getIDocumentFieldsAccess().UpdateTableFields( &aMsgHint ); | ||||||
1629 | pTableNode->GetTable().GCLines(); | ||||||
1630 | |||||||
1631 | pFrame = pTableNode->MakeFrame( pLay ); | ||||||
1632 | |||||||
1633 | if( pPageMaker ) | ||||||
1634 | pPageMaker->CheckInsert( nIndex ); | ||||||
1635 | |||||||
1636 | pFrame->InsertBehind( pLay, pPrv ); | ||||||
1637 | if (pPage) // would null in SwCellFrame ctor | ||||||
1638 | { // tdf#134931 call ResetTurbo(); not sure if Paste() would be | ||||||
1639 | pFrame->InvalidatePage(pPage); // better than InsertBehind()? | ||||||
1640 | } | ||||||
1641 | // #i27138# | ||||||
1642 | // notify accessibility paragraphs objects about changed | ||||||
1643 | // CONTENT_FLOWS_FROM/_TO relation. | ||||||
1644 | // Relation CONTENT_FLOWS_FROM for next paragraph will change | ||||||
1645 | // and relation CONTENT_FLOWS_TO for previous paragraph will change. | ||||||
1646 | { | ||||||
1647 | SwViewShell* pViewShell( pFrame->getRootFrame()->GetCurrShell() ); | ||||||
1648 | // no notification, if <SwViewShell> is in construction | ||||||
1649 | if ( pViewShell && !pViewShell->IsInConstructor() && | ||||||
1650 | pViewShell->GetLayout() && | ||||||
1651 | pViewShell->GetLayout()->IsAnyShellAccessible() && | ||||||
1652 | pFrame->FindPageFrame() != nullptr) | ||||||
1653 | { | ||||||
1654 | pViewShell->InvalidateAccessibleParaFlowRelation( | ||||||
1655 | dynamic_cast<SwTextFrame*>(pFrame->FindNextCnt( true )), | ||||||
1656 | dynamic_cast<SwTextFrame*>(pFrame->FindPrevCnt()) ); | ||||||
1657 | } | ||||||
1658 | } | ||||||
1659 | if ( bObjsDirect && !pTable->empty() ) | ||||||
1660 | static_cast<SwTabFrame*>(pFrame)->RegistFlys(); | ||||||
1661 | // OD 12.08.2003 #i17969# - consider horizontal/vertical layout | ||||||
1662 | // for setting position at newly inserted frame | ||||||
1663 | lcl_SetPos( *pFrame, *pLay ); | ||||||
1664 | |||||||
1665 | pPrv = pFrame; | ||||||
1666 | //Set the index to the endnode of the table section. | ||||||
1667 | nIndex = pTableNode->EndOfSectionIndex(); | ||||||
1668 | |||||||
1669 | SwTabFrame* pTmpFrame = static_cast<SwTabFrame*>(pFrame); | ||||||
1670 | while ( pTmpFrame ) | ||||||
1671 | { | ||||||
1672 | pTmpFrame->CheckDirChange(); | ||||||
1673 | pTmpFrame = pTmpFrame->IsFollow() ? pTmpFrame->FindMaster() : nullptr; | ||||||
1674 | } | ||||||
1675 | |||||||
1676 | } | ||||||
1677 | else if ( pNd->IsSectionNode() ) | ||||||
1678 | { | ||||||
1679 | if (pLayout->IsHideRedlines() && !pNd->IsCreateFrameWhenHidingRedlines()) | ||||||
1680 | { | ||||||
1681 | assert(pNd->GetRedlineMergeFlag() == SwNode::Merge::Hidden)(static_cast <bool> (pNd->GetRedlineMergeFlag() == SwNode ::Merge::Hidden) ? void (0) : __assert_fail ("pNd->GetRedlineMergeFlag() == SwNode::Merge::Hidden" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1681, __extension__ __PRETTY_FUNCTION__)); | ||||||
1682 | continue; // skip it | ||||||
1683 | } | ||||||
1684 | SwSectionNode *pNode = static_cast<SwSectionNode*>(pNd); | ||||||
1685 | if( pNode->GetSection().CalcHiddenFlag() ) | ||||||
1686 | // is hidden, skip the area | ||||||
1687 | nIndex = pNode->EndOfSectionIndex(); | ||||||
1688 | else | ||||||
1689 | { | ||||||
1690 | pFrame = pNode->MakeFrame( pLay ); | ||||||
1691 | pActualSection.reset( new SwActualSection( pActualSection.release(), | ||||||
1692 | static_cast<SwSectionFrame*>(pFrame), pNode ) ); | ||||||
1693 | if ( pActualSection->GetUpper() ) | ||||||
1694 | { | ||||||
1695 | //Insert behind the Upper, the "Follow" of the Upper will be | ||||||
1696 | //generated at the EndNode. | ||||||
1697 | SwSectionFrame *pTmp = pActualSection->GetUpper()->GetSectionFrame(); | ||||||
1698 | pFrame->InsertBehind( pTmp->GetUpper(), pTmp ); | ||||||
1699 | // OD 25.03.2003 #108339# - direct initialization of section | ||||||
1700 | // after insertion in the layout | ||||||
1701 | static_cast<SwSectionFrame*>(pFrame)->Init(); | ||||||
1702 | } | ||||||
1703 | else | ||||||
1704 | { | ||||||
1705 | pFrame->InsertBehind( pLay, pPrv ); | ||||||
1706 | // OD 25.03.2003 #108339# - direct initialization of section | ||||||
1707 | // after insertion in the layout | ||||||
1708 | static_cast<SwSectionFrame*>(pFrame)->Init(); | ||||||
1709 | |||||||
1710 | // #i33963# | ||||||
1711 | // Do not trust the IsInFootnote flag. If we are currently | ||||||
1712 | // building up a table, the upper of pPrv may be a cell | ||||||
1713 | // frame, but the cell frame does not have an upper yet. | ||||||
1714 | if( pPrv && nullptr != pPrv->ImplFindFootnoteFrame() ) | ||||||
1715 | { | ||||||
1716 | if( pPrv->IsSctFrame() ) | ||||||
1717 | pPrv = static_cast<SwSectionFrame*>(pPrv)->ContainsContent(); | ||||||
1718 | if( pPrv && pPrv->IsTextFrame() ) | ||||||
1719 | static_cast<SwTextFrame*>(pPrv)->Prepare( PrepareHint::QuoVadis, nullptr, false ); | ||||||
1720 | } | ||||||
1721 | } | ||||||
1722 | if (nIndex + 1 == nEndIndex) | ||||||
1723 | { // tdf#131684 tdf#132236 fix upper of frame moved in | ||||||
1724 | // SwUndoDelete; can't be done there unfortunately | ||||||
1725 | // because empty section frames are deleted here | ||||||
1726 | SwFrame *const pNext( | ||||||
1727 | // if there's a parent section, it has been split | ||||||
1728 | // into 2 SwSectionFrame already :( | ||||||
1729 | ( pFrame->GetNext() | ||||||
1730 | && pFrame->GetNext()->IsSctFrame() | ||||||
1731 | && pActualSection->GetUpper() | ||||||
1732 | && pActualSection->GetUpper()->GetSectionNode() == | ||||||
1733 | static_cast<SwSectionFrame const*>(pFrame->GetNext())->GetSection()->GetFormat()->GetSectionNode()) | ||||||
1734 | ? static_cast<SwSectionFrame *>(pFrame->GetNext())->ContainsContent() | ||||||
1735 | : pFrame->GetNext()); | ||||||
1736 | if (pNext | ||||||
1737 | && pNext->IsTextFrame() | ||||||
1738 | && static_cast<SwTextFrame*>(pNext)->GetTextNodeFirst() == pDoc->GetNodes()[nEndIndex] | ||||||
1739 | && (pNext->GetUpper() == pFrame->GetUpper() | ||||||
1740 | || pFrame->GetNext()->IsSctFrame())) // checked above | ||||||
1741 | { | ||||||
1742 | pNext->Cut(); | ||||||
1743 | pNext->InvalidateInfFlags(); // mbInfSct changed | ||||||
1744 | // could have columns | ||||||
1745 | SwSectionFrame *const pSection(static_cast<SwSectionFrame*>(pFrame)); | ||||||
1746 | assert(!pSection->Lower() || pSection->Lower()->IsLayoutFrame())(static_cast <bool> (!pSection->Lower() || pSection-> Lower()->IsLayoutFrame()) ? void (0) : __assert_fail ("!pSection->Lower() || pSection->Lower()->IsLayoutFrame()" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1746, __extension__ __PRETTY_FUNCTION__)); | ||||||
1747 | SwLayoutFrame *const pParent(pSection->Lower() ? pSection->GetNextLayoutLeaf() : pSection); | ||||||
1748 | assert(!pParent->Lower())(static_cast <bool> (!pParent->Lower()) ? void (0) : __assert_fail ("!pParent->Lower()", "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1748, __extension__ __PRETTY_FUNCTION__)); | ||||||
1749 | // paste invalidates, section could have indent... | ||||||
1750 | pNext->Paste(pParent, nullptr); | ||||||
1751 | } | ||||||
1752 | } | ||||||
1753 | // #i27138# | ||||||
1754 | // notify accessibility paragraphs objects about changed | ||||||
1755 | // CONTENT_FLOWS_FROM/_TO relation. | ||||||
1756 | // Relation CONTENT_FLOWS_FROM for next paragraph will change | ||||||
1757 | // and relation CONTENT_FLOWS_TO for previous paragraph will change. | ||||||
1758 | { | ||||||
1759 | SwViewShell* pViewShell( pFrame->getRootFrame()->GetCurrShell() ); | ||||||
1760 | // no notification, if <SwViewShell> is in construction | ||||||
1761 | if ( pViewShell && !pViewShell->IsInConstructor() && | ||||||
1762 | pViewShell->GetLayout() && | ||||||
1763 | pViewShell->GetLayout()->IsAnyShellAccessible() && | ||||||
1764 | pFrame->FindPageFrame() != nullptr) | ||||||
1765 | { | ||||||
1766 | pViewShell->InvalidateAccessibleParaFlowRelation( | ||||||
1767 | dynamic_cast<SwTextFrame*>(pFrame->FindNextCnt( true )), | ||||||
1768 | dynamic_cast<SwTextFrame*>(pFrame->FindPrevCnt()) ); | ||||||
1769 | } | ||||||
1770 | } | ||||||
1771 | pFrame->CheckDirChange(); | ||||||
1772 | |||||||
1773 | // OD 12.08.2003 #i17969# - consider horizontal/vertical layout | ||||||
1774 | // for setting position at newly inserted frame | ||||||
1775 | lcl_SetPos( *pFrame, *pLay ); | ||||||
1776 | |||||||
1777 | // OD 20.11.2002 #105405# - no page, no invalidate. | ||||||
1778 | if ( pPage ) | ||||||
1779 | { | ||||||
1780 | // OD 18.09.2002 #100522# | ||||||
1781 | // invalidate page in order to force format and paint of | ||||||
1782 | // inserted section frame | ||||||
1783 | pFrame->InvalidatePage( pPage ); | ||||||
1784 | |||||||
1785 | // FME 10.11.2003 #112243# | ||||||
1786 | // Invalidate fly content flag: | ||||||
1787 | if ( pFrame->IsInFly() ) | ||||||
1788 | pPage->InvalidateFlyContent(); | ||||||
1789 | |||||||
1790 | // OD 14.11.2002 #104684# - invalidate page content in order to | ||||||
1791 | // force format and paint of section content. | ||||||
1792 | pPage->InvalidateContent(); | ||||||
1793 | } | ||||||
1794 | |||||||
1795 | pLay = static_cast<SwLayoutFrame*>(pFrame); | ||||||
1796 | if ( pLay->Lower() && pLay->Lower()->IsLayoutFrame() ) | ||||||
1797 | pLay = pLay->GetNextLayoutLeaf(); | ||||||
1798 | pPrv = nullptr; | ||||||
1799 | } | ||||||
1800 | } | ||||||
1801 | else if ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode() ) | ||||||
1802 | { | ||||||
1803 | if (pLayout->IsHideRedlines() && !pNd->IsCreateFrameWhenHidingRedlines()) | ||||||
| |||||||
1804 | { | ||||||
1805 | assert(pNd->GetRedlineMergeFlag() == SwNode::Merge::Hidden)(static_cast <bool> (pNd->GetRedlineMergeFlag() == SwNode ::Merge::Hidden) ? void (0) : __assert_fail ("pNd->GetRedlineMergeFlag() == SwNode::Merge::Hidden" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1805, __extension__ __PRETTY_FUNCTION__)); | ||||||
1806 | continue; // skip it | ||||||
1807 | } | ||||||
1808 | assert(pActualSection && "Section end without section start?")(static_cast <bool> (pActualSection && "Section end without section start?" ) ? void (0) : __assert_fail ("pActualSection && \"Section end without section start?\"" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1808, __extension__ __PRETTY_FUNCTION__)); | ||||||
1809 | assert(pActualSection->GetSectionNode() == pNd->StartOfSectionNode())(static_cast <bool> (pActualSection->GetSectionNode( ) == pNd->StartOfSectionNode()) ? void (0) : __assert_fail ("pActualSection->GetSectionNode() == pNd->StartOfSectionNode()" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1809, __extension__ __PRETTY_FUNCTION__)); | ||||||
1810 | |||||||
1811 | //Close the section, where appropriate activate the surrounding | ||||||
1812 | //section again. | ||||||
1813 | pActualSection.reset(pActualSection->GetUpper()); | ||||||
1814 | pLay = pLay->FindSctFrame(); | ||||||
1815 | if ( pActualSection ) | ||||||
1816 | { | ||||||
1817 | //Could be, that the last SectionFrame remains empty. | ||||||
1818 | //Then now is the time to remove them. | ||||||
1819 | if ( !pLay->ContainsContent() ) | ||||||
1820 | { | ||||||
1821 | SwFrame *pTmpFrame = pLay; | ||||||
1822 | pLay = pTmpFrame->GetUpper(); | ||||||
1823 | pPrv = pTmpFrame->GetPrev(); | ||||||
1824 | pTmpFrame->RemoveFromLayout(); | ||||||
1825 | SwFrame::DestroyFrame(pTmpFrame); | ||||||
1826 | } | ||||||
1827 | else | ||||||
1828 | { | ||||||
1829 | pPrv = pLay; | ||||||
1830 | pLay = pLay->GetUpper(); | ||||||
1831 | } | ||||||
1832 | |||||||
1833 | // new section frame | ||||||
1834 | pFrame = pActualSection->GetSectionNode()->MakeFrame( pLay ); | ||||||
1835 | pFrame->InsertBehind( pLay, pPrv ); | ||||||
1836 | static_cast<SwSectionFrame*>(pFrame)->Init(); | ||||||
1837 | |||||||
1838 | // OD 12.08.2003 #i17969# - consider horizontal/vertical layout | ||||||
1839 | // for setting position at newly inserted frame | ||||||
1840 | lcl_SetPos( *pFrame, *pLay ); | ||||||
1841 | |||||||
1842 | SwSectionFrame* pOuterSectionFrame = pActualSection->GetSectionFrame(); | ||||||
1843 | |||||||
1844 | // a follow has to be appended to the new section frame | ||||||
1845 | SwSectionFrame* pFollow = pOuterSectionFrame ? pOuterSectionFrame->GetFollow() : nullptr; | ||||||
1846 | if ( pFollow ) | ||||||
1847 | { | ||||||
1848 | pOuterSectionFrame->SetFollow( nullptr ); | ||||||
1849 | pOuterSectionFrame->InvalidateSize(); | ||||||
1850 | static_cast<SwSectionFrame*>(pFrame)->SetFollow( pFollow ); | ||||||
1851 | } | ||||||
1852 | |||||||
1853 | // We don't want to leave empty parts back. | ||||||
1854 | if (pOuterSectionFrame && | ||||||
1855 | ! pOuterSectionFrame->IsColLocked() && | ||||||
1856 | ! pOuterSectionFrame->ContainsContent() ) | ||||||
1857 | { | ||||||
1858 | pOuterSectionFrame->DelEmpty( true ); | ||||||
1859 | SwFrame::DestroyFrame(pOuterSectionFrame); | ||||||
1860 | } | ||||||
1861 | pActualSection->SetSectionFrame( static_cast<SwSectionFrame*>(pFrame) ); | ||||||
1862 | |||||||
1863 | pLay = static_cast<SwLayoutFrame*>(pFrame); | ||||||
1864 | if ( pLay->Lower() && pLay->Lower()->IsLayoutFrame() ) | ||||||
1865 | pLay = pLay->GetNextLayoutLeaf(); | ||||||
1866 | pPrv = nullptr; | ||||||
1867 | } | ||||||
1868 | else | ||||||
1869 | { | ||||||
1870 | //Nothing more with sections, it goes on right behind | ||||||
1871 | //the SectionFrame. | ||||||
1872 | pPrv = pLay; | ||||||
1873 | pLay = pLay->GetUpper(); | ||||||
1874 | } | ||||||
1875 | } | ||||||
1876 | else if( pNd->IsStartNode() && | ||||||
1877 | SwFlyStartNode == static_cast<SwStartNode*>(pNd)->GetStartNodeType() ) | ||||||
1878 | { | ||||||
1879 | if (pLayout->IsHideRedlines() && !pNd->IsCreateFrameWhenHidingRedlines()) | ||||||
1880 | { | ||||||
1881 | assert(pNd->GetRedlineMergeFlag() == SwNode::Merge::Hidden)(static_cast <bool> (pNd->GetRedlineMergeFlag() == SwNode ::Merge::Hidden) ? void (0) : __assert_fail ("pNd->GetRedlineMergeFlag() == SwNode::Merge::Hidden" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1881, __extension__ __PRETTY_FUNCTION__)); | ||||||
1882 | assert(false)(static_cast <bool> (false) ? void (0) : __assert_fail ( "false", "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1882, __extension__ __PRETTY_FUNCTION__)); // actually a fly-section can't be deleted? | ||||||
1883 | continue; // skip it | ||||||
1884 | } | ||||||
1885 | if ( !pTable->empty() && bObjsDirect && !bDontCreateObjects ) | ||||||
1886 | { | ||||||
1887 | SwFlyFrame* pFly = pLay->FindFlyFrame(); | ||||||
1888 | if( pFly ) | ||||||
1889 | AppendObjs( pTable, nIndex, pFly, pPage, pDoc ); | ||||||
1890 | } | ||||||
1891 | } | ||||||
1892 | else | ||||||
1893 | { | ||||||
1894 | assert(!pLayout->IsHideRedlines()(static_cast <bool> (!pLayout->IsHideRedlines() || pNd ->GetRedlineMergeFlag() != SwNode::Merge::Hidden) ? void ( 0) : __assert_fail ("!pLayout->IsHideRedlines() || pNd->GetRedlineMergeFlag() != SwNode::Merge::Hidden" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1895, __extension__ __PRETTY_FUNCTION__)) | ||||||
1895 | || pNd->GetRedlineMergeFlag() != SwNode::Merge::Hidden)(static_cast <bool> (!pLayout->IsHideRedlines() || pNd ->GetRedlineMergeFlag() != SwNode::Merge::Hidden) ? void ( 0) : __assert_fail ("!pLayout->IsHideRedlines() || pNd->GetRedlineMergeFlag() != SwNode::Merge::Hidden" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1895, __extension__ __PRETTY_FUNCTION__)); | ||||||
1896 | // Neither Content nor table nor section, so we are done. | ||||||
1897 | break; | ||||||
1898 | } | ||||||
1899 | } | ||||||
1900 | |||||||
1901 | if ( pActualSection ) | ||||||
1902 | { | ||||||
1903 | // Might happen that an empty (Follow-)Section is left over. | ||||||
1904 | if ( !(pLay = pActualSection->GetSectionFrame())->ContainsContent() ) | ||||||
1905 | { | ||||||
1906 | pLay->RemoveFromLayout(); | ||||||
1907 | SwFrame::DestroyFrame(pLay); | ||||||
1908 | } | ||||||
1909 | pActualSection.reset(); | ||||||
1910 | } | ||||||
1911 | |||||||
1912 | if ( bPages ) // let the Flys connect to each other | ||||||
1913 | { | ||||||
1914 | if ( !bDontCreateObjects ) | ||||||
1915 | AppendAllObjs( pTable, pLayout ); | ||||||
1916 | bObjsDirect = true; | ||||||
1917 | } | ||||||
1918 | |||||||
1919 | if( pPageMaker ) | ||||||
1920 | { | ||||||
1921 | pPageMaker->CheckFlyCache( pPage ); | ||||||
1922 | pPageMaker.reset(); | ||||||
1923 | if( pDoc->GetLayoutCache() ) | ||||||
1924 | { | ||||||
1925 | #ifdef DBG_UTIL | ||||||
1926 | pDoc->GetLayoutCache()->CompareLayout( *pDoc ); | ||||||
1927 | #endif | ||||||
1928 | pDoc->GetLayoutCache()->ClearImpl(); | ||||||
1929 | } | ||||||
1930 | } | ||||||
1931 | |||||||
1932 | pDoc->getIDocumentTimerAccess().UnblockIdling(); | ||||||
1933 | if( bOldCallbackActionEnabled ) | ||||||
1934 | pLayout->SetCallbackActionEnabled( bOldCallbackActionEnabled ); | ||||||
1935 | } | ||||||
1936 | |||||||
1937 | void MakeFrames( SwDoc *pDoc, const SwNodeIndex &rSttIdx, | ||||||
1938 | const SwNodeIndex &rEndIdx ) | ||||||
1939 | { | ||||||
1940 | bObjsDirect = false; | ||||||
1941 | |||||||
1942 | SwNodeIndex aTmp( rSttIdx ); | ||||||
1943 | sal_uLong nEndIdx = rEndIdx.GetIndex(); | ||||||
1944 | SwNode* pNd = pDoc->GetNodes().FindPrvNxtFrameNode( aTmp, | ||||||
1945 | pDoc->GetNodes()[ nEndIdx-1 ]); | ||||||
1946 | if ( pNd ) | ||||||
1947 | { | ||||||
1948 | bool bApres = aTmp < rSttIdx; | ||||||
1949 | SwNode2Layout aNode2Layout( *pNd, rSttIdx.GetIndex() ); | ||||||
1950 | SwFrame* pFrame; | ||||||
1951 | sw::FrameMode eMode = sw::FrameMode::Existing; | ||||||
1952 | while( nullptr != (pFrame = aNode2Layout.NextFrame()) ) | ||||||
1953 | { | ||||||
1954 | SwLayoutFrame *pUpper = pFrame->GetUpper(); | ||||||
1955 | SwFootnoteFrame* pFootnoteFrame = pUpper->FindFootnoteFrame(); | ||||||
1956 | bool bOldLock, bOldFootnote; | ||||||
1957 | if( pFootnoteFrame ) | ||||||
1958 | { | ||||||
1959 | bOldFootnote = pFootnoteFrame->IsColLocked(); | ||||||
1960 | pFootnoteFrame->ColLock(); | ||||||
1961 | } | ||||||
1962 | else | ||||||
1963 | bOldFootnote = true; | ||||||
1964 | SwSectionFrame* pSct = pUpper->FindSctFrame(); | ||||||
1965 | // Inside of footnotes only those areas are interesting that are inside of them. But | ||||||
1966 | // not the ones (e.g. column areas) in which are the footnote containers positioned. | ||||||
1967 | // #109767# Table frame is in section, insert section in cell frame. | ||||||
1968 | if( pSct && ((pFootnoteFrame && !pSct->IsInFootnote()) || pUpper->IsCellFrame()) ) | ||||||
1969 | pSct = nullptr; | ||||||
1970 | if( pSct ) | ||||||
1971 | { // to prevent pTmp->MoveFwd from destroying the SectionFrame | ||||||
1972 | bOldLock = pSct->IsColLocked(); | ||||||
1973 | pSct->ColLock(); | ||||||
1974 | } | ||||||
1975 | else | ||||||
1976 | bOldLock = true; | ||||||
1977 | |||||||
1978 | // If pFrame cannot be moved, it is not possible to move it to the next page. This applies | ||||||
1979 | // also for frames (in the first column of a frame pFrame is moveable) and column | ||||||
1980 | // sections of tables (also here pFrame is moveable). | ||||||
1981 | bool bMoveNext = nEndIdx - rSttIdx.GetIndex() > 120; | ||||||
1982 | bool bAllowMove = !pFrame->IsInFly() && pFrame->IsMoveable() && | ||||||
1983 | (!pFrame->IsInTab() || pFrame->IsTabFrame() ); | ||||||
1984 | if ( bMoveNext && bAllowMove ) | ||||||
1985 | { | ||||||
1986 | SwFrame *pMove = pFrame; | ||||||
1987 | SwFrame *pPrev = pFrame->GetPrev(); | ||||||
1988 | SwFlowFrame *pTmp = SwFlowFrame::CastFlowFrame( pMove ); | ||||||
1989 | assert(pTmp)(static_cast <bool> (pTmp) ? void (0) : __assert_fail ( "pTmp", "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1989, __extension__ __PRETTY_FUNCTION__)); | ||||||
1990 | |||||||
1991 | if ( bApres ) | ||||||
1992 | { | ||||||
1993 | // The rest of this page should be empty. Thus, the following one has to move to | ||||||
1994 | // the next page (it might also be located in the following column). | ||||||
1995 | assert(!pTmp->HasFollow() && "prev. node's frame is not last")(static_cast <bool> (!pTmp->HasFollow() && "prev. node's frame is not last" ) ? void (0) : __assert_fail ("!pTmp->HasFollow() && \"prev. node's frame is not last\"" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 1995, __extension__ __PRETTY_FUNCTION__)); | ||||||
1996 | pPrev = pFrame; | ||||||
1997 | // If the surrounding SectionFrame has a "next" one, | ||||||
1998 | // so this one needs to be moved as well. | ||||||
1999 | pMove = pFrame->GetIndNext(); | ||||||
2000 | SwColumnFrame* pCol = static_cast<SwColumnFrame*>(pFrame->FindColFrame()); | ||||||
2001 | if( pCol ) | ||||||
2002 | pCol = static_cast<SwColumnFrame*>(pCol->GetNext()); | ||||||
2003 | do | ||||||
2004 | { | ||||||
2005 | if( pCol && !pMove ) | ||||||
2006 | { // No successor so far, look into the next column | ||||||
2007 | pMove = pCol->ContainsAny(); | ||||||
2008 | if( pCol->GetNext() ) | ||||||
2009 | pCol = static_cast<SwColumnFrame*>(pCol->GetNext()); | ||||||
2010 | else if( pCol->IsInSct() ) | ||||||
2011 | { // If there is no following column but we are in a column frame, | ||||||
2012 | // there might be (page) columns outside of it. | ||||||
2013 | pCol = static_cast<SwColumnFrame*>(pCol->FindSctFrame()->FindColFrame()); | ||||||
2014 | if( pCol ) | ||||||
2015 | pCol = static_cast<SwColumnFrame*>(pCol->GetNext()); | ||||||
2016 | } | ||||||
2017 | else | ||||||
2018 | pCol = nullptr; | ||||||
2019 | } | ||||||
2020 | // skip invalid SectionFrames | ||||||
2021 | while( pMove && pMove->IsSctFrame() && | ||||||
2022 | !static_cast<SwSectionFrame*>(pMove)->GetSection() ) | ||||||
2023 | pMove = pMove->GetNext(); | ||||||
2024 | } while( !pMove && pCol ); | ||||||
2025 | |||||||
2026 | if( pMove ) | ||||||
2027 | { | ||||||
2028 | if ( pMove->IsContentFrame() ) | ||||||
2029 | pTmp = static_cast<SwContentFrame*>(pMove); | ||||||
2030 | else if ( pMove->IsTabFrame() ) | ||||||
2031 | pTmp = static_cast<SwTabFrame*>(pMove); | ||||||
2032 | else if ( pMove->IsSctFrame() ) | ||||||
2033 | { | ||||||
2034 | pMove = static_cast<SwSectionFrame*>(pMove)->ContainsAny(); | ||||||
2035 | if( pMove ) | ||||||
2036 | pTmp = SwFlowFrame::CastFlowFrame( pMove ); | ||||||
2037 | else | ||||||
2038 | pTmp = nullptr; | ||||||
2039 | } | ||||||
2040 | } | ||||||
2041 | else | ||||||
2042 | pTmp = nullptr; | ||||||
2043 | } | ||||||
2044 | else | ||||||
2045 | { | ||||||
2046 | assert(!pTmp->IsFollow() && "next node's frame is not master")(static_cast <bool> (!pTmp->IsFollow() && "next node's frame is not master" ) ? void (0) : __assert_fail ("!pTmp->IsFollow() && \"next node's frame is not master\"" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 2046, __extension__ __PRETTY_FUNCTION__)); | ||||||
2047 | // move the _content_ of a section frame | ||||||
2048 | if( pMove->IsSctFrame() ) | ||||||
2049 | { | ||||||
2050 | while( pMove && pMove->IsSctFrame() && | ||||||
2051 | !static_cast<SwSectionFrame*>(pMove)->GetSection() ) | ||||||
2052 | pMove = pMove->GetNext(); | ||||||
2053 | if( pMove && pMove->IsSctFrame() ) | ||||||
2054 | pMove = static_cast<SwSectionFrame*>(pMove)->ContainsAny(); | ||||||
2055 | if( pMove ) | ||||||
2056 | pTmp = SwFlowFrame::CastFlowFrame( pMove ); | ||||||
2057 | else | ||||||
2058 | pTmp = nullptr; | ||||||
2059 | } | ||||||
2060 | } | ||||||
2061 | |||||||
2062 | if( pTmp ) | ||||||
2063 | { | ||||||
2064 | SwFrame* pOldUp = pTmp->GetFrame().GetUpper(); | ||||||
2065 | // MoveFwd==true means that we are still on the same page. | ||||||
2066 | // But since we want to move if possible! | ||||||
2067 | bool bTmpOldLock = pTmp->IsJoinLocked(); | ||||||
2068 | pTmp->LockJoin(); | ||||||
2069 | while( pTmp->MoveFwd( true, false, true ) ) | ||||||
2070 | { | ||||||
2071 | if( pOldUp == pTmp->GetFrame().GetUpper() ) | ||||||
2072 | break; | ||||||
2073 | pOldUp = pTmp->GetFrame().GetUpper(); | ||||||
2074 | } | ||||||
2075 | if( !bTmpOldLock ) | ||||||
2076 | pTmp->UnlockJoin(); | ||||||
2077 | } | ||||||
2078 | ::InsertCnt_( pUpper, pDoc, rSttIdx.GetIndex(), | ||||||
2079 | pFrame->IsInDocBody(), nEndIdx, pPrev, eMode ); | ||||||
2080 | } | ||||||
2081 | else | ||||||
2082 | { | ||||||
2083 | bool bSplit; | ||||||
2084 | SwFrame* pPrv = bApres ? pFrame : pFrame->GetPrev(); | ||||||
2085 | // If the section frame is inserted into another one, it must be split. | ||||||
2086 | if( pSct && rSttIdx.GetNode().IsSectionNode() ) | ||||||
2087 | { | ||||||
2088 | bSplit = pSct->SplitSect( pFrame, bApres ); | ||||||
2089 | if( !bSplit && !bApres ) | ||||||
2090 | { | ||||||
2091 | pUpper = pSct->GetUpper(); | ||||||
2092 | pPrv = pSct->GetPrev(); | ||||||
2093 | } | ||||||
2094 | } | ||||||
2095 | else | ||||||
2096 | bSplit = false; | ||||||
2097 | |||||||
2098 | ::InsertCnt_( pUpper, pDoc, rSttIdx.GetIndex(), false, | ||||||
2099 | nEndIdx, pPrv, eMode ); | ||||||
2100 | // OD 23.06.2003 #108784# - correction: append objects doesn't | ||||||
2101 | // depend on value of <bAllowMove> | ||||||
2102 | if( !bDontCreateObjects ) | ||||||
2103 | { | ||||||
2104 | const SwFrameFormats *pTable = pDoc->GetSpzFrameFormats(); | ||||||
2105 | if( !pTable->empty() ) | ||||||
2106 | AppendAllObjs( pTable, pUpper ); | ||||||
2107 | } | ||||||
2108 | |||||||
2109 | // If nothing was added (e.g. a hidden section), the split must be reversed. | ||||||
2110 | if( bSplit && pSct && pSct->GetNext() | ||||||
2111 | && pSct->GetNext()->IsSctFrame() ) | ||||||
2112 | pSct->MergeNext( static_cast<SwSectionFrame*>(pSct->GetNext()) ); | ||||||
2113 | if( pFrame->IsInFly() ) | ||||||
2114 | pFrame->FindFlyFrame()->Invalidate_(); | ||||||
2115 | if( pFrame->IsInTab() ) | ||||||
2116 | pFrame->InvalidateSize(); | ||||||
2117 | } | ||||||
2118 | |||||||
2119 | SwPageFrame *pPage = pUpper->FindPageFrame(); | ||||||
2120 | SwFrame::CheckPageDescs( pPage, false ); | ||||||
2121 | if( !bOldFootnote ) | ||||||
2122 | pFootnoteFrame->ColUnlock(); | ||||||
2123 | if( !bOldLock ) | ||||||
2124 | { | ||||||
2125 | pSct->ColUnlock(); | ||||||
2126 | // pSct might be empty (e.g. when inserting linked section containing further | ||||||
2127 | // sections) and can be destroyed in such cases. | ||||||
2128 | if( !pSct->ContainsContent() ) | ||||||
2129 | { | ||||||
2130 | pSct->DelEmpty( true ); | ||||||
2131 | pUpper->getRootFrame()->RemoveFromList( pSct ); | ||||||
2132 | SwFrame::DestroyFrame(pSct); | ||||||
2133 | } | ||||||
2134 | } | ||||||
2135 | eMode = sw::FrameMode::New; // use Existing only once! | ||||||
2136 | } | ||||||
2137 | } | ||||||
2138 | |||||||
2139 | bObjsDirect = true; | ||||||
2140 | } | ||||||
2141 | |||||||
2142 | SwBorderAttrs::SwBorderAttrs(const SwModify *pMod, const SwFrame *pConstructor) | ||||||
2143 | : SwCacheObj(pMod) | ||||||
2144 | , m_rAttrSet(pConstructor->IsContentFrame() | ||||||
2145 | ? pConstructor->IsTextFrame() | ||||||
2146 | ? static_cast<const SwTextFrame*>(pConstructor)->GetTextNodeForParaProps()->GetSwAttrSet() | ||||||
2147 | : static_cast<const SwNoTextFrame*>(pConstructor)->GetNode()->GetSwAttrSet() | ||||||
2148 | : static_cast<const SwLayoutFrame*>(pConstructor)->GetFormat()->GetAttrSet()) | ||||||
2149 | , m_rUL(m_rAttrSet.GetULSpace()) | ||||||
2150 | // #i96772# | ||||||
2151 | // LRSpaceItem is copied due to the possibility that it is adjusted - see below | ||||||
2152 | , m_rLR(m_rAttrSet.GetLRSpace().Clone()) | ||||||
2153 | , m_rBox(m_rAttrSet.GetBox()) | ||||||
2154 | , m_rShadow(m_rAttrSet.GetShadow()) | ||||||
2155 | , m_aFrameSize(m_rAttrSet.GetFrameSize().GetSize()) | ||||||
2156 | , m_bIsLine(false) | ||||||
2157 | , m_bJoinedWithPrev(false) | ||||||
2158 | , m_bJoinedWithNext(false) | ||||||
2159 | , m_nTopLine(0) | ||||||
2160 | , m_nBottomLine(0) | ||||||
2161 | , m_nLeftLine(0) | ||||||
2162 | , m_nRightLine(0) | ||||||
2163 | , m_nTop(0) | ||||||
2164 | , m_nBottom(0) | ||||||
2165 | , m_nGetTopLine(0) | ||||||
2166 | , m_nGetBottomLine(0) | ||||||
2167 | , m_nLineSpacing(0) | ||||||
2168 | { | ||||||
2169 | // #i96772# | ||||||
2170 | const SwTextFrame* pTextFrame = dynamic_cast<const SwTextFrame*>(pConstructor); | ||||||
2171 | if ( pTextFrame ) | ||||||
2172 | { | ||||||
2173 | pTextFrame->GetTextNodeForParaProps()->ClearLRSpaceItemDueToListLevelIndents( m_rLR ); | ||||||
2174 | } | ||||||
2175 | else if ( pConstructor->IsNoTextFrame() ) | ||||||
2176 | { | ||||||
2177 | m_rLR = std::make_shared<SvxLRSpaceItem>(RES_LR_SPACE); | ||||||
2178 | } | ||||||
2179 | |||||||
2180 | // Caution: The USHORTs for the cached values are not initialized by intention! | ||||||
2181 | |||||||
2182 | // everything needs to be calculated at least once: | ||||||
2183 | m_bTopLine = m_bBottomLine = m_bLeftLine = m_bRightLine = | ||||||
2184 | m_bTop = m_bBottom = m_bLine = true; | ||||||
2185 | |||||||
2186 | // except this one: calculate line spacing before cell border only for text frames | ||||||
2187 | m_bLineSpacing = bool(pTextFrame); | ||||||
2188 | |||||||
2189 | m_bCacheGetLine = m_bCachedGetTopLine = m_bCachedGetBottomLine = false; | ||||||
2190 | // OD 21.05.2003 #108789# - init cache status for values <m_bJoinedWithPrev> | ||||||
2191 | // and <m_bJoinedWithNext>, which aren't initialized by default. | ||||||
2192 | m_bCachedJoinedWithPrev = false; | ||||||
2193 | m_bCachedJoinedWithNext = false; | ||||||
2194 | } | ||||||
2195 | |||||||
2196 | SwBorderAttrs::~SwBorderAttrs() | ||||||
2197 | { | ||||||
2198 | const_cast<SwModify *>(static_cast<SwModify const *>(m_pOwner))->SetInCache( false ); | ||||||
2199 | } | ||||||
2200 | |||||||
2201 | /* All calc methods calculate a safety distance in addition to the values given by the attributes. | ||||||
2202 | * This safety distance is only added when working with borders and/or shadows to prevent that | ||||||
2203 | * e.g. borders are painted over. | ||||||
2204 | */ | ||||||
2205 | |||||||
2206 | void SwBorderAttrs::CalcTop_() | ||||||
2207 | { | ||||||
2208 | m_nTop = CalcTopLine() + m_rUL.GetUpper(); | ||||||
2209 | m_bTop = false; | ||||||
2210 | } | ||||||
2211 | |||||||
2212 | void SwBorderAttrs::CalcBottom_() | ||||||
2213 | { | ||||||
2214 | m_nBottom = CalcBottomLine() + m_rUL.GetLower(); | ||||||
2215 | m_bBottom = false; | ||||||
2216 | } | ||||||
2217 | |||||||
2218 | long SwBorderAttrs::CalcRight( const SwFrame* pCaller ) const | ||||||
2219 | { | ||||||
2220 | long nRight=0; | ||||||
2221 | |||||||
2222 | if (!pCaller->IsTextFrame() || !static_cast<const SwTextFrame*>(pCaller)->GetDoc().GetDocumentSettingManager().get(DocumentSettingId::INVERT_BORDER_SPACING)) { | ||||||
2223 | // OD 23.01.2003 #106895# - for cell frame in R2L text direction the left | ||||||
2224 | // and right border are painted on the right respectively left. | ||||||
2225 | if ( pCaller->IsCellFrame() && pCaller->IsRightToLeft() ) | ||||||
2226 | nRight = CalcLeftLine(); | ||||||
2227 | else | ||||||
2228 | nRight = CalcRightLine(); | ||||||
2229 | |||||||
2230 | } | ||||||
2231 | // for paragraphs, "left" is "before text" and "right" is "after text" | ||||||
2232 | if ( pCaller->IsTextFrame() && pCaller->IsRightToLeft() ) | ||||||
2233 | nRight += m_rLR->GetLeft(); | ||||||
2234 | else | ||||||
2235 | nRight += m_rLR->GetRight(); | ||||||
2236 | |||||||
2237 | // correction: retrieve left margin for numbering in R2L-layout | ||||||
2238 | if ( pCaller->IsTextFrame() && pCaller->IsRightToLeft() ) | ||||||
2239 | { | ||||||
2240 | nRight += static_cast<const SwTextFrame*>(pCaller)->GetTextNodeForParaProps()->GetLeftMarginWithNum(); | ||||||
2241 | } | ||||||
2242 | |||||||
2243 | return nRight; | ||||||
2244 | } | ||||||
2245 | |||||||
2246 | /// Tries to detect if this paragraph has a floating table attached. | ||||||
2247 | static bool lcl_hasTabFrame(const SwTextFrame* pTextFrame) | ||||||
2248 | { | ||||||
2249 | if (pTextFrame->GetDrawObjs()) | ||||||
2250 | { | ||||||
2251 | const SwSortedObjs* pSortedObjs = pTextFrame->GetDrawObjs(); | ||||||
2252 | if (pSortedObjs->size() > 0) | ||||||
2253 | { | ||||||
2254 | SwAnchoredObject* pObject = (*pSortedObjs)[0]; | ||||||
2255 | if (dynamic_cast<const SwFlyFrame*>(pObject) != nullptr) | ||||||
2256 | { | ||||||
2257 | SwFlyFrame* pFly = static_cast<SwFlyFrame*>(pObject); | ||||||
2258 | if (pFly->Lower() && pFly->Lower()->IsTabFrame()) | ||||||
2259 | return true; | ||||||
2260 | } | ||||||
2261 | } | ||||||
2262 | } | ||||||
2263 | return false; | ||||||
2264 | } | ||||||
2265 | |||||||
2266 | long SwBorderAttrs::CalcLeft( const SwFrame *pCaller ) const | ||||||
2267 | { | ||||||
2268 | long nLeft=0; | ||||||
2269 | |||||||
2270 | if (!pCaller->IsTextFrame() || !static_cast<const SwTextFrame*>(pCaller)->GetDoc().GetDocumentSettingManager().get(DocumentSettingId::INVERT_BORDER_SPACING)) | ||||||
2271 | { | ||||||
2272 | // OD 23.01.2003 #106895# - for cell frame in R2L text direction the left | ||||||
2273 | // and right border are painted on the right respectively left. | ||||||
2274 | if ( pCaller->IsCellFrame() && pCaller->IsRightToLeft() ) | ||||||
2275 | nLeft = CalcRightLine(); | ||||||
2276 | else | ||||||
2277 | nLeft = CalcLeftLine(); | ||||||
2278 | } | ||||||
2279 | |||||||
2280 | // for paragraphs, "left" is "before text" and "right" is "after text" | ||||||
2281 | if ( pCaller->IsTextFrame() && pCaller->IsRightToLeft() ) | ||||||
2282 | nLeft += m_rLR->GetRight(); | ||||||
2283 | else | ||||||
2284 | { | ||||||
2285 | bool bIgnoreMargin = false; | ||||||
2286 | if (pCaller->IsTextFrame()) | ||||||
2287 | { | ||||||
2288 | const SwTextFrame* pTextFrame = static_cast<const SwTextFrame*>(pCaller); | ||||||
2289 | if (pTextFrame->GetDoc().GetDocumentSettingManager().get(DocumentSettingId::FLOATTABLE_NOMARGINS)) | ||||||
2290 | { | ||||||
2291 | // If this is explicitly requested, ignore the margins next to the floating table. | ||||||
2292 | if (lcl_hasTabFrame(pTextFrame)) | ||||||
2293 | bIgnoreMargin = true; | ||||||
2294 | // TODO here we only handle the first two paragraphs, would be nice to generalize this. | ||||||
2295 | else if (pTextFrame->FindPrev() && pTextFrame->FindPrev()->IsTextFrame() && lcl_hasTabFrame(static_cast<const SwTextFrame*>(pTextFrame->FindPrev()))) | ||||||
2296 | bIgnoreMargin = true; | ||||||
2297 | } | ||||||
2298 | } | ||||||
2299 | if (!bIgnoreMargin) | ||||||
2300 | nLeft += m_rLR->GetLeft(); | ||||||
2301 | } | ||||||
2302 | |||||||
2303 | // correction: do not retrieve left margin for numbering in R2L-layout | ||||||
2304 | if ( pCaller->IsTextFrame() && !pCaller->IsRightToLeft() ) | ||||||
2305 | { | ||||||
2306 | nLeft += static_cast<const SwTextFrame*>(pCaller)->GetTextNodeForParaProps()->GetLeftMarginWithNum(); | ||||||
2307 | } | ||||||
2308 | |||||||
2309 | return nLeft; | ||||||
2310 | } | ||||||
2311 | |||||||
2312 | /* Calculated values for borders and shadows. | ||||||
2313 | * It might be that a distance is wanted even without lines. This will be | ||||||
2314 | * considered here and not by the attribute (e.g. bBorderDist for cells). | ||||||
2315 | */ | ||||||
2316 | |||||||
2317 | void SwBorderAttrs::CalcTopLine_() | ||||||
2318 | { | ||||||
2319 | m_nTopLine = m_rBox.CalcLineSpace( SvxBoxItemLine::TOP, /*bEvenIfNoLine*/true ); | ||||||
2320 | m_nTopLine = m_nTopLine + m_rShadow.CalcShadowSpace(SvxShadowItemSide::TOP); | ||||||
2321 | m_bTopLine = false; | ||||||
2322 | } | ||||||
2323 | |||||||
2324 | void SwBorderAttrs::CalcBottomLine_() | ||||||
2325 | { | ||||||
2326 | m_nBottomLine = m_rBox.CalcLineSpace( SvxBoxItemLine::BOTTOM, true ); | ||||||
2327 | m_nBottomLine = m_nBottomLine + m_rShadow.CalcShadowSpace(SvxShadowItemSide::BOTTOM); | ||||||
2328 | m_bBottomLine = false; | ||||||
2329 | } | ||||||
2330 | |||||||
2331 | void SwBorderAttrs::CalcLeftLine_() | ||||||
2332 | { | ||||||
2333 | m_nLeftLine = m_rBox.CalcLineSpace( SvxBoxItemLine::LEFT, true); | ||||||
2334 | m_nLeftLine = m_nLeftLine + m_rShadow.CalcShadowSpace(SvxShadowItemSide::LEFT); | ||||||
2335 | m_bLeftLine = false; | ||||||
2336 | } | ||||||
2337 | |||||||
2338 | void SwBorderAttrs::CalcRightLine_() | ||||||
2339 | { | ||||||
2340 | m_nRightLine = m_rBox.CalcLineSpace( SvxBoxItemLine::RIGHT, true ); | ||||||
2341 | m_nRightLine = m_nRightLine + m_rShadow.CalcShadowSpace(SvxShadowItemSide::RIGHT); | ||||||
2342 | m_bRightLine = false; | ||||||
2343 | } | ||||||
2344 | |||||||
2345 | void SwBorderAttrs::IsLine_() | ||||||
2346 | { | ||||||
2347 | m_bIsLine = m_rBox.GetTop() || m_rBox.GetBottom() || | ||||||
2348 | m_rBox.GetLeft()|| m_rBox.GetRight(); | ||||||
2349 | m_bLine = false; | ||||||
2350 | } | ||||||
2351 | |||||||
2352 | /* The borders of neighboring paragraphs are condensed by following algorithm: | ||||||
2353 | * | ||||||
2354 | * 1. No top border if the predecessor has the same top border and (3) applies. | ||||||
2355 | * In addition, the paragraph needs to have a border at least one side (left/right/bottom). | ||||||
2356 | * 2. No bottom border if the successor has the same bottom border and (3) applies. | ||||||
2357 | * In addition, the paragraph needs to have a border at least one side (left/right/top). | ||||||
2358 | * 3. The borders on the left and right side are identical between the current and the | ||||||
2359 | * pre-/succeeding paragraph. | ||||||
2360 | */ | ||||||
2361 | |||||||
2362 | static bool CmpLines( const editeng::SvxBorderLine *pL1, const editeng::SvxBorderLine *pL2 ) | ||||||
2363 | { | ||||||
2364 | return ( ((pL1 && pL2) && (*pL1 == *pL2)) || (!pL1 && !pL2) ); | ||||||
2365 | } | ||||||
2366 | |||||||
2367 | // OD 21.05.2003 #108789# - change name of 1st parameter - "rAttrs" -> "rCmpAttrs" | ||||||
2368 | // OD 21.05.2003 #108789# - compare <CalcRight()> and <rCmpAttrs.CalcRight()> | ||||||
2369 | // instead of only the right LR-spacing, because R2L-layout has to be | ||||||
2370 | // considered. | ||||||
2371 | bool SwBorderAttrs::CmpLeftRight( const SwBorderAttrs &rCmpAttrs, | ||||||
2372 | const SwFrame *pCaller, | ||||||
2373 | const SwFrame *pCmp ) const | ||||||
2374 | { | ||||||
2375 | return ( CmpLines( rCmpAttrs.GetBox().GetLeft(), GetBox().GetLeft() ) && | ||||||
2376 | CmpLines( rCmpAttrs.GetBox().GetRight(),GetBox().GetRight() ) && | ||||||
2377 | CalcLeft( pCaller ) == rCmpAttrs.CalcLeft( pCmp ) && | ||||||
2378 | // OD 21.05.2003 #108789# - compare <CalcRight> with <rCmpAttrs.CalcRight>. | ||||||
2379 | CalcRight( pCaller ) == rCmpAttrs.CalcRight( pCmp ) ); | ||||||
2380 | } | ||||||
2381 | |||||||
2382 | bool SwBorderAttrs::JoinWithCmp( const SwFrame& _rCallerFrame, | ||||||
2383 | const SwFrame& _rCmpFrame ) const | ||||||
2384 | { | ||||||
2385 | bool bReturnVal = false; | ||||||
2386 | |||||||
2387 | SwBorderAttrAccess aCmpAccess( SwFrame::GetCache(), &_rCmpFrame ); | ||||||
2388 | const SwBorderAttrs &rCmpAttrs = *aCmpAccess.Get(); | ||||||
2389 | if ( m_rShadow == rCmpAttrs.GetShadow() && | ||||||
2390 | CmpLines( m_rBox.GetTop(), rCmpAttrs.GetBox().GetTop() ) && | ||||||
2391 | CmpLines( m_rBox.GetBottom(), rCmpAttrs.GetBox().GetBottom() ) && | ||||||
2392 | CmpLeftRight( rCmpAttrs, &_rCallerFrame, &_rCmpFrame ) | ||||||
2393 | ) | ||||||
2394 | { | ||||||
2395 | bReturnVal = true; | ||||||
2396 | } | ||||||
2397 | |||||||
2398 | return bReturnVal; | ||||||
2399 | } | ||||||
2400 | |||||||
2401 | // OD 21.05.2003 #108789# - method to determine, if borders are joined with | ||||||
2402 | // previous frame. Calculated value saved in cached value <m_bJoinedWithPrev> | ||||||
2403 | // OD 2004-02-26 #i25029# - add 2nd parameter <_pPrevFrame> | ||||||
2404 | void SwBorderAttrs::CalcJoinedWithPrev( const SwFrame& _rFrame, | ||||||
2405 | const SwFrame* _pPrevFrame ) | ||||||
2406 | { | ||||||
2407 | // set default | ||||||
2408 | m_bJoinedWithPrev = false; | ||||||
2409 | |||||||
2410 | if ( _rFrame.IsTextFrame() ) | ||||||
2411 | { | ||||||
2412 | // text frame can potentially join with previous text frame, if | ||||||
2413 | // corresponding attribute set is set at previous text frame. | ||||||
2414 | // OD 2004-02-26 #i25029# - If parameter <_pPrevFrame> is set, take this | ||||||
2415 | // one as previous frame. | ||||||
2416 | const SwFrame* pPrevFrame = _pPrevFrame ? _pPrevFrame : _rFrame.GetPrev(); | ||||||
2417 | // OD 2004-02-13 #i25029# - skip hidden text frames. | ||||||
2418 | while ( pPrevFrame && pPrevFrame->IsTextFrame() && | ||||||
2419 | static_cast<const SwTextFrame*>(pPrevFrame)->IsHiddenNow() ) | ||||||
2420 | { | ||||||
2421 | pPrevFrame = pPrevFrame->GetPrev(); | ||||||
2422 | } | ||||||
2423 | if ( pPrevFrame && pPrevFrame->IsTextFrame() && | ||||||
2424 | pPrevFrame->GetAttrSet()->GetParaConnectBorder().GetValue() | ||||||
2425 | ) | ||||||
2426 | { | ||||||
2427 | m_bJoinedWithPrev = JoinWithCmp( _rFrame, *pPrevFrame ); | ||||||
2428 | } | ||||||
2429 | } | ||||||
2430 | |||||||
2431 | // valid cache status, if demanded | ||||||
2432 | // OD 2004-02-26 #i25029# - Do not validate cache, if parameter <_pPrevFrame> | ||||||
2433 | // is set. | ||||||
2434 | m_bCachedJoinedWithPrev = m_bCacheGetLine && !_pPrevFrame; | ||||||
2435 | } | ||||||
2436 | |||||||
2437 | // OD 21.05.2003 #108789# - method to determine, if borders are joined with | ||||||
2438 | // next frame. Calculated value saved in cached value <m_bJoinedWithNext> | ||||||
2439 | void SwBorderAttrs::CalcJoinedWithNext( const SwFrame& _rFrame ) | ||||||
2440 | { | ||||||
2441 | // set default | ||||||
2442 | m_bJoinedWithNext = false; | ||||||
2443 | |||||||
2444 | if ( _rFrame.IsTextFrame() ) | ||||||
2445 | { | ||||||
2446 | // text frame can potentially join with next text frame, if | ||||||
2447 | // corresponding attribute set is set at current text frame. | ||||||
2448 | // OD 2004-02-13 #i25029# - get next frame, but skip hidden text frames. | ||||||
2449 | const SwFrame* pNextFrame = _rFrame.GetNext(); | ||||||
2450 | while ( pNextFrame && pNextFrame->IsTextFrame() && | ||||||
2451 | static_cast<const SwTextFrame*>(pNextFrame)->IsHiddenNow() ) | ||||||
2452 | { | ||||||
2453 | pNextFrame = pNextFrame->GetNext(); | ||||||
2454 | } | ||||||
2455 | if ( pNextFrame && pNextFrame->IsTextFrame() && | ||||||
2456 | _rFrame.GetAttrSet()->GetParaConnectBorder().GetValue() | ||||||
2457 | ) | ||||||
2458 | { | ||||||
2459 | m_bJoinedWithNext = JoinWithCmp( _rFrame, *pNextFrame ); | ||||||
2460 | } | ||||||
2461 | } | ||||||
2462 | |||||||
2463 | // valid cache status, if demanded | ||||||
2464 | m_bCachedJoinedWithNext = m_bCacheGetLine; | ||||||
2465 | } | ||||||
2466 | |||||||
2467 | // OD 21.05.2003 #108789# - accessor for cached values <m_bJoinedWithPrev> | ||||||
2468 | // OD 2004-02-26 #i25029# - add 2nd parameter <_pPrevFrame>, which is passed to | ||||||
2469 | // method <_CalcJoindWithPrev(..)>. | ||||||
2470 | bool SwBorderAttrs::JoinedWithPrev( const SwFrame& _rFrame, | ||||||
2471 | const SwFrame* _pPrevFrame ) const | ||||||
2472 | { | ||||||
2473 | if ( !m_bCachedJoinedWithPrev || _pPrevFrame ) | ||||||
2474 | { | ||||||
2475 | // OD 2004-02-26 #i25029# - pass <_pPrevFrame> as 2nd parameter | ||||||
2476 | const_cast<SwBorderAttrs*>(this)->CalcJoinedWithPrev( _rFrame, _pPrevFrame ); | ||||||
2477 | } | ||||||
2478 | |||||||
2479 | return m_bJoinedWithPrev; | ||||||
2480 | } | ||||||
2481 | |||||||
2482 | bool SwBorderAttrs::JoinedWithNext( const SwFrame& _rFrame ) const | ||||||
2483 | { | ||||||
2484 | if ( !m_bCachedJoinedWithNext ) | ||||||
2485 | { | ||||||
2486 | const_cast<SwBorderAttrs*>(this)->CalcJoinedWithNext( _rFrame ); | ||||||
2487 | } | ||||||
2488 | |||||||
2489 | return m_bJoinedWithNext; | ||||||
2490 | } | ||||||
2491 | |||||||
2492 | // OD 2004-02-26 #i25029# - added 2nd parameter <_pPrevFrame>, which is passed to | ||||||
2493 | // method <JoinedWithPrev> | ||||||
2494 | void SwBorderAttrs::GetTopLine_( const SwFrame& _rFrame, | ||||||
2495 | const SwFrame* _pPrevFrame ) | ||||||
2496 | { | ||||||
2497 | sal_uInt16 nRet = CalcTopLine(); | ||||||
2498 | |||||||
2499 | // OD 21.05.2003 #108789# - use new method <JoinWithPrev()> | ||||||
2500 | // OD 2004-02-26 #i25029# - add 2nd parameter | ||||||
2501 | if ( JoinedWithPrev( _rFrame, _pPrevFrame ) ) | ||||||
2502 | { | ||||||
2503 | nRet = 0; | ||||||
2504 | } | ||||||
2505 | |||||||
2506 | m_bCachedGetTopLine = m_bCacheGetLine; | ||||||
2507 | |||||||
2508 | m_nGetTopLine = nRet; | ||||||
2509 | } | ||||||
2510 | |||||||
2511 | void SwBorderAttrs::GetBottomLine_( const SwFrame& _rFrame ) | ||||||
2512 | { | ||||||
2513 | sal_uInt16 nRet = CalcBottomLine(); | ||||||
2514 | |||||||
2515 | // OD 21.05.2003 #108789# - use new method <JoinWithPrev()> | ||||||
2516 | if ( JoinedWithNext( _rFrame ) ) | ||||||
2517 | { | ||||||
2518 | nRet = 0; | ||||||
2519 | } | ||||||
2520 | |||||||
2521 | m_bCachedGetBottomLine = m_bCacheGetLine; | ||||||
2522 | |||||||
2523 | m_nGetBottomLine = nRet; | ||||||
2524 | } | ||||||
2525 | |||||||
2526 | void SwBorderAttrs::CalcLineSpacing_() | ||||||
2527 | { | ||||||
2528 | // tdf#125300 compatibility option AddParaLineSpacingToTableCells needs also line spacing | ||||||
2529 | const SvxLineSpacingItem &rSpace = m_rAttrSet.GetLineSpacing(); | ||||||
2530 | if ( rSpace.GetInterLineSpaceRule() == SvxInterLineSpaceRule::Prop && rSpace.GetPropLineSpace() > 100 ) | ||||||
2531 | { | ||||||
2532 | sal_Int32 nFontSize = m_rAttrSet.Get(RES_CHRATR_FONTSIZE).GetHeight(); | ||||||
2533 | m_nLineSpacing = nFontSize * (rSpace.GetPropLineSpace() - 100) * 1.15 / 100; | ||||||
2534 | } | ||||||
2535 | m_bLineSpacing = false; | ||||||
2536 | } | ||||||
2537 | |||||||
2538 | static SwModify const* GetCacheOwner(SwFrame const& rFrame) | ||||||
2539 | { | ||||||
2540 | return rFrame.IsContentFrame() | ||||||
2541 | ? static_cast<SwModify const*>(rFrame.IsTextFrame() | ||||||
2542 | // sw_redlinehide: presumably this caches the border attrs at the model level and can be shared across different layouts so we want the ParaProps node here | ||||||
2543 | ? static_cast<const SwTextFrame&>(rFrame).GetTextNodeForParaProps() | ||||||
2544 | : static_cast<const SwNoTextFrame&>(rFrame).GetNode()) | ||||||
2545 | : static_cast<SwModify const*>(static_cast<const SwLayoutFrame&>(rFrame).GetFormat()); | ||||||
2546 | } | ||||||
2547 | |||||||
2548 | SwBorderAttrAccess::SwBorderAttrAccess( SwCache &rCach, const SwFrame *pFrame ) : | ||||||
2549 | SwCacheAccess( rCach, | ||||||
2550 | static_cast<void const *>(GetCacheOwner(*pFrame)), | ||||||
2551 | GetCacheOwner(*pFrame)->IsInCache()), | ||||||
2552 | m_pConstructor( pFrame ) | ||||||
2553 | { | ||||||
2554 | } | ||||||
2555 | |||||||
2556 | SwCacheObj *SwBorderAttrAccess::NewObj() | ||||||
2557 | { | ||||||
2558 | const_cast<SwModify *>(static_cast<SwModify const *>(m_pOwner))->SetInCache( true ); | ||||||
2559 | return new SwBorderAttrs( static_cast<SwModify const *>(m_pOwner), m_pConstructor ); | ||||||
2560 | } | ||||||
2561 | |||||||
2562 | SwBorderAttrs *SwBorderAttrAccess::Get() | ||||||
2563 | { | ||||||
2564 | return static_cast<SwBorderAttrs*>(SwCacheAccess::Get()); | ||||||
2565 | } | ||||||
2566 | |||||||
2567 | SwOrderIter::SwOrderIter( const SwPageFrame *pPg ) : | ||||||
2568 | m_pPage( pPg ), | ||||||
2569 | m_pCurrent( nullptr ) | ||||||
2570 | { | ||||||
2571 | } | ||||||
2572 | |||||||
2573 | void SwOrderIter::Top() | ||||||
2574 | { | ||||||
2575 | m_pCurrent = nullptr; | ||||||
2576 | if ( !m_pPage->GetSortedObjs() ) | ||||||
2577 | return; | ||||||
2578 | |||||||
2579 | const SwSortedObjs *pObjs = m_pPage->GetSortedObjs(); | ||||||
2580 | if ( !pObjs->size() ) | ||||||
2581 | return; | ||||||
2582 | |||||||
2583 | sal_uInt32 nTopOrd = 0; | ||||||
2584 | (*pObjs)[0]->GetDrawObj()->GetOrdNum(); // force updating | ||||||
2585 | for (SwAnchoredObject* i : *pObjs) | ||||||
2586 | { | ||||||
2587 | const SdrObject* pObj = i->GetDrawObj(); | ||||||
2588 | if ( dynamic_cast<const SwVirtFlyDrawObj*>( pObj) == nullptr ) | ||||||
2589 | continue; | ||||||
2590 | sal_uInt32 nTmp = pObj->GetOrdNumDirect(); | ||||||
2591 | if ( nTmp >= nTopOrd ) | ||||||
2592 | { | ||||||
2593 | nTopOrd = nTmp; | ||||||
2594 | m_pCurrent = pObj; | ||||||
2595 | } | ||||||
2596 | } | ||||||
2597 | } | ||||||
2598 | |||||||
2599 | const SdrObject *SwOrderIter::Bottom() | ||||||
2600 | { | ||||||
2601 | m_pCurrent = nullptr; | ||||||
2602 | if ( m_pPage->GetSortedObjs() ) | ||||||
2603 | { | ||||||
2604 | sal_uInt32 nBotOrd = USHRT_MAX(32767 *2 +1); | ||||||
2605 | const SwSortedObjs *pObjs = m_pPage->GetSortedObjs(); | ||||||
2606 | if ( pObjs->size() ) | ||||||
2607 | { | ||||||
2608 | (*pObjs)[0]->GetDrawObj()->GetOrdNum(); // force updating | ||||||
2609 | for (SwAnchoredObject* i : *pObjs) | ||||||
2610 | { | ||||||
2611 | const SdrObject* pObj = i->GetDrawObj(); | ||||||
2612 | if ( dynamic_cast<const SwVirtFlyDrawObj*>( pObj) == nullptr ) | ||||||
2613 | continue; | ||||||
2614 | sal_uInt32 nTmp = pObj->GetOrdNumDirect(); | ||||||
2615 | if ( nTmp < nBotOrd ) | ||||||
2616 | { | ||||||
2617 | nBotOrd = nTmp; | ||||||
2618 | m_pCurrent = pObj; | ||||||
2619 | } | ||||||
2620 | } | ||||||
2621 | } | ||||||
2622 | } | ||||||
2623 | return m_pCurrent; | ||||||
2624 | } | ||||||
2625 | |||||||
2626 | const SdrObject *SwOrderIter::Next() | ||||||
2627 | { | ||||||
2628 | const sal_uInt32 nCurOrd = m_pCurrent ? m_pCurrent->GetOrdNumDirect() : 0; | ||||||
2629 | m_pCurrent = nullptr; | ||||||
2630 | if ( m_pPage->GetSortedObjs() ) | ||||||
2631 | { | ||||||
2632 | sal_uInt32 nOrd = USHRT_MAX(32767 *2 +1); | ||||||
2633 | const SwSortedObjs *pObjs = m_pPage->GetSortedObjs(); | ||||||
2634 | if ( pObjs->size() ) | ||||||
2635 | { | ||||||
2636 | (*pObjs)[0]->GetDrawObj()->GetOrdNum(); // force updating | ||||||
2637 | for (SwAnchoredObject* i : *pObjs) | ||||||
2638 | { | ||||||
2639 | const SdrObject* pObj = i->GetDrawObj(); | ||||||
2640 | if ( dynamic_cast<const SwVirtFlyDrawObj*>( pObj) == nullptr ) | ||||||
2641 | continue; | ||||||
2642 | sal_uInt32 nTmp = pObj->GetOrdNumDirect(); | ||||||
2643 | if ( nTmp > nCurOrd && nTmp < nOrd ) | ||||||
2644 | { | ||||||
2645 | nOrd = nTmp; | ||||||
2646 | m_pCurrent = pObj; | ||||||
2647 | } | ||||||
2648 | } | ||||||
2649 | } | ||||||
2650 | } | ||||||
2651 | return m_pCurrent; | ||||||
2652 | } | ||||||
2653 | |||||||
2654 | void SwOrderIter::Prev() | ||||||
2655 | { | ||||||
2656 | const sal_uInt32 nCurOrd = m_pCurrent ? m_pCurrent->GetOrdNumDirect() : 0; | ||||||
2657 | m_pCurrent = nullptr; | ||||||
2658 | if ( !m_pPage->GetSortedObjs() ) | ||||||
2659 | return; | ||||||
2660 | |||||||
2661 | const SwSortedObjs *pObjs = m_pPage->GetSortedObjs(); | ||||||
2662 | if ( !pObjs->size() ) | ||||||
2663 | return; | ||||||
2664 | |||||||
2665 | sal_uInt32 nOrd = 0; | ||||||
2666 | (*pObjs)[0]->GetDrawObj()->GetOrdNum(); // force updating | ||||||
2667 | for (SwAnchoredObject* i : *pObjs) | ||||||
2668 | { | ||||||
2669 | const SdrObject* pObj = i->GetDrawObj(); | ||||||
2670 | if ( dynamic_cast<const SwVirtFlyDrawObj*>( pObj) == nullptr ) | ||||||
2671 | continue; | ||||||
2672 | sal_uInt32 nTmp = pObj->GetOrdNumDirect(); | ||||||
2673 | if ( nTmp < nCurOrd && nTmp >= nOrd ) | ||||||
2674 | { | ||||||
2675 | nOrd = nTmp; | ||||||
2676 | m_pCurrent = pObj; | ||||||
2677 | } | ||||||
2678 | } | ||||||
2679 | } | ||||||
2680 | |||||||
2681 | /// Keep and restore the substructure of a layout frame for an action. | ||||||
2682 | // New algorithm: | ||||||
2683 | // Do not look at each neighbor one by one to set all pointers correctly. | ||||||
2684 | // It is sufficient to detach a part of a chain and check if another chain needs to be added | ||||||
2685 | // when attaching it again. Only the pointers necessary for the chain connection need to be | ||||||
2686 | // adjusted. The correction happens in RestoreContent(). In between all access is restricted. | ||||||
2687 | // During this action, the Flys are detached from the page. | ||||||
2688 | |||||||
2689 | // #115759# - 'remove' also drawing object from page and | ||||||
2690 | // at-fly anchored objects from page | ||||||
2691 | static void lcl_RemoveObjsFromPage( SwFrame* _pFrame ) | ||||||
2692 | { | ||||||
2693 | OSL_ENSURE( _pFrame->GetDrawObjs(), "no DrawObjs in lcl_RemoveObjsFromPage." )do { if (true && (!(_pFrame->GetDrawObjs()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "2693" ": "), "%s", "no DrawObjs in lcl_RemoveObjsFromPage." ); } } while (false); | ||||||
2694 | SwSortedObjs &rObjs = *_pFrame->GetDrawObjs(); | ||||||
2695 | for (SwAnchoredObject* pObj : rObjs) | ||||||
2696 | { | ||||||
2697 | // #115759# - reset member, at which the anchored | ||||||
2698 | // object orients its vertical position | ||||||
2699 | pObj->ClearVertPosOrientFrame(); | ||||||
2700 | // #i43913# | ||||||
2701 | pObj->ResetLayoutProcessBools(); | ||||||
2702 | // #115759# - remove also lower objects of as-character | ||||||
2703 | // anchored Writer fly frames from page | ||||||
2704 | if ( dynamic_cast<const SwFlyFrame*>( pObj) != nullptr ) | ||||||
2705 | { | ||||||
2706 | SwFlyFrame* pFlyFrame = static_cast<SwFlyFrame*>(pObj); | ||||||
2707 | |||||||
2708 | // #115759# - remove also direct lowers of Writer | ||||||
2709 | // fly frame from page | ||||||
2710 | if ( pFlyFrame->GetDrawObjs() ) | ||||||
2711 | { | ||||||
2712 | ::lcl_RemoveObjsFromPage( pFlyFrame ); | ||||||
2713 | } | ||||||
2714 | |||||||
2715 | SwContentFrame* pCnt = pFlyFrame->ContainsContent(); | ||||||
2716 | while ( pCnt ) | ||||||
2717 | { | ||||||
2718 | if ( pCnt->GetDrawObjs() ) | ||||||
2719 | ::lcl_RemoveObjsFromPage( pCnt ); | ||||||
2720 | pCnt = pCnt->GetNextContentFrame(); | ||||||
2721 | } | ||||||
2722 | if ( pFlyFrame->IsFlyFreeFrame() ) | ||||||
2723 | { | ||||||
2724 | // #i28701# - use new method <GetPageFrame()> | ||||||
2725 | if (SwPageFrame *pPg = pFlyFrame->GetPageFrame()) | ||||||
2726 | pPg->RemoveFlyFromPage(pFlyFrame); | ||||||
2727 | } | ||||||
2728 | } | ||||||
2729 | // #115759# - remove also drawing objects from page | ||||||
2730 | else if ( dynamic_cast<const SwAnchoredDrawObject*>( pObj) != nullptr ) | ||||||
2731 | { | ||||||
2732 | if (pObj->GetFrameFormat().GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR) | ||||||
2733 | { | ||||||
2734 | if (SwPageFrame *pPg = pObj->GetPageFrame()) | ||||||
2735 | pPg->RemoveDrawObjFromPage( | ||||||
2736 | *static_cast<SwAnchoredDrawObject*>(pObj) ); | ||||||
2737 | } | ||||||
2738 | } | ||||||
2739 | } | ||||||
2740 | } | ||||||
2741 | |||||||
2742 | SwFrame *SaveContent( SwLayoutFrame *pLay, SwFrame *pStart ) | ||||||
2743 | { | ||||||
2744 | if( pLay->IsSctFrame() && pLay->Lower() && pLay->Lower()->IsColumnFrame() ) | ||||||
2745 | sw_RemoveFootnotes( static_cast<SwColumnFrame*>(pLay->Lower()), true, true ); | ||||||
2746 | |||||||
2747 | SwFrame *pSav = pLay->ContainsAny(); | ||||||
2748 | if ( nullptr == pSav ) | ||||||
2749 | return nullptr; | ||||||
2750 | |||||||
2751 | if( pSav->IsInFootnote() && !pLay->IsInFootnote() ) | ||||||
2752 | { | ||||||
2753 | do | ||||||
2754 | pSav = pSav->FindNext(); | ||||||
2755 | while( pSav && pSav->IsInFootnote() ); | ||||||
2756 | if( !pSav || !pLay->IsAnLower( pSav ) ) | ||||||
2757 | return nullptr; | ||||||
2758 | } | ||||||
2759 | |||||||
2760 | // Tables should be saved as a whole, exception: | ||||||
2761 | // The contents of a section or a cell inside a table should be saved | ||||||
2762 | if ( pSav->IsInTab() && !( ( pLay->IsSctFrame() || pLay->IsCellFrame() ) && pLay->IsInTab() ) ) | ||||||
2763 | while ( !pSav->IsTabFrame() ) | ||||||
2764 | pSav = pSav->GetUpper(); | ||||||
2765 | |||||||
2766 | if( pSav->IsInSct() ) | ||||||
2767 | { // search the upmost section inside of pLay | ||||||
2768 | SwFrame* pSect = pLay->FindSctFrame(); | ||||||
2769 | SwFrame *pTmp = pSav; | ||||||
2770 | do | ||||||
2771 | { | ||||||
2772 | pSav = pTmp; | ||||||
2773 | pTmp = (pSav && pSav->GetUpper()) ? pSav->GetUpper()->FindSctFrame() : nullptr; | ||||||
2774 | } while ( pTmp != pSect ); | ||||||
2775 | } | ||||||
2776 | |||||||
2777 | SwFrame *pFloat = pSav; | ||||||
2778 | if( !pStart ) | ||||||
2779 | pStart = pSav; | ||||||
2780 | bool bGo = pStart == pSav; | ||||||
2781 | do | ||||||
2782 | { | ||||||
2783 | if( bGo ) | ||||||
2784 | pFloat->GetUpper()->m_pLower = nullptr; // detach the chain part | ||||||
2785 | |||||||
2786 | // search the end of the chain part, remove Flys on the way | ||||||
2787 | do | ||||||
2788 | { | ||||||
2789 | if( bGo ) | ||||||
2790 | { | ||||||
2791 | if ( pFloat->IsContentFrame() ) | ||||||
2792 | { | ||||||
2793 | if ( pFloat->GetDrawObjs() ) | ||||||
2794 | ::lcl_RemoveObjsFromPage( static_cast<SwContentFrame*>(pFloat) ); | ||||||
2795 | } | ||||||
2796 | else if ( pFloat->IsTabFrame() || pFloat->IsSctFrame() ) | ||||||
2797 | { | ||||||
2798 | SwContentFrame *pCnt = static_cast<SwLayoutFrame*>(pFloat)->ContainsContent(); | ||||||
2799 | if( pCnt ) | ||||||
2800 | { | ||||||
2801 | do | ||||||
2802 | { if ( pCnt->GetDrawObjs() ) | ||||||
2803 | ::lcl_RemoveObjsFromPage( pCnt ); | ||||||
2804 | pCnt = pCnt->GetNextContentFrame(); | ||||||
2805 | } while ( pCnt && static_cast<SwLayoutFrame*>(pFloat)->IsAnLower( pCnt ) ); | ||||||
2806 | } | ||||||
2807 | } | ||||||
2808 | else { | ||||||
2809 | OSL_ENSURE( !pFloat, "new FloatFrame?" )do { if (true && (!(!pFloat))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "2809" ": "), "%s", "new FloatFrame?"); } } while (false ); | ||||||
2810 | } | ||||||
2811 | } | ||||||
2812 | if ( pFloat->GetNext() ) | ||||||
2813 | { | ||||||
2814 | if( bGo ) | ||||||
2815 | pFloat->mpUpper = nullptr; | ||||||
2816 | pFloat = pFloat->GetNext(); | ||||||
2817 | if( !bGo && pFloat == pStart ) | ||||||
2818 | { | ||||||
2819 | bGo = true; | ||||||
2820 | pFloat->mpPrev->mpNext = nullptr; | ||||||
2821 | pFloat->mpPrev = nullptr; | ||||||
2822 | } | ||||||
2823 | } | ||||||
2824 | else | ||||||
2825 | break; | ||||||
2826 | |||||||
2827 | } while ( pFloat ); | ||||||
2828 | |||||||
2829 | // search next chain part and connect both chains | ||||||
2830 | SwFrame *pTmp = pFloat->FindNext(); | ||||||
2831 | if( bGo ) | ||||||
2832 | pFloat->mpUpper = nullptr; | ||||||
2833 | |||||||
2834 | if( !pLay->IsInFootnote() ) | ||||||
2835 | while( pTmp && pTmp->IsInFootnote() ) | ||||||
2836 | pTmp = pTmp->FindNext(); | ||||||
2837 | |||||||
2838 | if ( !pLay->IsAnLower( pTmp ) ) | ||||||
2839 | pTmp = nullptr; | ||||||
2840 | |||||||
2841 | if ( pTmp && bGo ) | ||||||
2842 | { | ||||||
2843 | pFloat->mpNext = pTmp; // connect both chains | ||||||
2844 | pFloat->mpNext->mpPrev = pFloat; | ||||||
2845 | } | ||||||
2846 | pFloat = pTmp; | ||||||
2847 | bGo = bGo || ( pStart == pFloat ); | ||||||
2848 | } while ( pFloat ); | ||||||
2849 | |||||||
2850 | return bGo ? pStart : nullptr; | ||||||
2851 | } | ||||||
2852 | |||||||
2853 | // #115759# - add also drawing objects to page and at-fly | ||||||
2854 | // anchored objects to page | ||||||
2855 | static void lcl_AddObjsToPage( SwFrame* _pFrame, SwPageFrame* _pPage ) | ||||||
2856 | { | ||||||
2857 | OSL_ENSURE( _pFrame->GetDrawObjs(), "no DrawObjs in lcl_AddObjsToPage." )do { if (true && (!(_pFrame->GetDrawObjs()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "2857" ": "), "%s", "no DrawObjs in lcl_AddObjsToPage.") ; } } while (false); | ||||||
2858 | SwSortedObjs &rObjs = *_pFrame->GetDrawObjs(); | ||||||
2859 | for (SwAnchoredObject* pObj : rObjs) | ||||||
2860 | { | ||||||
2861 | // #115759# - unlock position of anchored object | ||||||
2862 | // in order to get the object's position calculated. | ||||||
2863 | pObj->UnlockPosition(); | ||||||
2864 | // #115759# - add also lower objects of as-character | ||||||
2865 | // anchored Writer fly frames from page | ||||||
2866 | if ( dynamic_cast<const SwFlyFrame*>( pObj) != nullptr ) | ||||||
2867 | { | ||||||
2868 | SwFlyFrame* pFlyFrame = static_cast<SwFlyFrame*>(pObj); | ||||||
2869 | if ( dynamic_cast<const SwFlyFreeFrame*>( pObj) != nullptr ) | ||||||
2870 | { | ||||||
2871 | _pPage->AppendFlyToPage( pFlyFrame ); | ||||||
2872 | } | ||||||
2873 | pFlyFrame->InvalidatePos_(); | ||||||
2874 | pFlyFrame->InvalidateSize_(); | ||||||
2875 | pFlyFrame->InvalidatePage( _pPage ); | ||||||
2876 | |||||||
2877 | // #115759# - add also at-fly anchored objects | ||||||
2878 | // to page | ||||||
2879 | if ( pFlyFrame->GetDrawObjs() ) | ||||||
2880 | { | ||||||
2881 | ::lcl_AddObjsToPage( pFlyFrame, _pPage ); | ||||||
2882 | } | ||||||
2883 | |||||||
2884 | SwContentFrame *pCnt = pFlyFrame->ContainsContent(); | ||||||
2885 | while ( pCnt ) | ||||||
2886 | { | ||||||
2887 | if ( pCnt->GetDrawObjs() ) | ||||||
2888 | ::lcl_AddObjsToPage( pCnt, _pPage ); | ||||||
2889 | pCnt = pCnt->GetNextContentFrame(); | ||||||
2890 | } | ||||||
2891 | } | ||||||
2892 | // #115759# - remove also drawing objects from page | ||||||
2893 | else if ( dynamic_cast<const SwAnchoredDrawObject*>( pObj) != nullptr ) | ||||||
2894 | { | ||||||
2895 | if (pObj->GetFrameFormat().GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR) | ||||||
2896 | { | ||||||
2897 | pObj->InvalidateObjPos(); | ||||||
2898 | _pPage->AppendDrawObjToPage( | ||||||
2899 | *static_cast<SwAnchoredDrawObject*>(pObj) ); | ||||||
2900 | } | ||||||
2901 | } | ||||||
2902 | } | ||||||
2903 | } | ||||||
2904 | |||||||
2905 | void RestoreContent( SwFrame *pSav, SwLayoutFrame *pParent, SwFrame *pSibling ) | ||||||
2906 | { | ||||||
2907 | OSL_ENSURE( pSav && pParent, "no Save or Parent provided for RestoreContent." )do { if (true && (!(pSav && pParent))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "2907" ": "), "%s", "no Save or Parent provided for RestoreContent." ); } } while (false); | ||||||
2908 | SwRectFnSet aRectFnSet(pParent); | ||||||
2909 | |||||||
2910 | // If there are already FlowFrames below the new parent, so add the chain (starting with pSav) | ||||||
2911 | // after the last one. The parts are inserted and invalidated if needed. | ||||||
2912 | // On the way, the Flys of the ContentFrames are registered at the page. | ||||||
2913 | |||||||
2914 | SwPageFrame *pPage = pParent->FindPageFrame(); | ||||||
2915 | |||||||
2916 | if ( pPage ) | ||||||
2917 | pPage->InvalidatePage( pPage ); | ||||||
2918 | |||||||
2919 | // determine predecessor and establish connection or initialize | ||||||
2920 | pSav->mpPrev = pSibling; | ||||||
2921 | SwFrame* pNxt; | ||||||
2922 | if ( pSibling ) | ||||||
2923 | { | ||||||
2924 | pNxt = pSibling->mpNext; | ||||||
2925 | pSibling->mpNext = pSav; | ||||||
2926 | pSibling->InvalidatePrt_(); | ||||||
2927 | pSibling->InvalidatePage( pPage ); | ||||||
2928 | SwFlowFrame *pFlowFrame = dynamic_cast<SwFlowFrame*>(pSibling); | ||||||
2929 | if (pFlowFrame && pFlowFrame->GetFollow()) | ||||||
2930 | pSibling->Prepare( PrepareHint::Clear, nullptr, false ); | ||||||
2931 | } | ||||||
2932 | else | ||||||
2933 | { pNxt = pParent->m_pLower; | ||||||
2934 | pParent->m_pLower = pSav; | ||||||
2935 | pSav->mpUpper = pParent; // set here already, so that it is explicit when invalidating | ||||||
2936 | |||||||
2937 | if ( pSav->IsContentFrame() ) | ||||||
2938 | static_cast<SwContentFrame*>(pSav)->InvalidatePage( pPage ); | ||||||
2939 | else | ||||||
2940 | { // pSav might be an empty SectFrame | ||||||
2941 | SwContentFrame* pCnt = pParent->ContainsContent(); | ||||||
2942 | if( pCnt ) | ||||||
2943 | pCnt->InvalidatePage( pPage ); | ||||||
2944 | } | ||||||
2945 | } | ||||||
2946 | |||||||
2947 | // the parent needs to grow appropriately | ||||||
2948 | SwTwips nGrowVal = 0; | ||||||
2949 | SwFrame* pLast; | ||||||
2950 | do | ||||||
2951 | { pSav->mpUpper = pParent; | ||||||
2952 | nGrowVal += aRectFnSet.GetHeight(pSav->getFrameArea()); | ||||||
2953 | pSav->InvalidateAll_(); | ||||||
2954 | |||||||
2955 | // register Flys, if TextFrames than also invalidate appropriately | ||||||
2956 | if ( pSav->IsContentFrame() ) | ||||||
2957 | { | ||||||
2958 | if ( pSav->IsTextFrame() && | ||||||
2959 | static_cast<SwTextFrame*>(pSav)->GetCacheIdx() != USHRT_MAX(32767 *2 +1) ) | ||||||
2960 | static_cast<SwTextFrame*>(pSav)->Init(); // I am its friend | ||||||
2961 | |||||||
2962 | if ( pPage && pSav->GetDrawObjs() ) | ||||||
2963 | ::lcl_AddObjsToPage( static_cast<SwContentFrame*>(pSav), pPage ); | ||||||
2964 | } | ||||||
2965 | else | ||||||
2966 | { SwContentFrame *pBlub = static_cast<SwLayoutFrame*>(pSav)->ContainsContent(); | ||||||
2967 | if( pBlub ) | ||||||
2968 | { | ||||||
2969 | do | ||||||
2970 | { if ( pPage && pBlub->GetDrawObjs() ) | ||||||
2971 | ::lcl_AddObjsToPage( pBlub, pPage ); | ||||||
2972 | if( pBlub->IsTextFrame() && static_cast<SwTextFrame*>(pBlub)->HasFootnote() && | ||||||
2973 | static_cast<SwTextFrame*>(pBlub)->GetCacheIdx() != USHRT_MAX(32767 *2 +1) ) | ||||||
2974 | static_cast<SwTextFrame*>(pBlub)->Init(); // I am its friend | ||||||
2975 | pBlub = pBlub->GetNextContentFrame(); | ||||||
2976 | } while ( pBlub && static_cast<SwLayoutFrame*>(pSav)->IsAnLower( pBlub )); | ||||||
2977 | } | ||||||
2978 | } | ||||||
2979 | pLast = pSav; | ||||||
2980 | pSav = pSav->GetNext(); | ||||||
2981 | |||||||
2982 | } while ( pSav ); | ||||||
2983 | |||||||
2984 | if( pNxt ) | ||||||
2985 | { | ||||||
2986 | pLast->mpNext = pNxt; | ||||||
2987 | pNxt->mpPrev = pLast; | ||||||
2988 | } | ||||||
2989 | |||||||
2990 | pParent->Grow( nGrowVal ); | ||||||
2991 | } | ||||||
2992 | |||||||
2993 | namespace sw { | ||||||
2994 | |||||||
2995 | bool IsRightPageByNumber(SwRootFrame const& rLayout, sal_uInt16 const nPageNum) | ||||||
2996 | { | ||||||
2997 | assert(rLayout.GetLower())(static_cast <bool> (rLayout.GetLower()) ? void (0) : __assert_fail ("rLayout.GetLower()", "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 2997, __extension__ __PRETTY_FUNCTION__)); | ||||||
2998 | // unfortunately can only get SwPageDesc, not SwFormatPageDesc here... | ||||||
2999 | auto const nFirstVirtPageNum(rLayout.GetLower()->GetVirtPageNum()); | ||||||
3000 | bool const isFirstPageOfLayoutOdd(nFirstVirtPageNum % 2 == 1); | ||||||
3001 | return ((nPageNum % 2) == 1) == isFirstPageOfLayoutOdd; | ||||||
3002 | } | ||||||
3003 | |||||||
3004 | } // namespace sw | ||||||
3005 | |||||||
3006 | SwPageFrame * InsertNewPage( SwPageDesc &rDesc, SwFrame *pUpper, | ||||||
3007 | bool const isRightPage, bool const bFirst, bool bInsertEmpty, | ||||||
3008 | bool const bFootnote, | ||||||
3009 | SwFrame *pSibling, | ||||||
3010 | bool const bVeryFirstPage ) | ||||||
3011 | { | ||||||
3012 | assert(pUpper)(static_cast <bool> (pUpper) ? void (0) : __assert_fail ("pUpper", "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 3012, __extension__ __PRETTY_FUNCTION__)); | ||||||
3013 | assert(pUpper->IsRootFrame())(static_cast <bool> (pUpper->IsRootFrame()) ? void ( 0) : __assert_fail ("pUpper->IsRootFrame()", "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 3013, __extension__ __PRETTY_FUNCTION__)); | ||||||
3014 | assert(!pSibling || static_cast<SwLayoutFrame const*>(pUpper)->Lower() != pSibling)(static_cast <bool> (!pSibling || static_cast<SwLayoutFrame const*>(pUpper)->Lower() != pSibling) ? void (0) : __assert_fail ("!pSibling || static_cast<SwLayoutFrame const*>(pUpper)->Lower() != pSibling" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" , 3014, __extension__ __PRETTY_FUNCTION__)); // currently no insert before 1st page | ||||||
3015 | SwPageFrame *pRet; | ||||||
3016 | SwDoc *pDoc = static_cast<SwLayoutFrame*>(pUpper)->GetFormat()->GetDoc(); | ||||||
3017 | if (bFirst) | ||||||
3018 | { | ||||||
3019 | if (rDesc.IsFirstShared()) | ||||||
3020 | { | ||||||
3021 | // We need to fallback to left or right page format, decide it now. | ||||||
3022 | // FIXME: is this still needed? | ||||||
3023 | if (isRightPage) | ||||||
3024 | { | ||||||
3025 | rDesc.GetFirstMaster().SetFormatAttr( rDesc.GetMaster().GetHeader() ); | ||||||
3026 | rDesc.GetFirstMaster().SetFormatAttr( rDesc.GetMaster().GetFooter() ); | ||||||
3027 | // fdo#60250 copy margins for mirrored pages | ||||||
3028 | rDesc.GetFirstMaster().SetFormatAttr( rDesc.GetMaster().GetLRSpace() ); | ||||||
3029 | } | ||||||
3030 | else | ||||||
3031 | { | ||||||
3032 | rDesc.GetFirstLeft().SetFormatAttr( rDesc.GetLeft().GetHeader() ); | ||||||
3033 | rDesc.GetFirstLeft().SetFormatAttr( rDesc.GetLeft().GetFooter() ); | ||||||
3034 | rDesc.GetFirstLeft().SetFormatAttr( rDesc.GetLeft().GetLRSpace() ); | ||||||
3035 | } | ||||||
3036 | } | ||||||
3037 | } | ||||||
3038 | SwFrameFormat *pFormat(isRightPage ? rDesc.GetRightFormat(bFirst) : rDesc.GetLeftFormat(bFirst)); | ||||||
3039 | // If there is no FrameFormat for this page, add an empty page | ||||||
3040 | if ( !pFormat ) | ||||||
3041 | { | ||||||
3042 | pFormat = isRightPage ? rDesc.GetLeftFormat(bVeryFirstPage) : rDesc.GetRightFormat(bVeryFirstPage); | ||||||
3043 | OSL_ENSURE( pFormat, "Descriptor without any format?!" )do { if (true && (!(pFormat))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "3043" ": "), "%s", "Descriptor without any format?!"); } } while (false); | ||||||
3044 | bInsertEmpty = !bInsertEmpty; | ||||||
3045 | } | ||||||
3046 | if( bInsertEmpty ) | ||||||
3047 | { | ||||||
3048 | SwPageDesc *pTmpDesc = pSibling && pSibling->GetPrev() ? | ||||||
3049 | static_cast<SwPageFrame*>(pSibling->GetPrev())->GetPageDesc() : &rDesc; | ||||||
3050 | pRet = new SwPageFrame( pDoc->GetEmptyPageFormat(), pUpper, pTmpDesc ); | ||||||
3051 | SAL_INFO( "sw.pageframe", "InsertNewPage - insert empty p: " << pRet << " d: " << pTmpDesc )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "sw.pageframe")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break ; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "InsertNewPage - insert empty p: " << pRet << " d: " << pTmpDesc) == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sw.pageframe"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "3051" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "InsertNewPage - insert empty p: " << pRet << " d: " << pTmpDesc), 0); } else { ::std:: ostringstream sal_detail_stream; sal_detail_stream << "InsertNewPage - insert empty p: " << pRet << " d: " << pTmpDesc; ::sal::detail ::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sw.pageframe"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "3051" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "InsertNewPage - insert empty p: " << pRet << " d: " << pTmpDesc) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("sw.pageframe"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "3051" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "InsertNewPage - insert empty p: " << pRet << " d: " << pTmpDesc), 0); } else { ::std:: ostringstream sal_detail_stream; sal_detail_stream << "InsertNewPage - insert empty p: " << pRet << " d: " << pTmpDesc; ::sal::detail ::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sw.pageframe"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "3051" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
3052 | pRet->Paste( pUpper, pSibling ); | ||||||
3053 | pRet->PreparePage( bFootnote ); | ||||||
3054 | } | ||||||
3055 | pRet = new SwPageFrame( pFormat, pUpper, &rDesc ); | ||||||
3056 | SAL_INFO( "sw.pageframe", "InsertNewPage p: " << pRet << " d: " << &rDesc << " f: " << pFormat )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "sw.pageframe")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break ; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "InsertNewPage p: " << pRet << " d: " << &rDesc << " f: " << pFormat) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("sw.pageframe"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "3056" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "InsertNewPage p: " << pRet << " d: " << &rDesc << " f: " << pFormat) , 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "InsertNewPage p: " << pRet << " d: " << &rDesc << " f: " << pFormat; ::sal::detail:: log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sw.pageframe"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "3056" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "InsertNewPage p: " << pRet << " d: " << &rDesc << " f: " << pFormat) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sw.pageframe" ), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "3056" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "InsertNewPage p: " << pRet << " d: " << &rDesc << " f: " << pFormat) , 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "InsertNewPage p: " << pRet << " d: " << &rDesc << " f: " << pFormat; ::sal::detail:: log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sw.pageframe"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "3056" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
3057 | pRet->Paste( pUpper, pSibling ); | ||||||
3058 | pRet->PreparePage( bFootnote ); | ||||||
3059 | if ( pRet->GetNext() ) | ||||||
3060 | SwRootFrame::AssertPageFlys( pRet ); | ||||||
3061 | return pRet; | ||||||
3062 | } | ||||||
3063 | |||||||
3064 | /* The following two methods search the layout structure recursively and | ||||||
3065 | * register all Flys at the page that have a Frame in this structure as an anchor. | ||||||
3066 | */ | ||||||
3067 | |||||||
3068 | static void lcl_Regist( SwPageFrame *pPage, const SwFrame *pAnch ) | ||||||
3069 | { | ||||||
3070 | SwSortedObjs *pObjs = const_cast<SwSortedObjs*>(pAnch->GetDrawObjs()); | ||||||
3071 | for (SwAnchoredObject* pObj : *pObjs) | ||||||
3072 | { | ||||||
3073 | if (SwFlyFrame* pFly = dynamic_cast<SwFlyFrame*>(pObj)) | ||||||
3074 | { | ||||||
3075 | // register (not if already known) | ||||||
3076 | // #i28701# - use new method <GetPageFrame()> | ||||||
3077 | SwPageFrame *pPg = pFly->IsFlyFreeFrame() | ||||||
3078 | ? pFly->GetPageFrame() : pFly->FindPageFrame(); | ||||||
3079 | if ( pPg != pPage ) | ||||||
3080 | { | ||||||
3081 | if ( pPg ) | ||||||
3082 | pPg->RemoveFlyFromPage( pFly ); | ||||||
3083 | pPage->AppendFlyToPage( pFly ); | ||||||
3084 | } | ||||||
3085 | ::RegistFlys( pPage, pFly ); | ||||||
3086 | } | ||||||
3087 | else | ||||||
3088 | { | ||||||
3089 | // #i87493# | ||||||
3090 | if ( pPage != pObj->GetPageFrame() ) | ||||||
3091 | { | ||||||
3092 | // #i28701# | ||||||
3093 | if (SwPageFrame *pPg = pObj->GetPageFrame()) | ||||||
3094 | pPg->RemoveDrawObjFromPage( *pObj ); | ||||||
3095 | pPage->AppendDrawObjToPage( *pObj ); | ||||||
3096 | } | ||||||
3097 | } | ||||||
3098 | |||||||
3099 | const SwFlyFrame* pFly = pAnch->FindFlyFrame(); | ||||||
3100 | if ( pFly && | ||||||
3101 | pObj->GetDrawObj()->GetOrdNum() < pFly->GetVirtDrawObj()->GetOrdNum() && | ||||||
3102 | pObj->GetDrawObj()->getSdrPageFromSdrObject() ) | ||||||
3103 | { | ||||||
3104 | //#i119945# set pFly's OrdNum to pObj's. So when pFly is removed by Undo, the original OrdNum will not be changed. | ||||||
3105 | pObj->DrawObj()->getSdrPageFromSdrObject()->SetObjectOrdNum( pFly->GetVirtDrawObj()->GetOrdNumDirect(), | ||||||
3106 | pObj->GetDrawObj()->GetOrdNumDirect() ); | ||||||
3107 | } | ||||||
3108 | } | ||||||
3109 | } | ||||||
3110 | |||||||
3111 | void RegistFlys( SwPageFrame *pPage, const SwLayoutFrame *pLay ) | ||||||
3112 | { | ||||||
3113 | if ( pLay->GetDrawObjs() ) | ||||||
3114 | ::lcl_Regist( pPage, pLay ); | ||||||
3115 | const SwFrame *pFrame = pLay->Lower(); | ||||||
3116 | while ( pFrame ) | ||||||
3117 | { | ||||||
3118 | if ( pFrame->IsLayoutFrame() ) | ||||||
3119 | ::RegistFlys( pPage, static_cast<const SwLayoutFrame*>(pFrame) ); | ||||||
3120 | else if ( pFrame->GetDrawObjs() ) | ||||||
3121 | ::lcl_Regist( pPage, pFrame ); | ||||||
3122 | pFrame = pFrame->GetNext(); | ||||||
3123 | } | ||||||
3124 | } | ||||||
3125 | |||||||
3126 | /// Notify the background based on the difference between old and new rectangle | ||||||
3127 | void Notify( SwFlyFrame *pFly, SwPageFrame *pOld, const SwRect &rOld, | ||||||
3128 | const SwRect* pOldPrt ) | ||||||
3129 | { | ||||||
3130 | const SwRect aFrame( pFly->GetObjRectWithSpaces() ); | ||||||
3131 | if ( rOld.Pos() != aFrame.Pos() ) | ||||||
3132 | { // changed position, invalidate old and new area | ||||||
3133 | if ( rOld.HasArea() && | ||||||
3134 | rOld.Left()+pFly->GetFormat()->GetLRSpace().GetLeft() < FAR_AWAY(((sal_Int32) 0x7FFFFFFF) - 20000) ) | ||||||
3135 | { | ||||||
3136 | pFly->NotifyBackground( pOld, rOld, PrepareHint::FlyFrameLeave ); | ||||||
3137 | } | ||||||
3138 | pFly->NotifyBackground( pFly->FindPageFrame(), aFrame, PrepareHint::FlyFrameArrive ); | ||||||
3139 | } | ||||||
3140 | else if ( rOld.SSize() != aFrame.SSize() ) | ||||||
3141 | { // changed size, invalidate the area that was left or is now overlapped | ||||||
3142 | // For simplicity, we purposely invalidate a Twip even if not needed. | ||||||
3143 | |||||||
3144 | SwViewShell *pSh = pFly->getRootFrame()->GetCurrShell(); | ||||||
3145 | if( pSh && rOld.HasArea() ) | ||||||
3146 | pSh->InvalidateWindows( rOld ); | ||||||
3147 | |||||||
3148 | // #i51941# - consider case that fly frame isn't | ||||||
3149 | // registered at the old page <pOld> | ||||||
3150 | SwPageFrame* pPageFrame = pFly->FindPageFrame(); | ||||||
3151 | if ( pOld != pPageFrame ) | ||||||
3152 | { | ||||||
3153 | pFly->NotifyBackground( pPageFrame, aFrame, PrepareHint::FlyFrameArrive ); | ||||||
3154 | } | ||||||
3155 | |||||||
3156 | if ( rOld.Left() != aFrame.Left() ) | ||||||
3157 | { | ||||||
3158 | SwRect aTmp( rOld ); | ||||||
3159 | aTmp.Union( aFrame ); | ||||||
3160 | aTmp.Left( std::min(aFrame.Left(), rOld.Left()) ); | ||||||
3161 | aTmp.Right( std::max(aFrame.Left(), rOld.Left()) ); | ||||||
3162 | pFly->NotifyBackground( pOld, aTmp, PrepareHint::FlyFrameSizeChanged ); | ||||||
3163 | } | ||||||
3164 | SwTwips nOld = rOld.Right(); | ||||||
3165 | SwTwips nNew = aFrame.Right(); | ||||||
3166 | if ( nOld != nNew ) | ||||||
3167 | { | ||||||
3168 | SwRect aTmp( rOld ); | ||||||
3169 | aTmp.Union( aFrame ); | ||||||
3170 | aTmp.Left( std::min(nNew, nOld) ); | ||||||
3171 | aTmp.Right( std::max(nNew, nOld) ); | ||||||
3172 | pFly->NotifyBackground( pOld, aTmp, PrepareHint::FlyFrameSizeChanged ); | ||||||
3173 | } | ||||||
3174 | if ( rOld.Top() != aFrame.Top() ) | ||||||
3175 | { | ||||||
3176 | SwRect aTmp( rOld ); | ||||||
3177 | aTmp.Union( aFrame ); | ||||||
3178 | aTmp.Top( std::min(aFrame.Top(), rOld.Top()) ); | ||||||
3179 | aTmp.Bottom( std::max(aFrame.Top(), rOld.Top()) ); | ||||||
3180 | pFly->NotifyBackground( pOld, aTmp, PrepareHint::FlyFrameSizeChanged ); | ||||||
3181 | } | ||||||
3182 | nOld = rOld.Bottom(); | ||||||
3183 | nNew = aFrame.Bottom(); | ||||||
3184 | if ( nOld != nNew ) | ||||||
3185 | { | ||||||
3186 | SwRect aTmp( rOld ); | ||||||
3187 | aTmp.Union( aFrame ); | ||||||
3188 | aTmp.Top( std::min(nNew, nOld) ); | ||||||
3189 | aTmp.Bottom( std::max(nNew, nOld) ); | ||||||
3190 | pFly->NotifyBackground( pOld, aTmp, PrepareHint::FlyFrameSizeChanged ); | ||||||
3191 | } | ||||||
3192 | } | ||||||
3193 | else if(pOldPrt && *pOldPrt != pFly->getFramePrintArea()) | ||||||
3194 | { | ||||||
3195 | bool bNotifyBackground(pFly->GetFormat()->GetSurround().IsContour()); | ||||||
3196 | |||||||
3197 | if(!bNotifyBackground && | ||||||
3198 | pFly->IsFlyFreeFrame() && | ||||||
3199 | static_cast< const SwFlyFreeFrame* >(pFly)->supportsAutoContour()) | ||||||
3200 | { | ||||||
3201 | // RotateFlyFrame3: Also notify for FlyFrames which allow AutoContour | ||||||
3202 | bNotifyBackground = true; | ||||||
3203 | } | ||||||
3204 | |||||||
3205 | if(bNotifyBackground) | ||||||
3206 | { | ||||||
3207 | // #i24097# | ||||||
3208 | pFly->NotifyBackground( pFly->FindPageFrame(), aFrame, PrepareHint::FlyFrameArrive ); | ||||||
3209 | } | ||||||
3210 | } | ||||||
3211 | } | ||||||
3212 | |||||||
3213 | static void lcl_CheckFlowBack( SwFrame* pFrame, const SwRect &rRect ) | ||||||
3214 | { | ||||||
3215 | SwTwips nBottom = rRect.Bottom(); | ||||||
3216 | while( pFrame ) | ||||||
3217 | { | ||||||
3218 | if( pFrame->IsLayoutFrame() ) | ||||||
3219 | { | ||||||
3220 | if( rRect.IsOver( pFrame->getFrameArea() ) ) | ||||||
3221 | lcl_CheckFlowBack( static_cast<SwLayoutFrame*>(pFrame)->Lower(), rRect ); | ||||||
3222 | } | ||||||
3223 | else if( !pFrame->GetNext() && nBottom > pFrame->getFrameArea().Bottom() ) | ||||||
3224 | { | ||||||
3225 | if( pFrame->IsContentFrame() && static_cast<SwContentFrame*>(pFrame)->HasFollow() ) | ||||||
3226 | pFrame->InvalidateSize(); | ||||||
3227 | else | ||||||
3228 | pFrame->InvalidateNextPos(); | ||||||
3229 | } | ||||||
3230 | pFrame = pFrame->GetNext(); | ||||||
3231 | } | ||||||
3232 | } | ||||||
3233 | |||||||
3234 | static void lcl_NotifyContent( const SdrObject *pThis, SwContentFrame *pCnt, | ||||||
3235 | const SwRect &rRect, const PrepareHint eHint ) | ||||||
3236 | { | ||||||
3237 | if ( !pCnt->IsTextFrame() ) | ||||||
3238 | return; | ||||||
3239 | |||||||
3240 | SwRect aCntPrt( pCnt->getFramePrintArea() ); | ||||||
3241 | aCntPrt.Pos() += pCnt->getFrameArea().Pos(); | ||||||
3242 | if ( eHint == PrepareHint::FlyFrameAttributesChanged ) | ||||||
3243 | { | ||||||
3244 | // #i35640# - use given rectangle <rRect> instead | ||||||
3245 | // of current bound rectangle | ||||||
3246 | if ( aCntPrt.IsOver( rRect ) ) | ||||||
3247 | pCnt->Prepare( PrepareHint::FlyFrameAttributesChanged ); | ||||||
3248 | } | ||||||
3249 | // #i23129# - only invalidate, if the text frame | ||||||
3250 | // printing area overlaps with the given rectangle. | ||||||
3251 | else if ( aCntPrt.IsOver( rRect ) ) | ||||||
3252 | pCnt->Prepare( eHint, static_cast<void*>(&aCntPrt.Intersection_( rRect )) ); | ||||||
3253 | if ( !pCnt->GetDrawObjs() ) | ||||||
3254 | return; | ||||||
3255 | |||||||
3256 | const SwSortedObjs &rObjs = *pCnt->GetDrawObjs(); | ||||||
3257 | for (SwAnchoredObject* pObj : rObjs) | ||||||
3258 | { | ||||||
3259 | if ( dynamic_cast<const SwFlyFrame*>( pObj) != nullptr ) | ||||||
3260 | { | ||||||
3261 | SwFlyFrame *pFly = static_cast<SwFlyFrame*>(pObj); | ||||||
3262 | if ( pFly->IsFlyInContentFrame() ) | ||||||
3263 | { | ||||||
3264 | SwContentFrame *pContent = pFly->ContainsContent(); | ||||||
3265 | while ( pContent ) | ||||||
3266 | { | ||||||
3267 | ::lcl_NotifyContent( pThis, pContent, rRect, eHint ); | ||||||
3268 | pContent = pContent->GetNextContentFrame(); | ||||||
3269 | } | ||||||
3270 | } | ||||||
3271 | } | ||||||
3272 | } | ||||||
3273 | } | ||||||
3274 | |||||||
3275 | void Notify_Background( const SdrObject* pObj, | ||||||
3276 | SwPageFrame* pPage, | ||||||
3277 | const SwRect& rRect, | ||||||
3278 | const PrepareHint eHint, | ||||||
3279 | const bool bInva ) | ||||||
3280 | { | ||||||
3281 | // If the frame was positioned correctly for the first time, do not inform the old area | ||||||
3282 | if ( eHint == PrepareHint::FlyFrameLeave && rRect.Top() == FAR_AWAY(((sal_Int32) 0x7FFFFFFF) - 20000) ) | ||||||
3283 | return; | ||||||
3284 | |||||||
3285 | SwLayoutFrame* pArea; | ||||||
3286 | SwFlyFrame *pFlyFrame = nullptr; | ||||||
3287 | SwFrame* pAnchor; | ||||||
3288 | if( auto pVirtFlyDrawObj = dynamic_cast<const SwVirtFlyDrawObj*>( pObj) ) | ||||||
3289 | { | ||||||
3290 | pFlyFrame = const_cast<SwVirtFlyDrawObj*>(pVirtFlyDrawObj)->GetFlyFrame(); | ||||||
3291 | pAnchor = pFlyFrame->AnchorFrame(); | ||||||
3292 | } | ||||||
3293 | else | ||||||
3294 | { | ||||||
3295 | pFlyFrame = nullptr; | ||||||
3296 | pAnchor = const_cast<SwFrame*>( | ||||||
3297 | GetUserCall(pObj)->GetAnchoredObj( pObj )->GetAnchorFrame() ); | ||||||
3298 | } | ||||||
3299 | if( PrepareHint::FlyFrameLeave != eHint && pAnchor->IsInFly() ) | ||||||
3300 | pArea = pAnchor->FindFlyFrame(); | ||||||
3301 | else | ||||||
3302 | pArea = pPage; | ||||||
3303 | SwContentFrame *pCnt = nullptr; | ||||||
3304 | if ( pArea ) | ||||||
3305 | { | ||||||
3306 | if( PrepareHint::FlyFrameArrive != eHint ) | ||||||
3307 | lcl_CheckFlowBack( pArea, rRect ); | ||||||
3308 | |||||||
3309 | // Only the Flys following this anchor are reacting. Thus, those do not | ||||||
3310 | // need to be processed. | ||||||
3311 | // An exception is LEAVE, since the Fly might come "from above". | ||||||
3312 | // If the anchor is positioned on the previous page, the whole page | ||||||
3313 | // needs to be processed (47722). | ||||||
3314 | // OD 2004-05-13 #i28701# - If the wrapping style has to be considered | ||||||
3315 | // on the object positioning, the complete area has to be processed, | ||||||
3316 | // because content frames before the anchor frame also have to consider | ||||||
3317 | // the object for the text wrapping. | ||||||
3318 | // #i3317# - The complete area has always been | ||||||
3319 | // processed. | ||||||
3320 | { | ||||||
3321 | pCnt = pArea->ContainsContent(); | ||||||
3322 | } | ||||||
3323 | } | ||||||
3324 | SwFrame *pLastTab = nullptr; | ||||||
3325 | |||||||
3326 | bool isValidTableBeforeAnchor(false); | ||||||
3327 | while ( pCnt && pArea && pArea->IsAnLower( pCnt ) ) | ||||||
3328 | { | ||||||
3329 | ::lcl_NotifyContent( pObj, pCnt, rRect, eHint ); | ||||||
3330 | if ( pCnt->IsInTab() ) | ||||||
3331 | { | ||||||
3332 | SwTabFrame *pTab = pCnt->FindTabFrame(); | ||||||
3333 | if ( pTab != pLastTab ) | ||||||
3334 | { | ||||||
3335 | pLastTab = pTab; | ||||||
3336 | isValidTableBeforeAnchor = false; | ||||||
3337 | if (PrepareHint::FlyFrameArrive == eHint | ||||||
3338 | && pFlyFrame // TODO: do it for draw objects too? | ||||||
3339 | && pTab->IsFollow() // table starts on previous page? | ||||||
3340 | // "through" means they will actually overlap anyway | ||||||
3341 | && css::text::WrapTextMode_THROUGH != pFlyFrame->GetFormat()->GetSurround().GetSurround() | ||||||
3342 | // if it's anchored in footer it can't move to other page | ||||||
3343 | && !pAnchor->FindFooterOrHeader()) | ||||||
3344 | { | ||||||
3345 | SwFrame * pTmp(pAnchor->GetPrev()); | ||||||
3346 | while (pTmp) | ||||||
3347 | { | ||||||
3348 | if (pTmp == pTab) | ||||||
3349 | { | ||||||
3350 | // tdf#99460 the table shouldn't be moved by the fly | ||||||
3351 | isValidTableBeforeAnchor = true; | ||||||
3352 | break; | ||||||
3353 | } | ||||||
3354 | pTmp = pTmp->GetPrev(); | ||||||
3355 | } | ||||||
3356 | } | ||||||
3357 | // #i40606# - use <GetLastBoundRect()> | ||||||
3358 | // instead of <GetCurrentBoundRect()>, because a recalculation | ||||||
3359 | // of the bounding rectangle isn't intended here. | ||||||
3360 | if (!isValidTableBeforeAnchor | ||||||
3361 | && (pTab->getFrameArea().IsOver(pObj->GetLastBoundRect()) || | ||||||
3362 | pTab->getFrameArea().IsOver(rRect))) | ||||||
3363 | { | ||||||
3364 | if ( !pFlyFrame || !pFlyFrame->IsLowerOf( pTab ) ) | ||||||
3365 | pTab->InvalidatePrt(); | ||||||
3366 | } | ||||||
3367 | } | ||||||
3368 | SwLayoutFrame* pCell = pCnt->GetUpper(); | ||||||
3369 | // #i40606# - use <GetLastBoundRect()> | ||||||
3370 | // instead of <GetCurrentBoundRect()>, because a recalculation | ||||||
3371 | // of the bounding rectangle isn't intended here. | ||||||
3372 | if (!isValidTableBeforeAnchor && pCell->IsCellFrame() && | ||||||
3373 | ( pCell->getFrameArea().IsOver( pObj->GetLastBoundRect() ) || | ||||||
3374 | pCell->getFrameArea().IsOver( rRect ) ) ) | ||||||
3375 | { | ||||||
3376 | const SwFormatVertOrient &rOri = pCell->GetFormat()->GetVertOrient(); | ||||||
3377 | if ( text::VertOrientation::NONE != rOri.GetVertOrient() ) | ||||||
3378 | pCell->InvalidatePrt(); | ||||||
3379 | } | ||||||
3380 | } | ||||||
3381 | pCnt = pCnt->GetNextContentFrame(); | ||||||
3382 | } | ||||||
3383 | // #128702# - make code robust | ||||||
3384 | if ( pPage && pPage->GetSortedObjs() ) | ||||||
3385 | { | ||||||
3386 | pObj->GetOrdNum(); | ||||||
3387 | const SwSortedObjs &rObjs = *pPage->GetSortedObjs(); | ||||||
3388 | for (SwAnchoredObject* pAnchoredObj : rObjs) | ||||||
3389 | { | ||||||
3390 | if ( dynamic_cast<const SwFlyFrame*>( pAnchoredObj) != nullptr ) | ||||||
3391 | { | ||||||
3392 | if( pAnchoredObj->GetDrawObj() == pObj ) | ||||||
3393 | continue; | ||||||
3394 | SwFlyFrame *pFly = static_cast<SwFlyFrame*>(pAnchoredObj); | ||||||
3395 | if ( pFly->getFrameArea().Top() == FAR_AWAY(((sal_Int32) 0x7FFFFFFF) - 20000) ) | ||||||
3396 | continue; | ||||||
3397 | |||||||
3398 | if ( !pFlyFrame || | ||||||
3399 | (!pFly->IsLowerOf( pFlyFrame ) && | ||||||
3400 | pFly->GetVirtDrawObj()->GetOrdNumDirect() < pObj->GetOrdNumDirect())) | ||||||
3401 | { | ||||||
3402 | pCnt = pFly->ContainsContent(); | ||||||
3403 | while ( pCnt ) | ||||||
3404 | { | ||||||
3405 | ::lcl_NotifyContent( pObj, pCnt, rRect, eHint ); | ||||||
3406 | pCnt = pCnt->GetNextContentFrame(); | ||||||
3407 | } | ||||||
3408 | } | ||||||
3409 | if( pFly->IsFlyLayFrame() ) | ||||||
3410 | { | ||||||
3411 | if( pFly->Lower() && pFly->Lower()->IsColumnFrame() && | ||||||
3412 | pFly->getFrameArea().Bottom() >= rRect.Top() && | ||||||
3413 | pFly->getFrameArea().Top() <= rRect.Bottom() && | ||||||
3414 | pFly->getFrameArea().Right() >= rRect.Left() && | ||||||
3415 | pFly->getFrameArea().Left() <= rRect.Right() ) | ||||||
3416 | { | ||||||
3417 | pFly->InvalidateSize(); | ||||||
3418 | } | ||||||
3419 | } | ||||||
3420 | // Flys above myself might sidestep if they have an automatic | ||||||
3421 | // alignment. This happens independently of my attributes since | ||||||
3422 | // this might have been changed as well. | ||||||
3423 | else if ( pFly->IsFlyAtContentFrame() && | ||||||
3424 | pObj->GetOrdNumDirect() < | ||||||
3425 | pFly->GetVirtDrawObj()->GetOrdNumDirect() && | ||||||
3426 | pFlyFrame && !pFly->IsLowerOf( pFlyFrame ) ) | ||||||
3427 | { | ||||||
3428 | const SwFormatHoriOrient &rH = pFly->GetFormat()->GetHoriOrient(); | ||||||
3429 | if ( text::HoriOrientation::NONE != rH.GetHoriOrient() && | ||||||
3430 | text::HoriOrientation::CENTER != rH.GetHoriOrient() && | ||||||
3431 | ( !pFly->IsAutoPos() || text::RelOrientation::CHAR != rH.GetRelationOrient() ) && | ||||||
3432 | (pFly->getFrameArea().Bottom() >= rRect.Top() && | ||||||
3433 | pFly->getFrameArea().Top() <= rRect.Bottom()) ) | ||||||
3434 | pFly->InvalidatePos(); | ||||||
3435 | } | ||||||
3436 | } | ||||||
3437 | } | ||||||
3438 | } | ||||||
3439 | if ( pFlyFrame && pAnchor->GetUpper() && pAnchor->IsInTab() )//MA_FLY_HEIGHT | ||||||
3440 | pAnchor->GetUpper()->InvalidateSize(); | ||||||
3441 | |||||||
3442 | // #i82258# - make code robust | ||||||
3443 | SwViewShell* pSh = nullptr; | ||||||
3444 | if ( bInva && pPage && | ||||||
3445 | nullptr != (pSh = pPage->getRootFrame()->GetCurrShell()) ) | ||||||
3446 | { | ||||||
3447 | pSh->InvalidateWindows( rRect ); | ||||||
3448 | } | ||||||
3449 | } | ||||||
3450 | |||||||
3451 | /// Provides the Upper of an anchor in paragraph-bound objects. If the latter | ||||||
3452 | /// is a chained border or a footnote, the "virtual" Upper might be returned. | ||||||
3453 | const SwFrame* GetVirtualUpper( const SwFrame* pFrame, const Point& rPos ) | ||||||
3454 | { | ||||||
3455 | if( pFrame->IsTextFrame() ) | ||||||
3456 | { | ||||||
3457 | pFrame = pFrame->GetUpper(); | ||||||
3458 | if( !pFrame->getFrameArea().IsInside( rPos ) ) | ||||||
3459 | { | ||||||
3460 | if( pFrame->IsFootnoteFrame() ) | ||||||
3461 | { | ||||||
3462 | const SwFootnoteFrame* pTmp = static_cast<const SwFootnoteFrame*>(pFrame)->GetFollow(); | ||||||
3463 | while( pTmp ) | ||||||
3464 | { | ||||||
3465 | if( pTmp->getFrameArea().IsInside( rPos ) ) | ||||||
3466 | return pTmp; | ||||||
3467 | pTmp = pTmp->GetFollow(); | ||||||
3468 | } | ||||||
3469 | } | ||||||
3470 | else | ||||||
3471 | { | ||||||
3472 | SwFlyFrame* pTmp = const_cast<SwFlyFrame*>(pFrame->FindFlyFrame()); | ||||||
3473 | while( pTmp ) | ||||||
3474 | { | ||||||
3475 | if( pTmp->getFrameArea().IsInside( rPos ) ) | ||||||
3476 | return pTmp; | ||||||
3477 | pTmp = pTmp->GetNextLink(); | ||||||
3478 | } | ||||||
3479 | } | ||||||
3480 | } | ||||||
3481 | } | ||||||
3482 | return pFrame; | ||||||
3483 | } | ||||||
3484 | |||||||
3485 | bool Is_Lower_Of(const SwFrame *pCurrFrame, const SdrObject* pObj) | ||||||
3486 | { | ||||||
3487 | Point aPos; | ||||||
3488 | const SwFrame* pFrame; | ||||||
3489 | if (const SwVirtFlyDrawObj *pFlyDrawObj = dynamic_cast<const SwVirtFlyDrawObj*>(pObj)) | ||||||
3490 | { | ||||||
3491 | const SwFlyFrame* pFly = pFlyDrawObj->GetFlyFrame(); | ||||||
3492 | pFrame = pFly->GetAnchorFrame(); | ||||||
3493 | aPos = pFly->getFrameArea().Pos(); | ||||||
3494 | } | ||||||
3495 | else | ||||||
3496 | { | ||||||
3497 | pFrame = static_cast<SwDrawContact*>(GetUserCall(pObj))->GetAnchorFrame(pObj); | ||||||
3498 | aPos = pObj->GetCurrentBoundRect().TopLeft(); | ||||||
3499 | } | ||||||
3500 | OSL_ENSURE( pFrame, "8-( Fly is lost in Space." )do { if (true && (!(pFrame))) { sal_detail_logFormat( (SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "3500" ": "), "%s", "8-( Fly is lost in Space."); } } while (false); | ||||||
3501 | pFrame = GetVirtualUpper( pFrame, aPos ); | ||||||
3502 | do | ||||||
3503 | { if ( pFrame == pCurrFrame ) | ||||||
3504 | return true; | ||||||
3505 | if( pFrame->IsFlyFrame() ) | ||||||
3506 | { | ||||||
3507 | aPos = pFrame->getFrameArea().Pos(); | ||||||
3508 | pFrame = GetVirtualUpper( static_cast<const SwFlyFrame*>(pFrame)->GetAnchorFrame(), aPos ); | ||||||
3509 | } | ||||||
3510 | else | ||||||
3511 | pFrame = pFrame->GetUpper(); | ||||||
3512 | } while ( pFrame ); | ||||||
3513 | return false; | ||||||
3514 | } | ||||||
3515 | |||||||
3516 | /// provides the area of a frame in that no Fly from another area can overlap | ||||||
3517 | const SwFrame *FindContext( const SwFrame *pFrame, SwFrameType nAdditionalContextType ) | ||||||
3518 | { | ||||||
3519 | const SwFrameType nTyp = SwFrameType::Root | SwFrameType::Header | SwFrameType::Footer | SwFrameType::FtnCont | | ||||||
3520 | SwFrameType::Ftn | SwFrameType::Fly | | ||||||
3521 | SwFrameType::Tab | SwFrameType::Row | SwFrameType::Cell | | ||||||
3522 | nAdditionalContextType; | ||||||
3523 | do | ||||||
3524 | { if ( pFrame->GetType() & nTyp ) | ||||||
3525 | break; | ||||||
3526 | pFrame = pFrame->GetUpper(); | ||||||
3527 | } while( pFrame ); | ||||||
3528 | return pFrame; | ||||||
3529 | } | ||||||
3530 | |||||||
3531 | bool IsFrameInSameContext( const SwFrame *pInnerFrame, const SwFrame *pFrame ) | ||||||
3532 | { | ||||||
3533 | const SwFrame *pContext = FindContext( pInnerFrame, SwFrameType::None ); | ||||||
3534 | |||||||
3535 | const SwFrameType nTyp = SwFrameType::Root | SwFrameType::Header | SwFrameType::Footer | SwFrameType::FtnCont | | ||||||
3536 | SwFrameType::Ftn | SwFrameType::Fly | | ||||||
3537 | SwFrameType::Tab | SwFrameType::Row | SwFrameType::Cell; | ||||||
3538 | do | ||||||
3539 | { if ( pFrame->GetType() & nTyp ) | ||||||
3540 | { | ||||||
3541 | if( pFrame == pContext ) | ||||||
3542 | return true; | ||||||
3543 | if( pFrame->IsCellFrame() ) | ||||||
3544 | return false; | ||||||
3545 | } | ||||||
3546 | if( pFrame->IsFlyFrame() ) | ||||||
3547 | { | ||||||
3548 | Point aPos( pFrame->getFrameArea().Pos() ); | ||||||
3549 | pFrame = GetVirtualUpper( static_cast<const SwFlyFrame*>(pFrame)->GetAnchorFrame(), aPos ); | ||||||
3550 | } | ||||||
3551 | else | ||||||
3552 | pFrame = pFrame->GetUpper(); | ||||||
3553 | } while( pFrame ); | ||||||
3554 | |||||||
3555 | return false; | ||||||
3556 | } | ||||||
3557 | |||||||
3558 | static SwTwips lcl_CalcCellRstHeight( SwLayoutFrame *pCell ) | ||||||
3559 | { | ||||||
3560 | SwFrame *pLow = pCell->Lower(); | ||||||
3561 | if ( pLow && (pLow->IsContentFrame() || pLow->IsSctFrame()) ) | ||||||
3562 | { | ||||||
3563 | long nHeight = 0, nFlyAdd = 0; | ||||||
3564 | do | ||||||
3565 | { | ||||||
3566 | long nLow = pLow->getFrameArea().Height(); | ||||||
3567 | if( pLow->IsTextFrame() && static_cast<SwTextFrame*>(pLow)->IsUndersized() ) | ||||||
3568 | nLow += static_cast<SwTextFrame*>(pLow)->GetParHeight()-pLow->getFramePrintArea().Height(); | ||||||
3569 | else if( pLow->IsSctFrame() && static_cast<SwSectionFrame*>(pLow)->IsUndersized() ) | ||||||
3570 | nLow += static_cast<SwSectionFrame*>(pLow)->Undersize(); | ||||||
3571 | nFlyAdd = std::max( 0L, nFlyAdd - nLow ); | ||||||
3572 | nFlyAdd = std::max( nFlyAdd, ::CalcHeightWithFlys( pLow ) ); | ||||||
3573 | nHeight += nLow; | ||||||
3574 | pLow = pLow->GetNext(); | ||||||
3575 | } while ( pLow ); | ||||||
3576 | if ( nFlyAdd ) | ||||||
3577 | nHeight += nFlyAdd; | ||||||
3578 | |||||||
3579 | // The border cannot be calculated based on PrtArea and Frame, since both can be invalid. | ||||||
3580 | SwBorderAttrAccess aAccess( SwFrame::GetCache(), pCell ); | ||||||
3581 | const SwBorderAttrs &rAttrs = *aAccess.Get(); | ||||||
3582 | nHeight += rAttrs.CalcTop() + rAttrs.CalcBottom(); | ||||||
3583 | |||||||
3584 | return pCell->getFrameArea().Height() - nHeight; | ||||||
3585 | } | ||||||
3586 | else | ||||||
3587 | { | ||||||
3588 | long nRstHeight = 0; | ||||||
3589 | while (pLow && pLow->IsLayoutFrame()) | ||||||
3590 | { | ||||||
3591 | nRstHeight += ::CalcRowRstHeight(static_cast<SwLayoutFrame*>(pLow)); | ||||||
3592 | pLow = pLow->GetNext(); | ||||||
3593 | } | ||||||
3594 | return nRstHeight; | ||||||
3595 | } | ||||||
3596 | } | ||||||
3597 | |||||||
3598 | SwTwips CalcRowRstHeight( SwLayoutFrame *pRow ) | ||||||
3599 | { | ||||||
3600 | SwFrame *pLow = pRow->Lower(); | ||||||
3601 | if (!(pLow && pLow->IsLayoutFrame())) | ||||||
3602 | { | ||||||
3603 | return 0; | ||||||
3604 | } | ||||||
3605 | SwTwips nRstHeight = LONG_MAX9223372036854775807L; | ||||||
3606 | while (pLow && pLow->IsLayoutFrame()) | ||||||
3607 | { | ||||||
3608 | nRstHeight = std::min(nRstHeight, ::lcl_CalcCellRstHeight(static_cast<SwLayoutFrame*>(pLow))); | ||||||
3609 | pLow = pLow->GetNext(); | ||||||
3610 | } | ||||||
3611 | return nRstHeight; | ||||||
3612 | } | ||||||
3613 | |||||||
3614 | const SwFrame* FindPage( const SwRect &rRect, const SwFrame *pPage ) | ||||||
3615 | { | ||||||
3616 | if ( !rRect.IsOver( pPage->getFrameArea() ) ) | ||||||
3617 | { | ||||||
3618 | const SwRootFrame* pRootFrame = static_cast<const SwRootFrame*>(pPage->GetUpper()); | ||||||
3619 | const SwFrame* pTmpPage = pRootFrame ? pRootFrame->GetPageAtPos( rRect.TopLeft(), &rRect.SSize(), true ) : nullptr; | ||||||
3620 | if ( pTmpPage ) | ||||||
3621 | pPage = pTmpPage; | ||||||
3622 | } | ||||||
3623 | |||||||
3624 | return pPage; | ||||||
3625 | } | ||||||
3626 | |||||||
3627 | namespace { | ||||||
3628 | |||||||
3629 | class SwFrameHolder : private SfxListener | ||||||
3630 | { | ||||||
3631 | SwFrame* pFrame; | ||||||
3632 | bool bSet; | ||||||
3633 | virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override; | ||||||
3634 | public: | ||||||
3635 | SwFrameHolder() : pFrame(nullptr), bSet(false) {} | ||||||
3636 | void SetFrame( SwFrame* pHold ); | ||||||
3637 | SwFrame* GetFrame() { return pFrame; } | ||||||
3638 | void Reset(); | ||||||
3639 | bool IsSet() const { return bSet; } | ||||||
3640 | }; | ||||||
3641 | |||||||
3642 | } | ||||||
3643 | |||||||
3644 | void SwFrameHolder::SetFrame( SwFrame* pHold ) | ||||||
3645 | { | ||||||
3646 | bSet = true; | ||||||
3647 | if (pFrame != pHold) | ||||||
3648 | { | ||||||
3649 | if (pFrame) | ||||||
3650 | EndListening(*pFrame); | ||||||
3651 | StartListening(*pHold); | ||||||
3652 | pFrame = pHold; | ||||||
3653 | } | ||||||
3654 | } | ||||||
3655 | |||||||
3656 | void SwFrameHolder::Reset() | ||||||
3657 | { | ||||||
3658 | if (pFrame) | ||||||
3659 | EndListening(*pFrame); | ||||||
3660 | bSet = false; | ||||||
3661 | pFrame = nullptr; | ||||||
3662 | } | ||||||
3663 | |||||||
3664 | void SwFrameHolder::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) | ||||||
3665 | { | ||||||
3666 | if ( rHint.GetId() == SfxHintId::Dying && &rBC == pFrame ) | ||||||
3667 | { | ||||||
3668 | pFrame = nullptr; | ||||||
3669 | } | ||||||
3670 | } | ||||||
3671 | |||||||
3672 | SwFrame* GetFrameOfModify(SwRootFrame const*const pLayout, SwModify const& rMod, | ||||||
3673 | SwFrameType const nFrameType, SwPosition const*const pPos, | ||||||
3674 | std::pair<Point, bool> const*const pViewPosAndCalcFrame) | ||||||
3675 | { | ||||||
3676 | SwFrame *pMinFrame = nullptr, *pTmpFrame; | ||||||
3677 | SwFrameHolder aHolder; | ||||||
3678 | SwRect aCalcRect; | ||||||
3679 | bool bClientIterChanged = false; | ||||||
3680 | |||||||
3681 | SwIterator<SwFrame, SwModify, sw::IteratorMode::UnwrapMulti> aIter(rMod); | ||||||
3682 | do { | ||||||
3683 | pMinFrame = nullptr; | ||||||
3684 | aHolder.Reset(); | ||||||
3685 | sal_uInt64 nMinDist = 0; | ||||||
3686 | bClientIterChanged = false; | ||||||
3687 | |||||||
3688 | for( pTmpFrame = aIter.First(); pTmpFrame; pTmpFrame = aIter.Next() ) | ||||||
3689 | { | ||||||
3690 | if( pTmpFrame->GetType() & nFrameType && | ||||||
3691 | ( !pLayout || pLayout == pTmpFrame->getRootFrame() ) && | ||||||
3692 | (!pTmpFrame->IsFlowFrame() || | ||||||
3693 | !SwFlowFrame::CastFlowFrame( pTmpFrame )->IsFollow() )) | ||||||
3694 | { | ||||||
3695 | if (pViewPosAndCalcFrame) | ||||||
3696 | { | ||||||
3697 | // watch for Frame being deleted | ||||||
3698 | if ( pMinFrame ) | ||||||
3699 | aHolder.SetFrame( pMinFrame ); | ||||||
3700 | else | ||||||
3701 | aHolder.Reset(); | ||||||
3702 | |||||||
3703 | if (pViewPosAndCalcFrame->second) | ||||||
3704 | { | ||||||
3705 | // tdf#108118 prevent recursion | ||||||
3706 | DisableCallbackAction a(*pTmpFrame->getRootFrame()); | ||||||
3707 | // - format parent Writer | ||||||
3708 | // fly frame, if it isn't been formatted yet. | ||||||
3709 | // Note: The Writer fly frame could be the frame itself. | ||||||
3710 | SwFlyFrame* pFlyFrame( pTmpFrame->FindFlyFrame() ); | ||||||
3711 | if ( pFlyFrame && | ||||||
3712 | pFlyFrame->getFrameArea().Pos().X() == FAR_AWAY(((sal_Int32) 0x7FFFFFFF) - 20000) && | ||||||
3713 | pFlyFrame->getFrameArea().Pos().Y() == FAR_AWAY(((sal_Int32) 0x7FFFFFFF) - 20000) ) | ||||||
3714 | { | ||||||
3715 | SwObjectFormatter::FormatObj( *pFlyFrame ); | ||||||
3716 | } | ||||||
3717 | pTmpFrame->Calc(pLayout ? pLayout->GetCurrShell()->GetOut() : nullptr); | ||||||
3718 | } | ||||||
3719 | |||||||
3720 | // aIter.IsChanged checks if the current pTmpFrame has been deleted while | ||||||
3721 | // it is the current iterator | ||||||
3722 | // FrameHolder watches for deletion of the current pMinFrame | ||||||
3723 | if( aIter.IsChanged() || ( aHolder.IsSet() && !aHolder.GetFrame() ) ) | ||||||
3724 | { | ||||||
3725 | // restart iteration | ||||||
3726 | bClientIterChanged = true; | ||||||
3727 | break; | ||||||
3728 | } | ||||||
3729 | |||||||
3730 | // for Flys go via the parent if the Fly is not yet "formatted" | ||||||
3731 | if (!pViewPosAndCalcFrame->second && | ||||||
3732 | pTmpFrame->GetType() & SwFrameType::Fly && | ||||||
3733 | static_cast<SwFlyFrame*>(pTmpFrame)->GetAnchorFrame() && | ||||||
3734 | FAR_AWAY(((sal_Int32) 0x7FFFFFFF) - 20000) == pTmpFrame->getFrameArea().Pos().getX() && | ||||||
3735 | FAR_AWAY(((sal_Int32) 0x7FFFFFFF) - 20000) == pTmpFrame->getFrameArea().Pos().getY() ) | ||||||
3736 | aCalcRect = static_cast<SwFlyFrame*>(pTmpFrame)->GetAnchorFrame()->getFrameArea(); | ||||||
3737 | else | ||||||
3738 | aCalcRect = pTmpFrame->getFrameArea(); | ||||||
3739 | |||||||
3740 | if (aCalcRect.IsInside(pViewPosAndCalcFrame->first)) | ||||||
3741 | { | ||||||
3742 | pMinFrame = pTmpFrame; | ||||||
3743 | break; | ||||||
3744 | } | ||||||
3745 | |||||||
3746 | // Point not in rectangle. Compare distances: | ||||||
3747 | const Point aCalcRectCenter = aCalcRect.Center(); | ||||||
3748 | const Point aDiff = aCalcRectCenter - pViewPosAndCalcFrame->first; | ||||||
3749 | const sal_uInt64 nCurrentDist = sal_Int64(aDiff.getX()) * sal_Int64(aDiff.getX()) + sal_Int64(aDiff.getY()) * sal_Int64(aDiff.getY()); // opt: no sqrt | ||||||
3750 | if ( !pMinFrame || nCurrentDist < nMinDist ) | ||||||
3751 | { | ||||||
3752 | pMinFrame = pTmpFrame; | ||||||
3753 | nMinDist = nCurrentDist; | ||||||
3754 | } | ||||||
3755 | } | ||||||
3756 | else | ||||||
3757 | { | ||||||
3758 | // if no pViewPosAndCalcFrame is provided, take the first one | ||||||
3759 | pMinFrame = pTmpFrame; | ||||||
3760 | break; | ||||||
3761 | } | ||||||
3762 | } | ||||||
3763 | } | ||||||
3764 | } while( bClientIterChanged ); | ||||||
3765 | |||||||
3766 | if( pPos && pMinFrame && pMinFrame->IsTextFrame() ) | ||||||
3767 | return static_cast<SwTextFrame*>(pMinFrame)->GetFrameAtPos( *pPos ); | ||||||
3768 | |||||||
3769 | return pMinFrame; | ||||||
3770 | } | ||||||
3771 | |||||||
3772 | bool IsExtraData( const SwDoc *pDoc ) | ||||||
3773 | { | ||||||
3774 | const SwLineNumberInfo &rInf = pDoc->GetLineNumberInfo(); | ||||||
3775 | return rInf.IsPaintLineNumbers() || | ||||||
3776 | rInf.IsCountInFlys() || | ||||||
3777 | (static_cast<sal_Int16>(SW_MOD()( static_cast<SwModule*>(SfxApplication::GetModule(SfxToolsModule ::Writer)))->GetRedlineMarkPos()) != text::HoriOrientation::NONE && | ||||||
3778 | !pDoc->getIDocumentRedlineAccess().GetRedlineTable().empty()); | ||||||
3779 | } | ||||||
3780 | |||||||
3781 | // OD 22.09.2003 #110978# | ||||||
3782 | SwRect SwPageFrame::PrtWithoutHeaderAndFooter() const | ||||||
3783 | { | ||||||
3784 | SwRect aPrtWithoutHeaderFooter( getFramePrintArea() ); | ||||||
3785 | aPrtWithoutHeaderFooter.Pos() += getFrameArea().Pos(); | ||||||
3786 | |||||||
3787 | const SwFrame* pLowerFrame = Lower(); | ||||||
3788 | while ( pLowerFrame ) | ||||||
3789 | { | ||||||
3790 | // Note: independent on text direction page header and page footer are | ||||||
3791 | // always at top respectively at bottom of the page frame. | ||||||
3792 | if ( pLowerFrame->IsHeaderFrame() ) | ||||||
3793 | { | ||||||
3794 | aPrtWithoutHeaderFooter.AddTop( pLowerFrame->getFrameArea().Height() ); | ||||||
3795 | } | ||||||
3796 | if ( pLowerFrame->IsFooterFrame() ) | ||||||
3797 | { | ||||||
3798 | aPrtWithoutHeaderFooter.AddBottom( - pLowerFrame->getFrameArea().Height() ); | ||||||
3799 | } | ||||||
3800 | |||||||
3801 | pLowerFrame = pLowerFrame->GetNext(); | ||||||
3802 | } | ||||||
3803 | |||||||
3804 | return aPrtWithoutHeaderFooter; | ||||||
3805 | } | ||||||
3806 | |||||||
3807 | /** method to determine the spacing values of a frame | ||||||
3808 | |||||||
3809 | OD 2004-03-10 #i28701# | ||||||
3810 | OD 2009-08-28 #i102458# | ||||||
3811 | Add output parameter <obIsLineSpacingProportional> | ||||||
3812 | */ | ||||||
3813 | void GetSpacingValuesOfFrame( const SwFrame& rFrame, | ||||||
3814 | SwTwips& onLowerSpacing, | ||||||
3815 | SwTwips& onLineSpacing, | ||||||
3816 | bool& obIsLineSpacingProportional, | ||||||
3817 | bool bIdenticalStyles ) | ||||||
3818 | { | ||||||
3819 | if ( !rFrame.IsFlowFrame() ) | ||||||
3820 | { | ||||||
3821 | onLowerSpacing = 0; | ||||||
3822 | onLineSpacing = 0; | ||||||
3823 | } | ||||||
3824 | else | ||||||
3825 | { | ||||||
3826 | const SvxULSpaceItem& rULSpace = rFrame.GetAttrSet()->GetULSpace(); | ||||||
3827 | // check contextual spacing if the style of actual and next paragraphs are identical | ||||||
3828 | if (bIdenticalStyles) | ||||||
3829 | onLowerSpacing = (rULSpace.GetContext() ? 0 : rULSpace.GetLower()); | ||||||
3830 | else | ||||||
3831 | onLowerSpacing = rULSpace.GetLower(); | ||||||
3832 | |||||||
3833 | onLineSpacing = 0; | ||||||
3834 | obIsLineSpacingProportional = false; | ||||||
3835 | if ( rFrame.IsTextFrame() ) | ||||||
3836 | { | ||||||
3837 | onLineSpacing = static_cast<const SwTextFrame&>(rFrame).GetLineSpace(); | ||||||
3838 | obIsLineSpacingProportional = | ||||||
3839 | onLineSpacing != 0 && | ||||||
3840 | static_cast<const SwTextFrame&>(rFrame).GetLineSpace( true ) == 0; | ||||||
3841 | } | ||||||
3842 | |||||||
3843 | OSL_ENSURE( onLowerSpacing >= 0 && onLineSpacing >= 0,do { if (true && (!(onLowerSpacing >= 0 && onLineSpacing >= 0))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "3844" ": "), "%s", "<GetSpacingValuesOfFrame(..)> - spacing values aren't positive!" ); } } while (false) | ||||||
3844 | "<GetSpacingValuesOfFrame(..)> - spacing values aren't positive!" )do { if (true && (!(onLowerSpacing >= 0 && onLineSpacing >= 0))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/frmtool.cxx" ":" "3844" ": "), "%s", "<GetSpacingValuesOfFrame(..)> - spacing values aren't positive!" ); } } while (false); | ||||||
3845 | } | ||||||
3846 | } | ||||||
3847 | |||||||
3848 | /// get the content of the table cell, skipping content from nested tables | ||||||
3849 | const SwContentFrame* GetCellContent( const SwLayoutFrame& rCell ) | ||||||
3850 | { | ||||||
3851 | const SwContentFrame* pContent = rCell.ContainsContent(); | ||||||
3852 | const SwTabFrame* pTab = rCell.FindTabFrame(); | ||||||
3853 | |||||||
3854 | while ( pContent && rCell.IsAnLower( pContent ) ) | ||||||
3855 | { | ||||||
3856 | const SwTabFrame* pTmpTab = pContent->FindTabFrame(); | ||||||
3857 | if ( pTmpTab != pTab ) | ||||||
3858 | { | ||||||
3859 | SwFrame const*const pTmp = pTmpTab->FindLastContentOrTable(); | ||||||
3860 | if (pTmp) | ||||||
3861 | { | ||||||
3862 | pContent = pTmp->FindNextCnt(); | ||||||
3863 | } | ||||||
3864 | else | ||||||
3865 | { | ||||||
3866 | pContent = nullptr; | ||||||
3867 | } | ||||||
3868 | } | ||||||
3869 | else | ||||||
3870 | break; | ||||||
3871 | } | ||||||
3872 | return pContent; | ||||||
3873 | } | ||||||
3874 | |||||||
3875 | SwDeletionChecker::SwDeletionChecker(const SwFrame* pFrame) | ||||||
3876 | : mpFrame( pFrame ) | ||||||
3877 | , mpRegIn( pFrame | ||||||
3878 | ? pFrame->IsTextFrame() | ||||||
3879 | // sw_redlinehide: GetDep() may be a member of SwTextFrame! | ||||||
3880 | ? static_cast<SwTextFrame const*>(pFrame)->GetTextNodeFirst() | ||||||
3881 | : const_cast<SwFrame*>(pFrame)->GetDep() | ||||||
3882 | : nullptr ) | ||||||
3883 | { | ||||||
3884 | } | ||||||
3885 | |||||||
3886 | /// Can be used to check if a frame has been deleted | ||||||
3887 | bool SwDeletionChecker::HasBeenDeleted() const | ||||||
3888 | { | ||||||
3889 | if ( !mpFrame || !mpRegIn ) | ||||||
3890 | return false; | ||||||
3891 | |||||||
3892 | SwIterator<SwFrame, SwModify, sw::IteratorMode::UnwrapMulti> aIter(*mpRegIn); | ||||||
3893 | SwFrame* pLast = aIter.First(); | ||||||
3894 | while ( pLast ) | ||||||
3895 | { | ||||||
3896 | if ( pLast == mpFrame ) | ||||||
3897 | return false; | ||||||
3898 | pLast = aIter.Next(); | ||||||
3899 | } | ||||||
3900 | |||||||
3901 | return true; | ||||||
3902 | } | ||||||
3903 | |||||||
3904 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
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_SW_INC_NODE_HXX |
21 | #define INCLUDED_SW_INC_NODE_HXX |
22 | |
23 | #include <sal/types.h> |
24 | |
25 | #include "swdllapi.h" |
26 | #include "ndarr.hxx" |
27 | #include "ndtyp.hxx" |
28 | #include "index.hxx" |
29 | #include "fmtcol.hxx" |
30 | |
31 | #include <memory> |
32 | #include <vector> |
33 | |
34 | class SwContentFrame; |
35 | class SwContentNode; |
36 | class SwDoc; |
37 | class SwEndNode; |
38 | class SwFrame; |
39 | class SwFrameFormat; |
40 | class SwGrfNode; |
41 | class SwNoTextNode; |
42 | class SwNodeIndex; |
43 | class SwOLENode; |
44 | class SwRect; |
45 | class SwSection; |
46 | class SwSectionFormat; |
47 | class SwTOXBase; |
48 | class SwSectionNode; |
49 | class SwStartNode; |
50 | class SwTabFrame; |
51 | class SwRootFrame; |
52 | class SwTable; |
53 | class SwTableNode; |
54 | class SwTableBox; |
55 | class SwTextNode; |
56 | class SwPageDesc; |
57 | class SwViewShell; |
58 | struct SwPosition; |
59 | class IStyleAccess; |
60 | class IDocumentSettingAccess; |
61 | class IDocumentDeviceAccess; |
62 | class IDocumentMarkAccess; |
63 | class IDocumentRedlineAccess; |
64 | class IDocumentStylePoolAccess; |
65 | class IDocumentLinksAdministration; |
66 | class IDocumentFieldsAccess; |
67 | class IDocumentContentOperations; |
68 | class IDocumentListItems; |
69 | class Point; |
70 | enum class SvxFrameDirection; |
71 | typedef std::vector<SwOLENode*> SwOLENodes; // docary.hxx |
72 | |
73 | namespace drawinglayer::attribute { |
74 | class SdrAllFillAttributesHelper; |
75 | typedef std::shared_ptr< SdrAllFillAttributesHelper > SdrAllFillAttributesHelperPtr; |
76 | } |
77 | |
78 | /// Base class of the Writer document model elements. |
79 | class SW_DLLPUBLIC__attribute__ ((visibility("default"))) SwNode |
80 | : private BigPtrEntry |
81 | { |
82 | friend class SwNodes; |
83 | |
84 | SwNodeType m_nNodeType; |
85 | |
86 | /// For text nodes: level of auto format. Was put here because we had still free bits. |
87 | sal_uInt8 m_nAFormatNumLvl : 3; |
88 | bool m_bIgnoreDontExpand : 1; ///< for Text Attributes - ignore the flag |
89 | |
90 | public: |
91 | /// sw_redlinehide: redline node merge state |
92 | enum class Merge { None, First, NonFirst, Hidden }; |
93 | bool IsCreateFrameWhenHidingRedlines() const { |
94 | return m_eMerge == Merge::None || m_eMerge == Merge::First; |
95 | } |
96 | void SetRedlineMergeFlag(Merge const eMerge) { m_eMerge = eMerge; } |
97 | Merge GetRedlineMergeFlag() const { return m_eMerge; } |
98 | private: |
99 | Merge m_eMerge; |
100 | |
101 | #ifdef DBG_UTIL |
102 | static long s_nSerial; |
103 | long m_nSerial; |
104 | #endif |
105 | |
106 | /// all SwFrameFormat that are anchored at the node |
107 | /// invariant: SwFrameFormat is in the list iff |
108 | /// SwFrameFormat::GetAnchor().GetContentAnchor() points to this node |
109 | std::unique_ptr<std::vector<SwFrameFormat*>> m_pAnchoredFlys; |
110 | |
111 | protected: |
112 | SwStartNode* m_pStartOfSection; |
113 | |
114 | SwNode( const SwNodeIndex &rWhere, const SwNodeType nNodeId ); |
115 | |
116 | /// for the initial StartNode |
117 | SwNode( SwNodes& rNodes, sal_uLong nPos, const SwNodeType nNodeId ); |
118 | |
119 | public: |
120 | /** the = 0 forces the class to be an abstract base class, but the dtor can be still called |
121 | from subclasses */ |
122 | virtual ~SwNode() override = 0; |
123 | |
124 | #ifdef DBG_UTIL |
125 | long GetSerial() const { return m_nSerial; } |
126 | #endif |
127 | |
128 | sal_uInt16 GetSectionLevel() const; |
129 | |
130 | inline sal_uLong StartOfSectionIndex() const; |
131 | const SwStartNode* StartOfSectionNode() const { return m_pStartOfSection; } |
132 | SwStartNode* StartOfSectionNode() { return m_pStartOfSection; } |
133 | |
134 | inline sal_uLong EndOfSectionIndex() const; |
135 | inline const SwEndNode* EndOfSectionNode() const; |
136 | inline SwEndNode* EndOfSectionNode(); |
137 | |
138 | sal_uInt8 GetAutoFormatLvl() const { return m_nAFormatNumLvl; } |
139 | void SetAutoFormatLvl( sal_uInt8 nVal ) { m_nAFormatNumLvl = nVal; } |
140 | |
141 | bool IsIgnoreDontExpand() const { return m_bIgnoreDontExpand; } |
142 | void SetIgnoreDontExpand( bool bNew ) { m_bIgnoreDontExpand = bNew; } |
143 | |
144 | SwNodeType GetNodeType() const { return m_nNodeType; } |
145 | |
146 | inline SwStartNode *GetStartNode(); |
147 | inline const SwStartNode *GetStartNode() const; |
148 | inline SwContentNode *GetContentNode(); |
149 | inline const SwContentNode *GetContentNode() const; |
150 | inline SwEndNode *GetEndNode(); |
151 | inline const SwEndNode *GetEndNode() const; |
152 | inline SwTextNode *GetTextNode(); |
153 | inline const SwTextNode *GetTextNode() const; |
154 | inline SwOLENode *GetOLENode(); |
155 | inline const SwOLENode *GetOLENode() const; |
156 | inline SwNoTextNode *GetNoTextNode(); |
157 | inline const SwNoTextNode *GetNoTextNode() const; |
158 | inline SwGrfNode *GetGrfNode(); |
159 | inline const SwGrfNode *GetGrfNode() const; |
160 | inline SwTableNode *GetTableNode(); |
161 | inline const SwTableNode *GetTableNode() const; |
162 | inline SwSectionNode *GetSectionNode(); |
163 | inline const SwSectionNode *GetSectionNode() const; |
164 | |
165 | inline bool IsStartNode() const; |
166 | inline bool IsContentNode() const; |
167 | inline bool IsEndNode() const; |
168 | inline bool IsTextNode() const; |
169 | inline bool IsTableNode() const; |
170 | inline bool IsSectionNode() const; |
171 | inline bool IsOLENode() const; |
172 | inline bool IsNoTextNode() const; |
173 | inline bool IsGrfNode() const; |
174 | |
175 | /** |
176 | Checks if this node is in redlines. |
177 | |
178 | @retval true this node is in redlines |
179 | @retval false else |
180 | */ |
181 | bool IsInRedlines() const; |
182 | |
183 | /** Search table node, in which it is. If it is in no table |
184 | @return 0. */ |
185 | SwTableNode *FindTableNode(); |
186 | inline const SwTableNode *FindTableNode() const; |
187 | |
188 | /** Search section node, in which it is. If it is in no section |
189 | @return 0. */ |
190 | SwSectionNode *FindSectionNode(); |
191 | inline const SwSectionNode *FindSectionNode() const; |
192 | |
193 | SwStartNode* FindSttNodeByType( SwStartNodeType eTyp ); |
194 | inline const SwStartNode* FindSttNodeByType( SwStartNodeType eTyp ) const; |
195 | |
196 | const SwStartNode* FindTableBoxStartNode() const |
197 | { return FindSttNodeByType( SwTableBoxStartNode ); } |
198 | const SwStartNode* FindFlyStartNode() const |
199 | { return FindSttNodeByType( SwFlyStartNode ); } |
200 | const SwStartNode* FindFootnoteStartNode() const |
201 | { return FindSttNodeByType( SwFootnoteStartNode ); } |
202 | const SwStartNode* FindHeaderStartNode() const |
203 | { return FindSttNodeByType( SwHeaderStartNode ); } |
204 | const SwStartNode* FindFooterStartNode() const |
205 | { return FindSttNodeByType( SwFooterStartNode ); } |
206 | |
207 | /// Node is in which nodes-array/doc? |
208 | inline SwNodes& GetNodes(); |
209 | inline const SwNodes& GetNodes() const; |
210 | |
211 | SwDoc& GetDoc() |
212 | { |
213 | return GetNodes().GetDoc(); |
214 | } |
215 | |
216 | const SwDoc& GetDoc() const |
217 | { |
218 | return GetNodes().GetDoc(); |
219 | } |
220 | |
221 | /** Provides access to the document setting interface |
222 | */ |
223 | const IDocumentSettingAccess* getIDocumentSettingAccess() const; |
224 | |
225 | /** Provides access to the document device interface |
226 | */ |
227 | const IDocumentDeviceAccess& getIDocumentDeviceAccess() const; |
228 | |
229 | /** Provides access to the document bookmark interface |
230 | */ |
231 | const IDocumentMarkAccess* getIDocumentMarkAccess() const; |
232 | |
233 | /** Provides access to the document redline interface |
234 | */ |
235 | const IDocumentRedlineAccess& getIDocumentRedlineAccess() const; |
236 | |
237 | /** Provides access to the document style pool interface |
238 | */ |
239 | const IDocumentStylePoolAccess& getIDocumentStylePoolAccess() const; |
240 | |
241 | /** Provides access to the document draw model interface |
242 | */ |
243 | const IDocumentDrawModelAccess& getIDocumentDrawModelAccess() const; |
244 | |
245 | /** Provides access to the document layout interface |
246 | */ |
247 | const IDocumentLayoutAccess& getIDocumentLayoutAccess() const; |
248 | IDocumentLayoutAccess& getIDocumentLayoutAccess(); |
249 | |
250 | /** Provides access to the document links administration interface |
251 | */ |
252 | const IDocumentLinksAdministration& getIDocumentLinksAdministration() const; |
253 | IDocumentLinksAdministration& getIDocumentLinksAdministration(); |
254 | |
255 | /** Provides access to the document fields administration interface |
256 | */ |
257 | const IDocumentFieldsAccess& getIDocumentFieldsAccess() const; |
258 | IDocumentFieldsAccess& getIDocumentFieldsAccess(); |
259 | |
260 | /** Provides access to the document content operations interface |
261 | */ |
262 | IDocumentContentOperations& getIDocumentContentOperations(); |
263 | |
264 | /** Provides access to the document automatic styles interface |
265 | */ |
266 | IStyleAccess& getIDocumentStyleAccess(); |
267 | |
268 | /** Provides access to the document's numbered items interface */ |
269 | IDocumentListItems& getIDocumentListItems(); |
270 | |
271 | /// Is node in the visible area of the Shell? |
272 | bool IsInVisibleArea( SwViewShell const * pSh ) const; |
273 | /// Is node in a protected area? |
274 | bool IsInProtectSect() const; |
275 | /** Is node in something that is protected (range, frame, |
276 | table cells ... including anchor in case of frames or footnotes)? */ |
277 | bool IsProtect() const; |
278 | |
279 | /** Search PageDesc with which this node is formatted. If layout is existent |
280 | search over layout, else only the hard way is left: search over the nodes |
281 | to the front!! */ |
282 | const SwPageDesc* FindPageDesc( size_t* pPgDescNdIdx = nullptr ) const; |
283 | |
284 | /// If node is in a fly return the respective format. |
285 | SwFrameFormat* GetFlyFormat() const; |
286 | |
287 | /// If node is in a table return the respective table box. |
288 | SwTableBox* GetTableBox() const; |
289 | |
290 | sal_uLong GetIndex() const { return GetPos(); } |
291 | |
292 | const SwTextNode* FindOutlineNodeOfLevel(sal_uInt8 nLvl, SwRootFrame const* pLayout = nullptr) const; |
293 | |
294 | sal_uInt8 HasPrevNextLayNode() const; |
295 | |
296 | std::vector<SwFrameFormat *> const* GetAnchoredFlys() const { return m_pAnchoredFlys.get(); } |
297 | void AddAnchoredFly(SwFrameFormat *); |
298 | void RemoveAnchoredFly(SwFrameFormat *); |
299 | |
300 | /** |
301 | * Dumps the node structure to the given destination (file nodes.xml in the current directory by default) |
302 | */ |
303 | virtual void dumpAsXml(xmlTextWriterPtr pWriter) const; |
304 | |
305 | private: |
306 | SwNode( const SwNode & rNodes ) = delete; |
307 | SwNode & operator= ( const SwNode & rNodes ) = delete; |
308 | }; |
309 | |
310 | /// Starts a section of nodes in the document model. |
311 | class SAL_DLLPUBLIC_RTTI__attribute__ ((type_visibility("default"))) SwStartNode: public SwNode |
312 | { |
313 | friend class SwNode; |
314 | friend class SwNodes; |
315 | friend class SwEndNode; ///< to set the theEndOfSection !! |
316 | |
317 | SwEndNode* m_pEndOfSection; |
318 | SwStartNodeType m_eStartNodeType; |
319 | |
320 | /// for the initial StartNode |
321 | SwStartNode( SwNodes& rNodes, sal_uLong nPos ); |
322 | |
323 | protected: |
324 | SwStartNode( const SwNodeIndex &rWhere, |
325 | const SwNodeType nNodeType = SwNodeType::Start, |
326 | SwStartNodeType = SwNormalStartNode ); |
327 | public: |
328 | SwStartNodeType GetStartNodeType() const { return m_eStartNodeType; } |
329 | |
330 | /// Call ChkCondcoll to all ContentNodes of section. |
331 | void CheckSectionCondColl() const; |
332 | |
333 | virtual void dumpAsXml(xmlTextWriterPtr pWriter) const override; |
334 | |
335 | private: |
336 | SwStartNode( const SwStartNode & rNode ) = delete; |
337 | SwStartNode & operator= ( const SwStartNode & rNode ) = delete; |
338 | }; |
339 | |
340 | /// Ends a section of nodes in the document model. |
341 | class SwEndNode : public SwNode |
342 | { |
343 | friend class SwNodes; |
344 | friend class SwTableNode; ///< To enable creation of its EndNote. |
345 | friend class SwSectionNode; ///< To enable creation of its EndNote. |
346 | |
347 | /// for the initial StartNode |
348 | SwEndNode( SwNodes& rNodes, sal_uLong nPos, SwStartNode& rSttNd ); |
349 | |
350 | protected: |
351 | SwEndNode( const SwNodeIndex &rWhere, SwStartNode& rSttNd ); |
352 | |
353 | private: |
354 | SwEndNode( const SwEndNode & rNode ) = delete; |
355 | SwEndNode & operator= ( const SwEndNode & rNode ) = delete; |
356 | }; |
357 | |
358 | // SwContentNode |
359 | |
360 | class SW_DLLPUBLIC__attribute__ ((visibility("default"))) SwContentNode: public sw::BroadcastingModify, public SwNode, public SwIndexReg |
361 | { |
362 | |
363 | sw::WriterMultiListener m_aCondCollListener; |
364 | SwFormatColl* m_pCondColl; |
365 | mutable bool mbSetModifyAtAttr; |
366 | |
367 | protected: |
368 | SwContentNode( const SwNodeIndex &rWhere, const SwNodeType nNodeType, |
369 | SwFormatColl *pFormatColl ); |
370 | /** the = 0 forces the class to be an abstract base class, but the dtor can be still called |
371 | from subclasses */ |
372 | virtual ~SwContentNode() override = 0; |
373 | |
374 | /** Attribute-set for all auto attributes of a ContentNode. |
375 | (e.g. TextNode or NoTextNode). */ |
376 | std::shared_ptr<const SfxItemSet> mpAttrSet; |
377 | |
378 | /// Make respective nodes create the specific AttrSets. |
379 | virtual void NewAttrSet( SwAttrPool& ) = 0; |
380 | |
381 | /** There some functions that like to remove items from the internal |
382 | SwAttrSet (handle): */ |
383 | sal_uInt16 ClearItemsFromAttrSet( const std::vector<sal_uInt16>& rWhichIds ); |
384 | |
385 | virtual void SwClientNotify( const SwModify&, const SfxHint& rHint) override; |
386 | |
387 | public: |
388 | |
389 | /** MakeFrame will be called for a certain layout |
390 | pSib is another SwFrame of the same layout (e.g. the SwRootFrame itself, a sibling, the parent) */ |
391 | virtual SwContentFrame *MakeFrame( SwFrame* pSib ) = 0; |
392 | |
393 | virtual SwContentNode *JoinNext(); |
394 | /** Is it possible to join two nodes? |
395 | In pIdx the second position can be returned. */ |
396 | bool CanJoinNext( SwNodeIndex* pIdx =nullptr ) const; |
397 | bool CanJoinPrev( SwNodeIndex* pIdx =nullptr ) const; |
398 | |
399 | void MakeStartIndex( SwIndex * pIdx ) { pIdx->Assign( this, 0 ); } |
400 | void MakeEndIndex( SwIndex * pIdx ) { pIdx->Assign( this, Len() ); } |
401 | |
402 | bool GoNext(SwIndex *, sal_uInt16 nMode ) const; |
403 | bool GoPrevious(SwIndex *, sal_uInt16 nMode ) const; |
404 | |
405 | /// @see GetFrameOfModify |
406 | SwContentFrame *getLayoutFrame( const SwRootFrame*, |
407 | const SwPosition *pPos = nullptr, |
408 | std::pair<Point, bool> const* pViewPosAndCalcFrame = nullptr) const; |
409 | /** @return the real size of the frame or an empty rectangle if |
410 | no layout exists. Needed for export filters. */ |
411 | SwRect FindLayoutRect( const bool bPrtArea = false, |
412 | const Point* pPoint = nullptr ) const; |
413 | SwRect FindPageFrameRect() const; |
414 | |
415 | /** Method creates all views of document for given node. The content |
416 | frames that are created are put in the respective layout. */ |
417 | void MakeFramesForAdjacentContentNode(SwContentNode& rNode); |
418 | |
419 | /** Method deletes all views of document for the node. The content- |
420 | frames are removed from the respective layout. |
421 | */ |
422 | void DelFrames(SwRootFrame const* pLayout); |
423 | |
424 | /** @return count of elements of node content. Default is 1. |
425 | There are differences between text node and formula node. */ |
426 | virtual sal_Int32 Len() const; |
427 | |
428 | virtual SwContentNode* MakeCopy(SwDoc&, const SwNodeIndex&, bool bNewFrames) const = 0; |
429 | |
430 | /// Get information from Client. |
431 | virtual bool GetInfo( SfxPoolItem& ) const override; |
432 | |
433 | /// SS for PoolItems: hard attributation. |
434 | |
435 | /// If bInParent is FALSE search for attribute only in this node. |
436 | const SfxPoolItem& GetAttr( sal_uInt16 nWhich, bool bInParent=true ) const; |
437 | bool GetAttr( SfxItemSet& rSet ) const; |
438 | /// made virtual |
439 | virtual bool SetAttr( const SfxPoolItem& ); |
440 | virtual bool SetAttr( const SfxItemSet& rSet ); |
441 | virtual bool ResetAttr( sal_uInt16 nWhich1, sal_uInt16 nWhich2 = 0 ); |
442 | virtual bool ResetAttr( const std::vector<sal_uInt16>& rWhichArr ); |
443 | virtual sal_uInt16 ResetAllAttr(); |
444 | |
445 | /// Obtains attribute that is not delivered via conditional style! |
446 | const SfxPoolItem* GetNoCondAttr( sal_uInt16 nWhich, bool bInParents ) const; |
447 | |
448 | /** Does node has already its own auto-attributes? |
449 | Access to SwAttrSet. */ |
450 | inline const SwAttrSet &GetSwAttrSet() const; |
451 | const SwAttrSet *GetpSwAttrSet() const { return static_cast<const SwAttrSet*>(mpAttrSet.get()); } |
452 | bool HasSwAttrSet() const { return mpAttrSet != nullptr; } |
453 | |
454 | virtual SwFormatColl* ChgFormatColl( SwFormatColl* ); |
455 | SwFormatColl* GetFormatColl() const { return const_cast<SwFormatColl*>(static_cast<const SwFormatColl*>(GetRegisteredIn())); } |
456 | |
457 | //FEATURE::CONDCOLL |
458 | inline SwFormatColl& GetAnyFormatColl() const; |
459 | void SetCondFormatColl( SwFormatColl* ); |
460 | inline SwFormatColl* GetCondFormatColl() const; |
461 | |
462 | bool IsAnyCondition( SwCollCondition& rTmp ) const; |
463 | void ChkCondColl(); |
464 | //FEATURE::CONDCOLL |
465 | |
466 | /** Invalidates NumRule at the node. NumRule is updated |
467 | on EndAction of a Shell at the latest. */ |
468 | bool InvalidateNumRule(); |
469 | |
470 | /** determines the text direction for a certain |
471 | position. @return -1, if text direction could *not* be determined. */ |
472 | SvxFrameDirection GetTextDirection( const SwPosition& rPos, |
473 | const Point* pPt ) const; |
474 | |
475 | void SetModifyAtAttr( bool bSetModifyAtAttr ) const { mbSetModifyAtAttr = bSetModifyAtAttr; } |
476 | bool GetModifyAtAttr() const { return mbSetModifyAtAttr; } |
477 | |
478 | static std::unique_ptr<SwOLENodes> CreateOLENodesArray( const SwFormatColl& rColl, bool bOnlyWithInvalidSize ); |
479 | |
480 | // Access to DrawingLayer FillAttributes in a preprocessed form for primitive usage |
481 | virtual drawinglayer::attribute::SdrAllFillAttributesHelperPtr getSdrAllFillAttributesHelper() const; |
482 | |
483 | virtual void ModifyNotification(const SfxPoolItem* pOld, const SfxPoolItem* pNew) override |
484 | { |
485 | SwClientNotify(*this, sw::LegacyModifyHint(pOld, pNew)); |
486 | } |
487 | |
488 | private: |
489 | SwContentNode( const SwContentNode & rNode ) = delete; |
490 | SwContentNode & operator= ( const SwContentNode & rNode ) = delete; |
491 | }; |
492 | |
493 | // SwTableNode |
494 | |
495 | class SW_DLLPUBLIC__attribute__ ((visibility("default"))) SwTableNode : public SwStartNode, public sw::BroadcastingModify |
496 | { |
497 | friend class SwNodes; |
498 | std::unique_ptr<SwTable> m_pTable; |
499 | protected: |
500 | virtual ~SwTableNode() override; |
501 | |
502 | public: |
503 | SwTableNode( const SwNodeIndex & ); |
504 | |
505 | const SwTable& GetTable() const { return *m_pTable; } |
506 | SwTable& GetTable() { return *m_pTable; } |
507 | SwTabFrame *MakeFrame( SwFrame* ); |
508 | |
509 | /// Creates the frms for the table node (i.e. the TabFrames). |
510 | void MakeOwnFrames(SwNodeIndex* pIdxBehind); |
511 | |
512 | /** Method deletes all views of document for the node. |
513 | The content frames are removed from the respective layout. */ |
514 | void DelFrames(SwRootFrame const* pLayout = nullptr); |
515 | |
516 | /** Method creates all views of the document for the previous node. |
517 | The content frames that are created are put into the respective layout. */ |
518 | void MakeFramesForAdjacentContentNode(const SwNodeIndex & rIdx); |
519 | |
520 | SwTableNode* MakeCopy( SwDoc&, const SwNodeIndex& ) const; |
521 | void SetNewTable( std::unique_ptr<SwTable> , bool bNewFrames=true ); |
522 | |
523 | // Removes redline objects that relate to this table from the 'Extra Redlines' table |
524 | void RemoveRedlines(); |
525 | |
526 | private: |
527 | SwTableNode( const SwTableNode & rNode ) = delete; |
528 | SwTableNode & operator= ( const SwTableNode & rNode ) = delete; |
529 | }; |
530 | |
531 | class SAL_DLLPUBLIC_RTTI__attribute__ ((type_visibility("default"))) SwSectionNode |
532 | : public SwStartNode |
533 | { |
534 | friend class SwNodes; |
535 | |
536 | private: |
537 | SwSectionNode(const SwSectionNode&) = delete; |
538 | SwSectionNode& operator=(const SwSectionNode&) = delete; |
539 | |
540 | std::unique_ptr<SwSection> const m_pSection; |
541 | |
542 | protected: |
543 | virtual ~SwSectionNode() override; |
544 | |
545 | public: |
546 | SwSectionNode(SwNodeIndex const&, |
547 | SwSectionFormat & rFormat, SwTOXBase const*const pTOXBase); |
548 | |
549 | const SwSection& GetSection() const { return *m_pSection; } |
550 | SwSection& GetSection() { return *m_pSection; } |
551 | |
552 | SwFrame *MakeFrame( SwFrame* ); |
553 | |
554 | /** Creates the frms for the SectionNode (i.e. the SectionFrames). |
555 | On default the frames are created until the end of the range. |
556 | When another NodeIndex pEnd is passed a MakeFrames is called up to it. |
557 | Used by TableToText. */ |
558 | void MakeOwnFrames(SwNodeIndex* pIdxBehind, SwNodeIndex* pEnd = nullptr); |
559 | |
560 | /** Method deletes all views of document for the node. The |
561 | content frames are removed from the respective layout. */ |
562 | void DelFrames(SwRootFrame const* pLayout = nullptr, bool bForce = false); |
563 | |
564 | /** Method creates all views of document for the previous node. |
565 | The content frames created are put into the respective layout. */ |
566 | void MakeFramesForAdjacentContentNode(const SwNodeIndex & rIdx); |
567 | |
568 | SwSectionNode* MakeCopy( SwDoc&, const SwNodeIndex& ) const; |
569 | |
570 | /// Set pointer in format of section on itself. |
571 | void NodesArrChgd(); |
572 | |
573 | /** Check for not hidden areas whether there is content that is not in |
574 | a hidden sub-area. */ |
575 | bool IsContentHidden() const; |
576 | |
577 | }; |
578 | |
579 | /** This class is internal, used only during DocumentContentOperationsManager::CopyWithFlyInFly(), and for undo. |
580 | |
581 | Some of the nodes are then replaced with SwPlaceholderNode, and at the end of the operation, removed again. |
582 | FIXME find out if this is really necessary, and if we can avoid creation of the SwPlaceholderNodes in the first place. |
583 | */ |
584 | class SwPlaceholderNode final : private SwNode |
585 | { |
586 | private: |
587 | friend class SwNodes; |
588 | SwPlaceholderNode(const SwNodeIndex &rWhere); |
589 | }; |
590 | |
591 | inline SwEndNode *SwNode::GetEndNode() |
592 | { |
593 | return SwNodeType::End == m_nNodeType ? static_cast<SwEndNode*>(this) : nullptr; |
594 | } |
595 | inline const SwEndNode *SwNode::GetEndNode() const |
596 | { |
597 | return SwNodeType::End == m_nNodeType ? static_cast<const SwEndNode*>(this) : nullptr; |
598 | } |
599 | inline SwStartNode *SwNode::GetStartNode() |
600 | { |
601 | return SwNodeType::Start & m_nNodeType ? static_cast<SwStartNode*>(this) : nullptr; |
602 | } |
603 | inline const SwStartNode *SwNode::GetStartNode() const |
604 | { |
605 | return SwNodeType::Start & m_nNodeType ? static_cast<const SwStartNode*>(this) : nullptr; |
606 | } |
607 | inline SwTableNode *SwNode::GetTableNode() |
608 | { |
609 | return SwNodeType::Table == m_nNodeType ? static_cast<SwTableNode*>(this) : nullptr; |
610 | } |
611 | inline const SwTableNode *SwNode::GetTableNode() const |
612 | { |
613 | return SwNodeType::Table == m_nNodeType ? static_cast<const SwTableNode*>(this) : nullptr; |
614 | } |
615 | inline SwSectionNode *SwNode::GetSectionNode() |
616 | { |
617 | return SwNodeType::Section == m_nNodeType ? static_cast<SwSectionNode*>(this) : nullptr; |
618 | } |
619 | inline const SwSectionNode *SwNode::GetSectionNode() const |
620 | { |
621 | return SwNodeType::Section == m_nNodeType ? static_cast<const SwSectionNode*>(this) : nullptr; |
622 | } |
623 | inline SwContentNode *SwNode::GetContentNode() |
624 | { |
625 | return SwNodeType::ContentMask & m_nNodeType ? static_cast<SwContentNode*>(this) : nullptr; |
626 | } |
627 | inline const SwContentNode *SwNode::GetContentNode() const |
628 | { |
629 | return SwNodeType::ContentMask & m_nNodeType ? static_cast<const SwContentNode*>(this) : nullptr; |
630 | } |
631 | |
632 | inline bool SwNode::IsStartNode() const |
633 | { |
634 | return bool(SwNodeType::Start & m_nNodeType); |
635 | } |
636 | inline bool SwNode::IsContentNode() const |
637 | { |
638 | return bool(SwNodeType::ContentMask & m_nNodeType); |
639 | } |
640 | inline bool SwNode::IsEndNode() const |
641 | { |
642 | return SwNodeType::End == m_nNodeType; |
643 | } |
644 | inline bool SwNode::IsTextNode() const |
645 | { |
646 | return SwNodeType::Text == m_nNodeType; |
647 | } |
648 | inline bool SwNode::IsTableNode() const |
649 | { |
650 | return SwNodeType::Table == m_nNodeType; |
651 | } |
652 | inline bool SwNode::IsSectionNode() const |
653 | { |
654 | return SwNodeType::Section == m_nNodeType; |
655 | } |
656 | inline bool SwNode::IsNoTextNode() const |
657 | { |
658 | return bool(SwNodeType::NoTextMask & m_nNodeType); |
659 | } |
660 | inline bool SwNode::IsOLENode() const |
661 | { |
662 | return SwNodeType::Ole == m_nNodeType; |
663 | } |
664 | inline bool SwNode::IsGrfNode() const |
665 | { |
666 | return SwNodeType::Grf == m_nNodeType; |
667 | } |
668 | |
669 | inline const SwStartNode* SwNode::FindSttNodeByType( SwStartNodeType eTyp ) const |
670 | { |
671 | return const_cast<SwNode*>(this)->FindSttNodeByType( eTyp ); |
672 | } |
673 | inline const SwTableNode* SwNode::FindTableNode() const |
674 | { |
675 | return const_cast<SwNode*>(this)->FindTableNode(); |
676 | } |
677 | inline const SwSectionNode* SwNode::FindSectionNode() const |
678 | { |
679 | return const_cast<SwNode*>(this)->FindSectionNode(); |
680 | } |
681 | inline sal_uLong SwNode::StartOfSectionIndex() const |
682 | { |
683 | return m_pStartOfSection->GetIndex(); |
684 | } |
685 | inline sal_uLong SwNode::EndOfSectionIndex() const |
686 | { |
687 | const SwStartNode* pStNd = IsStartNode() ? static_cast<const SwStartNode*>(this) : m_pStartOfSection; |
688 | return pStNd->m_pEndOfSection->GetIndex(); |
689 | } |
690 | inline const SwEndNode* SwNode::EndOfSectionNode() const |
691 | { |
692 | const SwStartNode* pStNd = IsStartNode() ? static_cast<const SwStartNode*>(this) : m_pStartOfSection; |
693 | return pStNd->m_pEndOfSection; |
694 | } |
695 | inline SwEndNode* SwNode::EndOfSectionNode() |
696 | { |
697 | const SwStartNode* pStNd = IsStartNode() ? static_cast<const SwStartNode*>(this) : m_pStartOfSection; |
698 | return pStNd->m_pEndOfSection; |
699 | } |
700 | |
701 | inline SwNodes& SwNode::GetNodes() |
702 | { |
703 | return static_cast<SwNodes&>(GetArray()); |
704 | } |
705 | inline const SwNodes& SwNode::GetNodes() const |
706 | { |
707 | return static_cast<SwNodes&>(GetArray()); |
708 | } |
709 | |
710 | inline SwFormatColl* SwContentNode::GetCondFormatColl() const |
711 | { |
712 | return m_pCondColl; |
713 | } |
714 | |
715 | inline SwFormatColl& SwContentNode::GetAnyFormatColl() const |
716 | { |
717 | return m_pCondColl |
718 | ? *m_pCondColl |
719 | : *const_cast<SwFormatColl*>(static_cast<const SwFormatColl*>(GetRegisteredIn())); |
720 | } |
721 | |
722 | inline const SwAttrSet& SwContentNode::GetSwAttrSet() const |
723 | { |
724 | return mpAttrSet ? *GetpSwAttrSet() : GetAnyFormatColl().GetAttrSet(); |
725 | } |
726 | |
727 | //FEATURE::CONDCOLL |
728 | |
729 | inline const SfxPoolItem& SwContentNode::GetAttr( sal_uInt16 nWhich, |
730 | bool bInParents ) const |
731 | { |
732 | return GetSwAttrSet().Get( nWhich, bInParents ); |
733 | } |
734 | |
735 | inline SwPlaceholderNode::SwPlaceholderNode(const SwNodeIndex &rWhere) |
736 | : SwNode(rWhere, SwNodeType::PlaceHolder) |
737 | { |
738 | } |
739 | |
740 | inline SwNodePtr SwNodes::operator[]( sal_uLong n ) const |
741 | { |
742 | return static_cast<SwNodePtr>(BigPtrArray::operator[] ( n )); |
743 | } |
744 | |
745 | #endif |
746 | |
747 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
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 | |
31 | namespace o3tl { |
32 | |
33 | namespace detail { |
34 | |
35 | template<typename T> constexpr |
36 | typename std::enable_if<std::is_signed<T>::value, bool>::type isNonNegative( |
37 | T value) |
38 | { |
39 | return value >= 0; |
40 | } |
41 | |
42 | template<typename T> constexpr |
43 | typename std::enable_if<std::is_unsigned<T>::value, bool>::type isNonNegative(T) |
44 | { |
45 | return true; |
46 | } |
47 | |
48 | } |
49 | |
50 | template<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. |
65 | template<typename E, typename std::underlying_type<E>::type M> |
66 | struct 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; } |
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 | |
104 | template<typename E> |
105 | constexpr 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 | |
114 | template<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 | |
122 | template<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 | |
136 | template<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 | |
147 | template<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 | |
158 | template<typename W> constexpr |
159 | typename 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 | |
167 | template<typename E> |
168 | constexpr 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 | |
180 | template<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 | |
191 | template<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 | |
202 | template<typename W> constexpr |
203 | typename 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 | |
211 | template<typename E> |
212 | constexpr 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 | |
224 | template<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 | |
235 | template<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 | |
246 | template<typename W> constexpr |
247 | typename 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 | |
255 | template<typename E> |
256 | inline 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 | |
267 | template<typename E> |
268 | inline 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 | |
278 | template<typename E> |
279 | inline 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 | |
290 | template<typename E> |
291 | inline 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 | |
301 | template<typename E> |
302 | inline 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 | |
313 | template<typename E> |
314 | inline 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: */ |