splash: de-confuse mixed VCL and UNO reference counting.
Change-Id: I1c8ded2e5c5e8072111d3e1480ba7086db135810
diff --git a/desktop/source/splash/splash.cxx b/desktop/source/splash/splash.cxx
index cb1ed36..cb1630a 100644
--- a/desktop/source/splash/splash.cxx
+++ b/desktop/source/splash/splash.cxx
@@ -46,16 +46,31 @@ using namespace ::com::sun::star::uno;
namespace {
class SplashScreen;
class SplashScreenWindow : public IntroWindow
{
public:
SplashScreen *pSpl;
ScopedVclPtr<VirtualDevice> _vdev;
SplashScreenWindow(SplashScreen *);
virtual ~SplashScreenWindow() { disposeOnce(); }
virtual void dispose() SAL_OVERRIDE;
// workwindow
virtual void Paint( const Rectangle& ) SAL_OVERRIDE;
};
class SplashScreen
: public ::cppu::WeakImplHelper3< XStatusIndicator, XInitialization, XServiceInfo >
, public IntroWindow
{
friend SplashScreenWindow;
private:
enum BitmapMode { BM_FULLSCREEN, BM_DEFAULTMODE };
VclPtr<SplashScreenWindow> pWindow;
DECL_LINK( AppEventListenerHdl, VclWindowEvent * );
virtual ~SplashScreen();
virtual void dispose() SAL_OVERRIDE;
void loadConfig();
void updateStatus();
void SetScreenBitmap(BitmapEx &rBitmap);
@@ -63,7 +78,6 @@ private:
static osl::Mutex _aMutex;
ScopedVclPtr<VirtualDevice> _vdev;
BitmapEx _aIntroBmp;
Color _cProgressFrameColor;
Color _cProgressBarColor;
@@ -112,15 +126,24 @@ public:
virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames()
throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
{ return desktop::splash::getSupportedServiceNames(); }
// workwindow
virtual void Paint( const Rectangle& ) SAL_OVERRIDE;
};
SplashScreen::SplashScreen()
SplashScreenWindow::SplashScreenWindow(SplashScreen *pSplash)
: IntroWindow()
, _vdev(new VirtualDevice(*((IntroWindow*)this)))
, pSpl( pSplash )
, _vdev(new VirtualDevice(*this))
{
_vdev->EnableRTL(IsRTLEnabled());
}
void SplashScreenWindow::dispose()
{
pSpl = NULL;
IntroWindow::dispose();
}
SplashScreen::SplashScreen()
: pWindow( new SplashScreenWindow (this) )
, _cProgressFrameColor(sal::static_int_cast< ColorData >(NOT_LOADED))
, _cProgressBarColor(sal::static_int_cast< ColorData >(NOT_LOADED))
, _cProgressTextColor(sal::static_int_cast< ColorData >(NOT_LOADED))
@@ -150,20 +173,14 @@ SplashScreen::SplashScreen()
, _yoffset(18)
{
loadConfig();
_vdev->EnableRTL(IsRTLEnabled());
}
SplashScreen::~SplashScreen()
{
disposeOnce();
}
void SplashScreen::dispose()
{
Application::RemoveEventListener(
LINK( this, SplashScreen, AppEventListenerHdl ) );
Hide();
IntroWindow::dispose();
pWindow->Hide();
pWindow.disposeAndClear();
}
void SAL_CALL SplashScreen::start(const OUString&, sal_Int32 nRange)
@@ -174,10 +191,10 @@ void SAL_CALL SplashScreen::start(const OUString&, sal_Int32 nRange)
_bProgressEnd = false;
SolarMutexGuard aSolarGuard;
if ( _eBitmapMode == BM_FULLSCREEN )
ShowFullScreenMode( true );
Show();
Paint(Rectangle());
Flush();
pWindow->ShowFullScreenMode( true );
pWindow->Show();
pWindow->Paint(Rectangle());
pWindow->Flush();
}
}
@@ -188,8 +205,8 @@ void SAL_CALL SplashScreen::end()
if (_bVisible )
{
if ( _eBitmapMode == BM_FULLSCREEN )
EndFullScreenMode();
Hide();
pWindow->EndFullScreenMode();
pWindow->Hide();
}
_bProgressEnd = true;
}
@@ -201,8 +218,8 @@ void SAL_CALL SplashScreen::reset()
if (_bVisible && !_bProgressEnd )
{
if ( _eBitmapMode == BM_FULLSCREEN )
ShowFullScreenMode( true );
Show();
pWindow->ShowFullScreenMode( true );
pWindow->Show();
updateStatus();
}
}
@@ -218,8 +235,8 @@ void SAL_CALL SplashScreen::setText(const OUString& rText)
if (_bVisible && !_bProgressEnd)
{
if ( _eBitmapMode == BM_FULLSCREEN )
ShowFullScreenMode( true );
Show();
pWindow->ShowFullScreenMode( true );
pWindow->Show();
updateStatus();
}
}
@@ -233,11 +250,13 @@ void SAL_CALL SplashScreen::setValue(sal_Int32 nValue)
SolarMutexGuard aSolarGuard;
if (_bVisible && !_bProgressEnd) {
if ( _eBitmapMode == BM_FULLSCREEN )
ShowFullScreenMode( true );
Show();
if (nValue >= _iMax) _iProgress = _iMax;
else _iProgress = nValue;
updateStatus();
pWindow->ShowFullScreenMode( true );
pWindow->Show();
if (nValue >= _iMax)
_iProgress = _iMax;
else
_iProgress = nValue;
updateStatus();
}
}
@@ -257,8 +276,8 @@ SplashScreen::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::sta
if ( _bShowLogo )
SetScreenBitmap (_aIntroBmp);
Size aSize = _aIntroBmp.GetSizePixel();
SetOutputSizePixel( aSize );
_vdev->SetOutputSizePixel( aSize );
pWindow->SetOutputSizePixel( aSize );
pWindow->_vdev->SetOutputSizePixel( aSize );
_height = aSize.Height();
_width = aSize.Width();
if (_width > 500)
@@ -328,10 +347,12 @@ SplashScreen::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::sta
void SplashScreen::updateStatus()
{
if (!_bVisible || _bProgressEnd) return;
if (!_bPaintProgress) _bPaintProgress = true;
Paint(Rectangle());
Flush();
if (!_bVisible || _bProgressEnd)
return;
if (!_bPaintProgress)
_bPaintProgress = true;
pWindow->Paint(Rectangle());
pWindow->Flush();
}
// internal private methods
@@ -342,7 +363,7 @@ IMPL_LINK( SplashScreen, AppEventListenerHdl, VclWindowEvent *, inEvent )
switch ( inEvent->GetId() )
{
case VCLEVENT_WINDOW_SHOW:
Paint( Rectangle() );
pWindow->Paint( Rectangle() );
break;
default:
break;
@@ -583,18 +604,19 @@ void SplashScreen::determineProgressRatioValues(
}
}
void SplashScreen::Paint( const Rectangle&)
void SplashScreenWindow::Paint( const Rectangle&)
{
if(!_bVisible) return;
if (!pSpl || !pSpl->_bVisible)
return;
//native drawing
// in case of native controls we need to draw directly to the window
if( _bNativeProgress && IsNativeControlSupported( CTRL_INTROPROGRESS, PART_ENTIRE_CONTROL ) )
if( pSpl->_bNativeProgress && IsNativeControlSupported( CTRL_INTROPROGRESS, PART_ENTIRE_CONTROL ) )
{
DrawBitmapEx( Point(), _aIntroBmp );
DrawBitmapEx( Point(), pSpl->_aIntroBmp );
ImplControlValue aValue( _iProgress * _barwidth / _iMax);
Rectangle aDrawRect( Point(_tlx, _tly), Size( _barwidth, _barheight ) );
ImplControlValue aValue( pSpl->_iProgress * pSpl->_barwidth / pSpl->_iMax);
Rectangle aDrawRect( Point(pSpl->_tlx, pSpl->_tly), Size( pSpl->_barwidth, pSpl->_barheight ) );
Rectangle aNativeControlRegion, aNativeContentRegion;
if( GetNativeControlRegion( CTRL_INTROPROGRESS, PART_ENTIRE_CONTROL, aDrawRect,
@@ -602,39 +624,40 @@ void SplashScreen::Paint( const Rectangle&)
aNativeControlRegion, aNativeContentRegion ) )
{
long nProgressHeight = aNativeControlRegion.GetHeight();
aDrawRect.Top() -= (nProgressHeight - _barheight)/2;
aDrawRect.Bottom() += (nProgressHeight - _barheight)/2;
aDrawRect.Top() -= (nProgressHeight - pSpl->_barheight)/2;
aDrawRect.Bottom() += (nProgressHeight - pSpl->_barheight)/2;
}
if( (DrawNativeControl( CTRL_INTROPROGRESS, PART_ENTIRE_CONTROL, aDrawRect,
ControlState::ENABLED, aValue, _sProgressText )) )
ControlState::ENABLED, aValue, _sProgressText )) )
{
return;
}
}
//non native drawing
// draw bitmap
if (_bPaintBitmap)
_vdev->DrawBitmapEx( Point(), _aIntroBmp );
if (_bPaintProgress) {
// non native drawing
// draw bitmap
if (pSpl->_bPaintBitmap)
_vdev->DrawBitmapEx( Point(), pSpl->_aIntroBmp );
if (pSpl->_bPaintProgress) {
// draw progress...
long length = (_iProgress * _barwidth / _iMax) - (2 * _barspace);
long length = (pSpl->_iProgress * pSpl->_barwidth / pSpl->_iMax) - (2 * pSpl->_barspace);
if (length < 0) length = 0;
// border
_vdev->SetFillColor();
_vdev->SetLineColor( _cProgressFrameColor );
_vdev->DrawRect(Rectangle(_tlx, _tly, _tlx+_barwidth, _tly+_barheight));
_vdev->SetFillColor( _cProgressBarColor );
_vdev->SetLineColor( pSpl->_cProgressFrameColor );
_vdev->DrawRect(Rectangle(pSpl->_tlx, pSpl->_tly, pSpl->_tlx+pSpl->_barwidth, pSpl->_tly+pSpl->_barheight));
_vdev->SetFillColor( pSpl->_cProgressBarColor );
_vdev->SetLineColor();
_vdev->DrawRect(Rectangle(_tlx+_barspace, _tly+_barspace, _tlx+_barspace+length, _tly+_barheight-_barspace));
_vdev->DrawRect(Rectangle(pSpl->_tlx+pSpl->_barspace, pSpl->_tly+pSpl->_barspace, pSpl->_tlx+pSpl->_barspace+length, pSpl->_tly+pSpl->_barheight-pSpl->_barspace));
vcl::Font aFont;
aFont.SetSize(Size(0, 12));
aFont.SetAlign(ALIGN_BASELINE);
_vdev->SetFont(aFont);
_vdev->SetTextColor(_cProgressTextColor);
_vdev->DrawText(Point(_tlx, _textBaseline), _sProgressText);
_vdev->SetTextColor(pSpl->_cProgressTextColor);
_vdev->DrawText(Point(pSpl->_tlx, pSpl->_textBaseline), pSpl->_sProgressText);
}
DrawOutDev(Point(), GetOutputSizePixel(), Point(), _vdev->GetOutputSizePixel(), *_vdev.get() );
}