1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <com/sun/star/datatransfer/XTransferable.hpp>
21 #include <com/sun/star/datatransfer/clipboard/XClipboardManager.hpp>
22 #include <com/sun/star/datatransfer/clipboard/XClipboardOwner.hpp>
23 #include <com/sun/star/datatransfer/clipboard/XClipboardNotifier.hpp>
24 #include <com/sun/star/datatransfer/clipboard/XClipboardEx.hpp>
25 #include <com/sun/star/lang/XComponent.hpp>
27 #include <cppuhelper/servicefactory.hxx>
28 #include <cppuhelper/implbase1.hxx>
29 #include <cppuhelper/implbase2.hxx>
30 #include <rtl/ustring.hxx>
31 #include <osl/diagnose.h>
40 #define PATH_SEPARATOR '/'
42 #define PATH_SEPARATOR '\\'
45 #define ENSURE( a, b ) if( !a ) { fprintf( stderr, b "\n" ); exit( -1 ); }
46 #define TEST( a, b ) fprintf( stderr, "Testing " a ); fprintf( stderr, b ? "passed\n" : "FAILED\n" )
47 #define PERFORM( a, b ) fprintf( stderr, "Performing " a); b; fprintf( stderr, "done\n" )
48 #define TRACE( a ) fprintf( stderr, a )
52 using namespace ::std
;
53 using namespace ::cppu
;
54 using namespace ::com::sun::star::container
;
55 using namespace ::com::sun::star::datatransfer
;
56 using namespace ::com::sun::star::datatransfer::clipboard
;
57 using namespace ::com::sun::star::uno
;
58 using namespace ::com::sun::star::io
;
59 using namespace ::com::sun::star::lang
;
63 const char * app
= NULL
;
67 class ClipboardOwner
: public WeakImplHelper1
< XClipboardOwner
>
69 Reference
< XClipboard
> m_xClipboard
;
70 Reference
< XTransferable
> m_xTransferable
;
72 sal_uInt32 m_nReceivedLostOwnerships
;
79 virtual void SAL_CALL
lostOwnership( const Reference
< XClipboard
>& xClipboard
, const Reference
< XTransferable
>& xTrans
) throw(RuntimeException
);
81 sal_uInt32
receivedLostOwnerships() { return m_nReceivedLostOwnerships
; };
82 Reference
< XClipboard
> lostOwnershipClipboardValue() { return m_xClipboard
; }
83 Reference
< XTransferable
> lostOwnershipTransferableValue() { return m_xTransferable
; };
88 ClipboardOwner::ClipboardOwner():
89 m_nReceivedLostOwnerships( 0 )
95 void SAL_CALL
ClipboardOwner::lostOwnership( const Reference
< XClipboard
>& xClipboard
, const Reference
< XTransferable
>& xTrans
)
96 throw(RuntimeException
)
98 m_nReceivedLostOwnerships
++;
99 m_xClipboard
= xClipboard
;
100 m_xTransferable
= xTrans
;
105 class ClipboardListener
: public WeakImplHelper1
< XClipboardListener
>
107 Reference
< XClipboard
> m_xClipboard
;
108 Reference
< XTransferable
> m_xTransferable
;
110 sal_uInt32 m_nReceivedChangedContentsEvents
;
117 virtual void SAL_CALL
changedContents( const ClipboardEvent
& event
) throw(RuntimeException
);
121 virtual void SAL_CALL
disposing( const EventObject
& event
) throw(RuntimeException
);
123 sal_uInt32
receivedChangedContentsEvents() { return m_nReceivedChangedContentsEvents
; };
124 Reference
< XClipboard
> changedContentsEventClipboardValue() { return m_xClipboard
; }
125 Reference
< XTransferable
> changedContentsEventTransferableValue() { return m_xTransferable
; };
130 ClipboardListener::ClipboardListener():
131 m_nReceivedChangedContentsEvents( 0 )
137 void SAL_CALL
ClipboardListener::changedContents( const ClipboardEvent
& event
)
138 throw(RuntimeException
)
140 m_nReceivedChangedContentsEvents
++;
141 m_xClipboard
= Reference
< XClipboard
> (event
.Source
, UNO_QUERY
);
142 m_xTransferable
= event
.Contents
;
147 void SAL_CALL
ClipboardListener::disposing( const EventObject
& event
)
148 throw(RuntimeException
)
152 // StringTransferable
154 class StringTransferable
: public WeakImplHelper2
< XClipboardOwner
, XTransferable
>
157 StringTransferable( );
161 virtual Any SAL_CALL
getTransferData( const DataFlavor
& aFlavor
) throw(UnsupportedFlavorException
, IOException
, RuntimeException
);
162 virtual Sequence
< DataFlavor
> SAL_CALL
getTransferDataFlavors( ) throw(RuntimeException
);
163 virtual sal_Bool SAL_CALL
isDataFlavorSupported( const DataFlavor
& aFlavor
) throw(RuntimeException
);
167 virtual void SAL_CALL
lostOwnership( const Reference
< XClipboard
>& xClipboard
, const Reference
< XTransferable
>& xTrans
) throw(RuntimeException
);
169 sal_Bool
receivedLostOwnership() { return m_receivedLostOwnership
; };
170 void clearReceivedLostOwnership() { m_receivedLostOwnership
= sal_False
; };
173 Sequence
< DataFlavor
> m_seqDFlv
;
175 sal_Bool m_receivedLostOwnership
;
180 StringTransferable::StringTransferable( ) :
182 m_receivedLostOwnership( sal_False
),
183 m_Data( OUString("clipboard test content") )
188 df.MimeType = L"text/plain; charset=unicode";
189 df.DataType = cppu::UnoType<OUString>::get();
194 //df.MimeType = L"text/plain; charset=windows1252";
195 df
.MimeType
= "text/html";
196 df
.DataType
= cppu::UnoType
<Sequence
< sal_Int8
>>::get();
203 Any SAL_CALL
StringTransferable::getTransferData( const DataFlavor
& aFlavor
)
204 throw(UnsupportedFlavorException
, IOException
, RuntimeException
)
208 /*if ( aFlavor == m_seqDFlv[0] )
210 anyData = makeAny( m_Data );
216 // getTransferDataFlavors
218 Sequence
< DataFlavor
> SAL_CALL
StringTransferable::getTransferDataFlavors( )
219 throw(RuntimeException
)
224 // isDataFlavorSupported
226 sal_Bool SAL_CALL
StringTransferable::isDataFlavorSupported( const DataFlavor
& aFlavor
)
227 throw(RuntimeException
)
229 sal_Int32 nLength
= m_seqDFlv
.getLength( );
230 sal_Bool bRet
= sal_False
;
232 // for ( sal_Int32 i = 0; i < nLength; ++i )
234 // if ( m_seqDFlv[i] == aFlavor )
246 void SAL_CALL
StringTransferable::lostOwnership( const Reference
< XClipboard
>& xClipboard
, const Reference
< XTransferable
>& xTrans
)
247 throw(RuntimeException
)
249 m_receivedLostOwnership
= sal_True
;
254 int SAL_CALL
main( int argc
, const char* argv
[] )
258 // check command line parameters
260 if ( NULL
== ( app
= strrchr( argv
[0], PATH_SEPARATOR
) ) )
265 for( int n
= 1; n
< argc
; n
++ )
267 if( strncmp( argv
[n
], "-r", 2 ) == 0 )
269 if( strlen( argv
[n
] ) > 2 )
270 aRegistry
= OUString::createFromAscii( argv
[n
] + 2 );
271 else if ( n
+ 1 < argc
)
272 aRegistry
= OUString::createFromAscii( argv
[++n
] );
276 if( aRegistry
.isEmpty( ) )
277 fprintf( stderr
, "Usage: %s -r full-path-to-applicat.rdb\n", app
);
279 // create service manager
281 Reference
< XMultiServiceFactory
> xServiceManager
;
285 xServiceManager
= createRegistryServiceFactory( aRegistry
, sal_True
);
286 ENSURE( xServiceManager
.is(), "*** ERROR *** service manager could not be created." );
288 // create an instance of GenericClipboard service
290 Sequence
< Any
> arguments(1);
291 arguments
[0] = makeAny( OUString("generic") );
293 Reference
< XClipboard
> xClipboard( xServiceManager
->createInstanceWithArguments(
294 OUString("com.sun.star.datatransfer.clipboard.GenericClipboard"),
295 arguments
), UNO_QUERY
);
297 ENSURE( xClipboard
.is(), "*** ERROR *** generic clipboard service could not be created." );
299 Reference
< XClipboardNotifier
> xClipboardNotifier( xClipboard
, UNO_QUERY
);
300 Reference
< XClipboardListener
> xClipboardListener
= new ClipboardListener();
301 ClipboardListener
* pListener
= (ClipboardListener
*) xClipboardListener
.get();
303 if( xClipboardNotifier
.is() )
304 xClipboardNotifier
->addClipboardListener( xClipboardListener
);
306 // run various tests on clipboard implementation
308 TRACE( "\n*** testing generic clipboard service ***\n" );
310 Reference
< XTransferable
> xContents
= new StringTransferable();
311 Reference
< XClipboardOwner
> xOwner
= new ClipboardOwner();
312 ClipboardOwner
*pOwner
= (ClipboardOwner
*) xOwner
.get();
314 TEST( "initial contents (none): ", xClipboard
->getContents().is() == sal_False
);
316 PERFORM( "update on contents with clipboard owner: ", xClipboard
->setContents( xContents
, xOwner
) );
317 TEST( "current clipboard contents: ", xContents
== xClipboard
->getContents() );
319 if( xClipboardNotifier
.is() )
321 TEST( "if received changedContents notifications: ", pListener
->receivedChangedContentsEvents() > 0 );
322 TEST( "if received exactly 1 changedContents notification: ", pListener
->receivedChangedContentsEvents() == 1 );
323 TEST( "if received changedContents notification for correct clipboard: ", pListener
->changedContentsEventClipboardValue() == xClipboard
);
324 TEST( "if received changedContents notification for correct clipboard: ", pListener
->changedContentsEventTransferableValue() == xContents
);
327 PERFORM( "update on contents without data (clear): ", xClipboard
->setContents( Reference
< XTransferable
>(), Reference
< XClipboardOwner
>() ) );
328 TEST( "if received lostOwnership message(s): ", pOwner
->receivedLostOwnerships() > 0 );
329 TEST( "if received exactly 1 lostOwnership message: ", pOwner
->receivedLostOwnerships() == 1 );
330 TEST( "if received lostOwnership message for the correct clipboard: ", pOwner
->lostOwnershipClipboardValue() == xClipboard
);
331 TEST( "if received lostOwnership message for the correct transferable: ", pOwner
->lostOwnershipTransferableValue() == xContents
);
332 TEST( "current clipboard contents (none): ", xClipboard
->getContents().is() == sal_False
);
334 if( xClipboardNotifier
.is() )
336 TEST( "if received changedContents notifications: ", pListener
->receivedChangedContentsEvents() > 1 );
337 TEST( "if received exactly 1 changedContents notification: ", pListener
->receivedChangedContentsEvents() == 2 );
338 TEST( "if received changedContents notification for correct clipboard: ", pListener
->changedContentsEventClipboardValue() == xClipboard
);
339 TEST( "if received changedContents notification for correct transferable: ", ! pListener
->changedContentsEventTransferableValue().is() );
342 PERFORM( "update on contents without clipboard owner: ", xClipboard
->setContents( xContents
, Reference
< XClipboardOwner
>() ) );
343 TEST( "that no further lostOwnership messages were received: ", pOwner
->receivedLostOwnerships() == 1 );
344 TEST( "current clipboard contents: ", xContents
== xClipboard
->getContents() );
346 if( xClipboardNotifier
.is() )
348 TEST( "if received changedContents notifications: ", pListener
->receivedChangedContentsEvents() > 2 );
349 TEST( "if received exactly 1 changedContents notification: ", pListener
->receivedChangedContentsEvents() == 3 );
350 TEST( "if received changedContents notification for correct clipboard: ", pListener
->changedContentsEventClipboardValue() == xClipboard
);
351 TEST( "if received changedContents notification for correct transferable: ", pListener
->changedContentsEventTransferableValue() == xContents
);
354 PERFORM( "update on contents without data (clear): ", xClipboard
->setContents( Reference
< XTransferable
>(), Reference
< XClipboardOwner
>() ) );
355 TEST( "that no further lostOwnership messages were received: ", pOwner
->receivedLostOwnerships() == 1 );
356 TEST( "current clipboard contents (none): ", xClipboard
->getContents().is() == sal_False
);
358 if( xClipboardNotifier
.is() )
360 TEST( "if received changedContents notifications: ", pListener
->receivedChangedContentsEvents() > 3 );
361 TEST( "if received exactly 1 changedContents notification: ", pListener
->receivedChangedContentsEvents() == 4 );
362 TEST( "if received changedContents notification for correct clipboard: ", pListener
->changedContentsEventClipboardValue() == xClipboard
);
363 TEST( "if received changedContents notification for correct transferable: ", ! pListener
->changedContentsEventTransferableValue().is() );
366 // create an instance of ClipboardManager service
368 Reference
< XClipboardManager
> xClipboardManager( xServiceManager
->createInstance(
369 OUString("com.sun.star.datatransfer.clipboard.ClipboardManager") ), UNO_QUERY
);
371 ENSURE( xClipboardManager
.is(), "*** ERROR *** clipboard manager service could not be created." );
373 // run various tests on clipboard manager implementation
375 TRACE( "\n*** testing clipboard manager service ***\n" );
377 TEST( "initial number of clipboards (0): ", xClipboardManager
->listClipboardNames().getLength() == 0 );
378 PERFORM( "insertion of generic clipboard: ", xClipboardManager
->addClipboard( xClipboard
) );
379 TEST( "number of inserted clipboards (1): ", xClipboardManager
->listClipboardNames().getLength() == 1 );
380 TEST( "name of inserted clipboard (generic): ", xClipboardManager
->listClipboardNames()[0] == "generic" );
381 TEST( "inserted clipboard instance: ", xClipboardManager
->getClipboard( OUString("generic") ) == xClipboard
);
382 PERFORM( "removal of generic clipboard: ", xClipboardManager
->removeClipboard( OUString("generic") ) );
383 TEST( "number of inserted clipboards (0): ", xClipboardManager
->listClipboardNames().getLength() == 0 );
384 TRACE( "Testing inserted clipboard instance (none): " );
387 xClipboardManager
->getClipboard( OUString("generic") );
390 catch (const NoSuchElementException
&)
396 catch (const Exception
&)
398 ENSURE( sal_False
, "*** ERROR *** exception caught." );
401 // shutdown the service manager
403 // query XComponent interface
404 Reference
< XComponent
> xComponent( xServiceManager
, UNO_QUERY
);
406 ENSURE( xComponent
.is(), "*** ERROR *** service manager does not support XComponent." );
408 // Dispose and clear factory
409 xComponent
->dispose();
410 xServiceManager
.clear();
412 fprintf( stderr
, "Done.\n" );
416 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */