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 <hintids.hxx>
21 #include <svx/strings.hrc>
22 #include <svx/sdrobjectfilter.hxx>
23 #include <svx/svddrgmt.hxx>
24 #include <svx/svditer.hxx>
25 #include <svx/svdobj.hxx>
26 #include <svx/svdouno.hxx>
27 #include <svx/svdogrp.hxx>
28 #include <svx/svdocirc.hxx>
29 #include <svx/svdopath.hxx>
30 #include <svx/sxciaitm.hxx>
31 #include <svx/svdocapt.hxx>
32 #include <svx/xlnwtit.hxx>
33 #include <svx/xlnstwit.hxx>
34 #include <svx/xlnedwit.hxx>
35 #include <svx/xlnedit.hxx>
36 #include <svx/xlnstit.hxx>
37 #include <svx/svdomeas.hxx>
38 #include <svx/sdtagitm.hxx>
39 #include <svx/sdtacitm.hxx>
40 #include <svx/sdtaaitm.hxx>
41 #include <editeng/opaqitem.hxx>
42 #include <editeng/protitem.hxx>
43 #include <svx/svdpage.hxx>
44 #include <svx/svdpagv.hxx>
45 #include <svx/dialmgr.hxx>
46 #include <tools/globname.hxx>
47 #include <sot/exchange.hxx>
48 #include <IDocumentDrawModelAccess.hxx>
49 #include <IDocumentSettingAccess.hxx>
50 #include <DocumentSettingManager.hxx>
51 #include <IDocumentState.hxx>
52 #include <IDocumentLayoutAccess.hxx>
53 #include <drawdoc.hxx>
54 #include <textboxhelper.hxx>
57 #include <frmtool.hxx>
58 #include <fmtfsize.hxx>
59 #include <fmtanchr.hxx>
60 #include <fmtornt.hxx>
61 #include <fmtsrnd.hxx>
62 #include <fmtcntnt.hxx>
63 #include <fmtflcnt.hxx>
64 #include <fmtcnct.hxx>
65 #include <swmodule.hxx>
67 #include <rootfrm.hxx>
68 #include <pagefrm.hxx>
69 #include <sectfrm.hxx>
71 #include <IDocumentUndoRedo.hxx>
73 #include <dflyobj.hxx>
74 #include <dcontact.hxx>
75 #include <viewimp.hxx>
81 #include <viewopt.hxx>
83 #include <notxtfrm.hxx>
86 #include <sortedobjs.hxx>
87 #include <HandleAnchorNodeChg.hxx>
88 #include <basegfx/polygon/b2dpolygon.hxx>
89 #include <comphelper/lok.hxx>
90 #include <sfx2/lokhelper.hxx>
91 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
93 #include <flyfrms.hxx>
94 #include <basegfx/polygon/b2dpolygontools.hxx>
95 #include <svx/svxids.hrc>
96 #include <osl/diagnose.h>
98 #include <com/sun/star/embed/EmbedMisc.hpp>
99 #include <com/sun/star/embed/Aspects.hpp>
100 #include <com/sun/star/embed/XEmbeddedObject.hpp>
102 #include <svx/srchdlg.hxx>
106 using namespace com::sun::star
;
109 * set line starts and ends for the object to be created
114 ::basegfx::B2DPolyPolygon
getPolygon(TranslateId pResId
, const SdrModel
& rModel
)
116 ::basegfx::B2DPolyPolygon aRetval
;
117 XLineEndListRef
pLineEndList(rModel
.GetLineEndList());
119 if( pLineEndList
.is() )
121 OUString
aArrowName( SvxResId(pResId
) );
122 tools::Long nCount
= pLineEndList
->Count();
124 for( nIndex
= 0; nIndex
< nCount
; nIndex
++ )
126 const XLineEndEntry
* pEntry
= pLineEndList
->GetLineEnd(nIndex
);
127 if( pEntry
->GetName() == aArrowName
)
129 aRetval
= pEntry
->GetLineEnd();
140 SwFlyFrame
*GetFlyFromMarked( const SdrMarkList
*pLst
, SwViewShell
*pSh
)
143 pLst
= pSh
->HasDrawView() ? &pSh
->Imp()->GetDrawView()->GetMarkedObjectList():nullptr;
145 if ( pLst
&& pLst
->GetMarkCount() == 1 )
147 SdrObject
*pO
= pLst
->GetMark( 0 )->GetMarkedSdrObj();
148 if (SwVirtFlyDrawObj
* pVirtO
= dynamic_cast<SwVirtFlyDrawObj
*>(pO
))
149 return pVirtO
->GetFlyFrame();
154 static void lcl_GrabCursor( SwFEShell
* pSh
, SwFlyFrame
* pOldSelFly
, SwFrameFormat
* pNewDrawFormat
= nullptr)
156 const SwFrameFormat
*pFlyFormat
= pSh
->SelFlyGrabCursor();
157 if( pFlyFormat
&& !pSh
->ActionPend() &&
158 (!pOldSelFly
|| pOldSelFly
->GetFormat() != pFlyFormat
) )
160 // now call set macro if applicable
161 pSh
->GetFlyMacroLnk().Call( static_cast<const SwFlyFrameFormat
*>(pFlyFormat
) );
162 // if a dialog was started inside a macro, then
163 // MouseButtonUp arrives at macro and not to us. Therefore
164 // flag is always set here and will never be switched to
165 // respective Shell !!!!!!!
167 g_bNoInterrupt
= false;
169 else if( !pFlyFormat
|| RES_DRAWFRMFMT
== pFlyFormat
->Which() )
171 // --> assure consistent cursor
176 // If we selected a draw shape format, move the cursor to its anchor position.
177 // SetCursor() may pick something inside, which is not wanted: code later assumes that
178 // the cursor is at the anchor point if a shape is selected.
179 const SwPosition
* pContentAnchor
= pNewDrawFormat
->GetAnchor().GetContentAnchor();
182 pSh
->SetSelection(SwPaM(*pContentAnchor
));
187 pSh
->SetCursor( pSh
->Imp()->GetDrawView()->GetAllMarkedRect().TopLeft(), true);
192 bool SwFEShell::SelectObj( const Point
& rPt
, sal_uInt8 nFlag
, SdrObject
*pObj
)
194 SwDrawView
*pDView
= Imp()->GetDrawView();
197 CurrShell
aCurr( this );
198 StartAction(); // action is necessary to assure only one AttrChgdNotify
199 // (e.g. due to Unmark->MarkListHasChgd) arrives
201 const SdrMarkList
&rMrkList
= pDView
->GetMarkedObjectList();
202 const bool bHadSelection
= rMrkList
.GetMarkCount();
203 const bool bAddSelect
= 0 != (SW_ADD_SELECT
& nFlag
);
204 const bool bEnterGroup
= 0 != (SW_ENTER_GROUP
& nFlag
);
205 SwFlyFrame
* pOldSelFly
= nullptr;
206 const Point
aOldPos( pDView
->GetAllMarkedRect().TopLeft() );
210 // call Unmark when !bAddSelect or if fly was selected
211 bool bUnmark
= !bAddSelect
;
213 if ( rMrkList
.GetMarkCount() == 1 )
215 // if fly was selected, deselect it first
216 pOldSelFly
= ::GetFlyFromMarked( &rMrkList
, this );
219 const sal_uInt16 nType
= GetCntType();
220 if( nType
!= CNT_TXT
|| (SW_LEAVE_FRAME
& nFlag
) ||
221 ( pOldSelFly
->GetFormat()->GetProtect().IsContentProtected()
222 && !IsReadOnlyAvailable() ))
224 // If a fly is deselected, which contains graphic, OLE or
225 // otherwise, the cursor should be removed from it.
226 // Similar if a fly with protected content is deselected.
227 // For simplicity we put the cursor next to the upper-left
229 Point
aPt( pOldSelFly
->getFrameArea().Pos() );
230 aPt
.setX(aPt
.getX() - 1);
231 bool bUnLockView
= !IsViewLocked();
233 SetCursor( aPt
, true );
237 if ( nType
& CNT_GRF
&&
238 static_cast<SwNoTextFrame
*>(pOldSelFly
->Lower())->HasAnimation() )
240 GetWin()->Invalidate( pOldSelFly
->getFrameArea().SVRect() );
244 if ( SdrDragMode::Crop
== GetDragMode() )
245 SetDragMode( SdrDragMode::Move
);
254 pOldSelFly
->SelectionHasChanged(this);
265 OSL_ENSURE( !bEnterGroup
, "SW_ENTER_GROUP is not supported" );
266 pDView
->MarkObj( pObj
, Imp()->GetPageView() );
270 // tolerance limit of Drawing-SS
271 const auto nHdlSizePixel
= Imp()->GetDrawView()->GetMarkHdlSizePixel();
272 const short nMinMove
= static_cast<short>(GetOut()->PixelToLogic(Size(nHdlSizePixel
/2, 0)).Width());
273 pDView
->MarkObj( rPt
, nMinMove
, bAddSelect
, bEnterGroup
);
276 const bool bRet
= 0 != rMrkList
.GetMarkCount();
278 if ( rMrkList
.GetMarkCount() > 1 )
280 // It sucks if Drawing objects were selected and now
281 // additionally a fly is selected.
282 for ( size_t i
= 0; i
< rMrkList
.GetMarkCount(); ++i
)
284 SdrObject
*pTmpObj
= rMrkList
.GetMark( i
)->GetMarkedSdrObj();
285 bool bForget
= dynamic_cast<const SwVirtFlyDrawObj
*>( pTmpObj
) != nullptr;
289 pDView
->MarkObj( pTmpObj
, Imp()->GetPageView(), bAddSelect
, bEnterGroup
);
295 if (rMrkList
.GetMarkCount() == 1)
297 SwFlyFrame
* pSelFly
= ::GetFlyFromMarked(&rMrkList
, this);
298 if (pSelFly
&& pSelFly
->IsFlySplitAllowed())
300 auto pMaster
= static_cast<SwFlyAtContentFrame
*>(pSelFly
);
301 while (pMaster
->IsFollow())
303 pMaster
= pMaster
->GetPrecede();
305 if (pMaster
!= pSelFly
)
307 // A follow fly frame is selected, select the master instead. Selection of a follow
308 // would not be ideal, since one can't customize its vertical position (always
309 // starts at the top of the page).
311 pDView
->MarkObj(pMaster
->DrawObj(), Imp()->GetPageView(), bAddSelect
, bEnterGroup
);
316 if ( rMrkList
.GetMarkCount() == 1 )
318 SwFlyFrame
*pSelFly
= ::GetFlyFromMarked( &rMrkList
, this );
320 pSelFly
->SelectionHasChanged(this);
323 SwFrameFormat
* pNewDrawFormat
= nullptr;
324 if (!(nFlag
& SW_ALLOW_TEXTBOX
))
326 // If the fly frame is a textbox of a shape, then select the shape instead.
327 for (size_t i
= 0; i
< rMrkList
.GetMarkCount(); ++i
)
329 SdrObject
* pObject
= rMrkList
.GetMark(i
)->GetMarkedSdrObj();
330 SwContact
* pContact
= GetUserCall(pObject
);
336 SwFrameFormat
* pFormat
= pContact
->GetFormat();
337 if (SwFrameFormat
* pShapeFormat
= SwTextBoxHelper::getOtherTextBoxFormat(pFormat
, RES_FLYFRMFMT
))
339 SdrObject
* pShape
= pShapeFormat
->FindSdrObject();
341 pDView
->MarkObj(pShape
, Imp()->GetPageView(), bAddSelect
, bEnterGroup
);
342 // Remember that this frame format was marked for selection.
343 pNewDrawFormat
= pShapeFormat
;
351 ::lcl_GrabCursor(this, pOldSelFly
, pNewDrawFormat
);
352 if ( GetCntType() & CNT_GRF
)
354 const SwFlyFrame
*pTmp
= GetFlyFromMarked( &rMrkList
, this );
355 OSL_ENSURE( pTmp
, "Graphic without Fly" );
356 if ( pTmp
&& static_cast<const SwNoTextFrame
*>(pTmp
->Lower())->HasAnimation() )
357 static_cast<const SwNoTextFrame
*>(pTmp
->Lower())->StopAnimation( GetOut() );
360 else if ( !pOldSelFly
&& bHadSelection
)
361 SetCursor( aOldPos
, true);
363 if( bRet
|| !bHadSelection
)
366 // update status line
367 ::FrameNotify( this, bRet
? FLY_DRAG_START
: FLY_DRAG_END
);
374 * Description: MoveAnchor( nDir ) looked for an another Anchor for
375 * the selected drawing object (or fly frame) in the given direction.
376 * An object "as character" doesn't moves anyway.
377 * A page bounded object could move to the previous/next page with up/down,
378 * an object bounded "at paragraph" moves to the previous/next paragraph, too.
379 * An object bounded "at character" moves to the previous/next paragraph
380 * with up/down and to the previous/next character with left/right.
381 * If the anchor for at paragraph/character bounded objects has vertical or
382 * right_to_left text direction, the directions for up/down/left/right will
383 * interpreted accordingly.
384 * An object bounded "at fly" takes the center of the actual anchor and looks
385 * for the nearest fly frame in the given direction.
388 static bool LessX( Point
const & aPt1
, Point
const & aPt2
, bool bOld
)
390 return aPt1
.getX() < aPt2
.getX()
391 || ( aPt1
.getX() == aPt2
.getX()
392 && ( aPt1
.getY() < aPt2
.getY()
393 || ( aPt1
.getY() == aPt2
.getY() && bOld
) ) );
395 static bool LessY( Point
const & aPt1
, Point
const & aPt2
, bool bOld
)
397 return aPt1
.getY() < aPt2
.getY()
398 || ( aPt1
.getY() == aPt2
.getY()
399 && ( aPt1
.getX() < aPt2
.getX()
400 || ( aPt1
.getX() == aPt2
.getX() && bOld
) ) );
403 bool SwFEShell::MoveAnchor( SwMove nDir
)
405 if (!Imp()->GetDrawView())
407 const SdrMarkList
& pMrkList
= Imp()->GetDrawView()->GetMarkedObjectList();
408 if (1 != pMrkList
.GetMarkCount())
411 SwFlyFrame
* pFly
= nullptr;
412 SdrObject
*pObj
= pMrkList
.GetMark( 0 )->GetMarkedSdrObj();
413 if (SwVirtFlyDrawObj
* pVirtO
= dynamic_cast<SwVirtFlyDrawObj
*>(pObj
))
415 pFly
= pVirtO
->GetFlyFrame();
416 pOld
= pFly
->AnchorFrame();
419 pOld
= static_cast<SwDrawContact
*>(GetUserCall(pObj
))->GetAnchorFrame( pObj
);
423 SwFrame
* pNew
= pOld
;
425 SwAnchoredObject
* pAnchoredObj
= ::GetUserCall( pObj
)->GetAnchoredObj( pObj
);
426 SwFrameFormat
& rFormat
= pAnchoredObj
->GetFrameFormat();
427 SwFormatAnchor
aAnch( rFormat
.GetAnchor() );
428 RndStdIds nAnchorId
= aAnch
.GetAnchorId();
429 if ( RndStdIds::FLY_AS_CHAR
== nAnchorId
)
431 if( pOld
->IsVertical() )
433 if( pOld
->IsTextFrame() )
436 case SwMove::UP
: nDir
= SwMove::LEFT
; break;
437 case SwMove::DOWN
: nDir
= SwMove::RIGHT
; break;
438 case SwMove::LEFT
: nDir
= SwMove::DOWN
; break;
439 case SwMove::RIGHT
: nDir
= SwMove::UP
; break;
441 if( pOld
->IsRightToLeft() )
443 if( nDir
== SwMove::LEFT
)
444 nDir
= SwMove::RIGHT
;
445 else if( nDir
== SwMove::RIGHT
)
450 switch ( nAnchorId
) {
451 case RndStdIds::FLY_AT_PAGE
:
453 OSL_ENSURE( pOld
->IsPageFrame(), "Wrong anchor, page expected." );
454 if( SwMove::UP
== nDir
)
455 pNew
= pOld
->GetPrev();
456 else if( SwMove::DOWN
== nDir
)
457 pNew
= pOld
->GetNext();
458 if( pNew
&& pNew
!= pOld
)
460 aAnch
.SetPageNum( static_cast<SwPageFrame
*>(pNew
)->GetPhyPageNum() );
465 case RndStdIds::FLY_AT_CHAR
:
467 OSL_ENSURE(pOld
->IsTextFrame(), "Wrong anchor, text frame expected.");
468 if( SwMove::LEFT
== nDir
|| SwMove::RIGHT
== nDir
)
470 SwPosition pos
= *aAnch
.GetContentAnchor();
471 SwTextFrame
*const pOldFrame(static_cast<SwTextFrame
*>(pOld
));
472 TextFrameIndex
const nAct(pOldFrame
->MapModelToViewPos(pos
));
473 if( SwMove::LEFT
== nDir
)
478 pos
= pOldFrame
->MapViewToModelPos(nAct
- TextFrameIndex(1));
485 TextFrameIndex
const nMax(pOldFrame
->GetText().getLength());
489 pos
= pOldFrame
->MapViewToModelPos(nAct
+ TextFrameIndex(1));
494 if( pos
!= *aAnch
.GetContentAnchor())
495 aAnch
.SetAnchor( &pos
);
499 case RndStdIds::FLY_AT_PARA
:
501 OSL_ENSURE(pOld
->IsTextFrame(), "Wrong anchor, text frame expected.");
502 if( SwMove::UP
== nDir
)
503 pNew
= pOld
->FindPrev();
504 else if( SwMove::DOWN
== nDir
)
505 pNew
= pOld
->FindNext();
506 if( pNew
&& pNew
!= pOld
&& pNew
->IsContentFrame() )
508 SwTextFrame
*const pNewFrame(static_cast<SwTextFrame
*>(pNew
));
509 SwPosition
const pos
= pNewFrame
->MapViewToModelPos(
511 (bRet
&& pNewFrame
->GetText().getLength() != 0)
512 ? pNewFrame
->GetText().getLength() - 1
514 aAnch
.SetAnchor( &pos
);
517 else if( SwMove::UP
== nDir
|| SwMove::DOWN
== nDir
)
521 case RndStdIds::FLY_AT_FLY
:
523 OSL_ENSURE( pOld
->IsFlyFrame(), "Wrong anchor, fly frame expected.");
524 SwPageFrame
* pPage
= pOld
->FindPageFrame();
525 OSL_ENSURE( pPage
, "Where's my page?" );
526 SwFlyFrame
* pNewFly
= nullptr;
527 if( pPage
->GetSortedObjs() )
530 Point
aCenter( pOld
->getFrameArea().Left() + pOld
->getFrameArea().Width()/2,
531 pOld
->getFrameArea().Top() + pOld
->getFrameArea().Height()/2 );
533 for(SwAnchoredObject
* pAnchObj
: *pPage
->GetSortedObjs())
535 if( auto pTmp
= pAnchObj
->DynCastFlyFrame() )
541 const SwFlyFrame
* pCheck
= pFly
? pTmp
: nullptr;
546 const SwFrame
*pNxt
= pCheck
->GetAnchorFrame();
547 pCheck
= pNxt
? pNxt
->FindFlyFrame() : nullptr;
549 if( pCheck
|| pTmp
->IsProtected() )
551 Point
aNew( pTmp
->getFrameArea().Left() +
552 pTmp
->getFrameArea().Width()/2,
553 pTmp
->getFrameArea().Top() +
554 pTmp
->getFrameArea().Height()/2 );
555 bool bAccept
= false;
559 bAccept
= LessX( aCenter
, aNew
, bOld
)
561 LessX( aNew
, aBest
, false ) );
566 bAccept
= LessX( aNew
, aCenter
, !bOld
)
568 LessX( aBest
, aNew
, true ) );
573 bAccept
= LessY( aNew
, aCenter
, !bOld
)
575 LessY( aBest
, aNew
, true ) );
580 bAccept
= LessY( aCenter
, aNew
, bOld
)
582 LessY( aNew
, aBest
, false ) );
598 SwPosition
aPos( *pNewFly
->GetFormat()->
599 GetContent().GetContentIdx());
600 aAnch
.SetAnchor( &aPos
);
610 // --> handle change of anchor node:
611 // if count of the anchor frame also change, the fly frames have to be
612 // re-created. Thus, delete all fly frames except the <this> before the
613 // anchor attribute is change and re-create them afterwards.
615 std::unique_ptr
<SwHandleAnchorNodeChg
> pHandleAnchorNodeChg
;
616 SwFlyFrameFormat
* pFlyFrameFormat( dynamic_cast<SwFlyFrameFormat
*>(&rFormat
) );
617 if ( pFlyFrameFormat
)
619 pHandleAnchorNodeChg
.reset(
620 new SwHandleAnchorNodeChg( *pFlyFrameFormat
, aAnch
));
622 rFormat
.GetDoc()->SetAttr( aAnch
, rFormat
);
624 // #i28701# - no call of method
625 // <CheckCharRectAndTopOfLine()> for to-character anchored
626 // Writer fly frame needed. This method call can cause a
627 // format of the anchor frame, which is no longer intended.
628 // Instead clear the anchor character rectangle and
629 // the top of line values for all to-character anchored objects.
630 pAnchoredObj
->ClearCharRectAndTopOfLine();
637 const SdrMarkList
* SwFEShell::GetMarkList_() const
639 const SdrMarkList
* pMarkList
= nullptr;
640 if( Imp()->GetDrawView() != nullptr )
641 pMarkList
= &Imp()->GetDrawView()->GetMarkedObjectList();
645 FrameTypeFlags
SwFEShell::GetSelFrameType() const
647 FrameTypeFlags eType
;
649 // get marked frame list, and check if anything is selected
650 const SdrMarkList
* pMarkList
= GetMarkList_();
651 if( pMarkList
== nullptr || pMarkList
->GetMarkCount() == 0 )
652 eType
= FrameTypeFlags::NONE
;
655 // obtain marked item as fly frame; if no fly frame, it must
657 const SwFlyFrame
* pFly
= ::GetFlyFromMarked(pMarkList
, const_cast<SwFEShell
*>(this));
658 if ( pFly
!= nullptr )
660 if( pFly
->IsFlyLayFrame() )
661 eType
= FrameTypeFlags::FLY_FREE
;
662 else if( pFly
->IsFlyAtContentFrame() )
663 eType
= FrameTypeFlags::FLY_ATCNT
;
666 OSL_ENSURE( pFly
->IsFlyInContentFrame(), "New frametype?" );
667 eType
= FrameTypeFlags::FLY_INCNT
;
671 eType
= FrameTypeFlags::DRAWOBJ
;
677 // does the draw selection contain a control?
678 bool SwFEShell::IsSelContainsControl() const
682 // basically, copy the mechanism from GetSelFrameType(), but call
683 // CheckControl... if you get a drawing object
684 const SdrMarkList
* pMarkList
= GetMarkList_();
685 if( pMarkList
!= nullptr && pMarkList
->GetMarkCount() == 1 )
687 // if we have one marked object, get the SdrObject and check
688 // whether it contains a control
689 const SdrObject
* pSdrObject
= pMarkList
->GetMark( 0 )->GetMarkedSdrObj();
690 bRet
= pSdrObject
&& ::CheckControlLayer( pSdrObject
);
695 void SwFEShell::ScrollTo( const Point
&rPt
)
697 const SwRect
aRect( rPt
, rPt
);
698 if ( IsScrollMDI( this, aRect
) &&
699 (!Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() ||
700 Imp()->IsDragPossible( rPt
)) )
702 ScrollMDI( this, aRect
, SCROLLVAL
, SCROLLVAL
);
706 void SwFEShell::SetDragMode( SdrDragMode eDragMode
)
708 if ( Imp()->HasDrawView() )
709 Imp()->GetDrawView()->SetDragMode( eDragMode
);
712 SdrDragMode
SwFEShell::GetDragMode() const
714 SdrDragMode nRet
= SdrDragMode(0);
715 if ( Imp()->HasDrawView() )
717 nRet
= Imp()->GetDrawView()->GetDragMode();
722 void SwFEShell::StartCropImage()
724 if ( !Imp()->HasDrawView() )
728 SdrView
*pView
= Imp()->GetDrawView();
731 const SdrMarkList
&rMarkList
= pView
->GetMarkedObjectList();
732 if( 0 == rMarkList
.GetMarkCount() ) {
733 // No object selected
737 // If more than a single SwVirtFlyDrawObj is selected, select only the first SwVirtFlyDrawObj
738 if ( rMarkList
.GetMarkCount() > 1 )
740 for ( size_t i
= 0; i
< rMarkList
.GetMarkCount(); ++i
)
742 SdrObject
*pTmpObj
= rMarkList
.GetMark( i
)->GetMarkedSdrObj();
743 bool bForget
= dynamic_cast<const SwVirtFlyDrawObj
*>( pTmpObj
) != nullptr;
747 pView
->MarkObj( pTmpObj
, Imp()->GetPageView() );
753 // Activate CROP mode
754 pView
->SetEditMode( SdrViewEditMode::Edit
);
755 SetDragMode( SdrDragMode::Crop
);
758 void SwFEShell::BeginDrag( const Point
* pPt
, bool bIsShift
)
760 SdrView
*pView
= Imp()->GetDrawView();
761 if ( pView
&& pView
->AreObjectsMarked() )
763 m_pChainFrom
.reset();
765 SdrHdl
* pHdl
= pView
->PickHandle( *pPt
);
766 if (pView
->BegDragObj( *pPt
, nullptr, pHdl
))
767 pView
->GetDragMethod()->SetShiftPressed( bIsShift
);
768 ::FrameNotify( this );
772 void SwFEShell::Drag( const Point
*pPt
, bool )
774 OSL_ENSURE( Imp()->HasDrawView(), "Drag without DrawView?" );
775 if ( HasDrawViewDrag() )
778 Imp()->GetDrawView()->MovDragObj( *pPt
);
779 Imp()->GetDrawView()->ShowDragAnchor();
780 ::FrameNotify( this );
784 void SwFEShell::EndDrag()
786 OSL_ENSURE( Imp()->HasDrawView(), "EndDrag without DrawView?" );
787 SdrView
*pView
= Imp()->GetDrawView();
788 if ( !pView
->IsDragObj() )
791 for(SwViewShell
& rSh
: GetRingContainer())
794 StartUndo( SwUndoId::START
);
796 // #50778# Bug during dragging: In StartAction a HideShowXor is called.
797 // In EndDragObj() this is reversed, for no reason and even wrong.
798 // To restore consistency we should bring up the Xor again.
800 // Reanimation from the hack #50778 to fix bug #97057
801 // May be not the best solution, but the one with lowest risc at the moment.
802 // pView->ShowShownXor( GetOut() );
806 // DrawUndo on to flyframes are not stored
807 // The flys change the flag.
808 GetDoc()->GetIDocumentUndoRedo().DoDrawUndo(true);
809 ChgAnchor( RndStdIds::FLY_AT_PARA
, true );
811 EndUndo( SwUndoId::END
);
813 for(SwViewShell
& rSh
: GetRingContainer())
816 if( auto pCursorShell
= dynamic_cast<SwCursorShell
*>(&rSh
) )
817 pCursorShell
->CallChgLnk();
820 GetDoc()->getIDocumentState().SetModified();
821 ::FrameNotify( this );
824 void SwFEShell::BreakDrag()
826 OSL_ENSURE( Imp()->HasDrawView(), "BreakDrag without DrawView?" );
827 if( HasDrawViewDrag() )
828 Imp()->GetDrawView()->BrkDragObj();
832 // If a fly is selected, pulls the crsr in the first ContentFrame
833 const SwFrameFormat
* SwFEShell::SelFlyGrabCursor()
835 if ( Imp()->HasDrawView() )
837 const SdrMarkList
&rMrkList
= Imp()->GetDrawView()->GetMarkedObjectList();
838 SwFlyFrame
*pFly
= ::GetFlyFromMarked( &rMrkList
, this );
842 SwContentFrame
*pCFrame
= pFly
->ContainsContent();
845 // --> assure, that the cursor is consistent.
848 SwPaM
*pCursor
= GetCursor();
850 if (pCFrame
->IsTextFrame())
852 *pCursor
->GetPoint() = static_cast<SwTextFrame
*>(pCFrame
)
853 ->MapViewToModelPos(TextFrameIndex(0));
857 assert(pCFrame
->IsNoTextFrame());
858 SwContentNode
*const pCNode
= static_cast<SwNoTextFrame
*>(pCFrame
)->GetNode();
859 pCursor
->GetPoint()->Assign(*pCNode
);
862 SwRect
& rChrRect
= const_cast<SwRect
&>(GetCharRect());
863 rChrRect
= pFly
->getFramePrintArea();
864 rChrRect
.Pos() += pFly
->getFrameArea().Pos();
865 GetCursorDocPos() = rChrRect
.Pos();
867 return pFly
->GetFormat();
873 // Selection to above/below (Z-Order)
874 static void lcl_NotifyNeighbours( const SdrMarkList
*pLst
)
876 // Rules for evasion have changed.
877 // 1. The environment of the fly and everything inside should be notified
878 // 2. The content of the frame itself has to be notified
879 // 3. Frames displaced by the frame have to be notified
880 // 4. Also Drawing objects can displace frames
881 for( size_t j
= 0; j
< pLst
->GetMarkCount(); ++j
)
884 bool bCheckNeighbours
= false;
885 sal_Int16 aHori
= text::HoriOrientation::NONE
;
887 SdrObject
*pO
= pLst
->GetMark( j
)->GetMarkedSdrObj();
888 if (SwVirtFlyDrawObj
* pVirtO
= dynamic_cast<SwVirtFlyDrawObj
*>(pO
))
890 SwFlyFrame
*pFly
= pVirtO
->GetFlyFrame();
892 const SwFormatHoriOrient
&rHori
= pFly
->GetFormat()->GetHoriOrient();
893 aHori
= rHori
.GetHoriOrient();
894 if( text::HoriOrientation::NONE
!= aHori
&& text::HoriOrientation::CENTER
!= aHori
&&
895 pFly
->IsFlyAtContentFrame() )
897 bCheckNeighbours
= true;
898 pFly
->InvalidatePos();
899 SwFrameAreaDefinition::FrameAreaWriteAccess
aFrm(*pFly
);
900 aFrm
.Pos().AdjustY(1 );
903 pPage
= pFly
->FindPageFrame();
904 aRect
= pFly
->getFrameArea();
908 SwFrame
* pAnch
= static_cast<SwDrawContact
*>( GetUserCall(pO
) )->GetAnchorFrame( pO
);
911 pPage
= pAnch
->FindPageFrame();
912 // #i68520# - naming changed
913 aRect
= GetBoundRectOfAnchoredObj( pO
);
916 const size_t nCount
= pPage
->GetSortedObjs() ? pPage
->GetSortedObjs()->size() : 0;
917 for ( size_t i
= 0; i
< nCount
; ++i
)
919 SwAnchoredObject
* pAnchoredObj
= (*pPage
->GetSortedObjs())[i
];
920 SwFlyFrame
* pAct
= pAnchoredObj
->DynCastFlyFrame();
924 SwRect
aTmpCalcPnt( pAct
->getFramePrintArea() );
925 aTmpCalcPnt
+= pAct
->getFrameArea().Pos();
926 if ( aRect
.Overlaps( aTmpCalcPnt
) )
928 SwContentFrame
*pCnt
= pAct
->ContainsContent();
931 aTmpCalcPnt
= pCnt
->getFramePrintArea();
932 aTmpCalcPnt
+= pCnt
->getFrameArea().Pos();
933 if ( aRect
.Overlaps( aTmpCalcPnt
) )
934 static_cast<SwFrame
*>(pCnt
)->Prepare( PrepareHint::FlyFrameAttributesChanged
);
935 pCnt
= pCnt
->GetNextContentFrame();
938 if ( bCheckNeighbours
&& pAct
->IsFlyAtContentFrame() )
940 const SwFormatHoriOrient
&rH
= pAct
->GetFormat()->GetHoriOrient();
941 if ( rH
.GetHoriOrient() == aHori
&&
942 pAct
->getFrameArea().Top() <= aRect
.Bottom() &&
943 pAct
->getFrameArea().Bottom() >= aRect
.Top() )
945 pAct
->InvalidatePos();
946 SwFrameAreaDefinition::FrameAreaWriteAccess
aFrm(*pAct
);
947 aFrm
.Pos().AdjustY(1 );
954 void SwFEShell::SetLineEnds(SfxItemSet
& rAttr
, SdrObject
const & rObj
, sal_uInt16 nSlotId
)
956 SdrModel
& rModel(rObj
.getSdrModelFromSdrObject());
958 if ( !(nSlotId
== SID_LINE_ARROW_START
||
959 nSlotId
== SID_LINE_ARROW_END
||
960 nSlotId
== SID_LINE_ARROWS
||
961 nSlotId
== SID_LINE_ARROW_CIRCLE
||
962 nSlotId
== SID_LINE_CIRCLE_ARROW
||
963 nSlotId
== SID_LINE_ARROW_SQUARE
||
964 nSlotId
== SID_LINE_SQUARE_ARROW
||
965 nSlotId
== SID_DRAW_MEASURELINE
) )
968 // set attributes of line start and ends
971 ::basegfx::B2DPolyPolygon
aArrow( getPolygon( RID_SVXSTR_ARROW
, rModel
) );
972 if( !aArrow
.count() )
974 ::basegfx::B2DPolygon aNewArrow
;
975 aNewArrow
.append(::basegfx::B2DPoint(10.0, 0.0));
976 aNewArrow
.append(::basegfx::B2DPoint(0.0, 30.0));
977 aNewArrow
.append(::basegfx::B2DPoint(20.0, 30.0));
978 aNewArrow
.setClosed(true);
979 aArrow
.append(aNewArrow
);
983 ::basegfx::B2DPolyPolygon
aCircle( getPolygon( RID_SVXSTR_CIRCLE
, rModel
) );
984 if( !aCircle
.count() )
986 ::basegfx::B2DPolygon aNewCircle
= ::basegfx::utils::createPolygonFromEllipse(::basegfx::B2DPoint(0.0, 0.0), 250.0, 250.0);
987 aNewCircle
.setClosed(true);
988 aCircle
.append(aNewCircle
);
992 ::basegfx::B2DPolyPolygon
aSquare( getPolygon( RID_SVXSTR_SQUARE
, rModel
) );
993 if( !aSquare
.count() )
995 ::basegfx::B2DPolygon aNewSquare
;
996 aNewSquare
.append(::basegfx::B2DPoint(0.0, 0.0));
997 aNewSquare
.append(::basegfx::B2DPoint(10.0, 0.0));
998 aNewSquare
.append(::basegfx::B2DPoint(10.0, 10.0));
999 aNewSquare
.append(::basegfx::B2DPoint(0.0, 10.0));
1000 aNewSquare
.setClosed(true);
1001 aSquare
.append(aNewSquare
);
1004 SfxItemSet
aSet( rModel
.GetItemPool() );
1005 tools::Long nWidth
= 100; // (1/100th mm)
1007 // determine line width and calculate with it the line end width
1008 if( aSet
.GetItemState( XATTR_LINEWIDTH
) != SfxItemState::DONTCARE
)
1010 tools::Long nValue
= aSet
.Get( XATTR_LINEWIDTH
).GetValue();
1012 nWidth
= nValue
* 3;
1017 case SID_LINE_ARROWS
:
1018 case SID_DRAW_MEASURELINE
:
1020 // connector with arrow ends
1021 rAttr
.Put(XLineStartItem(SvxResId(RID_SVXSTR_ARROW
), aArrow
));
1022 rAttr
.Put(XLineStartWidthItem(nWidth
));
1023 rAttr
.Put(XLineEndItem(SvxResId(RID_SVXSTR_ARROW
), aArrow
));
1024 rAttr
.Put(XLineEndWidthItem(nWidth
));
1028 case SID_LINE_ARROW_START
:
1029 case SID_LINE_ARROW_CIRCLE
:
1030 case SID_LINE_ARROW_SQUARE
:
1032 // connector with arrow start
1033 rAttr
.Put(XLineStartItem(SvxResId(RID_SVXSTR_ARROW
), aArrow
));
1034 rAttr
.Put(XLineStartWidthItem(nWidth
));
1038 case SID_LINE_ARROW_END
:
1039 case SID_LINE_CIRCLE_ARROW
:
1040 case SID_LINE_SQUARE_ARROW
:
1042 // connector with arrow end
1043 rAttr
.Put(XLineEndItem(SvxResId(RID_SVXSTR_ARROW
), aArrow
));
1044 rAttr
.Put(XLineEndWidthItem(nWidth
));
1049 // and again, for the still missing ends
1052 case SID_LINE_ARROW_CIRCLE
:
1055 rAttr
.Put(XLineEndItem(SvxResId(RID_SVXSTR_CIRCLE
), aCircle
));
1056 rAttr
.Put(XLineEndWidthItem(nWidth
));
1060 case SID_LINE_CIRCLE_ARROW
:
1063 rAttr
.Put(XLineStartItem(SvxResId(RID_SVXSTR_CIRCLE
), aCircle
));
1064 rAttr
.Put(XLineStartWidthItem(nWidth
));
1068 case SID_LINE_ARROW_SQUARE
:
1071 rAttr
.Put(XLineEndItem(SvxResId(RID_SVXSTR_SQUARE
), aSquare
));
1072 rAttr
.Put(XLineEndWidthItem(nWidth
));
1076 case SID_LINE_SQUARE_ARROW
:
1079 rAttr
.Put(XLineStartItem(SvxResId(RID_SVXSTR_SQUARE
), aSquare
));
1080 rAttr
.Put(XLineStartWidthItem(nWidth
));
1087 void SwFEShell::SelectionToTop( bool bTop
)
1089 OSL_ENSURE( Imp()->HasDrawView(), "SelectionToTop without DrawView?" );
1090 const SdrMarkList
&rMrkList
= Imp()->GetDrawView()->GetMarkedObjectList();
1091 OSL_ENSURE( rMrkList
.GetMarkCount(), "No object selected." );
1093 SwFlyFrame
*pFly
= ::GetFlyFromMarked( &rMrkList
, this );
1094 if ( pFly
&& pFly
->IsFlyInContentFrame() )
1099 Imp()->GetDrawView()->PutMarkedToTop();
1101 Imp()->GetDrawView()->MovMarkedToTop();
1102 ::lcl_NotifyNeighbours( &rMrkList
);
1104 // Does the selection contain a textbox?
1105 for (size_t i
= 0; i
< rMrkList
.GetMarkCount(); i
++)
1106 if (auto pObj
= rMrkList
.GetMark(i
)->GetMarkedSdrObj())
1107 // Get the textbox-shape
1108 if (auto pFormat
= FindFrameFormat(pObj
))
1110 // If it has not textframe skip...
1111 if (!SwTextBoxHelper::isTextBox(pFormat
, RES_DRAWFRMFMT
, pObj
))
1113 // If it has a textframe so it is a textbox, get its page
1115 = pFormat
->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel())
1116 // Not really understood why everything is on page 0...
1117 // but it is easier to handle sdrobjects, that's true
1118 if (auto pPage
= pDrwModel
->GetPage(0))
1120 // nShift: it means how many layers the pObj have to be shifted up,
1121 // in order not to interfere with other shapes and textboxes.
1123 // - The next shape has textframe: This shape have to shifted with
1125 // - The next shape has not got textframe: This shape have to be
1126 // shifted only one layer up.
1127 // - The next shape is null:
1128 // - This shape is already at heaven: Only the textframe have
1130 sal_uInt32 nShift
= 0;
1131 // Get the one level higher object (note: can be nullptr!)
1132 const auto pNextObj
= pPage
->SetObjectOrdNum(pObj
->GetOrdNum() + 1, pObj
->GetOrdNum() + 1);
1133 // If there is a higher object (not null)...
1136 // One level shift is necessary
1138 // If this object is a textbox, two level increasing needed
1139 // (one for the shape and one for the frame)
1140 if (auto pNextFormat
= FindFrameFormat(pNextObj
))
1141 if (SwTextBoxHelper::isTextBox(pNextFormat
, RES_DRAWFRMFMT
, pNextObj
)
1142 || SwTextBoxHelper::isTextBox(pNextFormat
, RES_FLYFRMFMT
))
1145 // Set the new z-order.
1146 pPage
->SetObjectOrdNum(pObj
->GetOrdNum(), pObj
->GetOrdNum() + nShift
);
1148 // The shape is on the right level, correct the layer of the frame
1149 SwTextBoxHelper::DoTextBoxZOrderCorrection(pFormat
, pObj
);
1152 GetDoc()->getIDocumentState().SetModified();
1156 void SwFEShell::SelectionToBottom( bool bBottom
)
1158 OSL_ENSURE( Imp()->HasDrawView(), "SelectionToBottom without DrawView?" );
1159 const SdrMarkList
&rMrkList
= Imp()->GetDrawView()->GetMarkedObjectList();
1160 OSL_ENSURE( rMrkList
.GetMarkCount(), "No object selected." );
1162 SwFlyFrame
*pFly
= ::GetFlyFromMarked( &rMrkList
, this );
1163 if ( pFly
&& pFly
->IsFlyInContentFrame() )
1168 Imp()->GetDrawView()->PutMarkedToBtm();
1170 Imp()->GetDrawView()->MovMarkedToBtm();
1171 ::lcl_NotifyNeighbours( &rMrkList
);
1173 // If the selection has textbox
1174 for(size_t i
= 0; i
< rMrkList
.GetMarkCount(); i
++)
1175 if (auto pObj
= rMrkList
.GetMark(i
)->GetMarkedSdrObj())
1176 // Get the shape of the textbox
1177 if (auto pFormat
= FindFrameFormat(pObj
))
1179 // If the shape has not textframes skip.
1180 if (!SwTextBoxHelper::isTextBox(pFormat
, RES_DRAWFRMFMT
, pObj
))
1182 // If has, move the shape to correct level with...
1184 = pFormat
->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel())
1185 if (auto pPage
= pDrwModel
->GetPage(0))
1187 const auto pNextObj
= pPage
->SetObjectOrdNum(pObj
->GetOrdNum() - 1, pObj
->GetOrdNum() - 1);
1188 // If there is a lower object (not null)...
1191 // If the lower has no textframe, just do nothing, else move by one lower
1192 if (auto pNextFormat
= FindFrameFormat(pNextObj
))
1193 if (SwTextBoxHelper::isTextBox(pNextFormat
, RES_DRAWFRMFMT
, pNextObj
)
1194 || SwTextBoxHelper::isTextBox(pNextFormat
, RES_FLYFRMFMT
))
1195 pPage
->SetObjectOrdNum(pObj
->GetOrdNum(), pObj
->GetOrdNum() - 1);
1198 // And set correct layer for the selected textbox.
1199 SwTextBoxHelper::DoTextBoxZOrderCorrection(pFormat
, pObj
);
1202 GetDoc()->getIDocumentState().SetModified();
1206 // Object above/below the document? 2 Controls, 1 Heaven, 0 Hell,
1207 // SDRLAYER_NOTFOUND Ambiguous
1208 SdrLayerID
SwFEShell::GetLayerId() const
1210 if ( !Imp()->HasDrawView() )
1211 return SDRLAYER_NOTFOUND
;
1213 SdrLayerID nRet
= SDRLAYER_NOTFOUND
;
1214 const SdrMarkList
&rMrkList
= Imp()->GetDrawView()->GetMarkedObjectList();
1215 for ( size_t i
= 0; i
< rMrkList
.GetMarkCount(); ++i
)
1217 const SdrObject
*pObj
= rMrkList
.GetMark( i
)->GetMarkedSdrObj();
1220 if ( nRet
== SDRLAYER_NOTFOUND
)
1221 nRet
= pObj
->GetLayer();
1222 else if ( nRet
!= pObj
->GetLayer() )
1224 return SDRLAYER_NOTFOUND
;
1230 // Object above/below the document
1231 // Note: only visible objects can be marked. Thus, objects with invisible
1232 // layer IDs have not to be considered.
1233 // If <SwFEShell> exists, layout exists!!
1234 void SwFEShell::ChangeOpaque( SdrLayerID nLayerId
)
1236 if ( !Imp()->HasDrawView() )
1239 const SdrMarkList
&rMrkList
= Imp()->GetDrawView()->GetMarkedObjectList();
1240 const IDocumentDrawModelAccess
& rIDDMA
= getIDocumentDrawModelAccess();
1241 // correct type of <nControls>
1242 for ( size_t i
= 0; i
< rMrkList
.GetMarkCount(); ++i
)
1244 SdrObject
* pObj
= rMrkList
.GetMark( i
)->GetMarkedSdrObj();
1247 // or group objects containing controls.
1249 // consider that a member of a drawing group has been selected.
1250 const SwContact
* pContact
= ::GetUserCall( pObj
);
1251 OSL_ENSURE( pContact
&& pContact
->GetMaster(), "<SwFEShell::ChangeOpaque(..)> - missing contact or missing master object at contact!" );
1252 const bool bControlObj
= ( pContact
&& pContact
->GetMaster() )
1253 ? ::CheckControlLayer( pContact
->GetMaster() )
1254 : ::CheckControlLayer( pObj
);
1255 if ( !bControlObj
&& pObj
->GetLayer() != nLayerId
)
1257 pObj
->SetLayer( nLayerId
);
1258 InvalidateWindows( SwRect( pObj
->GetCurrentBoundRect() ) );
1259 if (SwVirtFlyDrawObj
* pVirtO
= dynamic_cast<SwVirtFlyDrawObj
*>(pObj
))
1261 SwFormat
*pFormat
= pVirtO
->GetFlyFrame()->GetFormat();
1262 SvxOpaqueItem
aOpa( pFormat
->GetOpaque() );
1263 aOpa
.SetValue( nLayerId
== rIDDMA
.GetHellId() );
1264 pFormat
->SetFormatAttr( aOpa
);
1265 // If pObj has textframe, put its textframe to the right level
1266 if (auto pTextBx
= FindFrameFormat(pObj
))
1267 SwTextBoxHelper::DoTextBoxZOrderCorrection(pTextBx
, pObj
);
1271 GetDoc()->getIDocumentState().SetModified();
1274 void SwFEShell::SelectionToHeaven()
1276 ChangeOpaque( getIDocumentDrawModelAccess().GetHeavenId() );
1279 void SwFEShell::SelectionToHell()
1281 ChangeOpaque( getIDocumentDrawModelAccess().GetHellId() );
1284 size_t SwFEShell::IsObjSelected() const
1286 if ( IsFrameSelected() || !Imp()->HasDrawView() )
1289 return Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount();
1292 bool SwFEShell::IsFrameSelected() const
1294 if ( !Imp()->HasDrawView() )
1297 return nullptr != ::GetFlyFromMarked( &Imp()->GetDrawView()->GetMarkedObjectList(),
1298 const_cast<SwFEShell
*>(this) );
1301 bool SwFEShell::IsObjSelected( const SdrObject
& rObj
) const
1303 if ( IsFrameSelected() || !Imp()->HasDrawView() )
1306 return Imp()->GetDrawView()->IsObjMarked( &rObj
);
1309 bool SwFEShell::IsRotationOfSwGrfNodePossible() const
1311 // RotGrfFlyFrame: check if RotationMode is possible
1312 const SdrView
*pSdrView
= Imp()->GetDrawView();
1316 const SdrMarkList
& rList(pSdrView
->GetMarkedObjectList());
1318 if(1 == rList
.GetMarkCount())
1320 const SwVirtFlyDrawObj
* pVirtFlyDraw(dynamic_cast< const SwVirtFlyDrawObj
* >(rList
.GetMark(0)->GetMarkedSdrObj()));
1322 if(nullptr != pVirtFlyDraw
)
1324 return pVirtFlyDraw
->ContainsSwGrfNode();
1332 bool SwFEShell::IsObjSameLevelWithMarked(const SdrObject
* pObj
) const
1336 const SdrMarkList
& aMarkList
= Imp()->GetDrawView()->GetMarkedObjectList();
1337 if (aMarkList
.GetMarkCount() == 0)
1341 SdrMark
* pM
=aMarkList
.GetMark(0);
1344 SdrObject
* pMarkObj
= pM
->GetMarkedSdrObj();
1345 if (pMarkObj
&& pMarkObj
->getParentSdrObjectFromSdrObject() == pObj
->getParentSdrObjectFromSdrObject())
1352 void SwFEShell::EndTextEdit()
1354 // Terminate the TextEditMode. If required (default if the object
1355 // does not contain any more text and does not carry attributes) the object
1356 // is deleted. All other objects marked are preserved.
1358 OSL_ENSURE( Imp()->HasDrawView() && Imp()->GetDrawView()->IsTextEdit(),
1359 "EndTextEdit a no Object" );
1362 SdrView
*pView
= Imp()->GetDrawView();
1363 SdrObject
*pObj
= pView
->GetTextEditObject();
1364 SdrObjUserCall
* pUserCall
= GetUserCall(pObj
);
1365 if( nullptr != pUserCall
)
1367 SdrObject
*pTmp
= static_cast<SwContact
*>(pUserCall
)->GetMaster();
1370 pUserCall
->Changed( *pTmp
, SdrUserCallType::Resize
, pTmp
->GetLastBoundRect() );
1372 if ( !pObj
->getParentSdrObjectFromSdrObject() )
1374 if ( SdrEndTextEditKind::ShouldBeDeleted
== pView
->SdrEndTextEdit(true) )
1376 if ( pView
->GetMarkedObjectList().GetMarkCount() > 1 )
1378 SdrMarkList
aSave( pView
->GetMarkedObjectList() );
1379 aSave
.DeleteMark( aSave
.FindObject( pObj
) );
1380 if ( aSave
.GetMarkCount() )
1383 pView
->MarkObj( pObj
, Imp()->GetPageView() );
1386 for ( size_t i
= 0; i
< aSave
.GetMarkCount(); ++i
)
1387 pView
->MarkObj( aSave
.GetMark( i
)->GetMarkedSdrObj(), Imp()->GetPageView() );
1394 pView
->SdrEndTextEdit();
1396 if (comphelper::LibreOfficeKit::isActive())
1397 SfxLokHelper::notifyOtherViews(GetSfxViewShell(), LOK_CALLBACK_VIEW_LOCK
, "rectangle", "EMPTY");
1402 bool SwFEShell::IsInsideSelectedObj( const Point
&rPt
)
1404 if( Imp()->HasDrawView() )
1406 SwDrawView
*pDView
= Imp()->GetDrawView();
1408 if( pDView
->GetMarkedObjectList().GetMarkCount() &&
1409 pDView
->IsMarkedObjHit( rPt
) )
1417 bool SwFEShell::IsObjSelectable( const Point
& rPt
)
1419 CurrShell
aCurr(this);
1420 SwDrawView
*pDView
= Imp()->GetDrawView();
1425 const auto nOld
= pDView
->GetHitTolerancePixel();
1426 pDView
->SetHitTolerancePixel( pDView
->GetMarkHdlSizePixel()/2 );
1428 bRet
= pDView
->PickObj(rPt
, pDView
->getHitTolLog(), pPV
, SdrSearchOptions::PICKMARKABLE
) != nullptr;
1429 pDView
->SetHitTolerancePixel( nOld
);
1434 SdrObject
* SwFEShell::GetObjAt( const Point
& rPt
)
1436 SdrObject
* pRet
= nullptr;
1437 CurrShell
aCurr(this);
1438 SwDrawView
*pDView
= Imp()->GetDrawView();
1442 const auto nOld
= pDView
->GetHitTolerancePixel();
1443 pDView
->SetHitTolerancePixel( pDView
->GetMarkHdlSizePixel()/2 );
1445 pRet
= pDView
->PickObj(rPt
, pDView
->getHitTolLog(), pPV
, SdrSearchOptions::PICKMARKABLE
);
1446 pDView
->SetHitTolerancePixel( nOld
);
1451 // Test if there is an object at that position and if it should be selected.
1452 bool SwFEShell::ShouldObjectBeSelected(const Point
& rPt
)
1454 CurrShell
aCurr(this);
1455 SwDrawView
*pDrawView
= Imp()->GetDrawView();
1461 const auto nOld(pDrawView
->GetHitTolerancePixel());
1463 pDrawView
->SetHitTolerancePixel(pDrawView
->GetMarkHdlSizePixel()/2);
1464 SdrObject
* pObj
= pDrawView
->PickObj(rPt
, pDrawView
->getHitTolLog(), pPV
, SdrSearchOptions::PICKMARKABLE
);
1465 pDrawView
->SetHitTolerancePixel(nOld
);
1470 const IDocumentDrawModelAccess
& rIDDMA
= getIDocumentDrawModelAccess();
1472 // Do not select object in background which is overlapping this text
1473 // at the given position.
1474 bool bObjInBackground( false );
1476 if ( pObj
->GetLayer() == rIDDMA
.GetHellId() )
1478 const SwAnchoredObject
* pAnchoredObj
= ::GetUserCall( pObj
)->GetAnchoredObj( pObj
);
1479 const SwFrameFormat
& rFormat
= pAnchoredObj
->GetFrameFormat();
1480 const SwFormatSurround
& rSurround
= rFormat
.GetSurround();
1481 if ( rSurround
.GetSurround() == css::text::WrapTextMode_THROUGH
)
1483 bObjInBackground
= true;
1487 if ( bObjInBackground
)
1489 const SwPageFrame
* pPageFrame
= GetLayout()->GetPageAtPos( rPt
);
1492 const SwContentFrame
* pContentFrame( pPageFrame
->ContainsContent() );
1493 while ( pContentFrame
)
1495 if ( pContentFrame
->UnionFrame().Contains( rPt
) )
1497 const SwTextFrame
* pTextFrame
= pContentFrame
->DynCastTextFrame();
1500 SwPosition
aPos(GetDoc()->GetNodes());
1501 Point
aTmpPt( rPt
);
1502 if (pTextFrame
->GetKeyCursorOfst(&aPos
, aTmpPt
))
1504 SwRect aCursorCharRect
;
1505 if (pTextFrame
->GetCharRect(aCursorCharRect
,
1508 if ( aCursorCharRect
.Overlaps( SwRect( pObj
->GetLastBoundRect() ) ) )
1522 pContentFrame
= pContentFrame
->GetNextContentFrame();
1527 // Don't select header / footer objects in body edition and vice-versa
1528 SwContact
* pContact
= static_cast<SwContact
*>(pObj
->GetUserCall());
1529 if (pContact
&& !pContact
->ObjAnchoredAtPage() )
1531 const SwNode
& rAnchorNode
= pContact
->GetAnchorNode();
1532 bool bInHdrFtr
= GetDoc()->IsInHeaderFooter( rAnchorNode
);
1533 if (IsHeaderFooterEdit() != bInHdrFtr
)
1541 const SdrPage
* pPage
= rIDDMA
.GetDrawModel()->GetPage(0);
1542 for(size_t a
= pObj
->GetOrdNum()+1; bRet
&& a
< pPage
->GetObjCount(); ++a
)
1544 SdrObject
*pCandidate
= pPage
->GetObj(a
);
1546 SwVirtFlyDrawObj
* pDrawObj
= dynamic_cast<SwVirtFlyDrawObj
*>(pCandidate
);
1547 if (pDrawObj
&& pDrawObj
->GetCurrentBoundRect().Contains(rPt
))
1560 * If an object was selected, we assume its upper-left corner
1561 * otherwise the middle of the current CharRects.
1562 * Does the object include a control or groups,
1563 * which comprise only controls
1565 static bool lcl_IsControlGroup( const SdrObject
*pObj
)
1568 if(dynamic_cast<const SdrUnoObj
*>( pObj
) != nullptr)
1570 else if( auto pObjGroup
= dynamic_cast<const SdrObjGroup
*>( pObj
) )
1573 const SdrObjList
*pLst
= pObjGroup
->GetSubList();
1574 for ( size_t i
= 0; i
< pLst
->GetObjCount(); ++i
)
1575 if( !::lcl_IsControlGroup( pLst
->GetObj( i
) ) )
1583 class MarkableObjectsOnly
: public svx::ISdrObjectFilter
1586 explicit MarkableObjectsOnly( SdrPageView
* i_pPV
)
1591 virtual bool includeObject( const SdrObject
& i_rObject
) const override
1593 return m_pPV
&& m_pPV
->GetView().IsObjMarkable( &i_rObject
, m_pPV
);
1601 const SdrObject
* SwFEShell::GetBestObject(bool bNext
, GotoObjFlags eType
, bool bFlat
,
1602 const svx::ISdrObjectFilter
* pFilter
,
1608 if( !Imp()->HasDrawView() )
1611 const SdrObject
*pBest
= nullptr,
1614 const tools::Long nTmp
= bNext
? LONG_MAX
: 0;
1615 Point
aBestPos( nTmp
, nTmp
);
1616 Point
aTopPos( nTmp
, nTmp
);
1619 bool bNoDraw((GotoObjFlags::DrawAny
& eType
) == GotoObjFlags::NONE
);
1620 bool bNoFly((GotoObjFlags::FlyAny
& eType
) == GotoObjFlags::NONE
);
1622 if( !bNoFly
&& bNoDraw
)
1624 SwFlyFrame
*pFly
= GetCurrFrame( false )->FindFlyFrame();
1626 pBest
= pFly
->GetVirtDrawObj();
1628 const SdrMarkList
&rMrkList
= Imp()->GetDrawView()->GetMarkedObjectList();
1629 SdrPageView
* pPV
= Imp()->GetDrawView()->GetSdrPageView();
1631 MarkableObjectsOnly
aDefaultFilter( pPV
);
1633 pFilter
= &aDefaultFilter
;
1635 if( !pBest
|| rMrkList
.GetMarkCount() == 1 )
1637 // Determine starting point
1638 SdrObjList
* pList
= nullptr;
1639 if ( rMrkList
.GetMarkCount() )
1641 const SdrObject
* pStartObj
= rMrkList
.GetMark(0)->GetMarkedSdrObj();
1642 if( auto pVirtFlyDrawObj
= dynamic_cast<const SwVirtFlyDrawObj
*>( pStartObj
) )
1643 aPos
= pVirtFlyDrawObj
->GetFlyFrame()->getFrameArea().Pos();
1645 aPos
= pStartObj
->GetSnapRect().TopLeft();
1647 // If an object inside a group is selected, we want to
1648 // iterate over the group members.
1649 if ( ! pStartObj
->GetUserCall() )
1650 pList
= pStartObj
->getParentSdrObjListFromSdrObject();
1654 // If no object is selected, we check if we just entered a group.
1655 // In this case we want to iterate over the group members.
1656 aPos
= GetCharRect().Center();
1657 const SdrObject
* pStartObj
= pPV
? pPV
->GetCurrentGroup() : nullptr;
1658 if ( dynamic_cast<const SdrObjGroup
*>( pStartObj
) )
1659 pList
= pStartObj
->GetSubList();
1665 // A No object has been selected and no group has been entered or
1666 // B An object has been selected and it is not inside a group
1667 pList
= getIDocumentDrawModelAccess().GetDrawModel()->GetPage( 0 );
1670 OSL_ENSURE( pList
, "No object list to iterate" );
1672 SdrObjListIter
aObjIter( pList
, bFlat
? SdrIterMode::Flat
: SdrIterMode::DeepNoGroups
);
1673 while ( aObjIter
.IsMore() )
1675 SdrObject
* pObj
= aObjIter
.Next();
1676 SwVirtFlyDrawObj
*pVirtO
= dynamic_cast<SwVirtFlyDrawObj
*>(pObj
);
1677 if( ( bNoFly
&& pVirtO
) ||
1678 ( bNoDraw
&& !pVirtO
) ||
1679 // Ignore TextBoxes of draw shapes here, so that
1680 // SwFEShell::SelectObj() won't jump back on this list, meaning
1681 // we never jump to the next draw shape.
1682 (pVirtO
&& pVirtO
->IsTextBox()) ||
1683 ( eType
== GotoObjFlags::DrawSimple
&& lcl_IsControlGroup( pObj
) ) ||
1684 ( eType
== GotoObjFlags::DrawControl
&& !lcl_IsControlGroup( pObj
) ) ||
1685 !pFilter
->includeObject( *pObj
) )
1689 SwFlyFrame
*pFly
= pVirtO
->GetFlyFrame();
1690 if( GotoObjFlags::FlyAny
!= ( GotoObjFlags::FlyAny
& eType
) )
1694 case GotoObjFlags::FlyFrame
:
1695 if ( pFly
->Lower() && pFly
->Lower()->IsNoTextFrame() )
1698 case GotoObjFlags::FlyGrf
:
1699 if ( pFly
->Lower() &&
1700 (!pFly
->Lower()->IsNoTextFrame() ||
1701 !static_cast<SwNoTextFrame
*>(pFly
->Lower())->GetNode()->GetGrfNode()))
1704 case GotoObjFlags::FlyOLE
:
1705 if ( pFly
->Lower() &&
1706 (!pFly
->Lower()->IsNoTextFrame() ||
1707 !static_cast<SwNoTextFrame
*>(pFly
->Lower())->GetNode()->GetOLENode()))
1713 aCurPos
= pFly
->getFrameArea().Pos();
1716 aCurPos
= pObj
->GetSnapRect().TopLeft();
1718 // Special case if another object is on same Y.
1719 if( aCurPos
!= aPos
&& // only when it is not me
1720 aCurPos
.getY() == aPos
.getY() && // Y positions equal
1721 (bNext
? (aCurPos
.getX() > aPos
.getX()) : // lies next to me
1722 (aCurPos
.getX() < aPos
.getX())) ) // " reverse
1724 aBestPos
= Point( nTmp
, nTmp
);
1725 SdrObjListIter
aTmpIter( pList
, bFlat
? SdrIterMode::Flat
: SdrIterMode::DeepNoGroups
);
1726 while ( aTmpIter
.IsMore() )
1728 SdrObject
* pTmpObj
= aTmpIter
.Next();
1729 pVirtO
= dynamic_cast<SwVirtFlyDrawObj
*>(pTmpObj
);
1730 if( ( bNoFly
&& pVirtO
) || ( bNoDraw
&& !pVirtO
) )
1734 aCurPos
= pVirtO
->GetFlyFrame()->getFrameArea().Pos();
1737 aCurPos
= pTmpObj
->GetCurrentBoundRect().TopLeft();
1739 if( aCurPos
!= aPos
&& aCurPos
.Y() == aPos
.Y() &&
1740 (bNext
? (aCurPos
.getX() > aPos
.getX()) : // lies next to me
1741 (aCurPos
.getX() < aPos
.getX())) && // " reverse
1742 (bNext
? (aCurPos
.getX() < aBestPos
.getX()) : // better as best
1743 (aCurPos
.getX() > aBestPos
.getX())) ) // " reverse
1753 (bNext
? (aPos
.getY() < aCurPos
.getY()) : // only below me
1754 (aPos
.getY() > aCurPos
.getY())) && // " reverse
1755 (bNext
? (aBestPos
.getY() > aCurPos
.getY()) : // closer below
1756 (aBestPos
.getY() < aCurPos
.getY()))
1758 (aBestPos
.getY() == aCurPos
.getY() &&
1759 (bNext
? (aBestPos
.getX() > aCurPos
.getX()) : // further left
1760 (aBestPos
.getX() < aCurPos
.getX())))) // " reverse
1767 if( (bNext
? (aTopPos
.getY() > aCurPos
.getY()) : // higher as best
1768 (aTopPos
.getY() < aCurPos
.getY())) || // " reverse
1769 (aTopPos
.getY() == aCurPos
.getY() &&
1770 (bNext
? (aTopPos
.getX() > aCurPos
.getX()) : // further left
1771 (aTopPos
.getX() < aCurPos
.getX())))) // " reverse
1777 // unfortunately nothing found
1778 if( bNext
? (aBestPos
.getX() == LONG_MAX
) : (aBestPos
.getX() == 0) )
1781 if (pbWrapped
&& pBest
)
1789 bool SwFEShell::GotoObj( bool bNext
, GotoObjFlags eType
)
1791 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::Empty
);
1793 bool bWrapped(false);
1794 const SdrObject
* pBest
= GetBestObject(bNext
, eType
, true, nullptr, &bWrapped
);
1798 SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::NavElementNotFound
);
1802 const SwVirtFlyDrawObj
*pVirtO
= dynamic_cast<const SwVirtFlyDrawObj
*>(pBest
);
1805 const SwRect
& rFrame
= pVirtO
->GetFlyFrame()->getFrameArea();
1806 SelectObj( rFrame
.Pos(), 0, const_cast<SdrObject
*>(pBest
) );
1808 MakeVisible( rFrame
);
1812 SelectObj( Point(), 0, const_cast<SdrObject
*>(pBest
) );
1814 MakeVisible( SwRect(pBest
->GetCurrentBoundRect()) );
1819 SvxSearchDialogWrapper::SetSearchLabel(bNext
? SearchLabel::EndWrapped
:
1820 SearchLabel::StartWrapped
);
1825 bool SwFEShell::BeginCreate( SdrObjKind eSdrObjectKind
, const Point
&rPos
)
1829 if ( !Imp()->HasDrawView() )
1830 Imp()->MakeDrawView();
1832 if ( GetPageNumber( rPos
) )
1834 Imp()->GetDrawView()->SetCurrentObj( eSdrObjectKind
);
1835 if ( eSdrObjectKind
== SdrObjKind::Caption
)
1836 bRet
= Imp()->GetDrawView()->BegCreateCaptionObj(
1837 rPos
, Size( lMinBorder
- MINFLY
, lMinBorder
- MINFLY
),
1840 bRet
= Imp()->GetDrawView()->BegCreateObj( rPos
, GetOut() );
1844 ::FrameNotify( this, FLY_DRAG_START
);
1849 bool SwFEShell::BeginCreate( SdrObjKind eSdrObjectKind
, SdrInventor eObjInventor
,
1854 if ( !Imp()->HasDrawView() )
1855 Imp()->MakeDrawView();
1857 if ( GetPageNumber( rPos
) )
1859 Imp()->GetDrawView()->SetCurrentObj( eSdrObjectKind
, eObjInventor
);
1860 bRet
= Imp()->GetDrawView()->BegCreateObj( rPos
, GetOut() );
1863 ::FrameNotify( this, FLY_DRAG_START
);
1867 void SwFEShell::MoveCreate( const Point
&rPos
)
1869 OSL_ENSURE( Imp()->HasDrawView(), "MoveCreate without DrawView?" );
1870 if ( GetPageNumber( rPos
) )
1873 Imp()->GetDrawView()->MovCreateObj( rPos
);
1874 ::FrameNotify( this );
1878 bool SwFEShell::EndCreate( SdrCreateCmd eSdrCreateCmd
)
1880 // To assure undo-object from the DrawEngine is not stored,
1881 // (we create our own undo-object!), temporarily switch-off Undo
1882 OSL_ENSURE( Imp()->HasDrawView(), "EndCreate without DrawView?" );
1883 if( !Imp()->GetDrawView()->IsGroupEntered() )
1885 GetDoc()->GetIDocumentUndoRedo().DoDrawUndo(false);
1887 bool bCreate
= Imp()->GetDrawView()->EndCreateObj( eSdrCreateCmd
);
1888 GetDoc()->GetIDocumentUndoRedo().DoDrawUndo(true);
1892 ::FrameNotify( this, FLY_DRAG_END
);
1896 if ( eSdrCreateCmd
== SdrCreateCmd::NextPoint
)
1898 ::FrameNotify( this );
1901 return ImpEndCreate();
1904 bool SwFEShell::ImpEndCreate()
1906 if (Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() == 0)
1909 SdrObject
& rSdrObj
= *Imp()->GetDrawView()->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj();
1911 if( rSdrObj
.GetSnapRect().IsEmpty() )
1913 // preferably we forget the object, only gives problems
1914 Imp()->GetDrawView()->DeleteMarked();
1915 Imp()->GetDrawView()->UnmarkAll();
1916 ::FrameNotify( this, FLY_DRAG_END
);
1920 if( rSdrObj
.getParentSdrObjectFromSdrObject() )
1922 Point
aTmpPos( rSdrObj
.GetSnapRect().TopLeft() );
1923 Point
aNewAnchor( rSdrObj
.getParentSdrObjectFromSdrObject()->GetAnchorPos() );
1924 // OD 2004-04-05 #i26791# - direct object positioning for group members
1925 rSdrObj
.NbcSetRelativePos( aTmpPos
- aNewAnchor
);
1926 rSdrObj
.NbcSetAnchorPos( aNewAnchor
);
1927 ::FrameNotify( this );
1931 LockPaint(LockPaintReason::EndSdrCreate
);
1934 Imp()->GetDrawView()->UnmarkAll();
1936 const tools::Rectangle
&rBound
= rSdrObj
.GetSnapRect();
1937 Point
aPt( rBound
.TopRight() );
1939 // default for controls character bound, otherwise paragraph bound.
1940 SwFormatAnchor aAnch
;
1941 const SwFrame
*pAnch
= nullptr;
1942 bool bCharBound
= false;
1943 if( dynamic_cast<const SdrUnoObj
*>( &rSdrObj
) != nullptr )
1945 SwPosition
aPos( GetDoc()->GetNodes() );
1946 SwCursorMoveState
aState( CursorMoveState::SetOnlyText
);
1947 Point
aPoint( aPt
.getX(), aPt
.getY() + rBound
.GetHeight()/2 );
1948 GetLayout()->GetModelPositionForViewPoint( &aPos
, aPoint
, &aState
);
1950 // characterbinding not allowed in readonly-content
1951 if( !aPos
.GetNode().IsProtect() )
1953 std::pair
<Point
, bool> const tmp(aPoint
, true);
1954 pAnch
= aPos
.GetNode().GetContentNode()->getLayoutFrame(GetLayout(), &aPos
, &tmp
);
1956 pAnch
->GetCharRect( aTmp
, aPos
);
1958 // The crsr should not be too far away
1960 constexpr tools::Long constTwips_1cm
= o3tl::toTwips(1, o3tl::Length::cm
);
1961 tools::Rectangle
aRect( aTmp
.SVRect() );
1962 // Extend by 1 cm in each direction
1963 aRect
.AdjustLeft(-constTwips_1cm
);
1964 aRect
.AdjustTop(-constTwips_1cm
);
1965 aRect
.AdjustRight(constTwips_1cm
);
1966 aRect
.AdjustBottom(constTwips_1cm
);
1968 if( !aRect
.Overlaps( rBound
) && !::GetHtmlMode( GetDoc()->GetDocShell() ))
1971 // anchor in header/footer also not allowed.
1973 bCharBound
= !GetDoc()->IsInHeaderFooter( aPos
.GetNode() );
1977 aAnch
.SetType( RndStdIds::FLY_AS_CHAR
);
1978 aAnch
.SetAnchor( &aPos
);
1985 // allow native drawing objects in header/footer.
1986 // Thus, set <bBodyOnly> to <false> for these objects using value
1987 // of <nIdent> - value <0xFFFF> indicates control objects, which aren't
1988 // allowed in header/footer.
1989 //bool bBodyOnly = OBJ_NONE != nIdent;
1990 bool bBodyOnly
= SdrInventor::Default
!= rSdrObj
.GetObjInventor();
1991 bool bAtPage
= false;
1992 const SwFrame
* pPage
= nullptr;
1993 SwCursorMoveState
aState( CursorMoveState::SetOnlyText
);
1994 Point
aPoint( aPt
);
1995 SwPosition
aPos( GetDoc()->GetNodes() );
1996 GetLayout()->GetModelPositionForViewPoint( &aPos
, aPoint
, &aState
);
1998 // do not set in ReadnOnly-content
1999 if (aPos
.GetNode().IsProtect())
2001 // then only page bound. Or should we
2002 // search the next not-readonly position?
2006 SwContentNode
* pCNode
= aPos
.GetNode().GetContentNode();
2007 std::pair
<Point
, bool> const tmp(aPoint
, false);
2008 pAnch
= pCNode
? pCNode
->getLayoutFrame(GetLayout(), nullptr, &tmp
) : nullptr;
2011 // Hidden content. Anchor to the page instead
2017 const SwFlyFrame
*pTmp
= pAnch
->FindFlyFrame();
2020 const SwFrame
* pTmpFrame
= pAnch
;
2021 SwRect
aBound( rBound
);
2024 if( pTmp
->getFrameArea().Contains( aBound
) )
2026 if( !bBodyOnly
|| !pTmp
->FindFooterOrHeader() )
2030 pTmp
= pTmp
->GetAnchorFrame()
2031 ? pTmp
->GetAnchorFrame()->FindFlyFrame()
2038 pPage
= pAnch
->FindPageFrame();
2040 // Always via FindAnchor, to assure the frame will be bound
2041 // to the previous. With GetCrsOfst we can also reach the next. THIS IS WRONG.
2042 pAnch
= ::FindAnchor( pPage
, aPt
, bBodyOnly
);
2043 if (pAnch
->IsTextFrame())
2045 std::pair
<SwTextNode
const*, sal_Int32
> const pos(
2046 static_cast<SwTextFrame
const*>(pAnch
)->MapViewToModel(TextFrameIndex(0)));
2047 aPos
.Assign( *pos
.first
);
2051 aPos
.Assign( *static_cast<const SwNoTextFrame
*>(pAnch
)->GetNode() );
2054 // do not set in ReadnOnly-content
2055 if( aPos
.GetNode().IsProtect() )
2056 // then only page bound. Or should we
2057 // search the next not-readonly position?
2061 aAnch
.SetType( RndStdIds::FLY_AT_PARA
);
2062 aAnch
.SetAnchor( &aPos
);
2068 pPage
= pAnch
? pAnch
->FindPageFrame() : GetLayout()->GetPageAtPos(aPoint
);
2070 aAnch
.SetType( RndStdIds::FLY_AT_PAGE
);
2071 aAnch
.SetPageNum( pPage
->GetPhyPageNum() );
2072 pAnch
= pPage
; // page becomes an anchor
2076 SfxItemSetFixed
<RES_FRM_SIZE
, RES_FRM_SIZE
,
2077 RES_SURROUND
, RES_ANCHOR
> aSet( GetDoc()->GetAttrPool() );
2080 // OD 2004-03-30 #i26791# - determine relative object position
2082 SwTwips nYOffset
= rBound
.Top() - pAnch
->getFrameArea().Top();
2084 if( pAnch
->IsVertical() )
2086 nXOffset
= nYOffset
;
2087 nYOffset
= pAnch
->getFrameArea().Left()+pAnch
->getFrameArea().Width()-rBound
.Right();
2089 else if( pAnch
->IsRightToLeft() )
2090 nXOffset
= pAnch
->getFrameArea().Left()+pAnch
->getFrameArea().Width()-rBound
.Right();
2092 nXOffset
= rBound
.Left() - pAnch
->getFrameArea().Left();
2093 if (pAnch
->IsTextFrame())
2095 const SwTextFrame
* pTmp
= static_cast<const SwTextFrame
*>(pAnch
);
2096 if (pTmp
->IsFollow())
2099 pTmp
= pTmp
->FindMaster();
2100 OSL_ENSURE(pTmp
, "Where's my Master?");
2101 // OD 2004-03-30 #i26791# - correction: add frame area height
2102 // of master frames.
2103 nYOffset
+= pTmp
->IsVertical() ?
2104 pTmp
->getFrameArea().Width() : pTmp
->getFrameArea().Height();
2105 } while (pTmp
->IsFollow());
2108 nYOffset
-= pTmp
->GetBaseVertOffsetForFly(false);
2112 if (SdrInventor::Default
== rSdrObj
.GetObjInventor() && rSdrObj
.GetObjIdentifier() == SdrObjKind::NewFrame
)
2114 // For OBJ_NONE a fly is inserted.
2115 const tools::Long nWidth
= rBound
.Right() - rBound
.Left();
2116 const tools::Long nHeight
= rBound
.Bottom() - rBound
.Top();
2117 aSet
.Put( SwFormatFrameSize( SwFrameSize::Minimum
, std::max( nWidth
, tools::Long(MINFLY
) ),
2118 std::max( nHeight
, tools::Long(MINFLY
) )));
2120 SwFormatHoriOrient
aHori( nXOffset
, text::HoriOrientation::NONE
, text::RelOrientation::FRAME
);
2121 SwFormatVertOrient
aVert( nYOffset
, text::VertOrientation::NONE
, text::RelOrientation::FRAME
);
2122 aSet
.Put( SwFormatSurround( css::text::WrapTextMode_PARALLEL
) );
2126 // Quickly store the square
2127 const SwRect
aFlyRect( rBound
);
2129 // Throw away generated object, now the fly can nicely
2130 // via the available SS be generated.
2131 GetDoc()->GetIDocumentUndoRedo().DoDrawUndo(false); // see above
2132 // #i52858# - method name changed
2133 SdrPage
*pPg
= getIDocumentDrawModelAccess().GetOrCreateDrawModel()->GetPage( 0 );
2136 SdrModel
* pTmpSdrModel
= getIDocumentDrawModelAccess().GetDrawModel();
2137 auto pNewPage
= pTmpSdrModel
->AllocPage( false );
2138 pTmpSdrModel
->InsertPage( pNewPage
.get() );
2139 pPg
= pNewPage
.get();
2141 pPg
->RecalcObjOrdNums();
2142 pPg
->RemoveObject( rSdrObj
.GetOrdNumDirect() );
2143 GetDoc()->GetIDocumentUndoRedo().DoDrawUndo(true);
2145 SwFlyFrame
* pFlyFrame
;
2146 if( NewFlyFrame( aSet
, true ) &&
2147 ::GetHtmlMode( GetDoc()->GetDocShell() ) &&
2148 nullptr != ( pFlyFrame
= GetSelectedFlyFrame() ))
2150 SfxItemSetFixed
<RES_VERT_ORIENT
, RES_HORI_ORIENT
> aHtmlSet( GetDoc()->GetAttrPool() );
2151 // horizontal orientation:
2152 const bool bLeftFrame
= aFlyRect
.Left() <
2153 pAnch
->getFrameArea().Left() + pAnch
->getFramePrintArea().Left(),
2154 bLeftPrt
= aFlyRect
.Left() + aFlyRect
.Width() <
2155 pAnch
->getFrameArea().Left() + pAnch
->getFramePrintArea().Width()/2;
2156 if( bLeftFrame
|| bLeftPrt
)
2158 aHori
.SetHoriOrient( text::HoriOrientation::LEFT
);
2159 aHori
.SetRelationOrient( bLeftFrame
? text::RelOrientation::FRAME
: text::RelOrientation::PRINT_AREA
);
2163 const bool bRightFrame
= aFlyRect
.Left() >
2164 pAnch
->getFrameArea().Left() + pAnch
->getFramePrintArea().Width();
2165 aHori
.SetHoriOrient( text::HoriOrientation::RIGHT
);
2166 aHori
.SetRelationOrient( bRightFrame
? text::RelOrientation::FRAME
: text::RelOrientation::PRINT_AREA
);
2168 aHtmlSet
.Put( aHori
);
2169 aVert
.SetVertOrient( text::VertOrientation::TOP
);
2170 aVert
.SetRelationOrient( text::RelOrientation::PRINT_AREA
);
2171 aHtmlSet
.Put( aVert
);
2173 GetDoc()->SetAttr( aHtmlSet
, *pFlyFrame
->GetFormat() );
2178 if (rSdrObj
.GetName().isEmpty())
2180 bool bRestore
= GetDoc()->GetIDocumentUndoRedo().DoesDrawUndo();
2181 GetDoc()->GetIDocumentUndoRedo().DoDrawUndo(false);
2182 rSdrObj
.MakeNameUnique();
2183 GetDoc()->GetIDocumentUndoRedo().DoDrawUndo(bRestore
);
2187 aSet
.Put( SwFormatSurround( css::text::WrapTextMode_THROUGH
) );
2188 // OD 2004-03-30 #i26791# - set horizontal position
2189 SwFormatHoriOrient
aHori( nXOffset
, text::HoriOrientation::NONE
, text::RelOrientation::FRAME
);
2191 // OD 2004-03-30 #i26791# - set vertical position
2192 if( pAnch
->IsTextFrame() && static_cast<const SwTextFrame
*>(pAnch
)->IsFollow() )
2194 const SwTextFrame
* pTmp
= static_cast<const SwTextFrame
*>(pAnch
);
2196 pTmp
= pTmp
->FindMaster();
2197 assert(pTmp
&& "Where's my Master?");
2198 nYOffset
+= pTmp
->IsVertical() ?
2199 pTmp
->getFramePrintArea().Width() : pTmp
->getFramePrintArea().Height();
2200 } while ( pTmp
->IsFollow() );
2202 SwFormatVertOrient
aVert( nYOffset
, text::VertOrientation::NONE
, text::RelOrientation::FRAME
);
2204 SwDrawFrameFormat
* pFormat
= static_cast<SwDrawFrameFormat
*>(getIDocumentLayoutAccess().MakeLayoutFormat( RndStdIds::DRAW_OBJECT
, &aSet
));
2205 // #i36010# - set layout direction of the position
2206 pFormat
->SetPositionLayoutDir(
2207 text::PositionLayoutDir::PositionInLayoutDirOfAnchor
);
2208 // #i44344#, #i44681# - positioning attributes already set
2209 pFormat
->PosAttrSet();
2210 pFormat
->SetFormatName(rSdrObj
.GetName());
2212 SwDrawContact
*pContact
= new SwDrawContact( pFormat
, &rSdrObj
);
2214 pContact
->MoveObjToVisibleLayer( &rSdrObj
);
2217 OSL_ENSURE( aAnch
.GetAnchorId() == RndStdIds::FLY_AS_CHAR
, "wrong AnchorType" );
2218 SwTextNode
*pNd
= aAnch
.GetAnchorNode()->GetTextNode();
2219 SwFormatFlyCnt
aFormat( pFormat
);
2220 pNd
->InsertItem(aFormat
,
2221 aAnch
.GetAnchorContentOffset(), 0 );
2222 SwFormatVertOrient
aVertical( pFormat
->GetVertOrient() );
2223 aVertical
.SetVertOrient( text::VertOrientation::LINE_CENTER
);
2224 pFormat
->SetFormatAttr( aVertical
);
2226 if( pAnch
->IsTextFrame() && static_cast<const SwTextFrame
*>(pAnch
)->IsFollow() )
2228 const SwTextFrame
* pTmp
= static_cast<const SwTextFrame
*>(pAnch
);
2230 pTmp
= pTmp
->FindMaster();
2231 OSL_ENSURE( pTmp
, "Where's my Master?" );
2232 } while( pTmp
->IsFollow() );
2236 pContact
->ConnectToLayout();
2238 // mark object at frame the object is inserted at.
2240 SdrObject
* pMarkObj
= pContact
->GetDrawObjectByAnchorFrame( *pAnch
);
2243 Imp()->GetDrawView()->MarkObj( pMarkObj
, Imp()->GetPageView() );
2247 Imp()->GetDrawView()->MarkObj( &rSdrObj
, Imp()->GetPageView() );
2252 GetDoc()->getIDocumentState().SetModified();
2255 EndAllActionAndCall();
2260 void SwFEShell::BreakCreate()
2262 OSL_ENSURE( Imp()->HasDrawView(), "BreakCreate without DrawView?" );
2263 Imp()->GetDrawView()->BrkCreateObj();
2264 ::FrameNotify( this, FLY_DRAG_END
);
2267 bool SwFEShell::IsDrawCreate() const
2269 return Imp()->HasDrawView() && Imp()->GetDrawView()->IsCreateObj();
2272 bool SwFEShell::BeginMark( const Point
&rPos
)
2274 if ( !Imp()->HasDrawView() )
2275 Imp()->MakeDrawView();
2277 if ( GetPageNumber( rPos
) )
2279 SwDrawView
* pDView
= Imp()->GetDrawView();
2281 if (pDView
->HasMarkablePoints())
2282 return pDView
->BegMarkPoints( rPos
);
2285 pDView
->BegMarkObj( rPos
);
2293 void SwFEShell::MoveMark( const Point
&rPos
)
2295 OSL_ENSURE( Imp()->HasDrawView(), "MoveMark without DrawView?" );
2297 if ( GetPageNumber( rPos
) )
2300 SwDrawView
* pDView
= Imp()->GetDrawView();
2302 if (pDView
->IsInsObjPoint())
2303 pDView
->MovInsObjPoint( rPos
);
2304 else if (pDView
->IsMarkPoints())
2305 pDView
->MovMarkPoints( rPos
);
2307 pDView
->MovAction( rPos
);
2311 bool SwFEShell::EndMark()
2314 OSL_ENSURE( Imp()->HasDrawView(), "EndMark without DrawView?" );
2316 if (Imp()->GetDrawView()->IsMarkObj())
2318 bRet
= Imp()->GetDrawView()->EndMarkObj();
2322 bool bShowHdl
= false;
2323 SwDrawView
* pDView
= Imp()->GetDrawView();
2324 // frames are not selected this way, except when
2325 // it is only one frame
2326 SdrMarkList
&rMrkList
= const_cast<SdrMarkList
&>(pDView
->GetMarkedObjectList());
2327 SwFlyFrame
* pOldSelFly
= ::GetFlyFromMarked( &rMrkList
, this );
2329 if ( rMrkList
.GetMarkCount() > 1 )
2330 for ( size_t i
= 0; i
< rMrkList
.GetMarkCount(); ++i
)
2332 SdrObject
*pObj
= rMrkList
.GetMark( i
)->GetMarkedSdrObj();
2333 if( dynamic_cast<const SwVirtFlyDrawObj
*>( pObj
) != nullptr )
2339 rMrkList
.DeleteMark( i
);
2340 --i
; // no exceptions
2346 pDView
->MarkListHasChanged();
2347 pDView
->AdjustMarkHdl();
2350 if ( rMrkList
.GetMarkCount() )
2351 ::lcl_GrabCursor(this, pOldSelFly
);
2356 ::FrameNotify( this, FLY_DRAG_START
);
2360 if (Imp()->GetDrawView()->IsMarkPoints())
2361 bRet
= Imp()->GetDrawView()->EndMarkPoints();
2368 RndStdIds
SwFEShell::GetAnchorId() const
2370 RndStdIds nRet
= RndStdIds(SHRT_MAX
);
2371 if ( Imp()->HasDrawView() )
2373 const SdrMarkList
&rMrkList
= Imp()->GetDrawView()->GetMarkedObjectList();
2374 for ( size_t i
= 0; i
< rMrkList
.GetMarkCount(); ++i
)
2376 SdrObject
*pObj
= rMrkList
.GetMark( i
)->GetMarkedSdrObj();
2377 if ( dynamic_cast<const SwVirtFlyDrawObj
*>( pObj
) != nullptr )
2379 nRet
= RndStdIds::UNKNOWN
;
2382 SwDrawContact
*pContact
= static_cast<SwDrawContact
*>(GetUserCall(pObj
));
2383 RndStdIds nId
= pContact
->GetFormat()->GetAnchor().GetAnchorId();
2384 if ( nRet
== RndStdIds(SHRT_MAX
) )
2386 else if ( nRet
!= nId
)
2388 nRet
= RndStdIds::UNKNOWN
;
2393 if ( nRet
== RndStdIds(SHRT_MAX
) )
2394 nRet
= RndStdIds::UNKNOWN
;
2398 void SwFEShell::ChgAnchor( RndStdIds eAnchorId
, bool bSameOnly
, bool bPosCorr
)
2400 OSL_ENSURE( Imp()->HasDrawView(), "ChgAnchor without DrawView?" );
2401 const SdrMarkList
&rMrkList
= Imp()->GetDrawView()->GetMarkedObjectList();
2402 if( rMrkList
.GetMarkCount() &&
2403 !rMrkList
.GetMark( 0 )->GetMarkedSdrObj()->getParentSdrObjectFromSdrObject() )
2407 if( GetDoc()->ChgAnchor( rMrkList
, eAnchorId
, bSameOnly
, bPosCorr
))
2408 Imp()->GetDrawView()->UnmarkAll();
2412 ::FrameNotify( this );
2416 void SwFEShell::DelSelectedObj()
2418 OSL_ENSURE( Imp()->HasDrawView(), "DelSelectedObj(), no DrawView available" );
2419 if ( Imp()->HasDrawView() )
2422 Imp()->GetDrawView()->DeleteMarked();
2424 ::FrameNotify( this, FLY_DRAG_END
);
2428 // For the statusline to request the current conditions
2429 Size
SwFEShell::GetObjSize() const
2431 tools::Rectangle aRect
;
2432 if ( Imp()->HasDrawView() )
2434 if ( Imp()->GetDrawView()->IsAction() )
2435 Imp()->GetDrawView()->TakeActionRect( aRect
);
2437 aRect
= Imp()->GetDrawView()->GetAllMarkedRect();
2439 return aRect
.GetSize();
2442 Point
SwFEShell::GetAnchorObjDiff() const
2444 const SdrView
*pView
= Imp()->GetDrawView();
2445 OSL_ENSURE( pView
, "GetAnchorObjDiff without DrawView?" );
2447 tools::Rectangle aRect
;
2448 if ( Imp()->GetDrawView()->IsAction() )
2449 Imp()->GetDrawView()->TakeActionRect( aRect
);
2451 aRect
= Imp()->GetDrawView()->GetAllMarkedRect();
2453 Point
aRet( aRect
.TopLeft() );
2455 if ( IsFrameSelected() )
2457 SwFlyFrame
*pFly
= GetSelectedFlyFrame();
2458 aRet
-= pFly
->GetAnchorFrame()->getFrameArea().Pos();
2462 const SdrObject
*pObj
= pView
->GetMarkedObjectList().GetMarkCount() == 1 ?
2463 pView
->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj() : nullptr;
2465 aRet
-= pObj
->GetAnchorPos();
2471 Point
SwFEShell::GetObjAbsPos() const
2473 OSL_ENSURE( Imp()->GetDrawView(), "GetObjAbsPos() without DrawView?" );
2474 return Imp()->GetDrawView()->GetDragStat().GetActionRect().TopLeft();
2477 bool SwFEShell::IsGroupSelected(bool bAllowDiagams
)
2479 if ( IsObjSelected() )
2481 const SdrMarkList
&rMrkList
= Imp()->GetDrawView()->GetMarkedObjectList();
2482 for ( size_t i
= 0; i
< rMrkList
.GetMarkCount(); ++i
)
2484 SdrObject
*pObj
= rMrkList
.GetMark( i
)->GetMarkedSdrObj();
2485 // consider 'virtual' drawing objects.
2486 // Thus, use corresponding method instead of checking type.
2487 if ( pObj
->IsGroupObject() &&
2488 // --> #i38505# No ungroup allowed for 3d objects
2490 RndStdIds::FLY_AS_CHAR
!= static_cast<SwDrawContact
*>(GetUserCall(pObj
))->
2491 GetFormat()->GetAnchor().GetAnchorId() )
2495 // Don't allow enter Diagrams
2496 if(pObj
->isDiagram())
2511 bool HasSuitableGroupingAnchor(const SdrObject
* pObj
)
2513 bool bSuitable
= true;
2514 SwFrameFormat
* pFrameFormat(::FindFrameFormat(const_cast<SdrObject
*>(pObj
)));
2517 OSL_FAIL( "<HasSuitableGroupingAnchor> - missing frame format" );
2520 else if (RndStdIds::FLY_AS_CHAR
== pFrameFormat
->GetAnchor().GetAnchorId())
2528 // Change return type.
2529 // Adjustments for drawing objects in header/footer:
2530 // allow group, only if all selected objects are in the same header/footer
2531 // or not in header/footer.
2532 bool SwFEShell::IsGroupAllowed() const
2534 bool bIsGroupAllowed
= false;
2535 if ( IsObjSelected() > 1 )
2537 bIsGroupAllowed
= true;
2538 const SdrObject
* pUpGroup
= nullptr;
2539 const SwFrame
* pHeaderFooterFrame
= nullptr;
2540 const SdrMarkList
&rMrkList
= Imp()->GetDrawView()->GetMarkedObjectList();
2541 for ( size_t i
= 0; bIsGroupAllowed
&& i
< rMrkList
.GetMarkCount(); ++i
)
2543 const SdrObject
* pObj
= rMrkList
.GetMark( i
)->GetMarkedSdrObj();
2545 bIsGroupAllowed
= pObj
->getParentSdrObjectFromSdrObject() == pUpGroup
;
2547 pUpGroup
= pObj
->getParentSdrObjectFromSdrObject();
2549 if ( bIsGroupAllowed
)
2550 bIsGroupAllowed
= HasSuitableGroupingAnchor(pObj
);
2552 // check, if all selected objects are in the
2553 // same header/footer or not in header/footer.
2554 if ( bIsGroupAllowed
)
2556 const SwFrame
* pAnchorFrame
= nullptr;
2557 if ( auto pVirtFlyDrawObj
= dynamic_cast<const SwVirtFlyDrawObj
*>( pObj
) )
2559 const SwFlyFrame
* pFlyFrame
= pVirtFlyDrawObj
->GetFlyFrame();
2562 pAnchorFrame
= pFlyFrame
->GetAnchorFrame();
2567 SwDrawContact
* pDrawContact
= static_cast<SwDrawContact
*>(GetUserCall( pObj
));
2570 pAnchorFrame
= pDrawContact
->GetAnchorFrame( pObj
);
2578 ( pAnchorFrame
->FindFooterOrHeader() == pHeaderFooterFrame
);
2582 pHeaderFooterFrame
= pAnchorFrame
->FindFooterOrHeader();
2589 return bIsGroupAllowed
;
2592 bool SwFEShell::IsUnGroupAllowed() const
2594 bool bIsUnGroupAllowed
= false;
2596 const SdrMarkList
&rMrkList
= Imp()->GetDrawView()->GetMarkedObjectList();
2597 for (size_t i
= 0; i
< rMrkList
.GetMarkCount(); ++i
)
2599 const SdrObject
* pObj
= rMrkList
.GetMark(i
)->GetMarkedSdrObj();
2600 bIsUnGroupAllowed
= HasSuitableGroupingAnchor(pObj
);
2601 if (!bIsUnGroupAllowed
)
2605 return bIsUnGroupAllowed
;
2608 // The group gets the anchor and the contactobject of the first in the selection
2609 void SwFEShell::GroupSelection()
2611 if ( IsGroupAllowed() )
2614 StartUndo( SwUndoId::START
);
2616 GetDoc()->GroupSelection( *Imp()->GetDrawView() );
2618 EndUndo( SwUndoId::END
);
2623 // The individual objects get a copy of the anchor and the contactobject of the group
2624 void SwFEShell::UnGroupSelection()
2626 if ( IsGroupSelected(true) )
2629 StartUndo( SwUndoId::START
);
2631 GetDoc()->UnGroupSelection( *Imp()->GetDrawView() );
2633 EndUndo( SwUndoId::END
);
2638 void SwFEShell::MirrorSelection( bool bHorizontal
)
2640 SdrView
*pView
= Imp()->GetDrawView();
2641 if ( IsObjSelected() && pView
->IsMirrorAllowed() )
2644 pView
->MirrorAllMarkedHorizontal();
2646 pView
->MirrorAllMarkedVertical();
2650 // jump to named frame (Graphic/OLE)
2652 bool SwFEShell::GotoFly( const OUString
& rName
, FlyCntType eType
, bool bSelFrame
)
2655 static SwNodeType
const aChkArr
[ 4 ] = {
2656 /* FLYCNTTYPE_ALL */ SwNodeType::NONE
,
2657 /* FLYCNTTYPE_FRM */ SwNodeType::Text
,
2658 /* FLYCNTTYPE_GRF */ SwNodeType::Grf
,
2659 /* FLYCNTTYPE_OLE */ SwNodeType::Ole
2662 const SwFlyFrameFormat
* pFlyFormat
= mxDoc
->FindFlyByName( rName
, aChkArr
[ eType
]);
2665 CurrShell
aCurr( this );
2667 SwFlyFrame
* pFrame
= SwIterator
<SwFlyFrame
,SwFormat
>( *pFlyFormat
).First();
2672 // first make visible, to get a11y events in proper order
2674 MakeVisible( pFrame
->getFrameArea() );
2675 SelectObj( pFrame
->getFrameArea().Pos(), 0, pFrame
->GetVirtDrawObj() );
2679 SwContentFrame
*pCFrame
= pFrame
->ContainsContent();
2683 SwPaM
* pCursor
= GetCursor();
2685 if (pCFrame
->IsTextFrame())
2687 *pCursor
->GetPoint() = static_cast<SwTextFrame
*>(pCFrame
)
2688 ->MapViewToModelPos(TextFrameIndex(0));
2692 assert(pCFrame
->IsNoTextFrame());
2693 SwContentNode
*const pCNode
= static_cast<SwNoTextFrame
*>(pCFrame
)->GetNode();
2695 pCursor
->GetPoint()->Assign(*pCNode
);
2698 SwRect
& rChrRect
= const_cast<SwRect
&>(GetCharRect());
2699 rChrRect
= pFrame
->getFramePrintArea();
2700 rChrRect
.Pos() += pFrame
->getFrameArea().Pos();
2701 GetCursorDocPos() = rChrRect
.Pos();
2710 size_t SwFEShell::GetFlyCount( FlyCntType eType
, bool bIgnoreTextBoxes
) const
2712 return GetDoc()->GetFlyCount(eType
, bIgnoreTextBoxes
);
2715 const SwFrameFormat
* SwFEShell::GetFlyNum(size_t nIdx
, FlyCntType eType
, bool bIgnoreTextBoxes
) const
2717 return GetDoc()->GetFlyNum(nIdx
, eType
, bIgnoreTextBoxes
);
2720 std::vector
<SwFrameFormat
const*> SwFEShell::GetFlyFrameFormats(
2721 FlyCntType
const eType
, bool const bIgnoreTextBoxes
)
2723 return GetDoc()->GetFlyFrameFormats(eType
, bIgnoreTextBoxes
);
2726 // show the current selected object
2727 void SwFEShell::MakeSelVisible()
2729 if ( Imp()->HasDrawView() &&
2730 Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() )
2732 GetCurrFrame(); // just to trigger formatting in case the selected object is not formatted.
2733 MakeVisible( SwRect(Imp()->GetDrawView()->GetAllMarkedRect()) );
2736 SwCursorShell::MakeSelVisible();
2739 // how is the selected object protected?
2740 FlyProtectFlags
SwFEShell::IsSelObjProtected( FlyProtectFlags eType
) const
2742 FlyProtectFlags nChk
= FlyProtectFlags::NONE
;
2743 const bool bParent(eType
& FlyProtectFlags::Parent
);
2744 if( Imp()->HasDrawView() )
2746 const SdrMarkList
&rMrkList
= Imp()->GetDrawView()->GetMarkedObjectList();
2747 for( size_t i
= rMrkList
.GetMarkCount(); i
; )
2749 SdrObject
*pObj
= rMrkList
.GetMark( --i
)->GetMarkedSdrObj();
2757 nChk
|= ( pObj
->IsMoveProtect() ? FlyProtectFlags::Pos
: FlyProtectFlags::NONE
) |
2758 ( pObj
->IsResizeProtect()? FlyProtectFlags::Size
: FlyProtectFlags::NONE
);
2760 if (SwVirtFlyDrawObj
* pVirtO
= dynamic_cast<SwVirtFlyDrawObj
*>(pObj
))
2762 SwFlyFrame
*pFly
= pVirtO
->GetFlyFrame();
2763 if ( (FlyProtectFlags::Content
& eType
) && pFly
->GetFormat()->GetProtect().IsContentProtected() )
2764 nChk
|= FlyProtectFlags::Content
;
2766 if ( pFly
->Lower() && pFly
->Lower()->IsNoTextFrame() )
2768 SwOLENode
*pNd
= static_cast<SwNoTextFrame
*>(pFly
->Lower())->GetNode()->GetOLENode();
2769 uno::Reference
< embed::XEmbeddedObject
> xObj( pNd
? pNd
->GetOLEObj().GetOleRef() : nullptr );
2772 // TODO/LATER: use correct aspect
2773 const bool bNeverResize
= (embed::EmbedMisc::EMBED_NEVERRESIZE
& xObj
->getStatus( embed::Aspects::MSOLE_CONTENT
));
2774 if ( ( (FlyProtectFlags::Content
& eType
) || (FlyProtectFlags::Size
& eType
) ) && bNeverResize
)
2776 nChk
|= FlyProtectFlags::Size
;
2777 nChk
|= FlyProtectFlags::Fixed
;
2780 // set FlyProtectFlags::Pos if it is a Math object anchored 'as char' and baseline alignment is activated
2781 const bool bProtectMathPos
= SotExchange::IsMath( xObj
->getClassID() )
2782 && RndStdIds::FLY_AS_CHAR
== pFly
->GetFormat()->GetAnchor().GetAnchorId()
2783 && mxDoc
->GetDocumentSettingManager().get( DocumentSettingId::MATH_BASELINE_ALIGNMENT
);
2784 if ((FlyProtectFlags::Pos
& eType
) && bProtectMathPos
)
2785 nChk
|= FlyProtectFlags::Pos
;
2793 const SwFrame
* pAnch
;
2794 if (SwVirtFlyDrawObj
* pVirtO
= dynamic_cast<SwVirtFlyDrawObj
*>(pObj
))
2795 pAnch
= pVirtO
->GetFlyFrame()->GetAnchorFrame();
2798 SwDrawContact
* pTmp
= static_cast<SwDrawContact
*>(GetUserCall(pObj
));
2799 pAnch
= pTmp
? pTmp
->GetAnchorFrame( pObj
) : nullptr;
2801 if( pAnch
&& pAnch
->IsProtected() )
2808 bool SwFEShell::GetObjAttr( SfxItemSet
&rSet
) const
2810 if ( !IsObjSelected() )
2813 const SdrMarkList
&rMrkList
= Imp()->GetDrawView()->GetMarkedObjectList();
2814 for ( size_t i
= 0; i
< rMrkList
.GetMarkCount(); ++i
)
2816 SdrObject
*pObj
= rMrkList
.GetMark( i
)->GetMarkedSdrObj();
2817 SwDrawContact
*pContact
= static_cast<SwDrawContact
*>(GetUserCall(pObj
));
2818 // --> make code robust
2819 OSL_ENSURE( pContact
, "<SwFEShell::GetObjAttr(..)> - missing <pContact>." );
2823 rSet
.MergeValues( pContact
->GetFormat()->GetAttrSet() );
2825 rSet
.Put( pContact
->GetFormat()->GetAttrSet() );
2831 void SwFEShell::SetObjAttr( const SfxItemSet
& rSet
)
2833 CurrShell
aCurr( this );
2835 if ( !rSet
.Count() )
2837 OSL_ENSURE( false, "SetObjAttr, empty set." );
2842 StartUndo( SwUndoId::INSATTR
);
2844 const SdrMarkList
&rMrkList
= Imp()->GetDrawView()->GetMarkedObjectList();
2845 for ( size_t i
= 0; i
< rMrkList
.GetMarkCount(); ++i
)
2847 SdrObject
*pObj
= rMrkList
.GetMark( i
)->GetMarkedSdrObj();
2848 SwDrawContact
*pContact
= static_cast<SwDrawContact
*>(GetUserCall(pObj
));
2849 GetDoc()->SetAttr( rSet
, *pContact
->GetFormat() );
2852 EndUndo( SwUndoId::INSATTR
);
2853 EndAllActionAndCall();
2854 GetDoc()->getIDocumentState().SetModified();
2857 bool SwFEShell::IsAlignPossible() const
2859 return Imp()->GetDrawView()->IsAlignPossible();
2862 void SwFEShell::CheckUnboundObjects()
2864 CurrShell
aCurr( this );
2866 const SdrMarkList
&rMrkList
= Imp()->GetDrawView()->GetMarkedObjectList();
2867 for ( size_t i
= 0; i
< rMrkList
.GetMarkCount(); ++i
)
2869 SdrObject
*pObj
= rMrkList
.GetMark( i
)->GetMarkedSdrObj();
2870 if ( !GetUserCall(pObj
) )
2872 const tools::Rectangle
&rBound
= pObj
->GetSnapRect();
2873 const Point
aPt( rBound
.TopLeft() );
2874 const SwFrame
*pPage
= GetLayout()->Lower();
2875 const SwFrame
*pLast
= pPage
;
2876 while ( pPage
&& !pPage
->getFrameArea().Contains( aPt
) )
2878 if ( aPt
.Y() > pPage
->getFrameArea().Bottom() )
2880 pPage
= pPage
->GetNext();
2884 OSL_ENSURE( pPage
, "Page not found." );
2886 SwFormatAnchor aAnch
;
2888 const SwContentFrame
*const pAnch
= ::FindAnchor(pPage
, aPt
, true);
2889 SwPosition
aPos( pAnch
->IsTextFrame()
2890 ? *static_cast<SwTextFrame
const*>(pAnch
)->GetTextNodeForParaProps()
2891 : *static_cast<SwNoTextFrame
const*>(pAnch
)->GetNode() );
2892 aAnch
.SetType( RndStdIds::FLY_AT_PARA
);
2893 aAnch
.SetAnchor( &aPos
);
2894 const_cast<SwRect
&>(GetCharRect()).Pos() = aPt
;
2897 // First the action here, to assure GetCharRect delivers current values.
2900 SfxItemSetFixed
<RES_FRM_SIZE
, RES_FRM_SIZE
,
2901 RES_SURROUND
, RES_ANCHOR
> aSet( GetAttrPool() );
2903 aSet
.Put( SwFormatSurround( css::text::WrapTextMode_THROUGH
) );
2904 SwFrameFormat
* pFormat
= getIDocumentLayoutAccess().MakeLayoutFormat( RndStdIds::DRAW_OBJECT
, &aSet
);
2906 SwDrawContact
*pContact
= new SwDrawContact(
2907 static_cast<SwDrawFrameFormat
*>(pFormat
), pObj
);
2910 pContact
->MoveObjToVisibleLayer( pObj
);
2911 pContact
->ConnectToLayout();
2918 void SwFEShell::SetCalcFieldValueHdl(Outliner
* pOutliner
)
2920 GetDoc()->SetCalcFieldValueHdl(pOutliner
);
2923 SwChainRet
SwFEShell::Chainable( SwRect
&rRect
, const SwFrameFormat
&rSource
,
2924 const Point
&rPt
) const
2928 // The source is not allowed to have a follow.
2929 const SwFormatChain
&rChain
= rSource
.GetChain();
2930 if ( rChain
.GetNext() )
2931 return SwChainRet::SOURCE_CHAINED
;
2933 SwChainRet nRet
= SwChainRet::NOT_FOUND
;
2934 if( Imp()->HasDrawView() )
2936 SdrPageView
* pPView
;
2937 SwDrawView
*pDView
= const_cast<SwDrawView
*>(Imp()->GetDrawView());
2938 const auto nOld
= pDView
->GetHitTolerancePixel();
2939 pDView
->SetHitTolerancePixel( 0 );
2940 SdrObject
* pObj
= pDView
->PickObj(rPt
, pDView
->getHitTolLog(), pPView
, SdrSearchOptions::PICKMARKABLE
);
2941 SwVirtFlyDrawObj
* pDrawObj
= dynamic_cast<SwVirtFlyDrawObj
*>(pObj
);
2944 SwFlyFrame
*pFly
= pDrawObj
->GetFlyFrame();
2945 rRect
= pFly
->getFrameArea();
2947 // Target and source should not be equal and the list
2948 // should not be cyclic
2949 SwFrameFormat
*pFormat
= pFly
->GetFormat();
2950 nRet
= GetDoc()->Chainable(rSource
, *pFormat
);
2952 pDView
->SetHitTolerancePixel( nOld
);
2957 void SwFEShell::Chain( SwFrameFormat
&rSource
, const SwFrameFormat
&rDest
)
2959 GetDoc()->Chain(rSource
, rDest
);
2962 SwChainRet
SwFEShell::Chain( SwFrameFormat
&rSource
, const Point
&rPt
)
2965 SwChainRet nErr
= Chainable( aDummy
, rSource
, rPt
);
2966 if ( nErr
== SwChainRet::OK
)
2969 SdrPageView
* pPView
;
2970 SwDrawView
*pDView
= Imp()->GetDrawView();
2971 const auto nOld
= pDView
->GetHitTolerancePixel();
2972 pDView
->SetHitTolerancePixel( 0 );
2973 SdrObject
* pObj
= pDView
->PickObj(rPt
, pDView
->getHitTolLog(), pPView
, SdrSearchOptions::PICKMARKABLE
);
2974 pDView
->SetHitTolerancePixel( nOld
);
2975 SwFlyFrame
*pFly
= static_cast<SwVirtFlyDrawObj
*>(pObj
)->GetFlyFrame();
2977 SwFlyFrameFormat
*pFormat
= pFly
->GetFormat();
2978 GetDoc()->Chain(rSource
, *pFormat
);
2985 void SwFEShell::Unchain( SwFrameFormat
&rFormat
)
2988 GetDoc()->Unchain(rFormat
);
2992 void SwFEShell::HideChainMarker()
2994 m_pChainFrom
.reset();
2998 void SwFEShell::SetChainMarker()
3000 bool bDelFrom
= true,
3002 if ( IsFrameSelected() )
3004 SwFlyFrame
*pFly
= GetSelectedFlyFrame();
3006 if ( pFly
->GetPrevLink() )
3009 const SwFrame
*pPre
= pFly
->GetPrevLink();
3011 Point
aStart( pPre
->getFrameArea().Right(), pPre
->getFrameArea().Bottom());
3012 Point
aEnd(pFly
->getFrameArea().Pos());
3017 new SdrDropMarkerOverlay( *GetDrawView(), aStart
, aEnd
));
3020 if ( pFly
->GetNextLink() )
3023 const SwFlyFrame
*pNxt
= pFly
->GetNextLink();
3025 Point
aStart( pFly
->getFrameArea().Right(), pFly
->getFrameArea().Bottom());
3026 Point
aEnd(pNxt
->getFrameArea().Pos());
3031 new SdrDropMarkerOverlay( *GetDrawView(), aStart
, aEnd
));
3038 m_pChainFrom
.reset();
3047 tools::Long
SwFEShell::GetSectionWidth( SwFormat
const & rFormat
) const
3049 SwFrame
*pFrame
= GetCurrFrame();
3050 // Is the cursor at this moment in a SectionFrame?
3051 if( pFrame
&& pFrame
->IsInSct() )
3053 SwSectionFrame
* pSect
= pFrame
->FindSctFrame();
3056 // Is it the right one?
3057 if( pSect
->KnowsFormat( rFormat
) )
3058 return pSect
->getFrameArea().Width();
3060 pSect
= pSect
->GetUpper()->FindSctFrame();
3064 SwIterator
<SwSectionFrame
,SwFormat
> aIter( rFormat
);
3065 for ( SwSectionFrame
* pSct
= aIter
.First(); pSct
; pSct
= aIter
.Next() )
3067 if( !pSct
->IsFollow() )
3069 return pSct
->getFrameArea().Width();
3075 void SwFEShell::CreateDefaultShape( SdrObjKind eSdrObjectKind
, const tools::Rectangle
& rRect
,
3078 SdrView
* pDrawView
= GetDrawView();
3079 SdrModel
& rDrawModel
= pDrawView
->GetModel();
3080 rtl::Reference
<SdrObject
> pObj
= SdrObjFactory::MakeNewObject(
3082 SdrInventor::Default
,
3087 tools::Rectangle
aRect(rRect
);
3088 if(SdrObjKind::CircleArc
== eSdrObjectKind
|| SdrObjKind::CircleCut
== eSdrObjectKind
)
3091 if(aRect
.GetWidth() > aRect
.GetHeight())
3093 aRect
= tools::Rectangle(
3094 Point(aRect
.Left() + ((aRect
.GetWidth() - aRect
.GetHeight()) / 2), aRect
.Top()),
3095 Size(aRect
.GetHeight(), aRect
.GetHeight()));
3099 aRect
= tools::Rectangle(
3100 Point(aRect
.Left(), aRect
.Top() + ((aRect
.GetHeight() - aRect
.GetWidth()) / 2)),
3101 Size(aRect
.GetWidth(), aRect
.GetWidth()));
3104 pObj
->SetLogicRect(aRect
);
3106 Point aStart
= aRect
.TopLeft();
3107 Point aEnd
= aRect
.BottomRight();
3109 if(dynamic_cast<const SdrCircObj
*>( pObj
.get()) != nullptr)
3111 SfxItemSet
aAttr(rDrawModel
.GetItemPool());
3112 aAttr
.Put(makeSdrCircStartAngleItem(9000_deg100
));
3113 aAttr
.Put(makeSdrCircEndAngleItem(0_deg100
));
3114 pObj
->SetMergedItemSet(aAttr
);
3116 else if(auto pPathObj
= dynamic_cast<SdrPathObj
*>( pObj
.get()))
3118 basegfx::B2DPolyPolygon aPoly
;
3120 switch(eSdrObjectKind
)
3122 case SdrObjKind::PathLine
:
3123 case SdrObjKind::PathFill
:
3125 basegfx::B2DPolygon aInnerPoly
;
3127 aInnerPoly
.append(basegfx::B2DPoint(aRect
.Left(), aRect
.Bottom()));
3129 const basegfx::B2DPoint
aCenterBottom(aRect
.Center().getX(), aRect
.Bottom());
3130 aInnerPoly
.appendBezierSegment(
3133 basegfx::B2DPoint(aRect
.Center().getX(), aRect
.Center().getY()));
3135 const basegfx::B2DPoint
aCenterTop(aRect
.Center().getX(), aRect
.Top());
3136 aInnerPoly
.appendBezierSegment(
3139 basegfx::B2DPoint(aRect
.Right(), aRect
.Top()));
3141 aInnerPoly
.setClosed(true);
3142 aPoly
.append(aInnerPoly
);
3145 case SdrObjKind::FreehandLine
:
3146 case SdrObjKind::FreehandFill
:
3148 basegfx::B2DPolygon aInnerPoly
;
3150 aInnerPoly
.append(basegfx::B2DPoint(aRect
.Left(), aRect
.Bottom()));
3152 aInnerPoly
.appendBezierSegment(
3153 basegfx::B2DPoint(aRect
.Left(), aRect
.Top()),
3154 basegfx::B2DPoint(aRect
.Center().getX(), aRect
.Top()),
3155 basegfx::B2DPoint(aRect
.Center().getX(), aRect
.Center().getY()));
3157 aInnerPoly
.appendBezierSegment(
3158 basegfx::B2DPoint(aRect
.Center().getX(), aRect
.Bottom()),
3159 basegfx::B2DPoint(aRect
.Right(), aRect
.Bottom()),
3160 basegfx::B2DPoint(aRect
.Right(), aRect
.Top()));
3162 aInnerPoly
.append(basegfx::B2DPoint(aRect
.Right(), aRect
.Bottom()));
3163 aInnerPoly
.setClosed(true);
3164 aPoly
.append(aInnerPoly
);
3167 case SdrObjKind::Polygon
:
3168 case SdrObjKind::PolyLine
:
3170 basegfx::B2DPolygon aInnerPoly
;
3171 sal_Int32
nWdt(aRect
.GetWidth());
3172 sal_Int32
nHgt(aRect
.GetHeight());
3174 aInnerPoly
.append(basegfx::B2DPoint(aRect
.Left(), aRect
.Bottom()));
3175 aInnerPoly
.append(basegfx::B2DPoint(aRect
.Left() + (nWdt
* 30) / 100, aRect
.Top() + (nHgt
* 70) / 100));
3176 aInnerPoly
.append(basegfx::B2DPoint(aRect
.Left(), aRect
.Top() + (nHgt
* 15) / 100));
3177 aInnerPoly
.append(basegfx::B2DPoint(aRect
.Left() + (nWdt
* 65) / 100, aRect
.Top()));
3178 aInnerPoly
.append(basegfx::B2DPoint(aRect
.Left() + nWdt
, aRect
.Top() + (nHgt
* 30) / 100));
3179 aInnerPoly
.append(basegfx::B2DPoint(aRect
.Left() + (nWdt
* 80) / 100, aRect
.Top() + (nHgt
* 50) / 100));
3180 aInnerPoly
.append(basegfx::B2DPoint(aRect
.Left() + (nWdt
* 80) / 100, aRect
.Top() + (nHgt
* 75) / 100));
3181 aInnerPoly
.append(basegfx::B2DPoint(aRect
.Bottom(), aRect
.Right()));
3183 if(SdrObjKind::PolyLine
== eSdrObjectKind
)
3185 aInnerPoly
.append(basegfx::B2DPoint(aRect
.Center().getX(), aRect
.Bottom()));
3189 aInnerPoly
.setClosed(true);
3192 aPoly
.append(aInnerPoly
);
3195 case SdrObjKind::Line
:
3197 sal_Int32
nYMiddle((aRect
.Top() + aRect
.Bottom()) / 2);
3198 basegfx::B2DPolygon aTempPoly
;
3199 aTempPoly
.append(basegfx::B2DPoint(aRect
.TopLeft().getX(), nYMiddle
));
3200 aTempPoly
.append(basegfx::B2DPoint(aRect
.BottomRight().getX(), nYMiddle
));
3201 aPoly
.append(aTempPoly
);
3203 SfxItemSet
aAttr(pObj
->getSdrModelFromSdrObject().GetItemPool());
3204 SetLineEnds(aAttr
, *pObj
, nSlotId
);
3205 pObj
->SetMergedItemSet(aAttr
);
3212 pPathObj
->SetPathPoly(aPoly
);
3214 else if(auto pMeasureObj
= dynamic_cast<SdrMeasureObj
*>( pObj
.get()))
3216 sal_Int32
nYMiddle((aRect
.Top() + aRect
.Bottom()) / 2);
3217 pMeasureObj
->SetPoint(Point(aStart
.X(), nYMiddle
), 0);
3218 pMeasureObj
->SetPoint(Point(aEnd
.X(), nYMiddle
), 1);
3220 SfxItemSet
aAttr(pObj
->getSdrModelFromSdrObject().GetItemPool());
3221 SetLineEnds(aAttr
, *pObj
, nSlotId
);
3222 pObj
->SetMergedItemSet(aAttr
);
3224 else if(auto pCaptionObj
= dynamic_cast<SdrCaptionObj
*>( pObj
.get()))
3226 bool bVerticalText
= ( SID_DRAW_TEXT_VERTICAL
== nSlotId
||
3227 SID_DRAW_CAPTION_VERTICAL
== nSlotId
);
3228 pCaptionObj
->SetVerticalWriting(bVerticalText
);
3231 SfxItemSet
aSet(pObj
->GetMergedItemSet());
3232 aSet
.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_CENTER
));
3233 aSet
.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT
));
3234 pObj
->SetMergedItemSet(aSet
);
3237 pCaptionObj
->SetLogicRect(aRect
);
3238 pCaptionObj
->SetTailPos(
3239 aRect
.TopLeft() - Point(aRect
.GetWidth() / 2, aRect
.GetHeight() / 2));
3241 else if(auto pText
= DynCastSdrTextObj( pObj
.get()))
3243 pText
->SetLogicRect(aRect
);
3245 bool bVertical
= (SID_DRAW_TEXT_VERTICAL
== nSlotId
);
3246 bool bMarquee
= (SID_DRAW_TEXT_MARQUEE
== nSlotId
);
3248 pText
->SetVerticalWriting(bVertical
);
3252 SfxItemSet
aSet(rDrawModel
.GetItemPool());
3253 aSet
.Put(makeSdrTextAutoGrowWidthItem(true));
3254 aSet
.Put(makeSdrTextAutoGrowHeightItem(false));
3255 aSet
.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_TOP
));
3256 aSet
.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT
));
3257 pText
->SetMergedItemSet(aSet
);
3262 SfxItemSetFixed
<SDRATTR_MISC_FIRST
, SDRATTR_MISC_LAST
> aSet(rDrawModel
.GetItemPool());
3263 aSet
.Put( makeSdrTextAutoGrowWidthItem( false ) );
3264 aSet
.Put( makeSdrTextAutoGrowHeightItem( false ) );
3265 aSet
.Put( SdrTextAniKindItem( SdrTextAniKind::Slide
) );
3266 aSet
.Put( SdrTextAniDirectionItem( SdrTextAniDirection::Left
) );
3267 aSet
.Put( SdrTextAniCountItem( 1 ) );
3268 aSet
.Put( SdrTextAniAmountItem( static_cast<sal_Int16
>(GetWin()->PixelToLogic(Size(2,1)).Width())) );
3269 pObj
->SetMergedItemSetAndBroadcast(aSet
);
3272 SdrPageView
* pPageView
= pDrawView
->GetSdrPageView();
3273 SdrCreateView::SetupObjLayer(pPageView
, pDrawView
->GetActiveLayer(), pObj
.get());
3274 // switch undo off or this combined with ImpEndCreate will cause two undos
3275 // see comment made in SwFEShell::EndCreate (we create our own undo-object!)
3276 const bool bUndo(GetDoc()->GetIDocumentUndoRedo().DoesUndo());
3277 GetDoc()->GetIDocumentUndoRedo().DoUndo(false);
3278 pDrawView
->InsertObjectAtView(pObj
.get(), *pPageView
);
3279 GetDoc()->GetIDocumentUndoRedo().DoUndo(bUndo
);
3284 /** SwFEShell::GetShapeBackground
3285 method determines background color of the page the selected drawing
3286 object is on and returns this color.
3287 If no color is found, because no drawing object is selected or ...,
3288 color COL_BLACK (default color on constructing object of class Color)
3291 @returns an object of class Color
3293 Color
SwFEShell::GetShapeBackground() const
3297 // check, if a draw view exists
3298 OSL_ENSURE( Imp()->GetDrawView(), "wrong usage of SwFEShell::GetShapeBackground - no draw view!");
3299 if( Imp()->GetDrawView() )
3301 // determine list of selected objects
3302 const SdrMarkList
* pMrkList
= &Imp()->GetDrawView()->GetMarkedObjectList();
3303 // check, if exactly one object is selected.
3304 OSL_ENSURE( pMrkList
->GetMarkCount() == 1, "wrong usage of SwFEShell::GetShapeBackground - no selected object!");
3305 if ( pMrkList
->GetMarkCount() == 1)
3307 // get selected object
3308 const SdrObject
*pSdrObj
= pMrkList
->GetMark( 0 )->GetMarkedSdrObj();
3309 // check, if selected object is a shape (drawing object)
3310 OSL_ENSURE( dynamic_cast<const SwVirtFlyDrawObj
*>( pSdrObj
) == nullptr, "wrong usage of SwFEShell::GetShapeBackground - selected object is not a drawing object!");
3311 if ( dynamic_cast<const SwVirtFlyDrawObj
*>( pSdrObj
) == nullptr )
3313 // determine page frame of the frame the shape is anchored.
3314 const SwFrame
* pAnchorFrame
=
3315 static_cast<SwDrawContact
*>(GetUserCall(pSdrObj
))->GetAnchorFrame( pSdrObj
);
3316 OSL_ENSURE( pAnchorFrame
, "inconsistent model - no anchor at shape!");
3319 const SwPageFrame
* pPageFrame
= pAnchorFrame
->FindPageFrame();
3320 OSL_ENSURE( pPageFrame
, "inconsistent model - no page!");
3323 aRetColor
= pPageFrame
->GetDrawBackgroundColor();
3333 /** Is default horizontal text direction for selected drawing object right-to-left
3334 Because drawing objects only painted for each page only, the default
3335 horizontal text direction of a drawing object is given by the corresponding
3338 @returns boolean, indicating, if the horizontal text direction of the
3339 page, the selected drawing object is on, is right-to-left.
3341 bool SwFEShell::IsShapeDefaultHoriTextDirR2L() const
3345 // check, if a draw view exists
3346 OSL_ENSURE( Imp()->GetDrawView(), "wrong usage of SwFEShell::GetShapeBackground - no draw view!");
3347 if( Imp()->GetDrawView() )
3349 // determine list of selected objects
3350 const SdrMarkList
* pMrkList
= &Imp()->GetDrawView()->GetMarkedObjectList();
3351 // check, if exactly one object is selected.
3352 OSL_ENSURE( pMrkList
->GetMarkCount() == 1, "wrong usage of SwFEShell::GetShapeBackground - no selected object!");
3353 if ( pMrkList
->GetMarkCount() == 1)
3355 // get selected object
3356 const SdrObject
*pSdrObj
= pMrkList
->GetMark( 0 )->GetMarkedSdrObj();
3357 // check, if selected object is a shape (drawing object)
3358 OSL_ENSURE( dynamic_cast<const SwVirtFlyDrawObj
*>( pSdrObj
) == nullptr, "wrong usage of SwFEShell::GetShapeBackground - selected object is not a drawing object!");
3359 if ( dynamic_cast<const SwVirtFlyDrawObj
*>( pSdrObj
) == nullptr )
3361 // determine page frame of the frame the shape is anchored.
3362 const SwContact
* pContact
= GetUserCall(pSdrObj
);
3363 OSL_ENSURE( pContact
, "<SwFEShell::IsShapeDefaultHoriTextDirR2L(..)> - missing contact!" );
3366 const SwFrame
* pAnchorFrame
= static_cast<const SwDrawContact
*>(pContact
)->GetAnchorFrame( pSdrObj
);
3367 OSL_ENSURE( pAnchorFrame
, "inconsistent model - no anchor at shape!");
3370 const SwPageFrame
* pPageFrame
= pAnchorFrame
->FindPageFrame();
3371 OSL_ENSURE( pPageFrame
, "inconsistent model - no page!");
3374 bRet
= pPageFrame
->IsRightToLeft();
3384 Point
SwFEShell::GetRelativePagePosition(const Point
& rDocPos
)
3387 const SwFrame
*pPage
= GetLayout()->Lower();
3388 while ( pPage
&& !pPage
->getFrameArea().Contains( rDocPos
) )
3390 pPage
= pPage
->GetNext();
3394 aRet
= rDocPos
- pPage
->getFrameArea().TopLeft();
3399 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */