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., 59 Temple Place - Suite 330, Boston, MA 02111, 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"
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 # define wxRB_SINGLE 0
59 #define SELECTION_DISC_TYPE_DVD_MENUS 0
60 #define SELECTION_DISC_TYPE_DVD 1
61 #define SELECTION_DISC_TYPE_VCD 2
62 #define SELECTION_DISC_TYPE_CDDA 3
64 /*****************************************************************************
66 *****************************************************************************/
68 /* IDs for the controls and the menu commands */
71 Notebook_Event = wxID_HIGHEST,
88 NetRadio1_Event, NetRadio2_Event, NetRadio3_Event, NetRadio4_Event,
89 NetPort1_Event, NetPort2_Event, NetPort3_Event,
90 NetAddr1_Event, NetAddr2_Event, NetAddr3_Event, NetAddr4_Event,
91 NetForceIPv6_Event, NetTimeshift_Event,
94 SubsFileSettings_Event,
102 AdvancedOptions_Event
105 BEGIN_EVENT_TABLE(OpenDialog, wxDialog)
107 EVT_BUTTON(wxID_OK, OpenDialog::OnOk)
108 EVT_BUTTON(wxID_CANCEL, OpenDialog::OnCancel)
110 EVT_NOTEBOOK_PAGE_CHANGED(Notebook_Event, OpenDialog::OnPageChange)
112 EVT_TEXT(MRL_Event, OpenDialog::OnMRLChange)
114 /* Events generated by the file panel */
115 EVT_TEXT(FileName_Event, OpenDialog::OnFilePanelChange)
116 EVT_BUTTON(FileBrowse_Event, OpenDialog::OnFileBrowse)
118 /* Events generated by the disc panel */
119 EVT_RADIOBOX(DiscType_Event, OpenDialog::OnDiscTypeChange)
121 EVT_CHECKBOX(DiscProbe_Event, OpenDialog::OnDiscProbe)
123 EVT_TEXT(DiscDevice_Event, OpenDialog::OnDiscDeviceChange)
124 EVT_TEXT(DiscDevice_Event, OpenDialog::OnDiscPanelChange)
125 EVT_TEXT(DiscTitle_Event, OpenDialog::OnDiscPanelChange)
126 EVT_SPINCTRL(DiscTitle_Event, OpenDialog::OnDiscPanelChangeSpin)
127 EVT_TEXT(DiscChapter_Event, OpenDialog::OnDiscPanelChange)
128 EVT_SPINCTRL(DiscChapter_Event, OpenDialog::OnDiscPanelChangeSpin)
129 EVT_TEXT(DiscSub_Event, OpenDialog::OnDiscPanelChange)
130 EVT_TEXT(DiscAudio_Event, OpenDialog::OnDiscPanelChange)
131 EVT_SPINCTRL(DiscSub_Event, OpenDialog::OnDiscPanelChangeSpin)
133 /* Events generated by the net panel */
134 EVT_RADIOBUTTON(NetRadio1_Event, OpenDialog::OnNetTypeChange)
135 EVT_RADIOBUTTON(NetRadio2_Event, OpenDialog::OnNetTypeChange)
136 EVT_RADIOBUTTON(NetRadio3_Event, OpenDialog::OnNetTypeChange)
137 EVT_RADIOBUTTON(NetRadio4_Event, OpenDialog::OnNetTypeChange)
138 EVT_TEXT(NetPort1_Event, OpenDialog::OnNetPanelChange)
139 EVT_SPINCTRL(NetPort1_Event, OpenDialog::OnNetPanelChangeSpin)
140 EVT_TEXT(NetPort2_Event, OpenDialog::OnNetPanelChange)
141 EVT_SPINCTRL(NetPort2_Event, OpenDialog::OnNetPanelChangeSpin)
142 EVT_TEXT(NetPort3_Event, OpenDialog::OnNetPanelChange)
143 EVT_SPINCTRL(NetPort3_Event, OpenDialog::OnNetPanelChangeSpin)
144 EVT_TEXT(NetAddr2_Event, OpenDialog::OnNetPanelChange)
145 EVT_TEXT(NetAddr3_Event, OpenDialog::OnNetPanelChange)
146 EVT_TEXT(NetAddr4_Event, OpenDialog::OnNetPanelChange)
147 EVT_CHECKBOX(NetForceIPv6_Event, OpenDialog::OnNetPanelChange)
148 EVT_CHECKBOX(NetTimeshift_Event, OpenDialog::OnNetPanelChange)
150 /* Events generated by the subtitle file buttons */
151 EVT_CHECKBOX(SubsFileEnable_Event, OpenDialog::OnSubsFileEnable)
152 EVT_BUTTON(SubsFileSettings_Event, OpenDialog::OnSubsFileSettings)
154 /* Events generated by the stream output buttons */
155 EVT_CHECKBOX(SoutEnable_Event, OpenDialog::OnSoutEnable)
156 EVT_BUTTON(SoutSettings_Event, OpenDialog::OnSoutSettings)
158 /* Events generated by the caching button */
159 EVT_CHECKBOX(CachingEnable_Event, OpenDialog::OnCachingEnable)
160 EVT_TEXT(CachingChange_Event, OpenDialog::OnCachingChange)
161 EVT_SPINCTRL(CachingChange_Event, OpenDialog::OnCachingChangeSpin)
163 /* Hide the window when the user closes the window */
164 EVT_CLOSE(OpenDialog::OnClose)
169 /* Perhaps someday we'll figure out how to add media information to
170 "Stream-and-Media info" when no input thread hasn't been initialized.
172 extern void MediaInsertCDDA( intf_thread_t *_p_intf, CdIo_t *p_cdio,
173 track_t i_last_track );
176 /*****************************************************************************
178 *****************************************************************************/
179 WX_DEFINE_ARRAY(ConfigControl *, ArrayOfConfigControls);
181 class AutoBuiltPanel : public wxPanel
186 AutoBuiltPanel( wxWindow *, OpenDialog *, intf_thread_t *,
189 virtual ~AutoBuiltPanel() {}
191 void UpdateAdvancedMRL();
194 ArrayOfConfigControls config_array;
195 ArrayOfConfigControls advanced_config_array;
196 wxComboBox *p_advanced_mrl_combo;
199 intf_thread_t *p_intf;
200 OpenDialog *p_open_dialog;
202 void OnAdvanced( wxCommandEvent& event );
203 wxDialog *p_advanced_dialog;
205 DECLARE_EVENT_TABLE();
208 BEGIN_EVENT_TABLE(AutoBuiltPanel, wxPanel)
209 EVT_BUTTON(AdvancedOptions_Event, AutoBuiltPanel::OnAdvanced)
212 static void AutoBuildCallback( void *p_data )
214 ((OpenDialog *)p_data)->UpdateMRL();
217 static void AutoBuildAdvancedCallback( void *p_data )
219 ((AutoBuiltPanel *)p_data)->UpdateAdvancedMRL();
222 AutoBuiltPanel::AutoBuiltPanel( wxWindow *parent, OpenDialog *dialog,
223 intf_thread_t *_p_intf,
224 const module_t *p_module )
225 : wxPanel( parent, -1, wxDefaultPosition, wxDefaultSize ),
226 name( wxU(p_module->psz_object_name) ),
227 p_advanced_mrl_combo( NULL ),
228 p_intf( _p_intf ), p_open_dialog( dialog ), p_advanced_dialog( NULL )
230 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
231 module_config_t *p_item = p_module->p_config;
232 bool b_advanced = false;
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 );
254 while( p_item->i_type != CONFIG_HINT_END && p_item++ );
259 new wxButton( this, AdvancedOptions_Event,
260 wxU(_("Advanced options...")) );
261 sizer->Add( button, 0, wxALL, 5 );
263 /* Build the advanced dialog */
265 new wxDialog( this, -1, ((wxString)wxU(_("Advanced options"))) +
266 wxT(" (") + wxU( p_module->psz_longname ) + wxT(")"),
267 wxDefaultPosition, wxDefaultSize,
268 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER );
270 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
272 /* Create MRL combobox */
273 wxBoxSizer *mrl_sizer_sizer = new wxBoxSizer( wxHORIZONTAL );
274 wxStaticBox *mrl_box =
275 new wxStaticBox( p_advanced_dialog, -1,
276 wxU(_("Advanced options")) );
277 wxStaticBoxSizer *mrl_sizer =
278 new wxStaticBoxSizer( mrl_box, wxHORIZONTAL );
279 wxStaticText *mrl_label =
280 new wxStaticText( p_advanced_dialog, -1, wxU(_("Options:")) );
281 p_advanced_mrl_combo =
282 new wxComboBox( p_advanced_dialog, MRL_Event, wxT(""),
283 wxDefaultPosition, wxDefaultSize );
284 mrl_sizer->Add( mrl_label, 0, wxALL | wxALIGN_CENTER, 5 );
285 mrl_sizer->Add( p_advanced_mrl_combo, 1, wxALL | wxALIGN_CENTER, 5 );
286 mrl_sizer_sizer->Add( mrl_sizer, 1, wxEXPAND | wxALL, 5 );
287 sizer->Add( mrl_sizer_sizer, 0, wxEXPAND | wxALL, 2 );
289 /* Add advanced options to panel */
290 module_config_t *p_item = p_module->p_config;
293 if( p_item->i_type & CONFIG_HINT || !p_item->b_advanced )
296 ConfigControl *control =
297 CreateConfigControl( VLC_OBJECT(p_intf), p_item,
300 advanced_config_array.Add( control );
302 /* Don't add items that were not recognized */
303 if( control == NULL ) continue;
305 control->SetUpdateCallback( AutoBuildAdvancedCallback,
308 sizer->Add( control, 0, wxEXPAND | wxALL, 2 );
310 while( p_item->i_type != CONFIG_HINT_END && p_item++ );
313 wxPanel *dummy_panel = new wxPanel( p_advanced_dialog, -1 );
314 sizer->Add( dummy_panel, 1 );
315 wxStaticLine *static_line =
316 new wxStaticLine( p_advanced_dialog, wxID_OK );
317 sizer->Add( static_line, 0, wxEXPAND | wxALL, 5 );
320 wxButton *ok_button =
321 new wxButton( p_advanced_dialog, wxID_OK, wxU(_("OK")) );
322 ok_button->SetDefault();
323 wxButton *cancel_button =
324 new wxButton( p_advanced_dialog, wxID_CANCEL, wxU(_("Cancel")) );
325 wxBoxSizer *button_sizer = new wxBoxSizer( wxHORIZONTAL );
326 button_sizer->Add( ok_button, 0, wxALL, 5 );
327 button_sizer->Add( cancel_button, 0, wxALL, 5 );
328 button_sizer->Layout();
329 sizer->Add( button_sizer, 0, wxALL, 0 );
331 sizer->SetMinSize( 400, -1 );
332 p_advanced_dialog->SetSizerAndFit( sizer );
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 );
418 /* Create MRL combobox */
419 wxBoxSizer *mrl_sizer_sizer = new wxBoxSizer( wxHORIZONTAL );
420 wxStaticBox *mrl_box = new wxStaticBox( panel, -1,
421 wxU(_("Media Resource Locator (MRL)")) );
422 wxStaticBoxSizer *mrl_sizer = new wxStaticBoxSizer( mrl_box,
424 wxStaticText *mrl_label = new wxStaticText( panel, -1,
426 mrl_combo = new wxComboBox( panel, MRL_Event, wxT(""),
427 wxPoint(20,25), wxSize(120, -1) );
428 mrl_combo->SetToolTip( wxU(_("You can use this field directly by typing "
429 "the full MRL you want to open.\n""Alternatively, the field will be "
430 "filled automatically when you use the controls below.")) );
432 mrl_sizer->Add( mrl_label, 0, wxALL | wxALIGN_CENTER, 5 );
433 mrl_sizer->Add( mrl_combo, 1, wxALL | wxALIGN_CENTER, 5 );
434 mrl_sizer_sizer->Add( mrl_sizer, 1, wxEXPAND | wxALL, 5 );
437 /* Create Static Text */
438 wxStaticText *label = new wxStaticText( panel, -1,
439 wxU(_("Alternatively, you can build an MRL using one of the "
440 "following predefined targets:")) );
442 wxFlexGridSizer *common_opt_sizer = new wxFlexGridSizer( 5, 1, 20 );
444 if( i_method == OPEN_NORMAL )
446 /* Create Stream Output checkox */
447 sout_checkbox = new wxCheckBox( panel, SoutEnable_Event,
448 wxU(_("Stream output")) );
449 sout_checkbox->SetToolTip( wxU(_("Use VLC as a server of streams")) );
450 common_opt_sizer->Add( sout_checkbox, 0,
451 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
453 sout_button = new wxButton( panel, SoutSettings_Event,
454 wxU(_("Settings...")) );
455 sout_button->Disable();
457 char *psz_sout = config_GetPsz( p_intf, "sout" );
458 if( psz_sout && *psz_sout )
460 sout_checkbox->SetValue(TRUE);
461 sout_button->Enable();
462 subsfile_mrl.Add( wxString(wxT("sout=")) + wxL2U(psz_sout) );
464 if( psz_sout ) free( psz_sout );
466 common_opt_sizer->Add( sout_button, 1, wxALIGN_LEFT |
467 wxALIGN_CENTER_VERTICAL );
469 common_opt_sizer->Add( new wxPanel( this, -1 ), 1,
470 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
473 /* Create caching options */
474 caching_checkbox = new wxCheckBox( panel, CachingEnable_Event,
476 caching_checkbox->SetToolTip( wxU(_("Change the default caching value "
477 "(in milliseconds)")) );
478 common_opt_sizer->Add( caching_checkbox, 0,
479 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
480 caching_value = new wxSpinCtrl( panel, CachingChange_Event );
481 caching_value->SetRange( 0, 1000000 );
482 caching_value->Disable();
483 common_opt_sizer->Add( caching_value, 0,
484 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
487 wxStaticLine *static_line = new wxStaticLine( panel, wxID_OK );
489 /* Create the buttons */
490 wxButton *ok_button = new wxButton( panel, wxID_OK, wxU(_("OK")) );
491 ok_button->SetDefault();
492 wxButton *cancel_button = new wxButton( panel, wxID_CANCEL,
495 /* Create notebook */
496 notebook = new wxNotebook( panel, Notebook_Event );
498 #if (!wxCHECK_VERSION(2,5,2))
499 wxNotebookSizer *notebook_sizer = new wxNotebookSizer( notebook );
502 notebook->AddPage( FilePanel( notebook ), wxU(_("File")),
503 i_access_method == FILE_ACCESS );
504 notebook->AddPage( DiscPanel( notebook ), wxU(_("Disc")),
505 i_access_method == DISC_ACCESS );
506 notebook->AddPage( NetPanel( notebook ), wxU(_("Network")),
507 i_access_method == NET_ACCESS );
509 module_t *p_module = config_FindModule( VLC_OBJECT(p_intf), "v4l" );
512 AutoBuiltPanel *autopanel =
513 new AutoBuiltPanel( notebook, this, p_intf, p_module );
514 input_tab_array.Add( autopanel );
515 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
516 p_module->psz_shortname : p_module->psz_object_name ),
517 i_access_method == CAPTURE_ACCESS );
520 p_module = config_FindModule( VLC_OBJECT(p_intf), "pvr" );
523 AutoBuiltPanel *autopanel =
524 new AutoBuiltPanel( notebook, this, p_intf, p_module );
525 input_tab_array.Add( autopanel );
526 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
527 p_module->psz_shortname : p_module->psz_object_name ),
528 i_access_method == CAPTURE_ACCESS );
531 p_module = config_FindModule( VLC_OBJECT(p_intf), "dvb" );
534 AutoBuiltPanel *autopanel =
535 new AutoBuiltPanel( notebook, this, p_intf, p_module );
536 input_tab_array.Add( autopanel );
537 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
538 p_module->psz_shortname : p_module->psz_object_name ),
539 i_access_method == CAPTURE_ACCESS );
542 p_module = config_FindModule( VLC_OBJECT(p_intf), "dshow" );
545 AutoBuiltPanel *autopanel =
546 new AutoBuiltPanel( notebook, this, p_intf, p_module );
547 input_tab_array.Add( autopanel );
548 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
549 p_module->psz_shortname : p_module->psz_object_name ),
550 i_access_method == CAPTURE_ACCESS );
553 /* Update Disc panel */
554 wxCommandEvent dummy_event;
555 OnDiscTypeChange( dummy_event );
557 /* Update Net panel */
558 dummy_event.SetId( NetRadio1_Event );
559 OnNetTypeChange( dummy_event );
562 wxNotebookEvent event( wxEVT_NULL, 0, i_access_method );
563 OnPageChange( event );
565 /* Place everything in sizers */
566 wxBoxSizer *button_sizer = new wxBoxSizer( wxHORIZONTAL );
567 button_sizer->Add( ok_button, 0, wxALL, 5 );
568 button_sizer->Add( cancel_button, 0, wxALL, 5 );
569 button_sizer->Layout();
570 wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL );
571 wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
572 panel_sizer->Add( mrl_sizer_sizer, 0, wxEXPAND, 5 );
573 panel_sizer->Add( label, 0, wxEXPAND | wxALL, 5 );
574 #if (!wxCHECK_VERSION(2,5,2))
575 panel_sizer->Add( notebook_sizer, 1, wxEXPAND | wxALL, 5 );
577 panel_sizer->Add( notebook, 1, wxEXPAND | wxALL, 5 );
579 panel_sizer->Add( common_opt_sizer, 0, wxALIGN_LEFT | wxALL, 5 );
580 panel_sizer->Add( static_line, 0, wxEXPAND | wxALL, 5 );
581 panel_sizer->Add( button_sizer, 0, wxALIGN_LEFT | wxALL, 5 );
582 panel_sizer->Layout();
583 panel->SetSizerAndFit( panel_sizer );
584 main_sizer->Add( panel, 1, wxGROW, 0 );
585 main_sizer->Layout();
586 SetSizerAndFit( main_sizer );
589 OpenDialog::~OpenDialog()
592 if( file_dialog ) delete file_dialog;
593 if( sout_dialog ) delete sout_dialog;
594 if( subsfile_dialog ) delete subsfile_dialog;
597 int OpenDialog::Show( int i_access_method, int i_arg )
599 notebook->SetSelection( i_access_method );
600 int i_ret = wxDialog::Show();
607 int OpenDialog::Show()
609 int i_ret = wxDialog::Show();
615 /*****************************************************************************
617 *****************************************************************************/
618 wxPanel *OpenDialog::FilePanel( wxWindow* parent )
620 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
623 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
625 /* Create browse file line */
626 wxBoxSizer *file_sizer = new wxBoxSizer( wxHORIZONTAL );
628 file_combo = new wxComboBox( panel, FileName_Event, wxT(""),
629 wxPoint(20,25), wxSize(200, -1) );
630 wxButton *browse_button = new wxButton( panel, FileBrowse_Event,
631 wxU(_("Browse...")) );
632 file_sizer->Add( file_combo, 1, wxALL, 5 );
633 file_sizer->Add( browse_button, 0, wxALL, 5 );
635 /* Create Subtitles File checkox */
636 wxFlexGridSizer *subsfile_sizer = new wxFlexGridSizer( 2, 1, 20 );
637 subsfile_checkbox = new wxCheckBox( panel, SubsFileEnable_Event,
638 wxU(_("Subtitle options")) );
639 subsfile_checkbox->SetToolTip( wxU(_("Force options for separate subtitle files.")) );
640 subsfile_sizer->Add( subsfile_checkbox, 0,
641 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
642 subsfile_button = new wxButton( panel, SubsFileSettings_Event,
643 wxU(_("Settings...")) );
644 subsfile_button->Disable();
646 char *psz_subsfile = config_GetPsz( p_intf, "sub-file" );
647 if( psz_subsfile && *psz_subsfile )
649 subsfile_checkbox->SetValue(TRUE);
650 subsfile_button->Enable();
651 subsfile_mrl.Add( wxString(wxT("sub-file=")) + wxL2U(psz_subsfile) );
653 if( psz_subsfile ) free( psz_subsfile );
655 subsfile_sizer->Add( subsfile_button, 1,
656 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
658 sizer->Add( file_sizer, 0, wxEXPAND | wxALL, 5 );
659 sizer->Add( subsfile_sizer, 0, wxEXPAND | wxALL, 5 );
660 panel->SetSizerAndFit( sizer );
664 wxPanel *OpenDialog::DiscPanel( wxWindow* parent )
666 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
669 wxBoxSizer *sizer_row = new wxBoxSizer( wxVERTICAL );
670 wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 3, 20 );
672 static const wxString disc_type_array[] =
674 wxU(_("DVD (menus)")),
680 disc_type = new wxRadioBox( panel, DiscType_Event, wxU(_("Disc type")),
681 wxDefaultPosition, wxDefaultSize,
682 WXSIZEOF(disc_type_array), disc_type_array,
683 WXSIZEOF(disc_type_array), wxRA_SPECIFY_COLS );
686 disc_probe = new wxCheckBox( panel, DiscProbe_Event,
687 wxU(_("Probe Disc(s)")) );
688 disc_probe->SetToolTip( wxU(_("Probe for a DVD, VCD or audio CD. "
689 "First try the Device name entered for the selected Disc type "
690 "(DVD, DVD Menu, VCD, audio CD). If that doesn't find media, try any device "
691 "for the Disc type. If that doesn't work, then try looking for CD-ROMs or "
692 "DVD drives. The Disc type, Device name, and some parameter ranges are set "
693 "based on media we find.")) );
696 sizer_row->Add( disc_type, i_disc_type_selection, wxEXPAND | wxALL, 5 );
698 sizer_row->Add( disc_probe, 0, wxEXPAND | wxALL );
701 wxStaticText *label = new wxStaticText( panel, -1, wxU(_("Device name")) );
702 disc_device = new wxTextCtrl( panel, DiscDevice_Event, wxT(""),
703 wxDefaultPosition, wxDefaultSize,
707 char psz_default_device[3] = {0};
709 /* find the drive_name for the first cdrom drive,
710 * which is probably "D:" and put the drive_name into
711 * psz_default_device... */
712 for( char drive_letter = 'A'; drive_letter <= 'Z'; ++drive_letter )
714 char drive_name[3] = {drive_letter, ':', 0};
715 UINT type = GetDriveTypeA( drive_name );
716 if( type == DRIVE_CDROM )
718 psz_default_device[0] = drive_letter;
719 psz_default_device[1] = ':';
725 if( strlen(psz_default_device) > 0 )
728 disc_device->SetValue( wxL2U(psz_default_device) );
732 sizer->Add( label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
733 sizer->Add( disc_device, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
735 disc_title_label = new wxStaticText( panel, -1, wxU(_("Title")) );
736 disc_title = new wxSpinCtrl( panel, DiscTitle_Event );
737 sizer->Add( disc_title_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
738 sizer->Add( disc_title, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
740 disc_chapter_label = new wxStaticText( panel, -1, wxU(_("Chapter")) );
741 disc_chapter = new wxSpinCtrl( panel, DiscChapter_Event );
742 sizer->Add( disc_chapter_label, 0,
743 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
744 sizer->Add( disc_chapter, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
746 disc_sub_label = new wxStaticText( panel, -1, wxU(_("Subtitles track")) );
747 disc_sub = new wxSpinCtrl( panel, DiscSub_Event );
748 sizer->Add( disc_sub_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
749 sizer->Add( disc_sub, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
750 disc_sub->SetRange( -1, 255 );
751 i_disc_sub = config_GetInt( p_intf, "sub-track" );
752 disc_sub->SetValue( i_disc_sub );
754 disc_audio_label = new wxStaticText( panel, -1, wxU(_("Audio track")) );
755 disc_audio = new wxSpinCtrl( panel, DiscAudio_Event );
756 sizer->Add( disc_audio_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
757 sizer->Add( disc_audio, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
758 disc_audio->SetRange( -1, 255 );
759 i_disc_audio = config_GetInt( p_intf, "audio-track" );
760 disc_audio->SetValue( i_disc_audio );
762 sizer_row->Add( sizer, 0, wxEXPAND | wxALL, 5 );
764 panel->SetSizerAndFit( sizer_row );
768 wxPanel *OpenDialog::NetPanel( wxWindow* parent )
771 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
774 wxBoxSizer *sizer_row = new wxBoxSizer( wxVERTICAL );
775 wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 4, 20 );
777 static const wxString net_type_array[] =
780 wxU(_("UDP/RTP Multicast")),
781 wxU(_("HTTP/HTTPS/FTP/MMS")),
787 net_radios[i] = new wxRadioButton( panel, NetRadio1_Event + i,
789 wxDefaultPosition, wxDefaultSize,
792 net_subpanels[i] = new wxPanel( panel, -1,
793 wxDefaultPosition, wxDefaultSize );
797 net_timeshift = new wxCheckBox( panel, NetTimeshift_Event,
798 wxU(_("Allow timeshifting")) );
801 wxFlexGridSizer *subpanel_sizer;
803 i_net_ports[0] = config_GetInt( p_intf, "server-port" );
804 subpanel_sizer = new wxFlexGridSizer( 3, 1, 20 );
805 label = new wxStaticText( net_subpanels[0], -1, wxU(_("Port")) );
806 net_ports[0] = new wxSpinCtrl( net_subpanels[0], NetPort1_Event,
807 wxString::Format(wxT("%d"), i_net_ports[0]),
808 wxDefaultPosition, wxDefaultSize,
810 0, 65535, i_net_ports[0] );
812 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
813 subpanel_sizer->Add( net_ports[0], 1,
814 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
815 net_ipv6 = new wxCheckBox( net_subpanels[0], NetForceIPv6_Event,
816 wxU(_("Force IPv6")));
817 subpanel_sizer->Add( net_ipv6, 0,
818 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
819 net_subpanels[0]->SetSizerAndFit( subpanel_sizer );
820 net_radios[0]->SetValue( TRUE );
822 /* UDP/RTP Multicast row */
823 subpanel_sizer = new wxFlexGridSizer( 4, 1, 20 );
824 label = new wxStaticText( net_subpanels[1], -1, wxU(_("Address")) );
825 net_addrs[1] = new wxTextCtrl( net_subpanels[1], NetAddr2_Event, wxT(""),
826 wxDefaultPosition, wxDefaultSize,
828 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
829 subpanel_sizer->Add( net_addrs[1], 1,
830 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
832 label = new wxStaticText( net_subpanels[1], -1, wxU(_("Port")) );
833 i_net_ports[1] = i_net_ports[0];
834 net_ports[1] = new wxSpinCtrl( net_subpanels[1], NetPort2_Event,
835 wxString::Format(wxT("%d"), i_net_ports[1]),
836 wxDefaultPosition, wxDefaultSize,
838 0, 65535, i_net_ports[1] );
840 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
841 subpanel_sizer->Add( net_ports[1], 1,
842 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
843 net_subpanels[1]->SetSizerAndFit( subpanel_sizer );
845 /* HTTP and RTSP rows */
848 subpanel_sizer = new wxFlexGridSizer( 2, 1, 20 );
849 label = new wxStaticText( net_subpanels[i], -1, wxU(_("URL")) );
850 net_addrs[i] = new wxTextCtrl( net_subpanels[i], NetAddr1_Event + i,
851 (i == 2) ? wxT("") : wxT("rtsp://"),
852 wxDefaultPosition, wxSize( 200, -1 ),
854 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
855 subpanel_sizer->Add( net_addrs[i], 1,
856 wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
857 net_subpanels[i]->SetSizerAndFit( subpanel_sizer );
860 /* Stuff everything into the main panel */
863 sizer->Add( net_radios[i], 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
865 sizer->Add( net_subpanels[i], 1, wxEXPAND | wxALIGN_LEFT |
866 wxALIGN_CENTER_VERTICAL | wxALL, 5 );
868 sizer->Add( net_timeshift, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
871 sizer_row->Add( sizer, 0, wxEXPAND | wxALL, 5 );
873 panel->SetSizerAndFit( sizer_row );
877 void OpenDialog::UpdateMRL()
879 UpdateMRL( i_current_access_method );
882 void OpenDialog::UpdateMRL( int i_access_method )
884 wxString mrltemp, caching_name;
886 i_current_access_method = i_access_method;
888 switch( i_access_method )
891 mrltemp = file_combo->GetValue();
892 caching_name = wxT("file-caching");
896 i_disc_type_selection = disc_type->GetSelection();
898 switch ( i_disc_type_selection )
900 case 0: /* DVD with menus */
901 case 1: /* DVD without menus */
902 disc_device->SetToolTip( wxU(_("Name of DVD device "
904 if( i_disc_type_selection == 0 )
906 mrltemp = wxT("dvd://") + disc_device->GetValue();
907 caching_name = wxT("dvdnav-caching");
911 mrltemp = wxT("dvdsimple://") + disc_device->GetValue();
912 caching_name = wxT("dvdread-caching");
915 if( i_disc_title > 0 )
917 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
919 if( i_disc_chapter > 0 )
920 mrltemp += wxString::Format( wxT(":%d"), i_disc_chapter );
923 if( i_disc_sub >= 0 )
924 mrltemp += wxString::Format( wxT(" :sub-track=%d"),
926 if( i_disc_audio >= 0 )
927 mrltemp += wxString::Format( wxT(" :audio-track=%d"),
931 case 2: /* VCD of some sort */
933 disc_device->SetToolTip( wxU(_("Name of CD-ROM device "
934 "to read Video CD from. If this field is left empty, we will scan "
935 "for a CD-ROM with a VCD in it.")) );
936 mrltemp = wxT("vcdx://") + disc_device->GetValue();
937 if( i_disc_title > 0 )
938 mrltemp += wxString::Format( wxT("@%c%d"),
939 config_GetInt( p_intf, "vcdx-PBC" )
940 ? 'P' : 'E', i_disc_title );
942 disc_device->SetToolTip( wxU(_("Name of CD-ROM device "
943 "to read Video CD from.")) );
944 mrltemp = wxT("vcd://") + disc_device->GetValue();
945 if( i_disc_title > 0 )
946 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
949 if( i_disc_sub >= 0 )
950 mrltemp += wxString::Format( wxT(" :sub-track=%d"),
953 if( i_disc_audio >= 0 )
954 mrltemp += wxString::Format( wxT(" :audio-track=%d"),
956 caching_name = wxT("vcd-caching");
961 disc_device->SetToolTip( wxU(_("Name of CD-ROM device "
962 "to read audio CD from. If this field is left empty, we will scan "
963 "for a CD-ROM with an audio CD in it." )) );
964 mrltemp = wxT("cddax://")
966 disc_device->SetToolTip( wxU(_("Name of CD-ROM device "
967 "to read audio CD from." )) );
968 mrltemp = wxT("cdda://")
970 + disc_device->GetValue();
971 if( i_disc_title > 0 )
972 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
974 caching_name = wxT("cdda-caching");
978 msg_Err( p_intf, "invalid selection (%d)",
979 disc_type->GetSelection() );
988 mrltemp = wxT("udp://@");
989 if ( net_ipv6->GetValue() )
991 mrltemp += wxT("[::]");
993 if( i_net_ports[0] !=
994 config_GetInt( p_intf, "server-port" ) )
996 mrltemp += wxString::Format( wxT(":%d"), i_net_ports[0] );
999 caching_name = wxT("udp-caching");
1003 mrltemp = wxT("udp://@");
1004 if ((net_addrs[1]->GetLineText(0).Find (':') != -1)
1005 && (net_addrs[1]->GetLineText(0)[0u] != '['))
1007 /* automatically adds '[' and ']' to IPv6 addresses */
1008 mrltemp += wxT("[") + net_addrs[1]->GetLineText(0)
1013 mrltemp += net_addrs[1]->GetLineText(0);
1015 if( i_net_ports[1] != config_GetInt( p_intf, "server-port" ) )
1017 mrltemp += wxString::Format( wxT(":%d"), i_net_ports[1] );
1020 caching_name = wxT("udp-caching");
1025 if( net_addrs[2]->GetLineText(0).Find(wxT("://")) == -1 )
1026 mrltemp = wxT("http://");
1028 mrltemp += net_addrs[2]->GetLineText(0);
1030 caching_name = wxT("http-caching");
1035 if( net_addrs[3]->GetLineText(0).Find(wxT("rtsp://")) != 0 )
1037 mrltemp = wxT("rtsp://");
1039 mrltemp += net_addrs[3]->GetLineText(0);
1041 caching_name = wxT("rtsp-caching");
1044 if( net_timeshift->IsEnabled() && net_timeshift->IsChecked() )
1045 mrltemp += wxT(" :access-filter=timeshift");
1050 int i_item = i_access_method - MAX_ACCESS;
1052 if( i_item < 0 || i_item >= (int)input_tab_array.GetCount() )
1055 AutoBuiltPanel *input_panel = input_tab_array.Item( i_item );
1057 mrltemp = input_panel->name + wxT("://");
1059 for( int i=0; i < (int)input_panel->config_array.GetCount(); i++ )
1061 ConfigControl *control = input_panel->config_array.Item(i);
1063 mrltemp += wxT(" :");
1065 if( control->GetType() == CONFIG_ITEM_BOOL &&
1066 !control->GetIntValue() ) mrltemp += wxT("no-");
1068 mrltemp += control->GetName();
1070 switch( control->GetType() )
1072 case CONFIG_ITEM_STRING:
1073 case CONFIG_ITEM_FILE:
1074 case CONFIG_ITEM_DIRECTORY:
1075 case CONFIG_ITEM_MODULE:
1076 mrltemp += wxT("=\"") + control->GetPszValue() + wxT("\"");
1078 case CONFIG_ITEM_INTEGER:
1080 wxString::Format( wxT("=%i"), control->GetIntValue() );
1082 case CONFIG_ITEM_FLOAT:
1084 wxString::Format(wxT("=%f"), control->GetFloatValue());
1089 if( input_panel->p_advanced_mrl_combo &&
1090 input_panel->p_advanced_mrl_combo->GetValue() )
1092 mrltemp += wxT(" ") +
1093 input_panel->p_advanced_mrl_combo->GetValue();
1099 if( caching_name.size() )
1101 if( caching_value->IsEnabled() )
1103 mrltemp += wxT(" :") + caching_name +
1104 wxString::Format( wxT("=%d"), i_caching );
1108 int i_value = config_GetInt( p_intf, caching_name.mb_str() );
1109 caching_value->SetValue( i_value );
1113 mrl_combo->SetValue( mrltemp );
1116 /*****************************************************************************
1118 *****************************************************************************/
1119 void OpenDialog::OnOk( wxCommandEvent& WXUNUSED(event) )
1121 mrl = SeparateEntries( mrl_combo->GetValue() );
1122 mrl_combo->Append( mrl_combo->GetValue() );
1123 if( mrl_combo->GetCount() > 10 ) mrl_combo->Delete( 0 );
1124 mrl_combo->SetSelection( mrl_combo->GetCount() - 1 );
1126 if( i_method == OPEN_STREAM )
1128 if( IsModal() ) EndModal( wxID_OK );
1133 /* Update the playlist */
1134 playlist_t *p_playlist =
1135 (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
1137 if( p_playlist == NULL ) return;
1139 for( int i = 0; i < (int)mrl.GetCount(); i++ )
1141 vlc_bool_t b_start = !i && i_open_arg;
1142 playlist_item_t *p_item;
1145 psz_utf8 = wxFromLocale( mrl[i] );
1146 p_item = playlist_ItemNew( p_intf, psz_utf8, psz_utf8 );
1147 wxLocaleFree( psz_utf8 );
1149 /* Insert options */
1150 while( i + 1 < (int)mrl.GetCount() &&
1151 ((const char *)mrl[i + 1].mb_str())[0] == ':' )
1153 psz_utf8 = wxFromLocale( mrl[i + 1] );
1154 playlist_ItemAddOption( p_item, psz_utf8 );
1155 wxLocaleFree( psz_utf8 );
1159 /* Get the options from the subtitles dialog */
1160 if( subsfile_checkbox->IsChecked() && subsfile_mrl.GetCount() )
1162 for( int j = 0; j < (int)subsfile_mrl.GetCount(); j++ )
1164 psz_utf8 = wxFromLocale( subsfile_mrl[j] );
1165 playlist_ItemAddOption( p_item, psz_utf8 );
1166 wxLocaleFree( psz_utf8 );
1170 /* Get the options from the stream output dialog */
1171 if( sout_checkbox->IsChecked() && sout_mrl.GetCount() )
1173 for( int j = 0; j < (int)sout_mrl.GetCount(); j++ )
1175 psz_utf8 = wxFromLocale( sout_mrl[j] );
1176 playlist_ItemAddOption( p_item, psz_utf8 );
1177 wxLocaleFree( psz_utf8 );
1181 playlist_AddItem( p_playlist, p_item, PLAYLIST_APPEND, PLAYLIST_END );
1185 playlist_Control( p_playlist, PLAYLIST_ITEMPLAY, p_item );
1189 vlc_object_release( p_playlist );
1193 if( IsModal() ) EndModal( wxID_OK );
1196 void OpenDialog::OnCancel( wxCommandEvent& WXUNUSED(event) )
1198 wxCloseEvent cevent;
1202 void OpenDialog::OnClose( wxCloseEvent& WXUNUSED(event) )
1206 if( IsModal() ) EndModal( wxID_CANCEL );
1209 void OpenDialog::OnPageChange( wxNotebookEvent& event )
1211 UpdateMRL( event.GetSelection() );
1214 void OpenDialog::OnMRLChange( wxCommandEvent& event )
1216 //mrl = SeparateEntries( event.GetString() );
1219 /*****************************************************************************
1220 * File panel event methods.
1221 *****************************************************************************/
1222 void OpenDialog::OnFilePanelChange( wxCommandEvent& WXUNUSED(event) )
1224 UpdateMRL( FILE_ACCESS );
1227 void OpenDialog::OnFileBrowse( wxCommandEvent& WXUNUSED(event) )
1229 if( file_dialog == NULL )
1230 file_dialog = new wxFileDialog( this, wxU(_("Open File")),
1231 wxT(""), wxT(""), wxT("*"), wxOPEN | wxMULTIPLE );
1233 if( file_dialog && file_dialog->ShowModal() == wxID_OK )
1235 wxArrayString paths;
1238 file_dialog->GetPaths( paths );
1240 for( size_t i = 0; i < paths.GetCount(); i++ )
1242 if( paths[i].Find( wxT(' ') ) >= 0 )
1243 path += wxT("\"") + paths[i] + wxT("\" ");
1245 path += paths[i] + wxT(" ");
1248 file_combo->SetValue( path );
1249 file_combo->Append( path );
1250 if( file_combo->GetCount() > 10 ) file_combo->Delete( 0 );
1251 UpdateMRL( FILE_ACCESS );
1255 /*****************************************************************************
1256 * Disc panel event methods.
1257 *****************************************************************************/
1258 void OpenDialog::OnDiscPanelChangeSpin( wxSpinEvent& event )
1260 wxCommandEvent cevent;
1261 cevent.SetId(event.GetId());
1262 cevent.SetInt(event.GetPosition());
1263 OnDiscPanelChange(cevent);
1266 void OpenDialog::OnDiscPanelChange( wxCommandEvent& event )
1268 if( event.GetId() == DiscTitle_Event ) i_disc_title = event.GetInt();
1269 if( event.GetId() == DiscChapter_Event ) i_disc_chapter = event.GetInt();
1270 if( event.GetId() == DiscSub_Event ) i_disc_sub = event.GetInt();
1271 if( event.GetId() == DiscAudio_Event ) i_disc_audio = event.GetInt();
1273 UpdateMRL( DISC_ACCESS );
1276 void OpenDialog::OnDiscDeviceChange( wxCommandEvent& event )
1280 switch( disc_type->GetSelection() )
1283 psz_device = config_GetPsz( p_intf, "cd-audio" );
1287 psz_device = config_GetPsz( p_intf, "vcd" );
1291 psz_device = config_GetPsz( p_intf, "dvd" );
1295 if ( !psz_device ) psz_device = "";
1297 if( disc_device->GetValue().Cmp( wxL2U( psz_device ) ) )
1299 b_disc_device_changed = true;
1302 UpdateMRL( DISC_ACCESS );
1307 /* Return true if *psz_drive is a drive with a DVD in it. A more complete
1308 check would see if the media looks like a *playable* DVD. This should
1311 static bool IsDVD(const char *psz_drive)
1313 CdIo_t *p_cdio = cdio_open (psz_drive, DRIVER_UNKNOWN);
1316 discmode_t discmode = cdio_get_discmode(p_cdio);
1317 cdio_destroy(p_cdio);
1318 return cdio_is_discmode_dvd(discmode);
1324 /* Return a device that has a DVD in it. The caller needs to free
1325 the returned string.
1327 static char * ProbeDVD(const wxChar *device)
1330 char **ppsz_cd_drives;
1331 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1332 char *psz_device = (char *) tmp_buf;
1334 if( IsDVD(psz_device) )
1336 return strdup(psz_device);
1339 ppsz_cd_drives = cdio_get_devices(DRIVER_DEVICE);
1340 if( ppsz_cd_drives )
1343 for( c = ppsz_cd_drives; *c != NULL; c++ )
1347 char *psz_drive = strdup(*c);
1348 cdio_free_device_list(ppsz_cd_drives);
1349 return strdup(psz_drive);
1352 cdio_free_device_list(ppsz_cd_drives);
1358 static char * ProbeDevice(char **ppsz_search_devices, cdio_fs_anal_t mask,
1361 char **ppsz_devices;
1363 if( ppsz_search_devices && !ppsz_search_devices[0] )
1364 ppsz_search_devices = NULL;
1366 /* Start out trying the device that has been entered so far. */
1367 ppsz_devices = cdio_get_devices_with_cap(ppsz_search_devices, mask,
1370 if (ppsz_devices && *ppsz_devices)
1372 char *psz_device = strdup(*ppsz_devices);
1373 cdio_free_device_list(ppsz_devices);
1377 /* If there was no device specified on the first try, then give up
1378 now. Otherwise accept any CD-ROM in the class (e.g. VCD or DVD).
1380 if( !ppsz_search_devices ) return NULL;
1382 ppsz_devices = cdio_get_devices_with_cap(NULL, mask, true);
1384 if (ppsz_devices && *ppsz_devices)
1386 char *psz_device = strdup(*ppsz_devices);
1387 cdio_free_device_list(ppsz_devices);
1395 /* Return a device that has a CD-DA in it. The caller needs to free
1396 the returned string.
1398 static char * ProbeCDDA(const wxChar *device)
1401 char *ppsz_device[2];
1402 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1403 char *psz_device = (char *) tmp_buf;
1404 ppsz_device[0] = (device && *device) ? psz_device : NULL;
1405 ppsz_device[1] = NULL;
1406 return ProbeDevice(ppsz_device, CDIO_FS_AUDIO, false);
1410 /* Return a device that has a VCD in it. The caller needs to free
1411 the returned string.
1413 static char * ProbeVCD(const wxChar *device)
1415 char *ppsz_device[2];
1416 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1417 char *psz_device = (char *) tmp_buf;
1418 ppsz_device[0] = (device && *device) ? psz_device : NULL;
1419 ppsz_device[1] = NULL;
1420 return ProbeDevice(ppsz_device,
1421 (CDIO_FS_ANAL_SVCD|CDIO_FS_ANAL_CVD|CDIO_FS_ANAL_VIDEOCD
1422 |CDIO_FS_UNKNOWN), true);
1428 Probe (find anywhere) a CD-DA, VCD, or a DVD.
1429 First try the device name that may have been entered for the "disc type"
1430 selected. If that doesn't work we try any device for the disc type.
1431 If that doesn't work, try looking for CD-ROMs or DVD drives. the
1432 disc type, device name and paramter ranges are set to whatever we find.
1434 void OpenDialog::OnDiscProbe( wxCommandEvent& WXUNUSED(event) )
1436 wxCommandEvent dummy_event;
1437 char *psz_device = NULL;
1438 bool b_probed_DVD = false;
1439 bool b_probed_VCD = false;
1440 const int i_selection = disc_type->GetSelection();
1442 /* Reduce verbosity of cdio errors. */
1443 cdio_loglevel_default = CDIO_LOG_ERROR;
1446 switch( disc_type->GetSelection() )
1449 case SELECTION_DISC_TYPE_DVD_MENUS:
1450 case SELECTION_DISC_TYPE_DVD:
1451 /* If not a DVD then try for a VCD. If VCD fails it will
1453 if (!psz_device) psz_device = ProbeDVD(disc_device->GetValue());
1456 b_probed_DVD = true;
1457 disc_type->SetSelection(SELECTION_DISC_TYPE_VCD);
1458 OnDiscTypeChange( dummy_event );
1461 disc_device->SetValue( wxL2U(psz_device) );
1464 case SELECTION_DISC_TYPE_VCD: /* VCD probe of some sort */
1465 if(!psz_device) psz_device = ProbeVCD(disc_device->GetValue());
1469 #if LIBVCD_VERSION_NUM > 23
1470 vcdinfo_obj_t *p_vcdinfo;
1472 /* Set LID or entry range accurately if possible. */
1473 if( vcdinfo_open(&p_vcdinfo, &psz_device, DRIVER_DEVICE,
1474 NULL) == VCDINFO_OPEN_VCD)
1476 if (config_GetInt( p_intf, "vcdx-PBC" ))
1478 /* Set largest LID. */;
1479 disc_title->SetRange( 0, vcdinfo_get_num_LIDs(p_vcdinfo) );
1484 /* Set largest Entry */
1485 disc_title->SetRange( 0,
1486 vcdinfo_get_num_entries(p_vcdinfo)-1 );
1488 vcdinfo_close(p_vcdinfo);
1490 #endif /* LIBVCD_VERSION_NUM > 23 */
1491 disc_device->SetValue( wxL2U(psz_device) );
1493 CdIo_t *p_cdio = cdio_open (psz_device, DRIVER_UNKNOWN);
1494 disc_device->SetValue( wxL2U(psz_device) );
1496 /* Set track range accurately if possible. */
1499 track_t i_last_track = cdio_get_last_track_num(p_cdio);
1500 disc_title->SetRange( 0, i_last_track-1 );
1502 cdio_destroy(p_cdio);
1507 b_probed_VCD = true;
1509 /* Not a VCD. Try for a DVD unless we've been there before. */
1510 if( !b_probed_DVD && (psz_device = ProbeDVD(disc_device->GetValue())) )
1512 disc_type->SetSelection(SELECTION_DISC_TYPE_DVD_MENUS);
1513 OnDiscTypeChange( dummy_event );
1516 b_probed_DVD = true;
1518 /* Couldn't find a VCD or DVD. See if we can find a CD-DA. */
1519 psz_device = ProbeCDDA(disc_device->GetValue());
1522 disc_type->SetSelection(SELECTION_DISC_TYPE_CDDA);
1523 OnDiscTypeChange( dummy_event );
1527 /* Couldn't find a VCD, DVD or CD-DA. Null out the Device name and
1528 set to original selection.
1530 disc_device->SetValue( wxL2U("") );
1531 disc_type->SetSelection(i_selection);
1532 OnDiscTypeChange( dummy_event );
1535 case SELECTION_DISC_TYPE_CDDA:
1536 if(!psz_device) psz_device = ProbeCDDA(disc_device->GetValue());
1539 CdIo_t *p_cdio = cdio_open (psz_device, DRIVER_UNKNOWN);
1540 disc_device->SetValue( wxL2U(psz_device) );
1543 track_t i_last_track = cdio_get_last_track_num(p_cdio);
1544 disc_title->SetRange( 0, i_last_track );
1546 MediaInsertCDDA( p_intf, p_cdio, i_last_track );
1549 cdio_destroy(p_cdio);
1553 /* Not a CD-DA. Try for a DVD unless we've been there before. */
1554 if( !b_probed_DVD && (psz_device = ProbeDVD(disc_device->GetValue())) )
1556 disc_type->SetSelection(SELECTION_DISC_TYPE_DVD_MENUS);
1557 OnDiscTypeChange( dummy_event );
1561 /* Couldn't find a CD-DA or DVD. See if we can find a VCD, unless
1562 we've tried that before. */
1563 if (!b_probed_VCD) psz_device = ProbeVCD(disc_device->GetValue());
1566 disc_type->SetSelection(SELECTION_DISC_TYPE_VCD);
1567 OnDiscTypeChange( dummy_event );
1570 disc_device->SetValue( wxL2U("") );
1574 msg_Err( p_intf, "invalid Disc type selection (%d)",
1575 disc_type->GetSelection() );
1580 disc_probe->SetValue(FALSE);
1582 UpdateMRL( DISC_ACCESS );
1584 #endif /* HAVE_LIBCDIO */
1586 void OpenDialog::OnDiscTypeChange( wxCommandEvent& WXUNUSED(event) )
1588 char *psz_device = NULL;
1590 switch( disc_type->GetSelection() )
1593 case SELECTION_DISC_TYPE_DVD_MENUS:
1594 case SELECTION_DISC_TYPE_DVD:
1595 disc_sub->Enable(); disc_sub_label->Enable();
1596 disc_audio->Enable(); disc_audio_label->Enable();
1597 disc_chapter->Enable(); disc_chapter_label->Enable();
1598 disc_title_label->SetLabel ( wxU(_("Title")) );
1599 psz_device = config_GetPsz( p_intf, "dvd" );
1600 if( !b_disc_device_changed )
1602 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1603 else disc_device->SetValue( wxT("") );
1605 disc_title->SetRange( 0, 255 );
1606 disc_sub->SetRange( -1, 31 ); // up to 32 subtitles -1: no subtitle
1607 disc_audio->SetRange( 0, 7 ); // up to 8 audio channels
1608 disc_chapter->SetRange( 0, 255 );
1609 disc_title->SetToolTip( wxU(_("Title number.")) );
1610 disc_sub->SetToolTip( wxU(_(
1611 "DVD's can have up to 32 subtitles numbered 0..31. "
1612 "Note this is not the same thing as a subtitle name e.g. 'en'. "
1613 "If a value -1 is used, no subtitle will be shown." )) );
1614 disc_audio->SetToolTip( wxU(_("Audio track number. "
1615 "DVD's can have up to 8 audio tracks numbered 0..7."
1619 case SELECTION_DISC_TYPE_VCD:
1620 disc_sub->Enable(); disc_sub_label->Enable();
1621 disc_audio->Enable(); disc_audio_label->Enable();
1622 disc_chapter->Disable(); disc_chapter_label->Disable();
1623 psz_device = config_GetPsz( p_intf, "vcd" );
1624 if( !b_disc_device_changed )
1626 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1627 else disc_device->SetValue( wxT("") );
1631 if (config_GetInt( p_intf, "vcdx-PBC" ))
1633 disc_title_label->SetLabel ( wxT("Playback LID") );
1634 disc_title->SetToolTip( wxU(_(
1635 "Playback control (PBC) usually starts with number 1." )) );
1639 disc_title_label->SetLabel ( wxT("Entry") );
1640 disc_title->SetToolTip( wxU(_(
1641 "The first entry (the beginning of the first MPEG track) is 0." )) );
1645 disc_title_label->SetLabel ( wxU(_("Track")) );
1646 disc_title->SetToolTip( wxU(_("Track number.")) );
1648 disc_title->SetRange( 0, 99 ); // only 100 tracks allowed on VCDs
1649 disc_sub->SetRange( -1, 3 ); // up to 4 subtitles -1 = no subtitle
1650 disc_audio->SetRange( 0, 1 ); // up to 2 audio tracks
1651 disc_sub->SetToolTip( wxU(_(
1652 "SVCD's can have up to 4 subtitles numbered 0..3. "
1653 "If a value -1 is used, no subtitle will be shown." )) );
1654 disc_audio->SetToolTip( wxU(_("Audio track number. "
1655 "VCD's can have up to 2 audio tracks numbered 0 or 1. "
1659 case SELECTION_DISC_TYPE_CDDA:
1660 disc_sub->Disable(); disc_sub_label->Disable();
1661 disc_chapter->Disable(); disc_chapter_label->Disable();
1662 disc_audio->Disable(); disc_audio_label->Disable();
1663 disc_title_label->SetLabel ( wxU(_("Track")) );
1665 disc_title->SetToolTip( wxU(_(
1666 "Audio CDs can have up to 100 tracks, the first track is usually 1. "
1667 "If 0 is given, then all tracks are played.")) );
1669 disc_title->SetToolTip( wxU(_(
1670 "Audio CDs can have up to 100 tracks, the first track is usually 1."
1673 psz_device = config_GetPsz( p_intf, "cd-audio" );
1674 if( !b_disc_device_changed )
1676 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1677 else disc_device->SetValue( wxT("") );
1680 /* There are at most 100 tracks in a CD-DA */
1681 disc_title->SetRange( 0, 100 );
1685 msg_Err( p_intf, "invalid Disc type selection (%d)",
1686 disc_type->GetSelection() );
1690 disc_title->SetValue( 0 ); i_disc_title = 0;
1691 disc_chapter->SetValue( 0 ); i_disc_chapter = 0;
1693 if( psz_device ) free( psz_device );
1695 UpdateMRL( DISC_ACCESS );
1698 /*****************************************************************************
1699 * Net panel event methods.
1700 *****************************************************************************/
1701 void OpenDialog::OnNetPanelChangeSpin( wxSpinEvent& event )
1703 wxCommandEvent cevent;
1704 cevent.SetId(event.GetId());
1705 cevent.SetInt(event.GetPosition());
1706 OnNetPanelChange(cevent);
1709 void OpenDialog::OnNetPanelChange( wxCommandEvent& event )
1711 if( event.GetId() >= NetPort1_Event && event.GetId() <= NetPort3_Event )
1713 i_net_ports[event.GetId() - NetPort1_Event] = event.GetInt();
1716 UpdateMRL( NET_ACCESS );
1719 void OpenDialog::OnNetTypeChange( wxCommandEvent& event )
1723 i_net_type = event.GetId() - NetRadio1_Event;
1727 net_radios[i]->SetValue( event.GetId() == (NetRadio1_Event+i) );
1728 net_subpanels[i]->Enable( event.GetId() == (NetRadio1_Event+i) );
1730 /* UDP Unicast or multicast -> timeshift */
1731 if( i_net_type == 0 || i_net_type == 1 )
1732 net_timeshift->Enable();
1734 net_timeshift->Disable();
1736 UpdateMRL( NET_ACCESS );
1739 /*****************************************************************************
1740 * Subtitles file event methods.
1741 *****************************************************************************/
1742 void OpenDialog::OnSubsFileEnable( wxCommandEvent& event )
1744 subsfile_button->Enable( event.GetInt() != 0 );
1747 void OpenDialog::OnSubsFileSettings( wxCommandEvent& WXUNUSED(event) )
1749 /* Show/hide the open dialog */
1750 if( subsfile_dialog == NULL )
1751 subsfile_dialog = new SubsFileDialog( p_intf, this );
1753 if( subsfile_dialog && subsfile_dialog->ShowModal() == wxID_OK )
1755 subsfile_mrl.Empty();
1756 subsfile_mrl.Add( wxString(wxT("sub-file=")) +
1757 subsfile_dialog->file_combo->GetValue() );
1758 if( subsfile_dialog->encoding_combo )
1760 subsfile_mrl.Add( wxString(wxT("subsdec-encoding=")) +
1761 subsfile_dialog->encoding_combo->GetValue() );
1763 if( subsfile_dialog->align_combo )
1765 subsfile_mrl.Add( wxString::Format(wxT("subsdec-align=%i"),
1766 (int)subsfile_dialog->align_combo->GetClientData(
1767 subsfile_dialog->align_combo->GetSelection()) ) );
1769 if( subsfile_dialog->size_combo )
1771 subsfile_mrl.Add( wxString::Format( wxT("freetype-rel-fontsize=%i"),
1772 (int)subsfile_dialog->size_combo->GetClientData(
1773 subsfile_dialog->size_combo->GetSelection()) ) );
1775 subsfile_mrl.Add( wxString::Format( wxT("sub-fps=%i"),
1776 subsfile_dialog->fps_spinctrl->GetValue() ) );
1777 subsfile_mrl.Add( wxString::Format( wxT("sub-delay=%i"),
1778 subsfile_dialog->delay_spinctrl->GetValue() ) );
1782 /*****************************************************************************
1783 * Stream output event methods.
1784 *****************************************************************************/
1785 void OpenDialog::OnSoutEnable( wxCommandEvent& event )
1787 sout_button->Enable( event.GetInt() != 0 );
1790 void OpenDialog::OnSoutSettings( wxCommandEvent& WXUNUSED(event) )
1792 /* Show/hide the open dialog */
1793 if( sout_dialog == NULL )
1794 sout_dialog = new SoutDialog( p_intf, this );
1796 if( sout_dialog && sout_dialog->ShowModal() == wxID_OK )
1798 sout_mrl = sout_dialog->GetOptions();
1802 /*****************************************************************************
1803 * Caching event methods.
1804 *****************************************************************************/
1805 void OpenDialog::OnCachingEnable( wxCommandEvent& event )
1807 caching_value->Enable( event.GetInt() != 0 );
1808 i_caching = caching_value->GetValue();
1812 void OpenDialog::OnCachingChangeSpin( wxSpinEvent& event )
1814 wxCommandEvent cevent;
1815 OnCachingChange(cevent);
1818 void OpenDialog::OnCachingChange( wxCommandEvent& event )
1820 i_caching = event.GetInt();
1824 /*****************************************************************************
1825 * Utility functions.
1826 *****************************************************************************/
1827 wxArrayString SeparateEntries( wxString entries )
1829 vlc_bool_t b_quotes_mode = VLC_FALSE;
1831 wxArrayString entries_array;
1834 wxStringTokenizer token( entries, wxT(" \t\r\n\""), wxTOKEN_RET_DELIMS );
1836 while( token.HasMoreTokens() )
1838 entry += token.GetNextToken();
1840 if( entry.IsEmpty() ) continue;
1842 if( !b_quotes_mode && entry.Last() == wxT('\"') )
1844 /* Enters quotes mode */
1846 b_quotes_mode = VLC_TRUE;
1848 else if( b_quotes_mode && entry.Last() == wxT('\"') )
1850 /* Finished the quotes mode */
1852 b_quotes_mode = VLC_FALSE;
1854 else if( !b_quotes_mode && entry.Last() != wxT('\"') )
1856 /* we found a non-quoted standalone string */
1857 if( token.HasMoreTokens() ||
1858 entry.Last() == wxT(' ') || entry.Last() == wxT('\t') ||
1859 entry.Last() == wxT('\r') || entry.Last() == wxT('\n') )
1861 if( !entry.IsEmpty() ) entries_array.Add( entry );
1868 if( !entry.IsEmpty() ) entries_array.Add( entry );
1870 return entries_array;