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
55using namespace ::com::sun::star;
56
57namespace
58{
59
60SwTwips lcl_GetTopForObjPos(const SwContentFrame* pCnt, const bool bVert, const bool bVertL2R)
61{
62 if ( bVert )
63 {
64 SwTwips aResult = pCnt->getFrameArea().Left();
65 if ( bVertL2R )
66 aResult += pCnt->GetUpperSpaceAmountConsideredForPrevFrameAndPageGrid();
67 else
68 aResult += pCnt->getFrameArea().Width() - pCnt->GetUpperSpaceAmountConsideredForPrevFrameAndPageGrid();
69 return aResult;
70 }
71 else
72 return pCnt->getFrameArea().Top() + pCnt->GetUpperSpaceAmountConsideredForPrevFrameAndPageGrid();
73}
74
75}
76
78 SwFlyFreeFrame( pFormat, pSib, pAnch, bFollow ),
79 SwFlowFrame(static_cast<SwFrame&>(*this))
80{
81 m_bAtCnt = true;
82 m_bAutoPosition = (RndStdIds::FLY_AT_CHAR == pFormat->GetAnchor().GetAnchorId());
83}
84
86 : SwFlyAtContentFrame(rPrecede.GetFormat(), const_cast<SwFrame*>(rPrecede.GetAnchorFrame()),
87 const_cast<SwFrame*>(rPrecede.GetAnchorFrame()), /*bFollow=*/true)
88{
89 SetFollow(rPrecede.GetFollow());
90 rPrecede.SetFollow(this);
91}
92
94{
95}
96
97// #i28701#
98
100{
101 if (rHint.GetId() != SfxHintId::SwLegacyModify)
102 {
103 SwFlyFrame::SwClientNotify(rMod, rHint);
104 return;
105 }
106 auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
107 const SwFormatAnchor* pAnch = pLegacy->m_pNew ? GetAnchorFromPoolItem(*pLegacy->m_pNew) : nullptr;
108 if(!pAnch)
109 {
110 SwFlyFrame::SwClientNotify(rMod, rHint);
111 return;
112 }
113 OSL_ENSURE(pAnch->GetAnchorId() == GetFormat()->GetAnchor().GetAnchorId(),
114 "Illegal change of anchor type.");
115
116 //Unregister, get hold of a new anchor and attach it
118 SwPageFrame* pOldPage = FindPageFrame();
119 const SwFrame* pOldAnchor = GetAnchorFrame();
120 SwContentFrame* pContent = const_cast<SwContentFrame*>(static_cast<const SwContentFrame*>(GetAnchorFrame()));
121 AnchorFrame()->RemoveFly(this);
122
123 const bool bBodyFootnote = (pContent->IsInDocBody() || pContent->IsInFootnote());
124
125 // Search the new anchor using the NodeIdx; the relation between old
126 // and new NodeIdx determines the search direction
127 const SwNodeIndex aNewIdx(*pAnch->GetAnchorNode());
128 SwNodeIndex aOldIdx(pContent->IsTextFrame()
129 // sw_redlinehide: can pick any node here, the compare with
130 // FrameContainsNode should catch it
131 ? *static_cast<SwTextFrame *>(pContent)->GetTextNodeFirst()
132 : *static_cast<SwNoTextFrame *>(pContent)->GetNode());
133
134 //fix: depending on which index was smaller, searching in the do-while
135 //loop previously was done forward or backwards respectively. This however
136 //could lead to an infinite loop. To at least avoid the loop, searching
137 //is now done in only one direction. Getting hold of a frame from the node
138 //is still possible if the new anchor could not be found. Chances are
139 //good that this will be the correct one.
140 // consider the case that at found anchor frame candidate already a
141 // fly frame of the given fly format is registered.
142 // consider, that <pContent> is the already
143 // the new anchor frame.
144 bool bFound(FrameContainsNode(*pContent, aNewIdx.GetIndex()));
145 const bool bNext = !bFound && aOldIdx < aNewIdx;
146 while(pContent && !bFound)
147 {
148 do
149 {
150 if(bNext)
151 pContent = pContent->GetNextContentFrame();
152 else
153 pContent = pContent->GetPrevContentFrame();
154 } while(pContent &&
155 (bBodyFootnote != (pContent->IsInDocBody() || pContent->IsInFootnote())));
156 if(pContent)
157 bFound = FrameContainsNode(*pContent, aNewIdx.GetIndex());
158
159 // check, if at found anchor frame candidate already a fly frame
160 // of the given fly frame format is registered.
161 if(bFound && pContent && pContent->GetDrawObjs())
162 {
163 SwFrameFormat* pMyFlyFrameFormat(&GetFrameFormat());
164 SwSortedObjs &rObjs = *pContent->GetDrawObjs();
165 for(SwAnchoredObject* rObj : rObjs)
166 {
167 SwFlyFrame* pFlyFrame = rObj->DynCastFlyFrame();
168 if (pFlyFrame &&
169 &(pFlyFrame->GetFrameFormat()) == pMyFlyFrameFormat)
170 {
171 bFound = false;
172 break;
173 }
174 }
175 }
176 }
177 if(!pContent)
178 {
179 SwContentNode *pNode = aNewIdx.GetNode().GetContentNode();
180 std::pair<Point, bool> const tmp(pOldAnchor->getFrameArea().Pos(), false);
181 pContent = pNode->getLayoutFrame(getRootFrame(), nullptr, &tmp);
182 OSL_ENSURE(pContent, "New anchor not found");
183 }
184 //Flys are never attached to a follow, but always on the master which
185 //we are going to search now.
186 SwContentFrame* pFlow = pContent;
187 while(pFlow->IsFollow())
188 pFlow = pFlow->FindMaster();
189 pContent = pFlow;
190
191 //and *puff* it's attached...
192 pContent->AppendFly( this );
193 if(pOldPage && pOldPage != FindPageFrame())
195
196 //Fix(3495)
200 // #i28701# - reset member <maLastCharRect> and
201 // <mnLastTopOfLine> for to-character anchored objects.
203}
204
205//We need some helper classes to monitor the oscillation and a few functions
206//to not get lost.
207
208namespace {
209
210// #i3317# - re-factoring of the position stack
211class SwOszControl
212{
213 static const SwFlyFrame* s_pStack1;
214 static const SwFlyFrame* s_pStack2;
215 static const SwFlyFrame* s_pStack3;
216 static const SwFlyFrame* s_pStack4;
217 static const SwFlyFrame* s_pStack5;
218
219 const SwFlyFrame* m_pFly;
220 std::vector<Point> maObjPositions;
221
222public:
223 explicit SwOszControl( const SwFlyFrame *pFrame );
224 ~SwOszControl();
225 bool ChkOsz();
226 static bool IsInProgress( const SwFlyFrame *pFly );
227};
228
229}
230
231const SwFlyFrame* SwOszControl::s_pStack1 = nullptr;
232const SwFlyFrame* SwOszControl::s_pStack2 = nullptr;
233const SwFlyFrame* SwOszControl::s_pStack3 = nullptr;
234const SwFlyFrame* SwOszControl::s_pStack4 = nullptr;
235const SwFlyFrame* SwOszControl::s_pStack5 = nullptr;
236
237SwOszControl::SwOszControl(const SwFlyFrame* pFrame)
238 : m_pFly(pFrame)
239{
240 if (!SwOszControl::s_pStack1)
241 SwOszControl::s_pStack1 = m_pFly;
242 else if (!SwOszControl::s_pStack2)
243 SwOszControl::s_pStack2 = m_pFly;
244 else if (!SwOszControl::s_pStack3)
245 SwOszControl::s_pStack3 = m_pFly;
246 else if (!SwOszControl::s_pStack4)
247 SwOszControl::s_pStack4 = m_pFly;
248 else if (!SwOszControl::s_pStack5)
249 SwOszControl::s_pStack5 = m_pFly;
250}
251
252SwOszControl::~SwOszControl()
253{
254 if (SwOszControl::s_pStack1 == m_pFly)
255 SwOszControl::s_pStack1 = nullptr;
256 else if (SwOszControl::s_pStack2 == m_pFly)
257 SwOszControl::s_pStack2 = nullptr;
258 else if (SwOszControl::s_pStack3 == m_pFly)
259 SwOszControl::s_pStack3 = nullptr;
260 else if (SwOszControl::s_pStack4 == m_pFly)
261 SwOszControl::s_pStack4 = nullptr;
262 else if (SwOszControl::s_pStack5 == m_pFly)
263 SwOszControl::s_pStack5 = nullptr;
264 // #i3317#
265 maObjPositions.clear();
266}
267
268bool SwOszControl::IsInProgress( const SwFlyFrame *pFly )
269{
270 if (SwOszControl::s_pStack1 && !pFly->IsLowerOf(SwOszControl::s_pStack1))
271 return true;
272 if (SwOszControl::s_pStack2 && !pFly->IsLowerOf(SwOszControl::s_pStack2))
273 return true;
274 if (SwOszControl::s_pStack3 && !pFly->IsLowerOf(SwOszControl::s_pStack3))
275 return true;
276 if (SwOszControl::s_pStack4 && !pFly->IsLowerOf(SwOszControl::s_pStack4))
277 return true;
278 if (SwOszControl::s_pStack5 && !pFly->IsLowerOf(SwOszControl::s_pStack5))
279 return true;
280 return false;
281}
282
283bool SwOszControl::ChkOsz()
284{
285 bool bOscillationDetected = false;
286
287 if ( maObjPositions.size() == 20 )
288 {
289 // #i3317# position stack is full -> oscillation
290 bOscillationDetected = true;
291 }
292 else
293 {
294 Point aNewObjPos = m_pFly->GetObjRect().Pos();
295 for ( auto const & pt : maObjPositions )
296 {
297 if ( aNewObjPos == pt )
298 {
299 // position already occurred -> oscillation
300 bOscillationDetected = true;
301 break;
302 }
303 }
304 if ( !bOscillationDetected )
305 {
306 maObjPositions.push_back( aNewObjPos );
307 }
308 }
309
310 return bOscillationDetected;
311}
312
330{
331 if ( !GetFormat()->GetDoc()->getIDocumentDrawModelAccess().IsVisibleLayerId( GetVirtDrawObj()->GetLayer() ) )
332 {
333 return;
334 }
335
336 if ( SwOszControl::IsInProgress( this ) || IsLocked() || IsColLocked() )
337 return;
338
339 // #i28701# - use new method <GetPageFrame()>
341 {
343 SwPageFrame *pTmpPage = pFly ? pFly->FindPageFrame() : nullptr;
344 if( pTmpPage )
345 pTmpPage->AppendFlyToPage( this );
346 }
347 // #i28701# - use new method <GetPageFrame()>
348 if( !GetPageFrame() )
349 return;
350
352 {
353 SwFlyFrameFormat *pFormat = GetFormat();
354 const SwFormatFrameSize &rFrameSz = GetFormat()->GetFrameSize();
356 rFrameSz.GetHeightPercent() >= 100 )
357 {
358 pFormat->LockModify();
359 SwFormatSurround aMain( pFormat->GetSurround() );
360 if ( aMain.GetSurround() == css::text::WrapTextMode_NONE )
361 {
362 aMain.SetSurround( css::text::WrapTextMode_THROUGH );
363 pFormat->SetFormatAttr( aMain );
364 }
365 pFormat->UnlockModify();
366 }
367 }
368
369 SwOszControl aOszCntrl( this );
370
371 // #i43255#
372 // #i50356# - format the anchor frame, which
373 // contains the anchor position. E.g., for at-character anchored
374 // object this can be the follow frame of the anchor frame.
375 const bool bFormatAnchor =
376 !static_cast<const SwTextFrame*>( GetAnchorFrameContainingAnchPos() )->IsAnyJoinLocked() &&
379
380 const SwFrame* pFooter = GetAnchorFrame()->FindFooterOrHeader();
381 if( pFooter && !pFooter->IsFooterFrame() )
382 pFooter = nullptr;
383 bool bOsz = false;
384 bool bExtra = Lower() && Lower()->IsColumnFrame();
385 // #i3317# - boolean, to apply temporarily the
386 // 'straightforward positioning process' for the frame due to its
387 // overlapping with a previous column.
388 bool bConsiderWrapInfluenceDueToOverlapPrevCol( false );
389 // #i35911# - boolean, to apply temporarily the
390 // 'straightforward positioning process' for the frame due to fact
391 // that it causes the complete content of its layout environment
392 // to move forward.
393 // #i40444# - extend usage of this boolean:
394 // apply temporarily the 'straightforward positioning process' for
395 // the frame due to the fact that the frame clears the area for
396 // the anchor frame, thus it has to move forward.
397 bool bConsiderWrapInfluenceDueToMovedFwdAnchor( false );
398 do {
399 SwRectFnSet aRectFnSet(this);
400 Point aOldPos( aRectFnSet.GetPos(getFrameArea()) );
401 SwFlyFreeFrame::MakeAll(pRenderContext);
402
403 const bool bPosChgDueToOwnFormat =
404 aOldPos != aRectFnSet.GetPos(getFrameArea());
405 // #i3317#
408 {
409 bConsiderWrapInfluenceDueToOverlapPrevCol = true;
410 }
411 // #i28701# - no format of anchor frame, if
412 // wrapping style influence is considered on object positioning
413 if ( bFormatAnchor )
414 {
415 SwTextFrame& rAnchPosAnchorFrame =
417 // #i58182# - For the usage of new method
418 // <SwObjectFormatterTextFrame::CheckMovedFwdCondition(..)>
419 // to check move forward of anchor frame due to the object
420 // positioning it's needed to know, if the object is anchored
421 // at the master frame before the anchor frame is formatted.
422 const bool bAnchoredAtMaster(!rAnchPosAnchorFrame.IsFollow());
423
424 // #i56300#
425 // perform complete format of anchor text frame and its
426 // previous frames, which have become invalid due to the
427 // fly frame format.
429 // #i35911#
430 // #i40444#
431 // #i58182# - usage of new method
432 // <SwObjectFormatterTextFrame::CheckMovedFwdCondition(..)>
433 sal_uInt32 nToPageNum( 0 );
434 bool bDummy( false );
435 bool bPageHasFlysAnchoredBelowThis(false);
437// TODO: what if this fly moved bc it's in table? does sth prevent that?
438 *this, *GetPageFrame(),
439 bAnchoredAtMaster, nToPageNum, bDummy,
440 bPageHasFlysAnchoredBelowThis) )
441 {
442 if (!bPageHasFlysAnchoredBelowThis)
443 {
444 bConsiderWrapInfluenceDueToMovedFwdAnchor = true;
445 }
446 // mark anchor text frame
447 // directly, that it is moved forward by object positioning.
448 SwTextFrame* pAnchorTextFrame( static_cast<SwTextFrame*>(AnchorFrame()) );
449 bool bInsert( true );
450 sal_uInt32 nAnchorFrameToPageNum( 0 );
451 const SwDoc& rDoc = *(GetFrameFormat().GetDoc());
453 rDoc, *pAnchorTextFrame, nAnchorFrameToPageNum ) )
454 {
455 if ( nAnchorFrameToPageNum < nToPageNum )
456 {
457 if (!bPageHasFlysAnchoredBelowThis)
458 {
459 SwLayouter::RemoveMovedFwdFrame(rDoc, *pAnchorTextFrame);
460 }
461 }
462 else
463 bInsert = false;
464 }
465 if ( bInsert )
466 {
467 if (!bPageHasFlysAnchoredBelowThis)
468 {
469 SwLayouter::InsertMovedFwdFrame(rDoc, *pAnchorTextFrame,
470 nToPageNum);
471 }
472 }
473 }
474 }
475
476 if ( aOldPos != aRectFnSet.GetPos(getFrameArea()) ||
478 ( pFooter || bPosChgDueToOwnFormat ) ) )
479 {
480 bOsz = aOszCntrl.ChkOsz();
481
482 // special loop prevention for dedicated document:
483 if ( bOsz &&
484 HasFixSize() && IsClipped() &&
486 {
487 SwFrameFormat* pFormat = GetFormat();
488 const SwFormatFrameSize& rFrameSz = pFormat->GetFrameSize();
489 if ( rFrameSz.GetWidthPercent() &&
491 {
492 SwFormatSurround aSurround( pFormat->GetSurround() );
493 if ( aSurround.GetSurround() == css::text::WrapTextMode_NONE )
494 {
495 pFormat->LockModify();
496 aSurround.SetSurround( css::text::WrapTextMode_THROUGH );
497 pFormat->SetFormatAttr( aSurround );
498 pFormat->UnlockModify();
499 bOsz = false;
500 OSL_FAIL( "<SwFlyAtContentFrame::MakeAll()> - special loop prevention for dedicated document of b6403541 applied" );
501 }
502 }
503 }
504 }
505
506 if ( bExtra && Lower() && !Lower()->isFrameAreaPositionValid() )
507 {
508 // If a multi column frame leaves invalid columns because of
509 // a position change, we loop once more and format
510 // our content using FormatWidthCols again.
512 bExtra = false; // Ensure only one additional loop run
513 }
514 } while ( !isFrameAreaDefinitionValid() && !bOsz &&
515 // #i3317#
516 !bConsiderWrapInfluenceDueToOverlapPrevCol &&
517 // #i40444#
518 !bConsiderWrapInfluenceDueToMovedFwdAnchor &&
519 GetFormat()->GetDoc()->getIDocumentDrawModelAccess().IsVisibleLayerId( GetVirtDrawObj()->GetLayer() ) );
520
521 // #i3317# - instead of attribute change apply
522 // temporarily the 'straightforward positioning process'.
523 // #i80924#
524 // handle special case during splitting of table rows
525 if ( bConsiderWrapInfluenceDueToMovedFwdAnchor &&
526 GetAnchorFrame()->IsInTab() &&
528 {
529 const SwFrame* pCellFrame = GetAnchorFrame();
530 while ( pCellFrame && !pCellFrame->IsCellFrame() )
531 {
532 pCellFrame = pCellFrame->GetUpper();
533 }
534 if ( pCellFrame )
535 {
536 SwRectFnSet aRectFnSet(pCellFrame);
537 if ( aRectFnSet.GetTop(pCellFrame->getFrameArea()) == 0 &&
538 aRectFnSet.GetHeight(pCellFrame->getFrameArea()) == 0 )
539 {
540 bConsiderWrapInfluenceDueToMovedFwdAnchor = false;
541 }
542 }
543 }
544 // tdf#137803: Fix the position of the shape during autoSize
545 SwFrameFormat* pShapeFormat
547 // FIXME: According to tdf37153, ignore FollowTextFlow objs, because
548 // wrong position will applied in that case. FollowTextFlow needs fix.
549 if (pShapeFormat && !pShapeFormat->GetFollowTextFlow().GetValue() &&
550 SwTextBoxHelper::getProperty(pShapeFormat,
552 SwTextBoxHelper::getProperty(pShapeFormat,
554 {
555 // get the text area of the shape
556 const tools::Rectangle aTextRectangle
558 // get the original textframe position
559 SwFormatHoriOrient aHOri = pShapeFormat->GetHoriOrient();
560 SwFormatVertOrient aVOri = pShapeFormat->GetVertOrient();
561 // calc the right position of the shape depending on text area
562 aHOri.SetPos(aHOri.GetPos() + aTextRectangle.Left());
563 aVOri.SetPos(aVOri.GetPos() + aTextRectangle.Top());
564 // save the new position for the shape
565 auto pFormat = GetFormat();
566 const bool bLocked = pFormat->IsModifyLocked();
567 if (!bLocked)
568 pFormat->LockModify();
569 pFormat->SetFormatAttr(aHOri);
570 pFormat->SetFormatAttr(aVOri);
571 if (!bLocked)
572 pFormat->UnlockModify();
573 }
574 if ( bOsz || bConsiderWrapInfluenceDueToOverlapPrevCol ||
575 // #i40444#
576 bConsiderWrapInfluenceDueToMovedFwdAnchor )
577 {
581 }
583}
584
590{
592 !SwOszControl::IsInProgress( this );
593}
594
595namespace {
596
597class SwDistance
598{
599public:
600 SwTwips m_nMain, m_nSub;
601 SwDistance()
602 : m_nMain(0)
603 , m_nSub(0)
604 {
605 }
606 bool operator<( const SwDistance& rTwo ) const
607 {
608 return m_nMain < rTwo.m_nMain
609 || (m_nMain == rTwo.m_nMain && m_nSub && rTwo.m_nSub && m_nSub < rTwo.m_nSub);
610 }
611 bool operator<=( const SwDistance& rTwo ) const
612 {
613 return m_nMain < rTwo.m_nMain
614 || (m_nMain == rTwo.m_nMain
615 && (!m_nSub || !rTwo.m_nSub || m_nSub <= rTwo.m_nSub));
616 }
617};
618
619}
620
621static const SwFrame * lcl_CalcDownDist( SwDistance &rRet,
622 const Point &rPt,
623 const SwContentFrame *pCnt )
624{
625 rRet.m_nSub = 0;
626 //If the point stays inside the Cnt everything is clear already; the Content
627 //automatically has a distance of 0.
628 if ( pCnt->getFrameArea().Contains( rPt ) )
629 {
630 rRet.m_nMain = 0;
631 return pCnt;
632 }
633 else
634 {
635 const SwLayoutFrame *pUp = pCnt->IsInTab() ? pCnt->FindTabFrame()->GetUpper() : pCnt->GetUpper();
636 // single column sections need to interconnect to their upper
637 while( pUp->IsSctFrame() )
638 pUp = pUp->GetUpper();
639 const bool bVert = pUp->IsVertical();
640
641 const bool bVertL2R = pUp->IsVertLR();
642
643 //Follow the text flow.
644 // #i70582#
645 // --> OD 2009-03-05 - adopted for Support for Classical Mongolian Script
646 const SwTwips nTopForObjPos = lcl_GetTopForObjPos(pCnt, bVert, bVertL2R);
647 if ( pUp->getFrameArea().Contains( rPt ) )
648 {
649 // <rPt> point is inside environment of given content frame
650 // #i70582#
651 if( bVert )
652 {
653 if ( bVertL2R )
654 rRet.m_nMain = rPt.X() - nTopForObjPos;
655 else
656 rRet.m_nMain = nTopForObjPos - rPt.X();
657 }
658 else
659 rRet.m_nMain = rPt.Y() - nTopForObjPos;
660 return pCnt;
661 }
662 else if ( rPt.Y() <= pUp->getFrameArea().Top() )
663 {
664 // <rPt> point is above environment of given content frame
665 // correct for vertical layout?
666 rRet.m_nMain = LONG_MAX;
667 }
668 else if( rPt.X() < pUp->getFrameArea().Left() &&
669 rPt.Y() <= ( bVert ? pUp->getFrameArea().Top() : pUp->getFrameArea().Bottom() ) )
670 {
671 // <rPt> point is left of environment of given content frame
672 // seems not to be correct for vertical layout!?
673 const SwFrame *pLay = pUp->GetLeaf( MAKEPAGE_NONE, false, pCnt );
674 if( !pLay ||
675 (bVert && (pLay->getFrameArea().Top() + pLay->getFramePrintArea().Bottom()) <rPt.Y())||
676 (!bVert && (pLay->getFrameArea().Left() + pLay->getFramePrintArea().Right())<rPt.X()) )
677 {
678 // <rPt> point is in left border of environment
679 // #i70582#
680 if( bVert )
681 {
682 if ( bVertL2R )
683 rRet.m_nMain = rPt.X() - nTopForObjPos;
684 else
685 rRet.m_nMain = nTopForObjPos - rPt.X();
686 }
687 else
688 rRet.m_nMain = rPt.Y() - nTopForObjPos;
689 return pCnt;
690 }
691 else
692 rRet.m_nMain = LONG_MAX;
693 }
694 else
695 {
696 rRet.m_nMain
697 = bVert ? (bVertL2R
698 ? ((pUp->getFrameArea().Left() + pUp->getFramePrintArea().Right())
699 - nTopForObjPos)
700 : (nTopForObjPos
701 - (pUp->getFrameArea().Left() + pUp->getFramePrintArea().Left())))
702 : ((pUp->getFrameArea().Top() + pUp->getFramePrintArea().Bottom())
703 - nTopForObjPos);
704
705 const SwFrame *pPre = pCnt;
706 const SwFrame *pLay = pUp->GetLeaf( MAKEPAGE_NONE, true, pCnt );
707 SwTwips nFrameTop = 0;
708 SwTwips nPrtHeight = 0;
709 bool bSct = false;
710 const SwSectionFrame *pSect = pUp->FindSctFrame();
711 if( pSect )
712 {
713 rRet.m_nSub = rRet.m_nMain;
714 rRet.m_nMain = 0;
715 }
716 if( pSect && !pSect->IsAnLower( pLay ) )
717 {
718 bSct = false;
719 const SwSectionFrame* pNxtSect = pLay ? pLay->FindSctFrame() : nullptr;
720 if (pSect->IsAnFollow(pNxtSect) && pLay)
721 {
722 if( pLay->IsVertical() )
723 {
724 if ( pLay->IsVertLR() )
725 nFrameTop = pLay->getFrameArea().Left();
726 else
727 nFrameTop = pLay->getFrameArea().Left() + pLay->getFrameArea().Width();
728 nPrtHeight = pLay->getFramePrintArea().Width();
729 }
730 else
731 {
732 nFrameTop = pLay->getFrameArea().Top();
733 nPrtHeight = pLay->getFramePrintArea().Height();
734 }
735 pSect = pNxtSect;
736 }
737 else
738 {
739 pLay = pSect->GetUpper();
740 if( pLay->IsVertical() )
741 {
742 if ( pLay->IsVertLR() )
743 {
744 nFrameTop = pSect->getFrameArea().Right();
745 nPrtHeight = pLay->getFrameArea().Left() + pLay->getFramePrintArea().Left()
746 + pLay->getFramePrintArea().Width() - pSect->getFrameArea().Left()
747 - pSect->getFrameArea().Width();
748 }
749 else
750 {
751 nFrameTop = pSect->getFrameArea().Left();
752 nPrtHeight = pSect->getFrameArea().Left() - pLay->getFrameArea().Left()
753 - pLay->getFramePrintArea().Left();
754 }
755 }
756 else
757 {
758 nFrameTop = pSect->getFrameArea().Bottom();
759 nPrtHeight = pLay->getFrameArea().Top() + pLay->getFramePrintArea().Top()
760 + pLay->getFramePrintArea().Height() - pSect->getFrameArea().Top()
761 - pSect->getFrameArea().Height();
762 }
763 pSect = nullptr;
764 }
765 }
766 else if( pLay )
767 {
768 if( pLay->IsVertical() )
769 {
770 if ( pLay->IsVertLR() )
771 {
772 nFrameTop = pLay->getFrameArea().Left();
773 nPrtHeight = pLay->getFramePrintArea().Width();
774 }
775 else
776 {
777 nFrameTop = pLay->getFrameArea().Left() + pLay->getFrameArea().Width();
778 nPrtHeight = pLay->getFramePrintArea().Width();
779 }
780 }
781 else
782 {
783 nFrameTop = pLay->getFrameArea().Top();
784 nPrtHeight = pLay->getFramePrintArea().Height();
785 }
786 bSct = nullptr != pSect;
787 }
788 while ( pLay && !pLay->getFrameArea().Contains( rPt ) &&
789 ( pLay->getFrameArea().Top() <= rPt.Y() || pLay->IsInFly() ||
790 ( pLay->IsInSct() &&
791 pLay->FindSctFrame()->GetUpper()->getFrameArea().Top() <= rPt.Y())) )
792 {
793 if ( pLay->IsFootnoteContFrame() )
794 {
795 if ( !static_cast<const SwLayoutFrame*>(pLay)->Lower() )
796 {
797 SwFrame *pDel = const_cast<SwFrame*>(pLay);
798 pDel->Cut();
800 return pPre;
801 }
802 return nullptr;
803 }
804 else
805 {
806 if( bSct || pSect )
807 rRet.m_nSub += nPrtHeight;
808 else
809 rRet.m_nMain += nPrtHeight;
810 pPre = pLay;
811 pLay = pLay->GetLeaf( MAKEPAGE_NONE, true, pCnt );
812 if( pSect && !pSect->IsAnLower( pLay ) )
813 { // If we're leaving a SwSectionFrame, the next Leaf-Frame
814 // is the part of the upper below the SectionFrame.
815 const SwSectionFrame* pNxtSect = pLay ?
816 pLay->FindSctFrame() : nullptr;
817 bSct = false;
818 if (pLay && pSect->IsAnFollow(pNxtSect))
819 {
820 pSect = pNxtSect;
821 if( pLay->IsVertical() )
822 {
823 if ( pLay->IsVertLR() )
824 {
825 nFrameTop = pLay->getFrameArea().Left();
826 nPrtHeight = pLay->getFramePrintArea().Width();
827 }
828 else
829 {
830 nFrameTop = pLay->getFrameArea().Left() + pLay->getFrameArea().Width();
831 nPrtHeight = pLay->getFramePrintArea().Width();
832 }
833 }
834 else
835 {
836 nFrameTop = pLay->getFrameArea().Top();
837 nPrtHeight = pLay->getFramePrintArea().Height();
838 }
839 }
840 else
841 {
842 pLay = pSect->GetUpper();
843 if( pLay->IsVertical() )
844 {
845 if ( pLay->IsVertLR() )
846 {
847 nFrameTop = pSect->getFrameArea().Right();
848 nPrtHeight = pLay->getFrameArea().Left()+pLay->getFramePrintArea().Left()
849 + pLay->getFramePrintArea().Width() - pSect->getFrameArea().Left()
850 - pSect->getFrameArea().Width();
851 }
852 else
853 {
854 nFrameTop = pSect->getFrameArea().Left();
855 nPrtHeight = pSect->getFrameArea().Left() -
856 pLay->getFrameArea().Left() - pLay->getFramePrintArea().Left();
857 }
858 }
859 else
860 {
861 nFrameTop = pSect->getFrameArea().Bottom();
862 nPrtHeight = pLay->getFrameArea().Top()+pLay->getFramePrintArea().Top()
863 + pLay->getFramePrintArea().Height() - pSect->getFrameArea().Top()
864 - pSect->getFrameArea().Height();
865 }
866 pSect = nullptr;
867 }
868 }
869 else if( pLay )
870 {
871 if( pLay->IsVertical() )
872 {
873 if ( pLay->IsVertLR() )
874 {
875 nFrameTop = pLay->getFrameArea().Left();
876 nPrtHeight = pLay->getFramePrintArea().Width();
877 }
878 else
879 {
880 nFrameTop = pLay->getFrameArea().Left() + pLay->getFrameArea().Width();
881 nPrtHeight = pLay->getFramePrintArea().Width();
882 }
883 }
884 else
885 {
886 nFrameTop = pLay->getFrameArea().Top();
887 nPrtHeight = pLay->getFramePrintArea().Height();
888 }
889 bSct = nullptr != pSect;
890 }
891 }
892 }
893 if ( pLay )
894 {
895 if ( pLay->getFrameArea().Contains( rPt ) )
896 {
897 SwTwips nDiff = pLay->IsVertical() ? ( pLay->IsVertLR() ? ( rPt.X() - nFrameTop ) : ( nFrameTop - rPt.X() ) )
898 : ( rPt.Y() - nFrameTop );
899 if( bSct || pSect )
900 rRet.m_nSub += nDiff;
901 else
902 rRet.m_nMain += nDiff;
903 }
904 if ( pLay->IsFootnoteContFrame() && !static_cast<const SwLayoutFrame*>(pLay)->Lower() )
905 {
906 SwFrame *pDel = const_cast<SwFrame*>(pLay);
907 pDel->Cut();
909 return nullptr;
910 }
911 return pLay;
912 }
913 else
914 rRet.m_nMain = LONG_MAX;
915 }
916 }
917 return nullptr;
918}
919
920static sal_uInt64 lcl_FindCntDiff( const Point &rPt, const SwLayoutFrame *pLay,
921 const SwContentFrame *& rpCnt,
922 const bool bBody, const bool bFootnote )
923{
924 // Searches below pLay the nearest Cnt to the point. The reference point of
925 //the Contents is always the left upper corner.
926 //The Cnt should preferably be above the point.
927
928 rpCnt = nullptr;
929 sal_uInt64 nDistance = SAL_MAX_UINT64;
930 sal_uInt64 nNearest = SAL_MAX_UINT64;
931 const SwContentFrame *pCnt = pLay ? pLay->ContainsContent() : nullptr;
932
933 while ( pCnt && (bBody != pCnt->IsInDocBody() || bFootnote != pCnt->IsInFootnote()))
934 {
935 pCnt = pCnt->GetNextContentFrame();
936 if ( !pLay->IsAnLower( pCnt ) )
937 pCnt = nullptr;
938 }
939 const SwContentFrame *pNearest = pCnt;
940 if ( pCnt )
941 {
942 do
943 {
944 //Calculate the distance between those two points.
945 //'delta' X^2 + 'delta' Y^2 = 'distance'^2
946 sal_uInt64 dX = std::max( pCnt->getFrameArea().Left(), rPt.X() ) -
947 std::min( pCnt->getFrameArea().Left(), rPt.X() ),
948 dY = std::max( pCnt->getFrameArea().Top(), rPt.Y() ) -
949 std::min( pCnt->getFrameArea().Top(), rPt.Y() );
950 // square of the difference will do fine here
951 const sal_uInt64 nDiff = (dX * dX) + (dY * dY);
952 if ( pCnt->getFrameArea().Top() <= rPt.Y() )
953 {
954 if ( nDiff < nDistance )
955 {
956 //This one is the nearer one
957 nDistance = nNearest = nDiff;
958 rpCnt = pNearest = pCnt;
959 }
960 }
961 else if ( nDiff < nNearest )
962 {
963 nNearest = nDiff;
964 pNearest = pCnt;
965 }
966 pCnt = pCnt->GetNextContentFrame();
967 while ( pCnt &&
968 (bBody != pCnt->IsInDocBody() || bFootnote != pCnt->IsInFootnote()))
969 pCnt = pCnt->GetNextContentFrame();
970
971 } while ( pCnt && pLay->IsAnLower( pCnt ) );
972 }
973 if (nDistance == SAL_MAX_UINT64)
974 { rpCnt = pNearest;
975 return nNearest;
976 }
977 return nDistance;
978}
979
980static const SwContentFrame * lcl_FindCnt( const Point &rPt, const SwContentFrame *pCnt,
981 const bool bBody, const bool bFootnote )
982{
983 //Starting from pCnt searches the ContentFrame whose left upper corner is the
984 //nearest to the point.
985 //Always returns a ContentFrame.
986
987 //First the nearest Content inside the page which contains the Content is
988 //searched. Starting from this page the pages in both directions need to
989 //be considered. If possible a Content is returned whose Y-position is
990 //above the point.
991 const SwContentFrame *pRet, *pNew;
992 const SwLayoutFrame *pLay = pCnt->FindPageFrame();
993 sal_uInt64 nDist; // not sure if a sal_Int32 would be enough?
994
995 nDist = ::lcl_FindCntDiff( rPt, pLay, pNew, bBody, bFootnote );
996 if ( pNew )
997 pRet = pNew;
998 else
999 { pRet = pCnt;
1000 nDist = SAL_MAX_UINT64;
1001 }
1002 const SwContentFrame *pNearest = pRet;
1003 sal_uInt64 nNearest = nDist;
1004
1005 if ( pLay )
1006 {
1007 const SwLayoutFrame *pPge = pLay;
1008 sal_uInt64 nOldNew = SAL_MAX_UINT64;
1009 for ( int i = 0; pPge->GetPrev() && (i < 3); ++i )
1010 {
1011 pPge = static_cast<const SwLayoutFrame*>(pPge->GetPrev());
1012 const sal_uInt64 nNew = ::lcl_FindCntDiff( rPt, pPge, pNew, bBody, bFootnote );
1013 if ( nNew < nDist )
1014 {
1015 if ( pNew->getFrameArea().Top() <= rPt.Y() )
1016 {
1017 pRet = pNearest = pNew;
1018 nDist = nNearest = nNew;
1019 }
1020 else if ( nNew < nNearest )
1021 {
1022 pNearest = pNew;
1023 nNearest = nNew;
1024 }
1025 }
1026 else if (nOldNew != SAL_MAX_UINT64 && nNew > nOldNew)
1027 break;
1028 else
1029 nOldNew = nNew;
1030
1031 }
1032 pPge = pLay;
1033 nOldNew = SAL_MAX_UINT64;
1034 for ( int j = 0; pPge->GetNext() && (j < 3); ++j )
1035 {
1036 pPge = static_cast<const SwLayoutFrame*>(pPge->GetNext());
1037 const sal_uInt64 nNew = ::lcl_FindCntDiff( rPt, pPge, pNew, bBody, bFootnote );
1038 if ( nNew < nDist )
1039 {
1040 if ( pNew->getFrameArea().Top() <= rPt.Y() )
1041 {
1042 pRet = pNearest = pNew;
1043 nDist = nNearest = nNew;
1044 }
1045 else if ( nNew < nNearest )
1046 {
1047 pNearest = pNew;
1048 nNearest = nNew;
1049 }
1050 }
1051 else if (nOldNew != SAL_MAX_UINT64 && nNew > nOldNew)
1052 break;
1053 else
1054 nOldNew = nNew;
1055 }
1056 }
1057 if ( pRet->getFrameArea().Top() > rPt.Y() )
1058 return pNearest;
1059 else
1060 return pRet;
1061}
1062
1063static void lcl_PointToPrt( Point &rPoint, const SwFrame *pFrame )
1064{
1065 SwRect aTmp( pFrame->getFramePrintArea() );
1066 aTmp += pFrame->getFrameArea().Pos();
1067 if ( rPoint.getX() < aTmp.Left() )
1068 rPoint.setX(aTmp.Left());
1069 else if ( rPoint.getX() > aTmp.Right() )
1070 rPoint.setX(aTmp.Right());
1071 if ( rPoint.getY() < aTmp.Top() )
1072 rPoint.setY(aTmp.Top());
1073 else if ( rPoint.getY() > aTmp.Bottom() )
1074 rPoint.setY(aTmp.Bottom());
1075
1076}
1077
1083const SwContentFrame *FindAnchor( const SwFrame *pOldAnch, const Point &rNew,
1084 const bool bBodyOnly )
1085{
1086 //Search the nearest Cnt around the given document position in the text
1087 //flow. The given anchor is the starting Frame.
1088 const SwContentFrame* pCnt;
1089 if ( pOldAnch->IsContentFrame() )
1090 {
1091 pCnt = static_cast<const SwContentFrame*>(pOldAnch);
1092 }
1093 else
1094 {
1095 Point aTmp( rNew );
1096 const SwLayoutFrame *pTmpLay = static_cast<const SwLayoutFrame*>(pOldAnch);
1097 if( pTmpLay->IsRootFrame() )
1098 {
1099 SwRect aTmpRect( aTmp, Size(0,0) );
1100 pTmpLay = static_cast<const SwLayoutFrame*>(::FindPage( aTmpRect, pTmpLay->Lower() ));
1101 }
1102 pCnt = pTmpLay->GetContentPos( aTmp, false, bBodyOnly );
1103 }
1104
1105 //Take care to use meaningful ranges during search. This means to not enter
1106 //or leave header/footer in this case.
1107 const bool bBody = pCnt->IsInDocBody() || bBodyOnly;
1108 const bool bFootnote = !bBodyOnly && pCnt->IsInFootnote();
1109
1110 Point aNew( rNew );
1111 if ( bBody )
1112 {
1113 //#38848 drag from page margin into the body.
1114 const SwFrame *pPage = pCnt->FindPageFrame();
1115 ::lcl_PointToPrt( aNew, pPage->GetUpper() );
1116 SwRect aTmp( aNew, Size( 0, 0 ) );
1117 pPage = ::FindPage( aTmp, pPage );
1118 ::lcl_PointToPrt( aNew, pPage );
1119 }
1120
1121 if ( pCnt->IsInDocBody() == bBody && pCnt->getFrameArea().Contains( aNew ) )
1122 return pCnt;
1123 else if ( pOldAnch->IsInDocBody() || pOldAnch->IsPageFrame() )
1124 {
1125 // Maybe the selected anchor is on the same page as the current anchor.
1126 // With this we won't run into problems with the columns.
1127 Point aTmp( aNew );
1128 const SwContentFrame *pTmp = pCnt->FindPageFrame()->
1129 GetContentPos( aTmp, false, true );
1130 if ( pTmp && pTmp->getFrameArea().Contains( aNew ) )
1131 return pTmp;
1132 }
1133
1134 //Starting from the anchor we now search in both directions until we found
1135 //the nearest one respectively.
1136 //Not the direct distance is relevant but the distance which needs to be
1137 //traveled through the text flow.
1138 const SwContentFrame *pUpLst;
1139 const SwContentFrame *pUpFrame = pCnt;
1140 SwDistance nUp, nUpLst;
1141 ::lcl_CalcDownDist( nUp, aNew, pUpFrame );
1142 SwDistance nDown = nUp;
1143 bool bNegAllowed = true;// Make it possible to leave the negative section once.
1144 do
1145 {
1146 pUpLst = pUpFrame; nUpLst = nUp;
1147 pUpFrame = pUpLst->GetPrevContentFrame();
1148 while ( pUpFrame &&
1149 (bBody != pUpFrame->IsInDocBody() || bFootnote != pUpFrame->IsInFootnote()))
1150 pUpFrame = pUpFrame->GetPrevContentFrame();
1151 if ( pUpFrame )
1152 {
1153 ::lcl_CalcDownDist( nUp, aNew, pUpFrame );
1154 //It makes sense to search further, if the distance grows inside
1155 //a table.
1156 if ( pUpLst->IsInTab() && pUpFrame->IsInTab() )
1157 {
1158 while ( pUpFrame && ((nUpLst < nUp && pUpFrame->IsInTab()) ||
1159 bBody != pUpFrame->IsInDocBody()) )
1160 {
1161 pUpFrame = pUpFrame->GetPrevContentFrame();
1162 if ( pUpFrame )
1163 ::lcl_CalcDownDist( nUp, aNew, pUpFrame );
1164 }
1165 }
1166 }
1167 if ( !pUpFrame )
1168 nUp.m_nMain = LONG_MAX;
1169 if (nUp.m_nMain >= 0 && LONG_MAX != nUp.m_nMain)
1170 {
1171 bNegAllowed = false;
1172 if (nUpLst.m_nMain < 0) //don't take the wrong one, if the value
1173 //just changed from negative to positive.
1174 { pUpLst = pUpFrame;
1175 nUpLst = nUp;
1176 }
1177 }
1178 } while (pUpFrame && ((bNegAllowed && nUp.m_nMain < 0) || (nUp <= nUpLst)));
1179
1180 const SwContentFrame *pDownLst;
1181 const SwContentFrame *pDownFrame = pCnt;
1182 SwDistance nDownLst;
1183 if (nDown.m_nMain < 0)
1184 nDown.m_nMain = LONG_MAX;
1185 do
1186 {
1187 pDownLst = pDownFrame; nDownLst = nDown;
1188 pDownFrame = pDownLst->GetNextContentFrame();
1189 while ( pDownFrame &&
1190 (bBody != pDownFrame->IsInDocBody() || bFootnote != pDownFrame->IsInFootnote()))
1191 pDownFrame = pDownFrame->GetNextContentFrame();
1192 if ( pDownFrame )
1193 {
1194 ::lcl_CalcDownDist( nDown, aNew, pDownFrame );
1195 if (nDown.m_nMain < 0)
1196 nDown.m_nMain = LONG_MAX;
1197 //It makes sense to search further, if the distance grows inside
1198 //a table.
1199 if ( pDownLst->IsInTab() && pDownFrame->IsInTab() )
1200 {
1201 while (pDownFrame
1202 && ((nDown.m_nMain != LONG_MAX && pDownFrame->IsInTab())
1203 || bBody != pDownFrame->IsInDocBody()))
1204 {
1205 pDownFrame = pDownFrame->GetNextContentFrame();
1206 if ( pDownFrame )
1207 ::lcl_CalcDownDist( nDown, aNew, pDownFrame );
1208 if (nDown.m_nMain < 0)
1209 nDown.m_nMain = LONG_MAX;
1210 }
1211 }
1212 }
1213 if ( !pDownFrame )
1214 nDown.m_nMain = LONG_MAX;
1215
1216 } while (pDownFrame && nDown <= nDownLst && nDown.m_nMain != LONG_MAX
1217 && nDownLst.m_nMain != LONG_MAX);
1218
1219 //If we couldn't find one in both directions, we'll search the Content whose
1220 //left upper corner is the nearest to the point. Such a situation may
1221 //happen, if the point doesn't lay in the text flow but in any margin.
1222 if (nDownLst.m_nMain == LONG_MAX && nUpLst.m_nMain == LONG_MAX)
1223 {
1224 // If an OLE objects, which is contained in a fly frame
1225 // is resized in inplace mode and the new Position is outside the
1226 // fly frame, we do not want to leave our fly frame.
1227 if ( pCnt->IsInFly() )
1228 return pCnt;
1229
1230 return ::lcl_FindCnt( aNew, pCnt, bBody, bFootnote );
1231 }
1232 else
1233 return nDownLst < nUpLst ? pDownLst : pUpLst;
1234}
1235
1236void SwFlyAtContentFrame::SetAbsPos( const Point &rNew )
1237{
1238 SwPageFrame *pOldPage = FindPageFrame();
1239 const SwRect aOld( GetObjRectWithSpaces() );
1240 Point aNew( rNew );
1241
1243 aNew.setX(aNew.getX() + getFrameArea().Width());
1244 SwContentFrame *pCnt = const_cast<SwContentFrame*>(::FindAnchor( GetAnchorFrame(), aNew ));
1245 if( pCnt->IsProtected() )
1246 pCnt = const_cast<SwContentFrame*>(static_cast<const SwContentFrame*>(GetAnchorFrame()));
1247
1248 SwPageFrame *pTmpPage = nullptr;
1249 const bool bVert = pCnt->IsVertical();
1250
1251 const bool bVertL2R = pCnt->IsVertLR();
1252 const bool bRTL = pCnt->IsRightToLeft();
1253
1254 if( ( !bVert != !GetAnchorFrame()->IsVertical() ) ||
1255 ( !bRTL != !GetAnchorFrame()->IsRightToLeft() ) )
1256 {
1257 if( bVert || bRTL )
1258 aNew.setX(aNew.getX() + getFrameArea().Width());
1259 else
1260 aNew.setX(aNew.getX() - getFrameArea().Width());
1261 }
1262
1263 if ( pCnt->IsInDocBody() )
1264 {
1265 //#38848 drag from page margin into the body.
1266 pTmpPage = pCnt->FindPageFrame();
1267 ::lcl_PointToPrt( aNew, pTmpPage->GetUpper() );
1268 SwRect aTmp( aNew, Size( 0, 0 ) );
1269 pTmpPage = const_cast<SwPageFrame*>(static_cast<const SwPageFrame*>(::FindPage( aTmp, pTmpPage )));
1270 ::lcl_PointToPrt( aNew, pTmpPage );
1271 }
1272
1273 //Setup RelPos, only invalidate if requested.
1274 //rNew is an absolute position. We need to calculate the distance from rNew
1275 //to the anchor inside the text flow to correctly set RelPos.
1277 const SwFrame *pFrame = nullptr;
1278 SwTwips nY;
1279 if ( pCnt->getFrameArea().Contains( aNew ) )
1280 {
1281 // #i70582#
1282 if ( bVert )
1283 {
1284 nY = pCnt->getFrameArea().Left() - rNew.X();
1285 if ( bVertL2R )
1286 nY = -nY;
1287 else
1288 nY += pCnt->getFrameArea().Width() - getFrameArea().Width();
1289 nY -= pCnt->GetUpperSpaceAmountConsideredForPrevFrameAndPageGrid();
1290 }
1291 else
1292 nY = rNew.Y() - pCnt->getFrameArea().Top() - pCnt->GetUpperSpaceAmountConsideredForPrevFrameAndPageGrid();
1293 }
1294 else
1295 {
1296 SwDistance aDist;
1297 pFrame = ::lcl_CalcDownDist( aDist, aNew, pCnt );
1298 nY = aDist.m_nMain + aDist.m_nSub;
1299 }
1300
1301 SwTwips nX = 0;
1302
1303 if ( pCnt->IsFollow() )
1304 {
1305 // Flys are never attached to the follow but always to the master,
1306 // which we're going to search now.
1307 const SwContentFrame *pOriginal = pCnt;
1308 const SwContentFrame *pFollow = pCnt;
1309 while ( pCnt->IsFollow() )
1310 {
1311 do
1312 {
1313 SwContentFrame* pPrev = pCnt->GetPrevContentFrame();
1314 if (!pPrev)
1315 {
1316 SAL_WARN("sw.core", "very unexpected missing PrevContentFrame");
1317 break;
1318 }
1319 pCnt = pPrev;
1320 }
1321 while ( pCnt->GetFollow() != pFollow );
1322 pFollow = pCnt;
1323 }
1324 SwTwips nDiff = 0;
1325 do
1326 { const SwFrame *pUp = pFollow->GetUpper();
1327 if( pUp->IsVertical() )
1328 {
1329 if ( pUp->IsVertLR() )
1330 nDiff += pUp->getFramePrintArea().Width() - pFollow->GetRelPos().getX();
1331 else
1332 nDiff += pFollow->getFrameArea().Left() + pFollow->getFrameArea().Width()
1333 - pUp->getFrameArea().Left() - pUp->getFramePrintArea().Left();
1334 }
1335 else
1336 nDiff += pUp->getFramePrintArea().Height() - pFollow->GetRelPos().Y();
1337 pFollow = pFollow->GetFollow();
1338 } while ( pFollow != pOriginal );
1339 nY += nDiff;
1340 if( bVert )
1341 nX = pCnt->getFrameArea().Top() - pOriginal->getFrameArea().Top();
1342 else
1343 nX = pCnt->getFrameArea().Left() - pOriginal->getFrameArea().Left();
1344 }
1345
1346 if ( nY == LONG_MAX )
1347 {
1348 // #i70582#
1349 const SwTwips nTopForObjPos = lcl_GetTopForObjPos(pCnt, bVert, bVertL2R);
1350 if( bVert )
1351 {
1352 if ( bVertL2R )
1353 nY = rNew.X() - nTopForObjPos;
1354 else
1355 nY = nTopForObjPos - rNew.X();
1356 }
1357 else
1358 {
1359 nY = rNew.Y() - nTopForObjPos;
1360 }
1361 }
1362
1363 SwFlyFrameFormat *pFormat = GetFormat();
1364
1365 if( bVert )
1366 {
1367 if( !pFrame )
1368 nX += rNew.Y() - pCnt->getFrameArea().Top();
1369 else
1370 nX = rNew.Y() - pFrame->getFrameArea().Top();
1371 }
1372 else
1373 {
1374 if( !pFrame )
1375 {
1376 if ( pCnt->IsRightToLeft() )
1377 nX += pCnt->getFrameArea().Right() - rNew.X() - getFrameArea().Width();
1378 else
1379 nX += rNew.X() - pCnt->getFrameArea().Left();
1380 }
1381 else
1382 {
1383 if ( pFrame->IsRightToLeft() )
1384 nX += pFrame->getFrameArea().Right() - rNew.X() - getFrameArea().Width();
1385 else
1386 nX = rNew.X() - pFrame->getFrameArea().Left();
1387 }
1388 }
1389 GetFormat()->GetDoc()->GetIDocumentUndoRedo().StartUndo( SwUndoId::START, nullptr );
1390
1391 if( pCnt != GetAnchorFrame() || ( IsAutoPos() && pCnt->IsTextFrame() &&
1392 GetFormat()->getIDocumentSettingAccess().get(DocumentSettingId::HTML_MODE)) )
1393 {
1394 //Set the anchor attribute according to the new Cnt.
1395 SwFormatAnchor aAnch( pFormat->GetAnchor() );
1396 SwPosition pos = *aAnch.GetContentAnchor();
1397 if( IsAutoPos() && pCnt->IsTextFrame() )
1398 {
1399 SwTextFrame const*const pTextFrame(static_cast<SwTextFrame const*>(pCnt));
1401 Point aPt( rNew );
1402 if( pCnt->GetModelPositionForViewPoint( &pos, aPt, &eTmpState )
1403 && FrameContainsNode(*pTextFrame, pos.GetNodeIndex()))
1404 {
1405 const SwTextAttr *const pTextInputField =
1406 pos.GetNode().GetTextNode()->GetTextAttrAt(
1408 if (pTextInputField != nullptr)
1409 {
1410 pos.SetContent( pTextInputField->GetStart() );
1411 }
1413 if( text::RelOrientation::CHAR == pFormat->GetVertOrient().GetRelationOrient() )
1414 nY = LONG_MAX;
1415 if( text::RelOrientation::CHAR == pFormat->GetHoriOrient().GetRelationOrient() )
1416 nX = LONG_MAX;
1417 }
1418 else
1419 {
1420 pos = pTextFrame->MapViewToModelPos(TextFrameIndex(0));
1421 }
1422 }
1423 else if (pCnt->IsTextFrame())
1424 {
1425 pos = static_cast<SwTextFrame const*>(pCnt)->MapViewToModelPos(TextFrameIndex(0));
1426 }
1427 else // is that even possible? maybe if there was a change of anchor type from AT_FLY or something?
1428 {
1429 assert(pCnt->IsNoTextFrame());
1430 pos.Assign(*static_cast<SwNoTextFrame*>(pCnt)->GetNode());
1431 }
1432 aAnch.SetAnchor( &pos );
1433
1434 // handle change of anchor node:
1435 // if count of the anchor frame also change, the fly frames have to be
1436 // re-created. Thus, delete all fly frames except the <this> before the
1437 // anchor attribute is change and re-create them afterwards.
1438 {
1439 SwHandleAnchorNodeChg aHandleAnchorNodeChg( *pFormat, aAnch, this );
1440 pFormat->GetDoc()->SetAttr( aAnch, *pFormat );
1441 }
1442 }
1443 else if ( pTmpPage && pTmpPage != GetPageFrame() )
1444 GetPageFrame()->MoveFly( this, pTmpPage );
1445
1446 const Point aRelPos = bVert ? Point( -nY, nX ) : Point( nX, nY );
1447 ChgRelPos( aRelPos );
1448 GetFormat()->GetDoc()->GetIDocumentUndoRedo().EndUndo( SwUndoId::END, nullptr );
1449
1450 if ( pOldPage != FindPageFrame() )
1452}
1453
1461{
1462 SwPageFrame* pPageFrame( nullptr );
1463 if ( GetVertPosOrientFrame() )
1464 {
1465 pPageFrame = const_cast<SwPageFrame*>(GetVertPosOrientFrame()->FindPageFrame());
1466 }
1467 if ( pPageFrame && GetPageFrame() != pPageFrame )
1468 {
1469 RegisterAtPage(*pPageFrame);
1470 }
1471}
1472
1474{
1475 assert(GetPageFrame() != &rPageFrame);
1476 if (GetPageFrame())
1477 {
1478 GetPageFrame()->MoveFly( this, &rPageFrame );
1479 }
1480 else
1481 {
1482 rPageFrame.AppendFlyToPage( this );
1483 }
1484}
1485
1486// #i26791#
1488{
1489 // if fly frame position is valid, nothing is to do. Thus, return
1491 {
1492 return;
1493 }
1494
1495 // #i26791# - validate position flag here.
1497
1498 // #i35911# - no calculation of new position, if
1499 // anchored object is marked that it clears its environment and its
1500 // environment is already cleared.
1501 // before checking for cleared environment
1502 // check, if member <mpVertPosOrientFrame> is set.
1503 if ( GetVertPosOrientFrame() &&
1505 {
1506 return;
1507 }
1508
1509 // use new class to position object
1511 aObjPositioning( *GetVirtDrawObj() );
1512 aObjPositioning.CalcPosition();
1513
1514 SetVertPosOrientFrame ( aObjPositioning.GetVertPosOrientFrame() );
1515}
1516
1517// #i28701#
1519{
1520 bool bAllowed( SwFlyFreeFrame::InvalidationAllowed( _nInvalid ) );
1521
1522 // forbiddance of base instance can't be over ruled.
1523 if ( bAllowed )
1524 {
1525 if ( _nInvalid == INVALID_POS ||
1526 _nInvalid == INVALID_ALL )
1527 {
1528 bAllowed = InvalidationOfPosAllowed();
1529 }
1530 }
1531
1532 return bAllowed;
1533}
1534
1535bool SwFlyAtContentFrame::ShouldBwdMoved(SwLayoutFrame* /*pNewUpper*/, bool& /*rReformat*/)
1536{
1537 return false;
1538}
1539
1541{
1542 return static_cast<const SwFlyAtContentFrame*>(SwFlowFrame::GetFollow());
1543}
1544
1546{
1547 return static_cast<SwFlyAtContentFrame*>(SwFlowFrame::GetFollow());
1548}
1549
1551{
1552 auto pFly = dynamic_cast<SwFlyAtContentFrame*>(FindFlyFrame());
1553 assert(pFly && "GetNextFlyLeaf: missing fly frame");
1554 assert(pFly->IsFlySplitAllowed() && "GetNextFlyLeaf: fly split not allowed");
1555
1556 SwTextFrame* pFlyAnchor = pFly->FindAnchorCharFrame();
1557 bool bBody = pFlyAnchor && pFlyAnchor->IsInDocBody();
1558 SwLayoutFrame *pLayLeaf = nullptr;
1559 // Look up the first candidate.
1560 if (IsTabFrame())
1561 {
1562 // If we're in a table, try to find the next frame of the table's last content.
1563 SwFrame* pContent = static_cast<SwTabFrame*>(this)->FindLastContentOrTable();
1564 pLayLeaf = pContent ? pContent->GetUpper() : nullptr;
1565 }
1566 else
1567 {
1568 pLayLeaf = GetNextLayoutLeaf();
1569 }
1570
1571 SwLayoutFrame* pOldLayLeaf = nullptr;
1572 while (true)
1573 {
1574 if (pLayLeaf)
1575 {
1576 // If we're anchored in a body frame, the candidate has to be in a body frame as well.
1577 bool bLeftBody = bBody && !pLayLeaf->IsInDocBody();
1578 // If the candidate is in a fly, make sure that the candidate is a child of our follow.
1579 bool bLeftFly = pLayLeaf->IsInFly() && pLayLeaf->FindFlyFrame() != pFly->GetFollow();
1580 if (bLeftBody || bLeftFly)
1581 {
1582 // The above conditions are not held, reject.
1583 pOldLayLeaf = pLayLeaf;
1584 pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
1585 continue;
1586 }
1587 }
1588 else
1589 {
1590 // No candidate: insert a page and try again.
1591 if (eMakePage == MAKEPAGE_INSERT)
1592 {
1593 InsertPage(FindPageFrame(), false);
1594 // If we already had a candidate, continue trying with that instead of starting from
1595 // scratch.
1596 pLayLeaf = pOldLayLeaf ? pOldLayLeaf : GetNextLayoutLeaf();
1597 continue;
1598 }
1599 }
1600 break;
1601 }
1602
1603 if( pLayLeaf )
1604 {
1605 SwFlyAtContentFrame* pNew = nullptr;
1606 // Find the anchor frame to split.
1607 if (pFlyAnchor)
1608 {
1609 // Split the anchor at char 0: all the content goes to the follow of the anchor.
1610 pFlyAnchor->SplitFrame(TextFrameIndex(0));
1611 auto pNext = static_cast<SwTextFrame*>(pFlyAnchor->GetNext());
1612 pNext->MoveSubTree(pLayLeaf);
1613
1614 // Now create the follow of the fly and anchor it in the master of the anchor.
1615 pNew = new SwFlyAtContentFrame(*pFly);
1616 while (pFlyAnchor->IsFollow())
1617 {
1618 pFlyAnchor = pFlyAnchor->FindMaster();
1619 }
1620 pFlyAnchor->AppendFly(pNew);
1621 }
1622 pLayLeaf = pNew;
1623 }
1624 return pLayLeaf;
1625}
1626
1628{
1629 return static_cast<const SwFlyAtContentFrame*>(SwFlowFrame::GetPrecede());
1630}
1631
1633{
1634 return static_cast<SwFlyAtContentFrame*>(SwFlowFrame::GetPrecede());
1635}
1636
1638{
1639 auto pFly = dynamic_cast<SwFlyAtContentFrame*>(FindFlyFrame());
1640 assert(pFly && "GetPrevFlyLeaf: missing fly frame");
1641 if (!pFly->IsFlySplitAllowed())
1642 {
1643 return nullptr;
1644 }
1645
1646 return pFly->GetPrecede();
1647}
1648
1649/* 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)
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
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:737
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1225
Definition: doc.hxx:195
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:452
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:152
virtual bool InvalidationAllowed(const InvalidationType _nInvalid) const override
method to determine, if an invalidation is allowed.
Definition: flycnt.cxx:1518
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:329
const SwFlyAtContentFrame * GetPrecede() const
Definition: flycnt.cxx:1627
bool ShouldBwdMoved(SwLayoutFrame *pNewUpper, bool &rReformat) override
Definition: flycnt.cxx:1535
virtual void MakeObjPos() override
method to determine position for the object and set the position at the object
Definition: flycnt.cxx:1487
SwFlyAtContentFrame(SwFlyFrameFormat *, SwFrame *, SwFrame *pAnchor, bool bFollow=false)
Definition: flycnt.cxx:77
void SetAbsPos(const Point &rNew)
Definition: flycnt.cxx:1236
virtual void RegisterAtCorrectPage() override
method to assure that anchored object is registered at the correct page frame
Definition: flycnt.cxx:1460
virtual void SwClientNotify(const SwModify &, const SfxHint &) override
Definition: flycnt.cxx:99
const SwFlyAtContentFrame * GetFollow() const
Definition: flycnt.cxx:1540
virtual bool IsFormatPossible() const override
method to determine, if a format on the Writer fly frame is possible
Definition: flycnt.cxx:589
virtual void RegisterAtPage(SwPageFrame &) override
Definition: flycnt.cxx:1473
general base class for all free-flowing frames
Definition: flyfrm.hxx:79
const SwVirtFlyDrawObj * GetVirtDrawObj() const
Definition: fly.cxx:2964
virtual const SwFlyFrameFormat * GetFormat() const override
Definition: fly.cxx:3058
static const SwFormatAnchor * GetAnchorFromPoolItem(const SfxPoolItem &rItem)
Definition: fly.cxx:3129
bool IsFlySplitAllowed() const
Is this fly allowed to split across pages? (Disabled by default.)
Definition: fly.cxx:655
void SetNotifyBack()
Definition: flyfrm.hxx:228
bool IsLowerOf(const SwLayoutFrame *pUpper) const
Definition: fly.cxx:2331
virtual const SwFlyFrame * DynCastFlyFrame() const override
Definition: fly.cxx:3142
virtual SwFrameFormat & GetFrameFormat() override
Definition: fly.cxx:2983
virtual void SwClientNotify(const SwModify &rMod, const SfxHint &rHint) override
Definition: fly.cxx:737
bool IsLocked() const
Definition: flyfrm.hxx:216
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:367
bool IsClipped() const
Definition: flyfrm.hxx:231
bool IsAutoPos() const
Definition: flyfrm.hxx:217
void ChgRelPos(const Point &rAbsPos)
Change the relative position.
Definition: fly.cxx:1203
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:1586
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:67
const SwPosition * GetContentAnchor() const
Definition: fmtanchr.hxx:74
SwNode * GetAnchorNode() const
Definition: atrfrm.cxx:1606
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:62
SdrObject * FindRealSdrObject()
Definition: atrfrm.cxx:2795
Base class of the Writer layout elements.
Definition: frame.hxx:315
virtual void Cut()=0
bool IsCellFrame() const
Definition: frame.hxx:1232
bool IsFootnoteContFrame() const
Definition: frame.hxx:1204
void RemoveFly(SwFlyFrame *pToRemove)
Definition: fly.cxx:2368
bool IsTextFrame() const
Definition: frame.hxx:1240
SwTextFrame * DynCastTextFrame()
Definition: findfrm.cxx:1914
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
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:1956
SwLayoutFrame * GetNextFlyLeaf(MakePageType eMakePage)
Definition: flycnt.cxx:1550
void InvalidatePos_()
Definition: frame.hxx:793
bool IsInFootnote() const
Definition: frame.hxx:955
SwPageFrame * InsertPage(SwPageFrame *pSibling, bool bFootnote)
Definition: pagechg.cxx:1366
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:1637
bool IsRightToLeft() const
Definition: frame.hxx:993
bool IsInFly() const
Definition: frame.hxx:967
void AppendFly(SwFlyFrame *pNew)
Definition: fly.cxx:2350
const SwRowFrame * IsInFollowFlowRow() const
Definition: findfrm.cxx:1861
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
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:842
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:620
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:232
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:71
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:312
static bool FrameMovedFwdByObjPos(const SwDoc &_rDoc, const SwTextFrame &_rTextFrame, sal_uInt32 &_ornToPageNum)
Definition: layouter.cxx:342
static void RemoveMovedFwdFrame(const SwDoc &_rDoc, const SwTextFrame &_rTextFrame)
Definition: layouter.cxx:332
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:59
void AppendFlyToPage(SwFlyFrame *pNew)
Definition: flylay.cxx:801
void MoveFly(SwFlyFrame *pToMove, SwPageFrame *pDest)
Definition: flylay.cxx:963
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
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:166
SwPosition MapViewToModelPos(TextFrameIndex nIndex) const
Definition: txtfrm.cxx:1246
SwTextNode * GetTextNodeFirst()
Definition: txtfrm.hxx:467
void SplitFrame(TextFrameIndex nTextPos)
Methods to manage the FollowFrame.
Definition: frmform.cxx:718
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:1083
static void lcl_PointToPrt(Point &rPoint, const SwFrame *pFrame)
Definition: flycnt.cxx:1063
static const SwFrame * lcl_CalcDownDist(SwDistance &rRet, const Point &rPt, const SwContentFrame *pCnt)
Definition: flycnt.cxx:621
static sal_uInt64 lcl_FindCntDiff(const Point &rPt, const SwLayoutFrame *pLay, const SwContentFrame *&rpCnt, const bool bBody, const bool bFootnote)
Definition: flycnt.cxx:920
static const SwContentFrame * lcl_FindCnt(const Point &rPt, const SwContentFrame *pCnt, const bool bBody, const bool bFootnote)
Definition: flycnt.cxx:980
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:1020
Marks a position in the document model.
Definition: pam.hxx:37
tools::Long SwTwips
Definition: swtypes.hxx:51
#define SAL_MAX_UINT64
constexpr OUStringLiteral UNO_NAME_FRAME_ISAUTOMATIC_HEIGHT
Definition: unoprnms.hxx:632
size_t pos
bool operator<(const wwFont &r1, const wwFont &r2)
Definition: wrtw8sty.cxx:885