xref: /trunk/main/svx/source/svdraw/svddrgv.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svx.hxx"
30 
31 #include <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