WinCE: update the interface module
[vlc.git] / modules / gui / wince / preferences.cpp
index 3905575..44018ea 100644 (file)
 
 #include "preferences_widgets.h"
 
-#define GENERAL_ID 1242
-#define PLUGIN_ID 1243
-#define CAPABILITY_ID 1244
+#define TYPE_CATEGORY 0
+#define TYPE_CATSUBCAT 1  /* Category with embedded subcategory */
+#define TYPE_SUBCATEGORY 2
+#define TYPE_MODULE 3
 
 /*****************************************************************************
  * Event Table.
@@ -98,7 +99,7 @@ public:
 
     PrefsPanel() { }
     PrefsPanel( HWND parent, HINSTANCE hInst, intf_thread_t *_p_intf,
-                PrefsDialog *, int i_object_id, char *, char * );
+                PrefsDialog *, module_t *p_module, char *, char *, ConfigTreeData * );
     virtual ~PrefsPanel() {}
 
     void Hide();
@@ -126,17 +127,20 @@ class ConfigTreeData
 {
 public:
 
-    ConfigTreeData() { b_submodule = 0; panel = NULL; psz_section = NULL;
+    ConfigTreeData() { b_submodule = 0; panel = NULL; psz_name = NULL;
                        psz_help = NULL; }
     virtual ~ConfigTreeData() { delete panel;
-                                free( psz_section );
+                                free( psz_name );
                                 free( psz_help ); }
 
     bool b_submodule;
 
     PrefsPanel *panel;
+    module_t *p_module;
     int i_object_id;
-    char *psz_section;
+    int i_subcat_id;
+    int i_type;
+    char *psz_name;
     char *psz_help;
 };
 
@@ -318,7 +322,7 @@ PrefsTreeCtrl::PrefsTreeCtrl( intf_thread_t *_p_intf,
                               HINSTANCE hInst )
 {
     vlc_list_t      *p_list;
-    module_t        *p_module;
+    module_t        *p_module = NULL;
     module_config_t *p_item;
     int i_index;
 
@@ -331,7 +335,7 @@ PrefsTreeCtrl::PrefsTreeCtrl( intf_thread_t *_p_intf,
     size_t i_capability_count = 0;
     size_t i_child_index;
 
-    HTREEITEM capability_item;
+    HTREEITEM category_item, subcategory_item;
 
     /* Initializations */
     p_intf = _p_intf;
@@ -366,9 +370,9 @@ PrefsTreeCtrl::PrefsTreeCtrl( intf_thread_t *_p_intf,
      * Build a tree of the main options
      */
     ConfigTreeData *config_data = new ConfigTreeData;
-    config_data->i_object_id = GENERAL_ID;
-    config_data->psz_help = strdup("nothing");//strdup( GENERAL_HELP );
-    config_data->psz_section = strdup( GENERAL_TITLE );
+    config_data->i_object_id = TYPE_CATEGORY;
+    config_data->psz_help = strdup(MAIN_HELP);
+    config_data->psz_name = strdup( GENERAL_TITLE );
     tvi.pszText = _T("General settings");
     tvi.cchTextMax = lstrlen(_T("General settings"));
     tvi.lParam = (long)config_data;
@@ -380,173 +384,240 @@ PrefsTreeCtrl::PrefsTreeCtrl( intf_thread_t *_p_intf,
     hPrev = (HTREEITEM) TreeView_InsertItem( hwndTV, &tvins);
     general_item = hPrev;
 
+    /* Build the categories list */
     for( i_index = 0; i_index < p_list->i_count; i_index++ )
     {
         p_module = (module_t *)p_list->p_values[i_index].p_object;
-        if( !strcmp( p_module->psz_object_name, "main" ) )
+        if( strcmp( module_GetObjName( p_module ), "main" ) == 0 )
             break;
     }
+    /* TODO replace by
+     * p_module = module_GetMainModule( p_intf );
+     */
     if( i_index < p_list->i_count )
     {
+        unsigned int confsize;
+        const char *psz_help;
+        module_config_t * p_config;
+
         /* We found the main module */
 
         /* Enumerate config categories and store a reference so we can
          * generate their config panel them when it is asked by the user. */
-        p_item = p_module->p_config;
+        p_config = module_GetConfig (p_module, &confsize);
 
-        if( p_item ) do
+        for( size_t i = 0; i < confsize; i++ )
         {
-            switch( p_item->i_type )
-            {
-            case CONFIG_HINT_CATEGORY:
-                ConfigTreeData *config_data = new ConfigTreeData;
-                config_data->psz_section = strdup( p_item->psz_text );
-                if( p_item->psz_longtext )
-                {
-                    config_data->psz_help =
-                        strdup( p_item->psz_longtext );
-                }
-                else
-                {
-                    config_data->psz_help = NULL;
-                }
-                config_data->i_object_id = p_module->i_object_id;
-
-                /* Add the category to the tree */
-                // Set the text of the item.
-                tvi.pszText = _FROMMB(p_item->psz_text);
-                tvi.cchTextMax = _tcslen(tvi.pszText);
-                tvi.lParam = (long)config_data;
-                tvins.item = tvi;
-                tvins.hInsertAfter = hPrev;
-                tvins.hParent = general_item; //level 3
-                // Add the item to the tree-view control.
-                hPrev = (HTREEITEM)TreeView_InsertItem( hwndTV, &tvins );
+        /* Work on a new item */
+            module_config_t *p_item = p_config + i;
 
-                break;
-            }
-        }
-        while( p_item->i_type != CONFIG_HINT_END && p_item++ );
+                switch( p_item->i_type )
+                {
+                    case CONFIG_CATEGORY:
+                        if( p_item->value.i == -1 )   break; // Don't display it
+                        config_data = new ConfigTreeData;
+                        config_data->psz_name = strdup( config_CategoryNameGet(p_item->value.i ) );
+                        psz_help = config_CategoryHelpGet( p_item->value.i );
+                        if( psz_help )
+                        {
+                            config_data->psz_help = wraptext( strdup( psz_help ), 72 );
+                        }
+                        else
+                        {
+                            config_data->psz_help = NULL;
+                        }
+
+                        config_data->i_type = TYPE_CATEGORY;
+                        config_data->i_object_id = p_item->value.i;
+                        config_data->p_module =  p_module;
+                        tvi.pszText = _FROMMB(config_data->psz_name);
+                        tvi.cchTextMax = _tcslen(tvi.pszText);
+
+                        /* Add the category to the tree */
+                        tvi.lParam = (long)config_data;
+                        tvins.item = tvi;
+                        tvins.hInsertAfter = hPrev;
+                        tvins.hParent = general_item; //level 3
+
+                        // Add the item to the tree-view control.
+                        hPrev = (HTREEITEM)TreeView_InsertItem( hwndTV, &tvins );
+                        break;
+
+                    case CONFIG_SUBCATEGORY:
+                        if( p_item->value.i == -1 ) break; // Don't display it
+                        /* Special case: move the "general" subcategories to their parent category */
+                        if(config_data && p_item->value.i == SUBCAT_VIDEO_GENERAL ||
+                            p_item->value.i == SUBCAT_ADVANCED_MISC ||
+                            p_item->value.i == SUBCAT_INPUT_GENERAL ||
+                            p_item->value.i == SUBCAT_INTERFACE_GENERAL ||
+                            p_item->value.i == SUBCAT_SOUT_GENERAL||
+                            p_item->value.i == SUBCAT_PLAYLIST_GENERAL||
+                            p_item->value.i == SUBCAT_AUDIO_GENERAL )
+                        {
+
+                            config_data->i_type = TYPE_CATSUBCAT;
+                            config_data->i_subcat_id = p_item->value.i;
+                            free( config_data->psz_name );
+                            config_data->psz_name = strdup( config_CategoryNameGet( p_item->value.i ) );
+
+                            free( config_data->psz_help );
+                            const char *psz_help = config_CategoryHelpGet( p_item->value.i );
+                            if( psz_help )
+                            {
+                                config_data->psz_help = wraptext( strdup( psz_help ), 72 );
+                            }
+                            else
+                            {
+                                config_data->psz_help = NULL;
+                            }
+                            continue;
+                        }
+
+                        config_data = new ConfigTreeData;
+
+                        config_data->psz_name = strdup(  config_CategoryNameGet( p_item->value.i ) );
+                        psz_help = config_CategoryHelpGet( p_item->value.i );
+                        if( psz_help )
+                        {
+                            config_data->psz_help = wraptext( strdup( psz_help ), 72 );
+                        }
+                        else
+                        {
+                            config_data->psz_help = NULL;
+                        }
+                        config_data->i_type = TYPE_SUBCATEGORY;
+                        config_data->i_object_id = p_item->value.i;
+
+                        tvi.pszText = _FROMMB(config_data->psz_name);
+                        tvi.cchTextMax = _tcslen(tvi.pszText);
+
+                        tvi.lParam = (long)config_data;
+                        tvins.item = tvi;
+                        tvins.hInsertAfter = hPrev;
+                        tvins.hParent = hPrev;
+
+                        // Add the item to the tree-view control.
+                        TreeView_InsertItem( hwndTV, &tvins );
+                        break;
 
+                }
+         }
         TreeView_SortChildren( hwndTV, general_item, 0 );
+        module_PutConfig( p_config );
     }
-    /*
-     * Build a tree of all the plugins
-     */
-    config_data = new ConfigTreeData;
-    config_data->i_object_id = PLUGIN_ID;
-    config_data->psz_help = strdup("nothing");//strdup( PLUGIN_HELP );
-    config_data->psz_section = strdup("nothing");//strdup( PLUGIN_TITLE );
-    tvi.pszText = _T("Modules");
-    tvi.cchTextMax = lstrlen(_T("Modules"));
-    tvi.lParam = (long)config_data;
-    tvins.item = tvi;
-    tvins.hInsertAfter = TVI_LAST;
-    tvins.hParent = TVI_ROOT;
 
-    // Add the item to the tree-view control.
-    hPrev = (HTREEITEM) TreeView_InsertItem( hwndTV, &tvins);
-    plugins_item = hPrev;
 
-    i_capability_count = 0;
+    module_config_t *p_config;
+    /*
+    * Build a tree of all the plugins
+    */
     for( i_index = 0; i_index < p_list->i_count; i_index++ )
     {
-        i_child_index = 0;
-
+        /* Take every module */
         p_module = (module_t *)p_list->p_values[i_index].p_object;
 
         /* Exclude the main module */
-        if( !strcmp( p_module->psz_object_name, "main" ) )
+        if( !strcmp( module_GetObjName( p_module ), "main" ) )
             continue;
 
         /* Exclude empty plugins (submodules don't have config options, they
          * are stored in the parent module) */
-        if( p_module->b_submodule )
-            p_item = ((module_t *)p_module->p_parent)->p_config;
-        else
-            p_item = p_module->p_config;
 
-        if( !p_item ) continue;
-        do
+        unsigned int confsize;
+        i_child_index = 0;
+        int i_category = 0, i_subcategory = 0, i_options = 0;
+        bool b_options = false;
+
+        p_config = module_GetConfig( (module_t *) p_module,&confsize);
+
+        /* Loop through the configurations items */
+        for( size_t i = 0; i < confsize; i++ )
         {
+            module_config_t *p_item = p_config + i;
+            if( p_item->i_type == CONFIG_CATEGORY )
+                i_category = p_item->value.i;
+            else if( p_item->i_type == CONFIG_SUBCATEGORY )
+                i_subcategory = p_item->value.i;
+
             if( p_item->i_type & CONFIG_ITEM )
+                b_options = true;
+
+            if( b_options && i_category && i_subcategory )
                 break;
         }
-        while( p_item->i_type != CONFIG_HINT_END && p_item++ );
-        if( p_item->i_type == CONFIG_HINT_END ) continue;
+        module_PutConfig (p_config);
 
-        /* Find the capability child item */
-        /*long cookie; size_t i_child_index;*/
-        capability_item = TreeView_GetChild( hwndTV, plugins_item );
-        while( capability_item != 0 )
-        {
-            TVITEM capability_tvi = {0};
-            TCHAR psz_text[256];
-            i_child_index++;
-
-            capability_tvi.mask = TVIF_TEXT;
-            capability_tvi.pszText = psz_text;
-            capability_tvi.cchTextMax = 256;
-            capability_tvi.hItem = capability_item;
-            TreeView_GetItem( hwndTV, &capability_tvi );
-            if( !strcmp( _TOMB(capability_tvi.pszText),
-                         p_module->psz_capability ) ) break;
-            capability_item =
-                TreeView_GetNextSibling( hwndTV, capability_item );
-        }
+        //if( !i_options ) continue;
+        /* Dummy item, please proceed */
+        if( !b_options || i_category == 0 || i_subcategory == 0 ) continue;
 
-        if( i_child_index == i_capability_count &&
-            p_module->psz_capability && *p_module->psz_capability )
+        category_item = TreeView_GetChild( hwndTV, general_item );
+        while(category_item != 0)
         {
-            /* We didn't find it, add it */
-            ConfigTreeData *config_data = new ConfigTreeData;
-            config_data->psz_section =
-                strdup( GetCapabilityHelp( p_module->psz_capability , 1 ) );
-            config_data->psz_help =
-                strdup( GetCapabilityHelp( p_module->psz_capability , 2 ) );
-            config_data->i_object_id = CAPABILITY_ID;
-            tvi.pszText = _FROMMB(p_module->psz_capability);
-            tvi.cchTextMax = _tcslen(tvi.pszText);
-            tvi.lParam = (long)config_data;
-            tvins.item = tvi;
-            tvins.hInsertAfter = plugins_item;
-            tvins.hParent = plugins_item;// level 3
-
-            // Add the item to the tree-view control.
-            capability_item = (HTREEITEM) TreeView_InsertItem( hwndTV, &tvins);
-
-            i_capability_count++;
+            TVITEM category_tvi = {0};
+
+            category_tvi.mask = TVIF_PARAM;
+            category_tvi.lParam = NULL;
+            category_tvi.hItem = category_item;
+            TreeView_GetItem( hwndTV, &category_tvi );
+
+            ConfigTreeData * data = (ConfigTreeData *)category_tvi.lParam;
+
+            if( data->i_object_id == i_category )
+            {
+                subcategory_item = TreeView_GetChild( hwndTV, category_item );
+
+                while(subcategory_item != 0)
+                {
+                    TVITEM subcategory_tvi = {0};
+
+                    subcategory_tvi.mask = TVIF_PARAM;
+                    subcategory_tvi.lParam = NULL;
+                    subcategory_tvi.hItem = subcategory_item;
+                    TreeView_GetItem( hwndTV, &subcategory_tvi );
+
+                    ConfigTreeData * subdata = (ConfigTreeData *)subcategory_tvi.lParam;
+
+                    if( subdata->i_object_id == i_subcategory )
+                    {
+                        config_data = new ConfigTreeData;
+
+                        config_data->psz_name = strdup( module_GetObjName( p_module ) );
+                        config_data->psz_help = NULL;
+                        config_data->i_type = TYPE_MODULE;
+                        config_data->i_object_id = p_item->value.i;
+                        config_data->p_module = p_module;
+
+                        tvi.pszText = _FROMMB(module_GetName( p_module, false ));
+                        tvi.cchTextMax = _tcslen(tvi.pszText);
+
+                        tvi.lParam = (long)config_data;
+                        tvins.item = tvi;
+                        tvins.hInsertAfter = subcategory_item;
+                        tvins.hParent = subcategory_item;
+
+                // Add the item to the tree-view control.
+                        hPrev = (HTREEITEM)TreeView_InsertItem( hwndTV, &tvins );
+                        break;
+                    }
+                    subcategory_item = TreeView_GetNextSibling( hwndTV, subcategory_item );
+                }
+
+                break;
+            }
+
+            category_item = TreeView_GetNextSibling( hwndTV, category_item );
         }
 
-        /* Add the plugin to the tree */
-        ConfigTreeData *config_data = new ConfigTreeData;
-        config_data->b_submodule = p_module->b_submodule;
-        config_data->i_object_id = p_module->b_submodule ?
-            ((module_t *)p_module->p_parent)->i_object_id :
-            p_module->i_object_id;
-        config_data->psz_help = NULL;
-        tvi.pszText = _FROMMB(p_module->psz_object_name);
-        tvi.cchTextMax = _tcslen(tvi.pszText);
-        tvi.lParam = (long)config_data;
-        tvins.item = tvi;
-        tvins.hInsertAfter = capability_item;
-        tvins.hParent = capability_item;// level 4
-
-        // Add the item to the tree-view control.
-        TreeView_InsertItem( hwndTV, &tvins );
     }
 
     /* Sort all this mess */
-    /*long cookie; size_t i_child_index;*/
-    TreeView_SortChildren( hwndTV, plugins_item, 0 );
-    capability_item = TreeView_GetChild( hwndTV, plugins_item );
-    while( capability_item != 0 )
+    TreeView_SortChildren( hwndTV, general_item, 0 );
+    category_item = TreeView_GetChild( hwndTV, general_item );
+    while( category_item != 0 )
     {
-        TreeView_SortChildren( hwndTV, capability_item, 0 );
-        capability_item = TreeView_GetNextSibling( hwndTV, capability_item );
+        TreeView_SortChildren( hwndTV, category_item, 0 );
+        category_item = TreeView_GetNextSibling( hwndTV, category_item );
     }
 
     /* Clean-up everything */
@@ -561,7 +632,6 @@ PrefsTreeCtrl::~PrefsTreeCtrl()
 
 void PrefsTreeCtrl::ApplyChanges()
 {
-    /*long cookie, cookie2;*/
     ConfigTreeData *config_data;
 
     /* Apply changes to the main module */
@@ -582,20 +652,25 @@ void PrefsTreeCtrl::ApplyChanges()
     }
 
     /* Apply changes to the plugins */
-    item = TreeView_GetChild( hwndTV, plugins_item );
+    item = TreeView_GetChild( hwndTV, general_item );
     while( item != 0 )
     {
         HTREEITEM item2 = TreeView_GetChild( hwndTV, item );
         while( item2 != 0 )
         {
-            TVITEM tvi = {0};
-            tvi.mask = TVIF_PARAM;
-            tvi.hItem = item2;
-            TreeView_GetItem( hwndTV, &tvi );
-            config_data = (ConfigTreeData *)tvi.lParam;
-            if( config_data && config_data->panel )
+            HTREEITEM item3 = TreeView_GetChild( hwndTV, item2 );
+            while(item3 !=0)
             {
-                config_data->panel->ApplyChanges();
+                TVITEM tvi = {0};
+                tvi.mask = TVIF_PARAM;
+                tvi.hItem = item3;
+                TreeView_GetItem( hwndTV, &tvi );
+                config_data = (ConfigTreeData *)tvi.lParam;
+                if( config_data && config_data->panel )
+                {
+                    config_data->panel->ApplyChanges();
+                }
+                item3 = TreeView_GetNextSibling( hwndTV, item3 );
             }
             item2 = TreeView_GetNextSibling( hwndTV, item2 );
         }
@@ -605,31 +680,31 @@ void PrefsTreeCtrl::ApplyChanges()
 
 ConfigTreeData *PrefsTreeCtrl::FindModuleConfig( ConfigTreeData *config_data )
 {
-    /* We need this complexity because submodules don't have their own config
-     * options. They use the parent module ones. */
-
-    if( !config_data || !config_data->b_submodule )
+    if( !config_data || !config_data->p_module )
     {
         return config_data;
     }
 
-    /*long cookie, cookie2;*/
     ConfigTreeData *config_new;
-    HTREEITEM item = TreeView_GetChild( hwndTV, plugins_item );
+    HTREEITEM item = TreeView_GetChild( hwndTV, general_item );
     while( item != 0 )
     {
         HTREEITEM item2 = TreeView_GetChild( hwndTV, item );
         while( item2 != 0 )
         {
-            TVITEM tvi = {0};
-            tvi.mask = TVIF_PARAM;
-            tvi.hItem = item2;
-            TreeView_GetItem( hwndTV, &tvi );
-            config_new = (ConfigTreeData *)tvi.lParam;
-            if( config_new && !config_new->b_submodule &&
-                config_new->i_object_id == config_data->i_object_id )
+            HTREEITEM item3 = TreeView_GetChild( hwndTV, item2 );
+            while( item3 != 0 )
             {
-                return config_new;
+                TVITEM tvi = {0};
+                tvi.mask = TVIF_PARAM;
+                tvi.hItem = item3;
+                TreeView_GetItem( hwndTV, &tvi );
+                config_new = (ConfigTreeData *)tvi.lParam;
+                if( config_new && config_new->p_module == config_data->p_module )
+                {
+                    return config_new;
+                }
+                item3 = TreeView_GetNextSibling( hwndTV, item3 );
             }
             item2 = TreeView_GetNextSibling( hwndTV, item2 );
         }
@@ -666,9 +741,9 @@ void PrefsTreeCtrl::OnSelectTreeItem( LPNM_TREEVIEW pnmtv, HWND parent,
             /* The panel hasn't been created yet. Let's do it. */
             config_data->panel =
                 new PrefsPanel( parent, hInst, p_intf, p_prefs_dialog,
-                                config_data->i_object_id,
-                                config_data->psz_section,
-                                config_data->psz_help );
+                                config_data->p_module,
+                                config_data->psz_name,
+                                config_data->psz_help, config_data );
         }
         else
         {
@@ -682,21 +757,20 @@ void PrefsTreeCtrl::OnSelectTreeItem( LPNM_TREEVIEW pnmtv, HWND parent,
  *****************************************************************************/
 PrefsPanel::PrefsPanel( HWND parent, HINSTANCE hInst, intf_thread_t *_p_intf,
                         PrefsDialog *_p_prefs_dialog,
-                        int i_object_id, char *psz_section, char *psz_help )
+                        module_t *p_module, char *psz_name, char *psz_help, ConfigTreeData * config_data )
 {
-    module_config_t *p_item;
-    module_t *p_module = NULL;
+    module_config_t *p_item, *p_config, *p_end;
 
     /* Initializations */
     p_intf = _p_intf;
     p_prefs_dialog = _p_prefs_dialog;
+    vlc_list_t *p_list = NULL;
 
     b_advanced = true;
 
-    if( i_object_id == PLUGIN_ID || i_object_id == GENERAL_ID ||
-        i_object_id == CAPABILITY_ID )
+    if( config_data->i_type == TYPE_CATEGORY )
     {
-        label = CreateWindow( _T("STATIC"), _FROMMB(psz_section),
+        label = CreateWindow( _T("STATIC"), _FROMMB(psz_name),
                               WS_CHILD | WS_VISIBLE | SS_LEFT,
                               5, 10 + (15 + 10), 200, 15,
                               parent, NULL, hInst, NULL );
@@ -705,33 +779,79 @@ PrefsPanel::PrefsPanel( HWND parent, HINSTANCE hInst, intf_thread_t *_p_intf,
     else
     {
         /* Get a pointer to the module */
-        p_module = (module_t *)vlc_object_get( i_object_id );
+        if( config_data->i_type == TYPE_MODULE )
+        {
+            p_module = config_data->p_module;
+        }
+        else
+        {
+            /* List the plugins */
+            int i_index;
+            bool b_found = false;
+            p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
+            if( !p_list ) return;
+
+            for( i_index = 0; i_index < p_list->i_count; i_index++ )
+            {
+                p_module = (module_t *)p_list->p_values[i_index].p_object;
+                if( !strcmp( module_GetObjName(p_module), "main" ) )
+                {
+                    b_found = true;
+                    break;
+                }
+            }
+            if( !p_module && !b_found )
+            {
+                msg_Warn( p_intf, "unable to create preferences "
+                        "(main module not found)" );
+                return;
+            }
+        }
 
         /* Enumerate config options and add corresponding config boxes
          * (submodules don't have config options, they are stored in the
          *  parent module) */
-        if( p_module->b_submodule )
-            p_item = ((module_t *)p_module->p_parent)->p_config;
-        else
-            p_item = p_module->p_config;
+        unsigned confsize;
+        p_config = module_GetConfig( (module_t *) p_module,&confsize);
+
+        p_item = p_config;
+        p_end = p_config + confsize;
 
         /* Find the category if it has been specified */
-        if( psz_section && p_item->i_type == CONFIG_HINT_CATEGORY )
+        if( config_data->i_type == TYPE_SUBCATEGORY ||
+            config_data->i_type == TYPE_CATSUBCAT )
         {
-            while( !(p_item->i_type == CONFIG_HINT_CATEGORY) ||
-                   strcmp( psz_section, p_item->psz_text ) )
+            for( ; p_item && p_item < p_end ; p_item++ )
             {
-                if( p_item->i_type == CONFIG_HINT_END ) break;
-                p_item++;
+                if( p_item->i_type == CONFIG_SUBCATEGORY &&
+                    ( config_data->i_type == TYPE_SUBCATEGORY &&
+                    p_item->value.i == config_data->i_object_id ) ||
+                    ( config_data->i_type == TYPE_CATSUBCAT &&
+                    p_item->value.i == config_data->i_subcat_id ) )
+                {
+                    break;
+                }
             }
         }
 
         /* Add a head title to the panel */
-        label = CreateWindow( _T("STATIC"), _FROMMB(psz_section ?
-                        p_item->psz_text : p_module->psz_longname),
+        const char *psz_head;
+        if( config_data->i_type == TYPE_SUBCATEGORY ||
+            config_data->i_type == TYPE_CATSUBCAT )
+        {
+            psz_head = config_data->psz_name;
+            p_item++;
+        }
+        else
+        {
+            psz_head = module_GetLongName(p_module);
+        }
+
+        label = CreateWindow( _T("STATIC"), _FROMMB(psz_head ?
+                psz_head : _("Unknown")),
                         WS_CHILD | WS_VISIBLE | SS_LEFT,
                         5, 10 + (15 + 10), 250, 15,
-                        parent, NULL, hInst, NULL );
+                                 parent, NULL, hInst, NULL );
 
         WNDCLASS wc;
         memset( &wc, 0, sizeof(wc) );
@@ -756,15 +876,20 @@ PrefsPanel::PrefsPanel( HWND parent, HINSTANCE hInst, intf_thread_t *_p_intf,
                         parent, NULL, hInst, (void *) _p_prefs_dialog );
 
         int y_pos = 5;
-        if( p_item ) do
+        for( ; p_item && p_item < p_end ; p_item++ )
         {
             /* If a category has been specified, check we finished the job */
-            if( psz_section && p_item->i_type == CONFIG_HINT_CATEGORY &&
-                strcmp( psz_section, p_item->psz_text ) )
+            if( ( ( config_data->i_type == TYPE_SUBCATEGORY &&
+                    p_item->value.i != config_data->i_object_id ) ||
+                    ( config_data->i_type == TYPE_CATSUBCAT  &&
+                    p_item->value.i != config_data->i_subcat_id ) ) &&
+                    (p_item->i_type == CONFIG_CATEGORY ||
+                    p_item->i_type == CONFIG_SUBCATEGORY ) )
                 break;
 
-            ConfigControl *control =
-                CreateConfigControl( VLC_OBJECT(p_intf),
+            ConfigControl *control = NULL;
+
+            control = CreateConfigControl( VLC_OBJECT(p_intf),
                                      p_item, config_window,
                                      hInst, &y_pos );
 
@@ -774,8 +899,6 @@ PrefsPanel::PrefsPanel( HWND parent, HINSTANCE hInst, intf_thread_t *_p_intf,
             /* Add the config data to our array so we can keep a trace of it */
             config_array.push_back( control );
         }
-        while( p_item->i_type != CONFIG_HINT_END && p_item++ );
         GetWindowRect( config_window, &rc);
         maxvalue = y_pos - (rc.bottom - rc.top) + 5;
         oldvalue = 0;
@@ -798,7 +921,6 @@ void PrefsPanel::Show()
 void PrefsPanel::ApplyChanges()
 {
     vlc_value_t val;
-
     for( size_t i = 0; i < config_array.size(); i++ )
     {
         ConfigControl *control = config_array[i];