1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: splash.cxx,v $
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>
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
;
59 SplashScreen::SplashScreen(const Reference
< XMultiServiceFactory
>& rSMgr
)
61 , _vdev(*((IntroWindow
*)this))
62 , _cProgressFrameColor(sal::static_int_cast
< ColorData
>(NOT_LOADED
))
63 , _cProgressBarColor(sal::static_int_cast
< ColorData
>(NOT_LOADED
))
66 , _eBitmapMode(BM_DEFAULTMODE
)
67 , _bPaintBitmap(sal_True
)
68 , _bPaintProgress(sal_False
)
69 , _bShowLogo(sal_True
)
70 , _bFullScreenSplash(sal_False
)
71 , _bProgressEnd(sal_False
)
74 , _barwidth(NOT_LOADED
)
75 , _barheight(NOT_LOADED
)
89 SplashScreen::~SplashScreen()
91 Application::RemoveEventListener(
92 LINK( this, SplashScreen
, AppEventListenerHdl
) );
97 void SAL_CALL
SplashScreen::start(const OUString
&, sal_Int32 nRange
)
98 throw (RuntimeException
)
102 _bProgressEnd
= sal_False
;
103 ::vos::OGuard
aSolarGuard( Application::GetSolarMutex() );
104 if ( _eBitmapMode
== BM_FULLSCREEN
)
105 ShowFullScreenMode( TRUE
);
112 void SAL_CALL
SplashScreen::end()
113 throw (RuntimeException
)
118 if ( _eBitmapMode
== BM_FULLSCREEN
)
122 _bProgressEnd
= sal_True
;
125 void SAL_CALL
SplashScreen::reset()
126 throw (RuntimeException
)
129 if (_bVisible
&& !_bProgressEnd
)
131 if ( _eBitmapMode
== BM_FULLSCREEN
)
132 ShowFullScreenMode( TRUE
);
138 void SAL_CALL
SplashScreen::setText(const OUString
&)
139 throw (RuntimeException
)
141 if (_bVisible
&& !_bProgressEnd
) {
142 if ( _eBitmapMode
== BM_FULLSCREEN
)
143 ShowFullScreenMode( TRUE
);
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
);
160 if (nValue
>= _iMax
) _iProgress
= _iMax
;
161 else _iProgress
= nValue
;
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
180 Size aSize
= _aIntroBmp
.GetSizePixel();
181 SetOutputSizePixel( aSize
);
182 _vdev
.SetOutputSizePixel( aSize
);
183 _height
= aSize
.Height();
184 _width
= aSize
.Width();
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
)
195 if ( NOT_LOADED
== _barheight
)
197 if (( _eBitmapMode
== BM_FULLSCREEN
) &&
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
);
213 if ( NOT_LOADED
== _barwidth
)
214 _barwidth
= _width
- (2 * _xoffset
);
215 if ( NOT_LOADED
== _barheight
)
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
233 _cProgressBarColor
= Color( 157, 202, 18 );
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;
251 //_bPaintBitmap=sal_True;
255 // internal private methods
256 IMPL_LINK( SplashScreen
, AppEventListenerHdl
, VclWindowEvent
*, inEvent
)
260 // Paint( Rectangle() );
261 switch ( inEvent
->GetId() )
263 case VCLEVENT_WINDOW_SHOW
:
264 Paint( Rectangle() );
273 // Read keys from edition/edition.ini or soffice{.ini|rc}:
274 OUString
implReadBootstrapKey( const OUString
& _rKey
)
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
);
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() )
317 sal_Int32 temp
= sProgressFrameColor
.getToken( 0, ',', idx
).toInt32();
320 nRed
= static_cast< UINT8
>( temp
);
321 temp
= sProgressFrameColor
.getToken( 0, ',', idx
).toInt32();
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() )
337 sal_Int32 temp
= sProgressBarColor
.getToken( 0, ',', idx
).toInt32();
340 nRed
= static_cast< UINT8
>( temp
);
341 temp
= sProgressBarColor
.getToken( 0, ',', idx
).toInt32();
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() )
354 sal_Int32 temp
= sSize
.getToken( 0, ',', idx
).toInt32();
358 _barheight
= sSize
.getToken( 0, ',', idx
).toInt32();
362 if ( _barheight
>= 10 )
363 _barspace
= 3; // more space between frame and bar
365 if ( sPosition
.getLength() )
368 sal_Int32 temp
= sPosition
.getToken( 0, ',', idx
).toInt32();
372 _tly
= sPosition
.getToken( 0, ',', idx
).toInt32();
377 void SplashScreen::initBitmap()
381 OUString sExecutePath
;
382 ::rtl::Bootstrap::get(
383 OUString( RTL_CONSTASCII_USTRINGPARAM( "BRAND_BASE_DIR" ) ),
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 ) );
399 rtl::OUString
edition(
401 RTL_CONSTASCII_USTRINGPARAM(
402 "${BRAND_BASE_DIR}/program/edition")));
403 rtl::Bootstrap::expandMacros(edition
);
404 haveBitmap
= findBitmap(edition
);
407 findBitmap(sExecutePath
);
412 bool SplashScreen::loadBitmap(
413 rtl::OUString
const & path
, const rtl::OUString
&rBmpFileName
)
415 if ( rBmpFileName
.getLength() == 0 )
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)
433 bool SplashScreen::findBitmap(rtl::OUString
const & path
) {
434 bool haveBitmap
= false;
435 if ( _bFullScreenSplash
)
437 haveBitmap
= findScreenBitmap(path
);
439 _eBitmapMode
= BM_FULLSCREEN
;
441 haveBitmap
= findAppBitmap(path
);
444 haveBitmap
= loadBitmap(
445 path
, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("intro.bmp")));
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();
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
);
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
);
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
);
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();
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() )
557 double temp
= sFullScreenProgressPos
.getToken( 0, ',', idx
).toDouble();
561 rYRelPos
= sFullScreenProgressPos
.getToken( 0, ',', idx
).toDouble();
565 if ( sFullScreenProgressSize
.getLength() )
568 double temp
= sFullScreenProgressSize
.getToken( 0, ',', idx
).toDouble();
572 rRelHeight
= sFullScreenProgressSize
.getToken( 0, ',', idx
).toDouble();
582 void SplashScreen::Paint( const Rectangle
&)
584 if(!_bVisible
) return;
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
)
618 _vdev
.DrawBitmap( Point(), _aIntroBmp
);
620 if (_bPaintProgress
) {
622 long length
= (_iProgress
* _barwidth
/ _iMax
) - (2 * _barspace
);
623 if (length
< 0) length
= 0;
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();
639 //_vdev.DrawOutDev(Point(), GetOutputSize(), Point(), GetOutputSize(), *((IntroWindow*)this) );
640 DrawOutDev(Point(), GetOutputSizePixel(), Point(), _vdev
.GetOutputSizePixel(), _vdev
);
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
);
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",
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
};