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