]> git.sesse.net Git - vlc/blob - modules/gui/qt4/dialogs_provider.cpp
Qt: PostProc getter helper
[vlc] / modules / gui / qt4 / dialogs_provider.cpp
1 /*****************************************************************************
2  * dialogs_provider.cpp : Dialog Provider
3  *****************************************************************************
4  * Copyright (C) 2006-2009 the VideoLAN team
5  * $Id$
6  *
7  * Authors: ClĂ©ment Stenac <zorglub@videolan.org>
8  *          Jean-Baptiste Kempf <jb@videolan.org>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program 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 General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #include <vlc_intf_strings.h>
30
31 #include "qt4.hpp"
32 #include "dialogs_provider.hpp"
33 #include "input_manager.hpp" /* Load Subtitles */
34 #include "menus.hpp"
35 #include "recents.hpp"
36 #include "util/qt_dirs.hpp"
37 #include "util/customwidgets.hpp" /* VLCKeyToString() */
38 #include "main_interface.hpp"
39
40 /* The dialogs */
41 #include "dialogs/playlist.hpp"
42 #include "dialogs/bookmarks.hpp"
43 #include "dialogs/preferences.hpp"
44 #include "dialogs/mediainfo.hpp"
45 #include "dialogs/messages.hpp"
46 #include "dialogs/extended.hpp"
47 #include "dialogs/vlm.hpp"
48 #include "dialogs/sout.hpp"
49 #include "dialogs/convert.hpp"
50 #include "dialogs/open.hpp"
51 #include "dialogs/openurl.hpp"
52 #include "dialogs/help.hpp"
53 #include "dialogs/gototime.hpp"
54 #include "dialogs/podcast_configuration.hpp"
55 #include "dialogs/toolbar.hpp"
56 #include "dialogs/plugins.hpp"
57 #include "dialogs/external.hpp"
58 #include "dialogs/epg.hpp"
59 #include "dialogs/errors.hpp"
60
61 #include <QEvent>
62 #include <QApplication>
63 #include <QSignalMapper>
64 #include <QFileDialog>
65
66 #define I_OP_DIR_WINTITLE I_DIR_OR_FOLDER( N_("Open Directory"), \
67                                            N_("Open Folder") )
68
69 DialogsProvider* DialogsProvider::instance = NULL;
70
71 DialogsProvider::DialogsProvider( intf_thread_t *_p_intf ) :
72                                   QObject( NULL ), p_intf( _p_intf ),
73                                   popupMenu( NULL ),
74                                   videoPopupMenu( NULL ),
75                                   audioPopupMenu( NULL ),
76                                   miscPopupMenu( NULL )
77 {
78     b_isDying = false;
79
80     /* Various signal mappers for the menus */
81     menusMapper = new QSignalMapper();
82     CONNECT( menusMapper, mapped(QObject *), this, menuAction( QObject *) );
83
84     menusUpdateMapper = new QSignalMapper();
85     CONNECT( menusUpdateMapper, mapped(QObject *),
86              this, menuUpdateAction( QObject *) );
87
88     SDMapper = new QSignalMapper();
89     CONNECT( SDMapper, mapped (QString), this, SDMenuAction( QString ) );
90
91     new DialogHandler (p_intf, this );
92 }
93
94 DialogsProvider::~DialogsProvider()
95 {
96     PlaylistDialog::killInstance();
97     MediaInfoDialog::killInstance();
98     MessagesDialog::killInstance();
99     BookmarksDialog::killInstance();
100     HelpDialog::killInstance();
101 #ifdef UPDATE_CHECK
102     UpdateDialog::killInstance();
103 #endif
104     PluginDialog::killInstance();
105     EpgDialog::killInstance();
106
107     delete menusMapper;
108     delete menusUpdateMapper;
109     delete SDMapper;
110
111     delete popupMenu;
112     delete videoPopupMenu;
113     delete audioPopupMenu;
114     delete miscPopupMenu;
115 }
116
117 void DialogsProvider::quit()
118 {
119     b_isDying = true;
120     libvlc_Quit( p_intf->p_libvlc );
121 }
122
123 void DialogsProvider::customEvent( QEvent *event )
124 {
125     if( event->type() == DialogEvent::DialogEvent_Type )
126     {
127         DialogEvent *de = static_cast<DialogEvent*>(event);
128         switch( de->i_dialog )
129         {
130         case INTF_DIALOG_FILE_SIMPLE:
131         case INTF_DIALOG_FILE:
132             openDialog(); break;
133         case INTF_DIALOG_FILE_GENERIC:
134             openFileGenericDialog( de->p_arg ); break;
135         case INTF_DIALOG_DISC:
136             openDiscDialog(); break;
137         case INTF_DIALOG_NET:
138             openNetDialog(); break;
139         case INTF_DIALOG_SAT:
140         case INTF_DIALOG_CAPTURE:
141             openCaptureDialog(); break;
142         case INTF_DIALOG_DIRECTORY:
143             PLAppendDir(); break;
144         case INTF_DIALOG_PLAYLIST:
145             playlistDialog(); break;
146         case INTF_DIALOG_MESSAGES:
147             messagesDialog(); break;
148         case INTF_DIALOG_FILEINFO:
149            mediaInfoDialog(); break;
150         case INTF_DIALOG_PREFS:
151            prefsDialog(); break;
152         case INTF_DIALOG_BOOKMARKS:
153            bookmarksDialog(); break;
154         case INTF_DIALOG_EXTENDED:
155            extendedDialog(); break;
156         case INTF_DIALOG_SENDKEY:
157            sendKey( de->i_arg ); break;
158 #ifdef ENABLE_VLM
159         case INTF_DIALOG_VLM:
160            vlmDialog(); break;
161 #endif
162         case INTF_DIALOG_POPUPMENU:
163         {
164            delete popupMenu; popupMenu = NULL;
165            bool show = (de->i_arg != 0);
166            if( show )
167                popupMenu = VLCMenuBar::PopupMenu( p_intf, show );
168            break;
169         }
170         case INTF_DIALOG_AUDIOPOPUPMENU:
171         {
172            delete audioPopupMenu; audioPopupMenu = NULL;
173            bool show = (de->i_arg != 0);
174            if( show )
175                audioPopupMenu = VLCMenuBar::AudioPopupMenu( p_intf, show );
176            break;
177         }
178         case INTF_DIALOG_VIDEOPOPUPMENU:
179         {
180            delete videoPopupMenu; videoPopupMenu = NULL;
181            bool show = (de->i_arg != 0);
182            if( show )
183                videoPopupMenu = VLCMenuBar::VideoPopupMenu( p_intf, show );
184            break;
185         }
186         case INTF_DIALOG_MISCPOPUPMENU:
187         {
188            delete miscPopupMenu; miscPopupMenu = NULL;
189            bool show = (de->i_arg != 0);
190            if( show )
191                miscPopupMenu = VLCMenuBar::MiscPopupMenu( p_intf, show );
192            break;
193         }
194         case INTF_DIALOG_WIZARD:
195         case INTF_DIALOG_STREAMWIZARD:
196             openAndStreamingDialogs(); break;
197 #ifdef UPDATE_CHECK
198         case INTF_DIALOG_UPDATEVLC:
199             updateDialog(); break;
200 #endif
201         case INTF_DIALOG_EXIT:
202             quit(); break;
203         default:
204            msg_Warn( p_intf, "unimplemented dialog" );
205         }
206     }
207 }
208
209 /****************************************************************************
210  * Individual simple dialogs
211  ****************************************************************************/
212 const QEvent::Type DialogEvent::DialogEvent_Type =
213         (QEvent::Type)QEvent::registerEventType();
214
215 void DialogsProvider::playlistDialog()
216 {
217     PlaylistDialog::getInstance( p_intf )->toggleVisible();
218 }
219
220 void DialogsProvider::prefsDialog()
221 {
222     PrefsDialog *p = new PrefsDialog( (QWidget *)p_intf->p_sys->p_mi, p_intf );
223     p->toggleVisible();
224 }
225
226 void DialogsProvider::extendedDialog()
227 {
228     ExtendedDialog *extDialog = ExtendedDialog::getInstance(p_intf );
229
230     if( !extDialog->isVisible() || /* Hidden */
231         extDialog->currentTab() != 0 )  /* wrong tab */
232         extDialog->showTab( 0 );
233     else
234         extDialog->hide();
235 }
236
237 void DialogsProvider::synchroDialog()
238 {
239     ExtendedDialog *extDialog = ExtendedDialog::getInstance(p_intf );
240
241     if( !extDialog->isVisible() || /* Hidden */
242         extDialog->currentTab() != 2 )  /* wrong tab */
243         extDialog->showTab( 2 );
244     else
245         extDialog->hide();
246 }
247
248 void DialogsProvider::messagesDialog()
249 {
250     MessagesDialog::getInstance( p_intf )->toggleVisible();
251 }
252
253 void DialogsProvider::gotoTimeDialog()
254 {
255     GotoTimeDialog::getInstance( p_intf )->toggleVisible();
256 }
257
258 #ifdef ENABLE_VLM
259 void DialogsProvider::vlmDialog()
260 {
261     VLMDialog::getInstance( p_intf )->toggleVisible();
262 }
263 #endif
264
265 void DialogsProvider::helpDialog()
266 {
267     HelpDialog::getInstance( p_intf )->toggleVisible();
268 }
269
270 #ifdef UPDATE_CHECK
271 void DialogsProvider::updateDialog()
272 {
273     UpdateDialog::getInstance( p_intf )->toggleVisible();
274 }
275 #endif
276
277 void DialogsProvider::aboutDialog()
278 {
279     AboutDialog::getInstance( p_intf )->toggleVisible();
280 }
281
282 void DialogsProvider::mediaInfoDialog()
283 {
284     MediaInfoDialog::getInstance( p_intf )->showTab( MediaInfoDialog::META_PANEL );
285 }
286
287 void DialogsProvider::mediaCodecDialog()
288 {
289     MediaInfoDialog::getInstance( p_intf )->showTab( MediaInfoDialog::INFO_PANEL );
290 }
291
292 void DialogsProvider::bookmarksDialog()
293 {
294     BookmarksDialog::getInstance( p_intf )->toggleVisible();
295 }
296
297 void DialogsProvider::podcastConfigureDialog()
298 {
299     PodcastConfigDialog::getInstance( p_intf )->toggleVisible();
300 }
301
302 void DialogsProvider::toolbarDialog()
303 {
304     ToolbarEditDialog *toolbarEditor = new ToolbarEditDialog( (QWidget *)p_intf->p_sys->p_mi, p_intf );
305     if( toolbarEditor->exec() == QDialog::Accepted )
306         emit toolBarConfUpdated();
307 }
308
309 void DialogsProvider::pluginDialog()
310 {
311     PluginDialog::getInstance( p_intf )->toggleVisible();
312 }
313
314 void DialogsProvider::epgDialog()
315 {
316     EpgDialog::getInstance( p_intf )->toggleVisible();
317 }
318
319 void DialogsProvider::setPopupMenu()
320 {
321     delete popupMenu;
322     popupMenu = VLCMenuBar::PopupMenu( p_intf, true );
323 }
324
325 void DialogsProvider::destroyPopupMenu()
326 {
327     delete popupMenu;
328     popupMenu = NULL;
329 }
330
331 /* Generic open file */
332 void DialogsProvider::openFileGenericDialog( intf_dialog_args_t *p_arg )
333 {
334     if( p_arg == NULL )
335     {
336         msg_Warn( p_intf, "openFileGenericDialog() called with NULL arg" );
337         return;
338     }
339
340     /* Replace the extensions to a Qt format */
341     int i = 0;
342     QString extensions = qfu( p_arg->psz_extensions );
343     while ( ( i = extensions.indexOf( "|", i ) ) != -1 )
344     {
345         if( ( extensions.count( "|" ) % 2 ) == 0 )
346             extensions.replace( i, 1, ");;" );
347         else
348             extensions.replace( i, 1, "(" );
349     }
350     extensions.replace( ";*", " *" );
351     extensions.append( ")" );
352
353     /* Save */
354     if( p_arg->b_save )
355     {
356         QString file = QFileDialog::getSaveFileName( NULL,
357                                         qfu( p_arg->psz_title ),
358                                         p_intf->p_sys->filepath, extensions );
359         if( !file.isEmpty() )
360         {
361             p_arg->i_results = 1;
362             p_arg->psz_results = (char **)malloc( p_arg->i_results * sizeof( char * ) );
363             p_arg->psz_results[0] = strdup( qtu( toNativeSepNoSlash( file ) ) );
364         }
365         else
366             p_arg->i_results = 0;
367     }
368     else /* non-save mode */
369     {
370         QStringList files = QFileDialog::getOpenFileNames( NULL,
371                 qfu( p_arg->psz_title ), p_intf->p_sys->filepath,
372                 extensions );
373         p_arg->i_results = files.count();
374         p_arg->psz_results = (char **)malloc( p_arg->i_results * sizeof( char * ) );
375         i = 0;
376         foreach( const QString &file, files )
377             p_arg->psz_results[i++] = strdup( qtu( toNativeSepNoSlash( file ) ) );
378         if(i == 0)
379             p_intf->p_sys->filepath = QString::fromLatin1("");
380         else
381             p_intf->p_sys->filepath = qfu( p_arg->psz_results[i-1] );
382     }
383
384     /* Callback */
385     if( p_arg->pf_callback )
386         p_arg->pf_callback( p_arg );
387
388     /* Clean afterwards */
389     if( p_arg->psz_results )
390     {
391         for( i = 0; i < p_arg->i_results; i++ )
392             free( p_arg->psz_results[i] );
393         free( p_arg->psz_results );
394     }
395     free( p_arg->psz_title );
396     free( p_arg->psz_extensions );
397     free( p_arg );
398 }
399 /****************************************************************************
400  * All the open/add stuff
401  * Open Dialog first - Simple Open then
402  ****************************************************************************/
403
404 void DialogsProvider::openDialog( int i_tab )
405 {
406     OpenDialog::getInstance( p_intf->p_sys->p_mi , p_intf )->showTab( i_tab );
407 }
408 void DialogsProvider::openDialog()
409 {
410     openDialog( OPEN_FILE_TAB );
411 }
412 void DialogsProvider::openFileDialog()
413 {
414     openDialog( OPEN_FILE_TAB );
415 }
416 void DialogsProvider::openDiscDialog()
417 {
418     openDialog( OPEN_DISC_TAB );
419 }
420 void DialogsProvider::openNetDialog()
421 {
422     openDialog( OPEN_NETWORK_TAB );
423 }
424 void DialogsProvider::openCaptureDialog()
425 {
426     openDialog( OPEN_CAPTURE_TAB );
427 }
428
429 /* Same as the open one, but force the enqueue */
430 void DialogsProvider::PLAppendDialog( int tab )
431 {
432     OpenDialog::getInstance( p_intf->p_sys->p_mi, p_intf, false,
433                              OPEN_AND_ENQUEUE )->showTab( tab );
434 }
435
436 void DialogsProvider::MLAppendDialog( int tab )
437 {
438     OpenDialog::getInstance( p_intf->p_sys->p_mi, p_intf, false,
439                             OPEN_AND_ENQUEUE, false, false )
440                                     ->showTab( tab );
441 }
442
443 /**
444  * Simple open
445  ***/
446 QStringList DialogsProvider::showSimpleOpen( const QString& help,
447                                              int filters,
448                                              const QString& path )
449 {
450     QString fileTypes = "";
451     if( filters & EXT_FILTER_MEDIA ) {
452         ADD_EXT_FILTER( fileTypes, EXTENSIONS_MEDIA );
453     }
454     if( filters & EXT_FILTER_VIDEO ) {
455         ADD_EXT_FILTER( fileTypes, EXTENSIONS_VIDEO );
456     }
457     if( filters & EXT_FILTER_AUDIO ) {
458         ADD_EXT_FILTER( fileTypes, EXTENSIONS_AUDIO );
459     }
460     if( filters & EXT_FILTER_PLAYLIST ) {
461         ADD_EXT_FILTER( fileTypes, EXTENSIONS_PLAYLIST );
462     }
463     if( filters & EXT_FILTER_SUBTITLE ) {
464         ADD_EXT_FILTER( fileTypes, EXTENSIONS_SUBTITLE );
465     }
466     ADD_EXT_FILTER( fileTypes, EXTENSIONS_ALL );
467     fileTypes.replace( ";*", " *");
468
469     QStringList files = QFileDialog::getOpenFileNames( NULL,
470         help.isEmpty() ? qtr(I_OP_SEL_FILES ) : help,
471         path.isEmpty() ? p_intf->p_sys->filepath : path,
472         fileTypes );
473
474     if( !files.isEmpty() ) savedirpathFromFile( files.last() );
475
476     return files;
477 }
478
479 /**
480  * Open a file,
481  * pl helps you to choose from playlist or media library,
482  * go to start or enqueue
483  **/
484 void DialogsProvider::addFromSimple( bool pl, bool go)
485 {
486     QStringList files = DialogsProvider::showSimpleOpen();
487
488     bool first = go;
489     files.sort();
490     foreach( const QString &file, files )
491     {
492         QString url = toURI( toNativeSeparators( file ) );
493         Open::openMRL( p_intf, url, first, pl);
494         first = false;
495     }
496 }
497
498 void DialogsProvider::simpleOpenDialog()
499 {
500     addFromSimple( true, true ); /* Playlist and Go */
501 }
502
503 /* Url & Clipboard */
504 /**
505  * Open a MRL.
506  * If the clipboard contains URLs, the first is automatically 'preselected'.
507  **/
508 void DialogsProvider::openUrlDialog()
509 {
510     OpenUrlDialog oud( p_intf );
511     if( oud.exec() != QDialog::Accepted )
512         return;
513
514     QString url = oud.url();
515     if( url.isEmpty() )
516         return;
517
518     if( !url.contains( qfu( "://" ) ) )
519     {
520         char *uri = vlc_path2uri( qtu( url ), NULL );
521         if( uri == NULL )
522             return;
523         url = qfu(uri);
524         free( uri );
525     }
526
527     Open::openMRL( p_intf, qtu(url), !oud.shouldEnqueue() );
528 }
529
530 /* Directory */
531 /**
532  * Open a directory,
533  * pl helps you to choose from playlist or media library,
534  * go to start or enqueue
535  **/
536 static void openDirectory( intf_thread_t *p_intf, bool pl, bool go )
537 {
538     QString uri = DialogsProvider::getDirectoryDialog( p_intf );
539     if( !uri.isEmpty() )
540         Open::openMRL( p_intf, uri, go, pl );
541 }
542
543 QString DialogsProvider::getDirectoryDialog( intf_thread_t *p_intf )
544 {
545     QString dir = QFileDialog::getExistingDirectory( NULL,
546             qtr( I_OP_DIR_WINTITLE ), p_intf->p_sys->filepath );
547
548     if( dir.isEmpty() ) return QString();
549
550     p_intf->p_sys->filepath = dir;
551
552     const char *scheme = "directory";
553     if( dir.endsWith( DIR_SEP "VIDEO_TS", Qt::CaseInsensitive ) )
554         scheme = "dvd";
555     else if( dir.endsWith( DIR_SEP "BDMV", Qt::CaseInsensitive ) )
556     {
557         scheme = "bluray";
558         dir.remove( "BDMV" );
559     }
560
561     char *uri = vlc_path2uri( qtu( toNativeSeparators( dir ) ), scheme );
562     if( unlikely(uri == NULL) )
563         return QString();
564
565     dir = qfu( uri );
566     free( uri );
567
568     RecentsMRL::getInstance( p_intf )->addRecent( dir );
569
570     return dir;
571 }
572
573 void DialogsProvider::PLOpenDir()
574 {
575     openDirectory( p_intf, true, true );
576 }
577
578 void DialogsProvider::PLAppendDir()
579 {
580     openDirectory( p_intf, true, false );
581 }
582
583 /****************
584  * Playlist     *
585  ****************/
586 void DialogsProvider::openAPlaylist()
587 {
588     QStringList files = showSimpleOpen( qtr( "Open playlist..." ),
589                                         EXT_FILTER_PLAYLIST );
590     foreach( const QString &file, files )
591     {
592         playlist_Import( THEPL, qtu( toNativeSeparators( file ) ) );
593     }
594 }
595
596 void DialogsProvider::saveAPlaylist(playlist_t *p_playlist, playlist_item_t *p_node)
597 {
598     static const struct
599     {
600         char filter_name[14];
601         char filter_patterns[5];
602         char module[12];
603     } types[] = {
604         { N_("XSPF playlist"), "xspf", "export-xspf", },
605         { N_("M3U playlist"),  "m3u",  "export-m3u", },
606         { N_("M3U8 playlist"), "m3u8", "export-m3u8", },
607         { N_("HTML playlist"), "html", "export-html", },
608     };
609
610     QStringList filters;
611     QString ext = getSettings()->value( "last-playlist-ext" ).toString();
612
613     for( size_t i = 0; i < sizeof (types) / sizeof (types[0]); i++ )
614     {
615         QString tmp = qfu( vlc_gettext( types[i].filter_name ) ) + " (*." + types[i].filter_patterns + ")";
616         if( ext == qfu( types[i].filter_patterns ) )
617             filters.insert( 0, tmp );
618         else
619             filters.append( tmp );
620     }
621
622     QString selected;
623     QString file = QFileDialog::getSaveFileName( NULL,
624                                                  qtr( "Save playlist as..." ),
625                                                  p_intf->p_sys->filepath, filters.join( ";;" ),
626                                                  &selected );
627     const char *psz_selected_module = NULL;
628     const char *psz_last_playlist_ext = NULL;
629
630     if( file.isEmpty() )
631         return;
632
633     /* First test if the file extension is set, and different to selected filter */
634     for( size_t i = 0; i < sizeof (types) / sizeof (types[0]); i++)
635     {
636         if ( file.endsWith( QString( "." ) + qfu( types[i].filter_patterns ) ) )
637         {
638             psz_selected_module = types[i].module;
639             psz_last_playlist_ext = types[i].filter_patterns;
640             break;
641         }
642     }
643
644     /* otherwise apply the selected extension */
645     if ( !psz_last_playlist_ext )
646     {
647         for( size_t i = 0; i < sizeof (types) / sizeof (types[0]); i++)
648         {
649             if ( selected.startsWith( qfu( vlc_gettext( types[i].filter_name ) ) ) )
650             {
651                 psz_selected_module = types[i].module;
652                 psz_last_playlist_ext = types[i].filter_patterns;
653                 /* Fix file extension */
654                 file = file.append( QString( "." ) + qfu( psz_last_playlist_ext ) );
655                 break;
656             }
657         }
658     }
659
660     if ( psz_selected_module )
661     {
662         playlist_Export( p_playlist, qtu( toNativeSeparators( file ) ),
663                          p_node, psz_selected_module );
664         getSettings()->setValue( "last-playlist-ext", psz_last_playlist_ext );
665     }
666 }
667
668 void DialogsProvider::savePlayingToPlaylist()
669 {
670     saveAPlaylist(THEPL, THEPL->p_playing);
671 }
672
673 void DialogsProvider::saveRecentsToPlaylist()
674 {
675     playlist_item_t *p_node_recents = RecentsMRL::getInstance(p_intf)->toPlaylist(0);
676
677     if (p_node_recents == NULL)
678     {
679         msg_Warn(p_intf, "cannot create playlist from recents");
680         return;
681     }
682
683     saveAPlaylist(THEPL, p_node_recents);
684     playlist_NodeDelete(THEPL, p_node_recents, true, false);
685 }
686
687 /****************************************************************************
688  * Sout emulation
689  ****************************************************************************/
690
691 void DialogsProvider::streamingDialog( QWidget *parent,
692                                        const QString& mrl,
693                                        bool b_transcode_only,
694                                        QStringList options )
695 {
696     QString soutoption;
697
698     /* Stream */
699     if( !b_transcode_only )
700     {
701         SoutDialog *s = new SoutDialog( parent, p_intf, mrl );
702         s->setAttribute( Qt::WA_QuitOnClose, false ); // See #4883
703         if( s->exec() == QDialog::Accepted )
704         {
705             soutoption = s->getMrl();
706             delete s;
707         }
708         else
709         {
710             delete s; return;
711         }
712     } else {
713     /* Convert */
714         ConvertDialog *s = new ConvertDialog( parent, p_intf, mrl );
715         s->setAttribute( Qt::WA_QuitOnClose, false ); // See #4883
716         if( s->exec() == QDialog::Accepted )
717         {
718             soutoption = s->getMrl();
719             delete s;
720         }
721         else
722         {
723             delete s; return;
724         }
725     }
726
727     /* Get SoutMRL */
728     if( !soutoption.isEmpty() )
729     {
730         options += soutoption.split( " :");
731
732         Open::openMRLwithOptions( p_intf, mrl, &options, true, true, _("Streaming") );
733     }
734 }
735
736 void DialogsProvider::openAndStreamingDialogs()
737 {
738     OpenDialog::getInstance( p_intf->p_sys->p_mi, p_intf, false, OPEN_AND_STREAM )
739                                 ->showTab( OPEN_FILE_TAB );
740 }
741
742 void DialogsProvider::openAndTranscodingDialogs()
743 {
744     OpenDialog::getInstance( p_intf->p_sys->p_mi , p_intf, false, OPEN_AND_SAVE )
745                                 ->showTab( OPEN_FILE_TAB );
746 }
747
748 void DialogsProvider::loadSubtitlesFile()
749 {
750     input_thread_t *p_input = THEMIM->getInput();
751     if( !p_input ) return;
752
753     input_item_t *p_item = input_GetItem( p_input );
754     if( !p_item ) return;
755
756     char *path = input_item_GetURI( p_item );
757     char *path2 = NULL;
758     if( path )
759     {
760         path2 = make_path( path );
761         free( path );
762         if( path2 )
763         {
764             char *sep = strrchr( path2, DIR_SEP_CHAR );
765             if( sep ) *sep = '\0';
766         }
767     }
768
769     QStringList qsl = showSimpleOpen( qtr( "Open subtitles..." ),
770                                       EXT_FILTER_SUBTITLE,
771                                       qfu( path2 ) );
772     free( path2 );
773     foreach( const QString &qsFile, qsl )
774     {
775         if( input_AddSubtitleOSD( p_input, qtu( toNativeSeparators( qsFile ) ),
776                     true, true ) )
777             msg_Warn( p_intf, "unable to load subtitles from '%s'",
778                       qtu( qsFile ) );
779     }
780 }
781
782
783 /****************************************************************************
784  * Menus
785  ****************************************************************************/
786
787 void DialogsProvider::menuAction( QObject *data )
788 {
789     VLCMenuBar::DoAction( data );
790 }
791
792 void DialogsProvider::menuUpdateAction( QObject *data )
793 {
794     MenuFunc *func = qobject_cast<MenuFunc *>(data);
795     assert( func );
796     func->doFunc( p_intf );
797 }
798
799 void DialogsProvider::SDMenuAction( const QString& data )
800 {
801     if( !playlist_IsServicesDiscoveryLoaded( THEPL, qtu( data ) ) )
802         playlist_ServicesDiscoveryAdd( THEPL, qtu( data ) );
803     else
804         playlist_ServicesDiscoveryRemove( THEPL, qtu( data ) );
805 }
806
807 void DialogsProvider::sendKey( int key )
808 {
809      // translate from a vlc keycode into a Qt sequence
810      QKeySequence kseq0( VLCKeyToString( key, true ) );
811
812      if( popupMenu == NULL )
813      {
814          // make sure at least a non visible popupmenu is available
815          popupMenu = VLCMenuBar::PopupMenu( p_intf, false );
816          if( unlikely( popupMenu == NULL ) )
817              return;
818      }
819
820      // test against key accelerators from the popupmenu
821      QList<QAction*> actions = popupMenu->findChildren<QAction*>();
822      for( int i = 0; i < actions.size(); i++ )
823      {
824          QAction* action = actions.at(i);
825          QKeySequence kseq = action->shortcut();
826          if( kseq == kseq0 )
827          {
828              action->trigger();
829              return;
830          }
831      }
832
833      // forward key to vlc core when not a key accelerator
834      var_SetInteger( p_intf->p_libvlc, "key-pressed", key );
835 }