1 /*****************************************************************************
2 * open.cpp : Open dialog box
3 *****************************************************************************
4 * Copyright (C) 2000-2005 the VideoLAN team
7 * Authors: Gildas Bazin <gbazin@videolan.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
27 #include "dialogs/open.hpp"
28 #include "dialogs/streamout.hpp"
29 #include "dialogs/preferences_widgets.h"
30 #include "dialogs/subtitles.hpp"
32 #include "vlc_charset.h"
34 #undef HAVE_LIBCDIO // Disable broken code
37 #include <cdio/cdio.h>
38 #include <cdio/cd_types.h>
39 #include <cdio/logging.h>
40 #endif /* HAVE_LIBCDIO */
43 #include <libvcd/version.h>
44 /* There was a bug in libvcdinfo <= 23 which prevented C++ compilation */
45 #if LIBVCD_VERSION_NUM > 23
46 #include <libvcd/info.h>
47 #endif /* LIBVCD_VERSION_NUM > 23 */
48 #endif /* HAVE_VCDINFO */
50 #include <wx/combobox.h>
51 #include <wx/statline.h>
52 #include <wx/tokenzr.h>
55 # define wxRB_SINGLE 0
58 #define SELECTION_DISC_TYPE_DVD_MENUS 0
59 #define SELECTION_DISC_TYPE_DVD 1
60 #define SELECTION_DISC_TYPE_VCD 2
61 #define SELECTION_DISC_TYPE_CDDA 3
63 /*****************************************************************************
65 *****************************************************************************/
67 /* IDs for the controls and the menu commands */
70 Notebook_Event = wxID_HIGHEST,
89 NetRadio1_Event, NetRadio2_Event, NetRadio3_Event, NetRadio4_Event,
90 NetPort1_Event, NetPort2_Event, NetPort3_Event,
91 NetAddr1_Event, NetAddr2_Event, NetAddr3_Event, NetAddr4_Event,
92 NetForceIPv6_Event, NetTimeshift_Event,
95 SubsFileSettings_Event,
103 AdvancedOptions_Event
106 BEGIN_EVENT_TABLE(OpenDialog, wxDialog)
108 EVT_BUTTON(wxID_OK, OpenDialog::OnOk)
109 EVT_BUTTON(wxID_CANCEL, OpenDialog::OnCancel)
111 EVT_NOTEBOOK_PAGE_CHANGED(Notebook_Event, OpenDialog::OnPageChange)
113 EVT_TEXT(MRL_Event, OpenDialog::OnMRLChange)
115 /* Events generated by the file panel */
116 EVT_TEXT(FileName_Event, OpenDialog::OnFilePanelChange)
117 EVT_BUTTON(FileBrowse_Event, OpenDialog::OnFileBrowse)
118 EVT_TEXT(SubFileName_Event, OpenDialog::OnSubFileChange)
119 EVT_BUTTON(SubFileBrowse_Event, OpenDialog::OnSubFileBrowse)
121 /* Events generated by the disc panel */
122 EVT_RADIOBOX(DiscType_Event, OpenDialog::OnDiscTypeChange)
124 EVT_CHECKBOX(DiscProbe_Event, OpenDialog::OnDiscProbe)
126 EVT_TEXT(DiscDevice_Event, OpenDialog::OnDiscDeviceChange)
127 EVT_TEXT(DiscDevice_Event, OpenDialog::OnDiscPanelChange)
128 EVT_TEXT(DiscTitle_Event, OpenDialog::OnDiscPanelChange)
129 EVT_SPINCTRL(DiscTitle_Event, OpenDialog::OnDiscPanelChangeSpin)
130 EVT_TEXT(DiscChapter_Event, OpenDialog::OnDiscPanelChange)
131 EVT_SPINCTRL(DiscChapter_Event, OpenDialog::OnDiscPanelChangeSpin)
132 EVT_TEXT(DiscSub_Event, OpenDialog::OnDiscPanelChange)
133 EVT_TEXT(DiscAudio_Event, OpenDialog::OnDiscPanelChange)
134 EVT_SPINCTRL(DiscSub_Event, OpenDialog::OnDiscPanelChangeSpin)
136 /* Events generated by the net panel */
137 EVT_RADIOBUTTON(NetRadio1_Event, OpenDialog::OnNetTypeChange)
138 EVT_RADIOBUTTON(NetRadio2_Event, OpenDialog::OnNetTypeChange)
139 EVT_RADIOBUTTON(NetRadio3_Event, OpenDialog::OnNetTypeChange)
140 EVT_RADIOBUTTON(NetRadio4_Event, OpenDialog::OnNetTypeChange)
141 EVT_TEXT(NetPort1_Event, OpenDialog::OnNetPanelChange)
142 EVT_SPINCTRL(NetPort1_Event, OpenDialog::OnNetPanelChangeSpin)
143 EVT_TEXT(NetPort2_Event, OpenDialog::OnNetPanelChange)
144 EVT_SPINCTRL(NetPort2_Event, OpenDialog::OnNetPanelChangeSpin)
145 EVT_TEXT(NetPort3_Event, OpenDialog::OnNetPanelChange)
146 EVT_SPINCTRL(NetPort3_Event, OpenDialog::OnNetPanelChangeSpin)
147 EVT_TEXT(NetAddr2_Event, OpenDialog::OnNetPanelChange)
148 EVT_TEXT(NetAddr3_Event, OpenDialog::OnNetPanelChange)
149 EVT_TEXT(NetAddr4_Event, OpenDialog::OnNetPanelChange)
150 EVT_CHECKBOX(NetForceIPv6_Event, OpenDialog::OnNetPanelChange)
151 EVT_CHECKBOX(NetTimeshift_Event, OpenDialog::OnNetPanelChange)
153 /* Events generated by the subtitle file buttons */
154 EVT_CHECKBOX(SubsFileEnable_Event, OpenDialog::OnSubsFileEnable)
155 EVT_BUTTON(SubsFileSettings_Event, OpenDialog::OnSubsFileSettings)
157 /* Events generated by the stream output buttons */
158 EVT_CHECKBOX(SoutEnable_Event, OpenDialog::OnSoutEnable)
159 EVT_BUTTON(SoutSettings_Event, OpenDialog::OnSoutSettings)
161 /* Events generated by the caching button */
162 EVT_CHECKBOX(CachingEnable_Event, OpenDialog::OnCachingEnable)
163 EVT_TEXT(CachingChange_Event, OpenDialog::OnCachingChange)
164 EVT_SPINCTRL(CachingChange_Event, OpenDialog::OnCachingChangeSpin)
166 /* Hide the window when the user closes the window */
167 EVT_CLOSE(OpenDialog::OnClose)
172 /*****************************************************************************
174 *****************************************************************************/
175 WX_DEFINE_ARRAY(ConfigControl *, ArrayOfConfigControls);
177 class AutoBuiltPanel : public wxPanel
182 AutoBuiltPanel( wxWindow *, OpenDialog *, intf_thread_t *,
185 virtual ~AutoBuiltPanel() {}
187 void UpdateAdvancedMRL();
190 ArrayOfConfigControls config_array;
191 ArrayOfConfigControls advanced_config_array;
192 wxComboBox *p_advanced_mrl_combo;
195 intf_thread_t *p_intf;
196 OpenDialog *p_open_dialog;
198 void OnAdvanced( wxCommandEvent& event );
199 wxDialog *p_advanced_dialog;
201 DECLARE_EVENT_TABLE();
204 BEGIN_EVENT_TABLE(AutoBuiltPanel, wxPanel)
205 EVT_BUTTON(AdvancedOptions_Event, AutoBuiltPanel::OnAdvanced)
208 static void AutoBuildCallback( void *p_data )
210 ((OpenDialog *)p_data)->UpdateMRL();
213 static void AutoBuildAdvancedCallback( void *p_data )
215 ((AutoBuiltPanel *)p_data)->UpdateAdvancedMRL();
218 AutoBuiltPanel::AutoBuiltPanel( wxWindow *parent, OpenDialog *dialog,
219 intf_thread_t *_p_intf,
220 const module_t *p_module )
221 : wxPanel( parent, -1, wxDefaultPosition, wxDefaultSize ),
222 name( wxU(module_GetObjName(p_module)) ),
223 p_advanced_mrl_combo( NULL ),
224 p_intf( _p_intf ), p_open_dialog( dialog ), p_advanced_dialog( NULL )
226 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
227 bool b_advanced = false;
228 unsigned int i_confsize;
229 module_config_t *p_config;
232 p_config = module_GetConfig (p_module, &i_confsize);
233 for( n = 0; n < i_confsize; n++ )
235 module_config_t *p_item = p_config + n;
236 if( !(p_item->i_type & CONFIG_HINT) && p_item->b_advanced )
239 if( p_item->i_type & CONFIG_HINT || p_item->b_advanced )
242 ConfigControl *control =
243 CreateConfigControl( VLC_OBJECT(p_intf), p_item, this );
245 config_array.Add( control );
247 /* Don't add items that were not recognized */
248 if( control == NULL ) continue;
250 control->SetUpdateCallback( AutoBuildCallback, (void *)dialog );
252 sizer->Add( control, 0, wxEXPAND | wxALL, 2 );
258 new wxButton( this, AdvancedOptions_Event,
259 wxU(_("Advanced options...")) );
260 sizer->Add( button, 0, wxALL, 5 );
262 /* Build the advanced dialog */
264 new wxDialog( this, -1, ((wxString)wxU(_("Advanced options"))) +
265 wxT(" (") + wxU( module_GetLongName(p_module) ) +
266 wxT(")"), wxDefaultPosition, wxDefaultSize,
267 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER );
269 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
271 /* Create MRL combobox */
272 wxBoxSizer *mrl_sizer_sizer = new wxBoxSizer( wxHORIZONTAL );
273 wxStaticBox *mrl_box =
274 new wxStaticBox( p_advanced_dialog, -1,
275 wxU(_("Advanced options")) );
276 wxStaticBoxSizer *mrl_sizer =
277 new wxStaticBoxSizer( mrl_box, wxHORIZONTAL );
278 wxStaticText *mrl_label =
279 new wxStaticText( p_advanced_dialog, -1, wxU(_("Options:")) );
280 p_advanced_mrl_combo =
281 new wxComboBox( p_advanced_dialog, MRL_Event, wxT(""),
282 wxDefaultPosition, wxDefaultSize );
283 mrl_sizer->Add( mrl_label, 0, wxALL | wxALIGN_CENTER, 5 );
284 mrl_sizer->Add( p_advanced_mrl_combo, 1, wxALL | wxALIGN_CENTER, 5 );
285 mrl_sizer_sizer->Add( mrl_sizer, 1, wxEXPAND | wxALL, 5 );
286 sizer->Add( mrl_sizer_sizer, 0, wxEXPAND | wxALL, 2 );
288 /* Add advanced options to panel */
289 for( n = 0; n < i_confsize; n++ )
291 module_config_t *p_item = p_config + n;
292 if( p_item->i_type & CONFIG_HINT || !p_item->b_advanced )
295 ConfigControl *control =
296 CreateConfigControl( VLC_OBJECT(p_intf), p_item,
299 advanced_config_array.Add( control );
301 /* Don't add items that were not recognized */
302 if( control == NULL ) continue;
304 control->SetUpdateCallback( AutoBuildAdvancedCallback,
307 sizer->Add( control, 0, wxEXPAND | wxALL, 2 );
311 wxPanel *dummy_panel = new wxPanel( p_advanced_dialog, -1 );
312 sizer->Add( dummy_panel, 1 );
313 wxStaticLine *static_line =
314 new wxStaticLine( p_advanced_dialog, wxID_OK );
315 sizer->Add( static_line, 0, wxEXPAND | wxALL, 5 );
318 wxButton *ok_button =
319 new wxButton( p_advanced_dialog, wxID_OK, wxU(_("&OK")) );
320 ok_button->SetDefault();
321 wxButton *cancel_button =
322 new wxButton( p_advanced_dialog, wxID_CANCEL, wxU(_("&Cancel")) );
323 wxStdDialogButtonSizer *button_sizer = new wxStdDialogButtonSizer;
324 button_sizer->AddButton( ok_button );
325 button_sizer->AddButton( cancel_button );
326 button_sizer->Realize();
327 sizer->Add( button_sizer, 0, wxEXPAND|wxALL, 5 );
329 sizer->SetMinSize( 400, -1 );
330 p_advanced_dialog->SetSizerAndFit( sizer );
333 module_PutConfig (p_config);
335 this->SetSizerAndFit( sizer );
338 void AutoBuiltPanel::OnAdvanced( wxCommandEvent& event )
340 if( p_advanced_dialog->ShowModal() == wxID_OK )
343 p_open_dialog->UpdateMRL();
347 void AutoBuiltPanel::UpdateAdvancedMRL()
351 for( int i = 0; i < (int)advanced_config_array.GetCount(); i++ )
353 ConfigControl *control = advanced_config_array.Item(i);
355 mrltemp += (i ? wxT(" :") : wxT(":"));
357 if( control->GetType() == CONFIG_ITEM_BOOL &&
358 !control->GetIntValue() ) mrltemp += wxT("no-");
360 mrltemp += control->GetName();
362 switch( control->GetType() )
364 case CONFIG_ITEM_STRING:
365 case CONFIG_ITEM_FILE:
366 case CONFIG_ITEM_DIRECTORY:
367 case CONFIG_ITEM_MODULE:
368 mrltemp += wxT("=\"") + control->GetPszValue() + wxT("\"");
370 case CONFIG_ITEM_INTEGER:
372 wxString::Format( wxT("=%i"), control->GetIntValue() );
374 case CONFIG_ITEM_FLOAT:
376 wxString::Format(wxT("=%f"), control->GetFloatValue());
381 p_advanced_mrl_combo->SetValue( mrltemp );
384 /*****************************************************************************
386 *****************************************************************************/
387 OpenDialog::OpenDialog( intf_thread_t *_p_intf, wxWindow *_p_parent,
388 int i_access_method, int i_arg ):
389 wxDialog( _p_parent, -1, wxU(_("Open...")), wxDefaultPosition,
390 wxDefaultSize, wxDEFAULT_FRAME_STYLE )
392 OpenDialog( _p_intf, _p_parent, i_access_method, i_arg, OPEN_NORMAL );
395 OpenDialog::OpenDialog( intf_thread_t *_p_intf, wxWindow *_p_parent,
396 int i_access_method, int i_arg, int _i_method ):
397 wxDialog( _p_parent, -1, wxU(_("Open...")), wxDefaultPosition,
398 wxDefaultSize, wxDEFAULT_FRAME_STYLE )
400 /* Initializations */
401 i_method = _i_method;
403 p_parent = _p_parent;
404 SetIcon( *p_intf->p_sys->p_icon );
406 i_disc_type_selection = 0;
411 subsfile_dialog = NULL;
412 b_disc_device_changed = false;
414 /* Create a panel to put everything in */
415 wxPanel *panel = new wxPanel( this, -1 );
416 panel->SetAutoLayout( TRUE );
419 /* Advanced options */
420 wxStaticBox *adv_box = new wxStaticBox( panel, -1,
421 wxU(_("Advanced options")) );
422 wxStaticBoxSizer *adv_sizer = new wxStaticBoxSizer( adv_box,
426 wxFlexGridSizer *common_opt_sizer = new wxFlexGridSizer( 5, 1, 20 );
427 if( i_method == OPEN_NORMAL )
429 /* Create Stream Output checkox */
430 sout_checkbox = new wxCheckBox( panel, SoutEnable_Event,
431 wxU(_("Stream/Save")) );
432 sout_checkbox->SetToolTip( wxU(_("Use VLC as a stream server")) );
433 common_opt_sizer->Add( sout_checkbox, 0,
434 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
436 sout_button = new wxButton( panel, SoutSettings_Event,
437 wxU(_("Settings...")) );
438 sout_button->Disable();
440 char *psz_sout = config_GetPsz( p_intf, "sout" );
441 if( psz_sout && *psz_sout )
443 sout_checkbox->SetValue(TRUE);
444 sout_button->Enable();
445 subsfile_mrl.Add( wxString(wxT("sout=")) + wxL2U(psz_sout) );
449 common_opt_sizer->Add( sout_button, 1, wxALIGN_LEFT |
450 wxALIGN_CENTER_VERTICAL );
452 common_opt_sizer->Add( new wxPanel( this, -1 ), 1,
453 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
456 /* Create caching options */
457 caching_checkbox = new wxCheckBox( panel, CachingEnable_Event,
459 caching_checkbox->SetToolTip( wxU(_("Change the default caching value "
460 "(in milliseconds)")) );
461 common_opt_sizer->Add( caching_checkbox, 0,
462 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
463 caching_value = new wxSpinCtrl( panel, CachingChange_Event );
464 caching_value->SetRange( 0, 1000000 );
465 caching_value->Disable();
466 common_opt_sizer->Add( caching_value, 0,
467 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
470 wxBoxSizer *mrl_sizer = new wxBoxSizer( wxHORIZONTAL );
471 wxStaticText *mrl_label = new wxStaticText( panel, -1,
472 wxU(_("Customize:")) );
473 mrl_combo = new wxComboBox( panel, MRL_Event, wxT(""),
474 wxDefaultPosition, wxDefaultSize );
475 //Point(20,25), wxSize(120, -1) );
476 mrl_combo->SetToolTip( wxU(_("You can use this field directly by typing "
477 "the full MRL you want to open.\n""Alternatively, the field will be "
478 "filled automatically when you use the controls above.")) );
480 mrl_sizer->Add( mrl_label, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
481 mrl_sizer->Add( mrl_combo, 1, wxALL | wxEXPAND | wxALIGN_CENTER_VERTICAL,
484 adv_sizer->Add( common_opt_sizer, 0, wxTOP | wxLEFT|wxRIGHT | wxEXPAND, 5 );
485 adv_sizer->Add( mrl_sizer, 0, wxBOTTOM | wxLEFT|wxRIGHT | wxEXPAND, 5 );
488 wxStaticLine *static_line = new wxStaticLine( panel, wxID_OK );
490 /* Create the buttons */
491 wxButton *ok_button = new wxButton( panel, wxID_OK, wxU(_("&OK")) );
492 ok_button->SetDefault();
493 wxButton *cancel_button = new wxButton( panel, wxID_CANCEL,
496 /* Create notebook */
497 notebook = new wxNotebook( panel, Notebook_Event );
499 #if (!wxCHECK_VERSION(2,5,2))
500 wxNotebookSizer *notebook_sizer = new wxNotebookSizer( notebook );
503 notebook->AddPage( FilePanel( notebook ), wxU(_("File")),
504 i_access_method == FILE_ACCESS );
505 notebook->AddPage( DiscPanel( notebook ), wxU(_("Disc")),
506 i_access_method == DISC_ACCESS );
507 notebook->AddPage( NetPanel( notebook ), wxU(_("Network")),
508 i_access_method == NET_ACCESS );
510 module_t *p_module = module_Find( VLC_OBJECT(p_intf), "v4l" );
513 AutoBuiltPanel *autopanel =
514 new AutoBuiltPanel( notebook, this, p_intf, p_module );
515 input_tab_array.Add( autopanel );
516 notebook->AddPage( autopanel, wxU( module_GetName(p_module, 0) ),
517 i_access_method == CAPTURE_ACCESS );
518 module_Put( p_module );
521 p_module = module_Find( VLC_OBJECT(p_intf), "pvr" );
524 AutoBuiltPanel *autopanel =
525 new AutoBuiltPanel( notebook, this, p_intf, p_module );
526 input_tab_array.Add( autopanel );
527 notebook->AddPage( autopanel, wxU( module_GetName(p_module, 0) ),
528 i_access_method == CAPTURE_ACCESS );
529 module_Put( p_module );
532 p_module = module_Find( VLC_OBJECT(p_intf), "dvb" );
535 AutoBuiltPanel *autopanel =
536 new AutoBuiltPanel( notebook, this, p_intf, p_module );
537 input_tab_array.Add( autopanel );
538 notebook->AddPage( autopanel, wxU( module_GetName(p_module, 0) ),
539 i_access_method == CAPTURE_ACCESS );
540 module_Put( p_module );
543 p_module = module_Find( VLC_OBJECT(p_intf), "dshow" );
546 AutoBuiltPanel *autopanel =
547 new AutoBuiltPanel( notebook, this, p_intf, p_module );
548 input_tab_array.Add( autopanel );
549 notebook->AddPage( autopanel, wxU( module_GetName(p_module, 0) ),
550 i_access_method == CAPTURE_ACCESS );
551 module_Put( p_module );
554 /* Update Disc panel */
555 wxCommandEvent dummy_event;
556 OnDiscTypeChange( dummy_event );
558 /* Update Net panel */
559 dummy_event.SetId( NetRadio1_Event );
560 OnNetTypeChange( dummy_event );
563 wxNotebookEvent event( wxEVT_NULL, 0, i_access_method );
564 OnPageChange( event );
566 /* Place everything in sizers */
567 wxStdDialogButtonSizer *button_sizer = new wxStdDialogButtonSizer;
568 button_sizer->AddButton( cancel_button );
569 button_sizer->AddButton( ok_button );
570 button_sizer->Realize();
571 wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL );
572 wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
573 #if (!wxCHECK_VERSION(2,5,2))
574 panel_sizer->Add( notebook_sizer, 1, wxEXPAND | wxALL, 5 );
576 panel_sizer->Add( notebook, 1, wxEXPAND | wxALL, 5 );
578 panel_sizer->Add( adv_sizer, 0, wxEXPAND | wxALL, 5 );
579 panel_sizer->Add( static_line, 0, wxEXPAND | wxALL, 5 );
580 panel_sizer->Add( button_sizer, 0, wxEXPAND | wxALL, 5 );
581 panel_sizer->Layout();
582 panel->SetSizerAndFit( panel_sizer );
583 main_sizer->Add( panel, 1, wxGROW, 0 );
584 main_sizer->Layout();
585 SetSizerAndFit( main_sizer );
588 OpenDialog::~OpenDialog()
593 delete subsfile_dialog;
596 int OpenDialog::Show( int i_access_method, int i_arg )
598 notebook->SetSelection( i_access_method );
599 int i_ret = wxDialog::Show();
606 int OpenDialog::Show()
608 int i_ret = wxDialog::Show();
614 /*****************************************************************************
616 *****************************************************************************/
617 wxPanel *OpenDialog::FilePanel( wxWindow* parent )
619 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
622 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
624 /* Create browse file line */
625 wxBoxSizer *file_sizer = new wxBoxSizer( wxHORIZONTAL );
627 file_sizer->Add( new wxStaticText( panel, -1, wxU(_("Open:") ) ), 0,
628 wxALL | wxALIGN_CENTER_VERTICAL, 5 );
630 file_combo = new wxComboBox( panel, FileName_Event, wxT("") );
631 wxButton *browse_button = new wxButton( panel, FileBrowse_Event,
632 wxU(_("Browse...")) );
633 file_sizer->Add( file_combo, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
634 file_sizer->Add( browse_button, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
636 /* Create Subtitles File checkox - button */
637 wxFlexGridSizer *subtitles_sizer = new wxFlexGridSizer( 2, 1, 20 );
638 subsfile_checkbox = new wxCheckBox( panel, SubsFileEnable_Event,
639 wxU(_("Use a subtitles file")) );
640 subsfile_checkbox->SetToolTip( wxU(_("Use an external subtitles file.")) );
641 subtitles_sizer->Add( subsfile_checkbox, 0, wxALIGN_CENTER_VERTICAL |
643 subsfile_button = new wxButton( panel, SubsFileSettings_Event,
644 wxU(_("Advanced Settings...")) );
645 subsfile_button->Disable();
646 subtitles_sizer->Add( subsfile_button, 1, wxALIGN_CENTER_VERTICAL |
649 /* Create subtitles file line */
650 wxBoxSizer *subfile_sizer = new wxBoxSizer( wxHORIZONTAL );
652 char *psz_subsfile = config_GetPsz( p_intf, "sub-file" );
653 if( psz_subsfile && *psz_subsfile )
655 subsfile_checkbox->SetValue(TRUE);
656 subsfile_button->Enable();
657 subsfile_mrl.Add( wxString(wxT("sub-file=")) + wxL2U(psz_subsfile) );
659 if( !psz_subsfile ) psz_subsfile = strdup("");
660 subfile_sizer->Add( new wxStaticText( panel, -1, wxU(_("File:") ) ),
661 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
662 subfile_combo = new wxComboBox( panel, SubFileName_Event,
663 wxL2U( psz_subsfile ) );
664 free( psz_subsfile );
665 subbrowse_button = new wxButton( panel, SubFileBrowse_Event,
666 wxU(_("Browse...")) );
667 subfile_sizer->Add( subfile_combo, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
668 subfile_sizer->Add( subbrowse_button, 0, wxALL |wxALIGN_CENTER_VERTICAL, 5 );
670 subfile_combo->Disable();
671 subbrowse_button->Disable();
673 psz_subsfile = config_GetPsz( p_intf, "sub-file" );
674 if( psz_subsfile && *psz_subsfile )
676 subfile_combo->Enable();
677 subbrowse_button->Enable();
680 sizer->Add( file_sizer, 0, wxEXPAND | wxALL, 5 );
681 sizer->Add( subtitles_sizer, 0, wxLEFT | wxRIGHT | wxTOP, 5 );
682 sizer->Add( subfile_sizer, 0, wxEXPAND | wxLEFT | wxRIGHT| wxBOTTOM, 5 );
683 panel->SetSizerAndFit( sizer );
687 wxPanel *OpenDialog::DiscPanel( wxWindow* parent )
689 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
692 wxBoxSizer *sizer_row = new wxBoxSizer( wxVERTICAL );
693 wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 3, 20 );
695 static const wxString disc_type_array[] =
697 wxU(_("DVD (menus)")),
703 disc_type = new wxRadioBox( panel, DiscType_Event, wxU(_("Disc type")),
704 wxDefaultPosition, wxDefaultSize,
705 WXSIZEOF(disc_type_array), disc_type_array,
706 WXSIZEOF(disc_type_array), wxRA_SPECIFY_COLS );
709 disc_probe = new wxCheckBox( panel, DiscProbe_Event,
710 wxU(_("Probe Disc(s)")) );
711 disc_probe->SetToolTip( wxU(_("Probe for a DVD, VCD or audio CD. "
712 "First try the Device name entered for the selected Disc type "
713 "(DVD, DVD Menu, VCD, audio CD). If that doesn't find media, try any device "
714 "for the Disc type. If that doesn't work, then try looking for CD-ROMs or "
715 "DVD drives. The Disc type, Device name, and some parameter ranges are set "
716 "based on media we find.")) );
719 sizer_row->Add( disc_type, i_disc_type_selection, wxEXPAND | wxALL, 5 );
721 sizer_row->Add( disc_probe, 0, wxEXPAND | wxALL );
724 wxStaticText *label = new wxStaticText( panel, -1, wxU(_("Device name")) );
725 disc_device = new wxTextCtrl( panel, DiscDevice_Event, wxT(""),
726 wxDefaultPosition, wxDefaultSize,
730 char psz_default_device[3] = {0};
733 /* find the drive_name for the first cdrom drive,
734 * which is probably "D:" and put the drive_name into
735 * psz_default_device... */
736 for( char drive_letter = 'A'; drive_letter <= 'Z'; ++drive_letter )
738 char drive_name[3] = {drive_letter, ':', 0};
739 UINT type = GetDriveTypeA( drive_name );
740 if( type == DRIVE_CDROM )
742 psz_default_device[0] = drive_letter;
743 psz_default_device[1] = ':';
748 psz_forced = config_GetPsz( p_intf, "dvd" );
750 if( strlen(psz_default_device) > 0 &&
751 ( !psz_forced || psz_forced && !*psz_forced ) )
754 disc_device->SetValue( wxL2U(psz_default_device) );
758 sizer->Add( label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
759 sizer->Add( disc_device, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
761 disc_title_label = new wxStaticText( panel, -1, wxU(_("Title")) );
762 disc_title = new wxSpinCtrl( panel, DiscTitle_Event );
763 sizer->Add( disc_title_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
764 sizer->Add( disc_title, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
766 disc_chapter_label = new wxStaticText( panel, -1, wxU(_("Chapter")) );
767 disc_chapter = new wxSpinCtrl( panel, DiscChapter_Event );
768 sizer->Add( disc_chapter_label, 0,
769 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
770 sizer->Add( disc_chapter, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
772 disc_sub_label = new wxStaticText( panel, -1, wxU(_("Subtitles track")) );
773 disc_sub = new wxSpinCtrl( panel, DiscSub_Event );
774 sizer->Add( disc_sub_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
775 sizer->Add( disc_sub, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
776 disc_sub->SetRange( -1, 255 );
777 i_disc_sub = config_GetInt( p_intf, "sub-track" );
778 disc_sub->SetValue( i_disc_sub );
780 disc_audio_label = new wxStaticText( panel, -1, wxU(_("Audio track")) );
781 disc_audio = new wxSpinCtrl( panel, DiscAudio_Event );
782 sizer->Add( disc_audio_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
783 sizer->Add( disc_audio, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
784 disc_audio->SetRange( -1, 255 );
785 i_disc_audio = config_GetInt( p_intf, "audio-track" );
786 disc_audio->SetValue( i_disc_audio );
788 sizer_row->Add( sizer, 0, wxEXPAND | wxALL, 5 );
790 panel->SetSizerAndFit( sizer_row );
794 wxPanel *OpenDialog::NetPanel( wxWindow* parent )
797 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
800 wxBoxSizer *sizer_row = new wxBoxSizer( wxVERTICAL );
801 wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 4, 20 );
803 static const wxString net_type_array[] =
806 wxU(_("UDP/RTP Multicast")),
807 wxU(_("HTTP/HTTPS/FTP/MMS")),
813 net_radios[i] = new wxRadioButton( panel, NetRadio1_Event + i,
815 wxDefaultPosition, wxDefaultSize,
818 net_subpanels[i] = new wxPanel( panel, -1,
819 wxDefaultPosition, wxDefaultSize );
823 net_timeshift = new wxCheckBox( panel, NetTimeshift_Event,
824 wxU(_("Allow timeshifting")) );
827 wxFlexGridSizer *subpanel_sizer;
829 i_net_ports[0] = config_GetInt( p_intf, "server-port" );
830 subpanel_sizer = new wxFlexGridSizer( 3, 1, 20 );
831 label = new wxStaticText( net_subpanels[0], -1, wxU(_("Port")) );
832 net_ports[0] = new wxSpinCtrl( net_subpanels[0], NetPort1_Event,
833 wxString::Format(wxT("%d"), i_net_ports[0]),
834 wxDefaultPosition, wxDefaultSize,
836 0, 65535, i_net_ports[0] );
838 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
839 subpanel_sizer->Add( net_ports[0], 1,
840 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
841 net_ipv6 = new wxCheckBox( net_subpanels[0], NetForceIPv6_Event,
842 wxU(_("Force IPv6")));
843 subpanel_sizer->Add( net_ipv6, 0,
844 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
845 net_subpanels[0]->SetSizerAndFit( subpanel_sizer );
846 net_radios[0]->SetValue( TRUE );
848 /* UDP/RTP Multicast row */
849 subpanel_sizer = new wxFlexGridSizer( 4, 1, 20 );
850 label = new wxStaticText( net_subpanels[1], -1, wxU(_("Address")) );
851 net_addrs[1] = new wxTextCtrl( net_subpanels[1], NetAddr2_Event, wxT(""),
852 wxDefaultPosition, wxDefaultSize,
854 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
855 subpanel_sizer->Add( net_addrs[1], 1,
856 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
858 label = new wxStaticText( net_subpanels[1], -1, wxU(_("Port")) );
859 i_net_ports[1] = i_net_ports[0];
860 net_ports[1] = new wxSpinCtrl( net_subpanels[1], NetPort2_Event,
861 wxString::Format(wxT("%d"), i_net_ports[1]),
862 wxDefaultPosition, wxDefaultSize,
864 0, 65535, i_net_ports[1] );
866 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
867 subpanel_sizer->Add( net_ports[1], 1,
868 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
869 net_subpanels[1]->SetSizerAndFit( subpanel_sizer );
871 /* HTTP and RTSP rows */
874 subpanel_sizer = new wxFlexGridSizer( 2, 1, 20 );
875 label = new wxStaticText( net_subpanels[i], -1, wxU(_("URL")) );
876 net_addrs[i] = new wxTextCtrl( net_subpanels[i], NetAddr1_Event + i,
877 (i == 2) ? wxT("") : wxT("rtsp://"),
878 wxDefaultPosition, wxSize( 200, -1 ),
880 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
881 subpanel_sizer->Add( net_addrs[i], 1,
882 wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
883 net_subpanels[i]->SetSizerAndFit( subpanel_sizer );
886 /* Stuff everything into the main panel */
889 sizer->Add( net_radios[i], 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
891 sizer->Add( net_subpanels[i], 1, wxEXPAND | wxALIGN_LEFT |
892 wxALIGN_CENTER_VERTICAL | wxALL, 5 );
894 sizer->Add( net_timeshift, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
897 sizer_row->Add( sizer, 0, wxEXPAND | wxALL, 5 );
899 panel->SetSizerAndFit( sizer_row );
903 void OpenDialog::UpdateMRL()
905 UpdateMRL( i_current_access_method );
908 void OpenDialog::UpdateMRL( int i_access_method )
910 wxString mrltemp, caching_name;
912 i_current_access_method = i_access_method;
914 switch( i_access_method )
917 mrltemp = file_combo->GetValue();
918 caching_name = wxT("file-caching");
922 i_disc_type_selection = disc_type->GetSelection();
924 switch ( i_disc_type_selection )
926 case 0: /* DVD with menus */
927 case 1: /* DVD without menus */
928 disc_device->SetToolTip( wxU(_("DVD device to use" ) ) );
929 if( i_disc_type_selection == 0 )
931 mrltemp = wxT("dvd://") + disc_device->GetValue();
932 caching_name = wxT("dvdnav-caching");
936 mrltemp = wxT("dvdsimple://") + disc_device->GetValue();
937 caching_name = wxT("dvdread-caching");
940 if( i_disc_title > 0 )
942 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
944 if( i_disc_chapter > 0 )
945 mrltemp += wxString::Format( wxT(":%d"), i_disc_chapter );
948 if( i_disc_sub >= 0 )
949 mrltemp += wxString::Format( wxT(" :sub-track=%d"),
951 if( i_disc_audio >= 0 )
952 mrltemp += wxString::Format( wxT(" :audio-track=%d"),
956 case 2: /* VCD of some sort */
958 disc_device->SetToolTip( wxU(_("Name of CD-ROM device "
959 "to read Video CD from. If this field is left empty, we will scan "
960 "for a CD-ROM with a VCD in it.")) );
961 mrltemp = wxT("vcdx://") + disc_device->GetValue();
962 if( i_disc_title > 0 )
963 mrltemp += wxString::Format( wxT("@%c%d"),
964 config_GetInt( p_intf, "vcdx-PBC" )
965 ? 'P' : 'E', i_disc_title );
967 disc_device->SetToolTip( wxU(_("CD-ROM device to use" ) ) );
968 mrltemp = wxT("vcd://") + disc_device->GetValue();
969 if( i_disc_title > 0 )
970 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
973 if( i_disc_sub >= 0 )
974 mrltemp += wxString::Format( wxT(" :sub-track=%d"),
977 if( i_disc_audio >= 0 )
978 mrltemp += wxString::Format( wxT(" :audio-track=%d"),
980 caching_name = wxT("vcd-caching");
985 disc_device->SetToolTip( wxU(_("Name of CD-ROM device "
986 "to read audio CD from. If this field is left empty, we will scan "
987 "for a CD-ROM with an audio CD in it." )) );
988 mrltemp = wxT("cddax://")
990 disc_device->SetToolTip( wxU(_("CD-ROM device to use" ) ) ) ;
991 mrltemp = wxT("cdda://")
993 + disc_device->GetValue();
994 if( i_disc_title > 0 )
995 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
997 caching_name = wxT("cdda-caching");
1001 msg_Err( p_intf, "invalid selection (%d)",
1002 disc_type->GetSelection() );
1008 switch( i_net_type )
1011 mrltemp = wxT("udp://@");
1012 if ( net_ipv6->GetValue() )
1014 mrltemp += wxT("[::]");
1016 if( i_net_ports[0] !=
1017 config_GetInt( p_intf, "server-port" ) )
1019 mrltemp += wxString::Format( wxT(":%d"), i_net_ports[0] );
1022 caching_name = wxT("udp-caching");
1026 mrltemp = wxT("udp://@");
1027 if ((net_addrs[1]->GetLineText(0).Find (':') != -1)
1028 && (net_addrs[1]->GetLineText(0)[0u] != '['))
1030 /* automatically adds '[' and ']' to IPv6 addresses */
1031 mrltemp += wxT("[") + net_addrs[1]->GetLineText(0)
1036 mrltemp += net_addrs[1]->GetLineText(0);
1038 if( i_net_ports[1] != config_GetInt( p_intf, "server-port" ) )
1040 mrltemp += wxString::Format( wxT(":%d"), i_net_ports[1] );
1043 caching_name = wxT("udp-caching");
1048 if( net_addrs[2]->GetLineText(0).Find(wxT("://")) == -1 )
1049 mrltemp = wxT("http://");
1051 mrltemp += net_addrs[2]->GetLineText(0);
1052 if( ! mrltemp.Left(4).CmpNoCase(wxT("http")) )
1053 caching_name = wxT("http-caching");
1054 else if( ! mrltemp.Left(3).CmpNoCase(wxT("mms")) )
1055 caching_name = wxT("mms-caching");
1057 caching_name= wxT("ftp-caching");
1062 if( net_addrs[3]->GetLineText(0).Find(wxT("rtsp://")) != 0 )
1064 mrltemp = wxT("rtsp://");
1066 mrltemp += net_addrs[3]->GetLineText(0);
1068 caching_name = wxT("rtsp-caching");
1071 if( net_timeshift->IsEnabled() && net_timeshift->IsChecked() )
1072 mrltemp += wxT(" :access-filter=timeshift");
1077 int i_item = i_access_method - MAX_ACCESS;
1079 if( i_item < 0 || i_item >= (int)input_tab_array.GetCount() )
1082 AutoBuiltPanel *input_panel = input_tab_array.Item( i_item );
1084 mrltemp = input_panel->name + wxT("://");
1086 for( int i=0; i < (int)input_panel->config_array.GetCount(); i++ )
1088 ConfigControl *control = input_panel->config_array.Item(i);
1090 mrltemp += wxT(" :");
1092 if( control->GetType() == CONFIG_ITEM_BOOL &&
1093 !control->GetIntValue() ) mrltemp += wxT("no-");
1095 mrltemp += control->GetName();
1097 switch( control->GetType() )
1099 case CONFIG_ITEM_STRING:
1100 case CONFIG_ITEM_FILE:
1101 case CONFIG_ITEM_DIRECTORY:
1102 case CONFIG_ITEM_MODULE:
1103 mrltemp += wxT("=\"") + control->GetPszValue() + wxT("\"");
1105 case CONFIG_ITEM_INTEGER:
1107 wxString::Format( wxT("=%i"), control->GetIntValue() );
1109 case CONFIG_ITEM_FLOAT:
1111 wxString::Format(wxT("=%f"), control->GetFloatValue());
1116 if( input_panel->p_advanced_mrl_combo &&
1117 input_panel->p_advanced_mrl_combo->GetValue() )
1119 mrltemp += wxT(" ") +
1120 input_panel->p_advanced_mrl_combo->GetValue();
1126 if( caching_name.size() )
1128 if( caching_value->IsEnabled() )
1130 mrltemp += wxT(" :") + caching_name +
1131 wxString::Format( wxT("=%d"), i_caching );
1135 int i_value = config_GetInt( p_intf, caching_name.mb_str(wxConvUTF8) );
1136 caching_value->SetValue( i_value );
1140 mrl_combo->SetValue( mrltemp );
1143 /*****************************************************************************
1145 *****************************************************************************/
1146 void OpenDialog::OnOk( wxCommandEvent& WXUNUSED(event) )
1148 mrl = SeparateEntries( mrl_combo->GetValue() );
1149 mrl_combo->Append( mrl_combo->GetValue() );
1150 if( mrl_combo->GetCount() > 10 ) mrl_combo->Delete( 0 );
1151 mrl_combo->SetSelection( mrl_combo->GetCount() - 1 );
1153 if( i_method == OPEN_STREAM )
1155 if( IsModal() ) EndModal( wxID_OK );
1160 /* Update the playlist */
1161 playlist_t *p_playlist =
1162 (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
1164 if( p_playlist == NULL ) return;
1166 for( int i = 0; i < (int)mrl.GetCount(); i++ )
1168 bool b_start = !i && i_open_arg;
1169 input_item_t *p_input;
1172 psz_utf8 = wxFromLocale( mrl[i] );
1173 p_input = input_ItemNew( p_intf, psz_utf8, NULL );
1174 wxLocaleFree( psz_utf8 );
1176 /* Insert options */
1177 while( i + 1 < (int)mrl.GetCount() &&
1178 ((const char *)mrl[i + 1].mb_str(wxConvUTF8))[0] == ':' )
1180 psz_utf8 = wxFromLocale( mrl[i + 1] );
1181 input_ItemAddOption( p_input, psz_utf8 );
1182 wxLocaleFree( psz_utf8 );
1186 /* Get the options from the subtitles dialog */
1187 if( subsfile_checkbox->IsChecked() && subsfile_mrl.GetCount() )
1189 for( int j = 0; j < (int)subsfile_mrl.GetCount(); j++ )
1191 psz_utf8 = wxFromLocale( subsfile_mrl[j] );
1192 input_ItemAddOption( p_input, psz_utf8 );
1193 wxLocaleFree( psz_utf8 );
1197 /* Get the options from the stream output dialog */
1198 if( sout_checkbox->IsChecked() && sout_mrl.GetCount() )
1200 for( int j = 0; j < (int)sout_mrl.GetCount(); j++ )
1202 psz_utf8 = wxFromLocale( sout_mrl[j] );
1203 input_ItemAddOption( p_input, psz_utf8 );
1204 wxLocaleFree( psz_utf8 );
1208 /* FIXME: playlist_AddInput() can fail */
1209 playlist_AddInput( p_playlist, p_input,
1210 PLAYLIST_APPEND | ( b_start ? PLAYLIST_GO : PLAYLIST_PREPARSE ),
1211 PLAYLIST_END, true, false );
1212 vlc_gc_decref( p_input );
1215 vlc_object_release( p_playlist );
1219 if( IsModal() ) EndModal( wxID_OK );
1222 void OpenDialog::OnCancel( wxCommandEvent& WXUNUSED(event) )
1224 wxCloseEvent cevent;
1228 void OpenDialog::OnClose( wxCloseEvent& WXUNUSED(event) )
1232 if( IsModal() ) EndModal( wxID_CANCEL );
1235 void OpenDialog::OnPageChange( wxNotebookEvent& event )
1237 UpdateMRL( event.GetSelection() );
1240 void OpenDialog::OnMRLChange( wxCommandEvent& event )
1242 //mrl = SeparateEntries( event.GetString() );
1245 /*****************************************************************************
1246 * File panel event methods.
1247 *****************************************************************************/
1248 void OpenDialog::OnFilePanelChange( wxCommandEvent& WXUNUSED(event) )
1250 UpdateMRL( FILE_ACCESS );
1253 void OpenDialog::OnFileBrowse( wxCommandEvent& WXUNUSED(event) )
1255 if( file_dialog == NULL )
1256 file_dialog = new wxFileDialog( this, wxU(_("Open File")),
1257 wxT(""), wxT(""), wxT("*"), wxOPEN | wxMULTIPLE );
1259 file_dialog->SetWildcard(wxU(_("All Files (*.*)|*"
1260 "|Sound Files (*.mp3, *.ogg, etc.)|" EXTENSIONS_AUDIO
1261 "|Video Files (*.avi, *.mpg, etc.)|" EXTENSIONS_VIDEO
1262 "|Playlist Files (*.m3u, *.pls, etc.)|" EXTENSIONS_PLAYLIST
1263 "|Subtitle Files (*.srt, *.sub, etc.)|" EXTENSIONS_SUBTITLE)));
1265 if( file_dialog && file_dialog->ShowModal() == wxID_OK )
1267 wxArrayString paths;
1270 file_dialog->GetPaths( paths );
1272 for( size_t i = 0; i < paths.GetCount(); i++ )
1274 if( paths[i].Find( wxT(' ') ) >= 0 )
1275 path += wxT("\"") + paths[i] + wxT("\" ");
1277 path += paths[i] + wxT(" ");
1280 file_combo->SetValue( path );
1281 file_combo->Append( path );
1282 if( file_combo->GetCount() > 10 ) file_combo->Delete( 0 );
1283 UpdateMRL( FILE_ACCESS );
1287 void OpenDialog::OnSubFileBrowse( wxCommandEvent& WXUNUSED(event) )
1289 wxFileDialog dialog( this, wxU(_("Open subtitles file")),
1290 wxT(""), wxT(""), wxT("*"), wxOPEN );
1292 if( dialog.ShowModal() == wxID_OK )
1294 subfile_combo->SetValue( dialog.GetPath() );
1296 wxCommandEvent event; OnSubFileChange( event );
1299 void OpenDialog::OnSubFileChange( wxCommandEvent& WXUNUSED(event) )
1301 if( subsfile_mrl.GetCount() != 0 )
1303 subsfile_mrl.RemoveAt( 0 );
1304 subsfile_mrl.Insert( wxString(wxT("sub-file=")) + subfile_combo->GetValue() , 0 );
1308 subsfile_mrl.Add( wxString(wxT("sub-file=")) + subfile_combo->GetValue() );
1312 /*****************************************************************************
1313 * Disc panel event methods.
1314 *****************************************************************************/
1315 void OpenDialog::OnDiscPanelChangeSpin( wxSpinEvent& event )
1317 wxCommandEvent cevent;
1318 cevent.SetId(event.GetId());
1319 cevent.SetInt(event.GetPosition());
1320 OnDiscPanelChange(cevent);
1323 void OpenDialog::OnDiscPanelChange( wxCommandEvent& event )
1325 if( event.GetId() == DiscTitle_Event ) i_disc_title = event.GetInt();
1326 if( event.GetId() == DiscChapter_Event ) i_disc_chapter = event.GetInt();
1327 if( event.GetId() == DiscSub_Event ) i_disc_sub = event.GetInt();
1328 if( event.GetId() == DiscAudio_Event ) i_disc_audio = event.GetInt();
1330 UpdateMRL( DISC_ACCESS );
1333 void OpenDialog::OnDiscDeviceChange( wxCommandEvent& event )
1337 switch( disc_type->GetSelection() )
1340 psz_device = config_GetPsz( p_intf, "cd-audio" );
1344 psz_device = config_GetPsz( p_intf, "vcd" );
1348 psz_device = config_GetPsz( p_intf, "dvd" );
1352 if ( !psz_device ) psz_device = "";
1354 if( disc_device->GetValue().Cmp( wxL2U( psz_device ) ) )
1356 b_disc_device_changed = true;
1359 UpdateMRL( DISC_ACCESS );
1364 /* Return true if *psz_drive is a drive with a DVD in it. A more complete
1365 check would see if the media looks like a *playable* DVD. This should
1368 static bool IsDVD(const char *psz_drive)
1370 CdIo_t *p_cdio = cdio_open (psz_drive, DRIVER_UNKNOWN);
1373 discmode_t discmode = cdio_get_discmode(p_cdio);
1374 cdio_destroy(p_cdio);
1375 return cdio_is_discmode_dvd(discmode);
1381 /* Return a device that has a DVD in it. The caller needs to free
1382 the returned string.
1384 static char * ProbeDVD(const wxChar *device)
1387 char **ppsz_cd_drives;
1388 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1389 char *psz_device = (char *) tmp_buf;
1391 if( IsDVD(psz_device) )
1393 return strdup(psz_device);
1396 ppsz_cd_drives = cdio_get_devices(DRIVER_DEVICE);
1397 if( ppsz_cd_drives )
1400 for( c = ppsz_cd_drives; *c != NULL; c++ )
1404 char *psz_drive = strdup(*c);
1405 cdio_free_device_list(ppsz_cd_drives);
1406 return strdup(psz_drive);
1409 cdio_free_device_list(ppsz_cd_drives);
1415 static char * ProbeDevice(char **ppsz_search_devices, cdio_fs_anal_t mask,
1418 char **ppsz_devices;
1420 if( ppsz_search_devices && !ppsz_search_devices[0] )
1421 ppsz_search_devices = NULL;
1423 /* Start out trying the device that has been entered so far. */
1424 ppsz_devices = cdio_get_devices_with_cap(ppsz_search_devices, mask,
1427 if (ppsz_devices && *ppsz_devices)
1429 char *psz_device = strdup(*ppsz_devices);
1430 cdio_free_device_list(ppsz_devices);
1434 /* If there was no device specified on the first try, then give up
1435 now. Otherwise accept any CD-ROM in the class (e.g. VCD or DVD).
1437 if( !ppsz_search_devices ) return NULL;
1439 ppsz_devices = cdio_get_devices_with_cap(NULL, mask, true);
1441 if (ppsz_devices && *ppsz_devices)
1443 char *psz_device = strdup(*ppsz_devices);
1444 cdio_free_device_list(ppsz_devices);
1452 /* Return a device that has a CD-DA in it. The caller needs to free
1453 the returned string.
1455 static char * ProbeCDDA(const wxChar *device)
1458 char *ppsz_device[2];
1459 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1460 char *psz_device = (char *) tmp_buf;
1461 ppsz_device[0] = (device && *device) ? psz_device : NULL;
1462 ppsz_device[1] = NULL;
1463 return ProbeDevice(ppsz_device, CDIO_FS_AUDIO, false);
1467 /* Return a device that has a VCD in it. The caller needs to free
1468 the returned string.
1470 static char * ProbeVCD(const wxChar *device)
1472 char *ppsz_device[2];
1473 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1474 char *psz_device = (char *) tmp_buf;
1475 ppsz_device[0] = (device && *device) ? psz_device : NULL;
1476 ppsz_device[1] = NULL;
1477 return ProbeDevice(ppsz_device,
1478 (CDIO_FS_ANAL_SVCD|CDIO_FS_ANAL_CVD|CDIO_FS_ANAL_VIDEOCD
1479 |CDIO_FS_UNKNOWN), true);
1485 Probe (find anywhere) a CD-DA, VCD, or a DVD.
1486 First try the device name that may have been entered for the "disc type"
1487 selected. If that doesn't work we try any device for the disc type.
1488 If that doesn't work, try looking for CD-ROMs or DVD drives. the
1489 disc type, device name and paramter ranges are set to whatever we find.
1491 void OpenDialog::OnDiscProbe( wxCommandEvent& WXUNUSED(event) )
1493 wxCommandEvent dummy_event;
1494 char *psz_device = NULL;
1495 bool b_probed_DVD = false;
1496 bool b_probed_VCD = false;
1497 const int i_selection = disc_type->GetSelection();
1499 /* Reduce verbosity of cdio errors. */
1500 cdio_loglevel_default = CDIO_LOG_ERROR;
1503 switch( disc_type->GetSelection() )
1506 case SELECTION_DISC_TYPE_DVD_MENUS:
1507 case SELECTION_DISC_TYPE_DVD:
1508 /* If not a DVD then try for a VCD. If VCD fails it will
1510 if (!psz_device) psz_device = ProbeDVD(disc_device->GetValue());
1513 b_probed_DVD = true;
1514 disc_type->SetSelection(SELECTION_DISC_TYPE_VCD);
1515 OnDiscTypeChange( dummy_event );
1518 disc_device->SetValue( wxL2U(psz_device) );
1521 case SELECTION_DISC_TYPE_VCD: /* VCD probe of some sort */
1522 if(!psz_device) psz_device = ProbeVCD(disc_device->GetValue());
1526 #if LIBVCD_VERSION_NUM > 23
1527 vcdinfo_obj_t *p_vcdinfo;
1529 /* Set LID or entry range accurately if possible. */
1530 if( vcdinfo_open(&p_vcdinfo, &psz_device, DRIVER_DEVICE,
1531 NULL) == VCDINFO_OPEN_VCD)
1533 if (config_GetInt( p_intf, "vcdx-PBC" ))
1535 /* Set largest LID. */;
1536 disc_title->SetRange( 0, vcdinfo_get_num_LIDs(p_vcdinfo) );
1541 /* Set largest Entry */
1542 disc_title->SetRange( 0,
1543 vcdinfo_get_num_entries(p_vcdinfo)-1 );
1545 vcdinfo_close(p_vcdinfo);
1547 #endif /* LIBVCD_VERSION_NUM > 23 */
1548 disc_device->SetValue( wxL2U(psz_device) );
1550 CdIo_t *p_cdio = cdio_open (psz_device, DRIVER_UNKNOWN);
1551 disc_device->SetValue( wxL2U(psz_device) );
1553 /* Set track range accurately if possible. */
1556 track_t i_last_track = cdio_get_last_track_num(p_cdio);
1557 disc_title->SetRange( 0, i_last_track-1 );
1559 cdio_destroy(p_cdio);
1564 b_probed_VCD = true;
1566 /* Not a VCD. Try for a DVD unless we've been there before. */
1567 if( !b_probed_DVD && (psz_device = ProbeDVD(disc_device->GetValue())) )
1569 disc_type->SetSelection(SELECTION_DISC_TYPE_DVD_MENUS);
1570 OnDiscTypeChange( dummy_event );
1573 b_probed_DVD = true;
1575 /* Couldn't find a VCD or DVD. See if we can find a CD-DA. */
1576 psz_device = ProbeCDDA(disc_device->GetValue());
1579 disc_type->SetSelection(SELECTION_DISC_TYPE_CDDA);
1580 OnDiscTypeChange( dummy_event );
1584 /* Couldn't find a VCD, DVD or CD-DA. Null out the Device name and
1585 set to original selection.
1587 disc_device->SetValue( wxL2U("") );
1588 disc_type->SetSelection(i_selection);
1589 OnDiscTypeChange( dummy_event );
1592 case SELECTION_DISC_TYPE_CDDA:
1593 if(!psz_device) psz_device = ProbeCDDA(disc_device->GetValue());
1596 CdIo_t *p_cdio = cdio_open (psz_device, DRIVER_UNKNOWN);
1597 disc_device->SetValue( wxL2U(psz_device) );
1600 track_t i_last_track = cdio_get_last_track_num(p_cdio);
1601 disc_title->SetRange( 0, i_last_track );
1603 MediaInsertCDDA( p_intf, p_cdio, i_last_track );
1606 cdio_destroy(p_cdio);
1610 /* Not a CD-DA. Try for a DVD unless we've been there before. */
1611 if( !b_probed_DVD && (psz_device = ProbeDVD(disc_device->GetValue())) )
1613 disc_type->SetSelection(SELECTION_DISC_TYPE_DVD_MENUS);
1614 OnDiscTypeChange( dummy_event );
1618 /* Couldn't find a CD-DA or DVD. See if we can find a VCD, unless
1619 we've tried that before. */
1620 if (!b_probed_VCD) psz_device = ProbeVCD(disc_device->GetValue());
1623 disc_type->SetSelection(SELECTION_DISC_TYPE_VCD);
1624 OnDiscTypeChange( dummy_event );
1627 disc_device->SetValue( wxL2U("") );
1631 msg_Err( p_intf, "invalid Disc type selection (%d)",
1632 disc_type->GetSelection() );
1637 disc_probe->SetValue(FALSE);
1639 UpdateMRL( DISC_ACCESS );
1641 #endif /* HAVE_LIBCDIO */
1643 void OpenDialog::OnDiscTypeChange( wxCommandEvent& WXUNUSED(event) )
1645 char *psz_device = NULL;
1647 switch( disc_type->GetSelection() )
1650 case SELECTION_DISC_TYPE_DVD_MENUS:
1651 case SELECTION_DISC_TYPE_DVD:
1652 disc_sub->Enable(); disc_sub_label->Enable();
1653 disc_audio->Enable(); disc_audio_label->Enable();
1654 disc_chapter->Enable(); disc_chapter_label->Enable();
1655 disc_title_label->SetLabel ( wxU(_("Title")) );
1656 psz_device = config_GetPsz( p_intf, "dvd" );
1657 if( !b_disc_device_changed )
1659 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1660 else disc_device->SetValue( wxT("") );
1662 disc_title->SetRange( 0, 255 );
1663 disc_sub->SetRange( -1, 31 ); // up to 32 subtitles -1: no subtitle
1664 disc_audio->SetRange( 0, 7 ); // up to 8 audio channels
1665 disc_chapter->SetRange( 0, 255 );
1666 disc_title->SetToolTip( wxU(_("Title number.")) );
1667 disc_sub->SetToolTip( wxU(_(
1668 "DVDs can have up to 32 subtitles numbered 0..31. "
1669 "Note this is not the same thing as a subtitle name (e.g. 'en'). "
1670 "If a value -1 is used, no subtitle will be shown." )) );
1671 disc_audio->SetToolTip( wxU(_("Audio track number. "
1672 "DVDs can have up to 8 audio tracks numbered 0..7."
1676 case SELECTION_DISC_TYPE_VCD:
1677 disc_sub->Enable(); disc_sub_label->Enable();
1678 disc_audio->Enable(); disc_audio_label->Enable();
1679 disc_chapter->Disable(); disc_chapter_label->Disable();
1680 psz_device = config_GetPsz( p_intf, "vcd" );
1681 if( !b_disc_device_changed )
1683 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1684 else disc_device->SetValue( wxT("") );
1688 if (config_GetInt( p_intf, "vcdx-PBC" ))
1690 disc_title_label->SetLabel ( wxT("Playback LID") );
1691 disc_title->SetToolTip( wxU(_(
1692 "Playback control (PBC) usually starts with number 1." )) );
1696 disc_title_label->SetLabel ( wxT("Entry") );
1697 disc_title->SetToolTip( wxU(_(
1698 "The first entry (the beginning of the first MPEG track) is 0." )) );
1702 disc_title_label->SetLabel ( wxU(_("Track")) );
1703 disc_title->SetToolTip( wxU(_("Track number.")) );
1705 disc_title->SetRange( 0, 99 ); // only 100 tracks allowed on VCDs
1706 disc_sub->SetRange( -1, 3 ); // up to 4 subtitles -1 = no subtitle
1707 disc_audio->SetRange( 0, 1 ); // up to 2 audio tracks
1708 disc_sub->SetToolTip( wxU(_(
1709 "SVCDs can have up to 4 subtitles numbered 0..3. "
1710 "If a value -1 is used, no subtitle will be shown." )) );
1711 disc_audio->SetToolTip( wxU(_("Audio track number. "
1712 "VCDs can have up to 2 audio tracks numbered 0 or 1. "
1716 case SELECTION_DISC_TYPE_CDDA:
1717 disc_sub->Disable(); disc_sub_label->Disable();
1718 disc_chapter->Disable(); disc_chapter_label->Disable();
1719 disc_audio->Disable(); disc_audio_label->Disable();
1720 disc_title_label->SetLabel ( wxU(_("Track")) );
1722 disc_title->SetToolTip( wxU(_(
1723 "Audio CDs can have up to 100 tracks, the first track is usually 1. "
1724 "If 0 is given, then all tracks are played.")) );
1726 disc_title->SetToolTip( wxU(_(
1727 "Audio CDs can have up to 100 tracks, the first track is usually 1."
1730 psz_device = config_GetPsz( p_intf, "cd-audio" );
1731 if( !b_disc_device_changed )
1733 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1734 else disc_device->SetValue( wxT("") );
1737 /* There are at most 100 tracks in a CD-DA */
1738 disc_title->SetRange( 0, 100 );
1742 msg_Err( p_intf, "invalid Disc type selection (%d)",
1743 disc_type->GetSelection() );
1747 disc_title->SetValue( 0 ); i_disc_title = 0;
1748 disc_chapter->SetValue( 0 ); i_disc_chapter = 0;
1752 UpdateMRL( DISC_ACCESS );
1755 /*****************************************************************************
1756 * Net panel event methods.
1757 *****************************************************************************/
1758 void OpenDialog::OnNetPanelChangeSpin( wxSpinEvent& event )
1760 wxCommandEvent cevent;
1761 cevent.SetId(event.GetId());
1762 cevent.SetInt(event.GetPosition());
1763 OnNetPanelChange(cevent);
1766 void OpenDialog::OnNetPanelChange( wxCommandEvent& event )
1768 if( event.GetId() >= NetPort1_Event && event.GetId() <= NetPort3_Event )
1770 i_net_ports[event.GetId() - NetPort1_Event] = event.GetInt();
1773 UpdateMRL( NET_ACCESS );
1776 void OpenDialog::OnNetTypeChange( wxCommandEvent& event )
1780 i_net_type = event.GetId() - NetRadio1_Event;
1784 net_radios[i]->SetValue( event.GetId() == (NetRadio1_Event+i) );
1785 net_subpanels[i]->Enable( event.GetId() == (NetRadio1_Event+i) );
1787 /* UDP Unicast or multicast -> timeshift */
1788 if( i_net_type == 0 || i_net_type == 1 )
1789 net_timeshift->Enable();
1791 net_timeshift->Disable();
1793 UpdateMRL( NET_ACCESS );
1796 /*****************************************************************************
1797 * Subtitles file event methods.
1798 *****************************************************************************/
1799 void OpenDialog::OnSubsFileEnable( wxCommandEvent& event )
1801 subsfile_button->Enable( event.GetInt() != 0 );
1802 subbrowse_button->Enable( event.GetInt() != 0 );
1803 subfile_combo->Enable( event.GetInt() != 0 );
1806 void OpenDialog::OnSubsFileSettings( wxCommandEvent& WXUNUSED(event) )
1808 /* Show/hide the open dialog */
1809 if( subsfile_dialog == NULL )
1810 subsfile_dialog = new SubsFileDialog( p_intf, this );
1812 if( subsfile_dialog && subsfile_dialog->ShowModal() == wxID_OK )
1814 subsfile_mrl.Empty();
1815 subsfile_mrl.Add( wxString(wxT("sub-file=")) + subfile_combo->GetValue() );
1816 if( subsfile_dialog->encoding_combo )
1818 subsfile_mrl.Add( wxString(wxT("subsdec-encoding=")) +
1819 subsfile_dialog->encoding_combo->GetValue() );
1821 if( subsfile_dialog->align_combo )
1823 subsfile_mrl.Add( wxString::Format(wxT("subsdec-align=%i"),
1824 (int)subsfile_dialog->align_combo->GetClientData(
1825 subsfile_dialog->align_combo->GetSelection()) ) );
1827 if( subsfile_dialog->size_combo )
1829 subsfile_mrl.Add( wxString::Format( wxT("freetype-rel-fontsize=%i"),
1830 (int)subsfile_dialog->size_combo->GetClientData(
1831 subsfile_dialog->size_combo->GetSelection()) ) );
1833 subsfile_mrl.Add( wxString( wxT("sub-fps="))+
1834 subsfile_dialog->fps_ctrl->GetValue() );
1835 subsfile_mrl.Add( wxString::Format( wxT("sub-delay=%i"),
1836 subsfile_dialog->delay_spinctrl->GetValue() ) );
1840 /*****************************************************************************
1841 * Stream output event methods.
1842 *****************************************************************************/
1843 void OpenDialog::OnSoutEnable( wxCommandEvent& event )
1845 sout_button->Enable( event.GetInt() != 0 );
1848 void OpenDialog::OnSoutSettings( wxCommandEvent& WXUNUSED(event) )
1850 /* Show/hide the open dialog */
1851 if( sout_dialog == NULL )
1852 sout_dialog = new SoutDialog( p_intf, this );
1854 if( sout_dialog && sout_dialog->ShowModal() == wxID_OK )
1856 sout_mrl = sout_dialog->GetOptions();
1860 /*****************************************************************************
1861 * Caching event methods.
1862 *****************************************************************************/
1863 void OpenDialog::OnCachingEnable( wxCommandEvent& event )
1865 caching_value->Enable( event.GetInt() != 0 );
1866 i_caching = caching_value->GetValue();
1870 void OpenDialog::OnCachingChangeSpin( wxSpinEvent& event )
1872 wxCommandEvent cevent;
1873 OnCachingChange(cevent);
1876 void OpenDialog::OnCachingChange( wxCommandEvent& event )
1878 i_caching = event.GetInt();
1882 /*****************************************************************************
1883 * Utility functions.
1884 *****************************************************************************/
1885 wxArrayString SeparateEntries( wxString entries )
1887 bool b_quotes_mode = false;
1889 wxArrayString entries_array;
1892 wxStringTokenizer token( entries, wxT(" \t\r\n\""), wxTOKEN_RET_DELIMS );
1894 while( token.HasMoreTokens() )
1896 entry += token.GetNextToken();
1898 if( entry.IsEmpty() ) continue;
1900 if( !b_quotes_mode && entry.Last() == wxT('\"') )
1902 /* Enters quotes mode */
1904 b_quotes_mode = true;
1906 else if( b_quotes_mode && entry.Last() == wxT('\"') )
1908 /* Finished the quotes mode */
1910 b_quotes_mode = false;
1912 else if( !b_quotes_mode && entry.Last() != wxT('\"') )
1914 /* we found a non-quoted standalone string */
1915 if( token.HasMoreTokens() ||
1916 entry.Last() == wxT(' ') || entry.Last() == wxT('\t') ||
1917 entry.Last() == wxT('\r') || entry.Last() == wxT('\n') )
1919 if( !entry.IsEmpty() ) entries_array.Add( entry );
1926 if( !entry.IsEmpty() ) entries_array.Add( entry );
1928 return entries_array;