xref: /trunk/main/svx/source/svdraw/svddrgmt.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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