update dev300-m58
[ooovba.git] / svx / source / svdraw / svddrgmt.cxx
blob5c582541e278e1a568e2ce75ab610dbbac808a9f
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 const SdrObject* pObj = GetDragObj();
1140 if(pObj)
1142 rStr = pObj->getSpecialDragComment(DragStat());
1146 bool SdrDragObjOwn::BeginSdrDrag()
1148 if(!mpClone)
1150 const SdrObject* pObj = GetDragObj();
1152 if(pObj && !pObj->IsResizeProtect())
1154 if(pObj->beginSpecialDrag(DragStat()))
1156 // create nitial clone to have a start visualisation
1157 mpClone = pObj->getFullDragClone();
1158 mpClone->applySpecialDrag(DragStat());
1160 return true;
1165 return false;
1168 void SdrDragObjOwn::MoveSdrDrag(const Point& rNoSnapPnt)
1170 const SdrObject* pObj = GetDragObj();
1172 if(pObj)
1174 Point aPnt(rNoSnapPnt);
1175 SdrPageView* pPV = GetDragPV();
1177 if(pPV)
1179 if(!DragStat().IsNoSnap())
1181 SnapPos(aPnt);
1184 if(getSdrDragView().IsOrtho())
1186 if (DragStat().IsOrtho8Possible())
1188 OrthoDistance8(DragStat().GetStart(),aPnt,getSdrDragView().IsBigOrtho());
1190 else if (DragStat().IsOrtho4Possible())
1192 OrthoDistance4(DragStat().GetStart(),aPnt,getSdrDragView().IsBigOrtho());
1196 if(DragStat().CheckMinMoved(rNoSnapPnt))
1198 if(aPnt != DragStat().GetNow())
1200 Hide();
1201 DragStat().NextMove(aPnt);
1203 // since SdrDragObjOwn currently supports no transformation of
1204 // existing SdrDragEntries but only their recreation, a recreation
1205 // after every move is needed in this mode. Delete existing
1206 // SdrDragEntries here to force their recreation in the following Show().
1207 clearSdrDragEntries();
1209 // delete current clone (after the last reference to it is deleted above)
1210 if(mpClone)
1212 SdrObject::Free(mpClone);
1213 mpClone = 0;
1216 // create a new clone and modify to current drag state
1217 if(!mpClone)
1219 mpClone = pObj->getFullDragClone();
1220 mpClone->applySpecialDrag(DragStat());
1223 Show();
1230 bool SdrDragObjOwn::EndSdrDrag(bool /*bCopy*/)
1232 Hide();
1233 SdrUndoAction* pUndo = NULL;
1234 SdrUndoAction* pUndo2 = NULL;
1235 std::vector< SdrUndoAction* > vConnectorUndoActions;
1236 bool bRet = false;
1237 SdrObject* pObj = GetDragObj();
1239 if(pObj)
1241 const bool bUndo = getSdrDragView().IsUndoEnabled();
1243 if( bUndo )
1245 if(!getSdrDragView().IsInsObjPoint() && pObj->IsInserted() )
1247 if (DragStat().IsEndDragChangesAttributes())
1249 pUndo=getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pObj);
1251 if (DragStat().IsEndDragChangesGeoAndAttributes())
1253 vConnectorUndoActions = getSdrDragView().CreateConnectorUndo( *pObj );
1254 pUndo2 = getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj);
1257 else
1259 vConnectorUndoActions = getSdrDragView().CreateConnectorUndo( *pObj );
1260 pUndo= getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj);
1264 if( pUndo )
1266 getSdrDragView().BegUndo( pUndo->GetComment() );
1268 else
1270 getSdrDragView().BegUndo();
1274 // evtl. use opertator= for setting changed object data (do not change selection in
1275 // view, this will destroy the interactor). This is possible since a clone is now
1276 // directly modified by the modifiers. Only SdrTableObj is adding own UNDOs
1277 // in it's SdrTableObj::endSpecialDrag, so currently not possible. OTOH it uses
1278 // a CreateUndoGeoObject() so maybe setting SetEndDragChangesAttributes is okay. I
1279 // will test this now
1280 Rectangle aBoundRect0;
1282 if(pObj->GetUserCall())
1284 aBoundRect0 = pObj->GetLastBoundRect();
1287 bRet = pObj->applySpecialDrag(DragStat());
1289 if(bRet)
1291 pObj->SetChanged();
1292 pObj->BroadcastObjectChange();
1293 pObj->SendUserCall( SDRUSERCALL_RESIZE, aBoundRect0 );
1296 if(bRet)
1298 if( bUndo )
1300 getSdrDragView().AddUndoActions( vConnectorUndoActions );
1302 if ( pUndo )
1304 getSdrDragView().AddUndo(pUndo);
1307 if ( pUndo2 )
1309 getSdrDragView().AddUndo(pUndo2);
1313 else
1315 if( bUndo )
1317 std::vector< SdrUndoAction* >::iterator vConnectorUndoIter( vConnectorUndoActions.begin() );
1319 while( vConnectorUndoIter != vConnectorUndoActions.end() )
1321 delete *vConnectorUndoIter++;
1324 delete pUndo;
1325 delete pUndo2;
1329 if( bUndo )
1330 getSdrDragView().EndUndo();
1333 return bRet;
1336 Pointer SdrDragObjOwn::GetSdrDragPointer() const
1338 const SdrHdl* pHdl=GetDragHdl();
1340 if (pHdl)
1342 return pHdl->GetPointer();
1345 return Pointer(POINTER_MOVE);
1348 ////////////////////////////////////////////////////////////////////////////////////////////////////
1350 TYPEINIT1(SdrDragMove,SdrDragMethod);
1352 void SdrDragMove::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
1354 rTarget.Move(Size(DragStat().GetDX(), DragStat().GetDY()));
1357 SdrDragMove::SdrDragMove(SdrDragView& rNewView)
1358 : SdrDragMethod(rNewView)
1360 setMoveOnly(true);
1363 void SdrDragMove::TakeSdrDragComment(XubString& rStr) const
1365 XubString aStr;
1367 ImpTakeDescriptionStr(STR_DragMethMove, rStr);
1368 rStr.AppendAscii(" (x=");
1369 getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDX(), aStr);
1370 rStr += aStr;
1371 rStr.AppendAscii(" y=");
1372 getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDY(), aStr);
1373 rStr += aStr;
1374 rStr += sal_Unicode(')');
1376 if(getSdrDragView().IsDragWithCopy())
1378 if(!getSdrDragView().IsInsObjPoint() && !getSdrDragView().IsInsGluePoint())
1380 rStr += ImpGetResStr(STR_EditWithCopy);
1385 bool SdrDragMove::BeginSdrDrag()
1387 DragStat().SetActionRect(GetMarkedRect());
1388 Show();
1390 return true;
1393 basegfx::B2DHomMatrix SdrDragMove::getCurrentTransformation()
1395 basegfx::B2DHomMatrix aRetval;
1397 aRetval.translate(DragStat().GetDX(), DragStat().GetDY());
1399 return aRetval;
1402 void SdrDragMove::ImpCheckSnap(const Point& rPt)
1404 Point aPt(rPt);
1405 sal_uInt16 nRet=SnapPos(aPt);
1406 aPt-=rPt;
1408 if ((nRet & SDRSNAP_XSNAPPED) !=0)
1410 if (bXSnapped)
1412 if (Abs(aPt.X())<Abs(nBestXSnap))
1414 nBestXSnap=aPt.X();
1417 else
1419 nBestXSnap=aPt.X();
1420 bXSnapped=true;
1424 if ((nRet & SDRSNAP_YSNAPPED) !=0)
1426 if (bYSnapped)
1428 if (Abs(aPt.Y())<Abs(nBestYSnap))
1430 nBestYSnap=aPt.Y();
1433 else
1435 nBestYSnap=aPt.Y();
1436 bYSnapped=true;
1441 void SdrDragMove::MoveSdrDrag(const Point& rNoSnapPnt_)
1443 nBestXSnap=0;
1444 nBestYSnap=0;
1445 bXSnapped=false;
1446 bYSnapped=false;
1447 Point aNoSnapPnt(rNoSnapPnt_);
1448 const Rectangle& aSR=GetMarkedRect();
1449 long nMovedx=aNoSnapPnt.X()-DragStat().GetStart().X();
1450 long nMovedy=aNoSnapPnt.Y()-DragStat().GetStart().Y();
1451 Point aLO(aSR.TopLeft()); aLO.X()+=nMovedx; aLO.Y()+=nMovedy;
1452 Point aRU(aSR.BottomRight()); aRU.X()+=nMovedx; aRU.Y()+=nMovedy;
1453 Point aLU(aLO.X(),aRU.Y());
1454 Point aRO(aRU.X(),aLO.Y());
1455 ImpCheckSnap(aLO);
1457 if (!getSdrDragView().IsMoveSnapOnlyTopLeft())
1459 ImpCheckSnap(aRO);
1460 ImpCheckSnap(aLU);
1461 ImpCheckSnap(aRU);
1464 Point aPnt(aNoSnapPnt.X()+nBestXSnap,aNoSnapPnt.Y()+nBestYSnap);
1465 bool bOrtho=getSdrDragView().IsOrtho();
1467 if (bOrtho)
1468 OrthoDistance8(DragStat().GetStart(),aPnt,getSdrDragView().IsBigOrtho());
1470 if (DragStat().CheckMinMoved(aNoSnapPnt))
1472 Point aPt1(aPnt);
1473 Rectangle aLR(getSdrDragView().GetWorkArea());
1474 bool bWorkArea=!aLR.IsEmpty();
1475 bool bDragLimit=IsDragLimit();
1477 if (bDragLimit || bWorkArea)
1479 Rectangle aSR2(GetMarkedRect());
1480 Point aD(aPt1-DragStat().GetStart());
1482 if (bDragLimit)
1484 Rectangle aR2(GetDragLimitRect());
1486 if (bWorkArea)
1487 aLR.Intersection(aR2);
1488 else
1489 aLR=aR2;
1492 if (aSR2.Left()>aLR.Left() || aSR2.Right()<aLR.Right())
1493 { // ist ueberhaupt Platz zum verschieben?
1494 aSR2.Move(aD.X(),0);
1496 if (aSR2.Left()<aLR.Left())
1498 aPt1.X()-=aSR2.Left()-aLR.Left();
1500 else if (aSR2.Right()>aLR.Right())
1502 aPt1.X()-=aSR2.Right()-aLR.Right();
1505 else
1506 aPt1.X()=DragStat().GetStart().X(); // kein Platz zum verschieben
1508 if (aSR2.Top()>aLR.Top() || aSR2.Bottom()<aLR.Bottom())
1509 { // ist ueberhaupt Platz zum verschieben?
1510 aSR2.Move(0,aD.Y());
1512 if (aSR2.Top()<aLR.Top())
1514 aPt1.Y()-=aSR2.Top()-aLR.Top();
1516 else if (aSR2.Bottom()>aLR.Bottom())
1518 aPt1.Y()-=aSR2.Bottom()-aLR.Bottom();
1521 else
1522 aPt1.Y()=DragStat().GetStart().Y(); // kein Platz zum verschieben
1525 if (getSdrDragView().IsDraggingGluePoints())
1526 { // Klebepunkte aufs BoundRect des Obj limitieren
1527 aPt1-=DragStat().GetStart();
1528 const SdrMarkList& rML=GetMarkedObjectList();
1529 ULONG nMarkAnz=rML.GetMarkCount();
1531 for (ULONG nMarkNum=0; nMarkNum<nMarkAnz; nMarkNum++)
1533 const SdrMark* pM=rML.GetMark(nMarkNum);
1534 const SdrUShortCont* pPts=pM->GetMarkedGluePoints();
1535 ULONG nPtAnz=pPts==NULL ? 0 : pPts->GetCount();
1537 if (nPtAnz!=0)
1539 const SdrObject* pObj=pM->GetMarkedSdrObj();
1540 const SdrGluePointList* pGPL=pObj->GetGluePointList();
1541 Rectangle aBound(pObj->GetCurrentBoundRect());
1543 for (ULONG nPtNum=0; nPtNum<nPtAnz; nPtNum++)
1545 sal_uInt16 nId=pPts->GetObject(nPtNum);
1546 sal_uInt16 nGlueNum=pGPL->FindGluePoint(nId);
1548 if (nGlueNum!=SDRGLUEPOINT_NOTFOUND)
1550 Point aPt((*pGPL)[nGlueNum].GetAbsolutePos(*pObj));
1551 aPt+=aPt1; // soviel soll verschoben werden
1552 if (aPt.X()<aBound.Left() ) aPt1.X()-=aPt.X()-aBound.Left() ;
1553 if (aPt.X()>aBound.Right() ) aPt1.X()-=aPt.X()-aBound.Right() ;
1554 if (aPt.Y()<aBound.Top() ) aPt1.Y()-=aPt.Y()-aBound.Top() ;
1555 if (aPt.Y()>aBound.Bottom()) aPt1.Y()-=aPt.Y()-aBound.Bottom();
1561 aPt1+=DragStat().GetStart();
1564 if (bOrtho)
1565 OrthoDistance8(DragStat().GetStart(),aPt1,false);
1567 if (aPt1!=DragStat().GetNow())
1569 Hide();
1570 DragStat().NextMove(aPt1);
1571 Rectangle aAction(GetMarkedRect());
1572 aAction.Move(DragStat().GetDX(),DragStat().GetDY());
1573 DragStat().SetActionRect(aAction);
1574 Show();
1579 bool SdrDragMove::EndSdrDrag(bool bCopy)
1581 Hide();
1583 if (getSdrDragView().IsInsObjPoint() || getSdrDragView().IsInsGluePoint())
1584 bCopy=false;
1586 if (IsDraggingPoints())
1588 getSdrDragView().MoveMarkedPoints(Size(DragStat().GetDX(),DragStat().GetDY()),bCopy);
1590 else if (IsDraggingGluePoints())
1592 getSdrDragView().MoveMarkedGluePoints(Size(DragStat().GetDX(),DragStat().GetDY()),bCopy);
1594 else
1596 getSdrDragView().MoveMarkedObj(Size(DragStat().GetDX(),DragStat().GetDY()),bCopy);
1599 return true;
1602 Pointer SdrDragMove::GetSdrDragPointer() const
1604 if (IsDraggingPoints() || IsDraggingGluePoints())
1606 return Pointer(POINTER_MOVEPOINT);
1608 else
1610 return Pointer(POINTER_MOVE);
1614 ////////////////////////////////////////////////////////////////////////////////////////////////////
1616 TYPEINIT1(SdrDragResize,SdrDragMethod);
1618 SdrDragResize::SdrDragResize(SdrDragView& rNewView)
1619 : SdrDragMethod(rNewView),
1620 aXFact(1,1),
1621 aYFact(1,1)
1625 void SdrDragResize::TakeSdrDragComment(XubString& rStr) const
1627 ImpTakeDescriptionStr(STR_DragMethResize, rStr);
1628 bool bEqual(aXFact == aYFact);
1629 Fraction aFact1(1,1);
1630 Point aStart(DragStat().GetStart());
1631 Point aRef(DragStat().GetRef1());
1632 INT32 nXDiv(aStart.X() - aRef.X());
1634 if(!nXDiv)
1635 nXDiv = 1;
1637 INT32 nYDiv(aStart.Y() - aRef.Y());
1639 if(!nYDiv)
1640 nYDiv = 1;
1642 bool bX(aXFact != aFact1 && Abs(nXDiv) > 1);
1643 bool bY(aYFact != aFact1 && Abs(nYDiv) > 1);
1645 if(bX || bY)
1647 XubString aStr;
1649 rStr.AppendAscii(" (");
1651 if(bX)
1653 if(!bEqual)
1654 rStr.AppendAscii("x=");
1656 getSdrDragView().GetModel()->TakePercentStr(aXFact, aStr);
1657 rStr += aStr;
1660 if(bY && !bEqual)
1662 if(bX)
1663 rStr += sal_Unicode(' ');
1665 rStr.AppendAscii("y=");
1666 getSdrDragView().GetModel()->TakePercentStr(aYFact, aStr);
1667 rStr += aStr;
1670 rStr += sal_Unicode(')');
1673 if(getSdrDragView().IsDragWithCopy())
1674 rStr += ImpGetResStr(STR_EditWithCopy);
1677 bool SdrDragResize::BeginSdrDrag()
1679 SdrHdlKind eRefHdl=HDL_MOVE;
1680 SdrHdl* pRefHdl=NULL;
1682 switch (GetDragHdlKind())
1684 case HDL_UPLFT: eRefHdl=HDL_LWRGT; break;
1685 case HDL_UPPER: eRefHdl=HDL_LOWER; DragStat().SetHorFixed(true); break;
1686 case HDL_UPRGT: eRefHdl=HDL_LWLFT; break;
1687 case HDL_LEFT : eRefHdl=HDL_RIGHT; DragStat().SetVerFixed(true); break;
1688 case HDL_RIGHT: eRefHdl=HDL_LEFT ; DragStat().SetVerFixed(true); break;
1689 case HDL_LWLFT: eRefHdl=HDL_UPRGT; break;
1690 case HDL_LOWER: eRefHdl=HDL_UPPER; DragStat().SetHorFixed(true); break;
1691 case HDL_LWRGT: eRefHdl=HDL_UPLFT; break;
1692 default: break;
1695 if (eRefHdl!=HDL_MOVE)
1696 pRefHdl=GetHdlList().GetHdl(eRefHdl);
1698 if (pRefHdl!=NULL && !getSdrDragView().IsResizeAtCenter())
1700 DragStat().Ref1()=pRefHdl->GetPos();
1702 else
1704 SdrHdl* pRef1=GetHdlList().GetHdl(HDL_UPLFT);
1705 SdrHdl* pRef2=GetHdlList().GetHdl(HDL_LWRGT);
1707 if (pRef1!=NULL && pRef2!=NULL)
1709 DragStat().Ref1()=Rectangle(pRef1->GetPos(),pRef2->GetPos()).Center();
1711 else
1713 DragStat().Ref1()=GetMarkedRect().Center();
1717 Show();
1719 return true;
1722 basegfx::B2DHomMatrix SdrDragResize::getCurrentTransformation()
1724 basegfx::B2DHomMatrix aRetval;
1726 aRetval.translate(-DragStat().Ref1().X(), -DragStat().Ref1().Y());
1727 aRetval.scale(aXFact, aYFact);
1728 aRetval.translate(DragStat().Ref1().X(), DragStat().Ref1().Y());
1730 return aRetval;
1733 void SdrDragResize::MoveSdrDrag(const Point& rNoSnapPnt)
1735 Point aPnt(GetSnapPos(rNoSnapPnt));
1736 Point aStart(DragStat().GetStart());
1737 Point aRef(DragStat().GetRef1());
1738 Fraction aMaxFact(0x7FFFFFFF,1);
1739 Rectangle aLR(getSdrDragView().GetWorkArea());
1740 bool bWorkArea=!aLR.IsEmpty();
1741 bool bDragLimit=IsDragLimit();
1743 if (bDragLimit || bWorkArea)
1745 Rectangle aSR(GetMarkedRect());
1747 if (bDragLimit)
1749 Rectangle aR2(GetDragLimitRect());
1751 if (bWorkArea)
1752 aLR.Intersection(aR2);
1753 else
1754 aLR=aR2;
1757 if (aPnt.X()<aLR.Left())
1758 aPnt.X()=aLR.Left();
1759 else if (aPnt.X()>aLR.Right())
1760 aPnt.X()=aLR.Right();
1762 if (aPnt.Y()<aLR.Top())
1763 aPnt.Y()=aLR.Top();
1764 else if (aPnt.Y()>aLR.Bottom())
1765 aPnt.Y()=aLR.Bottom();
1767 if (aRef.X()>aSR.Left())
1769 Fraction aMax(aRef.X()-aLR.Left(),aRef.X()-aSR.Left());
1771 if (aMax<aMaxFact)
1772 aMaxFact=aMax;
1775 if (aRef.X()<aSR.Right())
1777 Fraction aMax(aLR.Right()-aRef.X(),aSR.Right()-aRef.X());
1779 if (aMax<aMaxFact)
1780 aMaxFact=aMax;
1783 if (aRef.Y()>aSR.Top())
1785 Fraction aMax(aRef.Y()-aLR.Top(),aRef.Y()-aSR.Top());
1787 if (aMax<aMaxFact)
1788 aMaxFact=aMax;
1791 if (aRef.Y()<aSR.Bottom())
1793 Fraction aMax(aLR.Bottom()-aRef.Y(),aSR.Bottom()-aRef.Y());
1795 if (aMax<aMaxFact)
1796 aMaxFact=aMax;
1800 long nXDiv=aStart.X()-aRef.X(); if (nXDiv==0) nXDiv=1;
1801 long nYDiv=aStart.Y()-aRef.Y(); if (nYDiv==0) nYDiv=1;
1802 long nXMul=aPnt.X()-aRef.X();
1803 long nYMul=aPnt.Y()-aRef.Y();
1805 if (nXDiv<0)
1807 nXDiv=-nXDiv;
1808 nXMul=-nXMul;
1811 if (nYDiv<0)
1813 nYDiv=-nYDiv;
1814 nYMul=-nYMul;
1817 bool bXNeg=nXMul<0; if (bXNeg) nXMul=-nXMul;
1818 bool bYNeg=nYMul<0; if (bYNeg) nYMul=-nYMul;
1819 bool bOrtho=getSdrDragView().IsOrtho() || !getSdrDragView().IsResizeAllowed(false);
1821 if (!DragStat().IsHorFixed() && !DragStat().IsVerFixed())
1823 if (Abs(nXDiv)<=1 || Abs(nYDiv)<=1)
1824 bOrtho=false;
1826 if (bOrtho)
1828 if ((Fraction(nXMul,nXDiv)>Fraction(nYMul,nYDiv)) !=getSdrDragView().IsBigOrtho())
1830 nXMul=nYMul;
1831 nXDiv=nYDiv;
1833 else
1835 nYMul=nXMul;
1836 nYDiv=nXDiv;
1840 else
1842 if (bOrtho)
1844 if (DragStat().IsHorFixed())
1846 bXNeg=false;
1847 nXMul=nYMul;
1848 nXDiv=nYDiv;
1851 if (DragStat().IsVerFixed())
1853 bYNeg=false;
1854 nYMul=nXMul;
1855 nYDiv=nXDiv;
1858 else
1860 if (DragStat().IsHorFixed())
1862 bXNeg=false;
1863 nXMul=1;
1864 nXDiv=1;
1867 if (DragStat().IsVerFixed())
1869 bYNeg=false;
1870 nYMul=1;
1871 nYDiv=1;
1876 Fraction aNeuXFact(nXMul,nXDiv);
1877 Fraction aNeuYFact(nYMul,nYDiv);
1879 if (bOrtho)
1881 if (aNeuXFact>aMaxFact)
1883 aNeuXFact=aMaxFact;
1884 aNeuYFact=aMaxFact;
1887 if (aNeuYFact>aMaxFact)
1889 aNeuXFact=aMaxFact;
1890 aNeuYFact=aMaxFact;
1894 if (bXNeg)
1895 aNeuXFact=Fraction(-aNeuXFact.GetNumerator(),aNeuXFact.GetDenominator());
1897 if (bYNeg)
1898 aNeuYFact=Fraction(-aNeuYFact.GetNumerator(),aNeuYFact.GetDenominator());
1900 if (DragStat().CheckMinMoved(aPnt))
1902 if ((!DragStat().IsHorFixed() && aPnt.X()!=DragStat().GetNow().X()) ||
1903 (!DragStat().IsVerFixed() && aPnt.Y()!=DragStat().GetNow().Y()))
1905 Hide();
1906 DragStat().NextMove(aPnt);
1907 aXFact=aNeuXFact;
1908 aYFact=aNeuYFact;
1909 Show();
1914 void SdrDragResize::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
1916 rTarget.Resize(DragStat().Ref1(),aXFact,aYFact);
1919 bool SdrDragResize::EndSdrDrag(bool bCopy)
1921 Hide();
1923 if (IsDraggingPoints())
1925 getSdrDragView().ResizeMarkedPoints(DragStat().Ref1(),aXFact,aYFact,bCopy);
1927 else if (IsDraggingGluePoints())
1929 getSdrDragView().ResizeMarkedGluePoints(DragStat().Ref1(),aXFact,aYFact,bCopy);
1931 else
1933 getSdrDragView().ResizeMarkedObj(DragStat().Ref1(),aXFact,aYFact,bCopy);
1936 return true;
1939 Pointer SdrDragResize::GetSdrDragPointer() const
1941 const SdrHdl* pHdl=GetDragHdl();
1943 if (pHdl!=NULL)
1945 return pHdl->GetPointer();
1948 return Pointer(POINTER_MOVE);
1951 ////////////////////////////////////////////////////////////////////////////////////////////////////
1953 TYPEINIT1(SdrDragRotate,SdrDragMethod);
1955 void SdrDragRotate::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
1957 rTarget.Rotate(DragStat().GetRef1(), nWink, sin(nWink*nPi180), cos(nWink*nPi180));
1960 SdrDragRotate::SdrDragRotate(SdrDragView& rNewView)
1961 : SdrDragMethod(rNewView),
1962 nSin(0.0),
1963 nCos(1.0),
1964 nWink0(0),
1965 nWink(0),
1966 bRight(false)
1970 void SdrDragRotate::TakeSdrDragComment(XubString& rStr) const
1972 ImpTakeDescriptionStr(STR_DragMethRotate, rStr);
1973 rStr.AppendAscii(" (");
1974 XubString aStr;
1975 INT32 nTmpWink(NormAngle360(nWink));
1977 if(bRight && nWink)
1979 nTmpWink -= 36000;
1982 getSdrDragView().GetModel()->TakeWinkStr(nTmpWink, aStr);
1983 rStr += aStr;
1984 rStr += sal_Unicode(')');
1986 if(getSdrDragView().IsDragWithCopy())
1987 rStr += ImpGetResStr(STR_EditWithCopy);
1990 bool SdrDragRotate::BeginSdrDrag()
1992 SdrHdl* pH=GetHdlList().GetHdl(HDL_REF1);
1994 if (pH!=NULL)
1996 Show();
1997 DragStat().Ref1()=pH->GetPos();
1998 nWink0=GetAngle(DragStat().GetStart()-DragStat().GetRef1());
1999 return true;
2001 else
2003 DBG_ERROR("SdrDragRotate::BeginSdrDrag(): Kein Referenzpunkt-Handle gefunden");
2004 return false;
2008 basegfx::B2DHomMatrix SdrDragRotate::getCurrentTransformation()
2010 basegfx::B2DHomMatrix aRetval;
2012 aRetval.translate(-DragStat().GetRef1().X(), -DragStat().GetRef1().Y());
2013 aRetval.rotate(-atan2(nSin, nCos));
2014 aRetval.translate(DragStat().GetRef1().X(), DragStat().GetRef1().Y());
2016 return aRetval;
2019 void SdrDragRotate::MoveSdrDrag(const Point& rPnt_)
2021 Point aPnt(rPnt_);
2022 if (DragStat().CheckMinMoved(aPnt))
2024 long nNeuWink=NormAngle360(GetAngle(aPnt-DragStat().GetRef1())-nWink0);
2025 long nSA=0;
2027 if (getSdrDragView().IsAngleSnapEnabled())
2028 nSA=getSdrDragView().GetSnapAngle();
2030 if (!getSdrDragView().IsRotateAllowed(false))
2031 nSA=9000;
2033 if (nSA!=0)
2034 { // Winkelfang
2035 nNeuWink+=nSA/2;
2036 nNeuWink/=nSA;
2037 nNeuWink*=nSA;
2040 nNeuWink=NormAngle180(nNeuWink);
2042 if (nWink!=nNeuWink)
2044 sal_uInt16 nSekt0=GetAngleSector(nWink);
2045 sal_uInt16 nSekt1=GetAngleSector(nNeuWink);
2047 if (nSekt0==0 && nSekt1==3)
2048 bRight=true;
2050 if (nSekt0==3 && nSekt1==0)
2051 bRight=false;
2053 nWink=nNeuWink;
2054 double a=nWink*nPi180;
2055 double nSin1=sin(a); // schonmal berechnen, damit mgl. wenig Zeit
2056 double nCos1=cos(a); // zwischen Hide() und Show() vergeht
2057 Hide();
2058 nSin=nSin1;
2059 nCos=nCos1;
2060 DragStat().NextMove(aPnt);
2061 Show();
2066 bool SdrDragRotate::EndSdrDrag(bool bCopy)
2068 Hide();
2070 if (nWink!=0)
2072 if (IsDraggingPoints())
2074 getSdrDragView().RotateMarkedPoints(DragStat().GetRef1(),nWink,bCopy);
2076 else if (IsDraggingGluePoints())
2078 getSdrDragView().RotateMarkedGluePoints(DragStat().GetRef1(),nWink,bCopy);
2080 else
2082 getSdrDragView().RotateMarkedObj(DragStat().GetRef1(),nWink,bCopy);
2085 return true;
2088 Pointer SdrDragRotate::GetSdrDragPointer() const
2090 return Pointer(POINTER_ROTATE);
2093 ////////////////////////////////////////////////////////////////////////////////////////////////////
2095 TYPEINIT1(SdrDragShear,SdrDragMethod);
2097 SdrDragShear::SdrDragShear(SdrDragView& rNewView, bool bSlant1)
2098 : SdrDragMethod(rNewView),
2099 aFact(1,1),
2100 nWink0(0),
2101 nWink(0),
2102 nTan(0.0),
2103 bVertical(false),
2104 bResize(false),
2105 bUpSideDown(false),
2106 bSlant(bSlant1)
2110 void SdrDragShear::TakeSdrDragComment(XubString& rStr) const
2112 ImpTakeDescriptionStr(STR_DragMethShear, rStr);
2113 rStr.AppendAscii(" (");
2115 INT32 nTmpWink(nWink);
2117 if(bUpSideDown)
2118 nTmpWink += 18000;
2120 nTmpWink = NormAngle180(nTmpWink);
2122 XubString aStr;
2124 getSdrDragView().GetModel()->TakeWinkStr(nTmpWink, aStr);
2125 rStr += aStr;
2126 rStr += sal_Unicode(')');
2128 if(getSdrDragView().IsDragWithCopy())
2129 rStr += ImpGetResStr(STR_EditWithCopy);
2132 bool SdrDragShear::BeginSdrDrag()
2134 SdrHdlKind eRefHdl=HDL_MOVE;
2135 SdrHdl* pRefHdl=NULL;
2137 switch (GetDragHdlKind())
2139 case HDL_UPPER: eRefHdl=HDL_LOWER; break;
2140 case HDL_LOWER: eRefHdl=HDL_UPPER; break;
2141 case HDL_LEFT : eRefHdl=HDL_RIGHT; bVertical=true; break;
2142 case HDL_RIGHT: eRefHdl=HDL_LEFT ; bVertical=true; break;
2143 default: break;
2146 if (eRefHdl!=HDL_MOVE)
2147 pRefHdl=GetHdlList().GetHdl(eRefHdl);
2149 if (pRefHdl!=NULL)
2151 DragStat().Ref1()=pRefHdl->GetPos();
2152 nWink0=GetAngle(DragStat().GetStart()-DragStat().GetRef1());
2154 else
2156 DBG_ERROR("SdrDragShear::BeginSdrDrag(): Kein Referenzpunkt-Handle fuer Shear gefunden");
2157 return false;
2160 Show();
2161 return true;
2164 basegfx::B2DHomMatrix SdrDragShear::getCurrentTransformation()
2166 basegfx::B2DHomMatrix aRetval;
2168 aRetval.translate(-DragStat().GetRef1().X(), -DragStat().GetRef1().Y());
2170 if (bResize)
2172 if (bVertical)
2174 aRetval.scale(aFact, 1.0);
2175 aRetval.shearY(-nTan);
2177 else
2179 aRetval.scale(1.0, aFact);
2180 aRetval.shearX(-nTan);
2184 aRetval.translate(DragStat().GetRef1().X(), DragStat().GetRef1().Y());
2186 return aRetval;
2189 void SdrDragShear::MoveSdrDrag(const Point& rPnt)
2191 if (DragStat().CheckMinMoved(rPnt))
2193 bResize=!getSdrDragView().IsOrtho();
2194 long nSA=0;
2196 if (getSdrDragView().IsAngleSnapEnabled())
2197 nSA=getSdrDragView().GetSnapAngle();
2199 Point aP0(DragStat().GetStart());
2200 Point aPnt(rPnt);
2201 Fraction aNeuFact(1,1);
2203 // Wenn kein Winkelfang, dann ggf. Rasterfang (ausser bei Slant)
2204 if (nSA==0 && !bSlant)
2205 aPnt=GetSnapPos(aPnt);
2207 if (!bSlant && !bResize)
2208 { // Shear ohne Resize
2209 if (bVertical)
2210 aPnt.X()=aP0.X();
2211 else
2212 aPnt.Y()=aP0.Y();
2215 Point aRef(DragStat().GetRef1());
2216 Point aDif(aPnt-aRef);
2218 long nNeuWink=0;
2220 if (bSlant)
2222 nNeuWink=NormAngle180(-(GetAngle(aDif)-nWink0));
2224 if (bVertical)
2225 nNeuWink=NormAngle180(-nNeuWink);
2227 else
2229 if (bVertical)
2230 nNeuWink=NormAngle180(GetAngle(aDif));
2231 else
2232 nNeuWink=NormAngle180(-(GetAngle(aDif)-9000));
2234 if (nNeuWink<-9000 || nNeuWink>9000)
2235 nNeuWink=NormAngle180(nNeuWink+18000);
2237 if (bResize)
2239 Point aPt2(aPnt);
2241 if (nSA!=0)
2242 aPt2=GetSnapPos(aPnt); // den also in jedem Falle fangen
2244 if (bVertical)
2246 aNeuFact=Fraction(aPt2.X()-aRef.X(),aP0.X()-aRef.X());
2248 else
2250 aNeuFact=Fraction(aPt2.Y()-aRef.Y(),aP0.Y()-aRef.Y());
2255 bool bNeg=nNeuWink<0;
2257 if (bNeg)
2258 nNeuWink=-nNeuWink;
2260 if (nSA!=0)
2261 { // Winkelfang
2262 nNeuWink+=nSA/2;
2263 nNeuWink/=nSA;
2264 nNeuWink*=nSA;
2267 nNeuWink=NormAngle360(nNeuWink);
2268 bUpSideDown=nNeuWink>9000 && nNeuWink<27000;
2270 if (bSlant)
2271 { // Resize fuer Slant berechnen
2272 // Mit Winkelfang jedoch ohne 89deg Begrenzung
2273 long nTmpWink=nNeuWink;
2274 if (bUpSideDown) nNeuWink-=18000;
2275 if (bNeg) nTmpWink=-nTmpWink;
2276 bResize=true;
2277 double nCos=cos(nTmpWink*nPi180);
2278 aNeuFact=nCos;
2279 Kuerzen(aFact,10); // 3 Dezimalstellen sollten reichen
2282 if (nNeuWink>8900)
2283 nNeuWink=8900;
2285 if (bNeg)
2286 nNeuWink=-nNeuWink;
2288 if (nWink!=nNeuWink || aFact!=aNeuFact)
2290 nWink=nNeuWink;
2291 aFact=aNeuFact;
2292 double a=nWink*nPi180;
2293 double nTan1=0.0;
2294 nTan1=tan(a); // schonmal berechnen, damit mgl. wenig Zeit zwischen Hide() und Show() vergeht
2295 Hide();
2296 nTan=nTan1;
2297 DragStat().NextMove(rPnt);
2298 Show();
2303 void SdrDragShear::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
2305 if (bResize)
2307 if (bVertical)
2309 rTarget.Resize(DragStat().GetRef1(),aFact,Fraction(1,1));
2311 else
2313 rTarget.Resize(DragStat().GetRef1(),Fraction(1,1),aFact);
2317 if (nWink!=0)
2319 rTarget.Shear(DragStat().GetRef1(),nWink,tan(nWink*nPi180),bVertical);
2323 bool SdrDragShear::EndSdrDrag(bool bCopy)
2325 Hide();
2327 if (bResize && aFact==Fraction(1,1))
2328 bResize=false;
2330 if (nWink!=0 || bResize)
2332 if (nWink!=0 && bResize)
2334 XubString aStr;
2335 ImpTakeDescriptionStr(STR_EditShear,aStr);
2337 if (bCopy)
2338 aStr+=ImpGetResStr(STR_EditWithCopy);
2340 getSdrDragView().BegUndo(aStr);
2343 if (bResize)
2345 if (bVertical)
2347 getSdrDragView().ResizeMarkedObj(DragStat().GetRef1(),aFact,Fraction(1,1),bCopy);
2349 else
2351 getSdrDragView().ResizeMarkedObj(DragStat().GetRef1(),Fraction(1,1),aFact,bCopy);
2354 bCopy=false;
2357 if (nWink!=0)
2359 getSdrDragView().ShearMarkedObj(DragStat().GetRef1(),nWink,bVertical,bCopy);
2362 if (nWink!=0 && bResize)
2363 getSdrDragView().EndUndo();
2365 return true;
2368 return false;
2371 Pointer SdrDragShear::GetSdrDragPointer() const
2373 if (bVertical)
2374 return Pointer(POINTER_VSHEAR);
2375 else
2376 return Pointer(POINTER_HSHEAR);
2379 ////////////////////////////////////////////////////////////////////////////////////////////////////
2381 TYPEINIT1(SdrDragMirror,SdrDragMethod);
2383 void SdrDragMirror::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
2385 if(bMirrored)
2387 rTarget.Mirror(DragStat().GetRef1(), DragStat().GetRef2());
2391 SdrDragMirror::SdrDragMirror(SdrDragView& rNewView)
2392 : SdrDragMethod(rNewView),
2393 nWink(0),
2394 bMirrored(false),
2395 bSide0(false)
2399 bool SdrDragMirror::ImpCheckSide(const Point& rPnt) const
2401 long nWink1=GetAngle(rPnt-DragStat().GetRef1());
2402 nWink1-=nWink;
2403 nWink1=NormAngle360(nWink1);
2405 return nWink1<18000;
2408 void SdrDragMirror::TakeSdrDragComment(XubString& rStr) const
2410 if (aDif.X()==0)
2411 ImpTakeDescriptionStr(STR_DragMethMirrorHori,rStr);
2412 else if (aDif.Y()==0)
2413 ImpTakeDescriptionStr(STR_DragMethMirrorVert,rStr);
2414 else if (Abs(aDif.X())==Abs(aDif.Y()))
2415 ImpTakeDescriptionStr(STR_DragMethMirrorDiag,rStr);
2416 else
2417 ImpTakeDescriptionStr(STR_DragMethMirrorFree,rStr);
2419 if (getSdrDragView().IsDragWithCopy())
2420 rStr+=ImpGetResStr(STR_EditWithCopy);
2423 bool SdrDragMirror::BeginSdrDrag()
2425 SdrHdl* pH1=GetHdlList().GetHdl(HDL_REF1);
2426 SdrHdl* pH2=GetHdlList().GetHdl(HDL_REF2);
2428 if (pH1!=NULL && pH2!=NULL)
2430 DragStat().Ref1()=pH1->GetPos();
2431 DragStat().Ref2()=pH2->GetPos();
2432 Ref1()=pH1->GetPos();
2433 Ref2()=pH2->GetPos();
2434 aDif=pH2->GetPos()-pH1->GetPos();
2435 bool b90=(aDif.X()==0) || aDif.Y()==0;
2436 bool b45=b90 || (Abs(aDif.X())==Abs(aDif.Y()));
2437 nWink=NormAngle360(GetAngle(aDif));
2439 if (!getSdrDragView().IsMirrorAllowed(false,false) && !b45)
2440 return false; // freier Achsenwinkel nicht erlaubt
2442 if (!getSdrDragView().IsMirrorAllowed(true,false) && !b90)
2443 return false; // 45deg auch nicht erlaubt
2445 bSide0=ImpCheckSide(DragStat().GetStart());
2446 Show();
2447 return true;
2449 else
2451 DBG_ERROR("SdrDragMirror::BeginSdrDrag(): Spiegelachse nicht gefunden");
2452 return false;
2456 basegfx::B2DHomMatrix SdrDragMirror::getCurrentTransformation()
2458 basegfx::B2DHomMatrix aRetval;
2460 if (bMirrored)
2462 const double fDeltaX(DragStat().GetRef2().X() - DragStat().GetRef1().X());
2463 const double fDeltaY(DragStat().GetRef2().Y() - DragStat().GetRef1().Y());
2464 const double fRotation(atan2(fDeltaY, fDeltaX));
2466 aRetval.translate(-DragStat().GetRef1().X(), -DragStat().GetRef1().Y());
2467 aRetval.rotate(-fRotation);
2468 aRetval.scale(1.0, -1.0);
2469 aRetval.rotate(fRotation);
2470 aRetval.translate(DragStat().GetRef1().X(), DragStat().GetRef1().Y());
2473 return aRetval;
2476 void SdrDragMirror::MoveSdrDrag(const Point& rPnt)
2478 if (DragStat().CheckMinMoved(rPnt))
2480 bool bNeuSide=ImpCheckSide(rPnt);
2481 bool bNeuMirr=bSide0!=bNeuSide;
2483 if (bMirrored!=bNeuMirr)
2485 Hide();
2486 bMirrored=bNeuMirr;
2487 DragStat().NextMove(rPnt);
2488 Show();
2493 bool SdrDragMirror::EndSdrDrag(bool bCopy)
2495 Hide();
2497 if (bMirrored)
2499 getSdrDragView().MirrorMarkedObj(DragStat().GetRef1(),DragStat().GetRef2(),bCopy);
2502 return true;
2505 Pointer SdrDragMirror::GetSdrDragPointer() const
2507 return Pointer(POINTER_MIRROR);
2510 ////////////////////////////////////////////////////////////////////////////////////////////////////
2512 TYPEINIT1(SdrDragGradient, SdrDragMethod);
2514 SdrDragGradient::SdrDragGradient(SdrDragView& rNewView, bool bGrad)
2515 : SdrDragMethod(rNewView),
2516 pIAOHandle(NULL),
2517 bIsGradient(bGrad)
2521 void SdrDragGradient::TakeSdrDragComment(XubString& rStr) const
2523 if(IsGradient())
2524 ImpTakeDescriptionStr(STR_DragMethGradient, rStr);
2525 else
2526 ImpTakeDescriptionStr(STR_DragMethTransparence, rStr);
2529 bool SdrDragGradient::BeginSdrDrag()
2531 bool bRetval(false);
2533 pIAOHandle = (SdrHdlGradient*)GetHdlList().GetHdl(IsGradient() ? HDL_GRAD : HDL_TRNS);
2535 if(pIAOHandle)
2537 // save old values
2538 DragStat().Ref1() = pIAOHandle->GetPos();
2539 DragStat().Ref2() = pIAOHandle->Get2ndPos();
2541 // what was hit?
2542 bool bHit(false);
2543 SdrHdlColor* pColHdl = pIAOHandle->GetColorHdl1();
2545 // init handling flags
2546 pIAOHandle->SetMoveSingleHandle(false);
2547 pIAOHandle->SetMoveFirstHandle(false);
2549 // test first color handle
2550 if(pColHdl)
2552 basegfx::B2DPoint aPosition(DragStat().GetStart().X(), DragStat().GetStart().Y());
2554 if(pColHdl->getOverlayObjectList().isHitLogic(aPosition))
2556 bHit = true;
2557 pIAOHandle->SetMoveSingleHandle(true);
2558 pIAOHandle->SetMoveFirstHandle(true);
2562 // test second color handle
2563 pColHdl = pIAOHandle->GetColorHdl2();
2565 if(!bHit && pColHdl)
2567 basegfx::B2DPoint aPosition(DragStat().GetStart().X(), DragStat().GetStart().Y());
2569 if(pColHdl->getOverlayObjectList().isHitLogic(aPosition))
2571 bHit = true;
2572 pIAOHandle->SetMoveSingleHandle(true);
2576 // test gradient handle itself
2577 if(!bHit)
2579 basegfx::B2DPoint aPosition(DragStat().GetStart().X(), DragStat().GetStart().Y());
2581 if(pIAOHandle->getOverlayObjectList().isHitLogic(aPosition))
2583 bHit = true;
2587 // everything up and running :o}
2588 bRetval = bHit;
2590 else
2592 DBG_ERROR("SdrDragGradient::BeginSdrDrag(): IAOGradient nicht gefunden");
2595 return bRetval;
2598 void SdrDragGradient::MoveSdrDrag(const Point& rPnt)
2600 if(pIAOHandle && DragStat().CheckMinMoved(rPnt))
2602 DragStat().NextMove(rPnt);
2604 // Do the Move here!!! DragStat().GetStart()
2605 Point aMoveDiff = rPnt - DragStat().GetStart();
2607 if(pIAOHandle->IsMoveSingleHandle())
2609 if(pIAOHandle->IsMoveFirstHandle())
2611 pIAOHandle->SetPos(DragStat().Ref1() + aMoveDiff);
2612 if(pIAOHandle->GetColorHdl1())
2613 pIAOHandle->GetColorHdl1()->SetPos(DragStat().Ref1() + aMoveDiff);
2615 else
2617 pIAOHandle->Set2ndPos(DragStat().Ref2() + aMoveDiff);
2618 if(pIAOHandle->GetColorHdl2())
2619 pIAOHandle->GetColorHdl2()->SetPos(DragStat().Ref2() + aMoveDiff);
2622 else
2624 pIAOHandle->SetPos(DragStat().Ref1() + aMoveDiff);
2625 pIAOHandle->Set2ndPos(DragStat().Ref2() + aMoveDiff);
2627 if(pIAOHandle->GetColorHdl1())
2628 pIAOHandle->GetColorHdl1()->SetPos(DragStat().Ref1() + aMoveDiff);
2630 if(pIAOHandle->GetColorHdl2())
2631 pIAOHandle->GetColorHdl2()->SetPos(DragStat().Ref2() + aMoveDiff);
2634 // new state
2635 pIAOHandle->FromIAOToItem(getSdrDragView().GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(), false, false);
2639 bool SdrDragGradient::EndSdrDrag(bool /*bCopy*/)
2641 // here the result is clear, do something with the values
2642 Ref1() = pIAOHandle->GetPos();
2643 Ref2() = pIAOHandle->Get2ndPos();
2645 // new state
2646 pIAOHandle->FromIAOToItem(getSdrDragView().GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(), true, true);
2648 return true;
2651 void SdrDragGradient::CancelSdrDrag()
2653 // restore old values
2654 pIAOHandle->SetPos(DragStat().Ref1());
2655 pIAOHandle->Set2ndPos(DragStat().Ref2());
2657 if(pIAOHandle->GetColorHdl1())
2658 pIAOHandle->GetColorHdl1()->SetPos(DragStat().Ref1());
2660 if(pIAOHandle->GetColorHdl2())
2661 pIAOHandle->GetColorHdl2()->SetPos(DragStat().Ref2());
2663 // new state
2664 pIAOHandle->FromIAOToItem(getSdrDragView().GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(), true, false);
2667 Pointer SdrDragGradient::GetSdrDragPointer() const
2669 return Pointer(POINTER_REFHAND);
2672 ////////////////////////////////////////////////////////////////////////////////////////////////////
2674 TYPEINIT1(SdrDragCrook,SdrDragMethod);
2676 SdrDragCrook::SdrDragCrook(SdrDragView& rNewView)
2677 : SdrDragMethod(rNewView),
2678 aFact(1,1),
2679 bContortionAllowed(false),
2680 bNoContortionAllowed(false),
2681 bContortion(false),
2682 bResizeAllowed(false),
2683 bResize(false),
2684 bRotateAllowed(false),
2685 bRotate(false),
2686 bVertical(false),
2687 bValid(false),
2688 bLft(false),
2689 bRgt(false),
2690 bUpr(false),
2691 bLwr(false),
2692 bAtCenter(false),
2693 nWink(0),
2694 nMarkSize(0),
2695 eMode(SDRCROOK_ROTATE)
2699 void SdrDragCrook::TakeSdrDragComment(XubString& rStr) const
2701 ImpTakeDescriptionStr(!bContortion ? STR_DragMethCrook : STR_DragMethCrookContortion, rStr);
2703 if(bValid)
2705 rStr.AppendAscii(" (");
2707 XubString aStr;
2708 INT32 nVal(nWink);
2710 if(bAtCenter)
2711 nVal *= 2;
2713 nVal = Abs(nVal);
2714 getSdrDragView().GetModel()->TakeWinkStr(nVal, aStr);
2715 rStr += aStr;
2716 rStr += sal_Unicode(')');
2719 if(getSdrDragView().IsDragWithCopy())
2720 rStr += ImpGetResStr(STR_EditWithCopy);
2723 // #96920# These defines parametrise the created raster
2724 // for interactions
2725 #define DRAG_CROOK_RASTER_MINIMUM (4)
2726 #define DRAG_CROOK_RASTER_MAXIMUM (15)
2727 #define DRAG_CROOK_RASTER_DISTANCE (30)
2729 basegfx::B2DPolyPolygon impCreateDragRaster(SdrPageView& rPageView, const Rectangle& rMarkRect)
2731 basegfx::B2DPolyPolygon aRetval;
2733 if(rPageView.PageWindowCount())
2735 OutputDevice& rOut = (rPageView.GetPageWindow(0)->GetPaintWindow().GetOutputDevice());
2736 Rectangle aPixelSize = rOut.LogicToPixel(rMarkRect);
2737 sal_uInt32 nHorDiv(aPixelSize.GetWidth() / DRAG_CROOK_RASTER_DISTANCE);
2738 sal_uInt32 nVerDiv(aPixelSize.GetHeight() / DRAG_CROOK_RASTER_DISTANCE);
2740 if(nHorDiv > DRAG_CROOK_RASTER_MAXIMUM)
2741 nHorDiv = DRAG_CROOK_RASTER_MAXIMUM;
2742 if(nHorDiv < DRAG_CROOK_RASTER_MINIMUM)
2743 nHorDiv = DRAG_CROOK_RASTER_MINIMUM;
2745 if(nVerDiv > DRAG_CROOK_RASTER_MAXIMUM)
2746 nVerDiv = DRAG_CROOK_RASTER_MAXIMUM;
2747 if(nVerDiv < DRAG_CROOK_RASTER_MINIMUM)
2748 nVerDiv = DRAG_CROOK_RASTER_MINIMUM;
2750 const double fXLen(rMarkRect.GetWidth() / (double)nHorDiv);
2751 const double fYLen(rMarkRect.GetHeight() / (double)nVerDiv);
2752 double fYPos(rMarkRect.Top());
2753 sal_uInt32 a, b;
2755 for(a = 0; a <= nVerDiv; a++)
2757 // hor lines
2758 for(b = 0; b < nHorDiv; b++)
2760 basegfx::B2DPolygon aHorLineSegment;
2762 const double fNewX(rMarkRect.Left() + (b * fXLen));
2763 aHorLineSegment.append(basegfx::B2DPoint(fNewX, fYPos));
2764 aHorLineSegment.appendBezierSegment(
2765 basegfx::B2DPoint(fNewX + (fXLen * (1.0 / 3.0)), fYPos),
2766 basegfx::B2DPoint(fNewX + (fXLen * (2.0 / 3.0)), fYPos),
2767 basegfx::B2DPoint(fNewX + fXLen, fYPos));
2768 aRetval.append(aHorLineSegment);
2771 // increments
2772 fYPos += fYLen;
2775 double fXPos(rMarkRect.Left());
2777 for(a = 0; a <= nHorDiv; a++)
2779 // ver lines
2780 for(b = 0; b < nVerDiv; b++)
2782 basegfx::B2DPolygon aVerLineSegment;
2784 const double fNewY(rMarkRect.Top() + (b * fYLen));
2785 aVerLineSegment.append(basegfx::B2DPoint(fXPos, fNewY));
2786 aVerLineSegment.appendBezierSegment(
2787 basegfx::B2DPoint(fXPos, fNewY + (fYLen * (1.0 / 3.0))),
2788 basegfx::B2DPoint(fXPos, fNewY + (fYLen * (2.0 / 3.0))),
2789 basegfx::B2DPoint(fXPos, fNewY + fYLen));
2790 aRetval.append(aVerLineSegment);
2793 // increments
2794 fXPos += fXLen;
2798 return aRetval;
2801 void SdrDragCrook::createSdrDragEntries()
2803 // Add extended frame raster first, so it will be behind objects
2804 if(getSdrDragView().GetSdrPageView())
2806 const basegfx::B2DPolyPolygon aDragRaster(impCreateDragRaster(*getSdrDragView().GetSdrPageView(), GetMarkedRect()));
2808 if(aDragRaster.count())
2810 addSdrDragEntry(new SdrDragEntryPolyPolygon(aDragRaster));
2814 // call parent
2815 SdrDragMethod::createSdrDragEntries();
2818 bool SdrDragCrook::BeginSdrDrag()
2820 bContortionAllowed=getSdrDragView().IsCrookAllowed(false);
2821 bNoContortionAllowed=getSdrDragView().IsCrookAllowed(true);
2822 bResizeAllowed=getSdrDragView().IsResizeAllowed(false);
2823 bRotateAllowed=getSdrDragView().IsRotateAllowed(false);
2825 if (bContortionAllowed || bNoContortionAllowed)
2827 bVertical=(GetDragHdlKind()==HDL_LOWER || GetDragHdlKind()==HDL_UPPER);
2828 aMarkRect=GetMarkedRect();
2829 aMarkCenter=aMarkRect.Center();
2830 nMarkSize=bVertical ? (aMarkRect.GetHeight()-1) : (aMarkRect.GetWidth()-1);
2831 aCenter=aMarkCenter;
2832 aStart=DragStat().GetStart();
2833 Show();
2834 return true;
2836 else
2838 return false;
2842 void SdrDragCrook::_MovAllPoints(basegfx::B2DPolyPolygon& rTarget)
2844 SdrPageView* pPV = getSdrDragView().GetSdrPageView();
2846 if(pPV)
2848 XPolyPolygon aTempPolyPoly(rTarget);
2850 if (pPV->HasMarkedObjPageView())
2852 sal_uInt16 nPolyAnz=aTempPolyPoly.Count();
2854 if (!bContortion && !getSdrDragView().IsNoDragXorPolys())
2856 sal_uInt16 n1st=0,nLast=0;
2857 Point aC(aCenter);
2859 while (n1st<nPolyAnz)
2861 nLast=n1st;
2862 while (nLast<nPolyAnz && aTempPolyPoly[nLast].GetPointCount()!=0) nLast++;
2863 Rectangle aBound(aTempPolyPoly[n1st].GetBoundRect());
2864 sal_uInt16 i;
2866 for (i=n1st+1; i<nLast; i++)
2868 aBound.Union(aTempPolyPoly[n1st].GetBoundRect());
2871 Point aCtr0(aBound.Center());
2872 Point aCtr1(aCtr0);
2874 if (bResize)
2876 Fraction aFact1(1,1);
2878 if (bVertical)
2880 ResizePoint(aCtr1,aC,aFact1,aFact);
2882 else
2884 ResizePoint(aCtr1,aC,aFact,aFact1);
2888 bool bRotOk=false;
2889 double nSin=0,nCos=0;
2891 if (aRad.X()!=0 && aRad.Y()!=0)
2893 bRotOk=bRotate;
2895 switch (eMode)
2897 case SDRCROOK_ROTATE : CrookRotateXPoint (aCtr1,NULL,NULL,aC,aRad,nSin,nCos,bVertical); break;
2898 case SDRCROOK_SLANT : CrookSlantXPoint (aCtr1,NULL,NULL,aC,aRad,nSin,nCos,bVertical); break;
2899 case SDRCROOK_STRETCH: CrookStretchXPoint(aCtr1,NULL,NULL,aC,aRad,nSin,nCos,bVertical,aMarkRect); break;
2900 } // switch
2903 aCtr1-=aCtr0;
2905 for (i=n1st; i<nLast; i++)
2907 if (bRotOk)
2909 RotateXPoly(aTempPolyPoly[i],aCtr0,nSin,nCos);
2912 aTempPolyPoly[i].Move(aCtr1.X(),aCtr1.Y());
2915 n1st=nLast+1;
2918 else
2920 sal_uInt16 i,j;
2922 for (j=0; j<nPolyAnz; j++)
2924 XPolygon& aPol=aTempPolyPoly[j];
2925 sal_uInt16 nPtAnz=aPol.GetPointCount();
2926 i=0;
2928 while (i<nPtAnz)
2930 Point* pPnt=&aPol[i];
2931 Point* pC1=NULL;
2932 Point* pC2=NULL;
2934 if (i+1<nPtAnz && aPol.IsControl(i))
2935 { // Kontrollpunkt links
2936 pC1=pPnt;
2937 i++;
2938 pPnt=&aPol[i];
2941 i++;
2943 if (i<nPtAnz && aPol.IsControl(i))
2944 { // Kontrollpunkt rechts
2945 pC2=&aPol[i];
2946 i++;
2949 _MovCrookPoint(*pPnt,pC1,pC2);
2955 rTarget = aTempPolyPoly.getB2DPolyPolygon();
2959 void SdrDragCrook::_MovCrookPoint(Point& rPnt, Point* pC1, Point* pC2)
2961 bool bVert=bVertical;
2962 bool bC1=pC1!=NULL;
2963 bool bC2=pC2!=NULL;
2964 Point aC(aCenter);
2966 if (bResize)
2968 Fraction aFact1(1,1);
2970 if (bVert)
2972 ResizePoint(rPnt,aC,aFact1,aFact);
2974 if (bC1)
2975 ResizePoint(*pC1,aC,aFact1,aFact);
2977 if (bC2)
2978 ResizePoint(*pC2,aC,aFact1,aFact);
2980 else
2982 ResizePoint(rPnt,aC,aFact,aFact1);
2984 if (bC1)
2985 ResizePoint(*pC1,aC,aFact,aFact1);
2987 if (bC2)
2988 ResizePoint(*pC2,aC,aFact,aFact1);
2992 if (aRad.X()!=0 && aRad.Y()!=0)
2994 double nSin,nCos;
2996 switch (eMode)
2998 case SDRCROOK_ROTATE : CrookRotateXPoint (rPnt,pC1,pC2,aC,aRad,nSin,nCos,bVert); break;
2999 case SDRCROOK_SLANT : CrookSlantXPoint (rPnt,pC1,pC2,aC,aRad,nSin,nCos,bVert); break;
3000 case SDRCROOK_STRETCH: CrookStretchXPoint(rPnt,pC1,pC2,aC,aRad,nSin,nCos,bVert,aMarkRect); break;
3001 } // switch
3005 void SdrDragCrook::MoveSdrDrag(const Point& rPnt)
3007 if (DragStat().CheckMinMoved(rPnt))
3009 Point aPnt(rPnt);
3010 bool bNeuMoveOnly=getSdrDragView().IsMoveOnlyDragging();
3011 bAtCenter=false;
3012 SdrCrookMode eNeuMode=getSdrDragView().GetCrookMode();
3013 bool bNeuContortion=!bNeuMoveOnly && ((bContortionAllowed && !getSdrDragView().IsCrookNoContortion()) || !bNoContortionAllowed);
3014 bResize=!getSdrDragView().IsOrtho() && bResizeAllowed && !bNeuMoveOnly;
3015 bool bNeuRotate=bRotateAllowed && !bNeuContortion && !bNeuMoveOnly && eNeuMode==SDRCROOK_ROTATE;
3016 long nSA=0;
3018 if (nSA==0)
3019 aPnt=GetSnapPos(aPnt);
3021 Point aNeuCenter(aMarkCenter.X(),aStart.Y());
3023 if (bVertical)
3025 aNeuCenter.X()=aStart.X();
3026 aNeuCenter.Y()=aMarkCenter.Y();
3029 if (!getSdrDragView().IsCrookAtCenter())
3031 switch (GetDragHdlKind())
3033 case HDL_UPLFT: aNeuCenter.X()=aMarkRect.Right(); bLft=true; break;
3034 case HDL_UPPER: aNeuCenter.Y()=aMarkRect.Bottom(); bUpr=true; break;
3035 case HDL_UPRGT: aNeuCenter.X()=aMarkRect.Left(); bRgt=true; break;
3036 case HDL_LEFT : aNeuCenter.X()=aMarkRect.Right(); bLft=true; break;
3037 case HDL_RIGHT: aNeuCenter.X()=aMarkRect.Left(); bRgt=true; break;
3038 case HDL_LWLFT: aNeuCenter.X()=aMarkRect.Right(); bLft=true; break;
3039 case HDL_LOWER: aNeuCenter.Y()=aMarkRect.Top(); bLwr=true; break;
3040 case HDL_LWRGT: aNeuCenter.X()=aMarkRect.Left(); bRgt=true; break;
3041 default: bAtCenter=true;
3044 else
3045 bAtCenter=true;
3047 Fraction aNeuFact(1,1);
3048 long dx1=aPnt.X()-aNeuCenter.X();
3049 long dy1=aPnt.Y()-aNeuCenter.Y();
3050 bValid=bVertical ? dx1!=0 : dy1!=0;
3052 if (bValid)
3054 if (bVertical)
3055 bValid=Abs(dx1)*100>Abs(dy1);
3056 else
3057 bValid=Abs(dy1)*100>Abs(dx1);
3060 long nNeuRad=0;
3061 nWink=0;
3063 if (bValid)
3065 double a=0; // Steigung des Radius
3066 long nPntWink=0;
3068 if (bVertical)
3070 a=((double)dy1)/((double)dx1); // Steigung des Radius
3071 nNeuRad=((long)(dy1*a)+dx1) /2;
3072 aNeuCenter.X()+=nNeuRad;
3073 nPntWink=GetAngle(aPnt-aNeuCenter);
3075 else
3077 a=((double)dx1)/((double)dy1); // Steigung des Radius
3078 nNeuRad=((long)(dx1*a)+dy1) /2;
3079 aNeuCenter.Y()+=nNeuRad;
3080 nPntWink=GetAngle(aPnt-aNeuCenter)-9000;
3083 if (!bAtCenter)
3085 if (nNeuRad<0)
3087 if (bRgt) nPntWink+=18000;
3088 if (bLft) nPntWink=18000-nPntWink;
3089 if (bLwr) nPntWink=-nPntWink;
3091 else
3093 if (bRgt) nPntWink=-nPntWink;
3094 if (bUpr) nPntWink=18000-nPntWink;
3095 if (bLwr) nPntWink+=18000;
3098 nPntWink=NormAngle360(nPntWink);
3100 else
3102 if (nNeuRad<0) nPntWink+=18000;
3103 if (bVertical) nPntWink=18000-nPntWink;
3104 nPntWink=NormAngle180(nPntWink);
3105 nPntWink=Abs(nPntWink);
3108 double nUmfang=2*Abs(nNeuRad)*nPi;
3110 if (bResize)
3112 if (nSA!=0)
3113 { // Winkelfang
3114 long nWink0=nPntWink;
3115 nPntWink+=nSA/2;
3116 nPntWink/=nSA;
3117 nPntWink*=nSA;
3118 BigInt a2(nNeuRad);
3119 a2*=BigInt(nWink);
3120 a2/=BigInt(nWink0);
3121 nNeuRad=long(a2);
3123 if (bVertical)
3124 aNeuCenter.X()=aStart.X()+nNeuRad;
3125 else
3126 aNeuCenter.Y()=aStart.Y()+nNeuRad;
3129 long nMul=(long)(nUmfang*NormAngle360(nPntWink)/36000);
3131 if (bAtCenter)
3132 nMul*=2;
3134 aNeuFact=Fraction(nMul,nMarkSize);
3135 nWink=nPntWink;
3137 else
3139 nWink=(long)((nMarkSize*360/nUmfang)*100)/2;
3141 if (nWink==0)
3142 bValid=false;
3144 if (bValid && nSA!=0)
3145 { // Winkelfang
3146 long nWink0=nWink;
3147 nWink+=nSA/2;
3148 nWink/=nSA;
3149 nWink*=nSA;
3150 BigInt a2(nNeuRad);
3151 a2*=BigInt(nWink);
3152 a2/=BigInt(nWink0);
3153 nNeuRad=long(a2);
3155 if (bVertical)
3156 aNeuCenter.X()=aStart.X()+nNeuRad;
3157 else
3158 aNeuCenter.Y()=aStart.Y()+nNeuRad;
3163 if (nWink==0 || nNeuRad==0)
3164 bValid=false;
3166 if (!bValid)
3167 nNeuRad=0;
3169 if (!bValid && bResize)
3171 long nMul=bVertical ? dy1 : dx1;
3173 if (bLft || bUpr)
3174 nMul=-nMul;
3176 long nDiv=nMarkSize;
3178 if (bAtCenter)
3180 nMul*=2;
3181 nMul=Abs(nMul);
3184 aNeuFact=Fraction(nMul,nDiv);
3187 if (aNeuCenter!=aCenter || bNeuContortion!=bContortion || aNeuFact!=aFact ||
3188 bNeuMoveOnly != getMoveOnly() || bNeuRotate!=bRotate || eNeuMode!=eMode)
3190 Hide();
3191 setMoveOnly(bNeuMoveOnly);
3192 bRotate=bNeuRotate;
3193 eMode=eNeuMode;
3194 bContortion=bNeuContortion;
3195 aCenter=aNeuCenter;
3196 aFact=aNeuFact;
3197 aRad=Point(nNeuRad,nNeuRad);
3198 bResize=aFact!=Fraction(1,1) && aFact.GetDenominator()!=0 && aFact.IsValid();
3199 DragStat().NextMove(aPnt);
3200 Show();
3205 void SdrDragCrook::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
3207 const bool bDoResize(aFact!=Fraction(1,1));
3208 const bool bDoCrook(aCenter!=aMarkCenter && aRad.X()!=0 && aRad.Y()!=0);
3210 if (bDoCrook || bDoResize)
3212 if (bDoResize)
3214 Fraction aFact1(1,1);
3216 if (bContortion)
3218 if (bVertical)
3220 rTarget.Resize(aCenter,aFact1,aFact);
3222 else
3224 rTarget.Resize(aCenter,aFact,aFact1);
3227 else
3229 Point aCtr0(rTarget.GetSnapRect().Center());
3230 Point aCtr1(aCtr0);
3232 if (bVertical)
3234 ResizePoint(aCtr1,aCenter,aFact1,aFact);
3236 else
3238 ResizePoint(aCtr1,aCenter,aFact,aFact1);
3241 Size aSiz(aCtr1.X()-aCtr0.X(),aCtr1.Y()-aCtr0.Y());
3243 rTarget.Move(aSiz);
3247 if (bDoCrook)
3249 const Rectangle aLocalMarkRect(getSdrDragView().GetMarkedObjRect());
3250 const bool bLocalRotate(!bContortion && eMode == SDRCROOK_ROTATE && getSdrDragView().IsRotateAllowed(false));
3252 getSdrDragView().ImpCrookObj(&rTarget,aCenter,aRad,eMode,bVertical,!bContortion,bLocalRotate,aLocalMarkRect);
3257 void SdrDragCrook::applyCurrentTransformationToPolyPolygon(basegfx::B2DPolyPolygon& rTarget)
3259 // use helper derived from old stuff
3260 _MovAllPoints(rTarget);
3263 bool SdrDragCrook::EndSdrDrag(bool bCopy)
3265 Hide();
3267 if (bResize && aFact==Fraction(1,1))
3268 bResize=false;
3270 const bool bUndo = getSdrDragView().IsUndoEnabled();
3272 bool bDoCrook=aCenter!=aMarkCenter && aRad.X()!=0 && aRad.Y()!=0;
3274 if (bDoCrook || bResize)
3276 if (bResize && bUndo)
3278 XubString aStr;
3279 ImpTakeDescriptionStr(!bContortion?STR_EditCrook:STR_EditCrookContortion,aStr);
3281 if (bCopy)
3282 aStr+=ImpGetResStr(STR_EditWithCopy);
3284 getSdrDragView().BegUndo(aStr);
3287 if (bResize)
3289 Fraction aFact1(1,1);
3291 if (bContortion)
3293 if (bVertical)
3294 getSdrDragView().ResizeMarkedObj(aCenter,aFact1,aFact,bCopy);
3295 else
3296 getSdrDragView().ResizeMarkedObj(aCenter,aFact,aFact1,bCopy);
3298 else
3300 if (bCopy)
3301 getSdrDragView().CopyMarkedObj();
3303 ULONG nMarkAnz=getSdrDragView().GetMarkedObjectList().GetMarkCount();
3305 for (ULONG nm=0; nm<nMarkAnz; nm++)
3307 SdrMark* pM=getSdrDragView().GetMarkedObjectList().GetMark(nm);
3308 SdrObject* pO=pM->GetMarkedSdrObj();
3309 Point aCtr0(pO->GetSnapRect().Center());
3310 Point aCtr1(aCtr0);
3312 if (bVertical)
3313 ResizePoint(aCtr1,aCenter,aFact1,aFact);
3314 else
3315 ResizePoint(aCtr1,aCenter,aFact,aFact1);
3317 Size aSiz(aCtr1.X()-aCtr0.X(),aCtr1.Y()-aCtr0.Y());
3318 if( bUndo )
3319 AddUndo(getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoMoveObject(*pO,aSiz));
3320 pO->Move(aSiz);
3324 bCopy=false;
3327 if (bDoCrook)
3329 getSdrDragView().CrookMarkedObj(aCenter,aRad,eMode,bVertical,!bContortion,bCopy);
3330 getSdrDragView().SetLastCrookCenter(aCenter);
3333 if (bResize && bUndo)
3334 getSdrDragView().EndUndo();
3336 return true;
3339 return false;
3342 Pointer SdrDragCrook::GetSdrDragPointer() const
3344 return Pointer(POINTER_CROOK);
3347 ////////////////////////////////////////////////////////////////////////////////////////////////////
3349 TYPEINIT1(SdrDragDistort,SdrDragMethod);
3351 SdrDragDistort::SdrDragDistort(SdrDragView& rNewView)
3352 : SdrDragMethod(rNewView),
3353 nPolyPt(0),
3354 bContortionAllowed(false),
3355 bNoContortionAllowed(false),
3356 bContortion(false)
3360 void SdrDragDistort::TakeSdrDragComment(XubString& rStr) const
3362 ImpTakeDescriptionStr(STR_DragMethDistort, rStr);
3364 XubString aStr;
3366 rStr.AppendAscii(" (x=");
3367 getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDX(), aStr);
3368 rStr += aStr;
3369 rStr.AppendAscii(" y=");
3370 getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDY(), aStr);
3371 rStr += aStr;
3372 rStr += sal_Unicode(')');
3374 if(getSdrDragView().IsDragWithCopy())
3375 rStr += ImpGetResStr(STR_EditWithCopy);
3378 void SdrDragDistort::createSdrDragEntries()
3380 // Add extended frame raster first, so it will be behind objects
3381 if(getSdrDragView().GetSdrPageView())
3383 const basegfx::B2DPolyPolygon aDragRaster(impCreateDragRaster(*getSdrDragView().GetSdrPageView(), GetMarkedRect()));
3385 if(aDragRaster.count())
3387 addSdrDragEntry(new SdrDragEntryPolyPolygon(aDragRaster));
3391 // call parent
3392 SdrDragMethod::createSdrDragEntries();
3395 bool SdrDragDistort::BeginSdrDrag()
3397 bContortionAllowed=getSdrDragView().IsDistortAllowed(false);
3398 bNoContortionAllowed=getSdrDragView().IsDistortAllowed(true);
3400 if (bContortionAllowed || bNoContortionAllowed)
3402 SdrHdlKind eKind=GetDragHdlKind();
3403 nPolyPt=0xFFFF;
3405 if (eKind==HDL_UPLFT) nPolyPt=0;
3406 if (eKind==HDL_UPRGT) nPolyPt=1;
3407 if (eKind==HDL_LWRGT) nPolyPt=2;
3408 if (eKind==HDL_LWLFT) nPolyPt=3;
3409 if (nPolyPt>3) return false;
3411 aMarkRect=GetMarkedRect();
3412 aDistortedRect=XPolygon(aMarkRect);
3413 Show();
3414 return true;
3416 else
3418 return false;
3422 void SdrDragDistort::_MovAllPoints(basegfx::B2DPolyPolygon& rTarget)
3424 if (bContortion)
3426 SdrPageView* pPV = getSdrDragView().GetSdrPageView();
3428 if(pPV)
3430 if (pPV->HasMarkedObjPageView())
3432 basegfx::B2DPolyPolygon aDragPolygon(rTarget);
3433 const basegfx::B2DRange aOriginalRange(aMarkRect.Left(), aMarkRect.Top(), aMarkRect.Right(), aMarkRect.Bottom());
3434 const basegfx::B2DPoint aTopLeft(aDistortedRect[0].X(), aDistortedRect[0].Y());
3435 const basegfx::B2DPoint aTopRight(aDistortedRect[1].X(), aDistortedRect[1].Y());
3436 const basegfx::B2DPoint aBottomLeft(aDistortedRect[3].X(), aDistortedRect[3].Y());
3437 const basegfx::B2DPoint aBottomRight(aDistortedRect[2].X(), aDistortedRect[2].Y());
3439 aDragPolygon = basegfx::tools::distort(aDragPolygon, aOriginalRange, aTopLeft, aTopRight, aBottomLeft, aBottomRight);
3440 rTarget = aDragPolygon;
3446 void SdrDragDistort::MoveSdrDrag(const Point& rPnt)
3448 if (DragStat().CheckMinMoved(rPnt))
3450 Point aPnt(GetSnapPos(rPnt));
3452 if (getSdrDragView().IsOrtho())
3453 OrthoDistance8(DragStat().GetStart(),aPnt,getSdrDragView().IsBigOrtho());
3455 bool bNeuContortion=(bContortionAllowed && !getSdrDragView().IsCrookNoContortion()) || !bNoContortionAllowed;
3457 if (bNeuContortion!=bContortion || aDistortedRect[nPolyPt]!=aPnt)
3459 Hide();
3460 aDistortedRect[nPolyPt]=aPnt;
3461 bContortion=bNeuContortion;
3462 DragStat().NextMove(aPnt);
3463 Show();
3468 bool SdrDragDistort::EndSdrDrag(bool bCopy)
3470 Hide();
3471 bool bDoDistort=DragStat().GetDX()!=0 || DragStat().GetDY()!=0;
3473 if (bDoDistort)
3475 getSdrDragView().DistortMarkedObj(aMarkRect,aDistortedRect,!bContortion,bCopy);
3476 return true;
3479 return false;
3482 Pointer SdrDragDistort::GetSdrDragPointer() const
3484 return Pointer(POINTER_REFHAND);
3487 void SdrDragDistort::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
3489 const bool bDoDistort(DragStat().GetDX()!=0 || DragStat().GetDY()!=0);
3491 if (bDoDistort)
3493 getSdrDragView().ImpDistortObj(&rTarget, aMarkRect, aDistortedRect, !bContortion);
3497 void SdrDragDistort::applyCurrentTransformationToPolyPolygon(basegfx::B2DPolyPolygon& rTarget)
3499 // use helper derived from old stuff
3500 _MovAllPoints(rTarget);
3503 ////////////////////////////////////////////////////////////////////////////////////////////////////
3505 TYPEINIT1(SdrDragCrop,SdrDragResize);
3507 SdrDragCrop::SdrDragCrop(SdrDragView& rNewView)
3508 : SdrDragResize(rNewView)
3510 // switch off solid dragging for crop; it just makes no sense since showing
3511 // a 50% transparent object above the original will not be visible
3512 setSolidDraggingActive(false);
3515 void SdrDragCrop::TakeSdrDragComment(XubString& rStr) const
3517 ImpTakeDescriptionStr(STR_DragMethCrop, rStr);
3519 XubString aStr;
3521 rStr.AppendAscii(" (x=");
3522 getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDX(), aStr);
3523 rStr += aStr;
3524 rStr.AppendAscii(" y=");
3525 getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDY(), aStr);
3526 rStr += aStr;
3527 rStr += sal_Unicode(')');
3529 if(getSdrDragView().IsDragWithCopy())
3530 rStr += ImpGetResStr(STR_EditWithCopy);
3533 bool SdrDragCrop::EndSdrDrag(bool bCopy)
3535 Hide();
3537 if( DragStat().GetDX()==0 && DragStat().GetDY()==0 )
3538 return false;
3540 const SdrMarkList& rMarkList = getSdrDragView().GetMarkedObjectList();
3542 if( rMarkList.GetMarkCount() != 1 )
3543 return false;
3545 SdrGrafObj* pObj = dynamic_cast<SdrGrafObj*>( rMarkList.GetMark( 0 )->GetMarkedSdrObj() );
3547 if( !pObj || (pObj->GetGraphicType() == GRAPHIC_NONE) || (pObj->GetGraphicType() == GRAPHIC_DEFAULT) )
3548 return false;
3550 const GraphicObject& rGraphicObject = pObj->GetGraphicObject();
3551 const MapMode aMapMode100thmm(MAP_100TH_MM);
3552 Size aGraphicSize(rGraphicObject.GetPrefSize());
3554 if( MAP_PIXEL == rGraphicObject.GetPrefMapMode().GetMapUnit() )
3555 aGraphicSize = Application::GetDefaultDevice()->PixelToLogic( aGraphicSize, aMapMode100thmm );
3556 else
3557 aGraphicSize = Application::GetDefaultDevice()->LogicToLogic( aGraphicSize, rGraphicObject.GetPrefMapMode(), aMapMode100thmm);
3559 if( aGraphicSize.nA == 0 || aGraphicSize.nB == 0 )
3560 return false;
3562 const SdrGrafCropItem& rOldCrop = (const SdrGrafCropItem&)pObj->GetMergedItem(SDRATTR_GRAFCROP);
3564 const bool bUndo = getSdrDragView().IsUndoEnabled();
3566 if( bUndo )
3568 String aUndoStr;
3569 ImpTakeDescriptionStr(STR_DragMethCrop, aUndoStr);
3571 getSdrDragView().BegUndo( aUndoStr );
3572 getSdrDragView().AddUndo( getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoGeoObject( *pObj ) );
3575 Rectangle aOldRect( pObj->GetLogicRect() );
3576 getSdrDragView().ResizeMarkedObj(DragStat().Ref1(),aXFact,aYFact,bCopy);
3577 Rectangle aNewRect( pObj->GetLogicRect() );
3579 double fScaleX = ( aGraphicSize.Width() - rOldCrop.GetLeft() - rOldCrop.GetRight() ) / (double)aOldRect.GetWidth();
3580 double fScaleY = ( aGraphicSize.Height() - rOldCrop.GetTop() - rOldCrop.GetBottom() ) / (double)aOldRect.GetHeight();
3582 sal_Int32 nDiffLeft = aNewRect.nLeft - aOldRect.nLeft;
3583 sal_Int32 nDiffTop = aNewRect.nTop - aOldRect.nTop;
3584 sal_Int32 nDiffRight = aNewRect.nRight - aOldRect.nRight;
3585 sal_Int32 nDiffBottom = aNewRect.nBottom - aOldRect.nBottom;
3587 sal_Int32 nLeftCrop = static_cast<sal_Int32>( rOldCrop.GetLeft() + nDiffLeft * fScaleX );
3588 sal_Int32 nTopCrop = static_cast<sal_Int32>( rOldCrop.GetTop() + nDiffTop * fScaleY );
3589 sal_Int32 nRightCrop = static_cast<sal_Int32>( rOldCrop.GetRight() - nDiffRight * fScaleX );
3590 sal_Int32 nBottomCrop = static_cast<sal_Int32>( rOldCrop.GetBottom() - nDiffBottom * fScaleY );
3592 SfxItemPool& rPool = getSdrDragView().GetModel()->GetItemPool();
3593 SfxItemSet aSet( rPool, SDRATTR_GRAFCROP, SDRATTR_GRAFCROP );
3594 aSet.Put( SdrGrafCropItem( nLeftCrop, nTopCrop, nRightCrop, nBottomCrop ) );
3595 getSdrDragView().SetAttributes( aSet, false );
3597 if( bUndo )
3598 getSdrDragView().EndUndo();
3600 return true;
3603 Pointer SdrDragCrop::GetSdrDragPointer() const
3605 return Pointer(POINTER_CROP);
3608 ////////////////////////////////////////////////////////////////////////////////////////////////////
3609 // eof