Line data Source code
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 <editeng/protitem.hxx>
22 : #include <editeng/opaqitem.hxx>
23 : #include <editeng/ulspitem.hxx>
24 : #include <editeng/lrspitem.hxx>
25 : #include <svx/svdpage.hxx>
26 : #include <svx/svditer.hxx>
27 : #include <svx/fmglob.hxx>
28 : #include <svx/svdogrp.hxx>
29 : #include <svx/svdotext.hxx>
30 : #include <svx/svdmodel.hxx>
31 : #include <svx/svdpagv.hxx>
32 : #include <svx/svdviter.hxx>
33 : #include <svx/svdview.hxx>
34 : #include <svx/shapepropertynotifier.hxx>
35 : #include <svx/sdr/contact/objectcontactofobjlistpainter.hxx>
36 : #include <svx/sdr/contact/displayinfo.hxx>
37 : #include <drawdoc.hxx>
38 : #include <fmtornt.hxx>
39 : #include <viewimp.hxx>
40 : #include <fmtsrnd.hxx>
41 : #include <fmtanchr.hxx>
42 : #include <node.hxx>
43 : #include <fmtcntnt.hxx>
44 : #include <fmtfsize.hxx>
45 : #include <pagefrm.hxx>
46 : #include <rootfrm.hxx>
47 : #include <frmtool.hxx>
48 : #include <flyfrm.hxx>
49 : #include <textboxhelper.hxx>
50 : #include <frmfmt.hxx>
51 : #include <dflyobj.hxx>
52 : #include <dcontact.hxx>
53 : #include <unodraw.hxx>
54 : #include <IDocumentDrawModelAccess.hxx>
55 : #include <IDocumentLayoutAccess.hxx>
56 : #include <doc.hxx>
57 : #include <hints.hxx>
58 : #include <txtfrm.hxx>
59 : #include <editsh.hxx>
60 : #include <docary.hxx>
61 : #include <flyfrms.hxx>
62 : #include <sortedobjs.hxx>
63 : #include <basegfx/matrix/b2dhommatrix.hxx>
64 : #include <basegfx/matrix/b2dhommatrixtools.hxx>
65 : #include <svx/sdr/contact/viewcontactofvirtobj.hxx>
66 : #include <drawinglayer/primitive2d/transformprimitive2d.hxx>
67 : #include <svx/sdr/contact/viewobjectcontactofsdrobj.hxx>
68 : #include <com/sun/star/text/WritingMode2.hpp>
69 : #include <calbck.hxx>
70 : #include <algorithm>
71 : #include <txtfly.hxx>
72 :
73 : using namespace ::com::sun::star;
74 :
75 115887 : TYPEINIT1( SwContact, SwClient )
76 68327 : TYPEINIT1( SwFlyDrawContact, SwContact )
77 86660 : TYPEINIT1( SwDrawContact, SwContact )
78 :
79 2645 : void setContextWritingMode( SdrObject* pObj, SwFrm* pAnchor )
80 : {
81 2645 : if( pObj && pAnchor )
82 : {
83 2645 : short nWritingDirection = text::WritingMode2::LR_TB;
84 2645 : if( pAnchor->IsVertical() )
85 : {
86 0 : nWritingDirection = text::WritingMode2::TB_RL;
87 2645 : } else if( pAnchor->IsRightToLeft() )
88 : {
89 0 : nWritingDirection = text::WritingMode2::RL_TB;
90 : }
91 2645 : pObj->SetContextWritingMode( nWritingDirection );
92 : }
93 2645 : }
94 :
95 : /** The Get reverse way: seeks the format to the specified object.
96 : * If the object is a SwVirtFlyDrawObj then the format of this
97 : * will be acquired.
98 : * Otherwise it is just a simple drawing object. This has a
99 : * UserCall and is the client of the searched format.
100 : */
101 23102 : SwFrameFormat *FindFrameFormat( SdrObject *pObj )
102 : {
103 23102 : SwFrameFormat* pRetval = 0L;
104 :
105 23102 : if ( pObj->ISA(SwVirtFlyDrawObj) )
106 : {
107 4646 : pRetval = static_cast<SwVirtFlyDrawObj*>(pObj)->GetFormat();
108 : }
109 : else
110 : {
111 18456 : SwDrawContact* pContact = static_cast<SwDrawContact*>(GetUserCall( pObj ));
112 18456 : if ( pContact )
113 : {
114 16213 : pRetval = pContact->GetFormat();
115 : }
116 : }
117 23102 : return pRetval;
118 : }
119 :
120 2199 : bool HasWrap( const SdrObject* pObj )
121 : {
122 2199 : if ( pObj )
123 : {
124 2199 : const SwFrameFormat* pFormat = ::FindFrameFormat( pObj );
125 2199 : if ( pFormat )
126 : {
127 2199 : return SURROUND_THROUGHT != pFormat->GetSurround().GetSurround();
128 : }
129 : }
130 :
131 0 : return false;
132 : }
133 :
134 : /// returns the BoundRect _inclusive_ distance of the object.
135 0 : SwRect GetBoundRectOfAnchoredObj( const SdrObject* pObj )
136 : {
137 0 : SwRect aRet( pObj->GetCurrentBoundRect() );
138 : // #i68520# - call cache of <SwAnchoredObject>
139 0 : SwContact* pContact( GetUserCall( pObj ) );
140 0 : if ( pContact )
141 : {
142 0 : const SwAnchoredObject* pAnchoredObj( pContact->GetAnchoredObj( pObj ) );
143 0 : if ( pAnchoredObj )
144 : {
145 0 : aRet = pAnchoredObj->GetObjRectWithSpaces();
146 : }
147 : }
148 0 : return aRet;
149 : }
150 :
151 : /// Returns the UserCall if applicable from the group object
152 807961 : SwContact* GetUserCall( const SdrObject* pObj )
153 : {
154 : SdrObject *pTmp;
155 1618323 : while ( !pObj->GetUserCall() && 0 != (pTmp = pObj->GetUpGroup()) )
156 2401 : pObj = pTmp;
157 : OSL_ENSURE( !pObj->GetUserCall() || pObj->GetUserCall()->ISA(SwContact),
158 : "<::GetUserCall(..)> - wrong type of found object user call." );
159 807961 : return static_cast<SwContact*>(pObj->GetUserCall());
160 : }
161 :
162 : /// Returns true if the SrdObject is a Marquee-Object (scrolling text)
163 8 : bool IsMarqueeTextObj( const SdrObject& rObj )
164 : {
165 : SdrTextAniKind eTKind;
166 8 : return SdrInventor == rObj.GetObjInventor() &&
167 8 : OBJ_TEXT == rObj.GetObjIdentifier() &&
168 : ( SDRTEXTANI_SCROLL == ( eTKind = static_cast<const SdrTextObj&>(rObj).GetTextAniKind())
169 8 : || SDRTEXTANI_ALTERNATE == eTKind || SDRTEXTANI_SLIDE == eTKind );
170 : }
171 :
172 4728 : SwContact::SwContact( SwFrameFormat *pToRegisterIn ) :
173 : SwClient( pToRegisterIn ),
174 4728 : mbInDTOR( false )
175 4728 : {}
176 :
177 9454 : SwContact::~SwContact()
178 : {
179 4727 : SetInDTOR();
180 4727 : }
181 :
182 :
183 7170 : void SwContact::SetInDTOR()
184 : {
185 7170 : mbInDTOR = true;
186 7170 : }
187 :
188 : /// method to move drawing object to corresponding visible layer
189 40683 : void SwContact::MoveObjToVisibleLayer( SdrObject* _pDrawObj )
190 : {
191 : // #i46297# - notify background about the arriving of
192 : // the object and invalidate its position.
193 40683 : const bool bNotify( !GetFormat()->getIDocumentDrawModelAccess()->IsVisibleLayerId( _pDrawObj->GetLayer() ) );
194 :
195 40683 : _MoveObjToLayer( true, _pDrawObj );
196 :
197 : // #i46297#
198 40683 : if ( bNotify )
199 : {
200 1586 : SwAnchoredObject* pAnchoredObj = GetAnchoredObj( _pDrawObj );
201 : OSL_ENSURE( pAnchoredObj,
202 : "<SwContact::MoveObjToInvisibleLayer(..)> - missing anchored object" );
203 1586 : if ( pAnchoredObj )
204 : {
205 1586 : ::setContextWritingMode( _pDrawObj, pAnchoredObj->GetAnchorFrmContainingAnchPos() );
206 : // Note: as-character anchored objects aren't registered at a page frame and
207 : // a notification of its background isn't needed.
208 1586 : if ( pAnchoredObj->GetPageFrm() )
209 : {
210 : ::Notify_Background( _pDrawObj, pAnchoredObj->GetPageFrm(),
211 1097 : pAnchoredObj->GetObjRect(), PREP_FLY_ARRIVE, true );
212 : }
213 :
214 1586 : pAnchoredObj->InvalidateObjPos();
215 : }
216 : }
217 40683 : }
218 :
219 : /// method to move drawing object to corresponding invisible layer - #i18447#
220 8121 : void SwContact::MoveObjToInvisibleLayer( SdrObject* _pDrawObj )
221 : {
222 : // #i46297# - notify background about the leaving of the object.
223 8121 : const bool bNotify( GetFormat()->getIDocumentDrawModelAccess()->IsVisibleLayerId( _pDrawObj->GetLayer() ) );
224 :
225 8121 : _MoveObjToLayer( false, _pDrawObj );
226 :
227 : // #i46297#
228 8121 : if ( bNotify )
229 : {
230 1589 : SwAnchoredObject* pAnchoredObj = GetAnchoredObj( _pDrawObj );
231 : OSL_ENSURE( pAnchoredObj,
232 : "<SwContact::MoveObjToInvisibleLayer(..)> - missing anchored object" );
233 : // Note: as-character anchored objects aren't registered at a page frame and
234 : // a notification of its background isn't needed.
235 1589 : if ( pAnchoredObj && pAnchoredObj->GetPageFrm() )
236 : {
237 : ::Notify_Background( _pDrawObj, pAnchoredObj->GetPageFrm(),
238 0 : pAnchoredObj->GetObjRect(), PREP_FLY_LEAVE, true );
239 : }
240 : }
241 8121 : }
242 :
243 : /** method to move object to visible/invisible layer - #i18447#
244 :
245 : implementation for the public method <MoveObjToVisibleLayer(..)>
246 : and <MoveObjToInvisibleLayer(..)>
247 : */
248 89776 : void SwContact::_MoveObjToLayer( const bool _bToVisible,
249 : SdrObject* _pDrawObj )
250 : {
251 89776 : if ( !_pDrawObj )
252 : {
253 : OSL_FAIL( "SwDrawContact::_MoveObjToLayer(..) - no drawing object!" );
254 0 : return;
255 : }
256 :
257 89776 : if ( !GetRegisteredIn() )
258 : {
259 : OSL_FAIL( "SwDrawContact::_MoveObjToLayer(..) - no drawing frame format!" );
260 0 : return;
261 : }
262 :
263 89776 : const IDocumentDrawModelAccess* pIDDMA = static_cast<SwFrameFormat*>(GetRegisteredInNonConst())->getIDocumentDrawModelAccess();
264 89776 : if ( !pIDDMA )
265 : {
266 : OSL_FAIL( "SwDrawContact::_MoveObjToLayer(..) - no writer document!" );
267 0 : return;
268 : }
269 :
270 : SdrLayerID nToHellLayerId =
271 89776 : _bToVisible ? pIDDMA->GetHellId() : pIDDMA->GetInvisibleHellId();
272 : SdrLayerID nToHeavenLayerId =
273 89776 : _bToVisible ? pIDDMA->GetHeavenId() : pIDDMA->GetInvisibleHeavenId();
274 : SdrLayerID nToControlLayerId =
275 89776 : _bToVisible ? pIDDMA->GetControlsId() : pIDDMA->GetInvisibleControlsId();
276 : SdrLayerID nFromHellLayerId =
277 89776 : _bToVisible ? pIDDMA->GetInvisibleHellId() : pIDDMA->GetHellId();
278 : SdrLayerID nFromHeavenLayerId =
279 89776 : _bToVisible ? pIDDMA->GetInvisibleHeavenId() : pIDDMA->GetHeavenId();
280 : SdrLayerID nFromControlLayerId =
281 89776 : _bToVisible ? pIDDMA->GetInvisibleControlsId() : pIDDMA->GetControlsId();
282 :
283 89776 : if ( _pDrawObj->ISA( SdrObjGroup ) )
284 : {
285 : // determine layer for group object
286 : {
287 : // proposed layer of a group object is the hell layer
288 1964 : SdrLayerID nNewLayerId = nToHellLayerId;
289 1964 : if ( ::CheckControlLayer( _pDrawObj ) )
290 : {
291 : // it has to be the control layer, if one of the member
292 : // is a control
293 0 : nNewLayerId = nToControlLayerId;
294 : }
295 3511 : else if ( _pDrawObj->GetLayer() == pIDDMA->GetHeavenId() ||
296 1547 : _pDrawObj->GetLayer() == pIDDMA->GetInvisibleHeavenId() )
297 : {
298 : // it has to be the heaven layer, if method <GetLayer()> reveals
299 : // a heaven layer
300 890 : nNewLayerId = nToHeavenLayerId;
301 : }
302 : // set layer at group object, but do *not* broadcast and
303 : // no propagation to the members.
304 : // Thus, call <NbcSetLayer(..)> at super class
305 1964 : _pDrawObj->SdrObject::NbcSetLayer( nNewLayerId );
306 : }
307 :
308 : // call method recursively for group object members
309 : const SdrObjList* pLst =
310 1964 : static_cast<SdrObjGroup*>(_pDrawObj)->GetSubList();
311 1964 : if ( pLst )
312 : {
313 42936 : for ( size_t i = 0; i < pLst->GetObjCount(); ++i )
314 : {
315 40972 : _MoveObjToLayer( _bToVisible, pLst->GetObj( i ) );
316 : }
317 : }
318 : }
319 : else
320 : {
321 87812 : const SdrLayerID nLayerIdOfObj = _pDrawObj->GetLayer();
322 87812 : if ( nLayerIdOfObj == nFromHellLayerId )
323 : {
324 1861 : _pDrawObj->SetLayer( nToHellLayerId );
325 : }
326 85951 : else if ( nLayerIdOfObj == nFromHeavenLayerId )
327 : {
328 2806 : _pDrawObj->SetLayer( nToHeavenLayerId );
329 : }
330 83145 : else if ( nLayerIdOfObj == nFromControlLayerId )
331 : {
332 542 : _pDrawObj->SetLayer( nToControlLayerId );
333 : }
334 : }
335 : }
336 :
337 : // some virtual helper methods for information
338 : // about the object (Writer fly frame resp. drawing object)
339 :
340 3170 : const SwIndex& SwContact::GetContentAnchorIndex() const
341 : {
342 3170 : return GetContentAnchor().nContent;
343 : }
344 :
345 : /// get minimum order number of anchored objects handled by with contact
346 0 : sal_uInt32 SwContact::GetMinOrdNum() const
347 : {
348 0 : sal_uInt32 nMinOrdNum( SAL_MAX_UINT32 );
349 :
350 0 : std::list< SwAnchoredObject* > aObjs;
351 0 : GetAnchoredObjs( aObjs );
352 :
353 0 : while ( !aObjs.empty() )
354 : {
355 0 : sal_uInt32 nTmpOrdNum = aObjs.back()->GetDrawObj()->GetOrdNum();
356 :
357 0 : if ( nTmpOrdNum < nMinOrdNum )
358 : {
359 0 : nMinOrdNum = nTmpOrdNum;
360 : }
361 :
362 0 : aObjs.pop_back();
363 : }
364 :
365 : OSL_ENSURE( nMinOrdNum != SAL_MAX_UINT32,
366 : "<SwContact::GetMinOrdNum()> - no order number found." );
367 0 : return nMinOrdNum;
368 : }
369 :
370 : /// get maximum order number of anchored objects handled by with contact
371 0 : sal_uInt32 SwContact::GetMaxOrdNum() const
372 : {
373 0 : sal_uInt32 nMaxOrdNum( 0L );
374 :
375 0 : std::list< SwAnchoredObject* > aObjs;
376 0 : GetAnchoredObjs( aObjs );
377 :
378 0 : while ( !aObjs.empty() )
379 : {
380 0 : sal_uInt32 nTmpOrdNum = aObjs.back()->GetDrawObj()->GetOrdNum();
381 :
382 0 : if ( nTmpOrdNum > nMaxOrdNum )
383 : {
384 0 : nMaxOrdNum = nTmpOrdNum;
385 : }
386 :
387 0 : aObjs.pop_back();
388 : }
389 :
390 0 : return nMaxOrdNum;
391 : }
392 :
393 2284 : SwFlyDrawContact::SwFlyDrawContact( SwFlyFrameFormat *pToRegisterIn, SdrModel * ) :
394 2284 : SwContact( pToRegisterIn )
395 : {
396 : // #i26791# - class <SwFlyDrawContact> contains the 'master'
397 : // drawing object of type <SwFlyDrawObj> on its own.
398 2284 : mpMasterObj = new SwFlyDrawObj;
399 2284 : mpMasterObj->SetOrdNum( 0xFFFFFFFE );
400 2284 : mpMasterObj->SetUserCall( this );
401 2284 : }
402 :
403 6852 : SwFlyDrawContact::~SwFlyDrawContact()
404 : {
405 2284 : if ( mpMasterObj )
406 : {
407 2284 : mpMasterObj->SetUserCall( 0 );
408 2284 : if ( mpMasterObj->GetPage() )
409 526 : mpMasterObj->GetPage()->RemoveObject( mpMasterObj->GetOrdNum() );
410 2284 : delete mpMasterObj;
411 : }
412 4568 : }
413 :
414 : // #i26791#
415 16 : const SwAnchoredObject* SwFlyDrawContact::GetAnchoredObj( const SdrObject* _pSdrObj ) const
416 : {
417 : OSL_ENSURE( _pSdrObj,
418 : "<SwFlyDrawContact::GetAnchoredObj(..)> - no object provided" );
419 : OSL_ENSURE( _pSdrObj->ISA(SwVirtFlyDrawObj),
420 : "<SwFlyDrawContact::GetAnchoredObj(..)> - wrong object type object provided" );
421 : OSL_ENSURE( GetUserCall( _pSdrObj ) == this,
422 : "<SwFlyDrawContact::GetAnchoredObj(..)> - provided object doesn't belongs to this contact" );
423 :
424 16 : const SwAnchoredObject* pRetAnchoredObj = 0L;
425 :
426 16 : if ( _pSdrObj && _pSdrObj->ISA(SwVirtFlyDrawObj) )
427 : {
428 16 : pRetAnchoredObj = static_cast<const SwVirtFlyDrawObj*>(_pSdrObj)->GetFlyFrm();
429 : }
430 :
431 16 : return pRetAnchoredObj;
432 : }
433 :
434 11740 : SwAnchoredObject* SwFlyDrawContact::GetAnchoredObj( SdrObject* _pSdrObj )
435 : {
436 : OSL_ENSURE( _pSdrObj,
437 : "<SwFlyDrawContact::GetAnchoredObj(..)> - no object provided" );
438 : OSL_ENSURE( _pSdrObj->ISA(SwVirtFlyDrawObj),
439 : "<SwFlyDrawContact::GetAnchoredObj(..)> - wrong object type provided" );
440 : OSL_ENSURE( GetUserCall( _pSdrObj ) == this,
441 : "<SwFlyDrawContact::GetAnchoredObj(..)> - provided object doesn't belongs to this contact" );
442 :
443 11740 : SwAnchoredObject* pRetAnchoredObj = 0L;
444 :
445 11740 : if ( _pSdrObj && _pSdrObj->ISA(SwVirtFlyDrawObj) )
446 : {
447 11740 : pRetAnchoredObj = static_cast<SwVirtFlyDrawObj*>(_pSdrObj)->GetFlyFrm();
448 : }
449 :
450 11740 : return pRetAnchoredObj;
451 : }
452 :
453 669 : const SdrObject* SwFlyDrawContact::GetMaster() const
454 : {
455 669 : return mpMasterObj;
456 : }
457 :
458 17998 : SdrObject* SwFlyDrawContact::GetMaster()
459 : {
460 17998 : return mpMasterObj;
461 : }
462 :
463 0 : void SwFlyDrawContact::SetMaster( SdrObject* _pNewMaster )
464 : {
465 : OSL_ENSURE( _pNewMaster->ISA(SwFlyDrawObj),
466 : "<SwFlyDrawContact::SetMaster(..)> - wrong type of new master object" );
467 0 : mpMasterObj = static_cast<SwFlyDrawObj *>(_pNewMaster);
468 0 : }
469 :
470 13260 : void SwFlyDrawContact::Modify( const SfxPoolItem*, const SfxPoolItem * )
471 : {
472 13260 : }
473 :
474 : /**
475 : * @note Overriding method to control Writer fly frames, which are linked, and
476 : * to assure that all objects anchored at/inside the Writer fly frame are
477 : * also made visible.
478 : */
479 22245 : void SwFlyDrawContact::MoveObjToVisibleLayer( SdrObject* _pDrawObj )
480 : {
481 : OSL_ENSURE( _pDrawObj->ISA(SwVirtFlyDrawObj),
482 : "<SwFlyDrawContact::MoveObjToVisibleLayer(..)> - wrong SdrObject type -> crash" );
483 :
484 22245 : if ( GetFormat()->getIDocumentDrawModelAccess()->IsVisibleLayerId( _pDrawObj->GetLayer() ) )
485 : {
486 : // nothing to do
487 44490 : return;
488 : }
489 :
490 0 : SwFlyFrm* pFlyFrm = static_cast<SwVirtFlyDrawObj*>(_pDrawObj)->GetFlyFrm();
491 :
492 : // #i44464# - consider, that Writer fly frame content
493 : // already exists - (e.g. WW8 document is inserted into a existing document).
494 0 : if ( !pFlyFrm->Lower() )
495 : {
496 0 : pFlyFrm->InsertColumns();
497 0 : pFlyFrm->Chain( pFlyFrm->AnchorFrm() );
498 0 : pFlyFrm->InsertCnt();
499 : }
500 0 : if ( pFlyFrm->GetDrawObjs() )
501 : {
502 0 : for ( size_t i = 0; i < pFlyFrm->GetDrawObjs()->size(); ++i)
503 : {
504 : // #i28701# - consider type of objects in sorted object list.
505 0 : SdrObject* pObj = (*pFlyFrm->GetDrawObjs())[i]->DrawObj();
506 0 : SwContact* pContact = static_cast<SwContact*>(pObj->GetUserCall());
507 0 : pContact->MoveObjToVisibleLayer( pObj );
508 : }
509 : }
510 :
511 : // make fly frame visible
512 0 : SwContact::MoveObjToVisibleLayer( _pDrawObj );
513 : }
514 :
515 : /**
516 : * @note Override method to control Writer fly frames, which are linked, and
517 : * to assure that all objects anchored at/inside the Writer fly frame are
518 : * also made invisible.
519 : */
520 0 : void SwFlyDrawContact::MoveObjToInvisibleLayer( SdrObject* _pDrawObj )
521 : {
522 : OSL_ENSURE( _pDrawObj->ISA(SwVirtFlyDrawObj),
523 : "<SwFlyDrawContact::MoveObjToInvisibleLayer(..)> - wrong SdrObject type -> crash" );
524 :
525 0 : if ( !GetFormat()->getIDocumentDrawModelAccess()->IsVisibleLayerId( _pDrawObj->GetLayer() ) )
526 : {
527 : // nothing to do
528 0 : return;
529 : }
530 :
531 0 : SwFlyFrm* pFlyFrm = static_cast<SwVirtFlyDrawObj*>(_pDrawObj)->GetFlyFrm();
532 :
533 0 : pFlyFrm->Unchain();
534 0 : pFlyFrm->DeleteCnt();
535 0 : if ( pFlyFrm->GetDrawObjs() )
536 : {
537 0 : for ( size_t i = 0; i < pFlyFrm->GetDrawObjs()->size(); ++i)
538 : {
539 : // #i28701# - consider type of objects in sorted object list.
540 0 : SdrObject* pObj = (*pFlyFrm->GetDrawObjs())[i]->DrawObj();
541 0 : SwContact* pContact = static_cast<SwContact*>(pObj->GetUserCall());
542 0 : pContact->MoveObjToInvisibleLayer( pObj );
543 : }
544 : }
545 :
546 : // make fly frame invisible
547 0 : SwContact::MoveObjToInvisibleLayer( _pDrawObj );
548 : }
549 :
550 : /// get data collection of anchored objects, handled by with contact
551 18 : void SwFlyDrawContact::GetAnchoredObjs( std::list<SwAnchoredObject*>& _roAnchoredObjs ) const
552 : {
553 18 : const SwFrameFormat* pFormat = GetFormat();
554 18 : SwFlyFrm::GetAnchoredObjects( _roAnchoredObjs, *pFormat );
555 18 : }
556 :
557 : // SwDrawContact
558 :
559 100327 : bool CheckControlLayer( const SdrObject *pObj )
560 : {
561 100327 : if ( FmFormInventor == pObj->GetObjInventor() )
562 1038 : return true;
563 99289 : if ( pObj->ISA( SdrObjGroup ) )
564 : {
565 4417 : const SdrObjList *pLst = static_cast<const SdrObjGroup*>(pObj)->GetSubList();
566 94427 : for ( size_t i = 0; i < pLst->GetObjCount(); ++i )
567 : {
568 90010 : if ( ::CheckControlLayer( pLst->GetObj( i ) ) )
569 : {
570 : // #i18447# - return correct value ;-)
571 0 : return true;
572 : }
573 : }
574 : }
575 99289 : return false;
576 : }
577 :
578 2444 : SwDrawContact::SwDrawContact( SwFrameFormat* pToRegisterIn, SdrObject* pObj ) :
579 : SwContact( pToRegisterIn ),
580 : maAnchoredDrawObj(),
581 : mbMasterObjCleared( false ),
582 : mbDisconnectInProgress( false ),
583 : mbUserCallActive( false ),
584 : // Note: value of <meEventTypeOfCurrentUserCall> isn't of relevance, because
585 : // <mbUserCallActive> is false.
586 2444 : meEventTypeOfCurrentUserCall( SDRUSERCALL_MOVEONLY )
587 : {
588 : // clear list containing 'virtual' drawing objects.
589 2444 : maDrawVirtObjs.clear();
590 :
591 : // --> #i33909# - assure, that drawing object is inserted
592 : // in the drawing page.
593 2444 : if ( !pObj->IsInserted() )
594 : {
595 9 : pToRegisterIn->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage(0)->
596 9 : InsertObject( pObj, pObj->GetOrdNumDirect() );
597 : }
598 :
599 : // Controls have to be always in the Control-Layer. This is also true for
600 : // group objects, if they contain controls.
601 2444 : if ( ::CheckControlLayer( pObj ) )
602 : {
603 : // set layer of object to corresponding invisible layer.
604 271 : pObj->SetLayer( pToRegisterIn->getIDocumentDrawModelAccess()->GetInvisibleControlsId() );
605 : }
606 :
607 : // #i26791#
608 2444 : pObj->SetUserCall( this );
609 2444 : maAnchoredDrawObj.SetDrawObj( *pObj );
610 :
611 : // if there already exists an SwXShape for the object, ensure it knows about us, and the SdrObject
612 : // #i99056#
613 2444 : SwXShape::AddExistingShapeToFormat( *pObj );
614 2444 : }
615 :
616 7329 : SwDrawContact::~SwDrawContact()
617 : {
618 2443 : SetInDTOR();
619 :
620 2443 : DisconnectFromLayout();
621 :
622 : // remove 'master' from drawing page
623 2443 : RemoveMasterFromDrawPage();
624 :
625 : // remove and destroy 'virtual' drawing objects.
626 2443 : RemoveAllVirtObjs();
627 :
628 2443 : if ( !mbMasterObjCleared )
629 : {
630 2442 : SdrObject* pObject = const_cast< SdrObject* >( maAnchoredDrawObj.GetDrawObj() );
631 2442 : SdrObject::Free( pObject );
632 : }
633 4886 : }
634 :
635 0 : void SwDrawContact::GetTextObjectsFromFormat( std::list<SdrTextObj*>& rTextObjects, SwDoc* pDoc )
636 : {
637 0 : for( sal_Int32 n=0; n<(sal_Int32)pDoc->GetSpzFrameFormats()->size(); n++ )
638 : {
639 0 : const SwFrameFormat* pFly = (*pDoc->GetSpzFrameFormats())[n];
640 0 : if( pFly->IsA( TYPE(SwDrawFrameFormat) ) )
641 : {
642 0 : SwDrawContact* pContact = SwIterator<SwDrawContact,SwFrameFormat>(*pFly).First();
643 0 : if( pContact )
644 : {
645 0 : SdrObject* pSdrO = pContact->GetMaster();
646 0 : if ( pSdrO )
647 : {
648 0 : if ( pSdrO->IsA( TYPE(SdrObjGroup) ) )
649 : {
650 0 : SdrObjListIter aListIter( *pSdrO, IM_DEEPNOGROUPS );
651 : //iterate inside of a grouped object
652 0 : while( aListIter.IsMore() )
653 : {
654 0 : SdrObject* pSdrOElement = aListIter.Next();
655 0 : if( pSdrOElement && pSdrOElement->IsA( TYPE(SdrTextObj) ) &&
656 0 : static_cast<SdrTextObj*>( pSdrOElement)->HasText() )
657 : {
658 0 : rTextObjects.push_back(static_cast<SdrTextObj*>( pSdrOElement ));
659 : }
660 0 : }
661 : }
662 0 : else if( pSdrO->IsA( TYPE(SdrTextObj) ) &&
663 0 : static_cast<SdrTextObj*>( pSdrO )->HasText() )
664 : {
665 0 : rTextObjects.push_back(static_cast<SdrTextObj*>( pSdrO ));
666 : }
667 : }
668 : }
669 : }
670 : }
671 0 : }
672 :
673 : // #i26791#
674 45368 : const SwAnchoredObject* SwDrawContact::GetAnchoredObj( const SdrObject* _pSdrObj ) const
675 : {
676 : // handle default parameter value
677 45368 : if ( !_pSdrObj )
678 : {
679 0 : _pSdrObj = GetMaster();
680 : }
681 :
682 : OSL_ENSURE( _pSdrObj,
683 : "<SwDrawContact::GetAnchoredObj(..)> - no object provided" );
684 : OSL_ENSURE( _pSdrObj->ISA(SwDrawVirtObj) ||
685 : ( !_pSdrObj->ISA(SdrVirtObj) && !_pSdrObj->ISA(SwDrawVirtObj) ),
686 : "<SwDrawContact::GetAnchoredObj(..)> - wrong object type object provided" );
687 : OSL_ENSURE( GetUserCall( _pSdrObj ) == this ||
688 : _pSdrObj == GetMaster(),
689 : "<SwDrawContact::GetAnchoredObj(..)> - provided object doesn't belongs to this contact" );
690 :
691 45368 : const SwAnchoredObject* pRetAnchoredObj = 0L;
692 :
693 45368 : if ( _pSdrObj )
694 : {
695 45368 : if ( _pSdrObj->ISA(SwDrawVirtObj) )
696 : {
697 1794 : pRetAnchoredObj = &(static_cast<const SwDrawVirtObj*>(_pSdrObj)->GetAnchoredObj());
698 : }
699 43574 : else if ( !_pSdrObj->ISA(SdrVirtObj) && !_pSdrObj->ISA(SwDrawVirtObj) )
700 : {
701 43574 : pRetAnchoredObj = &maAnchoredDrawObj;
702 : }
703 : }
704 :
705 45368 : return pRetAnchoredObj;
706 : }
707 :
708 32281 : SwAnchoredObject* SwDrawContact::GetAnchoredObj( SdrObject* _pSdrObj )
709 : {
710 : // handle default parameter value
711 32281 : if ( !_pSdrObj )
712 : {
713 19162 : _pSdrObj = GetMaster();
714 : }
715 :
716 : OSL_ENSURE( _pSdrObj,
717 : "<SwDrawContact::GetAnchoredObj(..)> - no object provided" );
718 : OSL_ENSURE( _pSdrObj->ISA(SwDrawVirtObj) ||
719 : ( !_pSdrObj->ISA(SdrVirtObj) && !_pSdrObj->ISA(SwDrawVirtObj) ),
720 : "<SwDrawContact::GetAnchoredObj(..)> - wrong object type object provided" );
721 : OSL_ENSURE( GetUserCall( _pSdrObj ) == this || _pSdrObj == GetMaster(),
722 : "<SwDrawContact::GetAnchoredObj(..)> - provided object doesn't belongs to this contact" );
723 :
724 32281 : SwAnchoredObject* pRetAnchoredObj = 0L;
725 :
726 32281 : if ( _pSdrObj )
727 : {
728 32281 : if ( _pSdrObj->ISA(SwDrawVirtObj) )
729 : {
730 949 : pRetAnchoredObj = &(static_cast<SwDrawVirtObj*>(_pSdrObj)->AnchoredObj());
731 : }
732 31332 : else if ( !_pSdrObj->ISA(SdrVirtObj) && !_pSdrObj->ISA(SwDrawVirtObj) )
733 : {
734 31332 : pRetAnchoredObj = &maAnchoredDrawObj;
735 : }
736 : }
737 :
738 32281 : return pRetAnchoredObj;
739 : }
740 :
741 13293 : const SdrObject* SwDrawContact::GetMaster() const
742 : {
743 13293 : return !mbMasterObjCleared
744 13293 : ? maAnchoredDrawObj.GetDrawObj()
745 26586 : : 0L;
746 : }
747 :
748 96668 : SdrObject* SwDrawContact::GetMaster()
749 : {
750 96668 : return !mbMasterObjCleared
751 96666 : ? maAnchoredDrawObj.DrawObj()
752 193334 : : 0L;
753 : }
754 :
755 : /**
756 : * @note Override <SwContact::SetMaster(..)> in order to assert, if the
757 : * 'master' drawing object is replaced. The latter is correctly handled,
758 : * if handled by method <SwDrawContact::ChangeMasterObject(..)>. Thus,
759 : * assert only, if a debug level is given.
760 : */
761 1 : void SwDrawContact::SetMaster( SdrObject* _pNewMaster )
762 : {
763 1 : if ( _pNewMaster )
764 : {
765 : OSL_FAIL( "debug notification - master replaced!" );
766 0 : maAnchoredDrawObj.SetDrawObj( *_pNewMaster );
767 : }
768 : else
769 : {
770 1 : mbMasterObjCleared = true;
771 : }
772 1 : }
773 :
774 13296 : const SwFrm* SwDrawContact::GetAnchorFrm( const SdrObject* _pDrawObj ) const
775 : {
776 13296 : const SwFrm* pAnchorFrm = 0L;
777 25832 : if ( !_pDrawObj ||
778 26592 : _pDrawObj == GetMaster() ||
779 0 : ( !_pDrawObj->GetUserCall() &&
780 0 : GetUserCall( _pDrawObj ) == static_cast<const SwContact* const>(this) ) )
781 : {
782 13296 : pAnchorFrm = maAnchoredDrawObj.GetAnchorFrm();
783 : }
784 0 : else if ( _pDrawObj->ISA(SwDrawVirtObj) )
785 : {
786 0 : pAnchorFrm = static_cast<const SwDrawVirtObj*>(_pDrawObj)->GetAnchorFrm();
787 : }
788 : else
789 : {
790 : OSL_FAIL( "<SwDrawContact::GetAnchorFrm(..)> - unknown drawing object." );
791 : }
792 :
793 13296 : return pAnchorFrm;
794 : }
795 29344 : SwFrm* SwDrawContact::GetAnchorFrm( SdrObject* _pDrawObj )
796 : {
797 29344 : SwFrm* pAnchorFrm = 0L;
798 30313 : if ( !_pDrawObj ||
799 58797 : _pDrawObj == GetMaster() ||
800 473 : ( !_pDrawObj->GetUserCall() &&
801 109 : GetUserCall( _pDrawObj ) == this ) )
802 : {
803 29089 : pAnchorFrm = maAnchoredDrawObj.AnchorFrm();
804 : }
805 : else
806 : {
807 : OSL_ENSURE( _pDrawObj->ISA(SwDrawVirtObj),
808 : "<SwDrawContact::GetAnchorFrm(..)> - unknown drawing object." );
809 255 : pAnchorFrm = static_cast<SwDrawVirtObj*>(_pDrawObj)->AnchorFrm();
810 : }
811 :
812 29344 : return pAnchorFrm;
813 : }
814 :
815 : /// create a new 'virtual' drawing object.
816 220 : SwDrawVirtObj* SwDrawContact::CreateVirtObj()
817 : {
818 : // determine 'master'
819 220 : SdrObject* pOrgMasterSdrObj = GetMaster();
820 :
821 : // create 'virtual' drawing object
822 220 : SwDrawVirtObj* pNewDrawVirtObj = new SwDrawVirtObj ( *(pOrgMasterSdrObj), *(this) );
823 :
824 : // add new 'virtual' drawing object managing data structure
825 220 : maDrawVirtObjs.push_back( pNewDrawVirtObj );
826 :
827 220 : return pNewDrawVirtObj;
828 : }
829 :
830 : /** destroys a given 'virtual' drawing object.
831 : *
832 : * side effect: 'virtual' drawing object is removed from data structure
833 : * <maDrawVirtObjs>.
834 : */
835 220 : void SwDrawContact::DestroyVirtObj( SwDrawVirtObj* _pVirtObj )
836 : {
837 220 : if ( _pVirtObj )
838 : {
839 220 : delete _pVirtObj;
840 220 : _pVirtObj = 0;
841 : }
842 220 : }
843 :
844 : /** add a 'virtual' drawing object to drawing page.
845 : *
846 : * Use an already created one, which isn't used, or create a new one.
847 : */
848 363 : SwDrawVirtObj* SwDrawContact::AddVirtObj()
849 : {
850 363 : SwDrawVirtObj* pAddedDrawVirtObj = 0L;
851 :
852 : // check, if a disconnected 'virtual' drawing object exist and use it
853 : std::list<SwDrawVirtObj*>::const_iterator aFoundVirtObjIter =
854 : std::find_if( maDrawVirtObjs.begin(), maDrawVirtObjs.end(),
855 363 : UsedOrUnusedVirtObjPred( false ) );
856 :
857 363 : if ( aFoundVirtObjIter != maDrawVirtObjs.end() )
858 : {
859 : // use already created, disconnected 'virtual' drawing object
860 143 : pAddedDrawVirtObj = (*aFoundVirtObjIter);
861 : }
862 : else
863 : {
864 : // create new 'virtual' drawing object.
865 220 : pAddedDrawVirtObj = CreateVirtObj();
866 : }
867 363 : pAddedDrawVirtObj->AddToDrawingPage();
868 :
869 363 : return pAddedDrawVirtObj;
870 : }
871 :
872 : /// remove 'virtual' drawing objects and destroy them.
873 2443 : void SwDrawContact::RemoveAllVirtObjs()
874 : {
875 7989 : for ( std::list<SwDrawVirtObj*>::iterator aDrawVirtObjsIter = maDrawVirtObjs.begin();
876 5326 : aDrawVirtObjsIter != maDrawVirtObjs.end();
877 : ++aDrawVirtObjsIter )
878 : {
879 : // remove and destroy 'virtual object'
880 220 : SwDrawVirtObj* pDrawVirtObj = (*aDrawVirtObjsIter);
881 220 : pDrawVirtObj->RemoveFromWriterLayout();
882 220 : pDrawVirtObj->RemoveFromDrawingPage();
883 220 : DestroyVirtObj( pDrawVirtObj );
884 : }
885 2443 : maDrawVirtObjs.clear();
886 2443 : }
887 :
888 220 : SwDrawContact::VirtObjAnchoredAtFrmPred::VirtObjAnchoredAtFrmPred(
889 : const SwFrm& _rAnchorFrm )
890 220 : : mpAnchorFrm( &_rAnchorFrm )
891 : {
892 220 : if ( mpAnchorFrm->IsContentFrm() )
893 : {
894 : const SwContentFrm* pTmpFrm =
895 220 : static_cast<const SwContentFrm*>( mpAnchorFrm );
896 440 : while ( pTmpFrm->IsFollow() )
897 : {
898 0 : pTmpFrm = pTmpFrm->FindMaster();
899 : }
900 220 : mpAnchorFrm = pTmpFrm;
901 : }
902 220 : }
903 :
904 : // #i26791# - compare with master frame
905 2185 : bool SwDrawContact::VirtObjAnchoredAtFrmPred::operator() ( const SwDrawVirtObj* _pDrawVirtObj )
906 : {
907 2185 : const SwFrm* pObjAnchorFrm = _pDrawVirtObj->GetAnchorFrm();
908 2185 : if ( pObjAnchorFrm && pObjAnchorFrm->IsContentFrm() )
909 : {
910 : const SwContentFrm* pTmpFrm =
911 2185 : static_cast<const SwContentFrm*>( pObjAnchorFrm );
912 4370 : while ( pTmpFrm->IsFollow() )
913 : {
914 0 : pTmpFrm = pTmpFrm->FindMaster();
915 : }
916 2185 : pObjAnchorFrm = pTmpFrm;
917 : }
918 :
919 2185 : return ( pObjAnchorFrm == mpAnchorFrm );
920 : }
921 :
922 : /// get drawing object ('master' or 'virtual') by frame.
923 2721 : SdrObject* SwDrawContact::GetDrawObjectByAnchorFrm( const SwFrm& _rAnchorFrm )
924 : {
925 2721 : SdrObject* pRetDrawObj = 0L;
926 :
927 : // #i26791# - compare master frames instead of direct frames
928 2721 : const SwFrm* pProposedAnchorFrm = &_rAnchorFrm;
929 2721 : if ( pProposedAnchorFrm->IsContentFrm() )
930 : {
931 : const SwContentFrm* pTmpFrm =
932 2721 : static_cast<const SwContentFrm*>( pProposedAnchorFrm );
933 5497 : while ( pTmpFrm->IsFollow() )
934 : {
935 55 : pTmpFrm = pTmpFrm->FindMaster();
936 : }
937 2721 : pProposedAnchorFrm = pTmpFrm;
938 : }
939 :
940 2721 : const SwFrm* pMasterObjAnchorFrm = GetAnchorFrm();
941 2721 : if ( pMasterObjAnchorFrm && pMasterObjAnchorFrm->IsContentFrm() )
942 : {
943 : const SwContentFrm* pTmpFrm =
944 2721 : static_cast<const SwContentFrm*>( pMasterObjAnchorFrm );
945 5526 : while ( pTmpFrm->IsFollow() )
946 : {
947 84 : pTmpFrm = pTmpFrm->FindMaster();
948 : }
949 2721 : pMasterObjAnchorFrm = pTmpFrm;
950 : }
951 :
952 2721 : if ( pMasterObjAnchorFrm && pMasterObjAnchorFrm == pProposedAnchorFrm )
953 : {
954 2501 : pRetDrawObj = GetMaster();
955 : }
956 : else
957 : {
958 : std::list<SwDrawVirtObj*>::const_iterator aFoundVirtObjIter =
959 : std::find_if( maDrawVirtObjs.begin(), maDrawVirtObjs.end(),
960 220 : VirtObjAnchoredAtFrmPred( *pProposedAnchorFrm ) );
961 :
962 220 : if ( aFoundVirtObjIter != maDrawVirtObjs.end() )
963 : {
964 0 : pRetDrawObj = (*aFoundVirtObjIter);
965 : }
966 : }
967 :
968 2721 : return pRetDrawObj;
969 : }
970 :
971 7564 : void SwDrawContact::NotifyBackgrdOfAllVirtObjs( const Rectangle* pOldBoundRect )
972 : {
973 23352 : for ( std::list<SwDrawVirtObj*>::iterator aDrawVirtObjIter = maDrawVirtObjs.begin();
974 15568 : aDrawVirtObjIter != maDrawVirtObjs.end();
975 : ++aDrawVirtObjIter )
976 : {
977 220 : SwDrawVirtObj* pDrawVirtObj = (*aDrawVirtObjIter);
978 220 : if ( pDrawVirtObj->GetAnchorFrm() )
979 : {
980 : // #i34640# - determine correct page frame
981 0 : SwPageFrm* pPage = pDrawVirtObj->AnchoredObj().FindPageFrmOfAnchor();
982 0 : if( pOldBoundRect && pPage )
983 : {
984 0 : SwRect aOldRect( *pOldBoundRect );
985 0 : aOldRect.Pos() += pDrawVirtObj->GetOffset();
986 0 : if( aOldRect.HasArea() )
987 : ::Notify_Background( pDrawVirtObj, pPage,
988 0 : aOldRect, PREP_FLY_LEAVE,true);
989 : }
990 : // #i34640# - include spacing for wrapping
991 0 : SwRect aRect( pDrawVirtObj->GetAnchoredObj().GetObjRectWithSpaces() );
992 0 : if (aRect.HasArea() && pPage)
993 : {
994 0 : SwPageFrm* pPg = const_cast<SwPageFrm*>(static_cast<const SwPageFrm*>(::FindPage( aRect, pPage )));
995 0 : if ( pPg )
996 : ::Notify_Background( pDrawVirtObj, pPg, aRect,
997 0 : PREP_FLY_ARRIVE, true );
998 : }
999 0 : ::ClrContourCache( pDrawVirtObj );
1000 : }
1001 : }
1002 7564 : }
1003 :
1004 : /// local method to notify the background for a drawing object - #i26791#
1005 13967 : static void lcl_NotifyBackgroundOfObj( SwDrawContact& _rDrawContact,
1006 : const SdrObject& _rObj,
1007 : const Rectangle* _pOldObjRect )
1008 : {
1009 : // #i34640#
1010 : SwAnchoredObject* pAnchoredObj =
1011 13967 : const_cast<SwAnchoredObject*>(_rDrawContact.GetAnchoredObj( &_rObj ));
1012 13967 : if ( pAnchoredObj && pAnchoredObj->GetAnchorFrm() )
1013 : {
1014 : // #i34640# - determine correct page frame
1015 3341 : SwPageFrm* pPageFrm = pAnchoredObj->FindPageFrmOfAnchor();
1016 3341 : if( _pOldObjRect && pPageFrm )
1017 : {
1018 61 : SwRect aOldRect( *_pOldObjRect );
1019 61 : if( aOldRect.HasArea() )
1020 : {
1021 : // #i34640# - determine correct page frame
1022 49 : SwPageFrm* pOldPageFrm = const_cast<SwPageFrm*>(static_cast<const SwPageFrm*>(::FindPage( aOldRect, pPageFrm )));
1023 : ::Notify_Background( &_rObj, pOldPageFrm, aOldRect,
1024 49 : PREP_FLY_LEAVE, true);
1025 : }
1026 : }
1027 : // #i34640# - include spacing for wrapping
1028 3341 : SwRect aNewRect( pAnchoredObj->GetObjRectWithSpaces() );
1029 3341 : if( aNewRect.HasArea() && pPageFrm )
1030 : {
1031 1787 : pPageFrm = const_cast<SwPageFrm*>(static_cast<const SwPageFrm*>(::FindPage( aNewRect, pPageFrm )));
1032 : ::Notify_Background( &_rObj, pPageFrm, aNewRect,
1033 1787 : PREP_FLY_ARRIVE, true );
1034 : }
1035 3341 : ClrContourCache( &_rObj );
1036 : }
1037 13967 : }
1038 :
1039 32908 : void SwDrawContact::Changed( const SdrObject& rObj,
1040 : SdrUserCallType eType,
1041 : const Rectangle& rOldBoundRect )
1042 : {
1043 : // #i26791# - no event handling, if existing <SwViewShell>
1044 : // is in construction
1045 32908 : SwDoc* pDoc = GetFormat()->GetDoc();
1046 43946 : if ( pDoc->getIDocumentLayoutAccess().GetCurrentViewShell() &&
1047 11038 : pDoc->getIDocumentLayoutAccess().GetCurrentViewShell()->IsInConstructor() )
1048 : {
1049 1156 : return;
1050 : }
1051 :
1052 : // #i44339#
1053 : // no event handling, if document is in destruction.
1054 : // Exception: It's the SDRUSERCALL_DELETE event
1055 31752 : if ( pDoc->IsInDtor() && eType != SDRUSERCALL_DELETE )
1056 : {
1057 0 : return;
1058 : }
1059 :
1060 : //Put on Action, but not if presently anywhere an action runs.
1061 31752 : bool bHasActions(true);
1062 31752 : SwRootFrm *pTmpRoot = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
1063 31752 : if ( pTmpRoot && pTmpRoot->IsCallbackActionEnabled() )
1064 : {
1065 9651 : SwViewShell* const pSh = pDoc->getIDocumentLayoutAccess().GetCurrentViewShell();
1066 9651 : if ( pSh )
1067 : {
1068 9762 : for(SwViewShell& rShell : pSh->GetRingContainer() )
1069 : {
1070 9651 : if ( rShell.Imp()->IsAction() || rShell.Imp()->IsIdleAction() )
1071 : {
1072 9540 : bHasActions = true;
1073 9540 : break;
1074 : }
1075 111 : bHasActions = false;
1076 : }
1077 : }
1078 9651 : if(!bHasActions)
1079 111 : pTmpRoot->StartAllAction();
1080 : }
1081 31752 : SdrObjUserCall::Changed( rObj, eType, rOldBoundRect );
1082 31752 : _Changed( rObj, eType, &rOldBoundRect ); //Attention, possibly suicidal!
1083 :
1084 31752 : if(!bHasActions)
1085 111 : pTmpRoot->EndAllAction();
1086 : }
1087 :
1088 : /// helper class for method <SwDrawContact::_Changed(..)> for handling nested
1089 : /// <SdrObjUserCall> events
1090 : class NestedUserCallHdl
1091 : {
1092 : private:
1093 : SwDrawContact* mpDrawContact;
1094 : bool mbParentUserCallActive;
1095 : SdrUserCallType meParentUserCallEventType;
1096 :
1097 : public:
1098 31752 : NestedUserCallHdl( SwDrawContact* _pDrawContact,
1099 : SdrUserCallType _eEventType )
1100 : : mpDrawContact( _pDrawContact ),
1101 : mbParentUserCallActive( _pDrawContact->mbUserCallActive ),
1102 31752 : meParentUserCallEventType( _pDrawContact->meEventTypeOfCurrentUserCall )
1103 : {
1104 31752 : mpDrawContact->mbUserCallActive = true;
1105 31752 : mpDrawContact->meEventTypeOfCurrentUserCall = _eEventType;
1106 31752 : }
1107 :
1108 31752 : ~NestedUserCallHdl()
1109 : {
1110 31752 : if ( mpDrawContact )
1111 : {
1112 31751 : mpDrawContact->mbUserCallActive = mbParentUserCallActive;
1113 31751 : mpDrawContact->meEventTypeOfCurrentUserCall = meParentUserCallEventType;
1114 : }
1115 31752 : }
1116 :
1117 1 : void DrawContactDeleted()
1118 : {
1119 1 : mpDrawContact = 0;
1120 1 : }
1121 :
1122 31761 : bool IsNestedUserCall() const
1123 : {
1124 31761 : return mbParentUserCallActive;
1125 : }
1126 :
1127 9 : void AssertNestedUserCall()
1128 : {
1129 9 : if ( IsNestedUserCall() )
1130 : {
1131 9 : bool bTmpAssert( true );
1132 : // Currently its known, that a nested event SDRUSERCALL_RESIZE
1133 : // could occur during parent user call SDRUSERCALL_INSERTED,
1134 : // SDRUSERCALL_DELETE and SDRUSERCALL_RESIZE for edge objects.
1135 : // Also possible are nested SDRUSERCALL_CHILD_RESIZE events for
1136 : // edge objects
1137 : // Thus, assert all other combinations
1138 18 : if ( ( meParentUserCallEventType == SDRUSERCALL_INSERTED ||
1139 18 : meParentUserCallEventType == SDRUSERCALL_DELETE ||
1140 18 : meParentUserCallEventType == SDRUSERCALL_RESIZE ) &&
1141 9 : mpDrawContact->meEventTypeOfCurrentUserCall == SDRUSERCALL_RESIZE )
1142 : {
1143 9 : bTmpAssert = false;
1144 : }
1145 0 : else if ( meParentUserCallEventType == SDRUSERCALL_CHILD_RESIZE &&
1146 0 : mpDrawContact->meEventTypeOfCurrentUserCall == SDRUSERCALL_CHILD_RESIZE )
1147 : {
1148 0 : bTmpAssert = false;
1149 : }
1150 :
1151 : if ( bTmpAssert )
1152 : {
1153 : OSL_FAIL( "<SwDrawContact::_Changed(..)> - unknown nested <UserCall> event. This is serious, please inform OD." );
1154 : }
1155 : }
1156 9 : }
1157 : };
1158 :
1159 : /// Notify the format's textbox that it should reconsider its position / size.
1160 5 : void lcl_textBoxSizeNotify(SwFrameFormat* pFormat)
1161 : {
1162 5 : if (SwTextBoxHelper::findTextBox(pFormat))
1163 : {
1164 : // Just notify the textbox that the size has changed, the actual object size is not interesting.
1165 1 : SfxItemSet aResizeSet(pFormat->GetDoc()->GetAttrPool(), RES_FRM_SIZE, RES_FRM_SIZE, 0);
1166 2 : SwFormatFrmSize aSize;
1167 1 : aResizeSet.Put(aSize);
1168 2 : SwTextBoxHelper::syncFlyFrmAttr(*pFormat, aResizeSet);
1169 : }
1170 5 : }
1171 :
1172 : // !!!ATTENTION!!! The object may commit suicide!!!
1173 :
1174 31752 : void SwDrawContact::_Changed( const SdrObject& rObj,
1175 : SdrUserCallType eType,
1176 : const Rectangle* pOldBoundRect )
1177 : {
1178 : // suppress handling of nested <SdrObjUserCall> events
1179 31752 : NestedUserCallHdl aNestedUserCallHdl( this, eType );
1180 31752 : if ( aNestedUserCallHdl.IsNestedUserCall() )
1181 : {
1182 9 : aNestedUserCallHdl.AssertNestedUserCall();
1183 31761 : return;
1184 : }
1185 : // do *not* notify, if document is destructing
1186 : // #i35912# - do *not* notify for as-character anchored
1187 : // drawing objects.
1188 : // #i35007#
1189 : // improvement: determine as-character anchored object flag only once.
1190 31743 : const bool bAnchoredAsChar = ObjAnchoredAsChar();
1191 63486 : const bool bNotify = !(GetFormat()->GetDoc()->IsInDtor()) &&
1192 50747 : ( SURROUND_THROUGHT != GetFormat()->GetSurround().GetSurround() ) &&
1193 50747 : !bAnchoredAsChar;
1194 31743 : switch( eType )
1195 : {
1196 : case SDRUSERCALL_DELETE:
1197 : {
1198 1 : if ( bNotify )
1199 : {
1200 0 : lcl_NotifyBackgroundOfObj( *this, rObj, pOldBoundRect );
1201 : // --> #i36181# - background of 'virtual'
1202 : // drawing objects have also been notified.
1203 0 : NotifyBackgrdOfAllVirtObjs( pOldBoundRect );
1204 : }
1205 1 : DisconnectFromLayout( false );
1206 1 : SetMaster( NULL );
1207 1 : delete this;
1208 : // --> #i65784# Prevent memory corruption
1209 1 : aNestedUserCallHdl.DrawContactDeleted();
1210 1 : break;
1211 : }
1212 : case SDRUSERCALL_INSERTED:
1213 : {
1214 0 : if ( mbDisconnectInProgress )
1215 : {
1216 : OSL_FAIL( "<SwDrawContact::_Changed(..)> - Insert event during disconnection from layout is invalid." );
1217 : }
1218 : else
1219 : {
1220 0 : ConnectToLayout();
1221 0 : if ( bNotify )
1222 : {
1223 0 : lcl_NotifyBackgroundOfObj( *this, rObj, pOldBoundRect );
1224 : }
1225 : }
1226 0 : break;
1227 : }
1228 : case SDRUSERCALL_REMOVED:
1229 : {
1230 0 : if ( bNotify )
1231 : {
1232 0 : lcl_NotifyBackgroundOfObj( *this, rObj, pOldBoundRect );
1233 : }
1234 0 : DisconnectFromLayout( false );
1235 0 : break;
1236 : }
1237 : case SDRUSERCALL_CHILD_INSERTED :
1238 : case SDRUSERCALL_CHILD_REMOVED :
1239 : {
1240 : // --> #i113730#
1241 : // force layer of controls for group objects containing control objects
1242 1551 : if(dynamic_cast< SdrObjGroup* >(maAnchoredDrawObj.DrawObj()))
1243 : {
1244 1551 : if(::CheckControlLayer(maAnchoredDrawObj.DrawObj()))
1245 : {
1246 0 : const IDocumentDrawModelAccess* pIDDMA = static_cast<SwFrameFormat*>(GetRegisteredInNonConst())->getIDocumentDrawModelAccess();
1247 0 : const SdrLayerID aCurrentLayer(maAnchoredDrawObj.DrawObj()->GetLayer());
1248 0 : const SdrLayerID aControlLayerID(pIDDMA->GetControlsId());
1249 0 : const SdrLayerID aInvisibleControlLayerID(pIDDMA->GetInvisibleControlsId());
1250 :
1251 0 : if(aCurrentLayer != aControlLayerID && aCurrentLayer != aInvisibleControlLayerID)
1252 : {
1253 0 : if ( aCurrentLayer == pIDDMA->GetInvisibleHellId() ||
1254 0 : aCurrentLayer == pIDDMA->GetInvisibleHeavenId() )
1255 : {
1256 0 : maAnchoredDrawObj.DrawObj()->SetLayer(aInvisibleControlLayerID);
1257 : }
1258 : else
1259 : {
1260 0 : maAnchoredDrawObj.DrawObj()->SetLayer(aControlLayerID);
1261 : }
1262 : }
1263 : }
1264 : }
1265 : // fallthrough intended here
1266 : }
1267 : case SDRUSERCALL_MOVEONLY:
1268 : case SDRUSERCALL_RESIZE:
1269 : case SDRUSERCALL_CHILD_MOVEONLY :
1270 : case SDRUSERCALL_CHILD_RESIZE :
1271 : case SDRUSERCALL_CHILD_CHGATTR :
1272 : case SDRUSERCALL_CHILD_DELETE :
1273 : case SDRUSERCALL_CHILD_COPY :
1274 : {
1275 : // #i31698# - improvement
1276 : // get instance <SwAnchoredDrawObject> only once
1277 : const SwAnchoredDrawObject* pAnchoredDrawObj =
1278 25112 : static_cast<const SwAnchoredDrawObject*>( GetAnchoredObj( &rObj ) );
1279 :
1280 : /* protect against NULL pointer dereferencing */
1281 25112 : if(!pAnchoredDrawObj)
1282 : {
1283 0 : break;
1284 : }
1285 :
1286 : // #i26791# - adjust positioning and alignment attributes,
1287 : // if positioning of drawing object isn't in progress.
1288 : // #i53320# - no adjust of positioning attributes,
1289 : // if drawing object isn't positioned.
1290 40516 : if ( !pAnchoredDrawObj->IsPositioningInProgress() &&
1291 15404 : !pAnchoredDrawObj->NotYetPositioned() )
1292 : {
1293 : // #i34748# - If no last object rectangle is
1294 : // provided by the anchored object, use parameter <pOldBoundRect>.
1295 11 : const Rectangle& aOldObjRect = pAnchoredDrawObj->GetLastObjRect()
1296 : ? *(pAnchoredDrawObj->GetLastObjRect())
1297 11 : : *(pOldBoundRect);
1298 : // #i79400#
1299 : // always invalidate object rectangle inclusive spaces
1300 11 : pAnchoredDrawObj->InvalidateObjRectWithSpaces();
1301 : // #i41324# - notify background before
1302 : // adjusting position
1303 11 : if ( bNotify )
1304 : {
1305 : // #i31573# - correction
1306 : // background of given drawing object.
1307 8 : lcl_NotifyBackgroundOfObj( *this, rObj, &aOldObjRect );
1308 : }
1309 : // #i31698# - determine layout direction
1310 : // via draw frame format.
1311 : SwFrameFormat::tLayoutDir eLayoutDir =
1312 11 : pAnchoredDrawObj->GetFrameFormat().GetLayoutDir();
1313 : // use geometry of drawing object
1314 11 : SwRect aObjRect( rObj.GetSnapRect() );
1315 : // If drawing object is a member of a group, the adjustment
1316 : // of the positioning and the alignment attributes has to
1317 : // be done for the top group object.
1318 11 : if ( rObj.GetUpGroup() )
1319 : {
1320 0 : const SdrObject* pGroupObj = rObj.GetUpGroup();
1321 0 : while ( pGroupObj->GetUpGroup() )
1322 : {
1323 0 : pGroupObj = pGroupObj->GetUpGroup();
1324 : }
1325 : // use geometry of drawing object
1326 0 : aObjRect = pGroupObj->GetSnapRect();
1327 : }
1328 11 : SwTwips nXPosDiff(0L);
1329 11 : SwTwips nYPosDiff(0L);
1330 11 : switch ( eLayoutDir )
1331 : {
1332 : case SwFrameFormat::HORI_L2R:
1333 : {
1334 11 : nXPosDiff = aObjRect.Left() - aOldObjRect.Left();
1335 11 : nYPosDiff = aObjRect.Top() - aOldObjRect.Top();
1336 : }
1337 11 : break;
1338 : case SwFrameFormat::HORI_R2L:
1339 : {
1340 0 : nXPosDiff = aOldObjRect.Right() - aObjRect.Right();
1341 0 : nYPosDiff = aObjRect.Top() - aOldObjRect.Top();
1342 : }
1343 0 : break;
1344 : case SwFrameFormat::VERT_R2L:
1345 : {
1346 0 : nXPosDiff = aObjRect.Top() - aOldObjRect.Top();
1347 0 : nYPosDiff = aOldObjRect.Right() - aObjRect.Right();
1348 : }
1349 0 : break;
1350 : default:
1351 : {
1352 : OSL_FAIL( "<SwDrawContact::_Changed(..)> - unsupported layout direction" );
1353 : }
1354 : }
1355 11 : SfxItemSet aSet( GetFormat()->GetDoc()->GetAttrPool(),
1356 11 : RES_VERT_ORIENT, RES_HORI_ORIENT, 0 );
1357 11 : const SwFormatVertOrient& rVert = GetFormat()->GetVertOrient();
1358 11 : if ( nYPosDiff != 0 )
1359 : {
1360 :
1361 12 : if ( rVert.GetRelationOrient() == text::RelOrientation::CHAR ||
1362 6 : rVert.GetRelationOrient() == text::RelOrientation::TEXT_LINE )
1363 : {
1364 0 : nYPosDiff = -nYPosDiff;
1365 : }
1366 6 : aSet.Put( SwFormatVertOrient( rVert.GetPos()+nYPosDiff,
1367 : text::VertOrientation::NONE,
1368 12 : rVert.GetRelationOrient() ) );
1369 : }
1370 :
1371 11 : const SwFormatHoriOrient& rHori = GetFormat()->GetHoriOrient();
1372 11 : if ( !bAnchoredAsChar && nXPosDiff != 0 )
1373 : {
1374 0 : aSet.Put( SwFormatHoriOrient( rHori.GetPos()+nXPosDiff,
1375 : text::HoriOrientation::NONE,
1376 0 : rHori.GetRelationOrient() ) );
1377 : }
1378 :
1379 16 : if ( nYPosDiff ||
1380 10 : ( !bAnchoredAsChar && nXPosDiff != 0 ) )
1381 : {
1382 6 : GetFormat()->GetDoc()->SetFlyFrmAttr( *(GetFormat()), aSet );
1383 : // keep new object rectangle, to avoid multiple
1384 : // changes of the attributes by multiple event from
1385 : // the drawing layer - e.g. group objects and its members
1386 : // #i34748# - use new method
1387 : // <SwAnchoredDrawObject::SetLastObjRect(..)>.
1388 : const_cast<SwAnchoredDrawObject*>(pAnchoredDrawObj)
1389 6 : ->SetLastObjRect( aObjRect.SVRect() );
1390 : }
1391 5 : else if ( aObjRect.SSize() != aOldObjRect.GetSize() )
1392 : {
1393 4 : _InvalidateObjs();
1394 : // #i35007# - notify anchor frame
1395 : // of as-character anchored object
1396 4 : if ( bAnchoredAsChar )
1397 : {
1398 0 : SwFrm* pAnchorFrm = const_cast<SwAnchoredDrawObject*>(pAnchoredDrawObj)->AnchorFrm();
1399 0 : if(pAnchorFrm)
1400 : {
1401 0 : pAnchorFrm->Prepare( PREP_FLY_ATTR_CHG, GetFormat() );
1402 : }
1403 : }
1404 :
1405 4 : lcl_textBoxSizeNotify(GetFormat());
1406 : }
1407 1 : else if (eType == SDRUSERCALL_RESIZE)
1408 : // Even if the bounding box of the shape didn't change,
1409 : // notify about the size change, as an adjustment change
1410 : // may affect the size of the underlying textbox.
1411 1 : lcl_textBoxSizeNotify(GetFormat());
1412 : }
1413 : }
1414 25112 : break;
1415 : case SDRUSERCALL_CHGATTR:
1416 6630 : if ( bNotify )
1417 : {
1418 6395 : lcl_NotifyBackgroundOfObj( *this, rObj, pOldBoundRect );
1419 : }
1420 6630 : break;
1421 : default:
1422 0 : break;
1423 31743 : }
1424 : }
1425 :
1426 : namespace
1427 : {
1428 19892 : static const SwFormatAnchor* lcl_getAnchorFormat( const SfxPoolItem& _rItem )
1429 : {
1430 19892 : sal_uInt16 nWhich = _rItem.Which();
1431 19892 : const SwFormatAnchor* pAnchorFormat = NULL;
1432 19892 : if ( RES_ATTRSET_CHG == nWhich )
1433 : {
1434 19245 : static_cast<const SwAttrSetChg&>(_rItem).GetChgSet()->
1435 19245 : GetItemState( RES_ANCHOR, false, reinterpret_cast<const SfxPoolItem**>(&pAnchorFormat) );
1436 : }
1437 647 : else if ( RES_ANCHOR == nWhich )
1438 : {
1439 0 : pAnchorFormat = &static_cast<const SwFormatAnchor&>(_rItem);
1440 : }
1441 19892 : return pAnchorFormat;
1442 : }
1443 : }
1444 :
1445 15648 : void SwDrawContact::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew )
1446 : {
1447 : OSL_ENSURE( !mbDisconnectInProgress,
1448 : "<SwDrawContact::Modify(..)> called during disconnection.");
1449 :
1450 15648 : sal_uInt16 nWhich = pNew ? pNew->Which() : 0;
1451 15648 : const SwFormatAnchor* pNewAnchorFormat = pNew ? lcl_getAnchorFormat( *pNew ) : NULL;
1452 :
1453 15648 : if ( pNewAnchorFormat )
1454 : {
1455 : // Do not respond to a Reset Anchor !!!!!
1456 4245 : if ( SfxItemState::SET ==
1457 4245 : GetFormat()->GetAttrSet().GetItemState( RES_ANCHOR, false ) )
1458 : {
1459 : // no connect to layout during disconnection
1460 4244 : if ( !mbDisconnectInProgress )
1461 : {
1462 : // determine old object rectangle of 'master' drawing object
1463 : // for notification
1464 4244 : const Rectangle* pOldRect = 0L;
1465 4244 : Rectangle aOldRect;
1466 4244 : if ( GetAnchorFrm() )
1467 : {
1468 : // --> #i36181# - include spacing in object
1469 : // rectangle for notification.
1470 9 : aOldRect = maAnchoredDrawObj.GetObjRectWithSpaces().SVRect();
1471 9 : pOldRect = &aOldRect;
1472 : }
1473 : // re-connect to layout due to anchor format change
1474 4244 : ConnectToLayout( pNewAnchorFormat );
1475 : // notify background of drawing objects
1476 4244 : lcl_NotifyBackgroundOfObj( *this, *GetMaster(), pOldRect );
1477 4244 : NotifyBackgrdOfAllVirtObjs( pOldRect );
1478 :
1479 4244 : const SwFormatAnchor* pOldAnchorFormat = pOld ? lcl_getAnchorFormat( *pOld ) : NULL;
1480 4244 : if ( !pOldAnchorFormat || ( pOldAnchorFormat->GetAnchorId() != pNewAnchorFormat->GetAnchorId() ) )
1481 : {
1482 : OSL_ENSURE( maAnchoredDrawObj.DrawObj(), "SwDrawContact::Modify: no draw object here?" );
1483 2237 : if ( maAnchoredDrawObj.DrawObj() )
1484 : {
1485 : // --> #i102752#
1486 : // assure that a ShapePropertyChangeNotifier exists
1487 2237 : maAnchoredDrawObj.DrawObj()->notifyShapePropertyChange( svx::eTextShapeAnchorType );
1488 : }
1489 : }
1490 : }
1491 : }
1492 : else
1493 1 : DisconnectFromLayout();
1494 : }
1495 : // --> #i62875# - no further notification, if not connected to Writer layout
1496 13235 : else if ( maAnchoredDrawObj.GetAnchorFrm() &&
1497 1832 : maAnchoredDrawObj.GetDrawObj()->GetUserCall() )
1498 : {
1499 : // --> #i28701# - on change of wrapping style, hell|heaven layer,
1500 : // or wrapping style influence an update of the <SwSortedObjs> list,
1501 : // the drawing object is registered in, has to be performed. This is triggered
1502 : // by the 1st parameter of method call <_InvalidateObjs(..)>.
1503 3664 : if ( RES_SURROUND == nWhich ||
1504 1832 : RES_OPAQUE == nWhich ||
1505 3687 : RES_WRAP_INFLUENCE_ON_OBJPOS == nWhich ||
1506 1832 : ( RES_ATTRSET_CHG == nWhich &&
1507 1832 : ( SfxItemState::SET == static_cast<const SwAttrSetChg*>(pNew)->GetChgSet()->GetItemState(
1508 3641 : RES_SURROUND, false ) ||
1509 1809 : SfxItemState::SET == static_cast<const SwAttrSetChg*>(pNew)->GetChgSet()->GetItemState(
1510 3618 : RES_OPAQUE, false ) ||
1511 1809 : SfxItemState::SET == static_cast<const SwAttrSetChg*>(pNew)->GetChgSet()->GetItemState(
1512 1809 : RES_WRAP_INFLUENCE_ON_OBJPOS, false ) ) ) )
1513 : {
1514 23 : lcl_NotifyBackgroundOfObj( *this, *GetMaster(), 0L );
1515 23 : NotifyBackgrdOfAllVirtObjs( 0L );
1516 23 : _InvalidateObjs( true );
1517 : }
1518 3618 : else if ( RES_UL_SPACE == nWhich || RES_LR_SPACE == nWhich ||
1519 1809 : RES_HORI_ORIENT == nWhich || RES_VERT_ORIENT == nWhich ||
1520 : // #i28701# - add attribute 'Follow text flow'
1521 5426 : RES_FOLLOW_TEXT_FLOW == nWhich ||
1522 1809 : ( RES_ATTRSET_CHG == nWhich &&
1523 1809 : ( SfxItemState::SET == static_cast<const SwAttrSetChg*>(pNew)->GetChgSet()->GetItemState(
1524 3618 : RES_LR_SPACE, false ) ||
1525 1809 : SfxItemState::SET == static_cast<const SwAttrSetChg*>(pNew)->GetChgSet()->GetItemState(
1526 3618 : RES_UL_SPACE, false ) ||
1527 1809 : SfxItemState::SET == static_cast<const SwAttrSetChg*>(pNew)->GetChgSet()->GetItemState(
1528 2724 : RES_HORI_ORIENT, false ) ||
1529 915 : SfxItemState::SET == static_cast<const SwAttrSetChg*>(pNew)->GetChgSet()->GetItemState(
1530 916 : RES_VERT_ORIENT, false ) ||
1531 1 : SfxItemState::SET == static_cast<const SwAttrSetChg*>(pNew)->GetChgSet()->GetItemState(
1532 1 : RES_FOLLOW_TEXT_FLOW, false ) ) ) )
1533 : {
1534 1808 : lcl_NotifyBackgroundOfObj( *this, *GetMaster(), 0L );
1535 1808 : NotifyBackgrdOfAllVirtObjs( 0L );
1536 1808 : _InvalidateObjs();
1537 : }
1538 : // #i35443#
1539 1 : else if ( RES_ATTRSET_CHG == nWhich )
1540 : {
1541 1 : lcl_NotifyBackgroundOfObj( *this, *GetMaster(), 0L );
1542 1 : NotifyBackgrdOfAllVirtObjs( 0L );
1543 1 : _InvalidateObjs();
1544 : }
1545 : else if ( RES_REMOVE_UNO_OBJECT == nWhich )
1546 : {
1547 : // nothing to do
1548 : }
1549 : #if OSL_DEBUG_LEVEL > 0
1550 : else
1551 : {
1552 : OSL_FAIL( "<SwDrawContact::Modify(..)> - unhandled attribute? - please inform od@openoffice.org" );
1553 : }
1554 : #endif
1555 : }
1556 :
1557 : // #i51474#
1558 15648 : GetAnchoredObj( 0L )->ResetLayoutProcessBools();
1559 15648 : }
1560 :
1561 : // #i26791#
1562 : // #i28701# - added parameter <_bUpdateSortedObjsList>
1563 2895 : void SwDrawContact::_InvalidateObjs( const bool _bUpdateSortedObjsList )
1564 : {
1565 : // invalidate position of existing 'virtual' drawing objects
1566 9114 : for ( std::list<SwDrawVirtObj*>::iterator aDisconnectIter = maDrawVirtObjs.begin();
1567 6076 : aDisconnectIter != maDrawVirtObjs.end();
1568 : ++aDisconnectIter )
1569 : {
1570 143 : SwDrawVirtObj* pDrawVirtObj = (*aDisconnectIter);
1571 : // #i33313# - invalidation only for connected
1572 : // 'virtual' drawing objects
1573 143 : if ( pDrawVirtObj->IsConnected() )
1574 : {
1575 143 : pDrawVirtObj->AnchoredObj().InvalidateObjPos();
1576 : // #i28701#
1577 143 : if ( _bUpdateSortedObjsList )
1578 : {
1579 0 : pDrawVirtObj->AnchoredObj().UpdateObjInSortedList();
1580 : }
1581 : }
1582 : }
1583 :
1584 : // invalidate position of 'master' drawing object
1585 2895 : SwAnchoredObject* pAnchoredObj = GetAnchoredObj( 0L );
1586 2895 : pAnchoredObj->InvalidateObjPos();
1587 : // #i28701#
1588 2895 : if ( _bUpdateSortedObjsList )
1589 : {
1590 23 : pAnchoredObj->UpdateObjInSortedList();
1591 : }
1592 2895 : }
1593 :
1594 9248 : void SwDrawContact::DisconnectFromLayout( bool _bMoveMasterToInvisibleLayer )
1595 : {
1596 9248 : mbDisconnectInProgress = true;
1597 :
1598 : // --> #i36181# - notify background of drawing object
1599 17372 : if ( _bMoveMasterToInvisibleLayer &&
1600 14068 : !(GetFormat()->GetDoc()->IsInDtor()) &&
1601 16791 : GetAnchorFrm() && !GetAnchorFrm()->IsInDtor() )
1602 : {
1603 1488 : const Rectangle aOldRect( maAnchoredDrawObj.GetObjRectWithSpaces().SVRect() );
1604 1488 : lcl_NotifyBackgroundOfObj( *this, *GetMaster(), &aOldRect );
1605 1488 : NotifyBackgrdOfAllVirtObjs( &aOldRect );
1606 : }
1607 :
1608 : // remove 'virtual' drawing objects from writer
1609 : // layout and from drawing page
1610 29493 : for ( std::list<SwDrawVirtObj*>::iterator aDisconnectIter = maDrawVirtObjs.begin();
1611 19662 : aDisconnectIter != maDrawVirtObjs.end();
1612 : ++aDisconnectIter )
1613 : {
1614 583 : SwDrawVirtObj* pDrawVirtObj = (*aDisconnectIter);
1615 583 : pDrawVirtObj->RemoveFromWriterLayout();
1616 583 : pDrawVirtObj->RemoveFromDrawingPage();
1617 : }
1618 :
1619 9248 : if ( maAnchoredDrawObj.GetAnchorFrm() )
1620 : {
1621 1711 : maAnchoredDrawObj.AnchorFrm()->RemoveDrawObj( maAnchoredDrawObj );
1622 : }
1623 :
1624 9248 : if ( _bMoveMasterToInvisibleLayer && GetMaster() && GetMaster()->IsInserted() )
1625 : {
1626 8121 : SdrViewIter aIter( GetMaster() );
1627 8132 : for( SdrView* pView = aIter.FirstView(); pView;
1628 : pView = aIter.NextView() )
1629 : {
1630 11 : pView->MarkObj( GetMaster(), pView->GetSdrPageView(), true );
1631 : }
1632 :
1633 : // Instead of removing 'master' object from drawing page, move the
1634 : // 'master' drawing object into the corresponding invisible layer.
1635 : {
1636 : //static_cast<SwFrameFormat*>(GetRegisteredIn())->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage(0)->
1637 : // RemoveObject( GetMaster()->GetOrdNum() );
1638 : // #i18447# - in order to consider group object correct
1639 : // use new method <SwDrawContact::MoveObjToInvisibleLayer(..)>
1640 8121 : MoveObjToInvisibleLayer( GetMaster() );
1641 : }
1642 : }
1643 :
1644 9248 : mbDisconnectInProgress = false;
1645 9248 : }
1646 :
1647 : /// method to remove 'master' drawing object from drawing page.
1648 2444 : void SwDrawContact::RemoveMasterFromDrawPage()
1649 : {
1650 2444 : if ( GetMaster() )
1651 : {
1652 2443 : GetMaster()->SetUserCall( 0 );
1653 2443 : if ( GetMaster()->IsInserted() )
1654 : {
1655 2442 : static_cast<SwFrameFormat*>(GetRegisteredIn())->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage(0)->
1656 2442 : RemoveObject( GetMaster()->GetOrdNum() );
1657 : }
1658 : }
1659 2444 : }
1660 :
1661 : // disconnect for a dedicated drawing object - could be 'master' or 'virtual'.
1662 : // a 'master' drawing object will disconnect a 'virtual' drawing object
1663 : // in order to take its place.
1664 : // #i19919# - no special case, if drawing object isn't in
1665 : // page header/footer, in order to get drawing objects in repeating table headers
1666 : // also working.
1667 1801 : void SwDrawContact::DisconnectObjFromLayout( SdrObject* _pDrawObj )
1668 : {
1669 1801 : if ( _pDrawObj->ISA(SwDrawVirtObj) )
1670 : {
1671 140 : SwDrawVirtObj* pDrawVirtObj = static_cast<SwDrawVirtObj*>(_pDrawObj);
1672 140 : pDrawVirtObj->RemoveFromWriterLayout();
1673 140 : pDrawVirtObj->RemoveFromDrawingPage();
1674 : }
1675 : else
1676 : {
1677 : std::list<SwDrawVirtObj*>::const_iterator aFoundVirtObjIter =
1678 : std::find_if( maDrawVirtObjs.begin(), maDrawVirtObjs.end(),
1679 1661 : UsedOrUnusedVirtObjPred( true ) );
1680 1661 : if ( aFoundVirtObjIter != maDrawVirtObjs.end() )
1681 : {
1682 : // replace found 'virtual' drawing object by 'master' drawing
1683 : // object and disconnect the 'virtual' one
1684 80 : SwDrawVirtObj* pDrawVirtObj = (*aFoundVirtObjIter);
1685 80 : SwFrm* pNewAnchorFrmOfMaster = pDrawVirtObj->AnchorFrm();
1686 : // disconnect 'virtual' drawing object
1687 80 : pDrawVirtObj->RemoveFromWriterLayout();
1688 80 : pDrawVirtObj->RemoveFromDrawingPage();
1689 : // disconnect 'master' drawing object from current frame
1690 80 : GetAnchorFrm()->RemoveDrawObj( maAnchoredDrawObj );
1691 : // re-connect 'master' drawing object to frame of found 'virtual'
1692 : // drawing object.
1693 80 : pNewAnchorFrmOfMaster->AppendDrawObj( maAnchoredDrawObj );
1694 : }
1695 : else
1696 : {
1697 : // no connected 'virtual' drawing object found. Thus, disconnect
1698 : // completely from layout.
1699 1581 : DisconnectFromLayout();
1700 : }
1701 : }
1702 1801 : }
1703 :
1704 322 : static SwTextFrm* lcl_GetFlyInContentAnchor( SwTextFrm* _pProposedAnchorFrm,
1705 : const sal_Int32 _nTextOfs )
1706 : {
1707 322 : SwTextFrm* pAct = _pProposedAnchorFrm;
1708 : SwTextFrm* pTmp;
1709 324 : do
1710 : {
1711 324 : pTmp = pAct;
1712 324 : pAct = pTmp->GetFollow();
1713 : }
1714 324 : while( pAct && _nTextOfs >= pAct->GetOfst() );
1715 322 : return pTmp;
1716 : }
1717 :
1718 5610 : void SwDrawContact::ConnectToLayout( const SwFormatAnchor* pAnch )
1719 : {
1720 : // *no* connect to layout during disconnection from layout.
1721 5610 : if ( mbDisconnectInProgress )
1722 : {
1723 : OSL_FAIL( "<SwDrawContact::ConnectToLayout(..)> called during disconnection.");
1724 0 : return;
1725 : }
1726 :
1727 : // --> #i33909# - *no* connect to layout, if 'master' drawing
1728 : // object isn't inserted in the drawing page
1729 5610 : if ( !GetMaster()->IsInserted() )
1730 : {
1731 : OSL_FAIL( "<SwDrawContact::ConnectToLayout(..)> - master drawing object not inserted -> no connect to layout. Please inform od@openoffice.org" );
1732 0 : return;
1733 : }
1734 :
1735 5610 : SwFrameFormat* pDrawFrameFormat = static_cast<SwFrameFormat*>(GetRegisteredIn());
1736 :
1737 5610 : if( !pDrawFrameFormat->getIDocumentLayoutAccess()->GetCurrentViewShell() )
1738 4490 : return;
1739 :
1740 : // remove 'virtual' drawing objects from writer
1741 : // layout and from drawing page, and remove 'master' drawing object from
1742 : // writer layout - 'master' object will remain in drawing page.
1743 1120 : DisconnectFromLayout( false );
1744 :
1745 1120 : if ( !pAnch )
1746 : {
1747 1102 : pAnch = &(pDrawFrameFormat->GetAnchor());
1748 : }
1749 :
1750 1120 : switch ( pAnch->GetAnchorId() )
1751 : {
1752 : case FLY_AT_PAGE:
1753 : {
1754 34 : sal_uInt16 nPgNum = pAnch->GetPageNum();
1755 34 : SwViewShell *pShell = pDrawFrameFormat->getIDocumentLayoutAccess()->GetCurrentViewShell();
1756 34 : if( !pShell )
1757 0 : break;
1758 34 : SwRootFrm* pRoot = pShell->GetLayout();
1759 34 : SwPageFrm *pPage = static_cast<SwPageFrm*>(pRoot->Lower());
1760 :
1761 84 : for ( sal_uInt16 i = 1; i < nPgNum && pPage; ++i )
1762 : {
1763 50 : pPage = static_cast<SwPageFrm*>(pPage->GetNext());
1764 : }
1765 :
1766 34 : if ( pPage )
1767 : {
1768 20 : pPage->AppendDrawObj( maAnchoredDrawObj );
1769 : }
1770 : else
1771 : //Looks stupid but is allowed (compare SwFEShell::SetPageObjsNewPage)
1772 14 : pRoot->SetAssertFlyPages();
1773 : }
1774 34 : break;
1775 :
1776 : case FLY_AT_CHAR:
1777 : case FLY_AT_PARA:
1778 : case FLY_AT_FLY:
1779 : case FLY_AS_CHAR:
1780 : {
1781 1086 : if ( pAnch->GetAnchorId() == FLY_AS_CHAR )
1782 : {
1783 322 : ClrContourCache( GetMaster() );
1784 : }
1785 : // support drawing objects in header/footer,
1786 : // but not control objects:
1787 : // anchor at first found frame the 'master' object and
1788 : // at the following frames 'virtual' drawing objects.
1789 : // Note: method is similar to <SwFlyFrameFormat::MakeFrms(..)>
1790 1086 : SwModify *pModify = 0;
1791 1086 : if( pAnch->GetContentAnchor() )
1792 : {
1793 1086 : if ( pAnch->GetAnchorId() == FLY_AT_FLY )
1794 : {
1795 9 : SwNodeIndex aIdx( pAnch->GetContentAnchor()->nNode );
1796 9 : SwContentNode* pCNd = pDrawFrameFormat->GetDoc()->GetNodes().GoNext( &aIdx );
1797 9 : if ( SwIterator<SwFrm,SwContentNode>( *pCNd ).First() )
1798 9 : pModify = pCNd;
1799 : else
1800 : {
1801 0 : const SwNodeIndex& rIdx = pAnch->GetContentAnchor()->nNode;
1802 0 : SwFrameFormats& rFormats = *(pDrawFrameFormat->GetDoc()->GetSpzFrameFormats());
1803 0 : for( auto pFlyFormat : rFormats )
1804 : {
1805 0 : if( pFlyFormat->GetContent().GetContentIdx() &&
1806 0 : rIdx == *(pFlyFormat->GetContent().GetContentIdx()) )
1807 : {
1808 0 : pModify = pFlyFormat;
1809 0 : break;
1810 : }
1811 : }
1812 9 : }
1813 : }
1814 : else
1815 : {
1816 1077 : pModify = pAnch->GetContentAnchor()->nNode.GetNode().GetContentNode();
1817 : }
1818 : }
1819 :
1820 : // #i29199# - It is possible, that
1821 : // the anchor doesn't exist - E.g., reordering the
1822 : // sub-documents in a master document.
1823 : // Note: The anchor will be inserted later.
1824 1086 : if ( !pModify )
1825 : {
1826 : // break to end of the current switch case.
1827 0 : break;
1828 : }
1829 :
1830 1086 : SwIterator<SwFrm,SwModify> aIter( *pModify );
1831 1086 : SwFrm* pAnchorFrmOfMaster = 0;
1832 2270 : for( SwFrm *pFrm = aIter.First(); pFrm; pFrm = aIter.Next() )
1833 : {
1834 : // append drawing object, if
1835 : // (1) proposed anchor frame isn't a follow and
1836 : // (2) drawing object isn't a control object to be anchored
1837 : // in header/footer.
1838 2368 : const bool bAdd = ( !pFrm->IsContentFrm() ||
1839 3548 : !static_cast<SwContentFrm*>(pFrm)->IsFollow() ) &&
1840 1414 : ( !::CheckControlLayer( GetMaster() ) ||
1841 1416 : !pFrm->FindFooterOrHeader() );
1842 :
1843 1184 : if( bAdd )
1844 : {
1845 1182 : if ( FLY_AT_FLY == pAnch->GetAnchorId() && !pFrm->IsFlyFrm() )
1846 : {
1847 9 : pFrm = pFrm->FindFlyFrm();
1848 : OSL_ENSURE( pFrm,
1849 : "<SwDrawContact::ConnectToLayout(..)> - missing fly frame -> crash." );
1850 : }
1851 :
1852 : // find correct follow for as character anchored objects
1853 1504 : if ((pAnch->GetAnchorId() == FLY_AS_CHAR) &&
1854 322 : pFrm->IsTextFrm() )
1855 : {
1856 : pFrm = lcl_GetFlyInContentAnchor(
1857 : static_cast<SwTextFrm*>(pFrm),
1858 322 : pAnch->GetContentAnchor()->nContent.GetIndex() );
1859 : }
1860 :
1861 1182 : if ( !pAnchorFrmOfMaster )
1862 : {
1863 : // append 'master' drawing object
1864 1039 : pAnchorFrmOfMaster = pFrm;
1865 1039 : pFrm->AppendDrawObj( maAnchoredDrawObj );
1866 : }
1867 : else
1868 : {
1869 : // append 'virtual' drawing object
1870 143 : SwDrawVirtObj* pDrawVirtObj = AddVirtObj();
1871 143 : if ( pAnch->GetAnchorId() == FLY_AS_CHAR )
1872 : {
1873 0 : ClrContourCache( pDrawVirtObj );
1874 : }
1875 143 : pFrm->AppendDrawObj( pDrawVirtObj->AnchoredObj() );
1876 :
1877 143 : pDrawVirtObj->ActionChanged();
1878 : }
1879 :
1880 1182 : if ( pAnch->GetAnchorId() == FLY_AS_CHAR )
1881 : {
1882 322 : pFrm->InvalidatePrt();
1883 : }
1884 : }
1885 1086 : }
1886 : }
1887 1086 : break;
1888 : default:
1889 : OSL_FAIL( "Unknown Anchor." );
1890 0 : break;
1891 : }
1892 1120 : if ( GetAnchorFrm() )
1893 : {
1894 1059 : ::setContextWritingMode( maAnchoredDrawObj.DrawObj(), GetAnchorFrm() );
1895 : // #i26791# - invalidate objects instead of direct positioning
1896 1059 : _InvalidateObjs();
1897 : }
1898 : }
1899 :
1900 : /// insert 'master' drawing object into drawing page
1901 0 : void SwDrawContact::InsertMasterIntoDrawPage()
1902 : {
1903 0 : if ( !GetMaster()->IsInserted() )
1904 : {
1905 0 : GetFormat()->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage(0)
1906 0 : ->InsertObject( GetMaster(), GetMaster()->GetOrdNumDirect() );
1907 : }
1908 0 : GetMaster()->SetUserCall( this );
1909 0 : }
1910 :
1911 1080 : SwPageFrm* SwDrawContact::FindPage( const SwRect &rRect )
1912 : {
1913 : // --> #i28701# - use method <GetPageFrm()>
1914 1080 : SwPageFrm* pPg = GetPageFrm();
1915 1080 : if ( !pPg && GetAnchorFrm() )
1916 0 : pPg = GetAnchorFrm()->FindPageFrm();
1917 1080 : if ( pPg )
1918 1080 : pPg = const_cast<SwPageFrm*>(static_cast<const SwPageFrm*>(::FindPage( rRect, pPg )));
1919 1080 : return pPg;
1920 : }
1921 :
1922 1116 : void SwDrawContact::ChkPage()
1923 : {
1924 1116 : if ( mbDisconnectInProgress )
1925 : {
1926 : OSL_FAIL( "<SwDrawContact::ChkPage()> called during disconnection." );
1927 1116 : return;
1928 : }
1929 :
1930 : // --> #i28701#
1931 2232 : SwPageFrm* pPg = ( maAnchoredDrawObj.GetAnchorFrm() &&
1932 1116 : maAnchoredDrawObj.GetAnchorFrm()->IsPageFrm() )
1933 : ? GetPageFrm()
1934 2268 : : FindPage( GetMaster()->GetCurrentBoundRect() );
1935 1116 : if ( GetPageFrm() != pPg )
1936 : {
1937 : // if drawing object is anchor in header/footer a change of the page
1938 : // is a dramatic change. Thus, completely re-connect to the layout
1939 0 : if ( maAnchoredDrawObj.GetAnchorFrm() &&
1940 0 : maAnchoredDrawObj.GetAnchorFrm()->FindFooterOrHeader() )
1941 : {
1942 0 : ConnectToLayout();
1943 : }
1944 : else
1945 : {
1946 : // --> #i28701# - use methods <GetPageFrm()> and <SetPageFrm>
1947 0 : if ( GetPageFrm() )
1948 0 : GetPageFrm()->RemoveDrawObjFromPage( maAnchoredDrawObj );
1949 0 : pPg->AppendDrawObjToPage( maAnchoredDrawObj );
1950 0 : SetPageFrm( pPg );
1951 : }
1952 : }
1953 : }
1954 :
1955 : // Important note:
1956 : // method is called by method <SwDPage::ReplaceObject(..)>, which called its
1957 : // corresponding superclass method <FmFormPage::ReplaceObject(..)>.
1958 : // Note: 'master' drawing object *has* to be connected to layout triggered
1959 : // by the caller of this, if method is called.
1960 0 : void SwDrawContact::ChangeMasterObject( SdrObject *pNewMaster )
1961 : {
1962 0 : DisconnectFromLayout( false );
1963 : // consider 'virtual' drawing objects
1964 0 : RemoveAllVirtObjs();
1965 :
1966 0 : GetMaster()->SetUserCall( 0 );
1967 0 : SetMaster( pNewMaster );
1968 0 : GetMaster()->SetUserCall( this );
1969 :
1970 0 : _InvalidateObjs();
1971 0 : }
1972 :
1973 : /// get data collection of anchored objects, handled by with contact
1974 14 : void SwDrawContact::GetAnchoredObjs( std::list<SwAnchoredObject*>& _roAnchoredObjs ) const
1975 : {
1976 14 : _roAnchoredObjs.push_back( const_cast<SwAnchoredDrawObject*>(&maAnchoredDrawObj) );
1977 :
1978 42 : for ( std::list<SwDrawVirtObj*>::const_iterator aDrawVirtObjsIter = maDrawVirtObjs.begin();
1979 28 : aDrawVirtObjsIter != maDrawVirtObjs.end();
1980 : ++aDrawVirtObjsIter )
1981 : {
1982 0 : _roAnchoredObjs.push_back( &(*aDrawVirtObjsIter)->AnchoredObj() );
1983 : }
1984 14 : }
1985 :
1986 : // AW: own sdr::contact::ViewContact (VC) sdr::contact::ViewObjectContact (VOC) needed
1987 : // since offset is defined different from SdrVirtObj's sdr::contact::ViewContactOfVirtObj.
1988 : // For paint, that offset is used by setting at the OutputDevice; for primitives this is
1989 : // not possible since we have no OutputDevice, but define the geometry itself.
1990 :
1991 : namespace sdr
1992 : {
1993 : namespace contact
1994 : {
1995 : class VOCOfDrawVirtObj : public ViewObjectContactOfSdrObj
1996 : {
1997 : protected:
1998 : /**
1999 : * This method is responsible for creating the graphical visualisation data which is
2000 : * stored/cached in the local primitive. Default gets view-independent Primitive from
2001 : * the ViewContact using ViewContact::getViewIndependentPrimitive2DSequence(), takes
2002 : * care of visibility, handles glue and ghosted.
2003 : *
2004 : * This method will not handle included hierarchies and not check geometric visibility.
2005 : */
2006 : virtual drawinglayer::primitive2d::Primitive2DSequence createPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const SAL_OVERRIDE;
2007 :
2008 : public:
2009 216 : VOCOfDrawVirtObj(ObjectContact& rObjectContact, ViewContact& rViewContact)
2010 216 : : ViewObjectContactOfSdrObj(rObjectContact, rViewContact)
2011 : {
2012 216 : }
2013 :
2014 : virtual ~VOCOfDrawVirtObj();
2015 : };
2016 :
2017 : class VCOfDrawVirtObj : public ViewContactOfVirtObj
2018 : {
2019 : protected:
2020 : /** Create a Object-Specific ViewObjectContact, set ViewContact and ObjectContact.
2021 : *
2022 : * Always needs to return something. Default is to create a standard ViewObjectContact
2023 : * containing the given ObjectContact and *this.
2024 : */
2025 : virtual ViewObjectContact& CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) SAL_OVERRIDE;
2026 :
2027 : public:
2028 : /// basic constructor, used from SdrObject.
2029 220 : explicit VCOfDrawVirtObj(SwDrawVirtObj& rObj)
2030 220 : : ViewContactOfVirtObj(rObj)
2031 : {
2032 220 : }
2033 : virtual ~VCOfDrawVirtObj();
2034 :
2035 : /// access to SwDrawVirtObj
2036 1264 : SwDrawVirtObj& GetSwDrawVirtObj() const
2037 : {
2038 1264 : return static_cast<SwDrawVirtObj&>(mrObject);
2039 : }
2040 : };
2041 : } // end of namespace contact
2042 : } // end of namespace sdr
2043 :
2044 : namespace sdr
2045 : {
2046 : namespace contact
2047 : {
2048 : /// recursively collect primitive data from given VOC with given offset
2049 0 : void impAddPrimitivesFromGroup(const ViewObjectContact& rVOC, const basegfx::B2DHomMatrix& rOffsetMatrix, const DisplayInfo& rDisplayInfo, drawinglayer::primitive2d::Primitive2DSequence& rxTarget)
2050 : {
2051 0 : const sal_uInt32 nSubHierarchyCount(rVOC.GetViewContact().GetObjectCount());
2052 :
2053 0 : for(sal_uInt32 a(0L); a < nSubHierarchyCount; a++)
2054 : {
2055 0 : const ViewObjectContact& rCandidate(rVOC.GetViewContact().GetViewContact(a).GetViewObjectContact(rVOC.GetObjectContact()));
2056 :
2057 0 : if(rCandidate.GetViewContact().GetObjectCount())
2058 : {
2059 : // is a group object itself, call resursively
2060 0 : impAddPrimitivesFromGroup(rCandidate, rOffsetMatrix, rDisplayInfo, rxTarget);
2061 : }
2062 : else
2063 : {
2064 : // single object, add primitives; check model-view visibility
2065 0 : if(rCandidate.isPrimitiveVisible(rDisplayInfo))
2066 : {
2067 0 : drawinglayer::primitive2d::Primitive2DSequence aNewSequence(rCandidate.getPrimitive2DSequence(rDisplayInfo));
2068 :
2069 0 : if(aNewSequence.hasElements())
2070 : {
2071 : // get ranges
2072 0 : const drawinglayer::geometry::ViewInformation2D& rViewInformation2D(rCandidate.GetObjectContact().getViewInformation2D());
2073 0 : const basegfx::B2DRange aViewRange(rViewInformation2D.getViewport());
2074 0 : basegfx::B2DRange aObjectRange(rCandidate.getObjectRange());
2075 :
2076 : // correct with virtual object's offset
2077 0 : aObjectRange.transform(rOffsetMatrix);
2078 :
2079 : // check geometrical visibility (with offset)
2080 0 : if(!aViewRange.overlaps(aObjectRange))
2081 : {
2082 : // not visible, release
2083 0 : aNewSequence.realloc(0);
2084 : }
2085 : }
2086 :
2087 0 : if(aNewSequence.hasElements())
2088 : {
2089 0 : drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rxTarget, aNewSequence);
2090 0 : }
2091 : }
2092 : }
2093 : }
2094 0 : }
2095 :
2096 632 : drawinglayer::primitive2d::Primitive2DSequence VOCOfDrawVirtObj::createPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const
2097 : {
2098 632 : const VCOfDrawVirtObj& rVC = static_cast< const VCOfDrawVirtObj& >(GetViewContact());
2099 632 : const SdrObject& rReferencedObject = rVC.GetSwDrawVirtObj().GetReferencedObj();
2100 632 : drawinglayer::primitive2d::Primitive2DSequence xRetval;
2101 :
2102 : // create offset transformation
2103 1264 : basegfx::B2DHomMatrix aOffsetMatrix;
2104 632 : const Point aLocalOffset(rVC.GetSwDrawVirtObj().GetOffset());
2105 :
2106 632 : if(aLocalOffset.X() || aLocalOffset.Y())
2107 : {
2108 632 : aOffsetMatrix.set(0, 2, aLocalOffset.X());
2109 632 : aOffsetMatrix.set(1, 2, aLocalOffset.Y());
2110 : }
2111 :
2112 632 : if(rReferencedObject.ISA(SdrObjGroup))
2113 : {
2114 : // group object. Since the VOC/OC/VC hierarchy does not represent the
2115 : // hierarchy virtual objects when they have group objects
2116 : // (ViewContactOfVirtObj::GetObjectCount() returns null for that purpose)
2117 : // to avoid multiple usages of VOCs (which would not work), the primitives
2118 : // for the sub-hierarchy need to be collected here
2119 :
2120 : // Get the VOC of the referenced object (the Group) and fetch primitives from it
2121 0 : const ViewObjectContact& rVOCOfRefObj = rReferencedObject.GetViewContact().GetViewObjectContact(GetObjectContact());
2122 0 : impAddPrimitivesFromGroup(rVOCOfRefObj, aOffsetMatrix, rDisplayInfo, xRetval);
2123 : }
2124 : else
2125 : {
2126 : // single object, use method from referenced object to get the Primitive2DSequence
2127 632 : xRetval = rReferencedObject.GetViewContact().getViewIndependentPrimitive2DSequence();
2128 : }
2129 :
2130 632 : if(xRetval.hasElements())
2131 : {
2132 : // create transform primitive
2133 632 : const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::TransformPrimitive2D(aOffsetMatrix, xRetval));
2134 632 : xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1);
2135 : }
2136 :
2137 1264 : return xRetval;
2138 : }
2139 :
2140 432 : VOCOfDrawVirtObj::~VOCOfDrawVirtObj()
2141 : {
2142 432 : }
2143 :
2144 216 : ViewObjectContact& VCOfDrawVirtObj::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact)
2145 : {
2146 216 : return *(new VOCOfDrawVirtObj(rObjectContact, *this));
2147 : }
2148 :
2149 440 : VCOfDrawVirtObj::~VCOfDrawVirtObj()
2150 : {
2151 440 : }
2152 : } // end of namespace contact
2153 : } // end of namespace sdr
2154 :
2155 : /// implementation of class <SwDrawVirtObj>
2156 219761 : TYPEINIT1(SwDrawVirtObj,SdrVirtObj);
2157 :
2158 220 : sdr::contact::ViewContact* SwDrawVirtObj::CreateObjectSpecificViewContact()
2159 : {
2160 220 : return new sdr::contact::VCOfDrawVirtObj(*this);
2161 : }
2162 :
2163 220 : SwDrawVirtObj::SwDrawVirtObj( SdrObject& _rNewObj,
2164 : SwDrawContact& _rDrawContact )
2165 : : SdrVirtObj( _rNewObj ),
2166 : // #i26791# - init new member <maAnchoredDrawObj>
2167 : maAnchoredDrawObj(),
2168 220 : mrDrawContact( _rDrawContact )
2169 : {
2170 : // #i26791#
2171 220 : maAnchoredDrawObj.SetDrawObj( *this );
2172 : // #i35635# - set initial position out of sight
2173 220 : NbcMove( Size( -RECT_EMPTY, -RECT_EMPTY ) );
2174 220 : }
2175 :
2176 440 : SwDrawVirtObj::~SwDrawVirtObj()
2177 440 : {}
2178 :
2179 0 : SwDrawVirtObj& SwDrawVirtObj::operator=( const SwDrawVirtObj& rObj )
2180 : {
2181 0 : SdrVirtObj::operator=(rObj);
2182 : // Note: Members <maAnchoredDrawObj> and <mrDrawContact>
2183 : // haven't to be considered.
2184 0 : return *this;
2185 : }
2186 :
2187 0 : SwDrawVirtObj* SwDrawVirtObj::Clone() const
2188 : {
2189 0 : SwDrawVirtObj* pObj = new SwDrawVirtObj( rRefObj, mrDrawContact );
2190 :
2191 0 : pObj->operator=( *this );
2192 : // Note: Member <maAnchoredDrawObj> hasn't to be considered.
2193 :
2194 0 : return pObj;
2195 : }
2196 :
2197 7382 : const SwFrm* SwDrawVirtObj::GetAnchorFrm() const
2198 : {
2199 : // #i26791# - use new member <maAnchoredDrawObj>
2200 7382 : return maAnchoredDrawObj.GetAnchorFrm();
2201 : }
2202 :
2203 335 : SwFrm* SwDrawVirtObj::AnchorFrm()
2204 : {
2205 : // #i26791# - use new member <maAnchoredDrawObj>
2206 335 : return maAnchoredDrawObj.AnchorFrm();
2207 : }
2208 :
2209 1023 : void SwDrawVirtObj::RemoveFromWriterLayout()
2210 : {
2211 : // remove contact object from frame for 'virtual' drawing object
2212 : // #i26791# - use new member <maAnchoredDrawObj>
2213 1023 : if ( maAnchoredDrawObj.GetAnchorFrm() )
2214 : {
2215 363 : maAnchoredDrawObj.AnchorFrm()->RemoveDrawObj( maAnchoredDrawObj );
2216 : }
2217 1023 : }
2218 :
2219 363 : void SwDrawVirtObj::AddToDrawingPage()
2220 : {
2221 : // determine 'master'
2222 363 : SdrObject* pOrgMasterSdrObj = mrDrawContact.GetMaster();
2223 :
2224 : // insert 'virtual' drawing object into page, set layer and user call.
2225 : SdrPage* pDrawPg;
2226 : // #i27030# - apply order number of referenced object
2227 363 : if ( 0 != ( pDrawPg = pOrgMasterSdrObj->GetPage() ) )
2228 : {
2229 : // #i27030# - apply order number of referenced object
2230 363 : pDrawPg->InsertObject( this, GetReferencedObj().GetOrdNum() );
2231 : }
2232 : else
2233 : {
2234 0 : pDrawPg = GetPage();
2235 0 : if ( pDrawPg )
2236 : {
2237 0 : pDrawPg->SetObjectOrdNum( GetOrdNumDirect(),
2238 0 : GetReferencedObj().GetOrdNum() );
2239 : }
2240 : else
2241 : {
2242 0 : SetOrdNum( GetReferencedObj().GetOrdNum() );
2243 : }
2244 : }
2245 363 : SetUserCall( &mrDrawContact );
2246 363 : }
2247 :
2248 1023 : void SwDrawVirtObj::RemoveFromDrawingPage()
2249 : {
2250 1023 : SetUserCall( 0 );
2251 1023 : if ( GetPage() )
2252 : {
2253 363 : GetPage()->RemoveObject( GetOrdNum() );
2254 : }
2255 1023 : }
2256 :
2257 : /// Is 'virtual' drawing object connected to writer layout and to drawing layer?
2258 4977 : bool SwDrawVirtObj::IsConnected() const
2259 : {
2260 12175 : bool bRetVal = GetAnchorFrm() &&
2261 12175 : ( GetPage() && GetUserCall() );
2262 :
2263 4977 : return bRetVal;
2264 : }
2265 :
2266 431 : void SwDrawVirtObj::NbcSetAnchorPos(const Point& rPnt)
2267 : {
2268 431 : SdrObject::NbcSetAnchorPos( rPnt );
2269 431 : }
2270 :
2271 : // #i97197#
2272 : // the methods relevant for positioning
2273 :
2274 1222 : const Rectangle& SwDrawVirtObj::GetCurrentBoundRect() const
2275 : {
2276 1222 : if(aOutRect.IsEmpty())
2277 : {
2278 220 : const_cast<SwDrawVirtObj*>(this)->RecalcBoundRect();
2279 : }
2280 :
2281 1222 : return aOutRect;
2282 : }
2283 :
2284 4746 : const Rectangle& SwDrawVirtObj::GetLastBoundRect() const
2285 : {
2286 4746 : return aOutRect;
2287 : }
2288 :
2289 38631 : const Point SwDrawVirtObj::GetOffset() const
2290 : {
2291 : // do NOT use IsEmpty() here, there is already a useful offset
2292 : // in the position
2293 38631 : if(aOutRect == Rectangle())
2294 : {
2295 0 : return Point();
2296 : }
2297 : else
2298 : {
2299 38631 : return aOutRect.TopLeft() - GetReferencedObj().GetCurrentBoundRect().TopLeft();
2300 : }
2301 : }
2302 :
2303 2305 : void SwDrawVirtObj::SetBoundRectDirty()
2304 : {
2305 : // do nothing to not lose model information in aOutRect
2306 2305 : }
2307 :
2308 220 : void SwDrawVirtObj::RecalcBoundRect()
2309 : {
2310 : // #i26791# - switch order of calling <GetOffset()> and
2311 : // <ReferencedObj().GetCurrentBoundRect()>, because <GetOffset()> calculates
2312 : // its value by the 'BoundRect' of the referenced object.
2313 :
2314 220 : const Point aOffset(GetOffset());
2315 220 : aOutRect = ReferencedObj().GetCurrentBoundRect() + aOffset;
2316 220 : }
2317 :
2318 0 : basegfx::B2DPolyPolygon SwDrawVirtObj::TakeXorPoly() const
2319 : {
2320 0 : basegfx::B2DPolyPolygon aRetval(rRefObj.TakeXorPoly());
2321 0 : aRetval.transform(basegfx::tools::createTranslateB2DHomMatrix(GetOffset().X(), GetOffset().Y()));
2322 :
2323 0 : return aRetval;
2324 : }
2325 :
2326 0 : basegfx::B2DPolyPolygon SwDrawVirtObj::TakeContour() const
2327 : {
2328 0 : basegfx::B2DPolyPolygon aRetval(rRefObj.TakeContour());
2329 0 : aRetval.transform(basegfx::tools::createTranslateB2DHomMatrix(GetOffset().X(), GetOffset().Y()));
2330 :
2331 0 : return aRetval;
2332 : }
2333 :
2334 0 : SdrHdl* SwDrawVirtObj::GetHdl(sal_uInt32 nHdlNum) const
2335 : {
2336 0 : SdrHdl* pHdl = rRefObj.GetHdl(nHdlNum);
2337 :
2338 0 : if(pHdl)
2339 : {
2340 0 : Point aP(pHdl->GetPos() + GetOffset());
2341 0 : pHdl->SetPos(aP);
2342 : }
2343 : else
2344 : {
2345 : OSL_ENSURE(false, "Got no SdrHdl(!)");
2346 : }
2347 :
2348 0 : return pHdl;
2349 : }
2350 :
2351 1733 : void SwDrawVirtObj::NbcMove(const Size& rSiz)
2352 : {
2353 1733 : SdrObject::NbcMove( rSiz );
2354 1733 : }
2355 :
2356 0 : void SwDrawVirtObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
2357 : {
2358 0 : rRefObj.NbcResize(rRef - GetOffset(), xFact, yFact);
2359 0 : SetRectsDirty();
2360 0 : }
2361 :
2362 0 : void SwDrawVirtObj::NbcRotate(const Point& rRef, long nAngle, double sn, double cs)
2363 : {
2364 0 : rRefObj.NbcRotate(rRef - GetOffset(), nAngle, sn, cs);
2365 0 : SetRectsDirty();
2366 0 : }
2367 :
2368 0 : void SwDrawVirtObj::NbcMirror(const Point& rRef1, const Point& rRef2)
2369 : {
2370 0 : rRefObj.NbcMirror(rRef1 - GetOffset(), rRef2 - GetOffset());
2371 0 : SetRectsDirty();
2372 0 : }
2373 :
2374 0 : void SwDrawVirtObj::NbcShear(const Point& rRef, long nAngle, double tn, bool bVShear)
2375 : {
2376 0 : rRefObj.NbcShear(rRef - GetOffset(), nAngle, tn, bVShear);
2377 0 : SetRectsDirty();
2378 0 : }
2379 :
2380 3347 : void SwDrawVirtObj::Move(const Size& rSiz)
2381 : {
2382 3347 : SdrObject::Move( rSiz );
2383 3347 : }
2384 :
2385 0 : void SwDrawVirtObj::Resize(const Point& rRef, const Fraction& xFact, const Fraction& yFact, bool bUnsetRelative)
2386 : {
2387 0 : if(xFact.GetNumerator() != xFact.GetDenominator() || yFact.GetNumerator() != yFact.GetDenominator())
2388 : {
2389 0 : Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
2390 0 : rRefObj.Resize(rRef - GetOffset(), xFact, yFact, bUnsetRelative);
2391 0 : SetRectsDirty();
2392 0 : SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
2393 : }
2394 0 : }
2395 :
2396 0 : void SwDrawVirtObj::Rotate(const Point& rRef, long nAngle, double sn, double cs)
2397 : {
2398 0 : if(nAngle)
2399 : {
2400 0 : Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
2401 0 : rRefObj.Rotate(rRef - GetOffset(), nAngle, sn, cs);
2402 0 : SetRectsDirty();
2403 0 : SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
2404 : }
2405 0 : }
2406 :
2407 0 : void SwDrawVirtObj::Mirror(const Point& rRef1, const Point& rRef2)
2408 : {
2409 0 : Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
2410 0 : rRefObj.Mirror(rRef1 - GetOffset(), rRef2 - GetOffset());
2411 0 : SetRectsDirty();
2412 0 : SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
2413 0 : }
2414 :
2415 0 : void SwDrawVirtObj::Shear(const Point& rRef, long nAngle, double tn, bool bVShear)
2416 : {
2417 0 : if(nAngle)
2418 : {
2419 0 : Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
2420 0 : rRefObj.Shear(rRef - GetOffset(), nAngle, tn, bVShear);
2421 0 : SetRectsDirty();
2422 0 : SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
2423 : }
2424 0 : }
2425 :
2426 0 : void SwDrawVirtObj::RecalcSnapRect()
2427 : {
2428 0 : aSnapRect = rRefObj.GetSnapRect();
2429 0 : aSnapRect += GetOffset();
2430 0 : }
2431 :
2432 37779 : const Rectangle& SwDrawVirtObj::GetSnapRect() const
2433 : {
2434 37779 : const_cast<SwDrawVirtObj*>(this)->aSnapRect = rRefObj.GetSnapRect();
2435 37779 : const_cast<SwDrawVirtObj*>(this)->aSnapRect += GetOffset();
2436 :
2437 37779 : return aSnapRect;
2438 : }
2439 :
2440 0 : void SwDrawVirtObj::SetSnapRect(const Rectangle& rRect)
2441 : {
2442 0 : Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
2443 0 : Rectangle aR(rRect);
2444 0 : aR -= GetOffset();
2445 0 : rRefObj.SetSnapRect(aR);
2446 0 : SetRectsDirty();
2447 0 : SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
2448 0 : }
2449 :
2450 0 : void SwDrawVirtObj::NbcSetSnapRect(const Rectangle& rRect)
2451 : {
2452 0 : Rectangle aR(rRect);
2453 0 : aR -= GetOffset();
2454 0 : SetRectsDirty();
2455 0 : rRefObj.NbcSetSnapRect(aR);
2456 0 : }
2457 :
2458 0 : const Rectangle& SwDrawVirtObj::GetLogicRect() const
2459 : {
2460 0 : const_cast<SwDrawVirtObj*>(this)->aSnapRect = rRefObj.GetLogicRect();
2461 0 : const_cast<SwDrawVirtObj*>(this)->aSnapRect += GetOffset();
2462 :
2463 0 : return aSnapRect;
2464 : }
2465 :
2466 0 : void SwDrawVirtObj::SetLogicRect(const Rectangle& rRect)
2467 : {
2468 0 : Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
2469 0 : Rectangle aR(rRect);
2470 0 : aR -= GetOffset();
2471 0 : rRefObj.SetLogicRect(aR);
2472 0 : SetRectsDirty();
2473 0 : SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
2474 0 : }
2475 :
2476 0 : void SwDrawVirtObj::NbcSetLogicRect(const Rectangle& rRect)
2477 : {
2478 0 : Rectangle aR(rRect);
2479 0 : aR -= GetOffset();
2480 0 : rRefObj.NbcSetLogicRect(aR);
2481 0 : SetRectsDirty();
2482 0 : }
2483 :
2484 0 : Point SwDrawVirtObj::GetSnapPoint(sal_uInt32 i) const
2485 : {
2486 0 : Point aP(rRefObj.GetSnapPoint(i));
2487 0 : aP += GetOffset();
2488 :
2489 0 : return aP;
2490 : }
2491 :
2492 0 : Point SwDrawVirtObj::GetPoint(sal_uInt32 i) const
2493 : {
2494 0 : return Point(rRefObj.GetPoint(i) + GetOffset());
2495 : }
2496 :
2497 0 : void SwDrawVirtObj::NbcSetPoint(const Point& rPnt, sal_uInt32 i)
2498 : {
2499 0 : Point aP(rPnt);
2500 0 : aP -= GetOffset();
2501 0 : rRefObj.SetPoint(aP, i);
2502 0 : SetRectsDirty();
2503 0 : }
2504 :
2505 0 : bool SwDrawVirtObj::HasTextEdit() const
2506 : {
2507 0 : return rRefObj.HasTextEdit();
2508 : }
2509 :
2510 : // override 'layer' methods for 'virtual' drawing object to assure
2511 : // that layer of 'virtual' object is the layer of the referenced object.
2512 20431 : SdrLayerID SwDrawVirtObj::GetLayer() const
2513 : {
2514 20431 : return GetReferencedObj().GetLayer();
2515 : }
2516 :
2517 0 : void SwDrawVirtObj::NbcSetLayer(SdrLayerID nLayer)
2518 : {
2519 0 : ReferencedObj().NbcSetLayer( nLayer );
2520 0 : SdrVirtObj::NbcSetLayer( ReferencedObj().GetLayer() );
2521 0 : }
2522 :
2523 0 : void SwDrawVirtObj::SetLayer(SdrLayerID nLayer)
2524 : {
2525 0 : ReferencedObj().SetLayer( nLayer );
2526 0 : SdrVirtObj::NbcSetLayer( ReferencedObj().GetLayer() );
2527 0 : }
2528 :
2529 0 : bool SwDrawVirtObj::supportsFullDrag() const
2530 : {
2531 : // call parent
2532 0 : return SdrVirtObj::supportsFullDrag();
2533 : }
2534 :
2535 0 : SdrObject* SwDrawVirtObj::getFullDragClone() const
2536 : {
2537 : // call parent
2538 0 : return SdrVirtObj::getFullDragClone();
2539 177 : }
2540 :
2541 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|