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>
58 # define wxRB_SINGLE 0
61 #define SELECTION_DISC_TYPE_DVD_MENUS 0
62 #define SELECTION_DISC_TYPE_DVD 1
63 #define SELECTION_DISC_TYPE_VCD 2
64 #define SELECTION_DISC_TYPE_CDDA 3
66 /*****************************************************************************
68 *****************************************************************************/
70 /* IDs for the controls and the menu commands */
73 Notebook_Event = wxID_HIGHEST,
92 NetRadio1_Event, NetRadio2_Event, NetRadio3_Event, NetRadio4_Event,
93 NetPort1_Event, NetPort2_Event, NetPort3_Event,
94 NetAddr1_Event, NetAddr2_Event, NetAddr3_Event, NetAddr4_Event,
95 NetForceIPv6_Event, NetTimeshift_Event,
98 SubsFileSettings_Event,
106 AdvancedOptions_Event
109 BEGIN_EVENT_TABLE(OpenDialog, wxDialog)
111 EVT_BUTTON(wxID_OK, OpenDialog::OnOk)
112 EVT_BUTTON(wxID_CANCEL, OpenDialog::OnCancel)
114 EVT_NOTEBOOK_PAGE_CHANGED(Notebook_Event, OpenDialog::OnPageChange)
116 EVT_TEXT(MRL_Event, OpenDialog::OnMRLChange)
118 /* Events generated by the file panel */
119 EVT_TEXT(FileName_Event, OpenDialog::OnFilePanelChange)
120 EVT_BUTTON(FileBrowse_Event, OpenDialog::OnFileBrowse)
121 EVT_TEXT(SubFileName_Event, OpenDialog::OnSubFileChange)
122 EVT_BUTTON(SubFileBrowse_Event, OpenDialog::OnSubFileBrowse)
124 /* Events generated by the disc panel */
125 EVT_RADIOBOX(DiscType_Event, OpenDialog::OnDiscTypeChange)
127 EVT_CHECKBOX(DiscProbe_Event, OpenDialog::OnDiscProbe)
129 EVT_TEXT(DiscDevice_Event, OpenDialog::OnDiscDeviceChange)
130 EVT_TEXT(DiscDevice_Event, OpenDialog::OnDiscPanelChange)
131 EVT_TEXT(DiscTitle_Event, OpenDialog::OnDiscPanelChange)
132 EVT_SPINCTRL(DiscTitle_Event, OpenDialog::OnDiscPanelChangeSpin)
133 EVT_TEXT(DiscChapter_Event, OpenDialog::OnDiscPanelChange)
134 EVT_SPINCTRL(DiscChapter_Event, OpenDialog::OnDiscPanelChangeSpin)
135 EVT_TEXT(DiscSub_Event, OpenDialog::OnDiscPanelChange)
136 EVT_TEXT(DiscAudio_Event, OpenDialog::OnDiscPanelChange)
137 EVT_SPINCTRL(DiscSub_Event, OpenDialog::OnDiscPanelChangeSpin)
139 /* Events generated by the net panel */
140 EVT_RADIOBUTTON(NetRadio1_Event, OpenDialog::OnNetTypeChange)
141 EVT_RADIOBUTTON(NetRadio2_Event, OpenDialog::OnNetTypeChange)
142 EVT_RADIOBUTTON(NetRadio3_Event, OpenDialog::OnNetTypeChange)
143 EVT_RADIOBUTTON(NetRadio4_Event, OpenDialog::OnNetTypeChange)
144 EVT_TEXT(NetPort1_Event, OpenDialog::OnNetPanelChange)
145 EVT_SPINCTRL(NetPort1_Event, OpenDialog::OnNetPanelChangeSpin)
146 EVT_TEXT(NetPort2_Event, OpenDialog::OnNetPanelChange)
147 EVT_SPINCTRL(NetPort2_Event, OpenDialog::OnNetPanelChangeSpin)
148 EVT_TEXT(NetPort3_Event, OpenDialog::OnNetPanelChange)
149 EVT_SPINCTRL(NetPort3_Event, OpenDialog::OnNetPanelChangeSpin)
150 EVT_TEXT(NetAddr2_Event, OpenDialog::OnNetPanelChange)
151 EVT_TEXT(NetAddr3_Event, OpenDialog::OnNetPanelChange)
152 EVT_TEXT(NetAddr4_Event, OpenDialog::OnNetPanelChange)
153 EVT_CHECKBOX(NetForceIPv6_Event, OpenDialog::OnNetPanelChange)
154 EVT_CHECKBOX(NetTimeshift_Event, OpenDialog::OnNetPanelChange)
156 /* Events generated by the subtitle file buttons */
157 EVT_CHECKBOX(SubsFileEnable_Event, OpenDialog::OnSubsFileEnable)
158 EVT_BUTTON(SubsFileSettings_Event, OpenDialog::OnSubsFileSettings)
160 /* Events generated by the stream output buttons */
161 EVT_CHECKBOX(SoutEnable_Event, OpenDialog::OnSoutEnable)
162 EVT_BUTTON(SoutSettings_Event, OpenDialog::OnSoutSettings)
164 /* Events generated by the caching button */
165 EVT_CHECKBOX(CachingEnable_Event, OpenDialog::OnCachingEnable)
166 EVT_TEXT(CachingChange_Event, OpenDialog::OnCachingChange)
167 EVT_SPINCTRL(CachingChange_Event, OpenDialog::OnCachingChangeSpin)
169 /* Hide the window when the user closes the window */
170 EVT_CLOSE(OpenDialog::OnClose)
175 /*****************************************************************************
177 *****************************************************************************/
178 WX_DEFINE_ARRAY(ConfigControl *, ArrayOfConfigControls);
180 class AutoBuiltPanel : public wxPanel
185 AutoBuiltPanel( wxWindow *, OpenDialog *, intf_thread_t *,
188 virtual ~AutoBuiltPanel() {}
190 void UpdateAdvancedMRL();
193 ArrayOfConfigControls config_array;
194 ArrayOfConfigControls advanced_config_array;
195 wxComboBox *p_advanced_mrl_combo;
198 intf_thread_t *p_intf;
199 OpenDialog *p_open_dialog;
201 void OnAdvanced( wxCommandEvent& event );
202 wxDialog *p_advanced_dialog;
204 DECLARE_EVENT_TABLE();
207 BEGIN_EVENT_TABLE(AutoBuiltPanel, wxPanel)
208 EVT_BUTTON(AdvancedOptions_Event, AutoBuiltPanel::OnAdvanced)
211 static void AutoBuildCallback( void *p_data )
213 ((OpenDialog *)p_data)->UpdateMRL();
216 static void AutoBuildAdvancedCallback( void *p_data )
218 ((AutoBuiltPanel *)p_data)->UpdateAdvancedMRL();
221 AutoBuiltPanel::AutoBuiltPanel( wxWindow *parent, OpenDialog *dialog,
222 intf_thread_t *_p_intf,
223 const module_t *p_module )
224 : wxPanel( parent, -1, wxDefaultPosition, wxDefaultSize ),
225 name( wxU(p_module->psz_object_name) ),
226 p_advanced_mrl_combo( NULL ),
227 p_intf( _p_intf ), p_open_dialog( dialog ), p_advanced_dialog( NULL )
229 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
230 module_config_t *p_item = p_module->p_config;
231 bool b_advanced = false;
235 if( !(p_item->i_type & CONFIG_HINT) && p_item->b_advanced )
238 if( p_item->i_type & CONFIG_HINT || p_item->b_advanced )
241 ConfigControl *control =
242 CreateConfigControl( VLC_OBJECT(p_intf), p_item, this );
244 config_array.Add( control );
246 /* Don't add items that were not recognized */
247 if( control == NULL ) continue;
249 control->SetUpdateCallback( AutoBuildCallback, (void *)dialog );
251 sizer->Add( control, 0, wxEXPAND | wxALL, 2 );
253 while( p_item->i_type != CONFIG_HINT_END && p_item++ );
258 new wxButton( this, AdvancedOptions_Event,
259 wxU(_("Advanced options...")) );
260 sizer->Add( button, 0, wxALL, 5 );
262 /* Build the advanced dialog */
264 new wxDialog( this, -1, ((wxString)wxU(_("Advanced options"))) +
265 wxT(" (") + wxU( p_module->psz_longname ) + wxT(")"),
266 wxDefaultPosition, wxDefaultSize,
267 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER );
269 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
271 /* Create MRL combobox */
272 wxBoxSizer *mrl_sizer_sizer = new wxBoxSizer( wxHORIZONTAL );
273 wxStaticBox *mrl_box =
274 new wxStaticBox( p_advanced_dialog, -1,
275 wxU(_("Advanced options")) );
276 wxStaticBoxSizer *mrl_sizer =
277 new wxStaticBoxSizer( mrl_box, wxHORIZONTAL );
278 wxStaticText *mrl_label =
279 new wxStaticText( p_advanced_dialog, -1, wxU(_("Options:")) );
280 p_advanced_mrl_combo =
281 new wxComboBox( p_advanced_dialog, MRL_Event, wxT(""),
282 wxDefaultPosition, wxDefaultSize );
283 mrl_sizer->Add( mrl_label, 0, wxALL | wxALIGN_CENTER, 5 );
284 mrl_sizer->Add( p_advanced_mrl_combo, 1, wxALL | wxALIGN_CENTER, 5 );
285 mrl_sizer_sizer->Add( mrl_sizer, 1, wxEXPAND | wxALL, 5 );
286 sizer->Add( mrl_sizer_sizer, 0, wxEXPAND | wxALL, 2 );
288 /* Add advanced options to panel */
289 module_config_t *p_item = p_module->p_config;
292 if( p_item->i_type & CONFIG_HINT || !p_item->b_advanced )
295 ConfigControl *control =
296 CreateConfigControl( VLC_OBJECT(p_intf), p_item,
299 advanced_config_array.Add( control );
301 /* Don't add items that were not recognized */
302 if( control == NULL ) continue;
304 control->SetUpdateCallback( AutoBuildAdvancedCallback,
307 sizer->Add( control, 0, wxEXPAND | wxALL, 2 );
309 while( p_item->i_type != CONFIG_HINT_END && p_item++ );
312 wxPanel *dummy_panel = new wxPanel( p_advanced_dialog, -1 );
313 sizer->Add( dummy_panel, 1 );
314 wxStaticLine *static_line =
315 new wxStaticLine( p_advanced_dialog, wxID_OK );
316 sizer->Add( static_line, 0, wxEXPAND | wxALL, 5 );
319 wxButton *ok_button =
320 new wxButton( p_advanced_dialog, wxID_OK );
321 ok_button->SetDefault();
322 wxButton *cancel_button =
323 new wxButton( p_advanced_dialog, wxID_CANCEL );
324 wxBoxSizer *button_sizer = new wxBoxSizer( wxHORIZONTAL );
325 button_sizer->Add( ok_button, 0, wxALL, 5 );
326 button_sizer->Add( cancel_button, 0, wxALL, 5 );
327 button_sizer->Layout();
328 sizer->Add( button_sizer, 0, wxALL, 0 );
330 sizer->SetMinSize( 400, -1 );
331 p_advanced_dialog->SetSizerAndFit( sizer );
334 this->SetSizerAndFit( sizer );
337 void AutoBuiltPanel::OnAdvanced( wxCommandEvent& event )
339 if( p_advanced_dialog->ShowModal() == wxID_OK )
342 p_open_dialog->UpdateMRL();
346 void AutoBuiltPanel::UpdateAdvancedMRL()
350 for( int i = 0; i < (int)advanced_config_array.GetCount(); i++ )
352 ConfigControl *control = advanced_config_array.Item(i);
354 mrltemp += (i ? wxT(" :") : wxT(":"));
356 if( control->GetType() == CONFIG_ITEM_BOOL &&
357 !control->GetIntValue() ) mrltemp += wxT("no-");
359 mrltemp += control->GetName();
361 switch( control->GetType() )
363 case CONFIG_ITEM_STRING:
364 case CONFIG_ITEM_FILE:
365 case CONFIG_ITEM_DIRECTORY:
366 case CONFIG_ITEM_MODULE:
367 mrltemp += wxT("=\"") + control->GetPszValue() + wxT("\"");
369 case CONFIG_ITEM_INTEGER:
371 wxString::Format( wxT("=%i"), control->GetIntValue() );
373 case CONFIG_ITEM_FLOAT:
375 wxString::Format(wxT("=%f"), control->GetFloatValue());
380 p_advanced_mrl_combo->SetValue( mrltemp );
383 /*****************************************************************************
385 *****************************************************************************/
386 OpenDialog::OpenDialog( intf_thread_t *_p_intf, wxWindow *_p_parent,
387 int i_access_method, int i_arg ):
388 wxDialog( _p_parent, -1, wxU(_("Open...")), wxDefaultPosition,
389 wxDefaultSize, wxDEFAULT_FRAME_STYLE )
391 OpenDialog( _p_intf, _p_parent, i_access_method, i_arg, OPEN_NORMAL );
394 OpenDialog::OpenDialog( intf_thread_t *_p_intf, wxWindow *_p_parent,
395 int i_access_method, int i_arg, int _i_method ):
396 wxDialog( _p_parent, -1, wxU(_("Open...")), wxDefaultPosition,
397 wxDefaultSize, wxDEFAULT_FRAME_STYLE )
399 /* Initializations */
400 i_method = _i_method;
402 p_parent = _p_parent;
403 SetIcon( *p_intf->p_sys->p_icon );
405 i_disc_type_selection = 0;
410 subsfile_dialog = NULL;
411 b_disc_device_changed = false;
413 /* Create a panel to put everything in */
414 wxPanel *panel = new wxPanel( this, -1 );
415 panel->SetAutoLayout( TRUE );
418 /* Advanced options */
419 wxStaticBox *adv_box = new wxStaticBox( panel, -1,
420 wxU(_("Advanced options")) );
421 wxStaticBoxSizer *adv_sizer = new wxStaticBoxSizer( adv_box,
425 wxFlexGridSizer *common_opt_sizer = new wxFlexGridSizer( 5, 1, 20 );
426 if( i_method == OPEN_NORMAL )
428 /* Create Stream Output checkox */
429 sout_checkbox = new wxCheckBox( panel, SoutEnable_Event,
430 wxU(_("Stream/Save")) );
431 sout_checkbox->SetToolTip( wxU(_("Use VLC as a server of streams")) );
432 common_opt_sizer->Add( sout_checkbox, 0,
433 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
435 sout_button = new wxButton( panel, SoutSettings_Event,
436 wxU(_("Settings...")) );
437 sout_button->Disable();
439 char *psz_sout = config_GetPsz( p_intf, "sout" );
440 if( psz_sout && *psz_sout )
442 sout_checkbox->SetValue(TRUE);
443 sout_button->Enable();
444 subsfile_mrl.Add( wxString(wxT("sout=")) + wxL2U(psz_sout) );
446 if( psz_sout ) free( psz_sout );
448 common_opt_sizer->Add( sout_button, 1, wxALIGN_LEFT |
449 wxALIGN_CENTER_VERTICAL );
451 common_opt_sizer->Add( new wxPanel( this, -1 ), 1,
452 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
455 /* Create caching options */
456 caching_checkbox = new wxCheckBox( panel, CachingEnable_Event,
458 caching_checkbox->SetToolTip( wxU(_("Change the default caching value "
459 "(in milliseconds)")) );
460 common_opt_sizer->Add( caching_checkbox, 0,
461 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
462 caching_value = new wxSpinCtrl( panel, CachingChange_Event );
463 caching_value->SetRange( 0, 1000000 );
464 caching_value->Disable();
465 common_opt_sizer->Add( caching_value, 0,
466 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
469 wxBoxSizer *mrl_sizer = new wxBoxSizer( wxHORIZONTAL );
470 wxStaticText *mrl_label = new wxStaticText( panel, -1,
471 wxU(_("Customize:")) );
472 mrl_combo = new wxComboBox( panel, MRL_Event, wxT(""),
473 wxDefaultPosition, wxDefaultSize );
474 //Point(20,25), wxSize(120, -1) );
475 mrl_combo->SetToolTip( wxU(_("You can use this field directly by typing "
476 "the full MRL you want to open.\n""Alternatively, the field will be "
477 "filled automatically when you use the controls above.")) );
479 mrl_sizer->Add( mrl_label, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
480 mrl_sizer->Add( mrl_combo, 1, wxALL | wxEXPAND | wxALIGN_CENTER_VERTICAL,
483 adv_sizer->Add( common_opt_sizer, 0, wxTOP | wxLEFT|wxRIGHT | wxEXPAND, 5 );
484 adv_sizer->Add( mrl_sizer, 0, wxBOTTOM | wxLEFT|wxRIGHT | wxEXPAND, 5 );
487 wxStaticLine *static_line = new wxStaticLine( panel, wxID_OK );
489 /* Create the buttons */
490 wxButton *ok_button = new wxButton( panel, wxID_OK );
491 ok_button->SetDefault();
492 wxButton *cancel_button = new wxButton( panel, wxID_CANCEL );
494 /* Create notebook */
495 notebook = new wxNotebook( panel, Notebook_Event );
497 #if (!wxCHECK_VERSION(2,5,2))
498 wxNotebookSizer *notebook_sizer = new wxNotebookSizer( notebook );
501 notebook->AddPage( FilePanel( notebook ), wxU(_("File")),
502 i_access_method == FILE_ACCESS );
503 notebook->AddPage( DiscPanel( notebook ), wxU(_("Disc")),
504 i_access_method == DISC_ACCESS );
505 notebook->AddPage( NetPanel( notebook ), wxU(_("Network")),
506 i_access_method == NET_ACCESS );
508 module_t *p_module = config_FindModule( VLC_OBJECT(p_intf), "v4l" );
511 AutoBuiltPanel *autopanel =
512 new AutoBuiltPanel( notebook, this, p_intf, p_module );
513 input_tab_array.Add( autopanel );
514 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
515 p_module->psz_shortname : p_module->psz_object_name ),
516 i_access_method == CAPTURE_ACCESS );
519 p_module = config_FindModule( VLC_OBJECT(p_intf), "pvr" );
522 AutoBuiltPanel *autopanel =
523 new AutoBuiltPanel( notebook, this, p_intf, p_module );
524 input_tab_array.Add( autopanel );
525 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
526 p_module->psz_shortname : p_module->psz_object_name ),
527 i_access_method == CAPTURE_ACCESS );
530 p_module = config_FindModule( VLC_OBJECT(p_intf), "dvb" );
533 AutoBuiltPanel *autopanel =
534 new AutoBuiltPanel( notebook, this, p_intf, p_module );
535 input_tab_array.Add( autopanel );
536 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
537 p_module->psz_shortname : p_module->psz_object_name ),
538 i_access_method == CAPTURE_ACCESS );
541 p_module = config_FindModule( VLC_OBJECT(p_intf), "dshow" );
544 AutoBuiltPanel *autopanel =
545 new AutoBuiltPanel( notebook, this, p_intf, p_module );
546 input_tab_array.Add( autopanel );
547 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
548 p_module->psz_shortname : p_module->psz_object_name ),
549 i_access_method == CAPTURE_ACCESS );
552 /* Update Disc panel */
553 wxCommandEvent dummy_event;
554 OnDiscTypeChange( dummy_event );
556 /* Update Net panel */
557 dummy_event.SetId( NetRadio1_Event );
558 OnNetTypeChange( dummy_event );
561 wxNotebookEvent event( wxEVT_NULL, 0, i_access_method );
562 OnPageChange( event );
564 /* Place everything in sizers */
565 wxBoxSizer *button_sizer = new wxBoxSizer( wxHORIZONTAL );
566 button_sizer->Add( ok_button, 0, wxALL, 5 );
567 button_sizer->Add( cancel_button, 0, wxALL, 5 );
568 button_sizer->Layout();
569 wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL );
570 wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
571 #if (!wxCHECK_VERSION(2,5,2))
572 panel_sizer->Add( notebook_sizer, 1, wxEXPAND | wxALL, 5 );
574 panel_sizer->Add( notebook, 1, wxEXPAND | wxALL, 5 );
576 panel_sizer->Add( adv_sizer, 0, wxEXPAND | wxALL, 5 );
577 panel_sizer->Add( static_line, 0, wxEXPAND | wxALL, 5 );
578 panel_sizer->Add( button_sizer, 0, wxALIGN_LEFT | wxALL, 5 );
579 panel_sizer->Layout();
580 panel->SetSizerAndFit( panel_sizer );
581 main_sizer->Add( panel, 1, wxGROW, 0 );
582 main_sizer->Layout();
583 SetSizerAndFit( main_sizer );
586 OpenDialog::~OpenDialog()
589 if( file_dialog ) delete file_dialog;
590 if( sout_dialog ) delete sout_dialog;
591 if( subsfile_dialog ) delete subsfile_dialog;
594 int OpenDialog::Show( int i_access_method, int i_arg )
596 notebook->SetSelection( i_access_method );
597 int i_ret = wxDialog::Show();
604 int OpenDialog::Show()
606 int i_ret = wxDialog::Show();
612 /*****************************************************************************
614 *****************************************************************************/
615 wxPanel *OpenDialog::FilePanel( wxWindow* parent )
617 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
620 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
622 /* Create browse file line */
623 wxBoxSizer *file_sizer = new wxBoxSizer( wxHORIZONTAL );
625 file_sizer->Add( new wxStaticText( panel, -1, wxU(_("Open:") ) ), 0,
626 wxALL | wxALIGN_CENTER_VERTICAL, 5 );
628 file_combo = new wxComboBox( panel, FileName_Event, wxT("") );
629 wxButton *browse_button = new wxButton( panel, FileBrowse_Event,
630 wxU(_("Browse...")) );
631 file_sizer->Add( file_combo, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
632 file_sizer->Add( browse_button, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
634 /* Create Subtitles File checkox - button */
635 wxFlexGridSizer *subtitles_sizer = new wxFlexGridSizer( 2, 1, 20 );
636 subsfile_checkbox = new wxCheckBox( panel, SubsFileEnable_Event,
637 wxU(_("Use a subtitles file")) );
638 subsfile_checkbox->SetToolTip( wxU(_("Use an external subtitles file.")) );
639 subtitles_sizer->Add( subsfile_checkbox, 0, wxALIGN_CENTER_VERTICAL |
641 subsfile_button = new wxButton( panel, SubsFileSettings_Event,
642 wxU(_("Advanced Settings...")) );
643 subsfile_button->Disable();
644 subtitles_sizer->Add( subsfile_button, 1, wxALIGN_CENTER_VERTICAL |
647 /* Create subtitles file line */
648 wxBoxSizer *subfile_sizer = new wxBoxSizer( wxHORIZONTAL );
650 char *psz_subsfile = config_GetPsz( p_intf, "sub-file" );
651 if( psz_subsfile && *psz_subsfile )
653 subsfile_checkbox->SetValue(TRUE);
654 subsfile_button->Enable();
655 subsfile_mrl.Add( wxString(wxT("sub-file=")) + wxL2U(psz_subsfile) );
657 if( !psz_subsfile ) psz_subsfile = strdup("");
658 subfile_sizer->Add( new wxStaticText( panel, -1, wxU(_("File:") ) ),
659 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
660 subfile_combo = new wxComboBox( panel, SubFileName_Event,
661 wxL2U( psz_subsfile ) );
662 if( psz_subsfile ) free( psz_subsfile );
663 subbrowse_button = new wxButton( panel, SubFileBrowse_Event,
664 wxU(_("Browse...")) );
665 subfile_sizer->Add( subfile_combo, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
666 subfile_sizer->Add( subbrowse_button, 0, wxALL |wxALIGN_CENTER_VERTICAL, 5 );
668 subfile_combo->Disable();
669 subbrowse_button->Disable();
671 psz_subsfile = config_GetPsz( p_intf, "sub-file" );
672 if( psz_subsfile && *psz_subsfile )
674 subfile_combo->Enable();
675 subbrowse_button->Enable();
678 sizer->Add( file_sizer, 0, wxEXPAND | wxALL, 5 );
679 sizer->Add( subtitles_sizer, 0, wxLEFT | wxRIGHT | wxTOP, 5 );
680 sizer->Add( subfile_sizer, 0, wxEXPAND | wxLEFT | wxRIGHT| wxBOTTOM, 5 );
681 panel->SetSizerAndFit( sizer );
685 wxPanel *OpenDialog::DiscPanel( wxWindow* parent )
687 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
690 wxBoxSizer *sizer_row = new wxBoxSizer( wxVERTICAL );
691 wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 3, 20 );
693 static const wxString disc_type_array[] =
695 wxU(_("DVD (menus)")),
701 disc_type = new wxRadioBox( panel, DiscType_Event, wxU(_("Disc type")),
702 wxDefaultPosition, wxDefaultSize,
703 WXSIZEOF(disc_type_array), disc_type_array,
704 WXSIZEOF(disc_type_array), wxRA_SPECIFY_COLS );
707 disc_probe = new wxCheckBox( panel, DiscProbe_Event,
708 wxU(_("Probe Disc(s)")) );
709 disc_probe->SetToolTip( wxU(_("Probe for a DVD, VCD or audio CD. "
710 "First try the Device name entered for the selected Disc type "
711 "(DVD, DVD Menu, VCD, audio CD). If that doesn't find media, try any device "
712 "for the Disc type. If that doesn't work, then try looking for CD-ROMs or "
713 "DVD drives. The Disc type, Device name, and some parameter ranges are set "
714 "based on media we find.")) );
717 sizer_row->Add( disc_type, i_disc_type_selection, wxEXPAND | wxALL, 5 );
719 sizer_row->Add( disc_probe, 0, wxEXPAND | wxALL );
722 wxStaticText *label = new wxStaticText( panel, -1, wxU(_("Device name")) );
723 disc_device = new wxTextCtrl( panel, DiscDevice_Event, wxT(""),
724 wxDefaultPosition, wxDefaultSize,
728 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] = ':';
746 if( strlen(psz_default_device) > 0 )
749 disc_device->SetValue( wxL2U(psz_default_device) );
753 sizer->Add( label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
754 sizer->Add( disc_device, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
756 disc_title_label = new wxStaticText( panel, -1, wxU(_("Title")) );
757 disc_title = new wxSpinCtrl( panel, DiscTitle_Event );
758 sizer->Add( disc_title_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
759 sizer->Add( disc_title, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
761 disc_chapter_label = new wxStaticText( panel, -1, wxU(_("Chapter")) );
762 disc_chapter = new wxSpinCtrl( panel, DiscChapter_Event );
763 sizer->Add( disc_chapter_label, 0,
764 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
765 sizer->Add( disc_chapter, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
767 disc_sub_label = new wxStaticText( panel, -1, wxU(_("Subtitles track")) );
768 disc_sub = new wxSpinCtrl( panel, DiscSub_Event );
769 sizer->Add( disc_sub_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
770 sizer->Add( disc_sub, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
771 disc_sub->SetRange( -1, 255 );
772 i_disc_sub = config_GetInt( p_intf, "sub-track" );
773 disc_sub->SetValue( i_disc_sub );
775 disc_audio_label = new wxStaticText( panel, -1, wxU(_("Audio track")) );
776 disc_audio = new wxSpinCtrl( panel, DiscAudio_Event );
777 sizer->Add( disc_audio_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
778 sizer->Add( disc_audio, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
779 disc_audio->SetRange( -1, 255 );
780 i_disc_audio = config_GetInt( p_intf, "audio-track" );
781 disc_audio->SetValue( i_disc_audio );
783 sizer_row->Add( sizer, 0, wxEXPAND | wxALL, 5 );
785 panel->SetSizerAndFit( sizer_row );
789 wxPanel *OpenDialog::NetPanel( wxWindow* parent )
792 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
795 wxBoxSizer *sizer_row = new wxBoxSizer( wxVERTICAL );
796 wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 4, 20 );
798 static const wxString net_type_array[] =
801 wxU(_("UDP/RTP Multicast")),
802 wxU(_("HTTP/HTTPS/FTP/MMS")),
808 net_radios[i] = new wxRadioButton( panel, NetRadio1_Event + i,
810 wxDefaultPosition, wxDefaultSize,
813 net_subpanels[i] = new wxPanel( panel, -1,
814 wxDefaultPosition, wxDefaultSize );
818 net_timeshift = new wxCheckBox( panel, NetTimeshift_Event,
819 wxU(_("Allow timeshifting")) );
822 wxFlexGridSizer *subpanel_sizer;
824 i_net_ports[0] = config_GetInt( p_intf, "server-port" );
825 subpanel_sizer = new wxFlexGridSizer( 3, 1, 20 );
826 label = new wxStaticText( net_subpanels[0], -1, wxU(_("Port")) );
827 net_ports[0] = new wxSpinCtrl( net_subpanels[0], NetPort1_Event,
828 wxString::Format(wxT("%d"), i_net_ports[0]),
829 wxDefaultPosition, wxDefaultSize,
831 0, 65535, i_net_ports[0] );
833 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
834 subpanel_sizer->Add( net_ports[0], 1,
835 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
836 net_ipv6 = new wxCheckBox( net_subpanels[0], NetForceIPv6_Event,
837 wxU(_("Force IPv6")));
838 subpanel_sizer->Add( net_ipv6, 0,
839 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
840 net_subpanels[0]->SetSizerAndFit( subpanel_sizer );
841 net_radios[0]->SetValue( TRUE );
843 /* UDP/RTP Multicast row */
844 subpanel_sizer = new wxFlexGridSizer( 4, 1, 20 );
845 label = new wxStaticText( net_subpanels[1], -1, wxU(_("Address")) );
846 net_addrs[1] = new wxTextCtrl( net_subpanels[1], NetAddr2_Event, wxT(""),
847 wxDefaultPosition, wxDefaultSize,
849 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
850 subpanel_sizer->Add( net_addrs[1], 1,
851 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
853 label = new wxStaticText( net_subpanels[1], -1, wxU(_("Port")) );
854 i_net_ports[1] = i_net_ports[0];
855 net_ports[1] = new wxSpinCtrl( net_subpanels[1], NetPort2_Event,
856 wxString::Format(wxT("%d"), i_net_ports[1]),
857 wxDefaultPosition, wxDefaultSize,
859 0, 65535, i_net_ports[1] );
861 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
862 subpanel_sizer->Add( net_ports[1], 1,
863 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
864 net_subpanels[1]->SetSizerAndFit( subpanel_sizer );
866 /* HTTP and RTSP rows */
869 subpanel_sizer = new wxFlexGridSizer( 2, 1, 20 );
870 label = new wxStaticText( net_subpanels[i], -1, wxU(_("URL")) );
871 net_addrs[i] = new wxTextCtrl( net_subpanels[i], NetAddr1_Event + i,
872 (i == 2) ? wxT("") : wxT("rtsp://"),
873 wxDefaultPosition, wxSize( 200, -1 ),
875 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
876 subpanel_sizer->Add( net_addrs[i], 1,
877 wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
878 net_subpanels[i]->SetSizerAndFit( subpanel_sizer );
881 /* Stuff everything into the main panel */
884 sizer->Add( net_radios[i], 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
886 sizer->Add( net_subpanels[i], 1, wxEXPAND | wxALIGN_LEFT |
887 wxALIGN_CENTER_VERTICAL | wxALL, 5 );
889 sizer->Add( net_timeshift, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
892 sizer_row->Add( sizer, 0, wxEXPAND | wxALL, 5 );
894 panel->SetSizerAndFit( sizer_row );
898 void OpenDialog::UpdateMRL()
900 UpdateMRL( i_current_access_method );
903 void OpenDialog::UpdateMRL( int i_access_method )
905 wxString mrltemp, caching_name;
907 i_current_access_method = i_access_method;
909 switch( i_access_method )
912 mrltemp = file_combo->GetValue();
913 caching_name = wxT("file-caching");
917 i_disc_type_selection = disc_type->GetSelection();
919 switch ( i_disc_type_selection )
921 case 0: /* DVD with menus */
922 case 1: /* DVD without menus */
923 disc_device->SetToolTip( wxU(_("Name of DVD device "
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(_("Name of CD-ROM device "
964 "to read Video CD from.")) );
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(_("Name of CD-ROM device "
988 "to read audio CD from." )) );
989 mrltemp = wxT("cdda://")
991 + disc_device->GetValue();
992 if( i_disc_title > 0 )
993 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
995 caching_name = wxT("cdda-caching");
999 msg_Err( p_intf, "invalid selection (%d)",
1000 disc_type->GetSelection() );
1006 switch( i_net_type )
1009 mrltemp = wxT("udp://@");
1010 if ( net_ipv6->GetValue() )
1012 mrltemp += wxT("[::]");
1014 if( i_net_ports[0] !=
1015 config_GetInt( p_intf, "server-port" ) )
1017 mrltemp += wxString::Format( wxT(":%d"), i_net_ports[0] );
1020 caching_name = wxT("udp-caching");
1024 mrltemp = wxT("udp://@");
1025 if ((net_addrs[1]->GetLineText(0).Find (':') != -1)
1026 && (net_addrs[1]->GetLineText(0)[0u] != '['))
1028 /* automatically adds '[' and ']' to IPv6 addresses */
1029 mrltemp += wxT("[") + net_addrs[1]->GetLineText(0)
1034 mrltemp += net_addrs[1]->GetLineText(0);
1036 if( i_net_ports[1] != config_GetInt( p_intf, "server-port" ) )
1038 mrltemp += wxString::Format( wxT(":%d"), i_net_ports[1] );
1041 caching_name = wxT("udp-caching");
1046 if( net_addrs[2]->GetLineText(0).Find(wxT("://")) == -1 )
1047 mrltemp = wxT("http://");
1049 mrltemp += net_addrs[2]->GetLineText(0);
1051 caching_name = wxT("http-caching");
1056 if( net_addrs[3]->GetLineText(0).Find(wxT("rtsp://")) != 0 )
1058 mrltemp = wxT("rtsp://");
1060 mrltemp += net_addrs[3]->GetLineText(0);
1062 caching_name = wxT("rtsp-caching");
1065 if( net_timeshift->IsEnabled() && net_timeshift->IsChecked() )
1066 mrltemp += wxT(" :access-filter=timeshift");
1071 int i_item = i_access_method - MAX_ACCESS;
1073 if( i_item < 0 || i_item >= (int)input_tab_array.GetCount() )
1076 AutoBuiltPanel *input_panel = input_tab_array.Item( i_item );
1078 mrltemp = input_panel->name + wxT("://");
1080 for( int i=0; i < (int)input_panel->config_array.GetCount(); i++ )
1082 ConfigControl *control = input_panel->config_array.Item(i);
1084 mrltemp += wxT(" :");
1086 if( control->GetType() == CONFIG_ITEM_BOOL &&
1087 !control->GetIntValue() ) mrltemp += wxT("no-");
1089 mrltemp += control->GetName();
1091 switch( control->GetType() )
1093 case CONFIG_ITEM_STRING:
1094 case CONFIG_ITEM_FILE:
1095 case CONFIG_ITEM_DIRECTORY:
1096 case CONFIG_ITEM_MODULE:
1097 mrltemp += wxT("=\"") + control->GetPszValue() + wxT("\"");
1099 case CONFIG_ITEM_INTEGER:
1101 wxString::Format( wxT("=%i"), control->GetIntValue() );
1103 case CONFIG_ITEM_FLOAT:
1105 wxString::Format(wxT("=%f"), control->GetFloatValue());
1110 if( input_panel->p_advanced_mrl_combo &&
1111 input_panel->p_advanced_mrl_combo->GetValue() )
1113 mrltemp += wxT(" ") +
1114 input_panel->p_advanced_mrl_combo->GetValue();
1120 if( caching_name.size() )
1122 if( caching_value->IsEnabled() )
1124 mrltemp += wxT(" :") + caching_name +
1125 wxString::Format( wxT("=%d"), i_caching );
1129 int i_value = config_GetInt( p_intf, caching_name.mb_str() );
1130 caching_value->SetValue( i_value );
1134 mrl_combo->SetValue( mrltemp );
1137 /*****************************************************************************
1139 *****************************************************************************/
1140 void OpenDialog::OnOk( wxCommandEvent& WXUNUSED(event) )
1142 mrl = SeparateEntries( mrl_combo->GetValue() );
1143 mrl_combo->Append( mrl_combo->GetValue() );
1144 if( mrl_combo->GetCount() > 10 ) mrl_combo->Delete( 0 );
1145 mrl_combo->SetSelection( mrl_combo->GetCount() - 1 );
1147 if( i_method == OPEN_STREAM )
1149 if( IsModal() ) EndModal( wxID_OK );
1154 /* Update the playlist */
1155 playlist_t *p_playlist =
1156 (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
1158 if( p_playlist == NULL ) return;
1160 for( int i = 0; i < (int)mrl.GetCount(); i++ )
1162 vlc_bool_t b_start = !i && i_open_arg;
1163 playlist_item_t *p_item;
1166 psz_utf8 = wxFromLocale( mrl[i] );
1167 p_item = playlist_ItemNew( p_intf, psz_utf8, psz_utf8 );
1168 wxLocaleFree( psz_utf8 );
1170 /* Insert options */
1171 while( i + 1 < (int)mrl.GetCount() &&
1172 ((const char *)mrl[i + 1].mb_str())[0] == ':' )
1174 psz_utf8 = wxFromLocale( mrl[i + 1] );
1175 playlist_ItemAddOption( p_item, psz_utf8 );
1176 wxLocaleFree( psz_utf8 );
1180 /* Get the options from the subtitles dialog */
1181 if( subsfile_checkbox->IsChecked() && subsfile_mrl.GetCount() )
1183 for( int j = 0; j < (int)subsfile_mrl.GetCount(); j++ )
1185 psz_utf8 = wxFromLocale( subsfile_mrl[j] );
1186 playlist_ItemAddOption( p_item, psz_utf8 );
1187 wxLocaleFree( psz_utf8 );
1191 /* Get the options from the stream output dialog */
1192 if( sout_checkbox->IsChecked() && sout_mrl.GetCount() )
1194 for( int j = 0; j < (int)sout_mrl.GetCount(); j++ )
1196 psz_utf8 = wxFromLocale( sout_mrl[j] );
1197 playlist_ItemAddOption( p_item, psz_utf8 );
1198 wxLocaleFree( psz_utf8 );
1205 playlist_AddItem( p_playlist, p_item,
1208 playlist_Control( p_playlist, PLAYLIST_ITEMPLAY, p_item );
1212 playlist_AddItem( p_playlist, p_item,
1213 PLAYLIST_APPEND|PLAYLIST_PREPARSE,
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 if( file_dialog && file_dialog->ShowModal() == wxID_OK )
1264 wxArrayString paths;
1267 file_dialog->GetPaths( paths );
1269 for( size_t i = 0; i < paths.GetCount(); i++ )
1271 if( paths[i].Find( wxT(' ') ) >= 0 )
1272 path += wxT("\"") + paths[i] + wxT("\" ");
1274 path += paths[i] + wxT(" ");
1277 file_combo->SetValue( path );
1278 file_combo->Append( path );
1279 if( file_combo->GetCount() > 10 ) file_combo->Delete( 0 );
1280 UpdateMRL( FILE_ACCESS );
1284 void OpenDialog::OnSubFileBrowse( wxCommandEvent& WXUNUSED(event) )
1286 wxFileDialog dialog( this, wxU(_("Open subtitles file")),
1287 wxT(""), wxT(""), wxT("*"), wxOPEN );
1289 if( dialog.ShowModal() == wxID_OK )
1291 subfile_combo->SetValue( dialog.GetPath() );
1293 wxCommandEvent event; OnSubFileChange( event );
1296 void OpenDialog::OnSubFileChange( wxCommandEvent& WXUNUSED(event) )
1298 if( subsfile_mrl.GetCount() != 0 )
1300 subsfile_mrl.RemoveAt( 0 );
1301 subsfile_mrl.Insert( wxString(wxT("sub-file=")) + subfile_combo->GetValue() , 0 );
1305 subsfile_mrl.Add( wxString(wxT("sub-file=")) + subfile_combo->GetValue() );
1309 /*****************************************************************************
1310 * Disc panel event methods.
1311 *****************************************************************************/
1312 void OpenDialog::OnDiscPanelChangeSpin( wxSpinEvent& event )
1314 wxCommandEvent cevent;
1315 cevent.SetId(event.GetId());
1316 cevent.SetInt(event.GetPosition());
1317 OnDiscPanelChange(cevent);
1320 void OpenDialog::OnDiscPanelChange( wxCommandEvent& event )
1322 if( event.GetId() == DiscTitle_Event ) i_disc_title = event.GetInt();
1323 if( event.GetId() == DiscChapter_Event ) i_disc_chapter = event.GetInt();
1324 if( event.GetId() == DiscSub_Event ) i_disc_sub = event.GetInt();
1325 if( event.GetId() == DiscAudio_Event ) i_disc_audio = event.GetInt();
1327 UpdateMRL( DISC_ACCESS );
1330 void OpenDialog::OnDiscDeviceChange( wxCommandEvent& event )
1334 switch( disc_type->GetSelection() )
1337 psz_device = config_GetPsz( p_intf, "cd-audio" );
1341 psz_device = config_GetPsz( p_intf, "vcd" );
1345 psz_device = config_GetPsz( p_intf, "dvd" );
1349 if ( !psz_device ) psz_device = "";
1351 if( disc_device->GetValue().Cmp( wxL2U( psz_device ) ) )
1353 b_disc_device_changed = true;
1356 UpdateMRL( DISC_ACCESS );
1361 /* Return true if *psz_drive is a drive with a DVD in it. A more complete
1362 check would see if the media looks like a *playable* DVD. This should
1365 static bool IsDVD(const char *psz_drive)
1367 CdIo_t *p_cdio = cdio_open (psz_drive, DRIVER_UNKNOWN);
1370 discmode_t discmode = cdio_get_discmode(p_cdio);
1371 cdio_destroy(p_cdio);
1372 return cdio_is_discmode_dvd(discmode);
1378 /* Return a device that has a DVD in it. The caller needs to free
1379 the returned string.
1381 static char * ProbeDVD(const wxChar *device)
1384 char **ppsz_cd_drives;
1385 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1386 char *psz_device = (char *) tmp_buf;
1388 if( IsDVD(psz_device) )
1390 return strdup(psz_device);
1393 ppsz_cd_drives = cdio_get_devices(DRIVER_DEVICE);
1394 if( ppsz_cd_drives )
1397 for( c = ppsz_cd_drives; *c != NULL; c++ )
1401 char *psz_drive = strdup(*c);
1402 cdio_free_device_list(ppsz_cd_drives);
1403 return strdup(psz_drive);
1406 cdio_free_device_list(ppsz_cd_drives);
1412 static char * ProbeDevice(char **ppsz_search_devices, cdio_fs_anal_t mask,
1415 char **ppsz_devices;
1417 if( ppsz_search_devices && !ppsz_search_devices[0] )
1418 ppsz_search_devices = NULL;
1420 /* Start out trying the device that has been entered so far. */
1421 ppsz_devices = cdio_get_devices_with_cap(ppsz_search_devices, mask,
1424 if (ppsz_devices && *ppsz_devices)
1426 char *psz_device = strdup(*ppsz_devices);
1427 cdio_free_device_list(ppsz_devices);
1431 /* If there was no device specified on the first try, then give up
1432 now. Otherwise accept any CD-ROM in the class (e.g. VCD or DVD).
1434 if( !ppsz_search_devices ) return NULL;
1436 ppsz_devices = cdio_get_devices_with_cap(NULL, mask, true);
1438 if (ppsz_devices && *ppsz_devices)
1440 char *psz_device = strdup(*ppsz_devices);
1441 cdio_free_device_list(ppsz_devices);
1449 /* Return a device that has a CD-DA in it. The caller needs to free
1450 the returned string.
1452 static char * ProbeCDDA(const wxChar *device)
1455 char *ppsz_device[2];
1456 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1457 char *psz_device = (char *) tmp_buf;
1458 ppsz_device[0] = (device && *device) ? psz_device : NULL;
1459 ppsz_device[1] = NULL;
1460 return ProbeDevice(ppsz_device, CDIO_FS_AUDIO, false);
1464 /* Return a device that has a VCD in it. The caller needs to free
1465 the returned string.
1467 static char * ProbeVCD(const wxChar *device)
1469 char *ppsz_device[2];
1470 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1471 char *psz_device = (char *) tmp_buf;
1472 ppsz_device[0] = (device && *device) ? psz_device : NULL;
1473 ppsz_device[1] = NULL;
1474 return ProbeDevice(ppsz_device,
1475 (CDIO_FS_ANAL_SVCD|CDIO_FS_ANAL_CVD|CDIO_FS_ANAL_VIDEOCD
1476 |CDIO_FS_UNKNOWN), true);
1482 Probe (find anywhere) a CD-DA, VCD, or a DVD.
1483 First try the device name that may have been entered for the "disc type"
1484 selected. If that doesn't work we try any device for the disc type.
1485 If that doesn't work, try looking for CD-ROMs or DVD drives. the
1486 disc type, device name and paramter ranges are set to whatever we find.
1488 void OpenDialog::OnDiscProbe( wxCommandEvent& WXUNUSED(event) )
1490 wxCommandEvent dummy_event;
1491 char *psz_device = NULL;
1492 bool b_probed_DVD = false;
1493 bool b_probed_VCD = false;
1494 const int i_selection = disc_type->GetSelection();
1496 /* Reduce verbosity of cdio errors. */
1497 cdio_loglevel_default = CDIO_LOG_ERROR;
1500 switch( disc_type->GetSelection() )
1503 case SELECTION_DISC_TYPE_DVD_MENUS:
1504 case SELECTION_DISC_TYPE_DVD:
1505 /* If not a DVD then try for a VCD. If VCD fails it will
1507 if (!psz_device) psz_device = ProbeDVD(disc_device->GetValue());
1510 b_probed_DVD = true;
1511 disc_type->SetSelection(SELECTION_DISC_TYPE_VCD);
1512 OnDiscTypeChange( dummy_event );
1515 disc_device->SetValue( wxL2U(psz_device) );
1518 case SELECTION_DISC_TYPE_VCD: /* VCD probe of some sort */
1519 if(!psz_device) psz_device = ProbeVCD(disc_device->GetValue());
1523 #if LIBVCD_VERSION_NUM > 23
1524 vcdinfo_obj_t *p_vcdinfo;
1526 /* Set LID or entry range accurately if possible. */
1527 if( vcdinfo_open(&p_vcdinfo, &psz_device, DRIVER_DEVICE,
1528 NULL) == VCDINFO_OPEN_VCD)
1530 if (config_GetInt( p_intf, "vcdx-PBC" ))
1532 /* Set largest LID. */;
1533 disc_title->SetRange( 0, vcdinfo_get_num_LIDs(p_vcdinfo) );
1538 /* Set largest Entry */
1539 disc_title->SetRange( 0,
1540 vcdinfo_get_num_entries(p_vcdinfo)-1 );
1542 vcdinfo_close(p_vcdinfo);
1544 #endif /* LIBVCD_VERSION_NUM > 23 */
1545 disc_device->SetValue( wxL2U(psz_device) );
1547 CdIo_t *p_cdio = cdio_open (psz_device, DRIVER_UNKNOWN);
1548 disc_device->SetValue( wxL2U(psz_device) );
1550 /* Set track range accurately if possible. */
1553 track_t i_last_track = cdio_get_last_track_num(p_cdio);
1554 disc_title->SetRange( 0, i_last_track-1 );
1556 cdio_destroy(p_cdio);
1561 b_probed_VCD = true;
1563 /* Not a VCD. Try for a DVD unless we've been there before. */
1564 if( !b_probed_DVD && (psz_device = ProbeDVD(disc_device->GetValue())) )
1566 disc_type->SetSelection(SELECTION_DISC_TYPE_DVD_MENUS);
1567 OnDiscTypeChange( dummy_event );
1570 b_probed_DVD = true;
1572 /* Couldn't find a VCD or DVD. See if we can find a CD-DA. */
1573 psz_device = ProbeCDDA(disc_device->GetValue());
1576 disc_type->SetSelection(SELECTION_DISC_TYPE_CDDA);
1577 OnDiscTypeChange( dummy_event );
1581 /* Couldn't find a VCD, DVD or CD-DA. Null out the Device name and
1582 set to original selection.
1584 disc_device->SetValue( wxL2U("") );
1585 disc_type->SetSelection(i_selection);
1586 OnDiscTypeChange( dummy_event );
1589 case SELECTION_DISC_TYPE_CDDA:
1590 if(!psz_device) psz_device = ProbeCDDA(disc_device->GetValue());
1593 CdIo_t *p_cdio = cdio_open (psz_device, DRIVER_UNKNOWN);
1594 disc_device->SetValue( wxL2U(psz_device) );
1597 track_t i_last_track = cdio_get_last_track_num(p_cdio);
1598 disc_title->SetRange( 0, i_last_track );
1600 MediaInsertCDDA( p_intf, p_cdio, i_last_track );
1603 cdio_destroy(p_cdio);
1607 /* Not a CD-DA. Try for a DVD unless we've been there before. */
1608 if( !b_probed_DVD && (psz_device = ProbeDVD(disc_device->GetValue())) )
1610 disc_type->SetSelection(SELECTION_DISC_TYPE_DVD_MENUS);
1611 OnDiscTypeChange( dummy_event );
1615 /* Couldn't find a CD-DA or DVD. See if we can find a VCD, unless
1616 we've tried that before. */
1617 if (!b_probed_VCD) psz_device = ProbeVCD(disc_device->GetValue());
1620 disc_type->SetSelection(SELECTION_DISC_TYPE_VCD);
1621 OnDiscTypeChange( dummy_event );
1624 disc_device->SetValue( wxL2U("") );
1628 msg_Err( p_intf, "invalid Disc type selection (%d)",
1629 disc_type->GetSelection() );
1634 disc_probe->SetValue(FALSE);
1636 UpdateMRL( DISC_ACCESS );
1638 #endif /* HAVE_LIBCDIO */
1640 void OpenDialog::OnDiscTypeChange( wxCommandEvent& WXUNUSED(event) )
1642 char *psz_device = NULL;
1644 switch( disc_type->GetSelection() )
1647 case SELECTION_DISC_TYPE_DVD_MENUS:
1648 case SELECTION_DISC_TYPE_DVD:
1649 disc_sub->Enable(); disc_sub_label->Enable();
1650 disc_audio->Enable(); disc_audio_label->Enable();
1651 disc_chapter->Enable(); disc_chapter_label->Enable();
1652 disc_title_label->SetLabel ( wxU(_("Title")) );
1653 psz_device = config_GetPsz( p_intf, "dvd" );
1654 if( !b_disc_device_changed )
1656 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1657 else disc_device->SetValue( wxT("") );
1659 disc_title->SetRange( 0, 255 );
1660 disc_sub->SetRange( -1, 31 ); // up to 32 subtitles -1: no subtitle
1661 disc_audio->SetRange( 0, 7 ); // up to 8 audio channels
1662 disc_chapter->SetRange( 0, 255 );
1663 disc_title->SetToolTip( wxU(_("Title number.")) );
1664 disc_sub->SetToolTip( wxU(_(
1665 "DVD's can have up to 32 subtitles numbered 0..31. "
1666 "Note this is not the same thing as a subtitle name e.g. 'en'. "
1667 "If a value -1 is used, no subtitle will be shown." )) );
1668 disc_audio->SetToolTip( wxU(_("Audio track number. "
1669 "DVD's can have up to 8 audio tracks numbered 0..7."
1673 case SELECTION_DISC_TYPE_VCD:
1674 disc_sub->Enable(); disc_sub_label->Enable();
1675 disc_audio->Enable(); disc_audio_label->Enable();
1676 disc_chapter->Disable(); disc_chapter_label->Disable();
1677 psz_device = config_GetPsz( p_intf, "vcd" );
1678 if( !b_disc_device_changed )
1680 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1681 else disc_device->SetValue( wxT("") );
1685 if (config_GetInt( p_intf, "vcdx-PBC" ))
1687 disc_title_label->SetLabel ( wxT("Playback LID") );
1688 disc_title->SetToolTip( wxU(_(
1689 "Playback control (PBC) usually starts with number 1." )) );
1693 disc_title_label->SetLabel ( wxT("Entry") );
1694 disc_title->SetToolTip( wxU(_(
1695 "The first entry (the beginning of the first MPEG track) is 0." )) );
1699 disc_title_label->SetLabel ( wxU(_("Track")) );
1700 disc_title->SetToolTip( wxU(_("Track number.")) );
1702 disc_title->SetRange( 0, 99 ); // only 100 tracks allowed on VCDs
1703 disc_sub->SetRange( -1, 3 ); // up to 4 subtitles -1 = no subtitle
1704 disc_audio->SetRange( 0, 1 ); // up to 2 audio tracks
1705 disc_sub->SetToolTip( wxU(_(
1706 "SVCD's can have up to 4 subtitles numbered 0..3. "
1707 "If a value -1 is used, no subtitle will be shown." )) );
1708 disc_audio->SetToolTip( wxU(_("Audio track number. "
1709 "VCD's can have up to 2 audio tracks numbered 0 or 1. "
1713 case SELECTION_DISC_TYPE_CDDA:
1714 disc_sub->Disable(); disc_sub_label->Disable();
1715 disc_chapter->Disable(); disc_chapter_label->Disable();
1716 disc_audio->Disable(); disc_audio_label->Disable();
1717 disc_title_label->SetLabel ( wxU(_("Track")) );
1719 disc_title->SetToolTip( wxU(_(
1720 "Audio CDs can have up to 100 tracks, the first track is usually 1. "
1721 "If 0 is given, then all tracks are played.")) );
1723 disc_title->SetToolTip( wxU(_(
1724 "Audio CDs can have up to 100 tracks, the first track is usually 1."
1727 psz_device = config_GetPsz( p_intf, "cd-audio" );
1728 if( !b_disc_device_changed )
1730 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1731 else disc_device->SetValue( wxT("") );
1734 /* There are at most 100 tracks in a CD-DA */
1735 disc_title->SetRange( 0, 100 );
1739 msg_Err( p_intf, "invalid Disc type selection (%d)",
1740 disc_type->GetSelection() );
1744 disc_title->SetValue( 0 ); i_disc_title = 0;
1745 disc_chapter->SetValue( 0 ); i_disc_chapter = 0;
1747 if( psz_device ) free( psz_device );
1749 UpdateMRL( DISC_ACCESS );
1752 /*****************************************************************************
1753 * Net panel event methods.
1754 *****************************************************************************/
1755 void OpenDialog::OnNetPanelChangeSpin( wxSpinEvent& event )
1757 wxCommandEvent cevent;
1758 cevent.SetId(event.GetId());
1759 cevent.SetInt(event.GetPosition());
1760 OnNetPanelChange(cevent);
1763 void OpenDialog::OnNetPanelChange( wxCommandEvent& event )
1765 if( event.GetId() >= NetPort1_Event && event.GetId() <= NetPort3_Event )
1767 i_net_ports[event.GetId() - NetPort1_Event] = event.GetInt();
1770 UpdateMRL( NET_ACCESS );
1773 void OpenDialog::OnNetTypeChange( wxCommandEvent& event )
1777 i_net_type = event.GetId() - NetRadio1_Event;
1781 net_radios[i]->SetValue( event.GetId() == (NetRadio1_Event+i) );
1782 net_subpanels[i]->Enable( event.GetId() == (NetRadio1_Event+i) );
1784 /* UDP Unicast or multicast -> timeshift */
1785 if( i_net_type == 0 || i_net_type == 1 )
1786 net_timeshift->Enable();
1788 net_timeshift->Disable();
1790 UpdateMRL( NET_ACCESS );
1793 /*****************************************************************************
1794 * Subtitles file event methods.
1795 *****************************************************************************/
1796 void OpenDialog::OnSubsFileEnable( wxCommandEvent& event )
1798 subsfile_button->Enable( event.GetInt() != 0 );
1799 subbrowse_button->Enable( event.GetInt() != 0 );
1800 subfile_combo->Enable( event.GetInt() != 0 );
1803 void OpenDialog::OnSubsFileSettings( wxCommandEvent& WXUNUSED(event) )
1805 /* Show/hide the open dialog */
1806 if( subsfile_dialog == NULL )
1807 subsfile_dialog = new SubsFileDialog( p_intf, this );
1809 if( subsfile_dialog && subsfile_dialog->ShowModal() == wxID_OK )
1811 subsfile_mrl.Empty();
1812 subsfile_mrl.Add( wxString(wxT("sub-file=")) + subfile_combo->GetValue() );
1813 if( subsfile_dialog->encoding_combo )
1815 subsfile_mrl.Add( wxString(wxT("subsdec-encoding=")) +
1816 subsfile_dialog->encoding_combo->GetValue() );
1818 if( subsfile_dialog->align_combo )
1820 subsfile_mrl.Add( wxString::Format(wxT("subsdec-align=%i"),
1821 (int)subsfile_dialog->align_combo->GetClientData(
1822 subsfile_dialog->align_combo->GetSelection()) ) );
1824 if( subsfile_dialog->size_combo )
1826 subsfile_mrl.Add( wxString::Format( wxT("freetype-rel-fontsize=%i"),
1827 (int)subsfile_dialog->size_combo->GetClientData(
1828 subsfile_dialog->size_combo->GetSelection()) ) );
1830 subsfile_mrl.Add( wxString::Format( wxT("sub-fps=%i"),
1831 subsfile_dialog->fps_spinctrl->GetValue() ) );
1832 subsfile_mrl.Add( wxString::Format( wxT("sub-delay=%i"),
1833 subsfile_dialog->delay_spinctrl->GetValue() ) );
1837 /*****************************************************************************
1838 * Stream output event methods.
1839 *****************************************************************************/
1840 void OpenDialog::OnSoutEnable( wxCommandEvent& event )
1842 sout_button->Enable( event.GetInt() != 0 );
1845 void OpenDialog::OnSoutSettings( wxCommandEvent& WXUNUSED(event) )
1847 /* Show/hide the open dialog */
1848 if( sout_dialog == NULL )
1849 sout_dialog = new SoutDialog( p_intf, this );
1851 if( sout_dialog && sout_dialog->ShowModal() == wxID_OK )
1853 sout_mrl = sout_dialog->GetOptions();
1857 /*****************************************************************************
1858 * Caching event methods.
1859 *****************************************************************************/
1860 void OpenDialog::OnCachingEnable( wxCommandEvent& event )
1862 caching_value->Enable( event.GetInt() != 0 );
1863 i_caching = caching_value->GetValue();
1867 void OpenDialog::OnCachingChangeSpin( wxSpinEvent& event )
1869 wxCommandEvent cevent;
1870 OnCachingChange(cevent);
1873 void OpenDialog::OnCachingChange( wxCommandEvent& event )
1875 i_caching = event.GetInt();
1879 /*****************************************************************************
1880 * Utility functions.
1881 *****************************************************************************/
1882 wxArrayString SeparateEntries( wxString entries )
1884 vlc_bool_t b_quotes_mode = VLC_FALSE;
1886 wxArrayString entries_array;
1889 wxStringTokenizer token( entries, wxT(" \t\r\n\""), wxTOKEN_RET_DELIMS );
1891 while( token.HasMoreTokens() )
1893 entry += token.GetNextToken();
1895 if( entry.IsEmpty() ) continue;
1897 if( !b_quotes_mode && entry.Last() == wxT('\"') )
1899 /* Enters quotes mode */
1901 b_quotes_mode = VLC_TRUE;
1903 else if( b_quotes_mode && entry.Last() == wxT('\"') )
1905 /* Finished the quotes mode */
1907 b_quotes_mode = VLC_FALSE;
1909 else if( !b_quotes_mode && entry.Last() != wxT('\"') )
1911 /* we found a non-quoted standalone string */
1912 if( token.HasMoreTokens() ||
1913 entry.Last() == wxT(' ') || entry.Last() == wxT('\t') ||
1914 entry.Last() == wxT('\r') || entry.Last() == wxT('\n') )
1916 if( !entry.IsEmpty() ) entries_array.Add( entry );
1923 if( !entry.IsEmpty() ) entries_array.Add( entry );
1925 return entries_array;