Update ooo320-m1
[ooovba.git] / svx / source / svdraw / svddrgmt.cxx
blob93d9b9c9074ce881b3924dfedb0b7b9301f13c43
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: svddrgmt.cxx,v $
10 * $Revision: 1.21.6.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
34 #include "svddrgm1.hxx"
35 #include <math.h>
37 #ifndef _MATH_H
38 #define _MATH_H
39 #endif
40 #include <tools/bigint.hxx>
41 #include <vcl/svapp.hxx>
43 #include "xattr.hxx"
44 #include <svx/xpoly.hxx>
45 #include <svx/svdetc.hxx>
46 #include <svx/svdtrans.hxx>
47 #include <svx/svdundo.hxx>
48 #include <svx/svdmark.hxx>
49 #include <svx/svdocapt.hxx>
50 #include <svx/svdpagv.hxx>
51 #include "svdstr.hrc" // Namen aus der Resource
52 #include "svdglob.hxx" // StringCache
53 #include <svx/svddrgv.hxx>
54 #include <svx/svdundo.hxx>
55 #include <svx/svdograf.hxx>
56 #include <svx/dialogs.hrc>
57 #include <svx/dialmgr.hxx>
58 #include <svx/sdgcpitm.hxx>
59 #include <basegfx/polygon/b2dpolygon.hxx>
60 #include <basegfx/polygon/b2dpolygontools.hxx>
61 #include <svx/sdr/overlay/overlaypolypolygon.hxx>
62 #include <svx/sdr/overlay/overlaymanager.hxx>
63 #include <svx/sdr/overlay/overlayrollingrectangle.hxx>
64 #include <svx/sdrpagewindow.hxx>
65 #include <sdrpaintwindow.hxx>
66 #include <basegfx/matrix/b2dhommatrix.hxx>
67 #include <basegfx/polygon/b2dpolypolygontools.hxx>
68 #include <svx/sdr/contact/viewobjectcontact.hxx>
69 #include <svx/sdr/contact/viewcontact.hxx>
70 #include <svx/sdr/contact/displayinfo.hxx>
71 #include <svx/sdr/overlay/overlayprimitive2dsequenceobject.hxx>
72 #include <drawinglayer/primitive2d/unifiedalphaprimitive2d.hxx>
73 #include <svx/sdr/contact/objectcontact.hxx>
74 #include "svditer.hxx"
75 #include <svx/svdopath.hxx>
76 #include <svx/polypolygoneditor.hxx>
77 #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
78 #include <drawinglayer/primitive2d/transformprimitive2d.hxx>
79 #include <drawinglayer/primitive2d/markerarrayprimitive2d.hxx>
80 #include <svx/sdr/primitive2d/sdrattributecreator.hxx>
81 #include <drawinglayer/attribute/sdrattribute.hxx>
82 #include <svx/sdr/primitive2d/sdrdecompositiontools.hxx>
83 #include <svx/svdoole2.hxx>
84 #include <svx/svdovirt.hxx>
85 #include <svx/svdouno.hxx>
86 #include <svx/sdr/primitive2d/sdrprimitivetools.hxx>
88 ////////////////////////////////////////////////////////////////////////////////////////////////////
90 SdrDragEntry::SdrDragEntry()
91 : mbAddToTransparent(false)
95 SdrDragEntry::~SdrDragEntry()
99 ////////////////////////////////////////////////////////////////////////////////////////////////////
101 SdrDragEntryPolyPolygon::SdrDragEntryPolyPolygon(const basegfx::B2DPolyPolygon& rOriginalPolyPolygon)
102 : SdrDragEntry(),
103 maOriginalPolyPolygon(rOriginalPolyPolygon)
107 SdrDragEntryPolyPolygon::~SdrDragEntryPolyPolygon()
111 drawinglayer::primitive2d::Primitive2DSequence SdrDragEntryPolyPolygon::createPrimitive2DSequenceInCurrentState(SdrDragMethod& rDragMethod)
113 drawinglayer::primitive2d::Primitive2DSequence aRetval;
115 if(maOriginalPolyPolygon.count())
117 basegfx::B2DPolyPolygon aCopy(maOriginalPolyPolygon);
118 const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
120 rDragMethod.applyCurrentTransformationToPolyPolygon(aCopy);
121 basegfx::BColor aColA(aSvtOptionsDrawinglayer.GetStripeColorA().getBColor());
122 basegfx::BColor aColB(aSvtOptionsDrawinglayer.GetStripeColorB().getBColor());
123 const double fStripeLength(aSvtOptionsDrawinglayer.GetStripeLength());
125 if(Application::GetSettings().GetStyleSettings().GetHighContrastMode())
127 aColA = aColB = Application::GetSettings().GetStyleSettings().GetHighlightColor().getBColor();
128 aColB.invert();
131 drawinglayer::primitive2d::Primitive2DReference aPolyPolygonMarkerPrimitive2D(
132 new drawinglayer::primitive2d::PolyPolygonMarkerPrimitive2D(aCopy, aColA, aColB, fStripeLength));
134 aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aPolyPolygonMarkerPrimitive2D, 1);
137 return aRetval;
140 ////////////////////////////////////////////////////////////////////////////////////////////////////
142 SdrDragEntrySdrObject::SdrDragEntrySdrObject(const SdrObject& rOriginal, sdr::contact::ObjectContact& rObjectContact, bool bModify)
143 : SdrDragEntry(),
144 maOriginal(rOriginal),
145 mpClone(0),
146 mrObjectContact(rObjectContact),
147 mbModify(bModify)
149 // add SdrObject parts to transparent overlay stuff
150 setAddToTransparent(true);
153 SdrDragEntrySdrObject::~SdrDragEntrySdrObject()
155 if(mpClone)
157 SdrObject::Free(mpClone);
161 drawinglayer::primitive2d::Primitive2DSequence SdrDragEntrySdrObject::createPrimitive2DSequenceInCurrentState(SdrDragMethod& rDragMethod)
163 // for the moment, i need to re-create the clone in all cases. I need to figure
164 // out when clone and original have the same class, so that i can use operator=
165 // in those cases
167 // // copy all other needed stuff
168 // basegfx::B2DHomMatrix aMatrix;
169 // basegfx::B2DPolyPolygon aPolyPolygon;
170 // pOleObject->TRGetBaseGeometry(aMatrix, aPolyPolygon);
171 // pClone->TRSetBaseGeometry(aMatrix, aPolyPolygon);
173 const SdrObject* pSource = &maOriginal;
175 if(mpClone)
177 SdrObject::Free(mpClone);
178 mpClone = 0;
181 if(mbModify)
183 if(!mpClone)
185 mpClone = maOriginal.getFullDragClone();
188 // apply original transformation, implemented at the DragMethods
189 rDragMethod.applyCurrentTransformationToSdrObject(*mpClone);
191 // choose source for geometry data
192 pSource = mpClone;
195 // get VOC and Primitive2DSequence
196 sdr::contact::ViewContact& rVC = pSource->GetViewContact();
197 sdr::contact::ViewObjectContact& rVOC = rVC.GetViewObjectContact(mrObjectContact);
198 sdr::contact::DisplayInfo aDisplayInfo;
200 // Do not use the last ViewPort set at the OC from the last ProcessDisplay(),
201 // here we want the complete primitive sequence without visibility clippings
202 mrObjectContact.resetViewPort();
204 return rVOC.getPrimitive2DSequenceHierarchy(aDisplayInfo);
207 ////////////////////////////////////////////////////////////////////////////////////////////////////
209 SdrDragEntryPointGlueDrag::SdrDragEntryPointGlueDrag(const std::vector< basegfx::B2DPoint >& rPositions, bool bIsPointDrag)
210 : maPositions(rPositions),
211 mbIsPointDrag(bIsPointDrag)
213 // add SdrObject parts to transparent overlay stuff
214 setAddToTransparent(true);
217 SdrDragEntryPointGlueDrag::~SdrDragEntryPointGlueDrag()
221 drawinglayer::primitive2d::Primitive2DSequence SdrDragEntryPointGlueDrag::createPrimitive2DSequenceInCurrentState(SdrDragMethod& rDragMethod)
223 drawinglayer::primitive2d::Primitive2DSequence aRetval;
225 if(maPositions.size())
227 basegfx::B2DPolygon aPolygon;
228 sal_uInt32 a(0);
230 for(a = 0; a < maPositions.size(); a++)
232 aPolygon.append(maPositions[a]);
235 basegfx::B2DPolyPolygon aPolyPolygon(aPolygon);
237 rDragMethod.applyCurrentTransformationToPolyPolygon(aPolyPolygon);
239 const basegfx::B2DPolygon aTransformed(aPolyPolygon.getB2DPolygon(0));
240 std::vector< basegfx::B2DPoint > aTransformedPositions;
242 aTransformedPositions.reserve(aTransformed.count());
244 for(a = 0; a < aTransformed.count(); a++)
246 aTransformedPositions.push_back(aTransformed.getB2DPoint(a));
249 if(mbIsPointDrag)
251 const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
252 basegfx::BColor aColor(aSvtOptionsDrawinglayer.GetStripeColorA().getBColor());
254 if(Application::GetSettings().GetStyleSettings().GetHighContrastMode())
256 aColor = Application::GetSettings().GetStyleSettings().GetHighlightColor().getBColor();
259 drawinglayer::primitive2d::Primitive2DReference aMarkerArrayPrimitive2D(
260 new drawinglayer::primitive2d::MarkerArrayPrimitive2D(aTransformedPositions,
261 drawinglayer::primitive2d::createDefaultCross_3x3(aColor)));
263 aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aMarkerArrayPrimitive2D, 1);
265 else
267 const basegfx::BColor aBackPen(1.0, 1.0, 1.0);
268 const basegfx::BColor aRGBFrontColor(0.0, 0.0, 1.0); // COL_LIGHTBLUE
269 drawinglayer::primitive2d::Primitive2DReference aMarkerArrayPrimitive2D(
270 new drawinglayer::primitive2d::MarkerArrayPrimitive2D(aTransformedPositions,
271 drawinglayer::primitive2d::createDefaultGluepoint_7x7(aBackPen, aRGBFrontColor)));
273 aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aMarkerArrayPrimitive2D, 1);
277 return aRetval;
280 ////////////////////////////////////////////////////////////////////////////////////////////////////
282 TYPEINIT0(SdrDragMethod);
284 void SdrDragMethod::resetSdrDragEntries()
286 // clear entries; creation is on demand
287 clearSdrDragEntries();
290 basegfx::B2DRange SdrDragMethod::getCurrentRange() const
292 return getB2DRangeFromOverlayObjectList();
295 void SdrDragMethod::createSdrDragEntries()
297 if(getSdrDragView().GetSdrPageView() && getSdrDragView().GetSdrPageView()->HasMarkedObjPageView())
299 if(getSdrDragView().IsDraggingPoints())
301 createSdrDragEntries_PointDrag();
303 else if(getSdrDragView().IsDraggingGluePoints())
305 createSdrDragEntries_GlueDrag();
307 else
309 if(getSolidDraggingActive())
311 createSdrDragEntries_SolidDrag();
313 else
315 createSdrDragEntries_PolygonDrag();
321 void SdrDragMethod::createSdrDragEntries_SolidDrag()
323 const sal_uInt32 nMarkAnz(getSdrDragView().GetMarkedObjectCount());
324 SdrPageView* pPV = getSdrDragView().GetSdrPageView();
326 if(pPV)
328 for(sal_uInt32 a(0); a < nMarkAnz; a++)
330 SdrMark* pM = getSdrDragView().GetSdrMarkByIndex(a);
332 if(pM->GetPageView() == pPV)
334 const SdrObject* pObject = pM->GetMarkedSdrObj();
336 if(pObject)
338 if(pPV->PageWindowCount())
340 sdr::contact::ObjectContact& rOC = pPV->GetPageWindow(0)->GetObjectContact();
341 SdrObjListIter aIter(*pObject);
343 while(aIter.IsMore())
345 SdrObject* pCandidate = aIter.Next();
347 if(pCandidate)
349 const bool bSuppressFullDrag(!pCandidate->supportsFullDrag());
350 bool bAddWireframe(bSuppressFullDrag);
352 if(!bAddWireframe && !pCandidate->HasLineStyle())
354 // add wireframe for objects without outline
355 bAddWireframe = true;
358 if(!bSuppressFullDrag)
360 // add full obejct drag; Clone() at the object has to work
361 // for this
362 addSdrDragEntry(new SdrDragEntrySdrObject(*pCandidate, rOC, true));
365 if(bAddWireframe)
367 // when dragging a 50% transparent copy of a filled or not filled object without
368 // outline, this is normally hard to see. Add extra wireframe in that case. This
369 // works nice e.g. with thext frames etc.
370 addSdrDragEntry(new SdrDragEntryPolyPolygon(pCandidate->TakeXorPoly()));
381 void SdrDragMethod::createSdrDragEntries_PolygonDrag()
383 const sal_uInt32 nMarkAnz(getSdrDragView().GetMarkedObjectCount());
384 bool bNoPolygons(getSdrDragView().IsNoDragXorPolys() || nMarkAnz > getSdrDragView().GetDragXorPolyLimit());
385 basegfx::B2DPolyPolygon aResult;
386 sal_uInt32 nPointCount(0);
388 for(sal_uInt32 a(0); !bNoPolygons && a < nMarkAnz; a++)
390 SdrMark* pM = getSdrDragView().GetSdrMarkByIndex(a);
392 if(pM->GetPageView() == getSdrDragView().GetSdrPageView())
394 const basegfx::B2DPolyPolygon aNewPolyPolygon(pM->GetMarkedSdrObj()->TakeXorPoly());
396 for(sal_uInt32 b(0); b < aNewPolyPolygon.count(); b++)
398 nPointCount += aNewPolyPolygon.getB2DPolygon(b).count();
401 if(nPointCount > getSdrDragView().GetDragXorPointLimit())
403 bNoPolygons = true;
406 if(!bNoPolygons)
408 aResult.append(aNewPolyPolygon);
413 if(bNoPolygons)
415 const Rectangle aR(getSdrDragView().GetSdrPageView()->MarkSnap());
416 const basegfx::B2DRange aNewRectangle(aR.Left(), aR.Top(), aR.Right(), aR.Bottom());
417 basegfx::B2DPolygon aNewPolygon(basegfx::tools::createPolygonFromRect(aNewRectangle));
419 aResult = basegfx::B2DPolyPolygon(basegfx::tools::expandToCurve(aNewPolygon));
422 if(aResult.count())
424 addSdrDragEntry(new SdrDragEntryPolyPolygon(aResult));
428 void SdrDragMethod::createSdrDragEntries_PointDrag()
430 const sal_uInt32 nMarkAnz(getSdrDragView().GetMarkedObjectCount());
431 std::vector< basegfx::B2DPoint > aPositions;
433 for(sal_uInt32 nm(0); nm < nMarkAnz; nm++)
435 SdrMark* pM = getSdrDragView().GetSdrMarkByIndex(nm);
437 if(pM->GetPageView() == getSdrDragView().GetSdrPageView())
439 const SdrUShortCont* pPts = pM->GetMarkedPoints();
441 if(pPts && pPts->GetCount())
443 const SdrObject* pObj = pM->GetMarkedSdrObj();
444 const SdrPathObj* pPath = dynamic_cast< const SdrPathObj* >(pObj);
446 if(pPath)
448 const basegfx::B2DPolyPolygon aPathXPP = pPath->GetPathPoly();
450 if(aPathXPP.count())
452 const sal_uInt32 nPtAnz(pPts->GetCount());
454 for(sal_uInt32 nPtNum(0); nPtNum < nPtAnz; nPtNum++)
456 sal_uInt32 nPolyNum, nPointNum;
457 const sal_uInt16 nObjPt(pPts->GetObject(nPtNum));
459 if(sdr::PolyPolygonEditor::GetRelativePolyPoint(aPathXPP, nObjPt, nPolyNum, nPointNum))
461 aPositions.push_back(aPathXPP.getB2DPolygon(nPolyNum).getB2DPoint(nPointNum));
470 if(aPositions.size())
472 addSdrDragEntry(new SdrDragEntryPointGlueDrag(aPositions, true));
476 void SdrDragMethod::createSdrDragEntries_GlueDrag()
478 const sal_uInt32 nMarkAnz(getSdrDragView().GetMarkedObjectCount());
479 std::vector< basegfx::B2DPoint > aPositions;
481 for(sal_uInt32 nm(0); nm < nMarkAnz; nm++)
483 SdrMark* pM = getSdrDragView().GetSdrMarkByIndex(nm);
485 if(pM->GetPageView() == getSdrDragView().GetSdrPageView())
487 const SdrUShortCont* pPts = pM->GetMarkedGluePoints();
489 if(pPts && pPts->GetCount())
491 const SdrObject* pObj = pM->GetMarkedSdrObj();
492 const SdrGluePointList* pGPL = pObj->GetGluePointList();
494 if(pGPL)
496 const sal_uInt32 nPtAnz(pPts->GetCount());
498 for(sal_uInt32 nPtNum(0); nPtNum < nPtAnz; nPtNum++)
500 const sal_uInt16 nObjPt(pPts->GetObject(nPtNum));
501 const sal_uInt16 nGlueNum(pGPL->FindGluePoint(nObjPt));
503 if(SDRGLUEPOINT_NOTFOUND != nGlueNum)
505 const Point aPoint((*pGPL)[nGlueNum].GetAbsolutePos(*pObj));
506 aPositions.push_back(basegfx::B2DPoint(aPoint.X(), aPoint.Y()));
514 if(aPositions.size())
516 addSdrDragEntry(new SdrDragEntryPointGlueDrag(aPositions, false));
520 void SdrDragMethod::ImpTakeDescriptionStr(sal_uInt16 nStrCacheID, XubString& rStr, sal_uInt16 nVal) const
522 sal_uInt16 nOpt=0;
523 if (IsDraggingPoints()) {
524 nOpt=IMPSDR_POINTSDESCRIPTION;
525 } else if (IsDraggingGluePoints()) {
526 nOpt=IMPSDR_GLUEPOINTSDESCRIPTION;
528 getSdrDragView().ImpTakeDescriptionStr(nStrCacheID,rStr,nVal,nOpt);
531 SdrObject* SdrDragMethod::GetDragObj() const
533 SdrObject* pObj=NULL;
534 if (getSdrDragView().pDragHdl!=NULL) pObj=getSdrDragView().pDragHdl->GetObj();
535 if (pObj==NULL) pObj=getSdrDragView().pMarkedObj;
536 return pObj;
539 SdrPageView* SdrDragMethod::GetDragPV() const
541 SdrPageView* pPV=NULL;
542 if (getSdrDragView().pDragHdl!=NULL) pPV=getSdrDragView().pDragHdl->GetPageView();
543 if (pPV==NULL) pPV=getSdrDragView().pMarkedPV;
544 return pPV;
547 void SdrDragMethod::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
549 // the original applies the transformation using TRGetBaseGeometry/TRSetBaseGeometry.
550 // Later this should be the only needed one for linear transforms (not for SdrDragCrook and
551 // SdrDragDistort, those are NOT linear). Currently, this can not yet be used since the
552 // special handling of rotate/mirror due to the not-being-able to handle it in the old
553 // drawinglayer stuff. Text would currently not correctly be mirrored in the preview.
554 basegfx::B2DHomMatrix aObjectTransform;
555 basegfx::B2DPolyPolygon aObjectPolyPolygon;
556 bool bPolyUsed(rTarget.TRGetBaseGeometry(aObjectTransform, aObjectPolyPolygon));
558 // apply transform to object transform
559 aObjectTransform *= getCurrentTransformation();
561 if(bPolyUsed)
563 // do something special since the object size is in the polygon
564 // break up matrix to get the scale
565 basegfx::B2DTuple aScale;
566 basegfx::B2DTuple aTranslate;
567 double fRotate, fShearX;
568 aObjectTransform.decompose(aScale, aTranslate, fRotate, fShearX);
570 // get polygon's pos and size
571 const basegfx::B2DRange aPolyRange(aObjectPolyPolygon.getB2DRange());
573 // get the scaling factors (do not mirror, this is in the object transformation)
574 const double fScaleX(fabs(aScale.getX()) / (basegfx::fTools::equalZero(aPolyRange.getWidth()) ? 1.0 : aPolyRange.getWidth()));
575 const double fScaleY(fabs(aScale.getY()) / (basegfx::fTools::equalZero(aPolyRange.getHeight()) ? 1.0 : aPolyRange.getHeight()));
577 // prepare transform matrix for polygon
578 basegfx::B2DHomMatrix aPolyTransform;
580 aPolyTransform.translate(-aPolyRange.getMinX(), -aPolyRange.getMinY());
581 aPolyTransform.scale(fScaleX, fScaleY);
583 // normally the poly should be moved back, but the translation is in the object
584 // transformation and thus does not need to be done
585 // aPolyTransform.translate(-aPolyRange.getMinX(), -aPolyRange.getMinY());
587 // transform the polygon
588 aObjectPolyPolygon.transform(aPolyTransform);
591 rTarget.TRSetBaseGeometry(getCurrentTransformation() * aObjectTransform, aObjectPolyPolygon);
594 void SdrDragMethod::applyCurrentTransformationToPolyPolygon(basegfx::B2DPolyPolygon& rTarget)
596 // original uses CurrentTransformation
597 rTarget.transform(getCurrentTransformation());
600 SdrDragMethod::SdrDragMethod(SdrDragView& rNewView)
601 : maSdrDragEntries(),
602 maOverlayObjectList(),
603 mrSdrDragView(rNewView),
604 mbMoveOnly(false),
605 mbSolidDraggingActive(getSdrDragView().IsSolidDragging())
607 if(mbSolidDraggingActive && Application::GetSettings().GetStyleSettings().GetHighContrastMode())
609 // fallback to wireframe when high contrast is used
610 mbSolidDraggingActive = false;
614 SdrDragMethod::~SdrDragMethod()
616 clearSdrDragEntries();
619 void SdrDragMethod::Show()
621 getSdrDragView().ShowDragObj();
624 void SdrDragMethod::Hide()
626 getSdrDragView().HideDragObj();
629 basegfx::B2DHomMatrix SdrDragMethod::getCurrentTransformation()
631 return basegfx::B2DHomMatrix();
634 void SdrDragMethod::CancelSdrDrag()
636 Hide();
639 void SdrDragMethod::CreateOverlayGeometry(sdr::overlay::OverlayManager& rOverlayManager)
641 // create SdrDragEntries on demand
642 if(!maSdrDragEntries.size())
644 createSdrDragEntries();
647 // if there are entries, derive OverlayObjects fromthe entries, including
648 // modification from current interactive state
649 if(maSdrDragEntries.size())
651 drawinglayer::primitive2d::Primitive2DSequence aResult;
652 drawinglayer::primitive2d::Primitive2DSequence aResultTransparent;
654 for(sal_uInt32 a(0); a < maSdrDragEntries.size(); a++)
656 SdrDragEntry* pCandidate = maSdrDragEntries[a];
658 if(pCandidate)
660 const drawinglayer::primitive2d::Primitive2DSequence aCandidateResult(pCandidate->createPrimitive2DSequenceInCurrentState(*this));
662 if(aCandidateResult.hasElements())
664 if(pCandidate->getAddToTransparent())
666 drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(aResultTransparent, aCandidateResult);
668 else
670 drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(aResult, aCandidateResult);
676 if(DoAddConnectorOverlays())
678 const drawinglayer::primitive2d::Primitive2DSequence aConnectorOverlays(AddConnectorOverlays());
680 if(aConnectorOverlays.hasElements())
682 // add connector overlays to transparent part
683 drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(aResultTransparent, aConnectorOverlays);
687 if(aResult.hasElements())
689 sdr::overlay::OverlayObject* pNewOverlayObject = new sdr::overlay::OverlayPrimitive2DSequenceObject(aResult);
690 rOverlayManager.add(*pNewOverlayObject);
691 addToOverlayObjectList(*pNewOverlayObject);
694 if(aResultTransparent.hasElements())
696 drawinglayer::primitive2d::Primitive2DReference aUnifiedAlphaPrimitive2D(new drawinglayer::primitive2d::UnifiedAlphaPrimitive2D(aResultTransparent, 0.5));
697 aResultTransparent = drawinglayer::primitive2d::Primitive2DSequence(&aUnifiedAlphaPrimitive2D, 1);
699 sdr::overlay::OverlayObject* pNewOverlayObject = new sdr::overlay::OverlayPrimitive2DSequenceObject(aResultTransparent);
700 rOverlayManager.add(*pNewOverlayObject);
701 addToOverlayObjectList(*pNewOverlayObject);
705 // evtl add DragStripes (help lines cross the page when dragging)
706 if(getSdrDragView().IsDragStripes())
708 Rectangle aActionRectangle;
709 getSdrDragView().TakeActionRect(aActionRectangle);
711 const basegfx::B2DPoint aTopLeft(aActionRectangle.Left(), aActionRectangle.Top());
712 const basegfx::B2DPoint aBottomRight(aActionRectangle.Right(), aActionRectangle.Bottom());
713 sdr::overlay::OverlayRollingRectangleStriped* pNew = new sdr::overlay::OverlayRollingRectangleStriped(
714 aTopLeft, aBottomRight, true, false);
716 rOverlayManager.add(*pNew);
717 addToOverlayObjectList(*pNew);
721 void SdrDragMethod::destroyOverlayGeometry()
723 clearOverlayObjectList();
726 bool SdrDragMethod::DoAddConnectorOverlays()
728 // these conditions are translated from SdrDragView::ImpDrawEdgeXor
729 const SdrMarkList& rMarkedNodes = getSdrDragView().GetEdgesOfMarkedNodes();
731 if(!rMarkedNodes.GetMarkCount())
733 return false;
736 if(!getSdrDragView().IsRubberEdgeDragging() && !getSdrDragView().IsDetailedEdgeDragging())
738 return false;
741 if(getSdrDragView().IsDraggingPoints() || getSdrDragView().IsDraggingGluePoints())
743 return false;
746 if(!getMoveOnly() && !(
747 IS_TYPE(SdrDragMove, this) || IS_TYPE(SdrDragResize, this) ||
748 IS_TYPE(SdrDragRotate,this) || IS_TYPE(SdrDragMirror,this)))
750 return false;
753 const bool bDetail(getSdrDragView().IsDetailedEdgeDragging() && getMoveOnly());
755 if(!bDetail && !getSdrDragView().IsRubberEdgeDragging())
757 return false;
760 // one more migrated from SdrEdgeObj::NspToggleEdgeXor
761 if(IS_TYPE(SdrDragObjOwn, this) || IS_TYPE(SdrDragMovHdl, this))
763 return false;
766 return true;
769 drawinglayer::primitive2d::Primitive2DSequence SdrDragMethod::AddConnectorOverlays()
771 drawinglayer::primitive2d::Primitive2DSequence aRetval;
772 const bool bDetail(getSdrDragView().IsDetailedEdgeDragging() && getMoveOnly());
773 const SdrMarkList& rMarkedNodes = getSdrDragView().GetEdgesOfMarkedNodes();
775 for(sal_uInt16 a(0); a < rMarkedNodes.GetMarkCount(); a++)
777 SdrMark* pEM = rMarkedNodes.GetMark(a);
779 if(pEM && pEM->GetMarkedSdrObj())
781 SdrEdgeObj* pEdge = dynamic_cast< SdrEdgeObj* >(pEM->GetMarkedSdrObj());
783 if(pEdge)
785 const basegfx::B2DPolygon aEdgePolygon(pEdge->ImplAddConnectorOverlay(*this, pEM->IsCon1(), pEM->IsCon2(), bDetail));
787 if(aEdgePolygon.count())
789 // this polygon is a temporary calculated connector path, so it is not possible to fetch
790 // the needed primitives directly from the pEdge object which does not get changed. If full
791 // drag is on, use the SdrObjects ItemSet to create a adequate representation
792 if(getSolidDraggingActive())
794 const SfxItemSet& rItemSet = pEdge->GetMergedItemSet();
795 drawinglayer::attribute::SdrLineAttribute* pLine = drawinglayer::primitive2d::createNewSdrLineAttribute(rItemSet);
796 drawinglayer::attribute::SdrLineStartEndAttribute* pLineStartEnd = 0;
798 if(pLine && !pLine->isVisible())
800 delete pLine;
801 pLine = 0;
804 if(pLine)
806 pLineStartEnd = drawinglayer::primitive2d::createNewSdrLineStartEndAttribute(rItemSet, pLine->getWidth());
808 if(pLineStartEnd && !pLineStartEnd->isVisible())
810 delete pLineStartEnd;
811 pLineStartEnd = 0;
814 drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(
815 aRetval, drawinglayer::primitive2d::createPolygonLinePrimitive(
816 aEdgePolygon, basegfx::B2DHomMatrix(), *pLine, pLineStartEnd));
818 if(pLineStartEnd)
820 delete pLineStartEnd;
823 delete pLine;
826 else
828 const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
829 basegfx::BColor aColA(aSvtOptionsDrawinglayer.GetStripeColorA().getBColor());
830 basegfx::BColor aColB(aSvtOptionsDrawinglayer.GetStripeColorB().getBColor());
831 const double fStripeLength(aSvtOptionsDrawinglayer.GetStripeLength());
833 if(Application::GetSettings().GetStyleSettings().GetHighContrastMode())
835 aColA = aColB = Application::GetSettings().GetStyleSettings().GetHighlightColor().getBColor();
836 aColB.invert();
839 drawinglayer::primitive2d::Primitive2DReference aPolyPolygonMarkerPrimitive2D(
840 new drawinglayer::primitive2d::PolyPolygonMarkerPrimitive2D(
841 basegfx::B2DPolyPolygon(aEdgePolygon), aColA, aColB, fStripeLength));
842 drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, aPolyPolygonMarkerPrimitive2D);
849 return aRetval;
852 ////////////////////////////////////////////////////////////////////////////////////////////////////
854 TYPEINIT1(SdrDragMovHdl,SdrDragMethod);
856 SdrDragMovHdl::SdrDragMovHdl(SdrDragView& rNewView)
857 : SdrDragMethod(rNewView),
858 bMirrObjShown(false)
862 void SdrDragMovHdl::createSdrDragEntries()
864 // SdrDragMovHdl does not use the default drags,
865 // but creates nothing
868 void SdrDragMovHdl::TakeSdrDragComment(XubString& rStr) const
870 rStr=ImpGetResStr(STR_DragMethMovHdl);
871 if (getSdrDragView().IsDragWithCopy()) rStr+=ImpGetResStr(STR_EditWithCopy);
874 bool SdrDragMovHdl::BeginSdrDrag()
876 DragStat().Ref1()=GetDragHdl()->GetPos();
877 DragStat().SetShown(!DragStat().IsShown());
878 SdrHdlKind eKind=GetDragHdl()->GetKind();
879 SdrHdl* pH1=GetHdlList().GetHdl(HDL_REF1);
880 SdrHdl* pH2=GetHdlList().GetHdl(HDL_REF2);
882 if (eKind==HDL_MIRX)
884 if (pH1==NULL || pH2==NULL)
886 DBG_ERROR("SdrDragMovHdl::BeginSdrDrag(): Verschieben der Spiegelachse: Referenzhandles nicht gefunden");
887 return false;
890 DragStat().SetActionRect(Rectangle(pH1->GetPos(),pH2->GetPos()));
892 else
894 Point aPt(GetDragHdl()->GetPos());
895 DragStat().SetActionRect(Rectangle(aPt,aPt));
898 return true;
901 void SdrDragMovHdl::MoveSdrDrag(const Point& rNoSnapPnt)
903 Point aPnt(rNoSnapPnt);
905 if (DragStat().CheckMinMoved(rNoSnapPnt))
907 if (GetDragHdl()->GetKind()==HDL_MIRX)
909 SdrHdl* pH1=GetHdlList().GetHdl(HDL_REF1);
910 SdrHdl* pH2=GetHdlList().GetHdl(HDL_REF2);
912 if (pH1==NULL || pH2==NULL)
913 return;
915 if (!DragStat().IsNoSnap())
917 long nBestXSnap=0;
918 long nBestYSnap=0;
919 bool bXSnapped=false;
920 bool bYSnapped=false;
921 Point aDif(aPnt-DragStat().GetStart());
922 getSdrDragView().CheckSnap(Ref1()+aDif,NULL,nBestXSnap,nBestYSnap,bXSnapped,bYSnapped);
923 getSdrDragView().CheckSnap(Ref2()+aDif,NULL,nBestXSnap,nBestYSnap,bXSnapped,bYSnapped);
924 aPnt.X()+=nBestXSnap;
925 aPnt.Y()+=nBestYSnap;
928 if (aPnt!=DragStat().GetNow())
930 Hide();
931 DragStat().NextMove(aPnt);
932 Point aDif(DragStat().GetNow()-DragStat().GetStart());
933 pH1->SetPos(Ref1()+aDif);
934 pH2->SetPos(Ref2()+aDif);
936 SdrHdl* pHM = GetHdlList().GetHdl(HDL_MIRX);
938 if(pHM)
939 pHM->Touch();
941 Show();
942 DragStat().SetActionRect(Rectangle(pH1->GetPos(),pH2->GetPos()));
945 else
947 if (!DragStat().IsNoSnap()) SnapPos(aPnt);
948 long nSA=0;
950 if (getSdrDragView().IsAngleSnapEnabled())
951 nSA=getSdrDragView().GetSnapAngle();
953 if (getSdrDragView().IsMirrorAllowed(true,true))
954 { // eingeschraenkt
955 if (!getSdrDragView().IsMirrorAllowed(false,false)) nSA=4500;
956 if (!getSdrDragView().IsMirrorAllowed(true,false)) nSA=9000;
959 if (getSdrDragView().IsOrtho() && nSA!=9000)
960 nSA=4500;
962 if (nSA!=0)
963 { // Winkelfang
964 SdrHdlKind eRef=HDL_REF1;
966 if (GetDragHdl()->GetKind()==HDL_REF1)
967 eRef=HDL_REF2;
969 SdrHdl* pH=GetHdlList().GetHdl(eRef);
971 if (pH!=NULL)
973 Point aRef(pH->GetPos());
974 long nWink=NormAngle360(GetAngle(aPnt-aRef));
975 long nNeuWink=nWink;
976 nNeuWink+=nSA/2;
977 nNeuWink/=nSA;
978 nNeuWink*=nSA;
979 nNeuWink=NormAngle360(nNeuWink);
980 double a=(nNeuWink-nWink)*nPi180;
981 double nSin=sin(a);
982 double nCos=cos(a);
983 RotatePoint(aPnt,aRef,nSin,nCos);
985 // Bei bestimmten Werten Rundungsfehler ausschliessen:
986 if (nSA==9000)
988 if (nNeuWink==0 || nNeuWink==18000) aPnt.Y()=aRef.Y();
989 if (nNeuWink==9000 || nNeuWink==27000) aPnt.X()=aRef.X();
992 if (nSA==4500)
993 OrthoDistance8(aRef,aPnt,true);
997 if (aPnt!=DragStat().GetNow())
999 Hide();
1000 DragStat().NextMove(aPnt);
1001 GetDragHdl()->SetPos(DragStat().GetNow());
1002 SdrHdl* pHM = GetHdlList().GetHdl(HDL_MIRX);
1004 if(pHM)
1005 pHM->Touch();
1007 Show();
1008 DragStat().SetActionRect(Rectangle(aPnt,aPnt));
1014 bool SdrDragMovHdl::EndSdrDrag(bool /*bCopy*/)
1016 switch (GetDragHdl()->GetKind())
1018 case HDL_REF1:
1019 Ref1()=DragStat().GetNow();
1020 break;
1022 case HDL_REF2:
1023 Ref2()=DragStat().GetNow();
1024 break;
1026 case HDL_MIRX:
1027 Ref1()+=DragStat().GetNow()-DragStat().GetStart();
1028 Ref2()+=DragStat().GetNow()-DragStat().GetStart();
1029 break;
1031 default: break;
1034 return true;
1037 void SdrDragMovHdl::CancelSdrDrag()
1039 Hide();
1040 GetDragHdl()->SetPos(DragStat().GetRef1());
1041 SdrHdl* pHM = GetHdlList().GetHdl(HDL_MIRX);
1043 if(pHM)
1044 pHM->Touch();
1047 Pointer SdrDragMovHdl::GetSdrDragPointer() const
1049 const SdrHdl* pHdl = GetDragHdl();
1051 if (pHdl!=NULL)
1053 return pHdl->GetPointer();
1056 return Pointer(POINTER_REFHAND);
1059 ////////////////////////////////////////////////////////////////////////////////////////////////////
1061 TYPEINIT1(SdrDragObjOwn,SdrDragMethod);
1063 SdrDragObjOwn::SdrDragObjOwn(SdrDragView& rNewView)
1064 : SdrDragMethod(rNewView),
1065 mpClone(0)
1067 const SdrObject* pObj = GetDragObj();
1069 if(pObj)
1071 // suppress full drag for some object types
1072 setSolidDraggingActive(pObj->supportsFullDrag());
1076 SdrDragObjOwn::~SdrDragObjOwn()
1078 if(mpClone)
1080 SdrObject::Free(mpClone);
1084 void SdrDragObjOwn::createSdrDragEntries()
1086 if(mpClone)
1088 basegfx::B2DPolyPolygon aDragPolyPolygon;
1089 bool bAddWireframe(true);
1091 if(getSolidDraggingActive())
1093 SdrPageView* pPV = getSdrDragView().GetSdrPageView();
1095 if(pPV && pPV->PageWindowCount())
1097 sdr::contact::ObjectContact& rOC = pPV->GetPageWindow(0)->GetObjectContact();
1098 addSdrDragEntry(new SdrDragEntrySdrObject(*mpClone, rOC, false));
1100 // potentially no wireframe needed, full drag works
1101 bAddWireframe = false;
1105 if(!bAddWireframe)
1107 // check for extra conditions for wireframe, e.g. no border at
1108 // objects
1109 if(!mpClone->HasLineStyle())
1111 bAddWireframe = true;
1115 if(bAddWireframe)
1117 // use wireframe poly when full drag is off or did not work
1118 aDragPolyPolygon = mpClone->TakeXorPoly();
1121 // add evtl. extra DragPolyPolygon
1122 const basegfx::B2DPolyPolygon aSpecialDragPolyPolygon(mpClone->getSpecialDragPoly(DragStat()));
1124 if(aSpecialDragPolyPolygon.count())
1126 aDragPolyPolygon.append(aSpecialDragPolyPolygon);
1129 if(aDragPolyPolygon.count())
1131 addSdrDragEntry(new SdrDragEntryPolyPolygon(aDragPolyPolygon));
1136 void SdrDragObjOwn::TakeSdrDragComment(XubString& rStr) const
1138 // #i103058# get info string from the clone preferred, the original will
1139 // not be changed. For security, use original as fallback
1140 if(mpClone)
1142 rStr = mpClone->getSpecialDragComment(DragStat());
1144 else
1146 const SdrObject* pObj = GetDragObj();
1148 if(pObj)
1150 rStr = pObj->getSpecialDragComment(DragStat());
1155 bool SdrDragObjOwn::BeginSdrDrag()
1157 if(!mpClone)
1159 const SdrObject* pObj = GetDragObj();
1161 if(pObj && !pObj->IsResizeProtect())
1163 if(pObj->beginSpecialDrag(DragStat()))
1165 // create nitial clone to have a start visualisation
1166 mpClone = pObj->getFullDragClone();
1167 mpClone->applySpecialDrag(DragStat());
1169 return true;
1174 return false;
1177 void SdrDragObjOwn::MoveSdrDrag(const Point& rNoSnapPnt)
1179 const SdrObject* pObj = GetDragObj();
1181 if(pObj)
1183 Point aPnt(rNoSnapPnt);
1184 SdrPageView* pPV = GetDragPV();
1186 if(pPV)
1188 if(!DragStat().IsNoSnap())
1190 SnapPos(aPnt);
1193 if(getSdrDragView().IsOrtho())
1195 if (DragStat().IsOrtho8Possible())
1197 OrthoDistance8(DragStat().GetStart(),aPnt,getSdrDragView().IsBigOrtho());
1199 else if (DragStat().IsOrtho4Possible())
1201 OrthoDistance4(DragStat().GetStart(),aPnt,getSdrDragView().IsBigOrtho());
1205 if(DragStat().CheckMinMoved(rNoSnapPnt))
1207 if(aPnt != DragStat().GetNow())
1209 Hide();
1210 DragStat().NextMove(aPnt);
1212 // since SdrDragObjOwn currently supports no transformation of
1213 // existing SdrDragEntries but only their recreation, a recreation
1214 // after every move is needed in this mode. Delete existing
1215 // SdrDragEntries here to force their recreation in the following Show().
1216 clearSdrDragEntries();
1218 // delete current clone (after the last reference to it is deleted above)
1219 if(mpClone)
1221 SdrObject::Free(mpClone);
1222 mpClone = 0;
1225 // create a new clone and modify to current drag state
1226 if(!mpClone)
1228 mpClone = pObj->getFullDragClone();
1229 mpClone->applySpecialDrag(DragStat());
1232 Show();
1239 bool SdrDragObjOwn::EndSdrDrag(bool /*bCopy*/)
1241 Hide();
1242 SdrUndoAction* pUndo = NULL;
1243 SdrUndoAction* pUndo2 = NULL;
1244 std::vector< SdrUndoAction* > vConnectorUndoActions;
1245 bool bRet = false;
1246 SdrObject* pObj = GetDragObj();
1248 if(pObj)
1250 const bool bUndo = getSdrDragView().IsUndoEnabled();
1252 if( bUndo )
1254 if(!getSdrDragView().IsInsObjPoint() && pObj->IsInserted() )
1256 if (DragStat().IsEndDragChangesAttributes())
1258 pUndo=getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pObj);
1260 if (DragStat().IsEndDragChangesGeoAndAttributes())
1262 vConnectorUndoActions = getSdrDragView().CreateConnectorUndo( *pObj );
1263 pUndo2 = getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj);
1266 else
1268 vConnectorUndoActions = getSdrDragView().CreateConnectorUndo( *pObj );
1269 pUndo= getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj);
1273 if( pUndo )
1275 getSdrDragView().BegUndo( pUndo->GetComment() );
1277 else
1279 getSdrDragView().BegUndo();
1283 // evtl. use opertator= for setting changed object data (do not change selection in
1284 // view, this will destroy the interactor). This is possible since a clone is now
1285 // directly modified by the modifiers. Only SdrTableObj is adding own UNDOs
1286 // in it's SdrTableObj::endSpecialDrag, so currently not possible. OTOH it uses
1287 // a CreateUndoGeoObject() so maybe setting SetEndDragChangesAttributes is okay. I
1288 // will test this now
1289 Rectangle aBoundRect0;
1291 if(pObj->GetUserCall())
1293 aBoundRect0 = pObj->GetLastBoundRect();
1296 bRet = pObj->applySpecialDrag(DragStat());
1298 if(bRet)
1300 pObj->SetChanged();
1301 pObj->BroadcastObjectChange();
1302 pObj->SendUserCall( SDRUSERCALL_RESIZE, aBoundRect0 );
1305 if(bRet)
1307 if( bUndo )
1309 getSdrDragView().AddUndoActions( vConnectorUndoActions );
1311 if ( pUndo )
1313 getSdrDragView().AddUndo(pUndo);
1316 if ( pUndo2 )
1318 getSdrDragView().AddUndo(pUndo2);
1322 else
1324 if( bUndo )
1326 std::vector< SdrUndoAction* >::iterator vConnectorUndoIter( vConnectorUndoActions.begin() );
1328 while( vConnectorUndoIter != vConnectorUndoActions.end() )
1330 delete *vConnectorUndoIter++;
1333 delete pUndo;
1334 delete pUndo2;
1338 if( bUndo )
1339 getSdrDragView().EndUndo();
1342 return bRet;
1345 Pointer SdrDragObjOwn::GetSdrDragPointer() const
1347 const SdrHdl* pHdl=GetDragHdl();
1349 if (pHdl)
1351 return pHdl->GetPointer();
1354 return Pointer(POINTER_MOVE);
1357 ////////////////////////////////////////////////////////////////////////////////////////////////////
1359 TYPEINIT1(SdrDragMove,SdrDragMethod);
1361 void SdrDragMove::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
1363 rTarget.Move(Size(DragStat().GetDX(), DragStat().GetDY()));
1366 SdrDragMove::SdrDragMove(SdrDragView& rNewView)
1367 : SdrDragMethod(rNewView)
1369 setMoveOnly(true);
1372 void SdrDragMove::TakeSdrDragComment(XubString& rStr) const
1374 XubString aStr;
1376 ImpTakeDescriptionStr(STR_DragMethMove, rStr);
1377 rStr.AppendAscii(" (x=");
1378 getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDX(), aStr);
1379 rStr += aStr;
1380 rStr.AppendAscii(" y=");
1381 getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDY(), aStr);
1382 rStr += aStr;
1383 rStr += sal_Unicode(')');
1385 if(getSdrDragView().IsDragWithCopy())
1387 if(!getSdrDragView().IsInsObjPoint() && !getSdrDragView().IsInsGluePoint())
1389 rStr += ImpGetResStr(STR_EditWithCopy);
1394 bool SdrDragMove::BeginSdrDrag()
1396 DragStat().SetActionRect(GetMarkedRect());
1397 Show();
1399 return true;
1402 basegfx::B2DHomMatrix SdrDragMove::getCurrentTransformation()
1404 basegfx::B2DHomMatrix aRetval;
1406 aRetval.translate(DragStat().GetDX(), DragStat().GetDY());
1408 return aRetval;
1411 void SdrDragMove::ImpCheckSnap(const Point& rPt)
1413 Point aPt(rPt);
1414 sal_uInt16 nRet=SnapPos(aPt);
1415 aPt-=rPt;
1417 if ((nRet & SDRSNAP_XSNAPPED) !=0)
1419 if (bXSnapped)
1421 if (Abs(aPt.X())<Abs(nBestXSnap))
1423 nBestXSnap=aPt.X();
1426 else
1428 nBestXSnap=aPt.X();
1429 bXSnapped=true;
1433 if ((nRet & SDRSNAP_YSNAPPED) !=0)
1435 if (bYSnapped)
1437 if (Abs(aPt.Y())<Abs(nBestYSnap))
1439 nBestYSnap=aPt.Y();
1442 else
1444 nBestYSnap=aPt.Y();
1445 bYSnapped=true;
1450 void SdrDragMove::MoveSdrDrag(const Point& rNoSnapPnt_)
1452 nBestXSnap=0;
1453 nBestYSnap=0;
1454 bXSnapped=false;
1455 bYSnapped=false;
1456 Point aNoSnapPnt(rNoSnapPnt_);
1457 const Rectangle& aSR=GetMarkedRect();
1458 long nMovedx=aNoSnapPnt.X()-DragStat().GetStart().X();
1459 long nMovedy=aNoSnapPnt.Y()-DragStat().GetStart().Y();
1460 Point aLO(aSR.TopLeft()); aLO.X()+=nMovedx; aLO.Y()+=nMovedy;
1461 Point aRU(aSR.BottomRight()); aRU.X()+=nMovedx; aRU.Y()+=nMovedy;
1462 Point aLU(aLO.X(),aRU.Y());
1463 Point aRO(aRU.X(),aLO.Y());
1464 ImpCheckSnap(aLO);
1466 if (!getSdrDragView().IsMoveSnapOnlyTopLeft())
1468 ImpCheckSnap(aRO);
1469 ImpCheckSnap(aLU);
1470 ImpCheckSnap(aRU);
1473 Point aPnt(aNoSnapPnt.X()+nBestXSnap,aNoSnapPnt.Y()+nBestYSnap);
1474 bool bOrtho=getSdrDragView().IsOrtho();
1476 if (bOrtho)
1477 OrthoDistance8(DragStat().GetStart(),aPnt,getSdrDragView().IsBigOrtho());
1479 if (DragStat().CheckMinMoved(aNoSnapPnt))
1481 Point aPt1(aPnt);
1482 Rectangle aLR(getSdrDragView().GetWorkArea());
1483 bool bWorkArea=!aLR.IsEmpty();
1484 bool bDragLimit=IsDragLimit();
1486 if (bDragLimit || bWorkArea)
1488 Rectangle aSR2(GetMarkedRect());
1489 Point aD(aPt1-DragStat().GetStart());
1491 if (bDragLimit)
1493 Rectangle aR2(GetDragLimitRect());
1495 if (bWorkArea)
1496 aLR.Intersection(aR2);
1497 else
1498 aLR=aR2;
1501 if (aSR2.Left()>aLR.Left() || aSR2.Right()<aLR.Right())
1502 { // ist ueberhaupt Platz zum verschieben?
1503 aSR2.Move(aD.X(),0);
1505 if (aSR2.Left()<aLR.Left())
1507 aPt1.X()-=aSR2.Left()-aLR.Left();
1509 else if (aSR2.Right()>aLR.Right())
1511 aPt1.X()-=aSR2.Right()-aLR.Right();
1514 else
1515 aPt1.X()=DragStat().GetStart().X(); // kein Platz zum verschieben
1517 if (aSR2.Top()>aLR.Top() || aSR2.Bottom()<aLR.Bottom())
1518 { // ist ueberhaupt Platz zum verschieben?
1519 aSR2.Move(0,aD.Y());
1521 if (aSR2.Top()<aLR.Top())
1523 aPt1.Y()-=aSR2.Top()-aLR.Top();
1525 else if (aSR2.Bottom()>aLR.Bottom())
1527 aPt1.Y()-=aSR2.Bottom()-aLR.Bottom();
1530 else
1531 aPt1.Y()=DragStat().GetStart().Y(); // kein Platz zum verschieben
1534 if (getSdrDragView().IsDraggingGluePoints())
1535 { // Klebepunkte aufs BoundRect des Obj limitieren
1536 aPt1-=DragStat().GetStart();
1537 const SdrMarkList& rML=GetMarkedObjectList();
1538 ULONG nMarkAnz=rML.GetMarkCount();
1540 for (ULONG nMarkNum=0; nMarkNum<nMarkAnz; nMarkNum++)
1542 const SdrMark* pM=rML.GetMark(nMarkNum);
1543 const SdrUShortCont* pPts=pM->GetMarkedGluePoints();
1544 ULONG nPtAnz=pPts==NULL ? 0 : pPts->GetCount();
1546 if (nPtAnz!=0)
1548 const SdrObject* pObj=pM->GetMarkedSdrObj();
1549 const SdrGluePointList* pGPL=pObj->GetGluePointList();
1550 Rectangle aBound(pObj->GetCurrentBoundRect());
1552 for (ULONG nPtNum=0; nPtNum<nPtAnz; nPtNum++)
1554 sal_uInt16 nId=pPts->GetObject(nPtNum);
1555 sal_uInt16 nGlueNum=pGPL->FindGluePoint(nId);
1557 if (nGlueNum!=SDRGLUEPOINT_NOTFOUND)
1559 Point aPt((*pGPL)[nGlueNum].GetAbsolutePos(*pObj));
1560 aPt+=aPt1; // soviel soll verschoben werden
1561 if (aPt.X()<aBound.Left() ) aPt1.X()-=aPt.X()-aBound.Left() ;
1562 if (aPt.X()>aBound.Right() ) aPt1.X()-=aPt.X()-aBound.Right() ;
1563 if (aPt.Y()<aBound.Top() ) aPt1.Y()-=aPt.Y()-aBound.Top() ;
1564 if (aPt.Y()>aBound.Bottom()) aPt1.Y()-=aPt.Y()-aBound.Bottom();
1570 aPt1+=DragStat().GetStart();
1573 if (bOrtho)
1574 OrthoDistance8(DragStat().GetStart(),aPt1,false);
1576 if (aPt1!=DragStat().GetNow())
1578 Hide();
1579 DragStat().NextMove(aPt1);
1580 Rectangle aAction(GetMarkedRect());
1581 aAction.Move(DragStat().GetDX(),DragStat().GetDY());
1582 DragStat().SetActionRect(aAction);
1583 Show();
1588 bool SdrDragMove::EndSdrDrag(bool bCopy)
1590 Hide();
1592 if (getSdrDragView().IsInsObjPoint() || getSdrDragView().IsInsGluePoint())
1593 bCopy=false;
1595 if (IsDraggingPoints())
1597 getSdrDragView().MoveMarkedPoints(Size(DragStat().GetDX(),DragStat().GetDY()),bCopy);
1599 else if (IsDraggingGluePoints())
1601 getSdrDragView().MoveMarkedGluePoints(Size(DragStat().GetDX(),DragStat().GetDY()),bCopy);
1603 else
1605 getSdrDragView().MoveMarkedObj(Size(DragStat().GetDX(),DragStat().GetDY()),bCopy);
1608 return true;
1611 Pointer SdrDragMove::GetSdrDragPointer() const
1613 if (IsDraggingPoints() || IsDraggingGluePoints())
1615 return Pointer(POINTER_MOVEPOINT);
1617 else
1619 return Pointer(POINTER_MOVE);
1623 ////////////////////////////////////////////////////////////////////////////////////////////////////
1625 TYPEINIT1(SdrDragResize,SdrDragMethod);
1627 SdrDragResize::SdrDragResize(SdrDragView& rNewView)
1628 : SdrDragMethod(rNewView),
1629 aXFact(1,1),
1630 aYFact(1,1)
1634 void SdrDragResize::TakeSdrDragComment(XubString& rStr) const
1636 ImpTakeDescriptionStr(STR_DragMethResize, rStr);
1637 bool bEqual(aXFact == aYFact);
1638 Fraction aFact1(1,1);
1639 Point aStart(DragStat().GetStart());
1640 Point aRef(DragStat().GetRef1());
1641 INT32 nXDiv(aStart.X() - aRef.X());
1643 if(!nXDiv)
1644 nXDiv = 1;
1646 INT32 nYDiv(aStart.Y() - aRef.Y());
1648 if(!nYDiv)
1649 nYDiv = 1;
1651 bool bX(aXFact != aFact1 && Abs(nXDiv) > 1);
1652 bool bY(aYFact != aFact1 && Abs(nYDiv) > 1);
1654 if(bX || bY)
1656 XubString aStr;
1658 rStr.AppendAscii(" (");
1660 if(bX)
1662 if(!bEqual)
1663 rStr.AppendAscii("x=");
1665 getSdrDragView().GetModel()->TakePercentStr(aXFact, aStr);
1666 rStr += aStr;
1669 if(bY && !bEqual)
1671 if(bX)
1672 rStr += sal_Unicode(' ');
1674 rStr.AppendAscii("y=");
1675 getSdrDragView().GetModel()->TakePercentStr(aYFact, aStr);
1676 rStr += aStr;
1679 rStr += sal_Unicode(')');
1682 if(getSdrDragView().IsDragWithCopy())
1683 rStr += ImpGetResStr(STR_EditWithCopy);
1686 bool SdrDragResize::BeginSdrDrag()
1688 SdrHdlKind eRefHdl=HDL_MOVE;
1689 SdrHdl* pRefHdl=NULL;
1691 switch (GetDragHdlKind())
1693 case HDL_UPLFT: eRefHdl=HDL_LWRGT; break;
1694 case HDL_UPPER: eRefHdl=HDL_LOWER; DragStat().SetHorFixed(true); break;
1695 case HDL_UPRGT: eRefHdl=HDL_LWLFT; break;
1696 case HDL_LEFT : eRefHdl=HDL_RIGHT; DragStat().SetVerFixed(true); break;
1697 case HDL_RIGHT: eRefHdl=HDL_LEFT ; DragStat().SetVerFixed(true); break;
1698 case HDL_LWLFT: eRefHdl=HDL_UPRGT; break;
1699 case HDL_LOWER: eRefHdl=HDL_UPPER; DragStat().SetHorFixed(true); break;
1700 case HDL_LWRGT: eRefHdl=HDL_UPLFT; break;
1701 default: break;
1704 if (eRefHdl!=HDL_MOVE)
1705 pRefHdl=GetHdlList().GetHdl(eRefHdl);
1707 if (pRefHdl!=NULL && !getSdrDragView().IsResizeAtCenter())
1709 DragStat().Ref1()=pRefHdl->GetPos();
1711 else
1713 SdrHdl* pRef1=GetHdlList().GetHdl(HDL_UPLFT);
1714 SdrHdl* pRef2=GetHdlList().GetHdl(HDL_LWRGT);
1716 if (pRef1!=NULL && pRef2!=NULL)
1718 DragStat().Ref1()=Rectangle(pRef1->GetPos(),pRef2->GetPos()).Center();
1720 else
1722 DragStat().Ref1()=GetMarkedRect().Center();
1726 Show();
1728 return true;
1731 basegfx::B2DHomMatrix SdrDragResize::getCurrentTransformation()
1733 basegfx::B2DHomMatrix aRetval;
1735 aRetval.translate(-DragStat().Ref1().X(), -DragStat().Ref1().Y());
1736 aRetval.scale(aXFact, aYFact);
1737 aRetval.translate(DragStat().Ref1().X(), DragStat().Ref1().Y());
1739 return aRetval;
1742 void SdrDragResize::MoveSdrDrag(const Point& rNoSnapPnt)
1744 Point aPnt(GetSnapPos(rNoSnapPnt));
1745 Point aStart(DragStat().GetStart());
1746 Point aRef(DragStat().GetRef1());
1747 Fraction aMaxFact(0x7FFFFFFF,1);
1748 Rectangle aLR(getSdrDragView().GetWorkArea());
1749 bool bWorkArea=!aLR.IsEmpty();
1750 bool bDragLimit=IsDragLimit();
1752 if (bDragLimit || bWorkArea)
1754 Rectangle aSR(GetMarkedRect());
1756 if (bDragLimit)
1758 Rectangle aR2(GetDragLimitRect());
1760 if (bWorkArea)
1761 aLR.Intersection(aR2);
1762 else
1763 aLR=aR2;
1766 if (aPnt.X()<aLR.Left())
1767 aPnt.X()=aLR.Left();
1768 else if (aPnt.X()>aLR.Right())
1769 aPnt.X()=aLR.Right();
1771 if (aPnt.Y()<aLR.Top())
1772 aPnt.Y()=aLR.Top();
1773 else if (aPnt.Y()>aLR.Bottom())
1774 aPnt.Y()=aLR.Bottom();
1776 if (aRef.X()>aSR.Left())
1778 Fraction aMax(aRef.X()-aLR.Left(),aRef.X()-aSR.Left());
1780 if (aMax<aMaxFact)
1781 aMaxFact=aMax;
1784 if (aRef.X()<aSR.Right())
1786 Fraction aMax(aLR.Right()-aRef.X(),aSR.Right()-aRef.X());
1788 if (aMax<aMaxFact)
1789 aMaxFact=aMax;
1792 if (aRef.Y()>aSR.Top())
1794 Fraction aMax(aRef.Y()-aLR.Top(),aRef.Y()-aSR.Top());
1796 if (aMax<aMaxFact)
1797 aMaxFact=aMax;
1800 if (aRef.Y()<aSR.Bottom())
1802 Fraction aMax(aLR.Bottom()-aRef.Y(),aSR.Bottom()-aRef.Y());
1804 if (aMax<aMaxFact)
1805 aMaxFact=aMax;
1809 long nXDiv=aStart.X()-aRef.X(); if (nXDiv==0) nXDiv=1;
1810 long nYDiv=aStart.Y()-aRef.Y(); if (nYDiv==0) nYDiv=1;
1811 long nXMul=aPnt.X()-aRef.X();
1812 long nYMul=aPnt.Y()-aRef.Y();
1814 if (nXDiv<0)
1816 nXDiv=-nXDiv;
1817 nXMul=-nXMul;
1820 if (nYDiv<0)
1822 nYDiv=-nYDiv;
1823 nYMul=-nYMul;
1826 bool bXNeg=nXMul<0; if (bXNeg) nXMul=-nXMul;
1827 bool bYNeg=nYMul<0; if (bYNeg) nYMul=-nYMul;
1828 bool bOrtho=getSdrDragView().IsOrtho() || !getSdrDragView().IsResizeAllowed(false);
1830 if (!DragStat().IsHorFixed() && !DragStat().IsVerFixed())
1832 if (Abs(nXDiv)<=1 || Abs(nYDiv)<=1)
1833 bOrtho=false;
1835 if (bOrtho)
1837 if ((Fraction(nXMul,nXDiv)>Fraction(nYMul,nYDiv)) !=getSdrDragView().IsBigOrtho())
1839 nXMul=nYMul;
1840 nXDiv=nYDiv;
1842 else
1844 nYMul=nXMul;
1845 nYDiv=nXDiv;
1849 else
1851 if (bOrtho)
1853 if (DragStat().IsHorFixed())
1855 bXNeg=false;
1856 nXMul=nYMul;
1857 nXDiv=nYDiv;
1860 if (DragStat().IsVerFixed())
1862 bYNeg=false;
1863 nYMul=nXMul;
1864 nYDiv=nXDiv;
1867 else
1869 if (DragStat().IsHorFixed())
1871 bXNeg=false;
1872 nXMul=1;
1873 nXDiv=1;
1876 if (DragStat().IsVerFixed())
1878 bYNeg=false;
1879 nYMul=1;
1880 nYDiv=1;
1885 Fraction aNeuXFact(nXMul,nXDiv);
1886 Fraction aNeuYFact(nYMul,nYDiv);
1888 if (bOrtho)
1890 if (aNeuXFact>aMaxFact)
1892 aNeuXFact=aMaxFact;
1893 aNeuYFact=aMaxFact;
1896 if (aNeuYFact>aMaxFact)
1898 aNeuXFact=aMaxFact;
1899 aNeuYFact=aMaxFact;
1903 if (bXNeg)
1904 aNeuXFact=Fraction(-aNeuXFact.GetNumerator(),aNeuXFact.GetDenominator());
1906 if (bYNeg)
1907 aNeuYFact=Fraction(-aNeuYFact.GetNumerator(),aNeuYFact.GetDenominator());
1909 if (DragStat().CheckMinMoved(aPnt))
1911 if ((!DragStat().IsHorFixed() && aPnt.X()!=DragStat().GetNow().X()) ||
1912 (!DragStat().IsVerFixed() && aPnt.Y()!=DragStat().GetNow().Y()))
1914 Hide();
1915 DragStat().NextMove(aPnt);
1916 aXFact=aNeuXFact;
1917 aYFact=aNeuYFact;
1918 Show();
1923 void SdrDragResize::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
1925 rTarget.Resize(DragStat().Ref1(),aXFact,aYFact);
1928 bool SdrDragResize::EndSdrDrag(bool bCopy)
1930 Hide();
1932 if (IsDraggingPoints())
1934 getSdrDragView().ResizeMarkedPoints(DragStat().Ref1(),aXFact,aYFact,bCopy);
1936 else if (IsDraggingGluePoints())
1938 getSdrDragView().ResizeMarkedGluePoints(DragStat().Ref1(),aXFact,aYFact,bCopy);
1940 else
1942 getSdrDragView().ResizeMarkedObj(DragStat().Ref1(),aXFact,aYFact,bCopy);
1945 return true;
1948 Pointer SdrDragResize::GetSdrDragPointer() const
1950 const SdrHdl* pHdl=GetDragHdl();
1952 if (pHdl!=NULL)
1954 return pHdl->GetPointer();
1957 return Pointer(POINTER_MOVE);
1960 ////////////////////////////////////////////////////////////////////////////////////////////////////
1962 TYPEINIT1(SdrDragRotate,SdrDragMethod);
1964 void SdrDragRotate::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
1966 rTarget.Rotate(DragStat().GetRef1(), nWink, sin(nWink*nPi180), cos(nWink*nPi180));
1969 SdrDragRotate::SdrDragRotate(SdrDragView& rNewView)
1970 : SdrDragMethod(rNewView),
1971 nSin(0.0),
1972 nCos(1.0),
1973 nWink0(0),
1974 nWink(0),
1975 bRight(false)
1979 void SdrDragRotate::TakeSdrDragComment(XubString& rStr) const
1981 ImpTakeDescriptionStr(STR_DragMethRotate, rStr);
1982 rStr.AppendAscii(" (");
1983 XubString aStr;
1984 INT32 nTmpWink(NormAngle360(nWink));
1986 if(bRight && nWink)
1988 nTmpWink -= 36000;
1991 getSdrDragView().GetModel()->TakeWinkStr(nTmpWink, aStr);
1992 rStr += aStr;
1993 rStr += sal_Unicode(')');
1995 if(getSdrDragView().IsDragWithCopy())
1996 rStr += ImpGetResStr(STR_EditWithCopy);
1999 bool SdrDragRotate::BeginSdrDrag()
2001 SdrHdl* pH=GetHdlList().GetHdl(HDL_REF1);
2003 if (pH!=NULL)
2005 Show();
2006 DragStat().Ref1()=pH->GetPos();
2007 nWink0=GetAngle(DragStat().GetStart()-DragStat().GetRef1());
2008 return true;
2010 else
2012 DBG_ERROR("SdrDragRotate::BeginSdrDrag(): Kein Referenzpunkt-Handle gefunden");
2013 return false;
2017 basegfx::B2DHomMatrix SdrDragRotate::getCurrentTransformation()
2019 basegfx::B2DHomMatrix aRetval;
2021 aRetval.translate(-DragStat().GetRef1().X(), -DragStat().GetRef1().Y());
2022 aRetval.rotate(-atan2(nSin, nCos));
2023 aRetval.translate(DragStat().GetRef1().X(), DragStat().GetRef1().Y());
2025 return aRetval;
2028 void SdrDragRotate::MoveSdrDrag(const Point& rPnt_)
2030 Point aPnt(rPnt_);
2031 if (DragStat().CheckMinMoved(aPnt))
2033 long nNeuWink=NormAngle360(GetAngle(aPnt-DragStat().GetRef1())-nWink0);
2034 long nSA=0;
2036 if (getSdrDragView().IsAngleSnapEnabled())
2037 nSA=getSdrDragView().GetSnapAngle();
2039 if (!getSdrDragView().IsRotateAllowed(false))
2040 nSA=9000;
2042 if (nSA!=0)
2043 { // Winkelfang
2044 nNeuWink+=nSA/2;
2045 nNeuWink/=nSA;
2046 nNeuWink*=nSA;
2049 nNeuWink=NormAngle180(nNeuWink);
2051 if (nWink!=nNeuWink)
2053 sal_uInt16 nSekt0=GetAngleSector(nWink);
2054 sal_uInt16 nSekt1=GetAngleSector(nNeuWink);
2056 if (nSekt0==0 && nSekt1==3)
2057 bRight=true;
2059 if (nSekt0==3 && nSekt1==0)
2060 bRight=false;
2062 nWink=nNeuWink;
2063 double a=nWink*nPi180;
2064 double nSin1=sin(a); // schonmal berechnen, damit mgl. wenig Zeit
2065 double nCos1=cos(a); // zwischen Hide() und Show() vergeht
2066 Hide();
2067 nSin=nSin1;
2068 nCos=nCos1;
2069 DragStat().NextMove(aPnt);
2070 Show();
2075 bool SdrDragRotate::EndSdrDrag(bool bCopy)
2077 Hide();
2079 if (nWink!=0)
2081 if (IsDraggingPoints())
2083 getSdrDragView().RotateMarkedPoints(DragStat().GetRef1(),nWink,bCopy);
2085 else if (IsDraggingGluePoints())
2087 getSdrDragView().RotateMarkedGluePoints(DragStat().GetRef1(),nWink,bCopy);
2089 else
2091 getSdrDragView().RotateMarkedObj(DragStat().GetRef1(),nWink,bCopy);
2094 return true;
2097 Pointer SdrDragRotate::GetSdrDragPointer() const
2099 return Pointer(POINTER_ROTATE);
2102 ////////////////////////////////////////////////////////////////////////////////////////////////////
2104 TYPEINIT1(SdrDragShear,SdrDragMethod);
2106 SdrDragShear::SdrDragShear(SdrDragView& rNewView, bool bSlant1)
2107 : SdrDragMethod(rNewView),
2108 aFact(1,1),
2109 nWink0(0),
2110 nWink(0),
2111 nTan(0.0),
2112 bVertical(false),
2113 bResize(false),
2114 bUpSideDown(false),
2115 bSlant(bSlant1)
2119 void SdrDragShear::TakeSdrDragComment(XubString& rStr) const
2121 ImpTakeDescriptionStr(STR_DragMethShear, rStr);
2122 rStr.AppendAscii(" (");
2124 INT32 nTmpWink(nWink);
2126 if(bUpSideDown)
2127 nTmpWink += 18000;
2129 nTmpWink = NormAngle180(nTmpWink);
2131 XubString aStr;
2133 getSdrDragView().GetModel()->TakeWinkStr(nTmpWink, aStr);
2134 rStr += aStr;
2135 rStr += sal_Unicode(')');
2137 if(getSdrDragView().IsDragWithCopy())
2138 rStr += ImpGetResStr(STR_EditWithCopy);
2141 bool SdrDragShear::BeginSdrDrag()
2143 SdrHdlKind eRefHdl=HDL_MOVE;
2144 SdrHdl* pRefHdl=NULL;
2146 switch (GetDragHdlKind())
2148 case HDL_UPPER: eRefHdl=HDL_LOWER; break;
2149 case HDL_LOWER: eRefHdl=HDL_UPPER; break;
2150 case HDL_LEFT : eRefHdl=HDL_RIGHT; bVertical=true; break;
2151 case HDL_RIGHT: eRefHdl=HDL_LEFT ; bVertical=true; break;
2152 default: break;
2155 if (eRefHdl!=HDL_MOVE)
2156 pRefHdl=GetHdlList().GetHdl(eRefHdl);
2158 if (pRefHdl!=NULL)
2160 DragStat().Ref1()=pRefHdl->GetPos();
2161 nWink0=GetAngle(DragStat().GetStart()-DragStat().GetRef1());
2163 else
2165 DBG_ERROR("SdrDragShear::BeginSdrDrag(): Kein Referenzpunkt-Handle fuer Shear gefunden");
2166 return false;
2169 Show();
2170 return true;
2173 basegfx::B2DHomMatrix SdrDragShear::getCurrentTransformation()
2175 basegfx::B2DHomMatrix aRetval;
2177 aRetval.translate(-DragStat().GetRef1().X(), -DragStat().GetRef1().Y());
2179 if (bResize)
2181 if (bVertical)
2183 aRetval.scale(aFact, 1.0);
2184 aRetval.shearY(-nTan);
2186 else
2188 aRetval.scale(1.0, aFact);
2189 aRetval.shearX(-nTan);
2193 aRetval.translate(DragStat().GetRef1().X(), DragStat().GetRef1().Y());
2195 return aRetval;
2198 void SdrDragShear::MoveSdrDrag(const Point& rPnt)
2200 if (DragStat().CheckMinMoved(rPnt))
2202 bResize=!getSdrDragView().IsOrtho();
2203 long nSA=0;
2205 if (getSdrDragView().IsAngleSnapEnabled())
2206 nSA=getSdrDragView().GetSnapAngle();
2208 Point aP0(DragStat().GetStart());
2209 Point aPnt(rPnt);
2210 Fraction aNeuFact(1,1);
2212 // Wenn kein Winkelfang, dann ggf. Rasterfang (ausser bei Slant)
2213 if (nSA==0 && !bSlant)
2214 aPnt=GetSnapPos(aPnt);
2216 if (!bSlant && !bResize)
2217 { // Shear ohne Resize
2218 if (bVertical)
2219 aPnt.X()=aP0.X();
2220 else
2221 aPnt.Y()=aP0.Y();
2224 Point aRef(DragStat().GetRef1());
2225 Point aDif(aPnt-aRef);
2227 long nNeuWink=0;
2229 if (bSlant)
2231 nNeuWink=NormAngle180(-(GetAngle(aDif)-nWink0));
2233 if (bVertical)
2234 nNeuWink=NormAngle180(-nNeuWink);
2236 else
2238 if (bVertical)
2239 nNeuWink=NormAngle180(GetAngle(aDif));
2240 else
2241 nNeuWink=NormAngle180(-(GetAngle(aDif)-9000));
2243 if (nNeuWink<-9000 || nNeuWink>9000)
2244 nNeuWink=NormAngle180(nNeuWink+18000);
2246 if (bResize)
2248 Point aPt2(aPnt);
2250 if (nSA!=0)
2251 aPt2=GetSnapPos(aPnt); // den also in jedem Falle fangen
2253 if (bVertical)
2255 aNeuFact=Fraction(aPt2.X()-aRef.X(),aP0.X()-aRef.X());
2257 else
2259 aNeuFact=Fraction(aPt2.Y()-aRef.Y(),aP0.Y()-aRef.Y());
2264 bool bNeg=nNeuWink<0;
2266 if (bNeg)
2267 nNeuWink=-nNeuWink;
2269 if (nSA!=0)
2270 { // Winkelfang
2271 nNeuWink+=nSA/2;
2272 nNeuWink/=nSA;
2273 nNeuWink*=nSA;
2276 nNeuWink=NormAngle360(nNeuWink);
2277 bUpSideDown=nNeuWink>9000 && nNeuWink<27000;
2279 if (bSlant)
2280 { // Resize fuer Slant berechnen
2281 // Mit Winkelfang jedoch ohne 89deg Begrenzung
2282 long nTmpWink=nNeuWink;
2283 if (bUpSideDown) nNeuWink-=18000;
2284 if (bNeg) nTmpWink=-nTmpWink;
2285 bResize=true;
2286 double nCos=cos(nTmpWink*nPi180);
2287 aNeuFact=nCos;
2288 Kuerzen(aFact,10); // 3 Dezimalstellen sollten reichen
2291 if (nNeuWink>8900)
2292 nNeuWink=8900;
2294 if (bNeg)
2295 nNeuWink=-nNeuWink;
2297 if (nWink!=nNeuWink || aFact!=aNeuFact)
2299 nWink=nNeuWink;
2300 aFact=aNeuFact;
2301 double a=nWink*nPi180;
2302 double nTan1=0.0;
2303 nTan1=tan(a); // schonmal berechnen, damit mgl. wenig Zeit zwischen Hide() und Show() vergeht
2304 Hide();
2305 nTan=nTan1;
2306 DragStat().NextMove(rPnt);
2307 Show();
2312 void SdrDragShear::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
2314 if (bResize)
2316 if (bVertical)
2318 rTarget.Resize(DragStat().GetRef1(),aFact,Fraction(1,1));
2320 else
2322 rTarget.Resize(DragStat().GetRef1(),Fraction(1,1),aFact);
2326 if (nWink!=0)
2328 rTarget.Shear(DragStat().GetRef1(),nWink,tan(nWink*nPi180),bVertical);
2332 bool SdrDragShear::EndSdrDrag(bool bCopy)
2334 Hide();
2336 if (bResize && aFact==Fraction(1,1))
2337 bResize=false;
2339 if (nWink!=0 || bResize)
2341 if (nWink!=0 && bResize)
2343 XubString aStr;
2344 ImpTakeDescriptionStr(STR_EditShear,aStr);
2346 if (bCopy)
2347 aStr+=ImpGetResStr(STR_EditWithCopy);
2349 getSdrDragView().BegUndo(aStr);
2352 if (bResize)
2354 if (bVertical)
2356 getSdrDragView().ResizeMarkedObj(DragStat().GetRef1(),aFact,Fraction(1,1),bCopy);
2358 else
2360 getSdrDragView().ResizeMarkedObj(DragStat().GetRef1(),Fraction(1,1),aFact,bCopy);
2363 bCopy=false;
2366 if (nWink!=0)
2368 getSdrDragView().ShearMarkedObj(DragStat().GetRef1(),nWink,bVertical,bCopy);
2371 if (nWink!=0 && bResize)
2372 getSdrDragView().EndUndo();
2374 return true;
2377 return false;
2380 Pointer SdrDragShear::GetSdrDragPointer() const
2382 if (bVertical)
2383 return Pointer(POINTER_VSHEAR);
2384 else
2385 return Pointer(POINTER_HSHEAR);
2388 ////////////////////////////////////////////////////////////////////////////////////////////////////
2390 TYPEINIT1(SdrDragMirror,SdrDragMethod);
2392 void SdrDragMirror::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
2394 if(bMirrored)
2396 rTarget.Mirror(DragStat().GetRef1(), DragStat().GetRef2());
2400 SdrDragMirror::SdrDragMirror(SdrDragView& rNewView)
2401 : SdrDragMethod(rNewView),
2402 nWink(0),
2403 bMirrored(false),
2404 bSide0(false)
2408 bool SdrDragMirror::ImpCheckSide(const Point& rPnt) const
2410 long nWink1=GetAngle(rPnt-DragStat().GetRef1());
2411 nWink1-=nWink;
2412 nWink1=NormAngle360(nWink1);
2414 return nWink1<18000;
2417 void SdrDragMirror::TakeSdrDragComment(XubString& rStr) const
2419 if (aDif.X()==0)
2420 ImpTakeDescriptionStr(STR_DragMethMirrorHori,rStr);
2421 else if (aDif.Y()==0)
2422 ImpTakeDescriptionStr(STR_DragMethMirrorVert,rStr);
2423 else if (Abs(aDif.X())==Abs(aDif.Y()))
2424 ImpTakeDescriptionStr(STR_DragMethMirrorDiag,rStr);
2425 else
2426 ImpTakeDescriptionStr(STR_DragMethMirrorFree,rStr);
2428 if (getSdrDragView().IsDragWithCopy())
2429 rStr+=ImpGetResStr(STR_EditWithCopy);
2432 bool SdrDragMirror::BeginSdrDrag()
2434 SdrHdl* pH1=GetHdlList().GetHdl(HDL_REF1);
2435 SdrHdl* pH2=GetHdlList().GetHdl(HDL_REF2);
2437 if (pH1!=NULL && pH2!=NULL)
2439 DragStat().Ref1()=pH1->GetPos();
2440 DragStat().Ref2()=pH2->GetPos();
2441 Ref1()=pH1->GetPos();
2442 Ref2()=pH2->GetPos();
2443 aDif=pH2->GetPos()-pH1->GetPos();
2444 bool b90=(aDif.X()==0) || aDif.Y()==0;
2445 bool b45=b90 || (Abs(aDif.X())==Abs(aDif.Y()));
2446 nWink=NormAngle360(GetAngle(aDif));
2448 if (!getSdrDragView().IsMirrorAllowed(false,false) && !b45)
2449 return false; // freier Achsenwinkel nicht erlaubt
2451 if (!getSdrDragView().IsMirrorAllowed(true,false) && !b90)
2452 return false; // 45deg auch nicht erlaubt
2454 bSide0=ImpCheckSide(DragStat().GetStart());
2455 Show();
2456 return true;
2458 else
2460 DBG_ERROR("SdrDragMirror::BeginSdrDrag(): Spiegelachse nicht gefunden");
2461 return false;
2465 basegfx::B2DHomMatrix SdrDragMirror::getCurrentTransformation()
2467 basegfx::B2DHomMatrix aRetval;
2469 if (bMirrored)
2471 const double fDeltaX(DragStat().GetRef2().X() - DragStat().GetRef1().X());
2472 const double fDeltaY(DragStat().GetRef2().Y() - DragStat().GetRef1().Y());
2473 const double fRotation(atan2(fDeltaY, fDeltaX));
2475 aRetval.translate(-DragStat().GetRef1().X(), -DragStat().GetRef1().Y());
2476 aRetval.rotate(-fRotation);
2477 aRetval.scale(1.0, -1.0);
2478 aRetval.rotate(fRotation);
2479 aRetval.translate(DragStat().GetRef1().X(), DragStat().GetRef1().Y());
2482 return aRetval;
2485 void SdrDragMirror::MoveSdrDrag(const Point& rPnt)
2487 if (DragStat().CheckMinMoved(rPnt))
2489 bool bNeuSide=ImpCheckSide(rPnt);
2490 bool bNeuMirr=bSide0!=bNeuSide;
2492 if (bMirrored!=bNeuMirr)
2494 Hide();
2495 bMirrored=bNeuMirr;
2496 DragStat().NextMove(rPnt);
2497 Show();
2502 bool SdrDragMirror::EndSdrDrag(bool bCopy)
2504 Hide();
2506 if (bMirrored)
2508 getSdrDragView().MirrorMarkedObj(DragStat().GetRef1(),DragStat().GetRef2(),bCopy);
2511 return true;
2514 Pointer SdrDragMirror::GetSdrDragPointer() const
2516 return Pointer(POINTER_MIRROR);
2519 ////////////////////////////////////////////////////////////////////////////////////////////////////
2521 TYPEINIT1(SdrDragGradient, SdrDragMethod);
2523 SdrDragGradient::SdrDragGradient(SdrDragView& rNewView, bool bGrad)
2524 : SdrDragMethod(rNewView),
2525 pIAOHandle(NULL),
2526 bIsGradient(bGrad)
2530 void SdrDragGradient::TakeSdrDragComment(XubString& rStr) const
2532 if(IsGradient())
2533 ImpTakeDescriptionStr(STR_DragMethGradient, rStr);
2534 else
2535 ImpTakeDescriptionStr(STR_DragMethTransparence, rStr);
2538 bool SdrDragGradient::BeginSdrDrag()
2540 bool bRetval(false);
2542 pIAOHandle = (SdrHdlGradient*)GetHdlList().GetHdl(IsGradient() ? HDL_GRAD : HDL_TRNS);
2544 if(pIAOHandle)
2546 // save old values
2547 DragStat().Ref1() = pIAOHandle->GetPos();
2548 DragStat().Ref2() = pIAOHandle->Get2ndPos();
2550 // what was hit?
2551 bool bHit(false);
2552 SdrHdlColor* pColHdl = pIAOHandle->GetColorHdl1();
2554 // init handling flags
2555 pIAOHandle->SetMoveSingleHandle(false);
2556 pIAOHandle->SetMoveFirstHandle(false);
2558 // test first color handle
2559 if(pColHdl)
2561 basegfx::B2DPoint aPosition(DragStat().GetStart().X(), DragStat().GetStart().Y());
2563 if(pColHdl->getOverlayObjectList().isHitLogic(aPosition))
2565 bHit = true;
2566 pIAOHandle->SetMoveSingleHandle(true);
2567 pIAOHandle->SetMoveFirstHandle(true);
2571 // test second color handle
2572 pColHdl = pIAOHandle->GetColorHdl2();
2574 if(!bHit && pColHdl)
2576 basegfx::B2DPoint aPosition(DragStat().GetStart().X(), DragStat().GetStart().Y());
2578 if(pColHdl->getOverlayObjectList().isHitLogic(aPosition))
2580 bHit = true;
2581 pIAOHandle->SetMoveSingleHandle(true);
2585 // test gradient handle itself
2586 if(!bHit)
2588 basegfx::B2DPoint aPosition(DragStat().GetStart().X(), DragStat().GetStart().Y());
2590 if(pIAOHandle->getOverlayObjectList().isHitLogic(aPosition))
2592 bHit = true;
2596 // everything up and running :o}
2597 bRetval = bHit;
2599 else
2601 DBG_ERROR("SdrDragGradient::BeginSdrDrag(): IAOGradient nicht gefunden");
2604 return bRetval;
2607 void SdrDragGradient::MoveSdrDrag(const Point& rPnt)
2609 if(pIAOHandle && DragStat().CheckMinMoved(rPnt))
2611 DragStat().NextMove(rPnt);
2613 // Do the Move here!!! DragStat().GetStart()
2614 Point aMoveDiff = rPnt - DragStat().GetStart();
2616 if(pIAOHandle->IsMoveSingleHandle())
2618 if(pIAOHandle->IsMoveFirstHandle())
2620 pIAOHandle->SetPos(DragStat().Ref1() + aMoveDiff);
2621 if(pIAOHandle->GetColorHdl1())
2622 pIAOHandle->GetColorHdl1()->SetPos(DragStat().Ref1() + aMoveDiff);
2624 else
2626 pIAOHandle->Set2ndPos(DragStat().Ref2() + aMoveDiff);
2627 if(pIAOHandle->GetColorHdl2())
2628 pIAOHandle->GetColorHdl2()->SetPos(DragStat().Ref2() + aMoveDiff);
2631 else
2633 pIAOHandle->SetPos(DragStat().Ref1() + aMoveDiff);
2634 pIAOHandle->Set2ndPos(DragStat().Ref2() + aMoveDiff);
2636 if(pIAOHandle->GetColorHdl1())
2637 pIAOHandle->GetColorHdl1()->SetPos(DragStat().Ref1() + aMoveDiff);
2639 if(pIAOHandle->GetColorHdl2())
2640 pIAOHandle->GetColorHdl2()->SetPos(DragStat().Ref2() + aMoveDiff);
2643 // new state
2644 pIAOHandle->FromIAOToItem(getSdrDragView().GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(), false, false);
2648 bool SdrDragGradient::EndSdrDrag(bool /*bCopy*/)
2650 // here the result is clear, do something with the values
2651 Ref1() = pIAOHandle->GetPos();
2652 Ref2() = pIAOHandle->Get2ndPos();
2654 // new state
2655 pIAOHandle->FromIAOToItem(getSdrDragView().GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(), true, true);
2657 return true;
2660 void SdrDragGradient::CancelSdrDrag()
2662 // restore old values
2663 pIAOHandle->SetPos(DragStat().Ref1());
2664 pIAOHandle->Set2ndPos(DragStat().Ref2());
2666 if(pIAOHandle->GetColorHdl1())
2667 pIAOHandle->GetColorHdl1()->SetPos(DragStat().Ref1());
2669 if(pIAOHandle->GetColorHdl2())
2670 pIAOHandle->GetColorHdl2()->SetPos(DragStat().Ref2());
2672 // new state
2673 pIAOHandle->FromIAOToItem(getSdrDragView().GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(), true, false);
2676 Pointer SdrDragGradient::GetSdrDragPointer() const
2678 return Pointer(POINTER_REFHAND);
2681 ////////////////////////////////////////////////////////////////////////////////////////////////////
2683 TYPEINIT1(SdrDragCrook,SdrDragMethod);
2685 SdrDragCrook::SdrDragCrook(SdrDragView& rNewView)
2686 : SdrDragMethod(rNewView),
2687 aFact(1,1),
2688 bContortionAllowed(false),
2689 bNoContortionAllowed(false),
2690 bContortion(false),
2691 bResizeAllowed(false),
2692 bResize(false),
2693 bRotateAllowed(false),
2694 bRotate(false),
2695 bVertical(false),
2696 bValid(false),
2697 bLft(false),
2698 bRgt(false),
2699 bUpr(false),
2700 bLwr(false),
2701 bAtCenter(false),
2702 nWink(0),
2703 nMarkSize(0),
2704 eMode(SDRCROOK_ROTATE)
2708 void SdrDragCrook::TakeSdrDragComment(XubString& rStr) const
2710 ImpTakeDescriptionStr(!bContortion ? STR_DragMethCrook : STR_DragMethCrookContortion, rStr);
2712 if(bValid)
2714 rStr.AppendAscii(" (");
2716 XubString aStr;
2717 INT32 nVal(nWink);
2719 if(bAtCenter)
2720 nVal *= 2;
2722 nVal = Abs(nVal);
2723 getSdrDragView().GetModel()->TakeWinkStr(nVal, aStr);
2724 rStr += aStr;
2725 rStr += sal_Unicode(')');
2728 if(getSdrDragView().IsDragWithCopy())
2729 rStr += ImpGetResStr(STR_EditWithCopy);
2732 // #96920# These defines parametrise the created raster
2733 // for interactions
2734 #define DRAG_CROOK_RASTER_MINIMUM (4)
2735 #define DRAG_CROOK_RASTER_MAXIMUM (15)
2736 #define DRAG_CROOK_RASTER_DISTANCE (30)
2738 basegfx::B2DPolyPolygon impCreateDragRaster(SdrPageView& rPageView, const Rectangle& rMarkRect)
2740 basegfx::B2DPolyPolygon aRetval;
2742 if(rPageView.PageWindowCount())
2744 OutputDevice& rOut = (rPageView.GetPageWindow(0)->GetPaintWindow().GetOutputDevice());
2745 Rectangle aPixelSize = rOut.LogicToPixel(rMarkRect);
2746 sal_uInt32 nHorDiv(aPixelSize.GetWidth() / DRAG_CROOK_RASTER_DISTANCE);
2747 sal_uInt32 nVerDiv(aPixelSize.GetHeight() / DRAG_CROOK_RASTER_DISTANCE);
2749 if(nHorDiv > DRAG_CROOK_RASTER_MAXIMUM)
2750 nHorDiv = DRAG_CROOK_RASTER_MAXIMUM;
2751 if(nHorDiv < DRAG_CROOK_RASTER_MINIMUM)
2752 nHorDiv = DRAG_CROOK_RASTER_MINIMUM;
2754 if(nVerDiv > DRAG_CROOK_RASTER_MAXIMUM)
2755 nVerDiv = DRAG_CROOK_RASTER_MAXIMUM;
2756 if(nVerDiv < DRAG_CROOK_RASTER_MINIMUM)
2757 nVerDiv = DRAG_CROOK_RASTER_MINIMUM;
2759 const double fXLen(rMarkRect.GetWidth() / (double)nHorDiv);
2760 const double fYLen(rMarkRect.GetHeight() / (double)nVerDiv);
2761 double fYPos(rMarkRect.Top());
2762 sal_uInt32 a, b;
2764 for(a = 0; a <= nVerDiv; a++)
2766 // hor lines
2767 for(b = 0; b < nHorDiv; b++)
2769 basegfx::B2DPolygon aHorLineSegment;
2771 const double fNewX(rMarkRect.Left() + (b * fXLen));
2772 aHorLineSegment.append(basegfx::B2DPoint(fNewX, fYPos));
2773 aHorLineSegment.appendBezierSegment(
2774 basegfx::B2DPoint(fNewX + (fXLen * (1.0 / 3.0)), fYPos),
2775 basegfx::B2DPoint(fNewX + (fXLen * (2.0 / 3.0)), fYPos),
2776 basegfx::B2DPoint(fNewX + fXLen, fYPos));
2777 aRetval.append(aHorLineSegment);
2780 // increments
2781 fYPos += fYLen;
2784 double fXPos(rMarkRect.Left());
2786 for(a = 0; a <= nHorDiv; a++)
2788 // ver lines
2789 for(b = 0; b < nVerDiv; b++)
2791 basegfx::B2DPolygon aVerLineSegment;
2793 const double fNewY(rMarkRect.Top() + (b * fYLen));
2794 aVerLineSegment.append(basegfx::B2DPoint(fXPos, fNewY));
2795 aVerLineSegment.appendBezierSegment(
2796 basegfx::B2DPoint(fXPos, fNewY + (fYLen * (1.0 / 3.0))),
2797 basegfx::B2DPoint(fXPos, fNewY + (fYLen * (2.0 / 3.0))),
2798 basegfx::B2DPoint(fXPos, fNewY + fYLen));
2799 aRetval.append(aVerLineSegment);
2802 // increments
2803 fXPos += fXLen;
2807 return aRetval;
2810 void SdrDragCrook::createSdrDragEntries()
2812 // Add extended frame raster first, so it will be behind objects
2813 if(getSdrDragView().GetSdrPageView())
2815 const basegfx::B2DPolyPolygon aDragRaster(impCreateDragRaster(*getSdrDragView().GetSdrPageView(), GetMarkedRect()));
2817 if(aDragRaster.count())
2819 addSdrDragEntry(new SdrDragEntryPolyPolygon(aDragRaster));
2823 // call parent
2824 SdrDragMethod::createSdrDragEntries();
2827 bool SdrDragCrook::BeginSdrDrag()
2829 bContortionAllowed=getSdrDragView().IsCrookAllowed(false);
2830 bNoContortionAllowed=getSdrDragView().IsCrookAllowed(true);
2831 bResizeAllowed=getSdrDragView().IsResizeAllowed(false);
2832 bRotateAllowed=getSdrDragView().IsRotateAllowed(false);
2834 if (bContortionAllowed || bNoContortionAllowed)
2836 bVertical=(GetDragHdlKind()==HDL_LOWER || GetDragHdlKind()==HDL_UPPER);
2837 aMarkRect=GetMarkedRect();
2838 aMarkCenter=aMarkRect.Center();
2839 nMarkSize=bVertical ? (aMarkRect.GetHeight()-1) : (aMarkRect.GetWidth()-1);
2840 aCenter=aMarkCenter;
2841 aStart=DragStat().GetStart();
2842 Show();
2843 return true;
2845 else
2847 return false;
2851 void SdrDragCrook::_MovAllPoints(basegfx::B2DPolyPolygon& rTarget)
2853 SdrPageView* pPV = getSdrDragView().GetSdrPageView();
2855 if(pPV)
2857 XPolyPolygon aTempPolyPoly(rTarget);
2859 if (pPV->HasMarkedObjPageView())
2861 sal_uInt16 nPolyAnz=aTempPolyPoly.Count();
2863 if (!bContortion && !getSdrDragView().IsNoDragXorPolys())
2865 sal_uInt16 n1st=0,nLast=0;
2866 Point aC(aCenter);
2868 while (n1st<nPolyAnz)
2870 nLast=n1st;
2871 while (nLast<nPolyAnz && aTempPolyPoly[nLast].GetPointCount()!=0) nLast++;
2872 Rectangle aBound(aTempPolyPoly[n1st].GetBoundRect());
2873 sal_uInt16 i;
2875 for (i=n1st+1; i<nLast; i++)
2877 aBound.Union(aTempPolyPoly[n1st].GetBoundRect());
2880 Point aCtr0(aBound.Center());
2881 Point aCtr1(aCtr0);
2883 if (bResize)
2885 Fraction aFact1(1,1);
2887 if (bVertical)
2889 ResizePoint(aCtr1,aC,aFact1,aFact);
2891 else
2893 ResizePoint(aCtr1,aC,aFact,aFact1);
2897 bool bRotOk=false;
2898 double nSin=0,nCos=0;
2900 if (aRad.X()!=0 && aRad.Y()!=0)
2902 bRotOk=bRotate;
2904 switch (eMode)
2906 case SDRCROOK_ROTATE : CrookRotateXPoint (aCtr1,NULL,NULL,aC,aRad,nSin,nCos,bVertical); break;
2907 case SDRCROOK_SLANT : CrookSlantXPoint (aCtr1,NULL,NULL,aC,aRad,nSin,nCos,bVertical); break;
2908 case SDRCROOK_STRETCH: CrookStretchXPoint(aCtr1,NULL,NULL,aC,aRad,nSin,nCos,bVertical,aMarkRect); break;
2909 } // switch
2912 aCtr1-=aCtr0;
2914 for (i=n1st; i<nLast; i++)
2916 if (bRotOk)
2918 RotateXPoly(aTempPolyPoly[i],aCtr0,nSin,nCos);
2921 aTempPolyPoly[i].Move(aCtr1.X(),aCtr1.Y());
2924 n1st=nLast+1;
2927 else
2929 sal_uInt16 i,j;
2931 for (j=0; j<nPolyAnz; j++)
2933 XPolygon& aPol=aTempPolyPoly[j];
2934 sal_uInt16 nPtAnz=aPol.GetPointCount();
2935 i=0;
2937 while (i<nPtAnz)
2939 Point* pPnt=&aPol[i];
2940 Point* pC1=NULL;
2941 Point* pC2=NULL;
2943 if (i+1<nPtAnz && aPol.IsControl(i))
2944 { // Kontrollpunkt links
2945 pC1=pPnt;
2946 i++;
2947 pPnt=&aPol[i];
2950 i++;
2952 if (i<nPtAnz && aPol.IsControl(i))
2953 { // Kontrollpunkt rechts
2954 pC2=&aPol[i];
2955 i++;
2958 _MovCrookPoint(*pPnt,pC1,pC2);
2964 rTarget = aTempPolyPoly.getB2DPolyPolygon();
2968 void SdrDragCrook::_MovCrookPoint(Point& rPnt, Point* pC1, Point* pC2)
2970 bool bVert=bVertical;
2971 bool bC1=pC1!=NULL;
2972 bool bC2=pC2!=NULL;
2973 Point aC(aCenter);
2975 if (bResize)
2977 Fraction aFact1(1,1);
2979 if (bVert)
2981 ResizePoint(rPnt,aC,aFact1,aFact);
2983 if (bC1)
2984 ResizePoint(*pC1,aC,aFact1,aFact);
2986 if (bC2)
2987 ResizePoint(*pC2,aC,aFact1,aFact);
2989 else
2991 ResizePoint(rPnt,aC,aFact,aFact1);
2993 if (bC1)
2994 ResizePoint(*pC1,aC,aFact,aFact1);
2996 if (bC2)
2997 ResizePoint(*pC2,aC,aFact,aFact1);
3001 if (aRad.X()!=0 && aRad.Y()!=0)
3003 double nSin,nCos;
3005 switch (eMode)
3007 case SDRCROOK_ROTATE : CrookRotateXPoint (rPnt,pC1,pC2,aC,aRad,nSin,nCos,bVert); break;
3008 case SDRCROOK_SLANT : CrookSlantXPoint (rPnt,pC1,pC2,aC,aRad,nSin,nCos,bVert); break;
3009 case SDRCROOK_STRETCH: CrookStretchXPoint(rPnt,pC1,pC2,aC,aRad,nSin,nCos,bVert,aMarkRect); break;
3010 } // switch
3014 void SdrDragCrook::MoveSdrDrag(const Point& rPnt)
3016 if (DragStat().CheckMinMoved(rPnt))
3018 Point aPnt(rPnt);
3019 bool bNeuMoveOnly=getSdrDragView().IsMoveOnlyDragging();
3020 bAtCenter=false;
3021 SdrCrookMode eNeuMode=getSdrDragView().GetCrookMode();
3022 bool bNeuContortion=!bNeuMoveOnly && ((bContortionAllowed && !getSdrDragView().IsCrookNoContortion()) || !bNoContortionAllowed);
3023 bResize=!getSdrDragView().IsOrtho() && bResizeAllowed && !bNeuMoveOnly;
3024 bool bNeuRotate=bRotateAllowed && !bNeuContortion && !bNeuMoveOnly && eNeuMode==SDRCROOK_ROTATE;
3025 long nSA=0;
3027 if (nSA==0)
3028 aPnt=GetSnapPos(aPnt);
3030 Point aNeuCenter(aMarkCenter.X(),aStart.Y());
3032 if (bVertical)
3034 aNeuCenter.X()=aStart.X();
3035 aNeuCenter.Y()=aMarkCenter.Y();
3038 if (!getSdrDragView().IsCrookAtCenter())
3040 switch (GetDragHdlKind())
3042 case HDL_UPLFT: aNeuCenter.X()=aMarkRect.Right(); bLft=true; break;
3043 case HDL_UPPER: aNeuCenter.Y()=aMarkRect.Bottom(); bUpr=true; break;
3044 case HDL_UPRGT: aNeuCenter.X()=aMarkRect.Left(); bRgt=true; break;
3045 case HDL_LEFT : aNeuCenter.X()=aMarkRect.Right(); bLft=true; break;
3046 case HDL_RIGHT: aNeuCenter.X()=aMarkRect.Left(); bRgt=true; break;
3047 case HDL_LWLFT: aNeuCenter.X()=aMarkRect.Right(); bLft=true; break;
3048 case HDL_LOWER: aNeuCenter.Y()=aMarkRect.Top(); bLwr=true; break;
3049 case HDL_LWRGT: aNeuCenter.X()=aMarkRect.Left(); bRgt=true; break;
3050 default: bAtCenter=true;
3053 else
3054 bAtCenter=true;
3056 Fraction aNeuFact(1,1);
3057 long dx1=aPnt.X()-aNeuCenter.X();
3058 long dy1=aPnt.Y()-aNeuCenter.Y();
3059 bValid=bVertical ? dx1!=0 : dy1!=0;
3061 if (bValid)
3063 if (bVertical)
3064 bValid=Abs(dx1)*100>Abs(dy1);
3065 else
3066 bValid=Abs(dy1)*100>Abs(dx1);
3069 long nNeuRad=0;
3070 nWink=0;
3072 if (bValid)
3074 double a=0; // Steigung des Radius
3075 long nPntWink=0;
3077 if (bVertical)
3079 a=((double)dy1)/((double)dx1); // Steigung des Radius
3080 nNeuRad=((long)(dy1*a)+dx1) /2;
3081 aNeuCenter.X()+=nNeuRad;
3082 nPntWink=GetAngle(aPnt-aNeuCenter);
3084 else
3086 a=((double)dx1)/((double)dy1); // Steigung des Radius
3087 nNeuRad=((long)(dx1*a)+dy1) /2;
3088 aNeuCenter.Y()+=nNeuRad;
3089 nPntWink=GetAngle(aPnt-aNeuCenter)-9000;
3092 if (!bAtCenter)
3094 if (nNeuRad<0)
3096 if (bRgt) nPntWink+=18000;
3097 if (bLft) nPntWink=18000-nPntWink;
3098 if (bLwr) nPntWink=-nPntWink;
3100 else
3102 if (bRgt) nPntWink=-nPntWink;
3103 if (bUpr) nPntWink=18000-nPntWink;
3104 if (bLwr) nPntWink+=18000;
3107 nPntWink=NormAngle360(nPntWink);
3109 else
3111 if (nNeuRad<0) nPntWink+=18000;
3112 if (bVertical) nPntWink=18000-nPntWink;
3113 nPntWink=NormAngle180(nPntWink);
3114 nPntWink=Abs(nPntWink);
3117 double nUmfang=2*Abs(nNeuRad)*nPi;
3119 if (bResize)
3121 if (nSA!=0)
3122 { // Winkelfang
3123 long nWink0=nPntWink;
3124 nPntWink+=nSA/2;
3125 nPntWink/=nSA;
3126 nPntWink*=nSA;
3127 BigInt a2(nNeuRad);
3128 a2*=BigInt(nWink);
3129 a2/=BigInt(nWink0);
3130 nNeuRad=long(a2);
3132 if (bVertical)
3133 aNeuCenter.X()=aStart.X()+nNeuRad;
3134 else
3135 aNeuCenter.Y()=aStart.Y()+nNeuRad;
3138 long nMul=(long)(nUmfang*NormAngle360(nPntWink)/36000);
3140 if (bAtCenter)
3141 nMul*=2;
3143 aNeuFact=Fraction(nMul,nMarkSize);
3144 nWink=nPntWink;
3146 else
3148 nWink=(long)((nMarkSize*360/nUmfang)*100)/2;
3150 if (nWink==0)
3151 bValid=false;
3153 if (bValid && nSA!=0)
3154 { // Winkelfang
3155 long nWink0=nWink;
3156 nWink+=nSA/2;
3157 nWink/=nSA;
3158 nWink*=nSA;
3159 BigInt a2(nNeuRad);
3160 a2*=BigInt(nWink);
3161 a2/=BigInt(nWink0);
3162 nNeuRad=long(a2);
3164 if (bVertical)
3165 aNeuCenter.X()=aStart.X()+nNeuRad;
3166 else
3167 aNeuCenter.Y()=aStart.Y()+nNeuRad;
3172 if (nWink==0 || nNeuRad==0)
3173 bValid=false;
3175 if (!bValid)
3176 nNeuRad=0;
3178 if (!bValid && bResize)
3180 long nMul=bVertical ? dy1 : dx1;
3182 if (bLft || bUpr)
3183 nMul=-nMul;
3185 long nDiv=nMarkSize;
3187 if (bAtCenter)
3189 nMul*=2;
3190 nMul=Abs(nMul);
3193 aNeuFact=Fraction(nMul,nDiv);
3196 if (aNeuCenter!=aCenter || bNeuContortion!=bContortion || aNeuFact!=aFact ||
3197 bNeuMoveOnly != getMoveOnly() || bNeuRotate!=bRotate || eNeuMode!=eMode)
3199 Hide();
3200 setMoveOnly(bNeuMoveOnly);
3201 bRotate=bNeuRotate;
3202 eMode=eNeuMode;
3203 bContortion=bNeuContortion;
3204 aCenter=aNeuCenter;
3205 aFact=aNeuFact;
3206 aRad=Point(nNeuRad,nNeuRad);
3207 bResize=aFact!=Fraction(1,1) && aFact.GetDenominator()!=0 && aFact.IsValid();
3208 DragStat().NextMove(aPnt);
3209 Show();
3214 void SdrDragCrook::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
3216 const bool bDoResize(aFact!=Fraction(1,1));
3217 const bool bDoCrook(aCenter!=aMarkCenter && aRad.X()!=0 && aRad.Y()!=0);
3219 if (bDoCrook || bDoResize)
3221 if (bDoResize)
3223 Fraction aFact1(1,1);
3225 if (bContortion)
3227 if (bVertical)
3229 rTarget.Resize(aCenter,aFact1,aFact);
3231 else
3233 rTarget.Resize(aCenter,aFact,aFact1);
3236 else
3238 Point aCtr0(rTarget.GetSnapRect().Center());
3239 Point aCtr1(aCtr0);
3241 if (bVertical)
3243 ResizePoint(aCtr1,aCenter,aFact1,aFact);
3245 else
3247 ResizePoint(aCtr1,aCenter,aFact,aFact1);
3250 Size aSiz(aCtr1.X()-aCtr0.X(),aCtr1.Y()-aCtr0.Y());
3252 rTarget.Move(aSiz);
3256 if (bDoCrook)
3258 const Rectangle aLocalMarkRect(getSdrDragView().GetMarkedObjRect());
3259 const bool bLocalRotate(!bContortion && eMode == SDRCROOK_ROTATE && getSdrDragView().IsRotateAllowed(false));
3261 getSdrDragView().ImpCrookObj(&rTarget,aCenter,aRad,eMode,bVertical,!bContortion,bLocalRotate,aLocalMarkRect);
3266 void SdrDragCrook::applyCurrentTransformationToPolyPolygon(basegfx::B2DPolyPolygon& rTarget)
3268 // use helper derived from old stuff
3269 _MovAllPoints(rTarget);
3272 bool SdrDragCrook::EndSdrDrag(bool bCopy)
3274 Hide();
3276 if (bResize && aFact==Fraction(1,1))
3277 bResize=false;
3279 const bool bUndo = getSdrDragView().IsUndoEnabled();
3281 bool bDoCrook=aCenter!=aMarkCenter && aRad.X()!=0 && aRad.Y()!=0;
3283 if (bDoCrook || bResize)
3285 if (bResize && bUndo)
3287 XubString aStr;
3288 ImpTakeDescriptionStr(!bContortion?STR_EditCrook:STR_EditCrookContortion,aStr);
3290 if (bCopy)
3291 aStr+=ImpGetResStr(STR_EditWithCopy);
3293 getSdrDragView().BegUndo(aStr);
3296 if (bResize)
3298 Fraction aFact1(1,1);
3300 if (bContortion)
3302 if (bVertical)
3303 getSdrDragView().ResizeMarkedObj(aCenter,aFact1,aFact,bCopy);
3304 else
3305 getSdrDragView().ResizeMarkedObj(aCenter,aFact,aFact1,bCopy);
3307 else
3309 if (bCopy)
3310 getSdrDragView().CopyMarkedObj();
3312 ULONG nMarkAnz=getSdrDragView().GetMarkedObjectList().GetMarkCount();
3314 for (ULONG nm=0; nm<nMarkAnz; nm++)
3316 SdrMark* pM=getSdrDragView().GetMarkedObjectList().GetMark(nm);
3317 SdrObject* pO=pM->GetMarkedSdrObj();
3318 Point aCtr0(pO->GetSnapRect().Center());
3319 Point aCtr1(aCtr0);
3321 if (bVertical)
3322 ResizePoint(aCtr1,aCenter,aFact1,aFact);
3323 else
3324 ResizePoint(aCtr1,aCenter,aFact,aFact1);
3326 Size aSiz(aCtr1.X()-aCtr0.X(),aCtr1.Y()-aCtr0.Y());
3327 if( bUndo )
3328 AddUndo(getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoMoveObject(*pO,aSiz));
3329 pO->Move(aSiz);
3333 bCopy=false;
3336 if (bDoCrook)
3338 getSdrDragView().CrookMarkedObj(aCenter,aRad,eMode,bVertical,!bContortion,bCopy);
3339 getSdrDragView().SetLastCrookCenter(aCenter);
3342 if (bResize && bUndo)
3343 getSdrDragView().EndUndo();
3345 return true;
3348 return false;
3351 Pointer SdrDragCrook::GetSdrDragPointer() const
3353 return Pointer(POINTER_CROOK);
3356 ////////////////////////////////////////////////////////////////////////////////////////////////////
3358 TYPEINIT1(SdrDragDistort,SdrDragMethod);
3360 SdrDragDistort::SdrDragDistort(SdrDragView& rNewView)
3361 : SdrDragMethod(rNewView),
3362 nPolyPt(0),
3363 bContortionAllowed(false),
3364 bNoContortionAllowed(false),
3365 bContortion(false)
3369 void SdrDragDistort::TakeSdrDragComment(XubString& rStr) const
3371 ImpTakeDescriptionStr(STR_DragMethDistort, rStr);
3373 XubString aStr;
3375 rStr.AppendAscii(" (x=");
3376 getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDX(), aStr);
3377 rStr += aStr;
3378 rStr.AppendAscii(" y=");
3379 getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDY(), aStr);
3380 rStr += aStr;
3381 rStr += sal_Unicode(')');
3383 if(getSdrDragView().IsDragWithCopy())
3384 rStr += ImpGetResStr(STR_EditWithCopy);
3387 void SdrDragDistort::createSdrDragEntries()
3389 // Add extended frame raster first, so it will be behind objects
3390 if(getSdrDragView().GetSdrPageView())
3392 const basegfx::B2DPolyPolygon aDragRaster(impCreateDragRaster(*getSdrDragView().GetSdrPageView(), GetMarkedRect()));
3394 if(aDragRaster.count())
3396 addSdrDragEntry(new SdrDragEntryPolyPolygon(aDragRaster));
3400 // call parent
3401 SdrDragMethod::createSdrDragEntries();
3404 bool SdrDragDistort::BeginSdrDrag()
3406 bContortionAllowed=getSdrDragView().IsDistortAllowed(false);
3407 bNoContortionAllowed=getSdrDragView().IsDistortAllowed(true);
3409 if (bContortionAllowed || bNoContortionAllowed)
3411 SdrHdlKind eKind=GetDragHdlKind();
3412 nPolyPt=0xFFFF;
3414 if (eKind==HDL_UPLFT) nPolyPt=0;
3415 if (eKind==HDL_UPRGT) nPolyPt=1;
3416 if (eKind==HDL_LWRGT) nPolyPt=2;
3417 if (eKind==HDL_LWLFT) nPolyPt=3;
3418 if (nPolyPt>3) return false;
3420 aMarkRect=GetMarkedRect();
3421 aDistortedRect=XPolygon(aMarkRect);
3422 Show();
3423 return true;
3425 else
3427 return false;
3431 void SdrDragDistort::_MovAllPoints(basegfx::B2DPolyPolygon& rTarget)
3433 if (bContortion)
3435 SdrPageView* pPV = getSdrDragView().GetSdrPageView();
3437 if(pPV)
3439 if (pPV->HasMarkedObjPageView())
3441 basegfx::B2DPolyPolygon aDragPolygon(rTarget);
3442 const basegfx::B2DRange aOriginalRange(aMarkRect.Left(), aMarkRect.Top(), aMarkRect.Right(), aMarkRect.Bottom());
3443 const basegfx::B2DPoint aTopLeft(aDistortedRect[0].X(), aDistortedRect[0].Y());
3444 const basegfx::B2DPoint aTopRight(aDistortedRect[1].X(), aDistortedRect[1].Y());
3445 const basegfx::B2DPoint aBottomLeft(aDistortedRect[3].X(), aDistortedRect[3].Y());
3446 const basegfx::B2DPoint aBottomRight(aDistortedRect[2].X(), aDistortedRect[2].Y());
3448 aDragPolygon = basegfx::tools::distort(aDragPolygon, aOriginalRange, aTopLeft, aTopRight, aBottomLeft, aBottomRight);
3449 rTarget = aDragPolygon;
3455 void SdrDragDistort::MoveSdrDrag(const Point& rPnt)
3457 if (DragStat().CheckMinMoved(rPnt))
3459 Point aPnt(GetSnapPos(rPnt));
3461 if (getSdrDragView().IsOrtho())
3462 OrthoDistance8(DragStat().GetStart(),aPnt,getSdrDragView().IsBigOrtho());
3464 bool bNeuContortion=(bContortionAllowed && !getSdrDragView().IsCrookNoContortion()) || !bNoContortionAllowed;
3466 if (bNeuContortion!=bContortion || aDistortedRect[nPolyPt]!=aPnt)
3468 Hide();
3469 aDistortedRect[nPolyPt]=aPnt;
3470 bContortion=bNeuContortion;
3471 DragStat().NextMove(aPnt);
3472 Show();
3477 bool SdrDragDistort::EndSdrDrag(bool bCopy)
3479 Hide();
3480 bool bDoDistort=DragStat().GetDX()!=0 || DragStat().GetDY()!=0;
3482 if (bDoDistort)
3484 getSdrDragView().DistortMarkedObj(aMarkRect,aDistortedRect,!bContortion,bCopy);
3485 return true;
3488 return false;
3491 Pointer SdrDragDistort::GetSdrDragPointer() const
3493 return Pointer(POINTER_REFHAND);
3496 void SdrDragDistort::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
3498 const bool bDoDistort(DragStat().GetDX()!=0 || DragStat().GetDY()!=0);
3500 if (bDoDistort)
3502 getSdrDragView().ImpDistortObj(&rTarget, aMarkRect, aDistortedRect, !bContortion);
3506 void SdrDragDistort::applyCurrentTransformationToPolyPolygon(basegfx::B2DPolyPolygon& rTarget)
3508 // use helper derived from old stuff
3509 _MovAllPoints(rTarget);
3512 ////////////////////////////////////////////////////////////////////////////////////////////////////
3514 TYPEINIT1(SdrDragCrop,SdrDragResize);
3516 SdrDragCrop::SdrDragCrop(SdrDragView& rNewView)
3517 : SdrDragResize(rNewView)
3519 // switch off solid dragging for crop; it just makes no sense since showing
3520 // a 50% transparent object above the original will not be visible
3521 setSolidDraggingActive(false);
3524 void SdrDragCrop::TakeSdrDragComment(XubString& rStr) const
3526 ImpTakeDescriptionStr(STR_DragMethCrop, rStr);
3528 XubString aStr;
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(')');
3538 if(getSdrDragView().IsDragWithCopy())
3539 rStr += ImpGetResStr(STR_EditWithCopy);
3542 bool SdrDragCrop::EndSdrDrag(bool bCopy)
3544 Hide();
3546 if( DragStat().GetDX()==0 && DragStat().GetDY()==0 )
3547 return false;
3549 const SdrMarkList& rMarkList = getSdrDragView().GetMarkedObjectList();
3551 if( rMarkList.GetMarkCount() != 1 )
3552 return false;
3554 SdrGrafObj* pObj = dynamic_cast<SdrGrafObj*>( rMarkList.GetMark( 0 )->GetMarkedSdrObj() );
3556 if( !pObj || (pObj->GetGraphicType() == GRAPHIC_NONE) || (pObj->GetGraphicType() == GRAPHIC_DEFAULT) )
3557 return false;
3559 const GraphicObject& rGraphicObject = pObj->GetGraphicObject();
3560 const MapMode aMapMode100thmm(MAP_100TH_MM);
3561 Size aGraphicSize(rGraphicObject.GetPrefSize());
3563 if( MAP_PIXEL == rGraphicObject.GetPrefMapMode().GetMapUnit() )
3564 aGraphicSize = Application::GetDefaultDevice()->PixelToLogic( aGraphicSize, aMapMode100thmm );
3565 else
3566 aGraphicSize = Application::GetDefaultDevice()->LogicToLogic( aGraphicSize, rGraphicObject.GetPrefMapMode(), aMapMode100thmm);
3568 if( aGraphicSize.nA == 0 || aGraphicSize.nB == 0 )
3569 return false;
3571 const SdrGrafCropItem& rOldCrop = (const SdrGrafCropItem&)pObj->GetMergedItem(SDRATTR_GRAFCROP);
3573 const bool bUndo = getSdrDragView().IsUndoEnabled();
3575 if( bUndo )
3577 String aUndoStr;
3578 ImpTakeDescriptionStr(STR_DragMethCrop, aUndoStr);
3580 getSdrDragView().BegUndo( aUndoStr );
3581 getSdrDragView().AddUndo( getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoGeoObject( *pObj ) );
3584 Rectangle aOldRect( pObj->GetLogicRect() );
3585 getSdrDragView().ResizeMarkedObj(DragStat().Ref1(),aXFact,aYFact,bCopy);
3586 Rectangle aNewRect( pObj->GetLogicRect() );
3588 double fScaleX = ( aGraphicSize.Width() - rOldCrop.GetLeft() - rOldCrop.GetRight() ) / (double)aOldRect.GetWidth();
3589 double fScaleY = ( aGraphicSize.Height() - rOldCrop.GetTop() - rOldCrop.GetBottom() ) / (double)aOldRect.GetHeight();
3591 sal_Int32 nDiffLeft = aNewRect.nLeft - aOldRect.nLeft;
3592 sal_Int32 nDiffTop = aNewRect.nTop - aOldRect.nTop;
3593 sal_Int32 nDiffRight = aNewRect.nRight - aOldRect.nRight;
3594 sal_Int32 nDiffBottom = aNewRect.nBottom - aOldRect.nBottom;
3596 sal_Int32 nLeftCrop = static_cast<sal_Int32>( rOldCrop.GetLeft() + nDiffLeft * fScaleX );
3597 sal_Int32 nTopCrop = static_cast<sal_Int32>( rOldCrop.GetTop() + nDiffTop * fScaleY );
3598 sal_Int32 nRightCrop = static_cast<sal_Int32>( rOldCrop.GetRight() - nDiffRight * fScaleX );
3599 sal_Int32 nBottomCrop = static_cast<sal_Int32>( rOldCrop.GetBottom() - nDiffBottom * fScaleY );
3601 SfxItemPool& rPool = getSdrDragView().GetModel()->GetItemPool();
3602 SfxItemSet aSet( rPool, SDRATTR_GRAFCROP, SDRATTR_GRAFCROP );
3603 aSet.Put( SdrGrafCropItem( nLeftCrop, nTopCrop, nRightCrop, nBottomCrop ) );
3604 getSdrDragView().SetAttributes( aSet, false );
3606 if( bUndo )
3607 getSdrDragView().EndUndo();
3609 return true;
3612 Pointer SdrDragCrop::GetSdrDragPointer() const
3614 return Pointer(POINTER_CROP);
3617 ////////////////////////////////////////////////////////////////////////////////////////////////////
3618 // eof