Commit b1e4fd1c authored by Loïc Minier's avatar Loïc Minier

The "we love gibalou" commit :

  * plugins/gtk/gnome.c, plugins/gtk/gtk.c, plugins/gtk/gtk_common.h :
      . new Tooltips structure
  * plugins/gtk/gtk_preferences.c:
      . modifications of some widgets, the structure, cosmetic changes
  * src/interface/main.c:
      . typos
      . a couple new descriptions
parent 2feb20f8
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* gnome.c : Gnome plugin for vlc * gnome.c : Gnome plugin for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2000 VideoLAN * Copyright (C) 2000 VideoLAN
* $Id: gnome.c,v 1.13 2002/03/25 02:06:24 jobi Exp $ * $Id: gnome.c,v 1.14 2002/03/25 20:37:00 lool Exp $
* *
* Authors: Samuel Hocevar <sam@zoy.org> * Authors: Samuel Hocevar <sam@zoy.org>
* *
...@@ -250,6 +250,7 @@ static void intf_Run( intf_thread_t *p_intf ) ...@@ -250,6 +250,7 @@ static void intf_Run( intf_thread_t *p_intf )
p_intf->p_sys->p_network = NULL; p_intf->p_sys->p_network = NULL;
p_intf->p_sys->p_sat = NULL; p_intf->p_sys->p_sat = NULL;
p_intf->p_sys->p_jump = NULL; p_intf->p_sys->p_jump = NULL;
p_intf->p_sys->p_tooltips = gtk_tooltips_new();
/* Store p_intf to keep an eye on it */ /* Store p_intf to keep an eye on it */
gtk_object_set_data( GTK_OBJECT(p_intf->p_sys->p_window), gtk_object_set_data( GTK_OBJECT(p_intf->p_sys->p_window),
...@@ -280,6 +281,9 @@ static void intf_Run( intf_thread_t *p_intf ) ...@@ -280,6 +281,9 @@ static void intf_Run( intf_thread_t *p_intf )
/* Remove the timeout */ /* Remove the timeout */
gtk_timeout_remove( i_dummy ); gtk_timeout_remove( i_dummy );
/* Destroy the Tooltips structure */
gtk_object_destroy( GTK_OBJECT(p_intf->p_sys->p_tooltips) );
/* Get rid of stored callbacks so we can unload the plugin */ /* Get rid of stored callbacks so we can unload the plugin */
for( i_dummy = 0; for( i_dummy = 0;
i_dummy < MAX_ATEXIT && p_intf->p_sys->pf_callback[i_dummy] != NULL; i_dummy < MAX_ATEXIT && p_intf->p_sys->pf_callback[i_dummy] != NULL;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* gtk.c : Gtk+ plugin for vlc * gtk.c : Gtk+ plugin for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2000-2001 VideoLAN * Copyright (C) 2000-2001 VideoLAN
* $Id: gtk.c,v 1.15 2002/03/25 02:06:24 jobi Exp $ * $Id: gtk.c,v 1.16 2002/03/25 20:37:00 lool Exp $
* *
* Authors: Samuel Hocevar <sam@zoy.org> * Authors: Samuel Hocevar <sam@zoy.org>
* *
...@@ -198,10 +198,11 @@ static void intf_Run( intf_thread_t *p_intf ) ...@@ -198,10 +198,11 @@ static void intf_Run( intf_thread_t *p_intf )
gtk_init( &i_args, &pp_args ); gtk_init( &i_args, &pp_args );
/* Create some useful widgets that will certainly be used */ /* Create some useful widgets that will certainly be used */
p_intf->p_sys->p_window = create_intf_window( ); p_intf->p_sys->p_window = create_intf_window();
p_intf->p_sys->p_popup = create_intf_popup( ); p_intf->p_sys->p_popup = create_intf_popup();
p_intf->p_sys->p_playlist = create_intf_playlist(); p_intf->p_sys->p_playlist = create_intf_playlist();
p_intf->p_sys->p_messages = create_intf_messages(); p_intf->p_sys->p_messages = create_intf_messages();
p_intf->p_sys->p_tooltips = gtk_tooltips_new();
/* Set the title of the main window */ /* Set the title of the main window */
gtk_window_set_title( GTK_WINDOW(p_intf->p_sys->p_window), gtk_window_set_title( GTK_WINDOW(p_intf->p_sys->p_window),
...@@ -283,6 +284,9 @@ static void intf_Run( intf_thread_t *p_intf ) ...@@ -283,6 +284,9 @@ static void intf_Run( intf_thread_t *p_intf )
/* Remove the timeout */ /* Remove the timeout */
gtk_timeout_remove( i_dummy ); gtk_timeout_remove( i_dummy );
/* Destroy the Tooltips structure */
gtk_object_destroy( GTK_OBJECT(p_intf->p_sys->p_tooltips) );
/* Launch stored callbacks */ /* Launch stored callbacks */
for( i_dummy = 0; for( i_dummy = 0;
i_dummy < MAX_ATEXIT && p_intf->p_sys->pf_callback[i_dummy] != NULL; i_dummy < MAX_ATEXIT && p_intf->p_sys->pf_callback[i_dummy] != NULL;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* gtk_common.h: private Gtk+ interface description * gtk_common.h: private Gtk+ interface description
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * Copyright (C) 1999, 2000 VideoLAN
* $Id: gtk_common.h,v 1.6 2002/03/25 02:06:24 jobi Exp $ * $Id: gtk_common.h,v 1.7 2002/03/25 20:37:00 lool Exp $
* *
* Authors: Samuel Hocevar <sam@zoy.org> * Authors: Samuel Hocevar <sam@zoy.org>
* *
...@@ -72,6 +72,8 @@ typedef struct intf_sys_s ...@@ -72,6 +72,8 @@ typedef struct intf_sys_s
GtkWidget * p_network; /* network stream window */ GtkWidget * p_network; /* network stream window */
GtkWidget * p_jump; /* jump window */ GtkWidget * p_jump; /* jump window */
GtkTooltips * p_tooltips; /* tooltips */
/* The slider */ /* The slider */
GtkFrame * p_slider_frame; GtkFrame * p_slider_frame;
GtkAdjustment * p_adj; /* slider adjustment object */ GtkAdjustment * p_adj; /* slider adjustment object */
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* gtk_preferences.c: functions to handle the preferences dialog box. * gtk_preferences.c: functions to handle the preferences dialog box.
***************************************************************************** *****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN * Copyright (C) 2000, 2001 VideoLAN
* $Id: gtk_preferences.c,v 1.14 2002/03/16 01:40:58 gbazin Exp $ * $Id: gtk_preferences.c,v 1.15 2002/03/25 20:37:00 lool Exp $
* *
* Authors: Gildas Bazin <gbazin@netcourrier.com> * Authors: Gildas Bazin <gbazin@netcourrier.com>
* *
...@@ -55,7 +55,6 @@ static void GtkCreateConfigDialog( char *, intf_thread_t * ); ...@@ -55,7 +55,6 @@ static void GtkCreateConfigDialog( char *, intf_thread_t * );
static void GtkConfigOk ( GtkButton *, gpointer ); static void GtkConfigOk ( GtkButton *, gpointer );
static void GtkConfigApply ( GtkButton *, gpointer ); static void GtkConfigApply ( GtkButton *, gpointer );
static void GtkConfigCancel ( GtkButton *, gpointer ); static void GtkConfigCancel ( GtkButton *, gpointer );
static void GtkConfigSave ( GtkButton *, gpointer );
static void GtkConfigDialogDestroyed ( GtkObject *, gpointer ); static void GtkConfigDialogDestroyed ( GtkObject *, gpointer );
...@@ -77,7 +76,9 @@ static void GtkPluginHighlighted ( GtkCList *, int, int, GdkEventButton *, ...@@ -77,7 +76,9 @@ static void GtkPluginHighlighted ( GtkCList *, int, int, GdkEventButton *,
****************************************************************************/ ****************************************************************************/
void GtkPreferencesActivate( GtkMenuItem * menuitem, gpointer user_data ) void GtkPreferencesActivate( GtkMenuItem * menuitem, gpointer user_data )
{ {
intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), (char*)user_data ); intf_thread_t * p_intf;
p_intf = GetIntf( GTK_WIDGET(menuitem), (char*)user_data );
GtkCreateConfigDialog( "main", p_intf ); GtkCreateConfigDialog( "main", p_intf );
} }
...@@ -86,31 +87,59 @@ void GtkPreferencesActivate( GtkMenuItem * menuitem, gpointer user_data ) ...@@ -86,31 +87,59 @@ void GtkPreferencesActivate( GtkMenuItem * menuitem, gpointer user_data )
* GtkCreateConfigDialog: dynamically creates the configuration dialog * GtkCreateConfigDialog: dynamically creates the configuration dialog
* box from all the configuration data provided by the selected module. * box from all the configuration data provided by the selected module.
****************************************************************************/ ****************************************************************************/
/* create a new tooltipped area */
#define TOOLTIP( container, text, ev_box ) \
/* create an event box to catch some events */ \
ev_box = gtk_event_box_new(); \
gtk_container_add( GTK_CONTAINER(container), ev_box ); \
/* add a tooltip on mouseover */ \
/* FIXME: have a different text for the private text */ \
gtk_tooltips_set_tip( p_intf->p_sys->p_tooltips, \
ev_box, text, text ); \
gtk_container_set_border_width( GTK_CONTAINER(ev_box), 2 );
/* draws a right aligned label in side of a widget */
#define LABEL_AND_WIDGET( text, widget, hbox, label, align ) \
gtk_table_resize( GTK_TABLE(category_table), ++rows, 2 ); \
align = gtk_alignment_new( 1, .5, 0, 0 ); \
label = gtk_label_new( text ); \
gtk_container_add( GTK_CONTAINER(align), label ); \
gtk_table_attach_defaults( GTK_TABLE(category_table), align, \
0, 1, rows - 1, rows ); \
align = gtk_alignment_new( 0, .5, 0, 0 ); \
gtk_container_add( GTK_CONTAINER(align), widget ); \
gtk_table_attach_defaults( GTK_TABLE(category_table), align, \
1, 2, rows - 1, rows );
static void GtkCreateConfigDialog( char *psz_module_name, static void GtkCreateConfigDialog( char *psz_module_name,
intf_thread_t *p_intf ) intf_thread_t *p_intf )
{ {
module_t *p_module, *p_module_bis; module_t *p_module, *p_module_bis;
int i; int i;
guint rows = 0;
GHashTable *config_hash_table; GHashTable *config_hash_table;
GtkWidget *item_event_box;
GtkWidget *config_dialog; GtkWidget *config_dialog;
GtkWidget *config_dialog_vbox; GtkWidget *config_dialog_vbox;
GtkWidget *config_notebook; GtkWidget *config_notebook;
GtkWidget *scrolled_window; GtkWidget *category_table = NULL;
GtkWidget *category_vbox = NULL; GtkWidget *category_vbox = NULL;
GtkWidget *dialog_action_area; GtkWidget *dialog_action_area;
GtkWidget *ok_button; GtkWidget *ok_button;
GtkWidget *apply_button; GtkWidget *apply_button;
GtkWidget *save_button;
GtkWidget *cancel_button; GtkWidget *cancel_button;
GtkWidget *item_align;
GtkWidget *item_frame; GtkWidget *item_frame;
GtkWidget *item_table;
GtkWidget *item_hbox; GtkWidget *item_hbox;
GtkWidget *item_label; GtkWidget *item_label;
GtkWidget *item_text; GtkWidget *item_vbox;
GtkWidget *string_entry; GtkWidget *string_entry;
GtkWidget *integer_spinbutton; GtkWidget *integer_spinbutton;
GtkObject *item_adj; GtkObject *item_adj;
...@@ -125,6 +154,7 @@ static void GtkCreateConfigDialog( char *psz_module_name, ...@@ -125,6 +154,7 @@ static void GtkCreateConfigDialog( char *psz_module_name,
* close the dialog window, but remember that it is only hidden if you * close the dialog window, but remember that it is only hidden if you
* clicked on the action buttons). This trick also allows us not to * clicked on the action buttons). This trick also allows us not to
* duplicate identical dialog windows. */ * duplicate identical dialog windows. */
config_dialog = (GtkWidget *)gtk_object_get_data( config_dialog = (GtkWidget *)gtk_object_get_data(
GTK_OBJECT(p_intf->p_sys->p_window), psz_module_name ); GTK_OBJECT(p_intf->p_sys->p_window), psz_module_name );
if( config_dialog ) if( config_dialog )
...@@ -146,33 +176,24 @@ static void GtkCreateConfigDialog( char *psz_module_name, ...@@ -146,33 +176,24 @@ static void GtkCreateConfigDialog( char *psz_module_name,
} }
if( !p_module ) return; if( !p_module ) return;
/* We found it, now we can start building its configuration interface */
/*
* We found it, now we can start building its configuration interface
*/
/* Create the configuration dialog box */ /* Create the configuration dialog box */
config_dialog = gtk_dialog_new(); config_dialog = gtk_dialog_new();
gtk_window_set_title( GTK_WINDOW(config_dialog), p_module->psz_longname ); gtk_window_set_title( GTK_WINDOW(config_dialog), p_module->psz_longname );
gtk_window_set_default_size( GTK_WINDOW(config_dialog),
600 /*width*/, 400/*height*/ );
config_dialog_vbox = GTK_DIALOG(config_dialog)->vbox; config_dialog_vbox = GTK_DIALOG(config_dialog)->vbox;
gtk_widget_show( config_dialog_vbox );
gtk_container_set_border_width( GTK_CONTAINER(config_dialog_vbox), 0 ); gtk_container_set_border_width( GTK_CONTAINER(config_dialog_vbox), 0 );
/* Create our config hash table and associate it with the dialog box */ /* Create our config hash table and associate it with the dialog box */
config_hash_table = g_hash_table_new( NULL, NULL ); config_hash_table = g_hash_table_new( NULL, NULL );
gtk_object_set_data_full( GTK_OBJECT(config_dialog), "config_hash_table", gtk_object_set_data_full( GTK_OBJECT(config_dialog),
config_hash_table, "config_hash_table", config_hash_table,
(GtkDestroyNotify)GtkFreeHashTable ); (GtkDestroyNotify)GtkFreeHashTable );
/* Create notebook */ /* Create notebook */
config_notebook = gtk_notebook_new(); config_notebook = gtk_notebook_new();
gtk_notebook_set_scrollable( GTK_NOTEBOOK(config_notebook), TRUE); gtk_notebook_set_scrollable( GTK_NOTEBOOK(config_notebook), TRUE );
gtk_widget_show( config_notebook ); gtk_container_add( GTK_CONTAINER(config_dialog_vbox), config_notebook );
gtk_box_pack_start( GTK_BOX(config_dialog_vbox), config_notebook,
TRUE, TRUE, 0 );
/* Enumerate config options and add corresponding config boxes */ /* Enumerate config options and add corresponding config boxes */
for( i = 0; i < p_module->i_config_lines; i++ ) for( i = 0; i < p_module->i_config_lines; i++ )
...@@ -182,101 +203,87 @@ static void GtkCreateConfigDialog( char *psz_module_name, ...@@ -182,101 +203,87 @@ static void GtkCreateConfigDialog( char *psz_module_name,
{ {
case MODULE_CONFIG_HINT_CATEGORY: case MODULE_CONFIG_HINT_CATEGORY:
/* create a new scrolled window. */ /* pack a new vbox in the notebook */
scrolled_window = gtk_scrolled_window_new( NULL, NULL ); category_vbox = gtk_vbox_new( FALSE, 2 );
gtk_scrolled_window_set_policy( gtk_container_set_border_width( GTK_CONTAINER(category_vbox), 2 );
GTK_SCROLLED_WINDOW(scrolled_window), GTK_POLICY_NEVER,
GTK_POLICY_AUTOMATIC );
gtk_widget_show( scrolled_window );
/* add scrolled window as a notebook page */ /* add category vbox as a notebook page */
item_label = gtk_label_new( p_module->p_config[i].psz_text ); item_label = gtk_label_new( p_module->p_config[i].psz_text );
gtk_widget_show( item_label );
gtk_notebook_append_page( GTK_NOTEBOOK(config_notebook), gtk_notebook_append_page( GTK_NOTEBOOK(config_notebook),
scrolled_window, item_label ); category_vbox, item_label );
/* pack a new vbox into the scrolled window */ /* add a new table for right-left alignment */
category_vbox = gtk_vbox_new( FALSE, 10 ); category_table = gtk_table_new( 0, 0, FALSE );
gtk_container_set_border_width( GTK_CONTAINER(category_vbox), 5 ); gtk_table_set_col_spacings( GTK_TABLE(category_table), 2 );
gtk_scrolled_window_add_with_viewport( rows = 0;
GTK_SCROLLED_WINDOW( scrolled_window ), category_vbox ); gtk_container_add( GTK_CONTAINER(category_vbox), category_table );
gtk_widget_show( category_vbox );
break; break;
case MODULE_CONFIG_ITEM_PLUGIN: case MODULE_CONFIG_ITEM_PLUGIN:
/* add new frame for the config option */
item_frame = gtk_frame_new( p_module->p_config[i].psz_text ); item_frame = gtk_frame_new( p_module->p_config[i].psz_text );
gtk_widget_show( item_frame );
gtk_box_pack_start( GTK_BOX(category_vbox), item_frame,
FALSE, FALSE, 5 );
/* add a new table for the config option */ gtk_table_resize( GTK_TABLE(category_table), ++rows, 2 );
item_table = gtk_table_new( 3, 3, FALSE ); gtk_table_attach_defaults( GTK_TABLE(category_table), item_frame,
gtk_widget_show( item_table ); 0, 2, rows - 1, rows );
gtk_container_add( GTK_CONTAINER(item_frame), item_table );
TOOLTIP( item_frame, p_module->p_config[i].psz_longtext,
/* create a new scrolled window */ item_event_box )
scrolled_window = gtk_scrolled_window_new( NULL, NULL );
gtk_scrolled_window_set_policy( item_vbox = gtk_vbox_new( FALSE, 2 );
GTK_SCROLLED_WINDOW(scrolled_window), GTK_POLICY_NEVER, gtk_container_add( GTK_CONTAINER(item_event_box), item_vbox );
GTK_POLICY_AUTOMATIC );
gtk_widget_set_usize( scrolled_window, -2, 150 ); /* create a new clist widget */
gtk_widget_show( scrolled_window ); {
gtk_table_attach( GTK_TABLE(item_table), scrolled_window, gchar * titles[] = { "Name", "Description" };
0, 2, 0, 1, GTK_FILL, GTK_FILL, 5, 5 );
plugin_clist =
/* create a new clist widget and add it to the scrolled win */ gtk_clist_new_with_titles( 2, titles );
plugin_clist = gtk_clist_new_with_titles( 1, }
&p_module->p_config[i].psz_text );
gtk_clist_column_titles_passive( GTK_CLIST(plugin_clist) ); gtk_clist_column_titles_passive( GTK_CLIST(plugin_clist) );
gtk_clist_set_selection_mode( GTK_CLIST(plugin_clist), gtk_clist_set_selection_mode( GTK_CLIST(plugin_clist),
GTK_SELECTION_SINGLE); GTK_SELECTION_SINGLE);
gtk_container_add( GTK_CONTAINER(scrolled_window), plugin_clist ); gtk_container_add( GTK_CONTAINER(item_vbox), plugin_clist );
gtk_widget_show( plugin_clist );
/* build a list of available plugins */ /* build a list of available plugins */
{
gchar * entry[2];
for( p_module_bis = p_module_bank->first ; for( p_module_bis = p_module_bank->first ;
p_module_bis != NULL ; p_module_bis != NULL ;
p_module_bis = p_module_bis->next ) p_module_bis = p_module_bis->next )
{ {
if( p_module_bis->i_capabilities & if( p_module_bis->i_capabilities &
(1 << p_module->p_config[i].i_value) ) (1 << p_module->p_config[i].i_value) )
gtk_clist_append( GTK_CLIST(plugin_clist),
(gchar **)&p_module_bis->psz_name );
}
/* add text box for config description */
if( p_module->p_config[i].psz_longtext )
{ {
item_text = gtk_label_new( p_module->p_config[i].psz_longtext); entry[0] = p_module_bis->psz_name;
gtk_label_set_justify( GTK_LABEL(item_text), GTK_JUSTIFY_LEFT); entry[1] = p_module_bis->psz_longname;
gtk_label_set_line_wrap( GTK_LABEL(item_text), TRUE ); gtk_clist_append( GTK_CLIST(plugin_clist), entry );
gtk_widget_show( item_text ); }
gtk_table_attach( GTK_TABLE(item_table), item_text, }
2, 3, 0, 1, GTK_FILL, GTK_FILL, 5, 5 );
} }
/* pack a label into the config line */ gtk_clist_set_column_auto_resize( GTK_CLIST(plugin_clist),
item_label = gtk_label_new( "" ); 0, TRUE );
gtk_widget_show( item_label ); gtk_clist_set_column_auto_resize( GTK_CLIST(plugin_clist),
gtk_table_attach( GTK_TABLE(item_table), item_label, 1, TRUE );
2, 3, 1, 2, GTK_FILL, GTK_FILL, 5, 5 );
/* connect signals to the plugins list */ /* connect signals to the plugins list */
gtk_signal_connect( GTK_OBJECT(plugin_clist), "select_row", gtk_signal_connect( GTK_OBJECT(plugin_clist), "select_row",
GTK_SIGNAL_FUNC(GtkPluginHighlighted), GTK_SIGNAL_FUNC(GtkPluginHighlighted),
(gpointer)item_label ); NULL );
/* hbox holding the "select" and "configure" buttons */
item_hbox = gtk_hbox_new( FALSE, 2 );
gtk_container_add( GTK_CONTAINER(item_vbox), item_hbox);
/* add configure button */ /* add configure button */
plugin_config_button = plugin_config_button =
gtk_button_new_with_label( _("Configure") ); gtk_button_new_with_label( _("Configure") );
gtk_widget_set_sensitive( plugin_config_button, FALSE ); gtk_widget_set_sensitive( plugin_config_button, FALSE );
gtk_widget_show( plugin_config_button ); gtk_container_add( GTK_CONTAINER(item_hbox),
gtk_table_attach( GTK_TABLE(item_table), plugin_config_button, plugin_config_button );
0, 1, 1, 2, GTK_FILL, GTK_FILL, 5, 5 );
gtk_object_set_data( GTK_OBJECT(plugin_config_button), gtk_object_set_data( GTK_OBJECT(plugin_config_button),
"p_intf", p_intf ); "p_intf", p_intf );
gtk_object_set_data( GTK_OBJECT(plugin_clist), gtk_object_set_data( GTK_OBJECT(plugin_clist),
...@@ -285,23 +292,21 @@ static void GtkCreateConfigDialog( char *psz_module_name, ...@@ -285,23 +292,21 @@ static void GtkCreateConfigDialog( char *psz_module_name,
/* add select button */ /* add select button */
plugin_select_button = plugin_select_button =
gtk_button_new_with_label( _("Select") ); gtk_button_new_with_label( _("Select") );
gtk_widget_show( plugin_select_button ); gtk_container_add( GTK_CONTAINER(item_hbox),
gtk_table_attach( GTK_TABLE(item_table), plugin_select_button, plugin_select_button );
1, 2, 1, 2, GTK_FILL, GTK_FILL, 5, 5 );
/* hbox holding the "selected" label and text input */
item_hbox = gtk_hbox_new( FALSE, 2 );
gtk_container_add( GTK_CONTAINER(item_vbox), item_hbox);
/* add new label */ /* add new label */
item_label = gtk_label_new( _("Selected:") ); item_label = gtk_label_new( _("Selected:") );
gtk_widget_show( item_label ); gtk_container_add( GTK_CONTAINER(item_hbox), item_label );
gtk_table_attach( GTK_TABLE(item_table), item_label,
0, 1, 2, 3, GTK_FILL, GTK_FILL, 5, 5 );
/* add input box with default value */ /* add input box with default value */
string_entry = gtk_entry_new(); string_entry = gtk_entry_new();
gtk_object_set_data( GTK_OBJECT(plugin_clist), gtk_object_set_data( GTK_OBJECT(plugin_clist),
"plugin_entry", string_entry ); "plugin_entry", string_entry );
gtk_widget_show( string_entry ); gtk_container_add( GTK_CONTAINER(item_hbox), string_entry );
gtk_table_attach( GTK_TABLE(item_table), string_entry,
2, 3, 2, 3, GTK_FILL, GTK_FILL, 5, 5 );
vlc_mutex_lock( p_module->p_config[i].p_lock ); vlc_mutex_lock( p_module->p_config[i].p_lock );
gtk_entry_set_text( GTK_ENTRY(string_entry), gtk_entry_set_text( GTK_ENTRY(string_entry),
p_module->p_config[i].psz_value ? p_module->p_config[i].psz_value ?
...@@ -327,126 +332,58 @@ static void GtkCreateConfigDialog( char *psz_module_name, ...@@ -327,126 +332,58 @@ static void GtkCreateConfigDialog( char *psz_module_name,
case MODULE_CONFIG_ITEM_STRING: case MODULE_CONFIG_ITEM_STRING:
case MODULE_CONFIG_ITEM_FILE: case MODULE_CONFIG_ITEM_FILE:
/* add new frame for the config option */
item_frame = gtk_frame_new( p_module->p_config[i].psz_text );
gtk_widget_show( item_frame );
gtk_box_pack_start( GTK_BOX(category_vbox), item_frame,
FALSE, FALSE, 5 );
/* add a new table for the config option */
item_table = gtk_table_new( 1, 1, FALSE );
gtk_widget_show( item_table );
gtk_container_add( GTK_CONTAINER(item_frame), item_table );
/* add input box with default value */ /* add input box with default value */
string_entry = gtk_entry_new(); string_entry = gtk_entry_new();
gtk_widget_show( string_entry );
gtk_table_attach( GTK_TABLE(item_table), string_entry,
0, 1, 0, 1, GTK_FILL, GTK_FILL, 5, 5 );
vlc_mutex_lock( p_module->p_config[i].p_lock ); vlc_mutex_lock( p_module->p_config[i].p_lock );
gtk_entry_set_text( GTK_ENTRY(string_entry), gtk_entry_set_text( GTK_ENTRY(string_entry),
p_module->p_config[i].psz_value ? p_module->p_config[i].psz_value ?
p_module->p_config[i].psz_value : "" ); p_module->p_config[i].psz_value : "" );
vlc_mutex_unlock( p_module->p_config[i].p_lock ); vlc_mutex_unlock( p_module->p_config[i].p_lock );
/* add text box for config description */
if( p_module->p_config[i].psz_longtext )
{
item_text = gtk_label_new( p_module->p_config[i].psz_longtext);
gtk_label_set_justify( GTK_LABEL(item_text), GTK_JUSTIFY_LEFT);
gtk_label_set_line_wrap( GTK_LABEL(item_text), TRUE );
gtk_widget_set_usize( item_text, 500, -2 );
gtk_widget_show( item_text );
gtk_table_resize( GTK_TABLE(item_table), 2, 1 );
gtk_table_attach( GTK_TABLE(item_table), item_text,
0, 1, 1, 2, GTK_FILL, GTK_FILL, 5, 5 );
}
/* connect signal to track changes in the text box */ /* connect signal to track changes in the text box */
gtk_object_set_data( GTK_OBJECT(string_entry), "config_option", gtk_object_set_data( GTK_OBJECT(string_entry), "config_option",
p_module->p_config[i].psz_name ); p_module->p_config[i].psz_name );
gtk_signal_connect( GTK_OBJECT(string_entry), "changed", gtk_signal_connect( GTK_OBJECT(string_entry), "changed",
GTK_SIGNAL_FUNC(GtkStringChanged), GTK_SIGNAL_FUNC(GtkStringChanged),
(gpointer)config_dialog ); (gpointer)config_dialog );
break;
case MODULE_CONFIG_ITEM_INTEGER: TOOLTIP( category_vbox, p_module->p_config[i].psz_longtext,
item_event_box )
/* add new frame for the config option */ LABEL_AND_WIDGET( p_module->p_config[i].psz_text, string_entry,
item_frame = gtk_frame_new( p_module->p_config[i].psz_text ); item_hbox, item_label, item_align );
gtk_widget_show( item_frame ); break;
gtk_box_pack_start( GTK_BOX(category_vbox), item_frame,
FALSE, FALSE, 5 );
/* add a new table for the config option */ case MODULE_CONFIG_ITEM_INTEGER:
item_table = gtk_table_new( 2, 1, FALSE );
gtk_widget_show( item_table );
gtk_container_add( GTK_CONTAINER(item_frame), item_table );
/* add input box with default value */ /* add input box with default value */
item_adj = gtk_adjustment_new( p_module->p_config[i].i_value, item_adj = gtk_adjustment_new( p_module->p_config[i].i_value,
-1, 1000, 1, 10, 10 ); -1, 1000, 1, 10, 10 );
integer_spinbutton = gtk_spin_button_new( GTK_ADJUSTMENT(item_adj), integer_spinbutton = gtk_spin_button_new( GTK_ADJUSTMENT(item_adj),
1, 0 ); 1, 0 );
gtk_widget_show( integer_spinbutton );
gtk_table_attach( GTK_TABLE(item_table), integer_spinbutton,
0, 1, 0, 1, GTK_FILL, GTK_FILL, 5, 5 );
/* add text box for config description */
if( p_module->p_config[i].psz_longtext )
{
item_text = gtk_label_new( p_module->p_config[i].psz_longtext);
gtk_label_set_justify( GTK_LABEL(item_text), GTK_JUSTIFY_LEFT);
gtk_label_set_line_wrap( GTK_LABEL(item_text), TRUE );
gtk_widget_set_usize( item_text, 500, -2 );
gtk_widget_show( item_text );
gtk_table_resize( GTK_TABLE(item_table), 2, 1 );
gtk_table_attach( GTK_TABLE(item_table), item_text,
0, 2, 1, 2, GTK_FILL, GTK_FILL, 5, 5 );
}
/* connect signal to track changes in the spinbutton value */ /* connect signal to track changes in the spinbutton value */
gtk_object_set_data( GTK_OBJECT(integer_spinbutton), gtk_object_set_data( GTK_OBJECT(integer_spinbutton),
"config_option", p_module->p_config[i].psz_name ); "config_option",
p_module->p_config[i].psz_name );
gtk_signal_connect( GTK_OBJECT(integer_spinbutton), "changed", gtk_signal_connect( GTK_OBJECT(integer_spinbutton), "changed",
GTK_SIGNAL_FUNC(GtkIntChanged), GTK_SIGNAL_FUNC(GtkIntChanged),
(gpointer)config_dialog ); (gpointer)config_dialog );
break;
case MODULE_CONFIG_ITEM_BOOL: TOOLTIP( category_vbox, p_module->p_config[i].psz_longtext,
item_event_box )
/* add new frame for the config option */ LABEL_AND_WIDGET( p_module->p_config[i].psz_text,
item_frame = gtk_frame_new( p_module->p_config[i].psz_text ); integer_spinbutton, item_hbox, item_label,
gtk_widget_show( item_frame ); item_align );
gtk_box_pack_start( GTK_BOX(category_vbox), item_frame, break;
FALSE, FALSE, 5 );
/* add a new table for the config option */ case MODULE_CONFIG_ITEM_BOOL:
item_table = gtk_table_new( 2, 1, FALSE );
gtk_widget_show( item_table );
gtk_container_add( GTK_CONTAINER(item_frame), item_table );
/* add check button */ /* add check button */
bool_checkbutton = gtk_check_button_new_with_label( bool_checkbutton = gtk_check_button_new();
_(p_module->p_config[i].psz_text) );
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(bool_checkbutton), gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(bool_checkbutton),
p_module->p_config[i].i_value ); p_module->p_config[i].i_value );
gtk_widget_show( bool_checkbutton );
gtk_table_attach( GTK_TABLE(item_table), bool_checkbutton,
0, 1, 0, 1, GTK_FILL, GTK_FILL, 5, 5 );
/* add text box for config description */
if( p_module->p_config[i].psz_longtext )
{
item_text = gtk_label_new( p_module->p_config[i].psz_longtext);
gtk_label_set_justify( GTK_LABEL(item_text), GTK_JUSTIFY_LEFT);
gtk_label_set_line_wrap( GTK_LABEL(item_text), TRUE );
gtk_widget_set_usize( item_text, 500, -2 );
gtk_widget_show( item_text );
gtk_table_resize( GTK_TABLE(item_table), 2, 1 );
gtk_table_attach( GTK_TABLE(item_table), item_text,
0, 2, 1, 2, GTK_FILL, GTK_FILL, 5, 5 );
}
/* connect signal to track changes in the button state */ /* connect signal to track changes in the button state */
gtk_object_set_data( GTK_OBJECT(bool_checkbutton), "config_option", gtk_object_set_data( GTK_OBJECT(bool_checkbutton), "config_option",
...@@ -454,6 +391,12 @@ static void GtkCreateConfigDialog( char *psz_module_name, ...@@ -454,6 +391,12 @@ static void GtkCreateConfigDialog( char *psz_module_name,
gtk_signal_connect( GTK_OBJECT(bool_checkbutton), "toggled", gtk_signal_connect( GTK_OBJECT(bool_checkbutton), "toggled",
GTK_SIGNAL_FUNC(GtkBoolChanged), GTK_SIGNAL_FUNC(GtkBoolChanged),
(gpointer)config_dialog ); (gpointer)config_dialog );
TOOLTIP( category_vbox, p_module->p_config[i].psz_longtext,
item_event_box )
LABEL_AND_WIDGET( p_module->p_config[i].psz_text, bool_checkbutton,
item_hbox, item_label, item_align );
break; break;
} }
} }
...@@ -461,37 +404,26 @@ static void GtkCreateConfigDialog( char *psz_module_name, ...@@ -461,37 +404,26 @@ static void GtkCreateConfigDialog( char *psz_module_name,
/* Now let's add the action buttons at the bottom of the page */ /* Now let's add the action buttons at the bottom of the page */
dialog_action_area = GTK_DIALOG(config_dialog)->action_area; dialog_action_area = GTK_DIALOG(config_dialog)->action_area;
gtk_widget_show( dialog_action_area ); gtk_container_set_border_width( GTK_CONTAINER(dialog_action_area), 4 );
//gtk_container_set_border_width( GTK_CONTAINER(dialog_action_area), 10 );
/* add a new table for the config option */ /* add a new table for the config option */
item_hbox = gtk_hbox_new( FALSE, 0 ); item_hbox = gtk_hbox_new( FALSE, 0 );
gtk_widget_show( item_hbox );
gtk_box_pack_end( GTK_BOX(dialog_action_area), item_hbox, gtk_box_pack_end( GTK_BOX(dialog_action_area), item_hbox,
TRUE, FALSE, 0 ); TRUE, FALSE, 0 );
item_hbox = gtk_hbox_new( FALSE, 0 ); item_hbox = gtk_hbox_new( FALSE, 0 );
gtk_widget_show( item_hbox );
gtk_box_pack_end( GTK_BOX(dialog_action_area), item_hbox, gtk_box_pack_end( GTK_BOX(dialog_action_area), item_hbox,
TRUE, FALSE, 0 ); TRUE, FALSE, 0 );
/* Create the OK button */ /* Create the OK button */
ok_button = gtk_button_new_with_label( _("Ok") ); ok_button = gtk_button_new_with_label( _("Ok") );
gtk_widget_show( ok_button );
gtk_box_pack_start( GTK_BOX(dialog_action_area), ok_button, gtk_box_pack_start( GTK_BOX(dialog_action_area), ok_button,
TRUE, TRUE, 0 ); TRUE, TRUE, 0 );
apply_button = gtk_button_new_with_label( _("Apply") ); apply_button = gtk_button_new_with_label( _("Apply") );
gtk_widget_show( apply_button );
gtk_box_pack_start( GTK_BOX(dialog_action_area), apply_button, gtk_box_pack_start( GTK_BOX(dialog_action_area), apply_button,
TRUE, TRUE, 0 ); TRUE, TRUE, 0 );
save_button = gtk_button_new_with_label( _("Save") );
gtk_widget_show( save_button );
gtk_box_pack_start( GTK_BOX(dialog_action_area), save_button,
TRUE, TRUE, 0 );
cancel_button = gtk_button_new_with_label( _("Cancel") ); cancel_button = gtk_button_new_with_label( _("Cancel") );
gtk_widget_show( cancel_button );
gtk_box_pack_start( GTK_BOX(dialog_action_area), cancel_button, gtk_box_pack_start( GTK_BOX(dialog_action_area), cancel_button,
TRUE, TRUE, 0 ); TRUE, TRUE, 0 );
...@@ -501,9 +433,6 @@ static void GtkCreateConfigDialog( char *psz_module_name, ...@@ -501,9 +433,6 @@ static void GtkCreateConfigDialog( char *psz_module_name,
gtk_signal_connect( GTK_OBJECT(apply_button), "clicked", gtk_signal_connect( GTK_OBJECT(apply_button), "clicked",
GTK_SIGNAL_FUNC(GtkConfigApply), GTK_SIGNAL_FUNC(GtkConfigApply),
config_dialog ); config_dialog );
gtk_signal_connect( GTK_OBJECT(save_button), "clicked",
GTK_SIGNAL_FUNC(GtkConfigSave),
config_dialog );
gtk_signal_connect( GTK_OBJECT(cancel_button), "clicked", gtk_signal_connect( GTK_OBJECT(cancel_button), "clicked",
GTK_SIGNAL_FUNC(GtkConfigCancel), GTK_SIGNAL_FUNC(GtkConfigCancel),
config_dialog ); config_dialog );
...@@ -519,9 +448,14 @@ static void GtkCreateConfigDialog( char *psz_module_name, ...@@ -519,9 +448,14 @@ static void GtkCreateConfigDialog( char *psz_module_name,
GTK_SIGNAL_FUNC(GtkConfigDialogDestroyed), GTK_SIGNAL_FUNC(GtkConfigDialogDestroyed),
(gpointer)p_intf ); (gpointer)p_intf );
gtk_widget_show( config_dialog ); gtk_widget_show_all( config_dialog );
} }
#undef FRAME
#undef SCROLLED_WINDOW
#undef LABEL
#undef TOOLTIP
/**************************************************************************** /****************************************************************************
* GtkConfigApply: store the changes to the config inside the modules * GtkConfigApply: store the changes to the config inside the modules
* configuration structure * configuration structure
...@@ -532,6 +466,7 @@ void GtkConfigApply( GtkButton * button, gpointer user_data ) ...@@ -532,6 +466,7 @@ void GtkConfigApply( GtkButton * button, gpointer user_data )
hash_table = (GHashTable *)gtk_object_get_data( GTK_OBJECT(user_data), hash_table = (GHashTable *)gtk_object_get_data( GTK_OBJECT(user_data),
"config_hash_table" ); "config_hash_table" );
g_hash_table_foreach( hash_table, GtkSaveHashValue, NULL ); g_hash_table_foreach( hash_table, GtkSaveHashValue, NULL );
} }
void GtkConfigOk( GtkButton * button, gpointer user_data ) void GtkConfigOk( GtkButton * button, gpointer user_data )
...@@ -540,17 +475,12 @@ void GtkConfigOk( GtkButton * button, gpointer user_data ) ...@@ -540,17 +475,12 @@ void GtkConfigOk( GtkButton * button, gpointer user_data )
gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) ); gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
} }
void GtkConfigCancel( GtkButton * button, gpointer user_data ) void GtkConfigCancel( GtkButton * button, gpointer user_data )
{ {
gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) ); gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
} }
void GtkConfigSave( GtkButton * button, gpointer user_data )
{
GtkConfigApply( button, user_data );
config_SaveConfigFile( NULL );
}
/**************************************************************************** /****************************************************************************
* GtkPluginHighlighted: display plugin description when an entry is selected * GtkPluginHighlighted: display plugin description when an entry is selected
* in the clist, and activate the configure button if necessary. * in the clist, and activate the configure button if necessary.
...@@ -562,9 +492,8 @@ void GtkPluginHighlighted( GtkCList *plugin_clist, int row, int column, ...@@ -562,9 +492,8 @@ void GtkPluginHighlighted( GtkCList *plugin_clist, int row, int column,
module_t *p_module; module_t *p_module;
char *psz_name; char *psz_name;
if( gtk_clist_get_text( GTK_CLIST(plugin_clist), row, column, &psz_name ) ) if( gtk_clist_get_text( GTK_CLIST(plugin_clist), row, 0, &psz_name ) )
{ {
/* look for plugin 'psz_name' */ /* look for plugin 'psz_name' */
for( p_module = p_module_bank->first ; for( p_module = p_module_bank->first ;
p_module != NULL ; p_module != NULL ;
...@@ -572,12 +501,8 @@ void GtkPluginHighlighted( GtkCList *plugin_clist, int row, int column, ...@@ -572,12 +501,8 @@ void GtkPluginHighlighted( GtkCList *plugin_clist, int row, int column,
{ {
if( !strcmp( p_module->psz_name, psz_name ) ) if( !strcmp( p_module->psz_name, psz_name ) )
{ {
gtk_label_set_text( GTK_LABEL(user_data),
p_module->psz_longname ?
p_module->psz_longname : "" );
gtk_object_set_data( GTK_OBJECT(plugin_clist), gtk_object_set_data( GTK_OBJECT(plugin_clist),
"plugin_highlighted", p_module ); "plugin_highlighted", p_module );
config_button = gtk_object_get_data( GTK_OBJECT(plugin_clist), config_button = gtk_object_get_data( GTK_OBJECT(plugin_clist),
"config_button" ); "config_button" );
if( p_module->i_config_items ) if( p_module->i_config_items )
...@@ -604,7 +529,6 @@ void GtkPluginConfigure( GtkButton *button, gpointer user_data ) ...@@ -604,7 +529,6 @@ void GtkPluginConfigure( GtkButton *button, gpointer user_data )
"plugin_highlighted" ); "plugin_highlighted" );
if( !p_module ) return; if( !p_module ) return;
p_intf = (intf_thread_t *)gtk_object_get_data( GTK_OBJECT(button), p_intf = (intf_thread_t *)gtk_object_get_data( GTK_OBJECT(button),
"p_intf" ); "p_intf" );
GtkCreateConfigDialog( p_module->psz_name, (gpointer)p_intf ); GtkCreateConfigDialog( p_module->psz_name, (gpointer)p_intf );
...@@ -637,6 +561,7 @@ static void GtkStringChanged( GtkEditable *editable, gpointer user_data ) ...@@ -637,6 +561,7 @@ static void GtkStringChanged( GtkEditable *editable, gpointer user_data )
module_config_t *p_config; module_config_t *p_config;
GHashTable *hash_table; GHashTable *hash_table;
hash_table = (GHashTable *)gtk_object_get_data( GTK_OBJECT(user_data), hash_table = (GHashTable *)gtk_object_get_data( GTK_OBJECT(user_data),
"config_hash_table" ); "config_hash_table" );
/* free old p_config */ /* free old p_config */
...@@ -662,6 +587,7 @@ static void GtkIntChanged( GtkEditable *editable, gpointer user_data ) ...@@ -662,6 +587,7 @@ static void GtkIntChanged( GtkEditable *editable, gpointer user_data )
module_config_t *p_config; module_config_t *p_config;
GHashTable *hash_table; GHashTable *hash_table;
hash_table = (GHashTable *)gtk_object_get_data( GTK_OBJECT(user_data), hash_table = (GHashTable *)gtk_object_get_data( GTK_OBJECT(user_data),
"config_hash_table" ); "config_hash_table" );
...@@ -689,6 +615,7 @@ static void GtkBoolChanged( GtkToggleButton *button, gpointer user_data ) ...@@ -689,6 +615,7 @@ static void GtkBoolChanged( GtkToggleButton *button, gpointer user_data )
module_config_t *p_config; module_config_t *p_config;
GHashTable *hash_table; GHashTable *hash_table;
hash_table = (GHashTable *)gtk_object_get_data( GTK_OBJECT(user_data), hash_table = (GHashTable *)gtk_object_get_data( GTK_OBJECT(user_data),
"config_hash_table" ); "config_hash_table" );
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* and spawn threads. * and spawn threads.
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2001 VideoLAN * Copyright (C) 1998-2001 VideoLAN
* $Id: main.c,v 1.169 2002/03/25 19:16:20 gbazin Exp $ * $Id: main.c,v 1.170 2002/03/25 20:37:00 lool Exp $
* *
* Authors: Vincent Seguin <seguin@via.ecp.fr> * Authors: Vincent Seguin <seguin@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org> * Samuel Hocevar <sam@zoy.org>
...@@ -112,7 +112,7 @@ ...@@ -112,7 +112,7 @@
#define INTF_PATH_TEXT "interface default search path" #define INTF_PATH_TEXT "interface default search path"
#define INTF_PATH_LONGTEXT "This option allows you to set the default path" \ #define INTF_PATH_LONGTEXT "This option allows you to set the default path" \
"that the interface will open when looking for a" \ " that the interface will open when looking for a" \
" file" " file"
#define AOUT_TEXT "audio output method" #define AOUT_TEXT "audio output method"
...@@ -152,28 +152,31 @@ ...@@ -152,28 +152,31 @@
#define DESYNC_TEXT "Compensate desynchronization of audio (in ms)" #define DESYNC_TEXT "Compensate desynchronization of audio (in ms)"
#define DESYNC_LONGTEXT "This option allows you to delay the audio output." \ #define DESYNC_LONGTEXT "This option allows you to delay the audio output." \
"This can be handy if you notice a lag between the" \ " This can be handy if you notice a lag between the" \
" video and the audio" " video and the audio"
#define VOUT_TEXT "video output method" #define VOUT_TEXT "video output method"
#define VOUT_LONGTEXT "This option allows you to select the video output" \ #define VOUT_LONGTEXT "This option allows you to select the video output" \
"method used by vlc.\nNote that the default behaviour" \ " method used by vlc.\nNote that the default behaviour" \
"is to automatically select the best method available" " is to automatically select the best method available"
#define NOVIDEO_TEXT "disable video" #define NOVIDEO_TEXT "disable video"
#define NOVIDEO_LONGTEXT "This will completely disable the video output. The" \ #define NOVIDEO_LONGTEXT "This will completely disable the video output. The" \
"video decoding stage shouldn't even be done, so it" \ " video decoding stage shouldn't even be done, so" \
"can allow you to save some processing power" " it can allow you to save some processing power"
#define DISPLAY_TEXT "display identifier"
#define DISPLAY_LONGTEXT NULL
#define WIDTH_TEXT "video width" #define WIDTH_TEXT "video width"
#define WIDTH_LONGTEXT "You can enforce the video width here.\nNote" \ #define WIDTH_LONGTEXT "You can enforce the video width here.\nNote" \
"that by default vlc will adapt to the video " \ " that by default vlc will adapt to the video" \
"characteristics" " characteristics"
#define HEIGHT_TEXT "video height" #define HEIGHT_TEXT "video height"
#define HEIGHT_LONGTEXT "You can enforce the video height here.\nNote" \ #define HEIGHT_LONGTEXT "You can enforce the video height here.\nNote" \
"that by default vlc will adapt to the video " \ " that by default vlc will adapt to the video " \
"characteristics" " characteristics"
#define GRAYSCALE_TEXT "grayscale video output" #define GRAYSCALE_TEXT "grayscale video output"
#define GRAYSCALE_LONGTEXT "Using this option, vlc will not decode the color "\ #define GRAYSCALE_LONGTEXT "Using this option, vlc will not decode the color "\
...@@ -272,7 +275,7 @@ ...@@ -272,7 +275,7 @@
#define PLAYLIST_LAUNCH_TEXT "launch playlist on startup" #define PLAYLIST_LAUNCH_TEXT "launch playlist on startup"
#define PLAYLIST_LAUNCH_LONGTEXT NULL #define PLAYLIST_LAUNCH_LONGTEXT NULL
#define PLAYLIST_ENQUEUE_TEXT "enqeue playlist as default" #define PLAYLIST_ENQUEUE_TEXT "enqueue playlist as default"
#define PLAYLIST_ENQUEUE_LONGTEXT NULL #define PLAYLIST_ENQUEUE_LONGTEXT NULL
#define PLAYLIST_LOOP_TEXT "loop playlist on end" #define PLAYLIST_LOOP_TEXT "loop playlist on end"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment