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 <statusindicator.hxx>
22 #include <com/sun/star/awt/PosSize.hpp>
23 #include <com/sun/star/awt/XFixedText.hpp>
24 #include <com/sun/star/uno/XComponentContext.hpp>
25 #include <cppuhelper/queryinterface.hxx>
26 #include <cppuhelper/typeprovider.hxx>
28 #include <progressbar.hxx>
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
;
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" // -||-
42 namespace unocontrols
{
46 StatusIndicator::StatusIndicator( const css::uno::Reference
< XComponentContext
>& rxContext
)
47 : BaseContainerControl ( rxContext
)
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
);
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( "" );
70 osl_atomic_decrement(&m_refCount
);
73 StatusIndicator::~StatusIndicator() {}
77 Any SAL_CALL
StatusIndicator::queryInterface( const Type
& rType
)
80 // Don't use mutex or guard in this method!!! Is a method of XInterface.
82 css::uno::Reference
< XInterface
> xDel
= BaseContainerControl::impl_getDelegator();
85 // If a delegator exists, forward question to its queryInterface.
86 // Delegator will ask its own queryAggregation!
87 aReturn
= xDel
->queryInterface( rType
);
91 // If a delegator is unknown, forward question to own queryAggregation.
92 aReturn
= queryAggregation( rType
);
100 void SAL_CALL
StatusIndicator::acquire() throw()
103 // Don't use mutex or guard in this method!!! Is a method of XInterface.
105 // Forward to baseclass
106 BaseControl::acquire();
111 void SAL_CALL
StatusIndicator::release() throw()
114 // Don't use mutex or guard in this method!!! Is a method of XInterface.
116 // Forward to baseclass
117 BaseControl::release();
122 Sequence
< Type
> SAL_CALL
StatusIndicator::getTypes()
124 static OTypeCollection
ourTypeCollection(
125 cppu::UnoType
<XLayoutConstrains
>::get(),
126 cppu::UnoType
<XStatusIndicator
>::get(),
127 BaseContainerControl::getTypes() );
129 return ourTypeCollection
.getTypes();
134 Any SAL_CALL
StatusIndicator::queryAggregation( const Type
& aType
)
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 )
144 // If searched interface not supported by this class ...
145 if ( !aReturn
.hasValue() )
147 // ... ask baseclasses.
148 aReturn
= BaseControl::queryAggregation( aType
);
156 void SAL_CALL
StatusIndicator::start( const OUString
& sText
, sal_Int32 nRange
)
158 // Ready for multithreading
159 MutexGuard
aGuard( m_aMutex
);
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) );
170 void SAL_CALL
StatusIndicator::end()
172 // Ready for multithreading
173 MutexGuard
aGuard( m_aMutex
);
175 // Clear values of status controls.
176 m_xText
->setText( OUString() );
177 m_xProgressBar
->setValue( 0 );
183 void SAL_CALL
StatusIndicator::setText( const OUString
& sText
)
185 // Ready for multithreading
186 MutexGuard
aGuard( m_aMutex
);
188 // Take text on right control
189 m_xText
->setText( sText
);
194 void SAL_CALL
StatusIndicator::setValue( sal_Int32 nValue
)
196 // Ready for multithreading
197 MutexGuard
aGuard( m_aMutex
);
199 // Take value on right control
200 m_xProgressBar
->setValue( nValue
);
205 void SAL_CALL
StatusIndicator::reset()
207 // Ready for multithreading
208 MutexGuard
aGuard( m_aMutex
);
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 );
218 Size SAL_CALL
StatusIndicator::getMinimumSize ()
220 return Size (STATUSINDICATOR_DEFAULT_WIDTH
, STATUSINDICATOR_DEFAULT_HEIGHT
);
225 Size SAL_CALL
StatusIndicator::getPreferredSize ()
227 // Ready for multithreading
228 ClearableMutexGuard
aGuard ( m_aMutex
);
230 // get information about required place of child controls
231 css::uno::Reference
< XLayoutConstrains
> xTextLayout ( m_xText
, UNO_QUERY
);
232 Size aTextSize
= xTextLayout
->getPreferredSize();
236 // calc preferred size of status indicator
237 sal_Int32 nWidth
= impl_getWidth();
238 sal_Int32 nHeight
= (2*STATUSINDICATOR_FREEBORDER
)+aTextSize
.Height
;
241 if ( nWidth
<STATUSINDICATOR_DEFAULT_WIDTH
)
243 nWidth
= STATUSINDICATOR_DEFAULT_WIDTH
;
245 if ( nHeight
<STATUSINDICATOR_DEFAULT_HEIGHT
)
247 nHeight
= STATUSINDICATOR_DEFAULT_HEIGHT
;
251 return Size ( nWidth
, nHeight
);
256 Size SAL_CALL
StatusIndicator::calcAdjustedSize ( const Size
& /*rNewSize*/ )
258 return getPreferredSize ();
263 void SAL_CALL
StatusIndicator::createPeer (
264 const css::uno::Reference
< XToolkit
> & rToolkit
,
265 const css::uno::Reference
< XWindowPeer
> & rParent
268 if( !getPeer().is() )
270 BaseContainerControl::createPeer( rToolkit
, rParent
);
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
);
282 sal_Bool SAL_CALL
StatusIndicator::setModel ( const css::uno::Reference
< XControlModel
> & /*rModel*/ )
290 css::uno::Reference
< XControlModel
> SAL_CALL
StatusIndicator::getModel ()
293 // return (XControlModel*)this;
294 return css::uno::Reference
< XControlModel
> ();
299 void SAL_CALL
StatusIndicator::dispose ()
301 // Ready for multithreading
302 MutexGuard
aGuard ( m_aMutex
);
304 // "removeControl()" control the state of a reference
305 css::uno::Reference
< XControl
> xTextControl ( m_xText
, UNO_QUERY
);
307 removeControl( xTextControl
);
308 removeControl( m_xProgressBar
.get() );
310 // don't use "...->clear ()" or "... = XFixedText ()"
311 // when other hold a reference at this object !!!
312 xTextControl
->dispose();
313 m_xProgressBar
->dispose();
314 BaseContainerControl::dispose();
319 void SAL_CALL
StatusIndicator::setPosSize (
327 Rectangle aBasePosSize
= getPosSize ();
328 BaseContainerControl::setPosSize (nX
, nY
, nWidth
, nHeight
, nFlags
);
330 // if position or size changed
332 ( nWidth
!= aBasePosSize
.Width
) ||
333 ( nHeight
!= aBasePosSize
.Height
)
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() );
346 // impl but public method to register service
348 Sequence
< OUString
> StatusIndicator::impl_getStaticSupportedServiceNames()
350 return css::uno::Sequence
<OUString
>();
353 // impl but public method to register service
355 OUString
StatusIndicator::impl_getStaticImplementationName()
357 return "stardiv.UnoControls.StatusIndicator";
362 WindowDescriptor
StatusIndicator::impl_getWindowDescriptor( const css::uno::Reference
< XWindowPeer
>& xParentPeer
)
364 WindowDescriptor aDescriptor
;
366 aDescriptor
.Type
= WindowClass_SIMPLE
;
367 aDescriptor
.WindowServiceName
= "floatingwindow";
368 aDescriptor
.ParentIndex
= -1;
369 aDescriptor
.Parent
= xParentPeer
;
370 aDescriptor
.Bounds
= getPosSize ();
377 void StatusIndicator::impl_paint ( sal_Int32 nX
, sal_Int32 nY
, const css::uno::Reference
< XGraphics
> & rGraphics
)
379 // This paint method is not buffered!
380 // Every request paint the completely control. (But only, if peer exist)
381 if ( rGraphics
.is () )
383 MutexGuard
aGuard (m_aMutex
);
386 css::uno::Reference
< XWindowPeer
> xPeer( impl_getPeerWindow(), UNO_QUERY
);
388 xPeer
->setBackground( STATUSINDICATOR_BACKGROUNDCOLOR
);
390 // FixedText background = gray
391 css::uno::Reference
< XControl
> xTextControl( m_xText
, UNO_QUERY
);
392 xPeer
= xTextControl
->getPeer();
394 xPeer
->setBackground( STATUSINDICATOR_BACKGROUNDCOLOR
);
396 // Progress background = gray
397 xPeer
= m_xProgressBar
->getPeer();
399 xPeer
->setBackground( STATUSINDICATOR_BACKGROUNDCOLOR
);
401 // paint shadow border
402 rGraphics
->setLineColor ( STATUSINDICATOR_LINECOLOR_BRIGHT
);
403 rGraphics
->drawLine ( nX
, nY
, impl_getWidth(), nY
);
404 rGraphics
->drawLine ( nX
, nY
, nX
, impl_getHeight() );
406 rGraphics
->setLineColor ( STATUSINDICATOR_LINECOLOR_SHADOW
);
407 rGraphics
->drawLine ( impl_getWidth()-1, impl_getHeight()-1, impl_getWidth()-1, nY
);
408 rGraphics
->drawLine ( impl_getWidth()-1, impl_getHeight()-1, nX
, impl_getHeight()-1 );
414 void StatusIndicator::impl_recalcLayout ( const WindowEvent
& aEvent
)
416 sal_Int32 nX_ProgressBar
;
417 sal_Int32 nY_ProgressBar
;
418 sal_Int32 nWidth_ProgressBar
;
419 sal_Int32 nHeight_ProgressBar
;
422 sal_Int32 nWidth_Text
;
423 sal_Int32 nHeight_Text
;
425 // Ready for multithreading
426 MutexGuard
aGuard ( m_aMutex
);
428 // get information about required place of child controls
429 Size
aWindowSize ( aEvent
.Width
, aEvent
.Height
);
430 css::uno::Reference
< XLayoutConstrains
> xTextLayout ( m_xText
, UNO_QUERY
);
431 Size aTextSize
= xTextLayout
->getPreferredSize();
433 if( aWindowSize
.Width
< STATUSINDICATOR_DEFAULT_WIDTH
)
435 aWindowSize
.Width
= STATUSINDICATOR_DEFAULT_WIDTH
;
437 if( aWindowSize
.Height
< STATUSINDICATOR_DEFAULT_HEIGHT
)
439 aWindowSize
.Height
= STATUSINDICATOR_DEFAULT_HEIGHT
;
442 // calc position and size of child controls
443 nX_Text
= STATUSINDICATOR_FREEBORDER
;
444 nY_Text
= STATUSINDICATOR_FREEBORDER
;
445 nWidth_Text
= aTextSize
.Width
;
446 nHeight_Text
= aTextSize
.Height
;
448 nX_ProgressBar
= nX_Text
+nWidth_Text
+STATUSINDICATOR_FREEBORDER
;
449 nY_ProgressBar
= nY_Text
;
450 nWidth_ProgressBar
= aWindowSize
.Width
-nWidth_Text
-(3*STATUSINDICATOR_FREEBORDER
);
451 nHeight_ProgressBar
= nHeight_Text
;
453 // Set new position and size on all controls
454 css::uno::Reference
< XWindow
> xTextWindow ( m_xText
, UNO_QUERY
);
456 xTextWindow
->setPosSize ( nX_Text
, nY_Text
, nWidth_Text
, nHeight_Text
, 15 );
457 m_xProgressBar
->setPosSize( nX_ProgressBar
, nY_ProgressBar
, nWidth_ProgressBar
, nHeight_ProgressBar
, 15 );
460 } // namespace unocontrols
462 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */