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 //------------------------------------------------------------------------
29 // interface includes
30 //------------------------------------------------------------------------
31 #include <com/sun/star/datatransfer/XTransferable.hpp>
32 #include <com/sun/star/datatransfer/clipboard/XClipboardManager.hpp>
33 #include <com/sun/star/datatransfer/clipboard/XClipboardOwner.hpp>
34 #include <com/sun/star/datatransfer/clipboard/XClipboardNotifier.hpp>
35 #include <com/sun/star/datatransfer/clipboard/XClipboardEx.hpp>
36 #include <com/sun/star/lang/XComponent.hpp>
37
38 //------------------------------------------------------------------------
39 // other includes
40 //------------------------------------------------------------------------
41
42
43 #include <cppuhelper/servicefactory.hxx>
44 #include <cppuhelper/implbase1.hxx>
45 #include <cppuhelper/implbase2.hxx>
46 #include <rtl/ustring.hxx>
47 #include <osl/diagnose.h>
48
49 #include <stdlib.h>
50 #include <stdio.h>
51 #include <string.h>
52
53 //#include <memory>
54
55 //#include <process.h>
56
57 //------------------------------------------------------------------------
58 // my defines
59 //------------------------------------------------------------------------
60
61 #ifdef UNX
62 #define PATH_SEPERATOR '/'
63 #else
64 #define PATH_SEPERATOR '\\'
65 #endif
66
67 #define ENSURE( a, b ) if( !a ) { fprintf( stderr, b "\n" ); exit( -1 ); }
68 #define TEST( a, b ) fprintf( stderr, "Testing " a ); fprintf( stderr, b ? "passed\n" : "FAILED\n" )
69 #define PERFORM( a, b ) fprintf( stderr, "Performing " a); b; fprintf( stderr, "done\n" )
70 #define TRACE( a ) fprintf( stderr, a )
71
72 //------------------------------------------------------------------------
73 // namespaces
74 //------------------------------------------------------------------------
75
76 using namespace ::rtl;
77 using namespace ::std;
78 using namespace ::cppu;
79 using namespace ::com::sun::star::container;
80 using namespace ::com::sun::star::datatransfer;
81 using namespace ::com::sun::star::datatransfer::clipboard;
82 using namespace ::com::sun::star::uno;
83 using namespace ::com::sun::star::io;
84 using namespace ::com::sun::star::lang;
85
86 //------------------------------------------------------------------------
87 // globals
88 //------------------------------------------------------------------------
89
90 const char * app = NULL;
91
92 //------------------------------------------------------------------------
93 // ClipboardOwner
94 //------------------------------------------------------------------------
95
96 class ClipboardOwner : public WeakImplHelper1< XClipboardOwner >
97 {
98 Reference< XClipboard > m_xClipboard;
99 Reference< XTransferable > m_xTransferable;
100
101 sal_uInt32 m_nReceivedLostOwnerships;
102
103 public:
104 ClipboardOwner();
105
106 //--------------------------------------------------------------------
107 // XClipboardOwner
108 //--------------------------------------------------------------------
109
110 virtual void SAL_CALL lostOwnership( const Reference< XClipboard >& xClipboard, const Reference< XTransferable >& xTrans );
111
receivedLostOwnerships()112 sal_uInt32 receivedLostOwnerships() { return m_nReceivedLostOwnerships; };
lostOwnershipClipboardValue()113 Reference< XClipboard > lostOwnershipClipboardValue() { return m_xClipboard; }
lostOwnershipTransferableValue()114 Reference< XTransferable > lostOwnershipTransferableValue() { return m_xTransferable; };
115 };
116
117 //------------------------------------------------------------------------
118 // ctor
119 //------------------------------------------------------------------------
120
ClipboardOwner()121 ClipboardOwner::ClipboardOwner():
122 m_nReceivedLostOwnerships( 0 )
123 {
124 }
125
126 //------------------------------------------------------------------------
127 // lostOwnership
128 //------------------------------------------------------------------------
129
lostOwnership(const Reference<XClipboard> & xClipboard,const Reference<XTransferable> & xTrans)130 void SAL_CALL ClipboardOwner::lostOwnership( const Reference< XClipboard >& xClipboard, const Reference< XTransferable >& xTrans )
131 {
132 m_nReceivedLostOwnerships++;
133 m_xClipboard = xClipboard;
134 m_xTransferable = xTrans;
135 }
136
137 //------------------------------------------------------------------------
138 // ClipboardListener
139 //------------------------------------------------------------------------
140
141 class ClipboardListener : public WeakImplHelper1< XClipboardListener >
142 {
143 Reference< XClipboard > m_xClipboard;
144 Reference< XTransferable > m_xTransferable;
145
146 sal_uInt32 m_nReceivedChangedContentsEvents;
147
148 public:
149 ClipboardListener();
150
151 //--------------------------------------------------------------------
152 // XClipboardOwner
153 //--------------------------------------------------------------------
154
155 virtual void SAL_CALL changedContents( const ClipboardEvent& event );
156
157 //--------------------------------------------------------------------
158 // XEventListener
159 //--------------------------------------------------------------------
160
161 virtual void SAL_CALL disposing( const EventObject& event );
162
receivedChangedContentsEvents()163 sal_uInt32 receivedChangedContentsEvents() { return m_nReceivedChangedContentsEvents; };
changedContentsEventClipboardValue()164 Reference< XClipboard > changedContentsEventClipboardValue() { return m_xClipboard; }
changedContentsEventTransferableValue()165 Reference< XTransferable > changedContentsEventTransferableValue() { return m_xTransferable; };
166 };
167
168 //------------------------------------------------------------------------
169 // ctor
170 //------------------------------------------------------------------------
171
ClipboardListener()172 ClipboardListener::ClipboardListener():
173 m_nReceivedChangedContentsEvents( 0 )
174 {
175 }
176
177 //------------------------------------------------------------------------
178 // changedContents
179 //------------------------------------------------------------------------
180
changedContents(const ClipboardEvent & event)181 void SAL_CALL ClipboardListener::changedContents( const ClipboardEvent& event )
182 {
183 m_nReceivedChangedContentsEvents++;
184 m_xClipboard = Reference< XClipboard > (event.Source, UNO_QUERY);
185 m_xTransferable = event.Contents;
186 }
187
188 //------------------------------------------------------------------------
189 // disposing
190 //------------------------------------------------------------------------
191
disposing(const EventObject & event)192 void SAL_CALL ClipboardListener::disposing( const EventObject& event )
193 {
194 }
195
196 //------------------------------------------------------------------------
197 // StringTransferable
198 //------------------------------------------------------------------------
199
200 class StringTransferable : public WeakImplHelper2< XClipboardOwner, XTransferable >
201 {
202 public:
203 StringTransferable( );
204
205 //--------------------------------------------------------------------
206 // XTransferable
207 //--------------------------------------------------------------------
208
209 virtual Any SAL_CALL getTransferData( const DataFlavor& aFlavor );
210 virtual Sequence< DataFlavor > SAL_CALL getTransferDataFlavors( );
211 virtual sal_Bool SAL_CALL isDataFlavorSupported( const DataFlavor& aFlavor );
212
213 //--------------------------------------------------------------------
214 // XClipboardOwner
215 //--------------------------------------------------------------------
216
217 virtual void SAL_CALL lostOwnership( const Reference< XClipboard >& xClipboard, const Reference< XTransferable >& xTrans );
218
receivedLostOwnership()219 sal_Bool receivedLostOwnership() { return m_receivedLostOwnership; };
clearReceivedLostOwnership()220 void clearReceivedLostOwnership() { m_receivedLostOwnership = sal_False; };
221
222 private:
223 Sequence< DataFlavor > m_seqDFlv;
224 OUString m_Data;
225 sal_Bool m_receivedLostOwnership;
226 };
227
228 //------------------------------------------------------------------------
229 // ctor
230 //------------------------------------------------------------------------
231
StringTransferable()232 StringTransferable::StringTransferable( ) :
233 m_seqDFlv( 1 ),
234 m_receivedLostOwnership( sal_False ),
235 m_Data( OUString::createFromAscii("clipboard test content") )
236 {
237 DataFlavor df;
238
239 /*
240 df.MimeType = L"text/plain; charset=unicode";
241 df.DataType = getCppuType( ( OUString* )0 );
242
243 m_seqDFlv[0] = df;
244 */
245
246 //df.MimeType = L"text/plain; charset=windows1252";
247 df.MimeType = OUString::createFromAscii( "text/html" );
248 df.DataType = getCppuType( ( Sequence< sal_Int8 >* )0 );
249
250 m_seqDFlv[0] = df;
251 }
252
253 //------------------------------------------------------------------------
254 // getTransferData
255 //------------------------------------------------------------------------
256
getTransferData(const DataFlavor & aFlavor)257 Any SAL_CALL StringTransferable::getTransferData( const DataFlavor& aFlavor )
258 {
259 Any anyData;
260
261 /*if ( aFlavor == m_seqDFlv[0] )
262 {
263 anyData = makeAny( m_Data );
264 } */
265 #if 0
266 else if ( aFlavor == m_seqDFlv[0] )
267 {
268 OString aStr( m_Data.getStr( ), m_Data.getLength( ), 1252 );
269 Sequence< sal_Int8 > sOfChars( aStr.getLength( ) );
270 sal_Int32 lenStr = aStr.getLength( );
271
272 for ( sal_Int32 i = 0; i < lenStr; ++i )
273 sOfChars[i] = aStr[i];
274
275 anyData = makeAny( sOfChars );
276 }
277 #endif
278
279 return anyData;
280 }
281
282 //------------------------------------------------------------------------
283 // getTransferDataFlavors
284 //------------------------------------------------------------------------
285
getTransferDataFlavors()286 Sequence< DataFlavor > SAL_CALL StringTransferable::getTransferDataFlavors( )
287 {
288 return m_seqDFlv;
289 }
290
291 //------------------------------------------------------------------------
292 // isDataFlavorSupported
293 //------------------------------------------------------------------------
294
isDataFlavorSupported(const DataFlavor & aFlavor)295 sal_Bool SAL_CALL StringTransferable::isDataFlavorSupported( const DataFlavor& aFlavor )
296 {
297 sal_Int32 nLength = m_seqDFlv.getLength( );
298 sal_Bool bRet = sal_False;
299
300 // for ( sal_Int32 i = 0; i < nLength; ++i )
301 // {
302 // if ( m_seqDFlv[i] == aFlavor )
303 // {
304 // bRet = sal_True;
305 // break;
306 // }
307 // }
308
309 return bRet;
310 }
311
312 //------------------------------------------------------------------------
313 // lostOwnership
314 //------------------------------------------------------------------------
315
lostOwnership(const Reference<XClipboard> & xClipboard,const Reference<XTransferable> & xTrans)316 void SAL_CALL StringTransferable::lostOwnership( const Reference< XClipboard >& xClipboard, const Reference< XTransferable >& xTrans )
317 {
318 m_receivedLostOwnership = sal_True;
319 }
320
321 //------------------------------------------------------------------------
322 // main
323 //------------------------------------------------------------------------
324
main(int argc,const char * argv[])325 int SAL_CALL main( int argc, const char* argv[] )
326 {
327 OUString aRegistry;
328
329 //------------------------------------------------------------------
330 // check command line parameters
331 //------------------------------------------------------------------
332
333 if ( NULL == ( app = strrchr( argv[0], PATH_SEPERATOR ) ) )
334 app = argv[0];
335 else
336 app++;
337
338 for( int n = 1; n < argc; n++ )
339 {
340 if( strncmp( argv[n], "-r", 2 ) == 0 )
341 {
342 if( strlen( argv[n] ) > 2 )
343 aRegistry = OUString::createFromAscii( argv[n] + 2 );
344 else if ( n + 1 < argc )
345 aRegistry = OUString::createFromAscii( argv[++n] );
346 }
347 }
348
349 if( aRegistry.getLength() == 0 )
350 fprintf( stderr, "Usage: %s -r full-path-to-applicat.rdb\n", app );
351
352 //------------------------------------------------------------------
353 // create service manager
354 //------------------------------------------------------------------
355 Reference< XMultiServiceFactory > xServiceManager;
356
357 try
358 {
359 xServiceManager = createRegistryServiceFactory( aRegistry, sal_True );
360 ENSURE( xServiceManager.is(), "*** ERROR *** service manager could not be created." );
361
362 //--------------------------------------------------------------
363 // create an instance of GenericClipboard service
364 //--------------------------------------------------------------
365
366 Sequence< Any > arguments(1);
367 arguments[0] = makeAny( OUString::createFromAscii( "generic" ) );
368
369 Reference< XClipboard > xClipboard( xServiceManager->createInstanceWithArguments(
370 OUString::createFromAscii( "com.sun.star.datatransfer.clipboard.GenericClipboard" ),
371 arguments ), UNO_QUERY );
372
373 ENSURE( xClipboard.is(), "*** ERROR *** generic clipboard service could not be created." );
374
375 Reference< XClipboardNotifier > xClipboardNotifier( xClipboard, UNO_QUERY );
376 Reference< XClipboardListener > xClipboardListener = new ClipboardListener();
377 ClipboardListener * pListener = (ClipboardListener *) xClipboardListener.get();
378
379 if( xClipboardNotifier.is() )
380 xClipboardNotifier->addClipboardListener( xClipboardListener );
381
382 //--------------------------------------------------------------
383 // run various tests on clipboard implementation
384 //--------------------------------------------------------------
385
386 TRACE( "\n*** testing generic clipboard service ***\n" );
387
388 Reference< XTransferable > xContents = new StringTransferable();
389 Reference< XClipboardOwner > xOwner = new ClipboardOwner();
390 ClipboardOwner *pOwner = (ClipboardOwner *) xOwner.get();
391
392 TEST( "initial contents (none): ", xClipboard->getContents().is() == sal_False );
393
394 PERFORM( "update on contents with clipboard owner: ", xClipboard->setContents( xContents, xOwner ) );
395 TEST( "current clipboard contents: ", xContents == xClipboard->getContents() );
396
397 if( xClipboardNotifier.is() )
398 {
399 TEST( "if received changedContents notifications: ", pListener->receivedChangedContentsEvents() > 0 );
400 TEST( "if received exactly 1 changedContents notification: ", pListener->receivedChangedContentsEvents() == 1 );
401 TEST( "if received changedContents notification for correct clipboard: ", pListener->changedContentsEventClipboardValue() == xClipboard );
402 TEST( "if received changedContents notification for correct clipboard: ", pListener->changedContentsEventTransferableValue() == xContents );
403 }
404
405 PERFORM( "update on contents without data (clear): ", xClipboard->setContents( Reference< XTransferable >(), Reference< XClipboardOwner >() ) );
406 TEST( "if received lostOwnership message(s): ", pOwner->receivedLostOwnerships() > 0 );
407 TEST( "if received exactly 1 lostOwnership message: ", pOwner->receivedLostOwnerships() == 1 );
408 TEST( "if received lostOwnership message for the correct clipboard: ", pOwner->lostOwnershipClipboardValue() == xClipboard );
409 TEST( "if received lostOwnership message for the correct transferable: ", pOwner->lostOwnershipTransferableValue() == xContents );
410 TEST( "current clipboard contents (none): ", xClipboard->getContents().is() == sal_False );
411
412 if( xClipboardNotifier.is() )
413 {
414 TEST( "if received changedContents notifications: ", pListener->receivedChangedContentsEvents() > 1 );
415 TEST( "if received exactly 1 changedContents notification: ", pListener->receivedChangedContentsEvents() == 2 );
416 TEST( "if received changedContents notification for correct clipboard: ", pListener->changedContentsEventClipboardValue() == xClipboard );
417 TEST( "if received changedContents notification for correct transferable: ", ! pListener->changedContentsEventTransferableValue().is() );
418 }
419
420 PERFORM( "update on contents without clipboard owner: ", xClipboard->setContents( xContents, Reference< XClipboardOwner >() ) );
421 TEST( "that no further lostOwnership messages were received: ", pOwner->receivedLostOwnerships() == 1 );
422 TEST( "current clipboard contents: ", xContents == xClipboard->getContents() );
423
424 if( xClipboardNotifier.is() )
425 {
426 TEST( "if received changedContents notifications: ", pListener->receivedChangedContentsEvents() > 2 );
427 TEST( "if received exactly 1 changedContents notification: ", pListener->receivedChangedContentsEvents() == 3 );
428 TEST( "if received changedContents notification for correct clipboard: ", pListener->changedContentsEventClipboardValue() == xClipboard );
429 TEST( "if received changedContents notification for correct transferable: ", pListener->changedContentsEventTransferableValue() == xContents );
430 }
431
432
433 PERFORM( "update on contents without data (clear): ", xClipboard->setContents( Reference< XTransferable >(), Reference< XClipboardOwner >() ) );
434 TEST( "that no further lostOwnership messages were received: ", pOwner->receivedLostOwnerships() == 1 );
435 TEST( "current clipboard contents (none): ", xClipboard->getContents().is() == sal_False );
436
437 if( xClipboardNotifier.is() )
438 {
439 TEST( "if received changedContents notifications: ", pListener->receivedChangedContentsEvents() > 3 );
440 TEST( "if received exactly 1 changedContents notification: ", pListener->receivedChangedContentsEvents() == 4 );
441 TEST( "if received changedContents notification for correct clipboard: ", pListener->changedContentsEventClipboardValue() == xClipboard );
442 TEST( "if received changedContents notification for correct transferable: ", ! pListener->changedContentsEventTransferableValue().is() );
443 }
444
445 //--------------------------------------------------------------
446 // create an instance of ClipboardManager service
447 //--------------------------------------------------------------
448
449 Reference< XClipboardManager > xClipboardManager( xServiceManager->createInstance(
450 OUString::createFromAscii( "com.sun.star.datatransfer.clipboard.ClipboardManager" ) ), UNO_QUERY );
451
452 ENSURE( xClipboardManager.is(), "*** ERROR *** clipboard manager service could not be created." );
453
454 //--------------------------------------------------------------
455 // run various tests on clipboard manager implementation
456 //--------------------------------------------------------------
457
458 TRACE( "\n*** testing clipboard manager service ***\n" );
459
460 TEST( "initial number of clipboards (0): ", xClipboardManager->listClipboardNames().getLength() == 0 );
461 PERFORM( "insertion of generic clipboard: ", xClipboardManager->addClipboard( xClipboard ) );
462 TEST( "number of inserted clipboards (1): ", xClipboardManager->listClipboardNames().getLength() == 1 );
463 TEST( "name of inserted clipboard (generic): ", xClipboardManager->listClipboardNames()[0] == OUString::createFromAscii( "generic" ) );
464 TEST( "inserted clipboard instance: ", xClipboardManager->getClipboard( OUString::createFromAscii( "generic" ) ) == xClipboard );
465 PERFORM( "removal of generic clipboard: ", xClipboardManager->removeClipboard( OUString::createFromAscii( "generic" ) ) );
466 TEST( "number of inserted clipboards (0): ", xClipboardManager->listClipboardNames().getLength() == 0 );
467 TRACE( "Testing inserted clipboard instance (none): " );
468 try
469 {
470 xClipboardManager->getClipboard( OUString::createFromAscii( "generic" ) );
471 TRACE( "FAILED\n" );
472 }
473 catch( NoSuchElementException e )
474 {
475 TRACE( "passed\n" );
476 }
477 }
478
479 catch ( Exception aException )
480 {
481 ENSURE( sal_False, "*** ERROR *** exception caught." );
482 }
483
484 //--------------------------------------------------------------------
485 // shutdown the service manager
486 //--------------------------------------------------------------------
487
488 // query XComponent interface
489 Reference< XComponent > xComponent( xServiceManager, UNO_QUERY );
490
491 ENSURE( xComponent.is(), "*** ERROR *** service manager does not support XComponent." );
492
493 // Dispose and clear factory
494 xComponent->dispose();
495 xServiceManager.clear();
496
497 fprintf( stderr, "Done.\n" );
498 return 0;
499 }
500