LibreOffice Module dtrans (master)  1
test_dtrans.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
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>
26 
27 #include <cppuhelper/servicefactory.hxx>
28 #include <cppuhelper/implbase.hxx>
29 #include <rtl/ustring.hxx>
30 
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <string.h>
34 
35 // my defines
36 
37 #ifdef UNX
38 #define PATH_SEPARATOR '/'
39 #else
40 #define PATH_SEPARATOR '\\'
41 #endif
42 
43 #define ENSURE( a, b ) if( !a ) { fprintf( stderr, b "\n" ); exit( -1 ); }
44 #define TEST( a, b ) fprintf( stderr, "Testing " a ); fprintf( stderr, b ? "passed\n" : "FAILED\n" )
45 #define PERFORM( a, b ) fprintf( stderr, "Performing " a); b; fprintf( stderr, "done\n" )
46 #define TRACE( a ) fprintf( stderr, a )
47 
48 // namespaces
49 
50 using namespace ::std;
51 using namespace ::cppu;
52 using namespace ::com::sun::star::container;
53 using namespace ::com::sun::star::datatransfer;
55 using namespace ::com::sun::star::uno;
56 using namespace ::com::sun::star::io;
57 using namespace ::com::sun::star::lang;
58 
59 // globals
60 
61 const char * app = NULL;
62 
63 // ClipboardOwner
64 
65 class ClipboardOwner : public WeakImplHelper< XClipboardOwner >
66 {
67  Reference< XClipboard > m_xClipboard;
68  Reference< XTransferable > m_xTransferable;
69 
71 
72 public:
74 
75  // XClipboardOwner
76 
77  virtual void SAL_CALL lostOwnership( const Reference< XClipboard >& xClipboard, const Reference< XTransferable >& xTrans ) throw(RuntimeException);
78 
80  Reference< XClipboard > lostOwnershipClipboardValue() { return m_xClipboard; }
81  Reference< XTransferable > lostOwnershipTransferableValue() { return m_xTransferable; };
82 };
83 
84 // ctor
85 
87  m_nReceivedLostOwnerships( 0 )
88 {
89 }
90 
91 // lostOwnership
92 
93 void SAL_CALL ClipboardOwner::lostOwnership( const Reference< XClipboard >& xClipboard, const Reference< XTransferable >& xTrans )
94  throw(RuntimeException)
95 {
96  m_nReceivedLostOwnerships++;
97  m_xClipboard = xClipboard;
98  m_xTransferable = xTrans;
99 }
100 
101 // ClipboardListener
102 
103 class ClipboardListener : public WeakImplHelper< XClipboardListener >
104 {
105  Reference< XClipboard > m_xClipboard;
106  Reference< XTransferable > m_xTransferable;
107 
109 
110 public:
112 
113  // XClipboardOwner
114 
115  virtual void SAL_CALL changedContents( const ClipboardEvent& event ) throw(RuntimeException);
116 
117  // XEventListener
118 
119  virtual void SAL_CALL disposing( const EventObject& event ) throw(RuntimeException);
120 
122  Reference< XClipboard > changedContentsEventClipboardValue() { return m_xClipboard; }
123  Reference< XTransferable > changedContentsEventTransferableValue() { return m_xTransferable; };
124 };
125 
126 // ctor
127 
129  m_nReceivedChangedContentsEvents( 0 )
130 {
131 }
132 
133 // changedContents
134 
135 void SAL_CALL ClipboardListener::changedContents( const ClipboardEvent& event )
136  throw(RuntimeException)
137 {
138  m_nReceivedChangedContentsEvents++;
139  m_xClipboard.set(event.Source, UNO_QUERY);
140  m_xTransferable = event.Contents;
141 }
142 
143 // disposing
144 
145 void SAL_CALL ClipboardListener::disposing( const EventObject& event )
146  throw(RuntimeException)
147 {
148 }
149 
150 // StringTransferable
151 
152 class StringTransferable : public WeakImplHelper< XClipboardOwner, XTransferable >
153 {
154 public:
156 
157  // XTransferable
158 
159  virtual Any SAL_CALL getTransferData( const DataFlavor& aFlavor ) throw(UnsupportedFlavorException, IOException, RuntimeException);
160  virtual Sequence< DataFlavor > SAL_CALL getTransferDataFlavors( ) throw(RuntimeException);
161  virtual sal_Bool SAL_CALL isDataFlavorSupported( const DataFlavor& aFlavor ) throw(RuntimeException);
162 
163  // XClipboardOwner
164 
165  virtual void SAL_CALL lostOwnership( const Reference< XClipboard >& xClipboard, const Reference< XTransferable >& xTrans ) throw(RuntimeException);
166 
169 
170 private:
171  Sequence< DataFlavor > m_seqDFlv;
172  OUString m_Data;
174 };
175 
176 // ctor
177 
179  m_seqDFlv( 1 ),
180  m_receivedLostOwnership( sal_False ),
181  m_Data( OUString("clipboard test content") )
182 {
183  DataFlavor df;
184 
185  /*
186  df.MimeType = L"text/plain; charset=unicode";
187  df.DataType = cppu::UnoType<OUString>::get();
188 
189  m_seqDFlv[0] = df;
190  */
191 
192  //df.MimeType = L"text/plain; charset=windows1252";
193  df.MimeType = "text/html";
194  df.DataType = cppu::UnoType<Sequence< sal_Int8 >>::get();
195 
196  m_seqDFlv[0] = df;
197 }
198 
199 // getTransferData
200 
201 Any SAL_CALL StringTransferable::getTransferData( const DataFlavor& aFlavor )
202  throw(UnsupportedFlavorException, IOException, RuntimeException)
203 {
204  Any anyData;
205 
206  /*if ( aFlavor == m_seqDFlv[0] )
207  {
208  anyData = makeAny( m_Data );
209  } */
210 
211  return anyData;
212 }
213 
214 // getTransferDataFlavors
215 
216 Sequence< DataFlavor > SAL_CALL StringTransferable::getTransferDataFlavors( )
217  throw(RuntimeException)
218 {
219  return m_seqDFlv;
220 }
221 
222 // isDataFlavorSupported
223 
224 sal_Bool SAL_CALL StringTransferable::isDataFlavorSupported( const DataFlavor& aFlavor )
225  throw(RuntimeException)
226 {
227  sal_Int32 nLength = m_seqDFlv.getLength( );
228  sal_Bool bRet = sal_False;
229 
230 // for ( sal_Int32 i = 0; i < nLength; ++i )
231 // {
232 // if ( m_seqDFlv[i] == aFlavor )
233 // {
234 // bRet = sal_True;
235 // break;
236 // }
237 // }
238 
239  return bRet;
240 }
241 
242 // lostOwnership
243 
244 void SAL_CALL StringTransferable::lostOwnership( const Reference< XClipboard >& xClipboard, const Reference< XTransferable >& xTrans )
245  throw(RuntimeException)
246 {
247  m_receivedLostOwnership = sal_True;
248 }
249 
250 // main
251 
252 int SAL_CALL main( int argc, const char* argv[] )
253 {
254  OUString aRegistry;
255 
256  // check command line parameters
257 
258  if ( NULL == ( app = strrchr( argv[0], PATH_SEPARATOR ) ) )
259  app = argv[0];
260  else
261  app++;
262 
263  for( int n = 1; n < argc; n++ )
264  {
265  if( strncmp( argv[n], "-r", 2 ) == 0 )
266  {
267  if( strlen( argv[n] ) > 2 )
268  aRegistry = OUString::createFromAscii( argv[n] + 2 );
269  else if ( n + 1 < argc )
270  aRegistry = OUString::createFromAscii( argv[++n] );
271  }
272  }
273 
274  if( aRegistry.isEmpty( ) )
275  fprintf( stderr, "Usage: %s -r full-path-to-applicat.rdb\n", app );
276 
277  // create service manager
278 
279  Reference< XMultiServiceFactory > xServiceManager;
280 
281  try
282  {
283  xServiceManager = createRegistryServiceFactory( aRegistry, sal_True );
284  ENSURE( xServiceManager.is(), "*** ERROR *** service manager could not be created." );
285 
286  // create an instance of GenericClipboard service
287 
288  Sequence< Any > arguments(1);
289  arguments[0] = makeAny( OUString("generic") );
290 
291  Reference< XClipboard > xClipboard( xServiceManager->createInstanceWithArguments(
292  "com.sun.star.datatransfer.clipboard.GenericClipboard",
293  arguments ), UNO_QUERY );
294 
295  ENSURE( xClipboard.is(), "*** ERROR *** generic clipboard service could not be created." );
296 
297  Reference< XClipboardNotifier > xClipboardNotifier( xClipboard, UNO_QUERY );
298  Reference< XClipboardListener > xClipboardListener = new ClipboardListener();
299  ClipboardListener * pListener = (ClipboardListener *) xClipboardListener.get();
300 
301  if( xClipboardNotifier.is() )
302  xClipboardNotifier->addClipboardListener( xClipboardListener );
303 
304  // run various tests on clipboard implementation
305 
306  TRACE( "\n*** testing generic clipboard service ***\n" );
307 
308  Reference< XTransferable > xContents = new StringTransferable();
309  Reference< XClipboardOwner > xOwner = new ClipboardOwner();
310  ClipboardOwner *pOwner = (ClipboardOwner *) xOwner.get();
311 
312  TEST( "initial contents (none): ", xClipboard->getContents().is() == sal_False );
313 
314  PERFORM( "update on contents with clipboard owner: ", xClipboard->setContents( xContents, xOwner ) );
315  TEST( "current clipboard contents: ", xContents == xClipboard->getContents() );
316 
317  if( xClipboardNotifier.is() )
318  {
319  TEST( "if received changedContents notifications: ", pListener->receivedChangedContentsEvents() > 0 );
320  TEST( "if received exactly 1 changedContents notification: ", pListener->receivedChangedContentsEvents() == 1 );
321  TEST( "if received changedContents notification for correct clipboard: ", pListener->changedContentsEventClipboardValue() == xClipboard );
322  TEST( "if received changedContents notification for correct clipboard: ", pListener->changedContentsEventTransferableValue() == xContents );
323  }
324 
325  PERFORM( "update on contents without data (clear): ", xClipboard->setContents( Reference< XTransferable >(), Reference< XClipboardOwner >() ) );
326  TEST( "if received lostOwnership message(s): ", pOwner->receivedLostOwnerships() > 0 );
327  TEST( "if received exactly 1 lostOwnership message: ", pOwner->receivedLostOwnerships() == 1 );
328  TEST( "if received lostOwnership message for the correct clipboard: ", pOwner->lostOwnershipClipboardValue() == xClipboard );
329  TEST( "if received lostOwnership message for the correct transferable: ", pOwner->lostOwnershipTransferableValue() == xContents );
330  TEST( "current clipboard contents (none): ", xClipboard->getContents().is() == sal_False );
331 
332  if( xClipboardNotifier.is() )
333  {
334  TEST( "if received changedContents notifications: ", pListener->receivedChangedContentsEvents() > 1 );
335  TEST( "if received exactly 1 changedContents notification: ", pListener->receivedChangedContentsEvents() == 2 );
336  TEST( "if received changedContents notification for correct clipboard: ", pListener->changedContentsEventClipboardValue() == xClipboard );
337  TEST( "if received changedContents notification for correct transferable: ", ! pListener->changedContentsEventTransferableValue().is() );
338  }
339 
340  PERFORM( "update on contents without clipboard owner: ", xClipboard->setContents( xContents, Reference< XClipboardOwner >() ) );
341  TEST( "that no further lostOwnership messages were received: ", pOwner->receivedLostOwnerships() == 1 );
342  TEST( "current clipboard contents: ", xContents == xClipboard->getContents() );
343 
344  if( xClipboardNotifier.is() )
345  {
346  TEST( "if received changedContents notifications: ", pListener->receivedChangedContentsEvents() > 2 );
347  TEST( "if received exactly 1 changedContents notification: ", pListener->receivedChangedContentsEvents() == 3 );
348  TEST( "if received changedContents notification for correct clipboard: ", pListener->changedContentsEventClipboardValue() == xClipboard );
349  TEST( "if received changedContents notification for correct transferable: ", pListener->changedContentsEventTransferableValue() == xContents );
350  }
351 
352  PERFORM( "update on contents without data (clear): ", xClipboard->setContents( Reference< XTransferable >(), Reference< XClipboardOwner >() ) );
353  TEST( "that no further lostOwnership messages were received: ", pOwner->receivedLostOwnerships() == 1 );
354  TEST( "current clipboard contents (none): ", xClipboard->getContents().is() == sal_False );
355 
356  if( xClipboardNotifier.is() )
357  {
358  TEST( "if received changedContents notifications: ", pListener->receivedChangedContentsEvents() > 3 );
359  TEST( "if received exactly 1 changedContents notification: ", pListener->receivedChangedContentsEvents() == 4 );
360  TEST( "if received changedContents notification for correct clipboard: ", pListener->changedContentsEventClipboardValue() == xClipboard );
361  TEST( "if received changedContents notification for correct transferable: ", ! pListener->changedContentsEventTransferableValue().is() );
362  }
363 
364  // create an instance of ClipboardManager service
365 
366  Reference< XClipboardManager > xClipboardManager( xServiceManager->createInstance(
367  "com.sun.star.datatransfer.clipboard.ClipboardManager" ), UNO_QUERY );
368 
369  ENSURE( xClipboardManager.is(), "*** ERROR *** clipboard manager service could not be created." );
370 
371  // run various tests on clipboard manager implementation
372 
373  TRACE( "\n*** testing clipboard manager service ***\n" );
374 
375  TEST( "initial number of clipboards (0): ", xClipboardManager->listClipboardNames().getLength() == 0 );
376  PERFORM( "insertion of generic clipboard: ", xClipboardManager->addClipboard( xClipboard ) );
377  TEST( "number of inserted clipboards (1): ", xClipboardManager->listClipboardNames().getLength() == 1 );
378  TEST( "name of inserted clipboard (generic): ", xClipboardManager->listClipboardNames()[0] == "generic" );
379  TEST( "inserted clipboard instance: ", xClipboardManager->getClipboard( OUString("generic") ) == xClipboard );
380  PERFORM( "removal of generic clipboard: ", xClipboardManager->removeClipboard( OUString("generic") ) );
381  TEST( "number of inserted clipboards (0): ", xClipboardManager->listClipboardNames().getLength() == 0 );
382  TRACE( "Testing inserted clipboard instance (none): " );
383  try
384  {
385  xClipboardManager->getClipboard( OUString("generic") );
386  TRACE( "FAILED\n" );
387  }
388  catch (const NoSuchElementException&)
389  {
390  TRACE( "passed\n" );
391  }
392  }
393 
394  catch (const Exception&)
395  {
396  ENSURE( sal_False, "*** ERROR *** exception caught." );
397  }
398 
399  // shutdown the service manager
400 
401  // query XComponent interface
402  Reference< XComponent > xComponent( xServiceManager, UNO_QUERY );
403 
404  ENSURE( xComponent.is(), "*** ERROR *** service manager does not support XComponent." );
405 
406  // Dispose and clear factory
407  xComponent->dispose();
408  xServiceManager.clear();
409 
410  fprintf( stderr, "Done.\n" );
411  return 0;
412 }
413 
414 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_uInt32 m_nReceivedChangedContentsEvents
virtual void SAL_CALL disposing(const EventObject &event)
#define PERFORM(a, b)
Definition: test_dtrans.cxx:45
sal_uInt32 receivedLostOwnerships()
Definition: test_dtrans.cxx:79
virtual void SAL_CALL lostOwnership(const Reference< XClipboard > &xClipboard, const Reference< XTransferable > &xTrans)
void clearReceivedLostOwnership()
int SAL_CALL main(int argc, const char *argv[])
virtual Any SAL_CALL getTransferData(const DataFlavor &aFlavor)
#define ENSURE(a, b)
Definition: test_dtrans.cxx:43
#define TRACE(a)
Definition: test_dtrans.cxx:46
const char * app
Definition: test_dtrans.cxx:61
SAL_DLLPUBLIC_EXPORT css::uno::Reference< css::lang::XMultiServiceFactory > SAL_CALL createRegistryServiceFactory(OUString const &, OUString const &, sal_Bool, OUString const &)
return NULL
Reference< XClipboard > m_xClipboard
Definition: test_dtrans.cxx:67
css::uno::Reference< css::lang::XComponent > xComponent
Reference< XClipboard > changedContentsEventClipboardValue()
sal_Bool m_receivedLostOwnership
sal_uInt32 receivedChangedContentsEvents()
Reference< XTransferable > m_xTransferable
virtual Sequence< DataFlavor > SAL_CALL getTransferDataFlavors()
#define sal_True
virtual sal_Bool SAL_CALL isDataFlavorSupported(const DataFlavor &aFlavor)
unsigned char sal_Bool
virtual void SAL_CALL lostOwnership(const Reference< XClipboard > &xClipboard, const Reference< XTransferable > &xTrans)
Definition: test_dtrans.cxx:93
Reference< XClipboard > m_xClipboard
virtual void SAL_CALL changedContents(const ClipboardEvent &event)
#define TEST(a, b)
Definition: test_dtrans.cxx:44
Reference< XTransferable > lostOwnershipTransferableValue()
Definition: test_dtrans.cxx:81
sal_uInt32 m_nReceivedLostOwnerships
Definition: test_dtrans.cxx:70
#define sal_False
Sequence< DataFlavor > m_seqDFlv
sal_Bool receivedLostOwnership()
#define PATH_SEPARATOR
Definition: test_dtrans.cxx:38
Reference< XClipboard > lostOwnershipClipboardValue()
Definition: test_dtrans.cxx:80
sal_Int32 const nLength
Reference< XTransferable > m_xTransferable
Definition: test_dtrans.cxx:68
Reference< XTransferable > changedContentsEventTransferableValue()
css::uno::Any SAL_CALL makeAny(const SharedUNOComponent< INTERFACE, COMPONENT > &value)