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