LibreOffice Module dtrans (master)  1
WinClipboard.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <osl/diagnose.h>
21 #include "WinClipboard.hxx"
22 #include <com/sun/star/datatransfer/clipboard/ClipboardEvent.hpp>
23 #include <com/sun/star/lang/DisposedException.hpp>
24 #include <com/sun/star/lang/IllegalArgumentException.hpp>
26 #include "WinClipbImpl.hxx"
27 
28 using namespace osl;
29 using namespace std;
30 using namespace cppu;
31 
32 using namespace com::sun::star::uno;
33 using namespace com::sun::star::datatransfer;
35 using namespace com::sun::star::lang;
36 
37 #define WINCLIPBOARD_IMPL_NAME "com.sun.star.datatransfer.clipboard.ClipboardW32"
38 
39 namespace
40 {
41  Sequence< OUString > WinClipboard_getSupportedServiceNames()
42  {
43  Sequence< OUString > aRet { "com.sun.star.datatransfer.clipboard.SystemClipboard" };
44  return aRet;
45  }
46 }
47 
48 /*XEventListener,*/
49 CWinClipboard::CWinClipboard( const Reference< XComponentContext >& rxContext, const OUString& aClipboardName ) :
50  WeakComponentImplHelper< XSystemClipboard, XFlushableClipboard, XServiceInfo >( m_aCbListenerMutex ),
51  m_xContext( rxContext )
52 {
53  m_pImpl.reset( new CWinClipbImpl( aClipboardName, this ) );
54 }
55 
56 // XClipboard
57 
58 // to avoid unnecessary traffic we check first if there is a clipboard
59 // content which was set via setContent, in this case we don't need
60 // to query the content from the clipboard, create a new wrapper object
61 // and so on, we simply return the original XTransferable instead of our
62 // DOTransferable
63 
65 {
66  MutexGuard aGuard( m_aMutex );
67 
68  if ( rBHelper.bDisposed )
69  throw DisposedException("object is already disposed",
70  static_cast< XClipboardEx* >( this ) );
71 
72  if ( nullptr != m_pImpl.get( ) )
73  return m_pImpl->getContents( );
74 
76 }
77 
78 void SAL_CALL CWinClipboard::setContents( const Reference< XTransferable >& xTransferable,
79  const Reference< XClipboardOwner >& xClipboardOwner )
80 {
81  MutexGuard aGuard( m_aMutex );
82 
83  if ( rBHelper.bDisposed )
84  throw DisposedException("object is already disposed",
85  static_cast< XClipboardEx* >( this ) );
86 
87  if ( nullptr != m_pImpl.get( ) )
88  m_pImpl->setContents( xTransferable, xClipboardOwner );
89 }
90 
91 OUString SAL_CALL CWinClipboard::getName( )
92 {
93  if ( rBHelper.bDisposed )
94  throw DisposedException("object is already disposed",
95  static_cast< XClipboardEx* >( this ) );
96 
97  if ( nullptr != m_pImpl.get( ) )
98  return m_pImpl->getName( );
99 
100  return OUString();
101 }
102 
103 // XFlushableClipboard
104 
106 {
107  MutexGuard aGuard( m_aMutex );
108 
109  if ( rBHelper.bDisposed )
110  throw DisposedException("object is already disposed",
111  static_cast< XClipboardEx* >( this ) );
112 
113  if ( nullptr != m_pImpl.get( ) )
114  m_pImpl->flushClipboard( );
115 }
116 
117 // XClipboardEx
118 
120 {
121  if ( rBHelper.bDisposed )
122  throw DisposedException("object is already disposed",
123  static_cast< XClipboardEx* >( this ) );
124 
125  if ( nullptr != m_pImpl.get( ) )
127 
128  return 0;
129 }
130 
131 // XClipboardNotifier
132 
134 {
135  if ( rBHelper.bDisposed )
136  throw DisposedException("object is already disposed",
137  static_cast< XClipboardEx* >( this ) );
138 
139  // check input parameter
140  if ( !listener.is( ) )
141  throw IllegalArgumentException("empty reference",
142  static_cast< XClipboardEx* >( this ),
143  1 );
144 
145  rBHelper.aLC.addInterface( cppu::UnoType<decltype(listener)>::get(), listener );
146 }
147 
149 {
150  if ( rBHelper.bDisposed )
151  throw DisposedException("object is already disposed",
152  static_cast< XClipboardEx* >( this ) );
153 
154  // check input parameter
155  if ( !listener.is( ) )
156  throw IllegalArgumentException("empty reference",
157  static_cast< XClipboardEx* >( this ),
158  1 );
159 
160  rBHelper.aLC.removeInterface( cppu::UnoType<decltype(listener)>::get(), listener );
161 }
162 
164 {
165  if ( !rBHelper.bDisposed )
166  {
167  ClearableMutexGuard aGuard( rBHelper.rMutex );
168  if ( !rBHelper.bDisposed )
169  {
170  aGuard.clear( );
171 
172  OInterfaceContainerHelper* pICHelper = rBHelper.aLC.getContainer(
174 
175  if ( pICHelper )
176  {
177  try
178  {
179  OInterfaceIteratorHelper iter(*pICHelper);
180  Reference<XTransferable> rXTransf(m_pImpl->getContents());
181  ClipboardEvent aClipbEvent(static_cast<XClipboard*>(this), rXTransf);
182 
183  while(iter.hasMoreElements())
184  {
185  try
186  {
187  Reference<XClipboardListener> xCBListener(iter.next(), UNO_QUERY);
188  if (xCBListener.is())
189  xCBListener->changedContents(aClipbEvent);
190  }
191  catch(RuntimeException&)
192  {
193  OSL_FAIL( "RuntimeException caught" );
194  }
195  }
196  }
197  catch(const css::lang::DisposedException&)
198  {
199  OSL_FAIL("Service Manager disposed");
200 
201  // no further clipboard changed notifications
202  m_pImpl->unregisterClipboardViewer();
203  }
204 
205  } // end if
206  } // end if
207  } // end if
208 }
209 
210 // overwritten base class method which will be
211 // called by the base class dispose method
212 
214 {
215  // do my own stuff
216  m_pImpl->dispose( );
217 
218  // force destruction of the impl class
219  m_pImpl.reset();
220 }
221 
222 // XServiceInfo
223 
225 {
226  return WINCLIPBOARD_IMPL_NAME;
227 }
228 
229 sal_Bool SAL_CALL CWinClipboard::supportsService( const OUString& ServiceName )
230 {
231  return cppu::supportsService(this, ServiceName);
232 }
233 
235 {
236  return WinClipboard_getSupportedServiceNames();
237 }
238 
239 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static sal_Int8 getRenderingCapabilities()
std::unique_ptr< CWinClipbImpl > m_pImpl
signed char sal_Int8
CWinClipboard(const css::uno::Reference< css::uno::XComponentContext > &rxContext, const OUString &aClipboardName)
virtual void SAL_CALL flushClipboard() override
void notifyAllClipboardListener()
css::uno::XInterface *SAL_CALL next()
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
virtual css::uno::Reference< css::datatransfer::XTransferable > SAL_CALL getContents() override
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
virtual void SAL_CALL disposing() override
unsigned char sal_Bool
virtual sal_Int8 SAL_CALL getRenderingCapabilities() override
friend class CWinClipbImpl
virtual OUString SAL_CALL getName() override
virtual void SAL_CALL removeClipboardListener(const css::uno::Reference< css::datatransfer::clipboard::XClipboardListener > &listener) override
virtual OUString SAL_CALL getImplementationName() override
virtual void SAL_CALL setContents(const css::uno::Reference< css::datatransfer::XTransferable > &xTransferable, const css::uno::Reference< css::datatransfer::clipboard::XClipboardOwner > &xClipboardOwner) override
Reference< XComponentContext > m_xContext
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
#define WINCLIPBOARD_IMPL_NAME
virtual void SAL_CALL addClipboardListener(const css::uno::Reference< css::datatransfer::clipboard::XClipboardListener > &listener) override
bool SAL_CALL hasMoreElements() const