549 lines
21 KiB
C++
549 lines
21 KiB
C++
/*************************************************************************
|
|
*
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* Copyright 2008 by Sun Microsystems, Inc.
|
|
*
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
*
|
|
* $RCSfile: viewmediashape.cxx,v $
|
|
* $Revision: 1.6.2.1 $
|
|
*
|
|
* This file is part of OpenOffice.org.
|
|
*
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
* only, as published by the Free Software Foundation.
|
|
*
|
|
* OpenOffice.org is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License version 3 for more details
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
* <http://www.openoffice.org/license.html>
|
|
* for a copy of the LGPLv3 License.
|
|
*
|
|
************************************************************************/
|
|
|
|
// MARKER(update_precomp.py): autogen include statement, do not remove
|
|
#include "precompiled_slideshow.hxx"
|
|
|
|
// must be first
|
|
#include <canvas/debug.hxx>
|
|
#include <tools/diagnose_ex.h>
|
|
#include <canvas/verbosetrace.hxx>
|
|
|
|
#include <math.h>
|
|
|
|
#include <comphelper/anytostring.hxx>
|
|
#include <cppuhelper/exc_hlp.hxx>
|
|
|
|
#include <vcl/window.hxx>
|
|
#include <vcl/javachild.hxx>
|
|
#include <vcl/salbtype.hxx>
|
|
|
|
#include <basegfx/tools/canvastools.hxx>
|
|
#include <basegfx/numeric/ftools.hxx>
|
|
#include <basegfx/polygon/b2dpolygon.hxx>
|
|
#include <basegfx/point/b2dpoint.hxx>
|
|
#include <basegfx/matrix/b2dhommatrix.hxx>
|
|
#include <basegfx/polygon/b2dpolygontools.hxx>
|
|
#include <basegfx/range/b2irange.hxx>
|
|
#include <canvas/canvastools.hxx>
|
|
#include <cppcanvas/vclfactory.hxx>
|
|
#include <cppcanvas/basegfxfactory.hxx>
|
|
#include <cppcanvas/basegfxfactory.hxx>
|
|
#include <avmedia/mediawindow.hxx>
|
|
|
|
#include <com/sun/star/media/XManager.hpp>
|
|
#include <com/sun/star/media/XPlayer.hpp>
|
|
#include <com/sun/star/media/XPlayerWindow.hpp>
|
|
#include <com/sun/star/beans/XPropertySet.hpp>
|
|
#include <com/sun/star/lang/XMultiComponentFactory.hpp>
|
|
#include <com/sun/star/lang/NoSupportException.hpp>
|
|
#include <com/sun/star/awt/XWindow.hpp>
|
|
#include <com/sun/star/rendering/XCanvas.hpp>
|
|
#include <com/sun/star/lang/XComponent.hdl>
|
|
|
|
#include "viewmediashape.hxx"
|
|
#include "mediashape.hxx"
|
|
#include "tools.hxx"
|
|
#include "unoview.hxx"
|
|
|
|
using namespace ::com::sun::star;
|
|
|
|
namespace slideshow
|
|
{
|
|
namespace internal
|
|
{
|
|
ViewMediaShape::ViewMediaShape( const ViewLayerSharedPtr& rViewLayer,
|
|
const uno::Reference< drawing::XShape >& rxShape,
|
|
const uno::Reference< uno::XComponentContext >& rxContext ) :
|
|
mpViewLayer( rViewLayer ),
|
|
mpMediaWindow(),
|
|
maWindowOffset( 0, 0 ),
|
|
maBounds(),
|
|
mxShape( rxShape ),
|
|
mxPlayer(),
|
|
mxPlayerWindow(),
|
|
mxComponentContext( rxContext ),
|
|
mbIsSoundEnabled(true)
|
|
{
|
|
ENSURE_OR_THROW( mxShape.is(), "ViewMediaShape::ViewMediaShape(): Invalid Shape" );
|
|
ENSURE_OR_THROW( mpViewLayer, "ViewMediaShape::ViewMediaShape(): Invalid View" );
|
|
ENSURE_OR_THROW( mpViewLayer->getCanvas(), "ViewMediaShape::ViewMediaShape(): Invalid ViewLayer canvas" );
|
|
ENSURE_OR_THROW( mxComponentContext.is(), "ViewMediaShape::ViewMediaShape(): Invalid component context" );
|
|
|
|
UnoViewSharedPtr pUnoView (::boost::dynamic_pointer_cast<UnoView>(rViewLayer));
|
|
if (pUnoView)
|
|
{
|
|
mbIsSoundEnabled = pUnoView->isSoundEnabled();
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
ViewMediaShape::~ViewMediaShape()
|
|
{
|
|
try
|
|
{
|
|
endMedia();
|
|
}
|
|
catch (uno::Exception &)
|
|
{
|
|
OSL_ENSURE( false, rtl::OUStringToOString(
|
|
comphelper::anyToString(
|
|
cppu::getCaughtException() ),
|
|
RTL_TEXTENCODING_UTF8 ).getStr() );
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
ViewLayerSharedPtr ViewMediaShape::getViewLayer() const
|
|
{
|
|
return mpViewLayer;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
bool ViewMediaShape::startMedia()
|
|
{
|
|
if( !mxPlayer.is() )
|
|
implInitialize( maBounds );
|
|
|
|
if( mxPlayer.is() && ( mxPlayer->getDuration() > 0.0 ) )
|
|
mxPlayer->start();
|
|
|
|
return true;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void ViewMediaShape::endMedia()
|
|
{
|
|
// shutdown player window
|
|
if( mxPlayerWindow.is() )
|
|
{
|
|
uno::Reference< lang::XComponent > xComponent( mxPlayerWindow, uno::UNO_QUERY );
|
|
|
|
if( xComponent.is() )
|
|
xComponent->dispose();
|
|
|
|
mxPlayerWindow.clear();
|
|
}
|
|
|
|
mpMediaWindow = ::std::auto_ptr< JavaChildWindow >();
|
|
|
|
// shutdown player
|
|
if( mxPlayer.is() )
|
|
{
|
|
mxPlayer->stop();
|
|
|
|
uno::Reference< lang::XComponent > xComponent( mxPlayer, uno::UNO_QUERY );
|
|
|
|
if( xComponent.is() )
|
|
xComponent->dispose();
|
|
|
|
mxPlayer.clear();
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void ViewMediaShape::pauseMedia()
|
|
{
|
|
if( mxPlayer.is() && ( mxPlayer->getDuration() > 0.0 ) )
|
|
mxPlayer->stop();
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void ViewMediaShape::setMediaTime(double fTime)
|
|
{
|
|
if( mxPlayer.is() && ( mxPlayer->getDuration() > 0.0 ) )
|
|
mxPlayer->setMediaTime(fTime);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
bool ViewMediaShape::render( const ::basegfx::B2DRectangle& rBounds ) const
|
|
{
|
|
::cppcanvas::CanvasSharedPtr pCanvas = mpViewLayer->getCanvas();;
|
|
|
|
if( !pCanvas )
|
|
return false;
|
|
|
|
if( !mpMediaWindow.get() && !mxPlayerWindow.is() )
|
|
{
|
|
// fill the shape background with black
|
|
fillRect( pCanvas,
|
|
rBounds,
|
|
0x000000FFU );
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ViewMediaShape::resize( const ::basegfx::B2DRectangle& rNewBounds ) const
|
|
{
|
|
maBounds = rNewBounds;
|
|
|
|
::cppcanvas::CanvasSharedPtr pCanvas = mpViewLayer->getCanvas();;
|
|
|
|
if( !pCanvas )
|
|
return false;
|
|
|
|
if( !mxPlayerWindow.is() )
|
|
return true;
|
|
|
|
uno::Reference< beans::XPropertySet > xPropSet( pCanvas->getUNOCanvas()->getDevice(),
|
|
uno::UNO_QUERY );
|
|
|
|
uno::Reference< awt::XWindow > xParentWindow;
|
|
if( xPropSet.is() &&
|
|
getPropertyValue( xParentWindow,
|
|
xPropSet,
|
|
::rtl::OUString::createFromAscii( "Window" )) )
|
|
{
|
|
const awt::Rectangle aRect( xParentWindow->getPosSize() );
|
|
|
|
maWindowOffset.X = aRect.X;
|
|
maWindowOffset.Y = aRect.Y;
|
|
}
|
|
|
|
::basegfx::B2DRange aTmpRange;
|
|
::canvas::tools::calcTransformedRectBounds( aTmpRange,
|
|
rNewBounds,
|
|
mpViewLayer->getTransformation() );
|
|
const ::basegfx::B2IRange& rRangePix(
|
|
::basegfx::unotools::b2ISurroundingRangeFromB2DRange( aTmpRange ));
|
|
|
|
mxPlayerWindow->setEnable( !rRangePix.isEmpty() );
|
|
|
|
if( rRangePix.isEmpty() )
|
|
return true;
|
|
|
|
const Point aPosPixel( rRangePix.getMinX() + maWindowOffset.X,
|
|
rRangePix.getMinY() + maWindowOffset.Y );
|
|
const Size aSizePixel( rRangePix.getMaxX() - rRangePix.getMinX(),
|
|
rRangePix.getMaxY() - rRangePix.getMinY() );
|
|
|
|
if( mpMediaWindow.get() )
|
|
{
|
|
mpMediaWindow->SetPosSizePixel( aPosPixel, aSizePixel );
|
|
mxPlayerWindow->setPosSize( 0, 0,
|
|
aSizePixel.Width(), aSizePixel.Height(),
|
|
0 );
|
|
}
|
|
else
|
|
{
|
|
mxPlayerWindow->setPosSize( aPosPixel.X(), aPosPixel.Y(),
|
|
aSizePixel.Width(), aSizePixel.Height(),
|
|
0 );
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
bool ViewMediaShape::implInitialize( const ::basegfx::B2DRectangle& rBounds )
|
|
{
|
|
if( !mxPlayer.is() && mxShape.is() )
|
|
{
|
|
ENSURE_OR_RETURN( mpViewLayer->getCanvas(),
|
|
"ViewMediaShape::update(): Invalid layer canvas" );
|
|
|
|
uno::Reference< rendering::XCanvas > xCanvas( mpViewLayer->getCanvas()->getUNOCanvas() );
|
|
|
|
if( xCanvas.is() )
|
|
{
|
|
uno::Reference< beans::XPropertySet > xPropSet;
|
|
::rtl::OUString aURL;
|
|
|
|
try
|
|
{
|
|
xPropSet.set( mxShape, uno::UNO_QUERY );
|
|
|
|
// create Player
|
|
if( xPropSet.is() &&
|
|
( xPropSet->getPropertyValue(
|
|
::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaURL" ) ) ) >>=aURL ) )
|
|
{
|
|
implInitializeMediaPlayer( aURL );
|
|
}
|
|
|
|
// create visible object
|
|
uno::Sequence< uno::Any > aDeviceParams;
|
|
|
|
if( ::canvas::tools::getDeviceInfo( xCanvas, aDeviceParams ).getLength() > 1 )
|
|
{
|
|
::rtl::OUString aImplName;
|
|
|
|
aDeviceParams[ 0 ] >>= aImplName;
|
|
|
|
if( aImplName.endsWithIgnoreAsciiCaseAsciiL(
|
|
RTL_CONSTASCII_STRINGPARAM("VCL") ))
|
|
{
|
|
implInitializeVCLBasedPlayerWindow( rBounds, aDeviceParams );
|
|
}
|
|
else if( aImplName.endsWithIgnoreAsciiCaseAsciiL(
|
|
RTL_CONSTASCII_STRINGPARAM("DX")) ||
|
|
aImplName.endsWithIgnoreAsciiCaseAsciiL(
|
|
RTL_CONSTASCII_STRINGPARAM("DX9")))
|
|
{
|
|
implInitializeDXBasedPlayerWindow( rBounds, aDeviceParams );
|
|
}
|
|
}
|
|
|
|
// set player properties
|
|
implSetMediaProperties( xPropSet );
|
|
}
|
|
catch( uno::RuntimeException& )
|
|
{
|
|
throw;
|
|
}
|
|
catch( uno::Exception& )
|
|
{
|
|
OSL_ENSURE( false,
|
|
rtl::OUStringToOString(
|
|
comphelper::anyToString( cppu::getCaughtException() ),
|
|
RTL_TEXTENCODING_UTF8 ).getStr() );
|
|
}
|
|
}
|
|
}
|
|
|
|
return mxPlayer.is() || mxPlayerWindow.is();
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void ViewMediaShape::implSetMediaProperties( const uno::Reference< beans::XPropertySet >& rxProps )
|
|
{
|
|
if( mxPlayer.is() )
|
|
{
|
|
mxPlayer->setMediaTime( 0.0 );
|
|
|
|
if( rxProps.is() )
|
|
{
|
|
sal_Bool bLoop( false );
|
|
getPropertyValue( bLoop,
|
|
rxProps,
|
|
::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Loop" )));
|
|
mxPlayer->setPlaybackLoop( bLoop );
|
|
|
|
sal_Bool bMute( false );
|
|
getPropertyValue( bMute,
|
|
rxProps,
|
|
::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Mute" )));
|
|
mxPlayer->setMute( bMute || !mbIsSoundEnabled);
|
|
|
|
sal_Int16 nVolumeDB(0);
|
|
getPropertyValue( nVolumeDB,
|
|
rxProps,
|
|
::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VolumeDB" )));
|
|
mxPlayer->setVolumeDB( nVolumeDB );
|
|
|
|
if( mxPlayerWindow.is() )
|
|
{
|
|
media::ZoomLevel eZoom(media::ZoomLevel_FIT_TO_WINDOW);
|
|
getPropertyValue( eZoom,
|
|
rxProps,
|
|
::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Zoom" )));
|
|
mxPlayerWindow->setZoomLevel( eZoom );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void ViewMediaShape::implInitializeMediaPlayer( const ::rtl::OUString& rMediaURL )
|
|
{
|
|
if( !mxPlayer.is() )
|
|
{
|
|
try
|
|
{
|
|
if( rMediaURL.getLength() )
|
|
{
|
|
mxPlayer.set( avmedia::MediaWindow::createPlayer( rMediaURL ),
|
|
uno::UNO_QUERY );
|
|
}
|
|
}
|
|
catch( uno::RuntimeException& )
|
|
{
|
|
throw;
|
|
}
|
|
catch( const uno::Exception& )
|
|
{
|
|
throw lang::NoSupportException(
|
|
rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
|
|
"No video support for ") ) + rMediaURL,
|
|
uno::Reference<uno::XInterface>() );
|
|
}
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
bool ViewMediaShape::implInitializeVCLBasedPlayerWindow( const ::basegfx::B2DRectangle& rBounds,
|
|
const uno::Sequence< uno::Any >& rVCLDeviceParams)
|
|
{
|
|
if( !mpMediaWindow.get() && !rBounds.isEmpty() )
|
|
{
|
|
try
|
|
{
|
|
sal_Int64 aVal=0;
|
|
|
|
rVCLDeviceParams[ 1 ] >>= aVal;
|
|
|
|
Window* pWindow = reinterpret_cast< Window* >( aVal );
|
|
|
|
if( pWindow )
|
|
{
|
|
::basegfx::B2DRange aTmpRange;
|
|
::canvas::tools::calcTransformedRectBounds( aTmpRange,
|
|
rBounds,
|
|
mpViewLayer->getTransformation() );
|
|
const ::basegfx::B2IRange& rRangePix(
|
|
::basegfx::unotools::b2ISurroundingRangeFromB2DRange( aTmpRange ));
|
|
|
|
if( !rRangePix.isEmpty() )
|
|
{
|
|
uno::Sequence< uno::Any > aArgs( 2 );
|
|
awt::Rectangle aAWTRect( rRangePix.getMinX(),
|
|
rRangePix.getMinY(),
|
|
rRangePix.getMaxX() - rRangePix.getMinX(),
|
|
rRangePix.getMaxY() - rRangePix.getMinY() );
|
|
|
|
mpMediaWindow = ::std::auto_ptr< JavaChildWindow >( new JavaChildWindow( pWindow, WB_CLIPCHILDREN ) );
|
|
mpMediaWindow->SetBackground( Color( COL_BLACK ) );
|
|
mpMediaWindow->SetPosSizePixel( Point( aAWTRect.X,
|
|
aAWTRect.Y ),
|
|
Size( aAWTRect.Width,
|
|
aAWTRect.Height ));
|
|
mpMediaWindow->Show();
|
|
|
|
if( mxPlayer.is() )
|
|
{
|
|
aArgs[ 0 ] = uno::makeAny(
|
|
sal::static_int_cast<sal_IntPtr>(
|
|
mpMediaWindow->getParentWindowHandleForJava()) );
|
|
|
|
aAWTRect.X = aAWTRect.Y = 0;
|
|
aArgs[ 1 ] = uno::makeAny( aAWTRect );
|
|
|
|
mxPlayerWindow.set( mxPlayer->createPlayerWindow( aArgs ) );
|
|
|
|
if( mxPlayerWindow.is() )
|
|
{
|
|
mxPlayerWindow->setVisible( true );
|
|
mxPlayerWindow->setEnable( true );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch( uno::RuntimeException& )
|
|
{
|
|
throw;
|
|
}
|
|
catch( uno::Exception& )
|
|
{
|
|
OSL_ENSURE( false,
|
|
rtl::OUStringToOString(
|
|
comphelper::anyToString( cppu::getCaughtException() ),
|
|
RTL_TEXTENCODING_UTF8 ).getStr() );
|
|
}
|
|
}
|
|
|
|
return mxPlayerWindow.is();
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
bool ViewMediaShape::implInitializeDXBasedPlayerWindow( const ::basegfx::B2DRectangle& rBounds,
|
|
const uno::Sequence< uno::Any >& rDXDeviceParams )
|
|
{
|
|
if( !mxPlayerWindow.is() )
|
|
{
|
|
try
|
|
{
|
|
if( rDXDeviceParams.getLength() == 2 )
|
|
{
|
|
sal_Int64 aWNDVal=0;
|
|
|
|
rDXDeviceParams[ 1 ] >>= aWNDVal;
|
|
|
|
if( aWNDVal )
|
|
{
|
|
::basegfx::B2DRange aTmpRange;
|
|
::canvas::tools::calcTransformedRectBounds( aTmpRange,
|
|
rBounds,
|
|
mpViewLayer->getTransformation() );
|
|
const ::basegfx::B2IRange& rRangePix(
|
|
::basegfx::unotools::b2ISurroundingRangeFromB2DRange( aTmpRange ));
|
|
|
|
if( !rRangePix.isEmpty() )
|
|
{
|
|
uno::Sequence< uno::Any > aArgs( 2 );
|
|
awt::Rectangle aAWTRect( rRangePix.getMinX() + maWindowOffset.X,
|
|
rRangePix.getMinY() + maWindowOffset.Y,
|
|
rRangePix.getMaxX() - rRangePix.getMinX(),
|
|
rRangePix.getMaxY() - rRangePix.getMinY() );
|
|
|
|
if( mxPlayer.is() )
|
|
{
|
|
aArgs[ 0 ] = uno::makeAny(
|
|
sal::static_int_cast<sal_Int32>(
|
|
aWNDVal) );
|
|
aArgs[ 1 ] = uno::makeAny( aAWTRect );
|
|
|
|
mxPlayerWindow.set( mxPlayer->createPlayerWindow( aArgs ) );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch( uno::RuntimeException& )
|
|
{
|
|
throw;
|
|
}
|
|
catch( uno::Exception& )
|
|
{
|
|
OSL_ENSURE( false,
|
|
rtl::OUStringToOString(
|
|
comphelper::anyToString( cppu::getCaughtException() ),
|
|
RTL_TEXTENCODING_UTF8 ).getStr() );
|
|
}
|
|
}
|
|
|
|
return mxPlayerWindow.is();
|
|
}
|
|
}
|
|
}
|