tdf#142415 mouse events not propogated to table control event handlers

handle this with explicit callbacks from the cell widget for those
events

Change-Id: Ie605ca4286afc0fbd321f339fb7963771a303df5
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122072
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
diff --git a/include/svtools/editbrowsebox.hxx b/include/svtools/editbrowsebox.hxx
index a1badb8..4f9f952 100644
--- a/include/svtools/editbrowsebox.hxx
+++ b/include/svtools/editbrowsebox.hxx
@@ -184,13 +184,34 @@ namespace svt
            m_aFocusOutHdl = rHdl;
        }

        void SetMousePressHdl(const Link<const MouseEvent&,void>& rHdl)
        {
            m_aMousePressHdl = rHdl;
        }

        void SetMouseReleaseHdl(const Link<const MouseEvent&,void>& rHdl)
        {
            m_aMouseReleaseHdl = rHdl;
        }

        void SetMouseMoveHdl(const Link<const MouseEvent&,void>& rHdl)
        {
            m_aMouseMoveHdl = rHdl;
        }

    protected:
        DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
        DECL_LINK(FocusInHdl, weld::Widget&, void);
        DECL_LINK(FocusOutHdl, weld::Widget&, void);
        DECL_LINK(MousePressHdl, const MouseEvent&, bool);
        DECL_LINK(MouseReleaseHdl, const MouseEvent&, bool);
        DECL_LINK(MouseMoveHdl, const MouseEvent&, bool);
    private:
        Link<LinkParamNone*,void> m_aFocusInHdl;
        Link<LinkParamNone*,void> m_aFocusOutHdl;
        Link<const MouseEvent&,void> m_aMousePressHdl;
        Link<const MouseEvent&,void> m_aMouseReleaseHdl;
        Link<const MouseEvent&,void> m_aMouseMoveHdl;
    };

    class SVT_DLLPUBLIC EditControlBase : public ControlBase
diff --git a/svtools/source/brwbox/ebbcontrols.cxx b/svtools/source/brwbox/ebbcontrols.cxx
index 3989f6d..e8391175 100644
--- a/svtools/source/brwbox/ebbcontrols.cxx
+++ b/svtools/source/brwbox/ebbcontrols.cxx
@@ -33,6 +33,9 @@ namespace svt
        m_xWidget->connect_key_press(LINK(this, ControlBase, KeyInputHdl));
        m_xWidget->connect_focus_in(LINK(this, ControlBase, FocusInHdl));
        m_xWidget->connect_focus_out(LINK(this, ControlBase, FocusOutHdl));
        m_xWidget->connect_mouse_press(LINK(this, ControlBase, MousePressHdl));
        m_xWidget->connect_mouse_release(LINK(this, ControlBase, MouseReleaseHdl));
        m_xWidget->connect_mouse_move(LINK(this, ControlBase, MouseMoveHdl));
    }

    void ComboBoxControl::dispose()
@@ -120,6 +123,9 @@ namespace svt
        m_xWidget->connect_key_press(LINK(this, ControlBase, KeyInputHdl));
        m_xWidget->connect_focus_in(LINK(this, ControlBase, FocusInHdl));
        m_xWidget->connect_focus_out(LINK(this, ControlBase, FocusOutHdl));
        m_xWidget->connect_mouse_press(LINK(this, ControlBase, MousePressHdl));
        m_xWidget->connect_mouse_release(LINK(this, ControlBase, MouseReleaseHdl));
        m_xWidget->connect_mouse_move(LINK(this, ControlBase, MouseMoveHdl));
    }

    void ListBoxControl::dispose()
@@ -190,6 +196,9 @@ namespace svt
        m_xBox->connect_key_press(LINK(this, ControlBase, KeyInputHdl));
        m_xBox->connect_focus_in(LINK(this, ControlBase, FocusInHdl));
        m_xBox->connect_focus_out(LINK(this, ControlBase, FocusOutHdl));
        m_xBox->connect_mouse_press(LINK(this, ControlBase, MousePressHdl));
        m_xBox->connect_mouse_release(LINK(this, ControlBase, MouseReleaseHdl));
        m_xBox->connect_mouse_move(LINK(this, ControlBase, MouseMoveHdl));
        m_xBox->connect_toggled(LINK(this, CheckBoxControl, OnToggle));
    }

@@ -343,6 +352,9 @@ namespace svt
        m_pEntry->connect_key_press(LINK(this, ControlBase, KeyInputHdl));
        m_pEntry->connect_focus_in(LINK(this, ControlBase, FocusInHdl));
        connect_focus_out(LINK(this, ControlBase, FocusOutHdl));
        m_pEntry->connect_mouse_press(LINK(this, ControlBase, MousePressHdl));
        m_pEntry->connect_mouse_release(LINK(this, ControlBase, MouseReleaseHdl));
        m_pEntry->connect_mouse_move(LINK(this, ControlBase, MouseMoveHdl));
    }

    bool ControlBase::ProcessKey(const KeyEvent& rKEvt)
@@ -367,6 +379,24 @@ namespace svt
        static_cast<BrowserDataWin*>(GetParent())->GetParent()->ChildFocusOut();
    }

    IMPL_LINK(ControlBase, MousePressHdl, const MouseEvent&, rEvent, bool)
    {
        m_aMousePressHdl.Call(rEvent);
        return false;
    }

    IMPL_LINK(ControlBase, MouseReleaseHdl, const MouseEvent&, rEvent, bool)
    {
        m_aMouseReleaseHdl.Call(rEvent);
        return false;
    }

    IMPL_LINK(ControlBase, MouseMoveHdl, const MouseEvent&, rEvent, bool)
    {
        m_aMouseMoveHdl.Call(rEvent);
        return false;
    }

    void EditControlBase::dispose()
    {
        m_pEntry = nullptr;
@@ -641,6 +671,9 @@ namespace svt
        m_xWidget->connect_key_press(LINK(this, ControlBase, KeyInputHdl));
        m_xWidget->connect_focus_in(LINK(this, ControlBase, FocusInHdl));
        m_xWidget->connect_focus_out(LINK(this, ControlBase, FocusOutHdl));
        m_xWidget->connect_mouse_press(LINK(this, ControlBase, MousePressHdl));
        m_xWidget->connect_mouse_release(LINK(this, ControlBase, MouseReleaseHdl));
        m_xWidget->connect_mouse_move(LINK(this, ControlBase, MouseMoveHdl));
        // so any the natural size doesn't have an effect
        m_xWidget->set_size_request(1, 1);
    }
diff --git a/svx/source/fmcomp/gridcell.cxx b/svx/source/fmcomp/gridcell.cxx
index 08ca079..625e34c3 100644
--- a/svx/source/fmcomp/gridcell.cxx
+++ b/svx/source/fmcomp/gridcell.cxx
@@ -3104,6 +3104,9 @@ void FmXGridCell::init()
        pEventWindow->AddEventListener( LINK( this, FmXGridCell, OnWindowEvent ) );
        pEventWindow->SetFocusInHdl(LINK( this, FmXGridCell, OnFocusGained));
        pEventWindow->SetFocusOutHdl(LINK( this, FmXGridCell, OnFocusLost));
        pEventWindow->SetMousePressHdl(LINK( this, FmXGridCell, OnMousePress));
        pEventWindow->SetMouseReleaseHdl(LINK( this, FmXGridCell, OnMouseRelease));
        pEventWindow->SetMouseMoveHdl(LINK( this, FmXGridCell, OnMouseMove));
    }
}

@@ -3377,45 +3380,50 @@ IMPL_LINK_NOARG(FmXGridCell, OnFocusLost, LinkParamNone*, void)
    onFocusLost(aEvent);
}

IMPL_LINK(FmXGridCell, OnMousePress, const MouseEvent&, rEventData, void)
{
    if (!m_aMouseListeners.getLength())
        return;

    awt::MouseEvent aEvent(VCLUnoHelper::createMouseEvent(rEventData, *this));
    m_aMouseListeners.notifyEach(&awt::XMouseListener::mousePressed, aEvent);
}

IMPL_LINK(FmXGridCell, OnMouseRelease, const MouseEvent&, rEventData, void)
{
    if (!m_aMouseListeners.getLength())
        return;

    awt::MouseEvent aEvent(VCLUnoHelper::createMouseEvent(rEventData, *this));
    m_aMouseListeners.notifyEach(&awt::XMouseListener::mouseReleased, aEvent);
}

IMPL_LINK(FmXGridCell, OnMouseMove, const MouseEvent&, rMouseEvent, void)
{
    if ( rMouseEvent.IsEnterWindow() || rMouseEvent.IsLeaveWindow() )
    {
        if ( m_aMouseListeners.getLength() != 0 )
        {
            awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( rMouseEvent, *this ) );
            m_aMouseListeners.notifyEach( rMouseEvent.IsEnterWindow() ? &awt::XMouseListener::mouseEntered: &awt::XMouseListener::mouseExited, aEvent );
        }
    }
    else if ( !rMouseEvent.IsEnterWindow() && !rMouseEvent.IsLeaveWindow() )
    {
        if ( m_aMouseMotionListeners.getLength() != 0 )
        {
            awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( rMouseEvent, *this ) );
            aEvent.ClickCount = 0;
            const bool bSimpleMove = bool( rMouseEvent.GetMode() & MouseEventModifiers::SIMPLEMOVE );
            m_aMouseMotionListeners.notifyEach( bSimpleMove ? &awt::XMouseMotionListener::mouseMoved: &awt::XMouseMotionListener::mouseDragged, aEvent );
        }
    }
}

void FmXGridCell::onWindowEvent(const VclEventId _nEventId, const void* _pEventData)
{
    switch ( _nEventId )
    {
    case VclEventId::WindowMouseButtonDown:
    case VclEventId::WindowMouseButtonUp:
    {
        if ( !m_aMouseListeners.getLength() )
            break;

        const bool bButtonDown = ( _nEventId == VclEventId::WindowMouseButtonDown );

        awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( *static_cast< const ::MouseEvent* >( _pEventData ), *this ) );
        m_aMouseListeners.notifyEach( bButtonDown ? &awt::XMouseListener::mousePressed : &awt::XMouseListener::mouseReleased, aEvent );
    }
    break;
    case VclEventId::WindowMouseMove:
    {
        const MouseEvent& rMouseEvent = *static_cast< const ::MouseEvent* >( _pEventData );
        if ( rMouseEvent.IsEnterWindow() || rMouseEvent.IsLeaveWindow() )
        {
            if ( m_aMouseListeners.getLength() != 0 )
            {
                awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( rMouseEvent, *this ) );
                m_aMouseListeners.notifyEach( rMouseEvent.IsEnterWindow() ? &awt::XMouseListener::mouseEntered: &awt::XMouseListener::mouseExited, aEvent );
            }
        }
        else if ( !rMouseEvent.IsEnterWindow() && !rMouseEvent.IsLeaveWindow() )
        {
            if ( m_aMouseMotionListeners.getLength() != 0 )
            {
                awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( rMouseEvent, *this ) );
                aEvent.ClickCount = 0;
                const bool bSimpleMove = bool( rMouseEvent.GetMode() & MouseEventModifiers::SIMPLEMOVE );
                m_aMouseMotionListeners.notifyEach( bSimpleMove ? &awt::XMouseMotionListener::mouseMoved: &awt::XMouseMotionListener::mouseDragged, aEvent );
            }
        }
    }
    break;
    case VclEventId::WindowKeyInput:
    case VclEventId::WindowKeyUp:
    {
diff --git a/svx/source/inc/gridcell.hxx b/svx/source/inc/gridcell.hxx
index 6aef3de..f006c51 100644
--- a/svx/source/inc/gridcell.hxx
+++ b/svx/source/inc/gridcell.hxx
@@ -785,6 +785,10 @@ private:
    svt::ControlBase* getEventWindow() const;
    DECL_LINK(OnFocusGained, LinkParamNone*, void);
    DECL_LINK(OnFocusLost, LinkParamNone*, void);
    DECL_LINK(OnMousePress, const MouseEvent&, void);
    DECL_LINK(OnMouseRelease, const MouseEvent&, void);
    DECL_LINK(OnMouseMove, const MouseEvent&, void);

    DECL_LINK( OnWindowEvent, VclWindowEvent&, void );
};

diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index f1f8dde..a5d233e 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -9146,6 +9146,13 @@ private:
        pThis->signal_activate();
    }

    virtual void ensureMouseEventWidget() override
    {
        // The GtkEntry is sufficient to get mouse events without an intermediate GtkEventBox
        if (!m_pMouseEventBox)
            m_pMouseEventBox = m_pWidget;
    }

protected:

    virtual void signal_activate()