Bug Summary

File:home/maarten/src/libreoffice/core/sw/source/core/frmedt/fefly1.cxx
Warning:line 1796, column 42
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name fefly1.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /usr/include/libxml2 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D SW_DLLIMPLEMENTATION -D SWUI_DLL_NAME="libswuilo.so" -D SYSTEM_LIBXML -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/sw/source/core/inc -I /home/maarten/src/libreoffice/core/sw/source/filter/inc -I /home/maarten/src/libreoffice/core/sw/source/uibase/inc -I /home/maarten/src/libreoffice/core/sw/inc -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/sw/sdi -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/sw/generated -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/oovbaapi/normal -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/sw/source/core/frmedt/fefly1.cxx
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <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>
36#include <fmturl.hxx>
37#include <fmtfsize.hxx>
38#include <docary.hxx>
39#include <fesh.hxx>
40#include <rootfrm.hxx>
41#include <pagefrm.hxx>
42#include <cntfrm.hxx>
43#include <txtfrm.hxx>
44#include <viewimp.hxx>
45#include <viscrs.hxx>
46#include <doc.hxx>
47#include <IDocumentDrawModelAccess.hxx>
48#include <IDocumentUndoRedo.hxx>
49#include <IDocumentState.hxx>
50#include <IDocumentLayoutAccess.hxx>
51#include <dview.hxx>
52#include <dflyobj.hxx>
53#include <dcontact.hxx>
54#include <frmfmt.hxx>
55#include <flyfrm.hxx>
56#include <ndtxt.hxx>
57#include <swtable.hxx>
58#include <ndgrf.hxx>
59#include <flyfrms.hxx>
60#include <fldbas.hxx>
61#include <fmtfld.hxx>
62#include <swundo.hxx>
63#include <txatbase.hxx>
64#include <frame.hxx>
65#include <notxtfrm.hxx>
66#include <HandleAnchorNodeChg.hxx>
67#include <frmatr.hxx>
68#include <fmtsrnd.hxx>
69#include <ndole.hxx>
70#include <fefly.hxx>
71#include <fmtcnct.hxx>
72#include <frameformats.hxx>
73#include <textboxhelper.hxx>
74
75
76using namespace ::com::sun::star;
77
78// Based on the request, changes to the specific layouts will be made, to
79// fit to the format
80static bool lcl_SetNewFlyPos( const SwNode& rNode, SwFormatAnchor& rAnchor,
81 const Point& rPt )
82{
83 bool bRet = false;
84 const SwStartNode* pStNode = rNode.FindFlyStartNode();
85 if( pStNode )
86 {
87 SwPosition aPos( *pStNode );
88 rAnchor.SetAnchor( &aPos );
89 bRet = true;
90 }
91 else
92 {
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;
99
100 rAnchor.SetPageNum( pPg ? pPg->GetPhyPageNum() : 1 );
101 rAnchor.SetType( RndStdIds::FLY_AT_PAGE );
102 }
103 return bRet;
104}
105
106static bool lcl_FindAnchorPos(
107 SwDoc& rDoc,
108 const Point& rPt,
109 const SwFrame& rFrame,
110 SfxItemSet& rSet )
111{
112 bool bRet = true;
113 SwFormatAnchor aNewAnch( rSet.Get( RES_ANCHOR ) );
114 RndStdIds nNew = aNewAnch.GetAnchorId();
115 const SwFrame *pNewAnch;
116
117 //determine new anchor
118 Point aTmpPnt( rPt );
119 switch( nNew )
120 {
121 case RndStdIds::FLY_AS_CHAR: // also include this?
122 case RndStdIds::FLY_AT_PARA:
123 case RndStdIds::FLY_AT_CHAR: // LAYER_IMPL
124 {
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()
128 : &rFrame;
129 pNewAnch = ::FindAnchor( pFrame, aTmpPnt );
130 if( pNewAnch->IsProtected() )
131 {
132 bRet = false;
133 break;
134 }
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))
139 {
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 ) )
145 {
146 assert(pNewAnch->IsTextFrame())(static_cast <bool> (pNewAnch->IsTextFrame()) ? void
(0) : __assert_fail ("pNewAnch->IsTextFrame()", "/home/maarten/src/libreoffice/core/sw/source/core/frmedt/fefly1.cxx"
, 146, __extension__ __PRETTY_FUNCTION__))
; // because AT_CHAR/AS_CHAR
147 SwTextFrame const*const pTextFrame(
148 static_cast<SwTextFrame const*>(pNewAnch));
149 if( pNewAnch->getFrameArea().Bottom() < aTmpPnt.Y() )
150 {
151 aPos = pTextFrame->MapViewToModelPos(TextFrameIndex(0));
152 }
153 else
154 {
155 aPos = pTextFrame->MapViewToModelPos(
156 TextFrameIndex(pTextFrame->GetText().getLength()));
157 }
158 }
159 else
160 {
161 if ( SwCursorShell::PosInsideInputField( aPos ) )
162 {
163 aPos.nContent = SwCursorShell::StartOfInputFieldAtPos( aPos );
164 }
165 }
166 }
167 aNewAnch.SetAnchor( &aPos );
168 }
169 break;
170
171 case RndStdIds::FLY_AT_FLY: // LAYER_IMPL
172 {
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();
182
183 if( pNewAnch && &rFrame != pNewAnch && !pNewAnch->IsProtected() )
184 {
185 aPos.nNode = *static_cast<const SwFlyFrame*>(pNewAnch)->GetFormat()->GetContent().
186 GetContentIdx();
187 aNewAnch.SetAnchor( &aPos );
188 break;
189 }
190 }
191
192 nNew = RndStdIds::FLY_AT_PAGE;
193 aNewAnch.SetType( nNew );
194 [[fallthrough]];
195
196 case RndStdIds::FLY_AT_PAGE:
197 pNewAnch = rFrame.FindPageFrame();
198 aNewAnch.SetPageNum( pNewAnch->GetPhyPageNum() );
199 break;
200
201 default:
202 OSL_ENSURE( false, "Wrong Id for new anchor." )do { if (true && (!(false))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/frmedt/fefly1.cxx"
":" "202" ": "), "%s", "Wrong Id for new anchor."); } } while
(false)
;
203 }
204
205 rSet.Put( aNewAnch );
206 return bRet;
207}
208
209//! also used in unoframe.cxx
210
211bool sw_ChkAndSetNewAnchor(
212 const SwFlyFrame& rFly,
213 SfxItemSet& rSet )
214{
215 const SwFrameFormat& rFormat = *rFly.GetFormat();
216 const SwFormatAnchor &rOldAnch = rFormat.GetAnchor();
217 const RndStdIds nOld = rOldAnch.GetAnchorId();
218
219 RndStdIds nNew = rSet.Get( RES_ANCHOR ).GetAnchorId();
220
221 if( nOld == nNew )
222 return false;
223
224 SwDoc* pDoc = const_cast<SwDoc*>(rFormat.GetDoc());
225
226#if OSL_DEBUG_LEVEL1 > 0
227 OSL_ENSURE( !(nNew == RndStdIds::FLY_AT_PAGE &&do { if (true && (!(!(nNew == RndStdIds::FLY_AT_PAGE &&
(RndStdIds::FLY_AT_PARA==nOld || RndStdIds::FLY_AT_CHAR==nOld
|| RndStdIds::FLY_AS_CHAR==nOld ) && pDoc->IsInHeaderFooter
( rOldAnch.GetContentAnchor()->nNode ))))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/frmedt/fefly1.cxx"
":" "230" ": "), "%s", "forbidden anchor change in Head/Foot."
); } } while (false)
228 (RndStdIds::FLY_AT_PARA==nOld || RndStdIds::FLY_AT_CHAR==nOld || RndStdIds::FLY_AS_CHAR==nOld ) &&do { if (true && (!(!(nNew == RndStdIds::FLY_AT_PAGE &&
(RndStdIds::FLY_AT_PARA==nOld || RndStdIds::FLY_AT_CHAR==nOld
|| RndStdIds::FLY_AS_CHAR==nOld ) && pDoc->IsInHeaderFooter
( rOldAnch.GetContentAnchor()->nNode ))))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/frmedt/fefly1.cxx"
":" "230" ": "), "%s", "forbidden anchor change in Head/Foot."
); } } while (false)
229 pDoc->IsInHeaderFooter( rOldAnch.GetContentAnchor()->nNode )),do { if (true && (!(!(nNew == RndStdIds::FLY_AT_PAGE &&
(RndStdIds::FLY_AT_PARA==nOld || RndStdIds::FLY_AT_CHAR==nOld
|| RndStdIds::FLY_AS_CHAR==nOld ) && pDoc->IsInHeaderFooter
( rOldAnch.GetContentAnchor()->nNode ))))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/frmedt/fefly1.cxx"
":" "230" ": "), "%s", "forbidden anchor change in Head/Foot."
); } } while (false)
230 "forbidden anchor change in Head/Foot." )do { if (true && (!(!(nNew == RndStdIds::FLY_AT_PAGE &&
(RndStdIds::FLY_AT_PARA==nOld || RndStdIds::FLY_AT_CHAR==nOld
|| RndStdIds::FLY_AS_CHAR==nOld ) && pDoc->IsInHeaderFooter
( rOldAnch.GetContentAnchor()->nNode ))))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/frmedt/fefly1.cxx"
":" "230" ": "), "%s", "forbidden anchor change in Head/Foot."
); } } while (false)
;
231#endif
232
233 return ::lcl_FindAnchorPos( *pDoc, rFly.getFrameArea().Pos(), rFly, rSet );
234}
235
236void SwFEShell::SelectFlyFrame( SwFlyFrame& rFrame )
237{
238 CurrShell aCurr( this );
239
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();
248 if( !GetWin() )
249 return;
250
251 OSL_ENSURE( rFrame.IsFlyFrame(), "SelectFlyFrame wants a Fly" )do { if (true && (!(rFrame.IsFlyFrame()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/frmedt/fefly1.cxx"
":" "251" ": "), "%s", "SelectFlyFrame wants a Fly"); } } while
(false)
;
252
253 // nothing to be done if the Fly already was selected
254 if (GetSelectedFlyFrame() == &rFrame)
255 return;
256
257 // assure the anchor is drawn
258 if( rFrame.IsFlyInContentFrame() && rFrame.GetAnchorFrame() )
259 rFrame.GetAnchorFrame()->SetCompletePaint();
260
261 if( pImpl->GetDrawView()->AreObjectsMarked() )
262 pImpl->GetDrawView()->UnmarkAll();
263
264 pImpl->GetDrawView()->MarkObj( rFrame.GetVirtDrawObj(),
265 pImpl->GetPageView() );
266
267 rFrame.SelectionHasChanged(this);
268
269 KillPams();
270 ClearMark();
271 SelFlyGrabCursor();
272}
273
274// Get selected fly
275SwFlyFrame* SwFEShell::GetSelectedFlyFrame() const
276{
277 if ( Imp()->HasDrawView() )
278 {
279 // A Fly is only accessible if it is selected
280 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
281 if( rMrkList.GetMarkCount() != 1 )
282 return nullptr;
283
284 SdrObject *pO = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
285
286 SwVirtFlyDrawObj *pFlyObj = dynamic_cast<SwVirtFlyDrawObj*>(pO);
287
288 return pFlyObj ? pFlyObj->GetFlyFrame() : nullptr;
289 }
290 return nullptr;
291}
292
293// Get current fly in which the cursor is positioned
294SwFlyFrame* SwFEShell::GetCurrFlyFrame(const bool bCalcFrame) const
295{
296 SwContentFrame *pContent = GetCurrFrame(bCalcFrame);
297 return pContent ? pContent->FindFlyFrame() : nullptr;
298}
299
300// Get selected fly, but if none Get current fly in which the cursor is positioned
301SwFlyFrame* SwFEShell::GetSelectedOrCurrFlyFrame() const
302{
303 SwFlyFrame *pFly = GetSelectedFlyFrame();
304 if (pFly)
305 return pFly;
306 return GetCurrFlyFrame();
307}
308
309// Returns non-null pointer, if the current Fly could be anchored to another one (so it is inside)
310const SwFrameFormat* SwFEShell::IsFlyInFly()
311{
312 CurrShell aCurr( this );
313
314 if ( !Imp()->HasDrawView() )
315 return nullptr;
316
317 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
318 if ( !rMrkList.GetMarkCount() )
319 {
320 SwFlyFrame *pFly = GetCurrFlyFrame(false);
321 if (!pFly)
322 return nullptr;
323 return pFly->GetFormat();
324 }
325 else if ( rMrkList.GetMarkCount() != 1 ||
326 !GetUserCall(rMrkList.GetMark( 0 )->GetMarkedSdrObj()) )
327 return nullptr;
328
329 SdrObject *pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
330
331 SwFrameFormat *pFormat = FindFrameFormat( pObj );
332 if( pFormat && RndStdIds::FLY_AT_FLY == pFormat->GetAnchor().GetAnchorId() )
333 {
334 const SwFrame* pFly;
335 if (SwVirtFlyDrawObj* pFlyObj = dynamic_cast<SwVirtFlyDrawObj *>(pObj))
336 {
337 pFly = pFlyObj->GetFlyFrame()->GetAnchorFrame();
338 }
339 else
340 {
341 pFly = static_cast<SwDrawContact*>(GetUserCall(pObj))->GetAnchorFrame(pObj);
342 }
343
344 OSL_ENSURE( pFly, "IsFlyInFly: Where's my anchor?" )do { if (true && (!(pFly))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/frmedt/fefly1.cxx"
":" "344" ": "), "%s", "IsFlyInFly: Where's my anchor?"); } }
while (false)
;
345 OSL_ENSURE( pFly->IsFlyFrame(), "IsFlyInFly: Funny anchor!" )do { if (true && (!(pFly->IsFlyFrame()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/frmedt/fefly1.cxx"
":" "345" ": "), "%s", "IsFlyInFly: Funny anchor!"); } } while
(false)
;
346 return static_cast<const SwFlyFrame*>(pFly)->GetFormat();
347 }
348
349 Point aTmpPos = pObj->GetCurrentBoundRect().TopLeft();
350
351 SwFrame *pTextFrame;
352 {
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;
363 }
364 const SwFrame *pTmp = pTextFrame ? ::FindAnchor(pTextFrame, aTmpPos) : nullptr;
365 const SwFlyFrame *pFly = pTmp ? pTmp->FindFlyFrame() : nullptr;
366 if( pFly )
367 return pFly->GetFormat();
368 return nullptr;
369}
370
371void SwFEShell::SetFlyPos( const Point& rAbsPos )
372{
373 CurrShell aCurr( this );
374
375 // Determine reference point in document coordinates
376 SwFlyFrame *pFly = GetCurrFlyFrame(false);
377 if (!pFly)
378 return;
379
380 //SwSaveHdl aSaveX( Imp() );
381
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() )
385 {
386 if(pFly->IsFlyFreeFrame() && static_cast< SwFlyFreeFrame* >(pFly)->isTransformableSwFrame())
387 {
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);
397 }
398 else
399 {
400 static_cast<SwFlyAtContentFrame*>(pFly)->SetAbsPos( rAbsPos );
401 }
402 }
403 else
404 {
405 const SwFrame *pAnch = pFly->GetAnchorFrame();
406 Point aOrient( pAnch->getFrameArea().Pos() );
407
408 if ( pFly->IsFlyInContentFrame() )
409 aOrient.setX(rAbsPos.getX());
410
411 // calculate RelPos.
412 aOrient.setX(rAbsPos.getX() - aOrient.getX());
413 aOrient.setY(rAbsPos.getY() - aOrient.getY());
414 pFly->ChgRelPos( aOrient );
415 }
416 CallChgLnk(); // call the AttrChangeNotify on the UI-side.
417}
418
419Point SwFEShell::FindAnchorPos( const Point& rAbsPos, bool bMoveIt )
420{
421 Point aRet;
422
423 CurrShell aCurr( this );
424
425 if ( !Imp()->HasDrawView() )
426 return aRet;
427
428 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
429 if ( rMrkList.GetMarkCount() != 1 ||
430 !GetUserCall(rMrkList.GetMark( 0 )->GetMarkedSdrObj()) )
431 return aRet;
432
433 SdrObject* pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
434 // #i28701#
435 SwAnchoredObject* pAnchoredObj = ::GetUserCall( pObj )->GetAnchoredObj( pObj );
436 SwFrameFormat& rFormat = pAnchoredObj->GetFrameFormat();
437 const RndStdIds nAnchorId = rFormat.GetAnchor().GetAnchorId();
438
439 if ( RndStdIds::FLY_AS_CHAR == nAnchorId )
440 return aRet;
441
442 bool bFlyFrame = dynamic_cast<SwVirtFlyDrawObj *>(pObj) != nullptr;
443
444 bool bTextBox = false;
445 if (rFormat.Which() == RES_DRAWFRMFMT)
446 {
447 bTextBox = SwTextBoxHelper::isTextBox(&rFormat, RES_DRAWFRMFMT);
448 }
449
450 SwFlyFrame* pFly = nullptr;
451 const SwFrame* pFooterOrHeader = nullptr;
452
453 if( bFlyFrame )
454 {
455 // Calculate reference point in document coordinates
456 SwContentFrame *pContent = GetCurrFrame( false );
457 if( !pContent )
458 return aRet;
459 pFly = pContent->FindFlyFrame();
460 if ( !pFly )
461 return aRet;
462 const SwFrame* pOldAnch = pFly->GetAnchorFrame();
463 if( !pOldAnch )
464 return aRet;
465 if ( RndStdIds::FLY_AT_PAGE != nAnchorId )
466 {
467 pFooterOrHeader = pContent->FindFooterOrHeader();
468 }
469 }
470 else if (bTextBox)
471 {
472 auto pFlyFormat = dynamic_cast<const SwFlyFrameFormat*>(
473 SwTextBoxHelper::getOtherTextBoxFormat(&rFormat, RES_DRAWFRMFMT));
474 if (pFlyFormat)
475 {
476 pFly = pFlyFormat->GetFrame();
477 }
478 }
479
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 ) )
484 {
485 SwContentFrame *pContent = GetCurrFrame( false );
486 if( !pContent )
487 return aRet;
488 pFooterOrHeader = pContent->FindFooterOrHeader();
489 }
490
491 // Search nearest SwFlyFrame starting from the upper-left corner
492 // of the fly
493 SwContentFrame *pTextFrame = nullptr;
494 {
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)))
501 {
502 SwContentNode* pCNode = aPos.nNode.GetNode().GetContentNode();
503 assert(pCNode)(static_cast <bool> (pCNode) ? void (0) : __assert_fail
("pCNode", "/home/maarten/src/libreoffice/core/sw/source/core/frmedt/fefly1.cxx"
, 503, __extension__ __PRETTY_FUNCTION__))
;
504 pTextFrame = pCNode->getLayoutFrame(GetLayout(), &aPos, nullptr);
505 }
506 }
507 const SwFrame *pNewAnch = nullptr;
508 if( pTextFrame != nullptr )
509 {
510 if ( RndStdIds::FLY_AT_PAGE == nAnchorId )
511 {
512 pNewAnch = pTextFrame->FindPageFrame();
513 }
514 else
515 {
516 pNewAnch = ::FindAnchor( pTextFrame, rAbsPos );
517
518 if( RndStdIds::FLY_AT_FLY == nAnchorId ) // LAYER_IMPL
519 {
520 pNewAnch = pNewAnch->FindFlyFrame();
521 }
522 }
523 }
524
525 if( pNewAnch && !pNewAnch->IsProtected() )
526 {
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
530 while( pCheck )
531 {
532 if( pCheck == pFly )
533 break;
534 const SwFrame *pTmp = pCheck->GetAnchorFrame();
535 pCheck = pTmp ? pTmp->FindFlyFrame() : nullptr;
536 }
537
538 // Do not switch from header/footer to another area,
539 // do not switch to a header/footer
540 if( !pCheck &&
541 pFooterOrHeader == pNewAnch->FindFooterOrHeader() )
542 {
543 aRet = pNewAnch->GetFrameAnchorPos( ::HasWrap( pObj ) );
544
545 if ( bMoveIt || (nAnchorId == RndStdIds::FLY_AT_CHAR) )
546 {
547 SwFormatAnchor aAnch( rFormat.GetAnchor() );
548 switch ( nAnchorId )
549 {
550 case RndStdIds::FLY_AT_PARA:
551 {
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 );
558 break;
559 }
560 case RndStdIds::FLY_AT_PAGE:
561 {
562 aAnch.SetPageNum( static_cast<const SwPageFrame*>(pNewAnch)->
563 GetPhyPageNum() );
564 break;
565 }
566
567 case RndStdIds::FLY_AT_FLY:
568 {
569 SwPosition aPos( *static_cast<const SwFlyFrame*>(pNewAnch)->GetFormat()->
570 GetContent().GetContentIdx() );
571 aAnch.SetAnchor( &aPos );
572 break;
573 }
574
575 case RndStdIds::FLY_AT_CHAR:
576 {
577 SwPosition pos = *aAnch.GetContentAnchor();
578 Point aTmpPnt( rAbsPos );
579 if( pTextFrame->GetModelPositionForViewPoint( &pos, aTmpPnt ) )
580 {
581 SwRect aTmpRect;
582 pTextFrame->GetCharRect( aTmpRect, pos );
583 aRet = aTmpRect.Pos();
584 }
585 else
586 {
587 pos = static_cast<SwTextFrame const*>(pTextFrame)->MapViewToModelPos(TextFrameIndex(0));
588 }
589 aAnch.SetAnchor( &pos );
590 break;
591 }
592 default:
593 break;
594
595 }
596
597 if( bMoveIt )
598 {
599 StartAllAction();
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.
604 {
605 std::unique_ptr<SwHandleAnchorNodeChg, o3tl::default_delete<SwHandleAnchorNodeChg>> pHandleAnchorNodeChg;
606 SwFlyFrameFormat* pFlyFrameFormat( dynamic_cast<SwFlyFrameFormat*>(&rFormat) );
607 if ( pFlyFrameFormat )
608 {
609 pHandleAnchorNodeChg.reset(
610 new SwHandleAnchorNodeChg( *pFlyFrameFormat, aAnch ));
611 }
612 rFormat.GetDoc()->SetAttr( aAnch, rFormat );
613 if (SwTextBoxHelper::getOtherTextBoxFormat(&rFormat, RES_DRAWFRMFMT))
614 {
615 SwTextBoxHelper::syncFlyFrameAttr(rFormat, rFormat.GetAttrSet());
616 }
617 }
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();
625 EndAllAction();
626 }
627 }
628
629 SwRect aTmpRect( aRet, rAbsPos );
630 if( aTmpRect.HasArea() )
631 MakeVisible( aTmpRect );
632#if OSL_DEBUG_LEVEL1 > 0
633 //TODO: That doesn't seem to be intended
634 if( COL_TRANSPARENT != GetOut()->GetLineColor() )
635 {
636 OSL_FAIL( "Hey, Joe: Where's my Null Pen?" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/frmedt/fefly1.cxx"
":" "636" ": "), "%s", "Hey, Joe: Where's my Null Pen?"); } }
while (false)
;
637 GetOut()->SetLineColor( COL_TRANSPARENT );
638 }
639#endif
640 }
641 }
642
643 return aRet;
644}
645
646const SwFrameFormat *SwFEShell::NewFlyFrame( const SfxItemSet& rSet, bool bAnchValid,
647 SwFrameFormat *pParent )
648{
649 CurrShell aCurr( this );
650 StartAllAction();
651
652 SwPaM* pCursor = GetCursor();
653 const Point aPt( GetCursorDocPos() );
654
655 SwSelBoxes aBoxes;
656 bool bMoveContent = true;
657 if( IsTableMode() )
658 {
659 GetTableSel( *this, aBoxes );
660 if( !aBoxes.empty() )
661 {
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
665 // position
666 ParkCursor( SwNodeIndex( *aBoxes[0]->GetSttNd() ));
667
668 // #i127787# pCurrentCursor will be deleted in ParkCursor,
669 // we better get the current pCurrentCursor instead of working with the
670 // deleted one:
671 pCursor = GetCursor();
672 }
673 else
674 bMoveContent = false;
675 }
676 else if( !pCursor->HasMark() && !pCursor->IsMultiSelection() )
677 bMoveContent = false;
678
679 const SwPosition& rPos = *pCursor->Start();
680
681 SwFormatAnchor& rAnch = const_cast<SwFormatAnchor&>(rSet.Get( RES_ANCHOR ));
682 RndStdIds eRndId = rAnch.GetAnchorId();
683 switch( eRndId )
684 {
685 case RndStdIds::FLY_AT_PAGE:
686 if( !rAnch.GetPageNum() ) //HotFix: Bug in UpdateByExample
687 rAnch.SetPageNum( 1 );
688 break;
689
690 case RndStdIds::FLY_AT_FLY:
691 case RndStdIds::FLY_AT_PARA:
692 case RndStdIds::FLY_AT_CHAR:
693 case RndStdIds::FLY_AS_CHAR:
694 if( !bAnchValid )
695 {
696 if( RndStdIds::FLY_AT_FLY != eRndId )
697 {
698 rAnch.SetAnchor( &rPos );
699 }
700 else if( lcl_SetNewFlyPos( rPos.nNode.GetNode(), rAnch, aPt ) )
701 {
702 eRndId = RndStdIds::FLY_AT_PAGE;
703 }
704 }
705 break;
706
707 default:
708 OSL_ENSURE( false, "What is the purpose of this Fly?" )do { if (true && (!(false))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/frmedt/fefly1.cxx"
":" "708" ": "), "%s", "What is the purpose of this Fly?"); }
} while (false)
;
709 break;
710 }
711
712 SwFlyFrameFormat *pRet;
713 if( bMoveContent )
714 {
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;
720
721 if ( RndStdIds::FLY_AT_PAGE != eRndId )
722 {
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 ) );
729
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() )
733 {
734 bHOriChgd = true;
735 aOldH.reset(static_cast<SwFormatHoriOrient*>(pItem->Clone()));
736 const_cast<SfxItemSet&>(rSet).Put( SwFormatHoriOrient( 0, text::HoriOrientation::LEFT ) );
737 }
738 if( SfxItemState::SET == rSet.GetItemState( RES_VERT_ORIENT, false, &pItem )
739 && text::VertOrientation::NONE == static_cast<const SwFormatVertOrient*>(pItem)->GetVertOrient() )
740 {
741 bVOriChgd = true;
742 aOldV.reset(static_cast<SwFormatVertOrient*>(pItem->Clone()));
743 const_cast<SfxItemSet&>(rSet).Put( SwFormatVertOrient( 0, text::VertOrientation::TOP ) );
744 }
745 }
746
747 pRet = GetDoc()->MakeFlyAndMove( *pCursor, rSet, &aBoxes, pParent );
748
749 KillPams();
750
751 if( pOldAnchor )
752 {
753 if( pRet )
754 {
755 // calculate new position
756 // JP 24.03.97: also go via page links
757 // anchor should not lie in the shifted area
758 pRet->DelFrames();
759
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() );
764
765 if ( RndStdIds::FLY_AS_CHAR == eRndId )
766 {
767 assert(pAnch->IsTextFrame())(static_cast <bool> (pAnch->IsTextFrame()) ? void (0
) : __assert_fail ("pAnch->IsTextFrame()", "/home/maarten/src/libreoffice/core/sw/source/core/frmedt/fefly1.cxx"
, 767, __extension__ __PRETTY_FUNCTION__))
;
768 aPos = static_cast<SwTextFrame const*>(pAnch)->MapViewToModelPos(TextFrameIndex(0));
769 }
770 pOldAnchor->SetAnchor( &aPos );
771
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);
777 if (bDoesUndo &&
778 GetDoc()->GetIDocumentUndoRedo().GetLastUndoInfo(nullptr,
779 & nLastUndoId))
780 {
781 if (SwUndoId::INSLAYFMT == nLastUndoId)
782 {
783 GetDoc()->GetIDocumentUndoRedo().DoUndo(false);
784 }
785 }
786
787 const_cast<SfxItemSet&>(rSet).Put( *pOldAnchor );
788
789 if( bHOriChgd )
790 const_cast<SfxItemSet&>(rSet).Put( *aOldH );
791 if( bVOriChgd )
792 const_cast<SfxItemSet&>(rSet).Put( *aOldV );
793
794 GetDoc()->SetFlyFrameAttr( *pRet, const_cast<SfxItemSet&>(rSet) );
795 GetDoc()->GetIDocumentUndoRedo().DoUndo(bDoesUndo);
796 }
797 }
798 GetDoc()->GetIDocumentUndoRedo().EndUndo( SwUndoId::INSLAYFMT, nullptr );
799 }
800 else
801 /* If called from a shell try to propagate an
802 existing adjust item from rPos to the content node of the
803 new frame. */
804 pRet = GetDoc()->MakeFlySection( eRndId, &rPos, &rSet, pParent, true );
805
806 if( pRet )
807 {
808 SwFlyFrame* pFrame = pRet->GetFrame( &aPt );
809 if( pFrame )
810 SelectFlyFrame( *pFrame );
811 else
812 {
813 GetLayout()->SetAssertFlyPages();
814 pRet = nullptr;
815 }
816 }
817 EndAllActionAndCall();
818
819 return pRet;
820}
821
822void SwFEShell::Insert( const OUString& rGrfName, const OUString& rFltName,
823 const Graphic* pGraphic,
824 const SfxItemSet* pFlyAttrSet )
825{
826 SwFlyFrameFormat* pFormat = nullptr;
827 CurrShell aCurr( this );
828 StartAllAction();
829 SwShellCursor *pStartCursor = dynamic_cast<SwShellCursor*>(GetSwCursor());
830 SwShellCursor *pCursor = pStartCursor;
831 do
832 {
833 if (!pCursor)
834 break;
835
836 // Has the anchor not been set or been set incompletely?
837 if( pFlyAttrSet )
838 {
839 const SfxPoolItem* pItem;
840 if( SfxItemState::SET == pFlyAttrSet->GetItemState( RES_ANCHOR, false,
841 &pItem ) )
842 {
843 SwFormatAnchor* pAnchor = const_cast<SwFormatAnchor*>(static_cast<const SwFormatAnchor*>(pItem));
844 switch( pAnchor->GetAnchorId())
845 {
846 case RndStdIds::FLY_AT_PARA:
847 case RndStdIds::FLY_AT_CHAR: // LAYER_IMPL
848 case RndStdIds::FLY_AS_CHAR:
849 if( !pAnchor->GetContentAnchor() )
850 {
851 pAnchor->SetAnchor( pCursor->GetPoint() );
852 }
853 break;
854 case RndStdIds::FLY_AT_FLY:
855 if( !pAnchor->GetContentAnchor() )
856 {
857 lcl_SetNewFlyPos( pCursor->GetNode(),
858 *pAnchor, GetCursorDocPos() );
859 }
860 break;
861 case RndStdIds::FLY_AT_PAGE:
862 if( !pAnchor->GetPageNum() )
863 {
864 pAnchor->SetPageNum( pCursor->GetPageNum(
865 true, &pCursor->GetPtPos() ) );
866 }
867 break;
868 default :
869 break;
870 }
871 }
872 }
873 pFormat = GetDoc()->getIDocumentContentOperations().InsertGraphic(
874 *pCursor, rGrfName,
875 rFltName, pGraphic,
876 pFlyAttrSet,
877 nullptr, nullptr );
878 OSL_ENSURE(pFormat, "IDocumentContentOperations::InsertGraphic failed.")do { if (true && (!(pFormat))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/frmedt/fefly1.cxx"
":" "878" ": "), "%s", "IDocumentContentOperations::InsertGraphic failed."
); } } while (false)
;
879
880 pCursor = pCursor->GetNext();
881 } while( pCursor != pStartCursor );
882
883 EndAllAction();
884
885 if( !pFormat )
886 return;
887
888 const Point aPt( GetCursorDocPos() );
889 SwFlyFrame* pFrame = pFormat->GetFrame( &aPt );
890
891 if( pFrame )
892 {
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();
898
899 SelectFlyFrame( *pFrame );
900 }
901 else
902 GetLayout()->SetAssertFlyPages();
903}
904
905SwFlyFrameFormat* SwFEShell::InsertObject( const svt::EmbeddedObjectRef& xObj,
906 SfxItemSet* pFlyAttrSet )
907{
908 SwFlyFrameFormat* pFormat = nullptr;
909 CurrShell aCurr( this );
910 StartAllAction();
911 {
912 for(const SwPaM& rPaM : GetCursor()->GetRingContainer())
913 {
914 pFormat = GetDoc()->getIDocumentContentOperations().InsertEmbObject(
915 rPaM, xObj, pFlyAttrSet );
916 OSL_ENSURE(pFormat, "IDocumentContentOperations::InsertEmbObject failed.")do { if (true && (!(pFormat))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/frmedt/fefly1.cxx"
":" "916" ": "), "%s", "IDocumentContentOperations::InsertEmbObject failed."
); } } while (false)
;
917 }
918 }
919 EndAllAction();
920
921 if( pFormat )
922 {
923 const Point aPt( GetCursorDocPos() );
924 SwFlyFrame* pFrame = pFormat->GetFrame( &aPt );
925
926 if( pFrame )
927 SelectFlyFrame( *pFrame );
928 else
929 GetLayout()->SetAssertFlyPages();
930 }
931
932 return pFormat;
933}
934
935void SwFEShell::InsertDrawObj( SdrObject& rDrawObj,
936 const Point& rInsertPosition )
937{
938 CurrShell aCurr( this );
939
940 SfxItemSet rFlyAttrSet( GetDoc()->GetAttrPool(), aFrameFormatSetRange );
941 rFlyAttrSet.Put( SwFormatAnchor( RndStdIds::FLY_AT_PARA ));
942 // #i89920#
943 rFlyAttrSet.Put( SwFormatSurround( css::text::WrapTextMode_THROUGH ) );
944 rDrawObj.SetLayer( getIDocumentDrawModelAccess().GetHeavenId() );
945
946 // find anchor position
947 SwPaM aPam( mxDoc->GetNodes() );
948 {
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 );
957 }
958 // insert drawing object into the document creating a new <SwDrawFrameFormat> instance
959 SwDrawFrameFormat* pFormat = GetDoc()->getIDocumentContentOperations().InsertDrawObj( aPam, rDrawObj, rFlyAttrSet );
960
961 // move object to visible layer
962 SwContact* pContact = static_cast<SwContact*>(rDrawObj.GetUserCall());
963 if ( pContact )
964 {
965 pContact->MoveObjToVisibleLayer( &rDrawObj );
966 }
967
968 if (pFormat)
969 {
970 pFormat->SetName(rDrawObj.GetName());
971 // select drawing object
972 Imp()->GetDrawView()->MarkObj( &rDrawObj, Imp()->GetPageView() );
973 }
974 else
975 {
976 GetLayout()->SetAssertFlyPages();
977 }
978}
979
980void SwFEShell::GetPageObjs( std::vector<SwFrameFormat*>& rFillArr )
981{
982 rFillArr.clear();
983
984 for( auto pFormat : *mxDoc->GetSpzFrameFormats() )
985 {
986 if (RndStdIds::FLY_AT_PAGE == pFormat->GetAnchor().GetAnchorId())
987 {
988 rFillArr.push_back( pFormat );
989 }
990 }
991}
992
993void SwFEShell::SetPageObjsNewPage( std::vector<SwFrameFormat*>& rFillArr )
994{
995 if( rFillArr.empty() )
996 return;
997
998 StartAllAction();
999 StartUndo();
1000
1001 SwRootFrame* pTmpRootFrame = GetLayout();
1002 sal_uInt16 nMaxPage = pTmpRootFrame->GetPageNum();
1003 bool bTmpAssert = false;
1004 for( auto pFormat : rFillArr )
1005 {
1006 if (mxDoc->GetSpzFrameFormats()->IsAlive(pFormat))
1007 {
1008 // FlyFormat is still valid, therefore process
1009
1010 SwFormatAnchor aNewAnchor( pFormat->GetAnchor() );
1011 if (RndStdIds::FLY_AT_PAGE != aNewAnchor.GetAnchorId())
1012 // Anchor has been changed, therefore: do not change!
1013 continue;
1014 sal_uInt16 nNewPage = aNewAnchor.GetPageNum() + 1;
1015 if (nNewPage > nMaxPage)
1016 {
1017 if ( RES_DRAWFRMFMT == pFormat->Which() )
1018 pFormat->CallSwClientNotify(sw::DrawFrameFormatHint(sw::DrawFrameFormatHintId::PAGE_OUT_OF_BOUNDS));
1019 else
1020 pFormat->DelFrames();
1021 bTmpAssert = true;
1022 }
1023 aNewAnchor.SetPageNum(nNewPage);
1024 mxDoc->SetAttr( aNewAnchor, *pFormat );
1025 }
1026 }
1027
1028 if( bTmpAssert )
1029 pTmpRootFrame->SetAssertFlyPages();
1030
1031 EndUndo();
1032 EndAllAction();
1033}
1034
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.
1038bool SwFEShell::GetFlyFrameAttr( SfxItemSet &rSet ) const
1039{
1040 SwFlyFrame *pFly = GetSelectedOrCurrFlyFrame();
1041 if (!pFly)
1042 {
1043 OSL_ENSURE( false, "GetFlyFrameAttr, no Fly selected." )do { if (true && (!(false))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/frmedt/fefly1.cxx"
":" "1043" ": "), "%s", "GetFlyFrameAttr, no Fly selected.")
; } } while (false)
;
1044 return false;
1045 }
1046
1047 CurrShell aCurr( const_cast<SwFEShell*>(this) );
1048
1049 if( !rSet.Set( pFly->GetFormat()->GetAttrSet() ) )
1050 return false;
1051
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 ) )
1056 {
1057 const SwFormatAnchor* pAnchor = static_cast<const SwFormatAnchor*>(pItem);
1058 RndStdIds eType = pAnchor->GetAnchorId();
1059
1060 if ( RndStdIds::FLY_AT_PAGE != eType )
1061 {
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 )
1065 {
1066 rSet.ClearItem( RES_OPAQUE );
1067 rSet.ClearItem( RES_SURROUND );
1068 }
1069 }
1070 }
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 );
1077 return true;
1078}
1079
1080// Attributes of the current fly will change.
1081bool SwFEShell::SetFlyFrameAttr( SfxItemSet& rSet )
1082{
1083 CurrShell aCurr( this );
1084 bool bRet = false;
1085
1086 if( rSet.Count() )
1087 {
1088 SwFlyFrame *pFly = GetSelectedOrCurrFlyFrame();
1089 OSL_ENSURE(pFly, "SetFlyFrameAttr, no Fly selected.")do { if (true && (!(pFly))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/frmedt/fefly1.cxx"
":" "1089" ": "), "%s", "SetFlyFrameAttr, no Fly selected.")
; } } while (false)
;
1090 if (pFly)
1091 {
1092 StartAllAction();
1093 const Point aPt( pFly->getFrameArea().Pos() );
1094
1095 if( SfxItemState::SET == rSet.GetItemState( RES_ANCHOR, false ))
1096 sw_ChkAndSetNewAnchor( *pFly, rSet );
1097 SwFlyFrameFormat* pFlyFormat = pFly->GetFormat();
1098
1099 if( GetDoc()->SetFlyFrameAttr( *pFlyFormat, rSet ))
1100 {
1101 bRet = true;
1102 SwFlyFrame* pFrame = pFlyFormat->GetFrame( &aPt );
1103 if( pFrame )
1104 SelectFlyFrame( *pFrame );
1105 else
1106 GetLayout()->SetAssertFlyPages();
1107 }
1108
1109 EndAllActionAndCall();
1110 }
1111 }
1112 return bRet;
1113}
1114
1115SfxItemSet SwFEShell::makeItemSetFromFormatAnchor(SfxItemPool& rPool, const SwFormatAnchor &rAnchor)
1116{
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>{});
1121 aSet.Put(rAnchor);
1122 return aSet;
1123}
1124
1125bool SwFEShell::SetDrawingAttr( SfxItemSet& rSet )
1126{
1127 bool bRet = false;
1128 CurrShell aCurr( this );
1129 if ( !rSet.Count() ||
1130 !Imp()->HasDrawView() )
1131 return bRet;
1132
1133 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
1134 if ( rMrkList.GetMarkCount() != 1 )
1135 return bRet;
1136
1137 StartUndo();
1138 SdrObject *pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
1139 SwFrameFormat *pFormat = FindFrameFormat( pObj );
1140 StartAllAction();
1141 if( SfxItemState::SET == rSet.GetItemState( RES_ANCHOR, false ))
1142 {
1143 RndStdIds nNew = rSet.Get( RES_ANCHOR ).GetAnchorId();
1144 if ( nNew != pFormat->GetAnchor().GetAnchorId() )
1145 {
1146 ChgAnchor( nNew );
1147 // #i26791# - clear anchor attribute in item set,
1148 // because method <ChgAnchor(..)> takes care of it.
1149 rSet.ClearItem( RES_ANCHOR );
1150 }
1151 }
1152
1153 if( GetDoc()->SetFlyFrameAttr( *pFormat, rSet ))
1154 {
1155 bRet = true;
1156 SelectObj( Point(), 0, pObj );
1157 }
1158 EndAllActionAndCall();
1159 EndUndo();
1160 return bRet;
1161}
1162
1163// Reset attributes contained in the set.
1164void SwFEShell::ResetFlyFrameAttr( const SfxItemSet* pSet )
1165{
1166 CurrShell aCurr( this );
1167
1168 SwFlyFrame *pFly = GetSelectedOrCurrFlyFrame();
1169 OSL_ENSURE( pFly, "SetFlyFrameAttr, no Fly selected." )do { if (true && (!(pFly))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/frmedt/fefly1.cxx"
":" "1169" ": "), "%s", "SetFlyFrameAttr, no Fly selected.")
; } } while (false)
;
1170 if( !pFly )
1171 return;
1172
1173 StartAllAction();
1174
1175 SfxItemIter aIter( *pSet );
1176 for (const SfxPoolItem* pItem = aIter.GetCurItem(); pItem; pItem = aIter.NextItem())
1177 {
1178 if( !IsInvalidItem( pItem ) )
1179 {
1180 sal_uInt16 nWhich = pItem->Which();
1181 if( RES_ANCHOR != nWhich && RES_CHAIN != nWhich && RES_CNTNT != nWhich )
1182 pFly->GetFormat()->ResetFormatAttr( nWhich );
1183 }
1184 }
1185
1186 EndAllActionAndCall();
1187 GetDoc()->getIDocumentState().SetModified();
1188}
1189
1190// Returns frame-format if frame, otherwise 0
1191SwFrameFormat* SwFEShell::GetSelectedFrameFormat() const
1192{
1193 SwFrameFormat* pRet = nullptr;
1194 SwLayoutFrame *pFly = GetSelectedFlyFrame();
1195 if( pFly && ( pRet = static_cast<SwFrameFormat*>(pFly->GetFormat()->DerivedFrom()) ) ==
1196 GetDoc()->GetDfltFrameFormat() )
1197 pRet = nullptr;
1198 return pRet;
1199}
1200
1201void SwFEShell::SetFrameFormat( SwFrameFormat *pNewFormat, bool bKeepOrient, Point const * pDocPos )
1202{
1203 SwFlyFrame *pFly = nullptr;
1204 if(pDocPos)
1205 {
1206 const SwFrameFormat* pFormat = GetFormatFromObj( *pDocPos );
1207
1208 if (const SwFlyFrameFormat* pFlyFormat = dynamic_cast<const SwFlyFrameFormat*>(pFormat))
1209 pFly = pFlyFormat->GetFrame();
1210 }
1211 else
1212 pFly = GetSelectedFlyFrame();
1213 OSL_ENSURE( pFly, "SetFrameFormat: no frame" )do { if (true && (!(pFly))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/frmedt/fefly1.cxx"
":" "1213" ": "), "%s", "SetFrameFormat: no frame"); } } while
(false)
;
1214 if( !pFly )
1215 return;
1216
1217 StartAllAction();
1218 CurrShell aCurr( this );
1219
1220 SwFlyFrameFormat* pFlyFormat = pFly->GetFormat();
1221 const Point aPt( pFly->getFrameArea().Pos() );
1222
1223 std::unique_ptr<SfxItemSet> pSet;
1224 const SfxPoolItem* pItem;
1225 if( SfxItemState::SET == pNewFormat->GetItemState( RES_ANCHOR, false, &pItem ))
1226 {
1227 pSet.reset(new SfxItemSet( GetDoc()->GetAttrPool(), aFrameFormatSetRange ));
1228 pSet->Put( *pItem );
1229 if( !sw_ChkAndSetNewAnchor( *pFly, *pSet ))
1230 {
1231 pSet.reset();
1232 }
1233 }
1234
1235 if( GetDoc()->SetFrameFormatToFly( *pFlyFormat, *pNewFormat, pSet.get(), bKeepOrient ))
1236 {
1237 SwFlyFrame* pFrame = pFlyFormat->GetFrame( &aPt );
1238 if( pFrame )
1239 SelectFlyFrame( *pFrame );
1240 else
1241 GetLayout()->SetAssertFlyPages();
1242 }
1243 pSet.reset();
1244
1245 EndAllActionAndCall();
1246}
1247
1248const SwFrameFormat* SwFEShell::GetFlyFrameFormat() const
1249{
1250 const SwFlyFrame* pFly = GetSelectedOrCurrFlyFrame();
1251 if (pFly)
1252 return pFly->GetFormat();
1253 return nullptr;
1254}
1255
1256SwFrameFormat* SwFEShell::GetFlyFrameFormat()
1257{
1258 SwFlyFrame* pFly = GetSelectedOrCurrFlyFrame();
1259 if (pFly)
1260 return pFly->GetFormat();
1261 return nullptr;
1262}
1263
1264SwRect SwFEShell::GetFlyRect() const
1265{
1266 SwFlyFrame *pFly = GetCurrFlyFrame(false);
1267 if (!pFly)
1268 {
1269 SwRect aRect;
1270 return aRect;
1271 }
1272 else
1273 return pFly->getFrameArea();
1274}
1275
1276SwRect SwFEShell::GetObjRect() const
1277{
1278 if( Imp()->HasDrawView() )
1279 return Imp()->GetDrawView()->GetAllMarkedRect();
1280 else
1281 {
1282 SwRect aRect;
1283 return aRect;
1284 }
1285}
1286
1287void SwFEShell::SetObjRect( const SwRect& rRect )
1288{
1289 if ( Imp()->HasDrawView() )
1290 {
1291 Imp()->GetDrawView()->SetAllMarkedRect( rRect.SVRect() );
1292 CallChgLnk(); // call AttrChangeNotify on the UI-side.
1293 }
1294}
1295
1296Size SwFEShell::RequestObjectResize( const SwRect &rRect, const uno::Reference < embed::XEmbeddedObject >& xObj )
1297{
1298 Size aResult;
1299
1300 SwFlyFrame *pFly = FindFlyFrame( xObj );
1301 if ( !pFly )
1302 {
1303 aResult = rRect.SSize();
1304 return aResult;
1305 }
1306
1307 aResult = pFly->getFramePrintArea().SSize();
1308
1309 bool bPosProt = pFly->GetFormat()->GetProtect().IsPosProtected();
1310 bool bSizeProt = pFly->GetFormat()->GetProtect().IsSizeProtected();
1311
1312 StartAllAction();
1313
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 )
1320 {
1321 Size aSz( rRect.SSize() );
1322
1323 //JP 28.02.2001: Task 74707 - ask for fly in fly with automatic size
1324
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())
1333 {
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())
1337 {
1338 const SfxPoolItem* pItem = &pHint->GetAttr();
1339 if( RES_TXTATR_FIELD == pItem->Which()
1340 && SwFieldTypesEnum::Sequence == static_cast<const SwFormatField*>(pItem)->GetField()->GetTypeId() )
1341 {
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() );
1348
1349 SwFrameFormat *pFormat = pChgFly->GetFormat();
1350 SwFormatFrameSize aFrameSz( pFormat->GetFrameSize() );
1351 aFrameSz.SetWidth( aNewSz.Width() );
1352 if( SwFrameSize::Minimum != aFrameSz.GetHeightSizeType() )
1353 {
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() );
1358 }
1359 // via Doc for the Undo!
1360 pFormat->GetDoc()->SetAttr( aFrameSz, *pFormat );
1361 break;
1362 }
1363 }
1364 }
1365
1366 // set the new Size at the fly themself
1367 if ( !pFly->getFramePrintArea().IsEmpty() )
1368 {
1369 aSz.AdjustWidth(pFly->getFrameArea().Width() - pFly->getFramePrintArea().Width() );
1370 aSz.AdjustHeight(pFly->getFrameArea().Height()- pFly->getFramePrintArea().Height() );
1371 }
1372 aResult = pFly->ChgSize( aSz );
1373
1374 // if the object changes, the contour is outside the object
1375 assert(pFly->Lower()->IsNoTextFrame())(static_cast <bool> (pFly->Lower()->IsNoTextFrame
()) ? void (0) : __assert_fail ("pFly->Lower()->IsNoTextFrame()"
, "/home/maarten/src/libreoffice/core/sw/source/core/frmedt/fefly1.cxx"
, 1375, __extension__ __PRETTY_FUNCTION__))
;
1376 SwNoTextNode *pNd = static_cast<SwNoTextFrame*>(pFly->Lower())->GetNode()->GetNoTextNode();
1377 assert(pNd)(static_cast <bool> (pNd) ? void (0) : __assert_fail ("pNd"
, "/home/maarten/src/libreoffice/core/sw/source/core/frmedt/fefly1.cxx"
, 1377, __extension__ __PRETTY_FUNCTION__))
;
1378 pNd->SetContour( nullptr );
1379 ClrContourCache();
1380 }
1381
1382 // if only the size is to be adjusted, a position is transported with
1383 // allocated values
1384 Point aPt( pFly->getFramePrintArea().Pos() );
1385 aPt += pFly->getFrameArea().Pos();
1386 if ( rRect.Top() != LONG_MIN(-9223372036854775807L -1L) && rRect.Pos() != aPt && !bPosProt )
1387 {
1388 aPt = rRect.Pos();
1389 aPt.setX(aPt.getX() - pFly->getFramePrintArea().Left());
1390 aPt.setY(aPt.getY() - pFly->getFramePrintArea().Top());
1391
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 );
1397 else
1398 {
1399 const SwFrameFormat *pFormat = pFly->GetFormat();
1400 const SwFormatVertOrient &rVert = pFormat->GetVertOrient();
1401 const SwFormatHoriOrient &rHori = pFormat->GetHoriOrient();
1402 const long lXDiff = aPt.getX() - pFly->getFrameArea().Left();
1403 const long lYDiff = aPt.getY() - pFly->getFrameArea().Top();
1404 const Point aTmp( rHori.GetPos() + lXDiff,
1405 rVert.GetPos() + lYDiff );
1406 pFly->ChgRelPos( aTmp );
1407 }
1408 }
1409
1410 SwFlyFrameFormat *pFlyFrameFormat = pFly->GetFormat();
1411 OSL_ENSURE( pFlyFrameFormat, "fly frame format missing!" )do { if (true && (!(pFlyFrameFormat))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/frmedt/fefly1.cxx"
":" "1411" ": "), "%s", "fly frame format missing!"); } } while
(false)
;
1412 if ( pFlyFrameFormat )
1413 pFlyFrameFormat->SetLastFlyFramePrtRectPos( pFly->getFramePrintArea().Pos() ); //stores the value of last Prt rect
1414
1415 EndAllAction();
1416
1417 return aResult;
1418}
1419
1420SwFrameFormat* SwFEShell::WizardGetFly()
1421{
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() )
1426 {
1427 SwNodeIndex& rCursorNd = GetCursor()->GetPoint()->nNode;
1428 if( rCursorNd.GetIndex() > mxDoc->GetNodes().GetEndOfExtras().GetIndex() )
1429 // Cursor is in the body area!
1430 return nullptr;
1431
1432 for( auto pFormat : rSpzArr )
1433 {
1434 const SwNodeIndex* pIdx = pFormat->GetContent( false ).GetContentIdx();
1435 SwStartNode* pSttNd;
1436 if( pIdx &&
1437 nullptr != ( pSttNd = pIdx->GetNode().GetStartNode() ) &&
1438 pSttNd->GetIndex() < rCursorNd.GetIndex() &&
1439 rCursorNd.GetIndex() < pSttNd->EndOfSectionIndex() )
1440 {
1441 // found: return immediately
1442 return pFormat;
1443 }
1444 }
1445 }
1446 return nullptr;
1447}
1448
1449void SwFEShell::SetFlyName( const OUString& rName )
1450{
1451 SwLayoutFrame *pFly = GetSelectedFlyFrame();
1452 if( pFly )
1453 GetDoc()->SetFlyName( *static_cast<SwFlyFrameFormat*>(pFly->GetFormat()), rName );
1454 else {
1455 OSL_ENSURE( false, "no FlyFrame selected" )do { if (true && (!(false))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/frmedt/fefly1.cxx"
":" "1455" ": "), "%s", "no FlyFrame selected"); } } while (
false)
;
1456 }
1457}
1458
1459OUString SwFEShell::GetFlyName() const
1460{
1461 SwLayoutFrame *pFly = GetSelectedFlyFrame();
1462 if( pFly )
1463 return pFly->GetFormat()->GetName();
1464
1465 OSL_ENSURE( false, "no FlyFrame selected" )do { if (true && (!(false))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/frmedt/fefly1.cxx"
":" "1465" ": "), "%s", "no FlyFrame selected"); } } while (
false)
;
1466 return OUString();
1467}
1468
1469uno::Reference < embed::XEmbeddedObject > SwFEShell::GetOleRef() const
1470{
1471 uno::Reference < embed::XEmbeddedObject > xObj;
1472 SwFlyFrame * pFly = GetSelectedFlyFrame();
1473 if (pFly && pFly->Lower() && pFly->Lower()->IsNoTextFrame())
1474 {
1475 SwOLENode *pNd = static_cast<SwNoTextFrame*>(pFly->Lower())->GetNode()->GetOLENode();
1476 if (pNd)
1477 xObj = pNd->GetOLEObj().GetOleRef();
1478 }
1479 return xObj;
1480}
1481
1482OUString SwFEShell::GetUniqueGrfName() const
1483{
1484 return GetDoc()->GetUniqueGrfName();
1485}
1486
1487const SwFrameFormat* SwFEShell::IsURLGrfAtPos( const Point& rPt, OUString* pURL,
1488 OUString *pTargetFrameName,
1489 OUString *pDescription ) const
1490{
1491 if( !Imp()->HasDrawView() )
1492 return nullptr;
1493
1494 SdrPageView* pPV;
1495 const SwFrameFormat* pRet = nullptr;
1496 SwDrawView *pDView = const_cast<SwDrawView*>(Imp()->GetDrawView());
1497
1498 const auto nOld = pDView->GetHitTolerancePixel();
1499 pDView->SetHitTolerancePixel( 2 );
1500
1501 SdrObject* pObj = pDView->PickObj(rPt, pDView->getHitTolLog(), pPV, SdrSearchOptions::PICKMACRO);
1502 SwVirtFlyDrawObj* pFlyObj = dynamic_cast<SwVirtFlyDrawObj*>(pObj);
1503 if (pFlyObj)
1504 {
1505 SwFlyFrame *pFly = pFlyObj->GetFlyFrame();
1506 const SwFormatURL &rURL = pFly->GetFormat()->GetURL();
1507 if( !rURL.GetURL().isEmpty() || rURL.GetMap() )
1508 {
1509 bool bSetTargetFrameName = pTargetFrameName != nullptr;
1510 bool bSetDescription = pDescription != nullptr;
1511 if ( rURL.GetMap() )
1512 {
1513 IMapObject *pObject = pFly->GetFormat()->GetIMapObject( rPt, pFly );
1514 if ( pObject && !pObject->GetURL().isEmpty() )
1515 {
1516 if( pURL )
1517 *pURL = pObject->GetURL();
1518 if ( bSetTargetFrameName && !pObject->GetTarget().isEmpty() )
1519 {
1520 bSetTargetFrameName = false;
1521 *pTargetFrameName = pObject->GetTarget();
1522 }
1523 if ( bSetDescription )
1524 {
1525 bSetDescription = false;
1526 *pDescription = pObject->GetAltText();
1527 }
1528 pRet = pFly->GetFormat();
1529 }
1530 }
1531 else
1532 {
1533 if( pURL )
1534 {
1535 *pURL = rURL.GetURL();
1536 if( rURL.IsServerMap() )
1537 {
1538 // append the relative pixel position !!
1539 Point aPt( rPt );
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() );
1546 }
1547 }
1548 pRet = pFly->GetFormat();
1549 }
1550 if ( bSetTargetFrameName )
1551 *pTargetFrameName = rURL.GetTargetFrameName();
1552 if ( bSetDescription )
1553 *pDescription = pFly->GetFormat()->GetName();
1554 }
1555 }
1556 pDView->SetHitTolerancePixel( nOld );
1557 return pRet;
1558}
1559
1560const Graphic *SwFEShell::GetGrfAtPos( const Point &rPt,
1561 OUString &rName, bool &rbLink ) const
1562{
1563 if( !Imp()->HasDrawView() )
1564 return nullptr;
1565
1566 SdrPageView* pPV;
1567 SwDrawView *pDView = const_cast<SwDrawView*>(Imp()->GetDrawView());
1568
1569 SdrObject* pObj = pDView->PickObj(rPt, pDView->getHitTolLog(), pPV);
1570 SwVirtFlyDrawObj* pFlyObj = dynamic_cast<SwVirtFlyDrawObj*>(pObj);
1571 if (pFlyObj)
1572 {
1573 SwFlyFrame *pFly = pFlyObj->GetFlyFrame();
1574 if ( pFly->Lower() && pFly->Lower()->IsNoTextFrame() )
1575 {
1576 SwGrfNode *const pNd = static_cast<SwNoTextFrame*>(pFly->Lower())->GetNode()->GetGrfNode();
1577 if ( pNd )
1578 {
1579 if ( pNd->IsGrfLink() )
1580 {
1581 // halfway ready graphic?
1582 ::sfx2::SvLinkSource* pLnkObj = pNd->GetLink()->GetObj();
1583 if( pLnkObj && pLnkObj->IsPending() )
1584 return nullptr;
1585 rbLink = true;
1586 }
1587
1588 pNd->GetFileFilterNms( &rName, nullptr );
1589 if ( rName.isEmpty() )
1590 rName = pFly->GetFormat()->GetName();
1591 return &pNd->GetGrf(true);
1592 }
1593 }
1594 }
1595 return nullptr;
1596}
1597
1598const SwFrameFormat* SwFEShell::GetFormatFromObj( const Point& rPt, SwRect** pRectToFill ) const
1599{
1600 SwFrameFormat* pRet = nullptr;
1601
1602 if( Imp()->HasDrawView() )
1603 {
1604 SdrPageView* pPView;
1605
1606 SwDrawView *pDView = const_cast<SwDrawView*>(Imp()->GetDrawView());
1607
1608 const auto nOld = pDView->GetHitTolerancePixel();
1609 // tolerance for Drawing-SS
1610 pDView->SetHitTolerancePixel( pDView->GetMarkHdlSizePixel()/2 );
1611
1612 SdrObject* pObj = pDView->PickObj(rPt, pDView->getHitTolLog(), pPView, SdrSearchOptions::PICKMARKABLE);
1613 if (pObj)
1614 {
1615 // first check it:
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();
1622 }
1623 pDView->SetHitTolerancePixel( nOld );
1624 }
1625 return pRet;
1626}
1627
1628// returns a format too, if the point is over the text of any fly
1629const SwFrameFormat* SwFEShell::GetFormatFromAnyObj( const Point& rPt ) const
1630{
1631 const SwFrameFormat* pRet = GetFormatFromObj( rPt );
1632 if( !pRet || RES_FLYFRMFMT == pRet->Which() )
1633 {
1634 SwPosition aPos( *GetCursor()->GetPoint() );
1635 Point aPt( rPt );
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;
1641 }
1642 return pRet;
1643}
1644
1645ObjCntType SwFEShell::GetObjCntType( const SdrObject& rObj )
1646{
1647 ObjCntType eType = OBJCNT_NONE;
1648
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))
1653 {
1654 pInvestigatedObj = &(pDrawVirtObj->GetReferencedObj());
1655 }
1656 else
1657 {
1658 pInvestigatedObj = &rObj;
1659 }
1660
1661 if( SdrInventor::FmForm == pInvestigatedObj->GetObjInventor() )
1662 {
1663 eType = OBJCNT_CONTROL;
1664 uno::Reference< awt::XControlModel > xModel =
1665 static_cast<const SdrUnoObj&>(*pInvestigatedObj).GetUnoControlModel();
1666 if( xModel.is() )
1667 {
1668 uno::Any aVal;
1669 OUString sName("ButtonType");
1670 uno::Reference< beans::XPropertySet > xSet(xModel, uno::UNO_QUERY);
1671
1672 uno::Reference< beans::XPropertySetInfo > xInfo = xSet->getPropertySetInfo();
1673 if(xInfo->hasPropertyByName( sName ))
1674 {
1675 aVal = xSet->getPropertyValue( sName );
1676 if( aVal.hasValue() && form::FormButtonType_URL == *o3tl::doAccess<form::FormButtonType>(aVal) )
1677 eType = OBJCNT_URLBUTTON;
1678 }
1679 }
1680 }
1681 else if (const SwVirtFlyDrawObj *pFlyObj = dynamic_cast<const SwVirtFlyDrawObj*>(pInvestigatedObj))
1682 {
1683 const SwFlyFrame *pFly = pFlyObj->GetFlyFrame();
1684 if ( pFly->Lower() && pFly->Lower()->IsNoTextFrame() )
1685 {
1686 if (static_cast<const SwNoTextFrame*>(pFly->Lower())->GetNode()->GetGrfNode())
1687 eType = OBJCNT_GRF;
1688 else
1689 eType = OBJCNT_OLE;
1690 }
1691 else
1692 eType = OBJCNT_FLY;
1693 }
1694 else if ( dynamic_cast<const SdrObjGroup*>( pInvestigatedObj) != nullptr )
1695 {
1696 SwDrawContact* pDrawContact( dynamic_cast<SwDrawContact*>(GetUserCall( pInvestigatedObj ) ) );
1697 if ( !pDrawContact )
1698 {
1699 OSL_FAIL( "<SwFEShell::GetObjCntType(..)> - missing draw contact object" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/frmedt/fefly1.cxx"
":" "1699" ": "), "%s", "<SwFEShell::GetObjCntType(..)> - missing draw contact object"
); } } while (false)
;
1700 eType = OBJCNT_NONE;
1701 }
1702 else
1703 {
1704 SwFrameFormat* pFrameFormat( pDrawContact->GetFormat() );
1705 if ( !pFrameFormat )
1706 {
1707 OSL_FAIL( "<SwFEShell::GetObjCntType(..)> - missing frame format" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/frmedt/fefly1.cxx"
":" "1707" ": "), "%s", "<SwFEShell::GetObjCntType(..)> - missing frame format"
); } } while (false)
;
1708 eType = OBJCNT_NONE;
1709 }
1710 else if ( RndStdIds::FLY_AS_CHAR != pFrameFormat->GetAnchor().GetAnchorId() )
1711 {
1712 eType = OBJCNT_GROUPOBJ;
1713 }
1714 }
1715 }
1716 else
1717 eType = OBJCNT_SIMPLE;
1718 return eType;
1719}
1720
1721ObjCntType SwFEShell::GetObjCntType( const Point &rPt, SdrObject *&rpObj ) const
1722{
1723 ObjCntType eType = OBJCNT_NONE;
1724
1725 if( Imp()->HasDrawView() )
1726 {
1727 SdrPageView* pPView;
1728
1729 SwDrawView *pDView = const_cast<SwDrawView*>(Imp()->GetDrawView());
1730
1731 const auto nOld = pDView->GetHitTolerancePixel();
1732 // tolerance for Drawing-SS
1733 pDView->SetHitTolerancePixel( pDView->GetMarkHdlSizePixel()/2 );
1734
1735 SdrObject* pObj = pDView->PickObj(rPt, pDView->getHitTolLog(), pPView, SdrSearchOptions::PICKMARKABLE);
1736 if (pObj)
1737 {
1738 rpObj = pObj;
1739 eType = GetObjCntType( *rpObj );
1740 }
1741
1742 pDView->SetHitTolerancePixel( nOld );
1743 }
1744 return eType;
1745}
1746
1747ObjCntType SwFEShell::GetObjCntTypeOfSelection() const
1748{
1749 ObjCntType eType = OBJCNT_NONE;
1750
1751 if( Imp()->HasDrawView() )
1752 {
1753 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
1754 for( size_t i = 0, nE = rMrkList.GetMarkCount(); i < nE; ++i )
1755 {
1756 SdrObject* pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
1757 if( !pObj )
1758 continue;
1759 ObjCntType eTmp = GetObjCntType( *pObj );
1760 if( !i )
1761 {
1762 eType = eTmp;
1763 }
1764 else if( eTmp != eType )
1765 {
1766 eType = OBJCNT_DONTCARE;
1767 // once DontCare, always DontCare!
1768 break;
1769 }
1770 }
1771 }
1772 return eType;
1773}
1774
1775void SwFEShell::ReplaceSdrObj( const OUString& rGrfName, const Graphic* pGrf )
1776{
1777 CurrShell aCurr( this );
1778
1779 const SdrMarkList *pMrkList;
1780 if( !(Imp()->HasDrawView() && 1 ==
1
Assuming the condition is true
2
Taking false branch
1781 ( pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList())->GetMarkCount()) )
1782 return;
1783
1784 SdrObject* pObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj();
3
'pObj' initialized here
1785 SwFrameFormat *pFormat = FindFrameFormat( pObj );
1786
1787 // store attributes, then set the graphic
1788 SfxItemSet aFrameSet( mxDoc->GetAttrPool(),
1789 pFormat->GetAttrSet().GetRanges() );
1790 aFrameSet.Set( pFormat->GetAttrSet() );
1791
1792 // set size and position?
1793 if( dynamic_cast<const SwVirtFlyDrawObj*>( pObj) == nullptr )
4
Assuming pointer value is null
5
Taking true branch
1794 {
1795 // then let's do it:
1796 const tools::Rectangle &rBound = pObj->GetSnapRect();
6
Called C++ object pointer is null
1797 Point aRelPos( pObj->GetRelativePos() );
1798
1799 const long nWidth = rBound.Right() - rBound.Left();
1800 const long nHeight= rBound.Bottom() - rBound.Top();
1801 aFrameSet.Put( SwFormatFrameSize( SwFrameSize::Minimum,
1802 std::max( nWidth, long(MINFLY23) ),
1803 std::max( nHeight, long(MINFLY23) )));
1804
1805 if( SfxItemState::SET != aFrameSet.GetItemState( RES_HORI_ORIENT ))
1806 aFrameSet.Put( SwFormatHoriOrient( aRelPos.getX(), text::HoriOrientation::NONE, text::RelOrientation::FRAME ));
1807
1808 if( SfxItemState::SET != aFrameSet.GetItemState( RES_VERT_ORIENT ))
1809 aFrameSet.Put( SwFormatVertOrient( aRelPos.getY(), text::VertOrientation::NONE, text::RelOrientation::FRAME ));
1810
1811 }
1812
1813 pObj->GetOrdNum();
1814
1815 StartAllAction();
1816 StartUndo();
1817
1818 // delete "Sdr-Object", insert the graphic instead
1819 DelSelectedObj();
1820
1821 GetDoc()->getIDocumentContentOperations().InsertGraphic(
1822 *GetCursor(), rGrfName, "", pGrf, &aFrameSet, nullptr, nullptr);
1823
1824 EndUndo();
1825 EndAllAction();
1826}
1827
1828static sal_uInt16 SwFormatGetPageNum(const SwFlyFrameFormat * pFormat)
1829{
1830 OSL_ENSURE(pFormat != nullptr, "invalid argument")do { if (true && (!(pFormat != nullptr))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/frmedt/fefly1.cxx"
":" "1830" ": "), "%s", "invalid argument"); } } while (false
)
;
1831
1832 SwFlyFrame * pFrame = pFormat->GetFrame();
1833
1834 sal_uInt16 aResult;
1835
1836 if (pFrame != nullptr)
1837 aResult = pFrame->GetPhyPageNum();
1838 else
1839 aResult = pFormat->GetAnchor().GetPageNum();
1840
1841 return aResult;
1842}
1843
1844void SwFEShell::GetConnectableFrameFormats(SwFrameFormat & rFormat,
1845 const OUString & rReference,
1846 bool bSuccessors,
1847 std::vector< OUString > & aPrevPageVec,
1848 std::vector< OUString > & aThisPageVec,
1849 std::vector< OUString > & aNextPageVec,
1850 std::vector< OUString > & aRestVec)
1851{
1852 StartAction();
1853
1854 SwFormatChain rChain = rFormat.GetChain();
1855 SwFrameFormat * pOldChainNext = rChain.GetNext();
1856 SwFrameFormat * pOldChainPrev = rChain.GetPrev();
1857
1858 if (pOldChainNext)
1859 mxDoc->Unchain(rFormat);
1860
1861 if (pOldChainPrev)
1862 mxDoc->Unchain(*pOldChainPrev);
1863
1864 const size_t nCnt = mxDoc->GetFlyCount(FLYCNTTYPE_FRM);
1865
1866 /* potential successors resp. predecessors */
1867 std::vector< const SwFrameFormat * > aTmpSpzArray;
1868
1869 mxDoc->FindFlyByName(rReference);
1870
1871 for (size_t n = 0; n < nCnt; ++n)
1872 {
1873 const SwFrameFormat & rFormat1 = *(mxDoc->GetFlyNum(n, FLYCNTTYPE_FRM));
1874
1875 /*
1876 pFormat is a potential successor of rFormat if it is chainable after
1877 rFormat.
1878
1879 pFormat is a potential predecessor of rFormat if rFormat is chainable
1880 after pFormat.
1881 */
1882
1883 SwChainRet nChainState;
1884
1885 if (bSuccessors)
1886 nChainState = mxDoc->Chainable(rFormat, rFormat1);
1887 else
1888 nChainState = mxDoc->Chainable(rFormat1, rFormat);
1889
1890 if (nChainState == SwChainRet::OK)
1891 {
1892 aTmpSpzArray.push_back(&rFormat1);
1893
1894 }
1895
1896 }
1897
1898 if (!aTmpSpzArray.empty())
1899 {
1900 aPrevPageVec.clear();
1901 aThisPageVec.clear();
1902 aNextPageVec.clear();
1903 aRestVec.clear();
1904
1905 /* number of page rFormat resides on */
1906 sal_uInt16 nPageNum = SwFormatGetPageNum(static_cast<SwFlyFrameFormat *>(&rFormat));
1907
1908 for (const auto& rpFormat : aTmpSpzArray)
1909 {
1910 const OUString aString = rpFormat->GetName();
1911
1912 /* rFormat is not a valid successor or predecessor of
1913 itself */
1914 if (aString != rReference && aString != rFormat.GetName())
1915 {
1916 sal_uInt16 nNum1 =
1917 SwFormatGetPageNum(static_cast<const SwFlyFrameFormat *>(rpFormat));
1918
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);
1925 else
1926 aRestVec.push_back(aString);
1927 }
1928 }
1929
1930 }
1931
1932 if (pOldChainNext)
1933 mxDoc->Chain(rFormat, *pOldChainNext);
1934
1935 if (pOldChainPrev)
1936 mxDoc->Chain(*pOldChainPrev, rFormat);
1937
1938 EndAction();
1939}
1940
1941// #i73249#
1942OUString SwFEShell::GetObjTitle() const
1943{
1944 if ( Imp()->HasDrawView() )
1945 {
1946 const SdrMarkList *pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList();
1947 if ( pMrkList->GetMarkCount() == 1 )
1948 {
1949 const SdrObject* pObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj();
1950 const SwFrameFormat* pFormat = FindFrameFormat( pObj );
1951 if ( pFormat->Which() == RES_FLYFRMFMT )
1952 {
1953 return static_cast<const SwFlyFrameFormat*>(pFormat)->GetObjTitle();
1954 }
1955 return pObj->GetTitle();
1956 }
1957 }
1958
1959 return OUString();
1960}
1961
1962void SwFEShell::SetObjTitle( const OUString& rTitle )
1963{
1964 if ( !Imp()->HasDrawView() )
1965 return;
1966
1967 const SdrMarkList *pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList();
1968 if ( pMrkList->GetMarkCount() != 1 )
1969 return;
1970
1971 SdrObject* pObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj();
1972 SwFrameFormat* pFormat = FindFrameFormat( pObj );
1973 if ( pFormat->Which() == RES_FLYFRMFMT )
1974 {
1975 GetDoc()->SetFlyFrameTitle( dynamic_cast<SwFlyFrameFormat&>(*pFormat),
1976 rTitle );
1977 }
1978 else
1979 {
1980 pObj->SetTitle( rTitle );
1981 }
1982}
1983
1984OUString SwFEShell::GetObjDescription() const
1985{
1986 if ( Imp()->HasDrawView() )
1987 {
1988 const SdrMarkList *pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList();
1989 if ( pMrkList->GetMarkCount() == 1 )
1990 {
1991 const SdrObject* pObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj();
1992 const SwFrameFormat* pFormat = FindFrameFormat( pObj );
1993 if ( pFormat->Which() == RES_FLYFRMFMT )
1994 {
1995 return dynamic_cast<const SwFlyFrameFormat&>(*pFormat).GetObjDescription();
1996 }
1997 return pObj->GetDescription();
1998 }
1999 }
2000
2001 return OUString();
2002}
2003
2004void SwFEShell::SetObjDescription( const OUString& rDescription )
2005{
2006 if ( !Imp()->HasDrawView() )
2007 return;
2008
2009 const SdrMarkList *pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList();
2010 if ( pMrkList->GetMarkCount() != 1 )
2011 return;
2012
2013 SdrObject* pObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj();
2014 SwFrameFormat* pFormat = FindFrameFormat( pObj );
2015 if ( pFormat->Which() == RES_FLYFRMFMT )
2016 {
2017 GetDoc()->SetFlyFrameDescription(dynamic_cast<SwFlyFrameFormat&>(*pFormat),
2018 rDescription);
2019 }
2020 else
2021 {
2022 pObj->SetDescription( rDescription );
2023 }
2024}
2025
2026void SwFEShell::AlignFormulaToBaseline( const uno::Reference < embed::XEmbeddedObject >& xObj )
2027{
2028#if OSL_DEBUG_LEVEL1 > 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" )do { if (true && (!(bStarMath))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/frmedt/fefly1.cxx"
":" "2031" ": "), "%s", "AlignFormulaToBaseline should only be called for Math objects"
); } } while (false)
;
2032
2033 if ( !bStarMath )
2034 return;
2035#endif
2036
2037 SwFlyFrame * pFly = FindFlyFrame( xObj );
2038 OSL_ENSURE( pFly , "No fly frame!" )do { if (true && (!(pFly))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/frmedt/fefly1.cxx"
":" "2038" ": "), "%s", "No fly frame!"); } } while (false)
;
2039 SwFrameFormat * pFrameFormat = pFly ? pFly->GetFormat() : nullptr;
2040
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() )
2043 return;
2044
2045 // get baseline from Math object
2046 uno::Any aBaseline;
2047 if( svt::EmbeddedObjectRef::TryRunningState( xObj ) )
2048 {
2049 uno::Reference < beans::XPropertySet > xSet( xObj->getComponent(), uno::UNO_QUERY );
2050 if ( xSet.is() )
2051 {
2052 try
2053 {
2054 aBaseline = xSet->getPropertyValue("BaseLine");
2055 }
2056 catch ( uno::Exception& )
2057 {
2058 OSL_FAIL( "Baseline could not be retrieved from Starmath!" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/frmedt/fefly1.cxx"
":" "2058" ": "), "%s", "Baseline could not be retrieved from Starmath!"
); } } while (false)
;
2059 }
2060 }
2061 }
2062
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() );
2067
2068 OSL_ENSURE( nBaseline > 0, "Wrong value of Baseline while retrieving from Starmath!" )do { if (true && (!(nBaseline > 0))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/frmedt/fefly1.cxx"
":" "2068" ": "), "%s", "Wrong value of Baseline while retrieving from Starmath!"
); } } while (false)
;
2069 //nBaseline must be moved by aPrt position
2070 const SwFlyFrameFormat *pFlyFrameFormat = pFly->GetFormat();
2071 OSL_ENSURE( pFlyFrameFormat, "fly frame format missing!" )do { if (true && (!(pFlyFrameFormat))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/frmedt/fefly1.cxx"
":" "2071" ": "), "%s", "fly frame format missing!"); } } while
(false)
;
2072 if ( pFlyFrameFormat )
2073 nBaseline += pFlyFrameFormat->GetLastFlyFramePrtRectPos().Y();
2074
2075 const SwFormatVertOrient &rVert = pFrameFormat->GetVertOrient();
2076 SwFormatVertOrient aVert( rVert );
2077 aVert.SetPos( -nBaseline );
2078 aVert.SetVertOrient( css::text::VertOrientation::NONE );
2079
2080 pFrameFormat->LockModify();
2081 pFrameFormat->SetFormatAttr( aVert );
2082 pFrameFormat->UnlockModify();
2083 pFly->InvalidatePos();
2084
2085}
2086
2087void SwFEShell::AlignAllFormulasToBaseline()
2088{
2089 StartAllAction();
2090
2091 SwStartNode *pStNd;
2092 SwNodeIndex aIdx( *GetNodes().GetEndOfAutotext().StartOfSectionNode(), 1 );
2093 while ( nullptr != (pStNd = aIdx.GetNode().GetStartNode()) )
2094 {
2095 ++aIdx;
2096 SwOLENode *pOleNode = dynamic_cast< SwOLENode * >( &aIdx.GetNode() );
2097 if ( pOleNode )
2098 {
2099 const uno::Reference < embed::XEmbeddedObject > & xObj( pOleNode->GetOLEObj().GetOleRef() );
2100 if (xObj.is())
2101 {
2102 SvGlobalName aCLSID( xObj->getClassID() );
2103 if ( SotExchange::IsMath( aCLSID ) )
2104 AlignFormulaToBaseline( xObj );
2105 }
2106 }
2107
2108 aIdx.Assign( *pStNd->EndOfSectionNode(), + 1 );
2109 }
2110
2111 EndAllAction();
2112}
2113
2114/* vim:set shiftwidth=4 softtabstop=4 expandtab: */