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