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