1 /*****************************************************************************
2 * open.cpp : Open dialog box
3 *****************************************************************************
4 * Copyright (C) 2000-2005 the VideoLAN team
7 * Authors: Gildas Bazin <gbazin@videolan.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
27 #include "dialogs/open.hpp"
28 #include "dialogs/streamout.hpp"
29 #include "dialogs/preferences_widgets.h"
30 #include "dialogs/subtitles.hpp"
32 #include "vlc_charset.h"
34 #undef HAVE_LIBCDIO // Disable broken code
37 #include <cdio/cdio.h>
38 #include <cdio/cd_types.h>
39 #include <cdio/logging.h>
40 #endif /* HAVE_LIBCDIO */
43 #include <libvcd/version.h>
44 /* There was a bug in libvcdinfo <= 23 which prevented C++ compilation */
45 #if LIBVCD_VERSION_NUM > 23
46 #include <libvcd/info.h>
47 #endif /* LIBVCD_VERSION_NUM > 23 */
48 #endif /* HAVE_VCDINFO */
50 #include <wx/combobox.h>
51 #include <wx/statline.h>
52 #include <wx/tokenzr.h>
55 # define wxRB_SINGLE 0
58 #define SELECTION_DISC_TYPE_DVD_MENUS 0
59 #define SELECTION_DISC_TYPE_DVD 1
60 #define SELECTION_DISC_TYPE_VCD 2
61 #define SELECTION_DISC_TYPE_CDDA 3
63 /*****************************************************************************
65 *****************************************************************************/
67 /* IDs for the controls and the menu commands */
70 Notebook_Event = wxID_HIGHEST,
89 NetRadio1_Event, NetRadio2_Event, NetRadio3_Event, NetRadio4_Event,
90 NetPort1_Event, NetPort2_Event, NetPort3_Event,
91 NetAddr1_Event, NetAddr2_Event, NetAddr3_Event, NetAddr4_Event,
92 NetForceIPv6_Event, NetTimeshift_Event,
95 SubsFileSettings_Event,
103 AdvancedOptions_Event
106 BEGIN_EVENT_TABLE(OpenDialog, wxDialog)
108 EVT_BUTTON(wxID_OK, OpenDialog::OnOk)
109 EVT_BUTTON(wxID_CANCEL, OpenDialog::OnCancel)
111 EVT_NOTEBOOK_PAGE_CHANGED(Notebook_Event, OpenDialog::OnPageChange)
113 EVT_TEXT(MRL_Event, OpenDialog::OnMRLChange)
115 /* Events generated by the file panel */
116 EVT_TEXT(FileName_Event, OpenDialog::OnFilePanelChange)
117 EVT_BUTTON(FileBrowse_Event, OpenDialog::OnFileBrowse)
118 EVT_TEXT(SubFileName_Event, OpenDialog::OnSubFileChange)
119 EVT_BUTTON(SubFileBrowse_Event, OpenDialog::OnSubFileBrowse)
121 /* Events generated by the disc panel */
122 EVT_RADIOBOX(DiscType_Event, OpenDialog::OnDiscTypeChange)
124 EVT_CHECKBOX(DiscProbe_Event, OpenDialog::OnDiscProbe)
126 EVT_TEXT(DiscDevice_Event, OpenDialog::OnDiscDeviceChange)
127 EVT_TEXT(DiscDevice_Event, OpenDialog::OnDiscPanelChange)
128 EVT_TEXT(DiscTitle_Event, OpenDialog::OnDiscPanelChange)
129 EVT_SPINCTRL(DiscTitle_Event, OpenDialog::OnDiscPanelChangeSpin)
130 EVT_TEXT(DiscChapter_Event, OpenDialog::OnDiscPanelChange)
131 EVT_SPINCTRL(DiscChapter_Event, OpenDialog::OnDiscPanelChangeSpin)
132 EVT_TEXT(DiscSub_Event, OpenDialog::OnDiscPanelChange)
133 EVT_TEXT(DiscAudio_Event, OpenDialog::OnDiscPanelChange)
134 EVT_SPINCTRL(DiscSub_Event, OpenDialog::OnDiscPanelChangeSpin)
136 /* Events generated by the net panel */
137 EVT_RADIOBUTTON(NetRadio1_Event, OpenDialog::OnNetTypeChange)
138 EVT_RADIOBUTTON(NetRadio2_Event, OpenDialog::OnNetTypeChange)
139 EVT_RADIOBUTTON(NetRadio3_Event, OpenDialog::OnNetTypeChange)
140 EVT_RADIOBUTTON(NetRadio4_Event, OpenDialog::OnNetTypeChange)
141 EVT_TEXT(NetPort1_Event, OpenDialog::OnNetPanelChange)
142 EVT_SPINCTRL(NetPort1_Event, OpenDialog::OnNetPanelChangeSpin)
143 EVT_TEXT(NetPort2_Event, OpenDialog::OnNetPanelChange)
144 EVT_SPINCTRL(NetPort2_Event, OpenDialog::OnNetPanelChangeSpin)
145 EVT_TEXT(NetPort3_Event, OpenDialog::OnNetPanelChange)
146 EVT_SPINCTRL(NetPort3_Event, OpenDialog::OnNetPanelChangeSpin)
147 EVT_TEXT(NetAddr2_Event, OpenDialog::OnNetPanelChange)
148 EVT_TEXT(NetAddr3_Event, OpenDialog::OnNetPanelChange)
149 EVT_TEXT(NetAddr4_Event, OpenDialog::OnNetPanelChange)
150 EVT_CHECKBOX(NetForceIPv6_Event, OpenDialog::OnNetPanelChange)
151 EVT_CHECKBOX(NetTimeshift_Event, OpenDialog::OnNetPanelChange)
153 /* Events generated by the subtitle file buttons */
154 EVT_CHECKBOX(SubsFileEnable_Event, OpenDialog::OnSubsFileEnable)
155 EVT_BUTTON(SubsFileSettings_Event, OpenDialog::OnSubsFileSettings)
157 /* Events generated by the stream output buttons */
158 EVT_CHECKBOX(SoutEnable_Event, OpenDialog::OnSoutEnable)
159 EVT_BUTTON(SoutSettings_Event, OpenDialog::OnSoutSettings)
161 /* Events generated by the caching button */
162 EVT_CHECKBOX(CachingEnable_Event, OpenDialog::OnCachingEnable)
163 EVT_TEXT(CachingChange_Event, OpenDialog::OnCachingChange)
164 EVT_SPINCTRL(CachingChange_Event, OpenDialog::OnCachingChangeSpin)
166 /* Hide the window when the user closes the window */
167 EVT_CLOSE(OpenDialog::OnClose)
172 /*****************************************************************************
174 *****************************************************************************/
175 WX_DEFINE_ARRAY(ConfigControl *, ArrayOfConfigControls);
177 class AutoBuiltPanel : public wxPanel
182 AutoBuiltPanel( wxWindow *, OpenDialog *, intf_thread_t *,
185 virtual ~AutoBuiltPanel() {}
187 void UpdateAdvancedMRL();
190 ArrayOfConfigControls config_array;
191 ArrayOfConfigControls advanced_config_array;
192 wxComboBox *p_advanced_mrl_combo;
195 intf_thread_t *p_intf;
196 OpenDialog *p_open_dialog;
198 void OnAdvanced( wxCommandEvent& event );
199 wxDialog *p_advanced_dialog;
201 DECLARE_EVENT_TABLE();
204 BEGIN_EVENT_TABLE(AutoBuiltPanel, wxPanel)
205 EVT_BUTTON(AdvancedOptions_Event, AutoBuiltPanel::OnAdvanced)
208 static void AutoBuildCallback( void *p_data )
210 ((OpenDialog *)p_data)->UpdateMRL();
213 static void AutoBuildAdvancedCallback( void *p_data )
215 ((AutoBuiltPanel *)p_data)->UpdateAdvancedMRL();
218 AutoBuiltPanel::AutoBuiltPanel( wxWindow *parent, OpenDialog *dialog,
219 intf_thread_t *_p_intf,
220 const module_t *p_module )
221 : wxPanel( parent, -1, wxDefaultPosition, wxDefaultSize ),
222 name( wxU(p_module->psz_object_name) ),
223 p_advanced_mrl_combo( NULL ),
224 p_intf( _p_intf ), p_open_dialog( dialog ), p_advanced_dialog( NULL )
226 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
227 module_config_t *p_item = p_module->p_config,
228 *p_end = p_item + p_module->confsize;
229 bool b_advanced = false;
233 if( !(p_item->i_type & CONFIG_HINT) && p_item->b_advanced )
236 if( p_item->i_type & CONFIG_HINT || p_item->b_advanced )
239 ConfigControl *control =
240 CreateConfigControl( VLC_OBJECT(p_intf), p_item, this );
242 config_array.Add( control );
244 /* Don't add items that were not recognized */
245 if( control == NULL ) continue;
247 control->SetUpdateCallback( AutoBuildCallback, (void *)dialog );
249 sizer->Add( control, 0, wxEXPAND | wxALL, 2 );
251 while( p_item < p_end && p_item++ );
256 new wxButton( this, AdvancedOptions_Event,
257 wxU(_("Advanced options...")) );
258 sizer->Add( button, 0, wxALL, 5 );
260 /* Build the advanced dialog */
262 new wxDialog( this, -1, ((wxString)wxU(_("Advanced options"))) +
263 wxT(" (") + wxU( p_module->psz_longname ) + wxT(")"),
264 wxDefaultPosition, wxDefaultSize,
265 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER );
267 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
269 /* Create MRL combobox */
270 wxBoxSizer *mrl_sizer_sizer = new wxBoxSizer( wxHORIZONTAL );
271 wxStaticBox *mrl_box =
272 new wxStaticBox( p_advanced_dialog, -1,
273 wxU(_("Advanced options")) );
274 wxStaticBoxSizer *mrl_sizer =
275 new wxStaticBoxSizer( mrl_box, wxHORIZONTAL );
276 wxStaticText *mrl_label =
277 new wxStaticText( p_advanced_dialog, -1, wxU(_("Options:")) );
278 p_advanced_mrl_combo =
279 new wxComboBox( p_advanced_dialog, MRL_Event, wxT(""),
280 wxDefaultPosition, wxDefaultSize );
281 mrl_sizer->Add( mrl_label, 0, wxALL | wxALIGN_CENTER, 5 );
282 mrl_sizer->Add( p_advanced_mrl_combo, 1, wxALL | wxALIGN_CENTER, 5 );
283 mrl_sizer_sizer->Add( mrl_sizer, 1, wxEXPAND | wxALL, 5 );
284 sizer->Add( mrl_sizer_sizer, 0, wxEXPAND | wxALL, 2 );
286 /* Add advanced options to panel */
287 module_config_t *p_item = p_module->p_config;
290 if( p_item->i_type & CONFIG_HINT || !p_item->b_advanced )
293 ConfigControl *control =
294 CreateConfigControl( VLC_OBJECT(p_intf), p_item,
297 advanced_config_array.Add( control );
299 /* Don't add items that were not recognized */
300 if( control == NULL ) continue;
302 control->SetUpdateCallback( AutoBuildAdvancedCallback,
305 sizer->Add( control, 0, wxEXPAND | wxALL, 2 );
307 while( p_item < p_end && p_item++ );
310 wxPanel *dummy_panel = new wxPanel( p_advanced_dialog, -1 );
311 sizer->Add( dummy_panel, 1 );
312 wxStaticLine *static_line =
313 new wxStaticLine( p_advanced_dialog, wxID_OK );
314 sizer->Add( static_line, 0, wxEXPAND | wxALL, 5 );
317 wxButton *ok_button =
318 new wxButton( p_advanced_dialog, wxID_OK, wxU(_("&OK")) );
319 ok_button->SetDefault();
320 wxButton *cancel_button =
321 new wxButton( p_advanced_dialog, wxID_CANCEL, wxU(_("&Cancel")) );
322 wxStdDialogButtonSizer *button_sizer = new wxStdDialogButtonSizer;
323 button_sizer->AddButton( ok_button );
324 button_sizer->AddButton( cancel_button );
325 button_sizer->Realize();
326 sizer->Add( button_sizer, 0, wxEXPAND|wxALL, 5 );
328 sizer->SetMinSize( 400, -1 );
329 p_advanced_dialog->SetSizerAndFit( sizer );
332 this->SetSizerAndFit( sizer );
335 void AutoBuiltPanel::OnAdvanced( wxCommandEvent& event )
337 if( p_advanced_dialog->ShowModal() == wxID_OK )
340 p_open_dialog->UpdateMRL();
344 void AutoBuiltPanel::UpdateAdvancedMRL()
348 for( int i = 0; i < (int)advanced_config_array.GetCount(); i++ )
350 ConfigControl *control = advanced_config_array.Item(i);
352 mrltemp += (i ? wxT(" :") : wxT(":"));
354 if( control->GetType() == CONFIG_ITEM_BOOL &&
355 !control->GetIntValue() ) mrltemp += wxT("no-");
357 mrltemp += control->GetName();
359 switch( control->GetType() )
361 case CONFIG_ITEM_STRING:
362 case CONFIG_ITEM_FILE:
363 case CONFIG_ITEM_DIRECTORY:
364 case CONFIG_ITEM_MODULE:
365 mrltemp += wxT("=\"") + control->GetPszValue() + wxT("\"");
367 case CONFIG_ITEM_INTEGER:
369 wxString::Format( wxT("=%i"), control->GetIntValue() );
371 case CONFIG_ITEM_FLOAT:
373 wxString::Format(wxT("=%f"), control->GetFloatValue());
378 p_advanced_mrl_combo->SetValue( mrltemp );
381 /*****************************************************************************
383 *****************************************************************************/
384 OpenDialog::OpenDialog( intf_thread_t *_p_intf, wxWindow *_p_parent,
385 int i_access_method, int i_arg ):
386 wxDialog( _p_parent, -1, wxU(_("Open...")), wxDefaultPosition,
387 wxDefaultSize, wxDEFAULT_FRAME_STYLE )
389 OpenDialog( _p_intf, _p_parent, i_access_method, i_arg, OPEN_NORMAL );
392 OpenDialog::OpenDialog( intf_thread_t *_p_intf, wxWindow *_p_parent,
393 int i_access_method, int i_arg, int _i_method ):
394 wxDialog( _p_parent, -1, wxU(_("Open...")), wxDefaultPosition,
395 wxDefaultSize, wxDEFAULT_FRAME_STYLE )
397 /* Initializations */
398 i_method = _i_method;
400 p_parent = _p_parent;
401 SetIcon( *p_intf->p_sys->p_icon );
403 i_disc_type_selection = 0;
408 subsfile_dialog = NULL;
409 b_disc_device_changed = false;
411 /* Create a panel to put everything in */
412 wxPanel *panel = new wxPanel( this, -1 );
413 panel->SetAutoLayout( TRUE );
416 /* Advanced options */
417 wxStaticBox *adv_box = new wxStaticBox( panel, -1,
418 wxU(_("Advanced options")) );
419 wxStaticBoxSizer *adv_sizer = new wxStaticBoxSizer( adv_box,
423 wxFlexGridSizer *common_opt_sizer = new wxFlexGridSizer( 5, 1, 20 );
424 if( i_method == OPEN_NORMAL )
426 /* Create Stream Output checkox */
427 sout_checkbox = new wxCheckBox( panel, SoutEnable_Event,
428 wxU(_("Stream/Save")) );
429 sout_checkbox->SetToolTip( wxU(_("Use VLC as a stream server")) );
430 common_opt_sizer->Add( sout_checkbox, 0,
431 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
433 sout_button = new wxButton( panel, SoutSettings_Event,
434 wxU(_("Settings...")) );
435 sout_button->Disable();
437 char *psz_sout = config_GetPsz( p_intf, "sout" );
438 if( psz_sout && *psz_sout )
440 sout_checkbox->SetValue(TRUE);
441 sout_button->Enable();
442 subsfile_mrl.Add( wxString(wxT("sout=")) + wxL2U(psz_sout) );
444 if( psz_sout ) free( psz_sout );
446 common_opt_sizer->Add( sout_button, 1, wxALIGN_LEFT |
447 wxALIGN_CENTER_VERTICAL );
449 common_opt_sizer->Add( new wxPanel( this, -1 ), 1,
450 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
453 /* Create caching options */
454 caching_checkbox = new wxCheckBox( panel, CachingEnable_Event,
456 caching_checkbox->SetToolTip( wxU(_("Change the default caching value "
457 "(in milliseconds)")) );
458 common_opt_sizer->Add( caching_checkbox, 0,
459 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
460 caching_value = new wxSpinCtrl( panel, CachingChange_Event );
461 caching_value->SetRange( 0, 1000000 );
462 caching_value->Disable();
463 common_opt_sizer->Add( caching_value, 0,
464 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
467 wxBoxSizer *mrl_sizer = new wxBoxSizer( wxHORIZONTAL );
468 wxStaticText *mrl_label = new wxStaticText( panel, -1,
469 wxU(_("Customize:")) );
470 mrl_combo = new wxComboBox( panel, MRL_Event, wxT(""),
471 wxDefaultPosition, wxDefaultSize );
472 //Point(20,25), wxSize(120, -1) );
473 mrl_combo->SetToolTip( wxU(_("You can use this field directly by typing "
474 "the full MRL you want to open.\n""Alternatively, the field will be "
475 "filled automatically when you use the controls above.")) );
477 mrl_sizer->Add( mrl_label, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
478 mrl_sizer->Add( mrl_combo, 1, wxALL | wxEXPAND | wxALIGN_CENTER_VERTICAL,
481 adv_sizer->Add( common_opt_sizer, 0, wxTOP | wxLEFT|wxRIGHT | wxEXPAND, 5 );
482 adv_sizer->Add( mrl_sizer, 0, wxBOTTOM | wxLEFT|wxRIGHT | wxEXPAND, 5 );
485 wxStaticLine *static_line = new wxStaticLine( panel, wxID_OK );
487 /* Create the buttons */
488 wxButton *ok_button = new wxButton( panel, wxID_OK, wxU(_("&OK")) );
489 ok_button->SetDefault();
490 wxButton *cancel_button = new wxButton( panel, wxID_CANCEL,
493 /* Create notebook */
494 notebook = new wxNotebook( panel, Notebook_Event );
496 #if (!wxCHECK_VERSION(2,5,2))
497 wxNotebookSizer *notebook_sizer = new wxNotebookSizer( notebook );
500 notebook->AddPage( FilePanel( notebook ), wxU(_("File")),
501 i_access_method == FILE_ACCESS );
502 notebook->AddPage( DiscPanel( notebook ), wxU(_("Disc")),
503 i_access_method == DISC_ACCESS );
504 notebook->AddPage( NetPanel( notebook ), wxU(_("Network")),
505 i_access_method == NET_ACCESS );
507 module_t *p_module = config_FindModule( VLC_OBJECT(p_intf), "v4l" );
510 AutoBuiltPanel *autopanel =
511 new AutoBuiltPanel( notebook, this, p_intf, p_module );
512 input_tab_array.Add( autopanel );
513 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
514 p_module->psz_shortname : p_module->psz_object_name ),
515 i_access_method == CAPTURE_ACCESS );
518 p_module = config_FindModule( VLC_OBJECT(p_intf), "pvr" );
521 AutoBuiltPanel *autopanel =
522 new AutoBuiltPanel( notebook, this, p_intf, p_module );
523 input_tab_array.Add( autopanel );
524 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
525 p_module->psz_shortname : p_module->psz_object_name ),
526 i_access_method == CAPTURE_ACCESS );
529 p_module = config_FindModule( VLC_OBJECT(p_intf), "dvb" );
532 AutoBuiltPanel *autopanel =
533 new AutoBuiltPanel( notebook, this, p_intf, p_module );
534 input_tab_array.Add( autopanel );
535 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
536 p_module->psz_shortname : p_module->psz_object_name ),
537 i_access_method == CAPTURE_ACCESS );
540 p_module = config_FindModule( VLC_OBJECT(p_intf), "dshow" );
543 AutoBuiltPanel *autopanel =
544 new AutoBuiltPanel( notebook, this, p_intf, p_module );
545 input_tab_array.Add( autopanel );
546 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
547 p_module->psz_shortname : p_module->psz_object_name ),
548 i_access_method == CAPTURE_ACCESS );
551 /* Update Disc panel */
552 wxCommandEvent dummy_event;
553 OnDiscTypeChange( dummy_event );
555 /* Update Net panel */
556 dummy_event.SetId( NetRadio1_Event );
557 OnNetTypeChange( dummy_event );
560 wxNotebookEvent event( wxEVT_NULL, 0, i_access_method );
561 OnPageChange( event );
563 /* Place everything in sizers */
564 wxStdDialogButtonSizer *button_sizer = new wxStdDialogButtonSizer;
565 button_sizer->AddButton( cancel_button );
566 button_sizer->AddButton( ok_button );
567 button_sizer->Realize();
568 wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL );
569 wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
570 #if (!wxCHECK_VERSION(2,5,2))
571 panel_sizer->Add( notebook_sizer, 1, wxEXPAND | wxALL, 5 );
573 panel_sizer->Add( notebook, 1, wxEXPAND | wxALL, 5 );
575 panel_sizer->Add( adv_sizer, 0, wxEXPAND | wxALL, 5 );
576 panel_sizer->Add( static_line, 0, wxEXPAND | wxALL, 5 );
577 panel_sizer->Add( button_sizer, 0, wxEXPAND | wxALL, 5 );
578 panel_sizer->Layout();
579 panel->SetSizerAndFit( panel_sizer );
580 main_sizer->Add( panel, 1, wxGROW, 0 );
581 main_sizer->Layout();
582 SetSizerAndFit( main_sizer );
585 OpenDialog::~OpenDialog()
588 if( file_dialog ) delete file_dialog;
589 if( sout_dialog ) delete sout_dialog;
590 if( subsfile_dialog ) delete subsfile_dialog;
593 int OpenDialog::Show( int i_access_method, int i_arg )
595 notebook->SetSelection( i_access_method );
596 int i_ret = wxDialog::Show();
603 int OpenDialog::Show()
605 int i_ret = wxDialog::Show();
611 /*****************************************************************************
613 *****************************************************************************/
614 wxPanel *OpenDialog::FilePanel( wxWindow* parent )
616 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
619 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
621 /* Create browse file line */
622 wxBoxSizer *file_sizer = new wxBoxSizer( wxHORIZONTAL );
624 file_sizer->Add( new wxStaticText( panel, -1, wxU(_("Open:") ) ), 0,
625 wxALL | wxALIGN_CENTER_VERTICAL, 5 );
627 file_combo = new wxComboBox( panel, FileName_Event, wxT("") );
628 wxButton *browse_button = new wxButton( panel, FileBrowse_Event,
629 wxU(_("Browse...")) );
630 file_sizer->Add( file_combo, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
631 file_sizer->Add( browse_button, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
633 /* Create Subtitles File checkox - button */
634 wxFlexGridSizer *subtitles_sizer = new wxFlexGridSizer( 2, 1, 20 );
635 subsfile_checkbox = new wxCheckBox( panel, SubsFileEnable_Event,
636 wxU(_("Use a subtitles file")) );
637 subsfile_checkbox->SetToolTip( wxU(_("Use an external subtitles file.")) );
638 subtitles_sizer->Add( subsfile_checkbox, 0, wxALIGN_CENTER_VERTICAL |
640 subsfile_button = new wxButton( panel, SubsFileSettings_Event,
641 wxU(_("Advanced Settings...")) );
642 subsfile_button->Disable();
643 subtitles_sizer->Add( subsfile_button, 1, wxALIGN_CENTER_VERTICAL |
646 /* Create subtitles file line */
647 wxBoxSizer *subfile_sizer = new wxBoxSizer( wxHORIZONTAL );
649 char *psz_subsfile = config_GetPsz( p_intf, "sub-file" );
650 if( psz_subsfile && *psz_subsfile )
652 subsfile_checkbox->SetValue(TRUE);
653 subsfile_button->Enable();
654 subsfile_mrl.Add( wxString(wxT("sub-file=")) + wxL2U(psz_subsfile) );
656 if( !psz_subsfile ) psz_subsfile = strdup("");
657 subfile_sizer->Add( new wxStaticText( panel, -1, wxU(_("File:") ) ),
658 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
659 subfile_combo = new wxComboBox( panel, SubFileName_Event,
660 wxL2U( psz_subsfile ) );
661 if( psz_subsfile ) free( psz_subsfile );
662 subbrowse_button = new wxButton( panel, SubFileBrowse_Event,
663 wxU(_("Browse...")) );
664 subfile_sizer->Add( subfile_combo, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
665 subfile_sizer->Add( subbrowse_button, 0, wxALL |wxALIGN_CENTER_VERTICAL, 5 );
667 subfile_combo->Disable();
668 subbrowse_button->Disable();
670 psz_subsfile = config_GetPsz( p_intf, "sub-file" );
671 if( psz_subsfile && *psz_subsfile )
673 subfile_combo->Enable();
674 subbrowse_button->Enable();
677 sizer->Add( file_sizer, 0, wxEXPAND | wxALL, 5 );
678 sizer->Add( subtitles_sizer, 0, wxLEFT | wxRIGHT | wxTOP, 5 );
679 sizer->Add( subfile_sizer, 0, wxEXPAND | wxLEFT | wxRIGHT| wxBOTTOM, 5 );
680 panel->SetSizerAndFit( sizer );
684 wxPanel *OpenDialog::DiscPanel( wxWindow* parent )
686 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
689 wxBoxSizer *sizer_row = new wxBoxSizer( wxVERTICAL );
690 wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 3, 20 );
692 static const wxString disc_type_array[] =
694 wxU(_("DVD (menus)")),
700 disc_type = new wxRadioBox( panel, DiscType_Event, wxU(_("Disc type")),
701 wxDefaultPosition, wxDefaultSize,
702 WXSIZEOF(disc_type_array), disc_type_array,
703 WXSIZEOF(disc_type_array), wxRA_SPECIFY_COLS );
706 disc_probe = new wxCheckBox( panel, DiscProbe_Event,
707 wxU(_("Probe Disc(s)")) );
708 disc_probe->SetToolTip( wxU(_("Probe for a DVD, VCD or audio CD. "
709 "First try the Device name entered for the selected Disc type "
710 "(DVD, DVD Menu, VCD, audio CD). If that doesn't find media, try any device "
711 "for the Disc type. If that doesn't work, then try looking for CD-ROMs or "
712 "DVD drives. The Disc type, Device name, and some parameter ranges are set "
713 "based on media we find.")) );
716 sizer_row->Add( disc_type, i_disc_type_selection, wxEXPAND | wxALL, 5 );
718 sizer_row->Add( disc_probe, 0, wxEXPAND | wxALL );
721 wxStaticText *label = new wxStaticText( panel, -1, wxU(_("Device name")) );
722 disc_device = new wxTextCtrl( panel, DiscDevice_Event, wxT(""),
723 wxDefaultPosition, wxDefaultSize,
727 char psz_default_device[3] = {0};
730 /* find the drive_name for the first cdrom drive,
731 * which is probably "D:" and put the drive_name into
732 * psz_default_device... */
733 for( char drive_letter = 'A'; drive_letter <= 'Z'; ++drive_letter )
735 char drive_name[3] = {drive_letter, ':', 0};
736 UINT type = GetDriveTypeA( drive_name );
737 if( type == DRIVE_CDROM )
739 psz_default_device[0] = drive_letter;
740 psz_default_device[1] = ':';
745 psz_forced = config_GetPsz( p_intf, "dvd" );
747 if( strlen(psz_default_device) > 0 &&
748 ( !psz_forced || psz_forced && !*psz_forced ) )
751 disc_device->SetValue( wxL2U(psz_default_device) );
755 sizer->Add( label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
756 sizer->Add( disc_device, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
758 disc_title_label = new wxStaticText( panel, -1, wxU(_("Title")) );
759 disc_title = new wxSpinCtrl( panel, DiscTitle_Event );
760 sizer->Add( disc_title_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
761 sizer->Add( disc_title, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
763 disc_chapter_label = new wxStaticText( panel, -1, wxU(_("Chapter")) );
764 disc_chapter = new wxSpinCtrl( panel, DiscChapter_Event );
765 sizer->Add( disc_chapter_label, 0,
766 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
767 sizer->Add( disc_chapter, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
769 disc_sub_label = new wxStaticText( panel, -1, wxU(_("Subtitles track")) );
770 disc_sub = new wxSpinCtrl( panel, DiscSub_Event );
771 sizer->Add( disc_sub_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
772 sizer->Add( disc_sub, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
773 disc_sub->SetRange( -1, 255 );
774 i_disc_sub = config_GetInt( p_intf, "sub-track" );
775 disc_sub->SetValue( i_disc_sub );
777 disc_audio_label = new wxStaticText( panel, -1, wxU(_("Audio track")) );
778 disc_audio = new wxSpinCtrl( panel, DiscAudio_Event );
779 sizer->Add( disc_audio_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
780 sizer->Add( disc_audio, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
781 disc_audio->SetRange( -1, 255 );
782 i_disc_audio = config_GetInt( p_intf, "audio-track" );
783 disc_audio->SetValue( i_disc_audio );
785 sizer_row->Add( sizer, 0, wxEXPAND | wxALL, 5 );
787 panel->SetSizerAndFit( sizer_row );
791 wxPanel *OpenDialog::NetPanel( wxWindow* parent )
794 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
797 wxBoxSizer *sizer_row = new wxBoxSizer( wxVERTICAL );
798 wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 4, 20 );
800 static const wxString net_type_array[] =
803 wxU(_("UDP/RTP Multicast")),
804 wxU(_("HTTP/HTTPS/FTP/MMS")),
810 net_radios[i] = new wxRadioButton( panel, NetRadio1_Event + i,
812 wxDefaultPosition, wxDefaultSize,
815 net_subpanels[i] = new wxPanel( panel, -1,
816 wxDefaultPosition, wxDefaultSize );
820 net_timeshift = new wxCheckBox( panel, NetTimeshift_Event,
821 wxU(_("Allow timeshifting")) );
824 wxFlexGridSizer *subpanel_sizer;
826 i_net_ports[0] = config_GetInt( p_intf, "server-port" );
827 subpanel_sizer = new wxFlexGridSizer( 3, 1, 20 );
828 label = new wxStaticText( net_subpanels[0], -1, wxU(_("Port")) );
829 net_ports[0] = new wxSpinCtrl( net_subpanels[0], NetPort1_Event,
830 wxString::Format(wxT("%d"), i_net_ports[0]),
831 wxDefaultPosition, wxDefaultSize,
833 0, 65535, i_net_ports[0] );
835 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
836 subpanel_sizer->Add( net_ports[0], 1,
837 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
838 net_ipv6 = new wxCheckBox( net_subpanels[0], NetForceIPv6_Event,
839 wxU(_("Force IPv6")));
840 subpanel_sizer->Add( net_ipv6, 0,
841 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
842 net_subpanels[0]->SetSizerAndFit( subpanel_sizer );
843 net_radios[0]->SetValue( TRUE );
845 /* UDP/RTP Multicast row */
846 subpanel_sizer = new wxFlexGridSizer( 4, 1, 20 );
847 label = new wxStaticText( net_subpanels[1], -1, wxU(_("Address")) );
848 net_addrs[1] = new wxTextCtrl( net_subpanels[1], NetAddr2_Event, wxT(""),
849 wxDefaultPosition, wxDefaultSize,
851 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
852 subpanel_sizer->Add( net_addrs[1], 1,
853 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
855 label = new wxStaticText( net_subpanels[1], -1, wxU(_("Port")) );
856 i_net_ports[1] = i_net_ports[0];
857 net_ports[1] = new wxSpinCtrl( net_subpanels[1], NetPort2_Event,
858 wxString::Format(wxT("%d"), i_net_ports[1]),
859 wxDefaultPosition, wxDefaultSize,
861 0, 65535, i_net_ports[1] );
863 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
864 subpanel_sizer->Add( net_ports[1], 1,
865 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
866 net_subpanels[1]->SetSizerAndFit( subpanel_sizer );
868 /* HTTP and RTSP rows */
871 subpanel_sizer = new wxFlexGridSizer( 2, 1, 20 );
872 label = new wxStaticText( net_subpanels[i], -1, wxU(_("URL")) );
873 net_addrs[i] = new wxTextCtrl( net_subpanels[i], NetAddr1_Event + i,
874 (i == 2) ? wxT("") : wxT("rtsp://"),
875 wxDefaultPosition, wxSize( 200, -1 ),
877 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
878 subpanel_sizer->Add( net_addrs[i], 1,
879 wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
880 net_subpanels[i]->SetSizerAndFit( subpanel_sizer );
883 /* Stuff everything into the main panel */
886 sizer->Add( net_radios[i], 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
888 sizer->Add( net_subpanels[i], 1, wxEXPAND | wxALIGN_LEFT |
889 wxALIGN_CENTER_VERTICAL | wxALL, 5 );
891 sizer->Add( net_timeshift, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
894 sizer_row->Add( sizer, 0, wxEXPAND | wxALL, 5 );
896 panel->SetSizerAndFit( sizer_row );
900 void OpenDialog::UpdateMRL()
902 UpdateMRL( i_current_access_method );
905 void OpenDialog::UpdateMRL( int i_access_method )
907 wxString mrltemp, caching_name;
909 i_current_access_method = i_access_method;
911 switch( i_access_method )
914 mrltemp = file_combo->GetValue();
915 caching_name = wxT("file-caching");
919 i_disc_type_selection = disc_type->GetSelection();
921 switch ( i_disc_type_selection )
923 case 0: /* DVD with menus */
924 case 1: /* DVD without menus */
925 disc_device->SetToolTip( wxU(_("DVD device to use" ) ) );
926 if( i_disc_type_selection == 0 )
928 mrltemp = wxT("dvd://") + disc_device->GetValue();
929 caching_name = wxT("dvdnav-caching");
933 mrltemp = wxT("dvdsimple://") + disc_device->GetValue();
934 caching_name = wxT("dvdread-caching");
937 if( i_disc_title > 0 )
939 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
941 if( i_disc_chapter > 0 )
942 mrltemp += wxString::Format( wxT(":%d"), i_disc_chapter );
945 if( i_disc_sub >= 0 )
946 mrltemp += wxString::Format( wxT(" :sub-track=%d"),
948 if( i_disc_audio >= 0 )
949 mrltemp += wxString::Format( wxT(" :audio-track=%d"),
953 case 2: /* VCD of some sort */
955 disc_device->SetToolTip( wxU(_("Name of CD-ROM device "
956 "to read Video CD from. If this field is left empty, we will scan "
957 "for a CD-ROM with a VCD in it.")) );
958 mrltemp = wxT("vcdx://") + disc_device->GetValue();
959 if( i_disc_title > 0 )
960 mrltemp += wxString::Format( wxT("@%c%d"),
961 config_GetInt( p_intf, "vcdx-PBC" )
962 ? 'P' : 'E', i_disc_title );
964 disc_device->SetToolTip( wxU(_("CD-ROM device to use" ) ) );
965 mrltemp = wxT("vcd://") + disc_device->GetValue();
966 if( i_disc_title > 0 )
967 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
970 if( i_disc_sub >= 0 )
971 mrltemp += wxString::Format( wxT(" :sub-track=%d"),
974 if( i_disc_audio >= 0 )
975 mrltemp += wxString::Format( wxT(" :audio-track=%d"),
977 caching_name = wxT("vcd-caching");
982 disc_device->SetToolTip( wxU(_("Name of CD-ROM device "
983 "to read audio CD from. If this field is left empty, we will scan "
984 "for a CD-ROM with an audio CD in it." )) );
985 mrltemp = wxT("cddax://")
987 disc_device->SetToolTip( wxU(_("CD-ROM device to use" ) ) ) ;
988 mrltemp = wxT("cdda://")
990 + disc_device->GetValue();
991 if( i_disc_title > 0 )
992 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
994 caching_name = wxT("cdda-caching");
998 msg_Err( p_intf, "invalid selection (%d)",
999 disc_type->GetSelection() );
1005 switch( i_net_type )
1008 mrltemp = wxT("udp://@");
1009 if ( net_ipv6->GetValue() )
1011 mrltemp += wxT("[::]");
1013 if( i_net_ports[0] !=
1014 config_GetInt( p_intf, "server-port" ) )
1016 mrltemp += wxString::Format( wxT(":%d"), i_net_ports[0] );
1019 caching_name = wxT("udp-caching");
1023 mrltemp = wxT("udp://@");
1024 if ((net_addrs[1]->GetLineText(0).Find (':') != -1)
1025 && (net_addrs[1]->GetLineText(0)[0u] != '['))
1027 /* automatically adds '[' and ']' to IPv6 addresses */
1028 mrltemp += wxT("[") + net_addrs[1]->GetLineText(0)
1033 mrltemp += net_addrs[1]->GetLineText(0);
1035 if( i_net_ports[1] != config_GetInt( p_intf, "server-port" ) )
1037 mrltemp += wxString::Format( wxT(":%d"), i_net_ports[1] );
1040 caching_name = wxT("udp-caching");
1045 if( net_addrs[2]->GetLineText(0).Find(wxT("://")) == -1 )
1046 mrltemp = wxT("http://");
1048 mrltemp += net_addrs[2]->GetLineText(0);
1049 if( ! mrltemp.Left(4).CmpNoCase(wxT("http")) )
1050 caching_name = wxT("http-caching");
1051 else if( ! mrltemp.Left(3).CmpNoCase(wxT("mms")) )
1052 caching_name = wxT("mms-caching");
1054 caching_name= wxT("ftp-caching");
1059 if( net_addrs[3]->GetLineText(0).Find(wxT("rtsp://")) != 0 )
1061 mrltemp = wxT("rtsp://");
1063 mrltemp += net_addrs[3]->GetLineText(0);
1065 caching_name = wxT("rtsp-caching");
1068 if( net_timeshift->IsEnabled() && net_timeshift->IsChecked() )
1069 mrltemp += wxT(" :access-filter=timeshift");
1074 int i_item = i_access_method - MAX_ACCESS;
1076 if( i_item < 0 || i_item >= (int)input_tab_array.GetCount() )
1079 AutoBuiltPanel *input_panel = input_tab_array.Item( i_item );
1081 mrltemp = input_panel->name + wxT("://");
1083 for( int i=0; i < (int)input_panel->config_array.GetCount(); i++ )
1085 ConfigControl *control = input_panel->config_array.Item(i);
1087 mrltemp += wxT(" :");
1089 if( control->GetType() == CONFIG_ITEM_BOOL &&
1090 !control->GetIntValue() ) mrltemp += wxT("no-");
1092 mrltemp += control->GetName();
1094 switch( control->GetType() )
1096 case CONFIG_ITEM_STRING:
1097 case CONFIG_ITEM_FILE:
1098 case CONFIG_ITEM_DIRECTORY:
1099 case CONFIG_ITEM_MODULE:
1100 mrltemp += wxT("=\"") + control->GetPszValue() + wxT("\"");
1102 case CONFIG_ITEM_INTEGER:
1104 wxString::Format( wxT("=%i"), control->GetIntValue() );
1106 case CONFIG_ITEM_FLOAT:
1108 wxString::Format(wxT("=%f"), control->GetFloatValue());
1113 if( input_panel->p_advanced_mrl_combo &&
1114 input_panel->p_advanced_mrl_combo->GetValue() )
1116 mrltemp += wxT(" ") +
1117 input_panel->p_advanced_mrl_combo->GetValue();
1123 if( caching_name.size() )
1125 if( caching_value->IsEnabled() )
1127 mrltemp += wxT(" :") + caching_name +
1128 wxString::Format( wxT("=%d"), i_caching );
1132 int i_value = config_GetInt( p_intf, caching_name.mb_str(wxConvUTF8) );
1133 caching_value->SetValue( i_value );
1137 mrl_combo->SetValue( mrltemp );
1140 /*****************************************************************************
1142 *****************************************************************************/
1143 void OpenDialog::OnOk( wxCommandEvent& WXUNUSED(event) )
1145 mrl = SeparateEntries( mrl_combo->GetValue() );
1146 mrl_combo->Append( mrl_combo->GetValue() );
1147 if( mrl_combo->GetCount() > 10 ) mrl_combo->Delete( 0 );
1148 mrl_combo->SetSelection( mrl_combo->GetCount() - 1 );
1150 if( i_method == OPEN_STREAM )
1152 if( IsModal() ) EndModal( wxID_OK );
1157 /* Update the playlist */
1158 playlist_t *p_playlist =
1159 (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
1161 if( p_playlist == NULL ) return;
1163 for( int i = 0; i < (int)mrl.GetCount(); i++ )
1165 vlc_bool_t b_start = !i && i_open_arg;
1166 input_item_t *p_input;
1169 psz_utf8 = wxFromLocale( mrl[i] );
1170 p_input = input_ItemNew( p_intf, psz_utf8, NULL );
1171 wxLocaleFree( psz_utf8 );
1173 /* Insert options */
1174 while( i + 1 < (int)mrl.GetCount() &&
1175 ((const char *)mrl[i + 1].mb_str(wxConvUTF8))[0] == ':' )
1177 psz_utf8 = wxFromLocale( mrl[i + 1] );
1178 input_ItemAddOption( p_input, psz_utf8 );
1179 wxLocaleFree( psz_utf8 );
1183 /* Get the options from the subtitles dialog */
1184 if( subsfile_checkbox->IsChecked() && subsfile_mrl.GetCount() )
1186 for( int j = 0; j < (int)subsfile_mrl.GetCount(); j++ )
1188 psz_utf8 = wxFromLocale( subsfile_mrl[j] );
1189 input_ItemAddOption( p_input, psz_utf8 );
1190 wxLocaleFree( psz_utf8 );
1194 /* Get the options from the stream output dialog */
1195 if( sout_checkbox->IsChecked() && sout_mrl.GetCount() )
1197 for( int j = 0; j < (int)sout_mrl.GetCount(); j++ )
1199 psz_utf8 = wxFromLocale( sout_mrl[j] );
1200 input_ItemAddOption( p_input, psz_utf8 );
1201 wxLocaleFree( psz_utf8 );
1207 playlist_AddInput( p_playlist, p_input,
1208 PLAYLIST_APPEND | PLAYLIST_GO,
1209 PLAYLIST_END, VLC_TRUE );
1213 playlist_AddInput( p_playlist, p_input,
1214 PLAYLIST_APPEND|PLAYLIST_PREPARSE,
1215 PLAYLIST_END, VLC_TRUE );
1219 vlc_object_release( p_playlist );
1223 if( IsModal() ) EndModal( wxID_OK );
1226 void OpenDialog::OnCancel( wxCommandEvent& WXUNUSED(event) )
1228 wxCloseEvent cevent;
1232 void OpenDialog::OnClose( wxCloseEvent& WXUNUSED(event) )
1236 if( IsModal() ) EndModal( wxID_CANCEL );
1239 void OpenDialog::OnPageChange( wxNotebookEvent& event )
1241 UpdateMRL( event.GetSelection() );
1244 void OpenDialog::OnMRLChange( wxCommandEvent& event )
1246 //mrl = SeparateEntries( event.GetString() );
1249 /*****************************************************************************
1250 * File panel event methods.
1251 *****************************************************************************/
1252 void OpenDialog::OnFilePanelChange( wxCommandEvent& WXUNUSED(event) )
1254 UpdateMRL( FILE_ACCESS );
1257 void OpenDialog::OnFileBrowse( wxCommandEvent& WXUNUSED(event) )
1259 if( file_dialog == NULL )
1260 file_dialog = new wxFileDialog( this, wxU(_("Open File")),
1261 wxT(""), wxT(""), wxT("*"), wxOPEN | wxMULTIPLE );
1263 file_dialog->SetWildcard(wxU(_("All Files (*.*)|*"
1264 "|Sound Files (*.mp3, *.ogg, etc.)|" EXTENSIONS_AUDIO
1265 "|Video Files (*.avi, *.mpg, etc.)|" EXTENSIONS_VIDEO
1266 "|Playlist Files (*.m3u, *.pls, etc.)|" EXTENSIONS_PLAYLIST
1267 "|Subtitle Files (*.srt, *.sub, etc.)|" EXTENSIONS_SUBTITLE)));
1269 if( file_dialog && file_dialog->ShowModal() == wxID_OK )
1271 wxArrayString paths;
1274 file_dialog->GetPaths( paths );
1276 for( size_t i = 0; i < paths.GetCount(); i++ )
1278 if( paths[i].Find( wxT(' ') ) >= 0 )
1279 path += wxT("\"") + paths[i] + wxT("\" ");
1281 path += paths[i] + wxT(" ");
1284 file_combo->SetValue( path );
1285 file_combo->Append( path );
1286 if( file_combo->GetCount() > 10 ) file_combo->Delete( 0 );
1287 UpdateMRL( FILE_ACCESS );
1291 void OpenDialog::OnSubFileBrowse( wxCommandEvent& WXUNUSED(event) )
1293 wxFileDialog dialog( this, wxU(_("Open subtitles file")),
1294 wxT(""), wxT(""), wxT("*"), wxOPEN );
1296 if( dialog.ShowModal() == wxID_OK )
1298 subfile_combo->SetValue( dialog.GetPath() );
1300 wxCommandEvent event; OnSubFileChange( event );
1303 void OpenDialog::OnSubFileChange( wxCommandEvent& WXUNUSED(event) )
1305 if( subsfile_mrl.GetCount() != 0 )
1307 subsfile_mrl.RemoveAt( 0 );
1308 subsfile_mrl.Insert( wxString(wxT("sub-file=")) + subfile_combo->GetValue() , 0 );
1312 subsfile_mrl.Add( wxString(wxT("sub-file=")) + subfile_combo->GetValue() );
1316 /*****************************************************************************
1317 * Disc panel event methods.
1318 *****************************************************************************/
1319 void OpenDialog::OnDiscPanelChangeSpin( wxSpinEvent& event )
1321 wxCommandEvent cevent;
1322 cevent.SetId(event.GetId());
1323 cevent.SetInt(event.GetPosition());
1324 OnDiscPanelChange(cevent);
1327 void OpenDialog::OnDiscPanelChange( wxCommandEvent& event )
1329 if( event.GetId() == DiscTitle_Event ) i_disc_title = event.GetInt();
1330 if( event.GetId() == DiscChapter_Event ) i_disc_chapter = event.GetInt();
1331 if( event.GetId() == DiscSub_Event ) i_disc_sub = event.GetInt();
1332 if( event.GetId() == DiscAudio_Event ) i_disc_audio = event.GetInt();
1334 UpdateMRL( DISC_ACCESS );
1337 void OpenDialog::OnDiscDeviceChange( wxCommandEvent& event )
1341 switch( disc_type->GetSelection() )
1344 psz_device = config_GetPsz( p_intf, "cd-audio" );
1348 psz_device = config_GetPsz( p_intf, "vcd" );
1352 psz_device = config_GetPsz( p_intf, "dvd" );
1356 if ( !psz_device ) psz_device = "";
1358 if( disc_device->GetValue().Cmp( wxL2U( psz_device ) ) )
1360 b_disc_device_changed = true;
1363 UpdateMRL( DISC_ACCESS );
1368 /* Return true if *psz_drive is a drive with a DVD in it. A more complete
1369 check would see if the media looks like a *playable* DVD. This should
1372 static bool IsDVD(const char *psz_drive)
1374 CdIo_t *p_cdio = cdio_open (psz_drive, DRIVER_UNKNOWN);
1377 discmode_t discmode = cdio_get_discmode(p_cdio);
1378 cdio_destroy(p_cdio);
1379 return cdio_is_discmode_dvd(discmode);
1385 /* Return a device that has a DVD in it. The caller needs to free
1386 the returned string.
1388 static char * ProbeDVD(const wxChar *device)
1391 char **ppsz_cd_drives;
1392 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1393 char *psz_device = (char *) tmp_buf;
1395 if( IsDVD(psz_device) )
1397 return strdup(psz_device);
1400 ppsz_cd_drives = cdio_get_devices(DRIVER_DEVICE);
1401 if( ppsz_cd_drives )
1404 for( c = ppsz_cd_drives; *c != NULL; c++ )
1408 char *psz_drive = strdup(*c);
1409 cdio_free_device_list(ppsz_cd_drives);
1410 return strdup(psz_drive);
1413 cdio_free_device_list(ppsz_cd_drives);
1419 static char * ProbeDevice(char **ppsz_search_devices, cdio_fs_anal_t mask,
1422 char **ppsz_devices;
1424 if( ppsz_search_devices && !ppsz_search_devices[0] )
1425 ppsz_search_devices = NULL;
1427 /* Start out trying the device that has been entered so far. */
1428 ppsz_devices = cdio_get_devices_with_cap(ppsz_search_devices, mask,
1431 if (ppsz_devices && *ppsz_devices)
1433 char *psz_device = strdup(*ppsz_devices);
1434 cdio_free_device_list(ppsz_devices);
1438 /* If there was no device specified on the first try, then give up
1439 now. Otherwise accept any CD-ROM in the class (e.g. VCD or DVD).
1441 if( !ppsz_search_devices ) return NULL;
1443 ppsz_devices = cdio_get_devices_with_cap(NULL, mask, true);
1445 if (ppsz_devices && *ppsz_devices)
1447 char *psz_device = strdup(*ppsz_devices);
1448 cdio_free_device_list(ppsz_devices);
1456 /* Return a device that has a CD-DA in it. The caller needs to free
1457 the returned string.
1459 static char * ProbeCDDA(const wxChar *device)
1462 char *ppsz_device[2];
1463 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1464 char *psz_device = (char *) tmp_buf;
1465 ppsz_device[0] = (device && *device) ? psz_device : NULL;
1466 ppsz_device[1] = NULL;
1467 return ProbeDevice(ppsz_device, CDIO_FS_AUDIO, false);
1471 /* Return a device that has a VCD in it. The caller needs to free
1472 the returned string.
1474 static char * ProbeVCD(const wxChar *device)
1476 char *ppsz_device[2];
1477 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1478 char *psz_device = (char *) tmp_buf;
1479 ppsz_device[0] = (device && *device) ? psz_device : NULL;
1480 ppsz_device[1] = NULL;
1481 return ProbeDevice(ppsz_device,
1482 (CDIO_FS_ANAL_SVCD|CDIO_FS_ANAL_CVD|CDIO_FS_ANAL_VIDEOCD
1483 |CDIO_FS_UNKNOWN), true);
1489 Probe (find anywhere) a CD-DA, VCD, or a DVD.
1490 First try the device name that may have been entered for the "disc type"
1491 selected. If that doesn't work we try any device for the disc type.
1492 If that doesn't work, try looking for CD-ROMs or DVD drives. the
1493 disc type, device name and paramter ranges are set to whatever we find.
1495 void OpenDialog::OnDiscProbe( wxCommandEvent& WXUNUSED(event) )
1497 wxCommandEvent dummy_event;
1498 char *psz_device = NULL;
1499 bool b_probed_DVD = false;
1500 bool b_probed_VCD = false;
1501 const int i_selection = disc_type->GetSelection();
1503 /* Reduce verbosity of cdio errors. */
1504 cdio_loglevel_default = CDIO_LOG_ERROR;
1507 switch( disc_type->GetSelection() )
1510 case SELECTION_DISC_TYPE_DVD_MENUS:
1511 case SELECTION_DISC_TYPE_DVD:
1512 /* If not a DVD then try for a VCD. If VCD fails it will
1514 if (!psz_device) psz_device = ProbeDVD(disc_device->GetValue());
1517 b_probed_DVD = true;
1518 disc_type->SetSelection(SELECTION_DISC_TYPE_VCD);
1519 OnDiscTypeChange( dummy_event );
1522 disc_device->SetValue( wxL2U(psz_device) );
1525 case SELECTION_DISC_TYPE_VCD: /* VCD probe of some sort */
1526 if(!psz_device) psz_device = ProbeVCD(disc_device->GetValue());
1530 #if LIBVCD_VERSION_NUM > 23
1531 vcdinfo_obj_t *p_vcdinfo;
1533 /* Set LID or entry range accurately if possible. */
1534 if( vcdinfo_open(&p_vcdinfo, &psz_device, DRIVER_DEVICE,
1535 NULL) == VCDINFO_OPEN_VCD)
1537 if (config_GetInt( p_intf, "vcdx-PBC" ))
1539 /* Set largest LID. */;
1540 disc_title->SetRange( 0, vcdinfo_get_num_LIDs(p_vcdinfo) );
1545 /* Set largest Entry */
1546 disc_title->SetRange( 0,
1547 vcdinfo_get_num_entries(p_vcdinfo)-1 );
1549 vcdinfo_close(p_vcdinfo);
1551 #endif /* LIBVCD_VERSION_NUM > 23 */
1552 disc_device->SetValue( wxL2U(psz_device) );
1554 CdIo_t *p_cdio = cdio_open (psz_device, DRIVER_UNKNOWN);
1555 disc_device->SetValue( wxL2U(psz_device) );
1557 /* Set track range accurately if possible. */
1560 track_t i_last_track = cdio_get_last_track_num(p_cdio);
1561 disc_title->SetRange( 0, i_last_track-1 );
1563 cdio_destroy(p_cdio);
1568 b_probed_VCD = true;
1570 /* Not a VCD. Try for a DVD unless we've been there before. */
1571 if( !b_probed_DVD && (psz_device = ProbeDVD(disc_device->GetValue())) )
1573 disc_type->SetSelection(SELECTION_DISC_TYPE_DVD_MENUS);
1574 OnDiscTypeChange( dummy_event );
1577 b_probed_DVD = true;
1579 /* Couldn't find a VCD or DVD. See if we can find a CD-DA. */
1580 psz_device = ProbeCDDA(disc_device->GetValue());
1583 disc_type->SetSelection(SELECTION_DISC_TYPE_CDDA);
1584 OnDiscTypeChange( dummy_event );
1588 /* Couldn't find a VCD, DVD or CD-DA. Null out the Device name and
1589 set to original selection.
1591 disc_device->SetValue( wxL2U("") );
1592 disc_type->SetSelection(i_selection);
1593 OnDiscTypeChange( dummy_event );
1596 case SELECTION_DISC_TYPE_CDDA:
1597 if(!psz_device) psz_device = ProbeCDDA(disc_device->GetValue());
1600 CdIo_t *p_cdio = cdio_open (psz_device, DRIVER_UNKNOWN);
1601 disc_device->SetValue( wxL2U(psz_device) );
1604 track_t i_last_track = cdio_get_last_track_num(p_cdio);
1605 disc_title->SetRange( 0, i_last_track );
1607 MediaInsertCDDA( p_intf, p_cdio, i_last_track );
1610 cdio_destroy(p_cdio);
1614 /* Not a CD-DA. Try for a DVD unless we've been there before. */
1615 if( !b_probed_DVD && (psz_device = ProbeDVD(disc_device->GetValue())) )
1617 disc_type->SetSelection(SELECTION_DISC_TYPE_DVD_MENUS);
1618 OnDiscTypeChange( dummy_event );
1622 /* Couldn't find a CD-DA or DVD. See if we can find a VCD, unless
1623 we've tried that before. */
1624 if (!b_probed_VCD) psz_device = ProbeVCD(disc_device->GetValue());
1627 disc_type->SetSelection(SELECTION_DISC_TYPE_VCD);
1628 OnDiscTypeChange( dummy_event );
1631 disc_device->SetValue( wxL2U("") );
1635 msg_Err( p_intf, "invalid Disc type selection (%d)",
1636 disc_type->GetSelection() );
1641 disc_probe->SetValue(FALSE);
1643 UpdateMRL( DISC_ACCESS );
1645 #endif /* HAVE_LIBCDIO */
1647 void OpenDialog::OnDiscTypeChange( wxCommandEvent& WXUNUSED(event) )
1649 char *psz_device = NULL;
1651 switch( disc_type->GetSelection() )
1654 case SELECTION_DISC_TYPE_DVD_MENUS:
1655 case SELECTION_DISC_TYPE_DVD:
1656 disc_sub->Enable(); disc_sub_label->Enable();
1657 disc_audio->Enable(); disc_audio_label->Enable();
1658 disc_chapter->Enable(); disc_chapter_label->Enable();
1659 disc_title_label->SetLabel ( wxU(_("Title")) );
1660 psz_device = config_GetPsz( p_intf, "dvd" );
1661 if( !b_disc_device_changed )
1663 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1664 else disc_device->SetValue( wxT("") );
1666 disc_title->SetRange( 0, 255 );
1667 disc_sub->SetRange( -1, 31 ); // up to 32 subtitles -1: no subtitle
1668 disc_audio->SetRange( 0, 7 ); // up to 8 audio channels
1669 disc_chapter->SetRange( 0, 255 );
1670 disc_title->SetToolTip( wxU(_("Title number.")) );
1671 // \bug [string] needs to be DVDs instead of DVD's
1672 disc_sub->SetToolTip( wxU(_(
1673 "DVD's can have up to 32 subtitles numbered 0..31. "
1674 "Note this is not the same thing as a subtitle name (e.g. 'en'). "
1675 "If a value -1 is used, no subtitle will be shown." )) );
1676 // \bug [string] needs to be DVDs instead of DVD's
1677 disc_audio->SetToolTip( wxU(_("Audio track number. "
1678 "DVD's can have up to 8 audio tracks numbered 0..7."
1682 case SELECTION_DISC_TYPE_VCD:
1683 disc_sub->Enable(); disc_sub_label->Enable();
1684 disc_audio->Enable(); disc_audio_label->Enable();
1685 disc_chapter->Disable(); disc_chapter_label->Disable();
1686 psz_device = config_GetPsz( p_intf, "vcd" );
1687 if( !b_disc_device_changed )
1689 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1690 else disc_device->SetValue( wxT("") );
1694 if (config_GetInt( p_intf, "vcdx-PBC" ))
1696 disc_title_label->SetLabel ( wxT("Playback LID") );
1697 disc_title->SetToolTip( wxU(_(
1698 "Playback control (PBC) usually starts with number 1." )) );
1702 disc_title_label->SetLabel ( wxT("Entry") );
1703 disc_title->SetToolTip( wxU(_(
1704 "The first entry (the beginning of the first MPEG track) is 0." )) );
1708 disc_title_label->SetLabel ( wxU(_("Track")) );
1709 disc_title->SetToolTip( wxU(_("Track number.")) );
1711 disc_title->SetRange( 0, 99 ); // only 100 tracks allowed on VCDs
1712 disc_sub->SetRange( -1, 3 ); // up to 4 subtitles -1 = no subtitle
1713 disc_audio->SetRange( 0, 1 ); // up to 2 audio tracks
1714 // \bug [string] needs to be SVCDs instead of SVCD's
1715 disc_sub->SetToolTip( wxU(_(
1716 "SVCD's can have up to 4 subtitles numbered 0..3. "
1717 "If a value -1 is used, no subtitle will be shown." )) );
1718 // \bug [string] needs to be SVCDs instead of SVCD's
1719 disc_audio->SetToolTip( wxU(_("Audio track number. "
1720 "VCD's can have up to 2 audio tracks numbered 0 or 1. "
1724 case SELECTION_DISC_TYPE_CDDA:
1725 disc_sub->Disable(); disc_sub_label->Disable();
1726 disc_chapter->Disable(); disc_chapter_label->Disable();
1727 disc_audio->Disable(); disc_audio_label->Disable();
1728 disc_title_label->SetLabel ( wxU(_("Track")) );
1730 disc_title->SetToolTip( wxU(_(
1731 "Audio CDs can have up to 100 tracks, the first track is usually 1. "
1732 "If 0 is given, then all tracks are played.")) );
1734 disc_title->SetToolTip( wxU(_(
1735 "Audio CDs can have up to 100 tracks, the first track is usually 1."
1738 psz_device = config_GetPsz( p_intf, "cd-audio" );
1739 if( !b_disc_device_changed )
1741 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1742 else disc_device->SetValue( wxT("") );
1745 /* There are at most 100 tracks in a CD-DA */
1746 disc_title->SetRange( 0, 100 );
1750 msg_Err( p_intf, "invalid Disc type selection (%d)",
1751 disc_type->GetSelection() );
1755 disc_title->SetValue( 0 ); i_disc_title = 0;
1756 disc_chapter->SetValue( 0 ); i_disc_chapter = 0;
1758 if( psz_device ) free( psz_device );
1760 UpdateMRL( DISC_ACCESS );
1763 /*****************************************************************************
1764 * Net panel event methods.
1765 *****************************************************************************/
1766 void OpenDialog::OnNetPanelChangeSpin( wxSpinEvent& event )
1768 wxCommandEvent cevent;
1769 cevent.SetId(event.GetId());
1770 cevent.SetInt(event.GetPosition());
1771 OnNetPanelChange(cevent);
1774 void OpenDialog::OnNetPanelChange( wxCommandEvent& event )
1776 if( event.GetId() >= NetPort1_Event && event.GetId() <= NetPort3_Event )
1778 i_net_ports[event.GetId() - NetPort1_Event] = event.GetInt();
1781 UpdateMRL( NET_ACCESS );
1784 void OpenDialog::OnNetTypeChange( wxCommandEvent& event )
1788 i_net_type = event.GetId() - NetRadio1_Event;
1792 net_radios[i]->SetValue( event.GetId() == (NetRadio1_Event+i) );
1793 net_subpanels[i]->Enable( event.GetId() == (NetRadio1_Event+i) );
1795 /* UDP Unicast or multicast -> timeshift */
1796 if( i_net_type == 0 || i_net_type == 1 )
1797 net_timeshift->Enable();
1799 net_timeshift->Disable();
1801 UpdateMRL( NET_ACCESS );
1804 /*****************************************************************************
1805 * Subtitles file event methods.
1806 *****************************************************************************/
1807 void OpenDialog::OnSubsFileEnable( wxCommandEvent& event )
1809 subsfile_button->Enable( event.GetInt() != 0 );
1810 subbrowse_button->Enable( event.GetInt() != 0 );
1811 subfile_combo->Enable( event.GetInt() != 0 );
1814 void OpenDialog::OnSubsFileSettings( wxCommandEvent& WXUNUSED(event) )
1816 /* Show/hide the open dialog */
1817 if( subsfile_dialog == NULL )
1818 subsfile_dialog = new SubsFileDialog( p_intf, this );
1820 if( subsfile_dialog && subsfile_dialog->ShowModal() == wxID_OK )
1822 subsfile_mrl.Empty();
1823 subsfile_mrl.Add( wxString(wxT("sub-file=")) + subfile_combo->GetValue() );
1824 if( subsfile_dialog->encoding_combo )
1826 subsfile_mrl.Add( wxString(wxT("subsdec-encoding=")) +
1827 subsfile_dialog->encoding_combo->GetValue() );
1829 if( subsfile_dialog->align_combo )
1831 subsfile_mrl.Add( wxString::Format(wxT("subsdec-align=%i"),
1832 (int)subsfile_dialog->align_combo->GetClientData(
1833 subsfile_dialog->align_combo->GetSelection()) ) );
1835 if( subsfile_dialog->size_combo )
1837 subsfile_mrl.Add( wxString::Format( wxT("freetype-rel-fontsize=%i"),
1838 (int)subsfile_dialog->size_combo->GetClientData(
1839 subsfile_dialog->size_combo->GetSelection()) ) );
1841 subsfile_mrl.Add( wxString::Format( wxT("sub-fps=%i"),
1842 subsfile_dialog->fps_spinctrl->GetValue() ) );
1843 subsfile_mrl.Add( wxString::Format( wxT("sub-delay=%i"),
1844 subsfile_dialog->delay_spinctrl->GetValue() ) );
1848 /*****************************************************************************
1849 * Stream output event methods.
1850 *****************************************************************************/
1851 void OpenDialog::OnSoutEnable( wxCommandEvent& event )
1853 sout_button->Enable( event.GetInt() != 0 );
1856 void OpenDialog::OnSoutSettings( wxCommandEvent& WXUNUSED(event) )
1858 /* Show/hide the open dialog */
1859 if( sout_dialog == NULL )
1860 sout_dialog = new SoutDialog( p_intf, this );
1862 if( sout_dialog && sout_dialog->ShowModal() == wxID_OK )
1864 sout_mrl = sout_dialog->GetOptions();
1868 /*****************************************************************************
1869 * Caching event methods.
1870 *****************************************************************************/
1871 void OpenDialog::OnCachingEnable( wxCommandEvent& event )
1873 caching_value->Enable( event.GetInt() != 0 );
1874 i_caching = caching_value->GetValue();
1878 void OpenDialog::OnCachingChangeSpin( wxSpinEvent& event )
1880 wxCommandEvent cevent;
1881 OnCachingChange(cevent);
1884 void OpenDialog::OnCachingChange( wxCommandEvent& event )
1886 i_caching = event.GetInt();
1890 /*****************************************************************************
1891 * Utility functions.
1892 *****************************************************************************/
1893 wxArrayString SeparateEntries( wxString entries )
1895 vlc_bool_t b_quotes_mode = VLC_FALSE;
1897 wxArrayString entries_array;
1900 wxStringTokenizer token( entries, wxT(" \t\r\n\""), wxTOKEN_RET_DELIMS );
1902 while( token.HasMoreTokens() )
1904 entry += token.GetNextToken();
1906 if( entry.IsEmpty() ) continue;
1908 if( !b_quotes_mode && entry.Last() == wxT('\"') )
1910 /* Enters quotes mode */
1912 b_quotes_mode = VLC_TRUE;
1914 else if( b_quotes_mode && entry.Last() == wxT('\"') )
1916 /* Finished the quotes mode */
1918 b_quotes_mode = VLC_FALSE;
1920 else if( !b_quotes_mode && entry.Last() != wxT('\"') )
1922 /* we found a non-quoted standalone string */
1923 if( token.HasMoreTokens() ||
1924 entry.Last() == wxT(' ') || entry.Last() == wxT('\t') ||
1925 entry.Last() == wxT('\r') || entry.Last() == wxT('\n') )
1927 if( !entry.IsEmpty() ) entries_array.Add( entry );
1934 if( !entry.IsEmpty() ) entries_array.Add( entry );
1936 return entries_array;