1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "svddrgm1.hxx"
23 #include <tools/bigint.hxx>
24 #include <vcl/svapp.hxx>
25 #include "svx/xattr.hxx"
26 #include <svx/xpoly.hxx>
27 #include <svx/svdetc.hxx>
28 #include <svx/svdtrans.hxx>
29 #include <svx/svdundo.hxx>
30 #include <svx/svdmark.hxx>
31 #include <svx/svdocapt.hxx>
32 #include <svx/svdpagv.hxx>
33 #include "svx/svdstr.hrc" // names taken from the resource
34 #include "svx/svdglob.hxx" // StringCache
35 #include <svx/svddrgv.hxx>
36 #include <svx/svdograf.hxx>
37 #include <svx/dialogs.hrc>
38 #include <svx/dialmgr.hxx>
39 #include <svx/sdgcpitm.hxx>
40 #include <basegfx/polygon/b2dpolygon.hxx>
41 #include <basegfx/polygon/b2dpolygontools.hxx>
42 #include <svx/sdr/overlay/overlaypolypolygon.hxx>
43 #include <svx/sdr/overlay/overlaymanager.hxx>
44 #include <svx/sdr/overlay/overlayrollingrectangle.hxx>
45 #include <svx/sdrpagewindow.hxx>
46 #include <svx/sdrpaintwindow.hxx>
47 #include <basegfx/matrix/b2dhommatrix.hxx>
48 #include <basegfx/polygon/b2dpolypolygontools.hxx>
49 #include <svx/sdr/contact/viewobjectcontact.hxx>
50 #include <svx/sdr/contact/viewcontact.hxx>
51 #include <svx/sdr/contact/displayinfo.hxx>
52 #include <svx/sdr/overlay/overlayprimitive2dsequenceobject.hxx>
53 #include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx>
54 #include <svx/sdr/contact/objectcontact.hxx>
55 #include "svx/svditer.hxx"
56 #include <svx/svdopath.hxx>
57 #include <svx/polypolygoneditor.hxx>
58 #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
59 #include <drawinglayer/primitive2d/transformprimitive2d.hxx>
60 #include <drawinglayer/primitive2d/markerarrayprimitive2d.hxx>
61 #include <svx/sdr/primitive2d/sdrattributecreator.hxx>
62 #include <svx/sdr/primitive2d/sdrdecompositiontools.hxx>
63 #include <svx/svdoole2.hxx>
64 #include <svx/svdovirt.hxx>
65 #include <svx/svdouno.hxx>
66 #include <svx/sdr/primitive2d/sdrprimitivetools.hxx>
67 #include <basegfx/matrix/b2dhommatrixtools.hxx>
68 #include <drawinglayer/attribute/sdrlineattribute.hxx>
69 #include <drawinglayer/attribute/sdrlinestartendattribute.hxx>
73 ////////////////////////////////////////////////////////////////////////////////////////////////////
75 SdrDragEntry::SdrDragEntry()
76 : mbAddToTransparent(false)
80 SdrDragEntry::~SdrDragEntry()
84 ////////////////////////////////////////////////////////////////////////////////////////////////////
86 SdrDragEntryPolyPolygon::SdrDragEntryPolyPolygon(const basegfx::B2DPolyPolygon
& rOriginalPolyPolygon
)
88 maOriginalPolyPolygon(rOriginalPolyPolygon
)
92 SdrDragEntryPolyPolygon::~SdrDragEntryPolyPolygon()
96 drawinglayer::primitive2d::Primitive2DSequence
SdrDragEntryPolyPolygon::createPrimitive2DSequenceInCurrentState(SdrDragMethod
& rDragMethod
)
98 drawinglayer::primitive2d::Primitive2DSequence aRetval
;
100 if(maOriginalPolyPolygon
.count())
102 basegfx::B2DPolyPolygon
aCopy(maOriginalPolyPolygon
);
103 const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer
;
105 rDragMethod
.applyCurrentTransformationToPolyPolygon(aCopy
);
106 basegfx::BColor
aColA(aSvtOptionsDrawinglayer
.GetStripeColorA().getBColor());
107 basegfx::BColor
aColB(aSvtOptionsDrawinglayer
.GetStripeColorB().getBColor());
108 const double fStripeLength(aSvtOptionsDrawinglayer
.GetStripeLength());
110 if(Application::GetSettings().GetStyleSettings().GetHighContrastMode())
112 aColA
= aColB
= Application::GetSettings().GetStyleSettings().GetHighlightColor().getBColor();
116 drawinglayer::primitive2d::Primitive2DReference
aPolyPolygonMarkerPrimitive2D(
117 new drawinglayer::primitive2d::PolyPolygonMarkerPrimitive2D(aCopy
, aColA
, aColB
, fStripeLength
));
119 aRetval
= drawinglayer::primitive2d::Primitive2DSequence(&aPolyPolygonMarkerPrimitive2D
, 1);
125 ////////////////////////////////////////////////////////////////////////////////////////////////////
127 SdrDragEntrySdrObject::SdrDragEntrySdrObject(const SdrObject
& rOriginal
, sdr::contact::ObjectContact
& rObjectContact
, bool bModify
)
129 maOriginal(rOriginal
),
131 mrObjectContact(rObjectContact
),
134 // add SdrObject parts to transparent overlay stuff
135 setAddToTransparent(true);
138 SdrDragEntrySdrObject::~SdrDragEntrySdrObject()
142 SdrObject::Free(mpClone
);
146 void SdrDragEntrySdrObject::prepareCurrentState(SdrDragMethod
& rDragMethod
)
148 // for the moment, i need to re-create the clone in all cases. I need to figure
149 // out when clone and original have the same class, so that i can use operator=
154 SdrObject::Free(mpClone
);
162 mpClone
= maOriginal
.getFullDragClone();
165 // apply original transformation, implemented at the DragMethods
166 rDragMethod
.applyCurrentTransformationToSdrObject(*mpClone
);
170 drawinglayer::primitive2d::Primitive2DSequence
SdrDragEntrySdrObject::createPrimitive2DSequenceInCurrentState(SdrDragMethod
&)
172 const SdrObject
* pSource
= &maOriginal
;
174 if(mbModify
&& mpClone
)
176 // choose source for geometry data
180 // get VOC and Primitive2DSequence
181 sdr::contact::ViewContact
& rVC
= pSource
->GetViewContact();
182 sdr::contact::ViewObjectContact
& rVOC
= rVC
.GetViewObjectContact(mrObjectContact
);
183 sdr::contact::DisplayInfo aDisplayInfo
;
185 // Do not use the last ViewPort set at the OC from the last ProcessDisplay(),
186 // here we want the complete primitive sequence without visibility clippings
187 mrObjectContact
.resetViewPort();
189 return rVOC
.getPrimitive2DSequenceHierarchy(aDisplayInfo
);
192 ////////////////////////////////////////////////////////////////////////////////////////////////////
194 SdrDragEntryPrimitive2DSequence::SdrDragEntryPrimitive2DSequence(
195 const drawinglayer::primitive2d::Primitive2DSequence
& rSequence
,
196 bool bAddToTransparent
)
198 maPrimitive2DSequence(rSequence
)
200 // add parts to transparent overlay stuff if necessary
201 setAddToTransparent(bAddToTransparent
);
204 SdrDragEntryPrimitive2DSequence::~SdrDragEntryPrimitive2DSequence()
208 drawinglayer::primitive2d::Primitive2DSequence
SdrDragEntryPrimitive2DSequence::createPrimitive2DSequenceInCurrentState(SdrDragMethod
& rDragMethod
)
210 drawinglayer::primitive2d::Primitive2DReference
aTransformPrimitive2D(
211 new drawinglayer::primitive2d::TransformPrimitive2D(
212 rDragMethod
.getCurrentTransformation(),
213 maPrimitive2DSequence
));
215 return drawinglayer::primitive2d::Primitive2DSequence(&aTransformPrimitive2D
, 1);
218 ////////////////////////////////////////////////////////////////////////////////////////////////////
220 SdrDragEntryPointGlueDrag::SdrDragEntryPointGlueDrag(const std::vector
< basegfx::B2DPoint
>& rPositions
, bool bIsPointDrag
)
221 : maPositions(rPositions
),
222 mbIsPointDrag(bIsPointDrag
)
224 // add SdrObject parts to transparent overlay stuff
225 setAddToTransparent(true);
228 SdrDragEntryPointGlueDrag::~SdrDragEntryPointGlueDrag()
232 drawinglayer::primitive2d::Primitive2DSequence
SdrDragEntryPointGlueDrag::createPrimitive2DSequenceInCurrentState(SdrDragMethod
& rDragMethod
)
234 drawinglayer::primitive2d::Primitive2DSequence aRetval
;
236 if(!maPositions
.empty())
238 basegfx::B2DPolygon aPolygon
;
241 for(a
= 0; a
< maPositions
.size(); a
++)
243 aPolygon
.append(maPositions
[a
]);
246 basegfx::B2DPolyPolygon
aPolyPolygon(aPolygon
);
248 rDragMethod
.applyCurrentTransformationToPolyPolygon(aPolyPolygon
);
250 const basegfx::B2DPolygon
aTransformed(aPolyPolygon
.getB2DPolygon(0));
251 std::vector
< basegfx::B2DPoint
> aTransformedPositions
;
253 aTransformedPositions
.reserve(aTransformed
.count());
255 for(a
= 0; a
< aTransformed
.count(); a
++)
257 aTransformedPositions
.push_back(aTransformed
.getB2DPoint(a
));
262 const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer
;
263 basegfx::BColor
aColor(aSvtOptionsDrawinglayer
.GetStripeColorA().getBColor());
265 if(Application::GetSettings().GetStyleSettings().GetHighContrastMode())
267 aColor
= Application::GetSettings().GetStyleSettings().GetHighlightColor().getBColor();
270 drawinglayer::primitive2d::Primitive2DReference
aMarkerArrayPrimitive2D(
271 new drawinglayer::primitive2d::MarkerArrayPrimitive2D(aTransformedPositions
,
272 drawinglayer::primitive2d::createDefaultCross_3x3(aColor
)));
274 aRetval
= drawinglayer::primitive2d::Primitive2DSequence(&aMarkerArrayPrimitive2D
, 1);
278 drawinglayer::primitive2d::Primitive2DReference
aMarkerArrayPrimitive2D(
279 new drawinglayer::primitive2d::MarkerArrayPrimitive2D(aTransformedPositions
,
280 SdrHdl::createGluePointBitmap()));
281 aRetval
= drawinglayer::primitive2d::Primitive2DSequence(&aMarkerArrayPrimitive2D
, 1);
288 ////////////////////////////////////////////////////////////////////////////////////////////////////
290 TYPEINIT0(SdrDragMethod
);
292 void SdrDragMethod::resetSdrDragEntries()
294 // clear entries; creation is on demand
295 clearSdrDragEntries();
298 basegfx::B2DRange
SdrDragMethod::getCurrentRange() const
300 return getB2DRangeFromOverlayObjectList();
303 void SdrDragMethod::clearSdrDragEntries()
305 for(sal_uInt32
a(0); a
< maSdrDragEntries
.size(); a
++)
307 delete maSdrDragEntries
[a
];
310 maSdrDragEntries
.clear();
313 void SdrDragMethod::addSdrDragEntry(SdrDragEntry
* pNew
)
317 maSdrDragEntries
.push_back(pNew
);
321 void SdrDragMethod::createSdrDragEntries()
323 if(getSdrDragView().GetSdrPageView() && getSdrDragView().GetSdrPageView()->HasMarkedObjPageView())
325 if(getSdrDragView().IsDraggingPoints())
327 createSdrDragEntries_PointDrag();
329 else if(getSdrDragView().IsDraggingGluePoints())
331 createSdrDragEntries_GlueDrag();
335 if(getSolidDraggingActive())
337 createSdrDragEntries_SolidDrag();
341 createSdrDragEntries_PolygonDrag();
347 void SdrDragMethod::createSdrDragEntryForSdrObject(const SdrObject
& rOriginal
, sdr::contact::ObjectContact
& rObjectContact
, bool bModify
)
349 // add full object drag; Clone() at the object has to work
351 addSdrDragEntry(new SdrDragEntrySdrObject(rOriginal
, rObjectContact
, bModify
));
354 void SdrDragMethod::createSdrDragEntries_SolidDrag()
356 const sal_uInt32
nMarkAnz(getSdrDragView().GetMarkedObjectCount());
357 SdrPageView
* pPV
= getSdrDragView().GetSdrPageView();
361 for(sal_uInt32
a(0); a
< nMarkAnz
; a
++)
363 SdrMark
* pM
= getSdrDragView().GetSdrMarkByIndex(a
);
365 if(pM
->GetPageView() == pPV
)
367 const SdrObject
* pObject
= pM
->GetMarkedSdrObj();
371 if(pPV
->PageWindowCount())
373 sdr::contact::ObjectContact
& rOC
= pPV
->GetPageWindow(0)->GetObjectContact();
374 SdrObjListIter
aIter(*pObject
);
376 while(aIter
.IsMore())
378 SdrObject
* pCandidate
= aIter
.Next();
382 const bool bSuppressFullDrag(!pCandidate
->supportsFullDrag());
383 bool bAddWireframe(bSuppressFullDrag
);
385 if(!bAddWireframe
&& !pCandidate
->HasLineStyle())
387 // add wireframe for objects without outline
388 bAddWireframe
= true;
391 if(!bSuppressFullDrag
)
393 // add full object drag; Clone() at the object has to work
395 createSdrDragEntryForSdrObject(*pCandidate
, rOC
, true);
400 // when dragging a 50% transparent copy of a filled or not filled object without
401 // outline, this is normally hard to see. Add extra wireframe in that case. This
402 // works nice e.g. with text frames etc.
403 addSdrDragEntry(new SdrDragEntryPolyPolygon(pCandidate
->TakeXorPoly()));
414 void SdrDragMethod::createSdrDragEntries_PolygonDrag()
416 const sal_uInt32
nMarkAnz(getSdrDragView().GetMarkedObjectCount());
417 bool bNoPolygons(getSdrDragView().IsNoDragXorPolys() || nMarkAnz
> getSdrDragView().GetDragXorPolyLimit());
418 basegfx::B2DPolyPolygon aResult
;
419 sal_uInt32
nPointCount(0);
421 for(sal_uInt32
a(0); !bNoPolygons
&& a
< nMarkAnz
; a
++)
423 SdrMark
* pM
= getSdrDragView().GetSdrMarkByIndex(a
);
425 if(pM
->GetPageView() == getSdrDragView().GetSdrPageView())
427 const basegfx::B2DPolyPolygon
aNewPolyPolygon(pM
->GetMarkedSdrObj()->TakeXorPoly());
429 for(sal_uInt32
b(0); b
< aNewPolyPolygon
.count(); b
++)
431 nPointCount
+= aNewPolyPolygon
.getB2DPolygon(b
).count();
434 if(nPointCount
> getSdrDragView().GetDragXorPointLimit())
441 aResult
.append(aNewPolyPolygon
);
448 const Rectangle
aR(getSdrDragView().GetSdrPageView()->MarkSnap());
449 const basegfx::B2DRange
aNewRectangle(aR
.Left(), aR
.Top(), aR
.Right(), aR
.Bottom());
450 basegfx::B2DPolygon
aNewPolygon(basegfx::tools::createPolygonFromRect(aNewRectangle
));
452 aResult
= basegfx::B2DPolyPolygon(basegfx::tools::expandToCurve(aNewPolygon
));
457 addSdrDragEntry(new SdrDragEntryPolyPolygon(aResult
));
461 void SdrDragMethod::createSdrDragEntries_PointDrag()
463 const sal_uInt32
nMarkAnz(getSdrDragView().GetMarkedObjectCount());
464 std::vector
< basegfx::B2DPoint
> aPositions
;
466 for(sal_uInt32
nm(0); nm
< nMarkAnz
; nm
++)
468 SdrMark
* pM
= getSdrDragView().GetSdrMarkByIndex(nm
);
470 if(pM
->GetPageView() == getSdrDragView().GetSdrPageView())
472 const SdrUShortCont
* pPts
= pM
->GetMarkedPoints();
474 if(pPts
&& !pPts
->empty())
476 const SdrObject
* pObj
= pM
->GetMarkedSdrObj();
477 const SdrPathObj
* pPath
= dynamic_cast< const SdrPathObj
* >(pObj
);
481 const basegfx::B2DPolyPolygon aPathXPP
= pPath
->GetPathPoly();
485 for(SdrUShortCont::const_iterator it
= pPts
->begin(); it
!= pPts
->end(); ++it
)
487 sal_uInt32 nPolyNum
, nPointNum
;
488 const sal_uInt16 nObjPt
= *it
;
490 if(sdr::PolyPolygonEditor::GetRelativePolyPoint(aPathXPP
, nObjPt
, nPolyNum
, nPointNum
))
492 aPositions
.push_back(aPathXPP
.getB2DPolygon(nPolyNum
).getB2DPoint(nPointNum
));
501 if(!aPositions
.empty())
503 addSdrDragEntry(new SdrDragEntryPointGlueDrag(aPositions
, true));
507 void SdrDragMethod::createSdrDragEntries_GlueDrag()
509 const sal_uInt32
nMarkAnz(getSdrDragView().GetMarkedObjectCount());
510 std::vector
< basegfx::B2DPoint
> aPositions
;
512 for(sal_uInt32
nm(0); nm
< nMarkAnz
; nm
++)
514 SdrMark
* pM
= getSdrDragView().GetSdrMarkByIndex(nm
);
516 if(pM
->GetPageView() == getSdrDragView().GetSdrPageView())
518 const SdrUShortCont
* pPts
= pM
->GetMarkedGluePoints();
520 if(pPts
&& !pPts
->empty())
522 const SdrObject
* pObj
= pM
->GetMarkedSdrObj();
523 const SdrGluePointList
* pGPL
= pObj
->GetGluePointList();
527 for(SdrUShortCont::const_iterator it
= pPts
->begin(); it
!= pPts
->end(); ++it
)
529 const sal_uInt16 nObjPt
= *it
;
530 const sal_uInt16
nGlueNum(pGPL
->FindGluePoint(nObjPt
));
532 if(SDRGLUEPOINT_NOTFOUND
!= nGlueNum
)
534 const Point
aPoint((*pGPL
)[nGlueNum
].GetAbsolutePos(*pObj
));
535 aPositions
.push_back(basegfx::B2DPoint(aPoint
.X(), aPoint
.Y()));
543 if(!aPositions
.empty())
545 addSdrDragEntry(new SdrDragEntryPointGlueDrag(aPositions
, false));
549 void SdrDragMethod::ImpTakeDescriptionStr(sal_uInt16 nStrCacheID
, XubString
& rStr
, sal_uInt16 nVal
) const
552 if (IsDraggingPoints()) {
553 nOpt
=IMPSDR_POINTSDESCRIPTION
;
554 } else if (IsDraggingGluePoints()) {
555 nOpt
=IMPSDR_GLUEPOINTSDESCRIPTION
;
557 getSdrDragView().ImpTakeDescriptionStr(nStrCacheID
,rStr
,nVal
,nOpt
);
560 SdrObject
* SdrDragMethod::GetDragObj() const
562 SdrObject
* pObj
=NULL
;
563 if (getSdrDragView().pDragHdl
!=NULL
) pObj
=getSdrDragView().pDragHdl
->GetObj();
564 if (pObj
==NULL
) pObj
=getSdrDragView().pMarkedObj
;
568 SdrPageView
* SdrDragMethod::GetDragPV() const
570 SdrPageView
* pPV
=NULL
;
571 if (getSdrDragView().pDragHdl
!=NULL
) pPV
=getSdrDragView().pDragHdl
->GetPageView();
572 if (pPV
==NULL
) pPV
=getSdrDragView().pMarkedPV
;
576 void SdrDragMethod::applyCurrentTransformationToSdrObject(SdrObject
& rTarget
)
578 // the original applies the transformation using TRGetBaseGeometry/TRSetBaseGeometry.
579 // Later this should be the only needed one for linear transforms (not for SdrDragCrook and
580 // SdrDragDistort, those are NOT linear). Currently, this can not yet be used since the
581 // special handling of rotate/mirror due to the not-being-able to handle it in the old
582 // drawinglayer stuff. Text would currently not correctly be mirrored in the preview.
583 basegfx::B2DHomMatrix aObjectTransform
;
584 basegfx::B2DPolyPolygon aObjectPolyPolygon
;
585 bool bPolyUsed(rTarget
.TRGetBaseGeometry(aObjectTransform
, aObjectPolyPolygon
));
587 // apply transform to object transform
588 aObjectTransform
*= getCurrentTransformation();
592 // do something special since the object size is in the polygon
593 // break up matrix to get the scale
594 basegfx::B2DTuple aScale
;
595 basegfx::B2DTuple aTranslate
;
596 double fRotate
, fShearX
;
597 aObjectTransform
.decompose(aScale
, aTranslate
, fRotate
, fShearX
);
599 // get polygon's position and size
600 const basegfx::B2DRange
aPolyRange(aObjectPolyPolygon
.getB2DRange());
602 // get the scaling factors (do not mirror, this is in the object transformation)
603 const double fScaleX(fabs(aScale
.getX()) / (basegfx::fTools::equalZero(aPolyRange
.getWidth()) ? 1.0 : aPolyRange
.getWidth()));
604 const double fScaleY(fabs(aScale
.getY()) / (basegfx::fTools::equalZero(aPolyRange
.getHeight()) ? 1.0 : aPolyRange
.getHeight()));
606 // prepare transform matrix for polygon
607 basegfx::B2DHomMatrix
aPolyTransform(basegfx::tools::createTranslateB2DHomMatrix(
608 -aPolyRange
.getMinX(), -aPolyRange
.getMinY()));
609 aPolyTransform
.scale(fScaleX
, fScaleY
);
611 // transform the polygon
612 aObjectPolyPolygon
.transform(aPolyTransform
);
615 rTarget
.TRSetBaseGeometry(getCurrentTransformation() * aObjectTransform
, aObjectPolyPolygon
);
618 void SdrDragMethod::applyCurrentTransformationToPolyPolygon(basegfx::B2DPolyPolygon
& rTarget
)
620 // original uses CurrentTransformation
621 rTarget
.transform(getCurrentTransformation());
624 SdrDragMethod::SdrDragMethod(SdrDragView
& rNewView
)
625 : maSdrDragEntries(),
626 maOverlayObjectList(),
627 mrSdrDragView(rNewView
),
629 mbSolidDraggingActive(getSdrDragView().IsSolidDragging())
631 if(mbSolidDraggingActive
&& Application::GetSettings().GetStyleSettings().GetHighContrastMode())
633 // fallback to wireframe when high contrast is used
634 mbSolidDraggingActive
= false;
638 SdrDragMethod::~SdrDragMethod()
640 clearSdrDragEntries();
643 void SdrDragMethod::Show()
645 getSdrDragView().ShowDragObj();
648 void SdrDragMethod::Hide()
650 getSdrDragView().HideDragObj();
653 basegfx::B2DHomMatrix
SdrDragMethod::getCurrentTransformation()
655 return basegfx::B2DHomMatrix();
658 void SdrDragMethod::CancelSdrDrag()
663 struct compareConstSdrObjectRefs
665 bool operator()(const SdrObject
* p1
, const SdrObject
* p2
) const
671 typedef std::map
< const SdrObject
*, SdrObject
*, compareConstSdrObjectRefs
> SdrObjectAndCloneMap
;
673 void SdrDragMethod::CreateOverlayGeometry(sdr::overlay::OverlayManager
& rOverlayManager
)
675 // create SdrDragEntries on demand
676 if(maSdrDragEntries
.empty())
678 createSdrDragEntries();
681 // if there are entries, derive OverlayObjects from the entries, including
682 // modification from current interactive state
683 if(!maSdrDragEntries
.empty())
685 // #i54102# SdrDragEntrySdrObject creates clones of SdrObjects as base for creating the needed
686 // primitives, holding the original and the clone. If connectors (Edges) are involved,
687 // the cloned connectors need to be connected to the cloned SdrObjects (after cloning
688 // they are connected to the original SdrObjects). To do so, trigger the preparation
689 // steps for SdrDragEntrySdrObject, save an association of (orig, clone) in a helper
690 // and evtl. remember if it was an edge
691 SdrObjectAndCloneMap aOriginalAndClones
;
692 std::vector
< SdrEdgeObj
* > aEdges
;
695 // #i54102# execute prepareCurrentState for all SdrDragEntrySdrObject, register pair of original and
696 // clone, remember edges
697 for(a
= 0; a
< maSdrDragEntries
.size(); a
++)
699 SdrDragEntrySdrObject
* pSdrDragEntrySdrObject
= dynamic_cast< SdrDragEntrySdrObject
*>(maSdrDragEntries
[a
]);
701 if(pSdrDragEntrySdrObject
)
703 pSdrDragEntrySdrObject
->prepareCurrentState(*this);
705 SdrEdgeObj
* pSdrEdgeObj
= dynamic_cast< SdrEdgeObj
* >(pSdrDragEntrySdrObject
->getClone());
709 aEdges
.push_back(pSdrEdgeObj
);
712 if(pSdrDragEntrySdrObject
->getClone())
714 aOriginalAndClones
[&pSdrDragEntrySdrObject
->getOriginal()] = pSdrDragEntrySdrObject
->getClone();
719 // #i54102# if there are edges, reconnect their ends to the corresponding clones (if found)
722 for(a
= 0; a
< aEdges
.size(); a
++)
724 SdrEdgeObj
* pSdrEdgeObj
= aEdges
[a
];
725 SdrObject
* pConnectedTo
= pSdrEdgeObj
->GetConnectedNode(true);
729 SdrObjectAndCloneMap::iterator aEntry
= aOriginalAndClones
.find(pConnectedTo
);
731 if(aEntry
!= aOriginalAndClones
.end())
733 pSdrEdgeObj
->ConnectToNode(true, aEntry
->second
);
737 pConnectedTo
= pSdrEdgeObj
->GetConnectedNode(false);
741 SdrObjectAndCloneMap::iterator aEntry
= aOriginalAndClones
.find(pConnectedTo
);
743 if(aEntry
!= aOriginalAndClones
.end())
745 pSdrEdgeObj
->ConnectToNode(false, aEntry
->second
);
751 // collect primitives for visualisation
752 drawinglayer::primitive2d::Primitive2DSequence aResult
;
753 drawinglayer::primitive2d::Primitive2DSequence aResultTransparent
;
755 for(a
= 0; a
< maSdrDragEntries
.size(); a
++)
757 SdrDragEntry
* pCandidate
= maSdrDragEntries
[a
];
761 const drawinglayer::primitive2d::Primitive2DSequence
aCandidateResult(pCandidate
->createPrimitive2DSequenceInCurrentState(*this));
763 if(aCandidateResult
.hasElements())
765 if(pCandidate
->getAddToTransparent())
767 drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(aResultTransparent
, aCandidateResult
);
771 drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(aResult
, aCandidateResult
);
777 if(DoAddConnectorOverlays())
779 const drawinglayer::primitive2d::Primitive2DSequence
aConnectorOverlays(AddConnectorOverlays());
781 if(aConnectorOverlays
.hasElements())
783 // add connector overlays to transparent part
784 drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(aResultTransparent
, aConnectorOverlays
);
788 if(aResult
.hasElements())
790 sdr::overlay::OverlayObject
* pNewOverlayObject
= new sdr::overlay::OverlayPrimitive2DSequenceObject(aResult
);
791 rOverlayManager
.add(*pNewOverlayObject
);
792 addToOverlayObjectList(*pNewOverlayObject
);
795 if(aResultTransparent
.hasElements())
797 drawinglayer::primitive2d::Primitive2DReference
aUnifiedTransparencePrimitive2D(new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(aResultTransparent
, 0.5));
798 aResultTransparent
= drawinglayer::primitive2d::Primitive2DSequence(&aUnifiedTransparencePrimitive2D
, 1);
800 sdr::overlay::OverlayObject
* pNewOverlayObject
= new sdr::overlay::OverlayPrimitive2DSequenceObject(aResultTransparent
);
801 rOverlayManager
.add(*pNewOverlayObject
);
802 addToOverlayObjectList(*pNewOverlayObject
);
806 // add DragStripes if necessary (help lines cross the page when dragging)
807 if(getSdrDragView().IsDragStripes())
809 Rectangle aActionRectangle
;
810 getSdrDragView().TakeActionRect(aActionRectangle
);
812 const basegfx::B2DPoint
aTopLeft(aActionRectangle
.Left(), aActionRectangle
.Top());
813 const basegfx::B2DPoint
aBottomRight(aActionRectangle
.Right(), aActionRectangle
.Bottom());
814 sdr::overlay::OverlayRollingRectangleStriped
* pNew
= new sdr::overlay::OverlayRollingRectangleStriped(
815 aTopLeft
, aBottomRight
, true, false);
817 rOverlayManager
.add(*pNew
);
818 addToOverlayObjectList(*pNew
);
822 void SdrDragMethod::destroyOverlayGeometry()
824 clearOverlayObjectList();
827 bool SdrDragMethod::DoAddConnectorOverlays()
829 // these conditions are translated from SdrDragView::ImpDrawEdgeXor
830 const SdrMarkList
& rMarkedNodes
= getSdrDragView().GetEdgesOfMarkedNodes();
832 if(!rMarkedNodes
.GetMarkCount())
837 if(!getSdrDragView().IsRubberEdgeDragging() && !getSdrDragView().IsDetailedEdgeDragging())
842 if(getSdrDragView().IsDraggingPoints() || getSdrDragView().IsDraggingGluePoints())
847 if(!getMoveOnly() && !(
848 IS_TYPE(SdrDragMove
, this) || IS_TYPE(SdrDragResize
, this) ||
849 IS_TYPE(SdrDragRotate
,this) || IS_TYPE(SdrDragMirror
,this)))
854 const bool bDetail(getSdrDragView().IsDetailedEdgeDragging() && getMoveOnly());
856 if(!bDetail
&& !getSdrDragView().IsRubberEdgeDragging())
861 // one more migrated from SdrEdgeObj::NspToggleEdgeXor
862 if(IS_TYPE(SdrDragObjOwn
, this) || IS_TYPE(SdrDragMovHdl
, this))
870 drawinglayer::primitive2d::Primitive2DSequence
SdrDragMethod::AddConnectorOverlays()
872 drawinglayer::primitive2d::Primitive2DSequence aRetval
;
873 const bool bDetail(getSdrDragView().IsDetailedEdgeDragging() && getMoveOnly());
874 const SdrMarkList
& rMarkedNodes
= getSdrDragView().GetEdgesOfMarkedNodes();
876 for(sal_uInt16
a(0); a
< rMarkedNodes
.GetMarkCount(); a
++)
878 SdrMark
* pEM
= rMarkedNodes
.GetMark(a
);
880 if(pEM
&& pEM
->GetMarkedSdrObj())
882 SdrEdgeObj
* pEdge
= dynamic_cast< SdrEdgeObj
* >(pEM
->GetMarkedSdrObj());
886 const basegfx::B2DPolygon
aEdgePolygon(pEdge
->ImplAddConnectorOverlay(*this, pEM
->IsCon1(), pEM
->IsCon2(), bDetail
));
888 if(aEdgePolygon
.count())
890 // this polygon is a temporary calculated connector path, so it is not possible to fetch
891 // the needed primitives directly from the pEdge object which does not get changed. If full
892 // drag is on, use the SdrObjects ItemSet to create a adequate representation
893 bool bUseSolidDragging(getSolidDraggingActive());
895 if(bUseSolidDragging
)
897 // switch off solid dragging if connector is not visible
898 if(!pEdge
->HasLineStyle())
900 bUseSolidDragging
= false;
904 if(bUseSolidDragging
)
906 const SfxItemSet
& rItemSet
= pEdge
->GetMergedItemSet();
907 const drawinglayer::attribute::SdrLineAttribute
aLine(
908 drawinglayer::primitive2d::createNewSdrLineAttribute(rItemSet
));
910 if(!aLine
.isDefault())
912 const drawinglayer::attribute::SdrLineStartEndAttribute
aLineStartEnd(
913 drawinglayer::primitive2d::createNewSdrLineStartEndAttribute(
917 drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(
918 aRetval
, drawinglayer::primitive2d::createPolygonLinePrimitive(
920 basegfx::B2DHomMatrix(),
927 const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer
;
928 basegfx::BColor
aColA(aSvtOptionsDrawinglayer
.GetStripeColorA().getBColor());
929 basegfx::BColor
aColB(aSvtOptionsDrawinglayer
.GetStripeColorB().getBColor());
930 const double fStripeLength(aSvtOptionsDrawinglayer
.GetStripeLength());
932 if(Application::GetSettings().GetStyleSettings().GetHighContrastMode())
934 aColA
= aColB
= Application::GetSettings().GetStyleSettings().GetHighlightColor().getBColor();
938 drawinglayer::primitive2d::Primitive2DReference
aPolyPolygonMarkerPrimitive2D(
939 new drawinglayer::primitive2d::PolyPolygonMarkerPrimitive2D(
940 basegfx::B2DPolyPolygon(aEdgePolygon
), aColA
, aColB
, fStripeLength
));
941 drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(aRetval
, aPolyPolygonMarkerPrimitive2D
);
951 ////////////////////////////////////////////////////////////////////////////////////////////////////
953 TYPEINIT1(SdrDragMovHdl
,SdrDragMethod
);
955 SdrDragMovHdl::SdrDragMovHdl(SdrDragView
& rNewView
)
956 : SdrDragMethod(rNewView
)
960 void SdrDragMovHdl::createSdrDragEntries()
962 // SdrDragMovHdl does not use the default drags,
963 // but creates nothing
966 void SdrDragMovHdl::TakeSdrDragComment(XubString
& rStr
) const
968 rStr
=ImpGetResStr(STR_DragMethMovHdl
);
969 if (getSdrDragView().IsDragWithCopy()) rStr
+=ImpGetResStr(STR_EditWithCopy
);
972 bool SdrDragMovHdl::BeginSdrDrag()
977 DragStat().Ref1()=GetDragHdl()->GetPos();
978 DragStat().SetShown(!DragStat().IsShown());
979 SdrHdlKind eKind
=GetDragHdl()->GetKind();
980 SdrHdl
* pH1
=GetHdlList().GetHdl(HDL_REF1
);
981 SdrHdl
* pH2
=GetHdlList().GetHdl(HDL_REF2
);
985 if (pH1
==NULL
|| pH2
==NULL
)
987 OSL_FAIL("SdrDragMovHdl::BeginSdrDrag(): Moving the axis of reflection: reference handles not found.");
991 DragStat().SetActionRect(Rectangle(pH1
->GetPos(),pH2
->GetPos()));
995 Point
aPt(GetDragHdl()->GetPos());
996 DragStat().SetActionRect(Rectangle(aPt
,aPt
));
1002 void SdrDragMovHdl::MoveSdrDrag(const Point
& rNoSnapPnt
)
1004 Point
aPnt(rNoSnapPnt
);
1006 if ( GetDragHdl() && DragStat().CheckMinMoved(rNoSnapPnt
))
1008 if (GetDragHdl()->GetKind()==HDL_MIRX
)
1010 SdrHdl
* pH1
=GetHdlList().GetHdl(HDL_REF1
);
1011 SdrHdl
* pH2
=GetHdlList().GetHdl(HDL_REF2
);
1013 if (pH1
==NULL
|| pH2
==NULL
)
1016 if (!DragStat().IsNoSnap())
1020 bool bXSnapped
=false;
1021 bool bYSnapped
=false;
1022 Point
aDif(aPnt
-DragStat().GetStart());
1023 getSdrDragView().CheckSnap(Ref1()+aDif
,NULL
,nBestXSnap
,nBestYSnap
,bXSnapped
,bYSnapped
);
1024 getSdrDragView().CheckSnap(Ref2()+aDif
,NULL
,nBestXSnap
,nBestYSnap
,bXSnapped
,bYSnapped
);
1025 aPnt
.X()+=nBestXSnap
;
1026 aPnt
.Y()+=nBestYSnap
;
1029 if (aPnt
!=DragStat().GetNow())
1032 DragStat().NextMove(aPnt
);
1033 Point
aDif(DragStat().GetNow()-DragStat().GetStart());
1034 pH1
->SetPos(Ref1()+aDif
);
1035 pH2
->SetPos(Ref2()+aDif
);
1037 SdrHdl
* pHM
= GetHdlList().GetHdl(HDL_MIRX
);
1043 DragStat().SetActionRect(Rectangle(pH1
->GetPos(),pH2
->GetPos()));
1048 if (!DragStat().IsNoSnap()) SnapPos(aPnt
);
1051 if (getSdrDragView().IsAngleSnapEnabled())
1052 nSA
=getSdrDragView().GetSnapAngle();
1054 if (getSdrDragView().IsMirrorAllowed(true,true))
1056 if (!getSdrDragView().IsMirrorAllowed(false,false)) nSA
=4500;
1057 if (!getSdrDragView().IsMirrorAllowed(true,false)) nSA
=9000;
1060 if (getSdrDragView().IsOrtho() && nSA
!=9000)
1065 SdrHdlKind eRef
=HDL_REF1
;
1067 if (GetDragHdl()->GetKind()==HDL_REF1
)
1070 SdrHdl
* pH
=GetHdlList().GetHdl(eRef
);
1074 Point
aRef(pH
->GetPos());
1075 long nWink
=NormAngle360(GetAngle(aPnt
-aRef
));
1076 long nNeuWink
=nWink
;
1080 nNeuWink
=NormAngle360(nNeuWink
);
1081 double a
=(nNeuWink
-nWink
)*nPi180
;
1084 RotatePoint(aPnt
,aRef
,nSin
,nCos
);
1086 // eliminate rounding errors for certain values
1089 if (nNeuWink
==0 || nNeuWink
==18000) aPnt
.Y()=aRef
.Y();
1090 if (nNeuWink
==9000 || nNeuWink
==27000) aPnt
.X()=aRef
.X();
1094 OrthoDistance8(aRef
,aPnt
,true);
1098 if (aPnt
!=DragStat().GetNow())
1101 DragStat().NextMove(aPnt
);
1102 GetDragHdl()->SetPos(DragStat().GetNow());
1103 SdrHdl
* pHM
= GetHdlList().GetHdl(HDL_MIRX
);
1109 DragStat().SetActionRect(Rectangle(aPnt
,aPnt
));
1115 bool SdrDragMovHdl::EndSdrDrag(bool /*bCopy*/)
1119 switch (GetDragHdl()->GetKind())
1122 Ref1()=DragStat().GetNow();
1126 Ref2()=DragStat().GetNow();
1130 Ref1()+=DragStat().GetNow()-DragStat().GetStart();
1131 Ref2()+=DragStat().GetNow()-DragStat().GetStart();
1141 void SdrDragMovHdl::CancelSdrDrag()
1145 SdrHdl
* pHdl
= GetDragHdl();
1147 pHdl
->SetPos(DragStat().GetRef1());
1149 SdrHdl
* pHM
= GetHdlList().GetHdl(HDL_MIRX
);
1155 Pointer
SdrDragMovHdl::GetSdrDragPointer() const
1157 const SdrHdl
* pHdl
= GetDragHdl();
1161 return pHdl
->GetPointer();
1164 return Pointer(POINTER_REFHAND
);
1167 ////////////////////////////////////////////////////////////////////////////////////////////////////
1169 TYPEINIT1(SdrDragObjOwn
,SdrDragMethod
);
1171 SdrDragObjOwn::SdrDragObjOwn(SdrDragView
& rNewView
)
1172 : SdrDragMethod(rNewView
),
1175 const SdrObject
* pObj
= GetDragObj();
1179 // suppress full drag for some object types
1180 setSolidDraggingActive(pObj
->supportsFullDrag());
1184 SdrDragObjOwn::~SdrDragObjOwn()
1188 SdrObject::Free(mpClone
);
1192 void SdrDragObjOwn::createSdrDragEntries()
1196 basegfx::B2DPolyPolygon aDragPolyPolygon
;
1197 bool bAddWireframe(true);
1199 if(getSolidDraggingActive())
1201 SdrPageView
* pPV
= getSdrDragView().GetSdrPageView();
1203 if(pPV
&& pPV
->PageWindowCount())
1205 sdr::contact::ObjectContact
& rOC
= pPV
->GetPageWindow(0)->GetObjectContact();
1206 addSdrDragEntry(new SdrDragEntrySdrObject(*mpClone
, rOC
, false));
1208 // potentially no wireframe needed, full drag works
1209 bAddWireframe
= false;
1215 // check for extra conditions for wireframe, e.g. no border at
1217 if(!mpClone
->HasLineStyle())
1219 bAddWireframe
= true;
1225 // use wireframe poly when full drag is off or did not work
1226 aDragPolyPolygon
= mpClone
->TakeXorPoly();
1229 // add evtl. extra DragPolyPolygon
1230 const basegfx::B2DPolyPolygon
aSpecialDragPolyPolygon(mpClone
->getSpecialDragPoly(DragStat()));
1232 if(aSpecialDragPolyPolygon
.count())
1234 aDragPolyPolygon
.append(aSpecialDragPolyPolygon
);
1237 if(aDragPolyPolygon
.count())
1239 addSdrDragEntry(new SdrDragEntryPolyPolygon(aDragPolyPolygon
));
1244 void SdrDragObjOwn::TakeSdrDragComment(XubString
& rStr
) const
1246 // #i103058# get info string from the clone preferred, the original will
1247 // not be changed. For security, use original as fallback
1250 rStr
= mpClone
->getSpecialDragComment(DragStat());
1254 const SdrObject
* pObj
= GetDragObj();
1258 rStr
= pObj
->getSpecialDragComment(DragStat());
1263 bool SdrDragObjOwn::BeginSdrDrag()
1267 const SdrObject
* pObj
= GetDragObj();
1269 if(pObj
&& !pObj
->IsResizeProtect())
1271 if(pObj
->beginSpecialDrag(DragStat()))
1273 // create initial clone to have a start visualization
1274 mpClone
= pObj
->getFullDragClone();
1275 mpClone
->applySpecialDrag(DragStat());
1285 void SdrDragObjOwn::MoveSdrDrag(const Point
& rNoSnapPnt
)
1287 const SdrObject
* pObj
= GetDragObj();
1291 Point
aPnt(rNoSnapPnt
);
1292 SdrPageView
* pPV
= GetDragPV();
1296 if(!DragStat().IsNoSnap())
1301 if(getSdrDragView().IsOrtho())
1303 if (DragStat().IsOrtho8Possible())
1305 OrthoDistance8(DragStat().GetStart(),aPnt
,getSdrDragView().IsBigOrtho());
1307 else if (DragStat().IsOrtho4Possible())
1309 OrthoDistance4(DragStat().GetStart(),aPnt
,getSdrDragView().IsBigOrtho());
1313 if(DragStat().CheckMinMoved(rNoSnapPnt
))
1315 if(aPnt
!= DragStat().GetNow())
1318 DragStat().NextMove(aPnt
);
1320 // since SdrDragObjOwn currently supports no transformation of
1321 // existing SdrDragEntries but only their recreation, a recreation
1322 // after every move is needed in this mode. Delete existing
1323 // SdrDragEntries here to force their recreation in the following Show().
1324 clearSdrDragEntries();
1326 // delete current clone (after the last reference to it is deleted above)
1329 SdrObject::Free(mpClone
);
1333 // create a new clone and modify to current drag state
1336 mpClone
= pObj
->getFullDragClone();
1337 mpClone
->applySpecialDrag(DragStat());
1339 // #120999# AutoGrowWidth may change for SdrTextObj due to the automatism used
1340 // with bDisableAutoWidthOnDragging, so not only geometry changes but
1341 // also this (pretty indirect) property change is possible. If it gets
1342 // changed, it needs to be copied to the original since nothing will
1343 // happen when it only changes in the drag clone
1344 const bool bOldAutoGrowWidth(((SdrTextAutoGrowWidthItem
&)pObj
->GetMergedItem(SDRATTR_TEXT_AUTOGROWWIDTH
)).GetValue());
1345 const bool bNewAutoGrowWidth(((SdrTextAutoGrowWidthItem
&)mpClone
->GetMergedItem(SDRATTR_TEXT_AUTOGROWWIDTH
)).GetValue());
1347 if(bOldAutoGrowWidth
!= bNewAutoGrowWidth
)
1349 GetDragObj()->SetMergedItem(SdrTextAutoGrowWidthItem(bNewAutoGrowWidth
));
1360 bool SdrDragObjOwn::EndSdrDrag(bool /*bCopy*/)
1363 std::vector
< SdrUndoAction
* > vConnectorUndoActions
;
1365 SdrObject
* pObj
= GetDragObj();
1369 SdrUndoAction
* pUndo
= NULL
;
1370 SdrUndoAction
* pUndo2
= NULL
;
1371 const bool bUndo
= getSdrDragView().IsUndoEnabled();
1375 if(!getSdrDragView().IsInsObjPoint() && pObj
->IsInserted() )
1377 if (DragStat().IsEndDragChangesAttributes())
1379 pUndo
=getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pObj
);
1381 if (DragStat().IsEndDragChangesGeoAndAttributes())
1383 vConnectorUndoActions
= getSdrDragView().CreateConnectorUndo( *pObj
);
1384 pUndo2
= getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj
);
1389 vConnectorUndoActions
= getSdrDragView().CreateConnectorUndo( *pObj
);
1390 pUndo
= getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj
);
1396 getSdrDragView().BegUndo( pUndo
->GetComment() );
1400 getSdrDragView().BegUndo();
1404 // Maybe use operator = for setting changed object data (do not change selection in
1405 // view, this will destroy the interactor). This is possible since a clone is now
1406 // directly modified by the modifiers. Only SdrTableObj is adding own UNDOs
1407 // in its SdrTableObj::endSpecialDrag, so currently not possible. OTOH it uses
1408 // a CreateUndoGeoObject(), so maybe setting SetEndDragChangesAttributes is okay. I
1409 // will test this now
1410 Rectangle aBoundRect0
;
1412 if(pObj
->GetUserCall())
1414 aBoundRect0
= pObj
->GetLastBoundRect();
1417 bRet
= pObj
->applySpecialDrag(DragStat());
1422 pObj
->BroadcastObjectChange();
1423 pObj
->SendUserCall( SDRUSERCALL_RESIZE
, aBoundRect0
);
1430 getSdrDragView().AddUndoActions( vConnectorUndoActions
);
1434 getSdrDragView().AddUndo(pUndo
);
1439 getSdrDragView().AddUndo(pUndo2
);
1447 std::vector
< SdrUndoAction
* >::iterator
vConnectorUndoIter( vConnectorUndoActions
.begin() );
1449 while( vConnectorUndoIter
!= vConnectorUndoActions
.end() )
1451 delete *vConnectorUndoIter
++;
1460 getSdrDragView().EndUndo();
1466 Pointer
SdrDragObjOwn::GetSdrDragPointer() const
1468 const SdrHdl
* pHdl
=GetDragHdl();
1472 return pHdl
->GetPointer();
1475 return Pointer(POINTER_MOVE
);
1478 ////////////////////////////////////////////////////////////////////////////////////////////////////
1480 TYPEINIT1(SdrDragMove
,SdrDragMethod
);
1482 void SdrDragMove::createSdrDragEntryForSdrObject(const SdrObject
& rOriginal
, sdr::contact::ObjectContact
& rObjectContact
, bool /*bModify*/)
1484 // for SdrDragMove, use current Primitive2DSequence of SdrObject visualization
1485 // in given ObjectContact directly
1486 sdr::contact::ViewContact
& rVC
= rOriginal
.GetViewContact();
1487 sdr::contact::ViewObjectContact
& rVOC
= rVC
.GetViewObjectContact(rObjectContact
);
1488 sdr::contact::DisplayInfo aDisplayInfo
;
1490 // Do not use the last ViewPort set at the OC from the last ProcessDisplay(),
1491 // here we want the complete primitive sequence without visible clippings
1492 rObjectContact
.resetViewPort();
1494 addSdrDragEntry(new SdrDragEntryPrimitive2DSequence(rVOC
.getPrimitive2DSequenceHierarchy(aDisplayInfo
), true));
1497 void SdrDragMove::applyCurrentTransformationToSdrObject(SdrObject
& rTarget
)
1499 rTarget
.Move(Size(DragStat().GetDX(), DragStat().GetDY()));
1502 SdrDragMove::SdrDragMove(SdrDragView
& rNewView
)
1503 : SdrDragMethod(rNewView
)
1508 void SdrDragMove::TakeSdrDragComment(XubString
& rStr
) const
1512 ImpTakeDescriptionStr(STR_DragMethMove
, rStr
);
1513 rStr
.AppendAscii(" (x=");
1514 getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDX(), aStr
);
1516 rStr
.AppendAscii(" y=");
1517 getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDY(), aStr
);
1519 rStr
+= sal_Unicode(')');
1521 if(getSdrDragView().IsDragWithCopy())
1523 if(!getSdrDragView().IsInsObjPoint() && !getSdrDragView().IsInsGluePoint())
1525 rStr
+= ImpGetResStr(STR_EditWithCopy
);
1530 bool SdrDragMove::BeginSdrDrag()
1532 DragStat().SetActionRect(GetMarkedRect());
1538 basegfx::B2DHomMatrix
SdrDragMove::getCurrentTransformation()
1540 return basegfx::tools::createTranslateB2DHomMatrix(DragStat().GetDX(), DragStat().GetDY());
1543 void SdrDragMove::ImpCheckSnap(const Point
& rPt
)
1546 sal_uInt16 nRet
=SnapPos(aPt
);
1549 if ((nRet
& SDRSNAP_XSNAPPED
) !=0)
1553 if (std::abs(aPt
.X())<std::abs(nBestXSnap
))
1565 if ((nRet
& SDRSNAP_YSNAPPED
) !=0)
1569 if (std::abs(aPt
.Y())<std::abs(nBestYSnap
))
1582 void SdrDragMove::MoveSdrDrag(const Point
& rNoSnapPnt_
)
1588 Point
aNoSnapPnt(rNoSnapPnt_
);
1589 const Rectangle
& aSR
=GetMarkedRect();
1590 long nMovedx
=aNoSnapPnt
.X()-DragStat().GetStart().X();
1591 long nMovedy
=aNoSnapPnt
.Y()-DragStat().GetStart().Y();
1592 Point
aLO(aSR
.TopLeft()); aLO
.X()+=nMovedx
; aLO
.Y()+=nMovedy
;
1593 Point
aRU(aSR
.BottomRight()); aRU
.X()+=nMovedx
; aRU
.Y()+=nMovedy
;
1594 Point
aLU(aLO
.X(),aRU
.Y());
1595 Point
aRO(aRU
.X(),aLO
.Y());
1598 if (!getSdrDragView().IsMoveSnapOnlyTopLeft())
1605 Point
aPnt(aNoSnapPnt
.X()+nBestXSnap
,aNoSnapPnt
.Y()+nBestYSnap
);
1606 bool bOrtho
=getSdrDragView().IsOrtho();
1609 OrthoDistance8(DragStat().GetStart(),aPnt
,getSdrDragView().IsBigOrtho());
1611 if (DragStat().CheckMinMoved(aNoSnapPnt
))
1614 Rectangle
aLR(getSdrDragView().GetWorkArea());
1615 bool bWorkArea
=!aLR
.IsEmpty();
1616 bool bDragLimit
=IsDragLimit();
1618 if (bDragLimit
|| bWorkArea
)
1620 Rectangle
aSR2(GetMarkedRect());
1621 Point
aD(aPt1
-DragStat().GetStart());
1625 Rectangle
aR2(GetDragLimitRect());
1628 aLR
.Intersection(aR2
);
1633 if (aSR2
.Left()>aLR
.Left() || aSR2
.Right()<aLR
.Right())
1634 { // any space to move to?
1635 aSR2
.Move(aD
.X(),0);
1637 if (aSR2
.Left()<aLR
.Left())
1639 aPt1
.X()-=aSR2
.Left()-aLR
.Left();
1641 else if (aSR2
.Right()>aLR
.Right())
1643 aPt1
.X()-=aSR2
.Right()-aLR
.Right();
1647 aPt1
.X()=DragStat().GetStart().X(); // no space to move to
1649 if (aSR2
.Top()>aLR
.Top() || aSR2
.Bottom()<aLR
.Bottom())
1650 { // any space to move to?
1651 aSR2
.Move(0,aD
.Y());
1653 if (aSR2
.Top()<aLR
.Top())
1655 aPt1
.Y()-=aSR2
.Top()-aLR
.Top();
1657 else if (aSR2
.Bottom()>aLR
.Bottom())
1659 aPt1
.Y()-=aSR2
.Bottom()-aLR
.Bottom();
1663 aPt1
.Y()=DragStat().GetStart().Y(); // no space to move to
1666 if (getSdrDragView().IsDraggingGluePoints())
1667 { // restrict glue points to the BoundRect of the Obj
1668 aPt1
-=DragStat().GetStart();
1669 const SdrMarkList
& rML
=GetMarkedObjectList();
1670 sal_uLong nMarkAnz
=rML
.GetMarkCount();
1672 for (sal_uLong nMarkNum
=0; nMarkNum
<nMarkAnz
; nMarkNum
++)
1674 const SdrMark
* pM
=rML
.GetMark(nMarkNum
);
1675 const SdrUShortCont
* pPts
=pM
->GetMarkedGluePoints();
1676 sal_uLong nPtAnz
=pPts
==NULL
? 0 : pPts
->size();
1680 const SdrObject
* pObj
=pM
->GetMarkedSdrObj();
1681 const SdrGluePointList
* pGPL
=pObj
->GetGluePointList();
1682 Rectangle
aBound(pObj
->GetCurrentBoundRect());
1684 for (SdrUShortCont::const_iterator it
= pPts
->begin(); it
!= pPts
->end(); ++it
)
1686 sal_uInt16 nId
= *it
;
1687 sal_uInt16 nGlueNum
=pGPL
->FindGluePoint(nId
);
1689 if (nGlueNum
!=SDRGLUEPOINT_NOTFOUND
)
1691 Point
aPt((*pGPL
)[nGlueNum
].GetAbsolutePos(*pObj
));
1692 aPt
+=aPt1
; // move by this much
1693 if (aPt
.X()<aBound
.Left() ) aPt1
.X()-=aPt
.X()-aBound
.Left() ;
1694 if (aPt
.X()>aBound
.Right() ) aPt1
.X()-=aPt
.X()-aBound
.Right() ;
1695 if (aPt
.Y()<aBound
.Top() ) aPt1
.Y()-=aPt
.Y()-aBound
.Top() ;
1696 if (aPt
.Y()>aBound
.Bottom()) aPt1
.Y()-=aPt
.Y()-aBound
.Bottom();
1702 aPt1
+=DragStat().GetStart();
1706 OrthoDistance8(DragStat().GetStart(),aPt1
,false);
1708 if (aPt1
!=DragStat().GetNow())
1711 DragStat().NextMove(aPt1
);
1712 Rectangle
aAction(GetMarkedRect());
1713 aAction
.Move(DragStat().GetDX(),DragStat().GetDY());
1714 DragStat().SetActionRect(aAction
);
1720 bool SdrDragMove::EndSdrDrag(bool bCopy
)
1724 if (getSdrDragView().IsInsObjPoint() || getSdrDragView().IsInsGluePoint())
1727 if (IsDraggingPoints())
1729 getSdrDragView().MoveMarkedPoints(Size(DragStat().GetDX(),DragStat().GetDY()),bCopy
);
1731 else if (IsDraggingGluePoints())
1733 getSdrDragView().MoveMarkedGluePoints(Size(DragStat().GetDX(),DragStat().GetDY()),bCopy
);
1737 getSdrDragView().MoveMarkedObj(Size(DragStat().GetDX(),DragStat().GetDY()),bCopy
);
1743 Pointer
SdrDragMove::GetSdrDragPointer() const
1745 if (IsDraggingPoints() || IsDraggingGluePoints())
1747 return Pointer(POINTER_MOVEPOINT
);
1751 return Pointer(POINTER_MOVE
);
1755 ////////////////////////////////////////////////////////////////////////////////////////////////////
1757 TYPEINIT1(SdrDragResize
,SdrDragMethod
);
1759 SdrDragResize::SdrDragResize(SdrDragView
& rNewView
)
1760 : SdrDragMethod(rNewView
),
1766 void SdrDragResize::TakeSdrDragComment(XubString
& rStr
) const
1768 ImpTakeDescriptionStr(STR_DragMethResize
, rStr
);
1769 bool bEqual(aXFact
== aYFact
);
1770 Fraction
aFact1(1,1);
1771 Point
aStart(DragStat().GetStart());
1772 Point
aRef(DragStat().GetRef1());
1773 sal_Int32
nXDiv(aStart
.X() - aRef
.X());
1778 sal_Int32
nYDiv(aStart
.Y() - aRef
.Y());
1783 bool bX(aXFact
!= aFact1
&& std::abs(nXDiv
) > 1);
1784 bool bY(aYFact
!= aFact1
&& std::abs(nYDiv
) > 1);
1790 rStr
.AppendAscii(" (");
1795 rStr
.AppendAscii("x=");
1797 getSdrDragView().GetModel()->TakePercentStr(aXFact
, aStr
);
1804 rStr
+= sal_Unicode(' ');
1806 rStr
.AppendAscii("y=");
1807 getSdrDragView().GetModel()->TakePercentStr(aYFact
, aStr
);
1811 rStr
+= sal_Unicode(')');
1814 if(getSdrDragView().IsDragWithCopy())
1815 rStr
+= ImpGetResStr(STR_EditWithCopy
);
1818 bool SdrDragResize::BeginSdrDrag()
1820 SdrHdlKind eRefHdl
=HDL_MOVE
;
1821 SdrHdl
* pRefHdl
=NULL
;
1823 switch (GetDragHdlKind())
1825 case HDL_UPLFT
: eRefHdl
=HDL_LWRGT
; break;
1826 case HDL_UPPER
: eRefHdl
=HDL_LOWER
; DragStat().SetHorFixed(true); break;
1827 case HDL_UPRGT
: eRefHdl
=HDL_LWLFT
; break;
1828 case HDL_LEFT
: eRefHdl
=HDL_RIGHT
; DragStat().SetVerFixed(true); break;
1829 case HDL_RIGHT
: eRefHdl
=HDL_LEFT
; DragStat().SetVerFixed(true); break;
1830 case HDL_LWLFT
: eRefHdl
=HDL_UPRGT
; break;
1831 case HDL_LOWER
: eRefHdl
=HDL_UPPER
; DragStat().SetHorFixed(true); break;
1832 case HDL_LWRGT
: eRefHdl
=HDL_UPLFT
; break;
1836 if (eRefHdl
!=HDL_MOVE
)
1837 pRefHdl
=GetHdlList().GetHdl(eRefHdl
);
1839 if (pRefHdl
!=NULL
&& !getSdrDragView().IsResizeAtCenter())
1841 // Calc hack to adjust for calc grid
1842 DragStat().Ref1()=pRefHdl
->GetPos() - getSdrDragView().GetGridOffset();
1846 SdrHdl
* pRef1
=GetHdlList().GetHdl(HDL_UPLFT
);
1847 SdrHdl
* pRef2
=GetHdlList().GetHdl(HDL_LWRGT
);
1849 if (pRef1
!=NULL
&& pRef2
!=NULL
)
1851 DragStat().Ref1()=Rectangle(pRef1
->GetPos(),pRef2
->GetPos()).Center();
1855 DragStat().Ref1()=GetMarkedRect().Center();
1864 basegfx::B2DHomMatrix
SdrDragResize::getCurrentTransformation()
1866 basegfx::B2DHomMatrix
aRetval(basegfx::tools::createTranslateB2DHomMatrix(
1867 -DragStat().Ref1().X(), -DragStat().Ref1().Y()));
1868 aRetval
.scale(aXFact
, aYFact
);
1869 aRetval
.translate(DragStat().Ref1().X(), DragStat().Ref1().Y());
1874 void SdrDragResize::MoveSdrDrag(const Point
& rNoSnapPnt
)
1876 Point
aPnt(GetSnapPos(rNoSnapPnt
));
1877 Point
aStart(DragStat().GetStart());
1878 Point
aRef(DragStat().GetRef1());
1879 Fraction
aMaxFact(0x7FFFFFFF,1);
1880 Rectangle
aLR(getSdrDragView().GetWorkArea());
1881 bool bWorkArea
=!aLR
.IsEmpty();
1882 bool bDragLimit
=IsDragLimit();
1884 if (bDragLimit
|| bWorkArea
)
1886 Rectangle
aSR(GetMarkedRect());
1890 Rectangle
aR2(GetDragLimitRect());
1893 aLR
.Intersection(aR2
);
1898 if (aPnt
.X()<aLR
.Left())
1899 aPnt
.X()=aLR
.Left();
1900 else if (aPnt
.X()>aLR
.Right())
1901 aPnt
.X()=aLR
.Right();
1903 if (aPnt
.Y()<aLR
.Top())
1905 else if (aPnt
.Y()>aLR
.Bottom())
1906 aPnt
.Y()=aLR
.Bottom();
1908 if (aRef
.X()>aSR
.Left())
1910 Fraction
aMax(aRef
.X()-aLR
.Left(),aRef
.X()-aSR
.Left());
1916 if (aRef
.X()<aSR
.Right())
1918 Fraction
aMax(aLR
.Right()-aRef
.X(),aSR
.Right()-aRef
.X());
1924 if (aRef
.Y()>aSR
.Top())
1926 Fraction
aMax(aRef
.Y()-aLR
.Top(),aRef
.Y()-aSR
.Top());
1932 if (aRef
.Y()<aSR
.Bottom())
1934 Fraction
aMax(aLR
.Bottom()-aRef
.Y(),aSR
.Bottom()-aRef
.Y());
1941 long nXDiv
=aStart
.X()-aRef
.X(); if (nXDiv
==0) nXDiv
=1;
1942 long nYDiv
=aStart
.Y()-aRef
.Y(); if (nYDiv
==0) nYDiv
=1;
1943 long nXMul
=aPnt
.X()-aRef
.X();
1944 long nYMul
=aPnt
.Y()-aRef
.Y();
1958 bool bXNeg
=nXMul
<0; if (bXNeg
) nXMul
=-nXMul
;
1959 bool bYNeg
=nYMul
<0; if (bYNeg
) nYMul
=-nYMul
;
1960 bool bOrtho
=getSdrDragView().IsOrtho() || !getSdrDragView().IsResizeAllowed(false);
1962 if (!DragStat().IsHorFixed() && !DragStat().IsVerFixed())
1964 if (std::abs(nXDiv
)<=1 || std::abs(nYDiv
)<=1)
1969 if ((Fraction(nXMul
,nXDiv
)>Fraction(nYMul
,nYDiv
)) !=getSdrDragView().IsBigOrtho())
1985 if (DragStat().IsHorFixed())
1992 if (DragStat().IsVerFixed())
2001 if (DragStat().IsHorFixed())
2008 if (DragStat().IsVerFixed())
2017 Fraction
aNeuXFact(nXMul
,nXDiv
);
2018 Fraction
aNeuYFact(nYMul
,nYDiv
);
2022 if (aNeuXFact
>aMaxFact
)
2028 if (aNeuYFact
>aMaxFact
)
2036 aNeuXFact
=Fraction(-aNeuXFact
.GetNumerator(),aNeuXFact
.GetDenominator());
2039 aNeuYFact
=Fraction(-aNeuYFact
.GetNumerator(),aNeuYFact
.GetDenominator());
2041 if (DragStat().CheckMinMoved(aPnt
))
2043 if ((!DragStat().IsHorFixed() && aPnt
.X()!=DragStat().GetNow().X()) ||
2044 (!DragStat().IsVerFixed() && aPnt
.Y()!=DragStat().GetNow().Y()))
2047 DragStat().NextMove(aPnt
);
2055 void SdrDragResize::applyCurrentTransformationToSdrObject(SdrObject
& rTarget
)
2057 rTarget
.Resize(DragStat().Ref1(),aXFact
,aYFact
);
2060 bool SdrDragResize::EndSdrDrag(bool bCopy
)
2064 if (IsDraggingPoints())
2066 getSdrDragView().ResizeMarkedPoints(DragStat().Ref1(),aXFact
,aYFact
,bCopy
);
2068 else if (IsDraggingGluePoints())
2070 getSdrDragView().ResizeMarkedGluePoints(DragStat().Ref1(),aXFact
,aYFact
,bCopy
);
2074 getSdrDragView().ResizeMarkedObj(DragStat().Ref1(),aXFact
,aYFact
,bCopy
);
2080 Pointer
SdrDragResize::GetSdrDragPointer() const
2082 const SdrHdl
* pHdl
=GetDragHdl();
2086 return pHdl
->GetPointer();
2089 return Pointer(POINTER_MOVE
);
2092 ////////////////////////////////////////////////////////////////////////////////////////////////////
2094 TYPEINIT1(SdrDragRotate
,SdrDragMethod
);
2096 void SdrDragRotate::applyCurrentTransformationToSdrObject(SdrObject
& rTarget
)
2098 rTarget
.Rotate(DragStat().GetRef1(), nWink
, sin(nWink
*nPi180
), cos(nWink
*nPi180
));
2101 SdrDragRotate::SdrDragRotate(SdrDragView
& rNewView
)
2102 : SdrDragMethod(rNewView
),
2111 void SdrDragRotate::TakeSdrDragComment(XubString
& rStr
) const
2113 ImpTakeDescriptionStr(STR_DragMethRotate
, rStr
);
2114 rStr
.AppendAscii(" (");
2115 sal_Int32
nTmpWink(NormAngle360(nWink
));
2123 getSdrDragView().GetModel()->TakeWinkStr(nTmpWink
, aStr
);
2125 rStr
+= sal_Unicode(')');
2127 if(getSdrDragView().IsDragWithCopy())
2128 rStr
+= ImpGetResStr(STR_EditWithCopy
);
2131 bool SdrDragRotate::BeginSdrDrag()
2133 SdrHdl
* pH
=GetHdlList().GetHdl(HDL_REF1
);
2138 DragStat().Ref1()=pH
->GetPos();
2139 nWink0
=GetAngle(DragStat().GetStart()-DragStat().GetRef1());
2144 OSL_FAIL("SdrDragRotate::BeginSdrDrag(): No reference point handle found.");
2149 basegfx::B2DHomMatrix
SdrDragRotate::getCurrentTransformation()
2151 return basegfx::tools::createRotateAroundPoint(
2152 DragStat().GetRef1().X(), DragStat().GetRef1().Y(),
2153 -atan2(nSin
, nCos
));
2156 void SdrDragRotate::MoveSdrDrag(const Point
& rPnt_
)
2159 if (DragStat().CheckMinMoved(aPnt
))
2161 long nNeuWink
=NormAngle360(GetAngle(aPnt
-DragStat().GetRef1())-nWink0
);
2164 if (getSdrDragView().IsAngleSnapEnabled())
2165 nSA
=getSdrDragView().GetSnapAngle();
2167 if (!getSdrDragView().IsRotateAllowed(false))
2177 nNeuWink
=NormAngle180(nNeuWink
);
2179 if (nWink
!=nNeuWink
)
2181 sal_uInt16 nSekt0
=GetAngleSector(nWink
);
2182 sal_uInt16 nSekt1
=GetAngleSector(nNeuWink
);
2184 if (nSekt0
==0 && nSekt1
==3)
2187 if (nSekt0
==3 && nSekt1
==0)
2191 double a
=nWink
*nPi180
;
2192 double nSin1
=sin(a
); // calculate now, so as little time as possible
2193 double nCos1
=cos(a
); // passes between Hide() and Show()
2197 DragStat().NextMove(aPnt
);
2203 bool SdrDragRotate::EndSdrDrag(bool bCopy
)
2209 if (IsDraggingPoints())
2211 getSdrDragView().RotateMarkedPoints(DragStat().GetRef1(),nWink
,bCopy
);
2213 else if (IsDraggingGluePoints())
2215 getSdrDragView().RotateMarkedGluePoints(DragStat().GetRef1(),nWink
,bCopy
);
2219 getSdrDragView().RotateMarkedObj(DragStat().GetRef1(),nWink
,bCopy
);
2225 Pointer
SdrDragRotate::GetSdrDragPointer() const
2227 return Pointer(POINTER_ROTATE
);
2230 ////////////////////////////////////////////////////////////////////////////////////////////////////
2232 TYPEINIT1(SdrDragShear
,SdrDragMethod
);
2234 SdrDragShear::SdrDragShear(SdrDragView
& rNewView
, bool bSlant1
)
2235 : SdrDragMethod(rNewView
),
2247 void SdrDragShear::TakeSdrDragComment(XubString
& rStr
) const
2249 ImpTakeDescriptionStr(STR_DragMethShear
, rStr
);
2250 rStr
.AppendAscii(" (");
2252 sal_Int32
nTmpWink(nWink
);
2257 nTmpWink
= NormAngle180(nTmpWink
);
2260 getSdrDragView().GetModel()->TakeWinkStr(nTmpWink
, aStr
);
2262 rStr
+= sal_Unicode(')');
2264 if(getSdrDragView().IsDragWithCopy())
2265 rStr
+= ImpGetResStr(STR_EditWithCopy
);
2268 bool SdrDragShear::BeginSdrDrag()
2270 SdrHdlKind eRefHdl
=HDL_MOVE
;
2271 SdrHdl
* pRefHdl
=NULL
;
2273 switch (GetDragHdlKind())
2275 case HDL_UPPER
: eRefHdl
=HDL_LOWER
; break;
2276 case HDL_LOWER
: eRefHdl
=HDL_UPPER
; break;
2277 case HDL_LEFT
: eRefHdl
=HDL_RIGHT
; bVertical
=true; break;
2278 case HDL_RIGHT
: eRefHdl
=HDL_LEFT
; bVertical
=true; break;
2282 if (eRefHdl
!=HDL_MOVE
)
2283 pRefHdl
=GetHdlList().GetHdl(eRefHdl
);
2287 DragStat().Ref1()=pRefHdl
->GetPos();
2288 nWink0
=GetAngle(DragStat().GetStart()-DragStat().GetRef1());
2292 OSL_FAIL("SdrDragShear::BeginSdrDrag(): No reference point handle for shearing found.");
2300 basegfx::B2DHomMatrix
SdrDragShear::getCurrentTransformation()
2302 basegfx::B2DHomMatrix
aRetval(basegfx::tools::createTranslateB2DHomMatrix(
2303 -DragStat().GetRef1().X(), -DragStat().GetRef1().Y()));
2309 aRetval
.scale(aFact
, 1.0);
2310 aRetval
.shearY(-nTan
);
2314 aRetval
.scale(1.0, aFact
);
2315 aRetval
.shearX(-nTan
);
2319 aRetval
.translate(DragStat().GetRef1().X(), DragStat().GetRef1().Y());
2324 void SdrDragShear::MoveSdrDrag(const Point
& rPnt
)
2326 if (DragStat().CheckMinMoved(rPnt
))
2328 bResize
=!getSdrDragView().IsOrtho();
2331 if (getSdrDragView().IsAngleSnapEnabled())
2332 nSA
=getSdrDragView().GetSnapAngle();
2334 Point
aP0(DragStat().GetStart());
2336 Fraction
aNeuFact(1,1);
2338 // if angle snapping not activated, snap to raster (except when using slant)
2339 if (nSA
==0 && !bSlant
)
2340 aPnt
=GetSnapPos(aPnt
);
2342 if (!bSlant
&& !bResize
)
2343 { // shear, but no resize
2350 Point
aRef(DragStat().GetRef1());
2351 Point
aDif(aPnt
-aRef
);
2357 nNeuWink
=NormAngle180(-(GetAngle(aDif
)-nWink0
));
2360 nNeuWink
=NormAngle180(-nNeuWink
);
2365 nNeuWink
=NormAngle180(GetAngle(aDif
));
2367 nNeuWink
=NormAngle180(-(GetAngle(aDif
)-9000));
2369 if (nNeuWink
<-9000 || nNeuWink
>9000)
2370 nNeuWink
=NormAngle180(nNeuWink
+18000);
2377 aPt2
=GetSnapPos(aPnt
); // snap this one in any case
2381 aNeuFact
=Fraction(aPt2
.X()-aRef
.X(),aP0
.X()-aRef
.X());
2385 aNeuFact
=Fraction(aPt2
.Y()-aRef
.Y(),aP0
.Y()-aRef
.Y());
2390 bool bNeg
=nNeuWink
<0;
2402 nNeuWink
=NormAngle360(nNeuWink
);
2403 bUpSideDown
=nNeuWink
>9000 && nNeuWink
<27000;
2406 { // calculate resize for slant
2407 // when angle snapping is activated, disable 89 degree limit
2408 long nTmpWink
=nNeuWink
;
2409 if (bUpSideDown
) nNeuWink
-=18000;
2410 if (bNeg
) nTmpWink
=-nTmpWink
;
2412 double nCos
=cos(nTmpWink
*nPi180
);
2414 Kuerzen(aFact
,10); // three decimals should be enough
2423 if (nWink
!=nNeuWink
|| aFact
!=aNeuFact
)
2427 double a
=nWink
*nPi180
;
2428 double nTan1
=tan(a
); // calculate now, so as little time as possible passes between Hide() and Show()
2431 DragStat().NextMove(rPnt
);
2437 void SdrDragShear::applyCurrentTransformationToSdrObject(SdrObject
& rTarget
)
2443 rTarget
.Resize(DragStat().GetRef1(),aFact
,Fraction(1,1));
2447 rTarget
.Resize(DragStat().GetRef1(),Fraction(1,1),aFact
);
2453 rTarget
.Shear(DragStat().GetRef1(),nWink
,tan(nWink
*nPi180
),bVertical
);
2457 bool SdrDragShear::EndSdrDrag(bool bCopy
)
2461 if (bResize
&& aFact
==Fraction(1,1))
2464 if (nWink
!=0 || bResize
)
2466 if (nWink
!=0 && bResize
)
2469 ImpTakeDescriptionStr(STR_EditShear
,aStr
);
2472 aStr
+=ImpGetResStr(STR_EditWithCopy
);
2474 getSdrDragView().BegUndo(aStr
);
2481 getSdrDragView().ResizeMarkedObj(DragStat().GetRef1(),aFact
,Fraction(1,1),bCopy
);
2485 getSdrDragView().ResizeMarkedObj(DragStat().GetRef1(),Fraction(1,1),aFact
,bCopy
);
2493 getSdrDragView().ShearMarkedObj(DragStat().GetRef1(),nWink
,bVertical
,bCopy
);
2496 if (nWink
!=0 && bResize
)
2497 getSdrDragView().EndUndo();
2505 Pointer
SdrDragShear::GetSdrDragPointer() const
2508 return Pointer(POINTER_VSHEAR
);
2510 return Pointer(POINTER_HSHEAR
);
2513 ////////////////////////////////////////////////////////////////////////////////////////////////////
2515 TYPEINIT1(SdrDragMirror
,SdrDragMethod
);
2517 void SdrDragMirror::applyCurrentTransformationToSdrObject(SdrObject
& rTarget
)
2521 rTarget
.Mirror(DragStat().GetRef1(), DragStat().GetRef2());
2525 SdrDragMirror::SdrDragMirror(SdrDragView
& rNewView
)
2526 : SdrDragMethod(rNewView
),
2533 bool SdrDragMirror::ImpCheckSide(const Point
& rPnt
) const
2535 long nWink1
=GetAngle(rPnt
-DragStat().GetRef1());
2537 nWink1
=NormAngle360(nWink1
);
2539 return nWink1
<18000;
2542 void SdrDragMirror::TakeSdrDragComment(XubString
& rStr
) const
2545 ImpTakeDescriptionStr(STR_DragMethMirrorHori
,rStr
);
2546 else if (aDif
.Y()==0)
2547 ImpTakeDescriptionStr(STR_DragMethMirrorVert
,rStr
);
2548 else if (std::abs(aDif
.X()) == std::abs(aDif
.Y()))
2549 ImpTakeDescriptionStr(STR_DragMethMirrorDiag
,rStr
);
2551 ImpTakeDescriptionStr(STR_DragMethMirrorFree
,rStr
);
2553 if (getSdrDragView().IsDragWithCopy())
2554 rStr
+=ImpGetResStr(STR_EditWithCopy
);
2557 bool SdrDragMirror::BeginSdrDrag()
2559 SdrHdl
* pH1
=GetHdlList().GetHdl(HDL_REF1
);
2560 SdrHdl
* pH2
=GetHdlList().GetHdl(HDL_REF2
);
2562 if (pH1
!=NULL
&& pH2
!=NULL
)
2564 DragStat().Ref1()=pH1
->GetPos();
2565 DragStat().Ref2()=pH2
->GetPos();
2566 Ref1()=pH1
->GetPos();
2567 Ref2()=pH2
->GetPos();
2568 aDif
=pH2
->GetPos()-pH1
->GetPos();
2569 bool b90
=(aDif
.X()==0) || aDif
.Y()==0;
2570 bool b45
=b90
|| (std::abs(aDif
.X()) == std::abs(aDif
.Y()));
2571 nWink
=NormAngle360(GetAngle(aDif
));
2573 if (!getSdrDragView().IsMirrorAllowed(false,false) && !b45
)
2574 return false; // free choice of axis angle not allowed
2576 if (!getSdrDragView().IsMirrorAllowed(true,false) && !b90
)
2577 return false; // 45 degrees not allowed either
2579 bSide0
=ImpCheckSide(DragStat().GetStart());
2585 OSL_FAIL("SdrDragMirror::BeginSdrDrag(): Axis of reflection not found.");
2590 basegfx::B2DHomMatrix
SdrDragMirror::getCurrentTransformation()
2592 basegfx::B2DHomMatrix aRetval
;
2596 const double fDeltaX(DragStat().GetRef2().X() - DragStat().GetRef1().X());
2597 const double fDeltaY(DragStat().GetRef2().Y() - DragStat().GetRef1().Y());
2598 const double fRotation(atan2(fDeltaY
, fDeltaX
));
2600 aRetval
= basegfx::tools::createTranslateB2DHomMatrix(-DragStat().GetRef1().X(), -DragStat().GetRef1().Y());
2601 aRetval
.rotate(-fRotation
);
2602 aRetval
.scale(1.0, -1.0);
2603 aRetval
.rotate(fRotation
);
2604 aRetval
.translate(DragStat().GetRef1().X(), DragStat().GetRef1().Y());
2610 void SdrDragMirror::MoveSdrDrag(const Point
& rPnt
)
2612 if (DragStat().CheckMinMoved(rPnt
))
2614 bool bNeuSide
=ImpCheckSide(rPnt
);
2615 bool bNeuMirr
=bSide0
!=bNeuSide
;
2617 if (bMirrored
!=bNeuMirr
)
2621 DragStat().NextMove(rPnt
);
2627 bool SdrDragMirror::EndSdrDrag(bool bCopy
)
2633 getSdrDragView().MirrorMarkedObj(DragStat().GetRef1(),DragStat().GetRef2(),bCopy
);
2639 Pointer
SdrDragMirror::GetSdrDragPointer() const
2641 return Pointer(POINTER_MIRROR
);
2644 ////////////////////////////////////////////////////////////////////////////////////////////////////
2646 TYPEINIT1(SdrDragGradient
, SdrDragMethod
);
2648 SdrDragGradient::SdrDragGradient(SdrDragView
& rNewView
, bool bGrad
)
2649 : SdrDragMethod(rNewView
),
2655 void SdrDragGradient::TakeSdrDragComment(XubString
& rStr
) const
2658 ImpTakeDescriptionStr(STR_DragMethGradient
, rStr
);
2660 ImpTakeDescriptionStr(STR_DragMethTransparence
, rStr
);
2663 bool SdrDragGradient::BeginSdrDrag()
2665 bool bRetval(false);
2667 pIAOHandle
= (SdrHdlGradient
*)GetHdlList().GetHdl(IsGradient() ? HDL_GRAD
: HDL_TRNS
);
2672 DragStat().Ref1() = pIAOHandle
->GetPos();
2673 DragStat().Ref2() = pIAOHandle
->Get2ndPos();
2677 SdrHdlColor
* pColHdl
= pIAOHandle
->GetColorHdl1();
2679 // init handling flags
2680 pIAOHandle
->SetMoveSingleHandle(false);
2681 pIAOHandle
->SetMoveFirstHandle(false);
2683 // test first color handle
2686 basegfx::B2DPoint
aPosition(DragStat().GetStart().X(), DragStat().GetStart().Y());
2688 if(pColHdl
->getOverlayObjectList().isHitLogic(aPosition
))
2691 pIAOHandle
->SetMoveSingleHandle(true);
2692 pIAOHandle
->SetMoveFirstHandle(true);
2696 // test second color handle
2697 pColHdl
= pIAOHandle
->GetColorHdl2();
2699 if(!bHit
&& pColHdl
)
2701 basegfx::B2DPoint
aPosition(DragStat().GetStart().X(), DragStat().GetStart().Y());
2703 if(pColHdl
->getOverlayObjectList().isHitLogic(aPosition
))
2706 pIAOHandle
->SetMoveSingleHandle(true);
2710 // test gradient handle itself
2713 basegfx::B2DPoint
aPosition(DragStat().GetStart().X(), DragStat().GetStart().Y());
2715 if(pIAOHandle
->getOverlayObjectList().isHitLogic(aPosition
))
2721 // everything up and running :o}
2726 OSL_FAIL("SdrDragGradient::BeginSdrDrag(): IAOGradient not found.");
2732 void SdrDragGradient::MoveSdrDrag(const Point
& rPnt
)
2734 if(pIAOHandle
&& DragStat().CheckMinMoved(rPnt
))
2736 DragStat().NextMove(rPnt
);
2738 // Do the Move here!!! DragStat().GetStart()
2739 Point aMoveDiff
= rPnt
- DragStat().GetStart();
2741 if(pIAOHandle
->IsMoveSingleHandle())
2743 if(pIAOHandle
->IsMoveFirstHandle())
2745 pIAOHandle
->SetPos(DragStat().Ref1() + aMoveDiff
);
2746 if(pIAOHandle
->GetColorHdl1())
2747 pIAOHandle
->GetColorHdl1()->SetPos(DragStat().Ref1() + aMoveDiff
);
2751 pIAOHandle
->Set2ndPos(DragStat().Ref2() + aMoveDiff
);
2752 if(pIAOHandle
->GetColorHdl2())
2753 pIAOHandle
->GetColorHdl2()->SetPos(DragStat().Ref2() + aMoveDiff
);
2758 pIAOHandle
->SetPos(DragStat().Ref1() + aMoveDiff
);
2759 pIAOHandle
->Set2ndPos(DragStat().Ref2() + aMoveDiff
);
2761 if(pIAOHandle
->GetColorHdl1())
2762 pIAOHandle
->GetColorHdl1()->SetPos(DragStat().Ref1() + aMoveDiff
);
2764 if(pIAOHandle
->GetColorHdl2())
2765 pIAOHandle
->GetColorHdl2()->SetPos(DragStat().Ref2() + aMoveDiff
);
2769 pIAOHandle
->FromIAOToItem(getSdrDragView().GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(), false, false);
2773 bool SdrDragGradient::EndSdrDrag(bool /*bCopy*/)
2775 Ref1() = pIAOHandle
->GetPos();
2776 Ref2() = pIAOHandle
->Get2ndPos();
2779 pIAOHandle
->FromIAOToItem(getSdrDragView().GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(), true, true);
2784 void SdrDragGradient::CancelSdrDrag()
2786 // restore old values
2787 pIAOHandle
->SetPos(DragStat().Ref1());
2788 pIAOHandle
->Set2ndPos(DragStat().Ref2());
2790 if(pIAOHandle
->GetColorHdl1())
2791 pIAOHandle
->GetColorHdl1()->SetPos(DragStat().Ref1());
2793 if(pIAOHandle
->GetColorHdl2())
2794 pIAOHandle
->GetColorHdl2()->SetPos(DragStat().Ref2());
2797 pIAOHandle
->FromIAOToItem(getSdrDragView().GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(), true, false);
2800 Pointer
SdrDragGradient::GetSdrDragPointer() const
2802 return Pointer(POINTER_REFHAND
);
2805 ////////////////////////////////////////////////////////////////////////////////////////////////////
2807 TYPEINIT1(SdrDragCrook
,SdrDragMethod
);
2809 SdrDragCrook::SdrDragCrook(SdrDragView
& rNewView
)
2810 : SdrDragMethod(rNewView
),
2812 bContortionAllowed(false),
2813 bNoContortionAllowed(false),
2815 bResizeAllowed(false),
2817 bRotateAllowed(false),
2828 eMode(SDRCROOK_ROTATE
)
2832 void SdrDragCrook::TakeSdrDragComment(XubString
& rStr
) const
2834 ImpTakeDescriptionStr(!bContortion
? STR_DragMethCrook
: STR_DragMethCrookContortion
, rStr
);
2838 rStr
.AppendAscii(" (");
2840 sal_Int32
nVal(nWink
);
2845 nVal
= std::abs(nVal
);
2847 getSdrDragView().GetModel()->TakeWinkStr(nVal
, aStr
);
2849 rStr
+= sal_Unicode(')');
2852 if(getSdrDragView().IsDragWithCopy())
2853 rStr
+= ImpGetResStr(STR_EditWithCopy
);
2856 // These defines parameterize the created raster
2858 #define DRAG_CROOK_RASTER_MINIMUM (4)
2859 #define DRAG_CROOK_RASTER_MAXIMUM (15)
2860 #define DRAG_CROOK_RASTER_DISTANCE (30)
2862 basegfx::B2DPolyPolygon
impCreateDragRaster(SdrPageView
& rPageView
, const Rectangle
& rMarkRect
)
2864 basegfx::B2DPolyPolygon aRetval
;
2866 if(rPageView
.PageWindowCount())
2868 OutputDevice
& rOut
= (rPageView
.GetPageWindow(0)->GetPaintWindow().GetOutputDevice());
2869 Rectangle aPixelSize
= rOut
.LogicToPixel(rMarkRect
);
2870 sal_uInt32
nHorDiv(aPixelSize
.GetWidth() / DRAG_CROOK_RASTER_DISTANCE
);
2871 sal_uInt32
nVerDiv(aPixelSize
.GetHeight() / DRAG_CROOK_RASTER_DISTANCE
);
2873 if(nHorDiv
> DRAG_CROOK_RASTER_MAXIMUM
)
2874 nHorDiv
= DRAG_CROOK_RASTER_MAXIMUM
;
2875 if(nHorDiv
< DRAG_CROOK_RASTER_MINIMUM
)
2876 nHorDiv
= DRAG_CROOK_RASTER_MINIMUM
;
2878 if(nVerDiv
> DRAG_CROOK_RASTER_MAXIMUM
)
2879 nVerDiv
= DRAG_CROOK_RASTER_MAXIMUM
;
2880 if(nVerDiv
< DRAG_CROOK_RASTER_MINIMUM
)
2881 nVerDiv
= DRAG_CROOK_RASTER_MINIMUM
;
2883 const double fXLen(rMarkRect
.GetWidth() / (double)nHorDiv
);
2884 const double fYLen(rMarkRect
.GetHeight() / (double)nVerDiv
);
2885 double fYPos(rMarkRect
.Top());
2888 for(a
= 0; a
<= nVerDiv
; a
++)
2891 for(b
= 0; b
< nHorDiv
; b
++)
2893 basegfx::B2DPolygon aHorLineSegment
;
2895 const double fNewX(rMarkRect
.Left() + (b
* fXLen
));
2896 aHorLineSegment
.append(basegfx::B2DPoint(fNewX
, fYPos
));
2897 aHorLineSegment
.appendBezierSegment(
2898 basegfx::B2DPoint(fNewX
+ (fXLen
* (1.0 / 3.0)), fYPos
),
2899 basegfx::B2DPoint(fNewX
+ (fXLen
* (2.0 / 3.0)), fYPos
),
2900 basegfx::B2DPoint(fNewX
+ fXLen
, fYPos
));
2901 aRetval
.append(aHorLineSegment
);
2908 double fXPos(rMarkRect
.Left());
2910 for(a
= 0; a
<= nHorDiv
; a
++)
2913 for(b
= 0; b
< nVerDiv
; b
++)
2915 basegfx::B2DPolygon aVerLineSegment
;
2917 const double fNewY(rMarkRect
.Top() + (b
* fYLen
));
2918 aVerLineSegment
.append(basegfx::B2DPoint(fXPos
, fNewY
));
2919 aVerLineSegment
.appendBezierSegment(
2920 basegfx::B2DPoint(fXPos
, fNewY
+ (fYLen
* (1.0 / 3.0))),
2921 basegfx::B2DPoint(fXPos
, fNewY
+ (fYLen
* (2.0 / 3.0))),
2922 basegfx::B2DPoint(fXPos
, fNewY
+ fYLen
));
2923 aRetval
.append(aVerLineSegment
);
2934 void SdrDragCrook::createSdrDragEntries()
2936 // Add extended frame raster first, so it will be behind objects
2937 if(getSdrDragView().GetSdrPageView())
2939 const basegfx::B2DPolyPolygon
aDragRaster(impCreateDragRaster(*getSdrDragView().GetSdrPageView(), GetMarkedRect()));
2941 if(aDragRaster
.count())
2943 addSdrDragEntry(new SdrDragEntryPolyPolygon(aDragRaster
));
2948 SdrDragMethod::createSdrDragEntries();
2951 bool SdrDragCrook::BeginSdrDrag()
2953 bContortionAllowed
=getSdrDragView().IsCrookAllowed(false);
2954 bNoContortionAllowed
=getSdrDragView().IsCrookAllowed(true);
2955 bResizeAllowed
=getSdrDragView().IsResizeAllowed(false);
2956 bRotateAllowed
=getSdrDragView().IsRotateAllowed(false);
2958 if (bContortionAllowed
|| bNoContortionAllowed
)
2960 bVertical
=(GetDragHdlKind()==HDL_LOWER
|| GetDragHdlKind()==HDL_UPPER
);
2961 aMarkRect
=GetMarkedRect();
2962 aMarkCenter
=aMarkRect
.Center();
2963 nMarkSize
=bVertical
? (aMarkRect
.GetHeight()-1) : (aMarkRect
.GetWidth()-1);
2964 aCenter
=aMarkCenter
;
2965 aStart
=DragStat().GetStart();
2975 void SdrDragCrook::_MovAllPoints(basegfx::B2DPolyPolygon
& rTarget
)
2977 SdrPageView
* pPV
= getSdrDragView().GetSdrPageView();
2981 XPolyPolygon
aTempPolyPoly(rTarget
);
2983 if (pPV
->HasMarkedObjPageView())
2985 sal_uInt16 nPolyAnz
=aTempPolyPoly
.Count();
2987 if (!bContortion
&& !getSdrDragView().IsNoDragXorPolys())
2989 sal_uInt16 n1st
=0,nLast
=0;
2992 while (n1st
<nPolyAnz
)
2995 while (nLast
<nPolyAnz
&& aTempPolyPoly
[nLast
].GetPointCount()!=0) nLast
++;
2996 Rectangle
aBound(aTempPolyPoly
[n1st
].GetBoundRect());
2999 for (i
=n1st
+1; i
<nLast
; i
++)
3001 aBound
.Union(aTempPolyPoly
[n1st
].GetBoundRect());
3004 Point
aCtr0(aBound
.Center());
3009 Fraction
aFact1(1,1);
3013 ResizePoint(aCtr1
,aC
,aFact1
,aFact
);
3017 ResizePoint(aCtr1
,aC
,aFact
,aFact1
);
3022 double nSin
=0,nCos
=0;
3024 if (aRad
.X()!=0 && aRad
.Y()!=0)
3030 case SDRCROOK_ROTATE
: CrookRotateXPoint (aCtr1
,NULL
,NULL
,aC
,aRad
,nSin
,nCos
,bVertical
); break;
3031 case SDRCROOK_SLANT
: CrookSlantXPoint (aCtr1
,NULL
,NULL
,aC
,aRad
,nSin
,nCos
,bVertical
); break;
3032 case SDRCROOK_STRETCH
: CrookStretchXPoint(aCtr1
,NULL
,NULL
,aC
,aRad
,nSin
,nCos
,bVertical
,aMarkRect
); break;
3038 for (i
=n1st
; i
<nLast
; i
++)
3042 RotateXPoly(aTempPolyPoly
[i
],aCtr0
,nSin
,nCos
);
3045 aTempPolyPoly
[i
].Move(aCtr1
.X(),aCtr1
.Y());
3055 for (j
=0; j
<nPolyAnz
; j
++)
3057 XPolygon
& aPol
=aTempPolyPoly
[j
];
3058 sal_uInt16 nPtAnz
=aPol
.GetPointCount();
3063 Point
* pPnt
=&aPol
[i
];
3067 if (i
+1<nPtAnz
&& aPol
.IsControl(i
))
3068 { // control point on the left
3076 if (i
<nPtAnz
&& aPol
.IsControl(i
))
3077 { // control point on the right
3082 _MovCrookPoint(*pPnt
,pC1
,pC2
);
3088 rTarget
= aTempPolyPoly
.getB2DPolyPolygon();
3092 void SdrDragCrook::_MovCrookPoint(Point
& rPnt
, Point
* pC1
, Point
* pC2
)
3094 bool bVert
=bVertical
;
3101 Fraction
aFact1(1,1);
3105 ResizePoint(rPnt
,aC
,aFact1
,aFact
);
3108 ResizePoint(*pC1
,aC
,aFact1
,aFact
);
3111 ResizePoint(*pC2
,aC
,aFact1
,aFact
);
3115 ResizePoint(rPnt
,aC
,aFact
,aFact1
);
3118 ResizePoint(*pC1
,aC
,aFact
,aFact1
);
3121 ResizePoint(*pC2
,aC
,aFact
,aFact1
);
3125 if (aRad
.X()!=0 && aRad
.Y()!=0)
3131 case SDRCROOK_ROTATE
: CrookRotateXPoint (rPnt
,pC1
,pC2
,aC
,aRad
,nSin
,nCos
,bVert
); break;
3132 case SDRCROOK_SLANT
: CrookSlantXPoint (rPnt
,pC1
,pC2
,aC
,aRad
,nSin
,nCos
,bVert
); break;
3133 case SDRCROOK_STRETCH
: CrookStretchXPoint(rPnt
,pC1
,pC2
,aC
,aRad
,nSin
,nCos
,bVert
,aMarkRect
); break;
3138 void SdrDragCrook::MoveSdrDrag(const Point
& rPnt
)
3140 if (DragStat().CheckMinMoved(rPnt
))
3143 bool bNeuMoveOnly
=getSdrDragView().IsMoveOnlyDragging();
3145 SdrCrookMode eNeuMode
=getSdrDragView().GetCrookMode();
3146 bool bNeuContortion
=!bNeuMoveOnly
&& ((bContortionAllowed
&& !getSdrDragView().IsCrookNoContortion()) || !bNoContortionAllowed
);
3147 bResize
=!getSdrDragView().IsOrtho() && bResizeAllowed
&& !bNeuMoveOnly
;
3148 bool bNeuRotate
=bRotateAllowed
&& !bNeuContortion
&& !bNeuMoveOnly
&& eNeuMode
==SDRCROOK_ROTATE
;
3152 aPnt
=GetSnapPos(aPnt
);
3154 Point
aNeuCenter(aMarkCenter
.X(),aStart
.Y());
3158 aNeuCenter
.X()=aStart
.X();
3159 aNeuCenter
.Y()=aMarkCenter
.Y();
3162 if (!getSdrDragView().IsCrookAtCenter())
3164 switch (GetDragHdlKind())
3166 case HDL_UPLFT
: aNeuCenter
.X()=aMarkRect
.Right(); bLft
=true; break;
3167 case HDL_UPPER
: aNeuCenter
.Y()=aMarkRect
.Bottom(); bUpr
=true; break;
3168 case HDL_UPRGT
: aNeuCenter
.X()=aMarkRect
.Left(); bRgt
=true; break;
3169 case HDL_LEFT
: aNeuCenter
.X()=aMarkRect
.Right(); bLft
=true; break;
3170 case HDL_RIGHT
: aNeuCenter
.X()=aMarkRect
.Left(); bRgt
=true; break;
3171 case HDL_LWLFT
: aNeuCenter
.X()=aMarkRect
.Right(); bLft
=true; break;
3172 case HDL_LOWER
: aNeuCenter
.Y()=aMarkRect
.Top(); bLwr
=true; break;
3173 case HDL_LWRGT
: aNeuCenter
.X()=aMarkRect
.Left(); bRgt
=true; break;
3174 default: bAtCenter
=true;
3180 Fraction
aNeuFact(1,1);
3181 long dx1
=aPnt
.X()-aNeuCenter
.X();
3182 long dy1
=aPnt
.Y()-aNeuCenter
.Y();
3183 bValid
=bVertical
? dx1
!=0 : dy1
!=0;
3188 bValid
= std::abs(dx1
)*100>std::abs(dy1
);
3190 bValid
= std::abs(dy1
)*100>std::abs(dx1
);
3198 double a
=0; // slope of the radius
3203 a
=((double)dy1
)/((double)dx1
); // slope of the radius
3204 nNeuRad
=((long)(dy1
*a
)+dx1
) /2;
3205 aNeuCenter
.X()+=nNeuRad
;
3206 nPntWink
=GetAngle(aPnt
-aNeuCenter
);
3210 a
=((double)dx1
)/((double)dy1
); // slope of the radius
3211 nNeuRad
=((long)(dx1
*a
)+dy1
) /2;
3212 aNeuCenter
.Y()+=nNeuRad
;
3213 nPntWink
=GetAngle(aPnt
-aNeuCenter
)-9000;
3220 if (bRgt
) nPntWink
+=18000;
3221 if (bLft
) nPntWink
=18000-nPntWink
;
3222 if (bLwr
) nPntWink
=-nPntWink
;
3226 if (bRgt
) nPntWink
=-nPntWink
;
3227 if (bUpr
) nPntWink
=18000-nPntWink
;
3228 if (bLwr
) nPntWink
+=18000;
3231 nPntWink
=NormAngle360(nPntWink
);
3235 if (nNeuRad
<0) nPntWink
+=18000;
3236 if (bVertical
) nPntWink
=18000-nPntWink
;
3237 nPntWink
=NormAngle180(nPntWink
);
3238 nPntWink
= std::abs(nPntWink
);
3241 double nUmfang
= 2 * std::abs(nNeuRad
)*nPi
;
3247 long nWink0
=nPntWink
;
3257 aNeuCenter
.X()=aStart
.X()+nNeuRad
;
3259 aNeuCenter
.Y()=aStart
.Y()+nNeuRad
;
3262 long nMul
=(long)(nUmfang
*NormAngle360(nPntWink
)/36000);
3267 aNeuFact
=Fraction(nMul
,nMarkSize
);
3272 nWink
=(long)((nMarkSize
*360/nUmfang
)*100)/2;
3277 if (bValid
&& nSA
!=0)
3289 aNeuCenter
.X()=aStart
.X()+nNeuRad
;
3291 aNeuCenter
.Y()=aStart
.Y()+nNeuRad
;
3296 if (nWink
==0 || nNeuRad
==0)
3302 if (!bValid
&& bResize
)
3304 long nMul
=bVertical
? dy1
: dx1
;
3309 long nDiv
=nMarkSize
;
3314 nMul
= std::abs(nMul
);
3317 aNeuFact
=Fraction(nMul
,nDiv
);
3320 if (aNeuCenter
!=aCenter
|| bNeuContortion
!=bContortion
|| aNeuFact
!=aFact
||
3321 bNeuMoveOnly
!= getMoveOnly() || bNeuRotate
!=bRotate
|| eNeuMode
!=eMode
)
3324 setMoveOnly(bNeuMoveOnly
);
3327 bContortion
=bNeuContortion
;
3330 aRad
=Point(nNeuRad
,nNeuRad
);
3331 bResize
=aFact
!=Fraction(1,1) && aFact
.GetDenominator()!=0 && aFact
.IsValid();
3332 DragStat().NextMove(aPnt
);
3338 void SdrDragCrook::applyCurrentTransformationToSdrObject(SdrObject
& rTarget
)
3340 const bool bDoResize(aFact
!=Fraction(1,1));
3341 const bool bDoCrook(aCenter
!=aMarkCenter
&& aRad
.X()!=0 && aRad
.Y()!=0);
3343 if (bDoCrook
|| bDoResize
)
3347 Fraction
aFact1(1,1);
3353 rTarget
.Resize(aCenter
,aFact1
,aFact
);
3357 rTarget
.Resize(aCenter
,aFact
,aFact1
);
3362 Point
aCtr0(rTarget
.GetSnapRect().Center());
3367 ResizePoint(aCtr1
,aCenter
,aFact1
,aFact
);
3371 ResizePoint(aCtr1
,aCenter
,aFact
,aFact1
);
3374 Size
aSiz(aCtr1
.X()-aCtr0
.X(),aCtr1
.Y()-aCtr0
.Y());
3382 const Rectangle
aLocalMarkRect(getSdrDragView().GetMarkedObjRect());
3383 const bool bLocalRotate(!bContortion
&& eMode
== SDRCROOK_ROTATE
&& getSdrDragView().IsRotateAllowed(false));
3385 getSdrDragView().ImpCrookObj(&rTarget
,aCenter
,aRad
,eMode
,bVertical
,!bContortion
,bLocalRotate
,aLocalMarkRect
);
3390 void SdrDragCrook::applyCurrentTransformationToPolyPolygon(basegfx::B2DPolyPolygon
& rTarget
)
3392 // use helper derived from old stuff
3393 _MovAllPoints(rTarget
);
3396 bool SdrDragCrook::EndSdrDrag(bool bCopy
)
3400 if (bResize
&& aFact
==Fraction(1,1))
3403 const bool bUndo
= getSdrDragView().IsUndoEnabled();
3405 bool bDoCrook
=aCenter
!=aMarkCenter
&& aRad
.X()!=0 && aRad
.Y()!=0;
3407 if (bDoCrook
|| bResize
)
3409 if (bResize
&& bUndo
)
3412 ImpTakeDescriptionStr(!bContortion
?STR_EditCrook
:STR_EditCrookContortion
,aStr
);
3415 aStr
+=ImpGetResStr(STR_EditWithCopy
);
3417 getSdrDragView().BegUndo(aStr
);
3422 Fraction
aFact1(1,1);
3427 getSdrDragView().ResizeMarkedObj(aCenter
,aFact1
,aFact
,bCopy
);
3429 getSdrDragView().ResizeMarkedObj(aCenter
,aFact
,aFact1
,bCopy
);
3434 getSdrDragView().CopyMarkedObj();
3436 sal_uLong nMarkAnz
=getSdrDragView().GetMarkedObjectList().GetMarkCount();
3438 for (sal_uLong nm
=0; nm
<nMarkAnz
; nm
++)
3440 SdrMark
* pM
=getSdrDragView().GetMarkedObjectList().GetMark(nm
);
3441 SdrObject
* pO
=pM
->GetMarkedSdrObj();
3442 Point
aCtr0(pO
->GetSnapRect().Center());
3446 ResizePoint(aCtr1
,aCenter
,aFact1
,aFact
);
3448 ResizePoint(aCtr1
,aCenter
,aFact
,aFact1
);
3450 Size
aSiz(aCtr1
.X()-aCtr0
.X(),aCtr1
.Y()-aCtr0
.Y());
3452 AddUndo(getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoMoveObject(*pO
,aSiz
));
3462 getSdrDragView().CrookMarkedObj(aCenter
,aRad
,eMode
,bVertical
,!bContortion
,bCopy
);
3463 getSdrDragView().SetLastCrookCenter(aCenter
);
3466 if (bResize
&& bUndo
)
3467 getSdrDragView().EndUndo();
3475 Pointer
SdrDragCrook::GetSdrDragPointer() const
3477 return Pointer(POINTER_CROOK
);
3480 ////////////////////////////////////////////////////////////////////////////////////////////////////
3482 TYPEINIT1(SdrDragDistort
,SdrDragMethod
);
3484 SdrDragDistort::SdrDragDistort(SdrDragView
& rNewView
)
3485 : SdrDragMethod(rNewView
),
3487 bContortionAllowed(false),
3488 bNoContortionAllowed(false),
3493 void SdrDragDistort::TakeSdrDragComment(XubString
& rStr
) const
3495 ImpTakeDescriptionStr(STR_DragMethDistort
, rStr
);
3499 rStr
.AppendAscii(" (x=");
3500 getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDX(), aStr
);
3502 rStr
.AppendAscii(" y=");
3503 getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDY(), aStr
);
3505 rStr
+= sal_Unicode(')');
3507 if(getSdrDragView().IsDragWithCopy())
3508 rStr
+= ImpGetResStr(STR_EditWithCopy
);
3511 void SdrDragDistort::createSdrDragEntries()
3513 // Add extended frame raster first, so it will be behind objects
3514 if(getSdrDragView().GetSdrPageView())
3516 const basegfx::B2DPolyPolygon
aDragRaster(impCreateDragRaster(*getSdrDragView().GetSdrPageView(), GetMarkedRect()));
3518 if(aDragRaster
.count())
3520 addSdrDragEntry(new SdrDragEntryPolyPolygon(aDragRaster
));
3525 SdrDragMethod::createSdrDragEntries();
3528 bool SdrDragDistort::BeginSdrDrag()
3530 bContortionAllowed
=getSdrDragView().IsDistortAllowed(false);
3531 bNoContortionAllowed
=getSdrDragView().IsDistortAllowed(true);
3533 if (bContortionAllowed
|| bNoContortionAllowed
)
3535 SdrHdlKind eKind
=GetDragHdlKind();
3538 if (eKind
==HDL_UPLFT
) nPolyPt
=0;
3539 if (eKind
==HDL_UPRGT
) nPolyPt
=1;
3540 if (eKind
==HDL_LWRGT
) nPolyPt
=2;
3541 if (eKind
==HDL_LWLFT
) nPolyPt
=3;
3542 if (nPolyPt
>3) return false;
3544 aMarkRect
=GetMarkedRect();
3545 aDistortedRect
=XPolygon(aMarkRect
);
3555 void SdrDragDistort::_MovAllPoints(basegfx::B2DPolyPolygon
& rTarget
)
3559 SdrPageView
* pPV
= getSdrDragView().GetSdrPageView();
3563 if (pPV
->HasMarkedObjPageView())
3565 basegfx::B2DPolyPolygon
aDragPolygon(rTarget
);
3566 const basegfx::B2DRange
aOriginalRange(aMarkRect
.Left(), aMarkRect
.Top(), aMarkRect
.Right(), aMarkRect
.Bottom());
3567 const basegfx::B2DPoint
aTopLeft(aDistortedRect
[0].X(), aDistortedRect
[0].Y());
3568 const basegfx::B2DPoint
aTopRight(aDistortedRect
[1].X(), aDistortedRect
[1].Y());
3569 const basegfx::B2DPoint
aBottomLeft(aDistortedRect
[3].X(), aDistortedRect
[3].Y());
3570 const basegfx::B2DPoint
aBottomRight(aDistortedRect
[2].X(), aDistortedRect
[2].Y());
3572 aDragPolygon
= basegfx::tools::distort(aDragPolygon
, aOriginalRange
, aTopLeft
, aTopRight
, aBottomLeft
, aBottomRight
);
3573 rTarget
= aDragPolygon
;
3579 void SdrDragDistort::MoveSdrDrag(const Point
& rPnt
)
3581 if (DragStat().CheckMinMoved(rPnt
))
3583 Point
aPnt(GetSnapPos(rPnt
));
3585 if (getSdrDragView().IsOrtho())
3586 OrthoDistance8(DragStat().GetStart(),aPnt
,getSdrDragView().IsBigOrtho());
3588 bool bNeuContortion
=(bContortionAllowed
&& !getSdrDragView().IsCrookNoContortion()) || !bNoContortionAllowed
;
3590 if (bNeuContortion
!=bContortion
|| aDistortedRect
[nPolyPt
]!=aPnt
)
3593 aDistortedRect
[nPolyPt
]=aPnt
;
3594 bContortion
=bNeuContortion
;
3595 DragStat().NextMove(aPnt
);
3601 bool SdrDragDistort::EndSdrDrag(bool bCopy
)
3604 bool bDoDistort
=DragStat().GetDX()!=0 || DragStat().GetDY()!=0;
3608 getSdrDragView().DistortMarkedObj(aMarkRect
,aDistortedRect
,!bContortion
,bCopy
);
3615 Pointer
SdrDragDistort::GetSdrDragPointer() const
3617 return Pointer(POINTER_REFHAND
);
3620 void SdrDragDistort::applyCurrentTransformationToSdrObject(SdrObject
& rTarget
)
3622 const bool bDoDistort(DragStat().GetDX()!=0 || DragStat().GetDY()!=0);
3626 getSdrDragView().ImpDistortObj(&rTarget
, aMarkRect
, aDistortedRect
, !bContortion
);
3630 void SdrDragDistort::applyCurrentTransformationToPolyPolygon(basegfx::B2DPolyPolygon
& rTarget
)
3632 // use helper derived from old stuff
3633 _MovAllPoints(rTarget
);
3636 ////////////////////////////////////////////////////////////////////////////////////////////////////
3638 TYPEINIT1(SdrDragCrop
,SdrDragResize
);
3640 SdrDragCrop::SdrDragCrop(SdrDragView
& rNewView
)
3641 : SdrDragResize(rNewView
)
3643 // switch off solid dragging for crop; it just makes no sense since showing
3644 // a 50% transparent object above the original will not be visible
3645 setSolidDraggingActive(false);
3648 void SdrDragCrop::TakeSdrDragComment(XubString
& rStr
) const
3650 ImpTakeDescriptionStr(STR_DragMethCrop
, rStr
);
3654 rStr
.AppendAscii(" (x=");
3655 getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDX(), aStr
);
3657 rStr
.AppendAscii(" y=");
3658 getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDY(), aStr
);
3660 rStr
+= sal_Unicode(')');
3662 if(getSdrDragView().IsDragWithCopy())
3663 rStr
+= ImpGetResStr(STR_EditWithCopy
);
3666 bool SdrDragCrop::EndSdrDrag(bool bCopy
)
3670 if( DragStat().GetDX()==0 && DragStat().GetDY()==0 )
3673 const SdrMarkList
& rMarkList
= getSdrDragView().GetMarkedObjectList();
3675 if( rMarkList
.GetMarkCount() != 1 )
3678 SdrGrafObj
* pObj
= dynamic_cast<SdrGrafObj
*>( rMarkList
.GetMark( 0 )->GetMarkedSdrObj() );
3680 if( !pObj
|| (pObj
->GetGraphicType() == GRAPHIC_NONE
) || (pObj
->GetGraphicType() == GRAPHIC_DEFAULT
) )
3683 const GraphicObject
& rGraphicObject
= pObj
->GetGraphicObject();
3684 const MapMode
aMapMode100thmm(MAP_100TH_MM
);
3685 Size
aGraphicSize(rGraphicObject
.GetPrefSize());
3687 if( MAP_PIXEL
== rGraphicObject
.GetPrefMapMode().GetMapUnit() )
3688 aGraphicSize
= Application::GetDefaultDevice()->PixelToLogic( aGraphicSize
, aMapMode100thmm
);
3690 aGraphicSize
= Application::GetDefaultDevice()->LogicToLogic( aGraphicSize
, rGraphicObject
.GetPrefMapMode(), aMapMode100thmm
);
3692 if( aGraphicSize
.A() == 0 || aGraphicSize
.B() == 0 )
3695 const SdrGrafCropItem
& rOldCrop
= (const SdrGrafCropItem
&)pObj
->GetMergedItem(SDRATTR_GRAFCROP
);
3697 const bool bUndo
= getSdrDragView().IsUndoEnabled();
3702 ImpTakeDescriptionStr(STR_DragMethCrop
, aUndoStr
);
3704 getSdrDragView().BegUndo( aUndoStr
);
3705 getSdrDragView().AddUndo( getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoGeoObject( *pObj
) );
3708 Rectangle
aOldRect( pObj
->GetLogicRect() );
3709 getSdrDragView().ResizeMarkedObj(DragStat().Ref1(),aXFact
,aYFact
,bCopy
);
3710 Rectangle
aNewRect( pObj
->GetLogicRect() );
3712 double fScaleX
= ( aGraphicSize
.Width() - rOldCrop
.GetLeft() - rOldCrop
.GetRight() ) / (double)aOldRect
.GetWidth();
3713 double fScaleY
= ( aGraphicSize
.Height() - rOldCrop
.GetTop() - rOldCrop
.GetBottom() ) / (double)aOldRect
.GetHeight();
3715 // to correct the never working combination of cropped images and mirroring
3716 // I have to correct the rectangles the calculation is based on here. In the current
3717 // core geometry stuff a vertical mirror is expressed as 180 degree rotation. All
3718 // this can be removed again when aw080 will have cleaned up the old
3719 // (non-)transformation mess in the core.
3720 if(18000 == pObj
->GetGeoStat().nDrehWink
)
3722 // old notation of vertical mirror, need to correct diffs since both rects
3723 // are rotated by 180 degrees
3724 aOldRect
= Rectangle(aOldRect
.TopLeft() - (aOldRect
.BottomRight() - aOldRect
.TopLeft()), aOldRect
.TopLeft());
3725 aNewRect
= Rectangle(aNewRect
.TopLeft() - (aNewRect
.BottomRight() - aNewRect
.TopLeft()), aNewRect
.TopLeft());
3728 sal_Int32 nDiffLeft
= aNewRect
.Left() - aOldRect
.Left();
3729 sal_Int32 nDiffTop
= aNewRect
.Top() - aOldRect
.Top();
3730 sal_Int32 nDiffRight
= aNewRect
.Right() - aOldRect
.Right();
3731 sal_Int32 nDiffBottom
= aNewRect
.Bottom() - aOldRect
.Bottom();
3733 sal_Int32 nLeftCrop
= static_cast<sal_Int32
>( rOldCrop
.GetLeft() + nDiffLeft
* fScaleX
);
3734 sal_Int32 nTopCrop
= static_cast<sal_Int32
>( rOldCrop
.GetTop() + nDiffTop
* fScaleY
);
3735 sal_Int32 nRightCrop
= static_cast<sal_Int32
>( rOldCrop
.GetRight() - nDiffRight
* fScaleX
);
3736 sal_Int32 nBottomCrop
= static_cast<sal_Int32
>( rOldCrop
.GetBottom() - nDiffBottom
* fScaleY
);
3738 SfxItemPool
& rPool
= getSdrDragView().GetModel()->GetItemPool();
3739 SfxItemSet
aSet( rPool
, SDRATTR_GRAFCROP
, SDRATTR_GRAFCROP
);
3740 aSet
.Put( SdrGrafCropItem( nLeftCrop
, nTopCrop
, nRightCrop
, nBottomCrop
) );
3741 getSdrDragView().SetAttributes( aSet
, false );
3744 getSdrDragView().EndUndo();
3749 Pointer
SdrDragCrop::GetSdrDragPointer() const
3751 return Pointer(POINTER_CROP
);
3754 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */