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