1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "progressbar.hxx"
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/queryinterface.hxx>
28 #include <cppuhelper/typeprovider.hxx>
33 using namespace ::cppu
;
34 using namespace ::osl
;
35 using namespace ::com::sun::star::uno
;
36 using namespace ::com::sun::star::lang
;
37 using namespace ::com::sun::star::awt
;
39 namespace unocontrols
{
43 ProgressBar::ProgressBar( const Reference
< XComponentContext
>& rxContext
)
44 : BaseControl ( rxContext
)
45 , m_bHorizontal ( PROGRESSBAR_DEFAULT_HORIZONTAL
)
46 , m_aBlockSize ( PROGRESSBAR_DEFAULT_BLOCKDIMENSION
)
47 , m_nForegroundColor ( PROGRESSBAR_DEFAULT_FOREGROUNDCOLOR
)
48 , m_nBackgroundColor ( PROGRESSBAR_DEFAULT_BACKGROUNDCOLOR
)
49 , m_nMinRange ( PROGRESSBAR_DEFAULT_MINRANGE
)
50 , m_nMaxRange ( PROGRESSBAR_DEFAULT_MAXRANGE
)
51 , m_nBlockValue ( PROGRESSBAR_DEFAULT_BLOCKVALUE
)
52 , m_nValue ( PROGRESSBAR_DEFAULT_VALUE
)
56 ProgressBar::~ProgressBar()
62 Any SAL_CALL
ProgressBar::queryInterface( const Type
& rType
) throw( RuntimeException
, std::exception
)
65 // Don't use mutex or guard in this method!!! Is a method of XInterface.
67 Reference
< XInterface
> xDel
= BaseControl::impl_getDelegator();
70 // If an delegator exist, forward question to his queryInterface.
71 // Delegator will ask his own queryAggregation!
72 aReturn
= xDel
->queryInterface( rType
);
76 // If an delegator unknown, forward question to own queryAggregation.
77 aReturn
= queryAggregation( rType
);
85 void SAL_CALL
ProgressBar::acquire() throw()
88 // Don't use mutex or guard in this method!!! Is a method of XInterface.
90 // Forward to baseclass
91 BaseControl::acquire();
96 void SAL_CALL
ProgressBar::release() throw()
99 // Don't use mutex or guard in this method!!! Is a method of XInterface.
101 // Forward to baseclass
102 BaseControl::release();
107 Sequence
< Type
> SAL_CALL
ProgressBar::getTypes() throw( RuntimeException
, std::exception
)
109 // Optimize this method !
110 // We initialize a static variable only one time. And we don't must use a mutex at every call!
111 // For the first call; pTypeCollection is NULL - for the second call pTypeCollection is different from NULL!
112 static OTypeCollection
* pTypeCollection
= NULL
;
114 if ( pTypeCollection
== NULL
)
116 // Ready for multithreading; get global mutex for first call of this method only! see before
117 MutexGuard
aGuard( Mutex::getGlobalMutex() );
119 // Control these pointer again ... it can be, that another instance will be faster then these!
120 if ( pTypeCollection
== NULL
)
122 // Create a static typecollection ...
123 static OTypeCollection
aTypeCollection ( cppu::UnoType
<XControlModel
>::get(),
124 cppu::UnoType
<XProgressBar
>::get(),
125 BaseControl::getTypes()
127 // ... and set his address to static pointer!
128 pTypeCollection
= &aTypeCollection
;
132 return pTypeCollection
->getTypes();
137 Any SAL_CALL
ProgressBar::queryAggregation( const Type
& aType
) throw( RuntimeException
, std::exception
)
139 // Ask for my own supported interfaces ...
140 // Attention: XTypeProvider and XInterface are supported by OComponentHelper!
141 Any
aReturn ( ::cppu::queryInterface( aType
,
142 static_cast< XControlModel
* > ( this ) ,
143 static_cast< XProgressBar
* > ( this )
147 // If searched interface not supported by this class ...
148 if ( !aReturn
.hasValue() )
150 // ... ask baseclasses.
151 aReturn
= BaseControl::queryAggregation( aType
);
159 void SAL_CALL
ProgressBar::setForegroundColor( sal_Int32 nColor
) throw( RuntimeException
, std::exception
)
161 // Ready for multithreading
162 MutexGuard
aGuard (m_aMutex
);
164 // Safe color for later use.
165 m_nForegroundColor
= nColor
;
168 impl_paint ( 0, 0, impl_getGraphicsPeer() );
173 void SAL_CALL
ProgressBar::setBackgroundColor ( sal_Int32 nColor
) throw( RuntimeException
, std::exception
)
175 // Ready for multithreading
176 MutexGuard
aGuard (m_aMutex
);
178 // Safe color for later use.
179 m_nBackgroundColor
= nColor
;
182 impl_paint ( 0, 0, impl_getGraphicsPeer() );
187 void SAL_CALL
ProgressBar::setValue ( sal_Int32 nValue
) throw( RuntimeException
, std::exception
)
189 // This method is defined for follow things:
190 // 1) Values >= _nMinRange
191 // 2) Values <= _nMaxRange
193 // Ready for multithreading
194 MutexGuard
aGuard (m_aMutex
);
196 // save impossible cases
197 // This method is only defined for valid values
198 DBG_ASSERT ( (( nValue
>= m_nMinRange
) && ( nValue
<= m_nMaxRange
)), "ProgressBar::setValue()\nNot valid value.\n" );
200 // If new value not valid ... do nothing in release version!
202 ( nValue
>= m_nMinRange
) &&
203 ( nValue
<= m_nMaxRange
)
206 // New value is ok => save this
209 // Repaint to display changes
210 impl_paint ( 0, 0, impl_getGraphicsPeer() );
216 void SAL_CALL
ProgressBar::setRange ( sal_Int32 nMin
, sal_Int32 nMax
) throw( RuntimeException
, std::exception
)
218 // This method is defined for follow things:
219 // 1) All values of sal_Int32
223 // save impossible cases
224 // This method is only defined for valid values
225 // If you ignore this, the release version wil produce an error "division by zero" in "ProgressBar::setValue()"!
226 DBG_ASSERT ( ( nMin
!= nMax
) , "ProgressBar::setRange()\nValues for MIN and MAX are the same. This is not allowed!\n" );
228 // Ready for multithreading
229 MutexGuard
aGuard (m_aMutex
);
231 // control the values for min and max
234 // Take correct Min and Max
240 // Change Min and Max automatically
245 // assure that m_nValue is within the range
246 if (!(m_nMinRange
< m_nValue
&& m_nValue
< m_nMaxRange
))
247 m_nValue
= m_nMinRange
;
251 // Do not repaint the control at this place!!!
252 // An old "m_nValue" is set and can not be correct for this new range.
253 // Next call of "ProgressBar::setValue()" do this.
258 sal_Int32 SAL_CALL
ProgressBar::getValue () throw( RuntimeException
, std::exception
)
260 // Ready for multithreading
261 MutexGuard
aGuard (m_aMutex
);
268 void SAL_CALL
ProgressBar::setPosSize (
274 ) throw( RuntimeException
, std::exception
)
276 // Take old size BEFORE you set the new values at baseclass!
277 // You will control changes. At the other way, the values are the same!
278 Rectangle aBasePosSize
= getPosSize ();
279 BaseControl::setPosSize (nX
, nY
, nWidth
, nHeight
, nFlags
);
281 // Do only, if size has changed.
283 ( nWidth
!= aBasePosSize
.Width
) ||
284 ( nHeight
!= aBasePosSize
.Height
)
287 impl_recalcRange ( );
288 impl_paint ( 0, 0, impl_getGraphicsPeer () );
294 sal_Bool SAL_CALL
ProgressBar::setModel( const Reference
< XControlModel
>& /*xModel*/ ) throw( RuntimeException
, std::exception
)
296 // A model is not possible for this control.
302 Reference
< XControlModel
> SAL_CALL
ProgressBar::getModel() throw( RuntimeException
, std::exception
)
304 // A model is not possible for this control.
305 return Reference
< XControlModel
>();
308 // impl but public method to register service
310 const Sequence
< OUString
> ProgressBar::impl_getStaticSupportedServiceNames()
312 return css::uno::Sequence
<OUString
>();
315 // impl but public method to register service
317 const OUString
ProgressBar::impl_getStaticImplementationName()
319 return OUString("stardiv.UnoControls.ProgressBar");
324 void ProgressBar::impl_paint ( sal_Int32 nX
, sal_Int32 nY
, const Reference
< XGraphics
> & rGraphics
)
326 // save impossible cases
327 DBG_ASSERT ( rGraphics
.is(), "ProgressBar::paint()\nCalled with invalid Reference< XGraphics > ." );
329 // This paint method ist not buffered !!
330 // Every request paint the completely control. ( but only, if peer exist )
331 if ( rGraphics
.is () )
333 MutexGuard
aGuard (m_aMutex
);
336 // (same color for line and fill)
337 rGraphics
->setFillColor ( m_nBackgroundColor
);
338 rGraphics
->setLineColor ( m_nBackgroundColor
);
339 rGraphics
->drawRect ( nX
, nY
, impl_getWidth(), impl_getHeight() );
341 // same color for line and fill for blocks
342 rGraphics
->setFillColor ( m_nForegroundColor
);
343 rGraphics
->setLineColor ( m_nForegroundColor
);
345 sal_Int32 nBlockStart
= 0; // = left site of new block
346 sal_Int32 nBlockCount
= m_nBlockValue
!=0.00 ? (sal_Int32
)((m_nValue
-m_nMinRange
)/m_nBlockValue
) : 0; // = number of next block
348 // Draw horizontal progressbar
349 // decision in "recalcRange()"
352 // Step to left side of window
355 for ( sal_Int16 i
=1; i
<=nBlockCount
; ++i
)
358 nBlockStart
+= PROGRESSBAR_FREESPACE
;
360 rGraphics
->drawRect (nBlockStart
, nY
+PROGRESSBAR_FREESPACE
, m_aBlockSize
.Width
, m_aBlockSize
.Height
);
361 // step next free field
362 nBlockStart
+= m_aBlockSize
.Width
;
365 // draw vertikal progressbar
366 // decision in "recalcRange()"
369 // step to bottom side of window
370 nBlockStart
= nY
+impl_getHeight();
371 nBlockStart
-= m_aBlockSize
.Height
;
373 for ( sal_Int16 i
=1; i
<=nBlockCount
; ++i
)
376 nBlockStart
-= PROGRESSBAR_FREESPACE
;
378 rGraphics
->drawRect (nX
+PROGRESSBAR_FREESPACE
, nBlockStart
, m_aBlockSize
.Width
, m_aBlockSize
.Height
);
379 // step next free field
380 nBlockStart
-= m_aBlockSize
.Height
;
384 // Paint shadow border around the progressbar
385 rGraphics
->setLineColor ( PROGRESSBAR_LINECOLOR_SHADOW
);
386 rGraphics
->drawLine ( nX
, nY
, impl_getWidth(), nY
);
387 rGraphics
->drawLine ( nX
, nY
, nX
, impl_getHeight() );
389 rGraphics
->setLineColor ( PROGRESSBAR_LINECOLOR_BRIGHT
);
390 rGraphics
->drawLine ( impl_getWidth()-1, impl_getHeight()-1, impl_getWidth()-1, nY
);
391 rGraphics
->drawLine ( impl_getWidth()-1, impl_getHeight()-1, nX
, impl_getHeight()-1 );
397 void ProgressBar::impl_recalcRange ()
399 MutexGuard
aGuard (m_aMutex
);
401 sal_Int32 nWindowWidth
= impl_getWidth();
402 sal_Int32 nWindowHeight
= impl_getHeight();
407 if( nWindowWidth
> nWindowHeight
)
409 m_bHorizontal
= true;
410 fBlockHeight
= (nWindowHeight
-(2*PROGRESSBAR_FREESPACE
));
411 fBlockWidth
= fBlockHeight
;
412 fMaxBlocks
= nWindowWidth
/(fBlockWidth
+PROGRESSBAR_FREESPACE
);
416 m_bHorizontal
= false;
417 fBlockWidth
= (nWindowWidth
-(2*PROGRESSBAR_FREESPACE
));
418 fBlockHeight
= fBlockWidth
;
419 fMaxBlocks
= nWindowHeight
/(fBlockHeight
+PROGRESSBAR_FREESPACE
);
422 double fRange
= m_nMaxRange
-m_nMinRange
;
423 double fBlockValue
= fRange
/fMaxBlocks
;
425 m_nBlockValue
= fBlockValue
;
426 m_aBlockSize
.Height
= (sal_Int32
)fBlockHeight
;
427 m_aBlockSize
.Width
= (sal_Int32
)fBlockWidth
;
430 } // namespace unocontrols
432 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */