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 <osl/diagnose.h>
34 #include <fmtanchr.hxx>
35 #include <fmtcntnt.hxx>
36 #include <fmtornt.hxx>
38 #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>
51 #include <IDocumentRedlineAccess.hxx>
52 #include <redline.hxx>
54 #include <dflyobj.hxx>
55 #include <dcontact.hxx>
59 #include <swtable.hxx>
61 #include <flyfrms.hxx>
65 #include <txatbase.hxx>
67 #include <notxtfrm.hxx>
68 #include <HandleAnchorNodeChg.hxx>
70 #include <fmtsrnd.hxx>
73 #include <fmtcnct.hxx>
74 #include <frameformats.hxx>
75 #include <textboxhelper.hxx>
78 using namespace ::com::sun::star
;
80 // Based on the request, changes to the specific layouts will be made, to
82 static bool lcl_SetNewFlyPos( const SwNode
& rNode
, SwFormatAnchor
& rAnchor
,
86 const SwStartNode
* pStNode
= rNode
.FindFlyStartNode();
89 SwPosition
aPos( *pStNode
);
90 rAnchor
.SetAnchor( &aPos
);
95 const SwContentNode
*pCntNd
= rNode
.GetContentNode();
96 std::pair
<Point
, bool> const tmp(rPt
, false);
97 const SwContentFrame
* pCFrame
= pCntNd
? pCntNd
->getLayoutFrame(
98 pCntNd
->GetDoc().getIDocumentLayoutAccess().GetCurrentLayout(),
99 nullptr, &tmp
) : nullptr;
100 const SwPageFrame
*pPg
= pCFrame
? pCFrame
->FindPageFrame() : nullptr;
102 rAnchor
.SetPageNum( pPg
? pPg
->GetPhyPageNum() : 1 );
103 rAnchor
.SetType( RndStdIds::FLY_AT_PAGE
);
108 static bool lcl_FindAnchorPos(
111 const SwFrame
& rFrame
,
115 SwFormatAnchor
aNewAnch( rSet
.Get( RES_ANCHOR
) );
116 RndStdIds nNew
= aNewAnch
.GetAnchorId();
117 const SwFrame
*pNewAnch
;
119 //determine new anchor
120 Point
aTmpPnt( rPt
);
123 case RndStdIds::FLY_AS_CHAR
: // also include this?
124 case RndStdIds::FLY_AT_PARA
:
125 case RndStdIds::FLY_AT_CHAR
: // LAYER_IMPL
127 // starting from the upper-left corner of the Fly,
128 // search nearest ContentFrame
129 const SwFrame
* pFrame
= rFrame
.IsFlyFrame() ? static_cast<const SwFlyFrame
&>(rFrame
).GetAnchorFrame()
131 pNewAnch
= ::FindAnchor( pFrame
, aTmpPnt
);
132 if( pNewAnch
->IsProtected() )
137 SwPosition
aPos( pNewAnch
->IsTextFrame()
138 ? *static_cast<SwTextFrame
const*>(pNewAnch
)->GetTextNodeForParaProps()
139 : *static_cast<const SwNoTextFrame
*>(pNewAnch
)->GetNode() );
140 if ((RndStdIds::FLY_AT_CHAR
== nNew
) || (RndStdIds::FLY_AS_CHAR
== nNew
))
142 // textnode should be found, as only in those
143 // a content bound frame can be anchored
144 SwCursorMoveState
aState( CursorMoveState::SetOnlyText
);
145 aTmpPnt
.setX(aTmpPnt
.getX() - 1); // do not land in the fly!
146 if( !pNewAnch
->GetModelPositionForViewPoint( &aPos
, aTmpPnt
, &aState
) )
148 assert(pNewAnch
->IsTextFrame()); // because AT_CHAR/AS_CHAR
149 SwTextFrame
const*const pTextFrame(
150 static_cast<SwTextFrame
const*>(pNewAnch
));
151 if( pNewAnch
->getFrameArea().Bottom() < aTmpPnt
.Y() )
153 aPos
= pTextFrame
->MapViewToModelPos(TextFrameIndex(0));
157 aPos
= pTextFrame
->MapViewToModelPos(
158 TextFrameIndex(pTextFrame
->GetText().getLength()));
163 if ( SwCursorShell::PosInsideInputField( aPos
) )
165 aPos
.SetContent( SwCursorShell::StartOfInputFieldAtPos( aPos
) );
169 aNewAnch
.SetAnchor( &aPos
);
173 case RndStdIds::FLY_AT_FLY
: // LAYER_IMPL
175 // starting from the upper-left corner of the Fly
176 // search nearest SwFlyFrame
177 SwCursorMoveState
aState( CursorMoveState::SetOnlyText
);
178 SwPosition
aPos( rDoc
.GetNodes() );
179 aTmpPnt
.setX(aTmpPnt
.getX() - 1); // do not land in the fly!
180 rDoc
.getIDocumentLayoutAccess().GetCurrentLayout()->GetModelPositionForViewPoint( &aPos
, aTmpPnt
, &aState
);
181 pNewAnch
= ::FindAnchor(
182 aPos
.GetNode().GetContentNode()->getLayoutFrame(rFrame
.getRootFrame(), nullptr, nullptr),
183 aTmpPnt
)->FindFlyFrame();
185 if( pNewAnch
&& &rFrame
!= pNewAnch
&& !pNewAnch
->IsProtected() )
187 aPos
.Assign( *static_cast<const SwFlyFrame
*>(pNewAnch
)->GetFormat()->GetContent().
189 aNewAnch
.SetAnchor( &aPos
);
194 nNew
= RndStdIds::FLY_AT_PAGE
;
195 aNewAnch
.SetType( nNew
);
198 case RndStdIds::FLY_AT_PAGE
:
199 pNewAnch
= rFrame
.FindPageFrame();
200 aNewAnch
.SetPageNum( pNewAnch
->GetPhyPageNum() );
204 OSL_ENSURE( false, "Wrong Id for new anchor." );
207 rSet
.Put( aNewAnch
);
211 //! also used in unoframe.cxx
213 bool sw_ChkAndSetNewAnchor(
214 const SwFlyFrame
& rFly
,
217 const SwFrameFormat
& rFormat
= *rFly
.GetFormat();
218 const SwFormatAnchor
&rOldAnch
= rFormat
.GetAnchor();
219 const RndStdIds nOld
= rOldAnch
.GetAnchorId();
221 RndStdIds nNew
= rSet
.Get( RES_ANCHOR
).GetAnchorId();
226 SwDoc
* pDoc
= const_cast<SwDoc
*>(rFormat
.GetDoc());
228 #if OSL_DEBUG_LEVEL > 0
229 OSL_ENSURE( !(nNew
== RndStdIds::FLY_AT_PAGE
&&
230 (RndStdIds::FLY_AT_PARA
==nOld
|| RndStdIds::FLY_AT_CHAR
==nOld
|| RndStdIds::FLY_AS_CHAR
==nOld
) &&
231 pDoc
->IsInHeaderFooter( *rOldAnch
.GetAnchorNode() )),
232 "forbidden anchor change in Head/Foot." );
235 return ::lcl_FindAnchorPos( *pDoc
, rFly
.getFrameArea().Pos(), rFly
, rSet
);
238 void SwFEShell::SelectFlyFrame( SwFlyFrame
& rFrame
)
240 CurrShell
aCurr( this );
242 // The frame is new, thus select it.
243 // !! Always select the frame, if it's not selected.
244 // - it could be a new "old" one because the anchor was changed
245 // - "old" frames have had to be selected previously otherwise they could
246 // not have been changed
247 // The frames should not be selected by the document position, because
248 // it should have been selected!
249 SwViewShellImp
*pImpl
= Imp();
253 OSL_ENSURE( rFrame
.IsFlyFrame(), "SelectFlyFrame wants a Fly" );
255 // nothing to be done if the Fly already was selected
256 if (GetSelectedFlyFrame() == &rFrame
)
259 // assure the anchor is drawn
260 if( rFrame
.IsFlyInContentFrame() && rFrame
.GetAnchorFrame() )
261 rFrame
.GetAnchorFrame()->SetCompletePaint();
263 if( pImpl
->GetDrawView()->AreObjectsMarked() )
264 pImpl
->GetDrawView()->UnmarkAll();
266 pImpl
->GetDrawView()->MarkObj( rFrame
.GetVirtDrawObj(),
267 pImpl
->GetPageView() );
269 rFrame
.SelectionHasChanged(this);
277 SwFlyFrame
* SwFEShell::GetSelectedFlyFrame() const
279 if ( Imp()->HasDrawView() )
281 // A Fly is only accessible if it is selected
282 const SdrMarkList
&rMrkList
= Imp()->GetDrawView()->GetMarkedObjectList();
283 if( rMrkList
.GetMarkCount() != 1 )
286 SdrObject
*pO
= rMrkList
.GetMark( 0 )->GetMarkedSdrObj();
288 SwVirtFlyDrawObj
*pFlyObj
= dynamic_cast<SwVirtFlyDrawObj
*>(pO
);
290 return pFlyObj
? pFlyObj
->GetFlyFrame() : nullptr;
295 // Get current fly in which the cursor is positioned
296 SwFlyFrame
* SwFEShell::GetCurrFlyFrame(const bool bCalcFrame
) const
298 SwContentFrame
*pContent
= GetCurrFrame(bCalcFrame
);
299 return pContent
? pContent
->FindFlyFrame() : nullptr;
302 // Get selected fly, but if none Get current fly in which the cursor is positioned
303 SwFlyFrame
* SwFEShell::GetSelectedOrCurrFlyFrame() const
305 SwFlyFrame
*pFly
= GetSelectedFlyFrame();
308 return GetCurrFlyFrame();
311 // Returns non-null pointer, if the current Fly could be anchored to another one (so it is inside)
312 const SwFrameFormat
* SwFEShell::IsFlyInFly()
314 CurrShell
aCurr( this );
316 if ( !Imp()->HasDrawView() )
319 const SdrMarkList
&rMrkList
= Imp()->GetDrawView()->GetMarkedObjectList();
320 if ( !rMrkList
.GetMarkCount() )
322 SwFlyFrame
*pFly
= GetCurrFlyFrame(false);
325 return pFly
->GetFormat();
327 else if ( rMrkList
.GetMarkCount() != 1 ||
328 !GetUserCall(rMrkList
.GetMark( 0 )->GetMarkedSdrObj()) )
331 SdrObject
*pObj
= rMrkList
.GetMark( 0 )->GetMarkedSdrObj();
333 SwFrameFormat
*pFormat
= FindFrameFormat( pObj
);
334 if( pFormat
&& RndStdIds::FLY_AT_FLY
== pFormat
->GetAnchor().GetAnchorId() )
337 if (SwVirtFlyDrawObj
* pFlyObj
= dynamic_cast<SwVirtFlyDrawObj
*>(pObj
))
339 pFly
= pFlyObj
->GetFlyFrame()->GetAnchorFrame();
343 pFly
= static_cast<SwDrawContact
*>(GetUserCall(pObj
))->GetAnchorFrame(pObj
);
346 OSL_ENSURE( pFly
, "IsFlyInFly: Where's my anchor?" );
347 OSL_ENSURE( pFly
->IsFlyFrame(), "IsFlyInFly: Funny anchor!" );
348 return static_cast<const SwFlyFrame
*>(pFly
)->GetFormat();
351 Point aTmpPos
= pObj
->GetCurrentBoundRect().TopLeft();
355 SwCursorMoveState
aState( CursorMoveState::SetOnlyText
);
356 SwNodeIndex
aSwNodeIndex( GetDoc()->GetNodes() );
357 SwPosition
aPos( aSwNodeIndex
);
358 Point
aPoint( aTmpPos
);
359 aPoint
.setX(aPoint
.getX() - 1); //do not land in the fly!!
360 GetLayout()->GetModelPositionForViewPoint( &aPos
, aPoint
, &aState
);
361 // determine text frame by left-top-corner of object
362 SwContentNode
*pNd
= aPos
.GetNode().GetContentNode();
363 std::pair
<Point
, bool> const tmp(aTmpPos
, false);
364 pTextFrame
= pNd
? pNd
->getLayoutFrame(GetLayout(), nullptr, &tmp
) : nullptr;
366 const SwFrame
*pTmp
= pTextFrame
? ::FindAnchor(pTextFrame
, aTmpPos
) : nullptr;
367 const SwFlyFrame
*pFly
= pTmp
? pTmp
->FindFlyFrame() : nullptr;
369 return pFly
->GetFormat();
373 void SwFEShell::SetFlyPos( const Point
& rAbsPos
)
375 CurrShell
aCurr( this );
377 // Determine reference point in document coordinates
378 SwFlyFrame
*pFly
= GetCurrFlyFrame(false);
382 //SwSaveHdl aSaveX( Imp() );
384 // Set an anchor starting from the absolute position for paragraph bound Flys
385 // Anchor and new RelPos will be calculated and set by the Fly
386 if ( pFly
->IsFlyAtContentFrame() )
388 if(pFly
->IsFlyFreeFrame() && static_cast< SwFlyFreeFrame
* >(pFly
)->isTransformableSwFrame())
390 // RotateFlyFrame3: When we have a change and are in transformed state (e.g. rotation used),
391 // we need to correct the absolute position (rAbsPos) which was created in
392 // transformed coordinates to untransformed state
393 TransformableSwFrame
* pTransformableSwFrame(static_cast<SwFlyFreeFrame
*>(pFly
)->getTransformableSwFrame());
394 const SwRect
aUntransformedFrameArea(pTransformableSwFrame
->getUntransformedFrameArea());
395 const Point
aNewAbsPos(
396 rAbsPos
.X() + aUntransformedFrameArea
.Left() - pFly
->getFrameArea().Left(),
397 rAbsPos
.Y() + aUntransformedFrameArea
.Top() - pFly
->getFrameArea().Top());
398 static_cast<SwFlyAtContentFrame
*>(pFly
)->SetAbsPos(aNewAbsPos
);
402 static_cast<SwFlyAtContentFrame
*>(pFly
)->SetAbsPos( rAbsPos
);
407 const SwFrame
*pAnch
= pFly
->GetAnchorFrame();
408 Point
aOrient( pAnch
->getFrameArea().Pos() );
410 if ( pFly
->IsFlyInContentFrame() )
411 aOrient
.setX(rAbsPos
.getX());
414 aOrient
.setX(rAbsPos
.getX() - aOrient
.getX());
415 aOrient
.setY(rAbsPos
.getY() - aOrient
.getY());
416 pFly
->ChgRelPos( aOrient
);
418 CallChgLnk(); // call the AttrChangeNotify on the UI-side.
421 Point
SwFEShell::FindAnchorPos( const Point
& rAbsPos
, bool bMoveIt
)
425 CurrShell
aCurr( this );
427 if ( !Imp()->HasDrawView() )
430 const SdrMarkList
&rMrkList
= Imp()->GetDrawView()->GetMarkedObjectList();
431 if (rMrkList
.GetMarkCount() != 1)
434 SdrObject
* pObj
= rMrkList
.GetMark(0)->GetMarkedSdrObj();
436 if (!GetUserCall(pObj
))
440 SwAnchoredObject
* pAnchoredObj
= ::GetUserCall( pObj
)->GetAnchoredObj( pObj
);
441 SwFrameFormat
& rFormat
= pAnchoredObj
->GetFrameFormat();
442 const RndStdIds nAnchorId
= rFormat
.GetAnchor().GetAnchorId();
444 if ( RndStdIds::FLY_AS_CHAR
== nAnchorId
)
447 bool bFlyFrame
= dynamic_cast<SwVirtFlyDrawObj
*>(pObj
) != nullptr;
449 bool bTextBox
= false;
450 if (rFormat
.Which() == RES_DRAWFRMFMT
)
452 bTextBox
= SwTextBoxHelper::isTextBox(&rFormat
, RES_DRAWFRMFMT
, pObj
);
455 SwFlyFrame
* pFly
= nullptr;
456 const SwFrame
* pFooterOrHeader
= nullptr;
460 // Calculate reference point in document coordinates
461 SwContentFrame
*pContent
= GetCurrFrame( false );
464 pFly
= pContent
->FindFlyFrame();
467 const SwFrame
* pOldAnch
= pFly
->GetAnchorFrame();
470 if ( RndStdIds::FLY_AT_PAGE
!= nAnchorId
)
472 pFooterOrHeader
= pContent
->FindFooterOrHeader();
478 = dynamic_cast<const SwFlyFrameFormat
*>(SwTextBoxHelper::getOtherTextBoxFormat(
479 &rFormat
, RES_DRAWFRMFMT
, pObj
));
482 pFly
= pFlyFormat
->GetFrame();
486 // set <pFooterOrHeader> also for drawing
487 // objects, but not for control objects.
488 // Necessary for moving 'anchor symbol' at the user interface inside header/footer.
489 else if ( !::CheckControlLayer( pObj
) )
491 SwContentFrame
*pContent
= GetCurrFrame( false );
494 pFooterOrHeader
= pContent
->FindFooterOrHeader();
497 // Search nearest SwFlyFrame starting from the upper-left corner
499 SwContentFrame
*pTextFrame
= nullptr;
501 SwCursorMoveState
aState( CursorMoveState::SetOnlyText
);
502 SwPosition
aPos( GetDoc()->GetNodes().GetEndOfExtras() );
503 Point
aTmpPnt( rAbsPos
);
504 GetLayout()->GetModelPositionForViewPoint( &aPos
, aTmpPnt
, &aState
);
505 if (aPos
.GetNode() != GetDoc()->GetNodes().GetEndOfExtras()
506 && (nAnchorId
!= RndStdIds::FLY_AT_CHAR
|| !PosInsideInputField(aPos
)))
508 SwContentNode
* pCNode
= aPos
.GetNode().GetContentNode();
510 pTextFrame
= pCNode
->getLayoutFrame(GetLayout(), &aPos
, nullptr);
513 const SwFrame
*pNewAnch
= nullptr;
514 if( pTextFrame
!= nullptr )
516 if ( RndStdIds::FLY_AT_PAGE
== nAnchorId
)
518 pNewAnch
= pTextFrame
->FindPageFrame();
522 pNewAnch
= ::FindAnchor( pTextFrame
, rAbsPos
);
524 if( RndStdIds::FLY_AT_FLY
== nAnchorId
) // LAYER_IMPL
526 pNewAnch
= pNewAnch
->FindFlyFrame();
531 if( pNewAnch
&& !pNewAnch
->IsProtected() )
533 const SwFlyFrame
* pCheck
= (bFlyFrame
|| bTextBox
) ? pNewAnch
->FindFlyFrame() : nullptr;
534 // If we land inside the frame, make sure
535 // that the frame does not land inside its own content
540 const SwFrame
*pTmp
= pCheck
->GetAnchorFrame();
541 pCheck
= pTmp
? pTmp
->FindFlyFrame() : nullptr;
544 // Do not switch from header/footer to another area,
545 // do not switch to a header/footer
547 pFooterOrHeader
== pNewAnch
->FindFooterOrHeader() )
549 aRet
= pNewAnch
->GetFrameAnchorPos( ::HasWrap( pObj
) );
551 if ( bMoveIt
|| (nAnchorId
== RndStdIds::FLY_AT_CHAR
) )
553 SwFormatAnchor
aAnch( rFormat
.GetAnchor() );
556 case RndStdIds::FLY_AT_PARA
:
558 SwPosition
pos(pTextFrame
->IsTextFrame()
559 ? *static_cast<SwTextFrame
const*>(pTextFrame
)->GetTextNodeForParaProps()
560 : *static_cast<const SwNoTextFrame
*>(pTextFrame
)->GetNode());
561 aAnch
.SetAnchor( &pos
);
564 case RndStdIds::FLY_AT_PAGE
:
566 aAnch
.SetPageNum( static_cast<const SwPageFrame
*>(pNewAnch
)->
571 case RndStdIds::FLY_AT_FLY
:
573 SwPosition
aPos( *static_cast<const SwFlyFrame
*>(pNewAnch
)->GetFormat()->
574 GetContent().GetContentIdx() );
575 aAnch
.SetAnchor( &aPos
);
579 case RndStdIds::FLY_AT_CHAR
:
581 SwPosition pos
= *aAnch
.GetContentAnchor();
582 Point
aTmpPnt( rAbsPos
);
583 if( pTextFrame
->GetModelPositionForViewPoint( &pos
, aTmpPnt
) )
586 pTextFrame
->GetCharRect( aTmpRect
, pos
);
587 aRet
= aTmpRect
.Pos();
591 pos
= static_cast<SwTextFrame
const*>(pTextFrame
)->MapViewToModelPos(TextFrameIndex(0));
593 aAnch
.SetAnchor( &pos
);
604 // --> handle change of anchor node:
605 // if count of the anchor frame also change, the fly frames have to be
606 // re-created. Thus, delete all fly frames except the <this> before the
607 // anchor attribute is change and re-create them afterwards.
609 std::unique_ptr
<SwHandleAnchorNodeChg
> pHandleAnchorNodeChg
;
610 SwFlyFrameFormat
* pFlyFrameFormat( dynamic_cast<SwFlyFrameFormat
*>(&rFormat
) );
611 if ( pFlyFrameFormat
)
613 pHandleAnchorNodeChg
.reset(
614 new SwHandleAnchorNodeChg( *pFlyFrameFormat
, aAnch
));
616 rFormat
.GetDoc()->SetAttr( aAnch
, rFormat
);
617 if (SwTextBoxHelper::getOtherTextBoxFormat(&rFormat
, RES_DRAWFRMFMT
,
620 if (pObj
->getChildrenOfSdrObject())
623 i
< pObj
->getChildrenOfSdrObject()->GetObjCount(); ++i
)
624 SwTextBoxHelper::changeAnchor(
625 &rFormat
, pObj
->getChildrenOfSdrObject()->GetObj(i
));
628 SwTextBoxHelper::syncFlyFrameAttr(
629 rFormat
, rFormat
.GetAttrSet(), pObj
);
632 // #i28701# - no call of method
633 // <CheckCharRectAndTopOfLine()> for to-character anchored
634 // Writer fly frame needed. This method call can cause a
635 // format of the anchor frame, which is no longer intended.
636 // Instead clear the anchor character rectangle and
637 // the top of line values for all to-character anchored objects.
638 pAnchoredObj
->ClearCharRectAndTopOfLine();
643 SwRect
aTmpRect( aRet
, rAbsPos
);
644 if( aTmpRect
.HasArea() )
645 MakeVisible( aTmpRect
);
646 #if OSL_DEBUG_LEVEL > 0
647 //TODO: That doesn't seem to be intended
648 if( COL_TRANSPARENT
!= GetOut()->GetLineColor() )
650 OSL_FAIL( "Hey, Joe: Where's my Null Pen?" );
651 GetOut()->SetLineColor( COL_TRANSPARENT
);
660 const SwFrameFormat
*SwFEShell::NewFlyFrame( const SfxItemSet
& rSet
, bool bAnchValid
,
661 SwFrameFormat
*pParent
)
663 CurrShell
aCurr( this );
666 SwPaM
* pCursor
= GetCursor();
667 const Point
aPt( GetCursorDocPos() );
670 bool bMoveContent
= true;
673 GetTableSel( *this, aBoxes
);
674 if( !aBoxes
.empty() )
676 // Cursor should be removed from the removal area.
677 // Always put it after/on the table; via the
678 // document position they will be set to the old
680 ParkCursor( *aBoxes
[0]->GetSttNd() );
682 // #i127787# pCurrentCursor will be deleted in ParkCursor,
683 // we better get the current pCurrentCursor instead of working with the
685 pCursor
= GetCursor();
688 bMoveContent
= false;
690 else if( !pCursor
->HasMark() && !pCursor
->IsMultiSelection() )
691 bMoveContent
= false;
693 const SwPosition
& rPos
= *pCursor
->Start();
695 SwFormatAnchor
& rAnch
= const_cast<SwFormatAnchor
&>(rSet
.Get( RES_ANCHOR
));
696 RndStdIds eRndId
= rAnch
.GetAnchorId();
699 case RndStdIds::FLY_AT_PAGE
:
700 if( !rAnch
.GetPageNum() ) //HotFix: Bug in UpdateByExample
701 rAnch
.SetPageNum( 1 );
704 case RndStdIds::FLY_AT_FLY
:
705 case RndStdIds::FLY_AT_PARA
:
706 case RndStdIds::FLY_AT_CHAR
:
707 case RndStdIds::FLY_AS_CHAR
:
710 if( RndStdIds::FLY_AT_FLY
!= eRndId
)
712 rAnch
.SetAnchor( &rPos
);
714 else if( lcl_SetNewFlyPos( rPos
.GetNode(), rAnch
, aPt
) )
716 eRndId
= RndStdIds::FLY_AT_PAGE
;
722 OSL_ENSURE( false, "What is the purpose of this Fly?" );
726 SwFlyFrameFormat
*pRet
;
729 GetDoc()->GetIDocumentUndoRedo().StartUndo( SwUndoId::INSLAYFMT
, nullptr );
730 std::unique_ptr
<SwFormatAnchor
> pOldAnchor
;
731 bool bHOriChgd
= false, bVOriChgd
= false;
732 std::shared_ptr
<SwFormatVertOrient
> aOldV
;
733 std::shared_ptr
<SwFormatHoriOrient
> aOldH
;
735 if ( RndStdIds::FLY_AT_PAGE
!= eRndId
)
737 // First as with page link. Paragraph/character link on if
738 // everything was shifted. Then the position is valid!
739 // JP 13.05.98: if necessary also convert the horizontal/vertical
740 // orientation, to prevent correction during re-anchoring
741 pOldAnchor
.reset(new SwFormatAnchor( rAnch
));
742 const_cast<SfxItemSet
&>(rSet
).Put( SwFormatAnchor( RndStdIds::FLY_AT_PAGE
, 1 ) );
744 const SwFormatHoriOrient
* pHoriOrientItem
;
745 if( (pHoriOrientItem
= rSet
.GetItemIfSet( RES_HORI_ORIENT
, false ))
746 && text::HoriOrientation::NONE
== pHoriOrientItem
->GetHoriOrient() )
749 aOldH
.reset(pHoriOrientItem
->Clone());
750 const_cast<SfxItemSet
&>(rSet
).Put( SwFormatHoriOrient( 0, text::HoriOrientation::LEFT
) );
752 const SwFormatVertOrient
* pVertOrientItem
;
753 if( (pVertOrientItem
= rSet
.GetItemIfSet( RES_VERT_ORIENT
, false ))
754 && text::VertOrientation::NONE
== pVertOrientItem
->GetVertOrient() )
757 aOldV
.reset(pVertOrientItem
->Clone());
758 const_cast<SfxItemSet
&>(rSet
).Put( SwFormatVertOrient( 0, text::VertOrientation::TOP
) );
762 pRet
= GetDoc()->MakeFlyAndMove( *pCursor
, rSet
, &aBoxes
, pParent
);
770 // calculate new position
771 // JP 24.03.97: also go via page links
772 // anchor should not lie in the shifted area
775 const SwFrame
* pAnch
= ::FindAnchor( GetLayout(), aPt
);
776 SwPosition
aPos( pAnch
->IsTextFrame()
777 ? *static_cast<SwTextFrame
const*>(pAnch
)->GetTextNodeForParaProps()
778 : *static_cast<const SwNoTextFrame
*>(pAnch
)->GetNode() );
780 if ( RndStdIds::FLY_AS_CHAR
== eRndId
)
782 assert(pAnch
->IsTextFrame());
783 aPos
= static_cast<SwTextFrame
const*>(pAnch
)->MapViewToModelPos(TextFrameIndex(0));
785 pOldAnchor
->SetAnchor( &aPos
);
787 // shifting of table selection is not Undo-capable. therefore
788 // changing the anchors should not be recorded
789 bool const bDoesUndo
=
790 GetDoc()->GetIDocumentUndoRedo().DoesUndo();
791 SwUndoId
nLastUndoId(SwUndoId::EMPTY
);
793 GetDoc()->GetIDocumentUndoRedo().GetLastUndoInfo(nullptr,
796 if (SwUndoId::INSLAYFMT
== nLastUndoId
)
798 GetDoc()->GetIDocumentUndoRedo().DoUndo(false);
802 const_cast<SfxItemSet
&>(rSet
).Put( std::move(pOldAnchor
) );
805 const_cast<SfxItemSet
&>(rSet
).Put( *aOldH
);
807 const_cast<SfxItemSet
&>(rSet
).Put( *aOldV
);
809 GetDoc()->SetFlyFrameAttr( *pRet
, const_cast<SfxItemSet
&>(rSet
) );
810 GetDoc()->GetIDocumentUndoRedo().DoUndo(bDoesUndo
);
813 GetDoc()->GetIDocumentUndoRedo().EndUndo( SwUndoId::INSLAYFMT
, nullptr );
816 /* If called from a shell try to propagate an
817 existing adjust item from rPos to the content node of the
819 pRet
= GetDoc()->MakeFlySection( eRndId
, &rPos
, &rSet
, pParent
, true );
823 SwFlyFrame
* pFrame
= pRet
->GetFrame( &aPt
);
825 SelectFlyFrame( *pFrame
);
828 GetLayout()->SetAssertFlyPages();
832 EndAllActionAndCall();
837 void SwFEShell::Insert( const OUString
& rGrfName
, const OUString
& rFltName
,
838 const Graphic
* pGraphic
,
839 const SfxItemSet
* pFlyAttrSet
)
841 SwFlyFrameFormat
* pFormat
= nullptr;
842 CurrShell
aCurr( this );
844 SwShellCursor
*pStartCursor
= dynamic_cast<SwShellCursor
*>(GetCursor());
845 SwShellCursor
*pCursor
= pStartCursor
;
851 // Has the anchor not been set or been set incompletely?
854 if( const SwFormatAnchor
* pItem
= pFlyAttrSet
->GetItemIfSet( RES_ANCHOR
, false ) )
856 SwFormatAnchor
* pAnchor
= const_cast<SwFormatAnchor
*>(pItem
);
857 switch( pAnchor
->GetAnchorId())
859 case RndStdIds::FLY_AT_PARA
:
860 case RndStdIds::FLY_AT_CHAR
: // LAYER_IMPL
861 case RndStdIds::FLY_AS_CHAR
:
862 if( !pAnchor
->GetAnchorNode() )
864 pAnchor
->SetAnchor( pCursor
->GetPoint() );
867 case RndStdIds::FLY_AT_FLY
:
868 if( !pAnchor
->GetAnchorNode() )
870 lcl_SetNewFlyPos( pCursor
->GetPointNode(),
871 *pAnchor
, GetCursorDocPos() );
874 case RndStdIds::FLY_AT_PAGE
:
875 if( !pAnchor
->GetPageNum() )
877 pAnchor
->SetPageNum( pCursor
->GetPageNum(
878 true, &pCursor
->GetPtPos() ) );
886 pFormat
= GetDoc()->getIDocumentContentOperations().InsertGraphic(
891 OSL_ENSURE(pFormat
, "IDocumentContentOperations::InsertGraphic failed.");
893 pCursor
= pCursor
->GetNext();
894 } while( pCursor
!= pStartCursor
);
901 const Point
aPt( GetCursorDocPos() );
902 SwFlyFrame
* pFrame
= pFormat
->GetFrame( &aPt
);
906 // add a redline to the anchor point at tracked insertion of picture
909 const SwPosition
& rPos(*pFormat
->GetAnchor().GetContentAnchor());
910 SwPaM
aPaM(rPos
.GetNode(), rPos
.GetContentIndex(),
911 rPos
.GetNode(), rPos
.GetContentIndex() + 1);
912 GetDoc()->getIDocumentRedlineAccess().AppendRedline(
913 new SwRangeRedline( RedlineType::Insert
, aPaM
), true);
916 // fdo#36681: Invalidate the content and layout to refresh
917 // the picture anchoring properly
918 SwPageFrame
* pPageFrame
= pFrame
->FindPageFrameOfAnchor();
919 pPageFrame
->InvalidateFlyLayout();
920 pPageFrame
->InvalidateContent();
922 SelectFlyFrame( *pFrame
);
925 GetLayout()->SetAssertFlyPages();
928 SwFlyFrameFormat
* SwFEShell::InsertObject( const svt::EmbeddedObjectRef
& xObj
,
929 SfxItemSet
* pFlyAttrSet
)
931 SwFlyFrameFormat
* pFormat
= nullptr;
932 CurrShell
aCurr( this );
935 for(const SwPaM
& rPaM
: GetCursor()->GetRingContainer())
937 pFormat
= GetDoc()->getIDocumentContentOperations().InsertEmbObject(
938 rPaM
, xObj
, pFlyAttrSet
);
939 OSL_ENSURE(pFormat
, "IDocumentContentOperations::InsertEmbObject failed.");
946 const Point
aPt( GetCursorDocPos() );
947 SwFlyFrame
* pFrame
= pFormat
->GetFrame( &aPt
);
950 SelectFlyFrame( *pFrame
);
952 GetLayout()->SetAssertFlyPages();
958 void SwFEShell::InsertDrawObj( SdrObject
& rDrawObj
,
959 const Point
& rInsertPosition
)
961 CurrShell
aCurr( this );
963 SfxItemSet
rFlyAttrSet( GetDoc()->GetAttrPool(), aFrameFormatSetRange
);
964 rFlyAttrSet
.Put( SwFormatAnchor( RndStdIds::FLY_AT_PARA
));
966 rFlyAttrSet
.Put( SwFormatSurround( css::text::WrapTextMode_THROUGH
) );
967 rDrawObj
.SetLayer( getIDocumentDrawModelAccess().GetHeavenId() );
969 // find anchor position
970 SwPaM
aPam( mxDoc
->GetNodes() );
972 SwCursorMoveState
aState( CursorMoveState::SetOnlyText
);
973 Point
aTmpPt( rInsertPosition
);
974 GetLayout()->GetModelPositionForViewPoint( aPam
.GetPoint(), aTmpPt
, &aState
);
975 const SwFrame
* pFrame
= aPam
.GetPointContentNode()->getLayoutFrame(GetLayout(), nullptr, nullptr);
976 const Point
aRelPos( rInsertPosition
.X() - pFrame
->getFrameArea().Left(),
977 rInsertPosition
.Y() - pFrame
->getFrameArea().Top() );
978 rDrawObj
.SetRelativePos( aRelPos
);
979 ::lcl_FindAnchorPos( *GetDoc(), rInsertPosition
, *pFrame
, rFlyAttrSet
);
981 // insert drawing object into the document creating a new <SwDrawFrameFormat> instance
982 SwDrawFrameFormat
* pFormat
= GetDoc()->getIDocumentContentOperations().InsertDrawObj( aPam
, rDrawObj
, rFlyAttrSet
);
984 // move object to visible layer
985 SwContact
* pContact
= static_cast<SwContact
*>(rDrawObj
.GetUserCall());
988 pContact
->MoveObjToVisibleLayer( &rDrawObj
);
993 pFormat
->SetFormatName(rDrawObj
.GetName());
994 // select drawing object
995 Imp()->GetDrawView()->MarkObj( &rDrawObj
, Imp()->GetPageView() );
999 GetLayout()->SetAssertFlyPages();
1003 void SwFEShell::GetPageObjs( std::vector
<SwFrameFormat
*>& rFillArr
)
1007 for(sw::SpzFrameFormat
* pFormat
: *mxDoc
->GetSpzFrameFormats() )
1009 if (RndStdIds::FLY_AT_PAGE
== pFormat
->GetAnchor().GetAnchorId())
1011 rFillArr
.push_back( pFormat
);
1016 void SwFEShell::SetPageObjsNewPage( std::vector
<SwFrameFormat
*>& rFillArr
)
1018 if( rFillArr
.empty() )
1024 SwRootFrame
* pTmpRootFrame
= GetLayout();
1025 sal_uInt16 nMaxPage
= pTmpRootFrame
->GetPageNum();
1026 bool bTmpAssert
= false;
1027 for( auto pFormat
: rFillArr
)
1029 if (mxDoc
->GetSpzFrameFormats()->IsAlive(static_cast<sw::SpzFrameFormat
*>(pFormat
)))
1031 // FlyFormat is still valid, therefore process
1033 SwFormatAnchor
aNewAnchor( pFormat
->GetAnchor() );
1034 if (RndStdIds::FLY_AT_PAGE
!= aNewAnchor
.GetAnchorId())
1035 // Anchor has been changed, therefore: do not change!
1037 sal_uInt16 nNewPage
= aNewAnchor
.GetPageNum() + 1;
1038 if (nNewPage
> nMaxPage
)
1040 if ( RES_DRAWFRMFMT
== pFormat
->Which() )
1041 pFormat
->CallSwClientNotify(sw::DrawFrameFormatHint(sw::DrawFrameFormatHintId::PAGE_OUT_OF_BOUNDS
));
1043 pFormat
->DelFrames();
1046 aNewAnchor
.SetPageNum(nNewPage
);
1047 mxDoc
->SetAttr( aNewAnchor
, *pFormat
);
1052 pTmpRootFrame
->SetAssertFlyPages();
1058 // All attributes in the "baskets" will be filled with the attributes of the
1059 // current FlyFrames. Attributes which cannot be filled due to being at the
1060 // wrong place or which are ambiguous (multiple selections) will be removed.
1061 bool SwFEShell::GetFlyFrameAttr( SfxItemSet
&rSet
) const
1063 SwFlyFrame
*pFly
= GetSelectedOrCurrFlyFrame();
1066 OSL_ENSURE( false, "GetFlyFrameAttr, no Fly selected." );
1070 CurrShell
aCurr( const_cast<SwFEShell
*>(this) );
1072 if( !rSet
.Set( pFly
->GetFormat()->GetAttrSet() ) )
1075 // now examine all attributes. Remove forbidden attributes, then
1076 // get all remaining attributes and enter them
1078 if( const SwFormatAnchor
* pAnchor
= rSet
.GetItemIfSet( RES_ANCHOR
, false ) )
1080 RndStdIds eType
= pAnchor
->GetAnchorId();
1082 if ( RndStdIds::FLY_AT_PAGE
!= eType
)
1084 // OD 12.11.2003 #i22341# - content anchor of anchor item is needed.
1085 // Thus, don't overwrite anchor item by default constructed anchor item.
1086 if ( RndStdIds::FLY_AS_CHAR
== eType
)
1088 rSet
.ClearItem( RES_OPAQUE
);
1089 rSet
.ClearItem( RES_SURROUND
);
1093 rSet
.SetParent( pFly
->GetFormat()->GetAttrSet().GetParent() );
1094 // attributes must be removed
1095 rSet
.ClearItem( RES_FILL_ORDER
);
1096 rSet
.ClearItem( RES_CNTNT
);
1097 //MA: remove first (Template by example etc.)
1098 rSet
.ClearItem( RES_CHAIN
);
1102 // Attributes of the current fly will change.
1103 bool SwFEShell::SetFlyFrameAttr( SfxItemSet
& rSet
)
1105 CurrShell
aCurr( this );
1110 SwFlyFrame
*pFly
= GetSelectedOrCurrFlyFrame();
1111 OSL_ENSURE(pFly
, "SetFlyFrameAttr, no Fly selected.");
1115 const Point
aPt( pFly
->getFrameArea().Pos() );
1117 if( SfxItemState::SET
== rSet
.GetItemState( RES_ANCHOR
, false ))
1118 sw_ChkAndSetNewAnchor( *pFly
, rSet
);
1119 SwFlyFrameFormat
* pFlyFormat
= pFly
->GetFormat();
1121 if( GetDoc()->SetFlyFrameAttr( *pFlyFormat
, rSet
))
1124 SwFlyFrame
* pFrame
= pFlyFormat
->GetFrame( &aPt
);
1126 SelectFlyFrame( *pFrame
);
1128 GetLayout()->SetAssertFlyPages();
1131 EndAllActionAndCall();
1137 SfxItemSetFixed
<RES_VERT_ORIENT
, RES_ANCHOR
> SwFEShell::makeItemSetFromFormatAnchor(SfxItemPool
& rPool
, const SwFormatAnchor
&rAnchor
)
1139 // The set also includes VERT/HORI_ORIENT, because the align
1140 // shall be changed in FEShell::SetFlyFrameAttr/SetFlyFrameAnchor,
1141 // possibly as a result of the anchor change.
1142 SfxItemSetFixed
<RES_VERT_ORIENT
, RES_ANCHOR
> aSet(rPool
);
1147 bool SwFEShell::SetDrawingAttr( SfxItemSet
& rSet
)
1150 CurrShell
aCurr( this );
1151 if ( !rSet
.Count() ||
1152 !Imp()->HasDrawView() )
1155 const SdrMarkList
&rMrkList
= Imp()->GetDrawView()->GetMarkedObjectList();
1156 if ( rMrkList
.GetMarkCount() != 1 )
1160 SdrObject
*pObj
= rMrkList
.GetMark( 0 )->GetMarkedSdrObj();
1161 SwFrameFormat
*pFormat
= FindFrameFormat( pObj
);
1163 if( SfxItemState::SET
== rSet
.GetItemState( RES_ANCHOR
, false ))
1165 RndStdIds nNew
= rSet
.Get( RES_ANCHOR
).GetAnchorId();
1166 if ( nNew
!= pFormat
->GetAnchor().GetAnchorId() )
1169 // #i26791# - clear anchor attribute in item set,
1170 // because method <ChgAnchor(..)> takes care of it.
1171 rSet
.ClearItem( RES_ANCHOR
);
1175 if( GetDoc()->SetFlyFrameAttr( *pFormat
, rSet
))
1178 SelectObj( Point(), 0, pObj
);
1180 EndAllActionAndCall();
1185 // Reset attributes contained in the set.
1186 void SwFEShell::ResetFlyFrameAttr( const SfxItemSet
* pSet
)
1188 CurrShell
aCurr( this );
1190 SwFlyFrame
*pFly
= GetSelectedOrCurrFlyFrame();
1191 OSL_ENSURE( pFly
, "SetFlyFrameAttr, no Fly selected." );
1197 SfxItemIter
aIter( *pSet
);
1198 for (const SfxPoolItem
* pItem
= aIter
.GetCurItem(); pItem
; pItem
= aIter
.NextItem())
1200 if( !IsInvalidItem( pItem
) )
1202 sal_uInt16 nWhich
= pItem
->Which();
1203 if( RES_ANCHOR
!= nWhich
&& RES_CHAIN
!= nWhich
&& RES_CNTNT
!= nWhich
)
1204 pFly
->GetFormat()->ResetFormatAttr( nWhich
);
1208 EndAllActionAndCall();
1209 GetDoc()->getIDocumentState().SetModified();
1212 // Returns frame-format if frame, otherwise 0
1213 SwFrameFormat
* SwFEShell::GetSelectedFrameFormat() const
1215 SwFrameFormat
* pRet
= nullptr;
1216 SwLayoutFrame
*pFly
= GetSelectedFlyFrame();
1217 if( pFly
&& ( pRet
= static_cast<SwFrameFormat
*>(pFly
->GetFormat()->DerivedFrom()) ) ==
1218 GetDoc()->GetDfltFrameFormat() )
1223 void SwFEShell::SetFrameFormat( SwFrameFormat
*pNewFormat
, bool bKeepOrient
, Point
const * pDocPos
)
1225 SwFlyFrame
*pFly
= nullptr;
1228 const SwFrameFormat
* pFormat
= GetFormatFromObj( *pDocPos
);
1230 if (const SwFlyFrameFormat
* pFlyFormat
= dynamic_cast<const SwFlyFrameFormat
*>(pFormat
))
1231 pFly
= pFlyFormat
->GetFrame();
1234 pFly
= GetSelectedFlyFrame();
1235 OSL_ENSURE( pFly
, "SetFrameFormat: no frame" );
1240 CurrShell
aCurr( this );
1242 SwFlyFrameFormat
* pFlyFormat
= pFly
->GetFormat();
1243 const Point
aPt( pFly
->getFrameArea().Pos() );
1245 std::optional
<SfxItemSet
> oSet
;
1246 const SfxPoolItem
* pItem
;
1247 if( SfxItemState::SET
== pNewFormat
->GetItemState( RES_ANCHOR
, false, &pItem
))
1249 oSet
.emplace( GetDoc()->GetAttrPool(), aFrameFormatSetRange
);
1250 oSet
->Put( *pItem
);
1251 if( !sw_ChkAndSetNewAnchor( *pFly
, *oSet
))
1257 if( GetDoc()->SetFrameFormatToFly( *pFlyFormat
, *pNewFormat
, oSet
? &*oSet
: nullptr, bKeepOrient
))
1259 SwFlyFrame
* pFrame
= pFlyFormat
->GetFrame( &aPt
);
1261 SelectFlyFrame( *pFrame
);
1263 GetLayout()->SetAssertFlyPages();
1267 EndAllActionAndCall();
1270 const SwFrameFormat
* SwFEShell::GetFlyFrameFormat() const
1272 const SwFlyFrame
* pFly
= GetSelectedOrCurrFlyFrame();
1274 return pFly
->GetFormat();
1278 SwFrameFormat
* SwFEShell::GetFlyFrameFormat()
1280 SwFlyFrame
* pFly
= GetSelectedOrCurrFlyFrame();
1282 return pFly
->GetFormat();
1286 SwRect
SwFEShell::GetFlyRect() const
1288 SwFlyFrame
*pFly
= GetCurrFlyFrame(false);
1295 return pFly
->getFrameArea();
1298 SwRect
SwFEShell::GetObjRect() const
1300 if( Imp()->HasDrawView() )
1301 return SwRect(Imp()->GetDrawView()->GetAllMarkedRect());
1309 void SwFEShell::SetObjRect( const SwRect
& rRect
)
1311 if ( Imp()->HasDrawView() )
1313 Imp()->GetDrawView()->SetAllMarkedRect( rRect
.SVRect() );
1314 CallChgLnk(); // call AttrChangeNotify on the UI-side.
1318 Size
SwFEShell::RequestObjectResize( const SwRect
&rRect
, const uno::Reference
< embed::XEmbeddedObject
>& xObj
)
1322 SwFlyFrame
*pFly
= FindFlyFrame( xObj
);
1325 aResult
= rRect
.SSize();
1329 aResult
= pFly
->getFramePrintArea().SSize();
1331 bool bPosProt
= pFly
->GetFormat()->GetProtect().IsPosProtected();
1332 bool bSizeProt
= pFly
->GetFormat()->GetProtect().IsSizeProtected();
1336 // MA we do not allow to clip the Fly, as the OLE server can
1337 // request various wishes. Clipping is done via the formatting.
1338 // Correct display is done by scaling.
1339 // Scaling is done by SwNoTextFrame::Format by calling
1340 // SwWrtShell::CalcAndSetScale()
1341 if ( rRect
.SSize() != pFly
->getFramePrintArea().SSize() && !bSizeProt
)
1343 Size
aSz( rRect
.SSize() );
1345 //JP 28.02.2001: Task 74707 - ask for fly in fly with automatic size
1347 const SwFrame
* pAnchor
;
1348 const SwFormatFrameSize
& rFrameSz
= pFly
->GetFormat()->GetFrameSize();
1349 if (m_bCheckForOLEInCaption
&&
1350 0 != rFrameSz
.GetWidthPercent() &&
1351 nullptr != (pAnchor
= pFly
->GetAnchorFrame()) &&
1352 pAnchor
->IsTextFrame() &&
1353 !pAnchor
->GetNext() && !pAnchor
->GetPrev() &&
1354 pAnchor
->GetUpper()->IsFlyFrame())
1356 // search for a sequence field:
1357 sw::MergedAttrIter
iter(*static_cast<SwTextFrame
const*>(pAnchor
));
1358 for (SwTextAttr
const* pHint
= iter
.NextAttr(); pHint
; pHint
= iter
.NextAttr())
1360 const SfxPoolItem
* pItem
= &pHint
->GetAttr();
1361 if( RES_TXTATR_FIELD
== pItem
->Which()
1362 && SwFieldTypesEnum::Sequence
== static_cast<const SwFormatField
*>(pItem
)->GetField()->GetTypeId() )
1364 // sequence field found
1365 SwFlyFrame
* pChgFly
= const_cast<SwFlyFrame
*>(static_cast<const SwFlyFrame
*>(pAnchor
->GetUpper()));
1366 // calculate the changed size:
1367 // width must change, height can change
1368 Size
aNewSz( aSz
.Width() + pChgFly
->getFrameArea().Width() -
1369 pFly
->getFramePrintArea().Width(), aSz
.Height() );
1371 SwFrameFormat
*pFormat
= pChgFly
->GetFormat();
1372 SwFormatFrameSize
aFrameSz( pFormat
->GetFrameSize() );
1373 aFrameSz
.SetWidth( aNewSz
.Width() );
1374 if( SwFrameSize::Minimum
!= aFrameSz
.GetHeightSizeType() )
1376 aNewSz
.AdjustHeight(pChgFly
->getFrameArea().Height() -
1377 pFly
->getFramePrintArea().Height() );
1378 if( std::abs( aNewSz
.Height() - pChgFly
->getFrameArea().Height()) > 1 )
1379 aFrameSz
.SetHeight( aNewSz
.Height() );
1381 // via Doc for the Undo!
1382 pFormat
->GetDoc()->SetAttr( aFrameSz
, *pFormat
);
1388 // set the new Size at the fly themself
1389 if ( !pFly
->getFramePrintArea().IsEmpty() )
1391 aSz
.AdjustWidth(pFly
->getFrameArea().Width() - pFly
->getFramePrintArea().Width() );
1392 aSz
.AdjustHeight(pFly
->getFrameArea().Height()- pFly
->getFramePrintArea().Height() );
1394 aResult
= pFly
->ChgSize( aSz
);
1396 // if the object changes, the contour is outside the object
1397 assert(pFly
->Lower()->IsNoTextFrame());
1398 SwNoTextNode
*pNd
= static_cast<SwNoTextFrame
*>(pFly
->Lower())->GetNode()->GetNoTextNode();
1400 pNd
->SetContour( nullptr );
1404 // if only the size is to be adjusted, a position is transported with
1406 Point
aPt( pFly
->getFramePrintArea().Pos() );
1407 aPt
+= pFly
->getFrameArea().Pos();
1408 if ( rRect
.Top() != LONG_MIN
&& rRect
.Pos() != aPt
&& !bPosProt
)
1411 aPt
.setX(aPt
.getX() - pFly
->getFramePrintArea().Left());
1412 aPt
.setY(aPt
.getY() - pFly
->getFramePrintArea().Top());
1414 // in case of paragraph-bound Flys, starting from the new position,
1415 // a new anchor is to be set. The anchor and the new RelPos are
1416 // calculated by the Fly and set
1417 if( pFly
->IsFlyAtContentFrame() )
1418 static_cast<SwFlyAtContentFrame
*>(pFly
)->SetAbsPos( aPt
);
1421 const SwFrameFormat
*pFormat
= pFly
->GetFormat();
1422 const SwFormatVertOrient
&rVert
= pFormat
->GetVertOrient();
1423 const SwFormatHoriOrient
&rHori
= pFormat
->GetHoriOrient();
1424 const tools::Long lXDiff
= aPt
.getX() - pFly
->getFrameArea().Left();
1425 const tools::Long lYDiff
= aPt
.getY() - pFly
->getFrameArea().Top();
1426 const Point
aTmp( rHori
.GetPos() + lXDiff
,
1427 rVert
.GetPos() + lYDiff
);
1428 pFly
->ChgRelPos( aTmp
);
1432 SwFlyFrameFormat
*pFlyFrameFormat
= pFly
->GetFormat();
1433 OSL_ENSURE( pFlyFrameFormat
, "fly frame format missing!" );
1434 if ( pFlyFrameFormat
)
1435 pFlyFrameFormat
->SetLastFlyFramePrtRectPos( pFly
->getFramePrintArea().Pos() ); //stores the value of last Prt rect
1442 SwFrameFormat
* SwFEShell::WizardGetFly()
1444 // do not search the Fly via the layout. Now we can delete a frame
1445 // without a valid layout. ( e.g. for the wizards )
1446 sw::SpzFrameFormats
& rSpzArr
= *mxDoc
->GetSpzFrameFormats();
1447 if( !rSpzArr
.empty() )
1449 SwNode
& rCursorNd
= GetCursor()->GetPoint()->GetNode();
1450 if( rCursorNd
> mxDoc
->GetNodes().GetEndOfExtras() )
1451 // Cursor is in the body area!
1454 for( auto pFormat
: rSpzArr
)
1456 const SwNodeIndex
* pIdx
= pFormat
->GetContent( false ).GetContentIdx();
1457 SwStartNode
* pSttNd
;
1459 nullptr != ( pSttNd
= pIdx
->GetNode().GetStartNode() ) &&
1460 *pSttNd
< rCursorNd
&&
1461 rCursorNd
< *pSttNd
->EndOfSectionNode() )
1463 // found: return immediately
1471 void SwFEShell::SetFlyName( const OUString
& rName
)
1473 SwLayoutFrame
*pFly
= GetSelectedFlyFrame();
1475 GetDoc()->SetFlyName( *static_cast<SwFlyFrameFormat
*>(pFly
->GetFormat()), rName
);
1477 OSL_ENSURE( false, "no FlyFrame selected" );
1481 OUString
SwFEShell::GetFlyName() const
1483 SwLayoutFrame
*pFly
= GetSelectedFlyFrame();
1485 return pFly
->GetFormat()->GetName();
1487 OSL_ENSURE( false, "no FlyFrame selected" );
1491 uno::Reference
< embed::XEmbeddedObject
> SwFEShell::GetOleRef() const
1493 uno::Reference
< embed::XEmbeddedObject
> xObj
;
1494 SwFlyFrame
* pFly
= GetSelectedFlyFrame();
1495 if (pFly
&& pFly
->Lower() && pFly
->Lower()->IsNoTextFrame())
1497 SwOLENode
*pNd
= static_cast<SwNoTextFrame
*>(pFly
->Lower())->GetNode()->GetOLENode();
1499 xObj
= pNd
->GetOLEObj().GetOleRef();
1504 OUString
SwFEShell::GetUniqueGrfName() const
1506 return GetDoc()->GetUniqueGrfName();
1509 const SwFrameFormat
* SwFEShell::IsURLGrfAtPos( const Point
& rPt
, OUString
* pURL
,
1510 OUString
*pTargetFrameName
,
1511 OUString
*pDescription
) const
1513 if( !Imp()->HasDrawView() )
1517 const SwFrameFormat
* pRet
= nullptr;
1518 SwDrawView
*pDView
= const_cast<SwDrawView
*>(Imp()->GetDrawView());
1520 const auto nOld
= pDView
->GetHitTolerancePixel();
1521 pDView
->SetHitTolerancePixel( 2 );
1523 SdrObject
* pObj
= pDView
->PickObj(rPt
, pDView
->getHitTolLog(), pPV
, SdrSearchOptions::PICKMACRO
);
1524 SwVirtFlyDrawObj
* pFlyObj
= dynamic_cast<SwVirtFlyDrawObj
*>(pObj
);
1527 SwFlyFrame
*pFly
= pFlyObj
->GetFlyFrame();
1528 const SwFormatURL
&rURL
= pFly
->GetFormat()->GetURL();
1529 if( !rURL
.GetURL().isEmpty() || rURL
.GetMap() )
1531 bool bSetTargetFrameName
= pTargetFrameName
!= nullptr;
1532 bool bSetDescription
= pDescription
!= nullptr;
1533 if ( rURL
.GetMap() )
1535 IMapObject
*pObject
= pFly
->GetFormat()->GetIMapObject( rPt
, pFly
);
1536 if ( pObject
&& !pObject
->GetURL().isEmpty() )
1539 *pURL
= pObject
->GetURL();
1540 if ( bSetTargetFrameName
&& !pObject
->GetTarget().isEmpty() )
1542 bSetTargetFrameName
= false;
1543 *pTargetFrameName
= pObject
->GetTarget();
1545 if ( bSetDescription
)
1547 bSetDescription
= false;
1548 *pDescription
= pObject
->GetAltText();
1550 pRet
= pFly
->GetFormat();
1557 *pURL
= rURL
.GetURL();
1558 if( rURL
.IsServerMap() )
1560 // append the relative pixel position !!
1562 aPt
-= pFly
->getFrameArea().Pos();
1563 // without MapMode-Offset, without Offset, o ... !!!!!
1564 aPt
= GetOut()->LogicToPixel(
1565 aPt
, MapMode( MapUnit::MapTwip
) );
1566 *pURL
= *pURL
+ "?" + OUString::number( aPt
.getX() )
1567 + "," + OUString::number(aPt
.getY() );
1570 pRet
= pFly
->GetFormat();
1572 if ( bSetTargetFrameName
)
1573 *pTargetFrameName
= rURL
.GetTargetFrameName();
1574 if ( bSetDescription
)
1575 *pDescription
= pFly
->GetFormat()->GetName();
1578 pDView
->SetHitTolerancePixel( nOld
);
1582 const Graphic
*SwFEShell::GetGrfAtPos( const Point
&rPt
,
1583 OUString
&rName
, bool &rbLink
) const
1585 if( !Imp()->HasDrawView() )
1589 SwDrawView
*pDView
= const_cast<SwDrawView
*>(Imp()->GetDrawView());
1591 SdrObject
* pObj
= pDView
->PickObj(rPt
, pDView
->getHitTolLog(), pPV
);
1592 SwVirtFlyDrawObj
* pFlyObj
= dynamic_cast<SwVirtFlyDrawObj
*>(pObj
);
1595 SwFlyFrame
*pFly
= pFlyObj
->GetFlyFrame();
1596 if ( pFly
->Lower() && pFly
->Lower()->IsNoTextFrame() )
1598 SwGrfNode
*const pNd
= static_cast<SwNoTextFrame
*>(pFly
->Lower())->GetNode()->GetGrfNode();
1601 if ( pNd
->IsGrfLink() )
1603 // halfway ready graphic?
1604 ::sfx2::SvLinkSource
* pLnkObj
= pNd
->GetLink()->GetObj();
1605 if( pLnkObj
&& pLnkObj
->IsPending() )
1610 pNd
->GetFileFilterNms( &rName
, nullptr );
1611 if ( rName
.isEmpty() )
1612 rName
= pFly
->GetFormat()->GetName();
1613 return &pNd
->GetGrf(true);
1620 const SwFrameFormat
* SwFEShell::GetFormatFromObj( const Point
& rPt
, SwRect
** pRectToFill
) const
1622 SwFrameFormat
* pRet
= nullptr;
1624 if( Imp()->HasDrawView() )
1626 SdrPageView
* pPView
;
1628 SwDrawView
*pDView
= const_cast<SwDrawView
*>(Imp()->GetDrawView());
1630 const auto nOld
= pDView
->GetHitTolerancePixel();
1631 // tolerance for Drawing-SS
1632 pDView
->SetHitTolerancePixel( pDView
->GetMarkHdlSizePixel()/2 );
1634 SdrObject
* pObj
= pDView
->PickObj(rPt
, pDView
->getHitTolLog(), pPView
, SdrSearchOptions::PICKMARKABLE
);
1638 if (SwVirtFlyDrawObj
* pFlyObj
= dynamic_cast<SwVirtFlyDrawObj
*>(pObj
))
1639 pRet
= pFlyObj
->GetFormat();
1640 else if ( pObj
->GetUserCall() ) //not for group objects
1641 pRet
= static_cast<SwDrawContact
*>(pObj
->GetUserCall())->GetFormat();
1642 if(pRet
&& pRectToFill
)
1643 **pRectToFill
= SwRect(pObj
->GetCurrentBoundRect());
1645 pDView
->SetHitTolerancePixel( nOld
);
1650 // returns a format too, if the point is over the text of any fly
1651 const SwFrameFormat
* SwFEShell::GetFormatFromAnyObj( const Point
& rPt
) const
1653 const SwFrameFormat
* pRet
= GetFormatFromObj( rPt
);
1654 if( !pRet
|| RES_FLYFRMFMT
== pRet
->Which() )
1656 SwPosition
aPos( *GetCursor()->GetPoint() );
1658 GetLayout()->GetModelPositionForViewPoint( &aPos
, aPt
);
1659 SwContentNode
*pNd
= aPos
.GetNode().GetContentNode();
1660 std::pair
<Point
, bool> const tmp(rPt
, false);
1661 SwFrame
* pFrame
= pNd
->getLayoutFrame(GetLayout(), nullptr, &tmp
)->FindFlyFrame();
1662 pRet
= pFrame
? static_cast<SwLayoutFrame
*>(pFrame
)->GetFormat() : nullptr;
1667 ObjCntType
SwFEShell::GetObjCntType( const SdrObject
& rObj
)
1669 ObjCntType eType
= OBJCNT_NONE
;
1671 // investigate 'master' drawing object, if method
1672 // is called for a 'virtual' drawing object.
1673 const SdrObject
* pInvestigatedObj
;
1674 if (const SwDrawVirtObj
* pDrawVirtObj
= dynamic_cast<const SwDrawVirtObj
*>( &rObj
))
1676 pInvestigatedObj
= &(pDrawVirtObj
->GetReferencedObj());
1680 pInvestigatedObj
= &rObj
;
1683 if( SdrInventor::FmForm
== pInvestigatedObj
->GetObjInventor() )
1685 eType
= OBJCNT_CONTROL
;
1686 uno::Reference
< awt::XControlModel
> xModel
=
1687 static_cast<const SdrUnoObj
&>(*pInvestigatedObj
).GetUnoControlModel();
1691 OUString
sName("ButtonType");
1692 uno::Reference
< beans::XPropertySet
> xSet(xModel
, uno::UNO_QUERY
);
1694 uno::Reference
< beans::XPropertySetInfo
> xInfo
= xSet
->getPropertySetInfo();
1695 if(xInfo
->hasPropertyByName( sName
))
1697 aVal
= xSet
->getPropertyValue( sName
);
1698 if( aVal
.hasValue() && form::FormButtonType_URL
== *o3tl::doAccess
<form::FormButtonType
>(aVal
) )
1699 eType
= OBJCNT_URLBUTTON
;
1703 else if (const SwVirtFlyDrawObj
*pFlyObj
= dynamic_cast<const SwVirtFlyDrawObj
*>(pInvestigatedObj
))
1705 const SwFlyFrame
*pFly
= pFlyObj
->GetFlyFrame();
1706 if ( pFly
->Lower() && pFly
->Lower()->IsNoTextFrame() )
1708 if (static_cast<const SwNoTextFrame
*>(pFly
->Lower())->GetNode()->GetGrfNode())
1716 else if ( dynamic_cast<const SdrObjGroup
*>( pInvestigatedObj
) != nullptr )
1718 SwDrawContact
* pDrawContact( dynamic_cast<SwDrawContact
*>(GetUserCall( pInvestigatedObj
) ) );
1719 if ( !pDrawContact
)
1721 OSL_FAIL( "<SwFEShell::GetObjCntType(..)> - missing draw contact object" );
1722 eType
= OBJCNT_NONE
;
1726 SwFrameFormat
* pFrameFormat( pDrawContact
->GetFormat() );
1727 if ( !pFrameFormat
)
1729 OSL_FAIL( "<SwFEShell::GetObjCntType(..)> - missing frame format" );
1730 eType
= OBJCNT_NONE
;
1732 else if ( RndStdIds::FLY_AS_CHAR
!= pFrameFormat
->GetAnchor().GetAnchorId() )
1734 eType
= OBJCNT_GROUPOBJ
;
1739 eType
= OBJCNT_SIMPLE
;
1743 ObjCntType
SwFEShell::GetObjCntType( const Point
&rPt
, SdrObject
*&rpObj
) const
1745 ObjCntType eType
= OBJCNT_NONE
;
1747 if( Imp()->HasDrawView() )
1749 SdrPageView
* pPView
;
1751 SwDrawView
*pDView
= const_cast<SwDrawView
*>(Imp()->GetDrawView());
1753 const auto nOld
= pDView
->GetHitTolerancePixel();
1754 // tolerance for Drawing-SS
1755 pDView
->SetHitTolerancePixel( pDView
->GetMarkHdlSizePixel()/2 );
1757 SdrObject
* pObj
= pDView
->PickObj(rPt
, pDView
->getHitTolLog(), pPView
, SdrSearchOptions::PICKMARKABLE
);
1761 eType
= GetObjCntType( *rpObj
);
1764 pDView
->SetHitTolerancePixel( nOld
);
1769 ObjCntType
SwFEShell::GetObjCntTypeOfSelection() const
1771 ObjCntType eType
= OBJCNT_NONE
;
1773 if( Imp()->HasDrawView() )
1775 const SdrMarkList
&rMrkList
= Imp()->GetDrawView()->GetMarkedObjectList();
1776 for( size_t i
= 0, nE
= rMrkList
.GetMarkCount(); i
< nE
; ++i
)
1778 SdrObject
* pObj
= rMrkList
.GetMark( i
)->GetMarkedSdrObj();
1781 ObjCntType eTmp
= GetObjCntType( *pObj
);
1786 else if( eTmp
!= eType
)
1788 eType
= OBJCNT_DONTCARE
;
1789 // once DontCare, always DontCare!
1797 void SwFEShell::ReplaceSdrObj( const OUString
& rGrfName
, const Graphic
* pGrf
)
1799 CurrShell
aCurr( this );
1801 const SdrMarkList
*pMrkList
;
1802 if( !(Imp()->HasDrawView() && 1 ==
1803 ( pMrkList
= &Imp()->GetDrawView()->GetMarkedObjectList())->GetMarkCount()) )
1806 SdrObject
* pObj
= pMrkList
->GetMark( 0 )->GetMarkedSdrObj();
1807 SwFrameFormat
*pFormat
= FindFrameFormat( pObj
);
1809 // store attributes, then set the graphic
1810 SfxItemSet
aFrameSet( mxDoc
->GetAttrPool(),
1811 pFormat
->GetAttrSet().GetRanges() );
1812 aFrameSet
.Set( pFormat
->GetAttrSet() );
1814 // set size and position?
1815 if( dynamic_cast<const SwVirtFlyDrawObj
*>( pObj
) == nullptr )
1817 // then let's do it:
1818 const tools::Rectangle
&rBound
= pObj
->GetSnapRect();
1819 Point
aRelPos( pObj
->GetRelativePos() );
1821 const tools::Long nWidth
= rBound
.Right() - rBound
.Left();
1822 const tools::Long nHeight
= rBound
.Bottom() - rBound
.Top();
1823 aFrameSet
.Put( SwFormatFrameSize( SwFrameSize::Minimum
,
1824 std::max( nWidth
, tools::Long(MINFLY
) ),
1825 std::max( nHeight
, tools::Long(MINFLY
) )));
1827 if( SfxItemState::SET
!= aFrameSet
.GetItemState( RES_HORI_ORIENT
))
1828 aFrameSet
.Put( SwFormatHoriOrient( aRelPos
.getX(), text::HoriOrientation::NONE
, text::RelOrientation::FRAME
));
1830 if( SfxItemState::SET
!= aFrameSet
.GetItemState( RES_VERT_ORIENT
))
1831 aFrameSet
.Put( SwFormatVertOrient( aRelPos
.getY(), text::VertOrientation::NONE
, text::RelOrientation::FRAME
));
1840 // delete "Sdr-Object", insert the graphic instead
1843 GetDoc()->getIDocumentContentOperations().InsertGraphic(
1844 *GetCursor(), rGrfName
, "", pGrf
, &aFrameSet
, nullptr, nullptr);
1850 static sal_uInt16
SwFormatGetPageNum(const SwFlyFrameFormat
* pFormat
)
1852 OSL_ENSURE(pFormat
!= nullptr, "invalid argument");
1854 SwFlyFrame
* pFrame
= pFormat
->GetFrame();
1858 if (pFrame
!= nullptr)
1859 aResult
= pFrame
->GetPhyPageNum();
1861 aResult
= pFormat
->GetAnchor().GetPageNum();
1866 void SwFEShell::GetConnectableFrameFormats(SwFrameFormat
& rFormat
,
1867 const OUString
& rReference
,
1869 std::vector
< OUString
> & aPrevPageVec
,
1870 std::vector
< OUString
> & aThisPageVec
,
1871 std::vector
< OUString
> & aNextPageVec
,
1872 std::vector
< OUString
> & aRestVec
)
1876 SwFormatChain rChain
= rFormat
.GetChain();
1877 SwFrameFormat
* pOldChainNext
= rChain
.GetNext();
1878 SwFrameFormat
* pOldChainPrev
= rChain
.GetPrev();
1881 mxDoc
->Unchain(rFormat
);
1884 mxDoc
->Unchain(*pOldChainPrev
);
1886 const size_t nCnt
= mxDoc
->GetFlyCount(FLYCNTTYPE_FRM
);
1888 /* potential successors resp. predecessors */
1889 std::vector
< const SwFrameFormat
* > aTmpSpzArray
;
1891 mxDoc
->FindFlyByName(rReference
);
1893 for (size_t n
= 0; n
< nCnt
; ++n
)
1895 const SwFrameFormat
& rFormat1
= *(mxDoc
->GetFlyNum(n
, FLYCNTTYPE_FRM
));
1898 pFormat is a potential successor of rFormat if it is chainable after
1901 pFormat is a potential predecessor of rFormat if rFormat is chainable
1905 SwChainRet nChainState
;
1908 nChainState
= mxDoc
->Chainable(rFormat
, rFormat1
);
1910 nChainState
= mxDoc
->Chainable(rFormat1
, rFormat
);
1912 if (nChainState
== SwChainRet::OK
)
1914 aTmpSpzArray
.push_back(&rFormat1
);
1920 if (!aTmpSpzArray
.empty())
1922 aPrevPageVec
.clear();
1923 aThisPageVec
.clear();
1924 aNextPageVec
.clear();
1927 /* number of page rFormat resides on */
1928 sal_uInt16 nPageNum
= SwFormatGetPageNum(static_cast<SwFlyFrameFormat
*>(&rFormat
));
1930 for (const auto& rpFormat
: aTmpSpzArray
)
1932 const OUString aString
= rpFormat
->GetName();
1934 /* rFormat is not a valid successor or predecessor of
1936 if (aString
!= rReference
&& aString
!= rFormat
.GetName())
1939 SwFormatGetPageNum(static_cast<const SwFlyFrameFormat
*>(rpFormat
));
1941 if (nNum1
== nPageNum
-1)
1942 aPrevPageVec
.push_back(aString
);
1943 else if (nNum1
== nPageNum
)
1944 aThisPageVec
.push_back(aString
);
1945 else if (nNum1
== nPageNum
+ 1)
1946 aNextPageVec
.push_back(aString
);
1948 aRestVec
.push_back(aString
);
1955 mxDoc
->Chain(rFormat
, *pOldChainNext
);
1958 mxDoc
->Chain(*pOldChainPrev
, rFormat
);
1964 OUString
SwFEShell::GetObjTitle() const
1966 if ( Imp()->HasDrawView() )
1968 const SdrMarkList
*pMrkList
= &Imp()->GetDrawView()->GetMarkedObjectList();
1969 if ( pMrkList
->GetMarkCount() == 1 )
1971 const SdrObject
* pObj
= pMrkList
->GetMark( 0 )->GetMarkedSdrObj();
1972 const SwFrameFormat
* pFormat
= FindFrameFormat( pObj
);
1973 if ( pFormat
->Which() == RES_FLYFRMFMT
)
1975 return static_cast<const SwFlyFrameFormat
*>(pFormat
)->GetObjTitle();
1977 return pObj
->GetTitle();
1984 void SwFEShell::SetObjTitle( const OUString
& rTitle
)
1986 if ( !Imp()->HasDrawView() )
1989 const SdrMarkList
*pMrkList
= &Imp()->GetDrawView()->GetMarkedObjectList();
1990 if ( pMrkList
->GetMarkCount() != 1 )
1993 SdrObject
* pObj
= pMrkList
->GetMark( 0 )->GetMarkedSdrObj();
1994 SwFrameFormat
* pFormat
= FindFrameFormat( pObj
);
1995 if ( pFormat
->Which() == RES_FLYFRMFMT
)
1997 GetDoc()->SetFlyFrameTitle( dynamic_cast<SwFlyFrameFormat
&>(*pFormat
),
2002 pObj
->SetTitle( rTitle
);
2006 OUString
SwFEShell::GetObjDescription() const
2008 if ( Imp()->HasDrawView() )
2010 const SdrMarkList
*pMrkList
= &Imp()->GetDrawView()->GetMarkedObjectList();
2011 if ( pMrkList
->GetMarkCount() == 1 )
2013 const SdrObject
* pObj
= pMrkList
->GetMark( 0 )->GetMarkedSdrObj();
2014 const SwFrameFormat
* pFormat
= FindFrameFormat( pObj
);
2015 if ( pFormat
->Which() == RES_FLYFRMFMT
)
2017 return dynamic_cast<const SwFlyFrameFormat
&>(*pFormat
).GetObjDescription();
2019 return pObj
->GetDescription();
2026 void SwFEShell::SetObjDescription( const OUString
& rDescription
)
2028 if ( !Imp()->HasDrawView() )
2031 const SdrMarkList
*pMrkList
= &Imp()->GetDrawView()->GetMarkedObjectList();
2032 if ( pMrkList
->GetMarkCount() != 1 )
2035 SdrObject
* pObj
= pMrkList
->GetMark( 0 )->GetMarkedSdrObj();
2036 SwFrameFormat
* pFormat
= FindFrameFormat( pObj
);
2037 if ( pFormat
->Which() == RES_FLYFRMFMT
)
2039 GetDoc()->SetFlyFrameDescription(dynamic_cast<SwFlyFrameFormat
&>(*pFormat
),
2044 pObj
->SetDescription( rDescription
);
2048 bool SwFEShell::IsObjDecorative() const
2050 if (!Imp()->HasDrawView())
2055 SdrMarkList
const& rMarkList(Imp()->GetDrawView()->GetMarkedObjectList());
2056 if (rMarkList
.GetMarkCount() != 1)
2061 SdrObject
const*const pObj(rMarkList
.GetMark(0)->GetMarkedSdrObj());
2062 SwFrameFormat
const*const pFormat(FindFrameFormat(pObj
));
2063 if (pFormat
->Which() == RES_FLYFRMFMT
)
2065 return dynamic_cast<const SwFlyFrameFormat
&>(*pFormat
).GetAttrSet().Get(RES_DECORATIVE
).GetValue();
2067 return pObj
->IsDecorative();
2070 void SwFEShell::SetObjDecorative(bool const isDecorative
)
2072 if (!Imp()->HasDrawView())
2077 SdrMarkList
const& rMarkList(Imp()->GetDrawView()->GetMarkedObjectList());
2078 if (rMarkList
.GetMarkCount() != 1)
2083 SdrObject
*const pObj(rMarkList
.GetMark(0)->GetMarkedSdrObj());
2084 SwFrameFormat
*const pFormat(FindFrameFormat(pObj
));
2085 if (pFormat
->Which() == RES_FLYFRMFMT
)
2087 GetDoc()->SetFlyFrameDecorative(dynamic_cast<SwFlyFrameFormat
&>(*pFormat
),
2092 pObj
->SetDecorative(isDecorative
);
2097 void SwFEShell::AlignFormulaToBaseline( const uno::Reference
< embed::XEmbeddedObject
>& xObj
)
2099 #if OSL_DEBUG_LEVEL > 0
2100 SvGlobalName
aCLSID( xObj
->getClassID() );
2101 const bool bStarMath
= ( SotExchange::IsMath( aCLSID
) != 0 );
2102 OSL_ENSURE( bStarMath
, "AlignFormulaToBaseline should only be called for Math objects" );
2108 SwFlyFrame
* pFly
= FindFlyFrame( xObj
);
2109 OSL_ENSURE( pFly
, "No fly frame!" );
2110 SwFrameFormat
* pFrameFormat
= pFly
? pFly
->GetFormat() : nullptr;
2112 // baseline to baseline alignment should only be applied to formulas anchored as char
2113 if ( !pFly
|| !pFrameFormat
|| RndStdIds::FLY_AS_CHAR
!= pFrameFormat
->GetAnchor().GetAnchorId() )
2116 // get baseline from Math object
2118 if( svt::EmbeddedObjectRef::TryRunningState( xObj
) )
2120 uno::Reference
< beans::XPropertySet
> xSet( xObj
->getComponent(), uno::UNO_QUERY
);
2125 aBaseline
= xSet
->getPropertyValue("BaseLine");
2127 catch ( uno::Exception
& )
2129 OSL_FAIL( "Baseline could not be retrieved from Starmath!" );
2134 sal_Int32 nBaseline
= ::comphelper::getINT32(aBaseline
);
2135 nBaseline
= o3tl::toTwips( nBaseline
, o3tl::Length::mm100
);
2137 OSL_ENSURE( nBaseline
> 0, "Wrong value of Baseline while retrieving from Starmath!" );
2138 //nBaseline must be moved by aPrt position
2139 const SwFlyFrameFormat
*pFlyFrameFormat
= pFly
->GetFormat();
2140 OSL_ENSURE( pFlyFrameFormat
, "fly frame format missing!" );
2141 if ( pFlyFrameFormat
)
2142 nBaseline
+= pFlyFrameFormat
->GetLastFlyFramePrtRectPos().Y();
2144 const SwFormatVertOrient
&rVert
= pFrameFormat
->GetVertOrient();
2145 SwFormatVertOrient
aVert( rVert
);
2146 aVert
.SetPos( -nBaseline
);
2147 aVert
.SetVertOrient( css::text::VertOrientation::NONE
);
2149 pFrameFormat
->LockModify();
2150 pFrameFormat
->SetFormatAttr( aVert
);
2151 pFrameFormat
->UnlockModify();
2152 pFly
->InvalidatePos();
2156 void SwFEShell::AlignAllFormulasToBaseline()
2161 SwNodeIndex
aIdx( *GetNodes().GetEndOfAutotext().StartOfSectionNode(), 1 );
2162 while ( nullptr != (pStNd
= aIdx
.GetNode().GetStartNode()) )
2165 SwOLENode
*pOleNode
= aIdx
.GetNode().GetOLENode();
2168 const uno::Reference
< embed::XEmbeddedObject
> & xObj( pOleNode
->GetOLEObj().GetOleRef() );
2171 SvGlobalName
aCLSID( xObj
->getClassID() );
2172 if ( SotExchange::IsMath( aCLSID
) )
2173 AlignFormulaToBaseline( xObj
);
2177 aIdx
.Assign( *pStNd
->EndOfSectionNode(), + 1 );
2183 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */