1 /*****************************************************************************
2 * open.cpp : wxWindows plugin for vlc
3 *****************************************************************************
4 * Copyright (C) 2000-2004 VideoLAN
7 * Authors: Gildas Bazin <gbazin@videolan.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
27 #include <stdlib.h> /* malloc(), free() */
28 #include <errno.h> /* ENOMEM */
29 #include <string.h> /* strerror() */
34 #include <wx/combobox.h>
35 #include <wx/statline.h>
36 #include <wx/tokenzr.h>
40 #include "wxwindows.h"
41 #include "preferences_widgets.h"
44 # define wxRB_SINGLE 0
47 /*****************************************************************************
49 *****************************************************************************/
51 /* IDs for the controls and the menu commands */
54 Notebook_Event = wxID_HIGHEST,
67 NetRadio1_Event, NetRadio2_Event, NetRadio3_Event, NetRadio4_Event,
68 NetPort1_Event, NetPort2_Event, NetPort3_Event,
69 NetAddr1_Event, NetAddr2_Event, NetAddr3_Event, NetAddr4_Event,
73 SubsFileSettings_Event,
81 BEGIN_EVENT_TABLE(OpenDialog, wxDialog)
83 EVT_BUTTON(wxID_OK, OpenDialog::OnOk)
84 EVT_BUTTON(wxID_CANCEL, OpenDialog::OnCancel)
86 EVT_NOTEBOOK_PAGE_CHANGED(Notebook_Event, OpenDialog::OnPageChange)
88 EVT_TEXT(MRL_Event, OpenDialog::OnMRLChange)
90 /* Events generated by the file panel */
91 EVT_TEXT(FileName_Event, OpenDialog::OnFilePanelChange)
92 EVT_BUTTON(FileBrowse_Event, OpenDialog::OnFileBrowse)
94 /* Events generated by the disc panel */
95 EVT_RADIOBOX(DiscType_Event, OpenDialog::OnDiscTypeChange)
96 EVT_TEXT(DiscDevice_Event, OpenDialog::OnDiscDeviceChange)
97 EVT_TEXT(DiscDevice_Event, OpenDialog::OnDiscPanelChange)
98 EVT_TEXT(DiscTitle_Event, OpenDialog::OnDiscPanelChange)
99 EVT_SPINCTRL(DiscTitle_Event, OpenDialog::OnDiscPanelChange)
100 EVT_TEXT(DiscChapter_Event, OpenDialog::OnDiscPanelChange)
101 EVT_SPINCTRL(DiscChapter_Event, OpenDialog::OnDiscPanelChange)
102 EVT_TEXT(DiscSub_Event, OpenDialog::OnDiscPanelChange)
103 EVT_SPINCTRL(DiscSub_Event, OpenDialog::OnDiscPanelChange)
105 /* Events generated by the net panel */
106 EVT_RADIOBUTTON(NetRadio1_Event, OpenDialog::OnNetTypeChange)
107 EVT_RADIOBUTTON(NetRadio2_Event, OpenDialog::OnNetTypeChange)
108 EVT_RADIOBUTTON(NetRadio3_Event, OpenDialog::OnNetTypeChange)
109 EVT_RADIOBUTTON(NetRadio4_Event, OpenDialog::OnNetTypeChange)
110 EVT_TEXT(NetPort1_Event, OpenDialog::OnNetPanelChange)
111 EVT_SPINCTRL(NetPort1_Event, OpenDialog::OnNetPanelChange)
112 EVT_TEXT(NetPort2_Event, OpenDialog::OnNetPanelChange)
113 EVT_SPINCTRL(NetPort2_Event, OpenDialog::OnNetPanelChange)
114 EVT_TEXT(NetPort3_Event, OpenDialog::OnNetPanelChange)
115 EVT_SPINCTRL(NetPort3_Event, OpenDialog::OnNetPanelChange)
116 EVT_TEXT(NetAddr2_Event, OpenDialog::OnNetPanelChange)
117 EVT_TEXT(NetAddr3_Event, OpenDialog::OnNetPanelChange)
118 EVT_TEXT(NetAddr4_Event, OpenDialog::OnNetPanelChange)
119 EVT_CHECKBOX(NetForceIPv6_Event, OpenDialog::OnNetPanelChange)
121 /* Events generated by the subtitle file buttons */
122 EVT_CHECKBOX(SubsFileEnable_Event, OpenDialog::OnSubsFileEnable)
123 EVT_BUTTON(SubsFileSettings_Event, OpenDialog::OnSubsFileSettings)
125 /* Events generated by the stream output buttons */
126 EVT_CHECKBOX(SoutEnable_Event, OpenDialog::OnSoutEnable)
127 EVT_BUTTON(SoutSettings_Event, OpenDialog::OnSoutSettings)
129 /* Hide the window when the user closes the window */
130 EVT_CLOSE(OpenDialog::OnCancel)
134 /*****************************************************************************
136 *****************************************************************************/
137 WX_DEFINE_ARRAY(ConfigControl *, ArrayOfConfigControls);
139 class AutoBuiltPanel : public wxPanel
144 AutoBuiltPanel( wxWindow *, OpenDialog *, intf_thread_t *,
147 virtual ~AutoBuiltPanel() {}
149 void UpdateAdvancedMRL();
152 ArrayOfConfigControls config_array;
153 ArrayOfConfigControls advanced_config_array;
154 wxComboBox *p_advanced_mrl_combo;
157 intf_thread_t *p_intf;
158 OpenDialog *p_open_dialog;
160 void OnAdvanced( wxCommandEvent& event );
161 wxDialog *p_advanced_dialog;
163 DECLARE_EVENT_TABLE();
166 BEGIN_EVENT_TABLE(AutoBuiltPanel, wxPanel)
167 EVT_BUTTON(AdvancedOptions_Event, AutoBuiltPanel::OnAdvanced)
170 static void AutoBuildCallback( void *p_data )
172 ((OpenDialog *)p_data)->UpdateMRL();
175 static void AutoBuildAdvancedCallback( void *p_data )
177 ((AutoBuiltPanel *)p_data)->UpdateAdvancedMRL();
180 AutoBuiltPanel::AutoBuiltPanel( wxWindow *parent, OpenDialog *dialog,
181 intf_thread_t *_p_intf,
182 const module_t *p_module )
183 : wxPanel( parent, -1, wxDefaultPosition, wxDefaultSize ),
184 name( wxU(p_module->psz_object_name) ),
185 p_advanced_mrl_combo( NULL ),
186 p_intf( _p_intf ), p_open_dialog( dialog ), p_advanced_dialog( NULL )
188 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
189 module_config_t *p_item = p_module->p_config;
190 bool b_advanced = false;
194 if( !(p_item->i_type & CONFIG_HINT) && p_item->b_advanced )
197 if( p_item->i_type & CONFIG_HINT || p_item->b_advanced )
200 ConfigControl *control =
201 CreateConfigControl( VLC_OBJECT(p_intf), p_item, this );
203 config_array.Add( control );
205 /* Don't add items that were not recognized */
206 if( control == NULL ) continue;
208 control->SetUpdateCallback( AutoBuildCallback, (void *)dialog );
210 sizer->Add( control, 0, wxEXPAND | wxALL, 2 );
212 while( p_item->i_type != CONFIG_HINT_END && p_item++ );
216 wxPanel *dummy_panel = new wxPanel( this, -1 );
217 sizer->Add( dummy_panel, 1 );
220 new wxButton( this, AdvancedOptions_Event,
221 wxU(_("Advanced options...")) );
222 sizer->Add( button, 0, wxALL, 5 );
224 /* Build the advanced dialog */
226 new wxDialog( this, -1, ((wxString)wxU(_("Advanced options"))) +
227 wxT(" (") + wxU( p_module->psz_longname ) + wxT(")"),
228 wxDefaultPosition, wxDefaultSize,
229 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER );
231 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
233 /* Create MRL combobox */
234 wxBoxSizer *mrl_sizer_sizer = new wxBoxSizer( wxHORIZONTAL );
235 wxStaticBox *mrl_box =
236 new wxStaticBox( p_advanced_dialog, -1,
237 wxU(_("Advanced options")) );
238 wxStaticBoxSizer *mrl_sizer =
239 new wxStaticBoxSizer( mrl_box, wxHORIZONTAL );
240 wxStaticText *mrl_label =
241 new wxStaticText( p_advanced_dialog, -1, wxU(_("Options:")) );
242 p_advanced_mrl_combo =
243 new wxComboBox( p_advanced_dialog, MRL_Event, wxT(""),
244 wxDefaultPosition, wxDefaultSize );
245 mrl_sizer->Add( mrl_label, 0, wxALL | wxALIGN_CENTER, 5 );
246 mrl_sizer->Add( p_advanced_mrl_combo, 1, wxALL | wxALIGN_CENTER, 5 );
247 mrl_sizer_sizer->Add( mrl_sizer, 1, wxEXPAND | wxALL, 5 );
248 sizer->Add( mrl_sizer_sizer, 0, wxEXPAND | wxALL, 2 );
250 /* Add advanced options to panel */
251 module_config_t *p_item = p_module->p_config;
254 if( p_item->i_type & CONFIG_HINT || !p_item->b_advanced )
257 ConfigControl *control =
258 CreateConfigControl( VLC_OBJECT(p_intf), p_item,
261 advanced_config_array.Add( control );
263 /* Don't add items that were not recognized */
264 if( control == NULL ) continue;
266 control->SetUpdateCallback( AutoBuildAdvancedCallback,
269 sizer->Add( control, 0, wxEXPAND | wxALL, 2 );
271 while( p_item->i_type != CONFIG_HINT_END && p_item++ );
274 dummy_panel = new wxPanel( p_advanced_dialog, -1 );
275 sizer->Add( dummy_panel, 1 );
276 wxStaticLine *static_line =
277 new wxStaticLine( p_advanced_dialog, wxID_OK );
278 sizer->Add( static_line, 0, wxEXPAND | wxALL, 5 );
281 wxButton *ok_button =
282 new wxButton( p_advanced_dialog, wxID_OK, wxU(_("OK")) );
283 ok_button->SetDefault();
284 wxButton *cancel_button =
285 new wxButton( p_advanced_dialog, wxID_CANCEL, wxU(_("Cancel")) );
286 wxBoxSizer *button_sizer = new wxBoxSizer( wxHORIZONTAL );
287 button_sizer->Add( ok_button, 0, wxALL, 5 );
288 button_sizer->Add( cancel_button, 0, wxALL, 5 );
289 button_sizer->Layout();
290 sizer->Add( button_sizer, 0, wxALL, 0 );
292 sizer->SetMinSize( 400, -1 );
293 p_advanced_dialog->SetSizerAndFit( sizer );
296 this->SetSizerAndFit( sizer );
299 void AutoBuiltPanel::OnAdvanced( wxCommandEvent& event )
301 if( p_advanced_dialog->ShowModal() == wxID_OK )
304 p_open_dialog->UpdateMRL();
308 void AutoBuiltPanel::UpdateAdvancedMRL()
312 for( int i = 0; i < (int)advanced_config_array.GetCount(); i++ )
314 ConfigControl *control = advanced_config_array.Item(i);
316 mrltemp += (i ? wxT(" :") : wxT(":"));
318 if( control->GetType() == CONFIG_ITEM_BOOL &&
319 !control->GetIntValue() ) mrltemp += wxT("no-");
321 mrltemp += control->GetName();
323 switch( control->GetType() )
325 case CONFIG_ITEM_STRING:
326 case CONFIG_ITEM_FILE:
327 case CONFIG_ITEM_DIRECTORY:
328 case CONFIG_ITEM_MODULE:
329 mrltemp += wxT("=\"") + control->GetPszValue() + wxT("\"");
331 case CONFIG_ITEM_INTEGER:
333 wxString::Format( wxT("=%i"), control->GetIntValue() );
335 case CONFIG_ITEM_FLOAT:
337 wxString::Format(wxT("=%f"), control->GetFloatValue());
342 p_advanced_mrl_combo->SetValue( mrltemp );
345 /*****************************************************************************
347 *****************************************************************************/
348 OpenDialog::OpenDialog( intf_thread_t *_p_intf, wxWindow *_p_parent,
349 int i_access_method, int i_arg ):
350 wxDialog( _p_parent, -1, wxU(_("Open...")), wxDefaultPosition,
351 wxDefaultSize, wxDEFAULT_FRAME_STYLE )
353 OpenDialog( _p_intf, _p_parent, i_access_method, i_arg, OPEN_NORMAL );
356 OpenDialog::OpenDialog( intf_thread_t *_p_intf, wxWindow *_p_parent,
357 int i_access_method, int i_arg, int _i_method ):
358 wxDialog( _p_parent, -1, wxU(_("Open...")), wxDefaultPosition,
359 wxDefaultSize, wxDEFAULT_FRAME_STYLE )
361 /* Initializations */
362 i_method = _i_method;
364 p_parent = _p_parent;
365 SetIcon( *p_intf->p_sys->p_icon );
367 i_disc_type_selection = 0;
371 subsfile_dialog = NULL;
372 b_disc_device_changed = false;
374 /* Create a panel to put everything in */
375 wxPanel *panel = new wxPanel( this, -1 );
376 panel->SetAutoLayout( TRUE );
378 /* Create MRL combobox */
379 wxBoxSizer *mrl_sizer_sizer = new wxBoxSizer( wxHORIZONTAL );
380 wxStaticBox *mrl_box = new wxStaticBox( panel, -1,
381 wxU(_("Media Resource Locator (MRL)")) );
382 wxStaticBoxSizer *mrl_sizer = new wxStaticBoxSizer( mrl_box,
384 wxStaticText *mrl_label = new wxStaticText( panel, -1,
386 mrl_combo = new wxComboBox( panel, MRL_Event, wxT(""),
387 wxPoint(20,25), wxSize(120, -1),
389 mrl_combo->SetToolTip( wxU(_("You can use this field directly by typing "
390 "the full MRL you want to open.\n""Alternatively, the field will be "
391 "filled automatically when you use the controls below.")) );
393 mrl_sizer->Add( mrl_label, 0, wxALL | wxALIGN_CENTER, 5 );
394 mrl_sizer->Add( mrl_combo, 1, wxALL | wxALIGN_CENTER, 5 );
395 mrl_sizer_sizer->Add( mrl_sizer, 1, wxEXPAND | wxALL, 5 );
398 /* Create Static Text */
399 wxStaticText *label = new wxStaticText( panel, -1,
400 wxU(_("Alternatively, you can build an MRL using one of the "
401 "following predefined targets:")) );
403 wxFlexGridSizer *sout_sizer = NULL;
404 wxStaticLine *static_line = NULL;
406 if( i_method == OPEN_NORMAL )
408 /* Create Stream Output checkox */
409 sout_sizer = new wxFlexGridSizer( 2, 1, 20 );
412 sout_checkbox = new wxCheckBox( panel, SoutEnable_Event,
413 wxU(_("Stream output")) );
414 sout_checkbox->SetToolTip( wxU(_("Use VLC as a server of streams")) );
415 sout_sizer->Add( sout_checkbox, 0,
416 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
417 sout_button = new wxButton( panel, SoutSettings_Event,
418 wxU(_("Settings...")) );
419 sout_button->Disable();
421 char *psz_sout = config_GetPsz( p_intf, "sout" );
422 if( psz_sout && *psz_sout )
424 sout_checkbox->SetValue(TRUE);
425 sout_button->Enable();
426 subsfile_mrl.Add( wxString(wxT("sout=")) + wxL2U(psz_sout) );
428 if( psz_sout ) free( psz_sout );
430 sout_sizer->Add( sout_button, 1, wxALIGN_LEFT |
431 wxALIGN_CENTER_VERTICAL );
434 static_line = new wxStaticLine( panel, wxID_OK );
437 /* Create the buttons */
438 wxButton *ok_button = new wxButton( panel, wxID_OK, wxU(_("OK")) );
439 ok_button->SetDefault();
440 wxButton *cancel_button = new wxButton( panel, wxID_CANCEL,
443 /* Create notebook */
444 notebook = new wxNotebook( panel, Notebook_Event );
445 wxNotebookSizer *notebook_sizer = new wxNotebookSizer( notebook );
447 notebook->AddPage( FilePanel( notebook ), wxU(_("File")),
448 i_access_method == FILE_ACCESS );
449 notebook->AddPage( DiscPanel( notebook ), wxU(_("Disc")),
450 i_access_method == DISC_ACCESS );
451 notebook->AddPage( NetPanel( notebook ), wxU(_("Network")),
452 i_access_method == NET_ACCESS );
454 module_t *p_module = config_FindModule( VLC_OBJECT(p_intf), "v4l" );
457 AutoBuiltPanel *autopanel =
458 new AutoBuiltPanel( notebook, this, p_intf, p_module );
459 input_tab_array.Add( autopanel );
460 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ),
461 i_access_method == CAPTURE_ACCESS );
464 p_module = config_FindModule( VLC_OBJECT(p_intf), "pvr" );
467 AutoBuiltPanel *autopanel =
468 new AutoBuiltPanel( notebook, this, p_intf, p_module );
469 input_tab_array.Add( autopanel );
470 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ),
471 i_access_method == CAPTURE_ACCESS );
474 p_module = config_FindModule( VLC_OBJECT(p_intf), "dvb" );
477 AutoBuiltPanel *autopanel =
478 new AutoBuiltPanel( notebook, this, p_intf, p_module );
479 input_tab_array.Add( autopanel );
480 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ),
481 i_access_method == CAPTURE_ACCESS );
484 p_module = config_FindModule( VLC_OBJECT(p_intf), "dshow" );
487 AutoBuiltPanel *autopanel =
488 new AutoBuiltPanel( notebook, this, p_intf, p_module );
489 input_tab_array.Add( autopanel );
490 notebook->AddPage( autopanel, wxU( p_module->psz_shortname ),
491 i_access_method == CAPTURE_ACCESS );
494 /* Update Disc panel */
495 wxCommandEvent dummy_event;
496 OnDiscTypeChange( dummy_event );
498 /* Update Net panel */
499 dummy_event.SetId( NetRadio1_Event );
500 OnNetTypeChange( dummy_event );
503 wxNotebookEvent event( wxEVT_NULL, 0, i_access_method );
504 OnPageChange( event );
506 /* Place everything in sizers */
507 wxBoxSizer *button_sizer = new wxBoxSizer( wxHORIZONTAL );
508 button_sizer->Add( ok_button, 0, wxALL, 5 );
509 button_sizer->Add( cancel_button, 0, wxALL, 5 );
510 button_sizer->Layout();
511 wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL );
512 wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
513 panel_sizer->Add( mrl_sizer_sizer, 0, wxEXPAND, 5 );
514 panel_sizer->Add( label, 0, wxEXPAND | wxALL, 5 );
515 panel_sizer->Add( notebook_sizer, 1, wxEXPAND | wxALL, 5 );
516 if( i_method == OPEN_NORMAL)
518 panel_sizer->Add( sout_sizer, 0, wxALIGN_LEFT | wxALL, 5 );
519 panel_sizer->Add( static_line, 0, wxEXPAND | wxALL, 5 );
521 panel_sizer->Add( button_sizer, 0, wxALIGN_LEFT | wxALL, 5 );
522 panel_sizer->Layout();
523 panel->SetSizerAndFit( panel_sizer );
524 main_sizer->Add( panel, 1, wxGROW, 0 );
525 main_sizer->Layout();
526 SetSizerAndFit( main_sizer );
529 OpenDialog::~OpenDialog()
532 if( file_dialog ) delete file_dialog;
533 if( sout_dialog ) delete sout_dialog;
534 if( subsfile_dialog ) delete subsfile_dialog;
537 int OpenDialog::Show( int i_access_method, int i_arg )
539 notebook->SetSelection( i_access_method );
540 int i_ret = wxDialog::Show();
547 int OpenDialog::Show()
549 int i_ret = wxDialog::Show();
555 /*****************************************************************************
557 *****************************************************************************/
558 wxPanel *OpenDialog::FilePanel( wxWindow* parent )
560 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
563 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
565 /* Create browse file line */
566 wxBoxSizer *file_sizer = new wxBoxSizer( wxHORIZONTAL );
568 file_combo = new wxComboBox( panel, FileName_Event, wxT(""),
569 wxPoint(20,25), wxSize(200, -1), 0, NULL );
570 wxButton *browse_button = new wxButton( panel, FileBrowse_Event,
571 wxU(_("Browse...")) );
572 file_sizer->Add( file_combo, 1, wxALL, 5 );
573 file_sizer->Add( browse_button, 0, wxALL, 5 );
575 /* Create Subtitles File checkox */
576 wxFlexGridSizer *subsfile_sizer = new wxFlexGridSizer( 2, 1, 20 );
577 subsfile_checkbox = new wxCheckBox( panel, SubsFileEnable_Event,
578 wxU(_("Subtitle options")) );
579 subsfile_checkbox->SetToolTip( wxU(_("Force options for separate subtitle files.")) );
580 subsfile_sizer->Add( subsfile_checkbox, 0,
581 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
582 subsfile_button = new wxButton( panel, SubsFileSettings_Event,
583 wxU(_("Settings...")) );
584 subsfile_button->Disable();
586 char *psz_subsfile = config_GetPsz( p_intf, "sub-file" );
587 if( psz_subsfile && *psz_subsfile )
589 subsfile_checkbox->SetValue(TRUE);
590 subsfile_button->Enable();
591 subsfile_mrl.Add( wxString(wxT("sub-file=")) + wxL2U(psz_subsfile) );
593 if( psz_subsfile ) free( psz_subsfile );
595 subsfile_sizer->Add( subsfile_button, 1,
596 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
598 sizer->Add( file_sizer, 0, wxEXPAND | wxALL, 5 );
599 sizer->Add( subsfile_sizer, 0, wxEXPAND | wxALL, 5 );
600 panel->SetSizerAndFit( sizer );
604 wxPanel *OpenDialog::DiscPanel( wxWindow* parent )
606 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
609 wxBoxSizer *sizer_row = new wxBoxSizer( wxVERTICAL );
610 wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 3, 20 );
612 static const wxString disc_type_array[] =
614 wxU(_("DVD (menus)")),
620 disc_type = new wxRadioBox( panel, DiscType_Event, wxU(_("Disc type")),
621 wxDefaultPosition, wxDefaultSize,
622 WXSIZEOF(disc_type_array), disc_type_array,
623 WXSIZEOF(disc_type_array), wxRA_SPECIFY_COLS );
625 sizer_row->Add( disc_type, i_disc_type_selection, wxEXPAND | wxALL, 5 );
627 wxStaticText *label = new wxStaticText( panel, -1, wxU(_("Device name")) );
628 disc_device = new wxTextCtrl( panel, DiscDevice_Event, wxT(""),
629 wxDefaultPosition, wxDefaultSize,
632 sizer->Add( label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
633 sizer->Add( disc_device, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
635 disc_title_label = new wxStaticText( panel, -1, wxU(_("Title")) );
636 disc_title = new wxSpinCtrl( panel, DiscTitle_Event );
637 sizer->Add( disc_title_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
638 sizer->Add( disc_title, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
640 disc_chapter_label = new wxStaticText( panel, -1, wxU(_("Chapter")) );
641 disc_chapter = new wxSpinCtrl( panel, DiscChapter_Event );
642 sizer->Add( disc_chapter_label, 0,
643 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
644 sizer->Add( disc_chapter, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
646 disc_sub_label = new wxStaticText( panel, -1, wxU(_("Subtitles track")) );
647 disc_sub = new wxSpinCtrl( panel, DiscSub_Event );
648 sizer->Add( disc_sub_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
649 sizer->Add( disc_sub, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
650 disc_sub->SetRange( -1, 255 );
651 i_disc_sub = config_GetInt( p_intf, "spu-channel" );
652 disc_sub->SetValue( i_disc_sub );
654 sizer_row->Add( sizer, 0, wxEXPAND | wxALL, 5 );
656 panel->SetSizerAndFit( sizer_row );
660 wxPanel *OpenDialog::NetPanel( wxWindow* parent )
663 wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
666 wxBoxSizer *sizer_row = new wxBoxSizer( wxVERTICAL );
667 wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 4, 20 );
669 static const wxString net_type_array[] =
672 wxU(_("UDP/RTP Multicast")),
673 wxU(_("HTTP/FTP/MMS")),
679 net_radios[i] = new wxRadioButton( panel, NetRadio1_Event + i,
681 wxDefaultPosition, wxDefaultSize,
684 net_subpanels[i] = new wxPanel( panel, -1,
685 wxDefaultPosition, wxDefaultSize );
689 wxFlexGridSizer *subpanel_sizer;
691 i_net_ports[0] = config_GetInt( p_intf, "server-port" );
692 subpanel_sizer = new wxFlexGridSizer( 3, 1, 20 );
693 label = new wxStaticText( net_subpanels[0], -1, wxU(_("Port")) );
694 net_ports[0] = new wxSpinCtrl( net_subpanels[0], NetPort1_Event,
695 wxString::Format(wxT("%d"), i_net_ports[0]),
696 wxDefaultPosition, wxDefaultSize,
698 0, 16000, i_net_ports[0] );
700 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
701 subpanel_sizer->Add( net_ports[0], 1,
702 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
703 net_ipv6 = new wxCheckBox( net_subpanels[0], NetForceIPv6_Event,
704 wxU(_("Force IPv6")));
705 subpanel_sizer->Add( net_ipv6, 0,
706 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
707 net_subpanels[0]->SetSizerAndFit( subpanel_sizer );
708 net_radios[0]->SetValue( TRUE );
710 /* UDP/RTP Multicast row */
711 subpanel_sizer = new wxFlexGridSizer( 4, 1, 20 );
712 label = new wxStaticText( net_subpanels[1], -1, wxU(_("Address")) );
713 net_addrs[1] = new wxTextCtrl( net_subpanels[1], NetAddr2_Event, wxT(""),
714 wxDefaultPosition, wxDefaultSize,
716 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
717 subpanel_sizer->Add( net_addrs[1], 1,
718 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
720 label = new wxStaticText( net_subpanels[1], -1, wxU(_("Port")) );
721 i_net_ports[1] = i_net_ports[0];
722 net_ports[1] = new wxSpinCtrl( net_subpanels[1], NetPort2_Event,
723 wxString::Format(wxT("%d"), i_net_ports[1]),
724 wxDefaultPosition, wxDefaultSize,
726 0, 16000, i_net_ports[1] );
728 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
729 subpanel_sizer->Add( net_ports[1], 1,
730 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
731 net_subpanels[1]->SetSizerAndFit( subpanel_sizer );
733 /* HTTP and RTSP rows */
736 subpanel_sizer = new wxFlexGridSizer( 2, 1, 20 );
737 label = new wxStaticText( net_subpanels[i], -1, wxU(_("URL")) );
738 net_addrs[i] = new wxTextCtrl( net_subpanels[i], NetAddr1_Event + i,
739 (i == 2) ? wxT("") : wxT("rtsp://"),
740 wxDefaultPosition, wxSize( 200, -1 ),
742 subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
743 subpanel_sizer->Add( net_addrs[i], 1,
744 wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
745 net_subpanels[i]->SetSizerAndFit( subpanel_sizer );
748 /* Stuff everything into the main panel */
751 sizer->Add( net_radios[i], 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
753 sizer->Add( net_subpanels[i], 1, wxEXPAND | wxALIGN_LEFT |
754 wxALIGN_CENTER_VERTICAL | wxALL, 5 );
757 sizer_row->Add( sizer, 0, wxEXPAND | wxALL, 5 );
759 panel->SetSizerAndFit( sizer_row );
763 void OpenDialog::UpdateMRL()
765 UpdateMRL( i_current_access_method );
768 void OpenDialog::UpdateMRL( int i_access_method )
770 wxString demux, mrltemp;
772 i_current_access_method = i_access_method;
774 switch( i_access_method )
777 //mrltemp = wxT("file") + demux + wxT(":") + file_combo->GetValue();
778 mrltemp = file_combo->GetValue();
782 i_disc_type_selection = disc_type->GetSelection();
784 switch ( i_disc_type_selection )
786 case 0: /* DVD with menus */
787 case 1: /* DVD without menus */
788 if( i_disc_type_selection == 0 )
789 mrltemp = wxT("dvd://") + disc_device->GetValue();
791 mrltemp = wxT("dvdsimple://") + disc_device->GetValue();
793 if( i_disc_title > 0 )
795 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
797 if( i_disc_chapter > 0 )
798 mrltemp += wxString::Format( wxT(":%d"), i_disc_chapter );
801 if( i_disc_sub >= 0 )
802 mrltemp += wxString::Format( wxT(" :spu-channel=%d"),
806 case 2: /* VCD of some sort */
808 mrltemp = wxT("vcdx://") + disc_device->GetValue();
809 if( i_disc_title > 0 )
810 mrltemp += wxString::Format( wxT("@%c%d"),
811 config_GetInt( p_intf, "vcdx-PBC" )
812 ? 'P' : 'E', i_disc_title );
814 mrltemp = wxT("vcd://") + disc_device->GetValue();
815 if( i_disc_title > 0 )
816 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
819 if( i_disc_sub >= 0 )
820 mrltemp += wxString::Format( wxT(" :spu-channel=%d"),
825 mrltemp = wxT("cdda://") + disc_device->GetValue();
826 if( i_disc_title > 0 )
827 mrltemp += wxString::Format( wxT("@%d"), i_disc_title );
831 msg_Err( p_intf, "invalid selection (%d)",
832 disc_type->GetSelection() );
841 mrltemp = wxT("udp") + demux + wxT("://");
842 if ( net_ipv6->GetValue() )
844 mrltemp += wxT("@[::]");
846 if( i_net_ports[0] !=
847 config_GetInt( p_intf, "server-port" ) )
849 mrltemp += wxString::Format( wxT("@:%d"), i_net_ports[0] );
854 mrltemp = wxT("udp") + demux + wxT("://@");
855 if ((net_addrs[1]->GetLineText(0).Find (':') != -1)
856 && (net_addrs[1]->GetLineText(0)[0u] != '['))
858 /* automatically adds '[' and ']' to IPv6 addresses */
859 mrltemp += wxT("[") + net_addrs[1]->GetLineText(0)
864 mrltemp += net_addrs[1]->GetLineText(0);
866 if( i_net_ports[1] != config_GetInt( p_intf, "server-port" ) )
868 mrltemp += wxString::Format( wxT(":%d"), i_net_ports[1] );
874 if( net_addrs[2]->GetLineText(0).Find(wxT("http://")) )
876 mrltemp = wxT("http") + demux + wxT("://");
878 mrltemp += net_addrs[2]->GetLineText(0);
883 if( net_addrs[3]->GetLineText(0).Find(wxT("rtsp://")) != 0 )
885 mrltemp = wxT("rtsp") + demux + wxT("://");
887 mrltemp += net_addrs[3]->GetLineText(0);
894 int i_item = i_access_method - MAX_ACCESS;
896 if( i_item < 0 || i_item >= (int)input_tab_array.GetCount() )
899 AutoBuiltPanel *input_panel = input_tab_array.Item( i_item );
901 mrltemp = input_panel->name + wxT("://");
903 for( int i=0; i < (int)input_panel->config_array.GetCount(); i++ )
905 ConfigControl *control = input_panel->config_array.Item(i);
907 mrltemp += wxT(" :");
909 if( control->GetType() == CONFIG_ITEM_BOOL &&
910 !control->GetIntValue() ) mrltemp += wxT("no-");
912 mrltemp += control->GetName();
914 switch( control->GetType() )
916 case CONFIG_ITEM_STRING:
917 case CONFIG_ITEM_FILE:
918 case CONFIG_ITEM_DIRECTORY:
919 case CONFIG_ITEM_MODULE:
920 mrltemp += wxT("=\"") + control->GetPszValue() + wxT("\"");
922 case CONFIG_ITEM_INTEGER:
924 wxString::Format( wxT("=%i"), control->GetIntValue() );
926 case CONFIG_ITEM_FLOAT:
928 wxString::Format(wxT("=%f"), control->GetFloatValue());
933 if( input_panel->p_advanced_mrl_combo &&
934 input_panel->p_advanced_mrl_combo->GetValue() )
936 mrltemp += wxT(" ") +
937 input_panel->p_advanced_mrl_combo->GetValue();
943 mrl_combo->SetValue( mrltemp );
946 /*****************************************************************************
948 *****************************************************************************/
949 void OpenDialog::OnOk( wxCommandEvent& WXUNUSED(event) )
951 mrl = SeparateEntries( mrl_combo->GetValue() );
952 mrl_combo->Append( mrl_combo->GetValue() );
953 if( mrl_combo->GetCount() > 10 ) mrl_combo->Delete( 0 );
954 mrl_combo->SetSelection( mrl_combo->GetCount() - 1 );
956 if( i_method == OPEN_STREAM )
958 if( IsModal() ) EndModal( wxID_OK );
963 /* Update the playlist */
964 playlist_t *p_playlist =
965 (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
967 if( p_playlist == NULL ) return;
969 for( int i = 0; i < (int)mrl.GetCount(); i++ )
971 vlc_bool_t b_start = !i && i_open_arg;
972 playlist_item_t *p_item =
973 playlist_ItemNew( p_intf, (const char*)mrl[i].mb_str(),
974 (const char *)mrl[i].mb_str() );
977 while( i + 1 < (int)mrl.GetCount() &&
978 ((const char *)mrl[i + 1].mb_str())[0] == ':' )
980 playlist_ItemAddOption( p_item, mrl[i + 1].mb_str() );
984 /* Get the options from the subtitles dialog */
985 if( subsfile_checkbox->IsChecked() && subsfile_mrl.GetCount() )
987 for( int j = 0; j < (int)subsfile_mrl.GetCount(); j++ )
989 playlist_ItemAddOption( p_item, subsfile_mrl[j].mb_str() );
993 /* Get the options from the stream output dialog */
994 if( sout_checkbox->IsChecked() && sout_mrl.GetCount() )
996 for( int j = 0; j < (int)sout_mrl.GetCount(); j++ )
998 playlist_ItemAddOption( p_item, sout_mrl[j].mb_str() );
1002 int i_id = playlist_AddItem( p_playlist, p_item,
1003 PLAYLIST_APPEND, PLAYLIST_END );
1007 int i_pos = playlist_GetPositionById( p_playlist , i_id );
1008 playlist_Command( p_playlist, PLAYLIST_GOTO, i_pos );
1012 vlc_object_release( p_playlist );
1016 if( IsModal() ) EndModal( wxID_OK );
1019 void OpenDialog::OnCancel( wxCommandEvent& WXUNUSED(event) )
1023 if( IsModal() ) EndModal( wxID_CANCEL );
1026 void OpenDialog::OnPageChange( wxNotebookEvent& event )
1028 UpdateMRL( event.GetSelection() );
1031 void OpenDialog::OnMRLChange( wxCommandEvent& event )
1033 //mrl = SeparateEntries( event.GetString() );
1036 /*****************************************************************************
1037 * File panel event methods.
1038 *****************************************************************************/
1039 void OpenDialog::OnFilePanelChange( wxCommandEvent& WXUNUSED(event) )
1041 UpdateMRL( FILE_ACCESS );
1044 void OpenDialog::OnFileBrowse( wxCommandEvent& WXUNUSED(event) )
1046 if( file_dialog == NULL )
1047 file_dialog = new wxFileDialog( this, wxU(_("Open File")),
1048 wxT(""), wxT(""), wxT("*"), wxOPEN | wxMULTIPLE );
1050 if( file_dialog && file_dialog->ShowModal() == wxID_OK )
1052 wxArrayString paths;
1055 file_dialog->GetPaths( paths );
1057 for( size_t i = 0; i < paths.GetCount(); i++ )
1059 if( paths[i].Find( wxT(' ') ) >= 0 )
1060 path += wxT("\"") + paths[i] + wxT("\" ");
1062 path += paths[i] + wxT(" ");
1065 file_combo->SetValue( path );
1066 file_combo->Append( path );
1067 if( file_combo->GetCount() > 10 ) file_combo->Delete( 0 );
1068 UpdateMRL( FILE_ACCESS );
1072 /*****************************************************************************
1073 * Disc panel event methods.
1074 *****************************************************************************/
1075 void OpenDialog::OnDiscPanelChange( wxCommandEvent& event )
1077 if( event.GetId() == DiscTitle_Event ) i_disc_title = event.GetInt();
1078 if( event.GetId() == DiscChapter_Event ) i_disc_chapter = event.GetInt();
1079 if( event.GetId() == DiscSub_Event ) i_disc_sub = event.GetInt();
1081 UpdateMRL( DISC_ACCESS );
1084 void OpenDialog::OnDiscDeviceChange( wxCommandEvent& event )
1088 switch( disc_type->GetSelection() )
1091 psz_device = config_GetPsz( p_intf, "cd-audio" );
1095 psz_device = config_GetPsz( p_intf, "vcd" );
1099 psz_device = config_GetPsz( p_intf, "dvd" );
1103 if ( !psz_device ) psz_device = "";
1105 if( disc_device->GetValue().Cmp( wxL2U( psz_device ) ) )
1107 b_disc_device_changed = true;
1110 UpdateMRL( DISC_ACCESS );
1113 void OpenDialog::OnDiscTypeChange( wxCommandEvent& WXUNUSED(event) )
1115 char *psz_device = NULL;
1117 switch( disc_type->GetSelection() )
1120 case 0: /* DVD with menus */
1121 case 1: /* DVD without menus */
1122 disc_sub->Enable(); disc_sub_label->Enable();
1123 disc_chapter->Enable(); disc_chapter_label->Enable();
1124 disc_title_label->SetLabel ( wxU(_("Title")) );
1125 psz_device = config_GetPsz( p_intf, "dvd" );
1126 if( !b_disc_device_changed )
1128 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1129 else disc_device->SetValue( wxT("") );
1131 disc_title->SetRange( 0, 255 );
1132 disc_chapter->SetRange( 0, 255 );
1135 case 2: /* VCD of some sort */
1136 disc_sub->Enable(); disc_sub_label->Enable();
1137 disc_chapter->Disable(); disc_chapter_label->Disable();
1138 psz_device = config_GetPsz( p_intf, "vcd" );
1139 if( !b_disc_device_changed )
1141 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1142 else disc_device->SetValue( wxT("") );
1146 disc_title_label->SetLabel ( config_GetInt( p_intf, "vcdx-PBC" )
1147 ? wxT("Playback LID") : wxT("Entry") );
1149 disc_title_label->SetLabel ( wxU(_("Track")) );
1151 disc_title->SetRange( 0, 999 );
1155 disc_sub->Disable(); disc_sub_label->Disable();
1156 disc_chapter->Disable(); disc_chapter_label->Disable();
1157 disc_title_label->SetLabel ( wxU(_("Track")) );
1158 psz_device = config_GetPsz( p_intf, "cd-audio" );
1159 if( !b_disc_device_changed )
1161 if( psz_device ) disc_device->SetValue( wxL2U(psz_device) );
1162 else disc_device->SetValue( wxT("") );
1165 /* There are at most 99 tracks in a CD-DA */
1166 disc_title->SetRange( 0, 99 );
1170 msg_Err( p_intf, "invalid Disc type selection (%d)",
1171 disc_type->GetSelection() );
1175 disc_title->SetValue( 0 ); i_disc_title = 0;
1176 disc_chapter->SetValue( 0 ); i_disc_chapter = 0;
1178 if( psz_device ) free( psz_device );
1180 UpdateMRL( DISC_ACCESS );
1183 /*****************************************************************************
1184 * Net panel event methods.
1185 *****************************************************************************/
1186 void OpenDialog::OnNetPanelChange( wxCommandEvent& event )
1188 if( event.GetId() >= NetPort1_Event && event.GetId() <= NetPort3_Event )
1190 i_net_ports[event.GetId() - NetPort1_Event] = event.GetInt();
1193 UpdateMRL( NET_ACCESS );
1196 void OpenDialog::OnNetTypeChange( wxCommandEvent& event )
1200 i_net_type = event.GetId() - NetRadio1_Event;
1204 net_radios[i]->SetValue( event.GetId() == (NetRadio1_Event+i) );
1205 net_subpanels[i]->Enable( event.GetId() == (NetRadio1_Event+i) );
1208 UpdateMRL( NET_ACCESS );
1211 /*****************************************************************************
1212 * Subtitles file event methods.
1213 *****************************************************************************/
1214 void OpenDialog::OnSubsFileEnable( wxCommandEvent& event )
1216 subsfile_button->Enable( event.GetInt() != 0 );
1219 void OpenDialog::OnSubsFileSettings( wxCommandEvent& WXUNUSED(event) )
1221 /* Show/hide the open dialog */
1222 if( subsfile_dialog == NULL )
1223 subsfile_dialog = new SubsFileDialog( p_intf, this );
1225 if( subsfile_dialog && subsfile_dialog->ShowModal() == wxID_OK )
1227 subsfile_mrl.Empty();
1228 subsfile_mrl.Add( wxString(wxT("sub-file=")) +
1229 subsfile_dialog->file_combo->GetValue() );
1230 if( subsfile_dialog->encoding_combo )
1231 subsfile_mrl.Add( wxString(wxT("subsdec-encoding=")) +
1232 subsfile_dialog->encoding_combo->GetValue() );
1233 subsfile_mrl.Add( wxString::Format( wxT("sub-delay=%i"),
1234 subsfile_dialog->delay_spinctrl->GetValue() ) );
1235 subsfile_mrl.Add( wxString::Format( wxT("sub-fps=%i"),
1236 subsfile_dialog->fps_spinctrl->GetValue() ) );
1240 /*****************************************************************************
1241 * Stream output event methods.
1242 *****************************************************************************/
1243 void OpenDialog::OnSoutEnable( wxCommandEvent& event )
1245 sout_button->Enable( event.GetInt() != 0 );
1248 void OpenDialog::OnSoutSettings( wxCommandEvent& WXUNUSED(event) )
1250 /* Show/hide the open dialog */
1251 if( sout_dialog == NULL )
1252 sout_dialog = new SoutDialog( p_intf, this );
1254 if( sout_dialog && sout_dialog->ShowModal() == wxID_OK )
1256 sout_mrl = sout_dialog->GetOptions();
1260 /*****************************************************************************
1261 * Utility functions.
1262 *****************************************************************************/
1263 wxArrayString SeparateEntries( wxString entries )
1265 vlc_bool_t b_quotes_mode = VLC_FALSE;
1267 wxArrayString entries_array;
1270 wxStringTokenizer token( entries, wxT(" \t\r\n\""), wxTOKEN_RET_DELIMS );
1272 while( token.HasMoreTokens() )
1274 entry += token.GetNextToken();
1276 if( entry.IsEmpty() ) continue;
1278 if( !b_quotes_mode && entry.Last() == wxT('\"') )
1280 /* Enters quotes mode */
1282 b_quotes_mode = VLC_TRUE;
1284 else if( b_quotes_mode && entry.Last() == wxT('\"') )
1286 /* Finished the quotes mode */
1288 b_quotes_mode = VLC_FALSE;
1290 else if( !b_quotes_mode && entry.Last() != wxT('\"') )
1292 /* we found a non-quoted standalone string */
1293 if( token.HasMoreTokens() ||
1294 entry.Last() == wxT(' ') || entry.Last() == wxT('\t') ||
1295 entry.Last() == wxT('\r') || entry.Last() == wxT('\n') )
1297 if( !entry.IsEmpty() ) entries_array.Add( entry );
1304 if( !entry.IsEmpty() ) entries_array.Add( entry );
1306 return entries_array;