1 /*****************************************************************************
2 * open.cpp : Open dialog box
3 *****************************************************************************
4 * Copyright (C) 2000-2005 the VideoLAN team
7 * Authors: Gildas Bazin <gbazin@videolan.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
27 #include "dialogs/open.hpp"
28 #include "dialogs/streamout.hpp"
29 #include "dialogs/preferences_widgets.h"
30 #include "dialogs/subtitles.hpp"
34 #undef HAVE_LIBCDIO // Disable broken code
37 #include <cdio/cdio.h>
38 #include <cdio/cd_types.h>
39 #include <cdio/logging.h>
40 #endif /* HAVE_LIBCDIO */
43 #include <libvcd/version.h>
44 /* There was a bug in libvcdinfo <= 23 which prevented C++ compilation */
45 #if LIBVCD_VERSION_NUM > 23
46 #include <libvcd/info.h>
47 #endif /* LIBVCD_VERSION_NUM > 23 */
48 #endif /* HAVE_VCDINFO */
50 #include <wx/combobox.h>
51 #include <wx/statline.h>
52 #include <wx/tokenzr.h>
58 # define wxRB_SINGLE 0
61 #define SELECTION_DISC_TYPE_DVD_MENUS 0
62 #define SELECTION_DISC_TYPE_DVD 1
63 #define SELECTION_DISC_TYPE_VCD 2
64 #define SELECTION_DISC_TYPE_CDDA 3
66 /*****************************************************************************
68 *****************************************************************************/
70 /* IDs for the controls and the menu commands */
73 Notebook_Event = wxID_HIGHEST,
92 NetRadio1_Event, NetRadio2_Event, NetRadio3_Event, NetRadio4_Event,
93 NetPort1_Event, NetPort2_Event, NetPort3_Event,
94 NetAddr1_Event, NetAddr2_Event, NetAddr3_Event, NetAddr4_Event,
95 NetForceIPv6_Event, NetTimeshift_Event,
98 SubsFileSettings_Event,
106 AdvancedOptions_Event
109 BEGIN_EVENT_TABLE(OpenDialog, wxDialog)
111 EVT_BUTTON(wxID_OK, OpenDialog::OnOk)
112 EVT_BUTTON(wxID_CANCEL, OpenDialog::OnCancel)
114 EVT_NOTEBOOK_PAGE_CHANGED(Notebook_Event, OpenDialog::OnPageChange)
116 EVT_TEXT(MRL_Event, OpenDialog::OnMRLChange)
118 /* Events generated by the file panel */
119 EVT_TEXT(FileName_Event, OpenDialog::OnFilePanelChange)
120 EVT_BUTTON(FileBrowse_Event, OpenDialog::OnFileBrowse)
121 EVT_TEXT(SubFileName_Event, OpenDialog::OnSubFileChange)
122 EVT_BUTTON(SubFileBrowse_Event, OpenDialog::OnSubFileBrowse)
124 /* Events generated by the disc panel */
125 EVT_RADIOBOX(DiscType_Event, OpenDialog::OnDiscTypeChange)
127 EVT_CHECKBOX(DiscProbe_Event, OpenDialog::OnDiscProbe)
129 EVT_TEXT(DiscDevice_Event, OpenDialog::OnDiscDeviceChange)
130 EVT_TEXT(DiscDevice_Event, OpenDialog::OnDiscPanelChange)
131 EVT_TEXT(DiscTitle_Event, OpenDialog::OnDiscPanelChange)
132 EVT_SPINCTRL(DiscTitle_Event, OpenDialog::OnDiscPanelChangeSpin)
133 EVT_TEXT(DiscChapter_Event, OpenDialog::OnDiscPanelChange)
134 EVT_SPINCTRL(DiscChapter_Event, OpenDialog::OnDiscPanelChangeSpin)
135 EVT_TEXT(DiscSub_Event, OpenDialog::OnDiscPanelChange)
136 EVT_TEXT(DiscAudio_Event, OpenDialog::OnDiscPanelChange)
137 EVT_SPINCTRL(DiscSub_Event, OpenDialog::OnDiscPanelChangeSpin)
139 /* Events generated by the net panel */
140 EVT_RADIOBUTTON(NetRadio1_Event, OpenDialog::OnNetTypeChange)
141 EVT_RADIOBUTTON(NetRadio2_Event, OpenDialog::OnNetTypeChange)
142 EVT_RADIOBUTTON(NetRadio3_Event, OpenDialog::OnNetTypeChange)
143 EVT_RADIOBUTTON(NetRadio4_Event, OpenDialog::OnNetTypeChange)
144 EVT_TEXT(NetPort1_Event, OpenDialog::OnNetPanelChange)
145 EVT_SPINCTRL(NetPort1_Event, OpenDialog::OnNetPanelChangeSpin)
146 EVT_TEXT(NetPort2_Event, OpenDialog::OnNetPanelChange)
147 EVT_SPINCTRL(NetPort2_Event, OpenDialog::OnNetPanelChangeSpin)
148 EVT_TEXT(NetPort3_Event, OpenDialog::OnNetPanelChange)
149 EVT_SPINCTRL(NetPort3_Event, OpenDialog::OnNetPanelChangeSpin)
150 EVT_TEXT(NetAddr2_Event, OpenDialog::OnNetPanelChange)
151 EVT_TEXT(NetAddr3_Event, OpenDialog::OnNetPanelChange)
152 EVT_TEXT(NetAddr4_Event, OpenDialog::OnNetPanelChange)
153 EVT_CHECKBOX(NetForceIPv6_Event, OpenDialog::OnNetPanelChange)
154 EVT_CHECKBOX(NetTimeshift_Event, OpenDialog::OnNetPanelChange)
156 /* Events generated by the subtitle file buttons */
157 EVT_CHECKBOX(SubsFileEnable_Event, OpenDialog::OnSubsFileEnable)
158 EVT_BUTTON(SubsFileSettings_Event, OpenDialog::OnSubsFileSettings)
160 /* Events generated by the stream output buttons */
161 EVT_CHECKBOX(SoutEnable_Event, OpenDialog::OnSoutEnable)
162 EVT_BUTTON(SoutSettings_Event, OpenDialog::OnSoutSettings)
164 /* Events generated by the caching button */
165 EVT_CHECKBOX(CachingEnable_Event, OpenDialog::OnCachingEnable)
166 EVT_TEXT(CachingChange_Event, OpenDialog::OnCachingChange)
167 EVT_SPINCTRL(CachingChange_Event, OpenDialog::OnCachingChangeSpin)
169 /* Hide the window when the user closes the window */
170 EVT_CLOSE(OpenDialog::OnClose)
175 /*****************************************************************************
177 *****************************************************************************/
178 WX_DEFINE_ARRAY(ConfigControl *, ArrayOfConfigControls);
180 class AutoBuiltPanel : public wxPanel
185 AutoBuiltPanel( wxWindow *, OpenDialog *, intf_thread_t *,
188 virtual ~AutoBuiltPanel() {}
190 void UpdateAdvancedMRL();
193 ArrayOfConfigControls config_array;
194 ArrayOfConfigControls advanced_config_array;
195 wxComboBox *p_advanced_mrl_combo;
198 intf_thread_t *p_intf;
199 OpenDialog *p_open_dialog;
201 void OnAdvanced( wxCommandEvent& event );
202 wxDialog *p_advanced_dialog;
204 DECLARE_EVENT_TABLE();
207 BEGIN_EVENT_TABLE(AutoBuiltPanel, wxPanel)
208 EVT_BUTTON(AdvancedOptions_Event, AutoBuiltPanel::OnAdvanced)
211 static void AutoBuildCallback( void *p_data )
213 ((OpenDialog *)p_data)->UpdateMRL();
216 static void AutoBuildAdvancedCallback( void *p_data )
218 ((AutoBuiltPanel *)p_data)->UpdateAdvancedMRL();
221 AutoBuiltPanel::AutoBuiltPanel( wxWindow *parent, OpenDialog *dialog,
222 intf_thread_t *_p_intf,
223 const module_t *p_module )
224 : wxPanel( parent, -1, wxDefaultPosition, wxDefaultSize ),
225 name( wxU(p_module->psz_object_name) ),
226 p_advanced_mrl_combo( NULL ),
227 p_intf( _p_intf ), p_open_dialog( dialog ), p_advanced_dialog( NULL )
229 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
230 module_config_t *p_item = p_module->p_config;
231 bool b_advanced = false;
235 if( !(p_item->i_type & CONFIG_HINT) && p_item->b_advanced )
238 if( p_item->i_type & CONFIG_HINT || p_item->b_advanced )
241 ConfigControl *control =
242 CreateConfigControl( VLC_OBJECT(p_intf), p_item, this );
244 config_array.Add( control );
246 /* Don't add items that were not recognized */
247 if( control == NULL ) continue;
249 control->SetUpdateCallback( AutoBuildCallback, (void *)dialog );
251 sizer->Add( control, 0, wxEXPAND | wxALL, 2 );
253 while( p_item->i_type != CONFIG_HINT_END && p_item++ );
258 new wxButton( this, AdvancedOptions_Event,
259 wxU(_("Advanced options...")) );
260 sizer->Add( button, 0, wxALL, 5 );
262 /* Build the advanced dialog */
264 new wxDialog( this, -1, ((wxString)wxU(_("Advanced options"))) +
265 wxT(" (") + wxU( p_module->psz_longname ) + wxT(")"),
266 wxDefaultPosition, wxDefaultSize,
267 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER );
269 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
271 /* Create MRL combobox */
272 wxBoxSizer *mrl_sizer_sizer = new wxBoxSizer( wxHORIZONTAL );
273 wxStaticBox *mrl_box =
274 new wxStaticBox( p_advanced_dialog, -1,
275 wxU(_("Advanced options")) );
276 wxStaticBoxSizer *mrl_sizer =
277 new wxStaticBoxSizer( mrl_box, wxHORIZONTAL );
278 wxStaticText *mrl_label =
279 new wxStaticText( p_advanced_dialog, -1, wxU(_("Options:")) );
280 p_advanced_mrl_combo =
281 new wxComboBox( p_advanced_dialog, MRL_Event, wxT(""),
282 wxDefaultPosition, wxDefaultSize );
283 mrl_sizer->Add( mrl_label, 0, wxALL | wxALIGN_CENTER, 5 );
284 mrl_sizer->Add( p_advanced_mrl_combo, 1, wxALL | wxALIGN_CENTER, 5 );
285 mrl_sizer_sizer->Add( mrl_sizer, 1, wxEXPAND | wxALL, 5 );
286 sizer->Add( mrl_sizer_sizer, 0, wxEXPAND | wxALL, 2 );
288 /* Add advanced options to panel */
289 module_config_t *p_item = p_module->p_config;
292 if( p_item->i_type & CONFIG_HINT || !p_item->b_advanced )
295 ConfigControl *control =
296 CreateConfigControl( VLC_OBJECT(p_intf), p_item,
299 advanced_config_array.Add( control );
301 /* Don't add items that were not recognized */
302 if( control == NULL ) continue;
304 control->SetUpdateCallback( AutoBuildAdvancedCallback,
307 sizer->Add( control, 0, wxEXPAND | wxALL, 2 );
309 while( p_item->i_type != CONFIG_HINT_END && p_item++ );
312 wxPanel *dummy_panel = new wxPanel( p_advanced_dialog, -1 );
313 sizer->Add( dummy_panel, 1 );
314 wxStaticLine *static_line =
315 new wxStaticLine( p_advanced_dialog, wxID_OK );
316 sizer->Add( static_line, 0, wxEXPAND | wxALL, 5 );
319 wxButton *ok_button =
320 new wxButton( p_advanced_dialog, wxID_OK, wxU(_("&OK")) );
321 ok_button->SetDefault();
322 wxButton *cancel_button =
323 new wxButton( p_advanced_dialog, wxID_CANCEL, wxU(_("&Cancel")) );
324 wxStdDialogButtonSizer *button_sizer = new wxStdDialogButtonSizer;
325 button_sizer->AddButton( ok_button );
326 button_sizer->AddButton( cancel_button );
327 button_sizer->Realize();
328 sizer->Add( button_sizer, 0, wxEXPAND|wxALL, 5 );
330 sizer->SetMinSize( 400, -1 );
331 p_advanced_dialog->SetSizerAndFit( sizer );
334 this->SetSizerAndFit( sizer );
337 void AutoBuiltPanel::OnAdvanced( wxCommandEvent& event )
339 if( p_advanced_dialog->ShowModal() == wxID_OK )
342 p_open_dialog->UpdateMRL();
346 void AutoBuiltPanel::UpdateAdvancedMRL()
350 for( int i = 0; i < (int)advanced_config_array.GetCount(); i++ )
352 ConfigControl *control = advanced_config_array.Item(i);
354 mrltemp += (i ? wxT(" :") : wxT(":"));
356 if( control->GetType() == CONFIG_ITEM_BOOL &&
357 !control->GetIntValue() ) mrltemp += wxT("no-");
359 mrltemp += control->GetName();
361 switch( control->GetType() )
363 case CONFIG_ITEM_STRING:
364 case CONFIG_ITEM_FILE:
365 case CONFIG_ITEM_DIRECTORY:
366 case CONFIG_ITEM_MODULE:
367 mrltemp += wxT("=\"") + control->GetPszValue() + wxT("\"");
369 case CONFIG_ITEM_INTEGER:
371 wxString::Format( wxT("=%i"), control->GetIntValue() );
373 case CONFIG_ITEM_FLOAT:
375 wxString::Format(wxT("=%f"), control->GetFloatValue());
380 p_advanced_mrl_combo->SetValue( mrltemp );
383 /*****************************************************************************
385 *****************************************************************************/
386 OpenDialog::OpenDialog( intf_thread_t *_p_intf, wxWindow *_p_parent,
387 int i_access_method, int i_arg ):
388 wxDialog( _p_parent, -1, wxU(_("Open...")), wxDefaultPosition,
389 wxDefaultSize, wxDEFAULT_FRAME_STYLE )
391 OpenDialog( _p_intf, _p_parent, i_access_method, i_arg, OPEN_NORMAL );
394 OpenDialog::OpenDialog( intf_thread_t *_p_intf, wxWindow *_p_parent,
395 int i_access_method, int i_arg, int _i_method ):
396 wxDialog( _p_parent, -1, wxU(_("Open...")), wxDefaultPosition,
397 wxDefaultSize, wxDEFAULT_FRAME_STYLE )
399 /* Initializations */
400 i_method = _i_method;
402 p_parent = _p_parent;
403 SetIcon( *p_intf->p_sys->p_icon );
405 i_disc_type_selection = 0;
410 subsfile_dialog = NULL;
411 b_disc_device_changed = false;
413 /* Create a panel to put everything in */
414 wxPanel *panel = new wxPanel( this, -1 );
415 panel->SetAutoLayout( TRUE );
418 /* Advanced options */
419 wxStaticBox *adv_box = new wxStaticBox( panel, -1,
420 wxU(_("Advanced options")) );
421 wxStaticBoxSizer *adv_sizer = new wxStaticBoxSizer( adv_box,
425 wxFlexGridSizer *common_opt_sizer = new wxFlexGridSizer( 5, 1, 20 );
426 if( i_method == OPEN_NORMAL )
428 /* Create Stream Output checkox */
429 sout_checkbox = new wxCheckBox( panel, SoutEnable_Event,
430 wxU(_("Stream/Save")) );
431 sout_checkbox->SetToolTip( wxU(_("Use VLC as a stream server")) );
432 common_opt_sizer->Add( sout_checkbox, 0,
433 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
435 sout_button = new wxButton( panel, SoutSettings_Event,
436 wxU(_("Settings...")) );
437 sout_button->Disable();
439 char *psz_sout = config_GetPsz( p_intf, "sout" );
440 if( psz_sout && *psz_sout )
442 sout_checkbox->SetValue(TRUE);
443 sout_button->Enable();
444 subsfile_mrl.Add( wxString(wxT("sout=")) + wxL2U(psz_sout) );
446 if( psz_sout ) free( psz_sout );
448 common_opt_sizer->Add( sout_button, 1, wxALIGN_LEFT |
449 wxALIGN_CENTER_VERTICAL );
451 common_opt_sizer->Add( new wxPanel( this, -1 ), 1,
452 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
455 /* Create caching options */
456 caching_checkbox = new wxCheckBox( panel, CachingEnable_Event,
458 caching_checkbox->SetToolTip( wxU(_("Change the default caching value "
459 "(in milliseconds)")) );
460 common_opt_sizer->Add( caching_checkbox, 0,
461 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
462 caching_value = new wxSpinCtrl( panel, CachingChange_Event );
463 caching_value->SetRange( 0, 1000000 );
464 caching_value->Disable();
465 common_opt_sizer->Add( caching_value, 0,
466 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
469 wxBoxSizer *mrl_sizer = new wxBoxSizer( wxHORIZONTAL );
470 wxStaticText *mrl_label = new wxStaticText( panel, -1,
471 wxU(_("Customize:")) );
472 mrl_combo = new wxComboBox( panel, MRL_Event, wxT(""),
473 wxDefaultPosition, wxDefaultSize );
474 //Point(20,25), wxSize(120, -1) );
475 mrl_combo->SetToolTip( wxU(_("You can use this field directly by typing "
476 "the full MRL you want to open.\n""Alternatively, the field will be "
477 "filled automatically when you use the controls above.")) );
479 mrl_sizer->Add( mrl_label, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
480 mrl_sizer->Add( mrl_combo, 1, wxALL | wxEXPAND | wxALIGN_CENTER_VERTICAL,
483 adv_sizer->Add( common_opt_sizer, 0, wxTOP | wxLEFT|wxRIGHT | wxEXPAND, 5 );
484 adv_sizer->Add( mrl_sizer, 0, wxBOTTOM | wxLEFT|wxRIGHT | wxEXPAND, 5 );
487 wxStaticLine *static_line = new wxStaticLine( panel, wxID_OK );
489 /* Create the buttons */
490 wxButton *ok_button = new wxButton( panel, wxID_OK, wxU(_("&OK")) );
491 ok_button->SetDefault();
492 wxButton *cancel_button = new wxButton( panel, wxID_CANCEL,
495 /* Create notebook */
496 notebook = new wxNotebook( panel, Notebook_Event );
498 #if (!wxCHECK_VERSION(2,5,2))
499 wxNotebookSizer *notebook_sizer = new wxNotebookSizer( notebook );
502 notebook->AddPage( FilePanel( notebook ), wxU(_("File")),
503 i_access_method == FILE_ACCESS );
504 notebook->AddPage( DiscPanel( notebook ), wxU(_("Disc")),
505 i_access_method == DISC_ACCESS );
506 notebook->AddPage( NetPanel( notebook ), wxU(_("Network")),
507 i_access_method == NET_ACCESS );
509 module_t *p_module = config_FindModule( VLC_OBJECT(p_intf), "v4l" );
512 AutoBuiltPanel *autopanel =
513 new AutoBuiltPanel( notebook, this, p_intf, p_module );
514 input_tab_array.Add( autopanel );
515 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
516 p_module->psz_shortname : p_module->psz_object_name ),
517 i_access_method == CAPTURE_ACCESS );
520 p_module = config_FindModule( VLC_OBJECT(p_intf), "pvr" );
523 AutoBuiltPanel *autopanel =
524 new AutoBuiltPanel( notebook, this, p_intf, p_module );
525 input_tab_array.Add( autopanel );
526 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
527 p_module->psz_shortname : p_module->psz_object_name ),
528 i_access_method == CAPTURE_ACCESS );
531 p_module = config_FindModule( VLC_OBJECT(p_intf), "dvb" );
534 AutoBuiltPanel *autopanel =
535 new AutoBuiltPanel( notebook, this, p_intf, p_module );
536 input_tab_array.Add( autopanel );
537 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
538 p_module->psz_shortname : p_module->psz_object_name ),
539 i_access_method == CAPTURE_ACCESS );
542 p_module = config_FindModule( VLC_OBJECT(p_intf), "dshow" );
545 AutoBuiltPanel *autopanel =
546 new AutoBuiltPanel( notebook, this, p_intf, p_module );
547 input_tab_array.Add( autopanel );
548 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ?
549 p_module->psz_shortname : p_module->psz_object_name ),
550 i_access_method == CAPTURE_ACCESS );
553 /* Update Disc panel */
554 wxCommandEvent dummy_event;
555 OnDiscTypeChange( dummy_event );
557 /* Update Net panel */
558 dummy_event.SetId( NetRadio1_Event );
559 OnNetTypeChange( dummy_event );
562 wxNotebookEvent event( wxEVT_NULL, 0, i_access_method );
563 OnPageChange( event );
565 /* Place everything in sizers */
566 wxStdDialogButtonSizer *button_sizer = new wxStdDialogButtonSizer;
567 button_sizer->AddButton( cancel_button );
568 button_sizer->AddButton( ok_button );
569 button_sizer->Realize();
570 wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL );
571 wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
572 #if (!wxCHECK_VERSION(2,5,2))
573 panel_sizer->Add( notebook_sizer, 1, wxEXPAND | wxALL, 5 );
575 panel_sizer->Add( notebook, 1, wxEXPAND | wxALL, 5 );
577 panel_sizer->Add( adv_sizer, 0, wxEXPAND | wxALL, 5 );
578 panel_sizer->Add( static_line, 0, wxEXPAND | wxALL, 5 );
579 panel_sizer->Add( button_sizer, 0, wxEXPAND | wxALL, 5 );
580 panel_sizer->Layout();
581 panel->SetSizerAndFit( panel_sizer );
582 main_sizer->Add( panel, 1, wxGROW, 0 );
583 main_sizer->Layout();
584 SetSizerAndFit( main_sizer );
587 OpenDialog::~OpenDialog()
590 if( file_dialog ) delete file_dialog;
591 if( sout_dialog ) delete sout_dialog;
592 if( subsfile_dialog ) delete subsfile_dialog;
595 int OpenDialog::Show( int i_access_method, int i_arg )
597 notebook->SetSelection( i_access_method );
598 int i_ret = wxDialog::Show();
605 int OpenDialog::Show()
607 int i_ret = wxDialog::Show();
613 /*****************************************************************************
615 *****************************************************************************/
616 wxPanel *OpenDialog::FilePanel( wxWindow* parent )
618 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
621 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
623 /* Create browse file line */
624 wxBoxSizer *file_sizer = new wxBoxSizer( wxHORIZONTAL );
626 file_sizer->Add( new wxStaticText( panel, -1, wxU(_("Open:") ) ), 0,
627 wxALL | wxALIGN_CENTER_VERTICAL, 5 );
629 file_combo = new wxComboBox( panel, FileName_Event, wxT("") );
630 wxButton *browse_button = new wxButton( panel, FileBrowse_Event,
631 wxU(_("Browse...")) );
632 file_sizer->Add( file_combo, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
633 file_sizer->Add( browse_button, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
635 /* Create Subtitles File checkox - button */
636 wxFlexGridSizer *subtitles_sizer = new wxFlexGridSizer( 2, 1, 20 );
637 subsfile_checkbox = new wxCheckBox( panel, SubsFileEnable_Event,
638 wxU(_("Use a subtitles file")) );
639 subsfile_checkbox->SetToolTip( wxU(_("Use an external subtitles file.")) );
640 subtitles_sizer->Add( subsfile_checkbox, 0, wxALIGN_CENTER_VERTICAL |
642 subsfile_button = new wxButton( panel, SubsFileSettings_Event,
643 wxU(_("Advanced Settings...")) );
644 subsfile_button->Disable();
645 subtitles_sizer->Add( subsfile_button, 1, wxALIGN_CENTER_VERTICAL |
648 /* Create subtitles file line */
649 wxBoxSizer *subfile_sizer = new wxBoxSizer( wxHORIZONTAL );
651 char *psz_subsfile = config_GetPsz( p_intf, "sub-file" );
652 if( psz_subsfile && *psz_subsfile )
654 subsfile_checkbox->SetValue(TRUE);
655 subsfile_button->Enable();
656 subsfile_mrl.Add( wxString(wxT("sub-file=")) + wxL2U(psz_subsfile) );
658 if( !psz_subsfile ) psz_subsfile = strdup("");
659 subfile_sizer->Add( new wxStaticText( panel, -1, wxU(_("File:") ) ),
660 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
661 subfile_combo = new wxComboBox( panel, SubFileName_Event,
662 wxL2U( psz_subsfile ) );
663 if( psz_subsfile ) free( psz_subsfile );
664 subbrowse_button = new wxButton( panel, SubFileBrowse_Event,
665 wxU(_("Browse...")) );
666 subfile_sizer->Add( subfile_combo, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
667 subfile_sizer->Add( subbrowse_button, 0, wxALL |wxALIGN_CENTER_VERTICAL, 5 );
669 subfile_combo->Disable();
670 subbrowse_button->Disable();
672 psz_subsfile = config_GetPsz( p_intf, "sub-file" );
673 if( psz_subsfile && *psz_subsfile )
675 subfile_combo->Enable();
676 subbrowse_button->Enable();
679 sizer->Add( file_sizer, 0, wxEXPAND | wxALL, 5 );
680 sizer->Add( subtitles_sizer, 0, wxLEFT | wxRIGHT | wxTOP, 5 );
681 sizer->Add( subfile_sizer, 0, wxEXPAND | wxLEFT | wxRIGHT| wxBOTTOM, 5 );
682 panel->SetSizerAndFit( sizer );
686 wxPanel *OpenDialog::DiscPanel( wxWindow* parent )
688 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
691 wxBoxSizer *sizer_row = new wxBoxSizer( wxVERTICAL );
692 wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 3, 20 );
694 static const wxString disc_type_array[] =
696 wxU(_("DVD (menus)")),
702 disc_type = new wxRadioBox( panel, DiscType_Event, wxU(_("Disc type")),
703 wxDefaultPosition, wxDefaultSize,
704 WXSIZEOF(disc_type_array), disc_type_array,
705 WXSIZEOF(disc_type_array), wxRA_SPECIFY_COLS );
708 disc_probe = new wxCheckBox( panel, DiscProbe_Event,
709 wxU(_("Probe Disc(s)")) );
710 disc_probe->SetToolTip( wxU(_("Probe for a DVD, VCD or audio CD. "
711 "First try the Device name entered for the selected Disc type "
712 "(DVD, DVD Menu, VCD, audio CD). If that doesn't find media, try any device "
713 "for the Disc type. If that doesn't work, then try looking for CD-ROMs or "
714 "DVD drives. The Disc type, Device name, and some parameter ranges are set "
715 "based on media we find.")) );
718 sizer_row->Add( disc_type, i_disc_type_selection, wxEXPAND | wxALL, 5 );
720 sizer_row->Add( disc_probe, 0, wxEXPAND | wxALL );
723 wxStaticText *label = new wxStaticText( panel, -1, wxU(_("Device name")) );
724 disc_device = new wxTextCtrl( panel, DiscDevice_Event, wxT(""),
725 wxDefaultPosition, wxDefaultSize,
729 char psz_default_device[3] = {0};
732 /* find the drive_name for the first cdrom drive,
733 * which is probably "D:" and put the drive_name into
734 * psz_default_device... */
735 for( char drive_letter = 'A'; drive_letter <= 'Z'; ++drive_letter )
737 char drive_name[3] = {drive_letter, ':', 0};
738 UINT type = GetDriveTypeA( drive_name );
739 if( type == DRIVE_CDROM )
741 psz_default_device[0] = drive_letter;
742 psz_default_device[1] = ':';
747 psz_forced = config_GetPsz( p_intf, "dvd" );
749 if( strlen(psz_default_device) > 0 &&
750 ( !psz_forced || psz_forced && !*psz_forced ) )
753 disc_device->SetValue( wxL2U(psz_default_device) );
757 sizer->Add( label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
758 sizer->Add( disc_device, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
760 disc_title_label = new wxStaticText( panel, -1, wxU(_("Title")) );
761 disc_title = new wxSpinCtrl( panel, DiscTitle_Event );
762 sizer->Add( disc_title_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
763 sizer->Add( disc_title, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
765 disc_chapter_label = new wxStaticText( panel, -1, wxU(_("Chapter")) );
766 disc_chapter = new wxSpinCtrl( panel, DiscChapter_Event );
767 sizer->Add( disc_chapter_label, 0,
768 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
769 sizer->Add( disc_chapter, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
771 disc_sub_label = new wxStaticText( panel, -1, wxU(_("Subtitles track")) );
772 disc_sub = new wxSpinCtrl( panel, DiscSub_Event );
773 sizer->Add( disc_sub_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
774 sizer->Add( disc_sub, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
775 disc_sub->SetRange( -1, 255 );
776 i_disc_sub = config_GetInt( p_intf, "sub-track" );
777 disc_sub->SetValue( i_disc_sub );
779 disc_audio_label = new wxStaticText( panel, -1, wxU(_("Audio track")) );
780 disc_audio = new wxSpinCtrl( panel, DiscAudio_Event );
781 sizer->Add( disc_audio_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
782 sizer->Add( disc_audio, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
783 disc_audio->SetRange( -1, 255 );
784 i_disc_audio = config_GetInt( p_intf, "audio-track" );
785 disc_audio->SetValue( i_disc_audio );
787 sizer_row->Add( sizer, 0, wxEXPAND | wxALL, 5 );
789 panel->SetSizerAndFit( sizer_row );
793 wxPanel *OpenDialog::NetPanel( wxWindow* parent )
796 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
799 wxBoxSizer *sizer_row = new wxBoxSizer( wxVERTICAL );
800 wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 4, 20 );
802 static const wxString net_type_array[] =
805 wxU(_("UDP/RTP Multicast")),
806 wxU(_("HTTP/HTTPS/FTP/MMS")),
812 net_radios[i] = new wxRadioButton( panel, NetRadio1_Event + i,
814 wxDefaultPosition, wxDefaultSize,
817 net_subpanels[i] = new wxPanel( panel, -1,
818 wxDefaultPosition, wxDefaultSize );
822 net_timeshift = new wxCheckBox( panel, NetTimeshift_Event,
823 wxU(_("Allow timeshifting")) );
826 wxFlexGridSizer *subpanel_sizer;
828 i_net_ports[0] = config_GetInt( p_intf, "server-port" );
829 subpanel_sizer = new wxFlexGridSizer( 3, 1, 20 );
830 label = new wxStaticText( net_subpanels[0], -1, wxU(_("Port")) );
831 net_ports[0] = new wxSpinCtrl( net_subpanels[0], NetPort1_Event,
832 wxString::Format(wxT("%d"), i_net_ports[0]),
833 wxDefaultPosition, wxDefaultSize,
835 0, 65535, i_net_ports[0] );
837 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
838 subpanel_sizer->Add( net_ports[0], 1,
839 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
840 net_ipv6 = new wxCheckBox( net_subpanels[0], NetForceIPv6_Event,
841 wxU(_("Force IPv6")));
842 subpanel_sizer->Add( net_ipv6, 0,
843 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
844 net_subpanels[0]->SetSizerAndFit( subpanel_sizer );
845 net_radios[0]->SetValue( TRUE );
847 /* UDP/RTP Multicast row */
848 subpanel_sizer = new wxFlexGridSizer( 4, 1, 20 );
849 label = new wxStaticText( net_subpanels[1], -1, wxU(_("Address")) );
850 net_addrs[1] = new wxTextCtrl( net_subpanels[1], NetAddr2_Event, wxT(""),
851 wxDefaultPosition, wxDefaultSize,
853 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
854 subpanel_sizer->Add( net_addrs[1], 1,
855 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
857 label = new wxStaticText( net_subpanels[1], -1, wxU(_("Port")) );
858 i_net_ports[1] = i_net_ports[0];
859 net_ports[1] = new wxSpinCtrl( net_subpanels[1], NetPort2_Event,
860 wxString::Format(wxT("%d"), i_net_ports[1]),
861 wxDefaultPosition, wxDefaultSize,
863 0, 65535, i_net_ports[1] );
865 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
866 subpanel_sizer->Add( net_ports[1], 1,
867 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
868 net_subpanels[1]->SetSizerAndFit( subpanel_sizer );
870 /* HTTP and RTSP rows */
873 subpanel_sizer = new wxFlexGridSizer( 2, 1, 20 );
874 label = new wxStaticText( net_subpanels[i], -1, wxU(_("URL")) );
875 net_addrs[i] = new wxTextCtrl( net_subpanels[i], NetAddr1_Event + i,
876 (i == 2) ? wxT("") : wxT("rtsp://"),
877 wxDefaultPosition, wxSize( 200, -1 ),
879 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
880 subpanel_sizer->Add( net_addrs[i], 1,
881 wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
882 net_subpanels[i]->SetSizerAndFit( subpanel_sizer );
885 /* Stuff everything into the main panel */
888 sizer->Add( net_radios[i], 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
890 sizer->Add( net_subpanels[i], 1, wxEXPAND | wxALIGN_LEFT |
891 wxALIGN_CENTER_VERTICAL | wxALL, 5 );
893 sizer->Add( net_timeshift, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
896 sizer_row->Add( sizer, 0, wxEXPAND | wxALL, 5 );
898 panel->SetSizerAndFit( sizer_row );
902 void OpenDialog::UpdateMRL()
904 UpdateMRL( i_current_access_method );
907 void OpenDialog::UpdateMRL( int i_access_method )
909 wxString mrltemp, caching_name;
911 i_current_access_method = i_access_method;
913 switch( i_access_method )
916 mrltemp = file_combo->GetValue();
917 caching_name = wxT("file-caching");
921 i_disc_type_selection = disc_type->GetSelection();
923 switch ( i_disc_type_selection )
925 case 0: /* DVD with menus */
926 case 1: /* DVD without menus */
927 disc_device->SetToolTip( wxU(_("DVD device to use" ) ) );
928 if( i_disc_type_selection == 0 )
930 mrltemp = wxT("dvd://") + disc_device->GetValue();
931 caching_name = wxT("dvdnav-caching");
935 mrltemp = wxT("dvdsimple://") + disc_device->GetValue();
936 caching_name = wxT("dvdread-caching");
939 if( i_disc_title > 0 )
941 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
943 if( i_disc_chapter > 0 )
944 mrltemp += wxString::Format( wxT(":%d"), i_disc_chapter );
947 if( i_disc_sub >= 0 )
948 mrltemp += wxString::Format( wxT(" :sub-track=%d"),
950 if( i_disc_audio >= 0 )
951 mrltemp += wxString::Format( wxT(" :audio-track=%d"),
955 case 2: /* VCD of some sort */
957 disc_device->SetToolTip( wxU(_("Name of CD-ROM device "
958 "to read Video CD from. If this field is left empty, we will scan "
959 "for a CD-ROM with a VCD in it.")) );
960 mrltemp = wxT("vcdx://") + disc_device->GetValue();
961 if( i_disc_title > 0 )
962 mrltemp += wxString::Format( wxT("@%c%d"),
963 config_GetInt( p_intf, "vcdx-PBC" )
964 ? 'P' : 'E', i_disc_title );
966 disc_device->SetToolTip( wxU(_("CD-ROM device to use" ) ) );
967 mrltemp = wxT("vcd://") + disc_device->GetValue();
968 if( i_disc_title > 0 )
969 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
972 if( i_disc_sub >= 0 )
973 mrltemp += wxString::Format( wxT(" :sub-track=%d"),
976 if( i_disc_audio >= 0 )
977 mrltemp += wxString::Format( wxT(" :audio-track=%d"),
979 caching_name = wxT("vcd-caching");
984 disc_device->SetToolTip( wxU(_("Name of CD-ROM device "
985 "to read audio CD from. If this field is left empty, we will scan "
986 "for a CD-ROM with an audio CD in it." )) );
987 mrltemp = wxT("cddax://")
989 disc_device->SetToolTip( wxU(_("CD-ROM device to use" ) ) ) ;
990 mrltemp = wxT("cdda://")
992 + disc_device->GetValue();
993 if( i_disc_title > 0 )
994 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
996 caching_name = wxT("cdda-caching");
1000 msg_Err( p_intf, "invalid selection (%d)",
1001 disc_type->GetSelection() );
1007 switch( i_net_type )
1010 mrltemp = wxT("udp://@");
1011 if ( net_ipv6->GetValue() )
1013 mrltemp += wxT("[::]");
1015 if( i_net_ports[0] !=
1016 config_GetInt( p_intf, "server-port" ) )
1018 mrltemp += wxString::Format( wxT(":%d"), i_net_ports[0] );
1021 caching_name = wxT("udp-caching");
1025 mrltemp = wxT("udp://@");
1026 if ((net_addrs[1]->GetLineText(0).Find (':') != -1)
1027 && (net_addrs[1]->GetLineText(0)[0u] != '['))
1029 /* automatically adds '[' and ']' to IPv6 addresses */
1030 mrltemp += wxT("[") + net_addrs[1]->GetLineText(0)
1035 mrltemp += net_addrs[1]->GetLineText(0);
1037 if( i_net_ports[1] != config_GetInt( p_intf, "server-port" ) )
1039 mrltemp += wxString::Format( wxT(":%d"), i_net_ports[1] );
1042 caching_name = wxT("udp-caching");
1047 if( net_addrs[2]->GetLineText(0).Find(wxT("://")) == -1 )
1048 mrltemp = wxT("http://");
1050 mrltemp += net_addrs[2]->GetLineText(0);
1051 if( ! mrltemp.Left(4).CmpNoCase(wxT("http")) )
1052 caching_name = wxT("http-caching");
1053 else if( ! mrltemp.Left(3).CmpNoCase(wxT("mms")) )
1054 caching_name = wxT("mms-caching");
1056 caching_name= wxT("ftp-caching");
1061 if( net_addrs[3]->GetLineText(0).Find(wxT("rtsp://")) != 0 )
1063 mrltemp = wxT("rtsp://");
1065 mrltemp += net_addrs[3]->GetLineText(0);
1067 caching_name = wxT("rtsp-caching");
1070 if( net_timeshift->IsEnabled() && net_timeshift->IsChecked() )
1071 mrltemp += wxT(" :access-filter=timeshift");
1076 int i_item = i_access_method - MAX_ACCESS;
1078 if( i_item < 0 || i_item >= (int)input_tab_array.GetCount() )
1081 AutoBuiltPanel *input_panel = input_tab_array.Item( i_item );
1083 mrltemp = input_panel->name + wxT("://");
1085 for( int i=0; i < (int)input_panel->config_array.GetCount(); i++ )
1087 ConfigControl *control = input_panel->config_array.Item(i);
1089 mrltemp += wxT(" :");
1091 if( control->GetType() == CONFIG_ITEM_BOOL &&
1092 !control->GetIntValue() ) mrltemp += wxT("no-");
1094 mrltemp += control->GetName();
1096 switch( control->GetType() )
1098 case CONFIG_ITEM_STRING:
1099 case CONFIG_ITEM_FILE:
1100 case CONFIG_ITEM_DIRECTORY:
1101 case CONFIG_ITEM_MODULE:
1102 mrltemp += wxT("=\"") + control->GetPszValue() + wxT("\"");
1104 case CONFIG_ITEM_INTEGER:
1106 wxString::Format( wxT("=%i"), control->GetIntValue() );
1108 case CONFIG_ITEM_FLOAT:
1110 wxString::Format(wxT("=%f"), control->GetFloatValue());
1115 if( input_panel->p_advanced_mrl_combo &&
1116 input_panel->p_advanced_mrl_combo->GetValue() )
1118 mrltemp += wxT(" ") +
1119 input_panel->p_advanced_mrl_combo->GetValue();
1125 if( caching_name.size() )
1127 if( caching_value->IsEnabled() )
1129 mrltemp += wxT(" :") + caching_name +
1130 wxString::Format( wxT("=%d"), i_caching );
1134 int i_value = config_GetInt( p_intf, caching_name.mb_str() );
1135 caching_value->SetValue( i_value );
1139 mrl_combo->SetValue( mrltemp );
1142 /*****************************************************************************
1144 *****************************************************************************/
1145 void OpenDialog::OnOk( wxCommandEvent& WXUNUSED(event) )
1147 mrl = SeparateEntries( mrl_combo->GetValue() );
1148 mrl_combo->Append( mrl_combo->GetValue() );
1149 if( mrl_combo->GetCount() > 10 ) mrl_combo->Delete( 0 );
1150 mrl_combo->SetSelection( mrl_combo->GetCount() - 1 );
1152 if( i_method == OPEN_STREAM )
1154 if( IsModal() ) EndModal( wxID_OK );
1159 /* Update the playlist */
1160 playlist_t *p_playlist =
1161 (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
1163 if( p_playlist == NULL ) return;
1165 for( int i = 0; i < (int)mrl.GetCount(); i++ )
1167 vlc_bool_t b_start = !i && i_open_arg;
1168 input_item_t *p_input;
1171 psz_utf8 = wxFromLocale( mrl[i] );
1172 p_input = input_ItemNew( p_intf, psz_utf8, psz_utf8 );
1173 wxLocaleFree( psz_utf8 );
1175 /* Insert options */
1176 while( i + 1 < (int)mrl.GetCount() &&
1177 ((const char *)mrl[i + 1].mb_str())[0] == ':' )
1179 psz_utf8 = wxFromLocale( mrl[i + 1] );
1180 vlc_input_item_AddOption( p_input, psz_utf8 );
1181 wxLocaleFree( psz_utf8 );
1185 /* Get the options from the subtitles dialog */
1186 if( subsfile_checkbox->IsChecked() && subsfile_mrl.GetCount() )
1188 for( int j = 0; j < (int)subsfile_mrl.GetCount(); j++ )
1190 psz_utf8 = wxFromLocale( subsfile_mrl[j] );
1191 vlc_input_item_AddOption( p_input, psz_utf8 );
1192 wxLocaleFree( psz_utf8 );
1196 /* Get the options from the stream output dialog */
1197 if( sout_checkbox->IsChecked() && sout_mrl.GetCount() )
1199 for( int j = 0; j < (int)sout_mrl.GetCount(); j++ )
1201 psz_utf8 = wxFromLocale( sout_mrl[j] );
1202 vlc_input_item_AddOption( p_input, psz_utf8 );
1203 wxLocaleFree( psz_utf8 );
1209 playlist_PlaylistAddInput( p_playlist, p_input,
1210 PLAYLIST_APPEND | PLAYLIST_GO,
1215 playlist_PlaylistAddInput( p_playlist, p_input,
1216 PLAYLIST_APPEND|PLAYLIST_PREPARSE,
1221 vlc_object_release( p_playlist );
1225 if( IsModal() ) EndModal( wxID_OK );
1228 void OpenDialog::OnCancel( wxCommandEvent& WXUNUSED(event) )
1230 wxCloseEvent cevent;
1234 void OpenDialog::OnClose( wxCloseEvent& WXUNUSED(event) )
1238 if( IsModal() ) EndModal( wxID_CANCEL );
1241 void OpenDialog::OnPageChange( wxNotebookEvent& event )
1243 UpdateMRL( event.GetSelection() );
1246 void OpenDialog::OnMRLChange( wxCommandEvent& event )
1248 //mrl = SeparateEntries( event.GetString() );
1251 /*****************************************************************************
1252 * File panel event methods.
1253 *****************************************************************************/
1254 void OpenDialog::OnFilePanelChange( wxCommandEvent& WXUNUSED(event) )
1256 UpdateMRL( FILE_ACCESS );
1259 void OpenDialog::OnFileBrowse( wxCommandEvent& WXUNUSED(event) )
1261 if( file_dialog == NULL )
1262 file_dialog = new wxFileDialog( this, wxU(_("Open File")),
1263 wxT(""), wxT(""), wxT("*"), wxOPEN | wxMULTIPLE );
1265 p_file_dialog->SetWildcard(wxU(_("All Files (*.*)|*"
1266 "|Sound Files (*.mp3, *.ogg, etc.)|" EXTENSIONS_AUDIO
1267 "|Video Files (*.avi, *.mpg, etc.)|" EXTENSIONS_VIDEO
1268 "|Playlist Files (*.m3u, *.pls, etc.)|" EXTENSIONS_PLAYLIST
1269 "|Subtitle Files (*.srt, *.sub, etc.)|" EXTENSIONS_SUBTITLE)));
1271 if( file_dialog && file_dialog->ShowModal() == wxID_OK )
1273 wxArrayString paths;
1276 file_dialog->GetPaths( paths );
1278 for( size_t i = 0; i < paths.GetCount(); i++ )
1280 if( paths[i].Find( wxT(' ') ) >= 0 )
1281 path += wxT("\"") + paths[i] + wxT("\" ");
1283 path += paths[i] + wxT(" ");
1286 file_combo->SetValue( path );
1287 file_combo->Append( path );
1288 if( file_combo->GetCount() > 10 ) file_combo->Delete( 0 );
1289 UpdateMRL( FILE_ACCESS );
1293 void OpenDialog::OnSubFileBrowse( wxCommandEvent& WXUNUSED(event) )
1295 wxFileDialog dialog( this, wxU(_("Open subtitles file")),
1296 wxT(""), wxT(""), wxT("*"), wxOPEN );
1298 if( dialog.ShowModal() == wxID_OK )
1300 subfile_combo->SetValue( dialog.GetPath() );
1302 wxCommandEvent event; OnSubFileChange( event );
1305 void OpenDialog::OnSubFileChange( wxCommandEvent& WXUNUSED(event) )
1307 if( subsfile_mrl.GetCount() != 0 )
1309 subsfile_mrl.RemoveAt( 0 );
1310 subsfile_mrl.Insert( wxString(wxT("sub-file=")) + subfile_combo->GetValue() , 0 );
1314 subsfile_mrl.Add( wxString(wxT("sub-file=")) + subfile_combo->GetValue() );
1318 /*****************************************************************************
1319 * Disc panel event methods.
1320 *****************************************************************************/
1321 void OpenDialog::OnDiscPanelChangeSpin( wxSpinEvent& event )
1323 wxCommandEvent cevent;
1324 cevent.SetId(event.GetId());
1325 cevent.SetInt(event.GetPosition());
1326 OnDiscPanelChange(cevent);
1329 void OpenDialog::OnDiscPanelChange( wxCommandEvent& event )
1331 if( event.GetId() == DiscTitle_Event ) i_disc_title = event.GetInt();
1332 if( event.GetId() == DiscChapter_Event ) i_disc_chapter = event.GetInt();
1333 if( event.GetId() == DiscSub_Event ) i_disc_sub = event.GetInt();
1334 if( event.GetId() == DiscAudio_Event ) i_disc_audio = event.GetInt();
1336 UpdateMRL( DISC_ACCESS );
1339 void OpenDialog::OnDiscDeviceChange( wxCommandEvent& event )
1343 switch( disc_type->GetSelection() )
1346 psz_device = config_GetPsz( p_intf, "cd-audio" );
1350 psz_device = config_GetPsz( p_intf, "vcd" );
1354 psz_device = config_GetPsz( p_intf, "dvd" );
1358 if ( !psz_device ) psz_device = "";
1360 if( disc_device->GetValue().Cmp( wxL2U( psz_device ) ) )
1362 b_disc_device_changed = true;
1365 UpdateMRL( DISC_ACCESS );
1370 /* Return true if *psz_drive is a drive with a DVD in it. A more complete
1371 check would see if the media looks like a *playable* DVD. This should
1374 static bool IsDVD(const char *psz_drive)
1376 CdIo_t *p_cdio = cdio_open (psz_drive, DRIVER_UNKNOWN);
1379 discmode_t discmode = cdio_get_discmode(p_cdio);
1380 cdio_destroy(p_cdio);
1381 return cdio_is_discmode_dvd(discmode);
1387 /* Return a device that has a DVD in it. The caller needs to free
1388 the returned string.
1390 static char * ProbeDVD(const wxChar *device)
1393 char **ppsz_cd_drives;
1394 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1395 char *psz_device = (char *) tmp_buf;
1397 if( IsDVD(psz_device) )
1399 return strdup(psz_device);
1402 ppsz_cd_drives = cdio_get_devices(DRIVER_DEVICE);
1403 if( ppsz_cd_drives )
1406 for( c = ppsz_cd_drives; *c != NULL; c++ )
1410 char *psz_drive = strdup(*c);
1411 cdio_free_device_list(ppsz_cd_drives);
1412 return strdup(psz_drive);
1415 cdio_free_device_list(ppsz_cd_drives);
1421 static char * ProbeDevice(char **ppsz_search_devices, cdio_fs_anal_t mask,
1424 char **ppsz_devices;
1426 if( ppsz_search_devices && !ppsz_search_devices[0] )
1427 ppsz_search_devices = NULL;
1429 /* Start out trying the device that has been entered so far. */
1430 ppsz_devices = cdio_get_devices_with_cap(ppsz_search_devices, mask,
1433 if (ppsz_devices && *ppsz_devices)
1435 char *psz_device = strdup(*ppsz_devices);
1436 cdio_free_device_list(ppsz_devices);
1440 /* If there was no device specified on the first try, then give up
1441 now. Otherwise accept any CD-ROM in the class (e.g. VCD or DVD).
1443 if( !ppsz_search_devices ) return NULL;
1445 ppsz_devices = cdio_get_devices_with_cap(NULL, mask, true);
1447 if (ppsz_devices && *ppsz_devices)
1449 char *psz_device = strdup(*ppsz_devices);
1450 cdio_free_device_list(ppsz_devices);
1458 /* Return a device that has a CD-DA in it. The caller needs to free
1459 the returned string.
1461 static char * ProbeCDDA(const wxChar *device)
1464 char *ppsz_device[2];
1465 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1466 char *psz_device = (char *) tmp_buf;
1467 ppsz_device[0] = (device && *device) ? psz_device : NULL;
1468 ppsz_device[1] = NULL;
1469 return ProbeDevice(ppsz_device, CDIO_FS_AUDIO, false);
1473 /* Return a device that has a VCD in it. The caller needs to free
1474 the returned string.
1476 static char * ProbeVCD(const wxChar *device)
1478 char *ppsz_device[2];
1479 const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(device);
1480 char *psz_device = (char *) tmp_buf;
1481 ppsz_device[0] = (device && *device) ? psz_device : NULL;
1482 ppsz_device[1] = NULL;
1483 return ProbeDevice(ppsz_device,
1484 (CDIO_FS_ANAL_SVCD|CDIO_FS_ANAL_CVD|CDIO_FS_ANAL_VIDEOCD
1485 |CDIO_FS_UNKNOWN), true);
1491 Probe (find anywhere) a CD-DA, VCD, or a DVD.
1492 First try the device name that may have been entered for the "disc type"
1493 selected. If that doesn't work we try any device for the disc type.
1494 If that doesn't work, try looking for CD-ROMs or DVD drives. the
1495 disc type, device name and paramter ranges are set to whatever we find.
1497 void OpenDialog::OnDiscProbe( wxCommandEvent& WXUNUSED(event) )
1499 wxCommandEvent dummy_event;
1500 char *psz_device = NULL;
1501 bool b_probed_DVD = false;
1502 bool b_probed_VCD = false;
1503 const int i_selection = disc_type->GetSelection();
1505 /* Reduce verbosity of cdio errors. */
1506 cdio_loglevel_default = CDIO_LOG_ERROR;
1509 switch( disc_type->GetSelection() )
1512 case SELECTION_DISC_TYPE_DVD_MENUS:
1513 case SELECTION_DISC_TYPE_DVD:
1514 /* If not a DVD then try for a VCD. If VCD fails it will
1516 if (!psz_device) psz_device = ProbeDVD(disc_device->GetValue());
1519 b_probed_DVD = true;
1520 disc_type->SetSelection(SELECTION_DISC_TYPE_VCD);
1521 OnDiscTypeChange( dummy_event );
1524 disc_device->SetValue( wxL2U(psz_device) );
1527 case SELECTION_DISC_TYPE_VCD: /* VCD probe of some sort */
1528 if(!psz_device) psz_device = ProbeVCD(disc_device->GetValue());
1532 #if LIBVCD_VERSION_NUM > 23
1533 vcdinfo_obj_t *p_vcdinfo;
1535 /* Set LID or entry range accurately if possible. */
1536 if( vcdinfo_open(&p_vcdinfo, &psz_device, DRIVER_DEVICE,
1537 NULL) == VCDINFO_OPEN_VCD)
1539 if (config_GetInt( p_intf, "vcdx-PBC" ))
1541 /* Set largest LID. */;
1542 disc_title->SetRange( 0, vcdinfo_get_num_LIDs(p_vcdinfo) );
1547 /* Set largest Entry */
1548 disc_title->SetRange( 0,
1549 vcdinfo_get_num_entries(p_vcdinfo)-1 );
1551 vcdinfo_close(p_vcdinfo);
1553 #endif /* LIBVCD_VERSION_NUM > 23 */
1554 disc_device->SetValue( wxL2U(psz_device) );
1556 CdIo_t *p_cdio = cdio_open (psz_device, DRIVER_UNKNOWN);
1557 disc_device->SetValue( wxL2U(psz_device) );
1559 /* Set track range accurately if possible. */
1562 track_t i_last_track = cdio_get_last_track_num(p_cdio);
1563 disc_title->SetRange( 0, i_last_track-1 );
1565 cdio_destroy(p_cdio);
1570 b_probed_VCD = true;
1572 /* Not a VCD. Try for a DVD unless we've been there before. */
1573 if( !b_probed_DVD && (psz_device = ProbeDVD(disc_device->GetValue())) )
1575 disc_type->SetSelection(SELECTION_DISC_TYPE_DVD_MENUS);
1576 OnDiscTypeChange( dummy_event );
1579 b_probed_DVD = true;
1581 /* Couldn't find a VCD or DVD. See if we can find a CD-DA. */
1582 psz_device = ProbeCDDA(disc_device->GetValue());
1585 disc_type->SetSelection(SELECTION_DISC_TYPE_CDDA);
1586 OnDiscTypeChange( dummy_event );
1590 /* Couldn't find a VCD, DVD or CD-DA. Null out the Device name and
1591 set to original selection.
1593 disc_device->SetValue( wxL2U("") );
1594 disc_type->SetSelection(i_selection);
1595 OnDiscTypeChange( dummy_event );
1598 case SELECTION_DISC_TYPE_CDDA:
1599 if(!psz_device) psz_device = ProbeCDDA(disc_device->GetValue());
1602 CdIo_t *p_cdio = cdio_open (psz_device, DRIVER_UNKNOWN);
1603 disc_device->SetValue( wxL2U(psz_device) );
1606 track_t i_last_track = cdio_get_last_track_num(p_cdio);
1607 disc_title->SetRange( 0, i_last_track );
1609 MediaInsertCDDA( p_intf, p_cdio, i_last_track );
1612 cdio_destroy(p_cdio);
1616 /* Not a CD-DA. Try for a DVD unless we've been there before. */
1617 if( !b_probed_DVD && (psz_device = ProbeDVD(disc_device->GetValue())) )
1619 disc_type->SetSelection(SELECTION_DISC_TYPE_DVD_MENUS);
1620 OnDiscTypeChange( dummy_event );
1624 /* Couldn't find a CD-DA or DVD. See if we can find a VCD, unless
1625 we've tried that before. */
1626 if (!b_probed_VCD) psz_device = ProbeVCD(disc_device->GetValue());
1629 disc_type->SetSelection(SELECTION_DISC_TYPE_VCD);
1630 OnDiscTypeChange( dummy_event );
1633 disc_device->SetValue( wxL2U("") );
1637 msg_Err( p_intf, "invalid Disc type selection (%d)",
1638 disc_type->GetSelection() );
1643 disc_probe->SetValue(FALSE);
1645 UpdateMRL( DISC_ACCESS );
1647 #endif /* HAVE_LIBCDIO */
1649 void OpenDialog::OnDiscTypeChange( wxCommandEvent& WXUNUSED(event) )
1651 char *psz_device = NULL;
1653 switch( disc_type->GetSelection() )
1656 case SELECTION_DISC_TYPE_DVD_MENUS:
1657 case SELECTION_DISC_TYPE_DVD:
1658 disc_sub->Enable(); disc_sub_label->Enable();
1659 disc_audio->Enable(); disc_audio_label->Enable();
1660 disc_chapter->Enable(); disc_chapter_label->Enable();
1661 disc_title_label->SetLabel ( wxU(_("Title")) );
1662 psz_device = config_GetPsz( p_intf, "dvd" );
1663 if( !b_disc_device_changed )
1665 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1666 else disc_device->SetValue( wxT("") );
1668 disc_title->SetRange( 0, 255 );
1669 disc_sub->SetRange( -1, 31 ); // up to 32 subtitles -1: no subtitle
1670 disc_audio->SetRange( 0, 7 ); // up to 8 audio channels
1671 disc_chapter->SetRange( 0, 255 );
1672 disc_title->SetToolTip( wxU(_("Title number.")) );
1673 // \bug [string] needs to be DVDs instead of DVD's
1674 disc_sub->SetToolTip( wxU(_(
1675 "DVD's can have up to 32 subtitles numbered 0..31. "
1676 "Note this is not the same thing as a subtitle name (e.g. 'en'). "
1677 "If a value -1 is used, no subtitle will be shown." )) );
1678 // \bug [string] needs to be DVDs instead of DVD's
1679 disc_audio->SetToolTip( wxU(_("Audio track number. "
1680 "DVD's can have up to 8 audio tracks numbered 0..7."
1684 case SELECTION_DISC_TYPE_VCD:
1685 disc_sub->Enable(); disc_sub_label->Enable();
1686 disc_audio->Enable(); disc_audio_label->Enable();
1687 disc_chapter->Disable(); disc_chapter_label->Disable();
1688 psz_device = config_GetPsz( p_intf, "vcd" );
1689 if( !b_disc_device_changed )
1691 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1692 else disc_device->SetValue( wxT("") );
1696 if (config_GetInt( p_intf, "vcdx-PBC" ))
1698 disc_title_label->SetLabel ( wxT("Playback LID") );
1699 disc_title->SetToolTip( wxU(_(
1700 "Playback control (PBC) usually starts with number 1." )) );
1704 disc_title_label->SetLabel ( wxT("Entry") );
1705 disc_title->SetToolTip( wxU(_(
1706 "The first entry (the beginning of the first MPEG track) is 0." )) );
1710 disc_title_label->SetLabel ( wxU(_("Track")) );
1711 disc_title->SetToolTip( wxU(_("Track number.")) );
1713 disc_title->SetRange( 0, 99 ); // only 100 tracks allowed on VCDs
1714 disc_sub->SetRange( -1, 3 ); // up to 4 subtitles -1 = no subtitle
1715 disc_audio->SetRange( 0, 1 ); // up to 2 audio tracks
1716 // \bug [string] needs to be SVCDs instead of SVCD's
1717 disc_sub->SetToolTip( wxU(_(
1718 "SVCD's can have up to 4 subtitles numbered 0..3. "
1719 "If a value -1 is used, no subtitle will be shown." )) );
1720 // \bug [string] needs to be SVCDs instead of SVCD's
1721 disc_audio->SetToolTip( wxU(_("Audio track number. "
1722 "VCD's can have up to 2 audio tracks numbered 0 or 1. "
1726 case SELECTION_DISC_TYPE_CDDA:
1727 disc_sub->Disable(); disc_sub_label->Disable();
1728 disc_chapter->Disable(); disc_chapter_label->Disable();
1729 disc_audio->Disable(); disc_audio_label->Disable();
1730 disc_title_label->SetLabel ( wxU(_("Track")) );
1732 disc_title->SetToolTip( wxU(_(
1733 "Audio CDs can have up to 100 tracks, the first track is usually 1. "
1734 "If 0 is given, then all tracks are played.")) );
1736 disc_title->SetToolTip( wxU(_(
1737 "Audio CDs can have up to 100 tracks, the first track is usually 1."
1740 psz_device = config_GetPsz( p_intf, "cd-audio" );
1741 if( !b_disc_device_changed )
1743 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1744 else disc_device->SetValue( wxT("") );
1747 /* There are at most 100 tracks in a CD-DA */
1748 disc_title->SetRange( 0, 100 );
1752 msg_Err( p_intf, "invalid Disc type selection (%d)",
1753 disc_type->GetSelection() );
1757 disc_title->SetValue( 0 ); i_disc_title = 0;
1758 disc_chapter->SetValue( 0 ); i_disc_chapter = 0;
1760 if( psz_device ) free( psz_device );
1762 UpdateMRL( DISC_ACCESS );
1765 /*****************************************************************************
1766 * Net panel event methods.
1767 *****************************************************************************/
1768 void OpenDialog::OnNetPanelChangeSpin( wxSpinEvent& event )
1770 wxCommandEvent cevent;
1771 cevent.SetId(event.GetId());
1772 cevent.SetInt(event.GetPosition());
1773 OnNetPanelChange(cevent);
1776 void OpenDialog::OnNetPanelChange( wxCommandEvent& event )
1778 if( event.GetId() >= NetPort1_Event && event.GetId() <= NetPort3_Event )
1780 i_net_ports[event.GetId() - NetPort1_Event] = event.GetInt();
1783 UpdateMRL( NET_ACCESS );
1786 void OpenDialog::OnNetTypeChange( wxCommandEvent& event )
1790 i_net_type = event.GetId() - NetRadio1_Event;
1794 net_radios[i]->SetValue( event.GetId() == (NetRadio1_Event+i) );
1795 net_subpanels[i]->Enable( event.GetId() == (NetRadio1_Event+i) );
1797 /* UDP Unicast or multicast -> timeshift */
1798 if( i_net_type == 0 || i_net_type == 1 )
1799 net_timeshift->Enable();
1801 net_timeshift->Disable();
1803 UpdateMRL( NET_ACCESS );
1806 /*****************************************************************************
1807 * Subtitles file event methods.
1808 *****************************************************************************/
1809 void OpenDialog::OnSubsFileEnable( wxCommandEvent& event )
1811 subsfile_button->Enable( event.GetInt() != 0 );
1812 subbrowse_button->Enable( event.GetInt() != 0 );
1813 subfile_combo->Enable( event.GetInt() != 0 );
1816 void OpenDialog::OnSubsFileSettings( wxCommandEvent& WXUNUSED(event) )
1818 /* Show/hide the open dialog */
1819 if( subsfile_dialog == NULL )
1820 subsfile_dialog = new SubsFileDialog( p_intf, this );
1822 if( subsfile_dialog && subsfile_dialog->ShowModal() == wxID_OK )
1824 subsfile_mrl.Empty();
1825 subsfile_mrl.Add( wxString(wxT("sub-file=")) + subfile_combo->GetValue() );
1826 if( subsfile_dialog->encoding_combo )
1828 subsfile_mrl.Add( wxString(wxT("subsdec-encoding=")) +
1829 subsfile_dialog->encoding_combo->GetValue() );
1831 if( subsfile_dialog->align_combo )
1833 subsfile_mrl.Add( wxString::Format(wxT("subsdec-align=%i"),
1834 (int)subsfile_dialog->align_combo->GetClientData(
1835 subsfile_dialog->align_combo->GetSelection()) ) );
1837 if( subsfile_dialog->size_combo )
1839 subsfile_mrl.Add( wxString::Format( wxT("freetype-rel-fontsize=%i"),
1840 (int)subsfile_dialog->size_combo->GetClientData(
1841 subsfile_dialog->size_combo->GetSelection()) ) );
1843 subsfile_mrl.Add( wxString::Format( wxT("sub-fps=%i"),
1844 subsfile_dialog->fps_spinctrl->GetValue() ) );
1845 subsfile_mrl.Add( wxString::Format( wxT("sub-delay=%i"),
1846 subsfile_dialog->delay_spinctrl->GetValue() ) );
1850 /*****************************************************************************
1851 * Stream output event methods.
1852 *****************************************************************************/
1853 void OpenDialog::OnSoutEnable( wxCommandEvent& event )
1855 sout_button->Enable( event.GetInt() != 0 );
1858 void OpenDialog::OnSoutSettings( wxCommandEvent& WXUNUSED(event) )
1860 /* Show/hide the open dialog */
1861 if( sout_dialog == NULL )
1862 sout_dialog = new SoutDialog( p_intf, this );
1864 if( sout_dialog && sout_dialog->ShowModal() == wxID_OK )
1866 sout_mrl = sout_dialog->GetOptions();
1870 /*****************************************************************************
1871 * Caching event methods.
1872 *****************************************************************************/
1873 void OpenDialog::OnCachingEnable( wxCommandEvent& event )
1875 caching_value->Enable( event.GetInt() != 0 );
1876 i_caching = caching_value->GetValue();
1880 void OpenDialog::OnCachingChangeSpin( wxSpinEvent& event )
1882 wxCommandEvent cevent;
1883 OnCachingChange(cevent);
1886 void OpenDialog::OnCachingChange( wxCommandEvent& event )
1888 i_caching = event.GetInt();
1892 /*****************************************************************************
1893 * Utility functions.
1894 *****************************************************************************/
1895 wxArrayString SeparateEntries( wxString entries )
1897 vlc_bool_t b_quotes_mode = VLC_FALSE;
1899 wxArrayString entries_array;
1902 wxStringTokenizer token( entries, wxT(" \t\r\n\""), wxTOKEN_RET_DELIMS );
1904 while( token.HasMoreTokens() )
1906 entry += token.GetNextToken();
1908 if( entry.IsEmpty() ) continue;
1910 if( !b_quotes_mode && entry.Last() == wxT('\"') )
1912 /* Enters quotes mode */
1914 b_quotes_mode = VLC_TRUE;
1916 else if( b_quotes_mode && entry.Last() == wxT('\"') )
1918 /* Finished the quotes mode */
1920 b_quotes_mode = VLC_FALSE;
1922 else if( !b_quotes_mode && entry.Last() != wxT('\"') )
1924 /* we found a non-quoted standalone string */
1925 if( token.HasMoreTokens() ||
1926 entry.Last() == wxT(' ') || entry.Last() == wxT('\t') ||
1927 entry.Last() == wxT('\r') || entry.Last() == wxT('\n') )
1929 if( !entry.IsEmpty() ) entries_array.Add( entry );
1936 if( !entry.IsEmpty() ) entries_array.Add( entry );
1938 return entries_array;