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