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; }
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 ); }
HMENU CreateChoicesMenu( intf_thread_t *p_intf, vector<MenuItemExt*> *p_menu_list, char *psz_var, vlc_object_t *p_object, int *pi_item_id ) { MenuItemExt *pMenuItemExt; vlc_value_t val, val_list, text_list; int i_type, i; HMENU hSubMenu = CreatePopupMenu(); /* Check the type of the object variable */ i_type = var_Type( p_object, psz_var ); /* Make sure we want to display the variable */ if( i_type & VLC_VAR_HASCHOICE ) { var_Change( p_object, psz_var, VLC_VAR_CHOICESCOUNT, &val, NULL ); if( val.i_int == 0 ) return NULL; if( (i_type & VLC_VAR_TYPE) != VLC_VAR_VARIABLE && val.i_int == 1 ) return NULL; } else { return NULL; } 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: break; default: /* Variable doesn't exist or isn't handled */ return NULL; } if( var_Get( p_object, psz_var, &val ) < 0 ) return NULL; if( var_Change( p_object, psz_var, VLC_VAR_GETLIST, &val_list, &text_list ) < 0 ) { if( (i_type & VLC_VAR_TYPE) == VLC_VAR_STRING ) free( val.psz_string ); return NULL; } for( i = 0; i < val_list.p_list->i_count; i++ ) { vlc_value_t another_val; HMENU hMenuItem; char *psz_tmp; switch( i_type & VLC_VAR_TYPE ) { case VLC_VAR_VARIABLE: hMenuItem = CreateChoicesMenu( p_intf, p_menu_list, val_list.p_list->p_values[i].psz_string, p_object, pi_item_id ); AppendMenu( hSubMenu, MF_STRING | MF_POPUP, (UINT)hMenuItem, _FROMMB(text_list.p_list->p_values[i].psz_string ? text_list.p_list->p_values[i].psz_string : val_list.p_list->p_values[i].psz_string) ); break; case VLC_VAR_STRING: another_val.psz_string = strdup(val_list.p_list->p_values[i].psz_string); AppendMenu( hSubMenu, MF_STRING, ++(*pi_item_id), _FROMMB(text_list.p_list->p_values[i].psz_string ? text_list.p_list->p_values[i].psz_string : val_list.p_list->p_values[i].psz_string) ); pMenuItemExt = new MenuItemExt( p_intf, *pi_item_id, psz_var, p_object, another_val, i_type ); p_menu_list->push_back( pMenuItemExt ); if( !(i_type & VLC_VAR_ISCOMMAND) && val.psz_string && !strcmp( val.psz_string, val_list.p_list->p_values[i].psz_string ) ) CheckMenuItem( hSubMenu, *pi_item_id, MF_CHECKED | MF_BYCOMMAND); break; case VLC_VAR_INTEGER: asprintf( &psz_tmp, "%d", val_list.p_list->p_values[i].i_int ); AppendMenu( hSubMenu, MF_STRING, ++(*pi_item_id), _FROMMB(text_list.p_list->p_values[i].psz_string ? text_list.p_list->p_values[i].psz_string : psz_tmp)); free( psz_tmp ); pMenuItemExt = new MenuItemExt( p_intf, *pi_item_id, psz_var, p_object, val_list.p_list->p_values[i], i_type ); p_menu_list->push_back( pMenuItemExt ); if( val_list.p_list->p_values[i].i_int == val.i_int ) CheckMenuItem( hSubMenu, *pi_item_id, MF_CHECKED | MF_BYCOMMAND); break; default: break; } } /* Clean up everything */ if( (i_type & VLC_VAR_TYPE) == VLC_VAR_STRING ) free( val.psz_string ); var_FreeList( &val_list, &text_list ); return hSubMenu; }
/***************************************************************************** * Private methods. *****************************************************************************/ void CreateMenuItem( intf_thread_t *p_intf, vector<MenuItemExt*> *p_menu_list, HMENU hMenu, char *psz_var, vlc_object_t *p_object, int *pi_item_id ) { MenuItemExt *pMenuItemExt; HMENU hMenuItem; vlc_value_t val, text; int i_type; /* Check the type of the object variable */ 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( i_type & VLC_VAR_HASCHOICE ) { var_Change( p_object, psz_var, VLC_VAR_CHOICESCOUNT, &val, NULL ); if( val.i_int == 0 ) return; if( (i_type & VLC_VAR_TYPE) != VLC_VAR_VARIABLE && val.i_int == 1 ) return; } /* Get the descriptive name of the variable */ var_Change( p_object, psz_var, VLC_VAR_GETTEXT, &text, NULL ); var_Get( p_object, psz_var, &val ); if( i_type & VLC_VAR_HASCHOICE ) { hMenuItem = CreateChoicesMenu( p_intf, p_menu_list, psz_var, p_object, pi_item_id ); AppendMenu( hMenu, MF_STRING | MF_POPUP, (UINT)hMenuItem, _FROMMB(text.psz_string ? text.psz_string : psz_var) ); if( (i_type & VLC_VAR_TYPE) == VLC_VAR_STRING ) free( val.psz_string ); free( text.psz_string ); return; } switch( i_type & VLC_VAR_TYPE ) { case VLC_VAR_VOID: AppendMenu( hMenu, MF_STRING , ++(*pi_item_id), _FROMMB(text.psz_string ? text.psz_string : psz_var) ); pMenuItemExt = new MenuItemExt( p_intf, *pi_item_id, psz_var, p_object, val, i_type ); p_menu_list->push_back( pMenuItemExt ); break; case VLC_VAR_BOOL: val.b_bool = !val.b_bool; AppendMenu( hMenu, MF_STRING | MF_CHECKED, ++(*pi_item_id), _FROMMB(text.psz_string ? text.psz_string : psz_var) ); pMenuItemExt = new MenuItemExt( p_intf, *pi_item_id, psz_var, p_object, val, i_type ); p_menu_list->push_back( pMenuItemExt ); CheckMenuItem( hMenu, *pi_item_id , ( val.b_bool ? MF_UNCHECKED : MF_CHECKED ) | MF_BYCOMMAND ); break; default: free( text.psz_string ); return; } if( (i_type & VLC_VAR_TYPE) == VLC_VAR_STRING ) free( val.psz_string ); free( text.psz_string ); }