1 /*****************************************************************************
2 * open.cpp : wxWindows plugin for vlc
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., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
27 #include <stdlib.h> /* malloc(), free() */
28 #include <errno.h> /* ENOMEM */
29 #include <string.h> /* strerror() */
35 #include <cdio/cdio.h>
36 #include <cdio/cd_types.h>
37 #include <cdio/logging.h>
38 #endif /* HAVE_LIBCDIO */
41 #include <libvcd/version.h>
42 /* There was a bug in libvcdinfo <= 23 which prevented C++ compilation */
43 #if LIBVCD_VERSION_NUM > 23
44 #include <libvcd/info.h>
45 #endif /* LIBVCD_VERSION_NUM > 23 */
46 #endif /* HAVE_VCDINFO */
48 #include <wx/combobox.h>
49 #include <wx/statline.h>
50 #include <wx/tokenzr.h>
56 #include "wxwidgets.h"
57 #include "preferences_widgets.h"
60 # define wxRB_SINGLE 0
63 #define SELECTION_DISC_TYPE_DVD_MENUS 0
64 #define SELECTION_DISC_TYPE_DVD 1
65 #define SELECTION_DISC_TYPE_VCD 2
66 #define SELECTION_DISC_TYPE_CDDA 3
68 /*****************************************************************************
70 *****************************************************************************/
72 /* IDs for the controls and the menu commands */
75 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)
122 /* Events generated by the disc panel */
123 EVT_RADIOBOX(DiscType_Event, OpenDialog::OnDiscTypeChange)
125 EVT_CHECKBOX(DiscProbe_Event, OpenDialog::OnDiscProbe)
127 EVT_TEXT(DiscDevice_Event, OpenDialog::OnDiscDeviceChange)
128 EVT_TEXT(DiscDevice_Event, OpenDialog::OnDiscPanelChange)
129 EVT_TEXT(DiscTitle_Event, OpenDialog::OnDiscPanelChange)
130 EVT_SPINCTRL(DiscTitle_Event, OpenDialog::OnDiscPanelChangeSpin)
131 EVT_TEXT(DiscChapter_Event, OpenDialog::OnDiscPanelChange)
132 EVT_SPINCTRL(DiscChapter_Event, OpenDialog::OnDiscPanelChangeSpin)
133 EVT_TEXT(DiscSub_Event, OpenDialog::OnDiscPanelChange)
134 EVT_TEXT(DiscAudio_Event, OpenDialog::OnDiscPanelChange)
135 EVT_SPINCTRL(DiscSub_Event, OpenDialog::OnDiscPanelChangeSpin)
137 /* Events generated by the net panel */
138 EVT_RADIOBUTTON(NetRadio1_Event, OpenDialog::OnNetTypeChange)
139 EVT_RADIOBUTTON(NetRadio2_Event, OpenDialog::OnNetTypeChange)
140 EVT_RADIOBUTTON(NetRadio3_Event, OpenDialog::OnNetTypeChange)
141 EVT_RADIOBUTTON(NetRadio4_Event, OpenDialog::OnNetTypeChange)
142 EVT_TEXT(NetPort1_Event, OpenDialog::OnNetPanelChange)
143 EVT_SPINCTRL(NetPort1_Event, OpenDialog::OnNetPanelChangeSpin)
144 EVT_TEXT(NetPort2_Event, OpenDialog::OnNetPanelChange)
145 EVT_SPINCTRL(NetPort2_Event, OpenDialog::OnNetPanelChangeSpin)
146 EVT_TEXT(NetPort3_Event, OpenDialog::OnNetPanelChange)
147 EVT_SPINCTRL(NetPort3_Event, OpenDialog::OnNetPanelChangeSpin)
148 EVT_TEXT(NetAddr2_Event, OpenDialog::OnNetPanelChange)
149 EVT_TEXT(NetAddr3_Event, OpenDialog::OnNetPanelChange)
150 EVT_TEXT(NetAddr4_Event, OpenDialog::OnNetPanelChange)
151 EVT_CHECKBOX(NetForceIPv6_Event, OpenDialog::OnNetPanelChange)
152 EVT_CHECKBOX(NetTimeshift_Event, OpenDialog::OnNetPanelChange)
154 /* Events generated by the subtitle file buttons */
155 EVT_CHECKBOX(SubsFileEnable_Event, OpenDialog::OnSubsFileEnable)
156 EVT_BUTTON(SubsFileSettings_Event, OpenDialog::OnSubsFileSettings)
158 /* Events generated by the stream output buttons */
159 EVT_CHECKBOX(SoutEnable_Event, OpenDialog::OnSoutEnable)
160 EVT_BUTTON(SoutSettings_Event, OpenDialog::OnSoutSettings)
162 /* Events generated by the caching button */
163 EVT_CHECKBOX(CachingEnable_Event, OpenDialog::OnCachingEnable)
164 EVT_TEXT(CachingChange_Event, OpenDialog::OnCachingChange)
165 EVT_SPINCTRL(CachingChange_Event, OpenDialog::OnCachingChangeSpin)
167 /* Hide the window when the user closes the window */
168 EVT_CLOSE(OpenDialog::OnClose)
173 /* Perhaps someday we'll figure out how to add media information to
174 "Stream-and-Media info" when no input thread hasn't been initialized.
176 extern void MediaInsertCDDA( intf_thread_t *_p_intf, CdIo_t *p_cdio,
177 track_t i_last_track );
180 /*****************************************************************************
182 *****************************************************************************/
183 WX_DEFINE_ARRAY(ConfigControl *, ArrayOfConfigControls);
185 class AutoBuiltPanel : public wxPanel
190 AutoBuiltPanel( wxWindow *, OpenDialog *, intf_thread_t *,
193 virtual ~AutoBuiltPanel() {}
195 void UpdateAdvancedMRL();
198 ArrayOfConfigControls config_array;
199 ArrayOfConfigControls advanced_config_array;
200 wxComboBox *p_advanced_mrl_combo;
203 intf_thread_t *p_intf;
204 OpenDialog *p_open_dialog;
206 void OnAdvanced( wxCommandEvent& event );
207 wxDialog *p_advanced_dialog;
209 DECLARE_EVENT_TABLE();
212 BEGIN_EVENT_TABLE(AutoBuiltPanel, wxPanel)
213 EVT_BUTTON(AdvancedOptions_Event, AutoBuiltPanel::OnAdvanced)
216 static void AutoBuildCallback( void *p_data )
218 ((OpenDialog *)p_data)->UpdateMRL();
221 static void AutoBuildAdvancedCallback( void *p_data )
223 ((AutoBuiltPanel *)p_data)->UpdateAdvancedMRL();
226 AutoBuiltPanel::AutoBuiltPanel( wxWindow *parent, OpenDialog *dialog,
227 intf_thread_t *_p_intf,
228 const module_t *p_module )
229 : wxPanel( parent, -1, wxDefaultPosition, wxDefaultSize ),
230 name( wxU(p_module->psz_object_name) ),
231 p_advanced_mrl_combo( NULL ),
232 p_intf( _p_intf ), p_open_dialog( dialog ), p_advanced_dialog( NULL )
234 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
235 module_config_t *p_item = p_module->p_config;
236 bool b_advanced = false;
240 if( !(p_item->i_type & CONFIG_HINT) && p_item->b_advanced )
243 if( p_item->i_type & CONFIG_HINT || p_item->b_advanced )
246 ConfigControl *control =
247 CreateConfigControl( VLC_OBJECT(p_intf), p_item, this );
249 config_array.Add( control );
251 /* Don't add items that were not recognized */
252 if( control == NULL ) continue;
254 control->SetUpdateCallback( AutoBuildCallback, (void *)dialog );
256 sizer->Add( control, 0, wxEXPAND | wxALL, 2 );
258 while( p_item->i_type != CONFIG_HINT_END && p_item++ );
263 new wxButton( this, AdvancedOptions_Event,
264 wxU(_("Advanced options...")) );
265 sizer->Add( button, 0, wxALL, 5 );
267 /* Build the advanced dialog */
269 new wxDialog( this, -1, ((wxString)wxU(_("Advanced options"))) +
270 wxT(" (") + wxU( p_module->psz_longname ) + wxT(")"),
271 wxDefaultPosition, wxDefaultSize,
272 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER );
274 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
276 /* Create MRL combobox */
277 wxBoxSizer *mrl_sizer_sizer = new wxBoxSizer( wxHORIZONTAL );
278 wxStaticBox *mrl_box =
279 new wxStaticBox( p_advanced_dialog, -1,
280 wxU(_("Advanced options")) );
281 wxStaticBoxSizer *mrl_sizer =
282 new wxStaticBoxSizer( mrl_box, wxHORIZONTAL );
283 wxStaticText *mrl_label =
284 new wxStaticText( p_advanced_dialog, -1, wxU(_("Options:")) );
285 p_advanced_mrl_combo =
286 new wxComboBox( p_advanced_dialog, MRL_Event, wxT(""),
287 wxDefaultPosition, wxDefaultSize );
288 mrl_sizer->Add( mrl_label, 0, wxALL | wxALIGN_CENTER, 5 );
289 mrl_sizer->Add( p_advanced_mrl_combo, 1, wxALL | wxALIGN_CENTER, 5 );
290 mrl_sizer_sizer->Add( mrl_sizer, 1, wxEXPAND | wxALL, 5 );
291 sizer->Add( mrl_sizer_sizer, 0, wxEXPAND | wxALL, 2 );
293 /* Add advanced options to panel */
294 module_config_t *p_item = p_module->p_config;
297 if( p_item->i_type & CONFIG_HINT || !p_item->b_advanced )
300 ConfigControl *control =
301 CreateConfigControl( VLC_OBJECT(p_intf), p_item,
304 advanced_config_array.Add( control );
306 /* Don't add items that were not recognized */
307 if( control == NULL ) continue;
309 control->SetUpdateCallback( AutoBuildAdvancedCallback,
312 sizer->Add( control, 0, wxEXPAND | wxALL, 2 );
314 while( p_item->i_type != CONFIG_HINT_END && p_item++ );
317 wxPanel *dummy_panel = new wxPanel( p_advanced_dialog, -1 );
318 sizer->Add( dummy_panel, 1 );
319 wxStaticLine *static_line =
320 new wxStaticLine( p_advanced_dialog, wxID_OK );
321 sizer->Add( static_line, 0, wxEXPAND | wxALL, 5 );
324 wxButton *ok_button =
325 new wxButton( p_advanced_dialog, wxID_OK, wxU(_("OK")) );
326 ok_button->SetDefault();
327 wxButton *cancel_button =
328 new wxButton( p_advanced_dialog, wxID_CANCEL, wxU(_("Cancel")) );
329 wxBoxSizer *button_sizer = new wxBoxSizer( wxHORIZONTAL );
330 button_sizer->Add( ok_button, 0, wxALL, 5 );
331 button_sizer->Add( cancel_button, 0, wxALL, 5 );
332 button_sizer->Layout();
333 sizer->Add( button_sizer, 0, wxALL, 0 );
335 sizer->SetMinSize( 400, -1 );
336 p_advanced_dialog->SetSizerAndFit( sizer );
339 this->SetSizerAndFit( sizer );
342 void AutoBuiltPanel::OnAdvanced( wxCommandEvent& event )
344 if( p_advanced_dialog->ShowModal() == wxID_OK )
347 p_open_dialog->UpdateMRL();
351 void AutoBuiltPanel::UpdateAdvancedMRL()
355 for( int i = 0; i < (int)advanced_config_array.GetCount(); i++ )
357 ConfigControl *control = advanced_config_array.Item(i);
359 mrltemp += (i ? wxT(" :") : wxT(":"));
361 if( control->GetType() == CONFIG_ITEM_BOOL &&
362 !control->GetIntValue() ) mrltemp += wxT("no-");
364 mrltemp += control->GetName();
366 switch( control->GetType() )
368 case CONFIG_ITEM_STRING:
369 case CONFIG_ITEM_FILE:
370 case CONFIG_ITEM_DIRECTORY:
371 case CONFIG_ITEM_MODULE:
372 mrltemp += wxT("=\"") + control->GetPszValue() + wxT("\"");
374 case CONFIG_ITEM_INTEGER:
376 wxString::Format( wxT("=%i"), control->GetIntValue() );
378 case CONFIG_ITEM_FLOAT:
380 wxString::Format(wxT("=%f"), control->GetFloatValue());
385 p_advanced_mrl_combo->SetValue( mrltemp );
388 /*****************************************************************************
390 *****************************************************************************/
391 OpenDialog::OpenDialog( intf_thread_t *_p_intf, wxWindow *_p_parent,
392 int i_access_method, int i_arg ):
393 wxDialog( _p_parent, -1, wxU(_("Open...")), wxDefaultPosition,
394 wxDefaultSize, wxDEFAULT_FRAME_STYLE )
396 OpenDialog( _p_intf, _p_parent, i_access_method, i_arg, OPEN_NORMAL );
399 OpenDialog::OpenDialog( intf_thread_t *_p_intf, wxWindow *_p_parent,
400 int i_access_method, int i_arg, int _i_method ):
401 wxDialog( _p_parent, -1, wxU(_("Open...")), wxDefaultPosition,
402 wxDefaultSize, wxDEFAULT_FRAME_STYLE )
404 /* Initializations */
405 i_method = _i_method;
407 p_parent = _p_parent;
408 SetIcon( *p_intf->p_sys->p_icon );
410 i_disc_type_selection = 0;
415 subsfile_dialog = NULL;
416 b_disc_device_changed = false;
418 /* Create a panel to put everything in */
419 wxPanel *panel = new wxPanel( this, -1 );
420 panel->SetAutoLayout( TRUE );
422 /* Create MRL combobox */
423 wxBoxSizer *mrl_sizer_sizer = new wxBoxSizer( wxHORIZONTAL );
424 wxStaticBox *mrl_box = new wxStaticBox( panel, -1,
425 wxU(_("Media Resource Locator (MRL)")) );
426 wxStaticBoxSizer *mrl_sizer = new wxStaticBoxSizer( mrl_box,
428 wxStaticText *mrl_label = new wxStaticText( panel, -1,
430 mrl_combo = new wxComboBox( panel, MRL_Event, wxT(""),
431 wxPoint(20,25), wxSize(120, -1) );
432 mrl_combo->SetToolTip( wxU(_("You can use this field directly by typing "
433 "the full MRL you want to open.\n""Alternatively, the field will be "
434 "filled automatically when you use the controls below.")) );
436 mrl_sizer->Add( mrl_label, 0, wxALL | wxALIGN_CENTER, 5 );
437 mrl_sizer->Add( mrl_combo, 1, wxALL | wxALIGN_CENTER, 5 );
438 mrl_sizer_sizer->Add( mrl_sizer, 1, wxEXPAND | wxALL, 5 );
441 /* Create Static Text */
442 wxStaticText *label = new wxStaticText( panel, -1,
443 wxU(_("Alternatively, you can build an MRL using one of the "
444 "following predefined targets:")) );
446 wxFlexGridSizer *common_opt_sizer = new wxFlexGridSizer( 5, 1, 20 );
448 if( i_method == OPEN_NORMAL )
450 /* Create Stream Output checkox */
451 sout_checkbox = new wxCheckBox( panel, SoutEnable_Event,
452 wxU(_("Stream output")) );
453 sout_checkbox->SetToolTip( wxU(_("Use VLC as a server of streams")) );
454 common_opt_sizer->Add( sout_checkbox, 0,
455 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
457 sout_button = new wxButton( panel, SoutSettings_Event,
458 wxU(_("Settings...")) );
459 sout_button->Disable();
461 char *psz_sout = config_GetPsz( p_intf, "sout" );
462 if( psz_sout && *psz_sout )
464 sout_checkbox->SetValue(TRUE);
465 sout_button->Enable();
466 subsfile_mrl.Add( wxString(wxT("sout=")) + wxL2U(psz_sout) );
468 if( psz_sout ) free( psz_sout );
470 common_opt_sizer->Add( sout_button, 1, wxALIGN_LEFT |
471 wxALIGN_CENTER_VERTICAL );
473 common_opt_sizer->Add( new wxPanel( this, -1 ), 1,
474 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
477 /* Create caching options */
478 caching_checkbox = new wxCheckBox( panel, CachingEnable_Event,
480 caching_checkbox->SetToolTip( wxU(_("Change the default caching value "
481 "(in milliseconds)")) );
482 common_opt_sizer->Add( caching_checkbox, 0,
483 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
484 caching_value = new wxSpinCtrl( panel, CachingChange_Event );
485 caching_value->SetRange( 0, 1000000 );
486 caching_value->Disable();
487 common_opt_sizer->Add( caching_value, 0,
488 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
491 wxStaticLine *static_line = new wxStaticLine( panel, wxID_OK );
493 /* Create the buttons */
494 wxButton *ok_button = new wxButton( panel, wxID_OK, wxU(_("OK")) );
495 ok_button->SetDefault();
496 wxButton *cancel_button = new wxButton( panel, wxID_CANCEL,
499 /* Create notebook */
500 notebook = new wxNotebook( panel, Notebook_Event );
502 #if (!wxCHECK_VERSION(2,5,0))
503 wxNotebookSizer *notebook_sizer = new wxNotebookSizer( notebook );
506 notebook->AddPage( FilePanel( notebook ), wxU(_("File")),
507 i_access_method == FILE_ACCESS );
508 notebook->AddPage( DiscPanel( notebook ), wxU(_("Disc")),
509 i_access_method == DISC_ACCESS );
510 notebook->AddPage( NetPanel( notebook ), wxU(_("Network")),
511 i_access_method == NET_ACCESS );
513 module_t *p_module = config_FindModule( VLC_OBJECT(p_intf), "v4l" );
516 AutoBuiltPanel *autopanel =
517 new AutoBuiltPanel( notebook, this, p_intf, p_module );
518 input_tab_array.Add( autopanel );
519 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
520 p_module->psz_shortname : p_module->psz_object_name ),
521 i_access_method == CAPTURE_ACCESS );
524 p_module = config_FindModule( VLC_OBJECT(p_intf), "pvr" );
527 AutoBuiltPanel *autopanel =
528 new AutoBuiltPanel( notebook, this, p_intf, p_module );
529 input_tab_array.Add( autopanel );
530 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
531 p_module->psz_shortname : p_module->psz_object_name ),
532 i_access_method == CAPTURE_ACCESS );
535 p_module = config_FindModule( VLC_OBJECT(p_intf), "dvb" );
538 AutoBuiltPanel *autopanel =
539 new AutoBuiltPanel( notebook, this, p_intf, p_module );
540 input_tab_array.Add( autopanel );
541 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
542 p_module->psz_shortname : p_module->psz_object_name ),
543 i_access_method == CAPTURE_ACCESS );
546 p_module = config_FindModule( VLC_OBJECT(p_intf), "dshow" );
549 AutoBuiltPanel *autopanel =
550 new AutoBuiltPanel( notebook, this, p_intf, p_module );
551 input_tab_array.Add( autopanel );
552 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
553 p_module->psz_shortname : p_module->psz_object_name ),
554 i_access_method == CAPTURE_ACCESS );
557 /* Update Disc panel */
558 wxCommandEvent dummy_event;
559 OnDiscTypeChange( dummy_event );
561 /* Update Net panel */
562 dummy_event.SetId( NetRadio1_Event );
563 OnNetTypeChange( dummy_event );
566 wxNotebookEvent event( wxEVT_NULL, 0, i_access_method );
567 OnPageChange( event );
569 /* Place everything in sizers */
570 wxBoxSizer *button_sizer = new wxBoxSizer( wxHORIZONTAL );
571 button_sizer->Add( ok_button, 0, wxALL, 5 );
572 button_sizer->Add( cancel_button, 0, wxALL, 5 );
573 button_sizer->Layout();
574 wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL );
575 wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
576 panel_sizer->Add( mrl_sizer_sizer, 0, wxEXPAND, 5 );
577 panel_sizer->Add( label, 0, wxEXPAND | wxALL, 5 );
578 #if (!wxCHECK_VERSION(2,5,0))
579 panel_sizer->Add( notebook_sizer, 1, wxEXPAND | wxALL, 5 );
581 panel_sizer->Add( notebook, 1, wxEXPAND | wxALL, 5 );
583 panel_sizer->Add( common_opt_sizer, 0, wxALIGN_LEFT | wxALL, 5 );
584 panel_sizer->Add( static_line, 0, wxEXPAND | wxALL, 5 );
585 panel_sizer->Add( button_sizer, 0, wxALIGN_LEFT | wxALL, 5 );
586 panel_sizer->Layout();
587 panel->SetSizerAndFit( panel_sizer );
588 main_sizer->Add( panel, 1, wxGROW, 0 );
589 main_sizer->Layout();
590 SetSizerAndFit( main_sizer );
593 OpenDialog::~OpenDialog()
596 if( file_dialog ) delete file_dialog;
597 if( sout_dialog ) delete sout_dialog;
598 if( subsfile_dialog ) delete subsfile_dialog;
601 int OpenDialog::Show( int i_access_method, int i_arg )
603 notebook->SetSelection( i_access_method );
604 int i_ret = wxDialog::Show();
611 int OpenDialog::Show()
613 int i_ret = wxDialog::Show();
619 /*****************************************************************************
621 *****************************************************************************/
622 wxPanel *OpenDialog::FilePanel( wxWindow* parent )
624 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
627 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
629 /* Create browse file line */
630 wxBoxSizer *file_sizer = new wxBoxSizer( wxHORIZONTAL );
632 file_combo = new wxComboBox( panel, FileName_Event, wxT(""),
633 wxPoint(20,25), wxSize(200, -1) );
634 wxButton *browse_button = new wxButton( panel, FileBrowse_Event,
635 wxU(_("Browse...")) );
636 file_sizer->Add( file_combo, 1, wxALL, 5 );
637 file_sizer->Add( browse_button, 0, wxALL, 5 );
639 /* Create Subtitles File checkox */
640 wxFlexGridSizer *subsfile_sizer = new wxFlexGridSizer( 2, 1, 20 );
641 subsfile_checkbox = new wxCheckBox( panel, SubsFileEnable_Event,
642 wxU(_("Subtitle options")) );
643 subsfile_checkbox->SetToolTip( wxU(_("Force options for separate subtitle files.")) );
644 subsfile_sizer->Add( subsfile_checkbox, 0,
645 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
646 subsfile_button = new wxButton( panel, SubsFileSettings_Event,
647 wxU(_("Settings...")) );
648 subsfile_button->Disable();
650 char *psz_subsfile = config_GetPsz( p_intf, "sub-file" );
651 if( psz_subsfile && *psz_subsfile )
653 subsfile_checkbox->SetValue(TRUE);
654 subsfile_button->Enable();
655 subsfile_mrl.Add( wxString(wxT("sub-file=")) + wxL2U(psz_subsfile) );
657 if( psz_subsfile ) free( psz_subsfile );
659 subsfile_sizer->Add( subsfile_button, 1,
660 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
662 sizer->Add( file_sizer, 0, wxEXPAND | wxALL, 5 );
663 sizer->Add( subsfile_sizer, 0, wxEXPAND | wxALL, 5 );
664 panel->SetSizerAndFit( sizer );
668 wxPanel *OpenDialog::DiscPanel( wxWindow* parent )
670 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
673 wxBoxSizer *sizer_row = new wxBoxSizer( wxVERTICAL );
674 wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 3, 20 );
676 static const wxString disc_type_array[] =
678 wxU(_("DVD (menus)")),
684 disc_type = new wxRadioBox( panel, DiscType_Event, wxU(_("Disc type")),
685 wxDefaultPosition, wxDefaultSize,
686 WXSIZEOF(disc_type_array), disc_type_array,
687 WXSIZEOF(disc_type_array), wxRA_SPECIFY_COLS );
690 disc_probe = new wxCheckBox( panel, DiscProbe_Event,
691 wxU(_("Probe Disc(s)")) );
692 disc_probe->SetToolTip( wxU(_("Probe for a DVD, VCD or audio CD. "
693 "First try the Device name entered for the selected Disc type "
694 "(DVD, DVD Menu, VCD, audio CD). If that doesn't find media, try any device "
695 "for the Disc type. If that doesn't work, then try looking for CD-ROMs or "
696 "DVD drives. The Disc type, Device name, and some parameter ranges are set "
697 "based on media we find.")) );
700 sizer_row->Add( disc_type, i_disc_type_selection, wxEXPAND | wxALL, 5 );
702 sizer_row->Add( disc_probe, 0, wxEXPAND | wxALL );
705 wxStaticText *label = new wxStaticText( panel, -1, wxU(_("Device name")) );
706 disc_device = new wxTextCtrl( panel, DiscDevice_Event, wxT(""),
707 wxDefaultPosition, wxDefaultSize,
710 sizer->Add( label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
711 sizer->Add( disc_device, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
713 disc_title_label = new wxStaticText( panel, -1, wxU(_("Title")) );
714 disc_title = new wxSpinCtrl( panel, DiscTitle_Event );
715 sizer->Add( disc_title_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
716 sizer->Add( disc_title, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
718 disc_chapter_label = new wxStaticText( panel, -1, wxU(_("Chapter")) );
719 disc_chapter = new wxSpinCtrl( panel, DiscChapter_Event );
720 sizer->Add( disc_chapter_label, 0,
721 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
722 sizer->Add( disc_chapter, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
724 disc_sub_label = new wxStaticText( panel, -1, wxU(_("Subtitles track")) );
725 disc_sub = new wxSpinCtrl( panel, DiscSub_Event );
726 sizer->Add( disc_sub_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
727 sizer->Add( disc_sub, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
728 disc_sub->SetRange( -1, 255 );
729 i_disc_sub = config_GetInt( p_intf, "sub-track" );
730 disc_sub->SetValue( i_disc_sub );
732 disc_audio_label = new wxStaticText( panel, -1, wxU(_("Audio track")) );
733 disc_audio = new wxSpinCtrl( panel, DiscAudio_Event );
734 sizer->Add( disc_audio_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
735 sizer->Add( disc_audio, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
736 disc_audio->SetRange( -1, 255 );
737 i_disc_audio = config_GetInt( p_intf, "audio-track" );
738 disc_audio->SetValue( i_disc_audio );
740 sizer_row->Add( sizer, 0, wxEXPAND | wxALL, 5 );
742 panel->SetSizerAndFit( sizer_row );
746 wxPanel *OpenDialog::NetPanel( wxWindow* parent )
749 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
752 wxBoxSizer *sizer_row = new wxBoxSizer( wxVERTICAL );
753 wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 4, 20 );
755 static const wxString net_type_array[] =
758 wxU(_("UDP/RTP Multicast")),
759 wxU(_("HTTP/HTTPS/FTP/MMS")),
765 net_radios[i] = new wxRadioButton( panel, NetRadio1_Event + i,
767 wxDefaultPosition, wxDefaultSize,
770 net_subpanels[i] = new wxPanel( panel, -1,
771 wxDefaultPosition, wxDefaultSize );
775 net_timeshift = new wxCheckBox( panel, NetTimeshift_Event,
776 wxU(_("Allow timeshifting")) );
779 wxFlexGridSizer *subpanel_sizer;
781 i_net_ports[0] = config_GetInt( p_intf, "server-port" );
782 subpanel_sizer = new wxFlexGridSizer( 3, 1, 20 );
783 label = new wxStaticText( net_subpanels[0], -1, wxU(_("Port")) );
784 net_ports[0] = new wxSpinCtrl( net_subpanels[0], NetPort1_Event,
785 wxString::Format(wxT("%d"), i_net_ports[0]),
786 wxDefaultPosition, wxDefaultSize,
788 0, 65535, i_net_ports[0] );
790 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
791 subpanel_sizer->Add( net_ports[0], 1,
792 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
793 net_ipv6 = new wxCheckBox( net_subpanels[0], NetForceIPv6_Event,
794 wxU(_("Force IPv6")));
795 subpanel_sizer->Add( net_ipv6, 0,
796 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
797 net_subpanels[0]->SetSizerAndFit( subpanel_sizer );
798 net_radios[0]->SetValue( TRUE );
800 /* UDP/RTP Multicast row */
801 subpanel_sizer = new wxFlexGridSizer( 4, 1, 20 );
802 label = new wxStaticText( net_subpanels[1], -1, wxU(_("Address")) );
803 net_addrs[1] = new wxTextCtrl( net_subpanels[1], NetAddr2_Event, wxT(""),
804 wxDefaultPosition, wxDefaultSize,
806 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
807 subpanel_sizer->Add( net_addrs[1], 1,
808 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
810 label = new wxStaticText( net_subpanels[1], -1, wxU(_("Port")) );
811 i_net_ports[1] = i_net_ports[0];
812 net_ports[1] = new wxSpinCtrl( net_subpanels[1], NetPort2_Event,
813 wxString::Format(wxT("%d"), i_net_ports[1]),
814 wxDefaultPosition, wxDefaultSize,
816 0, 65535, i_net_ports[1] );
818 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
819 subpanel_sizer->Add( net_ports[1], 1,
820 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
821 net_subpanels[1]->SetSizerAndFit( subpanel_sizer );
823 /* HTTP and RTSP rows */
826 subpanel_sizer = new wxFlexGridSizer( 2, 1, 20 );
827 label = new wxStaticText( net_subpanels[i], -1, wxU(_("URL")) );
828 net_addrs[i] = new wxTextCtrl( net_subpanels[i], NetAddr1_Event + i,
829 (i == 2) ? wxT("") : wxT("rtsp://"),
830 wxDefaultPosition, wxSize( 200, -1 ),
832 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
833 subpanel_sizer->Add( net_addrs[i], 1,
834 wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
835 net_subpanels[i]->SetSizerAndFit( subpanel_sizer );
838 /* Stuff everything into the main panel */
841 sizer->Add( net_radios[i], 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
843 sizer->Add( net_subpanels[i], 1, wxEXPAND | wxALIGN_LEFT |
844 wxALIGN_CENTER_VERTICAL | wxALL, 5 );
846 sizer->Add( net_timeshift, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
849 sizer_row->Add( sizer, 0, wxEXPAND | wxALL, 5 );
851 panel->SetSizerAndFit( sizer_row );
855 void OpenDialog::UpdateMRL()
857 UpdateMRL( i_current_access_method );
860 void OpenDialog::UpdateMRL( int i_access_method )
862 wxString mrltemp, caching_name;
864 i_current_access_method = i_access_method;
866 switch( i_access_method )
869 mrltemp = file_combo->GetValue();
870 caching_name = wxT("file-caching");
874 i_disc_type_selection = disc_type->GetSelection();
876 switch ( i_disc_type_selection )
878 case 0: /* DVD with menus */
879 case 1: /* DVD without menus */
880 disc_device->SetToolTip( wxU(_("Name of DVD device "
882 if( i_disc_type_selection == 0 )
884 mrltemp = wxT("dvd://") + disc_device->GetValue();
885 caching_name = wxT("dvdnav-caching");
889 mrltemp = wxT("dvdsimple://") + disc_device->GetValue();
890 caching_name = wxT("dvdread-caching");
893 if( i_disc_title > 0 )
895 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
897 if( i_disc_chapter > 0 )
898 mrltemp += wxString::Format( wxT(":%d"), i_disc_chapter );
901 if( i_disc_sub >= 0 )
902 mrltemp += wxString::Format( wxT(" :sub-track=%d"),
904 if( i_disc_audio >= 0 )
905 mrltemp += wxString::Format( wxT(" :audio-track=%d"),
909 case 2: /* VCD of some sort */
911 disc_device->SetToolTip( wxU(_("Name of CD-ROM device "
912 "to read Video CD from. If this field is left empty, we will scan "
913 "for a CD-ROM with a VCD in it.")) );
914 mrltemp = wxT("vcdx://") + disc_device->GetValue();
915 if( i_disc_title > 0 )
916 mrltemp += wxString::Format( wxT("@%c%d"),
917 config_GetInt( p_intf, "vcdx-PBC" )
918 ? 'P' : 'E', i_disc_title );
920 disc_device->SetToolTip( wxU(_("Name of CD-ROM device "
921 "to read Video CD from.")) );
922 mrltemp = wxT("vcd://") + disc_device->GetValue();
923 if( i_disc_title > 0 )
924 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
927 if( i_disc_sub >= 0 )
928 mrltemp += wxString::Format( wxT(" :sub-track=%d"),
931 if( i_disc_audio >= 0 )
932 mrltemp += wxString::Format( wxT(" :audio-track=%d"),
934 caching_name = wxT("vcd-caching");
939 disc_device->SetToolTip( wxU(_("Name of CD-ROM device "
940 "to read audio CD from. If this field is left empty, we will scan "
941 "for a CD-ROM with an audio CD in it." )) );
942 mrltemp = wxT("cddax://")
944 disc_device->SetToolTip( wxU(_("Name of CD-ROM device "
945 "to read audio CD from." )) );
946 mrltemp = wxT("cdda://")
948 + disc_device->GetValue();
949 if( i_disc_title > 0 )
950 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
952 caching_name = wxT("cdda-caching");
956 msg_Err( p_intf, "invalid selection (%d)",
957 disc_type->GetSelection() );
966 mrltemp = wxT("udp://@");
967 if ( net_ipv6->GetValue() )
969 mrltemp += wxT("[::]");
971 if( i_net_ports[0] !=
972 config_GetInt( p_intf, "server-port" ) )
974 mrltemp += wxString::Format( wxT(":%d"), i_net_ports[0] );
977 caching_name = wxT("udp-caching");
981 mrltemp = wxT("udp://@");
982 if ((net_addrs[1]->GetLineText(0).Find (':') != -1)
983 && (net_addrs[1]->GetLineText(0)[0u] != '['))
985 /* automatically adds '[' and ']' to IPv6 addresses */
986 mrltemp += wxT("[") + net_addrs[1]->GetLineText(0)
991 mrltemp += net_addrs[1]->GetLineText(0);
993 if( i_net_ports[1] != config_GetInt( p_intf, "server-port" ) )
995 mrltemp += wxString::Format( wxT(":%d"), i_net_ports[1] );
998 caching_name = wxT("udp-caching");
1003 if( net_addrs[2]->GetLineText(0).Find(wxT("://")) == -1 )
1004 mrltemp = wxT("http://");
1006 mrltemp += net_addrs[2]->GetLineText(0);
1008 caching_name = wxT("http-caching");
1013 if( net_addrs[3]->GetLineText(0).Find(wxT("rtsp://")) != 0 )
1015 mrltemp = wxT("rtsp://");
1017 mrltemp += net_addrs[3]->GetLineText(0);
1019 caching_name = wxT("rtsp-caching");
1022 if( net_timeshift->IsEnabled() && net_timeshift->IsChecked() )
1023 mrltemp += wxT(" :access-filter=timeshift");
1028 int i_item = i_access_method - MAX_ACCESS;
1030 if( i_item < 0 || i_item >= (int)input_tab_array.GetCount() )
1033 AutoBuiltPanel *input_panel = input_tab_array.Item( i_item );
1035 mrltemp = input_panel->name + wxT("://");
1037 for( int i=0; i < (int)input_panel->config_array.GetCount(); i++ )
1039 ConfigControl *control = input_panel->config_array.Item(i);
1041 mrltemp += wxT(" :");
1043 if( control->GetType() == CONFIG_ITEM_BOOL &&
1044 !control->GetIntValue() ) mrltemp += wxT("no-");
1046 mrltemp += control->GetName();
1048 switch( control->GetType() )
1050 case CONFIG_ITEM_STRING:
1051 case CONFIG_ITEM_FILE:
1052 case CONFIG_ITEM_DIRECTORY:
1053 case CONFIG_ITEM_MODULE:
1054 mrltemp += wxT("=\"") + control->GetPszValue() + wxT("\"");
1056 case CONFIG_ITEM_INTEGER:
1058 wxString::Format( wxT("=%i"), control->GetIntValue() );
1060 case CONFIG_ITEM_FLOAT:
1062 wxString::Format(wxT("=%f"), control->GetFloatValue());
1067 if( input_panel->p_advanced_mrl_combo &&
1068 input_panel->p_advanced_mrl_combo->GetValue() )
1070 mrltemp += wxT(" ") +
1071 input_panel->p_advanced_mrl_combo->GetValue();
1077 if( caching_name.size() )
1079 if( caching_value->IsEnabled() )
1081 mrltemp += wxT(" :") + caching_name +
1082 wxString::Format( wxT("=%d"), i_caching );
1086 int i_value = config_GetInt( p_intf, caching_name.mb_str() );
1087 caching_value->SetValue( i_value );
1091 mrl_combo->SetValue( mrltemp );
1094 /*****************************************************************************
1096 *****************************************************************************/
1097 void OpenDialog::OnOk( wxCommandEvent& WXUNUSED(event) )
1099 mrl = SeparateEntries( mrl_combo->GetValue() );
1100 mrl_combo->Append( mrl_combo->GetValue() );
1101 if( mrl_combo->GetCount() > 10 ) mrl_combo->Delete( 0 );
1102 mrl_combo->SetSelection( mrl_combo->GetCount() - 1 );
1104 if( i_method == OPEN_STREAM )
1106 if( IsModal() ) EndModal( wxID_OK );
1111 /* Update the playlist */
1112 playlist_t *p_playlist =
1113 (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
1115 if( p_playlist == NULL ) return;
1117 for( int i = 0; i < (int)mrl.GetCount(); i++ )
1119 vlc_bool_t b_start = !i && i_open_arg;
1120 playlist_item_t *p_item =
1121 playlist_ItemNew( p_intf, (const char*)mrl[i].mb_str(),
1122 (const char *)mrl[i].mb_str() );
1124 /* Insert options */
1125 while( i + 1 < (int)mrl.GetCount() &&
1126 ((const char *)mrl[i + 1].mb_str())[0] == ':' )
1128 playlist_ItemAddOption( p_item, mrl[i + 1].mb_str() );
1132 /* Get the options from the subtitles dialog */
1133 if( subsfile_checkbox->IsChecked() && subsfile_mrl.GetCount() )
1135 for( int j = 0; j < (int)subsfile_mrl.GetCount(); j++ )
1137 playlist_ItemAddOption( p_item, subsfile_mrl[j].mb_str() );
1141 /* Get the options from the stream output dialog */
1142 if( sout_checkbox->IsChecked() && sout_mrl.GetCount() )
1144 for( int j = 0; j < (int)sout_mrl.GetCount(); j++ )
1146 playlist_ItemAddOption( p_item, sout_mrl[j].mb_str() );
1150 playlist_AddItem( p_playlist, p_item,
1151 PLAYLIST_APPEND, PLAYLIST_END );
1155 playlist_Control( p_playlist, PLAYLIST_ITEMPLAY , p_item );
1159 vlc_object_release( p_playlist );
1163 if( IsModal() ) EndModal( wxID_OK );
1166 void OpenDialog::OnCancel( wxCommandEvent& WXUNUSED(event) )
1168 wxCloseEvent cevent;
1172 void OpenDialog::OnClose( wxCloseEvent& WXUNUSED(event) )
1176 if( IsModal() ) EndModal( wxID_CANCEL );
1179 void OpenDialog::OnPageChange( wxNotebookEvent& event )
1181 UpdateMRL( event.GetSelection() );
1184 void OpenDialog::OnMRLChange( wxCommandEvent& event )
1186 //mrl = SeparateEntries( event.GetString() );
1189 /*****************************************************************************
1190 * File panel event methods.
1191 *****************************************************************************/
1192 void OpenDialog::OnFilePanelChange( wxCommandEvent& WXUNUSED(event) )
1194 UpdateMRL( FILE_ACCESS );
1197 void OpenDialog::OnFileBrowse( wxCommandEvent& WXUNUSED(event) )
1199 if( file_dialog == NULL )
1200 file_dialog = new wxFileDialog( this, wxU(_("Open File")),
1201 wxT(""), wxT(""), wxT("*"), wxOPEN | wxMULTIPLE );
1203 if( file_dialog && file_dialog->ShowModal() == wxID_OK )
1205 wxArrayString paths;
1208 file_dialog->GetPaths( paths );
1210 for( size_t i = 0; i < paths.GetCount(); i++ )
1212 if( paths[i].Find( wxT(' ') ) >= 0 )
1213 path += wxT("\"") + paths[i] + wxT("\" ");
1215 path += paths[i] + wxT(" ");
1218 file_combo->SetValue( path );
1219 file_combo->Append( path );
1220 if( file_combo->GetCount() > 10 ) file_combo->Delete( 0 );
1221 UpdateMRL( FILE_ACCESS );
1225 /*****************************************************************************
1226 * Disc panel event methods.
1227 *****************************************************************************/
1228 void OpenDialog::OnDiscPanelChangeSpin( wxSpinEvent& event )
1230 wxCommandEvent cevent;
1231 cevent.SetId(event.GetId());
1232 cevent.SetInt(event.GetPosition());
1233 OnDiscPanelChange(cevent);
1236 void OpenDialog::OnDiscPanelChange( wxCommandEvent& event )
1238 if( event.GetId() == DiscTitle_Event ) i_disc_title = event.GetInt();
1239 if( event.GetId() == DiscChapter_Event ) i_disc_chapter = event.GetInt();
1240 if( event.GetId() == DiscSub_Event ) i_disc_sub = event.GetInt();
1241 if( event.GetId() == DiscAudio_Event ) i_disc_audio = event.GetInt();
1243 UpdateMRL( DISC_ACCESS );
1246 void OpenDialog::OnDiscDeviceChange( wxCommandEvent& event )
1250 switch( disc_type->GetSelection() )
1253 psz_device = config_GetPsz( p_intf, "cd-audio" );
1257 psz_device = config_GetPsz( p_intf, "vcd" );
1261 psz_device = config_GetPsz( p_intf, "dvd" );
1265 if ( !psz_device ) psz_device = "";
1267 if( disc_device->GetValue().Cmp( wxL2U( psz_device ) ) )
1269 b_disc_device_changed = true;
1272 UpdateMRL( DISC_ACCESS );
1277 /* Return true if *psz_drive is a drive with a DVD in it. A more complete
1278 check would see if the media looks like a *playable* DVD. This should
1281 static bool IsDVD(const char *psz_drive)
1283 CdIo_t *p_cdio = cdio_open (psz_drive, DRIVER_UNKNOWN);
1286 discmode_t discmode = cdio_get_discmode(p_cdio);
1287 cdio_destroy(p_cdio);
1288 return cdio_is_discmode_dvd(discmode);
1294 /* Return a device that has a DVD in it. The caller needs to free
1295 the returned string.
1297 static char * ProbeDVD(const wxChar *device)
1299 char **ppsz_cd_drives;
1300 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1301 char *psz_device = (char *) tmp_buf;
1303 if( IsDVD(psz_device) )
1305 return strdup(psz_device);
1308 ppsz_cd_drives = cdio_get_devices(DRIVER_DEVICE);
1309 if( ppsz_cd_drives )
1312 for( c = ppsz_cd_drives; *c != NULL; c++ )
1316 char *psz_drive = strdup(*c);
1317 cdio_free_device_list(ppsz_cd_drives);
1318 return strdup(psz_drive);
1321 cdio_free_device_list(ppsz_cd_drives);
1327 static char * ProbeDevice(char **ppsz_search_devices, cdio_fs_anal_t mask,
1330 char **ppsz_devices;
1332 if( ppsz_search_devices && !ppsz_search_devices[0] )
1333 ppsz_search_devices = NULL;
1335 /* Start out trying the device that has been entered so far. */
1336 ppsz_devices = cdio_get_devices_with_cap(ppsz_search_devices, mask,
1339 if (ppsz_devices && *ppsz_devices)
1341 char *psz_device = strdup(*ppsz_devices);
1342 cdio_free_device_list(ppsz_devices);
1346 /* If there was no device specified on the first try, then give up
1347 now. Otherwise accept any CD-ROM in the class (e.g. VCD or DVD).
1349 if( !ppsz_search_devices ) return NULL;
1351 ppsz_devices = cdio_get_devices_with_cap(NULL, mask, true);
1353 if (ppsz_devices && *ppsz_devices)
1355 char *psz_device = strdup(*ppsz_devices);
1356 cdio_free_device_list(ppsz_devices);
1364 /* Return a device that has a CD-DA in it. The caller needs to free
1365 the returned string.
1367 static char * ProbeCDDA(const wxChar *device)
1369 char *ppsz_device[2];
1370 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1371 char *psz_device = (char *) tmp_buf;
1372 ppsz_device[0] = (device && *device) ? psz_device : NULL;
1373 ppsz_device[1] = NULL;
1374 return ProbeDevice(ppsz_device, CDIO_FS_AUDIO, false);
1377 /* Return a device that has a VCD in it. The caller needs to free
1378 the returned string.
1380 static char * ProbeVCD(const wxChar *device)
1382 char *ppsz_device[2];
1383 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1384 char *psz_device = (char *) tmp_buf;
1385 ppsz_device[0] = (device && *device) ? psz_device : NULL;
1386 ppsz_device[1] = NULL;
1387 return ProbeDevice(ppsz_device,
1388 (CDIO_FS_ANAL_SVCD|CDIO_FS_ANAL_CVD|CDIO_FS_ANAL_VIDEOCD
1389 |CDIO_FS_UNKNOWN), true);
1394 Probe (find anywhere) a CD-DA, VCD, or a DVD.
1395 First try the device name that may have been entered for the "disc type"
1396 selected. If that doesn't work we try any device for the disc type.
1397 If that doesn't work, try looking for CD-ROMs or DVD drives. the
1398 disc type, device name and paramter ranges are set to whatever we find.
1400 void OpenDialog::OnDiscProbe( wxCommandEvent& WXUNUSED(event) )
1402 wxCommandEvent dummy_event;
1403 char *psz_device = NULL;
1404 bool b_probed_DVD = false;
1405 bool b_probed_VCD = false;
1406 const int i_selection = disc_type->GetSelection();
1408 /* Reduce verbosity of cdio errors. */
1409 cdio_loglevel_default = CDIO_LOG_ERROR;
1412 switch( disc_type->GetSelection() )
1415 case SELECTION_DISC_TYPE_DVD_MENUS:
1416 case SELECTION_DISC_TYPE_DVD:
1417 /* If not a DVD then try for a VCD. If VCD fails it will
1419 if (!psz_device) psz_device = ProbeDVD(disc_device->GetValue());
1422 b_probed_DVD = true;
1423 disc_type->SetSelection(SELECTION_DISC_TYPE_VCD);
1424 OnDiscTypeChange( dummy_event );
1427 disc_device->SetValue( wxL2U(psz_device) );
1430 case SELECTION_DISC_TYPE_VCD: /* VCD probe of some sort */
1431 if(!psz_device) psz_device = ProbeVCD(disc_device->GetValue());
1435 #if LIBVCD_VERSION_NUM > 23
1436 vcdinfo_obj_t *p_vcdinfo;
1438 /* Set LID or entry range accurately if possible. */
1439 if( vcdinfo_open(&p_vcdinfo, &psz_device, DRIVER_DEVICE,
1440 NULL) == VCDINFO_OPEN_VCD)
1442 if (config_GetInt( p_intf, "vcdx-PBC" ))
1444 /* Set largest LID. */;
1445 disc_title->SetRange( 0, vcdinfo_get_num_LIDs(p_vcdinfo) );
1450 /* Set largest Entry */
1451 disc_title->SetRange( 0,
1452 vcdinfo_get_num_entries(p_vcdinfo)-1 );
1454 vcdinfo_close(p_vcdinfo);
1456 #endif /* LIBVCD_VERSION_NUM > 23 */
1457 disc_device->SetValue( wxL2U(psz_device) );
1459 CdIo_t *p_cdio = cdio_open (psz_device, DRIVER_UNKNOWN);
1460 disc_device->SetValue( wxL2U(psz_device) );
1462 /* Set track range accurately if possible. */
1465 track_t i_last_track = cdio_get_last_track_num(p_cdio);
1466 disc_title->SetRange( 0, i_last_track-1 );
1468 cdio_destroy(p_cdio);
1473 b_probed_VCD = true;
1475 /* Not a VCD. Try for a DVD unless we've been there before. */
1476 if( !b_probed_DVD && (psz_device = ProbeDVD(disc_device->GetValue())) )
1478 disc_type->SetSelection(SELECTION_DISC_TYPE_DVD_MENUS);
1479 OnDiscTypeChange( dummy_event );
1482 b_probed_DVD = true;
1484 /* Couldn't find a VCD or DVD. See if we can find a CD-DA. */
1485 psz_device = ProbeCDDA(disc_device->GetValue());
1488 disc_type->SetSelection(SELECTION_DISC_TYPE_CDDA);
1489 OnDiscTypeChange( dummy_event );
1493 /* Couldn't find a VCD, DVD or CD-DA. Null out the Device name and
1494 set to original selection.
1496 disc_device->SetValue( wxL2U("") );
1497 disc_type->SetSelection(i_selection);
1498 OnDiscTypeChange( dummy_event );
1501 case SELECTION_DISC_TYPE_CDDA:
1502 if(!psz_device) psz_device = ProbeCDDA(disc_device->GetValue());
1505 CdIo_t *p_cdio = cdio_open (psz_device, DRIVER_UNKNOWN);
1506 disc_device->SetValue( wxL2U(psz_device) );
1509 track_t i_last_track = cdio_get_last_track_num(p_cdio);
1510 disc_title->SetRange( 0, i_last_track );
1512 MediaInsertCDDA( p_intf, p_cdio, i_last_track );
1515 cdio_destroy(p_cdio);
1519 /* Not a CD-DA. Try for a DVD unless we've been there before. */
1520 if( !b_probed_DVD && (psz_device = ProbeDVD(disc_device->GetValue())) )
1522 disc_type->SetSelection(SELECTION_DISC_TYPE_DVD_MENUS);
1523 OnDiscTypeChange( dummy_event );
1527 /* Couldn't find a CD-DA or DVD. See if we can find a VCD, unless
1528 we've tried that before. */
1529 if (!b_probed_VCD) psz_device = ProbeVCD(disc_device->GetValue());
1532 disc_type->SetSelection(SELECTION_DISC_TYPE_VCD);
1533 OnDiscTypeChange( dummy_event );
1536 disc_device->SetValue( wxL2U("") );
1540 msg_Err( p_intf, "invalid Disc type selection (%d)",
1541 disc_type->GetSelection() );
1546 disc_probe->SetValue(FALSE);
1548 UpdateMRL( DISC_ACCESS );
1550 #endif /* HAVE_LIBCDIO */
1552 void OpenDialog::OnDiscTypeChange( wxCommandEvent& WXUNUSED(event) )
1554 char *psz_device = NULL;
1556 switch( disc_type->GetSelection() )
1559 case SELECTION_DISC_TYPE_DVD_MENUS:
1560 case SELECTION_DISC_TYPE_DVD:
1561 disc_sub->Enable(); disc_sub_label->Enable();
1562 disc_audio->Enable(); disc_audio_label->Enable();
1563 disc_chapter->Enable(); disc_chapter_label->Enable();
1564 disc_title_label->SetLabel ( wxU(_("Title")) );
1565 psz_device = config_GetPsz( p_intf, "dvd" );
1566 if( !b_disc_device_changed )
1568 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1569 else disc_device->SetValue( wxT("") );
1571 disc_title->SetRange( 0, 255 );
1572 disc_sub->SetRange( -1, 31 ); // up to 32 subtitles -1: no subtitle
1573 disc_audio->SetRange( 0, 7 ); // up to 8 audio channels
1574 disc_chapter->SetRange( 0, 255 );
1575 disc_title->SetToolTip( wxU(_("Title number.")) );
1576 disc_sub->SetToolTip( wxU(_(
1577 "DVD's can have up to 32 subtitles numbered 0..31. "
1578 "Note this is not the same thing as a subtitle name e.g. 'en'. "
1579 "If a value -1 is used, no subtitle will be shown." )) );
1580 disc_audio->SetToolTip( wxU(_("Audio track number. "
1581 "DVD's can have up to 8 audio tracks numbered 0..7."
1585 case SELECTION_DISC_TYPE_VCD:
1586 disc_sub->Enable(); disc_sub_label->Enable();
1587 disc_audio->Enable(); disc_audio_label->Enable();
1588 disc_chapter->Disable(); disc_chapter_label->Disable();
1589 psz_device = config_GetPsz( p_intf, "vcd" );
1590 if( !b_disc_device_changed )
1592 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1593 else disc_device->SetValue( wxT("") );
1597 if (config_GetInt( p_intf, "vcdx-PBC" ))
1599 disc_title_label->SetLabel ( wxT("Playback LID") );
1600 disc_title->SetToolTip( wxU(_(
1601 "Playback control (PBC) usually starts with number 1." )) );
1605 disc_title_label->SetLabel ( wxT("Entry") );
1606 disc_title->SetToolTip( wxU(_(
1607 "The first entry (the beginning of the first MPEG track) is 0." )) );
1611 disc_title_label->SetLabel ( wxU(_("Track")) );
1612 disc_title->SetToolTip( wxU(_("Track number.")) );
1614 disc_title->SetRange( 0, 99 ); // only 100 tracks allowed on VCDs
1615 disc_sub->SetRange( -1, 3 ); // up to 4 subtitles -1 = no subtitle
1616 disc_audio->SetRange( 0, 1 ); // up to 2 audio tracks
1617 disc_sub->SetToolTip( wxU(_(
1618 "SVCD's can have up to 4 subtitles numbered 0..3. "
1619 "If a value -1 is used, no subtitle will be shown." )) );
1620 disc_audio->SetToolTip( wxU(_("Audio track number. "
1621 "VCD's can have up to 2 audio tracks numbered 0 or 1. "
1625 case SELECTION_DISC_TYPE_CDDA:
1626 disc_sub->Disable(); disc_sub_label->Disable();
1627 disc_chapter->Disable(); disc_chapter_label->Disable();
1628 disc_audio->Disable(); disc_audio_label->Disable();
1629 disc_title_label->SetLabel ( wxU(_("Track")) );
1631 disc_title->SetToolTip( wxU(_(
1632 "Audio CDs can have up to 100 tracks, the first track is usually 1. "
1633 "If 0 is given, then all tracks are played.")) );
1635 disc_title->SetToolTip( wxU(_(
1636 "Audio CDs can have up to 100 tracks, the first track is usually 1."
1639 psz_device = config_GetPsz( p_intf, "cd-audio" );
1640 if( !b_disc_device_changed )
1642 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1643 else disc_device->SetValue( wxT("") );
1646 /* There are at most 100 tracks in a CD-DA */
1647 disc_title->SetRange( 0, 100 );
1651 msg_Err( p_intf, "invalid Disc type selection (%d)",
1652 disc_type->GetSelection() );
1656 disc_title->SetValue( 0 ); i_disc_title = 0;
1657 disc_chapter->SetValue( 0 ); i_disc_chapter = 0;
1659 if( psz_device ) free( psz_device );
1661 UpdateMRL( DISC_ACCESS );
1664 /*****************************************************************************
1665 * Net panel event methods.
1666 *****************************************************************************/
1667 void OpenDialog::OnNetPanelChangeSpin( wxSpinEvent& event )
1669 wxCommandEvent cevent;
1670 cevent.SetId(event.GetId());
1671 cevent.SetInt(event.GetPosition());
1672 OnNetPanelChange(cevent);
1675 void OpenDialog::OnNetPanelChange( wxCommandEvent& event )
1677 if( event.GetId() >= NetPort1_Event && event.GetId() <= NetPort3_Event )
1679 i_net_ports[event.GetId() - NetPort1_Event] = event.GetInt();
1682 UpdateMRL( NET_ACCESS );
1685 void OpenDialog::OnNetTypeChange( wxCommandEvent& event )
1689 i_net_type = event.GetId() - NetRadio1_Event;
1693 net_radios[i]->SetValue( event.GetId() == (NetRadio1_Event+i) );
1694 net_subpanels[i]->Enable( event.GetId() == (NetRadio1_Event+i) );
1696 /* UDP Unicast or multicast -> timeshift */
1697 if( i_net_type == 0 || i_net_type == 1 )
1698 net_timeshift->Enable();
1700 net_timeshift->Disable();
1702 UpdateMRL( NET_ACCESS );
1705 /*****************************************************************************
1706 * Subtitles file event methods.
1707 *****************************************************************************/
1708 void OpenDialog::OnSubsFileEnable( wxCommandEvent& event )
1710 subsfile_button->Enable( event.GetInt() != 0 );
1713 void OpenDialog::OnSubsFileSettings( wxCommandEvent& WXUNUSED(event) )
1715 /* Show/hide the open dialog */
1716 if( subsfile_dialog == NULL )
1717 subsfile_dialog = new SubsFileDialog( p_intf, this );
1719 if( subsfile_dialog && subsfile_dialog->ShowModal() == wxID_OK )
1721 subsfile_mrl.Empty();
1722 subsfile_mrl.Add( wxString(wxT("sub-file=")) +
1723 subsfile_dialog->file_combo->GetValue() );
1724 if( subsfile_dialog->encoding_combo )
1726 subsfile_mrl.Add( wxString(wxT("subsdec-encoding=")) +
1727 subsfile_dialog->encoding_combo->GetValue() );
1729 if( subsfile_dialog->align_combo )
1731 subsfile_mrl.Add( wxString::Format(wxT("subsdec-align=%i"),
1732 (int)subsfile_dialog->align_combo->GetClientData(
1733 subsfile_dialog->align_combo->GetSelection()) ) );
1735 if( subsfile_dialog->size_combo )
1737 subsfile_mrl.Add( wxString::Format( wxT("freetype-rel-fontsize=%i"),
1738 (int)subsfile_dialog->size_combo->GetClientData(
1739 subsfile_dialog->size_combo->GetSelection()) ) );
1741 subsfile_mrl.Add( wxString::Format( wxT("sub-fps=%i"),
1742 subsfile_dialog->fps_spinctrl->GetValue() ) );
1743 subsfile_mrl.Add( wxString::Format( wxT("sub-delay=%i"),
1744 subsfile_dialog->delay_spinctrl->GetValue() ) );
1748 /*****************************************************************************
1749 * Stream output event methods.
1750 *****************************************************************************/
1751 void OpenDialog::OnSoutEnable( wxCommandEvent& event )
1753 sout_button->Enable( event.GetInt() != 0 );
1756 void OpenDialog::OnSoutSettings( wxCommandEvent& WXUNUSED(event) )
1758 /* Show/hide the open dialog */
1759 if( sout_dialog == NULL )
1760 sout_dialog = new SoutDialog( p_intf, this );
1762 if( sout_dialog && sout_dialog->ShowModal() == wxID_OK )
1764 sout_mrl = sout_dialog->GetOptions();
1768 /*****************************************************************************
1769 * Caching event methods.
1770 *****************************************************************************/
1771 void OpenDialog::OnCachingEnable( wxCommandEvent& event )
1773 caching_value->Enable( event.GetInt() != 0 );
1774 i_caching = caching_value->GetValue();
1778 void OpenDialog::OnCachingChangeSpin( wxSpinEvent& event )
1780 wxCommandEvent cevent;
1781 OnCachingChange(cevent);
1784 void OpenDialog::OnCachingChange( wxCommandEvent& event )
1786 i_caching = event.GetInt();
1790 /*****************************************************************************
1791 * Utility functions.
1792 *****************************************************************************/
1793 wxArrayString SeparateEntries( wxString entries )
1795 vlc_bool_t b_quotes_mode = VLC_FALSE;
1797 wxArrayString entries_array;
1800 wxStringTokenizer token( entries, wxT(" \t\r\n\""), wxTOKEN_RET_DELIMS );
1802 while( token.HasMoreTokens() )
1804 entry += token.GetNextToken();
1806 if( entry.IsEmpty() ) continue;
1808 if( !b_quotes_mode && entry.Last() == wxT('\"') )
1810 /* Enters quotes mode */
1812 b_quotes_mode = VLC_TRUE;
1814 else if( b_quotes_mode && entry.Last() == wxT('\"') )
1816 /* Finished the quotes mode */
1818 b_quotes_mode = VLC_FALSE;
1820 else if( !b_quotes_mode && entry.Last() != wxT('\"') )
1822 /* we found a non-quoted standalone string */
1823 if( token.HasMoreTokens() ||
1824 entry.Last() == wxT(' ') || entry.Last() == wxT('\t') ||
1825 entry.Last() == wxT('\r') || entry.Last() == wxT('\n') )
1827 if( !entry.IsEmpty() ) entries_array.Add( entry );
1834 if( !entry.IsEmpty() ) entries_array.Add( entry );
1836 return entries_array;