]> git.sesse.net Git - vlc/blobdiff - modules/gui/gtk/preferences.c
* Fix the play/pause button status
[vlc] / modules / gui / gtk / preferences.c
index 11e58a892bb71726882c9377f82da3ea1cdb4ad8..a01bf9bea3e2f2e24aff8f36d47be69c2d4d4931 100644 (file)
@@ -1,8 +1,8 @@
 /*****************************************************************************
  * gtk_preferences.c: functions to handle the preferences dialog box.
  *****************************************************************************
- * Copyright (C) 2000, 2001 VideoLAN
- * $Id: preferences.c,v 1.1 2002/08/04 17:23:43 sam Exp $
+ * Copyright (C) 2001-2004 VideoLAN
+ * $Id: preferences.c,v 1.11 2004/01/25 18:34:55 gbazin Exp $
  *
  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  *          Loïc Minier <lool@via.ecp.fr>
@@ -62,7 +62,9 @@ static void GtkConfigDialogDestroyed ( GtkObject *, gpointer );
 
 static void GtkStringChanged     ( GtkEditable *, gpointer );
 static void GtkIntChanged        ( GtkEditable *, gpointer );
+static void GtkIntRangedChanged  ( GtkEditable *, gpointer );
 static void GtkFloatChanged      ( GtkEditable *, gpointer );
+static void GtkFloatRangedChanged      ( GtkEditable *, gpointer );
 static void GtkBoolChanged       ( GtkToggleButton *, gpointer );
 
 static void GtkFreeHashTable     ( GtkObject *object );
@@ -118,8 +120,11 @@ void GtkPreferencesShow( GtkMenuItem * menuitem, gpointer user_data )
 static void GtkCreateConfigDialog( char *psz_module_name,
                                    intf_thread_t *p_intf )
 {
-    module_t *p_module, *p_module_bis;
+    module_t *p_parser = NULL;
+    vlc_list_t *p_list;
     module_config_t *p_item;
+    vlc_bool_t b_advanced = config_GetInt( p_intf, "advanced" );
+    int i_index;
 
     guint rows = 0;
 
@@ -151,7 +156,9 @@ static void GtkCreateConfigDialog( char *psz_module_name,
     GtkWidget *item_combo;
     GtkWidget *string_entry;
     GtkWidget *integer_spinbutton;
+    GtkWidget *integer_slider;
     GtkWidget *float_spinbutton;
+    GtkWidget *float_slider;
     GtkObject *item_adj;
     GtkWidget *bool_checkbutton;
     GtkWidget *module_clist;
@@ -173,27 +180,35 @@ static void GtkCreateConfigDialog( char *psz_module_name,
 
 
     /* Look for the selected module */
-    for( p_module = p_intf->p_vlc->p_module_bank->first ; p_module != NULL ;
-         p_module = p_module->next )
+    p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
+
+    for( i_index = 0; i_index < p_list->i_count; i_index++ )
     {
+        p_parser = (module_t *)p_list->p_values[i_index].p_object ;
 
         if( psz_module_name
-             && !strcmp( psz_module_name, p_module->psz_object_name ) )
+             && !strcmp( psz_module_name, p_parser->psz_object_name ) )
         {
             break;
         }
     }
-    if( !p_module ) return;
+
+    if( !p_parser || i_index == p_list->i_count )
+    {
+        vlc_list_release( p_list );
+        return;
+    }
 
     /* We found it, now we can start building its configuration interface */
     /* Create the configuration dialog box */
 
 #ifdef MODULE_NAME_IS_gnome
-    config_dialog = gnome_dialog_new( p_module->psz_longname, NULL );
+    config_dialog = gnome_dialog_new( p_parser->psz_longname, NULL );
     config_dialog_vbox = GNOME_DIALOG(config_dialog)->vbox;
 #else
     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_parser->psz_longname );
     config_dialog_vbox = GTK_DIALOG(config_dialog)->vbox;
 #endif
 
@@ -215,15 +230,16 @@ static void GtkCreateConfigDialog( char *psz_module_name,
     gtk_container_add( GTK_CONTAINER(config_dialog_vbox), config_notebook );
 
     /* Enumerate config options and add corresponding config boxes */
-    p_item = p_module->p_config;
-    do
-    {
-        switch( p_item->i_type )
-        {
+    p_item = p_parser->p_config;
 
-        case CONFIG_HINT_CATEGORY:
-        case CONFIG_HINT_END:
+    if( p_item ) do
+    {
+        if( p_item->b_advanced && !b_advanced ) continue;
 
+        if( p_item->i_type == CONFIG_HINT_CATEGORY ||
+            p_item->i_type == CONFIG_HINT_END ||
+            !category_table )
+        {
             /*
              * Before we start building the interface for the new category, we
              * must close/finish the previous one we were generating.
@@ -277,7 +293,7 @@ static void GtkCreateConfigDialog( char *psz_module_name,
              * Now we can start taking care of the new category
              */
 
-            if( p_item->i_type == CONFIG_HINT_CATEGORY )
+            if( p_item->i_type != CONFIG_HINT_END )
             {
                 /* create a new table for right-left alignment of children */
                 category_table = gtk_table_new( 0, 0, FALSE );
@@ -285,10 +301,15 @@ static void GtkCreateConfigDialog( char *psz_module_name,
                 rows = 0;
 
                 /* create a new category label */
-                category_label = gtk_label_new( p_item->psz_text );
+                if( p_item->i_type == CONFIG_HINT_CATEGORY )
+                    category_label = gtk_label_new( p_item->psz_text );
+                else
+                    category_label = gtk_label_new( p_parser->psz_longname );
             }
+        }
 
-            break;
+        switch( p_item->i_type )
+        {
 
         case CONFIG_ITEM_MODULE:
 
@@ -303,7 +324,9 @@ static void GtkCreateConfigDialog( char *psz_module_name,
 
             /* create a new clist widget */
             {
-                gchar * titles[] = { _("Name"), _("Description") };
+                gchar * titles[] = { N_("Name"), N_("Description") };
+                titles[0] = _(titles[0]);
+                titles[1] = _(titles[1]);
 
                 module_clist = gtk_clist_new_with_titles( 2, titles );
             }
@@ -316,26 +339,18 @@ static void GtkCreateConfigDialog( char *psz_module_name,
             /* build a list of available modules */
             {
                 gchar * entry[2];
-                char *  psz_capability;
 
-                for( p_module_bis = p_intf->p_vlc->p_module_bank->first ;
-                     p_module_bis != NULL ;
-                     p_module_bis = p_module_bis->next )
+                for( i_index = 0; i_index < p_list->i_count; i_index++ )
                 {
-#if 0 /* FIXME */
-                    for( psz_capability = p_module_bis->pp_capabilities[0] ;
-                         *psz_capability ;
-                         psz_capability++ )
+                    p_parser = (module_t *)p_list->p_values[i_index].p_object ;
+
+                    if( !strcmp( p_parser->psz_capability,
+                                 p_item->psz_type ) )
                     {
-                        if( !strcmp( psz_capability, p_item->psz_type ) )
-                        {
-                            entry[0] = p_module_bis->psz_object_name;
-                            entry[1] = p_module_bis->psz_longname;
-                            gtk_clist_append( GTK_CLIST(module_clist), entry );
-                            break;
-                        }
+                        entry[0] = p_parser->psz_object_name;
+                        entry[1] = p_parser->psz_longname;
+                        gtk_clist_append( GTK_CLIST(module_clist), entry );
                     }
-#endif
                 }
             }
 
@@ -412,6 +427,7 @@ static void GtkCreateConfigDialog( char *psz_module_name,
 
         case CONFIG_ITEM_STRING:
         case CONFIG_ITEM_FILE:
+        case CONFIG_ITEM_DIRECTORY:
 
             if( !p_item->ppsz_list )
             {
@@ -452,42 +468,82 @@ static void GtkCreateConfigDialog( char *psz_module_name,
 
         case CONFIG_ITEM_INTEGER:
 
-            /* add input box with default value */
-            item_adj = gtk_adjustment_new( p_item->i_value,
-                                           -1, 99999, 1, 10, 10 );
-            integer_spinbutton = gtk_spin_button_new( GTK_ADJUSTMENT(item_adj),
-                                                      1, 0 );
-
-            /* connect signal to track changes in the spinbutton value */
-            gtk_object_set_data( GTK_OBJECT(integer_spinbutton),
-                                 "config_option", p_item->psz_name );
-            gtk_signal_connect( GTK_OBJECT(integer_spinbutton), "changed",
-                                GTK_SIGNAL_FUNC(GtkIntChanged),
-                                (gpointer)config_dialog );
-
-            LABEL_AND_WIDGET( p_item->psz_text,
-                              integer_spinbutton, p_item->psz_longtext );
+            if (( p_item->i_max == 0) && ( p_item->i_min == 0))
+            {
+                /* add input box with default value */
+                item_adj = gtk_adjustment_new( p_item->i_value,
+                                               -1, 99999, 1, 10, 10 );
+                integer_spinbutton = gtk_spin_button_new( GTK_ADJUSTMENT(item_adj), 1, 0 );
+
+                /* connect signal to track changes in the spinbutton value */
+                gtk_object_set_data( GTK_OBJECT(integer_spinbutton),
+                                     "config_option", p_item->psz_name );
+                gtk_signal_connect( GTK_OBJECT(integer_spinbutton), "changed",
+                                    GTK_SIGNAL_FUNC(GtkIntChanged),
+                                    (gpointer)config_dialog );
+
+                LABEL_AND_WIDGET( p_item->psz_text,
+                                  integer_spinbutton, p_item->psz_longtext );
+            }
+            else /* use i_min and i_max */
+            {
+                item_adj = gtk_adjustment_new( p_item->i_value, p_item->i_min,
+                                               p_item->i_max, 1, 1, 0 );
+                integer_slider = gtk_hscale_new( GTK_ADJUSTMENT(item_adj));
+                gtk_scale_set_digits (GTK_SCALE(integer_slider), 0);
+                                                
+                /* connect signal to track changes in the spinbutton value */
+                gtk_object_set_data( GTK_OBJECT(item_adj),
+                                     "config_option", p_item->psz_name );
+                gtk_signal_connect( GTK_OBJECT(item_adj), "value-changed",
+                                    GTK_SIGNAL_FUNC(GtkIntRangedChanged),
+                                    (gpointer)config_dialog );
+
+                LABEL_AND_WIDGET( p_item->psz_text,
+                                  integer_slider, p_item->psz_longtext );
+            }
             break;
 
         case CONFIG_ITEM_FLOAT:
 
-            /* add input box with default value */
-            item_adj = gtk_adjustment_new( p_item->f_value,
-                                           0, 99999, 0.01, 10, 10 );
-            float_spinbutton = gtk_spin_button_new( GTK_ADJUSTMENT(item_adj),
-                                                    0.01, 2 );
-
-            /* connect signal to track changes in the spinbutton value */
-            gtk_object_set_data( GTK_OBJECT(float_spinbutton),
-                                 "config_option", p_item->psz_name );
-            gtk_signal_connect( GTK_OBJECT(float_spinbutton), "changed",
-                                GTK_SIGNAL_FUNC(GtkFloatChanged),
-                                (gpointer)config_dialog );
-
-            LABEL_AND_WIDGET( p_item->psz_text,
-                              float_spinbutton, p_item->psz_longtext );
+            if (( p_item->f_max == 0.0) && ( p_item->f_min == 0.0))
+            {
+                /* add input box with default value */
+                item_adj = gtk_adjustment_new( p_item->f_value,
+                                               0, 99999, 0.01, 10, 10 );
+                float_spinbutton = gtk_spin_button_new( GTK_ADJUSTMENT(item_adj),
+                                                        0.01, 2 );
+
+                /* connect signal to track changes in the spinbutton value */
+                gtk_object_set_data( GTK_OBJECT(float_spinbutton),
+                                     "config_option", p_item->psz_name );
+                gtk_signal_connect( GTK_OBJECT(float_spinbutton), "changed",
+                                    GTK_SIGNAL_FUNC(GtkFloatChanged),
+                                    (gpointer)config_dialog );
+
+                LABEL_AND_WIDGET( p_item->psz_text,
+                                  float_spinbutton, p_item->psz_longtext );
+            }
+            else /* use f_min and f_max */
+            {
+                item_adj = gtk_adjustment_new( p_item->f_value, p_item->f_min,
+                                               p_item->f_max, 0.01, 0.01, 0 );
+                float_slider = gtk_hscale_new( GTK_ADJUSTMENT(item_adj));
+                gtk_scale_set_digits (GTK_SCALE(float_slider), 2);
+                                                
+                /* connect signal to track changes in the spinbutton value */
+                gtk_object_set_data( GTK_OBJECT(item_adj),
+                                     "config_option", p_item->psz_name );
+                gtk_signal_connect( GTK_OBJECT(item_adj), "value-changed",
+                                    GTK_SIGNAL_FUNC(GtkFloatRangedChanged),
+                                    (gpointer)config_dialog );
+
+                LABEL_AND_WIDGET( p_item->psz_text,
+                                  float_slider, p_item->psz_longtext );
+            }
             break;
 
+
         case CONFIG_ITEM_BOOL:
 
             /* add check button */
@@ -511,6 +567,8 @@ static void GtkCreateConfigDialog( char *psz_module_name,
     }
     while( p_item->i_type != CONFIG_HINT_END && p_item++ );
 
+    vlc_list_release( p_list );
+
 #ifndef MODULE_NAME_IS_gnome
     /* Now let's add the action buttons at the bottom of the page */
     dialog_action_area = GTK_DIALOG(config_dialog)->action_area;
@@ -603,7 +661,7 @@ static void GtkCreateConfigDialog( char *psz_module_name,
  * GtkConfigApply: store the changes to the config inside the modules
  * configuration structure and clear the hash table.
  ****************************************************************************/
-void GtkConfigApply( GtkButton * button, gpointer user_data )
+static void GtkConfigApply( GtkButton * button, gpointer user_data )
 {
     intf_thread_t *p_intf;
     GHashTable *hash_table;
@@ -621,19 +679,19 @@ void GtkConfigApply( GtkButton * button, gpointer user_data )
     gtk_widget_set_sensitive( apply_button, FALSE );
 }
 
-void GtkConfigOk( GtkButton * button, gpointer user_data )
+static void GtkConfigOk( GtkButton * button, gpointer user_data )
 {
     GtkConfigApply( button, user_data );
     gtk_widget_destroy( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
 }
 
 
-void GtkConfigCancel( GtkButton * button, gpointer user_data )
+static void GtkConfigCancel( GtkButton * button, gpointer user_data )
 {
     gtk_widget_destroy( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
 }
 
-void GtkConfigSave( GtkButton * button, gpointer user_data )
+static void GtkConfigSave( GtkButton * button, gpointer user_data )
 {
     intf_thread_t *p_intf;
 
@@ -647,46 +705,53 @@ void GtkConfigSave( GtkButton * button, gpointer user_data )
  * GtkModuleHighlighted: display module description when an entry is selected
  *   in the clist, and activate the configure button if necessary.
  ****************************************************************************/
-void GtkModuleHighlighted( GtkCList *module_clist, int row, int column,
-                           GdkEventButton *event, gpointer user_data )
+static void GtkModuleHighlighted( GtkCList *module_clist, int row, int column,
+                                  GdkEventButton *event, gpointer user_data )
 {
     intf_thread_t *p_intf;
     GtkWidget *config_button;
-    module_t *p_module;
+    module_t *p_parser;
+    vlc_list_t *p_list;
     char *psz_name;
+    int i_index;
 
     p_intf = (intf_thread_t *)gtk_object_get_data( GTK_OBJECT(module_clist),
                                                    "p_intf" );
 
-    if( gtk_clist_get_text( GTK_CLIST(module_clist), row, 0, &psz_name ) )
+    if( !gtk_clist_get_text( GTK_CLIST(module_clist), row, 0, &psz_name ) )
+    {
+        return;
+    }
+
+    /* look for module 'psz_name' */
+    p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
+
+    for( i_index = 0; i_index < p_list->i_count; i_index++ )
     {
-        /* look for module 'psz_name' */
-        for( p_module = p_intf->p_vlc->p_module_bank->first ;
-             p_module != NULL ;
-             p_module = p_module->next )
+        p_parser = (module_t *)p_list->p_values[i_index].p_object ;
+
+        if( !strcmp( p_parser->psz_object_name, psz_name ) )
         {
-          if( !strcmp( p_module->psz_object_name, psz_name ) )
-          {
-              gtk_object_set_data( GTK_OBJECT(module_clist),
-                                   "module_highlighted", p_module );
-              config_button = gtk_object_get_data( GTK_OBJECT(module_clist),
-                                                   "config_button" );
-              if( p_module->i_config_items )
-                  gtk_widget_set_sensitive( config_button, TRUE );
-              else
-                  gtk_widget_set_sensitive( config_button, FALSE );
-
-              break;
-          }
-        }
+            gtk_object_set_data( GTK_OBJECT(module_clist),
+                                 "module_highlighted", p_parser );
+            config_button = gtk_object_get_data( GTK_OBJECT(module_clist),
+                                                 "config_button" );
+            if( p_parser->i_config_items )
+                gtk_widget_set_sensitive( config_button, TRUE );
+            else
+                gtk_widget_set_sensitive( config_button, FALSE );
 
+            break;
+        }
     }
+
+    vlc_list_release( p_list );
 }
 
 /****************************************************************************
  * GtkModuleConfigure: display module configuration dialog box.
  ****************************************************************************/
-void GtkModuleConfigure( GtkButton *button, gpointer user_data )
+static void GtkModuleConfigure( GtkButton *button, gpointer user_data )
 {
     module_t *p_module;
     intf_thread_t *p_intf;
@@ -704,7 +769,7 @@ void GtkModuleConfigure( GtkButton *button, gpointer user_data )
 /****************************************************************************
  * GtkModuleSelected: select module.
  ****************************************************************************/
-void GtkModuleSelected( GtkButton *button, gpointer user_data )
+static void GtkModuleSelected( GtkButton *button, gpointer user_data )
 {
     module_t *p_module;
     GtkWidget *widget;
@@ -752,7 +817,6 @@ static void GtkStringChanged( GtkEditable *editable, gpointer user_data )
                                                     "apply_button" );
     gtk_widget_set_sensitive( apply_button, TRUE );
 }
-
 /****************************************************************************
  * GtkIntChanged: signal called when the user changes an integer value.
  ****************************************************************************/
@@ -791,6 +855,43 @@ static void GtkIntChanged( GtkEditable *editable, gpointer user_data )
     gtk_widget_set_sensitive( apply_button, TRUE );
 }
 
+
+/***************************************************************************************
+ * GtkIntRangedChanged: signal called when the user changes an integer with range value.
+ **************************************************************************************/
+static void GtkIntRangedChanged( GtkEditable *editable, gpointer user_data )
+{
+    intf_thread_t *p_intf;
+    module_config_t *p_config;
+    GHashTable *hash_table;
+    GtkWidget *apply_button;
+
+    p_intf = (intf_thread_t *)gtk_object_get_data( GTK_OBJECT(editable),
+                                                   "p_intf" );
+
+    hash_table = (GHashTable *)gtk_object_get_data( GTK_OBJECT(user_data),
+                                                    "config_hash_table" );
+
+    /* free old p_config */
+    p_config = (module_config_t *)g_hash_table_lookup( hash_table,
+                                                       (gpointer)editable );
+    if( p_config ) GtkFreeHashValue( NULL, (gpointer)p_config, (void *)p_intf );
+
+    p_config = malloc( sizeof(module_config_t) );
+    p_config->i_type = CONFIG_ITEM_INTEGER;
+    p_config->i_value = ((GTK_ADJUSTMENT(editable))->value);
+    p_config->psz_name = (char *)gtk_object_get_data( GTK_OBJECT(editable),
+                                                      "config_option" );
+
+    g_hash_table_insert( hash_table, (gpointer)editable,
+                         (gpointer)p_config );
+
+    /* change the highlight status of the Apply button */
+    apply_button = (GtkWidget *)gtk_object_get_data( GTK_OBJECT(user_data),
+                                                    "apply_button" );
+    gtk_widget_set_sensitive( apply_button, TRUE );
+}
+
 /****************************************************************************
  * GtkFloatChanged: signal called when the user changes a float value.
  ****************************************************************************/
@@ -829,6 +930,42 @@ static void GtkFloatChanged( GtkEditable *editable, gpointer user_data )
     gtk_widget_set_sensitive( apply_button, TRUE );
 }
 
+/***************************************************************************************
+ * GtkIntRangedChanged: signal called when the user changes an integer with range value.
+ **************************************************************************************/
+static void GtkFloatRangedChanged( GtkEditable *editable, gpointer user_data )
+{
+    intf_thread_t *p_intf;
+    module_config_t *p_config;
+    GHashTable *hash_table;
+    GtkWidget *apply_button;
+
+    p_intf = (intf_thread_t *)gtk_object_get_data( GTK_OBJECT(editable),
+                                                   "p_intf" );
+
+    hash_table = (GHashTable *)gtk_object_get_data( GTK_OBJECT(user_data),
+                                                    "config_hash_table" );
+
+    /* free old p_config */
+    p_config = (module_config_t *)g_hash_table_lookup( hash_table,
+                                                       (gpointer)editable );
+    if( p_config ) GtkFreeHashValue( NULL, (gpointer)p_config, (void *)p_intf );
+
+    p_config = malloc( sizeof(module_config_t) );
+    p_config->i_type = CONFIG_ITEM_FLOAT;
+    p_config->f_value = ((GTK_ADJUSTMENT(editable))->value);
+    p_config->psz_name = (char *)gtk_object_get_data( GTK_OBJECT(editable),
+                                                      "config_option" );
+
+    g_hash_table_insert( hash_table, (gpointer)editable,
+                         (gpointer)p_config );
+
+    /* change the highlight status of the Apply button */
+    apply_button = (GtkWidget *)gtk_object_get_data( GTK_OBJECT(user_data),
+                                                    "apply_button" );
+    gtk_widget_set_sensitive( apply_button, TRUE );
+}
+
 /****************************************************************************
  * GtkBoolChanged: signal called when the user changes a bool value.
  ****************************************************************************/
@@ -906,6 +1043,7 @@ static gboolean GtkSaveHashValue( gpointer key, gpointer value,
 
     case CONFIG_ITEM_STRING:
     case CONFIG_ITEM_FILE:
+    case CONFIG_ITEM_DIRECTORY:
     case CONFIG_ITEM_MODULE:
         config_PutPsz( p_intf, p_config->psz_name,
                        *p_config->psz_value ? p_config->psz_value : NULL );