diff options
author | Jan-Marek Glogowski <glogow@fbihome.de> | 2020-09-21 20:12:48 +0200 |
---|---|---|
committer | Jan-Marek Glogowski <glogow@fbihome.de> | 2020-09-23 06:12:32 +0200 |
commit | de810a8e78da0d562092e35041c8a0aec92b9ee0 (patch) | |
tree | 8f5cde173849b8116e8d30a47332009455f3b734 /vcl/win | |
parent | 6349cc0f358b695e2d09a8da2bb709eb6f19e32c (diff) |
WIN merge CWinClipbImpl into CWinClipboard
Get rid of the already minimal pImpl.
Change-Id: Ida6fedab6e779b649e546bae2cda5f14fd4090d2
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/103211
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
Diffstat (limited to 'vcl/win')
-rw-r--r-- | vcl/win/dtrans/WinClipbImpl.cxx | 210 | ||||
-rw-r--r-- | vcl/win/dtrans/WinClipbImpl.hxx | 103 | ||||
-rw-r--r-- | vcl/win/dtrans/WinClipboard.cxx | 365 | ||||
-rw-r--r-- | vcl/win/dtrans/WinClipboard.hxx | 94 | ||||
-rw-r--r-- | vcl/win/dtrans/XNotifyingDataObject.cxx | 7 | ||||
-rw-r--r-- | vcl/win/dtrans/XNotifyingDataObject.hxx | 11 |
6 files changed, 289 insertions, 501 deletions
diff --git a/vcl/win/dtrans/WinClipbImpl.cxx b/vcl/win/dtrans/WinClipbImpl.cxx deleted file mode 100644 index 05248d75e896..000000000000 --- a/vcl/win/dtrans/WinClipbImpl.cxx +++ /dev/null @@ -1,210 +0,0 @@ -/* -*- 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 "WinClipbImpl.hxx" - -#include <systools/win32/comtools.hxx> -#include "DtObjFactory.hxx" -#include "APNDataObject.hxx" -#include "DOTransferable.hxx" -#include "WinClipboard.hxx" -#include <com/sun/star/datatransfer/clipboard/RenderingCapabilities.hpp> -#include "XNotifyingDataObject.hxx" - -#if !defined WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -#endif -#include <windows.h> -#include <ole2.h> -#include <objidl.h> - -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::datatransfer::clipboard::RenderingCapabilities; - -// definition of static members -CWinClipbImpl* CWinClipbImpl::s_pCWinClipbImpl = nullptr; -osl::Mutex CWinClipbImpl::s_aMutex; - -CWinClipbImpl::CWinClipbImpl( const OUString& aClipboardName, CWinClipboard* theWinClipboard ) : - m_itsName( aClipboardName ), - m_pWinClipboard( theWinClipboard ), - m_pCurrentClipContent( nullptr ) -{ - OSL_ASSERT( nullptr != m_pWinClipboard ); - - // necessary to reassociate from - // the static callback function - s_pCWinClipbImpl = this; - registerClipboardViewer( ); -} - -CWinClipbImpl::~CWinClipbImpl( ) -{ - { - MutexGuard aGuard(s_aMutex); - s_pCWinClipbImpl = nullptr; - } - - unregisterClipboardViewer( ); -} - -Reference< XTransferable > CWinClipbImpl::getContents( ) -{ - // use the shortcut or create a transferable from - // system clipboard - { - MutexGuard aGuard(m_ClipContentMutex); - - if (nullptr != m_pCurrentClipContent) - { - return m_pCurrentClipContent->m_XTransferable; - } - - // Content cached? - if (m_foreignContent.is()) - return m_foreignContent; - - // release the mutex, so that the variable may be - // changed by other threads - } - - Reference< XTransferable > rClipContent; - - // get the current dataobject from clipboard - IDataObjectPtr pIDataObject; - HRESULT hr = m_MtaOleClipboard.getClipboard( &pIDataObject ); - - if ( SUCCEEDED( hr ) ) - { - // create an apartment neutral dataobject and initialize it with a - // com smart pointer to the IDataObject from clipboard - IDataObjectPtr pIDo( new CAPNDataObject( pIDataObject ) ); - - // remember pIDo destroys itself due to the smart pointer - rClipContent = CDOTransferable::create( m_pWinClipboard->m_xContext, pIDo ); - - MutexGuard aGuard(m_ClipContentMutex); - m_foreignContent = rClipContent; - } - - return rClipContent; -} - -void CWinClipbImpl::setContents( - const Reference< XTransferable >& xTransferable, - const Reference< XClipboardOwner >& xClipboardOwner ) -{ - IDataObjectPtr pIDataObj; - - if ( xTransferable.is( ) ) - { - { - MutexGuard aGuard(m_ClipContentMutex); - - m_foreignContent.clear(); - - m_pCurrentClipContent - = new CXNotifyingDataObject(CDTransObjFactory::createDataObjFromTransferable( - m_pWinClipboard->m_xContext, xTransferable), - xTransferable, xClipboardOwner, this); - } - - pIDataObj = IDataObjectPtr( m_pCurrentClipContent ); - } - - m_MtaOleClipboard.setClipboard(pIDataObj.get()); -} - -OUString CWinClipbImpl::getName( ) -{ - return m_itsName; -} - -sal_Int8 CWinClipbImpl::getRenderingCapabilities( ) -{ - return ( Delayed | Persistent ); -} - -void CWinClipbImpl::flushClipboard( ) -{ - // actually it should be ClearableMutexGuard aGuard( m_ClipContentMutex ); - // but it does not work since FlushClipboard does a callback and frees DataObject - // which results in a deadlock in onReleaseDataObject. - // FlushClipboard had to be synchron in order to prevent shutdown until all - // clipboard-formats are rendered. - // The request is needed to prevent flushing if we are not clipboard owner (it is - // not known what happens if we flush but aren't clipboard owner). - // It may be possible to move the request to the clipboard STA thread by saving the - // DataObject and call OleIsCurrentClipboard before flushing. - - if ( nullptr != m_pCurrentClipContent ) - m_MtaOleClipboard.flushClipboard( ); -} - -void CWinClipbImpl::registerClipboardViewer( ) -{ - m_MtaOleClipboard.registerClipViewer( CWinClipbImpl::onClipboardContentChanged ); -} - -void CWinClipbImpl::unregisterClipboardViewer( ) -{ - m_MtaOleClipboard.registerClipViewer( nullptr ); -} - -void CWinClipbImpl::dispose() -{ - OSL_ENSURE( !m_pCurrentClipContent, "Clipboard was not flushed before shutdown!" ); -} - -void WINAPI CWinClipbImpl::onClipboardContentChanged() -{ - MutexGuard aGuard( s_aMutex ); - - // reassociation to instance through static member - if ( nullptr != s_pCWinClipbImpl ) - { - s_pCWinClipbImpl->m_foreignContent.clear(); - s_pCWinClipbImpl->m_pWinClipboard->notifyAllClipboardListener( ); - } -} - -void CWinClipbImpl::onReleaseDataObject( CXNotifyingDataObject* theCaller ) -{ - OSL_ASSERT( nullptr != theCaller ); - - if ( theCaller ) - theCaller->lostOwnership( ); - - // if the current caller is the one we currently - // hold, then set it to NULL because an external - // source must be the clipboardowner now - MutexGuard aGuard( m_ClipContentMutex ); - - if ( m_pCurrentClipContent == theCaller ) - m_pCurrentClipContent = nullptr; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/win/dtrans/WinClipbImpl.hxx b/vcl/win/dtrans/WinClipbImpl.hxx deleted file mode 100644 index 9fd2fb894a8c..000000000000 --- a/vcl/win/dtrans/WinClipbImpl.hxx +++ /dev/null @@ -1,103 +0,0 @@ -/* -*- 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 . - */ - -#pragma once - -#include <sal/types.h> -#include <rtl/ustring.hxx> -#include <com/sun/star/datatransfer/XTransferable.hpp> -#include <com/sun/star/datatransfer/clipboard/XClipboardListener.hpp> -#include <com/sun/star/datatransfer/clipboard/XClipboardOwner.hpp> -#include "MtaOleClipb.hxx" - -#if !defined WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -#endif -#include <windows.h> - -class CWinClipboard; -class CXNotifyingDataObject; - -// impl class to avoid deadlocks between XTDataObject -// and the clipboard implementation - -class CWinClipbImpl -{ -public: - ~CWinClipbImpl( ); - -protected: - CWinClipbImpl( const OUString& aClipboardName, CWinClipboard* theWinClipboard ); - - /// @throws css::uno::RuntimeException - css::uno::Reference< css::datatransfer::XTransferable > getContents( ); - - /// @throws css::uno::RuntimeException - void setContents( - const css::uno::Reference< css::datatransfer::XTransferable >& xTransferable, - const css::uno::Reference< css::datatransfer::clipboard::XClipboardOwner >& xClipboardOwner ); - - /// @throws css::uno::RuntimeException - OUString getName( ); - - // XClipboardEx - - /// @throws css::uno::RuntimeException - static sal_Int8 getRenderingCapabilities( ); - - // XFlushableClipboard - - /// @throws css::uno::RuntimeException - void flushClipboard( ); - - // XComponent - - /// @throws css::uno::RuntimeException - void dispose( ); - - // member functions - - void registerClipboardViewer( ); - void unregisterClipboardViewer( ); - - static void WINAPI onClipboardContentChanged(); - -private: - void onReleaseDataObject( CXNotifyingDataObject* theCaller ); - -private: - OUString m_itsName; - CMtaOleClipboard m_MtaOleClipboard; - CWinClipboard* m_pWinClipboard; - CXNotifyingDataObject* m_pCurrentClipContent; - com::sun::star::uno::Reference< com::sun::star::datatransfer::XTransferable > m_foreignContent; - osl::Mutex m_ClipContentMutex; - - static osl::Mutex s_aMutex; - static CWinClipbImpl* s_pCWinClipbImpl; - -private: - CWinClipbImpl( const CWinClipbImpl& ); - CWinClipbImpl& operator=( const CWinClipbImpl& ); - - friend class CWinClipboard; - friend class CXNotifyingDataObject; -}; - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/win/dtrans/WinClipboard.cxx b/vcl/win/dtrans/WinClipboard.cxx index 8a1d1cc07e04..c1e4dde81c82 100644 --- a/vcl/win/dtrans/WinClipboard.cxx +++ b/vcl/win/dtrans/WinClipboard.cxx @@ -18,30 +18,60 @@ */ #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 <com/sun/star/uno/XComponentContext.hpp> #include <cppuhelper/supportsservice.hxx> #include <rtl/ref.hxx> -#include "WinClipbImpl.hxx" -using namespace osl; -using namespace std; -using namespace cppu; +#include <com/sun/star/datatransfer/clipboard/RenderingCapabilities.hpp> +#include "XNotifyingDataObject.hxx" + +#include <systools/win32/comtools.hxx> +#include "DtObjFactory.hxx" +#include "APNDataObject.hxx" +#include "DOTransferable.hxx" +#include "WinClipboard.hxx" + +#if !defined WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include <windows.h> +#include <ole2.h> +#include <objidl.h> -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; +#include "WinClipboard.hxx" + +using namespace com::sun::star; + +// definition of static members +CWinClipboard* CWinClipboard::s_pCWinClipbImpl = nullptr; +osl::Mutex CWinClipboard::s_aMutex; /*XEventListener,*/ -CWinClipboard::CWinClipboard( const Reference< XComponentContext >& rxContext, const OUString& aClipboardName ) : - WeakComponentImplHelper< XSystemClipboard, XFlushableClipboard, XServiceInfo >( m_aCbListenerMutex ), - m_xContext( rxContext ) +CWinClipboard::CWinClipboard(const uno::Reference<uno::XComponentContext>& rxContext, + const OUString& aClipboardName) + : WeakComponentImplHelper<XSystemClipboard, XFlushableClipboard, XServiceInfo>( + m_aCbListenerMutex) + , m_xContext(rxContext) + , m_itsName(aClipboardName) + , m_pCurrentClipContent(nullptr) { - m_pImpl.reset( new CWinClipbImpl( aClipboardName, this ) ); + // necessary to reassociate from + // the static callback function + s_pCWinClipbImpl = this; + registerClipboardViewer(); +} + +CWinClipboard::~CWinClipboard() +{ + { + osl::MutexGuard aGuard(s_aMutex); + s_pCWinClipbImpl = nullptr; + } + + unregisterClipboardViewer(); } // XClipboard @@ -52,188 +82,263 @@ CWinClipboard::CWinClipboard( const Reference< XComponentContext >& rxContext, c // and so on, we simply return the original XTransferable instead of our // DOTransferable -Reference< XTransferable > SAL_CALL CWinClipboard::getContents( ) +uno::Reference<datatransfer::XTransferable> SAL_CALL CWinClipboard::getContents() { - MutexGuard aGuard( m_aMutex ); + osl::MutexGuard aGuard(m_aMutex); + + if (rBHelper.bDisposed) + throw lang::DisposedException("object is already disposed", + static_cast<XClipboardEx*>(this)); + + // use the shortcut or create a transferable from + // system clipboard + { + osl::MutexGuard aGuard(m_ClipContentMutex); - if ( rBHelper.bDisposed ) - throw DisposedException("object is already disposed", - static_cast< XClipboardEx* >( this ) ); + if (nullptr != m_pCurrentClipContent) + return m_pCurrentClipContent->m_XTransferable; - if ( m_pImpl ) - return m_pImpl->getContents( ); + // Content cached? + if (m_foreignContent.is()) + return m_foreignContent; - return Reference< XTransferable >( ); + // release the mutex, so that the variable may be + // changed by other threads + } + + uno::Reference<datatransfer::XTransferable> rClipContent; + + // get the current dataobject from clipboard + IDataObjectPtr pIDataObject; + HRESULT hr = m_MtaOleClipboard.getClipboard(&pIDataObject); + + if (SUCCEEDED(hr)) + { + // create an apartment neutral dataobject and initialize it with a + // com smart pointer to the IDataObject from clipboard + IDataObjectPtr pIDo(new CAPNDataObject(pIDataObject)); + + // remember pIDo destroys itself due to the smart pointer + rClipContent = CDOTransferable::create(m_xContext, pIDo); + + osl::MutexGuard aGuard(m_ClipContentMutex); + m_foreignContent = rClipContent; + } + + return rClipContent; } -void SAL_CALL CWinClipboard::setContents( const Reference< XTransferable >& xTransferable, - const Reference< XClipboardOwner >& xClipboardOwner ) +void SAL_CALL CWinClipboard::setContents( + const uno::Reference<datatransfer::XTransferable>& xTransferable, + const uno::Reference<datatransfer::clipboard::XClipboardOwner>& xClipboardOwner) { - MutexGuard aGuard( m_aMutex ); + osl::MutexGuard aGuard(m_aMutex); + + if (rBHelper.bDisposed) + throw lang::DisposedException("object is already disposed", + static_cast<XClipboardEx*>(this)); + + IDataObjectPtr pIDataObj; + + if (xTransferable.is()) + { + { + osl::MutexGuard aGuard(m_ClipContentMutex); + + m_foreignContent.clear(); + + m_pCurrentClipContent = new CXNotifyingDataObject( + CDTransObjFactory::createDataObjFromTransferable(m_xContext, xTransferable), + xTransferable, xClipboardOwner, this); + } - if ( rBHelper.bDisposed ) - throw DisposedException("object is already disposed", - static_cast< XClipboardEx* >( this ) ); + pIDataObj = IDataObjectPtr(m_pCurrentClipContent); + } - if ( m_pImpl ) - m_pImpl->setContents( xTransferable, xClipboardOwner ); + m_MtaOleClipboard.setClipboard(pIDataObj.get()); } -OUString SAL_CALL CWinClipboard::getName( ) +OUString SAL_CALL CWinClipboard::getName() { - if ( rBHelper.bDisposed ) - throw DisposedException("object is already disposed", - static_cast< XClipboardEx* >( this ) ); + if (rBHelper.bDisposed) + throw lang::DisposedException("object is already disposed", + static_cast<XClipboardEx*>(this)); - if ( m_pImpl ) - return m_pImpl->getName( ); - - return OUString(); + return m_itsName; } // XFlushableClipboard -void SAL_CALL CWinClipboard::flushClipboard( ) +void SAL_CALL CWinClipboard::flushClipboard() { - MutexGuard aGuard( m_aMutex ); - - if ( rBHelper.bDisposed ) - throw DisposedException("object is already disposed", - static_cast< XClipboardEx* >( this ) ); - - if ( m_pImpl ) - m_pImpl->flushClipboard( ); + osl::MutexGuard aGuard(m_aMutex); + + if (rBHelper.bDisposed) + throw lang::DisposedException("object is already disposed", + static_cast<XClipboardEx*>(this)); + + // actually it should be ClearableMutexGuard aGuard( m_ClipContentMutex ); + // but it does not work since FlushClipboard does a callback and frees DataObject + // which results in a deadlock in onReleaseDataObject. + // FlushClipboard had to be synchron in order to prevent shutdown until all + // clipboard-formats are rendered. + // The request is needed to prevent flushing if we are not clipboard owner (it is + // not known what happens if we flush but aren't clipboard owner). + // It may be possible to move the request to the clipboard STA thread by saving the + // DataObject and call OleIsCurrentClipboard before flushing. + + if (nullptr != m_pCurrentClipContent) + m_MtaOleClipboard.flushClipboard(); } // XClipboardEx -sal_Int8 SAL_CALL CWinClipboard::getRenderingCapabilities( ) +sal_Int8 SAL_CALL CWinClipboard::getRenderingCapabilities() { - if ( rBHelper.bDisposed ) - throw DisposedException("object is already disposed", - static_cast< XClipboardEx* >( this ) ); - - if ( m_pImpl ) - return CWinClipbImpl::getRenderingCapabilities( ); + if (rBHelper.bDisposed) + throw lang::DisposedException("object is already disposed", + static_cast<XClipboardEx*>(this)); - return 0; + using namespace datatransfer::clipboard::RenderingCapabilities; + return (Delayed | Persistant); } // XClipboardNotifier -void SAL_CALL CWinClipboard::addClipboardListener( const Reference< XClipboardListener >& listener ) +void SAL_CALL CWinClipboard::addClipboardListener( + const uno::Reference<datatransfer::clipboard::XClipboardListener>& listener) { - if ( rBHelper.bDisposed ) - throw DisposedException("object is already disposed", - static_cast< XClipboardEx* >( this ) ); + if (rBHelper.bDisposed) + throw lang::DisposedException("object is already disposed", + static_cast<XClipboardEx*>(this)); // check input parameter - if ( !listener.is( ) ) - throw IllegalArgumentException("empty reference", - static_cast< XClipboardEx* >( this ), - 1 ); + if (!listener.is()) + throw lang::IllegalArgumentException("empty reference", static_cast<XClipboardEx*>(this), + 1); - rBHelper.aLC.addInterface( cppu::UnoType<decltype(listener)>::get(), listener ); + rBHelper.aLC.addInterface(cppu::UnoType<decltype(listener)>::get(), listener); } -void SAL_CALL CWinClipboard::removeClipboardListener( const Reference< XClipboardListener >& listener ) +void SAL_CALL CWinClipboard::removeClipboardListener( + const uno::Reference<datatransfer::clipboard::XClipboardListener>& listener) { - if ( rBHelper.bDisposed ) - throw DisposedException("object is already disposed", - static_cast< XClipboardEx* >( this ) ); + if (rBHelper.bDisposed) + throw lang::DisposedException("object is already disposed", + static_cast<XClipboardEx*>(this)); // check input parameter - if ( !listener.is( ) ) - throw IllegalArgumentException("empty reference", - static_cast< XClipboardEx* >( this ), - 1 ); + if (!listener.is()) + throw lang::IllegalArgumentException("empty reference", static_cast<XClipboardEx*>(this), + 1); - rBHelper.aLC.removeInterface( cppu::UnoType<decltype(listener)>::get(), listener ); + rBHelper.aLC.removeInterface(cppu::UnoType<decltype(listener)>::get(), listener); } -void CWinClipboard::notifyAllClipboardListener( ) +void CWinClipboard::notifyAllClipboardListener() { - if ( !rBHelper.bDisposed ) - { - ClearableMutexGuard aGuard( rBHelper.rMutex ); - if ( !rBHelper.bDisposed ) - { - aGuard.clear( ); + if (rBHelper.bDisposed) + return; + + osl::ClearableMutexGuard aGuard(rBHelper.rMutex); + if (rBHelper.bDisposed) + return; + aGuard.clear(); - OInterfaceContainerHelper* pICHelper = rBHelper.aLC.getContainer( - cppu::UnoType<XClipboardListener>::get()); + cppu::OInterfaceContainerHelper* pICHelper = rBHelper.aLC.getContainer( + cppu::UnoType<datatransfer::clipboard::XClipboardListener>::get()); + if (!pICHelper) + return; - if ( pICHelper ) + try + { + cppu::OInterfaceIteratorHelper iter(*pICHelper); + uno::Reference<datatransfer::XTransferable> rXTransf(getContents()); + datatransfer::clipboard::ClipboardEvent aClipbEvent(static_cast<XClipboard*>(this), + rXTransf); + + while (iter.hasMoreElements()) + { + try + { + uno::Reference<datatransfer::clipboard::XClipboardListener> xCBListener( + iter.next(), uno::UNO_QUERY); + if (xCBListener.is()) + xCBListener->changedContents(aClipbEvent); + } + catch (uno::RuntimeException&) { - 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(); + OSL_FAIL("RuntimeException caught"); + } + } + } + catch (const lang::DisposedException&) + { + OSL_FAIL("Service Manager disposed"); + + // no further clipboard changed notifications + unregisterClipboardViewer(); + } } // XServiceInfo -OUString SAL_CALL CWinClipboard::getImplementationName( ) +OUString SAL_CALL CWinClipboard::getImplementationName() { return "com.sun.star.datatransfer.clipboard.ClipboardW32"; } -sal_Bool SAL_CALL CWinClipboard::supportsService( const OUString& ServiceName ) +sal_Bool SAL_CALL CWinClipboard::supportsService(const OUString& ServiceName) { return cppu::supportsService(this, ServiceName); } -Sequence< OUString > SAL_CALL CWinClipboard::getSupportedServiceNames( ) +uno::Sequence<OUString> SAL_CALL CWinClipboard::getSupportedServiceNames() { return { "com.sun.star.datatransfer.clipboard.SystemClipboard" }; } extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* -dtrans_CWinClipboard_get_implementation( - css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&) +dtrans_CWinClipboard_get_implementation(css::uno::XComponentContext* context, + css::uno::Sequence<css::uno::Any> const&) { static rtl::Reference<CWinClipboard> g_Instance(new CWinClipboard(context, "")); g_Instance->acquire(); return static_cast<cppu::OWeakObject*>(g_Instance.get()); } +void CWinClipboard::onReleaseDataObject(CXNotifyingDataObject* theCaller) +{ + OSL_ASSERT(nullptr != theCaller); + + if (theCaller) + theCaller->lostOwnership(); + + // if the current caller is the one we currently hold, then set it to NULL + // because an external source must be the clipboardowner now + osl::MutexGuard aGuard(m_ClipContentMutex); + + if (m_pCurrentClipContent == theCaller) + m_pCurrentClipContent = nullptr; +} + +void CWinClipboard::registerClipboardViewer() +{ + m_MtaOleClipboard.registerClipViewer(CWinClipboard::onClipboardContentChanged); +} + +void CWinClipboard::unregisterClipboardViewer() { m_MtaOleClipboard.registerClipViewer(nullptr); } + +void WINAPI CWinClipboard::onClipboardContentChanged() +{ + osl::MutexGuard aGuard(s_aMutex); + + // reassociation to instance through static member + if (nullptr != s_pCWinClipbImpl) + { + s_pCWinClipbImpl->m_foreignContent.clear(); + s_pCWinClipbImpl->notifyAllClipboardListener(); + } +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/win/dtrans/WinClipboard.hxx b/vcl/win/dtrans/WinClipboard.hxx index a00375926456..1b0a05a3450d 100644 --- a/vcl/win/dtrans/WinClipboard.hxx +++ b/vcl/win/dtrans/WinClipboard.hxx @@ -33,10 +33,9 @@ #include <com/sun/star/uno/XComponentContext.hpp> #include <osl/conditn.hxx> -#include <memory> +#include "MtaOleClipb.hxx" -// forward -class CWinClipbImpl; +class CXNotifyingDataObject; // implements the XClipboard[Ex] ... interfaces // for the clipboard viewer mechanism we need a static callback function @@ -53,68 +52,67 @@ class CWinClipbImpl; class CWinClipboardDummy { protected: - osl::Mutex m_aMutex; - osl::Mutex m_aCbListenerMutex; + osl::Mutex m_aMutex; + osl::Mutex m_aCbListenerMutex; }; -class CWinClipboard : - public CWinClipboardDummy, - public cppu::WeakComponentImplHelper< - css::datatransfer::clipboard::XSystemClipboard, - css::datatransfer::clipboard::XFlushableClipboard, - css::lang::XServiceInfo > +class CWinClipboard final + : public CWinClipboardDummy, + public cppu::WeakComponentImplHelper<css::datatransfer::clipboard::XSystemClipboard, + css::datatransfer::clipboard::XFlushableClipboard, + css::lang::XServiceInfo> { -public: - CWinClipboard( const css::uno::Reference< css::uno::XComponentContext >& rxContext, - const OUString& aClipboardName ); + friend STDMETHODIMP_(ULONG) CXNotifyingDataObject::Release(); - // XClipboard + css::uno::Reference<css::uno::XComponentContext> m_xContext; + const OUString m_itsName; + CMtaOleClipboard m_MtaOleClipboard; + CXNotifyingDataObject* m_pCurrentClipContent; + com::sun::star::uno::Reference<com::sun::star::datatransfer::XTransferable> m_foreignContent; + osl::Mutex m_ClipContentMutex; - virtual css::uno::Reference< css::datatransfer::XTransferable > SAL_CALL getContents( ) override; + static osl::Mutex s_aMutex; + static CWinClipboard* s_pCWinClipbImpl; - virtual void SAL_CALL setContents( - const css::uno::Reference< css::datatransfer::XTransferable >& xTransferable, - const css::uno::Reference< css::datatransfer::clipboard::XClipboardOwner >& xClipboardOwner ) override; + void notifyAllClipboardListener(); + void onReleaseDataObject(CXNotifyingDataObject* theCaller); - virtual OUString SAL_CALL getName( ) override; + void registerClipboardViewer(); + void unregisterClipboardViewer(); - // XFlushableClipboard + static void WINAPI onClipboardContentChanged(); - virtual void SAL_CALL flushClipboard( ) override; +public: + CWinClipboard(const css::uno::Reference<css::uno::XComponentContext>& rxContext, + const OUString& aClipboardName); + virtual ~CWinClipboard() override; - // XClipboardEx + // XClipboard + virtual css::uno::Reference<css::datatransfer::XTransferable> SAL_CALL getContents() override; + virtual void SAL_CALL setContents( + const css::uno::Reference<css::datatransfer::XTransferable>& xTransferable, + const css::uno::Reference<css::datatransfer::clipboard::XClipboardOwner>& xClipboardOwner) + override; + virtual OUString SAL_CALL getName() override; - virtual sal_Int8 SAL_CALL getRenderingCapabilities( ) override; + // XFlushableClipboard + virtual void SAL_CALL flushClipboard() override; - // XClipboardNotifier + // XClipboardEx + virtual sal_Int8 SAL_CALL getRenderingCapabilities() override; + // XClipboardNotifier virtual void SAL_CALL addClipboardListener( - const css::uno::Reference< css::datatransfer::clipboard::XClipboardListener >& listener ) override; - + const css::uno::Reference<css::datatransfer::clipboard::XClipboardListener>& listener) + override; virtual void SAL_CALL removeClipboardListener( - const css::uno::Reference< css::datatransfer::clipboard::XClipboardListener >& listener ) override; - - // overwrite base class method, which is called - // by base class dispose function - - virtual void SAL_CALL disposing() override; + const css::uno::Reference<css::datatransfer::clipboard::XClipboardListener>& listener) + override; // XServiceInfo - - virtual OUString SAL_CALL getImplementationName( ) override; - - virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; - - virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override; - -private: - void notifyAllClipboardListener( ); - -private: - std::unique_ptr< CWinClipbImpl > m_pImpl; - css::uno::Reference< css::uno::XComponentContext > m_xContext; - - friend class CWinClipbImpl; + virtual OUString SAL_CALL getImplementationName() override; + virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override; + virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override; }; /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/win/dtrans/XNotifyingDataObject.cxx b/vcl/win/dtrans/XNotifyingDataObject.cxx index b12ea31271d2..a989b47e938d 100644 --- a/vcl/win/dtrans/XNotifyingDataObject.cxx +++ b/vcl/win/dtrans/XNotifyingDataObject.cxx @@ -19,7 +19,6 @@ #include <osl/diagnose.h> #include "XNotifyingDataObject.hxx" -#include "WinClipbImpl.hxx" #include "WinClipboard.hxx" using namespace com::sun::star::datatransfer; @@ -31,12 +30,12 @@ CXNotifyingDataObject::CXNotifyingDataObject( const IDataObjectPtr& aIDataObject, const Reference< XTransferable >& aXTransferable, const Reference< XClipboardOwner >& aXClipOwner, - CWinClipbImpl* theWinClipImpl ) : + CWinClipboard* const theWinClipoard) : m_nRefCnt( 0 ), m_aIDataObject( aIDataObject ), m_XTransferable( aXTransferable ), m_XClipboardOwner( aXClipOwner ), - m_pWinClipImpl( theWinClipImpl ) + m_pWinClipImpl( theWinClipoard ) { } @@ -138,7 +137,7 @@ void CXNotifyingDataObject::lostOwnership( ) { if (m_XClipboardOwner.is()) m_XClipboardOwner->lostOwnership( - static_cast<XClipboardEx*>(m_pWinClipImpl->m_pWinClipboard ), m_XTransferable); + static_cast<XClipboardEx*>(m_pWinClipImpl), m_XTransferable); } catch(RuntimeException&) { diff --git a/vcl/win/dtrans/XNotifyingDataObject.hxx b/vcl/win/dtrans/XNotifyingDataObject.hxx index 2fb3025a03fa..408413a5de17 100644 --- a/vcl/win/dtrans/XNotifyingDataObject.hxx +++ b/vcl/win/dtrans/XNotifyingDataObject.hxx @@ -36,16 +36,16 @@ ----------------------------------------------------------------------------*/ // forward -class CWinClipbImpl; +class CWinClipboard; -class CXNotifyingDataObject : public IDataObject +class CXNotifyingDataObject final : public IDataObject { public: CXNotifyingDataObject( const IDataObjectPtr& aIDataObject, const css::uno::Reference< css::datatransfer::XTransferable >& aXTransferable, const css::uno::Reference< css::datatransfer::clipboard::XClipboardOwner >& aXClipOwner, - CWinClipbImpl* theWinClipImpl ); + CWinClipboard* const theWinClipoard); virtual ~CXNotifyingDataObject() {} @@ -72,14 +72,13 @@ public: private: void lostOwnership( ); -private: sal_Int32 m_nRefCnt; IDataObjectPtr m_aIDataObject; const css::uno::Reference< css::datatransfer::XTransferable > m_XTransferable; const css::uno::Reference< css::datatransfer::clipboard::XClipboardOwner > m_XClipboardOwner; - CWinClipbImpl* m_pWinClipImpl; + CWinClipboard* const m_pWinClipImpl; - friend class CWinClipbImpl; + friend class CWinClipboard; }; /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |