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