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