Update ooo320-m1
[ooovba.git] / desktop / source / splash / splash.cxx
blob6101fa652bc0f4fc281e953bd56287e2e851171a
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: splash.cxx,v $
10 * $Revision: 1.32 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_desktop.hxx"
34 #include <introbmpnames.hxx>
35 #include "splash.hxx"
36 #include <stdio.h>
37 #include <unotools/bootstrap.hxx>
38 #include <vos/process.hxx>
39 #include <tools/urlobj.hxx>
40 #include <tools/stream.hxx>
41 #include <sfx2/sfx.hrc>
42 #include <vcl/svapp.hxx>
43 #include <vcl/salnativewidgets.hxx>
45 #include <com/sun/star/registry/XRegistryKey.hpp>
46 #include <rtl/bootstrap.hxx>
47 #include <rtl/logfile.hxx>
48 #include <rtl/ustrbuf.hxx>
49 #include <rtl/math.hxx>
51 #define NOT_LOADED ((long)-1)
53 using namespace ::rtl;
54 using namespace ::com::sun::star::registry;
56 namespace desktop
59 SplashScreen::SplashScreen(const Reference< XMultiServiceFactory >& rSMgr)
60 : IntroWindow()
61 , _vdev(*((IntroWindow*)this))
62 , _cProgressFrameColor(sal::static_int_cast< ColorData >(NOT_LOADED))
63 , _cProgressBarColor(sal::static_int_cast< ColorData >(NOT_LOADED))
64 , _iMax(100)
65 , _iProgress(0)
66 , _eBitmapMode(BM_DEFAULTMODE)
67 , _bPaintBitmap(sal_True)
68 , _bPaintProgress(sal_False)
69 , _bShowLogo(sal_True)
70 , _bFullScreenSplash(sal_False)
71 , _bProgressEnd(sal_False)
72 , _tlx(NOT_LOADED)
73 , _tly(NOT_LOADED)
74 , _barwidth(NOT_LOADED)
75 , _barheight(NOT_LOADED)
76 , _barspace(2)
77 , _fXPos(-1.0)
78 , _fYPos(-1.0)
79 , _fWidth(-1.0)
80 , _fHeight(-1.0)
81 , _xoffset(12)
82 , _yoffset(18)
84 _rFactory = rSMgr;
86 loadConfig();
89 SplashScreen::~SplashScreen()
91 Application::RemoveEventListener(
92 LINK( this, SplashScreen, AppEventListenerHdl ) );
93 Hide();
97 void SAL_CALL SplashScreen::start(const OUString&, sal_Int32 nRange)
98 throw (RuntimeException)
100 _iMax = nRange;
101 if (_bVisible) {
102 _bProgressEnd = sal_False;
103 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
104 if ( _eBitmapMode == BM_FULLSCREEN )
105 ShowFullScreenMode( TRUE );
106 Show();
107 Paint(Rectangle());
108 Flush();
112 void SAL_CALL SplashScreen::end()
113 throw (RuntimeException)
115 _iProgress = _iMax;
116 if (_bVisible )
118 if ( _eBitmapMode == BM_FULLSCREEN )
119 EndFullScreenMode();
120 Hide();
122 _bProgressEnd = sal_True;
125 void SAL_CALL SplashScreen::reset()
126 throw (RuntimeException)
128 _iProgress = 0;
129 if (_bVisible && !_bProgressEnd )
131 if ( _eBitmapMode == BM_FULLSCREEN )
132 ShowFullScreenMode( TRUE );
133 Show();
134 updateStatus();
138 void SAL_CALL SplashScreen::setText(const OUString&)
139 throw (RuntimeException)
141 if (_bVisible && !_bProgressEnd) {
142 if ( _eBitmapMode == BM_FULLSCREEN )
143 ShowFullScreenMode( TRUE );
144 Show();
145 Flush();
149 void SAL_CALL SplashScreen::setValue(sal_Int32 nValue)
150 throw (RuntimeException)
152 RTL_LOGFILE_CONTEXT( aLog, "::SplashScreen::setValue (lo119109)" );
153 RTL_LOGFILE_CONTEXT_TRACE1( aLog, "value=%d", nValue );
155 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
156 if (_bVisible && !_bProgressEnd) {
157 if ( _eBitmapMode == BM_FULLSCREEN )
158 ShowFullScreenMode( TRUE );
159 Show();
160 if (nValue >= _iMax) _iProgress = _iMax;
161 else _iProgress = nValue;
162 updateStatus();
166 // XInitialize
167 void SAL_CALL
168 SplashScreen::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any>& aArguments )
169 throw (RuntimeException)
171 ::osl::ClearableMutexGuard aGuard( _aMutex );
172 if (aArguments.getLength() > 0)
174 aArguments[0] >>= _bVisible;
175 if (aArguments.getLength() > 1 )
176 aArguments[1] >>= _sAppName;
178 // start to determine bitmap and all other required value
179 initBitmap();
180 Size aSize = _aIntroBmp.GetSizePixel();
181 SetOutputSizePixel( aSize );
182 _vdev.SetOutputSizePixel( aSize );
183 _height = aSize.Height();
184 _width = aSize.Width();
185 if (_width > 500)
187 Point xtopleft(212,216);
188 if ( NOT_LOADED == _tlx || NOT_LOADED == _tly )
190 _tlx = xtopleft.X(); // top-left x
191 _tly = xtopleft.Y(); // top-left y
193 if ( NOT_LOADED == _barwidth )
194 _barwidth = 263;
195 if ( NOT_LOADED == _barheight )
196 _barheight = 8;
197 if (( _eBitmapMode == BM_FULLSCREEN ) &&
198 _bFullScreenSplash )
200 if( ( _fXPos >= 0.0 ) && ( _fYPos >= 0.0 ))
202 _tlx = sal_Int32( double( aSize.Width() ) * _fXPos );
203 _tly = sal_Int32( double( aSize.Height() ) * _fYPos );
205 if ( _fWidth >= 0.0 )
206 _barwidth = sal_Int32( double( aSize.Width() ) * _fWidth );
207 if ( _fHeight >= 0.0 )
208 _barheight = sal_Int32( double( aSize.Width() ) * _fHeight );
211 else
213 if ( NOT_LOADED == _barwidth )
214 _barwidth = _width - (2 * _xoffset);
215 if ( NOT_LOADED == _barheight )
216 _barheight = 6;
217 if ( NOT_LOADED == _tlx || NOT_LOADED == _tly )
219 _tlx = _xoffset; // top-left x
220 _tly = _height - _yoffset; // top-left y
224 if ( sal::static_int_cast< ColorData >(NOT_LOADED) ==
225 _cProgressFrameColor.GetColor() )
226 _cProgressFrameColor = Color( COL_LIGHTGRAY );
228 if ( sal::static_int_cast< ColorData >(NOT_LOADED) ==
229 _cProgressBarColor.GetColor() )
231 // progress bar: new color only for big bitmap format
232 if ( _width > 500 )
233 _cProgressBarColor = Color( 157, 202, 18 );
234 else
235 _cProgressBarColor = Color( COL_BLUE );
238 Application::AddEventListener(
239 LINK( this, SplashScreen, AppEventListenerHdl ) );
241 SetBackgroundBitmap( _aIntroBmp );
245 void SplashScreen::updateStatus()
247 if (!_bVisible || _bProgressEnd) return;
248 if (!_bPaintProgress) _bPaintProgress = sal_True;
249 //_bPaintBitmap=sal_False;
250 Paint(Rectangle());
251 //_bPaintBitmap=sal_True;
252 Flush();
255 // internal private methods
256 IMPL_LINK( SplashScreen, AppEventListenerHdl, VclWindowEvent *, inEvent )
258 if ( inEvent != 0 )
260 // Paint( Rectangle() );
261 switch ( inEvent->GetId() )
263 case VCLEVENT_WINDOW_SHOW:
264 Paint( Rectangle() );
265 break;
266 default:
267 break;
270 return 0;
273 // Read keys from edition/edition.ini or soffice{.ini|rc}:
274 OUString implReadBootstrapKey( const OUString& _rKey )
276 OUString sValue(
277 rtl::OUString(
278 RTL_CONSTASCII_USTRINGPARAM(
279 "${.override:${BRAND_BASE_DIR}/program/edition/edition.ini:")) +
280 _rKey + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("}")));
281 rtl::Bootstrap::expandMacros(sValue);
282 return sValue;
285 void SplashScreen::loadConfig()
287 _bShowLogo = !implReadBootstrapKey(
288 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Logo"))).
289 equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("0"));
291 OUString sProgressFrameColor = implReadBootstrapKey(
292 OUString( RTL_CONSTASCII_USTRINGPARAM( "ProgressFrameColor" ) ) );
293 OUString sProgressBarColor = implReadBootstrapKey(
294 OUString( RTL_CONSTASCII_USTRINGPARAM( "ProgressBarColor" ) ) );
295 OUString sSize = implReadBootstrapKey(
296 OUString( RTL_CONSTASCII_USTRINGPARAM( "ProgressSize" ) ) );
297 OUString sPosition = implReadBootstrapKey(
298 OUString( RTL_CONSTASCII_USTRINGPARAM( "ProgressPosition" ) ) );
299 OUString sFullScreenSplash = implReadBootstrapKey(
300 OUString( RTL_CONSTASCII_USTRINGPARAM( "FullScreenSplash" ) ) );
302 // Determine full screen splash mode
303 _bFullScreenSplash = (( sFullScreenSplash.getLength() > 0 ) &&
304 ( !sFullScreenSplash.equalsAsciiL( "0", 1 )));
306 // Try to retrieve the relative values for the progress bar. The current
307 // schema uses the screen ratio to retrieve the associated values.
308 if ( _bFullScreenSplash )
309 determineProgressRatioValues( _fXPos, _fYPos, _fWidth, _fHeight );
311 if ( sProgressFrameColor.getLength() )
313 UINT8 nRed = 0;
314 UINT8 nGreen = 0;
315 UINT8 nBlue = 0;
316 sal_Int32 idx = 0;
317 sal_Int32 temp = sProgressFrameColor.getToken( 0, ',', idx ).toInt32();
318 if ( idx != -1 )
320 nRed = static_cast< UINT8 >( temp );
321 temp = sProgressFrameColor.getToken( 0, ',', idx ).toInt32();
323 if ( idx != -1 )
325 nGreen = static_cast< UINT8 >( temp );
326 nBlue = static_cast< UINT8 >( sProgressFrameColor.getToken( 0, ',', idx ).toInt32() );
327 _cProgressFrameColor = Color( nRed, nGreen, nBlue );
331 if ( sProgressBarColor.getLength() )
333 UINT8 nRed = 0;
334 UINT8 nGreen = 0;
335 UINT8 nBlue = 0;
336 sal_Int32 idx = 0;
337 sal_Int32 temp = sProgressBarColor.getToken( 0, ',', idx ).toInt32();
338 if ( idx != -1 )
340 nRed = static_cast< UINT8 >( temp );
341 temp = sProgressBarColor.getToken( 0, ',', idx ).toInt32();
343 if ( idx != -1 )
345 nGreen = static_cast< UINT8 >( temp );
346 nBlue = static_cast< UINT8 >( sProgressBarColor.getToken( 0, ',', idx ).toInt32() );
347 _cProgressBarColor = Color( nRed, nGreen, nBlue );
351 if ( sSize.getLength() )
353 sal_Int32 idx = 0;
354 sal_Int32 temp = sSize.getToken( 0, ',', idx ).toInt32();
355 if ( idx != -1 )
357 _barwidth = temp;
358 _barheight = sSize.getToken( 0, ',', idx ).toInt32();
362 if ( _barheight >= 10 )
363 _barspace = 3; // more space between frame and bar
365 if ( sPosition.getLength() )
367 sal_Int32 idx = 0;
368 sal_Int32 temp = sPosition.getToken( 0, ',', idx ).toInt32();
369 if ( idx != -1 )
371 _tlx = temp;
372 _tly = sPosition.getToken( 0, ',', idx ).toInt32();
377 void SplashScreen::initBitmap()
379 if ( _bShowLogo )
381 OUString sExecutePath;
382 ::rtl::Bootstrap::get(
383 OUString( RTL_CONSTASCII_USTRINGPARAM( "BRAND_BASE_DIR" ) ),
384 sExecutePath );
385 sExecutePath += OUString( RTL_CONSTASCII_USTRINGPARAM( "/program/" ) );
387 bool haveBitmap = false;
389 // Try all bitmaps in INTRO_BITMAP_NAMES
390 sal_Int32 nIndex = 0;
391 OUString aIntroBitmapFiles( RTL_CONSTASCII_USTRINGPARAM( INTRO_BITMAP_STRINGLIST ));
394 haveBitmap = loadBitmap( sExecutePath, aIntroBitmapFiles.getToken( 0, ',', nIndex ) );
396 while ( !haveBitmap && ( nIndex >= 0 ) );
398 if (!haveBitmap) {
399 rtl::OUString edition(
400 rtl::OUString(
401 RTL_CONSTASCII_USTRINGPARAM(
402 "${BRAND_BASE_DIR}/program/edition")));
403 rtl::Bootstrap::expandMacros(edition);
404 haveBitmap = findBitmap(edition);
406 if (!haveBitmap) {
407 findBitmap(sExecutePath);
412 bool SplashScreen::loadBitmap(
413 rtl::OUString const & path, const rtl::OUString &rBmpFileName )
415 if ( rBmpFileName.getLength() == 0 )
416 return false;
418 INetURLObject aObj( path, INET_PROT_FILE );
419 aObj.insertName( rBmpFileName );
421 SvFileStream aStrm( aObj.PathToFileName(), STREAM_STD_READ );
422 if ( !aStrm.GetError() )
424 // Default case, we load the intro bitmap from a seperate file
425 // (e.g. staroffice_intro.bmp or starsuite_intro.bmp)
426 aStrm >> _aIntroBmp;
427 return true;
430 return false;
433 bool SplashScreen::findBitmap(rtl::OUString const & path) {
434 bool haveBitmap = false;
435 if ( _bFullScreenSplash )
437 haveBitmap = findScreenBitmap(path);
438 if ( haveBitmap )
439 _eBitmapMode = BM_FULLSCREEN;
440 else
441 haveBitmap = findAppBitmap(path);
443 if ( !haveBitmap )
444 haveBitmap = loadBitmap(
445 path, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("intro.bmp")));
446 return haveBitmap;
449 bool SplashScreen::findScreenBitmap(rtl::OUString const & path)
451 sal_Int32 nWidth( 0 );
452 sal_Int32 nHeight( 0 );
454 // determine desktop resolution
455 sal_uInt32 nCount = Application::GetScreenCount();
456 if ( nCount > 0 )
458 // retrieve size from first screen
459 Rectangle aScreenArea = Application::GetScreenPosSizePixel((unsigned int)0);
460 nWidth = aScreenArea.GetWidth();
461 nHeight = aScreenArea.GetHeight();
464 // create file name from screen resolution information
465 OUStringBuffer aStrBuf( 128 );
466 aStrBuf.appendAscii( "intro_" );
467 if ( _sAppName.getLength() > 0 )
469 aStrBuf.append( _sAppName );
470 aStrBuf.appendAscii( "_" );
472 aStrBuf.append( OUString::valueOf( nWidth ));
473 aStrBuf.appendAscii( "x" );
474 aStrBuf.append( OUString::valueOf( nHeight ));
475 aStrBuf.appendAscii( ".bmp" );
476 OUString aBmpFileName = aStrBuf.makeStringAndClear();
478 bool haveBitmap = loadBitmap( path, aBmpFileName );
479 if ( !haveBitmap )
481 aStrBuf.appendAscii( "intro_" );
482 aStrBuf.appendAscii( "_" );
483 aStrBuf.append( OUString::valueOf( nWidth ));
484 aStrBuf.appendAscii( "x" );
485 aStrBuf.append( OUString::valueOf( nHeight ));
486 aStrBuf.appendAscii( ".bmp" );
487 aBmpFileName = aStrBuf.makeStringAndClear();
489 haveBitmap = loadBitmap( path, aBmpFileName );
491 return haveBitmap;
494 bool SplashScreen::findAppBitmap(rtl::OUString const & path)
496 bool haveBitmap = false;
498 if ( _sAppName.getLength() > 0 )
500 OUStringBuffer aStrBuf( 128 );
501 aStrBuf.appendAscii( "intro_" );
502 aStrBuf.appendAscii( "_" );
503 aStrBuf.append( _sAppName );
504 aStrBuf.appendAscii( ".bmp" );
505 OUString aBmpFileName = aStrBuf.makeStringAndClear();
506 haveBitmap = loadBitmap( path, aBmpFileName );
508 return haveBitmap;
511 void SplashScreen::determineProgressRatioValues(
512 double& rXRelPos, double& rYRelPos,
513 double& rRelWidth, double& rRelHeight )
515 sal_Int32 nWidth( 0 );
516 sal_Int32 nHeight( 0 );
517 sal_Int32 nScreenRatio( 0 );
519 // determine desktop resolution
520 sal_uInt32 nCount = Application::GetScreenCount();
521 if ( nCount > 0 )
523 // retrieve size from first screen
524 Rectangle aScreenArea = Application::GetScreenPosSizePixel((unsigned int)0);
525 nWidth = aScreenArea.GetWidth();
526 nHeight = aScreenArea.GetHeight();
527 nScreenRatio = sal_Int32( math::round( double( nWidth ) / double( nHeight ), 2 ) * 100 );
530 char szFullScreenProgressRatio[] = "FullScreenProgressRatio0";
531 char szFullScreenProgressPos[] = "FullScreenProgressPos0";
532 char szFullScreenProgressSize[] = "FullScreenProgressSize0";
533 for ( sal_Int32 i = 0; i <= 9; i++ )
535 char cNum = '0' + char( i );
536 szFullScreenProgressRatio[23] = cNum;
537 szFullScreenProgressPos[21] = cNum;
538 szFullScreenProgressSize[22] = cNum;
540 OUString sFullScreenProgressRatio = implReadBootstrapKey(
541 OUString::createFromAscii( szFullScreenProgressRatio ) );
543 if ( sFullScreenProgressRatio.getLength() > 0 )
545 double fRatio = sFullScreenProgressRatio.toDouble();
546 sal_Int32 nRatio = sal_Int32( math::round( fRatio, 2 ) * 100 );
547 if ( nRatio == nScreenRatio )
549 OUString sFullScreenProgressPos = implReadBootstrapKey(
550 OUString::createFromAscii( szFullScreenProgressPos ) );
551 OUString sFullScreenProgressSize = implReadBootstrapKey(
552 OUString::createFromAscii( szFullScreenProgressSize ) );
554 if ( sFullScreenProgressPos.getLength() )
556 sal_Int32 idx = 0;
557 double temp = sFullScreenProgressPos.getToken( 0, ',', idx ).toDouble();
558 if ( idx != -1 )
560 rXRelPos = temp;
561 rYRelPos = sFullScreenProgressPos.getToken( 0, ',', idx ).toDouble();
565 if ( sFullScreenProgressSize.getLength() )
567 sal_Int32 idx = 0;
568 double temp = sFullScreenProgressSize.getToken( 0, ',', idx ).toDouble();
569 if ( idx != -1 )
571 rRelWidth = temp;
572 rRelHeight = sFullScreenProgressSize.getToken( 0, ',', idx ).toDouble();
577 else
578 break;
582 void SplashScreen::Paint( const Rectangle&)
584 if(!_bVisible) return;
586 //native drawing
587 BOOL bNativeOK = FALSE;
589 // in case of native controls we need to draw directly to the window
590 if( IsNativeControlSupported( CTRL_INTROPROGRESS, PART_ENTIRE_CONTROL ) )
592 DrawBitmap( Point(), _aIntroBmp );
594 ImplControlValue aValue( _iProgress * _barwidth / _iMax);
595 Rectangle aDrawRect( Point(_tlx, _tly), Size( _barwidth, _barheight ) );
596 Region aControlRegion( aDrawRect );
597 Region aNativeControlRegion, aNativeContentRegion;
599 if( GetNativeControlRegion( CTRL_INTROPROGRESS, PART_ENTIRE_CONTROL, aControlRegion,
600 CTRL_STATE_ENABLED, aValue, rtl::OUString(),
601 aNativeControlRegion, aNativeContentRegion ) )
603 long nProgressHeight = aNativeControlRegion.GetBoundRect().GetHeight();
604 aDrawRect.Top() -= (nProgressHeight - _barheight)/2;
605 aDrawRect.Bottom() += (nProgressHeight - _barheight)/2;
606 aControlRegion = Region( aDrawRect );
609 if( (bNativeOK = DrawNativeControl( CTRL_INTROPROGRESS, PART_ENTIRE_CONTROL, aControlRegion,
610 CTRL_STATE_ENABLED, aValue, rtl::OUString() )) != FALSE )
612 return;
615 //non native drawing
616 // draw bitmap
617 if (_bPaintBitmap)
618 _vdev.DrawBitmap( Point(), _aIntroBmp );
620 if (_bPaintProgress) {
621 // draw progress...
622 long length = (_iProgress * _barwidth / _iMax) - (2 * _barspace);
623 if (length < 0) length = 0;
625 // border
626 _vdev.SetFillColor();
627 _vdev.SetLineColor( _cProgressFrameColor );
628 _vdev.DrawRect(Rectangle(_tlx, _tly, _tlx+_barwidth, _tly+_barheight));
629 _vdev.SetFillColor( _cProgressBarColor );
630 _vdev.SetLineColor();
631 Rectangle aRect(_tlx+_barspace, _tly+_barspace, _tlx+_barspace+length, _tly+_barheight-_barspace);
632 _vdev.DrawRect(Rectangle(_tlx+_barspace, _tly+_barspace,
633 _tlx+_barspace+length, _tly+_barheight-_barspace));
636 Size aSize = GetOutputSizePixel();
637 Size bSize = _vdev.GetOutputSizePixel();
638 //_vdev.Flush();
639 //_vdev.DrawOutDev(Point(), GetOutputSize(), Point(), GetOutputSize(), *((IntroWindow*)this) );
640 DrawOutDev(Point(), GetOutputSizePixel(), Point(), _vdev.GetOutputSizePixel(), _vdev );
641 //Flush();
645 // get service instance...
646 SplashScreen *SplashScreen::_pINSTANCE = NULL;
647 osl::Mutex SplashScreen::_aMutex;
649 Reference< XInterface > SplashScreen::getInstance(const Reference< XMultiServiceFactory >& rSMgr)
651 if ( _pINSTANCE == 0 )
653 osl::MutexGuard guard(_aMutex);
654 if (_pINSTANCE == 0)
655 return (XComponent*)new SplashScreen(rSMgr);
658 return (XComponent*)0;
661 // static service info...
662 const char* SplashScreen::interfaces[] =
664 "com.sun.star.task.XStartusIndicator",
665 "com.sun.star.lang.XInitialization",
666 NULL,
668 const sal_Char *SplashScreen::serviceName = "com.sun.star.office.SplashScreen";
669 const sal_Char *SplashScreen::implementationName = "com.sun.star.office.comp.SplashScreen";
670 const sal_Char *SplashScreen::supportedServiceNames[] = {"com.sun.star.office.SplashScreen", NULL};