xref: /aoo41x/main/svx/source/svdraw/svddrgv.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svx.hxx"
30 
31 #include <svx/svddrgv.hxx>
32 #include "svx/xattr.hxx"
33 #include <svx/xpoly.hxx>
34 #include <svx/svdetc.hxx>
35 #include <svx/svdtrans.hxx>
36 #include <svx/svdundo.hxx>
37 #include <svx/svdocapt.hxx>
38 #include <svx/svdpagv.hxx>
39 #include <svx/svdopath.hxx>
40 #include <svx/svdoedge.hxx>
41 #include "svx/svdstr.hrc"
42 #include "svx/svdglob.hxx"
43 #include "svddrgm1.hxx"
44 #include <svx/obj3d.hxx>
45 #include <svx/svdoashp.hxx>
46 #include <svx/sdrpaintwindow.hxx>
47 #include <basegfx/polygon/b2dpolypolygontools.hxx>
48 #include <basegfx/polygon/b2dpolygontools.hxx>
49 #include <svx/polypolygoneditor.hxx>
50 #include <basegfx/matrix/b2dhommatrix.hxx>
51 #include <svx/sdr/overlay/overlaymanager.hxx>
52 
53 using namespace sdr;
54 
55 ////////////////////////////////////////////////////////////////////////////////////////////////////
56 ////////////////////////////////////////////////////////////////////////////////////////////////////
57 //
58 //  @@@@@  @@@@@   @@@@   @@@@   @@ @@ @@ @@@@@ @@   @@
59 //  @@  @@ @@  @@ @@  @@ @@  @@  @@ @@ @@ @@    @@   @@
60 //  @@  @@ @@  @@ @@  @@ @@      @@ @@ @@ @@    @@ @ @@
61 //  @@  @@ @@@@@  @@@@@@ @@ @@@  @@@@@ @@ @@@@  @@@@@@@
62 //  @@  @@ @@  @@ @@  @@ @@  @@   @@@  @@ @@    @@@@@@@
63 //  @@  @@ @@  @@ @@  @@ @@  @@   @@@  @@ @@    @@@ @@@
64 //  @@@@@  @@  @@ @@  @@  @@@@@    @   @@ @@@@@ @@   @@
65 //
66 ////////////////////////////////////////////////////////////////////////////////////////////////////
67 ////////////////////////////////////////////////////////////////////////////////////////////////////
68 
69 void SdrDragView::ImpClearVars()
70 {
71 	bFramDrag=sal_False;
72 	eDragMode=SDRDRAG_MOVE;
73 	bDragLimit=sal_False;
74 	bMarkedHitMovesAlways=sal_False;
75 	eDragHdl=HDL_MOVE;
76 	pDragHdl=NULL;
77 	bDragHdl=sal_False;
78 	bDragSpecial=sal_False;
79 	mpCurrentSdrDragMethod=NULL;
80 	bDragStripes=sal_False;
81 	bMirrRefDragObj=sal_True;
82 	bDragWithCopy=sal_False;
83 	pInsPointUndo=NULL;
84 	bInsGluePoint=sal_False;
85 	bInsObjPointMode=sal_False;
86 	bInsGluePointMode=sal_False;
87 	nDragXorPolyLimit=100;
88 	nDragXorPointLimit=500;
89 	bNoDragXorPolys=sal_False;
90 	bAutoVertexCon=sal_True;
91 	bAutoCornerCon=sal_False;
92 	bRubberEdgeDragging=sal_True;
93 	nRubberEdgeDraggingLimit=100;
94 	bDetailedEdgeDragging=sal_True;
95 	nDetailedEdgeDraggingLimit=10;
96 	bResizeAtCenter=sal_False;
97 	bCrookAtCenter=sal_False;
98 	bMouseHideWhileDraggingPoints=sal_False;
99 
100 	// init using default
101 	mbSolidDragging = getOptionsDrawinglayer().IsSolidDragCreate();
102 }
103 
104 void SdrDragView::ImpMakeDragAttr()
105 {
106 	ImpDelDragAttr();
107 }
108 
109 SdrDragView::SdrDragView(SdrModel* pModel1, OutputDevice* pOut)
110 :	SdrExchangeView(pModel1,pOut)
111 {
112 	ImpClearVars();
113 	ImpMakeDragAttr();
114 }
115 
116 SdrDragView::~SdrDragView()
117 {
118 	ImpDelDragAttr();
119 }
120 
121 void SdrDragView::ImpDelDragAttr()
122 {
123 }
124 
125 sal_Bool SdrDragView::IsAction() const
126 {
127 	return (mpCurrentSdrDragMethod || SdrExchangeView::IsAction());
128 }
129 
130 void SdrDragView::MovAction(const Point& rPnt)
131 {
132 	SdrExchangeView::MovAction(rPnt);
133 	if (mpCurrentSdrDragMethod)
134 	{
135 		MovDragObj(rPnt);
136 	}
137 }
138 
139 void SdrDragView::EndAction()
140 {
141 	if (mpCurrentSdrDragMethod)
142 	{
143 		EndDragObj(sal_False);
144 	}
145 	SdrExchangeView::EndAction();
146 }
147 
148 void SdrDragView::BckAction()
149 {
150 	SdrExchangeView::BckAction();
151 	BrkDragObj();
152 }
153 
154 void SdrDragView::BrkAction()
155 {
156 	SdrExchangeView::BrkAction();
157 	BrkDragObj();
158 }
159 
160 void SdrDragView::TakeActionRect(Rectangle& rRect) const
161 {
162 	if (mpCurrentSdrDragMethod)
163 	{
164 		rRect=aDragStat.GetActionRect();
165 		if (rRect.IsEmpty())
166 		{
167 			SdrPageView* pPV = GetSdrPageView();
168 
169 			if(pPV&& pPV->HasMarkedObjPageView())
170 			{
171                 // #i95646# is this used..?
172                 const basegfx::B2DRange aBoundRange(mpCurrentSdrDragMethod->getCurrentRange());
173 				rRect = Rectangle(
174                     basegfx::fround(aBoundRange.getMinX()), basegfx::fround(aBoundRange.getMinY()),
175                     basegfx::fround(aBoundRange.getMaxX()), basegfx::fround(aBoundRange.getMaxY()));
176 			}
177 		}
178 		if (rRect.IsEmpty())
179 		{
180 			rRect=Rectangle(aDragStat.GetNow(),aDragStat.GetNow());
181 		}
182 	}
183 	else
184 	{
185 		SdrExchangeView::TakeActionRect(rRect);
186 	}
187 }
188 
189 sal_Bool SdrDragView::TakeDragObjAnchorPos(Point& rPos, sal_Bool bTR ) const
190 {
191 	Rectangle aR;
192 	TakeActionRect(aR);
193 	rPos = bTR ? aR.TopRight() : aR.TopLeft();
194 	if (GetMarkedObjectCount()==1 && IsDragObj() && // nur bei Einzelselektion
195 		!IsDraggingPoints() && !IsDraggingGluePoints() && // nicht beim Punkteschieben
196 		!mpCurrentSdrDragMethod->ISA(SdrDragMovHdl)) // nicht beim Handlesschieben
197 	{
198 		SdrObject* pObj=GetMarkedObjectByIndex(0);
199 		if (pObj->ISA(SdrCaptionObj))
200 		{
201 			Point aPt(((SdrCaptionObj*)pObj)->GetTailPos());
202 			sal_Bool bTail=eDragHdl==HDL_POLY; // Schwanz wird gedraggt (nicht so ganz feine Abfrage hier)
203 			sal_Bool bOwn=mpCurrentSdrDragMethod->ISA(SdrDragObjOwn); // Objektspeziefisch
204 			if (!bTail)
205 			{ // bei bTail liefert TakeActionRect schon das richtige
206 				if (bOwn)
207 				{ // bOwn kann sein MoveTextFrame, ResizeTextFrame aber eben nicht mehr DragTail
208 					rPos=aPt;
209 				}
210 				else
211 				{
212 					// drag the whole Object (Move, Resize, ...)
213 					const basegfx::B2DPoint aTransformed(mpCurrentSdrDragMethod->getCurrentTransformation() * basegfx::B2DPoint(aPt.X(), aPt.Y()));
214 					rPos.X() = basegfx::fround(aTransformed.getX());
215 					rPos.Y() = basegfx::fround(aTransformed.getY());
216 				}
217 			}
218 		}
219 		return sal_True;
220 	}
221 	return sal_False;
222 }
223 
224 ////////////////////////////////////////////////////////////////////////////////////////////////////
225 
226 sal_Bool SdrDragView::TakeDragLimit(SdrDragMode /*eMode*/, Rectangle& /*rRect*/) const
227 {
228 	return sal_False;
229 }
230 
231 sal_Bool SdrDragView::BegDragObj(const Point& rPnt, OutputDevice* pOut, SdrHdl* pHdl, short nMinMov, SdrDragMethod* pForcedMeth)
232 {
233 	BrkAction();
234 
235 	bool bRet=false;
236 	{
237 		SetDragWithCopy(sal_False);
238 		//ForceEdgesOfMarkedNodes();
239 		//TODO: aAni.Reset();
240 		mpCurrentSdrDragMethod=NULL;
241 		bDragSpecial=sal_False;
242 		bDragLimit=sal_False;
243 		SdrDragMode eTmpMode=eDragMode;
244 		if (eTmpMode==SDRDRAG_MOVE && pHdl!=NULL && pHdl->GetKind()!=HDL_MOVE) {
245 			eTmpMode=SDRDRAG_RESIZE;
246 		}
247 		bDragLimit=TakeDragLimit(eTmpMode,aDragLimit);
248 		bFramDrag=ImpIsFrameHandles();
249 		if (!bFramDrag &&
250 			(pMarkedObj==NULL || !pMarkedObj->hasSpecialDrag()) &&
251 			(pHdl==NULL || pHdl->GetObj()==NULL)) {
252 			bFramDrag=sal_True;
253 		}
254 
255 		Point aPnt(rPnt);
256 		if(pHdl == NULL
257 			|| pHdl->GetKind() == HDL_MOVE
258 			|| pHdl->GetKind() == HDL_MIRX
259 			|| pHdl->GetKind() == HDL_TRNS
260 			|| pHdl->GetKind() == HDL_GRAD)
261 		{
262 			aDragStat.Reset(aPnt);
263 		}
264 		else
265 		{
266 			aDragStat.Reset(pHdl->GetPos());
267 		}
268 
269 		aDragStat.SetView((SdrView*)this);
270 		aDragStat.SetPageView(pMarkedPV);  // <<-- hier muss die DragPV rein!!!
271 		aDragStat.SetMinMove(ImpGetMinMovLogic(nMinMov,pOut));
272 		aDragStat.SetHdl(pHdl);
273 		aDragStat.NextPoint();
274 		pDragWin=pOut;
275 		pDragHdl=pHdl;
276 		eDragHdl= pHdl==NULL ? HDL_MOVE : pHdl->GetKind();
277 		bDragHdl=eDragHdl==HDL_REF1 || eDragHdl==HDL_REF2 || eDragHdl==HDL_MIRX;
278 
279 		// #103894# Expand test for HDL_ANCHOR_TR
280 		sal_Bool bNotDraggable = (HDL_ANCHOR == eDragHdl || HDL_ANCHOR_TR == eDragHdl);
281 
282 		if(pHdl && (pHdl->GetKind() == HDL_SMARTTAG) && pForcedMeth )
283 		{
284 			// just use the forced method for smart tags
285 		}
286 		else if(bDragHdl)
287 		{
288 			mpCurrentSdrDragMethod = new SdrDragMovHdl(*this);
289 		}
290 		else if(!bNotDraggable)
291 		{
292 			switch (eDragMode)
293 			{
294 				case SDRDRAG_ROTATE: case SDRDRAG_SHEAR: case SDRDRAG_DISTORT:
295 				{
296 					switch (eDragHdl)
297 					{
298 						case HDL_LEFT:  case HDL_RIGHT:
299 						case HDL_UPPER: case HDL_LOWER:
300 						{
301 							// Sind 3D-Objekte selektiert?
302 							sal_Bool b3DObjSelected = sal_False;
303 							for(sal_uInt32 a=0;!b3DObjSelected && a<GetMarkedObjectCount();a++)
304 							{
305 								SdrObject* pObj = GetMarkedObjectByIndex(a);
306 								if(pObj && pObj->ISA(E3dObject))
307 									b3DObjSelected = sal_True;
308 							}
309 							// Falls ja, Shear auch bei !IsShearAllowed zulassen,
310 							// da es sich bei 3D-Objekten um eingeschraenkte
311 							// Rotationen handelt
312 							if (!b3DObjSelected && !IsShearAllowed())
313 								return sal_False;
314 							mpCurrentSdrDragMethod = new SdrDragShear(*this,eDragMode==SDRDRAG_ROTATE);
315 						} break;
316 						case HDL_UPLFT: case HDL_UPRGT:
317 						case HDL_LWLFT: case HDL_LWRGT:
318 						{
319 							if (eDragMode==SDRDRAG_SHEAR || eDragMode==SDRDRAG_DISTORT)
320 							{
321 								if (!IsDistortAllowed(sal_True) && !IsDistortAllowed(sal_False)) return sal_False;
322 								mpCurrentSdrDragMethod = new SdrDragDistort(*this);
323 							}
324 							else
325 							{
326 								if (!IsRotateAllowed(sal_True)) return sal_False;
327 								mpCurrentSdrDragMethod = new SdrDragRotate(*this);
328 							}
329 						} break;
330 						default:
331 						{
332 							if (IsMarkedHitMovesAlways() && eDragHdl==HDL_MOVE)
333 							{ // HDL_MOVE ist auch wenn Obj direkt getroffen
334 								if (!IsMoveAllowed()) return sal_False;
335 								mpCurrentSdrDragMethod = new SdrDragMove(*this);
336 							}
337 							else
338 							{
339 								if (!IsRotateAllowed(sal_True)) return sal_False;
340 								mpCurrentSdrDragMethod = new SdrDragRotate(*this);
341 							}
342 						}
343 					}
344 				} break;
345 				case SDRDRAG_MIRROR:
346 				{
347 					if (eDragHdl==HDL_MOVE && IsMarkedHitMovesAlways())
348 					{
349 						if (!IsMoveAllowed()) return sal_False;
350 						mpCurrentSdrDragMethod = new SdrDragMove(*this);
351 					}
352 					else
353 					{
354 						if (!IsMirrorAllowed(sal_True,sal_True)) return sal_False;
355 						mpCurrentSdrDragMethod = new SdrDragMirror(*this);
356 					}
357 				} break;
358 
359 				case SDRDRAG_CROP:
360 				{
361 					if (eDragHdl==HDL_MOVE && IsMarkedHitMovesAlways())
362 					{
363 						if (!IsMoveAllowed())
364 							return sal_False;
365 						mpCurrentSdrDragMethod = new SdrDragMove(*this);
366 					}
367 					else
368 					{
369 						if (!IsCrookAllowed(sal_True) && !IsCrookAllowed(sal_False))
370 							return sal_False;
371 						mpCurrentSdrDragMethod = new SdrDragCrop(*this);
372 					}
373 				}
374 				break;
375 
376 				case SDRDRAG_TRANSPARENCE:
377 				{
378 					if(eDragHdl == HDL_MOVE && IsMarkedHitMovesAlways())
379 					{
380 						if(!IsMoveAllowed())
381 							return sal_False;
382 						mpCurrentSdrDragMethod = new SdrDragMove(*this);
383 					}
384 					else
385 					{
386 						if(!IsTransparenceAllowed())
387 							return sal_False;
388 
389 						mpCurrentSdrDragMethod = new SdrDragGradient(*this, sal_False);
390 					}
391 					break;
392 				}
393 				case SDRDRAG_GRADIENT:
394 				{
395 					if(eDragHdl == HDL_MOVE && IsMarkedHitMovesAlways())
396 					{
397 						if(!IsMoveAllowed())
398 							return sal_False;
399 						mpCurrentSdrDragMethod = new SdrDragMove(*this);
400 					}
401 					else
402 					{
403 						if(!IsGradientAllowed())
404 							return sal_False;
405 
406 						mpCurrentSdrDragMethod = new SdrDragGradient(*this);
407 					}
408 					break;
409 				}
410 
411 				case SDRDRAG_CROOK :
412 				{
413 					if (eDragHdl==HDL_MOVE && IsMarkedHitMovesAlways())
414 					{
415 						if (!IsMoveAllowed()) return sal_False;
416 						mpCurrentSdrDragMethod = new SdrDragMove(*this);
417 					}
418 					else
419 					{
420 						if (!IsCrookAllowed(sal_True) && !IsCrookAllowed(sal_False)) return sal_False;
421 						mpCurrentSdrDragMethod = new SdrDragCrook(*this);
422 					}
423 				} break;
424 
425 				default:
426 				{
427 					// SDRDRAG_MOVE
428 					if((eDragHdl == HDL_MOVE) && !IsMoveAllowed())
429 					{
430 						return sal_False;
431 					}
432 					else if(eDragHdl == HDL_GLUE)
433 					{
434 						mpCurrentSdrDragMethod = new SdrDragMove(*this);
435 					}
436 					else
437 					{
438 						if(bFramDrag)
439 						{
440 							if(eDragHdl == HDL_MOVE)
441 							{
442 								mpCurrentSdrDragMethod = new SdrDragMove(*this);
443 							}
444 							else
445 							{
446 								if(!IsResizeAllowed(sal_True))
447 								{
448 									return sal_False;
449 								}
450 
451 								sal_Bool bSingleTextObjMark = sal_False;	// SJ: #i100490#
452 								if ( GetMarkedObjectCount() == 1 )
453 								{
454 									pMarkedObj=GetMarkedObjectByIndex(0);
455 									if ( pMarkedObj &&
456 										pMarkedObj->ISA( SdrTextObj ) &&
457 										static_cast<SdrTextObj*>(pMarkedObj)->IsTextFrame() )
458 										bSingleTextObjMark = sal_True;
459 								}
460 								if ( bSingleTextObjMark )
461 									mpCurrentSdrDragMethod = new SdrDragObjOwn(*this);
462 								else
463 									mpCurrentSdrDragMethod = new SdrDragResize(*this);
464 							}
465 						}
466 						else
467 						{
468 							if(HDL_MOVE == eDragHdl)
469 							{
470                                 const bool bCustomShapeSelected(1 == GetMarkedObjectCount() && GetMarkedObjectByIndex(0)->ISA(SdrObjCustomShape));
471 
472                                 if(bCustomShapeSelected)
473                                 {
474     								mpCurrentSdrDragMethod = new SdrDragMove( *this );
475                                 }
476 							}
477 							else if(HDL_POLY == eDragHdl)
478                             {
479                                 const bool bConnectorSelected(1 == GetMarkedObjectCount() && GetMarkedObjectByIndex(0)->ISA(SdrEdgeObj));
480 
481                                 if(bConnectorSelected)
482                                 {
483                                     // #i97784#
484                                     // fallback to old behaviour for connectors (see
485                                     // text in task description for more details)
486                                 }
487                                 else if(!IsMoveAllowed() || !IsResizeAllowed())
488     							{
489 	    							// #i77187#
490                                     // do not allow move of polygon points if object is move or size protected
491 		    						return sal_False;
492                                 }
493                             }
494 
495                             if(!mpCurrentSdrDragMethod)
496                             {
497                                 // fallback to DragSpecial if no interaction defined
498                                 bDragSpecial = sal_True;
499 								mpCurrentSdrDragMethod = new SdrDragObjOwn(*this);
500 							}
501 						}
502 					}
503 				}
504 			}
505 		}
506 		if (pForcedMeth!=NULL)
507 		{
508             delete mpCurrentSdrDragMethod;
509 			mpCurrentSdrDragMethod = pForcedMeth;
510 		}
511 		aDragStat.SetDragMethod(mpCurrentSdrDragMethod);
512 		if (mpCurrentSdrDragMethod)
513 		{
514 			bRet = mpCurrentSdrDragMethod->BeginSdrDrag();
515 			if (!bRet)
516 			{
517 				if (pHdl==NULL && IS_TYPE(SdrDragObjOwn,mpCurrentSdrDragMethod))
518 				{
519 					// Aha, Obj kann nicht Move SpecialDrag, also MoveFrameDrag versuchen
520                     delete mpCurrentSdrDragMethod;
521                     mpCurrentSdrDragMethod = 0;
522 					bDragSpecial=sal_False;
523 
524                     if (!IsMoveAllowed())
525                         return sal_False;
526 
527                     bFramDrag=sal_True;
528 					mpCurrentSdrDragMethod = new SdrDragMove(*this);
529 					aDragStat.SetDragMethod(mpCurrentSdrDragMethod);
530 					bRet = mpCurrentSdrDragMethod->BeginSdrDrag();
531 				}
532 			}
533 			if (!bRet)
534 			{
535                 delete mpCurrentSdrDragMethod;
536                 mpCurrentSdrDragMethod = 0;
537 				aDragStat.SetDragMethod(mpCurrentSdrDragMethod);
538 			}
539 		}
540 	}
541 
542 	return bRet;
543 }
544 
545 void SdrDragView::MovDragObj(const Point& rPnt)
546 {
547 	if (mpCurrentSdrDragMethod)
548 	{
549 		Point aPnt(rPnt);
550 		ImpLimitToWorkArea(aPnt);
551 		mpCurrentSdrDragMethod->MoveSdrDrag(aPnt); // this call already makes a Hide()/Show combination
552 	}
553 }
554 
555 sal_Bool SdrDragView::EndDragObj(sal_Bool bCopy)
556 {
557 	bool bRet(false);
558 
559 	// #i73341# If insert GluePoint, do not insist on last points being different
560 	if(mpCurrentSdrDragMethod && aDragStat.IsMinMoved() && (IsInsertGluePoint() || aDragStat.GetNow() != aDragStat.GetPrev()))
561 	{
562 		sal_uIntPtr nHdlAnzMerk=0;
563 
564 		if (bEliminatePolyPoints)
565 		{ // IBM Special
566 			nHdlAnzMerk=GetMarkablePointCount();
567 		}
568 
569 		const bool bUndo = IsUndoEnabled();
570         if (IsInsertGluePoint() && bUndo)
571 		{
572 			BegUndo(aInsPointUndoStr);
573 			AddUndo(pInsPointUndo);
574 		}
575 
576         bRet = mpCurrentSdrDragMethod->EndSdrDrag(bCopy);
577 
578         if( IsInsertGluePoint() && bUndo)
579             EndUndo();
580 
581         delete mpCurrentSdrDragMethod;
582         mpCurrentSdrDragMethod = 0;
583 
584         if (bEliminatePolyPoints)
585 		{ // IBM Special
586 			if (nHdlAnzMerk!=GetMarkablePointCount())
587 			{
588 				UnmarkAllPoints();
589 			}
590 		}
591 
592         if (bInsPolyPoint)
593 		{
594 			SetMarkHandles();
595 			bInsPolyPoint=sal_False;
596 			if( bUndo )
597 			{
598 				BegUndo(aInsPointUndoStr);
599 				AddUndo(pInsPointUndo);
600 				EndUndo();
601 			}
602 		}
603 
604 		eDragHdl=HDL_MOVE;
605 		pDragHdl=NULL;
606 
607 		if (!bSomeObjChgdFlag)
608 		{
609 			// Aha, Obj hat nicht gebroadcastet (z.B. Writer FlyFrames)
610 			if(!bDragHdl)
611 			{
612 				AdjustMarkHdl();
613 			}
614 		}
615 	}
616 	else
617 	{
618 		BrkDragObj();
619 	}
620 
621     bInsPolyPoint=sal_False;
622 	SetInsertGluePoint(sal_False);
623 
624 	return bRet;
625 }
626 
627 void SdrDragView::BrkDragObj()
628 {
629 	if (mpCurrentSdrDragMethod)
630 	{
631 		mpCurrentSdrDragMethod->CancelSdrDrag();
632 
633         delete mpCurrentSdrDragMethod;
634         mpCurrentSdrDragMethod = 0;
635 
636         if (bInsPolyPoint)
637 		{
638 			pInsPointUndo->Undo(); // Den eingefuegten Punkt wieder raus
639 			delete pInsPointUndo;
640 			pInsPointUndo=NULL;
641 			SetMarkHandles();
642 			bInsPolyPoint=sal_False;
643 		}
644 
645         if (IsInsertGluePoint())
646 		{
647 			pInsPointUndo->Undo(); // Den eingefuegten Klebepunkt wieder raus
648 			delete pInsPointUndo;
649 			pInsPointUndo=NULL;
650 			SetInsertGluePoint(sal_False);
651 		}
652 
653         eDragHdl=HDL_MOVE;
654 		pDragHdl=NULL;
655 	}
656 }
657 
658 sal_Bool SdrDragView::IsInsObjPointPossible() const
659 {
660 	return pMarkedObj!=NULL && pMarkedObj->IsPolyObj();
661 }
662 
663 sal_Bool SdrDragView::ImpBegInsObjPoint(sal_Bool bIdxZwang, sal_uInt32 nIdx, const Point& rPnt, sal_Bool bNewObj, OutputDevice* pOut)
664 {
665 	sal_Bool bRet(sal_False);
666 
667 	if(pMarkedObj && pMarkedObj->ISA(SdrPathObj))
668 	{
669 		SdrPathObj* pMarkedPath = (SdrPathObj*)pMarkedObj;
670 		BrkAction();
671 		pInsPointUndo = dynamic_cast< SdrUndoGeoObj* >( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pMarkedObj) );
672 		DBG_ASSERT( pInsPointUndo, "svx::SdrDragView::BegInsObjPoint(), could not create correct undo object!" );
673 
674 		XubString aStr(ImpGetResStr(STR_DragInsertPoint));
675 		XubString aName;
676         pMarkedObj->TakeObjNameSingul(aName);
677 		xub_StrLen nPos(aStr.SearchAscii("%1"));
678 
679 		if(STRING_NOTFOUND != nPos)
680 		{
681 			aStr.Erase(nPos, 2);
682 			aStr.Insert(aName, nPos);
683 		}
684 
685 		aInsPointUndoStr = aStr;
686 		Point aPt(rPnt);
687 
688 		if(bNewObj)
689 			aPt = GetSnapPos(aPt,pMarkedPV);
690 
691 		sal_Bool bClosed0(pMarkedPath->IsClosedObj());
692 
693 		if(bIdxZwang)
694 		{
695 			mnInsPointNum = pMarkedPath->NbcInsPoint(nIdx, aPt, bNewObj, sal_True);
696 		}
697 		else
698 		{
699 			mnInsPointNum = pMarkedPath->NbcInsPointOld(aPt, bNewObj, sal_True);
700 		}
701 
702 		if(bClosed0 != pMarkedPath->IsClosedObj())
703 		{
704 			// Obj was closed implicit
705 			// object changed
706 			pMarkedPath->SetChanged();
707 			pMarkedPath->BroadcastObjectChange();
708 		}
709 
710 		if(0xffffffff != mnInsPointNum)
711 		{
712 			bInsPolyPoint = sal_True;
713 			UnmarkAllPoints();
714 			AdjustMarkHdl();
715 
716 			bRet = BegDragObj(rPnt, pOut, aHdl.GetHdl(mnInsPointNum), 0);
717 
718 			if (bRet)
719 			{
720 				aDragStat.SetMinMoved();
721 				MovDragObj(rPnt);
722 			}
723 		}
724 		else
725 		{
726 			delete pInsPointUndo;
727 			pInsPointUndo = NULL;
728 		}
729 	}
730 
731 	return bRet;
732 }
733 
734 sal_Bool SdrDragView::EndInsObjPoint(SdrCreateCmd eCmd)
735 {
736 	if(IsInsObjPoint())
737 	{
738 		sal_uInt32 nNextPnt(mnInsPointNum);
739 		Point aPnt(aDragStat.GetNow());
740 		sal_Bool bOk=EndDragObj(sal_False);
741 		if (bOk==sal_True && eCmd!=SDRCREATE_FORCEEND)
742 		{
743 			// Ret=True bedeutet: Action ist vorbei.
744 			bOk=!(ImpBegInsObjPoint(sal_True, nNextPnt, aPnt, eCmd == SDRCREATE_NEXTOBJECT, pDragWin));
745 		}
746 
747 		return bOk;
748 	} else return sal_False;
749 }
750 
751 sal_Bool SdrDragView::IsInsGluePointPossible() const
752 {
753 	sal_Bool bRet=sal_False;
754 	if (IsInsGluePointMode() && AreObjectsMarked())
755 	{
756 		if (GetMarkedObjectCount()==1)
757 		{
758 			// sal_False liefern, wenn 1 Objekt und dieses ein Verbinder ist.
759 			const SdrObject* pObj=GetMarkedObjectByIndex(0);
760 			if (!HAS_BASE(SdrEdgeObj,pObj))
761 			{
762 			   bRet=sal_True;
763 			}
764 		}
765 		else
766 		{
767 			bRet=sal_True;
768 		}
769 	}
770 	return bRet;
771 }
772 
773 sal_Bool SdrDragView::BegInsGluePoint(const Point& rPnt)
774 {
775 	sal_Bool bRet=sal_False;
776 	SdrObject* pObj;
777 	SdrPageView* pPV;
778 	sal_uIntPtr nMarkNum;
779 	if (PickMarkedObj(rPnt,pObj,pPV,&nMarkNum,SDRSEARCH_PASS2BOUND))
780 	{
781 		BrkAction();
782 		UnmarkAllGluePoints();
783 		pInsPointUndo= dynamic_cast< SdrUndoGeoObj* >( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj) );
784 		DBG_ASSERT( pInsPointUndo, "svx::SdrDragView::BegInsObjPoint(), could not create correct undo object!" );
785 		XubString aStr(ImpGetResStr(STR_DragInsertGluePoint));
786 		XubString aName; pObj->TakeObjNameSingul(aName);
787 
788 		aStr.SearchAndReplaceAscii("%1", aName);
789 
790 		aInsPointUndoStr=aStr;
791 		SdrGluePointList* pGPL=pObj->ForceGluePointList();
792 		if (pGPL!=NULL)
793 		{
794 			sal_uInt16 nGlueIdx=pGPL->Insert(SdrGluePoint());
795 			SdrGluePoint& rGP=(*pGPL)[nGlueIdx];
796 			sal_uInt16 nGlueId=rGP.GetId();
797 			rGP.SetAbsolutePos(rPnt,*pObj);
798 
799 			SdrHdl* pHdl=NULL;
800 			if (MarkGluePoint(pObj,nGlueId,pPV))
801 			{
802 				pHdl=GetGluePointHdl(pObj,nGlueId);
803 			}
804 			if (pHdl!=NULL && pHdl->GetKind()==HDL_GLUE && pHdl->GetObj()==pObj && pHdl->GetObjHdlNum()==nGlueId)
805 			{
806 				SetInsertGluePoint(sal_True);
807 				bRet=BegDragObj(rPnt,NULL,pHdl,0);
808 				if (bRet)
809 				{
810 					aDragStat.SetMinMoved();
811 					MovDragObj(rPnt);
812 				}
813 				else
814 				{
815 					SetInsertGluePoint(sal_False);
816 					delete pInsPointUndo;
817 					pInsPointUndo=NULL;
818 				}
819 			}
820 			else
821 			{
822 				DBG_ERROR("BegInsGluePoint(): GluePoint-Handle nicht gefunden");
823 			}
824 		}
825 		else
826 		{
827 			// Keine Klebepunkte moeglich bei diesem Objekt (z.B. Edge)
828 			SetInsertGluePoint(sal_False);
829 			delete pInsPointUndo;
830 			pInsPointUndo=NULL;
831 		}
832 	}
833 
834 	return bRet;
835 }
836 
837 void SdrDragView::ShowDragObj()
838 {
839 	if(mpCurrentSdrDragMethod && !aDragStat.IsShown())
840 	{
841         for(sal_uInt32 a(0); a < PaintWindowCount(); a++)
842         {
843 	        SdrPaintWindow* pCandidate = GetPaintWindow(a);
844 	        sdr::overlay::OverlayManager* pOverlayManager = pCandidate->GetOverlayManager();
845 
846 	        if(pOverlayManager)
847 	        {
848 		        mpCurrentSdrDragMethod->CreateOverlayGeometry(*pOverlayManager);
849 
850 				// #i101679# Force changed overlay to be shown
851 				pOverlayManager->flush();
852 	        }
853         }
854 
855 		aDragStat.SetShown(sal_True);
856 	}
857 }
858 
859 void SdrDragView::HideDragObj()
860 {
861 	if(mpCurrentSdrDragMethod && aDragStat.IsShown())
862 	{
863         mpCurrentSdrDragMethod->destroyOverlayGeometry();
864 		aDragStat.SetShown(sal_False);
865 	}
866 }
867 
868 ////////////////////////////////////////////////////////////////////////////////////////////////////
869 
870 void SdrDragView::SetNoDragXorPolys(sal_Bool bOn)
871 {
872 	if (IsNoDragXorPolys()!=bOn)
873 	{
874 		const bool bDragging(mpCurrentSdrDragMethod);
875 		const bool bShown(bDragging && aDragStat.IsShown());
876 
877         if(bShown)
878         {
879             HideDragObj();
880         }
881 
882 		bNoDragXorPolys = bOn;
883 
884 		if(bDragging)
885 		{
886             // force recreation of drag content
887             mpCurrentSdrDragMethod->resetSdrDragEntries();
888 		}
889 
890 		if(bShown)
891         {
892 			ShowDragObj();
893         }
894 	}
895 }
896 
897 void SdrDragView::SetDragStripes(sal_Bool bOn)
898 {
899 	if (mpCurrentSdrDragMethod && aDragStat.IsShown())
900 	{
901 		HideDragObj();
902 		bDragStripes=bOn;
903 		ShowDragObj();
904 	}
905 	else
906 	{
907 		bDragStripes=bOn;
908 	}
909 }
910 
911 sal_Bool SdrDragView::IsOrthoDesired() const
912 {
913 	if(mpCurrentSdrDragMethod && (IS_TYPE(SdrDragObjOwn, mpCurrentSdrDragMethod) || IS_TYPE(SdrDragResize, mpCurrentSdrDragMethod)))
914 	{
915 		return bOrthoDesiredOnMarked;
916 	}
917 
918     return sal_False;
919 }
920 
921 ////////////////////////////////////////////////////////////////////////////////////////////////////
922 
923 void SdrDragView::SetRubberEdgeDragging(sal_Bool bOn)
924 {
925 	if (bOn!=IsRubberEdgeDragging())
926 	{
927 		sal_uIntPtr nAnz = GetEdgesOfMarkedNodes().GetMarkCount();
928 		sal_Bool bShowHide=nAnz!=0 && IsDragObj() &&
929 				 (nRubberEdgeDraggingLimit>=nAnz);
930 		if (bShowHide)
931 			HideDragObj();
932 		bRubberEdgeDragging=bOn;
933 		if (bShowHide)
934 			ShowDragObj();
935 	}
936 }
937 
938 void SdrDragView::SetRubberEdgeDraggingLimit(sal_uInt16 nEdgeObjAnz)
939 {
940 	if (nEdgeObjAnz!=nRubberEdgeDraggingLimit)
941 	{
942 		sal_uIntPtr nAnz = GetEdgesOfMarkedNodes().GetMarkCount();
943 		sal_Bool bShowHide=IsRubberEdgeDragging() && nAnz!=0 && IsDragObj() &&
944 				 (nEdgeObjAnz>=nAnz)!=(nRubberEdgeDraggingLimit>=nAnz);
945 		if (bShowHide)
946 			HideDragObj();
947 		nRubberEdgeDraggingLimit=nEdgeObjAnz;
948 		if (bShowHide)
949 			ShowDragObj();
950 	}
951 }
952 
953 void SdrDragView::SetDetailedEdgeDragging(sal_Bool bOn)
954 {
955 	if (bOn!=IsDetailedEdgeDragging())
956 	{
957 		sal_uIntPtr nAnz = GetEdgesOfMarkedNodes().GetMarkCount();
958 		sal_Bool bShowHide=nAnz!=0 && IsDragObj() &&
959 				 (nDetailedEdgeDraggingLimit>=nAnz);
960 		if (bShowHide)
961 			HideDragObj();
962 		bDetailedEdgeDragging=bOn;
963 		if (bShowHide)
964 			ShowDragObj();
965 	}
966 }
967 
968 void SdrDragView::SetDetailedEdgeDraggingLimit(sal_uInt16 nEdgeObjAnz)
969 {
970 	if (nEdgeObjAnz!=nDetailedEdgeDraggingLimit)
971 	{
972 		sal_uIntPtr nAnz = GetEdgesOfMarkedNodes().GetMarkCount();
973 		sal_Bool bShowHide=IsDetailedEdgeDragging() && nAnz!=0 && IsDragObj() &&
974 				 (nEdgeObjAnz>=nAnz)!=(nDetailedEdgeDraggingLimit>=nAnz);
975 		if (bShowHide)
976 			HideDragObj();
977 		nDetailedEdgeDraggingLimit=nEdgeObjAnz;
978 		if (bShowHide)
979 			ShowDragObj();
980 	}
981 }
982 
983 void SdrDragView::SetMarkHandles()
984 {
985 	if( pDragHdl )
986 		pDragHdl = 0;
987 
988 	SdrExchangeView::SetMarkHandles();
989 }
990 
991 void SdrDragView::SetSolidDragging(bool bOn)
992 {
993 	if((bool)mbSolidDragging != bOn)
994 	{
995 		mbSolidDragging = bOn;
996 	}
997 }
998 
999 bool SdrDragView::IsSolidDragging() const
1000 {
1001 	// allow each user to disable by having a local setting, but using AND for
1002 	// checking allowance
1003 	return mbSolidDragging && getOptionsDrawinglayer().IsSolidDragCreate();
1004 }
1005 
1006 // eof
1007