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