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 ) throw(RuntimeException);
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 throw(RuntimeException)
132 {
133 m_nReceivedLostOwnerships++;
134 m_xClipboard = xClipboard;
135 m_xTransferable = xTrans;
136 }
137
138 //------------------------------------------------------------------------
139 // ClipboardListener
140 //------------------------------------------------------------------------
141
142 class ClipboardListener : public WeakImplHelper1< XClipboardListener >
143 {
144 Reference< XClipboard > m_xClipboard;
145 Reference< XTransferable > m_xTransferable;
146
147 sal_uInt32 m_nReceivedChangedContentsEvents;
148
149 public:
150 ClipboardListener();
151
152 //--------------------------------------------------------------------
153 // XClipboardOwner
154 //--------------------------------------------------------------------
155
156 virtual void SAL_CALL changedContents( const ClipboardEvent& event ) throw(RuntimeException);
157
158 //--------------------------------------------------------------------
159 // XEventListener
160 //--------------------------------------------------------------------
161
162 virtual void SAL_CALL disposing( const EventObject& event ) throw(RuntimeException);
163
receivedChangedContentsEvents()164 sal_uInt32 receivedChangedContentsEvents() { return m_nReceivedChangedContentsEvents; };
changedContentsEventClipboardValue()165 Reference< XClipboard > changedContentsEventClipboardValue() { return m_xClipboard; }
changedContentsEventTransferableValue()166 Reference< XTransferable > changedContentsEventTransferableValue() { return m_xTransferable; };
167 };
168
169 //------------------------------------------------------------------------
170 // ctor
171 //------------------------------------------------------------------------
172
ClipboardListener()173 ClipboardListener::ClipboardListener():
174 m_nReceivedChangedContentsEvents( 0 )
175 {
176 }
177
178 //------------------------------------------------------------------------
179 // changedContents
180 //------------------------------------------------------------------------
181
changedContents(const ClipboardEvent & event)182 void SAL_CALL ClipboardListener::changedContents( const ClipboardEvent& event )
183 throw(RuntimeException)
184 {
185 m_nReceivedChangedContentsEvents++;
186 m_xClipboard = Reference< XClipboard > (event.Source, UNO_QUERY);
187 m_xTransferable = event.Contents;
188 }
189
190 //------------------------------------------------------------------------
191 // disposing
192 //------------------------------------------------------------------------
193
disposing(const EventObject & event)194 void SAL_CALL ClipboardListener::disposing( const EventObject& event )
195 throw(RuntimeException)
196 {
197 }
198
199 //------------------------------------------------------------------------
200 // StringTransferable
201 //------------------------------------------------------------------------
202
203 class StringTransferable : public WeakImplHelper2< XClipboardOwner, XTransferable >
204 {
205 public:
206 StringTransferable( );
207
208 //--------------------------------------------------------------------
209 // XTransferable
210 //--------------------------------------------------------------------
211
212 virtual Any SAL_CALL getTransferData( const DataFlavor& aFlavor ) throw(UnsupportedFlavorException, IOException, RuntimeException);
213 virtual Sequence< DataFlavor > SAL_CALL getTransferDataFlavors( ) throw(RuntimeException);
214 virtual sal_Bool SAL_CALL isDataFlavorSupported( const DataFlavor& aFlavor ) throw(RuntimeException);
215
216 //--------------------------------------------------------------------
217 // XClipboardOwner
218 //--------------------------------------------------------------------
219
220 virtual void SAL_CALL lostOwnership( const Reference< XClipboard >& xClipboard, const Reference< XTransferable >& xTrans ) throw(RuntimeException);
221
receivedLostOwnership()222 sal_Bool receivedLostOwnership() { return m_receivedLostOwnership; };
clearReceivedLostOwnership()223 void clearReceivedLostOwnership() { m_receivedLostOwnership = sal_False; };
224
225 private:
226 Sequence< DataFlavor > m_seqDFlv;
227 OUString m_Data;
228 sal_Bool m_receivedLostOwnership;
229 };
230
231 //------------------------------------------------------------------------
232 // ctor
233 //------------------------------------------------------------------------
234
StringTransferable()235 StringTransferable::StringTransferable( ) :
236 m_seqDFlv( 1 ),
237 m_receivedLostOwnership( sal_False ),
238 m_Data( OUString::createFromAscii("clipboard test content") )
239 {
240 DataFlavor df;
241
242 /*
243 df.MimeType = L"text/plain; charset=unicode";
244 df.DataType = getCppuType( ( OUString* )0 );
245
246 m_seqDFlv[0] = df;
247 */
248
249 //df.MimeType = L"text/plain; charset=windows1252";
250 df.MimeType = OUString::createFromAscii( "text/html" );
251 df.DataType = getCppuType( ( Sequence< sal_Int8 >* )0 );
252
253 m_seqDFlv[0] = df;
254 }
255
256 //------------------------------------------------------------------------
257 // getTransferData
258 //------------------------------------------------------------------------
259
getTransferData(const DataFlavor & aFlavor)260 Any SAL_CALL StringTransferable::getTransferData( const DataFlavor& aFlavor )
261 throw(UnsupportedFlavorException, IOException, RuntimeException)
262 {
263 Any anyData;
264
265 /*if ( aFlavor == m_seqDFlv[0] )
266 {
267 anyData = makeAny( m_Data );
268 } */
269 #if 0
270 else if ( aFlavor == m_seqDFlv[0] )
271 {
272 OString aStr( m_Data.getStr( ), m_Data.getLength( ), 1252 );
273 Sequence< sal_Int8 > sOfChars( aStr.getLength( ) );
274 sal_Int32 lenStr = aStr.getLength( );
275
276 for ( sal_Int32 i = 0; i < lenStr; ++i )
277 sOfChars[i] = aStr[i];
278
279 anyData = makeAny( sOfChars );
280 }
281 #endif
282
283 return anyData;
284 }
285
286 //------------------------------------------------------------------------
287 // getTransferDataFlavors
288 //------------------------------------------------------------------------
289
getTransferDataFlavors()290 Sequence< DataFlavor > SAL_CALL StringTransferable::getTransferDataFlavors( )
291 throw(RuntimeException)
292 {
293 return m_seqDFlv;
294 }
295
296 //------------------------------------------------------------------------
297 // isDataFlavorSupported
298 //------------------------------------------------------------------------
299
isDataFlavorSupported(const DataFlavor & aFlavor)300 sal_Bool SAL_CALL StringTransferable::isDataFlavorSupported( const DataFlavor& aFlavor )
301 throw(RuntimeException)
302 {
303 sal_Int32 nLength = m_seqDFlv.getLength( );
304 sal_Bool bRet = sal_False;
305
306 // for ( sal_Int32 i = 0; i < nLength; ++i )
307 // {
308 // if ( m_seqDFlv[i] == aFlavor )
309 // {
310 // bRet = sal_True;
311 // break;
312 // }
313 // }
314
315 return bRet;
316 }
317
318 //------------------------------------------------------------------------
319 // lostOwnership
320 //------------------------------------------------------------------------
321
lostOwnership(const Reference<XClipboard> & xClipboard,const Reference<XTransferable> & xTrans)322 void SAL_CALL StringTransferable::lostOwnership( const Reference< XClipboard >& xClipboard, const Reference< XTransferable >& xTrans )
323 throw(RuntimeException)
324 {
325 m_receivedLostOwnership = sal_True;
326 }
327
328 //------------------------------------------------------------------------
329 // main
330 //------------------------------------------------------------------------
331
main(int argc,const char * argv[])332 int SAL_CALL main( int argc, const char* argv[] )
333 {
334 OUString aRegistry;
335
336 //------------------------------------------------------------------
337 // check command line parameters
338 //------------------------------------------------------------------
339
340 if ( NULL == ( app = strrchr( argv[0], PATH_SEPERATOR ) ) )
341 app = argv[0];
342 else
343 app++;
344
345 for( int n = 1; n < argc; n++ )
346 {
347 if( strncmp( argv[n], "-r", 2 ) == 0 )
348 {
349 if( strlen( argv[n] ) > 2 )
350 aRegistry = OUString::createFromAscii( argv[n] + 2 );
351 else if ( n + 1 < argc )
352 aRegistry = OUString::createFromAscii( argv[++n] );
353 }
354 }
355
356 if( aRegistry.getLength() == 0 )
357 fprintf( stderr, "Usage: %s -r full-path-to-applicat.rdb\n", app );
358
359 //------------------------------------------------------------------
360 // create service manager
361 //------------------------------------------------------------------
362 Reference< XMultiServiceFactory > xServiceManager;
363
364 try
365 {
366 xServiceManager = createRegistryServiceFactory( aRegistry, sal_True );
367 ENSURE( xServiceManager.is(), "*** ERROR *** service manager could not be created." );
368
369 //--------------------------------------------------------------
370 // create an instance of GenericClipboard service
371 //--------------------------------------------------------------
372
373 Sequence< Any > arguments(1);
374 arguments[0] = makeAny( OUString::createFromAscii( "generic" ) );
375
376 Reference< XClipboard > xClipboard( xServiceManager->createInstanceWithArguments(
377 OUString::createFromAscii( "com.sun.star.datatransfer.clipboard.GenericClipboard" ),
378 arguments ), UNO_QUERY );
379
380 ENSURE( xClipboard.is(), "*** ERROR *** generic clipboard service could not be created." );
381
382 Reference< XClipboardNotifier > xClipboardNotifier( xClipboard, UNO_QUERY );
383 Reference< XClipboardListener > xClipboardListener = new ClipboardListener();
384 ClipboardListener * pListener = (ClipboardListener *) xClipboardListener.get();
385
386 if( xClipboardNotifier.is() )
387 xClipboardNotifier->addClipboardListener( xClipboardListener );
388
389 //--------------------------------------------------------------
390 // run various tests on clipboard implementation
391 //--------------------------------------------------------------
392
393 TRACE( "\n*** testing generic clipboard service ***\n" );
394
395 Reference< XTransferable > xContents = new StringTransferable();
396 Reference< XClipboardOwner > xOwner = new ClipboardOwner();
397 ClipboardOwner *pOwner = (ClipboardOwner *) xOwner.get();
398
399 TEST( "initial contents (none): ", xClipboard->getContents().is() == sal_False );
400
401 PERFORM( "update on contents with clipboard owner: ", xClipboard->setContents( xContents, xOwner ) );
402 TEST( "current clipboard contents: ", xContents == xClipboard->getContents() );
403
404 if( xClipboardNotifier.is() )
405 {
406 TEST( "if received changedContents notifications: ", pListener->receivedChangedContentsEvents() > 0 );
407 TEST( "if received exactly 1 changedContents notification: ", pListener->receivedChangedContentsEvents() == 1 );
408 TEST( "if received changedContents notification for correct clipboard: ", pListener->changedContentsEventClipboardValue() == xClipboard );
409 TEST( "if received changedContents notification for correct clipboard: ", pListener->changedContentsEventTransferableValue() == xContents );
410 }
411
412 PERFORM( "update on contents without data (clear): ", xClipboard->setContents( Reference< XTransferable >(), Reference< XClipboardOwner >() ) );
413 TEST( "if received lostOwnership message(s): ", pOwner->receivedLostOwnerships() > 0 );
414 TEST( "if received exactly 1 lostOwnership message: ", pOwner->receivedLostOwnerships() == 1 );
415 TEST( "if received lostOwnership message for the correct clipboard: ", pOwner->lostOwnershipClipboardValue() == xClipboard );
416 TEST( "if received lostOwnership message for the correct transferable: ", pOwner->lostOwnershipTransferableValue() == xContents );
417 TEST( "current clipboard contents (none): ", xClipboard->getContents().is() == sal_False );
418
419 if( xClipboardNotifier.is() )
420 {
421 TEST( "if received changedContents notifications: ", pListener->receivedChangedContentsEvents() > 1 );
422 TEST( "if received exactly 1 changedContents notification: ", pListener->receivedChangedContentsEvents() == 2 );
423 TEST( "if received changedContents notification for correct clipboard: ", pListener->changedContentsEventClipboardValue() == xClipboard );
424 TEST( "if received changedContents notification for correct transferable: ", ! pListener->changedContentsEventTransferableValue().is() );
425 }
426
427 PERFORM( "update on contents without clipboard owner: ", xClipboard->setContents( xContents, Reference< XClipboardOwner >() ) );
428 TEST( "that no further lostOwnership messages were received: ", pOwner->receivedLostOwnerships() == 1 );
429 TEST( "current clipboard contents: ", xContents == xClipboard->getContents() );
430
431 if( xClipboardNotifier.is() )
432 {
433 TEST( "if received changedContents notifications: ", pListener->receivedChangedContentsEvents() > 2 );
434 TEST( "if received exactly 1 changedContents notification: ", pListener->receivedChangedContentsEvents() == 3 );
435 TEST( "if received changedContents notification for correct clipboard: ", pListener->changedContentsEventClipboardValue() == xClipboard );
436 TEST( "if received changedContents notification for correct transferable: ", pListener->changedContentsEventTransferableValue() == xContents );
437 }
438
439
440 PERFORM( "update on contents without data (clear): ", xClipboard->setContents( Reference< XTransferable >(), Reference< XClipboardOwner >() ) );
441 TEST( "that no further lostOwnership messages were received: ", pOwner->receivedLostOwnerships() == 1 );
442 TEST( "current clipboard contents (none): ", xClipboard->getContents().is() == sal_False );
443
444 if( xClipboardNotifier.is() )
445 {
446 TEST( "if received changedContents notifications: ", pListener->receivedChangedContentsEvents() > 3 );
447 TEST( "if received exactly 1 changedContents notification: ", pListener->receivedChangedContentsEvents() == 4 );
448 TEST( "if received changedContents notification for correct clipboard: ", pListener->changedContentsEventClipboardValue() == xClipboard );
449 TEST( "if received changedContents notification for correct transferable: ", ! pListener->changedContentsEventTransferableValue().is() );
450 }
451
452 //--------------------------------------------------------------
453 // create an instance of ClipboardManager service
454 //--------------------------------------------------------------
455
456 Reference< XClipboardManager > xClipboardManager( xServiceManager->createInstance(
457 OUString::createFromAscii( "com.sun.star.datatransfer.clipboard.ClipboardManager" ) ), UNO_QUERY );
458
459 ENSURE( xClipboardManager.is(), "*** ERROR *** clipboard manager service could not be created." );
460
461 //--------------------------------------------------------------
462 // run various tests on clipboard manager implementation
463 //--------------------------------------------------------------
464
465 TRACE( "\n*** testing clipboard manager service ***\n" );
466
467 TEST( "initial number of clipboards (0): ", xClipboardManager->listClipboardNames().getLength() == 0 );
468 PERFORM( "insertion of generic clipboard: ", xClipboardManager->addClipboard( xClipboard ) );
469 TEST( "number of inserted clipboards (1): ", xClipboardManager->listClipboardNames().getLength() == 1 );
470 TEST( "name of inserted clipboard (generic): ", xClipboardManager->listClipboardNames()[0] == OUString::createFromAscii( "generic" ) );
471 TEST( "inserted clipboard instance: ", xClipboardManager->getClipboard( OUString::createFromAscii( "generic" ) ) == xClipboard );
472 PERFORM( "removal of generic clipboard: ", xClipboardManager->removeClipboard( OUString::createFromAscii( "generic" ) ) );
473 TEST( "number of inserted clipboards (0): ", xClipboardManager->listClipboardNames().getLength() == 0 );
474 TRACE( "Testing inserted clipboard instance (none): " );
475 try
476 {
477 xClipboardManager->getClipboard( OUString::createFromAscii( "generic" ) );
478 TRACE( "FAILED\n" );
479 }
480 catch( NoSuchElementException e )
481 {
482 TRACE( "passed\n" );
483 }
484 }
485
486 catch ( Exception aException )
487 {
488 ENSURE( sal_False, "*** ERROR *** exception caught." );
489 }
490
491 //--------------------------------------------------------------------
492 // shutdown the service manager
493 //--------------------------------------------------------------------
494
495 // query XComponent interface
496 Reference< XComponent > xComponent( xServiceManager, UNO_QUERY );
497
498 ENSURE( xComponent.is(), "*** ERROR *** service manager does not support XComponent." );
499
500 // Dispose and clear factory
501 xComponent->dispose();
502 xServiceManager.clear();
503
504 fprintf( stderr, "Done.\n" );
505 return 0;
506 }
507
508
509