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