Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include "vcl/throbber.hxx"
31 : : #include "vcl/svapp.hxx"
32 : :
33 : : #include <com/sun/star/uno/XComponentContext.hpp>
34 : : #include <com/sun/star/graphic/GraphicProvider.hpp>
35 : : #include <com/sun/star/graphic/XGraphicProvider.hpp>
36 : : #include <com/sun/star/awt/ImageScaleMode.hpp>
37 : :
38 : : #include <comphelper/componentcontext.hxx>
39 : : #include <comphelper/namedvaluecollection.hxx>
40 : : #include <comphelper/processfactory.hxx>
41 : : #include <rtl/ustrbuf.hxx>
42 : : #include <tools/diagnose_ex.h>
43 : : #include <tools/urlobj.hxx>
44 : :
45 : : #include <limits>
46 : :
47 : : using ::com::sun::star::uno::Sequence;
48 : : using ::com::sun::star::uno::Reference;
49 : : using ::com::sun::star::graphic::XGraphic;
50 : : using ::com::sun::star::graphic::XGraphicProvider;
51 : : using ::com::sun::star::uno::UNO_QUERY_THROW;
52 : : using ::com::sun::star::uno::UNO_QUERY;
53 : : using ::com::sun::star::uno::Exception;
54 : : namespace ImageScaleMode = ::com::sun::star::awt::ImageScaleMode;
55 : :
56 : : //----------------------------------------------------------------------------------------------------------------------
57 : 0 : Throbber::Throbber( Window* i_parentWindow, WinBits i_style, const ImageSet i_imageSet )
58 : : :ImageControl( i_parentWindow, i_style )
59 : : ,mbRepeat( sal_True )
60 : : ,mnStepTime( 100 )
61 : : ,mnCurStep( 0 )
62 : : ,mnStepCount( 0 )
63 [ # # ][ # # ]: 0 : ,meImageSet( i_imageSet )
64 : : {
65 [ # # ]: 0 : maWaitTimer.SetTimeout( mnStepTime );
66 [ # # ]: 0 : maWaitTimer.SetTimeoutHdl( LINK( this, Throbber, TimeOutHdl ) );
67 : :
68 [ # # ]: 0 : SetScaleMode( ImageScaleMode::None );
69 [ # # ]: 0 : initImages();
70 : 0 : }
71 : :
72 : : //--------------------------------------------------------------------
73 : 0 : Throbber::Throbber( Window* i_parentWindow, const ResId& i_resId, const ImageSet i_imageSet )
74 : : :ImageControl( i_parentWindow, i_resId )
75 : : ,mbRepeat( sal_True )
76 : : ,mnStepTime( 100 )
77 : : ,mnCurStep( 0 )
78 : : ,mnStepCount( 0 )
79 [ # # ][ # # ]: 0 : ,meImageSet( i_imageSet )
80 : : {
81 [ # # ]: 0 : maWaitTimer.SetTimeout( mnStepTime );
82 [ # # ]: 0 : maWaitTimer.SetTimeoutHdl( LINK( this, Throbber, TimeOutHdl ) );
83 : :
84 [ # # ]: 0 : SetScaleMode( ImageScaleMode::None );
85 [ # # ]: 0 : initImages();
86 : 0 : }
87 : :
88 : : //----------------------------------------------------------------------------------------------------------------------
89 [ # # ]: 0 : Throbber::~Throbber()
90 : : {
91 [ # # ]: 0 : maWaitTimer.Stop();
92 [ # # ]: 0 : }
93 : :
94 : : //----------------------------------------------------------------------------------------------------------------------
95 : : namespace
96 : : {
97 : : //..................................................................................................................
98 : 0 : ::rtl::OUString lcl_getHighContrastURL( ::rtl::OUString const& i_imageURL )
99 : : {
100 [ # # ]: 0 : INetURLObject aURL( i_imageURL );
101 [ # # ]: 0 : if ( aURL.GetProtocol() != INET_PROT_PRIV_SOFFICE )
102 : : {
103 [ # # ][ # # ]: 0 : OSL_VERIFY( aURL.insertName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "hicontrast" ) ), false, 0 ) );
104 [ # # ]: 0 : return aURL.GetMainURL( INetURLObject::NO_DECODE );
105 : : }
106 : : // the private: scheme is not considered to be hierarchical by INetURLObject, so manually insert the
107 : : // segment
108 : 0 : const sal_Int32 separatorPos = i_imageURL.indexOf( '/' );
109 [ # # ]: 0 : ENSURE_OR_RETURN( separatorPos != -1, "lcl_getHighContrastURL: unsipported URL scheme - cannot automatically determine HC version!", i_imageURL );
110 : :
111 : 0 : ::rtl::OUStringBuffer composer;
112 [ # # ]: 0 : composer.append( i_imageURL.copy( 0, separatorPos ) );
113 [ # # ]: 0 : composer.appendAscii( "/hicontrast" );
114 [ # # ]: 0 : composer.append( i_imageURL.copy( separatorPos ) );
115 [ # # ][ # # ]: 0 : return composer.makeStringAndClear();
116 : : }
117 : :
118 : : //..................................................................................................................
119 : 0 : ::std::vector< Image > lcl_loadImageSet( const Throbber::ImageSet i_imageSet, const bool i_isHiContrast )
120 : : {
121 [ # # ]: 0 : ::std::vector< Image > aImages;
122 [ # # ]: 0 : ENSURE_OR_RETURN( i_imageSet != Throbber::IMAGES_NONE, "lcl_loadImageSet: illegal image set", aImages );
123 : :
124 [ # # ]: 0 : const Reference< com::sun::star::uno::XComponentContext > aContext( ::comphelper::getProcessComponentContext() );
125 [ # # ]: 0 : const Reference< XGraphicProvider > xGraphicProvider( com::sun::star::graphic::GraphicProvider::create(aContext) );
126 : :
127 [ # # ]: 0 : ::std::vector< ::rtl::OUString > aImageURLs( Throbber::getDefaultImageURLs( i_imageSet ) );
128 [ # # ]: 0 : aImages.reserve( aImageURLs.size() );
129 : :
130 [ # # ]: 0 : ::comphelper::NamedValueCollection aMediaProperties;
131 [ # # ][ # # ]: 0 : for ( ::std::vector< ::rtl::OUString >::const_iterator imageURL = aImageURLs.begin();
[ # # ]
132 : 0 : imageURL != aImageURLs.end();
133 : : ++imageURL
134 : : )
135 : : {
136 : 0 : Reference< XGraphic > xGraphic;
137 [ # # ]: 0 : if ( i_isHiContrast )
138 : : {
139 [ # # ][ # # ]: 0 : aMediaProperties.put( "URL", lcl_getHighContrastURL( *imageURL ) );
140 [ # # ][ # # ]: 0 : xGraphic.set( xGraphicProvider->queryGraphic( aMediaProperties.getPropertyValues() ), UNO_QUERY );
[ # # ][ # # ]
[ # # ]
141 : : }
142 [ # # ]: 0 : if ( !xGraphic.is() )
143 : : {
144 [ # # ]: 0 : aMediaProperties.put( "URL", *imageURL );
145 [ # # ][ # # ]: 0 : xGraphic.set( xGraphicProvider->queryGraphic( aMediaProperties.getPropertyValues() ), UNO_QUERY );
[ # # ][ # # ]
[ # # ]
146 : : }
147 [ # # ][ # # ]: 0 : aImages.push_back( Image( xGraphic ) );
[ # # ]
148 : 0 : }
149 : :
150 [ # # ]: 0 : return aImages;
151 : : }
152 : : }
153 : :
154 : : //----------------------------------------------------------------------------------------------------------------------
155 : 0 : void Throbber::Resize()
156 : : {
157 : 0 : ImageControl::Resize();
158 : :
159 [ # # ]: 0 : if ( meImageSet == IMAGES_AUTO )
160 : 0 : initImages();
161 : 0 : }
162 : :
163 : : //----------------------------------------------------------------------------------------------------------------------
164 : 0 : void Throbber::initImages()
165 : : {
166 [ # # ]: 0 : if ( meImageSet == IMAGES_NONE )
167 : 0 : return;
168 : :
169 : : try
170 : : {
171 [ # # ]: 0 : ::std::vector< ::std::vector< Image > > aImageSets;
172 : 0 : const bool isHiContrast = GetSettings().GetStyleSettings().GetHighContrastMode();
173 [ # # ]: 0 : if ( meImageSet == IMAGES_AUTO )
174 : : {
175 [ # # ][ # # ]: 0 : aImageSets.push_back( lcl_loadImageSet( IMAGES_16_PX, isHiContrast ) );
176 [ # # ][ # # ]: 0 : aImageSets.push_back( lcl_loadImageSet( IMAGES_32_PX, isHiContrast ) );
177 [ # # ][ # # ]: 0 : aImageSets.push_back( lcl_loadImageSet( IMAGES_64_PX, isHiContrast ) );
178 : : }
179 : : else
180 : : {
181 [ # # ][ # # ]: 0 : aImageSets.push_back( lcl_loadImageSet( meImageSet, isHiContrast ) );
182 : : }
183 : :
184 : : // find the best matching image set (size-wise)
185 [ # # ]: 0 : const ::Size aWindowSizePixel = GetSizePixel();
186 : 0 : size_t nPreferredSet = 0;
187 [ # # ]: 0 : if ( aImageSets.size() > 1 )
188 : : {
189 : 0 : long nMinimalDistance = ::std::numeric_limits< long >::max();
190 [ # # # # ]: 0 : for ( ::std::vector< ::std::vector< Image > >::const_iterator check = aImageSets.begin();
[ # # ][ # # ]
191 : 0 : check != aImageSets.end();
192 : : ++check
193 : : )
194 : : {
195 [ # # ][ # # ]: 0 : if ( check->empty() )
196 : : {
197 : : SAL_WARN( "vcl.control", "Throbber::initImages: illegal image!" );
198 : 0 : continue;
199 : : }
200 : :
201 [ # # ][ # # ]: 0 : const Size aImageSize = (*check)[0].GetSizePixel();
[ # # ]
202 : :
203 [ # # # # ]: 0 : if ( ( aImageSize.Width() > aWindowSizePixel.Width() )
[ # # ]
204 : 0 : || ( aImageSize.Height() > aWindowSizePixel.Height() )
205 : : )
206 : : // do not use an image set which doesn't fit into the window
207 : 0 : continue;
208 : :
209 : : const sal_Int64 distance =
210 : 0 : ( aWindowSizePixel.Width() - aImageSize.Width() ) * ( aWindowSizePixel.Width() - aImageSize.Width() )
211 : 0 : + ( aWindowSizePixel.Height() - aImageSize.Height() ) * ( aWindowSizePixel.Height() - aImageSize.Height() );
212 [ # # ]: 0 : if ( distance < nMinimalDistance )
213 : : {
214 : 0 : nMinimalDistance = distance;
215 [ # # ]: 0 : nPreferredSet = check - aImageSets.begin();
216 : : }
217 : : }
218 : : }
219 : :
220 [ # # ]: 0 : if ( nPreferredSet < aImageSets.size() )
221 [ # # ][ # # ]: 0 : setImageList( aImageSets[nPreferredSet] );
[ # # ]
222 : : }
223 : 0 : catch( const Exception& )
224 : : {
225 : : DBG_UNHANDLED_EXCEPTION();
226 : : }
227 : : }
228 : :
229 : : //----------------------------------------------------------------------------------------------------------------------
230 : 0 : void Throbber::start()
231 : : {
232 : 0 : maWaitTimer.Start();
233 : 0 : }
234 : :
235 : : //----------------------------------------------------------------------------------------------------------------------
236 : 0 : void Throbber::stop()
237 : : {
238 : 0 : maWaitTimer.Stop();
239 : 0 : }
240 : :
241 : : //----------------------------------------------------------------------------------------------------------------------
242 : 0 : bool Throbber::isRunning() const
243 : : {
244 : 0 : return maWaitTimer.IsActive();
245 : : }
246 : :
247 : : //----------------------------------------------------------------------------------------------------------------------
248 : 0 : void Throbber::setImageList( ::std::vector< Image > const& i_images )
249 : : {
250 [ # # ]: 0 : maImageList = i_images;
251 : :
252 : 0 : mnStepCount = maImageList.size();
253 [ # # ][ # # ]: 0 : const Image aInitialImage( mnStepCount ? maImageList[ 0 ] : Image() );
[ # # ][ # # ]
254 [ # # ][ # # ]: 0 : SetImage( aInitialImage );
255 : 0 : }
256 : :
257 : : //----------------------------------------------------------------------------------------------------------------------
258 : 0 : void Throbber::setImageList( const Sequence< Reference< XGraphic > >& rImageList )
259 : : {
260 [ # # ]: 0 : ::std::vector< Image > aImages( rImageList.getLength() );
261 : : ::std::copy(
262 : : rImageList.getConstArray(),
263 : 0 : rImageList.getConstArray() + rImageList.getLength(),
264 : : aImages.begin()
265 [ # # ]: 0 : );
266 [ # # ]: 0 : setImageList( aImages );
267 : 0 : }
268 : :
269 : : //----------------------------------------------------------------------------------------------------------------------
270 : 0 : ::std::vector< ::rtl::OUString > Throbber::getDefaultImageURLs( const ImageSet i_imageSet )
271 : : {
272 [ # # ]: 0 : ::std::vector< ::rtl::OUString > aImageURLs;
273 : :
274 : 0 : sal_Char const* const pResolutions[] = { "16", "32", "64" };
275 : 0 : size_t const nImageCounts[] = { 6, 12, 12 };
276 : :
277 : 0 : size_t index = 0;
278 [ # # # # : 0 : switch ( i_imageSet )
# ]
279 : : {
280 : 0 : case IMAGES_16_PX: index = 0; break;
281 : 0 : case IMAGES_32_PX: index = 1; break;
282 : 0 : case IMAGES_64_PX: index = 2; break;
283 : : case IMAGES_NONE:
284 : : case IMAGES_AUTO:
285 : : OSL_ENSURE( false, "Throbber::getDefaultImageURLs: illegal image set!" );
286 : : return aImageURLs;
287 : : }
288 : :
289 [ # # ]: 0 : aImageURLs.reserve( nImageCounts[index] );
290 [ # # ]: 0 : for ( size_t i=0; i<nImageCounts[index]; ++i )
291 : : {
292 : 0 : ::rtl::OUStringBuffer aURL;
293 [ # # ]: 0 : aURL.appendAscii( "private:graphicrepository/shared/spinner-" );
294 [ # # ]: 0 : aURL.appendAscii( pResolutions[index] );
295 [ # # ]: 0 : aURL.appendAscii( "-" );
296 [ # # ]: 0 : if ( i < 9 )
297 [ # # ]: 0 : aURL.appendAscii( "0" );
298 [ # # ]: 0 : aURL.append ( sal_Int32( i + 1 ) );
299 [ # # ]: 0 : aURL.appendAscii( ".png" );
300 : :
301 [ # # ][ # # ]: 0 : aImageURLs.push_back( aURL.makeStringAndClear() );
302 : 0 : }
303 : :
304 : 0 : return aImageURLs;
305 : : }
306 : :
307 : : //----------------------------------------------------------------------------------------------------------------------
308 : 0 : IMPL_LINK_NOARG(Throbber, TimeOutHdl)
309 : : {
310 [ # # ]: 0 : SolarMutexGuard aGuard;
311 [ # # ]: 0 : if ( maImageList.empty() )
312 : 0 : return 0;
313 : :
314 [ # # ]: 0 : if ( mnCurStep < mnStepCount - 1 )
315 : 0 : mnCurStep += 1;
316 : : else
317 : : {
318 [ # # ]: 0 : if ( mbRepeat )
319 : : {
320 : : // start over
321 : 0 : mnCurStep = 0;
322 : : }
323 : : else
324 : : {
325 [ # # ]: 0 : stop();
326 : : }
327 : : }
328 : :
329 [ # # ][ # # ]: 0 : SetImage( maImageList[ mnCurStep ] );
330 : :
331 [ # # ]: 0 : return 0;
332 : : }
333 : :
334 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|