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 //-->Modified for i119654,2012.6.8 1509 SwFrm *pAnchorFrame = NULL; 1510 if ( pAnchoredDrawObj && ( pAnchorFrame = 1511 const_cast<SwAnchoredDrawObject*>( pAnchoredDrawObj )->AnchorFrm() ) ) 1512 pAnchorFrame->Prepare( PREP_FLY_ATTR_CHG, GetFmt() ); 1513 //<-- 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