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