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