Update ooo320-m1
[ooovba.git] / UnoControls / source / controls / progressbar.cxx
blob05b22c9ef3ebd82379569032630a35f840847221
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: progressbar.cxx,v $
10 * $Revision: 1.9 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
30 //____________________________________________________________________________________________________________
31 // my own includes
32 //____________________________________________________________________________________________________________
34 #include "progressbar.hxx"
36 //____________________________________________________________________________________________________________
37 // includes of other projects
38 //____________________________________________________________________________________________________________
39 #include <com/sun/star/awt/GradientStyle.hpp>
40 #include <com/sun/star/awt/RasterOperation.hpp>
41 #include <com/sun/star/awt/Gradient.hpp>
42 #include <com/sun/star/awt/XGraphics.hpp>
43 #include <tools/debug.hxx>
44 #include <cppuhelper/typeprovider.hxx>
46 #include <math.h>
47 #include <limits.h>
49 //____________________________________________________________________________________________________________
50 // includes of my project
51 //____________________________________________________________________________________________________________
53 //____________________________________________________________________________________________________________
54 // namespace
55 //____________________________________________________________________________________________________________
57 using namespace ::cppu ;
58 using namespace ::osl ;
59 using namespace ::rtl ;
60 using namespace ::com::sun::star::uno ;
61 using namespace ::com::sun::star::lang ;
62 using namespace ::com::sun::star::awt ;
64 namespace unocontrols{
66 //____________________________________________________________________________________________________________
67 // construct/destruct
68 //____________________________________________________________________________________________________________
70 ProgressBar::ProgressBar( const Reference< XMultiServiceFactory >& xFactory )
71 : BaseControl ( xFactory )
72 , m_bHorizontal ( DEFAULT_HORIZONTAL )
73 , m_aBlockSize ( DEFAULT_BLOCKDIMENSION )
74 , m_nForegroundColor ( DEFAULT_FOREGROUNDCOLOR )
75 , m_nBackgroundColor ( DEFAULT_BACKGROUNDCOLOR )
76 , m_nMinRange ( DEFAULT_MINRANGE )
77 , m_nMaxRange ( DEFAULT_MAXRANGE )
78 , m_nBlockValue ( DEFAULT_BLOCKVALUE )
79 , m_nValue ( DEFAULT_VALUE )
83 ProgressBar::~ProgressBar()
87 //____________________________________________________________________________________________________________
88 // XInterface
89 //____________________________________________________________________________________________________________
91 Any SAL_CALL ProgressBar::queryInterface( const Type& rType ) throw( RuntimeException )
93 // Attention:
94 // Don't use mutex or guard in this method!!! Is a method of XInterface.
95 Any aReturn ;
96 Reference< XInterface > xDel = BaseControl::impl_getDelegator();
97 if ( xDel.is() )
99 // If an delegator exist, forward question to his queryInterface.
100 // Delegator will ask his own queryAggregation!
101 aReturn = xDel->queryInterface( rType );
103 else
105 // If an delegator unknown, forward question to own queryAggregation.
106 aReturn = queryAggregation( rType );
109 return aReturn ;
112 //____________________________________________________________________________________________________________
113 // XInterface
114 //____________________________________________________________________________________________________________
116 void SAL_CALL ProgressBar::acquire() throw()
118 // Attention:
119 // Don't use mutex or guard in this method!!! Is a method of XInterface.
121 // Forward to baseclass
122 BaseControl::acquire();
125 //____________________________________________________________________________________________________________
126 // XInterface
127 //____________________________________________________________________________________________________________
129 void SAL_CALL ProgressBar::release() throw()
131 // Attention:
132 // Don't use mutex or guard in this method!!! Is a method of XInterface.
134 // Forward to baseclass
135 BaseControl::release();
138 //____________________________________________________________________________________________________________
139 // XTypeProvider
140 //____________________________________________________________________________________________________________
142 Sequence< Type > SAL_CALL ProgressBar::getTypes() throw( RuntimeException )
144 // Optimize this method !
145 // We initialize a static variable only one time. And we don't must use a mutex at every call!
146 // For the first call; pTypeCollection is NULL - for the second call pTypeCollection is different from NULL!
147 static OTypeCollection* pTypeCollection = NULL ;
149 if ( pTypeCollection == NULL )
151 // Ready for multithreading; get global mutex for first call of this method only! see before
152 MutexGuard aGuard( Mutex::getGlobalMutex() );
154 // Control these pointer again ... it can be, that another instance will be faster then these!
155 if ( pTypeCollection == NULL )
157 // Create a static typecollection ...
158 static OTypeCollection aTypeCollection ( ::getCppuType(( const Reference< XControlModel >*)NULL ) ,
159 ::getCppuType(( const Reference< XProgressBar >*)NULL ) ,
160 BaseControl::getTypes()
162 // ... and set his address to static pointer!
163 pTypeCollection = &aTypeCollection ;
167 return pTypeCollection->getTypes();
170 //____________________________________________________________________________________________________________
171 // XAggregation
172 //____________________________________________________________________________________________________________
174 Any SAL_CALL ProgressBar::queryAggregation( const Type& aType ) throw( RuntimeException )
176 // Ask for my own supported interfaces ...
177 // Attention: XTypeProvider and XInterface are supported by OComponentHelper!
178 Any aReturn ( ::cppu::queryInterface( aType ,
179 static_cast< XControlModel* > ( this ) ,
180 static_cast< XProgressBar* > ( this )
184 // If searched interface not supported by this class ...
185 if ( aReturn.hasValue() == sal_False )
187 // ... ask baseclasses.
188 aReturn = BaseControl::queryAggregation( aType );
191 return aReturn ;
194 //____________________________________________________________________________________________________________
195 // XProgressBar
196 //____________________________________________________________________________________________________________
198 void SAL_CALL ProgressBar::setForegroundColor( sal_Int32 nColor ) throw( RuntimeException )
200 // Ready for multithreading
201 MutexGuard aGuard (m_aMutex) ;
203 // Safe color for later use.
204 m_nForegroundColor = nColor ;
206 // Repaint control
207 impl_paint ( 0, 0, impl_getGraphicsPeer() ) ;
210 //____________________________________________________________________________________________________________
211 // XProgressBar
212 //____________________________________________________________________________________________________________
214 void SAL_CALL ProgressBar::setBackgroundColor ( sal_Int32 nColor ) throw( RuntimeException )
216 // Ready for multithreading
217 MutexGuard aGuard (m_aMutex) ;
219 // Safe color for later use.
220 m_nBackgroundColor = nColor ;
222 // Repaint control
223 impl_paint ( 0, 0, impl_getGraphicsPeer() ) ;
226 //____________________________________________________________________________________________________________
227 // XProgressBar
228 //____________________________________________________________________________________________________________
230 void SAL_CALL ProgressBar::setValue ( sal_Int32 nValue ) throw( RuntimeException )
232 // This method is defined for follow things:
233 // 1) Values >= _nMinRange
234 // 2) Values <= _nMaxRange
236 // Ready for multithreading
237 MutexGuard aGuard (m_aMutex) ;
239 // save impossible cases
240 // This method is only defined for valid values
241 DBG_ASSERT ( (( nValue >= m_nMinRange ) && ( nValue <= m_nMaxRange )), "ProgressBar::setValue()\nNot valid value.\n" ) ;
243 // If new value not valid ... do nothing in release version!
244 if (
245 ( nValue >= m_nMinRange ) &&
246 ( nValue <= m_nMaxRange )
249 // New value is ok => save this
250 m_nValue = nValue ;
252 // Repaint to display changes
253 impl_paint ( 0, 0, impl_getGraphicsPeer() ) ;
257 //____________________________________________________________________________________________________________
258 // XProgressBar
259 //____________________________________________________________________________________________________________
261 void SAL_CALL ProgressBar::setRange ( sal_Int32 nMin, sal_Int32 nMax ) throw( RuntimeException )
263 // This method is defined for follow things:
264 // 1) All values of sal_Int32
265 // 2) Min < Max
266 // 3) Min > Max
268 // save impossible cases
269 // This method is only defined for valid values
270 // If you ignore this, the release version wil produce an error "division by zero" in "ProgressBar::setValue()"!
271 DBG_ASSERT ( ( nMin != nMax ) , "ProgressBar::setRange()\nValues for MIN and MAX are the same. This is not allowed!\n" ) ;
273 // Ready for multithreading
274 MutexGuard aGuard (m_aMutex) ;
276 // control the values for min and max
277 if ( nMin < nMax )
279 // Take correct Min and Max
280 m_nMinRange = nMin ;
281 m_nMaxRange = nMax ;
283 else
285 // Change Min and Max automaticly
286 m_nMinRange = nMax ;
287 m_nMaxRange = nMin ;
290 // assure that m_nValue is within the range
291 if (!(m_nMinRange < m_nValue && m_nValue < m_nMaxRange))
292 m_nValue = m_nMinRange;
294 impl_recalcRange () ;
296 // Do not repaint the control at this place!!!
297 // An old "m_nValue" is set and can not be correct for this new range.
298 // Next call of "ProgressBar::setValue()" do this.
301 //____________________________________________________________________________________________________________
302 // XProgressBar
303 //____________________________________________________________________________________________________________
305 sal_Int32 SAL_CALL ProgressBar::getValue () throw( RuntimeException )
307 // Ready for multithreading
308 MutexGuard aGuard (m_aMutex) ;
310 return ( m_nValue ) ;
313 //____________________________________________________________________________________________________________
314 // XWindow
315 //____________________________________________________________________________________________________________
317 void SAL_CALL ProgressBar::setPosSize ( sal_Int32 nX, sal_Int32 nY, sal_Int32 nWidth, sal_Int32 nHeight, sal_Int16 nFlags ) throw( RuntimeException )
319 // Take old size BEFORE you set the new values at baseclass!
320 // You will control changes. At the other way, the values are the same!
321 Rectangle aBasePosSize = getPosSize () ;
322 BaseControl::setPosSize (nX, nY, nWidth, nHeight, nFlags) ;
324 // Do only, if size has changed.
325 if (
326 ( nWidth != aBasePosSize.Width ) ||
327 ( nHeight != aBasePosSize.Height )
330 impl_recalcRange ( ) ;
331 impl_paint ( 0, 0, impl_getGraphicsPeer () ) ;
335 //____________________________________________________________________________________________________________
336 // XControl
337 //____________________________________________________________________________________________________________
339 sal_Bool SAL_CALL ProgressBar::setModel( const Reference< XControlModel >& /*xModel*/ ) throw( RuntimeException )
341 // A model is not possible for this control.
342 return sal_False ;
345 //____________________________________________________________________________________________________________
346 // XControl
347 //____________________________________________________________________________________________________________
349 Reference< XControlModel > SAL_CALL ProgressBar::getModel() throw( RuntimeException )
351 // A model is not possible for this control.
352 return Reference< XControlModel >();
355 //____________________________________________________________________________________________________________
356 // impl but public method to register service
357 //____________________________________________________________________________________________________________
359 const Sequence< OUString > ProgressBar::impl_getStaticSupportedServiceNames()
361 MutexGuard aGuard( Mutex::getGlobalMutex() );
362 Sequence< OUString > seqServiceNames( 1 );
363 seqServiceNames.getArray() [0] = OUString::createFromAscii( SERVICENAME_PROGRESSBAR );
364 return seqServiceNames ;
367 //____________________________________________________________________________________________________________
368 // impl but public method to register service
369 //____________________________________________________________________________________________________________
371 const OUString ProgressBar::impl_getStaticImplementationName()
373 return OUString::createFromAscii( IMPLEMENTATIONNAME_PROGRESSBAR );
376 //____________________________________________________________________________________________________________
377 // protected method
378 //____________________________________________________________________________________________________________
380 void ProgressBar::impl_paint ( sal_Int32 nX, sal_Int32 nY, const Reference< XGraphics > & rGraphics )
382 // save impossible cases
383 DBG_ASSERT ( rGraphics.is(), "ProgressBar::paint()\nCalled with invalid Reference< XGraphics > ." ) ;
385 // This paint method ist not buffered !!
386 // Every request paint the completely control. ( but only, if peer exist )
387 if ( rGraphics.is () )
389 MutexGuard aGuard (m_aMutex) ;
391 // Clear background
392 // (same color for line and fill)
393 rGraphics->setFillColor ( m_nBackgroundColor ) ;
394 rGraphics->setLineColor ( m_nBackgroundColor ) ;
395 rGraphics->drawRect ( nX, nY, impl_getWidth(), impl_getHeight() ) ;
397 // same color for line and fill for blocks
398 rGraphics->setFillColor ( m_nForegroundColor ) ;
399 rGraphics->setLineColor ( m_nForegroundColor ) ;
401 sal_Int32 nBlockStart = 0 ; // = left site of new block
402 sal_Int32 nBlockCount = m_nBlockValue!=0.00 ? (sal_Int32)((m_nValue-m_nMinRange)/m_nBlockValue) : 0 ; // = number of next block
404 // Draw horizontal progressbar
405 // decision in "recalcRange()"
406 if (m_bHorizontal)
408 // Step to left side of window
409 nBlockStart = nX ;
411 for ( sal_Int16 i=1; i<=nBlockCount; ++i )
413 // step free field
414 nBlockStart += FREESPACE ;
415 // paint block
416 rGraphics->drawRect (nBlockStart, nY+FREESPACE, m_aBlockSize.Width, m_aBlockSize.Height) ;
417 // step next free field
418 nBlockStart += m_aBlockSize.Width ;
421 // draw vertikal progressbar
422 // decision in "recalcRange()"
423 else
425 // step to bottom side of window
426 nBlockStart = nY+impl_getHeight() ;
427 nBlockStart -= m_aBlockSize.Height ;
429 for ( sal_Int16 i=1; i<=nBlockCount; ++i )
431 // step free field
432 nBlockStart -= FREESPACE ;
433 // paint block
434 rGraphics->drawRect (nX+FREESPACE, nBlockStart, m_aBlockSize.Width, m_aBlockSize.Height) ;
435 // step next free field
436 nBlockStart -= m_aBlockSize.Height;
440 // Paint shadow border around the progressbar
441 rGraphics->setLineColor ( LINECOLOR_SHADOW ) ;
442 rGraphics->drawLine ( nX, nY, impl_getWidth(), nY ) ;
443 rGraphics->drawLine ( nX, nY, nX , impl_getHeight() ) ;
445 rGraphics->setLineColor ( LINECOLOR_BRIGHT ) ;
446 rGraphics->drawLine ( impl_getWidth()-1, impl_getHeight()-1, impl_getWidth()-1, nY ) ;
447 rGraphics->drawLine ( impl_getWidth()-1, impl_getHeight()-1, nX , impl_getHeight()-1 ) ;
451 //____________________________________________________________________________________________________________
452 // protected method
453 //____________________________________________________________________________________________________________
455 void ProgressBar::impl_recalcRange ()
457 MutexGuard aGuard (m_aMutex) ;
459 sal_Int32 nWindowWidth = impl_getWidth() ;
460 sal_Int32 nWindowHeight = impl_getHeight() ;
461 double fBlockHeight ;
462 double fBlockWidth ;
463 double fMaxBlocks ;
465 if( nWindowWidth > nWindowHeight )
467 m_bHorizontal = sal_True ;
468 fBlockHeight = (nWindowHeight-(2*FREESPACE)) ;
469 fBlockWidth = fBlockHeight ;
470 fMaxBlocks = nWindowWidth/(fBlockWidth+FREESPACE);
472 else
474 m_bHorizontal = sal_False ;
475 fBlockWidth = (nWindowWidth-(2*FREESPACE)) ;
476 fBlockHeight = fBlockWidth ;
477 fMaxBlocks = nWindowHeight/(fBlockHeight+FREESPACE);
480 double fRange = m_nMaxRange-m_nMinRange ;
481 double fBlockValue = fRange/fMaxBlocks ;
483 m_nBlockValue = fBlockValue ;
484 m_aBlockSize.Height = (sal_Int32)fBlockHeight;
485 m_aBlockSize.Width = (sal_Int32)fBlockWidth ;
487 // Calculate count of blocks for actual size
488 // (prevent error "division by zero")
489 if ( nHeight == 0 )
491 nHeight = 1 ;
494 nMaxBlock = nWidth / nHeight ;
495 nMaxBlock *= 2 ;
497 // prevent error "division by zero"
498 if ( nMaxBlock == 0 )
500 nMaxBlock = 1 ;
503 // Calculate new value and new size for ONE block.
505 // Do not a calculation like this: "m_nBlockValue=(m_nMaxRange-m_nMinRange)/nMaxBlock" !
506 // If difference between m_nMaxRange and m_nMinRange to large, it give an overflow and a
507 // following error "division by zero" in method "paint() ... nBlockCount=nDifference/m_nBlockValue ..."
509 // Overflow ? => example: _I32_MAX - _I32_MIN = -1 and not _UI32_MAX !!!
511 m_nBlockValue = ( m_nMaxRange / nMaxBlock ) - ( m_nMinRange / nMaxBlock ) ;
512 m_aBlockSize.Height = ( nHeight - ( FREESPACE * 2 ) ) ;
513 m_aBlockSize.Width = ( ( nWidth / nMaxBlock ) - FREESPACE ) ;
515 else
517 // Don't forget to save this state! Used in "ProgressBar::paint()"
518 m_bHorizontal = sal_False ;
520 double fBlockWidth = (nHeight-(2*FREESPACE)) ;
521 double fBlockHeight = fBlockWidth ;
522 double fRange = m_nMaxRange-m_nMinRange ;
523 double fBlockValue = fRange/(fBlockWidth+FREESPACE);
525 m_nBlockValue = fBlockValue ;
526 m_aBlockSize.Height = (sal_Int32)fBlockHeight;
527 m_aBlockSize.Width = (sal_Int32)fBlockWidth ;
529 // Calculate count of blocks for actual size
530 // (prevent error "division by zero")
531 if ( nWidth == 0 )
533 nWidth = 1 ;
536 nMaxBlock = nHeight / nWidth ;
537 nMaxBlock *= 2 ;
539 // prevent error "division by zero"
540 if ( nMaxBlock == 0 )
542 nMaxBlock = 1 ;
545 // Calculate new value and new size for ONE block.
547 // Do not a calculation like this: "m_nBlockValue=(m_nMaxRange-m_nMinRange)/nMaxBlock" !
548 // If difference between m_nMaxRange and m_nMinRange to large, it give an overflow and a
549 // following error "division by zero" in method "paint() ... nBlockCount=nDifference/m_nBlockValue ..."
551 // Overflow ? => example: _I32_MAX - _I32_MIN = -1 and not _UI32_MAX !!!
553 m_nBlockValue = ( m_nMaxRange / nMaxBlock ) - ( m_nMinRange / nMaxBlock ) ;
554 m_aBlockSize.Height = ( ( nHeight / nMaxBlock ) - FREESPACE ) ;
555 m_aBlockSize.Width = ( nWidth - ( FREESPACE * 2 ) ) ;
561 } // namespace unocontrols