You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
964 lines
33 KiB
964 lines
33 KiB
/*****************************************************************************
|
|
* menus.cpp : Qt menus
|
|
*****************************************************************************
|
|
* Copyright © 2006-2011 the VideoLAN team
|
|
*
|
|
* Authors: Clément Stenac <zorglub@videolan.org>
|
|
* Jean-Baptiste Kempf <jb@videolan.org>
|
|
* Jean-Philippe André <jpeg@videolan.org>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* ( at your option ) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
|
|
*****************************************************************************/
|
|
|
|
/** \todo
|
|
* - Remove static currentGroup
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
# include "config.h"
|
|
#endif
|
|
|
|
#include <vlc_common.h>
|
|
#include <vlc_intf_strings.h>
|
|
#include <vlc_aout.h> /* audio_output_t */
|
|
#include <vlc_interface.h>
|
|
|
|
#include "menus.hpp"
|
|
|
|
#include "maininterface/mainctx.hpp" /* View modifications */
|
|
#include "dialogs/dialogs_provider.hpp" /* Dialogs display */
|
|
#include "player/player_controller.hpp" /* Input Management */
|
|
#include "playlist/playlist_controller.hpp"
|
|
#include "dialogs/extensions/extensions_manager.hpp" /* Extensions menu */
|
|
#include "dialogs/extended/extended_panels.hpp"
|
|
#include "util/varchoicemodel.hpp"
|
|
#include "medialibrary/medialib.hpp"
|
|
#include "medialibrary/mlrecentsmodel.hpp"
|
|
#include "medialibrary/mlbookmarkmodel.hpp"
|
|
|
|
|
|
#include <QMenu>
|
|
#include <QMenuBar>
|
|
#include <QAction>
|
|
#include <QActionGroup>
|
|
#include <QSignalMapper>
|
|
|
|
using namespace vlc::playlist;
|
|
|
|
/*
|
|
This file defines the main menus and the pop-up menu (right-click menu)
|
|
and the systray menu (in that order in the file)
|
|
|
|
There are 4 menus that have to be rebuilt every time there are called:
|
|
Audio, Video, Navigation, view
|
|
4 functions are building those menus: AudioMenu, VideoMenu, NavigMenu, View
|
|
|
|
*/
|
|
|
|
RendererMenu *VLCMenuBar::rendererMenu = NULL;
|
|
|
|
/**
|
|
* @brief Add static entries to DP in menus
|
|
**/
|
|
template<typename Functor>
|
|
QAction *addDPStaticEntry( QMenu *menu,
|
|
const QString& text,
|
|
const char *icon,
|
|
const Functor member,
|
|
const char *shortcut = NULL,
|
|
QAction::MenuRole role = QAction::NoRole
|
|
)
|
|
{
|
|
QAction *action = NULL;
|
|
#ifndef __APPLE__ /* We don't set icons in menus in MacOS X */
|
|
if( !EMPTY_STR( icon ) )
|
|
{
|
|
if( !EMPTY_STR( shortcut ) )
|
|
action = menu->addAction( QIcon( icon ), text, THEDP,
|
|
member, qfut( shortcut ) );
|
|
else
|
|
action = menu->addAction( QIcon( icon ), text, THEDP, member );
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
if( !EMPTY_STR( shortcut ) )
|
|
action = menu->addAction( text, THEDP, member, qfut( shortcut ) );
|
|
else
|
|
action = menu->addAction( text, THEDP, member );
|
|
}
|
|
#ifdef __APPLE__
|
|
action->setMenuRole( role );
|
|
#else
|
|
Q_UNUSED( role );
|
|
#endif
|
|
return action;
|
|
}
|
|
|
|
/**
|
|
* @brief Add static entries to MIM in menus
|
|
**/
|
|
template<typename Fun>
|
|
static QAction* addMIMStaticEntry( qt_intf_t *p_intf,
|
|
QMenu *menu,
|
|
const QString& text,
|
|
const char *icon,
|
|
Fun member )
|
|
{
|
|
QAction *action;
|
|
#ifndef __APPLE__ /* We don't set icons in menus in MacOS X */
|
|
if( !EMPTY_STR( icon ) )
|
|
{
|
|
action = menu->addAction( text, THEMIM, member );
|
|
action->setIcon( QIcon( icon ) );
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
action = menu->addAction( text, THEMIM, member );
|
|
}
|
|
return action;
|
|
}
|
|
|
|
template<typename Fun>
|
|
static QAction* addMPLStaticEntry( qt_intf_t *p_intf,
|
|
QMenu *menu,
|
|
const QString& text,
|
|
const char *icon,
|
|
Fun member )
|
|
{
|
|
QAction *action;
|
|
#ifndef __APPLE__ /* We don't set icons in menus in MacOS X */
|
|
if( !EMPTY_STR( icon ) )
|
|
{
|
|
action = menu->addAction( text, THEMPL, member );
|
|
action->setIcon( QIcon( icon ) );
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
action = menu->addAction( text, THEMPL, member );
|
|
}
|
|
return action;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* All normal menus
|
|
* Simple Code
|
|
*****************************************************************************/
|
|
|
|
/**
|
|
* Main Menu Bar Creation
|
|
**/
|
|
VLCMenuBar::VLCMenuBar(QObject* parent)
|
|
: QObject(parent)
|
|
{}
|
|
|
|
|
|
/**
|
|
* Media ( File ) Menu
|
|
* Opening, streaming and quit
|
|
**/
|
|
void VLCMenuBar::FileMenu(qt_intf_t *p_intf, QMenu *menu)
|
|
{
|
|
auto mi = p_intf->p_mi;
|
|
QAction *action;
|
|
|
|
//use a lambda here as the Triggrered signal is emiting and it will pass false (checked) as a first argument
|
|
addDPStaticEntry( menu, qtr( "Open &File..." ),
|
|
":/menu/file.svg", []() { THEDP->simpleOpenDialog(); } , "Ctrl+O" );
|
|
addDPStaticEntry( menu, qtr( "&Open Multiple Files..." ),
|
|
":/menu/file.svg", &DialogsProvider::openFileDialog, "Ctrl+Shift+O" );
|
|
addDPStaticEntry( menu, qfut( I_OP_OPDIR ),
|
|
":/menu/folder.svg", &DialogsProvider::PLOpenDir, "Ctrl+F" );
|
|
addDPStaticEntry( menu, qtr( "Open &Disc..." ),
|
|
":/menu/disc.svg", &DialogsProvider::openDiscDialog, "Ctrl+D" );
|
|
addDPStaticEntry( menu, qtr( "Open &Network Stream..." ),
|
|
":/menu/network.svg", &DialogsProvider::openNetDialog, "Ctrl+N" );
|
|
addDPStaticEntry( menu, qtr( "Open &Capture Device..." ),
|
|
":/menu/capture-card.svg", &DialogsProvider::openCaptureDialog, "Ctrl+C" );
|
|
|
|
addDPStaticEntry( menu, qtr( "Open &Location from clipboard" ),
|
|
NULL, &DialogsProvider::openUrlDialog, "Ctrl+V" );
|
|
|
|
if( mi && var_InheritBool( p_intf, "save-recentplay" ) && mi->hasMediaLibrary() )
|
|
{
|
|
MLRecentsModel* recentModel = new MLRecentsModel(nullptr);
|
|
recentModel->setMl(mi->getMediaLibrary());
|
|
recentModel->setLimit(10);
|
|
QMenu* recentsMenu = new RecentMenu(recentModel, mi->getMediaLibrary(), menu);
|
|
recentsMenu->setTitle(qtr( "Open &Recent Media" ) );
|
|
recentModel->setParent(recentsMenu);
|
|
menu->addMenu( recentsMenu );
|
|
}
|
|
|
|
menu->addSeparator();
|
|
|
|
addDPStaticEntry( menu, qfut( I_PL_SAVE ), "", &DialogsProvider::savePlayingToPlaylist,
|
|
"Ctrl+Y" );
|
|
|
|
addDPStaticEntry( menu, qtr( "Conve&rt / Save..." ), "",
|
|
&DialogsProvider::openAndTranscodingDialogs, "Ctrl+R" );
|
|
addDPStaticEntry( menu, qtr( "&Stream..." ),
|
|
":/menu/stream.svg", &DialogsProvider::openAndStreamingDialogs, "Ctrl+S" );
|
|
menu->addSeparator();
|
|
|
|
action = addMPLStaticEntry( p_intf, menu, qtr( "Quit at the end of playlist" ), "",
|
|
&PlaylistController::playAndExitChanged );
|
|
action->setCheckable( true );
|
|
action->setChecked( THEMPL->isPlayAndExit() );
|
|
|
|
if( mi && mi->getSysTray() )
|
|
{
|
|
action = menu->addAction( qtr( "Close to systray"), mi,
|
|
&MainCtx::toggleUpdateSystrayMenu );
|
|
}
|
|
|
|
addDPStaticEntry( menu, qtr( "&Quit" ) ,
|
|
":/menu/exit.svg", &DialogsProvider::quit, "Ctrl+Q" );
|
|
}
|
|
|
|
/**
|
|
* Tools, like Media Information, Preferences or Messages
|
|
**/
|
|
void VLCMenuBar::ToolsMenu( qt_intf_t *p_intf, QMenu *menu )
|
|
{
|
|
addDPStaticEntry( menu, qtr( "&Effects and Filters"), ":/menu/settings.svg",
|
|
&DialogsProvider::extendedDialog, "Ctrl+E" );
|
|
|
|
addDPStaticEntry( menu, qtr( "&Track Synchronization"), ":/menu/setting.svgs",
|
|
&DialogsProvider::synchroDialog, "" );
|
|
|
|
addDPStaticEntry( menu, qfut( I_MENU_INFO ) , ":/menu/info.svg",
|
|
QOverload<>::of(&DialogsProvider::mediaInfoDialog), "Ctrl+I" );
|
|
|
|
addDPStaticEntry( menu, qfut( I_MENU_CODECINFO ) ,
|
|
":/menu/info.svg", &DialogsProvider::mediaCodecDialog, "Ctrl+J" );
|
|
|
|
#ifdef ENABLE_VLM
|
|
addDPStaticEntry( menu, qfut( I_MENU_VLM ), "", &DialogsProvider::vlmDialog,
|
|
"Ctrl+Shift+W" );
|
|
#endif
|
|
|
|
addDPStaticEntry( menu, qtr( "Program Guide" ), "", &DialogsProvider::epgDialog,
|
|
"" );
|
|
|
|
addDPStaticEntry( menu, qfut( I_MENU_MSG ),
|
|
":/menu/messages.svg", &DialogsProvider::messagesDialog, "Ctrl+M" );
|
|
|
|
addDPStaticEntry( menu, qtr( "Plu&gins and extensions" ),
|
|
"", &DialogsProvider::pluginDialog );
|
|
menu->addSeparator();
|
|
|
|
if( !p_intf->b_isDialogProvider )
|
|
addDPStaticEntry( menu, qtr( "Customi&ze Interface..." ),
|
|
":/menu/preferences.svg", &DialogsProvider::showToolbarEditorDialog);
|
|
|
|
addDPStaticEntry( menu, qtr( "&Preferences" ),
|
|
":/menu/preferences.svg", &DialogsProvider::prefsDialog, "Ctrl+P", QAction::PreferencesRole );
|
|
}
|
|
|
|
/**
|
|
* View Menu
|
|
* Interface modification, load other interfaces, activate Extensions
|
|
* \param current, set to NULL for menu creation, else for menu update
|
|
**/
|
|
void VLCMenuBar::ViewMenu( qt_intf_t *p_intf, QMenu *menu )
|
|
{
|
|
QAction *action;
|
|
|
|
MainCtx *mi = p_intf->p_mi;
|
|
assert( mi );
|
|
assert(menu);
|
|
|
|
//menu->clear();
|
|
//HACK menu->clear() does not delete submenus
|
|
QList<QAction*> actions = menu->actions();
|
|
foreach( QAction *a, actions )
|
|
{
|
|
QMenu *m = a->menu();
|
|
if( a->parent() == menu ) delete a;
|
|
else menu->removeAction( a );
|
|
if( m && m->parent() == menu ) delete m;
|
|
}
|
|
|
|
QString title;
|
|
|
|
if (mi->hasMediaLibrary())
|
|
title = qtr("Media Library");
|
|
else
|
|
title = qtr("Browse and Discover");
|
|
|
|
action = menu->addAction(
|
|
#ifndef __APPLE__
|
|
QIcon( ":/menu/media_library.svg" ),
|
|
#endif
|
|
title);
|
|
action->setCheckable( true );
|
|
connect( action, &QAction::triggered, mi, &MainCtx::setMediaLibraryVisible );
|
|
action->setChecked( mi->isMediaLibraryVisible() );
|
|
|
|
action = menu->addAction(
|
|
#ifndef __APPLE__
|
|
QIcon( ":/menu/playlist.svg" ),
|
|
#endif
|
|
qtr( "Play&list" ));
|
|
action->setShortcut(QString( "Ctrl+L" ));
|
|
action->setCheckable( true );
|
|
connect( action, &QAction::triggered, mi, &MainCtx::setPlaylistVisible );
|
|
action->setChecked( mi->isPlaylistVisible() );
|
|
|
|
/* Docked Playlist */
|
|
action = menu->addAction( qtr( "Docked Playlist" ) );
|
|
action->setCheckable( true );
|
|
connect( action, &QAction::triggered, mi, &MainCtx::setPlaylistDocked );
|
|
action->setChecked( mi->isPlaylistDocked() );
|
|
|
|
menu->addSeparator();
|
|
|
|
action = menu->addAction( qtr( "Always on &top" ) );
|
|
action->setCheckable( true );
|
|
action->setChecked( mi->isInterfaceAlwaysOnTop() );
|
|
connect( action, &QAction::triggered, mi, &MainCtx::setInterfaceAlwaysOnTop );
|
|
|
|
menu->addSeparator();
|
|
|
|
/* FullScreen View */
|
|
action = menu->addAction( qtr( "&Fullscreen Interface" ), mi,
|
|
&MainCtx::toggleInterfaceFullScreen, QString( "F11" ) );
|
|
action->setCheckable( true );
|
|
action->setChecked( mi->isInterfaceFullScreen() );
|
|
|
|
action = menu->addAction( qtr( "&View Items as Grid" ), mi,
|
|
&MainCtx::setGridView );
|
|
action->setCheckable( true );
|
|
action->setChecked( mi->hasGridView() );
|
|
|
|
menu->addMenu( new CheckableListMenu(qtr( "&Color Scheme" ), mi->getColorScheme(), CheckableListMenu::GROUPED_EXLUSIVE, menu) );
|
|
|
|
menu->addSeparator();
|
|
|
|
InterfacesMenu( p_intf, menu );
|
|
menu->addSeparator();
|
|
|
|
/* Extensions */
|
|
ExtensionsMenu( p_intf, menu );
|
|
}
|
|
|
|
/**
|
|
* Interface Sub-Menu, to list extras interface and skins
|
|
**/
|
|
void VLCMenuBar::InterfacesMenu( qt_intf_t *p_intf, QMenu *current )
|
|
{
|
|
assert(current);
|
|
VLCVarChoiceModel* model = new VLCVarChoiceModel(VLC_OBJECT(p_intf->intf), "intf-add", current);
|
|
CheckableListMenu* submenu = new CheckableListMenu(qtr("Interfaces"), model, CheckableListMenu::UNGROUPED, current);
|
|
current->addMenu(submenu);
|
|
}
|
|
|
|
/**
|
|
* Extensions menu: populate the current menu with extensions
|
|
**/
|
|
void VLCMenuBar::ExtensionsMenu( qt_intf_t *p_intf, QMenu *extMenu )
|
|
{
|
|
/* Get ExtensionsManager and load extensions if needed */
|
|
ExtensionsManager *extMgr = ExtensionsManager::getInstance( p_intf );
|
|
|
|
if( !var_InheritBool( p_intf, "qt-autoload-extensions")
|
|
&& !extMgr->isLoaded() )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if( !extMgr->isLoaded() && !extMgr->cannotLoad() )
|
|
{
|
|
extMgr->loadExtensions();
|
|
}
|
|
|
|
/* Let the ExtensionsManager build itself the menu */
|
|
extMenu->addSeparator();
|
|
extMgr->menu( extMenu );
|
|
}
|
|
|
|
static inline void VolumeEntries( qt_intf_t *p_intf, QMenu *current )
|
|
{
|
|
current->addSeparator();
|
|
|
|
current->addAction( QIcon( ":/menu/volume-high.svg" ), qtr( "&Increase Volume" ), THEMIM, &PlayerController::setVolumeUp );
|
|
current->addAction( QIcon( ":/menu/volume-low.svg" ), qtr( "&Decrease Volume" ), THEMIM, &PlayerController::setVolumeDown );
|
|
current->addAction( QIcon( ":/menu/volume-muted.svg" ), qtr( "&Mute" ), THEMIM, &PlayerController::toggleMuted );
|
|
}
|
|
|
|
/**
|
|
* Main Audio Menu
|
|
**/
|
|
void VLCMenuBar::AudioMenu( qt_intf_t *p_intf, QMenu * current )
|
|
{
|
|
if( current->isEmpty() )
|
|
{
|
|
current->addMenu(new CheckableListMenu(qtr( "Audio &Track" ), THEMIM->getAudioTracks(), CheckableListMenu::GROUPED_OPTIONAL, current));
|
|
|
|
QAction *audioDeviceAction = new QAction( qtr( "&Audio Device" ), current );
|
|
QMenu *audioDeviceSubmenu = new QMenu( current );
|
|
audioDeviceAction->setMenu( audioDeviceSubmenu );
|
|
current->addAction( audioDeviceAction );
|
|
connect(audioDeviceSubmenu, &QMenu::aboutToShow, [=]() {
|
|
updateAudioDevice( p_intf, audioDeviceSubmenu );
|
|
});
|
|
|
|
VLCVarChoiceModel *mix_mode = THEMIM->getAudioMixMode();
|
|
if (mix_mode->rowCount() == 0)
|
|
current->addMenu( new CheckableListMenu(qtr( "&Stereo Mode" ), THEMIM->getAudioStereoMode(), CheckableListMenu::GROUPED_EXLUSIVE, current) );
|
|
else
|
|
current->addMenu( new CheckableListMenu(qtr( "&Mix Mode" ), mix_mode, CheckableListMenu::GROUPED_EXLUSIVE, current) );
|
|
current->addSeparator();
|
|
|
|
current->addMenu( new CheckableListMenu(qtr( "&Visualizations" ), THEMIM->getAudioVisualizations(), CheckableListMenu::GROUPED_EXLUSIVE, current) );
|
|
VolumeEntries( p_intf, current );
|
|
}
|
|
}
|
|
|
|
/* Subtitles */
|
|
void VLCMenuBar::SubtitleMenu( qt_intf_t *p_intf, QMenu *current, bool b_popup )
|
|
{
|
|
if( current->isEmpty() || b_popup )
|
|
{
|
|
addDPStaticEntry( current, qtr( "Add &Subtitle File..." ), "",
|
|
&DialogsProvider::loadSubtitlesFile);
|
|
current->addMenu(new CheckableListMenu(qtr( "Sub &Track" ), THEMIM->getSubtitleTracks(), CheckableListMenu::GROUPED_OPTIONAL, current));
|
|
current->addSeparator();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Main Video Menu
|
|
* Subtitles are part of Video.
|
|
**/
|
|
void VLCMenuBar::VideoMenu( qt_intf_t *p_intf, QMenu *current )
|
|
{
|
|
if( current->isEmpty() )
|
|
{
|
|
current->addMenu(new CheckableListMenu(qtr( "Video &Track" ), THEMIM->getVideoTracks(), CheckableListMenu::GROUPED_OPTIONAL, current));
|
|
|
|
current->addSeparator();
|
|
/* Surface modifiers */
|
|
current->addAction(new BooleanPropertyAction(qtr( "&Fullscreen"), THEMIM, "fullscreen", current));
|
|
QAction* action = new BooleanPropertyAction(qtr( "Always Fit &Window"), THEMIM, "autoscale", current);
|
|
action->setEnabled( THEMIM->hasVideoOutput() );
|
|
connect(THEMIM, &PlayerController::hasVideoOutputChanged, action, &QAction::setEnabled);
|
|
current->addAction(action);
|
|
current->addAction(new BooleanPropertyAction(qtr( "Set as Wall&paper"), THEMIM, "wallpaperMode", current));
|
|
|
|
current->addSeparator();
|
|
/* Size modifiers */
|
|
current->addMenu( new CheckableListMenu(qtr( "&Zoom" ), THEMIM->getZoom(), CheckableListMenu::GROUPED_EXLUSIVE, current) );
|
|
current->addMenu( new CheckableListMenu(qtr( "&Aspect Ratio" ), THEMIM->getAspectRatio(), CheckableListMenu::GROUPED_EXLUSIVE, current) );
|
|
current->addMenu( new CheckableListMenu(qtr( "&Crop" ), THEMIM->getCrop(), CheckableListMenu::GROUPED_EXLUSIVE, current) );
|
|
|
|
current->addSeparator();
|
|
/* Rendering modifiers */
|
|
current->addMenu( new CheckableListMenu(qtr( "&Deinterlace" ), THEMIM->getDeinterlace(), CheckableListMenu::GROUPED_EXLUSIVE, current) );
|
|
current->addMenu( new CheckableListMenu(qtr( "&Deinterlace mode" ), THEMIM->getDeinterlaceMode(), CheckableListMenu::GROUPED_EXLUSIVE, current) );
|
|
|
|
current->addSeparator();
|
|
/* Other actions */
|
|
QAction* snapshotAction = new QAction(qtr( "Take &Snapshot" ), current);
|
|
connect(snapshotAction, &QAction::triggered, THEMIM, &PlayerController::snapshot);
|
|
current->addAction(snapshotAction);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Navigation Menu
|
|
* For DVD, MP4, MOV and other chapter based format
|
|
**/
|
|
void VLCMenuBar::NavigMenu( qt_intf_t *p_intf, QMenu *menu )
|
|
{
|
|
QAction *action;
|
|
QMenu *submenu;
|
|
|
|
menu->addMenu( new CheckableListMenu( qtr( "T&itle" ), THEMIM->getTitles(), CheckableListMenu::GROUPED_EXLUSIVE, menu) );
|
|
submenu = new CheckableListMenu( qtr( "&Chapter" ), THEMIM->getChapters(), CheckableListMenu::GROUPED_EXLUSIVE, menu );
|
|
submenu->setTearOffEnabled( true );
|
|
menu->addMenu( submenu );
|
|
menu->addMenu( new CheckableListMenu( qtr("&Program") , THEMIM->getPrograms(), CheckableListMenu::GROUPED_EXLUSIVE, menu) );
|
|
|
|
MainCtx * mi = p_intf->p_mi;
|
|
|
|
if (mi && p_intf->p_mi->hasMediaLibrary() )
|
|
{
|
|
MediaLib * mediaLib = mi->getMediaLibrary();
|
|
|
|
BookmarkMenu * bookmarks = new BookmarkMenu(mediaLib, p_intf->p_player, menu);
|
|
|
|
bookmarks->setTitle(qfut(I_MENU_BOOKMARK));
|
|
|
|
action = menu->addMenu(bookmarks);
|
|
|
|
action->setData("bookmark");
|
|
}
|
|
|
|
menu->addSeparator();
|
|
|
|
if ( !VLCMenuBar::rendererMenu )
|
|
VLCMenuBar::rendererMenu = new RendererMenu( NULL, p_intf );
|
|
|
|
menu->addMenu( VLCMenuBar::rendererMenu );
|
|
menu->addSeparator();
|
|
|
|
|
|
PopupMenuControlEntries( menu, p_intf );
|
|
|
|
RebuildNavigMenu( p_intf, menu );
|
|
}
|
|
|
|
void VLCMenuBar::RebuildNavigMenu( qt_intf_t *p_intf, QMenu *menu )
|
|
{
|
|
QAction* action;
|
|
|
|
#define ADD_ACTION( title, slot, visibleSignal, visible ) \
|
|
action = menu->addAction( title, THEMIM, slot ); \
|
|
if (! visible)\
|
|
action->setVisible(false); \
|
|
connect( THEMIM, visibleSignal, action, &QAction::setVisible );
|
|
|
|
ADD_ACTION( qtr("Previous Title"), &PlayerController::titlePrev, &PlayerController::hasTitlesChanged, THEMIM->hasTitles() );
|
|
ADD_ACTION( qtr("Next Title"), &PlayerController::titleNext, &PlayerController::hasTitlesChanged, THEMIM->hasTitles() );
|
|
ADD_ACTION( qtr("Previous Chapter"), &PlayerController::chapterPrev, &PlayerController::hasChaptersChanged, THEMIM->hasChapters() );
|
|
ADD_ACTION( qtr("Next Chapter"), &PlayerController::chapterNext, &PlayerController::hasChaptersChanged, THEMIM->hasChapters() );
|
|
|
|
#undef ADD_ACTION
|
|
|
|
PopupMenuPlaylistEntries( menu, p_intf );
|
|
}
|
|
|
|
/**
|
|
* Help/About Menu
|
|
**/
|
|
void VLCMenuBar::HelpMenu( QMenu *menu )
|
|
{
|
|
addDPStaticEntry( menu, qtr( "&Help" ) ,
|
|
":/menu/help.svg", &DialogsProvider::helpDialog, "F1" );
|
|
#ifdef UPDATE_CHECK
|
|
addDPStaticEntry( menu, qtr( "Check for &Updates..." ) , "",
|
|
&DialogsProvider::updateDialog);
|
|
#endif
|
|
menu->addSeparator();
|
|
addDPStaticEntry( menu, qfut( I_MENU_ABOUT ), ":/menu/info.svg",
|
|
&DialogsProvider::aboutDialog, "Shift+F1", QAction::AboutRole );
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Popup menus - Right Click menus *
|
|
*****************************************************************************/
|
|
|
|
void VLCMenuBar::PopupMenuPlaylistEntries( QMenu *menu, qt_intf_t *p_intf )
|
|
{
|
|
QAction *action;
|
|
bool hasInput = THEMIM->hasInput();
|
|
|
|
/* Play or Pause action and icon */
|
|
if( !hasInput || THEMIM->getPlayingState() != PlayerController::PLAYING_STATE_PLAYING )
|
|
{
|
|
action = menu->addAction( qtr( "&Play" ), [p_intf]() {
|
|
if ( THEMPL->isEmpty() )
|
|
THEDP->openFileDialog();
|
|
else
|
|
THEMPL->togglePlayPause();
|
|
});
|
|
#ifndef __APPLE__ /* No icons in menus in Mac */
|
|
action->setIcon( QIcon( ":/menu/ic_fluent_play_filled.svg" ) );
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
action = addMPLStaticEntry( p_intf, menu, qtr( "Pause" ),
|
|
":/menu/ic_pause_filled.svg", &PlaylistController::togglePlayPause );
|
|
}
|
|
|
|
/* Stop */
|
|
action = addMPLStaticEntry( p_intf, menu, qtr( "&Stop" ),
|
|
":/menu/stop.svg", &PlaylistController::stop );
|
|
if( !hasInput )
|
|
action->setEnabled( false );
|
|
|
|
/* Next / Previous */
|
|
bool bPlaylistEmpty = THEMPL->isEmpty();
|
|
QAction* previousAction = addMPLStaticEntry( p_intf, menu, qtr( "Pre&vious" ),
|
|
":/menu/ic_fluent_previous.svg", &PlaylistController::prev );
|
|
previousAction->setEnabled( !bPlaylistEmpty );
|
|
connect( THEMPL, &PlaylistController::isEmptyChanged, previousAction, &QAction::setDisabled);
|
|
|
|
QAction* nextAction = addMPLStaticEntry( p_intf, menu, qtr( "Ne&xt" ),
|
|
":/menu/ic_fluent_next.svg", &PlaylistController::next );
|
|
nextAction->setEnabled( !bPlaylistEmpty );
|
|
connect( THEMPL, &PlaylistController::isEmptyChanged, nextAction, &QAction::setDisabled);
|
|
|
|
action = menu->addAction( qtr( "Record" ), THEMIM, &PlayerController::toggleRecord );
|
|
action->setIcon( QIcon( ":/menu/record.svg" ) );
|
|
if( !hasInput )
|
|
action->setEnabled( false );
|
|
menu->addSeparator();
|
|
}
|
|
|
|
void VLCMenuBar::PopupMenuControlEntries( QMenu *menu, qt_intf_t *p_intf,
|
|
bool b_normal )
|
|
{
|
|
QAction *action;
|
|
QMenu *rateMenu = new QMenu( qtr( "Sp&eed" ), menu );
|
|
rateMenu->setTearOffEnabled( true );
|
|
|
|
if( b_normal )
|
|
{
|
|
/* Faster/Slower */
|
|
action = rateMenu->addAction( qtr( "&Faster" ), THEMIM,
|
|
&PlayerController::faster );
|
|
#ifndef __APPLE__ /* No icons in menus in Mac */
|
|
action->setIcon( QIcon( ":/menu/ic_fluent_fast_forward.svg") );
|
|
#endif
|
|
}
|
|
|
|
action = rateMenu->addAction( QIcon( ":/menu/ic_fluent_fast_forward.svg" ), qtr( "Faster (fine)" ), THEMIM,
|
|
&PlayerController::littlefaster );
|
|
|
|
action = rateMenu->addAction( qtr( "N&ormal Speed" ), THEMIM,
|
|
&PlayerController::normalRate );
|
|
|
|
action = rateMenu->addAction( QIcon( ":/menu/ic_fluent_rewind.svg" ), qtr( "Slower (fine)" ), THEMIM,
|
|
&PlayerController::littleslower );
|
|
|
|
if( b_normal )
|
|
{
|
|
action = rateMenu->addAction( qtr( "Slo&wer" ), THEMIM,
|
|
&PlayerController::slower );
|
|
#ifndef __APPLE__ /* No icons in menus in Mac */
|
|
action->setIcon( QIcon( ":/menu/ic_fluent_rewind.svg") );
|
|
#endif
|
|
}
|
|
|
|
action = menu->addMenu( rateMenu );
|
|
|
|
menu->addSeparator();
|
|
|
|
if( !b_normal ) return;
|
|
|
|
action = menu->addAction( qtr( "&Jump Forward" ), THEMIM,
|
|
&PlayerController::jumpFwd );
|
|
#ifndef __APPLE__ /* No icons in menus in Mac */
|
|
action->setIcon( QIcon( ":/menu/skip_fw.svg") );
|
|
#endif
|
|
|
|
action = menu->addAction( qtr( "Jump Bac&kward" ), THEMIM,
|
|
&PlayerController::jumpBwd );
|
|
#ifndef __APPLE__ /* No icons in menus in Mac */
|
|
action->setIcon( QIcon( ":/menu/skip_back.svg") );
|
|
#endif
|
|
|
|
action = menu->addAction( qfut( I_MENU_GOTOTIME ), THEDP, &DialogsProvider::gotoTimeDialog, qtr( "Ctrl+T" ) );
|
|
|
|
menu->addSeparator();
|
|
}
|
|
|
|
void VLCMenuBar::PopupMenuStaticEntries( QMenu *menu )
|
|
{
|
|
QMenu *openmenu = new QMenu( qtr( "Open Media" ), menu );
|
|
addDPStaticEntry( openmenu, qfut( I_OP_OPF ),
|
|
":/menu/file.svg", &DialogsProvider::openFileDialog);
|
|
addDPStaticEntry( openmenu, qfut( I_OP_OPDIR ),
|
|
":/menu/folder.svg", &DialogsProvider::PLOpenDir);
|
|
addDPStaticEntry( openmenu, qtr( "Open &Disc..." ),
|
|
":/menu/disc.svg", &DialogsProvider::openDiscDialog);
|
|
addDPStaticEntry( openmenu, qtr( "Open &Network..." ),
|
|
":/menu/network.svg", &DialogsProvider::openNetDialog);
|
|
addDPStaticEntry( openmenu, qtr( "Open &Capture Device..." ),
|
|
":/menu/capture-card.svg", &DialogsProvider::openCaptureDialog);
|
|
menu->addMenu( openmenu );
|
|
|
|
menu->addSeparator();
|
|
|
|
addDPStaticEntry( menu, qtr( "Quit" ), ":/menu/exit.svg",
|
|
&DialogsProvider::quit, "Ctrl+Q", QAction::QuitRole );
|
|
}
|
|
|
|
/* Video Tracks and Subtitles tracks */
|
|
QMenu* VLCMenuBar::VideoPopupMenu( qt_intf_t *p_intf, bool show )
|
|
{
|
|
QMenu* menu = new QMenu();
|
|
VideoMenu(p_intf, menu);
|
|
if( show )
|
|
menu->popup( QCursor::pos() );
|
|
return menu;
|
|
}
|
|
|
|
/* Audio Tracks */
|
|
QMenu* VLCMenuBar::AudioPopupMenu( qt_intf_t *p_intf, bool show )
|
|
{
|
|
QMenu* menu = new QMenu();
|
|
AudioMenu(p_intf, menu);
|
|
if( show )
|
|
menu->popup( QCursor::pos() );
|
|
return menu;
|
|
}
|
|
|
|
/* Navigation stuff, and general menus ( open ), used only for skins */
|
|
QMenu* VLCMenuBar::MiscPopupMenu( qt_intf_t *p_intf, bool show )
|
|
{
|
|
QMenu* menu = new QMenu();
|
|
|
|
menu->addSeparator();
|
|
PopupMenuPlaylistEntries( menu, p_intf );
|
|
|
|
menu->addSeparator();
|
|
PopupMenuControlEntries( menu, p_intf );
|
|
|
|
menu->addSeparator();
|
|
PopupMenuStaticEntries( menu );
|
|
|
|
if( show )
|
|
menu->popup( QCursor::pos() );
|
|
return menu;
|
|
}
|
|
|
|
/* Main Menu that sticks everything together */
|
|
QMenu* VLCMenuBar::PopupMenu( qt_intf_t *p_intf, bool show )
|
|
{
|
|
/* */
|
|
QMenu* menu = new QMenu();
|
|
input_item_t* p_input = THEMIM->getInput();
|
|
QAction *action;
|
|
bool b_isFullscreen = false;
|
|
|
|
PopupMenuPlaylistEntries( menu, p_intf );
|
|
menu->addSeparator();
|
|
|
|
if( p_input )
|
|
{
|
|
QMenu *submenu;
|
|
SharedVOutThread p_vout = THEMIM->getVout();
|
|
|
|
/* Add a fullscreen switch button, since it is the most used function */
|
|
if( p_vout )
|
|
{
|
|
b_isFullscreen = THEMIM->isFullscreen();
|
|
if (b_isFullscreen)
|
|
menu->addAction(new BooleanPropertyAction(qtr( "Leave Fullscreen" ), THEMIM, "fullscreen", menu) );
|
|
else
|
|
menu->addAction(new BooleanPropertyAction(qtr( "&Fullscreen" ), THEMIM, "fullscreen", menu) );
|
|
|
|
menu->addSeparator();
|
|
}
|
|
|
|
/* Input menu */
|
|
|
|
/* Audio menu */
|
|
submenu = new QMenu( menu );
|
|
AudioMenu( p_intf, submenu );
|
|
action = menu->addMenu( submenu );
|
|
action->setText( qtr( "&Audio" ) );
|
|
if( action->menu()->isEmpty() )
|
|
action->setEnabled( false );
|
|
|
|
/* Video menu */
|
|
submenu = new QMenu( menu );
|
|
VideoMenu( p_intf, submenu );
|
|
action = menu->addMenu( submenu );
|
|
action->setText( qtr( "&Video" ) );
|
|
if( action->menu()->isEmpty() )
|
|
action->setEnabled( false );
|
|
|
|
/* Subtitles menu */
|
|
submenu = new QMenu( menu );
|
|
SubtitleMenu( p_intf, submenu, true );
|
|
action = menu->addMenu( submenu );
|
|
action->setText( qtr( "Subti&tle") );
|
|
|
|
/* Playback menu for chapters */
|
|
submenu = new QMenu( menu );
|
|
NavigMenu( p_intf, submenu );
|
|
action = menu->addMenu( submenu );
|
|
action->setText( qtr( "&Playback" ) );
|
|
if( action->menu()->isEmpty() )
|
|
action->setEnabled( false );
|
|
}
|
|
|
|
menu->addSeparator();
|
|
|
|
/* Add some special entries for windowed mode: Interface Menu */
|
|
if( !b_isFullscreen )
|
|
{
|
|
if( p_intf->b_isDialogProvider )
|
|
{
|
|
// same as Tool menu but with extra entries
|
|
QMenu* submenu = new QMenu( qtr( "Interface" ), menu );
|
|
ToolsMenu( p_intf, submenu );
|
|
submenu->addSeparator();
|
|
|
|
vlc_object_t* p_object = vlc_object_parent(p_intf->intf);
|
|
|
|
/* Open skin dialog box */
|
|
if (var_Type(p_object, "intf-skins-interactive") & VLC_VAR_ISCOMMAND)
|
|
{
|
|
QAction* openSkinAction = new QAction(qtr("Open skin..."), menu);
|
|
openSkinAction->setShortcut( QKeySequence( "Ctrl+Shift+S" ));
|
|
connect(openSkinAction, &QAction::triggered, [=]() {
|
|
var_TriggerCallback(p_object, "intf-skins-interactive");
|
|
});
|
|
submenu->addAction(openSkinAction);
|
|
}
|
|
|
|
VLCVarChoiceModel* skinmodel = new VLCVarChoiceModel(p_object, "intf-skins", submenu);
|
|
CheckableListMenu* skinsubmenu = new CheckableListMenu(qtr("Interface"), skinmodel, CheckableListMenu::GROUPED_OPTIONAL, submenu);
|
|
submenu->addMenu(skinsubmenu);
|
|
|
|
submenu->addSeparator();
|
|
|
|
/* list of extensions */
|
|
ExtensionsMenu( p_intf, submenu );
|
|
|
|
menu->addMenu( submenu );
|
|
}
|
|
else
|
|
{
|
|
QMenu* toolsMenu = new QMenu( qtr( "Tool&s" ), menu );
|
|
ToolsMenu( p_intf, toolsMenu );
|
|
menu->addMenu( toolsMenu );
|
|
|
|
QMenu* viewMenu = new QMenu( qtr( "V&iew" ), menu );
|
|
ViewMenu( p_intf, viewMenu );
|
|
menu->addMenu( viewMenu );
|
|
}
|
|
}
|
|
|
|
/* Static entries for ending, like open */
|
|
if( p_intf->b_isDialogProvider )
|
|
{
|
|
|
|
QMenu* openmenu = new QMenu( qtr( "Open Media" ), menu );
|
|
FileMenu( p_intf, openmenu );
|
|
menu->addMenu( openmenu );
|
|
|
|
menu->addSeparator();
|
|
|
|
QMenu* helpmenu = new QMenu( qtr( "Help" ), menu );
|
|
HelpMenu( helpmenu );
|
|
menu->addMenu( helpmenu );
|
|
|
|
addDPStaticEntry( menu, qtr( "Quit" ), ":/menu/exit.svg",
|
|
&DialogsProvider::quit, "Ctrl+Q", QAction::QuitRole );
|
|
}
|
|
else
|
|
PopupMenuStaticEntries( menu );
|
|
|
|
if( show )
|
|
menu->popup( QCursor::pos() );
|
|
return menu;
|
|
}
|
|
|
|
/************************************************************************
|
|
* Systray Menu *
|
|
************************************************************************/
|
|
|
|
void VLCMenuBar::updateSystrayMenu( MainCtx *mi,
|
|
qt_intf_t *p_intf,
|
|
bool b_force_visible )
|
|
{
|
|
/* Get the systray menu and clean it */
|
|
QMenu *sysMenu = mi->getSysTrayMenu();
|
|
// explictly delete submenus, see QTBUG-11070
|
|
for (QAction *action : sysMenu->actions()) {
|
|
if (action->menu()) {
|
|
delete action->menu();
|
|
}
|
|
}
|
|
sysMenu->clear();
|
|
|
|
#ifndef Q_OS_MAC
|
|
/* Hide / Show VLC and cone */
|
|
if( mi->isInterfaceVisible() || b_force_visible )
|
|
{
|
|
sysMenu->addAction( QIcon( ":/logo/vlc16.png" ),
|
|
qtr( "&Hide VLC media player in taskbar" ), mi,
|
|
&MainCtx::hideUpdateSystrayMenu);
|
|
}
|
|
else
|
|
{
|
|
sysMenu->addAction( QIcon( ":/logo/vlc16.png" ),
|
|
qtr( "Sho&w VLC media player" ), mi,
|
|
&MainCtx::showUpdateSystrayMenu);
|
|
}
|
|
sysMenu->addSeparator();
|
|
#endif
|
|
|
|
PopupMenuPlaylistEntries( sysMenu, p_intf );
|
|
PopupMenuControlEntries( sysMenu, p_intf, false );
|
|
|
|
VolumeEntries( p_intf, sysMenu );
|
|
sysMenu->addSeparator();
|
|
addDPStaticEntry( sysMenu, qtr( "&Open Media" ),
|
|
":/menu/file.svg", &DialogsProvider::openFileDialog);
|
|
addDPStaticEntry( sysMenu, qtr( "&Quit" ) ,
|
|
":/menu/exit.svg", &DialogsProvider::quit);
|
|
|
|
/* Set the menu */
|
|
mi->getSysTray()->setContextMenu( sysMenu );
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
* Private methods.
|
|
*****************************************************************************/
|
|
|
|
void VLCMenuBar::updateAudioDevice( qt_intf_t * p_intf, QMenu *current )
|
|
{
|
|
char **ids, **names;
|
|
char *selected;
|
|
|
|
if( !current )
|
|
return;
|
|
|
|
current->clear();
|
|
SharedAOut aout = THEMIM->getAout();
|
|
if (!aout)
|
|
return;
|
|
|
|
int i_result = aout_DevicesList( aout.get(), &ids, &names);
|
|
if( i_result < 0 )
|
|
return;
|
|
|
|
selected = aout_DeviceGet( aout.get() );
|
|
|
|
QActionGroup *actionGroup = new QActionGroup(current);
|
|
QAction *action;
|
|
|
|
for( int i = 0; i < i_result; i++ )
|
|
{
|
|
action = new QAction( qfue( names[i] ), actionGroup );
|
|
action->setData( qfu(ids[i]) );
|
|
action->setCheckable( true );
|
|
if( (selected && !strcmp( ids[i], selected ) ) ||
|
|
(selected == NULL && ids[i] && ids[i][0] == '\0' ) )
|
|
action->setChecked( true );
|
|
actionGroup->addAction( action );
|
|
current->addAction( action );
|
|
connect(action, &QAction::triggered, THEMIM->menusAudioMapper, QOverload<>::of(&QSignalMapper::map));
|
|
THEMIM->menusAudioMapper->setMapping(action, ids[i]);
|
|
free( ids[i] );
|
|
free( names[i] );
|
|
}
|
|
free( ids );
|
|
free( names );
|
|
free( selected );
|
|
}
|
|
|