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 = pAnchoredDrawObj 1510 ? const_cast<SwAnchoredDrawObject*>( pAnchoredDrawObj )->AnchorFrm() 1511 : NULL; 1512 if ( pAnchorFrame ) 1513 { 1514 pAnchorFrame->Prepare( PREP_FLY_ATTR_CHG, GetFmt() ); 1515 } 1516 //<-- 1517 } 1518 // <-- 1519 } 1520 } 1521 // --> OD 2006-01-18 #129959# 1522 // It reveals that the following code causes several defects - 1523 // on copying or on ungrouping a group shape containing edge objects. 1524 // Testing fix for #i53320# also reveal that the following code 1525 // isn't necessary. 1526 // // --> OD 2005-08-15 #i53320# - reset positioning attributes, 1527 // // if anchored drawing object isn't yet positioned. 1528 // else if ( pAnchoredDrawObj->NotYetPositioned() && 1529 // static_cast<const SwDrawFrmFmt&>(pAnchoredDrawObj->GetFrmFmt()).IsPosAttrSet() ) 1530 // { 1531 // const_cast<SwDrawFrmFmt&>( 1532 // static_cast<const SwDrawFrmFmt&>(pAnchoredDrawObj->GetFrmFmt())) 1533 // .ResetPosAttr(); 1534 // } 1535 // // <-- 1536 // <-- 1537 } 1538 break; 1539 case SDRUSERCALL_CHGATTR: 1540 if ( bNotify ) 1541 { 1542 lcl_NotifyBackgroundOfObj( *this, rObj, pOldBoundRect ); 1543 } 1544 break; 1545 default: 1546 break; 1547 } 1548 } 1549 1550 namespace 1551 { 1552 static const SwFmtAnchor* lcl_getAnchorFmt( const SfxPoolItem& _rItem ) 1553 { 1554 sal_uInt16 nWhich = _rItem.Which(); 1555 const SwFmtAnchor* pAnchorFmt = NULL; 1556 if ( RES_ATTRSET_CHG == nWhich ) 1557 { 1558 static_cast<const SwAttrSetChg&>(_rItem).GetChgSet()-> 1559 GetItemState( RES_ANCHOR, sal_False, (const SfxPoolItem**)&pAnchorFmt ); 1560 } 1561 else if ( RES_ANCHOR == nWhich ) 1562 { 1563 pAnchorFmt = &static_cast<const SwFmtAnchor&>(_rItem); 1564 } 1565 return pAnchorFmt; 1566 } 1567 } 1568 1569 /************************************************************************* 1570 |* 1571 |* SwDrawContact::Modify() 1572 |* 1573 |* Ersterstellung MA 09. Jan. 95 1574 |* Letzte Aenderung MA 03. Dec. 95 1575 |* 1576 |*************************************************************************/ 1577 1578 void SwDrawContact::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew ) 1579 { 1580 // OD 10.10.2003 #112299# 1581 ASSERT( !mbDisconnectInProgress, 1582 "<SwDrawContact::Modify(..)> called during disconnection."); 1583 1584 sal_uInt16 nWhich = pNew ? pNew->Which() : 0; 1585 const SwFmtAnchor* pNewAnchorFmt = pNew ? lcl_getAnchorFmt( *pNew ) : NULL; 1586 1587 if ( pNewAnchorFmt ) 1588 { 1589 // JP 10.04.95: nicht auf ein Reset Anchor reagieren !!!!! 1590 if ( SFX_ITEM_SET == 1591 GetFmt()->GetAttrSet().GetItemState( RES_ANCHOR, sal_False ) ) 1592 { 1593 // OD 10.10.2003 #112299# - no connect to layout during disconnection 1594 if ( !mbDisconnectInProgress ) 1595 { 1596 // determine old object retangle of 'master' drawing object 1597 // for notification 1598 const Rectangle* pOldRect = 0L; 1599 Rectangle aOldRect; 1600 if ( GetAnchorFrm() ) 1601 { 1602 // --> OD 2004-10-27 #i36181# - include spacing in object 1603 // rectangle for notification. 1604 aOldRect = maAnchoredDrawObj.GetObjRectWithSpaces().SVRect(); 1605 pOldRect = &aOldRect; 1606 // <-- 1607 } 1608 // re-connect to layout due to anchor format change 1609 ConnectToLayout( pNewAnchorFmt ); 1610 // notify background of drawing objects 1611 lcl_NotifyBackgroundOfObj( *this, *GetMaster(), pOldRect ); 1612 NotifyBackgrdOfAllVirtObjs( pOldRect ); 1613 1614 const SwFmtAnchor* pOldAnchorFmt = pOld ? lcl_getAnchorFmt( *pOld ) : NULL; 1615 if ( !pOldAnchorFmt || ( pOldAnchorFmt->GetAnchorId() != pNewAnchorFmt->GetAnchorId() ) ) 1616 { 1617 ASSERT( maAnchoredDrawObj.DrawObj(), "SwDrawContact::Modify: no draw object here?" ); 1618 if ( maAnchoredDrawObj.DrawObj() ) 1619 { 1620 // --> OD 2009-07-10 #i102752# 1621 // assure that a ShapePropertyChangeNotifier exists 1622 maAnchoredDrawObj.DrawObj()->notifyShapePropertyChange( ::svx::eTextShapeAnchorType ); 1623 // <-- 1624 } 1625 } 1626 } 1627 } 1628 else 1629 DisconnectFromLayout(); 1630 } 1631 // --> OD 2006-03-17 #i62875# - revised fix for issue #124157# 1632 // no further notification, if not connected to Writer layout 1633 else if ( maAnchoredDrawObj.GetAnchorFrm() && 1634 maAnchoredDrawObj.GetDrawObj()->GetUserCall() ) 1635 { 1636 // --> OD 2004-07-01 #i28701# - on change of wrapping style, hell|heaven layer, 1637 // or wrapping style influence an update of the <SwSortedObjs> list, 1638 // the drawing object is registered in, has to be performed. This is triggered 1639 // by the 1st parameter of method call <_InvalidateObjs(..)>. 1640 if ( RES_SURROUND == nWhich || 1641 RES_OPAQUE == nWhich || 1642 RES_WRAP_INFLUENCE_ON_OBJPOS == nWhich || 1643 ( RES_ATTRSET_CHG == nWhich && 1644 ( SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState( 1645 RES_SURROUND, sal_False ) || 1646 SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState( 1647 RES_OPAQUE, sal_False ) || 1648 SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState( 1649 RES_WRAP_INFLUENCE_ON_OBJPOS, sal_False ) ) ) ) 1650 { 1651 lcl_NotifyBackgroundOfObj( *this, *GetMaster(), 0L ); 1652 NotifyBackgrdOfAllVirtObjs( 0L ); 1653 _InvalidateObjs( true ); 1654 } 1655 else if ( RES_UL_SPACE == nWhich || RES_LR_SPACE == nWhich || 1656 RES_HORI_ORIENT == nWhich || RES_VERT_ORIENT == nWhich || 1657 // --> OD 2004-07-01 #i28701# - add attribute 'Follow text flow' 1658 RES_FOLLOW_TEXT_FLOW == nWhich || 1659 ( RES_ATTRSET_CHG == nWhich && 1660 ( SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState( 1661 RES_LR_SPACE, sal_False ) || 1662 SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState( 1663 RES_UL_SPACE, sal_False ) || 1664 SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState( 1665 RES_HORI_ORIENT, sal_False ) || 1666 SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState( 1667 RES_VERT_ORIENT, sal_False ) || 1668 SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState( 1669 RES_FOLLOW_TEXT_FLOW, sal_False ) ) ) ) 1670 { 1671 lcl_NotifyBackgroundOfObj( *this, *GetMaster(), 0L ); 1672 NotifyBackgrdOfAllVirtObjs( 0L ); 1673 _InvalidateObjs(); 1674 } 1675 // --> OD 2004-10-26 #i35443# 1676 else if ( RES_ATTRSET_CHG == nWhich ) 1677 { 1678 lcl_NotifyBackgroundOfObj( *this, *GetMaster(), 0L ); 1679 NotifyBackgrdOfAllVirtObjs( 0L ); 1680 _InvalidateObjs(); 1681 } 1682 // <-- 1683 else if ( RES_REMOVE_UNO_OBJECT == nWhich ) 1684 { 1685 // nothing to do 1686 } 1687 #if OSL_DEBUG_LEVEL > 1 1688 else 1689 { 1690 ASSERT( false, 1691 "<SwDrawContact::Modify(..)> - unhandled attribute? - please inform od@openoffice.org" ); 1692 } 1693 #endif 1694 } 1695 1696 // --> OD 2005-07-18 #i51474# 1697 GetAnchoredObj( 0L )->ResetLayoutProcessBools(); 1698 // <-- 1699 } 1700 1701 // OD 2004-03-31 #i26791# 1702 // --> OD 2004-07-01 #i28701# - added parameter <_bUpdateSortedObjsList> 1703 void SwDrawContact::_InvalidateObjs( const bool _bUpdateSortedObjsList ) 1704 { 1705 // invalidate position of existing 'virtual' drawing objects 1706 for ( std::list<SwDrawVirtObj*>::iterator aDisconnectIter = maDrawVirtObjs.begin(); 1707 aDisconnectIter != maDrawVirtObjs.end(); 1708 ++aDisconnectIter ) 1709 { 1710 SwDrawVirtObj* pDrawVirtObj = (*aDisconnectIter); 1711 // --> OD 2004-08-23 #i33313# - invalidation only for connected 1712 // 'virtual' drawing objects 1713 if ( pDrawVirtObj->IsConnected() ) 1714 { 1715 pDrawVirtObj->AnchoredObj()->InvalidateObjPos(); 1716 // --> OD 2004-07-01 #i28701# 1717 if ( _bUpdateSortedObjsList ) 1718 { 1719 pDrawVirtObj->AnchoredObj()->UpdateObjInSortedList(); 1720 } 1721 // <-- 1722 } 1723 // <-- 1724 } 1725 1726 // invalidate position of 'master' drawing object 1727 SwAnchoredObject* pAnchoredObj = GetAnchoredObj( 0L ); 1728 pAnchoredObj->InvalidateObjPos(); 1729 // --> OD 2004-07-01 #i28701# 1730 if ( _bUpdateSortedObjsList ) 1731 { 1732 pAnchoredObj->UpdateObjInSortedList(); 1733 } 1734 // <-- 1735 } 1736 1737 /************************************************************************* 1738 |* 1739 |* SwDrawContact::DisconnectFromLayout() 1740 |* 1741 |* Ersterstellung MA 09. Jan. 95 1742 |* Letzte Aenderung MA 25. Mar. 99 1743 |* 1744 |*************************************************************************/ 1745 1746 void SwDrawContact::DisconnectFromLayout( bool _bMoveMasterToInvisibleLayer ) 1747 { 1748 // OD 10.10.2003 #112299# 1749 mbDisconnectInProgress = true; 1750 1751 // --> OD 2004-10-27 #i36181# - notify background of drawing object 1752 if ( _bMoveMasterToInvisibleLayer && 1753 !(GetFmt()->GetDoc()->IsInDtor()) && 1754 GetAnchorFrm() ) 1755 { 1756 const Rectangle aOldRect( maAnchoredDrawObj.GetObjRectWithSpaces().SVRect() ); 1757 lcl_NotifyBackgroundOfObj( *this, *GetMaster(), &aOldRect ); 1758 NotifyBackgrdOfAllVirtObjs( &aOldRect ); 1759 } 1760 // <-- 1761 1762 // OD 16.05.2003 #108784# - remove 'virtual' drawing objects from writer 1763 // layout and from drawing page 1764 for ( std::list<SwDrawVirtObj*>::iterator aDisconnectIter = maDrawVirtObjs.begin(); 1765 aDisconnectIter != maDrawVirtObjs.end(); 1766 ++aDisconnectIter ) 1767 { 1768 SwDrawVirtObj* pDrawVirtObj = (*aDisconnectIter); 1769 pDrawVirtObj->RemoveFromWriterLayout(); 1770 pDrawVirtObj->RemoveFromDrawingPage(); 1771 } 1772 1773 if ( maAnchoredDrawObj.GetAnchorFrm() ) 1774 { 1775 maAnchoredDrawObj.AnchorFrm()->RemoveDrawObj( maAnchoredDrawObj ); 1776 } 1777 1778 if ( _bMoveMasterToInvisibleLayer && GetMaster() && GetMaster()->IsInserted() ) 1779 { 1780 SdrViewIter aIter( GetMaster() ); 1781 for( SdrView* pView = aIter.FirstView(); pView; 1782 pView = aIter.NextView() ) 1783 { 1784 pView->MarkObj( GetMaster(), pView->GetSdrPageView(), sal_True ); 1785 } 1786 1787 // OD 25.06.2003 #108784# - Instead of removing 'master' object from 1788 // drawing page, move the 'master' drawing object into the corresponding 1789 // invisible layer. 1790 { 1791 //((SwFrmFmt*)GetRegisteredIn())->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage(0)-> 1792 // RemoveObject( GetMaster()->GetOrdNum() ); 1793 // OD 21.08.2003 #i18447# - in order to consider group object correct 1794 // use new method <SwDrawContact::MoveObjToInvisibleLayer(..)> 1795 MoveObjToInvisibleLayer( GetMaster() ); 1796 } 1797 } 1798 1799 // OD 10.10.2003 #112299# 1800 mbDisconnectInProgress = false; 1801 } 1802 1803 // OD 26.06.2003 #108784# - method to remove 'master' drawing object 1804 // from drawing page. 1805 void SwDrawContact::RemoveMasterFromDrawPage() 1806 { 1807 if ( GetMaster() ) 1808 { 1809 GetMaster()->SetUserCall( 0 ); 1810 if ( GetMaster()->IsInserted() ) 1811 { 1812 ((SwFrmFmt*)GetRegisteredIn())->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage(0)-> 1813 RemoveObject( GetMaster()->GetOrdNum() ); 1814 } 1815 } 1816 } 1817 1818 // OD 19.06.2003 #108784# - disconnect for a dedicated drawing object - 1819 // could be 'master' or 'virtual'. 1820 // a 'master' drawing object will disconnect a 'virtual' drawing object 1821 // in order to take its place. 1822 // OD 13.10.2003 #i19919# - no special case, if drawing object isn't in 1823 // page header/footer, in order to get drawing objects in repeating table headers 1824 // also working. 1825 void SwDrawContact::DisconnectObjFromLayout( SdrObject* _pDrawObj ) 1826 { 1827 if ( _pDrawObj->ISA(SwDrawVirtObj) ) 1828 { 1829 SwDrawVirtObj* pDrawVirtObj = static_cast<SwDrawVirtObj*>(_pDrawObj); 1830 pDrawVirtObj->RemoveFromWriterLayout(); 1831 pDrawVirtObj->RemoveFromDrawingPage(); 1832 } 1833 else 1834 { 1835 std::list<SwDrawVirtObj*>::const_iterator aFoundVirtObjIter = 1836 std::find_if( maDrawVirtObjs.begin(), maDrawVirtObjs.end(), 1837 UsedOrUnusedVirtObjPred( true ) ); 1838 if ( aFoundVirtObjIter != maDrawVirtObjs.end() ) 1839 { 1840 // replace found 'virtual' drawing object by 'master' drawing 1841 // object and disconnect the 'virtual' one 1842 SwDrawVirtObj* pDrawVirtObj = (*aFoundVirtObjIter); 1843 SwFrm* pNewAnchorFrmOfMaster = pDrawVirtObj->AnchorFrm(); 1844 // disconnect 'virtual' drawing object 1845 pDrawVirtObj->RemoveFromWriterLayout(); 1846 pDrawVirtObj->RemoveFromDrawingPage(); 1847 // disconnect 'master' drawing object from current frame 1848 GetAnchorFrm()->RemoveDrawObj( maAnchoredDrawObj ); 1849 // re-connect 'master' drawing object to frame of found 'virtual' 1850 // drawing object. 1851 pNewAnchorFrmOfMaster->AppendDrawObj( maAnchoredDrawObj ); 1852 } 1853 else 1854 { 1855 // no connected 'virtual' drawing object found. Thus, disconnect 1856 // completely from layout. 1857 DisconnectFromLayout(); 1858 } 1859 } 1860 } 1861 1862 /************************************************************************* 1863 |* 1864 |* SwDrawContact::ConnectToLayout() 1865 |* 1866 |* Ersterstellung MA 09. Jan. 95 1867 |* Letzte Aenderung MA 25. Mar. 99 1868 |* 1869 |*************************************************************************/ 1870 SwTxtFrm* lcl_GetFlyInCntntAnchor( SwTxtFrm* _pProposedAnchorFrm, 1871 const xub_StrLen _nTxtOfs ) 1872 { 1873 SwTxtFrm* pAct = _pProposedAnchorFrm; 1874 SwTxtFrm* pTmp; 1875 do 1876 { 1877 pTmp = pAct; 1878 pAct = pTmp->GetFollow(); 1879 } 1880 while( pAct && _nTxtOfs >= pAct->GetOfst() ); 1881 return pTmp; 1882 } 1883 1884 void SwDrawContact::ConnectToLayout( const SwFmtAnchor* pAnch ) 1885 { 1886 // OD 10.10.2003 #112299# - *no* connect to layout during disconnection from 1887 // layout. 1888 if ( mbDisconnectInProgress ) 1889 { 1890 ASSERT( false, 1891 "<SwDrawContact::ConnectToLayout(..)> called during disconnection."); 1892 return; 1893 } 1894 1895 // --> OD 2004-09-22 #i33909# - *no* connect to layout, if 'master' drawing 1896 // object isn't inserted in the drawing page 1897 if ( !GetMaster()->IsInserted() ) 1898 { 1899 ASSERT( false, "<SwDrawContact::ConnectToLayout(..)> - master drawing object not inserted -> no connect to layout. Please inform od@openoffice.org" ); 1900 return; 1901 } 1902 // <-- 1903 1904 SwFrmFmt* pDrawFrmFmt = (SwFrmFmt*)GetRegisteredIn(); 1905 1906 if( !pDrawFrmFmt->getIDocumentLayoutAccess()->GetCurrentViewShell() ) 1907 return; 1908 1909 // OD 16.05.2003 #108784# - remove 'virtual' drawing objects from writer 1910 // layout and from drawing page, and remove 'master' drawing object from 1911 // writer layout - 'master' object will remain in drawing page. 1912 DisconnectFromLayout( false ); 1913 1914 if ( !pAnch ) 1915 { 1916 pAnch = &(pDrawFrmFmt->GetAnchor()); 1917 } 1918 1919 switch ( pAnch->GetAnchorId() ) 1920 { 1921 case FLY_AT_PAGE: 1922 { 1923 sal_uInt16 nPgNum = pAnch->GetPageNum(); 1924 ViewShell *pShell = pDrawFrmFmt->getIDocumentLayoutAccess()->GetCurrentViewShell(); 1925 if( !pShell ) 1926 break; 1927 SwRootFrm* pRoot = pShell->GetLayout(); 1928 SwPageFrm *pPage = static_cast<SwPageFrm*>(pRoot->Lower()); 1929 1930 for ( sal_uInt16 i = 1; i < nPgNum && pPage; ++i ) 1931 { 1932 pPage = static_cast<SwPageFrm*>(pPage->GetNext()); 1933 } 1934 1935 if ( pPage ) 1936 { 1937 pPage->AppendDrawObj( maAnchoredDrawObj ); 1938 } 1939 else 1940 //Sieht doof aus, ist aber erlaubt (vlg. SwFEShell::SetPageObjsNewPage) 1941 pRoot->SetAssertFlyPages(); 1942 } 1943 break; 1944 1945 case FLY_AT_CHAR: 1946 case FLY_AT_PARA: 1947 case FLY_AT_FLY: 1948 case FLY_AS_CHAR: 1949 { 1950 if ( pAnch->GetAnchorId() == FLY_AS_CHAR ) 1951 { 1952 ClrContourCache( GetMaster() ); 1953 } 1954 // OD 16.05.2003 #108784# - support drawing objects in header/footer, 1955 // but not control objects: 1956 // anchor at first found frame the 'master' object and 1957 // at the following frames 'virtual' drawing objects. 1958 // Note: method is similar to <SwFlyFrmFmt::MakeFrms(..)> 1959 SwModify *pModify = 0; 1960 if( pAnch->GetCntntAnchor() ) 1961 { 1962 if ( pAnch->GetAnchorId() == FLY_AT_FLY ) 1963 { 1964 SwNodeIndex aIdx( pAnch->GetCntntAnchor()->nNode ); 1965 SwCntntNode* pCNd = pDrawFrmFmt->GetDoc()->GetNodes().GoNext( &aIdx ); 1966 if ( SwIterator<SwFrm,SwCntntNode>::FirstElement( *pCNd ) ) 1967 pModify = pCNd; 1968 else 1969 { 1970 const SwNodeIndex& rIdx = pAnch->GetCntntAnchor()->nNode; 1971 SwSpzFrmFmts& rFmts = *(pDrawFrmFmt->GetDoc()->GetSpzFrmFmts()); 1972 for( sal_uInt16 i = 0; i < rFmts.Count(); ++i ) 1973 { 1974 SwFrmFmt* pFlyFmt = rFmts[i]; 1975 if( pFlyFmt->GetCntnt().GetCntntIdx() && 1976 rIdx == *(pFlyFmt->GetCntnt().GetCntntIdx()) ) 1977 { 1978 pModify = pFlyFmt; 1979 break; 1980 } 1981 } 1982 } 1983 // --> OD 2004-06-15 #i29199# - It is possible, that 1984 // the anchor doesn't exist - E.g., reordering the 1985 // sub-documents in a master document. 1986 // Note: The anchor will be inserted later. 1987 if ( !pModify ) 1988 { 1989 // break to end of the current switch case. 1990 break; 1991 } 1992 } 1993 else 1994 { 1995 pModify = pAnch->GetCntntAnchor()->nNode.GetNode().GetCntntNode(); 1996 } 1997 } 1998 SwIterator<SwFrm,SwModify> aIter( *pModify ); 1999 SwFrm* pAnchorFrmOfMaster = 0; 2000 for( SwFrm *pFrm = aIter.First(); pFrm; pFrm = aIter.Next() ) 2001 { 2002 // append drawing object, if 2003 // (1) proposed anchor frame isn't a follow and 2004 // (2) drawing object isn't a control object to be anchored 2005 // in header/footer. 2006 const bool bAdd = ( !pFrm->IsCntntFrm() || 2007 !((SwCntntFrm*)pFrm)->IsFollow() ) && 2008 ( !::CheckControlLayer( GetMaster() ) || 2009 !pFrm->FindFooterOrHeader() ); 2010 2011 if( bAdd ) 2012 { 2013 if ( FLY_AT_FLY == pAnch->GetAnchorId() && !pFrm->IsFlyFrm() ) 2014 { 2015 pFrm = pFrm->FindFlyFrm(); 2016 ASSERT( pFrm, 2017 "<SwDrawContact::ConnectToLayout(..)> - missing fly frame -> crash." ); 2018 } 2019 2020 // OD 2004-01-20 #110582# - find correct follow for 2021 // as character anchored objects. 2022 if ((pAnch->GetAnchorId() == FLY_AS_CHAR) && 2023 pFrm->IsTxtFrm() ) 2024 { 2025 pFrm = lcl_GetFlyInCntntAnchor( 2026 static_cast<SwTxtFrm*>(pFrm), 2027 pAnch->GetCntntAnchor()->nContent.GetIndex() ); 2028 } 2029 2030 if ( !pAnchorFrmOfMaster ) 2031 { 2032 // append 'master' drawing object 2033 pAnchorFrmOfMaster = pFrm; 2034 pFrm->AppendDrawObj( maAnchoredDrawObj ); 2035 } 2036 else 2037 { 2038 // append 'virtual' drawing object 2039 SwDrawVirtObj* pDrawVirtObj = AddVirtObj(); 2040 if ( pAnch->GetAnchorId() == FLY_AS_CHAR ) 2041 { 2042 ClrContourCache( pDrawVirtObj ); 2043 } 2044 pFrm->AppendDrawObj( *(pDrawVirtObj->AnchoredObj()) ); 2045 2046 // for repaint, use new ActionChanged() 2047 // pDrawVirtObj->SendRepaintBroadcast(); 2048 pDrawVirtObj->ActionChanged(); 2049 } 2050 2051 if ( pAnch->GetAnchorId() == FLY_AS_CHAR ) 2052 { 2053 pFrm->InvalidatePrt(); 2054 } 2055 } 2056 } 2057 } 2058 break; 2059 default: 2060 ASSERT( sal_False, "Unknown Anchor." ) 2061 break; 2062 } 2063 if ( GetAnchorFrm() ) 2064 { 2065 ::setContextWritingMode( maAnchoredDrawObj.DrawObj(), GetAnchorFrm() ); 2066 // OD 2004-04-01 #i26791# - invalidate objects instead of direct positioning 2067 _InvalidateObjs(); 2068 } 2069 } 2070 2071 // OD 27.06.2003 #108784# - insert 'master' drawing object into drawing page 2072 void SwDrawContact::InsertMasterIntoDrawPage() 2073 { 2074 if ( !GetMaster()->IsInserted() ) 2075 { 2076 GetFmt()->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage(0) 2077 ->InsertObject( GetMaster(), GetMaster()->GetOrdNumDirect() ); 2078 } 2079 GetMaster()->SetUserCall( this ); 2080 } 2081 2082 /************************************************************************* 2083 |* 2084 |* SwDrawContact::FindPage(), ChkPage() 2085 |* 2086 |* Ersterstellung MA 21. Mar. 95 2087 |* Letzte Aenderung MA 19. Jul. 96 2088 |* 2089 |*************************************************************************/ 2090 2091 SwPageFrm* SwDrawContact::FindPage( const SwRect &rRect ) 2092 { 2093 // --> OD 2004-07-01 #i28701# - use method <GetPageFrm()> 2094 SwPageFrm* pPg = GetPageFrm(); 2095 if ( !pPg && GetAnchorFrm() ) 2096 pPg = GetAnchorFrm()->FindPageFrm(); 2097 if ( pPg ) 2098 pPg = (SwPageFrm*)::FindPage( rRect, pPg ); 2099 return pPg; 2100 } 2101 2102 void SwDrawContact::ChkPage() 2103 { 2104 // OD 10.10.2003 #112299# 2105 if ( mbDisconnectInProgress ) 2106 { 2107 ASSERT( false, 2108 "<SwDrawContact::ChkPage()> called during disconnection." ); 2109 return; 2110 } 2111 2112 // --> OD 2004-07-01 #i28701# 2113 SwPageFrm* pPg = ( maAnchoredDrawObj.GetAnchorFrm() && 2114 maAnchoredDrawObj.GetAnchorFrm()->IsPageFrm() ) 2115 ? GetPageFrm() 2116 : FindPage( GetMaster()->GetCurrentBoundRect() ); 2117 if ( GetPageFrm() != pPg ) 2118 { 2119 // OD 27.06.2003 #108784# - if drawing object is anchor in header/footer 2120 // a change of the page is a dramatic change. Thus, completely re-connect 2121 // to the layout 2122 if ( maAnchoredDrawObj.GetAnchorFrm() && 2123 maAnchoredDrawObj.GetAnchorFrm()->FindFooterOrHeader() ) 2124 { 2125 ConnectToLayout(); 2126 } 2127 else 2128 { 2129 // --> OD 2004-07-01 #i28701# - use methods <GetPageFrm()> and <SetPageFrm> 2130 if ( GetPageFrm() ) 2131 GetPageFrm()->RemoveDrawObjFromPage( maAnchoredDrawObj ); 2132 pPg->AppendDrawObjToPage( maAnchoredDrawObj ); 2133 SetPageFrm( pPg ); 2134 } 2135 } 2136 } 2137 2138 /************************************************************************* 2139 |* 2140 |* SwDrawContact::ChangeMasterObject() 2141 |* 2142 |* Ersterstellung MA 07. Aug. 95 2143 |* Letzte Aenderung MA 20. Apr. 99 2144 |* 2145 |*************************************************************************/ 2146 // OD 10.07.2003 #110742# - Important note: 2147 // method is called by method <SwDPage::ReplaceObject(..)>, which called its 2148 // corresponding superclass method <FmFormPage::ReplaceObject(..)>. 2149 // Note: 'master' drawing object *has* to be connected to layout triggered 2150 // by the caller of this, if method is called. 2151 void SwDrawContact::ChangeMasterObject( SdrObject *pNewMaster ) 2152 { 2153 DisconnectFromLayout( false ); 2154 // OD 10.07.2003 #110742# - consider 'virtual' drawing objects 2155 RemoveAllVirtObjs(); 2156 2157 GetMaster()->SetUserCall( 0 ); 2158 SetMaster( pNewMaster ); 2159 GetMaster()->SetUserCall( this ); 2160 2161 _InvalidateObjs(); 2162 } 2163 2164 /** get data collection of anchored objects, handled by with contact 2165 2166 OD 2004-08-23 #110810# 2167 2168 @author 2169 */ 2170 void SwDrawContact::GetAnchoredObjs( std::list<SwAnchoredObject*>& _roAnchoredObjs ) const 2171 { 2172 _roAnchoredObjs.push_back( const_cast<SwAnchoredDrawObject*>(&maAnchoredDrawObj) ); 2173 2174 for ( std::list<SwDrawVirtObj*>::const_iterator aDrawVirtObjsIter = maDrawVirtObjs.begin(); 2175 aDrawVirtObjsIter != maDrawVirtObjs.end(); 2176 ++aDrawVirtObjsIter ) 2177 { 2178 _roAnchoredObjs.push_back( (*aDrawVirtObjsIter)->AnchoredObj() ); 2179 } 2180 } 2181 2182 ////////////////////////////////////////////////////////////////////////////////////// 2183 // AW: own sdr::contact::ViewContact (VC) sdr::contact::ViewObjectContact (VOC) needed 2184 // since offset is defined different from SdrVirtObj's sdr::contact::ViewContactOfVirtObj. 2185 // For paint, that offset is used by setting at the OutputDevice; for primitives this is 2186 // not possible since we have no OutputDevice, but define the geometry itself. 2187 2188 namespace sdr 2189 { 2190 namespace contact 2191 { 2192 class VOCOfDrawVirtObj : public ViewObjectContactOfSdrObj 2193 { 2194 protected: 2195 // This method is responsible for creating the graphical visualisation data which is 2196 // stored/cached in the local primitive. Default gets view-independent Primitive 2197 // from the ViewContact using ViewContact::getViewIndependentPrimitive2DSequence(), takes care of 2198 // visibility, handles glue and ghosted. 2199 // This method will not handle included hierarchies and not check geometric visibility. 2200 virtual drawinglayer::primitive2d::Primitive2DSequence createPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const; 2201 2202 public: 2203 VOCOfDrawVirtObj(ObjectContact& rObjectContact, ViewContact& rViewContact) 2204 : ViewObjectContactOfSdrObj(rObjectContact, rViewContact) 2205 { 2206 } 2207 2208 virtual ~VOCOfDrawVirtObj(); 2209 }; 2210 2211 class VCOfDrawVirtObj : public ViewContactOfVirtObj 2212 { 2213 protected: 2214 // Create a Object-Specific ViewObjectContact, set ViewContact and 2215 // ObjectContact. Always needs to return something. Default is to create 2216 // a standard ViewObjectContact containing the given ObjectContact and *this 2217 virtual ViewObjectContact& CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact); 2218 2219 public: 2220 // basic constructor, used from SdrObject. 2221 VCOfDrawVirtObj(SwDrawVirtObj& rObj) 2222 : ViewContactOfVirtObj(rObj) 2223 { 2224 } 2225 virtual ~VCOfDrawVirtObj(); 2226 2227 // access to SwDrawVirtObj 2228 SwDrawVirtObj& GetSwDrawVirtObj() const 2229 { 2230 return (SwDrawVirtObj&)mrObject; 2231 } 2232 }; 2233 } // end of namespace contact 2234 } // end of namespace sdr 2235 2236 namespace sdr 2237 { 2238 namespace contact 2239 { 2240 // recursively collect primitive data from given VOC with given offset 2241 void impAddPrimitivesFromGroup(const ViewObjectContact& rVOC, const basegfx::B2DHomMatrix& rOffsetMatrix, const DisplayInfo& rDisplayInfo, drawinglayer::primitive2d::Primitive2DSequence& rxTarget) 2242 { 2243 const sal_uInt32 nSubHierarchyCount(rVOC.GetViewContact().GetObjectCount()); 2244 2245 for(sal_uInt32 a(0L); a < nSubHierarchyCount; a++) 2246 { 2247 const ViewObjectContact& rCandidate(rVOC.GetViewContact().GetViewContact(a).GetViewObjectContact(rVOC.GetObjectContact())); 2248 2249 if(rCandidate.GetViewContact().GetObjectCount()) 2250 { 2251 // is a group object itself, call resursively 2252 impAddPrimitivesFromGroup(rCandidate, rOffsetMatrix, rDisplayInfo, rxTarget); 2253 } 2254 else 2255 { 2256 // single object, add primitives; check model-view visibility 2257 if(rCandidate.isPrimitiveVisible(rDisplayInfo)) 2258 { 2259 drawinglayer::primitive2d::Primitive2DSequence aNewSequence(rCandidate.getPrimitive2DSequence(rDisplayInfo)); 2260 2261 if(aNewSequence.hasElements()) 2262 { 2263 // get ranges 2264 const drawinglayer::geometry::ViewInformation2D& rViewInformation2D(rCandidate.GetObjectContact().getViewInformation2D()); 2265 const basegfx::B2DRange aViewRange(rViewInformation2D.getViewport()); 2266 basegfx::B2DRange aObjectRange(rCandidate.getObjectRange()); 2267 2268 // correct with virtual object's offset 2269 aObjectRange.transform(rOffsetMatrix); 2270 2271 // check geometrical visibility (with offset) 2272 if(!aViewRange.overlaps(aObjectRange)) 2273 { 2274 // not visible, release 2275 aNewSequence.realloc(0); 2276 } 2277 } 2278 2279 if(aNewSequence.hasElements()) 2280 { 2281 drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rxTarget, aNewSequence); 2282 } 2283 } 2284 } 2285 } 2286 } 2287 2288 drawinglayer::primitive2d::Primitive2DSequence VOCOfDrawVirtObj::createPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const 2289 { 2290 #ifdef DBG_UTIL 2291 // #i101734# 2292 static bool bCheckOtherThanTranslate(false); 2293 static double fShearX(0.0); 2294 static double fRotation(0.0); 2295 static double fScaleX(0.0); 2296 static double fScaleY(0.0); 2297 #endif 2298 2299 const VCOfDrawVirtObj& rVC = static_cast< const VCOfDrawVirtObj& >(GetViewContact()); 2300 const SdrObject& rReferencedObject = rVC.GetSwDrawVirtObj().GetReferencedObj(); 2301 drawinglayer::primitive2d::Primitive2DSequence xRetval; 2302 2303 // create offset transformation 2304 basegfx::B2DHomMatrix aOffsetMatrix; 2305 const Point aLocalOffset(rVC.GetSwDrawVirtObj().GetOffset()); 2306 2307 if(aLocalOffset.X() || aLocalOffset.Y()) 2308 { 2309 #ifdef DBG_UTIL 2310 // #i101734# added debug code to check more complex transformations 2311 // than just a translation 2312 if(bCheckOtherThanTranslate) 2313 { 2314 aOffsetMatrix.scale(fScaleX, fScaleY); 2315 aOffsetMatrix.shearX(tan(fShearX * F_PI180)); 2316 aOffsetMatrix.rotate(fRotation * F_PI180); 2317 } 2318 #endif 2319 2320 aOffsetMatrix.set(0, 2, aLocalOffset.X()); 2321 aOffsetMatrix.set(1, 2, aLocalOffset.Y()); 2322 2323 } 2324 2325 if(rReferencedObject.ISA(SdrObjGroup)) 2326 { 2327 // group object. Since the VOC/OC/VC hierarchy does not represent the 2328 // hierarchy virtual objects when they have group objects 2329 // (ViewContactOfVirtObj::GetObjectCount() returns null for that purpose) 2330 // to avoid multiple usages of VOCs (which would not work), the primitives 2331 // for the sub-hierarchy need to be collected here 2332 2333 // Get the VOC of the referenced object (the Group) and fetch primitives from it 2334 const ViewObjectContact& rVOCOfRefObj = rReferencedObject.GetViewContact().GetViewObjectContact(GetObjectContact()); 2335 impAddPrimitivesFromGroup(rVOCOfRefObj, aOffsetMatrix, rDisplayInfo, xRetval); 2336 } 2337 else 2338 { 2339 // single object, use method from referenced object to get the Primitive2DSequence 2340 xRetval = rReferencedObject.GetViewContact().getViewIndependentPrimitive2DSequence(); 2341 } 2342 2343 if(xRetval.hasElements()) 2344 { 2345 // create transform primitive 2346 const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::TransformPrimitive2D(aOffsetMatrix, xRetval)); 2347 xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); 2348 } 2349 2350 return xRetval; 2351 } 2352 2353 VOCOfDrawVirtObj::~VOCOfDrawVirtObj() 2354 { 2355 } 2356 2357 ViewObjectContact& VCOfDrawVirtObj::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) 2358 { 2359 return *(new VOCOfDrawVirtObj(rObjectContact, *this)); 2360 } 2361 2362 VCOfDrawVirtObj::~VCOfDrawVirtObj() 2363 { 2364 } 2365 } // end of namespace contact 2366 } // end of namespace sdr 2367 2368 ////////////////////////////////////////////////////////////////////////////////////// 2369 2370 // ============================================================================= 2371 /** implementation of class <SwDrawVirtObj> 2372 2373 OD 14.05.2003 #108784# 2374 2375 @author OD 2376 */ 2377 2378 TYPEINIT1(SwDrawVirtObj,SdrVirtObj); 2379 2380 sdr::contact::ViewContact* SwDrawVirtObj::CreateObjectSpecificViewContact() 2381 { 2382 return new sdr::contact::VCOfDrawVirtObj(*this); 2383 } 2384 2385 // #108784# 2386 // implemetation of SwDrawVirtObj 2387 SwDrawVirtObj::SwDrawVirtObj( SdrObject& _rNewObj, 2388 SwDrawContact& _rDrawContact ) 2389 : SdrVirtObj( _rNewObj ), 2390 // OD 2004-03-29 #i26791# - init new member <maAnchoredDrawObj> 2391 maAnchoredDrawObj(), 2392 mrDrawContact( _rDrawContact ) 2393 { 2394 // OD 2004-03-29 #i26791# 2395 maAnchoredDrawObj.SetDrawObj( *this ); 2396 // --> OD 2004-11-17 #i35635# - set initial position out of sight 2397 NbcMove( Size( -RECT_EMPTY, -RECT_EMPTY ) ); 2398 // <-- 2399 } 2400 2401 SwDrawVirtObj::~SwDrawVirtObj() 2402 {} 2403 2404 void SwDrawVirtObj::operator=( const SdrObject& rObj ) 2405 { 2406 SdrVirtObj::operator=(rObj); 2407 // Note: Members <maAnchoredDrawObj> and <mrDrawContact> 2408 // haven't to be considered. 2409 } 2410 2411 SdrObject* SwDrawVirtObj::Clone() const 2412 { 2413 SwDrawVirtObj* pObj = new SwDrawVirtObj( rRefObj, mrDrawContact ); 2414 2415 if ( pObj ) 2416 { 2417 pObj->operator=(static_cast<const SdrObject&>(*this)); 2418 // Note: Member <maAnchoredDrawObj> hasn't to be considered. 2419 } 2420 2421 return pObj; 2422 } 2423 2424 // -------------------------------------------------------------------- 2425 // connection to writer layout: <GetAnchoredObj()>, <SetAnchorFrm(..)>, 2426 // <GetAnchorFrm()>, <SetPageFrm(..)>, <GetPageFrm()> and <RemoveFromWriterLayout()> 2427 // -------------------------------------------------------------------- 2428 const SwAnchoredObject* SwDrawVirtObj::GetAnchoredObj() const 2429 { 2430 return &maAnchoredDrawObj; 2431 } 2432 2433 SwAnchoredObject* SwDrawVirtObj::AnchoredObj() 2434 { 2435 return &maAnchoredDrawObj; 2436 } 2437 2438 const SwFrm* SwDrawVirtObj::GetAnchorFrm() const 2439 { 2440 // OD 2004-03-29 #i26791# - use new member <maAnchoredDrawObj> 2441 return maAnchoredDrawObj.GetAnchorFrm(); 2442 } 2443 2444 SwFrm* SwDrawVirtObj::AnchorFrm() 2445 { 2446 // OD 2004-03-29 #i26791# - use new member <maAnchoredDrawObj> 2447 return maAnchoredDrawObj.AnchorFrm(); 2448 } 2449 2450 void SwDrawVirtObj::RemoveFromWriterLayout() 2451 { 2452 // remove contact object from frame for 'virtual' drawing object 2453 // OD 2004-03-29 #i26791# - use new member <maAnchoredDrawObj> 2454 if ( maAnchoredDrawObj.GetAnchorFrm() ) 2455 { 2456 maAnchoredDrawObj.AnchorFrm()->RemoveDrawObj( maAnchoredDrawObj ); 2457 } 2458 } 2459 2460 // -------------------------------------------------------------------- 2461 // connection to writer layout: <AddToDrawingPage()>, <RemoveFromDrawingPage()> 2462 // -------------------------------------------------------------------- 2463 void SwDrawVirtObj::AddToDrawingPage() 2464 { 2465 // determine 'master' 2466 SdrObject* pOrgMasterSdrObj = mrDrawContact.GetMaster(); 2467 2468 // insert 'virtual' drawing object into page, set layer and user call. 2469 SdrPage* pDrawPg; 2470 // --> OD 2004-08-16 #i27030# - apply order number of referenced object 2471 if ( 0 != ( pDrawPg = pOrgMasterSdrObj->GetPage() ) ) 2472 { 2473 // --> OD 2004-08-16 #i27030# - apply order number of referenced object 2474 pDrawPg->InsertObject( this, GetReferencedObj().GetOrdNum() ); 2475 } 2476 else 2477 { 2478 pDrawPg = GetPage(); 2479 if ( pDrawPg ) 2480 { 2481 pDrawPg->SetObjectOrdNum( GetOrdNumDirect(), 2482 GetReferencedObj().GetOrdNum() ); 2483 } 2484 else 2485 { 2486 SetOrdNum( GetReferencedObj().GetOrdNum() ); 2487 } 2488 } 2489 // <-- 2490 SetUserCall( &mrDrawContact ); 2491 } 2492 2493 void SwDrawVirtObj::RemoveFromDrawingPage() 2494 { 2495 SetUserCall( 0 ); 2496 if ( GetPage() ) 2497 { 2498 GetPage()->RemoveObject( GetOrdNum() ); 2499 } 2500 } 2501 2502 // is 'virtual' drawing object connected to writer layout and to drawing layer. 2503 bool SwDrawVirtObj::IsConnected() const 2504 { 2505 bool bRetVal = GetAnchorFrm() && 2506 ( GetPage() && GetUserCall() ); 2507 2508 return bRetVal; 2509 } 2510 2511 void SwDrawVirtObj::NbcSetAnchorPos(const Point& rPnt) 2512 { 2513 SdrObject::NbcSetAnchorPos( rPnt ); 2514 } 2515 2516 ////////////////////////////////////////////////////////////////////////////// 2517 // #i97197# 2518 // the methods relevant for positioning 2519 2520 const Rectangle& SwDrawVirtObj::GetCurrentBoundRect() const 2521 { 2522 if(aOutRect.IsEmpty()) 2523 { 2524 const_cast<SwDrawVirtObj*>(this)->RecalcBoundRect(); 2525 } 2526 2527 return aOutRect; 2528 } 2529 2530 const Rectangle& SwDrawVirtObj::GetLastBoundRect() const 2531 { 2532 return aOutRect; 2533 } 2534 2535 const Point SwDrawVirtObj::GetOffset() const 2536 { 2537 // do NOT use IsEmpty() here, there is already a useful offset 2538 // in the position 2539 if(aOutRect == Rectangle()) 2540 { 2541 return Point(); 2542 } 2543 else 2544 { 2545 return aOutRect.TopLeft() - GetReferencedObj().GetCurrentBoundRect().TopLeft(); 2546 } 2547 } 2548 2549 void SwDrawVirtObj::SetBoundRectDirty() 2550 { 2551 // do nothing to not lose model information in aOutRect 2552 } 2553 2554 void SwDrawVirtObj::RecalcBoundRect() 2555 { 2556 // OD 2004-04-05 #i26791# - switch order of calling <GetOffset()> and 2557 // <ReferencedObj().GetCurrentBoundRect()>, because <GetOffset()> calculates 2558 // its value by the 'BoundRect' of the referenced object. 2559 //aOutRect = rRefObj.GetCurrentBoundRect(); 2560 //aOutRect += GetOffset(); 2561 2562 const Point aOffset(GetOffset()); 2563 aOutRect = ReferencedObj().GetCurrentBoundRect() + aOffset; 2564 } 2565 2566 basegfx::B2DPolyPolygon SwDrawVirtObj::TakeXorPoly() const 2567 { 2568 basegfx::B2DPolyPolygon aRetval(rRefObj.TakeXorPoly()); 2569 aRetval.transform(basegfx::tools::createTranslateB2DHomMatrix(GetOffset().X(), GetOffset().Y())); 2570 2571 return aRetval; 2572 } 2573 2574 basegfx::B2DPolyPolygon SwDrawVirtObj::TakeContour() const 2575 { 2576 basegfx::B2DPolyPolygon aRetval(rRefObj.TakeContour()); 2577 aRetval.transform(basegfx::tools::createTranslateB2DHomMatrix(GetOffset().X(), GetOffset().Y())); 2578 2579 return aRetval; 2580 } 2581 2582 SdrHdl* SwDrawVirtObj::GetHdl(sal_uInt32 nHdlNum) const 2583 { 2584 SdrHdl* pHdl = rRefObj.GetHdl(nHdlNum); 2585 2586 if(pHdl) 2587 { 2588 Point aP(pHdl->GetPos() + GetOffset()); 2589 pHdl->SetPos(aP); 2590 } 2591 else 2592 { 2593 OSL_ENSURE(false, "Got no SdrHdl(!)"); 2594 } 2595 2596 return pHdl; 2597 } 2598 2599 SdrHdl* SwDrawVirtObj::GetPlusHdl(const SdrHdl& rHdl, sal_uInt16 nPlNum) const 2600 { 2601 SdrHdl* pHdl = rRefObj.GetPlusHdl(rHdl, nPlNum); 2602 2603 if(pHdl) 2604 { 2605 pHdl->SetPos(pHdl->GetPos() + GetOffset()); 2606 } 2607 else 2608 { 2609 OSL_ENSURE(false, "Got no SdrHdl(!)"); 2610 } 2611 2612 return pHdl; 2613 } 2614 2615 void SwDrawVirtObj::NbcMove(const Size& rSiz) 2616 { 2617 SdrObject::NbcMove( rSiz ); 2618 } 2619 2620 void SwDrawVirtObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact) 2621 { 2622 rRefObj.NbcResize(rRef - GetOffset(), xFact, yFact); 2623 SetRectsDirty(); 2624 } 2625 2626 void SwDrawVirtObj::NbcRotate(const Point& rRef, long nWink, double sn, double cs) 2627 { 2628 rRefObj.NbcRotate(rRef - GetOffset(), nWink, sn, cs); 2629 SetRectsDirty(); 2630 } 2631 2632 void SwDrawVirtObj::NbcMirror(const Point& rRef1, const Point& rRef2) 2633 { 2634 rRefObj.NbcMirror(rRef1 - GetOffset(), rRef2 - GetOffset()); 2635 SetRectsDirty(); 2636 } 2637 2638 void SwDrawVirtObj::NbcShear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear) 2639 { 2640 rRefObj.NbcShear(rRef - GetOffset(), nWink, tn, bVShear); 2641 SetRectsDirty(); 2642 } 2643 2644 void SwDrawVirtObj::Move(const Size& rSiz) 2645 { 2646 SdrObject::Move( rSiz ); 2647 // Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect(); 2648 // rRefObj.Move( rSiz ); 2649 // SetRectsDirty(); 2650 // SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0); 2651 } 2652 2653 void SwDrawVirtObj::Resize(const Point& rRef, const Fraction& xFact, const Fraction& yFact) 2654 { 2655 if(xFact.GetNumerator() != xFact.GetDenominator() || yFact.GetNumerator() != yFact.GetDenominator()) 2656 { 2657 Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect(); 2658 rRefObj.Resize(rRef - GetOffset(), xFact, yFact); 2659 SetRectsDirty(); 2660 SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0); 2661 } 2662 } 2663 2664 void SwDrawVirtObj::Rotate(const Point& rRef, long nWink, double sn, double cs) 2665 { 2666 if(nWink) 2667 { 2668 Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect(); 2669 rRefObj.Rotate(rRef - GetOffset(), nWink, sn, cs); 2670 SetRectsDirty(); 2671 SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0); 2672 } 2673 } 2674 2675 void SwDrawVirtObj::Mirror(const Point& rRef1, const Point& rRef2) 2676 { 2677 Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect(); 2678 rRefObj.Mirror(rRef1 - GetOffset(), rRef2 - GetOffset()); 2679 SetRectsDirty(); 2680 SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0); 2681 } 2682 2683 void SwDrawVirtObj::Shear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear) 2684 { 2685 if(nWink) 2686 { 2687 Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect(); 2688 rRefObj.Shear(rRef - GetOffset(), nWink, tn, bVShear); 2689 SetRectsDirty(); 2690 SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0); 2691 } 2692 } 2693 2694 void SwDrawVirtObj::RecalcSnapRect() 2695 { 2696 aSnapRect = rRefObj.GetSnapRect(); 2697 aSnapRect += GetOffset(); 2698 } 2699 2700 const Rectangle& SwDrawVirtObj::GetSnapRect() const 2701 { 2702 ((SwDrawVirtObj*)this)->aSnapRect = rRefObj.GetSnapRect(); 2703 ((SwDrawVirtObj*)this)->aSnapRect += GetOffset(); 2704 2705 return aSnapRect; 2706 } 2707 2708 void SwDrawVirtObj::SetSnapRect(const Rectangle& rRect) 2709 { 2710 Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect(); 2711 Rectangle aR(rRect); 2712 aR -= GetOffset(); 2713 rRefObj.SetSnapRect(aR); 2714 SetRectsDirty(); 2715 SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0); 2716 } 2717 2718 void SwDrawVirtObj::NbcSetSnapRect(const Rectangle& rRect) 2719 { 2720 Rectangle aR(rRect); 2721 aR -= GetOffset(); 2722 SetRectsDirty(); 2723 rRefObj.NbcSetSnapRect(aR); 2724 } 2725 2726 const Rectangle& SwDrawVirtObj::GetLogicRect() const 2727 { 2728 ((SwDrawVirtObj*)this)->aSnapRect = rRefObj.GetLogicRect(); 2729 ((SwDrawVirtObj*)this)->aSnapRect += GetOffset(); 2730 2731 return aSnapRect; 2732 } 2733 2734 void SwDrawVirtObj::SetLogicRect(const Rectangle& rRect) 2735 { 2736 Rectangle aBoundRect0; if(pUserCall) aBoundRect0 = GetLastBoundRect(); 2737 Rectangle aR(rRect); 2738 aR -= GetOffset(); 2739 rRefObj.SetLogicRect(aR); 2740 SetRectsDirty(); 2741 SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0); 2742 } 2743 2744 void SwDrawVirtObj::NbcSetLogicRect(const Rectangle& rRect) 2745 { 2746 Rectangle aR(rRect); 2747 aR -= GetOffset(); 2748 rRefObj.NbcSetLogicRect(aR); 2749 SetRectsDirty(); 2750 } 2751 2752 Point SwDrawVirtObj::GetSnapPoint(sal_uInt32 i) const 2753 { 2754 Point aP(rRefObj.GetSnapPoint(i)); 2755 aP += GetOffset(); 2756 2757 return aP; 2758 } 2759 2760 Point SwDrawVirtObj::GetPoint(sal_uInt32 i) const 2761 { 2762 return Point(rRefObj.GetPoint(i) + GetOffset()); 2763 } 2764 2765 void SwDrawVirtObj::NbcSetPoint(const Point& rPnt, sal_uInt32 i) 2766 { 2767 Point aP(rPnt); 2768 aP -= GetOffset(); 2769 rRefObj.SetPoint(aP, i); 2770 SetRectsDirty(); 2771 } 2772 2773 // #108784# 2774 FASTBOOL SwDrawVirtObj::HasTextEdit() const 2775 { 2776 return rRefObj.HasTextEdit(); 2777 } 2778 2779 // OD 18.06.2003 #108784# - overloaded 'layer' methods for 'virtual' drawing 2780 // object to assure, that layer of 'virtual' object is the layer of the referenced 2781 // object. 2782 SdrLayerID SwDrawVirtObj::GetLayer() const 2783 { 2784 return GetReferencedObj().GetLayer(); 2785 } 2786 2787 void SwDrawVirtObj::NbcSetLayer(SdrLayerID nLayer) 2788 { 2789 ReferencedObj().NbcSetLayer( nLayer ); 2790 SdrVirtObj::NbcSetLayer( ReferencedObj().GetLayer() ); 2791 } 2792 2793 void SwDrawVirtObj::SetLayer(SdrLayerID nLayer) 2794 { 2795 ReferencedObj().SetLayer( nLayer ); 2796 SdrVirtObj::NbcSetLayer( ReferencedObj().GetLayer() ); 2797 } 2798 2799 bool SwDrawVirtObj::supportsFullDrag() const 2800 { 2801 // call parent 2802 return SdrVirtObj::supportsFullDrag(); 2803 } 2804 2805 SdrObject* SwDrawVirtObj::getFullDragClone() const 2806 { 2807 // call parent 2808 return SdrVirtObj::getFullDragClone(); 2809 } 2810 2811 // eof 2812 2813