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 112 sal_uInt32 receivedLostOwnerships() { return m_nReceivedLostOwnerships; }; 113 Reference< XClipboard > lostOwnershipClipboardValue() { return m_xClipboard; } 114 Reference< XTransferable > lostOwnershipTransferableValue() { return m_xTransferable; }; 115 }; 116 117 //------------------------------------------------------------------------ 118 // ctor 119 //------------------------------------------------------------------------ 120 121 ClipboardOwner::ClipboardOwner(): 122 m_nReceivedLostOwnerships( 0 ) 123 { 124 } 125 126 //------------------------------------------------------------------------ 127 // lostOwnership 128 //------------------------------------------------------------------------ 129 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 164 sal_uInt32 receivedChangedContentsEvents() { return m_nReceivedChangedContentsEvents; }; 165 Reference< XClipboard > changedContentsEventClipboardValue() { return m_xClipboard; } 166 Reference< XTransferable > changedContentsEventTransferableValue() { return m_xTransferable; }; 167 }; 168 169 //------------------------------------------------------------------------ 170 // ctor 171 //------------------------------------------------------------------------ 172 173 ClipboardListener::ClipboardListener(): 174 m_nReceivedChangedContentsEvents( 0 ) 175 { 176 } 177 178 //------------------------------------------------------------------------ 179 // changedContents 180 //------------------------------------------------------------------------ 181 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 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 222 sal_Bool receivedLostOwnership() { return m_receivedLostOwnership; }; 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 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 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 290 Sequence< DataFlavor > SAL_CALL StringTransferable::getTransferDataFlavors( ) 291 throw(RuntimeException) 292 { 293 return m_seqDFlv; 294 } 295 296 //------------------------------------------------------------------------ 297 // isDataFlavorSupported 298 //------------------------------------------------------------------------ 299 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 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 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