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 <o3tl/any.hxx>
22 #include <svl/itemiter.hxx>
23 #include <vcl/imapobj.hxx>
24 #include <editeng/protitem.hxx>
25 #include <svx/svdogrp.hxx>
26 #include <svx/svdouno.hxx>
27 #include <tools/globname.hxx>
28 #include <sot/exchange.hxx>
29 #include <com/sun/star/form/FormButtonType.hpp>
30 #include <com/sun/star/beans/XPropertySet.hpp>
31 #include <com/sun/star/embed/XEmbeddedObject.hpp>
32 #include <comphelper/types.hxx>
33 #include <fmtanchr.hxx>
34 #include <fmtcntnt.hxx>
35 #include <fmtornt.hxx>
37 #include <fmtfsize.hxx>
40 #include <rootfrm.hxx>
41 #include <pagefrm.hxx>
44 #include <viewimp.hxx>
47 #include <IDocumentDrawModelAccess.hxx>
48 #include <IDocumentUndoRedo.hxx>
49 #include <IDocumentState.hxx>
50 #include <IDocumentLayoutAccess.hxx>
52 #include <dflyobj.hxx>
53 #include <dcontact.hxx>
57 #include <swtable.hxx>
59 #include <flyfrms.hxx>
63 #include <txatbase.hxx>
65 #include <notxtfrm.hxx>
66 #include <HandleAnchorNodeChg.hxx>
68 #include <fmtsrnd.hxx>
71 #include <fmtcnct.hxx>
72 #include <frameformats.hxx>
73 #include <textboxhelper.hxx>
76 using namespace ::com::sun::star
;
78 // Based on the request, changes to the specific layouts will be made, to
80 static bool lcl_SetNewFlyPos( const SwNode
& rNode
, SwFormatAnchor
& rAnchor
,
84 const SwStartNode
* pStNode
= rNode
.FindFlyStartNode();
87 SwPosition
aPos( *pStNode
);
88 rAnchor
.SetAnchor( &aPos
);
93 const SwContentNode
*pCntNd
= rNode
.GetContentNode();
94 std::pair
<Point
, bool> const tmp(rPt
, false);
95 const SwContentFrame
* pCFrame
= pCntNd
? pCntNd
->getLayoutFrame(
96 pCntNd
->GetDoc().getIDocumentLayoutAccess().GetCurrentLayout(),
97 nullptr, &tmp
) : nullptr;
98 const SwPageFrame
*pPg
= pCFrame
? pCFrame
->FindPageFrame() : nullptr;
100 rAnchor
.SetPageNum( pPg
? pPg
->GetPhyPageNum() : 1 );
101 rAnchor
.SetType( RndStdIds::FLY_AT_PAGE
);
106 static bool lcl_FindAnchorPos(
109 const SwFrame
& rFrame
,
113 SwFormatAnchor
aNewAnch( rSet
.Get( RES_ANCHOR
) );
114 RndStdIds nNew
= aNewAnch
.GetAnchorId();
115 const SwFrame
*pNewAnch
;
117 //determine new anchor
118 Point
aTmpPnt( rPt
);
121 case RndStdIds::FLY_AS_CHAR
: // also include this?
122 case RndStdIds::FLY_AT_PARA
:
123 case RndStdIds::FLY_AT_CHAR
: // LAYER_IMPL
125 // starting from the upper-left corner of the Fly,
126 // search nearest ContentFrame
127 const SwFrame
* pFrame
= rFrame
.IsFlyFrame() ? static_cast<const SwFlyFrame
&>(rFrame
).GetAnchorFrame()
129 pNewAnch
= ::FindAnchor( pFrame
, aTmpPnt
);
130 if( pNewAnch
->IsProtected() )
135 SwPosition
aPos( pNewAnch
->IsTextFrame()
136 ? *static_cast<SwTextFrame
const*>(pNewAnch
)->GetTextNodeForParaProps()
137 : *static_cast<const SwNoTextFrame
*>(pNewAnch
)->GetNode() );
138 if ((RndStdIds::FLY_AT_CHAR
== nNew
) || (RndStdIds::FLY_AS_CHAR
== nNew
))
140 // textnode should be found, as only in those
141 // a content bound frame can be anchored
142 SwCursorMoveState
aState( CursorMoveState::SetOnlyText
);
143 aTmpPnt
.setX(aTmpPnt
.getX() - 1); // do not land in the fly!
144 if( !pNewAnch
->GetModelPositionForViewPoint( &aPos
, aTmpPnt
, &aState
) )
146 assert(pNewAnch
->IsTextFrame()); // because AT_CHAR/AS_CHAR
147 SwTextFrame
const*const pTextFrame(
148 static_cast<SwTextFrame
const*>(pNewAnch
));
149 if( pNewAnch
->getFrameArea().Bottom() < aTmpPnt
.Y() )
151 aPos
= pTextFrame
->MapViewToModelPos(TextFrameIndex(0));
155 aPos
= pTextFrame
->MapViewToModelPos(
156 TextFrameIndex(pTextFrame
->GetText().getLength()));
161 if ( SwCursorShell::PosInsideInputField( aPos
) )
163 aPos
.nContent
= SwCursorShell::StartOfInputFieldAtPos( aPos
);
167 aNewAnch
.SetAnchor( &aPos
);
171 case RndStdIds::FLY_AT_FLY
: // LAYER_IMPL
173 // starting from the upper-left corner of the Fly
174 // search nearest SwFlyFrame
175 SwCursorMoveState
aState( CursorMoveState::SetOnlyText
);
176 SwPosition
aPos( rDoc
.GetNodes() );
177 aTmpPnt
.setX(aTmpPnt
.getX() - 1); // do not land in the fly!
178 rDoc
.getIDocumentLayoutAccess().GetCurrentLayout()->GetModelPositionForViewPoint( &aPos
, aTmpPnt
, &aState
);
179 pNewAnch
= ::FindAnchor(
180 aPos
.nNode
.GetNode().GetContentNode()->getLayoutFrame(rFrame
.getRootFrame(), nullptr, nullptr),
181 aTmpPnt
)->FindFlyFrame();
183 if( pNewAnch
&& &rFrame
!= pNewAnch
&& !pNewAnch
->IsProtected() )
185 aPos
.nNode
= *static_cast<const SwFlyFrame
*>(pNewAnch
)->GetFormat()->GetContent().
187 aNewAnch
.SetAnchor( &aPos
);
192 nNew
= RndStdIds::FLY_AT_PAGE
;
193 aNewAnch
.SetType( nNew
);
196 case RndStdIds::FLY_AT_PAGE
:
197 pNewAnch
= rFrame
.FindPageFrame();
198 aNewAnch
.SetPageNum( pNewAnch
->GetPhyPageNum() );
202 OSL_ENSURE( false, "Wrong Id for new anchor." );
205 rSet
.Put( aNewAnch
);
209 //! also used in unoframe.cxx
211 bool sw_ChkAndSetNewAnchor(
212 const SwFlyFrame
& rFly
,
215 const SwFrameFormat
& rFormat
= *rFly
.GetFormat();
216 const SwFormatAnchor
&rOldAnch
= rFormat
.GetAnchor();
217 const RndStdIds nOld
= rOldAnch
.GetAnchorId();
219 RndStdIds nNew
= rSet
.Get( RES_ANCHOR
).GetAnchorId();
224 SwDoc
* pDoc
= const_cast<SwDoc
*>(rFormat
.GetDoc());
226 #if OSL_DEBUG_LEVEL > 0
227 OSL_ENSURE( !(nNew
== RndStdIds::FLY_AT_PAGE
&&
228 (RndStdIds::FLY_AT_PARA
==nOld
|| RndStdIds::FLY_AT_CHAR
==nOld
|| RndStdIds::FLY_AS_CHAR
==nOld
) &&
229 pDoc
->IsInHeaderFooter( rOldAnch
.GetContentAnchor()->nNode
)),
230 "forbidden anchor change in Head/Foot." );
233 return ::lcl_FindAnchorPos( *pDoc
, rFly
.getFrameArea().Pos(), rFly
, rSet
);
236 void SwFEShell::SelectFlyFrame( SwFlyFrame
& rFrame
)
238 CurrShell
aCurr( this );
240 // The frame is new, thus select it.
241 // !! Always select the frame, if it's not selected.
242 // - it could be a new "old" one because the anchor was changed
243 // - "old" frames have had to be selected previously otherwise they could
244 // not have been changed
245 // The frames should not be selected by the document position, because
246 // it should have been selected!
247 SwViewShellImp
*pImpl
= Imp();
251 OSL_ENSURE( rFrame
.IsFlyFrame(), "SelectFlyFrame wants a Fly" );
253 // nothing to be done if the Fly already was selected
254 if (GetSelectedFlyFrame() == &rFrame
)
257 // assure the anchor is drawn
258 if( rFrame
.IsFlyInContentFrame() && rFrame
.GetAnchorFrame() )
259 rFrame
.GetAnchorFrame()->SetCompletePaint();
261 if( pImpl
->GetDrawView()->AreObjectsMarked() )
262 pImpl
->GetDrawView()->UnmarkAll();
264 pImpl
->GetDrawView()->MarkObj( rFrame
.GetVirtDrawObj(),
265 pImpl
->GetPageView() );
267 rFrame
.SelectionHasChanged(this);
275 SwFlyFrame
* SwFEShell::GetSelectedFlyFrame() const
277 if ( Imp()->HasDrawView() )
279 // A Fly is only accessible if it is selected
280 const SdrMarkList
&rMrkList
= Imp()->GetDrawView()->GetMarkedObjectList();
281 if( rMrkList
.GetMarkCount() != 1 )
284 SdrObject
*pO
= rMrkList
.GetMark( 0 )->GetMarkedSdrObj();
286 SwVirtFlyDrawObj
*pFlyObj
= dynamic_cast<SwVirtFlyDrawObj
*>(pO
);
288 return pFlyObj
? pFlyObj
->GetFlyFrame() : nullptr;
293 // Get current fly in which the cursor is positioned
294 SwFlyFrame
* SwFEShell::GetCurrFlyFrame(const bool bCalcFrame
) const
296 SwContentFrame
*pContent
= GetCurrFrame(bCalcFrame
);
297 return pContent
? pContent
->FindFlyFrame() : nullptr;
300 // Get selected fly, but if none Get current fly in which the cursor is positioned
301 SwFlyFrame
* SwFEShell::GetSelectedOrCurrFlyFrame() const
303 SwFlyFrame
*pFly
= GetSelectedFlyFrame();
306 return GetCurrFlyFrame();
309 // Returns non-null pointer, if the current Fly could be anchored to another one (so it is inside)
310 const SwFrameFormat
* SwFEShell::IsFlyInFly()
312 CurrShell
aCurr( this );
314 if ( !Imp()->HasDrawView() )
317 const SdrMarkList
&rMrkList
= Imp()->GetDrawView()->GetMarkedObjectList();
318 if ( !rMrkList
.GetMarkCount() )
320 SwFlyFrame
*pFly
= GetCurrFlyFrame(false);
323 return pFly
->GetFormat();
325 else if ( rMrkList
.GetMarkCount() != 1 ||
326 !GetUserCall(rMrkList
.GetMark( 0 )->GetMarkedSdrObj()) )
329 SdrObject
*pObj
= rMrkList
.GetMark( 0 )->GetMarkedSdrObj();
331 SwFrameFormat
*pFormat
= FindFrameFormat( pObj
);
332 if( pFormat
&& RndStdIds::FLY_AT_FLY
== pFormat
->GetAnchor().GetAnchorId() )
335 if (SwVirtFlyDrawObj
* pFlyObj
= dynamic_cast<SwVirtFlyDrawObj
*>(pObj
))
337 pFly
= pFlyObj
->GetFlyFrame()->GetAnchorFrame();
341 pFly
= static_cast<SwDrawContact
*>(GetUserCall(pObj
))->GetAnchorFrame(pObj
);
344 OSL_ENSURE( pFly
, "IsFlyInFly: Where's my anchor?" );
345 OSL_ENSURE( pFly
->IsFlyFrame(), "IsFlyInFly: Funny anchor!" );
346 return static_cast<const SwFlyFrame
*>(pFly
)->GetFormat();
349 Point aTmpPos
= pObj
->GetCurrentBoundRect().TopLeft();
353 SwCursorMoveState
aState( CursorMoveState::SetOnlyText
);
354 SwNodeIndex
aSwNodeIndex( GetDoc()->GetNodes() );
355 SwPosition
aPos( aSwNodeIndex
);
356 Point
aPoint( aTmpPos
);
357 aPoint
.setX(aPoint
.getX() - 1); //do not land in the fly!!
358 GetLayout()->GetModelPositionForViewPoint( &aPos
, aPoint
, &aState
);
359 // determine text frame by left-top-corner of object
360 SwContentNode
*pNd
= aPos
.nNode
.GetNode().GetContentNode();
361 std::pair
<Point
, bool> const tmp(aTmpPos
, false);
362 pTextFrame
= pNd
? pNd
->getLayoutFrame(GetLayout(), nullptr, &tmp
) : nullptr;
364 const SwFrame
*pTmp
= pTextFrame
? ::FindAnchor(pTextFrame
, aTmpPos
) : nullptr;
365 const SwFlyFrame
*pFly
= pTmp
? pTmp
->FindFlyFrame() : nullptr;
367 return pFly
->GetFormat();
371 void SwFEShell::SetFlyPos( const Point
& rAbsPos
)
373 CurrShell
aCurr( this );
375 // Determine reference point in document coordinates
376 SwFlyFrame
*pFly
= GetCurrFlyFrame(false);
380 //SwSaveHdl aSaveX( Imp() );
382 // Set an anchor starting from the absolute position for paragraph bound Flys
383 // Anchor and new RelPos will be calculated and set by the Fly
384 if ( pFly
->IsFlyAtContentFrame() )
386 if(pFly
->IsFlyFreeFrame() && static_cast< SwFlyFreeFrame
* >(pFly
)->isTransformableSwFrame())
388 // RotateFlyFrame3: When we have a change and are in transformed state (e.g. rotation used),
389 // we need to correct the absolute position (rAbsPos) which was created in
390 // transformed coordinates to untransformed state
391 TransformableSwFrame
* pTransformableSwFrame(static_cast<SwFlyFreeFrame
*>(pFly
)->getTransformableSwFrame());
392 const SwRect
aUntransformedFrameArea(pTransformableSwFrame
->getUntransformedFrameArea());
393 const Point
aNewAbsPos(
394 rAbsPos
.X() + aUntransformedFrameArea
.Left() - pFly
->getFrameArea().Left(),
395 rAbsPos
.Y() + aUntransformedFrameArea
.Top() - pFly
->getFrameArea().Top());
396 static_cast<SwFlyAtContentFrame
*>(pFly
)->SetAbsPos(aNewAbsPos
);
400 static_cast<SwFlyAtContentFrame
*>(pFly
)->SetAbsPos( rAbsPos
);
405 const SwFrame
*pAnch
= pFly
->GetAnchorFrame();
406 Point
aOrient( pAnch
->getFrameArea().Pos() );
408 if ( pFly
->IsFlyInContentFrame() )
409 aOrient
.setX(rAbsPos
.getX());
412 aOrient
.setX(rAbsPos
.getX() - aOrient
.getX());
413 aOrient
.setY(rAbsPos
.getY() - aOrient
.getY());
414 pFly
->ChgRelPos( aOrient
);
416 CallChgLnk(); // call the AttrChangeNotify on the UI-side.
419 Point
SwFEShell::FindAnchorPos( const Point
& rAbsPos
, bool bMoveIt
)
423 CurrShell
aCurr( this );
425 if ( !Imp()->HasDrawView() )
428 const SdrMarkList
&rMrkList
= Imp()->GetDrawView()->GetMarkedObjectList();
429 if ( rMrkList
.GetMarkCount() != 1 ||
430 !GetUserCall(rMrkList
.GetMark( 0 )->GetMarkedSdrObj()) )
433 SdrObject
* pObj
= rMrkList
.GetMark( 0 )->GetMarkedSdrObj();
435 SwAnchoredObject
* pAnchoredObj
= ::GetUserCall( pObj
)->GetAnchoredObj( pObj
);
436 SwFrameFormat
& rFormat
= pAnchoredObj
->GetFrameFormat();
437 const RndStdIds nAnchorId
= rFormat
.GetAnchor().GetAnchorId();
439 if ( RndStdIds::FLY_AS_CHAR
== nAnchorId
)
442 bool bFlyFrame
= dynamic_cast<SwVirtFlyDrawObj
*>(pObj
) != nullptr;
444 bool bTextBox
= false;
445 if (rFormat
.Which() == RES_DRAWFRMFMT
)
447 bTextBox
= SwTextBoxHelper::isTextBox(&rFormat
, RES_DRAWFRMFMT
);
450 SwFlyFrame
* pFly
= nullptr;
451 const SwFrame
* pFooterOrHeader
= nullptr;
455 // Calculate reference point in document coordinates
456 SwContentFrame
*pContent
= GetCurrFrame( false );
459 pFly
= pContent
->FindFlyFrame();
462 const SwFrame
* pOldAnch
= pFly
->GetAnchorFrame();
465 if ( RndStdIds::FLY_AT_PAGE
!= nAnchorId
)
467 pFooterOrHeader
= pContent
->FindFooterOrHeader();
472 auto pFlyFormat
= dynamic_cast<const SwFlyFrameFormat
*>(
473 SwTextBoxHelper::getOtherTextBoxFormat(&rFormat
, RES_DRAWFRMFMT
));
476 pFly
= pFlyFormat
->GetFrame();
480 // set <pFooterOrHeader> also for drawing
481 // objects, but not for control objects.
482 // Necessary for moving 'anchor symbol' at the user interface inside header/footer.
483 else if ( !::CheckControlLayer( pObj
) )
485 SwContentFrame
*pContent
= GetCurrFrame( false );
488 pFooterOrHeader
= pContent
->FindFooterOrHeader();
491 // Search nearest SwFlyFrame starting from the upper-left corner
493 SwContentFrame
*pTextFrame
= nullptr;
495 SwCursorMoveState
aState( CursorMoveState::SetOnlyText
);
496 SwPosition
aPos( GetDoc()->GetNodes().GetEndOfExtras() );
497 Point
aTmpPnt( rAbsPos
);
498 GetLayout()->GetModelPositionForViewPoint( &aPos
, aTmpPnt
, &aState
);
499 if (aPos
.nNode
!= GetDoc()->GetNodes().GetEndOfExtras().GetIndex()
500 && (nAnchorId
!= RndStdIds::FLY_AT_CHAR
|| !PosInsideInputField(aPos
)))
502 SwContentNode
* pCNode
= aPos
.nNode
.GetNode().GetContentNode();
504 pTextFrame
= pCNode
->getLayoutFrame(GetLayout(), &aPos
, nullptr);
507 const SwFrame
*pNewAnch
= nullptr;
508 if( pTextFrame
!= nullptr )
510 if ( RndStdIds::FLY_AT_PAGE
== nAnchorId
)
512 pNewAnch
= pTextFrame
->FindPageFrame();
516 pNewAnch
= ::FindAnchor( pTextFrame
, rAbsPos
);
518 if( RndStdIds::FLY_AT_FLY
== nAnchorId
) // LAYER_IMPL
520 pNewAnch
= pNewAnch
->FindFlyFrame();
525 if( pNewAnch
&& !pNewAnch
->IsProtected() )
527 const SwFlyFrame
* pCheck
= (bFlyFrame
|| bTextBox
) ? pNewAnch
->FindFlyFrame() : nullptr;
528 // If we land inside the frame, make sure
529 // that the frame does not land inside its own content
534 const SwFrame
*pTmp
= pCheck
->GetAnchorFrame();
535 pCheck
= pTmp
? pTmp
->FindFlyFrame() : nullptr;
538 // Do not switch from header/footer to another area,
539 // do not switch to a header/footer
541 pFooterOrHeader
== pNewAnch
->FindFooterOrHeader() )
543 aRet
= pNewAnch
->GetFrameAnchorPos( ::HasWrap( pObj
) );
545 if ( bMoveIt
|| (nAnchorId
== RndStdIds::FLY_AT_CHAR
) )
547 SwFormatAnchor
aAnch( rFormat
.GetAnchor() );
550 case RndStdIds::FLY_AT_PARA
:
552 SwPosition pos
= *aAnch
.GetContentAnchor();
553 pos
.nNode
= pTextFrame
->IsTextFrame()
554 ? *static_cast<SwTextFrame
const*>(pTextFrame
)->GetTextNodeForParaProps()
555 : *static_cast<const SwNoTextFrame
*>(pTextFrame
)->GetNode();
556 pos
.nContent
.Assign(nullptr,0);
557 aAnch
.SetAnchor( &pos
);
560 case RndStdIds::FLY_AT_PAGE
:
562 aAnch
.SetPageNum( static_cast<const SwPageFrame
*>(pNewAnch
)->
567 case RndStdIds::FLY_AT_FLY
:
569 SwPosition
aPos( *static_cast<const SwFlyFrame
*>(pNewAnch
)->GetFormat()->
570 GetContent().GetContentIdx() );
571 aAnch
.SetAnchor( &aPos
);
575 case RndStdIds::FLY_AT_CHAR
:
577 SwPosition pos
= *aAnch
.GetContentAnchor();
578 Point
aTmpPnt( rAbsPos
);
579 if( pTextFrame
->GetModelPositionForViewPoint( &pos
, aTmpPnt
) )
582 pTextFrame
->GetCharRect( aTmpRect
, pos
);
583 aRet
= aTmpRect
.Pos();
587 pos
= static_cast<SwTextFrame
const*>(pTextFrame
)->MapViewToModelPos(TextFrameIndex(0));
589 aAnch
.SetAnchor( &pos
);
600 // --> handle change of anchor node:
601 // if count of the anchor frame also change, the fly frames have to be
602 // re-created. Thus, delete all fly frames except the <this> before the
603 // anchor attribute is change and re-create them afterwards.
605 std::unique_ptr
<SwHandleAnchorNodeChg
, o3tl::default_delete
<SwHandleAnchorNodeChg
>> pHandleAnchorNodeChg
;
606 SwFlyFrameFormat
* pFlyFrameFormat( dynamic_cast<SwFlyFrameFormat
*>(&rFormat
) );
607 if ( pFlyFrameFormat
)
609 pHandleAnchorNodeChg
.reset(
610 new SwHandleAnchorNodeChg( *pFlyFrameFormat
, aAnch
));
612 rFormat
.GetDoc()->SetAttr( aAnch
, rFormat
);
613 if (SwTextBoxHelper::getOtherTextBoxFormat(&rFormat
, RES_DRAWFRMFMT
))
615 SwTextBoxHelper::syncFlyFrameAttr(rFormat
, rFormat
.GetAttrSet());
618 // #i28701# - no call of method
619 // <CheckCharRectAndTopOfLine()> for to-character anchored
620 // Writer fly frame needed. This method call can cause a
621 // format of the anchor frame, which is no longer intended.
622 // Instead clear the anchor character rectangle and
623 // the top of line values for all to-character anchored objects.
624 pAnchoredObj
->ClearCharRectAndTopOfLine();
629 SwRect
aTmpRect( aRet
, rAbsPos
);
630 if( aTmpRect
.HasArea() )
631 MakeVisible( aTmpRect
);
632 #if OSL_DEBUG_LEVEL > 0
633 //TODO: That doesn't seem to be intended
634 if( COL_TRANSPARENT
!= GetOut()->GetLineColor() )
636 OSL_FAIL( "Hey, Joe: Where's my Null Pen?" );
637 GetOut()->SetLineColor( COL_TRANSPARENT
);
646 const SwFrameFormat
*SwFEShell::NewFlyFrame( const SfxItemSet
& rSet
, bool bAnchValid
,
647 SwFrameFormat
*pParent
)
649 CurrShell
aCurr( this );
652 SwPaM
* pCursor
= GetCursor();
653 const Point
aPt( GetCursorDocPos() );
656 bool bMoveContent
= true;
659 GetTableSel( *this, aBoxes
);
660 if( !aBoxes
.empty() )
662 // Cursor should be removed from the removal area.
663 // Always put it after/on the table; via the
664 // document position they will be set to the old
666 ParkCursor( SwNodeIndex( *aBoxes
[0]->GetSttNd() ));
668 // #i127787# pCurrentCursor will be deleted in ParkCursor,
669 // we better get the current pCurrentCursor instead of working with the
671 pCursor
= GetCursor();
674 bMoveContent
= false;
676 else if( !pCursor
->HasMark() && !pCursor
->IsMultiSelection() )
677 bMoveContent
= false;
679 const SwPosition
& rPos
= *pCursor
->Start();
681 SwFormatAnchor
& rAnch
= const_cast<SwFormatAnchor
&>(rSet
.Get( RES_ANCHOR
));
682 RndStdIds eRndId
= rAnch
.GetAnchorId();
685 case RndStdIds::FLY_AT_PAGE
:
686 if( !rAnch
.GetPageNum() ) //HotFix: Bug in UpdateByExample
687 rAnch
.SetPageNum( 1 );
690 case RndStdIds::FLY_AT_FLY
:
691 case RndStdIds::FLY_AT_PARA
:
692 case RndStdIds::FLY_AT_CHAR
:
693 case RndStdIds::FLY_AS_CHAR
:
696 if( RndStdIds::FLY_AT_FLY
!= eRndId
)
698 rAnch
.SetAnchor( &rPos
);
700 else if( lcl_SetNewFlyPos( rPos
.nNode
.GetNode(), rAnch
, aPt
) )
702 eRndId
= RndStdIds::FLY_AT_PAGE
;
708 OSL_ENSURE( false, "What is the purpose of this Fly?" );
712 SwFlyFrameFormat
*pRet
;
715 GetDoc()->GetIDocumentUndoRedo().StartUndo( SwUndoId::INSLAYFMT
, nullptr );
716 std::unique_ptr
<SwFormatAnchor
> pOldAnchor
;
717 bool bHOriChgd
= false, bVOriChgd
= false;
718 std::shared_ptr
<SwFormatVertOrient
> aOldV
;
719 std::shared_ptr
<SwFormatHoriOrient
> aOldH
;
721 if ( RndStdIds::FLY_AT_PAGE
!= eRndId
)
723 // First as with page link. Paragraph/character link on if
724 // everything was shifted. Then the position is valid!
725 // JP 13.05.98: if necessary also convert the horizontal/vertical
726 // orientation, to prevent correction during re-anchoring
727 pOldAnchor
.reset(new SwFormatAnchor( rAnch
));
728 const_cast<SfxItemSet
&>(rSet
).Put( SwFormatAnchor( RndStdIds::FLY_AT_PAGE
, 1 ) );
730 const SfxPoolItem
* pItem
;
731 if( SfxItemState::SET
== rSet
.GetItemState( RES_HORI_ORIENT
, false, &pItem
)
732 && text::HoriOrientation::NONE
== static_cast<const SwFormatHoriOrient
*>(pItem
)->GetHoriOrient() )
735 aOldH
.reset(static_cast<SwFormatHoriOrient
*>(pItem
->Clone()));
736 const_cast<SfxItemSet
&>(rSet
).Put( SwFormatHoriOrient( 0, text::HoriOrientation::LEFT
) );
738 if( SfxItemState::SET
== rSet
.GetItemState( RES_VERT_ORIENT
, false, &pItem
)
739 && text::VertOrientation::NONE
== static_cast<const SwFormatVertOrient
*>(pItem
)->GetVertOrient() )
742 aOldV
.reset(static_cast<SwFormatVertOrient
*>(pItem
->Clone()));
743 const_cast<SfxItemSet
&>(rSet
).Put( SwFormatVertOrient( 0, text::VertOrientation::TOP
) );
747 pRet
= GetDoc()->MakeFlyAndMove( *pCursor
, rSet
, &aBoxes
, pParent
);
755 // calculate new position
756 // JP 24.03.97: also go via page links
757 // anchor should not lie in the shifted area
760 const SwFrame
* pAnch
= ::FindAnchor( GetLayout(), aPt
);
761 SwPosition
aPos( pAnch
->IsTextFrame()
762 ? *static_cast<SwTextFrame
const*>(pAnch
)->GetTextNodeForParaProps()
763 : *static_cast<const SwNoTextFrame
*>(pAnch
)->GetNode() );
765 if ( RndStdIds::FLY_AS_CHAR
== eRndId
)
767 assert(pAnch
->IsTextFrame());
768 aPos
= static_cast<SwTextFrame
const*>(pAnch
)->MapViewToModelPos(TextFrameIndex(0));
770 pOldAnchor
->SetAnchor( &aPos
);
772 // shifting of table selection is not Undo-capable. therefore
773 // changing the anchors should not be recorded
774 bool const bDoesUndo
=
775 GetDoc()->GetIDocumentUndoRedo().DoesUndo();
776 SwUndoId
nLastUndoId(SwUndoId::EMPTY
);
778 GetDoc()->GetIDocumentUndoRedo().GetLastUndoInfo(nullptr,
781 if (SwUndoId::INSLAYFMT
== nLastUndoId
)
783 GetDoc()->GetIDocumentUndoRedo().DoUndo(false);
787 const_cast<SfxItemSet
&>(rSet
).Put( *pOldAnchor
);
790 const_cast<SfxItemSet
&>(rSet
).Put( *aOldH
);
792 const_cast<SfxItemSet
&>(rSet
).Put( *aOldV
);
794 GetDoc()->SetFlyFrameAttr( *pRet
, const_cast<SfxItemSet
&>(rSet
) );
795 GetDoc()->GetIDocumentUndoRedo().DoUndo(bDoesUndo
);
798 GetDoc()->GetIDocumentUndoRedo().EndUndo( SwUndoId::INSLAYFMT
, nullptr );
801 /* If called from a shell try to propagate an
802 existing adjust item from rPos to the content node of the
804 pRet
= GetDoc()->MakeFlySection( eRndId
, &rPos
, &rSet
, pParent
, true );
808 SwFlyFrame
* pFrame
= pRet
->GetFrame( &aPt
);
810 SelectFlyFrame( *pFrame
);
813 GetLayout()->SetAssertFlyPages();
817 EndAllActionAndCall();
822 void SwFEShell::Insert( const OUString
& rGrfName
, const OUString
& rFltName
,
823 const Graphic
* pGraphic
,
824 const SfxItemSet
* pFlyAttrSet
)
826 SwFlyFrameFormat
* pFormat
= nullptr;
827 CurrShell
aCurr( this );
829 SwShellCursor
*pStartCursor
= dynamic_cast<SwShellCursor
*>(GetSwCursor());
830 SwShellCursor
*pCursor
= pStartCursor
;
836 // Has the anchor not been set or been set incompletely?
839 const SfxPoolItem
* pItem
;
840 if( SfxItemState::SET
== pFlyAttrSet
->GetItemState( RES_ANCHOR
, false,
843 SwFormatAnchor
* pAnchor
= const_cast<SwFormatAnchor
*>(static_cast<const SwFormatAnchor
*>(pItem
));
844 switch( pAnchor
->GetAnchorId())
846 case RndStdIds::FLY_AT_PARA
:
847 case RndStdIds::FLY_AT_CHAR
: // LAYER_IMPL
848 case RndStdIds::FLY_AS_CHAR
:
849 if( !pAnchor
->GetContentAnchor() )
851 pAnchor
->SetAnchor( pCursor
->GetPoint() );
854 case RndStdIds::FLY_AT_FLY
:
855 if( !pAnchor
->GetContentAnchor() )
857 lcl_SetNewFlyPos( pCursor
->GetNode(),
858 *pAnchor
, GetCursorDocPos() );
861 case RndStdIds::FLY_AT_PAGE
:
862 if( !pAnchor
->GetPageNum() )
864 pAnchor
->SetPageNum( pCursor
->GetPageNum(
865 true, &pCursor
->GetPtPos() ) );
873 pFormat
= GetDoc()->getIDocumentContentOperations().InsertGraphic(
878 OSL_ENSURE(pFormat
, "IDocumentContentOperations::InsertGraphic failed.");
880 pCursor
= pCursor
->GetNext();
881 } while( pCursor
!= pStartCursor
);
888 const Point
aPt( GetCursorDocPos() );
889 SwFlyFrame
* pFrame
= pFormat
->GetFrame( &aPt
);
893 // fdo#36681: Invalidate the content and layout to refresh
894 // the picture anchoring properly
895 SwPageFrame
* pPageFrame
= pFrame
->FindPageFrameOfAnchor();
896 pPageFrame
->InvalidateFlyLayout();
897 pPageFrame
->InvalidateContent();
899 SelectFlyFrame( *pFrame
);
902 GetLayout()->SetAssertFlyPages();
905 SwFlyFrameFormat
* SwFEShell::InsertObject( const svt::EmbeddedObjectRef
& xObj
,
906 SfxItemSet
* pFlyAttrSet
)
908 SwFlyFrameFormat
* pFormat
= nullptr;
909 CurrShell
aCurr( this );
912 for(const SwPaM
& rPaM
: GetCursor()->GetRingContainer())
914 pFormat
= GetDoc()->getIDocumentContentOperations().InsertEmbObject(
915 rPaM
, xObj
, pFlyAttrSet
);
916 OSL_ENSURE(pFormat
, "IDocumentContentOperations::InsertEmbObject failed.");
923 const Point
aPt( GetCursorDocPos() );
924 SwFlyFrame
* pFrame
= pFormat
->GetFrame( &aPt
);
927 SelectFlyFrame( *pFrame
);
929 GetLayout()->SetAssertFlyPages();
935 void SwFEShell::InsertDrawObj( SdrObject
& rDrawObj
,
936 const Point
& rInsertPosition
)
938 CurrShell
aCurr( this );
940 SfxItemSet
rFlyAttrSet( GetDoc()->GetAttrPool(), aFrameFormatSetRange
);
941 rFlyAttrSet
.Put( SwFormatAnchor( RndStdIds::FLY_AT_PARA
));
943 rFlyAttrSet
.Put( SwFormatSurround( css::text::WrapTextMode_THROUGH
) );
944 rDrawObj
.SetLayer( getIDocumentDrawModelAccess().GetHeavenId() );
946 // find anchor position
947 SwPaM
aPam( mxDoc
->GetNodes() );
949 SwCursorMoveState
aState( CursorMoveState::SetOnlyText
);
950 Point
aTmpPt( rInsertPosition
);
951 GetLayout()->GetModelPositionForViewPoint( aPam
.GetPoint(), aTmpPt
, &aState
);
952 const SwFrame
* pFrame
= aPam
.GetContentNode()->getLayoutFrame(GetLayout(), nullptr, nullptr);
953 const Point
aRelPos( rInsertPosition
.X() - pFrame
->getFrameArea().Left(),
954 rInsertPosition
.Y() - pFrame
->getFrameArea().Top() );
955 rDrawObj
.SetRelativePos( aRelPos
);
956 ::lcl_FindAnchorPos( *GetDoc(), rInsertPosition
, *pFrame
, rFlyAttrSet
);
958 // insert drawing object into the document creating a new <SwDrawFrameFormat> instance
959 SwDrawFrameFormat
* pFormat
= GetDoc()->getIDocumentContentOperations().InsertDrawObj( aPam
, rDrawObj
, rFlyAttrSet
);
961 // move object to visible layer
962 SwContact
* pContact
= static_cast<SwContact
*>(rDrawObj
.GetUserCall());
965 pContact
->MoveObjToVisibleLayer( &rDrawObj
);
970 pFormat
->SetName(rDrawObj
.GetName());
971 // select drawing object
972 Imp()->GetDrawView()->MarkObj( &rDrawObj
, Imp()->GetPageView() );
976 GetLayout()->SetAssertFlyPages();
980 void SwFEShell::GetPageObjs( std::vector
<SwFrameFormat
*>& rFillArr
)
984 for( auto pFormat
: *mxDoc
->GetSpzFrameFormats() )
986 if (RndStdIds::FLY_AT_PAGE
== pFormat
->GetAnchor().GetAnchorId())
988 rFillArr
.push_back( pFormat
);
993 void SwFEShell::SetPageObjsNewPage( std::vector
<SwFrameFormat
*>& rFillArr
)
995 if( rFillArr
.empty() )
1001 SwRootFrame
* pTmpRootFrame
= GetLayout();
1002 sal_uInt16 nMaxPage
= pTmpRootFrame
->GetPageNum();
1003 bool bTmpAssert
= false;
1004 for( auto pFormat
: rFillArr
)
1006 if (mxDoc
->GetSpzFrameFormats()->IsAlive(pFormat
))
1008 // FlyFormat is still valid, therefore process
1010 SwFormatAnchor
aNewAnchor( pFormat
->GetAnchor() );
1011 if (RndStdIds::FLY_AT_PAGE
!= aNewAnchor
.GetAnchorId())
1012 // Anchor has been changed, therefore: do not change!
1014 sal_uInt16 nNewPage
= aNewAnchor
.GetPageNum() + 1;
1015 if (nNewPage
> nMaxPage
)
1017 if ( RES_DRAWFRMFMT
== pFormat
->Which() )
1018 pFormat
->CallSwClientNotify(sw::DrawFrameFormatHint(sw::DrawFrameFormatHintId::PAGE_OUT_OF_BOUNDS
));
1020 pFormat
->DelFrames();
1023 aNewAnchor
.SetPageNum(nNewPage
);
1024 mxDoc
->SetAttr( aNewAnchor
, *pFormat
);
1029 pTmpRootFrame
->SetAssertFlyPages();
1035 // All attributes in the "baskets" will be filled with the attributes of the
1036 // current FlyFrames. Attributes which cannot be filled due to being at the
1037 // wrong place or which are ambiguous (multiple selections) will be removed.
1038 bool SwFEShell::GetFlyFrameAttr( SfxItemSet
&rSet
) const
1040 SwFlyFrame
*pFly
= GetSelectedOrCurrFlyFrame();
1043 OSL_ENSURE( false, "GetFlyFrameAttr, no Fly selected." );
1047 CurrShell
aCurr( const_cast<SwFEShell
*>(this) );
1049 if( !rSet
.Set( pFly
->GetFormat()->GetAttrSet() ) )
1052 // now examine all attributes. Remove forbidden attributes, then
1053 // get all remaining attributes and enter them
1054 const SfxPoolItem
* pItem
;
1055 if( SfxItemState::SET
== rSet
.GetItemState( RES_ANCHOR
, false, &pItem
) )
1057 const SwFormatAnchor
* pAnchor
= static_cast<const SwFormatAnchor
*>(pItem
);
1058 RndStdIds eType
= pAnchor
->GetAnchorId();
1060 if ( RndStdIds::FLY_AT_PAGE
!= eType
)
1062 // OD 12.11.2003 #i22341# - content anchor of anchor item is needed.
1063 // Thus, don't overwrite anchor item by default constructed anchor item.
1064 if ( RndStdIds::FLY_AS_CHAR
== eType
)
1066 rSet
.ClearItem( RES_OPAQUE
);
1067 rSet
.ClearItem( RES_SURROUND
);
1071 rSet
.SetParent( pFly
->GetFormat()->GetAttrSet().GetParent() );
1072 // attributes must be removed
1073 rSet
.ClearItem( RES_FILL_ORDER
);
1074 rSet
.ClearItem( RES_CNTNT
);
1075 //MA: remove first (Template by example etc.)
1076 rSet
.ClearItem( RES_CHAIN
);
1080 // Attributes of the current fly will change.
1081 bool SwFEShell::SetFlyFrameAttr( SfxItemSet
& rSet
)
1083 CurrShell
aCurr( this );
1088 SwFlyFrame
*pFly
= GetSelectedOrCurrFlyFrame();
1089 OSL_ENSURE(pFly
, "SetFlyFrameAttr, no Fly selected.");
1093 const Point
aPt( pFly
->getFrameArea().Pos() );
1095 if( SfxItemState::SET
== rSet
.GetItemState( RES_ANCHOR
, false ))
1096 sw_ChkAndSetNewAnchor( *pFly
, rSet
);
1097 SwFlyFrameFormat
* pFlyFormat
= pFly
->GetFormat();
1099 if( GetDoc()->SetFlyFrameAttr( *pFlyFormat
, rSet
))
1102 SwFlyFrame
* pFrame
= pFlyFormat
->GetFrame( &aPt
);
1104 SelectFlyFrame( *pFrame
);
1106 GetLayout()->SetAssertFlyPages();
1109 EndAllActionAndCall();
1115 SfxItemSet
SwFEShell::makeItemSetFromFormatAnchor(SfxItemPool
& rPool
, const SwFormatAnchor
&rAnchor
)
1117 // The set also includes VERT/HORI_ORIENT, because the align
1118 // shall be changed in FEShell::SetFlyFrameAttr/SetFlyFrameAnchor,
1119 // possibly as a result of the anchor change.
1120 SfxItemSet
aSet(rPool
, svl::Items
<RES_VERT_ORIENT
, RES_ANCHOR
>{});
1125 bool SwFEShell::SetDrawingAttr( SfxItemSet
& rSet
)
1128 CurrShell
aCurr( this );
1129 if ( !rSet
.Count() ||
1130 !Imp()->HasDrawView() )
1133 const SdrMarkList
&rMrkList
= Imp()->GetDrawView()->GetMarkedObjectList();
1134 if ( rMrkList
.GetMarkCount() != 1 )
1138 SdrObject
*pObj
= rMrkList
.GetMark( 0 )->GetMarkedSdrObj();
1139 SwFrameFormat
*pFormat
= FindFrameFormat( pObj
);
1141 if( SfxItemState::SET
== rSet
.GetItemState( RES_ANCHOR
, false ))
1143 RndStdIds nNew
= rSet
.Get( RES_ANCHOR
).GetAnchorId();
1144 if ( nNew
!= pFormat
->GetAnchor().GetAnchorId() )
1147 // #i26791# - clear anchor attribute in item set,
1148 // because method <ChgAnchor(..)> takes care of it.
1149 rSet
.ClearItem( RES_ANCHOR
);
1153 if( GetDoc()->SetFlyFrameAttr( *pFormat
, rSet
))
1156 SelectObj( Point(), 0, pObj
);
1158 EndAllActionAndCall();
1163 // Reset attributes contained in the set.
1164 void SwFEShell::ResetFlyFrameAttr( const SfxItemSet
* pSet
)
1166 CurrShell
aCurr( this );
1168 SwFlyFrame
*pFly
= GetSelectedOrCurrFlyFrame();
1169 OSL_ENSURE( pFly
, "SetFlyFrameAttr, no Fly selected." );
1175 SfxItemIter
aIter( *pSet
);
1176 for (const SfxPoolItem
* pItem
= aIter
.GetCurItem(); pItem
; pItem
= aIter
.NextItem())
1178 if( !IsInvalidItem( pItem
) )
1180 sal_uInt16 nWhich
= pItem
->Which();
1181 if( RES_ANCHOR
!= nWhich
&& RES_CHAIN
!= nWhich
&& RES_CNTNT
!= nWhich
)
1182 pFly
->GetFormat()->ResetFormatAttr( nWhich
);
1186 EndAllActionAndCall();
1187 GetDoc()->getIDocumentState().SetModified();
1190 // Returns frame-format if frame, otherwise 0
1191 SwFrameFormat
* SwFEShell::GetSelectedFrameFormat() const
1193 SwFrameFormat
* pRet
= nullptr;
1194 SwLayoutFrame
*pFly
= GetSelectedFlyFrame();
1195 if( pFly
&& ( pRet
= static_cast<SwFrameFormat
*>(pFly
->GetFormat()->DerivedFrom()) ) ==
1196 GetDoc()->GetDfltFrameFormat() )
1201 void SwFEShell::SetFrameFormat( SwFrameFormat
*pNewFormat
, bool bKeepOrient
, Point
const * pDocPos
)
1203 SwFlyFrame
*pFly
= nullptr;
1206 const SwFrameFormat
* pFormat
= GetFormatFromObj( *pDocPos
);
1208 if (const SwFlyFrameFormat
* pFlyFormat
= dynamic_cast<const SwFlyFrameFormat
*>(pFormat
))
1209 pFly
= pFlyFormat
->GetFrame();
1212 pFly
= GetSelectedFlyFrame();
1213 OSL_ENSURE( pFly
, "SetFrameFormat: no frame" );
1218 CurrShell
aCurr( this );
1220 SwFlyFrameFormat
* pFlyFormat
= pFly
->GetFormat();
1221 const Point
aPt( pFly
->getFrameArea().Pos() );
1223 std::unique_ptr
<SfxItemSet
> pSet
;
1224 const SfxPoolItem
* pItem
;
1225 if( SfxItemState::SET
== pNewFormat
->GetItemState( RES_ANCHOR
, false, &pItem
))
1227 pSet
.reset(new SfxItemSet( GetDoc()->GetAttrPool(), aFrameFormatSetRange
));
1228 pSet
->Put( *pItem
);
1229 if( !sw_ChkAndSetNewAnchor( *pFly
, *pSet
))
1235 if( GetDoc()->SetFrameFormatToFly( *pFlyFormat
, *pNewFormat
, pSet
.get(), bKeepOrient
))
1237 SwFlyFrame
* pFrame
= pFlyFormat
->GetFrame( &aPt
);
1239 SelectFlyFrame( *pFrame
);
1241 GetLayout()->SetAssertFlyPages();
1245 EndAllActionAndCall();
1248 const SwFrameFormat
* SwFEShell::GetFlyFrameFormat() const
1250 const SwFlyFrame
* pFly
= GetSelectedOrCurrFlyFrame();
1252 return pFly
->GetFormat();
1256 SwFrameFormat
* SwFEShell::GetFlyFrameFormat()
1258 SwFlyFrame
* pFly
= GetSelectedOrCurrFlyFrame();
1260 return pFly
->GetFormat();
1264 SwRect
SwFEShell::GetFlyRect() const
1266 SwFlyFrame
*pFly
= GetCurrFlyFrame(false);
1273 return pFly
->getFrameArea();
1276 SwRect
SwFEShell::GetObjRect() const
1278 if( Imp()->HasDrawView() )
1279 return Imp()->GetDrawView()->GetAllMarkedRect();
1287 void SwFEShell::SetObjRect( const SwRect
& rRect
)
1289 if ( Imp()->HasDrawView() )
1291 Imp()->GetDrawView()->SetAllMarkedRect( rRect
.SVRect() );
1292 CallChgLnk(); // call AttrChangeNotify on the UI-side.
1296 Size
SwFEShell::RequestObjectResize( const SwRect
&rRect
, const uno::Reference
< embed::XEmbeddedObject
>& xObj
)
1300 SwFlyFrame
*pFly
= FindFlyFrame( xObj
);
1303 aResult
= rRect
.SSize();
1307 aResult
= pFly
->getFramePrintArea().SSize();
1309 bool bPosProt
= pFly
->GetFormat()->GetProtect().IsPosProtected();
1310 bool bSizeProt
= pFly
->GetFormat()->GetProtect().IsSizeProtected();
1314 // MA we do not allow to clip the Fly, as the OLE server can
1315 // request various wishes. Clipping is done via the formatting.
1316 // Correct display is done by scaling.
1317 // Scaling is done by SwNoTextFrame::Format by calling
1318 // SwWrtShell::CalcAndSetScale()
1319 if ( rRect
.SSize() != pFly
->getFramePrintArea().SSize() && !bSizeProt
)
1321 Size
aSz( rRect
.SSize() );
1323 //JP 28.02.2001: Task 74707 - ask for fly in fly with automatic size
1325 const SwFrame
* pAnchor
;
1326 const SwFormatFrameSize
& rFrameSz
= pFly
->GetFormat()->GetFrameSize();
1327 if (m_bCheckForOLEInCaption
&&
1328 0 != rFrameSz
.GetWidthPercent() &&
1329 nullptr != (pAnchor
= pFly
->GetAnchorFrame()) &&
1330 pAnchor
->IsTextFrame() &&
1331 !pAnchor
->GetNext() && !pAnchor
->GetPrev() &&
1332 pAnchor
->GetUpper()->IsFlyFrame())
1334 // search for a sequence field:
1335 sw::MergedAttrIter
iter(*static_cast<SwTextFrame
const*>(pAnchor
));
1336 for (SwTextAttr
const* pHint
= iter
.NextAttr(); pHint
; pHint
= iter
.NextAttr())
1338 const SfxPoolItem
* pItem
= &pHint
->GetAttr();
1339 if( RES_TXTATR_FIELD
== pItem
->Which()
1340 && SwFieldTypesEnum::Sequence
== static_cast<const SwFormatField
*>(pItem
)->GetField()->GetTypeId() )
1342 // sequence field found
1343 SwFlyFrame
* pChgFly
= const_cast<SwFlyFrame
*>(static_cast<const SwFlyFrame
*>(pAnchor
->GetUpper()));
1344 // calculate the changed size:
1345 // width must change, height can change
1346 Size
aNewSz( aSz
.Width() + pChgFly
->getFrameArea().Width() -
1347 pFly
->getFramePrintArea().Width(), aSz
.Height() );
1349 SwFrameFormat
*pFormat
= pChgFly
->GetFormat();
1350 SwFormatFrameSize
aFrameSz( pFormat
->GetFrameSize() );
1351 aFrameSz
.SetWidth( aNewSz
.Width() );
1352 if( SwFrameSize::Minimum
!= aFrameSz
.GetHeightSizeType() )
1354 aNewSz
.AdjustHeight(pChgFly
->getFrameArea().Height() -
1355 pFly
->getFramePrintArea().Height() );
1356 if( std::abs( aNewSz
.Height() - pChgFly
->getFrameArea().Height()) > 1 )
1357 aFrameSz
.SetHeight( aNewSz
.Height() );
1359 // via Doc for the Undo!
1360 pFormat
->GetDoc()->SetAttr( aFrameSz
, *pFormat
);
1366 // set the new Size at the fly themself
1367 if ( !pFly
->getFramePrintArea().IsEmpty() )
1369 aSz
.AdjustWidth(pFly
->getFrameArea().Width() - pFly
->getFramePrintArea().Width() );
1370 aSz
.AdjustHeight(pFly
->getFrameArea().Height()- pFly
->getFramePrintArea().Height() );
1372 aResult
= pFly
->ChgSize( aSz
);
1374 // if the object changes, the contour is outside the object
1375 assert(pFly
->Lower()->IsNoTextFrame());
1376 SwNoTextNode
*pNd
= static_cast<SwNoTextFrame
*>(pFly
->Lower())->GetNode()->GetNoTextNode();
1378 pNd
->SetContour( nullptr );
1382 // if only the size is to be adjusted, a position is transported with
1384 Point
aPt( pFly
->getFramePrintArea().Pos() );
1385 aPt
+= pFly
->getFrameArea().Pos();
1386 if ( rRect
.Top() != LONG_MIN
&& rRect
.Pos() != aPt
&& !bPosProt
)
1389 aPt
.setX(aPt
.getX() - pFly
->getFramePrintArea().Left());
1390 aPt
.setY(aPt
.getY() - pFly
->getFramePrintArea().Top());
1392 // in case of paragraph-bound Flys, starting from the new position,
1393 // a new anchor is to be set. The anchor and the new RelPos are
1394 // calculated by the Fly and set
1395 if( pFly
->IsFlyAtContentFrame() )
1396 static_cast<SwFlyAtContentFrame
*>(pFly
)->SetAbsPos( aPt
);
1399 const SwFrameFormat
*pFormat
= pFly
->GetFormat();
1400 const SwFormatVertOrient
&rVert
= pFormat
->GetVertOrient();
1401 const SwFormatHoriOrient
&rHori
= pFormat
->GetHoriOrient();
1402 const tools::Long lXDiff
= aPt
.getX() - pFly
->getFrameArea().Left();
1403 const tools::Long lYDiff
= aPt
.getY() - pFly
->getFrameArea().Top();
1404 const Point
aTmp( rHori
.GetPos() + lXDiff
,
1405 rVert
.GetPos() + lYDiff
);
1406 pFly
->ChgRelPos( aTmp
);
1410 SwFlyFrameFormat
*pFlyFrameFormat
= pFly
->GetFormat();
1411 OSL_ENSURE( pFlyFrameFormat
, "fly frame format missing!" );
1412 if ( pFlyFrameFormat
)
1413 pFlyFrameFormat
->SetLastFlyFramePrtRectPos( pFly
->getFramePrintArea().Pos() ); //stores the value of last Prt rect
1420 SwFrameFormat
* SwFEShell::WizardGetFly()
1422 // do not search the Fly via the layout. Now we can delete a frame
1423 // without a valid layout. ( e.g. for the wizards )
1424 SwFrameFormats
& rSpzArr
= *mxDoc
->GetSpzFrameFormats();
1425 if( !rSpzArr
.empty() )
1427 SwNodeIndex
& rCursorNd
= GetCursor()->GetPoint()->nNode
;
1428 if( rCursorNd
.GetIndex() > mxDoc
->GetNodes().GetEndOfExtras().GetIndex() )
1429 // Cursor is in the body area!
1432 for( auto pFormat
: rSpzArr
)
1434 const SwNodeIndex
* pIdx
= pFormat
->GetContent( false ).GetContentIdx();
1435 SwStartNode
* pSttNd
;
1437 nullptr != ( pSttNd
= pIdx
->GetNode().GetStartNode() ) &&
1438 pSttNd
->GetIndex() < rCursorNd
.GetIndex() &&
1439 rCursorNd
.GetIndex() < pSttNd
->EndOfSectionIndex() )
1441 // found: return immediately
1449 void SwFEShell::SetFlyName( const OUString
& rName
)
1451 SwLayoutFrame
*pFly
= GetSelectedFlyFrame();
1453 GetDoc()->SetFlyName( *static_cast<SwFlyFrameFormat
*>(pFly
->GetFormat()), rName
);
1455 OSL_ENSURE( false, "no FlyFrame selected" );
1459 OUString
SwFEShell::GetFlyName() const
1461 SwLayoutFrame
*pFly
= GetSelectedFlyFrame();
1463 return pFly
->GetFormat()->GetName();
1465 OSL_ENSURE( false, "no FlyFrame selected" );
1469 uno::Reference
< embed::XEmbeddedObject
> SwFEShell::GetOleRef() const
1471 uno::Reference
< embed::XEmbeddedObject
> xObj
;
1472 SwFlyFrame
* pFly
= GetSelectedFlyFrame();
1473 if (pFly
&& pFly
->Lower() && pFly
->Lower()->IsNoTextFrame())
1475 SwOLENode
*pNd
= static_cast<SwNoTextFrame
*>(pFly
->Lower())->GetNode()->GetOLENode();
1477 xObj
= pNd
->GetOLEObj().GetOleRef();
1482 OUString
SwFEShell::GetUniqueGrfName() const
1484 return GetDoc()->GetUniqueGrfName();
1487 const SwFrameFormat
* SwFEShell::IsURLGrfAtPos( const Point
& rPt
, OUString
* pURL
,
1488 OUString
*pTargetFrameName
,
1489 OUString
*pDescription
) const
1491 if( !Imp()->HasDrawView() )
1495 const SwFrameFormat
* pRet
= nullptr;
1496 SwDrawView
*pDView
= const_cast<SwDrawView
*>(Imp()->GetDrawView());
1498 const auto nOld
= pDView
->GetHitTolerancePixel();
1499 pDView
->SetHitTolerancePixel( 2 );
1501 SdrObject
* pObj
= pDView
->PickObj(rPt
, pDView
->getHitTolLog(), pPV
, SdrSearchOptions::PICKMACRO
);
1502 SwVirtFlyDrawObj
* pFlyObj
= dynamic_cast<SwVirtFlyDrawObj
*>(pObj
);
1505 SwFlyFrame
*pFly
= pFlyObj
->GetFlyFrame();
1506 const SwFormatURL
&rURL
= pFly
->GetFormat()->GetURL();
1507 if( !rURL
.GetURL().isEmpty() || rURL
.GetMap() )
1509 bool bSetTargetFrameName
= pTargetFrameName
!= nullptr;
1510 bool bSetDescription
= pDescription
!= nullptr;
1511 if ( rURL
.GetMap() )
1513 IMapObject
*pObject
= pFly
->GetFormat()->GetIMapObject( rPt
, pFly
);
1514 if ( pObject
&& !pObject
->GetURL().isEmpty() )
1517 *pURL
= pObject
->GetURL();
1518 if ( bSetTargetFrameName
&& !pObject
->GetTarget().isEmpty() )
1520 bSetTargetFrameName
= false;
1521 *pTargetFrameName
= pObject
->GetTarget();
1523 if ( bSetDescription
)
1525 bSetDescription
= false;
1526 *pDescription
= pObject
->GetAltText();
1528 pRet
= pFly
->GetFormat();
1535 *pURL
= rURL
.GetURL();
1536 if( rURL
.IsServerMap() )
1538 // append the relative pixel position !!
1540 aPt
-= pFly
->getFrameArea().Pos();
1541 // without MapMode-Offset, without Offset, o ... !!!!!
1542 aPt
= GetOut()->LogicToPixel(
1543 aPt
, MapMode( MapUnit::MapTwip
) );
1544 *pURL
= *pURL
+ "?" + OUString::number( aPt
.getX() )
1545 + "," + OUString::number(aPt
.getY() );
1548 pRet
= pFly
->GetFormat();
1550 if ( bSetTargetFrameName
)
1551 *pTargetFrameName
= rURL
.GetTargetFrameName();
1552 if ( bSetDescription
)
1553 *pDescription
= pFly
->GetFormat()->GetName();
1556 pDView
->SetHitTolerancePixel( nOld
);
1560 const Graphic
*SwFEShell::GetGrfAtPos( const Point
&rPt
,
1561 OUString
&rName
, bool &rbLink
) const
1563 if( !Imp()->HasDrawView() )
1567 SwDrawView
*pDView
= const_cast<SwDrawView
*>(Imp()->GetDrawView());
1569 SdrObject
* pObj
= pDView
->PickObj(rPt
, pDView
->getHitTolLog(), pPV
);
1570 SwVirtFlyDrawObj
* pFlyObj
= dynamic_cast<SwVirtFlyDrawObj
*>(pObj
);
1573 SwFlyFrame
*pFly
= pFlyObj
->GetFlyFrame();
1574 if ( pFly
->Lower() && pFly
->Lower()->IsNoTextFrame() )
1576 SwGrfNode
*const pNd
= static_cast<SwNoTextFrame
*>(pFly
->Lower())->GetNode()->GetGrfNode();
1579 if ( pNd
->IsGrfLink() )
1581 // halfway ready graphic?
1582 ::sfx2::SvLinkSource
* pLnkObj
= pNd
->GetLink()->GetObj();
1583 if( pLnkObj
&& pLnkObj
->IsPending() )
1588 pNd
->GetFileFilterNms( &rName
, nullptr );
1589 if ( rName
.isEmpty() )
1590 rName
= pFly
->GetFormat()->GetName();
1591 return &pNd
->GetGrf(true);
1598 const SwFrameFormat
* SwFEShell::GetFormatFromObj( const Point
& rPt
, SwRect
** pRectToFill
) const
1600 SwFrameFormat
* pRet
= nullptr;
1602 if( Imp()->HasDrawView() )
1604 SdrPageView
* pPView
;
1606 SwDrawView
*pDView
= const_cast<SwDrawView
*>(Imp()->GetDrawView());
1608 const auto nOld
= pDView
->GetHitTolerancePixel();
1609 // tolerance for Drawing-SS
1610 pDView
->SetHitTolerancePixel( pDView
->GetMarkHdlSizePixel()/2 );
1612 SdrObject
* pObj
= pDView
->PickObj(rPt
, pDView
->getHitTolLog(), pPView
, SdrSearchOptions::PICKMARKABLE
);
1616 if (SwVirtFlyDrawObj
* pFlyObj
= dynamic_cast<SwVirtFlyDrawObj
*>(pObj
))
1617 pRet
= pFlyObj
->GetFormat();
1618 else if ( pObj
->GetUserCall() ) //not for group objects
1619 pRet
= static_cast<SwDrawContact
*>(pObj
->GetUserCall())->GetFormat();
1620 if(pRet
&& pRectToFill
)
1621 **pRectToFill
= pObj
->GetCurrentBoundRect();
1623 pDView
->SetHitTolerancePixel( nOld
);
1628 // returns a format too, if the point is over the text of any fly
1629 const SwFrameFormat
* SwFEShell::GetFormatFromAnyObj( const Point
& rPt
) const
1631 const SwFrameFormat
* pRet
= GetFormatFromObj( rPt
);
1632 if( !pRet
|| RES_FLYFRMFMT
== pRet
->Which() )
1634 SwPosition
aPos( *GetCursor()->GetPoint() );
1636 GetLayout()->GetModelPositionForViewPoint( &aPos
, aPt
);
1637 SwContentNode
*pNd
= aPos
.nNode
.GetNode().GetContentNode();
1638 std::pair
<Point
, bool> const tmp(rPt
, false);
1639 SwFrame
* pFrame
= pNd
->getLayoutFrame(GetLayout(), nullptr, &tmp
)->FindFlyFrame();
1640 pRet
= pFrame
? static_cast<SwLayoutFrame
*>(pFrame
)->GetFormat() : nullptr;
1645 ObjCntType
SwFEShell::GetObjCntType( const SdrObject
& rObj
)
1647 ObjCntType eType
= OBJCNT_NONE
;
1649 // investigate 'master' drawing object, if method
1650 // is called for a 'virtual' drawing object.
1651 const SdrObject
* pInvestigatedObj
;
1652 if (const SwDrawVirtObj
* pDrawVirtObj
= dynamic_cast<const SwDrawVirtObj
*>( &rObj
))
1654 pInvestigatedObj
= &(pDrawVirtObj
->GetReferencedObj());
1658 pInvestigatedObj
= &rObj
;
1661 if( SdrInventor::FmForm
== pInvestigatedObj
->GetObjInventor() )
1663 eType
= OBJCNT_CONTROL
;
1664 uno::Reference
< awt::XControlModel
> xModel
=
1665 static_cast<const SdrUnoObj
&>(*pInvestigatedObj
).GetUnoControlModel();
1669 OUString
sName("ButtonType");
1670 uno::Reference
< beans::XPropertySet
> xSet(xModel
, uno::UNO_QUERY
);
1672 uno::Reference
< beans::XPropertySetInfo
> xInfo
= xSet
->getPropertySetInfo();
1673 if(xInfo
->hasPropertyByName( sName
))
1675 aVal
= xSet
->getPropertyValue( sName
);
1676 if( aVal
.hasValue() && form::FormButtonType_URL
== *o3tl::doAccess
<form::FormButtonType
>(aVal
) )
1677 eType
= OBJCNT_URLBUTTON
;
1681 else if (const SwVirtFlyDrawObj
*pFlyObj
= dynamic_cast<const SwVirtFlyDrawObj
*>(pInvestigatedObj
))
1683 const SwFlyFrame
*pFly
= pFlyObj
->GetFlyFrame();
1684 if ( pFly
->Lower() && pFly
->Lower()->IsNoTextFrame() )
1686 if (static_cast<const SwNoTextFrame
*>(pFly
->Lower())->GetNode()->GetGrfNode())
1694 else if ( dynamic_cast<const SdrObjGroup
*>( pInvestigatedObj
) != nullptr )
1696 SwDrawContact
* pDrawContact( dynamic_cast<SwDrawContact
*>(GetUserCall( pInvestigatedObj
) ) );
1697 if ( !pDrawContact
)
1699 OSL_FAIL( "<SwFEShell::GetObjCntType(..)> - missing draw contact object" );
1700 eType
= OBJCNT_NONE
;
1704 SwFrameFormat
* pFrameFormat( pDrawContact
->GetFormat() );
1705 if ( !pFrameFormat
)
1707 OSL_FAIL( "<SwFEShell::GetObjCntType(..)> - missing frame format" );
1708 eType
= OBJCNT_NONE
;
1710 else if ( RndStdIds::FLY_AS_CHAR
!= pFrameFormat
->GetAnchor().GetAnchorId() )
1712 eType
= OBJCNT_GROUPOBJ
;
1717 eType
= OBJCNT_SIMPLE
;
1721 ObjCntType
SwFEShell::GetObjCntType( const Point
&rPt
, SdrObject
*&rpObj
) const
1723 ObjCntType eType
= OBJCNT_NONE
;
1725 if( Imp()->HasDrawView() )
1727 SdrPageView
* pPView
;
1729 SwDrawView
*pDView
= const_cast<SwDrawView
*>(Imp()->GetDrawView());
1731 const auto nOld
= pDView
->GetHitTolerancePixel();
1732 // tolerance for Drawing-SS
1733 pDView
->SetHitTolerancePixel( pDView
->GetMarkHdlSizePixel()/2 );
1735 SdrObject
* pObj
= pDView
->PickObj(rPt
, pDView
->getHitTolLog(), pPView
, SdrSearchOptions::PICKMARKABLE
);
1739 eType
= GetObjCntType( *rpObj
);
1742 pDView
->SetHitTolerancePixel( nOld
);
1747 ObjCntType
SwFEShell::GetObjCntTypeOfSelection() const
1749 ObjCntType eType
= OBJCNT_NONE
;
1751 if( Imp()->HasDrawView() )
1753 const SdrMarkList
&rMrkList
= Imp()->GetDrawView()->GetMarkedObjectList();
1754 for( size_t i
= 0, nE
= rMrkList
.GetMarkCount(); i
< nE
; ++i
)
1756 SdrObject
* pObj
= rMrkList
.GetMark( i
)->GetMarkedSdrObj();
1759 ObjCntType eTmp
= GetObjCntType( *pObj
);
1764 else if( eTmp
!= eType
)
1766 eType
= OBJCNT_DONTCARE
;
1767 // once DontCare, always DontCare!
1775 void SwFEShell::ReplaceSdrObj( const OUString
& rGrfName
, const Graphic
* pGrf
)
1777 CurrShell
aCurr( this );
1779 const SdrMarkList
*pMrkList
;
1780 if( !(Imp()->HasDrawView() && 1 ==
1781 ( pMrkList
= &Imp()->GetDrawView()->GetMarkedObjectList())->GetMarkCount()) )
1784 SdrObject
* pObj
= pMrkList
->GetMark( 0 )->GetMarkedSdrObj();
1785 SwFrameFormat
*pFormat
= FindFrameFormat( pObj
);
1787 // store attributes, then set the graphic
1788 SfxItemSet
aFrameSet( mxDoc
->GetAttrPool(),
1789 pFormat
->GetAttrSet().GetRanges() );
1790 aFrameSet
.Set( pFormat
->GetAttrSet() );
1792 // set size and position?
1793 if( dynamic_cast<const SwVirtFlyDrawObj
*>( pObj
) == nullptr )
1795 // then let's do it:
1796 const tools::Rectangle
&rBound
= pObj
->GetSnapRect();
1797 Point
aRelPos( pObj
->GetRelativePos() );
1799 const tools::Long nWidth
= rBound
.Right() - rBound
.Left();
1800 const tools::Long nHeight
= rBound
.Bottom() - rBound
.Top();
1801 aFrameSet
.Put( SwFormatFrameSize( SwFrameSize::Minimum
,
1802 std::max( nWidth
, tools::Long(MINFLY
) ),
1803 std::max( nHeight
, tools::Long(MINFLY
) )));
1805 if( SfxItemState::SET
!= aFrameSet
.GetItemState( RES_HORI_ORIENT
))
1806 aFrameSet
.Put( SwFormatHoriOrient( aRelPos
.getX(), text::HoriOrientation::NONE
, text::RelOrientation::FRAME
));
1808 if( SfxItemState::SET
!= aFrameSet
.GetItemState( RES_VERT_ORIENT
))
1809 aFrameSet
.Put( SwFormatVertOrient( aRelPos
.getY(), text::VertOrientation::NONE
, text::RelOrientation::FRAME
));
1818 // delete "Sdr-Object", insert the graphic instead
1821 GetDoc()->getIDocumentContentOperations().InsertGraphic(
1822 *GetCursor(), rGrfName
, "", pGrf
, &aFrameSet
, nullptr, nullptr);
1828 static sal_uInt16
SwFormatGetPageNum(const SwFlyFrameFormat
* pFormat
)
1830 OSL_ENSURE(pFormat
!= nullptr, "invalid argument");
1832 SwFlyFrame
* pFrame
= pFormat
->GetFrame();
1836 if (pFrame
!= nullptr)
1837 aResult
= pFrame
->GetPhyPageNum();
1839 aResult
= pFormat
->GetAnchor().GetPageNum();
1844 void SwFEShell::GetConnectableFrameFormats(SwFrameFormat
& rFormat
,
1845 const OUString
& rReference
,
1847 std::vector
< OUString
> & aPrevPageVec
,
1848 std::vector
< OUString
> & aThisPageVec
,
1849 std::vector
< OUString
> & aNextPageVec
,
1850 std::vector
< OUString
> & aRestVec
)
1854 SwFormatChain rChain
= rFormat
.GetChain();
1855 SwFrameFormat
* pOldChainNext
= rChain
.GetNext();
1856 SwFrameFormat
* pOldChainPrev
= rChain
.GetPrev();
1859 mxDoc
->Unchain(rFormat
);
1862 mxDoc
->Unchain(*pOldChainPrev
);
1864 const size_t nCnt
= mxDoc
->GetFlyCount(FLYCNTTYPE_FRM
);
1866 /* potential successors resp. predecessors */
1867 std::vector
< const SwFrameFormat
* > aTmpSpzArray
;
1869 mxDoc
->FindFlyByName(rReference
);
1871 for (size_t n
= 0; n
< nCnt
; ++n
)
1873 const SwFrameFormat
& rFormat1
= *(mxDoc
->GetFlyNum(n
, FLYCNTTYPE_FRM
));
1876 pFormat is a potential successor of rFormat if it is chainable after
1879 pFormat is a potential predecessor of rFormat if rFormat is chainable
1883 SwChainRet nChainState
;
1886 nChainState
= mxDoc
->Chainable(rFormat
, rFormat1
);
1888 nChainState
= mxDoc
->Chainable(rFormat1
, rFormat
);
1890 if (nChainState
== SwChainRet::OK
)
1892 aTmpSpzArray
.push_back(&rFormat1
);
1898 if (!aTmpSpzArray
.empty())
1900 aPrevPageVec
.clear();
1901 aThisPageVec
.clear();
1902 aNextPageVec
.clear();
1905 /* number of page rFormat resides on */
1906 sal_uInt16 nPageNum
= SwFormatGetPageNum(static_cast<SwFlyFrameFormat
*>(&rFormat
));
1908 for (const auto& rpFormat
: aTmpSpzArray
)
1910 const OUString aString
= rpFormat
->GetName();
1912 /* rFormat is not a valid successor or predecessor of
1914 if (aString
!= rReference
&& aString
!= rFormat
.GetName())
1917 SwFormatGetPageNum(static_cast<const SwFlyFrameFormat
*>(rpFormat
));
1919 if (nNum1
== nPageNum
-1)
1920 aPrevPageVec
.push_back(aString
);
1921 else if (nNum1
== nPageNum
)
1922 aThisPageVec
.push_back(aString
);
1923 else if (nNum1
== nPageNum
+ 1)
1924 aNextPageVec
.push_back(aString
);
1926 aRestVec
.push_back(aString
);
1933 mxDoc
->Chain(rFormat
, *pOldChainNext
);
1936 mxDoc
->Chain(*pOldChainPrev
, rFormat
);
1942 OUString
SwFEShell::GetObjTitle() const
1944 if ( Imp()->HasDrawView() )
1946 const SdrMarkList
*pMrkList
= &Imp()->GetDrawView()->GetMarkedObjectList();
1947 if ( pMrkList
->GetMarkCount() == 1 )
1949 const SdrObject
* pObj
= pMrkList
->GetMark( 0 )->GetMarkedSdrObj();
1950 const SwFrameFormat
* pFormat
= FindFrameFormat( pObj
);
1951 if ( pFormat
->Which() == RES_FLYFRMFMT
)
1953 return static_cast<const SwFlyFrameFormat
*>(pFormat
)->GetObjTitle();
1955 return pObj
->GetTitle();
1962 void SwFEShell::SetObjTitle( const OUString
& rTitle
)
1964 if ( !Imp()->HasDrawView() )
1967 const SdrMarkList
*pMrkList
= &Imp()->GetDrawView()->GetMarkedObjectList();
1968 if ( pMrkList
->GetMarkCount() != 1 )
1971 SdrObject
* pObj
= pMrkList
->GetMark( 0 )->GetMarkedSdrObj();
1972 SwFrameFormat
* pFormat
= FindFrameFormat( pObj
);
1973 if ( pFormat
->Which() == RES_FLYFRMFMT
)
1975 GetDoc()->SetFlyFrameTitle( dynamic_cast<SwFlyFrameFormat
&>(*pFormat
),
1980 pObj
->SetTitle( rTitle
);
1984 OUString
SwFEShell::GetObjDescription() const
1986 if ( Imp()->HasDrawView() )
1988 const SdrMarkList
*pMrkList
= &Imp()->GetDrawView()->GetMarkedObjectList();
1989 if ( pMrkList
->GetMarkCount() == 1 )
1991 const SdrObject
* pObj
= pMrkList
->GetMark( 0 )->GetMarkedSdrObj();
1992 const SwFrameFormat
* pFormat
= FindFrameFormat( pObj
);
1993 if ( pFormat
->Which() == RES_FLYFRMFMT
)
1995 return dynamic_cast<const SwFlyFrameFormat
&>(*pFormat
).GetObjDescription();
1997 return pObj
->GetDescription();
2004 void SwFEShell::SetObjDescription( const OUString
& rDescription
)
2006 if ( !Imp()->HasDrawView() )
2009 const SdrMarkList
*pMrkList
= &Imp()->GetDrawView()->GetMarkedObjectList();
2010 if ( pMrkList
->GetMarkCount() != 1 )
2013 SdrObject
* pObj
= pMrkList
->GetMark( 0 )->GetMarkedSdrObj();
2014 SwFrameFormat
* pFormat
= FindFrameFormat( pObj
);
2015 if ( pFormat
->Which() == RES_FLYFRMFMT
)
2017 GetDoc()->SetFlyFrameDescription(dynamic_cast<SwFlyFrameFormat
&>(*pFormat
),
2022 pObj
->SetDescription( rDescription
);
2026 void SwFEShell::AlignFormulaToBaseline( const uno::Reference
< embed::XEmbeddedObject
>& xObj
)
2028 #if OSL_DEBUG_LEVEL > 0
2029 SvGlobalName
aCLSID( xObj
->getClassID() );
2030 const bool bStarMath
= ( SotExchange::IsMath( aCLSID
) != 0 );
2031 OSL_ENSURE( bStarMath
, "AlignFormulaToBaseline should only be called for Math objects" );
2037 SwFlyFrame
* pFly
= FindFlyFrame( xObj
);
2038 OSL_ENSURE( pFly
, "No fly frame!" );
2039 SwFrameFormat
* pFrameFormat
= pFly
? pFly
->GetFormat() : nullptr;
2041 // baseline to baseline alignment should only be applied to formulas anchored as char
2042 if ( !pFly
|| !pFrameFormat
|| RndStdIds::FLY_AS_CHAR
!= pFrameFormat
->GetAnchor().GetAnchorId() )
2045 // get baseline from Math object
2047 if( svt::EmbeddedObjectRef::TryRunningState( xObj
) )
2049 uno::Reference
< beans::XPropertySet
> xSet( xObj
->getComponent(), uno::UNO_QUERY
);
2054 aBaseline
= xSet
->getPropertyValue("BaseLine");
2056 catch ( uno::Exception
& )
2058 OSL_FAIL( "Baseline could not be retrieved from Starmath!" );
2063 sal_Int32 nBaseline
= ::comphelper::getINT32(aBaseline
);
2064 const MapMode
aSourceMapMode( MapUnit::Map100thMM
);
2065 const MapMode
aTargetMapMode( MapUnit::MapTwip
);
2066 nBaseline
= OutputDevice::LogicToLogic( nBaseline
, aSourceMapMode
.GetMapUnit(), aTargetMapMode
.GetMapUnit() );
2068 OSL_ENSURE( nBaseline
> 0, "Wrong value of Baseline while retrieving from Starmath!" );
2069 //nBaseline must be moved by aPrt position
2070 const SwFlyFrameFormat
*pFlyFrameFormat
= pFly
->GetFormat();
2071 OSL_ENSURE( pFlyFrameFormat
, "fly frame format missing!" );
2072 if ( pFlyFrameFormat
)
2073 nBaseline
+= pFlyFrameFormat
->GetLastFlyFramePrtRectPos().Y();
2075 const SwFormatVertOrient
&rVert
= pFrameFormat
->GetVertOrient();
2076 SwFormatVertOrient
aVert( rVert
);
2077 aVert
.SetPos( -nBaseline
);
2078 aVert
.SetVertOrient( css::text::VertOrientation::NONE
);
2080 pFrameFormat
->LockModify();
2081 pFrameFormat
->SetFormatAttr( aVert
);
2082 pFrameFormat
->UnlockModify();
2083 pFly
->InvalidatePos();
2087 void SwFEShell::AlignAllFormulasToBaseline()
2092 SwNodeIndex
aIdx( *GetNodes().GetEndOfAutotext().StartOfSectionNode(), 1 );
2093 while ( nullptr != (pStNd
= aIdx
.GetNode().GetStartNode()) )
2096 SwOLENode
*pOleNode
= dynamic_cast< SwOLENode
* >( &aIdx
.GetNode() );
2099 const uno::Reference
< embed::XEmbeddedObject
> & xObj( pOleNode
->GetOLEObj().GetOleRef() );
2102 SvGlobalName
aCLSID( xObj
->getClassID() );
2103 if ( SotExchange::IsMath( aCLSID
) )
2104 AlignFormulaToBaseline( xObj
);
2108 aIdx
.Assign( *pStNd
->EndOfSectionNode(), + 1 );
2114 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */