1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_slideshow.hxx"
30 
31 #include <canvas/debug.hxx>
32 #include <tools/diagnose_ex.h>
33 #include <canvas/verbosetrace.hxx>
34 
35 #include <comphelper/anytostring.hxx>
36 #include <cppuhelper/exc_hlp.hxx>
37 
38 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
39 #include <com/sun/star/lang/NoSupportException.hpp>
40 #include <com/sun/star/lang/XComponent.hdl>
41 
42 #include <tools/urlobj.hxx>
43 
44 #include <avmedia/mediawindow.hxx>
45 
46 #include "soundplayer.hxx"
47 
48 #include <algorithm>
49 
50 using namespace ::com::sun::star;
51 
52 
53 namespace slideshow
54 {
55     namespace internal
56     {
57         // TODO(Q3): Move the whole SoundPlayer class to avmedia.
58 
59         boost::shared_ptr<SoundPlayer> SoundPlayer::create(
60             EventMultiplexer & rEventMultiplexer,
61             const ::rtl::OUString& rSoundURL,
62             const uno::Reference< uno::XComponentContext>&	rComponentContext )
63         {
64             boost::shared_ptr<SoundPlayer> pPlayer(
65                 new SoundPlayer( rEventMultiplexer,
66                                  rSoundURL,
67                                  rComponentContext ) );
68             rEventMultiplexer.addPauseHandler( pPlayer );
69             pPlayer->mThis = pPlayer;
70             return pPlayer;
71         }
72 
73         bool SoundPlayer::handlePause( bool bPauseShow )
74         {
75             return bPauseShow ? stopPlayback() : startPlayback();
76         }
77 
78         void SoundPlayer::dispose()
79         {
80             if( mThis )
81             {
82                 mrEventMultiplexer.removePauseHandler( mThis );
83                 mThis.reset();
84             }
85 
86 			if( mxPlayer.is() )
87             {
88 				mxPlayer->stop();
89 				uno::Reference<lang::XComponent> xComponent(
90                     mxPlayer, uno::UNO_QUERY );
91 				if( xComponent.is() )
92 					xComponent->dispose();
93                 mxPlayer.clear();
94 			}
95         }
96 
97         SoundPlayer::SoundPlayer(
98             EventMultiplexer & rEventMultiplexer,
99             const ::rtl::OUString& rSoundURL,
100             const uno::Reference< uno::XComponentContext>&	rComponentContext )
101             : mrEventMultiplexer(rEventMultiplexer),
102               mThis(),
103               mxPlayer()
104         {
105             ENSURE_OR_THROW( rComponentContext.is(),
106                               "SoundPlayer::SoundPlayer(): Invalid component context" );
107 
108             try
109             {
110         		const INetURLObject aURL( rSoundURL );
111                 mxPlayer.set( avmedia::MediaWindow::createPlayer(
112                                 aURL.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS ) ),
113                                 uno::UNO_QUERY);
114             }
115             catch( uno::RuntimeException& )
116             {
117                 throw;
118             }
119             catch( uno::Exception& )
120             {
121             }
122 
123             if( !mxPlayer.is() )
124                 throw lang::NoSupportException(
125                     rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
126                                        "No sound support for ") ) + rSoundURL,
127                     uno::Reference<uno::XInterface>() );
128         }
129 
130         SoundPlayer::~SoundPlayer()
131         {
132             try
133             {
134                 dispose();
135             }
136             catch (uno::Exception &) {
137                 OSL_ENSURE( false, rtl::OUStringToOString(
138                                 comphelper::anyToString(
139                                     cppu::getCaughtException() ),
140                                 RTL_TEXTENCODING_UTF8 ).getStr() );
141             }
142         }
143 
144         double SoundPlayer::getDuration() const
145         {
146             if( !mxPlayer.is() )
147                 return 0.0;
148 
149             const double nDuration( mxPlayer->getDuration() );
150             if( mxPlayer->isPlaying() )
151                 return ::std::max( 0.0,
152                                    nDuration - mxPlayer->getMediaTime() );
153             else
154                 return nDuration;
155         }
156 
157         bool SoundPlayer::startPlayback()
158         {
159             if( !mxPlayer.is() )
160                 return false;
161 
162             if( mxPlayer->isPlaying() )
163                 mxPlayer->stop();
164 
165             mxPlayer->start();
166             return true;
167         }
168 
169         bool SoundPlayer::stopPlayback()
170         {
171             if( mxPlayer.is() )
172                 mxPlayer->stop();
173 
174             return true;
175         }
176 
177 		void SoundPlayer::setPlaybackLoop( bool bLoop )
178 		{
179 			if( mxPlayer.is() )
180 				mxPlayer->setPlaybackLoop( bLoop );
181 		}
182     }
183 }
184