1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_dtrans.hxx"
26
27 //------------------------------------------------------------------------
28 // includes
29 //------------------------------------------------------------------------
30 #include <osl/diagnose.h>
31 #include "WinClipboard.hxx"
32 #include <com/sun/star/datatransfer/clipboard/ClipboardEvent.hpp>
33 #include <com/sun/star/lang/DisposedException.hpp>
34 #include <com/sun/star/lang/IllegalArgumentException.hpp>
35 #include "WinClipbImpl.hxx"
36
37 //------------------------------------------------------------------------
38 // namespace directives
39 //------------------------------------------------------------------------
40
41 using namespace rtl;
42 using namespace osl;
43 using namespace std;
44 using namespace cppu;
45
46 using namespace com::sun::star::uno;
47 using namespace com::sun::star::datatransfer;
48 using namespace com::sun::star::datatransfer::clipboard;
49 using namespace com::sun::star::lang;
50
51 //------------------------------------------------------------------------
52 // defines
53 //------------------------------------------------------------------------
54
55 #define WINCLIPBOARD_IMPL_NAME "com.sun.star.datatransfer.clipboard.ClipboardW32"
56
57 //------------------------------------------------------------------------
58 // helper functions
59 //------------------------------------------------------------------------
60
61 namespace
62 {
WinClipboard_getSupportedServiceNames()63 Sequence< OUString > SAL_CALL WinClipboard_getSupportedServiceNames()
64 {
65 Sequence< OUString > aRet(1);
66 aRet[0] = OUString::createFromAscii("com.sun.star.datatransfer.clipboard.SystemClipboard");
67 return aRet;
68 }
69 }
70
71 //------------------------------------------------------------------------
72 // ctor
73 //------------------------------------------------------------------------
74 /*XEventListener,*/
CWinClipboard(const Reference<XMultiServiceFactory> & rServiceManager,const OUString & aClipboardName)75 CWinClipboard::CWinClipboard( const Reference< XMultiServiceFactory >& rServiceManager, const OUString& aClipboardName ) :
76 WeakComponentImplHelper4< XClipboardEx, XFlushableClipboard, XClipboardNotifier, XServiceInfo >( m_aCbListenerMutex ),
77 m_SrvMgr( rServiceManager )
78 {
79 m_pImpl.reset( new CWinClipbImpl( aClipboardName, this ) );
80 }
81
82 //========================================================================
83 // XClipboard
84 //========================================================================
85
86 //------------------------------------------------------------------------
87 // getContent
88 // to avoid unecessary traffic we check first if there is a clipboard
89 // content which was set via setContent, in this case we don't need
90 // to query the content from the clipboard, create a new wrapper object
91 // and so on, we simply return the orignial XTransferable instead of our
92 // DOTransferable
93 //------------------------------------------------------------------------
94
getContents()95 Reference< XTransferable > SAL_CALL CWinClipboard::getContents( ) throw( RuntimeException )
96 {
97 MutexGuard aGuard( m_aMutex );
98
99 if ( rBHelper.bDisposed )
100 throw DisposedException( OUString::createFromAscii( "object is already disposed" ),
101 static_cast< XClipboardEx* >( this ) );
102
103 if ( NULL != m_pImpl.get( ) )
104 return m_pImpl->getContents( );
105
106 return Reference< XTransferable >( );
107 }
108
109 //------------------------------------------------------------------------
110 // setContent
111 //------------------------------------------------------------------------
112
setContents(const Reference<XTransferable> & xTransferable,const Reference<XClipboardOwner> & xClipboardOwner)113 void SAL_CALL CWinClipboard::setContents( const Reference< XTransferable >& xTransferable,
114 const Reference< XClipboardOwner >& xClipboardOwner )
115 throw( RuntimeException )
116 {
117 MutexGuard aGuard( m_aMutex );
118
119 if ( rBHelper.bDisposed )
120 throw DisposedException( OUString::createFromAscii( "object is already disposed" ),
121 static_cast< XClipboardEx* >( this ) );
122
123 if ( NULL != m_pImpl.get( ) )
124 m_pImpl->setContents( xTransferable, xClipboardOwner );
125 }
126
127 //------------------------------------------------------------------------
128 // getName
129 //------------------------------------------------------------------------
130
getName()131 OUString SAL_CALL CWinClipboard::getName( ) throw( RuntimeException )
132 {
133 if ( rBHelper.bDisposed )
134 throw DisposedException( OUString::createFromAscii( "object is already disposed" ),
135 static_cast< XClipboardEx* >( this ) );
136
137 if ( NULL != m_pImpl.get( ) )
138 return m_pImpl->getName( );
139
140 return OUString::createFromAscii( "" );
141 }
142
143 //========================================================================
144 // XFlushableClipboard
145 //========================================================================
146
flushClipboard()147 void SAL_CALL CWinClipboard::flushClipboard( ) throw( RuntimeException )
148 {
149 MutexGuard aGuard( m_aMutex );
150
151 if ( rBHelper.bDisposed )
152 throw DisposedException( OUString::createFromAscii( "object is already disposed" ),
153 static_cast< XClipboardEx* >( this ) );
154
155 if ( NULL != m_pImpl.get( ) )
156 m_pImpl->flushClipboard( );
157 }
158
159 //========================================================================
160 // XClipboardEx
161 //========================================================================
162
getRenderingCapabilities()163 sal_Int8 SAL_CALL CWinClipboard::getRenderingCapabilities( ) throw( RuntimeException )
164 {
165 if ( rBHelper.bDisposed )
166 throw DisposedException( OUString::createFromAscii( "object is already disposed" ),
167 static_cast< XClipboardEx* >( this ) );
168
169 if ( NULL != m_pImpl.get( ) )
170 return m_pImpl->getRenderingCapabilities( );
171
172 return 0;
173 }
174
175 //========================================================================
176 // XClipboardNotifier
177 //========================================================================
178
179 //------------------------------------------------------------------------
180 // getName
181 //------------------------------------------------------------------------
182
addClipboardListener(const Reference<XClipboardListener> & listener)183 void SAL_CALL CWinClipboard::addClipboardListener( const Reference< XClipboardListener >& listener )
184 throw( RuntimeException )
185 {
186 if ( rBHelper.bDisposed )
187 throw DisposedException( OUString::createFromAscii( "object is already disposed" ),
188 static_cast< XClipboardEx* >( this ) );
189
190 // check input parameter
191 if ( !listener.is( ) )
192 throw IllegalArgumentException( OUString::createFromAscii( "empty reference" ),
193 static_cast< XClipboardEx* >( this ),
194 1 );
195
196 rBHelper.aLC.addInterface( getCppuType( &listener ), listener );
197 }
198
199 //------------------------------------------------------------------------
200 // getName
201 //------------------------------------------------------------------------
202
removeClipboardListener(const Reference<XClipboardListener> & listener)203 void SAL_CALL CWinClipboard::removeClipboardListener( const Reference< XClipboardListener >& listener )
204 throw( RuntimeException )
205 {
206 if ( rBHelper.bDisposed )
207 throw DisposedException( OUString::createFromAscii( "object is already disposed" ),
208 static_cast< XClipboardEx* >( this ) );
209
210 // check input parameter
211 if ( !listener.is( ) )
212 throw IllegalArgumentException( OUString::createFromAscii( "empty reference" ),
213 static_cast< XClipboardEx* >( this ),
214 1 );
215
216 rBHelper.aLC.removeInterface( getCppuType( &listener ), listener );
217 }
218
219 //------------------------------------------------------------------------
220 // getName
221 //------------------------------------------------------------------------
222
notifyAllClipboardListener()223 void SAL_CALL CWinClipboard::notifyAllClipboardListener( )
224 {
225 if ( !rBHelper.bDisposed )
226 {
227 ClearableMutexGuard aGuard( rBHelper.rMutex );
228 if ( !rBHelper.bDisposed )
229 {
230 aGuard.clear( );
231
232 OInterfaceContainerHelper* pICHelper = rBHelper.aLC.getContainer(
233 getCppuType( ( Reference< XClipboardListener > * ) 0 ) );
234
235 if ( pICHelper )
236 {
237 try
238 {
239 OInterfaceIteratorHelper iter(*pICHelper);
240 Reference<XTransferable> rXTransf(m_pImpl->getContents());
241 ClipboardEvent aClipbEvent(static_cast<XClipboard*>(this), rXTransf);
242
243 while(iter.hasMoreElements())
244 {
245 try
246 {
247 Reference<XClipboardListener> xCBListener(iter.next(), UNO_QUERY);
248 if (xCBListener.is())
249 xCBListener->changedContents(aClipbEvent);
250 }
251 catch(RuntimeException&)
252 {
253 OSL_ENSURE( false, "RuntimeException caught" );
254 }
255 }
256 }
257 catch(const ::com::sun::star::lang::DisposedException&)
258 {
259 OSL_ENSURE(false, "Service Manager disposed");
260
261 // no further clipboard changed notifications
262 m_pImpl->unregisterClipboardViewer();
263 }
264
265 } // end if
266 } // end if
267 } // end if
268 }
269
270 //------------------------------------------------
271 // overwritten base class method which will be
272 // called by the base class dispose method
273 //------------------------------------------------
274
disposing()275 void SAL_CALL CWinClipboard::disposing()
276 {
277 // do my own stuff
278 m_pImpl->dispose( );
279
280 // force destruction of the impl class
281 m_pImpl.reset();
282 }
283
284 // -------------------------------------------------
285 // XServiceInfo
286 // -------------------------------------------------
287
getImplementationName()288 OUString SAL_CALL CWinClipboard::getImplementationName( )
289 throw(RuntimeException)
290 {
291 return OUString::createFromAscii( WINCLIPBOARD_IMPL_NAME );
292 }
293
294 // -------------------------------------------------
295 // XServiceInfo
296 // -------------------------------------------------
297
supportsService(const OUString & ServiceName)298 sal_Bool SAL_CALL CWinClipboard::supportsService( const OUString& ServiceName )
299 throw(RuntimeException)
300 {
301 Sequence < OUString > SupportedServicesNames = WinClipboard_getSupportedServiceNames();
302
303 for ( sal_Int32 n = SupportedServicesNames.getLength(); n--; )
304 if (SupportedServicesNames[n].compareTo(ServiceName) == 0)
305 return sal_True;
306
307 return sal_False;
308 }
309
310 // -------------------------------------------------
311 // XServiceInfo
312 // -------------------------------------------------
313
getSupportedServiceNames()314 Sequence< OUString > SAL_CALL CWinClipboard::getSupportedServiceNames( )
315 throw(RuntimeException)
316 {
317 return WinClipboard_getSupportedServiceNames();
318 }
319