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-cruft
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, wxU(_("OK")) );
321 ok_button->SetDefault();
322 wxButton *cancel_button =
323 new wxButton( p_advanced_dialog, wxID_CANCEL, wxU(_("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, wxU(_("OK")) );
491 ok_button->SetDefault();
492 wxButton *cancel_button = new wxButton( panel, wxID_CANCEL,
495 /* Create notebook */
496 notebook = new wxNotebook( panel, Notebook_Event );
498 #if (!wxCHECK_VERSION(2,5,2))
499 wxNotebookSizer *notebook_sizer = new wxNotebookSizer( notebook );
502 notebook->AddPage( FilePanel( notebook ), wxU(_("File")),
503 i_access_method == FILE_ACCESS );
504 notebook->AddPage( DiscPanel( notebook ), wxU(_("Disc")),
505 i_access_method == DISC_ACCESS );
506 notebook->AddPage( NetPanel( notebook ), wxU(_("Network")),
507 i_access_method == NET_ACCESS );
509 module_t *p_module = config_FindModule( VLC_OBJECT(p_intf), "v4l" );
512 AutoBuiltPanel *autopanel =
513 new AutoBuiltPanel( notebook, this, p_intf, p_module );
514 input_tab_array.Add( autopanel );
515 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
516 p_module->psz_shortname : p_module->psz_object_name ),
517 i_access_method == CAPTURE_ACCESS );
520 p_module = config_FindModule( VLC_OBJECT(p_intf), "pvr" );
523 AutoBuiltPanel *autopanel =
524 new AutoBuiltPanel( notebook, this, p_intf, p_module );
525 input_tab_array.Add( autopanel );
526 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
527 p_module->psz_shortname : p_module->psz_object_name ),
528 i_access_method == CAPTURE_ACCESS );
531 p_module = config_FindModule( VLC_OBJECT(p_intf), "dvb" );
534 AutoBuiltPanel *autopanel =
535 new AutoBuiltPanel( notebook, this, p_intf, p_module );
536 input_tab_array.Add( autopanel );
537 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
538 p_module->psz_shortname : p_module->psz_object_name ),
539 i_access_method == CAPTURE_ACCESS );
542 p_module = config_FindModule( VLC_OBJECT(p_intf), "dshow" );
545 AutoBuiltPanel *autopanel =
546 new AutoBuiltPanel( notebook, this, p_intf, p_module );
547 input_tab_array.Add( autopanel );
548 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
549 p_module->psz_shortname : p_module->psz_object_name ),
550 i_access_method == CAPTURE_ACCESS );
553 /* Update Disc panel */
554 wxCommandEvent dummy_event;
555 OnDiscTypeChange( dummy_event );
557 /* Update Net panel */
558 dummy_event.SetId( NetRadio1_Event );
559 OnNetTypeChange( dummy_event );
562 wxNotebookEvent event( wxEVT_NULL, 0, i_access_method );
563 OnPageChange( event );
565 /* Place everything in sizers */
566 wxBoxSizer *button_sizer = new wxBoxSizer( wxHORIZONTAL );
567 button_sizer->Add( ok_button, 0, wxALL, 5 );
568 button_sizer->Add( cancel_button, 0, wxALL, 5 );
569 button_sizer->Layout();
570 wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL );
571 wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
572 #if (!wxCHECK_VERSION(2,5,2))
573 panel_sizer->Add( notebook_sizer, 1, wxEXPAND | wxALL, 5 );
575 panel_sizer->Add( notebook, 1, wxEXPAND | wxALL, 5 );
577 panel_sizer->Add( adv_sizer, 0, wxEXPAND | wxALL, 5 );
578 panel_sizer->Add( static_line, 0, wxEXPAND | wxALL, 5 );
579 panel_sizer->Add( button_sizer, 0, wxALIGN_LEFT | wxALL, 5 );
580 panel_sizer->Layout();
581 panel->SetSizerAndFit( panel_sizer );
582 main_sizer->Add( panel, 1, wxGROW, 0 );
583 main_sizer->Layout();
584 SetSizerAndFit( main_sizer );
587 OpenDialog::~OpenDialog()
590 if( file_dialog ) delete file_dialog;
591 if( sout_dialog ) delete sout_dialog;
592 if( subsfile_dialog ) delete subsfile_dialog;
595 int OpenDialog::Show( int i_access_method, int i_arg )
597 notebook->SetSelection( i_access_method );
598 int i_ret = wxDialog::Show();
605 int OpenDialog::Show()
607 int i_ret = wxDialog::Show();
613 /*****************************************************************************
615 *****************************************************************************/
616 wxPanel *OpenDialog::FilePanel( wxWindow* parent )
618 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
621 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
623 /* Create browse file line */
624 wxBoxSizer *file_sizer = new wxBoxSizer( wxHORIZONTAL );
626 file_sizer->Add( new wxStaticText( panel, -1, wxU(_("Open:") ) ), 0,
627 wxALL | wxALIGN_CENTER_VERTICAL, 5 );
629 file_combo = new wxComboBox( panel, FileName_Event, wxT("") );
630 wxButton *browse_button = new wxButton( panel, FileBrowse_Event,
631 wxU(_("Browse...")) );
632 file_sizer->Add( file_combo, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
633 file_sizer->Add( browse_button, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
635 /* Create Subtitles File checkox - button */
636 wxFlexGridSizer *subtitles_sizer = new wxFlexGridSizer( 2, 1, 20 );
637 subsfile_checkbox = new wxCheckBox( panel, SubsFileEnable_Event,
638 wxU(_("Use a subtitles file")) );
639 subsfile_checkbox->SetToolTip( wxU(_("Use an external subtitles file.")) );
640 subtitles_sizer->Add( subsfile_checkbox, 0, wxALIGN_CENTER_VERTICAL |
642 subsfile_button = new wxButton( panel, SubsFileSettings_Event,
643 wxU(_("Advanced Settings...")) );
644 subsfile_button->Disable();
645 subtitles_sizer->Add( subsfile_button, 1, wxALIGN_CENTER_VERTICAL |
648 /* Create subtitles file line */
649 wxBoxSizer *subfile_sizer = new wxBoxSizer( wxHORIZONTAL );
651 char *psz_subsfile = config_GetPsz( p_intf, "sub-file" );
652 if( psz_subsfile && *psz_subsfile )
654 subsfile_checkbox->SetValue(TRUE);
655 subsfile_button->Enable();
656 subsfile_mrl.Add( wxString(wxT("sub-file=")) + wxL2U(psz_subsfile) );
658 if( !psz_subsfile ) psz_subsfile = strdup("");
659 subfile_sizer->Add( new wxStaticText( panel, -1, wxU(_("File:") ) ),
660 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
661 subfile_combo = new wxComboBox( panel, SubFileName_Event,
662 wxL2U( psz_subsfile ) );
663 if( psz_subsfile ) free( psz_subsfile );
664 subbrowse_button = new wxButton( panel, SubFileBrowse_Event,
665 wxU(_("Browse...")) );
666 subfile_sizer->Add( subfile_combo, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
667 subfile_sizer->Add( subbrowse_button, 0, wxALL |wxALIGN_CENTER_VERTICAL, 5 );
669 subfile_combo->Disable();
670 subbrowse_button->Disable();
672 psz_subsfile = config_GetPsz( p_intf, "sub-file" );
673 if( psz_subsfile && *psz_subsfile )
675 subfile_combo->Enable();
676 subbrowse_button->Enable();
679 sizer->Add( file_sizer, 0, wxEXPAND | wxALL, 5 );
680 sizer->Add( subtitles_sizer, 0, wxLEFT | wxRIGHT | wxTOP, 5 );
681 sizer->Add( subfile_sizer, 0, wxEXPAND | wxLEFT | wxRIGHT| wxBOTTOM, 5 );
682 panel->SetSizerAndFit( sizer );
686 wxPanel *OpenDialog::DiscPanel( wxWindow* parent )
688 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
691 wxBoxSizer *sizer_row = new wxBoxSizer( wxVERTICAL );
692 wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 3, 20 );
694 static const wxString disc_type_array[] =
696 wxU(_("DVD (menus)")),
702 disc_type = new wxRadioBox( panel, DiscType_Event, wxU(_("Disc type")),
703 wxDefaultPosition, wxDefaultSize,
704 WXSIZEOF(disc_type_array), disc_type_array,
705 WXSIZEOF(disc_type_array), wxRA_SPECIFY_COLS );
708 disc_probe = new wxCheckBox( panel, DiscProbe_Event,
709 wxU(_("Probe Disc(s)")) );
710 disc_probe->SetToolTip( wxU(_("Probe for a DVD, VCD or audio CD. "
711 "First try the Device name entered for the selected Disc type "
712 "(DVD, DVD Menu, VCD, audio CD). If that doesn't find media, try any device "
713 "for the Disc type. If that doesn't work, then try looking for CD-ROMs or "
714 "DVD drives. The Disc type, Device name, and some parameter ranges are set "
715 "based on media we find.")) );
718 sizer_row->Add( disc_type, i_disc_type_selection, wxEXPAND | wxALL, 5 );
720 sizer_row->Add( disc_probe, 0, wxEXPAND | wxALL );
723 wxStaticText *label = new wxStaticText( panel, -1, wxU(_("Device name")) );
724 disc_device = new wxTextCtrl( panel, DiscDevice_Event, wxT(""),
725 wxDefaultPosition, wxDefaultSize,
729 char psz_default_device[3] = {0};
731 /* find the drive_name for the first cdrom drive,
732 * which is probably "D:" and put the drive_name into
733 * psz_default_device... */
734 for( char drive_letter = 'A'; drive_letter <= 'Z'; ++drive_letter )
736 char drive_name[3] = {drive_letter, ':', 0};
737 UINT type = GetDriveTypeA( drive_name );
738 if( type == DRIVE_CDROM )
740 psz_default_device[0] = drive_letter;
741 psz_default_device[1] = ':';
747 if( strlen(psz_default_device) > 0 )
750 disc_device->SetValue( wxL2U(psz_default_device) );
754 sizer->Add( label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
755 sizer->Add( disc_device, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
757 disc_title_label = new wxStaticText( panel, -1, wxU(_("Title")) );
758 disc_title = new wxSpinCtrl( panel, DiscTitle_Event );
759 sizer->Add( disc_title_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
760 sizer->Add( disc_title, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
762 disc_chapter_label = new wxStaticText( panel, -1, wxU(_("Chapter")) );
763 disc_chapter = new wxSpinCtrl( panel, DiscChapter_Event );
764 sizer->Add( disc_chapter_label, 0,
765 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
766 sizer->Add( disc_chapter, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
768 disc_sub_label = new wxStaticText( panel, -1, wxU(_("Subtitles track")) );
769 disc_sub = new wxSpinCtrl( panel, DiscSub_Event );
770 sizer->Add( disc_sub_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
771 sizer->Add( disc_sub, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
772 disc_sub->SetRange( -1, 255 );
773 i_disc_sub = config_GetInt( p_intf, "sub-track" );
774 disc_sub->SetValue( i_disc_sub );
776 disc_audio_label = new wxStaticText( panel, -1, wxU(_("Audio track")) );
777 disc_audio = new wxSpinCtrl( panel, DiscAudio_Event );
778 sizer->Add( disc_audio_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
779 sizer->Add( disc_audio, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
780 disc_audio->SetRange( -1, 255 );
781 i_disc_audio = config_GetInt( p_intf, "audio-track" );
782 disc_audio->SetValue( i_disc_audio );
784 sizer_row->Add( sizer, 0, wxEXPAND | wxALL, 5 );
786 panel->SetSizerAndFit( sizer_row );
790 wxPanel *OpenDialog::NetPanel( wxWindow* parent )
793 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
796 wxBoxSizer *sizer_row = new wxBoxSizer( wxVERTICAL );
797 wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 4, 20 );
799 static const wxString net_type_array[] =
802 wxU(_("UDP/RTP Multicast")),
803 wxU(_("HTTP/HTTPS/FTP/MMS")),
809 net_radios[i] = new wxRadioButton( panel, NetRadio1_Event + i,
811 wxDefaultPosition, wxDefaultSize,
814 net_subpanels[i] = new wxPanel( panel, -1,
815 wxDefaultPosition, wxDefaultSize );
819 net_timeshift = new wxCheckBox( panel, NetTimeshift_Event,
820 wxU(_("Allow timeshifting")) );
823 wxFlexGridSizer *subpanel_sizer;
825 i_net_ports[0] = config_GetInt( p_intf, "server-port" );
826 subpanel_sizer = new wxFlexGridSizer( 3, 1, 20 );
827 label = new wxStaticText( net_subpanels[0], -1, wxU(_("Port")) );
828 net_ports[0] = new wxSpinCtrl( net_subpanels[0], NetPort1_Event,
829 wxString::Format(wxT("%d"), i_net_ports[0]),
830 wxDefaultPosition, wxDefaultSize,
832 0, 65535, i_net_ports[0] );
834 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
835 subpanel_sizer->Add( net_ports[0], 1,
836 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
837 net_ipv6 = new wxCheckBox( net_subpanels[0], NetForceIPv6_Event,
838 wxU(_("Force IPv6")));
839 subpanel_sizer->Add( net_ipv6, 0,
840 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
841 net_subpanels[0]->SetSizerAndFit( subpanel_sizer );
842 net_radios[0]->SetValue( TRUE );
844 /* UDP/RTP Multicast row */
845 subpanel_sizer = new wxFlexGridSizer( 4, 1, 20 );
846 label = new wxStaticText( net_subpanels[1], -1, wxU(_("Address")) );
847 net_addrs[1] = new wxTextCtrl( net_subpanels[1], NetAddr2_Event, wxT(""),
848 wxDefaultPosition, wxDefaultSize,
850 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
851 subpanel_sizer->Add( net_addrs[1], 1,
852 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
854 label = new wxStaticText( net_subpanels[1], -1, wxU(_("Port")) );
855 i_net_ports[1] = i_net_ports[0];
856 net_ports[1] = new wxSpinCtrl( net_subpanels[1], NetPort2_Event,
857 wxString::Format(wxT("%d"), i_net_ports[1]),
858 wxDefaultPosition, wxDefaultSize,
860 0, 65535, i_net_ports[1] );
862 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
863 subpanel_sizer->Add( net_ports[1], 1,
864 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
865 net_subpanels[1]->SetSizerAndFit( subpanel_sizer );
867 /* HTTP and RTSP rows */
870 subpanel_sizer = new wxFlexGridSizer( 2, 1, 20 );
871 label = new wxStaticText( net_subpanels[i], -1, wxU(_("URL")) );
872 net_addrs[i] = new wxTextCtrl( net_subpanels[i], NetAddr1_Event + i,
873 (i == 2) ? wxT("") : wxT("rtsp://"),
874 wxDefaultPosition, wxSize( 200, -1 ),
876 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
877 subpanel_sizer->Add( net_addrs[i], 1,
878 wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
879 net_subpanels[i]->SetSizerAndFit( subpanel_sizer );
882 /* Stuff everything into the main panel */
885 sizer->Add( net_radios[i], 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
887 sizer->Add( net_subpanels[i], 1, wxEXPAND | wxALIGN_LEFT |
888 wxALIGN_CENTER_VERTICAL | wxALL, 5 );
890 sizer->Add( net_timeshift, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
893 sizer_row->Add( sizer, 0, wxEXPAND | wxALL, 5 );
895 panel->SetSizerAndFit( sizer_row );
899 void OpenDialog::UpdateMRL()
901 UpdateMRL( i_current_access_method );
904 void OpenDialog::UpdateMRL( int i_access_method )
906 wxString mrltemp, caching_name;
908 i_current_access_method = i_access_method;
910 switch( i_access_method )
913 mrltemp = file_combo->GetValue();
914 caching_name = wxT("file-caching");
918 i_disc_type_selection = disc_type->GetSelection();
920 switch ( i_disc_type_selection )
922 case 0: /* DVD with menus */
923 case 1: /* DVD without menus */
924 disc_device->SetToolTip( wxU(_("Name of DVD device "
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(_("Name of CD-ROM device "
965 "to read Video CD from.")) );
966 mrltemp = wxT("vcd://") + disc_device->GetValue();
967 if( i_disc_title > 0 )
968 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
971 if( i_disc_sub >= 0 )
972 mrltemp += wxString::Format( wxT(" :sub-track=%d"),
975 if( i_disc_audio >= 0 )
976 mrltemp += wxString::Format( wxT(" :audio-track=%d"),
978 caching_name = wxT("vcd-caching");
983 disc_device->SetToolTip( wxU(_("Name of CD-ROM device "
984 "to read audio CD from. If this field is left empty, we will scan "
985 "for a CD-ROM with an audio CD in it." )) );
986 mrltemp = wxT("cddax://")
988 disc_device->SetToolTip( wxU(_("Name of CD-ROM device "
989 "to read audio CD from." )) );
990 mrltemp = wxT("cdda://")
992 + disc_device->GetValue();
993 if( i_disc_title > 0 )
994 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
996 caching_name = wxT("cdda-caching");
1000 msg_Err( p_intf, "invalid selection (%d)",
1001 disc_type->GetSelection() );
1007 switch( i_net_type )
1010 mrltemp = wxT("udp://@");
1011 if ( net_ipv6->GetValue() )
1013 mrltemp += wxT("[::]");
1015 if( i_net_ports[0] !=
1016 config_GetInt( p_intf, "server-port" ) )
1018 mrltemp += wxString::Format( wxT(":%d"), i_net_ports[0] );
1021 caching_name = wxT("udp-caching");
1025 mrltemp = wxT("udp://@");
1026 if ((net_addrs[1]->GetLineText(0).Find (':') != -1)
1027 && (net_addrs[1]->GetLineText(0)[0u] != '['))
1029 /* automatically adds '[' and ']' to IPv6 addresses */
1030 mrltemp += wxT("[") + net_addrs[1]->GetLineText(0)
1035 mrltemp += net_addrs[1]->GetLineText(0);
1037 if( i_net_ports[1] != config_GetInt( p_intf, "server-port" ) )
1039 mrltemp += wxString::Format( wxT(":%d"), i_net_ports[1] );
1042 caching_name = wxT("udp-caching");
1047 if( net_addrs[2]->GetLineText(0).Find(wxT("://")) == -1 )
1048 mrltemp = wxT("http://");
1050 mrltemp += net_addrs[2]->GetLineText(0);
1052 caching_name = wxT("http-caching");
1057 if( net_addrs[3]->GetLineText(0).Find(wxT("rtsp://")) != 0 )
1059 mrltemp = wxT("rtsp://");
1061 mrltemp += net_addrs[3]->GetLineText(0);
1063 caching_name = wxT("rtsp-caching");
1066 if( net_timeshift->IsEnabled() && net_timeshift->IsChecked() )
1067 mrltemp += wxT(" :access-filter=timeshift");
1072 int i_item = i_access_method - MAX_ACCESS;
1074 if( i_item < 0 || i_item >= (int)input_tab_array.GetCount() )
1077 AutoBuiltPanel *input_panel = input_tab_array.Item( i_item );
1079 mrltemp = input_panel->name + wxT("://");
1081 for( int i=0; i < (int)input_panel->config_array.GetCount(); i++ )
1083 ConfigControl *control = input_panel->config_array.Item(i);
1085 mrltemp += wxT(" :");
1087 if( control->GetType() == CONFIG_ITEM_BOOL &&
1088 !control->GetIntValue() ) mrltemp += wxT("no-");
1090 mrltemp += control->GetName();
1092 switch( control->GetType() )
1094 case CONFIG_ITEM_STRING:
1095 case CONFIG_ITEM_FILE:
1096 case CONFIG_ITEM_DIRECTORY:
1097 case CONFIG_ITEM_MODULE:
1098 mrltemp += wxT("=\"") + control->GetPszValue() + wxT("\"");
1100 case CONFIG_ITEM_INTEGER:
1102 wxString::Format( wxT("=%i"), control->GetIntValue() );
1104 case CONFIG_ITEM_FLOAT:
1106 wxString::Format(wxT("=%f"), control->GetFloatValue());
1111 if( input_panel->p_advanced_mrl_combo &&
1112 input_panel->p_advanced_mrl_combo->GetValue() )
1114 mrltemp += wxT(" ") +
1115 input_panel->p_advanced_mrl_combo->GetValue();
1121 if( caching_name.size() )
1123 if( caching_value->IsEnabled() )
1125 mrltemp += wxT(" :") + caching_name +
1126 wxString::Format( wxT("=%d"), i_caching );
1130 int i_value = config_GetInt( p_intf, caching_name.mb_str() );
1131 caching_value->SetValue( i_value );
1135 mrl_combo->SetValue( mrltemp );
1138 /*****************************************************************************
1140 *****************************************************************************/
1141 void OpenDialog::OnOk( wxCommandEvent& WXUNUSED(event) )
1143 mrl = SeparateEntries( mrl_combo->GetValue() );
1144 mrl_combo->Append( mrl_combo->GetValue() );
1145 if( mrl_combo->GetCount() > 10 ) mrl_combo->Delete( 0 );
1146 mrl_combo->SetSelection( mrl_combo->GetCount() - 1 );
1148 if( i_method == OPEN_STREAM )
1150 if( IsModal() ) EndModal( wxID_OK );
1155 /* Update the playlist */
1156 playlist_t *p_playlist =
1157 (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
1159 if( p_playlist == NULL ) return;
1161 for( int i = 0; i < (int)mrl.GetCount(); i++ )
1163 vlc_bool_t b_start = !i && i_open_arg;
1164 playlist_item_t *p_item;
1167 psz_utf8 = wxFromLocale( mrl[i] );
1168 p_item = playlist_ItemNew( p_intf, psz_utf8, psz_utf8 );
1169 wxLocaleFree( psz_utf8 );
1171 /* Insert options */
1172 while( i + 1 < (int)mrl.GetCount() &&
1173 ((const char *)mrl[i + 1].mb_str())[0] == ':' )
1175 psz_utf8 = wxFromLocale( mrl[i + 1] );
1176 playlist_ItemAddOption( p_item, psz_utf8 );
1177 wxLocaleFree( psz_utf8 );
1181 /* Get the options from the subtitles dialog */
1182 if( subsfile_checkbox->IsChecked() && subsfile_mrl.GetCount() )
1184 for( int j = 0; j < (int)subsfile_mrl.GetCount(); j++ )
1186 psz_utf8 = wxFromLocale( subsfile_mrl[j] );
1187 playlist_ItemAddOption( p_item, psz_utf8 );
1188 wxLocaleFree( psz_utf8 );
1192 /* Get the options from the stream output dialog */
1193 if( sout_checkbox->IsChecked() && sout_mrl.GetCount() )
1195 for( int j = 0; j < (int)sout_mrl.GetCount(); j++ )
1197 psz_utf8 = wxFromLocale( sout_mrl[j] );
1198 playlist_ItemAddOption( p_item, psz_utf8 );
1199 wxLocaleFree( psz_utf8 );
1203 playlist_AddItem( p_playlist, p_item, PLAYLIST_APPEND|PLAYLIST_PREPARSE,
1208 playlist_Control( p_playlist, PLAYLIST_ITEMPLAY, p_item );
1212 vlc_object_release( p_playlist );
1216 if( IsModal() ) EndModal( wxID_OK );
1219 void OpenDialog::OnCancel( wxCommandEvent& WXUNUSED(event) )
1221 wxCloseEvent cevent;
1225 void OpenDialog::OnClose( wxCloseEvent& WXUNUSED(event) )
1229 if( IsModal() ) EndModal( wxID_CANCEL );
1232 void OpenDialog::OnPageChange( wxNotebookEvent& event )
1234 UpdateMRL( event.GetSelection() );
1237 void OpenDialog::OnMRLChange( wxCommandEvent& event )
1239 //mrl = SeparateEntries( event.GetString() );
1242 /*****************************************************************************
1243 * File panel event methods.
1244 *****************************************************************************/
1245 void OpenDialog::OnFilePanelChange( wxCommandEvent& WXUNUSED(event) )
1247 UpdateMRL( FILE_ACCESS );
1250 void OpenDialog::OnFileBrowse( wxCommandEvent& WXUNUSED(event) )
1252 if( file_dialog == NULL )
1253 file_dialog = new wxFileDialog( this, wxU(_("Open File")),
1254 wxT(""), wxT(""), wxT("*"), wxOPEN | wxMULTIPLE );
1256 if( file_dialog && file_dialog->ShowModal() == wxID_OK )
1258 wxArrayString paths;
1261 file_dialog->GetPaths( paths );
1263 for( size_t i = 0; i < paths.GetCount(); i++ )
1265 if( paths[i].Find( wxT(' ') ) >= 0 )
1266 path += wxT("\"") + paths[i] + wxT("\" ");
1268 path += paths[i] + wxT(" ");
1271 file_combo->SetValue( path );
1272 file_combo->Append( path );
1273 if( file_combo->GetCount() > 10 ) file_combo->Delete( 0 );
1274 UpdateMRL( FILE_ACCESS );
1278 void OpenDialog::OnSubFileBrowse( wxCommandEvent& WXUNUSED(event) )
1280 wxFileDialog dialog( this, wxU(_("Open subtitles file")),
1281 wxT(""), wxT(""), wxT("*"), wxOPEN );
1283 if( dialog.ShowModal() == wxID_OK )
1285 subfile_combo->SetValue( dialog.GetPath() );
1287 wxCommandEvent event; OnSubFileChange( event );
1290 void OpenDialog::OnSubFileChange( wxCommandEvent& WXUNUSED(event) )
1292 if( subsfile_mrl.GetCount() != 0 )
1294 subsfile_mrl.RemoveAt( 0 );
1295 subsfile_mrl.Insert( wxString(wxT("sub-file=")) + subfile_combo->GetValue() , 0 );
1299 subsfile_mrl.Add( wxString(wxT("sub-file=")) + subfile_combo->GetValue() );
1303 /*****************************************************************************
1304 * Disc panel event methods.
1305 *****************************************************************************/
1306 void OpenDialog::OnDiscPanelChangeSpin( wxSpinEvent& event )
1308 wxCommandEvent cevent;
1309 cevent.SetId(event.GetId());
1310 cevent.SetInt(event.GetPosition());
1311 OnDiscPanelChange(cevent);
1314 void OpenDialog::OnDiscPanelChange( wxCommandEvent& event )
1316 if( event.GetId() == DiscTitle_Event ) i_disc_title = event.GetInt();
1317 if( event.GetId() == DiscChapter_Event ) i_disc_chapter = event.GetInt();
1318 if( event.GetId() == DiscSub_Event ) i_disc_sub = event.GetInt();
1319 if( event.GetId() == DiscAudio_Event ) i_disc_audio = event.GetInt();
1321 UpdateMRL( DISC_ACCESS );
1324 void OpenDialog::OnDiscDeviceChange( wxCommandEvent& event )
1328 switch( disc_type->GetSelection() )
1331 psz_device = config_GetPsz( p_intf, "cd-audio" );
1335 psz_device = config_GetPsz( p_intf, "vcd" );
1339 psz_device = config_GetPsz( p_intf, "dvd" );
1343 if ( !psz_device ) psz_device = "";
1345 if( disc_device->GetValue().Cmp( wxL2U( psz_device ) ) )
1347 b_disc_device_changed = true;
1350 UpdateMRL( DISC_ACCESS );
1355 /* Return true if *psz_drive is a drive with a DVD in it. A more complete
1356 check would see if the media looks like a *playable* DVD. This should
1359 static bool IsDVD(const char *psz_drive)
1361 CdIo_t *p_cdio = cdio_open (psz_drive, DRIVER_UNKNOWN);
1364 discmode_t discmode = cdio_get_discmode(p_cdio);
1365 cdio_destroy(p_cdio);
1366 return cdio_is_discmode_dvd(discmode);
1372 /* Return a device that has a DVD in it. The caller needs to free
1373 the returned string.
1375 static char * ProbeDVD(const wxChar *device)
1378 char **ppsz_cd_drives;
1379 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1380 char *psz_device = (char *) tmp_buf;
1382 if( IsDVD(psz_device) )
1384 return strdup(psz_device);
1387 ppsz_cd_drives = cdio_get_devices(DRIVER_DEVICE);
1388 if( ppsz_cd_drives )
1391 for( c = ppsz_cd_drives; *c != NULL; c++ )
1395 char *psz_drive = strdup(*c);
1396 cdio_free_device_list(ppsz_cd_drives);
1397 return strdup(psz_drive);
1400 cdio_free_device_list(ppsz_cd_drives);
1406 static char * ProbeDevice(char **ppsz_search_devices, cdio_fs_anal_t mask,
1409 char **ppsz_devices;
1411 if( ppsz_search_devices && !ppsz_search_devices[0] )
1412 ppsz_search_devices = NULL;
1414 /* Start out trying the device that has been entered so far. */
1415 ppsz_devices = cdio_get_devices_with_cap(ppsz_search_devices, mask,
1418 if (ppsz_devices && *ppsz_devices)
1420 char *psz_device = strdup(*ppsz_devices);
1421 cdio_free_device_list(ppsz_devices);
1425 /* If there was no device specified on the first try, then give up
1426 now. Otherwise accept any CD-ROM in the class (e.g. VCD or DVD).
1428 if( !ppsz_search_devices ) return NULL;
1430 ppsz_devices = cdio_get_devices_with_cap(NULL, mask, true);
1432 if (ppsz_devices && *ppsz_devices)
1434 char *psz_device = strdup(*ppsz_devices);
1435 cdio_free_device_list(ppsz_devices);
1443 /* Return a device that has a CD-DA in it. The caller needs to free
1444 the returned string.
1446 static char * ProbeCDDA(const wxChar *device)
1449 char *ppsz_device[2];
1450 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1451 char *psz_device = (char *) tmp_buf;
1452 ppsz_device[0] = (device && *device) ? psz_device : NULL;
1453 ppsz_device[1] = NULL;
1454 return ProbeDevice(ppsz_device, CDIO_FS_AUDIO, false);
1458 /* Return a device that has a VCD in it. The caller needs to free
1459 the returned string.
1461 static char * ProbeVCD(const wxChar *device)
1463 char *ppsz_device[2];
1464 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1465 char *psz_device = (char *) tmp_buf;
1466 ppsz_device[0] = (device && *device) ? psz_device : NULL;
1467 ppsz_device[1] = NULL;
1468 return ProbeDevice(ppsz_device,
1469 (CDIO_FS_ANAL_SVCD|CDIO_FS_ANAL_CVD|CDIO_FS_ANAL_VIDEOCD
1470 |CDIO_FS_UNKNOWN), true);
1476 Probe (find anywhere) a CD-DA, VCD, or a DVD.
1477 First try the device name that may have been entered for the "disc type"
1478 selected. If that doesn't work we try any device for the disc type.
1479 If that doesn't work, try looking for CD-ROMs or DVD drives. the
1480 disc type, device name and paramter ranges are set to whatever we find.
1482 void OpenDialog::OnDiscProbe( wxCommandEvent& WXUNUSED(event) )
1484 wxCommandEvent dummy_event;
1485 char *psz_device = NULL;
1486 bool b_probed_DVD = false;
1487 bool b_probed_VCD = false;
1488 const int i_selection = disc_type->GetSelection();
1490 /* Reduce verbosity of cdio errors. */
1491 cdio_loglevel_default = CDIO_LOG_ERROR;
1494 switch( disc_type->GetSelection() )
1497 case SELECTION_DISC_TYPE_DVD_MENUS:
1498 case SELECTION_DISC_TYPE_DVD:
1499 /* If not a DVD then try for a VCD. If VCD fails it will
1501 if (!psz_device) psz_device = ProbeDVD(disc_device->GetValue());
1504 b_probed_DVD = true;
1505 disc_type->SetSelection(SELECTION_DISC_TYPE_VCD);
1506 OnDiscTypeChange( dummy_event );
1509 disc_device->SetValue( wxL2U(psz_device) );
1512 case SELECTION_DISC_TYPE_VCD: /* VCD probe of some sort */
1513 if(!psz_device) psz_device = ProbeVCD(disc_device->GetValue());
1517 #if LIBVCD_VERSION_NUM > 23
1518 vcdinfo_obj_t *p_vcdinfo;
1520 /* Set LID or entry range accurately if possible. */
1521 if( vcdinfo_open(&p_vcdinfo, &psz_device, DRIVER_DEVICE,
1522 NULL) == VCDINFO_OPEN_VCD)
1524 if (config_GetInt( p_intf, "vcdx-PBC" ))
1526 /* Set largest LID. */;
1527 disc_title->SetRange( 0, vcdinfo_get_num_LIDs(p_vcdinfo) );
1532 /* Set largest Entry */
1533 disc_title->SetRange( 0,
1534 vcdinfo_get_num_entries(p_vcdinfo)-1 );
1536 vcdinfo_close(p_vcdinfo);
1538 #endif /* LIBVCD_VERSION_NUM > 23 */
1539 disc_device->SetValue( wxL2U(psz_device) );
1541 CdIo_t *p_cdio = cdio_open (psz_device, DRIVER_UNKNOWN);
1542 disc_device->SetValue( wxL2U(psz_device) );
1544 /* Set track range accurately if possible. */
1547 track_t i_last_track = cdio_get_last_track_num(p_cdio);
1548 disc_title->SetRange( 0, i_last_track-1 );
1550 cdio_destroy(p_cdio);
1555 b_probed_VCD = true;
1557 /* Not a VCD. Try for a DVD unless we've been there before. */
1558 if( !b_probed_DVD && (psz_device = ProbeDVD(disc_device->GetValue())) )
1560 disc_type->SetSelection(SELECTION_DISC_TYPE_DVD_MENUS);
1561 OnDiscTypeChange( dummy_event );
1564 b_probed_DVD = true;
1566 /* Couldn't find a VCD or DVD. See if we can find a CD-DA. */
1567 psz_device = ProbeCDDA(disc_device->GetValue());
1570 disc_type->SetSelection(SELECTION_DISC_TYPE_CDDA);
1571 OnDiscTypeChange( dummy_event );
1575 /* Couldn't find a VCD, DVD or CD-DA. Null out the Device name and
1576 set to original selection.
1578 disc_device->SetValue( wxL2U("") );
1579 disc_type->SetSelection(i_selection);
1580 OnDiscTypeChange( dummy_event );
1583 case SELECTION_DISC_TYPE_CDDA:
1584 if(!psz_device) psz_device = ProbeCDDA(disc_device->GetValue());
1587 CdIo_t *p_cdio = cdio_open (psz_device, DRIVER_UNKNOWN);
1588 disc_device->SetValue( wxL2U(psz_device) );
1591 track_t i_last_track = cdio_get_last_track_num(p_cdio);
1592 disc_title->SetRange( 0, i_last_track );
1594 MediaInsertCDDA( p_intf, p_cdio, i_last_track );
1597 cdio_destroy(p_cdio);
1601 /* Not a CD-DA. Try for a DVD unless we've been there before. */
1602 if( !b_probed_DVD && (psz_device = ProbeDVD(disc_device->GetValue())) )
1604 disc_type->SetSelection(SELECTION_DISC_TYPE_DVD_MENUS);
1605 OnDiscTypeChange( dummy_event );
1609 /* Couldn't find a CD-DA or DVD. See if we can find a VCD, unless
1610 we've tried that before. */
1611 if (!b_probed_VCD) psz_device = ProbeVCD(disc_device->GetValue());
1614 disc_type->SetSelection(SELECTION_DISC_TYPE_VCD);
1615 OnDiscTypeChange( dummy_event );
1618 disc_device->SetValue( wxL2U("") );
1622 msg_Err( p_intf, "invalid Disc type selection (%d)",
1623 disc_type->GetSelection() );
1628 disc_probe->SetValue(FALSE);
1630 UpdateMRL( DISC_ACCESS );
1632 #endif /* HAVE_LIBCDIO */
1634 void OpenDialog::OnDiscTypeChange( wxCommandEvent& WXUNUSED(event) )
1636 char *psz_device = NULL;
1638 switch( disc_type->GetSelection() )
1641 case SELECTION_DISC_TYPE_DVD_MENUS:
1642 case SELECTION_DISC_TYPE_DVD:
1643 disc_sub->Enable(); disc_sub_label->Enable();
1644 disc_audio->Enable(); disc_audio_label->Enable();
1645 disc_chapter->Enable(); disc_chapter_label->Enable();
1646 disc_title_label->SetLabel ( wxU(_("Title")) );
1647 psz_device = config_GetPsz( p_intf, "dvd" );
1648 if( !b_disc_device_changed )
1650 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1651 else disc_device->SetValue( wxT("") );
1653 disc_title->SetRange( 0, 255 );
1654 disc_sub->SetRange( -1, 31 ); // up to 32 subtitles -1: no subtitle
1655 disc_audio->SetRange( 0, 7 ); // up to 8 audio channels
1656 disc_chapter->SetRange( 0, 255 );
1657 disc_title->SetToolTip( wxU(_("Title number.")) );
1658 disc_sub->SetToolTip( wxU(_(
1659 "DVD's can have up to 32 subtitles numbered 0..31. "
1660 "Note this is not the same thing as a subtitle name e.g. 'en'. "
1661 "If a value -1 is used, no subtitle will be shown." )) );
1662 disc_audio->SetToolTip( wxU(_("Audio track number. "
1663 "DVD's can have up to 8 audio tracks numbered 0..7."
1667 case SELECTION_DISC_TYPE_VCD:
1668 disc_sub->Enable(); disc_sub_label->Enable();
1669 disc_audio->Enable(); disc_audio_label->Enable();
1670 disc_chapter->Disable(); disc_chapter_label->Disable();
1671 psz_device = config_GetPsz( p_intf, "vcd" );
1672 if( !b_disc_device_changed )
1674 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1675 else disc_device->SetValue( wxT("") );
1679 if (config_GetInt( p_intf, "vcdx-PBC" ))
1681 disc_title_label->SetLabel ( wxT("Playback LID") );
1682 disc_title->SetToolTip( wxU(_(
1683 "Playback control (PBC) usually starts with number 1." )) );
1687 disc_title_label->SetLabel ( wxT("Entry") );
1688 disc_title->SetToolTip( wxU(_(
1689 "The first entry (the beginning of the first MPEG track) is 0." )) );
1693 disc_title_label->SetLabel ( wxU(_("Track")) );
1694 disc_title->SetToolTip( wxU(_("Track number.")) );
1696 disc_title->SetRange( 0, 99 ); // only 100 tracks allowed on VCDs
1697 disc_sub->SetRange( -1, 3 ); // up to 4 subtitles -1 = no subtitle
1698 disc_audio->SetRange( 0, 1 ); // up to 2 audio tracks
1699 disc_sub->SetToolTip( wxU(_(
1700 "SVCD's can have up to 4 subtitles numbered 0..3. "
1701 "If a value -1 is used, no subtitle will be shown." )) );
1702 disc_audio->SetToolTip( wxU(_("Audio track number. "
1703 "VCD's can have up to 2 audio tracks numbered 0 or 1. "
1707 case SELECTION_DISC_TYPE_CDDA:
1708 disc_sub->Disable(); disc_sub_label->Disable();
1709 disc_chapter->Disable(); disc_chapter_label->Disable();
1710 disc_audio->Disable(); disc_audio_label->Disable();
1711 disc_title_label->SetLabel ( wxU(_("Track")) );
1713 disc_title->SetToolTip( wxU(_(
1714 "Audio CDs can have up to 100 tracks, the first track is usually 1. "
1715 "If 0 is given, then all tracks are played.")) );
1717 disc_title->SetToolTip( wxU(_(
1718 "Audio CDs can have up to 100 tracks, the first track is usually 1."
1721 psz_device = config_GetPsz( p_intf, "cd-audio" );
1722 if( !b_disc_device_changed )
1724 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1725 else disc_device->SetValue( wxT("") );
1728 /* There are at most 100 tracks in a CD-DA */
1729 disc_title->SetRange( 0, 100 );
1733 msg_Err( p_intf, "invalid Disc type selection (%d)",
1734 disc_type->GetSelection() );
1738 disc_title->SetValue( 0 ); i_disc_title = 0;
1739 disc_chapter->SetValue( 0 ); i_disc_chapter = 0;
1741 if( psz_device ) free( psz_device );
1743 UpdateMRL( DISC_ACCESS );
1746 /*****************************************************************************
1747 * Net panel event methods.
1748 *****************************************************************************/
1749 void OpenDialog::OnNetPanelChangeSpin( wxSpinEvent& event )
1751 wxCommandEvent cevent;
1752 cevent.SetId(event.GetId());
1753 cevent.SetInt(event.GetPosition());
1754 OnNetPanelChange(cevent);
1757 void OpenDialog::OnNetPanelChange( wxCommandEvent& event )
1759 if( event.GetId() >= NetPort1_Event && event.GetId() <= NetPort3_Event )
1761 i_net_ports[event.GetId() - NetPort1_Event] = event.GetInt();
1764 UpdateMRL( NET_ACCESS );
1767 void OpenDialog::OnNetTypeChange( wxCommandEvent& event )
1771 i_net_type = event.GetId() - NetRadio1_Event;
1775 net_radios[i]->SetValue( event.GetId() == (NetRadio1_Event+i) );
1776 net_subpanels[i]->Enable( event.GetId() == (NetRadio1_Event+i) );
1778 /* UDP Unicast or multicast -> timeshift */
1779 if( i_net_type == 0 || i_net_type == 1 )
1780 net_timeshift->Enable();
1782 net_timeshift->Disable();
1784 UpdateMRL( NET_ACCESS );
1787 /*****************************************************************************
1788 * Subtitles file event methods.
1789 *****************************************************************************/
1790 void OpenDialog::OnSubsFileEnable( wxCommandEvent& event )
1792 subsfile_button->Enable( event.GetInt() != 0 );
1793 subbrowse_button->Enable( event.GetInt() != 0 );
1794 subfile_combo->Enable( event.GetInt() != 0 );
1797 void OpenDialog::OnSubsFileSettings( wxCommandEvent& WXUNUSED(event) )
1799 /* Show/hide the open dialog */
1800 if( subsfile_dialog == NULL )
1801 subsfile_dialog = new SubsFileDialog( p_intf, this );
1803 if( subsfile_dialog && subsfile_dialog->ShowModal() == wxID_OK )
1805 subsfile_mrl.Empty();
1806 subsfile_mrl.Add( wxString(wxT("sub-file=")) + subfile_combo->GetValue() );
1807 if( subsfile_dialog->encoding_combo )
1809 subsfile_mrl.Add( wxString(wxT("subsdec-encoding=")) +
1810 subsfile_dialog->encoding_combo->GetValue() );
1812 if( subsfile_dialog->align_combo )
1814 subsfile_mrl.Add( wxString::Format(wxT("subsdec-align=%i"),
1815 (int)subsfile_dialog->align_combo->GetClientData(
1816 subsfile_dialog->align_combo->GetSelection()) ) );
1818 if( subsfile_dialog->size_combo )
1820 subsfile_mrl.Add( wxString::Format( wxT("freetype-rel-fontsize=%i"),
1821 (int)subsfile_dialog->size_combo->GetClientData(
1822 subsfile_dialog->size_combo->GetSelection()) ) );
1824 subsfile_mrl.Add( wxString::Format( wxT("sub-fps=%i"),
1825 subsfile_dialog->fps_spinctrl->GetValue() ) );
1826 subsfile_mrl.Add( wxString::Format( wxT("sub-delay=%i"),
1827 subsfile_dialog->delay_spinctrl->GetValue() ) );
1831 /*****************************************************************************
1832 * Stream output event methods.
1833 *****************************************************************************/
1834 void OpenDialog::OnSoutEnable( wxCommandEvent& event )
1836 sout_button->Enable( event.GetInt() != 0 );
1839 void OpenDialog::OnSoutSettings( wxCommandEvent& WXUNUSED(event) )
1841 /* Show/hide the open dialog */
1842 if( sout_dialog == NULL )
1843 sout_dialog = new SoutDialog( p_intf, this );
1845 if( sout_dialog && sout_dialog->ShowModal() == wxID_OK )
1847 sout_mrl = sout_dialog->GetOptions();
1851 /*****************************************************************************
1852 * Caching event methods.
1853 *****************************************************************************/
1854 void OpenDialog::OnCachingEnable( wxCommandEvent& event )
1856 caching_value->Enable( event.GetInt() != 0 );
1857 i_caching = caching_value->GetValue();
1861 void OpenDialog::OnCachingChangeSpin( wxSpinEvent& event )
1863 wxCommandEvent cevent;
1864 OnCachingChange(cevent);
1867 void OpenDialog::OnCachingChange( wxCommandEvent& event )
1869 i_caching = event.GetInt();
1873 /*****************************************************************************
1874 * Utility functions.
1875 *****************************************************************************/
1876 wxArrayString SeparateEntries( wxString entries )
1878 vlc_bool_t b_quotes_mode = VLC_FALSE;
1880 wxArrayString entries_array;
1883 wxStringTokenizer token( entries, wxT(" \t\r\n\""), wxTOKEN_RET_DELIMS );
1885 while( token.HasMoreTokens() )
1887 entry += token.GetNextToken();
1889 if( entry.IsEmpty() ) continue;
1891 if( !b_quotes_mode && entry.Last() == wxT('\"') )
1893 /* Enters quotes mode */
1895 b_quotes_mode = VLC_TRUE;
1897 else if( b_quotes_mode && entry.Last() == wxT('\"') )
1899 /* Finished the quotes mode */
1901 b_quotes_mode = VLC_FALSE;
1903 else if( !b_quotes_mode && entry.Last() != wxT('\"') )
1905 /* we found a non-quoted standalone string */
1906 if( token.HasMoreTokens() ||
1907 entry.Last() == wxT(' ') || entry.Last() == wxT('\t') ||
1908 entry.Last() == wxT('\r') || entry.Last() == wxT('\n') )
1910 if( !entry.IsEmpty() ) entries_array.Add( entry );
1917 if( !entry.IsEmpty() ) entries_array.Add( entry );
1919 return entries_array;