📄 menus.cpp
字号:
/***************************************************************************** * menus.cpp : Qt menus ***************************************************************************** * Copyright © 2006-2008 the VideoLAN team * $Id: 86f9a5e1a3fa1b33371cab3ea62433e79decc244 $ * * 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 "main_interface.hpp"#include "menus.hpp"#include "dialogs_provider.hpp"#include "input_manager.hpp"#include <QMenu>#include <QMenuBar>#include <QAction>#include <QActionGroup>#include <QSignalMapper>#include <QSystemTrayIcon>/* 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 3 menus that have to be rebuilt everytime there are called: Audio, Video, Navigation 3 functions are building those menus: AudioMenu, VideoMenu, NavigMenu and 3 functions associated are collecting the objects : InputAutoMenuBuilder, AudioAutoMenuBuilder, VideoAutoMenuBuilder. A QSignalMapper decides when to rebuild those menus cf MenuFunc in the .hpp Just before one of those menus are aboutToShow(), they are rebuild. */enum{ ITEM_NORMAL, ITEM_CHECK, ITEM_RADIO};static QActionGroup *currentGroup;/* HACK for minimalView to go around a Qt bug/feature * that doesn't update the QAction checked state when QMenu is hidden */QAction *QVLCMenu::minimalViewAction = NULL;// Add static entries to menusvoid addDPStaticEntry( QMenu *menu, const QString text, const char *help, const char *icon, const char *member, const char *shortcut = NULL ){ QAction *action = NULL; if( !EMPTY_STR( icon ) > 0 ) { if( !EMPTY_STR( shortcut ) > 0 ) action = menu->addAction( QIcon( icon ), text, THEDP, member, qtr( shortcut ) ); else action = menu->addAction( QIcon( icon ), text, THEDP, member ); } else { if( !EMPTY_STR( shortcut ) > 0 ) action = menu->addAction( text, THEDP, member, qtr( shortcut ) ); else action = menu->addAction( text, THEDP, member ); } action->setData( "_static_" );}void addMIMStaticEntry( intf_thread_t *p_intf, QMenu *menu, const QString text, const char *help, const char *icon, const char *member ){ if( strlen( icon ) > 0 ) { QAction *action = menu->addAction( text, THEMIM, member ); action->setIcon( QIcon( icon ) ); } else { menu->addAction( text, THEMIM, member ); }}void EnableDPStaticEntries( QMenu *menu, bool enable = true ){ if( !menu ) return; QAction *action; foreach( action, menu->actions() ) { if( action->data().toString() == "_static_" ) action->setEnabled( enable ); }}/** * \return Number of static entries */int DeleteNonStaticEntries( QMenu *menu ){ int i_ret = 0; QAction *action; if( !menu ) return VLC_EGENERIC; foreach( action, menu->actions() ) { if( action->data().toString() != "_static_" ) delete action; else i_ret++; }}/***************************************************************************** * Definitions of variables for the dynamic menus *****************************************************************************/#define PUSH_VAR( var ) varnames.push_back( var ); \ objects.push_back( p_object ? p_object->i_object_id : 0 )#define PUSH_INPUTVAR( var ) varnames.push_back( var ); \ objects.push_back( p_input ? p_input->i_object_id : 0 );#define PUSH_SEPARATOR if( objects.size() != i_last_separator ) { \ objects.push_back( 0 ); varnames.push_back( "" ); \ i_last_separator = objects.size(); }static int InputAutoMenuBuilder( vlc_object_t *p_object, vector<int> &objects, vector<const char *> &varnames ){ PUSH_VAR( "bookmark" ); PUSH_VAR( "title" ); PUSH_VAR( "chapter" ); PUSH_VAR( "program" ); PUSH_VAR( "navigation" ); PUSH_VAR( "dvd_menus" ); return VLC_SUCCESS;}static int VideoAutoMenuBuilder( vlc_object_t *p_object, input_thread_t *p_input, vector<int> &objects, vector<const char *> &varnames ){ PUSH_INPUTVAR( "video-es" ); PUSH_INPUTVAR( "spu-es" ); PUSH_VAR( "fullscreen" ); PUSH_VAR( "zoom" ); PUSH_VAR( "deinterlace" ); PUSH_VAR( "aspect-ratio" ); PUSH_VAR( "crop" ); PUSH_VAR( "video-on-top" );#ifdef WIN32 PUSH_VAR( "directx-wallpaper" );#endif PUSH_VAR( "video-snapshot" ); if( p_object ) { vlc_object_t *p_dec_obj = ( vlc_object_t * )vlc_object_find( p_object, VLC_OBJECT_DECODER, FIND_PARENT ); if( p_dec_obj ) { vlc_object_t *p_object = p_dec_obj; PUSH_VAR( "ffmpeg-pp-q" ); vlc_object_release( p_dec_obj ); } } return VLC_SUCCESS;}static int AudioAutoMenuBuilder( vlc_object_t *p_object, input_thread_t *p_input, vector<int> &objects, vector<const char *> &varnames ){ PUSH_INPUTVAR( "audio-es" ); PUSH_VAR( "audio-device" ); PUSH_VAR( "audio-channels" ); PUSH_VAR( "visual" ); return VLC_SUCCESS;}static QAction * FindActionWithVar( QMenu *menu, const char *psz_var ){ QAction *action; foreach( action, menu->actions() ) { if( action->data().toString() == psz_var ) return action; } return NULL;}/***************************************************************************** * All normal menus * Simple Code *****************************************************************************/#define BAR_ADD( func, title ) { \ QMenu *_menu = func; _menu->setTitle( title ); bar->addMenu( _menu ); }#define BAR_DADD( func, title, id ) { \ QMenu *_menu = func; _menu->setTitle( title ); bar->addMenu( _menu ); \ MenuFunc *f = new MenuFunc( _menu, id ); \ CONNECT( _menu, aboutToShow(), THEDP->menusUpdateMapper, map() ); \ THEDP->menusUpdateMapper->setMapping( _menu, f ); }#define ACT_ADD( _menu, val, title ) { \ QAction *_action = new QAction( title, _menu ); _action->setData( val ); \ _menu->addAction( _action ); }/** * Main Menu Bar Creation **/void QVLCMenu::createMenuBar( MainInterface *mi, intf_thread_t *p_intf, bool visual_selector_enabled ){ /* QMainWindows->menuBar() gives the QProcess::destroyed timeout issue on Cleanlooks style with setDesktopAware set to false */ QMenuBar *bar = mi->menuBar(); BAR_ADD( FileMenu(), qtr( "&Media" ) ); BAR_DADD( AudioMenu( p_intf, NULL ), qtr( "&Audio" ), 1 ); BAR_DADD( VideoMenu( p_intf, NULL ), qtr( "&Video" ), 2 ); BAR_DADD( NavigMenu( p_intf, NULL ), qtr( "P&layback" ), 3 ); BAR_ADD( PlaylistMenu( p_intf, mi ), qtr( "&Playlist" ) ); BAR_ADD( ToolsMenu( p_intf, NULL, mi, visual_selector_enabled, true ), qtr( "&Tools" ) ); BAR_ADD( HelpMenu( NULL ), qtr( "&Help" ) );}#undef BAR_ADD#undef BAR_DADD/** * Media ( File ) Menu * Opening, streaming and quit **/QMenu *QVLCMenu::FileMenu(){ QMenu *menu = new QMenu(); addDPStaticEntry( menu, qtr( "&Open File..." ), "", ":/file-asym", SLOT( openFileDialog() ), "Ctrl+O" ); addDPStaticEntry( menu, qtr( I_OPEN_FOLDER ), "", ":/folder-grey", SLOT( PLOpenDir() ), "Ctrl+F" ); addDPStaticEntry( menu, qtr( "Open &Disc..." ), "", ":/disc", SLOT( openDiscDialog() ), "Ctrl+D" ); addDPStaticEntry( menu, qtr( "Open &Network..." ), "", ":/network", SLOT( openNetDialog() ), "Ctrl+N" ); addDPStaticEntry( menu, qtr( "Open &Capture Device..." ), "", ":/capture-card", SLOT( openCaptureDialog() ), "Ctrl+C" ); menu->addSeparator(); addDPStaticEntry( menu, qtr( "Conve&rt / Save..." ), "", "", SLOT( openThenTranscodingDialogs() ), "Ctrl+R" ); addDPStaticEntry( menu, qtr( "&Streaming..." ), "", ":/stream", SLOT( openThenStreamingDialogs() ), "Ctrl+S" ); menu->addSeparator(); addDPStaticEntry( menu, qtr( "&Quit" ) , "", ":/quit", SLOT( quit() ), "Ctrl+Q" ); return menu;}/* Playlist/MediaLibrary Control */QMenu *QVLCMenu::PlaylistMenu( intf_thread_t *p_intf, MainInterface *mi ){ QMenu *menu = new QMenu(); menu->addMenu( SDMenu( p_intf ) ); menu->addAction( QIcon( ":/playlist_menu" ), qtr( "Show P&laylist" ), mi, SLOT( togglePlaylist() ) ); menu->addSeparator(); addDPStaticEntry( menu, qtr( I_PL_LOAD ), "", "", SLOT( openAPlaylist() ), "Ctrl+X" ); addDPStaticEntry( menu, qtr( I_PL_SAVE ), "", "", SLOT( saveAPlaylist() ), "Ctrl+Y" ); /*menu->addSeparator(); menu->addAction( qtr( "Undock from Interface" ), mi, SLOT( undockPlaylist() ), qtr( "Ctrl+U" ) );*/ return menu;}/** * Tools/View Menu * This is kept in the same menu for now, but could change if it gets much * longer. * This menu can be an interface menu but also a right click menu. **/QMenu *QVLCMenu::ToolsMenu( intf_thread_t *p_intf, QMenu *current, MainInterface *mi, bool visual_selector_enabled, bool with_intf ){ QMenu *menu = new QMenu( current ); if( mi ) { QAction *act= menu->addAction( QIcon( ":/playlist_menu" ), qtr( "Play&list..." ), mi, SLOT( togglePlaylist() ), qtr( "Ctrl+L" ) ); act->setData( "_static_" ); } addDPStaticEntry( menu, qtr( I_MENU_EXT ), "", ":/settings", SLOT( extendedDialog() ), "Ctrl+E" ); menu->addSeparator(); if( with_intf ) { QMenu *intfmenu = InterfacesMenu( p_intf, menu ); MenuFunc *f = new MenuFunc( intfmenu, 4 ); CONNECT( intfmenu, aboutToShow(), THEDP->menusUpdateMapper, map() ); THEDP->menusUpdateMapper->setMapping( intfmenu, f ); menu->addSeparator(); } if( mi ) { /* Minimal View */ QAction *action = menu->addAction( qtr( "Mi&nimal View..." ), mi, SLOT( toggleMinimalView() ), qtr( "Ctrl+H" ) ); action->setCheckable( true ); action->setData( "_static_" ); if( mi->getControlsVisibilityStatus() & CONTROLS_VISIBLE ) action->setChecked( true ); minimalViewAction = action; /* HACK for minimalView */ /* FullScreen View */ action = menu->addAction( qtr( "&Fullscreen Interface" ), mi, SLOT( toggleFullScreen() ), QString( "F11" ) ); action->setCheckable( true ); action->setData( "_static_" ); /* Advanced Controls */ action = menu->addAction( qtr( "&Advanced Controls" ), mi, SLOT( toggleAdvanced() ) ); action->setCheckable( true ); action->setData( "_static_" ); if( mi->getControlsVisibilityStatus() & CONTROLS_ADVANCED ) action->setChecked( true );#if 0 /* For Visualisations. Not yet working */ adv = menu->addAction( qtr( "Visualizations selector" ), mi, SLOT( visual() ) ); adv->setCheckable( true ); if( visual_selector_enabled ) adv->setChecked( true );#endif } menu->addSeparator(); addDPStaticEntry( menu, qtr( I_MENU_MSG ), "", ":/messages", SLOT( messagesDialog() ), "Ctrl+M" ); addDPStaticEntry( menu, qtr( I_MENU_INFO ) , "", ":/info", SLOT( mediaInfoDialog() ), "Ctrl+I" ); addDPStaticEntry( menu, qtr( I_MENU_CODECINFO ) , "", ":/info", SLOT( mediaCodecDialog() ), "Ctrl+J" ); addDPStaticEntry( menu, qtr( I_MENU_BOOKMARK ), "","", SLOT( bookmarksDialog() ), "Ctrl+B" );#ifdef ENABLE_VLM addDPStaticEntry( menu, qtr( I_MENU_VLM ), "", "", SLOT( vlmDialog() ), "Ctrl+W" );#endif menu->addSeparator(); addDPStaticEntry( menu, qtr( "&Preferences..." ), "", ":/preferences", SLOT( prefsDialog() ), "Ctrl+P" ); return menu;}/** * Interface Sub-Menu, to list extras interface and skins **/QMenu *QVLCMenu::InterfacesMenu( intf_thread_t *p_intf, QMenu *current ){ vector<int> objects; vector<const char *> varnames; /** \todo add "switch to XXX" */ varnames.push_back( "intf-add" ); objects.push_back( p_intf->i_object_id ); return Populate( p_intf, current, varnames, objects );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -