static int CreateChoicesMenu( intf_thread_t *p_intf, GtkMenu *submenu, const char *psz_var, vlc_object_t *p_object, bool b_root ) { vlc_value_t val, val_list, text_list; int i_type, i; /* Check the type of the object variable */ i_type = var_Type( p_object, psz_var ); /* Make sure we want to display the variable */ if( !g_list_length(GTK_MENU_SHELL(submenu)->children) && IsMenuEmpty( psz_var, p_object, b_root ) ) return VLC_EGENERIC; switch( i_type & VLC_VAR_TYPE ) { case VLC_VAR_VOID: case VLC_VAR_BOOL: case VLC_VAR_VARIABLE: case VLC_VAR_STRING: case VLC_VAR_INTEGER: case VLC_VAR_FLOAT: break; default: /* Variable doesn't exist or isn't handled */ return VLC_EGENERIC; } if( var_Change( p_object, psz_var, VLC_VAR_GETLIST, &val_list, &text_list ) < 0 ) { return VLC_EGENERIC; } #define CURVAL val_list.p_list->p_values[i] #define CURTEXT text_list.p_list->p_values[i].psz_string for( i = 0; i < val_list.p_list->i_count; i++ ) { vlc_value_t another_val; char string[16] = {0}; char *menutext = string; switch( i_type & VLC_VAR_TYPE ) { case VLC_VAR_VARIABLE: { GtkWidget *subsubmenu = gtk_menu_new(); GtkWidget *submenuitem = gtk_menu_item_new_with_label( CURTEXT ? CURTEXT : CURVAL.psz_string ); gtk_menu_item_set_submenu(GTK_MENU_ITEM(submenuitem), subsubmenu); gtk_menu_append( submenu, submenuitem ); CreateChoicesMenu( p_intf, GTK_MENU(subsubmenu), CURVAL.psz_string, p_object, false ); break; } case VLC_VAR_STRING: var_Get( p_object, psz_var, &val ); another_val.psz_string = strdup( CURVAL.psz_string ); menutext = CURTEXT ? CURTEXT : another_val.psz_string; CreateAndConnect( p_intf, submenu, psz_var, menutext, "", ITEM_RADIO, p_object, another_val, i_type, val.psz_string && !strcmp( val.psz_string, CURVAL.psz_string ) ); free( val.psz_string ); break; case VLC_VAR_INTEGER: var_Get( p_object, psz_var, &val ); if( CURTEXT ) menutext = CURTEXT; else snprintf( menutext, sizeof(string)-1, "%"PRId64, CURVAL.i_int ); CreateAndConnect( p_intf, submenu, psz_var, menutext, "", ITEM_RADIO, p_object, CURVAL, i_type, ( CURVAL.i_int == val.i_int ) && CheckTitle( p_object, psz_var ) ); break; case VLC_VAR_FLOAT: var_Get( p_object, psz_var, &val ); if( CURTEXT ) menutext = CURTEXT; else snprintf( menutext, sizeof(string)-1, "%.2f", CURVAL.f_float ); CreateAndConnect( p_intf, submenu, psz_var, menutext, "", ITEM_RADIO, p_object, CURVAL, i_type, CURVAL.f_float == val.f_float ); break; default: break; } } /* clean up everything */ var_FreeList( &val_list, &text_list ); #undef CURVAL #undef CURTEXT return !g_list_length(GTK_MENU_SHELL(submenu)->children) ? VLC_EGENERIC : VLC_SUCCESS; }
static void UpdateItem( intf_thread_t *p_intf, GtkMenu *menu, const char *psz_var, vlc_object_t *p_object, bool b_submenu ) { vlc_value_t val, text; int i_type; /* Check the type of the object variable */ /* This HACK is needed so we have a radio button for audio and video tracks instread of a checkbox */ if( !strcmp( psz_var, "audio-es" ) || !strcmp( psz_var, "video-es" ) ) i_type = VLC_VAR_INTEGER | VLC_VAR_HASCHOICE; else i_type = var_Type( p_object, psz_var ); switch( i_type & VLC_VAR_TYPE ) { case VLC_VAR_VOID: case VLC_VAR_BOOL: case VLC_VAR_VARIABLE: case VLC_VAR_STRING: case VLC_VAR_INTEGER: case VLC_VAR_FLOAT: break; default: /* Variable doesn't exist or isn't handled */ return; } /* Make sure we want to display the variable */ if( !g_list_length(GTK_MENU_SHELL(menu)->children) && IsMenuEmpty( psz_var, p_object, true ) ) { return; } /* Get the descriptive name of the variable */ int i_ret = var_Change( p_object, psz_var, VLC_VAR_GETTEXT, &text, NULL ); if( i_ret != VLC_SUCCESS ) { text.psz_string = NULL; } /* Some specific stuff */ bool forceDisabled = false; if( !strcmp( psz_var, "spu-es" ) ) { vlc_object_t *p_vout = get_vout(p_intf); forceDisabled = ( p_vout == NULL ); if( p_vout ) vlc_object_release( p_vout ); } if( i_type & VLC_VAR_HASCHOICE ) { /* Append choices menu */ if( b_submenu ) { GtkWidget *item = gtk_menu_item_new_with_label( text.psz_string ? text.psz_string : psz_var ); GtkWidget *submenu = gtk_menu_new( ); gtk_menu_append( menu, item ); gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu); if( CreateChoicesMenu( p_intf, GTK_MENU(submenu), psz_var, p_object, true ) ) gtk_widget_set_sensitive(item, false); if( forceDisabled ) gtk_widget_set_sensitive(item, false); } else { if( CreateChoicesMenu( p_intf, menu, psz_var, p_object, true ) ) gtk_widget_set_sensitive(menu, false); } FREENULL( text.psz_string ); return; } switch( i_type & VLC_VAR_TYPE ) { case VLC_VAR_VOID: var_Get( p_object, psz_var, &val ); CreateAndConnect( p_intf, menu, psz_var, text.psz_string, "", ITEM_NORMAL, p_object, val, i_type, false ); break; case VLC_VAR_BOOL: var_Get( p_object, psz_var, &val ); val.b_bool = !val.b_bool; CreateAndConnect( p_intf, menu, psz_var, text.psz_string, "", ITEM_CHECK, p_object, val, i_type, !val.b_bool ); break; } FREENULL( text.psz_string ); }
int QVLCMenu::CreateChoicesMenu( QMenu *submenu, const char *psz_var, vlc_object_t *p_object, bool b_root ) { vlc_value_t val, val_list, text_list; int i_type, i; /* Check the type of the object variable */ i_type = var_Type( p_object, psz_var ); /* Make sure we want to display the variable */ if( submenu->isEmpty() && IsMenuEmpty( psz_var, p_object, b_root ) ) return VLC_EGENERIC; switch( i_type & VLC_VAR_TYPE ) { case VLC_VAR_VOID: case VLC_VAR_BOOL: case VLC_VAR_VARIABLE: case VLC_VAR_STRING: case VLC_VAR_INTEGER: case VLC_VAR_FLOAT: break; default: /* Variable doesn't exist or isn't handled */ return VLC_EGENERIC; } if( var_Change( p_object, psz_var, VLC_VAR_GETLIST, &val_list, &text_list ) < 0 ) { return VLC_EGENERIC; } #define CURVAL val_list.p_list->p_values[i] #define CURTEXT text_list.p_list->p_values[i].psz_string for( i = 0; i < val_list.p_list->i_count; i++ ) { vlc_value_t another_val; QString menutext; QMenu *subsubmenu = new QMenu( submenu ); switch( i_type & VLC_VAR_TYPE ) { case VLC_VAR_VARIABLE: CreateChoicesMenu( subsubmenu, CURVAL.psz_string, p_object, false ); subsubmenu->setTitle( qfu( CURTEXT ? CURTEXT :CURVAL.psz_string ) ); submenu->addMenu( subsubmenu ); break; case VLC_VAR_STRING: var_Get( p_object, psz_var, &val ); another_val.psz_string = strdup( CURVAL.psz_string ); menutext = qfu( CURTEXT ? CURTEXT : another_val.psz_string ); CreateAndConnect( submenu, psz_var, menutext, "", ITEM_RADIO, p_object, another_val, i_type, val.psz_string && !strcmp( val.psz_string, CURVAL.psz_string ) ); free( val.psz_string ); break; case VLC_VAR_INTEGER: var_Get( p_object, psz_var, &val ); if( CURTEXT ) menutext = qfu( CURTEXT ); else menutext.sprintf( "%d", CURVAL.i_int ); CreateAndConnect( submenu, psz_var, menutext, "", ITEM_RADIO, p_object, CURVAL, i_type, ( CURVAL.i_int == val.i_int ) && CheckTitle( p_object, psz_var ) ); break; case VLC_VAR_FLOAT: var_Get( p_object, psz_var, &val ); if( CURTEXT ) menutext = qfu( CURTEXT ); else menutext.sprintf( "%.2f", CURVAL.f_float ); CreateAndConnect( submenu, psz_var, menutext, "", ITEM_RADIO, p_object, CURVAL, i_type, CURVAL.f_float == val.f_float ); break; default: break; } } currentGroup = NULL; /* clean up everything */ var_FreeList( &val_list, &text_list ); #undef CURVAL #undef CURTEXT return submenu->isEmpty() ? VLC_EGENERIC : VLC_SUCCESS; }
/* Main Menu that sticks everything together */ void QVLCMenu::PopupMenu( intf_thread_t *p_intf, bool show ) { /* Delete old popup if there is one */ if( p_intf->p_sys->p_popup_menu ) delete p_intf->p_sys->p_popup_menu; if( !show ) { p_intf->p_sys->p_popup_menu = NULL; return; } /* */ QMenu *menu = new QMenu(); QAction *action; bool b_isFullscreen = false; MainInterface *mi = p_intf->p_sys->p_mi; POPUP_BOILERPLATE; PopupPlayEntries( menu, p_intf, p_input ); PopupMenuPlaylistControlEntries( menu, p_intf ); menu->addSeparator(); if( p_input ) { QMenu *submenu; vout_thread_t *p_vout = THEMIM->getVout(); /* Add a fullscreen switch button, since it is the most used function */ if( p_vout ) { vlc_value_t val; var_Get( p_vout, "fullscreen", &val ); b_isFullscreen = !( !val.b_bool ); if( b_isFullscreen ) CreateAndConnect( menu, "fullscreen", qtr( "Leave Fullscreen" ),"" , ITEM_NORMAL, VLC_OBJECT(p_vout), val, VLC_VAR_BOOL, b_isFullscreen ); vlc_object_release( p_vout ); menu->addSeparator(); } /* Input menu */ InputAutoMenuBuilder( p_input, objects, varnames ); /* Audio menu */ submenu = new QMenu( menu ); action = menu->addMenu( AudioMenu( p_intf, submenu ) ); action->setText( qtr( "&Audio" ) ); if( action->menu()->isEmpty() ) action->setEnabled( false ); /* Video menu */ submenu = new QMenu( menu ); action = menu->addMenu( VideoMenu( p_intf, submenu ) ); action->setText( qtr( "&Video" ) ); if( action->menu()->isEmpty() ) action->setEnabled( false ); /* Playback menu for chapters */ submenu = new QMenu( menu ); action = menu->addMenu( NavigMenu( p_intf, 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 ) { QMenu *submenu = new QMenu( qtr( "Interface" ), menu ); QMenu *tools = ToolsMenu( submenu ); submenu->addSeparator(); /* In skins interface, append some items */ if( !mi ) { vlc_object_t *p_object = ( vlc_object_t* ) vlc_object_find_name( p_intf, "skins2", FIND_PARENT ); if( p_object ) { objects.clear(); varnames.clear(); objects.push_back( p_object ); varnames.push_back( "intf-skins" ); Populate( p_intf, submenu, varnames, objects ); objects.clear(); varnames.clear(); objects.push_back( p_object ); varnames.push_back( "intf-skins-interactive" ); Populate( p_intf, submenu, varnames, objects ); vlc_object_release( p_object ); } else msg_Warn( p_intf, "could not find parent interface" ); } else menu->addMenu( ViewMenu( p_intf, mi, false )); menu->addMenu( submenu ); } /* Static entries for ending, like open */ PopupMenuStaticEntries( menu ); p_intf->p_sys->p_popup_menu = menu; p_intf->p_sys->p_popup_menu->popup( QCursor::pos() ); }
void QVLCMenu::UpdateItem( intf_thread_t *p_intf, QMenu *menu, const char *psz_var, vlc_object_t *p_object, bool b_submenu ) { vlc_value_t val, text; int i_type; QAction *action = FindActionWithVar( menu, psz_var ); if( action ) DeleteNonStaticEntries( action->menu() ); if( !p_object ) { if( action ) action->setEnabled( false ); return; } /* Check the type of the object variable */ /* This HACK is needed so we have a radio button for audio and video tracks instread of a checkbox */ if( !strcmp( psz_var, "audio-es" ) || !strcmp( psz_var, "video-es" ) ) i_type = VLC_VAR_INTEGER | VLC_VAR_HASCHOICE; else i_type = var_Type( p_object, psz_var ); switch( i_type & VLC_VAR_TYPE ) { case VLC_VAR_VOID: case VLC_VAR_BOOL: case VLC_VAR_VARIABLE: case VLC_VAR_STRING: case VLC_VAR_INTEGER: case VLC_VAR_FLOAT: break; default: /* Variable doesn't exist or isn't handled */ if( action ) action->setEnabled( false ); return; } /* Make sure we want to display the variable */ if( menu->isEmpty() && IsMenuEmpty( psz_var, p_object ) ) { if( action ) action->setEnabled( false ); return; } /* Get the descriptive name of the variable */ int i_ret = var_Change( p_object, psz_var, VLC_VAR_GETTEXT, &text, NULL ); if( i_ret != VLC_SUCCESS ) { text.psz_string = NULL; } if( !action ) { action = new QAction( TEXT_OR_VAR, menu ); menu->addAction( action ); action->setData( psz_var ); } /* Some specific stuff */ bool forceDisabled = false; if( !strcmp( psz_var, "spu-es" ) ) { vout_thread_t *p_vout = THEMIM->getVout(); forceDisabled = ( p_vout == NULL ); if( p_vout ) vlc_object_release( p_vout ); } if( i_type & VLC_VAR_HASCHOICE ) { /* Append choices menu */ if( b_submenu ) { QMenu *submenu; submenu = action->menu(); if( !submenu ) { submenu = new QMenu( menu ); action->setMenu( submenu ); } action->setEnabled( CreateChoicesMenu( submenu, psz_var, p_object, true ) == 0 ); if( forceDisabled ) action->setEnabled( false ); } else { action->setEnabled( CreateChoicesMenu( menu, psz_var, p_object, true ) == 0 ); } FREENULL( text.psz_string ); return; } switch( i_type & VLC_VAR_TYPE ) { case VLC_VAR_VOID: var_Get( p_object, psz_var, &val ); CreateAndConnect( menu, psz_var, TEXT_OR_VAR, "", ITEM_NORMAL, p_object, val, i_type ); break; case VLC_VAR_BOOL: var_Get( p_object, psz_var, &val ); val.b_bool = !val.b_bool; CreateAndConnect( menu, psz_var, TEXT_OR_VAR, "", ITEM_CHECK, p_object, val, i_type, !val.b_bool ); break; } FREENULL( text.psz_string ); }