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