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 <switerator.hxx>
70 : #include <algorithm>
71 : #include <txtfly.hxx>
72 :
73 : using namespace ::com::sun::star;
74 :
75 423320 : TYPEINIT1( SwContact, SwClient )
76 212586 : TYPEINIT1( SwFlyDrawContact, SwContact )
77 382348 : TYPEINIT1( SwDrawContact, SwContact )
78 :
79 5080 : void setContextWritingMode( SdrObject* pObj, SwFrm* pAnchor )
80 : {
81 5080 : if( pObj && pAnchor )
82 : {
83 5080 : short nWritingDirection = text::WritingMode2::LR_TB;
84 5080 : if( pAnchor->IsVertical() )
85 : {
86 4 : nWritingDirection = text::WritingMode2::TB_RL;
87 5076 : } else if( pAnchor->IsRightToLeft() )
88 : {
89 0 : nWritingDirection = text::WritingMode2::RL_TB;
90 : }
91 5080 : pObj->SetContextWritingMode( nWritingDirection );
92 : }
93 5080 : }
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 42647 : SwFrmFmt *FindFrmFmt( SdrObject *pObj )
102 : {
103 42647 : SwFrmFmt* pRetval = 0L;
104 :
105 42647 : if ( pObj->ISA(SwVirtFlyDrawObj) )
106 : {
107 8709 : pRetval = ((SwVirtFlyDrawObj*)pObj)->GetFmt();
108 : }
109 : else
110 : {
111 33938 : SwDrawContact* pContact = static_cast<SwDrawContact*>(GetUserCall( pObj ));
112 33938 : if ( pContact )
113 : {
114 29792 : pRetval = pContact->GetFmt();
115 : }
116 : }
117 42647 : return pRetval;
118 : }
119 :
120 3990 : bool HasWrap( const SdrObject* pObj )
121 : {
122 3990 : if ( pObj )
123 : {
124 3990 : const SwFrmFmt* pFmt = ::FindFrmFmt( pObj );
125 3990 : if ( pFmt )
126 : {
127 3990 : return SURROUND_THROUGHT != pFmt->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 1612544 : SwContact* GetUserCall( const SdrObject* pObj )
153 : {
154 : SdrObject *pTmp;
155 3228816 : while ( !pObj->GetUserCall() && 0 != (pTmp = pObj->GetUpGroup()) )
156 3728 : pObj = pTmp;
157 : OSL_ENSURE( !pObj->GetUserCall() || pObj->GetUserCall()->ISA(SwContact),
158 : "<::GetUserCall(..)> - wrong type of found object user call." );
159 1612544 : return static_cast<SwContact*>(pObj->GetUserCall());
160 : }
161 :
162 : /// Returns sal_True if the SrdObject is a Marquee-Object (scrolling text)
163 16 : bool IsMarqueeTextObj( const SdrObject& rObj )
164 : {
165 : SdrTextAniKind eTKind;
166 16 : return SdrInventor == rObj.GetObjInventor() &&
167 16 : OBJ_TEXT == rObj.GetObjIdentifier() &&
168 : ( SDRTEXTANI_SCROLL == ( eTKind = ((SdrTextObj&)rObj).GetTextAniKind())
169 16 : || SDRTEXTANI_ALTERNATE == eTKind || SDRTEXTANI_SLIDE == eTKind );
170 : }
171 :
172 8386 : SwContact::SwContact( SwFrmFmt *pToRegisterIn ) :
173 : SwClient( pToRegisterIn ),
174 8386 : mbInDTOR( false )
175 8386 : {}
176 :
177 16768 : SwContact::~SwContact()
178 : {
179 8384 : SetInDTOR();
180 8384 : }
181 :
182 :
183 12852 : void SwContact::SetInDTOR()
184 : {
185 12852 : mbInDTOR = true;
186 12852 : }
187 :
188 : /// method to move drawing object to corresponding visible layer
189 80310 : void SwContact::MoveObjToVisibleLayer( SdrObject* _pDrawObj )
190 : {
191 : // #i46297# - notify background about the arriving of
192 : // the object and invalidate its position.
193 80310 : const bool bNotify( !GetFmt()->getIDocumentDrawModelAccess()->IsVisibleLayerId( _pDrawObj->GetLayer() ) );
194 :
195 80310 : _MoveObjToLayer( true, _pDrawObj );
196 :
197 : // #i46297#
198 80310 : if ( bNotify )
199 : {
200 3000 : SwAnchoredObject* pAnchoredObj = GetAnchoredObj( _pDrawObj );
201 : OSL_ENSURE( pAnchoredObj,
202 : "<SwContact::MoveObjToInvisibleLayer(..)> - missing anchored object" );
203 3000 : if ( pAnchoredObj )
204 : {
205 3000 : ::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 3000 : if ( pAnchoredObj->GetPageFrm() )
209 : {
210 : ::Notify_Background( _pDrawObj, pAnchoredObj->GetPageFrm(),
211 2056 : pAnchoredObj->GetObjRect(), PREP_FLY_ARRIVE, true );
212 : }
213 :
214 3000 : pAnchoredObj->InvalidateObjPos();
215 : }
216 : }
217 80310 : }
218 :
219 : /// method to move drawing object to corresponding invisible layer - #i18447#
220 15186 : void SwContact::MoveObjToInvisibleLayer( SdrObject* _pDrawObj )
221 : {
222 : // #i46297# - notify background about the leaving of the object.
223 15186 : const bool bNotify( GetFmt()->getIDocumentDrawModelAccess()->IsVisibleLayerId( _pDrawObj->GetLayer() ) );
224 :
225 15186 : _MoveObjToLayer( false, _pDrawObj );
226 :
227 : // #i46297#
228 15186 : if ( bNotify )
229 : {
230 3006 : 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 3006 : if ( pAnchoredObj && pAnchoredObj->GetPageFrm() )
236 : {
237 : ::Notify_Background( _pDrawObj, pAnchoredObj->GetPageFrm(),
238 0 : pAnchoredObj->GetObjRect(), PREP_FLY_LEAVE, true );
239 : }
240 : }
241 15186 : }
242 :
243 : /** method to move object to visible/invisible layer - #i18447#
244 :
245 : implementation for the public method <MoveObjToVisibleLayer(..)>
246 : and <MoveObjToInvisibleLayer(..)>
247 : */
248 175468 : void SwContact::_MoveObjToLayer( const bool _bToVisible,
249 : SdrObject* _pDrawObj )
250 : {
251 175468 : if ( !_pDrawObj )
252 : {
253 : OSL_FAIL( "SwDrawContact::_MoveObjToLayer(..) - no drawing object!" );
254 0 : return;
255 : }
256 :
257 175468 : if ( !GetRegisteredIn() )
258 : {
259 : OSL_FAIL( "SwDrawContact::_MoveObjToLayer(..) - no drawing frame format!" );
260 0 : return;
261 : }
262 :
263 175468 : const IDocumentDrawModelAccess* pIDDMA = static_cast<SwFrmFmt*>(GetRegisteredInNonConst())->getIDocumentDrawModelAccess();
264 175468 : if ( !pIDDMA )
265 : {
266 : OSL_FAIL( "SwDrawContact::_MoveObjToLayer(..) - no writer document!" );
267 0 : return;
268 : }
269 :
270 : SdrLayerID nToHellLayerId =
271 175468 : _bToVisible ? pIDDMA->GetHellId() : pIDDMA->GetInvisibleHellId();
272 : SdrLayerID nToHeavenLayerId =
273 175468 : _bToVisible ? pIDDMA->GetHeavenId() : pIDDMA->GetInvisibleHeavenId();
274 : SdrLayerID nToControlLayerId =
275 175468 : _bToVisible ? pIDDMA->GetControlsId() : pIDDMA->GetInvisibleControlsId();
276 : SdrLayerID nFromHellLayerId =
277 175468 : _bToVisible ? pIDDMA->GetInvisibleHellId() : pIDDMA->GetHellId();
278 : SdrLayerID nFromHeavenLayerId =
279 175468 : _bToVisible ? pIDDMA->GetInvisibleHeavenId() : pIDDMA->GetHeavenId();
280 : SdrLayerID nFromControlLayerId =
281 175468 : _bToVisible ? pIDDMA->GetInvisibleControlsId() : pIDDMA->GetControlsId();
282 :
283 175468 : if ( _pDrawObj->ISA( SdrObjGroup ) )
284 : {
285 : // determine layer for group object
286 : {
287 : // proposed layer of a group object is the hell layer
288 3534 : SdrLayerID nNewLayerId = nToHellLayerId;
289 3534 : 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 6456 : else if ( _pDrawObj->GetLayer() == pIDDMA->GetHeavenId() ||
296 2922 : _pDrawObj->GetLayer() == pIDDMA->GetInvisibleHeavenId() )
297 : {
298 : // it has to be the heaven layer, if method <GetLayer()> reveals
299 : // a heaven layer
300 1428 : 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 3534 : _pDrawObj->SdrObject::NbcSetLayer( nNewLayerId );
306 : }
307 :
308 : // call method recursively for group object members
309 : const SdrObjList* pLst =
310 3534 : static_cast<SdrObjGroup*>(_pDrawObj)->GetSubList();
311 3534 : if ( pLst )
312 : {
313 83506 : for ( size_t i = 0; i < pLst->GetObjCount(); ++i )
314 : {
315 79972 : _MoveObjToLayer( _bToVisible, pLst->GetObj( i ) );
316 : }
317 : }
318 : }
319 : else
320 : {
321 171934 : const SdrLayerID nLayerIdOfObj = _pDrawObj->GetLayer();
322 171934 : if ( nLayerIdOfObj == nFromHellLayerId )
323 : {
324 3406 : _pDrawObj->SetLayer( nToHellLayerId );
325 : }
326 168528 : else if ( nLayerIdOfObj == nFromHeavenLayerId )
327 : {
328 5072 : _pDrawObj->SetLayer( nToHeavenLayerId );
329 : }
330 163456 : else if ( nLayerIdOfObj == nFromControlLayerId )
331 : {
332 1088 : _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 5984 : const SwIndex& SwContact::GetCntntAnchorIndex() const
341 : {
342 5984 : return GetCntntAnchor().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 3916 : SwFlyDrawContact::SwFlyDrawContact( SwFlyFrmFmt *pToRegisterIn, SdrModel * ) :
394 3916 : SwContact( pToRegisterIn )
395 : {
396 : // #i26791# - class <SwFlyDrawContact> contains the 'master'
397 : // drawing object of type <SwFlyDrawObj> on its own.
398 3916 : mpMasterObj = new SwFlyDrawObj;
399 3916 : mpMasterObj->SetOrdNum( 0xFFFFFFFE );
400 3916 : mpMasterObj->SetUserCall( this );
401 3916 : }
402 :
403 11748 : SwFlyDrawContact::~SwFlyDrawContact()
404 : {
405 3916 : if ( mpMasterObj )
406 : {
407 3916 : mpMasterObj->SetUserCall( 0 );
408 3916 : if ( mpMasterObj->GetPage() )
409 824 : mpMasterObj->GetPage()->RemoveObject( mpMasterObj->GetOrdNum() );
410 3916 : delete mpMasterObj;
411 : }
412 7832 : }
413 :
414 : // #i26791#
415 28 : 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 ) == const_cast<SwFlyDrawContact*>(this),
422 : "<SwFlyDrawContact::GetAnchoredObj(..)> - provided object doesn't belongs to this contact" );
423 :
424 28 : const SwAnchoredObject* pRetAnchoredObj = 0L;
425 :
426 28 : if ( _pSdrObj && _pSdrObj->ISA(SwVirtFlyDrawObj) )
427 : {
428 28 : pRetAnchoredObj = static_cast<const SwVirtFlyDrawObj*>(_pSdrObj)->GetFlyFrm();
429 : }
430 :
431 28 : return pRetAnchoredObj;
432 : }
433 :
434 21938 : 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 21938 : SwAnchoredObject* pRetAnchoredObj = 0L;
444 :
445 21938 : if ( _pSdrObj && _pSdrObj->ISA(SwVirtFlyDrawObj) )
446 : {
447 21938 : pRetAnchoredObj = static_cast<SwVirtFlyDrawObj*>(_pSdrObj)->GetFlyFrm();
448 : }
449 :
450 21938 : return pRetAnchoredObj;
451 : }
452 :
453 1300 : const SdrObject* SwFlyDrawContact::GetMaster() const
454 : {
455 1300 : return mpMasterObj;
456 : }
457 :
458 24446 : SdrObject* SwFlyDrawContact::GetMaster()
459 : {
460 24446 : 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 22044 : void SwFlyDrawContact::Modify( const SfxPoolItem*, const SfxPoolItem * )
471 : {
472 22044 : }
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 42936 : void SwFlyDrawContact::MoveObjToVisibleLayer( SdrObject* _pDrawObj )
480 : {
481 : OSL_ENSURE( _pDrawObj->ISA(SwVirtFlyDrawObj),
482 : "<SwFlyDrawContact::MoveObjToVisibleLayer(..)> - wrong SdrObject type -> crash" );
483 :
484 42936 : if ( GetFmt()->getIDocumentDrawModelAccess()->IsVisibleLayerId( _pDrawObj->GetLayer() ) )
485 : {
486 : // nothing to do
487 85872 : 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 ( !GetFmt()->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 16 : void SwFlyDrawContact::GetAnchoredObjs( std::list<SwAnchoredObject*>& _roAnchoredObjs ) const
552 : {
553 16 : const SwFrmFmt* pFmt = GetFmt();
554 16 : SwFlyFrm::GetAnchoredObjects( _roAnchoredObjs, *pFmt );
555 16 : }
556 :
557 : // SwDrawContact
558 :
559 192886 : bool CheckControlLayer( const SdrObject *pObj )
560 : {
561 192886 : if ( FmFormInventor == pObj->GetObjInventor() )
562 2084 : return true;
563 190802 : if ( pObj->ISA( SdrObjGroup ) )
564 : {
565 7820 : const SdrObjList *pLst = ((SdrObjGroup*)pObj)->GetSubList();
566 181654 : for ( size_t i = 0; i < pLst->GetObjCount(); ++i )
567 : {
568 173834 : if ( ::CheckControlLayer( pLst->GetObj( i ) ) )
569 : {
570 : // #i18447# - return correct value ;-)
571 0 : return true;
572 : }
573 : }
574 : }
575 190802 : return false;
576 : }
577 :
578 4470 : SwDrawContact::SwDrawContact( SwFrmFmt* 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 sal_False.
586 4470 : meEventTypeOfCurrentUserCall( SDRUSERCALL_MOVEONLY )
587 : {
588 : // clear list containing 'virtual' drawing objects.
589 4470 : maDrawVirtObjs.clear();
590 :
591 : // --> #i33909# - assure, that drawing object is inserted
592 : // in the drawing page.
593 4470 : if ( !pObj->IsInserted() )
594 : {
595 18 : pToRegisterIn->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage(0)->
596 18 : 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 4470 : if ( ::CheckControlLayer( pObj ) )
602 : {
603 : // set layer of object to corresponding invisible layer.
604 544 : pObj->SetLayer( pToRegisterIn->getIDocumentDrawModelAccess()->GetInvisibleControlsId() );
605 : }
606 :
607 : // #i26791#
608 4470 : pObj->SetUserCall( this );
609 4470 : 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 4470 : SwXShape::AddExistingShapeToFmt( *pObj );
614 4470 : }
615 :
616 13404 : SwDrawContact::~SwDrawContact()
617 : {
618 4468 : SetInDTOR();
619 :
620 4468 : DisconnectFromLayout();
621 :
622 : // remove 'master' from drawing page
623 4468 : RemoveMasterFromDrawPage();
624 :
625 : // remove and destroy 'virtual' drawing objects.
626 4468 : RemoveAllVirtObjs();
627 :
628 4468 : if ( !mbMasterObjCleared )
629 : {
630 4466 : SdrObject* pObject = const_cast< SdrObject* >( maAnchoredDrawObj.GetDrawObj() );
631 4466 : SdrObject::Free( pObject );
632 : }
633 8936 : }
634 :
635 0 : void SwDrawContact::GetTextObjectsFromFmt( std::list<SdrTextObj*>& rTextObjects, SwDoc* pDoc )
636 : {
637 0 : for( sal_Int32 n=0; n<(sal_Int32)pDoc->GetSpzFrmFmts()->size(); n++ )
638 : {
639 0 : SwFrmFmt* pFly = (*pDoc->GetSpzFrmFmts())[n];
640 0 : if( pFly->IsA( TYPE(SwDrawFrmFmt) ) )
641 : {
642 0 : SwDrawContact* pContact = SwIterator<SwDrawContact,SwFrmFmt>::FirstElement(*pFly);
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((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((SdrTextObj*) pSdrO);
666 : }
667 : }
668 : }
669 : }
670 : }
671 0 : }
672 :
673 : // #i26791#
674 83548 : const SwAnchoredObject* SwDrawContact::GetAnchoredObj( const SdrObject* _pSdrObj ) const
675 : {
676 : // handle default parameter value
677 83548 : 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 ) == const_cast<SwDrawContact*>(this) ||
688 : _pSdrObj == GetMaster(),
689 : "<SwDrawContact::GetAnchoredObj(..)> - provided object doesn't belongs to this contact" );
690 :
691 83548 : const SwAnchoredObject* pRetAnchoredObj = 0L;
692 :
693 83548 : if ( _pSdrObj )
694 : {
695 83548 : if ( _pSdrObj->ISA(SwDrawVirtObj) )
696 : {
697 3472 : pRetAnchoredObj = &(static_cast<const SwDrawVirtObj*>(_pSdrObj)->GetAnchoredObj());
698 : }
699 80076 : else if ( !_pSdrObj->ISA(SdrVirtObj) && !_pSdrObj->ISA(SwDrawVirtObj) )
700 : {
701 80076 : pRetAnchoredObj = &maAnchoredDrawObj;
702 : }
703 : }
704 :
705 83548 : return pRetAnchoredObj;
706 : }
707 :
708 58546 : SwAnchoredObject* SwDrawContact::GetAnchoredObj( SdrObject* _pSdrObj )
709 : {
710 : // handle default parameter value
711 58546 : if ( !_pSdrObj )
712 : {
713 34104 : _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 58546 : SwAnchoredObject* pRetAnchoredObj = 0L;
725 :
726 58546 : if ( _pSdrObj )
727 : {
728 58546 : if ( _pSdrObj->ISA(SwDrawVirtObj) )
729 : {
730 1746 : pRetAnchoredObj = &(static_cast<SwDrawVirtObj*>(_pSdrObj)->AnchoredObj());
731 : }
732 56800 : else if ( !_pSdrObj->ISA(SdrVirtObj) && !_pSdrObj->ISA(SwDrawVirtObj) )
733 : {
734 56800 : pRetAnchoredObj = &maAnchoredDrawObj;
735 : }
736 : }
737 :
738 58546 : return pRetAnchoredObj;
739 : }
740 :
741 29738 : const SdrObject* SwDrawContact::GetMaster() const
742 : {
743 29738 : return !mbMasterObjCleared
744 29738 : ? maAnchoredDrawObj.GetDrawObj()
745 59476 : : 0L;
746 : }
747 :
748 177747 : SdrObject* SwDrawContact::GetMaster()
749 : {
750 177747 : return !mbMasterObjCleared
751 177743 : ? maAnchoredDrawObj.DrawObj()
752 355490 : : 0L;
753 : }
754 :
755 : /**
756 : * @note Overloading <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 2 : void SwDrawContact::SetMaster( SdrObject* _pNewMaster )
762 : {
763 2 : if ( _pNewMaster )
764 : {
765 : OSL_FAIL( "debug notification - master replaced!" );
766 0 : maAnchoredDrawObj.SetDrawObj( *_pNewMaster );
767 : }
768 : else
769 : {
770 2 : mbMasterObjCleared = true;
771 : }
772 2 : }
773 :
774 29046 : const SwFrm* SwDrawContact::GetAnchorFrm( const SdrObject* _pDrawObj ) const
775 : {
776 29046 : const SwFrm* pAnchorFrm = 0L;
777 58092 : if ( !_pDrawObj ||
778 58092 : _pDrawObj == GetMaster() ||
779 0 : ( !_pDrawObj->GetUserCall() &&
780 0 : GetUserCall( _pDrawObj ) == static_cast<const SwContact* const>(this) ) )
781 : {
782 29046 : 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 29046 : return pAnchorFrm;
794 : }
795 47454 : SwFrm* SwDrawContact::GetAnchorFrm( SdrObject* _pDrawObj )
796 : {
797 47454 : SwFrm* pAnchorFrm = 0L;
798 49715 : if ( !_pDrawObj ||
799 94956 : _pDrawObj == GetMaster() ||
800 592 : ( !_pDrawObj->GetUserCall() &&
801 48 : GetUserCall( _pDrawObj ) == this ) )
802 : {
803 46958 : pAnchorFrm = maAnchoredDrawObj.AnchorFrm();
804 : }
805 : else
806 : {
807 : OSL_ENSURE( _pDrawObj->ISA(SwDrawVirtObj),
808 : "<SwDrawContact::GetAnchorFrm(..)> - unknown drawing object." );
809 496 : pAnchorFrm = static_cast<SwDrawVirtObj*>(_pDrawObj)->AnchorFrm();
810 : }
811 :
812 47454 : return pAnchorFrm;
813 : }
814 :
815 : /// create a new 'virtual' drawing object.
816 426 : SwDrawVirtObj* SwDrawContact::CreateVirtObj()
817 : {
818 : // determine 'master'
819 426 : SdrObject* pOrgMasterSdrObj = GetMaster();
820 :
821 : // create 'virtual' drawing object
822 426 : SwDrawVirtObj* pNewDrawVirtObj = new SwDrawVirtObj ( *(pOrgMasterSdrObj), *(this) );
823 :
824 : // add new 'virtual' drawing object managing data structure
825 426 : maDrawVirtObjs.push_back( pNewDrawVirtObj );
826 :
827 426 : 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 426 : void SwDrawContact::DestroyVirtObj( SwDrawVirtObj* _pVirtObj )
836 : {
837 426 : if ( _pVirtObj )
838 : {
839 426 : delete _pVirtObj;
840 426 : _pVirtObj = 0;
841 : }
842 426 : }
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 698 : SwDrawVirtObj* SwDrawContact::AddVirtObj()
849 : {
850 698 : 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 698 : UsedOrUnusedVirtObjPred( false ) );
856 :
857 698 : if ( aFoundVirtObjIter != maDrawVirtObjs.end() )
858 : {
859 : // use already created, disconnected 'virtual' drawing object
860 272 : pAddedDrawVirtObj = (*aFoundVirtObjIter);
861 : }
862 : else
863 : {
864 : // create new 'virtual' drawing object.
865 426 : pAddedDrawVirtObj = CreateVirtObj();
866 : }
867 698 : pAddedDrawVirtObj->AddToDrawingPage();
868 :
869 698 : return pAddedDrawVirtObj;
870 : }
871 :
872 : /// remove 'virtual' drawing objects and destroy them.
873 4468 : void SwDrawContact::RemoveAllVirtObjs()
874 : {
875 14682 : for ( std::list<SwDrawVirtObj*>::iterator aDrawVirtObjsIter = maDrawVirtObjs.begin();
876 9788 : aDrawVirtObjsIter != maDrawVirtObjs.end();
877 : ++aDrawVirtObjsIter )
878 : {
879 : // remove and destroy 'virtual object'
880 426 : SwDrawVirtObj* pDrawVirtObj = (*aDrawVirtObjsIter);
881 426 : pDrawVirtObj->RemoveFromWriterLayout();
882 426 : pDrawVirtObj->RemoveFromDrawingPage();
883 426 : DestroyVirtObj( pDrawVirtObj );
884 : }
885 4468 : maDrawVirtObjs.clear();
886 4468 : }
887 :
888 426 : SwDrawContact::VirtObjAnchoredAtFrmPred::VirtObjAnchoredAtFrmPred(
889 : const SwFrm& _rAnchorFrm )
890 426 : : mpAnchorFrm( &_rAnchorFrm )
891 : {
892 426 : if ( mpAnchorFrm->IsCntntFrm() )
893 : {
894 : const SwCntntFrm* pTmpFrm =
895 426 : static_cast<const SwCntntFrm*>( mpAnchorFrm );
896 852 : while ( pTmpFrm->IsFollow() )
897 : {
898 0 : pTmpFrm = pTmpFrm->FindMaster();
899 : }
900 426 : mpAnchorFrm = pTmpFrm;
901 : }
902 426 : }
903 :
904 : // #i26791# - compare with master frame
905 4328 : bool SwDrawContact::VirtObjAnchoredAtFrmPred::operator() ( const SwDrawVirtObj* _pDrawVirtObj )
906 : {
907 4328 : const SwFrm* pObjAnchorFrm = _pDrawVirtObj->GetAnchorFrm();
908 4328 : if ( pObjAnchorFrm && pObjAnchorFrm->IsCntntFrm() )
909 : {
910 : const SwCntntFrm* pTmpFrm =
911 4328 : static_cast<const SwCntntFrm*>( pObjAnchorFrm );
912 8656 : while ( pTmpFrm->IsFollow() )
913 : {
914 0 : pTmpFrm = pTmpFrm->FindMaster();
915 : }
916 4328 : pObjAnchorFrm = pTmpFrm;
917 : }
918 :
919 4328 : return ( pObjAnchorFrm == mpAnchorFrm );
920 : }
921 :
922 : /// get drawing object ('master' or 'virtual') by frame.
923 5086 : SdrObject* SwDrawContact::GetDrawObjectByAnchorFrm( const SwFrm& _rAnchorFrm )
924 : {
925 5086 : SdrObject* pRetDrawObj = 0L;
926 :
927 : // #i26791# - compare master frames instead of direct frames
928 5086 : const SwFrm* pProposedAnchorFrm = &_rAnchorFrm;
929 5086 : if ( pProposedAnchorFrm->IsCntntFrm() )
930 : {
931 : const SwCntntFrm* pTmpFrm =
932 5086 : static_cast<const SwCntntFrm*>( pProposedAnchorFrm );
933 10258 : while ( pTmpFrm->IsFollow() )
934 : {
935 86 : pTmpFrm = pTmpFrm->FindMaster();
936 : }
937 5086 : pProposedAnchorFrm = pTmpFrm;
938 : }
939 :
940 5086 : const SwFrm* pMasterObjAnchorFrm = GetAnchorFrm();
941 5086 : if ( pMasterObjAnchorFrm && pMasterObjAnchorFrm->IsCntntFrm() )
942 : {
943 : const SwCntntFrm* pTmpFrm =
944 5086 : static_cast<const SwCntntFrm*>( pMasterObjAnchorFrm );
945 10310 : while ( pTmpFrm->IsFollow() )
946 : {
947 138 : pTmpFrm = pTmpFrm->FindMaster();
948 : }
949 5086 : pMasterObjAnchorFrm = pTmpFrm;
950 : }
951 :
952 5086 : if ( pMasterObjAnchorFrm && pMasterObjAnchorFrm == pProposedAnchorFrm )
953 : {
954 4660 : pRetDrawObj = GetMaster();
955 : }
956 : else
957 : {
958 : std::list<SwDrawVirtObj*>::const_iterator aFoundVirtObjIter =
959 : std::find_if( maDrawVirtObjs.begin(), maDrawVirtObjs.end(),
960 426 : VirtObjAnchoredAtFrmPred( *pProposedAnchorFrm ) );
961 :
962 426 : if ( aFoundVirtObjIter != maDrawVirtObjs.end() )
963 : {
964 0 : pRetDrawObj = (*aFoundVirtObjIter);
965 : }
966 : }
967 :
968 5086 : return pRetDrawObj;
969 : }
970 :
971 14262 : void SwDrawContact::NotifyBackgrdOfAllVirtObjs( const Rectangle* pOldBoundRect )
972 : {
973 44064 : for ( std::list<SwDrawVirtObj*>::iterator aDrawVirtObjIter = maDrawVirtObjs.begin();
974 29376 : aDrawVirtObjIter != maDrawVirtObjs.end();
975 : ++aDrawVirtObjIter )
976 : {
977 426 : SwDrawVirtObj* pDrawVirtObj = (*aDrawVirtObjIter);
978 426 : 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 = (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 14262 : }
1003 :
1004 : /// local method to notify the background for a drawing object - #i26791#
1005 26186 : static void lcl_NotifyBackgroundOfObj( SwDrawContact& _rDrawContact,
1006 : const SdrObject& _rObj,
1007 : const Rectangle* _pOldObjRect )
1008 : {
1009 : // #i34640#
1010 : SwAnchoredObject* pAnchoredObj =
1011 26186 : const_cast<SwAnchoredObject*>(_rDrawContact.GetAnchoredObj( &_rObj ));
1012 26186 : if ( pAnchoredObj && pAnchoredObj->GetAnchorFrm() )
1013 : {
1014 : // #i34640# - determine correct page frame
1015 6296 : SwPageFrm* pPageFrm = pAnchoredObj->FindPageFrmOfAnchor();
1016 6296 : if( _pOldObjRect && pPageFrm )
1017 : {
1018 118 : SwRect aOldRect( *_pOldObjRect );
1019 118 : if( aOldRect.HasArea() )
1020 : {
1021 : // #i34640# - determine correct page frame
1022 94 : SwPageFrm* pOldPageFrm = (SwPageFrm*)::FindPage( aOldRect, pPageFrm );
1023 : ::Notify_Background( &_rObj, pOldPageFrm, aOldRect,
1024 94 : PREP_FLY_LEAVE, true);
1025 : }
1026 : }
1027 : // #i34640# - include spacing for wrapping
1028 6296 : SwRect aNewRect( pAnchoredObj->GetObjRectWithSpaces() );
1029 6296 : if( aNewRect.HasArea() && pPageFrm )
1030 : {
1031 3322 : pPageFrm = (SwPageFrm*)::FindPage( aNewRect, pPageFrm );
1032 : ::Notify_Background( &_rObj, pPageFrm, aNewRect,
1033 3322 : PREP_FLY_ARRIVE, true );
1034 : }
1035 6296 : ClrContourCache( &_rObj );
1036 : }
1037 26186 : }
1038 :
1039 60178 : 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 contruction
1045 60178 : SwDoc* pDoc = GetFmt()->GetDoc();
1046 80026 : if ( pDoc->getIDocumentLayoutAccess().GetCurrentViewShell() &&
1047 19848 : pDoc->getIDocumentLayoutAccess().GetCurrentViewShell()->IsInConstructor() )
1048 : {
1049 2110 : return;
1050 : }
1051 :
1052 : // #i44339#
1053 : // no event handling, if document is in destruction.
1054 : // Exception: It's the SDRUSERCALL_DELETE event
1055 58068 : 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 58068 : SwViewShell *pSh = 0, *pOrg;
1062 58068 : SwRootFrm *pTmpRoot = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
1063 58068 : if ( pTmpRoot && pTmpRoot->IsCallbackActionEnabled() )
1064 : {
1065 17692 : pOrg = pDoc->getIDocumentLayoutAccess().GetCurrentViewShell();
1066 17692 : pSh = pOrg;
1067 17692 : if ( pSh )
1068 17692 : do
1069 17692 : { if ( pSh->Imp()->IsAction() || pSh->Imp()->IsIdleAction() )
1070 17474 : pSh = 0;
1071 : else
1072 218 : pSh = (SwViewShell*)pSh->GetNext();
1073 :
1074 218 : } while ( pSh && pSh != pOrg );
1075 :
1076 17692 : if ( pSh )
1077 218 : pTmpRoot->StartAllAction();
1078 : }
1079 58068 : SdrObjUserCall::Changed( rObj, eType, rOldBoundRect );
1080 58068 : _Changed( rObj, eType, &rOldBoundRect ); //Attention, possibly suicidal!
1081 :
1082 58068 : if ( pSh )
1083 218 : pTmpRoot->EndAllAction();
1084 : }
1085 :
1086 : /// helper class for method <SwDrawContact::_Changed(..)> for handling nested
1087 : /// <SdrObjUserCall> events
1088 : class NestedUserCallHdl
1089 : {
1090 : private:
1091 : SwDrawContact* mpDrawContact;
1092 : bool mbParentUserCallActive;
1093 : SdrUserCallType meParentUserCallEventType;
1094 :
1095 : public:
1096 58068 : NestedUserCallHdl( SwDrawContact* _pDrawContact,
1097 : SdrUserCallType _eEventType )
1098 : : mpDrawContact( _pDrawContact ),
1099 : mbParentUserCallActive( _pDrawContact->mbUserCallActive ),
1100 58068 : meParentUserCallEventType( _pDrawContact->meEventTypeOfCurrentUserCall )
1101 : {
1102 58068 : mpDrawContact->mbUserCallActive = true;
1103 58068 : mpDrawContact->meEventTypeOfCurrentUserCall = _eEventType;
1104 58068 : }
1105 :
1106 58068 : ~NestedUserCallHdl()
1107 : {
1108 58068 : if ( mpDrawContact )
1109 : {
1110 58066 : mpDrawContact->mbUserCallActive = mbParentUserCallActive;
1111 58066 : mpDrawContact->meEventTypeOfCurrentUserCall = meParentUserCallEventType;
1112 : }
1113 58068 : }
1114 :
1115 2 : void DrawContactDeleted()
1116 : {
1117 2 : mpDrawContact = 0;
1118 2 : }
1119 :
1120 58088 : bool IsNestedUserCall() const
1121 : {
1122 58088 : return mbParentUserCallActive;
1123 : }
1124 :
1125 20 : void AssertNestedUserCall()
1126 : {
1127 20 : if ( IsNestedUserCall() )
1128 : {
1129 20 : bool bTmpAssert( true );
1130 : // Currently its known, that a nested event SDRUSERCALL_RESIZE
1131 : // could occur during parent user call SDRUSERCALL_INSERTED,
1132 : // SDRUSERCALL_DELETE and SDRUSERCALL_RESIZE for edge objects.
1133 : // Also possible are nested SDRUSERCALL_CHILD_RESIZE events for
1134 : // edge objects
1135 : // Thus, assert all other combinations
1136 40 : if ( ( meParentUserCallEventType == SDRUSERCALL_INSERTED ||
1137 40 : meParentUserCallEventType == SDRUSERCALL_DELETE ||
1138 40 : meParentUserCallEventType == SDRUSERCALL_RESIZE ) &&
1139 20 : mpDrawContact->meEventTypeOfCurrentUserCall == SDRUSERCALL_RESIZE )
1140 : {
1141 20 : bTmpAssert = false;
1142 : }
1143 0 : else if ( meParentUserCallEventType == SDRUSERCALL_CHILD_RESIZE &&
1144 0 : mpDrawContact->meEventTypeOfCurrentUserCall == SDRUSERCALL_CHILD_RESIZE )
1145 : {
1146 0 : bTmpAssert = false;
1147 : }
1148 :
1149 : if ( bTmpAssert )
1150 : {
1151 : OSL_FAIL( "<SwDrawContact::_Changed(..)> - unknown nested <UserCall> event. This is serious, please inform OD." );
1152 : }
1153 : }
1154 20 : }
1155 : };
1156 :
1157 : /// Notify the format's textbox that it should reconsider its position / size.
1158 12 : void lcl_textBoxSizeNotify(SwFrmFmt* pFmt)
1159 : {
1160 12 : if (SwTextBoxHelper::findTextBox(pFmt))
1161 : {
1162 : // Just notify the textbox that the size has changed, the actual object size is not interesting.
1163 6 : SfxItemSet aResizeSet(pFmt->GetDoc()->GetAttrPool(), RES_FRM_SIZE, RES_FRM_SIZE, 0);
1164 12 : SwFmtFrmSize aSize;
1165 6 : aResizeSet.Put(aSize);
1166 12 : SwTextBoxHelper::syncFlyFrmAttr(*pFmt, aResizeSet);
1167 : }
1168 12 : }
1169 :
1170 : // !!!ATTENTION!!! The object may commit suicide!!!
1171 :
1172 58068 : void SwDrawContact::_Changed( const SdrObject& rObj,
1173 : SdrUserCallType eType,
1174 : const Rectangle* pOldBoundRect )
1175 : {
1176 : // suppress handling of nested <SdrObjUserCall> events
1177 58068 : NestedUserCallHdl aNestedUserCallHdl( this, eType );
1178 58068 : if ( aNestedUserCallHdl.IsNestedUserCall() )
1179 : {
1180 20 : aNestedUserCallHdl.AssertNestedUserCall();
1181 58088 : return;
1182 : }
1183 : // do *not* notify, if document is destructing
1184 : // #i35912# - do *not* notify for as-character anchored
1185 : // drawing objects.
1186 : // #i35007#
1187 : // improvement: determine as-character anchored object flag only once.
1188 58048 : const bool bAnchoredAsChar = ObjAnchoredAsChar();
1189 116096 : const bool bNotify = !(GetFmt()->GetDoc()->IsInDtor()) &&
1190 91628 : ( SURROUND_THROUGHT != GetFmt()->GetSurround().GetSurround() ) &&
1191 91628 : !bAnchoredAsChar;
1192 58048 : switch( eType )
1193 : {
1194 : case SDRUSERCALL_DELETE:
1195 : {
1196 2 : if ( bNotify )
1197 : {
1198 0 : lcl_NotifyBackgroundOfObj( *this, rObj, pOldBoundRect );
1199 : // --> #i36181# - background of 'virtual'
1200 : // drawing objects have also been notified.
1201 0 : NotifyBackgrdOfAllVirtObjs( pOldBoundRect );
1202 : }
1203 2 : DisconnectFromLayout( false );
1204 2 : SetMaster( NULL );
1205 2 : delete this;
1206 : // --> #i65784# Prevent memory corruption
1207 2 : aNestedUserCallHdl.DrawContactDeleted();
1208 2 : break;
1209 : }
1210 : case SDRUSERCALL_INSERTED:
1211 : {
1212 0 : if ( mbDisconnectInProgress )
1213 : {
1214 : OSL_FAIL( "<SwDrawContact::_Changed(..)> - Insert event during disconnection from layout is invalid." );
1215 : }
1216 : else
1217 : {
1218 0 : ConnectToLayout();
1219 0 : if ( bNotify )
1220 : {
1221 0 : lcl_NotifyBackgroundOfObj( *this, rObj, pOldBoundRect );
1222 : }
1223 : }
1224 0 : break;
1225 : }
1226 : case SDRUSERCALL_REMOVED:
1227 : {
1228 0 : if ( bNotify )
1229 : {
1230 0 : lcl_NotifyBackgroundOfObj( *this, rObj, pOldBoundRect );
1231 : }
1232 0 : DisconnectFromLayout( false );
1233 0 : break;
1234 : }
1235 : case SDRUSERCALL_CHILD_INSERTED :
1236 : case SDRUSERCALL_CHILD_REMOVED :
1237 : {
1238 : // --> #i113730#
1239 : // force layer of controls for group objects containing control objects
1240 2838 : if(dynamic_cast< SdrObjGroup* >(maAnchoredDrawObj.DrawObj()))
1241 : {
1242 2838 : if(::CheckControlLayer(maAnchoredDrawObj.DrawObj()))
1243 : {
1244 0 : const IDocumentDrawModelAccess* pIDDMA = static_cast<SwFrmFmt*>(GetRegisteredInNonConst())->getIDocumentDrawModelAccess();
1245 0 : const SdrLayerID aCurrentLayer(maAnchoredDrawObj.DrawObj()->GetLayer());
1246 0 : const SdrLayerID aControlLayerID(pIDDMA->GetControlsId());
1247 0 : const SdrLayerID aInvisibleControlLayerID(pIDDMA->GetInvisibleControlsId());
1248 :
1249 0 : if(aCurrentLayer != aControlLayerID && aCurrentLayer != aInvisibleControlLayerID)
1250 : {
1251 0 : if ( aCurrentLayer == pIDDMA->GetInvisibleHellId() ||
1252 0 : aCurrentLayer == pIDDMA->GetInvisibleHeavenId() )
1253 : {
1254 0 : maAnchoredDrawObj.DrawObj()->SetLayer(aInvisibleControlLayerID);
1255 : }
1256 : else
1257 : {
1258 0 : maAnchoredDrawObj.DrawObj()->SetLayer(aControlLayerID);
1259 : }
1260 : }
1261 : }
1262 : }
1263 : // fallthrough intended here
1264 : }
1265 : case SDRUSERCALL_MOVEONLY:
1266 : case SDRUSERCALL_RESIZE:
1267 : case SDRUSERCALL_CHILD_MOVEONLY :
1268 : case SDRUSERCALL_CHILD_RESIZE :
1269 : case SDRUSERCALL_CHILD_CHGATTR :
1270 : case SDRUSERCALL_CHILD_DELETE :
1271 : case SDRUSERCALL_CHILD_COPY :
1272 : {
1273 : // #i31698# - improvement
1274 : // get instance <SwAnchoredDrawObject> only once
1275 : const SwAnchoredDrawObject* pAnchoredDrawObj =
1276 45756 : static_cast<const SwAnchoredDrawObject*>( GetAnchoredObj( &rObj ) );
1277 :
1278 : /* protect against NULL pointer dereferencing */
1279 45756 : if(!pAnchoredDrawObj)
1280 : {
1281 0 : break;
1282 : }
1283 :
1284 : // #i26791# - adjust positioning and alignment attributes,
1285 : // if positioning of drawing object isn't in progress.
1286 : // #i53320# - no adjust of positioning attributes,
1287 : // if drawing object isn't positioned.
1288 74096 : if ( !pAnchoredDrawObj->IsPositioningInProgress() &&
1289 28340 : !pAnchoredDrawObj->NotYetPositioned() )
1290 : {
1291 : // #i34748# - If no last object rectangle is
1292 : // provided by the anchored object, use parameter <pOldBoundRect>.
1293 20 : const Rectangle& aOldObjRect = pAnchoredDrawObj->GetLastObjRect()
1294 : ? *(pAnchoredDrawObj->GetLastObjRect())
1295 20 : : *(pOldBoundRect);
1296 : // #i79400#
1297 : // always invalidate object rectangle inclusive spaces
1298 20 : pAnchoredDrawObj->InvalidateObjRectWithSpaces();
1299 : // #i41324# - notify background before
1300 : // adjusting position
1301 20 : if ( bNotify )
1302 : {
1303 : // #i31573# - correction
1304 : // background of given drawing object.
1305 14 : lcl_NotifyBackgroundOfObj( *this, rObj, &aOldObjRect );
1306 : }
1307 : // #i31698# - determine layout direction
1308 : // via draw frame format.
1309 : SwFrmFmt::tLayoutDir eLayoutDir =
1310 20 : pAnchoredDrawObj->GetFrmFmt().GetLayoutDir();
1311 : // use geometry of drawing object
1312 20 : SwRect aObjRect( rObj.GetSnapRect() );
1313 : // If drawing object is a member of a group, the adjustment
1314 : // of the positioning and the alignment attributes has to
1315 : // be done for the top group object.
1316 20 : if ( rObj.GetUpGroup() )
1317 : {
1318 0 : const SdrObject* pGroupObj = rObj.GetUpGroup();
1319 0 : while ( pGroupObj->GetUpGroup() )
1320 : {
1321 0 : pGroupObj = pGroupObj->GetUpGroup();
1322 : }
1323 : // use geometry of drawing object
1324 0 : aObjRect = pGroupObj->GetSnapRect();
1325 : }
1326 20 : SwTwips nXPosDiff(0L);
1327 20 : SwTwips nYPosDiff(0L);
1328 20 : switch ( eLayoutDir )
1329 : {
1330 : case SwFrmFmt::HORI_L2R:
1331 : {
1332 20 : nXPosDiff = aObjRect.Left() - aOldObjRect.Left();
1333 20 : nYPosDiff = aObjRect.Top() - aOldObjRect.Top();
1334 : }
1335 20 : break;
1336 : case SwFrmFmt::HORI_R2L:
1337 : {
1338 0 : nXPosDiff = aOldObjRect.Right() - aObjRect.Right();
1339 0 : nYPosDiff = aObjRect.Top() - aOldObjRect.Top();
1340 : }
1341 0 : break;
1342 : case SwFrmFmt::VERT_R2L:
1343 : {
1344 0 : nXPosDiff = aObjRect.Top() - aOldObjRect.Top();
1345 0 : nYPosDiff = aOldObjRect.Right() - aObjRect.Right();
1346 : }
1347 0 : break;
1348 : default:
1349 : {
1350 : OSL_FAIL( "<SwDrawContact::_Changed(..)> - unsupported layout direction" );
1351 : }
1352 : }
1353 20 : SfxItemSet aSet( GetFmt()->GetDoc()->GetAttrPool(),
1354 20 : RES_VERT_ORIENT, RES_HORI_ORIENT, 0 );
1355 20 : const SwFmtVertOrient& rVert = GetFmt()->GetVertOrient();
1356 20 : if ( nYPosDiff != 0 )
1357 : {
1358 :
1359 16 : if ( rVert.GetRelationOrient() == text::RelOrientation::CHAR ||
1360 8 : rVert.GetRelationOrient() == text::RelOrientation::TEXT_LINE )
1361 : {
1362 0 : nYPosDiff = -nYPosDiff;
1363 : }
1364 8 : aSet.Put( SwFmtVertOrient( rVert.GetPos()+nYPosDiff,
1365 : text::VertOrientation::NONE,
1366 16 : rVert.GetRelationOrient() ) );
1367 : }
1368 :
1369 20 : const SwFmtHoriOrient& rHori = GetFmt()->GetHoriOrient();
1370 20 : if ( !bAnchoredAsChar && nXPosDiff != 0 )
1371 : {
1372 2 : aSet.Put( SwFmtHoriOrient( rHori.GetPos()+nXPosDiff,
1373 : text::HoriOrientation::NONE,
1374 4 : rHori.GetRelationOrient() ) );
1375 : }
1376 :
1377 32 : if ( nYPosDiff ||
1378 24 : ( !bAnchoredAsChar && nXPosDiff != 0 ) )
1379 : {
1380 8 : GetFmt()->GetDoc()->SetFlyFrmAttr( *(GetFmt()), aSet );
1381 : // keep new object rectangle, to avoid multiple
1382 : // changes of the attributes by multiple event from
1383 : // the drawing layer - e.g. group objects and its members
1384 : // #i34748# - use new method
1385 : // <SwAnchoredDrawObject::SetLastObjRect(..)>.
1386 : const_cast<SwAnchoredDrawObject*>(pAnchoredDrawObj)
1387 8 : ->SetLastObjRect( aObjRect.SVRect() );
1388 : }
1389 12 : else if ( aObjRect.SSize() != aOldObjRect.GetSize() )
1390 : {
1391 12 : _InvalidateObjs();
1392 : // #i35007# - notify anchor frame
1393 : // of as-character anchored object
1394 12 : if ( bAnchoredAsChar )
1395 : {
1396 0 : SwFrm* pAnchorFrm = const_cast<SwAnchoredDrawObject*>(pAnchoredDrawObj)->AnchorFrm();
1397 0 : if(pAnchorFrm)
1398 : {
1399 0 : pAnchorFrm->Prepare( PREP_FLY_ATTR_CHG, GetFmt() );
1400 : }
1401 : }
1402 :
1403 12 : lcl_textBoxSizeNotify(GetFmt());
1404 : }
1405 0 : else if (eType == SDRUSERCALL_RESIZE)
1406 : // Even if the bounding box of the shape didn't change,
1407 : // notify about the size change, as an adjustment change
1408 : // may affect the size of the underlying textbox.
1409 0 : lcl_textBoxSizeNotify(GetFmt());
1410 : }
1411 : }
1412 45756 : break;
1413 : case SDRUSERCALL_CHGATTR:
1414 12290 : if ( bNotify )
1415 : {
1416 11910 : lcl_NotifyBackgroundOfObj( *this, rObj, pOldBoundRect );
1417 : }
1418 12290 : break;
1419 : default:
1420 0 : break;
1421 58048 : }
1422 : }
1423 :
1424 : namespace
1425 : {
1426 35506 : static const SwFmtAnchor* lcl_getAnchorFmt( const SfxPoolItem& _rItem )
1427 : {
1428 35506 : sal_uInt16 nWhich = _rItem.Which();
1429 35506 : const SwFmtAnchor* pAnchorFmt = NULL;
1430 35506 : if ( RES_ATTRSET_CHG == nWhich )
1431 : {
1432 35504 : static_cast<const SwAttrSetChg&>(_rItem).GetChgSet()->
1433 35504 : GetItemState( RES_ANCHOR, false, (const SfxPoolItem**)&pAnchorFmt );
1434 : }
1435 2 : else if ( RES_ANCHOR == nWhich )
1436 : {
1437 0 : pAnchorFmt = &static_cast<const SwFmtAnchor&>(_rItem);
1438 : }
1439 35506 : return pAnchorFmt;
1440 : }
1441 : }
1442 :
1443 27488 : void SwDrawContact::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew )
1444 : {
1445 : OSL_ENSURE( !mbDisconnectInProgress,
1446 : "<SwDrawContact::Modify(..)> called during disconnection.");
1447 :
1448 27488 : sal_uInt16 nWhich = pNew ? pNew->Which() : 0;
1449 27488 : const SwFmtAnchor* pNewAnchorFmt = pNew ? lcl_getAnchorFmt( *pNew ) : NULL;
1450 :
1451 27488 : if ( pNewAnchorFmt )
1452 : {
1453 : // Do not respond to a Reset Anchor !!!!!
1454 8020 : if ( SfxItemState::SET ==
1455 8020 : GetFmt()->GetAttrSet().GetItemState( RES_ANCHOR, false ) )
1456 : {
1457 : // no connect to layout during disconnection
1458 8018 : if ( !mbDisconnectInProgress )
1459 : {
1460 : // determine old object rectangle of 'master' drawing object
1461 : // for notification
1462 8018 : const Rectangle* pOldRect = 0L;
1463 8018 : Rectangle aOldRect;
1464 8018 : if ( GetAnchorFrm() )
1465 : {
1466 : // --> #i36181# - include spacing in object
1467 : // rectangle for notification.
1468 18 : aOldRect = maAnchoredDrawObj.GetObjRectWithSpaces().SVRect();
1469 18 : pOldRect = &aOldRect;
1470 : }
1471 : // re-connect to layout due to anchor format change
1472 8018 : ConnectToLayout( pNewAnchorFmt );
1473 : // notify background of drawing objects
1474 8018 : lcl_NotifyBackgroundOfObj( *this, *GetMaster(), pOldRect );
1475 8018 : NotifyBackgrdOfAllVirtObjs( pOldRect );
1476 :
1477 8018 : const SwFmtAnchor* pOldAnchorFmt = pOld ? lcl_getAnchorFmt( *pOld ) : NULL;
1478 8018 : if ( !pOldAnchorFmt || ( pOldAnchorFmt->GetAnchorId() != pNewAnchorFmt->GetAnchorId() ) )
1479 : {
1480 : OSL_ENSURE( maAnchoredDrawObj.DrawObj(), "SwDrawContact::Modify: no draw object here?" );
1481 4270 : if ( maAnchoredDrawObj.DrawObj() )
1482 : {
1483 : // --> #i102752#
1484 : // assure that a ShapePropertyChangeNotifier exists
1485 4270 : maAnchoredDrawObj.DrawObj()->notifyShapePropertyChange( ::svx::eTextShapeAnchorType );
1486 : }
1487 : }
1488 : }
1489 : }
1490 : else
1491 2 : DisconnectFromLayout();
1492 : }
1493 : // --> #i62875# - no further notification, if not connected to Writer layout
1494 22876 : else if ( maAnchoredDrawObj.GetAnchorFrm() &&
1495 3408 : maAnchoredDrawObj.GetDrawObj()->GetUserCall() )
1496 : {
1497 : // --> #i28701# - on change of wrapping style, hell|heaven layer,
1498 : // or wrapping style influence an update of the <SwSortedObjs> list,
1499 : // the drawing object is registered in, has to be performed. This is triggered
1500 : // by the 1st parameter of method call <_InvalidateObjs(..)>.
1501 6816 : if ( RES_SURROUND == nWhich ||
1502 3408 : RES_OPAQUE == nWhich ||
1503 6862 : RES_WRAP_INFLUENCE_ON_OBJPOS == nWhich ||
1504 3408 : ( RES_ATTRSET_CHG == nWhich &&
1505 3408 : ( SfxItemState::SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
1506 6770 : RES_SURROUND, false ) ||
1507 3362 : SfxItemState::SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
1508 6724 : RES_OPAQUE, false ) ||
1509 3362 : SfxItemState::SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
1510 3362 : RES_WRAP_INFLUENCE_ON_OBJPOS, false ) ) ) )
1511 : {
1512 46 : lcl_NotifyBackgroundOfObj( *this, *GetMaster(), 0L );
1513 46 : NotifyBackgrdOfAllVirtObjs( 0L );
1514 46 : _InvalidateObjs( true );
1515 : }
1516 6724 : else if ( RES_UL_SPACE == nWhich || RES_LR_SPACE == nWhich ||
1517 3362 : RES_HORI_ORIENT == nWhich || RES_VERT_ORIENT == nWhich ||
1518 : // #i28701# - add attribute 'Follow text flow'
1519 10084 : RES_FOLLOW_TEXT_FLOW == nWhich ||
1520 3362 : ( RES_ATTRSET_CHG == nWhich &&
1521 3362 : ( SfxItemState::SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
1522 6724 : RES_LR_SPACE, false ) ||
1523 3362 : SfxItemState::SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
1524 6724 : RES_UL_SPACE, false ) ||
1525 3362 : SfxItemState::SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
1526 5062 : RES_HORI_ORIENT, false ) ||
1527 1700 : SfxItemState::SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
1528 1702 : RES_VERT_ORIENT, false ) ||
1529 2 : SfxItemState::SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
1530 2 : RES_FOLLOW_TEXT_FLOW, false ) ) ) )
1531 : {
1532 3360 : lcl_NotifyBackgroundOfObj( *this, *GetMaster(), 0L );
1533 3360 : NotifyBackgrdOfAllVirtObjs( 0L );
1534 3360 : _InvalidateObjs();
1535 : }
1536 : // #i35443#
1537 2 : else if ( RES_ATTRSET_CHG == nWhich )
1538 : {
1539 2 : lcl_NotifyBackgroundOfObj( *this, *GetMaster(), 0L );
1540 2 : NotifyBackgrdOfAllVirtObjs( 0L );
1541 2 : _InvalidateObjs();
1542 : }
1543 : else if ( RES_REMOVE_UNO_OBJECT == nWhich )
1544 : {
1545 : // nothing to do
1546 : }
1547 : #if OSL_DEBUG_LEVEL > 0
1548 : else
1549 : {
1550 : OSL_FAIL( "<SwDrawContact::Modify(..)> - unhandled attribute? - please inform od@openoffice.org" );
1551 : }
1552 : #endif
1553 : }
1554 :
1555 : // #i51474#
1556 27488 : GetAnchoredObj( 0L )->ResetLayoutProcessBools();
1557 27488 : }
1558 :
1559 : // #i26791#
1560 : // #i28701# - added parameter <_bUpdateSortedObjsList>
1561 5500 : void SwDrawContact::_InvalidateObjs( const bool _bUpdateSortedObjsList )
1562 : {
1563 : // invalidate position of existing 'virtual' drawing objects
1564 17316 : for ( std::list<SwDrawVirtObj*>::iterator aDisconnectIter = maDrawVirtObjs.begin();
1565 11544 : aDisconnectIter != maDrawVirtObjs.end();
1566 : ++aDisconnectIter )
1567 : {
1568 272 : SwDrawVirtObj* pDrawVirtObj = (*aDisconnectIter);
1569 : // #i33313# - invalidation only for connected
1570 : // 'virtual' drawing objects
1571 272 : if ( pDrawVirtObj->IsConnected() )
1572 : {
1573 272 : pDrawVirtObj->AnchoredObj().InvalidateObjPos();
1574 : // #i28701#
1575 272 : if ( _bUpdateSortedObjsList )
1576 : {
1577 0 : pDrawVirtObj->AnchoredObj().UpdateObjInSortedList();
1578 : }
1579 : }
1580 : }
1581 :
1582 : // invalidate position of 'master' drawing object
1583 5500 : SwAnchoredObject* pAnchoredObj = GetAnchoredObj( 0L );
1584 5500 : pAnchoredObj->InvalidateObjPos();
1585 : // #i28701#
1586 5500 : if ( _bUpdateSortedObjsList )
1587 : {
1588 46 : pAnchoredObj->UpdateObjInSortedList();
1589 : }
1590 5500 : }
1591 :
1592 17372 : void SwDrawContact::DisconnectFromLayout( bool _bMoveMasterToInvisibleLayer )
1593 : {
1594 17372 : mbDisconnectInProgress = true;
1595 :
1596 : // --> #i36181# - notify background of drawing object
1597 32564 : if ( _bMoveMasterToInvisibleLayer &&
1598 26224 : !(GetFmt()->GetDoc()->IsInDtor()) &&
1599 31436 : GetAnchorFrm() && !GetAnchorFrm()->IsInDtor() )
1600 : {
1601 2836 : const Rectangle aOldRect( maAnchoredDrawObj.GetObjRectWithSpaces().SVRect() );
1602 2836 : lcl_NotifyBackgroundOfObj( *this, *GetMaster(), &aOldRect );
1603 2836 : NotifyBackgrdOfAllVirtObjs( &aOldRect );
1604 : }
1605 :
1606 : // remove 'virtual' drawing objects from writer
1607 : // layout and from drawing page
1608 55488 : for ( std::list<SwDrawVirtObj*>::iterator aDisconnectIter = maDrawVirtObjs.begin();
1609 36992 : aDisconnectIter != maDrawVirtObjs.end();
1610 : ++aDisconnectIter )
1611 : {
1612 1124 : SwDrawVirtObj* pDrawVirtObj = (*aDisconnectIter);
1613 1124 : pDrawVirtObj->RemoveFromWriterLayout();
1614 1124 : pDrawVirtObj->RemoveFromDrawingPage();
1615 : }
1616 :
1617 17372 : if ( maAnchoredDrawObj.GetAnchorFrm() )
1618 : {
1619 3246 : maAnchoredDrawObj.AnchorFrm()->RemoveDrawObj( maAnchoredDrawObj );
1620 : }
1621 :
1622 17372 : if ( _bMoveMasterToInvisibleLayer && GetMaster() && GetMaster()->IsInserted() )
1623 : {
1624 15186 : SdrViewIter aIter( GetMaster() );
1625 15208 : for( SdrView* pView = aIter.FirstView(); pView;
1626 : pView = aIter.NextView() )
1627 : {
1628 22 : pView->MarkObj( GetMaster(), pView->GetSdrPageView(), true );
1629 : }
1630 :
1631 : // Instead of removing 'master' object from drawing page, move the
1632 : // 'master' drawing object into the corresponding invisible layer.
1633 : {
1634 : //((SwFrmFmt*)GetRegisteredIn())->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage(0)->
1635 : // RemoveObject( GetMaster()->GetOrdNum() );
1636 : // #i18447# - in order to consider group object correct
1637 : // use new method <SwDrawContact::MoveObjToInvisibleLayer(..)>
1638 15186 : MoveObjToInvisibleLayer( GetMaster() );
1639 : }
1640 : }
1641 :
1642 17372 : mbDisconnectInProgress = false;
1643 17372 : }
1644 :
1645 : /// method to remove 'master' drawing object from drawing page.
1646 4470 : void SwDrawContact::RemoveMasterFromDrawPage()
1647 : {
1648 4470 : if ( GetMaster() )
1649 : {
1650 4468 : GetMaster()->SetUserCall( 0 );
1651 4468 : if ( GetMaster()->IsInserted() )
1652 : {
1653 4466 : ((SwFrmFmt*)GetRegisteredIn())->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage(0)->
1654 4466 : RemoveObject( GetMaster()->GetOrdNum() );
1655 : }
1656 : }
1657 4470 : }
1658 :
1659 : // disconnect for a dedicated drawing object - could be 'master' or 'virtual'.
1660 : // a 'master' drawing object will disconnect a 'virtual' drawing object
1661 : // in order to take its place.
1662 : // #i19919# - no special case, if drawing object isn't in
1663 : // page header/footer, in order to get drawing objects in repeating table headers
1664 : // also working.
1665 3426 : void SwDrawContact::DisconnectObjFromLayout( SdrObject* _pDrawObj )
1666 : {
1667 3426 : if ( _pDrawObj->ISA(SwDrawVirtObj) )
1668 : {
1669 268 : SwDrawVirtObj* pDrawVirtObj = static_cast<SwDrawVirtObj*>(_pDrawObj);
1670 268 : pDrawVirtObj->RemoveFromWriterLayout();
1671 268 : pDrawVirtObj->RemoveFromDrawingPage();
1672 : }
1673 : else
1674 : {
1675 : std::list<SwDrawVirtObj*>::const_iterator aFoundVirtObjIter =
1676 : std::find_if( maDrawVirtObjs.begin(), maDrawVirtObjs.end(),
1677 3158 : UsedOrUnusedVirtObjPred( true ) );
1678 3158 : if ( aFoundVirtObjIter != maDrawVirtObjs.end() )
1679 : {
1680 : // replace found 'virtual' drawing object by 'master' drawing
1681 : // object and disconnect the 'virtual' one
1682 158 : SwDrawVirtObj* pDrawVirtObj = (*aFoundVirtObjIter);
1683 158 : SwFrm* pNewAnchorFrmOfMaster = pDrawVirtObj->AnchorFrm();
1684 : // disconnect 'virtual' drawing object
1685 158 : pDrawVirtObj->RemoveFromWriterLayout();
1686 158 : pDrawVirtObj->RemoveFromDrawingPage();
1687 : // disconnect 'master' drawing object from current frame
1688 158 : GetAnchorFrm()->RemoveDrawObj( maAnchoredDrawObj );
1689 : // re-connect 'master' drawing object to frame of found 'virtual'
1690 : // drawing object.
1691 158 : pNewAnchorFrmOfMaster->AppendDrawObj( maAnchoredDrawObj );
1692 : }
1693 : else
1694 : {
1695 : // no connected 'virtual' drawing object found. Thus, disconnect
1696 : // completely from layout.
1697 3000 : DisconnectFromLayout();
1698 : }
1699 : }
1700 3426 : }
1701 :
1702 634 : static SwTxtFrm* lcl_GetFlyInCntntAnchor( SwTxtFrm* _pProposedAnchorFrm,
1703 : const sal_Int32 _nTxtOfs )
1704 : {
1705 634 : SwTxtFrm* pAct = _pProposedAnchorFrm;
1706 : SwTxtFrm* pTmp;
1707 634 : do
1708 : {
1709 634 : pTmp = pAct;
1710 634 : pAct = pTmp->GetFollow();
1711 : }
1712 634 : while( pAct && _nTxtOfs >= pAct->GetOfst() );
1713 634 : return pTmp;
1714 : }
1715 :
1716 10556 : void SwDrawContact::ConnectToLayout( const SwFmtAnchor* pAnch )
1717 : {
1718 : // *no* connect to layout during disconnection from layout.
1719 10556 : if ( mbDisconnectInProgress )
1720 : {
1721 : OSL_FAIL( "<SwDrawContact::ConnectToLayout(..)> called during disconnection.");
1722 0 : return;
1723 : }
1724 :
1725 : // --> #i33909# - *no* connect to layout, if 'master' drawing
1726 : // object isn't inserted in the drawing page
1727 10556 : if ( !GetMaster()->IsInserted() )
1728 : {
1729 : OSL_FAIL( "<SwDrawContact::ConnectToLayout(..)> - master drawing object not inserted -> no connect to layout. Please inform od@openoffice.org" );
1730 0 : return;
1731 : }
1732 :
1733 10556 : SwFrmFmt* pDrawFrmFmt = (SwFrmFmt*)GetRegisteredIn();
1734 :
1735 10556 : if( !pDrawFrmFmt->getIDocumentLayoutAccess()->GetCurrentViewShell() )
1736 8378 : return;
1737 :
1738 : // remove 'virtual' drawing objects from writer
1739 : // layout and from drawing page, and remove 'master' drawing object from
1740 : // writer layout - 'master' object will remain in drawing page.
1741 2178 : DisconnectFromLayout( false );
1742 :
1743 2178 : if ( !pAnch )
1744 : {
1745 2136 : pAnch = &(pDrawFrmFmt->GetAnchor());
1746 : }
1747 :
1748 2178 : switch ( pAnch->GetAnchorId() )
1749 : {
1750 : case FLY_AT_PAGE:
1751 : {
1752 68 : sal_uInt16 nPgNum = pAnch->GetPageNum();
1753 68 : SwViewShell *pShell = pDrawFrmFmt->getIDocumentLayoutAccess()->GetCurrentViewShell();
1754 68 : if( !pShell )
1755 0 : break;
1756 68 : SwRootFrm* pRoot = pShell->GetLayout();
1757 68 : SwPageFrm *pPage = static_cast<SwPageFrm*>(pRoot->Lower());
1758 :
1759 180 : for ( sal_uInt16 i = 1; i < nPgNum && pPage; ++i )
1760 : {
1761 112 : pPage = static_cast<SwPageFrm*>(pPage->GetNext());
1762 : }
1763 :
1764 68 : if ( pPage )
1765 : {
1766 56 : pPage->AppendDrawObj( maAnchoredDrawObj );
1767 : }
1768 : else
1769 : //Looks stupid but is allowed (compare SwFEShell::SetPageObjsNewPage)
1770 12 : pRoot->SetAssertFlyPages();
1771 : }
1772 68 : break;
1773 :
1774 : case FLY_AT_CHAR:
1775 : case FLY_AT_PARA:
1776 : case FLY_AT_FLY:
1777 : case FLY_AS_CHAR:
1778 : {
1779 2110 : if ( pAnch->GetAnchorId() == FLY_AS_CHAR )
1780 : {
1781 634 : ClrContourCache( GetMaster() );
1782 : }
1783 : // support drawing objects in header/footer,
1784 : // but not control objects:
1785 : // anchor at first found frame the 'master' object and
1786 : // at the following frames 'virtual' drawing objects.
1787 : // Note: method is similar to <SwFlyFrmFmt::MakeFrms(..)>
1788 2110 : SwModify *pModify = 0;
1789 2110 : if( pAnch->GetCntntAnchor() )
1790 : {
1791 2110 : if ( pAnch->GetAnchorId() == FLY_AT_FLY )
1792 : {
1793 18 : SwNodeIndex aIdx( pAnch->GetCntntAnchor()->nNode );
1794 18 : SwCntntNode* pCNd = pDrawFrmFmt->GetDoc()->GetNodes().GoNext( &aIdx );
1795 18 : if ( SwIterator<SwFrm,SwCntntNode>::FirstElement( *pCNd ) )
1796 18 : pModify = pCNd;
1797 : else
1798 : {
1799 0 : const SwNodeIndex& rIdx = pAnch->GetCntntAnchor()->nNode;
1800 0 : SwFrmFmts& rFmts = *(pDrawFrmFmt->GetDoc()->GetSpzFrmFmts());
1801 0 : for( sal_uInt16 i = 0; i < rFmts.size(); ++i )
1802 : {
1803 0 : SwFrmFmt* pFlyFmt = rFmts[i];
1804 0 : if( pFlyFmt->GetCntnt().GetCntntIdx() &&
1805 0 : rIdx == *(pFlyFmt->GetCntnt().GetCntntIdx()) )
1806 : {
1807 0 : pModify = pFlyFmt;
1808 0 : break;
1809 : }
1810 : }
1811 18 : }
1812 : }
1813 : else
1814 : {
1815 2092 : pModify = pAnch->GetCntntAnchor()->nNode.GetNode().GetCntntNode();
1816 : }
1817 : }
1818 :
1819 : // #i29199# - It is possible, that
1820 : // the anchor doesn't exist - E.g., reordering the
1821 : // sub-documents in a master document.
1822 : // Note: The anchor will be inserted later.
1823 2110 : if ( !pModify )
1824 : {
1825 : // break to end of the current switch case.
1826 0 : break;
1827 : }
1828 :
1829 2110 : SwIterator<SwFrm,SwModify> aIter( *pModify );
1830 2110 : SwFrm* pAnchorFrmOfMaster = 0;
1831 4406 : for( SwFrm *pFrm = aIter.First(); pFrm; pFrm = aIter.Next() )
1832 : {
1833 : // append drawing object, if
1834 : // (1) proposed anchor frame isn't a follow and
1835 : // (2) drawing object isn't a control object to be anchored
1836 : // in header/footer.
1837 4592 : const bool bAdd = ( !pFrm->IsCntntFrm() ||
1838 6888 : !((SwCntntFrm*)pFrm)->IsFollow() ) &&
1839 2762 : ( !::CheckControlLayer( GetMaster() ) ||
1840 2762 : !pFrm->FindFooterOrHeader() );
1841 :
1842 2296 : if( bAdd )
1843 : {
1844 2296 : if ( FLY_AT_FLY == pAnch->GetAnchorId() && !pFrm->IsFlyFrm() )
1845 : {
1846 18 : pFrm = pFrm->FindFlyFrm();
1847 : OSL_ENSURE( pFrm,
1848 : "<SwDrawContact::ConnectToLayout(..)> - missing fly frame -> crash." );
1849 : }
1850 :
1851 : // find correct follow for as character anchored objects
1852 2930 : if ((pAnch->GetAnchorId() == FLY_AS_CHAR) &&
1853 634 : pFrm->IsTxtFrm() )
1854 : {
1855 : pFrm = lcl_GetFlyInCntntAnchor(
1856 : static_cast<SwTxtFrm*>(pFrm),
1857 634 : pAnch->GetCntntAnchor()->nContent.GetIndex() );
1858 : }
1859 :
1860 2296 : if ( !pAnchorFrmOfMaster )
1861 : {
1862 : // append 'master' drawing object
1863 2024 : pAnchorFrmOfMaster = pFrm;
1864 2024 : pFrm->AppendDrawObj( maAnchoredDrawObj );
1865 : }
1866 : else
1867 : {
1868 : // append 'virtual' drawing object
1869 272 : SwDrawVirtObj* pDrawVirtObj = AddVirtObj();
1870 272 : if ( pAnch->GetAnchorId() == FLY_AS_CHAR )
1871 : {
1872 0 : ClrContourCache( pDrawVirtObj );
1873 : }
1874 272 : pFrm->AppendDrawObj( pDrawVirtObj->AnchoredObj() );
1875 :
1876 272 : pDrawVirtObj->ActionChanged();
1877 : }
1878 :
1879 2296 : if ( pAnch->GetAnchorId() == FLY_AS_CHAR )
1880 : {
1881 634 : pFrm->InvalidatePrt();
1882 : }
1883 : }
1884 2110 : }
1885 : }
1886 2110 : break;
1887 : default:
1888 : OSL_FAIL( "Unknown Anchor." );
1889 0 : break;
1890 : }
1891 2178 : if ( GetAnchorFrm() )
1892 : {
1893 2080 : ::setContextWritingMode( maAnchoredDrawObj.DrawObj(), GetAnchorFrm() );
1894 : // #i26791# - invalidate objects instead of direct positioning
1895 2080 : _InvalidateObjs();
1896 : }
1897 : }
1898 :
1899 : /// insert 'master' drawing object into drawing page
1900 0 : void SwDrawContact::InsertMasterIntoDrawPage()
1901 : {
1902 0 : if ( !GetMaster()->IsInserted() )
1903 : {
1904 0 : GetFmt()->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage(0)
1905 0 : ->InsertObject( GetMaster(), GetMaster()->GetOrdNumDirect() );
1906 : }
1907 0 : GetMaster()->SetUserCall( this );
1908 0 : }
1909 :
1910 2066 : SwPageFrm* SwDrawContact::FindPage( const SwRect &rRect )
1911 : {
1912 : // --> #i28701# - use method <GetPageFrm()>
1913 2066 : SwPageFrm* pPg = GetPageFrm();
1914 2066 : if ( !pPg && GetAnchorFrm() )
1915 0 : pPg = GetAnchorFrm()->FindPageFrm();
1916 2066 : if ( pPg )
1917 2066 : pPg = (SwPageFrm*)::FindPage( rRect, pPg );
1918 2066 : return pPg;
1919 : }
1920 :
1921 2136 : void SwDrawContact::ChkPage()
1922 : {
1923 2136 : if ( mbDisconnectInProgress )
1924 : {
1925 : OSL_FAIL( "<SwDrawContact::ChkPage()> called during disconnection." );
1926 2136 : return;
1927 : }
1928 :
1929 : // --> #i28701#
1930 4272 : SwPageFrm* pPg = ( maAnchoredDrawObj.GetAnchorFrm() &&
1931 2136 : maAnchoredDrawObj.GetAnchorFrm()->IsPageFrm() )
1932 : ? GetPageFrm()
1933 4342 : : FindPage( GetMaster()->GetCurrentBoundRect() );
1934 2136 : if ( GetPageFrm() != pPg )
1935 : {
1936 : // if drawing object is anchor in header/footer a change of the page
1937 : // is a dramatic change. Thus, completely re-connect to the layout
1938 0 : if ( maAnchoredDrawObj.GetAnchorFrm() &&
1939 0 : maAnchoredDrawObj.GetAnchorFrm()->FindFooterOrHeader() )
1940 : {
1941 0 : ConnectToLayout();
1942 : }
1943 : else
1944 : {
1945 : // --> #i28701# - use methods <GetPageFrm()> and <SetPageFrm>
1946 0 : if ( GetPageFrm() )
1947 0 : GetPageFrm()->RemoveDrawObjFromPage( maAnchoredDrawObj );
1948 0 : pPg->AppendDrawObjToPage( maAnchoredDrawObj );
1949 0 : SetPageFrm( pPg );
1950 : }
1951 : }
1952 : }
1953 :
1954 : // Important note:
1955 : // method is called by method <SwDPage::ReplaceObject(..)>, which called its
1956 : // corresponding superclass method <FmFormPage::ReplaceObject(..)>.
1957 : // Note: 'master' drawing object *has* to be connected to layout triggered
1958 : // by the caller of this, if method is called.
1959 0 : void SwDrawContact::ChangeMasterObject( SdrObject *pNewMaster )
1960 : {
1961 0 : DisconnectFromLayout( false );
1962 : // consider 'virtual' drawing objects
1963 0 : RemoveAllVirtObjs();
1964 :
1965 0 : GetMaster()->SetUserCall( 0 );
1966 0 : SetMaster( pNewMaster );
1967 0 : GetMaster()->SetUserCall( this );
1968 :
1969 0 : _InvalidateObjs();
1970 0 : }
1971 :
1972 : /// get data collection of anchored objects, handled by with contact
1973 28 : void SwDrawContact::GetAnchoredObjs( std::list<SwAnchoredObject*>& _roAnchoredObjs ) const
1974 : {
1975 28 : _roAnchoredObjs.push_back( const_cast<SwAnchoredDrawObject*>(&maAnchoredDrawObj) );
1976 :
1977 84 : for ( std::list<SwDrawVirtObj*>::const_iterator aDrawVirtObjsIter = maDrawVirtObjs.begin();
1978 56 : aDrawVirtObjsIter != maDrawVirtObjs.end();
1979 : ++aDrawVirtObjsIter )
1980 : {
1981 0 : _roAnchoredObjs.push_back( &(*aDrawVirtObjsIter)->AnchoredObj() );
1982 : }
1983 28 : }
1984 :
1985 : // AW: own sdr::contact::ViewContact (VC) sdr::contact::ViewObjectContact (VOC) needed
1986 : // since offset is defined different from SdrVirtObj's sdr::contact::ViewContactOfVirtObj.
1987 : // For paint, that offset is used by setting at the OutputDevice; for primitives this is
1988 : // not possible since we have no OutputDevice, but define the geometry itself.
1989 :
1990 : namespace sdr
1991 : {
1992 : namespace contact
1993 : {
1994 : class VOCOfDrawVirtObj : public ViewObjectContactOfSdrObj
1995 : {
1996 : protected:
1997 : /**
1998 : * This method is responsible for creating the graphical visualisation data which is
1999 : * stored/cached in the local primitive. Default gets view-independent Primitive from
2000 : * the ViewContact using ViewContact::getViewIndependentPrimitive2DSequence(), takes
2001 : * care of visibility, handles glue and ghosted.
2002 : *
2003 : * This method will not handle included hierarchies and not check geometric visibility.
2004 : */
2005 : virtual drawinglayer::primitive2d::Primitive2DSequence createPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const SAL_OVERRIDE;
2006 :
2007 : public:
2008 418 : VOCOfDrawVirtObj(ObjectContact& rObjectContact, ViewContact& rViewContact)
2009 418 : : ViewObjectContactOfSdrObj(rObjectContact, rViewContact)
2010 : {
2011 418 : }
2012 :
2013 : virtual ~VOCOfDrawVirtObj();
2014 : };
2015 :
2016 : class VCOfDrawVirtObj : public ViewContactOfVirtObj
2017 : {
2018 : protected:
2019 : /** Create a Object-Specific ViewObjectContact, set ViewContact and ObjectContact.
2020 : *
2021 : * Always needs to return something. Default is to create a standard ViewObjectContact
2022 : * containing the given ObjectContact and *this.
2023 : */
2024 : virtual ViewObjectContact& CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) SAL_OVERRIDE;
2025 :
2026 : public:
2027 : /// basic constructor, used from SdrObject.
2028 426 : VCOfDrawVirtObj(SwDrawVirtObj& rObj)
2029 426 : : ViewContactOfVirtObj(rObj)
2030 : {
2031 426 : }
2032 : virtual ~VCOfDrawVirtObj();
2033 :
2034 : /// access to SwDrawVirtObj
2035 2500 : SwDrawVirtObj& GetSwDrawVirtObj() const
2036 : {
2037 2500 : return (SwDrawVirtObj&)mrObject;
2038 : }
2039 : };
2040 : } // end of namespace contact
2041 : } // end of namespace sdr
2042 :
2043 : namespace sdr
2044 : {
2045 : namespace contact
2046 : {
2047 : /// recursively collect primitive data from given VOC with given offset
2048 0 : void impAddPrimitivesFromGroup(const ViewObjectContact& rVOC, const basegfx::B2DHomMatrix& rOffsetMatrix, const DisplayInfo& rDisplayInfo, drawinglayer::primitive2d::Primitive2DSequence& rxTarget)
2049 : {
2050 0 : const sal_uInt32 nSubHierarchyCount(rVOC.GetViewContact().GetObjectCount());
2051 :
2052 0 : for(sal_uInt32 a(0L); a < nSubHierarchyCount; a++)
2053 : {
2054 0 : const ViewObjectContact& rCandidate(rVOC.GetViewContact().GetViewContact(a).GetViewObjectContact(rVOC.GetObjectContact()));
2055 :
2056 0 : if(rCandidate.GetViewContact().GetObjectCount())
2057 : {
2058 : // is a group object itself, call resursively
2059 0 : impAddPrimitivesFromGroup(rCandidate, rOffsetMatrix, rDisplayInfo, rxTarget);
2060 : }
2061 : else
2062 : {
2063 : // single object, add primitives; check model-view visibility
2064 0 : if(rCandidate.isPrimitiveVisible(rDisplayInfo))
2065 : {
2066 0 : drawinglayer::primitive2d::Primitive2DSequence aNewSequence(rCandidate.getPrimitive2DSequence(rDisplayInfo));
2067 :
2068 0 : if(aNewSequence.hasElements())
2069 : {
2070 : // get ranges
2071 0 : const drawinglayer::geometry::ViewInformation2D& rViewInformation2D(rCandidate.GetObjectContact().getViewInformation2D());
2072 0 : const basegfx::B2DRange aViewRange(rViewInformation2D.getViewport());
2073 0 : basegfx::B2DRange aObjectRange(rCandidate.getObjectRange());
2074 :
2075 : // correct with virtual object's offset
2076 0 : aObjectRange.transform(rOffsetMatrix);
2077 :
2078 : // check geometrical visibility (with offset)
2079 0 : if(!aViewRange.overlaps(aObjectRange))
2080 : {
2081 : // not visible, release
2082 0 : aNewSequence.realloc(0);
2083 : }
2084 : }
2085 :
2086 0 : if(aNewSequence.hasElements())
2087 : {
2088 0 : drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rxTarget, aNewSequence);
2089 0 : }
2090 : }
2091 : }
2092 : }
2093 0 : }
2094 :
2095 1250 : drawinglayer::primitive2d::Primitive2DSequence VOCOfDrawVirtObj::createPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const
2096 : {
2097 1250 : const VCOfDrawVirtObj& rVC = static_cast< const VCOfDrawVirtObj& >(GetViewContact());
2098 1250 : const SdrObject& rReferencedObject = rVC.GetSwDrawVirtObj().GetReferencedObj();
2099 1250 : drawinglayer::primitive2d::Primitive2DSequence xRetval;
2100 :
2101 : // create offset transformation
2102 2500 : basegfx::B2DHomMatrix aOffsetMatrix;
2103 1250 : const Point aLocalOffset(rVC.GetSwDrawVirtObj().GetOffset());
2104 :
2105 1250 : if(aLocalOffset.X() || aLocalOffset.Y())
2106 : {
2107 1250 : aOffsetMatrix.set(0, 2, aLocalOffset.X());
2108 1250 : aOffsetMatrix.set(1, 2, aLocalOffset.Y());
2109 : }
2110 :
2111 1250 : if(rReferencedObject.ISA(SdrObjGroup))
2112 : {
2113 : // group object. Since the VOC/OC/VC hierarchy does not represent the
2114 : // hierarchy virtual objects when they have group objects
2115 : // (ViewContactOfVirtObj::GetObjectCount() returns null for that purpose)
2116 : // to avoid multiple usages of VOCs (which would not work), the primitives
2117 : // for the sub-hierarchy need to be collected here
2118 :
2119 : // Get the VOC of the referenced object (the Group) and fetch primitives from it
2120 0 : const ViewObjectContact& rVOCOfRefObj = rReferencedObject.GetViewContact().GetViewObjectContact(GetObjectContact());
2121 0 : impAddPrimitivesFromGroup(rVOCOfRefObj, aOffsetMatrix, rDisplayInfo, xRetval);
2122 : }
2123 : else
2124 : {
2125 : // single object, use method from referenced object to get the Primitive2DSequence
2126 1250 : xRetval = rReferencedObject.GetViewContact().getViewIndependentPrimitive2DSequence();
2127 : }
2128 :
2129 1250 : if(xRetval.hasElements())
2130 : {
2131 : // create transform primitive
2132 1250 : const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::TransformPrimitive2D(aOffsetMatrix, xRetval));
2133 1250 : xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1);
2134 : }
2135 :
2136 2500 : return xRetval;
2137 : }
2138 :
2139 836 : VOCOfDrawVirtObj::~VOCOfDrawVirtObj()
2140 : {
2141 836 : }
2142 :
2143 418 : ViewObjectContact& VCOfDrawVirtObj::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact)
2144 : {
2145 418 : return *(new VOCOfDrawVirtObj(rObjectContact, *this));
2146 : }
2147 :
2148 852 : VCOfDrawVirtObj::~VCOfDrawVirtObj()
2149 : {
2150 852 : }
2151 : } // end of namespace contact
2152 : } // end of namespace sdr
2153 :
2154 : /// implementation of class <SwDrawVirtObj>
2155 400174 : TYPEINIT1(SwDrawVirtObj,SdrVirtObj);
2156 :
2157 426 : sdr::contact::ViewContact* SwDrawVirtObj::CreateObjectSpecificViewContact()
2158 : {
2159 426 : return new sdr::contact::VCOfDrawVirtObj(*this);
2160 : }
2161 :
2162 426 : SwDrawVirtObj::SwDrawVirtObj( SdrObject& _rNewObj,
2163 : SwDrawContact& _rDrawContact )
2164 : : SdrVirtObj( _rNewObj ),
2165 : // #i26791# - init new member <maAnchoredDrawObj>
2166 : maAnchoredDrawObj(),
2167 426 : mrDrawContact( _rDrawContact )
2168 : {
2169 : // #i26791#
2170 426 : maAnchoredDrawObj.SetDrawObj( *this );
2171 : // #i35635# - set initial position out of sight
2172 426 : NbcMove( Size( -RECT_EMPTY, -RECT_EMPTY ) );
2173 426 : }
2174 :
2175 852 : SwDrawVirtObj::~SwDrawVirtObj()
2176 852 : {}
2177 :
2178 0 : SwDrawVirtObj& SwDrawVirtObj::operator=( const SwDrawVirtObj& rObj )
2179 : {
2180 0 : SdrVirtObj::operator=(rObj);
2181 : // Note: Members <maAnchoredDrawObj> and <mrDrawContact>
2182 : // haven't to be considered.
2183 0 : return *this;
2184 : }
2185 :
2186 0 : SwDrawVirtObj* SwDrawVirtObj::Clone() const
2187 : {
2188 0 : SwDrawVirtObj* pObj = new SwDrawVirtObj( rRefObj, mrDrawContact );
2189 :
2190 0 : if ( pObj )
2191 : {
2192 0 : pObj->operator=( *this );
2193 : // Note: Member <maAnchoredDrawObj> hasn't to be considered.
2194 : }
2195 :
2196 0 : return pObj;
2197 : }
2198 :
2199 14580 : const SwFrm* SwDrawVirtObj::GetAnchorFrm() const
2200 : {
2201 : // #i26791# - use new member <maAnchoredDrawObj>
2202 14580 : return maAnchoredDrawObj.GetAnchorFrm();
2203 : }
2204 :
2205 654 : SwFrm* SwDrawVirtObj::AnchorFrm()
2206 : {
2207 : // #i26791# - use new member <maAnchoredDrawObj>
2208 654 : return maAnchoredDrawObj.AnchorFrm();
2209 : }
2210 :
2211 1976 : void SwDrawVirtObj::RemoveFromWriterLayout()
2212 : {
2213 : // remove contact object from frame for 'virtual' drawing object
2214 : // #i26791# - use new member <maAnchoredDrawObj>
2215 1976 : if ( maAnchoredDrawObj.GetAnchorFrm() )
2216 : {
2217 698 : maAnchoredDrawObj.AnchorFrm()->RemoveDrawObj( maAnchoredDrawObj );
2218 : }
2219 1976 : }
2220 :
2221 698 : void SwDrawVirtObj::AddToDrawingPage()
2222 : {
2223 : // determine 'master'
2224 698 : SdrObject* pOrgMasterSdrObj = mrDrawContact.GetMaster();
2225 :
2226 : // insert 'virtual' drawing object into page, set layer and user call.
2227 : SdrPage* pDrawPg;
2228 : // #i27030# - apply order number of referenced object
2229 698 : if ( 0 != ( pDrawPg = pOrgMasterSdrObj->GetPage() ) )
2230 : {
2231 : // #i27030# - apply order number of referenced object
2232 698 : pDrawPg->InsertObject( this, GetReferencedObj().GetOrdNum() );
2233 : }
2234 : else
2235 : {
2236 0 : pDrawPg = GetPage();
2237 0 : if ( pDrawPg )
2238 : {
2239 0 : pDrawPg->SetObjectOrdNum( GetOrdNumDirect(),
2240 0 : GetReferencedObj().GetOrdNum() );
2241 : }
2242 : else
2243 : {
2244 0 : SetOrdNum( GetReferencedObj().GetOrdNum() );
2245 : }
2246 : }
2247 698 : SetUserCall( &mrDrawContact );
2248 698 : }
2249 :
2250 1976 : void SwDrawVirtObj::RemoveFromDrawingPage()
2251 : {
2252 1976 : SetUserCall( 0 );
2253 1976 : if ( GetPage() )
2254 : {
2255 698 : GetPage()->RemoveObject( GetOrdNum() );
2256 : }
2257 1976 : }
2258 :
2259 : /// Is 'virtual' drawing object connected to writer layout and to drawing layer?
2260 9826 : bool SwDrawVirtObj::IsConnected() const
2261 : {
2262 24022 : bool bRetVal = GetAnchorFrm() &&
2263 24022 : ( GetPage() && GetUserCall() );
2264 :
2265 9826 : return bRetVal;
2266 : }
2267 :
2268 822 : void SwDrawVirtObj::NbcSetAnchorPos(const Point& rPnt)
2269 : {
2270 822 : SdrObject::NbcSetAnchorPos( rPnt );
2271 822 : }
2272 :
2273 : // #i97197#
2274 : // the methods relevant for positioning
2275 :
2276 2282 : const Rectangle& SwDrawVirtObj::GetCurrentBoundRect() const
2277 : {
2278 2282 : if(aOutRect.IsEmpty())
2279 : {
2280 426 : const_cast<SwDrawVirtObj*>(this)->RecalcBoundRect();
2281 : }
2282 :
2283 2282 : return aOutRect;
2284 : }
2285 :
2286 8576 : const Rectangle& SwDrawVirtObj::GetLastBoundRect() const
2287 : {
2288 8576 : return aOutRect;
2289 : }
2290 :
2291 72732 : const Point SwDrawVirtObj::GetOffset() const
2292 : {
2293 : // do NOT use IsEmpty() here, there is already a useful offset
2294 : // in the position
2295 72732 : if(aOutRect == Rectangle())
2296 : {
2297 0 : return Point();
2298 : }
2299 : else
2300 : {
2301 72732 : return aOutRect.TopLeft() - GetReferencedObj().GetCurrentBoundRect().TopLeft();
2302 : }
2303 : }
2304 :
2305 4420 : void SwDrawVirtObj::SetBoundRectDirty()
2306 : {
2307 : // do nothing to not lose model information in aOutRect
2308 4420 : }
2309 :
2310 426 : void SwDrawVirtObj::RecalcBoundRect()
2311 : {
2312 : // #i26791# - switch order of calling <GetOffset()> and
2313 : // <ReferencedObj().GetCurrentBoundRect()>, because <GetOffset()> calculates
2314 : // its value by the 'BoundRect' of the referenced object.
2315 :
2316 426 : const Point aOffset(GetOffset());
2317 426 : aOutRect = ReferencedObj().GetCurrentBoundRect() + aOffset;
2318 426 : }
2319 :
2320 0 : basegfx::B2DPolyPolygon SwDrawVirtObj::TakeXorPoly() const
2321 : {
2322 0 : basegfx::B2DPolyPolygon aRetval(rRefObj.TakeXorPoly());
2323 0 : aRetval.transform(basegfx::tools::createTranslateB2DHomMatrix(GetOffset().X(), GetOffset().Y()));
2324 :
2325 0 : return aRetval;
2326 : }
2327 :
2328 0 : basegfx::B2DPolyPolygon SwDrawVirtObj::TakeContour() const
2329 : {
2330 0 : basegfx::B2DPolyPolygon aRetval(rRefObj.TakeContour());
2331 0 : aRetval.transform(basegfx::tools::createTranslateB2DHomMatrix(GetOffset().X(), GetOffset().Y()));
2332 :
2333 0 : return aRetval;
2334 : }
2335 :
2336 0 : SdrHdl* SwDrawVirtObj::GetHdl(sal_uInt32 nHdlNum) const
2337 : {
2338 0 : SdrHdl* pHdl = rRefObj.GetHdl(nHdlNum);
2339 :
2340 0 : if(pHdl)
2341 : {
2342 0 : Point aP(pHdl->GetPos() + GetOffset());
2343 0 : pHdl->SetPos(aP);
2344 : }
2345 : else
2346 : {
2347 : OSL_ENSURE(false, "Got no SdrHdl(!)");
2348 : }
2349 :
2350 0 : return pHdl;
2351 : }
2352 :
2353 0 : SdrHdl* SwDrawVirtObj::GetPlusHdl(const SdrHdl& rHdl, sal_uInt16 nPlNum) const
2354 : {
2355 0 : SdrHdl* pHdl = rRefObj.GetPlusHdl(rHdl, nPlNum);
2356 :
2357 0 : if(pHdl)
2358 : {
2359 0 : pHdl->SetPos(pHdl->GetPos() + GetOffset());
2360 : }
2361 : else
2362 : {
2363 : OSL_ENSURE(false, "Got no SdrHdl(!)");
2364 : }
2365 :
2366 0 : return pHdl;
2367 : }
2368 :
2369 3318 : void SwDrawVirtObj::NbcMove(const Size& rSiz)
2370 : {
2371 3318 : SdrObject::NbcMove( rSiz );
2372 3318 : }
2373 :
2374 0 : void SwDrawVirtObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
2375 : {
2376 0 : rRefObj.NbcResize(rRef - GetOffset(), xFact, yFact);
2377 0 : SetRectsDirty();
2378 0 : }
2379 :
2380 0 : void SwDrawVirtObj::NbcRotate(const Point& rRef, long nWink, double sn, double cs)
2381 : {
2382 0 : rRefObj.NbcRotate(rRef - GetOffset(), nWink, sn, cs);
2383 0 : SetRectsDirty();
2384 0 : }
2385 :
2386 0 : void SwDrawVirtObj::NbcMirror(const Point& rRef1, const Point& rRef2)
2387 : {
2388 0 : rRefObj.NbcMirror(rRef1 - GetOffset(), rRef2 - GetOffset());
2389 0 : SetRectsDirty();
2390 0 : }
2391 :
2392 0 : void SwDrawVirtObj::NbcShear(const Point& rRef, long nWink, double tn, bool bVShear)
2393 : {
2394 0 : rRefObj.NbcShear(rRef - GetOffset(), nWink, tn, bVShear);
2395 0 : SetRectsDirty();
2396 0 : }
2397 :
2398 6102 : void SwDrawVirtObj::Move(const Size& rSiz)
2399 : {
2400 6102 : SdrObject::Move( rSiz );
2401 6102 : }
2402 :
2403 0 : void SwDrawVirtObj::Resize(const Point& rRef, const Fraction& xFact, const Fraction& yFact, bool bUnsetRelative)
2404 : {
2405 0 : if(xFact.GetNumerator() != xFact.GetDenominator() || yFact.GetNumerator() != yFact.GetDenominator())
2406 : {
2407 0 : Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
2408 0 : rRefObj.Resize(rRef - GetOffset(), xFact, yFact, bUnsetRelative);
2409 0 : SetRectsDirty();
2410 0 : SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
2411 : }
2412 0 : }
2413 :
2414 0 : void SwDrawVirtObj::Rotate(const Point& rRef, long nWink, double sn, double cs)
2415 : {
2416 0 : if(nWink)
2417 : {
2418 0 : Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
2419 0 : rRefObj.Rotate(rRef - GetOffset(), nWink, sn, cs);
2420 0 : SetRectsDirty();
2421 0 : SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
2422 : }
2423 0 : }
2424 :
2425 0 : void SwDrawVirtObj::Mirror(const Point& rRef1, const Point& rRef2)
2426 : {
2427 0 : Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
2428 0 : rRefObj.Mirror(rRef1 - GetOffset(), rRef2 - GetOffset());
2429 0 : SetRectsDirty();
2430 0 : SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
2431 0 : }
2432 :
2433 0 : void SwDrawVirtObj::Shear(const Point& rRef, long nWink, double tn, bool bVShear)
2434 : {
2435 0 : if(nWink)
2436 : {
2437 0 : Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
2438 0 : rRefObj.Shear(rRef - GetOffset(), nWink, tn, bVShear);
2439 0 : SetRectsDirty();
2440 0 : SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
2441 : }
2442 0 : }
2443 :
2444 0 : void SwDrawVirtObj::RecalcSnapRect()
2445 : {
2446 0 : aSnapRect = rRefObj.GetSnapRect();
2447 0 : aSnapRect += GetOffset();
2448 0 : }
2449 :
2450 71056 : const Rectangle& SwDrawVirtObj::GetSnapRect() const
2451 : {
2452 71056 : ((SwDrawVirtObj*)this)->aSnapRect = rRefObj.GetSnapRect();
2453 71056 : ((SwDrawVirtObj*)this)->aSnapRect += GetOffset();
2454 :
2455 71056 : return aSnapRect;
2456 : }
2457 :
2458 0 : void SwDrawVirtObj::SetSnapRect(const Rectangle& rRect)
2459 : {
2460 0 : Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
2461 0 : Rectangle aR(rRect);
2462 0 : aR -= GetOffset();
2463 0 : rRefObj.SetSnapRect(aR);
2464 0 : SetRectsDirty();
2465 0 : SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
2466 0 : }
2467 :
2468 0 : void SwDrawVirtObj::NbcSetSnapRect(const Rectangle& rRect)
2469 : {
2470 0 : Rectangle aR(rRect);
2471 0 : aR -= GetOffset();
2472 0 : SetRectsDirty();
2473 0 : rRefObj.NbcSetSnapRect(aR);
2474 0 : }
2475 :
2476 0 : const Rectangle& SwDrawVirtObj::GetLogicRect() const
2477 : {
2478 0 : ((SwDrawVirtObj*)this)->aSnapRect = rRefObj.GetLogicRect();
2479 0 : ((SwDrawVirtObj*)this)->aSnapRect += GetOffset();
2480 :
2481 0 : return aSnapRect;
2482 : }
2483 :
2484 0 : void SwDrawVirtObj::SetLogicRect(const Rectangle& rRect)
2485 : {
2486 0 : Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect();
2487 0 : Rectangle aR(rRect);
2488 0 : aR -= GetOffset();
2489 0 : rRefObj.SetLogicRect(aR);
2490 0 : SetRectsDirty();
2491 0 : SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
2492 0 : }
2493 :
2494 0 : void SwDrawVirtObj::NbcSetLogicRect(const Rectangle& rRect)
2495 : {
2496 0 : Rectangle aR(rRect);
2497 0 : aR -= GetOffset();
2498 0 : rRefObj.NbcSetLogicRect(aR);
2499 0 : SetRectsDirty();
2500 0 : }
2501 :
2502 0 : Point SwDrawVirtObj::GetSnapPoint(sal_uInt32 i) const
2503 : {
2504 0 : Point aP(rRefObj.GetSnapPoint(i));
2505 0 : aP += GetOffset();
2506 :
2507 0 : return aP;
2508 : }
2509 :
2510 0 : Point SwDrawVirtObj::GetPoint(sal_uInt32 i) const
2511 : {
2512 0 : return Point(rRefObj.GetPoint(i) + GetOffset());
2513 : }
2514 :
2515 0 : void SwDrawVirtObj::NbcSetPoint(const Point& rPnt, sal_uInt32 i)
2516 : {
2517 0 : Point aP(rPnt);
2518 0 : aP -= GetOffset();
2519 0 : rRefObj.SetPoint(aP, i);
2520 0 : SetRectsDirty();
2521 0 : }
2522 :
2523 0 : bool SwDrawVirtObj::HasTextEdit() const
2524 : {
2525 0 : return rRefObj.HasTextEdit();
2526 : }
2527 :
2528 : // overloaded 'layer' methods for 'virtual' drawing object to assure,
2529 : // that layer of 'virtual' object is the layer of the referenced object.
2530 37338 : SdrLayerID SwDrawVirtObj::GetLayer() const
2531 : {
2532 37338 : return GetReferencedObj().GetLayer();
2533 : }
2534 :
2535 0 : void SwDrawVirtObj::NbcSetLayer(SdrLayerID nLayer)
2536 : {
2537 0 : ReferencedObj().NbcSetLayer( nLayer );
2538 0 : SdrVirtObj::NbcSetLayer( ReferencedObj().GetLayer() );
2539 0 : }
2540 :
2541 0 : void SwDrawVirtObj::SetLayer(SdrLayerID nLayer)
2542 : {
2543 0 : ReferencedObj().SetLayer( nLayer );
2544 0 : SdrVirtObj::NbcSetLayer( ReferencedObj().GetLayer() );
2545 0 : }
2546 :
2547 0 : bool SwDrawVirtObj::supportsFullDrag() const
2548 : {
2549 : // call parent
2550 0 : return SdrVirtObj::supportsFullDrag();
2551 : }
2552 :
2553 0 : SdrObject* SwDrawVirtObj::getFullDragClone() const
2554 : {
2555 : // call parent
2556 0 : return SdrVirtObj::getFullDragClone();
2557 270 : }
2558 :
2559 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|