1 /*****************************************************************************
2 * open.cpp : Open dialog box
3 *****************************************************************************
4 * Copyright (C) 2000-2005 the VideoLAN team
7 * Authors: Gildas Bazin <gbazin@videolan.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
27 #include "dialogs/open.hpp"
28 #include "dialogs/streamout.hpp"
29 #include "dialogs/preferences_widgets.h"
30 #include "dialogs/subtitles.hpp"
32 #include "vlc_charset.h"
34 #undef HAVE_LIBCDIO // Disable broken code
37 #include <cdio/cdio.h>
38 #include <cdio/cd_types.h>
39 #include <cdio/logging.h>
40 #endif /* HAVE_LIBCDIO */
43 #include <libvcd/version.h>
44 /* There was a bug in libvcdinfo <= 23 which prevented C++ compilation */
45 #if LIBVCD_VERSION_NUM > 23
46 #include <libvcd/info.h>
47 #endif /* LIBVCD_VERSION_NUM > 23 */
48 #endif /* HAVE_VCDINFO */
50 #include <wx/combobox.h>
51 #include <wx/statline.h>
52 #include <wx/tokenzr.h>
55 # define wxRB_SINGLE 0
58 #define SELECTION_DISC_TYPE_DVD_MENUS 0
59 #define SELECTION_DISC_TYPE_DVD 1
60 #define SELECTION_DISC_TYPE_VCD 2
61 #define SELECTION_DISC_TYPE_CDDA 3
63 /*****************************************************************************
65 *****************************************************************************/
67 /* IDs for the controls and the menu commands */
70 Notebook_Event = wxID_HIGHEST,
89 NetRadio1_Event, NetRadio2_Event, NetRadio3_Event, NetRadio4_Event,
90 NetPort1_Event, NetPort2_Event, NetPort3_Event,
91 NetAddr1_Event, NetAddr2_Event, NetAddr3_Event, NetAddr4_Event,
92 NetForceIPv6_Event, NetTimeshift_Event,
95 SubsFileSettings_Event,
103 AdvancedOptions_Event
106 BEGIN_EVENT_TABLE(OpenDialog, wxDialog)
108 EVT_BUTTON(wxID_OK, OpenDialog::OnOk)
109 EVT_BUTTON(wxID_CANCEL, OpenDialog::OnCancel)
111 EVT_NOTEBOOK_PAGE_CHANGED(Notebook_Event, OpenDialog::OnPageChange)
113 EVT_TEXT(MRL_Event, OpenDialog::OnMRLChange)
115 /* Events generated by the file panel */
116 EVT_TEXT(FileName_Event, OpenDialog::OnFilePanelChange)
117 EVT_BUTTON(FileBrowse_Event, OpenDialog::OnFileBrowse)
118 EVT_TEXT(SubFileName_Event, OpenDialog::OnSubFileChange)
119 EVT_BUTTON(SubFileBrowse_Event, OpenDialog::OnSubFileBrowse)
121 /* Events generated by the disc panel */
122 EVT_RADIOBOX(DiscType_Event, OpenDialog::OnDiscTypeChange)
124 EVT_CHECKBOX(DiscProbe_Event, OpenDialog::OnDiscProbe)
126 EVT_TEXT(DiscDevice_Event, OpenDialog::OnDiscDeviceChange)
127 EVT_TEXT(DiscDevice_Event, OpenDialog::OnDiscPanelChange)
128 EVT_TEXT(DiscTitle_Event, OpenDialog::OnDiscPanelChange)
129 EVT_SPINCTRL(DiscTitle_Event, OpenDialog::OnDiscPanelChangeSpin)
130 EVT_TEXT(DiscChapter_Event, OpenDialog::OnDiscPanelChange)
131 EVT_SPINCTRL(DiscChapter_Event, OpenDialog::OnDiscPanelChangeSpin)
132 EVT_TEXT(DiscSub_Event, OpenDialog::OnDiscPanelChange)
133 EVT_TEXT(DiscAudio_Event, OpenDialog::OnDiscPanelChange)
134 EVT_SPINCTRL(DiscSub_Event, OpenDialog::OnDiscPanelChangeSpin)
136 /* Events generated by the net panel */
137 EVT_RADIOBUTTON(NetRadio1_Event, OpenDialog::OnNetTypeChange)
138 EVT_RADIOBUTTON(NetRadio2_Event, OpenDialog::OnNetTypeChange)
139 EVT_RADIOBUTTON(NetRadio3_Event, OpenDialog::OnNetTypeChange)
140 EVT_RADIOBUTTON(NetRadio4_Event, OpenDialog::OnNetTypeChange)
141 EVT_TEXT(NetPort1_Event, OpenDialog::OnNetPanelChange)
142 EVT_SPINCTRL(NetPort1_Event, OpenDialog::OnNetPanelChangeSpin)
143 EVT_TEXT(NetPort2_Event, OpenDialog::OnNetPanelChange)
144 EVT_SPINCTRL(NetPort2_Event, OpenDialog::OnNetPanelChangeSpin)
145 EVT_TEXT(NetPort3_Event, OpenDialog::OnNetPanelChange)
146 EVT_SPINCTRL(NetPort3_Event, OpenDialog::OnNetPanelChangeSpin)
147 EVT_TEXT(NetAddr2_Event, OpenDialog::OnNetPanelChange)
148 EVT_TEXT(NetAddr3_Event, OpenDialog::OnNetPanelChange)
149 EVT_TEXT(NetAddr4_Event, OpenDialog::OnNetPanelChange)
150 EVT_CHECKBOX(NetForceIPv6_Event, OpenDialog::OnNetPanelChange)
151 EVT_CHECKBOX(NetTimeshift_Event, OpenDialog::OnNetPanelChange)
153 /* Events generated by the subtitle file buttons */
154 EVT_CHECKBOX(SubsFileEnable_Event, OpenDialog::OnSubsFileEnable)
155 EVT_BUTTON(SubsFileSettings_Event, OpenDialog::OnSubsFileSettings)
157 /* Events generated by the stream output buttons */
158 EVT_CHECKBOX(SoutEnable_Event, OpenDialog::OnSoutEnable)
159 EVT_BUTTON(SoutSettings_Event, OpenDialog::OnSoutSettings)
161 /* Events generated by the caching button */
162 EVT_CHECKBOX(CachingEnable_Event, OpenDialog::OnCachingEnable)
163 EVT_TEXT(CachingChange_Event, OpenDialog::OnCachingChange)
164 EVT_SPINCTRL(CachingChange_Event, OpenDialog::OnCachingChangeSpin)
166 /* Hide the window when the user closes the window */
167 EVT_CLOSE(OpenDialog::OnClose)
172 /*****************************************************************************
174 *****************************************************************************/
175 WX_DEFINE_ARRAY(ConfigControl *, ArrayOfConfigControls);
177 class AutoBuiltPanel : public wxPanel
182 AutoBuiltPanel( wxWindow *, OpenDialog *, intf_thread_t *,
185 virtual ~AutoBuiltPanel() {}
187 void UpdateAdvancedMRL();
190 ArrayOfConfigControls config_array;
191 ArrayOfConfigControls advanced_config_array;
192 wxComboBox *p_advanced_mrl_combo;
195 intf_thread_t *p_intf;
196 OpenDialog *p_open_dialog;
198 void OnAdvanced( wxCommandEvent& event );
199 wxDialog *p_advanced_dialog;
201 DECLARE_EVENT_TABLE();
204 BEGIN_EVENT_TABLE(AutoBuiltPanel, wxPanel)
205 EVT_BUTTON(AdvancedOptions_Event, AutoBuiltPanel::OnAdvanced)
208 static void AutoBuildCallback( void *p_data )
210 ((OpenDialog *)p_data)->UpdateMRL();
213 static void AutoBuildAdvancedCallback( void *p_data )
215 ((AutoBuiltPanel *)p_data)->UpdateAdvancedMRL();
218 AutoBuiltPanel::AutoBuiltPanel( wxWindow *parent, OpenDialog *dialog,
219 intf_thread_t *_p_intf,
220 const module_t *p_module )
221 : wxPanel( parent, -1, wxDefaultPosition, wxDefaultSize ),
222 name( wxU(module_get_object(p_module)) ),
223 p_advanced_mrl_combo( NULL ),
224 p_intf( _p_intf ), p_open_dialog( dialog ), p_advanced_dialog( NULL )
226 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
227 bool b_advanced = false;
228 unsigned int i_confsize;
229 module_config_t *p_config;
232 p_config = module_config_get (p_module, &i_confsize);
233 for( n = 0; n < i_confsize; n++ )
235 module_config_t *p_item = p_config + n;
236 if( !(p_item->i_type & CONFIG_HINT) && p_item->b_advanced )
239 if( p_item->i_type & CONFIG_HINT || p_item->b_advanced )
242 ConfigControl *control =
243 CreateConfigControl( VLC_OBJECT(p_intf), p_item, this );
245 config_array.Add( control );
247 /* Don't add items that were not recognized */
248 if( control == NULL ) continue;
250 control->SetUpdateCallback( AutoBuildCallback, (void *)dialog );
252 sizer->Add( control, 0, wxEXPAND | wxALL, 2 );
258 new wxButton( this, AdvancedOptions_Event,
259 wxU(_("Advanced options...")) );
260 sizer->Add( button, 0, wxALL, 5 );
262 /* Build the advanced dialog */
264 new wxDialog( this, -1, ((wxString)wxU(_("Advanced options"))) +
265 wxT(" (") + wxU( module_GetLongName(p_module) ) +
266 wxT(")"), wxDefaultPosition, wxDefaultSize,
267 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER );
269 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
271 /* Create MRL combobox */
272 wxBoxSizer *mrl_sizer_sizer = new wxBoxSizer( wxHORIZONTAL );
273 wxStaticBox *mrl_box =
274 new wxStaticBox( p_advanced_dialog, -1,
275 wxU(_("Advanced options")) );
276 wxStaticBoxSizer *mrl_sizer =
277 new wxStaticBoxSizer( mrl_box, wxHORIZONTAL );
278 wxStaticText *mrl_label =
279 new wxStaticText( p_advanced_dialog, -1, wxU(_("Options:")) );
280 p_advanced_mrl_combo =
281 new wxComboBox( p_advanced_dialog, MRL_Event, wxT(""),
282 wxDefaultPosition, wxDefaultSize );
283 mrl_sizer->Add( mrl_label, 0, wxALL | wxALIGN_CENTER, 5 );
284 mrl_sizer->Add( p_advanced_mrl_combo, 1, wxALL | wxALIGN_CENTER, 5 );
285 mrl_sizer_sizer->Add( mrl_sizer, 1, wxEXPAND | wxALL, 5 );
286 sizer->Add( mrl_sizer_sizer, 0, wxEXPAND | wxALL, 2 );
288 /* Add advanced options to panel */
289 for( n = 0; n < i_confsize; n++ )
291 module_config_t *p_item = p_config + n;
292 if( p_item->i_type & CONFIG_HINT || !p_item->b_advanced )
295 ConfigControl *control =
296 CreateConfigControl( VLC_OBJECT(p_intf), p_item,
299 advanced_config_array.Add( control );
301 /* Don't add items that were not recognized */
302 if( control == NULL ) continue;
304 control->SetUpdateCallback( AutoBuildAdvancedCallback,
307 sizer->Add( control, 0, wxEXPAND | wxALL, 2 );
311 wxPanel *dummy_panel = new wxPanel( p_advanced_dialog, -1 );
312 sizer->Add( dummy_panel, 1 );
313 wxStaticLine *static_line =
314 new wxStaticLine( p_advanced_dialog, wxID_OK );
315 sizer->Add( static_line, 0, wxEXPAND | wxALL, 5 );
318 wxButton *ok_button =
319 new wxButton( p_advanced_dialog, wxID_OK, wxU(_("&OK")) );
320 ok_button->SetDefault();
321 wxButton *cancel_button =
322 new wxButton( p_advanced_dialog, wxID_CANCEL, wxU(_("&Cancel")) );
323 wxStdDialogButtonSizer *button_sizer = new wxStdDialogButtonSizer;
324 button_sizer->AddButton( ok_button );
325 button_sizer->AddButton( cancel_button );
326 button_sizer->Realize();
327 sizer->Add( button_sizer, 0, wxEXPAND|wxALL, 5 );
329 sizer->SetMinSize( 400, -1 );
330 p_advanced_dialog->SetSizerAndFit( sizer );
333 module_config_free (p_config);
335 this->SetSizerAndFit( sizer );
338 void AutoBuiltPanel::OnAdvanced( wxCommandEvent& event )
340 if( p_advanced_dialog->ShowModal() == wxID_OK )
343 p_open_dialog->UpdateMRL();
347 void AutoBuiltPanel::UpdateAdvancedMRL()
351 for( int i = 0; i < (int)advanced_config_array.GetCount(); i++ )
353 ConfigControl *control = advanced_config_array.Item(i);
355 mrltemp += (i ? wxT(" :") : wxT(":"));
357 if( control->GetType() == CONFIG_ITEM_BOOL &&
358 !control->GetIntValue() ) mrltemp += wxT("no-");
360 mrltemp += control->GetName();
362 switch( control->GetType() )
364 case CONFIG_ITEM_STRING:
365 case CONFIG_ITEM_FILE:
366 case CONFIG_ITEM_DIRECTORY:
367 case CONFIG_ITEM_MODULE:
368 mrltemp += wxT("=\"") + control->GetPszValue() + wxT("\"");
370 case CONFIG_ITEM_INTEGER:
372 wxString::Format( wxT("=%i"), control->GetIntValue() );
374 case CONFIG_ITEM_FLOAT:
376 wxString::Format(wxT("=%f"), control->GetFloatValue());
381 p_advanced_mrl_combo->SetValue( mrltemp );
384 /*****************************************************************************
386 *****************************************************************************/
387 OpenDialog::OpenDialog( intf_thread_t *_p_intf, wxWindow *_p_parent,
388 int i_access_method, int i_arg ):
389 wxDialog( _p_parent, -1, wxU(_("Open...")), wxDefaultPosition,
390 wxDefaultSize, wxDEFAULT_FRAME_STYLE )
392 OpenDialog( _p_intf, _p_parent, i_access_method, i_arg, OPEN_NORMAL );
395 OpenDialog::OpenDialog( intf_thread_t *_p_intf, wxWindow *_p_parent,
396 int i_access_method, int i_arg, int _i_method ):
397 wxDialog( _p_parent, -1, wxU(_("Open...")), wxDefaultPosition,
398 wxDefaultSize, wxDEFAULT_FRAME_STYLE )
400 /* Initializations */
401 i_method = _i_method;
403 p_parent = _p_parent;
404 SetIcon( *p_intf->p_sys->p_icon );
406 i_disc_type_selection = 0;
411 subsfile_dialog = NULL;
412 b_disc_device_changed = false;
414 /* Create a panel to put everything in */
415 wxPanel *panel = new wxPanel( this, -1 );
416 panel->SetAutoLayout( TRUE );
419 /* Advanced options */
420 wxStaticBox *adv_box = new wxStaticBox( panel, -1,
421 wxU(_("Advanced options")) );
422 wxStaticBoxSizer *adv_sizer = new wxStaticBoxSizer( adv_box,
426 wxFlexGridSizer *common_opt_sizer = new wxFlexGridSizer( 5, 1, 20 );
427 if( i_method == OPEN_NORMAL )
429 /* Create Stream Output checkox */
430 sout_checkbox = new wxCheckBox( panel, SoutEnable_Event,
431 wxU(_("Stream/Save")) );
432 sout_checkbox->SetToolTip( wxU(_("Use VLC as a stream server")) );
433 common_opt_sizer->Add( sout_checkbox, 0,
434 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
436 sout_button = new wxButton( panel, SoutSettings_Event,
437 wxU(_("Settings...")) );
438 sout_button->Disable();
440 char *psz_sout = config_GetPsz( p_intf, "sout" );
441 if( psz_sout && *psz_sout )
443 sout_checkbox->SetValue(TRUE);
444 sout_button->Enable();
445 subsfile_mrl.Add( wxString(wxT("sout=")) + wxL2U(psz_sout) );
449 common_opt_sizer->Add( sout_button, 1, wxALIGN_LEFT |
450 wxALIGN_CENTER_VERTICAL );
452 common_opt_sizer->Add( new wxPanel( this, -1 ), 1,
453 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
456 /* Create caching options */
457 caching_checkbox = new wxCheckBox( panel, CachingEnable_Event,
459 caching_checkbox->SetToolTip( wxU(_("Change the default caching value "
460 "(in milliseconds)")) );
461 common_opt_sizer->Add( caching_checkbox, 0,
462 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
463 caching_value = new wxSpinCtrl( panel, CachingChange_Event );
464 caching_value->SetRange( 0, 1000000 );
465 caching_value->Disable();
466 common_opt_sizer->Add( caching_value, 0,
467 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
470 wxBoxSizer *mrl_sizer = new wxBoxSizer( wxHORIZONTAL );
471 wxStaticText *mrl_label = new wxStaticText( panel, -1,
472 wxU(_("Customize:")) );
473 mrl_combo = new wxComboBox( panel, MRL_Event, wxT(""),
474 wxDefaultPosition, wxDefaultSize );
475 //Point(20,25), wxSize(120, -1) );
476 mrl_combo->SetToolTip( wxU(_("You can use this field directly by typing "
477 "the full MRL you want to open.\n""Alternatively, the field will be "
478 "filled automatically when you use the controls above.")) );
480 mrl_sizer->Add( mrl_label, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
481 mrl_sizer->Add( mrl_combo, 1, wxALL | wxEXPAND | wxALIGN_CENTER_VERTICAL,
484 adv_sizer->Add( common_opt_sizer, 0, wxTOP | wxLEFT|wxRIGHT | wxEXPAND, 5 );
485 adv_sizer->Add( mrl_sizer, 0, wxBOTTOM | wxLEFT|wxRIGHT | wxEXPAND, 5 );
488 wxStaticLine *static_line = new wxStaticLine( panel, wxID_OK );
490 /* Create the buttons */
491 wxButton *ok_button = new wxButton( panel, wxID_OK, wxU(_("&OK")) );
492 ok_button->SetDefault();
493 wxButton *cancel_button = new wxButton( panel, wxID_CANCEL,
496 /* Create notebook */
497 notebook = new wxNotebook( panel, Notebook_Event );
499 #if (!wxCHECK_VERSION(2,5,2))
500 wxNotebookSizer *notebook_sizer = new wxNotebookSizer( notebook );
503 notebook->AddPage( FilePanel( notebook ), wxU(_("File")),
504 i_access_method == FILE_ACCESS );
505 notebook->AddPage( DiscPanel( notebook ), wxU(_("Disc")),
506 i_access_method == DISC_ACCESS );
507 notebook->AddPage( NetPanel( notebook ), wxU(_("Network")),
508 i_access_method == NET_ACCESS );
510 if( module_exists( "v4l" ) )
512 AutoBuiltPanel *autopanel =
513 new AutoBuiltPanel( notebook, this, p_intf, p_module );
514 input_tab_array.Add( autopanel );
515 notebook->AddPage( autopanel, wxU( module_get_name(p_module, 0) ),
516 i_access_method == CAPTURE_ACCESS );
519 if( module_exists( "pvr" ) )
521 AutoBuiltPanel *autopanel =
522 new AutoBuiltPanel( notebook, this, p_intf, p_module );
523 input_tab_array.Add( autopanel );
524 notebook->AddPage( autopanel, wxU( module_get_name(p_module, 0) ),
525 i_access_method == CAPTURE_ACCESS );
528 if( module_exists( "dvb" ) )
530 AutoBuiltPanel *autopanel =
531 new AutoBuiltPanel( notebook, this, p_intf, p_module );
532 input_tab_array.Add( autopanel );
533 notebook->AddPage( autopanel, wxU( module_get_name(p_module, 0) ),
534 i_access_method == CAPTURE_ACCESS );
537 if( module_exists( "dshow" ) )
539 AutoBuiltPanel *autopanel =
540 new AutoBuiltPanel( notebook, this, p_intf, p_module );
541 input_tab_array.Add( autopanel );
542 notebook->AddPage( autopanel, wxU( module_get_name(p_module, 0) ),
543 i_access_method == CAPTURE_ACCESS );
546 /* Update Disc panel */
547 wxCommandEvent dummy_event;
548 OnDiscTypeChange( dummy_event );
550 /* Update Net panel */
551 dummy_event.SetId( NetRadio1_Event );
552 OnNetTypeChange( dummy_event );
555 wxNotebookEvent event( wxEVT_NULL, 0, i_access_method );
556 OnPageChange( event );
558 /* Place everything in sizers */
559 wxStdDialogButtonSizer *button_sizer = new wxStdDialogButtonSizer;
560 button_sizer->AddButton( cancel_button );
561 button_sizer->AddButton( ok_button );
562 button_sizer->Realize();
563 wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL );
564 wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
565 #if (!wxCHECK_VERSION(2,5,2))
566 panel_sizer->Add( notebook_sizer, 1, wxEXPAND | wxALL, 5 );
568 panel_sizer->Add( notebook, 1, wxEXPAND | wxALL, 5 );
570 panel_sizer->Add( adv_sizer, 0, wxEXPAND | wxALL, 5 );
571 panel_sizer->Add( static_line, 0, wxEXPAND | wxALL, 5 );
572 panel_sizer->Add( button_sizer, 0, wxEXPAND | wxALL, 5 );
573 panel_sizer->Layout();
574 panel->SetSizerAndFit( panel_sizer );
575 main_sizer->Add( panel, 1, wxGROW, 0 );
576 main_sizer->Layout();
577 SetSizerAndFit( main_sizer );
580 OpenDialog::~OpenDialog()
585 delete subsfile_dialog;
588 int OpenDialog::Show( int i_access_method, int i_arg )
590 notebook->SetSelection( i_access_method );
591 int i_ret = wxDialog::Show();
598 int OpenDialog::Show()
600 int i_ret = wxDialog::Show();
606 /*****************************************************************************
608 *****************************************************************************/
609 wxPanel *OpenDialog::FilePanel( wxWindow* parent )
611 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
614 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
616 /* Create browse file line */
617 wxBoxSizer *file_sizer = new wxBoxSizer( wxHORIZONTAL );
619 file_sizer->Add( new wxStaticText( panel, -1, wxU(_("Open:") ) ), 0,
620 wxALL | wxALIGN_CENTER_VERTICAL, 5 );
622 file_combo = new wxComboBox( panel, FileName_Event, wxT("") );
623 wxButton *browse_button = new wxButton( panel, FileBrowse_Event,
624 wxU(_("Browse...")) );
625 file_sizer->Add( file_combo, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
626 file_sizer->Add( browse_button, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
628 /* Create Subtitles File checkox - button */
629 wxFlexGridSizer *subtitles_sizer = new wxFlexGridSizer( 2, 1, 20 );
630 subsfile_checkbox = new wxCheckBox( panel, SubsFileEnable_Event,
631 wxU(_("Use a subtitles file")) );
632 subsfile_checkbox->SetToolTip( wxU(_("Use an external subtitles file.")) );
633 subtitles_sizer->Add( subsfile_checkbox, 0, wxALIGN_CENTER_VERTICAL |
635 subsfile_button = new wxButton( panel, SubsFileSettings_Event,
636 wxU(_("Advanced Settings...")) );
637 subsfile_button->Disable();
638 subtitles_sizer->Add( subsfile_button, 1, wxALIGN_CENTER_VERTICAL |
641 /* Create subtitles file line */
642 wxBoxSizer *subfile_sizer = new wxBoxSizer( wxHORIZONTAL );
644 char *psz_subsfile = config_GetPsz( p_intf, "sub-file" );
645 if( psz_subsfile && *psz_subsfile )
647 subsfile_checkbox->SetValue(TRUE);
648 subsfile_button->Enable();
649 subsfile_mrl.Add( wxString(wxT("sub-file=")) + wxL2U(psz_subsfile) );
651 if( !psz_subsfile ) psz_subsfile = strdup("");
652 subfile_sizer->Add( new wxStaticText( panel, -1, wxU(_("File:") ) ),
653 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
654 subfile_combo = new wxComboBox( panel, SubFileName_Event,
655 wxL2U( psz_subsfile ) );
656 free( psz_subsfile );
657 subbrowse_button = new wxButton( panel, SubFileBrowse_Event,
658 wxU(_("Browse...")) );
659 subfile_sizer->Add( subfile_combo, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
660 subfile_sizer->Add( subbrowse_button, 0, wxALL |wxALIGN_CENTER_VERTICAL, 5 );
662 subfile_combo->Disable();
663 subbrowse_button->Disable();
665 psz_subsfile = config_GetPsz( p_intf, "sub-file" );
666 if( psz_subsfile && *psz_subsfile )
668 subfile_combo->Enable();
669 subbrowse_button->Enable();
672 sizer->Add( file_sizer, 0, wxEXPAND | wxALL, 5 );
673 sizer->Add( subtitles_sizer, 0, wxLEFT | wxRIGHT | wxTOP, 5 );
674 sizer->Add( subfile_sizer, 0, wxEXPAND | wxLEFT | wxRIGHT| wxBOTTOM, 5 );
675 panel->SetSizerAndFit( sizer );
679 wxPanel *OpenDialog::DiscPanel( wxWindow* parent )
681 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
684 wxBoxSizer *sizer_row = new wxBoxSizer( wxVERTICAL );
685 wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 3, 20 );
687 static const wxString disc_type_array[] =
689 wxU(_("DVD (menus)")),
695 disc_type = new wxRadioBox( panel, DiscType_Event, wxU(_("Disc type")),
696 wxDefaultPosition, wxDefaultSize,
697 WXSIZEOF(disc_type_array), disc_type_array,
698 WXSIZEOF(disc_type_array), wxRA_SPECIFY_COLS );
701 disc_probe = new wxCheckBox( panel, DiscProbe_Event,
702 wxU(_("Probe Disc(s)")) );
703 disc_probe->SetToolTip( wxU(_("Probe for a DVD, VCD or audio CD. "
704 "First try the Device name entered for the selected Disc type "
705 "(DVD, DVD Menu, VCD, audio CD). If that doesn't find media, try any device "
706 "for the Disc type. If that doesn't work, then try looking for CD-ROMs or "
707 "DVD drives. The Disc type, Device name, and some parameter ranges are set "
708 "based on media we find.")) );
711 sizer_row->Add( disc_type, i_disc_type_selection, wxEXPAND | wxALL, 5 );
713 sizer_row->Add( disc_probe, 0, wxEXPAND | wxALL );
716 wxStaticText *label = new wxStaticText( panel, -1, wxU(_("Device name")) );
717 disc_device = new wxTextCtrl( panel, DiscDevice_Event, wxT(""),
718 wxDefaultPosition, wxDefaultSize,
722 char psz_default_device[3] = {0};
725 /* find the drive_name for the first cdrom drive,
726 * which is probably "D:" and put the drive_name into
727 * psz_default_device... */
728 for( char drive_letter = 'A'; drive_letter <= 'Z'; ++drive_letter )
730 char drive_name[3] = {drive_letter, ':', 0};
731 UINT type = GetDriveTypeA( drive_name );
732 if( type == DRIVE_CDROM )
734 psz_default_device[0] = drive_letter;
735 psz_default_device[1] = ':';
740 psz_forced = config_GetPsz( p_intf, "dvd" );
742 if( strlen(psz_default_device) > 0 &&
743 ( !psz_forced || psz_forced && !*psz_forced ) )
746 disc_device->SetValue( wxL2U(psz_default_device) );
750 sizer->Add( label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
751 sizer->Add( disc_device, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
753 disc_title_label = new wxStaticText( panel, -1, wxU(_("Title")) );
754 disc_title = new wxSpinCtrl( panel, DiscTitle_Event );
755 sizer->Add( disc_title_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
756 sizer->Add( disc_title, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
758 disc_chapter_label = new wxStaticText( panel, -1, wxU(_("Chapter")) );
759 disc_chapter = new wxSpinCtrl( panel, DiscChapter_Event );
760 sizer->Add( disc_chapter_label, 0,
761 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
762 sizer->Add( disc_chapter, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
764 disc_sub_label = new wxStaticText( panel, -1, wxU(_("Subtitles track")) );
765 disc_sub = new wxSpinCtrl( panel, DiscSub_Event );
766 sizer->Add( disc_sub_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
767 sizer->Add( disc_sub, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
768 disc_sub->SetRange( -1, 255 );
769 i_disc_sub = config_GetInt( p_intf, "sub-track" );
770 disc_sub->SetValue( i_disc_sub );
772 disc_audio_label = new wxStaticText( panel, -1, wxU(_("Audio track")) );
773 disc_audio = new wxSpinCtrl( panel, DiscAudio_Event );
774 sizer->Add( disc_audio_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
775 sizer->Add( disc_audio, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
776 disc_audio->SetRange( -1, 255 );
777 i_disc_audio = config_GetInt( p_intf, "audio-track" );
778 disc_audio->SetValue( i_disc_audio );
780 sizer_row->Add( sizer, 0, wxEXPAND | wxALL, 5 );
782 panel->SetSizerAndFit( sizer_row );
786 wxPanel *OpenDialog::NetPanel( wxWindow* parent )
789 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
792 wxBoxSizer *sizer_row = new wxBoxSizer( wxVERTICAL );
793 wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 4, 20 );
795 static const wxString net_type_array[] =
798 wxU(_("UDP/RTP Multicast")),
799 wxU(_("HTTP/HTTPS/FTP/MMS")),
805 net_radios[i] = new wxRadioButton( panel, NetRadio1_Event + i,
807 wxDefaultPosition, wxDefaultSize,
810 net_subpanels[i] = new wxPanel( panel, -1,
811 wxDefaultPosition, wxDefaultSize );
815 net_timeshift = new wxCheckBox( panel, NetTimeshift_Event,
816 wxU(_("Allow timeshifting")) );
819 wxFlexGridSizer *subpanel_sizer;
821 i_net_ports[0] = config_GetInt( p_intf, "server-port" );
822 subpanel_sizer = new wxFlexGridSizer( 3, 1, 20 );
823 label = new wxStaticText( net_subpanels[0], -1, wxU(_("Port")) );
824 net_ports[0] = new wxSpinCtrl( net_subpanels[0], NetPort1_Event,
825 wxString::Format(wxT("%d"), i_net_ports[0]),
826 wxDefaultPosition, wxDefaultSize,
828 0, 65535, i_net_ports[0] );
830 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
831 subpanel_sizer->Add( net_ports[0], 1,
832 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
833 net_ipv6 = new wxCheckBox( net_subpanels[0], NetForceIPv6_Event,
834 wxU(_("Force IPv6")));
835 subpanel_sizer->Add( net_ipv6, 0,
836 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
837 net_subpanels[0]->SetSizerAndFit( subpanel_sizer );
838 net_radios[0]->SetValue( TRUE );
840 /* UDP/RTP Multicast row */
841 subpanel_sizer = new wxFlexGridSizer( 4, 1, 20 );
842 label = new wxStaticText( net_subpanels[1], -1, wxU(_("Address")) );
843 net_addrs[1] = new wxTextCtrl( net_subpanels[1], NetAddr2_Event, wxT(""),
844 wxDefaultPosition, wxDefaultSize,
846 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
847 subpanel_sizer->Add( net_addrs[1], 1,
848 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
850 label = new wxStaticText( net_subpanels[1], -1, wxU(_("Port")) );
851 i_net_ports[1] = i_net_ports[0];
852 net_ports[1] = new wxSpinCtrl( net_subpanels[1], NetPort2_Event,
853 wxString::Format(wxT("%d"), i_net_ports[1]),
854 wxDefaultPosition, wxDefaultSize,
856 0, 65535, i_net_ports[1] );
858 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
859 subpanel_sizer->Add( net_ports[1], 1,
860 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
861 net_subpanels[1]->SetSizerAndFit( subpanel_sizer );
863 /* HTTP and RTSP rows */
866 subpanel_sizer = new wxFlexGridSizer( 2, 1, 20 );
867 label = new wxStaticText( net_subpanels[i], -1, wxU(_("URL")) );
868 net_addrs[i] = new wxTextCtrl( net_subpanels[i], NetAddr1_Event + i,
869 (i == 2) ? wxT("") : wxT("rtsp://"),
870 wxDefaultPosition, wxSize( 200, -1 ),
872 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
873 subpanel_sizer->Add( net_addrs[i], 1,
874 wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
875 net_subpanels[i]->SetSizerAndFit( subpanel_sizer );
878 /* Stuff everything into the main panel */
881 sizer->Add( net_radios[i], 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
883 sizer->Add( net_subpanels[i], 1, wxEXPAND | wxALIGN_LEFT |
884 wxALIGN_CENTER_VERTICAL | wxALL, 5 );
886 sizer->Add( net_timeshift, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
889 sizer_row->Add( sizer, 0, wxEXPAND | wxALL, 5 );
891 panel->SetSizerAndFit( sizer_row );
895 void OpenDialog::UpdateMRL()
897 UpdateMRL( i_current_access_method );
900 void OpenDialog::UpdateMRL( int i_access_method )
902 wxString mrltemp, caching_name;
904 i_current_access_method = i_access_method;
906 switch( i_access_method )
909 mrltemp = file_combo->GetValue();
910 caching_name = wxT("file-caching");
914 i_disc_type_selection = disc_type->GetSelection();
916 switch ( i_disc_type_selection )
918 case 0: /* DVD with menus */
919 case 1: /* DVD without menus */
920 disc_device->SetToolTip( wxU(_("DVD device to use" ) ) );
921 if( i_disc_type_selection == 0 )
923 mrltemp = wxT("dvd://") + disc_device->GetValue();
924 caching_name = wxT("dvdnav-caching");
928 mrltemp = wxT("dvdsimple://") + disc_device->GetValue();
929 caching_name = wxT("dvdread-caching");
932 if( i_disc_title > 0 )
934 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
936 if( i_disc_chapter > 0 )
937 mrltemp += wxString::Format( wxT(":%d"), i_disc_chapter );
940 if( i_disc_sub >= 0 )
941 mrltemp += wxString::Format( wxT(" :sub-track=%d"),
943 if( i_disc_audio >= 0 )
944 mrltemp += wxString::Format( wxT(" :audio-track=%d"),
948 case 2: /* VCD of some sort */
950 disc_device->SetToolTip( wxU(_("Name of CD-ROM device "
951 "to read Video CD from. If this field is left empty, we will scan "
952 "for a CD-ROM with a VCD in it.")) );
953 mrltemp = wxT("vcdx://") + disc_device->GetValue();
954 if( i_disc_title > 0 )
955 mrltemp += wxString::Format( wxT("@%c%d"),
956 config_GetInt( p_intf, "vcdx-PBC" )
957 ? 'P' : 'E', i_disc_title );
959 disc_device->SetToolTip( wxU(_("CD-ROM device to use" ) ) );
960 mrltemp = wxT("vcd://") + disc_device->GetValue();
961 if( i_disc_title > 0 )
962 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
965 if( i_disc_sub >= 0 )
966 mrltemp += wxString::Format( wxT(" :sub-track=%d"),
969 if( i_disc_audio >= 0 )
970 mrltemp += wxString::Format( wxT(" :audio-track=%d"),
972 caching_name = wxT("vcd-caching");
977 disc_device->SetToolTip( wxU(_("Name of CD-ROM device "
978 "to read audio CD from. If this field is left empty, we will scan "
979 "for a CD-ROM with an audio CD in it." )) );
980 mrltemp = wxT("cddax://")
982 disc_device->SetToolTip( wxU(_("CD-ROM device to use" ) ) ) ;
983 mrltemp = wxT("cdda://")
985 + disc_device->GetValue();
986 if( i_disc_title > 0 )
987 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
989 caching_name = wxT("cdda-caching");
993 msg_Err( p_intf, "invalid selection (%d)",
994 disc_type->GetSelection() );
1000 switch( i_net_type )
1003 mrltemp = wxT("udp://@");
1004 if ( net_ipv6->GetValue() )
1006 mrltemp += wxT("[::]");
1008 if( i_net_ports[0] !=
1009 config_GetInt( p_intf, "server-port" ) )
1011 mrltemp += wxString::Format( wxT(":%d"), i_net_ports[0] );
1014 caching_name = wxT("udp-caching");
1018 mrltemp = wxT("udp://@");
1019 if ((net_addrs[1]->GetLineText(0).Find (':') != -1)
1020 && (net_addrs[1]->GetLineText(0)[0u] != '['))
1022 /* automatically adds '[' and ']' to IPv6 addresses */
1023 mrltemp += wxT("[") + net_addrs[1]->GetLineText(0)
1028 mrltemp += net_addrs[1]->GetLineText(0);
1030 if( i_net_ports[1] != config_GetInt( p_intf, "server-port" ) )
1032 mrltemp += wxString::Format( wxT(":%d"), i_net_ports[1] );
1035 caching_name = wxT("udp-caching");
1040 if( net_addrs[2]->GetLineText(0).Find(wxT("://")) == -1 )
1041 mrltemp = wxT("http://");
1043 mrltemp += net_addrs[2]->GetLineText(0);
1044 if( ! mrltemp.Left(4).CmpNoCase(wxT("http")) )
1045 caching_name = wxT("http-caching");
1046 else if( ! mrltemp.Left(3).CmpNoCase(wxT("mms")) )
1047 caching_name = wxT("mms-caching");
1049 caching_name= wxT("ftp-caching");
1054 if( net_addrs[3]->GetLineText(0).Find(wxT("rtsp://")) != 0 )
1056 mrltemp = wxT("rtsp://");
1058 mrltemp += net_addrs[3]->GetLineText(0);
1060 caching_name = wxT("rtsp-caching");
1063 if( net_timeshift->IsEnabled() && net_timeshift->IsChecked() )
1064 mrltemp += wxT(" :access-filter=timeshift");
1069 int i_item = i_access_method - MAX_ACCESS;
1071 if( i_item < 0 || i_item >= (int)input_tab_array.GetCount() )
1074 AutoBuiltPanel *input_panel = input_tab_array.Item( i_item );
1076 mrltemp = input_panel->name + wxT("://");
1078 for( int i=0; i < (int)input_panel->config_array.GetCount(); i++ )
1080 ConfigControl *control = input_panel->config_array.Item(i);
1082 mrltemp += wxT(" :");
1084 if( control->GetType() == CONFIG_ITEM_BOOL &&
1085 !control->GetIntValue() ) mrltemp += wxT("no-");
1087 mrltemp += control->GetName();
1089 switch( control->GetType() )
1091 case CONFIG_ITEM_STRING:
1092 case CONFIG_ITEM_FILE:
1093 case CONFIG_ITEM_DIRECTORY:
1094 case CONFIG_ITEM_MODULE:
1095 mrltemp += wxT("=\"") + control->GetPszValue() + wxT("\"");
1097 case CONFIG_ITEM_INTEGER:
1099 wxString::Format( wxT("=%i"), control->GetIntValue() );
1101 case CONFIG_ITEM_FLOAT:
1103 wxString::Format(wxT("=%f"), control->GetFloatValue());
1108 if( input_panel->p_advanced_mrl_combo &&
1109 input_panel->p_advanced_mrl_combo->GetValue() )
1111 mrltemp += wxT(" ") +
1112 input_panel->p_advanced_mrl_combo->GetValue();
1118 if( caching_name.size() )
1120 if( caching_value->IsEnabled() )
1122 mrltemp += wxT(" :") + caching_name +
1123 wxString::Format( wxT("=%d"), i_caching );
1127 int i_value = config_GetInt( p_intf, caching_name.mb_str(wxConvUTF8) );
1128 caching_value->SetValue( i_value );
1132 mrl_combo->SetValue( mrltemp );
1135 /*****************************************************************************
1137 *****************************************************************************/
1138 void OpenDialog::OnOk( wxCommandEvent& WXUNUSED(event) )
1140 mrl = SeparateEntries( mrl_combo->GetValue() );
1141 mrl_combo->Append( mrl_combo->GetValue() );
1142 if( mrl_combo->GetCount() > 10 ) mrl_combo->Delete( 0 );
1143 mrl_combo->SetSelection( mrl_combo->GetCount() - 1 );
1145 if( i_method == OPEN_STREAM )
1147 if( IsModal() ) EndModal( wxID_OK );
1152 /* Update the playlist */
1153 playlist_t *p_playlist = pl_Hold( p_intf );
1154 if( p_playlist == NULL ) return;
1156 for( int i = 0; i < (int)mrl.GetCount(); i++ )
1158 bool b_start = !i && i_open_arg;
1159 input_item_t *p_input;
1162 psz_utf8 = wxFromLocale( mrl[i] );
1163 p_input = input_item_New( p_intf, psz_utf8, NULL );
1164 wxLocaleFree( psz_utf8 );
1166 /* Insert options */
1167 while( i + 1 < (int)mrl.GetCount() &&
1168 ((const char *)mrl[i + 1].mb_str(wxConvUTF8))[0] == ':' )
1170 psz_utf8 = wxFromLocale( mrl[i + 1] );
1171 input_item_AddOption( p_input, psz_utf8 );
1172 wxLocaleFree( psz_utf8 );
1176 /* Get the options from the subtitles dialog */
1177 if( subsfile_checkbox->IsChecked() && subsfile_mrl.GetCount() )
1179 for( int j = 0; j < (int)subsfile_mrl.GetCount(); j++ )
1181 psz_utf8 = wxFromLocale( subsfile_mrl[j] );
1182 input_item_AddOption( p_input, psz_utf8 );
1183 wxLocaleFree( psz_utf8 );
1187 /* Get the options from the stream output dialog */
1188 if( sout_checkbox->IsChecked() && sout_mrl.GetCount() )
1190 for( int j = 0; j < (int)sout_mrl.GetCount(); j++ )
1192 psz_utf8 = wxFromLocale( sout_mrl[j] );
1193 input_item_AddOption( p_input, psz_utf8 );
1194 wxLocaleFree( psz_utf8 );
1198 /* FIXME: playlist_AddInput() can fail */
1199 playlist_AddInput( p_playlist, p_input,
1200 PLAYLIST_APPEND | ( b_start ? PLAYLIST_GO : PLAYLIST_PREPARSE ),
1201 PLAYLIST_END, true, pl_Unlocked );
1202 vlc_gc_decref( p_input );
1204 pl_Release( p_intf );
1208 if( IsModal() ) EndModal( wxID_OK );
1211 void OpenDialog::OnCancel( wxCommandEvent& WXUNUSED(event) )
1213 wxCloseEvent cevent;
1217 void OpenDialog::OnClose( wxCloseEvent& WXUNUSED(event) )
1221 if( IsModal() ) EndModal( wxID_CANCEL );
1224 void OpenDialog::OnPageChange( wxNotebookEvent& event )
1226 UpdateMRL( event.GetSelection() );
1229 void OpenDialog::OnMRLChange( wxCommandEvent& event )
1231 //mrl = SeparateEntries( event.GetString() );
1234 /*****************************************************************************
1235 * File panel event methods.
1236 *****************************************************************************/
1237 void OpenDialog::OnFilePanelChange( wxCommandEvent& WXUNUSED(event) )
1239 UpdateMRL( FILE_ACCESS );
1242 void OpenDialog::OnFileBrowse( wxCommandEvent& WXUNUSED(event) )
1244 if( file_dialog == NULL )
1245 file_dialog = new wxFileDialog( this, wxU(_("Open File")),
1246 wxT(""), wxT(""), wxT("*"), wxOPEN | wxMULTIPLE );
1248 file_dialog->SetWildcard(wxU(_("All Files (*.*)|*"
1249 "|Sound Files (*.mp3, *.ogg, etc.)|" EXTENSIONS_AUDIO
1250 "|Video Files (*.avi, *.mpg, etc.)|" EXTENSIONS_VIDEO
1251 "|Playlist Files (*.m3u, *.pls, etc.)|" EXTENSIONS_PLAYLIST
1252 "|Subtitle Files (*.srt, *.sub, etc.)|" EXTENSIONS_SUBTITLE)));
1254 if( file_dialog && file_dialog->ShowModal() == wxID_OK )
1256 wxArrayString paths;
1259 file_dialog->GetPaths( paths );
1261 for( size_t i = 0; i < paths.GetCount(); i++ )
1263 if( paths[i].Find( wxT(' ') ) >= 0 )
1264 path += wxT("\"") + paths[i] + wxT("\" ");
1266 path += paths[i] + wxT(" ");
1269 file_combo->SetValue( path );
1270 file_combo->Append( path );
1271 if( file_combo->GetCount() > 10 ) file_combo->Delete( 0 );
1272 UpdateMRL( FILE_ACCESS );
1276 void OpenDialog::OnSubFileBrowse( wxCommandEvent& WXUNUSED(event) )
1278 wxFileDialog dialog( this, wxU(_("Open subtitles file")),
1279 wxT(""), wxT(""), wxT("*"), wxOPEN );
1281 if( dialog.ShowModal() == wxID_OK )
1283 subfile_combo->SetValue( dialog.GetPath() );
1285 wxCommandEvent event; OnSubFileChange( event );
1288 void OpenDialog::OnSubFileChange( wxCommandEvent& WXUNUSED(event) )
1290 if( subsfile_mrl.GetCount() != 0 )
1292 subsfile_mrl.RemoveAt( 0 );
1293 subsfile_mrl.Insert( wxString(wxT("sub-file=")) + subfile_combo->GetValue() , 0 );
1297 subsfile_mrl.Add( wxString(wxT("sub-file=")) + subfile_combo->GetValue() );
1301 /*****************************************************************************
1302 * Disc panel event methods.
1303 *****************************************************************************/
1304 void OpenDialog::OnDiscPanelChangeSpin( wxSpinEvent& event )
1306 wxCommandEvent cevent;
1307 cevent.SetId(event.GetId());
1308 cevent.SetInt(event.GetPosition());
1309 OnDiscPanelChange(cevent);
1312 void OpenDialog::OnDiscPanelChange( wxCommandEvent& event )
1314 if( event.GetId() == DiscTitle_Event ) i_disc_title = event.GetInt();
1315 if( event.GetId() == DiscChapter_Event ) i_disc_chapter = event.GetInt();
1316 if( event.GetId() == DiscSub_Event ) i_disc_sub = event.GetInt();
1317 if( event.GetId() == DiscAudio_Event ) i_disc_audio = event.GetInt();
1319 UpdateMRL( DISC_ACCESS );
1322 void OpenDialog::OnDiscDeviceChange( wxCommandEvent& event )
1326 switch( disc_type->GetSelection() )
1329 psz_device = config_GetPsz( p_intf, "cd-audio" );
1333 psz_device = config_GetPsz( p_intf, "vcd" );
1337 psz_device = config_GetPsz( p_intf, "dvd" );
1341 if ( !psz_device ) psz_device = "";
1343 if( disc_device->GetValue().Cmp( wxL2U( psz_device ) ) )
1345 b_disc_device_changed = true;
1348 UpdateMRL( DISC_ACCESS );
1353 /* Return true if *psz_drive is a drive with a DVD in it. A more complete
1354 check would see if the media looks like a *playable* DVD. This should
1357 static bool IsDVD(const char *psz_drive)
1359 CdIo_t *p_cdio = cdio_open (psz_drive, DRIVER_UNKNOWN);
1362 discmode_t discmode = cdio_get_discmode(p_cdio);
1363 cdio_destroy(p_cdio);
1364 return cdio_is_discmode_dvd(discmode);
1370 /* Return a device that has a DVD in it. The caller needs to free
1371 the returned string.
1373 static char * ProbeDVD(const wxChar *device)
1376 char **ppsz_cd_drives;
1377 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1378 char *psz_device = (char *) tmp_buf;
1380 if( IsDVD(psz_device) )
1382 return strdup(psz_device);
1385 ppsz_cd_drives = cdio_get_devices(DRIVER_DEVICE);
1386 if( ppsz_cd_drives )
1389 for( c = ppsz_cd_drives; *c != NULL; c++ )
1393 char *psz_drive = strdup(*c);
1394 cdio_free_device_list(ppsz_cd_drives);
1395 return strdup(psz_drive);
1398 cdio_free_device_list(ppsz_cd_drives);
1404 static char * ProbeDevice(char **ppsz_search_devices, cdio_fs_anal_t mask,
1407 char **ppsz_devices;
1409 if( ppsz_search_devices && !ppsz_search_devices[0] )
1410 ppsz_search_devices = NULL;
1412 /* Start out trying the device that has been entered so far. */
1413 ppsz_devices = cdio_get_devices_with_cap(ppsz_search_devices, mask,
1416 if (ppsz_devices && *ppsz_devices)
1418 char *psz_device = strdup(*ppsz_devices);
1419 cdio_free_device_list(ppsz_devices);
1423 /* If there was no device specified on the first try, then give up
1424 now. Otherwise accept any CD-ROM in the class (e.g. VCD or DVD).
1426 if( !ppsz_search_devices ) return NULL;
1428 ppsz_devices = cdio_get_devices_with_cap(NULL, mask, true);
1430 if (ppsz_devices && *ppsz_devices)
1432 char *psz_device = strdup(*ppsz_devices);
1433 cdio_free_device_list(ppsz_devices);
1441 /* Return a device that has a CD-DA in it. The caller needs to free
1442 the returned string.
1444 static char * ProbeCDDA(const wxChar *device)
1447 char *ppsz_device[2];
1448 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1449 char *psz_device = (char *) tmp_buf;
1450 ppsz_device[0] = (device && *device) ? psz_device : NULL;
1451 ppsz_device[1] = NULL;
1452 return ProbeDevice(ppsz_device, CDIO_FS_AUDIO, false);
1456 /* Return a device that has a VCD in it. The caller needs to free
1457 the returned string.
1459 static char * ProbeVCD(const wxChar *device)
1461 char *ppsz_device[2];
1462 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1463 char *psz_device = (char *) tmp_buf;
1464 ppsz_device[0] = (device && *device) ? psz_device : NULL;
1465 ppsz_device[1] = NULL;
1466 return ProbeDevice(ppsz_device,
1467 (CDIO_FS_ANAL_SVCD|CDIO_FS_ANAL_CVD|CDIO_FS_ANAL_VIDEOCD
1468 |CDIO_FS_UNKNOWN), true);
1474 Probe (find anywhere) a CD-DA, VCD, or a DVD.
1475 First try the device name that may have been entered for the "disc type"
1476 selected. If that doesn't work we try any device for the disc type.
1477 If that doesn't work, try looking for CD-ROMs or DVD drives. the
1478 disc type, device name and paramter ranges are set to whatever we find.
1480 void OpenDialog::OnDiscProbe( wxCommandEvent& WXUNUSED(event) )
1482 wxCommandEvent dummy_event;
1483 char *psz_device = NULL;
1484 bool b_probed_DVD = false;
1485 bool b_probed_VCD = false;
1486 const int i_selection = disc_type->GetSelection();
1488 /* Reduce verbosity of cdio errors. */
1489 cdio_loglevel_default = CDIO_LOG_ERROR;
1492 switch( disc_type->GetSelection() )
1495 case SELECTION_DISC_TYPE_DVD_MENUS:
1496 case SELECTION_DISC_TYPE_DVD:
1497 /* If not a DVD then try for a VCD. If VCD fails it will
1499 if (!psz_device) psz_device = ProbeDVD(disc_device->GetValue());
1502 b_probed_DVD = true;
1503 disc_type->SetSelection(SELECTION_DISC_TYPE_VCD);
1504 OnDiscTypeChange( dummy_event );
1507 disc_device->SetValue( wxL2U(psz_device) );
1510 case SELECTION_DISC_TYPE_VCD: /* VCD probe of some sort */
1511 if(!psz_device) psz_device = ProbeVCD(disc_device->GetValue());
1515 #if LIBVCD_VERSION_NUM > 23
1516 vcdinfo_obj_t *p_vcdinfo;
1518 /* Set LID or entry range accurately if possible. */
1519 if( vcdinfo_open(&p_vcdinfo, &psz_device, DRIVER_DEVICE,
1520 NULL) == VCDINFO_OPEN_VCD)
1522 if (config_GetInt( p_intf, "vcdx-PBC" ))
1524 /* Set largest LID. */;
1525 disc_title->SetRange( 0, vcdinfo_get_num_LIDs(p_vcdinfo) );
1530 /* Set largest Entry */
1531 disc_title->SetRange( 0,
1532 vcdinfo_get_num_entries(p_vcdinfo)-1 );
1534 vcdinfo_close(p_vcdinfo);
1536 #endif /* LIBVCD_VERSION_NUM > 23 */
1537 disc_device->SetValue( wxL2U(psz_device) );
1539 CdIo_t *p_cdio = cdio_open (psz_device, DRIVER_UNKNOWN);
1540 disc_device->SetValue( wxL2U(psz_device) );
1542 /* Set track range accurately if possible. */
1545 track_t i_last_track = cdio_get_last_track_num(p_cdio);
1546 disc_title->SetRange( 0, i_last_track-1 );
1548 cdio_destroy(p_cdio);
1553 b_probed_VCD = true;
1555 /* Not a VCD. Try for a DVD unless we've been there before. */
1556 if( !b_probed_DVD && (psz_device = ProbeDVD(disc_device->GetValue())) )
1558 disc_type->SetSelection(SELECTION_DISC_TYPE_DVD_MENUS);
1559 OnDiscTypeChange( dummy_event );
1562 b_probed_DVD = true;
1564 /* Couldn't find a VCD or DVD. See if we can find a CD-DA. */
1565 psz_device = ProbeCDDA(disc_device->GetValue());
1568 disc_type->SetSelection(SELECTION_DISC_TYPE_CDDA);
1569 OnDiscTypeChange( dummy_event );
1573 /* Couldn't find a VCD, DVD or CD-DA. Null out the Device name and
1574 set to original selection.
1576 disc_device->SetValue( wxL2U("") );
1577 disc_type->SetSelection(i_selection);
1578 OnDiscTypeChange( dummy_event );
1581 case SELECTION_DISC_TYPE_CDDA:
1582 if(!psz_device) psz_device = ProbeCDDA(disc_device->GetValue());
1585 CdIo_t *p_cdio = cdio_open (psz_device, DRIVER_UNKNOWN);
1586 disc_device->SetValue( wxL2U(psz_device) );
1589 track_t i_last_track = cdio_get_last_track_num(p_cdio);
1590 disc_title->SetRange( 0, i_last_track );
1592 MediaInsertCDDA( p_intf, p_cdio, i_last_track );
1595 cdio_destroy(p_cdio);
1599 /* Not a CD-DA. Try for a DVD unless we've been there before. */
1600 if( !b_probed_DVD && (psz_device = ProbeDVD(disc_device->GetValue())) )
1602 disc_type->SetSelection(SELECTION_DISC_TYPE_DVD_MENUS);
1603 OnDiscTypeChange( dummy_event );
1607 /* Couldn't find a CD-DA or DVD. See if we can find a VCD, unless
1608 we've tried that before. */
1609 if (!b_probed_VCD) psz_device = ProbeVCD(disc_device->GetValue());
1612 disc_type->SetSelection(SELECTION_DISC_TYPE_VCD);
1613 OnDiscTypeChange( dummy_event );
1616 disc_device->SetValue( wxL2U("") );
1620 msg_Err( p_intf, "invalid Disc type selection (%d)",
1621 disc_type->GetSelection() );
1626 disc_probe->SetValue(FALSE);
1628 UpdateMRL( DISC_ACCESS );
1630 #endif /* HAVE_LIBCDIO */
1632 void OpenDialog::OnDiscTypeChange( wxCommandEvent& WXUNUSED(event) )
1634 char *psz_device = NULL;
1636 switch( disc_type->GetSelection() )
1639 case SELECTION_DISC_TYPE_DVD_MENUS:
1640 case SELECTION_DISC_TYPE_DVD:
1641 disc_sub->Enable(); disc_sub_label->Enable();
1642 disc_audio->Enable(); disc_audio_label->Enable();
1643 disc_chapter->Enable(); disc_chapter_label->Enable();
1644 disc_title_label->SetLabel ( wxU(_("Title")) );
1645 psz_device = config_GetPsz( p_intf, "dvd" );
1646 if( !b_disc_device_changed )
1648 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1649 else disc_device->SetValue( wxT("") );
1651 disc_title->SetRange( 0, 255 );
1652 disc_sub->SetRange( -1, 31 ); // up to 32 subtitles -1: no subtitle
1653 disc_audio->SetRange( 0, 7 ); // up to 8 audio channels
1654 disc_chapter->SetRange( 0, 255 );
1655 disc_title->SetToolTip( wxU(_("Title number.")) );
1656 disc_sub->SetToolTip( wxU(_(
1657 "DVDs can have up to 32 subtitles numbered 0..31. "
1658 "Note this is not the same thing as a subtitle name (e.g. 'en'). "
1659 "If a value -1 is used, no subtitle will be shown." )) );
1660 disc_audio->SetToolTip( wxU(_("Audio track number. "
1661 "DVDs can have up to 8 audio tracks numbered 0..7."
1665 case SELECTION_DISC_TYPE_VCD:
1666 disc_sub->Enable(); disc_sub_label->Enable();
1667 disc_audio->Enable(); disc_audio_label->Enable();
1668 disc_chapter->Disable(); disc_chapter_label->Disable();
1669 psz_device = config_GetPsz( p_intf, "vcd" );
1670 if( !b_disc_device_changed )
1672 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1673 else disc_device->SetValue( wxT("") );
1677 if (config_GetInt( p_intf, "vcdx-PBC" ))
1679 disc_title_label->SetLabel ( wxT("Playback LID") );
1680 disc_title->SetToolTip( wxU(_(
1681 "Playback control (PBC) usually starts with number 1." )) );
1685 disc_title_label->SetLabel ( wxT("Entry") );
1686 disc_title->SetToolTip( wxU(_(
1687 "The first entry (the beginning of the first MPEG track) is 0." )) );
1691 disc_title_label->SetLabel ( wxU(_("Track")) );
1692 disc_title->SetToolTip( wxU(_("Track number.")) );
1694 disc_title->SetRange( 0, 99 ); // only 100 tracks allowed on VCDs
1695 disc_sub->SetRange( -1, 3 ); // up to 4 subtitles -1 = no subtitle
1696 disc_audio->SetRange( 0, 1 ); // up to 2 audio tracks
1697 disc_sub->SetToolTip( wxU(_(
1698 "SVCDs can have up to 4 subtitles numbered 0..3. "
1699 "If a value -1 is used, no subtitle will be shown." )) );
1700 disc_audio->SetToolTip( wxU(_("Audio track number. "
1701 "VCDs can have up to 2 audio tracks numbered 0 or 1. "
1705 case SELECTION_DISC_TYPE_CDDA:
1706 disc_sub->Disable(); disc_sub_label->Disable();
1707 disc_chapter->Disable(); disc_chapter_label->Disable();
1708 disc_audio->Disable(); disc_audio_label->Disable();
1709 disc_title_label->SetLabel ( wxU(_("Track")) );
1711 disc_title->SetToolTip( wxU(_(
1712 "Audio CDs can have up to 100 tracks, the first track is usually 1. "
1713 "If 0 is given, then all tracks are played.")) );
1715 disc_title->SetToolTip( wxU(_(
1716 "Audio CDs can have up to 100 tracks, the first track is usually 1."
1719 psz_device = config_GetPsz( p_intf, "cd-audio" );
1720 if( !b_disc_device_changed )
1722 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1723 else disc_device->SetValue( wxT("") );
1726 /* There are at most 100 tracks in a CD-DA */
1727 disc_title->SetRange( 0, 100 );
1731 msg_Err( p_intf, "invalid Disc type selection (%d)",
1732 disc_type->GetSelection() );
1736 disc_title->SetValue( 0 ); i_disc_title = 0;
1737 disc_chapter->SetValue( 0 ); i_disc_chapter = 0;
1741 UpdateMRL( DISC_ACCESS );
1744 /*****************************************************************************
1745 * Net panel event methods.
1746 *****************************************************************************/
1747 void OpenDialog::OnNetPanelChangeSpin( wxSpinEvent& event )
1749 wxCommandEvent cevent;
1750 cevent.SetId(event.GetId());
1751 cevent.SetInt(event.GetPosition());
1752 OnNetPanelChange(cevent);
1755 void OpenDialog::OnNetPanelChange( wxCommandEvent& event )
1757 if( event.GetId() >= NetPort1_Event && event.GetId() <= NetPort3_Event )
1759 i_net_ports[event.GetId() - NetPort1_Event] = event.GetInt();
1762 UpdateMRL( NET_ACCESS );
1765 void OpenDialog::OnNetTypeChange( wxCommandEvent& event )
1769 i_net_type = event.GetId() - NetRadio1_Event;
1773 net_radios[i]->SetValue( event.GetId() == (NetRadio1_Event+i) );
1774 net_subpanels[i]->Enable( event.GetId() == (NetRadio1_Event+i) );
1776 /* UDP Unicast or multicast -> timeshift */
1777 if( i_net_type == 0 || i_net_type == 1 )
1778 net_timeshift->Enable();
1780 net_timeshift->Disable();
1782 UpdateMRL( NET_ACCESS );
1785 /*****************************************************************************
1786 * Subtitles file event methods.
1787 *****************************************************************************/
1788 void OpenDialog::OnSubsFileEnable( wxCommandEvent& event )
1790 subsfile_button->Enable( event.GetInt() != 0 );
1791 subbrowse_button->Enable( event.GetInt() != 0 );
1792 subfile_combo->Enable( event.GetInt() != 0 );
1795 void OpenDialog::OnSubsFileSettings( wxCommandEvent& WXUNUSED(event) )
1797 /* Show/hide the open dialog */
1798 if( subsfile_dialog == NULL )
1799 subsfile_dialog = new SubsFileDialog( p_intf, this );
1801 if( subsfile_dialog && subsfile_dialog->ShowModal() == wxID_OK )
1803 subsfile_mrl.Empty();
1804 subsfile_mrl.Add( wxString(wxT("sub-file=")) + subfile_combo->GetValue() );
1805 if( subsfile_dialog->encoding_combo )
1807 subsfile_mrl.Add( wxString(wxT("subsdec-encoding=")) +
1808 subsfile_dialog->encoding_combo->GetValue() );
1810 if( subsfile_dialog->align_combo )
1812 subsfile_mrl.Add( wxString::Format(wxT("subsdec-align=%i"),
1813 (int)subsfile_dialog->align_combo->GetClientData(
1814 subsfile_dialog->align_combo->GetSelection()) ) );
1816 if( subsfile_dialog->size_combo )
1818 subsfile_mrl.Add( wxString::Format( wxT("freetype-rel-fontsize=%i"),
1819 (int)subsfile_dialog->size_combo->GetClientData(
1820 subsfile_dialog->size_combo->GetSelection()) ) );
1822 subsfile_mrl.Add( wxString( wxT("sub-fps="))+
1823 subsfile_dialog->fps_ctrl->GetValue() );
1824 subsfile_mrl.Add( wxString::Format( wxT("sub-delay=%i"),
1825 subsfile_dialog->delay_spinctrl->GetValue() ) );
1829 /*****************************************************************************
1830 * Stream output event methods.
1831 *****************************************************************************/
1832 void OpenDialog::OnSoutEnable( wxCommandEvent& event )
1834 sout_button->Enable( event.GetInt() != 0 );
1837 void OpenDialog::OnSoutSettings( wxCommandEvent& WXUNUSED(event) )
1839 /* Show/hide the open dialog */
1840 if( sout_dialog == NULL )
1841 sout_dialog = new SoutDialog( p_intf, this );
1843 if( sout_dialog && sout_dialog->ShowModal() == wxID_OK )
1845 sout_mrl = sout_dialog->GetOptions();
1849 /*****************************************************************************
1850 * Caching event methods.
1851 *****************************************************************************/
1852 void OpenDialog::OnCachingEnable( wxCommandEvent& event )
1854 caching_value->Enable( event.GetInt() != 0 );
1855 i_caching = caching_value->GetValue();
1859 void OpenDialog::OnCachingChangeSpin( wxSpinEvent& event )
1861 wxCommandEvent cevent;
1862 OnCachingChange(cevent);
1865 void OpenDialog::OnCachingChange( wxCommandEvent& event )
1867 i_caching = event.GetInt();
1871 /*****************************************************************************
1872 * Utility functions.
1873 *****************************************************************************/
1874 wxArrayString SeparateEntries( wxString entries )
1876 bool b_quotes_mode = false;
1878 wxArrayString entries_array;
1881 wxStringTokenizer token( entries, wxT(" \t\r\n\""), wxTOKEN_RET_DELIMS );
1883 while( token.HasMoreTokens() )
1885 entry += token.GetNextToken();
1887 if( entry.IsEmpty() ) continue;
1889 if( !b_quotes_mode && entry.Last() == wxT('\"') )
1891 /* Enters quotes mode */
1893 b_quotes_mode = true;
1895 else if( b_quotes_mode && entry.Last() == wxT('\"') )
1897 /* Finished the quotes mode */
1899 b_quotes_mode = false;
1901 else if( !b_quotes_mode && entry.Last() != wxT('\"') )
1903 /* we found a non-quoted standalone string */
1904 if( token.HasMoreTokens() ||
1905 entry.Last() == wxT(' ') || entry.Last() == wxT('\t') ||
1906 entry.Last() == wxT('\r') || entry.Last() == wxT('\n') )
1908 if( !entry.IsEmpty() ) entries_array.Add( entry );
1915 if( !entry.IsEmpty() ) entries_array.Add( entry );
1917 return entries_array;