LibreOffice Module sw (master) 1
flycnt.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <sal/log.hxx>
21#include <osl/diagnose.h>
22#include <svx/swframetypes.hxx>
23#include <pagefrm.hxx>
24#include <txtfrm.hxx>
25#include <notxtfrm.hxx>
26#include <doc.hxx>
27#include <pam.hxx>
28#include <IDocumentUndoRedo.hxx>
31#include <frmtool.hxx>
32#include <dflyobj.hxx>
33#include <fmtanchr.hxx>
34#include <fmtornt.hxx>
35#include <fmtfsize.hxx>
36#include <fmtsrnd.hxx>
37#include <txatbase.hxx>
38
39#include <tabfrm.hxx>
40#include <flyfrms.hxx>
41#include <crstate.hxx>
42#include <sectfrm.hxx>
43
45#include <sortedobjs.hxx>
46#include <layouter.hxx>
49#include <ndtxt.hxx>
50#include <textboxhelper.hxx>
51#include <fmtfollowtextflow.hxx>
52#include <unoprnms.hxx>
53#include <rootfrm.hxx>
54#include <bodyfrm.hxx>
55
56using namespace ::com::sun::star;
57
58namespace
59{
60
61SwTwips lcl_GetTopForObjPos(const SwContentFrame* pCnt, const bool bVert, const bool bVertL2R)
62{
63 if ( bVert )
64 {
65 SwTwips aResult = pCnt->getFrameArea().Left();
66 if ( bVertL2R )
67 aResult += pCnt->GetUpperSpaceAmountConsideredForPrevFrameAndPageGrid();
68 else
69 aResult += pCnt->getFrameArea().Width() - pCnt->GetUpperSpaceAmountConsideredForPrevFrameAndPageGrid();
70 return aResult;
71 }
72 else
73 return pCnt->getFrameArea().Top() + pCnt->GetUpperSpaceAmountConsideredForPrevFrameAndPageGrid();
74}
75
76}
77
79 SwFlyFreeFrame( pFormat, pSib, pAnch, bFollow ),
80 SwFlowFrame(static_cast<SwFrame&>(*this))
81{
82 m_bAtCnt = true;
83 m_bAutoPosition = (RndStdIds::FLY_AT_CHAR == pFormat->GetAnchor().GetAnchorId());
84}
85
87 : SwFlyAtContentFrame(rPrecede.GetFormat(), const_cast<SwFrame*>(rPrecede.GetAnchorFrame()),
88 const_cast<SwFrame*>(rPrecede.GetAnchorFrame()), /*bFollow=*/true)
89{
90 SetFollow(rPrecede.GetFollow());
91 rPrecede.SetFollow(this);
92}
93
95{
96}
97
98// #i28701#
99
101{
102 if (rHint.GetId() != SfxHintId::SwLegacyModify)
103 {
104 SwFlyFrame::SwClientNotify(rMod, rHint);
105 return;
106 }
107 auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
108 const SwFormatAnchor* pAnch = pLegacy->m_pNew ? GetAnchorFromPoolItem(*pLegacy->m_pNew) : nullptr;
109 if(!pAnch)
110 {
111 SwFlyFrame::SwClientNotify(rMod, rHint);
112 return;
113 }
114 OSL_ENSURE(pAnch->GetAnchorId() == GetFormat()->GetAnchor().GetAnchorId(),
115 "Illegal change of anchor type.");
116
117 //Unregister, get hold of a new anchor and attach it
119 SwPageFrame* pOldPage = FindPageFrame();
120 const SwFrame* pOldAnchor = GetAnchorFrame();
121 SwContentFrame* pContent = const_cast<SwContentFrame*>(static_cast<const SwContentFrame*>(GetAnchorFrame()));
122 AnchorFrame()->RemoveFly(this);
123
124 const bool bBodyFootnote = (pContent->IsInDocBody() || pContent->IsInFootnote());
125
126 // Search the new anchor using the NodeIdx; the relation between old
127 // and new NodeIdx determines the search direction
128 const SwNodeIndex aNewIdx(*pAnch->GetAnchorNode());
129 SwNodeIndex aOldIdx(pContent->IsTextFrame()
130 // sw_redlinehide: can pick any node here, the compare with
131 // FrameContainsNode should catch it
132 ? *static_cast<SwTextFrame *>(pContent)->GetTextNodeFirst()
133 : *static_cast<SwNoTextFrame *>(pContent)->GetNode());
134
135 //fix: depending on which index was smaller, searching in the do-while
136 //loop previously was done forward or backwards respectively. This however
137 //could lead to an infinite loop. To at least avoid the loop, searching
138 //is now done in only one direction. Getting hold of a frame from the node
139 //is still possible if the new anchor could not be found. Chances are
140 //good that this will be the correct one.
141 // consider the case that at found anchor frame candidate already a
142 // fly frame of the given fly format is registered.
143 // consider, that <pContent> is the already
144 // the new anchor frame.
145 bool bFound(FrameContainsNode(*pContent, aNewIdx.GetIndex()));
146 const bool bNext = !bFound && aOldIdx < aNewIdx;
147 while(pContent && !bFound)
148 {
149 do
150 {
151 if(bNext)
152 pContent = pContent->GetNextContentFrame();
153 else
154 pContent = pContent->GetPrevContentFrame();
155 } while(pContent &&
156 (bBodyFootnote != (pContent->IsInDocBody() || pContent->IsInFootnote())));
157 if(pContent)
158 bFound = FrameContainsNode(*pContent, aNewIdx.GetIndex());
159
160 // check, if at found anchor frame candidate already a fly frame
161 // of the given fly frame format is registered.
162 if(bFound && pContent && pContent->GetDrawObjs())
163 {
164 SwFrameFormat* pMyFlyFrameFormat(&GetFrameFormat());
165 SwSortedObjs &rObjs = *pContent->GetDrawObjs();
166 for(SwAnchoredObject* rObj : rObjs)
167 {
168 SwFlyFrame* pFlyFrame = rObj->DynCastFlyFrame();
169 if (pFlyFrame &&
170 &(pFlyFrame->GetFrameFormat()) == pMyFlyFrameFormat)
171 {
172 bFound = false;
173 break;
174 }
175 }
176 }
177 }
178 if(!pContent)
179 {
180 SwContentNode *pNode = aNewIdx.GetNode().GetContentNode();
181 std::pair<Point, bool> const tmp(pOldAnchor->getFrameArea().Pos(), false);
182 pContent = pNode->getLayoutFrame(getRootFrame(), nullptr, &tmp);
183 OSL_ENSURE(pContent, "New anchor not found");
184 }
185 //Flys are never attached to a follow, but always on the master which
186 //we are going to search now.
187 SwContentFrame* pFlow = pContent;
188 while(pFlow->IsFollow())
189 pFlow = pFlow->FindMaster();
190 pContent = pFlow;
191
192 //and *puff* it's attached...
193 pContent->AppendFly( this );
194 if(pOldPage && pOldPage != FindPageFrame())
196
197 //Fix(3495)
201 // #i28701# - reset member <maLastCharRect> and
202 // <mnLastTopOfLine> for to-character anchored objects.
204}
205
206//We need some helper classes to monitor the oscillation and a few functions
207//to not get lost.
208
209namespace {
210
211// #i3317# - re-factoring of the position stack
212class SwOszControl
213{
214 static const SwFlyFrame* s_pStack1;
215 static const SwFlyFrame* s_pStack2;
216 static const SwFlyFrame* s_pStack3;
217 static const SwFlyFrame* s_pStack4;
218 static const SwFlyFrame* s_pStack5;
219
220 const SwFlyFrame* m_pFly;
221 std::vector<Point> maObjPositions;
222
223public:
224 explicit SwOszControl( const SwFlyFrame *pFrame );
225 ~SwOszControl();
226 bool ChkOsz();
227 static bool IsInProgress( const SwFlyFrame *pFly );
228};
229
230}
231
232const SwFlyFrame* SwOszControl::s_pStack1 = nullptr;
233const SwFlyFrame* SwOszControl::s_pStack2 = nullptr;
234const SwFlyFrame* SwOszControl::s_pStack3 = nullptr;
235const SwFlyFrame* SwOszControl::s_pStack4 = nullptr;
236const SwFlyFrame* SwOszControl::s_pStack5 = nullptr;
237
238SwOszControl::SwOszControl(const SwFlyFrame* pFrame)
239 : m_pFly(pFrame)
240{
241 if (!SwOszControl::s_pStack1)
242 SwOszControl::s_pStack1 = m_pFly;
243 else if (!SwOszControl::s_pStack2)
244 SwOszControl::s_pStack2 = m_pFly;
245 else if (!SwOszControl::s_pStack3)
246 SwOszControl::s_pStack3 = m_pFly;
247 else if (!SwOszControl::s_pStack4)
248 SwOszControl::s_pStack4 = m_pFly;
249 else if (!SwOszControl::s_pStack5)
250 SwOszControl::s_pStack5 = m_pFly;
251}
252
253SwOszControl::~SwOszControl()
254{
255 if (SwOszControl::s_pStack1 == m_pFly)
256 SwOszControl::s_pStack1 = nullptr;
257 else if (SwOszControl::s_pStack2 == m_pFly)
258 SwOszControl::s_pStack2 = nullptr;
259 else if (SwOszControl::s_pStack3 == m_pFly)
260 SwOszControl::s_pStack3 = nullptr;
261 else if (SwOszControl::s_pStack4 == m_pFly)
262 SwOszControl::s_pStack4 = nullptr;
263 else if (SwOszControl::s_pStack5 == m_pFly)
264 SwOszControl::s_pStack5 = nullptr;
265 // #i3317#
266 maObjPositions.clear();
267}
268
269bool SwOszControl::IsInProgress( const SwFlyFrame *pFly )
270{
271 if (SwOszControl::s_pStack1 && !pFly->IsLowerOf(SwOszControl::s_pStack1))
272 return true;
273 if (SwOszControl::s_pStack2 && !pFly->IsLowerOf(SwOszControl::s_pStack2))
274 return true;
275 if (SwOszControl::s_pStack3 && !pFly->IsLowerOf(SwOszControl::s_pStack3))
276 return true;
277 if (SwOszControl::s_pStack4 && !pFly->IsLowerOf(SwOszControl::s_pStack4))
278 return true;
279 if (SwOszControl::s_pStack5 && !pFly->IsLowerOf(SwOszControl::s_pStack5))
280 return true;
281 return false;
282}
283
284bool SwOszControl::ChkOsz()
285{
286 bool bOscillationDetected = false;
287
288 if ( maObjPositions.size() == 20 )
289 {
290 // #i3317# position stack is full -> oscillation
291 bOscillationDetected = true;
292 }
293 else
294 {
295 Point aNewObjPos = m_pFly->GetObjRect().Pos();
296 for ( auto const & pt : maObjPositions )
297 {
298 if ( aNewObjPos == pt )
299 {
300 // position already occurred -> oscillation
301 bOscillationDetected = true;
302 break;
303 }
304 }
305 if ( !bOscillationDetected )
306 {
307 maObjPositions.push_back( aNewObjPos );
308 }
309 }
310
311 return bOscillationDetected;
312}
313
331{
332 if ( !GetFormat()->GetDoc()->getIDocumentDrawModelAccess().IsVisibleLayerId( GetVirtDrawObj()->GetLayer() ) )
333 {
334 return;
335 }
336
337 if ( SwOszControl::IsInProgress( this ) || IsLocked() || IsColLocked() )
338 return;
339
340 // #i28701# - use new method <GetPageFrame()>
342 {
344 SwPageFrame *pTmpPage = pFly ? pFly->FindPageFrame() : nullptr;
345 if( pTmpPage )
346 pTmpPage->AppendFlyToPage( this );
347 }
348 // #i28701# - use new method <GetPageFrame()>
349 if( !GetPageFrame() )
350 return;
351
353 {
354 SwFlyFrameFormat *pFormat = GetFormat();
355 const SwFormatFrameSize &rFrameSz = GetFormat()->GetFrameSize();
357 rFrameSz.GetHeightPercent() >= 100 )
358 {
359 pFormat->LockModify();
360 SwFormatSurround aMain( pFormat->GetSurround() );
361 if ( aMain.GetSurround() == css::text::WrapTextMode_NONE )
362 {
363 aMain.SetSurround( css::text::WrapTextMode_THROUGH );
364 pFormat->SetFormatAttr( aMain );
365 }
366 pFormat->UnlockModify();
367 }
368 }
369
370 SwOszControl aOszCntrl( this );
371
372 // #i43255#
373 // #i50356# - format the anchor frame, which
374 // contains the anchor position. E.g., for at-character anchored
375 // object this can be the follow frame of the anchor frame.
376 const bool bFormatAnchor =
377 !static_cast<const SwTextFrame*>( GetAnchorFrameContainingAnchPos() )->IsAnyJoinLocked() &&
380
381 const SwFrame* pFooter = GetAnchorFrame()->FindFooterOrHeader();
382 if( pFooter && !pFooter->IsFooterFrame() )
383 pFooter = nullptr;
384 bool bOsz = false;
385 bool bExtra = Lower() && Lower()->IsColumnFrame();
386 // #i3317# - boolean, to apply temporarily the
387 // 'straightforward positioning process' for the frame due to its
388 // overlapping with a previous column.
389 bool bConsiderWrapInfluenceDueToOverlapPrevCol( false );
390 // #i35911# - boolean, to apply temporarily the
391 // 'straightforward positioning process' for the frame due to fact
392 // that it causes the complete content of its layout environment
393 // to move forward.
394 // #i40444# - extend usage of this boolean:
395 // apply temporarily the 'straightforward positioning process' for
396 // the frame due to the fact that the frame clears the area for
397 // the anchor frame, thus it has to move forward.
398 bool bConsiderWrapInfluenceDueToMovedFwdAnchor( false );
399 do {
400 SwRectFnSet aRectFnSet(this);
401 Point aOldPos( aRectFnSet.GetPos(getFrameArea()) );
402 SwFlyFreeFrame::MakeAll(pRenderContext);
403
404 const bool bPosChgDueToOwnFormat =
405 aOldPos != aRectFnSet.GetPos(getFrameArea());
406 // #i3317#
409 {
410 bConsiderWrapInfluenceDueToOverlapPrevCol = true;
411 }
412 // #i28701# - no format of anchor frame, if
413 // wrapping style influence is considered on object positioning
414 if ( bFormatAnchor )
415 {
416 SwTextFrame& rAnchPosAnchorFrame =
418 // #i58182# - For the usage of new method
419 // <SwObjectFormatterTextFrame::CheckMovedFwdCondition(..)>
420 // to check move forward of anchor frame due to the object
421 // positioning it's needed to know, if the object is anchored
422 // at the master frame before the anchor frame is formatted.
423 const bool bAnchoredAtMaster(!rAnchPosAnchorFrame.IsFollow());
424
425 // #i56300#
426 // perform complete format of anchor text frame and its
427 // previous frames, which have become invalid due to the
428 // fly frame format.
430 // #i35911#
431 // #i40444#
432 // #i58182# - usage of new method
433 // <SwObjectFormatterTextFrame::CheckMovedFwdCondition(..)>
434 sal_uInt32 nToPageNum( 0 );
435 bool bDummy( false );
436 bool bPageHasFlysAnchoredBelowThis(false);
438// TODO: what if this fly moved bc it's in table? does sth prevent that?
439 *this, *GetPageFrame(),
440 bAnchoredAtMaster, nToPageNum, bDummy,
441 bPageHasFlysAnchoredBelowThis) )
442 {
443 if (!bPageHasFlysAnchoredBelowThis)
444 {
445 bConsiderWrapInfluenceDueToMovedFwdAnchor = true;
446 }
447 // mark anchor text frame
448 // directly, that it is moved forward by object positioning.
449 SwTextFrame* pAnchorTextFrame( static_cast<SwTextFrame*>(AnchorFrame()) );
450 bool bInsert( true );
451 sal_uInt32 nAnchorFrameToPageNum( 0 );
452 const SwDoc& rDoc = *(GetFrameFormat().GetDoc());
454 rDoc, *pAnchorTextFrame, nAnchorFrameToPageNum ) )
455 {
456 if ( nAnchorFrameToPageNum < nToPageNum )
457 {
458 if (!bPageHasFlysAnchoredBelowThis)
459 {
460 SwLayouter::RemoveMovedFwdFrame(rDoc, *pAnchorTextFrame);
461 }
462 }
463 else
464 bInsert = false;
465 }
466 if ( bInsert )
467 {
468 if (!bPageHasFlysAnchoredBelowThis)
469 {
470 SwLayouter::InsertMovedFwdFrame(rDoc, *pAnchorTextFrame,
471 nToPageNum);
472 }
473 }
474 }
475 }
476
477 if ( aOldPos != aRectFnSet.GetPos(getFrameArea()) ||
479 ( pFooter || bPosChgDueToOwnFormat ) ) )
480 {
481 bOsz = aOszCntrl.ChkOsz();
482
483 // special loop prevention for dedicated document:
484 if ( bOsz &&
485 HasFixSize() && IsClipped() &&
487 {
488 SwFrameFormat* pFormat = GetFormat();
489 const SwFormatFrameSize& rFrameSz = pFormat->GetFrameSize();
490 if ( rFrameSz.GetWidthPercent() &&
492 {
493 SwFormatSurround aSurround( pFormat->GetSurround() );
494 if ( aSurround.GetSurround() == css::text::WrapTextMode_NONE )
495 {
496 pFormat->LockModify();
497 aSurround.SetSurround( css::text::WrapTextMode_THROUGH );
498 pFormat->SetFormatAttr( aSurround );
499 pFormat->UnlockModify();
500 bOsz = false;
501 OSL_FAIL( "<SwFlyAtContentFrame::MakeAll()> - special loop prevention for dedicated document of b6403541 applied" );
502 }
503 }
504 }
505 }
506
507 if ( bExtra && Lower() && !Lower()->isFrameAreaPositionValid() )
508 {
509 // If a multi column frame leaves invalid columns because of
510 // a position change, we loop once more and format
511 // our content using FormatWidthCols again.
513 bExtra = false; // Ensure only one additional loop run
514 }
515 } while ( !isFrameAreaDefinitionValid() && !bOsz &&
516 // #i3317#
517 !bConsiderWrapInfluenceDueToOverlapPrevCol &&
518 // #i40444#
519 !bConsiderWrapInfluenceDueToMovedFwdAnchor &&
520 GetFormat()->GetDoc()->getIDocumentDrawModelAccess().IsVisibleLayerId( GetVirtDrawObj()->GetLayer() ) );
521
522 // #i3317# - instead of attribute change apply
523 // temporarily the 'straightforward positioning process'.
524 // #i80924#
525 // handle special case during splitting of table rows
526 if ( bConsiderWrapInfluenceDueToMovedFwdAnchor &&
527 GetAnchorFrame()->IsInTab() &&
529 {
530 const SwFrame* pCellFrame = GetAnchorFrame();
531 while ( pCellFrame && !pCellFrame->IsCellFrame() )
532 {
533 pCellFrame = pCellFrame->GetUpper();
534 }
535 if ( pCellFrame )
536 {
537 SwRectFnSet aRectFnSet(pCellFrame);
538 if ( aRectFnSet.GetTop(pCellFrame->getFrameArea()) == 0 &&
539 aRectFnSet.GetHeight(pCellFrame->getFrameArea()) == 0 )
540 {
541 bConsiderWrapInfluenceDueToMovedFwdAnchor = false;
542 }
543 }
544 }
545 // tdf#137803: Fix the position of the shape during autoSize
546 SwFrameFormat* pShapeFormat
548 // FIXME: According to tdf37153, ignore FollowTextFlow objs, because
549 // wrong position will applied in that case. FollowTextFlow needs fix.
550 if (pShapeFormat && !pShapeFormat->GetFollowTextFlow().GetValue() &&
551 SwTextBoxHelper::getProperty(pShapeFormat,
553 SwTextBoxHelper::getProperty(pShapeFormat,
555 {
556 // get the text area of the shape
557 const tools::Rectangle aTextRectangle
559 // get the original textframe position
560 SwFormatHoriOrient aHOri = pShapeFormat->GetHoriOrient();
561 SwFormatVertOrient aVOri = pShapeFormat->GetVertOrient();
562 // calc the right position of the shape depending on text area
563 aHOri.SetPos(aHOri.GetPos() + aTextRectangle.Left());
564 aVOri.SetPos(aVOri.GetPos() + aTextRectangle.Top());
565 // save the new position for the shape
566 auto pFormat = GetFormat();
567 const bool bLocked = pFormat->IsModifyLocked();
568 if (!bLocked)
569 pFormat->LockModify();
570 pFormat->SetFormatAttr(aHOri);
571 pFormat->SetFormatAttr(aVOri);
572 if (!bLocked)
573 pFormat->UnlockModify();
574 }
575 if ( bOsz || bConsiderWrapInfluenceDueToOverlapPrevCol ||
576 // #i40444#
577 bConsiderWrapInfluenceDueToMovedFwdAnchor )
578 {
582 }
584}
585
591{
593 !SwOszControl::IsInProgress( this );
594}
595
596namespace {
597
598class SwDistance
599{
600public:
601 SwTwips m_nMain, m_nSub;
602 SwDistance()
603 : m_nMain(0)
604 , m_nSub(0)
605 {
606 }
607 bool operator<( const SwDistance& rTwo ) const
608 {
609 return m_nMain < rTwo.m_nMain
610 || (m_nMain == rTwo.m_nMain && m_nSub && rTwo.m_nSub && m_nSub < rTwo.m_nSub);
611 }
612 bool operator<=( const SwDistance& rTwo ) const
613 {
614 return m_nMain < rTwo.m_nMain
615 || (m_nMain == rTwo.m_nMain
616 && (!m_nSub || !rTwo.m_nSub || m_nSub <= rTwo.m_nSub));
617 }
618};
619
620}
621
622static const SwFrame * lcl_CalcDownDist( SwDistance &rRet,
623 const Point &rPt,
624 const SwContentFrame *pCnt )
625{
626 rRet.m_nSub = 0;
627 //If the point stays inside the Cnt everything is clear already; the Content
628 //automatically has a distance of 0.
629 if ( pCnt->getFrameArea().Contains( rPt ) )
630 {
631 rRet.m_nMain = 0;
632 return pCnt;
633 }
634 else
635 {
636 const SwLayoutFrame *pUp = pCnt->IsInTab() ? pCnt->FindTabFrame()->GetUpper() : pCnt->GetUpper();
637 // single column sections need to interconnect to their upper
638 while( pUp->IsSctFrame() )
639 pUp = pUp->GetUpper();
640 const bool bVert = pUp->IsVertical();
641
642 const bool bVertL2R = pUp->IsVertLR();
643
644 //Follow the text flow.
645 // #i70582#
646 // --> OD 2009-03-05 - adopted for Support for Classical Mongolian Script
647 const SwTwips nTopForObjPos = lcl_GetTopForObjPos(pCnt, bVert, bVertL2R);
648 if ( pUp->getFrameArea().Contains( rPt ) )
649 {
650 // <rPt> point is inside environment of given content frame
651 // #i70582#
652 if( bVert )
653 {
654 if ( bVertL2R )
655 rRet.m_nMain = rPt.X() - nTopForObjPos;
656 else
657 rRet.m_nMain = nTopForObjPos - rPt.X();
658 }
659 else
660 rRet.m_nMain = rPt.Y() - nTopForObjPos;
661 return pCnt;
662 }
663 else if ( rPt.Y() <= pUp->getFrameArea().Top() )
664 {
665 // <rPt> point is above environment of given content frame
666 // correct for vertical layout?
667 rRet.m_nMain = LONG_MAX;
668 }
669 else if( rPt.X() < pUp->getFrameArea().Left() &&
670 rPt.Y() <= ( bVert ? pUp->getFrameArea().Top() : pUp->getFrameArea().Bottom() ) )
671 {
672 // <rPt> point is left of environment of given content frame
673 // seems not to be correct for vertical layout!?
674 const SwFrame *pLay = pUp->GetLeaf( MAKEPAGE_NONE, false, pCnt );
675 if( !pLay ||
676 (bVert && (pLay->getFrameArea().Top() + pLay->getFramePrintArea().Bottom()) <rPt.Y())||
677 (!bVert && (pLay->getFrameArea().Left() + pLay->getFramePrintArea().Right())<rPt.X()) )
678 {
679 // <rPt> point is in left border of environment
680 // #i70582#
681 if( bVert )
682 {
683 if ( bVertL2R )
684 rRet.m_nMain = rPt.X() - nTopForObjPos;
685 else
686 rRet.m_nMain = nTopForObjPos - rPt.X();
687 }
688 else
689 rRet.m_nMain = rPt.Y() - nTopForObjPos;
690 return pCnt;
691 }
692 else
693 rRet.m_nMain = LONG_MAX;
694 }
695 else
696 {
697 rRet.m_nMain
698 = bVert ? (bVertL2R
699 ? ((pUp->getFrameArea().Left() + pUp->getFramePrintArea().Right())
700 - nTopForObjPos)
701 : (nTopForObjPos
702 - (pUp->getFrameArea().Left() + pUp->getFramePrintArea().Left())))
703 : ((pUp->getFrameArea().Top() + pUp->getFramePrintArea().Bottom())
704 - nTopForObjPos);
705
706 const SwFrame *pPre = pCnt;
707 const SwFrame *pLay = pUp->GetLeaf( MAKEPAGE_NONE, true, pCnt );
708 SwTwips nFrameTop = 0;
709 SwTwips nPrtHeight = 0;
710 bool bSct = false;
711 const SwSectionFrame *pSect = pUp->FindSctFrame();
712 if( pSect )
713 {
714 rRet.m_nSub = rRet.m_nMain;
715 rRet.m_nMain = 0;
716 }
717 if( pSect && !pSect->IsAnLower( pLay ) )
718 {
719 bSct = false;
720 const SwSectionFrame* pNxtSect = pLay ? pLay->FindSctFrame() : nullptr;
721 if (pSect->IsAnFollow(pNxtSect) && pLay)
722 {
723 if( pLay->IsVertical() )
724 {
725 if ( pLay->IsVertLR() )
726 nFrameTop = pLay->getFrameArea().Left();
727 else
728 nFrameTop = pLay->getFrameArea().Left() + pLay->getFrameArea().Width();
729 nPrtHeight = pLay->getFramePrintArea().Width();
730 }
731 else
732 {
733 nFrameTop = pLay->getFrameArea().Top();
734 nPrtHeight = pLay->getFramePrintArea().Height();
735 }
736 pSect = pNxtSect;
737 }
738 else
739 {
740 pLay = pSect->GetUpper();
741 if( pLay->IsVertical() )
742 {
743 if ( pLay->IsVertLR() )
744 {
745 nFrameTop = pSect->getFrameArea().Right();
746 nPrtHeight = pLay->getFrameArea().Left() + pLay->getFramePrintArea().Left()
747 + pLay->getFramePrintArea().Width() - pSect->getFrameArea().Left()
748 - pSect->getFrameArea().Width();
749 }
750 else
751 {
752 nFrameTop = pSect->getFrameArea().Left();
753 nPrtHeight = pSect->getFrameArea().Left() - pLay->getFrameArea().Left()
754 - pLay->getFramePrintArea().Left();
755 }
756 }
757 else
758 {
759 nFrameTop = pSect->getFrameArea().Bottom();
760 nPrtHeight = pLay->getFrameArea().Top() + pLay->getFramePrintArea().Top()
761 + pLay->getFramePrintArea().Height() - pSect->getFrameArea().Top()
762 - pSect->getFrameArea().Height();
763 }
764 pSect = nullptr;
765 }
766 }
767 else if( pLay )
768 {
769 if( pLay->IsVertical() )
770 {
771 if ( pLay->IsVertLR() )
772 {
773 nFrameTop = pLay->getFrameArea().Left();
774 nPrtHeight = pLay->getFramePrintArea().Width();
775 }
776 else
777 {
778 nFrameTop = pLay->getFrameArea().Left() + pLay->getFrameArea().Width();
779 nPrtHeight = pLay->getFramePrintArea().Width();
780 }
781 }
782 else
783 {
784 nFrameTop = pLay->getFrameArea().Top();
785 nPrtHeight = pLay->getFramePrintArea().Height();
786 }
787 bSct = nullptr != pSect;
788 }
789 while ( pLay && !pLay->getFrameArea().Contains( rPt ) &&
790 ( pLay->getFrameArea().Top() <= rPt.Y() || pLay->IsInFly() ||
791 ( pLay->IsInSct() &&
792 pLay->FindSctFrame()->GetUpper()->getFrameArea().Top() <= rPt.Y())) )
793 {
794 if ( pLay->IsFootnoteContFrame() )
795 {
796 if ( !static_cast<const SwLayoutFrame*>(pLay)->Lower() )
797 {
798 SwFrame *pDel = const_cast<SwFrame*>(pLay);
799 pDel->Cut();
801 return pPre;
802 }
803 return nullptr;
804 }
805 else
806 {
807 if( bSct || pSect )
808 rRet.m_nSub += nPrtHeight;
809 else
810 rRet.m_nMain += nPrtHeight;
811 pPre = pLay;
812 pLay = pLay->GetLeaf( MAKEPAGE_NONE, true, pCnt );
813 if( pSect && !pSect->IsAnLower( pLay ) )
814 { // If we're leaving a SwSectionFrame, the next Leaf-Frame
815 // is the part of the upper below the SectionFrame.
816 const SwSectionFrame* pNxtSect = pLay ?
817 pLay->FindSctFrame() : nullptr;
818 bSct = false;
819 if (pLay && pSect->IsAnFollow(pNxtSect))
820 {
821 pSect = pNxtSect;
822 if( pLay->IsVertical() )
823 {
824 if ( pLay->IsVertLR() )
825 {
826 nFrameTop = pLay->getFrameArea().Left();
827 nPrtHeight = pLay->getFramePrintArea().Width();
828 }
829 else
830 {
831 nFrameTop = pLay->getFrameArea().Left() + pLay->getFrameArea().Width();
832 nPrtHeight = pLay->getFramePrintArea().Width();
833 }
834 }
835 else
836 {
837 nFrameTop = pLay->getFrameArea().Top();
838 nPrtHeight = pLay->getFramePrintArea().Height();
839 }
840 }
841 else
842 {
843 pLay = pSect->GetUpper();
844 if( pLay->IsVertical() )
845 {
846 if ( pLay->IsVertLR() )
847 {
848 nFrameTop = pSect->getFrameArea().Right();
849 nPrtHeight = pLay->getFrameArea().Left()+pLay->getFramePrintArea().Left()
850 + pLay->getFramePrintArea().Width() - pSect->getFrameArea().Left()
851 - pSect->getFrameArea().Width();
852 }
853 else
854 {
855 nFrameTop = pSect->getFrameArea().Left();
856 nPrtHeight = pSect->getFrameArea().Left() -
857 pLay->getFrameArea().Left() - pLay->getFramePrintArea().Left();
858 }
859 }
860 else
861 {
862 nFrameTop = pSect->getFrameArea().Bottom();
863 nPrtHeight = pLay->getFrameArea().Top()+pLay->getFramePrintArea().Top()
864 + pLay->getFramePrintArea().Height() - pSect->getFrameArea().Top()
865 - pSect->getFrameArea().Height();
866 }
867 pSect = nullptr;
868 }
869 }
870 else if( pLay )
871 {
872 if( pLay->IsVertical() )
873 {
874 if ( pLay->IsVertLR() )
875 {
876 nFrameTop = pLay->getFrameArea().Left();
877 nPrtHeight = pLay->getFramePrintArea().Width();
878 }
879 else
880 {
881 nFrameTop = pLay->getFrameArea().Left() + pLay->getFrameArea().Width();
882 nPrtHeight = pLay->getFramePrintArea().Width();
883 }
884 }
885 else
886 {
887 nFrameTop = pLay->getFrameArea().Top();
888 nPrtHeight = pLay->getFramePrintArea().Height();
889 }
890 bSct = nullptr != pSect;
891 }
892 }
893 }
894 if ( pLay )
895 {
896 if ( pLay->getFrameArea().Contains( rPt ) )
897 {
898 SwTwips nDiff = pLay->IsVertical() ? ( pLay->IsVertLR() ? ( rPt.X() - nFrameTop ) : ( nFrameTop - rPt.X() ) )
899 : ( rPt.Y() - nFrameTop );
900 if( bSct || pSect )
901 rRet.m_nSub += nDiff;
902 else
903 rRet.m_nMain += nDiff;
904 }
905 if ( pLay->IsFootnoteContFrame() && !static_cast<const SwLayoutFrame*>(pLay)->Lower() )
906 {
907 SwFrame *pDel = const_cast<SwFrame*>(pLay);
908 pDel->Cut();
910 return nullptr;
911 }
912 return pLay;
913 }
914 else
915 rRet.m_nMain = LONG_MAX;
916 }
917 }
918 return nullptr;
919}
920
921static sal_uInt64 lcl_FindCntDiff( const Point &rPt, const SwLayoutFrame *pLay,
922 const SwContentFrame *& rpCnt,
923 const bool bBody, const bool bFootnote )
924{
925 // Searches below pLay the nearest Cnt to the point. The reference point of
926 //the Contents is always the left upper corner.
927 //The Cnt should preferably be above the point.
928
929 rpCnt = nullptr;
930 sal_uInt64 nDistance = SAL_MAX_UINT64;
931 sal_uInt64 nNearest = SAL_MAX_UINT64;
932 const SwContentFrame *pCnt = pLay ? pLay->ContainsContent() : nullptr;
933
934 while ( pCnt && (bBody != pCnt->IsInDocBody() || bFootnote != pCnt->IsInFootnote()))
935 {
936 pCnt = pCnt->GetNextContentFrame();
937 if ( !pLay->IsAnLower( pCnt ) )
938 pCnt = nullptr;
939 }
940 const SwContentFrame *pNearest = pCnt;
941 if ( pCnt )
942 {
943 do
944 {
945 //Calculate the distance between those two points.
946 //'delta' X^2 + 'delta' Y^2 = 'distance'^2
947 sal_uInt64 dX = std::max( pCnt->getFrameArea().Left(), rPt.X() ) -
948 std::min( pCnt->getFrameArea().Left(), rPt.X() ),
949 dY = std::max( pCnt->getFrameArea().Top(), rPt.Y() ) -
950 std::min( pCnt->getFrameArea().Top(), rPt.Y() );
951 // square of the difference will do fine here
952 const sal_uInt64 nDiff = (dX * dX) + (dY * dY);
953 if ( pCnt->getFrameArea().Top() <= rPt.Y() )
954 {
955 if ( nDiff < nDistance )
956 {
957 //This one is the nearer one
958 nDistance = nNearest = nDiff;
959 rpCnt = pNearest = pCnt;
960 }
961 }
962 else if ( nDiff < nNearest )
963 {
964 nNearest = nDiff;
965 pNearest = pCnt;
966 }
967 pCnt = pCnt->GetNextContentFrame();
968 while ( pCnt &&
969 (bBody != pCnt->IsInDocBody() || bFootnote != pCnt->IsInFootnote()))
970 pCnt = pCnt->GetNextContentFrame();
971
972 } while ( pCnt && pLay->IsAnLower( pCnt ) );
973 }
974 if (nDistance == SAL_MAX_UINT64)
975 { rpCnt = pNearest;
976 return nNearest;
977 }
978 return nDistance;
979}
980
981static const SwContentFrame * lcl_FindCnt( const Point &rPt, const SwContentFrame *pCnt,
982 const bool bBody, const bool bFootnote )
983{
984 //Starting from pCnt searches the ContentFrame whose left upper corner is the
985 //nearest to the point.
986 //Always returns a ContentFrame.
987
988 //First the nearest Content inside the page which contains the Content is
989 //searched. Starting from this page the pages in both directions need to
990 //be considered. If possible a Content is returned whose Y-position is
991 //above the point.
992 const SwContentFrame *pRet, *pNew;
993 const SwLayoutFrame *pLay = pCnt->FindPageFrame();
994 sal_uInt64 nDist; // not sure if a sal_Int32 would be enough?
995
996 nDist = ::lcl_FindCntDiff( rPt, pLay, pNew, bBody, bFootnote );
997 if ( pNew )
998 pRet = pNew;
999 else
1000 { pRet = pCnt;
1001 nDist = SAL_MAX_UINT64;
1002 }
1003 const SwContentFrame *pNearest = pRet;
1004 sal_uInt64 nNearest = nDist;
1005
1006 if ( pLay )
1007 {
1008 const SwLayoutFrame *pPge = pLay;
1009 sal_uInt64 nOldNew = SAL_MAX_UINT64;
1010 for ( int i = 0; pPge->GetPrev() && (i < 3); ++i )
1011 {
1012 pPge = static_cast<const SwLayoutFrame*>(pPge->GetPrev());
1013 const sal_uInt64 nNew = ::lcl_FindCntDiff( rPt, pPge, pNew, bBody, bFootnote );
1014 if ( nNew < nDist )
1015 {
1016 if ( pNew->getFrameArea().Top() <= rPt.Y() )
1017 {
1018 pRet = pNearest = pNew;
1019 nDist = nNearest = nNew;
1020 }
1021 else if ( nNew < nNearest )
1022 {
1023 pNearest = pNew;
1024 nNearest = nNew;
1025 }
1026 }
1027 else if (nOldNew != SAL_MAX_UINT64 && nNew > nOldNew)
1028 break;
1029 else
1030 nOldNew = nNew;
1031
1032 }
1033 pPge = pLay;
1034 nOldNew = SAL_MAX_UINT64;
1035 for ( int j = 0; pPge->GetNext() && (j < 3); ++j )
1036 {
1037 pPge = static_cast<const SwLayoutFrame*>(pPge->GetNext());
1038 const sal_uInt64 nNew = ::lcl_FindCntDiff( rPt, pPge, pNew, bBody, bFootnote );
1039 if ( nNew < nDist )
1040 {
1041 if ( pNew->getFrameArea().Top() <= rPt.Y() )
1042 {
1043 pRet = pNearest = pNew;
1044 nDist = nNearest = nNew;
1045 }
1046 else if ( nNew < nNearest )
1047 {
1048 pNearest = pNew;
1049 nNearest = nNew;
1050 }
1051 }
1052 else if (nOldNew != SAL_MAX_UINT64 && nNew > nOldNew)
1053 break;
1054 else
1055 nOldNew = nNew;
1056 }
1057 }
1058 if ( pRet->getFrameArea().Top() > rPt.Y() )
1059 return pNearest;
1060 else
1061 return pRet;
1062}
1063
1064static void lcl_PointToPrt( Point &rPoint, const SwFrame *pFrame )
1065{
1066 SwRect aTmp( pFrame->getFramePrintArea() );
1067 aTmp += pFrame->getFrameArea().Pos();
1068 if ( rPoint.getX() < aTmp.Left() )
1069 rPoint.setX(aTmp.Left());
1070 else if ( rPoint.getX() > aTmp.Right() )
1071 rPoint.setX(aTmp.Right());
1072 if ( rPoint.getY() < aTmp.Top() )
1073 rPoint.setY(aTmp.Top());
1074 else if ( rPoint.getY() > aTmp.Bottom() )
1075 rPoint.setY(aTmp.Bottom());
1076
1077}
1078
1084const SwContentFrame *FindAnchor( const SwFrame *pOldAnch, const Point &rNew,
1085 const bool bBodyOnly )
1086{
1087 //Search the nearest Cnt around the given document position in the text
1088 //flow. The given anchor is the starting Frame.
1089 const SwContentFrame* pCnt;
1090 if ( pOldAnch->IsContentFrame() )
1091 {
1092 pCnt = static_cast<const SwContentFrame*>(pOldAnch);
1093 }
1094 else
1095 {
1096 Point aTmp( rNew );
1097 const SwLayoutFrame *pTmpLay = static_cast<const SwLayoutFrame*>(pOldAnch);
1098 if( pTmpLay->IsRootFrame() )
1099 {
1100 SwRect aTmpRect( aTmp, Size(0,0) );
1101 pTmpLay = static_cast<const SwLayoutFrame*>(::FindPage( aTmpRect, pTmpLay->Lower() ));
1102 }
1103 pCnt = pTmpLay->GetContentPos( aTmp, false, bBodyOnly );
1104 }
1105
1106 //Take care to use meaningful ranges during search. This means to not enter
1107 //or leave header/footer in this case.
1108 const bool bBody = pCnt->IsInDocBody() || bBodyOnly;
1109 const bool bFootnote = !bBodyOnly && pCnt->IsInFootnote();
1110
1111 Point aNew( rNew );
1112 if ( bBody )
1113 {
1114 //#38848 drag from page margin into the body.
1115 const SwFrame *pPage = pCnt->FindPageFrame();
1116 ::lcl_PointToPrt( aNew, pPage->GetUpper() );
1117 SwRect aTmp( aNew, Size( 0, 0 ) );
1118 pPage = ::FindPage( aTmp, pPage );
1119 ::lcl_PointToPrt( aNew, pPage );
1120 }
1121
1122 if ( pCnt->IsInDocBody() == bBody && pCnt->getFrameArea().Contains( aNew ) )
1123 return pCnt;
1124 else if ( pOldAnch->IsInDocBody() || pOldAnch->IsPageFrame() )
1125 {
1126 // Maybe the selected anchor is on the same page as the current anchor.
1127 // With this we won't run into problems with the columns.
1128 Point aTmp( aNew );
1129 const SwContentFrame *pTmp = pCnt->FindPageFrame()->
1130 GetContentPos( aTmp, false, true );
1131 if ( pTmp && pTmp->getFrameArea().Contains( aNew ) )
1132 return pTmp;
1133 }
1134
1135 //Starting from the anchor we now search in both directions until we found
1136 //the nearest one respectively.
1137 //Not the direct distance is relevant but the distance which needs to be
1138 //traveled through the text flow.
1139 const SwContentFrame *pUpLst;
1140 const SwContentFrame *pUpFrame = pCnt;
1141 SwDistance nUp, nUpLst;
1142 ::lcl_CalcDownDist( nUp, aNew, pUpFrame );
1143 SwDistance nDown = nUp;
1144 bool bNegAllowed = true;// Make it possible to leave the negative section once.
1145 do
1146 {
1147 pUpLst = pUpFrame; nUpLst = nUp;
1148 pUpFrame = pUpLst->GetPrevContentFrame();
1149 while ( pUpFrame &&
1150 (bBody != pUpFrame->IsInDocBody() || bFootnote != pUpFrame->IsInFootnote()))
1151 pUpFrame = pUpFrame->GetPrevContentFrame();
1152 if ( pUpFrame )
1153 {
1154 ::lcl_CalcDownDist( nUp, aNew, pUpFrame );
1155 //It makes sense to search further, if the distance grows inside
1156 //a table.
1157 if ( pUpLst->IsInTab() && pUpFrame->IsInTab() )
1158 {
1159 while ( pUpFrame && ((nUpLst < nUp && pUpFrame->IsInTab()) ||
1160 bBody != pUpFrame->IsInDocBody()) )
1161 {
1162 pUpFrame = pUpFrame->GetPrevContentFrame();
1163 if ( pUpFrame )
1164 ::lcl_CalcDownDist( nUp, aNew, pUpFrame );
1165 }
1166 }
1167 }
1168 if ( !pUpFrame )
1169 nUp.m_nMain = LONG_MAX;
1170 if (nUp.m_nMain >= 0 && LONG_MAX != nUp.m_nMain)
1171 {
1172 bNegAllowed = false;
1173 if (nUpLst.m_nMain < 0) //don't take the wrong one, if the value
1174 //just changed from negative to positive.
1175 { pUpLst = pUpFrame;
1176 nUpLst = nUp;
1177 }
1178 }
1179 } while (pUpFrame && ((bNegAllowed && nUp.m_nMain < 0) || (nUp <= nUpLst)));
1180
1181 const SwContentFrame *pDownLst;
1182 const SwContentFrame *pDownFrame = pCnt;
1183 SwDistance nDownLst;
1184 if (nDown.m_nMain < 0)
1185 nDown.m_nMain = LONG_MAX;
1186 do
1187 {
1188 pDownLst = pDownFrame; nDownLst = nDown;
1189 pDownFrame = pDownLst->GetNextContentFrame();
1190 while ( pDownFrame &&
1191 (bBody != pDownFrame->IsInDocBody() || bFootnote != pDownFrame->IsInFootnote()))
1192 pDownFrame = pDownFrame->GetNextContentFrame();
1193 if ( pDownFrame )
1194 {
1195 ::lcl_CalcDownDist( nDown, aNew, pDownFrame );
1196 if (nDown.m_nMain < 0)
1197 nDown.m_nMain = LONG_MAX;
1198 //It makes sense to search further, if the distance grows inside
1199 //a table.
1200 if ( pDownLst->IsInTab() && pDownFrame->IsInTab() )
1201 {
1202 while (pDownFrame
1203 && ((nDown.m_nMain != LONG_MAX && pDownFrame->IsInTab())
1204 || bBody != pDownFrame->IsInDocBody()))
1205 {
1206 pDownFrame = pDownFrame->GetNextContentFrame();
1207 if ( pDownFrame )
1208 ::lcl_CalcDownDist( nDown, aNew, pDownFrame );
1209 if (nDown.m_nMain < 0)
1210 nDown.m_nMain = LONG_MAX;
1211 }
1212 }
1213 }
1214 if ( !pDownFrame )
1215 nDown.m_nMain = LONG_MAX;
1216
1217 } while (pDownFrame && nDown <= nDownLst && nDown.m_nMain != LONG_MAX
1218 && nDownLst.m_nMain != LONG_MAX);
1219
1220 //If we couldn't find one in both directions, we'll search the Content whose
1221 //left upper corner is the nearest to the point. Such a situation may
1222 //happen, if the point doesn't lay in the text flow but in any margin.
1223 if (nDownLst.m_nMain == LONG_MAX && nUpLst.m_nMain == LONG_MAX)
1224 {
1225 // If an OLE objects, which is contained in a fly frame
1226 // is resized in inplace mode and the new Position is outside the
1227 // fly frame, we do not want to leave our fly frame.
1228 if ( pCnt->IsInFly() )
1229 return pCnt;
1230
1231 return ::lcl_FindCnt( aNew, pCnt, bBody, bFootnote );
1232 }
1233 else
1234 return nDownLst < nUpLst ? pDownLst : pUpLst;
1235}
1236
1238{
1239 SwPageFrame *pOldPage = FindPageFrame();
1240 const SwRect aOld( GetObjRectWithSpaces() );
1241 Point aNew( rNew );
1242
1244 aNew.setX(aNew.getX() + getFrameArea().Width());
1245 SwContentFrame *pCnt = const_cast<SwContentFrame*>(::FindAnchor( GetAnchorFrame(), aNew ));
1246 if( pCnt->IsProtected() )
1247 pCnt = const_cast<SwContentFrame*>(static_cast<const SwContentFrame*>(GetAnchorFrame()));
1248
1249 SwPageFrame *pTmpPage = nullptr;
1250 const bool bVert = pCnt->IsVertical();
1251
1252 const bool bVertL2R = pCnt->IsVertLR();
1253 const bool bRTL = pCnt->IsRightToLeft();
1254
1255 if( ( !bVert != !GetAnchorFrame()->IsVertical() ) ||
1256 ( !bRTL != !GetAnchorFrame()->IsRightToLeft() ) )
1257 {
1258 if( bVert || bRTL )
1259 aNew.setX(aNew.getX() + getFrameArea().Width());
1260 else
1261 aNew.setX(aNew.getX() - getFrameArea().Width());
1262 }
1263
1264 if ( pCnt->IsInDocBody() )
1265 {
1266 //#38848 drag from page margin into the body.
1267 pTmpPage = pCnt->FindPageFrame();
1268 ::lcl_PointToPrt( aNew, pTmpPage->GetUpper() );
1269 SwRect aTmp( aNew, Size( 0, 0 ) );
1270 pTmpPage = const_cast<SwPageFrame*>(static_cast<const SwPageFrame*>(::FindPage( aTmp, pTmpPage )));
1271 ::lcl_PointToPrt( aNew, pTmpPage );
1272 }
1273
1274 //Setup RelPos, only invalidate if requested.
1275 //rNew is an absolute position. We need to calculate the distance from rNew
1276 //to the anchor inside the text flow to correctly set RelPos.
1278 const SwFrame *pFrame = nullptr;
1279 SwTwips nY;
1280 if ( pCnt->getFrameArea().Contains( aNew ) )
1281 {
1282 // #i70582#
1283 if ( bVert )
1284 {
1285 nY = pCnt->getFrameArea().Left() - rNew.X();
1286 if ( bVertL2R )
1287 nY = -nY;
1288 else
1289 nY += pCnt->getFrameArea().Width() - getFrameArea().Width();
1290 nY -= pCnt->GetUpperSpaceAmountConsideredForPrevFrameAndPageGrid();
1291 }
1292 else
1293 nY = rNew.Y() - pCnt->getFrameArea().Top() - pCnt->GetUpperSpaceAmountConsideredForPrevFrameAndPageGrid();
1294 }
1295 else
1296 {
1297 SwDistance aDist;
1298 pFrame = ::lcl_CalcDownDist( aDist, aNew, pCnt );
1299 nY = aDist.m_nMain + aDist.m_nSub;
1300 }
1301
1302 SwTwips nX = 0;
1303
1304 if ( pCnt->IsFollow() )
1305 {
1306 // Flys are never attached to the follow but always to the master,
1307 // which we're going to search now.
1308 const SwContentFrame *pOriginal = pCnt;
1309 const SwContentFrame *pFollow = pCnt;
1310 while ( pCnt->IsFollow() )
1311 {
1312 do
1313 {
1314 SwContentFrame* pPrev = pCnt->GetPrevContentFrame();
1315 if (!pPrev)
1316 {
1317 SAL_WARN("sw.core", "very unexpected missing PrevContentFrame");
1318 break;
1319 }
1320 pCnt = pPrev;
1321 }
1322 while ( pCnt->GetFollow() != pFollow );
1323 pFollow = pCnt;
1324 }
1325 SwTwips nDiff = 0;
1326 do
1327 { const SwFrame *pUp = pFollow->GetUpper();
1328 if( pUp->IsVertical() )
1329 {
1330 if ( pUp->IsVertLR() )
1331 nDiff += pUp->getFramePrintArea().Width() - pFollow->GetRelPos().getX();
1332 else
1333 nDiff += pFollow->getFrameArea().Left() + pFollow->getFrameArea().Width()
1334 - pUp->getFrameArea().Left() - pUp->getFramePrintArea().Left();
1335 }
1336 else
1337 nDiff += pUp->getFramePrintArea().Height() - pFollow->GetRelPos().Y();
1338 pFollow = pFollow->GetFollow();
1339 } while ( pFollow != pOriginal );
1340 nY += nDiff;
1341 if( bVert )
1342 nX = pCnt->getFrameArea().Top() - pOriginal->getFrameArea().Top();
1343 else
1344 nX = pCnt->getFrameArea().Left() - pOriginal->getFrameArea().Left();
1345 }
1346
1347 if ( nY == LONG_MAX )
1348 {
1349 // #i70582#
1350 const SwTwips nTopForObjPos = lcl_GetTopForObjPos(pCnt, bVert, bVertL2R);
1351 if( bVert )
1352 {
1353 if ( bVertL2R )
1354 nY = rNew.X() - nTopForObjPos;
1355 else
1356 nY = nTopForObjPos - rNew.X();
1357 }
1358 else
1359 {
1360 nY = rNew.Y() - nTopForObjPos;
1361 }
1362 }
1363
1364 SwFlyFrameFormat *pFormat = GetFormat();
1365
1366 if( bVert )
1367 {
1368 if( !pFrame )
1369 nX += rNew.Y() - pCnt->getFrameArea().Top();
1370 else
1371 nX = rNew.Y() - pFrame->getFrameArea().Top();
1372 }
1373 else
1374 {
1375 if( !pFrame )
1376 {
1377 if ( pCnt->IsRightToLeft() )
1378 nX += pCnt->getFrameArea().Right() - rNew.X() - getFrameArea().Width();
1379 else
1380 nX += rNew.X() - pCnt->getFrameArea().Left();
1381 }
1382 else
1383 {
1384 if ( pFrame->IsRightToLeft() )
1385 nX += pFrame->getFrameArea().Right() - rNew.X() - getFrameArea().Width();
1386 else
1387 nX = rNew.X() - pFrame->getFrameArea().Left();
1388 }
1389 }
1390 GetFormat()->GetDoc()->GetIDocumentUndoRedo().StartUndo( SwUndoId::START, nullptr );
1391
1392 if( pCnt != GetAnchorFrame() || ( IsAutoPos() && pCnt->IsTextFrame() &&
1393 GetFormat()->getIDocumentSettingAccess().get(DocumentSettingId::HTML_MODE)) )
1394 {
1395 //Set the anchor attribute according to the new Cnt.
1396 SwFormatAnchor aAnch( pFormat->GetAnchor() );
1397 SwPosition pos = *aAnch.GetContentAnchor();
1398 if( IsAutoPos() && pCnt->IsTextFrame() )
1399 {
1400 SwTextFrame const*const pTextFrame(static_cast<SwTextFrame const*>(pCnt));
1402 Point aPt( rNew );
1403 if( pCnt->GetModelPositionForViewPoint( &pos, aPt, &eTmpState )
1404 && FrameContainsNode(*pTextFrame, pos.GetNodeIndex()))
1405 {
1406 const SwTextAttr *const pTextInputField =
1407 pos.GetNode().GetTextNode()->GetTextAttrAt(
1409 if (pTextInputField != nullptr)
1410 {
1411 pos.SetContent( pTextInputField->GetStart() );
1412 }
1414 if( text::RelOrientation::CHAR == pFormat->GetVertOrient().GetRelationOrient() )
1415 nY = LONG_MAX;
1416 if( text::RelOrientation::CHAR == pFormat->GetHoriOrient().GetRelationOrient() )
1417 nX = LONG_MAX;
1418 }
1419 else
1420 {
1421 pos = pTextFrame->MapViewToModelPos(TextFrameIndex(0));
1422 }
1423 }
1424 else if (pCnt->IsTextFrame())
1425 {
1426 pos = static_cast<SwTextFrame const*>(pCnt)->MapViewToModelPos(TextFrameIndex(0));
1427 }
1428 else // is that even possible? maybe if there was a change of anchor type from AT_FLY or something?
1429 {
1430 assert(pCnt->IsNoTextFrame());
1431 pos.Assign(*static_cast<SwNoTextFrame*>(pCnt)->GetNode());
1432 }
1433 aAnch.SetAnchor( &pos );
1434
1435 // handle change of anchor node:
1436 // if count of the anchor frame also change, the fly frames have to be
1437 // re-created. Thus, delete all fly frames except the <this> before the
1438 // anchor attribute is change and re-create them afterwards.
1439 {
1440 SwHandleAnchorNodeChg aHandleAnchorNodeChg( *pFormat, aAnch, this );
1441 pFormat->GetDoc()->SetAttr( aAnch, *pFormat );
1442 }
1443 }
1444 else if ( pTmpPage && pTmpPage != GetPageFrame() )
1445 GetPageFrame()->MoveFly( this, pTmpPage );
1446
1447 const Point aRelPos = bVert ? Point( -nY, nX ) : Point( nX, nY );
1448 ChgRelPos( aRelPos );
1449 GetFormat()->GetDoc()->GetIDocumentUndoRedo().EndUndo( SwUndoId::END, nullptr );
1450
1451 if ( pOldPage != FindPageFrame() )
1453}
1454
1462{
1463 SwPageFrame* pPageFrame( nullptr );
1464 if ( GetVertPosOrientFrame() )
1465 {
1466 pPageFrame = const_cast<SwPageFrame*>(GetVertPosOrientFrame()->FindPageFrame());
1467 }
1468 if ( pPageFrame && GetPageFrame() != pPageFrame )
1469 {
1470 RegisterAtPage(*pPageFrame);
1471 }
1472}
1473
1475{
1476 assert(GetPageFrame() != &rPageFrame);
1477 if (GetPageFrame())
1478 {
1479 GetPageFrame()->MoveFly( this, &rPageFrame );
1480 }
1481 else
1482 {
1483 rPageFrame.AppendFlyToPage( this );
1484 }
1485}
1486
1487// #i26791#
1489{
1490 // if fly frame position is valid, nothing is to do. Thus, return
1492 {
1493 return;
1494 }
1495
1496 // #i26791# - validate position flag here.
1498
1499 // #i35911# - no calculation of new position, if
1500 // anchored object is marked that it clears its environment and its
1501 // environment is already cleared.
1502 // before checking for cleared environment
1503 // check, if member <mpVertPosOrientFrame> is set.
1504 if ( GetVertPosOrientFrame() &&
1506 {
1507 return;
1508 }
1509
1510 // use new class to position object
1512 aObjPositioning( *GetVirtDrawObj() );
1513 aObjPositioning.CalcPosition();
1514
1515 SetVertPosOrientFrame ( aObjPositioning.GetVertPosOrientFrame() );
1516}
1517
1518// #i28701#
1520{
1521 bool bAllowed( SwFlyFreeFrame::InvalidationAllowed( _nInvalid ) );
1522
1523 // forbiddance of base instance can't be over ruled.
1524 if ( bAllowed )
1525 {
1526 if ( _nInvalid == INVALID_POS ||
1527 _nInvalid == INVALID_ALL )
1528 {
1529 bAllowed = InvalidationOfPosAllowed();
1530 }
1531 }
1532
1533 return bAllowed;
1534}
1535
1536bool SwFlyAtContentFrame::ShouldBwdMoved(SwLayoutFrame* /*pNewUpper*/, bool& /*rReformat*/)
1537{
1538 return false;
1539}
1540
1542{
1543 return static_cast<const SwFlyAtContentFrame*>(SwFlowFrame::GetFollow());
1544}
1545
1547{
1548 return static_cast<SwFlyAtContentFrame*>(SwFlowFrame::GetFollow());
1549}
1550
1552{
1553 auto pFly = dynamic_cast<SwFlyAtContentFrame*>(FindFlyFrame());
1554 assert(pFly && "GetNextFlyLeaf: missing fly frame");
1555 assert(pFly->IsFlySplitAllowed() && "GetNextFlyLeaf: fly split not allowed");
1556
1557 SwTextFrame* pFlyAnchor = pFly->FindAnchorCharFrame();
1558
1559 if (!pFlyAnchor)
1560 {
1561 // In case our fly frame is split already, but not yet moved, then FindAnchorCharFrame()
1562 // won't find the anchor, since it wants a follow anchor, but there is no follow anchor yet.
1563 // In this case work with a plain anchor, so FindSctFrame() works to find out we're in a
1564 // section.
1565 auto pAnchorFrame = const_cast<SwFrame*>(pFly->GetAnchorFrame());
1566 if (pAnchorFrame && pAnchorFrame->IsTextFrame())
1567 {
1568 pFlyAnchor = static_cast<SwTextFrame*>(pAnchorFrame);
1569 }
1570 }
1571
1572 bool bBody = pFlyAnchor && pFlyAnchor->IsInDocBody();
1573 SwLayoutFrame *pLayLeaf = nullptr;
1574 // Look up the first candidate.
1575 SwSectionFrame* pFlyAnchorSection = pFlyAnchor ? pFlyAnchor->FindSctFrame() : nullptr;
1576 if (pFlyAnchorSection)
1577 {
1578 // We can't just move the split anchor to the next page, that would be outside the section.
1579 // Rather split that section as well.
1580 pLayLeaf = pFlyAnchorSection->GetNextSctLeaf(eMakePage);
1581 }
1582 else if (IsTabFrame())
1583 {
1584 // If we're in a table, try to find the next frame of the table's last content.
1585 SwFrame* pContent = static_cast<SwTabFrame*>(this)->FindLastContentOrTable();
1586 pLayLeaf = pContent ? pContent->GetUpper() : nullptr;
1587 }
1588 else
1589 {
1590 pLayLeaf = GetNextLayoutLeaf();
1591 }
1592
1593 SwLayoutFrame* pOldLayLeaf = nullptr;
1594 while (true)
1595 {
1596 if (pLayLeaf)
1597 {
1598 // If we're anchored in a body frame, the candidate has to be in a body frame as well.
1599 bool bLeftBody = bBody && !pLayLeaf->IsInDocBody();
1600 // If the candidate is in a fly, make sure that the candidate is a child of our follow.
1601 bool bLeftFly = pLayLeaf->IsInFly() && pLayLeaf->FindFlyFrame() != pFly->GetFollow();
1602 bool bSameBody = false;
1603 if (bBody && pLayLeaf->IsInDocBody())
1604 {
1605 // Make sure the candidate is not inside the same body frame, that would prevent
1606 // inserting a new page.
1607 if (pFlyAnchor->FindBodyFrame() == pLayLeaf->FindBodyFrame())
1608 {
1609 bSameBody = true;
1610 }
1611 }
1612 if (bLeftBody || bLeftFly || bSameBody)
1613 {
1614 // The above conditions are not held, reject.
1615 pOldLayLeaf = pLayLeaf;
1616 pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
1617 continue;
1618 }
1619 }
1620 else
1621 {
1622 // No candidate: insert a page and try again.
1623 if (eMakePage == MAKEPAGE_INSERT)
1624 {
1625 InsertPage(FindPageFrame(), false);
1626 // If we already had a candidate, continue trying with that instead of starting from
1627 // scratch.
1628 pLayLeaf = pOldLayLeaf ? pOldLayLeaf : GetNextLayoutLeaf();
1629 continue;
1630 }
1631 }
1632 break;
1633 }
1634
1635 if( pLayLeaf )
1636 {
1637 SwFlyAtContentFrame* pNew = nullptr;
1638 // Find the anchor frame to split.
1639 if (pFlyAnchor)
1640 {
1641 // Split the anchor at char 0: all the content goes to the follow of the anchor.
1642 pFlyAnchor->SplitFrame(TextFrameIndex(0));
1643 auto pNext = static_cast<SwTextFrame*>(pFlyAnchor->GetNext());
1644 // Move the new anchor frame, before the first child of pLayLeaf.
1645 pNext->MoveSubTree(pLayLeaf, pLayLeaf->Lower());
1646
1647 // Now create the follow of the fly and anchor it in the master of the anchor.
1648 pNew = new SwFlyAtContentFrame(*pFly);
1649 while (pFlyAnchor->IsFollow())
1650 {
1651 pFlyAnchor = pFlyAnchor->FindMaster();
1652 }
1653 pFlyAnchor->AppendFly(pNew);
1654 }
1655 pLayLeaf = pNew;
1656 }
1657 return pLayLeaf;
1658}
1659
1661{
1662 assert(mpFlyDestroy);
1663
1664 while (!mpFlyDestroy->empty())
1665 {
1666 SwFlyFrame* pFly = *mpFlyDestroy->begin();
1667 mpFlyDestroy->erase( mpFlyDestroy->begin() );
1668 // Allow deletion of non-empty flys: a fly with no content is still formatted to have a
1669 // height of MINLAY.
1670 if (!pFly->ContainsContent() && !pFly->IsDeleteForbidden())
1671 {
1673 }
1674 }
1675}
1676
1678{
1679 return static_cast<const SwFlyAtContentFrame*>(SwFlowFrame::GetPrecede());
1680}
1681
1683{
1684 return static_cast<SwFlyAtContentFrame*>(SwFlowFrame::GetPrecede());
1685}
1686
1688{
1689 SwTextFrame* pAnchor = FindAnchorCharFrame();
1690 if (pAnchor)
1691 {
1692 if (SwFlowFrame* pAnchorPrecede = pAnchor->GetPrecede())
1693 {
1694 // The anchor has a precede: invalidate it so that JoinFrame() is called on it.
1695 pAnchorPrecede->GetFrame().InvalidateSize();
1696 }
1697 }
1698
1699 SwFlyAtContentFrame* pMaster = IsFollow() ? GetPrecede() : nullptr;
1700 if (pMaster)
1701 {
1702 pMaster->SetFollow(GetFollow());
1703 }
1704
1705 SwFlyAtContentFrame* pFollow = GetFollow();
1706 if (pFollow)
1707 {
1708 // I'll be deleted, so invalidate the position of my follow, so it can move up.
1709 pFollow->InvalidatePos();
1710 }
1711
1712 SetFollow(nullptr);
1713
1714 {
1716 aFrm.Height(0);
1717 }
1719
1720 if(getRootFrame())
1721 {
1723 }
1724}
1725
1727{
1728 if (!mpFlyDestroy)
1729 {
1730 mpFlyDestroy.reset(new SwFlyDestroyList);
1731 }
1732
1733 mpFlyDestroy->insert(pDel);
1734}
1735
1737{
1738 auto pFly = dynamic_cast<SwFlyAtContentFrame*>(FindFlyFrame());
1739 assert(pFly && "GetPrevFlyLeaf: missing fly frame");
1740 if (!pFly->IsFlySplitAllowed())
1741 {
1742 return nullptr;
1743 }
1744
1745 return pFly->GetPrecede();
1746}
1747
1748/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
o3tl::strong_int< sal_Int32, struct Tag_TextFrameIndex > TextFrameIndex
Denotes a character index in a text frame at a layout level, after extent mapping from a text node at...
bool operator<=(const BigInt &rVal1, const BigInt &rVal2)
constexpr tools::Long Y() const
void setX(tools::Long nX)
void setY(tools::Long nY)
constexpr tools::Long X() const
constexpr tools::Long getX() const
constexpr tools::Long getY() const
bool GetValue() const
SfxHintId GetId() const
wrapper class for the positioning of Writer fly frames and drawing objects
void SetTmpConsiderWrapInfluenceOfOtherObjs()
method to apply temporary consideration of wrapping style influence to the anchored objects,...
const SwFrame * GetAnchorFrame() const
bool InvalidationOfPosAllowed() const
method to determine, if invalidation of position is allowed
SwTextFrame * FindAnchorCharFrame()
get frame, which contains the anchor character, if the object is anchored at-character or as-characte...
void ResetLastCharRectHeight()
SwFrame * AnchorFrame()
void SetVertPosOrientFrame(const SwLayoutFrame &_rVertPosOrientFrame)
SwFrame * GetAnchorFrameContainingAnchPos()
determine anchor frame containing the anchor position
void ClearCharRectAndTopOfLine()
reset members <maLastCharRect> and <mnLastTopOfLine>
const SwLayoutFrame * GetVertPosOrientFrame() const
void SetTmpConsiderWrapInfluence(const bool _bTmpConsiderWrapInfluence)
bool OverlapsPrevColumn() const
method to determine, if the anchored object is overlapping with a previous column
bool ConsiderObjWrapInfluenceOnObjPos() const
method to determine, if wrapping style influence of the anchored object has to be considered on the o...
SwPageFrame * GetPageFrame()
bool HasClearedEnvironment() const
method to determine, if due to anchored object size and wrapping style, its layout environment is cle...
const SwRect & GetObjRectWithSpaces() const
method to determine object area inclusive its spacing
void InvalidateObjRectWithSpaces() const
bool ConsiderObjWrapInfluenceOfOtherObjs() const
method to determine, if other anchored objects, also attached at to the anchor frame,...
void SetRestartLayoutProcess(const bool _bRestartLayoutProcess)
bool ClearedEnvironment() const
SwContentFrame is the layout for content nodes: a common base class for text (paragraph) and non-text...
Definition: cntfrm.hxx:59
SwContentFrame * GetPrevContentFrame() const
Definition: cntfrm.hxx:128
const SwContentFrame * GetFollow() const
Definition: cntfrm.hxx:136
SwContentFrame * GetNextContentFrame() const
Definition: cntfrm.hxx:120
SwTextFrame * FindMaster() const
Definition: flowfrm.cxx:762
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1223
Definition: doc.hxx:197
void SetAttr(const SfxPoolItem &, SwFormat &)
Set attribute in given format.1y If Undo is enabled, the old values is added to the Undo history.
Definition: docfmt.cxx:458
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:158
Flys that are anchored to content (at-para, at-char) but not in content (as-char).
Definition: flyfrms.hxx:163
virtual bool InvalidationAllowed(const InvalidationType _nInvalid) const override
method to determine, if an invalidation is allowed.
Definition: flycnt.cxx:1519
virtual void MakeAll(vcl::RenderContext *pRenderContext) override
|* With a paragraph-anchored fly it's absolutely possible that |* the anchor reacts to changes of the...
Definition: flycnt.cxx:330
const SwFlyAtContentFrame * GetPrecede() const
Definition: flycnt.cxx:1677
bool ShouldBwdMoved(SwLayoutFrame *pNewUpper, bool &rReformat) override
Definition: flycnt.cxx:1536
virtual void MakeObjPos() override
method to determine position for the object and set the position at the object
Definition: flycnt.cxx:1488
SwFlyAtContentFrame(SwFlyFrameFormat *, SwFrame *, SwFrame *pAnchor, bool bFollow=false)
Definition: flycnt.cxx:78
void SetAbsPos(const Point &rNew)
Definition: flycnt.cxx:1237
virtual void RegisterAtCorrectPage() override
method to assure that anchored object is registered at the correct page frame
Definition: flycnt.cxx:1461
virtual void SwClientNotify(const SwModify &, const SfxHint &) override
Definition: flycnt.cxx:100
void DelEmpty()
Like Cut(), except that follow chaining is maintained.
Definition: flycnt.cxx:1687
const SwFlyAtContentFrame * GetFollow() const
Definition: flycnt.cxx:1541
virtual bool IsFormatPossible() const override
method to determine, if a format on the Writer fly frame is possible
Definition: flycnt.cxx:590
virtual void RegisterAtPage(SwPageFrame &) override
Definition: flycnt.cxx:1474
general base class for all free-flowing frames
Definition: flyfrm.hxx:79
const SwVirtFlyDrawObj * GetVirtDrawObj() const
Definition: fly.cxx:3025
virtual const SwFlyFrameFormat * GetFormat() const override
Definition: fly.cxx:3119
static const SwFormatAnchor * GetAnchorFromPoolItem(const SfxPoolItem &rItem)
Definition: fly.cxx:3217
bool IsFlySplitAllowed() const
Is this fly allowed to split across pages? (Disabled by default.)
Definition: fly.cxx:662
void SetNotifyBack()
Definition: flyfrm.hxx:227
bool IsLowerOf(const SwLayoutFrame *pUpper) const
Definition: fly.cxx:2392
virtual const SwFlyFrame * DynCastFlyFrame() const override
Definition: fly.cxx:3230
virtual SwFrameFormat & GetFrameFormat() override
Definition: fly.cxx:3044
virtual void SwClientNotify(const SwModify &rMod, const SfxHint &rHint) override
Definition: fly.cxx:765
bool IsLocked() const
Definition: flyfrm.hxx:215
bool m_bAtCnt
RndStdIds::FLY_AT_PARA, anchored at paragraph or RndStdIds::FLY_AT_CHAR.
Definition: flyfrm.hxx:129
bool m_bAutoPosition
RndStdIds::FLY_AT_CHAR, anchored at character.
Definition: flyfrm.hxx:132
virtual const IDocumentDrawModelAccess & getIDocumentDrawModelAccess() override
Definition: fly.cxx:374
bool IsClipped() const
Definition: flyfrm.hxx:230
bool IsAutoPos() const
Definition: flyfrm.hxx:216
void ChgRelPos(const Point &rAbsPos)
Change the relative position.
Definition: fly.cxx:1240
virtual void MakeAll(vcl::RenderContext *pRenderContext) override
Definition: flylay.cxx:113
virtual void NotifyBackground(SwPageFrame *pPage, const SwRect &rRect, PrepareHint eHint) override
Notifies the background (all ContentFrames that currently are overlapping).
Definition: flylay.cxx:107
virtual bool IsFormatPossible() const override
method to determine, if a format on the Writer fly frame is possible
Definition: flylay.cxx:710
FlyAnchors.
Definition: fmtanchr.hxx:37
void SetAnchor(const SwPosition *pPos)
Definition: atrfrm.cxx:1593
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:67
const SwPosition * GetContentAnchor() const
Definition: fmtanchr.hxx:74
SwNode * GetAnchorNode() const
Definition: atrfrm.cxx:1614
sal_uInt8 GetWidthPercent() const
Definition: fmtfsize.hxx:91
sal_uInt8 GetHeightPercent() const
Definition: fmtfsize.hxx:88
Defines the horizontal position of a fly frame.
Definition: fmtornt.hxx:73
void SetPos(SwTwips nNew)
Definition: fmtornt.hxx:100
SwTwips GetPos() const
Definition: fmtornt.hxx:99
sal_Int16 GetRelationOrient() const
Definition: fmtornt.hxx:95
void SetSurround(css::text::WrapTextMode eNew)
Definition: fmtsrnd.hxx:55
css::text::WrapTextMode GetSurround() const
Definition: fmtsrnd.hxx:51
Defines the vertical position of a fly frame.
Definition: fmtornt.hxx:37
sal_Int16 GetRelationOrient() const
Definition: fmtornt.hxx:58
SwTwips GetPos() const
Definition: fmtornt.hxx:62
void SetPos(SwTwips nNew)
Definition: fmtornt.hxx:63
const SwDoc * GetDoc() const
The document is set in SwAttrPool now, therefore you always can access it.
Definition: format.hxx:139
const SwFormatFrameSize & GetFrameSize(bool=true) const
Definition: fmtfsize.hxx:104
const SwFormatVertOrient & GetVertOrient(bool=true) const
Definition: fmtornt.hxx:113
const SwFormatFollowTextFlow & GetFollowTextFlow(bool=true) const
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:88
const SwFormatSurround & GetSurround(bool=true) const
Definition: fmtsrnd.hxx:66
const SwFormatHoriOrient & GetHoriOrient(bool=true) const
Definition: fmtornt.hxx:115
virtual bool SetFormatAttr(const SfxPoolItem &rAttr)
Definition: format.cxx:447
const SwRect & getFrameArea() const
Definition: frame.hxx:179
bool isFrameAreaDefinitionValid() const
Definition: frame.hxx:171
bool isFrameAreaPositionValid() const
Definition: frame.hxx:166
const SwRect & getFramePrintArea() const
Definition: frame.hxx:180
void setFrameAreaPositionValid(bool bNew)
Definition: wsfrm.cxx:86
Style of a layout element.
Definition: frmfmt.hxx:72
SdrObject * FindRealSdrObject()
Definition: atrfrm.cxx:2802
Base class of the Writer layout elements.
Definition: frame.hxx:315
virtual void Cut()=0
bool IsCellFrame() const
Definition: frame.hxx:1232
const SwBodyFrame * FindBodyFrame() const
Definition: frame.hxx:1126
bool IsFootnoteContFrame() const
Definition: frame.hxx:1204
void RemoveFly(SwFlyFrame *pToRemove)
Definition: fly.cxx:2429
bool IsTextFrame() const
Definition: frame.hxx:1240
SwTextFrame * DynCastTextFrame()
Definition: findfrm.cxx:1927
bool IsInDocBody() const
Definition: frame.hxx:949
SwFlyFrame * FindFlyFrame()
Definition: frame.hxx:1117
SwSectionFrame * FindSctFrame()
Definition: frame.hxx:1121
SwTabFrame * FindTabFrame()
Definition: frame.hxx:1105
SwFrame * GetNext()
Definition: frame.hxx:682
bool HasFixSize() const
Definition: frame.hxx:676
SwLayoutFrame * GetNextSctLeaf(MakePageType eMakePage)
Returns the next layout sheet where the frame can be moved in.
Definition: sectfrm.cxx:1597
bool IsPageFrame() const
Definition: frame.hxx:1184
bool IsColLocked() const
Definition: frame.hxx:892
bool IsColumnFrame() const
Definition: frame.hxx:1188
InvalidationType
enumeration for the different invalidations #i28701#
Definition: frame.hxx:491
@ INVALID_POS
Definition: frame.hxx:492
@ INVALID_ALL
Definition: frame.hxx:492
bool IsTabFrame() const
Definition: frame.hxx:1224
virtual bool InvalidationAllowed(const InvalidationType _nInvalid) const
method to determine, if an invalidation is allowed.
Definition: wsfrm.cxx:1957
SwLayoutFrame * GetNextFlyLeaf(MakePageType eMakePage)
Definition: flycnt.cxx:1551
void InvalidatePos_()
Definition: frame.hxx:793
bool IsInFootnote() const
Definition: frame.hxx:955
SwPageFrame * InsertPage(SwPageFrame *pSibling, bool bFootnote)
Definition: pagechg.cxx:1378
const SwSortedObjs * GetDrawObjs() const
Definition: frame.hxx:568
bool IsInTab() const
Definition: frame.hxx:961
bool IsProtected() const
Is the Frame or rather the Section in which it lies protected?
Definition: trvlfrm.cxx:1639
SwLayoutFrame * GetPrevFlyLeaf()
Definition: flycnt.cxx:1736
bool IsRightToLeft() const
Definition: frame.hxx:993
bool IsInFly() const
Definition: frame.hxx:967
void AppendFly(SwFlyFrame *pNew)
Definition: fly.cxx:2411
virtual bool IsDeleteForbidden() const
Definition: frame.hxx:893
const SwRowFrame * IsInFollowFlowRow() const
Definition: findfrm.cxx:1874
virtual bool GetModelPositionForViewPoint(SwPosition *, Point &, SwCursorMoveState *=nullptr, bool bTestBackground=false) const
Definition: unusedf.cxx:47
bool IsRootFrame() const
Definition: frame.hxx:1180
bool IsFooterFrame() const
Definition: frame.hxx:1200
void InvalidatePos()
Definition: frame.hxx:1049
SwLayoutFrame * GetUpper()
Definition: frame.hxx:684
const SwLayoutFrame * GetNextLayoutLeaf() const
Definition: frame.hxx:1026
bool IsVertical() const
Definition: frame.hxx:979
SwLayoutFrame * GetLeaf(MakePageType eMakePage, bool bFwd)
Definition: flowfrm.cxx:867
void InvalidatePage(const SwPageFrame *pPage=nullptr) const
Invalidates the page in which the Frame is currently placed.
Definition: wsfrm.cxx:618
SwRootFrame * getRootFrame()
Definition: frame.hxx:685
bool IsNoTextFrame() const
Definition: frame.hxx:1244
Point GetRelPos() const
Definition: trvlfrm.cxx:1807
bool IsContentFrame() const
Definition: frame.hxx:1236
SwFrame * GetPrev()
Definition: frame.hxx:683
void InvalidateSize_()
Definition: frame.hxx:777
bool IsSctFrame() const
Definition: frame.hxx:1220
bool IsVertLR() const
Definition: frame.hxx:985
SwPageFrame * FindPageFrame()
Definition: frame.hxx:686
SwFrame * FindFooterOrHeader()
Definition: findfrm.cxx:633
static void DestroyFrame(SwFrame *const pFrame)
this is the only way to delete a SwFrame instance
Definition: ssfrm.cxx:390
bool IsInSct() const
Definition: frame.hxx:973
A layout frame is a frame that contains other frames (m_pLower), e.g. SwPageFrame or SwTabFrame.
Definition: layfrm.hxx:36
bool IsAnLower(const SwFrame *) const
Definition: findfrm.cxx:233
friend class SwFlowFrame
Definition: layfrm.hxx:38
const SwContentFrame * ContainsContent() const
Checks if the frame contains one or more ContentFrame's anywhere in his subsidiary structure; if so t...
Definition: findfrm.cxx:72
const SwContentFrame * GetContentPos(Point &rPoint, const bool bDontLeave, const bool bBodyOnly=false, SwCursorMoveState *pCMS=nullptr, const bool bDefaultExpand=true) const
Finds the closest Content for the SPoint Is used for Pages, Flys and Cells if GetModelPositionForView...
Definition: trvlfrm.cxx:1183
const SwFrame * Lower() const
Definition: layfrm.hxx:101
static void InsertMovedFwdFrame(const SwDoc &_rDoc, const SwTextFrame &_rMovedFwdFrameByObjPos, const sal_uInt32 _nToPageNum)
Definition: layouter.cxx:308
static bool FrameMovedFwdByObjPos(const SwDoc &_rDoc, const SwTextFrame &_rTextFrame, sal_uInt32 &_ornToPageNum)
Definition: layouter.cxx:338
static void RemoveMovedFwdFrame(const SwDoc &_rDoc, const SwTextFrame &_rTextFrame)
Definition: layouter.cxx:328
const SwContentNode * GetNode() const
Definition: notxtfrm.hxx:77
Marks a node in the document model.
Definition: ndindex.hxx:31
SwNode & GetNode() const
Definition: ndindex.hxx:123
SwNodeOffset GetIndex() const
Definition: ndindex.hxx:111
SwContentNode * GetContentNode()
Definition: node.hxx:666
static void FormatAnchorFrameAndItsPrevs(SwTextFrame &_rAnchorTextFrame)
method to format given anchor text frame and its previous frames
static bool CheckMovedFwdCondition(SwAnchoredObject &_rAnchoredObj, SwPageFrame const &rFromPageFrame, const bool _bAnchoredAtMasterBeforeFormatAnchor, sal_uInt32 &_noToPageNum, bool &_boInFollow, bool &o_rbPageHasFlysAnchoredBelowThis)
method to check the conditions, if 'anchor is moved forward'
A page of the document layout.
Definition: pagefrm.hxx:60
void AppendFlyToPage(SwFlyFrame *pNew)
Definition: flylay.cxx:801
void MoveFly(SwFlyFrame *pToMove, SwPageFrame *pDest)
Definition: flylay.cxx:959
tools::Long GetHeight(const SwRect &rRect) const
Definition: frame.hxx:1387
tools::Long GetTop(const SwRect &rRect) const
Definition: frame.hxx:1382
Point GetPos(const SwRect &rRect) const
Definition: frame.hxx:1388
Of course Writer needs its own rectangles.
Definition: swrect.hxx:35
void Height(tools::Long nNew)
Definition: swrect.hxx:193
void Top(const tools::Long nTop)
Definition: swrect.hxx:206
void Right(const tools::Long nRight)
Definition: swrect.hxx:202
void Bottom(const tools::Long nBottom)
Definition: swrect.hxx:211
void Pos(const Point &rNew)
Definition: swrect.hxx:171
bool Contains(const Point &rPOINT) const
Definition: swrect.hxx:356
void Left(const tools::Long nLeft)
Definition: swrect.hxx:197
void Width(tools::Long nNew)
Definition: swrect.hxx:189
void DeleteEmptyFlys_()
Destroys the registered FlyFrames.
Definition: flycnt.cxx:1660
std::unique_ptr< SwFlyDestroyList > mpFlyDestroy
Definition: rootfrm.hxx:177
void InsertEmptyFly(SwFlyFrame *pDel)
Empty SwFlyFrames are registered here for deletion and destroyed later if they are not de-registered ...
Definition: flycnt.cxx:1726
class for collecting anchored objects
Definition: sortedobjs.hxx:49
SwTabFrame is one table in the document layout, containing rows (which contain cells).
Definition: tabfrm.hxx:49
A wrapper around SfxPoolItem to store the start position of (usually) a text portion,...
Definition: txatbase.hxx:44
sal_Int32 GetStart() const
Definition: txatbase.hxx:88
static tools::Rectangle getRelativeTextRectangle(SdrObject *pShape)
Return the textbox rectangle of a draw shape (in relative twips).
static SwFrameFormat * getOtherTextBoxFormat(const SwFrameFormat *pFormat, sal_uInt16 nType, const SdrObject *pObject=nullptr)
If we have an associated TextFrame, then return that.
static void getProperty(SwFrameFormat const *pShape, sal_uInt16 nWID, sal_uInt8 nMemberID, css::uno::Any &rValue)
Get a property of the underlying TextFrame.
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:168
SwPosition MapViewToModelPos(TextFrameIndex nIndex) const
Definition: txtfrm.cxx:1333
SwTextNode * GetTextNodeFirst()
Definition: txtfrm.hxx:472
void SplitFrame(TextFrameIndex nTextPos)
Methods to manage the FollowFrame.
Definition: frmform.cxx:745
virtual void CalcPosition() override
calculate position of object
const SwLayoutFrame & GetVertPosOrientFrame() const
frame, at which the vertical position is oriented at
constexpr tools::Long Top() const
constexpr tools::Long Left() const
@ SetOnlyText
stay with the cursor inside text
virtual SotClipboardFormatId GetFormat(const TransferableDataHelper &aHelper) override
const SwContentFrame * FindAnchor(const SwFrame *pOldAnch, const Point &rNew, const bool bBodyOnly)
Searches an anchor for paragraph bound objects starting from pOldAnch.
Definition: flycnt.cxx:1084
static void lcl_PointToPrt(Point &rPoint, const SwFrame *pFrame)
Definition: flycnt.cxx:1064
static const SwFrame * lcl_CalcDownDist(SwDistance &rRet, const Point &rPt, const SwContentFrame *pCnt)
Definition: flycnt.cxx:622
static sal_uInt64 lcl_FindCntDiff(const Point &rPt, const SwLayoutFrame *pLay, const SwContentFrame *&rpCnt, const bool bBody, const bool bFootnote)
Definition: flycnt.cxx:921
static const SwContentFrame * lcl_FindCnt(const Point &rPt, const SwContentFrame *pCnt, const bool bBody, const bool bFootnote)
Definition: flycnt.cxx:981
MakePageType
Definition: frame.hxx:113
@ MAKEPAGE_INSERT
Definition: frame.hxx:116
@ MAKEPAGE_NONE
Definition: frame.hxx:114
void Notify_Background(const SdrObject *pObj, SwPageFrame *pPage, const SwRect &rRect, const PrepareHint eHint, const bool bInva)
Definition: frmtool.cxx:3412
bool bSetCompletePaintOnInvalidate
Definition: frmtool.cxx:105
const SwFrame * FindPage(const SwRect &rRect, const SwFrame *pPage)
Definition: frmtool.cxx:3751
constexpr TypedWhichId< SwFlyFrameFormat > RES_FLYFRMFMT(162)
constexpr TypedWhichId< SwFormatField > RES_TXTATR_INPUTFIELD(55)
static bool bFootnote
Definition: insfnote.cxx:33
const long LONG_MAX
#define SAL_WARN(area, stream)
int i
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
bool FrameContainsNode(SwContentFrame const &rFrame, SwNodeOffset nNodeIndex)
Definition: txtfrm.cxx:290
@ Parent
EXPAND : (Start < nIndex <= End)
SwNodeOffset min(const SwNodeOffset &a, const SwNodeOffset &b)
Definition: nodeoffset.hxx:35
SwContentNode * GetNode(SwPaM &rPam, bool &rbFirst, SwMoveFnCollection const &fnMove, bool const bInReadOnly, SwRootFrame const *const i_pLayout)
This function returns the next node in direction of search.
Definition: pam.cxx:1043
Marks a position in the document model.
Definition: pam.hxx:38
tools::Long SwTwips
Definition: swtypes.hxx:51
#define SAL_MAX_UINT64
constexpr OUStringLiteral UNO_NAME_FRAME_ISAUTOMATIC_HEIGHT
Definition: unoprnms.hxx:639
size_t pos
bool operator<(const wwFont &r1, const wwFont &r2)
Definition: wrtw8sty.cxx:885