Resolves: tdf#143023 explicitly connect to ControlBase focus-[in/out]

instead of listening to the generic vcl::Window/Control focus events.
The thing which really gets/loses focus is now a Widget hosted inside
the ControlBase.

Change-Id: I012d0bea687aa6d5965a4e2f6ce3899bfc629f1b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/120003
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/include/svtools/editbrowsebox.hxx b/include/svtools/editbrowsebox.hxx
index fd111db..159e2ce 100644
--- a/include/svtools/editbrowsebox.hxx
+++ b/include/svtools/editbrowsebox.hxx
@@ -178,12 +178,19 @@ namespace svt
            m_aFocusInHdl = rHdl;
        }

        // chain after the FocusOutHdl
        void SetFocusOutHdl(const Link<LinkParamNone*,void>& rHdl)
        {
            m_aFocusOutHdl = rHdl;
        }

    protected:
        DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
        DECL_LINK(FocusInHdl, weld::Widget&, void);
        DECL_LINK(FocusOutHdl, weld::Widget&, void);
    private:
        Link<LinkParamNone*,void> m_aFocusInHdl;
        Link<LinkParamNone*,void> m_aFocusOutHdl;
    };

    class SVT_DLLPUBLIC EditControlBase : public ControlBase
diff --git a/svtools/source/brwbox/ebbcontrols.cxx b/svtools/source/brwbox/ebbcontrols.cxx
index 3b1819e..32ad1e5 100644
--- a/svtools/source/brwbox/ebbcontrols.cxx
+++ b/svtools/source/brwbox/ebbcontrols.cxx
@@ -362,6 +362,7 @@ namespace svt

    IMPL_LINK_NOARG(ControlBase, FocusOutHdl, weld::Widget&, void)
    {
        m_aFocusOutHdl.Call(nullptr);
        static_cast<BrowserDataWin*>(GetParent())->GetParent()->ChildFocusOut();
    }

diff --git a/svx/source/fmcomp/gridcell.cxx b/svx/source/fmcomp/gridcell.cxx
index 1a2b063..4fb6d1d 100644
--- a/svx/source/fmcomp/gridcell.cxx
+++ b/svx/source/fmcomp/gridcell.cxx
@@ -3098,7 +3098,11 @@ void FmXGridCell::init()
{
    svt::ControlBase* pEventWindow( getEventWindow() );
    if ( pEventWindow )
    {
        pEventWindow->AddEventListener( LINK( this, FmXGridCell, OnWindowEvent ) );
        pEventWindow->SetFocusInHdl(LINK( this, FmXGridCell, OnFocusGained));
        pEventWindow->SetFocusOutHdl(LINK( this, FmXGridCell, OnFocusLost));
    }
}

svt::ControlBase* FmXGridCell::getEventWindow() const
@@ -3319,78 +3323,62 @@ void SAL_CALL FmXGridCell::removeMouseMotionListener( const Reference< awt::XMou
    m_aMouseMotionListeners.removeInterface( _rxListener );
}


void SAL_CALL FmXGridCell::addPaintListener( const Reference< awt::XPaintListener >& )
{
    OSL_FAIL( "FmXGridCell::addPaintListener: not implemented" );
}


void SAL_CALL FmXGridCell::removePaintListener( const Reference< awt::XPaintListener >& )
{
    OSL_FAIL( "FmXGridCell::removePaintListener: not implemented" );
}


IMPL_LINK( FmXGridCell, OnWindowEvent, VclWindowEvent&, _rEvent, void )
{
    ENSURE_OR_THROW( _rEvent.GetWindow(), "illegal window" );
    onWindowEvent( _rEvent.GetId(), *_rEvent.GetWindow(), _rEvent.GetData() );
    onWindowEvent(_rEvent.GetId(), _rEvent.GetData());
}


void FmXGridCell::onFocusGained( const awt::FocusEvent& _rEvent )
{
    checkDisposed(OComponentHelper::rBHelper.bDisposed);
    m_aFocusListeners.notifyEach( &awt::XFocusListener::focusGained, _rEvent );
}


void FmXGridCell::onFocusLost( const awt::FocusEvent& _rEvent )
{
    checkDisposed(OComponentHelper::rBHelper.bDisposed);
    m_aFocusListeners.notifyEach( &awt::XFocusListener::focusLost, _rEvent );
}

IMPL_LINK_NOARG(FmXGridCell, OnFocusGained, LinkParamNone*, void)
{
    if (!m_aFocusListeners.getLength())
        return;

void FmXGridCell::onWindowEvent( const VclEventId _nEventId, const vcl::Window& _rWindow, const void* _pEventData )
    awt::FocusEvent aEvent;
    aEvent.Source = *this;
    aEvent.Temporary = false;

    onFocusGained(aEvent);
}

IMPL_LINK_NOARG(FmXGridCell, OnFocusLost, LinkParamNone*, void)
{
    if (!m_aFocusListeners.getLength())
        return;

    awt::FocusEvent aEvent;
    aEvent.Source = *this;
    aEvent.Temporary = false;

    onFocusLost(aEvent);
}

void FmXGridCell::onWindowEvent(const VclEventId _nEventId, const void* _pEventData)
{
    switch ( _nEventId )
    {
    case VclEventId::ControlGetFocus:
    case VclEventId::WindowGetFocus:
    case VclEventId::ControlLoseFocus:
    case VclEventId::WindowLoseFocus:
    {
        if  (   (   _rWindow.IsCompoundControl()
                &&  (   _nEventId == VclEventId::ControlGetFocus
                    ||  _nEventId == VclEventId::ControlLoseFocus
                    )
                )
            ||  (   !_rWindow.IsCompoundControl()
                &&  (   _nEventId == VclEventId::WindowGetFocus
                    ||  _nEventId == VclEventId::WindowLoseFocus
                    )
                )
            )
        {
            if ( !m_aFocusListeners.getLength() )
                break;

            bool bFocusGained = ( _nEventId == VclEventId::ControlGetFocus ) || ( _nEventId == VclEventId::WindowGetFocus );

            awt::FocusEvent aEvent;
            aEvent.Source = *this;
            aEvent.FocusFlags = static_cast<sal_Int16>(_rWindow.GetGetFocusFlags());
            aEvent.Temporary = false;

            if ( bFocusGained )
                onFocusGained( aEvent );
            else
                onFocusLost( aEvent );
        }
    }
    break;
    case VclEventId::WindowMouseButtonDown:
    case VclEventId::WindowMouseButtonUp:
    {
diff --git a/svx/source/inc/gridcell.hxx b/svx/source/inc/gridcell.hxx
index 355c39e..306dc57 100644
--- a/svx/source/inc/gridcell.hxx
+++ b/svx/source/inc/gridcell.hxx
@@ -772,7 +772,7 @@ public:
        { m_pCellControl->AlignControl(nAlignment);}

protected:
    void onWindowEvent( const VclEventId _nEventId, const vcl::Window& _rWindow, const void* _pEventData );
    void onWindowEvent(const VclEventId _nEventId, const void* _pEventData);

    // default implementations call our focus listeners, don't forget to call them if you override this
    virtual void onFocusGained( const css::awt::FocusEvent& _rEvent );
@@ -780,6 +780,8 @@ protected:

private:
    svt::ControlBase* getEventWindow() const;
    DECL_LINK(OnFocusGained, LinkParamNone*, void);
    DECL_LINK(OnFocusLost, LinkParamNone*, void);
    DECL_LINK( OnWindowEvent, VclWindowEvent&, void );
};