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_svx.hxx" 30 31 #include "svddrgm1.hxx" 32 #include <math.h> 33 34 #ifndef _MATH_H 35 #define _MATH_H 36 #endif 37 #include <tools/bigint.hxx> 38 #include <vcl/svapp.hxx> 39 40 #include "svx/xattr.hxx" 41 #include <svx/xpoly.hxx> 42 #include <svx/svdetc.hxx> 43 #include <svx/svdtrans.hxx> 44 #include <svx/svdundo.hxx> 45 #include <svx/svdmark.hxx> 46 #include <svx/svdocapt.hxx> 47 #include <svx/svdpagv.hxx> 48 #include "svx/svdstr.hrc" // Namen aus der Resource 49 #include "svx/svdglob.hxx" // StringCache 50 #include <svx/svddrgv.hxx> 51 #include <svx/svdundo.hxx> 52 #include <svx/svdograf.hxx> 53 #include <svx/dialogs.hrc> 54 #include <svx/dialmgr.hxx> 55 #include <svx/sdgcpitm.hxx> 56 #include <basegfx/polygon/b2dpolygon.hxx> 57 #include <basegfx/polygon/b2dpolygontools.hxx> 58 #include <svx/sdr/overlay/overlaypolypolygon.hxx> 59 #include <svx/sdr/overlay/overlaymanager.hxx> 60 #include <svx/sdr/overlay/overlayrollingrectangle.hxx> 61 #include <svx/sdrpagewindow.hxx> 62 #include <svx/sdrpaintwindow.hxx> 63 #include <basegfx/matrix/b2dhommatrix.hxx> 64 #include <basegfx/polygon/b2dpolypolygontools.hxx> 65 #include <svx/sdr/contact/viewobjectcontact.hxx> 66 #include <svx/sdr/contact/viewcontact.hxx> 67 #include <svx/sdr/contact/displayinfo.hxx> 68 #include <svx/sdr/overlay/overlayprimitive2dsequenceobject.hxx> 69 #include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx> 70 #include <svx/sdr/contact/objectcontact.hxx> 71 #include "svx/svditer.hxx" 72 #include <svx/svdopath.hxx> 73 #include <svx/polypolygoneditor.hxx> 74 #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> 75 #include <drawinglayer/primitive2d/transformprimitive2d.hxx> 76 #include <drawinglayer/primitive2d/markerarrayprimitive2d.hxx> 77 #include <svx/sdr/primitive2d/sdrattributecreator.hxx> 78 #include <svx/sdr/primitive2d/sdrdecompositiontools.hxx> 79 #include <svx/svdoole2.hxx> 80 #include <svx/svdovirt.hxx> 81 #include <svx/svdouno.hxx> 82 #include <svx/sdr/primitive2d/sdrprimitivetools.hxx> 83 #include <basegfx/matrix/b2dhommatrixtools.hxx> 84 #include <drawinglayer/attribute/sdrlineattribute.hxx> 85 #include <drawinglayer/attribute/sdrlinestartendattribute.hxx> 86 87 //////////////////////////////////////////////////////////////////////////////////////////////////// 88 89 SdrDragEntry::SdrDragEntry() 90 : mbAddToTransparent(false) 91 { 92 } 93 94 SdrDragEntry::~SdrDragEntry() 95 { 96 } 97 98 //////////////////////////////////////////////////////////////////////////////////////////////////// 99 100 SdrDragEntryPolyPolygon::SdrDragEntryPolyPolygon(const basegfx::B2DPolyPolygon& rOriginalPolyPolygon) 101 : SdrDragEntry(), 102 maOriginalPolyPolygon(rOriginalPolyPolygon) 103 { 104 } 105 106 SdrDragEntryPolyPolygon::~SdrDragEntryPolyPolygon() 107 { 108 } 109 110 drawinglayer::primitive2d::Primitive2DSequence SdrDragEntryPolyPolygon::createPrimitive2DSequenceInCurrentState(SdrDragMethod& rDragMethod) 111 { 112 drawinglayer::primitive2d::Primitive2DSequence aRetval; 113 114 if(maOriginalPolyPolygon.count()) 115 { 116 basegfx::B2DPolyPolygon aCopy(maOriginalPolyPolygon); 117 const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer; 118 119 rDragMethod.applyCurrentTransformationToPolyPolygon(aCopy); 120 basegfx::BColor aColA(aSvtOptionsDrawinglayer.GetStripeColorA().getBColor()); 121 basegfx::BColor aColB(aSvtOptionsDrawinglayer.GetStripeColorB().getBColor()); 122 const double fStripeLength(aSvtOptionsDrawinglayer.GetStripeLength()); 123 124 if(Application::GetSettings().GetStyleSettings().GetHighContrastMode()) 125 { 126 aColA = aColB = Application::GetSettings().GetStyleSettings().GetHighlightColor().getBColor(); 127 aColB.invert(); 128 } 129 130 drawinglayer::primitive2d::Primitive2DReference aPolyPolygonMarkerPrimitive2D( 131 new drawinglayer::primitive2d::PolyPolygonMarkerPrimitive2D(aCopy, aColA, aColB, fStripeLength)); 132 133 aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aPolyPolygonMarkerPrimitive2D, 1); 134 } 135 136 return aRetval; 137 } 138 139 //////////////////////////////////////////////////////////////////////////////////////////////////// 140 141 SdrDragEntrySdrObject::SdrDragEntrySdrObject(const SdrObject& rOriginal, sdr::contact::ObjectContact& rObjectContact, bool bModify) 142 : SdrDragEntry(), 143 maOriginal(rOriginal), 144 mpClone(0), 145 mrObjectContact(rObjectContact), 146 mbModify(bModify) 147 { 148 // add SdrObject parts to transparent overlay stuff 149 setAddToTransparent(true); 150 } 151 152 SdrDragEntrySdrObject::~SdrDragEntrySdrObject() 153 { 154 if(mpClone) 155 { 156 SdrObject::Free(mpClone); 157 } 158 } 159 160 drawinglayer::primitive2d::Primitive2DSequence SdrDragEntrySdrObject::createPrimitive2DSequenceInCurrentState(SdrDragMethod& rDragMethod) 161 { 162 // for the moment, i need to re-create the clone in all cases. I need to figure 163 // out when clone and original have the same class, so that i can use operator= 164 // in those cases 165 166 // // copy all other needed stuff 167 // basegfx::B2DHomMatrix aMatrix; 168 // basegfx::B2DPolyPolygon aPolyPolygon; 169 // pOleObject->TRGetBaseGeometry(aMatrix, aPolyPolygon); 170 // pClone->TRSetBaseGeometry(aMatrix, aPolyPolygon); 171 172 const SdrObject* pSource = &maOriginal; 173 174 if(mpClone) 175 { 176 SdrObject::Free(mpClone); 177 mpClone = 0; 178 } 179 180 if(mbModify) 181 { 182 if(!mpClone) 183 { 184 mpClone = maOriginal.getFullDragClone(); 185 } 186 187 // apply original transformation, implemented at the DragMethods 188 rDragMethod.applyCurrentTransformationToSdrObject(*mpClone); 189 190 // choose source for geometry data 191 pSource = mpClone; 192 } 193 194 // get VOC and Primitive2DSequence 195 sdr::contact::ViewContact& rVC = pSource->GetViewContact(); 196 sdr::contact::ViewObjectContact& rVOC = rVC.GetViewObjectContact(mrObjectContact); 197 sdr::contact::DisplayInfo aDisplayInfo; 198 199 // Do not use the last ViewPort set at the OC from the last ProcessDisplay(), 200 // here we want the complete primitive sequence without visibility clippings 201 mrObjectContact.resetViewPort(); 202 203 return rVOC.getPrimitive2DSequenceHierarchy(aDisplayInfo); 204 } 205 206 //////////////////////////////////////////////////////////////////////////////////////////////////// 207 208 SdrDragEntryPrimitive2DSequence::SdrDragEntryPrimitive2DSequence( 209 const drawinglayer::primitive2d::Primitive2DSequence& rSequence, 210 bool bAddToTransparent) 211 : SdrDragEntry(), 212 maPrimitive2DSequence(rSequence) 213 { 214 // add parts to transparent overlay stuff eventually 215 setAddToTransparent(bAddToTransparent); 216 } 217 218 SdrDragEntryPrimitive2DSequence::~SdrDragEntryPrimitive2DSequence() 219 { 220 } 221 222 drawinglayer::primitive2d::Primitive2DSequence SdrDragEntryPrimitive2DSequence::createPrimitive2DSequenceInCurrentState(SdrDragMethod& rDragMethod) 223 { 224 drawinglayer::primitive2d::Primitive2DReference aTransformPrimitive2D( 225 new drawinglayer::primitive2d::TransformPrimitive2D( 226 rDragMethod.getCurrentTransformation(), 227 maPrimitive2DSequence)); 228 229 return drawinglayer::primitive2d::Primitive2DSequence(&aTransformPrimitive2D, 1); 230 } 231 232 //////////////////////////////////////////////////////////////////////////////////////////////////// 233 234 SdrDragEntryPointGlueDrag::SdrDragEntryPointGlueDrag(const std::vector< basegfx::B2DPoint >& rPositions, bool bIsPointDrag) 235 : maPositions(rPositions), 236 mbIsPointDrag(bIsPointDrag) 237 { 238 // add SdrObject parts to transparent overlay stuff 239 setAddToTransparent(true); 240 } 241 242 SdrDragEntryPointGlueDrag::~SdrDragEntryPointGlueDrag() 243 { 244 } 245 246 drawinglayer::primitive2d::Primitive2DSequence SdrDragEntryPointGlueDrag::createPrimitive2DSequenceInCurrentState(SdrDragMethod& rDragMethod) 247 { 248 drawinglayer::primitive2d::Primitive2DSequence aRetval; 249 250 if(!maPositions.empty()) 251 { 252 basegfx::B2DPolygon aPolygon; 253 sal_uInt32 a(0); 254 255 for(a = 0; a < maPositions.size(); a++) 256 { 257 aPolygon.append(maPositions[a]); 258 } 259 260 basegfx::B2DPolyPolygon aPolyPolygon(aPolygon); 261 262 rDragMethod.applyCurrentTransformationToPolyPolygon(aPolyPolygon); 263 264 const basegfx::B2DPolygon aTransformed(aPolyPolygon.getB2DPolygon(0)); 265 std::vector< basegfx::B2DPoint > aTransformedPositions; 266 267 aTransformedPositions.reserve(aTransformed.count()); 268 269 for(a = 0; a < aTransformed.count(); a++) 270 { 271 aTransformedPositions.push_back(aTransformed.getB2DPoint(a)); 272 } 273 274 if(mbIsPointDrag) 275 { 276 const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer; 277 basegfx::BColor aColor(aSvtOptionsDrawinglayer.GetStripeColorA().getBColor()); 278 279 if(Application::GetSettings().GetStyleSettings().GetHighContrastMode()) 280 { 281 aColor = Application::GetSettings().GetStyleSettings().GetHighlightColor().getBColor(); 282 } 283 284 drawinglayer::primitive2d::Primitive2DReference aMarkerArrayPrimitive2D( 285 new drawinglayer::primitive2d::MarkerArrayPrimitive2D(aTransformedPositions, 286 drawinglayer::primitive2d::createDefaultCross_3x3(aColor))); 287 288 aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aMarkerArrayPrimitive2D, 1); 289 } 290 else 291 { 292 const basegfx::BColor aBackPen(1.0, 1.0, 1.0); 293 const basegfx::BColor aRGBFrontColor(0.0, 0.0, 1.0); // COL_LIGHTBLUE 294 drawinglayer::primitive2d::Primitive2DReference aMarkerArrayPrimitive2D( 295 new drawinglayer::primitive2d::MarkerArrayPrimitive2D(aTransformedPositions, 296 drawinglayer::primitive2d::createDefaultGluepoint_7x7(aBackPen, aRGBFrontColor))); 297 298 aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aMarkerArrayPrimitive2D, 1); 299 } 300 } 301 302 return aRetval; 303 } 304 305 //////////////////////////////////////////////////////////////////////////////////////////////////// 306 307 TYPEINIT0(SdrDragMethod); 308 309 void SdrDragMethod::resetSdrDragEntries() 310 { 311 // clear entries; creation is on demand 312 clearSdrDragEntries(); 313 } 314 315 basegfx::B2DRange SdrDragMethod::getCurrentRange() const 316 { 317 return getB2DRangeFromOverlayObjectList(); 318 } 319 320 void SdrDragMethod::createSdrDragEntries() 321 { 322 if(getSdrDragView().GetSdrPageView() && getSdrDragView().GetSdrPageView()->HasMarkedObjPageView()) 323 { 324 if(getSdrDragView().IsDraggingPoints()) 325 { 326 createSdrDragEntries_PointDrag(); 327 } 328 else if(getSdrDragView().IsDraggingGluePoints()) 329 { 330 createSdrDragEntries_GlueDrag(); 331 } 332 else 333 { 334 if(getSolidDraggingActive()) 335 { 336 createSdrDragEntries_SolidDrag(); 337 } 338 else 339 { 340 createSdrDragEntries_PolygonDrag(); 341 } 342 } 343 } 344 } 345 346 void SdrDragMethod::createSdrDragEntryForSdrObject(const SdrObject& rOriginal, sdr::contact::ObjectContact& rObjectContact, bool bModify) 347 { 348 // add full obejct drag; Clone() at the object has to work 349 // for this 350 addSdrDragEntry(new SdrDragEntrySdrObject(rOriginal, rObjectContact, bModify)); 351 } 352 353 void SdrDragMethod::createSdrDragEntries_SolidDrag() 354 { 355 const sal_uInt32 nMarkAnz(getSdrDragView().GetMarkedObjectCount()); 356 SdrPageView* pPV = getSdrDragView().GetSdrPageView(); 357 358 if(pPV) 359 { 360 for(sal_uInt32 a(0); a < nMarkAnz; a++) 361 { 362 SdrMark* pM = getSdrDragView().GetSdrMarkByIndex(a); 363 364 if(pM->GetPageView() == pPV) 365 { 366 const SdrObject* pObject = pM->GetMarkedSdrObj(); 367 368 if(pObject) 369 { 370 if(pPV->PageWindowCount()) 371 { 372 sdr::contact::ObjectContact& rOC = pPV->GetPageWindow(0)->GetObjectContact(); 373 SdrObjListIter aIter(*pObject); 374 375 while(aIter.IsMore()) 376 { 377 SdrObject* pCandidate = aIter.Next(); 378 379 if(pCandidate) 380 { 381 const bool bSuppressFullDrag(!pCandidate->supportsFullDrag()); 382 bool bAddWireframe(bSuppressFullDrag); 383 384 if(!bAddWireframe && !pCandidate->HasLineStyle()) 385 { 386 // add wireframe for objects without outline 387 bAddWireframe = true; 388 } 389 390 if(!bSuppressFullDrag) 391 { 392 // add full obejct drag; Clone() at the object has to work 393 // for this 394 createSdrDragEntryForSdrObject(*pCandidate, rOC, true); 395 } 396 397 if(bAddWireframe) 398 { 399 // when dragging a 50% transparent copy of a filled or not filled object without 400 // outline, this is normally hard to see. Add extra wireframe in that case. This 401 // works nice e.g. with thext frames etc. 402 addSdrDragEntry(new SdrDragEntryPolyPolygon(pCandidate->TakeXorPoly())); 403 } 404 } 405 } 406 } 407 } 408 } 409 } 410 } 411 } 412 413 void SdrDragMethod::createSdrDragEntries_PolygonDrag() 414 { 415 const sal_uInt32 nMarkAnz(getSdrDragView().GetMarkedObjectCount()); 416 bool bNoPolygons(getSdrDragView().IsNoDragXorPolys() || nMarkAnz > getSdrDragView().GetDragXorPolyLimit()); 417 basegfx::B2DPolyPolygon aResult; 418 sal_uInt32 nPointCount(0); 419 420 for(sal_uInt32 a(0); !bNoPolygons && a < nMarkAnz; a++) 421 { 422 SdrMark* pM = getSdrDragView().GetSdrMarkByIndex(a); 423 424 if(pM->GetPageView() == getSdrDragView().GetSdrPageView()) 425 { 426 const basegfx::B2DPolyPolygon aNewPolyPolygon(pM->GetMarkedSdrObj()->TakeXorPoly()); 427 428 for(sal_uInt32 b(0); b < aNewPolyPolygon.count(); b++) 429 { 430 nPointCount += aNewPolyPolygon.getB2DPolygon(b).count(); 431 } 432 433 if(nPointCount > getSdrDragView().GetDragXorPointLimit()) 434 { 435 bNoPolygons = true; 436 } 437 438 if(!bNoPolygons) 439 { 440 aResult.append(aNewPolyPolygon); 441 } 442 } 443 } 444 445 if(bNoPolygons) 446 { 447 const Rectangle aR(getSdrDragView().GetSdrPageView()->MarkSnap()); 448 const basegfx::B2DRange aNewRectangle(aR.Left(), aR.Top(), aR.Right(), aR.Bottom()); 449 basegfx::B2DPolygon aNewPolygon(basegfx::tools::createPolygonFromRect(aNewRectangle)); 450 451 aResult = basegfx::B2DPolyPolygon(basegfx::tools::expandToCurve(aNewPolygon)); 452 } 453 454 if(aResult.count()) 455 { 456 addSdrDragEntry(new SdrDragEntryPolyPolygon(aResult)); 457 } 458 } 459 460 void SdrDragMethod::createSdrDragEntries_PointDrag() 461 { 462 const sal_uInt32 nMarkAnz(getSdrDragView().GetMarkedObjectCount()); 463 std::vector< basegfx::B2DPoint > aPositions; 464 465 for(sal_uInt32 nm(0); nm < nMarkAnz; nm++) 466 { 467 SdrMark* pM = getSdrDragView().GetSdrMarkByIndex(nm); 468 469 if(pM->GetPageView() == getSdrDragView().GetSdrPageView()) 470 { 471 const SdrUShortCont* pPts = pM->GetMarkedPoints(); 472 473 if(pPts && pPts->GetCount()) 474 { 475 const SdrObject* pObj = pM->GetMarkedSdrObj(); 476 const SdrPathObj* pPath = dynamic_cast< const SdrPathObj* >(pObj); 477 478 if(pPath) 479 { 480 const basegfx::B2DPolyPolygon aPathXPP = pPath->GetPathPoly(); 481 482 if(aPathXPP.count()) 483 { 484 const sal_uInt32 nPtAnz(pPts->GetCount()); 485 486 for(sal_uInt32 nPtNum(0); nPtNum < nPtAnz; nPtNum++) 487 { 488 sal_uInt32 nPolyNum, nPointNum; 489 const sal_uInt16 nObjPt(pPts->GetObject(nPtNum)); 490 491 if(sdr::PolyPolygonEditor::GetRelativePolyPoint(aPathXPP, nObjPt, nPolyNum, nPointNum)) 492 { 493 aPositions.push_back(aPathXPP.getB2DPolygon(nPolyNum).getB2DPoint(nPointNum)); 494 } 495 } 496 } 497 } 498 } 499 } 500 } 501 502 if(!aPositions.empty()) 503 { 504 addSdrDragEntry(new SdrDragEntryPointGlueDrag(aPositions, true)); 505 } 506 } 507 508 void SdrDragMethod::createSdrDragEntries_GlueDrag() 509 { 510 const sal_uInt32 nMarkAnz(getSdrDragView().GetMarkedObjectCount()); 511 std::vector< basegfx::B2DPoint > aPositions; 512 513 for(sal_uInt32 nm(0); nm < nMarkAnz; nm++) 514 { 515 SdrMark* pM = getSdrDragView().GetSdrMarkByIndex(nm); 516 517 if(pM->GetPageView() == getSdrDragView().GetSdrPageView()) 518 { 519 const SdrUShortCont* pPts = pM->GetMarkedGluePoints(); 520 521 if(pPts && pPts->GetCount()) 522 { 523 const SdrObject* pObj = pM->GetMarkedSdrObj(); 524 const SdrGluePointList* pGPL = pObj->GetGluePointList(); 525 526 if(pGPL) 527 { 528 const sal_uInt32 nPtAnz(pPts->GetCount()); 529 530 for(sal_uInt32 nPtNum(0); nPtNum < nPtAnz; nPtNum++) 531 { 532 const sal_uInt16 nObjPt(pPts->GetObject(nPtNum)); 533 const sal_uInt16 nGlueNum(pGPL->FindGluePoint(nObjPt)); 534 535 if(SDRGLUEPOINT_NOTFOUND != nGlueNum) 536 { 537 const Point aPoint((*pGPL)[nGlueNum].GetAbsolutePos(*pObj)); 538 aPositions.push_back(basegfx::B2DPoint(aPoint.X(), aPoint.Y())); 539 } 540 } 541 } 542 } 543 } 544 } 545 546 if(!aPositions.empty()) 547 { 548 addSdrDragEntry(new SdrDragEntryPointGlueDrag(aPositions, false)); 549 } 550 } 551 552 void SdrDragMethod::ImpTakeDescriptionStr(sal_uInt16 nStrCacheID, XubString& rStr, sal_uInt16 nVal) const 553 { 554 sal_uInt16 nOpt=0; 555 if (IsDraggingPoints()) { 556 nOpt=IMPSDR_POINTSDESCRIPTION; 557 } else if (IsDraggingGluePoints()) { 558 nOpt=IMPSDR_GLUEPOINTSDESCRIPTION; 559 } 560 getSdrDragView().ImpTakeDescriptionStr(nStrCacheID,rStr,nVal,nOpt); 561 } 562 563 SdrObject* SdrDragMethod::GetDragObj() const 564 { 565 SdrObject* pObj=NULL; 566 if (getSdrDragView().pDragHdl!=NULL) pObj=getSdrDragView().pDragHdl->GetObj(); 567 if (pObj==NULL) pObj=getSdrDragView().pMarkedObj; 568 return pObj; 569 } 570 571 SdrPageView* SdrDragMethod::GetDragPV() const 572 { 573 SdrPageView* pPV=NULL; 574 if (getSdrDragView().pDragHdl!=NULL) pPV=getSdrDragView().pDragHdl->GetPageView(); 575 if (pPV==NULL) pPV=getSdrDragView().pMarkedPV; 576 return pPV; 577 } 578 579 void SdrDragMethod::applyCurrentTransformationToSdrObject(SdrObject& rTarget) 580 { 581 // the original applies the transformation using TRGetBaseGeometry/TRSetBaseGeometry. 582 // Later this should be the only needed one for linear transforms (not for SdrDragCrook and 583 // SdrDragDistort, those are NOT linear). Currently, this can not yet be used since the 584 // special handling of rotate/mirror due to the not-being-able to handle it in the old 585 // drawinglayer stuff. Text would currently not correctly be mirrored in the preview. 586 basegfx::B2DHomMatrix aObjectTransform; 587 basegfx::B2DPolyPolygon aObjectPolyPolygon; 588 bool bPolyUsed(rTarget.TRGetBaseGeometry(aObjectTransform, aObjectPolyPolygon)); 589 590 // apply transform to object transform 591 aObjectTransform *= getCurrentTransformation(); 592 593 if(bPolyUsed) 594 { 595 // do something special since the object size is in the polygon 596 // break up matrix to get the scale 597 basegfx::B2DTuple aScale; 598 basegfx::B2DTuple aTranslate; 599 double fRotate, fShearX; 600 aObjectTransform.decompose(aScale, aTranslate, fRotate, fShearX); 601 602 // get polygon's pos and size 603 const basegfx::B2DRange aPolyRange(aObjectPolyPolygon.getB2DRange()); 604 605 // get the scaling factors (do not mirror, this is in the object transformation) 606 const double fScaleX(fabs(aScale.getX()) / (basegfx::fTools::equalZero(aPolyRange.getWidth()) ? 1.0 : aPolyRange.getWidth())); 607 const double fScaleY(fabs(aScale.getY()) / (basegfx::fTools::equalZero(aPolyRange.getHeight()) ? 1.0 : aPolyRange.getHeight())); 608 609 // prepare transform matrix for polygon 610 basegfx::B2DHomMatrix aPolyTransform(basegfx::tools::createTranslateB2DHomMatrix( 611 -aPolyRange.getMinX(), -aPolyRange.getMinY())); 612 aPolyTransform.scale(fScaleX, fScaleY); 613 614 // normally the poly should be moved back, but the translation is in the object 615 // transformation and thus does not need to be done 616 // aPolyTransform.translate(-aPolyRange.getMinX(), -aPolyRange.getMinY()); 617 618 // transform the polygon 619 aObjectPolyPolygon.transform(aPolyTransform); 620 } 621 622 rTarget.TRSetBaseGeometry(getCurrentTransformation() * aObjectTransform, aObjectPolyPolygon); 623 } 624 625 void SdrDragMethod::applyCurrentTransformationToPolyPolygon(basegfx::B2DPolyPolygon& rTarget) 626 { 627 // original uses CurrentTransformation 628 rTarget.transform(getCurrentTransformation()); 629 } 630 631 SdrDragMethod::SdrDragMethod(SdrDragView& rNewView) 632 : maSdrDragEntries(), 633 maOverlayObjectList(), 634 mrSdrDragView(rNewView), 635 mbMoveOnly(false), 636 mbSolidDraggingActive(getSdrDragView().IsSolidDragging()) 637 { 638 if(mbSolidDraggingActive && Application::GetSettings().GetStyleSettings().GetHighContrastMode()) 639 { 640 // fallback to wireframe when high contrast is used 641 mbSolidDraggingActive = false; 642 } 643 } 644 645 SdrDragMethod::~SdrDragMethod() 646 { 647 clearSdrDragEntries(); 648 } 649 650 void SdrDragMethod::Show() 651 { 652 getSdrDragView().ShowDragObj(); 653 } 654 655 void SdrDragMethod::Hide() 656 { 657 getSdrDragView().HideDragObj(); 658 } 659 660 basegfx::B2DHomMatrix SdrDragMethod::getCurrentTransformation() 661 { 662 return basegfx::B2DHomMatrix(); 663 } 664 665 void SdrDragMethod::CancelSdrDrag() 666 { 667 Hide(); 668 } 669 670 void SdrDragMethod::CreateOverlayGeometry(sdr::overlay::OverlayManager& rOverlayManager) 671 { 672 // create SdrDragEntries on demand 673 if(maSdrDragEntries.empty()) 674 { 675 createSdrDragEntries(); 676 } 677 678 // if there are entries, derive OverlayObjects from the entries, including 679 // modification from current interactive state 680 if(!maSdrDragEntries.empty()) 681 { 682 drawinglayer::primitive2d::Primitive2DSequence aResult; 683 drawinglayer::primitive2d::Primitive2DSequence aResultTransparent; 684 685 for(sal_uInt32 a(0); a < maSdrDragEntries.size(); a++) 686 { 687 SdrDragEntry* pCandidate = maSdrDragEntries[a]; 688 689 if(pCandidate) 690 { 691 const drawinglayer::primitive2d::Primitive2DSequence aCandidateResult(pCandidate->createPrimitive2DSequenceInCurrentState(*this)); 692 693 if(aCandidateResult.hasElements()) 694 { 695 if(pCandidate->getAddToTransparent()) 696 { 697 drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(aResultTransparent, aCandidateResult); 698 } 699 else 700 { 701 drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(aResult, aCandidateResult); 702 } 703 } 704 } 705 } 706 707 if(DoAddConnectorOverlays()) 708 { 709 const drawinglayer::primitive2d::Primitive2DSequence aConnectorOverlays(AddConnectorOverlays()); 710 711 if(aConnectorOverlays.hasElements()) 712 { 713 // add connector overlays to transparent part 714 drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(aResultTransparent, aConnectorOverlays); 715 } 716 } 717 718 if(aResult.hasElements()) 719 { 720 sdr::overlay::OverlayObject* pNewOverlayObject = new sdr::overlay::OverlayPrimitive2DSequenceObject(aResult); 721 rOverlayManager.add(*pNewOverlayObject); 722 addToOverlayObjectList(*pNewOverlayObject); 723 } 724 725 if(aResultTransparent.hasElements()) 726 { 727 drawinglayer::primitive2d::Primitive2DReference aUnifiedTransparencePrimitive2D(new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(aResultTransparent, 0.5)); 728 aResultTransparent = drawinglayer::primitive2d::Primitive2DSequence(&aUnifiedTransparencePrimitive2D, 1); 729 730 sdr::overlay::OverlayObject* pNewOverlayObject = new sdr::overlay::OverlayPrimitive2DSequenceObject(aResultTransparent); 731 rOverlayManager.add(*pNewOverlayObject); 732 addToOverlayObjectList(*pNewOverlayObject); 733 } 734 } 735 736 // evtl add DragStripes (help lines cross the page when dragging) 737 if(getSdrDragView().IsDragStripes()) 738 { 739 Rectangle aActionRectangle; 740 getSdrDragView().TakeActionRect(aActionRectangle); 741 742 const basegfx::B2DPoint aTopLeft(aActionRectangle.Left(), aActionRectangle.Top()); 743 const basegfx::B2DPoint aBottomRight(aActionRectangle.Right(), aActionRectangle.Bottom()); 744 sdr::overlay::OverlayRollingRectangleStriped* pNew = new sdr::overlay::OverlayRollingRectangleStriped( 745 aTopLeft, aBottomRight, true, false); 746 747 rOverlayManager.add(*pNew); 748 addToOverlayObjectList(*pNew); 749 } 750 } 751 752 void SdrDragMethod::destroyOverlayGeometry() 753 { 754 clearOverlayObjectList(); 755 } 756 757 bool SdrDragMethod::DoAddConnectorOverlays() 758 { 759 // these conditions are translated from SdrDragView::ImpDrawEdgeXor 760 const SdrMarkList& rMarkedNodes = getSdrDragView().GetEdgesOfMarkedNodes(); 761 762 if(!rMarkedNodes.GetMarkCount()) 763 { 764 return false; 765 } 766 767 if(!getSdrDragView().IsRubberEdgeDragging() && !getSdrDragView().IsDetailedEdgeDragging()) 768 { 769 return false; 770 } 771 772 if(getSdrDragView().IsDraggingPoints() || getSdrDragView().IsDraggingGluePoints()) 773 { 774 return false; 775 } 776 777 if(!getMoveOnly() && !( 778 IS_TYPE(SdrDragMove, this) || IS_TYPE(SdrDragResize, this) || 779 IS_TYPE(SdrDragRotate,this) || IS_TYPE(SdrDragMirror,this))) 780 { 781 return false; 782 } 783 784 const bool bDetail(getSdrDragView().IsDetailedEdgeDragging() && getMoveOnly()); 785 786 if(!bDetail && !getSdrDragView().IsRubberEdgeDragging()) 787 { 788 return false; 789 } 790 791 // one more migrated from SdrEdgeObj::NspToggleEdgeXor 792 if(IS_TYPE(SdrDragObjOwn, this) || IS_TYPE(SdrDragMovHdl, this)) 793 { 794 return false; 795 } 796 797 return true; 798 } 799 800 drawinglayer::primitive2d::Primitive2DSequence SdrDragMethod::AddConnectorOverlays() 801 { 802 drawinglayer::primitive2d::Primitive2DSequence aRetval; 803 const bool bDetail(getSdrDragView().IsDetailedEdgeDragging() && getMoveOnly()); 804 const SdrMarkList& rMarkedNodes = getSdrDragView().GetEdgesOfMarkedNodes(); 805 806 for(sal_uInt16 a(0); a < rMarkedNodes.GetMarkCount(); a++) 807 { 808 SdrMark* pEM = rMarkedNodes.GetMark(a); 809 810 if(pEM && pEM->GetMarkedSdrObj()) 811 { 812 SdrEdgeObj* pEdge = dynamic_cast< SdrEdgeObj* >(pEM->GetMarkedSdrObj()); 813 814 if(pEdge) 815 { 816 const basegfx::B2DPolygon aEdgePolygon(pEdge->ImplAddConnectorOverlay(*this, pEM->IsCon1(), pEM->IsCon2(), bDetail)); 817 818 if(aEdgePolygon.count()) 819 { 820 // this polygon is a temporary calculated connector path, so it is not possible to fetch 821 // the needed primitives directly from the pEdge object which does not get changed. If full 822 // drag is on, use the SdrObjects ItemSet to create a adequate representation 823 bool bUseSolidDragging(getSolidDraggingActive()); 824 825 if(bUseSolidDragging) 826 { 827 // switch off solid dragging if connector is not visible 828 if(!pEdge->HasLineStyle()) 829 { 830 bUseSolidDragging = false; 831 } 832 } 833 834 if(bUseSolidDragging) 835 { 836 const SfxItemSet& rItemSet = pEdge->GetMergedItemSet(); 837 const drawinglayer::attribute::SdrLineAttribute aLine( 838 drawinglayer::primitive2d::createNewSdrLineAttribute(rItemSet)); 839 840 if(!aLine.isDefault()) 841 { 842 const drawinglayer::attribute::SdrLineStartEndAttribute aLineStartEnd( 843 drawinglayer::primitive2d::createNewSdrLineStartEndAttribute( 844 rItemSet, 845 aLine.getWidth())); 846 847 drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence( 848 aRetval, drawinglayer::primitive2d::createPolygonLinePrimitive( 849 aEdgePolygon, 850 basegfx::B2DHomMatrix(), 851 aLine, 852 aLineStartEnd)); 853 } 854 } 855 else 856 { 857 const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer; 858 basegfx::BColor aColA(aSvtOptionsDrawinglayer.GetStripeColorA().getBColor()); 859 basegfx::BColor aColB(aSvtOptionsDrawinglayer.GetStripeColorB().getBColor()); 860 const double fStripeLength(aSvtOptionsDrawinglayer.GetStripeLength()); 861 862 if(Application::GetSettings().GetStyleSettings().GetHighContrastMode()) 863 { 864 aColA = aColB = Application::GetSettings().GetStyleSettings().GetHighlightColor().getBColor(); 865 aColB.invert(); 866 } 867 868 drawinglayer::primitive2d::Primitive2DReference aPolyPolygonMarkerPrimitive2D( 869 new drawinglayer::primitive2d::PolyPolygonMarkerPrimitive2D( 870 basegfx::B2DPolyPolygon(aEdgePolygon), aColA, aColB, fStripeLength)); 871 drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, aPolyPolygonMarkerPrimitive2D); 872 } 873 } 874 } 875 } 876 } 877 878 return aRetval; 879 } 880 881 //////////////////////////////////////////////////////////////////////////////////////////////////// 882 883 TYPEINIT1(SdrDragMovHdl,SdrDragMethod); 884 885 SdrDragMovHdl::SdrDragMovHdl(SdrDragView& rNewView) 886 : SdrDragMethod(rNewView), 887 bMirrObjShown(false) 888 { 889 } 890 891 void SdrDragMovHdl::createSdrDragEntries() 892 { 893 // SdrDragMovHdl does not use the default drags, 894 // but creates nothing 895 } 896 897 void SdrDragMovHdl::TakeSdrDragComment(XubString& rStr) const 898 { 899 rStr=ImpGetResStr(STR_DragMethMovHdl); 900 if (getSdrDragView().IsDragWithCopy()) rStr+=ImpGetResStr(STR_EditWithCopy); 901 } 902 903 bool SdrDragMovHdl::BeginSdrDrag() 904 { 905 if( !GetDragHdl() ) 906 return false; 907 908 DragStat().Ref1()=GetDragHdl()->GetPos(); 909 DragStat().SetShown(!DragStat().IsShown()); 910 SdrHdlKind eKind=GetDragHdl()->GetKind(); 911 SdrHdl* pH1=GetHdlList().GetHdl(HDL_REF1); 912 SdrHdl* pH2=GetHdlList().GetHdl(HDL_REF2); 913 914 if (eKind==HDL_MIRX) 915 { 916 if (pH1==NULL || pH2==NULL) 917 { 918 DBG_ERROR("SdrDragMovHdl::BeginSdrDrag(): Verschieben der Spiegelachse: Referenzhandles nicht gefunden"); 919 return false; 920 } 921 922 DragStat().SetActionRect(Rectangle(pH1->GetPos(),pH2->GetPos())); 923 } 924 else 925 { 926 Point aPt(GetDragHdl()->GetPos()); 927 DragStat().SetActionRect(Rectangle(aPt,aPt)); 928 } 929 930 return true; 931 } 932 933 void SdrDragMovHdl::MoveSdrDrag(const Point& rNoSnapPnt) 934 { 935 Point aPnt(rNoSnapPnt); 936 937 if ( GetDragHdl() && DragStat().CheckMinMoved(rNoSnapPnt)) 938 { 939 if (GetDragHdl()->GetKind()==HDL_MIRX) 940 { 941 SdrHdl* pH1=GetHdlList().GetHdl(HDL_REF1); 942 SdrHdl* pH2=GetHdlList().GetHdl(HDL_REF2); 943 944 if (pH1==NULL || pH2==NULL) 945 return; 946 947 if (!DragStat().IsNoSnap()) 948 { 949 long nBestXSnap=0; 950 long nBestYSnap=0; 951 bool bXSnapped=false; 952 bool bYSnapped=false; 953 Point aDif(aPnt-DragStat().GetStart()); 954 getSdrDragView().CheckSnap(Ref1()+aDif,NULL,nBestXSnap,nBestYSnap,bXSnapped,bYSnapped); 955 getSdrDragView().CheckSnap(Ref2()+aDif,NULL,nBestXSnap,nBestYSnap,bXSnapped,bYSnapped); 956 aPnt.X()+=nBestXSnap; 957 aPnt.Y()+=nBestYSnap; 958 } 959 960 if (aPnt!=DragStat().GetNow()) 961 { 962 Hide(); 963 DragStat().NextMove(aPnt); 964 Point aDif(DragStat().GetNow()-DragStat().GetStart()); 965 pH1->SetPos(Ref1()+aDif); 966 pH2->SetPos(Ref2()+aDif); 967 968 SdrHdl* pHM = GetHdlList().GetHdl(HDL_MIRX); 969 970 if(pHM) 971 pHM->Touch(); 972 973 Show(); 974 DragStat().SetActionRect(Rectangle(pH1->GetPos(),pH2->GetPos())); 975 } 976 } 977 else 978 { 979 if (!DragStat().IsNoSnap()) SnapPos(aPnt); 980 long nSA=0; 981 982 if (getSdrDragView().IsAngleSnapEnabled()) 983 nSA=getSdrDragView().GetSnapAngle(); 984 985 if (getSdrDragView().IsMirrorAllowed(true,true)) 986 { // eingeschraenkt 987 if (!getSdrDragView().IsMirrorAllowed(false,false)) nSA=4500; 988 if (!getSdrDragView().IsMirrorAllowed(true,false)) nSA=9000; 989 } 990 991 if (getSdrDragView().IsOrtho() && nSA!=9000) 992 nSA=4500; 993 994 if (nSA!=0) 995 { // Winkelfang 996 SdrHdlKind eRef=HDL_REF1; 997 998 if (GetDragHdl()->GetKind()==HDL_REF1) 999 eRef=HDL_REF2; 1000 1001 SdrHdl* pH=GetHdlList().GetHdl(eRef); 1002 1003 if (pH!=NULL) 1004 { 1005 Point aRef(pH->GetPos()); 1006 long nWink=NormAngle360(GetAngle(aPnt-aRef)); 1007 long nNeuWink=nWink; 1008 nNeuWink+=nSA/2; 1009 nNeuWink/=nSA; 1010 nNeuWink*=nSA; 1011 nNeuWink=NormAngle360(nNeuWink); 1012 double a=(nNeuWink-nWink)*nPi180; 1013 double nSin=sin(a); 1014 double nCos=cos(a); 1015 RotatePoint(aPnt,aRef,nSin,nCos); 1016 1017 // Bei bestimmten Werten Rundungsfehler ausschliessen: 1018 if (nSA==9000) 1019 { 1020 if (nNeuWink==0 || nNeuWink==18000) aPnt.Y()=aRef.Y(); 1021 if (nNeuWink==9000 || nNeuWink==27000) aPnt.X()=aRef.X(); 1022 } 1023 1024 if (nSA==4500) 1025 OrthoDistance8(aRef,aPnt,true); 1026 } 1027 } 1028 1029 if (aPnt!=DragStat().GetNow()) 1030 { 1031 Hide(); 1032 DragStat().NextMove(aPnt); 1033 GetDragHdl()->SetPos(DragStat().GetNow()); 1034 SdrHdl* pHM = GetHdlList().GetHdl(HDL_MIRX); 1035 1036 if(pHM) 1037 pHM->Touch(); 1038 1039 Show(); 1040 DragStat().SetActionRect(Rectangle(aPnt,aPnt)); 1041 } 1042 } 1043 } 1044 } 1045 1046 bool SdrDragMovHdl::EndSdrDrag(bool /*bCopy*/) 1047 { 1048 if( GetDragHdl() ) 1049 { 1050 switch (GetDragHdl()->GetKind()) 1051 { 1052 case HDL_REF1: 1053 Ref1()=DragStat().GetNow(); 1054 break; 1055 1056 case HDL_REF2: 1057 Ref2()=DragStat().GetNow(); 1058 break; 1059 1060 case HDL_MIRX: 1061 Ref1()+=DragStat().GetNow()-DragStat().GetStart(); 1062 Ref2()+=DragStat().GetNow()-DragStat().GetStart(); 1063 break; 1064 1065 default: break; 1066 } 1067 } 1068 1069 return true; 1070 } 1071 1072 void SdrDragMovHdl::CancelSdrDrag() 1073 { 1074 Hide(); 1075 1076 SdrHdl* pHdl = GetDragHdl(); 1077 if( pHdl ) 1078 pHdl->SetPos(DragStat().GetRef1()); 1079 1080 SdrHdl* pHM = GetHdlList().GetHdl(HDL_MIRX); 1081 1082 if(pHM) 1083 pHM->Touch(); 1084 } 1085 1086 Pointer SdrDragMovHdl::GetSdrDragPointer() const 1087 { 1088 const SdrHdl* pHdl = GetDragHdl(); 1089 1090 if (pHdl!=NULL) 1091 { 1092 return pHdl->GetPointer(); 1093 } 1094 1095 return Pointer(POINTER_REFHAND); 1096 } 1097 1098 //////////////////////////////////////////////////////////////////////////////////////////////////// 1099 1100 TYPEINIT1(SdrDragObjOwn,SdrDragMethod); 1101 1102 SdrDragObjOwn::SdrDragObjOwn(SdrDragView& rNewView) 1103 : SdrDragMethod(rNewView), 1104 mpClone(0) 1105 { 1106 const SdrObject* pObj = GetDragObj(); 1107 1108 if(pObj) 1109 { 1110 // suppress full drag for some object types 1111 setSolidDraggingActive(pObj->supportsFullDrag()); 1112 } 1113 } 1114 1115 SdrDragObjOwn::~SdrDragObjOwn() 1116 { 1117 if(mpClone) 1118 { 1119 SdrObject::Free(mpClone); 1120 } 1121 } 1122 1123 void SdrDragObjOwn::createSdrDragEntries() 1124 { 1125 if(mpClone) 1126 { 1127 basegfx::B2DPolyPolygon aDragPolyPolygon; 1128 bool bAddWireframe(true); 1129 1130 if(getSolidDraggingActive()) 1131 { 1132 SdrPageView* pPV = getSdrDragView().GetSdrPageView(); 1133 1134 if(pPV && pPV->PageWindowCount()) 1135 { 1136 sdr::contact::ObjectContact& rOC = pPV->GetPageWindow(0)->GetObjectContact(); 1137 addSdrDragEntry(new SdrDragEntrySdrObject(*mpClone, rOC, false)); 1138 1139 // potentially no wireframe needed, full drag works 1140 bAddWireframe = false; 1141 } 1142 } 1143 1144 if(!bAddWireframe) 1145 { 1146 // check for extra conditions for wireframe, e.g. no border at 1147 // objects 1148 if(!mpClone->HasLineStyle()) 1149 { 1150 bAddWireframe = true; 1151 } 1152 } 1153 1154 if(bAddWireframe) 1155 { 1156 // use wireframe poly when full drag is off or did not work 1157 aDragPolyPolygon = mpClone->TakeXorPoly(); 1158 } 1159 1160 // add evtl. extra DragPolyPolygon 1161 const basegfx::B2DPolyPolygon aSpecialDragPolyPolygon(mpClone->getSpecialDragPoly(DragStat())); 1162 1163 if(aSpecialDragPolyPolygon.count()) 1164 { 1165 aDragPolyPolygon.append(aSpecialDragPolyPolygon); 1166 } 1167 1168 if(aDragPolyPolygon.count()) 1169 { 1170 addSdrDragEntry(new SdrDragEntryPolyPolygon(aDragPolyPolygon)); 1171 } 1172 } 1173 } 1174 1175 void SdrDragObjOwn::TakeSdrDragComment(XubString& rStr) const 1176 { 1177 // #i103058# get info string from the clone preferred, the original will 1178 // not be changed. For security, use original as fallback 1179 if(mpClone) 1180 { 1181 rStr = mpClone->getSpecialDragComment(DragStat()); 1182 } 1183 else 1184 { 1185 const SdrObject* pObj = GetDragObj(); 1186 1187 if(pObj) 1188 { 1189 rStr = pObj->getSpecialDragComment(DragStat()); 1190 } 1191 } 1192 } 1193 1194 bool SdrDragObjOwn::BeginSdrDrag() 1195 { 1196 if(!mpClone) 1197 { 1198 const SdrObject* pObj = GetDragObj(); 1199 1200 if(pObj && !pObj->IsResizeProtect()) 1201 { 1202 if(pObj->beginSpecialDrag(DragStat())) 1203 { 1204 // create nitial clone to have a start visualisation 1205 mpClone = pObj->getFullDragClone(); 1206 mpClone->applySpecialDrag(DragStat()); 1207 1208 return true; 1209 } 1210 } 1211 } 1212 1213 return false; 1214 } 1215 1216 void SdrDragObjOwn::MoveSdrDrag(const Point& rNoSnapPnt) 1217 { 1218 const SdrObject* pObj = GetDragObj(); 1219 1220 if(pObj) 1221 { 1222 Point aPnt(rNoSnapPnt); 1223 SdrPageView* pPV = GetDragPV(); 1224 1225 if(pPV) 1226 { 1227 if(!DragStat().IsNoSnap()) 1228 { 1229 SnapPos(aPnt); 1230 } 1231 1232 if(getSdrDragView().IsOrtho()) 1233 { 1234 if (DragStat().IsOrtho8Possible()) 1235 { 1236 OrthoDistance8(DragStat().GetStart(),aPnt,getSdrDragView().IsBigOrtho()); 1237 } 1238 else if (DragStat().IsOrtho4Possible()) 1239 { 1240 OrthoDistance4(DragStat().GetStart(),aPnt,getSdrDragView().IsBigOrtho()); 1241 } 1242 } 1243 1244 if(DragStat().CheckMinMoved(rNoSnapPnt)) 1245 { 1246 if(aPnt != DragStat().GetNow()) 1247 { 1248 Hide(); 1249 DragStat().NextMove(aPnt); 1250 1251 // since SdrDragObjOwn currently supports no transformation of 1252 // existing SdrDragEntries but only their recreation, a recreation 1253 // after every move is needed in this mode. Delete existing 1254 // SdrDragEntries here to force their recreation in the following Show(). 1255 clearSdrDragEntries(); 1256 1257 // delete current clone (after the last reference to it is deleted above) 1258 if(mpClone) 1259 { 1260 SdrObject::Free(mpClone); 1261 mpClone = 0; 1262 } 1263 1264 // create a new clone and modify to current drag state 1265 if(!mpClone) 1266 { 1267 mpClone = pObj->getFullDragClone(); 1268 mpClone->applySpecialDrag(DragStat()); 1269 } 1270 1271 Show(); 1272 } 1273 } 1274 } 1275 } 1276 } 1277 1278 bool SdrDragObjOwn::EndSdrDrag(bool /*bCopy*/) 1279 { 1280 Hide(); 1281 SdrUndoAction* pUndo = NULL; 1282 SdrUndoAction* pUndo2 = NULL; 1283 std::vector< SdrUndoAction* > vConnectorUndoActions; 1284 bool bRet = false; 1285 SdrObject* pObj = GetDragObj(); 1286 1287 if(pObj) 1288 { 1289 const bool bUndo = getSdrDragView().IsUndoEnabled(); 1290 1291 if( bUndo ) 1292 { 1293 if(!getSdrDragView().IsInsObjPoint() && pObj->IsInserted() ) 1294 { 1295 if (DragStat().IsEndDragChangesAttributes()) 1296 { 1297 pUndo=getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pObj); 1298 1299 if (DragStat().IsEndDragChangesGeoAndAttributes()) 1300 { 1301 vConnectorUndoActions = getSdrDragView().CreateConnectorUndo( *pObj ); 1302 pUndo2 = getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj); 1303 } 1304 } 1305 else 1306 { 1307 vConnectorUndoActions = getSdrDragView().CreateConnectorUndo( *pObj ); 1308 pUndo= getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj); 1309 } 1310 } 1311 1312 if( pUndo ) 1313 { 1314 getSdrDragView().BegUndo( pUndo->GetComment() ); 1315 } 1316 else 1317 { 1318 getSdrDragView().BegUndo(); 1319 } 1320 } 1321 1322 // evtl. use opertator= for setting changed object data (do not change selection in 1323 // view, this will destroy the interactor). This is possible since a clone is now 1324 // directly modified by the modifiers. Only SdrTableObj is adding own UNDOs 1325 // in it's SdrTableObj::endSpecialDrag, so currently not possible. OTOH it uses 1326 // a CreateUndoGeoObject() so maybe setting SetEndDragChangesAttributes is okay. I 1327 // will test this now 1328 Rectangle aBoundRect0; 1329 1330 if(pObj->GetUserCall()) 1331 { 1332 aBoundRect0 = pObj->GetLastBoundRect(); 1333 } 1334 1335 bRet = pObj->applySpecialDrag(DragStat()); 1336 1337 if(bRet) 1338 { 1339 pObj->SetChanged(); 1340 pObj->BroadcastObjectChange(); 1341 pObj->SendUserCall( SDRUSERCALL_RESIZE, aBoundRect0 ); 1342 } 1343 1344 if(bRet) 1345 { 1346 if( bUndo ) 1347 { 1348 getSdrDragView().AddUndoActions( vConnectorUndoActions ); 1349 1350 if ( pUndo ) 1351 { 1352 getSdrDragView().AddUndo(pUndo); 1353 } 1354 1355 if ( pUndo2 ) 1356 { 1357 getSdrDragView().AddUndo(pUndo2); 1358 } 1359 } 1360 } 1361 else 1362 { 1363 if( bUndo ) 1364 { 1365 std::vector< SdrUndoAction* >::iterator vConnectorUndoIter( vConnectorUndoActions.begin() ); 1366 1367 while( vConnectorUndoIter != vConnectorUndoActions.end() ) 1368 { 1369 delete *vConnectorUndoIter++; 1370 } 1371 1372 delete pUndo; 1373 delete pUndo2; 1374 } 1375 } 1376 1377 if( bUndo ) 1378 getSdrDragView().EndUndo(); 1379 } 1380 1381 return bRet; 1382 } 1383 1384 Pointer SdrDragObjOwn::GetSdrDragPointer() const 1385 { 1386 const SdrHdl* pHdl=GetDragHdl(); 1387 1388 if (pHdl) 1389 { 1390 return pHdl->GetPointer(); 1391 } 1392 1393 return Pointer(POINTER_MOVE); 1394 } 1395 1396 //////////////////////////////////////////////////////////////////////////////////////////////////// 1397 1398 TYPEINIT1(SdrDragMove,SdrDragMethod); 1399 1400 void SdrDragMove::createSdrDragEntryForSdrObject(const SdrObject& rOriginal, sdr::contact::ObjectContact& rObjectContact, bool /*bModify*/) 1401 { 1402 // for SdrDragMove, use current Primitive2DSequence of SdrObject visualisation 1403 // in given ObjectContact directly 1404 sdr::contact::ViewContact& rVC = rOriginal.GetViewContact(); 1405 sdr::contact::ViewObjectContact& rVOC = rVC.GetViewObjectContact(rObjectContact); 1406 sdr::contact::DisplayInfo aDisplayInfo; 1407 1408 // Do not use the last ViewPort set at the OC from the last ProcessDisplay(), 1409 // here we want the complete primitive sequence without visibility clippings 1410 rObjectContact.resetViewPort(); 1411 1412 addSdrDragEntry(new SdrDragEntryPrimitive2DSequence(rVOC.getPrimitive2DSequenceHierarchy(aDisplayInfo), true)); 1413 } 1414 1415 void SdrDragMove::applyCurrentTransformationToSdrObject(SdrObject& rTarget) 1416 { 1417 rTarget.Move(Size(DragStat().GetDX(), DragStat().GetDY())); 1418 } 1419 1420 SdrDragMove::SdrDragMove(SdrDragView& rNewView) 1421 : SdrDragMethod(rNewView) 1422 { 1423 setMoveOnly(true); 1424 } 1425 1426 void SdrDragMove::TakeSdrDragComment(XubString& rStr) const 1427 { 1428 XubString aStr; 1429 1430 ImpTakeDescriptionStr(STR_DragMethMove, rStr); 1431 rStr.AppendAscii(" (x="); 1432 getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDX(), aStr); 1433 rStr += aStr; 1434 rStr.AppendAscii(" y="); 1435 getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDY(), aStr); 1436 rStr += aStr; 1437 rStr += sal_Unicode(')'); 1438 1439 if(getSdrDragView().IsDragWithCopy()) 1440 { 1441 if(!getSdrDragView().IsInsObjPoint() && !getSdrDragView().IsInsGluePoint()) 1442 { 1443 rStr += ImpGetResStr(STR_EditWithCopy); 1444 } 1445 } 1446 } 1447 1448 bool SdrDragMove::BeginSdrDrag() 1449 { 1450 DragStat().SetActionRect(GetMarkedRect()); 1451 Show(); 1452 1453 return true; 1454 } 1455 1456 basegfx::B2DHomMatrix SdrDragMove::getCurrentTransformation() 1457 { 1458 return basegfx::tools::createTranslateB2DHomMatrix(DragStat().GetDX(), DragStat().GetDY()); 1459 } 1460 1461 void SdrDragMove::ImpCheckSnap(const Point& rPt) 1462 { 1463 Point aPt(rPt); 1464 sal_uInt16 nRet=SnapPos(aPt); 1465 aPt-=rPt; 1466 1467 if ((nRet & SDRSNAP_XSNAPPED) !=0) 1468 { 1469 if (bXSnapped) 1470 { 1471 if (Abs(aPt.X())<Abs(nBestXSnap)) 1472 { 1473 nBestXSnap=aPt.X(); 1474 } 1475 } 1476 else 1477 { 1478 nBestXSnap=aPt.X(); 1479 bXSnapped=true; 1480 } 1481 } 1482 1483 if ((nRet & SDRSNAP_YSNAPPED) !=0) 1484 { 1485 if (bYSnapped) 1486 { 1487 if (Abs(aPt.Y())<Abs(nBestYSnap)) 1488 { 1489 nBestYSnap=aPt.Y(); 1490 } 1491 } 1492 else 1493 { 1494 nBestYSnap=aPt.Y(); 1495 bYSnapped=true; 1496 } 1497 } 1498 } 1499 1500 void SdrDragMove::MoveSdrDrag(const Point& rNoSnapPnt_) 1501 { 1502 nBestXSnap=0; 1503 nBestYSnap=0; 1504 bXSnapped=false; 1505 bYSnapped=false; 1506 Point aNoSnapPnt(rNoSnapPnt_); 1507 const Rectangle& aSR=GetMarkedRect(); 1508 long nMovedx=aNoSnapPnt.X()-DragStat().GetStart().X(); 1509 long nMovedy=aNoSnapPnt.Y()-DragStat().GetStart().Y(); 1510 Point aLO(aSR.TopLeft()); aLO.X()+=nMovedx; aLO.Y()+=nMovedy; 1511 Point aRU(aSR.BottomRight()); aRU.X()+=nMovedx; aRU.Y()+=nMovedy; 1512 Point aLU(aLO.X(),aRU.Y()); 1513 Point aRO(aRU.X(),aLO.Y()); 1514 ImpCheckSnap(aLO); 1515 1516 if (!getSdrDragView().IsMoveSnapOnlyTopLeft()) 1517 { 1518 ImpCheckSnap(aRO); 1519 ImpCheckSnap(aLU); 1520 ImpCheckSnap(aRU); 1521 } 1522 1523 Point aPnt(aNoSnapPnt.X()+nBestXSnap,aNoSnapPnt.Y()+nBestYSnap); 1524 bool bOrtho=getSdrDragView().IsOrtho(); 1525 1526 if (bOrtho) 1527 OrthoDistance8(DragStat().GetStart(),aPnt,getSdrDragView().IsBigOrtho()); 1528 1529 if (DragStat().CheckMinMoved(aNoSnapPnt)) 1530 { 1531 Point aPt1(aPnt); 1532 Rectangle aLR(getSdrDragView().GetWorkArea()); 1533 bool bWorkArea=!aLR.IsEmpty(); 1534 bool bDragLimit=IsDragLimit(); 1535 1536 if (bDragLimit || bWorkArea) 1537 { 1538 Rectangle aSR2(GetMarkedRect()); 1539 Point aD(aPt1-DragStat().GetStart()); 1540 1541 if (bDragLimit) 1542 { 1543 Rectangle aR2(GetDragLimitRect()); 1544 1545 if (bWorkArea) 1546 aLR.Intersection(aR2); 1547 else 1548 aLR=aR2; 1549 } 1550 1551 if (aSR2.Left()>aLR.Left() || aSR2.Right()<aLR.Right()) 1552 { // ist ueberhaupt Platz zum verschieben? 1553 aSR2.Move(aD.X(),0); 1554 1555 if (aSR2.Left()<aLR.Left()) 1556 { 1557 aPt1.X()-=aSR2.Left()-aLR.Left(); 1558 } 1559 else if (aSR2.Right()>aLR.Right()) 1560 { 1561 aPt1.X()-=aSR2.Right()-aLR.Right(); 1562 } 1563 } 1564 else 1565 aPt1.X()=DragStat().GetStart().X(); // kein Platz zum verschieben 1566 1567 if (aSR2.Top()>aLR.Top() || aSR2.Bottom()<aLR.Bottom()) 1568 { // ist ueberhaupt Platz zum verschieben? 1569 aSR2.Move(0,aD.Y()); 1570 1571 if (aSR2.Top()<aLR.Top()) 1572 { 1573 aPt1.Y()-=aSR2.Top()-aLR.Top(); 1574 } 1575 else if (aSR2.Bottom()>aLR.Bottom()) 1576 { 1577 aPt1.Y()-=aSR2.Bottom()-aLR.Bottom(); 1578 } 1579 } 1580 else 1581 aPt1.Y()=DragStat().GetStart().Y(); // kein Platz zum verschieben 1582 } 1583 1584 if (getSdrDragView().IsDraggingGluePoints()) 1585 { // Klebepunkte aufs BoundRect des Obj limitieren 1586 aPt1-=DragStat().GetStart(); 1587 const SdrMarkList& rML=GetMarkedObjectList(); 1588 sal_uLong nMarkAnz=rML.GetMarkCount(); 1589 1590 for (sal_uLong nMarkNum=0; nMarkNum<nMarkAnz; nMarkNum++) 1591 { 1592 const SdrMark* pM=rML.GetMark(nMarkNum); 1593 const SdrUShortCont* pPts=pM->GetMarkedGluePoints(); 1594 sal_uLong nPtAnz=pPts==NULL ? 0 : pPts->GetCount(); 1595 1596 if (nPtAnz!=0) 1597 { 1598 const SdrObject* pObj=pM->GetMarkedSdrObj(); 1599 const SdrGluePointList* pGPL=pObj->GetGluePointList(); 1600 Rectangle aBound(pObj->GetCurrentBoundRect()); 1601 1602 for (sal_uLong nPtNum=0; nPtNum<nPtAnz; nPtNum++) 1603 { 1604 sal_uInt16 nId=pPts->GetObject(nPtNum); 1605 sal_uInt16 nGlueNum=pGPL->FindGluePoint(nId); 1606 1607 if (nGlueNum!=SDRGLUEPOINT_NOTFOUND) 1608 { 1609 Point aPt((*pGPL)[nGlueNum].GetAbsolutePos(*pObj)); 1610 aPt+=aPt1; // soviel soll verschoben werden 1611 if (aPt.X()<aBound.Left() ) aPt1.X()-=aPt.X()-aBound.Left() ; 1612 if (aPt.X()>aBound.Right() ) aPt1.X()-=aPt.X()-aBound.Right() ; 1613 if (aPt.Y()<aBound.Top() ) aPt1.Y()-=aPt.Y()-aBound.Top() ; 1614 if (aPt.Y()>aBound.Bottom()) aPt1.Y()-=aPt.Y()-aBound.Bottom(); 1615 } 1616 } 1617 } 1618 } 1619 1620 aPt1+=DragStat().GetStart(); 1621 } 1622 1623 if (bOrtho) 1624 OrthoDistance8(DragStat().GetStart(),aPt1,false); 1625 1626 if (aPt1!=DragStat().GetNow()) 1627 { 1628 Hide(); 1629 DragStat().NextMove(aPt1); 1630 Rectangle aAction(GetMarkedRect()); 1631 aAction.Move(DragStat().GetDX(),DragStat().GetDY()); 1632 DragStat().SetActionRect(aAction); 1633 Show(); 1634 } 1635 } 1636 } 1637 1638 bool SdrDragMove::EndSdrDrag(bool bCopy) 1639 { 1640 Hide(); 1641 1642 if (getSdrDragView().IsInsObjPoint() || getSdrDragView().IsInsGluePoint()) 1643 bCopy=false; 1644 1645 if (IsDraggingPoints()) 1646 { 1647 getSdrDragView().MoveMarkedPoints(Size(DragStat().GetDX(),DragStat().GetDY()),bCopy); 1648 } 1649 else if (IsDraggingGluePoints()) 1650 { 1651 getSdrDragView().MoveMarkedGluePoints(Size(DragStat().GetDX(),DragStat().GetDY()),bCopy); 1652 } 1653 else 1654 { 1655 getSdrDragView().MoveMarkedObj(Size(DragStat().GetDX(),DragStat().GetDY()),bCopy); 1656 } 1657 1658 return true; 1659 } 1660 1661 Pointer SdrDragMove::GetSdrDragPointer() const 1662 { 1663 if (IsDraggingPoints() || IsDraggingGluePoints()) 1664 { 1665 return Pointer(POINTER_MOVEPOINT); 1666 } 1667 else 1668 { 1669 return Pointer(POINTER_MOVE); 1670 } 1671 } 1672 1673 //////////////////////////////////////////////////////////////////////////////////////////////////// 1674 1675 TYPEINIT1(SdrDragResize,SdrDragMethod); 1676 1677 SdrDragResize::SdrDragResize(SdrDragView& rNewView) 1678 : SdrDragMethod(rNewView), 1679 aXFact(1,1), 1680 aYFact(1,1) 1681 { 1682 } 1683 1684 void SdrDragResize::TakeSdrDragComment(XubString& rStr) const 1685 { 1686 ImpTakeDescriptionStr(STR_DragMethResize, rStr); 1687 bool bEqual(aXFact == aYFact); 1688 Fraction aFact1(1,1); 1689 Point aStart(DragStat().GetStart()); 1690 Point aRef(DragStat().GetRef1()); 1691 sal_Int32 nXDiv(aStart.X() - aRef.X()); 1692 1693 if(!nXDiv) 1694 nXDiv = 1; 1695 1696 sal_Int32 nYDiv(aStart.Y() - aRef.Y()); 1697 1698 if(!nYDiv) 1699 nYDiv = 1; 1700 1701 bool bX(aXFact != aFact1 && Abs(nXDiv) > 1); 1702 bool bY(aYFact != aFact1 && Abs(nYDiv) > 1); 1703 1704 if(bX || bY) 1705 { 1706 XubString aStr; 1707 1708 rStr.AppendAscii(" ("); 1709 1710 if(bX) 1711 { 1712 if(!bEqual) 1713 rStr.AppendAscii("x="); 1714 1715 getSdrDragView().GetModel()->TakePercentStr(aXFact, aStr); 1716 rStr += aStr; 1717 } 1718 1719 if(bY && !bEqual) 1720 { 1721 if(bX) 1722 rStr += sal_Unicode(' '); 1723 1724 rStr.AppendAscii("y="); 1725 getSdrDragView().GetModel()->TakePercentStr(aYFact, aStr); 1726 rStr += aStr; 1727 } 1728 1729 rStr += sal_Unicode(')'); 1730 } 1731 1732 if(getSdrDragView().IsDragWithCopy()) 1733 rStr += ImpGetResStr(STR_EditWithCopy); 1734 } 1735 1736 bool SdrDragResize::BeginSdrDrag() 1737 { 1738 SdrHdlKind eRefHdl=HDL_MOVE; 1739 SdrHdl* pRefHdl=NULL; 1740 1741 switch (GetDragHdlKind()) 1742 { 1743 case HDL_UPLFT: eRefHdl=HDL_LWRGT; break; 1744 case HDL_UPPER: eRefHdl=HDL_LOWER; DragStat().SetHorFixed(true); break; 1745 case HDL_UPRGT: eRefHdl=HDL_LWLFT; break; 1746 case HDL_LEFT : eRefHdl=HDL_RIGHT; DragStat().SetVerFixed(true); break; 1747 case HDL_RIGHT: eRefHdl=HDL_LEFT ; DragStat().SetVerFixed(true); break; 1748 case HDL_LWLFT: eRefHdl=HDL_UPRGT; break; 1749 case HDL_LOWER: eRefHdl=HDL_UPPER; DragStat().SetHorFixed(true); break; 1750 case HDL_LWRGT: eRefHdl=HDL_UPLFT; break; 1751 default: break; 1752 } 1753 1754 if (eRefHdl!=HDL_MOVE) 1755 pRefHdl=GetHdlList().GetHdl(eRefHdl); 1756 1757 if (pRefHdl!=NULL && !getSdrDragView().IsResizeAtCenter()) 1758 { 1759 DragStat().Ref1()=pRefHdl->GetPos(); 1760 } 1761 else 1762 { 1763 SdrHdl* pRef1=GetHdlList().GetHdl(HDL_UPLFT); 1764 SdrHdl* pRef2=GetHdlList().GetHdl(HDL_LWRGT); 1765 1766 if (pRef1!=NULL && pRef2!=NULL) 1767 { 1768 DragStat().Ref1()=Rectangle(pRef1->GetPos(),pRef2->GetPos()).Center(); 1769 } 1770 else 1771 { 1772 DragStat().Ref1()=GetMarkedRect().Center(); 1773 } 1774 } 1775 1776 Show(); 1777 1778 return true; 1779 } 1780 1781 basegfx::B2DHomMatrix SdrDragResize::getCurrentTransformation() 1782 { 1783 basegfx::B2DHomMatrix aRetval(basegfx::tools::createTranslateB2DHomMatrix( 1784 -DragStat().Ref1().X(), -DragStat().Ref1().Y())); 1785 aRetval.scale(aXFact, aYFact); 1786 aRetval.translate(DragStat().Ref1().X(), DragStat().Ref1().Y()); 1787 1788 return aRetval; 1789 } 1790 1791 void SdrDragResize::MoveSdrDrag(const Point& rNoSnapPnt) 1792 { 1793 Point aPnt(GetSnapPos(rNoSnapPnt)); 1794 Point aStart(DragStat().GetStart()); 1795 Point aRef(DragStat().GetRef1()); 1796 Fraction aMaxFact(0x7FFFFFFF,1); 1797 Rectangle aLR(getSdrDragView().GetWorkArea()); 1798 bool bWorkArea=!aLR.IsEmpty(); 1799 bool bDragLimit=IsDragLimit(); 1800 1801 if (bDragLimit || bWorkArea) 1802 { 1803 Rectangle aSR(GetMarkedRect()); 1804 1805 if (bDragLimit) 1806 { 1807 Rectangle aR2(GetDragLimitRect()); 1808 1809 if (bWorkArea) 1810 aLR.Intersection(aR2); 1811 else 1812 aLR=aR2; 1813 } 1814 1815 if (aPnt.X()<aLR.Left()) 1816 aPnt.X()=aLR.Left(); 1817 else if (aPnt.X()>aLR.Right()) 1818 aPnt.X()=aLR.Right(); 1819 1820 if (aPnt.Y()<aLR.Top()) 1821 aPnt.Y()=aLR.Top(); 1822 else if (aPnt.Y()>aLR.Bottom()) 1823 aPnt.Y()=aLR.Bottom(); 1824 1825 if (aRef.X()>aSR.Left()) 1826 { 1827 Fraction aMax(aRef.X()-aLR.Left(),aRef.X()-aSR.Left()); 1828 1829 if (aMax<aMaxFact) 1830 aMaxFact=aMax; 1831 } 1832 1833 if (aRef.X()<aSR.Right()) 1834 { 1835 Fraction aMax(aLR.Right()-aRef.X(),aSR.Right()-aRef.X()); 1836 1837 if (aMax<aMaxFact) 1838 aMaxFact=aMax; 1839 } 1840 1841 if (aRef.Y()>aSR.Top()) 1842 { 1843 Fraction aMax(aRef.Y()-aLR.Top(),aRef.Y()-aSR.Top()); 1844 1845 if (aMax<aMaxFact) 1846 aMaxFact=aMax; 1847 } 1848 1849 if (aRef.Y()<aSR.Bottom()) 1850 { 1851 Fraction aMax(aLR.Bottom()-aRef.Y(),aSR.Bottom()-aRef.Y()); 1852 1853 if (aMax<aMaxFact) 1854 aMaxFact=aMax; 1855 } 1856 } 1857 1858 long nXDiv=aStart.X()-aRef.X(); if (nXDiv==0) nXDiv=1; 1859 long nYDiv=aStart.Y()-aRef.Y(); if (nYDiv==0) nYDiv=1; 1860 long nXMul=aPnt.X()-aRef.X(); 1861 long nYMul=aPnt.Y()-aRef.Y(); 1862 1863 if (nXDiv<0) 1864 { 1865 nXDiv=-nXDiv; 1866 nXMul=-nXMul; 1867 } 1868 1869 if (nYDiv<0) 1870 { 1871 nYDiv=-nYDiv; 1872 nYMul=-nYMul; 1873 } 1874 1875 bool bXNeg=nXMul<0; if (bXNeg) nXMul=-nXMul; 1876 bool bYNeg=nYMul<0; if (bYNeg) nYMul=-nYMul; 1877 bool bOrtho=getSdrDragView().IsOrtho() || !getSdrDragView().IsResizeAllowed(false); 1878 1879 if (!DragStat().IsHorFixed() && !DragStat().IsVerFixed()) 1880 { 1881 if (Abs(nXDiv)<=1 || Abs(nYDiv)<=1) 1882 bOrtho=false; 1883 1884 if (bOrtho) 1885 { 1886 if ((Fraction(nXMul,nXDiv)>Fraction(nYMul,nYDiv)) !=getSdrDragView().IsBigOrtho()) 1887 { 1888 nXMul=nYMul; 1889 nXDiv=nYDiv; 1890 } 1891 else 1892 { 1893 nYMul=nXMul; 1894 nYDiv=nXDiv; 1895 } 1896 } 1897 } 1898 else 1899 { 1900 if (bOrtho) 1901 { 1902 if (DragStat().IsHorFixed()) 1903 { 1904 bXNeg=false; 1905 nXMul=nYMul; 1906 nXDiv=nYDiv; 1907 } 1908 1909 if (DragStat().IsVerFixed()) 1910 { 1911 bYNeg=false; 1912 nYMul=nXMul; 1913 nYDiv=nXDiv; 1914 } 1915 } 1916 else 1917 { 1918 if (DragStat().IsHorFixed()) 1919 { 1920 bXNeg=false; 1921 nXMul=1; 1922 nXDiv=1; 1923 } 1924 1925 if (DragStat().IsVerFixed()) 1926 { 1927 bYNeg=false; 1928 nYMul=1; 1929 nYDiv=1; 1930 } 1931 } 1932 } 1933 1934 Fraction aNeuXFact(nXMul,nXDiv); 1935 Fraction aNeuYFact(nYMul,nYDiv); 1936 1937 if (bOrtho) 1938 { 1939 if (aNeuXFact>aMaxFact) 1940 { 1941 aNeuXFact=aMaxFact; 1942 aNeuYFact=aMaxFact; 1943 } 1944 1945 if (aNeuYFact>aMaxFact) 1946 { 1947 aNeuXFact=aMaxFact; 1948 aNeuYFact=aMaxFact; 1949 } 1950 } 1951 1952 if (bXNeg) 1953 aNeuXFact=Fraction(-aNeuXFact.GetNumerator(),aNeuXFact.GetDenominator()); 1954 1955 if (bYNeg) 1956 aNeuYFact=Fraction(-aNeuYFact.GetNumerator(),aNeuYFact.GetDenominator()); 1957 1958 if (DragStat().CheckMinMoved(aPnt)) 1959 { 1960 if ((!DragStat().IsHorFixed() && aPnt.X()!=DragStat().GetNow().X()) || 1961 (!DragStat().IsVerFixed() && aPnt.Y()!=DragStat().GetNow().Y())) 1962 { 1963 Hide(); 1964 DragStat().NextMove(aPnt); 1965 aXFact=aNeuXFact; 1966 aYFact=aNeuYFact; 1967 Show(); 1968 } 1969 } 1970 } 1971 1972 void SdrDragResize::applyCurrentTransformationToSdrObject(SdrObject& rTarget) 1973 { 1974 rTarget.Resize(DragStat().Ref1(),aXFact,aYFact); 1975 } 1976 1977 bool SdrDragResize::EndSdrDrag(bool bCopy) 1978 { 1979 Hide(); 1980 1981 if (IsDraggingPoints()) 1982 { 1983 getSdrDragView().ResizeMarkedPoints(DragStat().Ref1(),aXFact,aYFact,bCopy); 1984 } 1985 else if (IsDraggingGluePoints()) 1986 { 1987 getSdrDragView().ResizeMarkedGluePoints(DragStat().Ref1(),aXFact,aYFact,bCopy); 1988 } 1989 else 1990 { 1991 getSdrDragView().ResizeMarkedObj(DragStat().Ref1(),aXFact,aYFact,bCopy); 1992 } 1993 1994 return true; 1995 } 1996 1997 Pointer SdrDragResize::GetSdrDragPointer() const 1998 { 1999 const SdrHdl* pHdl=GetDragHdl(); 2000 2001 if (pHdl!=NULL) 2002 { 2003 return pHdl->GetPointer(); 2004 } 2005 2006 return Pointer(POINTER_MOVE); 2007 } 2008 2009 //////////////////////////////////////////////////////////////////////////////////////////////////// 2010 2011 TYPEINIT1(SdrDragRotate,SdrDragMethod); 2012 2013 void SdrDragRotate::applyCurrentTransformationToSdrObject(SdrObject& rTarget) 2014 { 2015 rTarget.Rotate(DragStat().GetRef1(), nWink, sin(nWink*nPi180), cos(nWink*nPi180)); 2016 } 2017 2018 SdrDragRotate::SdrDragRotate(SdrDragView& rNewView) 2019 : SdrDragMethod(rNewView), 2020 nSin(0.0), 2021 nCos(1.0), 2022 nWink0(0), 2023 nWink(0), 2024 bRight(false) 2025 { 2026 } 2027 2028 void SdrDragRotate::TakeSdrDragComment(XubString& rStr) const 2029 { 2030 ImpTakeDescriptionStr(STR_DragMethRotate, rStr); 2031 rStr.AppendAscii(" ("); 2032 XubString aStr; 2033 sal_Int32 nTmpWink(NormAngle360(nWink)); 2034 2035 if(bRight && nWink) 2036 { 2037 nTmpWink -= 36000; 2038 } 2039 2040 getSdrDragView().GetModel()->TakeWinkStr(nTmpWink, aStr); 2041 rStr += aStr; 2042 rStr += sal_Unicode(')'); 2043 2044 if(getSdrDragView().IsDragWithCopy()) 2045 rStr += ImpGetResStr(STR_EditWithCopy); 2046 } 2047 2048 bool SdrDragRotate::BeginSdrDrag() 2049 { 2050 SdrHdl* pH=GetHdlList().GetHdl(HDL_REF1); 2051 2052 if (pH!=NULL) 2053 { 2054 Show(); 2055 DragStat().Ref1()=pH->GetPos(); 2056 nWink0=GetAngle(DragStat().GetStart()-DragStat().GetRef1()); 2057 return true; 2058 } 2059 else 2060 { 2061 DBG_ERROR("SdrDragRotate::BeginSdrDrag(): Kein Referenzpunkt-Handle gefunden"); 2062 return false; 2063 } 2064 } 2065 2066 basegfx::B2DHomMatrix SdrDragRotate::getCurrentTransformation() 2067 { 2068 return basegfx::tools::createRotateAroundPoint( 2069 DragStat().GetRef1().X(), DragStat().GetRef1().Y(), 2070 -atan2(nSin, nCos)); 2071 } 2072 2073 void SdrDragRotate::MoveSdrDrag(const Point& rPnt_) 2074 { 2075 Point aPnt(rPnt_); 2076 if (DragStat().CheckMinMoved(aPnt)) 2077 { 2078 long nNeuWink=NormAngle360(GetAngle(aPnt-DragStat().GetRef1())-nWink0); 2079 long nSA=0; 2080 2081 if (getSdrDragView().IsAngleSnapEnabled()) 2082 nSA=getSdrDragView().GetSnapAngle(); 2083 2084 if (!getSdrDragView().IsRotateAllowed(false)) 2085 nSA=9000; 2086 2087 if (nSA!=0) 2088 { // Winkelfang 2089 nNeuWink+=nSA/2; 2090 nNeuWink/=nSA; 2091 nNeuWink*=nSA; 2092 } 2093 2094 nNeuWink=NormAngle180(nNeuWink); 2095 2096 if (nWink!=nNeuWink) 2097 { 2098 sal_uInt16 nSekt0=GetAngleSector(nWink); 2099 sal_uInt16 nSekt1=GetAngleSector(nNeuWink); 2100 2101 if (nSekt0==0 && nSekt1==3) 2102 bRight=true; 2103 2104 if (nSekt0==3 && nSekt1==0) 2105 bRight=false; 2106 2107 nWink=nNeuWink; 2108 double a=nWink*nPi180; 2109 double nSin1=sin(a); // schonmal berechnen, damit mgl. wenig Zeit 2110 double nCos1=cos(a); // zwischen Hide() und Show() vergeht 2111 Hide(); 2112 nSin=nSin1; 2113 nCos=nCos1; 2114 DragStat().NextMove(aPnt); 2115 Show(); 2116 } 2117 } 2118 } 2119 2120 bool SdrDragRotate::EndSdrDrag(bool bCopy) 2121 { 2122 Hide(); 2123 2124 if (nWink!=0) 2125 { 2126 if (IsDraggingPoints()) 2127 { 2128 getSdrDragView().RotateMarkedPoints(DragStat().GetRef1(),nWink,bCopy); 2129 } 2130 else if (IsDraggingGluePoints()) 2131 { 2132 getSdrDragView().RotateMarkedGluePoints(DragStat().GetRef1(),nWink,bCopy); 2133 } 2134 else 2135 { 2136 getSdrDragView().RotateMarkedObj(DragStat().GetRef1(),nWink,bCopy); 2137 } 2138 } 2139 return true; 2140 } 2141 2142 Pointer SdrDragRotate::GetSdrDragPointer() const 2143 { 2144 return Pointer(POINTER_ROTATE); 2145 } 2146 2147 //////////////////////////////////////////////////////////////////////////////////////////////////// 2148 2149 TYPEINIT1(SdrDragShear,SdrDragMethod); 2150 2151 SdrDragShear::SdrDragShear(SdrDragView& rNewView, bool bSlant1) 2152 : SdrDragMethod(rNewView), 2153 aFact(1,1), 2154 nWink0(0), 2155 nWink(0), 2156 nTan(0.0), 2157 bVertical(false), 2158 bResize(false), 2159 bUpSideDown(false), 2160 bSlant(bSlant1) 2161 { 2162 } 2163 2164 void SdrDragShear::TakeSdrDragComment(XubString& rStr) const 2165 { 2166 ImpTakeDescriptionStr(STR_DragMethShear, rStr); 2167 rStr.AppendAscii(" ("); 2168 2169 sal_Int32 nTmpWink(nWink); 2170 2171 if(bUpSideDown) 2172 nTmpWink += 18000; 2173 2174 nTmpWink = NormAngle180(nTmpWink); 2175 2176 XubString aStr; 2177 2178 getSdrDragView().GetModel()->TakeWinkStr(nTmpWink, aStr); 2179 rStr += aStr; 2180 rStr += sal_Unicode(')'); 2181 2182 if(getSdrDragView().IsDragWithCopy()) 2183 rStr += ImpGetResStr(STR_EditWithCopy); 2184 } 2185 2186 bool SdrDragShear::BeginSdrDrag() 2187 { 2188 SdrHdlKind eRefHdl=HDL_MOVE; 2189 SdrHdl* pRefHdl=NULL; 2190 2191 switch (GetDragHdlKind()) 2192 { 2193 case HDL_UPPER: eRefHdl=HDL_LOWER; break; 2194 case HDL_LOWER: eRefHdl=HDL_UPPER; break; 2195 case HDL_LEFT : eRefHdl=HDL_RIGHT; bVertical=true; break; 2196 case HDL_RIGHT: eRefHdl=HDL_LEFT ; bVertical=true; break; 2197 default: break; 2198 } 2199 2200 if (eRefHdl!=HDL_MOVE) 2201 pRefHdl=GetHdlList().GetHdl(eRefHdl); 2202 2203 if (pRefHdl!=NULL) 2204 { 2205 DragStat().Ref1()=pRefHdl->GetPos(); 2206 nWink0=GetAngle(DragStat().GetStart()-DragStat().GetRef1()); 2207 } 2208 else 2209 { 2210 DBG_ERROR("SdrDragShear::BeginSdrDrag(): Kein Referenzpunkt-Handle fuer Shear gefunden"); 2211 return false; 2212 } 2213 2214 Show(); 2215 return true; 2216 } 2217 2218 basegfx::B2DHomMatrix SdrDragShear::getCurrentTransformation() 2219 { 2220 basegfx::B2DHomMatrix aRetval(basegfx::tools::createTranslateB2DHomMatrix( 2221 -DragStat().GetRef1().X(), -DragStat().GetRef1().Y())); 2222 2223 if (bResize) 2224 { 2225 if (bVertical) 2226 { 2227 aRetval.scale(aFact, 1.0); 2228 aRetval.shearY(-nTan); 2229 } 2230 else 2231 { 2232 aRetval.scale(1.0, aFact); 2233 aRetval.shearX(-nTan); 2234 } 2235 } 2236 2237 aRetval.translate(DragStat().GetRef1().X(), DragStat().GetRef1().Y()); 2238 2239 return aRetval; 2240 } 2241 2242 void SdrDragShear::MoveSdrDrag(const Point& rPnt) 2243 { 2244 if (DragStat().CheckMinMoved(rPnt)) 2245 { 2246 bResize=!getSdrDragView().IsOrtho(); 2247 long nSA=0; 2248 2249 if (getSdrDragView().IsAngleSnapEnabled()) 2250 nSA=getSdrDragView().GetSnapAngle(); 2251 2252 Point aP0(DragStat().GetStart()); 2253 Point aPnt(rPnt); 2254 Fraction aNeuFact(1,1); 2255 2256 // Wenn kein Winkelfang, dann ggf. Rasterfang (ausser bei Slant) 2257 if (nSA==0 && !bSlant) 2258 aPnt=GetSnapPos(aPnt); 2259 2260 if (!bSlant && !bResize) 2261 { // Shear ohne Resize 2262 if (bVertical) 2263 aPnt.X()=aP0.X(); 2264 else 2265 aPnt.Y()=aP0.Y(); 2266 } 2267 2268 Point aRef(DragStat().GetRef1()); 2269 Point aDif(aPnt-aRef); 2270 2271 long nNeuWink=0; 2272 2273 if (bSlant) 2274 { 2275 nNeuWink=NormAngle180(-(GetAngle(aDif)-nWink0)); 2276 2277 if (bVertical) 2278 nNeuWink=NormAngle180(-nNeuWink); 2279 } 2280 else 2281 { 2282 if (bVertical) 2283 nNeuWink=NormAngle180(GetAngle(aDif)); 2284 else 2285 nNeuWink=NormAngle180(-(GetAngle(aDif)-9000)); 2286 2287 if (nNeuWink<-9000 || nNeuWink>9000) 2288 nNeuWink=NormAngle180(nNeuWink+18000); 2289 2290 if (bResize) 2291 { 2292 Point aPt2(aPnt); 2293 2294 if (nSA!=0) 2295 aPt2=GetSnapPos(aPnt); // den also in jedem Falle fangen 2296 2297 if (bVertical) 2298 { 2299 aNeuFact=Fraction(aPt2.X()-aRef.X(),aP0.X()-aRef.X()); 2300 } 2301 else 2302 { 2303 aNeuFact=Fraction(aPt2.Y()-aRef.Y(),aP0.Y()-aRef.Y()); 2304 } 2305 } 2306 } 2307 2308 bool bNeg=nNeuWink<0; 2309 2310 if (bNeg) 2311 nNeuWink=-nNeuWink; 2312 2313 if (nSA!=0) 2314 { // Winkelfang 2315 nNeuWink+=nSA/2; 2316 nNeuWink/=nSA; 2317 nNeuWink*=nSA; 2318 } 2319 2320 nNeuWink=NormAngle360(nNeuWink); 2321 bUpSideDown=nNeuWink>9000 && nNeuWink<27000; 2322 2323 if (bSlant) 2324 { // Resize fuer Slant berechnen 2325 // Mit Winkelfang jedoch ohne 89deg Begrenzung 2326 long nTmpWink=nNeuWink; 2327 if (bUpSideDown) nNeuWink-=18000; 2328 if (bNeg) nTmpWink=-nTmpWink; 2329 bResize=true; 2330 double nCos=cos(nTmpWink*nPi180); 2331 aNeuFact=nCos; 2332 Kuerzen(aFact,10); // 3 Dezimalstellen sollten reichen 2333 } 2334 2335 if (nNeuWink>8900) 2336 nNeuWink=8900; 2337 2338 if (bNeg) 2339 nNeuWink=-nNeuWink; 2340 2341 if (nWink!=nNeuWink || aFact!=aNeuFact) 2342 { 2343 nWink=nNeuWink; 2344 aFact=aNeuFact; 2345 double a=nWink*nPi180; 2346 double nTan1=0.0; 2347 nTan1=tan(a); // schonmal berechnen, damit mgl. wenig Zeit zwischen Hide() und Show() vergeht 2348 Hide(); 2349 nTan=nTan1; 2350 DragStat().NextMove(rPnt); 2351 Show(); 2352 } 2353 } 2354 } 2355 2356 void SdrDragShear::applyCurrentTransformationToSdrObject(SdrObject& rTarget) 2357 { 2358 if (bResize) 2359 { 2360 if (bVertical) 2361 { 2362 rTarget.Resize(DragStat().GetRef1(),aFact,Fraction(1,1)); 2363 } 2364 else 2365 { 2366 rTarget.Resize(DragStat().GetRef1(),Fraction(1,1),aFact); 2367 } 2368 } 2369 2370 if (nWink!=0) 2371 { 2372 rTarget.Shear(DragStat().GetRef1(),nWink,tan(nWink*nPi180),bVertical); 2373 } 2374 } 2375 2376 bool SdrDragShear::EndSdrDrag(bool bCopy) 2377 { 2378 Hide(); 2379 2380 if (bResize && aFact==Fraction(1,1)) 2381 bResize=false; 2382 2383 if (nWink!=0 || bResize) 2384 { 2385 if (nWink!=0 && bResize) 2386 { 2387 XubString aStr; 2388 ImpTakeDescriptionStr(STR_EditShear,aStr); 2389 2390 if (bCopy) 2391 aStr+=ImpGetResStr(STR_EditWithCopy); 2392 2393 getSdrDragView().BegUndo(aStr); 2394 } 2395 2396 if (bResize) 2397 { 2398 if (bVertical) 2399 { 2400 getSdrDragView().ResizeMarkedObj(DragStat().GetRef1(),aFact,Fraction(1,1),bCopy); 2401 } 2402 else 2403 { 2404 getSdrDragView().ResizeMarkedObj(DragStat().GetRef1(),Fraction(1,1),aFact,bCopy); 2405 } 2406 2407 bCopy=false; 2408 } 2409 2410 if (nWink!=0) 2411 { 2412 getSdrDragView().ShearMarkedObj(DragStat().GetRef1(),nWink,bVertical,bCopy); 2413 } 2414 2415 if (nWink!=0 && bResize) 2416 getSdrDragView().EndUndo(); 2417 2418 return true; 2419 } 2420 2421 return false; 2422 } 2423 2424 Pointer SdrDragShear::GetSdrDragPointer() const 2425 { 2426 if (bVertical) 2427 return Pointer(POINTER_VSHEAR); 2428 else 2429 return Pointer(POINTER_HSHEAR); 2430 } 2431 2432 //////////////////////////////////////////////////////////////////////////////////////////////////// 2433 2434 TYPEINIT1(SdrDragMirror,SdrDragMethod); 2435 2436 void SdrDragMirror::applyCurrentTransformationToSdrObject(SdrObject& rTarget) 2437 { 2438 if(bMirrored) 2439 { 2440 rTarget.Mirror(DragStat().GetRef1(), DragStat().GetRef2()); 2441 } 2442 } 2443 2444 SdrDragMirror::SdrDragMirror(SdrDragView& rNewView) 2445 : SdrDragMethod(rNewView), 2446 nWink(0), 2447 bMirrored(false), 2448 bSide0(false) 2449 { 2450 } 2451 2452 bool SdrDragMirror::ImpCheckSide(const Point& rPnt) const 2453 { 2454 long nWink1=GetAngle(rPnt-DragStat().GetRef1()); 2455 nWink1-=nWink; 2456 nWink1=NormAngle360(nWink1); 2457 2458 return nWink1<18000; 2459 } 2460 2461 void SdrDragMirror::TakeSdrDragComment(XubString& rStr) const 2462 { 2463 if (aDif.X()==0) 2464 ImpTakeDescriptionStr(STR_DragMethMirrorHori,rStr); 2465 else if (aDif.Y()==0) 2466 ImpTakeDescriptionStr(STR_DragMethMirrorVert,rStr); 2467 else if (Abs(aDif.X())==Abs(aDif.Y())) 2468 ImpTakeDescriptionStr(STR_DragMethMirrorDiag,rStr); 2469 else 2470 ImpTakeDescriptionStr(STR_DragMethMirrorFree,rStr); 2471 2472 if (getSdrDragView().IsDragWithCopy()) 2473 rStr+=ImpGetResStr(STR_EditWithCopy); 2474 } 2475 2476 bool SdrDragMirror::BeginSdrDrag() 2477 { 2478 SdrHdl* pH1=GetHdlList().GetHdl(HDL_REF1); 2479 SdrHdl* pH2=GetHdlList().GetHdl(HDL_REF2); 2480 2481 if (pH1!=NULL && pH2!=NULL) 2482 { 2483 DragStat().Ref1()=pH1->GetPos(); 2484 DragStat().Ref2()=pH2->GetPos(); 2485 Ref1()=pH1->GetPos(); 2486 Ref2()=pH2->GetPos(); 2487 aDif=pH2->GetPos()-pH1->GetPos(); 2488 bool b90=(aDif.X()==0) || aDif.Y()==0; 2489 bool b45=b90 || (Abs(aDif.X())==Abs(aDif.Y())); 2490 nWink=NormAngle360(GetAngle(aDif)); 2491 2492 if (!getSdrDragView().IsMirrorAllowed(false,false) && !b45) 2493 return false; // freier Achsenwinkel nicht erlaubt 2494 2495 if (!getSdrDragView().IsMirrorAllowed(true,false) && !b90) 2496 return false; // 45deg auch nicht erlaubt 2497 2498 bSide0=ImpCheckSide(DragStat().GetStart()); 2499 Show(); 2500 return true; 2501 } 2502 else 2503 { 2504 DBG_ERROR("SdrDragMirror::BeginSdrDrag(): Spiegelachse nicht gefunden"); 2505 return false; 2506 } 2507 } 2508 2509 basegfx::B2DHomMatrix SdrDragMirror::getCurrentTransformation() 2510 { 2511 basegfx::B2DHomMatrix aRetval; 2512 2513 if (bMirrored) 2514 { 2515 const double fDeltaX(DragStat().GetRef2().X() - DragStat().GetRef1().X()); 2516 const double fDeltaY(DragStat().GetRef2().Y() - DragStat().GetRef1().Y()); 2517 const double fRotation(atan2(fDeltaY, fDeltaX)); 2518 2519 aRetval = basegfx::tools::createTranslateB2DHomMatrix(-DragStat().GetRef1().X(), -DragStat().GetRef1().Y()); 2520 aRetval.rotate(-fRotation); 2521 aRetval.scale(1.0, -1.0); 2522 aRetval.rotate(fRotation); 2523 aRetval.translate(DragStat().GetRef1().X(), DragStat().GetRef1().Y()); 2524 } 2525 2526 return aRetval; 2527 } 2528 2529 void SdrDragMirror::MoveSdrDrag(const Point& rPnt) 2530 { 2531 if (DragStat().CheckMinMoved(rPnt)) 2532 { 2533 bool bNeuSide=ImpCheckSide(rPnt); 2534 bool bNeuMirr=bSide0!=bNeuSide; 2535 2536 if (bMirrored!=bNeuMirr) 2537 { 2538 Hide(); 2539 bMirrored=bNeuMirr; 2540 DragStat().NextMove(rPnt); 2541 Show(); 2542 } 2543 } 2544 } 2545 2546 bool SdrDragMirror::EndSdrDrag(bool bCopy) 2547 { 2548 Hide(); 2549 2550 if (bMirrored) 2551 { 2552 getSdrDragView().MirrorMarkedObj(DragStat().GetRef1(),DragStat().GetRef2(),bCopy); 2553 } 2554 2555 return true; 2556 } 2557 2558 Pointer SdrDragMirror::GetSdrDragPointer() const 2559 { 2560 return Pointer(POINTER_MIRROR); 2561 } 2562 2563 //////////////////////////////////////////////////////////////////////////////////////////////////// 2564 2565 TYPEINIT1(SdrDragGradient, SdrDragMethod); 2566 2567 SdrDragGradient::SdrDragGradient(SdrDragView& rNewView, bool bGrad) 2568 : SdrDragMethod(rNewView), 2569 pIAOHandle(NULL), 2570 bIsGradient(bGrad) 2571 { 2572 } 2573 2574 void SdrDragGradient::TakeSdrDragComment(XubString& rStr) const 2575 { 2576 if(IsGradient()) 2577 ImpTakeDescriptionStr(STR_DragMethGradient, rStr); 2578 else 2579 ImpTakeDescriptionStr(STR_DragMethTransparence, rStr); 2580 } 2581 2582 bool SdrDragGradient::BeginSdrDrag() 2583 { 2584 bool bRetval(false); 2585 2586 pIAOHandle = (SdrHdlGradient*)GetHdlList().GetHdl(IsGradient() ? HDL_GRAD : HDL_TRNS); 2587 2588 if(pIAOHandle) 2589 { 2590 // save old values 2591 DragStat().Ref1() = pIAOHandle->GetPos(); 2592 DragStat().Ref2() = pIAOHandle->Get2ndPos(); 2593 2594 // what was hit? 2595 bool bHit(false); 2596 SdrHdlColor* pColHdl = pIAOHandle->GetColorHdl1(); 2597 2598 // init handling flags 2599 pIAOHandle->SetMoveSingleHandle(false); 2600 pIAOHandle->SetMoveFirstHandle(false); 2601 2602 // test first color handle 2603 if(pColHdl) 2604 { 2605 basegfx::B2DPoint aPosition(DragStat().GetStart().X(), DragStat().GetStart().Y()); 2606 2607 if(pColHdl->getOverlayObjectList().isHitLogic(aPosition)) 2608 { 2609 bHit = true; 2610 pIAOHandle->SetMoveSingleHandle(true); 2611 pIAOHandle->SetMoveFirstHandle(true); 2612 } 2613 } 2614 2615 // test second color handle 2616 pColHdl = pIAOHandle->GetColorHdl2(); 2617 2618 if(!bHit && pColHdl) 2619 { 2620 basegfx::B2DPoint aPosition(DragStat().GetStart().X(), DragStat().GetStart().Y()); 2621 2622 if(pColHdl->getOverlayObjectList().isHitLogic(aPosition)) 2623 { 2624 bHit = true; 2625 pIAOHandle->SetMoveSingleHandle(true); 2626 } 2627 } 2628 2629 // test gradient handle itself 2630 if(!bHit) 2631 { 2632 basegfx::B2DPoint aPosition(DragStat().GetStart().X(), DragStat().GetStart().Y()); 2633 2634 if(pIAOHandle->getOverlayObjectList().isHitLogic(aPosition)) 2635 { 2636 bHit = true; 2637 } 2638 } 2639 2640 // everything up and running :o} 2641 bRetval = bHit; 2642 } 2643 else 2644 { 2645 DBG_ERROR("SdrDragGradient::BeginSdrDrag(): IAOGradient nicht gefunden"); 2646 } 2647 2648 return bRetval; 2649 } 2650 2651 void SdrDragGradient::MoveSdrDrag(const Point& rPnt) 2652 { 2653 if(pIAOHandle && DragStat().CheckMinMoved(rPnt)) 2654 { 2655 DragStat().NextMove(rPnt); 2656 2657 // Do the Move here!!! DragStat().GetStart() 2658 Point aMoveDiff = rPnt - DragStat().GetStart(); 2659 2660 if(pIAOHandle->IsMoveSingleHandle()) 2661 { 2662 if(pIAOHandle->IsMoveFirstHandle()) 2663 { 2664 pIAOHandle->SetPos(DragStat().Ref1() + aMoveDiff); 2665 if(pIAOHandle->GetColorHdl1()) 2666 pIAOHandle->GetColorHdl1()->SetPos(DragStat().Ref1() + aMoveDiff); 2667 } 2668 else 2669 { 2670 pIAOHandle->Set2ndPos(DragStat().Ref2() + aMoveDiff); 2671 if(pIAOHandle->GetColorHdl2()) 2672 pIAOHandle->GetColorHdl2()->SetPos(DragStat().Ref2() + aMoveDiff); 2673 } 2674 } 2675 else 2676 { 2677 pIAOHandle->SetPos(DragStat().Ref1() + aMoveDiff); 2678 pIAOHandle->Set2ndPos(DragStat().Ref2() + aMoveDiff); 2679 2680 if(pIAOHandle->GetColorHdl1()) 2681 pIAOHandle->GetColorHdl1()->SetPos(DragStat().Ref1() + aMoveDiff); 2682 2683 if(pIAOHandle->GetColorHdl2()) 2684 pIAOHandle->GetColorHdl2()->SetPos(DragStat().Ref2() + aMoveDiff); 2685 } 2686 2687 // new state 2688 pIAOHandle->FromIAOToItem(getSdrDragView().GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(), false, false); 2689 } 2690 } 2691 2692 bool SdrDragGradient::EndSdrDrag(bool /*bCopy*/) 2693 { 2694 // here the result is clear, do something with the values 2695 Ref1() = pIAOHandle->GetPos(); 2696 Ref2() = pIAOHandle->Get2ndPos(); 2697 2698 // new state 2699 pIAOHandle->FromIAOToItem(getSdrDragView().GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(), true, true); 2700 2701 return true; 2702 } 2703 2704 void SdrDragGradient::CancelSdrDrag() 2705 { 2706 // restore old values 2707 pIAOHandle->SetPos(DragStat().Ref1()); 2708 pIAOHandle->Set2ndPos(DragStat().Ref2()); 2709 2710 if(pIAOHandle->GetColorHdl1()) 2711 pIAOHandle->GetColorHdl1()->SetPos(DragStat().Ref1()); 2712 2713 if(pIAOHandle->GetColorHdl2()) 2714 pIAOHandle->GetColorHdl2()->SetPos(DragStat().Ref2()); 2715 2716 // new state 2717 pIAOHandle->FromIAOToItem(getSdrDragView().GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(), true, false); 2718 } 2719 2720 Pointer SdrDragGradient::GetSdrDragPointer() const 2721 { 2722 return Pointer(POINTER_REFHAND); 2723 } 2724 2725 //////////////////////////////////////////////////////////////////////////////////////////////////// 2726 2727 TYPEINIT1(SdrDragCrook,SdrDragMethod); 2728 2729 SdrDragCrook::SdrDragCrook(SdrDragView& rNewView) 2730 : SdrDragMethod(rNewView), 2731 aFact(1,1), 2732 bContortionAllowed(false), 2733 bNoContortionAllowed(false), 2734 bContortion(false), 2735 bResizeAllowed(false), 2736 bResize(false), 2737 bRotateAllowed(false), 2738 bRotate(false), 2739 bVertical(false), 2740 bValid(false), 2741 bLft(false), 2742 bRgt(false), 2743 bUpr(false), 2744 bLwr(false), 2745 bAtCenter(false), 2746 nWink(0), 2747 nMarkSize(0), 2748 eMode(SDRCROOK_ROTATE) 2749 { 2750 } 2751 2752 void SdrDragCrook::TakeSdrDragComment(XubString& rStr) const 2753 { 2754 ImpTakeDescriptionStr(!bContortion ? STR_DragMethCrook : STR_DragMethCrookContortion, rStr); 2755 2756 if(bValid) 2757 { 2758 rStr.AppendAscii(" ("); 2759 2760 XubString aStr; 2761 sal_Int32 nVal(nWink); 2762 2763 if(bAtCenter) 2764 nVal *= 2; 2765 2766 nVal = Abs(nVal); 2767 getSdrDragView().GetModel()->TakeWinkStr(nVal, aStr); 2768 rStr += aStr; 2769 rStr += sal_Unicode(')'); 2770 } 2771 2772 if(getSdrDragView().IsDragWithCopy()) 2773 rStr += ImpGetResStr(STR_EditWithCopy); 2774 } 2775 2776 // #96920# These defines parametrise the created raster 2777 // for interactions 2778 #define DRAG_CROOK_RASTER_MINIMUM (4) 2779 #define DRAG_CROOK_RASTER_MAXIMUM (15) 2780 #define DRAG_CROOK_RASTER_DISTANCE (30) 2781 2782 basegfx::B2DPolyPolygon impCreateDragRaster(SdrPageView& rPageView, const Rectangle& rMarkRect) 2783 { 2784 basegfx::B2DPolyPolygon aRetval; 2785 2786 if(rPageView.PageWindowCount()) 2787 { 2788 OutputDevice& rOut = (rPageView.GetPageWindow(0)->GetPaintWindow().GetOutputDevice()); 2789 Rectangle aPixelSize = rOut.LogicToPixel(rMarkRect); 2790 sal_uInt32 nHorDiv(aPixelSize.GetWidth() / DRAG_CROOK_RASTER_DISTANCE); 2791 sal_uInt32 nVerDiv(aPixelSize.GetHeight() / DRAG_CROOK_RASTER_DISTANCE); 2792 2793 if(nHorDiv > DRAG_CROOK_RASTER_MAXIMUM) 2794 nHorDiv = DRAG_CROOK_RASTER_MAXIMUM; 2795 if(nHorDiv < DRAG_CROOK_RASTER_MINIMUM) 2796 nHorDiv = DRAG_CROOK_RASTER_MINIMUM; 2797 2798 if(nVerDiv > DRAG_CROOK_RASTER_MAXIMUM) 2799 nVerDiv = DRAG_CROOK_RASTER_MAXIMUM; 2800 if(nVerDiv < DRAG_CROOK_RASTER_MINIMUM) 2801 nVerDiv = DRAG_CROOK_RASTER_MINIMUM; 2802 2803 const double fXLen(rMarkRect.GetWidth() / (double)nHorDiv); 2804 const double fYLen(rMarkRect.GetHeight() / (double)nVerDiv); 2805 double fYPos(rMarkRect.Top()); 2806 sal_uInt32 a, b; 2807 2808 for(a = 0; a <= nVerDiv; a++) 2809 { 2810 // hor lines 2811 for(b = 0; b < nHorDiv; b++) 2812 { 2813 basegfx::B2DPolygon aHorLineSegment; 2814 2815 const double fNewX(rMarkRect.Left() + (b * fXLen)); 2816 aHorLineSegment.append(basegfx::B2DPoint(fNewX, fYPos)); 2817 aHorLineSegment.appendBezierSegment( 2818 basegfx::B2DPoint(fNewX + (fXLen * (1.0 / 3.0)), fYPos), 2819 basegfx::B2DPoint(fNewX + (fXLen * (2.0 / 3.0)), fYPos), 2820 basegfx::B2DPoint(fNewX + fXLen, fYPos)); 2821 aRetval.append(aHorLineSegment); 2822 } 2823 2824 // increments 2825 fYPos += fYLen; 2826 } 2827 2828 double fXPos(rMarkRect.Left()); 2829 2830 for(a = 0; a <= nHorDiv; a++) 2831 { 2832 // ver lines 2833 for(b = 0; b < nVerDiv; b++) 2834 { 2835 basegfx::B2DPolygon aVerLineSegment; 2836 2837 const double fNewY(rMarkRect.Top() + (b * fYLen)); 2838 aVerLineSegment.append(basegfx::B2DPoint(fXPos, fNewY)); 2839 aVerLineSegment.appendBezierSegment( 2840 basegfx::B2DPoint(fXPos, fNewY + (fYLen * (1.0 / 3.0))), 2841 basegfx::B2DPoint(fXPos, fNewY + (fYLen * (2.0 / 3.0))), 2842 basegfx::B2DPoint(fXPos, fNewY + fYLen)); 2843 aRetval.append(aVerLineSegment); 2844 } 2845 2846 // increments 2847 fXPos += fXLen; 2848 } 2849 } 2850 2851 return aRetval; 2852 } 2853 2854 void SdrDragCrook::createSdrDragEntries() 2855 { 2856 // Add extended frame raster first, so it will be behind objects 2857 if(getSdrDragView().GetSdrPageView()) 2858 { 2859 const basegfx::B2DPolyPolygon aDragRaster(impCreateDragRaster(*getSdrDragView().GetSdrPageView(), GetMarkedRect())); 2860 2861 if(aDragRaster.count()) 2862 { 2863 addSdrDragEntry(new SdrDragEntryPolyPolygon(aDragRaster)); 2864 } 2865 } 2866 2867 // call parent 2868 SdrDragMethod::createSdrDragEntries(); 2869 } 2870 2871 bool SdrDragCrook::BeginSdrDrag() 2872 { 2873 bContortionAllowed=getSdrDragView().IsCrookAllowed(false); 2874 bNoContortionAllowed=getSdrDragView().IsCrookAllowed(true); 2875 bResizeAllowed=getSdrDragView().IsResizeAllowed(false); 2876 bRotateAllowed=getSdrDragView().IsRotateAllowed(false); 2877 2878 if (bContortionAllowed || bNoContortionAllowed) 2879 { 2880 bVertical=(GetDragHdlKind()==HDL_LOWER || GetDragHdlKind()==HDL_UPPER); 2881 aMarkRect=GetMarkedRect(); 2882 aMarkCenter=aMarkRect.Center(); 2883 nMarkSize=bVertical ? (aMarkRect.GetHeight()-1) : (aMarkRect.GetWidth()-1); 2884 aCenter=aMarkCenter; 2885 aStart=DragStat().GetStart(); 2886 Show(); 2887 return true; 2888 } 2889 else 2890 { 2891 return false; 2892 } 2893 } 2894 2895 void SdrDragCrook::_MovAllPoints(basegfx::B2DPolyPolygon& rTarget) 2896 { 2897 SdrPageView* pPV = getSdrDragView().GetSdrPageView(); 2898 2899 if(pPV) 2900 { 2901 XPolyPolygon aTempPolyPoly(rTarget); 2902 2903 if (pPV->HasMarkedObjPageView()) 2904 { 2905 sal_uInt16 nPolyAnz=aTempPolyPoly.Count(); 2906 2907 if (!bContortion && !getSdrDragView().IsNoDragXorPolys()) 2908 { 2909 sal_uInt16 n1st=0,nLast=0; 2910 Point aC(aCenter); 2911 2912 while (n1st<nPolyAnz) 2913 { 2914 nLast=n1st; 2915 while (nLast<nPolyAnz && aTempPolyPoly[nLast].GetPointCount()!=0) nLast++; 2916 Rectangle aBound(aTempPolyPoly[n1st].GetBoundRect()); 2917 sal_uInt16 i; 2918 2919 for (i=n1st+1; i<nLast; i++) 2920 { 2921 aBound.Union(aTempPolyPoly[n1st].GetBoundRect()); 2922 } 2923 2924 Point aCtr0(aBound.Center()); 2925 Point aCtr1(aCtr0); 2926 2927 if (bResize) 2928 { 2929 Fraction aFact1(1,1); 2930 2931 if (bVertical) 2932 { 2933 ResizePoint(aCtr1,aC,aFact1,aFact); 2934 } 2935 else 2936 { 2937 ResizePoint(aCtr1,aC,aFact,aFact1); 2938 } 2939 } 2940 2941 bool bRotOk=false; 2942 double nSin=0,nCos=0; 2943 2944 if (aRad.X()!=0 && aRad.Y()!=0) 2945 { 2946 bRotOk=bRotate; 2947 2948 switch (eMode) 2949 { 2950 case SDRCROOK_ROTATE : CrookRotateXPoint (aCtr1,NULL,NULL,aC,aRad,nSin,nCos,bVertical); break; 2951 case SDRCROOK_SLANT : CrookSlantXPoint (aCtr1,NULL,NULL,aC,aRad,nSin,nCos,bVertical); break; 2952 case SDRCROOK_STRETCH: CrookStretchXPoint(aCtr1,NULL,NULL,aC,aRad,nSin,nCos,bVertical,aMarkRect); break; 2953 } // switch 2954 } 2955 2956 aCtr1-=aCtr0; 2957 2958 for (i=n1st; i<nLast; i++) 2959 { 2960 if (bRotOk) 2961 { 2962 RotateXPoly(aTempPolyPoly[i],aCtr0,nSin,nCos); 2963 } 2964 2965 aTempPolyPoly[i].Move(aCtr1.X(),aCtr1.Y()); 2966 } 2967 2968 n1st=nLast+1; 2969 } 2970 } 2971 else 2972 { 2973 sal_uInt16 i,j; 2974 2975 for (j=0; j<nPolyAnz; j++) 2976 { 2977 XPolygon& aPol=aTempPolyPoly[j]; 2978 sal_uInt16 nPtAnz=aPol.GetPointCount(); 2979 i=0; 2980 2981 while (i<nPtAnz) 2982 { 2983 Point* pPnt=&aPol[i]; 2984 Point* pC1=NULL; 2985 Point* pC2=NULL; 2986 2987 if (i+1<nPtAnz && aPol.IsControl(i)) 2988 { // Kontrollpunkt links 2989 pC1=pPnt; 2990 i++; 2991 pPnt=&aPol[i]; 2992 } 2993 2994 i++; 2995 2996 if (i<nPtAnz && aPol.IsControl(i)) 2997 { // Kontrollpunkt rechts 2998 pC2=&aPol[i]; 2999 i++; 3000 } 3001 3002 _MovCrookPoint(*pPnt,pC1,pC2); 3003 } 3004 } 3005 } 3006 } 3007 3008 rTarget = aTempPolyPoly.getB2DPolyPolygon(); 3009 } 3010 } 3011 3012 void SdrDragCrook::_MovCrookPoint(Point& rPnt, Point* pC1, Point* pC2) 3013 { 3014 bool bVert=bVertical; 3015 bool bC1=pC1!=NULL; 3016 bool bC2=pC2!=NULL; 3017 Point aC(aCenter); 3018 3019 if (bResize) 3020 { 3021 Fraction aFact1(1,1); 3022 3023 if (bVert) 3024 { 3025 ResizePoint(rPnt,aC,aFact1,aFact); 3026 3027 if (bC1) 3028 ResizePoint(*pC1,aC,aFact1,aFact); 3029 3030 if (bC2) 3031 ResizePoint(*pC2,aC,aFact1,aFact); 3032 } 3033 else 3034 { 3035 ResizePoint(rPnt,aC,aFact,aFact1); 3036 3037 if (bC1) 3038 ResizePoint(*pC1,aC,aFact,aFact1); 3039 3040 if (bC2) 3041 ResizePoint(*pC2,aC,aFact,aFact1); 3042 } 3043 } 3044 3045 if (aRad.X()!=0 && aRad.Y()!=0) 3046 { 3047 double nSin,nCos; 3048 3049 switch (eMode) 3050 { 3051 case SDRCROOK_ROTATE : CrookRotateXPoint (rPnt,pC1,pC2,aC,aRad,nSin,nCos,bVert); break; 3052 case SDRCROOK_SLANT : CrookSlantXPoint (rPnt,pC1,pC2,aC,aRad,nSin,nCos,bVert); break; 3053 case SDRCROOK_STRETCH: CrookStretchXPoint(rPnt,pC1,pC2,aC,aRad,nSin,nCos,bVert,aMarkRect); break; 3054 } // switch 3055 } 3056 } 3057 3058 void SdrDragCrook::MoveSdrDrag(const Point& rPnt) 3059 { 3060 if (DragStat().CheckMinMoved(rPnt)) 3061 { 3062 Point aPnt(rPnt); 3063 bool bNeuMoveOnly=getSdrDragView().IsMoveOnlyDragging(); 3064 bAtCenter=false; 3065 SdrCrookMode eNeuMode=getSdrDragView().GetCrookMode(); 3066 bool bNeuContortion=!bNeuMoveOnly && ((bContortionAllowed && !getSdrDragView().IsCrookNoContortion()) || !bNoContortionAllowed); 3067 bResize=!getSdrDragView().IsOrtho() && bResizeAllowed && !bNeuMoveOnly; 3068 bool bNeuRotate=bRotateAllowed && !bNeuContortion && !bNeuMoveOnly && eNeuMode==SDRCROOK_ROTATE; 3069 long nSA=0; 3070 3071 if (nSA==0) 3072 aPnt=GetSnapPos(aPnt); 3073 3074 Point aNeuCenter(aMarkCenter.X(),aStart.Y()); 3075 3076 if (bVertical) 3077 { 3078 aNeuCenter.X()=aStart.X(); 3079 aNeuCenter.Y()=aMarkCenter.Y(); 3080 } 3081 3082 if (!getSdrDragView().IsCrookAtCenter()) 3083 { 3084 switch (GetDragHdlKind()) 3085 { 3086 case HDL_UPLFT: aNeuCenter.X()=aMarkRect.Right(); bLft=true; break; 3087 case HDL_UPPER: aNeuCenter.Y()=aMarkRect.Bottom(); bUpr=true; break; 3088 case HDL_UPRGT: aNeuCenter.X()=aMarkRect.Left(); bRgt=true; break; 3089 case HDL_LEFT : aNeuCenter.X()=aMarkRect.Right(); bLft=true; break; 3090 case HDL_RIGHT: aNeuCenter.X()=aMarkRect.Left(); bRgt=true; break; 3091 case HDL_LWLFT: aNeuCenter.X()=aMarkRect.Right(); bLft=true; break; 3092 case HDL_LOWER: aNeuCenter.Y()=aMarkRect.Top(); bLwr=true; break; 3093 case HDL_LWRGT: aNeuCenter.X()=aMarkRect.Left(); bRgt=true; break; 3094 default: bAtCenter=true; 3095 } 3096 } 3097 else 3098 bAtCenter=true; 3099 3100 Fraction aNeuFact(1,1); 3101 long dx1=aPnt.X()-aNeuCenter.X(); 3102 long dy1=aPnt.Y()-aNeuCenter.Y(); 3103 bValid=bVertical ? dx1!=0 : dy1!=0; 3104 3105 if (bValid) 3106 { 3107 if (bVertical) 3108 bValid=Abs(dx1)*100>Abs(dy1); 3109 else 3110 bValid=Abs(dy1)*100>Abs(dx1); 3111 } 3112 3113 long nNeuRad=0; 3114 nWink=0; 3115 3116 if (bValid) 3117 { 3118 double a=0; // Steigung des Radius 3119 long nPntWink=0; 3120 3121 if (bVertical) 3122 { 3123 a=((double)dy1)/((double)dx1); // Steigung des Radius 3124 nNeuRad=((long)(dy1*a)+dx1) /2; 3125 aNeuCenter.X()+=nNeuRad; 3126 nPntWink=GetAngle(aPnt-aNeuCenter); 3127 } 3128 else 3129 { 3130 a=((double)dx1)/((double)dy1); // Steigung des Radius 3131 nNeuRad=((long)(dx1*a)+dy1) /2; 3132 aNeuCenter.Y()+=nNeuRad; 3133 nPntWink=GetAngle(aPnt-aNeuCenter)-9000; 3134 } 3135 3136 if (!bAtCenter) 3137 { 3138 if (nNeuRad<0) 3139 { 3140 if (bRgt) nPntWink+=18000; 3141 if (bLft) nPntWink=18000-nPntWink; 3142 if (bLwr) nPntWink=-nPntWink; 3143 } 3144 else 3145 { 3146 if (bRgt) nPntWink=-nPntWink; 3147 if (bUpr) nPntWink=18000-nPntWink; 3148 if (bLwr) nPntWink+=18000; 3149 } 3150 3151 nPntWink=NormAngle360(nPntWink); 3152 } 3153 else 3154 { 3155 if (nNeuRad<0) nPntWink+=18000; 3156 if (bVertical) nPntWink=18000-nPntWink; 3157 nPntWink=NormAngle180(nPntWink); 3158 nPntWink=Abs(nPntWink); 3159 } 3160 3161 double nUmfang=2*Abs(nNeuRad)*nPi; 3162 3163 if (bResize) 3164 { 3165 if (nSA!=0) 3166 { // Winkelfang 3167 long nWink0=nPntWink; 3168 nPntWink+=nSA/2; 3169 nPntWink/=nSA; 3170 nPntWink*=nSA; 3171 BigInt a2(nNeuRad); 3172 a2*=BigInt(nWink); 3173 a2/=BigInt(nWink0); 3174 nNeuRad=long(a2); 3175 3176 if (bVertical) 3177 aNeuCenter.X()=aStart.X()+nNeuRad; 3178 else 3179 aNeuCenter.Y()=aStart.Y()+nNeuRad; 3180 } 3181 3182 long nMul=(long)(nUmfang*NormAngle360(nPntWink)/36000); 3183 3184 if (bAtCenter) 3185 nMul*=2; 3186 3187 aNeuFact=Fraction(nMul,nMarkSize); 3188 nWink=nPntWink; 3189 } 3190 else 3191 { 3192 nWink=(long)((nMarkSize*360/nUmfang)*100)/2; 3193 3194 if (nWink==0) 3195 bValid=false; 3196 3197 if (bValid && nSA!=0) 3198 { // Winkelfang 3199 long nWink0=nWink; 3200 nWink+=nSA/2; 3201 nWink/=nSA; 3202 nWink*=nSA; 3203 BigInt a2(nNeuRad); 3204 a2*=BigInt(nWink); 3205 a2/=BigInt(nWink0); 3206 nNeuRad=long(a2); 3207 3208 if (bVertical) 3209 aNeuCenter.X()=aStart.X()+nNeuRad; 3210 else 3211 aNeuCenter.Y()=aStart.Y()+nNeuRad; 3212 } 3213 } 3214 } 3215 3216 if (nWink==0 || nNeuRad==0) 3217 bValid=false; 3218 3219 if (!bValid) 3220 nNeuRad=0; 3221 3222 if (!bValid && bResize) 3223 { 3224 long nMul=bVertical ? dy1 : dx1; 3225 3226 if (bLft || bUpr) 3227 nMul=-nMul; 3228 3229 long nDiv=nMarkSize; 3230 3231 if (bAtCenter) 3232 { 3233 nMul*=2; 3234 nMul=Abs(nMul); 3235 } 3236 3237 aNeuFact=Fraction(nMul,nDiv); 3238 } 3239 3240 if (aNeuCenter!=aCenter || bNeuContortion!=bContortion || aNeuFact!=aFact || 3241 bNeuMoveOnly != getMoveOnly() || bNeuRotate!=bRotate || eNeuMode!=eMode) 3242 { 3243 Hide(); 3244 setMoveOnly(bNeuMoveOnly); 3245 bRotate=bNeuRotate; 3246 eMode=eNeuMode; 3247 bContortion=bNeuContortion; 3248 aCenter=aNeuCenter; 3249 aFact=aNeuFact; 3250 aRad=Point(nNeuRad,nNeuRad); 3251 bResize=aFact!=Fraction(1,1) && aFact.GetDenominator()!=0 && aFact.IsValid(); 3252 DragStat().NextMove(aPnt); 3253 Show(); 3254 } 3255 } 3256 } 3257 3258 void SdrDragCrook::applyCurrentTransformationToSdrObject(SdrObject& rTarget) 3259 { 3260 const bool bDoResize(aFact!=Fraction(1,1)); 3261 const bool bDoCrook(aCenter!=aMarkCenter && aRad.X()!=0 && aRad.Y()!=0); 3262 3263 if (bDoCrook || bDoResize) 3264 { 3265 if (bDoResize) 3266 { 3267 Fraction aFact1(1,1); 3268 3269 if (bContortion) 3270 { 3271 if (bVertical) 3272 { 3273 rTarget.Resize(aCenter,aFact1,aFact); 3274 } 3275 else 3276 { 3277 rTarget.Resize(aCenter,aFact,aFact1); 3278 } 3279 } 3280 else 3281 { 3282 Point aCtr0(rTarget.GetSnapRect().Center()); 3283 Point aCtr1(aCtr0); 3284 3285 if (bVertical) 3286 { 3287 ResizePoint(aCtr1,aCenter,aFact1,aFact); 3288 } 3289 else 3290 { 3291 ResizePoint(aCtr1,aCenter,aFact,aFact1); 3292 } 3293 3294 Size aSiz(aCtr1.X()-aCtr0.X(),aCtr1.Y()-aCtr0.Y()); 3295 3296 rTarget.Move(aSiz); 3297 } 3298 } 3299 3300 if (bDoCrook) 3301 { 3302 const Rectangle aLocalMarkRect(getSdrDragView().GetMarkedObjRect()); 3303 const bool bLocalRotate(!bContortion && eMode == SDRCROOK_ROTATE && getSdrDragView().IsRotateAllowed(false)); 3304 3305 getSdrDragView().ImpCrookObj(&rTarget,aCenter,aRad,eMode,bVertical,!bContortion,bLocalRotate,aLocalMarkRect); 3306 } 3307 } 3308 } 3309 3310 void SdrDragCrook::applyCurrentTransformationToPolyPolygon(basegfx::B2DPolyPolygon& rTarget) 3311 { 3312 // use helper derived from old stuff 3313 _MovAllPoints(rTarget); 3314 } 3315 3316 bool SdrDragCrook::EndSdrDrag(bool bCopy) 3317 { 3318 Hide(); 3319 3320 if (bResize && aFact==Fraction(1,1)) 3321 bResize=false; 3322 3323 const bool bUndo = getSdrDragView().IsUndoEnabled(); 3324 3325 bool bDoCrook=aCenter!=aMarkCenter && aRad.X()!=0 && aRad.Y()!=0; 3326 3327 if (bDoCrook || bResize) 3328 { 3329 if (bResize && bUndo) 3330 { 3331 XubString aStr; 3332 ImpTakeDescriptionStr(!bContortion?STR_EditCrook:STR_EditCrookContortion,aStr); 3333 3334 if (bCopy) 3335 aStr+=ImpGetResStr(STR_EditWithCopy); 3336 3337 getSdrDragView().BegUndo(aStr); 3338 } 3339 3340 if (bResize) 3341 { 3342 Fraction aFact1(1,1); 3343 3344 if (bContortion) 3345 { 3346 if (bVertical) 3347 getSdrDragView().ResizeMarkedObj(aCenter,aFact1,aFact,bCopy); 3348 else 3349 getSdrDragView().ResizeMarkedObj(aCenter,aFact,aFact1,bCopy); 3350 } 3351 else 3352 { 3353 if (bCopy) 3354 getSdrDragView().CopyMarkedObj(); 3355 3356 sal_uLong nMarkAnz=getSdrDragView().GetMarkedObjectList().GetMarkCount(); 3357 3358 for (sal_uLong nm=0; nm<nMarkAnz; nm++) 3359 { 3360 SdrMark* pM=getSdrDragView().GetMarkedObjectList().GetMark(nm); 3361 SdrObject* pO=pM->GetMarkedSdrObj(); 3362 Point aCtr0(pO->GetSnapRect().Center()); 3363 Point aCtr1(aCtr0); 3364 3365 if (bVertical) 3366 ResizePoint(aCtr1,aCenter,aFact1,aFact); 3367 else 3368 ResizePoint(aCtr1,aCenter,aFact,aFact1); 3369 3370 Size aSiz(aCtr1.X()-aCtr0.X(),aCtr1.Y()-aCtr0.Y()); 3371 if( bUndo ) 3372 AddUndo(getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoMoveObject(*pO,aSiz)); 3373 pO->Move(aSiz); 3374 } 3375 } 3376 3377 bCopy=false; 3378 } 3379 3380 if (bDoCrook) 3381 { 3382 getSdrDragView().CrookMarkedObj(aCenter,aRad,eMode,bVertical,!bContortion,bCopy); 3383 getSdrDragView().SetLastCrookCenter(aCenter); 3384 } 3385 3386 if (bResize && bUndo) 3387 getSdrDragView().EndUndo(); 3388 3389 return true; 3390 } 3391 3392 return false; 3393 } 3394 3395 Pointer SdrDragCrook::GetSdrDragPointer() const 3396 { 3397 return Pointer(POINTER_CROOK); 3398 } 3399 3400 //////////////////////////////////////////////////////////////////////////////////////////////////// 3401 3402 TYPEINIT1(SdrDragDistort,SdrDragMethod); 3403 3404 SdrDragDistort::SdrDragDistort(SdrDragView& rNewView) 3405 : SdrDragMethod(rNewView), 3406 nPolyPt(0), 3407 bContortionAllowed(false), 3408 bNoContortionAllowed(false), 3409 bContortion(false) 3410 { 3411 } 3412 3413 void SdrDragDistort::TakeSdrDragComment(XubString& rStr) const 3414 { 3415 ImpTakeDescriptionStr(STR_DragMethDistort, rStr); 3416 3417 XubString aStr; 3418 3419 rStr.AppendAscii(" (x="); 3420 getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDX(), aStr); 3421 rStr += aStr; 3422 rStr.AppendAscii(" y="); 3423 getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDY(), aStr); 3424 rStr += aStr; 3425 rStr += sal_Unicode(')'); 3426 3427 if(getSdrDragView().IsDragWithCopy()) 3428 rStr += ImpGetResStr(STR_EditWithCopy); 3429 } 3430 3431 void SdrDragDistort::createSdrDragEntries() 3432 { 3433 // Add extended frame raster first, so it will be behind objects 3434 if(getSdrDragView().GetSdrPageView()) 3435 { 3436 const basegfx::B2DPolyPolygon aDragRaster(impCreateDragRaster(*getSdrDragView().GetSdrPageView(), GetMarkedRect())); 3437 3438 if(aDragRaster.count()) 3439 { 3440 addSdrDragEntry(new SdrDragEntryPolyPolygon(aDragRaster)); 3441 } 3442 } 3443 3444 // call parent 3445 SdrDragMethod::createSdrDragEntries(); 3446 } 3447 3448 bool SdrDragDistort::BeginSdrDrag() 3449 { 3450 bContortionAllowed=getSdrDragView().IsDistortAllowed(false); 3451 bNoContortionAllowed=getSdrDragView().IsDistortAllowed(true); 3452 3453 if (bContortionAllowed || bNoContortionAllowed) 3454 { 3455 SdrHdlKind eKind=GetDragHdlKind(); 3456 nPolyPt=0xFFFF; 3457 3458 if (eKind==HDL_UPLFT) nPolyPt=0; 3459 if (eKind==HDL_UPRGT) nPolyPt=1; 3460 if (eKind==HDL_LWRGT) nPolyPt=2; 3461 if (eKind==HDL_LWLFT) nPolyPt=3; 3462 if (nPolyPt>3) return false; 3463 3464 aMarkRect=GetMarkedRect(); 3465 aDistortedRect=XPolygon(aMarkRect); 3466 Show(); 3467 return true; 3468 } 3469 else 3470 { 3471 return false; 3472 } 3473 } 3474 3475 void SdrDragDistort::_MovAllPoints(basegfx::B2DPolyPolygon& rTarget) 3476 { 3477 if (bContortion) 3478 { 3479 SdrPageView* pPV = getSdrDragView().GetSdrPageView(); 3480 3481 if(pPV) 3482 { 3483 if (pPV->HasMarkedObjPageView()) 3484 { 3485 basegfx::B2DPolyPolygon aDragPolygon(rTarget); 3486 const basegfx::B2DRange aOriginalRange(aMarkRect.Left(), aMarkRect.Top(), aMarkRect.Right(), aMarkRect.Bottom()); 3487 const basegfx::B2DPoint aTopLeft(aDistortedRect[0].X(), aDistortedRect[0].Y()); 3488 const basegfx::B2DPoint aTopRight(aDistortedRect[1].X(), aDistortedRect[1].Y()); 3489 const basegfx::B2DPoint aBottomLeft(aDistortedRect[3].X(), aDistortedRect[3].Y()); 3490 const basegfx::B2DPoint aBottomRight(aDistortedRect[2].X(), aDistortedRect[2].Y()); 3491 3492 aDragPolygon = basegfx::tools::distort(aDragPolygon, aOriginalRange, aTopLeft, aTopRight, aBottomLeft, aBottomRight); 3493 rTarget = aDragPolygon; 3494 } 3495 } 3496 } 3497 } 3498 3499 void SdrDragDistort::MoveSdrDrag(const Point& rPnt) 3500 { 3501 if (DragStat().CheckMinMoved(rPnt)) 3502 { 3503 Point aPnt(GetSnapPos(rPnt)); 3504 3505 if (getSdrDragView().IsOrtho()) 3506 OrthoDistance8(DragStat().GetStart(),aPnt,getSdrDragView().IsBigOrtho()); 3507 3508 bool bNeuContortion=(bContortionAllowed && !getSdrDragView().IsCrookNoContortion()) || !bNoContortionAllowed; 3509 3510 if (bNeuContortion!=bContortion || aDistortedRect[nPolyPt]!=aPnt) 3511 { 3512 Hide(); 3513 aDistortedRect[nPolyPt]=aPnt; 3514 bContortion=bNeuContortion; 3515 DragStat().NextMove(aPnt); 3516 Show(); 3517 } 3518 } 3519 } 3520 3521 bool SdrDragDistort::EndSdrDrag(bool bCopy) 3522 { 3523 Hide(); 3524 bool bDoDistort=DragStat().GetDX()!=0 || DragStat().GetDY()!=0; 3525 3526 if (bDoDistort) 3527 { 3528 getSdrDragView().DistortMarkedObj(aMarkRect,aDistortedRect,!bContortion,bCopy); 3529 return true; 3530 } 3531 3532 return false; 3533 } 3534 3535 Pointer SdrDragDistort::GetSdrDragPointer() const 3536 { 3537 return Pointer(POINTER_REFHAND); 3538 } 3539 3540 void SdrDragDistort::applyCurrentTransformationToSdrObject(SdrObject& rTarget) 3541 { 3542 const bool bDoDistort(DragStat().GetDX()!=0 || DragStat().GetDY()!=0); 3543 3544 if (bDoDistort) 3545 { 3546 getSdrDragView().ImpDistortObj(&rTarget, aMarkRect, aDistortedRect, !bContortion); 3547 } 3548 } 3549 3550 void SdrDragDistort::applyCurrentTransformationToPolyPolygon(basegfx::B2DPolyPolygon& rTarget) 3551 { 3552 // use helper derived from old stuff 3553 _MovAllPoints(rTarget); 3554 } 3555 3556 //////////////////////////////////////////////////////////////////////////////////////////////////// 3557 3558 TYPEINIT1(SdrDragCrop,SdrDragResize); 3559 3560 SdrDragCrop::SdrDragCrop(SdrDragView& rNewView) 3561 : SdrDragResize(rNewView) 3562 { 3563 // switch off solid dragging for crop; it just makes no sense since showing 3564 // a 50% transparent object above the original will not be visible 3565 setSolidDraggingActive(false); 3566 } 3567 3568 void SdrDragCrop::TakeSdrDragComment(XubString& rStr) const 3569 { 3570 ImpTakeDescriptionStr(STR_DragMethCrop, rStr); 3571 3572 XubString aStr; 3573 3574 rStr.AppendAscii(" (x="); 3575 getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDX(), aStr); 3576 rStr += aStr; 3577 rStr.AppendAscii(" y="); 3578 getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDY(), aStr); 3579 rStr += aStr; 3580 rStr += sal_Unicode(')'); 3581 3582 if(getSdrDragView().IsDragWithCopy()) 3583 rStr += ImpGetResStr(STR_EditWithCopy); 3584 } 3585 3586 bool SdrDragCrop::EndSdrDrag(bool bCopy) 3587 { 3588 Hide(); 3589 3590 if( DragStat().GetDX()==0 && DragStat().GetDY()==0 ) 3591 return false; 3592 3593 const SdrMarkList& rMarkList = getSdrDragView().GetMarkedObjectList(); 3594 3595 if( rMarkList.GetMarkCount() != 1 ) 3596 return false; 3597 3598 SdrGrafObj* pObj = dynamic_cast<SdrGrafObj*>( rMarkList.GetMark( 0 )->GetMarkedSdrObj() ); 3599 3600 if( !pObj || (pObj->GetGraphicType() == GRAPHIC_NONE) || (pObj->GetGraphicType() == GRAPHIC_DEFAULT) ) 3601 return false; 3602 3603 const GraphicObject& rGraphicObject = pObj->GetGraphicObject(); 3604 const MapMode aMapMode100thmm(MAP_100TH_MM); 3605 Size aGraphicSize(rGraphicObject.GetPrefSize()); 3606 3607 if( MAP_PIXEL == rGraphicObject.GetPrefMapMode().GetMapUnit() ) 3608 aGraphicSize = Application::GetDefaultDevice()->PixelToLogic( aGraphicSize, aMapMode100thmm ); 3609 else 3610 aGraphicSize = Application::GetDefaultDevice()->LogicToLogic( aGraphicSize, rGraphicObject.GetPrefMapMode(), aMapMode100thmm); 3611 3612 if( aGraphicSize.nA == 0 || aGraphicSize.nB == 0 ) 3613 return false; 3614 3615 const SdrGrafCropItem& rOldCrop = (const SdrGrafCropItem&)pObj->GetMergedItem(SDRATTR_GRAFCROP); 3616 3617 const bool bUndo = getSdrDragView().IsUndoEnabled(); 3618 3619 if( bUndo ) 3620 { 3621 String aUndoStr; 3622 ImpTakeDescriptionStr(STR_DragMethCrop, aUndoStr); 3623 3624 getSdrDragView().BegUndo( aUndoStr ); 3625 getSdrDragView().AddUndo( getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoGeoObject( *pObj ) ); 3626 } 3627 3628 Rectangle aOldRect( pObj->GetLogicRect() ); 3629 getSdrDragView().ResizeMarkedObj(DragStat().Ref1(),aXFact,aYFact,bCopy); 3630 Rectangle aNewRect( pObj->GetLogicRect() ); 3631 3632 double fScaleX = ( aGraphicSize.Width() - rOldCrop.GetLeft() - rOldCrop.GetRight() ) / (double)aOldRect.GetWidth(); 3633 double fScaleY = ( aGraphicSize.Height() - rOldCrop.GetTop() - rOldCrop.GetBottom() ) / (double)aOldRect.GetHeight(); 3634 3635 sal_Int32 nDiffLeft = aNewRect.nLeft - aOldRect.nLeft; 3636 sal_Int32 nDiffTop = aNewRect.nTop - aOldRect.nTop; 3637 sal_Int32 nDiffRight = aNewRect.nRight - aOldRect.nRight; 3638 sal_Int32 nDiffBottom = aNewRect.nBottom - aOldRect.nBottom; 3639 3640 sal_Int32 nLeftCrop = static_cast<sal_Int32>( rOldCrop.GetLeft() + nDiffLeft * fScaleX ); 3641 sal_Int32 nTopCrop = static_cast<sal_Int32>( rOldCrop.GetTop() + nDiffTop * fScaleY ); 3642 sal_Int32 nRightCrop = static_cast<sal_Int32>( rOldCrop.GetRight() - nDiffRight * fScaleX ); 3643 sal_Int32 nBottomCrop = static_cast<sal_Int32>( rOldCrop.GetBottom() - nDiffBottom * fScaleY ); 3644 3645 SfxItemPool& rPool = getSdrDragView().GetModel()->GetItemPool(); 3646 SfxItemSet aSet( rPool, SDRATTR_GRAFCROP, SDRATTR_GRAFCROP ); 3647 aSet.Put( SdrGrafCropItem( nLeftCrop, nTopCrop, nRightCrop, nBottomCrop ) ); 3648 getSdrDragView().SetAttributes( aSet, false ); 3649 3650 if( bUndo ) 3651 getSdrDragView().EndUndo(); 3652 3653 return true; 3654 } 3655 3656 Pointer SdrDragCrop::GetSdrDragPointer() const 3657 { 3658 return Pointer(POINTER_CROP); 3659 } 3660 3661 //////////////////////////////////////////////////////////////////////////////////////////////////// 3662 // eof 3663