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