1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <editeng/eeitem.hxx>
22 #include "svx/svdstr.hrc"
23 #include "svdglob.hxx"
24 #include <svx/svdpagv.hxx>
25 #include <svx/svdmrkv.hxx>
26 #include <svx/svdedxv.hxx>
27 #include <svx/svdobj.hxx>
28 #include <svx/svdopath.hxx>
29 #include <svx/svdograf.hxx>
30 #include <svx/svdomedia.hxx>
31 #include <svx/svdetc.hxx>
34 #include <svdibrow.hxx>
37 #include "svx/svdoutl.hxx"
38 #include "svx/svdview.hxx"
39 #include "editeng/editview.hxx"
40 #include "editeng/flditem.hxx"
41 #include "svx/obj3d.hxx"
42 #include "svx/svddrgmt.hxx"
43 #include "svx/svdotable.hxx"
44 #include <tools/tenccvt.hxx>
45 #include <svx/sdr/overlay/overlaypolypolygon.hxx>
46 #include <svx/sdr/overlay/overlaymanager.hxx>
47 #include <svx/sdrpaintwindow.hxx>
48 #include <svx/sdrpagewindow.hxx>
49 #include <svx/sdrhittesthelper.hxx>
50 #include <svx/sdr/contact/viewcontact.hxx>
51 #include <drawinglayer/processor2d/contourextractor2d.hxx>
55 SdrViewEvent::SdrViewEvent()
62 eEvent(SDREVENT_NONE
),
64 eEndCreateCmd(SDRCREATE_NEXTPOINT
),
66 nMouseMode(MouseEventModifiers::NONE
),
72 bDoubleHdlSize(false),
80 bInsPointNewObj(false),
87 SdrViewEvent::~SdrViewEvent()
92 // helper class for all D&D overlays
94 void SdrDropMarkerOverlay::ImplCreateOverlays(
96 const basegfx::B2DPolyPolygon
& rLinePolyPolygon
)
98 for(sal_uInt32
a(0L); a
< rView
.PaintWindowCount(); a
++)
100 SdrPaintWindow
* pCandidate
= rView
.GetPaintWindow(a
);
101 rtl::Reference
< sdr::overlay::OverlayManager
> xTargetOverlay
= pCandidate
->GetOverlayManager();
103 if (xTargetOverlay
.is())
105 sdr::overlay::OverlayPolyPolygonStripedAndFilled
* pNew
= new sdr::overlay::OverlayPolyPolygonStripedAndFilled(
108 xTargetOverlay
->add(*pNew
);
109 maObjects
.append(*pNew
);
114 SdrDropMarkerOverlay::SdrDropMarkerOverlay(const SdrView
& rView
, const SdrObject
& rObject
)
118 rObject
.TakeXorPoly());
121 SdrDropMarkerOverlay::SdrDropMarkerOverlay(const SdrView
& rView
, const Rectangle
& rRectangle
)
123 basegfx::B2DPolygon aB2DPolygon
;
125 aB2DPolygon
.append(basegfx::B2DPoint(rRectangle
.Left(), rRectangle
.Top()));
126 aB2DPolygon
.append(basegfx::B2DPoint(rRectangle
.Right(), rRectangle
.Top()));
127 aB2DPolygon
.append(basegfx::B2DPoint(rRectangle
.Right(), rRectangle
.Bottom()));
128 aB2DPolygon
.append(basegfx::B2DPoint(rRectangle
.Left(), rRectangle
.Bottom()));
129 aB2DPolygon
.setClosed(true);
133 basegfx::B2DPolyPolygon(aB2DPolygon
));
136 SdrDropMarkerOverlay::SdrDropMarkerOverlay(const SdrView
& rView
, const Point
& rStart
, const Point
& rEnd
)
138 basegfx::B2DPolygon aB2DPolygon
;
140 aB2DPolygon
.append(basegfx::B2DPoint(rStart
.X(), rStart
.Y()));
141 aB2DPolygon
.append(basegfx::B2DPoint(rEnd
.X(), rEnd
.Y()));
142 aB2DPolygon
.setClosed(true);
146 basegfx::B2DPolyPolygon(aB2DPolygon
));
149 SdrDropMarkerOverlay::~SdrDropMarkerOverlay()
151 // The OverlayObjects are cleared using the destructor of OverlayObjectList.
152 // That destructor calls clear() at the list which removes all objects from the
153 // OverlayManager and deletes them.
157 TYPEINIT1(SdrView
,SdrCreateView
);
159 SdrView::SdrView(SdrModel
* pModel1
, OutputDevice
* pOut
)
160 : SdrCreateView(pModel1
,pOut
),
161 bNoExtendedMouseDispatcher(false),
162 bNoExtendedKeyDispatcher(false),
163 bNoExtendedCommandDispatcher(false),
164 mbMasterPagePaintCaching(false)
166 bTextEditOnObjectsWithoutTextIfTextTool
=false;
168 maAccessibilityOptions
.AddListener(this);
170 onAccessibilityOptionsChanged();
175 maAccessibilityOptions
.RemoveListener(this);
178 bool SdrView::KeyInput(const KeyEvent
& rKEvt
, vcl::Window
* pWin
)
181 bool bRet
= SdrCreateView::KeyInput(rKEvt
,pWin
);
182 if (!bRet
&& !IsExtendedKeyInputDispatcherEnabled()) {
184 switch (rKEvt
.GetKeyCode().GetFullFunction()) {
185 case KeyFuncType::CUT
: Cut(); break;
186 case KeyFuncType::COPY
: Yank(); break;
187 case KeyFuncType::PASTE
: Paste(pWin
); break;
188 case KeyFuncType::DELETE
: DeleteMarked(); break;
189 case KeyFuncType::UNDO
: pMod
->Undo(); break;
190 case KeyFuncType::REDO
: pMod
->Redo(); break;
191 case KeyFuncType::REPEAT
: pMod
->Repeat(*this); break;
193 switch (rKEvt
.GetKeyCode().GetFullCode()) {
195 if (IsTextEdit()) SdrEndTextEdit();
196 if (IsAction()) BrkAction();
197 if (pWin
!=NULL
) pWin
->ReleaseMouse();
199 case KEY_DELETE
: DeleteMarked(); break;
200 case KEY_CUT
: case KEY_DELETE
+KEY_SHIFT
: Cut(); break;
201 case KEY_COPY
: case KEY_INSERT
+KEY_MOD1
: Yank(); break;
202 case KEY_PASTE
: case KEY_INSERT
+KEY_SHIFT
: Paste(pWin
); break;
203 case KEY_UNDO
: case KEY_BACKSPACE
+KEY_MOD2
: pMod
->Undo(); break;
204 case KEY_BACKSPACE
+KEY_MOD2
+KEY_SHIFT
: pMod
->Redo(); break;
205 case KEY_REPEAT
: case KEY_BACKSPACE
+KEY_MOD2
+KEY_MOD1
: pMod
->Repeat(*this); break;
206 case KEY_MOD1
+KEY_A
: MarkAll(); break;
211 if (bRet
&& pWin
!=NULL
) {
212 pWin
->SetPointer(GetPreferredPointer(
213 pWin
->PixelToLogic(pWin
->ScreenToOutputPixel( pWin
->GetPointerPosPixel() ) ),
215 rKEvt
.GetKeyCode().GetModifier()));
221 bool SdrView::MouseButtonDown(const MouseEvent
& rMEvt
, vcl::Window
* pWin
)
224 if (rMEvt
.IsLeft()) aDragStat
.SetMouseDown(true);
225 bool bRet
= SdrCreateView::MouseButtonDown(rMEvt
,pWin
);
226 if (!bRet
&& !IsExtendedMouseEventDispatcherEnabled()) {
228 PickAnything(rMEvt
,SdrMouseEventKind::BUTTONDOWN
,aVEvt
);
229 bRet
= DoMouseEvent(aVEvt
);
234 bool SdrView::MouseButtonUp(const MouseEvent
& rMEvt
, vcl::Window
* pWin
)
237 if (rMEvt
.IsLeft()) aDragStat
.SetMouseDown(false);
238 bool bAction
= IsAction();
239 bool bRet
= !bAction
&& SdrCreateView::MouseButtonUp(rMEvt
,pWin
);
240 if (!bRet
&& !IsExtendedMouseEventDispatcherEnabled()) {
242 PickAnything(rMEvt
,SdrMouseEventKind::BUTTONUP
,aVEvt
);
243 bRet
= DoMouseEvent(aVEvt
);
248 bool SdrView::MouseMove(const MouseEvent
& rMEvt
, vcl::Window
* pWin
)
251 aDragStat
.SetMouseDown(rMEvt
.IsLeft());
252 bool bRet
= SdrCreateView::MouseMove(rMEvt
,pWin
);
253 if (!IsExtendedMouseEventDispatcherEnabled() && !IsTextEditInSelectionMode()) {
255 PickAnything(rMEvt
,SdrMouseEventKind::MOVE
,aVEvt
);
256 if (DoMouseEvent(aVEvt
)) bRet
=true;
262 bool SdrView::Command(const CommandEvent
& rCEvt
, vcl::Window
* pWin
)
265 bool bRet
= SdrCreateView::Command(rCEvt
,pWin
);
269 bool SdrView::GetAttributes(SfxItemSet
& rTargetSet
, bool bOnlyHardAttr
) const
271 return SdrCreateView::GetAttributes(rTargetSet
, bOnlyHardAttr
);
274 SfxStyleSheet
* SdrView::GetStyleSheet() const
276 return SdrCreateView::GetStyleSheet();
279 SdrHitKind
SdrView::PickAnything(const MouseEvent
& rMEvt
, SdrMouseEventKind nEventKind
, SdrViewEvent
& rVEvt
) const
281 rVEvt
.bMouseDown
=nEventKind
==SdrMouseEventKind::BUTTONDOWN
;
282 rVEvt
.bMouseUp
=nEventKind
==SdrMouseEventKind::BUTTONUP
;
283 rVEvt
.nMouseClicks
=rMEvt
.GetClicks();
284 rVEvt
.nMouseMode
=rMEvt
.GetMode();
285 rVEvt
.nMouseCode
=rMEvt
.GetButtons() | rMEvt
.GetModifier();
286 const OutputDevice
* pOut
=pActualOutDev
;
289 pOut
= GetFirstOutputDevice();
291 Point
aPnt(rMEvt
.GetPosPixel());
292 if (pOut
!=NULL
) aPnt
=pOut
->PixelToLogic(aPnt
);
293 rVEvt
.aLogicPos
=aPnt
;
294 return PickAnything(aPnt
,rVEvt
);
297 // Dragging with the Mouse (Move)
298 // Example when creating a rectangle: MouseDown has to happen without a ModKey,
299 // else we usually force a selection (see below).
300 // When pressing Shift, Ctrl and Alt at the same time while doing a MouseMove,
301 // a centered, not snapped square is created.
302 // The dual allocation of Ortho and Shift won't usually create a problem, as the
303 // two functions are in most cases mutually exclusive. Only shearing (the kind
304 // that happens when contorting, not when rotating) can use both functions at
305 // the same time. To get around this, the user can use e. g. help lines.
306 #define MODKEY_NoSnap bCtrl /* temporarily disable snapping */
307 #define MODKEY_Ortho bShift /* ortho */
308 #define MODKEY_Center bAlt /* create/resize centeredly */
309 #define MODKEY_AngleSnap bShift
310 #define MODKEY_CopyDrag bCtrl /* drag and copy */
312 // click somewhere (MouseDown)
313 #define MODKEY_PolyPoly bAlt /* new Poly at InsPt and at Create */
314 #define MODKEY_MultiMark bShift /* MarkObj without doing UnmarkAll first */
315 #define MODKEY_Unmark bAlt /* deselect with a dragged frame */
316 #define MODKEY_ForceMark bCtrl /* force dragging a frame, even if there's an object at cursor position */
317 #define MODKEY_DeepMark bAlt /* MarkNextObj */
318 #define MODKEY_DeepBackw bShift /* MarkNextObj but backwards */
320 SdrHitKind
SdrView::PickAnything(const Point
& rLogicPos
, SdrViewEvent
& rVEvt
) const
322 const OutputDevice
* pOut
=pActualOutDev
;
325 pOut
= GetFirstOutputDevice();
328 // #i73628# Use a non-changeable copy of he logic position
329 const Point
aLocalLogicPosition(rLogicPos
);
331 bool bEditMode
=IsEditMode();
332 bool bPointMode
=bEditMode
&& HasMarkablePoints();
333 bool bGluePointMode
=IsGluePointEditMode();
334 bool bInsPolyPt
=bPointMode
&& IsInsObjPointMode() && IsInsObjPointPossible();
335 bool bInsGluePt
=bGluePointMode
&& IsInsGluePointMode() && IsInsGluePointPossible();
336 bool bIsTextEdit
=IsTextEdit();
337 bool bTextEditHit
=IsTextEditHit(aLocalLogicPosition
,0/*nHitTolLog*/);
338 bool bTextEditSel
=IsTextEditInSelectionMode();
339 bool bShift
=(rVEvt
.nMouseCode
& KEY_SHIFT
) !=0;
340 bool bCtrl
=(rVEvt
.nMouseCode
& KEY_MOD1
) !=0;
341 bool bAlt
=(rVEvt
.nMouseCode
& KEY_MOD2
) !=0;
342 SdrHitKind eHit
=SDRHIT_NONE
;
343 SdrHdl
* pHdl
=pOut
!=NULL
&& !bTextEditSel
? PickHandle(aLocalLogicPosition
) : NULL
;
344 SdrPageView
* pPV
=NULL
;
345 SdrObject
* pObj
=NULL
;
346 SdrObject
* pHitObj
=NULL
;
347 bool bHitPassDirect
=true;
348 sal_uInt16 nHlplIdx
=0;
349 sal_uInt16 nGlueId
=0;
350 if (bTextEditHit
|| bTextEditSel
)
352 eHit
=SDRHIT_TEXTEDIT
;
357 eHit
=SDRHIT_HANDLE
; // handle is hit: highest priority
359 else if (bEditMode
&& IsHlplVisible() && IsHlplFront() && pOut
!=NULL
&& PickHelpLine(aLocalLogicPosition
,nHitTolLog
,*pOut
,nHlplIdx
,pPV
))
361 eHit
=SDRHIT_HELPLINE
; // help line in the foreground hit: can be moved now
363 else if (bGluePointMode
&& PickGluePoint(aLocalLogicPosition
,pObj
,nGlueId
,pPV
))
365 eHit
=SDRHIT_GLUEPOINT
; // deselected glue point hit
367 else if (PickObj(aLocalLogicPosition
,nHitTolLog
,pHitObj
,pPV
,SdrSearchOptions::DEEP
|SdrSearchOptions::MARKED
,&pObj
,&bHitPassDirect
))
369 eHit
=SDRHIT_MARKEDOBJECT
;
370 sdr::table::SdrTableObj
* pTableObj
= dynamic_cast< sdr::table::SdrTableObj
* >( pObj
);
373 sal_Int32 nX
= 0, nY
= 0;
374 switch( pTableObj
->CheckTableHit( aLocalLogicPosition
, nX
, nY
, 0 ) )
376 case sdr::table::SDRTABLEHIT_CELL
:
379 case sdr::table::SDRTABLEHIT_CELLTEXTAREA
:
380 eHit
= SDRHIT_TEXTEDITOBJ
;
387 else if (PickObj(aLocalLogicPosition
,nHitTolLog
,pHitObj
,pPV
,SdrSearchOptions::DEEP
|SdrSearchOptions::ALSOONMASTER
|SdrSearchOptions::WHOLEPAGE
,&pObj
,&bHitPassDirect
))
389 // MasterPages and WholePage for Macro and URL
390 eHit
=SDRHIT_UNMARKEDOBJECT
;
391 sdr::table::SdrTableObj
* pTableObj
= dynamic_cast< sdr::table::SdrTableObj
* >( pObj
);
394 sal_Int32 nX
= 0, nY
= 0;
395 switch( pTableObj
->CheckTableHit( aLocalLogicPosition
, nX
, nY
, 0 ) )
397 case sdr::table::SDRTABLEHIT_CELL
:
400 case sdr::table::SDRTABLEHIT_CELLTEXTAREA
:
401 eHit
= SDRHIT_TEXTEDITOBJ
;
408 else if (bEditMode
&& IsHlplVisible() && !IsHlplFront() && pOut
!=NULL
&& PickHelpLine(aLocalLogicPosition
,nHitTolLog
,*pOut
,nHlplIdx
,pPV
))
410 eHit
=SDRHIT_HELPLINE
; // help line in foreground hit: can be moved now
412 if (IsMacroMode() && eHit
==SDRHIT_UNMARKEDOBJECT
)
414 bool bRoot
=pObj
->HasMacro();
415 bool bDeep
=pObj
!=pHitObj
&& pHitObj
->HasMacro();
416 bool bMid
=false; // Have we hit upon a grouped group with a macro?
417 SdrObject
* pMidObj
=NULL
;
420 SdrObject
* pObjTmp
=NULL
;
421 pObjTmp
=pHitObj
->GetUpGroup();
422 if (pObjTmp
==pObj
) pObjTmp
=NULL
;
423 while (pObjTmp
!=NULL
)
425 if (pObjTmp
->HasMacro())
430 pObjTmp
=pObjTmp
->GetUpGroup();
431 if (pObjTmp
==pObj
) pObjTmp
=NULL
;
435 if (bDeep
|| bMid
|| bRoot
)
437 SdrObjMacroHitRec aHitRec
;
438 aHitRec
.aPos
=aLocalLogicPosition
;
439 aHitRec
.aDownPos
=aLocalLogicPosition
;
440 aHitRec
.nTol
=nHitTolLog
;
441 aHitRec
.pVisiLayer
=&pPV
->GetVisibleLayers();
442 aHitRec
.pPageView
=pPV
;
443 if (bDeep
) bDeep
=pHitObj
->IsMacroHit(aHitRec
);
444 if (bMid
) bMid
=pMidObj
->IsMacroHit(aHitRec
);
445 if (bRoot
) bRoot
=pObj
->IsMacroHit(aHitRec
);
446 if (bRoot
|| bMid
|| bDeep
)
448 // Priorities: 1. Root, 2. Mid, 3. Deep
450 if (!bRoot
) pObj
=pMidObj
;
451 if (!bRoot
&& !bMid
) pObj
=pHitObj
;
456 // check for URL field
457 if (IsMacroMode() && eHit
==SDRHIT_UNMARKEDOBJECT
)
459 SdrTextObj
* pTextObj
=PTR_CAST(SdrTextObj
,pHitObj
);
460 if (pTextObj
!=NULL
&& pTextObj
->HasText())
463 SdrObjectPrimitiveHit(*pTextObj
, aLocalLogicPosition
, 0, *pPV
, &pPV
->GetVisibleLayers(), true));
469 SdrOutliner
* pOutliner
= &pTextObj
->ImpGetDrawOutliner();
470 if( pTextObj
->GetModel() )
471 pOutliner
= &pTextObj
->GetModel()->GetHitTestOutliner();
473 pTextObj
->TakeTextRect( *pOutliner
, aTextRect
, false, &aAnchor
, false );
475 // #i73628# Use a text-relative position for hit test in hit test outliner
476 Point
aTemporaryTextRelativePosition(aLocalLogicPosition
- aTextRect
.TopLeft());
478 // account for FitToSize
479 bool bFitToSize(pTextObj
->IsFitToSize());
481 Fraction
aX(aTextRect
.GetWidth()-1,aAnchor
.GetWidth()-1);
482 Fraction
aY(aTextRect
.GetHeight()-1,aAnchor
.GetHeight()-1);
483 ResizePoint(aTemporaryTextRelativePosition
,Point(),aX
,aY
);
485 // account for rotation
486 const GeoStat
& rGeo
=pTextObj
->GetGeoStat();
487 if (rGeo
.nRotationAngle
!=0) RotatePoint(aTemporaryTextRelativePosition
,Point(),-rGeo
.nSin
,rGeo
.nCos
); // -sin for Unrotate
488 // we currently don't account for ticker text
489 if(pActualOutDev
&& pActualOutDev
->GetOutDevType() == OUTDEV_WINDOW
)
491 OutlinerView
aOLV(pOutliner
, const_cast<vcl::Window
*>(static_cast<const vcl::Window
*>(pActualOutDev
.get())));
492 const EditView
& aEV
=aOLV
.GetEditView();
493 const SvxFieldItem
* pItem
=aEV
.GetField(aTemporaryTextRelativePosition
);
495 const SvxFieldData
* pFld
=pItem
->GetField();
496 const SvxURLField
* pURL
=PTR_CAST(SvxURLField
,pFld
);
498 eHit
=SDRHIT_URLFIELD
;
499 rVEvt
.pURLField
=pURL
;
507 if (bHitPassDirect
&&
508 (eHit
==SDRHIT_MARKEDOBJECT
|| eHit
==SDRHIT_UNMARKEDOBJECT
) &&
509 (IsTextTool() || (IsEditMode() && IsQuickTextEditMode())) && pHitObj
->HasTextEdit())
511 // Around the TextEditArea there's a border to select without going into text edit mode.
512 Rectangle
aBoundRect(pHitObj
->GetCurrentBoundRect());
514 // Force to SnapRect when Fontwork
515 if(pHitObj
->ISA(SdrTextObj
) && static_cast<SdrTextObj
*>(pHitObj
)->IsFontwork())
517 aBoundRect
= pHitObj
->GetSnapRect();
520 sal_Int32
nTolerance(nHitTolLog
);
521 bool bBoundRectHit(false);
525 nTolerance
= pOut
->PixelToLogic(Size(2, 0)).Width();
528 if( (aLocalLogicPosition
.X() >= aBoundRect
.Left() - nTolerance
&& aLocalLogicPosition
.X() <= aBoundRect
.Left() + nTolerance
)
529 || (aLocalLogicPosition
.X() >= aBoundRect
.Right() - nTolerance
&& aLocalLogicPosition
.X() <= aBoundRect
.Right() + nTolerance
)
530 || (aLocalLogicPosition
.Y() >= aBoundRect
.Top() - nTolerance
&& aLocalLogicPosition
.Y() <= aBoundRect
.Top() + nTolerance
)
531 || (aLocalLogicPosition
.Y() >= aBoundRect
.Bottom() - nTolerance
&& aLocalLogicPosition
.Y() <= aBoundRect
.Bottom() + nTolerance
))
533 bBoundRectHit
= true;
539 SdrObjectPrimitiveHit(*pHitObj
, aLocalLogicPosition
, 0, *pPV
, &pPV
->GetVisibleLayers(), true));
541 // TextEdit attached to an object in a locked layer
542 if (pPV
->GetLockedLayers().IsSet(pHitObj
->GetLayer()))
551 eHit
=SDRHIT_TEXTEDITOBJ
;
555 if (!bHitPassDirect
&& eHit
==SDRHIT_UNMARKEDOBJECT
) {
560 bool bMouseLeft
=(rVEvt
.nMouseCode
&MOUSE_LEFT
)!=0;
561 bool bMouseRight
=(rVEvt
.nMouseCode
&MOUSE_RIGHT
)!=0;
562 bool bMouseDown
=rVEvt
.bMouseDown
;
563 bool bMouseUp
=rVEvt
.bMouseUp
;
564 SdrEventKind eEvent
=SDREVENT_NONE
;
565 bool bIsAction
=IsAction();
571 if (bMouseRight
) eEvent
=SDREVENT_BCKACTION
;
577 eEvent
=SDREVENT_ENDACTION
;
580 eEvent
=SDREVENT_ENDDRAG
;
581 rVEvt
.bDragWithCopy
=MODKEY_CopyDrag
;
583 else if (IsCreateObj() || IsInsObjPoint())
585 eEvent
=IsCreateObj() ? SDREVENT_ENDCREATE
: SDREVENT_ENDINSOBJPOINT
;
586 rVEvt
.eEndCreateCmd
=SDRCREATE_NEXTPOINT
;
587 if (MODKEY_PolyPoly
) rVEvt
.eEndCreateCmd
=SDRCREATE_NEXTOBJECT
;
588 if (rVEvt
.nMouseClicks
>1) rVEvt
.eEndCreateCmd
=SDRCREATE_FORCEEND
;
590 else if (IsMarking())
592 eEvent
=SDREVENT_ENDMARK
;
593 if (!aDragStat
.IsMinMoved())
595 eEvent
=SDREVENT_BRKMARK
;
596 rVEvt
.bAddMark
=MODKEY_MultiMark
;
603 eEvent
=SDREVENT_MOVACTION
;
606 else if (eHit
==SDRHIT_TEXTEDIT
)
608 eEvent
=SDREVENT_TEXTEDIT
;
610 else if (bMouseDown
&& bMouseLeft
)
612 if (rVEvt
.nMouseClicks
==2 && rVEvt
.nMouseCode
==MOUSE_LEFT
&& pObj
!=NULL
&& pHitObj
!=NULL
&& pHitObj
->HasTextEdit() && eHit
==SDRHIT_MARKEDOBJECT
)
616 eEvent
=SDREVENT_BEGTEXTEDIT
;
618 else if (MODKEY_ForceMark
&& eHit
!=SDRHIT_URLFIELD
)
620 eEvent
=SDREVENT_BEGMARK
; // AddMark,Unmark */
622 else if (eHit
==SDRHIT_HELPLINE
)
624 eEvent
=SDREVENT_BEGDRAGHELPLINE
; // nothing, actually
626 else if (eHit
==SDRHIT_GLUEPOINT
)
628 eEvent
=SDREVENT_MARKGLUEPOINT
; // AddMark+Drag
629 rVEvt
.bAddMark
=MODKEY_MultiMark
|| MODKEY_DeepMark
; // if not hit with Deep
631 else if (eHit
==SDRHIT_HANDLE
)
633 eEvent
=SDREVENT_BEGDRAGOBJ
; // Mark+Drag,AddMark+Drag,DeepMark+Drag,Unmark
634 bool bGlue
=pHdl
->GetKind()==HDL_GLUE
;
635 bool bPoly
=!bGlue
&& IsPointMarkable(*pHdl
);
636 bool bMarked
=bGlue
|| (bPoly
&& pHdl
->IsSelected());
639 eEvent
=bGlue
? SDREVENT_MARKGLUEPOINT
: SDREVENT_MARKPOINT
;
643 rVEvt
.bPrevNextMark
=true;
644 rVEvt
.bMarkPrev
=MODKEY_DeepBackw
;
646 else if (MODKEY_MultiMark
)
649 rVEvt
.bUnmark
=bMarked
; // Toggle
653 nGlueId
=(sal_uInt16
)pHdl
->GetObjHdlNum();
658 eEvent
=SDREVENT_BEGDRAGOBJ
; // don't change MarkState, only change Drag
662 else if (bInsPolyPt
&& (MODKEY_PolyPoly
|| (!MODKEY_MultiMark
&& !MODKEY_DeepMark
)))
664 eEvent
=SDREVENT_BEGINSOBJPOINT
;
665 rVEvt
.bInsPointNewObj
=MODKEY_PolyPoly
;
667 else if (bInsGluePt
&& !MODKEY_MultiMark
&& !MODKEY_DeepMark
)
669 eEvent
=SDREVENT_BEGINSGLUEPOINT
;
671 else if (eHit
==SDRHIT_TEXTEDITOBJ
)
673 eEvent
=SDREVENT_BEGTEXTEDIT
; // AddMark+Drag,DeepMark+Drag,Unmark
674 if (MODKEY_MultiMark
|| MODKEY_DeepMark
)
675 { // if not hit with Deep
676 eEvent
=SDREVENT_MARKOBJ
;
679 else if (eHit
==SDRHIT_MACRO
)
681 eEvent
=SDREVENT_BEGMACROOBJ
; // AddMark+Drag
682 if (MODKEY_MultiMark
|| MODKEY_DeepMark
)
683 { // if not hit with Deep
684 eEvent
=SDREVENT_MARKOBJ
;
687 else if (eHit
==SDRHIT_URLFIELD
)
689 eEvent
=SDREVENT_EXECUTEURL
; // AddMark+Drag
690 if (MODKEY_MultiMark
|| MODKEY_DeepMark
)
691 { // if not hit with Deep
692 eEvent
=SDREVENT_MARKOBJ
;
695 else if (eHit
==SDRHIT_MARKEDOBJECT
)
697 eEvent
=SDREVENT_BEGDRAGOBJ
; // DeepMark+Drag,Unmark
699 if (MODKEY_MultiMark
|| MODKEY_DeepMark
)
700 { // if not hit with Deep
701 eEvent
=SDREVENT_MARKOBJ
;
704 else if (IsCreateMode())
706 eEvent
=SDREVENT_BEGCREATEOBJ
; // nothing, actually
708 else if (eHit
==SDRHIT_UNMARKEDOBJECT
)
710 eEvent
=SDREVENT_MARKOBJ
; // AddMark+Drag
714 eEvent
=SDREVENT_BEGMARK
;
717 if (eEvent
==SDREVENT_MARKOBJ
)
719 rVEvt
.bAddMark
=MODKEY_MultiMark
|| MODKEY_DeepMark
; // if not hit with Deep
720 rVEvt
.bPrevNextMark
=MODKEY_DeepMark
;
721 rVEvt
.bMarkPrev
=MODKEY_DeepMark
&& MODKEY_DeepBackw
;
723 if (eEvent
==SDREVENT_BEGMARK
)
725 rVEvt
.bAddMark
=MODKEY_MultiMark
;
726 rVEvt
.bUnmark
=MODKEY_Unmark
;
729 rVEvt
.bIsAction
=bIsAction
;
730 rVEvt
.bIsTextEdit
=bIsTextEdit
;
731 rVEvt
.bTextEditHit
=bTextEditHit
;
732 rVEvt
.aLogicPos
=aLocalLogicPosition
;
735 if(rVEvt
.pRootObj
==NULL
)
738 rVEvt
.nHlplIdx
=nHlplIdx
;
739 rVEvt
.nGlueId
=nGlueId
;
742 rVEvt
.bCaptureMouse
=bMouseLeft
&& bMouseDown
&& eEvent
!=SDREVENT_NONE
;
743 rVEvt
.bReleaseMouse
=bMouseLeft
&& bMouseUp
;
745 if (rVEvt
.pRootObj
!=NULL
) {
746 if (rVEvt
.pRootObj
->GetObjList()!=rVEvt
.pPV
->GetObjList()) {
747 OSL_FAIL("SdrView::PickAnything(): pRootObj->GetObjList()!=pPV->GetObjList() !");
754 bool SdrView::DoMouseEvent(const SdrViewEvent
& rVEvt
)
757 SdrHitKind eHit
=rVEvt
.eHit
;
758 Point
aLogicPos(rVEvt
.aLogicPos
);
760 bool bShift
=(rVEvt
.nMouseCode
& KEY_SHIFT
) !=0;
761 bool bCtrl
=(rVEvt
.nMouseCode
& KEY_MOD1
) !=0;
762 bool bAlt
=(rVEvt
.nMouseCode
& KEY_MOD2
) !=0;
763 bool bMouseLeft
=(rVEvt
.nMouseCode
&MOUSE_LEFT
)!=0;
764 bool bMouseDown
=rVEvt
.bMouseDown
;
765 bool bMouseUp
=rVEvt
.bMouseUp
;
767 if (bMouseLeft
) aDragStat
.SetMouseDown(true);
768 } else if (bMouseUp
) {
769 if (bMouseLeft
) aDragStat
.SetMouseDown(false);
770 } else { // else, MouseMove
771 aDragStat
.SetMouseDown(bMouseLeft
);
775 SetSnapEnabled(!MODKEY_NoSnap
);
778 SetOrtho(MODKEY_Ortho
!=IsOrthoDesired());
780 #ifdef MODKEY_AngleSnap
781 SetAngleSnapEnabled(MODKEY_AngleSnap
);
783 #ifdef MODKEY_CopyDrag
784 SetDragWithCopy(MODKEY_CopyDrag
);
787 SetCreate1stPointAsCenter(MODKEY_Center
);
788 SetResizeAtCenter(MODKEY_Center
);
789 SetCrookAtCenter(MODKEY_Center
);
791 if (bMouseLeft
&& bMouseDown
&& rVEvt
.bIsTextEdit
&& (eHit
==SDRHIT_UNMARKEDOBJECT
|| eHit
==SDRHIT_NONE
)) {
792 SdrEndTextEdit(); // User has clicked beneath object, exit edit mode.
793 // pHdl is invalid, then, that shouldn't matter, though, as we expect
794 // pHdl==NULL (because of eHit).
796 switch (rVEvt
.eEvent
) {
797 case SDREVENT_NONE
: bRet
=false; break;
798 case SDREVENT_TEXTEDIT
: bRet
=false; break; // Events handled by the OutlinerView are not taken into account here.
799 case SDREVENT_MOVACTION
: MovAction(aLogicPos
); bRet
=true; break;
800 case SDREVENT_ENDACTION
: EndAction(); bRet
=true; break;
801 case SDREVENT_BCKACTION
: BckAction(); bRet
=true; break;
802 case SDREVENT_BRKACTION
: BrkAction(); bRet
=true; break;
803 case SDREVENT_ENDMARK
: EndAction(); bRet
=true; break;
804 case SDREVENT_BRKMARK
: {
806 if (!MarkObj(aLogicPos
,nHitTolLog
,rVEvt
.bAddMark
)) {
807 // No object hit. Do the following:
808 // 1. deselect any selected glue points
809 // 2. deselect any selected polygon points
810 // 3. deselect any selected objects
811 if (!rVEvt
.bAddMark
) UnmarkAll();
815 case SDREVENT_ENDCREATE
: { // if necessary, MarkObj
816 SdrCreateCmd eCmd
=SDRCREATE_NEXTPOINT
;
817 if (MODKEY_PolyPoly
) eCmd
=SDRCREATE_NEXTOBJECT
;
818 if (rVEvt
.nMouseClicks
>1) eCmd
=SDRCREATE_FORCEEND
;
819 if (!EndCreateObj(eCmd
)) { // Don't evaluate event for Create? -> Select
820 if (eHit
==SDRHIT_UNMARKEDOBJECT
|| eHit
==SDRHIT_TEXTEDIT
) {
821 MarkObj(rVEvt
.pRootObj
,rVEvt
.pPV
);
822 if (eHit
==SDRHIT_TEXTEDIT
)
824 bool bRet2(pActualOutDev
&& OUTDEV_WINDOW
== pActualOutDev
->GetOutDevType() &&
825 SdrBeginTextEdit(rVEvt
.pObj
, rVEvt
.pPV
, const_cast<vcl::Window
*>(static_cast<const vcl::Window
*>(pActualOutDev
.get())), false, (SdrOutliner
*)0L));
829 MouseEvent
aMEvt(pActualOutDev
->LogicToPixel(aLogicPos
),
830 1,rVEvt
.nMouseMode
,rVEvt
.nMouseCode
,rVEvt
.nMouseCode
);
832 OutlinerView
* pOLV
=GetTextEditOutlinerView();
834 pOLV
->MouseButtonDown(aMEvt
); // event for the Outliner, but without double-click
835 pOLV
->MouseButtonUp(aMEvt
); // event for the Outliner, but without double-click
839 bRet
=true; // object is selected and (if necessary) TextEdit is started
840 } else bRet
=false; // canceled Create, nothing else
841 } else bRet
=true; // return true for EndCreate
843 case SDREVENT_ENDDRAG
: {
844 bRet
=EndDragObj(IsDragWithCopy());
845 ForceMarkedObjToAnotherPage(); // TODO: Undo+bracing missing!
847 case SDREVENT_MARKOBJ
: { // + (if applicable) BegDrag
848 if (!rVEvt
.bAddMark
) UnmarkAllObj();
849 bool bUnmark
=rVEvt
.bUnmark
;
850 if (rVEvt
.bPrevNextMark
) {
851 bRet
=MarkNextObj(aLogicPos
,nHitTolLog
,rVEvt
.bMarkPrev
);
854 const size_t nCount0
=GetMarkedObjectCount();
855 bRet
=MarkObj(aLogicPos
,nHitTolLog
,rVEvt
.bAddMark
);
857 const size_t nCount1
=GetMarkedObjectCount();
858 bUnmark
=nCount1
<nCount0
;
861 BegDragObj(aLogicPos
,NULL
,(SdrHdl
*)NULL
,nMinMovLog
);
865 case SDREVENT_MARKPOINT
: { // + (if applicable) BegDrag
866 if (!rVEvt
.bAddMark
) UnmarkAllPoints();
867 if (rVEvt
.bPrevNextMark
) {
868 bRet
=MarkNextPoint(aLogicPos
,rVEvt
.bMarkPrev
);
870 bRet
=MarkPoint(*rVEvt
.pHdl
,rVEvt
.bUnmark
);
872 if (!rVEvt
.bUnmark
&& !rVEvt
.bPrevNextMark
) {
873 BegDragObj(aLogicPos
,NULL
,rVEvt
.pHdl
,nMinMovLog
);
877 case SDREVENT_MARKGLUEPOINT
: { // + (if applicable) BegDrag
878 if (!rVEvt
.bAddMark
) UnmarkAllGluePoints();
879 if (rVEvt
.bPrevNextMark
) {
880 bRet
=MarkNextGluePoint(aLogicPos
,rVEvt
.bMarkPrev
);
882 bRet
=MarkGluePoint(rVEvt
.pObj
,rVEvt
.nGlueId
,rVEvt
.pPV
,rVEvt
.bUnmark
);
884 if (!rVEvt
.bUnmark
&& !rVEvt
.bPrevNextMark
) {
885 SdrHdl
* pHdl
=GetGluePointHdl(rVEvt
.pObj
,rVEvt
.nGlueId
);
886 BegDragObj(aLogicPos
,NULL
,pHdl
,nMinMovLog
);
890 case SDREVENT_BEGMARK
: bRet
=BegMark(aLogicPos
,rVEvt
.bAddMark
,rVEvt
.bUnmark
); break;
891 case SDREVENT_BEGINSOBJPOINT
: bRet
= BegInsObjPoint(aLogicPos
, MODKEY_PolyPoly
); break;
892 case SDREVENT_ENDINSOBJPOINT
: {
893 SdrCreateCmd eCmd
=SDRCREATE_NEXTPOINT
;
894 if (MODKEY_PolyPoly
) eCmd
=SDRCREATE_NEXTOBJECT
;
895 if (rVEvt
.nMouseClicks
>1) eCmd
=SDRCREATE_FORCEEND
;
896 EndInsObjPoint(eCmd
);
899 case SDREVENT_BEGINSGLUEPOINT
: bRet
=BegInsGluePoint(aLogicPos
); break;
900 case SDREVENT_BEGDRAGHELPLINE
: bRet
=BegDragHelpLine(rVEvt
.nHlplIdx
,rVEvt
.pPV
); break;
901 case SDREVENT_BEGDRAGOBJ
: bRet
=BegDragObj(aLogicPos
,NULL
,rVEvt
.pHdl
,nMinMovLog
); break;
902 case SDREVENT_BEGCREATEOBJ
: {
903 if (nAktInvent
==SdrInventor
&& nAktIdent
==OBJ_CAPTION
) {
904 long nHgt
=SdrEngineDefaults::GetFontHeight();
905 bRet
=BegCreateCaptionObj(aLogicPos
,Size(5*nHgt
,2*nHgt
));
906 } else bRet
=BegCreateObj(aLogicPos
);
908 case SDREVENT_BEGMACROOBJ
: {
909 bRet
=BegMacroObj(aLogicPos
,nHitTolLog
,rVEvt
.pObj
,rVEvt
.pPV
,const_cast<vcl::Window
*>(static_cast<const vcl::Window
*>(pActualOutDev
.get())));
911 case SDREVENT_BEGTEXTEDIT
: {
912 if (!IsObjMarked(rVEvt
.pObj
)) {
914 MarkObj(rVEvt
.pRootObj
,rVEvt
.pPV
);
917 bRet
= pActualOutDev
&& OUTDEV_WINDOW
== pActualOutDev
->GetOutDevType()&&
918 SdrBeginTextEdit(rVEvt
.pObj
, rVEvt
.pPV
, const_cast<vcl::Window
*>(static_cast<const vcl::Window
*>(pActualOutDev
.get())), false, (SdrOutliner
*)0L);
922 MouseEvent
aMEvt(pActualOutDev
->LogicToPixel(aLogicPos
),
923 1,rVEvt
.nMouseMode
,rVEvt
.nMouseCode
,rVEvt
.nMouseCode
);
924 OutlinerView
* pOLV
=GetTextEditOutlinerView();
925 if (pOLV
!=NULL
) pOLV
->MouseButtonDown(aMEvt
); // event for the Outliner, but without double-click
930 if (bRet
&& pActualOutDev
&& pActualOutDev
->GetOutDevType()==OUTDEV_WINDOW
) {
931 vcl::Window
* pWin
=const_cast<vcl::Window
*>(static_cast<const vcl::Window
*>(pActualOutDev
.get()));
932 // left mouse button pressed?
933 bool bLeftDown
=(rVEvt
.nMouseCode
&MOUSE_LEFT
)!=0 && rVEvt
.bMouseDown
;
934 // left mouse button released?
935 bool bLeftUp
=(rVEvt
.nMouseCode
&MOUSE_LEFT
)!=0 && rVEvt
.bMouseUp
;
936 // left mouse button pressed or held?
937 bool bLeftDown1
=(rVEvt
.nMouseCode
&MOUSE_LEFT
)!=0 && !rVEvt
.bMouseUp
;
938 pWin
->SetPointer(GetPreferredPointer(rVEvt
.aLogicPos
,pWin
,
939 rVEvt
.nMouseCode
& (KEY_SHIFT
|KEY_MOD1
|KEY_MOD2
),bLeftDown1
));
940 bool bAction
=IsAction();
941 if (bLeftDown
&& bAction
)
942 pWin
->CaptureMouse();
943 else if (bLeftUp
|| (rVEvt
.bIsAction
&& !bAction
))
944 pWin
->ReleaseMouse();
948 #include <editeng/outlobj.hxx>
950 Pointer
SdrView::GetPreferredPointer(const Point
& rMousePos
, const OutputDevice
* pOut
, sal_uInt16 nModifier
, bool bLeftDown
) const
955 return pAktCreate
->GetCreatePointer();
957 if (mpCurrentSdrDragMethod
)
959 if ((IsDraggingPoints() || IsDraggingGluePoints()) && IsMouseHideWhileDraggingPoints())
960 return Pointer(PointerStyle::Null
);
962 return mpCurrentSdrDragMethod
->GetSdrDragPointer();
964 if (IsMarkObj() || IsMarkPoints() || IsMarkGluePoints() || IsSetPageOrg()) return Pointer(PointerStyle::Arrow
);
965 if (IsDragHelpLine()) return GetDraggedHelpLinePointer();
967 SdrObjMacroHitRec aHitRec
;
968 aHitRec
.aPos
=pOut
->LogicToPixel(rMousePos
);
969 aHitRec
.aDownPos
=aMacroDownPos
;
970 aHitRec
.nTol
=nMacroTol
;
971 aHitRec
.pVisiLayer
=&pMacroPV
->GetVisibleLayers();
972 aHitRec
.pPageView
=pMacroPV
;
973 aHitRec
.pOut
=pMacroWin
.get();
974 aHitRec
.bDown
=bMacroDown
;
975 return pMacroObj
->GetMacroPointer(aHitRec
);
978 // TextEdit, ObjEdit, Macro
979 if (IsTextEdit() && (IsTextEditInSelectionMode() || IsTextEditHit(rMousePos
,0/*nTol*/)))
981 if(!pOut
|| IsTextEditInSelectionMode())
983 if(pTextEditOutliner
->IsVertical())
984 return Pointer(PointerStyle::TextVertical
);
986 return Pointer(PointerStyle::Text
);
988 // Outliner should return something here...
989 Point
aPos(pOut
->LogicToPixel(rMousePos
));
990 Pointer
aPointer(pTextEditOutlinerView
->GetPointer(aPos
));
991 if (aPointer
==PointerStyle::Arrow
)
993 if(pTextEditOutliner
->IsVertical())
994 aPointer
= PointerStyle::TextVertical
;
996 aPointer
= PointerStyle::Text
;
1002 aVEvt
.nMouseCode
=(nModifier
&(KEY_SHIFT
|KEY_MOD1
|KEY_MOD2
))|MOUSE_LEFT
; // to see what would happen on MouseLeftDown
1003 aVEvt
.bMouseDown
=!bLeftDown
; // What if ..?
1004 aVEvt
.bMouseUp
=bLeftDown
; // What if ..?
1006 const_cast<SdrView
*>(this)->SetActualWin(pOut
);
1007 SdrHitKind eHit
=PickAnything(rMousePos
,aVEvt
);
1008 SdrEventKind eEvent
=aVEvt
.eEvent
;
1011 case SDREVENT_BEGCREATEOBJ
:
1012 return aAktCreatePointer
;
1013 case SDREVENT_MARKOBJ
:
1014 return Pointer(PointerStyle::Move
);
1015 case SDREVENT_BEGMARK
:
1016 return Pointer(PointerStyle::Arrow
);
1017 case SDREVENT_MARKPOINT
:
1018 case SDREVENT_MARKGLUEPOINT
:
1019 return Pointer(PointerStyle::MovePoint
);
1020 case SDREVENT_BEGINSOBJPOINT
:
1021 case SDREVENT_BEGINSGLUEPOINT
:
1022 return Pointer(PointerStyle::Cross
);
1023 case SDREVENT_EXECUTEURL
:
1024 return Pointer(PointerStyle::RefHand
);
1025 case SDREVENT_BEGMACROOBJ
:
1027 SdrObjMacroHitRec aHitRec
;
1028 aHitRec
.aPos
=aVEvt
.aLogicPos
;
1029 aHitRec
.aDownPos
=aHitRec
.aPos
;
1030 aHitRec
.nTol
=nHitTolLog
;
1031 aHitRec
.pVisiLayer
=&aVEvt
.pPV
->GetVisibleLayers();
1032 aHitRec
.pPageView
=aVEvt
.pPV
;
1033 aHitRec
.pOut
=const_cast<OutputDevice
*>(pOut
);
1034 return aVEvt
.pObj
->GetMacroPointer(aHitRec
);
1042 return Pointer(PointerStyle::Arrow
);
1043 case SDRHIT_HELPLINE
:
1044 return aVEvt
.pPV
->GetHelpLines()[aVEvt
.nHlplIdx
].GetPointer();
1045 case SDRHIT_GLUEPOINT
:
1046 return Pointer(PointerStyle::MovePoint
);
1047 case SDRHIT_TEXTEDIT
:
1048 case SDRHIT_TEXTEDITOBJ
:
1050 SdrTextObj
* pText
= dynamic_cast< SdrTextObj
* >( aVEvt
.pObj
);
1051 if(pText
&& pText
->HasText())
1053 OutlinerParaObject
* pParaObj
= pText
->GetOutlinerParaObject();
1054 if(pParaObj
&& pParaObj
->IsVertical())
1055 return Pointer(PointerStyle::TextVertical
);
1057 return Pointer(PointerStyle::Text
);
1062 bool bMarkHit
=eHit
==SDRHIT_MARKEDOBJECT
;
1063 SdrHdl
* pHdl
=aVEvt
.pHdl
;
1064 // now check the pointers for dragging
1065 if (pHdl
!=NULL
|| bMarkHit
) {
1066 SdrHdlKind eHdl
= pHdl
!=NULL
? pHdl
->GetKind() : HDL_MOVE
;
1067 bool bCorner
=pHdl
!=NULL
&& pHdl
->IsCornerHdl();
1068 bool bVertex
=pHdl
!=NULL
&& pHdl
->IsVertexHdl();
1069 bool bMov
=eHdl
==HDL_MOVE
;
1070 if (bMov
&& (eDragMode
==SDRDRAG_MOVE
|| eDragMode
==SDRDRAG_RESIZE
|| bMarkedHitMovesAlways
)) {
1071 if (!IsMoveAllowed()) return Pointer(PointerStyle::Arrow
); // because double click or drag & drop is possible
1072 return Pointer(PointerStyle::Move
);
1074 switch (eDragMode
) {
1075 case SDRDRAG_ROTATE
: {
1076 if ((bCorner
|| bMov
) && !IsRotateAllowed(true))
1077 return Pointer(PointerStyle::NotAllowed
);
1079 // are 3D objects selected?
1080 bool b3DObjSelected
= false;
1081 for (size_t a
=0; !b3DObjSelected
&& a
<GetMarkedObjectCount(); ++a
) {
1082 SdrObject
* pObj
= GetMarkedObjectByIndex(a
);
1083 if(pObj
&& pObj
->ISA(E3dObject
))
1084 b3DObjSelected
= true;
1086 // If we have a 3D object, go on despite !IsShearAllowed,
1087 // because then we have a rotation instead of a shear.
1088 if (bVertex
&& !IsShearAllowed() && !b3DObjSelected
)
1089 return Pointer(PointerStyle::NotAllowed
);
1091 return Pointer(PointerStyle::Rotate
);
1093 case SDRDRAG_SHEAR
: case SDRDRAG_DISTORT
: {
1095 if (!IsDistortAllowed(true) && !IsDistortAllowed(false)) return Pointer(PointerStyle::NotAllowed
);
1096 else return Pointer(PointerStyle::RefHand
);
1098 if (bVertex
&& !IsShearAllowed()) return Pointer(PointerStyle::NotAllowed
);
1100 if (!IsMoveAllowed()) return Pointer(PointerStyle::Arrow
); // because double click or drag & drop is possible
1101 return Pointer(PointerStyle::Move
);
1104 case SDRDRAG_MIRROR
: {
1105 if (bCorner
|| bVertex
|| bMov
) {
1106 SdrHdl
* pH1
=maHdlList
.GetHdl(HDL_REF1
);
1107 SdrHdl
* pH2
=maHdlList
.GetHdl(HDL_REF2
);
1111 if (pH1
!=NULL
&& pH2
!=NULL
) {
1112 aDif
=pH2
->GetPos()-pH1
->GetPos();
1113 b90
=(aDif
.X()==0) || aDif
.Y()==0;
1114 b45
=b90
|| (std::abs(aDif
.X())==std::abs(aDif
.Y()));
1117 if (!IsMirrorAllowed(true,true)) bNo
=true; // any mirroring is forbidden
1118 if (!IsMirrorAllowed(false,false) && !b45
) bNo
=true; // mirroring freely is forbidden
1119 if (!IsMirrorAllowed(true,false) && !b90
) bNo
=true; // mirroring horizontally/vertically is allowed
1120 if (bNo
) return Pointer(PointerStyle::NotAllowed
);
1122 return Pointer(PointerStyle::Mirror
);
1124 return Pointer(PointerStyle::Mirror
);
1128 case SDRDRAG_TRANSPARENCE
:
1130 if(!IsTransparenceAllowed())
1131 return Pointer(PointerStyle::NotAllowed
);
1133 return Pointer(PointerStyle::RefHand
);
1136 case SDRDRAG_GRADIENT
:
1138 if(!IsGradientAllowed())
1139 return Pointer(PointerStyle::NotAllowed
);
1141 return Pointer(PointerStyle::RefHand
);
1144 case SDRDRAG_CROOK
: {
1145 if (bCorner
|| bVertex
|| bMov
) {
1146 if (!IsCrookAllowed(true) && !IsCrookAllowed(false)) return Pointer(PointerStyle::NotAllowed
);
1147 return Pointer(PointerStyle::Crook
);
1153 return Pointer(PointerStyle::Crop
);
1157 if ((bCorner
|| bVertex
) && !IsResizeAllowed(true)) return Pointer(PointerStyle::NotAllowed
);
1160 if (pHdl
!=NULL
) return pHdl
->GetPointer();
1162 if (!IsMoveAllowed()) return Pointer(PointerStyle::Arrow
); // because double click or drag & drop is possible
1163 return Pointer(PointerStyle::Move
);
1166 if (eEditMode
==SDREDITMODE_CREATE
) return aAktCreatePointer
;
1167 return Pointer(PointerStyle::Arrow
);
1170 #define STR_NOTHING "nothing"
1171 OUString
SdrView::GetStatusText()
1176 aStr
+= STR_NOTHING
;
1178 if (pAktCreate
!=NULL
)
1180 aStr
=pAktCreate
->getSpecialDragComment(aDragStat
);
1184 aName
= pAktCreate
->TakeObjNameSingul();
1185 aStr
= ImpGetResStr(STR_ViewCreateObj
);
1188 else if (mpCurrentSdrDragMethod
)
1190 if (bInsPolyPoint
|| IsInsertGluePoint())
1192 aStr
=aInsPointUndoStr
;
1196 if (aDragStat
.IsMinMoved())
1200 "(" << this << ") " << mpCurrentSdrDragMethod
);
1201 mpCurrentSdrDragMethod
->TakeSdrDragComment(aStr
);
1205 else if(IsMarkObj())
1207 if(AreObjectsMarked())
1209 aStr
= ImpGetResStr(STR_ViewMarkMoreObjs
);
1213 aStr
= ImpGetResStr(STR_ViewMarkObjs
);
1216 else if(IsMarkPoints())
1218 if(HasMarkedPoints())
1220 aStr
= ImpGetResStr(STR_ViewMarkMorePoints
);
1224 aStr
= ImpGetResStr(STR_ViewMarkPoints
);
1226 } else if (IsMarkGluePoints())
1228 if(HasMarkedGluePoints())
1230 aStr
= ImpGetResStr(STR_ViewMarkMoreGluePoints
);
1234 aStr
= ImpGetResStr(STR_ViewMarkGluePoints
);
1237 else if (IsTextEdit() && pTextEditOutlinerView
!=NULL
) {
1238 aStr
=ImpGetResStr(STR_ViewTextEdit
); // "TextEdit - Row y, Column x";
1239 ESelection
aSel(pTextEditOutlinerView
->GetSelection());
1240 long nPar
=aSel
.nEndPara
,nLin
=0,nCol
=aSel
.nEndPos
;
1241 if (aSel
.nEndPara
>0) {
1242 for (sal_Int32 nParaNum
=0; nParaNum
<aSel
.nEndPara
; nParaNum
++) {
1243 nLin
+=pTextEditOutliner
->GetLineCount(nParaNum
);
1246 // A little imperfection:
1247 // At the end of a line of any multi-line paragraph, we display the
1248 // position of the next line of the same paragraph, if there is one.
1249 sal_uInt16 nParaLine
= 0;
1250 sal_uIntPtr nParaLineCount
= pTextEditOutliner
->GetLineCount(aSel
.nEndPara
);
1254 sal_uInt16 nLen
= pTextEditOutliner
->GetLineLen(aSel
.nEndPara
, nParaLine
);
1255 bool bLastLine
= (nParaLine
== nParaLineCount
- 1);
1256 if (nCol
>nLen
|| (!bLastLine
&& nCol
== nLen
))
1266 bBrk
= true; // to be sure
1269 aStr
= aStr
.replaceFirst("%1", OUString::number(nPar
+ 1));
1270 aStr
= aStr
.replaceFirst("%2", OUString::number(nLin
+ 1));
1271 aStr
= aStr
.replaceFirst("%3", OUString::number(nCol
+ 1));
1274 aStr
+= ", Level " ;
1275 aStr
+= OUString::number( pTextEditOutliner
->GetDepth( aSel
.nEndPara
) );
1279 if(aStr
== STR_NOTHING
)
1281 if (AreObjectsMarked()) {
1282 ImpTakeDescriptionStr(STR_ViewMarked
,aStr
);
1283 if (IsGluePointEditMode()) {
1284 if (HasMarkedGluePoints()) {
1285 ImpTakeDescriptionStr(STR_ViewMarked
,aStr
,0,ImpTakeDescriptionOptions::GLUEPOINTS
);
1288 if (HasMarkedPoints()) {
1289 ImpTakeDescriptionStr(STR_ViewMarked
,aStr
,0,ImpTakeDescriptionOptions::POINTS
);
1296 else if(!aName
.isEmpty())
1298 aStr
= aStr
.replaceFirst("%1", aName
);
1303 // capitalize first letter
1304 aStr
= aStr
.replaceAt(0, 1, OUString(aStr
[0]).toAsciiUpperCase());
1309 SdrViewContext
SdrView::GetContext() const
1311 if( IsGluePointEditMode() )
1312 return SDRCONTEXT_GLUEPOINTEDIT
;
1314 const size_t nMarkCount
= GetMarkedObjectCount();
1316 if( HasMarkablePoints() && !IsFrameHandles() )
1319 for( size_t nMarkNum
= 0; nMarkNum
< nMarkCount
&& bPath
; ++nMarkNum
)
1320 if (!GetMarkedObjectByIndex(nMarkNum
)->ISA(SdrPathObj
))
1324 return SDRCONTEXT_POINTEDIT
;
1327 if( GetMarkedObjectCount() )
1329 bool bGraf
= true, bMedia
= true, bTable
= true;
1331 for( size_t nMarkNum
= 0; nMarkNum
< nMarkCount
&& ( bGraf
|| bMedia
); ++nMarkNum
)
1333 const SdrObject
* pMarkObj
= GetMarkedObjectByIndex( nMarkNum
);
1334 DBG_ASSERT( pMarkObj
, "SdrView::GetContext(), null pointer in mark list!" );
1339 if( !pMarkObj
->ISA( SdrGrafObj
) )
1342 if( !pMarkObj
->ISA( SdrMediaObj
) )
1345 if( !pMarkObj
->ISA( sdr::table::SdrTableObj
) )
1350 return SDRCONTEXT_GRAPHIC
;
1352 return SDRCONTEXT_MEDIA
;
1354 return SDRCONTEXT_TABLE
;
1357 return SDRCONTEXT_STANDARD
;
1360 void SdrView::MarkAll()
1363 GetTextEditOutlinerView()->SetSelection(ESelection(0,0,EE_PARA_ALL
,EE_TEXTPOS_ALL
));
1365 if (pItemBrowser
!=nullptr) pItemBrowser
->SetDirty();
1367 } else if (IsGluePointEditMode()) MarkAllGluePoints();
1368 else if (HasMarkablePoints()) MarkAllPoints();
1372 void SdrView::UnmarkAll()
1375 ESelection eSel
=GetTextEditOutlinerView()->GetSelection();
1376 eSel
.nStartPara
=eSel
.nEndPara
;
1377 eSel
.nStartPos
=eSel
.nEndPos
;
1378 GetTextEditOutlinerView()->SetSelection(eSel
);
1380 if (pItemBrowser
!=nullptr) pItemBrowser
->SetDirty();
1382 } else if (HasMarkedGluePoints()) UnmarkAllGluePoints();
1383 else if (HasMarkedPoints()) UnmarkAllPoints(); // Marked, not Markable!
1384 else UnmarkAllObj();
1387 const Rectangle
& SdrView::GetMarkedRect() const
1389 if (IsGluePointEditMode() && HasMarkedGluePoints()) {
1390 return GetMarkedGluePointsRect();
1392 if (HasMarkedPoints()) {
1393 return GetMarkedPointsRect();
1395 return GetMarkedObjRect();
1398 void SdrView::DeleteMarked()
1402 SdrObjEditView::KeyInput(KeyEvent(0,vcl::KeyCode(KeyFuncType::DELETE
)),pTextEditWin
);
1406 if( mxSelectionController
.is() && mxSelectionController
->DeleteMarked() )
1408 // action already performed by current selection controller, do nothing
1410 else if (IsGluePointEditMode() && HasMarkedGluePoints())
1412 DeleteMarkedGluePoints();
1414 else if (GetContext()==SDRCONTEXT_POINTEDIT
&& HasMarkedPoints())
1416 DeleteMarkedPoints();
1425 bool SdrView::BegMark(const Point
& rPnt
, bool bAddMark
, bool bUnmark
)
1427 if (bUnmark
) bAddMark
=true;
1428 if (IsGluePointEditMode()) {
1429 if (!bAddMark
) UnmarkAllGluePoints();
1430 return BegMarkGluePoints(rPnt
,bUnmark
);
1431 } else if (HasMarkablePoints()) {
1432 if (!bAddMark
) UnmarkAllPoints();
1433 return BegMarkPoints(rPnt
,bUnmark
);
1435 if (!bAddMark
) UnmarkAllObj();
1436 return BegMarkObj(rPnt
,bUnmark
);
1440 void SdrView::ConfigurationChanged( ::utl::ConfigurationBroadcaster
*p
, sal_uInt32 nHint
)
1442 onAccessibilityOptionsChanged();
1443 SdrCreateView::ConfigurationChanged(p
, nHint
);
1447 /** method is called whenever the global SvtAccessibilityOptions is changed */
1448 void SdrView::onAccessibilityOptionsChanged()
1452 void SdrView::SetMasterPagePaintCaching(bool bOn
)
1454 if(mbMasterPagePaintCaching
!= bOn
)
1456 mbMasterPagePaintCaching
= bOn
;
1458 // reset at all SdrPageWindows
1459 SdrPageView
* pPageView
= GetSdrPageView();
1463 for(sal_uInt32
b(0L); b
< pPageView
->PageWindowCount(); b
++)
1465 SdrPageWindow
* pPageWindow
= pPageView
->GetPageWindow(b
);
1466 assert(pPageWindow
&& "SdrView::SetMasterPagePaintCaching: Corrupt SdrPageWindow list (!)");
1468 // force deletion of ObjectContact, so at re-display all VOCs
1469 // will be re-created with updated flag setting
1470 pPageWindow
->ResetObjectContact();
1473 // force redraw of this view
1474 pPageView
->InvalidateAllWin();
1480 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */