1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
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.
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).
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.
27 ************************************************************************/
28 //____________________________________________________________________________________________________________
30 //____________________________________________________________________________________________________________
32 #include "progressbar.hxx"
34 //____________________________________________________________________________________________________________
35 // includes of other projects
36 //____________________________________________________________________________________________________________
37 #include <com/sun/star/awt/GradientStyle.hpp>
38 #include <com/sun/star/awt/RasterOperation.hpp>
39 #include <com/sun/star/awt/Gradient.hpp>
40 #include <com/sun/star/awt/XGraphics.hpp>
41 #include <tools/debug.hxx>
42 #include <cppuhelper/typeprovider.hxx>
47 //____________________________________________________________________________________________________________
48 // includes of my project
49 //____________________________________________________________________________________________________________
51 //____________________________________________________________________________________________________________
53 //____________________________________________________________________________________________________________
55 using namespace ::cppu
;
56 using namespace ::osl
;
57 using namespace ::rtl
;
58 using namespace ::com::sun::star::uno
;
59 using namespace ::com::sun::star::lang
;
60 using namespace ::com::sun::star::awt
;
62 namespace unocontrols
{
64 //____________________________________________________________________________________________________________
66 //____________________________________________________________________________________________________________
68 ProgressBar::ProgressBar( const Reference
< XMultiServiceFactory
>& xFactory
)
69 : BaseControl ( xFactory
)
70 , m_bHorizontal ( PROGRESSBAR_DEFAULT_HORIZONTAL
)
71 , m_aBlockSize ( PROGRESSBAR_DEFAULT_BLOCKDIMENSION
)
72 , m_nForegroundColor ( PROGRESSBAR_DEFAULT_FOREGROUNDCOLOR
)
73 , m_nBackgroundColor ( PROGRESSBAR_DEFAULT_BACKGROUNDCOLOR
)
74 , m_nMinRange ( PROGRESSBAR_DEFAULT_MINRANGE
)
75 , m_nMaxRange ( PROGRESSBAR_DEFAULT_MAXRANGE
)
76 , m_nBlockValue ( PROGRESSBAR_DEFAULT_BLOCKVALUE
)
77 , m_nValue ( PROGRESSBAR_DEFAULT_VALUE
)
81 ProgressBar::~ProgressBar()
85 //____________________________________________________________________________________________________________
87 //____________________________________________________________________________________________________________
89 Any SAL_CALL
ProgressBar::queryInterface( const Type
& rType
) throw( RuntimeException
)
92 // Don't use mutex or guard in this method!!! Is a method of XInterface.
94 Reference
< XInterface
> xDel
= BaseControl::impl_getDelegator();
97 // If an delegator exist, forward question to his queryInterface.
98 // Delegator will ask his own queryAggregation!
99 aReturn
= xDel
->queryInterface( rType
);
103 // If an delegator unknown, forward question to own queryAggregation.
104 aReturn
= queryAggregation( rType
);
110 //____________________________________________________________________________________________________________
112 //____________________________________________________________________________________________________________
114 void SAL_CALL
ProgressBar::acquire() throw()
117 // Don't use mutex or guard in this method!!! Is a method of XInterface.
119 // Forward to baseclass
120 BaseControl::acquire();
123 //____________________________________________________________________________________________________________
125 //____________________________________________________________________________________________________________
127 void SAL_CALL
ProgressBar::release() throw()
130 // Don't use mutex or guard in this method!!! Is a method of XInterface.
132 // Forward to baseclass
133 BaseControl::release();
136 //____________________________________________________________________________________________________________
138 //____________________________________________________________________________________________________________
140 Sequence
< Type
> SAL_CALL
ProgressBar::getTypes() throw( RuntimeException
)
142 // Optimize this method !
143 // We initialize a static variable only one time. And we don't must use a mutex at every call!
144 // For the first call; pTypeCollection is NULL - for the second call pTypeCollection is different from NULL!
145 static OTypeCollection
* pTypeCollection
= NULL
;
147 if ( pTypeCollection
== NULL
)
149 // Ready for multithreading; get global mutex for first call of this method only! see before
150 MutexGuard
aGuard( Mutex::getGlobalMutex() );
152 // Control these pointer again ... it can be, that another instance will be faster then these!
153 if ( pTypeCollection
== NULL
)
155 // Create a static typecollection ...
156 static OTypeCollection
aTypeCollection ( ::getCppuType(( const Reference
< XControlModel
>*) NULL
) ,
157 ::getCppuType(( const Reference
< XProgressBar
>*) NULL
) ,
158 BaseControl::getTypes()
160 // ... and set his address to static pointer!
161 pTypeCollection
= &aTypeCollection
;
165 return pTypeCollection
->getTypes();
168 //____________________________________________________________________________________________________________
170 //____________________________________________________________________________________________________________
172 Any SAL_CALL
ProgressBar::queryAggregation( const Type
& aType
) throw( RuntimeException
)
174 // Ask for my own supported interfaces ...
175 // Attention: XTypeProvider and XInterface are supported by OComponentHelper!
176 Any
aReturn ( ::cppu::queryInterface( aType
,
177 static_cast< XControlModel
* > ( this ) ,
178 static_cast< XProgressBar
* > ( this )
182 // If searched interface not supported by this class ...
183 if ( aReturn
.hasValue() == sal_False
)
185 // ... ask baseclasses.
186 aReturn
= BaseControl::queryAggregation( aType
);
192 //____________________________________________________________________________________________________________
194 //____________________________________________________________________________________________________________
196 void SAL_CALL
ProgressBar::setForegroundColor( sal_Int32 nColor
) throw( RuntimeException
)
198 // Ready for multithreading
199 MutexGuard
aGuard (m_aMutex
) ;
201 // Safe color for later use.
202 m_nForegroundColor
= nColor
;
205 impl_paint ( 0, 0, impl_getGraphicsPeer() ) ;
208 //____________________________________________________________________________________________________________
210 //____________________________________________________________________________________________________________
212 void SAL_CALL
ProgressBar::setBackgroundColor ( sal_Int32 nColor
) throw( RuntimeException
)
214 // Ready for multithreading
215 MutexGuard
aGuard (m_aMutex
) ;
217 // Safe color for later use.
218 m_nBackgroundColor
= nColor
;
221 impl_paint ( 0, 0, impl_getGraphicsPeer() ) ;
224 //____________________________________________________________________________________________________________
226 //____________________________________________________________________________________________________________
228 void SAL_CALL
ProgressBar::setValue ( sal_Int32 nValue
) throw( RuntimeException
)
230 // This method is defined for follow things:
231 // 1) Values >= _nMinRange
232 // 2) Values <= _nMaxRange
234 // Ready for multithreading
235 MutexGuard
aGuard (m_aMutex
) ;
237 // save impossible cases
238 // This method is only defined for valid values
239 DBG_ASSERT ( (( nValue
>= m_nMinRange
) && ( nValue
<= m_nMaxRange
)), "ProgressBar::setValue()\nNot valid value.\n" ) ;
241 // If new value not valid ... do nothing in release version!
243 ( nValue
>= m_nMinRange
) &&
244 ( nValue
<= m_nMaxRange
)
247 // New value is ok => save this
250 // Repaint to display changes
251 impl_paint ( 0, 0, impl_getGraphicsPeer() ) ;
255 //____________________________________________________________________________________________________________
257 //____________________________________________________________________________________________________________
259 void SAL_CALL
ProgressBar::setRange ( sal_Int32 nMin
, sal_Int32 nMax
) throw( RuntimeException
)
261 // This method is defined for follow things:
262 // 1) All values of sal_Int32
266 // save impossible cases
267 // This method is only defined for valid values
268 // If you ignore this, the release version wil produce an error "division by zero" in "ProgressBar::setValue()"!
269 DBG_ASSERT ( ( nMin
!= nMax
) , "ProgressBar::setRange()\nValues for MIN and MAX are the same. This is not allowed!\n" ) ;
271 // Ready for multithreading
272 MutexGuard
aGuard (m_aMutex
) ;
274 // control the values for min and max
277 // Take correct Min and Max
283 // Change Min and Max automaticly
288 // assure that m_nValue is within the range
289 if (!(m_nMinRange
< m_nValue
&& m_nValue
< m_nMaxRange
))
290 m_nValue
= m_nMinRange
;
292 impl_recalcRange () ;
294 // Do not repaint the control at this place!!!
295 // An old "m_nValue" is set and can not be correct for this new range.
296 // Next call of "ProgressBar::setValue()" do this.
299 //____________________________________________________________________________________________________________
301 //____________________________________________________________________________________________________________
303 sal_Int32 SAL_CALL
ProgressBar::getValue () throw( RuntimeException
)
305 // Ready for multithreading
306 MutexGuard
aGuard (m_aMutex
) ;
308 return ( m_nValue
) ;
311 //____________________________________________________________________________________________________________
313 //____________________________________________________________________________________________________________
315 void SAL_CALL
ProgressBar::setPosSize (
321 ) throw( RuntimeException
)
323 // Take old size BEFORE you set the new values at baseclass!
324 // You will control changes. At the other way, the values are the same!
325 Rectangle aBasePosSize
= getPosSize () ;
326 BaseControl::setPosSize (nX
, nY
, nWidth
, nHeight
, nFlags
) ;
328 // Do only, if size has changed.
330 ( nWidth
!= aBasePosSize
.Width
) ||
331 ( nHeight
!= aBasePosSize
.Height
)
334 impl_recalcRange ( ) ;
335 impl_paint ( 0, 0, impl_getGraphicsPeer () ) ;
339 //____________________________________________________________________________________________________________
341 //____________________________________________________________________________________________________________
343 sal_Bool SAL_CALL
ProgressBar::setModel( const Reference
< XControlModel
>& /*xModel*/ ) throw( RuntimeException
)
345 // A model is not possible for this control.
349 //____________________________________________________________________________________________________________
351 //____________________________________________________________________________________________________________
353 Reference
< XControlModel
> SAL_CALL
ProgressBar::getModel() throw( RuntimeException
)
355 // A model is not possible for this control.
356 return Reference
< XControlModel
>();
359 //____________________________________________________________________________________________________________
360 // impl but public method to register service
361 //____________________________________________________________________________________________________________
363 const Sequence
< OUString
> ProgressBar::impl_getStaticSupportedServiceNames()
365 MutexGuard
aGuard( Mutex::getGlobalMutex() );
366 Sequence
< OUString
> seqServiceNames( 1 );
367 seqServiceNames
.getArray() [0] = SERVICENAME_PROGRESSBAR
;
368 return seqServiceNames
;
371 //____________________________________________________________________________________________________________
372 // impl but public method to register service
373 //____________________________________________________________________________________________________________
375 const OUString
ProgressBar::impl_getStaticImplementationName()
377 return OUString(IMPLEMENTATIONNAME_PROGRESSBAR
);
380 //____________________________________________________________________________________________________________
382 //____________________________________________________________________________________________________________
384 void ProgressBar::impl_paint ( sal_Int32 nX
, sal_Int32 nY
, const Reference
< XGraphics
> & rGraphics
)
386 // save impossible cases
387 DBG_ASSERT ( rGraphics
.is(), "ProgressBar::paint()\nCalled with invalid Reference< XGraphics > ." ) ;
389 // This paint method ist not buffered !!
390 // Every request paint the completely control. ( but only, if peer exist )
391 if ( rGraphics
.is () )
393 MutexGuard
aGuard (m_aMutex
) ;
396 // (same color for line and fill)
397 rGraphics
->setFillColor ( m_nBackgroundColor
) ;
398 rGraphics
->setLineColor ( m_nBackgroundColor
) ;
399 rGraphics
->drawRect ( nX
, nY
, impl_getWidth(), impl_getHeight() ) ;
401 // same color for line and fill for blocks
402 rGraphics
->setFillColor ( m_nForegroundColor
) ;
403 rGraphics
->setLineColor ( m_nForegroundColor
) ;
405 sal_Int32 nBlockStart
= 0 ; // = left site of new block
406 sal_Int32 nBlockCount
= m_nBlockValue
!=0.00 ? (sal_Int32
)((m_nValue
-m_nMinRange
)/m_nBlockValue
) : 0 ; // = number of next block
408 // Draw horizontal progressbar
409 // decision in "recalcRange()"
412 // Step to left side of window
415 for ( sal_Int16 i
=1; i
<=nBlockCount
; ++i
)
418 nBlockStart
+= PROGRESSBAR_FREESPACE
;
420 rGraphics
->drawRect (nBlockStart
, nY
+PROGRESSBAR_FREESPACE
, m_aBlockSize
.Width
, m_aBlockSize
.Height
) ;
421 // step next free field
422 nBlockStart
+= m_aBlockSize
.Width
;
425 // draw vertikal progressbar
426 // decision in "recalcRange()"
429 // step to bottom side of window
430 nBlockStart
= nY
+impl_getHeight() ;
431 nBlockStart
-= m_aBlockSize
.Height
;
433 for ( sal_Int16 i
=1; i
<=nBlockCount
; ++i
)
436 nBlockStart
-= PROGRESSBAR_FREESPACE
;
438 rGraphics
->drawRect (nX
+PROGRESSBAR_FREESPACE
, nBlockStart
, m_aBlockSize
.Width
, m_aBlockSize
.Height
) ;
439 // step next free field
440 nBlockStart
-= m_aBlockSize
.Height
;
444 // Paint shadow border around the progressbar
445 rGraphics
->setLineColor ( PROGRESSBAR_LINECOLOR_SHADOW
) ;
446 rGraphics
->drawLine ( nX
, nY
, impl_getWidth(), nY
) ;
447 rGraphics
->drawLine ( nX
, nY
, nX
, impl_getHeight() ) ;
449 rGraphics
->setLineColor ( PROGRESSBAR_LINECOLOR_BRIGHT
) ;
450 rGraphics
->drawLine ( impl_getWidth()-1, impl_getHeight()-1, impl_getWidth()-1, nY
) ;
451 rGraphics
->drawLine ( impl_getWidth()-1, impl_getHeight()-1, nX
, impl_getHeight()-1 ) ;
455 //____________________________________________________________________________________________________________
457 //____________________________________________________________________________________________________________
459 void ProgressBar::impl_recalcRange ()
461 MutexGuard
aGuard (m_aMutex
) ;
463 sal_Int32 nWindowWidth
= impl_getWidth() ;
464 sal_Int32 nWindowHeight
= impl_getHeight() ;
465 double fBlockHeight
;
469 if( nWindowWidth
> nWindowHeight
)
471 m_bHorizontal
= sal_True
;
472 fBlockHeight
= (nWindowHeight
-(2*PROGRESSBAR_FREESPACE
)) ;
473 fBlockWidth
= fBlockHeight
;
474 fMaxBlocks
= nWindowWidth
/(fBlockWidth
+PROGRESSBAR_FREESPACE
);
478 m_bHorizontal
= sal_False
;
479 fBlockWidth
= (nWindowWidth
-(2*PROGRESSBAR_FREESPACE
)) ;
480 fBlockHeight
= fBlockWidth
;
481 fMaxBlocks
= nWindowHeight
/(fBlockHeight
+PROGRESSBAR_FREESPACE
);
484 double fRange
= m_nMaxRange
-m_nMinRange
;
485 double fBlockValue
= fRange
/fMaxBlocks
;
487 m_nBlockValue
= fBlockValue
;
488 m_aBlockSize
.Height
= (sal_Int32
)fBlockHeight
;
489 m_aBlockSize
.Width
= (sal_Int32
)fBlockWidth
;
492 } // namespace unocontrols
494 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */