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