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;
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( module_GetLongName(p_module) ) + 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 = module_Find( 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( module_GetName(p_module, VLC_FALSE) ),
512 i_access_method == CAPTURE_ACCESS );
515 p_module = module_Find( VLC_OBJECT(p_intf), "pvr" );
518 AutoBuiltPanel *autopanel =
519 new AutoBuiltPanel( notebook, this, p_intf, p_module );
520 input_tab_array.Add( autopanel );
521 notebook->AddPage( autopanel, wxU( module_GetName(p_module, VLC_FALSE) ),
522 i_access_method == CAPTURE_ACCESS );
525 p_module = module_Find( VLC_OBJECT(p_intf), "dvb" );
528 AutoBuiltPanel *autopanel =
529 new AutoBuiltPanel( notebook, this, p_intf, p_module );
530 input_tab_array.Add( autopanel );
531 notebook->AddPage( autopanel, wxU( module_GetName(p_module, VLC_FALSE) ),
532 i_access_method == CAPTURE_ACCESS );
535 p_module = module_Find( VLC_OBJECT(p_intf), "dshow" );
538 AutoBuiltPanel *autopanel =
539 new AutoBuiltPanel( notebook, this, p_intf, p_module );
540 input_tab_array.Add( autopanel );
541 notebook->AddPage( autopanel, wxU( module_GetName(p_module, VLC_FALSE) ),
542 i_access_method == CAPTURE_ACCESS );
545 /* Update Disc panel */
546 wxCommandEvent dummy_event;
547 OnDiscTypeChange( dummy_event );
549 /* Update Net panel */
550 dummy_event.SetId( NetRadio1_Event );
551 OnNetTypeChange( dummy_event );
554 wxNotebookEvent event( wxEVT_NULL, 0, i_access_method );
555 OnPageChange( event );
557 /* Place everything in sizers */
558 wxStdDialogButtonSizer *button_sizer = new wxStdDialogButtonSizer;
559 button_sizer->AddButton( cancel_button );
560 button_sizer->AddButton( ok_button );
561 button_sizer->Realize();
562 wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL );
563 wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
564 #if (!wxCHECK_VERSION(2,5,2))
565 panel_sizer->Add( notebook_sizer, 1, wxEXPAND | wxALL, 5 );
567 panel_sizer->Add( notebook, 1, wxEXPAND | wxALL, 5 );
569 panel_sizer->Add( adv_sizer, 0, wxEXPAND | wxALL, 5 );
570 panel_sizer->Add( static_line, 0, wxEXPAND | wxALL, 5 );
571 panel_sizer->Add( button_sizer, 0, wxEXPAND | wxALL, 5 );
572 panel_sizer->Layout();
573 panel->SetSizerAndFit( panel_sizer );
574 main_sizer->Add( panel, 1, wxGROW, 0 );
575 main_sizer->Layout();
576 SetSizerAndFit( main_sizer );
579 OpenDialog::~OpenDialog()
582 if( file_dialog ) delete file_dialog;
583 if( sout_dialog ) delete sout_dialog;
584 if( subsfile_dialog ) delete subsfile_dialog;
587 int OpenDialog::Show( int i_access_method, int i_arg )
589 notebook->SetSelection( i_access_method );
590 int i_ret = wxDialog::Show();
597 int OpenDialog::Show()
599 int i_ret = wxDialog::Show();
605 /*****************************************************************************
607 *****************************************************************************/
608 wxPanel *OpenDialog::FilePanel( wxWindow* parent )
610 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
613 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
615 /* Create browse file line */
616 wxBoxSizer *file_sizer = new wxBoxSizer( wxHORIZONTAL );
618 file_sizer->Add( new wxStaticText( panel, -1, wxU(_("Open:") ) ), 0,
619 wxALL | wxALIGN_CENTER_VERTICAL, 5 );
621 file_combo = new wxComboBox( panel, FileName_Event, wxT("") );
622 wxButton *browse_button = new wxButton( panel, FileBrowse_Event,
623 wxU(_("Browse...")) );
624 file_sizer->Add( file_combo, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
625 file_sizer->Add( browse_button, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
627 /* Create Subtitles File checkox - button */
628 wxFlexGridSizer *subtitles_sizer = new wxFlexGridSizer( 2, 1, 20 );
629 subsfile_checkbox = new wxCheckBox( panel, SubsFileEnable_Event,
630 wxU(_("Use a subtitles file")) );
631 subsfile_checkbox->SetToolTip( wxU(_("Use an external subtitles file.")) );
632 subtitles_sizer->Add( subsfile_checkbox, 0, wxALIGN_CENTER_VERTICAL |
634 subsfile_button = new wxButton( panel, SubsFileSettings_Event,
635 wxU(_("Advanced Settings...")) );
636 subsfile_button->Disable();
637 subtitles_sizer->Add( subsfile_button, 1, wxALIGN_CENTER_VERTICAL |
640 /* Create subtitles file line */
641 wxBoxSizer *subfile_sizer = new wxBoxSizer( wxHORIZONTAL );
643 char *psz_subsfile = config_GetPsz( p_intf, "sub-file" );
644 if( psz_subsfile && *psz_subsfile )
646 subsfile_checkbox->SetValue(TRUE);
647 subsfile_button->Enable();
648 subsfile_mrl.Add( wxString(wxT("sub-file=")) + wxL2U(psz_subsfile) );
650 if( !psz_subsfile ) psz_subsfile = strdup("");
651 subfile_sizer->Add( new wxStaticText( panel, -1, wxU(_("File:") ) ),
652 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
653 subfile_combo = new wxComboBox( panel, SubFileName_Event,
654 wxL2U( psz_subsfile ) );
655 if( psz_subsfile ) free( psz_subsfile );
656 subbrowse_button = new wxButton( panel, SubFileBrowse_Event,
657 wxU(_("Browse...")) );
658 subfile_sizer->Add( subfile_combo, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
659 subfile_sizer->Add( subbrowse_button, 0, wxALL |wxALIGN_CENTER_VERTICAL, 5 );
661 subfile_combo->Disable();
662 subbrowse_button->Disable();
664 psz_subsfile = config_GetPsz( p_intf, "sub-file" );
665 if( psz_subsfile && *psz_subsfile )
667 subfile_combo->Enable();
668 subbrowse_button->Enable();
671 sizer->Add( file_sizer, 0, wxEXPAND | wxALL, 5 );
672 sizer->Add( subtitles_sizer, 0, wxLEFT | wxRIGHT | wxTOP, 5 );
673 sizer->Add( subfile_sizer, 0, wxEXPAND | wxLEFT | wxRIGHT| wxBOTTOM, 5 );
674 panel->SetSizerAndFit( sizer );
678 wxPanel *OpenDialog::DiscPanel( wxWindow* parent )
680 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
683 wxBoxSizer *sizer_row = new wxBoxSizer( wxVERTICAL );
684 wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 3, 20 );
686 static const wxString disc_type_array[] =
688 wxU(_("DVD (menus)")),
694 disc_type = new wxRadioBox( panel, DiscType_Event, wxU(_("Disc type")),
695 wxDefaultPosition, wxDefaultSize,
696 WXSIZEOF(disc_type_array), disc_type_array,
697 WXSIZEOF(disc_type_array), wxRA_SPECIFY_COLS );
700 disc_probe = new wxCheckBox( panel, DiscProbe_Event,
701 wxU(_("Probe Disc(s)")) );
702 disc_probe->SetToolTip( wxU(_("Probe for a DVD, VCD or audio CD. "
703 "First try the Device name entered for the selected Disc type "
704 "(DVD, DVD Menu, VCD, audio CD). If that doesn't find media, try any device "
705 "for the Disc type. If that doesn't work, then try looking for CD-ROMs or "
706 "DVD drives. The Disc type, Device name, and some parameter ranges are set "
707 "based on media we find.")) );
710 sizer_row->Add( disc_type, i_disc_type_selection, wxEXPAND | wxALL, 5 );
712 sizer_row->Add( disc_probe, 0, wxEXPAND | wxALL );
715 wxStaticText *label = new wxStaticText( panel, -1, wxU(_("Device name")) );
716 disc_device = new wxTextCtrl( panel, DiscDevice_Event, wxT(""),
717 wxDefaultPosition, wxDefaultSize,
721 char psz_default_device[3] = {0};
724 /* find the drive_name for the first cdrom drive,
725 * which is probably "D:" and put the drive_name into
726 * psz_default_device... */
727 for( char drive_letter = 'A'; drive_letter <= 'Z'; ++drive_letter )
729 char drive_name[3] = {drive_letter, ':', 0};
730 UINT type = GetDriveTypeA( drive_name );
731 if( type == DRIVE_CDROM )
733 psz_default_device[0] = drive_letter;
734 psz_default_device[1] = ':';
739 psz_forced = config_GetPsz( p_intf, "dvd" );
741 if( strlen(psz_default_device) > 0 &&
742 ( !psz_forced || psz_forced && !*psz_forced ) )
745 disc_device->SetValue( wxL2U(psz_default_device) );
749 sizer->Add( label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
750 sizer->Add( disc_device, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
752 disc_title_label = new wxStaticText( panel, -1, wxU(_("Title")) );
753 disc_title = new wxSpinCtrl( panel, DiscTitle_Event );
754 sizer->Add( disc_title_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
755 sizer->Add( disc_title, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
757 disc_chapter_label = new wxStaticText( panel, -1, wxU(_("Chapter")) );
758 disc_chapter = new wxSpinCtrl( panel, DiscChapter_Event );
759 sizer->Add( disc_chapter_label, 0,
760 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
761 sizer->Add( disc_chapter, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
763 disc_sub_label = new wxStaticText( panel, -1, wxU(_("Subtitles track")) );
764 disc_sub = new wxSpinCtrl( panel, DiscSub_Event );
765 sizer->Add( disc_sub_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
766 sizer->Add( disc_sub, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
767 disc_sub->SetRange( -1, 255 );
768 i_disc_sub = config_GetInt( p_intf, "sub-track" );
769 disc_sub->SetValue( i_disc_sub );
771 disc_audio_label = new wxStaticText( panel, -1, wxU(_("Audio track")) );
772 disc_audio = new wxSpinCtrl( panel, DiscAudio_Event );
773 sizer->Add( disc_audio_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
774 sizer->Add( disc_audio, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
775 disc_audio->SetRange( -1, 255 );
776 i_disc_audio = config_GetInt( p_intf, "audio-track" );
777 disc_audio->SetValue( i_disc_audio );
779 sizer_row->Add( sizer, 0, wxEXPAND | wxALL, 5 );
781 panel->SetSizerAndFit( sizer_row );
785 wxPanel *OpenDialog::NetPanel( wxWindow* parent )
788 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
791 wxBoxSizer *sizer_row = new wxBoxSizer( wxVERTICAL );
792 wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 4, 20 );
794 static const wxString net_type_array[] =
797 wxU(_("UDP/RTP Multicast")),
798 wxU(_("HTTP/HTTPS/FTP/MMS")),
804 net_radios[i] = new wxRadioButton( panel, NetRadio1_Event + i,
806 wxDefaultPosition, wxDefaultSize,
809 net_subpanels[i] = new wxPanel( panel, -1,
810 wxDefaultPosition, wxDefaultSize );
814 net_timeshift = new wxCheckBox( panel, NetTimeshift_Event,
815 wxU(_("Allow timeshifting")) );
818 wxFlexGridSizer *subpanel_sizer;
820 i_net_ports[0] = config_GetInt( p_intf, "server-port" );
821 subpanel_sizer = new wxFlexGridSizer( 3, 1, 20 );
822 label = new wxStaticText( net_subpanels[0], -1, wxU(_("Port")) );
823 net_ports[0] = new wxSpinCtrl( net_subpanels[0], NetPort1_Event,
824 wxString::Format(wxT("%d"), i_net_ports[0]),
825 wxDefaultPosition, wxDefaultSize,
827 0, 65535, i_net_ports[0] );
829 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
830 subpanel_sizer->Add( net_ports[0], 1,
831 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
832 net_ipv6 = new wxCheckBox( net_subpanels[0], NetForceIPv6_Event,
833 wxU(_("Force IPv6")));
834 subpanel_sizer->Add( net_ipv6, 0,
835 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
836 net_subpanels[0]->SetSizerAndFit( subpanel_sizer );
837 net_radios[0]->SetValue( TRUE );
839 /* UDP/RTP Multicast row */
840 subpanel_sizer = new wxFlexGridSizer( 4, 1, 20 );
841 label = new wxStaticText( net_subpanels[1], -1, wxU(_("Address")) );
842 net_addrs[1] = new wxTextCtrl( net_subpanels[1], NetAddr2_Event, wxT(""),
843 wxDefaultPosition, wxDefaultSize,
845 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
846 subpanel_sizer->Add( net_addrs[1], 1,
847 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
849 label = new wxStaticText( net_subpanels[1], -1, wxU(_("Port")) );
850 i_net_ports[1] = i_net_ports[0];
851 net_ports[1] = new wxSpinCtrl( net_subpanels[1], NetPort2_Event,
852 wxString::Format(wxT("%d"), i_net_ports[1]),
853 wxDefaultPosition, wxDefaultSize,
855 0, 65535, i_net_ports[1] );
857 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
858 subpanel_sizer->Add( net_ports[1], 1,
859 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
860 net_subpanels[1]->SetSizerAndFit( subpanel_sizer );
862 /* HTTP and RTSP rows */
865 subpanel_sizer = new wxFlexGridSizer( 2, 1, 20 );
866 label = new wxStaticText( net_subpanels[i], -1, wxU(_("URL")) );
867 net_addrs[i] = new wxTextCtrl( net_subpanels[i], NetAddr1_Event + i,
868 (i == 2) ? wxT("") : wxT("rtsp://"),
869 wxDefaultPosition, wxSize( 200, -1 ),
871 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
872 subpanel_sizer->Add( net_addrs[i], 1,
873 wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
874 net_subpanels[i]->SetSizerAndFit( subpanel_sizer );
877 /* Stuff everything into the main panel */
880 sizer->Add( net_radios[i], 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
882 sizer->Add( net_subpanels[i], 1, wxEXPAND | wxALIGN_LEFT |
883 wxALIGN_CENTER_VERTICAL | wxALL, 5 );
885 sizer->Add( net_timeshift, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
888 sizer_row->Add( sizer, 0, wxEXPAND | wxALL, 5 );
890 panel->SetSizerAndFit( sizer_row );
894 void OpenDialog::UpdateMRL()
896 UpdateMRL( i_current_access_method );
899 void OpenDialog::UpdateMRL( int i_access_method )
901 wxString mrltemp, caching_name;
903 i_current_access_method = i_access_method;
905 switch( i_access_method )
908 mrltemp = file_combo->GetValue();
909 caching_name = wxT("file-caching");
913 i_disc_type_selection = disc_type->GetSelection();
915 switch ( i_disc_type_selection )
917 case 0: /* DVD with menus */
918 case 1: /* DVD without menus */
919 disc_device->SetToolTip( wxU(_("DVD device to use" ) ) );
920 if( i_disc_type_selection == 0 )
922 mrltemp = wxT("dvd://") + disc_device->GetValue();
923 caching_name = wxT("dvdnav-caching");
927 mrltemp = wxT("dvdsimple://") + disc_device->GetValue();
928 caching_name = wxT("dvdread-caching");
931 if( i_disc_title > 0 )
933 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
935 if( i_disc_chapter > 0 )
936 mrltemp += wxString::Format( wxT(":%d"), i_disc_chapter );
939 if( i_disc_sub >= 0 )
940 mrltemp += wxString::Format( wxT(" :sub-track=%d"),
942 if( i_disc_audio >= 0 )
943 mrltemp += wxString::Format( wxT(" :audio-track=%d"),
947 case 2: /* VCD of some sort */
949 disc_device->SetToolTip( wxU(_("Name of CD-ROM device "
950 "to read Video CD from. If this field is left empty, we will scan "
951 "for a CD-ROM with a VCD in it.")) );
952 mrltemp = wxT("vcdx://") + disc_device->GetValue();
953 if( i_disc_title > 0 )
954 mrltemp += wxString::Format( wxT("@%c%d"),
955 config_GetInt( p_intf, "vcdx-PBC" )
956 ? 'P' : 'E', i_disc_title );
958 disc_device->SetToolTip( wxU(_("CD-ROM device to use" ) ) );
959 mrltemp = wxT("vcd://") + disc_device->GetValue();
960 if( i_disc_title > 0 )
961 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
964 if( i_disc_sub >= 0 )
965 mrltemp += wxString::Format( wxT(" :sub-track=%d"),
968 if( i_disc_audio >= 0 )
969 mrltemp += wxString::Format( wxT(" :audio-track=%d"),
971 caching_name = wxT("vcd-caching");
976 disc_device->SetToolTip( wxU(_("Name of CD-ROM device "
977 "to read audio CD from. If this field is left empty, we will scan "
978 "for a CD-ROM with an audio CD in it." )) );
979 mrltemp = wxT("cddax://")
981 disc_device->SetToolTip( wxU(_("CD-ROM device to use" ) ) ) ;
982 mrltemp = wxT("cdda://")
984 + disc_device->GetValue();
985 if( i_disc_title > 0 )
986 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
988 caching_name = wxT("cdda-caching");
992 msg_Err( p_intf, "invalid selection (%d)",
993 disc_type->GetSelection() );
1002 mrltemp = wxT("udp://@");
1003 if ( net_ipv6->GetValue() )
1005 mrltemp += wxT("[::]");
1007 if( i_net_ports[0] !=
1008 config_GetInt( p_intf, "server-port" ) )
1010 mrltemp += wxString::Format( wxT(":%d"), i_net_ports[0] );
1013 caching_name = wxT("udp-caching");
1017 mrltemp = wxT("udp://@");
1018 if ((net_addrs[1]->GetLineText(0).Find (':') != -1)
1019 && (net_addrs[1]->GetLineText(0)[0u] != '['))
1021 /* automatically adds '[' and ']' to IPv6 addresses */
1022 mrltemp += wxT("[") + net_addrs[1]->GetLineText(0)
1027 mrltemp += net_addrs[1]->GetLineText(0);
1029 if( i_net_ports[1] != config_GetInt( p_intf, "server-port" ) )
1031 mrltemp += wxString::Format( wxT(":%d"), i_net_ports[1] );
1034 caching_name = wxT("udp-caching");
1039 if( net_addrs[2]->GetLineText(0).Find(wxT("://")) == -1 )
1040 mrltemp = wxT("http://");
1042 mrltemp += net_addrs[2]->GetLineText(0);
1043 if( ! mrltemp.Left(4).CmpNoCase(wxT("http")) )
1044 caching_name = wxT("http-caching");
1045 else if( ! mrltemp.Left(3).CmpNoCase(wxT("mms")) )
1046 caching_name = wxT("mms-caching");
1048 caching_name= wxT("ftp-caching");
1053 if( net_addrs[3]->GetLineText(0).Find(wxT("rtsp://")) != 0 )
1055 mrltemp = wxT("rtsp://");
1057 mrltemp += net_addrs[3]->GetLineText(0);
1059 caching_name = wxT("rtsp-caching");
1062 if( net_timeshift->IsEnabled() && net_timeshift->IsChecked() )
1063 mrltemp += wxT(" :access-filter=timeshift");
1068 int i_item = i_access_method - MAX_ACCESS;
1070 if( i_item < 0 || i_item >= (int)input_tab_array.GetCount() )
1073 AutoBuiltPanel *input_panel = input_tab_array.Item( i_item );
1075 mrltemp = input_panel->name + wxT("://");
1077 for( int i=0; i < (int)input_panel->config_array.GetCount(); i++ )
1079 ConfigControl *control = input_panel->config_array.Item(i);
1081 mrltemp += wxT(" :");
1083 if( control->GetType() == CONFIG_ITEM_BOOL &&
1084 !control->GetIntValue() ) mrltemp += wxT("no-");
1086 mrltemp += control->GetName();
1088 switch( control->GetType() )
1090 case CONFIG_ITEM_STRING:
1091 case CONFIG_ITEM_FILE:
1092 case CONFIG_ITEM_DIRECTORY:
1093 case CONFIG_ITEM_MODULE:
1094 mrltemp += wxT("=\"") + control->GetPszValue() + wxT("\"");
1096 case CONFIG_ITEM_INTEGER:
1098 wxString::Format( wxT("=%i"), control->GetIntValue() );
1100 case CONFIG_ITEM_FLOAT:
1102 wxString::Format(wxT("=%f"), control->GetFloatValue());
1107 if( input_panel->p_advanced_mrl_combo &&
1108 input_panel->p_advanced_mrl_combo->GetValue() )
1110 mrltemp += wxT(" ") +
1111 input_panel->p_advanced_mrl_combo->GetValue();
1117 if( caching_name.size() )
1119 if( caching_value->IsEnabled() )
1121 mrltemp += wxT(" :") + caching_name +
1122 wxString::Format( wxT("=%d"), i_caching );
1126 int i_value = config_GetInt( p_intf, caching_name.mb_str(wxConvUTF8) );
1127 caching_value->SetValue( i_value );
1131 mrl_combo->SetValue( mrltemp );
1134 /*****************************************************************************
1136 *****************************************************************************/
1137 void OpenDialog::OnOk( wxCommandEvent& WXUNUSED(event) )
1139 mrl = SeparateEntries( mrl_combo->GetValue() );
1140 mrl_combo->Append( mrl_combo->GetValue() );
1141 if( mrl_combo->GetCount() > 10 ) mrl_combo->Delete( 0 );
1142 mrl_combo->SetSelection( mrl_combo->GetCount() - 1 );
1144 if( i_method == OPEN_STREAM )
1146 if( IsModal() ) EndModal( wxID_OK );
1151 /* Update the playlist */
1152 playlist_t *p_playlist =
1153 (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
1155 if( p_playlist == NULL ) return;
1157 for( int i = 0; i < (int)mrl.GetCount(); i++ )
1159 vlc_bool_t b_start = !i && i_open_arg;
1160 input_item_t *p_input;
1163 psz_utf8 = wxFromLocale( mrl[i] );
1164 p_input = input_ItemNew( p_intf, psz_utf8, NULL );
1165 wxLocaleFree( psz_utf8 );
1167 /* Insert options */
1168 while( i + 1 < (int)mrl.GetCount() &&
1169 ((const char *)mrl[i + 1].mb_str(wxConvUTF8))[0] == ':' )
1171 psz_utf8 = wxFromLocale( mrl[i + 1] );
1172 input_ItemAddOption( p_input, psz_utf8 );
1173 wxLocaleFree( psz_utf8 );
1177 /* Get the options from the subtitles dialog */
1178 if( subsfile_checkbox->IsChecked() && subsfile_mrl.GetCount() )
1180 for( int j = 0; j < (int)subsfile_mrl.GetCount(); j++ )
1182 psz_utf8 = wxFromLocale( subsfile_mrl[j] );
1183 input_ItemAddOption( p_input, psz_utf8 );
1184 wxLocaleFree( psz_utf8 );
1188 /* Get the options from the stream output dialog */
1189 if( sout_checkbox->IsChecked() && sout_mrl.GetCount() )
1191 for( int j = 0; j < (int)sout_mrl.GetCount(); j++ )
1193 psz_utf8 = wxFromLocale( sout_mrl[j] );
1194 input_ItemAddOption( p_input, psz_utf8 );
1195 wxLocaleFree( psz_utf8 );
1201 playlist_AddInput( p_playlist, p_input,
1202 PLAYLIST_APPEND | PLAYLIST_GO,
1203 PLAYLIST_END, VLC_TRUE, VLC_FALSE );
1207 playlist_AddInput( p_playlist, p_input,
1208 PLAYLIST_APPEND|PLAYLIST_PREPARSE,
1209 PLAYLIST_END, VLC_TRUE, VLC_FALSE );
1213 vlc_object_release( p_playlist );
1217 if( IsModal() ) EndModal( wxID_OK );
1220 void OpenDialog::OnCancel( wxCommandEvent& WXUNUSED(event) )
1222 wxCloseEvent cevent;
1226 void OpenDialog::OnClose( wxCloseEvent& WXUNUSED(event) )
1230 if( IsModal() ) EndModal( wxID_CANCEL );
1233 void OpenDialog::OnPageChange( wxNotebookEvent& event )
1235 UpdateMRL( event.GetSelection() );
1238 void OpenDialog::OnMRLChange( wxCommandEvent& event )
1240 //mrl = SeparateEntries( event.GetString() );
1243 /*****************************************************************************
1244 * File panel event methods.
1245 *****************************************************************************/
1246 void OpenDialog::OnFilePanelChange( wxCommandEvent& WXUNUSED(event) )
1248 UpdateMRL( FILE_ACCESS );
1251 void OpenDialog::OnFileBrowse( wxCommandEvent& WXUNUSED(event) )
1253 if( file_dialog == NULL )
1254 file_dialog = new wxFileDialog( this, wxU(_("Open File")),
1255 wxT(""), wxT(""), wxT("*"), wxOPEN | wxMULTIPLE );
1257 file_dialog->SetWildcard(wxU(_("All Files (*.*)|*"
1258 "|Sound Files (*.mp3, *.ogg, etc.)|" EXTENSIONS_AUDIO
1259 "|Video Files (*.avi, *.mpg, etc.)|" EXTENSIONS_VIDEO
1260 "|Playlist Files (*.m3u, *.pls, etc.)|" EXTENSIONS_PLAYLIST
1261 "|Subtitle Files (*.srt, *.sub, etc.)|" EXTENSIONS_SUBTITLE)));
1263 if( file_dialog && file_dialog->ShowModal() == wxID_OK )
1265 wxArrayString paths;
1268 file_dialog->GetPaths( paths );
1270 for( size_t i = 0; i < paths.GetCount(); i++ )
1272 if( paths[i].Find( wxT(' ') ) >= 0 )
1273 path += wxT("\"") + paths[i] + wxT("\" ");
1275 path += paths[i] + wxT(" ");
1278 file_combo->SetValue( path );
1279 file_combo->Append( path );
1280 if( file_combo->GetCount() > 10 ) file_combo->Delete( 0 );
1281 UpdateMRL( FILE_ACCESS );
1285 void OpenDialog::OnSubFileBrowse( wxCommandEvent& WXUNUSED(event) )
1287 wxFileDialog dialog( this, wxU(_("Open subtitles file")),
1288 wxT(""), wxT(""), wxT("*"), wxOPEN );
1290 if( dialog.ShowModal() == wxID_OK )
1292 subfile_combo->SetValue( dialog.GetPath() );
1294 wxCommandEvent event; OnSubFileChange( event );
1297 void OpenDialog::OnSubFileChange( wxCommandEvent& WXUNUSED(event) )
1299 if( subsfile_mrl.GetCount() != 0 )
1301 subsfile_mrl.RemoveAt( 0 );
1302 subsfile_mrl.Insert( wxString(wxT("sub-file=")) + subfile_combo->GetValue() , 0 );
1306 subsfile_mrl.Add( wxString(wxT("sub-file=")) + subfile_combo->GetValue() );
1310 /*****************************************************************************
1311 * Disc panel event methods.
1312 *****************************************************************************/
1313 void OpenDialog::OnDiscPanelChangeSpin( wxSpinEvent& event )
1315 wxCommandEvent cevent;
1316 cevent.SetId(event.GetId());
1317 cevent.SetInt(event.GetPosition());
1318 OnDiscPanelChange(cevent);
1321 void OpenDialog::OnDiscPanelChange( wxCommandEvent& event )
1323 if( event.GetId() == DiscTitle_Event ) i_disc_title = event.GetInt();
1324 if( event.GetId() == DiscChapter_Event ) i_disc_chapter = event.GetInt();
1325 if( event.GetId() == DiscSub_Event ) i_disc_sub = event.GetInt();
1326 if( event.GetId() == DiscAudio_Event ) i_disc_audio = event.GetInt();
1328 UpdateMRL( DISC_ACCESS );
1331 void OpenDialog::OnDiscDeviceChange( wxCommandEvent& event )
1335 switch( disc_type->GetSelection() )
1338 psz_device = config_GetPsz( p_intf, "cd-audio" );
1342 psz_device = config_GetPsz( p_intf, "vcd" );
1346 psz_device = config_GetPsz( p_intf, "dvd" );
1350 if ( !psz_device ) psz_device = "";
1352 if( disc_device->GetValue().Cmp( wxL2U( psz_device ) ) )
1354 b_disc_device_changed = true;
1357 UpdateMRL( DISC_ACCESS );
1362 /* Return true if *psz_drive is a drive with a DVD in it. A more complete
1363 check would see if the media looks like a *playable* DVD. This should
1366 static bool IsDVD(const char *psz_drive)
1368 CdIo_t *p_cdio = cdio_open (psz_drive, DRIVER_UNKNOWN);
1371 discmode_t discmode = cdio_get_discmode(p_cdio);
1372 cdio_destroy(p_cdio);
1373 return cdio_is_discmode_dvd(discmode);
1379 /* Return a device that has a DVD in it. The caller needs to free
1380 the returned string.
1382 static char * ProbeDVD(const wxChar *device)
1385 char **ppsz_cd_drives;
1386 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1387 char *psz_device = (char *) tmp_buf;
1389 if( IsDVD(psz_device) )
1391 return strdup(psz_device);
1394 ppsz_cd_drives = cdio_get_devices(DRIVER_DEVICE);
1395 if( ppsz_cd_drives )
1398 for( c = ppsz_cd_drives; *c != NULL; c++ )
1402 char *psz_drive = strdup(*c);
1403 cdio_free_device_list(ppsz_cd_drives);
1404 return strdup(psz_drive);
1407 cdio_free_device_list(ppsz_cd_drives);
1413 static char * ProbeDevice(char **ppsz_search_devices, cdio_fs_anal_t mask,
1416 char **ppsz_devices;
1418 if( ppsz_search_devices && !ppsz_search_devices[0] )
1419 ppsz_search_devices = NULL;
1421 /* Start out trying the device that has been entered so far. */
1422 ppsz_devices = cdio_get_devices_with_cap(ppsz_search_devices, mask,
1425 if (ppsz_devices && *ppsz_devices)
1427 char *psz_device = strdup(*ppsz_devices);
1428 cdio_free_device_list(ppsz_devices);
1432 /* If there was no device specified on the first try, then give up
1433 now. Otherwise accept any CD-ROM in the class (e.g. VCD or DVD).
1435 if( !ppsz_search_devices ) return NULL;
1437 ppsz_devices = cdio_get_devices_with_cap(NULL, mask, true);
1439 if (ppsz_devices && *ppsz_devices)
1441 char *psz_device = strdup(*ppsz_devices);
1442 cdio_free_device_list(ppsz_devices);
1450 /* Return a device that has a CD-DA in it. The caller needs to free
1451 the returned string.
1453 static char * ProbeCDDA(const wxChar *device)
1456 char *ppsz_device[2];
1457 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1458 char *psz_device = (char *) tmp_buf;
1459 ppsz_device[0] = (device && *device) ? psz_device : NULL;
1460 ppsz_device[1] = NULL;
1461 return ProbeDevice(ppsz_device, CDIO_FS_AUDIO, false);
1465 /* Return a device that has a VCD in it. The caller needs to free
1466 the returned string.
1468 static char * ProbeVCD(const wxChar *device)
1470 char *ppsz_device[2];
1471 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1472 char *psz_device = (char *) tmp_buf;
1473 ppsz_device[0] = (device && *device) ? psz_device : NULL;
1474 ppsz_device[1] = NULL;
1475 return ProbeDevice(ppsz_device,
1476 (CDIO_FS_ANAL_SVCD|CDIO_FS_ANAL_CVD|CDIO_FS_ANAL_VIDEOCD
1477 |CDIO_FS_UNKNOWN), true);
1483 Probe (find anywhere) a CD-DA, VCD, or a DVD.
1484 First try the device name that may have been entered for the "disc type"
1485 selected. If that doesn't work we try any device for the disc type.
1486 If that doesn't work, try looking for CD-ROMs or DVD drives. the
1487 disc type, device name and paramter ranges are set to whatever we find.
1489 void OpenDialog::OnDiscProbe( wxCommandEvent& WXUNUSED(event) )
1491 wxCommandEvent dummy_event;
1492 char *psz_device = NULL;
1493 bool b_probed_DVD = false;
1494 bool b_probed_VCD = false;
1495 const int i_selection = disc_type->GetSelection();
1497 /* Reduce verbosity of cdio errors. */
1498 cdio_loglevel_default = CDIO_LOG_ERROR;
1501 switch( disc_type->GetSelection() )
1504 case SELECTION_DISC_TYPE_DVD_MENUS:
1505 case SELECTION_DISC_TYPE_DVD:
1506 /* If not a DVD then try for a VCD. If VCD fails it will
1508 if (!psz_device) psz_device = ProbeDVD(disc_device->GetValue());
1511 b_probed_DVD = true;
1512 disc_type->SetSelection(SELECTION_DISC_TYPE_VCD);
1513 OnDiscTypeChange( dummy_event );
1516 disc_device->SetValue( wxL2U(psz_device) );
1519 case SELECTION_DISC_TYPE_VCD: /* VCD probe of some sort */
1520 if(!psz_device) psz_device = ProbeVCD(disc_device->GetValue());
1524 #if LIBVCD_VERSION_NUM > 23
1525 vcdinfo_obj_t *p_vcdinfo;
1527 /* Set LID or entry range accurately if possible. */
1528 if( vcdinfo_open(&p_vcdinfo, &psz_device, DRIVER_DEVICE,
1529 NULL) == VCDINFO_OPEN_VCD)
1531 if (config_GetInt( p_intf, "vcdx-PBC" ))
1533 /* Set largest LID. */;
1534 disc_title->SetRange( 0, vcdinfo_get_num_LIDs(p_vcdinfo) );
1539 /* Set largest Entry */
1540 disc_title->SetRange( 0,
1541 vcdinfo_get_num_entries(p_vcdinfo)-1 );
1543 vcdinfo_close(p_vcdinfo);
1545 #endif /* LIBVCD_VERSION_NUM > 23 */
1546 disc_device->SetValue( wxL2U(psz_device) );
1548 CdIo_t *p_cdio = cdio_open (psz_device, DRIVER_UNKNOWN);
1549 disc_device->SetValue( wxL2U(psz_device) );
1551 /* Set track range accurately if possible. */
1554 track_t i_last_track = cdio_get_last_track_num(p_cdio);
1555 disc_title->SetRange( 0, i_last_track-1 );
1557 cdio_destroy(p_cdio);
1562 b_probed_VCD = true;
1564 /* Not a VCD. Try for a DVD unless we've been there before. */
1565 if( !b_probed_DVD && (psz_device = ProbeDVD(disc_device->GetValue())) )
1567 disc_type->SetSelection(SELECTION_DISC_TYPE_DVD_MENUS);
1568 OnDiscTypeChange( dummy_event );
1571 b_probed_DVD = true;
1573 /* Couldn't find a VCD or DVD. See if we can find a CD-DA. */
1574 psz_device = ProbeCDDA(disc_device->GetValue());
1577 disc_type->SetSelection(SELECTION_DISC_TYPE_CDDA);
1578 OnDiscTypeChange( dummy_event );
1582 /* Couldn't find a VCD, DVD or CD-DA. Null out the Device name and
1583 set to original selection.
1585 disc_device->SetValue( wxL2U("") );
1586 disc_type->SetSelection(i_selection);
1587 OnDiscTypeChange( dummy_event );
1590 case SELECTION_DISC_TYPE_CDDA:
1591 if(!psz_device) psz_device = ProbeCDDA(disc_device->GetValue());
1594 CdIo_t *p_cdio = cdio_open (psz_device, DRIVER_UNKNOWN);
1595 disc_device->SetValue( wxL2U(psz_device) );
1598 track_t i_last_track = cdio_get_last_track_num(p_cdio);
1599 disc_title->SetRange( 0, i_last_track );
1601 MediaInsertCDDA( p_intf, p_cdio, i_last_track );
1604 cdio_destroy(p_cdio);
1608 /* Not a CD-DA. Try for a DVD unless we've been there before. */
1609 if( !b_probed_DVD && (psz_device = ProbeDVD(disc_device->GetValue())) )
1611 disc_type->SetSelection(SELECTION_DISC_TYPE_DVD_MENUS);
1612 OnDiscTypeChange( dummy_event );
1616 /* Couldn't find a CD-DA or DVD. See if we can find a VCD, unless
1617 we've tried that before. */
1618 if (!b_probed_VCD) psz_device = ProbeVCD(disc_device->GetValue());
1621 disc_type->SetSelection(SELECTION_DISC_TYPE_VCD);
1622 OnDiscTypeChange( dummy_event );
1625 disc_device->SetValue( wxL2U("") );
1629 msg_Err( p_intf, "invalid Disc type selection (%d)",
1630 disc_type->GetSelection() );
1635 disc_probe->SetValue(FALSE);
1637 UpdateMRL( DISC_ACCESS );
1639 #endif /* HAVE_LIBCDIO */
1641 void OpenDialog::OnDiscTypeChange( wxCommandEvent& WXUNUSED(event) )
1643 char *psz_device = NULL;
1645 switch( disc_type->GetSelection() )
1648 case SELECTION_DISC_TYPE_DVD_MENUS:
1649 case SELECTION_DISC_TYPE_DVD:
1650 disc_sub->Enable(); disc_sub_label->Enable();
1651 disc_audio->Enable(); disc_audio_label->Enable();
1652 disc_chapter->Enable(); disc_chapter_label->Enable();
1653 disc_title_label->SetLabel ( wxU(_("Title")) );
1654 psz_device = config_GetPsz( p_intf, "dvd" );
1655 if( !b_disc_device_changed )
1657 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1658 else disc_device->SetValue( wxT("") );
1660 disc_title->SetRange( 0, 255 );
1661 disc_sub->SetRange( -1, 31 ); // up to 32 subtitles -1: no subtitle
1662 disc_audio->SetRange( 0, 7 ); // up to 8 audio channels
1663 disc_chapter->SetRange( 0, 255 );
1664 disc_title->SetToolTip( wxU(_("Title number.")) );
1665 disc_sub->SetToolTip( wxU(_(
1666 "DVDs can have up to 32 subtitles numbered 0..31. "
1667 "Note this is not the same thing as a subtitle name (e.g. 'en'). "
1668 "If a value -1 is used, no subtitle will be shown." )) );
1669 disc_audio->SetToolTip( wxU(_("Audio track number. "
1670 "DVDs can have up to 8 audio tracks numbered 0..7."
1674 case SELECTION_DISC_TYPE_VCD:
1675 disc_sub->Enable(); disc_sub_label->Enable();
1676 disc_audio->Enable(); disc_audio_label->Enable();
1677 disc_chapter->Disable(); disc_chapter_label->Disable();
1678 psz_device = config_GetPsz( p_intf, "vcd" );
1679 if( !b_disc_device_changed )
1681 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1682 else disc_device->SetValue( wxT("") );
1686 if (config_GetInt( p_intf, "vcdx-PBC" ))
1688 disc_title_label->SetLabel ( wxT("Playback LID") );
1689 disc_title->SetToolTip( wxU(_(
1690 "Playback control (PBC) usually starts with number 1." )) );
1694 disc_title_label->SetLabel ( wxT("Entry") );
1695 disc_title->SetToolTip( wxU(_(
1696 "The first entry (the beginning of the first MPEG track) is 0." )) );
1700 disc_title_label->SetLabel ( wxU(_("Track")) );
1701 disc_title->SetToolTip( wxU(_("Track number.")) );
1703 disc_title->SetRange( 0, 99 ); // only 100 tracks allowed on VCDs
1704 disc_sub->SetRange( -1, 3 ); // up to 4 subtitles -1 = no subtitle
1705 disc_audio->SetRange( 0, 1 ); // up to 2 audio tracks
1706 disc_sub->SetToolTip( wxU(_(
1707 "SVCDs can have up to 4 subtitles numbered 0..3. "
1708 "If a value -1 is used, no subtitle will be shown." )) );
1709 disc_audio->SetToolTip( wxU(_("Audio track number. "
1710 "VCDs can have up to 2 audio tracks numbered 0 or 1. "
1714 case SELECTION_DISC_TYPE_CDDA:
1715 disc_sub->Disable(); disc_sub_label->Disable();
1716 disc_chapter->Disable(); disc_chapter_label->Disable();
1717 disc_audio->Disable(); disc_audio_label->Disable();
1718 disc_title_label->SetLabel ( wxU(_("Track")) );
1720 disc_title->SetToolTip( wxU(_(
1721 "Audio CDs can have up to 100 tracks, the first track is usually 1. "
1722 "If 0 is given, then all tracks are played.")) );
1724 disc_title->SetToolTip( wxU(_(
1725 "Audio CDs can have up to 100 tracks, the first track is usually 1."
1728 psz_device = config_GetPsz( p_intf, "cd-audio" );
1729 if( !b_disc_device_changed )
1731 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1732 else disc_device->SetValue( wxT("") );
1735 /* There are at most 100 tracks in a CD-DA */
1736 disc_title->SetRange( 0, 100 );
1740 msg_Err( p_intf, "invalid Disc type selection (%d)",
1741 disc_type->GetSelection() );
1745 disc_title->SetValue( 0 ); i_disc_title = 0;
1746 disc_chapter->SetValue( 0 ); i_disc_chapter = 0;
1748 if( psz_device ) free( psz_device );
1750 UpdateMRL( DISC_ACCESS );
1753 /*****************************************************************************
1754 * Net panel event methods.
1755 *****************************************************************************/
1756 void OpenDialog::OnNetPanelChangeSpin( wxSpinEvent& event )
1758 wxCommandEvent cevent;
1759 cevent.SetId(event.GetId());
1760 cevent.SetInt(event.GetPosition());
1761 OnNetPanelChange(cevent);
1764 void OpenDialog::OnNetPanelChange( wxCommandEvent& event )
1766 if( event.GetId() >= NetPort1_Event && event.GetId() <= NetPort3_Event )
1768 i_net_ports[event.GetId() - NetPort1_Event] = event.GetInt();
1771 UpdateMRL( NET_ACCESS );
1774 void OpenDialog::OnNetTypeChange( wxCommandEvent& event )
1778 i_net_type = event.GetId() - NetRadio1_Event;
1782 net_radios[i]->SetValue( event.GetId() == (NetRadio1_Event+i) );
1783 net_subpanels[i]->Enable( event.GetId() == (NetRadio1_Event+i) );
1785 /* UDP Unicast or multicast -> timeshift */
1786 if( i_net_type == 0 || i_net_type == 1 )
1787 net_timeshift->Enable();
1789 net_timeshift->Disable();
1791 UpdateMRL( NET_ACCESS );
1794 /*****************************************************************************
1795 * Subtitles file event methods.
1796 *****************************************************************************/
1797 void OpenDialog::OnSubsFileEnable( wxCommandEvent& event )
1799 subsfile_button->Enable( event.GetInt() != 0 );
1800 subbrowse_button->Enable( event.GetInt() != 0 );
1801 subfile_combo->Enable( event.GetInt() != 0 );
1804 void OpenDialog::OnSubsFileSettings( wxCommandEvent& WXUNUSED(event) )
1806 /* Show/hide the open dialog */
1807 if( subsfile_dialog == NULL )
1808 subsfile_dialog = new SubsFileDialog( p_intf, this );
1810 if( subsfile_dialog && subsfile_dialog->ShowModal() == wxID_OK )
1812 subsfile_mrl.Empty();
1813 subsfile_mrl.Add( wxString(wxT("sub-file=")) + subfile_combo->GetValue() );
1814 if( subsfile_dialog->encoding_combo )
1816 subsfile_mrl.Add( wxString(wxT("subsdec-encoding=")) +
1817 subsfile_dialog->encoding_combo->GetValue() );
1819 if( subsfile_dialog->align_combo )
1821 subsfile_mrl.Add( wxString::Format(wxT("subsdec-align=%i"),
1822 (int)subsfile_dialog->align_combo->GetClientData(
1823 subsfile_dialog->align_combo->GetSelection()) ) );
1825 if( subsfile_dialog->size_combo )
1827 subsfile_mrl.Add( wxString::Format( wxT("freetype-rel-fontsize=%i"),
1828 (int)subsfile_dialog->size_combo->GetClientData(
1829 subsfile_dialog->size_combo->GetSelection()) ) );
1831 subsfile_mrl.Add( wxString( wxT("sub-fps="))+
1832 subsfile_dialog->fps_ctrl->GetValue() );
1833 subsfile_mrl.Add( wxString::Format( wxT("sub-delay=%i"),
1834 subsfile_dialog->delay_spinctrl->GetValue() ) );
1838 /*****************************************************************************
1839 * Stream output event methods.
1840 *****************************************************************************/
1841 void OpenDialog::OnSoutEnable( wxCommandEvent& event )
1843 sout_button->Enable( event.GetInt() != 0 );
1846 void OpenDialog::OnSoutSettings( wxCommandEvent& WXUNUSED(event) )
1848 /* Show/hide the open dialog */
1849 if( sout_dialog == NULL )
1850 sout_dialog = new SoutDialog( p_intf, this );
1852 if( sout_dialog && sout_dialog->ShowModal() == wxID_OK )
1854 sout_mrl = sout_dialog->GetOptions();
1858 /*****************************************************************************
1859 * Caching event methods.
1860 *****************************************************************************/
1861 void OpenDialog::OnCachingEnable( wxCommandEvent& event )
1863 caching_value->Enable( event.GetInt() != 0 );
1864 i_caching = caching_value->GetValue();
1868 void OpenDialog::OnCachingChangeSpin( wxSpinEvent& event )
1870 wxCommandEvent cevent;
1871 OnCachingChange(cevent);
1874 void OpenDialog::OnCachingChange( wxCommandEvent& event )
1876 i_caching = event.GetInt();
1880 /*****************************************************************************
1881 * Utility functions.
1882 *****************************************************************************/
1883 wxArrayString SeparateEntries( wxString entries )
1885 vlc_bool_t b_quotes_mode = VLC_FALSE;
1887 wxArrayString entries_array;
1890 wxStringTokenizer token( entries, wxT(" \t\r\n\""), wxTOKEN_RET_DELIMS );
1892 while( token.HasMoreTokens() )
1894 entry += token.GetNextToken();
1896 if( entry.IsEmpty() ) continue;
1898 if( !b_quotes_mode && entry.Last() == wxT('\"') )
1900 /* Enters quotes mode */
1902 b_quotes_mode = VLC_TRUE;
1904 else if( b_quotes_mode && entry.Last() == wxT('\"') )
1906 /* Finished the quotes mode */
1908 b_quotes_mode = VLC_FALSE;
1910 else if( !b_quotes_mode && entry.Last() != wxT('\"') )
1912 /* we found a non-quoted standalone string */
1913 if( token.HasMoreTokens() ||
1914 entry.Last() == wxT(' ') || entry.Last() == wxT('\t') ||
1915 entry.Last() == wxT('\r') || entry.Last() == wxT('\n') )
1917 if( !entry.IsEmpty() ) entries_array.Add( entry );
1924 if( !entry.IsEmpty() ) entries_array.Add( entry );
1926 return entries_array;