1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sw.hxx" 30 #include "hintids.hxx" 31 #include <svx/svdtrans.hxx> 32 #include <editeng/protitem.hxx> 33 #include <editeng/opaqitem.hxx> 34 #include <svx/svdpage.hxx> 35 36 37 #include <fmtclds.hxx> 38 #include <fmtornt.hxx> 39 #include <fmtfsize.hxx> 40 #include <fmturl.hxx> 41 #include "viewsh.hxx" 42 #include "viewimp.hxx" 43 #include "cntfrm.hxx" 44 #include "frmatr.hxx" 45 #include "doc.hxx" 46 #include <IDocumentUndoRedo.hxx> 47 #include "dview.hxx" 48 #include "dflyobj.hxx" 49 #include "flyfrm.hxx" 50 #include "frmfmt.hxx" 51 #include "viewopt.hxx" 52 #include "frmtool.hxx" 53 #include "flyfrms.hxx" 54 #include "ndnotxt.hxx" 55 #include "grfatr.hxx" 56 #include "pagefrm.hxx" 57 #include "rootfrm.hxx" 58 59 60 using namespace ::com::sun::star; 61 62 63 // --> OD 2004-11-22 #117958# 64 #include <svx/sdr/properties/defaultproperties.hxx> 65 // <-- 66 #include <basegfx/range/b2drange.hxx> 67 #include <basegfx/polygon/b2dpolygontools.hxx> 68 #include <basegfx/polygon/b2dpolygon.hxx> 69 70 // AW: For VCOfDrawVirtObj and stuff 71 #include <svx/sdr/contact/viewcontactofvirtobj.hxx> 72 #include <drawinglayer/primitive2d/baseprimitive2d.hxx> 73 #include <sw_primitivetypes2d.hxx> 74 #include <drawinglayer/primitive2d/sdrdecompositiontools2d.hxx> 75 76 using namespace ::com::sun::star; 77 78 static sal_Bool bInResize = sal_False; 79 80 TYPEINIT1( SwFlyDrawObj, SdrObject ) 81 TYPEINIT1( SwVirtFlyDrawObj, SdrVirtObj ) 82 83 /************************************************************************* 84 |* 85 |* SwFlyDrawObj::Ctor 86 |* 87 |* Ersterstellung MA 18. Apr. 95 88 |* Letzte Aenderung MA 28. May. 96 89 |* 90 *************************************************************************/ 91 92 //////////////////////////////////////////////////////////////////////////////////////////////////// 93 94 namespace sdr 95 { 96 namespace contact 97 { 98 // #i95264# currently needed since createViewIndependentPrimitive2DSequence() 99 // is called when RecalcBoundRect() is used. There should currently no VOCs being 100 // constructed since it gets not visualized (instead the corresponding SwVirtFlyDrawObj's 101 // referencing this one are visualized). 102 class VCOfSwFlyDrawObj : public ViewContactOfSdrObj 103 { 104 protected: 105 // This method is responsible for creating the graphical visualisation data 106 // ONLY based on model data 107 virtual drawinglayer::primitive2d::Primitive2DSequence createViewIndependentPrimitive2DSequence() const; 108 109 public: 110 // basic constructor, used from SdrObject. 111 VCOfSwFlyDrawObj(SwFlyDrawObj& rObj) 112 : ViewContactOfSdrObj(rObj) 113 { 114 } 115 virtual ~VCOfSwFlyDrawObj(); 116 }; 117 118 drawinglayer::primitive2d::Primitive2DSequence VCOfSwFlyDrawObj::createViewIndependentPrimitive2DSequence() const 119 { 120 // currently gets not visualized, return empty sequence 121 return drawinglayer::primitive2d::Primitive2DSequence(); 122 } 123 124 VCOfSwFlyDrawObj::~VCOfSwFlyDrawObj() 125 { 126 } 127 } // end of namespace contact 128 } // end of namespace sdr 129 130 //////////////////////////////////////////////////////////////////////////////////////////////////// 131 132 sdr::properties::BaseProperties* SwFlyDrawObj::CreateObjectSpecificProperties() 133 { 134 // --> OD 2004-11-22 #117958# - create default properties 135 return new sdr::properties::DefaultProperties(*this); 136 // <-- 137 } 138 139 sdr::contact::ViewContact* SwFlyDrawObj::CreateObjectSpecificViewContact() 140 { 141 // #i95264# needs an own VC since createViewIndependentPrimitive2DSequence() 142 // is called when RecalcBoundRect() is used 143 return new sdr::contact::VCOfSwFlyDrawObj(*this); 144 } 145 146 SwFlyDrawObj::SwFlyDrawObj() 147 { 148 } 149 150 SwFlyDrawObj::~SwFlyDrawObj() 151 { 152 } 153 154 /************************************************************************* 155 |* 156 |* SwFlyDrawObj::Factory-Methoden 157 |* 158 |* Ersterstellung MA 23. Feb. 95 159 |* Letzte Aenderung MA 23. Feb. 95 160 |* 161 *************************************************************************/ 162 163 sal_uInt32 __EXPORT SwFlyDrawObj::GetObjInventor() const 164 { 165 return SWGInventor; 166 } 167 168 169 sal_uInt16 __EXPORT SwFlyDrawObj::GetObjIdentifier() const 170 { 171 return SwFlyDrawObjIdentifier; 172 } 173 174 175 sal_uInt16 __EXPORT SwFlyDrawObj::GetObjVersion() const 176 { 177 return SwDrawFirst; 178 } 179 180 /************************************************************************* 181 |* 182 |* SwVirtFlyDrawObj::CToren, Dtor 183 |* 184 |* Ersterstellung MA 08. Dec. 94 185 |* Letzte Aenderung MA 28. May. 96 186 |* 187 *************************************************************************/ 188 189 ////////////////////////////////////////////////////////////////////////////////////// 190 // AW: Need own primitive to get the FlyFrame paint working 191 192 namespace drawinglayer 193 { 194 namespace primitive2d 195 { 196 class SwVirtFlyDrawObjPrimitive : public BufferedDecompositionPrimitive2D 197 { 198 private: 199 const SwVirtFlyDrawObj& mrSwVirtFlyDrawObj; 200 const basegfx::B2DRange maOuterRange; 201 202 protected: 203 // method which is to be used to implement the local decomposition of a 2D primitive 204 virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; 205 206 public: 207 SwVirtFlyDrawObjPrimitive( 208 const SwVirtFlyDrawObj& rSwVirtFlyDrawObj, 209 const basegfx::B2DRange &rOuterRange) 210 : BufferedDecompositionPrimitive2D(), 211 mrSwVirtFlyDrawObj(rSwVirtFlyDrawObj), 212 maOuterRange(rOuterRange) 213 { 214 } 215 216 // compare operator 217 virtual bool operator==(const BasePrimitive2D& rPrimitive) const; 218 219 // get range 220 virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; 221 222 // overloaded to allow callbacks to wrap_DoPaintObject 223 virtual Primitive2DSequence get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; 224 225 // data read access 226 const SwVirtFlyDrawObj& getSwVirtFlyDrawObj() const { return mrSwVirtFlyDrawObj; } 227 const basegfx::B2DRange& getOuterRange() const { return maOuterRange; } 228 229 // provide unique ID 230 DeclPrimitrive2DIDBlock() 231 }; 232 } // end of namespace primitive2d 233 } // end of namespace drawinglayer 234 235 namespace drawinglayer 236 { 237 namespace primitive2d 238 { 239 Primitive2DSequence SwVirtFlyDrawObjPrimitive::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const 240 { 241 Primitive2DSequence aRetval; 242 243 if(!getOuterRange().isEmpty()) 244 { 245 // currently this SW object has no primitive representation. As long as this is the case, 246 // create invisible geometry to allow corfect HitTest and BoundRect calculations for the 247 // object. Use a filled primitive to get 'inside' as default object hit. The special cases from 248 // the old SwVirtFlyDrawObj::CheckHit implementation are handled now in SwDrawView::PickObj; 249 // this removed the 'hack' to get a view from inside model data or to react on null-tolerance 250 // as it was done in the old implementation 251 const Primitive2DReference aHitTestReference( 252 createHiddenGeometryPrimitives2D( 253 true, 254 getOuterRange())); 255 256 aRetval = Primitive2DSequence(&aHitTestReference, 1); 257 } 258 259 return aRetval; 260 } 261 262 bool SwVirtFlyDrawObjPrimitive::operator==(const BasePrimitive2D& rPrimitive) const 263 { 264 if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) 265 { 266 const SwVirtFlyDrawObjPrimitive& rCompare = (SwVirtFlyDrawObjPrimitive&)rPrimitive; 267 268 return (&getSwVirtFlyDrawObj() == &rCompare.getSwVirtFlyDrawObj() 269 && getOuterRange() == rCompare.getOuterRange()); 270 } 271 272 return false; 273 } 274 275 basegfx::B2DRange SwVirtFlyDrawObjPrimitive::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const 276 { 277 return getOuterRange(); 278 } 279 280 Primitive2DSequence SwVirtFlyDrawObjPrimitive::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const 281 { 282 // This is the callback to keep the FlyFrame painting in SW alive as long as it 283 // is not changed to primitives. This is the method which will be called by the processors 284 // when they do not know this primitive (and they do not). Inside wrap_DoPaintObject 285 // there needs to be a test that paint is only done during SW repaints (see there). 286 // Using this mechanism guarantees the correct Z-Order of the VirtualObject-based FlyFrames. 287 getSwVirtFlyDrawObj().wrap_DoPaintObject(); 288 289 // call parent 290 return BufferedDecompositionPrimitive2D::get2DDecomposition(rViewInformation); 291 } 292 293 // provide unique ID 294 ImplPrimitrive2DIDBlock(SwVirtFlyDrawObjPrimitive, PRIMITIVE2D_ID_SWVIRTFLYDRAWOBJPRIMITIVE2D) 295 296 } // end of namespace primitive2d 297 } // end of namespace drawinglayer 298 299 ////////////////////////////////////////////////////////////////////////////////////// 300 // AW: own sdr::contact::ViewContact (VC) sdr::contact::ViewObjectContact (VOC) needed 301 // since offset is defined different from SdrVirtObj's sdr::contact::ViewContactOfVirtObj. 302 // For paint, that offset is used by setting at the OutputDevice; for primitives this is 303 // not possible since we have no OutputDevice, but define the geometry itself. 304 305 namespace sdr 306 { 307 namespace contact 308 { 309 class VCOfSwVirtFlyDrawObj : public ViewContactOfVirtObj 310 { 311 protected: 312 // This method is responsible for creating the graphical visualisation data 313 // ONLY based on model data 314 virtual drawinglayer::primitive2d::Primitive2DSequence createViewIndependentPrimitive2DSequence() const; 315 316 public: 317 // basic constructor, used from SdrObject. 318 VCOfSwVirtFlyDrawObj(SwVirtFlyDrawObj& rObj) 319 : ViewContactOfVirtObj(rObj) 320 { 321 } 322 virtual ~VCOfSwVirtFlyDrawObj(); 323 324 // access to SwVirtFlyDrawObj 325 SwVirtFlyDrawObj& GetSwVirtFlyDrawObj() const 326 { 327 return (SwVirtFlyDrawObj&)mrObject; 328 } 329 }; 330 } // end of namespace contact 331 } // end of namespace sdr 332 333 namespace sdr 334 { 335 namespace contact 336 { 337 drawinglayer::primitive2d::Primitive2DSequence VCOfSwVirtFlyDrawObj::createViewIndependentPrimitive2DSequence() const 338 { 339 drawinglayer::primitive2d::Primitive2DSequence xRetval; 340 const SdrObject& rReferencedObject = GetSwVirtFlyDrawObj().GetReferencedObj(); 341 342 if(rReferencedObject.ISA(SwFlyDrawObj)) 343 { 344 // create an own specialized primitive which is used as repaint callpoint and HitTest 345 // for HitTest processor (see primitive implementation above) 346 const basegfx::B2DRange aOuterRange(GetSwVirtFlyDrawObj().getOuterBound()); 347 348 if(!aOuterRange.isEmpty()) 349 { 350 const drawinglayer::primitive2d::Primitive2DReference xPrimitive( 351 new drawinglayer::primitive2d::SwVirtFlyDrawObjPrimitive( 352 GetSwVirtFlyDrawObj(), 353 aOuterRange)); 354 355 xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xPrimitive, 1); 356 } 357 } 358 359 return xRetval; 360 } 361 362 VCOfSwVirtFlyDrawObj::~VCOfSwVirtFlyDrawObj() 363 { 364 } 365 } // end of namespace contact 366 } // end of namespace sdr 367 368 ////////////////////////////////////////////////////////////////////////////////////// 369 370 basegfx::B2DRange SwVirtFlyDrawObj::getOuterBound() const 371 { 372 basegfx::B2DRange aOuterRange; 373 const SdrObject& rReferencedObject = GetReferencedObj(); 374 375 if(rReferencedObject.ISA(SwFlyDrawObj)) 376 { 377 const SwFlyFrm* pFlyFrame = GetFlyFrm(); 378 379 if(pFlyFrame) 380 { 381 const Rectangle aOuterRectangle(pFlyFrame->Frm().Pos(), pFlyFrame->Frm().SSize()); 382 383 if(!aOuterRectangle.IsEmpty() 384 && RECT_EMPTY != aOuterRectangle.Right() 385 && RECT_EMPTY != aOuterRectangle.Bottom()) 386 { 387 aOuterRange.expand(basegfx::B2DTuple(aOuterRectangle.Left(), aOuterRectangle.Top())); 388 aOuterRange.expand(basegfx::B2DTuple(aOuterRectangle.Right(), aOuterRectangle.Bottom())); 389 } 390 } 391 } 392 393 return aOuterRange; 394 } 395 396 basegfx::B2DRange SwVirtFlyDrawObj::getInnerBound() const 397 { 398 basegfx::B2DRange aInnerRange; 399 const SdrObject& rReferencedObject = GetReferencedObj(); 400 401 if(rReferencedObject.ISA(SwFlyDrawObj)) 402 { 403 const SwFlyFrm* pFlyFrame = GetFlyFrm(); 404 405 if(pFlyFrame) 406 { 407 const Rectangle aInnerRectangle(pFlyFrame->Frm().Pos() + pFlyFrame->Prt().Pos(), pFlyFrame->Prt().SSize()); 408 409 if(!aInnerRectangle.IsEmpty() 410 && RECT_EMPTY != aInnerRectangle.Right() 411 && RECT_EMPTY != aInnerRectangle.Bottom()) 412 { 413 aInnerRange.expand(basegfx::B2DTuple(aInnerRectangle.Left(), aInnerRectangle.Top())); 414 aInnerRange.expand(basegfx::B2DTuple(aInnerRectangle.Right(), aInnerRectangle.Bottom())); 415 } 416 } 417 } 418 419 return aInnerRange; 420 } 421 422 sdr::contact::ViewContact* SwVirtFlyDrawObj::CreateObjectSpecificViewContact() 423 { 424 // need an own ViewContact (VC) to allow creation of a specialized primitive 425 // for being able to visualize the FlyFrames in primitive renderers 426 return new sdr::contact::VCOfSwVirtFlyDrawObj(*this); 427 } 428 429 SwVirtFlyDrawObj::SwVirtFlyDrawObj(SdrObject& rNew, SwFlyFrm* pFly) : 430 SdrVirtObj( rNew ), 431 pFlyFrm( pFly ) 432 { 433 //#110094#-1 434 // bNotPersistent = bNeedColorRestore = bWriterFlyFrame = sal_True; 435 const SvxProtectItem &rP = pFlyFrm->GetFmt()->GetProtect(); 436 bMovProt = rP.IsPosProtected(); 437 bSizProt = rP.IsSizeProtected(); 438 } 439 440 441 __EXPORT SwVirtFlyDrawObj::~SwVirtFlyDrawObj() 442 { 443 if ( GetPage() ) //Der SdrPage die Verantwortung entziehen. 444 GetPage()->RemoveObject( GetOrdNum() ); 445 } 446 447 /************************************************************************* 448 |* 449 |* SwVirtFlyDrawObj::GetFmt() 450 |* 451 |* Ersterstellung MA 08. Dec. 94 452 |* Letzte Aenderung MA 08. Dec. 94 453 |* 454 *************************************************************************/ 455 456 const SwFrmFmt *SwVirtFlyDrawObj::GetFmt() const 457 { 458 return GetFlyFrm()->GetFmt(); 459 } 460 461 462 SwFrmFmt *SwVirtFlyDrawObj::GetFmt() 463 { 464 return GetFlyFrm()->GetFmt(); 465 } 466 467 /************************************************************************* 468 |* 469 |* SwVirtFlyDrawObj::Paint() 470 |* 471 |* Ersterstellung MA 20. Dec. 94 472 |* Letzte Aenderung MA 18. Dec. 95 473 |* 474 *************************************************************************/ 475 476 // --> OD #i102707# 477 namespace 478 { 479 class RestoreMapMode 480 { 481 public: 482 explicit RestoreMapMode( ViewShell* pViewShell ) 483 : mbMapModeRestored( false ) 484 , mpOutDev( pViewShell->GetOut() ) 485 { 486 if ( pViewShell->getPrePostMapMode() != mpOutDev->GetMapMode() ) 487 { 488 mpOutDev->Push(PUSH_MAPMODE); 489 490 GDIMetaFile* pMetaFile = mpOutDev->GetConnectMetaFile(); 491 if ( pMetaFile && 492 pMetaFile->IsRecord() && !pMetaFile->IsPause() ) 493 { 494 ASSERT( false, 495 "MapMode restoration during meta file creation is somehow suspect - using <SetRelativeMapMode(..)>, but not sure, if correct." ) 496 mpOutDev->SetRelativeMapMode( pViewShell->getPrePostMapMode() ); 497 } 498 else 499 { 500 mpOutDev->SetMapMode( pViewShell->getPrePostMapMode() ); 501 } 502 503 mbMapModeRestored = true; 504 } 505 }; 506 507 ~RestoreMapMode() 508 { 509 if ( mbMapModeRestored ) 510 { 511 mpOutDev->Pop(); 512 } 513 }; 514 515 private: 516 bool mbMapModeRestored; 517 OutputDevice* mpOutDev; 518 }; 519 } 520 // <-- 521 522 void SwVirtFlyDrawObj::wrap_DoPaintObject() const 523 { 524 ViewShell* pShell = pFlyFrm->getRootFrm()->GetCurrShell(); 525 526 // Only paint when we have a current shell and a DrawingLayer paint is in progress. 527 // This avcoids evtl. problems with renderers which do processing stuff, 528 // but no paints. IsPaintInProgress() depends on SW repaint, so, as long 529 // as SW paints self and calls DrawLayer() for Heaven and Hell, this will 530 // be correct 531 if ( pShell && pShell->IsDrawingLayerPaintInProgress() ) 532 { 533 sal_Bool bDrawObject(sal_True); 534 535 if ( !SwFlyFrm::IsPaint( (SdrObject*)this, pShell ) ) 536 { 537 bDrawObject = sal_False; 538 } 539 540 if ( bDrawObject ) 541 { 542 if ( !pFlyFrm->IsFlyInCntFrm() ) 543 { 544 // it is also necessary to restore the VCL MapMode from ViewInformation since e.g. 545 // the VCL PixelRenderer resets it at the used OutputDevice. Unfortunately, this 546 // excludes shears and rotates which are not expressable in MapMode. 547 // OD #i102707# 548 // new helper class to restore MapMode - restoration, only if 549 // needed and consideration of paint for meta file creation . 550 RestoreMapMode aRestoreMapModeIfNeeded( pShell ); 551 552 // paint the FlyFrame (use standard VCL-Paint) 553 pFlyFrm->Paint( GetFlyFrm()->Frm() ); 554 } 555 } 556 } 557 } 558 559 /************************************************************************* 560 |* 561 |* SwVirtFlyDrawObj::TakeObjInfo() 562 |* 563 |* Ersterstellung MA 03. May. 95 564 |* Letzte Aenderung MA 03. May. 95 565 |* 566 *************************************************************************/ 567 568 void __EXPORT SwVirtFlyDrawObj::TakeObjInfo( SdrObjTransformInfoRec& rInfo ) const 569 { 570 rInfo.bSelectAllowed = rInfo.bMoveAllowed = 571 rInfo.bResizeFreeAllowed = rInfo.bResizePropAllowed = sal_True; 572 573 rInfo.bRotateFreeAllowed = rInfo.bRotate90Allowed = 574 rInfo.bMirrorFreeAllowed = rInfo.bMirror45Allowed = 575 rInfo.bMirror90Allowed = rInfo.bShearAllowed = 576 rInfo.bCanConvToPath = rInfo.bCanConvToPoly = 577 rInfo.bCanConvToPathLineToArea = rInfo.bCanConvToPolyLineToArea = sal_False; 578 } 579 580 581 /************************************************************************* 582 |* 583 |* SwVirtFlyDrawObj::Groessenermittlung 584 |* 585 |* Ersterstellung MA 12. Jan. 95 586 |* Letzte Aenderung MA 10. Nov. 95 587 |* 588 *************************************************************************/ 589 590 void SwVirtFlyDrawObj::SetRect() const 591 { 592 if ( GetFlyFrm()->Frm().HasArea() ) 593 ((SwVirtFlyDrawObj*)this)->aOutRect = GetFlyFrm()->Frm().SVRect(); 594 else 595 ((SwVirtFlyDrawObj*)this)->aOutRect = Rectangle(); 596 } 597 598 599 const Rectangle& __EXPORT SwVirtFlyDrawObj::GetCurrentBoundRect() const 600 { 601 SetRect(); 602 return aOutRect; 603 } 604 605 const Rectangle& __EXPORT SwVirtFlyDrawObj::GetLastBoundRect() const 606 { 607 return GetCurrentBoundRect(); 608 } 609 610 611 void __EXPORT SwVirtFlyDrawObj::RecalcBoundRect() 612 { 613 SetRect(); 614 } 615 616 617 void __EXPORT SwVirtFlyDrawObj::RecalcSnapRect() 618 { 619 SetRect(); 620 } 621 622 623 const Rectangle& __EXPORT SwVirtFlyDrawObj::GetSnapRect() const 624 { 625 SetRect(); 626 return aOutRect; 627 } 628 629 630 void __EXPORT SwVirtFlyDrawObj::SetSnapRect(const Rectangle& ) 631 { 632 Rectangle aTmp( GetLastBoundRect() ); 633 SetRect(); 634 SetChanged(); 635 BroadcastObjectChange(); 636 if (pUserCall!=NULL) 637 pUserCall->Changed(*this, SDRUSERCALL_RESIZE, aTmp); 638 } 639 640 641 void __EXPORT SwVirtFlyDrawObj::NbcSetSnapRect(const Rectangle& ) 642 { 643 SetRect(); 644 } 645 646 647 const Rectangle& __EXPORT SwVirtFlyDrawObj::GetLogicRect() const 648 { 649 SetRect(); 650 return aOutRect; 651 } 652 653 654 void __EXPORT SwVirtFlyDrawObj::SetLogicRect(const Rectangle& ) 655 { 656 Rectangle aTmp( GetLastBoundRect() ); 657 SetRect(); 658 SetChanged(); 659 BroadcastObjectChange(); 660 if (pUserCall!=NULL) 661 pUserCall->Changed(*this, SDRUSERCALL_RESIZE, aTmp); 662 } 663 664 665 void __EXPORT SwVirtFlyDrawObj::NbcSetLogicRect(const Rectangle& ) 666 { 667 SetRect(); 668 } 669 670 671 ::basegfx::B2DPolyPolygon SwVirtFlyDrawObj::TakeXorPoly() const 672 { 673 const Rectangle aSourceRectangle(GetFlyFrm()->Frm().SVRect()); 674 const ::basegfx::B2DRange aSourceRange(aSourceRectangle.Left(), aSourceRectangle.Top(), aSourceRectangle.Right(), aSourceRectangle.Bottom()); 675 ::basegfx::B2DPolyPolygon aRetval; 676 677 aRetval.append(::basegfx::tools::createPolygonFromRect(aSourceRange)); 678 679 return aRetval; 680 } 681 682 /************************************************************************* 683 |* 684 |* SwVirtFlyDrawObj::Move() und Resize() 685 |* 686 |* Ersterstellung MA 12. Jan. 95 687 |* Letzte Aenderung MA 26. Jul. 96 688 |* 689 *************************************************************************/ 690 691 void __EXPORT SwVirtFlyDrawObj::NbcMove(const Size& rSiz) 692 { 693 MoveRect( aOutRect, rSiz ); 694 const Point aOldPos( GetFlyFrm()->Frm().Pos() ); 695 const Point aNewPos( aOutRect.TopLeft() ); 696 const SwRect aFlyRect( aOutRect ); 697 698 //Wenn der Fly eine automatische Ausrichtung hat (rechts oder oben), 699 //so soll die Automatik erhalten bleiben 700 SwFrmFmt *pFmt = GetFlyFrm()->GetFmt(); 701 const sal_Int16 eHori = pFmt->GetHoriOrient().GetHoriOrient(); 702 const sal_Int16 eVert = pFmt->GetVertOrient().GetVertOrient(); 703 const sal_Int16 eRelHori = pFmt->GetHoriOrient().GetRelationOrient(); 704 const sal_Int16 eRelVert = pFmt->GetVertOrient().GetRelationOrient(); 705 //Bei Absatzgebundenen Flys muss ausgehend von der neuen Position ein 706 //neuer Anker gesetzt werden. Anker und neue RelPos werden vom Fly selbst 707 //berechnet und gesetzt. 708 if( GetFlyFrm()->IsFlyAtCntFrm() ) 709 ((SwFlyAtCntFrm*)GetFlyFrm())->SetAbsPos( aNewPos ); 710 else 711 { 712 const SwFrmFmt *pTmpFmt = GetFmt(); 713 const SwFmtVertOrient &rVert = pTmpFmt->GetVertOrient(); 714 const SwFmtHoriOrient &rHori = pTmpFmt->GetHoriOrient(); 715 long lXDiff = aNewPos.X() - aOldPos.X(); 716 if( rHori.IsPosToggle() && text::HoriOrientation::NONE == eHori && 717 !GetFlyFrm()->FindPageFrm()->OnRightPage() ) 718 lXDiff = -lXDiff; 719 720 if( GetFlyFrm()->GetAnchorFrm()->IsRightToLeft() && 721 text::HoriOrientation::NONE == eHori ) 722 lXDiff = -lXDiff; 723 724 long lYDiff = aNewPos.Y() - aOldPos.Y(); 725 if( GetFlyFrm()->GetAnchorFrm()->IsVertical() ) 726 { 727 //lXDiff -= rVert.GetPos(); 728 //lYDiff += rHori.GetPos(); 729 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin 730 if ( GetFlyFrm()->GetAnchorFrm()->IsVertLR() ) 731 { 732 lXDiff += rVert.GetPos(); 733 lXDiff = -lXDiff; 734 } 735 else 736 { 737 lXDiff -= rVert.GetPos(); 738 lYDiff += rHori.GetPos(); 739 } 740 } 741 else 742 { 743 lXDiff += rHori.GetPos(); 744 lYDiff += rVert.GetPos(); 745 } 746 747 if( GetFlyFrm()->GetAnchorFrm()->IsRightToLeft() && 748 text::HoriOrientation::NONE != eHori ) 749 lXDiff = GetFlyFrm()->GetAnchorFrm()->Frm().Width() - 750 aFlyRect.Width() - lXDiff; 751 752 const Point aTmp( lXDiff, lYDiff ); 753 GetFlyFrm()->ChgRelPos( aTmp ); 754 } 755 756 SwAttrSet aSet( pFmt->GetDoc()->GetAttrPool(), 757 RES_VERT_ORIENT, RES_HORI_ORIENT ); 758 SwFmtHoriOrient aHori( pFmt->GetHoriOrient() ); 759 SwFmtVertOrient aVert( pFmt->GetVertOrient() ); 760 sal_Bool bPut = sal_False; 761 762 if( !GetFlyFrm()->IsFlyLayFrm() && 763 ::GetHtmlMode(pFmt->GetDoc()->GetDocShell()) ) 764 { 765 //Im HTML-Modus sind nur automatische Ausrichtungen erlaubt. 766 //Einzig einen Snap auf Links/Rechts bzw. Linker-/Rechter-Rand koennen 767 //wir versuchen. 768 const SwFrm* pAnch = GetFlyFrm()->GetAnchorFrm(); 769 sal_Bool bNextLine = sal_False; 770 771 if( !GetFlyFrm()->IsAutoPos() || text::RelOrientation::PAGE_FRAME != aHori.GetRelationOrient() ) 772 { 773 if( text::RelOrientation::CHAR == eRelHori ) 774 { 775 aHori.SetHoriOrient( text::HoriOrientation::LEFT ); 776 aHori.SetRelationOrient( text::RelOrientation::CHAR ); 777 } 778 else 779 { 780 bNextLine = sal_True; 781 //Horizontale Ausrichtung: 782 const sal_Bool bLeftFrm = 783 aFlyRect.Left() < pAnch->Frm().Left() + pAnch->Prt().Left(), 784 bLeftPrt = aFlyRect.Left() + aFlyRect.Width() < 785 pAnch->Frm().Left() + pAnch->Prt().Width()/2; 786 if ( bLeftFrm || bLeftPrt ) 787 { 788 aHori.SetHoriOrient( text::HoriOrientation::LEFT ); 789 aHori.SetRelationOrient( bLeftFrm ? text::RelOrientation::FRAME : text::RelOrientation::PRINT_AREA ); 790 } 791 else 792 { 793 const sal_Bool bRightFrm = aFlyRect.Left() > 794 pAnch->Frm().Left() + pAnch->Prt().Width(); 795 aHori.SetHoriOrient( text::HoriOrientation::RIGHT ); 796 aHori.SetRelationOrient( bRightFrm ? text::RelOrientation::FRAME : text::RelOrientation::PRINT_AREA ); 797 } 798 } 799 aSet.Put( aHori ); 800 } 801 //Vertikale Ausrichtung bleibt grundsaetzlich schlicht erhalten, 802 //nur bei nicht automatischer Ausrichtung wird umgeschaltet. 803 sal_Bool bRelChar = text::RelOrientation::CHAR == eRelVert; 804 aVert.SetVertOrient( eVert != text::VertOrientation::NONE ? eVert : 805 GetFlyFrm()->IsFlyInCntFrm() ? text::VertOrientation::CHAR_CENTER : 806 bRelChar && bNextLine ? text::VertOrientation::CHAR_TOP : text::VertOrientation::TOP ); 807 if( bRelChar ) 808 aVert.SetRelationOrient( text::RelOrientation::CHAR ); 809 else 810 aVert.SetRelationOrient( text::RelOrientation::PRINT_AREA ); 811 aSet.Put( aVert ); 812 bPut = sal_True; 813 } 814 815 //Automatische Ausrichtungen wollen wir moeglichst nicht verlieren. 816 if ( !bPut && bInResize ) 817 { 818 if ( text::HoriOrientation::NONE != eHori ) 819 { 820 aHori.SetHoriOrient( eHori ); 821 aHori.SetRelationOrient( eRelHori ); 822 aSet.Put( aHori ); 823 bPut = sal_True; 824 } 825 if ( text::VertOrientation::NONE != eVert ) 826 { 827 aVert.SetVertOrient( eVert ); 828 aVert.SetRelationOrient( eRelVert ); 829 aSet.Put( aVert ); 830 bPut = sal_True; 831 } 832 } 833 if ( bPut ) 834 pFmt->SetFmtAttr( aSet ); 835 } 836 837 838 void __EXPORT SwVirtFlyDrawObj::NbcResize(const Point& rRef, 839 const Fraction& xFact, const Fraction& yFact) 840 { 841 ResizeRect( aOutRect, rRef, xFact, yFact ); 842 843 const SwFrm* pTmpFrm = GetFlyFrm()->GetAnchorFrm(); 844 if( !pTmpFrm ) 845 pTmpFrm = GetFlyFrm(); 846 const bool bVertX = pTmpFrm->IsVertical(); 847 848 const sal_Bool bRTL = pTmpFrm->IsRightToLeft(); 849 850 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin 851 const bool bVertL2RX = pTmpFrm->IsVertLR(); 852 const Point aNewPos( ( bVertX && !bVertL2RX ) || bRTL ? 853 aOutRect.Right() + 1 : 854 aOutRect.Left(), 855 aOutRect.Top() ); 856 857 Size aSz( aOutRect.Right() - aOutRect.Left() + 1, 858 aOutRect.Bottom()- aOutRect.Top() + 1 ); 859 if( aSz != GetFlyFrm()->Frm().SSize() ) 860 { 861 //Die Breite darf bei Spalten nicht zu schmal werden 862 if ( GetFlyFrm()->Lower() && GetFlyFrm()->Lower()->IsColumnFrm() ) 863 { 864 SwBorderAttrAccess aAccess( SwFrm::GetCache(), GetFlyFrm() ); 865 const SwBorderAttrs &rAttrs = *aAccess.Get(); 866 long nMin = rAttrs.CalcLeftLine()+rAttrs.CalcRightLine(); 867 const SwFmtCol& rCol = rAttrs.GetAttrSet().GetCol(); 868 if ( rCol.GetColumns().Count() > 1 ) 869 { 870 for ( sal_uInt16 i = 0; i < rCol.GetColumns().Count(); ++i ) 871 { 872 nMin += rCol.GetColumns()[i]->GetLeft() + 873 rCol.GetColumns()[i]->GetRight() + 874 MINFLY; 875 } 876 nMin -= MINFLY; 877 } 878 aSz.Width() = Max( aSz.Width(), nMin ); 879 } 880 881 SwFrmFmt *pFmt = GetFmt(); 882 const SwFmtFrmSize aOldFrmSz( pFmt->GetFrmSize() ); 883 GetFlyFrm()->ChgSize( aSz ); 884 SwFmtFrmSize aFrmSz( pFmt->GetFrmSize() ); 885 if ( aFrmSz.GetWidthPercent() || aFrmSz.GetHeightPercent() ) 886 { 887 long nRelWidth, nRelHeight; 888 const SwFrm *pRel = GetFlyFrm()->IsFlyLayFrm() ? 889 GetFlyFrm()->GetAnchorFrm() : 890 GetFlyFrm()->GetAnchorFrm()->GetUpper(); 891 const ViewShell *pSh = GetFlyFrm()->getRootFrm()->GetCurrShell(); 892 if ( pSh && pRel->IsBodyFrm() && 893 pSh->GetViewOptions()->getBrowseMode() && 894 pSh->VisArea().HasArea() ) 895 { 896 nRelWidth = pSh->GetBrowseWidth(); 897 nRelHeight = pSh->VisArea().Height(); 898 const Size aBorder = pSh->GetOut()->PixelToLogic( pSh->GetBrowseBorder() ); 899 nRelHeight -= 2*aBorder.Height(); 900 } 901 else 902 { 903 nRelWidth = pRel->Prt().Width(); 904 nRelHeight = pRel->Prt().Height(); 905 } 906 if ( aFrmSz.GetWidthPercent() && aFrmSz.GetWidthPercent() != 0xFF && 907 aOldFrmSz.GetWidth() != aFrmSz.GetWidth() ) 908 aFrmSz.SetWidthPercent( sal_uInt8(aSz.Width() * 100L / nRelWidth + 0.5) ); 909 if ( aFrmSz.GetHeightPercent() && aFrmSz.GetHeightPercent() != 0xFF && 910 aOldFrmSz.GetHeight() != aFrmSz.GetHeight() ) 911 aFrmSz.SetHeightPercent( sal_uInt8(aSz.Height() * 100L / nRelHeight + 0.5) ); 912 pFmt->GetDoc()->SetAttr( aFrmSz, *pFmt ); 913 } 914 } 915 916 //Position kann auch veraendert sein! 917 const Point aOldPos( ( bVertX && !bVertL2RX ) || bRTL ? 918 GetFlyFrm()->Frm().TopRight() : 919 GetFlyFrm()->Frm().Pos() ); 920 if ( aNewPos != aOldPos ) 921 { 922 //Kann sich durch das ChgSize veraendert haben! 923 if( bVertX || bRTL ) 924 { 925 if( aOutRect.TopRight() != aNewPos ) 926 { 927 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin 928 SwTwips nDeltaX; 929 if ( bVertL2RX ) 930 nDeltaX = aNewPos.X() - aOutRect.Left(); 931 else 932 nDeltaX = aNewPos.X() - aOutRect.Right(); 933 SwTwips nDeltaY = aNewPos.Y() - aOutRect.Top(); 934 MoveRect( aOutRect, Size( nDeltaX, nDeltaY ) ); 935 } 936 } 937 else if ( aOutRect.TopLeft() != aNewPos ) 938 aOutRect.SetPos( aNewPos ); 939 bInResize = sal_True; 940 NbcMove( Size( 0, 0 ) ); 941 bInResize = sal_False; 942 } 943 } 944 945 946 void __EXPORT SwVirtFlyDrawObj::Move(const Size& rSiz) 947 { 948 NbcMove( rSiz ); 949 SetChanged(); 950 GetFmt()->GetDoc()->GetIDocumentUndoRedo().DoDrawUndo(false); 951 } 952 953 954 void __EXPORT SwVirtFlyDrawObj::Resize(const Point& rRef, 955 const Fraction& xFact, const Fraction& yFact) 956 { 957 NbcResize( rRef, xFact, yFact ); 958 SetChanged(); 959 GetFmt()->GetDoc()->GetIDocumentUndoRedo().DoDrawUndo(false); 960 } 961 962 963 Pointer __EXPORT SwVirtFlyDrawObj::GetMacroPointer( 964 const SdrObjMacroHitRec& ) const 965 { 966 return Pointer( POINTER_REFHAND ); 967 } 968 969 970 FASTBOOL __EXPORT SwVirtFlyDrawObj::HasMacro() const 971 { 972 const SwFmtURL &rURL = pFlyFrm->GetFmt()->GetURL(); 973 return rURL.GetMap() || rURL.GetURL().Len(); 974 } 975 976 977 SdrObject* SwVirtFlyDrawObj::CheckMacroHit( const SdrObjMacroHitRec& rRec ) const 978 { 979 const SwFmtURL &rURL = pFlyFrm->GetFmt()->GetURL(); 980 if( rURL.GetMap() || rURL.GetURL().Len() ) 981 { 982 SwRect aRect; 983 if ( pFlyFrm->Lower() && pFlyFrm->Lower()->IsNoTxtFrm() ) 984 { 985 aRect = pFlyFrm->Prt(); 986 aRect += pFlyFrm->Frm().Pos(); 987 } 988 else 989 aRect = pFlyFrm->Frm(); 990 991 if( aRect.IsInside( rRec.aPos ) ) 992 { 993 SwRect aActRect( aRect ); 994 Size aActSz( aRect.SSize() ); 995 aRect.Pos().X() += rRec.nTol; 996 aRect.Pos().Y() += rRec.nTol; 997 aRect.SSize().Height()-= 2 * rRec.nTol; 998 aRect.SSize().Width() -= 2 * rRec.nTol; 999 1000 if( aRect.IsInside( rRec.aPos ) ) 1001 { 1002 if( !rURL.GetMap() || 1003 pFlyFrm->GetFmt()->GetIMapObject( rRec.aPos, pFlyFrm )) 1004 return (SdrObject*)this; 1005 1006 return 0; 1007 } 1008 } 1009 } 1010 return SdrObject::CheckMacroHit( rRec ); 1011 } 1012 1013 bool SwVirtFlyDrawObj::supportsFullDrag() const 1014 { 1015 // call parent 1016 return SdrVirtObj::supportsFullDrag(); 1017 } 1018 1019 SdrObject* SwVirtFlyDrawObj::getFullDragClone() const 1020 { 1021 // call parent 1022 return SdrVirtObj::getFullDragClone(); 1023 } 1024 1025 // eof 1026