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(p_module->psz_object_name) ),
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;
230 for( n = 0; n < p_module->confsize; n++ )
232 module_config_t *p_item = &p_module->p_config[n];
233 if( !(p_item->i_type & CONFIG_HINT) && p_item->b_advanced )
236 if( p_item->i_type & CONFIG_HINT || p_item->b_advanced )
239 ConfigControl *control =
240 CreateConfigControl( VLC_OBJECT(p_intf), p_item, this );
242 config_array.Add( control );
244 /* Don't add items that were not recognized */
245 if( control == NULL ) continue;
247 control->SetUpdateCallback( AutoBuildCallback, (void *)dialog );
249 sizer->Add( control, 0, wxEXPAND | wxALL, 2 );
255 new wxButton( this, AdvancedOptions_Event,
256 wxU(_("Advanced options...")) );
257 sizer->Add( button, 0, wxALL, 5 );
259 /* Build the advanced dialog */
261 new wxDialog( this, -1, ((wxString)wxU(_("Advanced options"))) +
262 wxT(" (") + wxU( p_module->psz_longname ) + wxT(")"),
263 wxDefaultPosition, wxDefaultSize,
264 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER );
266 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
268 /* Create MRL combobox */
269 wxBoxSizer *mrl_sizer_sizer = new wxBoxSizer( wxHORIZONTAL );
270 wxStaticBox *mrl_box =
271 new wxStaticBox( p_advanced_dialog, -1,
272 wxU(_("Advanced options")) );
273 wxStaticBoxSizer *mrl_sizer =
274 new wxStaticBoxSizer( mrl_box, wxHORIZONTAL );
275 wxStaticText *mrl_label =
276 new wxStaticText( p_advanced_dialog, -1, wxU(_("Options:")) );
277 p_advanced_mrl_combo =
278 new wxComboBox( p_advanced_dialog, MRL_Event, wxT(""),
279 wxDefaultPosition, wxDefaultSize );
280 mrl_sizer->Add( mrl_label, 0, wxALL | wxALIGN_CENTER, 5 );
281 mrl_sizer->Add( p_advanced_mrl_combo, 1, wxALL | wxALIGN_CENTER, 5 );
282 mrl_sizer_sizer->Add( mrl_sizer, 1, wxEXPAND | wxALL, 5 );
283 sizer->Add( mrl_sizer_sizer, 0, wxEXPAND | wxALL, 2 );
285 /* Add advanced options to panel */
286 for( n = 0; n < p_module->confsize; n++ )
288 module_config_t *p_item = &p_module->p_config[n];
289 if( p_item->i_type & CONFIG_HINT || !p_item->b_advanced )
292 ConfigControl *control =
293 CreateConfigControl( VLC_OBJECT(p_intf), p_item,
296 advanced_config_array.Add( control );
298 /* Don't add items that were not recognized */
299 if( control == NULL ) continue;
301 control->SetUpdateCallback( AutoBuildAdvancedCallback,
304 sizer->Add( control, 0, wxEXPAND | wxALL, 2 );
308 wxPanel *dummy_panel = new wxPanel( p_advanced_dialog, -1 );
309 sizer->Add( dummy_panel, 1 );
310 wxStaticLine *static_line =
311 new wxStaticLine( p_advanced_dialog, wxID_OK );
312 sizer->Add( static_line, 0, wxEXPAND | wxALL, 5 );
315 wxButton *ok_button =
316 new wxButton( p_advanced_dialog, wxID_OK, wxU(_("&OK")) );
317 ok_button->SetDefault();
318 wxButton *cancel_button =
319 new wxButton( p_advanced_dialog, wxID_CANCEL, wxU(_("&Cancel")) );
320 wxStdDialogButtonSizer *button_sizer = new wxStdDialogButtonSizer;
321 button_sizer->AddButton( ok_button );
322 button_sizer->AddButton( cancel_button );
323 button_sizer->Realize();
324 sizer->Add( button_sizer, 0, wxEXPAND|wxALL, 5 );
326 sizer->SetMinSize( 400, -1 );
327 p_advanced_dialog->SetSizerAndFit( sizer );
330 this->SetSizerAndFit( sizer );
333 void AutoBuiltPanel::OnAdvanced( wxCommandEvent& event )
335 if( p_advanced_dialog->ShowModal() == wxID_OK )
338 p_open_dialog->UpdateMRL();
342 void AutoBuiltPanel::UpdateAdvancedMRL()
346 for( int i = 0; i < (int)advanced_config_array.GetCount(); i++ )
348 ConfigControl *control = advanced_config_array.Item(i);
350 mrltemp += (i ? wxT(" :") : wxT(":"));
352 if( control->GetType() == CONFIG_ITEM_BOOL &&
353 !control->GetIntValue() ) mrltemp += wxT("no-");
355 mrltemp += control->GetName();
357 switch( control->GetType() )
359 case CONFIG_ITEM_STRING:
360 case CONFIG_ITEM_FILE:
361 case CONFIG_ITEM_DIRECTORY:
362 case CONFIG_ITEM_MODULE:
363 mrltemp += wxT("=\"") + control->GetPszValue() + wxT("\"");
365 case CONFIG_ITEM_INTEGER:
367 wxString::Format( wxT("=%i"), control->GetIntValue() );
369 case CONFIG_ITEM_FLOAT:
371 wxString::Format(wxT("=%f"), control->GetFloatValue());
376 p_advanced_mrl_combo->SetValue( mrltemp );
379 /*****************************************************************************
381 *****************************************************************************/
382 OpenDialog::OpenDialog( intf_thread_t *_p_intf, wxWindow *_p_parent,
383 int i_access_method, int i_arg ):
384 wxDialog( _p_parent, -1, wxU(_("Open...")), wxDefaultPosition,
385 wxDefaultSize, wxDEFAULT_FRAME_STYLE )
387 OpenDialog( _p_intf, _p_parent, i_access_method, i_arg, OPEN_NORMAL );
390 OpenDialog::OpenDialog( intf_thread_t *_p_intf, wxWindow *_p_parent,
391 int i_access_method, int i_arg, int _i_method ):
392 wxDialog( _p_parent, -1, wxU(_("Open...")), wxDefaultPosition,
393 wxDefaultSize, wxDEFAULT_FRAME_STYLE )
395 /* Initializations */
396 i_method = _i_method;
398 p_parent = _p_parent;
399 SetIcon( *p_intf->p_sys->p_icon );
401 i_disc_type_selection = 0;
406 subsfile_dialog = NULL;
407 b_disc_device_changed = false;
409 /* Create a panel to put everything in */
410 wxPanel *panel = new wxPanel( this, -1 );
411 panel->SetAutoLayout( TRUE );
414 /* Advanced options */
415 wxStaticBox *adv_box = new wxStaticBox( panel, -1,
416 wxU(_("Advanced options")) );
417 wxStaticBoxSizer *adv_sizer = new wxStaticBoxSizer( adv_box,
421 wxFlexGridSizer *common_opt_sizer = new wxFlexGridSizer( 5, 1, 20 );
422 if( i_method == OPEN_NORMAL )
424 /* Create Stream Output checkox */
425 sout_checkbox = new wxCheckBox( panel, SoutEnable_Event,
426 wxU(_("Stream/Save")) );
427 sout_checkbox->SetToolTip( wxU(_("Use VLC as a stream server")) );
428 common_opt_sizer->Add( sout_checkbox, 0,
429 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
431 sout_button = new wxButton( panel, SoutSettings_Event,
432 wxU(_("Settings...")) );
433 sout_button->Disable();
435 char *psz_sout = config_GetPsz( p_intf, "sout" );
436 if( psz_sout && *psz_sout )
438 sout_checkbox->SetValue(TRUE);
439 sout_button->Enable();
440 subsfile_mrl.Add( wxString(wxT("sout=")) + wxL2U(psz_sout) );
442 if( psz_sout ) free( psz_sout );
444 common_opt_sizer->Add( sout_button, 1, wxALIGN_LEFT |
445 wxALIGN_CENTER_VERTICAL );
447 common_opt_sizer->Add( new wxPanel( this, -1 ), 1,
448 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
451 /* Create caching options */
452 caching_checkbox = new wxCheckBox( panel, CachingEnable_Event,
454 caching_checkbox->SetToolTip( wxU(_("Change the default caching value "
455 "(in milliseconds)")) );
456 common_opt_sizer->Add( caching_checkbox, 0,
457 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
458 caching_value = new wxSpinCtrl( panel, CachingChange_Event );
459 caching_value->SetRange( 0, 1000000 );
460 caching_value->Disable();
461 common_opt_sizer->Add( caching_value, 0,
462 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
465 wxBoxSizer *mrl_sizer = new wxBoxSizer( wxHORIZONTAL );
466 wxStaticText *mrl_label = new wxStaticText( panel, -1,
467 wxU(_("Customize:")) );
468 mrl_combo = new wxComboBox( panel, MRL_Event, wxT(""),
469 wxDefaultPosition, wxDefaultSize );
470 //Point(20,25), wxSize(120, -1) );
471 mrl_combo->SetToolTip( wxU(_("You can use this field directly by typing "
472 "the full MRL you want to open.\n""Alternatively, the field will be "
473 "filled automatically when you use the controls above.")) );
475 mrl_sizer->Add( mrl_label, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
476 mrl_sizer->Add( mrl_combo, 1, wxALL | wxEXPAND | wxALIGN_CENTER_VERTICAL,
479 adv_sizer->Add( common_opt_sizer, 0, wxTOP | wxLEFT|wxRIGHT | wxEXPAND, 5 );
480 adv_sizer->Add( mrl_sizer, 0, wxBOTTOM | wxLEFT|wxRIGHT | wxEXPAND, 5 );
483 wxStaticLine *static_line = new wxStaticLine( panel, wxID_OK );
485 /* Create the buttons */
486 wxButton *ok_button = new wxButton( panel, wxID_OK, wxU(_("&OK")) );
487 ok_button->SetDefault();
488 wxButton *cancel_button = new wxButton( panel, wxID_CANCEL,
491 /* Create notebook */
492 notebook = new wxNotebook( panel, Notebook_Event );
494 #if (!wxCHECK_VERSION(2,5,2))
495 wxNotebookSizer *notebook_sizer = new wxNotebookSizer( notebook );
498 notebook->AddPage( FilePanel( notebook ), wxU(_("File")),
499 i_access_method == FILE_ACCESS );
500 notebook->AddPage( DiscPanel( notebook ), wxU(_("Disc")),
501 i_access_method == DISC_ACCESS );
502 notebook->AddPage( NetPanel( notebook ), wxU(_("Network")),
503 i_access_method == NET_ACCESS );
505 module_t *p_module = config_FindModule( VLC_OBJECT(p_intf), "v4l" );
508 AutoBuiltPanel *autopanel =
509 new AutoBuiltPanel( notebook, this, p_intf, p_module );
510 input_tab_array.Add( autopanel );
511 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
512 p_module->psz_shortname : p_module->psz_object_name ),
513 i_access_method == CAPTURE_ACCESS );
516 p_module = config_FindModule( VLC_OBJECT(p_intf), "pvr" );
519 AutoBuiltPanel *autopanel =
520 new AutoBuiltPanel( notebook, this, p_intf, p_module );
521 input_tab_array.Add( autopanel );
522 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
523 p_module->psz_shortname : p_module->psz_object_name ),
524 i_access_method == CAPTURE_ACCESS );
527 p_module = config_FindModule( VLC_OBJECT(p_intf), "dvb" );
530 AutoBuiltPanel *autopanel =
531 new AutoBuiltPanel( notebook, this, p_intf, p_module );
532 input_tab_array.Add( autopanel );
533 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
534 p_module->psz_shortname : p_module->psz_object_name ),
535 i_access_method == CAPTURE_ACCESS );
538 p_module = config_FindModule( VLC_OBJECT(p_intf), "dshow" );
541 AutoBuiltPanel *autopanel =
542 new AutoBuiltPanel( notebook, this, p_intf, p_module );
543 input_tab_array.Add( autopanel );
544 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
545 p_module->psz_shortname : p_module->psz_object_name ),
546 i_access_method == CAPTURE_ACCESS );
549 /* Update Disc panel */
550 wxCommandEvent dummy_event;
551 OnDiscTypeChange( dummy_event );
553 /* Update Net panel */
554 dummy_event.SetId( NetRadio1_Event );
555 OnNetTypeChange( dummy_event );
558 wxNotebookEvent event( wxEVT_NULL, 0, i_access_method );
559 OnPageChange( event );
561 /* Place everything in sizers */
562 wxStdDialogButtonSizer *button_sizer = new wxStdDialogButtonSizer;
563 button_sizer->AddButton( cancel_button );
564 button_sizer->AddButton( ok_button );
565 button_sizer->Realize();
566 wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL );
567 wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
568 #if (!wxCHECK_VERSION(2,5,2))
569 panel_sizer->Add( notebook_sizer, 1, wxEXPAND | wxALL, 5 );
571 panel_sizer->Add( notebook, 1, wxEXPAND | wxALL, 5 );
573 panel_sizer->Add( adv_sizer, 0, wxEXPAND | wxALL, 5 );
574 panel_sizer->Add( static_line, 0, wxEXPAND | wxALL, 5 );
575 panel_sizer->Add( button_sizer, 0, wxEXPAND | wxALL, 5 );
576 panel_sizer->Layout();
577 panel->SetSizerAndFit( panel_sizer );
578 main_sizer->Add( panel, 1, wxGROW, 0 );
579 main_sizer->Layout();
580 SetSizerAndFit( main_sizer );
583 OpenDialog::~OpenDialog()
586 if( file_dialog ) delete file_dialog;
587 if( sout_dialog ) delete sout_dialog;
588 if( subsfile_dialog ) delete subsfile_dialog;
591 int OpenDialog::Show( int i_access_method, int i_arg )
593 notebook->SetSelection( i_access_method );
594 int i_ret = wxDialog::Show();
601 int OpenDialog::Show()
603 int i_ret = wxDialog::Show();
609 /*****************************************************************************
611 *****************************************************************************/
612 wxPanel *OpenDialog::FilePanel( wxWindow* parent )
614 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
617 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
619 /* Create browse file line */
620 wxBoxSizer *file_sizer = new wxBoxSizer( wxHORIZONTAL );
622 file_sizer->Add( new wxStaticText( panel, -1, wxU(_("Open:") ) ), 0,
623 wxALL | wxALIGN_CENTER_VERTICAL, 5 );
625 file_combo = new wxComboBox( panel, FileName_Event, wxT("") );
626 wxButton *browse_button = new wxButton( panel, FileBrowse_Event,
627 wxU(_("Browse...")) );
628 file_sizer->Add( file_combo, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
629 file_sizer->Add( browse_button, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
631 /* Create Subtitles File checkox - button */
632 wxFlexGridSizer *subtitles_sizer = new wxFlexGridSizer( 2, 1, 20 );
633 subsfile_checkbox = new wxCheckBox( panel, SubsFileEnable_Event,
634 wxU(_("Use a subtitles file")) );
635 subsfile_checkbox->SetToolTip( wxU(_("Use an external subtitles file.")) );
636 subtitles_sizer->Add( subsfile_checkbox, 0, wxALIGN_CENTER_VERTICAL |
638 subsfile_button = new wxButton( panel, SubsFileSettings_Event,
639 wxU(_("Advanced Settings...")) );
640 subsfile_button->Disable();
641 subtitles_sizer->Add( subsfile_button, 1, wxALIGN_CENTER_VERTICAL |
644 /* Create subtitles file line */
645 wxBoxSizer *subfile_sizer = new wxBoxSizer( wxHORIZONTAL );
647 char *psz_subsfile = config_GetPsz( p_intf, "sub-file" );
648 if( psz_subsfile && *psz_subsfile )
650 subsfile_checkbox->SetValue(TRUE);
651 subsfile_button->Enable();
652 subsfile_mrl.Add( wxString(wxT("sub-file=")) + wxL2U(psz_subsfile) );
654 if( !psz_subsfile ) psz_subsfile = strdup("");
655 subfile_sizer->Add( new wxStaticText( panel, -1, wxU(_("File:") ) ),
656 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
657 subfile_combo = new wxComboBox( panel, SubFileName_Event,
658 wxL2U( psz_subsfile ) );
659 if( psz_subsfile ) free( psz_subsfile );
660 subbrowse_button = new wxButton( panel, SubFileBrowse_Event,
661 wxU(_("Browse...")) );
662 subfile_sizer->Add( subfile_combo, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
663 subfile_sizer->Add( subbrowse_button, 0, wxALL |wxALIGN_CENTER_VERTICAL, 5 );
665 subfile_combo->Disable();
666 subbrowse_button->Disable();
668 psz_subsfile = config_GetPsz( p_intf, "sub-file" );
669 if( psz_subsfile && *psz_subsfile )
671 subfile_combo->Enable();
672 subbrowse_button->Enable();
675 sizer->Add( file_sizer, 0, wxEXPAND | wxALL, 5 );
676 sizer->Add( subtitles_sizer, 0, wxLEFT | wxRIGHT | wxTOP, 5 );
677 sizer->Add( subfile_sizer, 0, wxEXPAND | wxLEFT | wxRIGHT| wxBOTTOM, 5 );
678 panel->SetSizerAndFit( sizer );
682 wxPanel *OpenDialog::DiscPanel( wxWindow* parent )
684 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
687 wxBoxSizer *sizer_row = new wxBoxSizer( wxVERTICAL );
688 wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 3, 20 );
690 static const wxString disc_type_array[] =
692 wxU(_("DVD (menus)")),
698 disc_type = new wxRadioBox( panel, DiscType_Event, wxU(_("Disc type")),
699 wxDefaultPosition, wxDefaultSize,
700 WXSIZEOF(disc_type_array), disc_type_array,
701 WXSIZEOF(disc_type_array), wxRA_SPECIFY_COLS );
704 disc_probe = new wxCheckBox( panel, DiscProbe_Event,
705 wxU(_("Probe Disc(s)")) );
706 disc_probe->SetToolTip( wxU(_("Probe for a DVD, VCD or audio CD. "
707 "First try the Device name entered for the selected Disc type "
708 "(DVD, DVD Menu, VCD, audio CD). If that doesn't find media, try any device "
709 "for the Disc type. If that doesn't work, then try looking for CD-ROMs or "
710 "DVD drives. The Disc type, Device name, and some parameter ranges are set "
711 "based on media we find.")) );
714 sizer_row->Add( disc_type, i_disc_type_selection, wxEXPAND | wxALL, 5 );
716 sizer_row->Add( disc_probe, 0, wxEXPAND | wxALL );
719 wxStaticText *label = new wxStaticText( panel, -1, wxU(_("Device name")) );
720 disc_device = new wxTextCtrl( panel, DiscDevice_Event, wxT(""),
721 wxDefaultPosition, wxDefaultSize,
725 char psz_default_device[3] = {0};
728 /* find the drive_name for the first cdrom drive,
729 * which is probably "D:" and put the drive_name into
730 * psz_default_device... */
731 for( char drive_letter = 'A'; drive_letter <= 'Z'; ++drive_letter )
733 char drive_name[3] = {drive_letter, ':', 0};
734 UINT type = GetDriveTypeA( drive_name );
735 if( type == DRIVE_CDROM )
737 psz_default_device[0] = drive_letter;
738 psz_default_device[1] = ':';
743 psz_forced = config_GetPsz( p_intf, "dvd" );
745 if( strlen(psz_default_device) > 0 &&
746 ( !psz_forced || psz_forced && !*psz_forced ) )
749 disc_device->SetValue( wxL2U(psz_default_device) );
753 sizer->Add( label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
754 sizer->Add( disc_device, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
756 disc_title_label = new wxStaticText( panel, -1, wxU(_("Title")) );
757 disc_title = new wxSpinCtrl( panel, DiscTitle_Event );
758 sizer->Add( disc_title_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
759 sizer->Add( disc_title, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
761 disc_chapter_label = new wxStaticText( panel, -1, wxU(_("Chapter")) );
762 disc_chapter = new wxSpinCtrl( panel, DiscChapter_Event );
763 sizer->Add( disc_chapter_label, 0,
764 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
765 sizer->Add( disc_chapter, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
767 disc_sub_label = new wxStaticText( panel, -1, wxU(_("Subtitles track")) );
768 disc_sub = new wxSpinCtrl( panel, DiscSub_Event );
769 sizer->Add( disc_sub_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
770 sizer->Add( disc_sub, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
771 disc_sub->SetRange( -1, 255 );
772 i_disc_sub = config_GetInt( p_intf, "sub-track" );
773 disc_sub->SetValue( i_disc_sub );
775 disc_audio_label = new wxStaticText( panel, -1, wxU(_("Audio track")) );
776 disc_audio = new wxSpinCtrl( panel, DiscAudio_Event );
777 sizer->Add( disc_audio_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
778 sizer->Add( disc_audio, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
779 disc_audio->SetRange( -1, 255 );
780 i_disc_audio = config_GetInt( p_intf, "audio-track" );
781 disc_audio->SetValue( i_disc_audio );
783 sizer_row->Add( sizer, 0, wxEXPAND | wxALL, 5 );
785 panel->SetSizerAndFit( sizer_row );
789 wxPanel *OpenDialog::NetPanel( wxWindow* parent )
792 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
795 wxBoxSizer *sizer_row = new wxBoxSizer( wxVERTICAL );
796 wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 4, 20 );
798 static const wxString net_type_array[] =
801 wxU(_("UDP/RTP Multicast")),
802 wxU(_("HTTP/HTTPS/FTP/MMS")),
808 net_radios[i] = new wxRadioButton( panel, NetRadio1_Event + i,
810 wxDefaultPosition, wxDefaultSize,
813 net_subpanels[i] = new wxPanel( panel, -1,
814 wxDefaultPosition, wxDefaultSize );
818 net_timeshift = new wxCheckBox( panel, NetTimeshift_Event,
819 wxU(_("Allow timeshifting")) );
822 wxFlexGridSizer *subpanel_sizer;
824 i_net_ports[0] = config_GetInt( p_intf, "server-port" );
825 subpanel_sizer = new wxFlexGridSizer( 3, 1, 20 );
826 label = new wxStaticText( net_subpanels[0], -1, wxU(_("Port")) );
827 net_ports[0] = new wxSpinCtrl( net_subpanels[0], NetPort1_Event,
828 wxString::Format(wxT("%d"), i_net_ports[0]),
829 wxDefaultPosition, wxDefaultSize,
831 0, 65535, i_net_ports[0] );
833 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
834 subpanel_sizer->Add( net_ports[0], 1,
835 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
836 net_ipv6 = new wxCheckBox( net_subpanels[0], NetForceIPv6_Event,
837 wxU(_("Force IPv6")));
838 subpanel_sizer->Add( net_ipv6, 0,
839 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
840 net_subpanels[0]->SetSizerAndFit( subpanel_sizer );
841 net_radios[0]->SetValue( TRUE );
843 /* UDP/RTP Multicast row */
844 subpanel_sizer = new wxFlexGridSizer( 4, 1, 20 );
845 label = new wxStaticText( net_subpanels[1], -1, wxU(_("Address")) );
846 net_addrs[1] = new wxTextCtrl( net_subpanels[1], NetAddr2_Event, wxT(""),
847 wxDefaultPosition, wxDefaultSize,
849 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
850 subpanel_sizer->Add( net_addrs[1], 1,
851 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
853 label = new wxStaticText( net_subpanels[1], -1, wxU(_("Port")) );
854 i_net_ports[1] = i_net_ports[0];
855 net_ports[1] = new wxSpinCtrl( net_subpanels[1], NetPort2_Event,
856 wxString::Format(wxT("%d"), i_net_ports[1]),
857 wxDefaultPosition, wxDefaultSize,
859 0, 65535, i_net_ports[1] );
861 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
862 subpanel_sizer->Add( net_ports[1], 1,
863 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
864 net_subpanels[1]->SetSizerAndFit( subpanel_sizer );
866 /* HTTP and RTSP rows */
869 subpanel_sizer = new wxFlexGridSizer( 2, 1, 20 );
870 label = new wxStaticText( net_subpanels[i], -1, wxU(_("URL")) );
871 net_addrs[i] = new wxTextCtrl( net_subpanels[i], NetAddr1_Event + i,
872 (i == 2) ? wxT("") : wxT("rtsp://"),
873 wxDefaultPosition, wxSize( 200, -1 ),
875 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
876 subpanel_sizer->Add( net_addrs[i], 1,
877 wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
878 net_subpanels[i]->SetSizerAndFit( subpanel_sizer );
881 /* Stuff everything into the main panel */
884 sizer->Add( net_radios[i], 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
886 sizer->Add( net_subpanels[i], 1, wxEXPAND | wxALIGN_LEFT |
887 wxALIGN_CENTER_VERTICAL | wxALL, 5 );
889 sizer->Add( net_timeshift, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
892 sizer_row->Add( sizer, 0, wxEXPAND | wxALL, 5 );
894 panel->SetSizerAndFit( sizer_row );
898 void OpenDialog::UpdateMRL()
900 UpdateMRL( i_current_access_method );
903 void OpenDialog::UpdateMRL( int i_access_method )
905 wxString mrltemp, caching_name;
907 i_current_access_method = i_access_method;
909 switch( i_access_method )
912 mrltemp = file_combo->GetValue();
913 caching_name = wxT("file-caching");
917 i_disc_type_selection = disc_type->GetSelection();
919 switch ( i_disc_type_selection )
921 case 0: /* DVD with menus */
922 case 1: /* DVD without menus */
923 disc_device->SetToolTip( wxU(_("DVD device to use" ) ) );
924 if( i_disc_type_selection == 0 )
926 mrltemp = wxT("dvd://") + disc_device->GetValue();
927 caching_name = wxT("dvdnav-caching");
931 mrltemp = wxT("dvdsimple://") + disc_device->GetValue();
932 caching_name = wxT("dvdread-caching");
935 if( i_disc_title > 0 )
937 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
939 if( i_disc_chapter > 0 )
940 mrltemp += wxString::Format( wxT(":%d"), i_disc_chapter );
943 if( i_disc_sub >= 0 )
944 mrltemp += wxString::Format( wxT(" :sub-track=%d"),
946 if( i_disc_audio >= 0 )
947 mrltemp += wxString::Format( wxT(" :audio-track=%d"),
951 case 2: /* VCD of some sort */
953 disc_device->SetToolTip( wxU(_("Name of CD-ROM device "
954 "to read Video CD from. If this field is left empty, we will scan "
955 "for a CD-ROM with a VCD in it.")) );
956 mrltemp = wxT("vcdx://") + disc_device->GetValue();
957 if( i_disc_title > 0 )
958 mrltemp += wxString::Format( wxT("@%c%d"),
959 config_GetInt( p_intf, "vcdx-PBC" )
960 ? 'P' : 'E', i_disc_title );
962 disc_device->SetToolTip( wxU(_("CD-ROM device to use" ) ) );
963 mrltemp = wxT("vcd://") + disc_device->GetValue();
964 if( i_disc_title > 0 )
965 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
968 if( i_disc_sub >= 0 )
969 mrltemp += wxString::Format( wxT(" :sub-track=%d"),
972 if( i_disc_audio >= 0 )
973 mrltemp += wxString::Format( wxT(" :audio-track=%d"),
975 caching_name = wxT("vcd-caching");
980 disc_device->SetToolTip( wxU(_("Name of CD-ROM device "
981 "to read audio CD from. If this field is left empty, we will scan "
982 "for a CD-ROM with an audio CD in it." )) );
983 mrltemp = wxT("cddax://")
985 disc_device->SetToolTip( wxU(_("CD-ROM device to use" ) ) ) ;
986 mrltemp = wxT("cdda://")
988 + disc_device->GetValue();
989 if( i_disc_title > 0 )
990 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
992 caching_name = wxT("cdda-caching");
996 msg_Err( p_intf, "invalid selection (%d)",
997 disc_type->GetSelection() );
1003 switch( i_net_type )
1006 mrltemp = wxT("udp://@");
1007 if ( net_ipv6->GetValue() )
1009 mrltemp += wxT("[::]");
1011 if( i_net_ports[0] !=
1012 config_GetInt( p_intf, "server-port" ) )
1014 mrltemp += wxString::Format( wxT(":%d"), i_net_ports[0] );
1017 caching_name = wxT("udp-caching");
1021 mrltemp = wxT("udp://@");
1022 if ((net_addrs[1]->GetLineText(0).Find (':') != -1)
1023 && (net_addrs[1]->GetLineText(0)[0u] != '['))
1025 /* automatically adds '[' and ']' to IPv6 addresses */
1026 mrltemp += wxT("[") + net_addrs[1]->GetLineText(0)
1031 mrltemp += net_addrs[1]->GetLineText(0);
1033 if( i_net_ports[1] != config_GetInt( p_intf, "server-port" ) )
1035 mrltemp += wxString::Format( wxT(":%d"), i_net_ports[1] );
1038 caching_name = wxT("udp-caching");
1043 if( net_addrs[2]->GetLineText(0).Find(wxT("://")) == -1 )
1044 mrltemp = wxT("http://");
1046 mrltemp += net_addrs[2]->GetLineText(0);
1047 if( ! mrltemp.Left(4).CmpNoCase(wxT("http")) )
1048 caching_name = wxT("http-caching");
1049 else if( ! mrltemp.Left(3).CmpNoCase(wxT("mms")) )
1050 caching_name = wxT("mms-caching");
1052 caching_name= wxT("ftp-caching");
1057 if( net_addrs[3]->GetLineText(0).Find(wxT("rtsp://")) != 0 )
1059 mrltemp = wxT("rtsp://");
1061 mrltemp += net_addrs[3]->GetLineText(0);
1063 caching_name = wxT("rtsp-caching");
1066 if( net_timeshift->IsEnabled() && net_timeshift->IsChecked() )
1067 mrltemp += wxT(" :access-filter=timeshift");
1072 int i_item = i_access_method - MAX_ACCESS;
1074 if( i_item < 0 || i_item >= (int)input_tab_array.GetCount() )
1077 AutoBuiltPanel *input_panel = input_tab_array.Item( i_item );
1079 mrltemp = input_panel->name + wxT("://");
1081 for( int i=0; i < (int)input_panel->config_array.GetCount(); i++ )
1083 ConfigControl *control = input_panel->config_array.Item(i);
1085 mrltemp += wxT(" :");
1087 if( control->GetType() == CONFIG_ITEM_BOOL &&
1088 !control->GetIntValue() ) mrltemp += wxT("no-");
1090 mrltemp += control->GetName();
1092 switch( control->GetType() )
1094 case CONFIG_ITEM_STRING:
1095 case CONFIG_ITEM_FILE:
1096 case CONFIG_ITEM_DIRECTORY:
1097 case CONFIG_ITEM_MODULE:
1098 mrltemp += wxT("=\"") + control->GetPszValue() + wxT("\"");
1100 case CONFIG_ITEM_INTEGER:
1102 wxString::Format( wxT("=%i"), control->GetIntValue() );
1104 case CONFIG_ITEM_FLOAT:
1106 wxString::Format(wxT("=%f"), control->GetFloatValue());
1111 if( input_panel->p_advanced_mrl_combo &&
1112 input_panel->p_advanced_mrl_combo->GetValue() )
1114 mrltemp += wxT(" ") +
1115 input_panel->p_advanced_mrl_combo->GetValue();
1121 if( caching_name.size() )
1123 if( caching_value->IsEnabled() )
1125 mrltemp += wxT(" :") + caching_name +
1126 wxString::Format( wxT("=%d"), i_caching );
1130 int i_value = config_GetInt( p_intf, caching_name.mb_str(wxConvUTF8) );
1131 caching_value->SetValue( i_value );
1135 mrl_combo->SetValue( mrltemp );
1138 /*****************************************************************************
1140 *****************************************************************************/
1141 void OpenDialog::OnOk( wxCommandEvent& WXUNUSED(event) )
1143 mrl = SeparateEntries( mrl_combo->GetValue() );
1144 mrl_combo->Append( mrl_combo->GetValue() );
1145 if( mrl_combo->GetCount() > 10 ) mrl_combo->Delete( 0 );
1146 mrl_combo->SetSelection( mrl_combo->GetCount() - 1 );
1148 if( i_method == OPEN_STREAM )
1150 if( IsModal() ) EndModal( wxID_OK );
1155 /* Update the playlist */
1156 playlist_t *p_playlist =
1157 (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
1159 if( p_playlist == NULL ) return;
1161 for( int i = 0; i < (int)mrl.GetCount(); i++ )
1163 vlc_bool_t b_start = !i && i_open_arg;
1164 input_item_t *p_input;
1167 psz_utf8 = wxFromLocale( mrl[i] );
1168 p_input = input_ItemNew( p_intf, psz_utf8, NULL );
1169 wxLocaleFree( psz_utf8 );
1171 /* Insert options */
1172 while( i + 1 < (int)mrl.GetCount() &&
1173 ((const char *)mrl[i + 1].mb_str(wxConvUTF8))[0] == ':' )
1175 psz_utf8 = wxFromLocale( mrl[i + 1] );
1176 input_ItemAddOption( p_input, psz_utf8 );
1177 wxLocaleFree( psz_utf8 );
1181 /* Get the options from the subtitles dialog */
1182 if( subsfile_checkbox->IsChecked() && subsfile_mrl.GetCount() )
1184 for( int j = 0; j < (int)subsfile_mrl.GetCount(); j++ )
1186 psz_utf8 = wxFromLocale( subsfile_mrl[j] );
1187 input_ItemAddOption( p_input, psz_utf8 );
1188 wxLocaleFree( psz_utf8 );
1192 /* Get the options from the stream output dialog */
1193 if( sout_checkbox->IsChecked() && sout_mrl.GetCount() )
1195 for( int j = 0; j < (int)sout_mrl.GetCount(); j++ )
1197 psz_utf8 = wxFromLocale( sout_mrl[j] );
1198 input_ItemAddOption( p_input, psz_utf8 );
1199 wxLocaleFree( psz_utf8 );
1205 playlist_AddInput( p_playlist, p_input,
1206 PLAYLIST_APPEND | PLAYLIST_GO,
1207 PLAYLIST_END, VLC_TRUE, VLC_FALSE );
1211 playlist_AddInput( p_playlist, p_input,
1212 PLAYLIST_APPEND|PLAYLIST_PREPARSE,
1213 PLAYLIST_END, VLC_TRUE, VLC_FALSE );
1217 vlc_object_release( p_playlist );
1221 if( IsModal() ) EndModal( wxID_OK );
1224 void OpenDialog::OnCancel( wxCommandEvent& WXUNUSED(event) )
1226 wxCloseEvent cevent;
1230 void OpenDialog::OnClose( wxCloseEvent& WXUNUSED(event) )
1234 if( IsModal() ) EndModal( wxID_CANCEL );
1237 void OpenDialog::OnPageChange( wxNotebookEvent& event )
1239 UpdateMRL( event.GetSelection() );
1242 void OpenDialog::OnMRLChange( wxCommandEvent& event )
1244 //mrl = SeparateEntries( event.GetString() );
1247 /*****************************************************************************
1248 * File panel event methods.
1249 *****************************************************************************/
1250 void OpenDialog::OnFilePanelChange( wxCommandEvent& WXUNUSED(event) )
1252 UpdateMRL( FILE_ACCESS );
1255 void OpenDialog::OnFileBrowse( wxCommandEvent& WXUNUSED(event) )
1257 if( file_dialog == NULL )
1258 file_dialog = new wxFileDialog( this, wxU(_("Open File")),
1259 wxT(""), wxT(""), wxT("*"), wxOPEN | wxMULTIPLE );
1261 file_dialog->SetWildcard(wxU(_("All Files (*.*)|*"
1262 "|Sound Files (*.mp3, *.ogg, etc.)|" EXTENSIONS_AUDIO
1263 "|Video Files (*.avi, *.mpg, etc.)|" EXTENSIONS_VIDEO
1264 "|Playlist Files (*.m3u, *.pls, etc.)|" EXTENSIONS_PLAYLIST
1265 "|Subtitle Files (*.srt, *.sub, etc.)|" EXTENSIONS_SUBTITLE)));
1267 if( file_dialog && file_dialog->ShowModal() == wxID_OK )
1269 wxArrayString paths;
1272 file_dialog->GetPaths( paths );
1274 for( size_t i = 0; i < paths.GetCount(); i++ )
1276 if( paths[i].Find( wxT(' ') ) >= 0 )
1277 path += wxT("\"") + paths[i] + wxT("\" ");
1279 path += paths[i] + wxT(" ");
1282 file_combo->SetValue( path );
1283 file_combo->Append( path );
1284 if( file_combo->GetCount() > 10 ) file_combo->Delete( 0 );
1285 UpdateMRL( FILE_ACCESS );
1289 void OpenDialog::OnSubFileBrowse( wxCommandEvent& WXUNUSED(event) )
1291 wxFileDialog dialog( this, wxU(_("Open subtitles file")),
1292 wxT(""), wxT(""), wxT("*"), wxOPEN );
1294 if( dialog.ShowModal() == wxID_OK )
1296 subfile_combo->SetValue( dialog.GetPath() );
1298 wxCommandEvent event; OnSubFileChange( event );
1301 void OpenDialog::OnSubFileChange( wxCommandEvent& WXUNUSED(event) )
1303 if( subsfile_mrl.GetCount() != 0 )
1305 subsfile_mrl.RemoveAt( 0 );
1306 subsfile_mrl.Insert( wxString(wxT("sub-file=")) + subfile_combo->GetValue() , 0 );
1310 subsfile_mrl.Add( wxString(wxT("sub-file=")) + subfile_combo->GetValue() );
1314 /*****************************************************************************
1315 * Disc panel event methods.
1316 *****************************************************************************/
1317 void OpenDialog::OnDiscPanelChangeSpin( wxSpinEvent& event )
1319 wxCommandEvent cevent;
1320 cevent.SetId(event.GetId());
1321 cevent.SetInt(event.GetPosition());
1322 OnDiscPanelChange(cevent);
1325 void OpenDialog::OnDiscPanelChange( wxCommandEvent& event )
1327 if( event.GetId() == DiscTitle_Event ) i_disc_title = event.GetInt();
1328 if( event.GetId() == DiscChapter_Event ) i_disc_chapter = event.GetInt();
1329 if( event.GetId() == DiscSub_Event ) i_disc_sub = event.GetInt();
1330 if( event.GetId() == DiscAudio_Event ) i_disc_audio = event.GetInt();
1332 UpdateMRL( DISC_ACCESS );
1335 void OpenDialog::OnDiscDeviceChange( wxCommandEvent& event )
1339 switch( disc_type->GetSelection() )
1342 psz_device = config_GetPsz( p_intf, "cd-audio" );
1346 psz_device = config_GetPsz( p_intf, "vcd" );
1350 psz_device = config_GetPsz( p_intf, "dvd" );
1354 if ( !psz_device ) psz_device = "";
1356 if( disc_device->GetValue().Cmp( wxL2U( psz_device ) ) )
1358 b_disc_device_changed = true;
1361 UpdateMRL( DISC_ACCESS );
1366 /* Return true if *psz_drive is a drive with a DVD in it. A more complete
1367 check would see if the media looks like a *playable* DVD. This should
1370 static bool IsDVD(const char *psz_drive)
1372 CdIo_t *p_cdio = cdio_open (psz_drive, DRIVER_UNKNOWN);
1375 discmode_t discmode = cdio_get_discmode(p_cdio);
1376 cdio_destroy(p_cdio);
1377 return cdio_is_discmode_dvd(discmode);
1383 /* Return a device that has a DVD in it. The caller needs to free
1384 the returned string.
1386 static char * ProbeDVD(const wxChar *device)
1389 char **ppsz_cd_drives;
1390 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1391 char *psz_device = (char *) tmp_buf;
1393 if( IsDVD(psz_device) )
1395 return strdup(psz_device);
1398 ppsz_cd_drives = cdio_get_devices(DRIVER_DEVICE);
1399 if( ppsz_cd_drives )
1402 for( c = ppsz_cd_drives; *c != NULL; c++ )
1406 char *psz_drive = strdup(*c);
1407 cdio_free_device_list(ppsz_cd_drives);
1408 return strdup(psz_drive);
1411 cdio_free_device_list(ppsz_cd_drives);
1417 static char * ProbeDevice(char **ppsz_search_devices, cdio_fs_anal_t mask,
1420 char **ppsz_devices;
1422 if( ppsz_search_devices && !ppsz_search_devices[0] )
1423 ppsz_search_devices = NULL;
1425 /* Start out trying the device that has been entered so far. */
1426 ppsz_devices = cdio_get_devices_with_cap(ppsz_search_devices, mask,
1429 if (ppsz_devices && *ppsz_devices)
1431 char *psz_device = strdup(*ppsz_devices);
1432 cdio_free_device_list(ppsz_devices);
1436 /* If there was no device specified on the first try, then give up
1437 now. Otherwise accept any CD-ROM in the class (e.g. VCD or DVD).
1439 if( !ppsz_search_devices ) return NULL;
1441 ppsz_devices = cdio_get_devices_with_cap(NULL, mask, true);
1443 if (ppsz_devices && *ppsz_devices)
1445 char *psz_device = strdup(*ppsz_devices);
1446 cdio_free_device_list(ppsz_devices);
1454 /* Return a device that has a CD-DA in it. The caller needs to free
1455 the returned string.
1457 static char * ProbeCDDA(const wxChar *device)
1460 char *ppsz_device[2];
1461 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1462 char *psz_device = (char *) tmp_buf;
1463 ppsz_device[0] = (device && *device) ? psz_device : NULL;
1464 ppsz_device[1] = NULL;
1465 return ProbeDevice(ppsz_device, CDIO_FS_AUDIO, false);
1469 /* Return a device that has a VCD in it. The caller needs to free
1470 the returned string.
1472 static char * ProbeVCD(const wxChar *device)
1474 char *ppsz_device[2];
1475 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1476 char *psz_device = (char *) tmp_buf;
1477 ppsz_device[0] = (device && *device) ? psz_device : NULL;
1478 ppsz_device[1] = NULL;
1479 return ProbeDevice(ppsz_device,
1480 (CDIO_FS_ANAL_SVCD|CDIO_FS_ANAL_CVD|CDIO_FS_ANAL_VIDEOCD
1481 |CDIO_FS_UNKNOWN), true);
1487 Probe (find anywhere) a CD-DA, VCD, or a DVD.
1488 First try the device name that may have been entered for the "disc type"
1489 selected. If that doesn't work we try any device for the disc type.
1490 If that doesn't work, try looking for CD-ROMs or DVD drives. the
1491 disc type, device name and paramter ranges are set to whatever we find.
1493 void OpenDialog::OnDiscProbe( wxCommandEvent& WXUNUSED(event) )
1495 wxCommandEvent dummy_event;
1496 char *psz_device = NULL;
1497 bool b_probed_DVD = false;
1498 bool b_probed_VCD = false;
1499 const int i_selection = disc_type->GetSelection();
1501 /* Reduce verbosity of cdio errors. */
1502 cdio_loglevel_default = CDIO_LOG_ERROR;
1505 switch( disc_type->GetSelection() )
1508 case SELECTION_DISC_TYPE_DVD_MENUS:
1509 case SELECTION_DISC_TYPE_DVD:
1510 /* If not a DVD then try for a VCD. If VCD fails it will
1512 if (!psz_device) psz_device = ProbeDVD(disc_device->GetValue());
1515 b_probed_DVD = true;
1516 disc_type->SetSelection(SELECTION_DISC_TYPE_VCD);
1517 OnDiscTypeChange( dummy_event );
1520 disc_device->SetValue( wxL2U(psz_device) );
1523 case SELECTION_DISC_TYPE_VCD: /* VCD probe of some sort */
1524 if(!psz_device) psz_device = ProbeVCD(disc_device->GetValue());
1528 #if LIBVCD_VERSION_NUM > 23
1529 vcdinfo_obj_t *p_vcdinfo;
1531 /* Set LID or entry range accurately if possible. */
1532 if( vcdinfo_open(&p_vcdinfo, &psz_device, DRIVER_DEVICE,
1533 NULL) == VCDINFO_OPEN_VCD)
1535 if (config_GetInt( p_intf, "vcdx-PBC" ))
1537 /* Set largest LID. */;
1538 disc_title->SetRange( 0, vcdinfo_get_num_LIDs(p_vcdinfo) );
1543 /* Set largest Entry */
1544 disc_title->SetRange( 0,
1545 vcdinfo_get_num_entries(p_vcdinfo)-1 );
1547 vcdinfo_close(p_vcdinfo);
1549 #endif /* LIBVCD_VERSION_NUM > 23 */
1550 disc_device->SetValue( wxL2U(psz_device) );
1552 CdIo_t *p_cdio = cdio_open (psz_device, DRIVER_UNKNOWN);
1553 disc_device->SetValue( wxL2U(psz_device) );
1555 /* Set track range accurately if possible. */
1558 track_t i_last_track = cdio_get_last_track_num(p_cdio);
1559 disc_title->SetRange( 0, i_last_track-1 );
1561 cdio_destroy(p_cdio);
1566 b_probed_VCD = true;
1568 /* Not a VCD. Try for a DVD unless we've been there before. */
1569 if( !b_probed_DVD && (psz_device = ProbeDVD(disc_device->GetValue())) )
1571 disc_type->SetSelection(SELECTION_DISC_TYPE_DVD_MENUS);
1572 OnDiscTypeChange( dummy_event );
1575 b_probed_DVD = true;
1577 /* Couldn't find a VCD or DVD. See if we can find a CD-DA. */
1578 psz_device = ProbeCDDA(disc_device->GetValue());
1581 disc_type->SetSelection(SELECTION_DISC_TYPE_CDDA);
1582 OnDiscTypeChange( dummy_event );
1586 /* Couldn't find a VCD, DVD or CD-DA. Null out the Device name and
1587 set to original selection.
1589 disc_device->SetValue( wxL2U("") );
1590 disc_type->SetSelection(i_selection);
1591 OnDiscTypeChange( dummy_event );
1594 case SELECTION_DISC_TYPE_CDDA:
1595 if(!psz_device) psz_device = ProbeCDDA(disc_device->GetValue());
1598 CdIo_t *p_cdio = cdio_open (psz_device, DRIVER_UNKNOWN);
1599 disc_device->SetValue( wxL2U(psz_device) );
1602 track_t i_last_track = cdio_get_last_track_num(p_cdio);
1603 disc_title->SetRange( 0, i_last_track );
1605 MediaInsertCDDA( p_intf, p_cdio, i_last_track );
1608 cdio_destroy(p_cdio);
1612 /* Not a CD-DA. Try for a DVD unless we've been there before. */
1613 if( !b_probed_DVD && (psz_device = ProbeDVD(disc_device->GetValue())) )
1615 disc_type->SetSelection(SELECTION_DISC_TYPE_DVD_MENUS);
1616 OnDiscTypeChange( dummy_event );
1620 /* Couldn't find a CD-DA or DVD. See if we can find a VCD, unless
1621 we've tried that before. */
1622 if (!b_probed_VCD) psz_device = ProbeVCD(disc_device->GetValue());
1625 disc_type->SetSelection(SELECTION_DISC_TYPE_VCD);
1626 OnDiscTypeChange( dummy_event );
1629 disc_device->SetValue( wxL2U("") );
1633 msg_Err( p_intf, "invalid Disc type selection (%d)",
1634 disc_type->GetSelection() );
1639 disc_probe->SetValue(FALSE);
1641 UpdateMRL( DISC_ACCESS );
1643 #endif /* HAVE_LIBCDIO */
1645 void OpenDialog::OnDiscTypeChange( wxCommandEvent& WXUNUSED(event) )
1647 char *psz_device = NULL;
1649 switch( disc_type->GetSelection() )
1652 case SELECTION_DISC_TYPE_DVD_MENUS:
1653 case SELECTION_DISC_TYPE_DVD:
1654 disc_sub->Enable(); disc_sub_label->Enable();
1655 disc_audio->Enable(); disc_audio_label->Enable();
1656 disc_chapter->Enable(); disc_chapter_label->Enable();
1657 disc_title_label->SetLabel ( wxU(_("Title")) );
1658 psz_device = config_GetPsz( p_intf, "dvd" );
1659 if( !b_disc_device_changed )
1661 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1662 else disc_device->SetValue( wxT("") );
1664 disc_title->SetRange( 0, 255 );
1665 disc_sub->SetRange( -1, 31 ); // up to 32 subtitles -1: no subtitle
1666 disc_audio->SetRange( 0, 7 ); // up to 8 audio channels
1667 disc_chapter->SetRange( 0, 255 );
1668 disc_title->SetToolTip( wxU(_("Title number.")) );
1669 disc_sub->SetToolTip( wxU(_(
1670 "DVDs can have up to 32 subtitles numbered 0..31. "
1671 "Note this is not the same thing as a subtitle name (e.g. 'en'). "
1672 "If a value -1 is used, no subtitle will be shown." )) );
1673 disc_audio->SetToolTip( wxU(_("Audio track number. "
1674 "DVDs can have up to 8 audio tracks numbered 0..7."
1678 case SELECTION_DISC_TYPE_VCD:
1679 disc_sub->Enable(); disc_sub_label->Enable();
1680 disc_audio->Enable(); disc_audio_label->Enable();
1681 disc_chapter->Disable(); disc_chapter_label->Disable();
1682 psz_device = config_GetPsz( p_intf, "vcd" );
1683 if( !b_disc_device_changed )
1685 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1686 else disc_device->SetValue( wxT("") );
1690 if (config_GetInt( p_intf, "vcdx-PBC" ))
1692 disc_title_label->SetLabel ( wxT("Playback LID") );
1693 disc_title->SetToolTip( wxU(_(
1694 "Playback control (PBC) usually starts with number 1." )) );
1698 disc_title_label->SetLabel ( wxT("Entry") );
1699 disc_title->SetToolTip( wxU(_(
1700 "The first entry (the beginning of the first MPEG track) is 0." )) );
1704 disc_title_label->SetLabel ( wxU(_("Track")) );
1705 disc_title->SetToolTip( wxU(_("Track number.")) );
1707 disc_title->SetRange( 0, 99 ); // only 100 tracks allowed on VCDs
1708 disc_sub->SetRange( -1, 3 ); // up to 4 subtitles -1 = no subtitle
1709 disc_audio->SetRange( 0, 1 ); // up to 2 audio tracks
1710 disc_sub->SetToolTip( wxU(_(
1711 "SVCDs can have up to 4 subtitles numbered 0..3. "
1712 "If a value -1 is used, no subtitle will be shown." )) );
1713 disc_audio->SetToolTip( wxU(_("Audio track number. "
1714 "VCDs can have up to 2 audio tracks numbered 0 or 1. "
1718 case SELECTION_DISC_TYPE_CDDA:
1719 disc_sub->Disable(); disc_sub_label->Disable();
1720 disc_chapter->Disable(); disc_chapter_label->Disable();
1721 disc_audio->Disable(); disc_audio_label->Disable();
1722 disc_title_label->SetLabel ( wxU(_("Track")) );
1724 disc_title->SetToolTip( wxU(_(
1725 "Audio CDs can have up to 100 tracks, the first track is usually 1. "
1726 "If 0 is given, then all tracks are played.")) );
1728 disc_title->SetToolTip( wxU(_(
1729 "Audio CDs can have up to 100 tracks, the first track is usually 1."
1732 psz_device = config_GetPsz( p_intf, "cd-audio" );
1733 if( !b_disc_device_changed )
1735 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1736 else disc_device->SetValue( wxT("") );
1739 /* There are at most 100 tracks in a CD-DA */
1740 disc_title->SetRange( 0, 100 );
1744 msg_Err( p_intf, "invalid Disc type selection (%d)",
1745 disc_type->GetSelection() );
1749 disc_title->SetValue( 0 ); i_disc_title = 0;
1750 disc_chapter->SetValue( 0 ); i_disc_chapter = 0;
1752 if( psz_device ) free( psz_device );
1754 UpdateMRL( DISC_ACCESS );
1757 /*****************************************************************************
1758 * Net panel event methods.
1759 *****************************************************************************/
1760 void OpenDialog::OnNetPanelChangeSpin( wxSpinEvent& event )
1762 wxCommandEvent cevent;
1763 cevent.SetId(event.GetId());
1764 cevent.SetInt(event.GetPosition());
1765 OnNetPanelChange(cevent);
1768 void OpenDialog::OnNetPanelChange( wxCommandEvent& event )
1770 if( event.GetId() >= NetPort1_Event && event.GetId() <= NetPort3_Event )
1772 i_net_ports[event.GetId() - NetPort1_Event] = event.GetInt();
1775 UpdateMRL( NET_ACCESS );
1778 void OpenDialog::OnNetTypeChange( wxCommandEvent& event )
1782 i_net_type = event.GetId() - NetRadio1_Event;
1786 net_radios[i]->SetValue( event.GetId() == (NetRadio1_Event+i) );
1787 net_subpanels[i]->Enable( event.GetId() == (NetRadio1_Event+i) );
1789 /* UDP Unicast or multicast -> timeshift */
1790 if( i_net_type == 0 || i_net_type == 1 )
1791 net_timeshift->Enable();
1793 net_timeshift->Disable();
1795 UpdateMRL( NET_ACCESS );
1798 /*****************************************************************************
1799 * Subtitles file event methods.
1800 *****************************************************************************/
1801 void OpenDialog::OnSubsFileEnable( wxCommandEvent& event )
1803 subsfile_button->Enable( event.GetInt() != 0 );
1804 subbrowse_button->Enable( event.GetInt() != 0 );
1805 subfile_combo->Enable( event.GetInt() != 0 );
1808 void OpenDialog::OnSubsFileSettings( wxCommandEvent& WXUNUSED(event) )
1810 /* Show/hide the open dialog */
1811 if( subsfile_dialog == NULL )
1812 subsfile_dialog = new SubsFileDialog( p_intf, this );
1814 if( subsfile_dialog && subsfile_dialog->ShowModal() == wxID_OK )
1816 subsfile_mrl.Empty();
1817 subsfile_mrl.Add( wxString(wxT("sub-file=")) + subfile_combo->GetValue() );
1818 if( subsfile_dialog->encoding_combo )
1820 subsfile_mrl.Add( wxString(wxT("subsdec-encoding=")) +
1821 subsfile_dialog->encoding_combo->GetValue() );
1823 if( subsfile_dialog->align_combo )
1825 subsfile_mrl.Add( wxString::Format(wxT("subsdec-align=%i"),
1826 (int)subsfile_dialog->align_combo->GetClientData(
1827 subsfile_dialog->align_combo->GetSelection()) ) );
1829 if( subsfile_dialog->size_combo )
1831 subsfile_mrl.Add( wxString::Format( wxT("freetype-rel-fontsize=%i"),
1832 (int)subsfile_dialog->size_combo->GetClientData(
1833 subsfile_dialog->size_combo->GetSelection()) ) );
1835 subsfile_mrl.Add( wxString( wxT("sub-fps="))+
1836 subsfile_dialog->fps_ctrl->GetValue() );
1837 subsfile_mrl.Add( wxString::Format( wxT("sub-delay=%i"),
1838 subsfile_dialog->delay_spinctrl->GetValue() ) );
1842 /*****************************************************************************
1843 * Stream output event methods.
1844 *****************************************************************************/
1845 void OpenDialog::OnSoutEnable( wxCommandEvent& event )
1847 sout_button->Enable( event.GetInt() != 0 );
1850 void OpenDialog::OnSoutSettings( wxCommandEvent& WXUNUSED(event) )
1852 /* Show/hide the open dialog */
1853 if( sout_dialog == NULL )
1854 sout_dialog = new SoutDialog( p_intf, this );
1856 if( sout_dialog && sout_dialog->ShowModal() == wxID_OK )
1858 sout_mrl = sout_dialog->GetOptions();
1862 /*****************************************************************************
1863 * Caching event methods.
1864 *****************************************************************************/
1865 void OpenDialog::OnCachingEnable( wxCommandEvent& event )
1867 caching_value->Enable( event.GetInt() != 0 );
1868 i_caching = caching_value->GetValue();
1872 void OpenDialog::OnCachingChangeSpin( wxSpinEvent& event )
1874 wxCommandEvent cevent;
1875 OnCachingChange(cevent);
1878 void OpenDialog::OnCachingChange( wxCommandEvent& event )
1880 i_caching = event.GetInt();
1884 /*****************************************************************************
1885 * Utility functions.
1886 *****************************************************************************/
1887 wxArrayString SeparateEntries( wxString entries )
1889 vlc_bool_t b_quotes_mode = VLC_FALSE;
1891 wxArrayString entries_array;
1894 wxStringTokenizer token( entries, wxT(" \t\r\n\""), wxTOKEN_RET_DELIMS );
1896 while( token.HasMoreTokens() )
1898 entry += token.GetNextToken();
1900 if( entry.IsEmpty() ) continue;
1902 if( !b_quotes_mode && entry.Last() == wxT('\"') )
1904 /* Enters quotes mode */
1906 b_quotes_mode = VLC_TRUE;
1908 else if( b_quotes_mode && entry.Last() == wxT('\"') )
1910 /* Finished the quotes mode */
1912 b_quotes_mode = VLC_FALSE;
1914 else if( !b_quotes_mode && entry.Last() != wxT('\"') )
1916 /* we found a non-quoted standalone string */
1917 if( token.HasMoreTokens() ||
1918 entry.Last() == wxT(' ') || entry.Last() == wxT('\t') ||
1919 entry.Last() == wxT('\r') || entry.Last() == wxT('\n') )
1921 if( !entry.IsEmpty() ) entries_array.Add( entry );
1928 if( !entry.IsEmpty() ) entries_array.Add( entry );
1930 return entries_array;