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