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_svx.hxx" 26 27 #include <svx/svdovirt.hxx> 28 #include <svx/xpool.hxx> 29 #include <svx/svdtrans.hxx> 30 #include <svx/svdetc.hxx> 31 #include <svx/svdhdl.hxx> 32 #include <svx/sdr/contact/viewcontactofvirtobj.hxx> 33 #include <basegfx/matrix/b2dhommatrix.hxx> 34 #include <svx/svdograf.hxx> 35 #include <svx/svddrgv.hxx> 36 #include <basegfx/matrix/b2dhommatrixtools.hxx> 37 38 //////////////////////////////////////////////////////////////////////////////////////////////////// 39 40 sdr::properties::BaseProperties& SdrVirtObj::GetProperties() const 41 { 42 return rRefObj.GetProperties(); 43 } 44 45 //////////////////////////////////////////////////////////////////////////////////////////////////// 46 // AW, OD 2004-05-03 #i27224# 47 sdr::contact::ViewContact* SdrVirtObj::CreateObjectSpecificViewContact() 48 { 49 return new sdr::contact::ViewContactOfVirtObj(*this); 50 } 51 52 //////////////////////////////////////////////////////////////////////////////////////////////////// 53 54 TYPEINIT1(SdrVirtObj,SdrObject); 55 56 SdrVirtObj::SdrVirtObj(SdrObject& rNewObj): 57 rRefObj(rNewObj) 58 { 59 bVirtObj=sal_True; // Ja, ich bin ein virtuelles Objekt 60 rRefObj.AddReference(*this); 61 bClosedObj=rRefObj.IsClosedObj(); 62 } 63 64 SdrVirtObj::SdrVirtObj(SdrObject& rNewObj, const Point& rAnchorPos): 65 rRefObj(rNewObj) 66 { 67 aAnchor=rAnchorPos; 68 bVirtObj=sal_True; // Ja, ich bin ein virtuelles Objekt 69 rRefObj.AddReference(*this); 70 bClosedObj=rRefObj.IsClosedObj(); 71 } 72 73 SdrVirtObj::~SdrVirtObj() 74 { 75 rRefObj.DelReference(*this); 76 } 77 78 //////////////////////////////////////////////////////////////////////////////////////////////////// 79 80 const SdrObject& SdrVirtObj::GetReferencedObj() const 81 { 82 return rRefObj; 83 } 84 85 SdrObject& SdrVirtObj::ReferencedObj() 86 { 87 return rRefObj; 88 } 89 90 void __EXPORT SdrVirtObj::Notify(SfxBroadcaster& /*rBC*/, const SfxHint& /*rHint*/) 91 { 92 bClosedObj=rRefObj.IsClosedObj(); 93 SetRectsDirty(); // hier noch Optimieren. 94 95 // Only a repaint here, rRefObj may have changed and broadcasts 96 ActionChanged(); 97 // BroadcastObjectChange(); 98 } 99 100 void SdrVirtObj::NbcSetAnchorPos(const Point& rAnchorPos) 101 { 102 aAnchor=rAnchorPos; 103 } 104 105 //////////////////////////////////////////////////////////////////////////////////////////////////// 106 107 void SdrVirtObj::SetModel(SdrModel* pNewModel) 108 { 109 SdrObject::SetModel(pNewModel); 110 rRefObj.SetModel(pNewModel); 111 } 112 113 void SdrVirtObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const 114 { 115 rRefObj.TakeObjInfo(rInfo); 116 } 117 118 sal_uInt32 SdrVirtObj::GetObjInventor() const 119 { 120 return rRefObj.GetObjInventor(); 121 } 122 123 sal_uInt16 SdrVirtObj::GetObjIdentifier() const 124 { 125 return rRefObj.GetObjIdentifier(); 126 } 127 128 SdrObjList* SdrVirtObj::GetSubList() const 129 { 130 return rRefObj.GetSubList(); 131 } 132 133 const Rectangle& SdrVirtObj::GetCurrentBoundRect() const 134 { 135 ((SdrVirtObj*)this)->aOutRect=rRefObj.GetCurrentBoundRect(); // Hier noch optimieren 136 ((SdrVirtObj*)this)->aOutRect+=aAnchor; 137 return aOutRect; 138 } 139 140 const Rectangle& SdrVirtObj::GetLastBoundRect() const 141 { 142 ((SdrVirtObj*)this)->aOutRect=rRefObj.GetLastBoundRect(); // Hier noch optimieren 143 ((SdrVirtObj*)this)->aOutRect+=aAnchor; 144 return aOutRect; 145 } 146 147 void SdrVirtObj::RecalcBoundRect() 148 { 149 aOutRect=rRefObj.GetCurrentBoundRect(); 150 aOutRect+=aAnchor; 151 } 152 153 void SdrVirtObj::SetChanged() 154 { 155 SdrObject::SetChanged(); 156 } 157 158 SdrObject* SdrVirtObj::Clone() const 159 { 160 SdrObject* pObj=new SdrVirtObj(((SdrVirtObj*)this)->rRefObj); // Nur eine weitere Referenz 161 return pObj; 162 } 163 164 void SdrVirtObj::operator=(const SdrObject& rObj) 165 { // ???anderes Objekt referenzieren??? 166 SdrObject::operator=(rObj); 167 aAnchor=((SdrVirtObj&)rObj).aAnchor; 168 } 169 170 void SdrVirtObj::TakeObjNameSingul(XubString& rName) const 171 { 172 rRefObj.TakeObjNameSingul(rName); 173 rName.Insert(sal_Unicode('['), 0); 174 rName += sal_Unicode(']'); 175 176 String aName( GetName() ); 177 if(aName.Len()) 178 { 179 rName += sal_Unicode(' '); 180 rName += sal_Unicode('\''); 181 rName += aName; 182 rName += sal_Unicode('\''); 183 } 184 } 185 186 void SdrVirtObj::TakeObjNamePlural(XubString& rName) const 187 { 188 rRefObj.TakeObjNamePlural(rName); 189 rName.Insert(sal_Unicode('['), 0); 190 rName += sal_Unicode(']'); 191 } 192 193 void operator +=(PolyPolygon& rPoly, const Point& rOfs) 194 { 195 if (rOfs.X()!=0 || rOfs.Y()!=0) { 196 sal_uInt16 i,j; 197 for (j=0; j<rPoly.Count(); j++) { 198 Polygon aP1(rPoly.GetObject(j)); 199 for (i=0; i<aP1.GetSize(); i++) { 200 aP1[i]+=rOfs; 201 } 202 rPoly.Replace(aP1,j); 203 } 204 } 205 } 206 207 basegfx::B2DPolyPolygon SdrVirtObj::TakeXorPoly() const 208 { 209 basegfx::B2DPolyPolygon aPolyPolygon(rRefObj.TakeXorPoly()); 210 211 if(aAnchor.X() || aAnchor.Y()) 212 { 213 aPolyPolygon.transform(basegfx::tools::createTranslateB2DHomMatrix(aAnchor.X(), aAnchor.Y())); 214 } 215 216 return aPolyPolygon; 217 } 218 219 //////////////////////////////////////////////////////////////////////////////////////////////////// 220 221 sal_uInt32 SdrVirtObj::GetHdlCount() const 222 { 223 return rRefObj.GetHdlCount(); 224 } 225 226 SdrHdl* SdrVirtObj::GetHdl(sal_uInt32 nHdlNum) const 227 { 228 SdrHdl* pHdl=rRefObj.GetHdl(nHdlNum); 229 230 // #i73248# 231 // GetHdl() at SdrObject is not guaranteed to return an object 232 if(pHdl) 233 { 234 Point aP(pHdl->GetPos()+aAnchor); 235 pHdl->SetPos(aP); 236 } 237 238 return pHdl; 239 } 240 241 sal_uInt32 SdrVirtObj::GetPlusHdlCount(const SdrHdl& rHdl) const 242 { 243 return rRefObj.GetPlusHdlCount(rHdl); 244 } 245 246 SdrHdl* SdrVirtObj::GetPlusHdl(const SdrHdl& rHdl, sal_uInt32 nPlNum) const 247 { 248 SdrHdl* pHdl=rRefObj.GetPlusHdl(rHdl,nPlNum); 249 pHdl->SetPos(pHdl->GetPos() + aAnchor); 250 return pHdl; 251 } 252 253 void SdrVirtObj::AddToHdlList(SdrHdlList& rHdlList) const 254 { 255 // #i73248# 256 // SdrObject::AddToHdlList(rHdlList) is not a good thing to call 257 // since at SdrPathObj, only AddToHdlList may be used and the call 258 // will instead use the standard implementation which uses GetHdlCount() 259 // and GetHdl instead. This is not wrong, but may be much less effective 260 // and may not be prepared to GetHdl returning NULL 261 262 // get handles using AddToHdlList from ref object 263 SdrHdlList aLocalList(0); 264 rRefObj.AddToHdlList(aLocalList); 265 const sal_uInt32 nHdlCount(aLocalList.GetHdlCount()); 266 267 if(nHdlCount) 268 { 269 // translate handles and add them to dest list. They are temporarily part of 270 // two lists then 271 const Point aOffset(GetOffset()); 272 273 for(sal_uInt32 a(0L); a < nHdlCount; a++) 274 { 275 SdrHdl* pCandidate = aLocalList.GetHdl(a); 276 pCandidate->SetPos(pCandidate->GetPos() + aOffset); 277 rHdlList.AddHdl(pCandidate); 278 } 279 280 // remove them from source list, else they will be deleted when 281 // source list is deleted 282 while(aLocalList.GetHdlCount()) 283 { 284 aLocalList.RemoveHdl(aLocalList.GetHdlCount() - 1L); 285 } 286 } 287 } 288 289 //////////////////////////////////////////////////////////////////////////////////////////////////// 290 291 bool SdrVirtObj::hasSpecialDrag() const 292 { 293 return rRefObj.hasSpecialDrag(); 294 } 295 296 bool SdrVirtObj::supportsFullDrag() const 297 { 298 return false; 299 } 300 301 SdrObject* SdrVirtObj::getFullDragClone() const 302 { 303 static bool bSpecialHandling(false); 304 SdrObject* pRetval = 0; 305 306 if(bSpecialHandling) 307 { 308 // special handling for VirtObj. Do not create another 309 // reference to rRefObj, this would allow to change that 310 // one on drag. Instead, create a SdrGrafObj for drag containing 311 // the graphical representation 312 pRetval = new SdrGrafObj(SdrDragView::GetObjGraphic(GetModel(), this), GetLogicRect()); 313 } 314 else 315 { 316 SdrObject& rReferencedObject = ((SdrVirtObj*)this)->ReferencedObj(); 317 pRetval = new SdrGrafObj(SdrDragView::GetObjGraphic(GetModel(), &rReferencedObject), GetLogicRect()); 318 } 319 320 return pRetval; 321 } 322 323 bool SdrVirtObj::beginSpecialDrag(SdrDragStat& rDrag) const 324 { 325 return rRefObj.beginSpecialDrag(rDrag); 326 } 327 328 bool SdrVirtObj::applySpecialDrag(SdrDragStat& rDrag) 329 { 330 return rRefObj.applySpecialDrag(rDrag); 331 } 332 333 basegfx::B2DPolyPolygon SdrVirtObj::getSpecialDragPoly(const SdrDragStat& rDrag) const 334 { 335 return rRefObj.getSpecialDragPoly(rDrag); 336 // Offset handlen !!!!!! fehlt noch !!!!!!! 337 } 338 339 String SdrVirtObj::getSpecialDragComment(const SdrDragStat& rDrag) const 340 { 341 return rRefObj.getSpecialDragComment(rDrag); 342 } 343 344 //////////////////////////////////////////////////////////////////////////////////////////////////// 345 346 FASTBOOL SdrVirtObj::BegCreate(SdrDragStat& rStat) 347 { 348 return rRefObj.BegCreate(rStat); 349 } 350 351 FASTBOOL SdrVirtObj::MovCreate(SdrDragStat& rStat) 352 { 353 return rRefObj.MovCreate(rStat); 354 } 355 356 FASTBOOL SdrVirtObj::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd) 357 { 358 return rRefObj.EndCreate(rStat,eCmd); 359 } 360 361 FASTBOOL SdrVirtObj::BckCreate(SdrDragStat& rStat) 362 { 363 return rRefObj.BckCreate(rStat); 364 } 365 366 void SdrVirtObj::BrkCreate(SdrDragStat& rStat) 367 { 368 rRefObj.BrkCreate(rStat); 369 } 370 371 basegfx::B2DPolyPolygon SdrVirtObj::TakeCreatePoly(const SdrDragStat& rDrag) const 372 { 373 return rRefObj.TakeCreatePoly(rDrag); 374 // Offset handlen !!!!!! fehlt noch !!!!!!! 375 } 376 377 //////////////////////////////////////////////////////////////////////////////////////////////////// 378 379 void SdrVirtObj::NbcMove(const Size& rSiz) 380 { 381 MovePoint(aAnchor,rSiz); 382 SetRectsDirty(); 383 } 384 385 void SdrVirtObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact) 386 { 387 rRefObj.NbcResize(rRef-aAnchor,xFact,yFact); 388 SetRectsDirty(); 389 } 390 391 void SdrVirtObj::NbcRotate(const Point& rRef, long nWink, double sn, double cs) 392 { 393 rRefObj.NbcRotate(rRef-aAnchor,nWink,sn,cs); 394 SetRectsDirty(); 395 } 396 397 void SdrVirtObj::NbcMirror(const Point& rRef1, const Point& rRef2) 398 { 399 rRefObj.NbcMirror(rRef1-aAnchor,rRef2-aAnchor); 400 SetRectsDirty(); 401 } 402 403 void SdrVirtObj::NbcShear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear) 404 { 405 rRefObj.NbcShear(rRef-aAnchor,nWink,tn,bVShear); 406 SetRectsDirty(); 407 } 408 409 //////////////////////////////////////////////////////////////////////////////////////////////////// 410 411 void SdrVirtObj::Move(const Size& rSiz) 412 { 413 if (rSiz.Width()!=0 || rSiz.Height()!=0) { 414 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect(); 415 // #110094#-14 SendRepaintBroadcast(); 416 NbcMove(rSiz); 417 SetChanged(); 418 BroadcastObjectChange(); 419 SendUserCall(SDRUSERCALL_MOVEONLY,aBoundRect0); 420 } 421 } 422 423 void SdrVirtObj::Resize(const Point& rRef, const Fraction& xFact, const Fraction& yFact) 424 { 425 if (xFact.GetNumerator()!=xFact.GetDenominator() || yFact.GetNumerator()!=yFact.GetDenominator()) { 426 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect(); 427 rRefObj.Resize(rRef-aAnchor,xFact,yFact); 428 SetRectsDirty(); 429 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0); 430 } 431 } 432 433 void SdrVirtObj::Rotate(const Point& rRef, long nWink, double sn, double cs) 434 { 435 if (nWink!=0) { 436 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect(); 437 rRefObj.Rotate(rRef-aAnchor,nWink,sn,cs); 438 SetRectsDirty(); 439 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0); 440 } 441 } 442 443 void SdrVirtObj::Mirror(const Point& rRef1, const Point& rRef2) 444 { 445 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect(); 446 rRefObj.Mirror(rRef1-aAnchor,rRef2-aAnchor); 447 SetRectsDirty(); 448 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0); 449 } 450 451 void SdrVirtObj::Shear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear) 452 { 453 if (nWink!=0) { 454 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect(); 455 rRefObj.Shear(rRef-aAnchor,nWink,tn,bVShear); 456 SetRectsDirty(); 457 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0); 458 } 459 } 460 461 //////////////////////////////////////////////////////////////////////////////////////////////////// 462 463 void SdrVirtObj::RecalcSnapRect() 464 { 465 aSnapRect=rRefObj.GetSnapRect(); 466 aSnapRect+=aAnchor; 467 } 468 469 const Rectangle& SdrVirtObj::GetSnapRect() const 470 { 471 ((SdrVirtObj*)this)->aSnapRect=rRefObj.GetSnapRect(); 472 ((SdrVirtObj*)this)->aSnapRect+=aAnchor; 473 return aSnapRect; 474 } 475 476 void SdrVirtObj::SetSnapRect(const Rectangle& rRect) 477 { 478 { 479 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect(); 480 Rectangle aR(rRect); 481 aR-=aAnchor; 482 rRefObj.SetSnapRect(aR); 483 SetRectsDirty(); 484 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0); 485 } 486 } 487 488 void SdrVirtObj::NbcSetSnapRect(const Rectangle& rRect) 489 { 490 Rectangle aR(rRect); 491 aR-=aAnchor; 492 SetRectsDirty(); 493 rRefObj.NbcSetSnapRect(aR); 494 } 495 496 //////////////////////////////////////////////////////////////////////////////////////////////////// 497 498 const Rectangle& SdrVirtObj::GetLogicRect() const 499 { 500 ((SdrVirtObj*)this)->aSnapRect=rRefObj.GetLogicRect(); // !!! Missbrauch von aSnapRect !!! 501 ((SdrVirtObj*)this)->aSnapRect+=aAnchor; // Wenns mal Aerger gibt, muss ein weiteres Rectangle Member her (oder Heap) 502 return aSnapRect; 503 } 504 505 void SdrVirtObj::SetLogicRect(const Rectangle& rRect) 506 { 507 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect(); 508 Rectangle aR(rRect); 509 aR-=aAnchor; 510 rRefObj.SetLogicRect(aR); 511 SetRectsDirty(); 512 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0); 513 } 514 515 void SdrVirtObj::NbcSetLogicRect(const Rectangle& rRect) 516 { 517 Rectangle aR(rRect); 518 aR-=aAnchor; 519 SetRectsDirty(); 520 rRefObj.NbcSetLogicRect(aR); 521 } 522 523 //////////////////////////////////////////////////////////////////////////////////////////////////// 524 525 long SdrVirtObj::GetRotateAngle() const 526 { 527 return rRefObj.GetRotateAngle(); 528 } 529 530 long SdrVirtObj::GetShearAngle(FASTBOOL bVertical) const 531 { 532 return rRefObj.GetShearAngle(bVertical); 533 } 534 535 //////////////////////////////////////////////////////////////////////////////////////////////////// 536 537 sal_uInt32 SdrVirtObj::GetSnapPointCount() const 538 { 539 return rRefObj.GetSnapPointCount(); 540 } 541 542 Point SdrVirtObj::GetSnapPoint(sal_uInt32 i) const 543 { 544 Point aP(rRefObj.GetSnapPoint(i)); 545 aP+=aAnchor; 546 return aP; 547 } 548 549 sal_Bool SdrVirtObj::IsPolyObj() const 550 { 551 return rRefObj.IsPolyObj(); 552 } 553 554 sal_uInt32 SdrVirtObj::GetPointCount() const 555 { 556 return rRefObj.GetPointCount(); 557 } 558 559 Point SdrVirtObj::GetPoint(sal_uInt32 i) const 560 { 561 return Point(rRefObj.GetPoint(i) + aAnchor); 562 } 563 564 void SdrVirtObj::NbcSetPoint(const Point& rPnt, sal_uInt32 i) 565 { 566 Point aP(rPnt); 567 aP-=aAnchor; 568 rRefObj.SetPoint(aP,i); 569 SetRectsDirty(); 570 } 571 572 //////////////////////////////////////////////////////////////////////////////////////////////////// 573 574 SdrObjGeoData* SdrVirtObj::NewGeoData() const 575 { 576 return rRefObj.NewGeoData(); 577 } 578 579 void SdrVirtObj::SaveGeoData(SdrObjGeoData& rGeo) const 580 { 581 rRefObj.SaveGeoData(rGeo); 582 } 583 584 void SdrVirtObj::RestGeoData(const SdrObjGeoData& rGeo) 585 { 586 rRefObj.RestGeoData(rGeo); 587 SetRectsDirty(); 588 } 589 590 //////////////////////////////////////////////////////////////////////////////////////////////////// 591 592 SdrObjGeoData* SdrVirtObj::GetGeoData() const 593 { 594 return rRefObj.GetGeoData(); 595 } 596 597 void SdrVirtObj::SetGeoData(const SdrObjGeoData& rGeo) 598 { 599 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect(); 600 rRefObj.SetGeoData(rGeo); 601 SetRectsDirty(); 602 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0); 603 } 604 605 //////////////////////////////////////////////////////////////////////////////////////////////////// 606 607 void SdrVirtObj::NbcReformatText() 608 { 609 rRefObj.NbcReformatText(); 610 } 611 612 void SdrVirtObj::ReformatText() 613 { 614 rRefObj.ReformatText(); 615 } 616 617 //////////////////////////////////////////////////////////////////////////////////////////////////// 618 619 FASTBOOL SdrVirtObj::HasMacro() const 620 { 621 return rRefObj.HasMacro(); 622 } 623 624 SdrObject* SdrVirtObj::CheckMacroHit(const SdrObjMacroHitRec& rRec) const 625 { 626 return rRefObj.CheckMacroHit(rRec); // Todo: Positionsversatz 627 } 628 629 Pointer SdrVirtObj::GetMacroPointer(const SdrObjMacroHitRec& rRec) const 630 { 631 return rRefObj.GetMacroPointer(rRec); // Todo: Positionsversatz 632 } 633 634 void SdrVirtObj::PaintMacro(OutputDevice& rOut, const Rectangle& rDirtyRect, const SdrObjMacroHitRec& rRec) const 635 { 636 rRefObj.PaintMacro(rOut,rDirtyRect,rRec); // Todo: Positionsversatz 637 } 638 639 FASTBOOL SdrVirtObj::DoMacro(const SdrObjMacroHitRec& rRec) 640 { 641 return rRefObj.DoMacro(rRec); // Todo: Positionsversatz 642 } 643 644 XubString SdrVirtObj::GetMacroPopupComment(const SdrObjMacroHitRec& rRec) const 645 { 646 return rRefObj.GetMacroPopupComment(rRec); // Todo: Positionsversatz 647 } 648 649 const Point SdrVirtObj::GetOffset() const 650 { 651 // #i73248# default offset of SdrVirtObj is aAnchor 652 return aAnchor; 653 } 654 655 // eof 656