]> git.sesse.net Git - vlc/blob - modules/gui/wxwidgets/dialogs/open.cpp
fa08588b4e69accad5570a67a2d06a6086fb6d8b
[vlc] / modules / gui / wxwidgets / dialogs / open.cpp
1 /*****************************************************************************
2  * open.cpp : Open dialog box
3  *****************************************************************************
4  * Copyright (C) 2000-2005 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Gildas Bazin <gbazin@videolan.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include "dialogs/open.hpp"
28 #include "dialogs/streamout.hpp"
29 #include "dialogs/preferences_widgets.h"
30 #include "dialogs/subtitles.hpp"
31
32 #include "charset.h"
33
34 //#undef HAVE_LIBCDIO // Disable-cruft
35
36 #ifdef HAVE_LIBCDIO
37 #include <cdio/cdio.h>
38 #include <cdio/cd_types.h>
39 #include <cdio/logging.h>
40 #endif /* HAVE_LIBCDIO */
41
42 #ifdef HAVE_VCDINFO
43 #include <libvcd/version.h>
44 /* There was a bug in libvcdinfo <= 23 which prevented C++ compilation */
45 #if LIBVCD_VERSION_NUM > 23
46 #include <libvcd/info.h>
47 #endif /* LIBVCD_VERSION_NUM > 23 */
48 #endif /* HAVE_VCDINFO */
49
50 #include <wx/combobox.h>
51 #include <wx/statline.h>
52 #include <wx/tokenzr.h>
53
54 #include <vector>
55
56
57 #ifndef wxRB_SINGLE
58 #   define wxRB_SINGLE 0
59 #endif
60
61 #define SELECTION_DISC_TYPE_DVD_MENUS 0
62 #define SELECTION_DISC_TYPE_DVD       1
63 #define SELECTION_DISC_TYPE_VCD       2
64 #define SELECTION_DISC_TYPE_CDDA      3
65
66 /*****************************************************************************
67  * Event Table.
68  *****************************************************************************/
69
70 /* IDs for the controls and the menu commands */
71 enum
72 {
73     Notebook_Event = wxID_HIGHEST,
74     MRL_Event,
75
76     FileBrowse_Event,
77     SubFileBrowse_Event,
78     FileName_Event,
79     SubFileName_Event,
80
81     DiscType_Event,
82 #ifdef HAVE_LIBCDIO
83     DiscProbe_Event,
84 #endif
85     DiscDevice_Event,
86     DiscTitle_Event,
87     DiscChapter_Event,
88     DiscSub_Event,
89     DiscAudio_Event,
90
91     NetType_Event,
92     NetRadio1_Event, NetRadio2_Event, NetRadio3_Event, NetRadio4_Event,
93     NetPort1_Event, NetPort2_Event, NetPort3_Event,
94     NetAddr1_Event, NetAddr2_Event, NetAddr3_Event, NetAddr4_Event,
95     NetForceIPv6_Event, NetTimeshift_Event,
96
97     SubsFileEnable_Event,
98     SubsFileSettings_Event,
99
100     SoutEnable_Event,
101     SoutSettings_Event,
102
103     CachingEnable_Event,
104     CachingChange_Event,
105
106     AdvancedOptions_Event
107 };
108
109 BEGIN_EVENT_TABLE(OpenDialog, wxDialog)
110     /* Button events */
111     EVT_BUTTON(wxID_OK, OpenDialog::OnOk)
112     EVT_BUTTON(wxID_CANCEL, OpenDialog::OnCancel)
113
114     EVT_NOTEBOOK_PAGE_CHANGED(Notebook_Event, OpenDialog::OnPageChange)
115
116     EVT_TEXT(MRL_Event, OpenDialog::OnMRLChange)
117
118     /* Events generated by the file panel */
119     EVT_TEXT(FileName_Event, OpenDialog::OnFilePanelChange)
120     EVT_BUTTON(FileBrowse_Event, OpenDialog::OnFileBrowse)
121     EVT_TEXT(SubFileName_Event, OpenDialog::OnSubFileChange)
122     EVT_BUTTON(SubFileBrowse_Event, OpenDialog::OnSubFileBrowse)
123
124     /* Events generated by the disc panel */
125     EVT_RADIOBOX(DiscType_Event, OpenDialog::OnDiscTypeChange)
126 #ifdef HAVE_LIBCDIO
127     EVT_CHECKBOX(DiscProbe_Event, OpenDialog::OnDiscProbe)
128 #endif
129     EVT_TEXT(DiscDevice_Event, OpenDialog::OnDiscDeviceChange)
130     EVT_TEXT(DiscDevice_Event, OpenDialog::OnDiscPanelChange)
131     EVT_TEXT(DiscTitle_Event, OpenDialog::OnDiscPanelChange)
132     EVT_SPINCTRL(DiscTitle_Event, OpenDialog::OnDiscPanelChangeSpin)
133     EVT_TEXT(DiscChapter_Event, OpenDialog::OnDiscPanelChange)
134     EVT_SPINCTRL(DiscChapter_Event, OpenDialog::OnDiscPanelChangeSpin)
135     EVT_TEXT(DiscSub_Event, OpenDialog::OnDiscPanelChange)
136     EVT_TEXT(DiscAudio_Event, OpenDialog::OnDiscPanelChange)
137     EVT_SPINCTRL(DiscSub_Event, OpenDialog::OnDiscPanelChangeSpin)
138
139     /* Events generated by the net panel */
140     EVT_RADIOBUTTON(NetRadio1_Event, OpenDialog::OnNetTypeChange)
141     EVT_RADIOBUTTON(NetRadio2_Event, OpenDialog::OnNetTypeChange)
142     EVT_RADIOBUTTON(NetRadio3_Event, OpenDialog::OnNetTypeChange)
143     EVT_RADIOBUTTON(NetRadio4_Event, OpenDialog::OnNetTypeChange)
144     EVT_TEXT(NetPort1_Event, OpenDialog::OnNetPanelChange)
145     EVT_SPINCTRL(NetPort1_Event, OpenDialog::OnNetPanelChangeSpin)
146     EVT_TEXT(NetPort2_Event, OpenDialog::OnNetPanelChange)
147     EVT_SPINCTRL(NetPort2_Event, OpenDialog::OnNetPanelChangeSpin)
148     EVT_TEXT(NetPort3_Event, OpenDialog::OnNetPanelChange)
149     EVT_SPINCTRL(NetPort3_Event, OpenDialog::OnNetPanelChangeSpin)
150     EVT_TEXT(NetAddr2_Event, OpenDialog::OnNetPanelChange)
151     EVT_TEXT(NetAddr3_Event, OpenDialog::OnNetPanelChange)
152     EVT_TEXT(NetAddr4_Event, OpenDialog::OnNetPanelChange)
153     EVT_CHECKBOX(NetForceIPv6_Event, OpenDialog::OnNetPanelChange)
154     EVT_CHECKBOX(NetTimeshift_Event, OpenDialog::OnNetPanelChange)
155
156     /* Events generated by the subtitle file buttons */
157     EVT_CHECKBOX(SubsFileEnable_Event, OpenDialog::OnSubsFileEnable)
158     EVT_BUTTON(SubsFileSettings_Event, OpenDialog::OnSubsFileSettings)
159
160     /* Events generated by the stream output buttons */
161     EVT_CHECKBOX(SoutEnable_Event, OpenDialog::OnSoutEnable)
162     EVT_BUTTON(SoutSettings_Event, OpenDialog::OnSoutSettings)
163
164     /* Events generated by the caching button */
165     EVT_CHECKBOX(CachingEnable_Event, OpenDialog::OnCachingEnable)
166     EVT_TEXT(CachingChange_Event, OpenDialog::OnCachingChange)
167     EVT_SPINCTRL(CachingChange_Event, OpenDialog::OnCachingChangeSpin)
168
169     /* Hide the window when the user closes the window */
170     EVT_CLOSE(OpenDialog::OnClose)
171
172 END_EVENT_TABLE()
173
174
175 /*****************************************************************************
176  * AutoBuiltPanel.
177  *****************************************************************************/
178 WX_DEFINE_ARRAY(ConfigControl *, ArrayOfConfigControls);
179
180 class AutoBuiltPanel : public wxPanel
181 {
182 public:
183
184     AutoBuiltPanel() { }
185     AutoBuiltPanel( wxWindow *, OpenDialog *, intf_thread_t *,
186                     const module_t * );
187
188     virtual ~AutoBuiltPanel() {}
189
190     void UpdateAdvancedMRL();
191
192     wxString name;
193     ArrayOfConfigControls config_array;
194     ArrayOfConfigControls advanced_config_array;
195     wxComboBox *p_advanced_mrl_combo;
196
197 private:
198     intf_thread_t *p_intf;
199     OpenDialog *p_open_dialog;
200
201     void OnAdvanced( wxCommandEvent& event );
202     wxDialog *p_advanced_dialog;
203
204     DECLARE_EVENT_TABLE();
205 };
206
207 BEGIN_EVENT_TABLE(AutoBuiltPanel, wxPanel)
208     EVT_BUTTON(AdvancedOptions_Event, AutoBuiltPanel::OnAdvanced)
209 END_EVENT_TABLE()
210
211 static void AutoBuildCallback( void *p_data )
212 {
213     ((OpenDialog *)p_data)->UpdateMRL();
214 }
215
216 static void AutoBuildAdvancedCallback( void *p_data )
217 {
218     ((AutoBuiltPanel *)p_data)->UpdateAdvancedMRL();
219 }
220
221 AutoBuiltPanel::AutoBuiltPanel( wxWindow *parent, OpenDialog *dialog,
222                                 intf_thread_t *_p_intf,
223                                 const module_t *p_module )
224   : wxPanel( parent, -1, wxDefaultPosition, wxDefaultSize ),
225     name( wxU(p_module->psz_object_name) ),
226     p_advanced_mrl_combo( NULL ),
227     p_intf( _p_intf ), p_open_dialog( dialog ), p_advanced_dialog( NULL )
228 {
229     wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
230     module_config_t *p_item = p_module->p_config;
231     bool b_advanced = false;
232
233     if( p_item ) do
234     {
235         if( !(p_item->i_type & CONFIG_HINT) && p_item->b_advanced )
236             b_advanced = true;
237
238         if( p_item->i_type & CONFIG_HINT || p_item->b_advanced )
239             continue;
240
241         ConfigControl *control =
242             CreateConfigControl( VLC_OBJECT(p_intf), p_item, this );
243
244         config_array.Add( control );
245
246         /* Don't add items that were not recognized */
247         if( control == NULL ) continue;
248
249         control->SetUpdateCallback( AutoBuildCallback, (void *)dialog );
250
251         sizer->Add( control, 0, wxEXPAND | wxALL, 2 );
252     }
253     while( p_item->i_type != CONFIG_HINT_END && p_item++ );
254
255     if( b_advanced )
256     {
257         wxButton *button =
258             new wxButton( this, AdvancedOptions_Event,
259                           wxU(_("Advanced options...")) );
260         sizer->Add( button, 0, wxALL, 5 );
261
262         /* Build the advanced dialog */
263         p_advanced_dialog =
264             new wxDialog( this, -1, ((wxString)wxU(_("Advanced options"))) +
265                           wxT(" (") + wxU( p_module->psz_longname ) + wxT(")"),
266                           wxDefaultPosition, wxDefaultSize,
267                           wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER );
268
269         wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
270
271         /* Create MRL combobox */
272         wxBoxSizer *mrl_sizer_sizer = new wxBoxSizer( wxHORIZONTAL );
273         wxStaticBox *mrl_box =
274             new wxStaticBox( p_advanced_dialog, -1,
275                              wxU(_("Advanced options")) );
276         wxStaticBoxSizer *mrl_sizer =
277             new wxStaticBoxSizer( mrl_box, wxHORIZONTAL );
278         wxStaticText *mrl_label =
279             new wxStaticText( p_advanced_dialog, -1, wxU(_("Options:")) );
280         p_advanced_mrl_combo =
281             new wxComboBox( p_advanced_dialog, MRL_Event, wxT(""),
282                             wxDefaultPosition, wxDefaultSize );
283         mrl_sizer->Add( mrl_label, 0, wxALL | wxALIGN_CENTER, 5 );
284         mrl_sizer->Add( p_advanced_mrl_combo, 1, wxALL | wxALIGN_CENTER, 5 );
285         mrl_sizer_sizer->Add( mrl_sizer, 1, wxEXPAND | wxALL, 5 );
286         sizer->Add( mrl_sizer_sizer, 0, wxEXPAND | wxALL, 2 );
287
288         /* Add advanced options to panel */
289         module_config_t *p_item = p_module->p_config;
290         if( p_item ) do
291         {
292             if( p_item->i_type & CONFIG_HINT || !p_item->b_advanced )
293                 continue;
294
295             ConfigControl *control =
296                 CreateConfigControl( VLC_OBJECT(p_intf), p_item,
297                                      p_advanced_dialog );
298
299             advanced_config_array.Add( control );
300
301             /* Don't add items that were not recognized */
302             if( control == NULL ) continue;
303
304             control->SetUpdateCallback( AutoBuildAdvancedCallback,
305                                         (void *)this );
306
307             sizer->Add( control, 0, wxEXPAND | wxALL, 2 );
308         }
309         while( p_item->i_type != CONFIG_HINT_END && p_item++ );
310
311         /* Separation */
312         wxPanel *dummy_panel = new wxPanel( p_advanced_dialog, -1 );
313         sizer->Add( dummy_panel, 1 );
314         wxStaticLine *static_line =
315             new wxStaticLine( p_advanced_dialog, wxID_OK );
316         sizer->Add( static_line, 0, wxEXPAND | wxALL, 5 );
317
318         /* Create buttons */
319         wxButton *ok_button =
320             new wxButton( p_advanced_dialog, wxID_OK, wxU(_("OK")) );
321         ok_button->SetDefault();
322         wxButton *cancel_button =
323             new wxButton( p_advanced_dialog, wxID_CANCEL, wxU(_("Cancel")) );
324         wxBoxSizer *button_sizer = new wxBoxSizer( wxHORIZONTAL );
325         button_sizer->Add( ok_button, 0, wxALL, 5 );
326         button_sizer->Add( cancel_button, 0, wxALL, 5 );
327         button_sizer->Layout();
328         sizer->Add( button_sizer, 0, wxALL, 0 );
329
330         sizer->SetMinSize( 400, -1 );
331         p_advanced_dialog->SetSizerAndFit( sizer );
332     }
333
334     this->SetSizerAndFit( sizer );
335 }
336
337 void AutoBuiltPanel::OnAdvanced( wxCommandEvent& event )
338 {
339     if( p_advanced_dialog->ShowModal() == wxID_OK )
340     {
341         UpdateAdvancedMRL();
342         p_open_dialog->UpdateMRL();
343     }
344 }
345
346 void AutoBuiltPanel::UpdateAdvancedMRL()
347 {
348     wxString mrltemp;
349
350     for( int i = 0; i < (int)advanced_config_array.GetCount(); i++ )
351     {
352         ConfigControl *control = advanced_config_array.Item(i);
353
354         mrltemp += (i ? wxT(" :") : wxT(":"));
355
356         if( control->GetType() == CONFIG_ITEM_BOOL &&
357             !control->GetIntValue() ) mrltemp += wxT("no-");
358
359         mrltemp += control->GetName();
360
361         switch( control->GetType() )
362         {
363         case CONFIG_ITEM_STRING:
364         case CONFIG_ITEM_FILE:
365         case CONFIG_ITEM_DIRECTORY:
366         case CONFIG_ITEM_MODULE:
367             mrltemp += wxT("=\"") + control->GetPszValue() + wxT("\"");
368             break;
369         case CONFIG_ITEM_INTEGER:
370             mrltemp +=
371                 wxString::Format( wxT("=%i"), control->GetIntValue() );
372             break;
373         case CONFIG_ITEM_FLOAT:
374             mrltemp +=
375                 wxString::Format(wxT("=%f"), control->GetFloatValue());
376             break;
377         }
378     }
379
380     p_advanced_mrl_combo->SetValue( mrltemp );
381 }
382
383 /*****************************************************************************
384  * Constructor.
385  *****************************************************************************/
386 OpenDialog::OpenDialog( intf_thread_t *_p_intf, wxWindow *_p_parent,
387                         int i_access_method, int i_arg ):
388       wxDialog( _p_parent, -1, wxU(_("Open...")), wxDefaultPosition,
389              wxDefaultSize, wxDEFAULT_FRAME_STYLE )
390 {
391     OpenDialog( _p_intf, _p_parent, i_access_method, i_arg, OPEN_NORMAL );
392 }
393
394 OpenDialog::OpenDialog( intf_thread_t *_p_intf, wxWindow *_p_parent,
395                         int i_access_method, int i_arg, int _i_method ):
396       wxDialog( _p_parent, -1, wxU(_("Open...")), wxDefaultPosition,
397              wxDefaultSize, wxDEFAULT_FRAME_STYLE )
398 {
399     /* Initializations */
400     i_method = _i_method;
401     p_intf = _p_intf;
402     p_parent = _p_parent;
403     SetIcon( *p_intf->p_sys->p_icon );
404     file_dialog = NULL;
405     i_disc_type_selection = 0;
406     i_disc_title = 0;
407     i_open_arg = i_arg;
408
409     sout_dialog = NULL;
410     subsfile_dialog = NULL;
411     b_disc_device_changed = false;
412
413     /* Create a panel to put everything in */
414     wxPanel *panel = new wxPanel( this, -1 );
415     panel->SetAutoLayout( TRUE );
416
417
418     /* Advanced options */
419     wxStaticBox *adv_box = new wxStaticBox( panel, -1,
420                                wxU(_("Advanced options")) );
421     wxStaticBoxSizer *adv_sizer = new wxStaticBoxSizer( adv_box,
422                                                         wxVERTICAL );
423
424
425     wxFlexGridSizer *common_opt_sizer = new wxFlexGridSizer( 5, 1, 20 );
426     if( i_method == OPEN_NORMAL )
427     {
428         /* Create Stream Output checkox */
429         sout_checkbox = new wxCheckBox( panel, SoutEnable_Event,
430                                          wxU(_("Stream/Save")) );
431         sout_checkbox->SetToolTip( wxU(_("Use VLC as a server of streams")) );
432         common_opt_sizer->Add( sout_checkbox, 0,
433                                wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
434
435         sout_button = new wxButton( panel, SoutSettings_Event,
436                                     wxU(_("Settings...")) );
437         sout_button->Disable();
438
439         char *psz_sout = config_GetPsz( p_intf, "sout" );
440         if( psz_sout && *psz_sout )
441         {
442             sout_checkbox->SetValue(TRUE);
443             sout_button->Enable();
444             subsfile_mrl.Add( wxString(wxT("sout=")) + wxL2U(psz_sout) );
445         }
446         if( psz_sout ) free( psz_sout );
447
448         common_opt_sizer->Add( sout_button, 1, wxALIGN_LEFT |
449                                wxALIGN_CENTER_VERTICAL );
450
451         common_opt_sizer->Add( new wxPanel( this, -1 ), 1,
452                                wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
453     }
454
455     /* Create caching options */
456     caching_checkbox = new wxCheckBox( panel, CachingEnable_Event,
457                                        wxU(_("Caching")) );
458     caching_checkbox->SetToolTip( wxU(_("Change the default caching value "
459                                         "(in milliseconds)")) );
460     common_opt_sizer->Add( caching_checkbox, 0,
461                            wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
462     caching_value = new wxSpinCtrl( panel, CachingChange_Event );
463     caching_value->SetRange( 0, 1000000 );
464     caching_value->Disable();
465     common_opt_sizer->Add( caching_value, 0,
466                            wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
467
468
469     wxBoxSizer *mrl_sizer = new wxBoxSizer( wxHORIZONTAL );
470     wxStaticText *mrl_label = new wxStaticText( panel, -1,
471                                                 wxU(_("Customize:")) );
472     mrl_combo = new wxComboBox( panel, MRL_Event, wxT(""),
473                                 wxDefaultPosition, wxDefaultSize );
474     //Point(20,25), wxSize(120, -1) );
475     mrl_combo->SetToolTip( wxU(_("You can use this field directly by typing "
476         "the full MRL you want to open.\n""Alternatively, the field will be "
477         "filled automatically when you use the controls above.")) );
478
479     mrl_sizer->Add( mrl_label, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
480     mrl_sizer->Add( mrl_combo, 1, wxALL | wxEXPAND | wxALIGN_CENTER_VERTICAL,
481                     5 );
482
483     adv_sizer->Add( common_opt_sizer, 0, wxTOP | wxLEFT|wxRIGHT | wxEXPAND, 5 );
484     adv_sizer->Add( mrl_sizer, 0, wxBOTTOM  | wxLEFT|wxRIGHT  | wxEXPAND, 5 );
485
486     /* Separation */
487     wxStaticLine *static_line = new wxStaticLine( panel, wxID_OK );
488
489     /* Create the buttons */
490     wxButton *ok_button = new wxButton( panel, wxID_OK, wxU(_("OK")) );
491     ok_button->SetDefault();
492     wxButton *cancel_button = new wxButton( panel, wxID_CANCEL,
493                                             wxU(_("Cancel")) );
494
495     /* Create notebook */
496     notebook = new wxNotebook( panel, Notebook_Event );
497
498 #if (!wxCHECK_VERSION(2,5,2))
499     wxNotebookSizer *notebook_sizer = new wxNotebookSizer( notebook );
500 #endif
501
502     notebook->AddPage( FilePanel( notebook ), wxU(_("File")),
503                        i_access_method == FILE_ACCESS );
504     notebook->AddPage( DiscPanel( notebook ), wxU(_("Disc")),
505                        i_access_method == DISC_ACCESS );
506     notebook->AddPage( NetPanel( notebook ), wxU(_("Network")),
507                        i_access_method == NET_ACCESS );
508
509     module_t *p_module = config_FindModule( VLC_OBJECT(p_intf), "v4l" );
510     if( p_module )
511     {
512         AutoBuiltPanel *autopanel =
513             new AutoBuiltPanel( notebook, this, p_intf, p_module );
514         input_tab_array.Add( autopanel );
515         notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
516                         p_module->psz_shortname : p_module->psz_object_name ),
517                            i_access_method == CAPTURE_ACCESS );
518     }
519
520     p_module = config_FindModule( VLC_OBJECT(p_intf), "pvr" );
521     if( p_module )
522     {
523         AutoBuiltPanel *autopanel =
524             new AutoBuiltPanel( notebook, this, p_intf, p_module );
525         input_tab_array.Add( autopanel );
526         notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
527                         p_module->psz_shortname : p_module->psz_object_name ),
528                            i_access_method == CAPTURE_ACCESS );
529     }
530
531     p_module = config_FindModule( VLC_OBJECT(p_intf), "dvb" );
532     if( p_module )
533     {
534         AutoBuiltPanel *autopanel =
535             new AutoBuiltPanel( notebook, this, p_intf, p_module );
536         input_tab_array.Add( autopanel );
537         notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
538                         p_module->psz_shortname : p_module->psz_object_name ),
539                            i_access_method == CAPTURE_ACCESS );
540     }
541
542     p_module = config_FindModule( VLC_OBJECT(p_intf), "dshow" );
543     if( p_module )
544     {
545         AutoBuiltPanel *autopanel =
546             new AutoBuiltPanel( notebook, this, p_intf, p_module );
547         input_tab_array.Add( autopanel );
548         notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
549                         p_module->psz_shortname : p_module->psz_object_name ),
550                            i_access_method == CAPTURE_ACCESS );
551     }
552
553     /* Update Disc panel */
554     wxCommandEvent dummy_event;
555     OnDiscTypeChange( dummy_event );
556
557     /* Update Net panel */
558     dummy_event.SetId( NetRadio1_Event );
559     OnNetTypeChange( dummy_event );
560
561     /* Update MRL */
562     wxNotebookEvent event( wxEVT_NULL, 0, i_access_method );
563     OnPageChange( event );
564
565     /* Place everything in sizers */
566     wxBoxSizer *button_sizer = new wxBoxSizer( wxHORIZONTAL );
567     button_sizer->Add( ok_button, 0, wxALL, 5 );
568     button_sizer->Add( cancel_button, 0, wxALL, 5 );
569     button_sizer->Layout();
570     wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL );
571     wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
572 #if (!wxCHECK_VERSION(2,5,2))
573     panel_sizer->Add( notebook_sizer, 1, wxEXPAND | wxALL, 5 );
574 #else
575     panel_sizer->Add( notebook, 1, wxEXPAND | wxALL, 5 );
576 #endif
577     panel_sizer->Add( adv_sizer, 0, wxEXPAND | wxALL, 5 );
578     panel_sizer->Add( static_line, 0, wxEXPAND | wxALL, 5 );
579     panel_sizer->Add( button_sizer, 0, wxALIGN_LEFT | wxALL, 5 );
580     panel_sizer->Layout();
581     panel->SetSizerAndFit( panel_sizer );
582     main_sizer->Add( panel, 1, wxGROW, 0 );
583     main_sizer->Layout();
584     SetSizerAndFit( main_sizer );
585 }
586
587 OpenDialog::~OpenDialog()
588 {
589     /* Clean up */
590     if( file_dialog ) delete file_dialog;
591     if( sout_dialog ) delete sout_dialog;
592     if( subsfile_dialog ) delete subsfile_dialog;
593 }
594
595 int OpenDialog::Show( int i_access_method, int i_arg )
596 {
597     notebook->SetSelection( i_access_method );
598     int i_ret = wxDialog::Show();
599     Raise();
600     SetFocus();
601     i_open_arg = i_arg;
602     return i_ret;
603 }
604
605 int OpenDialog::Show()
606 {
607     int i_ret = wxDialog::Show();
608     Raise();
609     SetFocus();
610     return i_ret;
611 }
612
613 /*****************************************************************************
614  * Private methods.
615  *****************************************************************************/
616 wxPanel *OpenDialog::FilePanel( wxWindow* parent )
617 {
618     wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
619                                   wxSize(200, 200) );
620
621     wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
622
623     /* Create browse file line */
624     wxBoxSizer *file_sizer = new wxBoxSizer( wxHORIZONTAL );
625
626     file_sizer->Add( new wxStaticText( panel, -1, wxU(_("Open:") ) ), 0,
627                      wxALL | wxALIGN_CENTER_VERTICAL, 5 );
628
629     file_combo = new wxComboBox( panel, FileName_Event, wxT("") );
630     wxButton *browse_button = new wxButton( panel, FileBrowse_Event,
631                                             wxU(_("Browse...")) );
632     file_sizer->Add( file_combo, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
633     file_sizer->Add( browse_button, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
634
635     /* Create Subtitles File checkox - button  */
636     wxFlexGridSizer *subtitles_sizer = new wxFlexGridSizer( 2, 1, 20 );
637     subsfile_checkbox = new wxCheckBox( panel, SubsFileEnable_Event,
638                                         wxU(_("Use a subtitles file")) );
639     subsfile_checkbox->SetToolTip( wxU(_("Use an external subtitles file.")) );
640     subtitles_sizer->Add( subsfile_checkbox, 0,  wxALIGN_CENTER_VERTICAL |
641                           wxALL, 5 );
642     subsfile_button = new wxButton( panel, SubsFileSettings_Event,
643                                     wxU(_("Advanced Settings...")) );
644     subsfile_button->Disable();
645     subtitles_sizer->Add( subsfile_button, 1, wxALIGN_CENTER_VERTICAL |
646                            wxALL, 5 );
647
648     /* Create subtitles file line */
649     wxBoxSizer *subfile_sizer = new wxBoxSizer( wxHORIZONTAL );
650
651     char *psz_subsfile = config_GetPsz( p_intf, "sub-file" );
652     if( psz_subsfile && *psz_subsfile )
653     {
654         subsfile_checkbox->SetValue(TRUE);
655         subsfile_button->Enable();
656         subsfile_mrl.Add( wxString(wxT("sub-file=")) + wxL2U(psz_subsfile) );
657     }
658     if( !psz_subsfile )  psz_subsfile = strdup("");
659     subfile_sizer->Add( new wxStaticText( panel, -1, wxU(_("File:") ) ),
660                         0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
661     subfile_combo = new wxComboBox( panel, SubFileName_Event,
662                                     wxL2U( psz_subsfile ) );
663     if( psz_subsfile ) free( psz_subsfile );
664     subbrowse_button = new wxButton( panel, SubFileBrowse_Event,
665                                      wxU(_("Browse...")) );
666     subfile_sizer->Add( subfile_combo, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
667     subfile_sizer->Add( subbrowse_button, 0, wxALL |wxALIGN_CENTER_VERTICAL, 5 );
668
669     subfile_combo->Disable();
670     subbrowse_button->Disable();
671
672     psz_subsfile = config_GetPsz( p_intf, "sub-file" );
673     if( psz_subsfile && *psz_subsfile )
674     {
675         subfile_combo->Enable();
676         subbrowse_button->Enable();
677     }
678
679     sizer->Add( file_sizer, 0, wxEXPAND | wxALL, 5 );
680     sizer->Add( subtitles_sizer, 0, wxLEFT | wxRIGHT | wxTOP, 5 );
681     sizer->Add( subfile_sizer, 0, wxEXPAND | wxLEFT | wxRIGHT| wxBOTTOM, 5 );
682     panel->SetSizerAndFit( sizer );
683     return panel;
684 }
685
686 wxPanel *OpenDialog::DiscPanel( wxWindow* parent )
687 {
688     wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
689                                   wxSize(200, 200) );
690
691     wxBoxSizer *sizer_row = new wxBoxSizer( wxVERTICAL );
692     wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 3, 20 );
693
694     static const wxString disc_type_array[] =
695     {
696         wxU(_("DVD (menus)")),
697         wxU(_("DVD")),
698         wxU(_("VCD")),
699         wxU(_("Audio CD")),
700     };
701
702     disc_type = new wxRadioBox( panel, DiscType_Event, wxU(_("Disc type")),
703                                 wxDefaultPosition, wxDefaultSize,
704                                 WXSIZEOF(disc_type_array), disc_type_array,
705                                 WXSIZEOF(disc_type_array), wxRA_SPECIFY_COLS );
706
707 #ifdef HAVE_LIBCDIO
708     disc_probe = new wxCheckBox( panel, DiscProbe_Event,
709                                  wxU(_("Probe Disc(s)")) );
710     disc_probe->SetToolTip( wxU(_("Probe for a DVD, VCD or audio CD. "
711 "First try the Device name entered for the selected Disc type "
712 "(DVD, DVD Menu, VCD, audio CD). If that doesn't find media, try any device "
713 "for the Disc type.  If that doesn't work, then try looking for CD-ROMs or "
714 "DVD drives. The Disc type, Device name, and some parameter ranges are set "
715 "based on media we find.")) );
716 #endif
717
718     sizer_row->Add( disc_type, i_disc_type_selection, wxEXPAND | wxALL, 5 );
719 #ifdef HAVE_LIBCDIO
720     sizer_row->Add( disc_probe, 0, wxEXPAND | wxALL );
721 #endif
722
723     wxStaticText *label = new wxStaticText( panel, -1, wxU(_("Device name")) );
724     disc_device = new wxTextCtrl( panel, DiscDevice_Event, wxT(""),
725                                   wxDefaultPosition, wxDefaultSize,
726                                   wxTE_PROCESS_ENTER);
727
728 #ifdef WIN32
729     char psz_default_device[3] = {0};
730
731     /* find the drive_name for the first cdrom drive,
732      * which is probably "D:" and put the drive_name into
733      * psz_default_device... */
734     for( char drive_letter = 'A'; drive_letter <= 'Z'; ++drive_letter )
735     {
736         char drive_name[3] = {drive_letter, ':', 0};
737         UINT type = GetDriveTypeA( drive_name );
738         if( type == DRIVE_CDROM )
739         {
740             psz_default_device[0] = drive_letter;
741             psz_default_device[1] = ':';
742             break;
743         }
744     }
745
746
747     if( strlen(psz_default_device) > 0 )
748     {
749         if(disc_device)
750             disc_device->SetValue( wxL2U(psz_default_device) );
751     }
752 #endif
753
754     sizer->Add( label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
755     sizer->Add( disc_device, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
756
757     disc_title_label = new wxStaticText( panel, -1, wxU(_("Title")) );
758     disc_title = new wxSpinCtrl( panel, DiscTitle_Event );
759     sizer->Add( disc_title_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
760     sizer->Add( disc_title, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
761
762     disc_chapter_label = new wxStaticText( panel, -1, wxU(_("Chapter")) );
763     disc_chapter = new wxSpinCtrl( panel, DiscChapter_Event );
764     sizer->Add( disc_chapter_label, 0,
765                 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
766     sizer->Add( disc_chapter, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
767
768     disc_sub_label = new wxStaticText( panel, -1, wxU(_("Subtitles track")) );
769     disc_sub = new wxSpinCtrl( panel, DiscSub_Event );
770     sizer->Add( disc_sub_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
771     sizer->Add( disc_sub, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
772     disc_sub->SetRange( -1, 255 );
773     i_disc_sub = config_GetInt( p_intf, "sub-track" );
774     disc_sub->SetValue( i_disc_sub );
775
776     disc_audio_label = new wxStaticText( panel, -1, wxU(_("Audio track")) );
777     disc_audio = new wxSpinCtrl( panel, DiscAudio_Event );
778     sizer->Add( disc_audio_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
779     sizer->Add( disc_audio, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
780     disc_audio->SetRange( -1, 255 );
781     i_disc_audio = config_GetInt( p_intf, "audio-track" );
782     disc_audio->SetValue( i_disc_audio );
783
784     sizer_row->Add( sizer, 0, wxEXPAND | wxALL, 5 );
785
786     panel->SetSizerAndFit( sizer_row );
787     return panel;
788 }
789
790 wxPanel *OpenDialog::NetPanel( wxWindow* parent )
791 {
792     int i;
793     wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
794                                   wxSize(200, 200) );
795
796     wxBoxSizer *sizer_row = new wxBoxSizer( wxVERTICAL );
797     wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 4, 20 );
798
799     static const wxString net_type_array[] =
800     {
801         wxU(_("UDP/RTP")),
802         wxU(_("UDP/RTP Multicast")),
803         wxU(_("HTTP/HTTPS/FTP/MMS")),
804         wxU(_("RTSP"))
805     };
806
807     for( i=0; i<4; i++ )
808     {
809         net_radios[i] = new wxRadioButton( panel, NetRadio1_Event + i,
810                                            net_type_array[i],
811                                            wxDefaultPosition, wxDefaultSize,
812                                            wxRB_SINGLE );
813
814         net_subpanels[i] = new wxPanel( panel, -1,
815                                         wxDefaultPosition, wxDefaultSize );
816     }
817
818     /* Timeshift */
819     net_timeshift  = new wxCheckBox( panel, NetTimeshift_Event,
820                                      wxU(_("Allow timeshifting")) );
821
822     /* UDP/RTP row */
823     wxFlexGridSizer *subpanel_sizer;
824     wxStaticText *label;
825     i_net_ports[0] = config_GetInt( p_intf, "server-port" );
826     subpanel_sizer = new wxFlexGridSizer( 3, 1, 20 );
827     label = new wxStaticText( net_subpanels[0], -1, wxU(_("Port")) );
828     net_ports[0] = new wxSpinCtrl( net_subpanels[0], NetPort1_Event,
829                                    wxString::Format(wxT("%d"), i_net_ports[0]),
830                                    wxDefaultPosition, wxDefaultSize,
831                                    wxSP_ARROW_KEYS,
832                                    0, 65535, i_net_ports[0] );
833
834     subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
835     subpanel_sizer->Add( net_ports[0], 1,
836                          wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
837     net_ipv6 = new wxCheckBox( net_subpanels[0], NetForceIPv6_Event,
838                                wxU(_("Force IPv6")));
839     subpanel_sizer->Add( net_ipv6, 0,
840                          wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
841     net_subpanels[0]->SetSizerAndFit( subpanel_sizer );
842     net_radios[0]->SetValue( TRUE );
843
844     /* UDP/RTP Multicast row */
845     subpanel_sizer = new wxFlexGridSizer( 4, 1, 20 );
846     label = new wxStaticText( net_subpanels[1], -1, wxU(_("Address")) );
847     net_addrs[1] = new wxTextCtrl( net_subpanels[1], NetAddr2_Event, wxT(""),
848                                    wxDefaultPosition, wxDefaultSize,
849                                    wxTE_PROCESS_ENTER);
850     subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
851     subpanel_sizer->Add( net_addrs[1], 1,
852                          wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
853
854     label = new wxStaticText( net_subpanels[1], -1, wxU(_("Port")) );
855     i_net_ports[1] = i_net_ports[0];
856     net_ports[1] = new wxSpinCtrl( net_subpanels[1], NetPort2_Event,
857                                    wxString::Format(wxT("%d"), i_net_ports[1]),
858                                    wxDefaultPosition, wxDefaultSize,
859                                    wxSP_ARROW_KEYS,
860                                    0, 65535, i_net_ports[1] );
861
862     subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
863     subpanel_sizer->Add( net_ports[1], 1,
864                          wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
865     net_subpanels[1]->SetSizerAndFit( subpanel_sizer );
866
867     /* HTTP and RTSP rows */
868     for( i=2; i<4; i++ )
869     {
870         subpanel_sizer = new wxFlexGridSizer( 2, 1, 20 );
871         label = new wxStaticText( net_subpanels[i], -1, wxU(_("URL")) );
872         net_addrs[i] = new wxTextCtrl( net_subpanels[i], NetAddr1_Event + i,
873                                        (i == 2) ? wxT("") : wxT("rtsp://"),
874                                        wxDefaultPosition, wxSize( 200, -1 ),
875                                        wxTE_PROCESS_ENTER);
876         subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
877         subpanel_sizer->Add( net_addrs[i], 1,
878                              wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
879         net_subpanels[i]->SetSizerAndFit( subpanel_sizer );
880     }
881
882     /* Stuff everything into the main panel */
883     for( i=0; i<4; i++ )
884     {
885         sizer->Add( net_radios[i], 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
886                     wxALL, 5 );
887         sizer->Add( net_subpanels[i], 1, wxEXPAND | wxALIGN_LEFT |
888                     wxALIGN_CENTER_VERTICAL | wxALL, 5  );
889     }
890     sizer->Add( net_timeshift, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
891                 wxALL, 5 );
892
893     sizer_row->Add( sizer, 0, wxEXPAND | wxALL, 5 );
894
895     panel->SetSizerAndFit( sizer_row );
896     return panel;
897 }
898
899 void OpenDialog::UpdateMRL()
900 {
901     UpdateMRL( i_current_access_method );
902 }
903
904 void OpenDialog::UpdateMRL( int i_access_method )
905 {
906     wxString mrltemp, caching_name;
907
908     i_current_access_method = i_access_method;
909
910     switch( i_access_method )
911     {
912     case FILE_ACCESS:
913         mrltemp = file_combo->GetValue();
914         caching_name = wxT("file-caching");
915         break;
916
917     case DISC_ACCESS:
918         i_disc_type_selection = disc_type->GetSelection();
919
920         switch ( i_disc_type_selection )
921         {
922         case 0: /* DVD with menus */
923         case 1: /* DVD without menus */
924             disc_device->SetToolTip( wxU(_("Name of DVD device "
925             "to read from.")) );
926             if( i_disc_type_selection == 0 )
927             {
928                 mrltemp = wxT("dvd://") + disc_device->GetValue();
929                 caching_name = wxT("dvdnav-caching");
930             }
931             else
932             {
933                 mrltemp = wxT("dvdsimple://") + disc_device->GetValue();
934                 caching_name = wxT("dvdread-caching");
935             }
936
937             if( i_disc_title > 0 )
938             {
939                 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
940
941                 if( i_disc_chapter > 0 )
942                     mrltemp += wxString::Format( wxT(":%d"), i_disc_chapter );
943             }
944
945             if( i_disc_sub >= 0 )
946                 mrltemp += wxString::Format( wxT("  :sub-track=%d"),
947                                              i_disc_sub );
948             if( i_disc_audio >= 0 )
949                 mrltemp += wxString::Format( wxT("  :audio-track=%d"),
950                                              i_disc_audio );
951             break;
952
953         case 2:  /* VCD of some sort */
954 #ifdef HAVE_VCDX
955             disc_device->SetToolTip( wxU(_("Name of CD-ROM device "
956             "to read Video CD from. If this field is left empty, we will scan "
957             "for a CD-ROM with a VCD in it.")) );
958             mrltemp = wxT("vcdx://") + disc_device->GetValue();
959             if( i_disc_title > 0 )
960                 mrltemp += wxString::Format( wxT("@%c%d"),
961                                   config_GetInt( p_intf, "vcdx-PBC"  )
962                                   ? 'P' : 'E', i_disc_title );
963 #else
964             disc_device->SetToolTip( wxU(_("Name of CD-ROM device "
965             "to read Video CD from.")) );
966             mrltemp = wxT("vcd://") + disc_device->GetValue();
967             if( i_disc_title > 0 )
968                 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
969 #endif
970
971             if( i_disc_sub >= 0 )
972                 mrltemp += wxString::Format( wxT("  :sub-track=%d"),
973                                              i_disc_sub );
974
975             if( i_disc_audio >= 0 )
976                 mrltemp += wxString::Format( wxT("  :audio-track=%d"),
977                                              i_disc_audio );
978             caching_name = wxT("vcd-caching");
979             break;
980
981         case 3: /* CD-DA */
982 #ifdef HAVE_CDDAX
983             disc_device->SetToolTip( wxU(_("Name of CD-ROM device "
984             "to read audio CD from. If this field is left empty, we will scan "
985             "for a CD-ROM with an audio CD in it." )) );
986             mrltemp = wxT("cddax://")
987 #else
988             disc_device->SetToolTip( wxU(_("Name of CD-ROM device "
989             "to read audio CD from." )) );
990             mrltemp = wxT("cdda://")
991 #endif
992               + disc_device->GetValue();
993             if( i_disc_title > 0 )
994                 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
995
996             caching_name = wxT("cdda-caching");
997             break;
998
999         default:
1000             msg_Err( p_intf, "invalid selection (%d)",
1001                      disc_type->GetSelection() );
1002         }
1003
1004         break;
1005
1006     case NET_ACCESS:
1007         switch( i_net_type )
1008         {
1009         case 0:
1010             mrltemp = wxT("udp://@");
1011             if ( net_ipv6->GetValue() )
1012             {
1013                 mrltemp += wxT("[::]");
1014             }
1015             if( i_net_ports[0] !=
1016                 config_GetInt( p_intf, "server-port" ) )
1017             {
1018                 mrltemp += wxString::Format( wxT(":%d"), i_net_ports[0] );
1019             }
1020
1021             caching_name = wxT("udp-caching");
1022             break;
1023
1024         case 1:
1025             mrltemp = wxT("udp://@");
1026             if ((net_addrs[1]->GetLineText(0).Find (':') != -1)
1027                 && (net_addrs[1]->GetLineText(0)[0u] != '['))
1028             {
1029                 /* automatically adds '[' and ']' to IPv6 addresses */
1030                 mrltemp += wxT("[") + net_addrs[1]->GetLineText(0)
1031                          + wxT("]");
1032             }
1033             else
1034             {
1035                 mrltemp += net_addrs[1]->GetLineText(0);
1036             }
1037             if( i_net_ports[1] != config_GetInt( p_intf, "server-port" ) )
1038             {
1039                 mrltemp += wxString::Format( wxT(":%d"), i_net_ports[1] );
1040             }
1041
1042             caching_name = wxT("udp-caching");
1043             break;
1044
1045         case 2:
1046             /* http access */
1047             if( net_addrs[2]->GetLineText(0).Find(wxT("://")) == -1 )
1048                 mrltemp = wxT("http://");
1049
1050             mrltemp += net_addrs[2]->GetLineText(0);
1051
1052             caching_name = wxT("http-caching");
1053             break;
1054
1055         case 3:
1056             /* RTSP access */
1057             if( net_addrs[3]->GetLineText(0).Find(wxT("rtsp://")) != 0 )
1058             {
1059                 mrltemp = wxT("rtsp://");
1060             }
1061             mrltemp += net_addrs[3]->GetLineText(0);
1062
1063             caching_name = wxT("rtsp-caching");
1064             break;
1065         }
1066         if( net_timeshift->IsEnabled() && net_timeshift->IsChecked() )
1067             mrltemp += wxT(" :access-filter=timeshift");
1068         break;
1069
1070     default:
1071         {
1072             int i_item = i_access_method - MAX_ACCESS;
1073
1074             if( i_item < 0 || i_item >= (int)input_tab_array.GetCount() )
1075                 break;
1076
1077             AutoBuiltPanel *input_panel = input_tab_array.Item( i_item );
1078
1079             mrltemp = input_panel->name + wxT("://");
1080
1081             for( int i=0; i < (int)input_panel->config_array.GetCount(); i++ )
1082             {
1083                 ConfigControl *control = input_panel->config_array.Item(i);
1084
1085                 mrltemp += wxT(" :");
1086
1087                 if( control->GetType() == CONFIG_ITEM_BOOL &&
1088                     !control->GetIntValue() ) mrltemp += wxT("no-");
1089
1090                 mrltemp += control->GetName();
1091
1092                 switch( control->GetType() )
1093                 {
1094                 case CONFIG_ITEM_STRING:
1095                 case CONFIG_ITEM_FILE:
1096                 case CONFIG_ITEM_DIRECTORY:
1097                 case CONFIG_ITEM_MODULE:
1098                     mrltemp += wxT("=\"") + control->GetPszValue() + wxT("\"");
1099                     break;
1100                 case CONFIG_ITEM_INTEGER:
1101                     mrltemp +=
1102                         wxString::Format( wxT("=%i"), control->GetIntValue() );
1103                     break;
1104                 case CONFIG_ITEM_FLOAT:
1105                     mrltemp +=
1106                         wxString::Format(wxT("=%f"), control->GetFloatValue());
1107                     break;
1108                 }
1109             }
1110
1111             if( input_panel->p_advanced_mrl_combo &&
1112                 input_panel->p_advanced_mrl_combo->GetValue() )
1113             {
1114                 mrltemp += wxT(" ") +
1115                     input_panel->p_advanced_mrl_combo->GetValue();
1116             }
1117         }
1118         break;
1119     }
1120
1121     if( caching_name.size() )
1122     {
1123         if( caching_value->IsEnabled() )
1124         {
1125             mrltemp += wxT("  :") + caching_name +
1126                 wxString::Format( wxT("=%d"), i_caching );
1127         }
1128         else
1129         {
1130             int i_value = config_GetInt( p_intf, caching_name.mb_str() );
1131             caching_value->SetValue( i_value );
1132         }
1133     }
1134
1135     mrl_combo->SetValue( mrltemp );
1136 }
1137
1138 /*****************************************************************************
1139  * Events methods.
1140  *****************************************************************************/
1141 void OpenDialog::OnOk( wxCommandEvent& WXUNUSED(event) )
1142 {
1143     mrl = SeparateEntries( mrl_combo->GetValue() );
1144     mrl_combo->Append( mrl_combo->GetValue() );
1145     if( mrl_combo->GetCount() > 10 ) mrl_combo->Delete( 0 );
1146     mrl_combo->SetSelection( mrl_combo->GetCount() - 1 );
1147
1148     if( i_method == OPEN_STREAM )
1149     {
1150         if( IsModal() ) EndModal( wxID_OK );
1151         Hide();
1152         return;
1153     }
1154
1155     /* Update the playlist */
1156     playlist_t *p_playlist =
1157         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
1158                                        FIND_ANYWHERE );
1159     if( p_playlist == NULL ) return;
1160
1161     for( int i = 0; i < (int)mrl.GetCount(); i++ )
1162     {
1163         vlc_bool_t b_start = !i && i_open_arg;
1164         playlist_item_t *p_item;
1165         char *psz_utf8;
1166
1167         psz_utf8 = wxFromLocale( mrl[i] );
1168         p_item = playlist_ItemNew( p_intf, psz_utf8, psz_utf8 );
1169         wxLocaleFree( psz_utf8 );
1170
1171         /* Insert options */
1172         while( i + 1 < (int)mrl.GetCount() &&
1173                ((const char *)mrl[i + 1].mb_str())[0] == ':' )
1174         {
1175             psz_utf8 = wxFromLocale( mrl[i + 1] );
1176             playlist_ItemAddOption( p_item, psz_utf8 );
1177             wxLocaleFree( psz_utf8 );
1178             i++;
1179         }
1180
1181         /* Get the options from the subtitles dialog */
1182         if( subsfile_checkbox->IsChecked() && subsfile_mrl.GetCount() )
1183         {
1184             for( int j = 0; j < (int)subsfile_mrl.GetCount(); j++ )
1185             {
1186                 psz_utf8 = wxFromLocale( subsfile_mrl[j] );
1187                 playlist_ItemAddOption( p_item, psz_utf8 );
1188                 wxLocaleFree( psz_utf8 );
1189             }
1190         }
1191
1192         /* Get the options from the stream output dialog */
1193         if( sout_checkbox->IsChecked() && sout_mrl.GetCount() )
1194         {
1195             for( int j = 0; j < (int)sout_mrl.GetCount(); j++ )
1196             {
1197                 psz_utf8 = wxFromLocale( sout_mrl[j] );
1198                 playlist_ItemAddOption( p_item, psz_utf8 );
1199                 wxLocaleFree( psz_utf8 );
1200             }
1201         }
1202
1203
1204         if( b_start )
1205         {
1206             playlist_AddItem( p_playlist, p_item,
1207                               PLAYLIST_APPEND,
1208                               PLAYLIST_END );
1209             playlist_Control( p_playlist, PLAYLIST_ITEMPLAY, p_item );
1210         }
1211         else
1212         {
1213             playlist_AddItem( p_playlist, p_item,
1214                               PLAYLIST_APPEND|PLAYLIST_PREPARSE,
1215                               PLAYLIST_END );
1216         }
1217     }
1218
1219     vlc_object_release( p_playlist );
1220
1221     Hide();
1222
1223     if( IsModal() ) EndModal( wxID_OK );
1224 }
1225
1226 void OpenDialog::OnCancel( wxCommandEvent& WXUNUSED(event) )
1227 {
1228     wxCloseEvent cevent;
1229     OnClose(cevent);
1230 }
1231
1232 void OpenDialog::OnClose( wxCloseEvent& WXUNUSED(event) )
1233 {
1234     Hide();
1235
1236     if( IsModal() ) EndModal( wxID_CANCEL );
1237 }
1238
1239 void OpenDialog::OnPageChange( wxNotebookEvent& event )
1240 {
1241     UpdateMRL( event.GetSelection() );
1242 }
1243
1244 void OpenDialog::OnMRLChange( wxCommandEvent& event )
1245 {
1246     //mrl = SeparateEntries( event.GetString() );
1247 }
1248
1249 /*****************************************************************************
1250  * File panel event methods.
1251  *****************************************************************************/
1252 void OpenDialog::OnFilePanelChange( wxCommandEvent& WXUNUSED(event) )
1253 {
1254     UpdateMRL( FILE_ACCESS );
1255 }
1256
1257 void OpenDialog::OnFileBrowse( wxCommandEvent& WXUNUSED(event) )
1258 {
1259     if( file_dialog == NULL )
1260         file_dialog = new wxFileDialog( this, wxU(_("Open File")),
1261             wxT(""), wxT(""), wxT("*"), wxOPEN | wxMULTIPLE );
1262
1263     if( file_dialog && file_dialog->ShowModal() == wxID_OK )
1264     {
1265         wxArrayString paths;
1266         wxString path;
1267
1268         file_dialog->GetPaths( paths );
1269
1270         for( size_t i = 0; i < paths.GetCount(); i++ )
1271         {
1272             if( paths[i].Find( wxT(' ') ) >= 0 )
1273                 path += wxT("\"") + paths[i] + wxT("\" ");
1274             else
1275                 path += paths[i] + wxT(" ");
1276         }
1277
1278         file_combo->SetValue( path );
1279         file_combo->Append( path );
1280         if( file_combo->GetCount() > 10 ) file_combo->Delete( 0 );
1281         UpdateMRL( FILE_ACCESS );
1282     }
1283 }
1284
1285 void OpenDialog::OnSubFileBrowse( wxCommandEvent& WXUNUSED(event) )
1286 {
1287     wxFileDialog dialog( this, wxU(_("Open subtitles file")),
1288                          wxT(""), wxT(""), wxT("*"), wxOPEN );
1289
1290     if( dialog.ShowModal() == wxID_OK )
1291     {
1292         subfile_combo->SetValue( dialog.GetPath() );
1293     }
1294     wxCommandEvent event; OnSubFileChange( event );
1295 }
1296
1297 void OpenDialog::OnSubFileChange( wxCommandEvent& WXUNUSED(event) )
1298 {
1299     if( subsfile_mrl.GetCount() != 0 )
1300     {
1301         subsfile_mrl.RemoveAt( 0 );
1302         subsfile_mrl.Insert( wxString(wxT("sub-file=")) + subfile_combo->GetValue() , 0 );
1303     }
1304     else
1305     {
1306         subsfile_mrl.Add( wxString(wxT("sub-file=")) + subfile_combo->GetValue() );
1307     }
1308 }
1309
1310 /*****************************************************************************
1311  * Disc panel event methods.
1312  *****************************************************************************/
1313 void OpenDialog::OnDiscPanelChangeSpin( wxSpinEvent& event )
1314 {
1315     wxCommandEvent cevent;
1316     cevent.SetId(event.GetId());
1317     cevent.SetInt(event.GetPosition());
1318     OnDiscPanelChange(cevent);
1319 }
1320
1321 void OpenDialog::OnDiscPanelChange( wxCommandEvent& event )
1322 {
1323     if( event.GetId() == DiscTitle_Event ) i_disc_title = event.GetInt();
1324     if( event.GetId() == DiscChapter_Event ) i_disc_chapter = event.GetInt();
1325     if( event.GetId() == DiscSub_Event ) i_disc_sub = event.GetInt();
1326     if( event.GetId() == DiscAudio_Event ) i_disc_audio = event.GetInt();
1327
1328     UpdateMRL( DISC_ACCESS );
1329 }
1330
1331 void OpenDialog::OnDiscDeviceChange( wxCommandEvent& event )
1332 {
1333     char *psz_device;
1334
1335     switch( disc_type->GetSelection() )
1336     {
1337         case 3:
1338             psz_device = config_GetPsz( p_intf, "cd-audio" );
1339             break;
1340
1341         case 2:
1342             psz_device = config_GetPsz( p_intf, "vcd" );
1343             break;
1344
1345         default:
1346             psz_device = config_GetPsz( p_intf, "dvd" );
1347             break;
1348     }
1349
1350     if ( !psz_device ) psz_device = "";
1351
1352     if( disc_device->GetValue().Cmp( wxL2U( psz_device ) ) )
1353     {
1354         b_disc_device_changed = true;
1355     }
1356
1357     UpdateMRL( DISC_ACCESS );
1358 }
1359
1360 #ifdef HAVE_LIBCDIO
1361
1362 /* Return true if *psz_drive is a drive with a DVD in it. A more complete
1363    check would see if the media looks like a *playable* DVD. This should
1364    go into libcdio.
1365  */
1366 static bool IsDVD(const char *psz_drive)
1367 {
1368   CdIo_t *p_cdio = cdio_open (psz_drive, DRIVER_UNKNOWN);
1369   if (p_cdio)
1370   {
1371       discmode_t discmode = cdio_get_discmode(p_cdio);
1372       cdio_destroy(p_cdio);
1373       return cdio_is_discmode_dvd(discmode);
1374   }
1375   return false;
1376 }
1377
1378
1379 /* Return a device that has a DVD in it. The caller needs to free
1380    the returned string.
1381 */
1382 static char * ProbeDVD(const wxChar *device)
1383 {
1384         /*
1385   char **ppsz_cd_drives;
1386   const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1387   char *psz_device = (char *) tmp_buf;
1388
1389   if( IsDVD(psz_device) )
1390   {
1391       return strdup(psz_device);
1392   }
1393
1394   ppsz_cd_drives = cdio_get_devices(DRIVER_DEVICE);
1395   if( ppsz_cd_drives )
1396   {
1397       char **c;
1398       for( c = ppsz_cd_drives; *c != NULL; c++ )
1399       {
1400       if( IsDVD(*c) )
1401       {
1402           char *psz_drive = strdup(*c);
1403           cdio_free_device_list(ppsz_cd_drives);
1404           return strdup(psz_drive);
1405           }
1406       }
1407       cdio_free_device_list(ppsz_cd_drives);
1408   }*/
1409   return NULL;
1410 }
1411
1412
1413 static char * ProbeDevice(char **ppsz_search_devices, cdio_fs_anal_t mask,
1414               bool b_any)
1415 {
1416     char **ppsz_devices;
1417
1418     if( ppsz_search_devices && !ppsz_search_devices[0] )
1419         ppsz_search_devices = NULL;
1420
1421     /* Start out trying the device that has been entered so far. */
1422     ppsz_devices = cdio_get_devices_with_cap(ppsz_search_devices, mask,
1423                          b_any);
1424
1425     if (ppsz_devices && *ppsz_devices)
1426     {
1427         char *psz_device = strdup(*ppsz_devices);
1428         cdio_free_device_list(ppsz_devices);
1429         return psz_device;
1430     }
1431
1432     /* If there was no device specified on the first try, then give up
1433        now. Otherwise accept any CD-ROM in the class (e.g. VCD or DVD).
1434     */
1435     if( !ppsz_search_devices ) return NULL;
1436
1437     ppsz_devices = cdio_get_devices_with_cap(NULL, mask, true);
1438
1439     if (ppsz_devices && *ppsz_devices)
1440     {
1441         char *psz_device = strdup(*ppsz_devices);
1442         cdio_free_device_list(ppsz_devices);
1443         return psz_device;
1444     }
1445
1446     return NULL;
1447 }
1448
1449
1450 /* Return a device that has a CD-DA in it. The caller needs to free
1451    the returned string.
1452 */
1453 static char * ProbeCDDA(const wxChar *device)
1454 {
1455         /*
1456    char *ppsz_device[2];
1457    const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1458    char *psz_device = (char *) tmp_buf;
1459    ppsz_device[0] = (device && *device) ? psz_device : NULL;
1460    ppsz_device[1] = NULL;
1461    return ProbeDevice(ppsz_device, CDIO_FS_AUDIO, false);
1462    */ return NULL;
1463 }
1464
1465 /* Return a device that has a VCD in it. The caller needs to free
1466    the returned string.
1467 */
1468 static char * ProbeVCD(const wxChar *device)
1469 {/*
1470    char *ppsz_device[2];
1471    const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1472    char *psz_device = (char *) tmp_buf;
1473    ppsz_device[0] = (device && *device) ? psz_device : NULL;
1474    ppsz_device[1] = NULL;
1475    return ProbeDevice(ppsz_device,
1476                       (CDIO_FS_ANAL_SVCD|CDIO_FS_ANAL_CVD|CDIO_FS_ANAL_VIDEOCD
1477                        |CDIO_FS_UNKNOWN), true);
1478                        */ return NULL;
1479 }
1480
1481
1482 /*
1483    Probe (find anywhere) a CD-DA, VCD, or a DVD.
1484    First try the device name that may have been entered for the "disc type"
1485    selected. If that doesn't work we try any device for the disc type.
1486    If that doesn't work, try looking for CD-ROMs or DVD drives. the
1487    disc type, device name and paramter ranges are set to whatever we find.
1488 */
1489 void OpenDialog::OnDiscProbe( wxCommandEvent& WXUNUSED(event) )
1490 {
1491     wxCommandEvent dummy_event;
1492     char *psz_device = NULL;
1493     bool b_probed_DVD = false;
1494     bool b_probed_VCD = false;
1495     const int i_selection = disc_type->GetSelection();
1496
1497     /* Reduce verbosity of cdio errors. */
1498     cdio_loglevel_default = CDIO_LOG_ERROR;
1499
1500  retry:
1501     switch( disc_type->GetSelection() )
1502     {
1503
1504     case SELECTION_DISC_TYPE_DVD_MENUS:
1505     case SELECTION_DISC_TYPE_DVD:
1506       /* If not a DVD then try for a VCD. If VCD fails it will
1507          try for a CD-DA. */
1508       if (!psz_device) psz_device = ProbeDVD(disc_device->GetValue());
1509       if (!psz_device)
1510       {
1511           b_probed_DVD = true;
1512           disc_type->SetSelection(SELECTION_DISC_TYPE_VCD);
1513           OnDiscTypeChange( dummy_event );
1514           goto retry;
1515       }
1516       disc_device->SetValue( wxL2U(psz_device) );
1517       break;
1518
1519     case SELECTION_DISC_TYPE_VCD:  /* VCD probe of some sort */
1520       if(!psz_device) psz_device = ProbeVCD(disc_device->GetValue());
1521       if( psz_device  )
1522       {
1523 #ifdef HAVE_VCDX
1524 #if LIBVCD_VERSION_NUM > 23
1525       vcdinfo_obj_t *p_vcdinfo;
1526
1527           /* Set LID or entry range accurately if possible. */
1528       if( vcdinfo_open(&p_vcdinfo, &psz_device, DRIVER_DEVICE,
1529                 NULL) == VCDINFO_OPEN_VCD)
1530       {
1531           if (config_GetInt( p_intf, "vcdx-PBC"  ))
1532           {
1533           /* Set largest LID. */;
1534           disc_title->SetRange( 0, vcdinfo_get_num_LIDs(p_vcdinfo) );
1535
1536           }
1537           else
1538           {
1539           /* Set largest Entry */
1540           disc_title->SetRange( 0,
1541                     vcdinfo_get_num_entries(p_vcdinfo)-1 );
1542           }
1543           vcdinfo_close(p_vcdinfo);
1544       }
1545 #endif /* LIBVCD_VERSION_NUM > 23 */
1546           disc_device->SetValue( wxL2U(psz_device) );
1547 #else
1548           CdIo_t *p_cdio = cdio_open (psz_device, DRIVER_UNKNOWN);
1549           disc_device->SetValue( wxL2U(psz_device) );
1550
1551           /* Set track range accurately if possible. */
1552           if (p_cdio)
1553           {
1554               track_t i_last_track = cdio_get_last_track_num(p_cdio);
1555               disc_title->SetRange( 0, i_last_track-1 );
1556           }
1557           cdio_destroy(p_cdio);
1558 #endif
1559           break;
1560       }
1561
1562       b_probed_VCD = true;
1563
1564       /* Not a VCD. Try for a DVD unless we've been there before. */
1565       if( !b_probed_DVD && (psz_device = ProbeDVD(disc_device->GetValue())) )
1566       {
1567           disc_type->SetSelection(SELECTION_DISC_TYPE_DVD_MENUS);
1568           OnDiscTypeChange( dummy_event );
1569           goto retry;
1570       }
1571       b_probed_DVD = true;
1572
1573       /* Couldn't find a VCD or DVD. See if we can find a CD-DA. */
1574       psz_device = ProbeCDDA(disc_device->GetValue());
1575       if( psz_device  )
1576       {
1577           disc_type->SetSelection(SELECTION_DISC_TYPE_CDDA);
1578           OnDiscTypeChange( dummy_event );
1579           goto retry;
1580       }
1581
1582       /* Couldn't find a VCD, DVD or CD-DA. Null out the Device name and
1583      set to original selection.
1584        */
1585       disc_device->SetValue( wxL2U("") );
1586       disc_type->SetSelection(i_selection);
1587       OnDiscTypeChange( dummy_event );
1588       break;
1589
1590     case SELECTION_DISC_TYPE_CDDA:
1591       if(!psz_device) psz_device = ProbeCDDA(disc_device->GetValue());
1592       if( psz_device  )
1593       {
1594           CdIo_t *p_cdio = cdio_open (psz_device, DRIVER_UNKNOWN);
1595           disc_device->SetValue( wxL2U(psz_device) );
1596           if (p_cdio)
1597           {
1598               track_t i_last_track = cdio_get_last_track_num(p_cdio);
1599               disc_title->SetRange( 0, i_last_track );
1600 #if 0
1601           MediaInsertCDDA( p_intf,  p_cdio, i_last_track );
1602 #endif
1603           }
1604           cdio_destroy(p_cdio);
1605           break;
1606       }
1607
1608       /* Not a CD-DA. Try for a DVD unless we've been there before. */
1609       if( !b_probed_DVD && (psz_device = ProbeDVD(disc_device->GetValue())) )
1610       {
1611           disc_type->SetSelection(SELECTION_DISC_TYPE_DVD_MENUS);
1612           OnDiscTypeChange( dummy_event );
1613           goto retry;
1614       }
1615
1616       /* Couldn't find a CD-DA or DVD. See if we can find a VCD, unless
1617          we've tried that before. */
1618       if (!b_probed_VCD) psz_device = ProbeVCD(disc_device->GetValue());
1619       if( psz_device  )
1620       {
1621           disc_type->SetSelection(SELECTION_DISC_TYPE_VCD);
1622           OnDiscTypeChange( dummy_event );
1623           goto retry;
1624       }
1625       disc_device->SetValue( wxL2U("") );
1626       break;
1627
1628     default:
1629         msg_Err( p_intf, "invalid Disc type selection (%d)",
1630                  disc_type->GetSelection() );
1631         break;
1632     }
1633
1634     free(psz_device);
1635     disc_probe->SetValue(FALSE);
1636
1637     UpdateMRL( DISC_ACCESS );
1638 }
1639 #endif /* HAVE_LIBCDIO */
1640
1641 void OpenDialog::OnDiscTypeChange( wxCommandEvent& WXUNUSED(event) )
1642 {
1643     char *psz_device = NULL;
1644
1645     switch( disc_type->GetSelection() )
1646     {
1647
1648     case SELECTION_DISC_TYPE_DVD_MENUS:
1649     case SELECTION_DISC_TYPE_DVD:
1650         disc_sub->Enable(); disc_sub_label->Enable();
1651         disc_audio->Enable(); disc_audio_label->Enable();
1652         disc_chapter->Enable(); disc_chapter_label->Enable();
1653         disc_title_label->SetLabel ( wxU(_("Title")) );
1654         psz_device = config_GetPsz( p_intf, "dvd" );
1655         if( !b_disc_device_changed )
1656         {
1657             if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1658             else disc_device->SetValue( wxT("") );
1659         }
1660         disc_title->SetRange( 0, 255 );
1661         disc_sub->SetRange( -1, 31 );  // up to 32 subtitles -1: no subtitle
1662         disc_audio->SetRange( 0, 7 );  // up to 8 audio channels
1663         disc_chapter->SetRange( 0, 255 );
1664         disc_title->SetToolTip( wxU(_("Title number.")) );
1665         disc_sub->SetToolTip( wxU(_(
1666           "DVD's can have up to 32 subtitles numbered 0..31. "
1667           "Note this is not the same thing as a subtitle name e.g. 'en'. "
1668           "If a value -1 is used, no subtitle will be shown." )) );
1669         disc_audio->SetToolTip( wxU(_("Audio track number. "
1670           "DVD's can have up to 8 audio tracks numbered 0..7."
1671         )) );
1672         break;
1673
1674     case SELECTION_DISC_TYPE_VCD:
1675         disc_sub->Enable(); disc_sub_label->Enable();
1676         disc_audio->Enable(); disc_audio_label->Enable();
1677         disc_chapter->Disable(); disc_chapter_label->Disable();
1678         psz_device = config_GetPsz( p_intf, "vcd" );
1679         if( !b_disc_device_changed )
1680         {
1681             if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1682             else disc_device->SetValue( wxT("") );
1683         }
1684
1685 #ifdef HAVE_VCDX
1686         if (config_GetInt( p_intf, "vcdx-PBC"  ))
1687         {
1688           disc_title_label->SetLabel ( wxT("Playback LID") );
1689           disc_title->SetToolTip( wxU(_(
1690           "Playback control (PBC) usually starts with number 1." )) );
1691         }
1692         else
1693         {
1694           disc_title_label->SetLabel ( wxT("Entry") );
1695           disc_title->SetToolTip( wxU(_(
1696           "The first entry (the beginning of the first MPEG track) is 0." )) );
1697         }
1698
1699 #else
1700         disc_title_label->SetLabel ( wxU(_("Track")) );
1701         disc_title->SetToolTip( wxU(_("Track number.")) );
1702 #endif
1703         disc_title->SetRange( 0, 99 );  // only 100 tracks allowed on VCDs
1704         disc_sub->SetRange( -1, 3 );    // up to 4 subtitles -1 = no subtitle
1705         disc_audio->SetRange( 0, 1 );   // up to 2 audio tracks
1706         disc_sub->SetToolTip( wxU(_(
1707           "SVCD's can have up to 4 subtitles numbered 0..3. "
1708           "If a value -1 is used, no subtitle will be shown." )) );
1709         disc_audio->SetToolTip( wxU(_("Audio track number. "
1710           "VCD's can have up to 2 audio tracks numbered 0 or 1. "
1711         )) );
1712         break;
1713
1714     case SELECTION_DISC_TYPE_CDDA:
1715         disc_sub->Disable(); disc_sub_label->Disable();
1716         disc_chapter->Disable(); disc_chapter_label->Disable();
1717         disc_audio->Disable(); disc_audio_label->Disable();
1718         disc_title_label->SetLabel ( wxU(_("Track")) );
1719 #ifdef HAVE_CDDAX
1720         disc_title->SetToolTip( wxU(_(
1721         "Audio CDs can have up to 100 tracks, the first track is usually 1. "
1722         "If 0 is given, then all tracks are played.")) );
1723 #else
1724         disc_title->SetToolTip( wxU(_(
1725         "Audio CDs can have up to 100 tracks, the first track is usually 1."
1726         )) );
1727 #endif
1728         psz_device = config_GetPsz( p_intf, "cd-audio" );
1729         if( !b_disc_device_changed )
1730         {
1731             if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1732             else disc_device->SetValue( wxT("") );
1733         }
1734
1735         /* There are at most 100 tracks in a CD-DA */
1736         disc_title->SetRange( 0, 100 );
1737         break;
1738
1739     default:
1740         msg_Err( p_intf, "invalid Disc type selection (%d)",
1741                  disc_type->GetSelection() );
1742         break;
1743     }
1744
1745     disc_title->SetValue( 0 ); i_disc_title = 0;
1746     disc_chapter->SetValue( 0 ); i_disc_chapter = 0;
1747
1748     if( psz_device ) free( psz_device );
1749
1750     UpdateMRL( DISC_ACCESS );
1751 }
1752
1753 /*****************************************************************************
1754  * Net panel event methods.
1755  *****************************************************************************/
1756 void OpenDialog::OnNetPanelChangeSpin( wxSpinEvent& event )
1757 {
1758     wxCommandEvent cevent;
1759     cevent.SetId(event.GetId());
1760     cevent.SetInt(event.GetPosition());
1761     OnNetPanelChange(cevent);
1762 }
1763
1764 void OpenDialog::OnNetPanelChange( wxCommandEvent& event )
1765 {
1766     if( event.GetId() >= NetPort1_Event && event.GetId() <= NetPort3_Event )
1767     {
1768         i_net_ports[event.GetId() - NetPort1_Event] = event.GetInt();
1769     }
1770
1771     UpdateMRL( NET_ACCESS );
1772 }
1773
1774 void OpenDialog::OnNetTypeChange( wxCommandEvent& event )
1775 {
1776     int i;
1777
1778     i_net_type = event.GetId() - NetRadio1_Event;
1779
1780     for(i=0; i<4; i++)
1781     {
1782         net_radios[i]->SetValue( event.GetId() == (NetRadio1_Event+i) );
1783         net_subpanels[i]->Enable( event.GetId() == (NetRadio1_Event+i) );
1784     }
1785     /* UDP Unicast or multicast -> timeshift */
1786     if( i_net_type == 0 || i_net_type == 1 )
1787         net_timeshift->Enable();
1788     else
1789         net_timeshift->Disable();
1790
1791     UpdateMRL( NET_ACCESS );
1792 }
1793
1794 /*****************************************************************************
1795  * Subtitles file event methods.
1796  *****************************************************************************/
1797 void OpenDialog::OnSubsFileEnable( wxCommandEvent& event )
1798 {
1799     subsfile_button->Enable( event.GetInt() != 0 );
1800     subbrowse_button->Enable( event.GetInt() != 0 );
1801     subfile_combo->Enable( event.GetInt() != 0 );
1802 }
1803
1804 void OpenDialog::OnSubsFileSettings( wxCommandEvent& WXUNUSED(event) )
1805 {
1806     /* Show/hide the open dialog */
1807     if( subsfile_dialog == NULL )
1808         subsfile_dialog = new SubsFileDialog( p_intf, this );
1809
1810     if( subsfile_dialog && subsfile_dialog->ShowModal() == wxID_OK )
1811     {
1812         subsfile_mrl.Empty();
1813         subsfile_mrl.Add( wxString(wxT("sub-file="))  + subfile_combo->GetValue() );
1814         if( subsfile_dialog->encoding_combo )
1815         {
1816             subsfile_mrl.Add( wxString(wxT("subsdec-encoding=")) +
1817                               subsfile_dialog->encoding_combo->GetValue() );
1818         }
1819         if( subsfile_dialog->align_combo )
1820         {
1821             subsfile_mrl.Add( wxString::Format(wxT("subsdec-align=%i"),
1822                               (int)subsfile_dialog->align_combo->GetClientData(
1823                               subsfile_dialog->align_combo->GetSelection()) ) );
1824         }
1825         if( subsfile_dialog->size_combo )
1826         {
1827             subsfile_mrl.Add( wxString::Format( wxT("freetype-rel-fontsize=%i"),
1828                               (int)subsfile_dialog->size_combo->GetClientData(
1829                               subsfile_dialog->size_combo->GetSelection()) ) );
1830         }
1831         subsfile_mrl.Add( wxString::Format( wxT("sub-fps=%i"),
1832                           subsfile_dialog->fps_spinctrl->GetValue() ) );
1833         subsfile_mrl.Add( wxString::Format( wxT("sub-delay=%i"),
1834                           subsfile_dialog->delay_spinctrl->GetValue() ) );
1835     }
1836 }
1837
1838 /*****************************************************************************
1839  * Stream output event methods.
1840  *****************************************************************************/
1841 void OpenDialog::OnSoutEnable( wxCommandEvent& event )
1842 {
1843     sout_button->Enable( event.GetInt() != 0 );
1844 }
1845
1846 void OpenDialog::OnSoutSettings( wxCommandEvent& WXUNUSED(event) )
1847 {
1848     /* Show/hide the open dialog */
1849     if( sout_dialog == NULL )
1850         sout_dialog = new SoutDialog( p_intf, this );
1851
1852     if( sout_dialog && sout_dialog->ShowModal() == wxID_OK )
1853     {
1854         sout_mrl = sout_dialog->GetOptions();
1855     }
1856 }
1857
1858 /*****************************************************************************
1859  * Caching event methods.
1860  *****************************************************************************/
1861 void OpenDialog::OnCachingEnable( wxCommandEvent& event )
1862 {
1863     caching_value->Enable( event.GetInt() != 0 );
1864     i_caching = caching_value->GetValue();
1865     UpdateMRL();
1866 }
1867
1868 void OpenDialog::OnCachingChangeSpin( wxSpinEvent& event )
1869 {
1870     wxCommandEvent cevent;
1871     OnCachingChange(cevent);
1872 }
1873
1874 void OpenDialog::OnCachingChange( wxCommandEvent& event )
1875 {
1876     i_caching = event.GetInt();
1877     UpdateMRL();
1878 }
1879
1880 /*****************************************************************************
1881  * Utility functions.
1882  *****************************************************************************/
1883 wxArrayString SeparateEntries( wxString entries )
1884 {
1885     vlc_bool_t b_quotes_mode = VLC_FALSE;
1886
1887     wxArrayString entries_array;
1888     wxString entry;
1889
1890     wxStringTokenizer token( entries, wxT(" \t\r\n\""), wxTOKEN_RET_DELIMS );
1891
1892     while( token.HasMoreTokens() )
1893     {
1894         entry += token.GetNextToken();
1895
1896         if( entry.IsEmpty() ) continue;
1897
1898         if( !b_quotes_mode && entry.Last() == wxT('\"') )
1899         {
1900             /* Enters quotes mode */
1901             entry.RemoveLast();
1902             b_quotes_mode = VLC_TRUE;
1903         }
1904         else if( b_quotes_mode && entry.Last() == wxT('\"') )
1905         {
1906             /* Finished the quotes mode */
1907             entry.RemoveLast();
1908             b_quotes_mode = VLC_FALSE;
1909         }
1910         else if( !b_quotes_mode && entry.Last() != wxT('\"') )
1911         {
1912             /* we found a non-quoted standalone string */
1913             if( token.HasMoreTokens() ||
1914                 entry.Last() == wxT(' ') || entry.Last() == wxT('\t') ||
1915                 entry.Last() == wxT('\r') || entry.Last() == wxT('\n') )
1916                 entry.RemoveLast();
1917             if( !entry.IsEmpty() ) entries_array.Add( entry );
1918             entry.Empty();
1919         }
1920         else
1921         {;}
1922     }
1923
1924     if( !entry.IsEmpty() ) entries_array.Add( entry );
1925
1926     return entries_array;
1927 }