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/WindowAttribute.hpp>
23 #include <com/sun/star/uno/XComponentContext.hpp>
24 #include <cppuhelper/queryinterface.hxx>
25 #include <cppuhelper/typeprovider.hxx>
27 #include "progressbar.hxx"
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 using namespace ::com::sun::star::task
;
36 namespace unocontrols
{
40 StatusIndicator::StatusIndicator( const css::uno::Reference
< XComponentContext
>& rxContext
)
41 : BaseContainerControl ( rxContext
)
43 // Its not allowed to work with member in this method (refcounter !!!)
44 // But with a HACK (++refcount) its "OK" :-(
47 // Create instances for fixedtext and progress ...
48 m_xText
= css::uno::Reference
< XFixedText
> ( rxContext
->getServiceManager()->createInstanceWithContext( FIXEDTEXT_SERVICENAME
, rxContext
), UNO_QUERY
);
49 m_xProgressBar
= VclPtr
<ProgressBar
>::Create(rxContext
);
50 // ... cast controls to css::uno::Reference< XControl > and set model ...
51 // ( ProgressBar has no model !!! )
52 css::uno::Reference
< XControl
> xTextControl ( m_xText
, UNO_QUERY
);
53 xTextControl
->setModel( css::uno::Reference
< XControlModel
>( rxContext
->getServiceManager()->createInstanceWithContext( FIXEDTEXT_MODELNAME
, rxContext
), UNO_QUERY
) );
54 // ... and add controls to basecontainercontrol!
55 addControl( CONTROLNAME_TEXT
, xTextControl
);
56 addControl( CONTROLNAME_PROGRESSBAR
, m_xProgressBar
.get() );
57 // FixedText make it automatically visible by himself ... but not the progressbar !!!
58 // it must be set explicitly
59 m_xProgressBar
->setVisible( true );
60 // Reset to defaults !!!
61 // (progressbar take automatically its own defaults)
62 m_xText
->setText( "" );
67 StatusIndicator::~StatusIndicator() {}
71 Any SAL_CALL
StatusIndicator::queryInterface( const Type
& rType
) throw( RuntimeException
, std::exception
)
74 // Don't use mutex or guard in this method!!! Is a method of XInterface.
76 css::uno::Reference
< XInterface
> xDel
= BaseContainerControl::impl_getDelegator();
79 // If an delegator exist, forward question to his queryInterface.
80 // Delegator will ask his own queryAggregation!
81 aReturn
= xDel
->queryInterface( rType
);
85 // If an delegator unknown, forward question to own queryAggregation.
86 aReturn
= queryAggregation( rType
);
94 void SAL_CALL
StatusIndicator::acquire() throw()
97 // Don't use mutex or guard in this method!!! Is a method of XInterface.
99 // Forward to baseclass
100 BaseControl::acquire();
105 void SAL_CALL
StatusIndicator::release() throw()
108 // Don't use mutex or guard in this method!!! Is a method of XInterface.
110 // Forward to baseclass
111 BaseControl::release();
116 Sequence
< Type
> SAL_CALL
StatusIndicator::getTypes() throw( RuntimeException
, std::exception
)
118 // Optimize this method !
119 // We initialize a static variable only one time. And we don't must use a mutex at every call!
120 // For the first call; pTypeCollection is NULL - for the second call pTypeCollection is different from NULL!
121 static OTypeCollection
* pTypeCollection
= NULL
;
123 if ( pTypeCollection
== NULL
)
125 // Ready for multithreading; get global mutex for first call of this method only! see before
126 MutexGuard
aGuard( Mutex::getGlobalMutex() );
128 // Control these pointer again ... it can be, that another instance will be faster then these!
129 if ( pTypeCollection
== NULL
)
131 // Create a static typecollection ...
132 static OTypeCollection
aTypeCollection ( cppu::UnoType
<XLayoutConstrains
>::get(),
133 cppu::UnoType
<XStatusIndicator
>::get(),
134 BaseContainerControl::getTypes()
136 // ... and set his address to static pointer!
137 pTypeCollection
= &aTypeCollection
;
141 return pTypeCollection
->getTypes();
146 Any SAL_CALL
StatusIndicator::queryAggregation( const Type
& aType
) throw( RuntimeException
, std::exception
)
148 // Ask for my own supported interfaces ...
149 // Attention: XTypeProvider and XInterface are supported by OComponentHelper!
150 Any
aReturn ( ::cppu::queryInterface( aType
,
151 static_cast< XLayoutConstrains
* > ( this ) ,
152 static_cast< XStatusIndicator
* > ( this )
156 // If searched interface not supported by this class ...
157 if ( !aReturn
.hasValue() )
159 // ... ask baseclasses.
160 aReturn
= BaseControl::queryAggregation( aType
);
168 void SAL_CALL
StatusIndicator::start( const OUString
& sText
, sal_Int32 nRange
) throw( RuntimeException
, std::exception
)
170 // Ready for multithreading
171 MutexGuard
aGuard( m_aMutex
);
173 // Initialize status controls with given values.
174 m_xText
->setText( sText
);
175 m_xProgressBar
->setRange( 0, nRange
);
176 // force repaint ... fixedtext has changed !
177 impl_recalcLayout ( WindowEvent(static_cast< OWeakObject
* >(this),0,0,impl_getWidth(),impl_getHeight(),0,0,0,0) );
182 void SAL_CALL
StatusIndicator::end() throw( RuntimeException
, std::exception
)
184 // Ready for multithreading
185 MutexGuard
aGuard( m_aMutex
);
187 // Clear values of status controls.
188 m_xText
->setText( OUString() );
189 m_xProgressBar
->setValue( 0 );
195 void SAL_CALL
StatusIndicator::setText( const OUString
& sText
) throw( RuntimeException
, std::exception
)
197 // Ready for multithreading
198 MutexGuard
aGuard( m_aMutex
);
200 // Take text on right control
201 m_xText
->setText( sText
);
206 void SAL_CALL
StatusIndicator::setValue( sal_Int32 nValue
) throw( RuntimeException
, std::exception
)
208 // Ready for multithreading
209 MutexGuard
aGuard( m_aMutex
);
211 // Take value on right control
212 m_xProgressBar
->setValue( nValue
);
217 void SAL_CALL
StatusIndicator::reset() throw( RuntimeException
, std::exception
)
219 // Ready for multithreading
220 MutexGuard
aGuard( m_aMutex
);
222 // Clear values of status controls.
223 // (Don't hide the window! User will reset current values ... but he will not finish using of indicator!)
224 m_xText
->setText( OUString() );
225 m_xProgressBar
->setValue( 0 );
230 Size SAL_CALL
StatusIndicator::getMinimumSize () throw( RuntimeException
, std::exception
)
232 return Size (STATUSINDICATOR_DEFAULT_WIDTH
, STATUSINDICATOR_DEFAULT_HEIGHT
);
237 Size SAL_CALL
StatusIndicator::getPreferredSize () throw( RuntimeException
, std::exception
)
239 // Ready for multithreading
240 ClearableMutexGuard
aGuard ( m_aMutex
);
242 // get information about required place of child controls
243 css::uno::Reference
< XLayoutConstrains
> xTextLayout ( m_xText
, UNO_QUERY
);
244 Size aTextSize
= xTextLayout
->getPreferredSize();
248 // calc preferred size of status indicator
249 sal_Int32 nWidth
= impl_getWidth();
250 sal_Int32 nHeight
= (2*STATUSINDICATOR_FREEBORDER
)+aTextSize
.Height
;
253 if ( nWidth
<STATUSINDICATOR_DEFAULT_WIDTH
)
255 nWidth
= STATUSINDICATOR_DEFAULT_WIDTH
;
257 if ( nHeight
<STATUSINDICATOR_DEFAULT_HEIGHT
)
259 nHeight
= STATUSINDICATOR_DEFAULT_HEIGHT
;
263 return Size ( nWidth
, nHeight
);
268 Size SAL_CALL
StatusIndicator::calcAdjustedSize ( const Size
& /*rNewSize*/ ) throw( RuntimeException
, std::exception
)
270 return getPreferredSize ();
275 void SAL_CALL
StatusIndicator::createPeer (
276 const css::uno::Reference
< XToolkit
> & rToolkit
,
277 const css::uno::Reference
< XWindowPeer
> & rParent
278 ) throw( RuntimeException
, std::exception
)
280 if( !getPeer().is() )
282 BaseContainerControl::createPeer( rToolkit
, rParent
);
284 // If user forget to call "setPosSize()", we have still a correct size.
285 // And a "MinimumSize" IS A "MinimumSize"!
286 // We change not the position of control at this point.
287 Size aDefaultSize
= getMinimumSize ();
288 setPosSize ( 0, 0, aDefaultSize
.Width
, aDefaultSize
.Height
, PosSize::SIZE
);
294 sal_Bool SAL_CALL
StatusIndicator::setModel ( const css::uno::Reference
< XControlModel
> & /*rModel*/ ) throw( RuntimeException
, std::exception
)
302 css::uno::Reference
< XControlModel
> SAL_CALL
StatusIndicator::getModel () throw( RuntimeException
, std::exception
)
305 // return (XControlModel*)this;
306 return css::uno::Reference
< XControlModel
> ();
311 void SAL_CALL
StatusIndicator::dispose () throw( RuntimeException
, std::exception
)
313 // Ready for multithreading
314 MutexGuard
aGuard ( m_aMutex
);
316 // "removeControl()" control the state of a reference
317 css::uno::Reference
< XControl
> xTextControl ( m_xText
, UNO_QUERY
);
319 removeControl( xTextControl
);
320 removeControl( m_xProgressBar
.get() );
322 // do'nt use "...->clear ()" or "... = XFixedText ()"
323 // when other hold a reference at this object !!!
324 xTextControl
->dispose();
325 m_xProgressBar
->dispose();
326 BaseContainerControl::dispose();
331 void SAL_CALL
StatusIndicator::setPosSize (
337 ) throw( RuntimeException
, std::exception
)
339 Rectangle aBasePosSize
= getPosSize ();
340 BaseContainerControl::setPosSize (nX
, nY
, nWidth
, nHeight
, nFlags
);
342 // if position or size changed
344 ( nWidth
!= aBasePosSize
.Width
) ||
345 ( nHeight
!= aBasePosSize
.Height
)
348 // calc new layout for controls
349 impl_recalcLayout ( WindowEvent(static_cast< OWeakObject
* >(this),0,0,nWidth
,nHeight
,0,0,0,0) );
350 // clear background (!)
351 // [Children were repainted in "recalcLayout" by setPosSize() automatically!]
352 getPeer()->invalidate(2);
353 // and repaint the control
354 impl_paint ( 0, 0, impl_getGraphicsPeer() );
358 // impl but public method to register service
360 const Sequence
< OUString
> StatusIndicator::impl_getStaticSupportedServiceNames()
362 return css::uno::Sequence
<OUString
>();
365 // impl but public method to register service
367 const OUString
StatusIndicator::impl_getStaticImplementationName()
369 return OUString("stardiv.UnoControls.StatusIndicator");
374 WindowDescriptor
* StatusIndicator::impl_getWindowDescriptor( const css::uno::Reference
< XWindowPeer
>& xParentPeer
)
376 // - used from "createPeer()" to set the values of an ::com::sun::star::awt::WindowDescriptor !!!
377 // - if you will change the descriptor-values, you must override this virtuell function
378 // - the caller must release the memory for this dynamical descriptor !!!
380 WindowDescriptor
* pDescriptor
= new WindowDescriptor
;
382 pDescriptor
->Type
= WindowClass_SIMPLE
;
383 pDescriptor
->WindowServiceName
= "floatingwindow";
384 pDescriptor
->ParentIndex
= -1;
385 pDescriptor
->Parent
= xParentPeer
;
386 pDescriptor
->Bounds
= getPosSize ();
393 void StatusIndicator::impl_paint ( sal_Int32 nX
, sal_Int32 nY
, const css::uno::Reference
< XGraphics
> & rGraphics
)
395 // This paint method ist not buffered !!
396 // Every request paint the completely control. ( but only, if peer exist )
397 if ( rGraphics
.is () )
399 MutexGuard
aGuard (m_aMutex
);
402 css::uno::Reference
< XWindowPeer
> xPeer( impl_getPeerWindow(), UNO_QUERY
);
404 xPeer
->setBackground( STATUSINDICATOR_BACKGROUNDCOLOR
);
406 // FixedText background = gray
407 css::uno::Reference
< XControl
> xTextControl( m_xText
, UNO_QUERY
);
408 xPeer
= xTextControl
->getPeer();
410 xPeer
->setBackground( STATUSINDICATOR_BACKGROUNDCOLOR
);
412 // Progress background = gray
413 xPeer
= m_xProgressBar
->getPeer();
415 xPeer
->setBackground( STATUSINDICATOR_BACKGROUNDCOLOR
);
417 // paint shadow border
418 rGraphics
->setLineColor ( STATUSINDICATOR_LINECOLOR_BRIGHT
);
419 rGraphics
->drawLine ( nX
, nY
, impl_getWidth(), nY
);
420 rGraphics
->drawLine ( nX
, nY
, nX
, impl_getHeight() );
422 rGraphics
->setLineColor ( STATUSINDICATOR_LINECOLOR_SHADOW
);
423 rGraphics
->drawLine ( impl_getWidth()-1, impl_getHeight()-1, impl_getWidth()-1, nY
);
424 rGraphics
->drawLine ( impl_getWidth()-1, impl_getHeight()-1, nX
, impl_getHeight()-1 );
430 void StatusIndicator::impl_recalcLayout ( const WindowEvent
& aEvent
)
432 sal_Int32 nX_ProgressBar
;
433 sal_Int32 nY_ProgressBar
;
434 sal_Int32 nWidth_ProgressBar
;
435 sal_Int32 nHeight_ProgressBar
;
438 sal_Int32 nWidth_Text
;
439 sal_Int32 nHeight_Text
;
441 // Ready for multithreading
442 MutexGuard
aGuard ( m_aMutex
);
444 // get information about required place of child controls
445 Size
aWindowSize ( aEvent
.Width
, aEvent
.Height
);
446 css::uno::Reference
< XLayoutConstrains
> xTextLayout ( m_xText
, UNO_QUERY
);
447 Size aTextSize
= xTextLayout
->getPreferredSize();
449 if( aWindowSize
.Width
< STATUSINDICATOR_DEFAULT_WIDTH
)
451 aWindowSize
.Width
= STATUSINDICATOR_DEFAULT_WIDTH
;
453 if( aWindowSize
.Height
< STATUSINDICATOR_DEFAULT_HEIGHT
)
455 aWindowSize
.Height
= STATUSINDICATOR_DEFAULT_HEIGHT
;
458 // calc position and size of child controls
459 nX_Text
= STATUSINDICATOR_FREEBORDER
;
460 nY_Text
= STATUSINDICATOR_FREEBORDER
;
461 nWidth_Text
= aTextSize
.Width
;
462 nHeight_Text
= aTextSize
.Height
;
464 nX_ProgressBar
= nX_Text
+nWidth_Text
+STATUSINDICATOR_FREEBORDER
;
465 nY_ProgressBar
= nY_Text
;
466 nWidth_ProgressBar
= aWindowSize
.Width
-nWidth_Text
-(3*STATUSINDICATOR_FREEBORDER
);
467 nHeight_ProgressBar
= nHeight_Text
;
469 // Set new position and size on all controls
470 css::uno::Reference
< XWindow
> xTextWindow ( m_xText
, UNO_QUERY
);
472 xTextWindow
->setPosSize ( nX_Text
, nY_Text
, nWidth_Text
, nHeight_Text
, 15 );
473 m_xProgressBar
->setPosSize( nX_ProgressBar
, nY_ProgressBar
, nWidth_ProgressBar
, nHeight_ProgressBar
, 15 );
476 } // namespace unocontrols
478 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */