xref: /AOO41X/main/dtrans/source/win32/clipb/WinClipboard.cxx (revision 3d7628264b67541a59f8a1d4df8ea02ab31c33a6)
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