qt: move media info dialogs component to its own folder
[vlc.git] / modules / gui / qt / dialogs_provider.cpp
blob827641e6388787e7a1232312e8dbfd7fbc00fe6a
1 /*****************************************************************************
2 * dialogs_provider.cpp : Dialog Provider
3 *****************************************************************************
4 * Copyright (C) 2006-2009 the VideoLAN team
6 * Authors: Clément Stenac <zorglub@videolan.org>
7 * Jean-Baptiste Kempf <jb@videolan.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 #ifdef HAVE_CONFIG_H
25 # include "config.h"
26 #endif
28 #include <vlc_intf_strings.h>
30 #include "qt.hpp"
31 #include "dialogs_provider.hpp"
32 #include "player/player_controller.hpp" /* Load Subtitles */
33 #include "playlist/playlist_controller.hpp"
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"
40 /* The dialogs */
41 #include "dialogs/bookmarks.hpp"
42 #include "dialogs/preferences/preferences.hpp"
43 #include "dialogs/mediainfo/mediainfo.hpp"
44 #include "dialogs/messages.hpp"
45 #include "dialogs/extended.hpp"
46 #include "dialogs/vlm.hpp"
47 #include "dialogs/sout/sout.hpp"
48 #include "dialogs/sout/convert.hpp"
49 #include "dialogs/open.hpp"
50 #include "dialogs/openurl.hpp"
51 #include "dialogs/help/help.hpp"
52 #include "dialogs/gototime.hpp"
53 #include "dialogs/podcast_configuration.hpp"
54 #include "dialogs/toolbar.hpp"
55 #include "dialogs/toolbareditor.hpp"
56 #include "dialogs/plugins/plugins.hpp"
57 #include "dialogs/epg/epg.hpp"
58 #include "dialogs/errors.hpp"
60 #include <QEvent>
61 #include <QApplication>
62 #include <QSignalMapper>
63 #include <QFileDialog>
64 #include <QUrl>
66 #define I_OP_DIR_WINTITLE I_DIR_OR_FOLDER( N_("Open Directory"), \
67 N_("Open Folder") )
69 DialogsProvider* DialogsProvider::instance = NULL;
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 )
78 b_isDying = false;
81 DialogsProvider::~DialogsProvider()
83 MediaInfoDialog::killInstance();
84 MessagesDialog::killInstance();
85 BookmarksDialog::killInstance();
86 #ifdef ENABLE_VLM
87 VLMDialog::killInstance();
88 #endif
89 HelpDialog::killInstance();
90 #ifdef UPDATE_CHECK
91 UpdateDialog::killInstance();
92 #endif
93 PluginDialog::killInstance();
94 EpgDialog::killInstance();
96 delete popupMenu;
97 delete videoPopupMenu;
98 delete audioPopupMenu;
99 delete miscPopupMenu;
101 /* free parentless menus */
102 VLCMenuBar::freeRecentsMenu();
103 VLCMenuBar::freeRendererMenu();
106 QString DialogsProvider::getSaveFileName( QWidget *parent,
107 const QString &caption,
108 const QUrl &dir,
109 const QString &filter,
110 QString *selectedFilter )
112 const QStringList schemes = QStringList(QStringLiteral("file"));
113 return QFileDialog::getSaveFileUrl( parent, caption, dir, filter, selectedFilter, QFileDialog::Options(), schemes).toLocalFile();
116 void DialogsProvider::quit()
118 b_isDying = true;
119 libvlc_Quit( vlc_object_instance(p_intf) );
122 void DialogsProvider::customEvent( QEvent *event )
124 if( event->type() == DialogEvent::DialogEvent_Type )
126 DialogEvent *de = static_cast<DialogEvent*>(event);
127 switch( de->i_dialog )
129 case INTF_DIALOG_FILE_SIMPLE:
130 case INTF_DIALOG_FILE:
131 openDialog(); break;
132 case INTF_DIALOG_FILE_GENERIC:
133 openFileGenericDialog( de->p_arg ); break;
134 case INTF_DIALOG_DISC:
135 openDiscDialog(); break;
136 case INTF_DIALOG_NET:
137 openNetDialog(); break;
138 case INTF_DIALOG_SAT:
139 case INTF_DIALOG_CAPTURE:
140 openCaptureDialog(); break;
141 case INTF_DIALOG_DIRECTORY:
142 PLAppendDir(); break;
143 case INTF_DIALOG_PLAYLIST:
144 //FIXME
145 //playlistDialog(); break;
146 break;
147 case INTF_DIALOG_MESSAGES:
148 messagesDialog(); break;
149 case INTF_DIALOG_FILEINFO:
150 mediaInfoDialog(); break;
151 case INTF_DIALOG_PREFS:
152 prefsDialog(); break;
153 case INTF_DIALOG_BOOKMARKS:
154 bookmarksDialog(); break;
155 case INTF_DIALOG_EXTENDED:
156 extendedDialog(); break;
157 case INTF_DIALOG_SENDKEY:
158 sendKey( de->i_arg ); break;
159 #ifdef ENABLE_VLM
160 case INTF_DIALOG_VLM:
161 vlmDialog(); break;
162 #endif
163 case INTF_DIALOG_POPUPMENU:
165 delete popupMenu; popupMenu = NULL;
166 bool show = (de->i_arg != 0);
167 if( show )
169 if( p_intf->p_sys->p_mi )
170 p_intf->p_sys->p_mi->popupMenu( show );
171 else
173 //popping a QMenu prevents mouse release events to be received,
174 //this ensures the coherency of the vout mouse state.
175 emit releaseMouseEvents();
176 popupMenu = VLCMenuBar::PopupMenu( p_intf, show );
179 break;
181 case INTF_DIALOG_AUDIOPOPUPMENU:
183 delete audioPopupMenu; audioPopupMenu = NULL;
184 bool show = (de->i_arg != 0);
185 if( show )
186 audioPopupMenu = VLCMenuBar::AudioPopupMenu( p_intf, show );
187 break;
189 case INTF_DIALOG_VIDEOPOPUPMENU:
191 delete videoPopupMenu; videoPopupMenu = NULL;
192 bool show = (de->i_arg != 0);
193 if( show )
194 videoPopupMenu = VLCMenuBar::VideoPopupMenu( p_intf, show );
195 break;
197 case INTF_DIALOG_MISCPOPUPMENU:
199 delete miscPopupMenu; miscPopupMenu = NULL;
200 bool show = (de->i_arg != 0);
201 if( show )
202 miscPopupMenu = VLCMenuBar::MiscPopupMenu( p_intf, show );
203 break;
205 case INTF_DIALOG_WIZARD:
206 case INTF_DIALOG_STREAMWIZARD:
207 openAndStreamingDialogs(); break;
208 #ifdef UPDATE_CHECK
209 case INTF_DIALOG_UPDATEVLC:
210 updateDialog(); break;
211 #endif
212 case INTF_DIALOG_EXIT:
213 quit(); break;
214 default:
215 msg_Warn( p_intf, "unimplemented dialog" );
220 /****************************************************************************
221 * Individual simple dialogs
222 ****************************************************************************/
223 const QEvent::Type DialogEvent::DialogEvent_Type =
224 (QEvent::Type)QEvent::registerEventType();
226 void DialogsProvider::prefsDialog()
228 PrefsDialog *p = new PrefsDialog( (QWidget *)p_intf->p_sys->p_mi, p_intf );
229 p->toggleVisible();
232 void DialogsProvider::extendedDialog()
234 ExtendedDialog *extDialog = ExtendedDialog::getInstance(p_intf );
236 if( !extDialog->isVisible() || /* Hidden */
237 extDialog->currentTab() != 0 ) /* wrong tab */
238 extDialog->showTab( 0 );
239 else
240 extDialog->hide();
243 void DialogsProvider::synchroDialog()
245 ExtendedDialog *extDialog = ExtendedDialog::getInstance(p_intf );
247 if( !extDialog->isVisible() || /* Hidden */
248 extDialog->currentTab() != 2 ) /* wrong tab */
249 extDialog->showTab( 2 );
250 else
251 extDialog->hide();
254 void DialogsProvider::messagesDialog()
256 MessagesDialog::getInstance( p_intf )->toggleVisible();
259 void DialogsProvider::gotoTimeDialog()
261 GotoTimeDialog::getInstance( p_intf )->toggleVisible();
264 #ifdef ENABLE_VLM
265 void DialogsProvider::vlmDialog()
267 VLMDialog::getInstance( p_intf )->toggleVisible();
269 #endif
271 void DialogsProvider::helpDialog()
273 HelpDialog::getInstance( p_intf )->toggleVisible();
276 #ifdef UPDATE_CHECK
277 void DialogsProvider::updateDialog()
279 UpdateDialog::getInstance( p_intf )->toggleVisible();
281 #endif
283 void DialogsProvider::aboutDialog()
285 AboutDialog::getInstance( p_intf )->toggleVisible();
288 void DialogsProvider::mediaInfoDialog()
290 MediaInfoDialog *dialog = MediaInfoDialog::getInstance( p_intf );
291 if( !dialog->isVisible() || dialog->currentTab() != MediaInfoDialog::META_PANEL )
292 dialog->showTab( MediaInfoDialog::META_PANEL );
293 else
294 dialog->hide();
297 void DialogsProvider::mediaCodecDialog()
299 MediaInfoDialog *dialog = MediaInfoDialog::getInstance( p_intf );
300 if( !dialog->isVisible() || dialog->currentTab() != MediaInfoDialog::INFO_PANEL )
301 dialog->showTab( MediaInfoDialog::INFO_PANEL );
302 else
303 dialog->hide();
306 void DialogsProvider::bookmarksDialog()
308 BookmarksDialog::getInstance( p_intf )->toggleVisible();
311 void DialogsProvider::podcastConfigureDialog()
313 PodcastConfigDialog::getInstance( p_intf )->toggleVisible();
316 void DialogsProvider::toolbarDialog()
318 ToolbarEditorDialog *toolbarEditor = new ToolbarEditorDialog( (QWidget *)p_intf->p_sys->p_mi, p_intf);
319 if( toolbarEditor->exec() == QDialog::Accepted )
320 emit toolBarConfUpdated();
321 delete toolbarEditor;
324 void DialogsProvider::pluginDialog()
326 PluginDialog::getInstance( p_intf )->toggleVisible();
329 void DialogsProvider::epgDialog()
331 EpgDialog::getInstance( p_intf )->toggleVisible();
334 void DialogsProvider::setPopupMenu()
336 delete popupMenu;
337 popupMenu = VLCMenuBar::PopupMenu( p_intf, true );
340 void DialogsProvider::destroyPopupMenu()
342 delete popupMenu;
343 popupMenu = NULL;
346 /* Generic open file */
347 void DialogsProvider::openFileGenericDialog( intf_dialog_args_t *p_arg )
349 if( p_arg == NULL )
351 msg_Warn( p_intf, "openFileGenericDialog() called with NULL arg" );
352 return;
355 /* Replace the extensions to a Qt format */
356 int i = 0;
357 QString extensions = qfu( p_arg->psz_extensions );
358 while ( ( i = extensions.indexOf( "|", i ) ) != -1 )
360 if( ( extensions.count( "|" ) % 2 ) == 0 )
361 extensions.replace( i, 1, ");;" );
362 else
363 extensions.replace( i, 1, "(" );
365 extensions.replace( ";*", " *" );
366 extensions.append( ")" );
368 /* Save */
369 if( p_arg->b_save )
371 QString file = getSaveFileName( NULL,
372 qfu( p_arg->psz_title ),
373 p_intf->p_sys->filepath, extensions );
374 if( !file.isEmpty() )
376 p_arg->i_results = 1;
377 p_arg->psz_results = (char **)vlc_alloc( p_arg->i_results, sizeof( char * ) );
378 p_arg->psz_results[0] = strdup( qtu( toNativeSepNoSlash( file ) ) );
380 else
381 p_arg->i_results = 0;
383 else /* non-save mode */
385 QList<QUrl> urls = QFileDialog::getOpenFileUrls( NULL, qfu( p_arg->psz_title ),
386 p_intf->p_sys->filepath, extensions );
387 p_arg->i_results = urls.count();
388 p_arg->psz_results = (char **)vlc_alloc( p_arg->i_results, sizeof( char * ) );
389 i = 0;
390 foreach( const QUrl &uri, urls )
391 p_arg->psz_results[i++] = strdup( uri.toEncoded().constData() );
392 if( !urls.isEmpty() )
393 p_intf->p_sys->filepath = urls.last();
396 /* Callback */
397 if( p_arg->pf_callback )
398 p_arg->pf_callback( p_arg );
400 /* Clean afterwards */
401 if( p_arg->psz_results )
403 for( i = 0; i < p_arg->i_results; i++ )
404 free( p_arg->psz_results[i] );
405 free( p_arg->psz_results );
407 free( p_arg->psz_title );
408 free( p_arg->psz_extensions );
409 free( p_arg );
411 /****************************************************************************
412 * All the open/add stuff
413 * Open Dialog first - Simple Open then
414 ****************************************************************************/
416 void DialogsProvider::openDialog( int i_tab )
418 OpenDialog::getInstance( p_intf->p_sys->p_mi , p_intf )->showTab( i_tab );
420 void DialogsProvider::openDialog()
422 openDialog( OPEN_FILE_TAB );
424 void DialogsProvider::openFileDialog()
426 openDialog( OPEN_FILE_TAB );
428 void DialogsProvider::openDiscDialog()
430 openDialog( OPEN_DISC_TAB );
432 void DialogsProvider::openNetDialog()
434 openDialog( OPEN_NETWORK_TAB );
436 void DialogsProvider::openCaptureDialog()
438 openDialog( OPEN_CAPTURE_TAB );
441 /* Same as the open one, but force the enqueue */
442 void DialogsProvider::PLAppendDialog( int tab )
444 OpenDialog::getInstance( p_intf->p_sys->p_mi, p_intf, false,
445 OPEN_AND_ENQUEUE )->showTab( tab );
449 * Simple open
450 ***/
451 QStringList DialogsProvider::showSimpleOpen( const QString& help,
452 int filters,
453 const QUrl& path )
455 QString fileTypes = "";
456 if( filters & EXT_FILTER_MEDIA ) {
457 ADD_EXT_FILTER( fileTypes, EXTENSIONS_MEDIA );
459 if( filters & EXT_FILTER_VIDEO ) {
460 ADD_EXT_FILTER( fileTypes, EXTENSIONS_VIDEO );
462 if( filters & EXT_FILTER_AUDIO ) {
463 ADD_EXT_FILTER( fileTypes, EXTENSIONS_AUDIO );
465 if( filters & EXT_FILTER_PLAYLIST ) {
466 ADD_EXT_FILTER( fileTypes, EXTENSIONS_PLAYLIST );
468 if( filters & EXT_FILTER_SUBTITLE ) {
469 ADD_EXT_FILTER( fileTypes, EXTENSIONS_SUBTITLE );
471 ADD_EXT_FILTER( fileTypes, EXTENSIONS_ALL );
472 fileTypes.replace( ";*", " *");
473 fileTypes.chop(2); //remove trailling ";;"
475 QList<QUrl> urls = QFileDialog::getOpenFileUrls( NULL,
476 help.isEmpty() ? qtr(I_OP_SEL_FILES ) : help,
477 path.isEmpty() ? p_intf->p_sys->filepath : path,
478 fileTypes );
480 if( !urls.isEmpty() )
481 p_intf->p_sys->filepath = urls.last();
483 QStringList res;
484 foreach( const QUrl &url, urls )
485 res << url.toEncoded();
487 return res;
490 void DialogsProvider::simpleOpenDialog()
492 QStringList urls = DialogsProvider::showSimpleOpen();
494 bool first = true;
495 urls.sort();
496 foreach( const QString &url, urls )
498 Open::openMRL( p_intf, url, first );
499 first = false;
503 /* Url & Clipboard */
505 * Open a MRL.
506 * If the clipboard contains URLs, the first is automatically 'preselected'.
508 void DialogsProvider::openUrlDialog()
510 OpenUrlDialog oud( p_intf );
511 if( oud.exec() != QDialog::Accepted )
512 return;
514 QString url = oud.url();
515 if( url.isEmpty() )
516 return;
518 if( !url.contains( qfu( "://" ) ) )
520 char *uri = vlc_path2uri( qtu( url ), NULL );
521 if( uri == NULL )
522 return;
523 url = qfu(uri);
524 free( uri );
527 Open::openMRL( p_intf, qtu(url), !oud.shouldEnqueue() );
530 /* Directory */
532 * Open a directory,
533 * pl helps you to choose from playlist or media library,
534 * go to start or enqueue
536 static void openDirectory( intf_thread_t *p_intf, bool go )
538 QString uri = DialogsProvider::getDirectoryDialog( p_intf );
539 if( !uri.isEmpty() )
540 Open::openMRL( p_intf, uri, go );
543 QString DialogsProvider::getDirectoryDialog( intf_thread_t *p_intf )
545 const QStringList schemes = QStringList(QStringLiteral("file"));
546 QUrl dirurl = QFileDialog::getExistingDirectoryUrl( NULL,
547 qtr( I_OP_DIR_WINTITLE ), p_intf->p_sys->filepath,
548 QFileDialog::ShowDirsOnly, schemes );
550 if( dirurl.isEmpty() ) return QString();
552 p_intf->p_sys->filepath = dirurl;
554 QString dir = dirurl.toLocalFile();
555 const char *scheme = "directory";
556 if( dir.endsWith( DIR_SEP "VIDEO_TS", Qt::CaseInsensitive ) )
557 scheme = "dvd";
558 else if( dir.endsWith( DIR_SEP "BDMV", Qt::CaseInsensitive ) )
560 scheme = "bluray";
561 dir.remove( "BDMV" );
564 char *uri = vlc_path2uri( qtu( toNativeSeparators( dir ) ), scheme );
565 if( unlikely(uri == NULL) )
566 return QString();
568 dir = qfu( uri );
569 free( uri );
571 return dir;
574 void DialogsProvider::PLOpenDir()
576 openDirectory( p_intf, true );
579 void DialogsProvider::PLAppendDir()
581 openDirectory( p_intf, false );
584 /****************
585 * Playlist *
586 ****************/
587 void DialogsProvider::savePlayingToPlaylist()
589 static const struct
591 char filter_name[14];
592 char filter_patterns[5];
593 char module[12];
594 } types[] = {
595 { N_("XSPF playlist"), "xspf", "export-xspf", },
596 { N_("M3U playlist"), "m3u", "export-m3u", },
597 { N_("M3U8 playlist"), "m3u8", "export-m3u8", },
598 { N_("HTML playlist"), "html", "export-html", },
601 QStringList filters;
602 QString ext = getSettings()->value( "last-playlist-ext" ).toString();
604 for( size_t i = 0; i < sizeof (types) / sizeof (types[0]); i++ )
606 QString tmp = qfu( vlc_gettext( types[i].filter_name ) ) + " (*." + types[i].filter_patterns + ")";
607 if( ext == qfu( types[i].filter_patterns ) )
608 filters.insert( 0, tmp );
609 else
610 filters.append( tmp );
613 QString selected;
614 QString file = getSaveFileName( NULL,
615 qtr( "Save playlist as..." ),
616 p_intf->p_sys->filepath, filters.join( ";;" ),
617 &selected );
618 const char *psz_selected_module = NULL;
619 const char *psz_last_playlist_ext = NULL;
621 if( file.isEmpty() )
622 return;
624 /* First test if the file extension is set, and different to selected filter */
625 for( size_t i = 0; i < sizeof (types) / sizeof (types[0]); i++)
627 if ( file.endsWith( QString( "." ) + qfu( types[i].filter_patterns ) ) )
629 psz_selected_module = types[i].module;
630 psz_last_playlist_ext = types[i].filter_patterns;
631 break;
635 /* otherwise apply the selected extension */
636 if ( !psz_last_playlist_ext )
638 for( size_t i = 0; i < sizeof (types) / sizeof (types[0]); i++)
640 if ( selected.startsWith( qfu( vlc_gettext( types[i].filter_name ) ) ) )
642 psz_selected_module = types[i].module;
643 psz_last_playlist_ext = types[i].filter_patterns;
644 /* Fix file extension */
645 file = file.append( QString( "." ) + qfu( psz_last_playlist_ext ) );
646 break;
651 if ( psz_selected_module )
653 vlc_playlist_Lock( p_intf->p_sys->p_playlist );
654 vlc_playlist_Export( p_intf->p_sys->p_playlist,
655 qtu( toNativeSeparators( file ) ),
656 psz_selected_module );
657 vlc_playlist_Unlock( p_intf->p_sys->p_playlist );
658 getSettings()->setValue( "last-playlist-ext", psz_last_playlist_ext );
662 /****************************************************************************
663 * Sout emulation
664 ****************************************************************************/
666 void DialogsProvider::streamingDialog( QWidget *parent,
667 const QStringList& mrls,
668 bool b_transcode_only,
669 QStringList options )
671 QStringList outputMRLs;
673 /* Stream */
674 // Does streaming multiple files make sense? I suppose so, just stream one
675 // after the other, but not at the moment.
676 if( !b_transcode_only )
678 SoutDialog *s = new SoutDialog( parent, p_intf, mrls[0] );
679 s->setAttribute( Qt::WA_QuitOnClose, false ); // See #4883
680 if( s->exec() == QDialog::Accepted )
682 outputMRLs.append(s->getChain());
683 delete s;
685 else
687 delete s; return;
689 } else {
690 /* Convert */
691 ConvertDialog *s = new ConvertDialog( parent, p_intf, mrls );
692 s->setAttribute( Qt::WA_QuitOnClose, false ); // See #4883
693 if( s->exec() == QDialog::Accepted )
695 /* Clear the playlist. This is because we're going to be populating
696 it */
697 THEMPL->clear();
698 outputMRLs = s->getMrls();
699 delete s;
701 else
703 delete s; return;
707 /* Get SoutChain(s) */
708 if( !outputMRLs.isEmpty() )
710 QVector<vlc::playlist::Media> outputMedias;
711 std::transform(outputMRLs.cbegin(), outputMRLs.cend(), std::back_inserter(outputMedias), [&](const QString& mrl) {
712 QString title = "Converting " + mrl;
713 return vlc::playlist::Media(mrl, title, &options);
715 THEMPL->append(outputMedias, true);
719 void DialogsProvider::openAndStreamingDialogs()
721 OpenDialog::getInstance( p_intf->p_sys->p_mi, p_intf, false, OPEN_AND_STREAM )
722 ->showTab( OPEN_FILE_TAB );
725 void DialogsProvider::openAndTranscodingDialogs()
727 OpenDialog::getInstance( p_intf->p_sys->p_mi , p_intf, false, OPEN_AND_SAVE )
728 ->showTab( OPEN_FILE_TAB );
731 void DialogsProvider::loadSubtitlesFile()
733 input_item_t *p_item = THEMIM->getInput();
734 if( !p_item ) return;
736 char *path = input_item_GetURI( p_item );
737 QUrl url;
738 if( path )
740 url.setUrl( qfu(path) );
741 url = url.adjusted(QUrl::RemoveFilename);
742 if (url.scheme() != "file")
743 url.clear();
744 free(path);
747 QStringList qsl = showSimpleOpen( qtr( "Open subtitles..." ),
748 EXT_FILTER_SUBTITLE,
749 url );
751 foreach( const QString &qsUrl, qsl )
754 if ( THEMIM->AddAssociatedMedia( SPU_ES, qsUrl, true, true, false ) )
755 msg_Warn( p_intf, "unable to load subtitles from '%s'", qtu( qsUrl ) );
760 /****************************************************************************
761 * Menus
762 ****************************************************************************/
764 void DialogsProvider::sendKey( int key )
766 // translate from a vlc keycode into a Qt sequence
767 QKeySequence kseq0( VLCKeyToString( key, true ) );
769 if( popupMenu == NULL )
771 // make sure at least a non visible popupmenu is available
772 popupMenu = VLCMenuBar::PopupMenu( p_intf, false );
773 if( unlikely( popupMenu == NULL ) )
774 return;
777 // test against key accelerators from the popupmenu
778 QList<QAction*> actions = popupMenu->findChildren<QAction*>();
779 for( int i = 0; i < actions.size(); i++ )
781 QAction* action = actions.at(i);
782 QKeySequence kseq = action->shortcut();
783 if( kseq == kseq0 )
785 action->trigger();
786 return;
790 // forward key to vlc core when not a key accelerator
791 var_SetInteger( vlc_object_instance(p_intf), "key-pressed", key );