Version 3.6.0.2, tag libreoffice-3.6.0.2
[LibreOffice.git] / svx / source / svdraw / svddrgmt.cxx
blob4390fe9f2ced3ad6e3f98b1f90bc1eed47492083
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include "svddrgm1.hxx"
31 #include <math.h>
33 #ifndef _MATH_H
34 #define _MATH_H
35 #endif
36 #include <tools/bigint.hxx>
37 #include <vcl/svapp.hxx>
39 #include "svx/xattr.hxx"
40 #include <svx/xpoly.hxx>
41 #include <svx/svdetc.hxx>
42 #include <svx/svdtrans.hxx>
43 #include <svx/svdundo.hxx>
44 #include <svx/svdmark.hxx>
45 #include <svx/svdocapt.hxx>
46 #include <svx/svdpagv.hxx>
47 #include "svx/svdstr.hrc" // names taken from the resource
48 #include "svx/svdglob.hxx" // StringCache
49 #include <svx/svddrgv.hxx>
50 #include <svx/svdograf.hxx>
51 #include <svx/dialogs.hrc>
52 #include <svx/dialmgr.hxx>
53 #include <svx/sdgcpitm.hxx>
54 #include <basegfx/polygon/b2dpolygon.hxx>
55 #include <basegfx/polygon/b2dpolygontools.hxx>
56 #include <svx/sdr/overlay/overlaypolypolygon.hxx>
57 #include <svx/sdr/overlay/overlaymanager.hxx>
58 #include <svx/sdr/overlay/overlayrollingrectangle.hxx>
59 #include <svx/sdrpagewindow.hxx>
60 #include <svx/sdrpaintwindow.hxx>
61 #include <basegfx/matrix/b2dhommatrix.hxx>
62 #include <basegfx/polygon/b2dpolypolygontools.hxx>
63 #include <svx/sdr/contact/viewobjectcontact.hxx>
64 #include <svx/sdr/contact/viewcontact.hxx>
65 #include <svx/sdr/contact/displayinfo.hxx>
66 #include <svx/sdr/overlay/overlayprimitive2dsequenceobject.hxx>
67 #include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx>
68 #include <svx/sdr/contact/objectcontact.hxx>
69 #include "svx/svditer.hxx"
70 #include <svx/svdopath.hxx>
71 #include <svx/polypolygoneditor.hxx>
72 #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
73 #include <drawinglayer/primitive2d/transformprimitive2d.hxx>
74 #include <drawinglayer/primitive2d/markerarrayprimitive2d.hxx>
75 #include <svx/sdr/primitive2d/sdrattributecreator.hxx>
76 #include <svx/sdr/primitive2d/sdrdecompositiontools.hxx>
77 #include <svx/svdoole2.hxx>
78 #include <svx/svdovirt.hxx>
79 #include <svx/svdouno.hxx>
80 #include <svx/sdr/primitive2d/sdrprimitivetools.hxx>
81 #include <basegfx/matrix/b2dhommatrixtools.hxx>
82 #include <drawinglayer/attribute/sdrlineattribute.hxx>
83 #include <drawinglayer/attribute/sdrlinestartendattribute.hxx>
85 ////////////////////////////////////////////////////////////////////////////////////////////////////
87 SdrDragEntry::SdrDragEntry()
88 : mbAddToTransparent(false)
92 SdrDragEntry::~SdrDragEntry()
96 ////////////////////////////////////////////////////////////////////////////////////////////////////
98 SdrDragEntryPolyPolygon::SdrDragEntryPolyPolygon(const basegfx::B2DPolyPolygon& rOriginalPolyPolygon)
99 : SdrDragEntry(),
100 maOriginalPolyPolygon(rOriginalPolyPolygon)
104 SdrDragEntryPolyPolygon::~SdrDragEntryPolyPolygon()
108 drawinglayer::primitive2d::Primitive2DSequence SdrDragEntryPolyPolygon::createPrimitive2DSequenceInCurrentState(SdrDragMethod& rDragMethod)
110 drawinglayer::primitive2d::Primitive2DSequence aRetval;
112 if(maOriginalPolyPolygon.count())
114 basegfx::B2DPolyPolygon aCopy(maOriginalPolyPolygon);
115 const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
117 rDragMethod.applyCurrentTransformationToPolyPolygon(aCopy);
118 basegfx::BColor aColA(aSvtOptionsDrawinglayer.GetStripeColorA().getBColor());
119 basegfx::BColor aColB(aSvtOptionsDrawinglayer.GetStripeColorB().getBColor());
120 const double fStripeLength(aSvtOptionsDrawinglayer.GetStripeLength());
122 if(Application::GetSettings().GetStyleSettings().GetHighContrastMode())
124 aColA = aColB = Application::GetSettings().GetStyleSettings().GetHighlightColor().getBColor();
125 aColB.invert();
128 drawinglayer::primitive2d::Primitive2DReference aPolyPolygonMarkerPrimitive2D(
129 new drawinglayer::primitive2d::PolyPolygonMarkerPrimitive2D(aCopy, aColA, aColB, fStripeLength));
131 aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aPolyPolygonMarkerPrimitive2D, 1);
134 return aRetval;
137 ////////////////////////////////////////////////////////////////////////////////////////////////////
139 SdrDragEntrySdrObject::SdrDragEntrySdrObject(const SdrObject& rOriginal, sdr::contact::ObjectContact& rObjectContact, bool bModify)
140 : SdrDragEntry(),
141 maOriginal(rOriginal),
142 mpClone(0),
143 mrObjectContact(rObjectContact),
144 mbModify(bModify)
146 // add SdrObject parts to transparent overlay stuff
147 setAddToTransparent(true);
150 SdrDragEntrySdrObject::~SdrDragEntrySdrObject()
152 if(mpClone)
154 SdrObject::Free(mpClone);
158 drawinglayer::primitive2d::Primitive2DSequence SdrDragEntrySdrObject::createPrimitive2DSequenceInCurrentState(SdrDragMethod& rDragMethod)
160 // for the moment, i need to re-create the clone in all cases. I need to figure
161 // out when clone and original have the same class, so that i can use operator=
162 // in those cases
164 const SdrObject* pSource = &maOriginal;
166 if(mpClone)
168 SdrObject::Free(mpClone);
169 mpClone = 0;
172 if(mbModify)
174 if(!mpClone)
176 mpClone = maOriginal.getFullDragClone();
179 // apply original transformation, implemented at the DragMethods
180 rDragMethod.applyCurrentTransformationToSdrObject(*mpClone);
182 // choose source for geometry data
183 pSource = mpClone;
186 // get VOC and Primitive2DSequence
187 sdr::contact::ViewContact& rVC = pSource->GetViewContact();
188 sdr::contact::ViewObjectContact& rVOC = rVC.GetViewObjectContact(mrObjectContact);
189 sdr::contact::DisplayInfo aDisplayInfo;
191 // Do not use the last ViewPort set at the OC from the last ProcessDisplay(),
192 // here we want the complete primitive sequence without visibility clippings
193 mrObjectContact.resetViewPort();
195 return rVOC.getPrimitive2DSequenceHierarchy(aDisplayInfo);
198 ////////////////////////////////////////////////////////////////////////////////////////////////////
200 SdrDragEntryPrimitive2DSequence::SdrDragEntryPrimitive2DSequence(
201 const drawinglayer::primitive2d::Primitive2DSequence& rSequence,
202 bool bAddToTransparent)
203 : SdrDragEntry(),
204 maPrimitive2DSequence(rSequence)
206 // add parts to transparent overlay stuff if necessary
207 setAddToTransparent(bAddToTransparent);
210 SdrDragEntryPrimitive2DSequence::~SdrDragEntryPrimitive2DSequence()
214 drawinglayer::primitive2d::Primitive2DSequence SdrDragEntryPrimitive2DSequence::createPrimitive2DSequenceInCurrentState(SdrDragMethod& rDragMethod)
216 drawinglayer::primitive2d::Primitive2DReference aTransformPrimitive2D(
217 new drawinglayer::primitive2d::TransformPrimitive2D(
218 rDragMethod.getCurrentTransformation(),
219 maPrimitive2DSequence));
221 return drawinglayer::primitive2d::Primitive2DSequence(&aTransformPrimitive2D, 1);
224 ////////////////////////////////////////////////////////////////////////////////////////////////////
226 SdrDragEntryPointGlueDrag::SdrDragEntryPointGlueDrag(const std::vector< basegfx::B2DPoint >& rPositions, bool bIsPointDrag)
227 : maPositions(rPositions),
228 mbIsPointDrag(bIsPointDrag)
230 // add SdrObject parts to transparent overlay stuff
231 setAddToTransparent(true);
234 SdrDragEntryPointGlueDrag::~SdrDragEntryPointGlueDrag()
238 drawinglayer::primitive2d::Primitive2DSequence SdrDragEntryPointGlueDrag::createPrimitive2DSequenceInCurrentState(SdrDragMethod& rDragMethod)
240 drawinglayer::primitive2d::Primitive2DSequence aRetval;
242 if(!maPositions.empty())
244 basegfx::B2DPolygon aPolygon;
245 sal_uInt32 a(0);
247 for(a = 0; a < maPositions.size(); a++)
249 aPolygon.append(maPositions[a]);
252 basegfx::B2DPolyPolygon aPolyPolygon(aPolygon);
254 rDragMethod.applyCurrentTransformationToPolyPolygon(aPolyPolygon);
256 const basegfx::B2DPolygon aTransformed(aPolyPolygon.getB2DPolygon(0));
257 std::vector< basegfx::B2DPoint > aTransformedPositions;
259 aTransformedPositions.reserve(aTransformed.count());
261 for(a = 0; a < aTransformed.count(); a++)
263 aTransformedPositions.push_back(aTransformed.getB2DPoint(a));
266 if(mbIsPointDrag)
268 const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
269 basegfx::BColor aColor(aSvtOptionsDrawinglayer.GetStripeColorA().getBColor());
271 if(Application::GetSettings().GetStyleSettings().GetHighContrastMode())
273 aColor = Application::GetSettings().GetStyleSettings().GetHighlightColor().getBColor();
276 drawinglayer::primitive2d::Primitive2DReference aMarkerArrayPrimitive2D(
277 new drawinglayer::primitive2d::MarkerArrayPrimitive2D(aTransformedPositions,
278 drawinglayer::primitive2d::createDefaultCross_3x3(aColor)));
280 aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aMarkerArrayPrimitive2D, 1);
282 else
284 drawinglayer::primitive2d::Primitive2DReference aMarkerArrayPrimitive2D(
285 new drawinglayer::primitive2d::MarkerArrayPrimitive2D(aTransformedPositions,
286 SdrHdl::createGluePointBitmap()));
287 aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aMarkerArrayPrimitive2D, 1);
291 return aRetval;
294 ////////////////////////////////////////////////////////////////////////////////////////////////////
296 TYPEINIT0(SdrDragMethod);
298 void SdrDragMethod::resetSdrDragEntries()
300 // clear entries; creation is on demand
301 clearSdrDragEntries();
304 basegfx::B2DRange SdrDragMethod::getCurrentRange() const
306 return getB2DRangeFromOverlayObjectList();
309 void SdrDragMethod::createSdrDragEntries()
311 if(getSdrDragView().GetSdrPageView() && getSdrDragView().GetSdrPageView()->HasMarkedObjPageView())
313 if(getSdrDragView().IsDraggingPoints())
315 createSdrDragEntries_PointDrag();
317 else if(getSdrDragView().IsDraggingGluePoints())
319 createSdrDragEntries_GlueDrag();
321 else
323 if(getSolidDraggingActive())
325 createSdrDragEntries_SolidDrag();
327 else
329 createSdrDragEntries_PolygonDrag();
335 void SdrDragMethod::createSdrDragEntryForSdrObject(const SdrObject& rOriginal, sdr::contact::ObjectContact& rObjectContact, bool bModify)
337 // add full object drag; Clone() at the object has to work
338 // for this
339 addSdrDragEntry(new SdrDragEntrySdrObject(rOriginal, rObjectContact, bModify));
342 void SdrDragMethod::createSdrDragEntries_SolidDrag()
344 const sal_uInt32 nMarkAnz(getSdrDragView().GetMarkedObjectCount());
345 SdrPageView* pPV = getSdrDragView().GetSdrPageView();
347 if(pPV)
349 for(sal_uInt32 a(0); a < nMarkAnz; a++)
351 SdrMark* pM = getSdrDragView().GetSdrMarkByIndex(a);
353 if(pM->GetPageView() == pPV)
355 const SdrObject* pObject = pM->GetMarkedSdrObj();
357 if(pObject)
359 if(pPV->PageWindowCount())
361 sdr::contact::ObjectContact& rOC = pPV->GetPageWindow(0)->GetObjectContact();
362 SdrObjListIter aIter(*pObject);
364 while(aIter.IsMore())
366 SdrObject* pCandidate = aIter.Next();
368 if(pCandidate)
370 const bool bSuppressFullDrag(!pCandidate->supportsFullDrag());
371 bool bAddWireframe(bSuppressFullDrag);
373 if(!bAddWireframe && !pCandidate->HasLineStyle())
375 // add wireframe for objects without outline
376 bAddWireframe = true;
379 if(!bSuppressFullDrag)
381 // add full object drag; Clone() at the object has to work
382 // for this
383 createSdrDragEntryForSdrObject(*pCandidate, rOC, true);
386 if(bAddWireframe)
388 // when dragging a 50% transparent copy of a filled or not filled object without
389 // outline, this is normally hard to see. Add extra wireframe in that case. This
390 // works nice e.g. with text frames etc.
391 addSdrDragEntry(new SdrDragEntryPolyPolygon(pCandidate->TakeXorPoly()));
402 void SdrDragMethod::createSdrDragEntries_PolygonDrag()
404 const sal_uInt32 nMarkAnz(getSdrDragView().GetMarkedObjectCount());
405 bool bNoPolygons(getSdrDragView().IsNoDragXorPolys() || nMarkAnz > getSdrDragView().GetDragXorPolyLimit());
406 basegfx::B2DPolyPolygon aResult;
407 sal_uInt32 nPointCount(0);
409 for(sal_uInt32 a(0); !bNoPolygons && a < nMarkAnz; a++)
411 SdrMark* pM = getSdrDragView().GetSdrMarkByIndex(a);
413 if(pM->GetPageView() == getSdrDragView().GetSdrPageView())
415 const basegfx::B2DPolyPolygon aNewPolyPolygon(pM->GetMarkedSdrObj()->TakeXorPoly());
417 for(sal_uInt32 b(0); b < aNewPolyPolygon.count(); b++)
419 nPointCount += aNewPolyPolygon.getB2DPolygon(b).count();
422 if(nPointCount > getSdrDragView().GetDragXorPointLimit())
424 bNoPolygons = true;
427 if(!bNoPolygons)
429 aResult.append(aNewPolyPolygon);
434 if(bNoPolygons)
436 const Rectangle aR(getSdrDragView().GetSdrPageView()->MarkSnap());
437 const basegfx::B2DRange aNewRectangle(aR.Left(), aR.Top(), aR.Right(), aR.Bottom());
438 basegfx::B2DPolygon aNewPolygon(basegfx::tools::createPolygonFromRect(aNewRectangle));
440 aResult = basegfx::B2DPolyPolygon(basegfx::tools::expandToCurve(aNewPolygon));
443 if(aResult.count())
445 addSdrDragEntry(new SdrDragEntryPolyPolygon(aResult));
449 void SdrDragMethod::createSdrDragEntries_PointDrag()
451 const sal_uInt32 nMarkAnz(getSdrDragView().GetMarkedObjectCount());
452 std::vector< basegfx::B2DPoint > aPositions;
454 for(sal_uInt32 nm(0); nm < nMarkAnz; nm++)
456 SdrMark* pM = getSdrDragView().GetSdrMarkByIndex(nm);
458 if(pM->GetPageView() == getSdrDragView().GetSdrPageView())
460 const SdrUShortCont* pPts = pM->GetMarkedPoints();
462 if(pPts && pPts->GetCount())
464 const SdrObject* pObj = pM->GetMarkedSdrObj();
465 const SdrPathObj* pPath = dynamic_cast< const SdrPathObj* >(pObj);
467 if(pPath)
469 const basegfx::B2DPolyPolygon aPathXPP = pPath->GetPathPoly();
471 if(aPathXPP.count())
473 const sal_uInt32 nPtAnz(pPts->GetCount());
475 for(sal_uInt32 nPtNum(0); nPtNum < nPtAnz; nPtNum++)
477 sal_uInt32 nPolyNum, nPointNum;
478 const sal_uInt16 nObjPt(pPts->GetObject(nPtNum));
480 if(sdr::PolyPolygonEditor::GetRelativePolyPoint(aPathXPP, nObjPt, nPolyNum, nPointNum))
482 aPositions.push_back(aPathXPP.getB2DPolygon(nPolyNum).getB2DPoint(nPointNum));
491 if(!aPositions.empty())
493 addSdrDragEntry(new SdrDragEntryPointGlueDrag(aPositions, true));
497 void SdrDragMethod::createSdrDragEntries_GlueDrag()
499 const sal_uInt32 nMarkAnz(getSdrDragView().GetMarkedObjectCount());
500 std::vector< basegfx::B2DPoint > aPositions;
502 for(sal_uInt32 nm(0); nm < nMarkAnz; nm++)
504 SdrMark* pM = getSdrDragView().GetSdrMarkByIndex(nm);
506 if(pM->GetPageView() == getSdrDragView().GetSdrPageView())
508 const SdrUShortCont* pPts = pM->GetMarkedGluePoints();
510 if(pPts && pPts->GetCount())
512 const SdrObject* pObj = pM->GetMarkedSdrObj();
513 const SdrGluePointList* pGPL = pObj->GetGluePointList();
515 if(pGPL)
517 const sal_uInt32 nPtAnz(pPts->GetCount());
519 for(sal_uInt32 nPtNum(0); nPtNum < nPtAnz; nPtNum++)
521 const sal_uInt16 nObjPt(pPts->GetObject(nPtNum));
522 const sal_uInt16 nGlueNum(pGPL->FindGluePoint(nObjPt));
524 if(SDRGLUEPOINT_NOTFOUND != nGlueNum)
526 const Point aPoint((*pGPL)[nGlueNum].GetAbsolutePos(*pObj));
527 aPositions.push_back(basegfx::B2DPoint(aPoint.X(), aPoint.Y()));
535 if(!aPositions.empty())
537 addSdrDragEntry(new SdrDragEntryPointGlueDrag(aPositions, false));
541 void SdrDragMethod::ImpTakeDescriptionStr(sal_uInt16 nStrCacheID, XubString& rStr, sal_uInt16 nVal) const
543 sal_uInt16 nOpt=0;
544 if (IsDraggingPoints()) {
545 nOpt=IMPSDR_POINTSDESCRIPTION;
546 } else if (IsDraggingGluePoints()) {
547 nOpt=IMPSDR_GLUEPOINTSDESCRIPTION;
549 getSdrDragView().ImpTakeDescriptionStr(nStrCacheID,rStr,nVal,nOpt);
552 SdrObject* SdrDragMethod::GetDragObj() const
554 SdrObject* pObj=NULL;
555 if (getSdrDragView().pDragHdl!=NULL) pObj=getSdrDragView().pDragHdl->GetObj();
556 if (pObj==NULL) pObj=getSdrDragView().pMarkedObj;
557 return pObj;
560 SdrPageView* SdrDragMethod::GetDragPV() const
562 SdrPageView* pPV=NULL;
563 if (getSdrDragView().pDragHdl!=NULL) pPV=getSdrDragView().pDragHdl->GetPageView();
564 if (pPV==NULL) pPV=getSdrDragView().pMarkedPV;
565 return pPV;
568 void SdrDragMethod::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
570 // the original applies the transformation using TRGetBaseGeometry/TRSetBaseGeometry.
571 // Later this should be the only needed one for linear transforms (not for SdrDragCrook and
572 // SdrDragDistort, those are NOT linear). Currently, this can not yet be used since the
573 // special handling of rotate/mirror due to the not-being-able to handle it in the old
574 // drawinglayer stuff. Text would currently not correctly be mirrored in the preview.
575 basegfx::B2DHomMatrix aObjectTransform;
576 basegfx::B2DPolyPolygon aObjectPolyPolygon;
577 bool bPolyUsed(rTarget.TRGetBaseGeometry(aObjectTransform, aObjectPolyPolygon));
579 // apply transform to object transform
580 aObjectTransform *= getCurrentTransformation();
582 if(bPolyUsed)
584 // do something special since the object size is in the polygon
585 // break up matrix to get the scale
586 basegfx::B2DTuple aScale;
587 basegfx::B2DTuple aTranslate;
588 double fRotate, fShearX;
589 aObjectTransform.decompose(aScale, aTranslate, fRotate, fShearX);
591 // get polygon's position and size
592 const basegfx::B2DRange aPolyRange(aObjectPolyPolygon.getB2DRange());
594 // get the scaling factors (do not mirror, this is in the object transformation)
595 const double fScaleX(fabs(aScale.getX()) / (basegfx::fTools::equalZero(aPolyRange.getWidth()) ? 1.0 : aPolyRange.getWidth()));
596 const double fScaleY(fabs(aScale.getY()) / (basegfx::fTools::equalZero(aPolyRange.getHeight()) ? 1.0 : aPolyRange.getHeight()));
598 // prepare transform matrix for polygon
599 basegfx::B2DHomMatrix aPolyTransform(basegfx::tools::createTranslateB2DHomMatrix(
600 -aPolyRange.getMinX(), -aPolyRange.getMinY()));
601 aPolyTransform.scale(fScaleX, fScaleY);
603 // transform the polygon
604 aObjectPolyPolygon.transform(aPolyTransform);
607 rTarget.TRSetBaseGeometry(getCurrentTransformation() * aObjectTransform, aObjectPolyPolygon);
610 void SdrDragMethod::applyCurrentTransformationToPolyPolygon(basegfx::B2DPolyPolygon& rTarget)
612 // original uses CurrentTransformation
613 rTarget.transform(getCurrentTransformation());
616 SdrDragMethod::SdrDragMethod(SdrDragView& rNewView)
617 : maSdrDragEntries(),
618 maOverlayObjectList(),
619 mrSdrDragView(rNewView),
620 mbMoveOnly(false),
621 mbSolidDraggingActive(getSdrDragView().IsSolidDragging())
623 if(mbSolidDraggingActive && Application::GetSettings().GetStyleSettings().GetHighContrastMode())
625 // fallback to wireframe when high contrast is used
626 mbSolidDraggingActive = false;
630 SdrDragMethod::~SdrDragMethod()
632 clearSdrDragEntries();
635 void SdrDragMethod::Show()
637 getSdrDragView().ShowDragObj();
640 void SdrDragMethod::Hide()
642 getSdrDragView().HideDragObj();
645 basegfx::B2DHomMatrix SdrDragMethod::getCurrentTransformation()
647 return basegfx::B2DHomMatrix();
650 void SdrDragMethod::CancelSdrDrag()
652 Hide();
655 void SdrDragMethod::CreateOverlayGeometry(sdr::overlay::OverlayManager& rOverlayManager)
657 // create SdrDragEntries on demand
658 if(maSdrDragEntries.empty())
660 createSdrDragEntries();
663 // if there are entries, derive OverlayObjects from the entries, including
664 // modification from current interactive state
665 if(!maSdrDragEntries.empty())
667 drawinglayer::primitive2d::Primitive2DSequence aResult;
668 drawinglayer::primitive2d::Primitive2DSequence aResultTransparent;
670 for(sal_uInt32 a(0); a < maSdrDragEntries.size(); a++)
672 SdrDragEntry* pCandidate = maSdrDragEntries[a];
674 if(pCandidate)
676 const drawinglayer::primitive2d::Primitive2DSequence aCandidateResult(pCandidate->createPrimitive2DSequenceInCurrentState(*this));
678 if(aCandidateResult.hasElements())
680 if(pCandidate->getAddToTransparent())
682 drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(aResultTransparent, aCandidateResult);
684 else
686 drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(aResult, aCandidateResult);
692 if(DoAddConnectorOverlays())
694 const drawinglayer::primitive2d::Primitive2DSequence aConnectorOverlays(AddConnectorOverlays());
696 if(aConnectorOverlays.hasElements())
698 // add connector overlays to transparent part
699 drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(aResultTransparent, aConnectorOverlays);
703 if(aResult.hasElements())
705 sdr::overlay::OverlayObject* pNewOverlayObject = new sdr::overlay::OverlayPrimitive2DSequenceObject(aResult);
706 rOverlayManager.add(*pNewOverlayObject);
707 addToOverlayObjectList(*pNewOverlayObject);
710 if(aResultTransparent.hasElements())
712 drawinglayer::primitive2d::Primitive2DReference aUnifiedTransparencePrimitive2D(new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(aResultTransparent, 0.5));
713 aResultTransparent = drawinglayer::primitive2d::Primitive2DSequence(&aUnifiedTransparencePrimitive2D, 1);
715 sdr::overlay::OverlayObject* pNewOverlayObject = new sdr::overlay::OverlayPrimitive2DSequenceObject(aResultTransparent);
716 rOverlayManager.add(*pNewOverlayObject);
717 addToOverlayObjectList(*pNewOverlayObject);
721 // add DragStripes if necessary (help lines cross the page when dragging)
722 if(getSdrDragView().IsDragStripes())
724 Rectangle aActionRectangle;
725 getSdrDragView().TakeActionRect(aActionRectangle);
727 const basegfx::B2DPoint aTopLeft(aActionRectangle.Left(), aActionRectangle.Top());
728 const basegfx::B2DPoint aBottomRight(aActionRectangle.Right(), aActionRectangle.Bottom());
729 sdr::overlay::OverlayRollingRectangleStriped* pNew = new sdr::overlay::OverlayRollingRectangleStriped(
730 aTopLeft, aBottomRight, true, false);
732 rOverlayManager.add(*pNew);
733 addToOverlayObjectList(*pNew);
737 void SdrDragMethod::destroyOverlayGeometry()
739 clearOverlayObjectList();
742 bool SdrDragMethod::DoAddConnectorOverlays()
744 // these conditions are translated from SdrDragView::ImpDrawEdgeXor
745 const SdrMarkList& rMarkedNodes = getSdrDragView().GetEdgesOfMarkedNodes();
747 if(!rMarkedNodes.GetMarkCount())
749 return false;
752 if(!getSdrDragView().IsRubberEdgeDragging() && !getSdrDragView().IsDetailedEdgeDragging())
754 return false;
757 if(getSdrDragView().IsDraggingPoints() || getSdrDragView().IsDraggingGluePoints())
759 return false;
762 if(!getMoveOnly() && !(
763 IS_TYPE(SdrDragMove, this) || IS_TYPE(SdrDragResize, this) ||
764 IS_TYPE(SdrDragRotate,this) || IS_TYPE(SdrDragMirror,this)))
766 return false;
769 const bool bDetail(getSdrDragView().IsDetailedEdgeDragging() && getMoveOnly());
771 if(!bDetail && !getSdrDragView().IsRubberEdgeDragging())
773 return false;
776 // one more migrated from SdrEdgeObj::NspToggleEdgeXor
777 if(IS_TYPE(SdrDragObjOwn, this) || IS_TYPE(SdrDragMovHdl, this))
779 return false;
782 return true;
785 drawinglayer::primitive2d::Primitive2DSequence SdrDragMethod::AddConnectorOverlays()
787 drawinglayer::primitive2d::Primitive2DSequence aRetval;
788 const bool bDetail(getSdrDragView().IsDetailedEdgeDragging() && getMoveOnly());
789 const SdrMarkList& rMarkedNodes = getSdrDragView().GetEdgesOfMarkedNodes();
791 for(sal_uInt16 a(0); a < rMarkedNodes.GetMarkCount(); a++)
793 SdrMark* pEM = rMarkedNodes.GetMark(a);
795 if(pEM && pEM->GetMarkedSdrObj())
797 SdrEdgeObj* pEdge = dynamic_cast< SdrEdgeObj* >(pEM->GetMarkedSdrObj());
799 if(pEdge)
801 const basegfx::B2DPolygon aEdgePolygon(pEdge->ImplAddConnectorOverlay(*this, pEM->IsCon1(), pEM->IsCon2(), bDetail));
803 if(aEdgePolygon.count())
805 // this polygon is a temporary calculated connector path, so it is not possible to fetch
806 // the needed primitives directly from the pEdge object which does not get changed. If full
807 // drag is on, use the SdrObjects ItemSet to create a adequate representation
808 bool bUseSolidDragging(getSolidDraggingActive());
810 if(bUseSolidDragging)
812 // switch off solid dragging if connector is not visible
813 if(!pEdge->HasLineStyle())
815 bUseSolidDragging = false;
819 if(bUseSolidDragging)
821 const SfxItemSet& rItemSet = pEdge->GetMergedItemSet();
822 const drawinglayer::attribute::SdrLineAttribute aLine(
823 drawinglayer::primitive2d::createNewSdrLineAttribute(rItemSet));
825 if(!aLine.isDefault())
827 const drawinglayer::attribute::SdrLineStartEndAttribute aLineStartEnd(
828 drawinglayer::primitive2d::createNewSdrLineStartEndAttribute(
829 rItemSet,
830 aLine.getWidth()));
832 drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(
833 aRetval, drawinglayer::primitive2d::createPolygonLinePrimitive(
834 aEdgePolygon,
835 basegfx::B2DHomMatrix(),
836 aLine,
837 aLineStartEnd));
840 else
842 const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
843 basegfx::BColor aColA(aSvtOptionsDrawinglayer.GetStripeColorA().getBColor());
844 basegfx::BColor aColB(aSvtOptionsDrawinglayer.GetStripeColorB().getBColor());
845 const double fStripeLength(aSvtOptionsDrawinglayer.GetStripeLength());
847 if(Application::GetSettings().GetStyleSettings().GetHighContrastMode())
849 aColA = aColB = Application::GetSettings().GetStyleSettings().GetHighlightColor().getBColor();
850 aColB.invert();
853 drawinglayer::primitive2d::Primitive2DReference aPolyPolygonMarkerPrimitive2D(
854 new drawinglayer::primitive2d::PolyPolygonMarkerPrimitive2D(
855 basegfx::B2DPolyPolygon(aEdgePolygon), aColA, aColB, fStripeLength));
856 drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, aPolyPolygonMarkerPrimitive2D);
863 return aRetval;
866 ////////////////////////////////////////////////////////////////////////////////////////////////////
868 TYPEINIT1(SdrDragMovHdl,SdrDragMethod);
870 SdrDragMovHdl::SdrDragMovHdl(SdrDragView& rNewView)
871 : SdrDragMethod(rNewView),
872 bMirrObjShown(false)
876 void SdrDragMovHdl::createSdrDragEntries()
878 // SdrDragMovHdl does not use the default drags,
879 // but creates nothing
882 void SdrDragMovHdl::TakeSdrDragComment(XubString& rStr) const
884 rStr=ImpGetResStr(STR_DragMethMovHdl);
885 if (getSdrDragView().IsDragWithCopy()) rStr+=ImpGetResStr(STR_EditWithCopy);
888 bool SdrDragMovHdl::BeginSdrDrag()
890 if( !GetDragHdl() )
891 return false;
893 DragStat().Ref1()=GetDragHdl()->GetPos();
894 DragStat().SetShown(!DragStat().IsShown());
895 SdrHdlKind eKind=GetDragHdl()->GetKind();
896 SdrHdl* pH1=GetHdlList().GetHdl(HDL_REF1);
897 SdrHdl* pH2=GetHdlList().GetHdl(HDL_REF2);
899 if (eKind==HDL_MIRX)
901 if (pH1==NULL || pH2==NULL)
903 OSL_FAIL("SdrDragMovHdl::BeginSdrDrag(): Moving the axis of reflection: reference handles not found.");
904 return false;
907 DragStat().SetActionRect(Rectangle(pH1->GetPos(),pH2->GetPos()));
909 else
911 Point aPt(GetDragHdl()->GetPos());
912 DragStat().SetActionRect(Rectangle(aPt,aPt));
915 return true;
918 void SdrDragMovHdl::MoveSdrDrag(const Point& rNoSnapPnt)
920 Point aPnt(rNoSnapPnt);
922 if ( GetDragHdl() && DragStat().CheckMinMoved(rNoSnapPnt))
924 if (GetDragHdl()->GetKind()==HDL_MIRX)
926 SdrHdl* pH1=GetHdlList().GetHdl(HDL_REF1);
927 SdrHdl* pH2=GetHdlList().GetHdl(HDL_REF2);
929 if (pH1==NULL || pH2==NULL)
930 return;
932 if (!DragStat().IsNoSnap())
934 long nBestXSnap=0;
935 long nBestYSnap=0;
936 bool bXSnapped=false;
937 bool bYSnapped=false;
938 Point aDif(aPnt-DragStat().GetStart());
939 getSdrDragView().CheckSnap(Ref1()+aDif,NULL,nBestXSnap,nBestYSnap,bXSnapped,bYSnapped);
940 getSdrDragView().CheckSnap(Ref2()+aDif,NULL,nBestXSnap,nBestYSnap,bXSnapped,bYSnapped);
941 aPnt.X()+=nBestXSnap;
942 aPnt.Y()+=nBestYSnap;
945 if (aPnt!=DragStat().GetNow())
947 Hide();
948 DragStat().NextMove(aPnt);
949 Point aDif(DragStat().GetNow()-DragStat().GetStart());
950 pH1->SetPos(Ref1()+aDif);
951 pH2->SetPos(Ref2()+aDif);
953 SdrHdl* pHM = GetHdlList().GetHdl(HDL_MIRX);
955 if(pHM)
956 pHM->Touch();
958 Show();
959 DragStat().SetActionRect(Rectangle(pH1->GetPos(),pH2->GetPos()));
962 else
964 if (!DragStat().IsNoSnap()) SnapPos(aPnt);
965 long nSA=0;
967 if (getSdrDragView().IsAngleSnapEnabled())
968 nSA=getSdrDragView().GetSnapAngle();
970 if (getSdrDragView().IsMirrorAllowed(true,true))
971 { // limited
972 if (!getSdrDragView().IsMirrorAllowed(false,false)) nSA=4500;
973 if (!getSdrDragView().IsMirrorAllowed(true,false)) nSA=9000;
976 if (getSdrDragView().IsOrtho() && nSA!=9000)
977 nSA=4500;
979 if (nSA!=0)
980 { // angle snapping
981 SdrHdlKind eRef=HDL_REF1;
983 if (GetDragHdl()->GetKind()==HDL_REF1)
984 eRef=HDL_REF2;
986 SdrHdl* pH=GetHdlList().GetHdl(eRef);
988 if (pH!=NULL)
990 Point aRef(pH->GetPos());
991 long nWink=NormAngle360(GetAngle(aPnt-aRef));
992 long nNeuWink=nWink;
993 nNeuWink+=nSA/2;
994 nNeuWink/=nSA;
995 nNeuWink*=nSA;
996 nNeuWink=NormAngle360(nNeuWink);
997 double a=(nNeuWink-nWink)*nPi180;
998 double nSin=sin(a);
999 double nCos=cos(a);
1000 RotatePoint(aPnt,aRef,nSin,nCos);
1002 // eliminate rounding errors for certain values
1003 if (nSA==9000)
1005 if (nNeuWink==0 || nNeuWink==18000) aPnt.Y()=aRef.Y();
1006 if (nNeuWink==9000 || nNeuWink==27000) aPnt.X()=aRef.X();
1009 if (nSA==4500)
1010 OrthoDistance8(aRef,aPnt,true);
1014 if (aPnt!=DragStat().GetNow())
1016 Hide();
1017 DragStat().NextMove(aPnt);
1018 GetDragHdl()->SetPos(DragStat().GetNow());
1019 SdrHdl* pHM = GetHdlList().GetHdl(HDL_MIRX);
1021 if(pHM)
1022 pHM->Touch();
1024 Show();
1025 DragStat().SetActionRect(Rectangle(aPnt,aPnt));
1031 bool SdrDragMovHdl::EndSdrDrag(bool /*bCopy*/)
1033 if( GetDragHdl() )
1035 switch (GetDragHdl()->GetKind())
1037 case HDL_REF1:
1038 Ref1()=DragStat().GetNow();
1039 break;
1041 case HDL_REF2:
1042 Ref2()=DragStat().GetNow();
1043 break;
1045 case HDL_MIRX:
1046 Ref1()+=DragStat().GetNow()-DragStat().GetStart();
1047 Ref2()+=DragStat().GetNow()-DragStat().GetStart();
1048 break;
1050 default: break;
1054 return true;
1057 void SdrDragMovHdl::CancelSdrDrag()
1059 Hide();
1061 SdrHdl* pHdl = GetDragHdl();
1062 if( pHdl )
1063 pHdl->SetPos(DragStat().GetRef1());
1065 SdrHdl* pHM = GetHdlList().GetHdl(HDL_MIRX);
1067 if(pHM)
1068 pHM->Touch();
1071 Pointer SdrDragMovHdl::GetSdrDragPointer() const
1073 const SdrHdl* pHdl = GetDragHdl();
1075 if (pHdl!=NULL)
1077 return pHdl->GetPointer();
1080 return Pointer(POINTER_REFHAND);
1083 ////////////////////////////////////////////////////////////////////////////////////////////////////
1085 TYPEINIT1(SdrDragObjOwn,SdrDragMethod);
1087 SdrDragObjOwn::SdrDragObjOwn(SdrDragView& rNewView)
1088 : SdrDragMethod(rNewView),
1089 mpClone(0)
1091 const SdrObject* pObj = GetDragObj();
1093 if(pObj)
1095 // suppress full drag for some object types
1096 setSolidDraggingActive(pObj->supportsFullDrag());
1100 SdrDragObjOwn::~SdrDragObjOwn()
1102 if(mpClone)
1104 SdrObject::Free(mpClone);
1108 void SdrDragObjOwn::createSdrDragEntries()
1110 if(mpClone)
1112 basegfx::B2DPolyPolygon aDragPolyPolygon;
1113 bool bAddWireframe(true);
1115 if(getSolidDraggingActive())
1117 SdrPageView* pPV = getSdrDragView().GetSdrPageView();
1119 if(pPV && pPV->PageWindowCount())
1121 sdr::contact::ObjectContact& rOC = pPV->GetPageWindow(0)->GetObjectContact();
1122 addSdrDragEntry(new SdrDragEntrySdrObject(*mpClone, rOC, false));
1124 // potentially no wireframe needed, full drag works
1125 bAddWireframe = false;
1129 if(!bAddWireframe)
1131 // check for extra conditions for wireframe, e.g. no border at
1132 // objects
1133 if(!mpClone->HasLineStyle())
1135 bAddWireframe = true;
1139 if(bAddWireframe)
1141 // use wireframe poly when full drag is off or did not work
1142 aDragPolyPolygon = mpClone->TakeXorPoly();
1145 // add evtl. extra DragPolyPolygon
1146 const basegfx::B2DPolyPolygon aSpecialDragPolyPolygon(mpClone->getSpecialDragPoly(DragStat()));
1148 if(aSpecialDragPolyPolygon.count())
1150 aDragPolyPolygon.append(aSpecialDragPolyPolygon);
1153 if(aDragPolyPolygon.count())
1155 addSdrDragEntry(new SdrDragEntryPolyPolygon(aDragPolyPolygon));
1160 void SdrDragObjOwn::TakeSdrDragComment(XubString& rStr) const
1162 // #i103058# get info string from the clone preferred, the original will
1163 // not be changed. For security, use original as fallback
1164 if(mpClone)
1166 rStr = mpClone->getSpecialDragComment(DragStat());
1168 else
1170 const SdrObject* pObj = GetDragObj();
1172 if(pObj)
1174 rStr = pObj->getSpecialDragComment(DragStat());
1179 bool SdrDragObjOwn::BeginSdrDrag()
1181 if(!mpClone)
1183 const SdrObject* pObj = GetDragObj();
1185 if(pObj && !pObj->IsResizeProtect())
1187 if(pObj->beginSpecialDrag(DragStat()))
1189 // create initial clone to have a start visualization
1190 mpClone = pObj->getFullDragClone();
1191 mpClone->applySpecialDrag(DragStat());
1193 return true;
1198 return false;
1201 void SdrDragObjOwn::MoveSdrDrag(const Point& rNoSnapPnt)
1203 const SdrObject* pObj = GetDragObj();
1205 if(pObj)
1207 Point aPnt(rNoSnapPnt);
1208 SdrPageView* pPV = GetDragPV();
1210 if(pPV)
1212 if(!DragStat().IsNoSnap())
1214 SnapPos(aPnt);
1217 if(getSdrDragView().IsOrtho())
1219 if (DragStat().IsOrtho8Possible())
1221 OrthoDistance8(DragStat().GetStart(),aPnt,getSdrDragView().IsBigOrtho());
1223 else if (DragStat().IsOrtho4Possible())
1225 OrthoDistance4(DragStat().GetStart(),aPnt,getSdrDragView().IsBigOrtho());
1229 if(DragStat().CheckMinMoved(rNoSnapPnt))
1231 if(aPnt != DragStat().GetNow())
1233 Hide();
1234 DragStat().NextMove(aPnt);
1236 // since SdrDragObjOwn currently supports no transformation of
1237 // existing SdrDragEntries but only their recreation, a recreation
1238 // after every move is needed in this mode. Delete existing
1239 // SdrDragEntries here to force their recreation in the following Show().
1240 clearSdrDragEntries();
1242 // delete current clone (after the last reference to it is deleted above)
1243 if(mpClone)
1245 SdrObject::Free(mpClone);
1246 mpClone = 0;
1249 // create a new clone and modify to current drag state
1250 if(!mpClone)
1252 mpClone = pObj->getFullDragClone();
1253 mpClone->applySpecialDrag(DragStat());
1256 Show();
1263 bool SdrDragObjOwn::EndSdrDrag(bool /*bCopy*/)
1265 Hide();
1266 SdrUndoAction* pUndo = NULL;
1267 SdrUndoAction* pUndo2 = NULL;
1268 std::vector< SdrUndoAction* > vConnectorUndoActions;
1269 bool bRet = false;
1270 SdrObject* pObj = GetDragObj();
1272 if(pObj)
1274 const bool bUndo = getSdrDragView().IsUndoEnabled();
1276 if( bUndo )
1278 if(!getSdrDragView().IsInsObjPoint() && pObj->IsInserted() )
1280 if (DragStat().IsEndDragChangesAttributes())
1282 pUndo=getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pObj);
1284 if (DragStat().IsEndDragChangesGeoAndAttributes())
1286 vConnectorUndoActions = getSdrDragView().CreateConnectorUndo( *pObj );
1287 pUndo2 = getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj);
1290 else
1292 vConnectorUndoActions = getSdrDragView().CreateConnectorUndo( *pObj );
1293 pUndo= getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj);
1297 if( pUndo )
1299 getSdrDragView().BegUndo( pUndo->GetComment() );
1301 else
1303 getSdrDragView().BegUndo();
1307 // Maybe use operator = for setting changed object data (do not change selection in
1308 // view, this will destroy the interactor). This is possible since a clone is now
1309 // directly modified by the modifiers. Only SdrTableObj is adding own UNDOs
1310 // in its SdrTableObj::endSpecialDrag, so currently not possible. OTOH it uses
1311 // a CreateUndoGeoObject(), so maybe setting SetEndDragChangesAttributes is okay. I
1312 // will test this now
1313 Rectangle aBoundRect0;
1315 if(pObj->GetUserCall())
1317 aBoundRect0 = pObj->GetLastBoundRect();
1320 bRet = pObj->applySpecialDrag(DragStat());
1322 if(bRet)
1324 pObj->SetChanged();
1325 pObj->BroadcastObjectChange();
1326 pObj->SendUserCall( SDRUSERCALL_RESIZE, aBoundRect0 );
1329 if(bRet)
1331 if( bUndo )
1333 getSdrDragView().AddUndoActions( vConnectorUndoActions );
1335 if ( pUndo )
1337 getSdrDragView().AddUndo(pUndo);
1340 if ( pUndo2 )
1342 getSdrDragView().AddUndo(pUndo2);
1346 else
1348 if( bUndo )
1350 std::vector< SdrUndoAction* >::iterator vConnectorUndoIter( vConnectorUndoActions.begin() );
1352 while( vConnectorUndoIter != vConnectorUndoActions.end() )
1354 delete *vConnectorUndoIter++;
1357 delete pUndo;
1358 delete pUndo2;
1362 if( bUndo )
1363 getSdrDragView().EndUndo();
1366 return bRet;
1369 Pointer SdrDragObjOwn::GetSdrDragPointer() const
1371 const SdrHdl* pHdl=GetDragHdl();
1373 if (pHdl)
1375 return pHdl->GetPointer();
1378 return Pointer(POINTER_MOVE);
1381 ////////////////////////////////////////////////////////////////////////////////////////////////////
1383 TYPEINIT1(SdrDragMove,SdrDragMethod);
1385 void SdrDragMove::createSdrDragEntryForSdrObject(const SdrObject& rOriginal, sdr::contact::ObjectContact& rObjectContact, bool /*bModify*/)
1387 // for SdrDragMove, use current Primitive2DSequence of SdrObject visualization
1388 // in given ObjectContact directly
1389 sdr::contact::ViewContact& rVC = rOriginal.GetViewContact();
1390 sdr::contact::ViewObjectContact& rVOC = rVC.GetViewObjectContact(rObjectContact);
1391 sdr::contact::DisplayInfo aDisplayInfo;
1393 // Do not use the last ViewPort set at the OC from the last ProcessDisplay(),
1394 // here we want the complete primitive sequence without visible clippings
1395 rObjectContact.resetViewPort();
1397 addSdrDragEntry(new SdrDragEntryPrimitive2DSequence(rVOC.getPrimitive2DSequenceHierarchy(aDisplayInfo), true));
1400 void SdrDragMove::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
1402 rTarget.Move(Size(DragStat().GetDX(), DragStat().GetDY()));
1405 SdrDragMove::SdrDragMove(SdrDragView& rNewView)
1406 : SdrDragMethod(rNewView)
1408 setMoveOnly(true);
1411 void SdrDragMove::TakeSdrDragComment(XubString& rStr) const
1413 rtl::OUString aStr;
1415 ImpTakeDescriptionStr(STR_DragMethMove, rStr);
1416 rStr.AppendAscii(" (x=");
1417 getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDX(), aStr);
1418 rStr.Append(aStr);
1419 rStr.AppendAscii(" y=");
1420 getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDY(), aStr);
1421 rStr.Append(aStr);
1422 rStr += sal_Unicode(')');
1424 if(getSdrDragView().IsDragWithCopy())
1426 if(!getSdrDragView().IsInsObjPoint() && !getSdrDragView().IsInsGluePoint())
1428 rStr += ImpGetResStr(STR_EditWithCopy);
1433 bool SdrDragMove::BeginSdrDrag()
1435 DragStat().SetActionRect(GetMarkedRect());
1436 Show();
1438 return true;
1441 basegfx::B2DHomMatrix SdrDragMove::getCurrentTransformation()
1443 return basegfx::tools::createTranslateB2DHomMatrix(DragStat().GetDX(), DragStat().GetDY());
1446 void SdrDragMove::ImpCheckSnap(const Point& rPt)
1448 Point aPt(rPt);
1449 sal_uInt16 nRet=SnapPos(aPt);
1450 aPt-=rPt;
1452 if ((nRet & SDRSNAP_XSNAPPED) !=0)
1454 if (bXSnapped)
1456 if (Abs(aPt.X())<Abs(nBestXSnap))
1458 nBestXSnap=aPt.X();
1461 else
1463 nBestXSnap=aPt.X();
1464 bXSnapped=true;
1468 if ((nRet & SDRSNAP_YSNAPPED) !=0)
1470 if (bYSnapped)
1472 if (Abs(aPt.Y())<Abs(nBestYSnap))
1474 nBestYSnap=aPt.Y();
1477 else
1479 nBestYSnap=aPt.Y();
1480 bYSnapped=true;
1485 void SdrDragMove::MoveSdrDrag(const Point& rNoSnapPnt_)
1487 nBestXSnap=0;
1488 nBestYSnap=0;
1489 bXSnapped=false;
1490 bYSnapped=false;
1491 Point aNoSnapPnt(rNoSnapPnt_);
1492 const Rectangle& aSR=GetMarkedRect();
1493 long nMovedx=aNoSnapPnt.X()-DragStat().GetStart().X();
1494 long nMovedy=aNoSnapPnt.Y()-DragStat().GetStart().Y();
1495 Point aLO(aSR.TopLeft()); aLO.X()+=nMovedx; aLO.Y()+=nMovedy;
1496 Point aRU(aSR.BottomRight()); aRU.X()+=nMovedx; aRU.Y()+=nMovedy;
1497 Point aLU(aLO.X(),aRU.Y());
1498 Point aRO(aRU.X(),aLO.Y());
1499 ImpCheckSnap(aLO);
1501 if (!getSdrDragView().IsMoveSnapOnlyTopLeft())
1503 ImpCheckSnap(aRO);
1504 ImpCheckSnap(aLU);
1505 ImpCheckSnap(aRU);
1508 Point aPnt(aNoSnapPnt.X()+nBestXSnap,aNoSnapPnt.Y()+nBestYSnap);
1509 bool bOrtho=getSdrDragView().IsOrtho();
1511 if (bOrtho)
1512 OrthoDistance8(DragStat().GetStart(),aPnt,getSdrDragView().IsBigOrtho());
1514 if (DragStat().CheckMinMoved(aNoSnapPnt))
1516 Point aPt1(aPnt);
1517 Rectangle aLR(getSdrDragView().GetWorkArea());
1518 bool bWorkArea=!aLR.IsEmpty();
1519 bool bDragLimit=IsDragLimit();
1521 if (bDragLimit || bWorkArea)
1523 Rectangle aSR2(GetMarkedRect());
1524 Point aD(aPt1-DragStat().GetStart());
1526 if (bDragLimit)
1528 Rectangle aR2(GetDragLimitRect());
1530 if (bWorkArea)
1531 aLR.Intersection(aR2);
1532 else
1533 aLR=aR2;
1536 if (aSR2.Left()>aLR.Left() || aSR2.Right()<aLR.Right())
1537 { // any space to move to?
1538 aSR2.Move(aD.X(),0);
1540 if (aSR2.Left()<aLR.Left())
1542 aPt1.X()-=aSR2.Left()-aLR.Left();
1544 else if (aSR2.Right()>aLR.Right())
1546 aPt1.X()-=aSR2.Right()-aLR.Right();
1549 else
1550 aPt1.X()=DragStat().GetStart().X(); // no space to move to
1552 if (aSR2.Top()>aLR.Top() || aSR2.Bottom()<aLR.Bottom())
1553 { // any space to move to?
1554 aSR2.Move(0,aD.Y());
1556 if (aSR2.Top()<aLR.Top())
1558 aPt1.Y()-=aSR2.Top()-aLR.Top();
1560 else if (aSR2.Bottom()>aLR.Bottom())
1562 aPt1.Y()-=aSR2.Bottom()-aLR.Bottom();
1565 else
1566 aPt1.Y()=DragStat().GetStart().Y(); // no space to move to
1569 if (getSdrDragView().IsDraggingGluePoints())
1570 { // restrict glue points to the BoundRect of the Obj
1571 aPt1-=DragStat().GetStart();
1572 const SdrMarkList& rML=GetMarkedObjectList();
1573 sal_uLong nMarkAnz=rML.GetMarkCount();
1575 for (sal_uLong nMarkNum=0; nMarkNum<nMarkAnz; nMarkNum++)
1577 const SdrMark* pM=rML.GetMark(nMarkNum);
1578 const SdrUShortCont* pPts=pM->GetMarkedGluePoints();
1579 sal_uLong nPtAnz=pPts==NULL ? 0 : pPts->GetCount();
1581 if (nPtAnz!=0)
1583 const SdrObject* pObj=pM->GetMarkedSdrObj();
1584 const SdrGluePointList* pGPL=pObj->GetGluePointList();
1585 Rectangle aBound(pObj->GetCurrentBoundRect());
1587 for (sal_uLong nPtNum=0; nPtNum<nPtAnz; nPtNum++)
1589 sal_uInt16 nId=pPts->GetObject(nPtNum);
1590 sal_uInt16 nGlueNum=pGPL->FindGluePoint(nId);
1592 if (nGlueNum!=SDRGLUEPOINT_NOTFOUND)
1594 Point aPt((*pGPL)[nGlueNum].GetAbsolutePos(*pObj));
1595 aPt+=aPt1; // move by this much
1596 if (aPt.X()<aBound.Left() ) aPt1.X()-=aPt.X()-aBound.Left() ;
1597 if (aPt.X()>aBound.Right() ) aPt1.X()-=aPt.X()-aBound.Right() ;
1598 if (aPt.Y()<aBound.Top() ) aPt1.Y()-=aPt.Y()-aBound.Top() ;
1599 if (aPt.Y()>aBound.Bottom()) aPt1.Y()-=aPt.Y()-aBound.Bottom();
1605 aPt1+=DragStat().GetStart();
1608 if (bOrtho)
1609 OrthoDistance8(DragStat().GetStart(),aPt1,false);
1611 if (aPt1!=DragStat().GetNow())
1613 Hide();
1614 DragStat().NextMove(aPt1);
1615 Rectangle aAction(GetMarkedRect());
1616 aAction.Move(DragStat().GetDX(),DragStat().GetDY());
1617 DragStat().SetActionRect(aAction);
1618 Show();
1623 bool SdrDragMove::EndSdrDrag(bool bCopy)
1625 Hide();
1627 if (getSdrDragView().IsInsObjPoint() || getSdrDragView().IsInsGluePoint())
1628 bCopy=false;
1630 if (IsDraggingPoints())
1632 getSdrDragView().MoveMarkedPoints(Size(DragStat().GetDX(),DragStat().GetDY()),bCopy);
1634 else if (IsDraggingGluePoints())
1636 getSdrDragView().MoveMarkedGluePoints(Size(DragStat().GetDX(),DragStat().GetDY()),bCopy);
1638 else
1640 getSdrDragView().MoveMarkedObj(Size(DragStat().GetDX(),DragStat().GetDY()),bCopy);
1643 return true;
1646 Pointer SdrDragMove::GetSdrDragPointer() const
1648 if (IsDraggingPoints() || IsDraggingGluePoints())
1650 return Pointer(POINTER_MOVEPOINT);
1652 else
1654 return Pointer(POINTER_MOVE);
1658 ////////////////////////////////////////////////////////////////////////////////////////////////////
1660 TYPEINIT1(SdrDragResize,SdrDragMethod);
1662 SdrDragResize::SdrDragResize(SdrDragView& rNewView)
1663 : SdrDragMethod(rNewView),
1664 aXFact(1,1),
1665 aYFact(1,1)
1669 void SdrDragResize::TakeSdrDragComment(XubString& rStr) const
1671 ImpTakeDescriptionStr(STR_DragMethResize, rStr);
1672 bool bEqual(aXFact == aYFact);
1673 Fraction aFact1(1,1);
1674 Point aStart(DragStat().GetStart());
1675 Point aRef(DragStat().GetRef1());
1676 sal_Int32 nXDiv(aStart.X() - aRef.X());
1678 if(!nXDiv)
1679 nXDiv = 1;
1681 sal_Int32 nYDiv(aStart.Y() - aRef.Y());
1683 if(!nYDiv)
1684 nYDiv = 1;
1686 bool bX(aXFact != aFact1 && Abs(nXDiv) > 1);
1687 bool bY(aYFact != aFact1 && Abs(nYDiv) > 1);
1689 if(bX || bY)
1691 XubString aStr;
1693 rStr.AppendAscii(" (");
1695 if(bX)
1697 if(!bEqual)
1698 rStr.AppendAscii("x=");
1700 getSdrDragView().GetModel()->TakePercentStr(aXFact, aStr);
1701 rStr += aStr;
1704 if(bY && !bEqual)
1706 if(bX)
1707 rStr += sal_Unicode(' ');
1709 rStr.AppendAscii("y=");
1710 getSdrDragView().GetModel()->TakePercentStr(aYFact, aStr);
1711 rStr += aStr;
1714 rStr += sal_Unicode(')');
1717 if(getSdrDragView().IsDragWithCopy())
1718 rStr += ImpGetResStr(STR_EditWithCopy);
1721 bool SdrDragResize::BeginSdrDrag()
1723 SdrHdlKind eRefHdl=HDL_MOVE;
1724 SdrHdl* pRefHdl=NULL;
1726 switch (GetDragHdlKind())
1728 case HDL_UPLFT: eRefHdl=HDL_LWRGT; break;
1729 case HDL_UPPER: eRefHdl=HDL_LOWER; DragStat().SetHorFixed(true); break;
1730 case HDL_UPRGT: eRefHdl=HDL_LWLFT; break;
1731 case HDL_LEFT : eRefHdl=HDL_RIGHT; DragStat().SetVerFixed(true); break;
1732 case HDL_RIGHT: eRefHdl=HDL_LEFT ; DragStat().SetVerFixed(true); break;
1733 case HDL_LWLFT: eRefHdl=HDL_UPRGT; break;
1734 case HDL_LOWER: eRefHdl=HDL_UPPER; DragStat().SetHorFixed(true); break;
1735 case HDL_LWRGT: eRefHdl=HDL_UPLFT; break;
1736 default: break;
1739 if (eRefHdl!=HDL_MOVE)
1740 pRefHdl=GetHdlList().GetHdl(eRefHdl);
1742 if (pRefHdl!=NULL && !getSdrDragView().IsResizeAtCenter())
1744 DragStat().Ref1()=pRefHdl->GetPos();
1746 else
1748 SdrHdl* pRef1=GetHdlList().GetHdl(HDL_UPLFT);
1749 SdrHdl* pRef2=GetHdlList().GetHdl(HDL_LWRGT);
1751 if (pRef1!=NULL && pRef2!=NULL)
1753 DragStat().Ref1()=Rectangle(pRef1->GetPos(),pRef2->GetPos()).Center();
1755 else
1757 DragStat().Ref1()=GetMarkedRect().Center();
1761 Show();
1763 return true;
1766 basegfx::B2DHomMatrix SdrDragResize::getCurrentTransformation()
1768 basegfx::B2DHomMatrix aRetval(basegfx::tools::createTranslateB2DHomMatrix(
1769 -DragStat().Ref1().X(), -DragStat().Ref1().Y()));
1770 aRetval.scale(aXFact, aYFact);
1771 aRetval.translate(DragStat().Ref1().X(), DragStat().Ref1().Y());
1773 return aRetval;
1776 void SdrDragResize::MoveSdrDrag(const Point& rNoSnapPnt)
1778 Point aPnt(GetSnapPos(rNoSnapPnt));
1779 Point aStart(DragStat().GetStart());
1780 Point aRef(DragStat().GetRef1());
1781 Fraction aMaxFact(0x7FFFFFFF,1);
1782 Rectangle aLR(getSdrDragView().GetWorkArea());
1783 bool bWorkArea=!aLR.IsEmpty();
1784 bool bDragLimit=IsDragLimit();
1786 if (bDragLimit || bWorkArea)
1788 Rectangle aSR(GetMarkedRect());
1790 if (bDragLimit)
1792 Rectangle aR2(GetDragLimitRect());
1794 if (bWorkArea)
1795 aLR.Intersection(aR2);
1796 else
1797 aLR=aR2;
1800 if (aPnt.X()<aLR.Left())
1801 aPnt.X()=aLR.Left();
1802 else if (aPnt.X()>aLR.Right())
1803 aPnt.X()=aLR.Right();
1805 if (aPnt.Y()<aLR.Top())
1806 aPnt.Y()=aLR.Top();
1807 else if (aPnt.Y()>aLR.Bottom())
1808 aPnt.Y()=aLR.Bottom();
1810 if (aRef.X()>aSR.Left())
1812 Fraction aMax(aRef.X()-aLR.Left(),aRef.X()-aSR.Left());
1814 if (aMax<aMaxFact)
1815 aMaxFact=aMax;
1818 if (aRef.X()<aSR.Right())
1820 Fraction aMax(aLR.Right()-aRef.X(),aSR.Right()-aRef.X());
1822 if (aMax<aMaxFact)
1823 aMaxFact=aMax;
1826 if (aRef.Y()>aSR.Top())
1828 Fraction aMax(aRef.Y()-aLR.Top(),aRef.Y()-aSR.Top());
1830 if (aMax<aMaxFact)
1831 aMaxFact=aMax;
1834 if (aRef.Y()<aSR.Bottom())
1836 Fraction aMax(aLR.Bottom()-aRef.Y(),aSR.Bottom()-aRef.Y());
1838 if (aMax<aMaxFact)
1839 aMaxFact=aMax;
1843 long nXDiv=aStart.X()-aRef.X(); if (nXDiv==0) nXDiv=1;
1844 long nYDiv=aStart.Y()-aRef.Y(); if (nYDiv==0) nYDiv=1;
1845 long nXMul=aPnt.X()-aRef.X();
1846 long nYMul=aPnt.Y()-aRef.Y();
1848 if (nXDiv<0)
1850 nXDiv=-nXDiv;
1851 nXMul=-nXMul;
1854 if (nYDiv<0)
1856 nYDiv=-nYDiv;
1857 nYMul=-nYMul;
1860 bool bXNeg=nXMul<0; if (bXNeg) nXMul=-nXMul;
1861 bool bYNeg=nYMul<0; if (bYNeg) nYMul=-nYMul;
1862 bool bOrtho=getSdrDragView().IsOrtho() || !getSdrDragView().IsResizeAllowed(false);
1864 if (!DragStat().IsHorFixed() && !DragStat().IsVerFixed())
1866 if (Abs(nXDiv)<=1 || Abs(nYDiv)<=1)
1867 bOrtho=false;
1869 if (bOrtho)
1871 if ((Fraction(nXMul,nXDiv)>Fraction(nYMul,nYDiv)) !=getSdrDragView().IsBigOrtho())
1873 nXMul=nYMul;
1874 nXDiv=nYDiv;
1876 else
1878 nYMul=nXMul;
1879 nYDiv=nXDiv;
1883 else
1885 if (bOrtho)
1887 if (DragStat().IsHorFixed())
1889 bXNeg=false;
1890 nXMul=nYMul;
1891 nXDiv=nYDiv;
1894 if (DragStat().IsVerFixed())
1896 bYNeg=false;
1897 nYMul=nXMul;
1898 nYDiv=nXDiv;
1901 else
1903 if (DragStat().IsHorFixed())
1905 bXNeg=false;
1906 nXMul=1;
1907 nXDiv=1;
1910 if (DragStat().IsVerFixed())
1912 bYNeg=false;
1913 nYMul=1;
1914 nYDiv=1;
1919 Fraction aNeuXFact(nXMul,nXDiv);
1920 Fraction aNeuYFact(nYMul,nYDiv);
1922 if (bOrtho)
1924 if (aNeuXFact>aMaxFact)
1926 aNeuXFact=aMaxFact;
1927 aNeuYFact=aMaxFact;
1930 if (aNeuYFact>aMaxFact)
1932 aNeuXFact=aMaxFact;
1933 aNeuYFact=aMaxFact;
1937 if (bXNeg)
1938 aNeuXFact=Fraction(-aNeuXFact.GetNumerator(),aNeuXFact.GetDenominator());
1940 if (bYNeg)
1941 aNeuYFact=Fraction(-aNeuYFact.GetNumerator(),aNeuYFact.GetDenominator());
1943 if (DragStat().CheckMinMoved(aPnt))
1945 if ((!DragStat().IsHorFixed() && aPnt.X()!=DragStat().GetNow().X()) ||
1946 (!DragStat().IsVerFixed() && aPnt.Y()!=DragStat().GetNow().Y()))
1948 Hide();
1949 DragStat().NextMove(aPnt);
1950 aXFact=aNeuXFact;
1951 aYFact=aNeuYFact;
1952 Show();
1957 void SdrDragResize::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
1959 rTarget.Resize(DragStat().Ref1(),aXFact,aYFact);
1962 bool SdrDragResize::EndSdrDrag(bool bCopy)
1964 Hide();
1966 if (IsDraggingPoints())
1968 getSdrDragView().ResizeMarkedPoints(DragStat().Ref1(),aXFact,aYFact,bCopy);
1970 else if (IsDraggingGluePoints())
1972 getSdrDragView().ResizeMarkedGluePoints(DragStat().Ref1(),aXFact,aYFact,bCopy);
1974 else
1976 getSdrDragView().ResizeMarkedObj(DragStat().Ref1(),aXFact,aYFact,bCopy);
1979 return true;
1982 Pointer SdrDragResize::GetSdrDragPointer() const
1984 const SdrHdl* pHdl=GetDragHdl();
1986 if (pHdl!=NULL)
1988 return pHdl->GetPointer();
1991 return Pointer(POINTER_MOVE);
1994 ////////////////////////////////////////////////////////////////////////////////////////////////////
1996 TYPEINIT1(SdrDragRotate,SdrDragMethod);
1998 void SdrDragRotate::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
2000 rTarget.Rotate(DragStat().GetRef1(), nWink, sin(nWink*nPi180), cos(nWink*nPi180));
2003 SdrDragRotate::SdrDragRotate(SdrDragView& rNewView)
2004 : SdrDragMethod(rNewView),
2005 nSin(0.0),
2006 nCos(1.0),
2007 nWink0(0),
2008 nWink(0),
2009 bRight(false)
2013 void SdrDragRotate::TakeSdrDragComment(XubString& rStr) const
2015 ImpTakeDescriptionStr(STR_DragMethRotate, rStr);
2016 rStr.AppendAscii(" (");
2017 sal_Int32 nTmpWink(NormAngle360(nWink));
2019 if(bRight && nWink)
2021 nTmpWink -= 36000;
2024 rtl::OUString aStr;
2025 getSdrDragView().GetModel()->TakeWinkStr(nTmpWink, aStr);
2026 rStr.Append(aStr);
2027 rStr += sal_Unicode(')');
2029 if(getSdrDragView().IsDragWithCopy())
2030 rStr += ImpGetResStr(STR_EditWithCopy);
2033 bool SdrDragRotate::BeginSdrDrag()
2035 SdrHdl* pH=GetHdlList().GetHdl(HDL_REF1);
2037 if (pH!=NULL)
2039 Show();
2040 DragStat().Ref1()=pH->GetPos();
2041 nWink0=GetAngle(DragStat().GetStart()-DragStat().GetRef1());
2042 return true;
2044 else
2046 OSL_FAIL("SdrDragRotate::BeginSdrDrag(): No reference point handle found.");
2047 return false;
2051 basegfx::B2DHomMatrix SdrDragRotate::getCurrentTransformation()
2053 return basegfx::tools::createRotateAroundPoint(
2054 DragStat().GetRef1().X(), DragStat().GetRef1().Y(),
2055 -atan2(nSin, nCos));
2058 void SdrDragRotate::MoveSdrDrag(const Point& rPnt_)
2060 Point aPnt(rPnt_);
2061 if (DragStat().CheckMinMoved(aPnt))
2063 long nNeuWink=NormAngle360(GetAngle(aPnt-DragStat().GetRef1())-nWink0);
2064 long nSA=0;
2066 if (getSdrDragView().IsAngleSnapEnabled())
2067 nSA=getSdrDragView().GetSnapAngle();
2069 if (!getSdrDragView().IsRotateAllowed(false))
2070 nSA=9000;
2072 if (nSA!=0)
2073 { // angle snapping
2074 nNeuWink+=nSA/2;
2075 nNeuWink/=nSA;
2076 nNeuWink*=nSA;
2079 nNeuWink=NormAngle180(nNeuWink);
2081 if (nWink!=nNeuWink)
2083 sal_uInt16 nSekt0=GetAngleSector(nWink);
2084 sal_uInt16 nSekt1=GetAngleSector(nNeuWink);
2086 if (nSekt0==0 && nSekt1==3)
2087 bRight=true;
2089 if (nSekt0==3 && nSekt1==0)
2090 bRight=false;
2092 nWink=nNeuWink;
2093 double a=nWink*nPi180;
2094 double nSin1=sin(a); // calculate now, so as little time as possible
2095 double nCos1=cos(a); // passes between Hide() and Show()
2096 Hide();
2097 nSin=nSin1;
2098 nCos=nCos1;
2099 DragStat().NextMove(aPnt);
2100 Show();
2105 bool SdrDragRotate::EndSdrDrag(bool bCopy)
2107 Hide();
2109 if (nWink!=0)
2111 if (IsDraggingPoints())
2113 getSdrDragView().RotateMarkedPoints(DragStat().GetRef1(),nWink,bCopy);
2115 else if (IsDraggingGluePoints())
2117 getSdrDragView().RotateMarkedGluePoints(DragStat().GetRef1(),nWink,bCopy);
2119 else
2121 getSdrDragView().RotateMarkedObj(DragStat().GetRef1(),nWink,bCopy);
2124 return true;
2127 Pointer SdrDragRotate::GetSdrDragPointer() const
2129 return Pointer(POINTER_ROTATE);
2132 ////////////////////////////////////////////////////////////////////////////////////////////////////
2134 TYPEINIT1(SdrDragShear,SdrDragMethod);
2136 SdrDragShear::SdrDragShear(SdrDragView& rNewView, bool bSlant1)
2137 : SdrDragMethod(rNewView),
2138 aFact(1,1),
2139 nWink0(0),
2140 nWink(0),
2141 nTan(0.0),
2142 bVertical(false),
2143 bResize(false),
2144 bUpSideDown(false),
2145 bSlant(bSlant1)
2149 void SdrDragShear::TakeSdrDragComment(XubString& rStr) const
2151 ImpTakeDescriptionStr(STR_DragMethShear, rStr);
2152 rStr.AppendAscii(" (");
2154 sal_Int32 nTmpWink(nWink);
2156 if(bUpSideDown)
2157 nTmpWink += 18000;
2159 nTmpWink = NormAngle180(nTmpWink);
2161 rtl::OUString aStr;
2162 getSdrDragView().GetModel()->TakeWinkStr(nTmpWink, aStr);
2163 rStr.Append(aStr);
2164 rStr += sal_Unicode(')');
2166 if(getSdrDragView().IsDragWithCopy())
2167 rStr += ImpGetResStr(STR_EditWithCopy);
2170 bool SdrDragShear::BeginSdrDrag()
2172 SdrHdlKind eRefHdl=HDL_MOVE;
2173 SdrHdl* pRefHdl=NULL;
2175 switch (GetDragHdlKind())
2177 case HDL_UPPER: eRefHdl=HDL_LOWER; break;
2178 case HDL_LOWER: eRefHdl=HDL_UPPER; break;
2179 case HDL_LEFT : eRefHdl=HDL_RIGHT; bVertical=true; break;
2180 case HDL_RIGHT: eRefHdl=HDL_LEFT ; bVertical=true; break;
2181 default: break;
2184 if (eRefHdl!=HDL_MOVE)
2185 pRefHdl=GetHdlList().GetHdl(eRefHdl);
2187 if (pRefHdl!=NULL)
2189 DragStat().Ref1()=pRefHdl->GetPos();
2190 nWink0=GetAngle(DragStat().GetStart()-DragStat().GetRef1());
2192 else
2194 OSL_FAIL("SdrDragShear::BeginSdrDrag(): No reference point handle for shearing found.");
2195 return false;
2198 Show();
2199 return true;
2202 basegfx::B2DHomMatrix SdrDragShear::getCurrentTransformation()
2204 basegfx::B2DHomMatrix aRetval(basegfx::tools::createTranslateB2DHomMatrix(
2205 -DragStat().GetRef1().X(), -DragStat().GetRef1().Y()));
2207 if (bResize)
2209 if (bVertical)
2211 aRetval.scale(aFact, 1.0);
2212 aRetval.shearY(-nTan);
2214 else
2216 aRetval.scale(1.0, aFact);
2217 aRetval.shearX(-nTan);
2221 aRetval.translate(DragStat().GetRef1().X(), DragStat().GetRef1().Y());
2223 return aRetval;
2226 void SdrDragShear::MoveSdrDrag(const Point& rPnt)
2228 if (DragStat().CheckMinMoved(rPnt))
2230 bResize=!getSdrDragView().IsOrtho();
2231 long nSA=0;
2233 if (getSdrDragView().IsAngleSnapEnabled())
2234 nSA=getSdrDragView().GetSnapAngle();
2236 Point aP0(DragStat().GetStart());
2237 Point aPnt(rPnt);
2238 Fraction aNeuFact(1,1);
2240 // if angle snapping not activated, snap to raster (except when using slant)
2241 if (nSA==0 && !bSlant)
2242 aPnt=GetSnapPos(aPnt);
2244 if (!bSlant && !bResize)
2245 { // shear, but no resize
2246 if (bVertical)
2247 aPnt.X()=aP0.X();
2248 else
2249 aPnt.Y()=aP0.Y();
2252 Point aRef(DragStat().GetRef1());
2253 Point aDif(aPnt-aRef);
2255 long nNeuWink=0;
2257 if (bSlant)
2259 nNeuWink=NormAngle180(-(GetAngle(aDif)-nWink0));
2261 if (bVertical)
2262 nNeuWink=NormAngle180(-nNeuWink);
2264 else
2266 if (bVertical)
2267 nNeuWink=NormAngle180(GetAngle(aDif));
2268 else
2269 nNeuWink=NormAngle180(-(GetAngle(aDif)-9000));
2271 if (nNeuWink<-9000 || nNeuWink>9000)
2272 nNeuWink=NormAngle180(nNeuWink+18000);
2274 if (bResize)
2276 Point aPt2(aPnt);
2278 if (nSA!=0)
2279 aPt2=GetSnapPos(aPnt); // snap this one in any case
2281 if (bVertical)
2283 aNeuFact=Fraction(aPt2.X()-aRef.X(),aP0.X()-aRef.X());
2285 else
2287 aNeuFact=Fraction(aPt2.Y()-aRef.Y(),aP0.Y()-aRef.Y());
2292 bool bNeg=nNeuWink<0;
2294 if (bNeg)
2295 nNeuWink=-nNeuWink;
2297 if (nSA!=0)
2298 { // angle snapping
2299 nNeuWink+=nSA/2;
2300 nNeuWink/=nSA;
2301 nNeuWink*=nSA;
2304 nNeuWink=NormAngle360(nNeuWink);
2305 bUpSideDown=nNeuWink>9000 && nNeuWink<27000;
2307 if (bSlant)
2308 { // calculate resize for slant
2309 // when angle snapping is activated, disable 89 degree limit
2310 long nTmpWink=nNeuWink;
2311 if (bUpSideDown) nNeuWink-=18000;
2312 if (bNeg) nTmpWink=-nTmpWink;
2313 bResize=true;
2314 double nCos=cos(nTmpWink*nPi180);
2315 aNeuFact=nCos;
2316 Kuerzen(aFact,10); // three decimals should be enough
2319 if (nNeuWink>8900)
2320 nNeuWink=8900;
2322 if (bNeg)
2323 nNeuWink=-nNeuWink;
2325 if (nWink!=nNeuWink || aFact!=aNeuFact)
2327 nWink=nNeuWink;
2328 aFact=aNeuFact;
2329 double a=nWink*nPi180;
2330 double nTan1=0.0;
2331 nTan1=tan(a); // calculate now, so as little time as possible passes between Hide() and Show()
2332 Hide();
2333 nTan=nTan1;
2334 DragStat().NextMove(rPnt);
2335 Show();
2340 void SdrDragShear::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
2342 if (bResize)
2344 if (bVertical)
2346 rTarget.Resize(DragStat().GetRef1(),aFact,Fraction(1,1));
2348 else
2350 rTarget.Resize(DragStat().GetRef1(),Fraction(1,1),aFact);
2354 if (nWink!=0)
2356 rTarget.Shear(DragStat().GetRef1(),nWink,tan(nWink*nPi180),bVertical);
2360 bool SdrDragShear::EndSdrDrag(bool bCopy)
2362 Hide();
2364 if (bResize && aFact==Fraction(1,1))
2365 bResize=false;
2367 if (nWink!=0 || bResize)
2369 if (nWink!=0 && bResize)
2371 XubString aStr;
2372 ImpTakeDescriptionStr(STR_EditShear,aStr);
2374 if (bCopy)
2375 aStr+=ImpGetResStr(STR_EditWithCopy);
2377 getSdrDragView().BegUndo(aStr);
2380 if (bResize)
2382 if (bVertical)
2384 getSdrDragView().ResizeMarkedObj(DragStat().GetRef1(),aFact,Fraction(1,1),bCopy);
2386 else
2388 getSdrDragView().ResizeMarkedObj(DragStat().GetRef1(),Fraction(1,1),aFact,bCopy);
2391 bCopy=false;
2394 if (nWink!=0)
2396 getSdrDragView().ShearMarkedObj(DragStat().GetRef1(),nWink,bVertical,bCopy);
2399 if (nWink!=0 && bResize)
2400 getSdrDragView().EndUndo();
2402 return true;
2405 return false;
2408 Pointer SdrDragShear::GetSdrDragPointer() const
2410 if (bVertical)
2411 return Pointer(POINTER_VSHEAR);
2412 else
2413 return Pointer(POINTER_HSHEAR);
2416 ////////////////////////////////////////////////////////////////////////////////////////////////////
2418 TYPEINIT1(SdrDragMirror,SdrDragMethod);
2420 void SdrDragMirror::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
2422 if(bMirrored)
2424 rTarget.Mirror(DragStat().GetRef1(), DragStat().GetRef2());
2428 SdrDragMirror::SdrDragMirror(SdrDragView& rNewView)
2429 : SdrDragMethod(rNewView),
2430 nWink(0),
2431 bMirrored(false),
2432 bSide0(false)
2436 bool SdrDragMirror::ImpCheckSide(const Point& rPnt) const
2438 long nWink1=GetAngle(rPnt-DragStat().GetRef1());
2439 nWink1-=nWink;
2440 nWink1=NormAngle360(nWink1);
2442 return nWink1<18000;
2445 void SdrDragMirror::TakeSdrDragComment(XubString& rStr) const
2447 if (aDif.X()==0)
2448 ImpTakeDescriptionStr(STR_DragMethMirrorHori,rStr);
2449 else if (aDif.Y()==0)
2450 ImpTakeDescriptionStr(STR_DragMethMirrorVert,rStr);
2451 else if (Abs(aDif.X())==Abs(aDif.Y()))
2452 ImpTakeDescriptionStr(STR_DragMethMirrorDiag,rStr);
2453 else
2454 ImpTakeDescriptionStr(STR_DragMethMirrorFree,rStr);
2456 if (getSdrDragView().IsDragWithCopy())
2457 rStr+=ImpGetResStr(STR_EditWithCopy);
2460 bool SdrDragMirror::BeginSdrDrag()
2462 SdrHdl* pH1=GetHdlList().GetHdl(HDL_REF1);
2463 SdrHdl* pH2=GetHdlList().GetHdl(HDL_REF2);
2465 if (pH1!=NULL && pH2!=NULL)
2467 DragStat().Ref1()=pH1->GetPos();
2468 DragStat().Ref2()=pH2->GetPos();
2469 Ref1()=pH1->GetPos();
2470 Ref2()=pH2->GetPos();
2471 aDif=pH2->GetPos()-pH1->GetPos();
2472 bool b90=(aDif.X()==0) || aDif.Y()==0;
2473 bool b45=b90 || (Abs(aDif.X())==Abs(aDif.Y()));
2474 nWink=NormAngle360(GetAngle(aDif));
2476 if (!getSdrDragView().IsMirrorAllowed(false,false) && !b45)
2477 return false; // free choice of axis angle not allowed
2479 if (!getSdrDragView().IsMirrorAllowed(true,false) && !b90)
2480 return false; // 45 degrees not allowed either
2482 bSide0=ImpCheckSide(DragStat().GetStart());
2483 Show();
2484 return true;
2486 else
2488 OSL_FAIL("SdrDragMirror::BeginSdrDrag(): Axis of reflection not found.");
2489 return false;
2493 basegfx::B2DHomMatrix SdrDragMirror::getCurrentTransformation()
2495 basegfx::B2DHomMatrix aRetval;
2497 if (bMirrored)
2499 const double fDeltaX(DragStat().GetRef2().X() - DragStat().GetRef1().X());
2500 const double fDeltaY(DragStat().GetRef2().Y() - DragStat().GetRef1().Y());
2501 const double fRotation(atan2(fDeltaY, fDeltaX));
2503 aRetval = basegfx::tools::createTranslateB2DHomMatrix(-DragStat().GetRef1().X(), -DragStat().GetRef1().Y());
2504 aRetval.rotate(-fRotation);
2505 aRetval.scale(1.0, -1.0);
2506 aRetval.rotate(fRotation);
2507 aRetval.translate(DragStat().GetRef1().X(), DragStat().GetRef1().Y());
2510 return aRetval;
2513 void SdrDragMirror::MoveSdrDrag(const Point& rPnt)
2515 if (DragStat().CheckMinMoved(rPnt))
2517 bool bNeuSide=ImpCheckSide(rPnt);
2518 bool bNeuMirr=bSide0!=bNeuSide;
2520 if (bMirrored!=bNeuMirr)
2522 Hide();
2523 bMirrored=bNeuMirr;
2524 DragStat().NextMove(rPnt);
2525 Show();
2530 bool SdrDragMirror::EndSdrDrag(bool bCopy)
2532 Hide();
2534 if (bMirrored)
2536 getSdrDragView().MirrorMarkedObj(DragStat().GetRef1(),DragStat().GetRef2(),bCopy);
2539 return true;
2542 Pointer SdrDragMirror::GetSdrDragPointer() const
2544 return Pointer(POINTER_MIRROR);
2547 ////////////////////////////////////////////////////////////////////////////////////////////////////
2549 TYPEINIT1(SdrDragGradient, SdrDragMethod);
2551 SdrDragGradient::SdrDragGradient(SdrDragView& rNewView, bool bGrad)
2552 : SdrDragMethod(rNewView),
2553 pIAOHandle(NULL),
2554 bIsGradient(bGrad)
2558 void SdrDragGradient::TakeSdrDragComment(XubString& rStr) const
2560 if(IsGradient())
2561 ImpTakeDescriptionStr(STR_DragMethGradient, rStr);
2562 else
2563 ImpTakeDescriptionStr(STR_DragMethTransparence, rStr);
2566 bool SdrDragGradient::BeginSdrDrag()
2568 bool bRetval(false);
2570 pIAOHandle = (SdrHdlGradient*)GetHdlList().GetHdl(IsGradient() ? HDL_GRAD : HDL_TRNS);
2572 if(pIAOHandle)
2574 // save old values
2575 DragStat().Ref1() = pIAOHandle->GetPos();
2576 DragStat().Ref2() = pIAOHandle->Get2ndPos();
2578 // what was hit?
2579 bool bHit(false);
2580 SdrHdlColor* pColHdl = pIAOHandle->GetColorHdl1();
2582 // init handling flags
2583 pIAOHandle->SetMoveSingleHandle(false);
2584 pIAOHandle->SetMoveFirstHandle(false);
2586 // test first color handle
2587 if(pColHdl)
2589 basegfx::B2DPoint aPosition(DragStat().GetStart().X(), DragStat().GetStart().Y());
2591 if(pColHdl->getOverlayObjectList().isHitLogic(aPosition))
2593 bHit = true;
2594 pIAOHandle->SetMoveSingleHandle(true);
2595 pIAOHandle->SetMoveFirstHandle(true);
2599 // test second color handle
2600 pColHdl = pIAOHandle->GetColorHdl2();
2602 if(!bHit && pColHdl)
2604 basegfx::B2DPoint aPosition(DragStat().GetStart().X(), DragStat().GetStart().Y());
2606 if(pColHdl->getOverlayObjectList().isHitLogic(aPosition))
2608 bHit = true;
2609 pIAOHandle->SetMoveSingleHandle(true);
2613 // test gradient handle itself
2614 if(!bHit)
2616 basegfx::B2DPoint aPosition(DragStat().GetStart().X(), DragStat().GetStart().Y());
2618 if(pIAOHandle->getOverlayObjectList().isHitLogic(aPosition))
2620 bHit = true;
2624 // everything up and running :o}
2625 bRetval = bHit;
2627 else
2629 OSL_FAIL("SdrDragGradient::BeginSdrDrag(): IAOGradient not found.");
2632 return bRetval;
2635 void SdrDragGradient::MoveSdrDrag(const Point& rPnt)
2637 if(pIAOHandle && DragStat().CheckMinMoved(rPnt))
2639 DragStat().NextMove(rPnt);
2641 // Do the Move here!!! DragStat().GetStart()
2642 Point aMoveDiff = rPnt - DragStat().GetStart();
2644 if(pIAOHandle->IsMoveSingleHandle())
2646 if(pIAOHandle->IsMoveFirstHandle())
2648 pIAOHandle->SetPos(DragStat().Ref1() + aMoveDiff);
2649 if(pIAOHandle->GetColorHdl1())
2650 pIAOHandle->GetColorHdl1()->SetPos(DragStat().Ref1() + aMoveDiff);
2652 else
2654 pIAOHandle->Set2ndPos(DragStat().Ref2() + aMoveDiff);
2655 if(pIAOHandle->GetColorHdl2())
2656 pIAOHandle->GetColorHdl2()->SetPos(DragStat().Ref2() + aMoveDiff);
2659 else
2661 pIAOHandle->SetPos(DragStat().Ref1() + aMoveDiff);
2662 pIAOHandle->Set2ndPos(DragStat().Ref2() + aMoveDiff);
2664 if(pIAOHandle->GetColorHdl1())
2665 pIAOHandle->GetColorHdl1()->SetPos(DragStat().Ref1() + aMoveDiff);
2667 if(pIAOHandle->GetColorHdl2())
2668 pIAOHandle->GetColorHdl2()->SetPos(DragStat().Ref2() + aMoveDiff);
2671 // new state
2672 pIAOHandle->FromIAOToItem(getSdrDragView().GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(), false, false);
2676 bool SdrDragGradient::EndSdrDrag(bool /*bCopy*/)
2678 Ref1() = pIAOHandle->GetPos();
2679 Ref2() = pIAOHandle->Get2ndPos();
2681 // new state
2682 pIAOHandle->FromIAOToItem(getSdrDragView().GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(), true, true);
2684 return true;
2687 void SdrDragGradient::CancelSdrDrag()
2689 // restore old values
2690 pIAOHandle->SetPos(DragStat().Ref1());
2691 pIAOHandle->Set2ndPos(DragStat().Ref2());
2693 if(pIAOHandle->GetColorHdl1())
2694 pIAOHandle->GetColorHdl1()->SetPos(DragStat().Ref1());
2696 if(pIAOHandle->GetColorHdl2())
2697 pIAOHandle->GetColorHdl2()->SetPos(DragStat().Ref2());
2699 // new state
2700 pIAOHandle->FromIAOToItem(getSdrDragView().GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(), true, false);
2703 Pointer SdrDragGradient::GetSdrDragPointer() const
2705 return Pointer(POINTER_REFHAND);
2708 ////////////////////////////////////////////////////////////////////////////////////////////////////
2710 TYPEINIT1(SdrDragCrook,SdrDragMethod);
2712 SdrDragCrook::SdrDragCrook(SdrDragView& rNewView)
2713 : SdrDragMethod(rNewView),
2714 aFact(1,1),
2715 bContortionAllowed(false),
2716 bNoContortionAllowed(false),
2717 bContortion(false),
2718 bResizeAllowed(false),
2719 bResize(false),
2720 bRotateAllowed(false),
2721 bRotate(false),
2722 bVertical(false),
2723 bValid(false),
2724 bLft(false),
2725 bRgt(false),
2726 bUpr(false),
2727 bLwr(false),
2728 bAtCenter(false),
2729 nWink(0),
2730 nMarkSize(0),
2731 eMode(SDRCROOK_ROTATE)
2735 void SdrDragCrook::TakeSdrDragComment(XubString& rStr) const
2737 ImpTakeDescriptionStr(!bContortion ? STR_DragMethCrook : STR_DragMethCrookContortion, rStr);
2739 if(bValid)
2741 rStr.AppendAscii(" (");
2743 sal_Int32 nVal(nWink);
2745 if(bAtCenter)
2746 nVal *= 2;
2748 nVal = Abs(nVal);
2749 rtl::OUString aStr;
2750 getSdrDragView().GetModel()->TakeWinkStr(nVal, aStr);
2751 rStr.Append(aStr);
2752 rStr += sal_Unicode(')');
2755 if(getSdrDragView().IsDragWithCopy())
2756 rStr += ImpGetResStr(STR_EditWithCopy);
2759 // These defines parameterize the created raster
2760 // for interactions
2761 #define DRAG_CROOK_RASTER_MINIMUM (4)
2762 #define DRAG_CROOK_RASTER_MAXIMUM (15)
2763 #define DRAG_CROOK_RASTER_DISTANCE (30)
2765 basegfx::B2DPolyPolygon impCreateDragRaster(SdrPageView& rPageView, const Rectangle& rMarkRect)
2767 basegfx::B2DPolyPolygon aRetval;
2769 if(rPageView.PageWindowCount())
2771 OutputDevice& rOut = (rPageView.GetPageWindow(0)->GetPaintWindow().GetOutputDevice());
2772 Rectangle aPixelSize = rOut.LogicToPixel(rMarkRect);
2773 sal_uInt32 nHorDiv(aPixelSize.GetWidth() / DRAG_CROOK_RASTER_DISTANCE);
2774 sal_uInt32 nVerDiv(aPixelSize.GetHeight() / DRAG_CROOK_RASTER_DISTANCE);
2776 if(nHorDiv > DRAG_CROOK_RASTER_MAXIMUM)
2777 nHorDiv = DRAG_CROOK_RASTER_MAXIMUM;
2778 if(nHorDiv < DRAG_CROOK_RASTER_MINIMUM)
2779 nHorDiv = DRAG_CROOK_RASTER_MINIMUM;
2781 if(nVerDiv > DRAG_CROOK_RASTER_MAXIMUM)
2782 nVerDiv = DRAG_CROOK_RASTER_MAXIMUM;
2783 if(nVerDiv < DRAG_CROOK_RASTER_MINIMUM)
2784 nVerDiv = DRAG_CROOK_RASTER_MINIMUM;
2786 const double fXLen(rMarkRect.GetWidth() / (double)nHorDiv);
2787 const double fYLen(rMarkRect.GetHeight() / (double)nVerDiv);
2788 double fYPos(rMarkRect.Top());
2789 sal_uInt32 a, b;
2791 for(a = 0; a <= nVerDiv; a++)
2793 // horizontal lines
2794 for(b = 0; b < nHorDiv; b++)
2796 basegfx::B2DPolygon aHorLineSegment;
2798 const double fNewX(rMarkRect.Left() + (b * fXLen));
2799 aHorLineSegment.append(basegfx::B2DPoint(fNewX, fYPos));
2800 aHorLineSegment.appendBezierSegment(
2801 basegfx::B2DPoint(fNewX + (fXLen * (1.0 / 3.0)), fYPos),
2802 basegfx::B2DPoint(fNewX + (fXLen * (2.0 / 3.0)), fYPos),
2803 basegfx::B2DPoint(fNewX + fXLen, fYPos));
2804 aRetval.append(aHorLineSegment);
2807 // increments
2808 fYPos += fYLen;
2811 double fXPos(rMarkRect.Left());
2813 for(a = 0; a <= nHorDiv; a++)
2815 // vertical lines
2816 for(b = 0; b < nVerDiv; b++)
2818 basegfx::B2DPolygon aVerLineSegment;
2820 const double fNewY(rMarkRect.Top() + (b * fYLen));
2821 aVerLineSegment.append(basegfx::B2DPoint(fXPos, fNewY));
2822 aVerLineSegment.appendBezierSegment(
2823 basegfx::B2DPoint(fXPos, fNewY + (fYLen * (1.0 / 3.0))),
2824 basegfx::B2DPoint(fXPos, fNewY + (fYLen * (2.0 / 3.0))),
2825 basegfx::B2DPoint(fXPos, fNewY + fYLen));
2826 aRetval.append(aVerLineSegment);
2829 // increments
2830 fXPos += fXLen;
2834 return aRetval;
2837 void SdrDragCrook::createSdrDragEntries()
2839 // Add extended frame raster first, so it will be behind objects
2840 if(getSdrDragView().GetSdrPageView())
2842 const basegfx::B2DPolyPolygon aDragRaster(impCreateDragRaster(*getSdrDragView().GetSdrPageView(), GetMarkedRect()));
2844 if(aDragRaster.count())
2846 addSdrDragEntry(new SdrDragEntryPolyPolygon(aDragRaster));
2850 // call parent
2851 SdrDragMethod::createSdrDragEntries();
2854 bool SdrDragCrook::BeginSdrDrag()
2856 bContortionAllowed=getSdrDragView().IsCrookAllowed(false);
2857 bNoContortionAllowed=getSdrDragView().IsCrookAllowed(true);
2858 bResizeAllowed=getSdrDragView().IsResizeAllowed(false);
2859 bRotateAllowed=getSdrDragView().IsRotateAllowed(false);
2861 if (bContortionAllowed || bNoContortionAllowed)
2863 bVertical=(GetDragHdlKind()==HDL_LOWER || GetDragHdlKind()==HDL_UPPER);
2864 aMarkRect=GetMarkedRect();
2865 aMarkCenter=aMarkRect.Center();
2866 nMarkSize=bVertical ? (aMarkRect.GetHeight()-1) : (aMarkRect.GetWidth()-1);
2867 aCenter=aMarkCenter;
2868 aStart=DragStat().GetStart();
2869 Show();
2870 return true;
2872 else
2874 return false;
2878 void SdrDragCrook::_MovAllPoints(basegfx::B2DPolyPolygon& rTarget)
2880 SdrPageView* pPV = getSdrDragView().GetSdrPageView();
2882 if(pPV)
2884 XPolyPolygon aTempPolyPoly(rTarget);
2886 if (pPV->HasMarkedObjPageView())
2888 sal_uInt16 nPolyAnz=aTempPolyPoly.Count();
2890 if (!bContortion && !getSdrDragView().IsNoDragXorPolys())
2892 sal_uInt16 n1st=0,nLast=0;
2893 Point aC(aCenter);
2895 while (n1st<nPolyAnz)
2897 nLast=n1st;
2898 while (nLast<nPolyAnz && aTempPolyPoly[nLast].GetPointCount()!=0) nLast++;
2899 Rectangle aBound(aTempPolyPoly[n1st].GetBoundRect());
2900 sal_uInt16 i;
2902 for (i=n1st+1; i<nLast; i++)
2904 aBound.Union(aTempPolyPoly[n1st].GetBoundRect());
2907 Point aCtr0(aBound.Center());
2908 Point aCtr1(aCtr0);
2910 if (bResize)
2912 Fraction aFact1(1,1);
2914 if (bVertical)
2916 ResizePoint(aCtr1,aC,aFact1,aFact);
2918 else
2920 ResizePoint(aCtr1,aC,aFact,aFact1);
2924 bool bRotOk=false;
2925 double nSin=0,nCos=0;
2927 if (aRad.X()!=0 && aRad.Y()!=0)
2929 bRotOk=bRotate;
2931 switch (eMode)
2933 case SDRCROOK_ROTATE : CrookRotateXPoint (aCtr1,NULL,NULL,aC,aRad,nSin,nCos,bVertical); break;
2934 case SDRCROOK_SLANT : CrookSlantXPoint (aCtr1,NULL,NULL,aC,aRad,nSin,nCos,bVertical); break;
2935 case SDRCROOK_STRETCH: CrookStretchXPoint(aCtr1,NULL,NULL,aC,aRad,nSin,nCos,bVertical,aMarkRect); break;
2936 } // switch
2939 aCtr1-=aCtr0;
2941 for (i=n1st; i<nLast; i++)
2943 if (bRotOk)
2945 RotateXPoly(aTempPolyPoly[i],aCtr0,nSin,nCos);
2948 aTempPolyPoly[i].Move(aCtr1.X(),aCtr1.Y());
2951 n1st=nLast+1;
2954 else
2956 sal_uInt16 i,j;
2958 for (j=0; j<nPolyAnz; j++)
2960 XPolygon& aPol=aTempPolyPoly[j];
2961 sal_uInt16 nPtAnz=aPol.GetPointCount();
2962 i=0;
2964 while (i<nPtAnz)
2966 Point* pPnt=&aPol[i];
2967 Point* pC1=NULL;
2968 Point* pC2=NULL;
2970 if (i+1<nPtAnz && aPol.IsControl(i))
2971 { // control point on the left
2972 pC1=pPnt;
2973 i++;
2974 pPnt=&aPol[i];
2977 i++;
2979 if (i<nPtAnz && aPol.IsControl(i))
2980 { // control point on the right
2981 pC2=&aPol[i];
2982 i++;
2985 _MovCrookPoint(*pPnt,pC1,pC2);
2991 rTarget = aTempPolyPoly.getB2DPolyPolygon();
2995 void SdrDragCrook::_MovCrookPoint(Point& rPnt, Point* pC1, Point* pC2)
2997 bool bVert=bVertical;
2998 bool bC1=pC1!=NULL;
2999 bool bC2=pC2!=NULL;
3000 Point aC(aCenter);
3002 if (bResize)
3004 Fraction aFact1(1,1);
3006 if (bVert)
3008 ResizePoint(rPnt,aC,aFact1,aFact);
3010 if (bC1)
3011 ResizePoint(*pC1,aC,aFact1,aFact);
3013 if (bC2)
3014 ResizePoint(*pC2,aC,aFact1,aFact);
3016 else
3018 ResizePoint(rPnt,aC,aFact,aFact1);
3020 if (bC1)
3021 ResizePoint(*pC1,aC,aFact,aFact1);
3023 if (bC2)
3024 ResizePoint(*pC2,aC,aFact,aFact1);
3028 if (aRad.X()!=0 && aRad.Y()!=0)
3030 double nSin,nCos;
3032 switch (eMode)
3034 case SDRCROOK_ROTATE : CrookRotateXPoint (rPnt,pC1,pC2,aC,aRad,nSin,nCos,bVert); break;
3035 case SDRCROOK_SLANT : CrookSlantXPoint (rPnt,pC1,pC2,aC,aRad,nSin,nCos,bVert); break;
3036 case SDRCROOK_STRETCH: CrookStretchXPoint(rPnt,pC1,pC2,aC,aRad,nSin,nCos,bVert,aMarkRect); break;
3037 } // switch
3041 void SdrDragCrook::MoveSdrDrag(const Point& rPnt)
3043 if (DragStat().CheckMinMoved(rPnt))
3045 Point aPnt(rPnt);
3046 bool bNeuMoveOnly=getSdrDragView().IsMoveOnlyDragging();
3047 bAtCenter=false;
3048 SdrCrookMode eNeuMode=getSdrDragView().GetCrookMode();
3049 bool bNeuContortion=!bNeuMoveOnly && ((bContortionAllowed && !getSdrDragView().IsCrookNoContortion()) || !bNoContortionAllowed);
3050 bResize=!getSdrDragView().IsOrtho() && bResizeAllowed && !bNeuMoveOnly;
3051 bool bNeuRotate=bRotateAllowed && !bNeuContortion && !bNeuMoveOnly && eNeuMode==SDRCROOK_ROTATE;
3052 long nSA=0;
3054 if (nSA==0)
3055 aPnt=GetSnapPos(aPnt);
3057 Point aNeuCenter(aMarkCenter.X(),aStart.Y());
3059 if (bVertical)
3061 aNeuCenter.X()=aStart.X();
3062 aNeuCenter.Y()=aMarkCenter.Y();
3065 if (!getSdrDragView().IsCrookAtCenter())
3067 switch (GetDragHdlKind())
3069 case HDL_UPLFT: aNeuCenter.X()=aMarkRect.Right(); bLft=true; break;
3070 case HDL_UPPER: aNeuCenter.Y()=aMarkRect.Bottom(); bUpr=true; break;
3071 case HDL_UPRGT: aNeuCenter.X()=aMarkRect.Left(); bRgt=true; break;
3072 case HDL_LEFT : aNeuCenter.X()=aMarkRect.Right(); bLft=true; break;
3073 case HDL_RIGHT: aNeuCenter.X()=aMarkRect.Left(); bRgt=true; break;
3074 case HDL_LWLFT: aNeuCenter.X()=aMarkRect.Right(); bLft=true; break;
3075 case HDL_LOWER: aNeuCenter.Y()=aMarkRect.Top(); bLwr=true; break;
3076 case HDL_LWRGT: aNeuCenter.X()=aMarkRect.Left(); bRgt=true; break;
3077 default: bAtCenter=true;
3080 else
3081 bAtCenter=true;
3083 Fraction aNeuFact(1,1);
3084 long dx1=aPnt.X()-aNeuCenter.X();
3085 long dy1=aPnt.Y()-aNeuCenter.Y();
3086 bValid=bVertical ? dx1!=0 : dy1!=0;
3088 if (bValid)
3090 if (bVertical)
3091 bValid=Abs(dx1)*100>Abs(dy1);
3092 else
3093 bValid=Abs(dy1)*100>Abs(dx1);
3096 long nNeuRad=0;
3097 nWink=0;
3099 if (bValid)
3101 double a=0; // slope of the radius
3102 long nPntWink=0;
3104 if (bVertical)
3106 a=((double)dy1)/((double)dx1); // slope of the radius
3107 nNeuRad=((long)(dy1*a)+dx1) /2;
3108 aNeuCenter.X()+=nNeuRad;
3109 nPntWink=GetAngle(aPnt-aNeuCenter);
3111 else
3113 a=((double)dx1)/((double)dy1); // slope of the radius
3114 nNeuRad=((long)(dx1*a)+dy1) /2;
3115 aNeuCenter.Y()+=nNeuRad;
3116 nPntWink=GetAngle(aPnt-aNeuCenter)-9000;
3119 if (!bAtCenter)
3121 if (nNeuRad<0)
3123 if (bRgt) nPntWink+=18000;
3124 if (bLft) nPntWink=18000-nPntWink;
3125 if (bLwr) nPntWink=-nPntWink;
3127 else
3129 if (bRgt) nPntWink=-nPntWink;
3130 if (bUpr) nPntWink=18000-nPntWink;
3131 if (bLwr) nPntWink+=18000;
3134 nPntWink=NormAngle360(nPntWink);
3136 else
3138 if (nNeuRad<0) nPntWink+=18000;
3139 if (bVertical) nPntWink=18000-nPntWink;
3140 nPntWink=NormAngle180(nPntWink);
3141 nPntWink=Abs(nPntWink);
3144 double nUmfang=2*Abs(nNeuRad)*nPi;
3146 if (bResize)
3148 if (nSA!=0)
3149 { // angle snapping
3150 long nWink0=nPntWink;
3151 nPntWink+=nSA/2;
3152 nPntWink/=nSA;
3153 nPntWink*=nSA;
3154 BigInt a2(nNeuRad);
3155 a2*=BigInt(nWink);
3156 a2/=BigInt(nWink0);
3157 nNeuRad=long(a2);
3159 if (bVertical)
3160 aNeuCenter.X()=aStart.X()+nNeuRad;
3161 else
3162 aNeuCenter.Y()=aStart.Y()+nNeuRad;
3165 long nMul=(long)(nUmfang*NormAngle360(nPntWink)/36000);
3167 if (bAtCenter)
3168 nMul*=2;
3170 aNeuFact=Fraction(nMul,nMarkSize);
3171 nWink=nPntWink;
3173 else
3175 nWink=(long)((nMarkSize*360/nUmfang)*100)/2;
3177 if (nWink==0)
3178 bValid=false;
3180 if (bValid && nSA!=0)
3181 { // angle snapping
3182 long nWink0=nWink;
3183 nWink+=nSA/2;
3184 nWink/=nSA;
3185 nWink*=nSA;
3186 BigInt a2(nNeuRad);
3187 a2*=BigInt(nWink);
3188 a2/=BigInt(nWink0);
3189 nNeuRad=long(a2);
3191 if (bVertical)
3192 aNeuCenter.X()=aStart.X()+nNeuRad;
3193 else
3194 aNeuCenter.Y()=aStart.Y()+nNeuRad;
3199 if (nWink==0 || nNeuRad==0)
3200 bValid=false;
3202 if (!bValid)
3203 nNeuRad=0;
3205 if (!bValid && bResize)
3207 long nMul=bVertical ? dy1 : dx1;
3209 if (bLft || bUpr)
3210 nMul=-nMul;
3212 long nDiv=nMarkSize;
3214 if (bAtCenter)
3216 nMul*=2;
3217 nMul=Abs(nMul);
3220 aNeuFact=Fraction(nMul,nDiv);
3223 if (aNeuCenter!=aCenter || bNeuContortion!=bContortion || aNeuFact!=aFact ||
3224 bNeuMoveOnly != getMoveOnly() || bNeuRotate!=bRotate || eNeuMode!=eMode)
3226 Hide();
3227 setMoveOnly(bNeuMoveOnly);
3228 bRotate=bNeuRotate;
3229 eMode=eNeuMode;
3230 bContortion=bNeuContortion;
3231 aCenter=aNeuCenter;
3232 aFact=aNeuFact;
3233 aRad=Point(nNeuRad,nNeuRad);
3234 bResize=aFact!=Fraction(1,1) && aFact.GetDenominator()!=0 && aFact.IsValid();
3235 DragStat().NextMove(aPnt);
3236 Show();
3241 void SdrDragCrook::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
3243 const bool bDoResize(aFact!=Fraction(1,1));
3244 const bool bDoCrook(aCenter!=aMarkCenter && aRad.X()!=0 && aRad.Y()!=0);
3246 if (bDoCrook || bDoResize)
3248 if (bDoResize)
3250 Fraction aFact1(1,1);
3252 if (bContortion)
3254 if (bVertical)
3256 rTarget.Resize(aCenter,aFact1,aFact);
3258 else
3260 rTarget.Resize(aCenter,aFact,aFact1);
3263 else
3265 Point aCtr0(rTarget.GetSnapRect().Center());
3266 Point aCtr1(aCtr0);
3268 if (bVertical)
3270 ResizePoint(aCtr1,aCenter,aFact1,aFact);
3272 else
3274 ResizePoint(aCtr1,aCenter,aFact,aFact1);
3277 Size aSiz(aCtr1.X()-aCtr0.X(),aCtr1.Y()-aCtr0.Y());
3279 rTarget.Move(aSiz);
3283 if (bDoCrook)
3285 const Rectangle aLocalMarkRect(getSdrDragView().GetMarkedObjRect());
3286 const bool bLocalRotate(!bContortion && eMode == SDRCROOK_ROTATE && getSdrDragView().IsRotateAllowed(false));
3288 getSdrDragView().ImpCrookObj(&rTarget,aCenter,aRad,eMode,bVertical,!bContortion,bLocalRotate,aLocalMarkRect);
3293 void SdrDragCrook::applyCurrentTransformationToPolyPolygon(basegfx::B2DPolyPolygon& rTarget)
3295 // use helper derived from old stuff
3296 _MovAllPoints(rTarget);
3299 bool SdrDragCrook::EndSdrDrag(bool bCopy)
3301 Hide();
3303 if (bResize && aFact==Fraction(1,1))
3304 bResize=false;
3306 const bool bUndo = getSdrDragView().IsUndoEnabled();
3308 bool bDoCrook=aCenter!=aMarkCenter && aRad.X()!=0 && aRad.Y()!=0;
3310 if (bDoCrook || bResize)
3312 if (bResize && bUndo)
3314 XubString aStr;
3315 ImpTakeDescriptionStr(!bContortion?STR_EditCrook:STR_EditCrookContortion,aStr);
3317 if (bCopy)
3318 aStr+=ImpGetResStr(STR_EditWithCopy);
3320 getSdrDragView().BegUndo(aStr);
3323 if (bResize)
3325 Fraction aFact1(1,1);
3327 if (bContortion)
3329 if (bVertical)
3330 getSdrDragView().ResizeMarkedObj(aCenter,aFact1,aFact,bCopy);
3331 else
3332 getSdrDragView().ResizeMarkedObj(aCenter,aFact,aFact1,bCopy);
3334 else
3336 if (bCopy)
3337 getSdrDragView().CopyMarkedObj();
3339 sal_uLong nMarkAnz=getSdrDragView().GetMarkedObjectList().GetMarkCount();
3341 for (sal_uLong nm=0; nm<nMarkAnz; nm++)
3343 SdrMark* pM=getSdrDragView().GetMarkedObjectList().GetMark(nm);
3344 SdrObject* pO=pM->GetMarkedSdrObj();
3345 Point aCtr0(pO->GetSnapRect().Center());
3346 Point aCtr1(aCtr0);
3348 if (bVertical)
3349 ResizePoint(aCtr1,aCenter,aFact1,aFact);
3350 else
3351 ResizePoint(aCtr1,aCenter,aFact,aFact1);
3353 Size aSiz(aCtr1.X()-aCtr0.X(),aCtr1.Y()-aCtr0.Y());
3354 if( bUndo )
3355 AddUndo(getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoMoveObject(*pO,aSiz));
3356 pO->Move(aSiz);
3360 bCopy=false;
3363 if (bDoCrook)
3365 getSdrDragView().CrookMarkedObj(aCenter,aRad,eMode,bVertical,!bContortion,bCopy);
3366 getSdrDragView().SetLastCrookCenter(aCenter);
3369 if (bResize && bUndo)
3370 getSdrDragView().EndUndo();
3372 return true;
3375 return false;
3378 Pointer SdrDragCrook::GetSdrDragPointer() const
3380 return Pointer(POINTER_CROOK);
3383 ////////////////////////////////////////////////////////////////////////////////////////////////////
3385 TYPEINIT1(SdrDragDistort,SdrDragMethod);
3387 SdrDragDistort::SdrDragDistort(SdrDragView& rNewView)
3388 : SdrDragMethod(rNewView),
3389 nPolyPt(0),
3390 bContortionAllowed(false),
3391 bNoContortionAllowed(false),
3392 bContortion(false)
3396 void SdrDragDistort::TakeSdrDragComment(XubString& rStr) const
3398 ImpTakeDescriptionStr(STR_DragMethDistort, rStr);
3400 rtl::OUString aStr;
3402 rStr.AppendAscii(" (x=");
3403 getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDX(), aStr);
3404 rStr.Append(aStr);
3405 rStr.AppendAscii(" y=");
3406 getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDY(), aStr);
3407 rStr.Append(aStr);
3408 rStr += sal_Unicode(')');
3410 if(getSdrDragView().IsDragWithCopy())
3411 rStr += ImpGetResStr(STR_EditWithCopy);
3414 void SdrDragDistort::createSdrDragEntries()
3416 // Add extended frame raster first, so it will be behind objects
3417 if(getSdrDragView().GetSdrPageView())
3419 const basegfx::B2DPolyPolygon aDragRaster(impCreateDragRaster(*getSdrDragView().GetSdrPageView(), GetMarkedRect()));
3421 if(aDragRaster.count())
3423 addSdrDragEntry(new SdrDragEntryPolyPolygon(aDragRaster));
3427 // call parent
3428 SdrDragMethod::createSdrDragEntries();
3431 bool SdrDragDistort::BeginSdrDrag()
3433 bContortionAllowed=getSdrDragView().IsDistortAllowed(false);
3434 bNoContortionAllowed=getSdrDragView().IsDistortAllowed(true);
3436 if (bContortionAllowed || bNoContortionAllowed)
3438 SdrHdlKind eKind=GetDragHdlKind();
3439 nPolyPt=0xFFFF;
3441 if (eKind==HDL_UPLFT) nPolyPt=0;
3442 if (eKind==HDL_UPRGT) nPolyPt=1;
3443 if (eKind==HDL_LWRGT) nPolyPt=2;
3444 if (eKind==HDL_LWLFT) nPolyPt=3;
3445 if (nPolyPt>3) return false;
3447 aMarkRect=GetMarkedRect();
3448 aDistortedRect=XPolygon(aMarkRect);
3449 Show();
3450 return true;
3452 else
3454 return false;
3458 void SdrDragDistort::_MovAllPoints(basegfx::B2DPolyPolygon& rTarget)
3460 if (bContortion)
3462 SdrPageView* pPV = getSdrDragView().GetSdrPageView();
3464 if(pPV)
3466 if (pPV->HasMarkedObjPageView())
3468 basegfx::B2DPolyPolygon aDragPolygon(rTarget);
3469 const basegfx::B2DRange aOriginalRange(aMarkRect.Left(), aMarkRect.Top(), aMarkRect.Right(), aMarkRect.Bottom());
3470 const basegfx::B2DPoint aTopLeft(aDistortedRect[0].X(), aDistortedRect[0].Y());
3471 const basegfx::B2DPoint aTopRight(aDistortedRect[1].X(), aDistortedRect[1].Y());
3472 const basegfx::B2DPoint aBottomLeft(aDistortedRect[3].X(), aDistortedRect[3].Y());
3473 const basegfx::B2DPoint aBottomRight(aDistortedRect[2].X(), aDistortedRect[2].Y());
3475 aDragPolygon = basegfx::tools::distort(aDragPolygon, aOriginalRange, aTopLeft, aTopRight, aBottomLeft, aBottomRight);
3476 rTarget = aDragPolygon;
3482 void SdrDragDistort::MoveSdrDrag(const Point& rPnt)
3484 if (DragStat().CheckMinMoved(rPnt))
3486 Point aPnt(GetSnapPos(rPnt));
3488 if (getSdrDragView().IsOrtho())
3489 OrthoDistance8(DragStat().GetStart(),aPnt,getSdrDragView().IsBigOrtho());
3491 bool bNeuContortion=(bContortionAllowed && !getSdrDragView().IsCrookNoContortion()) || !bNoContortionAllowed;
3493 if (bNeuContortion!=bContortion || aDistortedRect[nPolyPt]!=aPnt)
3495 Hide();
3496 aDistortedRect[nPolyPt]=aPnt;
3497 bContortion=bNeuContortion;
3498 DragStat().NextMove(aPnt);
3499 Show();
3504 bool SdrDragDistort::EndSdrDrag(bool bCopy)
3506 Hide();
3507 bool bDoDistort=DragStat().GetDX()!=0 || DragStat().GetDY()!=0;
3509 if (bDoDistort)
3511 getSdrDragView().DistortMarkedObj(aMarkRect,aDistortedRect,!bContortion,bCopy);
3512 return true;
3515 return false;
3518 Pointer SdrDragDistort::GetSdrDragPointer() const
3520 return Pointer(POINTER_REFHAND);
3523 void SdrDragDistort::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
3525 const bool bDoDistort(DragStat().GetDX()!=0 || DragStat().GetDY()!=0);
3527 if (bDoDistort)
3529 getSdrDragView().ImpDistortObj(&rTarget, aMarkRect, aDistortedRect, !bContortion);
3533 void SdrDragDistort::applyCurrentTransformationToPolyPolygon(basegfx::B2DPolyPolygon& rTarget)
3535 // use helper derived from old stuff
3536 _MovAllPoints(rTarget);
3539 ////////////////////////////////////////////////////////////////////////////////////////////////////
3541 TYPEINIT1(SdrDragCrop,SdrDragResize);
3543 SdrDragCrop::SdrDragCrop(SdrDragView& rNewView)
3544 : SdrDragResize(rNewView)
3546 // switch off solid dragging for crop; it just makes no sense since showing
3547 // a 50% transparent object above the original will not be visible
3548 setSolidDraggingActive(false);
3551 void SdrDragCrop::TakeSdrDragComment(XubString& rStr) const
3553 ImpTakeDescriptionStr(STR_DragMethCrop, rStr);
3555 rtl::OUString aStr;
3557 rStr.AppendAscii(" (x=");
3558 getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDX(), aStr);
3559 rStr.Append(aStr);
3560 rStr.AppendAscii(" y=");
3561 getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDY(), aStr);
3562 rStr.Append(aStr);
3563 rStr += sal_Unicode(')');
3565 if(getSdrDragView().IsDragWithCopy())
3566 rStr += ImpGetResStr(STR_EditWithCopy);
3569 bool SdrDragCrop::EndSdrDrag(bool bCopy)
3571 Hide();
3573 if( DragStat().GetDX()==0 && DragStat().GetDY()==0 )
3574 return false;
3576 const SdrMarkList& rMarkList = getSdrDragView().GetMarkedObjectList();
3578 if( rMarkList.GetMarkCount() != 1 )
3579 return false;
3581 SdrGrafObj* pObj = dynamic_cast<SdrGrafObj*>( rMarkList.GetMark( 0 )->GetMarkedSdrObj() );
3583 if( !pObj || (pObj->GetGraphicType() == GRAPHIC_NONE) || (pObj->GetGraphicType() == GRAPHIC_DEFAULT) )
3584 return false;
3586 const GraphicObject& rGraphicObject = pObj->GetGraphicObject();
3587 const MapMode aMapMode100thmm(MAP_100TH_MM);
3588 Size aGraphicSize(rGraphicObject.GetPrefSize());
3590 if( MAP_PIXEL == rGraphicObject.GetPrefMapMode().GetMapUnit() )
3591 aGraphicSize = Application::GetDefaultDevice()->PixelToLogic( aGraphicSize, aMapMode100thmm );
3592 else
3593 aGraphicSize = Application::GetDefaultDevice()->LogicToLogic( aGraphicSize, rGraphicObject.GetPrefMapMode(), aMapMode100thmm);
3595 if( aGraphicSize.nA == 0 || aGraphicSize.nB == 0 )
3596 return false;
3598 const SdrGrafCropItem& rOldCrop = (const SdrGrafCropItem&)pObj->GetMergedItem(SDRATTR_GRAFCROP);
3600 const bool bUndo = getSdrDragView().IsUndoEnabled();
3602 if( bUndo )
3604 String aUndoStr;
3605 ImpTakeDescriptionStr(STR_DragMethCrop, aUndoStr);
3607 getSdrDragView().BegUndo( aUndoStr );
3608 getSdrDragView().AddUndo( getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoGeoObject( *pObj ) );
3611 Rectangle aOldRect( pObj->GetLogicRect() );
3612 getSdrDragView().ResizeMarkedObj(DragStat().Ref1(),aXFact,aYFact,bCopy);
3613 Rectangle aNewRect( pObj->GetLogicRect() );
3615 double fScaleX = ( aGraphicSize.Width() - rOldCrop.GetLeft() - rOldCrop.GetRight() ) / (double)aOldRect.GetWidth();
3616 double fScaleY = ( aGraphicSize.Height() - rOldCrop.GetTop() - rOldCrop.GetBottom() ) / (double)aOldRect.GetHeight();
3618 sal_Int32 nDiffLeft = aNewRect.nLeft - aOldRect.nLeft;
3619 sal_Int32 nDiffTop = aNewRect.nTop - aOldRect.nTop;
3620 sal_Int32 nDiffRight = aNewRect.nRight - aOldRect.nRight;
3621 sal_Int32 nDiffBottom = aNewRect.nBottom - aOldRect.nBottom;
3623 sal_Int32 nLeftCrop = static_cast<sal_Int32>( rOldCrop.GetLeft() + nDiffLeft * fScaleX );
3624 sal_Int32 nTopCrop = static_cast<sal_Int32>( rOldCrop.GetTop() + nDiffTop * fScaleY );
3625 sal_Int32 nRightCrop = static_cast<sal_Int32>( rOldCrop.GetRight() - nDiffRight * fScaleX );
3626 sal_Int32 nBottomCrop = static_cast<sal_Int32>( rOldCrop.GetBottom() - nDiffBottom * fScaleY );
3628 SfxItemPool& rPool = getSdrDragView().GetModel()->GetItemPool();
3629 SfxItemSet aSet( rPool, SDRATTR_GRAFCROP, SDRATTR_GRAFCROP );
3630 aSet.Put( SdrGrafCropItem( nLeftCrop, nTopCrop, nRightCrop, nBottomCrop ) );
3631 getSdrDragView().SetAttributes( aSet, false );
3633 if( bUndo )
3634 getSdrDragView().EndUndo();
3636 return true;
3639 Pointer SdrDragCrop::GetSdrDragPointer() const
3641 return Pointer(POINTER_CROP);
3644 ////////////////////////////////////////////////////////////////////////////////////////////////////
3645 // eof
3647 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */