    /* -*- 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 <osl/diagnose.h>
    #include "WinClipboard.hxx"
    #include <com/sun/star/datatransfer/clipboard/ClipboardEvent.hpp>
    #include <com/sun/star/lang/DisposedException.hpp>
    #include <com/sun/star/lang/IllegalArgumentException.hpp>
    #include <cppuhelper/supportsservice.hxx>
    #include "WinClipbImpl.hxx"

    using namespace osl;
    using namespace std;
    using namespace cppu;

    using namespace com::sun::star::uno;
    using namespace com::sun::star::datatransfer;
    using namespace com::sun::star::datatransfer::clipboard;
    using namespace com::sun::star::lang;

    #define WINCLIPBOARD_IMPL_NAME  "com.sun.star.datatransfer.clipboard.ClipboardW32"

    namespace
    {
        Sequence< OUString > WinClipboard_getSupportedServiceNames()
        {
            Sequence< OUString > aRet { "com.sun.star.datatransfer.clipboard.SystemClipboard" };
            return aRet;
        }
    }

    /*XEventListener,*/
    CWinClipboard::CWinClipboard( const Reference< XComponentContext >& rxContext, const OUString& aClipboardName ) :
        WeakComponentImplHelper< XSystemClipboard, XFlushableClipboard, XServiceInfo >( m_aCbListenerMutex ),
        m_xContext( rxContext )
    {
        m_pImpl.reset( new CWinClipbImpl( aClipboardName, this ) );
    }

    // XClipboard

    // to avoid unnecessary traffic we check first if there is a clipboard
    // content which was set via setContent, in this case we don't need
    // to query the content from the clipboard, create a new wrapper object
    // and so on, we simply return the original XTransferable instead of our
    // DOTransferable

    Reference< XTransferable > SAL_CALL CWinClipboard::getContents( )
    {
        MutexGuard aGuard( m_aMutex );

        if ( rBHelper.bDisposed )
            throw DisposedException("object is already disposed",
                                     static_cast< XClipboardEx* >( this ) );

        if ( nullptr != m_pImpl.get( ) )
            return m_pImpl->getContents( );

        return Reference< XTransferable >( );
    }

    void SAL_CALL CWinClipboard::setContents( const Reference< XTransferable >& xTransferable,
                                              const Reference< XClipboardOwner >& xClipboardOwner )
    {
        MutexGuard aGuard( m_aMutex );

        if ( rBHelper.bDisposed )
            throw DisposedException("object is already disposed",
                                     static_cast< XClipboardEx* >( this ) );

        if ( nullptr != m_pImpl.get( ) )
            m_pImpl->setContents( xTransferable, xClipboardOwner );
    }

    OUString SAL_CALL CWinClipboard::getName(  )
    {
        if ( rBHelper.bDisposed )
            throw DisposedException("object is already disposed",
                                     static_cast< XClipboardEx* >( this ) );

        if ( nullptr != m_pImpl.get( ) )
            return m_pImpl->getName( );

        return OUString();
    }

    // XFlushableClipboard

    void SAL_CALL CWinClipboard::flushClipboard( )
    {
        MutexGuard aGuard( m_aMutex );

        if ( rBHelper.bDisposed )
            throw DisposedException("object is already disposed",
                                     static_cast< XClipboardEx* >( this ) );

        if ( nullptr != m_pImpl.get( ) )
            m_pImpl->flushClipboard( );
    }

    // XClipboardEx

    sal_Int8 SAL_CALL CWinClipboard::getRenderingCapabilities(  )
    {
        if ( rBHelper.bDisposed )
            throw DisposedException("object is already disposed",
                                     static_cast< XClipboardEx* >( this ) );

        if ( nullptr != m_pImpl.get( ) )
            return CWinClipbImpl::getRenderingCapabilities( );

        return 0;
    }

    // XClipboardNotifier

    void SAL_CALL CWinClipboard::addClipboardListener( const Reference< XClipboardListener >& listener )
    {
        if ( rBHelper.bDisposed )
            throw DisposedException("object is already disposed",
                                     static_cast< XClipboardEx* >( this ) );

        // check input parameter
        if ( !listener.is( ) )
            throw IllegalArgumentException("empty reference",
                                            static_cast< XClipboardEx* >( this ),
                                            1 );

        rBHelper.aLC.addInterface( cppu::UnoType<decltype(listener)>::get(), listener );
    }

    void SAL_CALL CWinClipboard::removeClipboardListener( const Reference< XClipboardListener >& listener )
    {
        if ( rBHelper.bDisposed )
            throw DisposedException("object is already disposed",
                                     static_cast< XClipboardEx* >( this ) );

        // check input parameter
        if ( !listener.is( ) )
            throw IllegalArgumentException("empty reference",
                                            static_cast< XClipboardEx* >( this ),
                                            1 );

        rBHelper.aLC.removeInterface( cppu::UnoType<decltype(listener)>::get(), listener );
    }

    void CWinClipboard::notifyAllClipboardListener( )
    {
        if ( !rBHelper.bDisposed )
        {
            ClearableMutexGuard aGuard( rBHelper.rMutex );
            if ( !rBHelper.bDisposed )
            {
                aGuard.clear( );

                OInterfaceContainerHelper* pICHelper = rBHelper.aLC.getContainer(
                    cppu::UnoType<XClipboardListener>::get());

                if ( pICHelper )
                {
                    try
                    {
                        OInterfaceIteratorHelper iter(*pICHelper);
                        Reference<XTransferable> rXTransf(m_pImpl->getContents());
                        ClipboardEvent aClipbEvent(static_cast<XClipboard*>(this), rXTransf);

                        while(iter.hasMoreElements())
                        {
                            try
                            {
                                Reference<XClipboardListener> xCBListener(iter.next(), UNO_QUERY);
                                if (xCBListener.is())
                                    xCBListener->changedContents(aClipbEvent);
                            }
                            catch(RuntimeException&)
                            {
                                OSL_FAIL( "RuntimeException caught" );
                            }
                        }
                    }
                    catch(const css::lang::DisposedException&)
                    {
                        OSL_FAIL("Service Manager disposed");

                        // no further clipboard changed notifications
                        m_pImpl->unregisterClipboardViewer();
                    }

                } // end if
            } // end if
        } // end if
    }

    // overwritten base class method which will be
    // called by the base class dispose method

    void SAL_CALL CWinClipboard::disposing()
    {
        // do my own stuff
        m_pImpl->dispose( );

        // force destruction of the impl class
        m_pImpl.reset();
    }

    // XServiceInfo

    OUString SAL_CALL CWinClipboard::getImplementationName(  )
    {
        return OUString( WINCLIPBOARD_IMPL_NAME );
    }

    sal_Bool SAL_CALL CWinClipboard::supportsService( const OUString& ServiceName )
    {
        return cppu::supportsService(this, ServiceName);
    }

    Sequence< OUString > SAL_CALL CWinClipboard::getSupportedServiceNames(   )
    {
        return WinClipboard_getSupportedServiceNames();
    }

    /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

↑ V547 Expression '!rBHelper.bDisposed' is always true.