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"
34 #undef HAVE_LIBCDIO // Disable broken code
37 #include <cdio/cdio.h>
38 #include <cdio/cd_types.h>
39 #include <cdio/logging.h>
40 #endif /* HAVE_LIBCDIO */
43 #include <libvcd/version.h>
44 /* There was a bug in libvcdinfo <= 23 which prevented C++ compilation */
45 #if LIBVCD_VERSION_NUM > 23
46 #include <libvcd/info.h>
47 #endif /* LIBVCD_VERSION_NUM > 23 */
48 #endif /* HAVE_VCDINFO */
50 #include <wx/combobox.h>
51 #include <wx/statline.h>
52 #include <wx/tokenzr.h>
55 # define wxRB_SINGLE 0
58 #define SELECTION_DISC_TYPE_DVD_MENUS 0
59 #define SELECTION_DISC_TYPE_DVD 1
60 #define SELECTION_DISC_TYPE_VCD 2
61 #define SELECTION_DISC_TYPE_CDDA 3
63 /*****************************************************************************
65 *****************************************************************************/
67 /* IDs for the controls and the menu commands */
70 Notebook_Event = wxID_HIGHEST,
89 NetRadio1_Event, NetRadio2_Event, NetRadio3_Event, NetRadio4_Event,
90 NetPort1_Event, NetPort2_Event, NetPort3_Event,
91 NetAddr1_Event, NetAddr2_Event, NetAddr3_Event, NetAddr4_Event,
92 NetForceIPv6_Event, NetTimeshift_Event,
95 SubsFileSettings_Event,
103 AdvancedOptions_Event
106 BEGIN_EVENT_TABLE(OpenDialog, wxDialog)
108 EVT_BUTTON(wxID_OK, OpenDialog::OnOk)
109 EVT_BUTTON(wxID_CANCEL, OpenDialog::OnCancel)
111 EVT_NOTEBOOK_PAGE_CHANGED(Notebook_Event, OpenDialog::OnPageChange)
113 EVT_TEXT(MRL_Event, OpenDialog::OnMRLChange)
115 /* Events generated by the file panel */
116 EVT_TEXT(FileName_Event, OpenDialog::OnFilePanelChange)
117 EVT_BUTTON(FileBrowse_Event, OpenDialog::OnFileBrowse)
118 EVT_TEXT(SubFileName_Event, OpenDialog::OnSubFileChange)
119 EVT_BUTTON(SubFileBrowse_Event, OpenDialog::OnSubFileBrowse)
121 /* Events generated by the disc panel */
122 EVT_RADIOBOX(DiscType_Event, OpenDialog::OnDiscTypeChange)
124 EVT_CHECKBOX(DiscProbe_Event, OpenDialog::OnDiscProbe)
126 EVT_TEXT(DiscDevice_Event, OpenDialog::OnDiscDeviceChange)
127 EVT_TEXT(DiscDevice_Event, OpenDialog::OnDiscPanelChange)
128 EVT_TEXT(DiscTitle_Event, OpenDialog::OnDiscPanelChange)
129 EVT_SPINCTRL(DiscTitle_Event, OpenDialog::OnDiscPanelChangeSpin)
130 EVT_TEXT(DiscChapter_Event, OpenDialog::OnDiscPanelChange)
131 EVT_SPINCTRL(DiscChapter_Event, OpenDialog::OnDiscPanelChangeSpin)
132 EVT_TEXT(DiscSub_Event, OpenDialog::OnDiscPanelChange)
133 EVT_TEXT(DiscAudio_Event, OpenDialog::OnDiscPanelChange)
134 EVT_SPINCTRL(DiscSub_Event, OpenDialog::OnDiscPanelChangeSpin)
136 /* Events generated by the net panel */
137 EVT_RADIOBUTTON(NetRadio1_Event, OpenDialog::OnNetTypeChange)
138 EVT_RADIOBUTTON(NetRadio2_Event, OpenDialog::OnNetTypeChange)
139 EVT_RADIOBUTTON(NetRadio3_Event, OpenDialog::OnNetTypeChange)
140 EVT_RADIOBUTTON(NetRadio4_Event, OpenDialog::OnNetTypeChange)
141 EVT_TEXT(NetPort1_Event, OpenDialog::OnNetPanelChange)
142 EVT_SPINCTRL(NetPort1_Event, OpenDialog::OnNetPanelChangeSpin)
143 EVT_TEXT(NetPort2_Event, OpenDialog::OnNetPanelChange)
144 EVT_SPINCTRL(NetPort2_Event, OpenDialog::OnNetPanelChangeSpin)
145 EVT_TEXT(NetPort3_Event, OpenDialog::OnNetPanelChange)
146 EVT_SPINCTRL(NetPort3_Event, OpenDialog::OnNetPanelChangeSpin)
147 EVT_TEXT(NetAddr2_Event, OpenDialog::OnNetPanelChange)
148 EVT_TEXT(NetAddr3_Event, OpenDialog::OnNetPanelChange)
149 EVT_TEXT(NetAddr4_Event, OpenDialog::OnNetPanelChange)
150 EVT_CHECKBOX(NetForceIPv6_Event, OpenDialog::OnNetPanelChange)
151 EVT_CHECKBOX(NetTimeshift_Event, OpenDialog::OnNetPanelChange)
153 /* Events generated by the subtitle file buttons */
154 EVT_CHECKBOX(SubsFileEnable_Event, OpenDialog::OnSubsFileEnable)
155 EVT_BUTTON(SubsFileSettings_Event, OpenDialog::OnSubsFileSettings)
157 /* Events generated by the stream output buttons */
158 EVT_CHECKBOX(SoutEnable_Event, OpenDialog::OnSoutEnable)
159 EVT_BUTTON(SoutSettings_Event, OpenDialog::OnSoutSettings)
161 /* Events generated by the caching button */
162 EVT_CHECKBOX(CachingEnable_Event, OpenDialog::OnCachingEnable)
163 EVT_TEXT(CachingChange_Event, OpenDialog::OnCachingChange)
164 EVT_SPINCTRL(CachingChange_Event, OpenDialog::OnCachingChangeSpin)
166 /* Hide the window when the user closes the window */
167 EVT_CLOSE(OpenDialog::OnClose)
172 /*****************************************************************************
174 *****************************************************************************/
175 WX_DEFINE_ARRAY(ConfigControl *, ArrayOfConfigControls);
177 class AutoBuiltPanel : public wxPanel
182 AutoBuiltPanel( wxWindow *, OpenDialog *, intf_thread_t *,
185 virtual ~AutoBuiltPanel() {}
187 void UpdateAdvancedMRL();
190 ArrayOfConfigControls config_array;
191 ArrayOfConfigControls advanced_config_array;
192 wxComboBox *p_advanced_mrl_combo;
195 intf_thread_t *p_intf;
196 OpenDialog *p_open_dialog;
198 void OnAdvanced( wxCommandEvent& event );
199 wxDialog *p_advanced_dialog;
201 DECLARE_EVENT_TABLE();
204 BEGIN_EVENT_TABLE(AutoBuiltPanel, wxPanel)
205 EVT_BUTTON(AdvancedOptions_Event, AutoBuiltPanel::OnAdvanced)
208 static void AutoBuildCallback( void *p_data )
210 ((OpenDialog *)p_data)->UpdateMRL();
213 static void AutoBuildAdvancedCallback( void *p_data )
215 ((AutoBuiltPanel *)p_data)->UpdateAdvancedMRL();
218 AutoBuiltPanel::AutoBuiltPanel( wxWindow *parent, OpenDialog *dialog,
219 intf_thread_t *_p_intf,
220 const module_t *p_module )
221 : wxPanel( parent, -1, wxDefaultPosition, wxDefaultSize ),
222 name( wxU(p_module->psz_object_name) ),
223 p_advanced_mrl_combo( NULL ),
224 p_intf( _p_intf ), p_open_dialog( dialog ), p_advanced_dialog( NULL )
226 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
227 module_config_t *p_item = p_module->p_config;
228 bool b_advanced = false;
232 if( !(p_item->i_type & CONFIG_HINT) && p_item->b_advanced )
235 if( p_item->i_type & CONFIG_HINT || p_item->b_advanced )
238 ConfigControl *control =
239 CreateConfigControl( VLC_OBJECT(p_intf), p_item, this );
241 config_array.Add( control );
243 /* Don't add items that were not recognized */
244 if( control == NULL ) continue;
246 control->SetUpdateCallback( AutoBuildCallback, (void *)dialog );
248 sizer->Add( control, 0, wxEXPAND | wxALL, 2 );
250 while( p_item->i_type != CONFIG_HINT_END && p_item++ );
255 new wxButton( this, AdvancedOptions_Event,
256 wxU(_("Advanced options...")) );
257 sizer->Add( button, 0, wxALL, 5 );
259 /* Build the advanced dialog */
261 new wxDialog( this, -1, ((wxString)wxU(_("Advanced options"))) +
262 wxT(" (") + wxU( p_module->psz_longname ) + wxT(")"),
263 wxDefaultPosition, wxDefaultSize,
264 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER );
266 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
268 /* Create MRL combobox */
269 wxBoxSizer *mrl_sizer_sizer = new wxBoxSizer( wxHORIZONTAL );
270 wxStaticBox *mrl_box =
271 new wxStaticBox( p_advanced_dialog, -1,
272 wxU(_("Advanced options")) );
273 wxStaticBoxSizer *mrl_sizer =
274 new wxStaticBoxSizer( mrl_box, wxHORIZONTAL );
275 wxStaticText *mrl_label =
276 new wxStaticText( p_advanced_dialog, -1, wxU(_("Options:")) );
277 p_advanced_mrl_combo =
278 new wxComboBox( p_advanced_dialog, MRL_Event, wxT(""),
279 wxDefaultPosition, wxDefaultSize );
280 mrl_sizer->Add( mrl_label, 0, wxALL | wxALIGN_CENTER, 5 );
281 mrl_sizer->Add( p_advanced_mrl_combo, 1, wxALL | wxALIGN_CENTER, 5 );
282 mrl_sizer_sizer->Add( mrl_sizer, 1, wxEXPAND | wxALL, 5 );
283 sizer->Add( mrl_sizer_sizer, 0, wxEXPAND | wxALL, 2 );
285 /* Add advanced options to panel */
286 module_config_t *p_item = p_module->p_config;
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 );
306 while( p_item->i_type != CONFIG_HINT_END && p_item++ );
309 wxPanel *dummy_panel = new wxPanel( p_advanced_dialog, -1 );
310 sizer->Add( dummy_panel, 1 );
311 wxStaticLine *static_line =
312 new wxStaticLine( p_advanced_dialog, wxID_OK );
313 sizer->Add( static_line, 0, wxEXPAND | wxALL, 5 );
316 wxButton *ok_button =
317 new wxButton( p_advanced_dialog, wxID_OK, wxU(_("&OK")) );
318 ok_button->SetDefault();
319 wxButton *cancel_button =
320 new wxButton( p_advanced_dialog, wxID_CANCEL, wxU(_("&Cancel")) );
321 wxStdDialogButtonSizer *button_sizer = new wxStdDialogButtonSizer;
322 button_sizer->AddButton( ok_button );
323 button_sizer->AddButton( cancel_button );
324 button_sizer->Realize();
325 sizer->Add( button_sizer, 0, wxEXPAND|wxALL, 5 );
327 sizer->SetMinSize( 400, -1 );
328 p_advanced_dialog->SetSizerAndFit( sizer );
331 this->SetSizerAndFit( sizer );
334 void AutoBuiltPanel::OnAdvanced( wxCommandEvent& event )
336 if( p_advanced_dialog->ShowModal() == wxID_OK )
339 p_open_dialog->UpdateMRL();
343 void AutoBuiltPanel::UpdateAdvancedMRL()
347 for( int i = 0; i < (int)advanced_config_array.GetCount(); i++ )
349 ConfigControl *control = advanced_config_array.Item(i);
351 mrltemp += (i ? wxT(" :") : wxT(":"));
353 if( control->GetType() == CONFIG_ITEM_BOOL &&
354 !control->GetIntValue() ) mrltemp += wxT("no-");
356 mrltemp += control->GetName();
358 switch( control->GetType() )
360 case CONFIG_ITEM_STRING:
361 case CONFIG_ITEM_FILE:
362 case CONFIG_ITEM_DIRECTORY:
363 case CONFIG_ITEM_MODULE:
364 mrltemp += wxT("=\"") + control->GetPszValue() + wxT("\"");
366 case CONFIG_ITEM_INTEGER:
368 wxString::Format( wxT("=%i"), control->GetIntValue() );
370 case CONFIG_ITEM_FLOAT:
372 wxString::Format(wxT("=%f"), control->GetFloatValue());
377 p_advanced_mrl_combo->SetValue( mrltemp );
380 /*****************************************************************************
382 *****************************************************************************/
383 OpenDialog::OpenDialog( intf_thread_t *_p_intf, wxWindow *_p_parent,
384 int i_access_method, int i_arg ):
385 wxDialog( _p_parent, -1, wxU(_("Open...")), wxDefaultPosition,
386 wxDefaultSize, wxDEFAULT_FRAME_STYLE )
388 OpenDialog( _p_intf, _p_parent, i_access_method, i_arg, OPEN_NORMAL );
391 OpenDialog::OpenDialog( intf_thread_t *_p_intf, wxWindow *_p_parent,
392 int i_access_method, int i_arg, int _i_method ):
393 wxDialog( _p_parent, -1, wxU(_("Open...")), wxDefaultPosition,
394 wxDefaultSize, wxDEFAULT_FRAME_STYLE )
396 /* Initializations */
397 i_method = _i_method;
399 p_parent = _p_parent;
400 SetIcon( *p_intf->p_sys->p_icon );
402 i_disc_type_selection = 0;
407 subsfile_dialog = NULL;
408 b_disc_device_changed = false;
410 /* Create a panel to put everything in */
411 wxPanel *panel = new wxPanel( this, -1 );
412 panel->SetAutoLayout( TRUE );
415 /* Advanced options */
416 wxStaticBox *adv_box = new wxStaticBox( panel, -1,
417 wxU(_("Advanced options")) );
418 wxStaticBoxSizer *adv_sizer = new wxStaticBoxSizer( adv_box,
422 wxFlexGridSizer *common_opt_sizer = new wxFlexGridSizer( 5, 1, 20 );
423 if( i_method == OPEN_NORMAL )
425 /* Create Stream Output checkox */
426 sout_checkbox = new wxCheckBox( panel, SoutEnable_Event,
427 wxU(_("Stream/Save")) );
428 sout_checkbox->SetToolTip( wxU(_("Use VLC as a stream server")) );
429 common_opt_sizer->Add( sout_checkbox, 0,
430 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
432 sout_button = new wxButton( panel, SoutSettings_Event,
433 wxU(_("Settings...")) );
434 sout_button->Disable();
436 char *psz_sout = config_GetPsz( p_intf, "sout" );
437 if( psz_sout && *psz_sout )
439 sout_checkbox->SetValue(TRUE);
440 sout_button->Enable();
441 subsfile_mrl.Add( wxString(wxT("sout=")) + wxL2U(psz_sout) );
443 if( psz_sout ) free( psz_sout );
445 common_opt_sizer->Add( sout_button, 1, wxALIGN_LEFT |
446 wxALIGN_CENTER_VERTICAL );
448 common_opt_sizer->Add( new wxPanel( this, -1 ), 1,
449 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
452 /* Create caching options */
453 caching_checkbox = new wxCheckBox( panel, CachingEnable_Event,
455 caching_checkbox->SetToolTip( wxU(_("Change the default caching value "
456 "(in milliseconds)")) );
457 common_opt_sizer->Add( caching_checkbox, 0,
458 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
459 caching_value = new wxSpinCtrl( panel, CachingChange_Event );
460 caching_value->SetRange( 0, 1000000 );
461 caching_value->Disable();
462 common_opt_sizer->Add( caching_value, 0,
463 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
466 wxBoxSizer *mrl_sizer = new wxBoxSizer( wxHORIZONTAL );
467 wxStaticText *mrl_label = new wxStaticText( panel, -1,
468 wxU(_("Customize:")) );
469 mrl_combo = new wxComboBox( panel, MRL_Event, wxT(""),
470 wxDefaultPosition, wxDefaultSize );
471 //Point(20,25), wxSize(120, -1) );
472 mrl_combo->SetToolTip( wxU(_("You can use this field directly by typing "
473 "the full MRL you want to open.\n""Alternatively, the field will be "
474 "filled automatically when you use the controls above.")) );
476 mrl_sizer->Add( mrl_label, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
477 mrl_sizer->Add( mrl_combo, 1, wxALL | wxEXPAND | wxALIGN_CENTER_VERTICAL,
480 adv_sizer->Add( common_opt_sizer, 0, wxTOP | wxLEFT|wxRIGHT | wxEXPAND, 5 );
481 adv_sizer->Add( mrl_sizer, 0, wxBOTTOM | wxLEFT|wxRIGHT | wxEXPAND, 5 );
484 wxStaticLine *static_line = new wxStaticLine( panel, wxID_OK );
486 /* Create the buttons */
487 wxButton *ok_button = new wxButton( panel, wxID_OK, wxU(_("&OK")) );
488 ok_button->SetDefault();
489 wxButton *cancel_button = new wxButton( panel, wxID_CANCEL,
492 /* Create notebook */
493 notebook = new wxNotebook( panel, Notebook_Event );
495 #if (!wxCHECK_VERSION(2,5,2))
496 wxNotebookSizer *notebook_sizer = new wxNotebookSizer( notebook );
499 notebook->AddPage( FilePanel( notebook ), wxU(_("File")),
500 i_access_method == FILE_ACCESS );
501 notebook->AddPage( DiscPanel( notebook ), wxU(_("Disc")),
502 i_access_method == DISC_ACCESS );
503 notebook->AddPage( NetPanel( notebook ), wxU(_("Network")),
504 i_access_method == NET_ACCESS );
506 module_t *p_module = config_FindModule( VLC_OBJECT(p_intf), "v4l" );
509 AutoBuiltPanel *autopanel =
510 new AutoBuiltPanel( notebook, this, p_intf, p_module );
511 input_tab_array.Add( autopanel );
512 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
513 p_module->psz_shortname : p_module->psz_object_name ),
514 i_access_method == CAPTURE_ACCESS );
517 p_module = config_FindModule( VLC_OBJECT(p_intf), "pvr" );
520 AutoBuiltPanel *autopanel =
521 new AutoBuiltPanel( notebook, this, p_intf, p_module );
522 input_tab_array.Add( autopanel );
523 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
524 p_module->psz_shortname : p_module->psz_object_name ),
525 i_access_method == CAPTURE_ACCESS );
528 p_module = config_FindModule( VLC_OBJECT(p_intf), "dvb" );
531 AutoBuiltPanel *autopanel =
532 new AutoBuiltPanel( notebook, this, p_intf, p_module );
533 input_tab_array.Add( autopanel );
534 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
535 p_module->psz_shortname : p_module->psz_object_name ),
536 i_access_method == CAPTURE_ACCESS );
539 p_module = config_FindModule( VLC_OBJECT(p_intf), "dshow" );
542 AutoBuiltPanel *autopanel =
543 new AutoBuiltPanel( notebook, this, p_intf, p_module );
544 input_tab_array.Add( autopanel );
545 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
546 p_module->psz_shortname : p_module->psz_object_name ),
547 i_access_method == CAPTURE_ACCESS );
550 /* Update Disc panel */
551 wxCommandEvent dummy_event;
552 OnDiscTypeChange( dummy_event );
554 /* Update Net panel */
555 dummy_event.SetId( NetRadio1_Event );
556 OnNetTypeChange( dummy_event );
559 wxNotebookEvent event( wxEVT_NULL, 0, i_access_method );
560 OnPageChange( event );
562 /* Place everything in sizers */
563 wxStdDialogButtonSizer *button_sizer = new wxStdDialogButtonSizer;
564 button_sizer->AddButton( cancel_button );
565 button_sizer->AddButton( ok_button );
566 button_sizer->Realize();
567 wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL );
568 wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
569 #if (!wxCHECK_VERSION(2,5,2))
570 panel_sizer->Add( notebook_sizer, 1, wxEXPAND | wxALL, 5 );
572 panel_sizer->Add( notebook, 1, wxEXPAND | wxALL, 5 );
574 panel_sizer->Add( adv_sizer, 0, wxEXPAND | wxALL, 5 );
575 panel_sizer->Add( static_line, 0, wxEXPAND | wxALL, 5 );
576 panel_sizer->Add( button_sizer, 0, wxEXPAND | wxALL, 5 );
577 panel_sizer->Layout();
578 panel->SetSizerAndFit( panel_sizer );
579 main_sizer->Add( panel, 1, wxGROW, 0 );
580 main_sizer->Layout();
581 SetSizerAndFit( main_sizer );
584 OpenDialog::~OpenDialog()
587 if( file_dialog ) delete file_dialog;
588 if( sout_dialog ) delete sout_dialog;
589 if( subsfile_dialog ) delete subsfile_dialog;
592 int OpenDialog::Show( int i_access_method, int i_arg )
594 notebook->SetSelection( i_access_method );
595 int i_ret = wxDialog::Show();
602 int OpenDialog::Show()
604 int i_ret = wxDialog::Show();
610 /*****************************************************************************
612 *****************************************************************************/
613 wxPanel *OpenDialog::FilePanel( wxWindow* parent )
615 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
618 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
620 /* Create browse file line */
621 wxBoxSizer *file_sizer = new wxBoxSizer( wxHORIZONTAL );
623 file_sizer->Add( new wxStaticText( panel, -1, wxU(_("Open:") ) ), 0,
624 wxALL | wxALIGN_CENTER_VERTICAL, 5 );
626 file_combo = new wxComboBox( panel, FileName_Event, wxT("") );
627 wxButton *browse_button = new wxButton( panel, FileBrowse_Event,
628 wxU(_("Browse...")) );
629 file_sizer->Add( file_combo, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
630 file_sizer->Add( browse_button, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
632 /* Create Subtitles File checkox - button */
633 wxFlexGridSizer *subtitles_sizer = new wxFlexGridSizer( 2, 1, 20 );
634 subsfile_checkbox = new wxCheckBox( panel, SubsFileEnable_Event,
635 wxU(_("Use a subtitles file")) );
636 subsfile_checkbox->SetToolTip( wxU(_("Use an external subtitles file.")) );
637 subtitles_sizer->Add( subsfile_checkbox, 0, wxALIGN_CENTER_VERTICAL |
639 subsfile_button = new wxButton( panel, SubsFileSettings_Event,
640 wxU(_("Advanced Settings...")) );
641 subsfile_button->Disable();
642 subtitles_sizer->Add( subsfile_button, 1, wxALIGN_CENTER_VERTICAL |
645 /* Create subtitles file line */
646 wxBoxSizer *subfile_sizer = new wxBoxSizer( wxHORIZONTAL );
648 char *psz_subsfile = config_GetPsz( p_intf, "sub-file" );
649 if( psz_subsfile && *psz_subsfile )
651 subsfile_checkbox->SetValue(TRUE);
652 subsfile_button->Enable();
653 subsfile_mrl.Add( wxString(wxT("sub-file=")) + wxL2U(psz_subsfile) );
655 if( !psz_subsfile ) psz_subsfile = strdup("");
656 subfile_sizer->Add( new wxStaticText( panel, -1, wxU(_("File:") ) ),
657 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
658 subfile_combo = new wxComboBox( panel, SubFileName_Event,
659 wxL2U( psz_subsfile ) );
660 if( psz_subsfile ) free( psz_subsfile );
661 subbrowse_button = new wxButton( panel, SubFileBrowse_Event,
662 wxU(_("Browse...")) );
663 subfile_sizer->Add( subfile_combo, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
664 subfile_sizer->Add( subbrowse_button, 0, wxALL |wxALIGN_CENTER_VERTICAL, 5 );
666 subfile_combo->Disable();
667 subbrowse_button->Disable();
669 psz_subsfile = config_GetPsz( p_intf, "sub-file" );
670 if( psz_subsfile && *psz_subsfile )
672 subfile_combo->Enable();
673 subbrowse_button->Enable();
676 sizer->Add( file_sizer, 0, wxEXPAND | wxALL, 5 );
677 sizer->Add( subtitles_sizer, 0, wxLEFT | wxRIGHT | wxTOP, 5 );
678 sizer->Add( subfile_sizer, 0, wxEXPAND | wxLEFT | wxRIGHT| wxBOTTOM, 5 );
679 panel->SetSizerAndFit( sizer );
683 wxPanel *OpenDialog::DiscPanel( wxWindow* parent )
685 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
688 wxBoxSizer *sizer_row = new wxBoxSizer( wxVERTICAL );
689 wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 3, 20 );
691 static const wxString disc_type_array[] =
693 wxU(_("DVD (menus)")),
699 disc_type = new wxRadioBox( panel, DiscType_Event, wxU(_("Disc type")),
700 wxDefaultPosition, wxDefaultSize,
701 WXSIZEOF(disc_type_array), disc_type_array,
702 WXSIZEOF(disc_type_array), wxRA_SPECIFY_COLS );
705 disc_probe = new wxCheckBox( panel, DiscProbe_Event,
706 wxU(_("Probe Disc(s)")) );
707 disc_probe->SetToolTip( wxU(_("Probe for a DVD, VCD or audio CD. "
708 "First try the Device name entered for the selected Disc type "
709 "(DVD, DVD Menu, VCD, audio CD). If that doesn't find media, try any device "
710 "for the Disc type. If that doesn't work, then try looking for CD-ROMs or "
711 "DVD drives. The Disc type, Device name, and some parameter ranges are set "
712 "based on media we find.")) );
715 sizer_row->Add( disc_type, i_disc_type_selection, wxEXPAND | wxALL, 5 );
717 sizer_row->Add( disc_probe, 0, wxEXPAND | wxALL );
720 wxStaticText *label = new wxStaticText( panel, -1, wxU(_("Device name")) );
721 disc_device = new wxTextCtrl( panel, DiscDevice_Event, wxT(""),
722 wxDefaultPosition, wxDefaultSize,
726 char psz_default_device[3] = {0};
729 /* find the drive_name for the first cdrom drive,
730 * which is probably "D:" and put the drive_name into
731 * psz_default_device... */
732 for( char drive_letter = 'A'; drive_letter <= 'Z'; ++drive_letter )
734 char drive_name[3] = {drive_letter, ':', 0};
735 UINT type = GetDriveTypeA( drive_name );
736 if( type == DRIVE_CDROM )
738 psz_default_device[0] = drive_letter;
739 psz_default_device[1] = ':';
744 psz_forced = config_GetPsz( p_intf, "dvd" );
746 if( strlen(psz_default_device) > 0 &&
747 ( !psz_forced || psz_forced && !*psz_forced ) )
750 disc_device->SetValue( wxL2U(psz_default_device) );
754 sizer->Add( label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
755 sizer->Add( disc_device, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
757 disc_title_label = new wxStaticText( panel, -1, wxU(_("Title")) );
758 disc_title = new wxSpinCtrl( panel, DiscTitle_Event );
759 sizer->Add( disc_title_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
760 sizer->Add( disc_title, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
762 disc_chapter_label = new wxStaticText( panel, -1, wxU(_("Chapter")) );
763 disc_chapter = new wxSpinCtrl( panel, DiscChapter_Event );
764 sizer->Add( disc_chapter_label, 0,
765 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
766 sizer->Add( disc_chapter, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
768 disc_sub_label = new wxStaticText( panel, -1, wxU(_("Subtitles track")) );
769 disc_sub = new wxSpinCtrl( panel, DiscSub_Event );
770 sizer->Add( disc_sub_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
771 sizer->Add( disc_sub, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
772 disc_sub->SetRange( -1, 255 );
773 i_disc_sub = config_GetInt( p_intf, "sub-track" );
774 disc_sub->SetValue( i_disc_sub );
776 disc_audio_label = new wxStaticText( panel, -1, wxU(_("Audio track")) );
777 disc_audio = new wxSpinCtrl( panel, DiscAudio_Event );
778 sizer->Add( disc_audio_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
779 sizer->Add( disc_audio, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
780 disc_audio->SetRange( -1, 255 );
781 i_disc_audio = config_GetInt( p_intf, "audio-track" );
782 disc_audio->SetValue( i_disc_audio );
784 sizer_row->Add( sizer, 0, wxEXPAND | wxALL, 5 );
786 panel->SetSizerAndFit( sizer_row );
790 wxPanel *OpenDialog::NetPanel( wxWindow* parent )
793 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
796 wxBoxSizer *sizer_row = new wxBoxSizer( wxVERTICAL );
797 wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 4, 20 );
799 static const wxString net_type_array[] =
802 wxU(_("UDP/RTP Multicast")),
803 wxU(_("HTTP/HTTPS/FTP/MMS")),
809 net_radios[i] = new wxRadioButton( panel, NetRadio1_Event + i,
811 wxDefaultPosition, wxDefaultSize,
814 net_subpanels[i] = new wxPanel( panel, -1,
815 wxDefaultPosition, wxDefaultSize );
819 net_timeshift = new wxCheckBox( panel, NetTimeshift_Event,
820 wxU(_("Allow timeshifting")) );
823 wxFlexGridSizer *subpanel_sizer;
825 i_net_ports[0] = config_GetInt( p_intf, "server-port" );
826 subpanel_sizer = new wxFlexGridSizer( 3, 1, 20 );
827 label = new wxStaticText( net_subpanels[0], -1, wxU(_("Port")) );
828 net_ports[0] = new wxSpinCtrl( net_subpanels[0], NetPort1_Event,
829 wxString::Format(wxT("%d"), i_net_ports[0]),
830 wxDefaultPosition, wxDefaultSize,
832 0, 65535, i_net_ports[0] );
834 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
835 subpanel_sizer->Add( net_ports[0], 1,
836 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
837 net_ipv6 = new wxCheckBox( net_subpanels[0], NetForceIPv6_Event,
838 wxU(_("Force IPv6")));
839 subpanel_sizer->Add( net_ipv6, 0,
840 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
841 net_subpanels[0]->SetSizerAndFit( subpanel_sizer );
842 net_radios[0]->SetValue( TRUE );
844 /* UDP/RTP Multicast row */
845 subpanel_sizer = new wxFlexGridSizer( 4, 1, 20 );
846 label = new wxStaticText( net_subpanels[1], -1, wxU(_("Address")) );
847 net_addrs[1] = new wxTextCtrl( net_subpanels[1], NetAddr2_Event, wxT(""),
848 wxDefaultPosition, wxDefaultSize,
850 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
851 subpanel_sizer->Add( net_addrs[1], 1,
852 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
854 label = new wxStaticText( net_subpanels[1], -1, wxU(_("Port")) );
855 i_net_ports[1] = i_net_ports[0];
856 net_ports[1] = new wxSpinCtrl( net_subpanels[1], NetPort2_Event,
857 wxString::Format(wxT("%d"), i_net_ports[1]),
858 wxDefaultPosition, wxDefaultSize,
860 0, 65535, i_net_ports[1] );
862 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
863 subpanel_sizer->Add( net_ports[1], 1,
864 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
865 net_subpanels[1]->SetSizerAndFit( subpanel_sizer );
867 /* HTTP and RTSP rows */
870 subpanel_sizer = new wxFlexGridSizer( 2, 1, 20 );
871 label = new wxStaticText( net_subpanels[i], -1, wxU(_("URL")) );
872 net_addrs[i] = new wxTextCtrl( net_subpanels[i], NetAddr1_Event + i,
873 (i == 2) ? wxT("") : wxT("rtsp://"),
874 wxDefaultPosition, wxSize( 200, -1 ),
876 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
877 subpanel_sizer->Add( net_addrs[i], 1,
878 wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
879 net_subpanels[i]->SetSizerAndFit( subpanel_sizer );
882 /* Stuff everything into the main panel */
885 sizer->Add( net_radios[i], 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
887 sizer->Add( net_subpanels[i], 1, wxEXPAND | wxALIGN_LEFT |
888 wxALIGN_CENTER_VERTICAL | wxALL, 5 );
890 sizer->Add( net_timeshift, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
893 sizer_row->Add( sizer, 0, wxEXPAND | wxALL, 5 );
895 panel->SetSizerAndFit( sizer_row );
899 void OpenDialog::UpdateMRL()
901 UpdateMRL( i_current_access_method );
904 void OpenDialog::UpdateMRL( int i_access_method )
906 wxString mrltemp, caching_name;
908 i_current_access_method = i_access_method;
910 switch( i_access_method )
913 mrltemp = file_combo->GetValue();
914 caching_name = wxT("file-caching");
918 i_disc_type_selection = disc_type->GetSelection();
920 switch ( i_disc_type_selection )
922 case 0: /* DVD with menus */
923 case 1: /* DVD without menus */
924 disc_device->SetToolTip( wxU(_("DVD device to use" ) ) );
925 if( i_disc_type_selection == 0 )
927 mrltemp = wxT("dvd://") + disc_device->GetValue();
928 caching_name = wxT("dvdnav-caching");
932 mrltemp = wxT("dvdsimple://") + disc_device->GetValue();
933 caching_name = wxT("dvdread-caching");
936 if( i_disc_title > 0 )
938 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
940 if( i_disc_chapter > 0 )
941 mrltemp += wxString::Format( wxT(":%d"), i_disc_chapter );
944 if( i_disc_sub >= 0 )
945 mrltemp += wxString::Format( wxT(" :sub-track=%d"),
947 if( i_disc_audio >= 0 )
948 mrltemp += wxString::Format( wxT(" :audio-track=%d"),
952 case 2: /* VCD of some sort */
954 disc_device->SetToolTip( wxU(_("Name of CD-ROM device "
955 "to read Video CD from. If this field is left empty, we will scan "
956 "for a CD-ROM with a VCD in it.")) );
957 mrltemp = wxT("vcdx://") + disc_device->GetValue();
958 if( i_disc_title > 0 )
959 mrltemp += wxString::Format( wxT("@%c%d"),
960 config_GetInt( p_intf, "vcdx-PBC" )
961 ? 'P' : 'E', i_disc_title );
963 disc_device->SetToolTip( wxU(_("CD-ROM device to use" ) ) );
964 mrltemp = wxT("vcd://") + disc_device->GetValue();
965 if( i_disc_title > 0 )
966 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
969 if( i_disc_sub >= 0 )
970 mrltemp += wxString::Format( wxT(" :sub-track=%d"),
973 if( i_disc_audio >= 0 )
974 mrltemp += wxString::Format( wxT(" :audio-track=%d"),
976 caching_name = wxT("vcd-caching");
981 disc_device->SetToolTip( wxU(_("Name of CD-ROM device "
982 "to read audio CD from. If this field is left empty, we will scan "
983 "for a CD-ROM with an audio CD in it." )) );
984 mrltemp = wxT("cddax://")
986 disc_device->SetToolTip( wxU(_("CD-ROM device to use" ) ) ) ;
987 mrltemp = wxT("cdda://")
989 + disc_device->GetValue();
990 if( i_disc_title > 0 )
991 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
993 caching_name = wxT("cdda-caching");
997 msg_Err( p_intf, "invalid selection (%d)",
998 disc_type->GetSelection() );
1004 switch( i_net_type )
1007 mrltemp = wxT("udp://@");
1008 if ( net_ipv6->GetValue() )
1010 mrltemp += wxT("[::]");
1012 if( i_net_ports[0] !=
1013 config_GetInt( p_intf, "server-port" ) )
1015 mrltemp += wxString::Format( wxT(":%d"), i_net_ports[0] );
1018 caching_name = wxT("udp-caching");
1022 mrltemp = wxT("udp://@");
1023 if ((net_addrs[1]->GetLineText(0).Find (':') != -1)
1024 && (net_addrs[1]->GetLineText(0)[0u] != '['))
1026 /* automatically adds '[' and ']' to IPv6 addresses */
1027 mrltemp += wxT("[") + net_addrs[1]->GetLineText(0)
1032 mrltemp += net_addrs[1]->GetLineText(0);
1034 if( i_net_ports[1] != config_GetInt( p_intf, "server-port" ) )
1036 mrltemp += wxString::Format( wxT(":%d"), i_net_ports[1] );
1039 caching_name = wxT("udp-caching");
1044 if( net_addrs[2]->GetLineText(0).Find(wxT("://")) == -1 )
1045 mrltemp = wxT("http://");
1047 mrltemp += net_addrs[2]->GetLineText(0);
1048 if( ! mrltemp.Left(4).CmpNoCase(wxT("http")) )
1049 caching_name = wxT("http-caching");
1050 else if( ! mrltemp.Left(3).CmpNoCase(wxT("mms")) )
1051 caching_name = wxT("mms-caching");
1053 caching_name= wxT("ftp-caching");
1058 if( net_addrs[3]->GetLineText(0).Find(wxT("rtsp://")) != 0 )
1060 mrltemp = wxT("rtsp://");
1062 mrltemp += net_addrs[3]->GetLineText(0);
1064 caching_name = wxT("rtsp-caching");
1067 if( net_timeshift->IsEnabled() && net_timeshift->IsChecked() )
1068 mrltemp += wxT(" :access-filter=timeshift");
1073 int i_item = i_access_method - MAX_ACCESS;
1075 if( i_item < 0 || i_item >= (int)input_tab_array.GetCount() )
1078 AutoBuiltPanel *input_panel = input_tab_array.Item( i_item );
1080 mrltemp = input_panel->name + wxT("://");
1082 for( int i=0; i < (int)input_panel->config_array.GetCount(); i++ )
1084 ConfigControl *control = input_panel->config_array.Item(i);
1086 mrltemp += wxT(" :");
1088 if( control->GetType() == CONFIG_ITEM_BOOL &&
1089 !control->GetIntValue() ) mrltemp += wxT("no-");
1091 mrltemp += control->GetName();
1093 switch( control->GetType() )
1095 case CONFIG_ITEM_STRING:
1096 case CONFIG_ITEM_FILE:
1097 case CONFIG_ITEM_DIRECTORY:
1098 case CONFIG_ITEM_MODULE:
1099 mrltemp += wxT("=\"") + control->GetPszValue() + wxT("\"");
1101 case CONFIG_ITEM_INTEGER:
1103 wxString::Format( wxT("=%i"), control->GetIntValue() );
1105 case CONFIG_ITEM_FLOAT:
1107 wxString::Format(wxT("=%f"), control->GetFloatValue());
1112 if( input_panel->p_advanced_mrl_combo &&
1113 input_panel->p_advanced_mrl_combo->GetValue() )
1115 mrltemp += wxT(" ") +
1116 input_panel->p_advanced_mrl_combo->GetValue();
1122 if( caching_name.size() )
1124 if( caching_value->IsEnabled() )
1126 mrltemp += wxT(" :") + caching_name +
1127 wxString::Format( wxT("=%d"), i_caching );
1131 int i_value = config_GetInt( p_intf, caching_name.mb_str() );
1132 caching_value->SetValue( i_value );
1136 mrl_combo->SetValue( mrltemp );
1139 /*****************************************************************************
1141 *****************************************************************************/
1142 void OpenDialog::OnOk( wxCommandEvent& WXUNUSED(event) )
1144 mrl = SeparateEntries( mrl_combo->GetValue() );
1145 mrl_combo->Append( mrl_combo->GetValue() );
1146 if( mrl_combo->GetCount() > 10 ) mrl_combo->Delete( 0 );
1147 mrl_combo->SetSelection( mrl_combo->GetCount() - 1 );
1149 if( i_method == OPEN_STREAM )
1151 if( IsModal() ) EndModal( wxID_OK );
1156 /* Update the playlist */
1157 playlist_t *p_playlist =
1158 (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
1160 if( p_playlist == NULL ) return;
1162 for( int i = 0; i < (int)mrl.GetCount(); i++ )
1164 vlc_bool_t b_start = !i && i_open_arg;
1165 input_item_t *p_input;
1168 psz_utf8 = wxFromLocale( mrl[i] );
1169 p_input = input_ItemNew( p_intf, psz_utf8, NULL );
1170 wxLocaleFree( psz_utf8 );
1172 /* Insert options */
1173 while( i + 1 < (int)mrl.GetCount() &&
1174 ((const char *)mrl[i + 1].mb_str())[0] == ':' )
1176 psz_utf8 = wxFromLocale( mrl[i + 1] );
1177 input_ItemAddOption( p_input, psz_utf8 );
1178 wxLocaleFree( psz_utf8 );
1182 /* Get the options from the subtitles dialog */
1183 if( subsfile_checkbox->IsChecked() && subsfile_mrl.GetCount() )
1185 for( int j = 0; j < (int)subsfile_mrl.GetCount(); j++ )
1187 psz_utf8 = wxFromLocale( subsfile_mrl[j] );
1188 input_ItemAddOption( p_input, psz_utf8 );
1189 wxLocaleFree( psz_utf8 );
1193 /* Get the options from the stream output dialog */
1194 if( sout_checkbox->IsChecked() && sout_mrl.GetCount() )
1196 for( int j = 0; j < (int)sout_mrl.GetCount(); j++ )
1198 psz_utf8 = wxFromLocale( sout_mrl[j] );
1199 input_ItemAddOption( p_input, psz_utf8 );
1200 wxLocaleFree( psz_utf8 );
1206 playlist_AddInput( p_playlist, p_input,
1207 PLAYLIST_APPEND | PLAYLIST_GO,
1208 PLAYLIST_END, VLC_TRUE );
1212 playlist_AddInput( p_playlist, p_input,
1213 PLAYLIST_APPEND|PLAYLIST_PREPARSE,
1214 PLAYLIST_END, VLC_TRUE );
1218 vlc_object_release( p_playlist );
1222 if( IsModal() ) EndModal( wxID_OK );
1225 void OpenDialog::OnCancel( wxCommandEvent& WXUNUSED(event) )
1227 wxCloseEvent cevent;
1231 void OpenDialog::OnClose( wxCloseEvent& WXUNUSED(event) )
1235 if( IsModal() ) EndModal( wxID_CANCEL );
1238 void OpenDialog::OnPageChange( wxNotebookEvent& event )
1240 UpdateMRL( event.GetSelection() );
1243 void OpenDialog::OnMRLChange( wxCommandEvent& event )
1245 //mrl = SeparateEntries( event.GetString() );
1248 /*****************************************************************************
1249 * File panel event methods.
1250 *****************************************************************************/
1251 void OpenDialog::OnFilePanelChange( wxCommandEvent& WXUNUSED(event) )
1253 UpdateMRL( FILE_ACCESS );
1256 void OpenDialog::OnFileBrowse( wxCommandEvent& WXUNUSED(event) )
1258 if( file_dialog == NULL )
1259 file_dialog = new wxFileDialog( this, wxU(_("Open File")),
1260 wxT(""), wxT(""), wxT("*"), wxOPEN | wxMULTIPLE );
1262 file_dialog->SetWildcard(wxU(_("All Files (*.*)|*"
1263 "|Sound Files (*.mp3, *.ogg, etc.)|" EXTENSIONS_AUDIO
1264 "|Video Files (*.avi, *.mpg, etc.)|" EXTENSIONS_VIDEO
1265 "|Playlist Files (*.m3u, *.pls, etc.)|" EXTENSIONS_PLAYLIST
1266 "|Subtitle Files (*.srt, *.sub, etc.)|" EXTENSIONS_SUBTITLE)));
1268 if( file_dialog && file_dialog->ShowModal() == wxID_OK )
1270 wxArrayString paths;
1273 file_dialog->GetPaths( paths );
1275 for( size_t i = 0; i < paths.GetCount(); i++ )
1277 if( paths[i].Find( wxT(' ') ) >= 0 )
1278 path += wxT("\"") + paths[i] + wxT("\" ");
1280 path += paths[i] + wxT(" ");
1283 file_combo->SetValue( path );
1284 file_combo->Append( path );
1285 if( file_combo->GetCount() > 10 ) file_combo->Delete( 0 );
1286 UpdateMRL( FILE_ACCESS );
1290 void OpenDialog::OnSubFileBrowse( wxCommandEvent& WXUNUSED(event) )
1292 wxFileDialog dialog( this, wxU(_("Open subtitles file")),
1293 wxT(""), wxT(""), wxT("*"), wxOPEN );
1295 if( dialog.ShowModal() == wxID_OK )
1297 subfile_combo->SetValue( dialog.GetPath() );
1299 wxCommandEvent event; OnSubFileChange( event );
1302 void OpenDialog::OnSubFileChange( wxCommandEvent& WXUNUSED(event) )
1304 if( subsfile_mrl.GetCount() != 0 )
1306 subsfile_mrl.RemoveAt( 0 );
1307 subsfile_mrl.Insert( wxString(wxT("sub-file=")) + subfile_combo->GetValue() , 0 );
1311 subsfile_mrl.Add( wxString(wxT("sub-file=")) + subfile_combo->GetValue() );
1315 /*****************************************************************************
1316 * Disc panel event methods.
1317 *****************************************************************************/
1318 void OpenDialog::OnDiscPanelChangeSpin( wxSpinEvent& event )
1320 wxCommandEvent cevent;
1321 cevent.SetId(event.GetId());
1322 cevent.SetInt(event.GetPosition());
1323 OnDiscPanelChange(cevent);
1326 void OpenDialog::OnDiscPanelChange( wxCommandEvent& event )
1328 if( event.GetId() == DiscTitle_Event ) i_disc_title = event.GetInt();
1329 if( event.GetId() == DiscChapter_Event ) i_disc_chapter = event.GetInt();
1330 if( event.GetId() == DiscSub_Event ) i_disc_sub = event.GetInt();
1331 if( event.GetId() == DiscAudio_Event ) i_disc_audio = event.GetInt();
1333 UpdateMRL( DISC_ACCESS );
1336 void OpenDialog::OnDiscDeviceChange( wxCommandEvent& event )
1340 switch( disc_type->GetSelection() )
1343 psz_device = config_GetPsz( p_intf, "cd-audio" );
1347 psz_device = config_GetPsz( p_intf, "vcd" );
1351 psz_device = config_GetPsz( p_intf, "dvd" );
1355 if ( !psz_device ) psz_device = "";
1357 if( disc_device->GetValue().Cmp( wxL2U( psz_device ) ) )
1359 b_disc_device_changed = true;
1362 UpdateMRL( DISC_ACCESS );
1367 /* Return true if *psz_drive is a drive with a DVD in it. A more complete
1368 check would see if the media looks like a *playable* DVD. This should
1371 static bool IsDVD(const char *psz_drive)
1373 CdIo_t *p_cdio = cdio_open (psz_drive, DRIVER_UNKNOWN);
1376 discmode_t discmode = cdio_get_discmode(p_cdio);
1377 cdio_destroy(p_cdio);
1378 return cdio_is_discmode_dvd(discmode);
1384 /* Return a device that has a DVD in it. The caller needs to free
1385 the returned string.
1387 static char * ProbeDVD(const wxChar *device)
1390 char **ppsz_cd_drives;
1391 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1392 char *psz_device = (char *) tmp_buf;
1394 if( IsDVD(psz_device) )
1396 return strdup(psz_device);
1399 ppsz_cd_drives = cdio_get_devices(DRIVER_DEVICE);
1400 if( ppsz_cd_drives )
1403 for( c = ppsz_cd_drives; *c != NULL; c++ )
1407 char *psz_drive = strdup(*c);
1408 cdio_free_device_list(ppsz_cd_drives);
1409 return strdup(psz_drive);
1412 cdio_free_device_list(ppsz_cd_drives);
1418 static char * ProbeDevice(char **ppsz_search_devices, cdio_fs_anal_t mask,
1421 char **ppsz_devices;
1423 if( ppsz_search_devices && !ppsz_search_devices[0] )
1424 ppsz_search_devices = NULL;
1426 /* Start out trying the device that has been entered so far. */
1427 ppsz_devices = cdio_get_devices_with_cap(ppsz_search_devices, mask,
1430 if (ppsz_devices && *ppsz_devices)
1432 char *psz_device = strdup(*ppsz_devices);
1433 cdio_free_device_list(ppsz_devices);
1437 /* If there was no device specified on the first try, then give up
1438 now. Otherwise accept any CD-ROM in the class (e.g. VCD or DVD).
1440 if( !ppsz_search_devices ) return NULL;
1442 ppsz_devices = cdio_get_devices_with_cap(NULL, mask, true);
1444 if (ppsz_devices && *ppsz_devices)
1446 char *psz_device = strdup(*ppsz_devices);
1447 cdio_free_device_list(ppsz_devices);
1455 /* Return a device that has a CD-DA in it. The caller needs to free
1456 the returned string.
1458 static char * ProbeCDDA(const wxChar *device)
1461 char *ppsz_device[2];
1462 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1463 char *psz_device = (char *) tmp_buf;
1464 ppsz_device[0] = (device && *device) ? psz_device : NULL;
1465 ppsz_device[1] = NULL;
1466 return ProbeDevice(ppsz_device, CDIO_FS_AUDIO, false);
1470 /* Return a device that has a VCD in it. The caller needs to free
1471 the returned string.
1473 static char * ProbeVCD(const wxChar *device)
1475 char *ppsz_device[2];
1476 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1477 char *psz_device = (char *) tmp_buf;
1478 ppsz_device[0] = (device && *device) ? psz_device : NULL;
1479 ppsz_device[1] = NULL;
1480 return ProbeDevice(ppsz_device,
1481 (CDIO_FS_ANAL_SVCD|CDIO_FS_ANAL_CVD|CDIO_FS_ANAL_VIDEOCD
1482 |CDIO_FS_UNKNOWN), true);
1488 Probe (find anywhere) a CD-DA, VCD, or a DVD.
1489 First try the device name that may have been entered for the "disc type"
1490 selected. If that doesn't work we try any device for the disc type.
1491 If that doesn't work, try looking for CD-ROMs or DVD drives. the
1492 disc type, device name and paramter ranges are set to whatever we find.
1494 void OpenDialog::OnDiscProbe( wxCommandEvent& WXUNUSED(event) )
1496 wxCommandEvent dummy_event;
1497 char *psz_device = NULL;
1498 bool b_probed_DVD = false;
1499 bool b_probed_VCD = false;
1500 const int i_selection = disc_type->GetSelection();
1502 /* Reduce verbosity of cdio errors. */
1503 cdio_loglevel_default = CDIO_LOG_ERROR;
1506 switch( disc_type->GetSelection() )
1509 case SELECTION_DISC_TYPE_DVD_MENUS:
1510 case SELECTION_DISC_TYPE_DVD:
1511 /* If not a DVD then try for a VCD. If VCD fails it will
1513 if (!psz_device) psz_device = ProbeDVD(disc_device->GetValue());
1516 b_probed_DVD = true;
1517 disc_type->SetSelection(SELECTION_DISC_TYPE_VCD);
1518 OnDiscTypeChange( dummy_event );
1521 disc_device->SetValue( wxL2U(psz_device) );
1524 case SELECTION_DISC_TYPE_VCD: /* VCD probe of some sort */
1525 if(!psz_device) psz_device = ProbeVCD(disc_device->GetValue());
1529 #if LIBVCD_VERSION_NUM > 23
1530 vcdinfo_obj_t *p_vcdinfo;
1532 /* Set LID or entry range accurately if possible. */
1533 if( vcdinfo_open(&p_vcdinfo, &psz_device, DRIVER_DEVICE,
1534 NULL) == VCDINFO_OPEN_VCD)
1536 if (config_GetInt( p_intf, "vcdx-PBC" ))
1538 /* Set largest LID. */;
1539 disc_title->SetRange( 0, vcdinfo_get_num_LIDs(p_vcdinfo) );
1544 /* Set largest Entry */
1545 disc_title->SetRange( 0,
1546 vcdinfo_get_num_entries(p_vcdinfo)-1 );
1548 vcdinfo_close(p_vcdinfo);
1550 #endif /* LIBVCD_VERSION_NUM > 23 */
1551 disc_device->SetValue( wxL2U(psz_device) );
1553 CdIo_t *p_cdio = cdio_open (psz_device, DRIVER_UNKNOWN);
1554 disc_device->SetValue( wxL2U(psz_device) );
1556 /* Set track range accurately if possible. */
1559 track_t i_last_track = cdio_get_last_track_num(p_cdio);
1560 disc_title->SetRange( 0, i_last_track-1 );
1562 cdio_destroy(p_cdio);
1567 b_probed_VCD = true;
1569 /* Not a VCD. Try for a DVD unless we've been there before. */
1570 if( !b_probed_DVD && (psz_device = ProbeDVD(disc_device->GetValue())) )
1572 disc_type->SetSelection(SELECTION_DISC_TYPE_DVD_MENUS);
1573 OnDiscTypeChange( dummy_event );
1576 b_probed_DVD = true;
1578 /* Couldn't find a VCD or DVD. See if we can find a CD-DA. */
1579 psz_device = ProbeCDDA(disc_device->GetValue());
1582 disc_type->SetSelection(SELECTION_DISC_TYPE_CDDA);
1583 OnDiscTypeChange( dummy_event );
1587 /* Couldn't find a VCD, DVD or CD-DA. Null out the Device name and
1588 set to original selection.
1590 disc_device->SetValue( wxL2U("") );
1591 disc_type->SetSelection(i_selection);
1592 OnDiscTypeChange( dummy_event );
1595 case SELECTION_DISC_TYPE_CDDA:
1596 if(!psz_device) psz_device = ProbeCDDA(disc_device->GetValue());
1599 CdIo_t *p_cdio = cdio_open (psz_device, DRIVER_UNKNOWN);
1600 disc_device->SetValue( wxL2U(psz_device) );
1603 track_t i_last_track = cdio_get_last_track_num(p_cdio);
1604 disc_title->SetRange( 0, i_last_track );
1606 MediaInsertCDDA( p_intf, p_cdio, i_last_track );
1609 cdio_destroy(p_cdio);
1613 /* Not a CD-DA. Try for a DVD unless we've been there before. */
1614 if( !b_probed_DVD && (psz_device = ProbeDVD(disc_device->GetValue())) )
1616 disc_type->SetSelection(SELECTION_DISC_TYPE_DVD_MENUS);
1617 OnDiscTypeChange( dummy_event );
1621 /* Couldn't find a CD-DA or DVD. See if we can find a VCD, unless
1622 we've tried that before. */
1623 if (!b_probed_VCD) psz_device = ProbeVCD(disc_device->GetValue());
1626 disc_type->SetSelection(SELECTION_DISC_TYPE_VCD);
1627 OnDiscTypeChange( dummy_event );
1630 disc_device->SetValue( wxL2U("") );
1634 msg_Err( p_intf, "invalid Disc type selection (%d)",
1635 disc_type->GetSelection() );
1640 disc_probe->SetValue(FALSE);
1642 UpdateMRL( DISC_ACCESS );
1644 #endif /* HAVE_LIBCDIO */
1646 void OpenDialog::OnDiscTypeChange( wxCommandEvent& WXUNUSED(event) )
1648 char *psz_device = NULL;
1650 switch( disc_type->GetSelection() )
1653 case SELECTION_DISC_TYPE_DVD_MENUS:
1654 case SELECTION_DISC_TYPE_DVD:
1655 disc_sub->Enable(); disc_sub_label->Enable();
1656 disc_audio->Enable(); disc_audio_label->Enable();
1657 disc_chapter->Enable(); disc_chapter_label->Enable();
1658 disc_title_label->SetLabel ( wxU(_("Title")) );
1659 psz_device = config_GetPsz( p_intf, "dvd" );
1660 if( !b_disc_device_changed )
1662 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1663 else disc_device->SetValue( wxT("") );
1665 disc_title->SetRange( 0, 255 );
1666 disc_sub->SetRange( -1, 31 ); // up to 32 subtitles -1: no subtitle
1667 disc_audio->SetRange( 0, 7 ); // up to 8 audio channels
1668 disc_chapter->SetRange( 0, 255 );
1669 disc_title->SetToolTip( wxU(_("Title number.")) );
1670 // \bug [string] needs to be DVDs instead of DVD's
1671 disc_sub->SetToolTip( wxU(_(
1672 "DVD's can have up to 32 subtitles numbered 0..31. "
1673 "Note this is not the same thing as a subtitle name (e.g. 'en'). "
1674 "If a value -1 is used, no subtitle will be shown." )) );
1675 // \bug [string] needs to be DVDs instead of DVD's
1676 disc_audio->SetToolTip( wxU(_("Audio track number. "
1677 "DVD's can have up to 8 audio tracks numbered 0..7."
1681 case SELECTION_DISC_TYPE_VCD:
1682 disc_sub->Enable(); disc_sub_label->Enable();
1683 disc_audio->Enable(); disc_audio_label->Enable();
1684 disc_chapter->Disable(); disc_chapter_label->Disable();
1685 psz_device = config_GetPsz( p_intf, "vcd" );
1686 if( !b_disc_device_changed )
1688 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1689 else disc_device->SetValue( wxT("") );
1693 if (config_GetInt( p_intf, "vcdx-PBC" ))
1695 disc_title_label->SetLabel ( wxT("Playback LID") );
1696 disc_title->SetToolTip( wxU(_(
1697 "Playback control (PBC) usually starts with number 1." )) );
1701 disc_title_label->SetLabel ( wxT("Entry") );
1702 disc_title->SetToolTip( wxU(_(
1703 "The first entry (the beginning of the first MPEG track) is 0." )) );
1707 disc_title_label->SetLabel ( wxU(_("Track")) );
1708 disc_title->SetToolTip( wxU(_("Track number.")) );
1710 disc_title->SetRange( 0, 99 ); // only 100 tracks allowed on VCDs
1711 disc_sub->SetRange( -1, 3 ); // up to 4 subtitles -1 = no subtitle
1712 disc_audio->SetRange( 0, 1 ); // up to 2 audio tracks
1713 // \bug [string] needs to be SVCDs instead of SVCD's
1714 disc_sub->SetToolTip( wxU(_(
1715 "SVCD's can have up to 4 subtitles numbered 0..3. "
1716 "If a value -1 is used, no subtitle will be shown." )) );
1717 // \bug [string] needs to be SVCDs instead of SVCD's
1718 disc_audio->SetToolTip( wxU(_("Audio track number. "
1719 "VCD's can have up to 2 audio tracks numbered 0 or 1. "
1723 case SELECTION_DISC_TYPE_CDDA:
1724 disc_sub->Disable(); disc_sub_label->Disable();
1725 disc_chapter->Disable(); disc_chapter_label->Disable();
1726 disc_audio->Disable(); disc_audio_label->Disable();
1727 disc_title_label->SetLabel ( wxU(_("Track")) );
1729 disc_title->SetToolTip( wxU(_(
1730 "Audio CDs can have up to 100 tracks, the first track is usually 1. "
1731 "If 0 is given, then all tracks are played.")) );
1733 disc_title->SetToolTip( wxU(_(
1734 "Audio CDs can have up to 100 tracks, the first track is usually 1."
1737 psz_device = config_GetPsz( p_intf, "cd-audio" );
1738 if( !b_disc_device_changed )
1740 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1741 else disc_device->SetValue( wxT("") );
1744 /* There are at most 100 tracks in a CD-DA */
1745 disc_title->SetRange( 0, 100 );
1749 msg_Err( p_intf, "invalid Disc type selection (%d)",
1750 disc_type->GetSelection() );
1754 disc_title->SetValue( 0 ); i_disc_title = 0;
1755 disc_chapter->SetValue( 0 ); i_disc_chapter = 0;
1757 if( psz_device ) free( psz_device );
1759 UpdateMRL( DISC_ACCESS );
1762 /*****************************************************************************
1763 * Net panel event methods.
1764 *****************************************************************************/
1765 void OpenDialog::OnNetPanelChangeSpin( wxSpinEvent& event )
1767 wxCommandEvent cevent;
1768 cevent.SetId(event.GetId());
1769 cevent.SetInt(event.GetPosition());
1770 OnNetPanelChange(cevent);
1773 void OpenDialog::OnNetPanelChange( wxCommandEvent& event )
1775 if( event.GetId() >= NetPort1_Event && event.GetId() <= NetPort3_Event )
1777 i_net_ports[event.GetId() - NetPort1_Event] = event.GetInt();
1780 UpdateMRL( NET_ACCESS );
1783 void OpenDialog::OnNetTypeChange( wxCommandEvent& event )
1787 i_net_type = event.GetId() - NetRadio1_Event;
1791 net_radios[i]->SetValue( event.GetId() == (NetRadio1_Event+i) );
1792 net_subpanels[i]->Enable( event.GetId() == (NetRadio1_Event+i) );
1794 /* UDP Unicast or multicast -> timeshift */
1795 if( i_net_type == 0 || i_net_type == 1 )
1796 net_timeshift->Enable();
1798 net_timeshift->Disable();
1800 UpdateMRL( NET_ACCESS );
1803 /*****************************************************************************
1804 * Subtitles file event methods.
1805 *****************************************************************************/
1806 void OpenDialog::OnSubsFileEnable( wxCommandEvent& event )
1808 subsfile_button->Enable( event.GetInt() != 0 );
1809 subbrowse_button->Enable( event.GetInt() != 0 );
1810 subfile_combo->Enable( event.GetInt() != 0 );
1813 void OpenDialog::OnSubsFileSettings( wxCommandEvent& WXUNUSED(event) )
1815 /* Show/hide the open dialog */
1816 if( subsfile_dialog == NULL )
1817 subsfile_dialog = new SubsFileDialog( p_intf, this );
1819 if( subsfile_dialog && subsfile_dialog->ShowModal() == wxID_OK )
1821 subsfile_mrl.Empty();
1822 subsfile_mrl.Add( wxString(wxT("sub-file=")) + subfile_combo->GetValue() );
1823 if( subsfile_dialog->encoding_combo )
1825 subsfile_mrl.Add( wxString(wxT("subsdec-encoding=")) +
1826 subsfile_dialog->encoding_combo->GetValue() );
1828 if( subsfile_dialog->align_combo )
1830 subsfile_mrl.Add( wxString::Format(wxT("subsdec-align=%i"),
1831 (int)subsfile_dialog->align_combo->GetClientData(
1832 subsfile_dialog->align_combo->GetSelection()) ) );
1834 if( subsfile_dialog->size_combo )
1836 subsfile_mrl.Add( wxString::Format( wxT("freetype-rel-fontsize=%i"),
1837 (int)subsfile_dialog->size_combo->GetClientData(
1838 subsfile_dialog->size_combo->GetSelection()) ) );
1840 subsfile_mrl.Add( wxString::Format( wxT("sub-fps=%i"),
1841 subsfile_dialog->fps_spinctrl->GetValue() ) );
1842 subsfile_mrl.Add( wxString::Format( wxT("sub-delay=%i"),
1843 subsfile_dialog->delay_spinctrl->GetValue() ) );
1847 /*****************************************************************************
1848 * Stream output event methods.
1849 *****************************************************************************/
1850 void OpenDialog::OnSoutEnable( wxCommandEvent& event )
1852 sout_button->Enable( event.GetInt() != 0 );
1855 void OpenDialog::OnSoutSettings( wxCommandEvent& WXUNUSED(event) )
1857 /* Show/hide the open dialog */
1858 if( sout_dialog == NULL )
1859 sout_dialog = new SoutDialog( p_intf, this );
1861 if( sout_dialog && sout_dialog->ShowModal() == wxID_OK )
1863 sout_mrl = sout_dialog->GetOptions();
1867 /*****************************************************************************
1868 * Caching event methods.
1869 *****************************************************************************/
1870 void OpenDialog::OnCachingEnable( wxCommandEvent& event )
1872 caching_value->Enable( event.GetInt() != 0 );
1873 i_caching = caching_value->GetValue();
1877 void OpenDialog::OnCachingChangeSpin( wxSpinEvent& event )
1879 wxCommandEvent cevent;
1880 OnCachingChange(cevent);
1883 void OpenDialog::OnCachingChange( wxCommandEvent& event )
1885 i_caching = event.GetInt();
1889 /*****************************************************************************
1890 * Utility functions.
1891 *****************************************************************************/
1892 wxArrayString SeparateEntries( wxString entries )
1894 vlc_bool_t b_quotes_mode = VLC_FALSE;
1896 wxArrayString entries_array;
1899 wxStringTokenizer token( entries, wxT(" \t\r\n\""), wxTOKEN_RET_DELIMS );
1901 while( token.HasMoreTokens() )
1903 entry += token.GetNextToken();
1905 if( entry.IsEmpty() ) continue;
1907 if( !b_quotes_mode && entry.Last() == wxT('\"') )
1909 /* Enters quotes mode */
1911 b_quotes_mode = VLC_TRUE;
1913 else if( b_quotes_mode && entry.Last() == wxT('\"') )
1915 /* Finished the quotes mode */
1917 b_quotes_mode = VLC_FALSE;
1919 else if( !b_quotes_mode && entry.Last() != wxT('\"') )
1921 /* we found a non-quoted standalone string */
1922 if( token.HasMoreTokens() ||
1923 entry.Last() == wxT(' ') || entry.Last() == wxT('\t') ||
1924 entry.Last() == wxT('\r') || entry.Last() == wxT('\n') )
1926 if( !entry.IsEmpty() ) entries_array.Add( entry );
1933 if( !entry.IsEmpty() ) entries_array.Add( entry );
1935 return entries_array;