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) );
447 if( psz_sout ) free( 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()
591 if( file_dialog ) delete file_dialog;
592 if( sout_dialog ) delete sout_dialog;
593 if( subsfile_dialog ) 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 if( psz_subsfile ) 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 =
1162 (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
1164 if( p_playlist == NULL ) return;
1166 for( int i = 0; i < (int)mrl.GetCount(); i++ )
1168 vlc_bool_t b_start = !i && i_open_arg;
1169 input_item_t *p_input;
1172 psz_utf8 = wxFromLocale( mrl[i] );
1173 p_input = input_ItemNew( p_intf, psz_utf8, NULL );
1174 wxLocaleFree( psz_utf8 );
1176 /* Insert options */
1177 while( i + 1 < (int)mrl.GetCount() &&
1178 ((const char *)mrl[i + 1].mb_str(wxConvUTF8))[0] == ':' )
1180 psz_utf8 = wxFromLocale( mrl[i + 1] );
1181 input_ItemAddOption( p_input, psz_utf8 );
1182 wxLocaleFree( psz_utf8 );
1186 /* Get the options from the subtitles dialog */
1187 if( subsfile_checkbox->IsChecked() && subsfile_mrl.GetCount() )
1189 for( int j = 0; j < (int)subsfile_mrl.GetCount(); j++ )
1191 psz_utf8 = wxFromLocale( subsfile_mrl[j] );
1192 input_ItemAddOption( p_input, psz_utf8 );
1193 wxLocaleFree( psz_utf8 );
1197 /* Get the options from the stream output dialog */
1198 if( sout_checkbox->IsChecked() && sout_mrl.GetCount() )
1200 for( int j = 0; j < (int)sout_mrl.GetCount(); j++ )
1202 psz_utf8 = wxFromLocale( sout_mrl[j] );
1203 input_ItemAddOption( p_input, psz_utf8 );
1204 wxLocaleFree( psz_utf8 );
1210 playlist_AddInput( p_playlist, p_input,
1211 PLAYLIST_APPEND | PLAYLIST_GO,
1212 PLAYLIST_END, VLC_TRUE, VLC_FALSE );
1216 playlist_AddInput( p_playlist, p_input,
1217 PLAYLIST_APPEND|PLAYLIST_PREPARSE,
1218 PLAYLIST_END, VLC_TRUE, VLC_FALSE );
1222 vlc_object_release( p_playlist );
1226 if( IsModal() ) EndModal( wxID_OK );
1229 void OpenDialog::OnCancel( wxCommandEvent& WXUNUSED(event) )
1231 wxCloseEvent cevent;
1235 void OpenDialog::OnClose( wxCloseEvent& WXUNUSED(event) )
1239 if( IsModal() ) EndModal( wxID_CANCEL );
1242 void OpenDialog::OnPageChange( wxNotebookEvent& event )
1244 UpdateMRL( event.GetSelection() );
1247 void OpenDialog::OnMRLChange( wxCommandEvent& event )
1249 //mrl = SeparateEntries( event.GetString() );
1252 /*****************************************************************************
1253 * File panel event methods.
1254 *****************************************************************************/
1255 void OpenDialog::OnFilePanelChange( wxCommandEvent& WXUNUSED(event) )
1257 UpdateMRL( FILE_ACCESS );
1260 void OpenDialog::OnFileBrowse( wxCommandEvent& WXUNUSED(event) )
1262 if( file_dialog == NULL )
1263 file_dialog = new wxFileDialog( this, wxU(_("Open File")),
1264 wxT(""), wxT(""), wxT("*"), wxOPEN | wxMULTIPLE );
1266 file_dialog->SetWildcard(wxU(_("All Files (*.*)|*"
1267 "|Sound Files (*.mp3, *.ogg, etc.)|" EXTENSIONS_AUDIO
1268 "|Video Files (*.avi, *.mpg, etc.)|" EXTENSIONS_VIDEO
1269 "|Playlist Files (*.m3u, *.pls, etc.)|" EXTENSIONS_PLAYLIST
1270 "|Subtitle Files (*.srt, *.sub, etc.)|" EXTENSIONS_SUBTITLE)));
1272 if( file_dialog && file_dialog->ShowModal() == wxID_OK )
1274 wxArrayString paths;
1277 file_dialog->GetPaths( paths );
1279 for( size_t i = 0; i < paths.GetCount(); i++ )
1281 if( paths[i].Find( wxT(' ') ) >= 0 )
1282 path += wxT("\"") + paths[i] + wxT("\" ");
1284 path += paths[i] + wxT(" ");
1287 file_combo->SetValue( path );
1288 file_combo->Append( path );
1289 if( file_combo->GetCount() > 10 ) file_combo->Delete( 0 );
1290 UpdateMRL( FILE_ACCESS );
1294 void OpenDialog::OnSubFileBrowse( wxCommandEvent& WXUNUSED(event) )
1296 wxFileDialog dialog( this, wxU(_("Open subtitles file")),
1297 wxT(""), wxT(""), wxT("*"), wxOPEN );
1299 if( dialog.ShowModal() == wxID_OK )
1301 subfile_combo->SetValue( dialog.GetPath() );
1303 wxCommandEvent event; OnSubFileChange( event );
1306 void OpenDialog::OnSubFileChange( wxCommandEvent& WXUNUSED(event) )
1308 if( subsfile_mrl.GetCount() != 0 )
1310 subsfile_mrl.RemoveAt( 0 );
1311 subsfile_mrl.Insert( wxString(wxT("sub-file=")) + subfile_combo->GetValue() , 0 );
1315 subsfile_mrl.Add( wxString(wxT("sub-file=")) + subfile_combo->GetValue() );
1319 /*****************************************************************************
1320 * Disc panel event methods.
1321 *****************************************************************************/
1322 void OpenDialog::OnDiscPanelChangeSpin( wxSpinEvent& event )
1324 wxCommandEvent cevent;
1325 cevent.SetId(event.GetId());
1326 cevent.SetInt(event.GetPosition());
1327 OnDiscPanelChange(cevent);
1330 void OpenDialog::OnDiscPanelChange( wxCommandEvent& event )
1332 if( event.GetId() == DiscTitle_Event ) i_disc_title = event.GetInt();
1333 if( event.GetId() == DiscChapter_Event ) i_disc_chapter = event.GetInt();
1334 if( event.GetId() == DiscSub_Event ) i_disc_sub = event.GetInt();
1335 if( event.GetId() == DiscAudio_Event ) i_disc_audio = event.GetInt();
1337 UpdateMRL( DISC_ACCESS );
1340 void OpenDialog::OnDiscDeviceChange( wxCommandEvent& event )
1344 switch( disc_type->GetSelection() )
1347 psz_device = config_GetPsz( p_intf, "cd-audio" );
1351 psz_device = config_GetPsz( p_intf, "vcd" );
1355 psz_device = config_GetPsz( p_intf, "dvd" );
1359 if ( !psz_device ) psz_device = "";
1361 if( disc_device->GetValue().Cmp( wxL2U( psz_device ) ) )
1363 b_disc_device_changed = true;
1366 UpdateMRL( DISC_ACCESS );
1371 /* Return true if *psz_drive is a drive with a DVD in it. A more complete
1372 check would see if the media looks like a *playable* DVD. This should
1375 static bool IsDVD(const char *psz_drive)
1377 CdIo_t *p_cdio = cdio_open (psz_drive, DRIVER_UNKNOWN);
1380 discmode_t discmode = cdio_get_discmode(p_cdio);
1381 cdio_destroy(p_cdio);
1382 return cdio_is_discmode_dvd(discmode);
1388 /* Return a device that has a DVD in it. The caller needs to free
1389 the returned string.
1391 static char * ProbeDVD(const wxChar *device)
1394 char **ppsz_cd_drives;
1395 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1396 char *psz_device = (char *) tmp_buf;
1398 if( IsDVD(psz_device) )
1400 return strdup(psz_device);
1403 ppsz_cd_drives = cdio_get_devices(DRIVER_DEVICE);
1404 if( ppsz_cd_drives )
1407 for( c = ppsz_cd_drives; *c != NULL; c++ )
1411 char *psz_drive = strdup(*c);
1412 cdio_free_device_list(ppsz_cd_drives);
1413 return strdup(psz_drive);
1416 cdio_free_device_list(ppsz_cd_drives);
1422 static char * ProbeDevice(char **ppsz_search_devices, cdio_fs_anal_t mask,
1425 char **ppsz_devices;
1427 if( ppsz_search_devices && !ppsz_search_devices[0] )
1428 ppsz_search_devices = NULL;
1430 /* Start out trying the device that has been entered so far. */
1431 ppsz_devices = cdio_get_devices_with_cap(ppsz_search_devices, mask,
1434 if (ppsz_devices && *ppsz_devices)
1436 char *psz_device = strdup(*ppsz_devices);
1437 cdio_free_device_list(ppsz_devices);
1441 /* If there was no device specified on the first try, then give up
1442 now. Otherwise accept any CD-ROM in the class (e.g. VCD or DVD).
1444 if( !ppsz_search_devices ) return NULL;
1446 ppsz_devices = cdio_get_devices_with_cap(NULL, mask, true);
1448 if (ppsz_devices && *ppsz_devices)
1450 char *psz_device = strdup(*ppsz_devices);
1451 cdio_free_device_list(ppsz_devices);
1459 /* Return a device that has a CD-DA in it. The caller needs to free
1460 the returned string.
1462 static char * ProbeCDDA(const wxChar *device)
1465 char *ppsz_device[2];
1466 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1467 char *psz_device = (char *) tmp_buf;
1468 ppsz_device[0] = (device && *device) ? psz_device : NULL;
1469 ppsz_device[1] = NULL;
1470 return ProbeDevice(ppsz_device, CDIO_FS_AUDIO, false);
1474 /* Return a device that has a VCD in it. The caller needs to free
1475 the returned string.
1477 static char * ProbeVCD(const wxChar *device)
1479 char *ppsz_device[2];
1480 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1481 char *psz_device = (char *) tmp_buf;
1482 ppsz_device[0] = (device && *device) ? psz_device : NULL;
1483 ppsz_device[1] = NULL;
1484 return ProbeDevice(ppsz_device,
1485 (CDIO_FS_ANAL_SVCD|CDIO_FS_ANAL_CVD|CDIO_FS_ANAL_VIDEOCD
1486 |CDIO_FS_UNKNOWN), true);
1492 Probe (find anywhere) a CD-DA, VCD, or a DVD.
1493 First try the device name that may have been entered for the "disc type"
1494 selected. If that doesn't work we try any device for the disc type.
1495 If that doesn't work, try looking for CD-ROMs or DVD drives. the
1496 disc type, device name and paramter ranges are set to whatever we find.
1498 void OpenDialog::OnDiscProbe( wxCommandEvent& WXUNUSED(event) )
1500 wxCommandEvent dummy_event;
1501 char *psz_device = NULL;
1502 bool b_probed_DVD = false;
1503 bool b_probed_VCD = false;
1504 const int i_selection = disc_type->GetSelection();
1506 /* Reduce verbosity of cdio errors. */
1507 cdio_loglevel_default = CDIO_LOG_ERROR;
1510 switch( disc_type->GetSelection() )
1513 case SELECTION_DISC_TYPE_DVD_MENUS:
1514 case SELECTION_DISC_TYPE_DVD:
1515 /* If not a DVD then try for a VCD. If VCD fails it will
1517 if (!psz_device) psz_device = ProbeDVD(disc_device->GetValue());
1520 b_probed_DVD = true;
1521 disc_type->SetSelection(SELECTION_DISC_TYPE_VCD);
1522 OnDiscTypeChange( dummy_event );
1525 disc_device->SetValue( wxL2U(psz_device) );
1528 case SELECTION_DISC_TYPE_VCD: /* VCD probe of some sort */
1529 if(!psz_device) psz_device = ProbeVCD(disc_device->GetValue());
1533 #if LIBVCD_VERSION_NUM > 23
1534 vcdinfo_obj_t *p_vcdinfo;
1536 /* Set LID or entry range accurately if possible. */
1537 if( vcdinfo_open(&p_vcdinfo, &psz_device, DRIVER_DEVICE,
1538 NULL) == VCDINFO_OPEN_VCD)
1540 if (config_GetInt( p_intf, "vcdx-PBC" ))
1542 /* Set largest LID. */;
1543 disc_title->SetRange( 0, vcdinfo_get_num_LIDs(p_vcdinfo) );
1548 /* Set largest Entry */
1549 disc_title->SetRange( 0,
1550 vcdinfo_get_num_entries(p_vcdinfo)-1 );
1552 vcdinfo_close(p_vcdinfo);
1554 #endif /* LIBVCD_VERSION_NUM > 23 */
1555 disc_device->SetValue( wxL2U(psz_device) );
1557 CdIo_t *p_cdio = cdio_open (psz_device, DRIVER_UNKNOWN);
1558 disc_device->SetValue( wxL2U(psz_device) );
1560 /* Set track range accurately if possible. */
1563 track_t i_last_track = cdio_get_last_track_num(p_cdio);
1564 disc_title->SetRange( 0, i_last_track-1 );
1566 cdio_destroy(p_cdio);
1571 b_probed_VCD = true;
1573 /* Not a VCD. Try for a DVD unless we've been there before. */
1574 if( !b_probed_DVD && (psz_device = ProbeDVD(disc_device->GetValue())) )
1576 disc_type->SetSelection(SELECTION_DISC_TYPE_DVD_MENUS);
1577 OnDiscTypeChange( dummy_event );
1580 b_probed_DVD = true;
1582 /* Couldn't find a VCD or DVD. See if we can find a CD-DA. */
1583 psz_device = ProbeCDDA(disc_device->GetValue());
1586 disc_type->SetSelection(SELECTION_DISC_TYPE_CDDA);
1587 OnDiscTypeChange( dummy_event );
1591 /* Couldn't find a VCD, DVD or CD-DA. Null out the Device name and
1592 set to original selection.
1594 disc_device->SetValue( wxL2U("") );
1595 disc_type->SetSelection(i_selection);
1596 OnDiscTypeChange( dummy_event );
1599 case SELECTION_DISC_TYPE_CDDA:
1600 if(!psz_device) psz_device = ProbeCDDA(disc_device->GetValue());
1603 CdIo_t *p_cdio = cdio_open (psz_device, DRIVER_UNKNOWN);
1604 disc_device->SetValue( wxL2U(psz_device) );
1607 track_t i_last_track = cdio_get_last_track_num(p_cdio);
1608 disc_title->SetRange( 0, i_last_track );
1610 MediaInsertCDDA( p_intf, p_cdio, i_last_track );
1613 cdio_destroy(p_cdio);
1617 /* Not a CD-DA. Try for a DVD unless we've been there before. */
1618 if( !b_probed_DVD && (psz_device = ProbeDVD(disc_device->GetValue())) )
1620 disc_type->SetSelection(SELECTION_DISC_TYPE_DVD_MENUS);
1621 OnDiscTypeChange( dummy_event );
1625 /* Couldn't find a CD-DA or DVD. See if we can find a VCD, unless
1626 we've tried that before. */
1627 if (!b_probed_VCD) psz_device = ProbeVCD(disc_device->GetValue());
1630 disc_type->SetSelection(SELECTION_DISC_TYPE_VCD);
1631 OnDiscTypeChange( dummy_event );
1634 disc_device->SetValue( wxL2U("") );
1638 msg_Err( p_intf, "invalid Disc type selection (%d)",
1639 disc_type->GetSelection() );
1644 disc_probe->SetValue(FALSE);
1646 UpdateMRL( DISC_ACCESS );
1648 #endif /* HAVE_LIBCDIO */
1650 void OpenDialog::OnDiscTypeChange( wxCommandEvent& WXUNUSED(event) )
1652 char *psz_device = NULL;
1654 switch( disc_type->GetSelection() )
1657 case SELECTION_DISC_TYPE_DVD_MENUS:
1658 case SELECTION_DISC_TYPE_DVD:
1659 disc_sub->Enable(); disc_sub_label->Enable();
1660 disc_audio->Enable(); disc_audio_label->Enable();
1661 disc_chapter->Enable(); disc_chapter_label->Enable();
1662 disc_title_label->SetLabel ( wxU(_("Title")) );
1663 psz_device = config_GetPsz( p_intf, "dvd" );
1664 if( !b_disc_device_changed )
1666 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1667 else disc_device->SetValue( wxT("") );
1669 disc_title->SetRange( 0, 255 );
1670 disc_sub->SetRange( -1, 31 ); // up to 32 subtitles -1: no subtitle
1671 disc_audio->SetRange( 0, 7 ); // up to 8 audio channels
1672 disc_chapter->SetRange( 0, 255 );
1673 disc_title->SetToolTip( wxU(_("Title number.")) );
1674 disc_sub->SetToolTip( wxU(_(
1675 "DVDs can have up to 32 subtitles numbered 0..31. "
1676 "Note this is not the same thing as a subtitle name (e.g. 'en'). "
1677 "If a value -1 is used, no subtitle will be shown." )) );
1678 disc_audio->SetToolTip( wxU(_("Audio track number. "
1679 "DVDs can have up to 8 audio tracks numbered 0..7."
1683 case SELECTION_DISC_TYPE_VCD:
1684 disc_sub->Enable(); disc_sub_label->Enable();
1685 disc_audio->Enable(); disc_audio_label->Enable();
1686 disc_chapter->Disable(); disc_chapter_label->Disable();
1687 psz_device = config_GetPsz( p_intf, "vcd" );
1688 if( !b_disc_device_changed )
1690 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1691 else disc_device->SetValue( wxT("") );
1695 if (config_GetInt( p_intf, "vcdx-PBC" ))
1697 disc_title_label->SetLabel ( wxT("Playback LID") );
1698 disc_title->SetToolTip( wxU(_(
1699 "Playback control (PBC) usually starts with number 1." )) );
1703 disc_title_label->SetLabel ( wxT("Entry") );
1704 disc_title->SetToolTip( wxU(_(
1705 "The first entry (the beginning of the first MPEG track) is 0." )) );
1709 disc_title_label->SetLabel ( wxU(_("Track")) );
1710 disc_title->SetToolTip( wxU(_("Track number.")) );
1712 disc_title->SetRange( 0, 99 ); // only 100 tracks allowed on VCDs
1713 disc_sub->SetRange( -1, 3 ); // up to 4 subtitles -1 = no subtitle
1714 disc_audio->SetRange( 0, 1 ); // up to 2 audio tracks
1715 disc_sub->SetToolTip( wxU(_(
1716 "SVCDs can have up to 4 subtitles numbered 0..3. "
1717 "If a value -1 is used, no subtitle will be shown." )) );
1718 disc_audio->SetToolTip( wxU(_("Audio track number. "
1719 "VCDs can have up to 2 audio tracks numbered 0 or 1. "
1723 case SELECTION_DISC_TYPE_CDDA:
1724 disc_sub->Disable(); disc_sub_label->Disable();
1725 disc_chapter->Disable(); disc_chapter_label->Disable();
1726 disc_audio->Disable(); disc_audio_label->Disable();
1727 disc_title_label->SetLabel ( wxU(_("Track")) );
1729 disc_title->SetToolTip( wxU(_(
1730 "Audio CDs can have up to 100 tracks, the first track is usually 1. "
1731 "If 0 is given, then all tracks are played.")) );
1733 disc_title->SetToolTip( wxU(_(
1734 "Audio CDs can have up to 100 tracks, the first track is usually 1."
1737 psz_device = config_GetPsz( p_intf, "cd-audio" );
1738 if( !b_disc_device_changed )
1740 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1741 else disc_device->SetValue( wxT("") );
1744 /* There are at most 100 tracks in a CD-DA */
1745 disc_title->SetRange( 0, 100 );
1749 msg_Err( p_intf, "invalid Disc type selection (%d)",
1750 disc_type->GetSelection() );
1754 disc_title->SetValue( 0 ); i_disc_title = 0;
1755 disc_chapter->SetValue( 0 ); i_disc_chapter = 0;
1757 if( psz_device ) free( psz_device );
1759 UpdateMRL( DISC_ACCESS );
1762 /*****************************************************************************
1763 * Net panel event methods.
1764 *****************************************************************************/
1765 void OpenDialog::OnNetPanelChangeSpin( wxSpinEvent& event )
1767 wxCommandEvent cevent;
1768 cevent.SetId(event.GetId());
1769 cevent.SetInt(event.GetPosition());
1770 OnNetPanelChange(cevent);
1773 void OpenDialog::OnNetPanelChange( wxCommandEvent& event )
1775 if( event.GetId() >= NetPort1_Event && event.GetId() <= NetPort3_Event )
1777 i_net_ports[event.GetId() - NetPort1_Event] = event.GetInt();
1780 UpdateMRL( NET_ACCESS );
1783 void OpenDialog::OnNetTypeChange( wxCommandEvent& event )
1787 i_net_type = event.GetId() - NetRadio1_Event;
1791 net_radios[i]->SetValue( event.GetId() == (NetRadio1_Event+i) );
1792 net_subpanels[i]->Enable( event.GetId() == (NetRadio1_Event+i) );
1794 /* UDP Unicast or multicast -> timeshift */
1795 if( i_net_type == 0 || i_net_type == 1 )
1796 net_timeshift->Enable();
1798 net_timeshift->Disable();
1800 UpdateMRL( NET_ACCESS );
1803 /*****************************************************************************
1804 * Subtitles file event methods.
1805 *****************************************************************************/
1806 void OpenDialog::OnSubsFileEnable( wxCommandEvent& event )
1808 subsfile_button->Enable( event.GetInt() != 0 );
1809 subbrowse_button->Enable( event.GetInt() != 0 );
1810 subfile_combo->Enable( event.GetInt() != 0 );
1813 void OpenDialog::OnSubsFileSettings( wxCommandEvent& WXUNUSED(event) )
1815 /* Show/hide the open dialog */
1816 if( subsfile_dialog == NULL )
1817 subsfile_dialog = new SubsFileDialog( p_intf, this );
1819 if( subsfile_dialog && subsfile_dialog->ShowModal() == wxID_OK )
1821 subsfile_mrl.Empty();
1822 subsfile_mrl.Add( wxString(wxT("sub-file=")) + subfile_combo->GetValue() );
1823 if( subsfile_dialog->encoding_combo )
1825 subsfile_mrl.Add( wxString(wxT("subsdec-encoding=")) +
1826 subsfile_dialog->encoding_combo->GetValue() );
1828 if( subsfile_dialog->align_combo )
1830 subsfile_mrl.Add( wxString::Format(wxT("subsdec-align=%i"),
1831 (int)subsfile_dialog->align_combo->GetClientData(
1832 subsfile_dialog->align_combo->GetSelection()) ) );
1834 if( subsfile_dialog->size_combo )
1836 subsfile_mrl.Add( wxString::Format( wxT("freetype-rel-fontsize=%i"),
1837 (int)subsfile_dialog->size_combo->GetClientData(
1838 subsfile_dialog->size_combo->GetSelection()) ) );
1840 subsfile_mrl.Add( wxString( wxT("sub-fps="))+
1841 subsfile_dialog->fps_ctrl->GetValue() );
1842 subsfile_mrl.Add( wxString::Format( wxT("sub-delay=%i"),
1843 subsfile_dialog->delay_spinctrl->GetValue() ) );
1847 /*****************************************************************************
1848 * Stream output event methods.
1849 *****************************************************************************/
1850 void OpenDialog::OnSoutEnable( wxCommandEvent& event )
1852 sout_button->Enable( event.GetInt() != 0 );
1855 void OpenDialog::OnSoutSettings( wxCommandEvent& WXUNUSED(event) )
1857 /* Show/hide the open dialog */
1858 if( sout_dialog == NULL )
1859 sout_dialog = new SoutDialog( p_intf, this );
1861 if( sout_dialog && sout_dialog->ShowModal() == wxID_OK )
1863 sout_mrl = sout_dialog->GetOptions();
1867 /*****************************************************************************
1868 * Caching event methods.
1869 *****************************************************************************/
1870 void OpenDialog::OnCachingEnable( wxCommandEvent& event )
1872 caching_value->Enable( event.GetInt() != 0 );
1873 i_caching = caching_value->GetValue();
1877 void OpenDialog::OnCachingChangeSpin( wxSpinEvent& event )
1879 wxCommandEvent cevent;
1880 OnCachingChange(cevent);
1883 void OpenDialog::OnCachingChange( wxCommandEvent& event )
1885 i_caching = event.GetInt();
1889 /*****************************************************************************
1890 * Utility functions.
1891 *****************************************************************************/
1892 wxArrayString SeparateEntries( wxString entries )
1894 vlc_bool_t b_quotes_mode = VLC_FALSE;
1896 wxArrayString entries_array;
1899 wxStringTokenizer token( entries, wxT(" \t\r\n\""), wxTOKEN_RET_DELIMS );
1901 while( token.HasMoreTokens() )
1903 entry += token.GetNextToken();
1905 if( entry.IsEmpty() ) continue;
1907 if( !b_quotes_mode && entry.Last() == wxT('\"') )
1909 /* Enters quotes mode */
1911 b_quotes_mode = VLC_TRUE;
1913 else if( b_quotes_mode && entry.Last() == wxT('\"') )
1915 /* Finished the quotes mode */
1917 b_quotes_mode = VLC_FALSE;
1919 else if( !b_quotes_mode && entry.Last() != wxT('\"') )
1921 /* we found a non-quoted standalone string */
1922 if( token.HasMoreTokens() ||
1923 entry.Last() == wxT(' ') || entry.Last() == wxT('\t') ||
1924 entry.Last() == wxT('\r') || entry.Last() == wxT('\n') )
1926 if( !entry.IsEmpty() ) entries_array.Add( entry );
1933 if( !entry.IsEmpty() ) entries_array.Add( entry );
1935 return entries_array;