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