xref: /aoo41x/main/svx/source/svdraw/svddrgmt.cxx (revision ddde725d)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svx.hxx"
26 
27 #include "svddrgm1.hxx"
28 #include <math.h>
29 
30 #ifndef _MATH_H
31 #define _MATH_H
32 #endif
33 #include <tools/bigint.hxx>
34 #include <vcl/svapp.hxx>
35 
36 #include "svx/xattr.hxx"
37 #include <svx/xpoly.hxx>
38 #include <svx/svdetc.hxx>
39 #include <svx/svdtrans.hxx>
40 #include <svx/svdundo.hxx>
41 #include <svx/svdmark.hxx>
42 #include <svx/svdocapt.hxx>
43 #include <svx/svdpagv.hxx>
44 #include "svx/svdstr.hrc"   // Namen aus der Resource
45 #include "svx/svdglob.hxx"  // StringCache
46 #include <svx/svddrgv.hxx>
47 #include <svx/svdundo.hxx>
48 #include <svx/svdograf.hxx>
49 #include <svx/dialogs.hrc>
50 #include <svx/dialmgr.hxx>
51 #include <svx/sdgcpitm.hxx>
52 #include <basegfx/polygon/b2dpolygon.hxx>
53 #include <basegfx/polygon/b2dpolygontools.hxx>
54 #include <svx/sdr/overlay/overlaypolypolygon.hxx>
55 #include <svx/sdr/overlay/overlaymanager.hxx>
56 #include <svx/sdr/overlay/overlayrollingrectangle.hxx>
57 #include <svx/sdrpagewindow.hxx>
58 #include <svx/sdrpaintwindow.hxx>
59 #include <basegfx/matrix/b2dhommatrix.hxx>
60 #include <basegfx/polygon/b2dpolypolygontools.hxx>
61 #include <svx/sdr/contact/viewobjectcontact.hxx>
62 #include <svx/sdr/contact/viewcontact.hxx>
63 #include <svx/sdr/contact/displayinfo.hxx>
64 #include <svx/sdr/overlay/overlayprimitive2dsequenceobject.hxx>
65 #include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx>
66 #include <svx/sdr/contact/objectcontact.hxx>
67 #include "svx/svditer.hxx"
68 #include <svx/svdopath.hxx>
69 #include <svx/polypolygoneditor.hxx>
70 #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
71 #include <drawinglayer/primitive2d/transformprimitive2d.hxx>
72 #include <drawinglayer/primitive2d/markerarrayprimitive2d.hxx>
73 #include <svx/sdr/primitive2d/sdrattributecreator.hxx>
74 #include <svx/sdr/primitive2d/sdrdecompositiontools.hxx>
75 #include <svx/svdoole2.hxx>
76 #include <svx/svdovirt.hxx>
77 #include <svx/svdouno.hxx>
78 #include <svx/sdr/primitive2d/sdrprimitivetools.hxx>
79 #include <basegfx/matrix/b2dhommatrixtools.hxx>
80 #include <drawinglayer/attribute/sdrlineattribute.hxx>
81 #include <drawinglayer/attribute/sdrlinestartendattribute.hxx>
82 
83 ////////////////////////////////////////////////////////////////////////////////////////////////////
84 
85 SdrDragEntry::SdrDragEntry()
86 :	mbAddToTransparent(false)
87 {
88 }
89 
90 SdrDragEntry::~SdrDragEntry()
91 {
92 }
93 
94 ////////////////////////////////////////////////////////////////////////////////////////////////////
95 
96 SdrDragEntryPolyPolygon::SdrDragEntryPolyPolygon(const basegfx::B2DPolyPolygon& rOriginalPolyPolygon)
97 :   SdrDragEntry(),
98     maOriginalPolyPolygon(rOriginalPolyPolygon)
99 {
100 }
101 
102 SdrDragEntryPolyPolygon::~SdrDragEntryPolyPolygon()
103 {
104 }
105 
106 drawinglayer::primitive2d::Primitive2DSequence SdrDragEntryPolyPolygon::createPrimitive2DSequenceInCurrentState(SdrDragMethod& rDragMethod)
107 {
108 	drawinglayer::primitive2d::Primitive2DSequence aRetval;
109 
110 	if(maOriginalPolyPolygon.count())
111 	{
112 	    basegfx::B2DPolyPolygon aCopy(maOriginalPolyPolygon);
113 		const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
114 
115 		rDragMethod.applyCurrentTransformationToPolyPolygon(aCopy);
116 		basegfx::BColor aColA(aSvtOptionsDrawinglayer.GetStripeColorA().getBColor());
117 		basegfx::BColor aColB(aSvtOptionsDrawinglayer.GetStripeColorB().getBColor());
118 		const double fStripeLength(aSvtOptionsDrawinglayer.GetStripeLength());
119 
120 		if(Application::GetSettings().GetStyleSettings().GetHighContrastMode())
121 		{
122 			aColA = aColB = Application::GetSettings().GetStyleSettings().GetHighlightColor().getBColor();
123 			aColB.invert();
124 		}
125 
126 		drawinglayer::primitive2d::Primitive2DReference aPolyPolygonMarkerPrimitive2D(
127 			new drawinglayer::primitive2d::PolyPolygonMarkerPrimitive2D(aCopy, aColA, aColB, fStripeLength));
128 
129 		aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aPolyPolygonMarkerPrimitive2D, 1);
130 	}
131 
132 	return aRetval;
133 }
134 
135 ////////////////////////////////////////////////////////////////////////////////////////////////////
136 
137 SdrDragEntrySdrObject::SdrDragEntrySdrObject(const SdrObject& rOriginal, sdr::contact::ObjectContact& rObjectContact, bool bModify)
138 :   SdrDragEntry(),
139     maOriginal(rOriginal),
140     mpClone(0),
141     mrObjectContact(rObjectContact),
142 	mbModify(bModify)
143 {
144 	// add SdrObject parts to transparent overlay stuff
145 	setAddToTransparent(true);
146 }
147 
148 SdrDragEntrySdrObject::~SdrDragEntrySdrObject()
149 {
150     if(mpClone)
151     {
152         SdrObject::Free(mpClone);
153     }
154 }
155 
156 drawinglayer::primitive2d::Primitive2DSequence SdrDragEntrySdrObject::createPrimitive2DSequenceInCurrentState(SdrDragMethod& rDragMethod)
157 {
158 	// for the moment, i need to re-create the clone in all cases. I need to figure
159 	// out when clone and original have the same class, so that i can use operator=
160 	// in those cases
161 
162     //        // copy all other needed stuff
163     //        basegfx::B2DHomMatrix aMatrix;
164     //        basegfx::B2DPolyPolygon aPolyPolygon;
165     //	    pOleObject->TRGetBaseGeometry(aMatrix, aPolyPolygon);
166     //        pClone->TRSetBaseGeometry(aMatrix, aPolyPolygon);
167 
168 	const SdrObject* pSource = &maOriginal;
169 
170 	if(mpClone)
171     {
172         SdrObject::Free(mpClone);
173 		mpClone = 0;
174     }
175 
176 	if(mbModify)
177 	{
178 		if(!mpClone)
179 		{
180 			mpClone = maOriginal.getFullDragClone();
181 		}
182 
183 		// apply original transformation, implemented at the DragMethods
184 		rDragMethod.applyCurrentTransformationToSdrObject(*mpClone);
185 
186 		// choose source for geometry data
187 		pSource = mpClone;
188 	}
189 
190     // get VOC and Primitive2DSequence
191     sdr::contact::ViewContact& rVC = pSource->GetViewContact();
192     sdr::contact::ViewObjectContact& rVOC = rVC.GetViewObjectContact(mrObjectContact);
193     sdr::contact::DisplayInfo aDisplayInfo;
194 
195     // Do not use the last ViewPort set at the OC from the last ProcessDisplay(),
196     // here we want the complete primitive sequence without visibility clippings
197     mrObjectContact.resetViewPort();
198 
199     return rVOC.getPrimitive2DSequenceHierarchy(aDisplayInfo);
200 }
201 
202 ////////////////////////////////////////////////////////////////////////////////////////////////////
203 
204 SdrDragEntryPrimitive2DSequence::SdrDragEntryPrimitive2DSequence(
205     const drawinglayer::primitive2d::Primitive2DSequence& rSequence,
206     bool bAddToTransparent)
207 :   SdrDragEntry(),
208     maPrimitive2DSequence(rSequence)
209 {
210 	// add parts to transparent overlay stuff eventually
211 	setAddToTransparent(bAddToTransparent);
212 }
213 
214 SdrDragEntryPrimitive2DSequence::~SdrDragEntryPrimitive2DSequence()
215 {
216 }
217 
218 drawinglayer::primitive2d::Primitive2DSequence SdrDragEntryPrimitive2DSequence::createPrimitive2DSequenceInCurrentState(SdrDragMethod& rDragMethod)
219 {
220 	drawinglayer::primitive2d::Primitive2DReference aTransformPrimitive2D(
221         new drawinglayer::primitive2d::TransformPrimitive2D(
222             rDragMethod.getCurrentTransformation(),
223             maPrimitive2DSequence));
224 
225     return drawinglayer::primitive2d::Primitive2DSequence(&aTransformPrimitive2D, 1);
226 }
227 
228 ////////////////////////////////////////////////////////////////////////////////////////////////////
229 
230 SdrDragEntryPointGlueDrag::SdrDragEntryPointGlueDrag(const std::vector< basegfx::B2DPoint >& rPositions, bool bIsPointDrag)
231 :   maPositions(rPositions),
232     mbIsPointDrag(bIsPointDrag)
233 {
234 	// add SdrObject parts to transparent overlay stuff
235 	setAddToTransparent(true);
236 }
237 
238 SdrDragEntryPointGlueDrag::~SdrDragEntryPointGlueDrag()
239 {
240 }
241 
242 drawinglayer::primitive2d::Primitive2DSequence SdrDragEntryPointGlueDrag::createPrimitive2DSequenceInCurrentState(SdrDragMethod& rDragMethod)
243 {
244 	drawinglayer::primitive2d::Primitive2DSequence aRetval;
245 
246     if(!maPositions.empty())
247     {
248         basegfx::B2DPolygon aPolygon;
249         sal_uInt32 a(0);
250 
251         for(a = 0; a < maPositions.size(); a++)
252         {
253             aPolygon.append(maPositions[a]);
254         }
255 
256         basegfx::B2DPolyPolygon aPolyPolygon(aPolygon);
257 
258         rDragMethod.applyCurrentTransformationToPolyPolygon(aPolyPolygon);
259 
260         const basegfx::B2DPolygon aTransformed(aPolyPolygon.getB2DPolygon(0));
261         std::vector< basegfx::B2DPoint > aTransformedPositions;
262 
263         aTransformedPositions.reserve(aTransformed.count());
264 
265         for(a = 0; a < aTransformed.count(); a++)
266         {
267             aTransformedPositions.push_back(aTransformed.getB2DPoint(a));
268         }
269 
270         if(mbIsPointDrag)
271         {
272 		    const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
273 		    basegfx::BColor aColor(aSvtOptionsDrawinglayer.GetStripeColorA().getBColor());
274 
275 		    if(Application::GetSettings().GetStyleSettings().GetHighContrastMode())
276 		    {
277 			    aColor = Application::GetSettings().GetStyleSettings().GetHighlightColor().getBColor();
278 		    }
279 
280             drawinglayer::primitive2d::Primitive2DReference aMarkerArrayPrimitive2D(
281 			    new drawinglayer::primitive2d::MarkerArrayPrimitive2D(aTransformedPositions,
282 					drawinglayer::primitive2d::createDefaultCross_3x3(aColor)));
283 
284 		    aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aMarkerArrayPrimitive2D, 1);
285         }
286         else
287         {
288 			const basegfx::BColor aBackPen(1.0, 1.0, 1.0);
289 			const basegfx::BColor aRGBFrontColor(0.0, 0.0, 1.0); // COL_LIGHTBLUE
290             drawinglayer::primitive2d::Primitive2DReference aMarkerArrayPrimitive2D(
291 			    new drawinglayer::primitive2d::MarkerArrayPrimitive2D(aTransformedPositions,
292 					drawinglayer::primitive2d::createDefaultGluepoint_7x7(aBackPen, aRGBFrontColor)));
293 
294 		    aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aMarkerArrayPrimitive2D, 1);
295         }
296     }
297 
298     return aRetval;
299 }
300 
301 ////////////////////////////////////////////////////////////////////////////////////////////////////
302 
303 TYPEINIT0(SdrDragMethod);
304 
305 void SdrDragMethod::resetSdrDragEntries()
306 {
307     // clear entries; creation is on demand
308     clearSdrDragEntries();
309 }
310 
311 basegfx::B2DRange SdrDragMethod::getCurrentRange() const
312 {
313     return getB2DRangeFromOverlayObjectList();
314 }
315 
316 void SdrDragMethod::createSdrDragEntries()
317 {
318 	if(getSdrDragView().GetSdrPageView() && getSdrDragView().GetSdrPageView()->HasMarkedObjPageView())
319 	{
320 	    if(getSdrDragView().IsDraggingPoints())
321 	    {
322             createSdrDragEntries_PointDrag();
323 	    }
324 	    else if(getSdrDragView().IsDraggingGluePoints())
325 	    {
326             createSdrDragEntries_GlueDrag();
327 	    }
328 	    else
329 	    {
330             if(getSolidDraggingActive())
331             {
332                 createSdrDragEntries_SolidDrag();
333             }
334             else
335             {
336                 createSdrDragEntries_PolygonDrag();
337             }
338         }
339     }
340 }
341 
342 void SdrDragMethod::createSdrDragEntryForSdrObject(const SdrObject& rOriginal, sdr::contact::ObjectContact& rObjectContact, bool bModify)
343 {
344     // add full obejct drag; Clone() at the object has to work
345     // for this
346     addSdrDragEntry(new SdrDragEntrySdrObject(rOriginal, rObjectContact, bModify));
347 }
348 
349 void SdrDragMethod::createSdrDragEntries_SolidDrag()
350 {
351     const sal_uInt32 nMarkAnz(getSdrDragView().GetMarkedObjectCount());
352     SdrPageView* pPV = getSdrDragView().GetSdrPageView();
353 
354     if(pPV)
355     {
356         for(sal_uInt32 a(0); a < nMarkAnz; a++)
357         {
358 		    SdrMark* pM = getSdrDragView().GetSdrMarkByIndex(a);
359 
360 		    if(pM->GetPageView() == pPV)
361 		    {
362 			    const SdrObject* pObject = pM->GetMarkedSdrObj();
363 
364                 if(pObject)
365                 {
366                     if(pPV->PageWindowCount())
367                     {
368 	                    sdr::contact::ObjectContact& rOC = pPV->GetPageWindow(0)->GetObjectContact();
369                         SdrObjListIter aIter(*pObject);
370 
371                         while(aIter.IsMore())
372                         {
373                             SdrObject* pCandidate = aIter.Next();
374 
375                             if(pCandidate)
376                             {
377                                 const bool bSuppressFullDrag(!pCandidate->supportsFullDrag());
378                                 bool bAddWireframe(bSuppressFullDrag);
379 
380                                 if(!bAddWireframe && !pCandidate->HasLineStyle())
381                                 {
382 									// add wireframe for objects without outline
383                                     bAddWireframe = true;
384                                 }
385 
386                                 if(!bSuppressFullDrag)
387                                 {
388                                     // add full obejct drag; Clone() at the object has to work
389                                     // for this
390                                     createSdrDragEntryForSdrObject(*pCandidate, rOC, true);
391                                 }
392 
393                                 if(bAddWireframe)
394                                 {
395                                     // when dragging a 50% transparent copy of a filled or not filled object without
396                                     // outline, this is normally hard to see. Add extra wireframe in that case. This
397                                     // works nice e.g. with thext frames etc.
398                                     addSdrDragEntry(new SdrDragEntryPolyPolygon(pCandidate->TakeXorPoly()));
399                                 }
400                             }
401                         }
402                     }
403                 }
404             }
405         }
406     }
407 }
408 
409 void SdrDragMethod::createSdrDragEntries_PolygonDrag()
410 {
411     const sal_uInt32 nMarkAnz(getSdrDragView().GetMarkedObjectCount());
412     bool bNoPolygons(getSdrDragView().IsNoDragXorPolys() || nMarkAnz > getSdrDragView().GetDragXorPolyLimit());
413     basegfx::B2DPolyPolygon aResult;
414     sal_uInt32 nPointCount(0);
415 
416     for(sal_uInt32 a(0); !bNoPolygons && a < nMarkAnz; a++)
417     {
418 		SdrMark* pM = getSdrDragView().GetSdrMarkByIndex(a);
419 
420 		if(pM->GetPageView() == getSdrDragView().GetSdrPageView())
421 		{
422 			const basegfx::B2DPolyPolygon aNewPolyPolygon(pM->GetMarkedSdrObj()->TakeXorPoly());
423 
424             for(sal_uInt32 b(0); b < aNewPolyPolygon.count(); b++)
425             {
426                 nPointCount += aNewPolyPolygon.getB2DPolygon(b).count();
427             }
428 
429             if(nPointCount > getSdrDragView().GetDragXorPointLimit())
430             {
431                 bNoPolygons = true;
432             }
433 
434             if(!bNoPolygons)
435             {
436                 aResult.append(aNewPolyPolygon);
437             }
438         }
439     }
440 
441     if(bNoPolygons)
442     {
443 	    const Rectangle aR(getSdrDragView().GetSdrPageView()->MarkSnap());
444 	    const basegfx::B2DRange aNewRectangle(aR.Left(), aR.Top(), aR.Right(), aR.Bottom());
445 	    basegfx::B2DPolygon aNewPolygon(basegfx::tools::createPolygonFromRect(aNewRectangle));
446 
447         aResult = basegfx::B2DPolyPolygon(basegfx::tools::expandToCurve(aNewPolygon));
448     }
449 
450     if(aResult.count())
451     {
452         addSdrDragEntry(new SdrDragEntryPolyPolygon(aResult));
453     }
454 }
455 
456 void SdrDragMethod::createSdrDragEntries_PointDrag()
457 {
458     const sal_uInt32 nMarkAnz(getSdrDragView().GetMarkedObjectCount());
459     std::vector< basegfx::B2DPoint > aPositions;
460 
461     for(sal_uInt32 nm(0); nm < nMarkAnz; nm++)
462 	{
463 		SdrMark* pM = getSdrDragView().GetSdrMarkByIndex(nm);
464 
465         if(pM->GetPageView() == getSdrDragView().GetSdrPageView())
466 		{
467 			const SdrUShortCont* pPts = pM->GetMarkedPoints();
468 
469             if(pPts && pPts->GetCount())
470 			{
471 				const SdrObject* pObj = pM->GetMarkedSdrObj();
472 				const SdrPathObj* pPath = dynamic_cast< const SdrPathObj* >(pObj);
473 
474                 if(pPath)
475                 {
476 				    const basegfx::B2DPolyPolygon aPathXPP = pPath->GetPathPoly();
477 
478                     if(aPathXPP.count())
479 				    {
480 				        const sal_uInt32 nPtAnz(pPts->GetCount());
481 
482 				        for(sal_uInt32 nPtNum(0); nPtNum < nPtAnz; nPtNum++)
483 				        {
484 					        sal_uInt32 nPolyNum, nPointNum;
485 					        const sal_uInt16 nObjPt(pPts->GetObject(nPtNum));
486 
487                             if(sdr::PolyPolygonEditor::GetRelativePolyPoint(aPathXPP, nObjPt, nPolyNum, nPointNum))
488 					        {
489                                 aPositions.push_back(aPathXPP.getB2DPolygon(nPolyNum).getB2DPoint(nPointNum));
490 					        }
491 					    }
492 				    }
493                 }
494 			}
495 		}
496     }
497 
498     if(!aPositions.empty())
499     {
500         addSdrDragEntry(new SdrDragEntryPointGlueDrag(aPositions, true));
501     }
502 }
503 
504 void SdrDragMethod::createSdrDragEntries_GlueDrag()
505 {
506     const sal_uInt32 nMarkAnz(getSdrDragView().GetMarkedObjectCount());
507     std::vector< basegfx::B2DPoint > aPositions;
508 
509     for(sal_uInt32 nm(0); nm < nMarkAnz; nm++)
510 	{
511 		SdrMark* pM = getSdrDragView().GetSdrMarkByIndex(nm);
512 
513         if(pM->GetPageView() == getSdrDragView().GetSdrPageView())
514 		{
515 			const SdrUShortCont* pPts = pM->GetMarkedGluePoints();
516 
517             if(pPts && pPts->GetCount())
518 			{
519 				const SdrObject* pObj = pM->GetMarkedSdrObj();
520     			const SdrGluePointList* pGPL = pObj->GetGluePointList();
521 
522                 if(pGPL)
523 				{
524 				    const sal_uInt32 nPtAnz(pPts->GetCount());
525 
526 				    for(sal_uInt32 nPtNum(0); nPtNum < nPtAnz; nPtNum++)
527 				    {
528 					    const sal_uInt16 nObjPt(pPts->GetObject(nPtNum));
529 					    const sal_uInt16 nGlueNum(pGPL->FindGluePoint(nObjPt));
530 
531 					    if(SDRGLUEPOINT_NOTFOUND != nGlueNum)
532 					    {
533 						    const Point aPoint((*pGPL)[nGlueNum].GetAbsolutePos(*pObj));
534                             aPositions.push_back(basegfx::B2DPoint(aPoint.X(), aPoint.Y()));
535 					    }
536 				    }
537                 }
538 			}
539 		}
540     }
541 
542     if(!aPositions.empty())
543     {
544         addSdrDragEntry(new SdrDragEntryPointGlueDrag(aPositions, false));
545     }
546 }
547 
548 void SdrDragMethod::ImpTakeDescriptionStr(sal_uInt16 nStrCacheID, XubString& rStr, sal_uInt16 nVal) const
549 {
550 	sal_uInt16 nOpt=0;
551 	if (IsDraggingPoints()) {
552 		nOpt=IMPSDR_POINTSDESCRIPTION;
553 	} else if (IsDraggingGluePoints()) {
554 		nOpt=IMPSDR_GLUEPOINTSDESCRIPTION;
555 	}
556 	getSdrDragView().ImpTakeDescriptionStr(nStrCacheID,rStr,nVal,nOpt);
557 }
558 
559 SdrObject* SdrDragMethod::GetDragObj() const
560 {
561 	SdrObject* pObj=NULL;
562 	if (getSdrDragView().pDragHdl!=NULL) pObj=getSdrDragView().pDragHdl->GetObj();
563 	if (pObj==NULL) pObj=getSdrDragView().pMarkedObj;
564 	return pObj;
565 }
566 
567 SdrPageView* SdrDragMethod::GetDragPV() const
568 {
569 	SdrPageView* pPV=NULL;
570 	if (getSdrDragView().pDragHdl!=NULL) pPV=getSdrDragView().pDragHdl->GetPageView();
571 	if (pPV==NULL) pPV=getSdrDragView().pMarkedPV;
572 	return pPV;
573 }
574 
575 void SdrDragMethod::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
576 {
577     // the original applies the transformation using TRGetBaseGeometry/TRSetBaseGeometry.
578 	// Later this should be the only needed one for linear transforms (not for SdrDragCrook and
579 	// SdrDragDistort, those are NOT linear). Currently, this can not yet be used since the
580 	// special handling of rotate/mirror due to the not-being-able to handle it in the old
581 	// drawinglayer stuff. Text would currently not correctly be mirrored in the preview.
582 	basegfx::B2DHomMatrix aObjectTransform;
583 	basegfx::B2DPolyPolygon aObjectPolyPolygon;
584 	bool bPolyUsed(rTarget.TRGetBaseGeometry(aObjectTransform, aObjectPolyPolygon));
585 
586 	// apply transform to object transform
587 	aObjectTransform *= getCurrentTransformation();
588 
589 	if(bPolyUsed)
590 	{
591 		// do something special since the object size is in the polygon
592 		// break up matrix to get the scale
593 		basegfx::B2DTuple aScale;
594 		basegfx::B2DTuple aTranslate;
595 		double fRotate, fShearX;
596 		aObjectTransform.decompose(aScale, aTranslate, fRotate, fShearX);
597 
598 		// get polygon's pos and size
599 		const basegfx::B2DRange aPolyRange(aObjectPolyPolygon.getB2DRange());
600 
601 		// get the scaling factors (do not mirror, this is in the object transformation)
602 		const double fScaleX(fabs(aScale.getX()) / (basegfx::fTools::equalZero(aPolyRange.getWidth()) ? 1.0 : aPolyRange.getWidth()));
603 		const double fScaleY(fabs(aScale.getY()) / (basegfx::fTools::equalZero(aPolyRange.getHeight()) ? 1.0 : aPolyRange.getHeight()));
604 
605 		// prepare transform matrix for polygon
606         basegfx::B2DHomMatrix aPolyTransform(basegfx::tools::createTranslateB2DHomMatrix(
607             -aPolyRange.getMinX(), -aPolyRange.getMinY()));
608 		aPolyTransform.scale(fScaleX, fScaleY);
609 
610 		// normally the poly should be moved back, but the translation is in the object
611 		// transformation and thus does not need to be done
612 		// aPolyTransform.translate(-aPolyRange.getMinX(), -aPolyRange.getMinY());
613 
614 		// transform the polygon
615 		aObjectPolyPolygon.transform(aPolyTransform);
616 	}
617 
618 	rTarget.TRSetBaseGeometry(getCurrentTransformation() * aObjectTransform, aObjectPolyPolygon);
619 }
620 
621 void SdrDragMethod::applyCurrentTransformationToPolyPolygon(basegfx::B2DPolyPolygon& rTarget)
622 {
623 	// original uses CurrentTransformation
624 	rTarget.transform(getCurrentTransformation());
625 }
626 
627 SdrDragMethod::SdrDragMethod(SdrDragView& rNewView)
628 :	maSdrDragEntries(),
629     maOverlayObjectList(),
630     mrSdrDragView(rNewView),
631 	mbMoveOnly(false),
632 	mbSolidDraggingActive(getSdrDragView().IsSolidDragging())
633 {
634 	if(mbSolidDraggingActive && Application::GetSettings().GetStyleSettings().GetHighContrastMode())
635     {
636         // fallback to wireframe when high contrast is used
637         mbSolidDraggingActive = false;
638     }
639 }
640 
641 SdrDragMethod::~SdrDragMethod()
642 {
643     clearSdrDragEntries();
644 }
645 
646 void SdrDragMethod::Show()
647 {
648 	getSdrDragView().ShowDragObj();
649 }
650 
651 void SdrDragMethod::Hide()
652 {
653 	getSdrDragView().HideDragObj();
654 }
655 
656 basegfx::B2DHomMatrix SdrDragMethod::getCurrentTransformation()
657 {
658 	return basegfx::B2DHomMatrix();
659 }
660 
661 void SdrDragMethod::CancelSdrDrag()
662 {
663 	Hide();
664 }
665 
666 void SdrDragMethod::CreateOverlayGeometry(sdr::overlay::OverlayManager& rOverlayManager)
667 {
668     // create SdrDragEntries on demand
669     if(maSdrDragEntries.empty())
670     {
671         createSdrDragEntries();
672     }
673 
674     // if there are entries, derive OverlayObjects from the entries, including
675     // modification from current interactive state
676     if(!maSdrDragEntries.empty())
677     {
678 		drawinglayer::primitive2d::Primitive2DSequence aResult;
679 		drawinglayer::primitive2d::Primitive2DSequence aResultTransparent;
680 
681 		for(sal_uInt32 a(0); a < maSdrDragEntries.size(); a++)
682         {
683             SdrDragEntry* pCandidate = maSdrDragEntries[a];
684 
685             if(pCandidate)
686             {
687 				const drawinglayer::primitive2d::Primitive2DSequence aCandidateResult(pCandidate->createPrimitive2DSequenceInCurrentState(*this));
688 
689 				if(aCandidateResult.hasElements())
690 				{
691 					if(pCandidate->getAddToTransparent())
692 					{
693 						drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(aResultTransparent, aCandidateResult);
694 					}
695 					else
696 					{
697 						drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(aResult, aCandidateResult);
698 					}
699 				}
700 			}
701 		}
702 
703 		if(DoAddConnectorOverlays())
704 		{
705 			const drawinglayer::primitive2d::Primitive2DSequence aConnectorOverlays(AddConnectorOverlays());
706 
707 			if(aConnectorOverlays.hasElements())
708 			{
709 				// add connector overlays to transparent part
710 				drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(aResultTransparent, aConnectorOverlays);
711 			}
712 		}
713 
714 		if(aResult.hasElements())
715 		{
716 	        sdr::overlay::OverlayObject* pNewOverlayObject = new sdr::overlay::OverlayPrimitive2DSequenceObject(aResult);
717             rOverlayManager.add(*pNewOverlayObject);
718 			addToOverlayObjectList(*pNewOverlayObject);
719 		}
720 
721 		if(aResultTransparent.hasElements())
722 		{
723 			drawinglayer::primitive2d::Primitive2DReference aUnifiedTransparencePrimitive2D(new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(aResultTransparent, 0.5));
724 			aResultTransparent = drawinglayer::primitive2d::Primitive2DSequence(&aUnifiedTransparencePrimitive2D, 1);
725 
726 			sdr::overlay::OverlayObject* pNewOverlayObject = new sdr::overlay::OverlayPrimitive2DSequenceObject(aResultTransparent);
727             rOverlayManager.add(*pNewOverlayObject);
728 			addToOverlayObjectList(*pNewOverlayObject);
729 		}
730 	}
731 
732 	// evtl add DragStripes (help lines cross the page when dragging)
733 	if(getSdrDragView().IsDragStripes())
734 	{
735 		Rectangle aActionRectangle;
736 		getSdrDragView().TakeActionRect(aActionRectangle);
737 
738 		const basegfx::B2DPoint aTopLeft(aActionRectangle.Left(), aActionRectangle.Top());
739 		const basegfx::B2DPoint aBottomRight(aActionRectangle.Right(), aActionRectangle.Bottom());
740 		sdr::overlay::OverlayRollingRectangleStriped* pNew = new sdr::overlay::OverlayRollingRectangleStriped(
741 			aTopLeft, aBottomRight, true, false);
742 
743 		rOverlayManager.add(*pNew);
744 		addToOverlayObjectList(*pNew);
745 	}
746 }
747 
748 void SdrDragMethod::destroyOverlayGeometry()
749 {
750 	clearOverlayObjectList();
751 }
752 
753 bool SdrDragMethod::DoAddConnectorOverlays()
754 {
755 	// these conditions are translated from SdrDragView::ImpDrawEdgeXor
756 	const SdrMarkList& rMarkedNodes = getSdrDragView().GetEdgesOfMarkedNodes();
757 
758 	if(!rMarkedNodes.GetMarkCount())
759 	{
760 		return false;
761 	}
762 
763 	if(!getSdrDragView().IsRubberEdgeDragging() && !getSdrDragView().IsDetailedEdgeDragging())
764 	{
765 		return false;
766 	}
767 
768 	if(getSdrDragView().IsDraggingPoints() || getSdrDragView().IsDraggingGluePoints())
769 	{
770 		return false;
771 	}
772 
773 	if(!getMoveOnly() && !(
774 		IS_TYPE(SdrDragMove, this) || IS_TYPE(SdrDragResize, this) ||
775 		IS_TYPE(SdrDragRotate,this) || IS_TYPE(SdrDragMirror,this)))
776 	{
777 		return false;
778 	}
779 
780 	const bool bDetail(getSdrDragView().IsDetailedEdgeDragging() && getMoveOnly());
781 
782 	if(!bDetail && !getSdrDragView().IsRubberEdgeDragging())
783 	{
784 		return false;
785 	}
786 
787 	// one more migrated from SdrEdgeObj::NspToggleEdgeXor
788 	if(IS_TYPE(SdrDragObjOwn, this) || IS_TYPE(SdrDragMovHdl, this))
789 	{
790 		return false;
791 	}
792 
793 	return true;
794 }
795 
796 drawinglayer::primitive2d::Primitive2DSequence SdrDragMethod::AddConnectorOverlays()
797 {
798 	drawinglayer::primitive2d::Primitive2DSequence aRetval;
799 	const bool bDetail(getSdrDragView().IsDetailedEdgeDragging() && getMoveOnly());
800 	const SdrMarkList& rMarkedNodes = getSdrDragView().GetEdgesOfMarkedNodes();
801 
802 	for(sal_uInt16 a(0); a < rMarkedNodes.GetMarkCount(); a++)
803 	{
804 		SdrMark* pEM = rMarkedNodes.GetMark(a);
805 
806 		if(pEM && pEM->GetMarkedSdrObj())
807 		{
808 			SdrEdgeObj* pEdge = dynamic_cast< SdrEdgeObj* >(pEM->GetMarkedSdrObj());
809 
810 			if(pEdge)
811 			{
812 				const basegfx::B2DPolygon aEdgePolygon(pEdge->ImplAddConnectorOverlay(*this, pEM->IsCon1(), pEM->IsCon2(), bDetail));
813 
814 				if(aEdgePolygon.count())
815 				{
816 					// this polygon is a temporary calculated connector path, so it is not possible to fetch
817 					// the needed primitives directly from the pEdge object which does not get changed. If full
818 					// drag is on, use the SdrObjects ItemSet to create a adequate representation
819                     bool bUseSolidDragging(getSolidDraggingActive());
820 
821                     if(bUseSolidDragging)
822                     {
823                         // switch off solid dragging if connector is not visible
824                         if(!pEdge->HasLineStyle())
825                         {
826                             bUseSolidDragging = false;
827                         }
828                     }
829 
830 		            if(bUseSolidDragging)
831 					{
832 						const SfxItemSet& rItemSet = pEdge->GetMergedItemSet();
833 						const drawinglayer::attribute::SdrLineAttribute aLine(
834 							drawinglayer::primitive2d::createNewSdrLineAttribute(rItemSet));
835 
836 						if(!aLine.isDefault())
837 						{
838 							const drawinglayer::attribute::SdrLineStartEndAttribute aLineStartEnd(
839 								drawinglayer::primitive2d::createNewSdrLineStartEndAttribute(
840 									rItemSet,
841 									aLine.getWidth()));
842 
843 							drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(
844 								aRetval, drawinglayer::primitive2d::createPolygonLinePrimitive(
845 									aEdgePolygon,
846 									basegfx::B2DHomMatrix(),
847 									aLine,
848 									aLineStartEnd));
849 						}
850 					}
851 					else
852 					{
853 						const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
854 						basegfx::BColor aColA(aSvtOptionsDrawinglayer.GetStripeColorA().getBColor());
855 						basegfx::BColor aColB(aSvtOptionsDrawinglayer.GetStripeColorB().getBColor());
856 						const double fStripeLength(aSvtOptionsDrawinglayer.GetStripeLength());
857 
858 						if(Application::GetSettings().GetStyleSettings().GetHighContrastMode())
859 						{
860 							aColA = aColB = Application::GetSettings().GetStyleSettings().GetHighlightColor().getBColor();
861 							aColB.invert();
862 						}
863 
864 						drawinglayer::primitive2d::Primitive2DReference aPolyPolygonMarkerPrimitive2D(
865 							new drawinglayer::primitive2d::PolyPolygonMarkerPrimitive2D(
866 								basegfx::B2DPolyPolygon(aEdgePolygon), aColA, aColB, fStripeLength));
867 				        drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, aPolyPolygonMarkerPrimitive2D);
868 					}
869 				}
870 			}
871 		}
872 	}
873 
874 	return aRetval;
875 }
876 
877 ////////////////////////////////////////////////////////////////////////////////////////////////////
878 
879 TYPEINIT1(SdrDragMovHdl,SdrDragMethod);
880 
881 SdrDragMovHdl::SdrDragMovHdl(SdrDragView& rNewView)
882 :	SdrDragMethod(rNewView),
883 	bMirrObjShown(false)
884 {
885 }
886 
887 void SdrDragMovHdl::createSdrDragEntries()
888 {
889     // SdrDragMovHdl does not use the default drags,
890     // but creates nothing
891 }
892 
893 void SdrDragMovHdl::TakeSdrDragComment(XubString& rStr) const
894 {
895 	rStr=ImpGetResStr(STR_DragMethMovHdl);
896 	if (getSdrDragView().IsDragWithCopy()) rStr+=ImpGetResStr(STR_EditWithCopy);
897 }
898 
899 bool SdrDragMovHdl::BeginSdrDrag()
900 {
901 	if( !GetDragHdl() )
902 		return false;
903 
904 	DragStat().Ref1()=GetDragHdl()->GetPos();
905 	DragStat().SetShown(!DragStat().IsShown());
906 	SdrHdlKind eKind=GetDragHdl()->GetKind();
907 	SdrHdl* pH1=GetHdlList().GetHdl(HDL_REF1);
908 	SdrHdl* pH2=GetHdlList().GetHdl(HDL_REF2);
909 
910 	if (eKind==HDL_MIRX)
911 	{
912 		if (pH1==NULL || pH2==NULL)
913 		{
914 			DBG_ERROR("SdrDragMovHdl::BeginSdrDrag(): Verschieben der Spiegelachse: Referenzhandles nicht gefunden");
915 			return false;
916 		}
917 
918 		DragStat().SetActionRect(Rectangle(pH1->GetPos(),pH2->GetPos()));
919 	}
920 	else
921 	{
922 		Point aPt(GetDragHdl()->GetPos());
923 		DragStat().SetActionRect(Rectangle(aPt,aPt));
924 	}
925 
926 	return true;
927 }
928 
929 void SdrDragMovHdl::MoveSdrDrag(const Point& rNoSnapPnt)
930 {
931 	Point aPnt(rNoSnapPnt);
932 
933 	if ( GetDragHdl() && DragStat().CheckMinMoved(rNoSnapPnt))
934 	{
935 		if (GetDragHdl()->GetKind()==HDL_MIRX)
936 		{
937 			SdrHdl* pH1=GetHdlList().GetHdl(HDL_REF1);
938 			SdrHdl* pH2=GetHdlList().GetHdl(HDL_REF2);
939 
940 			if (pH1==NULL || pH2==NULL)
941 				return;
942 
943 			if (!DragStat().IsNoSnap())
944 			{
945 				long nBestXSnap=0;
946 				long nBestYSnap=0;
947 				bool bXSnapped=false;
948 				bool bYSnapped=false;
949 				Point aDif(aPnt-DragStat().GetStart());
950 				getSdrDragView().CheckSnap(Ref1()+aDif,NULL,nBestXSnap,nBestYSnap,bXSnapped,bYSnapped);
951 				getSdrDragView().CheckSnap(Ref2()+aDif,NULL,nBestXSnap,nBestYSnap,bXSnapped,bYSnapped);
952 				aPnt.X()+=nBestXSnap;
953 				aPnt.Y()+=nBestYSnap;
954 			}
955 
956 			if (aPnt!=DragStat().GetNow())
957 			{
958 				Hide();
959 				DragStat().NextMove(aPnt);
960 				Point aDif(DragStat().GetNow()-DragStat().GetStart());
961 				pH1->SetPos(Ref1()+aDif);
962 				pH2->SetPos(Ref2()+aDif);
963 
964 				SdrHdl* pHM = GetHdlList().GetHdl(HDL_MIRX);
965 
966 				if(pHM)
967 					pHM->Touch();
968 
969 				Show();
970 				DragStat().SetActionRect(Rectangle(pH1->GetPos(),pH2->GetPos()));
971 			}
972 		}
973 		else
974 		{
975 			if (!DragStat().IsNoSnap()) SnapPos(aPnt);
976 			long nSA=0;
977 
978 			if (getSdrDragView().IsAngleSnapEnabled())
979 				nSA=getSdrDragView().GetSnapAngle();
980 
981 			if (getSdrDragView().IsMirrorAllowed(true,true))
982 			{ // eingeschraenkt
983 				if (!getSdrDragView().IsMirrorAllowed(false,false)) nSA=4500;
984 				if (!getSdrDragView().IsMirrorAllowed(true,false)) nSA=9000;
985 			}
986 
987 			if (getSdrDragView().IsOrtho() && nSA!=9000)
988 				nSA=4500;
989 
990 			if (nSA!=0)
991 			{ // Winkelfang
992 				SdrHdlKind eRef=HDL_REF1;
993 
994 				if (GetDragHdl()->GetKind()==HDL_REF1)
995 					eRef=HDL_REF2;
996 
997 				SdrHdl* pH=GetHdlList().GetHdl(eRef);
998 
999 				if (pH!=NULL)
1000 				{
1001 					Point aRef(pH->GetPos());
1002 					long nWink=NormAngle360(GetAngle(aPnt-aRef));
1003 					long nNeuWink=nWink;
1004 					nNeuWink+=nSA/2;
1005 					nNeuWink/=nSA;
1006 					nNeuWink*=nSA;
1007 					nNeuWink=NormAngle360(nNeuWink);
1008 					double a=(nNeuWink-nWink)*nPi180;
1009 					double nSin=sin(a);
1010 					double nCos=cos(a);
1011 					RotatePoint(aPnt,aRef,nSin,nCos);
1012 
1013 					// Bei bestimmten Werten Rundungsfehler ausschliessen:
1014 					if (nSA==9000)
1015 					{
1016 						if (nNeuWink==0    || nNeuWink==18000) aPnt.Y()=aRef.Y();
1017 						if (nNeuWink==9000 || nNeuWink==27000) aPnt.X()=aRef.X();
1018 					}
1019 
1020 					if (nSA==4500)
1021 						OrthoDistance8(aRef,aPnt,true);
1022 				}
1023 			}
1024 
1025 			if (aPnt!=DragStat().GetNow())
1026 			{
1027 				Hide();
1028 				DragStat().NextMove(aPnt);
1029 				GetDragHdl()->SetPos(DragStat().GetNow());
1030 				SdrHdl* pHM = GetHdlList().GetHdl(HDL_MIRX);
1031 
1032 				if(pHM)
1033 					pHM->Touch();
1034 
1035 				Show();
1036 				DragStat().SetActionRect(Rectangle(aPnt,aPnt));
1037 			}
1038 		}
1039 	}
1040 }
1041 
1042 bool SdrDragMovHdl::EndSdrDrag(bool /*bCopy*/)
1043 {
1044 	if( GetDragHdl() )
1045 	{
1046 		switch (GetDragHdl()->GetKind())
1047 		{
1048 			case HDL_REF1:
1049 				Ref1()=DragStat().GetNow();
1050 				break;
1051 
1052 			case HDL_REF2:
1053 				Ref2()=DragStat().GetNow();
1054 				break;
1055 
1056 			case HDL_MIRX:
1057 				Ref1()+=DragStat().GetNow()-DragStat().GetStart();
1058 				Ref2()+=DragStat().GetNow()-DragStat().GetStart();
1059 				break;
1060 
1061 			default: break;
1062 		}
1063 	}
1064 
1065 	return true;
1066 }
1067 
1068 void SdrDragMovHdl::CancelSdrDrag()
1069 {
1070 	Hide();
1071 
1072 	SdrHdl* pHdl = GetDragHdl();
1073 	if( pHdl )
1074 		pHdl->SetPos(DragStat().GetRef1());
1075 
1076 	SdrHdl* pHM = GetHdlList().GetHdl(HDL_MIRX);
1077 
1078 	if(pHM)
1079 		pHM->Touch();
1080 }
1081 
1082 Pointer SdrDragMovHdl::GetSdrDragPointer() const
1083 {
1084 	const SdrHdl* pHdl = GetDragHdl();
1085 
1086 	if (pHdl!=NULL)
1087 	{
1088 		return pHdl->GetPointer();
1089 	}
1090 
1091 	return Pointer(POINTER_REFHAND);
1092 }
1093 
1094 ////////////////////////////////////////////////////////////////////////////////////////////////////
1095 
1096 TYPEINIT1(SdrDragObjOwn,SdrDragMethod);
1097 
1098 SdrDragObjOwn::SdrDragObjOwn(SdrDragView& rNewView)
1099 :	SdrDragMethod(rNewView),
1100 	mpClone(0)
1101 {
1102     const SdrObject* pObj = GetDragObj();
1103 
1104     if(pObj)
1105     {
1106 		// suppress full drag for some object types
1107 		setSolidDraggingActive(pObj->supportsFullDrag());
1108 	}
1109 }
1110 
1111 SdrDragObjOwn::~SdrDragObjOwn()
1112 {
1113 	if(mpClone)
1114 	{
1115 		SdrObject::Free(mpClone);
1116 	}
1117 }
1118 
1119 void SdrDragObjOwn::createSdrDragEntries()
1120 {
1121     if(mpClone)
1122     {
1123         basegfx::B2DPolyPolygon aDragPolyPolygon;
1124 		bool bAddWireframe(true);
1125 
1126 		if(getSolidDraggingActive())
1127 		{
1128 			SdrPageView* pPV = getSdrDragView().GetSdrPageView();
1129 
1130 			if(pPV && pPV->PageWindowCount())
1131 			{
1132 				sdr::contact::ObjectContact& rOC = pPV->GetPageWindow(0)->GetObjectContact();
1133 				addSdrDragEntry(new SdrDragEntrySdrObject(*mpClone, rOC, false));
1134 
1135                 // potentially no wireframe needed, full drag works
1136 				bAddWireframe = false;
1137 			}
1138 		}
1139 
1140         if(!bAddWireframe)
1141         {
1142             // check for extra conditions for wireframe, e.g. no border at
1143             // objects
1144             if(!mpClone->HasLineStyle())
1145             {
1146                 bAddWireframe = true;
1147             }
1148         }
1149 
1150 		if(bAddWireframe)
1151 		{
1152             // use wireframe poly when full drag is off or did not work
1153             aDragPolyPolygon = mpClone->TakeXorPoly();
1154         }
1155 
1156         // add evtl. extra DragPolyPolygon
1157     	const basegfx::B2DPolyPolygon aSpecialDragPolyPolygon(mpClone->getSpecialDragPoly(DragStat()));
1158 
1159         if(aSpecialDragPolyPolygon.count())
1160         {
1161             aDragPolyPolygon.append(aSpecialDragPolyPolygon);
1162         }
1163 
1164 		if(aDragPolyPolygon.count())
1165 		{
1166 			addSdrDragEntry(new SdrDragEntryPolyPolygon(aDragPolyPolygon));
1167 		}
1168 	}
1169 }
1170 
1171 void SdrDragObjOwn::TakeSdrDragComment(XubString& rStr) const
1172 {
1173     // #i103058# get info string from the clone preferred, the original will
1174     // not be changed. For security, use original as fallback
1175     if(mpClone)
1176     {
1177 		rStr = mpClone->getSpecialDragComment(DragStat());
1178     }
1179     else
1180     {
1181         const SdrObject* pObj = GetDragObj();
1182 
1183         if(pObj)
1184         {
1185 		    rStr = pObj->getSpecialDragComment(DragStat());
1186 	    }
1187     }
1188 }
1189 
1190 bool SdrDragObjOwn::BeginSdrDrag()
1191 {
1192 	if(!mpClone)
1193 	{
1194 		const SdrObject* pObj = GetDragObj();
1195 
1196 		if(pObj && !pObj->IsResizeProtect())
1197 		{
1198 			if(pObj->beginSpecialDrag(DragStat()))
1199 			{
1200 				// create nitial clone to have a start visualisation
1201 				mpClone = pObj->getFullDragClone();
1202 				mpClone->applySpecialDrag(DragStat());
1203 
1204 				return true;
1205 			}
1206 		}
1207 	}
1208 
1209     return false;
1210 }
1211 
1212 void SdrDragObjOwn::MoveSdrDrag(const Point& rNoSnapPnt)
1213 {
1214 	const SdrObject* pObj = GetDragObj();
1215 
1216 	if(pObj)
1217 	{
1218 		Point aPnt(rNoSnapPnt);
1219 		SdrPageView* pPV = GetDragPV();
1220 
1221 		if(pPV)
1222 		{
1223 			if(!DragStat().IsNoSnap())
1224 			{
1225 				SnapPos(aPnt);
1226 			}
1227 
1228 			if(getSdrDragView().IsOrtho())
1229 			{
1230 				if (DragStat().IsOrtho8Possible())
1231 				{
1232 					OrthoDistance8(DragStat().GetStart(),aPnt,getSdrDragView().IsBigOrtho());
1233 				}
1234 				else if (DragStat().IsOrtho4Possible())
1235 				{
1236 					OrthoDistance4(DragStat().GetStart(),aPnt,getSdrDragView().IsBigOrtho());
1237 				}
1238 			}
1239 
1240 			if(DragStat().CheckMinMoved(rNoSnapPnt))
1241 			{
1242 				if(aPnt != DragStat().GetNow())
1243 				{
1244 					Hide();
1245 					DragStat().NextMove(aPnt);
1246 
1247 					// since SdrDragObjOwn currently supports no transformation of
1248 					// existing SdrDragEntries but only their recreation, a recreation
1249 					// after every move is needed in this mode. Delete existing
1250 					// SdrDragEntries here  to force their recreation in the following Show().
1251 					clearSdrDragEntries();
1252 
1253 					// delete current clone (after the last reference to it is deleted above)
1254 					if(mpClone)
1255 					{
1256 						SdrObject::Free(mpClone);
1257 						mpClone = 0;
1258 					}
1259 
1260 					// create a new clone and modify to current drag state
1261 					if(!mpClone)
1262 					{
1263 						mpClone = pObj->getFullDragClone();
1264 						mpClone->applySpecialDrag(DragStat());
1265 					}
1266 
1267 					Show();
1268 				}
1269 			}
1270 		}
1271 	}
1272 }
1273 
1274 bool SdrDragObjOwn::EndSdrDrag(bool /*bCopy*/)
1275 {
1276 	Hide();
1277 	SdrUndoAction* pUndo = NULL;
1278 	SdrUndoAction* pUndo2 = NULL;
1279 	std::vector< SdrUndoAction* > vConnectorUndoActions;
1280 	bool bRet = false;
1281 	SdrObject* pObj = GetDragObj();
1282 
1283 	if(pObj)
1284 	{
1285 		const bool bUndo = getSdrDragView().IsUndoEnabled();
1286 
1287 		if( bUndo )
1288 		{
1289 			if(!getSdrDragView().IsInsObjPoint() && pObj->IsInserted() )
1290 			{
1291 				if (DragStat().IsEndDragChangesAttributes())
1292 				{
1293 					pUndo=getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pObj);
1294 
1295 					if (DragStat().IsEndDragChangesGeoAndAttributes())
1296 					{
1297 						vConnectorUndoActions = getSdrDragView().CreateConnectorUndo( *pObj );
1298 						pUndo2 = getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj);
1299 					}
1300 				}
1301 				else
1302 				{
1303 					vConnectorUndoActions = getSdrDragView().CreateConnectorUndo( *pObj );
1304 					pUndo= getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj);
1305 				}
1306 			}
1307 
1308 			if( pUndo )
1309 			{
1310 				getSdrDragView().BegUndo( pUndo->GetComment() );
1311 			}
1312 			else
1313 			{
1314 				getSdrDragView().BegUndo();
1315 			}
1316 		}
1317 
1318         // evtl. use opertator= for setting changed object data (do not change selection in
1319         // view, this will destroy the interactor). This is possible since a clone is now
1320         // directly modified by the modifiers. Only SdrTableObj is adding own UNDOs
1321         // in it's SdrTableObj::endSpecialDrag, so currently not possible. OTOH it uses
1322         // a CreateUndoGeoObject() so maybe setting SetEndDragChangesAttributes is okay. I
1323         // will test this now
1324         Rectangle aBoundRect0;
1325 
1326         if(pObj->GetUserCall())
1327         {
1328             aBoundRect0 = pObj->GetLastBoundRect();
1329         }
1330 
1331         bRet = pObj->applySpecialDrag(DragStat());
1332 
1333         if(bRet)
1334         {
1335 	        pObj->SetChanged();
1336 	        pObj->BroadcastObjectChange();
1337 	        pObj->SendUserCall( SDRUSERCALL_RESIZE, aBoundRect0 );
1338         }
1339 
1340         if(bRet)
1341 		{
1342 			if( bUndo )
1343 			{
1344 				getSdrDragView().AddUndoActions( vConnectorUndoActions );
1345 
1346 				if ( pUndo )
1347 				{
1348 					getSdrDragView().AddUndo(pUndo);
1349 				}
1350 
1351 				if ( pUndo2 )
1352 				{
1353 					getSdrDragView().AddUndo(pUndo2);
1354 				}
1355 			}
1356 		}
1357 		else
1358 		{
1359 			if( bUndo )
1360 			{
1361 				std::vector< SdrUndoAction* >::iterator vConnectorUndoIter( vConnectorUndoActions.begin() );
1362 
1363 				while( vConnectorUndoIter != vConnectorUndoActions.end() )
1364 				{
1365 					delete *vConnectorUndoIter++;
1366 				}
1367 
1368 				delete pUndo;
1369 				delete pUndo2;
1370 			}
1371 		}
1372 
1373 		if( bUndo )
1374 			getSdrDragView().EndUndo();
1375 	}
1376 
1377     return bRet;
1378 }
1379 
1380 Pointer SdrDragObjOwn::GetSdrDragPointer() const
1381 {
1382 	const SdrHdl* pHdl=GetDragHdl();
1383 
1384 	if (pHdl)
1385 	{
1386 		return pHdl->GetPointer();
1387 	}
1388 
1389 	return Pointer(POINTER_MOVE);
1390 }
1391 
1392 ////////////////////////////////////////////////////////////////////////////////////////////////////
1393 
1394 TYPEINIT1(SdrDragMove,SdrDragMethod);
1395 
1396 void SdrDragMove::createSdrDragEntryForSdrObject(const SdrObject& rOriginal, sdr::contact::ObjectContact& rObjectContact, bool /*bModify*/)
1397 {
1398     // for SdrDragMove, use current Primitive2DSequence of SdrObject visualisation
1399     // in given ObjectContact directly
1400     sdr::contact::ViewContact& rVC = rOriginal.GetViewContact();
1401     sdr::contact::ViewObjectContact& rVOC = rVC.GetViewObjectContact(rObjectContact);
1402     sdr::contact::DisplayInfo aDisplayInfo;
1403 
1404     // Do not use the last ViewPort set at the OC from the last ProcessDisplay(),
1405     // here we want the complete primitive sequence without visibility clippings
1406     rObjectContact.resetViewPort();
1407 
1408     addSdrDragEntry(new SdrDragEntryPrimitive2DSequence(rVOC.getPrimitive2DSequenceHierarchy(aDisplayInfo), true));
1409 }
1410 
1411 void SdrDragMove::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
1412 {
1413 	rTarget.Move(Size(DragStat().GetDX(), DragStat().GetDY()));
1414 }
1415 
1416 SdrDragMove::SdrDragMove(SdrDragView& rNewView)
1417 :	SdrDragMethod(rNewView)
1418 {
1419 	setMoveOnly(true);
1420 }
1421 
1422 void SdrDragMove::TakeSdrDragComment(XubString& rStr) const
1423 {
1424 	XubString aStr;
1425 
1426 	ImpTakeDescriptionStr(STR_DragMethMove, rStr);
1427 	rStr.AppendAscii(" (x=");
1428 	getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDX(), aStr);
1429 	rStr += aStr;
1430 	rStr.AppendAscii(" y=");
1431 	getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDY(), aStr);
1432 	rStr += aStr;
1433 	rStr += sal_Unicode(')');
1434 
1435 	if(getSdrDragView().IsDragWithCopy())
1436 	{
1437 		if(!getSdrDragView().IsInsObjPoint() && !getSdrDragView().IsInsGluePoint())
1438 		{
1439 			rStr += ImpGetResStr(STR_EditWithCopy);
1440 		}
1441 	}
1442 }
1443 
1444 bool SdrDragMove::BeginSdrDrag()
1445 {
1446 	DragStat().SetActionRect(GetMarkedRect());
1447 	Show();
1448 
1449 	return true;
1450 }
1451 
1452 basegfx::B2DHomMatrix SdrDragMove::getCurrentTransformation()
1453 {
1454     return basegfx::tools::createTranslateB2DHomMatrix(DragStat().GetDX(), DragStat().GetDY());
1455 }
1456 
1457 void SdrDragMove::ImpCheckSnap(const Point& rPt)
1458 {
1459 	Point aPt(rPt);
1460 	sal_uInt16 nRet=SnapPos(aPt);
1461 	aPt-=rPt;
1462 
1463 	if ((nRet & SDRSNAP_XSNAPPED) !=0)
1464 	{
1465 		if (bXSnapped)
1466 		{
1467 			if (Abs(aPt.X())<Abs(nBestXSnap))
1468 			{
1469 				nBestXSnap=aPt.X();
1470 			}
1471 		}
1472 		else
1473 		{
1474 			nBestXSnap=aPt.X();
1475 			bXSnapped=true;
1476 		}
1477 	}
1478 
1479 	if ((nRet & SDRSNAP_YSNAPPED) !=0)
1480 	{
1481 		if (bYSnapped)
1482 		{
1483 			if (Abs(aPt.Y())<Abs(nBestYSnap))
1484 			{
1485 				nBestYSnap=aPt.Y();
1486 			}
1487 		}
1488 		else
1489 		{
1490 			nBestYSnap=aPt.Y();
1491 			bYSnapped=true;
1492 		}
1493 	}
1494 }
1495 
1496 void SdrDragMove::MoveSdrDrag(const Point& rNoSnapPnt_)
1497 {
1498 	nBestXSnap=0;
1499 	nBestYSnap=0;
1500 	bXSnapped=false;
1501 	bYSnapped=false;
1502 	Point aNoSnapPnt(rNoSnapPnt_);
1503 	const Rectangle& aSR=GetMarkedRect();
1504 	long nMovedx=aNoSnapPnt.X()-DragStat().GetStart().X();
1505 	long nMovedy=aNoSnapPnt.Y()-DragStat().GetStart().Y();
1506 	Point aLO(aSR.TopLeft());      aLO.X()+=nMovedx; aLO.Y()+=nMovedy;
1507 	Point aRU(aSR.BottomRight());  aRU.X()+=nMovedx; aRU.Y()+=nMovedy;
1508 	Point aLU(aLO.X(),aRU.Y());
1509 	Point aRO(aRU.X(),aLO.Y());
1510 	ImpCheckSnap(aLO);
1511 
1512 	if (!getSdrDragView().IsMoveSnapOnlyTopLeft())
1513 	{
1514 		ImpCheckSnap(aRO);
1515 		ImpCheckSnap(aLU);
1516 		ImpCheckSnap(aRU);
1517 	}
1518 
1519 	Point aPnt(aNoSnapPnt.X()+nBestXSnap,aNoSnapPnt.Y()+nBestYSnap);
1520 	bool bOrtho=getSdrDragView().IsOrtho();
1521 
1522 	if (bOrtho)
1523 		OrthoDistance8(DragStat().GetStart(),aPnt,getSdrDragView().IsBigOrtho());
1524 
1525 	if (DragStat().CheckMinMoved(aNoSnapPnt))
1526 	{
1527 		Point aPt1(aPnt);
1528 		Rectangle aLR(getSdrDragView().GetWorkArea());
1529 		bool bWorkArea=!aLR.IsEmpty();
1530 		bool bDragLimit=IsDragLimit();
1531 
1532 		if (bDragLimit || bWorkArea)
1533 		{
1534 			Rectangle aSR2(GetMarkedRect());
1535 			Point aD(aPt1-DragStat().GetStart());
1536 
1537 			if (bDragLimit)
1538 			{
1539 				Rectangle aR2(GetDragLimitRect());
1540 
1541 				if (bWorkArea)
1542 					aLR.Intersection(aR2);
1543 				else
1544 					aLR=aR2;
1545 			}
1546 
1547 			if (aSR2.Left()>aLR.Left() || aSR2.Right()<aLR.Right())
1548 			{ // ist ueberhaupt Platz zum verschieben?
1549 				aSR2.Move(aD.X(),0);
1550 
1551 				if (aSR2.Left()<aLR.Left())
1552 				{
1553 					aPt1.X()-=aSR2.Left()-aLR.Left();
1554 				}
1555 				else if (aSR2.Right()>aLR.Right())
1556 				{
1557 					aPt1.X()-=aSR2.Right()-aLR.Right();
1558 				}
1559 			}
1560 			else
1561 				aPt1.X()=DragStat().GetStart().X(); // kein Platz zum verschieben
1562 
1563 			if (aSR2.Top()>aLR.Top() || aSR2.Bottom()<aLR.Bottom())
1564 			{ // ist ueberhaupt Platz zum verschieben?
1565 				aSR2.Move(0,aD.Y());
1566 
1567 				if (aSR2.Top()<aLR.Top())
1568 				{
1569 					aPt1.Y()-=aSR2.Top()-aLR.Top();
1570 				}
1571 				else if (aSR2.Bottom()>aLR.Bottom())
1572 				{
1573 					aPt1.Y()-=aSR2.Bottom()-aLR.Bottom();
1574 				}
1575 			}
1576 			else
1577 				aPt1.Y()=DragStat().GetStart().Y(); // kein Platz zum verschieben
1578 		}
1579 
1580 		if (getSdrDragView().IsDraggingGluePoints())
1581 		{ // Klebepunkte aufs BoundRect des Obj limitieren
1582 			aPt1-=DragStat().GetStart();
1583 			const SdrMarkList& rML=GetMarkedObjectList();
1584 			sal_uLong nMarkAnz=rML.GetMarkCount();
1585 
1586 			for (sal_uLong nMarkNum=0; nMarkNum<nMarkAnz; nMarkNum++)
1587 			{
1588 				const SdrMark* pM=rML.GetMark(nMarkNum);
1589 				const SdrUShortCont* pPts=pM->GetMarkedGluePoints();
1590 				sal_uLong nPtAnz=pPts==NULL ? 0 : pPts->GetCount();
1591 
1592 				if (nPtAnz!=0)
1593 				{
1594 					const SdrObject* pObj=pM->GetMarkedSdrObj();
1595 					const SdrGluePointList* pGPL=pObj->GetGluePointList();
1596 					Rectangle aBound(pObj->GetCurrentBoundRect());
1597 
1598 					for (sal_uLong nPtNum=0; nPtNum<nPtAnz; nPtNum++)
1599 					{
1600 						sal_uInt16 nId=pPts->GetObject(nPtNum);
1601 						sal_uInt16 nGlueNum=pGPL->FindGluePoint(nId);
1602 
1603 						if (nGlueNum!=SDRGLUEPOINT_NOTFOUND)
1604 						{
1605 							Point aPt((*pGPL)[nGlueNum].GetAbsolutePos(*pObj));
1606 							aPt+=aPt1; // soviel soll verschoben werden
1607 							if (aPt.X()<aBound.Left()  ) aPt1.X()-=aPt.X()-aBound.Left()  ;
1608 							if (aPt.X()>aBound.Right() ) aPt1.X()-=aPt.X()-aBound.Right() ;
1609 							if (aPt.Y()<aBound.Top()   ) aPt1.Y()-=aPt.Y()-aBound.Top()   ;
1610 							if (aPt.Y()>aBound.Bottom()) aPt1.Y()-=aPt.Y()-aBound.Bottom();
1611 						}
1612 					}
1613 				}
1614 			}
1615 
1616 			aPt1+=DragStat().GetStart();
1617 		}
1618 
1619 		if (bOrtho)
1620 			OrthoDistance8(DragStat().GetStart(),aPt1,false);
1621 
1622 		if (aPt1!=DragStat().GetNow())
1623 		{
1624 			Hide();
1625 			DragStat().NextMove(aPt1);
1626 			Rectangle aAction(GetMarkedRect());
1627 			aAction.Move(DragStat().GetDX(),DragStat().GetDY());
1628 			DragStat().SetActionRect(aAction);
1629 			Show();
1630 		}
1631 	}
1632 }
1633 
1634 bool SdrDragMove::EndSdrDrag(bool bCopy)
1635 {
1636 	Hide();
1637 
1638 	if (getSdrDragView().IsInsObjPoint() || getSdrDragView().IsInsGluePoint())
1639 		bCopy=false;
1640 
1641 	if (IsDraggingPoints())
1642 	{
1643 		getSdrDragView().MoveMarkedPoints(Size(DragStat().GetDX(),DragStat().GetDY()),bCopy);
1644 	}
1645 	else if (IsDraggingGluePoints())
1646 	{
1647 		getSdrDragView().MoveMarkedGluePoints(Size(DragStat().GetDX(),DragStat().GetDY()),bCopy);
1648 	}
1649 	else
1650 	{
1651 		getSdrDragView().MoveMarkedObj(Size(DragStat().GetDX(),DragStat().GetDY()),bCopy);
1652 	}
1653 
1654 	return true;
1655 }
1656 
1657 Pointer SdrDragMove::GetSdrDragPointer() const
1658 {
1659 	if (IsDraggingPoints() || IsDraggingGluePoints())
1660 	{
1661 		return Pointer(POINTER_MOVEPOINT);
1662 	}
1663 	else
1664 	{
1665 		return Pointer(POINTER_MOVE);
1666 	}
1667 }
1668 
1669 ////////////////////////////////////////////////////////////////////////////////////////////////////
1670 
1671 TYPEINIT1(SdrDragResize,SdrDragMethod);
1672 
1673 SdrDragResize::SdrDragResize(SdrDragView& rNewView)
1674 :	SdrDragMethod(rNewView),
1675 	aXFact(1,1),
1676 	aYFact(1,1)
1677 {
1678 }
1679 
1680 void SdrDragResize::TakeSdrDragComment(XubString& rStr) const
1681 {
1682 	ImpTakeDescriptionStr(STR_DragMethResize, rStr);
1683 	bool bEqual(aXFact == aYFact);
1684 	Fraction aFact1(1,1);
1685 	Point aStart(DragStat().GetStart());
1686 	Point aRef(DragStat().GetRef1());
1687 	sal_Int32 nXDiv(aStart.X() - aRef.X());
1688 
1689 	if(!nXDiv)
1690 		nXDiv = 1;
1691 
1692 	sal_Int32 nYDiv(aStart.Y() - aRef.Y());
1693 
1694 	if(!nYDiv)
1695 		nYDiv = 1;
1696 
1697 	bool bX(aXFact != aFact1 && Abs(nXDiv) > 1);
1698 	bool bY(aYFact != aFact1 && Abs(nYDiv) > 1);
1699 
1700 	if(bX || bY)
1701 	{
1702 		XubString aStr;
1703 
1704 		rStr.AppendAscii(" (");
1705 
1706 		if(bX)
1707 		{
1708 			if(!bEqual)
1709 				rStr.AppendAscii("x=");
1710 
1711 			getSdrDragView().GetModel()->TakePercentStr(aXFact, aStr);
1712 			rStr += aStr;
1713 		}
1714 
1715 		if(bY && !bEqual)
1716 		{
1717 			if(bX)
1718 				rStr += sal_Unicode(' ');
1719 
1720 			rStr.AppendAscii("y=");
1721 			getSdrDragView().GetModel()->TakePercentStr(aYFact, aStr);
1722 			rStr += aStr;
1723 		}
1724 
1725 		rStr += sal_Unicode(')');
1726 	}
1727 
1728 	if(getSdrDragView().IsDragWithCopy())
1729 		rStr += ImpGetResStr(STR_EditWithCopy);
1730 }
1731 
1732 bool SdrDragResize::BeginSdrDrag()
1733 {
1734 	SdrHdlKind eRefHdl=HDL_MOVE;
1735 	SdrHdl* pRefHdl=NULL;
1736 
1737 	switch (GetDragHdlKind())
1738 	{
1739 		case HDL_UPLFT: eRefHdl=HDL_LWRGT; break;
1740 		case HDL_UPPER: eRefHdl=HDL_LOWER; DragStat().SetHorFixed(true); break;
1741 		case HDL_UPRGT: eRefHdl=HDL_LWLFT; break;
1742 		case HDL_LEFT : eRefHdl=HDL_RIGHT; DragStat().SetVerFixed(true); break;
1743 		case HDL_RIGHT: eRefHdl=HDL_LEFT ; DragStat().SetVerFixed(true); break;
1744 		case HDL_LWLFT: eRefHdl=HDL_UPRGT; break;
1745 		case HDL_LOWER: eRefHdl=HDL_UPPER; DragStat().SetHorFixed(true); break;
1746 		case HDL_LWRGT: eRefHdl=HDL_UPLFT; break;
1747 		default: break;
1748 	}
1749 
1750 	if (eRefHdl!=HDL_MOVE)
1751 		pRefHdl=GetHdlList().GetHdl(eRefHdl);
1752 
1753 	if (pRefHdl!=NULL && !getSdrDragView().IsResizeAtCenter())
1754 	{
1755 		DragStat().Ref1()=pRefHdl->GetPos();
1756 	}
1757 	else
1758 	{
1759 		SdrHdl* pRef1=GetHdlList().GetHdl(HDL_UPLFT);
1760 		SdrHdl* pRef2=GetHdlList().GetHdl(HDL_LWRGT);
1761 
1762 		if (pRef1!=NULL && pRef2!=NULL)
1763 		{
1764 			DragStat().Ref1()=Rectangle(pRef1->GetPos(),pRef2->GetPos()).Center();
1765 		}
1766 		else
1767 		{
1768 			DragStat().Ref1()=GetMarkedRect().Center();
1769 		}
1770 	}
1771 
1772 	Show();
1773 
1774 	return true;
1775 }
1776 
1777 basegfx::B2DHomMatrix SdrDragResize::getCurrentTransformation()
1778 {
1779     basegfx::B2DHomMatrix aRetval(basegfx::tools::createTranslateB2DHomMatrix(
1780         -DragStat().Ref1().X(), -DragStat().Ref1().Y()));
1781 	aRetval.scale(aXFact, aYFact);
1782 	aRetval.translate(DragStat().Ref1().X(), DragStat().Ref1().Y());
1783 
1784 	return aRetval;
1785 }
1786 
1787 void SdrDragResize::MoveSdrDrag(const Point& rNoSnapPnt)
1788 {
1789 	Point aPnt(GetSnapPos(rNoSnapPnt));
1790 	Point aStart(DragStat().GetStart());
1791 	Point aRef(DragStat().GetRef1());
1792 	Fraction aMaxFact(0x7FFFFFFF,1);
1793 	Rectangle aLR(getSdrDragView().GetWorkArea());
1794 	bool bWorkArea=!aLR.IsEmpty();
1795 	bool bDragLimit=IsDragLimit();
1796 
1797 	if (bDragLimit || bWorkArea)
1798 	{
1799 		Rectangle aSR(GetMarkedRect());
1800 
1801 		if (bDragLimit)
1802 		{
1803 			Rectangle aR2(GetDragLimitRect());
1804 
1805 			if (bWorkArea)
1806 				aLR.Intersection(aR2);
1807 			else
1808 				aLR=aR2;
1809 		}
1810 
1811 		if (aPnt.X()<aLR.Left())
1812 			aPnt.X()=aLR.Left();
1813 		else if (aPnt.X()>aLR.Right())
1814 			aPnt.X()=aLR.Right();
1815 
1816 		if (aPnt.Y()<aLR.Top())
1817 			aPnt.Y()=aLR.Top();
1818 		else if (aPnt.Y()>aLR.Bottom())
1819 			aPnt.Y()=aLR.Bottom();
1820 
1821 		if (aRef.X()>aSR.Left())
1822 		{
1823 			Fraction aMax(aRef.X()-aLR.Left(),aRef.X()-aSR.Left());
1824 
1825 			if (aMax<aMaxFact)
1826 				aMaxFact=aMax;
1827 		}
1828 
1829 		if (aRef.X()<aSR.Right())
1830 		{
1831 			Fraction aMax(aLR.Right()-aRef.X(),aSR.Right()-aRef.X());
1832 
1833 			if (aMax<aMaxFact)
1834 				aMaxFact=aMax;
1835 		}
1836 
1837 		if (aRef.Y()>aSR.Top())
1838 		{
1839 			Fraction aMax(aRef.Y()-aLR.Top(),aRef.Y()-aSR.Top());
1840 
1841 			if (aMax<aMaxFact)
1842 				aMaxFact=aMax;
1843 		}
1844 
1845 		if (aRef.Y()<aSR.Bottom())
1846 		{
1847 			Fraction aMax(aLR.Bottom()-aRef.Y(),aSR.Bottom()-aRef.Y());
1848 
1849 			if (aMax<aMaxFact)
1850 				aMaxFact=aMax;
1851 		}
1852 	}
1853 
1854 	long nXDiv=aStart.X()-aRef.X(); if (nXDiv==0) nXDiv=1;
1855 	long nYDiv=aStart.Y()-aRef.Y(); if (nYDiv==0) nYDiv=1;
1856 	long nXMul=aPnt.X()-aRef.X();
1857 	long nYMul=aPnt.Y()-aRef.Y();
1858 
1859 	if (nXDiv<0)
1860 	{
1861 		nXDiv=-nXDiv;
1862 		nXMul=-nXMul;
1863 	}
1864 
1865 	if (nYDiv<0)
1866 	{
1867 		nYDiv=-nYDiv;
1868 		nYMul=-nYMul;
1869 	}
1870 
1871 	bool bXNeg=nXMul<0; if (bXNeg) nXMul=-nXMul;
1872 	bool bYNeg=nYMul<0; if (bYNeg) nYMul=-nYMul;
1873 	bool bOrtho=getSdrDragView().IsOrtho() || !getSdrDragView().IsResizeAllowed(false);
1874 
1875 	if (!DragStat().IsHorFixed() && !DragStat().IsVerFixed())
1876 	{
1877 		if (Abs(nXDiv)<=1 || Abs(nYDiv)<=1)
1878 			bOrtho=false;
1879 
1880 		if (bOrtho)
1881 		{
1882 			if ((Fraction(nXMul,nXDiv)>Fraction(nYMul,nYDiv)) !=getSdrDragView().IsBigOrtho())
1883 			{
1884 				nXMul=nYMul;
1885 				nXDiv=nYDiv;
1886 			}
1887 			else
1888 			{
1889 				nYMul=nXMul;
1890 				nYDiv=nXDiv;
1891 			}
1892 		}
1893 	}
1894 	else
1895 	{
1896 		if (bOrtho)
1897 		{
1898 			if (DragStat().IsHorFixed())
1899 			{
1900 				bXNeg=false;
1901 				nXMul=nYMul;
1902 				nXDiv=nYDiv;
1903 			}
1904 
1905 			if (DragStat().IsVerFixed())
1906 			{
1907 				bYNeg=false;
1908 				nYMul=nXMul;
1909 				nYDiv=nXDiv;
1910 			}
1911 		}
1912 		else
1913 		{
1914 			if (DragStat().IsHorFixed())
1915 			{
1916 				bXNeg=false;
1917 				nXMul=1;
1918 				nXDiv=1;
1919 			}
1920 
1921 			if (DragStat().IsVerFixed())
1922 			{
1923 				bYNeg=false;
1924 				nYMul=1;
1925 				nYDiv=1;
1926 			}
1927 		}
1928 	}
1929 
1930 	Fraction aNeuXFact(nXMul,nXDiv);
1931 	Fraction aNeuYFact(nYMul,nYDiv);
1932 
1933 	if (bOrtho)
1934 	{
1935 		if (aNeuXFact>aMaxFact)
1936 		{
1937 			aNeuXFact=aMaxFact;
1938 			aNeuYFact=aMaxFact;
1939 		}
1940 
1941 		if (aNeuYFact>aMaxFact)
1942 		{
1943 			aNeuXFact=aMaxFact;
1944 			aNeuYFact=aMaxFact;
1945 		}
1946 	}
1947 
1948 	if (bXNeg)
1949 		aNeuXFact=Fraction(-aNeuXFact.GetNumerator(),aNeuXFact.GetDenominator());
1950 
1951 	if (bYNeg)
1952 		aNeuYFact=Fraction(-aNeuYFact.GetNumerator(),aNeuYFact.GetDenominator());
1953 
1954 	if (DragStat().CheckMinMoved(aPnt))
1955 	{
1956 		if ((!DragStat().IsHorFixed() && aPnt.X()!=DragStat().GetNow().X()) ||
1957 			(!DragStat().IsVerFixed() && aPnt.Y()!=DragStat().GetNow().Y()))
1958 		{
1959 			Hide();
1960 			DragStat().NextMove(aPnt);
1961 			aXFact=aNeuXFact;
1962 			aYFact=aNeuYFact;
1963 			Show();
1964 		}
1965 	}
1966 }
1967 
1968 void SdrDragResize::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
1969 {
1970     rTarget.Resize(DragStat().Ref1(),aXFact,aYFact);
1971 }
1972 
1973 bool SdrDragResize::EndSdrDrag(bool bCopy)
1974 {
1975 	Hide();
1976 
1977 	if (IsDraggingPoints())
1978 	{
1979 		getSdrDragView().ResizeMarkedPoints(DragStat().Ref1(),aXFact,aYFact,bCopy);
1980 	}
1981 	else if (IsDraggingGluePoints())
1982 	{
1983 		getSdrDragView().ResizeMarkedGluePoints(DragStat().Ref1(),aXFact,aYFact,bCopy);
1984 	}
1985 	else
1986 	{
1987 		getSdrDragView().ResizeMarkedObj(DragStat().Ref1(),aXFact,aYFact,bCopy);
1988 	}
1989 
1990 	return true;
1991 }
1992 
1993 Pointer SdrDragResize::GetSdrDragPointer() const
1994 {
1995 	const SdrHdl* pHdl=GetDragHdl();
1996 
1997 	if (pHdl!=NULL)
1998 	{
1999 		return pHdl->GetPointer();
2000 	}
2001 
2002 	return Pointer(POINTER_MOVE);
2003 }
2004 
2005 ////////////////////////////////////////////////////////////////////////////////////////////////////
2006 
2007 TYPEINIT1(SdrDragRotate,SdrDragMethod);
2008 
2009 void SdrDragRotate::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
2010 {
2011 	rTarget.Rotate(DragStat().GetRef1(), nWink, sin(nWink*nPi180), cos(nWink*nPi180));
2012 }
2013 
2014 SdrDragRotate::SdrDragRotate(SdrDragView& rNewView)
2015 :	SdrDragMethod(rNewView),
2016 	nSin(0.0),
2017 	nCos(1.0),
2018 	nWink0(0),
2019 	nWink(0),
2020 	bRight(false)
2021 {
2022 }
2023 
2024 void SdrDragRotate::TakeSdrDragComment(XubString& rStr) const
2025 {
2026 	ImpTakeDescriptionStr(STR_DragMethRotate, rStr);
2027 	rStr.AppendAscii(" (");
2028 	XubString aStr;
2029 	sal_Int32 nTmpWink(NormAngle360(nWink));
2030 
2031 	if(bRight && nWink)
2032 	{
2033 		nTmpWink -= 36000;
2034 	}
2035 
2036 	getSdrDragView().GetModel()->TakeWinkStr(nTmpWink, aStr);
2037 	rStr += aStr;
2038 	rStr += sal_Unicode(')');
2039 
2040 	if(getSdrDragView().IsDragWithCopy())
2041 		rStr += ImpGetResStr(STR_EditWithCopy);
2042 }
2043 
2044 bool SdrDragRotate::BeginSdrDrag()
2045 {
2046 	SdrHdl* pH=GetHdlList().GetHdl(HDL_REF1);
2047 
2048 	if (pH!=NULL)
2049 	{
2050 		Show();
2051 		DragStat().Ref1()=pH->GetPos();
2052 		nWink0=GetAngle(DragStat().GetStart()-DragStat().GetRef1());
2053 		return true;
2054 	}
2055 	else
2056 	{
2057 		DBG_ERROR("SdrDragRotate::BeginSdrDrag(): Kein Referenzpunkt-Handle gefunden");
2058 		return false;
2059 	}
2060 }
2061 
2062 basegfx::B2DHomMatrix SdrDragRotate::getCurrentTransformation()
2063 {
2064     return basegfx::tools::createRotateAroundPoint(
2065         DragStat().GetRef1().X(), DragStat().GetRef1().Y(),
2066         -atan2(nSin, nCos));
2067 }
2068 
2069 void SdrDragRotate::MoveSdrDrag(const Point& rPnt_)
2070 {
2071 	Point aPnt(rPnt_);
2072 	if (DragStat().CheckMinMoved(aPnt))
2073 	{
2074 		long nNeuWink=NormAngle360(GetAngle(aPnt-DragStat().GetRef1())-nWink0);
2075 		long nSA=0;
2076 
2077 		if (getSdrDragView().IsAngleSnapEnabled())
2078 			nSA=getSdrDragView().GetSnapAngle();
2079 
2080 		if (!getSdrDragView().IsRotateAllowed(false))
2081 			nSA=9000;
2082 
2083 		if (nSA!=0)
2084 		{ // Winkelfang
2085 			nNeuWink+=nSA/2;
2086 			nNeuWink/=nSA;
2087 			nNeuWink*=nSA;
2088 		}
2089 
2090 		nNeuWink=NormAngle180(nNeuWink);
2091 
2092 		if (nWink!=nNeuWink)
2093 		{
2094 			sal_uInt16 nSekt0=GetAngleSector(nWink);
2095 			sal_uInt16 nSekt1=GetAngleSector(nNeuWink);
2096 
2097 			if (nSekt0==0 && nSekt1==3)
2098 				bRight=true;
2099 
2100 			if (nSekt0==3 && nSekt1==0)
2101 				bRight=false;
2102 
2103 			nWink=nNeuWink;
2104 			double a=nWink*nPi180;
2105 			double nSin1=sin(a); // schonmal berechnen, damit mgl. wenig Zeit
2106 			double nCos1=cos(a); // zwischen Hide() und Show() vergeht
2107 			Hide();
2108 			nSin=nSin1;
2109 			nCos=nCos1;
2110 			DragStat().NextMove(aPnt);
2111 			Show();
2112 		}
2113 	}
2114 }
2115 
2116 bool SdrDragRotate::EndSdrDrag(bool bCopy)
2117 {
2118 	Hide();
2119 
2120 	if (nWink!=0)
2121 	{
2122 		if (IsDraggingPoints())
2123 		{
2124 			getSdrDragView().RotateMarkedPoints(DragStat().GetRef1(),nWink,bCopy);
2125 		}
2126 		else if (IsDraggingGluePoints())
2127 		{
2128 			getSdrDragView().RotateMarkedGluePoints(DragStat().GetRef1(),nWink,bCopy);
2129 		}
2130 		else
2131 		{
2132 			getSdrDragView().RotateMarkedObj(DragStat().GetRef1(),nWink,bCopy);
2133 		}
2134 	}
2135 	return true;
2136 }
2137 
2138 Pointer SdrDragRotate::GetSdrDragPointer() const
2139 {
2140 	return Pointer(POINTER_ROTATE);
2141 }
2142 
2143 ////////////////////////////////////////////////////////////////////////////////////////////////////
2144 
2145 TYPEINIT1(SdrDragShear,SdrDragMethod);
2146 
2147 SdrDragShear::SdrDragShear(SdrDragView& rNewView, bool bSlant1)
2148 :	SdrDragMethod(rNewView),
2149 	aFact(1,1),
2150 	nWink0(0),
2151 	nWink(0),
2152 	nTan(0.0),
2153 	bVertical(false),
2154 	bResize(false),
2155 	bUpSideDown(false),
2156 	bSlant(bSlant1)
2157 {
2158 }
2159 
2160 void SdrDragShear::TakeSdrDragComment(XubString& rStr) const
2161 {
2162 	ImpTakeDescriptionStr(STR_DragMethShear, rStr);
2163 	rStr.AppendAscii(" (");
2164 
2165 	sal_Int32 nTmpWink(nWink);
2166 
2167 	if(bUpSideDown)
2168 		nTmpWink += 18000;
2169 
2170 	nTmpWink = NormAngle180(nTmpWink);
2171 
2172 	XubString aStr;
2173 
2174 	getSdrDragView().GetModel()->TakeWinkStr(nTmpWink, aStr);
2175 	rStr += aStr;
2176 	rStr += sal_Unicode(')');
2177 
2178 	if(getSdrDragView().IsDragWithCopy())
2179 		rStr += ImpGetResStr(STR_EditWithCopy);
2180 }
2181 
2182 bool SdrDragShear::BeginSdrDrag()
2183 {
2184 	SdrHdlKind eRefHdl=HDL_MOVE;
2185 	SdrHdl* pRefHdl=NULL;
2186 
2187 	switch (GetDragHdlKind())
2188 	{
2189 		case HDL_UPPER: eRefHdl=HDL_LOWER; break;
2190 		case HDL_LOWER: eRefHdl=HDL_UPPER; break;
2191 		case HDL_LEFT : eRefHdl=HDL_RIGHT; bVertical=true; break;
2192 		case HDL_RIGHT: eRefHdl=HDL_LEFT ; bVertical=true; break;
2193 		default: break;
2194 	}
2195 
2196 	if (eRefHdl!=HDL_MOVE)
2197 		pRefHdl=GetHdlList().GetHdl(eRefHdl);
2198 
2199 	if (pRefHdl!=NULL)
2200 	{
2201 		DragStat().Ref1()=pRefHdl->GetPos();
2202 		nWink0=GetAngle(DragStat().GetStart()-DragStat().GetRef1());
2203 	}
2204 	else
2205 	{
2206 		DBG_ERROR("SdrDragShear::BeginSdrDrag(): Kein Referenzpunkt-Handle fuer Shear gefunden");
2207 		return false;
2208 	}
2209 
2210 	Show();
2211 	return true;
2212 }
2213 
2214 basegfx::B2DHomMatrix SdrDragShear::getCurrentTransformation()
2215 {
2216     basegfx::B2DHomMatrix aRetval(basegfx::tools::createTranslateB2DHomMatrix(
2217         -DragStat().GetRef1().X(), -DragStat().GetRef1().Y()));
2218 
2219 	if (bResize)
2220 	{
2221 		if (bVertical)
2222 		{
2223 			aRetval.scale(aFact, 1.0);
2224 			aRetval.shearY(-nTan);
2225 		}
2226 		else
2227 		{
2228 			aRetval.scale(1.0, aFact);
2229 			aRetval.shearX(-nTan);
2230 		}
2231 	}
2232 
2233 	aRetval.translate(DragStat().GetRef1().X(), DragStat().GetRef1().Y());
2234 
2235 	return aRetval;
2236 }
2237 
2238 void SdrDragShear::MoveSdrDrag(const Point& rPnt)
2239 {
2240 	if (DragStat().CheckMinMoved(rPnt))
2241 	{
2242 		bResize=!getSdrDragView().IsOrtho();
2243 		long nSA=0;
2244 
2245 		if (getSdrDragView().IsAngleSnapEnabled())
2246 			nSA=getSdrDragView().GetSnapAngle();
2247 
2248 		Point aP0(DragStat().GetStart());
2249 		Point aPnt(rPnt);
2250 		Fraction aNeuFact(1,1);
2251 
2252 		// Wenn kein Winkelfang, dann ggf. Rasterfang (ausser bei Slant)
2253 		if (nSA==0 && !bSlant)
2254 			aPnt=GetSnapPos(aPnt);
2255 
2256 		if (!bSlant && !bResize)
2257 		{ // Shear ohne Resize
2258 			if (bVertical)
2259 				aPnt.X()=aP0.X();
2260 			else
2261 				aPnt.Y()=aP0.Y();
2262 		}
2263 
2264 		Point aRef(DragStat().GetRef1());
2265 		Point aDif(aPnt-aRef);
2266 
2267 		long nNeuWink=0;
2268 
2269 		if (bSlant)
2270 		{
2271 			nNeuWink=NormAngle180(-(GetAngle(aDif)-nWink0));
2272 
2273 			if (bVertical)
2274 				nNeuWink=NormAngle180(-nNeuWink);
2275 		}
2276 		else
2277 		{
2278 			if (bVertical)
2279 				nNeuWink=NormAngle180(GetAngle(aDif));
2280 			else
2281 				nNeuWink=NormAngle180(-(GetAngle(aDif)-9000));
2282 
2283 			if (nNeuWink<-9000 || nNeuWink>9000)
2284 				nNeuWink=NormAngle180(nNeuWink+18000);
2285 
2286 			if (bResize)
2287 			{
2288 				Point aPt2(aPnt);
2289 
2290 				if (nSA!=0)
2291 					aPt2=GetSnapPos(aPnt); // den also in jedem Falle fangen
2292 
2293 				if (bVertical)
2294 				{
2295 					aNeuFact=Fraction(aPt2.X()-aRef.X(),aP0.X()-aRef.X());
2296 				}
2297 				else
2298 				{
2299 					aNeuFact=Fraction(aPt2.Y()-aRef.Y(),aP0.Y()-aRef.Y());
2300 				}
2301 			}
2302 		}
2303 
2304 		bool bNeg=nNeuWink<0;
2305 
2306 		if (bNeg)
2307 			nNeuWink=-nNeuWink;
2308 
2309 		if (nSA!=0)
2310 		{ // Winkelfang
2311 			nNeuWink+=nSA/2;
2312 			nNeuWink/=nSA;
2313 			nNeuWink*=nSA;
2314 		}
2315 
2316 		nNeuWink=NormAngle360(nNeuWink);
2317 		bUpSideDown=nNeuWink>9000 && nNeuWink<27000;
2318 
2319 		if (bSlant)
2320 		{ // Resize fuer Slant berechnen
2321 			// Mit Winkelfang jedoch ohne 89deg Begrenzung
2322 			long nTmpWink=nNeuWink;
2323 			if (bUpSideDown) nNeuWink-=18000;
2324 			if (bNeg) nTmpWink=-nTmpWink;
2325 			bResize=true;
2326 			double nCos=cos(nTmpWink*nPi180);
2327 			aNeuFact=nCos;
2328 			Kuerzen(aFact,10); // 3 Dezimalstellen sollten reichen
2329 		}
2330 
2331 		if (nNeuWink>8900)
2332 			nNeuWink=8900;
2333 
2334 		if (bNeg)
2335 			nNeuWink=-nNeuWink;
2336 
2337 		if (nWink!=nNeuWink || aFact!=aNeuFact)
2338 		{
2339 			nWink=nNeuWink;
2340 			aFact=aNeuFact;
2341 			double a=nWink*nPi180;
2342 			double nTan1=0.0;
2343 			nTan1=tan(a); // schonmal berechnen, damit mgl. wenig Zeit zwischen Hide() und Show() vergeht
2344 			Hide();
2345 			nTan=nTan1;
2346 			DragStat().NextMove(rPnt);
2347 			Show();
2348 		}
2349 	}
2350 }
2351 
2352 void SdrDragShear::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
2353 {
2354 	if (bResize)
2355 	{
2356 		if (bVertical)
2357 		{
2358             rTarget.Resize(DragStat().GetRef1(),aFact,Fraction(1,1));
2359 		}
2360 		else
2361 		{
2362             rTarget.Resize(DragStat().GetRef1(),Fraction(1,1),aFact);
2363 		}
2364 	}
2365 
2366 	if (nWink!=0)
2367 	{
2368 		rTarget.Shear(DragStat().GetRef1(),nWink,tan(nWink*nPi180),bVertical);
2369 	}
2370 }
2371 
2372 bool SdrDragShear::EndSdrDrag(bool bCopy)
2373 {
2374 	Hide();
2375 
2376 	if (bResize && aFact==Fraction(1,1))
2377 		bResize=false;
2378 
2379 	if (nWink!=0 || bResize)
2380 	{
2381 		if (nWink!=0 && bResize)
2382 		{
2383 			XubString aStr;
2384 			ImpTakeDescriptionStr(STR_EditShear,aStr);
2385 
2386 			if (bCopy)
2387 				aStr+=ImpGetResStr(STR_EditWithCopy);
2388 
2389 			getSdrDragView().BegUndo(aStr);
2390 		}
2391 
2392 		if (bResize)
2393 		{
2394 			if (bVertical)
2395 			{
2396 				getSdrDragView().ResizeMarkedObj(DragStat().GetRef1(),aFact,Fraction(1,1),bCopy);
2397 			}
2398 			else
2399 			{
2400 				getSdrDragView().ResizeMarkedObj(DragStat().GetRef1(),Fraction(1,1),aFact,bCopy);
2401 			}
2402 
2403 			bCopy=false;
2404 		}
2405 
2406 		if (nWink!=0)
2407 		{
2408 			getSdrDragView().ShearMarkedObj(DragStat().GetRef1(),nWink,bVertical,bCopy);
2409 		}
2410 
2411 		if (nWink!=0 && bResize)
2412 			getSdrDragView().EndUndo();
2413 
2414 		return true;
2415 	}
2416 
2417 	return false;
2418 }
2419 
2420 Pointer SdrDragShear::GetSdrDragPointer() const
2421 {
2422 	if (bVertical)
2423 		return Pointer(POINTER_VSHEAR);
2424 	else
2425 		return Pointer(POINTER_HSHEAR);
2426 }
2427 
2428 ////////////////////////////////////////////////////////////////////////////////////////////////////
2429 
2430 TYPEINIT1(SdrDragMirror,SdrDragMethod);
2431 
2432 void SdrDragMirror::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
2433 {
2434 	if(bMirrored)
2435 	{
2436         rTarget.Mirror(DragStat().GetRef1(), DragStat().GetRef2());
2437 	}
2438 }
2439 
2440 SdrDragMirror::SdrDragMirror(SdrDragView& rNewView)
2441 :	SdrDragMethod(rNewView),
2442 	nWink(0),
2443 	bMirrored(false),
2444 	bSide0(false)
2445 {
2446 }
2447 
2448 bool SdrDragMirror::ImpCheckSide(const Point& rPnt) const
2449 {
2450 	long nWink1=GetAngle(rPnt-DragStat().GetRef1());
2451 	nWink1-=nWink;
2452 	nWink1=NormAngle360(nWink1);
2453 
2454 	return nWink1<18000;
2455 }
2456 
2457 void SdrDragMirror::TakeSdrDragComment(XubString& rStr) const
2458 {
2459 	if (aDif.X()==0)
2460 		ImpTakeDescriptionStr(STR_DragMethMirrorHori,rStr);
2461 	else if (aDif.Y()==0)
2462 		ImpTakeDescriptionStr(STR_DragMethMirrorVert,rStr);
2463 	else if (Abs(aDif.X())==Abs(aDif.Y()))
2464 		ImpTakeDescriptionStr(STR_DragMethMirrorDiag,rStr);
2465 	else
2466 		ImpTakeDescriptionStr(STR_DragMethMirrorFree,rStr);
2467 
2468 	if (getSdrDragView().IsDragWithCopy())
2469 		rStr+=ImpGetResStr(STR_EditWithCopy);
2470 }
2471 
2472 bool SdrDragMirror::BeginSdrDrag()
2473 {
2474 	SdrHdl* pH1=GetHdlList().GetHdl(HDL_REF1);
2475 	SdrHdl* pH2=GetHdlList().GetHdl(HDL_REF2);
2476 
2477 	if (pH1!=NULL && pH2!=NULL)
2478 	{
2479 		DragStat().Ref1()=pH1->GetPos();
2480 		DragStat().Ref2()=pH2->GetPos();
2481 		Ref1()=pH1->GetPos();
2482 		Ref2()=pH2->GetPos();
2483 		aDif=pH2->GetPos()-pH1->GetPos();
2484 		bool b90=(aDif.X()==0) || aDif.Y()==0;
2485 		bool b45=b90 || (Abs(aDif.X())==Abs(aDif.Y()));
2486 		nWink=NormAngle360(GetAngle(aDif));
2487 
2488 		if (!getSdrDragView().IsMirrorAllowed(false,false) && !b45)
2489 			return false; // freier Achsenwinkel nicht erlaubt
2490 
2491 		if (!getSdrDragView().IsMirrorAllowed(true,false) && !b90)
2492 			return false;  // 45deg auch nicht erlaubt
2493 
2494 		bSide0=ImpCheckSide(DragStat().GetStart());
2495 		Show();
2496 		return true;
2497 	}
2498 	else
2499 	{
2500 		DBG_ERROR("SdrDragMirror::BeginSdrDrag(): Spiegelachse nicht gefunden");
2501 		return false;
2502 	}
2503 }
2504 
2505 basegfx::B2DHomMatrix SdrDragMirror::getCurrentTransformation()
2506 {
2507 	basegfx::B2DHomMatrix aRetval;
2508 
2509     if (bMirrored)
2510 	{
2511 	    const double fDeltaX(DragStat().GetRef2().X() - DragStat().GetRef1().X());
2512 	    const double fDeltaY(DragStat().GetRef2().Y() - DragStat().GetRef1().Y());
2513 	    const double fRotation(atan2(fDeltaY, fDeltaX));
2514 
2515         aRetval = basegfx::tools::createTranslateB2DHomMatrix(-DragStat().GetRef1().X(), -DragStat().GetRef1().Y());
2516 	    aRetval.rotate(-fRotation);
2517 	    aRetval.scale(1.0, -1.0);
2518 	    aRetval.rotate(fRotation);
2519 	    aRetval.translate(DragStat().GetRef1().X(), DragStat().GetRef1().Y());
2520     }
2521 
2522 	return aRetval;
2523 }
2524 
2525 void SdrDragMirror::MoveSdrDrag(const Point& rPnt)
2526 {
2527 	if (DragStat().CheckMinMoved(rPnt))
2528 	{
2529 		bool bNeuSide=ImpCheckSide(rPnt);
2530 		bool bNeuMirr=bSide0!=bNeuSide;
2531 
2532 		if (bMirrored!=bNeuMirr)
2533 		{
2534 			Hide();
2535 			bMirrored=bNeuMirr;
2536 			DragStat().NextMove(rPnt);
2537 			Show();
2538 		}
2539 	}
2540 }
2541 
2542 bool SdrDragMirror::EndSdrDrag(bool bCopy)
2543 {
2544 	Hide();
2545 
2546 	if (bMirrored)
2547 	{
2548 		getSdrDragView().MirrorMarkedObj(DragStat().GetRef1(),DragStat().GetRef2(),bCopy);
2549 	}
2550 
2551 	return true;
2552 }
2553 
2554 Pointer SdrDragMirror::GetSdrDragPointer() const
2555 {
2556 	return Pointer(POINTER_MIRROR);
2557 }
2558 
2559 ////////////////////////////////////////////////////////////////////////////////////////////////////
2560 
2561 TYPEINIT1(SdrDragGradient, SdrDragMethod);
2562 
2563 SdrDragGradient::SdrDragGradient(SdrDragView& rNewView, bool bGrad)
2564 :	SdrDragMethod(rNewView),
2565 	pIAOHandle(NULL),
2566 	bIsGradient(bGrad)
2567 {
2568 }
2569 
2570 void SdrDragGradient::TakeSdrDragComment(XubString& rStr) const
2571 {
2572 	if(IsGradient())
2573 		ImpTakeDescriptionStr(STR_DragMethGradient, rStr);
2574 	else
2575 		ImpTakeDescriptionStr(STR_DragMethTransparence, rStr);
2576 }
2577 
2578 bool SdrDragGradient::BeginSdrDrag()
2579 {
2580 	bool bRetval(false);
2581 
2582 	pIAOHandle = (SdrHdlGradient*)GetHdlList().GetHdl(IsGradient() ? HDL_GRAD : HDL_TRNS);
2583 
2584 	if(pIAOHandle)
2585 	{
2586 		// save old values
2587 		DragStat().Ref1() = pIAOHandle->GetPos();
2588 		DragStat().Ref2() = pIAOHandle->Get2ndPos();
2589 
2590 		// what was hit?
2591 		bool bHit(false);
2592 		SdrHdlColor* pColHdl = pIAOHandle->GetColorHdl1();
2593 
2594 		// init handling flags
2595 		pIAOHandle->SetMoveSingleHandle(false);
2596 		pIAOHandle->SetMoveFirstHandle(false);
2597 
2598 		// test first color handle
2599 		if(pColHdl)
2600 		{
2601 			basegfx::B2DPoint aPosition(DragStat().GetStart().X(), DragStat().GetStart().Y());
2602 
2603 			if(pColHdl->getOverlayObjectList().isHitLogic(aPosition))
2604 			{
2605 				bHit = true;
2606 				pIAOHandle->SetMoveSingleHandle(true);
2607 				pIAOHandle->SetMoveFirstHandle(true);
2608 			}
2609 		}
2610 
2611 		// test second color handle
2612 		pColHdl = pIAOHandle->GetColorHdl2();
2613 
2614 		if(!bHit && pColHdl)
2615 		{
2616 			basegfx::B2DPoint aPosition(DragStat().GetStart().X(), DragStat().GetStart().Y());
2617 
2618 			if(pColHdl->getOverlayObjectList().isHitLogic(aPosition))
2619 			{
2620 				bHit = true;
2621 				pIAOHandle->SetMoveSingleHandle(true);
2622 			}
2623 		}
2624 
2625 		// test gradient handle itself
2626 		if(!bHit)
2627 		{
2628 			basegfx::B2DPoint aPosition(DragStat().GetStart().X(), DragStat().GetStart().Y());
2629 
2630 			if(pIAOHandle->getOverlayObjectList().isHitLogic(aPosition))
2631 			{
2632 				bHit = true;
2633 			}
2634 		}
2635 
2636 		// everything up and running :o}
2637 		bRetval = bHit;
2638 	}
2639 	else
2640 	{
2641 		DBG_ERROR("SdrDragGradient::BeginSdrDrag(): IAOGradient nicht gefunden");
2642 	}
2643 
2644 	return bRetval;
2645 }
2646 
2647 void SdrDragGradient::MoveSdrDrag(const Point& rPnt)
2648 {
2649 	if(pIAOHandle && DragStat().CheckMinMoved(rPnt))
2650 	{
2651 		DragStat().NextMove(rPnt);
2652 
2653 		// Do the Move here!!! DragStat().GetStart()
2654 		Point aMoveDiff = rPnt - DragStat().GetStart();
2655 
2656 		if(pIAOHandle->IsMoveSingleHandle())
2657 		{
2658 			if(pIAOHandle->IsMoveFirstHandle())
2659 			{
2660 				pIAOHandle->SetPos(DragStat().Ref1() + aMoveDiff);
2661 				if(pIAOHandle->GetColorHdl1())
2662 					pIAOHandle->GetColorHdl1()->SetPos(DragStat().Ref1() + aMoveDiff);
2663 			}
2664 			else
2665 			{
2666 				pIAOHandle->Set2ndPos(DragStat().Ref2() + aMoveDiff);
2667 				if(pIAOHandle->GetColorHdl2())
2668 					pIAOHandle->GetColorHdl2()->SetPos(DragStat().Ref2() + aMoveDiff);
2669 			}
2670 		}
2671 		else
2672 		{
2673 			pIAOHandle->SetPos(DragStat().Ref1() + aMoveDiff);
2674 			pIAOHandle->Set2ndPos(DragStat().Ref2() + aMoveDiff);
2675 
2676 			if(pIAOHandle->GetColorHdl1())
2677 				pIAOHandle->GetColorHdl1()->SetPos(DragStat().Ref1() + aMoveDiff);
2678 
2679 			if(pIAOHandle->GetColorHdl2())
2680 				pIAOHandle->GetColorHdl2()->SetPos(DragStat().Ref2() + aMoveDiff);
2681 		}
2682 
2683 		// new state
2684 		pIAOHandle->FromIAOToItem(getSdrDragView().GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(), false, false);
2685 	}
2686 }
2687 
2688 bool SdrDragGradient::EndSdrDrag(bool /*bCopy*/)
2689 {
2690 	// here the result is clear, do something with the values
2691 	Ref1() = pIAOHandle->GetPos();
2692 	Ref2() = pIAOHandle->Get2ndPos();
2693 
2694 	// new state
2695 	pIAOHandle->FromIAOToItem(getSdrDragView().GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(), true, true);
2696 
2697 	return true;
2698 }
2699 
2700 void SdrDragGradient::CancelSdrDrag()
2701 {
2702 	// restore old values
2703 	pIAOHandle->SetPos(DragStat().Ref1());
2704 	pIAOHandle->Set2ndPos(DragStat().Ref2());
2705 
2706 	if(pIAOHandle->GetColorHdl1())
2707 		pIAOHandle->GetColorHdl1()->SetPos(DragStat().Ref1());
2708 
2709 	if(pIAOHandle->GetColorHdl2())
2710 		pIAOHandle->GetColorHdl2()->SetPos(DragStat().Ref2());
2711 
2712 	// new state
2713 	pIAOHandle->FromIAOToItem(getSdrDragView().GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(), true, false);
2714 }
2715 
2716 Pointer SdrDragGradient::GetSdrDragPointer() const
2717 {
2718 	return Pointer(POINTER_REFHAND);
2719 }
2720 
2721 ////////////////////////////////////////////////////////////////////////////////////////////////////
2722 
2723 TYPEINIT1(SdrDragCrook,SdrDragMethod);
2724 
2725 SdrDragCrook::SdrDragCrook(SdrDragView& rNewView)
2726 :	SdrDragMethod(rNewView),
2727 	aFact(1,1),
2728 	bContortionAllowed(false),
2729 	bNoContortionAllowed(false),
2730 	bContortion(false),
2731 	bResizeAllowed(false),
2732 	bResize(false),
2733 	bRotateAllowed(false),
2734 	bRotate(false),
2735 	bVertical(false),
2736 	bValid(false),
2737 	bLft(false),
2738 	bRgt(false),
2739 	bUpr(false),
2740 	bLwr(false),
2741 	bAtCenter(false),
2742 	nWink(0),
2743 	nMarkSize(0),
2744 	eMode(SDRCROOK_ROTATE)
2745 {
2746 }
2747 
2748 void SdrDragCrook::TakeSdrDragComment(XubString& rStr) const
2749 {
2750 	ImpTakeDescriptionStr(!bContortion ? STR_DragMethCrook : STR_DragMethCrookContortion, rStr);
2751 
2752 	if(bValid)
2753 	{
2754 		rStr.AppendAscii(" (");
2755 
2756 		XubString aStr;
2757 		sal_Int32 nVal(nWink);
2758 
2759 		if(bAtCenter)
2760 			nVal *= 2;
2761 
2762 		nVal = Abs(nVal);
2763 		getSdrDragView().GetModel()->TakeWinkStr(nVal, aStr);
2764 		rStr += aStr;
2765 		rStr += sal_Unicode(')');
2766 	}
2767 
2768 	if(getSdrDragView().IsDragWithCopy())
2769 		rStr += ImpGetResStr(STR_EditWithCopy);
2770 }
2771 
2772 // #96920# These defines parametrise the created raster
2773 // for interactions
2774 #define DRAG_CROOK_RASTER_MINIMUM	(4)
2775 #define DRAG_CROOK_RASTER_MAXIMUM	(15)
2776 #define DRAG_CROOK_RASTER_DISTANCE	(30)
2777 
2778 basegfx::B2DPolyPolygon impCreateDragRaster(SdrPageView& rPageView, const Rectangle& rMarkRect)
2779 {
2780     basegfx::B2DPolyPolygon aRetval;
2781 
2782 	if(rPageView.PageWindowCount())
2783 	{
2784 		OutputDevice& rOut = (rPageView.GetPageWindow(0)->GetPaintWindow().GetOutputDevice());
2785 		Rectangle aPixelSize = rOut.LogicToPixel(rMarkRect);
2786 		sal_uInt32 nHorDiv(aPixelSize.GetWidth() / DRAG_CROOK_RASTER_DISTANCE);
2787 		sal_uInt32 nVerDiv(aPixelSize.GetHeight() / DRAG_CROOK_RASTER_DISTANCE);
2788 
2789 		if(nHorDiv > DRAG_CROOK_RASTER_MAXIMUM)
2790 			nHorDiv = DRAG_CROOK_RASTER_MAXIMUM;
2791 		if(nHorDiv < DRAG_CROOK_RASTER_MINIMUM)
2792 			nHorDiv = DRAG_CROOK_RASTER_MINIMUM;
2793 
2794 		if(nVerDiv > DRAG_CROOK_RASTER_MAXIMUM)
2795 			nVerDiv = DRAG_CROOK_RASTER_MAXIMUM;
2796 		if(nVerDiv < DRAG_CROOK_RASTER_MINIMUM)
2797 			nVerDiv = DRAG_CROOK_RASTER_MINIMUM;
2798 
2799 	    const double fXLen(rMarkRect.GetWidth() / (double)nHorDiv);
2800 	    const double fYLen(rMarkRect.GetHeight() / (double)nVerDiv);
2801 	    double fYPos(rMarkRect.Top());
2802 	    sal_uInt32 a, b;
2803 
2804 	    for(a = 0; a <= nVerDiv; a++)
2805 	    {
2806 		    // hor lines
2807 		    for(b = 0; b < nHorDiv; b++)
2808 		    {
2809 			    basegfx::B2DPolygon aHorLineSegment;
2810 
2811 			    const double fNewX(rMarkRect.Left() + (b * fXLen));
2812 			    aHorLineSegment.append(basegfx::B2DPoint(fNewX, fYPos));
2813 			    aHorLineSegment.appendBezierSegment(
2814 				    basegfx::B2DPoint(fNewX + (fXLen * (1.0 / 3.0)), fYPos),
2815 				    basegfx::B2DPoint(fNewX + (fXLen * (2.0 / 3.0)), fYPos),
2816 				    basegfx::B2DPoint(fNewX + fXLen, fYPos));
2817 			    aRetval.append(aHorLineSegment);
2818 		    }
2819 
2820 		    // increments
2821 		    fYPos += fYLen;
2822 	    }
2823 
2824 	    double fXPos(rMarkRect.Left());
2825 
2826 	    for(a = 0; a <= nHorDiv; a++)
2827 	    {
2828 		    // ver lines
2829 		    for(b = 0; b < nVerDiv; b++)
2830 		    {
2831 			    basegfx::B2DPolygon aVerLineSegment;
2832 
2833 			    const double fNewY(rMarkRect.Top() + (b * fYLen));
2834 			    aVerLineSegment.append(basegfx::B2DPoint(fXPos, fNewY));
2835 			    aVerLineSegment.appendBezierSegment(
2836 				    basegfx::B2DPoint(fXPos, fNewY + (fYLen * (1.0 / 3.0))),
2837 				    basegfx::B2DPoint(fXPos, fNewY + (fYLen * (2.0 / 3.0))),
2838 				    basegfx::B2DPoint(fXPos, fNewY + fYLen));
2839 			    aRetval.append(aVerLineSegment);
2840 		    }
2841 
2842 		    // increments
2843 		    fXPos += fXLen;
2844 	    }
2845     }
2846 
2847     return aRetval;
2848 }
2849 
2850 void SdrDragCrook::createSdrDragEntries()
2851 {
2852 	// Add extended frame raster first, so it will be behind objects
2853     if(getSdrDragView().GetSdrPageView())
2854     {
2855         const basegfx::B2DPolyPolygon aDragRaster(impCreateDragRaster(*getSdrDragView().GetSdrPageView(), GetMarkedRect()));
2856 
2857         if(aDragRaster.count())
2858         {
2859             addSdrDragEntry(new SdrDragEntryPolyPolygon(aDragRaster));
2860         }
2861     }
2862 
2863     // call parent
2864     SdrDragMethod::createSdrDragEntries();
2865 }
2866 
2867 bool SdrDragCrook::BeginSdrDrag()
2868 {
2869 	bContortionAllowed=getSdrDragView().IsCrookAllowed(false);
2870 	bNoContortionAllowed=getSdrDragView().IsCrookAllowed(true);
2871 	bResizeAllowed=getSdrDragView().IsResizeAllowed(false);
2872 	bRotateAllowed=getSdrDragView().IsRotateAllowed(false);
2873 
2874 	if (bContortionAllowed || bNoContortionAllowed)
2875 	{
2876 		bVertical=(GetDragHdlKind()==HDL_LOWER || GetDragHdlKind()==HDL_UPPER);
2877 		aMarkRect=GetMarkedRect();
2878 		aMarkCenter=aMarkRect.Center();
2879 		nMarkSize=bVertical ? (aMarkRect.GetHeight()-1) : (aMarkRect.GetWidth()-1);
2880 		aCenter=aMarkCenter;
2881 		aStart=DragStat().GetStart();
2882 		Show();
2883 		return true;
2884 	}
2885 	else
2886 	{
2887 		return false;
2888 	}
2889 }
2890 
2891 void SdrDragCrook::_MovAllPoints(basegfx::B2DPolyPolygon& rTarget)
2892 {
2893 	SdrPageView* pPV = getSdrDragView().GetSdrPageView();
2894 
2895 	if(pPV)
2896 	{
2897 		XPolyPolygon aTempPolyPoly(rTarget);
2898 
2899 		if (pPV->HasMarkedObjPageView())
2900 		{
2901 			sal_uInt16 nPolyAnz=aTempPolyPoly.Count();
2902 
2903 			if (!bContortion && !getSdrDragView().IsNoDragXorPolys())
2904 			{
2905 				sal_uInt16 n1st=0,nLast=0;
2906 				Point aC(aCenter);
2907 
2908 				while (n1st<nPolyAnz)
2909 				{
2910 					nLast=n1st;
2911 					while (nLast<nPolyAnz && aTempPolyPoly[nLast].GetPointCount()!=0) nLast++;
2912 					Rectangle aBound(aTempPolyPoly[n1st].GetBoundRect());
2913 					sal_uInt16 i;
2914 
2915 					for (i=n1st+1; i<nLast; i++)
2916 					{
2917 						aBound.Union(aTempPolyPoly[n1st].GetBoundRect());
2918 					}
2919 
2920 					Point aCtr0(aBound.Center());
2921 					Point aCtr1(aCtr0);
2922 
2923 					if (bResize)
2924 					{
2925 						Fraction aFact1(1,1);
2926 
2927 						if (bVertical)
2928 						{
2929 							ResizePoint(aCtr1,aC,aFact1,aFact);
2930 						}
2931 						else
2932 						{
2933 							ResizePoint(aCtr1,aC,aFact,aFact1);
2934 						}
2935 					}
2936 
2937 					bool bRotOk=false;
2938 					double nSin=0,nCos=0;
2939 
2940 					if (aRad.X()!=0 && aRad.Y()!=0)
2941 					{
2942 						bRotOk=bRotate;
2943 
2944 						switch (eMode)
2945 						{
2946 							case SDRCROOK_ROTATE : CrookRotateXPoint (aCtr1,NULL,NULL,aC,aRad,nSin,nCos,bVertical);           break;
2947 							case SDRCROOK_SLANT  : CrookSlantXPoint  (aCtr1,NULL,NULL,aC,aRad,nSin,nCos,bVertical);           break;
2948 							case SDRCROOK_STRETCH: CrookStretchXPoint(aCtr1,NULL,NULL,aC,aRad,nSin,nCos,bVertical,aMarkRect); break;
2949 						} // switch
2950 					}
2951 
2952 					aCtr1-=aCtr0;
2953 
2954 					for (i=n1st; i<nLast; i++)
2955 					{
2956 						if (bRotOk)
2957 						{
2958 							RotateXPoly(aTempPolyPoly[i],aCtr0,nSin,nCos);
2959 						}
2960 
2961 						aTempPolyPoly[i].Move(aCtr1.X(),aCtr1.Y());
2962 					}
2963 
2964 					n1st=nLast+1;
2965 				}
2966 			}
2967 			else
2968 			{
2969 				sal_uInt16 i,j;
2970 
2971 				for (j=0; j<nPolyAnz; j++)
2972 				{
2973 					XPolygon& aPol=aTempPolyPoly[j];
2974 					sal_uInt16 nPtAnz=aPol.GetPointCount();
2975 					i=0;
2976 
2977 					while (i<nPtAnz)
2978 					{
2979 						Point* pPnt=&aPol[i];
2980 						Point* pC1=NULL;
2981 						Point* pC2=NULL;
2982 
2983 						if (i+1<nPtAnz && aPol.IsControl(i))
2984 						{ // Kontrollpunkt links
2985 							pC1=pPnt;
2986 							i++;
2987 							pPnt=&aPol[i];
2988 						}
2989 
2990 						i++;
2991 
2992 						if (i<nPtAnz && aPol.IsControl(i))
2993 						{ // Kontrollpunkt rechts
2994 							pC2=&aPol[i];
2995 							i++;
2996 						}
2997 
2998 						_MovCrookPoint(*pPnt,pC1,pC2);
2999 					}
3000 				}
3001 			}
3002 		}
3003 
3004 		rTarget = aTempPolyPoly.getB2DPolyPolygon();
3005 	}
3006 }
3007 
3008 void SdrDragCrook::_MovCrookPoint(Point& rPnt, Point* pC1, Point* pC2)
3009 {
3010 	bool bVert=bVertical;
3011 	bool bC1=pC1!=NULL;
3012 	bool bC2=pC2!=NULL;
3013 	Point aC(aCenter);
3014 
3015 	if (bResize)
3016 	{
3017 		Fraction aFact1(1,1);
3018 
3019 		if (bVert)
3020 		{
3021 			ResizePoint(rPnt,aC,aFact1,aFact);
3022 
3023 			if (bC1)
3024 				ResizePoint(*pC1,aC,aFact1,aFact);
3025 
3026 			if (bC2)
3027 				ResizePoint(*pC2,aC,aFact1,aFact);
3028 		}
3029 		else
3030 		{
3031 			ResizePoint(rPnt,aC,aFact,aFact1);
3032 
3033 			if (bC1)
3034 				ResizePoint(*pC1,aC,aFact,aFact1);
3035 
3036 			if (bC2)
3037 				ResizePoint(*pC2,aC,aFact,aFact1);
3038 		}
3039 	}
3040 
3041 	if (aRad.X()!=0 && aRad.Y()!=0)
3042 	{
3043 		double nSin,nCos;
3044 
3045 		switch (eMode)
3046 		{
3047 			case SDRCROOK_ROTATE : CrookRotateXPoint (rPnt,pC1,pC2,aC,aRad,nSin,nCos,bVert);           break;
3048 			case SDRCROOK_SLANT  : CrookSlantXPoint  (rPnt,pC1,pC2,aC,aRad,nSin,nCos,bVert);           break;
3049 			case SDRCROOK_STRETCH: CrookStretchXPoint(rPnt,pC1,pC2,aC,aRad,nSin,nCos,bVert,aMarkRect); break;
3050 		} // switch
3051 	}
3052 }
3053 
3054 void SdrDragCrook::MoveSdrDrag(const Point& rPnt)
3055 {
3056 	if (DragStat().CheckMinMoved(rPnt))
3057 	{
3058 		Point aPnt(rPnt);
3059 		bool bNeuMoveOnly=getSdrDragView().IsMoveOnlyDragging();
3060 		bAtCenter=false;
3061 		SdrCrookMode eNeuMode=getSdrDragView().GetCrookMode();
3062 		bool bNeuContortion=!bNeuMoveOnly && ((bContortionAllowed && !getSdrDragView().IsCrookNoContortion()) || !bNoContortionAllowed);
3063 		bResize=!getSdrDragView().IsOrtho() && bResizeAllowed && !bNeuMoveOnly;
3064 		bool bNeuRotate=bRotateAllowed && !bNeuContortion && !bNeuMoveOnly && eNeuMode==SDRCROOK_ROTATE;
3065 		long nSA=0;
3066 
3067 		if (nSA==0)
3068 			aPnt=GetSnapPos(aPnt);
3069 
3070 		Point aNeuCenter(aMarkCenter.X(),aStart.Y());
3071 
3072 		if (bVertical)
3073 		{
3074 			aNeuCenter.X()=aStart.X();
3075 			aNeuCenter.Y()=aMarkCenter.Y();
3076 		}
3077 
3078 		if (!getSdrDragView().IsCrookAtCenter())
3079 		{
3080 			switch (GetDragHdlKind())
3081 			{
3082 				case HDL_UPLFT: aNeuCenter.X()=aMarkRect.Right();  bLft=true; break;
3083 				case HDL_UPPER: aNeuCenter.Y()=aMarkRect.Bottom(); bUpr=true; break;
3084 				case HDL_UPRGT: aNeuCenter.X()=aMarkRect.Left();   bRgt=true; break;
3085 				case HDL_LEFT : aNeuCenter.X()=aMarkRect.Right();  bLft=true; break;
3086 				case HDL_RIGHT: aNeuCenter.X()=aMarkRect.Left();   bRgt=true; break;
3087 				case HDL_LWLFT: aNeuCenter.X()=aMarkRect.Right();  bLft=true; break;
3088 				case HDL_LOWER: aNeuCenter.Y()=aMarkRect.Top();    bLwr=true; break;
3089 				case HDL_LWRGT: aNeuCenter.X()=aMarkRect.Left();   bRgt=true; break;
3090 				default: bAtCenter=true;
3091 			}
3092 		}
3093 		else
3094 			bAtCenter=true;
3095 
3096 		Fraction aNeuFact(1,1);
3097 		long dx1=aPnt.X()-aNeuCenter.X();
3098 		long dy1=aPnt.Y()-aNeuCenter.Y();
3099 		bValid=bVertical ? dx1!=0 : dy1!=0;
3100 
3101 		if (bValid)
3102 		{
3103 			if (bVertical)
3104 				bValid=Abs(dx1)*100>Abs(dy1);
3105 			else
3106 				bValid=Abs(dy1)*100>Abs(dx1);
3107 		}
3108 
3109 		long nNeuRad=0;
3110 		nWink=0;
3111 
3112 		if (bValid)
3113 		{
3114 			double a=0; // Steigung des Radius
3115 			long nPntWink=0;
3116 
3117 			if (bVertical)
3118 			{
3119 				a=((double)dy1)/((double)dx1); // Steigung des Radius
3120 				nNeuRad=((long)(dy1*a)+dx1) /2;
3121 				aNeuCenter.X()+=nNeuRad;
3122 				nPntWink=GetAngle(aPnt-aNeuCenter);
3123 			}
3124 			else
3125 			{
3126 				a=((double)dx1)/((double)dy1); // Steigung des Radius
3127 				nNeuRad=((long)(dx1*a)+dy1) /2;
3128 				aNeuCenter.Y()+=nNeuRad;
3129 				nPntWink=GetAngle(aPnt-aNeuCenter)-9000;
3130 			}
3131 
3132 			if (!bAtCenter)
3133 			{
3134 				if (nNeuRad<0)
3135 				{
3136 					if (bRgt) nPntWink+=18000;
3137 					if (bLft) nPntWink=18000-nPntWink;
3138 					if (bLwr) nPntWink=-nPntWink;
3139 				}
3140 				else
3141 				{
3142 					if (bRgt) nPntWink=-nPntWink;
3143 					if (bUpr) nPntWink=18000-nPntWink;
3144 					if (bLwr) nPntWink+=18000;
3145 				}
3146 
3147 				nPntWink=NormAngle360(nPntWink);
3148 			}
3149 			else
3150 			{
3151 				if (nNeuRad<0) nPntWink+=18000;
3152 				if (bVertical) nPntWink=18000-nPntWink;
3153 				nPntWink=NormAngle180(nPntWink);
3154 				nPntWink=Abs(nPntWink);
3155 			}
3156 
3157 			double nUmfang=2*Abs(nNeuRad)*nPi;
3158 
3159 			if (bResize)
3160 			{
3161 				if (nSA!=0)
3162 				{ // Winkelfang
3163 					long nWink0=nPntWink;
3164 					nPntWink+=nSA/2;
3165 					nPntWink/=nSA;
3166 					nPntWink*=nSA;
3167 					BigInt a2(nNeuRad);
3168 					a2*=BigInt(nWink);
3169 					a2/=BigInt(nWink0);
3170 					nNeuRad=long(a2);
3171 
3172 					if (bVertical)
3173 						aNeuCenter.X()=aStart.X()+nNeuRad;
3174 					else
3175 						aNeuCenter.Y()=aStart.Y()+nNeuRad;
3176 				}
3177 
3178 				long nMul=(long)(nUmfang*NormAngle360(nPntWink)/36000);
3179 
3180 				if (bAtCenter)
3181 					nMul*=2;
3182 
3183 				aNeuFact=Fraction(nMul,nMarkSize);
3184 				nWink=nPntWink;
3185 			}
3186 			else
3187 			{
3188 				nWink=(long)((nMarkSize*360/nUmfang)*100)/2;
3189 
3190 				if (nWink==0)
3191 					bValid=false;
3192 
3193 				if (bValid && nSA!=0)
3194 				{ // Winkelfang
3195 					long nWink0=nWink;
3196 					nWink+=nSA/2;
3197 					nWink/=nSA;
3198 					nWink*=nSA;
3199 					BigInt a2(nNeuRad);
3200 					a2*=BigInt(nWink);
3201 					a2/=BigInt(nWink0);
3202 					nNeuRad=long(a2);
3203 
3204 					if (bVertical)
3205 						aNeuCenter.X()=aStart.X()+nNeuRad;
3206 					else
3207 						aNeuCenter.Y()=aStart.Y()+nNeuRad;
3208 				}
3209 			}
3210 		}
3211 
3212 		if (nWink==0 || nNeuRad==0)
3213 			bValid=false;
3214 
3215 		if (!bValid)
3216 			nNeuRad=0;
3217 
3218 		if (!bValid && bResize)
3219 		{
3220 			long nMul=bVertical ? dy1 : dx1;
3221 
3222 			if (bLft || bUpr)
3223 				nMul=-nMul;
3224 
3225 			long nDiv=nMarkSize;
3226 
3227 			if (bAtCenter)
3228 			{
3229 				nMul*=2;
3230 				nMul=Abs(nMul);
3231 			}
3232 
3233 			aNeuFact=Fraction(nMul,nDiv);
3234 		}
3235 
3236 		if (aNeuCenter!=aCenter || bNeuContortion!=bContortion || aNeuFact!=aFact ||
3237 			bNeuMoveOnly != getMoveOnly() || bNeuRotate!=bRotate || eNeuMode!=eMode)
3238 		{
3239 			Hide();
3240 			setMoveOnly(bNeuMoveOnly);
3241 			bRotate=bNeuRotate;
3242 			eMode=eNeuMode;
3243 			bContortion=bNeuContortion;
3244 			aCenter=aNeuCenter;
3245 			aFact=aNeuFact;
3246 			aRad=Point(nNeuRad,nNeuRad);
3247 			bResize=aFact!=Fraction(1,1) && aFact.GetDenominator()!=0 && aFact.IsValid();
3248 			DragStat().NextMove(aPnt);
3249 			Show();
3250 		}
3251 	}
3252 }
3253 
3254 void SdrDragCrook::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
3255 {
3256     const bool bDoResize(aFact!=Fraction(1,1));
3257 	const bool bDoCrook(aCenter!=aMarkCenter && aRad.X()!=0 && aRad.Y()!=0);
3258 
3259 	if (bDoCrook || bDoResize)
3260 	{
3261 		if (bDoResize)
3262 		{
3263 			Fraction aFact1(1,1);
3264 
3265 			if (bContortion)
3266 			{
3267 				if (bVertical)
3268                 {
3269                     rTarget.Resize(aCenter,aFact1,aFact);
3270                 }
3271 				else
3272                 {
3273                     rTarget.Resize(aCenter,aFact,aFact1);
3274                 }
3275 			}
3276 			else
3277 			{
3278 				Point aCtr0(rTarget.GetSnapRect().Center());
3279 				Point aCtr1(aCtr0);
3280 
3281 				if (bVertical)
3282                 {
3283 					ResizePoint(aCtr1,aCenter,aFact1,aFact);
3284                 }
3285 				else
3286                 {
3287 					ResizePoint(aCtr1,aCenter,aFact,aFact1);
3288                 }
3289 
3290 				Size aSiz(aCtr1.X()-aCtr0.X(),aCtr1.Y()-aCtr0.Y());
3291 
3292                 rTarget.Move(aSiz);
3293 			}
3294 		}
3295 
3296 		if (bDoCrook)
3297 		{
3298         	const Rectangle aLocalMarkRect(getSdrDragView().GetMarkedObjRect());
3299         	const bool bLocalRotate(!bContortion && eMode == SDRCROOK_ROTATE && getSdrDragView().IsRotateAllowed(false));
3300 
3301 			getSdrDragView().ImpCrookObj(&rTarget,aCenter,aRad,eMode,bVertical,!bContortion,bLocalRotate,aLocalMarkRect);
3302 		}
3303     }
3304 }
3305 
3306 void SdrDragCrook::applyCurrentTransformationToPolyPolygon(basegfx::B2DPolyPolygon& rTarget)
3307 {
3308 	// use helper derived from old stuff
3309 	_MovAllPoints(rTarget);
3310 }
3311 
3312 bool SdrDragCrook::EndSdrDrag(bool bCopy)
3313 {
3314 	Hide();
3315 
3316 	if (bResize && aFact==Fraction(1,1))
3317 		bResize=false;
3318 
3319 	const bool bUndo = getSdrDragView().IsUndoEnabled();
3320 
3321 	bool bDoCrook=aCenter!=aMarkCenter && aRad.X()!=0 && aRad.Y()!=0;
3322 
3323 	if (bDoCrook || bResize)
3324 	{
3325 		if (bResize && bUndo)
3326 		{
3327 			XubString aStr;
3328 			ImpTakeDescriptionStr(!bContortion?STR_EditCrook:STR_EditCrookContortion,aStr);
3329 
3330 			if (bCopy)
3331 				aStr+=ImpGetResStr(STR_EditWithCopy);
3332 
3333 			getSdrDragView().BegUndo(aStr);
3334 		}
3335 
3336 		if (bResize)
3337 		{
3338 			Fraction aFact1(1,1);
3339 
3340 			if (bContortion)
3341 			{
3342 				if (bVertical)
3343 					getSdrDragView().ResizeMarkedObj(aCenter,aFact1,aFact,bCopy);
3344 				else
3345 					getSdrDragView().ResizeMarkedObj(aCenter,aFact,aFact1,bCopy);
3346 			}
3347 			else
3348 			{
3349 				if (bCopy)
3350 					getSdrDragView().CopyMarkedObj();
3351 
3352 				sal_uLong nMarkAnz=getSdrDragView().GetMarkedObjectList().GetMarkCount();
3353 
3354 				for (sal_uLong nm=0; nm<nMarkAnz; nm++)
3355 				{
3356 					SdrMark* pM=getSdrDragView().GetMarkedObjectList().GetMark(nm);
3357 					SdrObject* pO=pM->GetMarkedSdrObj();
3358 					Point aCtr0(pO->GetSnapRect().Center());
3359 					Point aCtr1(aCtr0);
3360 
3361 					if (bVertical)
3362 						ResizePoint(aCtr1,aCenter,aFact1,aFact);
3363 					else
3364 						ResizePoint(aCtr1,aCenter,aFact,aFact1);
3365 
3366 					Size aSiz(aCtr1.X()-aCtr0.X(),aCtr1.Y()-aCtr0.Y());
3367 					if( bUndo )
3368 						AddUndo(getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoMoveObject(*pO,aSiz));
3369 					pO->Move(aSiz);
3370 				}
3371 			}
3372 
3373 			bCopy=false;
3374 		}
3375 
3376 		if (bDoCrook)
3377 		{
3378 			getSdrDragView().CrookMarkedObj(aCenter,aRad,eMode,bVertical,!bContortion,bCopy);
3379 			getSdrDragView().SetLastCrookCenter(aCenter);
3380 		}
3381 
3382 		if (bResize && bUndo)
3383 			getSdrDragView().EndUndo();
3384 
3385 		return true;
3386 	}
3387 
3388 	return false;
3389 }
3390 
3391 Pointer SdrDragCrook::GetSdrDragPointer() const
3392 {
3393 	return Pointer(POINTER_CROOK);
3394 }
3395 
3396 ////////////////////////////////////////////////////////////////////////////////////////////////////
3397 
3398 TYPEINIT1(SdrDragDistort,SdrDragMethod);
3399 
3400 SdrDragDistort::SdrDragDistort(SdrDragView& rNewView)
3401 :	SdrDragMethod(rNewView),
3402 	nPolyPt(0),
3403 	bContortionAllowed(false),
3404 	bNoContortionAllowed(false),
3405 	bContortion(false)
3406 {
3407 }
3408 
3409 void SdrDragDistort::TakeSdrDragComment(XubString& rStr) const
3410 {
3411 	ImpTakeDescriptionStr(STR_DragMethDistort, rStr);
3412 
3413 	XubString aStr;
3414 
3415 	rStr.AppendAscii(" (x=");
3416 	getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDX(), aStr);
3417 	rStr += aStr;
3418 	rStr.AppendAscii(" y=");
3419 	getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDY(), aStr);
3420 	rStr += aStr;
3421 	rStr += sal_Unicode(')');
3422 
3423 	if(getSdrDragView().IsDragWithCopy())
3424 		rStr += ImpGetResStr(STR_EditWithCopy);
3425 }
3426 
3427 void SdrDragDistort::createSdrDragEntries()
3428 {
3429 	// Add extended frame raster first, so it will be behind objects
3430     if(getSdrDragView().GetSdrPageView())
3431     {
3432         const basegfx::B2DPolyPolygon aDragRaster(impCreateDragRaster(*getSdrDragView().GetSdrPageView(), GetMarkedRect()));
3433 
3434         if(aDragRaster.count())
3435         {
3436             addSdrDragEntry(new SdrDragEntryPolyPolygon(aDragRaster));
3437         }
3438     }
3439 
3440     // call parent
3441     SdrDragMethod::createSdrDragEntries();
3442 }
3443 
3444 bool SdrDragDistort::BeginSdrDrag()
3445 {
3446 	bContortionAllowed=getSdrDragView().IsDistortAllowed(false);
3447 	bNoContortionAllowed=getSdrDragView().IsDistortAllowed(true);
3448 
3449 	if (bContortionAllowed || bNoContortionAllowed)
3450 	{
3451 		SdrHdlKind eKind=GetDragHdlKind();
3452 		nPolyPt=0xFFFF;
3453 
3454 		if (eKind==HDL_UPLFT) nPolyPt=0;
3455 		if (eKind==HDL_UPRGT) nPolyPt=1;
3456 		if (eKind==HDL_LWRGT) nPolyPt=2;
3457 		if (eKind==HDL_LWLFT) nPolyPt=3;
3458 		if (nPolyPt>3) return false;
3459 
3460 		aMarkRect=GetMarkedRect();
3461 		aDistortedRect=XPolygon(aMarkRect);
3462 		Show();
3463 		return true;
3464 	}
3465 	else
3466 	{
3467 		return false;
3468 	}
3469 }
3470 
3471 void SdrDragDistort::_MovAllPoints(basegfx::B2DPolyPolygon& rTarget)
3472 {
3473 	if (bContortion)
3474 	{
3475 		SdrPageView* pPV = getSdrDragView().GetSdrPageView();
3476 
3477 		if(pPV)
3478 		{
3479 			if (pPV->HasMarkedObjPageView())
3480 			{
3481 				basegfx::B2DPolyPolygon aDragPolygon(rTarget);
3482 				const basegfx::B2DRange aOriginalRange(aMarkRect.Left(), aMarkRect.Top(), aMarkRect.Right(), aMarkRect.Bottom());
3483 				const basegfx::B2DPoint aTopLeft(aDistortedRect[0].X(), aDistortedRect[0].Y());
3484 				const basegfx::B2DPoint aTopRight(aDistortedRect[1].X(), aDistortedRect[1].Y());
3485 				const basegfx::B2DPoint aBottomLeft(aDistortedRect[3].X(), aDistortedRect[3].Y());
3486 				const basegfx::B2DPoint aBottomRight(aDistortedRect[2].X(), aDistortedRect[2].Y());
3487 
3488                 aDragPolygon = basegfx::tools::distort(aDragPolygon, aOriginalRange, aTopLeft, aTopRight, aBottomLeft, aBottomRight);
3489 				rTarget = aDragPolygon;
3490 			}
3491 		}
3492 	}
3493 }
3494 
3495 void SdrDragDistort::MoveSdrDrag(const Point& rPnt)
3496 {
3497 	if (DragStat().CheckMinMoved(rPnt))
3498 	{
3499 		Point aPnt(GetSnapPos(rPnt));
3500 
3501 		if (getSdrDragView().IsOrtho())
3502 			OrthoDistance8(DragStat().GetStart(),aPnt,getSdrDragView().IsBigOrtho());
3503 
3504 		bool bNeuContortion=(bContortionAllowed && !getSdrDragView().IsCrookNoContortion()) || !bNoContortionAllowed;
3505 
3506 		if (bNeuContortion!=bContortion || aDistortedRect[nPolyPt]!=aPnt)
3507 		{
3508 			Hide();
3509 			aDistortedRect[nPolyPt]=aPnt;
3510 			bContortion=bNeuContortion;
3511 			DragStat().NextMove(aPnt);
3512 			Show();
3513 		}
3514 	}
3515 }
3516 
3517 bool SdrDragDistort::EndSdrDrag(bool bCopy)
3518 {
3519 	Hide();
3520 	bool bDoDistort=DragStat().GetDX()!=0 || DragStat().GetDY()!=0;
3521 
3522 	if (bDoDistort)
3523 	{
3524 		getSdrDragView().DistortMarkedObj(aMarkRect,aDistortedRect,!bContortion,bCopy);
3525 		return true;
3526 	}
3527 
3528 	return false;
3529 }
3530 
3531 Pointer SdrDragDistort::GetSdrDragPointer() const
3532 {
3533 	return Pointer(POINTER_REFHAND);
3534 }
3535 
3536 void SdrDragDistort::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
3537 {
3538 	const bool bDoDistort(DragStat().GetDX()!=0 || DragStat().GetDY()!=0);
3539 
3540 	if (bDoDistort)
3541 	{
3542 		getSdrDragView().ImpDistortObj(&rTarget, aMarkRect, aDistortedRect, !bContortion);
3543 	}
3544 }
3545 
3546 void SdrDragDistort::applyCurrentTransformationToPolyPolygon(basegfx::B2DPolyPolygon& rTarget)
3547 {
3548 	// use helper derived from old stuff
3549 	_MovAllPoints(rTarget);
3550 }
3551 
3552 ////////////////////////////////////////////////////////////////////////////////////////////////////
3553 
3554 TYPEINIT1(SdrDragCrop,SdrDragResize);
3555 
3556 SdrDragCrop::SdrDragCrop(SdrDragView& rNewView)
3557 :	SdrDragResize(rNewView)
3558 {
3559 	// switch off solid dragging for crop; it just makes no sense since showing
3560 	// a 50% transparent object above the original will not be visible
3561 	setSolidDraggingActive(false);
3562 }
3563 
3564 void SdrDragCrop::TakeSdrDragComment(XubString& rStr) const
3565 {
3566 	ImpTakeDescriptionStr(STR_DragMethCrop, rStr);
3567 
3568 	XubString aStr;
3569 
3570 	rStr.AppendAscii(" (x=");
3571 	getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDX(), aStr);
3572 	rStr += aStr;
3573 	rStr.AppendAscii(" y=");
3574 	getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDY(), aStr);
3575 	rStr += aStr;
3576 	rStr += sal_Unicode(')');
3577 
3578 	if(getSdrDragView().IsDragWithCopy())
3579 		rStr += ImpGetResStr(STR_EditWithCopy);
3580 }
3581 
3582 bool SdrDragCrop::EndSdrDrag(bool bCopy)
3583 {
3584 	Hide();
3585 
3586 	if( DragStat().GetDX()==0 && DragStat().GetDY()==0 )
3587 		return false;
3588 
3589 	const SdrMarkList& rMarkList = getSdrDragView().GetMarkedObjectList();
3590 
3591 	if( rMarkList.GetMarkCount() != 1 )
3592 		return false;
3593 
3594 	SdrGrafObj* pObj = dynamic_cast<SdrGrafObj*>( rMarkList.GetMark( 0 )->GetMarkedSdrObj() );
3595 
3596 	if( !pObj || (pObj->GetGraphicType() == GRAPHIC_NONE) || (pObj->GetGraphicType() == GRAPHIC_DEFAULT) )
3597 		return false;
3598 
3599 	const GraphicObject& rGraphicObject = pObj->GetGraphicObject();
3600 	const MapMode aMapMode100thmm(MAP_100TH_MM);
3601 	Size aGraphicSize(rGraphicObject.GetPrefSize());
3602 
3603     if( MAP_PIXEL == rGraphicObject.GetPrefMapMode().GetMapUnit() )
3604         aGraphicSize = Application::GetDefaultDevice()->PixelToLogic( aGraphicSize, aMapMode100thmm );
3605     else
3606 		aGraphicSize = Application::GetDefaultDevice()->LogicToLogic( aGraphicSize, rGraphicObject.GetPrefMapMode(), aMapMode100thmm);
3607 
3608 	if( aGraphicSize.nA == 0 || aGraphicSize.nB == 0 )
3609 		return false;
3610 
3611 	const SdrGrafCropItem& rOldCrop = (const SdrGrafCropItem&)pObj->GetMergedItem(SDRATTR_GRAFCROP);
3612 
3613 	const bool bUndo = getSdrDragView().IsUndoEnabled();
3614 
3615 	if( bUndo )
3616 	{
3617 		String aUndoStr;
3618 		ImpTakeDescriptionStr(STR_DragMethCrop, aUndoStr);
3619 
3620 	    getSdrDragView().BegUndo( aUndoStr );
3621 		getSdrDragView().AddUndo( getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoGeoObject( *pObj ) );
3622 	}
3623 
3624 	Rectangle aOldRect( pObj->GetLogicRect() );
3625 	getSdrDragView().ResizeMarkedObj(DragStat().Ref1(),aXFact,aYFact,bCopy);
3626 	Rectangle aNewRect( pObj->GetLogicRect() );
3627 
3628 	double fScaleX = ( aGraphicSize.Width() - rOldCrop.GetLeft() - rOldCrop.GetRight() ) / (double)aOldRect.GetWidth();
3629 	double fScaleY = ( aGraphicSize.Height() - rOldCrop.GetTop() - rOldCrop.GetBottom() ) / (double)aOldRect.GetHeight();
3630 
3631     // to correct the never working combination of cropped images and mirroring
3632     // I have to correct the rectangles the calculation is based on here. In the current
3633     // core geometry stuff a vertical mirror is expressed as 180 degree rotation. All
3634     // this can be removed again when aw080 will have cleaned up the old
3635     // (non-)transformation mess in the core.
3636     if(18000 == pObj->GetGeoStat().nDrehWink)
3637     {
3638         // old notation of vertical mirror, need to correct diffs since both rects
3639         // are rotated by 180 degrees
3640         aOldRect = Rectangle(aOldRect.TopLeft() - (aOldRect.BottomRight() - aOldRect.TopLeft()), aOldRect.TopLeft());
3641         aNewRect = Rectangle(aNewRect.TopLeft() - (aNewRect.BottomRight() - aNewRect.TopLeft()), aNewRect.TopLeft());
3642     }
3643 
3644 	sal_Int32 nDiffLeft = aNewRect.nLeft - aOldRect.nLeft;
3645 	sal_Int32 nDiffTop = aNewRect.nTop - aOldRect.nTop;
3646 	sal_Int32 nDiffRight = aNewRect.nRight - aOldRect.nRight;
3647 	sal_Int32 nDiffBottom = aNewRect.nBottom - aOldRect.nBottom;
3648 
3649 	sal_Int32 nLeftCrop = static_cast<sal_Int32>( rOldCrop.GetLeft() + nDiffLeft * fScaleX );
3650 	sal_Int32 nTopCrop = static_cast<sal_Int32>( rOldCrop.GetTop() + nDiffTop * fScaleY );
3651 	sal_Int32 nRightCrop = static_cast<sal_Int32>( rOldCrop.GetRight() - nDiffRight * fScaleX );
3652 	sal_Int32 nBottomCrop = static_cast<sal_Int32>( rOldCrop.GetBottom() - nDiffBottom * fScaleY );
3653 
3654 	SfxItemPool& rPool = getSdrDragView().GetModel()->GetItemPool();
3655 	SfxItemSet aSet( rPool, SDRATTR_GRAFCROP, SDRATTR_GRAFCROP );
3656 	aSet.Put( SdrGrafCropItem( nLeftCrop, nTopCrop, nRightCrop, nBottomCrop ) );
3657 	getSdrDragView().SetAttributes( aSet, false );
3658 
3659 	if( bUndo )
3660 		getSdrDragView().EndUndo();
3661 
3662 	return true;
3663 }
3664 
3665 Pointer SdrDragCrop::GetSdrDragPointer() const
3666 {
3667 	return Pointer(POINTER_CROP);
3668 }
3669 
3670 ////////////////////////////////////////////////////////////////////////////////////////////////////
3671 // eof
3672