File: | home/maarten/src/libreoffice/core/sw/source/core/draw/dview.cxx |
Warning: | line 700, column 19 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 <svx/svdpage.hxx> | |||
22 | #include <svx/svdpagv.hxx> | |||
23 | #include <svx/fmmodel.hxx> | |||
24 | #include <sot/exchange.hxx> | |||
25 | #include <svx/sdrundomanager.hxx> | |||
26 | #include <tools/globname.hxx> | |||
27 | #include <editeng/outliner.hxx> | |||
28 | #include <com/sun/star/embed/EmbedMisc.hpp> | |||
29 | #include <com/sun/star/embed/XEmbeddedObject.hpp> | |||
30 | ||||
31 | #include <pagefrm.hxx> | |||
32 | #include <rootfrm.hxx> | |||
33 | #include <cntfrm.hxx> | |||
34 | #include <notxtfrm.hxx> | |||
35 | #include <flyfrm.hxx> | |||
36 | #include <frmfmt.hxx> | |||
37 | #include <dflyobj.hxx> | |||
38 | #include <dcontact.hxx> | |||
39 | #include <textboxhelper.hxx> | |||
40 | #include <viewsh.hxx> | |||
41 | #include <viewimp.hxx> | |||
42 | #include <dview.hxx> | |||
43 | #include <doc.hxx> | |||
44 | #include <mdiexp.hxx> | |||
45 | #include <ndole.hxx> | |||
46 | #include <ndgrf.hxx> | |||
47 | #include <fmtanchr.hxx> | |||
48 | #include <IDocumentUndoRedo.hxx> | |||
49 | #include <DocumentSettingManager.hxx> | |||
50 | #include <IDocumentLayoutAccess.hxx> | |||
51 | ||||
52 | #include <com/sun/star/embed/Aspects.hpp> | |||
53 | ||||
54 | #include <vector> | |||
55 | ||||
56 | #include <sortedobjs.hxx> | |||
57 | #include <UndoManager.hxx> | |||
58 | ||||
59 | using namespace com::sun::star; | |||
60 | ||||
61 | namespace { | |||
62 | ||||
63 | class SwSdrHdl : public SdrHdl | |||
64 | { | |||
65 | public: | |||
66 | SwSdrHdl(const Point& rPnt, bool bTopRight ) : | |||
67 | SdrHdl( rPnt, bTopRight ? SdrHdlKind::Anchor_TR : SdrHdlKind::Anchor ) {} | |||
68 | virtual bool IsFocusHdl() const override; | |||
69 | }; | |||
70 | ||||
71 | } | |||
72 | ||||
73 | bool SwSdrHdl::IsFocusHdl() const | |||
74 | { | |||
75 | if( SdrHdlKind::Anchor == eKind || SdrHdlKind::Anchor_TR == eKind ) | |||
76 | return true; | |||
77 | return SdrHdl::IsFocusHdl(); | |||
78 | } | |||
79 | ||||
80 | static const SwFrame *lcl_FindAnchor( const SdrObject *pObj, bool bAll ) | |||
81 | { | |||
82 | const SwVirtFlyDrawObj *pVirt = dynamic_cast< const SwVirtFlyDrawObj *>( pObj ) != nullptr ? | |||
83 | static_cast<const SwVirtFlyDrawObj*>(pObj) : nullptr; | |||
84 | if ( pVirt ) | |||
85 | { | |||
86 | if ( bAll || !pVirt->GetFlyFrame()->IsFlyInContentFrame() ) | |||
87 | return pVirt->GetFlyFrame()->GetAnchorFrame(); | |||
88 | } | |||
89 | else | |||
90 | { | |||
91 | const SwDrawContact *pCont = static_cast<const SwDrawContact*>(GetUserCall(pObj)); | |||
92 | if ( pCont ) | |||
93 | return pCont->GetAnchorFrame( pObj ); | |||
94 | } | |||
95 | return nullptr; | |||
96 | } | |||
97 | ||||
98 | SwDrawView::SwDrawView( | |||
99 | SwViewShellImp& rI, | |||
100 | FmFormModel& rFmFormModel, | |||
101 | OutputDevice* pOutDev) | |||
102 | : FmFormView(rFmFormModel, pOutDev), | |||
103 | m_rImp( rI ) | |||
104 | { | |||
105 | SetPageVisible( false ); | |||
106 | SetBordVisible( false ); | |||
107 | SetGridVisible( false ); | |||
108 | SetHlplVisible( false ); | |||
109 | SetGlueVisible( false ); | |||
110 | SetFrameDragSingles(); | |||
111 | SetSwapAsynchron(); | |||
112 | ||||
113 | EnableExtendedKeyInputDispatcher( false ); | |||
114 | EnableExtendedMouseEventDispatcher( false ); | |||
115 | ||||
116 | SetHitTolerancePixel( GetMarkHdlSizePixel()/2 ); | |||
117 | ||||
118 | SetPrintPreview( rI.GetShell()->IsPreview() ); | |||
119 | ||||
120 | // #i73602# Use default from the configuration | |||
121 | SetBufferedOverlayAllowed(getOptionsDrawinglayer().IsOverlayBuffer_Writer()); | |||
122 | ||||
123 | // #i74769#, #i75172# Use default from the configuration | |||
124 | SetBufferedOutputAllowed(getOptionsDrawinglayer().IsPaintBuffer_Writer()); | |||
125 | } | |||
126 | ||||
127 | // #i99665# | |||
128 | bool SwDrawView::IsAntiAliasing() const | |||
129 | { | |||
130 | return getOptionsDrawinglayer().IsAntiAliasing(); | |||
131 | } | |||
132 | ||||
133 | static SdrObject* impLocalHitCorrection(SdrObject* pRetval, const Point& rPnt, sal_uInt16 nTol, const SdrMarkList &rMrkList) | |||
134 | { | |||
135 | if(!nTol) | |||
136 | { | |||
137 | // the old method forced back to outer bounds test when nTol == 0, so | |||
138 | // do not try to correct when nTol is not set (used from HelpContent) | |||
139 | } | |||
140 | else | |||
141 | { | |||
142 | // rebuild logic from former SwVirtFlyDrawObj::CheckSdrObjectHit. This is needed since | |||
143 | // the SdrObject-specific CheckHit implementations are now replaced with primitives and | |||
144 | // 'tricks' like in the old implementation (e.g. using a view from a model-data class to | |||
145 | // detect if object is selected) are no longer valid. | |||
146 | // The standard primitive hit-test for SwVirtFlyDrawObj now is the outer bound. The old | |||
147 | // implementation reduced this excluding the inner bound when the object was not selected. | |||
148 | SwVirtFlyDrawObj* pSwVirtFlyDrawObj = dynamic_cast< SwVirtFlyDrawObj* >(pRetval); | |||
149 | ||||
150 | if(pSwVirtFlyDrawObj) | |||
151 | { | |||
152 | if(pSwVirtFlyDrawObj->GetFlyFrame()->Lower() && pSwVirtFlyDrawObj->GetFlyFrame()->Lower()->IsNoTextFrame()) | |||
153 | { | |||
154 | // the old method used IsNoTextFrame (should be for SW's own OLE and | |||
155 | // graphic's) to accept hit only based on outer bounds; nothing to do | |||
156 | } | |||
157 | else | |||
158 | { | |||
159 | // check if the object is selected in this view | |||
160 | const size_t nMarkCount(rMrkList.GetMarkCount()); | |||
161 | bool bSelected(false); | |||
162 | ||||
163 | for(size_t a = 0; !bSelected && a < nMarkCount; ++a) | |||
164 | { | |||
165 | if(pSwVirtFlyDrawObj == rMrkList.GetMark(a)->GetMarkedSdrObj()) | |||
166 | { | |||
167 | bSelected = true; | |||
168 | } | |||
169 | } | |||
170 | ||||
171 | if(!bSelected) | |||
172 | { | |||
173 | // when not selected, the object is not hit when hit position is inside | |||
174 | // inner range. Get and shrink inner range | |||
175 | basegfx::B2DRange aInnerBound(pSwVirtFlyDrawObj->getInnerBound()); | |||
176 | ||||
177 | aInnerBound.grow(-1.0 * nTol); | |||
178 | ||||
179 | if(aInnerBound.isInside(basegfx::B2DPoint(rPnt.X(), rPnt.Y()))) | |||
180 | { | |||
181 | // exclude this hit | |||
182 | pRetval = nullptr; | |||
183 | } | |||
184 | } | |||
185 | } | |||
186 | } | |||
187 | } | |||
188 | ||||
189 | return pRetval; | |||
190 | } | |||
191 | ||||
192 | SdrObject* SwDrawView::CheckSingleSdrObjectHit(const Point& rPnt, sal_uInt16 nTol, SdrObject* pObj, SdrPageView* pPV, SdrSearchOptions nOptions, const SdrLayerIDSet* pMVisLay) const | |||
193 | { | |||
194 | // call parent | |||
195 | SdrObject* pRetval = FmFormView::CheckSingleSdrObjectHit(rPnt, nTol, pObj, pPV, nOptions, pMVisLay); | |||
196 | ||||
197 | if(pRetval) | |||
198 | { | |||
199 | // override to allow extra handling when picking SwVirtFlyDrawObj's | |||
200 | pRetval = impLocalHitCorrection(pRetval, rPnt, nTol, GetMarkedObjectList()); | |||
201 | } | |||
202 | ||||
203 | return pRetval; | |||
204 | } | |||
205 | ||||
206 | /// Gets called every time the handles need to be build | |||
207 | void SwDrawView::AddCustomHdl() | |||
208 | { | |||
209 | const SdrMarkList &rMrkList = GetMarkedObjectList(); | |||
210 | ||||
211 | if(rMrkList.GetMarkCount() != 1 || !GetUserCall(rMrkList.GetMark( 0 )->GetMarkedSdrObj())) | |||
212 | return; | |||
213 | ||||
214 | SdrObject *pObj = rMrkList.GetMark(0)->GetMarkedSdrObj(); | |||
215 | // make code robust | |||
216 | SwFrameFormat* pFrameFormat( ::FindFrameFormat( pObj ) ); | |||
217 | if ( !pFrameFormat ) | |||
218 | { | |||
219 | OSL_FAIL( "<SwDrawView::AddCustomHdl()> - 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/draw/dview.cxx" ":" "219" ": "), "%s", "<SwDrawView::AddCustomHdl()> - missing frame format!" ); } } while (false); | |||
220 | return; | |||
221 | } | |||
222 | const SwFormatAnchor &rAnchor = pFrameFormat->GetAnchor(); | |||
223 | ||||
224 | if (RndStdIds::FLY_AS_CHAR == rAnchor.GetAnchorId()) | |||
225 | return; | |||
226 | ||||
227 | const SwFrame* pAnch = CalcAnchor(); | |||
228 | if(nullptr == pAnch) | |||
229 | return; | |||
230 | ||||
231 | Point aPos(m_aAnchorPoint); | |||
232 | ||||
233 | if ( RndStdIds::FLY_AT_CHAR == rAnchor.GetAnchorId() ) | |||
234 | { | |||
235 | // #i28701# - use last character rectangle saved at object | |||
236 | // in order to avoid a format of the anchor frame | |||
237 | SwAnchoredObject* pAnchoredObj = ::GetUserCall( pObj )->GetAnchoredObj( pObj ); | |||
238 | SwRect aAutoPos = pAnchoredObj->GetLastCharRect(); | |||
239 | if ( aAutoPos.Height() ) | |||
240 | { | |||
241 | aPos = aAutoPos.Pos(); | |||
242 | } | |||
243 | } | |||
244 | ||||
245 | // add anchor handle: | |||
246 | maHdlList.AddHdl( std::make_unique<SwSdrHdl>( aPos, ( pAnch->IsVertical() && !pAnch->IsVertLR() ) || | |||
247 | pAnch->IsRightToLeft() ) ); | |||
248 | } | |||
249 | ||||
250 | SdrObject* SwDrawView::GetMaxToTopObj( SdrObject* pObj ) const | |||
251 | { | |||
252 | if ( GetUserCall(pObj) ) | |||
253 | { | |||
254 | const SwFrame *pAnch = ::lcl_FindAnchor( pObj, false ); | |||
255 | if ( pAnch ) | |||
256 | { | |||
257 | //The topmost Obj within the anchor must not be overtaken. | |||
258 | const SwFlyFrame *pFly = pAnch->FindFlyFrame(); | |||
259 | if ( pFly ) | |||
260 | { | |||
261 | const SwPageFrame *pPage = pFly->FindPageFrame(); | |||
262 | if ( pPage->GetSortedObjs() ) | |||
263 | { | |||
264 | size_t nOrdNum = 0; | |||
265 | for (SwAnchoredObject* i : *pPage->GetSortedObjs()) | |||
266 | { | |||
267 | const SdrObject *pO = i->GetDrawObj(); | |||
268 | ||||
269 | if ( pO->GetOrdNumDirect() > nOrdNum ) | |||
270 | { | |||
271 | const SwFrame *pTmpAnch = ::lcl_FindAnchor( pO, false ); | |||
272 | if ( pFly->IsAnLower( pTmpAnch ) ) | |||
273 | { | |||
274 | nOrdNum = pO->GetOrdNumDirect(); | |||
275 | } | |||
276 | } | |||
277 | } | |||
278 | if ( nOrdNum ) | |||
279 | { | |||
280 | SdrPage *pTmpPage = GetModel()->GetPage( 0 ); | |||
281 | ++nOrdNum; | |||
282 | if ( nOrdNum < pTmpPage->GetObjCount() ) | |||
283 | { | |||
284 | return pTmpPage->GetObj( nOrdNum ); | |||
285 | } | |||
286 | } | |||
287 | } | |||
288 | } | |||
289 | } | |||
290 | } | |||
291 | return nullptr; | |||
292 | } | |||
293 | ||||
294 | SdrObject* SwDrawView::GetMaxToBtmObj(SdrObject* pObj) const | |||
295 | { | |||
296 | if ( GetUserCall(pObj) ) | |||
297 | { | |||
298 | const SwFrame *pAnch = ::lcl_FindAnchor( pObj, false ); | |||
299 | if ( pAnch ) | |||
300 | { | |||
301 | //The Fly of the anchor must not be "flying under". | |||
302 | const SwFlyFrame *pFly = pAnch->FindFlyFrame(); | |||
303 | if ( pFly ) | |||
304 | { | |||
305 | SdrObject *pRet = const_cast<SdrObject*>(static_cast<SdrObject const *>(pFly->GetVirtDrawObj())); | |||
306 | return pRet != pObj ? pRet : nullptr; | |||
307 | } | |||
308 | } | |||
309 | } | |||
310 | return nullptr; | |||
311 | } | |||
312 | ||||
313 | /// determine maximal order number for a 'child' object of given 'parent' object | |||
314 | sal_uInt32 SwDrawView::GetMaxChildOrdNum( const SwFlyFrame& _rParentObj, | |||
315 | const SdrObject* _pExclChildObj ) | |||
316 | { | |||
317 | sal_uInt32 nMaxChildOrdNum = _rParentObj.GetDrawObj()->GetOrdNum(); | |||
318 | ||||
319 | const SdrPage* pDrawPage = _rParentObj.GetDrawObj()->getSdrPageFromSdrObject(); | |||
320 | OSL_ENSURE( pDrawPage,do { if (true && (!(pDrawPage))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/draw/dview.cxx" ":" "321" ": "), "%s", "<SwDrawView::GetMaxChildOrdNum(..) - missing drawing page at parent object - crash!" ); } } while (false) | |||
321 | "<SwDrawView::GetMaxChildOrdNum(..) - missing drawing page at parent object - crash!" )do { if (true && (!(pDrawPage))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/draw/dview.cxx" ":" "321" ": "), "%s", "<SwDrawView::GetMaxChildOrdNum(..) - missing drawing page at parent object - crash!" ); } } while (false); | |||
322 | ||||
323 | const size_t nObjCount = pDrawPage->GetObjCount(); | |||
324 | for ( size_t i = nObjCount-1; i > _rParentObj.GetDrawObj()->GetOrdNum() ; --i ) | |||
325 | { | |||
326 | const SdrObject* pObj = pDrawPage->GetObj( i ); | |||
327 | ||||
328 | // Don't consider 'child' object <_pExclChildObj> | |||
329 | if ( pObj == _pExclChildObj ) | |||
330 | { | |||
331 | continue; | |||
332 | } | |||
333 | ||||
334 | if ( pObj->GetOrdNum() > nMaxChildOrdNum && | |||
335 | _rParentObj.IsAnLower( lcl_FindAnchor( pObj, true ) ) ) | |||
336 | { | |||
337 | nMaxChildOrdNum = pObj->GetOrdNum(); | |||
338 | break; | |||
339 | } | |||
340 | } | |||
341 | ||||
342 | return nMaxChildOrdNum; | |||
343 | } | |||
344 | ||||
345 | /// method to move 'repeated' objects of the given moved object to the according level | |||
346 | void SwDrawView::MoveRepeatedObjs( const SwAnchoredObject& _rMovedAnchoredObj, | |||
347 | const std::vector<SdrObject*>& _rMovedChildObjs ) const | |||
348 | { | |||
349 | // determine 'repeated' objects of already moved object <_rMovedAnchoredObj> | |||
350 | std::vector<SwAnchoredObject*> aAnchoredObjs; | |||
351 | { | |||
352 | const SwContact* pContact = ::GetUserCall( _rMovedAnchoredObj.GetDrawObj() ); | |||
353 | assert(pContact && "SwDrawView::MoveRepeatedObjs(..) - missing contact object -> crash.")(static_cast <bool> (pContact && "SwDrawView::MoveRepeatedObjs(..) - missing contact object -> crash." ) ? void (0) : __assert_fail ("pContact && \"SwDrawView::MoveRepeatedObjs(..) - missing contact object -> crash.\"" , "/home/maarten/src/libreoffice/core/sw/source/core/draw/dview.cxx" , 353, __extension__ __PRETTY_FUNCTION__)); | |||
354 | pContact->GetAnchoredObjs( aAnchoredObjs ); | |||
355 | } | |||
356 | ||||
357 | // check, if 'repeated' objects exists. | |||
358 | if ( aAnchoredObjs.size() <= 1 ) | |||
359 | return; | |||
360 | ||||
361 | SdrPage* pDrawPage = GetModel()->GetPage( 0 ); | |||
362 | ||||
363 | // move 'repeated' ones to the same order number as the already moved one. | |||
364 | const size_t nNewPos = _rMovedAnchoredObj.GetDrawObj()->GetOrdNum(); | |||
365 | while ( !aAnchoredObjs.empty() ) | |||
366 | { | |||
367 | SwAnchoredObject* pAnchoredObj = aAnchoredObjs.back(); | |||
368 | if ( pAnchoredObj != &_rMovedAnchoredObj ) | |||
369 | { | |||
370 | pDrawPage->SetObjectOrdNum( pAnchoredObj->GetDrawObj()->GetOrdNum(), | |||
371 | nNewPos ); | |||
372 | pDrawPage->RecalcObjOrdNums(); | |||
373 | // adjustments for accessibility API | |||
374 | if ( dynamic_cast< const SwFlyFrame *>( pAnchoredObj ) != nullptr ) | |||
375 | { | |||
376 | const SwFlyFrame *pTmpFlyFrame = static_cast<SwFlyFrame*>(pAnchoredObj); | |||
377 | m_rImp.DisposeAccessibleFrame( pTmpFlyFrame ); | |||
378 | m_rImp.AddAccessibleFrame( pTmpFlyFrame ); | |||
379 | } | |||
380 | else | |||
381 | { | |||
382 | m_rImp.DisposeAccessibleObj(pAnchoredObj->GetDrawObj(), true); | |||
383 | m_rImp.AddAccessibleObj( pAnchoredObj->GetDrawObj() ); | |||
384 | } | |||
385 | } | |||
386 | aAnchoredObjs.pop_back(); | |||
387 | } | |||
388 | ||||
389 | // move 'repeated' ones of 'child' objects | |||
390 | for ( SdrObject* pChildObj : _rMovedChildObjs ) | |||
391 | { | |||
392 | { | |||
393 | const SwContact* pContact = ::GetUserCall( pChildObj ); | |||
394 | assert(pContact && "SwDrawView::MoveRepeatedObjs(..) - missing contact object -> crash.")(static_cast <bool> (pContact && "SwDrawView::MoveRepeatedObjs(..) - missing contact object -> crash." ) ? void (0) : __assert_fail ("pContact && \"SwDrawView::MoveRepeatedObjs(..) - missing contact object -> crash.\"" , "/home/maarten/src/libreoffice/core/sw/source/core/draw/dview.cxx" , 394, __extension__ __PRETTY_FUNCTION__)); | |||
395 | pContact->GetAnchoredObjs( aAnchoredObjs ); | |||
396 | } | |||
397 | // move 'repeated' ones to the same order number as the already moved one. | |||
398 | const size_t nTmpNewPos = pChildObj->GetOrdNum(); | |||
399 | while ( !aAnchoredObjs.empty() ) | |||
400 | { | |||
401 | SwAnchoredObject* pAnchoredObj = aAnchoredObjs.back(); | |||
402 | if ( pAnchoredObj->GetDrawObj() != pChildObj ) | |||
403 | { | |||
404 | pDrawPage->SetObjectOrdNum( pAnchoredObj->GetDrawObj()->GetOrdNum(), | |||
405 | nTmpNewPos ); | |||
406 | pDrawPage->RecalcObjOrdNums(); | |||
407 | // adjustments for accessibility API | |||
408 | if ( dynamic_cast< const SwFlyFrame *>( pAnchoredObj ) != nullptr ) | |||
409 | { | |||
410 | const SwFlyFrame *pTmpFlyFrame = static_cast<SwFlyFrame*>(pAnchoredObj); | |||
411 | m_rImp.DisposeAccessibleFrame( pTmpFlyFrame ); | |||
412 | m_rImp.AddAccessibleFrame( pTmpFlyFrame ); | |||
413 | } | |||
414 | else | |||
415 | { | |||
416 | m_rImp.DisposeAccessibleObj(pAnchoredObj->GetDrawObj(), true); | |||
417 | m_rImp.AddAccessibleObj( pAnchoredObj->GetDrawObj() ); | |||
418 | } | |||
419 | } | |||
420 | aAnchoredObjs.pop_back(); | |||
421 | } | |||
422 | } | |||
423 | } | |||
424 | ||||
425 | // --> adjustment and re-factoring of method | |||
426 | void SwDrawView::ObjOrderChanged( SdrObject* pObj, size_t nOldPos, | |||
427 | size_t nNewPos ) | |||
428 | { | |||
429 | // nothing to do for group members | |||
430 | if ( pObj->getParentSdrObjectFromSdrObject() ) | |||
431 | { | |||
432 | return; | |||
433 | } | |||
434 | ||||
435 | // determine drawing page and assure that the order numbers are correct. | |||
436 | SdrPage* pDrawPage = GetModel()->GetPage( 0 ); | |||
437 | if ( pDrawPage->IsObjOrdNumsDirty() ) | |||
438 | pDrawPage->RecalcObjOrdNums(); | |||
439 | const size_t nObjCount = pDrawPage->GetObjCount(); | |||
440 | ||||
441 | SwAnchoredObject* pMovedAnchoredObj = | |||
442 | ::GetUserCall( pObj )->GetAnchoredObj( pObj ); | |||
443 | const SwFlyFrame* pParentAnchoredObj = | |||
444 | pMovedAnchoredObj->GetAnchorFrame()->FindFlyFrame(); | |||
445 | ||||
446 | const bool bMovedForward = nOldPos < nNewPos; | |||
447 | ||||
448 | // assure for a 'child' object, that it doesn't exceed the limits of its 'parent' | |||
449 | if ( pParentAnchoredObj ) | |||
450 | { | |||
451 | if ( bMovedForward ) | |||
452 | { | |||
453 | const size_t nMaxChildOrdNumWithoutMoved = | |||
454 | GetMaxChildOrdNum( *pParentAnchoredObj, pMovedAnchoredObj->GetDrawObj() ); | |||
455 | if ( nNewPos > nMaxChildOrdNumWithoutMoved+1 ) | |||
456 | { | |||
457 | // set position to the top of the 'child' object group | |||
458 | pDrawPage->SetObjectOrdNum( nNewPos, nMaxChildOrdNumWithoutMoved+1 ); | |||
459 | nNewPos = nMaxChildOrdNumWithoutMoved+1; | |||
460 | } | |||
461 | } | |||
462 | else | |||
463 | { | |||
464 | const size_t nParentOrdNum = pParentAnchoredObj->GetDrawObj()->GetOrdNum(); | |||
465 | if ( nNewPos < nParentOrdNum ) | |||
466 | { | |||
467 | // set position to the bottom of the 'child' object group | |||
468 | pDrawPage->SetObjectOrdNum( nNewPos, nParentOrdNum ); | |||
469 | nNewPos = nParentOrdNum; | |||
470 | } | |||
471 | } | |||
472 | if ( pDrawPage->IsObjOrdNumsDirty() ) | |||
473 | pDrawPage->RecalcObjOrdNums(); | |||
474 | } | |||
475 | ||||
476 | // Assure, that object isn't positioned between 'repeated' ones | |||
477 | if ( ( bMovedForward && nNewPos < nObjCount - 1 ) || | |||
478 | ( !bMovedForward && nNewPos > 0 ) ) | |||
479 | { | |||
480 | const SdrObject* pTmpObj = | |||
481 | pDrawPage->GetObj( bMovedForward ? nNewPos - 1 : nNewPos + 1 ); | |||
482 | if ( pTmpObj ) | |||
483 | { | |||
484 | size_t nTmpNewPos( nNewPos ); | |||
485 | if ( bMovedForward ) | |||
486 | { | |||
487 | // move before the top 'repeated' object | |||
488 | const sal_uInt32 nTmpMaxOrdNum = | |||
489 | ::GetUserCall( pTmpObj )->GetMaxOrdNum(); | |||
490 | if ( nTmpMaxOrdNum > nNewPos ) | |||
491 | nTmpNewPos = nTmpMaxOrdNum; | |||
492 | } | |||
493 | else | |||
494 | { | |||
495 | // move behind the bottom 'repeated' object | |||
496 | const sal_uInt32 nTmpMinOrdNum = | |||
497 | ::GetUserCall( pTmpObj )->GetMinOrdNum(); | |||
498 | if ( nTmpMinOrdNum < nNewPos ) | |||
499 | nTmpNewPos = nTmpMinOrdNum; | |||
500 | } | |||
501 | if ( nTmpNewPos != nNewPos ) | |||
502 | { | |||
503 | pDrawPage->SetObjectOrdNum( nNewPos, nTmpNewPos ); | |||
504 | nNewPos = nTmpNewPos; | |||
505 | pDrawPage->RecalcObjOrdNums(); | |||
506 | } | |||
507 | } | |||
508 | } | |||
509 | ||||
510 | // On move forward, assure that object is moved before its own children. | |||
511 | // Only Writer fly frames can have children. | |||
512 | if ( dynamic_cast< const SwFlyFrame *>( pMovedAnchoredObj ) != nullptr && | |||
513 | bMovedForward && nNewPos < nObjCount - 1 ) | |||
514 | { | |||
515 | sal_uInt32 nMaxChildOrdNum = | |||
516 | GetMaxChildOrdNum( *static_cast<const SwFlyFrame*>(pMovedAnchoredObj) ); | |||
517 | if ( nNewPos < nMaxChildOrdNum ) | |||
518 | { | |||
519 | // determine position before the object before its top 'child' object | |||
520 | const SdrObject* pTmpObj = pDrawPage->GetObj( nMaxChildOrdNum ); | |||
521 | size_t nTmpNewPos = ::GetUserCall( pTmpObj )->GetMaxOrdNum() + 1; | |||
522 | if ( nTmpNewPos >= nObjCount ) | |||
523 | { | |||
524 | --nTmpNewPos; | |||
525 | } | |||
526 | // assure, that determined position isn't between 'repeated' objects | |||
527 | pTmpObj = pDrawPage->GetObj( nTmpNewPos ); | |||
528 | nTmpNewPos = ::GetUserCall( pTmpObj )->GetMaxOrdNum(); | |||
529 | // apply new position | |||
530 | pDrawPage->SetObjectOrdNum( nNewPos, nTmpNewPos ); | |||
531 | nNewPos = nTmpNewPos; | |||
532 | pDrawPage->RecalcObjOrdNums(); | |||
533 | } | |||
534 | } | |||
535 | ||||
536 | // Assure, that object isn't positioned between nested objects | |||
537 | if ( ( bMovedForward && nNewPos < nObjCount - 1 ) || | |||
538 | ( !bMovedForward && nNewPos > 0 ) ) | |||
539 | { | |||
540 | size_t nTmpNewPos( nNewPos ); | |||
541 | const SwFrameFormat* pParentFrameFormat = | |||
542 | pParentAnchoredObj ? &(pParentAnchoredObj->GetFrameFormat()) : nullptr; | |||
543 | const SdrObject* pTmpObj = pDrawPage->GetObj( nNewPos + 1 ); | |||
544 | while ( pTmpObj ) | |||
545 | { | |||
546 | // #i38563# - assure, that anchor frame exists. | |||
547 | // If object is anchored inside an invisible part of the document | |||
548 | // (e.g. page header, whose page style isn't applied, or hidden | |||
549 | // section), no anchor frame exists. | |||
550 | const SwFrame* pTmpAnchorFrame = lcl_FindAnchor( pTmpObj, true ); | |||
551 | const SwFlyFrame* pTmpParentObj = pTmpAnchorFrame | |||
552 | ? pTmpAnchorFrame->FindFlyFrame() : nullptr; | |||
553 | if ( pTmpParentObj && | |||
554 | &(pTmpParentObj->GetFrameFormat()) != pParentFrameFormat ) | |||
555 | { | |||
556 | if ( bMovedForward ) | |||
557 | { | |||
558 | nTmpNewPos = ::GetUserCall( pTmpObj )->GetMaxOrdNum(); | |||
559 | pTmpObj = pDrawPage->GetObj( nTmpNewPos + 1 ); | |||
560 | } | |||
561 | else | |||
562 | { | |||
563 | nTmpNewPos = ::GetUserCall( pTmpParentObj->GetDrawObj() ) | |||
564 | ->GetMinOrdNum(); | |||
565 | pTmpObj = pTmpParentObj->GetDrawObj(); | |||
566 | } | |||
567 | } | |||
568 | else | |||
569 | break; | |||
570 | } | |||
571 | if ( nTmpNewPos != nNewPos ) | |||
572 | { | |||
573 | pDrawPage->SetObjectOrdNum( nNewPos, nTmpNewPos ); | |||
574 | nNewPos = nTmpNewPos; | |||
575 | pDrawPage->RecalcObjOrdNums(); | |||
576 | } | |||
577 | } | |||
578 | ||||
579 | // setup collection of moved 'child' objects to move its 'repeated' objects. | |||
580 | std::vector< SdrObject* > aMovedChildObjs; | |||
581 | ||||
582 | // move 'children' accordingly | |||
583 | if ( dynamic_cast< const SwFlyFrame *>( pMovedAnchoredObj ) != nullptr ) | |||
584 | { | |||
585 | const SwFlyFrame* pFlyFrame = static_cast<SwFlyFrame*>(pMovedAnchoredObj); | |||
586 | ||||
587 | // adjustments for accessibility API | |||
588 | m_rImp.DisposeAccessibleFrame( pFlyFrame ); | |||
589 | m_rImp.AddAccessibleFrame( pFlyFrame ); | |||
590 | ||||
591 | const sal_uInt32 nChildNewPos = bMovedForward ? nNewPos : nNewPos+1; | |||
592 | size_t i = bMovedForward ? nOldPos : nObjCount-1; | |||
593 | do | |||
594 | { | |||
595 | SdrObject* pTmpObj = pDrawPage->GetObj( i ); | |||
596 | if ( pTmpObj == pObj ) | |||
597 | break; | |||
598 | ||||
599 | // #i38563# - assure, that anchor frame exists. | |||
600 | // If object is anchored inside an invisible part of the document | |||
601 | // (e.g. page header, whose page style isn't applied, or hidden | |||
602 | // section), no anchor frame exists. | |||
603 | const SwFrame* pTmpAnchorFrame = lcl_FindAnchor( pTmpObj, true ); | |||
604 | const SwFlyFrame* pTmpParentObj = pTmpAnchorFrame | |||
605 | ? pTmpAnchorFrame->FindFlyFrame() : nullptr; | |||
606 | if ( pTmpParentObj && | |||
607 | ( ( pTmpParentObj == pFlyFrame ) || | |||
608 | ( pFlyFrame->IsUpperOf( *pTmpParentObj ) ) ) ) | |||
609 | { | |||
610 | // move child object., | |||
611 | pDrawPage->SetObjectOrdNum( i, nChildNewPos ); | |||
612 | pDrawPage->RecalcObjOrdNums(); | |||
613 | // collect 'child' object | |||
614 | aMovedChildObjs.push_back( pTmpObj ); | |||
615 | // adjustments for accessibility API | |||
616 | if ( dynamic_cast< const SwVirtFlyDrawObj *>( pTmpObj ) != nullptr ) | |||
617 | { | |||
618 | const SwFlyFrame *pTmpFlyFrame = | |||
619 | static_cast<SwVirtFlyDrawObj*>(pTmpObj)->GetFlyFrame(); | |||
620 | m_rImp.DisposeAccessibleFrame( pTmpFlyFrame ); | |||
621 | m_rImp.AddAccessibleFrame( pTmpFlyFrame ); | |||
622 | } | |||
623 | else | |||
624 | { | |||
625 | m_rImp.DisposeAccessibleObj(pTmpObj, true); | |||
626 | m_rImp.AddAccessibleObj( pTmpObj ); | |||
627 | } | |||
628 | } | |||
629 | else | |||
630 | { | |||
631 | // adjust loop counter | |||
632 | if ( bMovedForward ) | |||
633 | ++i; | |||
634 | else if (i > 0) | |||
635 | --i; | |||
636 | } | |||
637 | ||||
638 | } while ( ( bMovedForward && i < ( nObjCount - aMovedChildObjs.size() ) ) || | |||
639 | ( !bMovedForward && i > ( nNewPos + aMovedChildObjs.size() ) ) ); | |||
640 | } | |||
641 | else | |||
642 | { | |||
643 | // adjustments for accessibility API | |||
644 | m_rImp.DisposeAccessibleObj(pObj, true); | |||
645 | m_rImp.AddAccessibleObj( pObj ); | |||
646 | } | |||
647 | ||||
648 | MoveRepeatedObjs( *pMovedAnchoredObj, aMovedChildObjs ); | |||
649 | } | |||
650 | ||||
651 | bool SwDrawView::TakeDragLimit( SdrDragMode eMode, | |||
652 | tools::Rectangle& rRect ) const | |||
653 | { | |||
654 | const SdrMarkList &rMrkList = GetMarkedObjectList(); | |||
655 | bool bRet = false; | |||
656 | if( 1 == rMrkList.GetMarkCount() ) | |||
657 | { | |||
658 | const SdrObject *pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj(); | |||
659 | SwRect aRect; | |||
660 | if( ::CalcClipRect( pObj, aRect, eMode == SdrDragMode::Move ) ) | |||
661 | { | |||
662 | rRect = aRect.SVRect(); | |||
663 | bRet = true; | |||
664 | } | |||
665 | } | |||
666 | return bRet; | |||
667 | } | |||
668 | ||||
669 | const SwFrame* SwDrawView::CalcAnchor() | |||
670 | { | |||
671 | const SdrMarkList &rMrkList = GetMarkedObjectList(); | |||
672 | if ( rMrkList.GetMarkCount() != 1 ) | |||
673 | return nullptr; | |||
674 | ||||
675 | SdrObject* pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj(); | |||
676 | ||||
677 | //Search for paragraph bound objects, otherwise only the | |||
678 | //current anchor. Search only if we currently drag. | |||
679 | const SwFrame* pAnch; | |||
680 | tools::Rectangle aMyRect; | |||
681 | const bool bFly = dynamic_cast< const SwVirtFlyDrawObj *>( pObj ) != nullptr; | |||
682 | if ( bFly
| |||
683 | { | |||
684 | pAnch = static_cast<SwVirtFlyDrawObj*>(pObj)->GetFlyFrame()->GetAnchorFrame(); | |||
685 | aMyRect = static_cast<SwVirtFlyDrawObj*>(pObj)->GetFlyFrame()->getFrameArea().SVRect(); | |||
686 | } | |||
687 | else | |||
688 | { | |||
689 | SwDrawContact *pC = static_cast<SwDrawContact*>(GetUserCall(pObj)); | |||
690 | // determine correct anchor position for 'virtual' drawing objects. | |||
691 | // #i26791# | |||
692 | pAnch = pC->GetAnchorFrame( pObj ); | |||
693 | if( !pAnch ) | |||
694 | { | |||
695 | pC->ConnectToLayout(); | |||
696 | // determine correct anchor position for 'virtual' drawing objects. | |||
697 | // #i26791# | |||
698 | pAnch = pC->GetAnchorFrame( pObj ); | |||
699 | } | |||
700 | aMyRect = pObj->GetSnapRect(); | |||
| ||||
701 | } | |||
702 | ||||
703 | const bool bTopRight = pAnch && ( ( pAnch->IsVertical() && | |||
704 | !pAnch->IsVertLR() ) || | |||
705 | pAnch->IsRightToLeft() ); | |||
706 | const Point aMyPt = bTopRight ? aMyRect.TopRight() : aMyRect.TopLeft(); | |||
707 | ||||
708 | Point aPt; | |||
709 | if ( IsAction() ) | |||
710 | { | |||
711 | if ( !TakeDragObjAnchorPos( aPt, bTopRight ) ) | |||
712 | return nullptr; | |||
713 | } | |||
714 | else | |||
715 | { | |||
716 | tools::Rectangle aRect = pObj->GetSnapRect(); | |||
717 | aPt = bTopRight ? aRect.TopRight() : aRect.TopLeft(); | |||
718 | } | |||
719 | ||||
720 | if ( aPt != aMyPt ) | |||
721 | { | |||
722 | if ( pAnch && pAnch->IsContentFrame() ) | |||
723 | { | |||
724 | // allow drawing objects in header/footer, | |||
725 | // but exclude control objects. | |||
726 | bool bBodyOnly = CheckControlLayer( pObj ); | |||
727 | pAnch = ::FindAnchor( static_cast<const SwContentFrame*>(pAnch), aPt, bBodyOnly ); | |||
728 | } | |||
729 | else if ( !bFly ) | |||
730 | { | |||
731 | const SwRect aRect( aPt.getX(), aPt.getY(), 1, 1 ); | |||
732 | ||||
733 | SwDrawContact* pContact = static_cast<SwDrawContact*>(GetUserCall(pObj)); | |||
734 | if ( pContact->GetAnchorFrame( pObj ) && | |||
735 | pContact->GetAnchorFrame( pObj )->IsPageFrame() ) | |||
736 | pAnch = pContact->GetPageFrame(); | |||
737 | else | |||
738 | pAnch = pContact->FindPage( aRect ); | |||
739 | } | |||
740 | } | |||
741 | if( pAnch && !pAnch->IsProtected() ) | |||
742 | m_aAnchorPoint = pAnch->GetFrameAnchorPos( ::HasWrap( pObj ) ); | |||
743 | else | |||
744 | pAnch = nullptr; | |||
745 | return pAnch; | |||
746 | } | |||
747 | ||||
748 | void SwDrawView::ShowDragAnchor() | |||
749 | { | |||
750 | SdrHdl* pHdl = maHdlList.GetHdl(SdrHdlKind::Anchor); | |||
751 | if ( ! pHdl ) | |||
| ||||
752 | pHdl = maHdlList.GetHdl(SdrHdlKind::Anchor_TR); | |||
753 | ||||
754 | if(pHdl
| |||
755 | { | |||
756 | CalcAnchor(); | |||
757 | pHdl->SetPos(m_aAnchorPoint); | |||
758 | } | |||
759 | } | |||
760 | ||||
761 | void SwDrawView::MarkListHasChanged() | |||
762 | { | |||
763 | Imp().GetShell()->DrawSelChanged(); | |||
764 | FmFormView::MarkListHasChanged(); | |||
765 | } | |||
766 | ||||
767 | // #i7672# | |||
768 | void SwDrawView::ModelHasChanged() | |||
769 | { | |||
770 | // The ModelHasChanged() call in DrawingLayer also updates | |||
771 | // an eventually active text edit view (OutlinerView). This also leads | |||
772 | // to newly setting the background color for that edit view. Thus, | |||
773 | // this method rescues the current background color if an OutlinerView | |||
774 | // exists and re-establishes it then. To be more safe, the OutlinerView | |||
775 | // will be fetched again (maybe textedit has ended). | |||
776 | OutlinerView* pView = GetTextEditOutlinerView(); | |||
777 | Color aBackColor; | |||
778 | bool bColorWasSaved(false); | |||
779 | ||||
780 | if(pView) | |||
781 | { | |||
782 | aBackColor = pView->GetBackgroundColor(); | |||
783 | bColorWasSaved = true; | |||
784 | } | |||
785 | ||||
786 | // call parent | |||
787 | FmFormView::ModelHasChanged(); | |||
788 | ||||
789 | if(bColorWasSaved) | |||
790 | { | |||
791 | pView = GetTextEditOutlinerView(); | |||
792 | ||||
793 | if(pView) | |||
794 | { | |||
795 | pView->SetBackgroundColor(aBackColor); | |||
796 | } | |||
797 | } | |||
798 | } | |||
799 | ||||
800 | void SwDrawView::MakeVisible( const tools::Rectangle &rRect, vcl::Window & ) | |||
801 | { | |||
802 | OSL_ENSURE( m_rImp.GetShell()->GetWin(), "MakeVisible, unknown Window")do { if (true && (!(m_rImp.GetShell()->GetWin()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/sw/source/core/draw/dview.cxx" ":" "802" ": "), "%s", "MakeVisible, unknown Window"); } } while (false); | |||
803 | m_rImp.GetShell()->MakeVisible( SwRect( rRect ) ); | |||
804 | } | |||
805 | ||||
806 | void SwDrawView::CheckPossibilities() | |||
807 | { | |||
808 | FmFormView::CheckPossibilities(); | |||
809 | ||||
810 | //In addition to the existing flags of the objects themselves, | |||
811 | //which are evaluated by the DrawingEngine, other circumstances | |||
812 | //lead to a protection. | |||
813 | //Objects that are anchored in frames need to be protected | |||
814 | //if the content of the frame is protected. | |||
815 | //OLE-Objects may themselves wish a resize protection (StarMath) | |||
816 | ||||
817 | const SdrMarkList &rMrkList = GetMarkedObjectList(); | |||
818 | bool bProtect = false; | |||
819 | bool bSzProtect = false; | |||
820 | bool bRotate(false); | |||
821 | ||||
822 | for ( size_t i = 0; !bProtect && i < rMrkList.GetMarkCount(); ++i ) | |||
823 | { | |||
824 | const SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj(); | |||
825 | const SwFrame *pFrame = nullptr; | |||
826 | if ( auto pVirtFlyDrawObj = dynamic_cast< const SwVirtFlyDrawObj *>( pObj ) ) | |||
827 | { | |||
828 | const SwFlyFrame *pFly = pVirtFlyDrawObj->GetFlyFrame(); | |||
829 | if ( pFly ) | |||
830 | { | |||
831 | pFrame = pFly->GetAnchorFrame(); | |||
832 | if ( pFly->Lower() && pFly->Lower()->IsNoTextFrame() ) | |||
833 | { | |||
834 | const SwNoTextFrame *const pNTF(static_cast<const SwNoTextFrame*>(pFly->Lower())); | |||
835 | const SwOLENode *const pOLENd = pNTF->GetNode()->GetOLENode(); | |||
836 | const SwGrfNode *const pGrfNd = pNTF->GetNode()->GetGrfNode(); | |||
837 | ||||
838 | if ( pOLENd ) | |||
839 | { | |||
840 | const uno::Reference < embed::XEmbeddedObject > xObj = const_cast< SwOLEObj& >(pOLENd->GetOLEObj()).GetOleRef(); | |||
841 | ||||
842 | if ( xObj.is() ) | |||
843 | { | |||
844 | // --> improvement for the future, when more | |||
845 | // than one Writer fly frame can be selected. | |||
846 | ||||
847 | // TODO/LATER: retrieve Aspect - from where?! | |||
848 | bSzProtect |= ( embed::EmbedMisc::EMBED_NEVERRESIZE & xObj->getStatus( embed::Aspects::MSOLE_CONTENT ) ) != 0; | |||
849 | ||||
850 | // #i972: protect position if it is a Math object anchored 'as char' and baseline alignment is activated | |||
851 | SwDoc* pDoc = Imp().GetShell()->GetDoc(); | |||
852 | const bool bProtectMathPos = SotExchange::IsMath( xObj->getClassID() ) | |||
853 | && RndStdIds::FLY_AS_CHAR == pFly->GetFormat()->GetAnchor().GetAnchorId() | |||
854 | && pDoc->GetDocumentSettingManager().get( DocumentSettingId::MATH_BASELINE_ALIGNMENT ); | |||
855 | if (bProtectMathPos) | |||
856 | m_bMoveProtect = true; | |||
857 | } | |||
858 | } | |||
859 | else if(pGrfNd) | |||
860 | { | |||
861 | // RotGrfFlyFrame: GraphicNode allows rotation(s). The loop ew are in stops | |||
862 | // as soon as bMoveProtect is set, but since rotation is valid only with | |||
863 | // a single object selected this makes no difference | |||
864 | bRotate = true; | |||
865 | } | |||
866 | } | |||
867 | } | |||
868 | } | |||
869 | else | |||
870 | { | |||
871 | SwDrawContact *pC = static_cast<SwDrawContact*>(GetUserCall(pObj)); | |||
872 | if ( pC ) | |||
873 | pFrame = pC->GetAnchorFrame( pObj ); | |||
874 | } | |||
875 | if ( pFrame ) | |||
876 | bProtect = pFrame->IsProtected(); //Frames, areas etc. | |||
877 | { | |||
878 | SwFrameFormat* pFrameFormat( ::FindFrameFormat( const_cast<SdrObject*>(pObj) ) ); | |||
879 | if ( !pFrameFormat ) | |||
880 | { | |||
881 | OSL_FAIL( "<SwDrawView::CheckPossibilities()> - 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/draw/dview.cxx" ":" "881" ": "), "%s", "<SwDrawView::CheckPossibilities()> - missing frame format" ); } } while (false); | |||
882 | bProtect = true; | |||
883 | } | |||
884 | else if ((RndStdIds::FLY_AS_CHAR == pFrameFormat->GetAnchor().GetAnchorId()) && | |||
885 | rMrkList.GetMarkCount() > 1 ) | |||
886 | { | |||
887 | bProtect = true; | |||
888 | } | |||
889 | } | |||
890 | } | |||
891 | m_bMoveProtect |= bProtect; | |||
892 | m_bResizeProtect |= bProtect || bSzProtect; | |||
893 | ||||
894 | // RotGrfFlyFrame: allow rotation when SwGrfNode is selected and not size protected | |||
895 | m_bRotateFreeAllowed |= bRotate && !bProtect; | |||
896 | m_bRotate90Allowed |= m_bRotateFreeAllowed; | |||
897 | } | |||
898 | ||||
899 | /// replace marked <SwDrawVirtObj>-objects by its reference object for delete marked objects. | |||
900 | void SwDrawView::ReplaceMarkedDrawVirtObjs( SdrMarkView& _rMarkView ) | |||
901 | { | |||
902 | SdrPageView* pDrawPageView = _rMarkView.GetSdrPageView(); | |||
903 | const SdrMarkList& rMarkList = _rMarkView.GetMarkedObjectList(); | |||
904 | ||||
905 | if( !rMarkList.GetMarkCount() ) | |||
906 | return; | |||
907 | ||||
908 | // collect marked objects in a local data structure | |||
909 | std::vector<SdrObject*> aMarkedObjs; | |||
910 | for( size_t i = 0; i < rMarkList.GetMarkCount(); ++i ) | |||
911 | { | |||
912 | SdrObject* pMarkedObj = rMarkList.GetMark( i )->GetMarkedSdrObj(); | |||
913 | aMarkedObjs.push_back( pMarkedObj ); | |||
914 | } | |||
915 | // unmark all objects | |||
916 | _rMarkView.UnmarkAllObj(); | |||
917 | // re-mark objects, but for marked <SwDrawVirtObj>-objects marked its | |||
918 | // reference object. | |||
919 | while ( !aMarkedObjs.empty() ) | |||
920 | { | |||
921 | SdrObject* pMarkObj = aMarkedObjs.back(); | |||
922 | if ( dynamic_cast< const SwDrawVirtObj *>( pMarkObj ) != nullptr ) | |||
923 | { | |||
924 | SdrObject* pRefObj = &(static_cast<SwDrawVirtObj*>(pMarkObj)->ReferencedObj()); | |||
925 | if ( !_rMarkView.IsObjMarked( pRefObj ) ) | |||
926 | { | |||
927 | _rMarkView.MarkObj( pRefObj, pDrawPageView ); | |||
928 | } | |||
929 | } | |||
930 | else | |||
931 | { | |||
932 | _rMarkView.MarkObj( pMarkObj, pDrawPageView ); | |||
933 | } | |||
934 | ||||
935 | aMarkedObjs.pop_back(); | |||
936 | } | |||
937 | // sort marked list in order to assure consistent state in drawing layer | |||
938 | _rMarkView.SortMarkedObjects(); | |||
939 | } | |||
940 | ||||
941 | SfxViewShell* SwDrawView::GetSfxViewShell() const | |||
942 | { | |||
943 | return m_rImp.GetShell()->GetSfxViewShell(); | |||
944 | } | |||
945 | ||||
946 | void SwDrawView::DeleteMarked() | |||
947 | { | |||
948 | SwDoc* pDoc = Imp().GetShell()->GetDoc(); | |||
949 | SwRootFrame *pTmpRoot = pDoc->getIDocumentLayoutAccess().GetCurrentLayout(); | |||
950 | if ( pTmpRoot ) | |||
951 | pTmpRoot->StartAllAction(); | |||
952 | pDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::EMPTY, nullptr); | |||
953 | // replace marked <SwDrawVirtObj>-objects by its reference objects. | |||
954 | if (SdrPageView* pDrawPageView = m_rImp.GetPageView()) | |||
955 | { | |||
956 | ReplaceMarkedDrawVirtObjs(pDrawPageView->GetView()); | |||
957 | } | |||
958 | ||||
959 | // Check what textboxes have to be deleted afterwards. | |||
960 | const SdrMarkList& rMarkList = GetMarkedObjectList(); | |||
961 | std::vector<SwFrameFormat*> aTextBoxesToDelete; | |||
962 | for (size_t i = 0; i < rMarkList.GetMarkCount(); ++i) | |||
963 | { | |||
964 | SdrObject *pObject = rMarkList.GetMark(i)->GetMarkedSdrObj(); | |||
965 | SwContact* pContact = GetUserCall(pObject); | |||
966 | SwFrameFormat* pFormat = pContact->GetFormat(); | |||
967 | if (SwFrameFormat* pTextBox = SwTextBoxHelper::getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT)) | |||
968 | aTextBoxesToDelete.push_back(pTextBox); | |||
969 | } | |||
970 | ||||
971 | if ( pDoc->DeleteSelection( *this ) ) | |||
972 | { | |||
973 | FmFormView::DeleteMarked(); | |||
974 | ::FrameNotify( Imp().GetShell(), FLY_DRAG_END ); | |||
975 | } | |||
976 | ||||
977 | // Only delete these now: earlier deletion would clear the mark list as well. | |||
978 | // Delete in reverse order, assuming that the container is sorted by anchor positions. | |||
979 | for (int i = aTextBoxesToDelete.size() - 1; i >= 0; --i) | |||
980 | { | |||
981 | SwFrameFormat*& rpTextBox = aTextBoxesToDelete[i]; | |||
982 | pDoc->getIDocumentLayoutAccess().DelLayoutFormat(rpTextBox); | |||
983 | } | |||
984 | ||||
985 | pDoc->GetIDocumentUndoRedo().EndUndo(SwUndoId::EMPTY, nullptr); | |||
986 | if( pTmpRoot ) | |||
987 | pTmpRoot->EndAllAction(); | |||
988 | } | |||
989 | ||||
990 | // support enhanced text edit for draw objects | |||
991 | SdrUndoManager* SwDrawView::getSdrUndoManagerForEnhancedTextEdit() const | |||
992 | { | |||
993 | SwDoc* pDoc = Imp().GetShell()->GetDoc(); | |||
994 | ||||
995 | return pDoc ? dynamic_cast< SdrUndoManager* >(&(pDoc->GetUndoManager())) : nullptr; | |||
996 | } | |||
997 | ||||
998 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |