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 automatically 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 automatically 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() automatically!]
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