Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
5 : : * This Source Code Form is subject to the terms of the Mozilla Public
6 : : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : :
20 : : #include "progressbar.hxx"
21 : :
22 : : #include <com/sun/star/awt/GradientStyle.hpp>
23 : : #include <com/sun/star/awt/RasterOperation.hpp>
24 : : #include <com/sun/star/awt/Gradient.hpp>
25 : : #include <com/sun/star/awt/XGraphics.hpp>
26 : : #include <tools/debug.hxx>
27 : : #include <cppuhelper/typeprovider.hxx>
28 : :
29 : : #include <math.h>
30 : : #include <limits.h>
31 : :
32 : : using namespace ::cppu ;
33 : : using namespace ::osl ;
34 : : using namespace ::rtl ;
35 : : using namespace ::com::sun::star::uno ;
36 : : using namespace ::com::sun::star::lang ;
37 : : using namespace ::com::sun::star::awt ;
38 : :
39 : : namespace unocontrols{
40 : :
41 : : //____________________________________________________________________________________________________________
42 : : // construct/destruct
43 : : //____________________________________________________________________________________________________________
44 : :
45 : 0 : ProgressBar::ProgressBar( const Reference< XMultiServiceFactory >& xFactory )
46 : : : BaseControl ( xFactory )
47 : : , m_bHorizontal ( PROGRESSBAR_DEFAULT_HORIZONTAL )
48 : : , m_aBlockSize ( PROGRESSBAR_DEFAULT_BLOCKDIMENSION )
49 : : , m_nForegroundColor ( PROGRESSBAR_DEFAULT_FOREGROUNDCOLOR )
50 : : , m_nBackgroundColor ( PROGRESSBAR_DEFAULT_BACKGROUNDCOLOR )
51 : : , m_nMinRange ( PROGRESSBAR_DEFAULT_MINRANGE )
52 : : , m_nMaxRange ( PROGRESSBAR_DEFAULT_MAXRANGE )
53 : : , m_nBlockValue ( PROGRESSBAR_DEFAULT_BLOCKVALUE )
54 : 0 : , m_nValue ( PROGRESSBAR_DEFAULT_VALUE )
55 : : {
56 : 0 : }
57 : :
58 : 0 : ProgressBar::~ProgressBar()
59 : : {
60 : 0 : }
61 : :
62 : : //____________________________________________________________________________________________________________
63 : : // XInterface
64 : : //____________________________________________________________________________________________________________
65 : :
66 : 0 : Any SAL_CALL ProgressBar::queryInterface( const Type& rType ) throw( RuntimeException )
67 : : {
68 : : // Attention:
69 : : // Don't use mutex or guard in this method!!! Is a method of XInterface.
70 : 0 : Any aReturn ;
71 : 0 : Reference< XInterface > xDel = BaseControl::impl_getDelegator();
72 : 0 : if ( xDel.is() )
73 : : {
74 : : // If an delegator exist, forward question to his queryInterface.
75 : : // Delegator will ask his own queryAggregation!
76 : 0 : aReturn = xDel->queryInterface( rType );
77 : : }
78 : : else
79 : : {
80 : : // If an delegator unknown, forward question to own queryAggregation.
81 : 0 : aReturn = queryAggregation( rType );
82 : : }
83 : :
84 : 0 : return aReturn ;
85 : : }
86 : :
87 : : //____________________________________________________________________________________________________________
88 : : // XInterface
89 : : //____________________________________________________________________________________________________________
90 : :
91 : 0 : void SAL_CALL ProgressBar::acquire() throw()
92 : : {
93 : : // Attention:
94 : : // Don't use mutex or guard in this method!!! Is a method of XInterface.
95 : :
96 : : // Forward to baseclass
97 : 0 : BaseControl::acquire();
98 : 0 : }
99 : :
100 : : //____________________________________________________________________________________________________________
101 : : // XInterface
102 : : //____________________________________________________________________________________________________________
103 : :
104 : 0 : void SAL_CALL ProgressBar::release() throw()
105 : : {
106 : : // Attention:
107 : : // Don't use mutex or guard in this method!!! Is a method of XInterface.
108 : :
109 : : // Forward to baseclass
110 : 0 : BaseControl::release();
111 : 0 : }
112 : :
113 : : //____________________________________________________________________________________________________________
114 : : // XTypeProvider
115 : : //____________________________________________________________________________________________________________
116 : :
117 : 0 : Sequence< Type > SAL_CALL ProgressBar::getTypes() throw( RuntimeException )
118 : : {
119 : : // Optimize this method !
120 : : // We initialize a static variable only one time. And we don't must use a mutex at every call!
121 : : // For the first call; pTypeCollection is NULL - for the second call pTypeCollection is different from NULL!
122 : : static OTypeCollection* pTypeCollection = NULL ;
123 : :
124 : 0 : if ( pTypeCollection == NULL )
125 : : {
126 : : // Ready for multithreading; get global mutex for first call of this method only! see before
127 : 0 : MutexGuard aGuard( Mutex::getGlobalMutex() );
128 : :
129 : : // Control these pointer again ... it can be, that another instance will be faster then these!
130 : 0 : if ( pTypeCollection == NULL )
131 : : {
132 : : // Create a static typecollection ...
133 : 0 : static OTypeCollection aTypeCollection ( ::getCppuType(( const Reference< XControlModel >*) NULL ) ,
134 : 0 : ::getCppuType(( const Reference< XProgressBar >*) NULL ) ,
135 : : BaseControl::getTypes()
136 : 0 : );
137 : : // ... and set his address to static pointer!
138 : 0 : pTypeCollection = &aTypeCollection ;
139 : 0 : }
140 : : }
141 : :
142 : 0 : return pTypeCollection->getTypes();
143 : : }
144 : :
145 : : //____________________________________________________________________________________________________________
146 : : // XAggregation
147 : : //____________________________________________________________________________________________________________
148 : :
149 : 0 : Any SAL_CALL ProgressBar::queryAggregation( const Type& aType ) throw( RuntimeException )
150 : : {
151 : : // Ask for my own supported interfaces ...
152 : : // Attention: XTypeProvider and XInterface are supported by OComponentHelper!
153 : : Any aReturn ( ::cppu::queryInterface( aType ,
154 : : static_cast< XControlModel* > ( this ) ,
155 : : static_cast< XProgressBar* > ( this )
156 : : )
157 : 0 : );
158 : :
159 : : // If searched interface not supported by this class ...
160 : 0 : if ( aReturn.hasValue() == sal_False )
161 : : {
162 : : // ... ask baseclasses.
163 : 0 : aReturn = BaseControl::queryAggregation( aType );
164 : : }
165 : :
166 : 0 : return aReturn ;
167 : : }
168 : :
169 : : //____________________________________________________________________________________________________________
170 : : // XProgressBar
171 : : //____________________________________________________________________________________________________________
172 : :
173 : 0 : void SAL_CALL ProgressBar::setForegroundColor( sal_Int32 nColor ) throw( RuntimeException )
174 : : {
175 : : // Ready for multithreading
176 : 0 : MutexGuard aGuard (m_aMutex) ;
177 : :
178 : : // Safe color for later use.
179 : 0 : m_nForegroundColor = nColor ;
180 : :
181 : : // Repaint control
182 : 0 : impl_paint ( 0, 0, impl_getGraphicsPeer() ) ;
183 : 0 : }
184 : :
185 : : //____________________________________________________________________________________________________________
186 : : // XProgressBar
187 : : //____________________________________________________________________________________________________________
188 : :
189 : 0 : void SAL_CALL ProgressBar::setBackgroundColor ( sal_Int32 nColor ) throw( RuntimeException )
190 : : {
191 : : // Ready for multithreading
192 : 0 : MutexGuard aGuard (m_aMutex) ;
193 : :
194 : : // Safe color for later use.
195 : 0 : m_nBackgroundColor = nColor ;
196 : :
197 : : // Repaint control
198 : 0 : impl_paint ( 0, 0, impl_getGraphicsPeer() ) ;
199 : 0 : }
200 : :
201 : : //____________________________________________________________________________________________________________
202 : : // XProgressBar
203 : : //____________________________________________________________________________________________________________
204 : :
205 : 0 : void SAL_CALL ProgressBar::setValue ( sal_Int32 nValue ) throw( RuntimeException )
206 : : {
207 : : // This method is defined for follow things:
208 : : // 1) Values >= _nMinRange
209 : : // 2) Values <= _nMaxRange
210 : :
211 : : // Ready for multithreading
212 : 0 : MutexGuard aGuard (m_aMutex) ;
213 : :
214 : : // save impossible cases
215 : : // This method is only defined for valid values
216 : : DBG_ASSERT ( (( nValue >= m_nMinRange ) && ( nValue <= m_nMaxRange )), "ProgressBar::setValue()\nNot valid value.\n" ) ;
217 : :
218 : : // If new value not valid ... do nothing in release version!
219 : 0 : if (
220 : : ( nValue >= m_nMinRange ) &&
221 : : ( nValue <= m_nMaxRange )
222 : : )
223 : : {
224 : : // New value is ok => save this
225 : 0 : m_nValue = nValue ;
226 : :
227 : : // Repaint to display changes
228 : 0 : impl_paint ( 0, 0, impl_getGraphicsPeer() ) ;
229 : 0 : }
230 : 0 : }
231 : :
232 : : //____________________________________________________________________________________________________________
233 : : // XProgressBar
234 : : //____________________________________________________________________________________________________________
235 : :
236 : 0 : void SAL_CALL ProgressBar::setRange ( sal_Int32 nMin, sal_Int32 nMax ) throw( RuntimeException )
237 : : {
238 : : // This method is defined for follow things:
239 : : // 1) All values of sal_Int32
240 : : // 2) Min < Max
241 : : // 3) Min > Max
242 : :
243 : : // save impossible cases
244 : : // This method is only defined for valid values
245 : : // If you ignore this, the release version wil produce an error "division by zero" in "ProgressBar::setValue()"!
246 : : DBG_ASSERT ( ( nMin != nMax ) , "ProgressBar::setRange()\nValues for MIN and MAX are the same. This is not allowed!\n" ) ;
247 : :
248 : : // Ready for multithreading
249 : 0 : MutexGuard aGuard (m_aMutex) ;
250 : :
251 : : // control the values for min and max
252 : 0 : if ( nMin < nMax )
253 : : {
254 : : // Take correct Min and Max
255 : 0 : m_nMinRange = nMin ;
256 : 0 : m_nMaxRange = nMax ;
257 : : }
258 : : else
259 : : {
260 : : // Change Min and Max automaticly
261 : 0 : m_nMinRange = nMax ;
262 : 0 : m_nMaxRange = nMin ;
263 : : }
264 : :
265 : : // assure that m_nValue is within the range
266 : 0 : if (!(m_nMinRange < m_nValue && m_nValue < m_nMaxRange))
267 : 0 : m_nValue = m_nMinRange;
268 : :
269 : 0 : impl_recalcRange () ;
270 : :
271 : : // Do not repaint the control at this place!!!
272 : : // An old "m_nValue" is set and can not be correct for this new range.
273 : : // Next call of "ProgressBar::setValue()" do this.
274 : 0 : }
275 : :
276 : : //____________________________________________________________________________________________________________
277 : : // XProgressBar
278 : : //____________________________________________________________________________________________________________
279 : :
280 : 0 : sal_Int32 SAL_CALL ProgressBar::getValue () throw( RuntimeException )
281 : : {
282 : : // Ready for multithreading
283 : 0 : MutexGuard aGuard (m_aMutex) ;
284 : :
285 : 0 : return ( m_nValue ) ;
286 : : }
287 : :
288 : : //____________________________________________________________________________________________________________
289 : : // XWindow
290 : : //____________________________________________________________________________________________________________
291 : :
292 : 0 : void SAL_CALL ProgressBar::setPosSize (
293 : : sal_Int32 nX,
294 : : sal_Int32 nY,
295 : : sal_Int32 nWidth,
296 : : sal_Int32 nHeight,
297 : : sal_Int16 nFlags
298 : : ) throw( RuntimeException )
299 : : {
300 : : // Take old size BEFORE you set the new values at baseclass!
301 : : // You will control changes. At the other way, the values are the same!
302 : 0 : Rectangle aBasePosSize = getPosSize () ;
303 : 0 : BaseControl::setPosSize (nX, nY, nWidth, nHeight, nFlags) ;
304 : :
305 : : // Do only, if size has changed.
306 : 0 : if (
307 : : ( nWidth != aBasePosSize.Width ) ||
308 : : ( nHeight != aBasePosSize.Height )
309 : : )
310 : : {
311 : 0 : impl_recalcRange ( ) ;
312 : 0 : impl_paint ( 0, 0, impl_getGraphicsPeer () ) ;
313 : : }
314 : 0 : }
315 : :
316 : : //____________________________________________________________________________________________________________
317 : : // XControl
318 : : //____________________________________________________________________________________________________________
319 : :
320 : 0 : sal_Bool SAL_CALL ProgressBar::setModel( const Reference< XControlModel >& /*xModel*/ ) throw( RuntimeException )
321 : : {
322 : : // A model is not possible for this control.
323 : 0 : return sal_False ;
324 : : }
325 : :
326 : : //____________________________________________________________________________________________________________
327 : : // XControl
328 : : //____________________________________________________________________________________________________________
329 : :
330 : 0 : Reference< XControlModel > SAL_CALL ProgressBar::getModel() throw( RuntimeException )
331 : : {
332 : : // A model is not possible for this control.
333 : 0 : return Reference< XControlModel >();
334 : : }
335 : :
336 : : //____________________________________________________________________________________________________________
337 : : // impl but public method to register service
338 : : //____________________________________________________________________________________________________________
339 : :
340 : 0 : const Sequence< OUString > ProgressBar::impl_getStaticSupportedServiceNames()
341 : : {
342 : 0 : MutexGuard aGuard( Mutex::getGlobalMutex() );
343 : 0 : Sequence< OUString > seqServiceNames( 1 );
344 : 0 : seqServiceNames.getArray() [0] = SERVICENAME_PROGRESSBAR;
345 : 0 : return seqServiceNames ;
346 : : }
347 : :
348 : : //____________________________________________________________________________________________________________
349 : : // impl but public method to register service
350 : : //____________________________________________________________________________________________________________
351 : :
352 : 0 : const OUString ProgressBar::impl_getStaticImplementationName()
353 : : {
354 : 0 : return OUString(IMPLEMENTATIONNAME_PROGRESSBAR );
355 : : }
356 : :
357 : : //____________________________________________________________________________________________________________
358 : : // protected method
359 : : //____________________________________________________________________________________________________________
360 : :
361 : 0 : void ProgressBar::impl_paint ( sal_Int32 nX, sal_Int32 nY, const Reference< XGraphics > & rGraphics )
362 : : {
363 : : // save impossible cases
364 : : DBG_ASSERT ( rGraphics.is(), "ProgressBar::paint()\nCalled with invalid Reference< XGraphics > ." ) ;
365 : :
366 : : // This paint method ist not buffered !!
367 : : // Every request paint the completely control. ( but only, if peer exist )
368 : 0 : if ( rGraphics.is () )
369 : : {
370 : 0 : MutexGuard aGuard (m_aMutex) ;
371 : :
372 : : // Clear background
373 : : // (same color for line and fill)
374 : 0 : rGraphics->setFillColor ( m_nBackgroundColor ) ;
375 : 0 : rGraphics->setLineColor ( m_nBackgroundColor ) ;
376 : 0 : rGraphics->drawRect ( nX, nY, impl_getWidth(), impl_getHeight() ) ;
377 : :
378 : : // same color for line and fill for blocks
379 : 0 : rGraphics->setFillColor ( m_nForegroundColor ) ;
380 : 0 : rGraphics->setLineColor ( m_nForegroundColor ) ;
381 : :
382 : 0 : sal_Int32 nBlockStart = 0 ; // = left site of new block
383 : 0 : sal_Int32 nBlockCount = m_nBlockValue!=0.00 ? (sal_Int32)((m_nValue-m_nMinRange)/m_nBlockValue) : 0 ; // = number of next block
384 : :
385 : : // Draw horizontal progressbar
386 : : // decision in "recalcRange()"
387 : 0 : if (m_bHorizontal)
388 : : {
389 : : // Step to left side of window
390 : 0 : nBlockStart = nX ;
391 : :
392 : 0 : for ( sal_Int16 i=1; i<=nBlockCount; ++i )
393 : : {
394 : : // step free field
395 : 0 : nBlockStart += PROGRESSBAR_FREESPACE ;
396 : : // paint block
397 : 0 : rGraphics->drawRect (nBlockStart, nY+PROGRESSBAR_FREESPACE, m_aBlockSize.Width, m_aBlockSize.Height) ;
398 : : // step next free field
399 : 0 : nBlockStart += m_aBlockSize.Width ;
400 : : }
401 : : }
402 : : // draw vertikal progressbar
403 : : // decision in "recalcRange()"
404 : : else
405 : : {
406 : : // step to bottom side of window
407 : 0 : nBlockStart = nY+impl_getHeight() ;
408 : 0 : nBlockStart -= m_aBlockSize.Height ;
409 : :
410 : 0 : for ( sal_Int16 i=1; i<=nBlockCount; ++i )
411 : : {
412 : : // step free field
413 : 0 : nBlockStart -= PROGRESSBAR_FREESPACE ;
414 : : // paint block
415 : 0 : rGraphics->drawRect (nX+PROGRESSBAR_FREESPACE, nBlockStart, m_aBlockSize.Width, m_aBlockSize.Height) ;
416 : : // step next free field
417 : 0 : nBlockStart -= m_aBlockSize.Height;
418 : : }
419 : : }
420 : :
421 : : // Paint shadow border around the progressbar
422 : 0 : rGraphics->setLineColor ( PROGRESSBAR_LINECOLOR_SHADOW ) ;
423 : 0 : rGraphics->drawLine ( nX, nY, impl_getWidth(), nY ) ;
424 : 0 : rGraphics->drawLine ( nX, nY, nX , impl_getHeight() ) ;
425 : :
426 : 0 : rGraphics->setLineColor ( PROGRESSBAR_LINECOLOR_BRIGHT ) ;
427 : 0 : rGraphics->drawLine ( impl_getWidth()-1, impl_getHeight()-1, impl_getWidth()-1, nY ) ;
428 : 0 : rGraphics->drawLine ( impl_getWidth()-1, impl_getHeight()-1, nX , impl_getHeight()-1 ) ;
429 : : }
430 : 0 : }
431 : :
432 : : //____________________________________________________________________________________________________________
433 : : // protected method
434 : : //____________________________________________________________________________________________________________
435 : :
436 : 0 : void ProgressBar::impl_recalcRange ()
437 : : {
438 : 0 : MutexGuard aGuard (m_aMutex) ;
439 : :
440 : 0 : sal_Int32 nWindowWidth = impl_getWidth() ;
441 : 0 : sal_Int32 nWindowHeight = impl_getHeight() ;
442 : : double fBlockHeight ;
443 : : double fBlockWidth ;
444 : : double fMaxBlocks ;
445 : :
446 : 0 : if( nWindowWidth > nWindowHeight )
447 : : {
448 : 0 : m_bHorizontal = sal_True ;
449 : 0 : fBlockHeight = (nWindowHeight-(2*PROGRESSBAR_FREESPACE)) ;
450 : 0 : fBlockWidth = fBlockHeight ;
451 : 0 : fMaxBlocks = nWindowWidth/(fBlockWidth+PROGRESSBAR_FREESPACE);
452 : : }
453 : : else
454 : : {
455 : 0 : m_bHorizontal = sal_False ;
456 : 0 : fBlockWidth = (nWindowWidth-(2*PROGRESSBAR_FREESPACE)) ;
457 : 0 : fBlockHeight = fBlockWidth ;
458 : 0 : fMaxBlocks = nWindowHeight/(fBlockHeight+PROGRESSBAR_FREESPACE);
459 : : }
460 : :
461 : 0 : double fRange = m_nMaxRange-m_nMinRange ;
462 : 0 : double fBlockValue = fRange/fMaxBlocks ;
463 : :
464 : 0 : m_nBlockValue = fBlockValue ;
465 : 0 : m_aBlockSize.Height = (sal_Int32)fBlockHeight;
466 : 0 : m_aBlockSize.Width = (sal_Int32)fBlockWidth ;
467 : 0 : }
468 : :
469 : : } // namespace unocontrols
470 : :
471 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|