LibreOffice Module UnoControls (master)  1
statusindicator.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 <statusindicator.hxx>
21 
22 #include <com/sun/star/awt/PosSize.hpp>
23 #include <com/sun/star/awt/XFixedText.hpp>
24 #include <com/sun/star/uno/XComponentContext.hpp>
27 
28 #include <progressbar.hxx>
29 
30 using namespace ::cppu;
31 using namespace ::osl;
32 using namespace ::com::sun::star::uno;
33 using namespace ::com::sun::star::lang;
34 using namespace ::com::sun::star::awt;
35 using namespace ::com::sun::star::task;
36 
37 #define FIXEDTEXT_SERVICENAME "com.sun.star.awt.UnoControlFixedText"
38 #define FIXEDTEXT_MODELNAME "com.sun.star.awt.UnoControlFixedTextModel"
39 #define CONTROLNAME_TEXT "Text" // identifier the control in container
40 #define CONTROLNAME_PROGRESSBAR "ProgressBar" // -||-
41 
42 namespace unocontrols {
43 
44 // construct/destruct
45 
46 StatusIndicator::StatusIndicator( const css::uno::Reference< XComponentContext >& rxContext )
47  : BaseContainerControl ( rxContext )
48 {
49  // It's not allowed to work with member in this method (refcounter !!!)
50  // But with a HACK (++refcount) its "OK" :-(
51  osl_atomic_increment(&m_refCount);
52 
53  // Create instances for fixedtext and progress ...
54  m_xText.set( rxContext->getServiceManager()->createInstanceWithContext( FIXEDTEXT_SERVICENAME, rxContext ), UNO_QUERY );
55  m_xProgressBar = new ProgressBar(rxContext);
56  // ... cast controls to css::uno::Reference< XControl > and set model ...
57  // ( ProgressBar has no model !!! )
58  css::uno::Reference< XControl > xTextControl ( m_xText , UNO_QUERY );
59  xTextControl->setModel( css::uno::Reference< XControlModel >( rxContext->getServiceManager()->createInstanceWithContext( FIXEDTEXT_MODELNAME, rxContext ), UNO_QUERY ) );
60  // ... and add controls to basecontainercontrol!
61  addControl( CONTROLNAME_TEXT, xTextControl );
62  addControl( CONTROLNAME_PROGRESSBAR, m_xProgressBar.get() );
63  // FixedText make it automatically visible by himself ... but not the progressbar !!!
64  // it must be set explicitly
65  m_xProgressBar->setVisible( true );
66  // Reset to defaults !!!
67  // (progressbar take automatically its own defaults)
68  m_xText->setText( "" );
69 
70  osl_atomic_decrement(&m_refCount);
71 }
72 
74 
75 // XInterface
76 
77 Any SAL_CALL StatusIndicator::queryInterface( const Type& rType )
78 {
79  // Attention:
80  // Don't use mutex or guard in this method!!! Is a method of XInterface.
81  Any aReturn;
82  css::uno::Reference< XInterface > xDel = BaseContainerControl::impl_getDelegator();
83  if ( xDel.is() )
84  {
85  // If a delegator exists, forward question to its queryInterface.
86  // Delegator will ask its own queryAggregation!
87  aReturn = xDel->queryInterface( rType );
88  }
89  else
90  {
91  // If a delegator is unknown, forward question to own queryAggregation.
92  aReturn = queryAggregation( rType );
93  }
94 
95  return aReturn;
96 }
97 
98 // XInterface
99 
100 void SAL_CALL StatusIndicator::acquire() throw()
101 {
102  // Attention:
103  // Don't use mutex or guard in this method!!! Is a method of XInterface.
104 
105  // Forward to baseclass
107 }
108 
109 // XInterface
110 
111 void SAL_CALL StatusIndicator::release() throw()
112 {
113  // Attention:
114  // Don't use mutex or guard in this method!!! Is a method of XInterface.
115 
116  // Forward to baseclass
118 }
119 
120 // XTypeProvider
121 
122 Sequence< Type > SAL_CALL StatusIndicator::getTypes()
123 {
124  static OTypeCollection ourTypeCollection(
128 
129  return ourTypeCollection.getTypes();
130 }
131 
132 // XAggregation
133 
135 {
136  // Ask for my own supported interfaces ...
137  // Attention: XTypeProvider and XInterface are supported by OComponentHelper!
138  Any aReturn ( ::cppu::queryInterface( aType ,
139  static_cast< XLayoutConstrains* > ( this ) ,
140  static_cast< XStatusIndicator* > ( this )
141  )
142  );
143 
144  // If searched interface not supported by this class ...
145  if ( !aReturn.hasValue() )
146  {
147  // ... ask baseclasses.
148  aReturn = BaseControl::queryAggregation( aType );
149  }
150 
151  return aReturn;
152 }
153 
154 // XStatusIndicator
155 
156 void SAL_CALL StatusIndicator::start( const OUString& sText, sal_Int32 nRange )
157 {
158  // Ready for multithreading
159  MutexGuard aGuard( m_aMutex );
160 
161  // Initialize status controls with given values.
162  m_xText->setText( sText );
163  m_xProgressBar->setRange( 0, nRange );
164  // force repaint ... fixedtext has changed !
165  impl_recalcLayout ( WindowEvent(static_cast< OWeakObject* >(this),0,0,impl_getWidth(),impl_getHeight(),0,0,0,0) );
166 }
167 
168 // XStatusIndicator
169 
170 void SAL_CALL StatusIndicator::end()
171 {
172  // Ready for multithreading
173  MutexGuard aGuard( m_aMutex );
174 
175  // Clear values of status controls.
176  m_xText->setText( OUString() );
177  m_xProgressBar->setValue( 0 );
178  setVisible( false );
179 }
180 
181 // XStatusIndicator
182 
183 void SAL_CALL StatusIndicator::setText( const OUString& sText )
184 {
185  // Ready for multithreading
186  MutexGuard aGuard( m_aMutex );
187 
188  // Take text on right control
189  m_xText->setText( sText );
190 }
191 
192 // XStatusIndicator
193 
194 void SAL_CALL StatusIndicator::setValue( sal_Int32 nValue )
195 {
196  // Ready for multithreading
197  MutexGuard aGuard( m_aMutex );
198 
199  // Take value on right control
200  m_xProgressBar->setValue( nValue );
201 }
202 
203 // XStatusIndicator
204 
205 void SAL_CALL StatusIndicator::reset()
206 {
207  // Ready for multithreading
208  MutexGuard aGuard( m_aMutex );
209 
210  // Clear values of status controls.
211  // (Don't hide the window! User will reset current values ... but he will not finish using of indicator!)
212  m_xText->setText( OUString() );
213  m_xProgressBar->setValue( 0 );
214 }
215 
216 // XLayoutConstrains
217 
219 {
221 }
222 
223 // XLayoutConstrains
224 
226 {
227  // Ready for multithreading
228  ClearableMutexGuard aGuard ( m_aMutex );
229 
230  // get information about required place of child controls
231  css::uno::Reference< XLayoutConstrains > xTextLayout ( m_xText, UNO_QUERY );
232  Size aTextSize = xTextLayout->getPreferredSize();
233 
234  aGuard.clear ();
235 
236  // calc preferred size of status indicator
237  sal_Int32 nWidth = impl_getWidth();
238  sal_Int32 nHeight = (2*STATUSINDICATOR_FREEBORDER)+aTextSize.Height;
239 
240  // norm to minimum
242  {
244  }
245  if ( nHeight<STATUSINDICATOR_DEFAULT_HEIGHT )
246  {
248  }
249 
250  // return to caller
251  return Size ( nWidth, nHeight );
252 }
253 
254 // XLayoutConstrains
255 
256 Size SAL_CALL StatusIndicator::calcAdjustedSize ( const Size& /*rNewSize*/ )
257 {
258  return getPreferredSize ();
259 }
260 
261 // XControl
262 
264  const css::uno::Reference< XToolkit > & rToolkit,
265  const css::uno::Reference< XWindowPeer > & rParent
266 )
267 {
268  if( !getPeer().is() )
269  {
270  BaseContainerControl::createPeer( rToolkit, rParent );
271 
272  // If user forget to call "setPosSize()", we have still a correct size.
273  // And a "MinimumSize" IS A "MinimumSize"!
274  // We change not the position of control at this point.
275  Size aDefaultSize = getMinimumSize ();
276  setPosSize ( 0, 0, aDefaultSize.Width, aDefaultSize.Height, PosSize::SIZE );
277  }
278 }
279 
280 // XControl
281 
282 sal_Bool SAL_CALL StatusIndicator::setModel ( const css::uno::Reference< XControlModel > & /*rModel*/ )
283 {
284  // We have no model.
285  return false;
286 }
287 
288 // XControl
289 
290 css::uno::Reference< XControlModel > SAL_CALL StatusIndicator::getModel ()
291 {
292  // We have no model.
293  // return (XControlModel*)this;
294  return css::uno::Reference< XControlModel > ();
295 }
296 
297 // XComponent
298 
299 void SAL_CALL StatusIndicator::dispose ()
300 {
301  // Ready for multithreading
302  MutexGuard aGuard ( m_aMutex );
303 
304  // "removeControl()" control the state of a reference
305  css::uno::Reference< XControl > xTextControl ( m_xText , UNO_QUERY );
306 
307  removeControl( xTextControl );
308  removeControl( m_xProgressBar.get() );
309 
310  // don't use "...->clear ()" or "... = XFixedText ()"
311  // when other hold a reference at this object !!!
312  xTextControl->dispose();
313  m_xProgressBar->dispose();
315 }
316 
317 // XWindow
318 
320  sal_Int32 nX,
321  sal_Int32 nY,
322  sal_Int32 nWidth,
323  sal_Int32 nHeight,
324  sal_Int16 nFlags
325 )
326 {
327  Rectangle aBasePosSize = getPosSize ();
328  BaseContainerControl::setPosSize (nX, nY, nWidth, nHeight, nFlags);
329 
330  // if position or size changed
331  if (
332  ( nWidth != aBasePosSize.Width ) ||
333  ( nHeight != aBasePosSize.Height)
334  )
335  {
336  // calc new layout for controls
337  impl_recalcLayout ( WindowEvent(static_cast< OWeakObject* >(this),0,0,nWidth,nHeight,0,0,0,0) );
338  // clear background (!)
339  // [Children were repainted in "recalcLayout" by setPosSize() automatically!]
340  getPeer()->invalidate(2);
341  // and repaint the control
342  impl_paint ( 0, 0, impl_getGraphicsPeer() );
343  }
344 }
345 
346 // protected method
347 
348 WindowDescriptor StatusIndicator::impl_getWindowDescriptor( const css::uno::Reference< XWindowPeer >& xParentPeer )
349 {
350  WindowDescriptor aDescriptor;
351 
352  aDescriptor.Type = WindowClass_SIMPLE;
353  aDescriptor.WindowServiceName = "floatingwindow";
354  aDescriptor.ParentIndex = -1;
355  aDescriptor.Parent = xParentPeer;
356  aDescriptor.Bounds = getPosSize ();
357 
358  return aDescriptor;
359 }
360 
361 // protected method
362 
363 void StatusIndicator::impl_paint ( sal_Int32 nX, sal_Int32 nY, const css::uno::Reference< XGraphics > & rGraphics )
364 {
365  // This paint method is not buffered!
366  // Every request paint the completely control. (But only, if peer exist)
367  if ( !rGraphics.is () )
368  return;
369 
370  MutexGuard aGuard (m_aMutex);
371 
372  // background = gray
373  css::uno::Reference< XWindowPeer > xPeer( impl_getPeerWindow(), UNO_QUERY );
374  if( xPeer.is() )
375  xPeer->setBackground( STATUSINDICATOR_BACKGROUNDCOLOR );
376 
377  // FixedText background = gray
378  css::uno::Reference< XControl > xTextControl( m_xText, UNO_QUERY );
379  xPeer = xTextControl->getPeer();
380  if( xPeer.is() )
381  xPeer->setBackground( STATUSINDICATOR_BACKGROUNDCOLOR );
382 
383  // Progress background = gray
384  xPeer = m_xProgressBar->getPeer();
385  if( xPeer.is() )
386  xPeer->setBackground( STATUSINDICATOR_BACKGROUNDCOLOR );
387 
388  // paint shadow border
389  rGraphics->setLineColor ( STATUSINDICATOR_LINECOLOR_BRIGHT );
390  rGraphics->drawLine ( nX, nY, impl_getWidth(), nY );
391  rGraphics->drawLine ( nX, nY, nX , impl_getHeight() );
392 
393  rGraphics->setLineColor ( STATUSINDICATOR_LINECOLOR_SHADOW );
394  rGraphics->drawLine ( impl_getWidth()-1, impl_getHeight()-1, impl_getWidth()-1, nY );
395  rGraphics->drawLine ( impl_getWidth()-1, impl_getHeight()-1, nX , impl_getHeight()-1 );
396 }
397 
398 // protected method
399 
400 void StatusIndicator::impl_recalcLayout ( const WindowEvent& aEvent )
401 {
402  sal_Int32 nX_ProgressBar;
403  sal_Int32 nY_ProgressBar;
404  sal_Int32 nWidth_ProgressBar;
405  sal_Int32 nHeight_ProgressBar;
406  sal_Int32 nX_Text;
407  sal_Int32 nY_Text;
408  sal_Int32 nWidth_Text;
409  sal_Int32 nHeight_Text;
410 
411  // Ready for multithreading
412  MutexGuard aGuard ( m_aMutex );
413 
414  // get information about required place of child controls
415  Size aWindowSize ( aEvent.Width, aEvent.Height );
416  css::uno::Reference< XLayoutConstrains > xTextLayout ( m_xText, UNO_QUERY );
417  Size aTextSize = xTextLayout->getPreferredSize();
418 
419  if( aWindowSize.Width < STATUSINDICATOR_DEFAULT_WIDTH )
420  {
421  aWindowSize.Width = STATUSINDICATOR_DEFAULT_WIDTH;
422  }
423  if( aWindowSize.Height < STATUSINDICATOR_DEFAULT_HEIGHT )
424  {
426  }
427 
428  // calc position and size of child controls
429  nX_Text = STATUSINDICATOR_FREEBORDER;
430  nY_Text = STATUSINDICATOR_FREEBORDER;
431  nWidth_Text = aTextSize.Width;
432  nHeight_Text = aTextSize.Height;
433 
434  nX_ProgressBar = nX_Text+nWidth_Text+STATUSINDICATOR_FREEBORDER;
435  nY_ProgressBar = nY_Text;
436  nWidth_ProgressBar = aWindowSize.Width-nWidth_Text-(3*STATUSINDICATOR_FREEBORDER);
437  nHeight_ProgressBar = nHeight_Text;
438 
439  // Set new position and size on all controls
440  css::uno::Reference< XWindow > xTextWindow ( m_xText , UNO_QUERY );
441 
442  xTextWindow->setPosSize ( nX_Text , nY_Text , nWidth_Text , nHeight_Text , 15 );
443  m_xProgressBar->setPosSize( nX_ProgressBar, nY_ProgressBar, nWidth_ProgressBar, nHeight_ProgressBar, 15 );
444 }
445 
446 } // namespace unocontrols
447 
448 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
450  css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&)
451 {
452  return cppu::acquire(new unocontrols::StatusIndicator(context));
453 }
454 
455 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual css::awt::Size SAL_CALL getPreferredSize() override
Type
css::uno::Reference< css::awt::XFixedText > m_xText
#define STATUSINDICATOR_FREEBORDER
virtual ~StatusIndicator() override
ULONG m_refCount
rtl::Reference< ProgressBar > m_xProgressBar
virtual css::uno::Any SAL_CALL queryAggregation(const css::uno::Type &aType) override
virtual void SAL_CALL setValue(sal_Int32 nValue) override
#define STATUSINDICATOR_DEFAULT_HEIGHT
virtual void SAL_CALL release() override
decrement refcount XInterface acquire() A RuntimeException is thrown.
const css::uno::Reference< css::awt::XGraphics > & impl_getGraphicsPeer() const
virtual void SAL_CALL createPeer(const css::uno::Reference< css::awt::XToolkit > &xToolkit, const css::uno::Reference< css::awt::XWindowPeer > &xParent) override
virtual void SAL_CALL end() override
sal_Int32 impl_getHeight() const
virtual void SAL_CALL setText(const OUString &sText) override
virtual css::uno::Reference< css::awt::XControlModel > SAL_CALL getModel() override
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * stardiv_UnoControls_StatusIndicator_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
#define STATUSINDICATOR_LINECOLOR_BRIGHT
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
get information about supported interfaces XTypeProvider
virtual void impl_recalcLayout(const css::awt::WindowEvent &aEvent) override
#define CONTROLNAME_TEXT
virtual void SAL_CALL createPeer(const css::uno::Reference< css::awt::XToolkit > &xToolkit, const css::uno::Reference< css::awt::XWindowPeer > &xParent) override
sal_Int32 impl_getWidth() const
tools::Long Width() const
unsigned char sal_Bool
virtual css::awt::Size SAL_CALL getMinimumSize() override
#define FIXEDTEXT_SERVICENAME
virtual void impl_paint(sal_Int32 nX, sal_Int32 nY, const css::uno::Reference< css::awt::XGraphics > &rGraphics) override
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::Any SAL_CALL queryAggregation(const css::uno::Type &aType) override
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.
virtual css::awt::Rectangle SAL_CALL getPosSize() override
virtual void SAL_CALL setVisible(sal_Bool bVisible) override
StatusIndicator(const css::uno::Reference< css::uno::XComponentContext > &rxContext)
#define CONTROLNAME_PROGRESSBAR
#define STATUSINDICATOR_LINECOLOR_SHADOW
virtual css::uno::Reference< css::awt::XWindowPeer > SAL_CALL getPeer() override
#define FIXEDTEXT_MODELNAME
virtual sal_Bool SAL_CALL setModel(const css::uno::Reference< css::awt::XControlModel > &xModel) override
virtual void SAL_CALL removeControl(const css::uno::Reference< css::awt::XControl > &xControl) override
virtual void SAL_CALL dispose() override
virtual void SAL_CALL start(const OUString &sText, sal_Int32 nRange) override
tools::Long Height() const
virtual css::awt::Size SAL_CALL calcAdjustedSize(const css::awt::Size &aNewSize) override
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
get information about supported interfaces XTypeProvider
const css::uno::Reference< css::uno::XInterface > & impl_getDelegator() const
virtual css::awt::WindowDescriptor impl_getWindowDescriptor(const css::uno::Reference< css::awt::XWindowPeer > &xParentPeer) override
virtual void SAL_CALL dispose() override
if(!pCandidateA->getEnd().equal(pCandidateB->getStart()))
virtual void SAL_CALL acquire() override
increment refcount XInterface release() A RuntimeException is thrown.
#define STATUSINDICATOR_BACKGROUNDCOLOR
virtual void SAL_CALL reset() override
#define STATUSINDICATOR_DEFAULT_WIDTH
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.
const css::uno::Reference< css::awt::XWindow > & impl_getPeerWindow() const
virtual void SAL_CALL setPosSize(sal_Int32 nX, sal_Int32 nY, sal_Int32 nWidth, sal_Int32 nHeight, sal_Int16 nFlags) override