Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include <svx/svddrgv.hxx>
22 : #include "svx/xattr.hxx"
23 : #include <svx/xpoly.hxx>
24 : #include <svx/svdetc.hxx>
25 : #include <svx/svdtrans.hxx>
26 : #include <svx/svdundo.hxx>
27 : #include <svx/svdocapt.hxx>
28 : #include <svx/svdpagv.hxx>
29 : #include <svx/svdopath.hxx>
30 : #include <svx/svdoedge.hxx>
31 : #include "svx/svdstr.hrc"
32 : #include "svx/svdglob.hxx"
33 : #include "svddrgm1.hxx"
34 : #include <svx/obj3d.hxx>
35 : #include <svx/svdoashp.hxx>
36 : #include <svx/sdrpaintwindow.hxx>
37 : #include <basegfx/polygon/b2dpolypolygontools.hxx>
38 : #include <basegfx/polygon/b2dpolygontools.hxx>
39 : #include <svx/polypolygoneditor.hxx>
40 : #include <basegfx/matrix/b2dhommatrix.hxx>
41 : #include <svx/sdr/overlay/overlaymanager.hxx>
42 :
43 : using namespace sdr;
44 :
45 :
46 :
47 : // DragView
48 :
49 :
50 :
51 0 : void SdrDragView::ImpClearVars()
52 : {
53 0 : bFramDrag=false;
54 0 : eDragMode=SDRDRAG_MOVE;
55 0 : bDragLimit=false;
56 0 : bMarkedHitMovesAlways=false;
57 0 : eDragHdl=HDL_MOVE;
58 0 : pDragHdl=NULL;
59 0 : bDragHdl=false;
60 0 : bDragSpecial=false;
61 0 : mpCurrentSdrDragMethod=NULL;
62 0 : bDragStripes=false;
63 0 : bMirrRefDragObj=true;
64 0 : bDragWithCopy=false;
65 0 : pInsPointUndo=NULL;
66 0 : bInsGluePoint=false;
67 0 : bInsObjPointMode=false;
68 0 : bInsGluePointMode=false;
69 0 : nDragXorPolyLimit=100;
70 0 : nDragXorPointLimit=500;
71 0 : bNoDragXorPolys=false;
72 0 : bAutoVertexCon=true;
73 0 : bAutoCornerCon=false;
74 0 : bRubberEdgeDragging=true;
75 0 : bDetailedEdgeDragging=true;
76 0 : nDetailedEdgeDraggingLimit=10;
77 0 : bResizeAtCenter=false;
78 0 : bCrookAtCenter=false;
79 0 : bMouseHideWhileDraggingPoints=false;
80 :
81 : // init using default
82 0 : mbSolidDragging = getOptionsDrawinglayer().IsSolidDragCreate();
83 0 : }
84 :
85 0 : SdrDragView::SdrDragView(SdrModel* pModel1, OutputDevice* pOut)
86 0 : : SdrExchangeView(pModel1,pOut)
87 : {
88 0 : ImpClearVars();
89 0 : }
90 :
91 0 : SdrDragView::~SdrDragView()
92 : {
93 0 : }
94 :
95 0 : bool SdrDragView::IsAction() const
96 : {
97 0 : return (mpCurrentSdrDragMethod || SdrExchangeView::IsAction());
98 : }
99 :
100 0 : void SdrDragView::MovAction(const Point& rPnt)
101 : {
102 0 : SdrExchangeView::MovAction(rPnt);
103 0 : if (mpCurrentSdrDragMethod)
104 : {
105 0 : MovDragObj(rPnt);
106 : }
107 0 : }
108 :
109 0 : void SdrDragView::EndAction()
110 : {
111 0 : if (mpCurrentSdrDragMethod)
112 : {
113 0 : EndDragObj(false);
114 : }
115 0 : SdrExchangeView::EndAction();
116 0 : }
117 :
118 0 : void SdrDragView::BckAction()
119 : {
120 0 : SdrExchangeView::BckAction();
121 0 : BrkDragObj();
122 0 : }
123 :
124 0 : void SdrDragView::BrkAction()
125 : {
126 0 : SdrExchangeView::BrkAction();
127 0 : BrkDragObj();
128 0 : }
129 :
130 0 : void SdrDragView::TakeActionRect(Rectangle& rRect) const
131 : {
132 0 : if (mpCurrentSdrDragMethod)
133 : {
134 0 : rRect=aDragStat.GetActionRect();
135 0 : if (rRect.IsEmpty())
136 : {
137 0 : SdrPageView* pPV = GetSdrPageView();
138 :
139 0 : if(pPV&& pPV->HasMarkedObjPageView())
140 : {
141 : // #i95646# is this used..?
142 0 : const basegfx::B2DRange aBoundRange(mpCurrentSdrDragMethod->getCurrentRange());
143 : rRect = Rectangle(
144 : basegfx::fround(aBoundRange.getMinX()), basegfx::fround(aBoundRange.getMinY()),
145 0 : basegfx::fround(aBoundRange.getMaxX()), basegfx::fround(aBoundRange.getMaxY()));
146 : }
147 : }
148 0 : if (rRect.IsEmpty())
149 : {
150 0 : rRect=Rectangle(aDragStat.GetNow(),aDragStat.GetNow());
151 : }
152 : }
153 : else
154 : {
155 0 : SdrExchangeView::TakeActionRect(rRect);
156 : }
157 0 : }
158 :
159 0 : bool SdrDragView::TakeDragObjAnchorPos(Point& rPos, bool bTR ) const
160 : {
161 0 : Rectangle aR;
162 0 : TakeActionRect(aR);
163 0 : rPos = bTR ? aR.TopRight() : aR.TopLeft();
164 0 : if (GetMarkedObjectCount()==1 && IsDragObj() && // only on single selection
165 0 : !IsDraggingPoints() && !IsDraggingGluePoints() && // not when moving points
166 0 : !mpCurrentSdrDragMethod->ISA(SdrDragMovHdl)) // not when moving handles
167 : {
168 0 : SdrObject* pObj=GetMarkedObjectByIndex(0);
169 0 : if (pObj->ISA(SdrCaptionObj))
170 : {
171 0 : Point aPt(((SdrCaptionObj*)pObj)->GetTailPos());
172 0 : bool bTail=eDragHdl==HDL_POLY; // drag tail
173 0 : sal_Bool bOwn=mpCurrentSdrDragMethod->ISA(SdrDragObjOwn); // specific to object
174 0 : if (!bTail)
175 : { // for bTail, TakeActionRect already does the right thing
176 0 : if (bOwn)
177 : { // bOwn may be MoveTextFrame, ResizeTextFrame, but may not (any more) be DragTail
178 0 : rPos=aPt;
179 : }
180 : else
181 : {
182 : // drag the whole Object (Move, Resize, ...)
183 0 : const basegfx::B2DPoint aTransformed(mpCurrentSdrDragMethod->getCurrentTransformation() * basegfx::B2DPoint(aPt.X(), aPt.Y()));
184 0 : rPos.X() = basegfx::fround(aTransformed.getX());
185 0 : rPos.Y() = basegfx::fround(aTransformed.getY());
186 : }
187 : }
188 : }
189 0 : return true;
190 : }
191 0 : return false;
192 : }
193 :
194 :
195 :
196 0 : bool SdrDragView::TakeDragLimit(SdrDragMode /*eMode*/, Rectangle& /*rRect*/) const
197 : {
198 0 : return false;
199 : }
200 :
201 0 : bool SdrDragView::BegDragObj(const Point& rPnt, OutputDevice* pOut, SdrHdl* pHdl, short nMinMov, SdrDragMethod* pForcedMeth)
202 : {
203 0 : BrkAction();
204 :
205 0 : bool bRet=false;
206 : {
207 0 : SetDragWithCopy(false);
208 : //TODO: aAni.Reset();
209 0 : mpCurrentSdrDragMethod=NULL;
210 0 : bDragSpecial=false;
211 0 : bDragLimit=false;
212 0 : SdrDragMode eTmpMode=eDragMode;
213 0 : if (eTmpMode==SDRDRAG_MOVE && pHdl!=NULL && pHdl->GetKind()!=HDL_MOVE) {
214 0 : eTmpMode=SDRDRAG_RESIZE;
215 : }
216 0 : bDragLimit=TakeDragLimit(eTmpMode,aDragLimit);
217 0 : bFramDrag=ImpIsFrameHandles();
218 0 : if (!bFramDrag &&
219 0 : (pMarkedObj==NULL || !pMarkedObj->hasSpecialDrag()) &&
220 0 : (pHdl==NULL || pHdl->GetObj()==NULL)) {
221 0 : bFramDrag=true;
222 : }
223 :
224 0 : Point aPnt(rPnt);
225 0 : if(pHdl == NULL
226 0 : || pHdl->GetKind() == HDL_MOVE
227 0 : || pHdl->GetKind() == HDL_MIRX
228 0 : || pHdl->GetKind() == HDL_TRNS
229 0 : || pHdl->GetKind() == HDL_GRAD)
230 : {
231 0 : aDragStat.Reset(aPnt);
232 : }
233 : else
234 : {
235 0 : aDragStat.Reset(pHdl->GetPos());
236 : }
237 :
238 0 : aDragStat.SetView((SdrView*)this);
239 0 : aDragStat.SetPageView(pMarkedPV); // <<-- DragPV has to go here!!!
240 0 : aDragStat.SetMinMove(ImpGetMinMovLogic(nMinMov,pOut));
241 0 : aDragStat.SetHdl(pHdl);
242 0 : aDragStat.NextPoint();
243 0 : pDragWin=pOut;
244 0 : pDragHdl=pHdl;
245 0 : eDragHdl= pHdl==NULL ? HDL_MOVE : pHdl->GetKind();
246 0 : bDragHdl=eDragHdl==HDL_REF1 || eDragHdl==HDL_REF2 || eDragHdl==HDL_MIRX;
247 :
248 : // Expand test for HDL_ANCHOR_TR
249 0 : bool bNotDraggable = (HDL_ANCHOR == eDragHdl || HDL_ANCHOR_TR == eDragHdl);
250 :
251 0 : if(pHdl && (pHdl->GetKind() == HDL_SMARTTAG) && pForcedMeth )
252 : {
253 : // just use the forced method for smart tags
254 : }
255 0 : else if(bDragHdl)
256 : {
257 0 : mpCurrentSdrDragMethod = new SdrDragMovHdl(*this);
258 : }
259 0 : else if(!bNotDraggable)
260 : {
261 0 : switch (eDragMode)
262 : {
263 : case SDRDRAG_ROTATE: case SDRDRAG_SHEAR: case SDRDRAG_DISTORT:
264 : {
265 0 : switch (eDragHdl)
266 : {
267 : case HDL_LEFT: case HDL_RIGHT:
268 : case HDL_UPPER: case HDL_LOWER:
269 : {
270 : // are 3D objects selected?
271 0 : bool b3DObjSelected = false;
272 0 : for(sal_uInt32 a=0;!b3DObjSelected && a<GetMarkedObjectCount();a++)
273 : {
274 0 : SdrObject* pObj = GetMarkedObjectByIndex(a);
275 0 : if(pObj && pObj->ISA(E3dObject))
276 0 : b3DObjSelected = true;
277 : }
278 : // If yes, allow shear even when !IsShearAllowed,
279 : // because 3D objects are limited rotations
280 0 : if (!b3DObjSelected && !IsShearAllowed())
281 0 : return false;
282 0 : mpCurrentSdrDragMethod = new SdrDragShear(*this,eDragMode==SDRDRAG_ROTATE);
283 0 : } break;
284 : case HDL_UPLFT: case HDL_UPRGT:
285 : case HDL_LWLFT: case HDL_LWRGT:
286 : {
287 0 : if (eDragMode==SDRDRAG_SHEAR || eDragMode==SDRDRAG_DISTORT)
288 : {
289 0 : if (!IsDistortAllowed(true) && !IsDistortAllowed(false)) return false;
290 0 : mpCurrentSdrDragMethod = new SdrDragDistort(*this);
291 : }
292 : else
293 : {
294 0 : if (!IsRotateAllowed(true)) return false;
295 0 : mpCurrentSdrDragMethod = new SdrDragRotate(*this);
296 : }
297 0 : } break;
298 : default:
299 : {
300 0 : if (IsMarkedHitMovesAlways() && eDragHdl==HDL_MOVE)
301 : { // HDL_MOVE is true, even if Obj is hit directly
302 0 : if (!IsMoveAllowed()) return false;
303 0 : mpCurrentSdrDragMethod = new SdrDragMove(*this);
304 : }
305 : else
306 : {
307 0 : if (!IsRotateAllowed(true)) return false;
308 0 : mpCurrentSdrDragMethod = new SdrDragRotate(*this);
309 : }
310 : }
311 : }
312 0 : } break;
313 : case SDRDRAG_MIRROR:
314 : {
315 0 : if (eDragHdl==HDL_MOVE && IsMarkedHitMovesAlways())
316 : {
317 0 : if (!IsMoveAllowed()) return false;
318 0 : mpCurrentSdrDragMethod = new SdrDragMove(*this);
319 : }
320 : else
321 : {
322 0 : if (!IsMirrorAllowed(true,true)) return false;
323 0 : mpCurrentSdrDragMethod = new SdrDragMirror(*this);
324 : }
325 0 : } break;
326 :
327 : case SDRDRAG_CROP:
328 : {
329 0 : if (eDragHdl==HDL_MOVE && IsMarkedHitMovesAlways())
330 : {
331 0 : if (!IsMoveAllowed())
332 0 : return false;
333 0 : mpCurrentSdrDragMethod = new SdrDragMove(*this);
334 : }
335 : else
336 : {
337 0 : if (!IsCrookAllowed(true) && !IsCrookAllowed(false))
338 0 : return false;
339 0 : mpCurrentSdrDragMethod = new SdrDragCrop(*this);
340 : }
341 : }
342 0 : break;
343 :
344 : case SDRDRAG_TRANSPARENCE:
345 : {
346 0 : if(eDragHdl == HDL_MOVE && IsMarkedHitMovesAlways())
347 : {
348 0 : if(!IsMoveAllowed())
349 0 : return false;
350 0 : mpCurrentSdrDragMethod = new SdrDragMove(*this);
351 : }
352 : else
353 : {
354 0 : if(!IsTransparenceAllowed())
355 0 : return false;
356 :
357 0 : mpCurrentSdrDragMethod = new SdrDragGradient(*this, false);
358 : }
359 0 : break;
360 : }
361 : case SDRDRAG_GRADIENT:
362 : {
363 0 : if(eDragHdl == HDL_MOVE && IsMarkedHitMovesAlways())
364 : {
365 0 : if(!IsMoveAllowed())
366 0 : return false;
367 0 : mpCurrentSdrDragMethod = new SdrDragMove(*this);
368 : }
369 : else
370 : {
371 0 : if(!IsGradientAllowed())
372 0 : return false;
373 :
374 0 : mpCurrentSdrDragMethod = new SdrDragGradient(*this);
375 : }
376 0 : break;
377 : }
378 :
379 : case SDRDRAG_CROOK :
380 : {
381 0 : if (eDragHdl==HDL_MOVE && IsMarkedHitMovesAlways())
382 : {
383 0 : if (!IsMoveAllowed()) return false;
384 0 : mpCurrentSdrDragMethod = new SdrDragMove(*this);
385 : }
386 : else
387 : {
388 0 : if (!IsCrookAllowed(true) && !IsCrookAllowed(false)) return false;
389 0 : mpCurrentSdrDragMethod = new SdrDragCrook(*this);
390 : }
391 0 : } break;
392 :
393 : default:
394 : {
395 : // SDRDRAG_MOVE
396 0 : if((eDragHdl == HDL_MOVE) && !IsMoveAllowed())
397 : {
398 0 : return false;
399 : }
400 0 : else if(eDragHdl == HDL_GLUE)
401 : {
402 0 : mpCurrentSdrDragMethod = new SdrDragMove(*this);
403 : }
404 : else
405 : {
406 0 : if(bFramDrag)
407 : {
408 0 : if(eDragHdl == HDL_MOVE)
409 : {
410 0 : mpCurrentSdrDragMethod = new SdrDragMove(*this);
411 : }
412 : else
413 : {
414 0 : if(!IsResizeAllowed(true))
415 : {
416 0 : return false;
417 : }
418 :
419 0 : bool bSingleTextObjMark = false; // SJ: #i100490#
420 0 : if ( GetMarkedObjectCount() == 1 )
421 : {
422 0 : pMarkedObj=GetMarkedObjectByIndex(0);
423 0 : if ( pMarkedObj &&
424 0 : pMarkedObj->ISA( SdrTextObj ) &&
425 0 : static_cast<SdrTextObj*>(pMarkedObj)->IsTextFrame() )
426 0 : bSingleTextObjMark = true;
427 : }
428 0 : if ( bSingleTextObjMark )
429 0 : mpCurrentSdrDragMethod = new SdrDragObjOwn(*this);
430 : else
431 0 : mpCurrentSdrDragMethod = new SdrDragResize(*this);
432 : }
433 : }
434 : else
435 : {
436 0 : if(HDL_MOVE == eDragHdl)
437 : {
438 0 : const bool bCustomShapeSelected(1 == GetMarkedObjectCount() && GetMarkedObjectByIndex(0)->ISA(SdrObjCustomShape));
439 :
440 0 : if(bCustomShapeSelected)
441 : {
442 0 : mpCurrentSdrDragMethod = new SdrDragMove( *this );
443 : }
444 : }
445 0 : else if(HDL_POLY == eDragHdl)
446 : {
447 0 : const bool bConnectorSelected(1 == GetMarkedObjectCount() && GetMarkedObjectByIndex(0)->ISA(SdrEdgeObj));
448 :
449 0 : if(bConnectorSelected)
450 : {
451 : // #i97784#
452 : // fallback to old behaviour for connectors (see
453 : // text in task description for more details)
454 : }
455 0 : else if(!IsMoveAllowed() || !IsResizeAllowed())
456 : {
457 : // #i77187#
458 : // do not allow move of polygon points if object is move or size protected
459 0 : return false;
460 : }
461 : }
462 :
463 0 : if(!mpCurrentSdrDragMethod)
464 : {
465 : // fallback to DragSpecial if no interaction defined
466 0 : bDragSpecial = true;
467 0 : mpCurrentSdrDragMethod = new SdrDragObjOwn(*this);
468 : }
469 : }
470 : }
471 : }
472 : }
473 : }
474 0 : if (pForcedMeth!=NULL)
475 : {
476 0 : delete mpCurrentSdrDragMethod;
477 0 : mpCurrentSdrDragMethod = pForcedMeth;
478 : }
479 0 : aDragStat.SetDragMethod(mpCurrentSdrDragMethod);
480 0 : if (mpCurrentSdrDragMethod)
481 : {
482 0 : bRet = mpCurrentSdrDragMethod->BeginSdrDrag();
483 0 : if (!bRet)
484 : {
485 0 : if (pHdl==NULL && IS_TYPE(SdrDragObjOwn,mpCurrentSdrDragMethod))
486 : {
487 : // Obj may not Move SpecialDrag, so try with MoveFrameDrag
488 0 : delete mpCurrentSdrDragMethod;
489 0 : mpCurrentSdrDragMethod = 0;
490 0 : bDragSpecial=false;
491 :
492 0 : if (!IsMoveAllowed())
493 0 : return false;
494 :
495 0 : bFramDrag=true;
496 0 : mpCurrentSdrDragMethod = new SdrDragMove(*this);
497 0 : aDragStat.SetDragMethod(mpCurrentSdrDragMethod);
498 0 : bRet = mpCurrentSdrDragMethod->BeginSdrDrag();
499 : }
500 : }
501 0 : if (!bRet)
502 : {
503 0 : delete mpCurrentSdrDragMethod;
504 0 : mpCurrentSdrDragMethod = 0;
505 0 : aDragStat.SetDragMethod(mpCurrentSdrDragMethod);
506 : }
507 : }
508 : }
509 :
510 0 : return bRet;
511 : }
512 :
513 0 : void SdrDragView::MovDragObj(const Point& rPnt)
514 : {
515 0 : if (mpCurrentSdrDragMethod)
516 : {
517 0 : Point aPnt(rPnt);
518 0 : ImpLimitToWorkArea(aPnt);
519 0 : mpCurrentSdrDragMethod->MoveSdrDrag(aPnt); // this call already makes a Hide()/Show combination
520 : }
521 0 : }
522 :
523 0 : bool SdrDragView::EndDragObj(bool bCopy)
524 : {
525 0 : bool bRet(false);
526 :
527 : // #i73341# If inserting GluePoint, do not insist on last points being different
528 0 : if(mpCurrentSdrDragMethod && aDragStat.IsMinMoved() && (IsInsertGluePoint() || aDragStat.GetNow() != aDragStat.GetPrev()))
529 : {
530 0 : sal_uIntPtr nHdlAnzMerk=0;
531 :
532 0 : if (bEliminatePolyPoints)
533 : { // IBM Special
534 0 : nHdlAnzMerk=GetMarkablePointCount();
535 : }
536 :
537 0 : const bool bUndo = IsUndoEnabled();
538 0 : if (IsInsertGluePoint() && bUndo)
539 : {
540 0 : BegUndo(aInsPointUndoStr);
541 0 : AddUndo(pInsPointUndo);
542 : }
543 :
544 0 : bRet = mpCurrentSdrDragMethod->EndSdrDrag(bCopy);
545 :
546 0 : if( IsInsertGluePoint() && bUndo)
547 0 : EndUndo();
548 :
549 0 : delete mpCurrentSdrDragMethod;
550 0 : mpCurrentSdrDragMethod = 0;
551 :
552 0 : if (bEliminatePolyPoints)
553 : { // IBM Special
554 0 : if (nHdlAnzMerk!=GetMarkablePointCount())
555 : {
556 0 : UnmarkAllPoints();
557 : }
558 : }
559 :
560 0 : if (bInsPolyPoint)
561 : {
562 0 : SetMarkHandles();
563 0 : bInsPolyPoint=false;
564 0 : if( bUndo )
565 : {
566 0 : BegUndo(aInsPointUndoStr);
567 0 : AddUndo(pInsPointUndo);
568 0 : EndUndo();
569 : }
570 : }
571 :
572 0 : eDragHdl=HDL_MOVE;
573 0 : pDragHdl=NULL;
574 :
575 0 : if (!bSomeObjChgdFlag)
576 : {
577 : // Obj did not broadcast (e. g. Writer FlyFrames)
578 0 : if(!bDragHdl)
579 : {
580 0 : AdjustMarkHdl();
581 : }
582 : }
583 : }
584 : else
585 : {
586 0 : BrkDragObj();
587 : }
588 :
589 0 : bInsPolyPoint=false;
590 0 : SetInsertGluePoint(false);
591 :
592 0 : return bRet;
593 : }
594 :
595 0 : void SdrDragView::BrkDragObj()
596 : {
597 0 : if (mpCurrentSdrDragMethod)
598 : {
599 0 : mpCurrentSdrDragMethod->CancelSdrDrag();
600 :
601 0 : delete mpCurrentSdrDragMethod;
602 0 : mpCurrentSdrDragMethod = 0;
603 :
604 0 : if (bInsPolyPoint)
605 : {
606 0 : pInsPointUndo->Undo(); // delete inserted point again
607 0 : delete pInsPointUndo;
608 0 : pInsPointUndo=NULL;
609 0 : SetMarkHandles();
610 0 : bInsPolyPoint=false;
611 : }
612 :
613 0 : if (IsInsertGluePoint())
614 : {
615 0 : pInsPointUndo->Undo(); // delete inserted glue point again
616 0 : delete pInsPointUndo;
617 0 : pInsPointUndo=NULL;
618 0 : SetInsertGluePoint(false);
619 : }
620 :
621 0 : eDragHdl=HDL_MOVE;
622 0 : pDragHdl=NULL;
623 : }
624 0 : }
625 :
626 0 : bool SdrDragView::IsInsObjPointPossible() const
627 : {
628 0 : return pMarkedObj!=NULL && pMarkedObj->IsPolyObj();
629 : }
630 :
631 0 : bool SdrDragView::ImpBegInsObjPoint(bool bIdxZwang, sal_uInt32 nIdx, const Point& rPnt, bool bNewObj, OutputDevice* pOut)
632 : {
633 0 : bool bRet(false);
634 :
635 0 : if(pMarkedObj && pMarkedObj->ISA(SdrPathObj))
636 : {
637 0 : SdrPathObj* pMarkedPath = (SdrPathObj*)pMarkedObj;
638 0 : BrkAction();
639 0 : pInsPointUndo = dynamic_cast< SdrUndoGeoObj* >( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pMarkedObj) );
640 : DBG_ASSERT( pInsPointUndo, "svx::SdrDragView::BegInsObjPoint(), could not create correct undo object!" );
641 :
642 0 : OUString aStr(ImpGetResStr(STR_DragInsertPoint));
643 :
644 0 : aInsPointUndoStr = aStr.replaceFirst("%1", pMarkedObj->TakeObjNameSingul() );
645 :
646 0 : Point aPt(rPnt);
647 :
648 0 : if(bNewObj)
649 0 : aPt = GetSnapPos(aPt,pMarkedPV);
650 :
651 0 : bool bClosed0 = pMarkedPath->IsClosedObj();
652 :
653 0 : if(bIdxZwang)
654 : {
655 0 : mnInsPointNum = pMarkedPath->NbcInsPoint(nIdx, aPt, bNewObj, true);
656 : }
657 : else
658 : {
659 0 : mnInsPointNum = pMarkedPath->NbcInsPointOld(aPt, bNewObj, true);
660 : }
661 :
662 0 : if(bClosed0 != pMarkedPath->IsClosedObj())
663 : {
664 : // Obj was closed implicitly
665 : // object changed
666 0 : pMarkedPath->SetChanged();
667 0 : pMarkedPath->BroadcastObjectChange();
668 : }
669 :
670 0 : if(0xffffffff != mnInsPointNum)
671 : {
672 0 : bInsPolyPoint = true;
673 0 : UnmarkAllPoints();
674 0 : AdjustMarkHdl();
675 :
676 0 : bRet = BegDragObj(rPnt, pOut, aHdl.GetHdl(mnInsPointNum), 0);
677 :
678 0 : if (bRet)
679 : {
680 0 : aDragStat.SetMinMoved();
681 0 : MovDragObj(rPnt);
682 : }
683 : }
684 : else
685 : {
686 0 : delete pInsPointUndo;
687 0 : pInsPointUndo = NULL;
688 0 : }
689 : }
690 :
691 0 : return bRet;
692 : }
693 :
694 0 : bool SdrDragView::EndInsObjPoint(SdrCreateCmd eCmd)
695 : {
696 0 : if(IsInsObjPoint())
697 : {
698 0 : sal_uInt32 nNextPnt(mnInsPointNum);
699 0 : Point aPnt(aDragStat.GetNow());
700 0 : bool bOk=EndDragObj(false);
701 0 : if (bOk && eCmd!=SDRCREATE_FORCEEND)
702 : {
703 : // Ret=True means: Action is over.
704 0 : bOk=!(ImpBegInsObjPoint(true, nNextPnt, aPnt, eCmd == SDRCREATE_NEXTOBJECT, pDragWin));
705 : }
706 :
707 0 : return bOk;
708 0 : } else return false;
709 : }
710 :
711 0 : bool SdrDragView::IsInsGluePointPossible() const
712 : {
713 0 : bool bRet=false;
714 0 : if (IsInsGluePointMode() && AreObjectsMarked())
715 : {
716 0 : if (GetMarkedObjectCount()==1)
717 : {
718 : // return sal_False, if only 1 object which is a connector.
719 0 : const SdrObject* pObj=GetMarkedObjectByIndex(0);
720 0 : if (!HAS_BASE(SdrEdgeObj,pObj))
721 : {
722 0 : bRet=true;
723 : }
724 : }
725 : else
726 : {
727 0 : bRet=true;
728 : }
729 : }
730 0 : return bRet;
731 : }
732 :
733 0 : bool SdrDragView::BegInsGluePoint(const Point& rPnt)
734 : {
735 0 : bool bRet=false;
736 : SdrObject* pObj;
737 : SdrPageView* pPV;
738 : sal_uIntPtr nMarkNum;
739 0 : if (PickMarkedObj(rPnt,pObj,pPV,&nMarkNum,SDRSEARCH_PASS2BOUND))
740 : {
741 0 : BrkAction();
742 0 : UnmarkAllGluePoints();
743 0 : pInsPointUndo= dynamic_cast< SdrUndoGeoObj* >( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj) );
744 : DBG_ASSERT( pInsPointUndo, "svx::SdrDragView::BegInsObjPoint(), could not create correct undo object!" );
745 0 : OUString aStr(ImpGetResStr(STR_DragInsertGluePoint));
746 :
747 0 : aInsPointUndoStr = aStr.replaceFirst("%1", pObj->TakeObjNameSingul() );
748 :
749 0 : SdrGluePointList* pGPL=pObj->ForceGluePointList();
750 0 : if (pGPL!=NULL)
751 : {
752 0 : sal_uInt16 nGlueIdx=pGPL->Insert(SdrGluePoint());
753 0 : SdrGluePoint& rGP=(*pGPL)[nGlueIdx];
754 0 : sal_uInt16 nGlueId=rGP.GetId();
755 0 : rGP.SetAbsolutePos(rPnt,*pObj);
756 :
757 0 : SdrHdl* pHdl=NULL;
758 0 : if (MarkGluePoint(pObj,nGlueId,pPV))
759 : {
760 0 : pHdl=GetGluePointHdl(pObj,nGlueId);
761 : }
762 0 : if (pHdl!=NULL && pHdl->GetKind()==HDL_GLUE && pHdl->GetObj()==pObj && pHdl->GetObjHdlNum()==nGlueId)
763 : {
764 0 : SetInsertGluePoint(true);
765 0 : bRet=BegDragObj(rPnt,NULL,pHdl,0);
766 0 : if (bRet)
767 : {
768 0 : aDragStat.SetMinMoved();
769 0 : MovDragObj(rPnt);
770 : }
771 : else
772 : {
773 0 : SetInsertGluePoint(false);
774 0 : delete pInsPointUndo;
775 0 : pInsPointUndo=NULL;
776 : }
777 : }
778 : else
779 : {
780 : OSL_FAIL("BegInsGluePoint(): GluePoint handle not found.");
781 : }
782 : }
783 : else
784 : {
785 : // no glue points possible for this object (e. g. Edge)
786 0 : SetInsertGluePoint(false);
787 0 : delete pInsPointUndo;
788 0 : pInsPointUndo=NULL;
789 0 : }
790 : }
791 :
792 0 : return bRet;
793 : }
794 :
795 0 : void SdrDragView::ShowDragObj()
796 : {
797 0 : if(mpCurrentSdrDragMethod && !aDragStat.IsShown())
798 : {
799 0 : for(sal_uInt32 a(0); a < PaintWindowCount(); a++)
800 : {
801 0 : SdrPaintWindow* pCandidate = GetPaintWindow(a);
802 0 : rtl::Reference<sdr::overlay::OverlayManager> xOverlayManager = pCandidate->GetOverlayManager();
803 :
804 0 : if (xOverlayManager.is())
805 : {
806 0 : mpCurrentSdrDragMethod->CreateOverlayGeometry(*xOverlayManager);
807 :
808 : // #i101679# Force changed overlay to be shown
809 0 : xOverlayManager->flush();
810 : }
811 0 : }
812 :
813 0 : aDragStat.SetShown(true);
814 : }
815 0 : }
816 :
817 0 : void SdrDragView::HideDragObj()
818 : {
819 0 : if(mpCurrentSdrDragMethod && aDragStat.IsShown())
820 : {
821 0 : mpCurrentSdrDragMethod->destroyOverlayGeometry();
822 0 : aDragStat.SetShown(false);
823 : }
824 0 : }
825 :
826 :
827 :
828 0 : void SdrDragView::SetNoDragXorPolys(bool bOn)
829 : {
830 0 : if (IsNoDragXorPolys()!=bOn)
831 : {
832 0 : const bool bDragging(mpCurrentSdrDragMethod);
833 0 : const bool bShown(bDragging && aDragStat.IsShown());
834 :
835 0 : if(bShown)
836 : {
837 0 : HideDragObj();
838 : }
839 :
840 0 : bNoDragXorPolys = bOn;
841 :
842 0 : if(bDragging)
843 : {
844 : // force recreation of drag content
845 0 : mpCurrentSdrDragMethod->resetSdrDragEntries();
846 : }
847 :
848 0 : if(bShown)
849 : {
850 0 : ShowDragObj();
851 : }
852 : }
853 0 : }
854 :
855 0 : void SdrDragView::SetDragStripes(bool bOn)
856 : {
857 0 : if (mpCurrentSdrDragMethod && aDragStat.IsShown())
858 : {
859 0 : HideDragObj();
860 0 : bDragStripes=bOn;
861 0 : ShowDragObj();
862 : }
863 : else
864 : {
865 0 : bDragStripes=bOn;
866 : }
867 0 : }
868 :
869 0 : bool SdrDragView::IsOrthoDesired() const
870 : {
871 0 : if(mpCurrentSdrDragMethod && (IS_TYPE(SdrDragObjOwn, mpCurrentSdrDragMethod) || IS_TYPE(SdrDragResize, mpCurrentSdrDragMethod)))
872 : {
873 0 : return bOrthoDesiredOnMarked;
874 : }
875 :
876 0 : return false;
877 : }
878 :
879 0 : void SdrDragView::SetMarkHandles()
880 : {
881 0 : if( pDragHdl )
882 0 : pDragHdl = 0;
883 :
884 0 : SdrExchangeView::SetMarkHandles();
885 0 : }
886 :
887 0 : void SdrDragView::SetSolidDragging(bool bOn)
888 : {
889 0 : if((bool)mbSolidDragging != bOn)
890 : {
891 0 : mbSolidDragging = bOn;
892 : }
893 0 : }
894 :
895 0 : bool SdrDragView::IsSolidDragging() const
896 : {
897 : // allow each user to disable by having a local setting, but using AND for
898 : // checking allowance
899 0 : return mbSolidDragging && getOptionsDrawinglayer().IsSolidDragCreate();
900 : }
901 :
902 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|