diff options
Diffstat (limited to '')
-rw-r--r-- | toolkit/source/controls/animatedimages.cxx | 498 |
1 files changed, 498 insertions, 0 deletions
diff --git a/toolkit/source/controls/animatedimages.cxx b/toolkit/source/controls/animatedimages.cxx new file mode 100644 index 000000000..c304782e8 --- /dev/null +++ b/toolkit/source/controls/animatedimages.cxx @@ -0,0 +1,498 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include <controls/animatedimages.hxx> +#include <toolkit/helper/property.hxx> + +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <com/sun/star/awt/VisualEffect.hpp> +#include <com/sun/star/awt/ImageScaleMode.hpp> +#include <com/sun/star/awt/XAnimation.hpp> +#include <com/sun/star/awt/XAnimatedImages.hpp> +#include <com/sun/star/beans/XPropertySetInfo.hpp> +#include <com/sun/star/container/XContainerListener.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/util/XModifyListener.hpp> +#include <o3tl/safeint.hxx> +#include <toolkit/controls/unocontrolbase.hxx> +#include <toolkit/controls/unocontrolmodel.hxx> + +#include <cppuhelper/implbase2.hxx> + +#include <helper/unopropertyarrayhelper.hxx> + +using namespace css::awt; +using namespace css::container; +using namespace css::lang; +using namespace css::uno; + +namespace { + +typedef ::cppu::AggImplInheritanceHelper2 < UnoControlBase + , css::awt::XAnimation + , css::container::XContainerListener + > AnimatedImagesControl_Base; + +class AnimatedImagesControl : public AnimatedImagesControl_Base +{ +public: + AnimatedImagesControl(); + OUString GetComponentServiceName() override; + + // XAnimation + virtual void SAL_CALL startAnimation( ) override; + virtual void SAL_CALL stopAnimation( ) override; + virtual sal_Bool SAL_CALL isAnimationRunning( ) override; + + // XServiceInfo + OUString SAL_CALL getImplementationName( ) override; + css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + // XControl + sal_Bool SAL_CALL setModel( const css::uno::Reference< css::awt::XControlModel >& i_rModel ) override; + void SAL_CALL createPeer( const css::uno::Reference< css::awt::XToolkit >& i_toolkit, const css::uno::Reference< css::awt::XWindowPeer >& i_parentPeer ) override; + + + // XContainerListener + virtual void SAL_CALL elementInserted( const css::container::ContainerEvent& Event ) override; + virtual void SAL_CALL elementRemoved( const css::container::ContainerEvent& Event ) override; + virtual void SAL_CALL elementReplaced( const css::container::ContainerEvent& Event ) override; + + // XEventListener + virtual void SAL_CALL disposing( const css::lang::EventObject& i_event ) override; +}; + + AnimatedImagesControl::AnimatedImagesControl() + :AnimatedImagesControl_Base() + { + } + + + OUString AnimatedImagesControl::GetComponentServiceName() + { + return "AnimatedImages"; + } + + + void SAL_CALL AnimatedImagesControl::startAnimation( ) + { + Reference< XAnimation > xAnimation( getPeer(), UNO_QUERY ); + if ( xAnimation.is() ) + xAnimation->startAnimation(); + } + + + void SAL_CALL AnimatedImagesControl::stopAnimation( ) + { + Reference< XAnimation > xAnimation( getPeer(), UNO_QUERY ); + if ( xAnimation.is() ) + xAnimation->stopAnimation(); + } + + + sal_Bool SAL_CALL AnimatedImagesControl::isAnimationRunning( ) + { + Reference< XAnimation > xAnimation( getPeer(), UNO_QUERY ); + if ( xAnimation.is() ) + return xAnimation->isAnimationRunning(); + return false; + } + + + OUString SAL_CALL AnimatedImagesControl::getImplementationName( ) + { + return "org.openoffice.comp.toolkit.AnimatedImagesControl"; + } + + + Sequence< OUString > SAL_CALL AnimatedImagesControl::getSupportedServiceNames() + { + Sequence< OUString > aServices( AnimatedImagesControl_Base::getSupportedServiceNames() ); + aServices.realloc( aServices.getLength() + 1 ); + aServices[ aServices.getLength() - 1 ] = "com.sun.star.awt.AnimatedImagesControl"; + return aServices; + } + + void lcl_updatePeer( Reference< XWindowPeer > const& i_peer, Reference< XControlModel > const& i_model ) + { + const Reference< css::util::XModifyListener > xPeerModify( i_peer, UNO_QUERY ); + if ( xPeerModify.is() ) + { + EventObject aEvent; + aEvent.Source = i_model; + xPeerModify->modified( aEvent ); + } + } + + sal_Bool SAL_CALL AnimatedImagesControl::setModel( const Reference< XControlModel >& i_rModel ) + { + const Reference< XAnimatedImages > xOldContainer( getModel(), UNO_QUERY ); + const Reference< XAnimatedImages > xNewContainer( i_rModel, UNO_QUERY ); + + if ( !AnimatedImagesControl_Base::setModel( i_rModel ) ) + return false; + + if ( xOldContainer.is() ) + xOldContainer->removeContainerListener( this ); + + if ( xNewContainer.is() ) + xNewContainer->addContainerListener( this ); + + lcl_updatePeer( getPeer(), getModel() ); + + return true; + } + + + void SAL_CALL AnimatedImagesControl::createPeer( const Reference< XToolkit >& i_toolkit, const Reference< XWindowPeer >& i_parentPeer ) + { + AnimatedImagesControl_Base::createPeer( i_toolkit, i_parentPeer ); + + lcl_updatePeer( getPeer(), getModel() ); + } + + + void SAL_CALL AnimatedImagesControl::elementInserted( const ContainerEvent& i_event ) + { + const Reference< XContainerListener > xPeerListener( getPeer(), UNO_QUERY ); + if ( xPeerListener.is() ) + xPeerListener->elementInserted( i_event ); + } + + + void SAL_CALL AnimatedImagesControl::elementRemoved( const ContainerEvent& i_event ) + { + const Reference< XContainerListener > xPeerListener( getPeer(), UNO_QUERY ); + if ( xPeerListener.is() ) + xPeerListener->elementRemoved( i_event ); + } + + + void SAL_CALL AnimatedImagesControl::elementReplaced( const ContainerEvent& i_event ) + { + const Reference< XContainerListener > xPeerListener( getPeer(), UNO_QUERY ); + if ( xPeerListener.is() ) + xPeerListener->elementReplaced( i_event ); + } + + + void SAL_CALL AnimatedImagesControl::disposing( const EventObject& i_event ) + { + UnoControlBase::disposing( i_event ); + } + +} + +namespace toolkit { + + struct AnimatedImagesControlModel_Data + { + ::std::vector< Sequence< OUString > > aImageSets; + }; + + namespace + { + void lcl_checkIndex( const AnimatedImagesControlModel_Data& i_data, const sal_Int32 i_index, const Reference< XInterface >& i_context, + const bool i_forInsert = false ) + { + if ( ( i_index < 0 ) || ( o3tl::make_unsigned( i_index ) > i_data.aImageSets.size() + ( i_forInsert ? 1 : 0 ) ) ) + throw IndexOutOfBoundsException( OUString(), i_context ); + } + + void lcl_notify( ::osl::ClearableMutexGuard& i_guard, ::cppu::OBroadcastHelper const & i_broadcaseHelper, + void ( SAL_CALL XContainerListener::*i_notificationMethod )( const ContainerEvent& ), + const sal_Int32 i_accessor, const Sequence< OUString >& i_imageURLs, const Reference< XInterface >& i_context ) + { + ::cppu::OInterfaceContainerHelper* pContainerListeners = i_broadcaseHelper.getContainer( cppu::UnoType<XContainerListener>::get() ); + if ( pContainerListeners == nullptr ) + return; + + ContainerEvent aEvent; + aEvent.Source = i_context; + aEvent.Accessor <<= i_accessor; + aEvent.Element <<= i_imageURLs; + + i_guard.clear(); + pContainerListeners->notifyEach( i_notificationMethod, aEvent ); + } + } + + + AnimatedImagesControlModel::AnimatedImagesControlModel( Reference< css::uno::XComponentContext > const & i_factory ) + :AnimatedImagesControlModel_Base( i_factory ) + ,m_xData( new AnimatedImagesControlModel_Data ) + { + ImplRegisterProperty( BASEPROPERTY_AUTO_REPEAT ); + ImplRegisterProperty( BASEPROPERTY_BORDER ); + ImplRegisterProperty( BASEPROPERTY_BORDERCOLOR ); + ImplRegisterProperty( BASEPROPERTY_BACKGROUNDCOLOR ); + ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL ); + ImplRegisterProperty( BASEPROPERTY_ENABLEVISIBLE ); + ImplRegisterProperty( BASEPROPERTY_HELPTEXT ); + ImplRegisterProperty( BASEPROPERTY_HELPURL ); + ImplRegisterProperty( BASEPROPERTY_IMAGE_SCALE_MODE ); + ImplRegisterProperty( BASEPROPERTY_STEP_TIME ); + } + + + AnimatedImagesControlModel::AnimatedImagesControlModel( const AnimatedImagesControlModel& i_copySource ) + :AnimatedImagesControlModel_Base( i_copySource ) + ,m_xData( new AnimatedImagesControlModel_Data( *i_copySource.m_xData ) ) + { + } + + + AnimatedImagesControlModel::~AnimatedImagesControlModel() + { + } + + + rtl::Reference<UnoControlModel> AnimatedImagesControlModel::Clone() const + { + return new AnimatedImagesControlModel( *this ); + } + + + Reference< css::beans::XPropertySetInfo > SAL_CALL AnimatedImagesControlModel::getPropertySetInfo( ) + { + static Reference< css::beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; + } + + + OUString SAL_CALL AnimatedImagesControlModel::getServiceName() + { + return "com.sun.star.awt.AnimatedImagesControlModel"; + } + + + OUString SAL_CALL AnimatedImagesControlModel::getImplementationName( ) + { + return "org.openoffice.comp.toolkit.AnimatedImagesControlModel"; + } + + + Sequence< OUString > SAL_CALL AnimatedImagesControlModel::getSupportedServiceNames() + { + return { "com.sun.star.awt.AnimatedImagesControlModel", "com.sun.star.awt.UnoControlModel" }; + } + + + void SAL_CALL AnimatedImagesControlModel::setFastPropertyValue_NoBroadcast( sal_Int32 i_handle, const Any& i_value ) + { + switch ( i_handle ) + { + case BASEPROPERTY_IMAGE_SCALE_MODE: + { + sal_Int16 nImageScaleMode( ImageScaleMode::ANISOTROPIC ); + OSL_VERIFY( i_value >>= nImageScaleMode ); // convertFastPropertyValue ensures that this has the proper type + if ( ( nImageScaleMode != ImageScaleMode::NONE ) + && ( nImageScaleMode != ImageScaleMode::ISOTROPIC ) + && ( nImageScaleMode != ImageScaleMode::ANISOTROPIC ) + ) + throw IllegalArgumentException( OUString(), *this, 1 ); + } + break; + } + + AnimatedImagesControlModel_Base::setFastPropertyValue_NoBroadcast( i_handle, i_value ); + } + + + Any AnimatedImagesControlModel::ImplGetDefaultValue( sal_uInt16 i_propertyId ) const + { + switch ( i_propertyId ) + { + case BASEPROPERTY_DEFAULTCONTROL: + return makeAny( OUString("com.sun.star.awt.AnimatedImagesControl") ); + + case BASEPROPERTY_BORDER: + return makeAny( css::awt::VisualEffect::NONE ); + + case BASEPROPERTY_STEP_TIME: + return makeAny( sal_Int32(100) ); + + case BASEPROPERTY_AUTO_REPEAT: + return makeAny( true ); + + case BASEPROPERTY_IMAGE_SCALE_MODE: + return makeAny( ImageScaleMode::NONE ); + + default: + return UnoControlModel::ImplGetDefaultValue( i_propertyId ); + } + } + + + ::cppu::IPropertyArrayHelper& SAL_CALL AnimatedImagesControlModel::getInfoHelper() + { + static UnoPropertyArrayHelper aHelper( ImplGetPropertyIds() ); + return aHelper; + } + + + ::sal_Int32 SAL_CALL AnimatedImagesControlModel::getStepTime() + { + sal_Int32 nStepTime( 100 ); + OSL_VERIFY( getPropertyValue( GetPropertyName( BASEPROPERTY_STEP_TIME ) ) >>= nStepTime ); + return nStepTime; + } + + + void SAL_CALL AnimatedImagesControlModel::setStepTime( ::sal_Int32 i_stepTime ) + { + setPropertyValue( GetPropertyName( BASEPROPERTY_STEP_TIME ), makeAny( i_stepTime ) ); + } + + + sal_Bool SAL_CALL AnimatedImagesControlModel::getAutoRepeat() + { + bool bAutoRepeat( true ); + OSL_VERIFY( getPropertyValue( GetPropertyName( BASEPROPERTY_AUTO_REPEAT ) ) >>= bAutoRepeat ); + return bAutoRepeat; + } + + + void SAL_CALL AnimatedImagesControlModel::setAutoRepeat( sal_Bool i_autoRepeat ) + { + setPropertyValue( GetPropertyName( BASEPROPERTY_AUTO_REPEAT ), makeAny( i_autoRepeat ) ); + } + + + ::sal_Int16 SAL_CALL AnimatedImagesControlModel::getScaleMode() + { + sal_Int16 nImageScaleMode( ImageScaleMode::ANISOTROPIC ); + OSL_VERIFY( getPropertyValue( GetPropertyName( BASEPROPERTY_IMAGE_SCALE_MODE ) ) >>= nImageScaleMode ); + return nImageScaleMode; + } + + + void SAL_CALL AnimatedImagesControlModel::setScaleMode( ::sal_Int16 i_scaleMode ) + { + setPropertyValue( GetPropertyName( BASEPROPERTY_IMAGE_SCALE_MODE ), makeAny( i_scaleMode ) ); + } + + + ::sal_Int32 SAL_CALL AnimatedImagesControlModel::getImageSetCount( ) + { + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + if ( GetBroadcastHelper().bDisposed || GetBroadcastHelper().bInDispose ) + throw DisposedException(); + + return m_xData->aImageSets.size(); + } + + + Sequence< OUString > SAL_CALL AnimatedImagesControlModel::getImageSet( ::sal_Int32 i_index ) + { + ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + if ( GetBroadcastHelper().bDisposed || GetBroadcastHelper().bInDispose ) + throw DisposedException(); + + lcl_checkIndex( *m_xData, i_index, *this ); + + return m_xData->aImageSets[ i_index ]; + } + + + void SAL_CALL AnimatedImagesControlModel::insertImageSet( ::sal_Int32 i_index, const Sequence< OUString >& i_imageURLs ) + { + ::osl::ClearableMutexGuard aGuard( GetMutex() ); + // sanity checks + if ( GetBroadcastHelper().bDisposed || GetBroadcastHelper().bInDispose ) + throw DisposedException(); + + lcl_checkIndex( *m_xData, i_index, *this, true ); + + // actual insertion + m_xData->aImageSets.insert( m_xData->aImageSets.begin() + i_index, i_imageURLs ); + + // listener notification + lcl_notify( aGuard, BrdcstHelper, &XContainerListener::elementInserted, i_index, i_imageURLs, *this ); + } + + + void SAL_CALL AnimatedImagesControlModel::replaceImageSet( ::sal_Int32 i_index, const Sequence< OUString >& i_imageURLs ) + { + ::osl::ClearableMutexGuard aGuard( GetMutex() ); + // sanity checks + if ( GetBroadcastHelper().bDisposed || GetBroadcastHelper().bInDispose ) + throw DisposedException(); + + lcl_checkIndex( *m_xData, i_index, *this ); + + // actual insertion + m_xData->aImageSets[ i_index ] = i_imageURLs; + + // listener notification + lcl_notify( aGuard, BrdcstHelper, &XContainerListener::elementReplaced, i_index, i_imageURLs, *this ); + } + + + void SAL_CALL AnimatedImagesControlModel::removeImageSet( ::sal_Int32 i_index ) + { + ::osl::ClearableMutexGuard aGuard( GetMutex() ); + // sanity checks + if ( GetBroadcastHelper().bDisposed || GetBroadcastHelper().bInDispose ) + throw DisposedException(); + + lcl_checkIndex( *m_xData, i_index, *this ); + + // actual removal + ::std::vector< Sequence< OUString > >::iterator removalPos = m_xData->aImageSets.begin() + i_index; + Sequence< OUString > aRemovedElement( *removalPos ); + m_xData->aImageSets.erase( removalPos ); + + // listener notification + lcl_notify( aGuard, BrdcstHelper, &XContainerListener::elementRemoved, i_index, aRemovedElement, *this ); + } + + + void SAL_CALL AnimatedImagesControlModel::addContainerListener( const Reference< XContainerListener >& i_listener ) + { + BrdcstHelper.addListener( cppu::UnoType<XContainerListener>::get(), i_listener ); + } + + + void SAL_CALL AnimatedImagesControlModel::removeContainerListener( const Reference< XContainerListener >& i_listener ) + { + BrdcstHelper.removeListener( cppu::UnoType<XContainerListener>::get(), i_listener ); + } + +} + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * +org_openoffice_comp_toolkit_AnimatedImagesControl_get_implementation( + css::uno::XComponentContext *, + css::uno::Sequence<css::uno::Any> const &) +{ + return cppu::acquire(new AnimatedImagesControl()); +} + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * +org_openoffice_comp_toolkit_AnimatedImagesControlModel_get_implementation( + css::uno::XComponentContext *context, + css::uno::Sequence<css::uno::Any> const &) +{ + return cppu::acquire(new toolkit::AnimatedImagesControlModel(context)); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |