tdf#146499 Crash to desktop when activating presentation mode

mutex deadlock, regression from
    commit 62efb188668a3296591dcfa3658185e2f982e356
    use comphelper::WeakComponentImplHelper in SlideShowView

Change-Id: I1822d4beffaa44be7f789db4bd0f5a25d1896396
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/127998
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
diff --git a/sd/source/ui/slideshow/slideshowviewimpl.cxx b/sd/source/ui/slideshow/slideshowviewimpl.cxx
index 9666e232..29eca42 100644
--- a/sd/source/ui/slideshow/slideshowviewimpl.cxx
+++ b/sd/source/ui/slideshow/slideshowviewimpl.cxx
@@ -50,53 +50,6 @@ using namespace ::com::sun::star;
namespace sd
{

// SlideShowViewListeners

void SlideShowViewListeners::addListener( const Reference< util::XModifyListener >& _rxListener )
{
    WeakReference< util::XModifyListener > xWeak( _rxListener );
    if( std::find( maListeners.begin(), maListeners.end(), xWeak ) == maListeners.end() )
        maListeners.push_back( xWeak );
}

void SlideShowViewListeners::removeListener( const Reference< util::XModifyListener >& _rxListener )
{
    WeakReference< util::XModifyListener > xWeak( _rxListener );
    ViewListenerVector::iterator aIter( std::find( maListeners.begin(), maListeners.end(), xWeak ) );
    if( aIter != maListeners.end() )
        maListeners.erase( aIter );
}

void SlideShowViewListeners::notify( const lang::EventObject& _rEvent )
{
    ViewListenerVector::iterator aIter( maListeners.begin() );
    while( aIter != maListeners.end() )
    {
        Reference< util::XModifyListener > xListener( *aIter );
        if( xListener.is() )
        {
            xListener->modified( _rEvent );
            ++aIter;
        }
        else
        {
            aIter = maListeners.erase( aIter );
        }
    }
}

void SlideShowViewListeners::disposing( const lang::EventObject& _rEventSource )
{
    for( const auto& rxListener : maListeners )
    {
        Reference< util::XModifyListener > xListener( rxListener );
        if( xListener.is() )
            xListener->disposing( _rEventSource );
    }

    maListeners.clear();
}

void SlideShowViewMouseListeners::notify( const WrappedMouseEvent& rEvent )
{
    forEach(
@@ -223,9 +176,17 @@ void SlideShowView::disposingImpl(std::unique_lock<std::mutex>& rGuard)
    // notify all listeners that _we_ are going down (send a disposing()),
    // then delete listener containers:
    lang::EventObject const evt( static_cast<OWeakObject *>(this) );
    if (maViewListeners.getLength())
    if (!maViewListeners.empty())
    {
        maViewListeners.disposing( evt );
        auto tmp = std::move(maViewListeners);
        rGuard.unlock();
        for( const auto& rxListener : tmp )
        {
            Reference< util::XModifyListener > xListener( rxListener );
            if( xListener.is() )
                xListener->disposing( evt );
        }
        rGuard.lock();
    }
    if (maPaintListeners.getLength())
    {
@@ -366,16 +327,23 @@ void SAL_CALL SlideShowView::addTransformationChangedListener( const Reference< 
{
    std::unique_lock aGuard( m_aMutex );

    if (!m_bDisposed)
        maViewListeners.addListener( xListener );
    if (m_bDisposed)
        return;
    WeakReference< util::XModifyListener > xWeak( xListener );
    if( std::find( maViewListeners.begin(), maViewListeners.end(), xWeak ) == maViewListeners.end() )
        maViewListeners.push_back( xWeak );
}

void SAL_CALL SlideShowView::removeTransformationChangedListener( const Reference< util::XModifyListener >& xListener )
{
    std::unique_lock aGuard( m_aMutex );

    if (!m_bDisposed)
        maViewListeners.removeListener( xListener );
    if (m_bDisposed)
        return;
    WeakReference< util::XModifyListener > xWeak( xListener );
    auto aIter( std::find( maViewListeners.begin(), maViewListeners.end(), xWeak ) );
    if( aIter != maViewListeners.end() )
        maViewListeners.erase( aIter );
}

void SAL_CALL SlideShowView::addPaintListener( const Reference< awt::XPaintListener >& xListener )
@@ -488,16 +456,34 @@ void SAL_CALL SlideShowView::windowResized( const awt::WindowEvent& e )
{
    std::unique_lock aGuard( m_aMutex );

    if (!m_bDisposed)
    if (m_bDisposed)
        return;

    if (!maViewListeners.empty())
    {
        // Change event source, to enable listeners to match event
        // with view
        awt::WindowEvent aEvent( e );
        aEvent.Source = static_cast< ::cppu::OWeakObject* >( this );

        maViewListeners.notify( aEvent );
        updateimpl( aGuard, mpSlideShow ); // warning: clears guard!
        auto aIter( maViewListeners.begin() );
        while( aIter != maViewListeners.end() )
        {
            Reference< util::XModifyListener > xListener( *aIter );
            if( xListener.is() )
            {
                aGuard.unlock();
                xListener->modified( aEvent );
                aGuard.lock();
                ++aIter;
            }
            else
            {
                aIter = maViewListeners.erase( aIter );
            }
        }
    }

    updateimpl( aGuard, mpSlideShow ); // warning: clears guard!
}

void SAL_CALL SlideShowView::windowMoved( const awt::WindowEvent& )
diff --git a/sd/source/ui/slideshow/slideshowviewimpl.hxx b/sd/source/ui/slideshow/slideshowviewimpl.hxx
index e1bee91..b88fd2c 100644
--- a/sd/source/ui/slideshow/slideshowviewimpl.hxx
+++ b/sd/source/ui/slideshow/slideshowviewimpl.hxx
@@ -66,23 +66,6 @@ struct WrappedMouseMotionEvent : public css::lang::EventObject
    css::awt::MouseEvent   maEvent;
};

// SlideShowViewListeners
typedef std::vector< css::uno::WeakReference< css::util::XModifyListener > > ViewListenerVector;
class SlideShowViewListeners final
{
public:

    void    addListener( const css::uno::Reference< css::util::XModifyListener >& _rxListener );
    void    removeListener( const css::uno::Reference< css::util::XModifyListener >& _rxListener );
    /// @throws css::uno::Exception
    void    notify( const css::lang::EventObject& _rEvent );
    void    disposing( const css::lang::EventObject& _rEventSource );
    size_t  getLength() const { return maListeners.size(); }

private:
    ViewListenerVector maListeners;
};

// SlideShowViewPaintListeners
typedef ::comphelper::OInterfaceContainerHelper4< css::awt::XPaintListener >  SlideShowViewPaintListeners;

@@ -181,7 +164,8 @@ private:
    css::uno::Reference< css::awt::XPointer >             mxPointer;
    SlideshowImpl*                          mpSlideShow;
    ShowWindow&                             mrOutputWindow;
    SlideShowViewListeners                  maViewListeners;
    std::vector< css::uno::WeakReference< css::util::XModifyListener > >
                                            maViewListeners;
    SlideShowViewPaintListeners             maPaintListeners;
    SlideShowViewMouseListeners             maMouseListeners;
    SlideShowViewMouseMotionListeners       maMouseMotionListeners;