1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright © 2006-2011 the VideoLAN team
6 * Authors: Clément Stenac <zorglub@videolan.org>
7 * Jean-Baptiste Kempf <jb@videolan.org>
8 * Jean-Philippe André <jpeg@videolan.org>
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.
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.
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 *****************************************************************************/
26 * - Remove static currentGroup
33 #include <vlc_common.h>
34 #include <vlc_intf_strings.h>
35 #include <vlc_aout.h> /* audio_output_t */
36 #include <vlc_player.h>
40 #include "maininterface/main_interface.hpp" /* View modifications */
41 #include "dialogs/dialogs_provider.hpp" /* Dialogs display */
42 #include "player/player_controller.hpp" /* Input Management */
43 #include "playlist/playlist_controller.hpp"
44 #include "recents.hpp" /* Recent Items */
45 #include "dialogs/extensions/extensions_manager.hpp" /* Extensions menu */
46 #include "dialogs/extended/extended_panels.hpp"
47 #include "util/varchoicemodel.hpp"
52 #include <QActionGroup>
53 #include <QSignalMapper>
56 using namespace vlc::playlist
;
59 This file defines the main menus and the pop-up menu (right-click menu)
60 and the systray menu (in that order in the file)
62 There are 4 menus that have to be rebuilt everytime there are called:
63 Audio, Video, Navigation, view
64 4 functions are building those menus: AudioMenu, VideoMenu, NavigMenu, View
68 QMenu
*VLCMenuBar::recentsMenu
= NULL
;
69 RendererMenu
*VLCMenuBar::rendererMenu
= NULL
;
72 * @brief Add static entries to DP in menus
74 QAction
*addDPStaticEntry( QMenu
*menu
,
78 const char *shortcut
= NULL
,
79 QAction::MenuRole role
= QAction::NoRole
82 QAction
*action
= NULL
;
83 #ifndef __APPLE__ /* We don't set icons in menus in MacOS X */
84 if( !EMPTY_STR( icon
) )
86 if( !EMPTY_STR( shortcut
) )
87 action
= menu
->addAction( QIcon( icon
), text
, THEDP
,
88 member
, qtr( shortcut
) );
90 action
= menu
->addAction( QIcon( icon
), text
, THEDP
, member
);
95 if( !EMPTY_STR( shortcut
) )
96 action
= menu
->addAction( text
, THEDP
, member
, qtr( shortcut
) );
98 action
= menu
->addAction( text
, THEDP
, member
);
101 action
->setMenuRole( role
);
109 * @brief Add static entries to MIM in menus
111 template<typename Fun
>
112 static QAction
* addMIMStaticEntry( intf_thread_t
*p_intf
,
119 #ifndef __APPLE__ /* We don't set icons in menus in MacOS X */
120 if( !EMPTY_STR( icon
) )
122 action
= menu
->addAction( text
, THEMIM
, member
);
123 action
->setIcon( QIcon( icon
) );
128 action
= menu
->addAction( text
, THEMIM
, member
);
133 template<typename Fun
>
134 static QAction
* addMPLStaticEntry( intf_thread_t
*p_intf
,
141 #ifndef __APPLE__ /* We don't set icons in menus in MacOS X */
142 if( !EMPTY_STR( icon
) )
144 action
= menu
->addAction( text
, THEMPL
, member
);
145 action
->setIcon( QIcon( icon
) );
150 action
= menu
->addAction( text
, THEMPL
, member
);
155 /*****************************************************************************
158 *****************************************************************************/
161 static inline void addMenuToMainbar( QMenu
*func
, QString title
, QMenuBar
*bar
) {
162 func
->setTitle( title
);
166 * Main Menu Bar Creation
168 void VLCMenuBar::createMenuBar( MainInterface
*mi
,
169 intf_thread_t
*p_intf
)
171 /* QMainWindows->menuBar()
172 gives the QProcess::destroyed timeout issue on Cleanlooks style with
173 setDesktopAware set to false */
174 QMenuBar
*bar
= mi
->menuBar();
176 addMenuToMainbar( FileMenu( p_intf
, bar
, mi
), qtr( "&Media" ), bar
);
178 /* Dynamic menus, rebuilt before being showed */
179 addMenuToMainbar( NavigMenu( p_intf
, bar
), qtr( "P&layback" ), bar
);
180 addMenuToMainbar( AudioMenu( p_intf
, bar
), qtr( "&Audio" ), bar
);
181 addMenuToMainbar( VideoMenu( p_intf
, bar
), qtr( "&Video" ), bar
);
182 addMenuToMainbar( SubtitleMenu( p_intf
, bar
), qtr( "Subti&tle" ), bar
);
184 addMenuToMainbar( ToolsMenu( p_intf
, bar
), qtr( "Tool&s" ), bar
);
186 /* View menu, a bit different */
187 addMenuToMainbar( ViewMenu( p_intf
, NULL
, mi
), qtr( "V&iew" ), bar
);
189 addMenuToMainbar( HelpMenu( bar
), qtr( "&Help" ), bar
);
194 * Media ( File ) Menu
195 * Opening, streaming and quit
197 QMenu
*VLCMenuBar::FileMenu( intf_thread_t
*p_intf
, QWidget
*parent
, MainInterface
*mi
)
199 QMenu
*menu
= new QMenu( parent
);
202 addDPStaticEntry( menu
, qtr( "Open &File..." ),
203 ":/type/file-asym.svg", SLOT( simpleOpenDialog() ), "Ctrl+O" );
204 addDPStaticEntry( menu
, qtr( "&Open Multiple Files..." ),
205 ":/type/file-asym.svg", SLOT( openFileDialog() ), "Ctrl+Shift+O" );
206 addDPStaticEntry( menu
, qtr( I_OP_OPDIR
),
207 ":/type/folder-grey.svg", SLOT( PLOpenDir() ), "Ctrl+F" );
208 addDPStaticEntry( menu
, qtr( "Open &Disc..." ),
209 ":/type/disc.svg", SLOT( openDiscDialog() ), "Ctrl+D" );
210 addDPStaticEntry( menu
, qtr( "Open &Network Stream..." ),
211 ":/type/network.svg", SLOT( openNetDialog() ), "Ctrl+N" );
212 addDPStaticEntry( menu
, qtr( "Open &Capture Device..." ),
213 ":/type/capture-card.svg", SLOT( openCaptureDialog() ), "Ctrl+C" );
215 addDPStaticEntry( menu
, qtr( "Open &Location from clipboard" ),
216 NULL
, SLOT( openUrlDialog() ), "Ctrl+V" );
218 if( !recentsMenu
&& var_InheritBool( p_intf
, "qt-recentplay" ) )
219 recentsMenu
= new QMenu( qtr( "Open &Recent Media" ) );
223 updateRecents( p_intf
);
224 menu
->addMenu( recentsMenu
);
226 menu
->addSeparator();
228 addDPStaticEntry( menu
, qtr( I_PL_SAVE
), "", SLOT( savePlayingToPlaylist() ),
232 addDPStaticEntry( menu
, qtr( "Conve&rt / Save..." ), "",
233 SLOT( openAndTranscodingDialogs() ), "Ctrl+R" );
234 addDPStaticEntry( menu
, qtr( "&Stream..." ),
235 ":/menu/stream.svg", SLOT( openAndStreamingDialogs() ), "Ctrl+S" );
236 menu
->addSeparator();
239 action
= addMPLStaticEntry( p_intf
, menu
, qtr( "Quit at the end of playlist" ), "",
240 &PlaylistControllerModel::playAndExitChanged
);
241 action
->setCheckable( true );
242 action
->setChecked( THEMPL
->isPlayAndExit() );
244 if( mi
&& mi
->getSysTray() )
246 action
= menu
->addAction( qtr( "Close to systray"), mi
,
247 SLOT( toggleUpdateSystrayMenu() ) );
250 addDPStaticEntry( menu
, qtr( "&Quit" ) ,
251 ":/menu/exit.svg", SLOT( quit() ), "Ctrl+Q" );
256 * Tools, like Media Information, Preferences or Messages
258 QMenu
*VLCMenuBar::ToolsMenu( intf_thread_t
*p_intf
, QMenu
*menu
)
260 addDPStaticEntry( menu
, qtr( "&Effects and Filters"), ":/menu/settings.svg",
261 SLOT( extendedDialog() ), "Ctrl+E" );
263 addDPStaticEntry( menu
, qtr( "&Track Synchronization"), ":/menu/setting.svgs",
264 SLOT( synchroDialog() ), "" );
266 addDPStaticEntry( menu
, qtr( I_MENU_INFO
) , ":/menu/info.svg",
267 SLOT( mediaInfoDialog() ), "Ctrl+I" );
268 addDPStaticEntry( menu
, qtr( I_MENU_CODECINFO
) ,
269 ":/menu/info.svg", SLOT( mediaCodecDialog() ), "Ctrl+J" );
272 addDPStaticEntry( menu
, qtr( I_MENU_VLM
), "", SLOT( vlmDialog() ),
276 addDPStaticEntry( menu
, qtr( "Program Guide" ), "", SLOT( epgDialog() ),
279 addDPStaticEntry( menu
, qtr( I_MENU_MSG
),
280 ":/menu/messages.svg", SLOT( messagesDialog() ), "Ctrl+M" );
282 addDPStaticEntry( menu
, qtr( "Plu&gins and extensions" ),
283 "", SLOT( pluginDialog() ) );
284 menu
->addSeparator();
286 if( !p_intf
->p_sys
->b_isDialogProvider
)
287 addDPStaticEntry( menu
, qtr( "Customi&ze Interface..." ),
288 ":/menu/preferences.svg", SLOT( toolbarDialog() ) );
290 addDPStaticEntry( menu
, qtr( "&Preferences" ),
291 ":/menu/preferences.svg", SLOT( prefsDialog() ), "Ctrl+P", QAction::PreferencesRole
);
298 * Interface modification, load other interfaces, activate Extensions
299 * \param current, set to NULL for menu creation, else for menu update
301 QMenu
*VLCMenuBar::ViewMenu( intf_thread_t
*p_intf
, QMenu
*current
, MainInterface
*_mi
)
306 MainInterface
*mi
= _mi
? _mi
: p_intf
->p_sys
->p_mi
;
311 menu
= new QMenu( qtr( "&View" ), mi
);
317 //HACK menu->clear() does not delete submenus
318 QList
<QAction
*> actions
= menu
->actions();
319 foreach( QAction
*a
, actions
)
321 QMenu
*m
= a
->menu();
322 if( a
->parent() == menu
) delete a
;
323 else menu
->removeAction( a
);
324 if( m
&& m
->parent() == menu
) delete m
;
330 QIcon( ":/menu/playlist_menu.svg" ),
332 qtr( "Play&list" ), mi
,
333 SLOT( togglePlaylist() ), qtr( "Ctrl+L" ) );
335 /* Docked Playlist */
336 action
= menu
->addAction( qtr( "Docked Playlist" ) );
337 action
->setCheckable( true );
338 CONNECT( action
, triggered( bool ), mi
, dockPlaylist( bool ) );
340 menu
->addSeparator();
342 action
= menu
->addAction( qtr( "Always on &top" ) );
343 action
->setCheckable( true );
344 action
->setChecked( mi
->isInterfaceAlwaysOnTop() );
345 CONNECT( action
, triggered( bool ), mi
, setInterfaceAlwaysOnTop( bool ) );
347 menu
->addSeparator();
350 action
= menu
->addAction( qtr( "Mi&nimal Interface" ) );
351 action
->setShortcut( qtr( "Ctrl+H" ) );
352 action
->setCheckable( true );
355 CONNECT( action
, triggered( bool ), mi
, toggleMinimalView( bool ) );
356 CONNECT( mi
, minimalViewToggled( bool ), action
, setChecked( bool ) );
358 /* FullScreen View */
359 action
= menu
->addAction( qtr( "&Fullscreen Interface" ), mi
,
360 SLOT( toggleInterfaceFullScreen() ), QString( "F11" ) );
361 action
->setCheckable( true );
362 action
->setChecked( mi
->isInterfaceFullScreen() );
363 CONNECT( mi
, fullscreenInterfaceToggled( bool ),
364 action
, setChecked( bool ) );
366 /* Advanced Controls */
367 action
= menu
->addAction( qtr( "&Advanced Controls" ), mi
,
368 SLOT( toggleAdvancedButtons() ) );
369 action
->setCheckable( true );
371 action
= menu
->addAction( qtr( "Status Bar" ) );
372 action
->setCheckable( true );
373 action
->setChecked( mi
->statusBar()->isVisible() );
374 CONNECT( action
, triggered( bool ), mi
, setStatusBarVisibility( bool) );
375 #if 0 /* For Visualisations. Not yet working */
376 adv
= menu
->addAction( qtr( "Visualizations selector" ), mi
,
378 adv
->setCheckable( true );
379 if( visual_selector_enabled
) adv
->setChecked( true );
382 menu
->addSeparator();
384 InterfacesMenu( p_intf
, menu
);
385 menu
->addSeparator();
388 ExtensionsMenu( p_intf
, menu
);
394 * Interface Sub-Menu, to list extras interface and skins
396 QMenu
*VLCMenuBar::InterfacesMenu( intf_thread_t
*p_intf
, QMenu
*current
)
399 VLCVarChoiceModel
* model
= new VLCVarChoiceModel(VLC_OBJECT(p_intf
), "intf-add", current
);
400 CheckableListMenu
* submenu
= new CheckableListMenu(qtr("Interfaces"), model
, current
);
401 current
->addMenu(submenu
);
406 * Extensions menu: populate the current menu with extensions
408 void VLCMenuBar::ExtensionsMenu( intf_thread_t
*p_intf
, QMenu
*extMenu
)
410 /* Get ExtensionsManager and load extensions if needed */
411 ExtensionsManager
*extMgr
= ExtensionsManager::getInstance( p_intf
);
413 if( !var_InheritBool( p_intf
, "qt-autoload-extensions")
414 && !extMgr
->isLoaded() )
419 if( !extMgr
->isLoaded() && !extMgr
->cannotLoad() )
421 extMgr
->loadExtensions();
424 /* Let the ExtensionsManager build itself the menu */
425 extMenu
->addSeparator();
426 extMgr
->menu( extMenu
);
429 static inline void VolumeEntries( intf_thread_t
*p_intf
, QMenu
*current
)
431 current
->addSeparator();
433 current
->addAction( QIcon( ":/toolbar/volume-high.svg" ), qtr( "&Increase Volume" ), THEMIM
, &PlayerController::setVolumeUp
);
434 current
->addAction( QIcon( ":/toolbar/volume-low.svg" ), qtr( "D&ecrease Volume" ), THEMIM
, &PlayerController::setVolumeDown
);
435 current
->addAction( QIcon( ":/toolbar/volume-muted.svg" ), qtr( "&Mute" ), THEMIM
, &PlayerController::toggleMuted
);
441 QMenu
*VLCMenuBar::AudioMenu( intf_thread_t
*p_intf
, QMenu
* current
)
443 if( current
->isEmpty() )
445 current
->addMenu(new CheckableListMenu(qtr( "Audio &Track" ), THEMIM
->getAudioTracks(), current
));
447 QAction
*audioDeviceAction
= new QAction( qtr( "Audio &Device" ), current
);
448 QMenu
*audioDeviceSubmenu
= new QMenu( current
);
449 audioDeviceAction
->setMenu( audioDeviceSubmenu
);
450 current
->addAction( audioDeviceAction
);
451 connect(audioDeviceSubmenu
, &QMenu::aboutToShow
, [=]() {
452 updateAudioDevice( p_intf
, audioDeviceSubmenu
);
455 current
->addMenu( new CheckableListMenu(qtr( "&Stereo Mode" ), THEMIM
->getAudioStereoMode(), current
) );
456 current
->addSeparator();
458 current
->addMenu( new CheckableListMenu(qtr( "&Visualizations" ), THEMIM
->getAudioVisualizations(), current
) );
459 VolumeEntries( p_intf
, current
);
466 QMenu
*VLCMenuBar::SubtitleMenu( intf_thread_t
*p_intf
, QMenu
*current
, bool b_popup
)
468 if( current
->isEmpty() || b_popup
)
470 addDPStaticEntry( current
, qtr( "Add &Subtitle File..." ), "",
471 SLOT( loadSubtitlesFile() ) );
472 current
->addMenu(new CheckableListMenu(qtr( "Sub &Track" ), THEMIM
->getSubtitleTracks(), current
));
473 current
->addSeparator();
480 * Subtitles are part of Video.
482 QMenu
*VLCMenuBar::VideoMenu( intf_thread_t
*p_intf
, QMenu
*current
)
484 if( current
->isEmpty() )
486 current
->addMenu(new CheckableListMenu(qtr( "Video &Track" ), THEMIM
->getVideoTracks(), current
));
488 current
->addSeparator();
489 /* Surface modifiers */
490 current
->addAction(new BooleanPropertyAction(qtr( "&Fullscreen"), THEMIM
, "fullscreen", current
));
491 QAction
* action
= new BooleanPropertyAction(qtr( "Always Fit &Window"), THEMIM
, "autoscale", current
);
492 action
->setEnabled( THEMIM
->hasVideoOutput() );
493 connect(THEMIM
, &PlayerController::hasVideoOutputChanged
, action
, &QAction::setEnabled
);
494 current
->addAction(action
);
495 current
->addAction(new BooleanPropertyAction(qtr( "Set as Wall&paper"), THEMIM
, "wallpaperMode", current
));
497 current
->addSeparator();
499 current
->addMenu( new CheckableListMenu(qtr( "&Zoom" ), THEMIM
->getZoom(), current
) );
500 current
->addMenu( new CheckableListMenu(qtr( "&Aspect Ratio" ), THEMIM
->getAspectRatio(), current
) );
501 current
->addMenu( new CheckableListMenu(qtr( "&Crop" ), THEMIM
->getCrop(), current
) );
503 current
->addSeparator();
504 /* Rendering modifiers */
505 current
->addMenu( new CheckableListMenu(qtr( "&Deinterlace" ), THEMIM
->getDeinterlace(), current
) );
506 current
->addMenu( new CheckableListMenu(qtr( "&Deinterlace mode" ), THEMIM
->getDeinterlaceMode(), current
) );
508 current
->addSeparator();
510 QAction
* snapshotAction
= new QAction(qtr( "Take &Snapshot" ), current
);
511 connect(snapshotAction
, &QAction::triggered
, THEMIM
, &PlayerController::snapshot
);
512 current
->addAction(snapshotAction
);
520 * For DVD, MP4, MOV and other chapter based format
522 QMenu
*VLCMenuBar::NavigMenu( intf_thread_t
*p_intf
, QMenu
*menu
)
527 menu
->addMenu( new CheckableListMenu( qtr( "T&itle" ), THEMIM
->getTitles(), menu
) );
528 submenu
= new CheckableListMenu( qtr( "&Chapter" ), THEMIM
->getChapters(), menu
);
529 submenu
->setTearOffEnabled( true );
530 menu
->addMenu( submenu
);
531 menu
->addMenu( new CheckableListMenu( qtr("&Program") , THEMIM
->getPrograms(), menu
) );
533 submenu
= new QMenu( qtr( I_MENU_BOOKMARK
), menu
);
534 submenu
->setTearOffEnabled( true );
535 addDPStaticEntry( submenu
, qtr( "&Manage" ), "",
536 SLOT( bookmarksDialog() ), "Ctrl+B" );
537 submenu
->addSeparator();
538 action
= menu
->addMenu( submenu
);
539 action
->setData( "bookmark" );
541 menu
->addSeparator();
543 if ( !VLCMenuBar::rendererMenu
)
544 VLCMenuBar::rendererMenu
= new RendererMenu( NULL
, p_intf
);
546 menu
->addMenu( VLCMenuBar::rendererMenu
);
547 menu
->addSeparator();
550 PopupMenuControlEntries( menu
, p_intf
);
552 return RebuildNavigMenu( p_intf
, menu
);
555 QMenu
*VLCMenuBar::RebuildNavigMenu( intf_thread_t
*p_intf
, QMenu
*menu
)
559 #define ADD_ACTION( title, slot, visibleSignal, visible ) \
560 action = menu->addAction( title, THEMIM, slot ); \
562 action->setVisible(false); \
563 connect( THEMIM, visibleSignal, action, &QAction::setVisible );
565 ADD_ACTION( qtr("Previous Title"), &PlayerController::titlePrev
, &PlayerController::hasTitlesChanged
, THEMIM
->hasTitles() );
566 ADD_ACTION( qtr("Next Title"), &PlayerController::titleNext
, &PlayerController::hasTitlesChanged
, THEMIM
->hasTitles() );
567 ADD_ACTION( qtr("Previous Chapter"), &PlayerController::chapterPrev
, &PlayerController::hasChaptersChanged
, THEMIM
->hasChapters() );
568 ADD_ACTION( qtr("Next Chapter"), &PlayerController::chapterNext
, &PlayerController::hasChaptersChanged
, THEMIM
->hasChapters() );
572 PopupMenuPlaylistEntries( menu
, p_intf
);
580 QMenu
*VLCMenuBar::HelpMenu( QWidget
*parent
)
582 QMenu
*menu
= new QMenu( parent
);
583 addDPStaticEntry( menu
, qtr( "&Help" ) ,
584 ":/menu/help.svg", SLOT( helpDialog() ), "F1" );
586 addDPStaticEntry( menu
, qtr( "Check for &Updates..." ) , "",
587 SLOT( updateDialog() ) );
589 menu
->addSeparator();
590 addDPStaticEntry( menu
, qtr( I_MENU_ABOUT
), ":/menu/info.svg",
591 SLOT( aboutDialog() ), "Shift+F1", QAction::AboutRole
);
595 /*****************************************************************************
596 * Popup menus - Right Click menus *
597 *****************************************************************************/
598 #define POPUP_BOILERPLATE \
601 #define CREATE_POPUP \
602 menu = new QMenu(); \
604 menu->popup( QCursor::pos() ); \
606 void VLCMenuBar::PopupMenuPlaylistEntries( QMenu *menu, intf_thread_t *p_intf )
609 bool hasInput
= THEMIM
->hasInput();
611 /* Play or Pause action and icon */
612 if( !hasInput
|| THEMIM
->getPlayingState() != PlayerController::PLAYING_STATE_PLAYING
)
614 action
= menu
->addAction( qtr( "&Play" ), [p_intf
]() {
615 if ( THEMPL
->isEmpty() )
616 THEDP
->openFileDialog();
618 THEMPL
->togglePlayPause();
620 #ifndef __APPLE__ /* No icons in menus in Mac */
621 action
->setIcon( QIcon( ":/toolbar/play_b.svg" ) );
626 action
= addMPLStaticEntry( p_intf
, menu
, qtr( "Pause" ),
627 ":/toolbar/pause_b.svg", &PlaylistControllerModel::togglePlayPause
);
631 action
= addMPLStaticEntry( p_intf
, menu
, qtr( "&Stop" ),
632 ":/toolbar/stop_b.svg", &PlaylistControllerModel::stop
);
634 action
->setEnabled( false );
636 /* Next / Previous */
637 bool bPlaylistEmpty
= THEMPL
->isEmpty();
638 QAction
* previousAction
= addMPLStaticEntry( p_intf
, menu
, qtr( "Pre&vious" ),
639 ":/toolbar/previous_b.svg", &PlaylistControllerModel::prev
);
640 previousAction
->setEnabled( !bPlaylistEmpty
);
641 connect( THEMPL
, &PlaylistControllerModel::isEmptyChanged
, previousAction
, &QAction::setDisabled
);
643 QAction
* nextAction
= addMPLStaticEntry( p_intf
, menu
, qtr( "Ne&xt" ),
644 ":/toolbar/next_b.svg", &PlaylistControllerModel::next
);
645 nextAction
->setEnabled( !bPlaylistEmpty
);
646 connect( THEMPL
, &PlaylistControllerModel::isEmptyChanged
, nextAction
, &QAction::setDisabled
);
648 action
= menu
->addAction( qtr( "Record" ), THEMIM
, &PlayerController::toggleRecord
);
649 action
->setIcon( QIcon( ":/toolbar/record.svg" ) );
651 action
->setEnabled( false );
652 menu
->addSeparator();
655 void VLCMenuBar::PopupMenuControlEntries( QMenu
*menu
, intf_thread_t
*p_intf
,
659 QMenu
*rateMenu
= new QMenu( qtr( "Sp&eed" ), menu
);
660 rateMenu
->setTearOffEnabled( true );
665 action
= rateMenu
->addAction( qtr( "&Faster" ), THEMIM
,
666 &PlayerController::faster
);
667 #ifndef __APPLE__ /* No icons in menus in Mac */
668 action
->setIcon( QIcon( ":/toolbar/faster2.svg") );
672 action
= rateMenu
->addAction( QIcon( ":/toolbar/faster2.svg" ), qtr( "Faster (fine)" ), THEMIM
,
673 &PlayerController::littlefaster
);
675 action
= rateMenu
->addAction( qtr( "N&ormal Speed" ), THEMIM
,
676 &PlayerController::normalRate
);
678 action
= rateMenu
->addAction( QIcon( ":/toolbar/slower2.svg" ), qtr( "Slower (fine)" ), THEMIM
,
679 &PlayerController::littleslower
);
683 action
= rateMenu
->addAction( qtr( "Slo&wer" ), THEMIM
,
684 &PlayerController::slower
);
685 #ifndef __APPLE__ /* No icons in menus in Mac */
686 action
->setIcon( QIcon( ":/toolbar/slower2.svg") );
690 action
= menu
->addMenu( rateMenu
);
692 menu
->addSeparator();
694 if( !b_normal
) return;
696 action
= menu
->addAction( qtr( "&Jump Forward" ), THEMIM
,
697 &PlayerController::jumpFwd
);
698 #ifndef __APPLE__ /* No icons in menus in Mac */
699 action
->setIcon( QIcon( ":/toolbar/skip_fw.svg") );
702 action
= menu
->addAction( qtr( "Jump Bac&kward" ), THEMIM
,
703 &PlayerController::jumpBwd
);
704 #ifndef __APPLE__ /* No icons in menus in Mac */
705 action
->setIcon( QIcon( ":/toolbar/skip_back.svg") );
708 action
= menu
->addAction( qtr( I_MENU_GOTOTIME
), THEDP
, &DialogsProvider::gotoTimeDialog
, qtr( "Ctrl+T" ) );
710 menu
->addSeparator();
713 void VLCMenuBar::PopupMenuStaticEntries( QMenu
*menu
)
715 QMenu
*openmenu
= new QMenu( qtr( "Open Media" ), menu
);
716 addDPStaticEntry( openmenu
, qtr( I_OP_OPF
),
717 ":/type/file-asym.svg", SLOT( openFileDialog() ) );
718 addDPStaticEntry( openmenu
, qtr( I_OP_OPDIR
),
719 ":/type/folder-grey.svg", SLOT( PLOpenDir() ) );
720 addDPStaticEntry( openmenu
, qtr( "Open &Disc..." ),
721 ":/type/disc.svg", SLOT( openDiscDialog() ) );
722 addDPStaticEntry( openmenu
, qtr( "Open &Network..." ),
723 ":/type/network.svg", SLOT( openNetDialog() ) );
724 addDPStaticEntry( openmenu
, qtr( "Open &Capture Device..." ),
725 ":/type/capture-card.svg", SLOT( openCaptureDialog() ) );
726 menu
->addMenu( openmenu
);
728 menu
->addSeparator();
730 QMenu
*helpmenu
= HelpMenu( menu
);
731 helpmenu
->setTitle( qtr( "Help" ) );
732 menu
->addMenu( helpmenu
);
735 addDPStaticEntry( menu
, qtr( "Quit" ), ":/menu/exit.svg",
736 SLOT( quit() ), "Ctrl+Q", QAction::QuitRole
);
739 /* Video Tracks and Subtitles tracks */
740 QMenu
* VLCMenuBar::VideoPopupMenu( intf_thread_t
*p_intf
, bool show
)
742 QMenu
* menu
= new QMenu();
743 VideoMenu(p_intf
, menu
);
745 menu
->popup( QCursor::pos() );
750 QMenu
* VLCMenuBar::AudioPopupMenu( intf_thread_t
*p_intf
, bool show
)
752 QMenu
* menu
= new QMenu();
753 AudioMenu(p_intf
, menu
);
755 menu
->popup( QCursor::pos() );
759 /* Navigation stuff, and general menus ( open ), used only for skins */
760 QMenu
* VLCMenuBar::MiscPopupMenu( intf_thread_t
*p_intf
, bool show
)
762 QMenu
* menu
= new QMenu();
764 menu
->addSeparator();
765 PopupMenuPlaylistEntries( menu
, p_intf
);
767 menu
->addSeparator();
768 PopupMenuControlEntries( menu
, p_intf
);
770 menu
->addSeparator();
771 PopupMenuStaticEntries( menu
);
774 menu
->popup( QCursor::pos() );
778 /* Main Menu that sticks everything together */
779 QMenu
* VLCMenuBar::PopupMenu( intf_thread_t
*p_intf
, bool show
)
782 QMenu
* menu
= new QMenu();
783 input_item_t
* p_input
= THEMIM
->getInput();
785 bool b_isFullscreen
= false;
786 MainInterface
*mi
= p_intf
->p_sys
->p_mi
;
788 PopupMenuPlaylistEntries( menu
, p_intf
);
789 menu
->addSeparator();
794 PlayerController::VoutPtr p_vout
= THEMIM
->getVout();
796 /* Add a fullscreen switch button, since it is the most used function */
799 b_isFullscreen
= THEMIM
->isFullscreen();
801 menu
->addAction(new BooleanPropertyAction(qtr( "Leave Fullscreen" ), THEMIM
, "fullscreen", menu
) );
803 menu
->addAction(new BooleanPropertyAction(qtr( "&Fullscreen" ), THEMIM
, "fullscreen", menu
) );
805 menu
->addSeparator();
811 submenu
= new QMenu( menu
);
812 action
= menu
->addMenu( AudioMenu( p_intf
, submenu
) );
813 action
->setText( qtr( "&Audio" ) );
814 if( action
->menu()->isEmpty() )
815 action
->setEnabled( false );
818 submenu
= new QMenu( menu
);
819 action
= menu
->addMenu( VideoMenu( p_intf
, submenu
) );
820 action
->setText( qtr( "&Video" ) );
821 if( action
->menu()->isEmpty() )
822 action
->setEnabled( false );
825 submenu
= new QMenu( menu
);
826 action
= menu
->addMenu( SubtitleMenu( p_intf
, submenu
, true ) );
827 action
->setText( qtr( "Subti&tle") );
829 /* Playback menu for chapters */
830 submenu
= new QMenu( menu
);
831 action
= menu
->addMenu( NavigMenu( p_intf
, submenu
) );
832 action
->setText( qtr( "&Playback" ) );
833 if( action
->menu()->isEmpty() )
834 action
->setEnabled( false );
837 menu
->addSeparator();
839 /* Add some special entries for windowed mode: Interface Menu */
840 if( !b_isFullscreen
)
842 QMenu
*submenu
= new QMenu( qtr( "Tool&s" ), menu
);
843 /*QMenu *tools =*/ ToolsMenu( p_intf
, submenu
);
844 submenu
->addSeparator();
848 QMenu
* viewMenu
= ViewMenu( p_intf
, NULL
, mi
);
849 viewMenu
->setTitle( qtr( "V&iew" ) );
850 submenu
->addMenu( viewMenu
);
853 /* In skins interface, append some items */
854 if( p_intf
->p_sys
->b_isDialogProvider
)
856 vlc_object_t
* p_object
= vlc_object_parent(p_intf
);
857 submenu
->setTitle( qtr( "Interface" ) );
859 /* Open skin dialog box */
860 if (var_Type(p_object
, "intf-skins-interactive") & VLC_VAR_ISCOMMAND
)
862 QAction
* openSkinAction
= new QAction(qtr("Open skin..."));
863 openSkinAction
->setShortcut( QKeySequence( "Ctrl+Shift+S" ));
864 connect(openSkinAction
, &QAction::triggered
, [=]() {
865 var_TriggerCallback(p_object
, "intf-skins-interactive");
867 submenu
->addAction(openSkinAction
);
870 VLCVarChoiceModel
* skinmodel
= new VLCVarChoiceModel(p_object
, "intf-skins", submenu
);
871 CheckableListMenu
* skinsubmenu
= new CheckableListMenu(qtr("Interface"), skinmodel
, submenu
);
872 submenu
->addMenu(skinsubmenu
);
874 submenu
->addSeparator();
876 /* list of extensions */
877 ExtensionsMenu( p_intf
, submenu
);
880 menu
->addMenu( submenu
);
883 /* Static entries for ending, like open */
884 if( p_intf
->p_sys
->b_isDialogProvider
)
886 QMenu
*openmenu
= FileMenu( p_intf
, menu
);
887 openmenu
->setTitle( qtr( "Open Media" ) );
888 menu
->addMenu( openmenu
);
890 menu
->addSeparator();
892 QMenu
*helpmenu
= HelpMenu( menu
);
893 helpmenu
->setTitle( qtr( "Help" ) );
894 menu
->addMenu( helpmenu
);
896 addDPStaticEntry( menu
, qtr( "Quit" ), ":/menu/exit.svg",
897 SLOT( quit() ), "Ctrl+Q", QAction::QuitRole
);
900 PopupMenuStaticEntries( menu
);
903 menu
->popup( QCursor::pos() );
908 #undef POPUP_BOILERPLATE
911 /************************************************************************
913 ************************************************************************/
915 void VLCMenuBar::updateSystrayMenu( MainInterface
*mi
,
916 intf_thread_t
*p_intf
,
917 bool b_force_visible
)
919 /* Get the systray menu and clean it */
920 QMenu
*sysMenu
= mi
->getSysTrayMenu();
924 /* Hide / Show VLC and cone */
925 if( mi
->isVisible() || b_force_visible
)
927 sysMenu
->addAction( QIcon( ":/logo/vlc16.png" ),
928 qtr( "&Hide VLC media player in taskbar" ), mi
,
929 SLOT( hideUpdateSystrayMenu() ) );
933 sysMenu
->addAction( QIcon( ":/logo/vlc16.png" ),
934 qtr( "Sho&w VLC media player" ), mi
,
935 SLOT( showUpdateSystrayMenu() ) );
937 sysMenu
->addSeparator();
940 PopupMenuPlaylistEntries( sysMenu
, p_intf
);
941 PopupMenuControlEntries( sysMenu
, p_intf
, false );
943 VolumeEntries( p_intf
, sysMenu
);
944 sysMenu
->addSeparator();
945 addDPStaticEntry( sysMenu
, qtr( "&Open Media" ),
946 ":/type/file-wide.svg", SLOT( openFileDialog() ) );
947 addDPStaticEntry( sysMenu
, qtr( "&Quit" ) ,
948 ":/menu/exit.svg", SLOT( quit() ) );
951 mi
->getSysTray()->setContextMenu( sysMenu
);
956 /*****************************************************************************
958 *****************************************************************************/
960 void VLCMenuBar::updateAudioDevice( intf_thread_t
* p_intf
, QMenu
*current
)
969 PlayerController::AoutPtr aout
= THEMIM
->getAout();
973 int i_result
= aout_DevicesList( aout
.get(), &ids
, &names
);
977 selected
= aout_DeviceGet( aout
.get() );
979 QActionGroup
*actionGroup
= new QActionGroup(current
);
982 for( int i
= 0; i
< i_result
; i
++ )
984 action
= new QAction( qfue( names
[i
] ), actionGroup
);
985 action
->setData( ids
[i
] );
986 action
->setCheckable( true );
987 if( (selected
&& !strcmp( ids
[i
], selected
) ) ||
988 (selected
== NULL
&& ids
[i
] && ids
[i
][0] == '\0' ) )
989 action
->setChecked( true );
990 actionGroup
->addAction( action
);
991 current
->addAction( action
);
992 connect(action
, &QAction::triggered
, THEMIM
->menusAudioMapper
, QOverload
<>::of(&QSignalMapper::map
));
993 THEMIM
->menusAudioMapper
->setMapping(action
, ids
[i
]);
1002 void VLCMenuBar::updateRecents( intf_thread_t
*p_intf
)
1007 RecentsMRL
* rmrl
= RecentsMRL::getInstance( p_intf
);
1008 QStringList l
= rmrl
->recentList();
1010 recentsMenu
->clear();
1014 recentsMenu
->setEnabled( false );
1018 for( int i
= 0; i
< __MIN( l
.count(), 10) ; ++i
)
1020 QString mrl
= l
.at( i
);
1021 char *psz
= vlc_uri_decode_duplicate( qtu( mrl
) );
1022 QString text
= qfu( psz
);
1024 text
.replace("&", "&&");
1026 # define FILE_SCHEME "file:///"
1028 # define FILE_SCHEME "file://"
1030 if ( text
.startsWith( FILE_SCHEME
) )
1031 text
.remove( 0, strlen( FILE_SCHEME
) );
1035 action
= recentsMenu
->addAction(
1036 QString( i
< 9 ? "&%1: ": "%1: " ).arg( i
+ 1 ) +
1037 QApplication::fontMetrics().elidedText( text
,
1038 Qt::ElideLeft
, 400 ),
1039 rmrl
->signalMapper
, SLOT( map() ),
1040 i
< 9 ? QString( "Ctrl+%1" ).arg( i
+ 1 ) : "" );
1041 rmrl
->signalMapper
->setMapping( action
, l
.at( i
) );
1044 recentsMenu
->addSeparator();
1045 recentsMenu
->addAction( qtr("&Clear"), rmrl
, SLOT( clear() ) );
1046 recentsMenu
->setEnabled( true );