/* -*- 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: */

V530 The return value of function 'Execute' is required to be utilized.

V530 The return value of function 'Execute' is required to be utilized.

V530 The return value of function 'Execute' is required to be utilized.