1 /*****************************************************************************
2 * open.cpp : Open dialog box
3 *****************************************************************************
4 * Copyright (C) 2000-2005 the VideoLAN team
7 * Authors: Gildas Bazin <gbazin@videolan.org>
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.
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.
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 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
27 #include "dialogs/open.hpp"
28 #include "dialogs/streamout.hpp"
29 #include "dialogs/preferences_widgets.h"
30 #include "dialogs/subtitles.hpp"
32 #include "vlc_charset.h"
34 #undef HAVE_LIBCDIO // Disable broken code
37 #include <cdio/cdio.h>
38 #include <cdio/cd_types.h>
39 #include <cdio/logging.h>
40 #endif /* HAVE_LIBCDIO */
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 */
50 #include <wx/combobox.h>
51 #include <wx/statline.h>
52 #include <wx/tokenzr.h>
55 # define wxRB_SINGLE 0
58 #define SELECTION_DISC_TYPE_DVD_MENUS 0
59 #define SELECTION_DISC_TYPE_DVD 1
60 #define SELECTION_DISC_TYPE_VCD 2
61 #define SELECTION_DISC_TYPE_CDDA 3
63 /*****************************************************************************
65 *****************************************************************************/
67 /* IDs for the controls and the menu commands */
70 Notebook_Event = wxID_HIGHEST,
89 NetRadio1_Event, NetRadio2_Event, NetRadio3_Event, NetRadio4_Event,
90 NetPort1_Event, NetPort2_Event, NetPort3_Event,
91 NetAddr1_Event, NetAddr2_Event, NetAddr3_Event, NetAddr4_Event,
92 NetForceIPv6_Event, NetTimeshift_Event,
95 SubsFileSettings_Event,
103 AdvancedOptions_Event
106 BEGIN_EVENT_TABLE(OpenDialog, wxDialog)
108 EVT_BUTTON(wxID_OK, OpenDialog::OnOk)
109 EVT_BUTTON(wxID_CANCEL, OpenDialog::OnCancel)
111 EVT_NOTEBOOK_PAGE_CHANGED(Notebook_Event, OpenDialog::OnPageChange)
113 EVT_TEXT(MRL_Event, OpenDialog::OnMRLChange)
115 /* Events generated by the file panel */
116 EVT_TEXT(FileName_Event, OpenDialog::OnFilePanelChange)
117 EVT_BUTTON(FileBrowse_Event, OpenDialog::OnFileBrowse)
118 EVT_TEXT(SubFileName_Event, OpenDialog::OnSubFileChange)
119 EVT_BUTTON(SubFileBrowse_Event, OpenDialog::OnSubFileBrowse)
121 /* Events generated by the disc panel */
122 EVT_RADIOBOX(DiscType_Event, OpenDialog::OnDiscTypeChange)
124 EVT_CHECKBOX(DiscProbe_Event, OpenDialog::OnDiscProbe)
126 EVT_TEXT(DiscDevice_Event, OpenDialog::OnDiscDeviceChange)
127 EVT_TEXT(DiscDevice_Event, OpenDialog::OnDiscPanelChange)
128 EVT_TEXT(DiscTitle_Event, OpenDialog::OnDiscPanelChange)
129 EVT_SPINCTRL(DiscTitle_Event, OpenDialog::OnDiscPanelChangeSpin)
130 EVT_TEXT(DiscChapter_Event, OpenDialog::OnDiscPanelChange)
131 EVT_SPINCTRL(DiscChapter_Event, OpenDialog::OnDiscPanelChangeSpin)
132 EVT_TEXT(DiscSub_Event, OpenDialog::OnDiscPanelChange)
133 EVT_TEXT(DiscAudio_Event, OpenDialog::OnDiscPanelChange)
134 EVT_SPINCTRL(DiscSub_Event, OpenDialog::OnDiscPanelChangeSpin)
136 /* Events generated by the net panel */
137 EVT_RADIOBUTTON(NetRadio1_Event, OpenDialog::OnNetTypeChange)
138 EVT_RADIOBUTTON(NetRadio2_Event, OpenDialog::OnNetTypeChange)
139 EVT_RADIOBUTTON(NetRadio3_Event, OpenDialog::OnNetTypeChange)
140 EVT_RADIOBUTTON(NetRadio4_Event, OpenDialog::OnNetTypeChange)
141 EVT_TEXT(NetPort1_Event, OpenDialog::OnNetPanelChange)
142 EVT_SPINCTRL(NetPort1_Event, OpenDialog::OnNetPanelChangeSpin)
143 EVT_TEXT(NetPort2_Event, OpenDialog::OnNetPanelChange)
144 EVT_SPINCTRL(NetPort2_Event, OpenDialog::OnNetPanelChangeSpin)
145 EVT_TEXT(NetPort3_Event, OpenDialog::OnNetPanelChange)
146 EVT_SPINCTRL(NetPort3_Event, OpenDialog::OnNetPanelChangeSpin)
147 EVT_TEXT(NetAddr2_Event, OpenDialog::OnNetPanelChange)
148 EVT_TEXT(NetAddr3_Event, OpenDialog::OnNetPanelChange)
149 EVT_TEXT(NetAddr4_Event, OpenDialog::OnNetPanelChange)
150 EVT_CHECKBOX(NetForceIPv6_Event, OpenDialog::OnNetPanelChange)
151 EVT_CHECKBOX(NetTimeshift_Event, OpenDialog::OnNetPanelChange)
153 /* Events generated by the subtitle file buttons */
154 EVT_CHECKBOX(SubsFileEnable_Event, OpenDialog::OnSubsFileEnable)
155 EVT_BUTTON(SubsFileSettings_Event, OpenDialog::OnSubsFileSettings)
157 /* Events generated by the stream output buttons */
158 EVT_CHECKBOX(SoutEnable_Event, OpenDialog::OnSoutEnable)
159 EVT_BUTTON(SoutSettings_Event, OpenDialog::OnSoutSettings)
161 /* Events generated by the caching button */
162 EVT_CHECKBOX(CachingEnable_Event, OpenDialog::OnCachingEnable)
163 EVT_TEXT(CachingChange_Event, OpenDialog::OnCachingChange)
164 EVT_SPINCTRL(CachingChange_Event, OpenDialog::OnCachingChangeSpin)
166 /* Hide the window when the user closes the window */
167 EVT_CLOSE(OpenDialog::OnClose)
172 /*****************************************************************************
174 *****************************************************************************/
175 WX_DEFINE_ARRAY(ConfigControl *, ArrayOfConfigControls);
177 class AutoBuiltPanel : public wxPanel
182 AutoBuiltPanel( wxWindow *, OpenDialog *, intf_thread_t *,
185 virtual ~AutoBuiltPanel() {}
187 void UpdateAdvancedMRL();
190 ArrayOfConfigControls config_array;
191 ArrayOfConfigControls advanced_config_array;
192 wxComboBox *p_advanced_mrl_combo;
195 intf_thread_t *p_intf;
196 OpenDialog *p_open_dialog;
198 void OnAdvanced( wxCommandEvent& event );
199 wxDialog *p_advanced_dialog;
201 DECLARE_EVENT_TABLE();
204 BEGIN_EVENT_TABLE(AutoBuiltPanel, wxPanel)
205 EVT_BUTTON(AdvancedOptions_Event, AutoBuiltPanel::OnAdvanced)
208 static void AutoBuildCallback( void *p_data )
210 ((OpenDialog *)p_data)->UpdateMRL();
213 static void AutoBuildAdvancedCallback( void *p_data )
215 ((AutoBuiltPanel *)p_data)->UpdateAdvancedMRL();
218 AutoBuiltPanel::AutoBuiltPanel( wxWindow *parent, OpenDialog *dialog,
219 intf_thread_t *_p_intf,
220 const module_t *p_module )
221 : wxPanel( parent, -1, wxDefaultPosition, wxDefaultSize ),
222 name( wxU(module_GetObjName(p_module)) ),
223 p_advanced_mrl_combo( NULL ),
224 p_intf( _p_intf ), p_open_dialog( dialog ), p_advanced_dialog( NULL )
226 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
227 bool b_advanced = false;
228 unsigned int i_confsize;
229 module_config_t *p_config;
232 p_config = module_GetConfig (p_module, &i_confsize);
233 for( n = 0; n < i_confsize; n++ )
235 module_config_t *p_item = p_config + n;
236 if( !(p_item->i_type & CONFIG_HINT) && p_item->b_advanced )
239 if( p_item->i_type & CONFIG_HINT || p_item->b_advanced )
242 ConfigControl *control =
243 CreateConfigControl( VLC_OBJECT(p_intf), p_item, this );
245 config_array.Add( control );
247 /* Don't add items that were not recognized */
248 if( control == NULL ) continue;
250 control->SetUpdateCallback( AutoBuildCallback, (void *)dialog );
252 sizer->Add( control, 0, wxEXPAND | wxALL, 2 );
258 new wxButton( this, AdvancedOptions_Event,
259 wxU(_("Advanced options...")) );
260 sizer->Add( button, 0, wxALL, 5 );
262 /* Build the advanced dialog */
264 new wxDialog( this, -1, ((wxString)wxU(_("Advanced options"))) +
265 wxT(" (") + wxU( module_GetLongName(p_module) ) +
266 wxT(")"), wxDefaultPosition, wxDefaultSize,
267 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER );
269 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
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 );
288 /* Add advanced options to panel */
289 for( n = 0; n < i_confsize; n++ )
291 module_config_t *p_item = p_config + n;
292 if( p_item->i_type & CONFIG_HINT || !p_item->b_advanced )
295 ConfigControl *control =
296 CreateConfigControl( VLC_OBJECT(p_intf), p_item,
299 advanced_config_array.Add( control );
301 /* Don't add items that were not recognized */
302 if( control == NULL ) continue;
304 control->SetUpdateCallback( AutoBuildAdvancedCallback,
307 sizer->Add( control, 0, wxEXPAND | wxALL, 2 );
311 wxPanel *dummy_panel = new wxPanel( p_advanced_dialog, -1 );
312 sizer->Add( dummy_panel, 1 );
313 wxStaticLine *static_line =
314 new wxStaticLine( p_advanced_dialog, wxID_OK );
315 sizer->Add( static_line, 0, wxEXPAND | wxALL, 5 );
318 wxButton *ok_button =
319 new wxButton( p_advanced_dialog, wxID_OK, wxU(_("&OK")) );
320 ok_button->SetDefault();
321 wxButton *cancel_button =
322 new wxButton( p_advanced_dialog, wxID_CANCEL, wxU(_("&Cancel")) );
323 wxStdDialogButtonSizer *button_sizer = new wxStdDialogButtonSizer;
324 button_sizer->AddButton( ok_button );
325 button_sizer->AddButton( cancel_button );
326 button_sizer->Realize();
327 sizer->Add( button_sizer, 0, wxEXPAND|wxALL, 5 );
329 sizer->SetMinSize( 400, -1 );
330 p_advanced_dialog->SetSizerAndFit( sizer );
333 module_PutConfig (p_config);
335 this->SetSizerAndFit( sizer );
338 void AutoBuiltPanel::OnAdvanced( wxCommandEvent& event )
340 if( p_advanced_dialog->ShowModal() == wxID_OK )
343 p_open_dialog->UpdateMRL();
347 void AutoBuiltPanel::UpdateAdvancedMRL()
351 for( int i = 0; i < (int)advanced_config_array.GetCount(); i++ )
353 ConfigControl *control = advanced_config_array.Item(i);
355 mrltemp += (i ? wxT(" :") : wxT(":"));
357 if( control->GetType() == CONFIG_ITEM_BOOL &&
358 !control->GetIntValue() ) mrltemp += wxT("no-");
360 mrltemp += control->GetName();
362 switch( control->GetType() )
364 case CONFIG_ITEM_STRING:
365 case CONFIG_ITEM_FILE:
366 case CONFIG_ITEM_DIRECTORY:
367 case CONFIG_ITEM_MODULE:
368 mrltemp += wxT("=\"") + control->GetPszValue() + wxT("\"");
370 case CONFIG_ITEM_INTEGER:
372 wxString::Format( wxT("=%i"), control->GetIntValue() );
374 case CONFIG_ITEM_FLOAT:
376 wxString::Format(wxT("=%f"), control->GetFloatValue());
381 p_advanced_mrl_combo->SetValue( mrltemp );
384 /*****************************************************************************
386 *****************************************************************************/
387 OpenDialog::OpenDialog( intf_thread_t *_p_intf, wxWindow *_p_parent,
388 int i_access_method, int i_arg ):
389 wxDialog( _p_parent, -1, wxU(_("Open...")), wxDefaultPosition,
390 wxDefaultSize, wxDEFAULT_FRAME_STYLE )
392 OpenDialog( _p_intf, _p_parent, i_access_method, i_arg, OPEN_NORMAL );
395 OpenDialog::OpenDialog( intf_thread_t *_p_intf, wxWindow *_p_parent,
396 int i_access_method, int i_arg, int _i_method ):
397 wxDialog( _p_parent, -1, wxU(_("Open...")), wxDefaultPosition,
398 wxDefaultSize, wxDEFAULT_FRAME_STYLE )
400 /* Initializations */
401 i_method = _i_method;
403 p_parent = _p_parent;
404 SetIcon( *p_intf->p_sys->p_icon );
406 i_disc_type_selection = 0;
411 subsfile_dialog = NULL;
412 b_disc_device_changed = false;
414 /* Create a panel to put everything in */
415 wxPanel *panel = new wxPanel( this, -1 );
416 panel->SetAutoLayout( TRUE );
419 /* Advanced options */
420 wxStaticBox *adv_box = new wxStaticBox( panel, -1,
421 wxU(_("Advanced options")) );
422 wxStaticBoxSizer *adv_sizer = new wxStaticBoxSizer( adv_box,
426 wxFlexGridSizer *common_opt_sizer = new wxFlexGridSizer( 5, 1, 20 );
427 if( i_method == OPEN_NORMAL )
429 /* Create Stream Output checkox */
430 sout_checkbox = new wxCheckBox( panel, SoutEnable_Event,
431 wxU(_("Stream/Save")) );
432 sout_checkbox->SetToolTip( wxU(_("Use VLC as a stream server")) );
433 common_opt_sizer->Add( sout_checkbox, 0,
434 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
436 sout_button = new wxButton( panel, SoutSettings_Event,
437 wxU(_("Settings...")) );
438 sout_button->Disable();
440 char *psz_sout = config_GetPsz( p_intf, "sout" );
441 if( psz_sout && *psz_sout )
443 sout_checkbox->SetValue(TRUE);
444 sout_button->Enable();
445 subsfile_mrl.Add( wxString(wxT("sout=")) + wxL2U(psz_sout) );
449 common_opt_sizer->Add( sout_button, 1, wxALIGN_LEFT |
450 wxALIGN_CENTER_VERTICAL );
452 common_opt_sizer->Add( new wxPanel( this, -1 ), 1,
453 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
456 /* Create caching options */
457 caching_checkbox = new wxCheckBox( panel, CachingEnable_Event,
459 caching_checkbox->SetToolTip( wxU(_("Change the default caching value "
460 "(in milliseconds)")) );
461 common_opt_sizer->Add( caching_checkbox, 0,
462 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
463 caching_value = new wxSpinCtrl( panel, CachingChange_Event );
464 caching_value->SetRange( 0, 1000000 );
465 caching_value->Disable();
466 common_opt_sizer->Add( caching_value, 0,
467 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
470 wxBoxSizer *mrl_sizer = new wxBoxSizer( wxHORIZONTAL );
471 wxStaticText *mrl_label = new wxStaticText( panel, -1,
472 wxU(_("Customize:")) );
473 mrl_combo = new wxComboBox( panel, MRL_Event, wxT(""),
474 wxDefaultPosition, wxDefaultSize );
475 //Point(20,25), wxSize(120, -1) );
476 mrl_combo->SetToolTip( wxU(_("You can use this field directly by typing "
477 "the full MRL you want to open.\n""Alternatively, the field will be "
478 "filled automatically when you use the controls above.")) );
480 mrl_sizer->Add( mrl_label, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
481 mrl_sizer->Add( mrl_combo, 1, wxALL | wxEXPAND | wxALIGN_CENTER_VERTICAL,
484 adv_sizer->Add( common_opt_sizer, 0, wxTOP | wxLEFT|wxRIGHT | wxEXPAND, 5 );
485 adv_sizer->Add( mrl_sizer, 0, wxBOTTOM | wxLEFT|wxRIGHT | wxEXPAND, 5 );
488 wxStaticLine *static_line = new wxStaticLine( panel, wxID_OK );
490 /* Create the buttons */
491 wxButton *ok_button = new wxButton( panel, wxID_OK, wxU(_("&OK")) );
492 ok_button->SetDefault();
493 wxButton *cancel_button = new wxButton( panel, wxID_CANCEL,
496 /* Create notebook */
497 notebook = new wxNotebook( panel, Notebook_Event );
499 #if (!wxCHECK_VERSION(2,5,2))
500 wxNotebookSizer *notebook_sizer = new wxNotebookSizer( notebook );
503 notebook->AddPage( FilePanel( notebook ), wxU(_("File")),
504 i_access_method == FILE_ACCESS );
505 notebook->AddPage( DiscPanel( notebook ), wxU(_("Disc")),
506 i_access_method == DISC_ACCESS );
507 notebook->AddPage( NetPanel( notebook ), wxU(_("Network")),
508 i_access_method == NET_ACCESS );
510 module_t *p_module = module_Find( VLC_OBJECT(p_intf), "v4l" );
513 AutoBuiltPanel *autopanel =
514 new AutoBuiltPanel( notebook, this, p_intf, p_module );
515 input_tab_array.Add( autopanel );
516 notebook->AddPage( autopanel, wxU( module_GetName(p_module, 0) ),
517 i_access_method == CAPTURE_ACCESS );
518 module_Put( p_module );
521 p_module = module_Find( VLC_OBJECT(p_intf), "pvr" );
524 AutoBuiltPanel *autopanel =
525 new AutoBuiltPanel( notebook, this, p_intf, p_module );
526 input_tab_array.Add( autopanel );
527 notebook->AddPage( autopanel, wxU( module_GetName(p_module, 0) ),
528 i_access_method == CAPTURE_ACCESS );
529 module_Put( p_module );
532 p_module = module_Find( VLC_OBJECT(p_intf), "dvb" );
535 AutoBuiltPanel *autopanel =
536 new AutoBuiltPanel( notebook, this, p_intf, p_module );
537 input_tab_array.Add( autopanel );
538 notebook->AddPage( autopanel, wxU( module_GetName(p_module, 0) ),
539 i_access_method == CAPTURE_ACCESS );
540 module_Put( p_module );
543 p_module = module_Find( VLC_OBJECT(p_intf), "dshow" );
546 AutoBuiltPanel *autopanel =
547 new AutoBuiltPanel( notebook, this, p_intf, p_module );
548 input_tab_array.Add( autopanel );
549 notebook->AddPage( autopanel, wxU( module_GetName(p_module, 0) ),
550 i_access_method == CAPTURE_ACCESS );
551 module_Put( p_module );
554 /* Update Disc panel */
555 wxCommandEvent dummy_event;
556 OnDiscTypeChange( dummy_event );
558 /* Update Net panel */
559 dummy_event.SetId( NetRadio1_Event );
560 OnNetTypeChange( dummy_event );
563 wxNotebookEvent event( wxEVT_NULL, 0, i_access_method );
564 OnPageChange( event );
566 /* Place everything in sizers */
567 wxStdDialogButtonSizer *button_sizer = new wxStdDialogButtonSizer;
568 button_sizer->AddButton( cancel_button );
569 button_sizer->AddButton( ok_button );
570 button_sizer->Realize();
571 wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL );
572 wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
573 #if (!wxCHECK_VERSION(2,5,2))
574 panel_sizer->Add( notebook_sizer, 1, wxEXPAND | wxALL, 5 );
576 panel_sizer->Add( notebook, 1, wxEXPAND | wxALL, 5 );
578 panel_sizer->Add( adv_sizer, 0, wxEXPAND | wxALL, 5 );
579 panel_sizer->Add( static_line, 0, wxEXPAND | wxALL, 5 );
580 panel_sizer->Add( button_sizer, 0, wxEXPAND | wxALL, 5 );
581 panel_sizer->Layout();
582 panel->SetSizerAndFit( panel_sizer );
583 main_sizer->Add( panel, 1, wxGROW, 0 );
584 main_sizer->Layout();
585 SetSizerAndFit( main_sizer );
588 OpenDialog::~OpenDialog()
593 delete subsfile_dialog;
596 int OpenDialog::Show( int i_access_method, int i_arg )
598 notebook->SetSelection( i_access_method );
599 int i_ret = wxDialog::Show();
606 int OpenDialog::Show()
608 int i_ret = wxDialog::Show();
614 /*****************************************************************************
616 *****************************************************************************/
617 wxPanel *OpenDialog::FilePanel( wxWindow* parent )
619 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
622 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
624 /* Create browse file line */
625 wxBoxSizer *file_sizer = new wxBoxSizer( wxHORIZONTAL );
627 file_sizer->Add( new wxStaticText( panel, -1, wxU(_("Open:") ) ), 0,
628 wxALL | wxALIGN_CENTER_VERTICAL, 5 );
630 file_combo = new wxComboBox( panel, FileName_Event, wxT("") );
631 wxButton *browse_button = new wxButton( panel, FileBrowse_Event,
632 wxU(_("Browse...")) );
633 file_sizer->Add( file_combo, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
634 file_sizer->Add( browse_button, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
636 /* Create Subtitles File checkox - button */
637 wxFlexGridSizer *subtitles_sizer = new wxFlexGridSizer( 2, 1, 20 );
638 subsfile_checkbox = new wxCheckBox( panel, SubsFileEnable_Event,
639 wxU(_("Use a subtitles file")) );
640 subsfile_checkbox->SetToolTip( wxU(_("Use an external subtitles file.")) );
641 subtitles_sizer->Add( subsfile_checkbox, 0, wxALIGN_CENTER_VERTICAL |
643 subsfile_button = new wxButton( panel, SubsFileSettings_Event,
644 wxU(_("Advanced Settings...")) );
645 subsfile_button->Disable();
646 subtitles_sizer->Add( subsfile_button, 1, wxALIGN_CENTER_VERTICAL |
649 /* Create subtitles file line */
650 wxBoxSizer *subfile_sizer = new wxBoxSizer( wxHORIZONTAL );
652 char *psz_subsfile = config_GetPsz( p_intf, "sub-file" );
653 if( psz_subsfile && *psz_subsfile )
655 subsfile_checkbox->SetValue(TRUE);
656 subsfile_button->Enable();
657 subsfile_mrl.Add( wxString(wxT("sub-file=")) + wxL2U(psz_subsfile) );
659 if( !psz_subsfile ) psz_subsfile = strdup("");
660 subfile_sizer->Add( new wxStaticText( panel, -1, wxU(_("File:") ) ),
661 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
662 subfile_combo = new wxComboBox( panel, SubFileName_Event,
663 wxL2U( psz_subsfile ) );
664 free( psz_subsfile );
665 subbrowse_button = new wxButton( panel, SubFileBrowse_Event,
666 wxU(_("Browse...")) );
667 subfile_sizer->Add( subfile_combo, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
668 subfile_sizer->Add( subbrowse_button, 0, wxALL |wxALIGN_CENTER_VERTICAL, 5 );
670 subfile_combo->Disable();
671 subbrowse_button->Disable();
673 psz_subsfile = config_GetPsz( p_intf, "sub-file" );
674 if( psz_subsfile && *psz_subsfile )
676 subfile_combo->Enable();
677 subbrowse_button->Enable();
680 sizer->Add( file_sizer, 0, wxEXPAND | wxALL, 5 );
681 sizer->Add( subtitles_sizer, 0, wxLEFT | wxRIGHT | wxTOP, 5 );
682 sizer->Add( subfile_sizer, 0, wxEXPAND | wxLEFT | wxRIGHT| wxBOTTOM, 5 );
683 panel->SetSizerAndFit( sizer );
687 wxPanel *OpenDialog::DiscPanel( wxWindow* parent )
689 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
692 wxBoxSizer *sizer_row = new wxBoxSizer( wxVERTICAL );
693 wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 3, 20 );
695 static const wxString disc_type_array[] =
697 wxU(_("DVD (menus)")),
703 disc_type = new wxRadioBox( panel, DiscType_Event, wxU(_("Disc type")),
704 wxDefaultPosition, wxDefaultSize,
705 WXSIZEOF(disc_type_array), disc_type_array,
706 WXSIZEOF(disc_type_array), wxRA_SPECIFY_COLS );
709 disc_probe = new wxCheckBox( panel, DiscProbe_Event,
710 wxU(_("Probe Disc(s)")) );
711 disc_probe->SetToolTip( wxU(_("Probe for a DVD, VCD or audio CD. "
712 "First try the Device name entered for the selected Disc type "
713 "(DVD, DVD Menu, VCD, audio CD). If that doesn't find media, try any device "
714 "for the Disc type. If that doesn't work, then try looking for CD-ROMs or "
715 "DVD drives. The Disc type, Device name, and some parameter ranges are set "
716 "based on media we find.")) );
719 sizer_row->Add( disc_type, i_disc_type_selection, wxEXPAND | wxALL, 5 );
721 sizer_row->Add( disc_probe, 0, wxEXPAND | wxALL );
724 wxStaticText *label = new wxStaticText( panel, -1, wxU(_("Device name")) );
725 disc_device = new wxTextCtrl( panel, DiscDevice_Event, wxT(""),
726 wxDefaultPosition, wxDefaultSize,
730 char psz_default_device[3] = {0};
733 /* find the drive_name for the first cdrom drive,
734 * which is probably "D:" and put the drive_name into
735 * psz_default_device... */
736 for( char drive_letter = 'A'; drive_letter <= 'Z'; ++drive_letter )
738 char drive_name[3] = {drive_letter, ':', 0};
739 UINT type = GetDriveTypeA( drive_name );
740 if( type == DRIVE_CDROM )
742 psz_default_device[0] = drive_letter;
743 psz_default_device[1] = ':';
748 psz_forced = config_GetPsz( p_intf, "dvd" );
750 if( strlen(psz_default_device) > 0 &&
751 ( !psz_forced || psz_forced && !*psz_forced ) )
754 disc_device->SetValue( wxL2U(psz_default_device) );
758 sizer->Add( label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
759 sizer->Add( disc_device, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
761 disc_title_label = new wxStaticText( panel, -1, wxU(_("Title")) );
762 disc_title = new wxSpinCtrl( panel, DiscTitle_Event );
763 sizer->Add( disc_title_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
764 sizer->Add( disc_title, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
766 disc_chapter_label = new wxStaticText( panel, -1, wxU(_("Chapter")) );
767 disc_chapter = new wxSpinCtrl( panel, DiscChapter_Event );
768 sizer->Add( disc_chapter_label, 0,
769 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
770 sizer->Add( disc_chapter, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
772 disc_sub_label = new wxStaticText( panel, -1, wxU(_("Subtitles track")) );
773 disc_sub = new wxSpinCtrl( panel, DiscSub_Event );
774 sizer->Add( disc_sub_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
775 sizer->Add( disc_sub, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
776 disc_sub->SetRange( -1, 255 );
777 i_disc_sub = config_GetInt( p_intf, "sub-track" );
778 disc_sub->SetValue( i_disc_sub );
780 disc_audio_label = new wxStaticText( panel, -1, wxU(_("Audio track")) );
781 disc_audio = new wxSpinCtrl( panel, DiscAudio_Event );
782 sizer->Add( disc_audio_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
783 sizer->Add( disc_audio, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
784 disc_audio->SetRange( -1, 255 );
785 i_disc_audio = config_GetInt( p_intf, "audio-track" );
786 disc_audio->SetValue( i_disc_audio );
788 sizer_row->Add( sizer, 0, wxEXPAND | wxALL, 5 );
790 panel->SetSizerAndFit( sizer_row );
794 wxPanel *OpenDialog::NetPanel( wxWindow* parent )
797 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
800 wxBoxSizer *sizer_row = new wxBoxSizer( wxVERTICAL );
801 wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 4, 20 );
803 static const wxString net_type_array[] =
806 wxU(_("UDP/RTP Multicast")),
807 wxU(_("HTTP/HTTPS/FTP/MMS")),
813 net_radios[i] = new wxRadioButton( panel, NetRadio1_Event + i,
815 wxDefaultPosition, wxDefaultSize,
818 net_subpanels[i] = new wxPanel( panel, -1,
819 wxDefaultPosition, wxDefaultSize );
823 net_timeshift = new wxCheckBox( panel, NetTimeshift_Event,
824 wxU(_("Allow timeshifting")) );
827 wxFlexGridSizer *subpanel_sizer;
829 i_net_ports[0] = config_GetInt( p_intf, "server-port" );
830 subpanel_sizer = new wxFlexGridSizer( 3, 1, 20 );
831 label = new wxStaticText( net_subpanels[0], -1, wxU(_("Port")) );
832 net_ports[0] = new wxSpinCtrl( net_subpanels[0], NetPort1_Event,
833 wxString::Format(wxT("%d"), i_net_ports[0]),
834 wxDefaultPosition, wxDefaultSize,
836 0, 65535, i_net_ports[0] );
838 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
839 subpanel_sizer->Add( net_ports[0], 1,
840 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
841 net_ipv6 = new wxCheckBox( net_subpanels[0], NetForceIPv6_Event,
842 wxU(_("Force IPv6")));
843 subpanel_sizer->Add( net_ipv6, 0,
844 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
845 net_subpanels[0]->SetSizerAndFit( subpanel_sizer );
846 net_radios[0]->SetValue( TRUE );
848 /* UDP/RTP Multicast row */
849 subpanel_sizer = new wxFlexGridSizer( 4, 1, 20 );
850 label = new wxStaticText( net_subpanels[1], -1, wxU(_("Address")) );
851 net_addrs[1] = new wxTextCtrl( net_subpanels[1], NetAddr2_Event, wxT(""),
852 wxDefaultPosition, wxDefaultSize,
854 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
855 subpanel_sizer->Add( net_addrs[1], 1,
856 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
858 label = new wxStaticText( net_subpanels[1], -1, wxU(_("Port")) );
859 i_net_ports[1] = i_net_ports[0];
860 net_ports[1] = new wxSpinCtrl( net_subpanels[1], NetPort2_Event,
861 wxString::Format(wxT("%d"), i_net_ports[1]),
862 wxDefaultPosition, wxDefaultSize,
864 0, 65535, i_net_ports[1] );
866 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
867 subpanel_sizer->Add( net_ports[1], 1,
868 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
869 net_subpanels[1]->SetSizerAndFit( subpanel_sizer );
871 /* HTTP and RTSP rows */
874 subpanel_sizer = new wxFlexGridSizer( 2, 1, 20 );
875 label = new wxStaticText( net_subpanels[i], -1, wxU(_("URL")) );
876 net_addrs[i] = new wxTextCtrl( net_subpanels[i], NetAddr1_Event + i,
877 (i == 2) ? wxT("") : wxT("rtsp://"),
878 wxDefaultPosition, wxSize( 200, -1 ),
880 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
881 subpanel_sizer->Add( net_addrs[i], 1,
882 wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
883 net_subpanels[i]->SetSizerAndFit( subpanel_sizer );
886 /* Stuff everything into the main panel */
889 sizer->Add( net_radios[i], 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
891 sizer->Add( net_subpanels[i], 1, wxEXPAND | wxALIGN_LEFT |
892 wxALIGN_CENTER_VERTICAL | wxALL, 5 );
894 sizer->Add( net_timeshift, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
897 sizer_row->Add( sizer, 0, wxEXPAND | wxALL, 5 );
899 panel->SetSizerAndFit( sizer_row );
903 void OpenDialog::UpdateMRL()
905 UpdateMRL( i_current_access_method );
908 void OpenDialog::UpdateMRL( int i_access_method )
910 wxString mrltemp, caching_name;
912 i_current_access_method = i_access_method;
914 switch( i_access_method )
917 mrltemp = file_combo->GetValue();
918 caching_name = wxT("file-caching");
922 i_disc_type_selection = disc_type->GetSelection();
924 switch ( i_disc_type_selection )
926 case 0: /* DVD with menus */
927 case 1: /* DVD without menus */
928 disc_device->SetToolTip( wxU(_("DVD device to use" ) ) );
929 if( i_disc_type_selection == 0 )
931 mrltemp = wxT("dvd://") + disc_device->GetValue();
932 caching_name = wxT("dvdnav-caching");
936 mrltemp = wxT("dvdsimple://") + disc_device->GetValue();
937 caching_name = wxT("dvdread-caching");
940 if( i_disc_title > 0 )
942 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
944 if( i_disc_chapter > 0 )
945 mrltemp += wxString::Format( wxT(":%d"), i_disc_chapter );
948 if( i_disc_sub >= 0 )
949 mrltemp += wxString::Format( wxT(" :sub-track=%d"),
951 if( i_disc_audio >= 0 )
952 mrltemp += wxString::Format( wxT(" :audio-track=%d"),
956 case 2: /* VCD of some sort */
958 disc_device->SetToolTip( wxU(_("Name of CD-ROM device "
959 "to read Video CD from. If this field is left empty, we will scan "
960 "for a CD-ROM with a VCD in it.")) );
961 mrltemp = wxT("vcdx://") + disc_device->GetValue();
962 if( i_disc_title > 0 )
963 mrltemp += wxString::Format( wxT("@%c%d"),
964 config_GetInt( p_intf, "vcdx-PBC" )
965 ? 'P' : 'E', i_disc_title );
967 disc_device->SetToolTip( wxU(_("CD-ROM device to use" ) ) );
968 mrltemp = wxT("vcd://") + disc_device->GetValue();
969 if( i_disc_title > 0 )
970 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
973 if( i_disc_sub >= 0 )
974 mrltemp += wxString::Format( wxT(" :sub-track=%d"),
977 if( i_disc_audio >= 0 )
978 mrltemp += wxString::Format( wxT(" :audio-track=%d"),
980 caching_name = wxT("vcd-caching");
985 disc_device->SetToolTip( wxU(_("Name of CD-ROM device "
986 "to read audio CD from. If this field is left empty, we will scan "
987 "for a CD-ROM with an audio CD in it." )) );
988 mrltemp = wxT("cddax://")
990 disc_device->SetToolTip( wxU(_("CD-ROM device to use" ) ) ) ;
991 mrltemp = wxT("cdda://")
993 + disc_device->GetValue();
994 if( i_disc_title > 0 )
995 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
997 caching_name = wxT("cdda-caching");
1001 msg_Err( p_intf, "invalid selection (%d)",
1002 disc_type->GetSelection() );
1008 switch( i_net_type )
1011 mrltemp = wxT("udp://@");
1012 if ( net_ipv6->GetValue() )
1014 mrltemp += wxT("[::]");
1016 if( i_net_ports[0] !=
1017 config_GetInt( p_intf, "server-port" ) )
1019 mrltemp += wxString::Format( wxT(":%d"), i_net_ports[0] );
1022 caching_name = wxT("udp-caching");
1026 mrltemp = wxT("udp://@");
1027 if ((net_addrs[1]->GetLineText(0).Find (':') != -1)
1028 && (net_addrs[1]->GetLineText(0)[0u] != '['))
1030 /* automatically adds '[' and ']' to IPv6 addresses */
1031 mrltemp += wxT("[") + net_addrs[1]->GetLineText(0)
1036 mrltemp += net_addrs[1]->GetLineText(0);
1038 if( i_net_ports[1] != config_GetInt( p_intf, "server-port" ) )
1040 mrltemp += wxString::Format( wxT(":%d"), i_net_ports[1] );
1043 caching_name = wxT("udp-caching");
1048 if( net_addrs[2]->GetLineText(0).Find(wxT("://")) == -1 )
1049 mrltemp = wxT("http://");
1051 mrltemp += net_addrs[2]->GetLineText(0);
1052 if( ! mrltemp.Left(4).CmpNoCase(wxT("http")) )
1053 caching_name = wxT("http-caching");
1054 else if( ! mrltemp.Left(3).CmpNoCase(wxT("mms")) )
1055 caching_name = wxT("mms-caching");
1057 caching_name= wxT("ftp-caching");
1062 if( net_addrs[3]->GetLineText(0).Find(wxT("rtsp://")) != 0 )
1064 mrltemp = wxT("rtsp://");
1066 mrltemp += net_addrs[3]->GetLineText(0);
1068 caching_name = wxT("rtsp-caching");
1071 if( net_timeshift->IsEnabled() && net_timeshift->IsChecked() )
1072 mrltemp += wxT(" :access-filter=timeshift");
1077 int i_item = i_access_method - MAX_ACCESS;
1079 if( i_item < 0 || i_item >= (int)input_tab_array.GetCount() )
1082 AutoBuiltPanel *input_panel = input_tab_array.Item( i_item );
1084 mrltemp = input_panel->name + wxT("://");
1086 for( int i=0; i < (int)input_panel->config_array.GetCount(); i++ )
1088 ConfigControl *control = input_panel->config_array.Item(i);
1090 mrltemp += wxT(" :");
1092 if( control->GetType() == CONFIG_ITEM_BOOL &&
1093 !control->GetIntValue() ) mrltemp += wxT("no-");
1095 mrltemp += control->GetName();
1097 switch( control->GetType() )
1099 case CONFIG_ITEM_STRING:
1100 case CONFIG_ITEM_FILE:
1101 case CONFIG_ITEM_DIRECTORY:
1102 case CONFIG_ITEM_MODULE:
1103 mrltemp += wxT("=\"") + control->GetPszValue() + wxT("\"");
1105 case CONFIG_ITEM_INTEGER:
1107 wxString::Format( wxT("=%i"), control->GetIntValue() );
1109 case CONFIG_ITEM_FLOAT:
1111 wxString::Format(wxT("=%f"), control->GetFloatValue());
1116 if( input_panel->p_advanced_mrl_combo &&
1117 input_panel->p_advanced_mrl_combo->GetValue() )
1119 mrltemp += wxT(" ") +
1120 input_panel->p_advanced_mrl_combo->GetValue();
1126 if( caching_name.size() )
1128 if( caching_value->IsEnabled() )
1130 mrltemp += wxT(" :") + caching_name +
1131 wxString::Format( wxT("=%d"), i_caching );
1135 int i_value = config_GetInt( p_intf, caching_name.mb_str(wxConvUTF8) );
1136 caching_value->SetValue( i_value );
1140 mrl_combo->SetValue( mrltemp );
1143 /*****************************************************************************
1145 *****************************************************************************/
1146 void OpenDialog::OnOk( wxCommandEvent& WXUNUSED(event) )
1148 mrl = SeparateEntries( mrl_combo->GetValue() );
1149 mrl_combo->Append( mrl_combo->GetValue() );
1150 if( mrl_combo->GetCount() > 10 ) mrl_combo->Delete( 0 );
1151 mrl_combo->SetSelection( mrl_combo->GetCount() - 1 );
1153 if( i_method == OPEN_STREAM )
1155 if( IsModal() ) EndModal( wxID_OK );
1160 /* Update the playlist */
1161 playlist_t *p_playlist = pl_Yield( p_intf );
1162 if( p_playlist == NULL ) return;
1164 for( int i = 0; i < (int)mrl.GetCount(); i++ )
1166 bool b_start = !i && i_open_arg;
1167 input_item_t *p_input;
1170 psz_utf8 = wxFromLocale( mrl[i] );
1171 p_input = input_ItemNew( p_intf, psz_utf8, NULL );
1172 wxLocaleFree( psz_utf8 );
1174 /* Insert options */
1175 while( i + 1 < (int)mrl.GetCount() &&
1176 ((const char *)mrl[i + 1].mb_str(wxConvUTF8))[0] == ':' )
1178 psz_utf8 = wxFromLocale( mrl[i + 1] );
1179 input_ItemAddOption( p_input, psz_utf8 );
1180 wxLocaleFree( psz_utf8 );
1184 /* Get the options from the subtitles dialog */
1185 if( subsfile_checkbox->IsChecked() && subsfile_mrl.GetCount() )
1187 for( int j = 0; j < (int)subsfile_mrl.GetCount(); j++ )
1189 psz_utf8 = wxFromLocale( subsfile_mrl[j] );
1190 input_ItemAddOption( p_input, psz_utf8 );
1191 wxLocaleFree( psz_utf8 );
1195 /* Get the options from the stream output dialog */
1196 if( sout_checkbox->IsChecked() && sout_mrl.GetCount() )
1198 for( int j = 0; j < (int)sout_mrl.GetCount(); j++ )
1200 psz_utf8 = wxFromLocale( sout_mrl[j] );
1201 input_ItemAddOption( p_input, psz_utf8 );
1202 wxLocaleFree( psz_utf8 );
1206 /* FIXME: playlist_AddInput() can fail */
1207 playlist_AddInput( p_playlist, p_input,
1208 PLAYLIST_APPEND | ( b_start ? PLAYLIST_GO : PLAYLIST_PREPARSE ),
1209 PLAYLIST_END, true, pl_Unlocked );
1210 vlc_gc_decref( p_input );
1212 pl_Release( p_intf );
1216 if( IsModal() ) EndModal( wxID_OK );
1219 void OpenDialog::OnCancel( wxCommandEvent& WXUNUSED(event) )
1221 wxCloseEvent cevent;
1225 void OpenDialog::OnClose( wxCloseEvent& WXUNUSED(event) )
1229 if( IsModal() ) EndModal( wxID_CANCEL );
1232 void OpenDialog::OnPageChange( wxNotebookEvent& event )
1234 UpdateMRL( event.GetSelection() );
1237 void OpenDialog::OnMRLChange( wxCommandEvent& event )
1239 //mrl = SeparateEntries( event.GetString() );
1242 /*****************************************************************************
1243 * File panel event methods.
1244 *****************************************************************************/
1245 void OpenDialog::OnFilePanelChange( wxCommandEvent& WXUNUSED(event) )
1247 UpdateMRL( FILE_ACCESS );
1250 void OpenDialog::OnFileBrowse( wxCommandEvent& WXUNUSED(event) )
1252 if( file_dialog == NULL )
1253 file_dialog = new wxFileDialog( this, wxU(_("Open File")),
1254 wxT(""), wxT(""), wxT("*"), wxOPEN | wxMULTIPLE );
1256 file_dialog->SetWildcard(wxU(_("All Files (*.*)|*"
1257 "|Sound Files (*.mp3, *.ogg, etc.)|" EXTENSIONS_AUDIO
1258 "|Video Files (*.avi, *.mpg, etc.)|" EXTENSIONS_VIDEO
1259 "|Playlist Files (*.m3u, *.pls, etc.)|" EXTENSIONS_PLAYLIST
1260 "|Subtitle Files (*.srt, *.sub, etc.)|" EXTENSIONS_SUBTITLE)));
1262 if( file_dialog && file_dialog->ShowModal() == wxID_OK )
1264 wxArrayString paths;
1267 file_dialog->GetPaths( paths );
1269 for( size_t i = 0; i < paths.GetCount(); i++ )
1271 if( paths[i].Find( wxT(' ') ) >= 0 )
1272 path += wxT("\"") + paths[i] + wxT("\" ");
1274 path += paths[i] + wxT(" ");
1277 file_combo->SetValue( path );
1278 file_combo->Append( path );
1279 if( file_combo->GetCount() > 10 ) file_combo->Delete( 0 );
1280 UpdateMRL( FILE_ACCESS );
1284 void OpenDialog::OnSubFileBrowse( wxCommandEvent& WXUNUSED(event) )
1286 wxFileDialog dialog( this, wxU(_("Open subtitles file")),
1287 wxT(""), wxT(""), wxT("*"), wxOPEN );
1289 if( dialog.ShowModal() == wxID_OK )
1291 subfile_combo->SetValue( dialog.GetPath() );
1293 wxCommandEvent event; OnSubFileChange( event );
1296 void OpenDialog::OnSubFileChange( wxCommandEvent& WXUNUSED(event) )
1298 if( subsfile_mrl.GetCount() != 0 )
1300 subsfile_mrl.RemoveAt( 0 );
1301 subsfile_mrl.Insert( wxString(wxT("sub-file=")) + subfile_combo->GetValue() , 0 );
1305 subsfile_mrl.Add( wxString(wxT("sub-file=")) + subfile_combo->GetValue() );
1309 /*****************************************************************************
1310 * Disc panel event methods.
1311 *****************************************************************************/
1312 void OpenDialog::OnDiscPanelChangeSpin( wxSpinEvent& event )
1314 wxCommandEvent cevent;
1315 cevent.SetId(event.GetId());
1316 cevent.SetInt(event.GetPosition());
1317 OnDiscPanelChange(cevent);
1320 void OpenDialog::OnDiscPanelChange( wxCommandEvent& event )
1322 if( event.GetId() == DiscTitle_Event ) i_disc_title = event.GetInt();
1323 if( event.GetId() == DiscChapter_Event ) i_disc_chapter = event.GetInt();
1324 if( event.GetId() == DiscSub_Event ) i_disc_sub = event.GetInt();
1325 if( event.GetId() == DiscAudio_Event ) i_disc_audio = event.GetInt();
1327 UpdateMRL( DISC_ACCESS );
1330 void OpenDialog::OnDiscDeviceChange( wxCommandEvent& event )
1334 switch( disc_type->GetSelection() )
1337 psz_device = config_GetPsz( p_intf, "cd-audio" );
1341 psz_device = config_GetPsz( p_intf, "vcd" );
1345 psz_device = config_GetPsz( p_intf, "dvd" );
1349 if ( !psz_device ) psz_device = "";
1351 if( disc_device->GetValue().Cmp( wxL2U( psz_device ) ) )
1353 b_disc_device_changed = true;
1356 UpdateMRL( DISC_ACCESS );
1361 /* Return true if *psz_drive is a drive with a DVD in it. A more complete
1362 check would see if the media looks like a *playable* DVD. This should
1365 static bool IsDVD(const char *psz_drive)
1367 CdIo_t *p_cdio = cdio_open (psz_drive, DRIVER_UNKNOWN);
1370 discmode_t discmode = cdio_get_discmode(p_cdio);
1371 cdio_destroy(p_cdio);
1372 return cdio_is_discmode_dvd(discmode);
1378 /* Return a device that has a DVD in it. The caller needs to free
1379 the returned string.
1381 static char * ProbeDVD(const wxChar *device)
1384 char **ppsz_cd_drives;
1385 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1386 char *psz_device = (char *) tmp_buf;
1388 if( IsDVD(psz_device) )
1390 return strdup(psz_device);
1393 ppsz_cd_drives = cdio_get_devices(DRIVER_DEVICE);
1394 if( ppsz_cd_drives )
1397 for( c = ppsz_cd_drives; *c != NULL; c++ )
1401 char *psz_drive = strdup(*c);
1402 cdio_free_device_list(ppsz_cd_drives);
1403 return strdup(psz_drive);
1406 cdio_free_device_list(ppsz_cd_drives);
1412 static char * ProbeDevice(char **ppsz_search_devices, cdio_fs_anal_t mask,
1415 char **ppsz_devices;
1417 if( ppsz_search_devices && !ppsz_search_devices[0] )
1418 ppsz_search_devices = NULL;
1420 /* Start out trying the device that has been entered so far. */
1421 ppsz_devices = cdio_get_devices_with_cap(ppsz_search_devices, mask,
1424 if (ppsz_devices && *ppsz_devices)
1426 char *psz_device = strdup(*ppsz_devices);
1427 cdio_free_device_list(ppsz_devices);
1431 /* If there was no device specified on the first try, then give up
1432 now. Otherwise accept any CD-ROM in the class (e.g. VCD or DVD).
1434 if( !ppsz_search_devices ) return NULL;
1436 ppsz_devices = cdio_get_devices_with_cap(NULL, mask, true);
1438 if (ppsz_devices && *ppsz_devices)
1440 char *psz_device = strdup(*ppsz_devices);
1441 cdio_free_device_list(ppsz_devices);
1449 /* Return a device that has a CD-DA in it. The caller needs to free
1450 the returned string.
1452 static char * ProbeCDDA(const wxChar *device)
1455 char *ppsz_device[2];
1456 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1457 char *psz_device = (char *) tmp_buf;
1458 ppsz_device[0] = (device && *device) ? psz_device : NULL;
1459 ppsz_device[1] = NULL;
1460 return ProbeDevice(ppsz_device, CDIO_FS_AUDIO, false);
1464 /* Return a device that has a VCD in it. The caller needs to free
1465 the returned string.
1467 static char * ProbeVCD(const wxChar *device)
1469 char *ppsz_device[2];
1470 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1471 char *psz_device = (char *) tmp_buf;
1472 ppsz_device[0] = (device && *device) ? psz_device : NULL;
1473 ppsz_device[1] = NULL;
1474 return ProbeDevice(ppsz_device,
1475 (CDIO_FS_ANAL_SVCD|CDIO_FS_ANAL_CVD|CDIO_FS_ANAL_VIDEOCD
1476 |CDIO_FS_UNKNOWN), true);
1482 Probe (find anywhere) a CD-DA, VCD, or a DVD.
1483 First try the device name that may have been entered for the "disc type"
1484 selected. If that doesn't work we try any device for the disc type.
1485 If that doesn't work, try looking for CD-ROMs or DVD drives. the
1486 disc type, device name and paramter ranges are set to whatever we find.
1488 void OpenDialog::OnDiscProbe( wxCommandEvent& WXUNUSED(event) )
1490 wxCommandEvent dummy_event;
1491 char *psz_device = NULL;
1492 bool b_probed_DVD = false;
1493 bool b_probed_VCD = false;
1494 const int i_selection = disc_type->GetSelection();
1496 /* Reduce verbosity of cdio errors. */
1497 cdio_loglevel_default = CDIO_LOG_ERROR;
1500 switch( disc_type->GetSelection() )
1503 case SELECTION_DISC_TYPE_DVD_MENUS:
1504 case SELECTION_DISC_TYPE_DVD:
1505 /* If not a DVD then try for a VCD. If VCD fails it will
1507 if (!psz_device) psz_device = ProbeDVD(disc_device->GetValue());
1510 b_probed_DVD = true;
1511 disc_type->SetSelection(SELECTION_DISC_TYPE_VCD);
1512 OnDiscTypeChange( dummy_event );
1515 disc_device->SetValue( wxL2U(psz_device) );
1518 case SELECTION_DISC_TYPE_VCD: /* VCD probe of some sort */
1519 if(!psz_device) psz_device = ProbeVCD(disc_device->GetValue());
1523 #if LIBVCD_VERSION_NUM > 23
1524 vcdinfo_obj_t *p_vcdinfo;
1526 /* Set LID or entry range accurately if possible. */
1527 if( vcdinfo_open(&p_vcdinfo, &psz_device, DRIVER_DEVICE,
1528 NULL) == VCDINFO_OPEN_VCD)
1530 if (config_GetInt( p_intf, "vcdx-PBC" ))
1532 /* Set largest LID. */;
1533 disc_title->SetRange( 0, vcdinfo_get_num_LIDs(p_vcdinfo) );
1538 /* Set largest Entry */
1539 disc_title->SetRange( 0,
1540 vcdinfo_get_num_entries(p_vcdinfo)-1 );
1542 vcdinfo_close(p_vcdinfo);
1544 #endif /* LIBVCD_VERSION_NUM > 23 */
1545 disc_device->SetValue( wxL2U(psz_device) );
1547 CdIo_t *p_cdio = cdio_open (psz_device, DRIVER_UNKNOWN);
1548 disc_device->SetValue( wxL2U(psz_device) );
1550 /* Set track range accurately if possible. */
1553 track_t i_last_track = cdio_get_last_track_num(p_cdio);
1554 disc_title->SetRange( 0, i_last_track-1 );
1556 cdio_destroy(p_cdio);
1561 b_probed_VCD = true;
1563 /* Not a VCD. Try for a DVD unless we've been there before. */
1564 if( !b_probed_DVD && (psz_device = ProbeDVD(disc_device->GetValue())) )
1566 disc_type->SetSelection(SELECTION_DISC_TYPE_DVD_MENUS);
1567 OnDiscTypeChange( dummy_event );
1570 b_probed_DVD = true;
1572 /* Couldn't find a VCD or DVD. See if we can find a CD-DA. */
1573 psz_device = ProbeCDDA(disc_device->GetValue());
1576 disc_type->SetSelection(SELECTION_DISC_TYPE_CDDA);
1577 OnDiscTypeChange( dummy_event );
1581 /* Couldn't find a VCD, DVD or CD-DA. Null out the Device name and
1582 set to original selection.
1584 disc_device->SetValue( wxL2U("") );
1585 disc_type->SetSelection(i_selection);
1586 OnDiscTypeChange( dummy_event );
1589 case SELECTION_DISC_TYPE_CDDA:
1590 if(!psz_device) psz_device = ProbeCDDA(disc_device->GetValue());
1593 CdIo_t *p_cdio = cdio_open (psz_device, DRIVER_UNKNOWN);
1594 disc_device->SetValue( wxL2U(psz_device) );
1597 track_t i_last_track = cdio_get_last_track_num(p_cdio);
1598 disc_title->SetRange( 0, i_last_track );
1600 MediaInsertCDDA( p_intf, p_cdio, i_last_track );
1603 cdio_destroy(p_cdio);
1607 /* Not a CD-DA. Try for a DVD unless we've been there before. */
1608 if( !b_probed_DVD && (psz_device = ProbeDVD(disc_device->GetValue())) )
1610 disc_type->SetSelection(SELECTION_DISC_TYPE_DVD_MENUS);
1611 OnDiscTypeChange( dummy_event );
1615 /* Couldn't find a CD-DA or DVD. See if we can find a VCD, unless
1616 we've tried that before. */
1617 if (!b_probed_VCD) psz_device = ProbeVCD(disc_device->GetValue());
1620 disc_type->SetSelection(SELECTION_DISC_TYPE_VCD);
1621 OnDiscTypeChange( dummy_event );
1624 disc_device->SetValue( wxL2U("") );
1628 msg_Err( p_intf, "invalid Disc type selection (%d)",
1629 disc_type->GetSelection() );
1634 disc_probe->SetValue(FALSE);
1636 UpdateMRL( DISC_ACCESS );
1638 #endif /* HAVE_LIBCDIO */
1640 void OpenDialog::OnDiscTypeChange( wxCommandEvent& WXUNUSED(event) )
1642 char *psz_device = NULL;
1644 switch( disc_type->GetSelection() )
1647 case SELECTION_DISC_TYPE_DVD_MENUS:
1648 case SELECTION_DISC_TYPE_DVD:
1649 disc_sub->Enable(); disc_sub_label->Enable();
1650 disc_audio->Enable(); disc_audio_label->Enable();
1651 disc_chapter->Enable(); disc_chapter_label->Enable();
1652 disc_title_label->SetLabel ( wxU(_("Title")) );
1653 psz_device = config_GetPsz( p_intf, "dvd" );
1654 if( !b_disc_device_changed )
1656 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1657 else disc_device->SetValue( wxT("") );
1659 disc_title->SetRange( 0, 255 );
1660 disc_sub->SetRange( -1, 31 ); // up to 32 subtitles -1: no subtitle
1661 disc_audio->SetRange( 0, 7 ); // up to 8 audio channels
1662 disc_chapter->SetRange( 0, 255 );
1663 disc_title->SetToolTip( wxU(_("Title number.")) );
1664 disc_sub->SetToolTip( wxU(_(
1665 "DVDs can have up to 32 subtitles numbered 0..31. "
1666 "Note this is not the same thing as a subtitle name (e.g. 'en'). "
1667 "If a value -1 is used, no subtitle will be shown." )) );
1668 disc_audio->SetToolTip( wxU(_("Audio track number. "
1669 "DVDs can have up to 8 audio tracks numbered 0..7."
1673 case SELECTION_DISC_TYPE_VCD:
1674 disc_sub->Enable(); disc_sub_label->Enable();
1675 disc_audio->Enable(); disc_audio_label->Enable();
1676 disc_chapter->Disable(); disc_chapter_label->Disable();
1677 psz_device = config_GetPsz( p_intf, "vcd" );
1678 if( !b_disc_device_changed )
1680 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1681 else disc_device->SetValue( wxT("") );
1685 if (config_GetInt( p_intf, "vcdx-PBC" ))
1687 disc_title_label->SetLabel ( wxT("Playback LID") );
1688 disc_title->SetToolTip( wxU(_(
1689 "Playback control (PBC) usually starts with number 1." )) );
1693 disc_title_label->SetLabel ( wxT("Entry") );
1694 disc_title->SetToolTip( wxU(_(
1695 "The first entry (the beginning of the first MPEG track) is 0." )) );
1699 disc_title_label->SetLabel ( wxU(_("Track")) );
1700 disc_title->SetToolTip( wxU(_("Track number.")) );
1702 disc_title->SetRange( 0, 99 ); // only 100 tracks allowed on VCDs
1703 disc_sub->SetRange( -1, 3 ); // up to 4 subtitles -1 = no subtitle
1704 disc_audio->SetRange( 0, 1 ); // up to 2 audio tracks
1705 disc_sub->SetToolTip( wxU(_(
1706 "SVCDs can have up to 4 subtitles numbered 0..3. "
1707 "If a value -1 is used, no subtitle will be shown." )) );
1708 disc_audio->SetToolTip( wxU(_("Audio track number. "
1709 "VCDs can have up to 2 audio tracks numbered 0 or 1. "
1713 case SELECTION_DISC_TYPE_CDDA:
1714 disc_sub->Disable(); disc_sub_label->Disable();
1715 disc_chapter->Disable(); disc_chapter_label->Disable();
1716 disc_audio->Disable(); disc_audio_label->Disable();
1717 disc_title_label->SetLabel ( wxU(_("Track")) );
1719 disc_title->SetToolTip( wxU(_(
1720 "Audio CDs can have up to 100 tracks, the first track is usually 1. "
1721 "If 0 is given, then all tracks are played.")) );
1723 disc_title->SetToolTip( wxU(_(
1724 "Audio CDs can have up to 100 tracks, the first track is usually 1."
1727 psz_device = config_GetPsz( p_intf, "cd-audio" );
1728 if( !b_disc_device_changed )
1730 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1731 else disc_device->SetValue( wxT("") );
1734 /* There are at most 100 tracks in a CD-DA */
1735 disc_title->SetRange( 0, 100 );
1739 msg_Err( p_intf, "invalid Disc type selection (%d)",
1740 disc_type->GetSelection() );
1744 disc_title->SetValue( 0 ); i_disc_title = 0;
1745 disc_chapter->SetValue( 0 ); i_disc_chapter = 0;
1749 UpdateMRL( DISC_ACCESS );
1752 /*****************************************************************************
1753 * Net panel event methods.
1754 *****************************************************************************/
1755 void OpenDialog::OnNetPanelChangeSpin( wxSpinEvent& event )
1757 wxCommandEvent cevent;
1758 cevent.SetId(event.GetId());
1759 cevent.SetInt(event.GetPosition());
1760 OnNetPanelChange(cevent);
1763 void OpenDialog::OnNetPanelChange( wxCommandEvent& event )
1765 if( event.GetId() >= NetPort1_Event && event.GetId() <= NetPort3_Event )
1767 i_net_ports[event.GetId() - NetPort1_Event] = event.GetInt();
1770 UpdateMRL( NET_ACCESS );
1773 void OpenDialog::OnNetTypeChange( wxCommandEvent& event )
1777 i_net_type = event.GetId() - NetRadio1_Event;
1781 net_radios[i]->SetValue( event.GetId() == (NetRadio1_Event+i) );
1782 net_subpanels[i]->Enable( event.GetId() == (NetRadio1_Event+i) );
1784 /* UDP Unicast or multicast -> timeshift */
1785 if( i_net_type == 0 || i_net_type == 1 )
1786 net_timeshift->Enable();
1788 net_timeshift->Disable();
1790 UpdateMRL( NET_ACCESS );
1793 /*****************************************************************************
1794 * Subtitles file event methods.
1795 *****************************************************************************/
1796 void OpenDialog::OnSubsFileEnable( wxCommandEvent& event )
1798 subsfile_button->Enable( event.GetInt() != 0 );
1799 subbrowse_button->Enable( event.GetInt() != 0 );
1800 subfile_combo->Enable( event.GetInt() != 0 );
1803 void OpenDialog::OnSubsFileSettings( wxCommandEvent& WXUNUSED(event) )
1805 /* Show/hide the open dialog */
1806 if( subsfile_dialog == NULL )
1807 subsfile_dialog = new SubsFileDialog( p_intf, this );
1809 if( subsfile_dialog && subsfile_dialog->ShowModal() == wxID_OK )
1811 subsfile_mrl.Empty();
1812 subsfile_mrl.Add( wxString(wxT("sub-file=")) + subfile_combo->GetValue() );
1813 if( subsfile_dialog->encoding_combo )
1815 subsfile_mrl.Add( wxString(wxT("subsdec-encoding=")) +
1816 subsfile_dialog->encoding_combo->GetValue() );
1818 if( subsfile_dialog->align_combo )
1820 subsfile_mrl.Add( wxString::Format(wxT("subsdec-align=%i"),
1821 (int)subsfile_dialog->align_combo->GetClientData(
1822 subsfile_dialog->align_combo->GetSelection()) ) );
1824 if( subsfile_dialog->size_combo )
1826 subsfile_mrl.Add( wxString::Format( wxT("freetype-rel-fontsize=%i"),
1827 (int)subsfile_dialog->size_combo->GetClientData(
1828 subsfile_dialog->size_combo->GetSelection()) ) );
1830 subsfile_mrl.Add( wxString( wxT("sub-fps="))+
1831 subsfile_dialog->fps_ctrl->GetValue() );
1832 subsfile_mrl.Add( wxString::Format( wxT("sub-delay=%i"),
1833 subsfile_dialog->delay_spinctrl->GetValue() ) );
1837 /*****************************************************************************
1838 * Stream output event methods.
1839 *****************************************************************************/
1840 void OpenDialog::OnSoutEnable( wxCommandEvent& event )
1842 sout_button->Enable( event.GetInt() != 0 );
1845 void OpenDialog::OnSoutSettings( wxCommandEvent& WXUNUSED(event) )
1847 /* Show/hide the open dialog */
1848 if( sout_dialog == NULL )
1849 sout_dialog = new SoutDialog( p_intf, this );
1851 if( sout_dialog && sout_dialog->ShowModal() == wxID_OK )
1853 sout_mrl = sout_dialog->GetOptions();
1857 /*****************************************************************************
1858 * Caching event methods.
1859 *****************************************************************************/
1860 void OpenDialog::OnCachingEnable( wxCommandEvent& event )
1862 caching_value->Enable( event.GetInt() != 0 );
1863 i_caching = caching_value->GetValue();
1867 void OpenDialog::OnCachingChangeSpin( wxSpinEvent& event )
1869 wxCommandEvent cevent;
1870 OnCachingChange(cevent);
1873 void OpenDialog::OnCachingChange( wxCommandEvent& event )
1875 i_caching = event.GetInt();
1879 /*****************************************************************************
1880 * Utility functions.
1881 *****************************************************************************/
1882 wxArrayString SeparateEntries( wxString entries )
1884 bool b_quotes_mode = false;
1886 wxArrayString entries_array;
1889 wxStringTokenizer token( entries, wxT(" \t\r\n\""), wxTOKEN_RET_DELIMS );
1891 while( token.HasMoreTokens() )
1893 entry += token.GetNextToken();
1895 if( entry.IsEmpty() ) continue;
1897 if( !b_quotes_mode && entry.Last() == wxT('\"') )
1899 /* Enters quotes mode */
1901 b_quotes_mode = true;
1903 else if( b_quotes_mode && entry.Last() == wxT('\"') )
1905 /* Finished the quotes mode */
1907 b_quotes_mode = false;
1909 else if( !b_quotes_mode && entry.Last() != wxT('\"') )
1911 /* we found a non-quoted standalone string */
1912 if( token.HasMoreTokens() ||
1913 entry.Last() == wxT(' ') || entry.Last() == wxT('\t') ||
1914 entry.Last() == wxT('\r') || entry.Last() == wxT('\n') )
1916 if( !entry.IsEmpty() ) entries_array.Add( entry );
1923 if( !entry.IsEmpty() ) entries_array.Add( entry );
1925 return entries_array;