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 <sal/config.h>
22 #include <vcl/svapp.hxx>
23 #include <vcl/waitobj.hxx>
24 #include <vcl/ptrstyle.hxx>
25 #include <editeng/flditem.hxx>
26 #include <svx/svdogrp.hxx>
27 #include <svx/svdoole2.hxx>
28 #include <tools/urlobj.hxx>
29 #include <vcl/help.hxx>
30 #include <svx/bmpmask.hxx>
31 #include <svx/svdotext.hxx>
32 #include <sfx2/app.hxx>
33 #include <sfx2/dispatch.hxx>
34 #include <sfx2/bindings.hxx>
35 #include <svx/svdpagv.hxx>
36 #include <vcl/imapobj.hxx>
37 #include <svx/svxids.hrc>
38 #include <svx/obj3d.hxx>
39 #include <svx/scene3d.hxx>
40 #include <sfx2/viewfrm.hxx>
42 #include <anminfo.hxx>
43 #include <strings.hrc>
47 #include <GraphicDocShell.hxx>
49 #include <ViewShell.hxx>
50 #include <FrameView.hxx>
53 #include <drawdoc.hxx>
54 #include <DrawDocShell.hxx>
55 #include <sdresid.hxx>
56 #include <drawview.hxx>
58 #include <vcl/weld.hxx>
59 #include <slideshow.hxx>
60 #include <svx/sdrhittesthelper.hxx>
61 #include <unotools/securityoptions.hxx>
63 using namespace ::com::sun::star
;
69 * Base-class for all drawmodul-specific functions
71 FuDraw::FuDraw(ViewShell
* pViewSh
, ::sd::Window
* pWin
, ::sd::View
* pView
,
72 SdDrawDocument
* pDoc
, SfxRequest
& rReq
)
73 : FuPoor(pViewSh
, pWin
, pView
, pDoc
, rReq
)
74 , aNewPointer(PointerStyle::Arrow
)
75 , aOldPointer(PointerStyle::Arrow
)
77 , bDragHelpLine(false)
90 * Code shared by MouseButtonDown and MouseMove
92 void FuDraw::DoModifiers(const MouseEvent
& rMEvt
, bool bSnapModPressed
)
94 FrameView
* pFrameView
= mpViewShell
->GetFrameView();
95 bool bGridSnap
= pFrameView
->IsGridSnap();
96 bGridSnap
= (bSnapModPressed
!= bGridSnap
);
98 if (mpView
->IsGridSnap() != bGridSnap
)
99 mpView
->SetGridSnap(bGridSnap
);
101 bool bBordSnap
= pFrameView
->IsBordSnap();
102 bBordSnap
= (bSnapModPressed
!= bBordSnap
);
104 if (mpView
->IsBordSnap() != bBordSnap
)
105 mpView
->SetBordSnap(bBordSnap
);
107 bool bHlplSnap
= pFrameView
->IsHlplSnap();
108 bHlplSnap
= (bSnapModPressed
!= bHlplSnap
);
110 if (mpView
->IsHlplSnap() != bHlplSnap
)
111 mpView
->SetHlplSnap(bHlplSnap
);
113 bool bOFrmSnap
= pFrameView
->IsOFrmSnap();
114 bOFrmSnap
= (bSnapModPressed
!= bOFrmSnap
);
116 if (mpView
->IsOFrmSnap() != bOFrmSnap
)
117 mpView
->SetOFrmSnap(bOFrmSnap
);
119 bool bOPntSnap
= pFrameView
->IsOPntSnap();
120 bOPntSnap
= (bSnapModPressed
!= bOPntSnap
);
122 if (mpView
->IsOPntSnap() != bOPntSnap
)
123 mpView
->SetOPntSnap(bOPntSnap
);
125 bool bOConSnap
= pFrameView
->IsOConSnap();
126 bOConSnap
= (bSnapModPressed
!= bOConSnap
);
128 if (mpView
->IsOConSnap() != bOConSnap
)
129 mpView
->SetOConSnap(bOConSnap
);
131 bool bAngleSnap
= rMEvt
.IsShift() == !pFrameView
->IsAngleSnapEnabled();
133 if (mpView
->IsAngleSnapEnabled() != bAngleSnap
)
134 mpView
->SetAngleSnapEnabled(bAngleSnap
);
136 bool bCenter
= rMEvt
.IsMod2();
138 if ( mpView
->IsCreate1stPointAsCenter() != bCenter
||
139 mpView
->IsResizeAtCenter() != bCenter
)
141 mpView
->SetCreate1stPointAsCenter(bCenter
);
142 mpView
->SetResizeAtCenter(bCenter
);
147 bool FuDraw::MouseButtonDown(const MouseEvent
& rMEvt
)
149 // remember button state for creation of own MouseEvents
150 SetMouseButtonCode(rMEvt
.GetButtons());
152 bool bReturn
= false;
153 bDragHelpLine
= false;
154 aMDPos
= mpWindow
->PixelToLogic( rMEvt
.GetPosPixel() );
156 if ( rMEvt
.IsLeft() )
158 FrameView
* pFrameView
= mpViewShell
->GetFrameView();
162 bool bRestricted
= true;
164 if (mpView
->IsDragObj())
166 // object is dragged (move, resize,...)
167 const SdrHdl
* pHdl
= mpView
->GetDragStat().GetHdl();
169 if (!pHdl
|| (!pHdl
->IsCornerHdl() && !pHdl
->IsVertexHdl()))
177 if(bRestricted
&& doConstructOrthogonal())
179 // Restrict movement:
180 // rectangle->quadrat, ellipse->circle etc.
181 bOrtho
= !rMEvt
.IsShift();
185 bOrtho
= rMEvt
.IsShift() != pFrameView
->IsOrtho();
187 if (!mpView
->IsSnapEnabled())
188 mpView
->SetSnapEnabled(true);
190 bool bSnapModPressed
= rMEvt
.IsMod1();
191 if (mpView
->IsOrtho() != bOrtho
)
192 mpView
->SetOrtho(bOrtho
);
194 DoModifiers(rMEvt
, bSnapModPressed
);
196 SdrPageView
* pPV
= nullptr;
197 sal_uInt16 nHitLog
= sal_uInt16 ( mpWindow
->PixelToLogic(Size(HITPIX
,0)).Width() );
199 // look only for HelpLines when they are visible (!)
200 bool bHelpLine(false);
201 if(mpView
->IsHlplVisible())
202 bHelpLine
= mpView
->PickHelpLine(aMDPos
, nHitLog
, *mpWindow
, nHelpLine
, pPV
);
203 bool bHitHdl
= (mpView
->PickHandle(aMDPos
) != nullptr);
206 && !mpView
->IsCreateObj()
207 && ((mpView
->GetEditMode() == SdrViewEditMode::Edit
&& !bHitHdl
) || (rMEvt
.IsShift() && bSnapModPressed
)) )
209 mpWindow
->CaptureMouse();
210 mpView
->BegDragHelpLine(nHelpLine
, pPV
);
211 bDragHelpLine
= mpView
->IsDragHelpLine();
215 ForcePointer(&rMEvt
);
220 bool FuDraw::MouseMove(const MouseEvent
& rMEvt
)
222 FrameView
* pFrameView
= mpViewShell
->GetFrameView();
223 Point aPos
= mpWindow
->PixelToLogic( rMEvt
.GetPosPixel() );
226 bool bRestricted
= true;
228 if (mpView
->IsDragObj())
230 // object is dragged (move, resize, ...)
231 const SdrHdl
* pHdl
= mpView
->GetDragStat().GetHdl();
233 if (!pHdl
|| (!pHdl
->IsCornerHdl() && !pHdl
->IsVertexHdl()))
240 if (mpView
->IsAction())
242 // #i33136# and fdo#88339
243 if(bRestricted
&& doConstructOrthogonal())
245 // Scale proportionally by default:
246 // rectangle->quadrat, ellipse->circle, Images etc.
247 bOrtho
= !rMEvt
.IsShift();
251 bOrtho
= rMEvt
.IsShift() != pFrameView
->IsOrtho();
254 bool bSnapModPressed
= rMEvt
.IsMod2();
255 mpView
->SetDragWithCopy(rMEvt
.IsMod1() && pFrameView
->IsDragWithCopy());
257 if (mpView
->IsOrtho() != bOrtho
)
258 mpView
->SetOrtho(bOrtho
);
259 DoModifiers(rMEvt
, bSnapModPressed
);
262 if ( mpView
->IsDragHelpLine() )
263 mpView
->MovDragHelpLine(aPos
);
266 bool bReturn
= mpView
->MouseMove(rMEvt
, mpWindow
);
268 if (mpView
->IsAction())
270 // Because the flag set back if necessary in MouseMove
271 if (mpView
->IsOrtho() != bOrtho
)
272 mpView
->SetOrtho(bOrtho
);
275 ForcePointer(&rMEvt
);
280 bool FuDraw::MouseButtonUp(const MouseEvent
& rMEvt
)
282 if (mpView
&& mpView
->IsDragHelpLine())
283 mpView
->EndDragHelpLine();
287 ::tools::Rectangle
aOutputArea(Point(0,0), mpWindow
->GetOutputSizePixel());
289 if (mpView
&& !aOutputArea
.IsInside(rMEvt
.GetPosPixel()))
290 mpView
->GetSdrPageView()->DeleteHelpLine(nHelpLine
);
292 mpWindow
->ReleaseMouse();
297 FrameView
* pFrameView
= mpViewShell
->GetFrameView();
298 mpView
->SetOrtho( pFrameView
->IsOrtho() );
299 mpView
->SetAngleSnapEnabled( pFrameView
->IsAngleSnapEnabled() );
300 mpView
->SetSnapEnabled(true);
301 mpView
->SetCreate1stPointAsCenter(false);
302 mpView
->SetResizeAtCenter(false);
303 mpView
->SetDragWithCopy(pFrameView
->IsDragWithCopy());
304 mpView
->SetGridSnap(pFrameView
->IsGridSnap());
305 mpView
->SetBordSnap(pFrameView
->IsBordSnap());
306 mpView
->SetHlplSnap(pFrameView
->IsHlplSnap());
307 mpView
->SetOFrmSnap(pFrameView
->IsOFrmSnap());
308 mpView
->SetOPntSnap(pFrameView
->IsOPntSnap());
309 mpView
->SetOConSnap(pFrameView
->IsOConSnap());
312 bIsInDragMode
= false;
313 ForcePointer(&rMEvt
);
314 FuPoor::MouseButtonUp(rMEvt
);
320 * Process keyboard input
321 * @returns sal_True if a KeyEvent is being processed, sal_False otherwise
323 bool FuDraw::KeyInput(const KeyEvent
& rKEvt
)
325 bool bReturn
= false;
327 switch ( rKEvt
.GetKeyCode().GetCode() )
331 bReturn
= FuDraw::cancel();
338 if (!mpDocSh
->IsReadOnly())
340 if (mpView
->IsPresObjSelected(false, true, false, true))
342 std::unique_ptr
<weld::MessageDialog
> xInfoBox(Application::CreateMessageDialog(mpWindow
->GetFrameWeld(),
343 VclMessageType::Info
, VclButtonsType::Ok
,
344 SdResId(STR_ACTION_NOTPOSSIBLE
)));
349 // wait-mousepointer while deleting object
350 WaitObject
aWait( static_cast<vcl::Window
*>(mpViewShell
->GetActiveWindow()) );
352 mpView
->DeleteMarked();
361 vcl::KeyCode aCode
= rKEvt
.GetKeyCode();
363 if ( !aCode
.IsMod1() && !aCode
.IsMod2() )
365 // Moved next line which was a bugfix itself into
366 // the scope which really does the object selection travel
367 // and thus is allowed to call SelectionHasChanged().
369 // Switch to FuSelect.
370 mpViewShell
->GetViewFrame()->GetDispatcher()->Execute(
372 SfxCallMode::ASYNCHRON
| SfxCallMode::RECORD
);
374 // changeover to the next object
375 if(!mpView
->MarkNextObj( !aCode
.IsShift() ))
377 //If there is only one object, don't do the UnmarkAllObj() & MarkNextObj().
378 if ( mpView
->HasMultipleMarkableObjects() && mpView
->AreObjectsMarked() )
380 // No next object: go over open end and get first from
382 mpView
->UnmarkAllObj();
383 mpView
->MarkNextObj(!aCode
.IsShift());
387 if(mpView
->AreObjectsMarked())
388 mpView
->MakeVisible(mpView
->GetAllMarkedRect(), *mpWindow
);
397 vcl::KeyCode aCode
= rKEvt
.GetKeyCode();
399 if ( aCode
.IsMod1() )
402 mpView
->UnmarkAllObj();
403 mpView
->MarkNextObj();
405 if(mpView
->AreObjectsMarked())
406 mpView
->MakeVisible(mpView
->GetAllMarkedRect(), *mpWindow
);
415 vcl::KeyCode aCode
= rKEvt
.GetKeyCode();
417 if ( aCode
.IsMod1() )
420 mpView
->UnmarkAllObj();
421 mpView
->MarkNextObj(true);
423 if(mpView
->AreObjectsMarked())
424 mpView
->MakeVisible(mpView
->GetAllMarkedRect(), *mpWindow
);
437 bReturn
= FuPoor::KeyInput(rKEvt
);
441 mpWindow
->ReleaseMouse();
447 void FuDraw::Activate()
454 * Toggle mouse-pointer
456 void FuDraw::ForcePointer(const MouseEvent
* pMEvt
)
459 sal_uInt16 nModifier
= 0;
460 bool bLeftDown
= false;
461 bool bDefPointer
= true;
465 aPnt
= mpWindow
->PixelToLogic(pMEvt
->GetPosPixel());
466 nModifier
= pMEvt
->GetModifier();
467 bLeftDown
= pMEvt
->IsLeft();
471 aPnt
= mpWindow
->PixelToLogic(mpWindow
->GetPointerPosPixel());
474 if (mpView
->IsDragObj())
476 if (SD_MOD()->GetWaterCan() && !mpView
->PickHandle(aPnt
))
480 mpWindow
->SetPointer(PointerStyle::Fill
);
485 SdrHdl
* pHdl
= mpView
->PickHandle(aPnt
);
487 if (SD_MOD()->GetWaterCan() && !pHdl
)
491 mpWindow
->SetPointer(PointerStyle::Fill
);
494 mpViewShell
->GetViewFrame()->HasChildWindow(SvxBmpMaskChildWindow::GetChildWindowId()))
497 SfxChildWindow
* pWnd
= mpViewShell
->GetViewFrame()->GetChildWindow(SvxBmpMaskChildWindow::GetChildWindowId());
498 SvxBmpMask
* pMask
= pWnd
? static_cast<SvxBmpMask
*>(pWnd
->GetWindow()) : nullptr;
499 if (pMask
&& pMask
->IsEyedropping())
502 mpWindow
->SetPointer(PointerStyle::RefHand
);
505 else if (!mpView
->IsAction())
507 SdrObject
* pObj
= nullptr;
508 SdrPageView
* pPV
= nullptr;
510 SdrHitKind eHit
= SdrHitKind::NONE
;
511 SdrDragMode eDragMode
= mpView
->GetDragMode();
515 eHit
= mpView
->PickAnything(*pMEvt
, SdrMouseEventKind::MOVE
, aVEvt
);
518 if ((eDragMode
== SdrDragMode::Rotate
) && (eHit
== SdrHitKind::MarkedObject
))
520 // The goal of this request is show always the rotation arrow for 3D-objects at rotation mode
521 // Independent of the settings at Tools->Options->Draw "Objects always moveable"
522 // 2D-objects acquit in another way. Otherwise, the rotation of 3d-objects around any axes
523 // wouldn't be possible per default.
524 const SdrMarkList
& rMarkList
= mpView
->GetMarkedObjectList();
525 SdrObject
* pObject
= rMarkList
.GetMark(0)->GetMarkedSdrObj();
526 if ((dynamic_cast<const E3dObject
* >(pObject
) != nullptr) && (rMarkList
.GetMarkCount() == 1))
528 mpWindow
->SetPointer(PointerStyle::Rotate
);
529 bDefPointer
= false; // Otherwise it'll be called Joe's routine and the mousepointer will reconfigurate again
533 if (eHit
== SdrHitKind::NONE
)
535 // found nothing -> look after at the masterpage
536 pObj
= mpView
->PickObj(aPnt
, mpView
->getHitTolLog(), pPV
, SdrSearchOptions::ALSOONMASTER
);
538 else if (eHit
== SdrHitKind::UnmarkedObject
)
542 else if (eHit
== SdrHitKind::TextEditObj
&& dynamic_cast< const FuSelection
*>( this ) != nullptr)
544 sal_uInt16 nSdrObjKind
= aVEvt
.pObj
->GetObjIdentifier();
546 if ( nSdrObjKind
!= OBJ_TEXT
&&
547 nSdrObjKind
!= OBJ_TITLETEXT
&&
548 nSdrObjKind
!= OBJ_OUTLINETEXT
&&
549 aVEvt
.pObj
->IsEmptyPresObj() )
553 mpWindow
->SetPointer(PointerStyle::Arrow
);
557 if (pObj
&& pMEvt
&& !pMEvt
->IsMod2() && dynamic_cast< const FuSelection
*>( this ) != nullptr)
559 // test for animation or ImageMap
560 bDefPointer
= !SetPointer(pObj
, aPnt
);
562 if (bDefPointer
&& (dynamic_cast< const SdrObjGroup
*>( pObj
) != nullptr || dynamic_cast< const E3dScene
* >(pObj
) != nullptr))
564 // take a glance into the group
565 pObj
= mpView
->PickObj(aPnt
, mpView
->getHitTolLog(), pPV
, SdrSearchOptions::ALSOONMASTER
| SdrSearchOptions::DEEP
);
567 bDefPointer
= !SetPointer(pObj
, aPnt
);
575 mpWindow
->SetPointer(mpView
->GetPreferredPointer(
576 aPnt
, mpWindow
, nModifier
, bLeftDown
));
581 * Set cursor for animation or imagemap
583 bool FuDraw::SetPointer(SdrObject
* pObj
, const Point
& rPos
)
587 bool bAnimationInfo
= dynamic_cast< const GraphicDocShell
*>( mpDocSh
) == nullptr &&
588 SdDrawDocument::GetAnimationInfo(pObj
);
590 bool bImageMapInfo
= false;
593 bImageMapInfo
= SdDrawDocument::GetIMapInfo(pObj
) != nullptr;
595 if (bAnimationInfo
|| bImageMapInfo
)
597 const SdrLayerIDSet
* pVisiLayer
= &mpView
->GetSdrPageView()->GetVisibleLayers();
598 sal_uInt16
nHitLog(sal_uInt16 (mpWindow
->PixelToLogic(Size(HITPIX
,0)).Width()));
599 long n2HitLog(nHitLog
* 2);
600 Point
aHitPosR(rPos
);
601 Point
aHitPosL(rPos
);
602 Point
aHitPosT(rPos
);
603 Point
aHitPosB(rPos
);
605 aHitPosR
.AdjustX(n2HitLog
);
606 aHitPosL
.AdjustX( -n2HitLog
);
607 aHitPosT
.AdjustY(n2HitLog
);
608 aHitPosB
.AdjustY( -n2HitLog
);
610 if ( !pObj
->IsClosedObj() ||
611 ( SdrObjectPrimitiveHit(*pObj
, aHitPosR
, nHitLog
, *mpView
->GetSdrPageView(), pVisiLayer
, false) &&
612 SdrObjectPrimitiveHit(*pObj
, aHitPosL
, nHitLog
, *mpView
->GetSdrPageView(), pVisiLayer
, false) &&
613 SdrObjectPrimitiveHit(*pObj
, aHitPosT
, nHitLog
, *mpView
->GetSdrPageView(), pVisiLayer
, false) &&
614 SdrObjectPrimitiveHit(*pObj
, aHitPosB
, nHitLog
, *mpView
->GetSdrPageView(), pVisiLayer
, false)))
616 /**********************************************************
617 * hit inside the object (without margin) or open object
618 ********************************************************/
622 /******************************************************
624 ******************************************************/
625 SdAnimationInfo
* pInfo
= SdDrawDocument::GetAnimationInfo(pObj
);
627 if(( dynamic_cast< const DrawView
*>( mpView
) != nullptr &&
628 (pInfo
->meClickAction
== presentation::ClickAction_BOOKMARK
||
629 pInfo
->meClickAction
== presentation::ClickAction_DOCUMENT
||
630 pInfo
->meClickAction
== presentation::ClickAction_PREVPAGE
||
631 pInfo
->meClickAction
== presentation::ClickAction_NEXTPAGE
||
632 pInfo
->meClickAction
== presentation::ClickAction_FIRSTPAGE
||
633 pInfo
->meClickAction
== presentation::ClickAction_LASTPAGE
||
634 pInfo
->meClickAction
== presentation::ClickAction_VERB
||
635 pInfo
->meClickAction
== presentation::ClickAction_PROGRAM
||
636 pInfo
->meClickAction
== presentation::ClickAction_MACRO
||
637 pInfo
->meClickAction
== presentation::ClickAction_SOUND
))
639 ( dynamic_cast< const DrawView
*>( mpView
) != nullptr &&
640 SlideShow::IsRunning( mpViewShell
->GetViewShellBase() ) &&
641 (pInfo
->meClickAction
== presentation::ClickAction_VANISH
||
642 pInfo
->meClickAction
== presentation::ClickAction_INVISIBLE
||
643 pInfo
->meClickAction
== presentation::ClickAction_STOPPRESENTATION
||
645 ( pInfo
->meEffect
!= presentation::AnimationEffect_NONE
||
646 pInfo
->meTextEffect
!= presentation::AnimationEffect_NONE
)))))
650 mpWindow
->SetPointer(PointerStyle::RefHand
);
653 else if (bImageMapInfo
&&
654 SdDrawDocument::GetHitIMapObject(pObj
, rPos
))
656 /******************************************************
658 ******************************************************/
660 mpWindow
->SetPointer(PointerStyle::RefHand
);
669 * Response of doubleclick
671 void FuDraw::DoubleClick(const MouseEvent
& rMEvt
)
673 sal_uInt16 nHitLog
= sal_uInt16 ( mpWindow
->PixelToLogic(Size(HITPIX
,0)).Width() );
675 if ( mpView
->AreObjectsMarked() )
677 const SdrMarkList
& rMarkList
= mpView
->GetMarkedObjectList();
679 if (rMarkList
.GetMarkCount() == 1)
681 SdrMark
* pMark
= rMarkList
.GetMark(0);
682 SdrObject
* pObj
= pMark
->GetMarkedSdrObj();
684 SdrInventor nInv
= pObj
->GetObjInventor();
685 sal_uInt16 nSdrObjKind
= pObj
->GetObjIdentifier();
687 if (nInv
== SdrInventor::Default
&& nSdrObjKind
== OBJ_OLE2
)
689 DrawDocShell
* pDocSh
= mpDoc
->GetDocSh();
691 if ( !pDocSh
->IsUIActive() )
693 /**********************************************************
694 * activate OLE-object
695 **********************************************************/
696 mpViewShell
->ActivateObject( static_cast<SdrOle2Obj
*>(pObj
), 0);
699 else if (nInv
== SdrInventor::Default
&& nSdrObjKind
== OBJ_GRAF
&& pObj
->IsEmptyPresObj() )
701 mpViewShell
->GetViewFrame()->
702 GetDispatcher()->Execute( SID_INSERT_GRAPHIC
,
703 SfxCallMode::ASYNCHRON
| SfxCallMode::RECORD
);
705 else if ( ( dynamic_cast< const SdrTextObj
*>( pObj
) != nullptr || dynamic_cast< const SdrObjGroup
*>( pObj
) != nullptr ) &&
706 !SD_MOD()->GetWaterCan() &&
707 mpViewShell
->GetFrameView()->IsDoubleClickTextEdit() &&
708 !mpDocSh
->IsReadOnly())
710 SfxUInt16Item
aItem(SID_TEXTEDIT
, 2);
711 mpViewShell
->GetViewFrame()->GetDispatcher()->ExecuteList(
713 SfxCallMode::ASYNCHRON
| SfxCallMode::RECORD
,
716 else if (nInv
== SdrInventor::Default
&& nSdrObjKind
== OBJ_GRUP
)
718 // hit group -> select subobject
720 mpView
->MarkObj(aMDPos
, nHitLog
, rMEvt
.IsShift(), true);
725 mpViewShell
->GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT
, SfxCallMode::ASYNCHRON
| SfxCallMode::RECORD
);
728 bool FuDraw::RequestHelp(const HelpEvent
& rHEvt
)
730 bool bReturn
= false;
732 if (Help::IsBalloonHelpEnabled() || Help::IsQuickHelpEnabled())
736 MouseEvent
aMEvt(mpWindow
->GetPointerPosPixel(), 1, MouseEventModifiers::NONE
, MOUSE_LEFT
);
738 SdrHitKind eHit
= mpView
->PickAnything(aMEvt
, SdrMouseEventKind::BUTTONDOWN
, aVEvt
);
740 SdrObject
* pObj
= aVEvt
.pObj
;
742 if (eHit
!= SdrHitKind::NONE
&& pObj
!= nullptr)
744 Point aPosPixel
= rHEvt
.GetMousePosPixel();
746 bReturn
= SetHelpText(pObj
, aPosPixel
, aVEvt
);
748 if (!bReturn
&& (dynamic_cast< const SdrObjGroup
*>( pObj
) != nullptr || dynamic_cast< const E3dScene
* >(pObj
) != nullptr))
750 // take a glance into the group
751 SdrPageView
* pPV
= nullptr;
753 Point
aPos(mpWindow
->PixelToLogic(mpWindow
->ScreenToOutputPixel(aPosPixel
)));
755 pObj
= mpView
->PickObj(aPos
, mpView
->getHitTolLog(), pPV
, SdrSearchOptions::ALSOONMASTER
| SdrSearchOptions::DEEP
);
757 bReturn
= SetHelpText(pObj
, aPosPixel
, aVEvt
);
764 bReturn
= FuPoor::RequestHelp(rHEvt
);
768 bReturn
= mpView
->RequestHelp(rHEvt
);
773 bool FuDraw::SetHelpText(SdrObject
* pObj
, const Point
& rPosPixel
, const SdrViewEvent
& rVEvt
)
777 Point
aPos(mpWindow
->PixelToLogic(mpWindow
->ScreenToOutputPixel(rPosPixel
)));
779 // URL for IMapObject underneath pointer is help text
780 if ( SdDrawDocument::GetIMapInfo(pObj
) )
782 IMapObject
* pIMapObj
= SdDrawDocument::GetHitIMapObject(pObj
, aPos
);
787 aHelpText
= pIMapObj
->GetAltText();
789 if (aHelpText
.isEmpty())
791 // show url if no name is available
792 aHelpText
= INetURLObject::decode( pIMapObj
->GetURL(), INetURLObject::DecodeMechanism::WithCharset
);
796 else if (rVEvt
.pURLField
)
798 /**************************************************************
800 **************************************************************/
801 OUString aURL
= INetURLObject::decode(rVEvt
.pURLField
->GetURL(), INetURLObject::DecodeMechanism::WithCharset
);
803 SvtSecurityOptions aSecOpt
;
804 if (aSecOpt
.IsOptionSet(SvtSecurityOptions::EOption::CtrlClickHyperlink
))
806 // Hint about Ctrl-click to open hyperlink, but need to detect "Ctrl" key for MacOs
807 vcl::KeyCode
aCode(KEY_SPACE
);
808 vcl::KeyCode
aModifiedCode(KEY_SPACE
, KEY_MOD1
);
809 OUString
aModStr(aModifiedCode
.GetName());
810 aModStr
= aModStr
.replaceFirst(aCode
.GetName(), "");
811 aModStr
= aModStr
.replaceAll("+", "");
813 OUString aCtrlClickHlinkStr
= SdResId(STR_CTRLCLICKHYPERLINK
);
815 aCtrlClickHlinkStr
= aCtrlClickHlinkStr
.replaceAll("%s", aModStr
);
817 aHelpText
= aCtrlClickHlinkStr
+ aURL
;
821 // Hint about just clicking hyperlink
822 aHelpText
= SdResId(STR_CLICKHYPERLINK
) + aURL
;
825 else if (dynamic_cast< GraphicDocShell
*>( mpDocSh
) == nullptr && SdDrawDocument::GetAnimationInfo(pObj
))
827 SdAnimationInfo
* pInfo
= SdDrawDocument::GetAnimationInfo(pObj
);
829 switch (pInfo
->meClickAction
)
831 case presentation::ClickAction_PREVPAGE
:
833 // jump to the prior page
834 aHelpText
= SdResId(STR_CLICK_ACTION_PREVPAGE
);
838 case presentation::ClickAction_NEXTPAGE
:
840 // jump to the next page
841 aHelpText
= SdResId(STR_CLICK_ACTION_NEXTPAGE
);
845 case presentation::ClickAction_FIRSTPAGE
:
847 // jump to the first page
848 aHelpText
= SdResId(STR_CLICK_ACTION_FIRSTPAGE
);
852 case presentation::ClickAction_LASTPAGE
:
854 // jump to the last page
855 aHelpText
= SdResId(STR_CLICK_ACTION_LASTPAGE
);
859 case presentation::ClickAction_BOOKMARK
:
861 // jump to object/page
862 aHelpText
= SdResId(STR_CLICK_ACTION_BOOKMARK
)
864 + INetURLObject::decode( pInfo
->GetBookmark(), INetURLObject::DecodeMechanism::WithCharset
);
868 case presentation::ClickAction_DOCUMENT
:
870 // jump to document (object/page)
871 aHelpText
= SdResId(STR_CLICK_ACTION_DOCUMENT
)
873 + INetURLObject::decode( pInfo
->GetBookmark(), INetURLObject::DecodeMechanism::WithCharset
);
877 case presentation::ClickAction_PROGRAM
:
880 aHelpText
= SdResId(STR_CLICK_ACTION_PROGRAM
)
882 + INetURLObject::decode( pInfo
->GetBookmark(), INetURLObject::DecodeMechanism::WithCharset
);
886 case presentation::ClickAction_MACRO
:
889 aHelpText
= SdResId(STR_CLICK_ACTION_MACRO
) + ": ";
891 if ( SfxApplication::IsXScriptURL( pInfo
->GetBookmark() ) )
893 aHelpText
+= pInfo
->GetBookmark();
897 OUString
sBookmark( pInfo
->GetBookmark() );
899 const OUString s0
{ sBookmark
.getToken( 0, '.', nIdx
) };
900 const OUString s1
{ sBookmark
.getToken( 0, '.', nIdx
) };
901 const OUString s2
{ sBookmark
.getToken( 0, '.', nIdx
) };
902 aHelpText
+= s2
+ "." + s1
+ "." + s0
;
907 case presentation::ClickAction_SOUND
:
910 aHelpText
= SdResId(STR_CLICK_ACTION_SOUND
);
914 case presentation::ClickAction_VERB
:
917 aHelpText
= SdResId(STR_CLICK_ACTION_VERB
);
921 case presentation::ClickAction_STOPPRESENTATION
:
924 aHelpText
= SdResId(STR_CLICK_ACTION_STOPPRESENTATION
);
932 if (!aHelpText
.isEmpty())
935 ::tools::Rectangle aLogicPix
= mpWindow
->LogicToPixel(pObj
->GetLogicRect());
936 ::tools::Rectangle
aScreenRect(mpWindow
->OutputToScreenPixel(aLogicPix
.TopLeft()),
937 mpWindow
->OutputToScreenPixel(aLogicPix
.BottomRight()));
939 if (Help::IsBalloonHelpEnabled())
940 Help::ShowBalloon( static_cast<vcl::Window
*>(mpWindow
), rPosPixel
, aScreenRect
, aHelpText
);
941 else if (Help::IsQuickHelpEnabled())
942 Help::ShowQuickHelp( static_cast<vcl::Window
*>(mpWindow
), aScreenRect
, aHelpText
);
948 /** is called when the current function should be aborted. <p>
949 This is used when a function gets a KEY_ESCAPE but can also
952 @returns true if a active function was aborted
954 bool FuDraw::cancel()
956 bool bReturn
= false;
958 if ( mpView
->IsAction() )
963 else if ( mpView
->IsTextEdit() )
965 mpView
->SdrEndTextEdit();
968 SfxBindings
& rBindings
= mpViewShell
->GetViewFrame()->GetBindings();
969 rBindings
.Invalidate( SID_DEC_INDENT
);
970 rBindings
.Invalidate( SID_INC_INDENT
);
971 rBindings
.Invalidate( SID_PARASPACE_INCREASE
);
972 rBindings
.Invalidate( SID_PARASPACE_DECREASE
);
974 else if ( mpView
->AreObjectsMarked() )
976 const SdrHdlList
& rHdlList
= mpView
->GetHdlList();
977 SdrHdl
* pHdl
= rHdlList
.GetFocusHdl();
981 const_cast<SdrHdlList
&>(rHdlList
).ResetFocusHdl();
988 // Switch to FuSelect.
989 mpViewShell
->GetViewFrame()->GetDispatcher()->Execute(
991 SfxCallMode::ASYNCHRON
| SfxCallMode::RECORD
);
999 } // end of namespace sd
1001 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */