1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
23 #include <unotools/bootstrap.hxx>
24 #include <tools/stream.hxx>
25 #include <vcl/svapp.hxx>
26 #include <vcl/salnativewidgets.hxx>
28 #include <com/sun/star/lang/XInitialization.hpp>
29 #include <com/sun/star/registry/XRegistryKey.hpp>
30 #include <com/sun/star/task/XStatusIndicator.hpp>
31 #include <cppuhelper/implbase2.hxx>
32 #include <rtl/bootstrap.hxx>
33 #include <rtl/logfile.hxx>
34 #include <rtl/strbuf.hxx>
35 #include <rtl/math.hxx>
36 #include <vcl/introwin.hxx>
37 #include <vcl/virdev.hxx>
39 #define NOT_LOADED ((long)-1)
41 using namespace ::rtl
;
42 using namespace ::com::sun::star::lang
;
43 using namespace ::com::sun::star::registry
;
44 using namespace ::com::sun::star::task
;
45 using namespace ::com::sun::star::uno
;
50 : public ::cppu::WeakImplHelper2
< XStatusIndicator
, XInitialization
>
54 enum BitmapMode
{ BM_FULLSCREEN
, BM_DEFAULTMODE
};
56 DECL_LINK( AppEventListenerHdl
, VclWindowEvent
* );
57 virtual ~SplashScreen();
60 void SetScreenBitmap(BitmapEx
&rBitmap
);
61 void determineProgressRatioValues( double& rXRelPos
, double& rYRelPos
, double& rRelWidth
, double& rRelHeight
);
63 static osl::Mutex _aMutex
;
67 Color _cProgressFrameColor
;
68 Color _cProgressBarColor
;
69 Color _cProgressTextColor
;
70 bool _bNativeProgress
;
72 OUString _sProgressText
;
76 BitmapMode _eBitmapMode
;
77 sal_Bool _bPaintBitmap
;
78 sal_Bool _bPaintProgress
;
81 sal_Bool _bFullScreenSplash
;
82 sal_Bool _bProgressEnd
;
83 long _height
, _width
, _tlx
, _tly
, _barwidth
;
84 long _barheight
, _barspace
, _textBaseline
;
85 double _fXPos
, _fYPos
;
86 double _fWidth
, _fHeight
;
87 const long _xoffset
, _yoffset
;
93 virtual void SAL_CALL
end() throw ( RuntimeException
);
94 virtual void SAL_CALL
reset() throw ( RuntimeException
);
95 virtual void SAL_CALL
setText(const OUString
& aText
) throw ( RuntimeException
);
96 virtual void SAL_CALL
setValue(sal_Int32 nValue
) throw ( RuntimeException
);
97 virtual void SAL_CALL
start(const OUString
& aText
, sal_Int32 nRange
) throw ( RuntimeException
);
100 virtual void SAL_CALL
initialize( const ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Any
>& aArguments
)
101 throw ( RuntimeException
);
104 virtual void Paint( const Rectangle
& );
108 SplashScreen::SplashScreen()
110 , _vdev(*((IntroWindow
*)this))
111 , _cProgressFrameColor(sal::static_int_cast
< ColorData
>(NOT_LOADED
))
112 , _cProgressBarColor(sal::static_int_cast
< ColorData
>(NOT_LOADED
))
113 , _cProgressTextColor(sal::static_int_cast
< ColorData
>(NOT_LOADED
))
114 , _bNativeProgress(true)
117 , _eBitmapMode(BM_DEFAULTMODE
)
118 , _bPaintBitmap(sal_True
)
119 , _bPaintProgress(sal_False
)
120 , _bShowLogo(sal_True
)
121 , _bFullScreenSplash(sal_False
)
122 , _bProgressEnd(sal_False
)
125 , _barwidth(NOT_LOADED
)
126 , _barheight(NOT_LOADED
)
128 , _textBaseline(NOT_LOADED
)
137 _vdev
.EnableRTL(IsRTLEnabled());
140 SplashScreen::~SplashScreen()
142 Application::RemoveEventListener(
143 LINK( this, SplashScreen
, AppEventListenerHdl
) );
148 void SAL_CALL
SplashScreen::start(const OUString
&, sal_Int32 nRange
)
149 throw (RuntimeException
)
153 _bProgressEnd
= sal_False
;
154 SolarMutexGuard aSolarGuard
;
155 if ( _eBitmapMode
== BM_FULLSCREEN
)
156 ShowFullScreenMode( sal_True
);
163 void SAL_CALL
SplashScreen::end()
164 throw (RuntimeException
)
169 if ( _eBitmapMode
== BM_FULLSCREEN
)
173 _bProgressEnd
= sal_True
;
176 void SAL_CALL
SplashScreen::reset()
177 throw (RuntimeException
)
180 if (_bVisible
&& !_bProgressEnd
)
182 if ( _eBitmapMode
== BM_FULLSCREEN
)
183 ShowFullScreenMode( sal_True
);
189 void SAL_CALL
SplashScreen::setText(const OUString
& rText
)
190 throw (RuntimeException
)
192 SolarMutexGuard aSolarGuard
;
193 if ( _sProgressText
!= rText
)
195 _sProgressText
= rText
;
197 if (_bVisible
&& !_bProgressEnd
)
199 if ( _eBitmapMode
== BM_FULLSCREEN
)
200 ShowFullScreenMode( sal_True
);
207 void SAL_CALL
SplashScreen::setValue(sal_Int32 nValue
)
208 throw (RuntimeException
)
210 RTL_LOGFILE_CONTEXT( aLog
, "::SplashScreen::setValue (lo119109)" );
211 RTL_LOGFILE_CONTEXT_TRACE1( aLog
, "value=%d", nValue
);
213 SolarMutexGuard aSolarGuard
;
214 if (_bVisible
&& !_bProgressEnd
) {
215 if ( _eBitmapMode
== BM_FULLSCREEN
)
216 ShowFullScreenMode( sal_True
);
218 if (nValue
>= _iMax
) _iProgress
= _iMax
;
219 else _iProgress
= nValue
;
226 SplashScreen::initialize( const ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Any
>& aArguments
)
227 throw (RuntimeException
)
229 ::osl::ClearableMutexGuard
aGuard( _aMutex
);
230 if (aArguments
.getLength() > 0)
232 aArguments
[0] >>= _bVisible
;
233 if (aArguments
.getLength() > 1 )
234 aArguments
[1] >>= _sAppName
;
236 // start to determine bitmap and all other required value
238 SetScreenBitmap (_aIntroBmp
);
239 Size aSize
= _aIntroBmp
.GetSizePixel();
240 SetOutputSizePixel( aSize
);
241 _vdev
.SetOutputSizePixel( aSize
);
242 _height
= aSize
.Height();
243 _width
= aSize
.Width();
246 Point
xtopleft(212,216);
247 if ( NOT_LOADED
== _tlx
|| NOT_LOADED
== _tly
)
249 _tlx
= xtopleft
.X(); // top-left x
250 _tly
= xtopleft
.Y(); // top-left y
252 if ( NOT_LOADED
== _barwidth
)
254 if ( NOT_LOADED
== _barheight
)
256 if (( _eBitmapMode
== BM_FULLSCREEN
) &&
259 if( ( _fXPos
>= 0.0 ) && ( _fYPos
>= 0.0 ))
261 _tlx
= sal_Int32( double( aSize
.Width() ) * _fXPos
);
262 _tly
= sal_Int32( double( aSize
.Height() ) * _fYPos
);
264 if ( _fWidth
>= 0.0 )
265 _barwidth
= sal_Int32( double( aSize
.Width() ) * _fWidth
);
266 if ( _fHeight
>= 0.0 )
267 _barheight
= sal_Int32( double( aSize
.Width() ) * _fHeight
);
272 if ( NOT_LOADED
== _barwidth
)
273 _barwidth
= _width
- (2 * _xoffset
);
274 if ( NOT_LOADED
== _barheight
)
276 if ( NOT_LOADED
== _tlx
|| NOT_LOADED
== _tly
)
278 _tlx
= _xoffset
; // top-left x
279 _tly
= _height
- _yoffset
; // top-left y
283 if ( NOT_LOADED
== _textBaseline
)
284 _textBaseline
= _height
;
286 if ( sal::static_int_cast
< ColorData
>(NOT_LOADED
) ==
287 _cProgressFrameColor
.GetColor() )
288 _cProgressFrameColor
= Color( COL_LIGHTGRAY
);
290 if ( sal::static_int_cast
< ColorData
>(NOT_LOADED
) ==
291 _cProgressBarColor
.GetColor() )
293 // progress bar: new color only for big bitmap format
295 _cProgressBarColor
= Color( 157, 202, 18 );
297 _cProgressBarColor
= Color( COL_BLUE
);
300 if ( sal::static_int_cast
< ColorData
>(NOT_LOADED
) ==
301 _cProgressTextColor
.GetColor() )
302 _cProgressTextColor
= Color( COL_BLACK
);
304 Application::AddEventListener(
305 LINK( this, SplashScreen
, AppEventListenerHdl
) );
309 void SplashScreen::updateStatus()
311 if (!_bVisible
|| _bProgressEnd
) return;
312 if (!_bPaintProgress
) _bPaintProgress
= sal_True
;
317 // internal private methods
318 IMPL_LINK( SplashScreen
, AppEventListenerHdl
, VclWindowEvent
*, inEvent
)
322 switch ( inEvent
->GetId() )
324 case VCLEVENT_WINDOW_SHOW
:
325 Paint( Rectangle() );
334 // Read keys from soffice{.ini|rc}:
335 OUString
implReadBootstrapKey( const OUString
& _rKey
)
338 rtl::Bootstrap::get(_rKey
, sValue
);
342 void SplashScreen::loadConfig()
344 _bShowLogo
= implReadBootstrapKey( "Logo" ) != "0";
346 OUString sProgressFrameColor
= implReadBootstrapKey( "ProgressFrameColor" );
347 OUString sProgressBarColor
= implReadBootstrapKey( "ProgressBarColor" );
348 OUString sProgressTextColor
= implReadBootstrapKey( "ProgressTextColor" );
349 OUString sProgressTextBaseline
= implReadBootstrapKey( "ProgressTextBaseline" );
350 OUString sSize
= implReadBootstrapKey( "ProgressSize" );
351 OUString sPosition
= implReadBootstrapKey( "ProgressPosition" );
352 OUString sFullScreenSplash
= implReadBootstrapKey( "FullScreenSplash" );
353 OUString sNativeProgress
= implReadBootstrapKey( "NativeProgress" );
356 // Determine full screen splash mode
357 _bFullScreenSplash
= (( !sFullScreenSplash
.isEmpty() ) &&
358 ( !sFullScreenSplash
.equals( "0" )));
360 // Try to retrieve the relative values for the progress bar. The current
361 // schema uses the screen ratio to retrieve the associated values.
362 if ( _bFullScreenSplash
)
363 determineProgressRatioValues( _fXPos
, _fYPos
, _fWidth
, _fHeight
);
365 if ( !sProgressFrameColor
.isEmpty() )
369 sal_Int32 temp
= sProgressFrameColor
.getToken( 0, ',', idx
).toInt32();
372 nRed
= static_cast< sal_uInt8
>( temp
);
373 temp
= sProgressFrameColor
.getToken( 0, ',', idx
).toInt32();
377 sal_uInt8 nGreen
= static_cast< sal_uInt8
>( temp
);
378 sal_uInt8 nBlue
= static_cast< sal_uInt8
>( sProgressFrameColor
.getToken( 0, ',', idx
).toInt32() );
379 _cProgressFrameColor
= Color( nRed
, nGreen
, nBlue
);
383 if ( !sProgressBarColor
.isEmpty() )
387 sal_Int32 temp
= sProgressBarColor
.getToken( 0, ',', idx
).toInt32();
390 nRed
= static_cast< sal_uInt8
>( temp
);
391 temp
= sProgressBarColor
.getToken( 0, ',', idx
).toInt32();
395 sal_uInt8 nGreen
= static_cast< sal_uInt8
>( temp
);
396 sal_uInt8 nBlue
= static_cast< sal_uInt8
>( sProgressBarColor
.getToken( 0, ',', idx
).toInt32() );
397 _cProgressBarColor
= Color( nRed
, nGreen
, nBlue
);
401 if ( !sProgressTextColor
.isEmpty() )
405 sal_Int32 temp
= sProgressTextColor
.getToken( 0, ',', idx
).toInt32();
408 nRed
= static_cast< sal_uInt8
>( temp
);
409 temp
= sProgressTextColor
.getToken( 0, ',', idx
).toInt32();
413 sal_uInt8 nGreen
= static_cast< sal_uInt8
>( temp
);
414 sal_uInt8 nBlue
= static_cast< sal_uInt8
>( sProgressTextColor
.getToken( 0, ',', idx
).toInt32() );
415 _cProgressTextColor
= Color( nRed
, nGreen
, nBlue
);
419 if ( !sProgressTextBaseline
.isEmpty() )
421 _textBaseline
= sProgressTextBaseline
.toInt32();
424 if( !sNativeProgress
.isEmpty() )
426 _bNativeProgress
= sNativeProgress
.toBoolean();
429 if ( !sSize
.isEmpty() )
432 sal_Int32 temp
= sSize
.getToken( 0, ',', idx
).toInt32();
436 _barheight
= sSize
.getToken( 0, ',', idx
).toInt32();
440 if ( _barheight
>= 10 )
441 _barspace
= 3; // more space between frame and bar
443 if ( !sPosition
.isEmpty() )
446 sal_Int32 temp
= sPosition
.getToken( 0, ',', idx
).toInt32();
450 _tly
= sPosition
.getToken( 0, ',', idx
).toInt32();
455 void SplashScreen::SetScreenBitmap(BitmapEx
&rBitmap
)
457 sal_Int32
nWidth( 0 );
458 sal_Int32
nHeight( 0 );
460 // determine desktop resolution
461 sal_uInt32 nCount
= Application::GetScreenCount();
464 // retrieve size from first screen
465 Rectangle aScreenArea
= Application::GetScreenPosSizePixel((unsigned int)0);
466 nWidth
= aScreenArea
.GetWidth();
467 nHeight
= aScreenArea
.GetHeight();
470 // create file name from screen resolution information
471 OStringBuffer
aStrBuf( 128 );
472 OStringBuffer
aResBuf( 32 );
473 aStrBuf
.append( "intro_" );
474 if ( !_sAppName
.isEmpty() )
476 aStrBuf
.append( OUStringToOString(_sAppName
, RTL_TEXTENCODING_UTF8
) );
477 aStrBuf
.append( "_" );
479 aResBuf
.append( OString::valueOf( nWidth
));
480 aResBuf
.append( "x" );
481 aResBuf
.append( OString::valueOf( nHeight
));
483 aStrBuf
.append( aResBuf
.getStr() );
484 if (Application::LoadBrandBitmap (aStrBuf
.makeStringAndClear().getStr(), rBitmap
))
487 aStrBuf
.append( "intro_" );
488 aStrBuf
.append( aResBuf
.getStr() );
489 if (Application::LoadBrandBitmap (aResBuf
.makeStringAndClear().getStr(), rBitmap
))
492 Application::LoadBrandBitmap ("intro", rBitmap
);
495 void SplashScreen::determineProgressRatioValues(
496 double& rXRelPos
, double& rYRelPos
,
497 double& rRelWidth
, double& rRelHeight
)
499 sal_Int32
nWidth( 0 );
500 sal_Int32
nHeight( 0 );
501 sal_Int32
nScreenRatio( 0 );
503 // determine desktop resolution
504 sal_uInt32 nCount
= Application::GetScreenCount();
507 // retrieve size from first screen
508 Rectangle aScreenArea
= Application::GetScreenPosSizePixel((unsigned int)0);
509 nWidth
= aScreenArea
.GetWidth();
510 nHeight
= aScreenArea
.GetHeight();
511 nScreenRatio
= sal_Int32( math::round( double( nWidth
) / double( nHeight
), 2 ) * 100 );
514 char szFullScreenProgressRatio
[] = "FullScreenProgressRatio0";
515 char szFullScreenProgressPos
[] = "FullScreenProgressPos0";
516 char szFullScreenProgressSize
[] = "FullScreenProgressSize0";
517 for ( sal_Int32 i
= 0; i
<= 9; i
++ )
519 char cNum
= '0' + char( i
);
520 szFullScreenProgressRatio
[23] = cNum
;
521 szFullScreenProgressPos
[21] = cNum
;
522 szFullScreenProgressSize
[22] = cNum
;
524 OUString sFullScreenProgressRatio
= implReadBootstrapKey(
525 OUString::createFromAscii( szFullScreenProgressRatio
) );
527 if ( !sFullScreenProgressRatio
.isEmpty() )
529 double fRatio
= sFullScreenProgressRatio
.toDouble();
530 sal_Int32 nRatio
= sal_Int32( math::round( fRatio
, 2 ) * 100 );
531 if ( nRatio
== nScreenRatio
)
533 OUString sFullScreenProgressPos
= implReadBootstrapKey(
534 OUString::createFromAscii( szFullScreenProgressPos
) );
535 OUString sFullScreenProgressSize
= implReadBootstrapKey(
536 OUString::createFromAscii( szFullScreenProgressSize
) );
538 if ( !sFullScreenProgressPos
.isEmpty() )
541 double temp
= sFullScreenProgressPos
.getToken( 0, ',', idx
).toDouble();
545 rYRelPos
= sFullScreenProgressPos
.getToken( 0, ',', idx
).toDouble();
549 if ( !sFullScreenProgressSize
.isEmpty() )
552 double temp
= sFullScreenProgressSize
.getToken( 0, ',', idx
).toDouble();
556 rRelHeight
= sFullScreenProgressSize
.getToken( 0, ',', idx
).toDouble();
566 void SplashScreen::Paint( const Rectangle
&)
568 if(!_bVisible
) return;
571 sal_Bool bNativeOK
= sal_False
;
573 // in case of native controls we need to draw directly to the window
574 if( _bNativeProgress
&& IsNativeControlSupported( CTRL_INTROPROGRESS
, PART_ENTIRE_CONTROL
) )
576 DrawBitmapEx( Point(), _aIntroBmp
);
578 ImplControlValue
aValue( _iProgress
* _barwidth
/ _iMax
);
579 Rectangle
aDrawRect( Point(_tlx
, _tly
), Size( _barwidth
, _barheight
) );
580 Rectangle aNativeControlRegion
, aNativeContentRegion
;
582 if( GetNativeControlRegion( CTRL_INTROPROGRESS
, PART_ENTIRE_CONTROL
, aDrawRect
,
583 CTRL_STATE_ENABLED
, aValue
, OUString(),
584 aNativeControlRegion
, aNativeContentRegion
) )
586 long nProgressHeight
= aNativeControlRegion
.GetHeight();
587 aDrawRect
.Top() -= (nProgressHeight
- _barheight
)/2;
588 aDrawRect
.Bottom() += (nProgressHeight
- _barheight
)/2;
591 if( (bNativeOK
= DrawNativeControl( CTRL_INTROPROGRESS
, PART_ENTIRE_CONTROL
, aDrawRect
,
592 CTRL_STATE_ENABLED
, aValue
, _sProgressText
)) != sal_False
)
600 _vdev
.DrawBitmapEx( Point(), _aIntroBmp
);
602 if (_bPaintProgress
) {
604 long length
= (_iProgress
* _barwidth
/ _iMax
) - (2 * _barspace
);
605 if (length
< 0) length
= 0;
608 _vdev
.SetFillColor();
609 _vdev
.SetLineColor( _cProgressFrameColor
);
610 _vdev
.DrawRect(Rectangle(_tlx
, _tly
, _tlx
+_barwidth
, _tly
+_barheight
));
611 _vdev
.SetFillColor( _cProgressBarColor
);
612 _vdev
.SetLineColor();
613 _vdev
.DrawRect(Rectangle(_tlx
+_barspace
, _tly
+_barspace
, _tlx
+_barspace
+length
, _tly
+_barheight
-_barspace
));
615 aFont
.SetSize(Size(0, 12));
616 aFont
.SetAlign(ALIGN_BASELINE
);
617 _vdev
.SetFont(aFont
);
618 _vdev
.SetTextColor(_cProgressTextColor
);
619 _vdev
.DrawText(Point(_tlx
, _textBaseline
), _sProgressText
);
621 DrawOutDev(Point(), GetOutputSizePixel(), Point(), _vdev
.GetOutputSizePixel(), _vdev
);
625 // get service instance...
626 osl::Mutex
SplashScreen::_aMutex
;
630 css::uno::Reference
< css::uno::XInterface
> desktop::splash::create(
631 css::uno::Reference
< css::uno::XComponentContext
> const &)
633 return static_cast< cppu::OWeakObject
* >(new SplashScreen
);
636 OUString
desktop::splash::getImplementationName() {
637 return OUString("com.sun.star.office.comp.SplashScreen");
640 css::uno::Sequence
< OUString
> desktop::splash::getSupportedServiceNames() {
641 OUString
name("com.sun.star.office.SplashScreen");
642 return css::uno::Sequence
< OUString
>(&name
, 1);
645 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */