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 #include <stdio.h>
29 
30 #include <avmedia/mediawindow.hxx>
31 #include "mediawindow_impl.hxx"
32 #include "mediamisc.hxx"
33 #include "mediawindow.hrc"
34 #include <tools/urlobj.hxx>
35 #include <vcl/msgbox.hxx>
36 #include <unotools/pathoptions.hxx>
37 #include <sfx2/filedlghelper.hxx>
38 #include <comphelper/processfactory.hxx>
39 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
40 #include <com/sun/star/media/XManager.hpp>
41 #include "com/sun/star/ui/dialogs/TemplateDescription.hpp"
42 
43 #define AVMEDIA_FRAMEGRABBER_DEFAULTFRAME_MEDIATIME 3.0
44 
45 using namespace ::com::sun::star;
46 
47 namespace avmedia {
48 
49 // ---------------
50 // - MediaWindow -
51 // ---------------
52 
53 MediaWindow::MediaWindow( Window* parent, bool bInternalMediaControl ) :
54     mpImpl( new priv::MediaWindowImpl( parent, this, bInternalMediaControl ) )
55 {
56     mpImpl->Show();
57 }
58 
59 // -------------------------------------------------------------------------
60 
61 MediaWindow::~MediaWindow()
62 {
63     mpImpl->cleanUp();
64     delete mpImpl;
65     mpImpl = NULL;
66 }
67 
68 // -------------------------------------------------------------------------
69 
70 void MediaWindow::setURL( const ::rtl::OUString& rURL )
71 {
72     if( mpImpl )
73         mpImpl->setURL( rURL );
74 }
75 
76 // -------------------------------------------------------------------------
77 
78 const ::rtl::OUString& MediaWindow::getURL() const
79 {
80     return mpImpl->getURL();
81 }
82 
83 // -------------------------------------------------------------------------
84 
85 bool MediaWindow::isValid() const
86 {
87     return( mpImpl != NULL && mpImpl->isValid() );
88 }
89 
90 // -------------------------------------------------------------------------
91 
92 void MediaWindow::MouseMove( const MouseEvent& /* rMEvt */ )
93 {
94 }
95 
96 // ---------------------------------------------------------------------
97 
98 void MediaWindow::MouseButtonDown( const MouseEvent& /* rMEvt */ )
99 {
100 }
101 
102 // ---------------------------------------------------------------------
103 
104 void MediaWindow::MouseButtonUp( const MouseEvent& /* rMEvt */ )
105 {
106 }
107 
108 // -------------------------------------------------------------------------
109 
110 void MediaWindow::KeyInput( const KeyEvent& /* rKEvt */ )
111 {
112 }
113 
114 // -------------------------------------------------------------------------
115 
116 void MediaWindow::KeyUp( const KeyEvent& /* rKEvt */ )
117 {
118 }
119 
120 // -------------------------------------------------------------------------
121 
122 void MediaWindow::Command( const CommandEvent& /* rCEvt */ )
123 {
124 }
125 
126 // -------------------------------------------------------------------------
127 
128 sal_Int8 MediaWindow::AcceptDrop( const AcceptDropEvent& /* rEvt */ )
129 {
130     return 0;
131 }
132 
133 // -------------------------------------------------------------------------
134 
135 sal_Int8 MediaWindow::ExecuteDrop( const ExecuteDropEvent& /* rEvt */ )
136 {
137     return 0;
138 }
139 
140 // -------------------------------------------------------------------------
141 
142 void MediaWindow::StartDrag( sal_Int8 /* nAction */, const Point& /* rPosPixel */ )
143 {
144 }
145 
146 // -------------------------------------------------------------------------
147 
148 bool MediaWindow::hasPreferredSize() const
149 {
150     return( mpImpl != NULL && mpImpl->hasPreferredSize() );
151 }
152 
153 // -------------------------------------------------------------------------
154 
155 Size MediaWindow::getPreferredSize() const
156 {
157     return mpImpl->getPreferredSize();
158 }
159 
160 // -------------------------------------------------------------------------
161 
162 void MediaWindow::setPosSize( const Rectangle& rNewRect )
163 {
164     if( mpImpl )
165     {
166         mpImpl->setPosSize( rNewRect );
167     }
168 }
169 
170 // -------------------------------------------------------------------------
171 
172 Rectangle MediaWindow::getPosSize() const
173 {
174     return Rectangle( mpImpl->GetPosPixel(), mpImpl->GetSizePixel() );
175 }
176 
177 // -------------------------------------------------------------------------
178 
179 void MediaWindow::setPointer( const Pointer& rPointer )
180 {
181     if( mpImpl )
182         mpImpl->setPointer( rPointer );
183 }
184 
185 // -------------------------------------------------------------------------
186 
187 const Pointer& MediaWindow::getPointer() const
188 {
189     return mpImpl->getPointer();
190 }
191 
192 // -------------------------------------------------------------------------
193 
194 bool MediaWindow::setZoom( ::com::sun::star::media::ZoomLevel eLevel )
195 {
196     return( mpImpl != NULL && mpImpl->setZoom( eLevel ) );
197 }
198 
199 // -------------------------------------------------------------------------
200 
201 ::com::sun::star::media::ZoomLevel MediaWindow::getZoom() const
202 {
203     return mpImpl->getZoom();
204 }
205 
206 // -------------------------------------------------------------------------
207 
208 bool MediaWindow::start()
209 {
210     return( mpImpl != NULL && mpImpl->start() );
211 }
212 
213 // -------------------------------------------------------------------------
214 
215 void MediaWindow::stop()
216 {
217     if( mpImpl )
218         mpImpl->stop();
219 }
220 
221 // -------------------------------------------------------------------------
222 
223 bool MediaWindow::isPlaying() const
224 {
225     return( mpImpl != NULL && mpImpl->isPlaying() );
226 }
227 
228 // -------------------------------------------------------------------------
229 
230 double MediaWindow::getDuration() const
231 {
232     return mpImpl->getDuration();
233 }
234 
235 // -------------------------------------------------------------------------
236 
237 void MediaWindow::setMediaTime( double fTime )
238 {
239     if( mpImpl )
240         mpImpl->setMediaTime( fTime );
241 }
242 
243 // -------------------------------------------------------------------------
244 
245 double MediaWindow::getMediaTime() const
246 {
247     return mpImpl->getMediaTime();
248 }
249 
250 // -------------------------------------------------------------------------
251 
252 void MediaWindow::setStopTime( double fTime )
253 {
254     if( mpImpl )
255         mpImpl->setStopTime( fTime );
256 }
257 
258 // -------------------------------------------------------------------------
259 
260 double MediaWindow::getStopTime() const
261 {
262     return mpImpl->getStopTime();
263 }
264 
265 // -------------------------------------------------------------------------
266 
267 void MediaWindow::setRate( double fRate )
268 {
269     if( mpImpl )
270         mpImpl->setRate( fRate );
271 }
272 
273 // -------------------------------------------------------------------------
274 
275 double MediaWindow::getRate() const
276 {
277     return mpImpl->getRate();
278 }
279 
280 // -------------------------------------------------------------------------
281 
282 void MediaWindow::setPlaybackLoop( bool bSet )
283 {
284     if( mpImpl )
285         mpImpl->setPlaybackLoop( bSet );
286 }
287 
288 // -------------------------------------------------------------------------
289 
290 bool MediaWindow::isPlaybackLoop() const
291 {
292     return mpImpl->isPlaybackLoop();
293 }
294 
295 // -------------------------------------------------------------------------
296 
297 void MediaWindow::setMute( bool bSet )
298 {
299     if( mpImpl )
300         mpImpl->setMute( bSet );
301 }
302 
303 // -------------------------------------------------------------------------
304 
305 bool MediaWindow::isMute() const
306 {
307     return mpImpl->isMute();
308 }
309 
310 // -------------------------------------------------------------------------
311 
312 void MediaWindow::updateMediaItem( MediaItem& rItem ) const
313 {
314     if( mpImpl )
315         mpImpl->updateMediaItem( rItem );
316 }
317 
318 // -------------------------------------------------------------------------
319 
320 void MediaWindow::executeMediaItem( const MediaItem& rItem )
321 {
322     if( mpImpl )
323         mpImpl->executeMediaItem( rItem );
324 }
325 
326 // -------------------------------------------------------------------------
327 
328 void MediaWindow::show()
329 {
330     if( mpImpl )
331         mpImpl->Show();
332 }
333 
334 // -------------------------------------------------------------------------
335 
336 void MediaWindow::hide()
337 {
338     if( mpImpl )
339         mpImpl->Hide();
340 }
341 
342 // -------------------------------------------------------------------------
343 
344 void MediaWindow::enable()
345 {
346     if( mpImpl )
347         mpImpl->Enable();
348 }
349 
350 // -------------------------------------------------------------------------
351 
352 void MediaWindow::disable()
353 {
354     if( mpImpl )
355         mpImpl->Disable();
356 }
357 
358 // -------------------------------------------------------------------------
359 
360 Window* MediaWindow::getWindow() const
361 {
362     return mpImpl;
363 }
364 
365 // -------------------------------------------------------------------------
366 
367 void MediaWindow::getMediaFilters( FilterNameVector& rFilterNameVector )
368 {
369     static const char* pFilters[] = {   "AIF Audio", "aif;aiff",
370                                         "AU Audio", "au",
371                                         "AVI", "avi",
372                                         "CD Audio", "cda",
373                                         "Matroska Media", "mkv",
374                                         "MIDI Audio", "mid;midi",
375                                         "MPEG Audio", "mp2;mp3;mpa",
376                                         "MPEG Video", "mpg;mpeg;mpv;mp4",
377                                         "Ogg bitstream", "ogg",
378                                         "Quicktime Video", "mov",
379                                         "Vivo Video", "viv",
380                                         "WAVE Audio", "wav" };
381 
382     unsigned int i;
383 	for( i = 0; i < ( sizeof( pFilters ) / sizeof( char* ) ); i += 2 )
384     {
385         rFilterNameVector.push_back( ::std::make_pair< ::rtl::OUString, ::rtl::OUString >(
386                                         ::rtl::OUString::createFromAscii( pFilters[ i ] ),
387                                         ::rtl::OUString::createFromAscii( pFilters[ i + 1 ] ) ) );
388     }
389 }
390 
391 // -------------------------------------------------------------------------
392 
393 bool MediaWindow::executeMediaURLDialog( Window* /* pParent */, ::rtl::OUString& rURL, bool bInsertDialog )
394 {
395     ::sfx2::FileDialogHelper        aDlg( com::sun::star::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, 0 );
396     static const ::rtl::OUString    aWildcard( RTL_CONSTASCII_USTRINGPARAM( "*." ) );
397     FilterNameVector                aFilters;
398     const ::rtl::OUString           aSeparator( RTL_CONSTASCII_USTRINGPARAM( ";" ) );
399     ::rtl::OUString                 aAllTypes;
400 
401     aDlg.SetTitle( AVMEDIA_RESID( bInsertDialog ? AVMEDIA_STR_INSERTMEDIA_DLG : AVMEDIA_STR_OPENMEDIA_DLG ) );
402 
403     getMediaFilters( aFilters );
404 
405 	unsigned int i;
406     for( i = 0; i < aFilters.size(); ++i )
407     {
408         for( sal_Int32 nIndex = 0; nIndex >= 0; )
409         {
410             if( aAllTypes.getLength() )
411                 aAllTypes += aSeparator;
412 
413             ( aAllTypes += aWildcard ) += aFilters[ i ].second.getToken( 0, ';', nIndex );
414         }
415     }
416 
417     // add filter for all media types
418     aDlg.AddFilter( AVMEDIA_RESID( AVMEDIA_STR_ALL_MEDIAFILES ), aAllTypes );
419 
420     for( i = 0; i < aFilters.size(); ++i )
421     {
422         ::rtl::OUString aTypes;
423 
424         for( sal_Int32 nIndex = 0; nIndex >= 0; )
425         {
426             if( aTypes.getLength() )
427                 aTypes += aSeparator;
428 
429             ( aTypes += aWildcard ) += aFilters[ i ].second.getToken( 0, ';', nIndex );
430         }
431 
432         // add single filters
433         aDlg.AddFilter( aFilters[ i ].first, aTypes );
434     }
435 
436     // add filter for all types
437     aDlg.AddFilter( AVMEDIA_RESID( AVMEDIA_STR_ALL_FILES ), String( RTL_CONSTASCII_USTRINGPARAM( "*.*" ) ) );
438 
439     if( aDlg.Execute() == ERRCODE_NONE )
440     {
441         const INetURLObject aURL( aDlg.GetPath() );
442         rURL = aURL.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS );
443     }
444     else if( rURL.getLength() )
445         rURL = ::rtl::OUString();
446 
447     return( rURL.getLength() > 0 );
448 }
449 
450 // -------------------------------------------------------------------------
451 
452 void MediaWindow::executeFormatErrorBox( Window* pParent )
453 {
454     ErrorBox aErrBox( pParent, AVMEDIA_RESID( AVMEDIA_ERR_URL ) );
455 
456     aErrBox.Execute();
457 }
458 
459 // -------------------------------------------------------------------------
460 
461 bool MediaWindow::isMediaURL( const ::rtl::OUString& rURL, bool bDeep, Size* pPreferredSizePixel )
462 {
463     const INetURLObject aURL( rURL );
464     bool                bRet = false;
465 
466     if( aURL.GetProtocol() != INET_PROT_NOT_VALID )
467     {
468         if( bDeep || pPreferredSizePixel )
469         {
470             try
471             {
472                 sal_Bool bIsJavaBasedMediaWindow;
473     	        uno::Reference< media::XPlayer > xPlayer( priv::MediaWindowImpl::createPlayer(
474         	                                                aURL.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS ),
475                                                             bIsJavaBasedMediaWindow ) );
476 
477             	if( xPlayer.is() )
478                 {
479                     bRet = true;
480 
481                     if( pPreferredSizePixel )
482                     {
483                         const awt::Size aAwtSize( xPlayer->getPreferredPlayerWindowSize() );
484 
485                         pPreferredSizePixel->Width() = aAwtSize.Width;
486                         pPreferredSizePixel->Height() = aAwtSize.Height;
487                     }
488                 }
489             }
490             catch( ... )
491             {
492             }
493         }
494         else
495         {
496             FilterNameVector        aFilters;
497             const ::rtl::OUString   aExt( aURL.getExtension() );
498 
499             getMediaFilters( aFilters );
500 
501 			unsigned int i;
502             for( i = 0; ( i < aFilters.size() ) && !bRet; ++i )
503             {
504                 for( sal_Int32 nIndex = 0; nIndex >= 0 && !bRet; )
505                 {
506                     if( aExt.equalsIgnoreAsciiCase( aFilters[ i ].second.getToken( 0, ';', nIndex ) ) )
507                         bRet = true;
508                 }
509             }
510         }
511     }
512 
513     return bRet;
514 }
515 
516 // -------------------------------------------------------------------------
517 
518 uno::Reference< media::XPlayer > MediaWindow::createPlayer( const ::rtl::OUString& rURL )
519 {
520     sal_Bool bJavaBased = sal_False;
521     return priv::MediaWindowImpl::createPlayer( rURL, bJavaBased );
522 }
523 
524 // -------------------------------------------------------------------------
525 
526 uno::Reference< graphic::XGraphic > MediaWindow::grabFrame( const ::rtl::OUString& rURL,
527                                                             bool bAllowToCreateReplacementGraphic,
528                                                             double fMediaTime )
529 {
530     uno::Reference< media::XPlayer >    xPlayer( createPlayer( rURL ) );
531     uno::Reference< graphic::XGraphic > xRet;
532     ::std::auto_ptr< Graphic >          apGraphic;
533 
534     if( xPlayer.is() )
535     {
536         uno::Reference< media::XFrameGrabber > xGrabber( xPlayer->createFrameGrabber() );
537 
538         if( xGrabber.is() )
539         {
540             if( AVMEDIA_FRAMEGRABBER_DEFAULTFRAME == fMediaTime )
541                 fMediaTime = AVMEDIA_FRAMEGRABBER_DEFAULTFRAME_MEDIATIME;
542 
543             if( fMediaTime >= xPlayer->getDuration() )
544                 fMediaTime = ( xPlayer->getDuration() * 0.5 );
545 
546             xRet = xGrabber->grabFrame( fMediaTime );
547         }
548 
549         if( !xRet.is() && bAllowToCreateReplacementGraphic  )
550         {
551             awt::Size aPrefSize( xPlayer->getPreferredPlayerWindowSize() );
552 
553             if( !aPrefSize.Width && !aPrefSize.Height )
554             {
555                 const BitmapEx aBmpEx( AVMEDIA_RESID( AVMEDIA_BMP_AUDIOLOGO ) );
556                 apGraphic.reset( new Graphic( aBmpEx ) );
557             }
558         }
559     }
560 
561     if( !xRet.is() && !apGraphic.get() && bAllowToCreateReplacementGraphic )
562     {
563         const BitmapEx aBmpEx( AVMEDIA_RESID( AVMEDIA_BMP_EMPTYLOGO ) );
564         apGraphic.reset( new Graphic( aBmpEx ) );
565     }
566 
567     if( apGraphic.get() )
568         xRet = apGraphic->GetXGraphic();
569 
570     return xRet;
571 }
572 
573 } // namespace avemdia
574