1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski #include "precompiled_toolkit.hxx"
25*b1cdbd2cSJim Jagielski 
26*b1cdbd2cSJim Jagielski #include "toolkit/awt/animatedimagespeer.hxx"
27*b1cdbd2cSJim Jagielski #include "toolkit/helper/property.hxx"
28*b1cdbd2cSJim Jagielski 
29*b1cdbd2cSJim Jagielski /** === begin UNO includes === **/
30*b1cdbd2cSJim Jagielski #include <com/sun/star/awt/XAnimatedImages.hpp>
31*b1cdbd2cSJim Jagielski #include <com/sun/star/awt/Size.hpp>
32*b1cdbd2cSJim Jagielski #include <com/sun/star/graphic/XGraphicProvider.hpp>
33*b1cdbd2cSJim Jagielski #include <com/sun/star/beans/XPropertySet.hpp>
34*b1cdbd2cSJim Jagielski #include <com/sun/star/graphic/XGraphic.hpp>
35*b1cdbd2cSJim Jagielski #include <com/sun/star/awt/ImageScaleMode.hpp>
36*b1cdbd2cSJim Jagielski /** === end UNO includes === **/
37*b1cdbd2cSJim Jagielski 
38*b1cdbd2cSJim Jagielski #include <comphelper/componentcontext.hxx>
39*b1cdbd2cSJim Jagielski #include <comphelper/namedvaluecollection.hxx>
40*b1cdbd2cSJim Jagielski #include <comphelper/processfactory.hxx>
41*b1cdbd2cSJim Jagielski #include <rtl/ustrbuf.hxx>
42*b1cdbd2cSJim Jagielski #include <tools/diagnose_ex.h>
43*b1cdbd2cSJim Jagielski #include <tools/urlobj.hxx>
44*b1cdbd2cSJim Jagielski #include <vcl/throbber.hxx>
45*b1cdbd2cSJim Jagielski 
46*b1cdbd2cSJim Jagielski #include <limits>
47*b1cdbd2cSJim Jagielski 
48*b1cdbd2cSJim Jagielski //......................................................................................................................
49*b1cdbd2cSJim Jagielski namespace toolkit
50*b1cdbd2cSJim Jagielski {
51*b1cdbd2cSJim Jagielski //......................................................................................................................
52*b1cdbd2cSJim Jagielski 
53*b1cdbd2cSJim Jagielski 	/** === begin UNO using === **/
54*b1cdbd2cSJim Jagielski 	using ::com::sun::star::uno::Reference;
55*b1cdbd2cSJim Jagielski 	using ::com::sun::star::uno::XInterface;
56*b1cdbd2cSJim Jagielski 	using ::com::sun::star::uno::UNO_QUERY;
57*b1cdbd2cSJim Jagielski 	using ::com::sun::star::uno::UNO_QUERY_THROW;
58*b1cdbd2cSJim Jagielski 	using ::com::sun::star::uno::UNO_SET_THROW;
59*b1cdbd2cSJim Jagielski 	using ::com::sun::star::uno::Exception;
60*b1cdbd2cSJim Jagielski 	using ::com::sun::star::uno::RuntimeException;
61*b1cdbd2cSJim Jagielski 	using ::com::sun::star::uno::Any;
62*b1cdbd2cSJim Jagielski 	using ::com::sun::star::uno::makeAny;
63*b1cdbd2cSJim Jagielski 	using ::com::sun::star::uno::Sequence;
64*b1cdbd2cSJim Jagielski 	using ::com::sun::star::uno::Type;
65*b1cdbd2cSJim Jagielski     using ::com::sun::star::lang::EventObject;
66*b1cdbd2cSJim Jagielski     using ::com::sun::star::container::ContainerEvent;
67*b1cdbd2cSJim Jagielski     using ::com::sun::star::awt::XAnimatedImages;
68*b1cdbd2cSJim Jagielski     using ::com::sun::star::awt::Size;
69*b1cdbd2cSJim Jagielski     using ::com::sun::star::lang::XMultiServiceFactory;
70*b1cdbd2cSJim Jagielski     using ::com::sun::star::graphic::XGraphicProvider;
71*b1cdbd2cSJim Jagielski     using ::com::sun::star::beans::XPropertySet;
72*b1cdbd2cSJim Jagielski     using ::com::sun::star::graphic::XGraphic;
73*b1cdbd2cSJim Jagielski 	/** === end UNO using === **/
74*b1cdbd2cSJim Jagielski     namespace ImageScaleMode = ::com::sun::star::awt::ImageScaleMode;
75*b1cdbd2cSJim Jagielski 
76*b1cdbd2cSJim Jagielski 	//==================================================================================================================
77*b1cdbd2cSJim Jagielski 	//= AnimatedImagesPeer_Data
78*b1cdbd2cSJim Jagielski 	//==================================================================================================================
79*b1cdbd2cSJim Jagielski     struct CachedImage
80*b1cdbd2cSJim Jagielski     {
81*b1cdbd2cSJim Jagielski         ::rtl::OUString                 sImageURL;
82*b1cdbd2cSJim Jagielski         mutable Reference< XGraphic >   xGraphic;
83*b1cdbd2cSJim Jagielski 
CachedImagetoolkit::CachedImage84*b1cdbd2cSJim Jagielski         CachedImage()
85*b1cdbd2cSJim Jagielski             :sImageURL()
86*b1cdbd2cSJim Jagielski             ,xGraphic()
87*b1cdbd2cSJim Jagielski         {
88*b1cdbd2cSJim Jagielski         }
89*b1cdbd2cSJim Jagielski 
CachedImagetoolkit::CachedImage90*b1cdbd2cSJim Jagielski         CachedImage( ::rtl::OUString const& i_imageURL )
91*b1cdbd2cSJim Jagielski             :sImageURL( i_imageURL )
92*b1cdbd2cSJim Jagielski             ,xGraphic()
93*b1cdbd2cSJim Jagielski         {
94*b1cdbd2cSJim Jagielski         }
95*b1cdbd2cSJim Jagielski     };
96*b1cdbd2cSJim Jagielski 
97*b1cdbd2cSJim Jagielski     struct AnimatedImagesPeer_Data
98*b1cdbd2cSJim Jagielski     {
99*b1cdbd2cSJim Jagielski         AnimatedImagesPeer&                             rAntiImpl;
100*b1cdbd2cSJim Jagielski         ::std::vector< ::std::vector< CachedImage > >   aCachedImageSets;
101*b1cdbd2cSJim Jagielski 
AnimatedImagesPeer_Datatoolkit::AnimatedImagesPeer_Data102*b1cdbd2cSJim Jagielski         AnimatedImagesPeer_Data( AnimatedImagesPeer& i_antiImpl )
103*b1cdbd2cSJim Jagielski             :rAntiImpl( i_antiImpl )
104*b1cdbd2cSJim Jagielski             ,aCachedImageSets()
105*b1cdbd2cSJim Jagielski         {
106*b1cdbd2cSJim Jagielski         }
107*b1cdbd2cSJim Jagielski     };
108*b1cdbd2cSJim Jagielski 
109*b1cdbd2cSJim Jagielski 	//==================================================================================================================
110*b1cdbd2cSJim Jagielski 	//= helper
111*b1cdbd2cSJim Jagielski 	//==================================================================================================================
112*b1cdbd2cSJim Jagielski     namespace
113*b1cdbd2cSJim Jagielski     {
114*b1cdbd2cSJim Jagielski         //--------------------------------------------------------------------------------------------------------------
lcl_ensureImage_throw(Reference<XGraphicProvider> const & i_graphicProvider,const bool i_isHighContrast,const CachedImage & i_cachedImage)115*b1cdbd2cSJim Jagielski         bool lcl_ensureImage_throw( Reference< XGraphicProvider > const& i_graphicProvider, const bool i_isHighContrast, const CachedImage& i_cachedImage )
116*b1cdbd2cSJim Jagielski         {
117*b1cdbd2cSJim Jagielski             if ( !i_cachedImage.xGraphic.is() )
118*b1cdbd2cSJim Jagielski             {
119*b1cdbd2cSJim Jagielski                 ::comphelper::NamedValueCollection aMediaProperties;
120*b1cdbd2cSJim Jagielski                 if ( i_isHighContrast )
121*b1cdbd2cSJim Jagielski                 {
122*b1cdbd2cSJim Jagielski                     // try (to find) the high-contrast version of the graphic first
123*b1cdbd2cSJim Jagielski                     INetURLObject aURL( i_cachedImage.sImageURL );
124*b1cdbd2cSJim Jagielski                     if ( aURL.GetProtocol() != INET_PROT_PRIV_SOFFICE )
125*b1cdbd2cSJim Jagielski                     {
126*b1cdbd2cSJim Jagielski                         rtl::OUString sURL( i_cachedImage.sImageURL );
127*b1cdbd2cSJim Jagielski                         const sal_Int32 separatorPos = sURL.lastIndexOf( '/' );
128*b1cdbd2cSJim Jagielski                         if ( separatorPos != -1 )
129*b1cdbd2cSJim Jagielski                         {
130*b1cdbd2cSJim Jagielski                             ::rtl::OUStringBuffer composer;
131*b1cdbd2cSJim Jagielski                             composer.append( sURL.copy( 0, separatorPos ) );
132*b1cdbd2cSJim Jagielski                             composer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "/hicontrast" ) );
133*b1cdbd2cSJim Jagielski                             composer.append( sURL.copy( separatorPos ) );
134*b1cdbd2cSJim Jagielski 
135*b1cdbd2cSJim Jagielski                             aMediaProperties.put( "URL", composer.makeStringAndClear() );
136*b1cdbd2cSJim Jagielski                             i_cachedImage.xGraphic.set( i_graphicProvider->queryGraphic( aMediaProperties.getPropertyValues() ), UNO_QUERY );
137*b1cdbd2cSJim Jagielski                         }
138*b1cdbd2cSJim Jagielski                     }
139*b1cdbd2cSJim Jagielski                 }
140*b1cdbd2cSJim Jagielski                 if ( !i_cachedImage.xGraphic.is() )
141*b1cdbd2cSJim Jagielski                 {
142*b1cdbd2cSJim Jagielski                     aMediaProperties.put( "URL", i_cachedImage.sImageURL );
143*b1cdbd2cSJim Jagielski                     i_cachedImage.xGraphic.set( i_graphicProvider->queryGraphic( aMediaProperties.getPropertyValues() ), UNO_QUERY );
144*b1cdbd2cSJim Jagielski                 }
145*b1cdbd2cSJim Jagielski             }
146*b1cdbd2cSJim Jagielski             return i_cachedImage.xGraphic.is();
147*b1cdbd2cSJim Jagielski         }
148*b1cdbd2cSJim Jagielski 
149*b1cdbd2cSJim Jagielski 	    //--------------------------------------------------------------------------------------------------------------
lcl_getGraphicSizePixel(Reference<XGraphic> const & i_graphic)150*b1cdbd2cSJim Jagielski         Size lcl_getGraphicSizePixel( Reference< XGraphic > const& i_graphic )
151*b1cdbd2cSJim Jagielski         {
152*b1cdbd2cSJim Jagielski             Size aSizePixel;
153*b1cdbd2cSJim Jagielski             try
154*b1cdbd2cSJim Jagielski             {
155*b1cdbd2cSJim Jagielski                 if ( i_graphic.is() )
156*b1cdbd2cSJim Jagielski                 {
157*b1cdbd2cSJim Jagielski                     const Reference< XPropertySet > xGraphicProps( i_graphic, UNO_QUERY_THROW );
158*b1cdbd2cSJim Jagielski                     OSL_VERIFY( xGraphicProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SizePixel" ) ) ) >>= aSizePixel );
159*b1cdbd2cSJim Jagielski                 }
160*b1cdbd2cSJim Jagielski             }
161*b1cdbd2cSJim Jagielski             catch( const Exception& )
162*b1cdbd2cSJim Jagielski             {
163*b1cdbd2cSJim Jagielski             	DBG_UNHANDLED_EXCEPTION();
164*b1cdbd2cSJim Jagielski             }
165*b1cdbd2cSJim Jagielski             return aSizePixel;
166*b1cdbd2cSJim Jagielski         }
167*b1cdbd2cSJim Jagielski 
168*b1cdbd2cSJim Jagielski 	    //--------------------------------------------------------------------------------------------------------------
lcl_init(Sequence<::rtl::OUString> const & i_imageURLs,::std::vector<CachedImage> & o_images)169*b1cdbd2cSJim Jagielski         void lcl_init( Sequence< ::rtl::OUString > const& i_imageURLs, ::std::vector< CachedImage >& o_images )
170*b1cdbd2cSJim Jagielski         {
171*b1cdbd2cSJim Jagielski             o_images.resize(0);
172*b1cdbd2cSJim Jagielski             size_t count = size_t( i_imageURLs.getLength() );
173*b1cdbd2cSJim Jagielski             o_images.reserve( count );
174*b1cdbd2cSJim Jagielski             for ( size_t i = 0; i < count; ++i )
175*b1cdbd2cSJim Jagielski             {
176*b1cdbd2cSJim Jagielski                 o_images.push_back( CachedImage( i_imageURLs[i] ) );
177*b1cdbd2cSJim Jagielski             }
178*b1cdbd2cSJim Jagielski         }
179*b1cdbd2cSJim Jagielski 
180*b1cdbd2cSJim Jagielski 	    //--------------------------------------------------------------------------------------------------------------
lcl_updateImageList_nothrow(AnimatedImagesPeer_Data & i_data)181*b1cdbd2cSJim Jagielski         void lcl_updateImageList_nothrow( AnimatedImagesPeer_Data& i_data )
182*b1cdbd2cSJim Jagielski         {
183*b1cdbd2cSJim Jagielski             Throbber* pThrobber = dynamic_cast< Throbber* >( i_data.rAntiImpl.GetWindow() );
184*b1cdbd2cSJim Jagielski             if ( pThrobber == NULL )
185*b1cdbd2cSJim Jagielski                 return;
186*b1cdbd2cSJim Jagielski 
187*b1cdbd2cSJim Jagielski             try
188*b1cdbd2cSJim Jagielski             {
189*b1cdbd2cSJim Jagielski                 // collect the image sizes of the different image sets
190*b1cdbd2cSJim Jagielski                 const ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
191*b1cdbd2cSJim Jagielski                 const Reference< XGraphicProvider > xGraphicProvider( aContext.createComponent( "com.sun.star.graphic.GraphicProvider" ), UNO_QUERY_THROW );
192*b1cdbd2cSJim Jagielski 
193*b1cdbd2cSJim Jagielski                 const bool isHighContrast = pThrobber->GetSettings().GetStyleSettings().GetHighContrastMode();
194*b1cdbd2cSJim Jagielski 
195*b1cdbd2cSJim Jagielski                 sal_Int32 nPreferredSet = -1;
196*b1cdbd2cSJim Jagielski                 const size_t nImageSetCount = i_data.aCachedImageSets.size();
197*b1cdbd2cSJim Jagielski                 if ( nImageSetCount < 2 )
198*b1cdbd2cSJim Jagielski                 {
199*b1cdbd2cSJim Jagielski                     nPreferredSet = sal_Int32( nImageSetCount ) - 1;
200*b1cdbd2cSJim Jagielski                 }
201*b1cdbd2cSJim Jagielski                 else
202*b1cdbd2cSJim Jagielski                 {
203*b1cdbd2cSJim Jagielski                     ::std::vector< Size > aImageSizes( nImageSetCount );
204*b1cdbd2cSJim Jagielski                     for ( sal_Int32 nImageSet = 0; size_t( nImageSet ) < nImageSetCount; ++nImageSet )
205*b1cdbd2cSJim Jagielski                     {
206*b1cdbd2cSJim Jagielski                         ::std::vector< CachedImage > const& rImageSet( i_data.aCachedImageSets[ nImageSet ] );
207*b1cdbd2cSJim Jagielski                         if  (   ( rImageSet.empty() )
208*b1cdbd2cSJim Jagielski                             ||  ( !lcl_ensureImage_throw( xGraphicProvider, isHighContrast, rImageSet[0] ) )
209*b1cdbd2cSJim Jagielski                             )
210*b1cdbd2cSJim Jagielski                         {
211*b1cdbd2cSJim Jagielski                             aImageSizes[ nImageSet ] = Size( ::std::numeric_limits< long >::max(), ::std::numeric_limits< long >::max() );
212*b1cdbd2cSJim Jagielski                         }
213*b1cdbd2cSJim Jagielski                         else
214*b1cdbd2cSJim Jagielski                         {
215*b1cdbd2cSJim Jagielski                             aImageSizes[ nImageSet ] = lcl_getGraphicSizePixel( rImageSet[0].xGraphic );
216*b1cdbd2cSJim Jagielski                         }
217*b1cdbd2cSJim Jagielski                     }
218*b1cdbd2cSJim Jagielski 
219*b1cdbd2cSJim Jagielski                     // find the set with the smallest difference between window size and image size
220*b1cdbd2cSJim Jagielski                     const ::Size aWindowSizePixel = pThrobber->GetSizePixel();
221*b1cdbd2cSJim Jagielski                     long nMinimalDistance = ::std::numeric_limits< long >::max();
222*b1cdbd2cSJim Jagielski                     for (   ::std::vector< Size >::const_iterator check = aImageSizes.begin();
223*b1cdbd2cSJim Jagielski                             check != aImageSizes.end();
224*b1cdbd2cSJim Jagielski                             ++check
225*b1cdbd2cSJim Jagielski                         )
226*b1cdbd2cSJim Jagielski                     {
227*b1cdbd2cSJim Jagielski                         if  (   ( check->Width > aWindowSizePixel.Width() )
228*b1cdbd2cSJim Jagielski                             ||  ( check->Height > aWindowSizePixel.Height() )
229*b1cdbd2cSJim Jagielski                             )
230*b1cdbd2cSJim Jagielski                             // do not use an image set which doesn't fit into the window
231*b1cdbd2cSJim Jagielski                             continue;
232*b1cdbd2cSJim Jagielski 
233*b1cdbd2cSJim Jagielski                         const sal_Int64 distance =
234*b1cdbd2cSJim Jagielski                                 ( aWindowSizePixel.Width() - check->Width ) * ( aWindowSizePixel.Width() - check->Width )
235*b1cdbd2cSJim Jagielski                             +   ( aWindowSizePixel.Height() - check->Height ) * ( aWindowSizePixel.Height() - check->Height );
236*b1cdbd2cSJim Jagielski                         if ( distance < nMinimalDistance )
237*b1cdbd2cSJim Jagielski                         {
238*b1cdbd2cSJim Jagielski                             nMinimalDistance = distance;
239*b1cdbd2cSJim Jagielski                             nPreferredSet = check - aImageSizes.begin();
240*b1cdbd2cSJim Jagielski                         }
241*b1cdbd2cSJim Jagielski                     }
242*b1cdbd2cSJim Jagielski                 }
243*b1cdbd2cSJim Jagielski 
244*b1cdbd2cSJim Jagielski                 // found a set?
245*b1cdbd2cSJim Jagielski                 Sequence< Reference< XGraphic > > aImages;
246*b1cdbd2cSJim Jagielski                 if ( ( nPreferredSet >= 0 ) && ( size_t( nPreferredSet ) < nImageSetCount ) )
247*b1cdbd2cSJim Jagielski                 {
248*b1cdbd2cSJim Jagielski                     // => set the images
249*b1cdbd2cSJim Jagielski                     ::std::vector< CachedImage > const& rImageSet( i_data.aCachedImageSets[ nPreferredSet ] );
250*b1cdbd2cSJim Jagielski                     aImages.realloc( rImageSet.size() );
251*b1cdbd2cSJim Jagielski                     sal_Int32 imageIndex = 0;
252*b1cdbd2cSJim Jagielski                     for (   ::std::vector< CachedImage >::const_iterator cachedImage = rImageSet.begin();
253*b1cdbd2cSJim Jagielski                             cachedImage != rImageSet.end();
254*b1cdbd2cSJim Jagielski                             ++cachedImage, ++imageIndex
255*b1cdbd2cSJim Jagielski                         )
256*b1cdbd2cSJim Jagielski                     {
257*b1cdbd2cSJim Jagielski                         lcl_ensureImage_throw( xGraphicProvider, isHighContrast, *cachedImage );
258*b1cdbd2cSJim Jagielski                         aImages[ imageIndex ] = cachedImage->xGraphic;
259*b1cdbd2cSJim Jagielski                     }
260*b1cdbd2cSJim Jagielski                 }
261*b1cdbd2cSJim Jagielski                 pThrobber->setImageList( aImages );
262*b1cdbd2cSJim Jagielski             }
263*b1cdbd2cSJim Jagielski             catch( const Exception& )
264*b1cdbd2cSJim Jagielski             {
265*b1cdbd2cSJim Jagielski             	DBG_UNHANDLED_EXCEPTION();
266*b1cdbd2cSJim Jagielski             }
267*b1cdbd2cSJim Jagielski         }
268*b1cdbd2cSJim Jagielski 
269*b1cdbd2cSJim Jagielski 	    //--------------------------------------------------------------------------------------------------------------
lcl_updateImageList_nothrow(AnimatedImagesPeer_Data & i_data,const Reference<XAnimatedImages> & i_images)270*b1cdbd2cSJim Jagielski         void lcl_updateImageList_nothrow( AnimatedImagesPeer_Data& i_data, const Reference< XAnimatedImages >& i_images )
271*b1cdbd2cSJim Jagielski         {
272*b1cdbd2cSJim Jagielski             try
273*b1cdbd2cSJim Jagielski             {
274*b1cdbd2cSJim Jagielski                 const sal_Int32 nImageSetCount = i_images->getImageSetCount();
275*b1cdbd2cSJim Jagielski                 i_data.aCachedImageSets.resize(0);
276*b1cdbd2cSJim Jagielski                 for ( sal_Int32 set = 0;  set < nImageSetCount; ++set )
277*b1cdbd2cSJim Jagielski                 {
278*b1cdbd2cSJim Jagielski                     const Sequence< ::rtl::OUString > aImageURLs( i_images->getImageSet( set ) );
279*b1cdbd2cSJim Jagielski                     ::std::vector< CachedImage > aImages;
280*b1cdbd2cSJim Jagielski                     lcl_init( aImageURLs, aImages );
281*b1cdbd2cSJim Jagielski                     i_data.aCachedImageSets.push_back( aImages );
282*b1cdbd2cSJim Jagielski                 }
283*b1cdbd2cSJim Jagielski 
284*b1cdbd2cSJim Jagielski                 lcl_updateImageList_nothrow( i_data );
285*b1cdbd2cSJim Jagielski             }
286*b1cdbd2cSJim Jagielski             catch( const Exception& )
287*b1cdbd2cSJim Jagielski             {
288*b1cdbd2cSJim Jagielski             	DBG_UNHANDLED_EXCEPTION();
289*b1cdbd2cSJim Jagielski             }
290*b1cdbd2cSJim Jagielski         }
291*b1cdbd2cSJim Jagielski     }
292*b1cdbd2cSJim Jagielski 
293*b1cdbd2cSJim Jagielski 	//==================================================================================================================
294*b1cdbd2cSJim Jagielski 	//= AnimatedImagesPeer
295*b1cdbd2cSJim Jagielski 	//==================================================================================================================
296*b1cdbd2cSJim Jagielski 	//------------------------------------------------------------------------------------------------------------------
AnimatedImagesPeer()297*b1cdbd2cSJim Jagielski     AnimatedImagesPeer::AnimatedImagesPeer()
298*b1cdbd2cSJim Jagielski         :AnimatedImagesPeer_Base()
299*b1cdbd2cSJim Jagielski         ,m_pData( new AnimatedImagesPeer_Data( *this ) )
300*b1cdbd2cSJim Jagielski     {
301*b1cdbd2cSJim Jagielski     }
302*b1cdbd2cSJim Jagielski 
303*b1cdbd2cSJim Jagielski 	//------------------------------------------------------------------------------------------------------------------
~AnimatedImagesPeer()304*b1cdbd2cSJim Jagielski     AnimatedImagesPeer::~AnimatedImagesPeer()
305*b1cdbd2cSJim Jagielski     {
306*b1cdbd2cSJim Jagielski     }
307*b1cdbd2cSJim Jagielski 
308*b1cdbd2cSJim Jagielski 	//------------------------------------------------------------------------------------------------------------------
startAnimation()309*b1cdbd2cSJim Jagielski     void SAL_CALL AnimatedImagesPeer::startAnimation(  ) throw (RuntimeException)
310*b1cdbd2cSJim Jagielski     {
311*b1cdbd2cSJim Jagielski         ::vos::OGuard aGuard( GetMutex() );
312*b1cdbd2cSJim Jagielski         Throbber* pThrobber( dynamic_cast< Throbber* >( GetWindow() ) );
313*b1cdbd2cSJim Jagielski         if ( pThrobber != NULL)
314*b1cdbd2cSJim Jagielski             pThrobber->start();
315*b1cdbd2cSJim Jagielski     }
316*b1cdbd2cSJim Jagielski 
317*b1cdbd2cSJim Jagielski 	//------------------------------------------------------------------------------------------------------------------
stopAnimation()318*b1cdbd2cSJim Jagielski     void SAL_CALL AnimatedImagesPeer::stopAnimation(  ) throw (RuntimeException)
319*b1cdbd2cSJim Jagielski     {
320*b1cdbd2cSJim Jagielski         ::vos::OGuard aGuard( GetMutex() );
321*b1cdbd2cSJim Jagielski         Throbber* pThrobber( dynamic_cast< Throbber* >( GetWindow() ) );
322*b1cdbd2cSJim Jagielski         if ( pThrobber != NULL)
323*b1cdbd2cSJim Jagielski             pThrobber->stop();
324*b1cdbd2cSJim Jagielski     }
325*b1cdbd2cSJim Jagielski 
326*b1cdbd2cSJim Jagielski 	//------------------------------------------------------------------------------------------------------------------
isAnimationRunning()327*b1cdbd2cSJim Jagielski     ::sal_Bool SAL_CALL AnimatedImagesPeer::isAnimationRunning(  ) throw (RuntimeException)
328*b1cdbd2cSJim Jagielski     {
329*b1cdbd2cSJim Jagielski         ::vos::OGuard aGuard( GetMutex() );
330*b1cdbd2cSJim Jagielski         Throbber* pThrobber( dynamic_cast< Throbber* >( GetWindow() ) );
331*b1cdbd2cSJim Jagielski         if ( pThrobber != NULL)
332*b1cdbd2cSJim Jagielski             return pThrobber->isRunning();
333*b1cdbd2cSJim Jagielski         return sal_False;
334*b1cdbd2cSJim Jagielski     }
335*b1cdbd2cSJim Jagielski 
336*b1cdbd2cSJim Jagielski 	//------------------------------------------------------------------------------------------------------------------
setProperty(const::rtl::OUString & i_propertyName,const Any & i_value)337*b1cdbd2cSJim Jagielski     void SAL_CALL AnimatedImagesPeer::setProperty( const ::rtl::OUString& i_propertyName, const Any& i_value ) throw(RuntimeException)
338*b1cdbd2cSJim Jagielski     {
339*b1cdbd2cSJim Jagielski 	    ::vos::OGuard aGuard( GetMutex() );
340*b1cdbd2cSJim Jagielski 
341*b1cdbd2cSJim Jagielski         Throbber* pThrobber( dynamic_cast< Throbber* >( GetWindow() ) );
342*b1cdbd2cSJim Jagielski         if ( pThrobber == NULL )
343*b1cdbd2cSJim Jagielski         {
344*b1cdbd2cSJim Jagielski             VCLXWindow::setProperty( i_propertyName, i_value );
345*b1cdbd2cSJim Jagielski             return;
346*b1cdbd2cSJim Jagielski         }
347*b1cdbd2cSJim Jagielski 
348*b1cdbd2cSJim Jagielski         const sal_uInt16 nPropertyId = GetPropertyId( i_propertyName );
349*b1cdbd2cSJim Jagielski         switch ( nPropertyId )
350*b1cdbd2cSJim Jagielski         {
351*b1cdbd2cSJim Jagielski             case BASEPROPERTY_STEP_TIME:
352*b1cdbd2cSJim Jagielski             {
353*b1cdbd2cSJim Jagielski                 sal_Int32 nStepTime( 0 );
354*b1cdbd2cSJim Jagielski                 if ( i_value >>= nStepTime )
355*b1cdbd2cSJim Jagielski                     pThrobber->setStepTime( nStepTime );
356*b1cdbd2cSJim Jagielski                 break;
357*b1cdbd2cSJim Jagielski             }
358*b1cdbd2cSJim Jagielski             case BASEPROPERTY_AUTO_REPEAT:
359*b1cdbd2cSJim Jagielski             {
360*b1cdbd2cSJim Jagielski                 sal_Bool bRepeat( sal_True );
361*b1cdbd2cSJim Jagielski                 if ( i_value >>= bRepeat )
362*b1cdbd2cSJim Jagielski                     pThrobber->setRepeat( bRepeat );
363*b1cdbd2cSJim Jagielski                 break;
364*b1cdbd2cSJim Jagielski             }
365*b1cdbd2cSJim Jagielski 
366*b1cdbd2cSJim Jagielski             case BASEPROPERTY_IMAGE_SCALE_MODE:
367*b1cdbd2cSJim Jagielski             {
368*b1cdbd2cSJim Jagielski                 sal_Int16 nScaleMode( ImageScaleMode::ANISOTROPIC );
369*b1cdbd2cSJim Jagielski                 ImageControl* pImageControl = dynamic_cast< ImageControl* >( GetWindow() );
370*b1cdbd2cSJim Jagielski                 if ( pImageControl && ( i_value >>= nScaleMode ) )
371*b1cdbd2cSJim Jagielski                 {
372*b1cdbd2cSJim Jagielski                     pImageControl->SetScaleMode( nScaleMode );
373*b1cdbd2cSJim Jagielski                 }
374*b1cdbd2cSJim Jagielski             }
375*b1cdbd2cSJim Jagielski             break;
376*b1cdbd2cSJim Jagielski 
377*b1cdbd2cSJim Jagielski             default:
378*b1cdbd2cSJim Jagielski                 AnimatedImagesPeer_Base::setProperty( i_propertyName, i_value );
379*b1cdbd2cSJim Jagielski                 break;
380*b1cdbd2cSJim Jagielski         }
381*b1cdbd2cSJim Jagielski     }
382*b1cdbd2cSJim Jagielski 
383*b1cdbd2cSJim Jagielski 	//------------------------------------------------------------------------------------------------------------------
getProperty(const::rtl::OUString & i_propertyName)384*b1cdbd2cSJim Jagielski     Any SAL_CALL AnimatedImagesPeer::getProperty( const ::rtl::OUString& i_propertyName ) throw(RuntimeException)
385*b1cdbd2cSJim Jagielski     {
386*b1cdbd2cSJim Jagielski         ::vos::OGuard aGuard( GetMutex() );
387*b1cdbd2cSJim Jagielski 
388*b1cdbd2cSJim Jagielski         Any aReturn;
389*b1cdbd2cSJim Jagielski 
390*b1cdbd2cSJim Jagielski         Throbber* pThrobber( dynamic_cast< Throbber* >( GetWindow() ) );
391*b1cdbd2cSJim Jagielski         if ( pThrobber == NULL )
392*b1cdbd2cSJim Jagielski             return VCLXWindow::getProperty( i_propertyName );
393*b1cdbd2cSJim Jagielski 
394*b1cdbd2cSJim Jagielski         const sal_uInt16 nPropertyId = GetPropertyId( i_propertyName );
395*b1cdbd2cSJim Jagielski         switch ( nPropertyId )
396*b1cdbd2cSJim Jagielski         {
397*b1cdbd2cSJim Jagielski         case BASEPROPERTY_STEP_TIME:
398*b1cdbd2cSJim Jagielski             aReturn <<= pThrobber->getStepTime();
399*b1cdbd2cSJim Jagielski             break;
400*b1cdbd2cSJim Jagielski 
401*b1cdbd2cSJim Jagielski         case BASEPROPERTY_AUTO_REPEAT:
402*b1cdbd2cSJim Jagielski             aReturn <<= pThrobber->getRepeat();
403*b1cdbd2cSJim Jagielski             break;
404*b1cdbd2cSJim Jagielski 
405*b1cdbd2cSJim Jagielski         case BASEPROPERTY_IMAGE_SCALE_MODE:
406*b1cdbd2cSJim Jagielski             {
407*b1cdbd2cSJim Jagielski                 ImageControl const* pImageControl = dynamic_cast< ImageControl* >( GetWindow() );
408*b1cdbd2cSJim Jagielski                 aReturn <<= ( pImageControl ? pImageControl->GetScaleMode() : ImageScaleMode::ANISOTROPIC );
409*b1cdbd2cSJim Jagielski             }
410*b1cdbd2cSJim Jagielski             break;
411*b1cdbd2cSJim Jagielski 
412*b1cdbd2cSJim Jagielski         default:
413*b1cdbd2cSJim Jagielski             aReturn = AnimatedImagesPeer_Base::getProperty( i_propertyName );
414*b1cdbd2cSJim Jagielski             break;
415*b1cdbd2cSJim Jagielski         }
416*b1cdbd2cSJim Jagielski 
417*b1cdbd2cSJim Jagielski         return aReturn;
418*b1cdbd2cSJim Jagielski     }
419*b1cdbd2cSJim Jagielski 
420*b1cdbd2cSJim Jagielski     //------------------------------------------------------------------------------------------------------------------
ProcessWindowEvent(const VclWindowEvent & i_windowEvent)421*b1cdbd2cSJim Jagielski     void AnimatedImagesPeer::ProcessWindowEvent( const VclWindowEvent& i_windowEvent )
422*b1cdbd2cSJim Jagielski     {
423*b1cdbd2cSJim Jagielski         switch ( i_windowEvent.GetId() )
424*b1cdbd2cSJim Jagielski         {
425*b1cdbd2cSJim Jagielski         case VCLEVENT_WINDOW_RESIZE:
426*b1cdbd2cSJim Jagielski             lcl_updateImageList_nothrow( *m_pData );
427*b1cdbd2cSJim Jagielski             break;
428*b1cdbd2cSJim Jagielski         }
429*b1cdbd2cSJim Jagielski 
430*b1cdbd2cSJim Jagielski         AnimatedImagesPeer_Base::ProcessWindowEvent( i_windowEvent );
431*b1cdbd2cSJim Jagielski     }
432*b1cdbd2cSJim Jagielski 
433*b1cdbd2cSJim Jagielski     //------------------------------------------------------------------------------------------------------------------
impl_updateImages_nolck(const Reference<XInterface> & i_animatedImages)434*b1cdbd2cSJim Jagielski     void AnimatedImagesPeer::impl_updateImages_nolck( const Reference< XInterface >& i_animatedImages )
435*b1cdbd2cSJim Jagielski     {
436*b1cdbd2cSJim Jagielski         ::vos::OGuard aGuard( GetMutex() );
437*b1cdbd2cSJim Jagielski 
438*b1cdbd2cSJim Jagielski         lcl_updateImageList_nothrow( *m_pData, Reference< XAnimatedImages >( i_animatedImages, UNO_QUERY_THROW ) );
439*b1cdbd2cSJim Jagielski     }
440*b1cdbd2cSJim Jagielski 
441*b1cdbd2cSJim Jagielski     //------------------------------------------------------------------------------------------------------------------
elementInserted(const ContainerEvent & i_event)442*b1cdbd2cSJim Jagielski     void SAL_CALL AnimatedImagesPeer::elementInserted( const ContainerEvent& i_event ) throw (RuntimeException)
443*b1cdbd2cSJim Jagielski     {
444*b1cdbd2cSJim Jagielski         ::vos::OGuard aGuard( GetMutex() );
445*b1cdbd2cSJim Jagielski         Reference< XAnimatedImages > xAnimatedImages( i_event.Source, UNO_QUERY_THROW );
446*b1cdbd2cSJim Jagielski 
447*b1cdbd2cSJim Jagielski         sal_Int32 nPosition(0);
448*b1cdbd2cSJim Jagielski         OSL_VERIFY( i_event.Accessor >>= nPosition );
449*b1cdbd2cSJim Jagielski         size_t position = size_t( nPosition );
450*b1cdbd2cSJim Jagielski         if ( position > m_pData->aCachedImageSets.size() )
451*b1cdbd2cSJim Jagielski         {
452*b1cdbd2cSJim Jagielski             OSL_ENSURE( false, "AnimatedImagesPeer::elementInserted: illegal accessor/index!" );
453*b1cdbd2cSJim Jagielski             lcl_updateImageList_nothrow( *m_pData, xAnimatedImages );
454*b1cdbd2cSJim Jagielski         }
455*b1cdbd2cSJim Jagielski 
456*b1cdbd2cSJim Jagielski         Sequence< ::rtl::OUString > aImageURLs;
457*b1cdbd2cSJim Jagielski         OSL_VERIFY( i_event.Element >>= aImageURLs );
458*b1cdbd2cSJim Jagielski         ::std::vector< CachedImage > aImages;
459*b1cdbd2cSJim Jagielski         lcl_init( aImageURLs, aImages );
460*b1cdbd2cSJim Jagielski         m_pData->aCachedImageSets.insert( m_pData->aCachedImageSets.begin() + position, aImages );
461*b1cdbd2cSJim Jagielski         lcl_updateImageList_nothrow( *m_pData );
462*b1cdbd2cSJim Jagielski     }
463*b1cdbd2cSJim Jagielski 
464*b1cdbd2cSJim Jagielski     //------------------------------------------------------------------------------------------------------------------
elementRemoved(const ContainerEvent & i_event)465*b1cdbd2cSJim Jagielski     void SAL_CALL AnimatedImagesPeer::elementRemoved( const ContainerEvent& i_event ) throw (RuntimeException)
466*b1cdbd2cSJim Jagielski     {
467*b1cdbd2cSJim Jagielski         ::vos::OGuard aGuard( GetMutex() );
468*b1cdbd2cSJim Jagielski         Reference< XAnimatedImages > xAnimatedImages( i_event.Source, UNO_QUERY_THROW );
469*b1cdbd2cSJim Jagielski 
470*b1cdbd2cSJim Jagielski         sal_Int32 nPosition(0);
471*b1cdbd2cSJim Jagielski         OSL_VERIFY( i_event.Accessor >>= nPosition );
472*b1cdbd2cSJim Jagielski         size_t position = size_t( nPosition );
473*b1cdbd2cSJim Jagielski         if ( position >= m_pData->aCachedImageSets.size() )
474*b1cdbd2cSJim Jagielski         {
475*b1cdbd2cSJim Jagielski             OSL_ENSURE( false, "AnimatedImagesPeer::elementRemoved: illegal accessor/index!" );
476*b1cdbd2cSJim Jagielski             lcl_updateImageList_nothrow( *m_pData, xAnimatedImages );
477*b1cdbd2cSJim Jagielski         }
478*b1cdbd2cSJim Jagielski 
479*b1cdbd2cSJim Jagielski         m_pData->aCachedImageSets.erase( m_pData->aCachedImageSets.begin() + position );
480*b1cdbd2cSJim Jagielski         lcl_updateImageList_nothrow( *m_pData );
481*b1cdbd2cSJim Jagielski     }
482*b1cdbd2cSJim Jagielski 
483*b1cdbd2cSJim Jagielski     //------------------------------------------------------------------------------------------------------------------
elementReplaced(const ContainerEvent & i_event)484*b1cdbd2cSJim Jagielski     void SAL_CALL AnimatedImagesPeer::elementReplaced( const ContainerEvent& i_event ) throw (RuntimeException)
485*b1cdbd2cSJim Jagielski     {
486*b1cdbd2cSJim Jagielski         ::vos::OGuard aGuard( GetMutex() );
487*b1cdbd2cSJim Jagielski         Reference< XAnimatedImages > xAnimatedImages( i_event.Source, UNO_QUERY_THROW );
488*b1cdbd2cSJim Jagielski 
489*b1cdbd2cSJim Jagielski         sal_Int32 nPosition(0);
490*b1cdbd2cSJim Jagielski         OSL_VERIFY( i_event.Accessor >>= nPosition );
491*b1cdbd2cSJim Jagielski         size_t position = size_t( nPosition );
492*b1cdbd2cSJim Jagielski         if ( position >= m_pData->aCachedImageSets.size() )
493*b1cdbd2cSJim Jagielski         {
494*b1cdbd2cSJim Jagielski             OSL_ENSURE( false, "AnimatedImagesPeer::elementReplaced: illegal accessor/index!" );
495*b1cdbd2cSJim Jagielski             lcl_updateImageList_nothrow( *m_pData, xAnimatedImages );
496*b1cdbd2cSJim Jagielski         }
497*b1cdbd2cSJim Jagielski 
498*b1cdbd2cSJim Jagielski         Sequence< ::rtl::OUString > aImageURLs;
499*b1cdbd2cSJim Jagielski         OSL_VERIFY( i_event.Element >>= aImageURLs );
500*b1cdbd2cSJim Jagielski         ::std::vector< CachedImage > aImages;
501*b1cdbd2cSJim Jagielski         lcl_init( aImageURLs, aImages );
502*b1cdbd2cSJim Jagielski         m_pData->aCachedImageSets[ position ] = aImages;
503*b1cdbd2cSJim Jagielski         lcl_updateImageList_nothrow( *m_pData );
504*b1cdbd2cSJim Jagielski     }
505*b1cdbd2cSJim Jagielski 
506*b1cdbd2cSJim Jagielski     //------------------------------------------------------------------------------------------------------------------
disposing(const EventObject & i_event)507*b1cdbd2cSJim Jagielski     void SAL_CALL AnimatedImagesPeer::disposing( const EventObject& i_event ) throw (RuntimeException)
508*b1cdbd2cSJim Jagielski     {
509*b1cdbd2cSJim Jagielski         VCLXWindow::disposing( i_event );
510*b1cdbd2cSJim Jagielski     }
511*b1cdbd2cSJim Jagielski 
512*b1cdbd2cSJim Jagielski     //------------------------------------------------------------------------------------------------------------------
modified(const EventObject & i_event)513*b1cdbd2cSJim Jagielski     void SAL_CALL AnimatedImagesPeer::modified( const EventObject& i_event ) throw (RuntimeException)
514*b1cdbd2cSJim Jagielski     {
515*b1cdbd2cSJim Jagielski         impl_updateImages_nolck( i_event.Source );
516*b1cdbd2cSJim Jagielski     }
517*b1cdbd2cSJim Jagielski 
518*b1cdbd2cSJim Jagielski     //------------------------------------------------------------------------------------------------------------------
dispose()519*b1cdbd2cSJim Jagielski     void SAL_CALL AnimatedImagesPeer::dispose(  ) throw(RuntimeException)
520*b1cdbd2cSJim Jagielski     {
521*b1cdbd2cSJim Jagielski         AnimatedImagesPeer_Base::dispose();
522*b1cdbd2cSJim Jagielski         ::vos::OGuard aGuard( GetMutex() );
523*b1cdbd2cSJim Jagielski         m_pData->aCachedImageSets.resize(0);
524*b1cdbd2cSJim Jagielski     }
525*b1cdbd2cSJim Jagielski 
526*b1cdbd2cSJim Jagielski //......................................................................................................................
527*b1cdbd2cSJim Jagielski } // namespace toolkit
528*b1cdbd2cSJim Jagielski //......................................................................................................................
529