xref: /AOO41X/main/UnoControls/source/controls/statusindicator.cxx (revision 0b4ced1d4e3a9bc987eae61b8e131e5e85d0fb11)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 //____________________________________________________________________________________________________________
25 //  my own includes
26 //____________________________________________________________________________________________________________
27 
28 #include "statusindicator.hxx"
29 
30 //____________________________________________________________________________________________________________
31 //  includes of other projects
32 //____________________________________________________________________________________________________________
33 #include <com/sun/star/awt/InvalidateStyle.hpp>
34 #include <com/sun/star/awt/WindowAttribute.hpp>
35 #include <cppuhelper/typeprovider.hxx>
36 #include <tools/debug.hxx>
37 
38 //____________________________________________________________________________________________________________
39 //  includes of my project
40 //____________________________________________________________________________________________________________
41 #include "progressbar.hxx"
42 
43 //____________________________________________________________________________________________________________
44 //  namespace
45 //____________________________________________________________________________________________________________
46 
47 using namespace ::cppu                  ;
48 using namespace ::osl                   ;
49 using namespace ::rtl                   ;
50 using namespace ::com::sun::star::uno   ;
51 using namespace ::com::sun::star::lang  ;
52 using namespace ::com::sun::star::awt   ;
53 using namespace ::com::sun::star::task  ;
54 
55 namespace unocontrols{
56 
57 //____________________________________________________________________________________________________________
58 //  construct/destruct
59 //____________________________________________________________________________________________________________
60 
StatusIndicator(const Reference<XMultiServiceFactory> & xFactory)61 StatusIndicator::StatusIndicator( const Reference< XMultiServiceFactory >& xFactory )
62     : BaseContainerControl  ( xFactory  )
63 {
64     // Its not allowed to work with member in this method (refcounter !!!)
65     // But with a HACK (++refcount) its "OK" :-(
66     ++m_refCount ;
67 
68     // Create instances for fixedtext and progress ...
69     m_xText         = Reference< XFixedText >   ( xFactory->createInstance( OUString::createFromAscii( FIXEDTEXT_SERVICENAME    ) ), UNO_QUERY );
70     m_xProgressBar  = Reference< XProgressBar > ( xFactory->createInstance( OUString::createFromAscii( SERVICENAME_PROGRESSBAR  ) ), UNO_QUERY );
71     // ... cast controls to Reference< XControl > and set model ...
72     // ( ProgressBar has no model !!! )
73     Reference< XControl > xTextControl      ( m_xText       , UNO_QUERY );
74     Reference< XControl > xProgressControl  ( m_xProgressBar, UNO_QUERY );
75     xTextControl->setModel( Reference< XControlModel >( xFactory->createInstance( OUString::createFromAscii( FIXEDTEXT_MODELNAME ) ), UNO_QUERY ) );
76     // ... and add controls to basecontainercontrol!
77     addControl( OUString::createFromAscii( CONTROLNAME_TEXT         ), xTextControl     );
78     addControl( OUString::createFromAscii( CONTROLNAME_PROGRESSBAR  ), xProgressControl );
79     // FixedText make it automaticly visible by himself ... but not the progressbar !!!
80     // it must be set explicitly
81     Reference< XWindow > xProgressWindow( m_xProgressBar, UNO_QUERY );
82     xProgressWindow->setVisible( sal_True );
83     // Reset to defaults !!!
84     // (progressbar take automaticly its own defaults)
85     m_xText->setText( OUString::createFromAscii( DEFAULT_TEXT ) );
86 
87     --m_refCount ;
88 }
89 
~StatusIndicator()90 StatusIndicator::~StatusIndicator()
91 {
92     // Release all references
93     m_xText         = Reference< XFixedText >();
94     m_xProgressBar  = Reference< XProgressBar >();
95 }
96 
97 //____________________________________________________________________________________________________________
98 //  XInterface
99 //____________________________________________________________________________________________________________
100 
queryInterface(const Type & rType)101 Any SAL_CALL StatusIndicator::queryInterface( const Type& rType ) throw( RuntimeException )
102 {
103     // Attention:
104     //  Don't use mutex or guard in this method!!! Is a method of XInterface.
105     Any aReturn ;
106     Reference< XInterface > xDel = BaseContainerControl::impl_getDelegator();
107     if ( xDel.is() )
108     {
109         // If an delegator exist, forward question to his queryInterface.
110         // Delegator will ask his own queryAggregation!
111         aReturn = xDel->queryInterface( rType );
112     }
113     else
114     {
115         // If an delegator unknown, forward question to own queryAggregation.
116         aReturn = queryAggregation( rType );
117     }
118 
119     return aReturn ;
120 }
121 
122 //____________________________________________________________________________________________________________
123 //  XInterface
124 //____________________________________________________________________________________________________________
125 
acquire()126 void SAL_CALL StatusIndicator::acquire() throw()
127 {
128     // Attention:
129     //  Don't use mutex or guard in this method!!! Is a method of XInterface.
130 
131     // Forward to baseclass
132     BaseControl::acquire();
133 }
134 
135 //____________________________________________________________________________________________________________
136 //  XInterface
137 //____________________________________________________________________________________________________________
138 
release()139 void SAL_CALL StatusIndicator::release() throw()
140 {
141     // Attention:
142     //  Don't use mutex or guard in this method!!! Is a method of XInterface.
143 
144     // Forward to baseclass
145     BaseControl::release();
146 }
147 
148 //____________________________________________________________________________________________________________
149 //  XTypeProvider
150 //____________________________________________________________________________________________________________
151 
getTypes()152 Sequence< Type > SAL_CALL StatusIndicator::getTypes() throw( RuntimeException )
153 {
154     // Optimize this method !
155     // We initialize a static variable only one time. And we don't must use a mutex at every call!
156     // For the first call; pTypeCollection is NULL - for the second call pTypeCollection is different from NULL!
157     static OTypeCollection* pTypeCollection = NULL ;
158 
159     if ( pTypeCollection == NULL )
160     {
161         // Ready for multithreading; get global mutex for first call of this method only! see before
162         MutexGuard aGuard( Mutex::getGlobalMutex() );
163 
164         // Control these pointer again ... it can be, that another instance will be faster then these!
165         if ( pTypeCollection == NULL )
166         {
167             // Create a static typecollection ...
168             static OTypeCollection aTypeCollection  (   ::getCppuType(( const Reference< XLayoutConstrains  >*)NULL )   ,
169                                                         ::getCppuType(( const Reference< XStatusIndicator   >*)NULL )   ,
170                                                         BaseContainerControl::getTypes()
171                                                     );
172             // ... and set his address to static pointer!
173             pTypeCollection = &aTypeCollection ;
174         }
175     }
176 
177     return pTypeCollection->getTypes();
178 }
179 
180 //____________________________________________________________________________________________________________
181 //  XAggregation
182 //____________________________________________________________________________________________________________
183 
queryAggregation(const Type & aType)184 Any SAL_CALL StatusIndicator::queryAggregation( const Type& aType ) throw( RuntimeException )
185 {
186     // Ask for my own supported interfaces ...
187     // Attention: XTypeProvider and XInterface are supported by OComponentHelper!
188     Any aReturn ( ::cppu::queryInterface(   aType                                       ,
189                                             static_cast< XLayoutConstrains* > ( this )  ,
190                                             static_cast< XStatusIndicator*  > ( this )
191                                         )
192                 );
193 
194     // If searched interface not supported by this class ...
195     if ( aReturn.hasValue() == sal_False )
196     {
197         // ... ask baseclasses.
198         aReturn = BaseControl::queryAggregation( aType );
199     }
200 
201     return aReturn ;
202 }
203 
204 //____________________________________________________________________________________________________________
205 //  XStatusIndicator
206 //____________________________________________________________________________________________________________
207 
start(const OUString & sText,sal_Int32 nRange)208 void SAL_CALL StatusIndicator::start( const OUString& sText, sal_Int32 nRange ) throw( RuntimeException )
209 {
210     // Ready for multithreading
211     MutexGuard aGuard( m_aMutex );
212 
213     // Initialize status controls with given values.
214     m_xText->setText( sText );
215     m_xProgressBar->setRange( 0, nRange );
216     // force repaint ... fixedtext has changed !
217     impl_recalcLayout ( WindowEvent(static_cast< OWeakObject* >(this),0,0,impl_getWidth(),impl_getHeight(),0,0,0,0) ) ;
218 }
219 
220 //____________________________________________________________________________________________________________
221 //  XStatusIndicator
222 //____________________________________________________________________________________________________________
223 
end()224 void SAL_CALL StatusIndicator::end() throw( RuntimeException )
225 {
226     // Ready for multithreading
227     MutexGuard aGuard( m_aMutex );
228 
229     // Clear values of status controls.
230     m_xText->setText( OUString() );
231     m_xProgressBar->setValue( 0 );
232     setVisible( sal_False );
233 }
234 
235 //____________________________________________________________________________________________________________
236 //  XStatusIndicator
237 //____________________________________________________________________________________________________________
238 
setText(const OUString & sText)239 void SAL_CALL StatusIndicator::setText( const OUString& sText ) throw( RuntimeException )
240 {
241     // Ready for multithreading
242     MutexGuard aGuard( m_aMutex );
243 
244     // Take text on right control
245     m_xText->setText( sText );
246 }
247 
248 //____________________________________________________________________________________________________________
249 //  XStatusIndicator
250 //____________________________________________________________________________________________________________
251 
setValue(sal_Int32 nValue)252 void SAL_CALL StatusIndicator::setValue( sal_Int32 nValue ) throw( RuntimeException )
253 {
254     // Ready for multithreading
255     MutexGuard aGuard( m_aMutex );
256 
257     // Take value on right control
258     m_xProgressBar->setValue( nValue );
259 }
260 
261 //____________________________________________________________________________________________________________
262 //  XStatusIndicator
263 //____________________________________________________________________________________________________________
264 
reset()265 void SAL_CALL StatusIndicator::reset() throw( RuntimeException )
266 {
267     // Ready for multithreading
268     MutexGuard aGuard( m_aMutex );
269 
270     // Clear values of status controls.
271     // (Don't hide the window! User will reset current values ... but he will not finish using of indicator!)
272     m_xText->setText( OUString() );
273     m_xProgressBar->setValue( 0 );
274 }
275 
276 //____________________________________________________________________________________________________________
277 //  XLayoutConstrains
278 //____________________________________________________________________________________________________________
279 
getMinimumSize()280 Size SAL_CALL StatusIndicator::getMinimumSize () throw( RuntimeException )
281 {
282     return Size (DEFAULT_WIDTH, DEFAULT_HEIGHT) ;
283 }
284 
285 //____________________________________________________________________________________________________________
286 //  XLayoutConstrains
287 //____________________________________________________________________________________________________________
288 
getPreferredSize()289 Size SAL_CALL StatusIndicator::getPreferredSize () throw( RuntimeException )
290 {
291     // Ready for multithreading
292     ClearableMutexGuard aGuard ( m_aMutex ) ;
293 
294     // get information about required place of child controls
295     Reference< XLayoutConstrains >  xTextLayout ( m_xText, UNO_QUERY );
296     Size                            aTextSize   = xTextLayout->getPreferredSize();
297 
298     aGuard.clear () ;
299 
300     // calc preferred size of status indicator
301     sal_Int32 nWidth  = impl_getWidth()                 ;
302     sal_Int32 nHeight = (2*FREEBORDER)+aTextSize.Height ;
303 
304     // norm to minimum
305     if ( nWidth<DEFAULT_WIDTH )
306     {
307         nWidth = DEFAULT_WIDTH ;
308     }
309     if ( nHeight<DEFAULT_HEIGHT )
310     {
311         nHeight = DEFAULT_HEIGHT ;
312     }
313 
314     // return to caller
315     return Size ( nWidth, nHeight ) ;
316 }
317 
318 //____________________________________________________________________________________________________________
319 //  XLayoutConstrains
320 //____________________________________________________________________________________________________________
321 
calcAdjustedSize(const Size &)322 Size SAL_CALL StatusIndicator::calcAdjustedSize ( const Size& /*rNewSize*/ ) throw( RuntimeException )
323 {
324     return getPreferredSize () ;
325 }
326 
327 //____________________________________________________________________________________________________________
328 //  XControl
329 //____________________________________________________________________________________________________________
330 
createPeer(const Reference<XToolkit> & rToolkit,const Reference<XWindowPeer> & rParent)331 void SAL_CALL StatusIndicator::createPeer ( const Reference< XToolkit > & rToolkit, const Reference< XWindowPeer > & rParent    ) throw( RuntimeException )
332 {
333     if( getPeer().is() == sal_False )
334     {
335         BaseContainerControl::createPeer( rToolkit, rParent );
336 
337         // If user forget to call "setPosSize()", we have still a correct size.
338         // And a "MinimumSize" IS A "MinimumSize"!
339         // We change not the position of control at this point.
340         Size aDefaultSize = getMinimumSize () ;
341         setPosSize ( 0, 0, aDefaultSize.Width, aDefaultSize.Height, PosSize::SIZE ) ;
342     }
343 }
344 
345 //____________________________________________________________________________________________________________
346 //  XControl
347 //____________________________________________________________________________________________________________
348 
setModel(const Reference<XControlModel> &)349 sal_Bool SAL_CALL StatusIndicator::setModel ( const Reference< XControlModel > & /*rModel*/ ) throw( RuntimeException )
350 {
351     // We have no model.
352     return sal_False ;
353 }
354 
355 //____________________________________________________________________________________________________________
356 //  XControl
357 //____________________________________________________________________________________________________________
358 
getModel()359 Reference< XControlModel > SAL_CALL StatusIndicator::getModel () throw( RuntimeException )
360 {
361     // We have no model.
362     // return (XControlModel*)this ;
363     return Reference< XControlModel >  () ;
364 }
365 
366 //____________________________________________________________________________________________________________
367 //  XComponent
368 //____________________________________________________________________________________________________________
369 
dispose()370 void SAL_CALL StatusIndicator::dispose () throw( RuntimeException )
371 {
372     // Ready for multithreading
373     MutexGuard aGuard ( m_aMutex ) ;
374 
375     // "removeControl()" control the state of a reference
376     Reference< XControl >  xTextControl     ( m_xText       , UNO_QUERY );
377     Reference< XControl >  xProgressControl ( m_xProgressBar, UNO_QUERY );
378 
379     removeControl( xTextControl     );
380     removeControl( xProgressControl );
381 
382     // do'nt use "...->clear ()" or "... = XFixedText ()"
383     // when other hold a reference at this object !!!
384     xTextControl->dispose();
385     xProgressControl->dispose();
386     BaseContainerControl::dispose();
387 }
388 
389 //____________________________________________________________________________________________________________
390 //  XWindow
391 //____________________________________________________________________________________________________________
392 
setPosSize(sal_Int32 nX,sal_Int32 nY,sal_Int32 nWidth,sal_Int32 nHeight,sal_Int16 nFlags)393 void SAL_CALL StatusIndicator::setPosSize ( sal_Int32 nX, sal_Int32 nY, sal_Int32 nWidth, sal_Int32 nHeight, sal_Int16 nFlags ) throw( RuntimeException )
394 {
395     Rectangle   aBasePosSize = getPosSize () ;
396     BaseContainerControl::setPosSize (nX, nY, nWidth, nHeight, nFlags) ;
397 
398     // if position or size changed
399     if (
400         ( nWidth  != aBasePosSize.Width ) ||
401         ( nHeight != aBasePosSize.Height)
402        )
403     {
404         // calc new layout for controls
405         impl_recalcLayout ( WindowEvent(static_cast< OWeakObject* >(this),0,0,nWidth,nHeight,0,0,0,0) ) ;
406         // clear background (!)
407         // [Childs was repainted in "recalcLayout" by setPosSize() automaticly!]
408         getPeer()->invalidate(2);
409         // and repaint the control
410         impl_paint ( 0, 0, impl_getGraphicsPeer() ) ;
411     }
412 }
413 
414 //____________________________________________________________________________________________________________
415 //  impl but public method to register service
416 //____________________________________________________________________________________________________________
417 
impl_getStaticSupportedServiceNames()418 const Sequence< OUString > StatusIndicator::impl_getStaticSupportedServiceNames()
419 {
420     MutexGuard aGuard( Mutex::getGlobalMutex() );
421     Sequence< OUString > seqServiceNames( 1 );
422     seqServiceNames.getArray() [0] = OUString::createFromAscii( SERVICENAME_STATUSINDICATOR );
423     return seqServiceNames ;
424 }
425 
426 //____________________________________________________________________________________________________________
427 //  impl but public method to register service
428 //____________________________________________________________________________________________________________
429 
impl_getStaticImplementationName()430 const OUString StatusIndicator::impl_getStaticImplementationName()
431 {
432     return OUString::createFromAscii( IMPLEMENTATIONNAME_STATUSINDICATOR );
433 }
434 
435 //____________________________________________________________________________________________________________
436 //  protected method
437 //____________________________________________________________________________________________________________
438 
impl_getWindowDescriptor(const Reference<XWindowPeer> & xParentPeer)439 WindowDescriptor* StatusIndicator::impl_getWindowDescriptor( const Reference< XWindowPeer >& xParentPeer )
440 {
441     // - used from "createPeer()" to set the values of an ::com::sun::star::awt::WindowDescriptor !!!
442     // - if you will change the descriptor-values, you must override this virtuell function
443     // - the caller must release the memory for this dynamical descriptor !!!
444 
445     WindowDescriptor* pDescriptor = new WindowDescriptor ;
446 
447     pDescriptor->Type               =   WindowClass_SIMPLE                              ;
448     pDescriptor->WindowServiceName  =   OUString::createFromAscii( "floatingwindow" )   ;
449     pDescriptor->ParentIndex        =   -1                                              ;
450     pDescriptor->Parent             =   xParentPeer                                     ;
451     pDescriptor->Bounds             =   getPosSize ()                                   ;
452 
453     return pDescriptor ;
454 }
455 
456 //____________________________________________________________________________________________________________
457 //  protected method
458 //____________________________________________________________________________________________________________
459 
impl_paint(sal_Int32 nX,sal_Int32 nY,const Reference<XGraphics> & rGraphics)460 void StatusIndicator::impl_paint ( sal_Int32 nX, sal_Int32 nY, const Reference< XGraphics > & rGraphics )
461 {
462     // This paint method ist not buffered !!
463     // Every request paint the completely control. ( but only, if peer exist )
464     if ( rGraphics.is () )
465     {
466         MutexGuard  aGuard (m_aMutex) ;
467 
468         // background = gray
469         Reference< XWindowPeer > xPeer( impl_getPeerWindow(), UNO_QUERY );
470         if( xPeer.is() == sal_True )
471             xPeer->setBackground( BACKGROUNDCOLOR );
472 
473         // FixedText background = gray
474         Reference< XControl > xTextControl( m_xText, UNO_QUERY );
475         xPeer = xTextControl->getPeer();
476         if( xPeer.is() == sal_True )
477             xPeer->setBackground( BACKGROUNDCOLOR );
478 
479         // Progress background = gray
480         xPeer = Reference< XWindowPeer >( m_xProgressBar, UNO_QUERY );
481         if( xPeer.is() == sal_True )
482             xPeer->setBackground( BACKGROUNDCOLOR );
483 
484         // paint shadow border
485         rGraphics->setLineColor ( LINECOLOR_BRIGHT                          );
486         rGraphics->drawLine     ( nX, nY, impl_getWidth(), nY               );
487         rGraphics->drawLine     ( nX, nY, nX             , impl_getHeight() );
488 
489         rGraphics->setLineColor ( LINECOLOR_SHADOW                                                              );
490         rGraphics->drawLine     ( impl_getWidth()-1, impl_getHeight()-1, impl_getWidth()-1, nY                  );
491         rGraphics->drawLine     ( impl_getWidth()-1, impl_getHeight()-1, nX               , impl_getHeight()-1  );
492     }
493 }
494 
495 //____________________________________________________________________________________________________________
496 //  protected method
497 //____________________________________________________________________________________________________________
498 
impl_recalcLayout(const WindowEvent & aEvent)499 void StatusIndicator::impl_recalcLayout ( const WindowEvent& aEvent )
500 {
501     sal_Int32   nX_ProgressBar          ;
502     sal_Int32   nY_ProgressBar          ;
503     sal_Int32   nWidth_ProgressBar      ;
504     sal_Int32   nHeight_ProgressBar     ;
505     sal_Int32   nX_Text                 ;
506     sal_Int32   nY_Text                 ;
507     sal_Int32   nWidth_Text             ;
508     sal_Int32   nHeight_Text            ;
509 
510     // Ready for multithreading
511     MutexGuard aGuard ( m_aMutex ) ;
512 
513     // get information about required place of child controls
514     Size                            aWindowSize     ( aEvent.Width, aEvent.Height );
515     Reference< XLayoutConstrains >  xTextLayout     ( m_xText, UNO_QUERY );
516     Size                            aTextSize       = xTextLayout->getPreferredSize();
517 
518     if( aWindowSize.Width < DEFAULT_WIDTH )
519     {
520         aWindowSize.Width = DEFAULT_WIDTH;
521     }
522     if( aWindowSize.Height < DEFAULT_HEIGHT )
523     {
524         aWindowSize.Height = DEFAULT_HEIGHT;
525     }
526 
527     // calc position and size of child controls
528     nX_Text             = FREEBORDER                                    ;
529     nY_Text             = FREEBORDER                                    ;
530     nWidth_Text         = aTextSize.Width                               ;
531     nHeight_Text        = aTextSize.Height                              ;
532 
533     nX_ProgressBar      = nX_Text+nWidth_Text+FREEBORDER                ;
534     nY_ProgressBar      = nY_Text                                       ;
535     nWidth_ProgressBar  = aWindowSize.Width-nWidth_Text-(3*FREEBORDER)  ;
536     nHeight_ProgressBar = nHeight_Text                                  ;
537 
538     // Set new position and size on all controls
539     Reference< XWindow >  xTextWindow       ( m_xText       , UNO_QUERY );
540     Reference< XWindow >  xProgressWindow   ( m_xProgressBar, UNO_QUERY );
541 
542     xTextWindow->setPosSize     ( nX_Text       , nY_Text       , nWidth_Text       , nHeight_Text          , 15 ) ;
543     xProgressWindow->setPosSize ( nX_ProgressBar, nY_ProgressBar, nWidth_ProgressBar, nHeight_ProgressBar   , 15 ) ;
544 }
545 
546 //____________________________________________________________________________________________________________
547 //  debug methods
548 //____________________________________________________________________________________________________________
549 
550 #if OSL_DEBUG_LEVEL > 1
551 
552 #endif  // #if OSL_DEBUG_LEVEL > 1
553 
554 }   // namespace unocontrols
555