1 /************************************************************************* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * Copyright 2000, 2010 Oracle and/or its affiliates. 5 * 6 * OpenOffice.org - a multi-platform office productivity suite 7 * 8 * This file is part of OpenOffice.org. 9 * 10 * OpenOffice.org is free software: you can redistribute it and/or modify 11 * it under the terms of the GNU Lesser General Public License version 3 12 * only, as published by the Free Software Foundation. 13 * 14 * OpenOffice.org is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU Lesser General Public License version 3 for more details 18 * (a copy is included in the LICENSE file that accompanied this code). 19 * 20 * You should have received a copy of the GNU Lesser General Public License 21 * version 3 along with OpenOffice.org. If not, see 22 * <http://www.openoffice.org/license.html> 23 * for a copy of the LGPLv3 License. 24 * 25 ************************************************************************/ 26 27 #include "precompiled_toolkit.hxx" 28 29 #include "toolkit/controls/animatedimages.hxx" 30 #include "toolkit/helper/servicenames.hxx" 31 #include "toolkit/helper/property.hxx" 32 #include "toolkit/helper/unopropertyarrayhelper.hxx" 33 34 /** === begin UNO includes === **/ 35 #include <com/sun/star/lang/DisposedException.hpp> 36 #include <com/sun/star/awt/VisualEffect.hpp> 37 #include <com/sun/star/awt/ImageScaleMode.hpp> 38 #include <com/sun/star/util/XModifyListener.hpp> 39 /** === end UNO includes === **/ 40 41 //...................................................................................................................... 42 namespace toolkit 43 { 44 //...................................................................................................................... 45 46 /** === begin UNO using === **/ 47 using ::com::sun::star::uno::Reference; 48 using ::com::sun::star::uno::XInterface; 49 using ::com::sun::star::uno::UNO_QUERY; 50 using ::com::sun::star::uno::UNO_QUERY_THROW; 51 using ::com::sun::star::uno::UNO_SET_THROW; 52 using ::com::sun::star::uno::Exception; 53 using ::com::sun::star::uno::RuntimeException; 54 using ::com::sun::star::uno::Any; 55 using ::com::sun::star::uno::makeAny; 56 using ::com::sun::star::uno::Sequence; 57 using ::com::sun::star::uno::Type; 58 using ::com::sun::star::container::ContainerEvent; 59 using ::com::sun::star::container::XContainerListener; 60 using ::com::sun::star::beans::XPropertySetInfo; 61 using ::com::sun::star::lang::DisposedException; 62 using ::com::sun::star::lang::IndexOutOfBoundsException; 63 using ::com::sun::star::lang::EventObject; 64 using ::com::sun::star::awt::XControlModel; 65 using ::com::sun::star::awt::XAnimatedImages; 66 using ::com::sun::star::lang::IllegalArgumentException; 67 using ::com::sun::star::awt::XWindowPeer; 68 using ::com::sun::star::util::XModifyListener; 69 using ::com::sun::star::awt::XToolkit; 70 using ::com::sun::star::lang::XMultiServiceFactory; 71 /** === end UNO using === **/ 72 namespace VisualEffect = ::com::sun::star::awt::VisualEffect; 73 namespace ImageScaleMode = ::com::sun::star::awt::ImageScaleMode; 74 75 //================================================================================================================== 76 //= AnimatedImagesControl 77 //================================================================================================================== 78 //------------------------------------------------------------------------------------------------------------------ 79 AnimatedImagesControl::AnimatedImagesControl( Reference< XMultiServiceFactory > const & i_factory ) 80 :AnimatedImagesControl_Base( i_factory ) 81 { 82 } 83 84 //------------------------------------------------------------------------------------------------------------------ 85 ::rtl::OUString AnimatedImagesControl::GetComponentServiceName() 86 { 87 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AnimatedImages" ) ); 88 } 89 90 //------------------------------------------------------------------------------------------------------------------ 91 void SAL_CALL AnimatedImagesControl::startAnimation( ) throw (RuntimeException) 92 { 93 Reference< XAnimation > xAnimation( getPeer(), UNO_QUERY ); 94 if ( xAnimation.is() ) 95 xAnimation->startAnimation(); 96 } 97 98 //------------------------------------------------------------------------------------------------------------------ 99 void SAL_CALL AnimatedImagesControl::stopAnimation( ) throw (RuntimeException) 100 { 101 Reference< XAnimation > xAnimation( getPeer(), UNO_QUERY ); 102 if ( xAnimation.is() ) 103 xAnimation->stopAnimation(); 104 } 105 106 //------------------------------------------------------------------------------------------------------------------ 107 ::sal_Bool SAL_CALL AnimatedImagesControl::isAnimationRunning( ) throw (RuntimeException) 108 { 109 Reference< XAnimation > xAnimation( getPeer(), UNO_QUERY ); 110 if ( xAnimation.is() ) 111 return xAnimation->isAnimationRunning(); 112 return sal_False; 113 } 114 115 //------------------------------------------------------------------------------------------------------------------ 116 ::rtl::OUString SAL_CALL AnimatedImagesControl::getImplementationName( ) throw(RuntimeException) 117 { 118 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.comp.toolkit.AnimatedImagesControl" ) ); 119 } 120 121 //------------------------------------------------------------------------------------------------------------------ 122 Sequence< ::rtl::OUString > SAL_CALL AnimatedImagesControl::getSupportedServiceNames() throw(RuntimeException) 123 { 124 Sequence< ::rtl::OUString > aServices( AnimatedImagesControl_Base::getSupportedServiceNames() ); 125 aServices.realloc( aServices.getLength() + 1 ); 126 aServices[ aServices.getLength() - 1 ] = ::rtl::OUString::createFromAscii( szServiceName_AnimatedImagesControl ); 127 return aServices; 128 } 129 130 //------------------------------------------------------------------------------------------------------------------ 131 namespace 132 { 133 void lcl_updatePeer( Reference< XWindowPeer > const& i_peer, Reference< XControlModel > const& i_model ) 134 { 135 const Reference< XModifyListener > xPeerModify( i_peer, UNO_QUERY ); 136 if ( xPeerModify.is() ) 137 { 138 EventObject aEvent; 139 aEvent.Source = i_model; 140 xPeerModify->modified( aEvent ); 141 } 142 } 143 } 144 145 //------------------------------------------------------------------------------------------------------------------ 146 sal_Bool SAL_CALL AnimatedImagesControl::setModel( const Reference< XControlModel >& i_rModel ) throw ( RuntimeException ) 147 { 148 const Reference< XAnimatedImages > xOldContainer( getModel(), UNO_QUERY ); 149 const Reference< XAnimatedImages > xNewContainer( i_rModel, UNO_QUERY ); 150 151 if ( !AnimatedImagesControl_Base::setModel( i_rModel ) ) 152 return sal_False; 153 154 if ( xOldContainer.is() ) 155 xOldContainer->removeContainerListener( this ); 156 157 if ( xNewContainer.is() ) 158 xNewContainer->addContainerListener( this ); 159 160 lcl_updatePeer( getPeer(), getModel() ); 161 162 return sal_True; 163 } 164 165 //------------------------------------------------------------------------------------------------------------------ 166 void SAL_CALL AnimatedImagesControl::createPeer( const Reference< XToolkit >& i_toolkit, const Reference< XWindowPeer >& i_parentPeer ) throw(RuntimeException) 167 { 168 AnimatedImagesControl_Base::createPeer( i_toolkit, i_parentPeer ); 169 170 lcl_updatePeer( getPeer(), getModel() ); 171 } 172 173 //------------------------------------------------------------------------------------------------------------------ 174 void SAL_CALL AnimatedImagesControl::elementInserted( const ContainerEvent& i_event ) throw (RuntimeException) 175 { 176 const Reference< XContainerListener > xPeerListener( getPeer(), UNO_QUERY ); 177 if ( xPeerListener.is() ) 178 xPeerListener->elementInserted( i_event ); 179 } 180 181 //------------------------------------------------------------------------------------------------------------------ 182 void SAL_CALL AnimatedImagesControl::elementRemoved( const ContainerEvent& i_event ) throw (RuntimeException) 183 { 184 const Reference< XContainerListener > xPeerListener( getPeer(), UNO_QUERY ); 185 if ( xPeerListener.is() ) 186 xPeerListener->elementRemoved( i_event ); 187 } 188 189 //------------------------------------------------------------------------------------------------------------------ 190 void SAL_CALL AnimatedImagesControl::elementReplaced( const ContainerEvent& i_event ) throw (RuntimeException) 191 { 192 const Reference< XContainerListener > xPeerListener( getPeer(), UNO_QUERY ); 193 if ( xPeerListener.is() ) 194 xPeerListener->elementReplaced( i_event ); 195 } 196 197 //------------------------------------------------------------------------------------------------------------------ 198 void SAL_CALL AnimatedImagesControl::disposing( const EventObject& i_event ) throw (RuntimeException) 199 { 200 UnoControlBase::disposing( i_event ); 201 } 202 203 //================================================================================================================== 204 //= AnimatedImagesControlModel_Data 205 //================================================================================================================== 206 struct AnimatedImagesControlModel_Data 207 { 208 ::std::vector< Sequence< ::rtl::OUString > > aImageSets; 209 }; 210 211 namespace 212 { 213 void lcl_checkIndex( const AnimatedImagesControlModel_Data& i_data, const sal_Int32 i_index, const Reference< XInterface >& i_context, 214 const bool i_forInsert = false ) 215 { 216 if ( ( i_index < 0 ) || ( size_t( i_index ) > i_data.aImageSets.size() + ( i_forInsert ? 1 : 0 ) ) ) 217 throw IndexOutOfBoundsException( ::rtl::OUString(), i_context ); 218 } 219 220 void lcl_notify( ::osl::ClearableMutexGuard& i_guard, ::cppu::OBroadcastHelper& i_broadcaseHelper, 221 void ( SAL_CALL XContainerListener::*i_notificationMethod )( const ContainerEvent& ), 222 const sal_Int32 i_accessor, const Sequence< ::rtl::OUString >& i_imageURLs, const Reference< XInterface >& i_context ) 223 { 224 ::cppu::OInterfaceContainerHelper* pContainerListeners = i_broadcaseHelper.getContainer( XContainerListener::static_type() ); 225 if ( pContainerListeners == NULL ) 226 return; 227 228 ContainerEvent aEvent; 229 aEvent.Source = i_context; 230 aEvent.Accessor <<= i_accessor; 231 aEvent.Element <<= i_imageURLs; 232 233 i_guard.clear(); 234 pContainerListeners->notifyEach( i_notificationMethod, aEvent ); 235 } 236 } 237 238 //================================================================================================================== 239 //= AnimatedImagesControlModel 240 //================================================================================================================== 241 //------------------------------------------------------------------------------------------------------------------ 242 AnimatedImagesControlModel::AnimatedImagesControlModel( Reference< XMultiServiceFactory > const & i_factory ) 243 :AnimatedImagesControlModel_Base( i_factory ) 244 ,m_pData( new AnimatedImagesControlModel_Data ) 245 { 246 ImplRegisterProperty( BASEPROPERTY_AUTO_REPEAT ); 247 ImplRegisterProperty( BASEPROPERTY_BORDER ); 248 ImplRegisterProperty( BASEPROPERTY_BORDERCOLOR ); 249 ImplRegisterProperty( BASEPROPERTY_BACKGROUNDCOLOR ); 250 ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL ); 251 ImplRegisterProperty( BASEPROPERTY_ENABLEVISIBLE ); 252 ImplRegisterProperty( BASEPROPERTY_HELPTEXT ); 253 ImplRegisterProperty( BASEPROPERTY_HELPURL ); 254 ImplRegisterProperty( BASEPROPERTY_IMAGE_SCALE_MODE ); 255 ImplRegisterProperty( BASEPROPERTY_STEP_TIME ); 256 } 257 258 //------------------------------------------------------------------------------------------------------------------ 259 AnimatedImagesControlModel::AnimatedImagesControlModel( const AnimatedImagesControlModel& i_copySource ) 260 :AnimatedImagesControlModel_Base( i_copySource ) 261 ,m_pData( new AnimatedImagesControlModel_Data( *i_copySource.m_pData ) ) 262 { 263 } 264 265 //------------------------------------------------------------------------------------------------------------------ 266 AnimatedImagesControlModel::~AnimatedImagesControlModel() 267 { 268 } 269 270 //------------------------------------------------------------------------------------------------------------------ 271 UnoControlModel* AnimatedImagesControlModel::Clone() const 272 { 273 return new AnimatedImagesControlModel( *this ); 274 } 275 276 //------------------------------------------------------------------------------------------------------------------ 277 Reference< XPropertySetInfo > SAL_CALL AnimatedImagesControlModel::getPropertySetInfo( ) throw(RuntimeException) 278 { 279 static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); 280 return xInfo; 281 } 282 283 //------------------------------------------------------------------------------------------------------------------ 284 ::rtl::OUString SAL_CALL AnimatedImagesControlModel::getServiceName() throw(RuntimeException) 285 { 286 return ::rtl::OUString::createFromAscii( szServiceName_AnimatedImagesControlModel ); 287 } 288 289 //------------------------------------------------------------------------------------------------------------------ 290 ::rtl::OUString SAL_CALL AnimatedImagesControlModel::getImplementationName( ) throw(RuntimeException) 291 { 292 return ::rtl::OUString::createFromAscii( "org.openoffice.comp.toolkit.AnimatedImagesControlModel" ); 293 } 294 295 //------------------------------------------------------------------------------------------------------------------ 296 Sequence< ::rtl::OUString > SAL_CALL AnimatedImagesControlModel::getSupportedServiceNames() throw(RuntimeException) 297 { 298 Sequence< ::rtl::OUString > aServiceNames(2); 299 aServiceNames[0] = ::rtl::OUString::createFromAscii( szServiceName_AnimatedImagesControlModel ); 300 aServiceNames[1] = ::rtl::OUString::createFromAscii( "com.sun.star.awt.UnoControlModel" ); 301 return aServiceNames; 302 } 303 304 //------------------------------------------------------------------------------------------------------------------ 305 void SAL_CALL AnimatedImagesControlModel::setFastPropertyValue_NoBroadcast( sal_Int32 i_handle, const Any& i_value ) throw (Exception) 306 { 307 switch ( i_handle ) 308 { 309 case BASEPROPERTY_IMAGE_SCALE_MODE: 310 { 311 sal_Int16 nImageScaleMode( ImageScaleMode::Anisotropic ); 312 OSL_VERIFY( i_value >>= nImageScaleMode ); // convertFastPropertyValue ensures that this has the proper type 313 if ( ( nImageScaleMode != ImageScaleMode::None ) 314 && ( nImageScaleMode != ImageScaleMode::Isotropic ) 315 && ( nImageScaleMode != ImageScaleMode::Anisotropic ) 316 ) 317 throw IllegalArgumentException( ::rtl::OUString(), *this, 1 ); 318 } 319 break; 320 } 321 322 AnimatedImagesControlModel_Base::setFastPropertyValue_NoBroadcast( i_handle, i_value ); 323 } 324 325 //------------------------------------------------------------------------------------------------------------------ 326 Any AnimatedImagesControlModel::ImplGetDefaultValue( sal_uInt16 i_propertyId ) const 327 { 328 switch ( i_propertyId ) 329 { 330 case BASEPROPERTY_DEFAULTCONTROL: 331 return makeAny( ::rtl::OUString::createFromAscii( szServiceName_AnimatedImagesControl ) ); 332 333 case BASEPROPERTY_BORDER: 334 return makeAny( VisualEffect::NONE ); 335 336 case BASEPROPERTY_STEP_TIME: 337 return makeAny( (sal_Int32) 100 ); 338 339 case BASEPROPERTY_AUTO_REPEAT: 340 return makeAny( (sal_Bool)sal_True ); 341 342 case BASEPROPERTY_IMAGE_SCALE_MODE: 343 return makeAny( ImageScaleMode::None ); 344 345 default: 346 return UnoControlModel::ImplGetDefaultValue( i_propertyId ); 347 } 348 } 349 350 //------------------------------------------------------------------------------------------------------------------ 351 ::cppu::IPropertyArrayHelper& SAL_CALL AnimatedImagesControlModel::getInfoHelper() 352 { 353 static UnoPropertyArrayHelper* pHelper = NULL; 354 if ( !pHelper ) 355 { 356 Sequence< sal_Int32 > aIDs = ImplGetPropertyIds(); 357 pHelper = new UnoPropertyArrayHelper( aIDs ); 358 } 359 return *pHelper; 360 } 361 362 //------------------------------------------------------------------------------------------------------------------ 363 ::sal_Int32 SAL_CALL AnimatedImagesControlModel::getStepTime() throw (RuntimeException) 364 { 365 sal_Int32 nStepTime( 100 ); 366 OSL_VERIFY( getPropertyValue( GetPropertyName( BASEPROPERTY_STEP_TIME ) ) >>= nStepTime ); 367 return nStepTime; 368 } 369 370 //------------------------------------------------------------------------------------------------------------------ 371 void SAL_CALL AnimatedImagesControlModel::setStepTime( ::sal_Int32 i_stepTime ) throw (RuntimeException) 372 { 373 setPropertyValue( GetPropertyName( BASEPROPERTY_STEP_TIME ), makeAny( i_stepTime ) ); 374 } 375 376 //------------------------------------------------------------------------------------------------------------------ 377 ::sal_Bool SAL_CALL AnimatedImagesControlModel::getAutoRepeat() throw (RuntimeException) 378 { 379 sal_Bool bAutoRepeat( sal_True ); 380 OSL_VERIFY( getPropertyValue( GetPropertyName( BASEPROPERTY_AUTO_REPEAT ) ) >>= bAutoRepeat ); 381 return bAutoRepeat; 382 } 383 384 //------------------------------------------------------------------------------------------------------------------ 385 void SAL_CALL AnimatedImagesControlModel::setAutoRepeat( ::sal_Bool i_autoRepeat ) throw (RuntimeException) 386 { 387 setPropertyValue( GetPropertyName( BASEPROPERTY_AUTO_REPEAT ), makeAny( i_autoRepeat ) ); 388 } 389 390 //------------------------------------------------------------------------------------------------------------------ 391 ::sal_Int16 SAL_CALL AnimatedImagesControlModel::getScaleMode() throw (RuntimeException) 392 { 393 sal_Int16 nImageScaleMode( ImageScaleMode::Anisotropic ); 394 OSL_VERIFY( getPropertyValue( GetPropertyName( BASEPROPERTY_IMAGE_SCALE_MODE ) ) >>= nImageScaleMode ); 395 return nImageScaleMode; 396 } 397 398 //------------------------------------------------------------------------------------------------------------------ 399 void SAL_CALL AnimatedImagesControlModel::setScaleMode( ::sal_Int16 i_scaleMode ) throw (IllegalArgumentException, RuntimeException) 400 { 401 setPropertyValue( GetPropertyName( BASEPROPERTY_IMAGE_SCALE_MODE ), makeAny( i_scaleMode ) ); 402 } 403 404 //------------------------------------------------------------------------------------------------------------------ 405 ::sal_Int32 SAL_CALL AnimatedImagesControlModel::getImageSetCount( ) throw (RuntimeException) 406 { 407 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 408 if ( GetBroadcastHelper().bDisposed || GetBroadcastHelper().bInDispose ) 409 throw DisposedException(); 410 411 return m_pData->aImageSets.size(); 412 } 413 414 //------------------------------------------------------------------------------------------------------------------ 415 Sequence< ::rtl::OUString > SAL_CALL AnimatedImagesControlModel::getImageSet( ::sal_Int32 i_index ) throw (IndexOutOfBoundsException, RuntimeException) 416 { 417 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 418 if ( GetBroadcastHelper().bDisposed || GetBroadcastHelper().bInDispose ) 419 throw DisposedException(); 420 421 lcl_checkIndex( *m_pData, i_index, *this ); 422 423 return m_pData->aImageSets[ i_index ]; 424 } 425 426 //------------------------------------------------------------------------------------------------------------------ 427 void SAL_CALL AnimatedImagesControlModel::insertImageSet( ::sal_Int32 i_index, const Sequence< ::rtl::OUString >& i_imageURLs ) throw (IndexOutOfBoundsException, RuntimeException) 428 { 429 ::osl::ClearableMutexGuard aGuard( GetMutex() ); 430 // sanity checks 431 if ( GetBroadcastHelper().bDisposed || GetBroadcastHelper().bInDispose ) 432 throw DisposedException(); 433 434 lcl_checkIndex( *m_pData, i_index, *this, true ); 435 436 // actaul insertion 437 m_pData->aImageSets.insert( m_pData->aImageSets.begin() + i_index, i_imageURLs ); 438 439 // listener notification 440 lcl_notify( aGuard, BrdcstHelper, &XContainerListener::elementInserted, i_index, i_imageURLs, *this ); 441 } 442 443 //------------------------------------------------------------------------------------------------------------------ 444 void SAL_CALL AnimatedImagesControlModel::replaceImageSet( ::sal_Int32 i_index, const Sequence< ::rtl::OUString >& i_imageURLs ) throw (IndexOutOfBoundsException, RuntimeException) 445 { 446 ::osl::ClearableMutexGuard aGuard( GetMutex() ); 447 // sanity checks 448 if ( GetBroadcastHelper().bDisposed || GetBroadcastHelper().bInDispose ) 449 throw DisposedException(); 450 451 lcl_checkIndex( *m_pData, i_index, *this ); 452 453 // actaul insertion 454 m_pData->aImageSets[ i_index ] = i_imageURLs; 455 456 // listener notification 457 lcl_notify( aGuard, BrdcstHelper, &XContainerListener::elementReplaced, i_index, i_imageURLs, *this ); 458 } 459 460 //------------------------------------------------------------------------------------------------------------------ 461 void SAL_CALL AnimatedImagesControlModel::removeImageSet( ::sal_Int32 i_index ) throw (IndexOutOfBoundsException, RuntimeException) 462 { 463 ::osl::ClearableMutexGuard aGuard( GetMutex() ); 464 // sanity checks 465 if ( GetBroadcastHelper().bDisposed || GetBroadcastHelper().bInDispose ) 466 throw DisposedException(); 467 468 lcl_checkIndex( *m_pData, i_index, *this ); 469 470 // actual removal 471 ::std::vector< Sequence< ::rtl::OUString > >::iterator removalPos = m_pData->aImageSets.begin() + i_index; 472 Sequence< ::rtl::OUString > aRemovedElement( *removalPos ); 473 m_pData->aImageSets.erase( removalPos ); 474 475 // listener notification 476 lcl_notify( aGuard, BrdcstHelper, &XContainerListener::elementRemoved, i_index, aRemovedElement, *this ); 477 } 478 479 //------------------------------------------------------------------------------------------------------------------ 480 void SAL_CALL AnimatedImagesControlModel::addContainerListener( const Reference< XContainerListener >& i_listener ) throw (RuntimeException) 481 { 482 BrdcstHelper.addListener( XContainerListener::static_type(), i_listener ); 483 } 484 485 //------------------------------------------------------------------------------------------------------------------ 486 void SAL_CALL AnimatedImagesControlModel::removeContainerListener( const Reference< XContainerListener >& i_listener ) throw (RuntimeException) 487 { 488 BrdcstHelper.removeListener( XContainerListener::static_type(), i_listener ); 489 } 490 491 //...................................................................................................................... 492 } // namespace toolkit 493 //...................................................................................................................... 494