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 =
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 );
1208 /* FIXME: playlist_AddInput() can fail */
1209 playlist_AddInput( p_playlist, p_input,
1210 PLAYLIST_APPEND | ( b_start ? PLAYLIST_GO : PLAYLIST_PREPARSE ),
1211 PLAYLIST_END, VLC_TRUE, VLC_FALSE );
1214 vlc_object_release( p_playlist );
1218 if( IsModal() ) EndModal( wxID_OK );
1221 void OpenDialog::OnCancel( wxCommandEvent& WXUNUSED(event) )
1223 wxCloseEvent cevent;
1227 void OpenDialog::OnClose( wxCloseEvent& WXUNUSED(event) )
1231 if( IsModal() ) EndModal( wxID_CANCEL );
1234 void OpenDialog::OnPageChange( wxNotebookEvent& event )
1236 UpdateMRL( event.GetSelection() );
1239 void OpenDialog::OnMRLChange( wxCommandEvent& event )
1241 //mrl = SeparateEntries( event.GetString() );
1244 /*****************************************************************************
1245 * File panel event methods.
1246 *****************************************************************************/
1247 void OpenDialog::OnFilePanelChange( wxCommandEvent& WXUNUSED(event) )
1249 UpdateMRL( FILE_ACCESS );
1252 void OpenDialog::OnFileBrowse( wxCommandEvent& WXUNUSED(event) )
1254 if( file_dialog == NULL )
1255 file_dialog = new wxFileDialog( this, wxU(_("Open File")),
1256 wxT(""), wxT(""), wxT("*"), wxOPEN | wxMULTIPLE );
1258 file_dialog->SetWildcard(wxU(_("All Files (*.*)|*"
1259 "|Sound Files (*.mp3, *.ogg, etc.)|" EXTENSIONS_AUDIO
1260 "|Video Files (*.avi, *.mpg, etc.)|" EXTENSIONS_VIDEO
1261 "|Playlist Files (*.m3u, *.pls, etc.)|" EXTENSIONS_PLAYLIST
1262 "|Subtitle Files (*.srt, *.sub, etc.)|" EXTENSIONS_SUBTITLE)));
1264 if( file_dialog && file_dialog->ShowModal() == wxID_OK )
1266 wxArrayString paths;
1269 file_dialog->GetPaths( paths );
1271 for( size_t i = 0; i < paths.GetCount(); i++ )
1273 if( paths[i].Find( wxT(' ') ) >= 0 )
1274 path += wxT("\"") + paths[i] + wxT("\" ");
1276 path += paths[i] + wxT(" ");
1279 file_combo->SetValue( path );
1280 file_combo->Append( path );
1281 if( file_combo->GetCount() > 10 ) file_combo->Delete( 0 );
1282 UpdateMRL( FILE_ACCESS );
1286 void OpenDialog::OnSubFileBrowse( wxCommandEvent& WXUNUSED(event) )
1288 wxFileDialog dialog( this, wxU(_("Open subtitles file")),
1289 wxT(""), wxT(""), wxT("*"), wxOPEN );
1291 if( dialog.ShowModal() == wxID_OK )
1293 subfile_combo->SetValue( dialog.GetPath() );
1295 wxCommandEvent event; OnSubFileChange( event );
1298 void OpenDialog::OnSubFileChange( wxCommandEvent& WXUNUSED(event) )
1300 if( subsfile_mrl.GetCount() != 0 )
1302 subsfile_mrl.RemoveAt( 0 );
1303 subsfile_mrl.Insert( wxString(wxT("sub-file=")) + subfile_combo->GetValue() , 0 );
1307 subsfile_mrl.Add( wxString(wxT("sub-file=")) + subfile_combo->GetValue() );
1311 /*****************************************************************************
1312 * Disc panel event methods.
1313 *****************************************************************************/
1314 void OpenDialog::OnDiscPanelChangeSpin( wxSpinEvent& event )
1316 wxCommandEvent cevent;
1317 cevent.SetId(event.GetId());
1318 cevent.SetInt(event.GetPosition());
1319 OnDiscPanelChange(cevent);
1322 void OpenDialog::OnDiscPanelChange( wxCommandEvent& event )
1324 if( event.GetId() == DiscTitle_Event ) i_disc_title = event.GetInt();
1325 if( event.GetId() == DiscChapter_Event ) i_disc_chapter = event.GetInt();
1326 if( event.GetId() == DiscSub_Event ) i_disc_sub = event.GetInt();
1327 if( event.GetId() == DiscAudio_Event ) i_disc_audio = event.GetInt();
1329 UpdateMRL( DISC_ACCESS );
1332 void OpenDialog::OnDiscDeviceChange( wxCommandEvent& event )
1336 switch( disc_type->GetSelection() )
1339 psz_device = config_GetPsz( p_intf, "cd-audio" );
1343 psz_device = config_GetPsz( p_intf, "vcd" );
1347 psz_device = config_GetPsz( p_intf, "dvd" );
1351 if ( !psz_device ) psz_device = "";
1353 if( disc_device->GetValue().Cmp( wxL2U( psz_device ) ) )
1355 b_disc_device_changed = true;
1358 UpdateMRL( DISC_ACCESS );
1363 /* Return true if *psz_drive is a drive with a DVD in it. A more complete
1364 check would see if the media looks like a *playable* DVD. This should
1367 static bool IsDVD(const char *psz_drive)
1369 CdIo_t *p_cdio = cdio_open (psz_drive, DRIVER_UNKNOWN);
1372 discmode_t discmode = cdio_get_discmode(p_cdio);
1373 cdio_destroy(p_cdio);
1374 return cdio_is_discmode_dvd(discmode);
1380 /* Return a device that has a DVD in it. The caller needs to free
1381 the returned string.
1383 static char * ProbeDVD(const wxChar *device)
1386 char **ppsz_cd_drives;
1387 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1388 char *psz_device = (char *) tmp_buf;
1390 if( IsDVD(psz_device) )
1392 return strdup(psz_device);
1395 ppsz_cd_drives = cdio_get_devices(DRIVER_DEVICE);
1396 if( ppsz_cd_drives )
1399 for( c = ppsz_cd_drives; *c != NULL; c++ )
1403 char *psz_drive = strdup(*c);
1404 cdio_free_device_list(ppsz_cd_drives);
1405 return strdup(psz_drive);
1408 cdio_free_device_list(ppsz_cd_drives);
1414 static char * ProbeDevice(char **ppsz_search_devices, cdio_fs_anal_t mask,
1417 char **ppsz_devices;
1419 if( ppsz_search_devices && !ppsz_search_devices[0] )
1420 ppsz_search_devices = NULL;
1422 /* Start out trying the device that has been entered so far. */
1423 ppsz_devices = cdio_get_devices_with_cap(ppsz_search_devices, mask,
1426 if (ppsz_devices && *ppsz_devices)
1428 char *psz_device = strdup(*ppsz_devices);
1429 cdio_free_device_list(ppsz_devices);
1433 /* If there was no device specified on the first try, then give up
1434 now. Otherwise accept any CD-ROM in the class (e.g. VCD or DVD).
1436 if( !ppsz_search_devices ) return NULL;
1438 ppsz_devices = cdio_get_devices_with_cap(NULL, mask, true);
1440 if (ppsz_devices && *ppsz_devices)
1442 char *psz_device = strdup(*ppsz_devices);
1443 cdio_free_device_list(ppsz_devices);
1451 /* Return a device that has a CD-DA in it. The caller needs to free
1452 the returned string.
1454 static char * ProbeCDDA(const wxChar *device)
1457 char *ppsz_device[2];
1458 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1459 char *psz_device = (char *) tmp_buf;
1460 ppsz_device[0] = (device && *device) ? psz_device : NULL;
1461 ppsz_device[1] = NULL;
1462 return ProbeDevice(ppsz_device, CDIO_FS_AUDIO, false);
1466 /* Return a device that has a VCD in it. The caller needs to free
1467 the returned string.
1469 static char * ProbeVCD(const wxChar *device)
1471 char *ppsz_device[2];
1472 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1473 char *psz_device = (char *) tmp_buf;
1474 ppsz_device[0] = (device && *device) ? psz_device : NULL;
1475 ppsz_device[1] = NULL;
1476 return ProbeDevice(ppsz_device,
1477 (CDIO_FS_ANAL_SVCD|CDIO_FS_ANAL_CVD|CDIO_FS_ANAL_VIDEOCD
1478 |CDIO_FS_UNKNOWN), true);
1484 Probe (find anywhere) a CD-DA, VCD, or a DVD.
1485 First try the device name that may have been entered for the "disc type"
1486 selected. If that doesn't work we try any device for the disc type.
1487 If that doesn't work, try looking for CD-ROMs or DVD drives. the
1488 disc type, device name and paramter ranges are set to whatever we find.
1490 void OpenDialog::OnDiscProbe( wxCommandEvent& WXUNUSED(event) )
1492 wxCommandEvent dummy_event;
1493 char *psz_device = NULL;
1494 bool b_probed_DVD = false;
1495 bool b_probed_VCD = false;
1496 const int i_selection = disc_type->GetSelection();
1498 /* Reduce verbosity of cdio errors. */
1499 cdio_loglevel_default = CDIO_LOG_ERROR;
1502 switch( disc_type->GetSelection() )
1505 case SELECTION_DISC_TYPE_DVD_MENUS:
1506 case SELECTION_DISC_TYPE_DVD:
1507 /* If not a DVD then try for a VCD. If VCD fails it will
1509 if (!psz_device) psz_device = ProbeDVD(disc_device->GetValue());
1512 b_probed_DVD = true;
1513 disc_type->SetSelection(SELECTION_DISC_TYPE_VCD);
1514 OnDiscTypeChange( dummy_event );
1517 disc_device->SetValue( wxL2U(psz_device) );
1520 case SELECTION_DISC_TYPE_VCD: /* VCD probe of some sort */
1521 if(!psz_device) psz_device = ProbeVCD(disc_device->GetValue());
1525 #if LIBVCD_VERSION_NUM > 23
1526 vcdinfo_obj_t *p_vcdinfo;
1528 /* Set LID or entry range accurately if possible. */
1529 if( vcdinfo_open(&p_vcdinfo, &psz_device, DRIVER_DEVICE,
1530 NULL) == VCDINFO_OPEN_VCD)
1532 if (config_GetInt( p_intf, "vcdx-PBC" ))
1534 /* Set largest LID. */;
1535 disc_title->SetRange( 0, vcdinfo_get_num_LIDs(p_vcdinfo) );
1540 /* Set largest Entry */
1541 disc_title->SetRange( 0,
1542 vcdinfo_get_num_entries(p_vcdinfo)-1 );
1544 vcdinfo_close(p_vcdinfo);
1546 #endif /* LIBVCD_VERSION_NUM > 23 */
1547 disc_device->SetValue( wxL2U(psz_device) );
1549 CdIo_t *p_cdio = cdio_open (psz_device, DRIVER_UNKNOWN);
1550 disc_device->SetValue( wxL2U(psz_device) );
1552 /* Set track range accurately if possible. */
1555 track_t i_last_track = cdio_get_last_track_num(p_cdio);
1556 disc_title->SetRange( 0, i_last_track-1 );
1558 cdio_destroy(p_cdio);
1563 b_probed_VCD = true;
1565 /* Not a VCD. Try for a DVD unless we've been there before. */
1566 if( !b_probed_DVD && (psz_device = ProbeDVD(disc_device->GetValue())) )
1568 disc_type->SetSelection(SELECTION_DISC_TYPE_DVD_MENUS);
1569 OnDiscTypeChange( dummy_event );
1572 b_probed_DVD = true;
1574 /* Couldn't find a VCD or DVD. See if we can find a CD-DA. */
1575 psz_device = ProbeCDDA(disc_device->GetValue());
1578 disc_type->SetSelection(SELECTION_DISC_TYPE_CDDA);
1579 OnDiscTypeChange( dummy_event );
1583 /* Couldn't find a VCD, DVD or CD-DA. Null out the Device name and
1584 set to original selection.
1586 disc_device->SetValue( wxL2U("") );
1587 disc_type->SetSelection(i_selection);
1588 OnDiscTypeChange( dummy_event );
1591 case SELECTION_DISC_TYPE_CDDA:
1592 if(!psz_device) psz_device = ProbeCDDA(disc_device->GetValue());
1595 CdIo_t *p_cdio = cdio_open (psz_device, DRIVER_UNKNOWN);
1596 disc_device->SetValue( wxL2U(psz_device) );
1599 track_t i_last_track = cdio_get_last_track_num(p_cdio);
1600 disc_title->SetRange( 0, i_last_track );
1602 MediaInsertCDDA( p_intf, p_cdio, i_last_track );
1605 cdio_destroy(p_cdio);
1609 /* Not a CD-DA. Try for a DVD unless we've been there before. */
1610 if( !b_probed_DVD && (psz_device = ProbeDVD(disc_device->GetValue())) )
1612 disc_type->SetSelection(SELECTION_DISC_TYPE_DVD_MENUS);
1613 OnDiscTypeChange( dummy_event );
1617 /* Couldn't find a CD-DA or DVD. See if we can find a VCD, unless
1618 we've tried that before. */
1619 if (!b_probed_VCD) psz_device = ProbeVCD(disc_device->GetValue());
1622 disc_type->SetSelection(SELECTION_DISC_TYPE_VCD);
1623 OnDiscTypeChange( dummy_event );
1626 disc_device->SetValue( wxL2U("") );
1630 msg_Err( p_intf, "invalid Disc type selection (%d)",
1631 disc_type->GetSelection() );
1636 disc_probe->SetValue(FALSE);
1638 UpdateMRL( DISC_ACCESS );
1640 #endif /* HAVE_LIBCDIO */
1642 void OpenDialog::OnDiscTypeChange( wxCommandEvent& WXUNUSED(event) )
1644 char *psz_device = NULL;
1646 switch( disc_type->GetSelection() )
1649 case SELECTION_DISC_TYPE_DVD_MENUS:
1650 case SELECTION_DISC_TYPE_DVD:
1651 disc_sub->Enable(); disc_sub_label->Enable();
1652 disc_audio->Enable(); disc_audio_label->Enable();
1653 disc_chapter->Enable(); disc_chapter_label->Enable();
1654 disc_title_label->SetLabel ( wxU(_("Title")) );
1655 psz_device = config_GetPsz( p_intf, "dvd" );
1656 if( !b_disc_device_changed )
1658 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1659 else disc_device->SetValue( wxT("") );
1661 disc_title->SetRange( 0, 255 );
1662 disc_sub->SetRange( -1, 31 ); // up to 32 subtitles -1: no subtitle
1663 disc_audio->SetRange( 0, 7 ); // up to 8 audio channels
1664 disc_chapter->SetRange( 0, 255 );
1665 disc_title->SetToolTip( wxU(_("Title number.")) );
1666 disc_sub->SetToolTip( wxU(_(
1667 "DVDs can have up to 32 subtitles numbered 0..31. "
1668 "Note this is not the same thing as a subtitle name (e.g. 'en'). "
1669 "If a value -1 is used, no subtitle will be shown." )) );
1670 disc_audio->SetToolTip( wxU(_("Audio track number. "
1671 "DVDs can have up to 8 audio tracks numbered 0..7."
1675 case SELECTION_DISC_TYPE_VCD:
1676 disc_sub->Enable(); disc_sub_label->Enable();
1677 disc_audio->Enable(); disc_audio_label->Enable();
1678 disc_chapter->Disable(); disc_chapter_label->Disable();
1679 psz_device = config_GetPsz( p_intf, "vcd" );
1680 if( !b_disc_device_changed )
1682 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1683 else disc_device->SetValue( wxT("") );
1687 if (config_GetInt( p_intf, "vcdx-PBC" ))
1689 disc_title_label->SetLabel ( wxT("Playback LID") );
1690 disc_title->SetToolTip( wxU(_(
1691 "Playback control (PBC) usually starts with number 1." )) );
1695 disc_title_label->SetLabel ( wxT("Entry") );
1696 disc_title->SetToolTip( wxU(_(
1697 "The first entry (the beginning of the first MPEG track) is 0." )) );
1701 disc_title_label->SetLabel ( wxU(_("Track")) );
1702 disc_title->SetToolTip( wxU(_("Track number.")) );
1704 disc_title->SetRange( 0, 99 ); // only 100 tracks allowed on VCDs
1705 disc_sub->SetRange( -1, 3 ); // up to 4 subtitles -1 = no subtitle
1706 disc_audio->SetRange( 0, 1 ); // up to 2 audio tracks
1707 disc_sub->SetToolTip( wxU(_(
1708 "SVCDs can have up to 4 subtitles numbered 0..3. "
1709 "If a value -1 is used, no subtitle will be shown." )) );
1710 disc_audio->SetToolTip( wxU(_("Audio track number. "
1711 "VCDs can have up to 2 audio tracks numbered 0 or 1. "
1715 case SELECTION_DISC_TYPE_CDDA:
1716 disc_sub->Disable(); disc_sub_label->Disable();
1717 disc_chapter->Disable(); disc_chapter_label->Disable();
1718 disc_audio->Disable(); disc_audio_label->Disable();
1719 disc_title_label->SetLabel ( wxU(_("Track")) );
1721 disc_title->SetToolTip( wxU(_(
1722 "Audio CDs can have up to 100 tracks, the first track is usually 1. "
1723 "If 0 is given, then all tracks are played.")) );
1725 disc_title->SetToolTip( wxU(_(
1726 "Audio CDs can have up to 100 tracks, the first track is usually 1."
1729 psz_device = config_GetPsz( p_intf, "cd-audio" );
1730 if( !b_disc_device_changed )
1732 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1733 else disc_device->SetValue( wxT("") );
1736 /* There are at most 100 tracks in a CD-DA */
1737 disc_title->SetRange( 0, 100 );
1741 msg_Err( p_intf, "invalid Disc type selection (%d)",
1742 disc_type->GetSelection() );
1746 disc_title->SetValue( 0 ); i_disc_title = 0;
1747 disc_chapter->SetValue( 0 ); i_disc_chapter = 0;
1751 UpdateMRL( DISC_ACCESS );
1754 /*****************************************************************************
1755 * Net panel event methods.
1756 *****************************************************************************/
1757 void OpenDialog::OnNetPanelChangeSpin( wxSpinEvent& event )
1759 wxCommandEvent cevent;
1760 cevent.SetId(event.GetId());
1761 cevent.SetInt(event.GetPosition());
1762 OnNetPanelChange(cevent);
1765 void OpenDialog::OnNetPanelChange( wxCommandEvent& event )
1767 if( event.GetId() >= NetPort1_Event && event.GetId() <= NetPort3_Event )
1769 i_net_ports[event.GetId() - NetPort1_Event] = event.GetInt();
1772 UpdateMRL( NET_ACCESS );
1775 void OpenDialog::OnNetTypeChange( wxCommandEvent& event )
1779 i_net_type = event.GetId() - NetRadio1_Event;
1783 net_radios[i]->SetValue( event.GetId() == (NetRadio1_Event+i) );
1784 net_subpanels[i]->Enable( event.GetId() == (NetRadio1_Event+i) );
1786 /* UDP Unicast or multicast -> timeshift */
1787 if( i_net_type == 0 || i_net_type == 1 )
1788 net_timeshift->Enable();
1790 net_timeshift->Disable();
1792 UpdateMRL( NET_ACCESS );
1795 /*****************************************************************************
1796 * Subtitles file event methods.
1797 *****************************************************************************/
1798 void OpenDialog::OnSubsFileEnable( wxCommandEvent& event )
1800 subsfile_button->Enable( event.GetInt() != 0 );
1801 subbrowse_button->Enable( event.GetInt() != 0 );
1802 subfile_combo->Enable( event.GetInt() != 0 );
1805 void OpenDialog::OnSubsFileSettings( wxCommandEvent& WXUNUSED(event) )
1807 /* Show/hide the open dialog */
1808 if( subsfile_dialog == NULL )
1809 subsfile_dialog = new SubsFileDialog( p_intf, this );
1811 if( subsfile_dialog && subsfile_dialog->ShowModal() == wxID_OK )
1813 subsfile_mrl.Empty();
1814 subsfile_mrl.Add( wxString(wxT("sub-file=")) + subfile_combo->GetValue() );
1815 if( subsfile_dialog->encoding_combo )
1817 subsfile_mrl.Add( wxString(wxT("subsdec-encoding=")) +
1818 subsfile_dialog->encoding_combo->GetValue() );
1820 if( subsfile_dialog->align_combo )
1822 subsfile_mrl.Add( wxString::Format(wxT("subsdec-align=%i"),
1823 (int)subsfile_dialog->align_combo->GetClientData(
1824 subsfile_dialog->align_combo->GetSelection()) ) );
1826 if( subsfile_dialog->size_combo )
1828 subsfile_mrl.Add( wxString::Format( wxT("freetype-rel-fontsize=%i"),
1829 (int)subsfile_dialog->size_combo->GetClientData(
1830 subsfile_dialog->size_combo->GetSelection()) ) );
1832 subsfile_mrl.Add( wxString( wxT("sub-fps="))+
1833 subsfile_dialog->fps_ctrl->GetValue() );
1834 subsfile_mrl.Add( wxString::Format( wxT("sub-delay=%i"),
1835 subsfile_dialog->delay_spinctrl->GetValue() ) );
1839 /*****************************************************************************
1840 * Stream output event methods.
1841 *****************************************************************************/
1842 void OpenDialog::OnSoutEnable( wxCommandEvent& event )
1844 sout_button->Enable( event.GetInt() != 0 );
1847 void OpenDialog::OnSoutSettings( wxCommandEvent& WXUNUSED(event) )
1849 /* Show/hide the open dialog */
1850 if( sout_dialog == NULL )
1851 sout_dialog = new SoutDialog( p_intf, this );
1853 if( sout_dialog && sout_dialog->ShowModal() == wxID_OK )
1855 sout_mrl = sout_dialog->GetOptions();
1859 /*****************************************************************************
1860 * Caching event methods.
1861 *****************************************************************************/
1862 void OpenDialog::OnCachingEnable( wxCommandEvent& event )
1864 caching_value->Enable( event.GetInt() != 0 );
1865 i_caching = caching_value->GetValue();
1869 void OpenDialog::OnCachingChangeSpin( wxSpinEvent& event )
1871 wxCommandEvent cevent;
1872 OnCachingChange(cevent);
1875 void OpenDialog::OnCachingChange( wxCommandEvent& event )
1877 i_caching = event.GetInt();
1881 /*****************************************************************************
1882 * Utility functions.
1883 *****************************************************************************/
1884 wxArrayString SeparateEntries( wxString entries )
1886 vlc_bool_t b_quotes_mode = VLC_FALSE;
1888 wxArrayString entries_array;
1891 wxStringTokenizer token( entries, wxT(" \t\r\n\""), wxTOKEN_RET_DELIMS );
1893 while( token.HasMoreTokens() )
1895 entry += token.GetNextToken();
1897 if( entry.IsEmpty() ) continue;
1899 if( !b_quotes_mode && entry.Last() == wxT('\"') )
1901 /* Enters quotes mode */
1903 b_quotes_mode = VLC_TRUE;
1905 else if( b_quotes_mode && entry.Last() == wxT('\"') )
1907 /* Finished the quotes mode */
1909 b_quotes_mode = VLC_FALSE;
1911 else if( !b_quotes_mode && entry.Last() != wxT('\"') )
1913 /* we found a non-quoted standalone string */
1914 if( token.HasMoreTokens() ||
1915 entry.Last() == wxT(' ') || entry.Last() == wxT('\t') ||
1916 entry.Last() == wxT('\r') || entry.Last() == wxT('\n') )
1918 if( !entry.IsEmpty() ) entries_array.Add( entry );
1925 if( !entry.IsEmpty() ) entries_array.Add( entry );
1927 return entries_array;