preferences.cpp 36.4 KB
Newer Older
Gildas Bazin's avatar
 
Gildas Bazin committed
1 2 3
/*****************************************************************************
 * preferences.cpp : wxWindows plugin for vlc
 *****************************************************************************
4
 * Copyright (C) 2000-2004 the VideoLAN team
5
 * $Id$
Gildas Bazin's avatar
 
Gildas Bazin committed
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
 *
 * Authors: Gildas Bazin <gbazin@netcourrier.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
Antoine Cellerier's avatar
Antoine Cellerier committed
21
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
Gildas Bazin's avatar
 
Gildas Bazin committed
22 23 24 25 26 27
 *****************************************************************************/

/*****************************************************************************
 * Preamble
 *****************************************************************************/

28
#include "dialogs/preferences.hpp"
Clément Stenac's avatar
Clément Stenac committed
29
#include <vlc_config_cat.h>
30
#include "dialogs/preferences_widgets.h"
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
31

Gildas Bazin's avatar
 
Gildas Bazin committed
32 33
#include <wx/combobox.h>
#include <wx/statline.h>
Gildas Bazin's avatar
 
Gildas Bazin committed
34 35
#include <wx/clntdata.h>
#include <wx/dynarray.h>
Clément Stenac's avatar
Clément Stenac committed
36
#include <wx/imaglist.h>
37
#include <wx/treectrl.h>
Gildas Bazin's avatar
 
Gildas Bazin committed
38

Clément Stenac's avatar
Clément Stenac committed
39 40 41 42 43 44 45 46
#include "bitmaps/type_net.xpm"
#include "bitmaps/codec.xpm"
#include "bitmaps/video.xpm"
#include "bitmaps/type_playlist.xpm"
#include "bitmaps/advanced.xpm"
#include "bitmaps/intf.xpm"
#include "bitmaps/audio.xpm"

Gildas Bazin's avatar
 
Gildas Bazin committed
47 48 49 50
#ifndef wxRB_SINGLE
#   define wxRB_SINGLE 0
#endif

Clément Stenac's avatar
Clément Stenac committed
51
#define TYPE_CATEGORY 0
52 53 54
#define TYPE_CATSUBCAT 1  /* Category with embedded subcategory */
#define TYPE_SUBCATEGORY 2
#define TYPE_MODULE 3
55

Gildas Bazin's avatar
 
Gildas Bazin committed
56 57 58
/*****************************************************************************
 * Classes declarations.
 *****************************************************************************/
Gildas Bazin's avatar
 
Gildas Bazin committed
59
class ConfigTreeData;
Gildas Bazin's avatar
 
Gildas Bazin committed
60 61 62 63 64 65 66 67 68
class PrefsTreeCtrl : public wxTreeCtrl
{
public:

    PrefsTreeCtrl() { }
    PrefsTreeCtrl( wxWindow *parent, intf_thread_t *_p_intf,
                   PrefsDialog *p_prefs_dialog, wxBoxSizer *_p_sizer );
    virtual ~PrefsTreeCtrl();

Gildas Bazin's avatar
 
Gildas Bazin committed
69
    void ApplyChanges();
Gildas Bazin's avatar
 
Gildas Bazin committed
70
    void CleanChanges();
Gildas Bazin's avatar
 
Gildas Bazin committed
71

Gildas Bazin's avatar
 
Gildas Bazin committed
72 73 74
private:
    /* Event handlers (these functions should _not_ be virtual) */
    void OnSelectTreeItem( wxTreeEvent& event );
Gildas Bazin's avatar
 
Gildas Bazin committed
75 76
    void OnAdvanced( wxCommandEvent& event );

Gildas Bazin's avatar
 
Gildas Bazin committed
77
    ConfigTreeData *FindModuleConfig( ConfigTreeData *config_data );
Gildas Bazin's avatar
 
Gildas Bazin committed
78 79 80 81 82 83 84

    DECLARE_EVENT_TABLE()

    intf_thread_t *p_intf;
    PrefsDialog *p_prefs_dialog;
    wxBoxSizer *p_sizer;
    wxWindow *p_parent;
Gildas Bazin's avatar
 
Gildas Bazin committed
85
    vlc_bool_t b_advanced;
Gildas Bazin's avatar
 
Gildas Bazin committed
86

87 88
    wxPanel *p_current;

Gildas Bazin's avatar
 
Gildas Bazin committed
89
    wxTreeItemId root_item;
Gildas Bazin's avatar
 
Gildas Bazin committed
90
    wxTreeItemId plugins_item;
Gildas Bazin's avatar
 
Gildas Bazin committed
91 92
};

93
WX_DEFINE_ARRAY(ConfigControl *, ArrayOfConfigControls);
Gildas Bazin's avatar
 
Gildas Bazin committed
94 95

class PrefsPanel : public wxPanel
Gildas Bazin's avatar
 
Gildas Bazin committed
96 97 98 99 100
{
public:

    PrefsPanel() { }
    PrefsPanel( wxWindow *parent, intf_thread_t *_p_intf,
Clément Stenac's avatar
Clément Stenac committed
101
                PrefsDialog *, ConfigTreeData* );
Gildas Bazin's avatar
 
Gildas Bazin committed
102 103
    virtual ~PrefsPanel() {}

Gildas Bazin's avatar
 
Gildas Bazin committed
104
    void ApplyChanges();
Gildas Bazin's avatar
 
Gildas Bazin committed
105
    void SwitchAdvanced( vlc_bool_t );
Gildas Bazin's avatar
 
Gildas Bazin committed
106

Gildas Bazin's avatar
 
Gildas Bazin committed
107 108
private:
    intf_thread_t *p_intf;
Gildas Bazin's avatar
 
Gildas Bazin committed
109 110
    PrefsDialog *p_prefs_dialog;

Gildas Bazin's avatar
 
Gildas Bazin committed
111 112
    vlc_bool_t b_advanced;

Clément Stenac's avatar
Clément Stenac committed
113
    wxStaticText *hidden_text;
Gildas Bazin's avatar
 
Gildas Bazin committed
114 115 116
    wxBoxSizer *config_sizer;
    wxScrolledWindow *config_window;

117
    ArrayOfConfigControls config_array;
Gildas Bazin's avatar
 
Gildas Bazin committed
118 119
};

Gildas Bazin's avatar
 
Gildas Bazin committed
120
class ConfigTreeData : public wxTreeItemData
Gildas Bazin's avatar
 
Gildas Bazin committed
121 122 123
{
public:

Clément Stenac's avatar
Clément Stenac committed
124
    ConfigTreeData() { b_submodule = 0; panel = NULL; psz_name = NULL;
Gildas Bazin's avatar
 
Gildas Bazin committed
125
                       psz_help = NULL; }
Clément Stenac's avatar
Clément Stenac committed
126 127 128 129 130
    virtual ~ConfigTreeData() {
                                 if( panel ) delete panel;
                                 if( psz_name ) free( psz_name );
                                 if( psz_help ) free( psz_help );
                              };
Gildas Bazin's avatar
 
Gildas Bazin committed
131

Gildas Bazin's avatar
 
Gildas Bazin committed
132 133
    vlc_bool_t b_submodule;

Gildas Bazin's avatar
 
Gildas Bazin committed
134
    PrefsPanel *panel;
Gildas Bazin's avatar
 
Gildas Bazin committed
135
    wxBoxSizer *sizer;
Clément Stenac's avatar
Clément Stenac committed
136

Gildas Bazin's avatar
 
Gildas Bazin committed
137
    int i_object_id;
Clément Stenac's avatar
 
Clément Stenac committed
138
    int i_subcat_id;
Clément Stenac's avatar
Clément Stenac committed
139 140
    int i_type;
    char *psz_name;
Gildas Bazin's avatar
 
Gildas Bazin committed
141
    char *psz_help;
Gildas Bazin's avatar
 
Gildas Bazin committed
142 143 144 145 146 147 148 149 150 151 152
};

/*****************************************************************************
 * Event Table.
 *****************************************************************************/

/* IDs for the controls and the menu commands */
enum
{
    Notebook_Event = wxID_HIGHEST,
    MRL_Event,
Gildas Bazin's avatar
 
Gildas Bazin committed
153
    ResetAll_Event,
Gildas Bazin's avatar
 
Gildas Bazin committed
154
    Advanced_Event,
Gildas Bazin's avatar
 
Gildas Bazin committed
155 156
};

Gildas Bazin's avatar
 
Gildas Bazin committed
157
BEGIN_EVENT_TABLE(PrefsDialog, wxFrame)
Gildas Bazin's avatar
 
Gildas Bazin committed
158 159 160
    /* Button events */
    EVT_BUTTON(wxID_OK, PrefsDialog::OnOk)
    EVT_BUTTON(wxID_CANCEL, PrefsDialog::OnCancel)
Gildas Bazin's avatar
 
Gildas Bazin committed
161
    EVT_BUTTON(wxID_SAVE, PrefsDialog::OnSave)
Gildas Bazin's avatar
 
Gildas Bazin committed
162
    EVT_BUTTON(ResetAll_Event, PrefsDialog::OnResetAll)
Gildas Bazin's avatar
 
Gildas Bazin committed
163
    EVT_CHECKBOX(Advanced_Event, PrefsDialog::OnAdvanced)
Gildas Bazin's avatar
 
Gildas Bazin committed
164

Gildas Bazin's avatar
 
Gildas Bazin committed
165
    /* Don't destroy the window when the user closes it */
166
    EVT_CLOSE(PrefsDialog::OnClose)
Gildas Bazin's avatar
 
Gildas Bazin committed
167 168 169 170 171 172 173 174 175 176
END_EVENT_TABLE()

// menu and control ids
enum
{
    PrefsTree_Ctrl = wxID_HIGHEST
};

BEGIN_EVENT_TABLE(PrefsTreeCtrl, wxTreeCtrl)
    EVT_TREE_SEL_CHANGED(PrefsTree_Ctrl, PrefsTreeCtrl::OnSelectTreeItem)
Gildas Bazin's avatar
 
Gildas Bazin committed
177
    EVT_COMMAND(Advanced_Event, wxEVT_USER_FIRST, PrefsTreeCtrl::OnAdvanced)
Gildas Bazin's avatar
 
Gildas Bazin committed
178 179 180 181 182
END_EVENT_TABLE()

/*****************************************************************************
 * Constructor.
 *****************************************************************************/
Gildas Bazin's avatar
 
Gildas Bazin committed
183 184
PrefsDialog::PrefsDialog( intf_thread_t *_p_intf, wxWindow *p_parent)
  :  wxFrame( p_parent, -1, wxU(_("Preferences")), wxDefaultPosition,
Gildas Bazin's avatar
 
Gildas Bazin committed
185
              wxSize(700,450), wxDEFAULT_FRAME_STYLE )
Gildas Bazin's avatar
 
Gildas Bazin committed
186 187 188
{
    /* Initializations */
    p_intf = _p_intf;
Gildas Bazin's avatar
 
Gildas Bazin committed
189
    SetIcon( *p_intf->p_sys->p_icon );
Gildas Bazin's avatar
 
Gildas Bazin committed
190 191 192 193 194 195 196

    /* Create a panel to put everything in */
    wxPanel *panel = new wxPanel( this, -1 );
    panel->SetAutoLayout( TRUE );

    /* Create the preferences tree control */
    wxBoxSizer *controls_sizer = new wxBoxSizer( wxHORIZONTAL );
Gildas Bazin's avatar
 
Gildas Bazin committed
197
    prefs_tree =
Gildas Bazin's avatar
 
Gildas Bazin committed
198 199 200 201 202
        new PrefsTreeCtrl( panel, p_intf, this, controls_sizer );

    /* Separation */
    wxStaticLine *static_line = new wxStaticLine( panel, wxID_OK );

Clément Stenac's avatar
Clément Stenac committed
203
#if 0
Gildas Bazin's avatar
 
Gildas Bazin committed
204
    /* Create the buttons */
205
    wxButton *ok_button = new wxButton( panel, wxID_OK, wxU(_("OK")) );
Gildas Bazin's avatar
 
Gildas Bazin committed
206
    ok_button->SetDefault();
Clément Stenac's avatar
Clément Stenac committed
207
#endif
208
    wxButton *save_button = new wxButton( panel, wxID_SAVE, wxU(_("&Save")) );
Clément Stenac's avatar
Clément Stenac committed
209
    save_button->SetDefault();
210 211
    wxButton *cancel_button = new wxButton( panel, wxID_CANCEL,
                                            wxU(_("&Cancel")) );
Gildas Bazin's avatar
 
Gildas Bazin committed
212 213
    wxButton *reset_button = new wxButton( panel, ResetAll_Event,
                                           wxU(_("Reset All")) );
Gildas Bazin's avatar
 
Gildas Bazin committed
214

Gildas Bazin's avatar
 
Gildas Bazin committed
215 216 217 218 219 220 221 222 223 224 225 226
    wxPanel *dummy_panel = new wxPanel( this, -1 );
    wxCheckBox *advanced_checkbox =
        new wxCheckBox( panel, Advanced_Event, wxU(_("Advanced options")) );

    if( config_GetInt( p_intf, "advanced" ) )
    {
        advanced_checkbox->SetValue(TRUE);
        wxCommandEvent dummy_event;
        dummy_event.SetInt(TRUE);
        OnAdvanced( dummy_event );
    }

Gildas Bazin's avatar
 
Gildas Bazin committed
227 228
    /* Place everything in sizers */
    wxBoxSizer *button_sizer = new wxBoxSizer( wxHORIZONTAL );
Clément Stenac's avatar
Clément Stenac committed
229
#if 0
Gildas Bazin's avatar
 
Gildas Bazin committed
230
    button_sizer->Add( ok_button, 0, wxALL, 5 );
Clément Stenac's avatar
Clément Stenac committed
231
#endif
Gildas Bazin's avatar
 
Gildas Bazin committed
232
    button_sizer->Add( save_button, 0, wxALL, 5 );
Clément Stenac's avatar
Clément Stenac committed
233
    button_sizer->Add( cancel_button, 0, wxALL, 5 );
Gildas Bazin's avatar
 
Gildas Bazin committed
234
    button_sizer->Add( reset_button, 0, wxALL, 5 );
Gildas Bazin's avatar
 
Gildas Bazin committed
235 236 237
    button_sizer->Add( dummy_panel, 1, wxALL, 5 );
    button_sizer->Add( advanced_checkbox, 0, wxALL | wxALIGN_RIGHT |
                       wxALIGN_CENTER_VERTICAL, 0 );
Gildas Bazin's avatar
 
Gildas Bazin committed
238 239 240 241 242 243 244
    button_sizer->Layout();

    wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL );
    wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
    panel_sizer->Add( controls_sizer, 1, wxEXPAND | wxALL, 5 );
    panel_sizer->Add( static_line, 0, wxEXPAND | wxALL, 5 );
    panel_sizer->Add( button_sizer, 0, wxALIGN_LEFT | wxALIGN_BOTTOM |
Gildas Bazin's avatar
 
Gildas Bazin committed
245
                      wxALL | wxEXPAND, 5 );
Gildas Bazin's avatar
 
Gildas Bazin committed
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266
    panel_sizer->Layout();
    panel->SetSizer( panel_sizer );
    main_sizer->Add( panel, 1, wxEXPAND, 0 );
    main_sizer->Layout();
    SetSizer( main_sizer );
}

PrefsDialog::~PrefsDialog()
{
}

/*****************************************************************************
 * Private methods.
 *****************************************************************************/


/*****************************************************************************
 * Events methods.
 *****************************************************************************/
void PrefsDialog::OnOk( wxCommandEvent& WXUNUSED(event) )
{
Gildas Bazin's avatar
 
Gildas Bazin committed
267
    prefs_tree->ApplyChanges();
Gildas Bazin's avatar
 
Gildas Bazin committed
268
    this->Hide();
Gildas Bazin's avatar
 
Gildas Bazin committed
269
    prefs_tree->CleanChanges();
Gildas Bazin's avatar
 
Gildas Bazin committed
270 271
}

272 273 274 275 276 277 278
void PrefsDialog::OnClose( wxCloseEvent& WXUNUSED(event) )
{
    wxCommandEvent cevent;
    OnCancel(cevent);
}

void PrefsDialog::OnCancel( wxCommandEvent& WXUNUSED(event) )
Gildas Bazin's avatar
 
Gildas Bazin committed
279 280
{
    this->Hide();
Gildas Bazin's avatar
 
Gildas Bazin committed
281
    prefs_tree->CleanChanges();
Gildas Bazin's avatar
 
Gildas Bazin committed
282 283
}

Gildas Bazin's avatar
 
Gildas Bazin committed
284
void PrefsDialog::OnSave( wxCommandEvent& WXUNUSED(event) )
Gildas Bazin's avatar
 
Gildas Bazin committed
285
{
Gildas Bazin's avatar
 
Gildas Bazin committed
286 287
    prefs_tree->ApplyChanges();
    config_SaveConfigFile( p_intf, NULL );
Gildas Bazin's avatar
 
Gildas Bazin committed
288
    this->Hide();
Gildas Bazin's avatar
 
Gildas Bazin committed
289 290
}

Gildas Bazin's avatar
 
Gildas Bazin committed
291 292 293
void PrefsDialog::OnResetAll( wxCommandEvent& WXUNUSED(event) )
{
    wxMessageDialog dlg( this,
294
        wxU(_("This will reset your VLC media player preferences.\n"
Gildas Bazin's avatar
 
Gildas Bazin committed
295
              "Are you sure you want to continue?")),
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
296
        wxU(_("Reset Preferences")), wxYES_NO|wxNO_DEFAULT|wxCENTRE );
Gildas Bazin's avatar
 
Gildas Bazin committed
297 298 299 300 301

    if ( dlg.ShowModal() == wxID_YES )
    {
        /* TODO: need to reset all the controls */
        config_ResetAll( p_intf );
Gildas Bazin's avatar
 
Gildas Bazin committed
302
        prefs_tree->CleanChanges();
Gildas Bazin's avatar
 
Gildas Bazin committed
303 304 305 306
        config_SaveConfigFile( p_intf, NULL );
    }
}

Gildas Bazin's avatar
 
Gildas Bazin committed
307 308 309 310 311 312 313 314
void PrefsDialog::OnAdvanced( wxCommandEvent& event )
{
    wxCommandEvent newevent( wxEVT_USER_FIRST, Advanced_Event );
    newevent.SetInt( event.GetInt() );

    prefs_tree->AddPendingEvent( newevent );
}

Gildas Bazin's avatar
 
Gildas Bazin committed
315 316 317 318 319 320
/*****************************************************************************
 * PrefsTreeCtrl class definition.
 *****************************************************************************/
PrefsTreeCtrl::PrefsTreeCtrl( wxWindow *_p_parent, intf_thread_t *_p_intf,
                              PrefsDialog *_p_prefs_dialog,
                              wxBoxSizer *_p_sizer )
Clément Stenac's avatar
 
Clément Stenac committed
321
  : wxTreeCtrl( _p_parent, PrefsTree_Ctrl, wxDefaultPosition, wxSize(200,-1),
Gildas Bazin's avatar
 
Gildas Bazin committed
322 323 324 325
                wxTR_NO_LINES | wxTR_FULL_ROW_HIGHLIGHT |
                wxTR_LINES_AT_ROOT | wxTR_HIDE_ROOT |
                wxTR_HAS_BUTTONS | wxTR_TWIST_BUTTONS | wxSUNKEN_BORDER )
{
Clément Stenac's avatar
Clément Stenac committed
326
    vlc_list_t      *p_list = NULL;;
Gildas Bazin's avatar
 
Gildas Bazin committed
327
    module_t        *p_module;
328
    module_config_t *p_item, *p_end;
329
    int i_index, i_image=0;
Gildas Bazin's avatar
 
Gildas Bazin committed
330 331 332 333 334 335

    /* Initializations */
    p_intf = _p_intf;
    p_prefs_dialog = _p_prefs_dialog;
    p_sizer = _p_sizer;
    p_parent = _p_parent;
Gildas Bazin's avatar
 
Gildas Bazin committed
336
    b_advanced = VLC_FALSE;
Gildas Bazin's avatar
 
Gildas Bazin committed
337

Gildas Bazin's avatar
 
Gildas Bazin committed
338
    root_item = AddRoot( wxT("") );
339
    wxASSERT_MSG(root_item.IsOk(), wxT("Could not add root item"));
Gildas Bazin's avatar
 
Gildas Bazin committed
340

Clément Stenac's avatar
Clément Stenac committed
341 342 343 344 345 346 347 348 349 350
    wxImageList *p_images = new wxImageList( 16,16,TRUE );
    p_images->Add( wxIcon( audio_xpm ) );
    p_images->Add( wxIcon( video_xpm ) );
    p_images->Add( wxIcon( codec_xpm ) );
    p_images->Add( wxIcon( type_net_xpm ) );
    p_images->Add( wxIcon( advanced_xpm ) );
    p_images->Add( wxIcon( type_playlist_xpm ) );
    p_images->Add( wxIcon( intf_xpm ) );
    AssignImageList( p_images );

Gildas Bazin's avatar
 
Gildas Bazin committed
351 352 353 354
    /* List the plugins */
    p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
    if( !p_list ) return;

Clément Stenac's avatar
Clément Stenac committed
355
    /* Build the categories list */
Gildas Bazin's avatar
 
Gildas Bazin committed
356 357 358
    for( i_index = 0; i_index < p_list->i_count; i_index++ )
    {
        p_module = (module_t *)p_list->p_values[i_index].p_object;
359
        if( !strcmp( module_GetObjName(p_module), "main" ) )
Gildas Bazin's avatar
 
Gildas Bazin committed
360 361 362 363
            break;
    }
    if( i_index < p_list->i_count )
    {
Clément Stenac's avatar
Clément Stenac committed
364
        wxTreeItemId current_item;
365
        const char *psz_help;
366 367 368
        unsigned int i_confsize;
        module_config_t *p_config;

Gildas Bazin's avatar
 
Gildas Bazin committed
369 370
        /* We found the main module */

Gildas Bazin's avatar
 
Gildas Bazin committed
371 372
        /* Enumerate config categories and store a reference so we can
         * generate their config panel them when it is asked by the user. */
Gildas Bazin's avatar
 
Gildas Bazin committed
373

374 375
        p_config = module_GetConfig( p_module, &i_confsize );
        for( size_t i = 0; i < i_confsize; i++ )
Gildas Bazin's avatar
 
Gildas Bazin committed
376
        {
377
            module_config_t *p_item = p_config + i;
Clément Stenac's avatar
Clément Stenac committed
378
            ConfigTreeData *config_data;
Gildas Bazin's avatar
 
Gildas Bazin committed
379 380
            switch( p_item->i_type )
            {
Clément Stenac's avatar
Clément Stenac committed
381
            case CONFIG_CATEGORY:
382
                if( p_item->value.i == -1 )   break; // Don't display it
383 384

                config_data = new ConfigTreeData;
Clément Stenac's avatar
Clément Stenac committed
385
                config_data->psz_name = strdup( config_CategoryNameGet(
386 387
                                                            p_item->value.i ) );
                psz_help = config_CategoryHelpGet( p_item->value.i );
Clément Stenac's avatar
Clément Stenac committed
388
                if( psz_help )
Gildas Bazin's avatar
 
Gildas Bazin committed
389
                {
390
                    config_data->psz_help = wraptext( strdup( psz_help ), 72 );
Gildas Bazin's avatar
 
Gildas Bazin committed
391 392 393 394 395
                }
                else
                {
                    config_data->psz_help = NULL;
                }
Clément Stenac's avatar
Clément Stenac committed
396
                config_data->i_type = TYPE_CATEGORY;
397
                config_data->i_object_id = p_item->value.i;
Gildas Bazin's avatar
 
Gildas Bazin committed
398 399

                /* Add the category to the tree */
400
                switch( p_item->value.i )
Clément Stenac's avatar
Clément Stenac committed
401 402
                {
                    case CAT_AUDIO:
403
                        i_image = 0; break;
Clément Stenac's avatar
Clément Stenac committed
404
                    case CAT_VIDEO:
405
                        i_image = 1; break;
Clément Stenac's avatar
Clément Stenac committed
406
                    case CAT_INPUT:
407
                        i_image = 2; break;
Clément Stenac's avatar
Clément Stenac committed
408
                    case CAT_SOUT:
409
                        i_image = 3; break;
Clément Stenac's avatar
Clément Stenac committed
410
                    case CAT_ADVANCED:
411
                        i_image = 4; break;
Clément Stenac's avatar
Clément Stenac committed
412
                    case CAT_PLAYLIST:
413
                        i_image = 5; break;
Clément Stenac's avatar
Clément Stenac committed
414
                    case CAT_INTERFACE:
415
                        i_image = 6; break;
Clément Stenac's avatar
Clément Stenac committed
416
                }
417
                current_item = AppendItem( root_item,
418
                                           wxU( _(config_data->psz_name) ),
419 420
                                           i_image, -1, config_data );

Clément Stenac's avatar
Clément Stenac committed
421 422
                break;
            case CONFIG_SUBCATEGORY:
423
                if( p_item->value.i == -1 ) break; // Don't display it
Clément Stenac's avatar
Clément Stenac committed
424 425
                /* Special case: move the "general" subcategories to their
                 * parent category */
426 427 428 429 430 431 432
                if( 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 )
433 434 435 436
                {
                    ConfigTreeData *cd = (ConfigTreeData *)
                                            GetItemData( current_item );
                    cd->i_type = TYPE_CATSUBCAT;
437
                    cd->i_subcat_id = p_item->value.i;
438 439
                    if( cd->psz_name ) free( cd->psz_name );
                    cd->psz_name = strdup(  config_CategoryNameGet(
440
                                                      p_item->value.i ) );
441
                    if( cd->psz_help ) free( cd->psz_help );
442
                    const char *psz_help = config_CategoryHelpGet( p_item->value.i );
443 444
                    if( psz_help )
                    {
445
                        cd->psz_help = wraptext( strdup( psz_help ), 72 );
446 447 448 449 450 451 452 453
                    }
                    else
                    {
                        cd->psz_help = NULL;
                    }
                    continue;
                }

Clément Stenac's avatar
Clément Stenac committed
454
                config_data = new ConfigTreeData;
455

Clément Stenac's avatar
Clément Stenac committed
456
                config_data->psz_name = strdup(  config_CategoryNameGet(
457 458
                                                           p_item->value.i ) );
                psz_help = config_CategoryHelpGet( p_item->value.i );
Clément Stenac's avatar
Clément Stenac committed
459 460
                if( psz_help )
                {
461
                    config_data->psz_help = wraptext( strdup( psz_help ), 72 );
Clément Stenac's avatar
Clément Stenac committed
462 463 464 465 466 467
                }
                else
                {
                    config_data->psz_help = NULL;
                }
                config_data->i_type = TYPE_SUBCATEGORY;
468
                config_data->i_object_id = p_item->value.i;
469 470
                /* WXMSW doesn't know image -1 ... FIXME */
                #ifdef __WXMSW__
471
                switch( p_item->value.i / 100 )
472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490
                {
                    case CAT_AUDIO:
                        i_image = 0; break;
                    case CAT_VIDEO:
                        i_image = 1; break;
                    case CAT_INPUT:
                        i_image = 2; break;
                    case CAT_SOUT:
                        i_image = 3; break;
                    case CAT_ADVANCED:
                        i_image = 4; break;
                    case CAT_PLAYLIST:
                        i_image = 5; break;
                    case CAT_INTERFACE:
                        i_image = 6; break;
                }
                #else
                i_image = -1;
                #endif
491
                AppendItem( current_item, wxU( _(config_data->psz_name) ),
492
                            i_image, -1, config_data );
Gildas Bazin's avatar
 
Gildas Bazin committed
493 494 495 496
                break;
            }
        }

497
        module_PutConfig( p_config );
Gildas Bazin's avatar
 
Gildas Bazin committed
498 499
    }

Gildas Bazin's avatar
 
Gildas Bazin committed
500

Gildas Bazin's avatar
 
Gildas Bazin committed
501 502 503 504 505
    /*
     * Build a tree of all the plugins
     */
    for( i_index = 0; i_index < p_list->i_count; i_index++ )
    {
506 507 508
        int i_category = -1, i_subcategory = -1, i_options = 0;
        unsigned int i_confsize;
        module_config_t *p_config;
Clément Stenac's avatar
Clément Stenac committed
509

Gildas Bazin's avatar
 
Gildas Bazin committed
510 511
        p_module = (module_t *)p_list->p_values[i_index].p_object;

Gildas Bazin's avatar
 
Gildas Bazin committed
512
        /* Exclude the main module */
513
        if( !strcmp( module_GetObjName(p_module), "main" ) )
Gildas Bazin's avatar
 
Gildas Bazin committed
514
            continue;
515

Gildas Bazin's avatar
 
Gildas Bazin committed
516 517
        /* Exclude empty plugins (submodules don't have config options, they
         * are stored in the parent module) */
518 519 520 521 522
        if( module_IsSubModule(p_module) )
            continue;

        p_config = module_GetConfig( p_module, &i_confsize );
        for( size_t i = 0; i < i_confsize; i++ )
Gildas Bazin's avatar
 
Gildas Bazin committed
523
        {
524
            module_config_t *p_item = p_config + i;
Clément Stenac's avatar
Clément Stenac committed
525 526
            if( p_item->i_type == CONFIG_CATEGORY )
            {
527
                i_category = p_item->value.i;
Clément Stenac's avatar
Clément Stenac committed
528 529 530
            }
            else if( p_item->i_type == CONFIG_SUBCATEGORY )
            {
531
                i_subcategory = p_item->value.i;
Clément Stenac's avatar
Clément Stenac committed
532
            }
Gildas Bazin's avatar
 
Gildas Bazin committed
533
            if( p_item->i_type & CONFIG_ITEM )
Clément Stenac's avatar
Clément Stenac committed
534 535 536
                i_options ++;
            if( i_options > 0 && i_category >= 0 && i_subcategory >= 0 )
            {
Gildas Bazin's avatar
 
Gildas Bazin committed
537
                break;
Clément Stenac's avatar
Clément Stenac committed
538
            }
Gildas Bazin's avatar
 
Gildas Bazin committed
539 540
        }

Clément Stenac's avatar
Clément Stenac committed
541 542 543
        if( !i_options ) continue;

        /* Find the right category item */
544
        wxTreeItemIdValue cookie;
Clément Stenac's avatar
Clément Stenac committed
545
        vlc_bool_t b_found = VLC_FALSE;
546

Clément Stenac's avatar
Clément Stenac committed
547 548
        wxTreeItemId category_item = GetFirstChild( root_item , cookie);
        while( category_item.IsOk() )
Gildas Bazin's avatar
 
Gildas Bazin committed
549
        {
Clément Stenac's avatar
Clément Stenac committed
550 551 552
            ConfigTreeData *config_data =
                    (ConfigTreeData *)GetItemData( category_item );
            if( config_data->i_object_id == i_category )
Gildas Bazin's avatar
 
Gildas Bazin committed
553
            {
Clément Stenac's avatar
Clément Stenac committed
554
                b_found = VLC_TRUE;
Gildas Bazin's avatar
 
Gildas Bazin committed
555 556
                break;
            }
Clément Stenac's avatar
Clément Stenac committed
557
            category_item = GetNextChild( root_item, cookie );
Gildas Bazin's avatar
 
Gildas Bazin committed
558
        }
Clément Stenac's avatar
Clément Stenac committed
559 560 561 562
        if( !b_found ) continue;

        /* Find subcategory item */
        b_found = VLC_FALSE;
563
        //cookie = -1;
Clément Stenac's avatar
Clément Stenac committed
564 565
        wxTreeItemId subcategory_item = GetFirstChild( category_item, cookie );
        while( subcategory_item.IsOk() )
Gildas Bazin's avatar
 
Gildas Bazin committed
566
        {
Clément Stenac's avatar
Clément Stenac committed
567 568 569 570 571 572 573 574 575 576 577 578
            ConfigTreeData *config_data =
                    (ConfigTreeData *)GetItemData( subcategory_item );
            if( config_data->i_object_id == i_subcategory )
            {
                b_found = VLC_TRUE;
                break;
            }
            subcategory_item = GetNextChild( category_item, cookie );
        }
        if( !b_found )
        {
            subcategory_item = category_item;
Gildas Bazin's avatar
 
Gildas Bazin committed
579 580 581
        }

        /* Add the plugin to the tree */
Gildas Bazin's avatar
 
Gildas Bazin committed
582
        ConfigTreeData *config_data = new ConfigTreeData;
583
        config_data->b_submodule = module_IsSubModule(p_module);
Clément Stenac's avatar
Clément Stenac committed
584
        config_data->i_type = TYPE_MODULE;
585 586 587
        config_data->i_object_id = config_data->b_submodule ?
            ((vlc_object_t *)p_module)->p_parent->i_object_id :
            ((vlc_object_t *)p_module)->i_object_id;
Gildas Bazin's avatar
 
Gildas Bazin committed
588
        config_data->psz_help = NULL;
Clément Stenac's avatar
Clément Stenac committed
589

590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611
        /* WXMSW doesn't know image -1 ... FIXME */
        #ifdef __WXMSW__
        switch( i_subcategory / 100 )
        {
            case CAT_AUDIO:
                i_image = 0; break;
            case CAT_VIDEO:
                i_image = 1; break;
            case CAT_INPUT:
                i_image = 2; break;
            case CAT_SOUT:
                i_image = 3; break;
            case CAT_ADVANCED:
                i_image = 4; break;
            case CAT_PLAYLIST:
                i_image = 5; break;
            case CAT_INTERFACE:
                i_image = 6; break;
        }
        #else
        i_image = -1;
        #endif
612 613
        AppendItem( subcategory_item, wxU( module_GetName(p_module, 0) ),
                    i_image, -1, config_data );
Gildas Bazin's avatar
 
Gildas Bazin committed
614 615 616
    }

    /* Sort all this mess */
617
    wxTreeItemIdValue cookie;
618
    size_t i_child_index;
Clément Stenac's avatar
Clément Stenac committed
619
    wxTreeItemId capability_item = GetFirstChild( root_item, cookie);
Gildas Bazin's avatar
 
Gildas Bazin committed
620
    for( i_child_index = 0;
621
         (capability_item.IsOk() &&
622 623
          //(i_child_index < GetChildrenCount( plugins_item, FALSE )));
          (i_child_index < GetChildrenCount( root_item, FALSE )));
Gildas Bazin's avatar
 
Gildas Bazin committed
624 625 626
         i_child_index++ )
    {
        SortChildren( capability_item );
627 628
        //capability_item = GetNextChild( plugins_item, cookie );
        capability_item = GetNextChild( root_item, cookie );
Gildas Bazin's avatar
 
Gildas Bazin committed
629 630 631 632 633 634 635 636
    }

    /* Clean-up everything */
    vlc_list_release( p_list );

    p_sizer->Add( this, 1, wxEXPAND | wxALL, 0 );
    p_sizer->Layout();

637 638
    p_current = NULL;

Gildas Bazin's avatar
 
Gildas Bazin committed
639
    /* Update Tree Ctrl */
Gildas Bazin's avatar
 
Gildas Bazin committed
640
#ifndef WIN32 /* Workaround a bug in win32 implementation */
Gildas Bazin's avatar
 
Gildas Bazin committed
641
    SelectItem( GetFirstChild( root_item, cookie ) );
Gildas Bazin's avatar
 
Gildas Bazin committed
642
#endif
Gildas Bazin's avatar
 
Gildas Bazin committed
643

644 645
    //cannot expand hidden root item
    //Expand( root_item );
Gildas Bazin's avatar
 
Gildas Bazin committed
646 647
}

648
PrefsTreeCtrl::~PrefsTreeCtrl(){
Gildas Bazin's avatar
 
Gildas Bazin committed
649 650
}

Gildas Bazin's avatar
 
Gildas Bazin committed
651 652
void PrefsTreeCtrl::ApplyChanges()
{
653
    wxTreeItemIdValue cookie, cookie2, cookie3;
Gildas Bazin's avatar
 
Gildas Bazin committed
654 655
    ConfigTreeData *config_data;

Clément Stenac's avatar
Clément Stenac committed
656 657
    wxTreeItemId category = GetFirstChild( root_item, cookie );
    while( category.IsOk() )
Gildas Bazin's avatar
 
Gildas Bazin committed
658
    {
Clément Stenac's avatar
Clément Stenac committed
659 660
        wxTreeItemId subcategory = GetFirstChild( category, cookie2 );
        while( subcategory.IsOk() )
Gildas Bazin's avatar
 
Gildas Bazin committed
661
        {
Clément Stenac's avatar
Clément Stenac committed
662 663 664 665 666 667 668 669 670 671 672
            wxTreeItemId module = GetFirstChild( subcategory, cookie3 );
            while( module.IsOk() )
            {
                config_data = (ConfigTreeData *)GetItemData( module );
                if( config_data && config_data->panel )
                {
                    config_data->panel->ApplyChanges();
                }
                module = GetNextChild( subcategory, cookie3 );
            }
            config_data = (ConfigTreeData *)GetItemData( subcategory );
Gildas Bazin's avatar
 
Gildas Bazin committed
673
            if( config_data && config_data->panel )
Gildas Bazin's avatar
 
Gildas Bazin committed
674 675 676
            {
                config_data->panel->ApplyChanges();
            }
Clément Stenac's avatar
Clément Stenac committed
677
            subcategory = GetNextChild( category, cookie2 );
Gildas Bazin's avatar
 
Gildas Bazin committed
678
        }
Clément Stenac's avatar
Clément Stenac committed
679 680 681 682 683 684
        config_data = (ConfigTreeData *)GetItemData( category );
        if( config_data && config_data->panel )
        {
            config_data->panel->ApplyChanges();
        }
        category = GetNextChild( root_item, cookie );
Gildas Bazin's avatar
 
Gildas Bazin committed
685
    }
Gildas Bazin's avatar
 
Gildas Bazin committed
686 687
}

Gildas Bazin's avatar
 
Gildas Bazin committed
688 689
void PrefsTreeCtrl::CleanChanges()
{
690
    wxTreeItemIdValue cookie, cookie2, cookie3;
Gildas Bazin's avatar
 
Gildas Bazin committed
691 692
    ConfigTreeData *config_data;

Gildas Bazin's avatar
 
Gildas Bazin committed
693 694 695 696 697
    config_data = !GetSelection() ? NULL :
        FindModuleConfig( (ConfigTreeData *)GetItemData( GetSelection() ) );
    if( config_data  )
    {
        config_data->panel->Hide();
Clément Stenac's avatar
Clément Stenac committed
698
#if (wxCHECK_VERSION(2,5,0))
699
        p_sizer->Detach( config_data->panel );
Clément Stenac's avatar
Clément Stenac committed
700 701
#else
        p_sizer->Remove( config_data->panel );
702
#endif
703
        p_current = NULL;
Gildas Bazin's avatar
 
Gildas Bazin committed
704 705
    }

Clément Stenac's avatar
Clément Stenac committed
706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739
    wxTreeItemId category = GetFirstChild( root_item, cookie );
    while( category.IsOk() )
    {
        wxTreeItemId subcategory = GetFirstChild( category, cookie2 );
        while( subcategory.IsOk() )
        {
            wxTreeItemId module = GetFirstChild( subcategory, cookie3 );
            while( module.IsOk() )
            {
                config_data = (ConfigTreeData *)GetItemData( module );
                if( config_data && config_data->panel )
                {
                    delete config_data->panel;
                    config_data->panel = NULL;
                }
                module = GetNextChild( subcategory, cookie3 );
            }
            config_data = (ConfigTreeData *)GetItemData( subcategory );
            if( config_data && config_data->panel )
            {
                delete config_data->panel;
                config_data->panel = NULL;
            }
            subcategory = GetNextChild( category, cookie2 );
        }
        config_data = (ConfigTreeData *)GetItemData( category );
        if( config_data && config_data->panel )
        {
            delete config_data->panel;
            config_data->panel = NULL;
        }
        category = GetNextChild( root_item, cookie );
    }

Gildas Bazin's avatar
 
Gildas Bazin committed
740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756
    if( GetSelection() )
    {
        wxTreeEvent event;
        OnSelectTreeItem( event );
    }
}

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 )
    {
        return config_data;
    }

757
    wxTreeItemIdValue cookie, cookie2, cookie3;
Gildas Bazin's avatar
 
Gildas Bazin committed
758
    ConfigTreeData *config_new;
Clément Stenac's avatar
Clément Stenac committed
759 760
    wxTreeItemId category = GetFirstChild( root_item, cookie );
    while( category.IsOk() )
Gildas Bazin's avatar
 
Gildas Bazin committed
761
    {
Clément Stenac's avatar
Clément Stenac committed
762 763
        wxTreeItemId subcategory = GetFirstChild( category, cookie2 );
        while( subcategory.IsOk() )
Gildas Bazin's avatar
 
Gildas Bazin committed
764
        {
Clément Stenac's avatar
Clément Stenac committed
765 766
            wxTreeItemId module = GetFirstChild( subcategory, cookie3 );
            while( module.IsOk() )
Gildas Bazin's avatar
 
Gildas Bazin committed
767
            {
Clément Stenac's avatar
Clément Stenac committed
768 769 770 771 772 773 774
                config_new = (ConfigTreeData *)GetItemData( module );
                if( config_new && !config_new->b_submodule &&
                    config_new->i_object_id == config_data->i_object_id )
                {
                    return config_new;
                }
                module = GetNextChild( subcategory, cookie3 );
Gildas Bazin's avatar
 
Gildas Bazin committed
775
            }
Clément Stenac's avatar
Clément Stenac committed
776
            subcategory = GetNextChild( category, cookie2 );
Gildas Bazin's avatar
 
Gildas Bazin committed
777
        }
Clément Stenac's avatar
Clément Stenac committed
778
        category = GetNextChild( root_item, cookie );
Gildas Bazin's avatar
 
Gildas Bazin committed
779
    }
Gildas Bazin's avatar
 
Gildas Bazin committed
780 781 782

    /* Found nothing */
    return NULL;
Gildas Bazin's avatar
 
Gildas Bazin committed
783 784
}

Gildas Bazin's avatar
 
Gildas Bazin committed
785 786
void PrefsTreeCtrl::OnSelectTreeItem( wxTreeEvent& event )
{
Gildas Bazin's avatar
 
Gildas Bazin committed
787
    ConfigTreeData *config_data = NULL;
Gildas Bazin's avatar
 
Gildas Bazin committed
788

789
    if( p_current )
Gildas Bazin's avatar
 
Gildas Bazin committed
790
    {
791
        p_current->Hide();
Clément Stenac's avatar
Clément Stenac committed
792
#if (wxCHECK_VERSION(2,5,0))
793
        p_sizer->Detach( p_current  );
Clément Stenac's avatar
Clément Stenac committed
794
#else
795
        p_sizer->Remove( p_current );
796
#endif
797
        p_current = NULL;
Gildas Bazin's avatar
 
Gildas Bazin committed
798 799
    }

Gildas Bazin's avatar
 
Gildas Bazin committed
800
    /* Don't use event.GetItem() because we also send fake events */
Gildas Bazin's avatar
 
Gildas Bazin committed
801 802
    config_data = FindModuleConfig( (ConfigTreeData *)GetItemData(
                                    GetSelection() ) );
Gildas Bazin's avatar
 
Gildas Bazin committed
803
    if( config_data )
Gildas Bazin's avatar
 
Gildas Bazin committed
804
    {
Gildas Bazin's avatar
 
Gildas Bazin committed
805 806 807 808 809
        if( !config_data->panel )
        {
            /* The panel hasn't been created yet. Let's do it. */
            config_data->panel =
                new PrefsPanel( p_parent, p_intf, p_prefs_dialog,
Clément Stenac's avatar
Clément Stenac committed
810
                                config_data );
Gildas Bazin's avatar
 
Gildas Bazin committed
811
            config_data->panel->SwitchAdvanced( b_advanced );
Gildas Bazin's avatar
 
Gildas Bazin committed
812 813 814
        }
        else
        {
Gildas Bazin's avatar
 
Gildas Bazin committed
815
            config_data->panel->SwitchAdvanced( b_advanced );
Gildas Bazin's avatar
 
Gildas Bazin committed
816 817 818
            config_data->panel->Show();
        }

819 820
        p_current = config_data->panel;

821
        p_sizer->Add( config_data->panel, 3, wxEXPAND | wxALL, 0 );
Gildas Bazin's avatar
 
Gildas Bazin committed
822 823 824 825
        p_sizer->Layout();
    }
}

Gildas Bazin's avatar
 
Gildas Bazin committed
826 827 828 829 830 831 832 833 834
void PrefsTreeCtrl::OnAdvanced( wxCommandEvent& event )
{
    b_advanced = event.GetInt();

    ConfigTreeData *config_data = !GetSelection() ? NULL :
        FindModuleConfig( (ConfigTreeData *)GetItemData( GetSelection() ) );
    if( config_data  )
    {
        config_data->panel->Hide();
Clément Stenac's avatar
Clément Stenac committed
835
#if (wxCHECK_VERSION(2,5,0))
836
        p_sizer->Detach( config_data->panel );
Clément Stenac's avatar
Clément Stenac committed
837 838
#else
        p_sizer->Remove( config_data->panel );
839
#endif
840
        p_current = NULL;
Gildas Bazin's avatar
 
Gildas Bazin committed
841 842 843 844 845 846 847 848 849
    }

    if( GetSelection() )
    {
        wxTreeEvent event;
        OnSelectTreeItem( event );
    }
}

Gildas Bazin's avatar
 
Gildas Bazin committed
850 851 852 853
/*****************************************************************************
 * PrefsPanel class definition.
 *****************************************************************************/
PrefsPanel::PrefsPanel( wxWindow* parent, intf_thread_t *_p_intf,
Gildas Bazin's avatar
 
Gildas Bazin committed
854
                        PrefsDialog *_p_prefs_dialog,
Clément Stenac's avatar
Clément Stenac committed
855
                        ConfigTreeData *config_data )
Gildas Bazin's avatar
 
Gildas Bazin committed
856
  :  wxPanel( parent, -1, wxDefaultPosition, wxDefaultSize )
Gildas Bazin's avatar
 
Gildas Bazin committed
857
{
858 859
    module_config_t *p_item, *p_start, *p_end;
    unsigned int i_confsize;
Clément Stenac's avatar
Clément Stenac committed
860
    vlc_list_t *p_list = NULL;;
Gildas Bazin's avatar
 
Gildas Bazin committed
861

Gildas Bazin's avatar
 
Gildas Bazin committed
862
    wxStaticText *label;
863
    wxStaticText *help;
Gildas Bazin's avatar
 
Gildas Bazin committed
864
    wxArrayString array;
Gildas Bazin's avatar
 
Gildas Bazin committed
865

866
    module_t *p_module = NULL;
Sam Hocevar's avatar
Sam Hocevar committed
867

Gildas Bazin's avatar
 
Gildas Bazin committed
868 869
    /* Initializations */
    p_intf = _p_intf;
Gildas Bazin's avatar
 
Gildas Bazin committed
870 871
    p_prefs_dialog =_p_prefs_dialog,

Gildas Bazin's avatar
 
Gildas Bazin committed
872
    b_advanced = VLC_TRUE;
Gildas Bazin's avatar
 
Gildas Bazin committed
873
    SetAutoLayout( TRUE );
874
    Hide();
Gildas Bazin's avatar
 
Gildas Bazin committed
875 876 877

    wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );

878

Clément Stenac's avatar
Clément Stenac committed
879
    if( config_data->i_type == TYPE_CATEGORY )
Gildas Bazin's avatar
 
Gildas Bazin committed
880
    {
Clément Stenac's avatar
Clément Stenac committed
881
        label = new wxStaticText( this, -1,wxU(_( config_data->psz_name )));
882 883 884 885 886 887 888
        wxFont heading_font = label->GetFont();
        heading_font.SetPointSize( heading_font.GetPointSize() + 5 );
        label->SetFont( heading_font );
        sizer->Add( label, 0, wxEXPAND | wxLEFT, 10 );
        sizer->Add( new wxStaticLine( this, 0 ), 0,
                    wxEXPAND | wxLEFT | wxRIGHT, 2 );

Clément Stenac's avatar
Clément Stenac committed
889 890
        hidden_text = NULL;
        help = new wxStaticText( this, -1, wxU(_( config_data->psz_help ) ) );
891 892
        sizer->Add( help ,0 ,wxEXPAND | wxALL, 5 );

Gildas Bazin's avatar
 
Gildas Bazin committed
893 894
        config_sizer = NULL; config_window = NULL;
    }
895
    else
Gildas Bazin's avatar
 
Gildas Bazin committed
896
    {
897
        /* Get a pointer to the module */
Clément Stenac's avatar
Clément Stenac committed
898 899
        if( config_data->i_type == TYPE_MODULE )
        {
900 901
            p_module = (module_t *)
                vlc_object_get( p_intf, config_data->i_object_id );
Clément Stenac's avatar
Clément Stenac committed
902 903 904 905 906 907 908 909 910 911 912 913
        }
        else
        {
            /* List the plugins */
            int i_index;
            vlc_bool_t b_found = VLC_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;
914
                if( !strcmp( module_GetObjName(p_module), "main" ) )
Clément Stenac's avatar
Clément Stenac committed
915 916 917 918 919 920 921
                {
                    b_found = VLC_TRUE;
                    break;
                }
            }
            if( !p_module && !b_found )
            {
922 923
                msg_Warn( p_intf, "unable to create preferences "
                                  "(main module not found)" );
Clément Stenac's avatar
Clément Stenac committed
924 925 926 927
                return;
            }
        }

928 929 930
        /* Enumerate config options and add corresponding config boxes
         * (submodules don't have config options, they are stored in the
         *  parent module) */
931 932
        if( module_IsSubModule(p_module) )
            p_start = module_GetConfig((module_t *)(((vlc_object_t *)p_module)->p_parent), &i_confsize);
Gildas Bazin's avatar
 
Gildas Bazin committed
933
        else
934
            p_start = module_GetConfig(p_module, &i_confsize);
Gildas Bazin's avatar
 
Gildas Bazin committed
935

936 937
        p_item = p_start;
        p_end = p_start + i_confsize;
938

Gildas Bazin's avatar
 
Gildas Bazin committed
939
        /* Find the category if it has been specified */
940 941
        if( config_data->i_type == TYPE_SUBCATEGORY ||
            config_data->i_type == TYPE_CATSUBCAT )
Gildas Bazin's avatar
 
Gildas Bazin committed
942
        {
943
            for( ; p_item && p_item < p_end; p_item++ )
Gildas Bazin's avatar
 
Gildas Bazin committed
944
            {
Clément Stenac's avatar
Clément Stenac committed
945
                if( p_item->i_type == CONFIG_SUBCATEGORY &&
Clément Stenac's avatar
 
Clément Stenac committed
946
                    ( config_data->i_type == TYPE_SUBCATEGORY &&
947
                      p_item->value.i == config_data->i_object_id ) ||
Clément Stenac's avatar
 
Clément Stenac committed
948
                    ( config_data->i_type == TYPE_CATSUBCAT &&
949
                      p_item->value.i == config_data->i_subcat_id ) )
Clément Stenac's avatar
Clément Stenac committed
950 951 952
                {
                    break;
                }
953
            }
Gildas Bazin's avatar
 
Gildas Bazin committed
954 955 956
        }

        /* Add a head title to the panel */
957
        const char *psz_head;
958 959
        if( config_data->i_type == TYPE_SUBCATEGORY ||
            config_data->i_type == TYPE_CATSUBCAT )
Clément Stenac's avatar
Clément Stenac committed
960 961 962 963 964 965
        {
            psz_head = config_data->psz_name;
            p_item++;
        }
        else
        {
966
            psz_head = module_GetLongName(p_module);
Clément Stenac's avatar
Clément Stenac committed
967 968
        }

Gildas Bazin's avatar
 
Gildas Bazin committed
969
        label = new wxStaticText( this, -1,
Clément Stenac's avatar
Clément Stenac committed
970
                      wxU(_( psz_head ? psz_head : _("Unknown") ) ) );
971 972 973 974
        wxFont heading_font = label->GetFont();
        heading_font.SetPointSize( heading_font.GetPointSize() + 5 );
        label->SetFont( heading_font );
        sizer->Add( label, 0, wxEXPAND | wxLEFT, 10 );
975
        sizer->Add( new wxStaticLine( this, 0 ), 0,
976
                    wxEXPAND | wxLEFT | wxRIGHT, 2 );
Gildas Bazin's avatar
 
Gildas Bazin committed
977 978 979 980

        /* Now put all the config options into a scrolled window */
        config_sizer = new wxBoxSizer( wxVERTICAL );
        config_window = new wxScrolledWindow( this, -1, wxDefaultPosition,
981
            wxDefaultSize, wxBORDER_NONE | wxHSCROLL | wxVSCROLL );
Gildas Bazin's avatar
 
Gildas Bazin committed
982 983
        config_window->SetAutoLayout( TRUE );
        config_window->SetScrollRate( 5, 5 );
984

985
        for( ; p_item && p_item < p_end; p_item++ )
Gildas Bazin's avatar
 
Gildas Bazin committed
986
        {
987
            /* If a category has been specified, check we finished the job */
Clément Stenac's avatar
 
Clément Stenac committed
988
            if( ( ( config_data->i_type == TYPE_SUBCATEGORY &&
989
                    p_item->value.i != config_data->i_object_id ) ||
Clément Stenac's avatar
 
Clément Stenac committed
990
                  ( config_data->i_type == TYPE_CATSUBCAT  &&
991
                    p_item->value.i != config_data->i_subcat_id ) ) &&
Clément Stenac's avatar
Clément Stenac committed
992
                (p_item->i_type == CONFIG_CATEGORY ||
Clément Stenac's avatar
 
Clément Stenac committed
993
                  p_item->i_type == CONFIG_SUBCATEGORY ) )
Gildas Bazin's avatar
 
Gildas Bazin committed
994
                break;
995

996 997
            if( p_item->b_internal == VLC_TRUE ) continue;

998 999 1000
            ConfigControl *control =
                CreateConfigControl( VLC_OBJECT(p_intf),
                                     p_item, config_window );
Gildas Bazin's avatar
 
Gildas Bazin committed
1001

1002
            /* Don't add items that were not recognized */
1003
            if( control == NULL ) continue;
Gildas Bazin's avatar
 
Gildas Bazin committed
1004

1005
            /* Add the config data to our array so we can keep a trace of it */
1006
            config_array.Add( control );
1007

1008
            config_sizer->Add( control, 0, wxEXPAND | wxALL, 2 );
Gildas Bazin's avatar
 
Gildas Bazin committed
1009
        }
Clément Stenac's avatar
Clément Stenac committed
1010

1011
        module_PutConfig( p_start );
Gildas Bazin's avatar
 
Gildas Bazin committed
1012

1013 1014 1015
        config_sizer->Layout();
        config_window->SetSizer( config_sizer );
        sizer->Add( config_window, 1, wxEXPAND | wxALL, 5 );
Clément Stenac's avatar
Clément Stenac committed
1016 1017 1018 1019
        hidden_text = new wxStaticText( this, -1,
                        wxU( _( "Some options are available but hidden. " \
                                "Check \"Advanced options\" to see them." ) ) );
        sizer->Add( hidden_text );
1020

1021
        /* And at last put a useful help string if available */
Clément Stenac's avatar
Clément Stenac committed
1022
        if( config_data->psz_help && *config_data->psz_help )
1023 1024 1025
        {
            sizer->Add( new wxStaticLine( this, 0 ), 0,
                        wxEXPAND | wxLEFT | wxRIGHT, 2 );
Clément Stenac's avatar
Clément Stenac committed
1026
            help = new wxStaticText( this, -1, wxU(_(config_data->psz_help)),
1027 1028 1029 1030 1031 1032
                                     wxDefaultPosition, wxDefaultSize,
                                     wxALIGN_LEFT,
                                     wxT("") );
            sizer->Add( help ,0 ,wxEXPAND | wxALL, 5 );
        }

Clément Stenac's avatar
Clément Stenac committed
1033 1034
        if( config_data->i_type == TYPE_MODULE )
        {
1035
            module_Put( p_module );
Clément Stenac's avatar
Clément Stenac committed
1036 1037 1038 1039 1040
        }
        else
        {
            vlc_list_release( p_list );
        }