1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <svx/svdobj.hxx>
21 #include <comphelper/lok.hxx>
25 #include <pagefrm.hxx>
26 #include <rootfrm.hxx>
29 #include <frmtool.hxx>
30 #include <swtable.hxx>
31 #include <viewimp.hxx>
36 #include <sectfrm.hxx>
37 #include <fmtpdsc.hxx>
38 #include <fmtsrnd.hxx>
39 #include <fmtcntnt.hxx>
40 #include <fmtfsize.hxx>
42 #include <flyfrms.hxx>
45 #include <pagedesc.hxx>
46 #include <fmtanchr.hxx>
47 #include <environmentofanchoredobject.hxx>
49 #include <dflyobj.hxx>
50 #include <dcontact.hxx>
51 #include <UndoInsert.hxx>
53 using namespace com::sun::star
;
58 * This mutex is only used for the paste listeners, where the solar mutex can't
61 osl::Mutex
& GetPasteMutex()
63 static osl::Mutex aMutex
;
68 void SwFEShell::EndAllActionAndCall()
70 for(SwViewShell
& rCurrentShell
: GetRingContainer())
72 if( dynamic_cast<const SwCursorShell
*>( &rCurrentShell
) != nullptr )
74 static_cast<SwFEShell
*>(&rCurrentShell
)->EndAction();
75 static_cast<SwFEShell
*>(&rCurrentShell
)->CallChgLnk();
78 rCurrentShell
.EndAction();
82 // Determine the Content's nearest to the point
83 Point
SwFEShell::GetContentPos( const Point
& rPoint
, bool bNext
) const
85 CurrShell
aCurr( const_cast<SwFEShell
*>(this) );
86 return GetLayout()->GetNextPrevContentPos( rPoint
, bNext
);
89 const SwRect
& SwFEShell::GetAnyCurRect( CurRectType eType
, const Point
* pPt
,
90 const uno::Reference
< embed::XEmbeddedObject
>& xObj
) const
92 const SwFrame
*pFrame
= Imp()->HasDrawView()
93 ? ::GetFlyFromMarked( &Imp()->GetDrawView()->GetMarkedObjectList(),
94 const_cast<SwFEShell
*>(this))
101 SwPosition
aPos( *GetCursor()->GetPoint() );
103 GetLayout()->GetModelPositionForViewPoint( &aPos
, aPt
);
104 SwContentNode
*pNd
= aPos
.nNode
.GetNode().GetContentNode();
105 std::pair
<Point
, bool> const tmp(*pPt
, true);
106 pFrame
= pNd
->getLayoutFrame(GetLayout(), nullptr, &tmp
);
110 const bool bOldCallbackActionEnabled
= GetLayout()->IsCallbackActionEnabled();
111 if( bOldCallbackActionEnabled
)
112 GetLayout()->SetCallbackActionEnabled( false );
113 pFrame
= GetCurrFrame();
114 if( bOldCallbackActionEnabled
)
115 GetLayout()->SetCallbackActionEnabled( true );
120 return GetLayout()->getFrameArea();
125 case CurRectType::PagePrt
: bFrame
= false;
127 case CurRectType::Page
: pFrame
= pFrame
->FindPageFrame();
130 case CurRectType::PageCalc
:
132 DisableCallbackAction
a(const_cast<SwRootFrame
&>(*pFrame
->getRootFrame()));
133 pFrame
->Calc(Imp()->GetShell()->GetOut());
134 pFrame
= pFrame
->FindPageFrame();
135 pFrame
->Calc(Imp()->GetShell()->GetOut());
139 case CurRectType::FlyEmbeddedPrt
:
142 case CurRectType::FlyEmbedded
:
144 const SwFrame
*pFlyFrame
= xObj
.is() ? FindFlyFrame(xObj
) : nullptr;
145 pFrame
= pFlyFrame
? pFlyFrame
146 : pFrame
->IsFlyFrame()
148 : pFrame
->FindFlyFrame();
151 case CurRectType::SectionOutsideTable
:
152 if( pFrame
->IsInTab() )
153 pFrame
= pFrame
->FindTabFrame();
155 OSL_FAIL( "Missing Table" );
158 case CurRectType::SectionPrt
:
159 case CurRectType::Section
:
160 if( pFrame
->IsInSct() )
161 pFrame
= pFrame
->FindSctFrame();
163 OSL_FAIL( "Missing section" );
166 if( CurRectType::SectionPrt
== eType
)
170 case CurRectType::HeaderFooter
:
171 pFrame
= pFrame
->FindFooterOrHeader();
172 if( nullptr == pFrame
)
173 return GetLayout()->getFrameArea();
176 case CurRectType::PagesArea
:
177 return GetLayout()->GetPagesArea();
181 return bFrame
? pFrame
->getFrameArea() : pFrame
->getFramePrintArea();
184 sal_uInt16
SwFEShell::GetPageNumber( const Point
&rPoint
) const
186 const SwFrame
*pPage
= GetLayout()->Lower();
187 while ( pPage
&& !pPage
->getFrameArea().IsInside( rPoint
) )
188 pPage
= pPage
->GetNext();
190 return static_cast<const SwPageFrame
*>(pPage
)->GetPhyPageNum();
195 bool SwFEShell::GetPageNumber( tools::Long nYPos
, bool bAtCursorPos
, sal_uInt16
& rPhyNum
, sal_uInt16
& rVirtNum
, OUString
&rDisplay
) const
197 const SwFrame
*pPage
;
199 if ( bAtCursorPos
) // get page of Cursor
201 pPage
= GetCurrFrame( false );
203 pPage
= pPage
->FindPageFrame();
205 else if ( nYPos
> -1 ) // determine page via the position
207 pPage
= GetLayout()->Lower();
208 while( pPage
&& (pPage
->getFrameArea().Bottom() < nYPos
||
209 nYPos
< pPage
->getFrameArea().Top() ) )
210 pPage
= pPage
->GetNext();
212 else // first visible page
214 pPage
= Imp()->GetFirstVisPage(GetOut());
215 if ( pPage
&& static_cast<const SwPageFrame
*>(pPage
)->IsEmptyPage() )
216 pPage
= pPage
->GetNext();
221 rPhyNum
= static_cast<const SwPageFrame
*>(pPage
)->GetPhyPageNum();
222 rVirtNum
= static_cast<const SwPageFrame
*>(pPage
)->GetVirtPageNum();
223 const SvxNumberType
& rNum
= static_cast<const SwPageFrame
*>(pPage
)->GetPageDesc()->GetNumType();
224 rDisplay
= rNum
.GetNumStr( rVirtNum
);
227 return nullptr != pPage
;
230 bool SwFEShell::IsDirectlyInSection() const
232 SwFrame
* pFrame
= GetCurrFrame( false );
233 return pFrame
&& pFrame
->GetUpper() && pFrame
->GetUpper()->IsSctFrame();
236 FrameTypeFlags
SwFEShell::GetFrameType( const Point
*pPt
, bool bStopAtFly
) const
238 FrameTypeFlags nReturn
= FrameTypeFlags::NONE
;
239 const SwFrame
*pFrame
;
242 SwPosition
aPos( *GetCursor()->GetPoint() );
244 GetLayout()->GetModelPositionForViewPoint( &aPos
, aPt
);
245 SwContentNode
*pNd
= aPos
.nNode
.GetNode().GetContentNode();
246 std::pair
<Point
, bool> const tmp(*pPt
, true);
247 pFrame
= pNd
->getLayoutFrame(GetLayout(), nullptr, &tmp
);
250 pFrame
= GetCurrFrame( false );
253 switch ( pFrame
->GetType() )
255 case SwFrameType::Column
:
256 if( pFrame
->GetUpper()->IsSctFrame() )
258 // Check, if isn't not only a single column
259 // from a section with footnotes at the end.
260 if( pFrame
->GetNext() || pFrame
->GetPrev() )
262 nReturn
|= ( nReturn
& FrameTypeFlags::TABLE
) ?
263 FrameTypeFlags::COLSECTOUTTAB
: FrameTypeFlags::COLSECT
;
265 else // only pages and frame columns
266 nReturn
|= FrameTypeFlags::COLUMN
;
268 case SwFrameType::Page
:
269 nReturn
|= FrameTypeFlags::PAGE
;
270 if( static_cast<const SwPageFrame
*>(pFrame
)->IsFootnotePage() )
271 nReturn
|= FrameTypeFlags::FTNPAGE
;
273 case SwFrameType::Header
: nReturn
|= FrameTypeFlags::HEADER
; break;
274 case SwFrameType::Footer
: nReturn
|= FrameTypeFlags::FOOTER
; break;
275 case SwFrameType::Body
:
276 if( pFrame
->GetUpper()->IsPageFrame() ) // not for ColumnFrames
277 nReturn
|= FrameTypeFlags::BODY
;
279 case SwFrameType::Ftn
: nReturn
|= FrameTypeFlags::FOOTNOTE
; break;
280 case SwFrameType::Fly
:
281 if( static_cast<const SwFlyFrame
*>(pFrame
)->IsFlyLayFrame() )
282 nReturn
|= FrameTypeFlags::FLY_FREE
;
283 else if ( static_cast<const SwFlyFrame
*>(pFrame
)->IsFlyAtContentFrame() )
284 nReturn
|= FrameTypeFlags::FLY_ATCNT
;
287 OSL_ENSURE( static_cast<const SwFlyFrame
*>(pFrame
)->IsFlyInContentFrame(),
289 nReturn
|= FrameTypeFlags::FLY_INCNT
;
291 nReturn
|= FrameTypeFlags::FLY_ANY
;
295 case SwFrameType::Tab
:
296 case SwFrameType::Row
:
297 case SwFrameType::Cell
: nReturn
|= FrameTypeFlags::TABLE
; break;
298 default: /* do nothing */ break;
300 if ( pFrame
->IsFlyFrame() )
301 pFrame
= static_cast<const SwFlyFrame
*>(pFrame
)->GetAnchorFrame();
303 pFrame
= pFrame
->GetUpper();
308 void SwFEShell::ShellGetFocus()
311 SwCursorShell::ShellGetFocus();
315 if (!comphelper::LibreOfficeKit::isActive())
316 Imp()->GetDrawView()->showMarkHandles();
317 if ( Imp()->GetDrawView()->AreObjectsMarked() )
318 FrameNotify( this, FLY_DRAG_START
);
322 void SwFEShell::ShellLoseFocus()
324 SwCursorShell::ShellLoseFocus();
326 if ( HasDrawView() && Imp()->GetDrawView()->AreObjectsMarked() )
328 if (!comphelper::LibreOfficeKit::isActive())
329 Imp()->GetDrawView()->hideMarkHandles();
330 FrameNotify( this, FLY_DRAG_END
);
334 sal_uInt16
SwFEShell::GetPhyPageNum() const
336 SwFrame
*pFrame
= GetCurrFrame();
338 return pFrame
->GetPhyPageNum();
342 sal_uInt16
SwFEShell::GetVirtPageNum() const
344 SwFrame
*pFrame
= GetCurrFrame();
346 return pFrame
->GetVirtPageNum();
350 static void lcl_SetAPageOffset( sal_uInt16 nOffset
, SwPageFrame
* pPage
, SwFEShell
* pThis
)
352 pThis
->StartAllAction();
353 OSL_ENSURE( pPage
->FindFirstBodyContent(),
354 "SwFEShell _SetAPageOffset() without ContentFrame" );
356 SwFormatPageDesc
aDesc( pPage
->GetPageDesc() );
357 aDesc
.SetNumOffset( nOffset
);
359 SwFrame
*pFrame
= pThis
->GetCurrFrame( false );
360 if ( pFrame
->IsInTab() )
361 pThis
->GetDoc()->SetAttr( aDesc
, *pFrame
->FindTabFrame()->GetFormat() );
364 pThis
->GetDoc()->getIDocumentContentOperations().InsertPoolItem(
365 *pThis
->GetCursor(), aDesc
, SetAttrMode::DEFAULT
, pThis
->GetLayout());
368 pThis
->EndAllAction();
371 void SwFEShell::SetNewPageOffset( sal_uInt16 nOffset
)
373 GetLayout()->SetVirtPageNum( true );
374 const SwPageFrame
*pPage
= GetCurrFrame( false )->FindPageFrame();
375 lcl_SetAPageOffset( nOffset
, const_cast<SwPageFrame
*>(pPage
), this );
378 void SwFEShell::SetPageOffset( sal_uInt16 nOffset
)
380 const SwPageFrame
*pPage
= GetCurrFrame( false )->FindPageFrame();
381 const SwRootFrame
* pDocLayout
= GetLayout();
384 const SwFrame
*pFlow
= pPage
->FindFirstBodyContent();
387 if ( pFlow
->IsInTab() )
388 pFlow
= pFlow
->FindTabFrame();
389 const SwFormatPageDesc
& rPgDesc
= pFlow
->GetPageDescItem();
390 if ( rPgDesc
.GetNumOffset() )
392 pDocLayout
->SetVirtPageNum( true );
393 lcl_SetAPageOffset( nOffset
, const_cast<SwPageFrame
*>(pPage
), this );
397 pPage
= static_cast<const SwPageFrame
*>(pPage
->GetPrev());
401 sal_uInt16
SwFEShell::GetPageOffset() const
403 const SwPageFrame
*pPage
= GetCurrFrame()->FindPageFrame();
406 const SwFrame
*pFlow
= pPage
->FindFirstBodyContent();
409 if ( pFlow
->IsInTab() )
410 pFlow
= pFlow
->FindTabFrame();
411 ::std::optional
<sal_uInt16
> oNumOffset
= pFlow
->GetPageDescItem().GetNumOffset();
415 pPage
= static_cast<const SwPageFrame
*>(pPage
->GetPrev());
420 void SwFEShell::InsertLabel( const SwLabelType eType
, const OUString
&rText
, const OUString
& rSeparator
,
421 const OUString
& rNumberSeparator
,
422 const bool bBefore
, const sal_uInt16 nId
,
423 const OUString
& rCharacterStyle
,
426 // get node index of cursor position, SwDoc can do everything else itself
427 SwContentFrame
*pCnt
= SwLabelType::Draw
==eType
? nullptr : GetCurrFrame( false );
428 if( SwLabelType::Draw
!=eType
&& !pCnt
)
432 SwRewriter
aRewriter(SwUndoInsertLabel::CreateRewriter(rText
));
433 StartUndo(SwUndoId::INSERTLABEL
, &aRewriter
);
436 bool bInnerCntIsFly
= false;
437 SwFlyFrameFormat
* pFlyFormat
= nullptr;
440 case SwLabelType::Object
:
441 case SwLabelType::Fly
:
442 bInnerCntIsFly
= pCnt
->IsInFly();
445 // pass down index to the startnode for flys
446 nIdx
= pCnt
->FindFlyFrame()->
447 GetFormat()->GetContent().GetContentIdx()->GetIndex();
450 case SwLabelType::Table
:
451 if( pCnt
->IsInTab() )
453 // pass down index to the TableNode for tables
454 const SwTable
& rTable
= *pCnt
->FindTabFrame()->GetTable();
455 nIdx
= rTable
.GetTabSortBoxes()[ 0 ]
456 ->GetSttNd()->FindTableNode()->GetIndex();
459 case SwLabelType::Draw
:
460 if( Imp()->GetDrawView() )
462 SwDrawView
*pDView
= Imp()->GetDrawView();
463 const SdrMarkList
& rMrkList
= pDView
->GetMarkedObjectList();
465 // copy marked drawing objects to
466 // local list to perform the corresponding action for each object
467 std::vector
<SdrObject
*> aDrawObjs
;
469 for ( size_t i
= 0; i
< rMrkList
.GetMarkCount(); ++i
)
471 SdrObject
* pDrawObj
= rMrkList
.GetMark(i
)->GetMarkedSdrObj();
473 aDrawObjs
.push_back( pDrawObj
);
476 // loop on marked drawing objects
477 while ( !aDrawObjs
.empty() )
479 SdrObject
* pDrawObj
= aDrawObjs
.back();
480 if ( dynamic_cast<const SwVirtFlyDrawObj
*>( pDrawObj
) == nullptr &&
481 dynamic_cast<const SwFlyDrawObj
*>( pDrawObj
) == nullptr )
483 SwFlyFrameFormat
*pFormat
=
484 GetDoc()->InsertDrawLabel( rText
, rSeparator
, rNumberSeparator
, nId
, rCharacterStyle
, *pDrawObj
);
486 pFlyFormat
= pFormat
;
489 aDrawObjs
.pop_back();
495 OSL_ENSURE( false, "Cursor neither in table nor in fly." );
500 pFlyFormat
= GetDoc()->InsertLabel(eType
, rText
, rSeparator
,
501 rNumberSeparator
, bBefore
, nId
,
502 nIdx
, rCharacterStyle
, bCpyBrd
);
507 const Point
aPt(GetCursorDocPos());
508 if (SwFlyFrame
* pFrame
= pFlyFormat
->GetFrame(&aPt
))
509 SelectFlyFrame(*pFrame
);
512 EndAllActionAndCall();
516 bool SwFEShell::Sort(const SwSortOptions
& rOpt
)
518 if( !HasSelection() )
521 CurrShell
aCurr( this );
527 // check if Point/Mark of current Cursor are in one table
528 SwFrame
*pFrame
= GetCurrFrame( false );
529 OSL_ENSURE( pFrame
->FindTabFrame(), "Cursor not in table." );
531 // search boxes via the layout
533 GetTableSel(*this, aBoxes
);
535 // The Cursor should be removed from the deletion area.
536 // Always put them behind/on the table; via the
537 // document position they will always be set to the old position
538 while( !pFrame
->IsCellFrame() )
539 pFrame
= pFrame
->GetUpper();
541 /* ParkCursor->ParkCursorTab */
545 // call sorting on document
546 bRet
= mxDoc
->SortTable(aBoxes
, rOpt
);
550 // Sort text nothing else
551 for(SwPaM
& rPaM
: GetCursor()->GetRingContainer())
555 SwPosition
* pStart
= pPam
->Start();
556 SwPosition
* pEnd
= pPam
->End();
558 SwNodeIndex
aPrevIdx( pStart
->nNode
, -1 );
559 sal_uLong nOffset
= pEnd
->nNode
.GetIndex() - pStart
->nNode
.GetIndex();
560 const sal_Int32 nCntStt
= pStart
->nContent
.GetIndex();
563 bRet
= mxDoc
->SortText(*pPam
, rOpt
);
565 // put selection again
567 pPam
->GetPoint()->nNode
.Assign( aPrevIdx
.GetNode(), +1 );
568 SwContentNode
* pCNd
= pPam
->GetContentNode();
569 sal_Int32 nLen
= pCNd
->Len();
572 pPam
->GetPoint()->nContent
.Assign(pCNd
, nLen
);
575 pPam
->GetPoint()->nNode
+= nOffset
;
576 pCNd
= pPam
->GetContentNode();
577 pPam
->GetPoint()->nContent
.Assign( pCNd
, pCNd
->Len() );
585 bool SwFEShell::IsColRightToLeft() const
587 SwFrame
* pFrame
= GetCurrFrame();
590 pFrame
= pFrame
->GetUpper();
591 if (pFrame
&& pFrame
->IsColumnFrame())
593 return pFrame
->IsRightToLeft();
599 sal_uInt16
SwFEShell::GetCurColNum_( const SwFrame
*pFrame
,
600 SwGetCurColNumPara
* pPara
)
605 pFrame
= pFrame
->GetUpper();
606 if( pFrame
&& pFrame
->IsColumnFrame() )
608 const SwFrame
*pCurFrame
= pFrame
;
611 pFrame
= pFrame
->GetPrev();
616 // now search the format, determining the columness
617 pFrame
= pCurFrame
->GetUpper();
620 if( ( SwFrameType::Page
| SwFrameType::Fly
| SwFrameType::Section
) & pFrame
->GetType() )
622 pPara
->pFrameFormat
= static_cast<const SwLayoutFrame
*>(pFrame
)->GetFormat();
623 pPara
->pPrtRect
= &pFrame
->getFramePrintArea();
626 pFrame
= pFrame
->GetUpper();
630 pPara
->pFrameFormat
= nullptr;
631 pPara
->pPrtRect
= nullptr;
640 sal_uInt16
SwFEShell::GetCurColNum( SwGetCurColNumPara
* pPara
) const
642 OSL_ENSURE( GetCurrFrame(), "Cursor parked?" );
643 return GetCurColNum_( GetCurrFrame(), pPara
);
646 sal_uInt16
SwFEShell::GetCurOutColNum() const
649 SwFrame
* pFrame
= GetCurrFrame();
650 OSL_ENSURE( pFrame
, "Cursor parked?" );
653 pFrame
= pFrame
->IsInTab() ? static_cast<SwFrame
*>(pFrame
->FindTabFrame())
654 : static_cast<SwFrame
*>(pFrame
->FindSctFrame());
655 OSL_ENSURE( pFrame
, "No Tab, no Sect" );
657 nRet
= GetCurColNum_( pFrame
, nullptr );
662 SwFEShell::SwFEShell( SwDoc
& rDoc
, vcl::Window
*pWindow
, const SwViewOption
*pOptions
)
663 : SwEditShell( rDoc
, pWindow
, pOptions
)
664 , m_bCheckForOLEInCaption(false)
665 , m_aPasteListeners(GetPasteMutex())
666 , m_eTableInsertMode(SwTable::SEARCH_NONE
)
667 , m_bTableCopied(false)
671 SwFEShell::SwFEShell( SwEditShell
& rShell
, vcl::Window
*pWindow
)
672 : SwEditShell( rShell
, pWindow
)
673 , m_bCheckForOLEInCaption(false)
674 , m_aPasteListeners(GetPasteMutex())
675 , m_eTableInsertMode(SwTable::SEARCH_NONE
)
676 , m_bTableCopied(false)
680 SwFEShell::~SwFEShell()
684 // #i17567# - adjustments for allowing
685 // negative vertical positions for fly frames anchored to paragraph/to character.
686 // #i22305# - adjustments for option 'Follow text flow'
687 // for to frame anchored objects.
688 // #i22341# - adjustments for vertical alignment at top of line
689 // for to character anchored objects.
690 void SwFEShell::CalcBoundRect( SwRect
& _orRect
,
691 const RndStdIds _nAnchorId
,
692 const sal_Int16 _eHoriRelOrient
,
693 const sal_Int16 _eVertRelOrient
,
694 const SwPosition
* _pToCharContentPos
,
695 const bool _bFollowTextFlow
,
699 const SwFormatFrameSize
* pFormatFrameSize
) const
701 const SwFrame
* pFrame
;
702 const SwFlyFrame
* pFly
;
705 pFrame
= GetCurrFrame();
706 pFly
= pFrame
->FindFlyFrame();
707 if( nullptr != pFly
)
708 pFrame
= pFly
->GetAnchorFrame();
712 pFly
= GetSelectedFlyFrame();
713 pFrame
= pFly
? pFly
->GetAnchorFrame() : GetCurrFrame();
716 bool bWrapThrough
= false;
719 SwFlyFrameFormat
* pFormat
= const_cast<SwFlyFrameFormat
*>(pFly
->GetFormat());
720 const SwFormatSurround
& rSurround
= pFormat
->GetSurround();
721 bWrapThrough
= rSurround
.GetSurround() == css::text::WrapTextMode_THROUGH
;
724 const SwPageFrame
* pPage
= pFrame
->FindPageFrame();
725 _bMirror
= _bMirror
&& !pPage
->OnRightPage();
728 bool bVertic
= false;
730 bool bVerticalL2R
= false;
732 if ((RndStdIds::FLY_AT_PAGE
== _nAnchorId
) || (RndStdIds::FLY_AT_FLY
== _nAnchorId
)) // LAYER_IMPL
734 const SwFrame
* pTmp
= pFrame
;
736 if ((RndStdIds::FLY_AT_PAGE
== _nAnchorId
) ||
737 ((RndStdIds::FLY_AT_FLY
== _nAnchorId
) && !_bFollowTextFlow
))
743 pFrame
= pFrame
->FindFlyFrame();
747 _orRect
= pFrame
->getFrameArea();
748 SwRectFnSet
aRectFnSet(pFrame
);
749 bRTL
= pFrame
->IsRightToLeft();
751 aPos
= pFrame
->getFrameArea().TopRight();
753 aPos
= aRectFnSet
.GetPos(pFrame
->getFrameArea());
755 if( aRectFnSet
.IsVert() || aRectFnSet
.IsVertL2R() )
757 bVertic
= aRectFnSet
.IsVert();
758 bVerticalL2R
= aRectFnSet
.IsVertL2R();
759 _bMirror
= false; // no mirroring in vertical environment
760 switch ( _eHoriRelOrient
)
762 case text::RelOrientation::PAGE_RIGHT
:
763 case text::RelOrientation::FRAME_RIGHT
: aPos
.AdjustY(pFrame
->getFramePrintArea().Height() );
765 case text::RelOrientation::PRINT_AREA
:
766 case text::RelOrientation::PAGE_PRINT_AREA
: aPos
.AdjustY(pFrame
->getFramePrintArea().Top() ); break;
772 switch ( _eHoriRelOrient
)
774 case text::RelOrientation::PRINT_AREA
:
775 case text::RelOrientation::PAGE_PRINT_AREA
: aPos
.AdjustX(pFrame
->getFramePrintArea().Width() );
777 case text::RelOrientation::PAGE_RIGHT
:
778 case text::RelOrientation::FRAME_RIGHT
: aPos
.AdjustX(pFrame
->getFramePrintArea().Left() ); break;
779 default: aPos
.AdjustX(pFrame
->getFrameArea().Width() );
784 switch ( _eHoriRelOrient
)
786 case text::RelOrientation::PRINT_AREA
:
787 case text::RelOrientation::PAGE_PRINT_AREA
: aPos
.AdjustX(pFrame
->getFramePrintArea().Width() );
789 case text::RelOrientation::PAGE_LEFT
:
790 case text::RelOrientation::FRAME_LEFT
: aPos
.AdjustX(pFrame
->getFramePrintArea().Left() -
791 pFrame
->getFrameArea().Width() ); break;
797 switch ( _eHoriRelOrient
)
799 case text::RelOrientation::PAGE_RIGHT
:
800 case text::RelOrientation::FRAME_RIGHT
: aPos
.AdjustX(pFrame
->getFramePrintArea().Width() );
802 case text::RelOrientation::PRINT_AREA
:
803 case text::RelOrientation::PAGE_PRINT_AREA
: aPos
.AdjustX(pFrame
->getFramePrintArea().Left() ); break;
808 if ( aRectFnSet
.IsVert() && !aRectFnSet
.IsVertL2R() )
810 switch ( _eVertRelOrient
)
812 case text::RelOrientation::PRINT_AREA
:
813 case text::RelOrientation::PAGE_PRINT_AREA
:
815 aPos
.AdjustX( -(pFrame
->GetRightMargin()) );
820 else if ( aRectFnSet
.IsVertL2R() )
822 switch ( _eVertRelOrient
)
824 case text::RelOrientation::PRINT_AREA
:
825 case text::RelOrientation::PAGE_PRINT_AREA
:
827 aPos
.AdjustX(pFrame
->GetLeftMargin() );
834 switch ( _eVertRelOrient
)
836 case text::RelOrientation::PRINT_AREA
:
837 case text::RelOrientation::PAGE_PRINT_AREA
:
839 if ( pFrame
->IsPageFrame() )
842 static_cast<const SwPageFrame
*>(pFrame
)->PrtWithoutHeaderAndFooter().Top() );
846 aPos
.AdjustY(pFrame
->getFramePrintArea().Top() );
853 *_opPercent
= pFrame
->getFramePrintArea().SSize();
857 const SwFrame
* pUpper
= ( pFrame
->IsPageFrame() || pFrame
->IsFlyFrame() ) ?
858 pFrame
: pFrame
->GetUpper();
859 SwRectFnSet
aRectFnSet(pUpper
);
862 // If the size is relative from page, then full size should be counted from the page frame.
863 if (pFormatFrameSize
&& pFormatFrameSize
->GetWidthPercentRelation() == text::RelOrientation::PAGE_FRAME
)
864 _opPercent
->setWidth(pPage
->getFrameArea().Width());
866 _opPercent
->setWidth(pUpper
->getFramePrintArea().Width());
868 if (pFormatFrameSize
&& pFormatFrameSize
->GetHeightPercentRelation() == text::RelOrientation::PAGE_FRAME
)
869 // If the size is relative from page, then full size should be counted from the page frame.
870 _opPercent
->setHeight(pPage
->getFrameArea().Height());
872 _opPercent
->setHeight(pUpper
->getFramePrintArea().Height());
875 bRTL
= pFrame
->IsRightToLeft();
877 aPos
= pFrame
->getFrameArea().TopRight();
879 aPos
= aRectFnSet
.GetPos(pFrame
->getFrameArea());
880 // #i17567# - allow negative positions
881 // for fly frames anchor to paragraph/to character.
882 if ((_nAnchorId
== RndStdIds::FLY_AT_PARA
) || (_nAnchorId
== RndStdIds::FLY_AT_CHAR
))
884 // The rectangle, the fly frame can be positioned in, is determined
885 // horizontally by the frame area of the horizontal environment
886 // and vertically by the printing area of the vertical environment,
887 // if the object follows the text flow, or by the frame area of the
888 // vertical environment, if the object doesn't follow the text flow.
889 // new class <SwEnvironmentOfAnchoredObject>
890 objectpositioning::SwEnvironmentOfAnchoredObject
aEnvOfObj(
892 const SwLayoutFrame
& rHoriEnvironLayFrame
=
893 aEnvOfObj
.GetHoriEnvironmentLayoutFrame( *pFrame
);
894 const SwLayoutFrame
& rVertEnvironLayFrame
=
895 aEnvOfObj
.GetVertEnvironmentLayoutFrame( *pFrame
);
896 const SwRect
& aHoriEnvironRect( rHoriEnvironLayFrame
.getFrameArea() );
897 SwRect aVertEnvironRect
;
898 if ( _bFollowTextFlow
)
900 aVertEnvironRect
= rVertEnvironLayFrame
.getFramePrintArea();
901 aVertEnvironRect
.Pos() += rVertEnvironLayFrame
.getFrameArea().Pos();
902 // #i18732# - adjust vertical 'virtual' anchor position
903 // (<aPos.Y()> respectively <aPos.X()>), if object is vertical aligned
905 if ( _eVertRelOrient
== text::RelOrientation::PAGE_FRAME
|| _eVertRelOrient
== text::RelOrientation::PAGE_PRINT_AREA
)
907 if ( aRectFnSet
.IsVert() && !aRectFnSet
.IsVertL2R() )
909 aPos
.setX( aVertEnvironRect
.Right() );
911 else if ( aRectFnSet
.IsVertL2R() )
913 aPos
.setX( aVertEnvironRect
.Left() );
917 aPos
.setY( aVertEnvironRect
.Top() );
923 OSL_ENSURE( rVertEnvironLayFrame
.IsPageFrame(),
924 "<SwFEShell::CalcBoundRect(..)> - not following text flow, but vertical environment *not* page!" );
925 aVertEnvironRect
= rVertEnvironLayFrame
.getFrameArea();
926 // #i18732# - adjustment vertical 'virtual' anchor position
927 // (<aPos.Y()> respectively <aPos.X()>), if object is vertical aligned
929 if (_eVertRelOrient
== text::RelOrientation::PAGE_FRAME
930 || _eVertRelOrient
== text::RelOrientation::PAGE_PRINT_AREA
931 || _eVertRelOrient
== text::RelOrientation::PAGE_PRINT_AREA_BOTTOM
)
933 if ( aRectFnSet
.IsVert() && !aRectFnSet
.IsVertL2R() )
935 aPos
.setX( aVertEnvironRect
.Right() );
936 if ( _eVertRelOrient
== text::RelOrientation::PAGE_PRINT_AREA
)
938 aPos
.setX(aPos
.getX() - rVertEnvironLayFrame
.GetRightMargin());
941 else if ( aRectFnSet
.IsVertL2R() )
943 aPos
.setX( aVertEnvironRect
.Left() );
944 if ( _eVertRelOrient
== text::RelOrientation::PAGE_PRINT_AREA
)
946 aPos
.setX(aPos
.getX() + rVertEnvironLayFrame
.GetLeftMargin());
951 aPos
.setY( aVertEnvironRect
.Top() );
952 if ( _eVertRelOrient
== text::RelOrientation::PAGE_PRINT_AREA
)
954 aPos
.setY(aPos
.getY() + rVertEnvironLayFrame
.GetTopMargin());
955 // add height of page header
956 const SwFrame
* pTmpFrame
= rVertEnvironLayFrame
.Lower();
957 if ( pTmpFrame
->IsHeaderFrame() )
959 aPos
.setY(aPos
.getY() + pTmpFrame
->getFrameArea().Height());
962 else if (_eVertRelOrient
== text::RelOrientation::PAGE_PRINT_AREA_BOTTOM
)
964 if (rVertEnvironLayFrame
.IsPageFrame())
966 auto& rPageFrame
= static_cast<const SwPageFrame
&>(rVertEnvironLayFrame
);
967 aPos
.setY(rPageFrame
.PrtWithoutHeaderAndFooter().Bottom());
971 aPos
.AdjustY(rVertEnvironLayFrame
.getFramePrintArea().Bottom());
978 // #i22341# - adjust vertical 'virtual' anchor position
979 // (<aPos.Y()> respectively <aPos.X()>), if object is anchored to
980 // character and vertical aligned at character or top of line
981 // <pFrame>, which is the anchor frame or the proposed anchor frame,
982 // doesn't have to be a text frame (e.g. edit a to-page anchored
983 // fly frame). Thus, assure this.
984 const SwTextFrame
* pTextFrame( dynamic_cast<const SwTextFrame
*>(pFrame
) );
986 (_nAnchorId
== RndStdIds::FLY_AT_CHAR
) &&
987 ( _eVertRelOrient
== text::RelOrientation::CHAR
||
988 _eVertRelOrient
== text::RelOrientation::TEXT_LINE
) )
991 if ( _eVertRelOrient
== text::RelOrientation::CHAR
)
994 if ( _pToCharContentPos
)
996 pTextFrame
->GetAutoPos( aChRect
, *_pToCharContentPos
);
1000 // No content position provided. Thus, use a default one.
1001 SwPosition
aDefaultContentPos(*(pTextFrame
->GetTextNodeFirst()));
1002 pTextFrame
->GetAutoPos( aChRect
, aDefaultContentPos
);
1004 nTop
= aRectFnSet
.GetBottom(aChRect
);
1008 if ( _pToCharContentPos
)
1010 pTextFrame
->GetTopOfLine( nTop
, *_pToCharContentPos
);
1014 // No content position provided. Thus, use a default one.
1015 SwPosition
aDefaultContentPos(*(pTextFrame
->GetTextNodeFirst()));
1016 pTextFrame
->GetTopOfLine( nTop
, aDefaultContentPos
);
1019 if ( aRectFnSet
.IsVert() || aRectFnSet
.IsVertL2R() )
1029 // #i26945# - adjust horizontal 'virtual' anchor
1030 // position (<aPos.X()> respectively <aPos.Y()>), if object is
1031 // anchored to character and horizontal aligned at character.
1033 (_nAnchorId
== RndStdIds::FLY_AT_CHAR
) &&
1034 _eHoriRelOrient
== text::RelOrientation::CHAR
)
1038 if ( _pToCharContentPos
)
1040 pTextFrame
->GetAutoPos( aChRect
, *_pToCharContentPos
);
1044 // No content position provided. Thus, use a default one.
1045 SwPosition
aDefaultContentPos(*(pTextFrame
->GetTextNodeFirst()));
1046 pTextFrame
->GetAutoPos( aChRect
, aDefaultContentPos
);
1048 nLeft
= aRectFnSet
.GetLeft(aChRect
);
1049 if ( aRectFnSet
.IsVert() || aRectFnSet
.IsVertL2R() )
1058 if ( aRectFnSet
.IsVert() || aRectFnSet
.IsVertL2R() )
1060 _orRect
= SwRect( aVertEnvironRect
.Left(),
1061 aHoriEnvironRect
.Top(),
1062 aVertEnvironRect
.Width(),
1063 aHoriEnvironRect
.Height() );
1067 _orRect
= SwRect( aHoriEnvironRect
.Left(),
1068 aVertEnvironRect
.Top(),
1069 aHoriEnvironRect
.Width(),
1070 aVertEnvironRect
.Height() );
1075 if( _opRef
&& pFly
&& pFly
->IsFlyInContentFrame() )
1076 *_opRef
= static_cast<const SwFlyInContentFrame
*>( pFly
)->GetRefPoint();
1078 _orRect
= pUpper
->getFrameArea();
1079 if( !pUpper
->IsBodyFrame() )
1081 _orRect
+= pUpper
->getFramePrintArea().Pos();
1082 _orRect
.SSize( pUpper
->getFramePrintArea().SSize() );
1083 if ( pUpper
->IsCellFrame() )//MA_FLY_HEIGHT
1085 const SwFrame
* pTab
= pUpper
->FindTabFrame();
1086 tools::Long nBottom
= aRectFnSet
.GetPrtBottom(*pTab
->GetUpper());
1087 aRectFnSet
.SetBottom( _orRect
, nBottom
);
1090 // only use 90% of height for character bound
1092 if( aRectFnSet
.IsVert() || aRectFnSet
.IsVertL2R() )
1093 _orRect
.Width( (_orRect
.Width()*9)/10 );
1095 _orRect
.Height( (_orRect
.Height()*9)/10 );
1099 const SwTwips nBaseOfstForFly
= ( pFrame
->IsTextFrame() && pFly
) ?
1100 static_cast<const SwTextFrame
*>(pFrame
)->GetBaseOffsetForFly( !bWrapThrough
) :
1102 if( aRectFnSet
.IsVert() || aRectFnSet
.IsVertL2R() )
1104 bVertic
= aRectFnSet
.IsVert();
1105 bVerticalL2R
= aRectFnSet
.IsVertL2R();
1108 switch ( _eHoriRelOrient
)
1110 case text::RelOrientation::FRAME_RIGHT
:
1112 aPos
.setY(aPos
.getY() + pFrame
->getFramePrintArea().Height());
1113 aPos
+= aRectFnSet
.GetPos(pFrame
->getFramePrintArea());
1116 case text::RelOrientation::PRINT_AREA
:
1118 aPos
+= aRectFnSet
.GetPos(pFrame
->getFramePrintArea());
1119 aPos
.setY(aPos
.getY() + nBaseOfstForFly
);
1122 case text::RelOrientation::PAGE_RIGHT
:
1124 aPos
.setY(pPage
->getFrameArea().Top() + pPage
->getFramePrintArea().Bottom());
1127 case text::RelOrientation::PAGE_PRINT_AREA
:
1129 aPos
.setY(pPage
->getFrameArea().Top() + pPage
->getFramePrintArea().Top());
1132 case text::RelOrientation::PAGE_LEFT
:
1133 case text::RelOrientation::PAGE_FRAME
:
1135 aPos
.setY(pPage
->getFrameArea().Top());
1138 case text::RelOrientation::FRAME
:
1140 aPos
.setY(aPos
.getY() + nBaseOfstForFly
);
1148 switch ( _eHoriRelOrient
)
1150 case text::RelOrientation::FRAME_RIGHT
: aPos
.setX(aPos
.getX() + pFrame
->getFramePrintArea().Left()); break;
1151 case text::RelOrientation::FRAME
:
1152 case text::RelOrientation::FRAME_LEFT
: aPos
.setX(aPos
.getX() + pFrame
->getFrameArea().Width()); break;
1153 case text::RelOrientation::PRINT_AREA
: aPos
.setX(aPos
.getX() + pFrame
->getFramePrintArea().Right()); break;
1154 case text::RelOrientation::PAGE_LEFT
:
1155 case text::RelOrientation::PAGE_FRAME
: aPos
.setX(pPage
->getFrameArea().Right()); break;
1156 case text::RelOrientation::PAGE_PRINT_AREA
: aPos
.setX(pPage
->getFrameArea().Left()
1157 + pPage
->getFramePrintArea().Left()); break;
1163 switch ( _eHoriRelOrient
)
1165 case text::RelOrientation::FRAME_LEFT
:
1166 aPos
.setX(pFrame
->getFrameArea().Left() +
1167 pFrame
->getFramePrintArea().Left());
1170 case text::RelOrientation::PRINT_AREA
:
1171 aPos
.setX(pFrame
->getFrameArea().Left() + pFrame
->getFramePrintArea().Left() +
1172 pFrame
->getFramePrintArea().Width());
1173 aPos
.setX(aPos
.getX() + nBaseOfstForFly
);
1176 case text::RelOrientation::PAGE_LEFT
:
1177 aPos
.setX(pPage
->getFrameArea().Left() + pPage
->getFramePrintArea().Left());
1180 case text::RelOrientation::PAGE_PRINT_AREA
:
1181 aPos
.setX(pPage
->getFrameArea().Left() + pPage
->getFramePrintArea().Left() +
1182 pPage
->getFramePrintArea().Width());
1185 case text::RelOrientation::PAGE_RIGHT
:
1186 case text::RelOrientation::PAGE_FRAME
:
1187 aPos
.setX(pPage
->getFrameArea().Right());
1190 case text::RelOrientation::FRAME
:
1191 aPos
.setX(aPos
.getX() + nBaseOfstForFly
);
1198 switch ( _eHoriRelOrient
)
1200 case text::RelOrientation::FRAME_RIGHT
:
1201 aPos
.AdjustX(pFrame
->getFramePrintArea().Width() );
1202 aPos
+= pFrame
->getFramePrintArea().Pos();
1204 case text::RelOrientation::PRINT_AREA
:
1205 aPos
+= pFrame
->getFramePrintArea().Pos();
1206 aPos
.setX(aPos
.getX() + nBaseOfstForFly
);
1208 case text::RelOrientation::PAGE_RIGHT
:
1209 aPos
.setX(pPage
->getFrameArea().Left() + pPage
->getFramePrintArea().Right());
1211 case text::RelOrientation::PAGE_PRINT_AREA
:
1212 aPos
.setX(pPage
->getFrameArea().Left() + pPage
->getFramePrintArea().Left());
1214 case text::RelOrientation::PAGE_LEFT
:
1215 case text::RelOrientation::PAGE_FRAME
:
1216 aPos
.setX(pPage
->getFrameArea().Left());
1218 case text::RelOrientation::FRAME
:
1219 aPos
.setX(aPos
.getX() + nBaseOfstForFly
);
1229 if( bVertic
&& !bVerticalL2R
)
1230 _orRect
.Pos( aPos
.getX() - _orRect
.Width() - _orRect
.Left(), _orRect
.Top() - aPos
.getY() );
1231 else if( bVerticalL2R
)
1232 _orRect
.Pos( _orRect
.Left() - aPos
.getX(), _orRect
.Top() - aPos
.getY() );
1234 _orRect
.Pos( - ( _orRect
.Right() - aPos
.getX() ), _orRect
.Top() - aPos
.getY() );
1236 _orRect
.Pos( _orRect
.Left() - aPos
.getX(), _orRect
.Top() - aPos
.getY() );
1238 _orRect
.Pos( -_orRect
.Right(), _orRect
.Top() );
1241 Size
SwFEShell::GetGraphicDefaultSize() const
1244 SwFlyFrame
*pFly
= GetSelectedFlyFrame();
1247 // #i32951# - due to issue #i28701# no format of a
1248 // newly inserted Writer fly frame or its anchor frame is performed
1249 // any more. Thus, it could be possible (e.g. on insert of a horizontal
1250 // line) that the anchor frame isn't formatted and its printing area
1251 // size is (0,0). If this is the case the printing area of the upper
1252 // of the anchor frame is taken.
1253 const SwFrame
* pAnchorFrame
= pFly
->GetAnchorFrame();
1254 aRet
= pAnchorFrame
->getFramePrintArea().SSize();
1255 if ( aRet
.IsEmpty() && pAnchorFrame
->GetUpper() )
1257 aRet
= pAnchorFrame
->GetUpper()->getFramePrintArea().SSize();
1261 CalcBoundRect( aBound
, pFly
->GetFormat()->GetAnchor().GetAnchorId());
1262 if ( pFly
->GetAnchorFrame()->IsVertical() )
1263 aRet
.setWidth( aBound
.Width() );
1265 aRet
.setHeight( aBound
.Height() );
1270 bool SwFEShell::IsFrameVertical(const bool bEnvironment
, bool& bRTL
, bool& bVertL2R
) const
1276 if ( Imp()->HasDrawView() )
1278 const SdrMarkList
&rMrkList
= Imp()->GetDrawView()->GetMarkedObjectList();
1279 if( rMrkList
.GetMarkCount() != 1 )
1282 SdrObject
* pObj
= rMrkList
.GetMark( 0 )->GetMarkedSdrObj();
1285 OSL_FAIL( "<SwFEShell::IsFrameVertical(..)> - missing SdrObject instance in marked object list -> This is a serious situation" );
1289 SwContact
* pContact
= GetUserCall( pObj
);
1292 OSL_FAIL( "<SwFEShell::IsFrameVertical(..)> - missing SwContact instance at marked object -> This is a serious situation" );
1295 const SwFrame
* pRef
= pContact
->GetAnchoredObj( pObj
)->GetAnchorFrame();
1298 OSL_FAIL( "<SwFEShell::IsFrameVertical(..)> - missing anchor frame at marked object -> This is a serious situation" );
1302 if ( dynamic_cast<const SwVirtFlyDrawObj
*>( pObj
) != nullptr && !bEnvironment
)
1303 pRef
= static_cast<const SwVirtFlyDrawObj
*>(pObj
)->GetFlyFrame();
1305 bVert
= pRef
->IsVertical();
1306 bRTL
= pRef
->IsRightToLeft();
1307 bVertL2R
= pRef
->IsVertLR();
1313 void SwFEShell::MoveObjectIfActive( svt::EmbeddedObjectRef
&, const Point
& )
1315 // does not do anything, only avoids crash if the method is used for wrong shell
1318 void SwFEShell::ToggleHeaderFooterEdit()
1320 // Clear objects selection
1321 if ( Imp()->GetDrawView()->AreObjectsMarked() )
1323 Imp()->GetDrawView()->UnmarkAll();
1327 SwCursorShell::ToggleHeaderFooterEdit();
1330 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */