764 lines
27 KiB
C++
764 lines
27 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
#include <editeng/editeng.hxx>
|
|
#include <editeng/outlobj.hxx>
|
|
#include <svx/svdobj.hxx>
|
|
#include <svx/svdoole2.hxx>
|
|
#include <svx/svdouno.hxx>
|
|
#include <svx/ImageMapInfo.hxx>
|
|
#include <sfx2/dispatch.hxx>
|
|
#include <sfx2/viewfrm.hxx>
|
|
#include <vcl/uitest/logger.hxx>
|
|
#include <vcl/uitest/eventdescription.hxx>
|
|
|
|
#include <sc.hrc>
|
|
#include <fudraw.hxx>
|
|
#include <futext.hxx>
|
|
#include <tabvwsh.hxx>
|
|
#include <drwlayer.hxx>
|
|
#include <userdat.hxx>
|
|
#include <docsh.hxx>
|
|
#include <drawview.hxx>
|
|
#include <comphelper/lok.hxx>
|
|
#include <com/sun/star/embed/EmbedVerbs.hpp>
|
|
|
|
namespace
|
|
{
|
|
|
|
void collectUIInformation( const OUString& aevent )
|
|
{
|
|
EventDescription aDescription;
|
|
aDescription.aID = "grid_window";
|
|
aDescription.aParameters = {{ aevent , ""}};
|
|
aDescription.aAction = "COMMENT";
|
|
aDescription.aParent = "MainWindow";
|
|
aDescription.aKeyWord = "ScGridWinUIObject";
|
|
UITestLogger::getInstance().logEvent(aDescription);
|
|
}
|
|
|
|
}
|
|
|
|
// base class for draw module specific functions
|
|
FuDraw::FuDraw(ScTabViewShell& rViewSh, vcl::Window* pWin, ScDrawView* pViewP,
|
|
SdrModel* pDoc, const SfxRequest& rReq)
|
|
: FuPoor(rViewSh, pWin, pViewP, pDoc, rReq)
|
|
, aNewPointer(PointerStyle::Arrow)
|
|
, aOldPointer(PointerStyle::Arrow)
|
|
{
|
|
}
|
|
|
|
FuDraw::~FuDraw()
|
|
{
|
|
}
|
|
|
|
void FuDraw::DoModifiers(const MouseEvent& rMEvt)
|
|
{
|
|
// Shift = Ortho and AngleSnap
|
|
// Control = Snap (Toggle)
|
|
// Alt = centric
|
|
|
|
bool bShift = rMEvt.IsShift();
|
|
bool bAlt = rMEvt.IsMod2();
|
|
|
|
bool bOrtho = bShift;
|
|
bool bAngleSnap = bShift;
|
|
bool bCenter = bAlt;
|
|
|
|
// #i33136#
|
|
if(doConstructOrthogonal())
|
|
{
|
|
bOrtho = !bShift;
|
|
}
|
|
|
|
if (pView->IsOrtho() != bOrtho)
|
|
pView->SetOrtho(bOrtho);
|
|
if (pView->IsAngleSnapEnabled() != bAngleSnap)
|
|
pView->SetAngleSnapEnabled(bAngleSnap);
|
|
|
|
if (pView->IsCreate1stPointAsCenter() != bCenter)
|
|
pView->SetCreate1stPointAsCenter(bCenter);
|
|
if (pView->IsResizeAtCenter() != bCenter)
|
|
pView->SetResizeAtCenter(bCenter);
|
|
|
|
}
|
|
|
|
void FuDraw::ResetModifiers()
|
|
{
|
|
if (!pView)
|
|
return;
|
|
|
|
ScViewData& rViewData = rViewShell.GetViewData();
|
|
const ScViewOptions& rOpt = rViewData.GetOptions();
|
|
const ScGridOptions& rGrid = rOpt.GetGridOptions();
|
|
bool bGridOpt = rGrid.GetUseGridSnap();
|
|
|
|
if (pView->IsOrtho())
|
|
pView->SetOrtho(false);
|
|
if (pView->IsAngleSnapEnabled())
|
|
pView->SetAngleSnapEnabled(false);
|
|
|
|
if (pView->IsGridSnap() != bGridOpt)
|
|
pView->SetGridSnap(bGridOpt);
|
|
if (pView->IsSnapEnabled() != bGridOpt)
|
|
pView->SetSnapEnabled(bGridOpt);
|
|
|
|
if (pView->IsCreate1stPointAsCenter())
|
|
pView->SetCreate1stPointAsCenter(false);
|
|
if (pView->IsResizeAtCenter())
|
|
pView->SetResizeAtCenter(false);
|
|
}
|
|
|
|
bool FuDraw::MouseButtonDown(const MouseEvent& rMEvt)
|
|
{
|
|
// remember button state for creation of own MouseEvents
|
|
SetMouseButtonCode(rMEvt.GetButtons());
|
|
|
|
DoModifiers( rMEvt );
|
|
return false;
|
|
}
|
|
|
|
bool FuDraw::MouseMove(const MouseEvent& rMEvt)
|
|
{
|
|
// evaluate modifiers only if in a drawing layer action
|
|
// (don't interfere with keyboard shortcut handling)
|
|
if (pView->IsAction())
|
|
DoModifiers( rMEvt );
|
|
|
|
return false;
|
|
}
|
|
|
|
bool FuDraw::MouseButtonUp(const MouseEvent& rMEvt)
|
|
{
|
|
// remember button state for creation of own MouseEvents
|
|
SetMouseButtonCode(rMEvt.GetButtons());
|
|
|
|
ResetModifiers();
|
|
return false;
|
|
}
|
|
|
|
// Process Keyboard events. Return true if an event is being handled
|
|
static bool lcl_KeyEditMode( SdrObject* pObj, ScTabViewShell& rViewShell, const KeyEvent* pInitialKey )
|
|
{
|
|
bool bReturn = false;
|
|
if ( DynCastSdrTextObj( pObj) != nullptr && dynamic_cast<const SdrUnoObj*>( pObj) == nullptr )
|
|
{
|
|
assert(pObj);
|
|
// start text edit - like FuSelection::MouseButtonUp,
|
|
// but with bCursorToEnd instead of mouse position
|
|
|
|
OutlinerParaObject* pOPO = pObj->GetOutlinerParaObject();
|
|
bool bVertical = ( pOPO && pOPO->IsEffectivelyVertical() );
|
|
sal_uInt16 nTextSlotId = bVertical ? SID_DRAW_TEXT_VERTICAL : SID_DRAW_TEXT;
|
|
|
|
// don't switch shells if text shell is already active
|
|
FuPoor* pPoor = rViewShell.GetViewData().GetView()->GetDrawFuncPtr();
|
|
if ( !pPoor || pPoor->GetSlotID() != nTextSlotId )
|
|
{
|
|
rViewShell.GetViewData().GetDispatcher().
|
|
Execute(nTextSlotId, SfxCallMode::SYNCHRON | SfxCallMode::RECORD);
|
|
}
|
|
|
|
// get the resulting FuText and set in edit mode
|
|
pPoor = rViewShell.GetViewData().GetView()->GetDrawFuncPtr();
|
|
if ( pPoor && pPoor->GetSlotID() == nTextSlotId ) // no RTTI
|
|
{
|
|
FuText* pText = static_cast<FuText*>(pPoor);
|
|
pText->SetInEditMode( pObj, nullptr, true, pInitialKey );
|
|
//! set cursor to end of text
|
|
}
|
|
bReturn = true;
|
|
}
|
|
return bReturn;
|
|
}
|
|
|
|
bool FuDraw::KeyInput(const KeyEvent& rKEvt)
|
|
{
|
|
bool bReturn = false;
|
|
ScViewData& rViewData = rViewShell.GetViewData();
|
|
|
|
const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
|
|
switch ( rKEvt.GetKeyCode().GetCode() )
|
|
{
|
|
case KEY_ESCAPE:
|
|
if ( rViewShell.IsDrawTextShell() || aSfxRequest.GetSlot() == SID_DRAW_NOTEEDIT )
|
|
{
|
|
collectUIInformation(u"CLOSE"_ustr);
|
|
// if object selected -> normal draw-shell, else turn off drawing
|
|
rViewData.GetDispatcher().Execute(aSfxRequest.GetSlot(), SfxCallMode::SLOT | SfxCallMode::RECORD);
|
|
bReturn = true;
|
|
}
|
|
else if ( rViewShell.IsDrawSelMode() )
|
|
{
|
|
pView->UnmarkAll();
|
|
rViewData.GetDispatcher().Execute(SID_OBJECT_SELECT, SfxCallMode::SLOT | SfxCallMode::RECORD);
|
|
bReturn = true;
|
|
}
|
|
else if ( rMarkList.GetMarkCount() != 0 )
|
|
{
|
|
// III
|
|
SdrHdlList& rHdlList = const_cast< SdrHdlList& >( pView->GetHdlList() );
|
|
if( rHdlList.GetFocusHdl() )
|
|
rHdlList.ResetFocusHdl();
|
|
else
|
|
pView->UnmarkAll();
|
|
|
|
// while bezier editing, object is selected
|
|
if (rMarkList.GetMarkCount() == 0)
|
|
rViewShell.SetDrawShell( false );
|
|
|
|
bReturn = true;
|
|
}
|
|
break;
|
|
|
|
case KEY_DELETE: //! via accelerator
|
|
pView->DeleteMarked();
|
|
bReturn = true;
|
|
break;
|
|
|
|
case KEY_RETURN:
|
|
{
|
|
if( rKEvt.GetKeyCode().GetModifier() == 0 )
|
|
{
|
|
// activate OLE object on RETURN for selected object
|
|
// put selected text object in edit mode
|
|
if( !pView->IsTextEdit() && 1 == rMarkList.GetMarkCount() )
|
|
{
|
|
bool bOle = rViewShell.GetViewFrame().GetFrame().IsInPlace();
|
|
SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
|
|
auto pOleObj = dynamic_cast<SdrOle2Obj*>(pObj);
|
|
if( pOleObj && !bOle )
|
|
{
|
|
rViewShell.ActivateObject(pOleObj, css::embed::EmbedVerbs::MS_OLEVERB_PRIMARY);
|
|
|
|
// consumed
|
|
bReturn = true;
|
|
}
|
|
else if ( lcl_KeyEditMode( pObj, rViewShell, nullptr ) ) // start text edit for suitable object
|
|
bReturn = true;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case KEY_F2:
|
|
{
|
|
if( rKEvt.GetKeyCode().GetModifier() == 0 )
|
|
{
|
|
// put selected text object in edit mode
|
|
// (this is not SID_SETINPUTMODE, but F2 hardcoded, like in Writer)
|
|
if( !pView->IsTextEdit() && 1 == rMarkList.GetMarkCount() )
|
|
{
|
|
SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
|
|
bool isMobilePhone = comphelper::LibreOfficeKit::isActive() && rViewShell.isLOKMobilePhone();
|
|
// Double tapping on charts on phone may result in activating the edit mode which is not wanted.
|
|
// It happens due to the delay of selection message of the object from kit to javascript
|
|
// in that case F2 is sent instead of double click
|
|
if (isMobilePhone && ScDocument::IsChart(pObj))
|
|
{
|
|
rViewShell.ActivateObject(static_cast<SdrOle2Obj*>(pObj), css::embed::EmbedVerbs::MS_OLEVERB_PRIMARY);
|
|
break;
|
|
}
|
|
if ( lcl_KeyEditMode( pObj, rViewShell, nullptr ) ) // start text edit for suitable object
|
|
bReturn = true;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case KEY_TAB:
|
|
{
|
|
// in calc do NOT start draw object selection using TAB/SHIFT-TAB when
|
|
// there is not yet an object selected
|
|
if(rMarkList.GetMarkCount() != 0)
|
|
{
|
|
vcl::KeyCode aCode = rKEvt.GetKeyCode();
|
|
|
|
if ( !aCode.IsMod1() && !aCode.IsMod2() )
|
|
{
|
|
// changeover to the next object
|
|
if(!pView->MarkNextObj( !aCode.IsShift() ))
|
|
{
|
|
//If there is only one object, don't do the UnmarkAllObj() & MarkNextObj().
|
|
if ( pView->HasMultipleMarkableObjects() && pView->HasMarkableObj() )
|
|
{
|
|
// No next object: go over open end and
|
|
// get first from the other side
|
|
pView->UnmarkAllObj();
|
|
pView->MarkNextObj(!aCode.IsShift());
|
|
}
|
|
}
|
|
|
|
// II
|
|
if(rMarkList.GetMarkCount() != 0)
|
|
pView->MakeVisible(pView->GetAllMarkedRect(), *pWindow);
|
|
|
|
bReturn = true;
|
|
}
|
|
|
|
// handle Mod1 and Mod2 to get travelling running on different systems
|
|
if(rKEvt.GetKeyCode().IsMod1() || rKEvt.GetKeyCode().IsMod2())
|
|
{
|
|
// II do something with a selected handle?
|
|
const SdrHdlList& rHdlList = pView->GetHdlList();
|
|
bool bForward(!rKEvt.GetKeyCode().IsShift());
|
|
|
|
const_cast<SdrHdlList&>(rHdlList).TravelFocusHdl(bForward);
|
|
|
|
// guarantee visibility of focused handle
|
|
SdrHdl* pHdl = rHdlList.GetFocusHdl();
|
|
|
|
if(pHdl)
|
|
{
|
|
Point aHdlPosition(pHdl->GetPos());
|
|
tools::Rectangle aVisRect(aHdlPosition - Point(100, 100), Size(200, 200));
|
|
pView->MakeVisible(aVisRect, *pWindow);
|
|
}
|
|
|
|
// consumed
|
|
bReturn = true;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case KEY_END:
|
|
{
|
|
// in calc do NOT select the last draw object when
|
|
// there is not yet an object selected
|
|
if(rMarkList.GetMarkCount() != 0)
|
|
{
|
|
vcl::KeyCode aCode = rKEvt.GetKeyCode();
|
|
|
|
if ( aCode.IsMod1() )
|
|
{
|
|
// mark last object
|
|
pView->UnmarkAllObj();
|
|
pView->MarkNextObj();
|
|
|
|
// II
|
|
if(rMarkList.GetMarkCount() != 0)
|
|
pView->MakeVisible(pView->GetAllMarkedRect(), *pWindow);
|
|
|
|
bReturn = true;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case KEY_HOME:
|
|
{
|
|
// in calc do NOT select the first draw object when
|
|
// there is not yet an object selected
|
|
if(rMarkList.GetMarkCount() != 0)
|
|
{
|
|
vcl::KeyCode aCode = rKEvt.GetKeyCode();
|
|
|
|
if ( aCode.IsMod1() )
|
|
{
|
|
// mark first object
|
|
pView->UnmarkAllObj();
|
|
pView->MarkNextObj(true);
|
|
|
|
// II
|
|
if(rMarkList.GetMarkCount() != 0)
|
|
pView->MakeVisible(pView->GetAllMarkedRect(), *pWindow);
|
|
|
|
bReturn = true;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case KEY_UP:
|
|
case KEY_DOWN:
|
|
case KEY_LEFT:
|
|
case KEY_RIGHT:
|
|
{
|
|
// in calc do cursor travelling of draw objects only when
|
|
// there is an object selected yet
|
|
if(rMarkList.GetMarkCount() != 0)
|
|
{
|
|
|
|
if(rMarkList.GetMarkCount() == 1)
|
|
{
|
|
// disable cursor travelling on note objects as the tail connector position
|
|
// must not move.
|
|
SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
|
|
if( ScDrawLayer::IsNoteCaption( pObj ) )
|
|
break;
|
|
}
|
|
|
|
tools::Long nX = 0;
|
|
tools::Long nY = 0;
|
|
sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode();
|
|
|
|
if (nCode == KEY_UP)
|
|
{
|
|
// scroll up
|
|
nX = 0;
|
|
nY =-1;
|
|
}
|
|
else if (nCode == KEY_DOWN)
|
|
{
|
|
// scroll down
|
|
nX = 0;
|
|
nY = 1;
|
|
}
|
|
else if (nCode == KEY_LEFT)
|
|
{
|
|
// scroll left
|
|
nX =-1;
|
|
nY = 0;
|
|
}
|
|
else if (nCode == KEY_RIGHT)
|
|
{
|
|
// scroll right
|
|
nX = 1;
|
|
nY = 0;
|
|
}
|
|
|
|
bool bReadOnly = rViewData.GetDocShell()->IsReadOnly();
|
|
|
|
if(!rKEvt.GetKeyCode().IsMod1() && !bReadOnly)
|
|
{
|
|
if(rKEvt.GetKeyCode().IsMod2())
|
|
{
|
|
// move in 1 pixel distance
|
|
Size aLogicSizeOnePixel = pWindow ? pWindow->PixelToLogic(Size(1,1)) : Size(100, 100);
|
|
nX *= aLogicSizeOnePixel.Width();
|
|
nY *= aLogicSizeOnePixel.Height();
|
|
}
|
|
else if(rKEvt.GetKeyCode().IsShift()) // #i121236# Support for shift key in calc
|
|
{
|
|
nX *= 1000;
|
|
nY *= 1000;
|
|
}
|
|
else
|
|
{
|
|
// old, fixed move distance
|
|
nX *= 100;
|
|
nY *= 100;
|
|
}
|
|
|
|
// is there a movement to do?
|
|
if(0 != nX || 0 != nY)
|
|
{
|
|
// II
|
|
const SdrHdlList& rHdlList = pView->GetHdlList();
|
|
SdrHdl* pHdl = rHdlList.GetFocusHdl();
|
|
|
|
if(nullptr == pHdl)
|
|
{
|
|
// only take action when move is allowed
|
|
if(pView->IsMoveAllowed())
|
|
{
|
|
// restrict movement to WorkArea
|
|
const tools::Rectangle& rWorkArea = pView->GetWorkArea();
|
|
|
|
if(!rWorkArea.IsEmpty())
|
|
{
|
|
tools::Rectangle aMarkRect(pView->GetMarkedObjRect());
|
|
aMarkRect.Move(nX, nY);
|
|
|
|
if(!aMarkRect.Contains(rWorkArea))
|
|
{
|
|
if(aMarkRect.Left() < rWorkArea.Left())
|
|
{
|
|
nX += rWorkArea.Left() - aMarkRect.Left();
|
|
}
|
|
|
|
if(aMarkRect.Right() > rWorkArea.Right())
|
|
{
|
|
nX -= aMarkRect.Right() - rWorkArea.Right();
|
|
}
|
|
|
|
if(aMarkRect.Top() < rWorkArea.Top())
|
|
{
|
|
nY += rWorkArea.Top() - aMarkRect.Top();
|
|
}
|
|
|
|
if(aMarkRect.Bottom() > rWorkArea.Bottom())
|
|
{
|
|
nY -= aMarkRect.Bottom() - rWorkArea.Bottom();
|
|
}
|
|
}
|
|
}
|
|
|
|
// now move the selected draw objects
|
|
pView->MoveAllMarked(Size(nX, nY));
|
|
|
|
// II
|
|
pView->MakeVisible(pView->GetAllMarkedRect(), *pWindow);
|
|
|
|
bReturn = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// move handle with index nHandleIndex
|
|
if (nX || nY)
|
|
{
|
|
// now move the Handle (nX, nY)
|
|
Point aStartPoint(pHdl->GetPos());
|
|
Point aEndPoint(pHdl->GetPos() + Point(nX, nY));
|
|
const SdrDragStat& rDragStat = pView->GetDragStat();
|
|
|
|
// start dragging
|
|
pView->BegDragObj(aStartPoint, nullptr, pHdl, 0);
|
|
|
|
if(pView->IsDragObj())
|
|
{
|
|
bool bWasNoSnap = rDragStat.IsNoSnap();
|
|
bool bWasSnapEnabled = pView->IsSnapEnabled();
|
|
|
|
// switch snapping off
|
|
if(!bWasNoSnap)
|
|
const_cast<SdrDragStat&>(rDragStat).SetNoSnap();
|
|
if(bWasSnapEnabled)
|
|
pView->SetSnapEnabled(false);
|
|
|
|
pView->MovAction(aEndPoint);
|
|
pView->EndDragObj();
|
|
|
|
// restore snap
|
|
if(!bWasNoSnap)
|
|
const_cast<SdrDragStat&>(rDragStat).SetNoSnap(bWasNoSnap);
|
|
if(bWasSnapEnabled)
|
|
pView->SetSnapEnabled(bWasSnapEnabled);
|
|
}
|
|
|
|
// make moved handle visible
|
|
tools::Rectangle aVisRect(aEndPoint - Point(100, 100), Size(200, 200));
|
|
pView->MakeVisible(aVisRect, *pWindow);
|
|
|
|
bReturn = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case KEY_SPACE:
|
|
{
|
|
// in calc do only something when draw objects are selected
|
|
if(rMarkList.GetMarkCount() != 0)
|
|
{
|
|
const SdrHdlList& rHdlList = pView->GetHdlList();
|
|
SdrHdl* pHdl = rHdlList.GetFocusHdl();
|
|
|
|
if(pHdl)
|
|
{
|
|
if(pHdl->GetKind() == SdrHdlKind::Poly)
|
|
{
|
|
// rescue ID of point with focus
|
|
sal_uInt32 nPol(pHdl->GetPolyNum());
|
|
sal_uInt32 nPnt(pHdl->GetPointNum());
|
|
|
|
if(pView->IsPointMarked(*pHdl))
|
|
{
|
|
if(rKEvt.GetKeyCode().IsShift())
|
|
{
|
|
pView->UnmarkPoint(*pHdl);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(!rKEvt.GetKeyCode().IsShift())
|
|
{
|
|
pView->UnmarkAllPoints();
|
|
}
|
|
|
|
pView->MarkPoint(*pHdl);
|
|
}
|
|
|
|
if(nullptr == rHdlList.GetFocusHdl())
|
|
{
|
|
// restore point with focus
|
|
SdrHdl* pNewOne = nullptr;
|
|
|
|
for(size_t a = 0; !pNewOne && a < rHdlList.GetHdlCount(); ++a)
|
|
{
|
|
SdrHdl* pAct = rHdlList.GetHdl(a);
|
|
|
|
if(pAct
|
|
&& pAct->GetKind() == SdrHdlKind::Poly
|
|
&& pAct->GetPolyNum() == nPol
|
|
&& pAct->GetPointNum() == nPnt)
|
|
{
|
|
pNewOne = pAct;
|
|
}
|
|
}
|
|
|
|
if(pNewOne)
|
|
{
|
|
const_cast<SdrHdlList&>(rHdlList).SetFocusHdl(pNewOne);
|
|
}
|
|
}
|
|
|
|
bReturn = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (!bReturn)
|
|
{
|
|
bReturn = FuPoor::KeyInput(rKEvt);
|
|
}
|
|
|
|
if (!bReturn)
|
|
{
|
|
// allow direct typing into a selected text object
|
|
|
|
if( !pView->IsTextEdit() && 1 == rMarkList.GetMarkCount() && EditEngine::IsSimpleCharInput(rKEvt) )
|
|
{
|
|
SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
|
|
|
|
// start text edit for suitable object, pass key event to OutlinerView
|
|
if ( lcl_KeyEditMode( pObj, rViewShell, &rKEvt ) )
|
|
bReturn = true;
|
|
}
|
|
}
|
|
|
|
return bReturn;
|
|
}
|
|
|
|
// toggle mouse-pointer
|
|
static bool lcl_UrlHit( const SdrView* pView, const Point& rPosPixel, const vcl::Window* pWindow )
|
|
{
|
|
SdrViewEvent aVEvt;
|
|
MouseEvent aMEvt( rPosPixel, 1, MouseEventModifiers::NONE, MOUSE_LEFT );
|
|
SdrHitKind eHit = pView->PickAnything( aMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt );
|
|
|
|
if (eHit != SdrHitKind::NONE && aVEvt.mpObj != nullptr)
|
|
{
|
|
if ( SvxIMapInfo::GetIMapInfo(aVEvt.mpObj) && SvxIMapInfo::GetHitIMapObject(
|
|
aVEvt.mpObj, pWindow->PixelToLogic(rPosPixel), pWindow->GetOutDev() ) )
|
|
return true;
|
|
|
|
if (aVEvt.meEvent == SdrEventKind::ExecuteUrl)
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void FuDraw::ForcePointer(const MouseEvent* pMEvt)
|
|
{
|
|
if ( pView->IsAction() )
|
|
return;
|
|
|
|
Point aPosPixel = pWindow->GetPointerPosPixel();
|
|
bool bAlt = pMEvt && pMEvt->IsMod2();
|
|
Point aPnt = pWindow->PixelToLogic( aPosPixel );
|
|
SdrHdl* pHdl = pView->PickHandle(aPnt);
|
|
SdrPageView* pPV;
|
|
SdrObject* pMacroPickObj;
|
|
|
|
ScMacroInfo* pInfo = nullptr;
|
|
SdrObject* pObj = pView->PickObj(aPnt, pView->getHitTolLog(), pPV, SdrSearchOptions::ALSOONMASTER);
|
|
if (pObj)
|
|
{
|
|
if ( pObj->IsGroupObject() )
|
|
{
|
|
SdrObject* pHit = pView->PickObj(aMDPos, pView->getHitTolLog(), pPV, SdrSearchOptions::DEEP);
|
|
if (pHit)
|
|
pObj = pHit;
|
|
}
|
|
pInfo = ScDrawLayer::GetMacroInfo( pObj );
|
|
}
|
|
|
|
if ( pView->IsTextEdit() )
|
|
{
|
|
rViewShell.SetActivePointer(PointerStyle::Text); // can't be ?
|
|
}
|
|
else if ( pHdl )
|
|
{
|
|
rViewShell.SetActivePointer(
|
|
pView->GetPreferredPointer( aPnt, pWindow->GetOutDev() ) );
|
|
}
|
|
else if ( pView->IsMarkedHit(aPnt) )
|
|
{
|
|
rViewShell.SetActivePointer( PointerStyle::Move );
|
|
}
|
|
else if ( !bAlt && ( !pMEvt || !pMEvt->GetButtons() )
|
|
&& lcl_UrlHit( pView, aPosPixel, pWindow ) )
|
|
{
|
|
// could be suppressed with ALT
|
|
pWindow->SetPointer( PointerStyle::RefHand ); // Text-URL / ImageMap
|
|
}
|
|
else if ( !bAlt && (pMacroPickObj = pView->PickObj(aPnt, pView->getHitTolLog(), pPV, SdrSearchOptions::PICKMACRO)) )
|
|
{
|
|
// could be suppressed with ALT
|
|
SdrObjMacroHitRec aHitRec; //! something missing ????
|
|
rViewShell.SetActivePointer(pMacroPickObj->GetMacroPointer(aHitRec));
|
|
}
|
|
else if ( !bAlt && pInfo && (!pInfo->GetMacro().isEmpty() || !pObj->getHyperlink().isEmpty()) )
|
|
pWindow->SetPointer( PointerStyle::RefHand );
|
|
else if ( IsDetectiveHit( aPnt ) )
|
|
rViewShell.SetActivePointer( PointerStyle::Detective );
|
|
else
|
|
{
|
|
const bool bIsThemed = rViewShell.GetViewData().IsThemedCursor();
|
|
rViewShell.SetActivePointer( bIsThemed ? PointerStyle::FatCross : PointerStyle::Arrow ); //! in Gridwin?
|
|
}
|
|
}
|
|
|
|
bool FuDraw::IsEditingANote() const
|
|
{
|
|
const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
|
|
const size_t backval=rMarkList.GetMarkCount();
|
|
for (size_t nlv1=0; nlv1<backval; ++nlv1)
|
|
{
|
|
SdrObject* pObj = rMarkList.GetMark( nlv1 )->GetMarkedSdrObj();
|
|
if ( ScDrawLayer::IsNoteCaption( pObj ) )
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool FuDraw::IsSizingOrMovingNote( const MouseEvent& rMEvt ) const
|
|
{
|
|
bool bIsSizingOrMoving = false;
|
|
if ( rMEvt.IsLeft() )
|
|
{
|
|
const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
|
|
if(rMarkList.GetMarkCount() == 1)
|
|
{
|
|
SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
|
|
if ( ScDrawLayer::IsNoteCaption( pObj ) )
|
|
{
|
|
Point aMPos = pWindow->PixelToLogic( rMEvt.GetPosPixel() );
|
|
bIsSizingOrMoving =
|
|
pView->PickHandle( aMPos ) || // handles to resize the note
|
|
pView->IsTextEditFrameHit( aMPos ); // frame for moving the note
|
|
}
|
|
}
|
|
}
|
|
return bIsSizingOrMoving;
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|