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< XComponentContext >& rxContext )
46 : : BaseControl ( rxContext )
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: */
|