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