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