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