bump product version to 5.0.4.1
[LibreOffice.git] / UnoControls / source / controls / progressbar.cxx
blob6ff24bed4704c8bd54683d5463f37af445dfff18
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
30 #include <math.h>
31 #include <limits.h>
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{
41 // construct/destruct
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()
60 // XInterface
62 Any SAL_CALL ProgressBar::queryInterface( const Type& rType ) throw( RuntimeException, std::exception )
64 // Attention:
65 // Don't use mutex or guard in this method!!! Is a method of XInterface.
66 Any aReturn;
67 Reference< XInterface > xDel = BaseControl::impl_getDelegator();
68 if ( xDel.is() )
70 // If an delegator exist, forward question to his queryInterface.
71 // Delegator will ask his own queryAggregation!
72 aReturn = xDel->queryInterface( rType );
74 else
76 // If an delegator unknown, forward question to own queryAggregation.
77 aReturn = queryAggregation( rType );
80 return aReturn;
83 // XInterface
85 void SAL_CALL ProgressBar::acquire() throw()
87 // Attention:
88 // Don't use mutex or guard in this method!!! Is a method of XInterface.
90 // Forward to baseclass
91 BaseControl::acquire();
94 // XInterface
96 void SAL_CALL ProgressBar::release() throw()
98 // Attention:
99 // Don't use mutex or guard in this method!!! Is a method of XInterface.
101 // Forward to baseclass
102 BaseControl::release();
105 // XTypeProvider
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();
135 // XAggregation
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 );
154 return aReturn;
157 // XProgressBar
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;
167 // Repaint control
168 impl_paint ( 0, 0, impl_getGraphicsPeer() );
171 // XProgressBar
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;
181 // Repaint control
182 impl_paint ( 0, 0, impl_getGraphicsPeer() );
185 // XProgressBar
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!
201 if (
202 ( nValue >= m_nMinRange ) &&
203 ( nValue <= m_nMaxRange )
206 // New value is ok => save this
207 m_nValue = nValue;
209 // Repaint to display changes
210 impl_paint ( 0, 0, impl_getGraphicsPeer() );
214 // XProgressBar
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
220 // 2) Min < Max
221 // 3) Min > Max
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
232 if ( nMin < nMax )
234 // Take correct Min and Max
235 m_nMinRange = nMin;
236 m_nMaxRange = nMax;
238 else
240 // Change Min and Max automatically
241 m_nMinRange = nMax;
242 m_nMaxRange = nMin;
245 // assure that m_nValue is within the range
246 if (!(m_nMinRange < m_nValue && m_nValue < m_nMaxRange))
247 m_nValue = m_nMinRange;
249 impl_recalcRange ();
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.
256 // XProgressBar
258 sal_Int32 SAL_CALL ProgressBar::getValue () throw( RuntimeException, std::exception )
260 // Ready for multithreading
261 MutexGuard aGuard (m_aMutex);
263 return m_nValue;
266 // XWindow
268 void SAL_CALL ProgressBar::setPosSize (
269 sal_Int32 nX,
270 sal_Int32 nY,
271 sal_Int32 nWidth,
272 sal_Int32 nHeight,
273 sal_Int16 nFlags
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.
282 if (
283 ( nWidth != aBasePosSize.Width ) ||
284 ( nHeight != aBasePosSize.Height )
287 impl_recalcRange ( );
288 impl_paint ( 0, 0, impl_getGraphicsPeer () );
292 // XControl
294 sal_Bool SAL_CALL ProgressBar::setModel( const Reference< XControlModel >& /*xModel*/ ) throw( RuntimeException, std::exception )
296 // A model is not possible for this control.
297 return false;
300 // XControl
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");
322 // protected method
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);
335 // Clear background
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()"
350 if (m_bHorizontal)
352 // Step to left side of window
353 nBlockStart = nX;
355 for ( sal_Int16 i=1; i<=nBlockCount; ++i )
357 // step free field
358 nBlockStart += PROGRESSBAR_FREESPACE;
359 // paint block
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()"
367 else
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 )
375 // step free field
376 nBlockStart -= PROGRESSBAR_FREESPACE;
377 // paint block
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 );
395 // protected method
397 void ProgressBar::impl_recalcRange ()
399 MutexGuard aGuard (m_aMutex);
401 sal_Int32 nWindowWidth = impl_getWidth();
402 sal_Int32 nWindowHeight = impl_getHeight();
403 double fBlockHeight;
404 double fBlockWidth;
405 double fMaxBlocks;
407 if( nWindowWidth > nWindowHeight )
409 m_bHorizontal = true;
410 fBlockHeight = (nWindowHeight-(2*PROGRESSBAR_FREESPACE));
411 fBlockWidth = fBlockHeight;
412 fMaxBlocks = nWindowWidth/(fBlockWidth+PROGRESSBAR_FREESPACE);
414 else
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: */