LibreOffice Module UnoControls (master)  1
progressbar.cxx
Go to the documentation of this file.
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/XGraphics.hpp>
23 #include <tools/debug.hxx>
26 
27 #include <limits.h>
28 
29 using namespace ::cppu;
30 using namespace ::osl;
31 using namespace ::com::sun::star::uno;
32 using namespace ::com::sun::star::lang;
33 using namespace ::com::sun::star::awt;
34 
35 namespace unocontrols {
36 
37 // construct/destruct
38 
40  : BaseControl ( rxContext )
41  , m_bHorizontal ( PROGRESSBAR_DEFAULT_HORIZONTAL )
42  , m_aBlockSize ( PROGRESSBAR_DEFAULT_BLOCKDIMENSION )
43  , m_nForegroundColor ( PROGRESSBAR_DEFAULT_FOREGROUNDCOLOR )
44  , m_nBackgroundColor ( PROGRESSBAR_DEFAULT_BACKGROUNDCOLOR )
45  , m_nMinRange ( PROGRESSBAR_DEFAULT_MINRANGE )
46  , m_nMaxRange ( PROGRESSBAR_DEFAULT_MAXRANGE )
47  , m_nBlockValue ( PROGRESSBAR_DEFAULT_BLOCKVALUE )
48  , m_nValue ( PROGRESSBAR_DEFAULT_VALUE )
49 {
50 }
51 
53 {
54 }
55 
56 // XInterface
57 
58 Any SAL_CALL ProgressBar::queryInterface( const Type& rType )
59 {
60  // Attention:
61  // Don't use mutex or guard in this method!!! Is a method of XInterface.
62  Any aReturn;
64  if ( xDel.is() )
65  {
66  // If a delegator exists, forward question to its queryInterface.
67  // Delegator will ask its own queryAggregation!
68  aReturn = xDel->queryInterface( rType );
69  }
70  else
71  {
72  // If a delegator is unknown, forward question to own queryAggregation.
73  aReturn = queryAggregation( rType );
74  }
75 
76  return aReturn;
77 }
78 
79 // XInterface
80 
81 void SAL_CALL ProgressBar::acquire() throw()
82 {
83  // Attention:
84  // Don't use mutex or guard in this method!!! Is a method of XInterface.
85 
86  // Forward to baseclass
88 }
89 
90 // XInterface
91 
92 void SAL_CALL ProgressBar::release() throw()
93 {
94  // Attention:
95  // Don't use mutex or guard in this method!!! Is a method of XInterface.
96 
97  // Forward to baseclass
99 }
100 
101 // XTypeProvider
102 
103 Sequence< Type > SAL_CALL ProgressBar::getTypes()
104 {
105  static OTypeCollection ourTypeCollection(
109 
110  return ourTypeCollection.getTypes();
111 }
112 
113 // XAggregation
114 
115 Any SAL_CALL ProgressBar::queryAggregation( const Type& aType )
116 {
117  // Ask for my own supported interfaces ...
118  // Attention: XTypeProvider and XInterface are supported by OComponentHelper!
119  Any aReturn ( ::cppu::queryInterface( aType ,
120  static_cast< XControlModel* > ( this ) ,
121  static_cast< XProgressBar* > ( this )
122  )
123  );
124 
125  // If searched interface not supported by this class ...
126  if ( !aReturn.hasValue() )
127  {
128  // ... ask baseclasses.
129  aReturn = BaseControl::queryAggregation( aType );
130  }
131 
132  return aReturn;
133 }
134 
135 // XProgressBar
136 
137 void SAL_CALL ProgressBar::setForegroundColor( sal_Int32 nColor )
138 {
139  // Ready for multithreading
140  MutexGuard aGuard (m_aMutex);
141 
142  // Safe color for later use.
143  m_nForegroundColor = Color(nColor);
144 
145  // Repaint control
146  impl_paint ( 0, 0, impl_getGraphicsPeer() );
147 }
148 
149 // XProgressBar
150 
151 void SAL_CALL ProgressBar::setBackgroundColor ( sal_Int32 nColor )
152 {
153  // Ready for multithreading
154  MutexGuard aGuard (m_aMutex);
155 
156  // Safe color for later use.
157  m_nBackgroundColor = Color(nColor);
158 
159  // Repaint control
160  impl_paint ( 0, 0, impl_getGraphicsPeer() );
161 }
162 
163 // XProgressBar
164 
165 void SAL_CALL ProgressBar::setValue ( sal_Int32 nValue )
166 {
167  // This method is defined for follow things:
168  // 1) Values >= _nMinRange
169  // 2) Values <= _nMaxRange
170 
171  // Ready for multithreading
172  MutexGuard aGuard (m_aMutex);
173 
174  // save impossible cases
175  // This method is only defined for valid values
176  DBG_ASSERT ( (( nValue >= m_nMinRange ) && ( nValue <= m_nMaxRange )), "ProgressBar::setValue()\nNot valid value.\n" );
177 
178  // If new value not valid ... do nothing in release version!
179  if (
180  ( nValue >= m_nMinRange ) &&
181  ( nValue <= m_nMaxRange )
182  )
183  {
184  // New value is ok => save this
185  m_nValue = nValue;
186 
187  // Repaint to display changes
188  impl_paint ( 0, 0, impl_getGraphicsPeer() );
189  }
190 }
191 
192 // XProgressBar
193 
194 void SAL_CALL ProgressBar::setRange ( sal_Int32 nMin, sal_Int32 nMax )
195 {
196  // This method is defined for follow things:
197  // 1) All values of sal_Int32
198  // 2) Min < Max
199  // 3) Min > Max
200 
201  // save impossible cases
202  // This method is only defined for valid values
203  // If you ignore this, the release version will produce an error "division by zero" in "ProgressBar::setValue()"!
204  DBG_ASSERT ( ( nMin != nMax ) , "ProgressBar::setRange()\nValues for MIN and MAX are the same. This is not allowed!\n" );
205 
206  // Ready for multithreading
207  MutexGuard aGuard (m_aMutex);
208 
209  // control the values for min and max
210  if ( nMin < nMax )
211  {
212  // Take correct Min and Max
213  m_nMinRange = nMin;
214  m_nMaxRange = nMax;
215  }
216  else
217  {
218  // Change Min and Max automatically
219  m_nMinRange = nMax;
220  m_nMaxRange = nMin;
221  }
222 
223  // assure that m_nValue is within the range
226 
227  impl_recalcRange ();
228 
229  // Do not repaint the control at this place!!!
230  // An old "m_nValue" is set and can not be correct for this new range.
231  // Next call of "ProgressBar::setValue()" do this.
232 }
233 
234 // XProgressBar
235 
236 sal_Int32 SAL_CALL ProgressBar::getValue ()
237 {
238  // Ready for multithreading
239  MutexGuard aGuard (m_aMutex);
240 
241  return m_nValue;
242 }
243 
244 // XWindow
245 
246 void SAL_CALL ProgressBar::setPosSize (
247  sal_Int32 nX,
248  sal_Int32 nY,
249  sal_Int32 nWidth,
250  sal_Int32 nHeight,
251  sal_Int16 nFlags
252 )
253 {
254  // Take old size BEFORE you set the new values at baseclass!
255  // You will control changes. At the other way, the values are the same!
256  Rectangle aBasePosSize = getPosSize ();
257  BaseControl::setPosSize (nX, nY, nWidth, nHeight, nFlags);
258 
259  // Do only, if size has changed.
260  if (
261  ( nWidth != aBasePosSize.Width ) ||
262  ( nHeight != aBasePosSize.Height )
263  )
264  {
265  impl_recalcRange ( );
266  impl_paint ( 0, 0, impl_getGraphicsPeer () );
267  }
268 }
269 
270 // XControl
271 
272 sal_Bool SAL_CALL ProgressBar::setModel( const Reference< XControlModel >& /*xModel*/ )
273 {
274  // A model is not possible for this control.
275  return false;
276 }
277 
278 // XControl
279 
280 Reference< XControlModel > SAL_CALL ProgressBar::getModel()
281 {
282  // A model is not possible for this control.
283  return Reference< XControlModel >();
284 }
285 
286 // protected method
287 
288 void ProgressBar::impl_paint ( sal_Int32 nX, sal_Int32 nY, const Reference< XGraphics > & rGraphics )
289 {
290  // save impossible cases
291  DBG_ASSERT ( rGraphics.is(), "ProgressBar::paint()\nCalled with invalid Reference< XGraphics > ." );
292 
293  // This paint method is not buffered !!
294  // Every request paint the completely control. ( but only, if peer exist )
295  if ( !rGraphics.is () )
296  return;
297 
298  MutexGuard aGuard (m_aMutex);
299 
300  // Clear background
301  // (same color for line and fill)
302  rGraphics->setFillColor ( sal_Int32(m_nBackgroundColor) );
303  rGraphics->setLineColor ( sal_Int32(m_nBackgroundColor) );
304  rGraphics->drawRect ( nX, nY, impl_getWidth(), impl_getHeight() );
305 
306  // same color for line and fill for blocks
307  rGraphics->setFillColor ( sal_Int32(m_nForegroundColor) );
308  rGraphics->setLineColor ( sal_Int32(m_nForegroundColor) );
309 
310  sal_Int32 nBlockStart = 0; // = left site of new block
311  sal_Int32 nBlockCount = m_nBlockValue!=0.00 ? static_cast<sal_Int32>((m_nValue-m_nMinRange)/m_nBlockValue) : 0; // = number of next block
312 
313  // Draw horizontal progressbar
314  // decision in "recalcRange()"
315  if (m_bHorizontal)
316  {
317  // Step to left side of window
318  nBlockStart = nX;
319 
320  for ( sal_Int32 i=1; i<=nBlockCount; ++i )
321  {
322  // step free field
323  nBlockStart += PROGRESSBAR_FREESPACE;
324  // paint block
325  rGraphics->drawRect (nBlockStart, nY+PROGRESSBAR_FREESPACE, m_aBlockSize.Width, m_aBlockSize.Height);
326  // step next free field
327  nBlockStart += m_aBlockSize.Width;
328  }
329  }
330  // draw vertical progressbar
331  // decision in "recalcRange()"
332  else
333  {
334  // step to bottom side of window
335  nBlockStart = nY+impl_getHeight();
336  nBlockStart -= m_aBlockSize.Height;
337 
338  for ( sal_Int32 i=1; i<=nBlockCount; ++i )
339  {
340  // step free field
341  nBlockStart -= PROGRESSBAR_FREESPACE;
342  // paint block
343  rGraphics->drawRect (nX+PROGRESSBAR_FREESPACE, nBlockStart, m_aBlockSize.Width, m_aBlockSize.Height);
344  // step next free field
345  nBlockStart -= m_aBlockSize.Height;
346  }
347  }
348 
349  // Paint shadow border around the progressbar
350  rGraphics->setLineColor ( PROGRESSBAR_LINECOLOR_SHADOW );
351  rGraphics->drawLine ( nX, nY, impl_getWidth(), nY );
352  rGraphics->drawLine ( nX, nY, nX , impl_getHeight() );
353 
354  rGraphics->setLineColor ( PROGRESSBAR_LINECOLOR_BRIGHT );
355  rGraphics->drawLine ( impl_getWidth()-1, impl_getHeight()-1, impl_getWidth()-1, nY );
356  rGraphics->drawLine ( impl_getWidth()-1, impl_getHeight()-1, nX , impl_getHeight()-1 );
357 }
358 
359 // protected method
360 
362 {
363  MutexGuard aGuard (m_aMutex);
364 
365  sal_Int32 nWindowWidth = impl_getWidth();
366  sal_Int32 nWindowHeight = impl_getHeight();
367  double fBlockHeight;
368  double fBlockWidth;
369  double fMaxBlocks;
370 
371  if( nWindowWidth > nWindowHeight )
372  {
373  m_bHorizontal = true;
374  fBlockHeight = (nWindowHeight-(2*PROGRESSBAR_FREESPACE));
375  fBlockWidth = fBlockHeight;
376  fMaxBlocks = nWindowWidth/(fBlockWidth+PROGRESSBAR_FREESPACE);
377  }
378  else
379  {
380  m_bHorizontal = false;
381  fBlockWidth = (nWindowWidth-(2*PROGRESSBAR_FREESPACE));
382  fBlockHeight = fBlockWidth;
383  fMaxBlocks = nWindowHeight/(fBlockHeight+PROGRESSBAR_FREESPACE);
384  }
385 
386  double fRange = m_nMaxRange-m_nMinRange;
387  double fBlockValue = fRange/fMaxBlocks;
388 
389  m_nBlockValue = fBlockValue;
390  m_aBlockSize.Height = static_cast<sal_Int32>(fBlockHeight);
391  m_aBlockSize.Width = static_cast<sal_Int32>(fBlockWidth);
392 }
393 
394 } // namespace unocontrols
395 
396 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
398  css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&)
399 {
400  return cppu::acquire(new unocontrols::ProgressBar(context));
401 }
402 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Type
virtual void SAL_CALL setRange(sal_Int32 nMin, sal_Int32 nMax) override
#define PROGRESSBAR_LINECOLOR_BRIGHT
Definition: progressbar.hxx:39
#define PROGRESSBAR_DEFAULT_BLOCKVALUE
Definition: progressbar.hxx:37
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
get information about supported interfaces XTypeProvider
virtual void SAL_CALL setValue(sal_Int32 nValue) override
css::awt::Size m_aBlockSize
const css::uno::Reference< css::awt::XGraphics > & impl_getGraphicsPeer() const
#define PROGRESSBAR_DEFAULT_FOREGROUNDCOLOR
Definition: progressbar.hxx:34
#define PROGRESSBAR_DEFAULT_MINRANGE
Definition: progressbar.hxx:35
sal_Int32 impl_getHeight() const
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &aType) override
give answer, if interface is supported The interfaces are searched by type.
Definition: progressbar.cxx:58
#define PROGRESSBAR_DEFAULT_VALUE
Definition: progressbar.hxx:38
#define PROGRESSBAR_FREESPACE
Definition: progressbar.hxx:30
ProgressBar(const css::uno::Reference< css::uno::XComponentContext > &rxContext)
#define DBG_ASSERT(sCon, aError)
int i
virtual ~ProgressBar() override
Definition: progressbar.cxx:52
sal_Int32 impl_getWidth() const
unsigned char sal_Bool
virtual void SAL_CALL acquire() override
increment refcount XInterface release() A RuntimeException is thrown.
Definition: basecontrol.cxx:91
virtual void SAL_CALL setPosSize(sal_Int32 nX, sal_Int32 nY, sal_Int32 nWidth, sal_Int32 nHeight, sal_Int16 nFlags) override
virtual css::uno::Reference< css::awt::XControlModel > SAL_CALL getModel() override
virtual css::uno::Any SAL_CALL queryAggregation(const css::uno::Type &aType) override
virtual void SAL_CALL acquire() override
increment refcount XInterface release() A RuntimeException is thrown.
Definition: progressbar.cxx:81
virtual sal_Int32 SAL_CALL getValue() override
virtual void impl_paint(sal_Int32 nX, sal_Int32 nY, const css::uno::Reference< css::awt::XGraphics > &xGraphics) override
virtual css::awt::Rectangle SAL_CALL getPosSize() override
virtual sal_Bool SAL_CALL setModel(const css::uno::Reference< css::awt::XControlModel > &xModel) override
#define PROGRESSBAR_LINECOLOR_SHADOW
Definition: progressbar.hxx:40
virtual void SAL_CALL setForegroundColor(sal_Int32 nColor) override
virtual void SAL_CALL setPosSize(sal_Int32 nX, sal_Int32 nY, sal_Int32 nWidth, sal_Int32 nHeight, sal_Int16 nFlags) override
const css::uno::Reference< css::uno::XInterface > & impl_getDelegator() const
#define PROGRESSBAR_DEFAULT_BLOCKDIMENSION
Definition: progressbar.hxx:32
css::uno::Any SAL_CALL queryAggregation(const css::uno::Type &aType) override
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
get information about supported interfaces XTypeProvider
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * stardiv_UnoControls_ProgressBar_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
#define PROGRESSBAR_DEFAULT_BACKGROUNDCOLOR
Definition: progressbar.hxx:33
#define PROGRESSBAR_DEFAULT_HORIZONTAL
Definition: progressbar.hxx:31
virtual void SAL_CALL release() override
decrement refcount XInterface acquire() A RuntimeException is thrown.
Definition: progressbar.cxx:92
#define PROGRESSBAR_DEFAULT_MAXRANGE
Definition: progressbar.hxx:36
virtual void SAL_CALL setBackgroundColor(sal_Int32 nColor) override
css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType, Interface1 *p1)
virtual void SAL_CALL release() override
decrement refcount XInterface acquire() A RuntimeException is thrown.