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