]> git.sesse.net Git - vlc/blob - modules/gui/wxwidgets/dialogs/wizard.cpp
sout-standard-url is deprecated
[vlc] / modules / gui / wxwidgets / dialogs / wizard.cpp
1 /*****************************************************************************
2  * wizard.cpp : wxWindows plugin for vlc
3  *****************************************************************************
4  * Copyright (C) 2000-2005 the VideoLAN team
5  * $Id$
6  *
7  * Authors: ClĂ©ment Stenac <zorglub@videolan.org>
8  *
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.
13  *
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.
18  *
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  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include "dialogs/wizard.hpp"
28 #include "streamdata.h"
29 #include "dialogs/open.hpp"
30
31 #include <wx/listctrl.h>
32 #include <wx/statline.h>
33 #include <network.h>
34
35 class wizHelloPage;
36 class wizInputPage;
37
38 /*****************************************************************************
39  * Define events
40  *****************************************************************************/
41 enum
42 {
43     ActionRadio0_Event, ActionRadio1_Event,
44     MoreInfoStreaming_Event,
45     MoreInfoTranscode_Event,
46
47     Open_Event , Choose_Event ,
48     ListView_Event,
49     InputRadio0_Event, InputRadio1_Event,
50     PartialEnable_Event,
51
52     MethodRadio0_Event, MethodRadio1_Event,
53     MethodRadio2_Event, MethodRadio3_Event,
54
55     EncapRadio0_Event, EncapRadio1_Event,
56     EncapRadio2_Event, EncapRadio3_Event,
57     EncapRadio4_Event, EncapRadio5_Event,
58     EncapRadio6_Event, EncapRadio7_Event,
59     EncapRadio8_Event, EncapRadio9_Event,
60     EncapRadio10_Event, EncapRadio11_Event,
61
62     VideoEnable_Event, VideoCodec_Event,VideoBitrate_Event,
63     AudioEnable_Event, AudioCodec_Event,AudioBitrate_Event,
64
65     SAP_Event,
66
67 };
68
69 #define TEXTWIDTH 55
70 #define ACTION_STREAM 0
71 #define ACTION_TRANSCODE 1
72
73 BEGIN_EVENT_TABLE(WizardDialog, wxWizard)
74 END_EVENT_TABLE()
75
76 /*****************************************************************************
77  * Wizard strings
78  *****************************************************************************/
79
80 #define ERROR_MSG _("Error")
81 #define ITEM_NAME _("Streaming/Transcoding Wizard")
82
83 /* Hello page */
84 #define HELLO_TITLE _("Streaming/Transcoding Wizard")
85 #define HELLO_TEXT _("This wizard helps you to stream, transcode or" \
86                      " save a stream.")
87 #define HELLO_STREAMING _("Stream to network")
88 #define HELLO_STREAMING_DESC _("Use this to stream on a network.")
89 #define HELLO_TRANSCODE _("Transcode/Save to file")
90 #define HELLO_TRANSCODE_DESC _("Use this to re-encode a stream and save it to a file.")
91 #define HELLO_NOTICE _("This wizard only gives access to a small subset of VLC's streaming and transcoding capabilities. Use the Open and Stream Output dialogs to get all of them.")
92
93 #define MOREINFO_STREAM _("Use this to stream on a network")
94
95 #define MOREINFO_TRANSCODE _("Use this to save a stream to a file. You have the possibility to reencode the stream. You can save whatever VLC can read.\nPlease notice that VLC is not very suited " \
96              "for file to file transcoding. You should use its transcoding " \
97              "features to save network streams, for example." )
98
99 /* Input page */
100 #define INPUT_TITLE _("Choose input")
101 #define INPUT_TEXT _("Choose here your input stream.")
102
103 #define INPUT_OPEN _("Select a stream" )
104 #define INPUT_PL _( "Existing playlist item" )
105
106 #define CHOOSE_STREAM _("You must choose a stream")
107 #define NO_PLAYLIST _("Uh Oh! Unable to find playlist !")
108
109 #define PARTIAL _("Use this to read only a part of the stream. " \
110                   "You must be able to control the incoming stream " \
111                   "(for example, a file or a disc, but not a RTP/UDP " \
112                   "network stream.)\n" \
113                   "Enter the starting and ending times (in seconds).")
114
115 #define INPUT_BUTTON _("Choose")
116
117 /* Transcode 1 */
118 #define TRANSCODE1_TITLE _("Transcode")
119 #define TRANSCODE1_TEXT _("If you want to change the compression format of the audio or video tracks, fill in this page. (If you only want to change the container format, proceed to next page.)")
120
121 #define TR_VIDEO_TEXT0 _("If your stream has video and you want to " \
122                          "transcode it, enable this.")
123 #define TR_VIDEO_TEXT _("Select your video codec. Click one to get more " \
124                         "information.")
125
126 #define TR_AUDIO_TEXT0 _("If your stream has audio and you want to "\
127                          "transcode it, enable this.")
128 #define TR_AUDIO_TEXT _("Select your audio codec. Click one to get more " \
129                         "information.")
130
131 /* Streaming 1 */
132 #define STREAMING1_TITLE _("Streaming")
133 #define STREAMING1_TEXT _("In this page, you will select how your input stream will be sent.")
134
135
136 #define INVALID_MCAST_ADDRESS _("This does not appear to be a valid " \
137                                 "multicast address" )
138 #define NO_ADDRESS_TEXT _("You need to enter an address" )
139
140 /* Encap  */
141 #define ENCAP_TITLE _("Encapsulation format")
142 #define ENCAP_TEXT _("In this page, you will select how the stream will be "\
143                      "encapsulated. Depending on the choices you made, all "\
144                      "formats won't be available." )
145
146
147 /* Transcode 2 */
148 #define EXTRATRANSCODE_TITLE _("Additional transcode options")
149 #define EXTRATRANSCODE_TEXT _("In this page, you will define a few " \
150                               "additionnal parameters for your transcoding" )
151
152 #define CHOOSE_OUTFILE _("You must choose a file to save to")
153
154 /* Streaming 2 */
155 #define EXTRASTREAMING_TITLE _("Additional streaming options")
156 #define EXTRASTREAMING_TEXT _("In this page, you will define a few " \
157                               "additionnal parameters for your stream" )
158
159 #define TTL _("Define the TTL (Time-To-Live) of the stream. This parameter " \
160               "is the maximum number of routers your stream can go through. " \
161               "If you don't know what it means, or if you want to stream on " \
162               "your local network only, leave this setting to 1." )
163
164 #define SAP _("When streaming using RTP, you can announce your streams " \
165               "using the SAP/SDP announcing protocol. This way, the clients " \
166               "won't have to type in the multicast address, it will appear " \
167               "in their playlist if they enable the SAP extra interface.\n" \
168               "If you want to give a name to your stream, enter it here, " \
169               "else, a default name will be used" )
170
171 /*****************************************************************************
172  * All the pages of the wizard, declaration
173  *****************************************************************************/
174
175 /* Declare classes */
176 class wizHelloPage : public wxWizardPageSimple
177 {
178     public:
179         wizHelloPage( wxWizard *parent);
180         void OnActionChange( wxCommandEvent& event );
181         void OnWizardPageChanging(wxWizardEvent& event);
182         void OnMoreInfo( wxCommandEvent& event );
183     protected:
184         int i_action;
185         WizardDialog *p_parent;
186         wxRadioButton *action_radios[2];
187         DECLARE_EVENT_TABLE()
188 };
189
190 BEGIN_EVENT_TABLE(wizHelloPage, wxWizardPageSimple)
191     EVT_RADIOBUTTON( ActionRadio0_Event, wizHelloPage::OnActionChange)
192     EVT_RADIOBUTTON( ActionRadio1_Event, wizHelloPage::OnActionChange)
193     EVT_BUTTON( MoreInfoStreaming_Event, wizHelloPage::OnMoreInfo )
194     EVT_BUTTON( MoreInfoTranscode_Event, wizHelloPage::OnMoreInfo )
195
196     EVT_WIZARD_PAGE_CHANGING(-1, wizHelloPage::OnWizardPageChanging)
197 END_EVENT_TABLE()
198
199
200 class wizInputPage : public wxWizardPage
201 {
202     public:
203         wizInputPage( wxWizard *, wxWizardPage *, intf_thread_t *);
204         wizInputPage::~wizInputPage();
205         void OnWizardPageChanging(wxWizardEvent& event);
206         void OnInputChange( wxCommandEvent& event );
207         void OnEnablePartial(wxCommandEvent& event);
208         virtual wxWizardPage *GetPrev() const;
209         virtual wxWizardPage *GetNext() const;
210         void SetStreamingPage( wxWizardPage *page);
211         void SetTranscodePage( wxWizardPage *page);
212         void SetAction( int i_action );
213         void SetPintf( intf_thread_t *p_intf );
214         void SetUri( char *psz_uri );
215         void SetPartial( int i_from, int i_to );
216
217     protected:
218         bool b_chosen;
219         intf_thread_t *p_intf;
220         int i_action;
221         int i_input;
222
223         void OnChoose( wxCommandEvent& event );
224
225         WizardDialog *p_parent;
226         wxRadioButton *input_radios[2];
227         wxCheckBox *enable_checkbox;
228         wxBoxSizer *mainSizer;
229         wxArrayString mrl;
230         wxTextCtrl *mrl_text;
231         wxTextCtrl *from_text;
232         wxTextCtrl *to_text;
233         OpenDialog *p_open_dialog;
234         wxListView *listview;
235         wxPanel *open_panel;
236         wxPanel *radio_panel; /* radio buttons should be in their own panel... */
237         wxWizardPage *p_prev;
238         wxWizardPage *p_streaming_page;
239         wxWizardPage *p_transcode_page;
240
241         DECLARE_EVENT_TABLE()
242 };
243
244 BEGIN_EVENT_TABLE(wizInputPage, wxWizardPage)
245     EVT_RADIOBUTTON( InputRadio0_Event, wizInputPage::OnInputChange)
246     EVT_RADIOBUTTON( InputRadio1_Event, wizInputPage::OnInputChange)
247     EVT_BUTTON( Choose_Event, wizInputPage::OnChoose)
248     EVT_CHECKBOX( PartialEnable_Event, wizInputPage::OnEnablePartial)
249     EVT_WIZARD_PAGE_CHANGING(-1, wizInputPage::OnWizardPageChanging)
250 END_EVENT_TABLE()
251
252
253 class wizTranscodeCodecPage : public wxWizardPage
254 {
255 public:
256     wizTranscodeCodecPage( wxWizard *parent, wxWizardPage *next);
257     ~wizTranscodeCodecPage();
258     void wizTranscodeCodecPage::OnWizardPageChanging(wxWizardEvent& event);
259     virtual wxWizardPage *GetPrev() const;
260     virtual wxWizardPage *GetNext() const;
261     void SetPrev( wxWizardPage *page);
262 protected:
263     wxCheckBox *video_checkbox;
264     wxComboBox *video_combo;
265     wxComboBox *vb_combo;
266     wxStaticText * video_text;
267     wxCheckBox *audio_checkbox;
268     wxComboBox *audio_combo;
269     wxComboBox *ab_combo;
270     wxStaticText * audio_text;
271
272     WizardDialog *p_parent;
273     int i_audio_codec;
274     int i_video_codec;
275
276     char *vcodec;
277     char *acodec;
278
279     wxWizardPage *p_prev;
280     wxWizardPage *p_next;
281
282     void OnVideoCodecChange(wxCommandEvent& event);
283     void OnAudioCodecChange(wxCommandEvent& event);
284     void OnEnableVideo(wxCommandEvent& event);
285     void OnEnableAudio(wxCommandEvent& event);
286
287     DECLARE_EVENT_TABLE()
288 };
289
290 BEGIN_EVENT_TABLE(wizTranscodeCodecPage, wxWizardPage)
291    EVT_CHECKBOX( VideoEnable_Event, wizTranscodeCodecPage::OnEnableVideo)
292    EVT_CHECKBOX( AudioEnable_Event, wizTranscodeCodecPage::OnEnableAudio)
293    EVT_COMBOBOX( VideoCodec_Event, wizTranscodeCodecPage::OnVideoCodecChange)
294    EVT_COMBOBOX( AudioCodec_Event, wizTranscodeCodecPage::OnAudioCodecChange)
295    EVT_WIZARD_PAGE_CHANGING(-1, wizTranscodeCodecPage::OnWizardPageChanging)
296 END_EVENT_TABLE()
297
298 class wizStreamingMethodPage : public wxWizardPage
299 {
300 public:
301     wizStreamingMethodPage( intf_thread_t *p_this, wxWizard *parent,
302                             wxWizardPage *next) ;
303     void OnWizardPageChanging(wxWizardEvent& event);
304     virtual wxWizardPage *GetPrev() const;
305     virtual wxWizardPage *GetNext() const;
306     void SetPrev( wxWizardPage *page);
307 protected:
308     DECLARE_EVENT_TABLE()
309     int i_method;
310     wxBoxSizer *mainSizer;
311     wxStaticBoxSizer *address_sizer;
312     wxStaticText *address_text;
313     wxTextCtrl *address_txtctrl;
314     WizardDialog * p_parent;
315     void OnMethodChange( wxCommandEvent& event );
316     wxRadioButton *method_radios[4];
317     wxWizardPage *p_prev;
318     wxWizardPage *p_next;
319     intf_thread_t *p_intf;
320 };
321
322 BEGIN_EVENT_TABLE(wizStreamingMethodPage, wxWizardPage)
323     EVT_RADIOBUTTON( MethodRadio0_Event, wizStreamingMethodPage::OnMethodChange)
324     EVT_RADIOBUTTON( MethodRadio1_Event, wizStreamingMethodPage::OnMethodChange)
325     EVT_RADIOBUTTON( MethodRadio2_Event, wizStreamingMethodPage::OnMethodChange)
326     EVT_RADIOBUTTON( MethodRadio3_Event, wizStreamingMethodPage::OnMethodChange)
327     EVT_WIZARD_PAGE_CHANGING(-1, wizStreamingMethodPage::OnWizardPageChanging)
328 END_EVENT_TABLE()
329
330
331 class wizEncapPage : public wxWizardPage
332 {
333 public:
334     wizEncapPage( wxWizard *parent);
335     wizEncapPage::~wizEncapPage();
336     void OnWizardPageChanging(wxWizardEvent& event);
337     virtual wxWizardPage *GetPrev() const;
338     virtual wxWizardPage *GetNext() const;
339     void SetStreamingPage( wxWizardPage *page);
340     void SetTranscodePage( wxWizardPage *page);
341     void SetPrev( wxWizardPage *page);
342     void SetAction( int );
343     void EnableEncap( int encap );
344 protected:
345     DECLARE_EVENT_TABLE()
346     int i_encap;
347     int i_mux;
348     int i_action;
349     void OnEncapChange( wxCommandEvent& event );
350     wxRadioButton *encap_radios[MUXERS_NUMBER];
351     WizardDialog *p_parent;
352     wxWizardPage *p_prev;
353     wxWizardPage *p_streaming_page;
354     wxWizardPage *p_transcode_page;
355 };
356
357 BEGIN_EVENT_TABLE(wizEncapPage, wxWizardPage)
358     EVT_WIZARD_PAGE_CHANGING(-1, wizEncapPage::OnWizardPageChanging)
359     EVT_RADIOBUTTON( EncapRadio0_Event, wizEncapPage::OnEncapChange)
360     EVT_RADIOBUTTON( EncapRadio1_Event, wizEncapPage::OnEncapChange)
361     EVT_RADIOBUTTON( EncapRadio2_Event, wizEncapPage::OnEncapChange)
362     EVT_RADIOBUTTON( EncapRadio3_Event, wizEncapPage::OnEncapChange)
363     EVT_RADIOBUTTON( EncapRadio4_Event, wizEncapPage::OnEncapChange)
364     EVT_RADIOBUTTON( EncapRadio5_Event, wizEncapPage::OnEncapChange)
365     EVT_RADIOBUTTON( EncapRadio6_Event, wizEncapPage::OnEncapChange)
366     EVT_RADIOBUTTON( EncapRadio7_Event, wizEncapPage::OnEncapChange)
367     EVT_RADIOBUTTON( EncapRadio8_Event, wizEncapPage::OnEncapChange)
368     EVT_RADIOBUTTON( EncapRadio9_Event, wizEncapPage::OnEncapChange)
369     EVT_RADIOBUTTON( EncapRadio10_Event, wizEncapPage::OnEncapChange)
370 END_EVENT_TABLE()
371
372 /* Additional settings for transcode */
373 class wizTranscodeExtraPage : public wxWizardPage
374 {
375 public:
376     wizTranscodeExtraPage( wxWizard *parent, wxWizardPage *prev,
377                             wxWizardPage *next);
378     virtual wxWizardPage *GetPrev() const;
379     virtual wxWizardPage *GetNext() const;
380     void OnWizardPageChanging( wxWizardEvent& event );
381 protected:
382     DECLARE_EVENT_TABLE()
383     void wizTranscodeExtraPage::OnSelectFile(wxCommandEvent&);
384     wxTextCtrl *file_text;
385     WizardDialog *p_parent;
386     wxWizardPage *p_prev;
387     wxWizardPage *p_next;
388 };
389
390 BEGIN_EVENT_TABLE(wizTranscodeExtraPage, wxWizardPage)
391     EVT_BUTTON( Open_Event, wizTranscodeExtraPage::OnSelectFile)
392     EVT_WIZARD_PAGE_CHANGING(-1, wizTranscodeExtraPage::OnWizardPageChanging)
393 END_EVENT_TABLE()
394
395 /* Additional settings for streaming */
396 class wizStreamingExtraPage : public wxWizardPage
397 {
398 public:
399     wizStreamingExtraPage( wxWizard *parent, wxWizardPage *prev,
400                             wxWizardPage *next);
401     virtual wxWizardPage *GetPrev() const;
402     virtual wxWizardPage *GetNext() const;
403     void OnWizardPageChanging(wxWizardEvent&);
404     void OnSAP( wxCommandEvent&);
405     wxCheckBox *sap_checkbox;
406     wxTextCtrl *sap_text;
407 protected:
408     friend class wizEncapPage;
409     DECLARE_EVENT_TABLE()
410     WizardDialog *p_parent;
411     wxWizardPage *p_prev;
412     wxWizardPage *p_next;
413
414     wxSpinCtrl *ttl_spin;
415 };
416
417 BEGIN_EVENT_TABLE(wizStreamingExtraPage, wxWizardPage)
418     EVT_CHECKBOX( SAP_Event, wizStreamingExtraPage::OnSAP )
419     EVT_WIZARD_PAGE_CHANGING(-1, wizStreamingExtraPage::OnWizardPageChanging)
420 END_EVENT_TABLE()
421
422
423 /* Local functions */
424 static void pageHeader( wxWindow *window, wxBoxSizer *sizer,
425                        char *psz_title, char *psz_text);
426
427 static void pageHeader( wxWindow *window, wxBoxSizer *sizer,
428                         char *psz_title, char *psz_text)
429 {
430     wxStaticText *wtitle = new wxStaticText( window, -1, wxU( psz_title ) );
431     wxFont font = wtitle->GetFont();
432     font.SetPointSize(14);
433     wtitle->SetFont(font);
434     sizer->Add( wtitle, 0, wxALL, 5 );
435     sizer->Add( new wxStaticText( window, -1,
436                 wxU( vlc_wraptext( psz_text , TEXTWIDTH, false ) ) ),
437                         0, wxALL, 5 );
438 }
439
440 /***************************************************************************
441  * Implementation of the pages
442  ***************************************************************************/
443
444
445 /***************************************************
446  * First page: choose between stream and transcode *
447  ***************************************************/
448 wizHelloPage::wizHelloPage( wxWizard *parent) : wxWizardPageSimple(parent)
449 {
450         i_action = 0;
451         p_parent = (WizardDialog *)parent;
452         wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL);
453
454         /* Create the texts */
455         pageHeader( this, mainSizer, HELLO_TITLE, HELLO_TEXT );
456
457         /* Create the radio buttons with their helps */
458         action_radios[0] = new wxRadioButton( this, ActionRadio0_Event,
459                                               wxU( HELLO_STREAMING ) );
460         action_radios[1] = new wxRadioButton( this, ActionRadio1_Event,
461                                               wxU( HELLO_TRANSCODE ) );
462         i_action = 0;
463
464         mainSizer->Add( 0, 0, 1 );
465
466         wxBoxSizer *stream_sizer = new wxBoxSizer( wxHORIZONTAL );
467         stream_sizer->Add( action_radios[0], 0, wxALL, 5 );
468         stream_sizer->Add( 0,0,1 );
469         stream_sizer->Add( new wxButton( this, MoreInfoStreaming_Event,
470                                 wxU( _("More Info")) ), 0, 0, 0 );
471         mainSizer->Add( stream_sizer, 0, wxALL | wxEXPAND , 5 );
472
473         wxBoxSizer *transcode_sizer = new wxBoxSizer( wxHORIZONTAL );
474         transcode_sizer->Add( action_radios[1], 0, wxALL, 5 );
475         transcode_sizer->Add( 0,0,1);
476         transcode_sizer->Add( new wxButton( this, MoreInfoTranscode_Event,
477                                 wxU( _("More Info")) ), 0 ,  0 , 0 );
478         mainSizer->Add( transcode_sizer, 0, wxALL | wxEXPAND, 5 );
479
480         mainSizer->Add( 0, 0, 1 );
481
482         mainSizer->Add( new wxStaticLine(this, -1 ), 0, wxEXPAND| wxTOP|
483                         wxBOTTOM, 5 );
484
485         mainSizer->Add( new wxStaticText(this, -1,
486                         wxU( vlc_wraptext(HELLO_NOTICE , TEXTWIDTH , false ))),
487                         0, wxALL, 5 );
488
489         SetSizer(mainSizer);
490         mainSizer->Fit(this);
491     }
492
493 void wizHelloPage::OnMoreInfo(wxCommandEvent& event)
494 {
495     wxString msg;
496     msg.Printf( wxString( wxU( event.GetId() == MoreInfoStreaming_Event ?
497                                     MOREINFO_STREAM :
498                                     MOREINFO_TRANSCODE ) ) );
499     wxMessageBox( msg, wxU(_("More information")),
500                   wxOK | wxICON_INFORMATION, this->p_parent );
501 }
502
503 void wizHelloPage::OnActionChange( wxCommandEvent& event )
504 {
505     i_action = event.GetId() - ActionRadio0_Event;
506     ((wizInputPage *)GetNext())->SetAction( i_action );
507     p_parent->SetAction( i_action );
508 }
509
510 void wizHelloPage::OnWizardPageChanging(wxWizardEvent& event)
511 {
512     ((wizInputPage *)GetNext())->SetAction( i_action );
513     p_parent->SetAction( i_action );
514 }
515
516 /************************************
517  * Second page: choose input stream *
518  ************************************/
519 wizInputPage::wizInputPage( wxWizard *parent, wxWizardPage *prev, intf_thread_t *_p_intf) :
520               wxWizardPage(parent)
521 {
522     p_prev = prev;
523     p_intf = _p_intf;
524     p_parent = (WizardDialog *)parent;
525     b_chosen = false;
526     p_open_dialog = NULL;
527     listview = NULL;
528     mrl_text = NULL;
529     mainSizer = new wxBoxSizer(wxVERTICAL);
530
531     /* Create the texts */
532     pageHeader( this, mainSizer, INPUT_TITLE, INPUT_TEXT );
533
534     mainSizer->Add( 0,20,0 );
535
536     radio_panel = new wxPanel(this, -1);
537     radio_panel->SetAutoLayout( TRUE );
538
539     wxBoxSizer *radioSizer = new wxBoxSizer(wxVERTICAL);
540
541     /* Create the radio buttons */
542     input_radios[0] = new wxRadioButton( radio_panel, InputRadio0_Event ,
543                                wxU( INPUT_OPEN ) );
544     radioSizer->Add( input_radios[0], 0, wxALL, 5 );
545     input_radios[1] = new wxRadioButton( radio_panel, InputRadio1_Event ,
546                                wxU( INPUT_PL ) );  
547     radioSizer->Add( input_radios[1], 0, wxALL, 5 );
548
549     radio_panel->SetSizer( radioSizer );
550     radioSizer->Layout();
551     radioSizer->Fit(radio_panel);
552     mainSizer->Add( radio_panel );
553
554     i_input = 0;
555
556     /* Open Panel */
557     open_panel = new wxPanel(this, -1);
558     open_panel->SetAutoLayout( TRUE );
559
560     wxBoxSizer *openSizer = new wxBoxSizer(wxHORIZONTAL);
561
562     mrl_text = new wxTextCtrl( open_panel, -1, wxU( "" ), wxDefaultPosition,
563                               wxSize(200,25) );
564
565     openSizer->Add( mrl_text, 0 , wxALL, 5 );
566     openSizer->Add( new wxButton( open_panel, Choose_Event, wxU(_("Choose...")) ), 0, wxALL, 5 );
567
568     open_panel->SetSizer( openSizer );
569     openSizer->Layout();
570     openSizer->Fit(open_panel);
571     mainSizer->Add( open_panel );
572
573     playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_intf,
574                                        VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
575
576     if( p_playlist )
577     {
578         if( p_playlist->i_size > 0)
579         {
580             listview = new wxListView( this, ListView_Event,
581                                        wxDefaultPosition, wxDefaultSize,
582                                        wxLC_REPORT | wxSUNKEN_BORDER );
583             listview->InsertColumn( 0, wxU(_("Name")) );
584             listview->InsertColumn( 1, wxU(_("URI")) );
585             listview->SetColumnWidth( 0, 250 );
586             listview->SetColumnWidth( 1, 100 );
587             for( int i=0 ; i < p_playlist->i_size ; i++ )
588             {
589                 wxString filename = wxL2U( p_playlist->pp_items[i]->input.
590                                                                     psz_name );
591                 listview->InsertItem( i, filename );
592                 listview->SetItem( i, 1, wxL2U( p_playlist->pp_items[i]->
593                                                             input.psz_uri) );
594                 listview->SetItemData( i,
595                                   (long)p_playlist->pp_items[i]->input.i_id );
596             }
597             listview->Select( p_playlist->i_index , TRUE);
598             mainSizer->Add( listview, 1, wxALL|wxEXPAND, 5 );
599
600             listview->Hide();
601             mainSizer->Hide( listview );
602             mainSizer->Layout();
603         }
604         else
605         {
606             input_radios[1]->Disable();
607         }
608         vlc_object_release( p_playlist );
609     }
610     else
611     {
612         input_radios[1]->Disable();
613     }
614
615     /* Partial Extract Box */
616     mainSizer->Add( 0, 10, 0 );
617     wxStaticBox *partial_box = new wxStaticBox( this, -1,
618                     wxU(_("Partial Extract")) );
619
620     wxStaticBoxSizer *partial_sizer = new wxStaticBoxSizer( partial_box,
621                                                           wxVERTICAL );
622
623     enable_checkbox = new wxCheckBox( this, PartialEnable_Event,
624                                                 wxU(_("Enable") ) );
625     enable_checkbox->SetToolTip(wxU(_(PARTIAL) ) ) ;
626     partial_sizer->Add( enable_checkbox, 0 , wxALIGN_CENTER_VERTICAL|wxALL, 5 ); //wxLEFT
627
628     wxFlexGridSizer *partial_sizer2 = new wxFlexGridSizer( 4 , 1 , 20 );
629     partial_sizer2->Add( new wxStaticText(this, -1, wxU(_( "From" ) ) ),
630                          0 , wxLEFT , 5 );
631     from_text = new wxTextCtrl( this, -1, wxT(""),
632                                 wxDefaultPosition, wxSize( 80,25 ) );
633     partial_sizer2->Add( from_text, 0 , wxALIGN_RIGHT);
634     partial_sizer2->Add( new wxStaticText(this, -1, wxU(_( "To" ) ) ),
635                          0 , wxLEFT , 5 );
636     to_text = new wxTextCtrl( this, -1, wxT(""),
637                                   wxDefaultPosition, wxSize( 80 , 25 ) );
638     partial_sizer2->Add( to_text, 0 , wxALIGN_RIGHT );
639
640     partial_sizer->Add( partial_sizer2, 0, wxALL, 0 );
641
642     partial_sizer->Fit( partial_box );
643
644     mainSizer->Add( partial_sizer, 0, 0, 0 );
645
646     from_text->Disable();
647     to_text->Disable();
648     SetSizer(mainSizer);
649     mainSizer->Fit(this);
650     mainSizer->Layout();
651 }
652
653 wizInputPage::~wizInputPage()
654 {
655 }
656
657 void wizInputPage::OnInputChange( wxCommandEvent& event )
658 {
659     i_input = event.GetId() - InputRadio0_Event;
660     if( i_input == 0 )
661     {
662         if( listview )
663         {
664             listview->Hide();
665             mainSizer->Hide( listview );
666             open_panel->Show();
667             mainSizer->Show( open_panel );
668             mainSizer->Layout();
669         }
670     }
671     else
672     {
673         open_panel->Hide();
674         mainSizer->Hide( open_panel );
675         listview->Show();
676         mainSizer->Show( listview );
677         mainSizer->Layout();
678     }
679 }
680
681 void wizInputPage::OnEnablePartial(wxCommandEvent& event)
682 {
683    from_text->Enable( event.IsChecked() );
684    to_text->Enable( event.IsChecked() );
685 }
686
687
688 void wizInputPage::OnChoose(wxCommandEvent& event)
689 {
690     p_open_dialog = new OpenDialog( p_intf, this, -1, -1, OPEN_STREAM );
691     if(  p_open_dialog->ShowModal() == wxID_OK &&
692          !p_open_dialog->mrl.IsEmpty() )
693     {
694         mrl_text->SetValue(p_open_dialog->mrl[0] );
695     }
696     delete p_open_dialog;
697     p_open_dialog = NULL;
698 }
699
700 void wizInputPage::OnWizardPageChanging(wxWizardEvent& event)
701 {
702     if( i_input == 0)
703     {
704         if( mrl_text->GetValue().IsSameAs( wxT(""), TRUE ) &&
705                         event.GetDirection() )
706         {
707             wxMessageBox( wxU( CHOOSE_STREAM ), wxU( ERROR_MSG ),
708                           wxICON_WARNING | wxOK, this->p_parent );
709             event.Veto();
710             return;
711         }
712         else
713         {
714             p_parent->SetMrl( (const char *)mrl_text->GetValue().mb_str() );
715         }
716     }
717     else
718     {
719         int i = -1;
720         i = listview->GetNextItem( i , wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
721         if( i != -1 )
722         {
723             long data = listview->GetItemData( i );            
724             playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_intf,
725                                       VLC_OBJECT_PLAYLIST, FIND_ANYWHERE);
726             if( p_playlist )
727             {
728                 playlist_item_t * p_item = playlist_LockItemGetById(
729                                                    p_playlist, (int)data );
730                 if( p_item )
731                 {
732                     p_parent->SetMrl( (const char*)p_item->input.psz_uri );
733                 }
734                 else
735                     event.Veto();
736             }
737             else
738                 event.Veto();
739         }
740     }
741     if( enable_checkbox->IsChecked() )
742     {
743         int i_from = atoi( from_text->GetValue().mb_str() );
744         int i_to = atoi( to_text->GetValue().mb_str() );
745         p_parent->SetPartial( i_from, i_to );
746     }
747     return;
748 }
749
750 wxWizardPage *wizInputPage::GetPrev() const { return p_prev; }
751 wxWizardPage *wizInputPage::GetNext() const
752 {
753     if( i_action == ACTION_STREAM )
754         return p_streaming_page;
755     else
756        return p_transcode_page;
757 }
758
759 void wizInputPage::SetStreamingPage( wxWizardPage *page)
760 {
761     p_streaming_page = page;
762 }
763
764 void wizInputPage::SetTranscodePage( wxWizardPage *page)
765 {
766     p_transcode_page = page;
767 }
768
769 void wizInputPage::SetAction( int i_action )
770 {
771     this->i_action = i_action;
772 }
773
774 void wizInputPage::SetPintf( intf_thread_t *p_intf )
775 {
776     this->p_intf = p_intf;
777 }
778
779 void wizInputPage::SetUri( char *psz_uri )
780 {
781     mrl_text->SetValue( wxU( psz_uri ) );
782 }
783
784 void wizInputPage::SetPartial( int i_from, int i_to )
785 {
786    wxString msg;
787    msg.Printf( wxString( wxT( "%i") ), i_from );
788    from_text->Enable( TRUE );
789    from_text->SetValue( msg );
790    msg.Printf( wxString( wxT( "%i") ), i_to );
791    to_text->Enable( TRUE );
792    to_text->SetValue( msg );
793    enable_checkbox->SetValue( TRUE );
794 }
795
796 /***************************************************
797  * First transcode page: choose codecs             *
798  ***************************************************/
799 wizTranscodeCodecPage::wizTranscodeCodecPage( wxWizard *parent,
800                        wxWizardPage *next) : wxWizardPage(parent)
801 {
802     int i;
803
804     p_next = next;
805
806     acodec = NULL;
807     vcodec = NULL;
808     p_parent = (WizardDialog *) parent;
809
810     wxBoxSizer *main_sizer = new wxBoxSizer(wxVERTICAL);
811
812     /* Header */
813     pageHeader( this, main_sizer,  TRANSCODE1_TITLE, TRANSCODE1_TEXT );
814
815     /* Video Box */
816     wxStaticBox *video_box = new wxStaticBox( this, -1, wxU(_("Video")) );
817     wxStaticBoxSizer *video_sizer = new wxStaticBoxSizer( video_box,
818                                                           wxVERTICAL );
819     /* Line 1 : only the checkbox */
820     wxFlexGridSizer *video_sizer1 = new wxFlexGridSizer( 2,3,20 );
821     video_sizer1->Add( new wxCheckBox( this, VideoEnable_Event,
822                        wxU(_("Transcode video") ) ), 0 , wxALIGN_CENTER_VERTICAL|wxALL , 5 );
823     video_sizer1->Add( 0,0,1);
824     /* Line 2 : codec */
825     video_sizer1->Add( new wxStaticText(this, -1, wxU(_("Codec"))),0,wxLEFT ,5);
826     video_combo = new wxComboBox( this, VideoCodec_Event, wxT(""),
827                                   wxDefaultPosition, wxSize(200,25), 0, NULL, 
828                                   wxCB_DROPDOWN| wxCB_READONLY );
829     for( i= 0; vcodecs_array[i].psz_display != NULL; i++ )
830     {
831         video_combo->Append( wxU( vcodecs_array[i].psz_display ) ,
832                             (void *)&vcodecs_array[i] );
833     }
834     i_video_codec = 0;
835     video_combo->SetSelection(0);
836
837     video_sizer1->Add( video_combo, 0 , wxALIGN_LEFT , 0 );
838
839     video_sizer1->Add( new wxStaticText(this, -1, wxU(_("Bitrate (kb/s)"))),0,
840                        wxLEFT ,5);
841     vb_combo = new wxComboBox( this, VideoBitrate_Event, wxT("1024"),
842                                wxDefaultPosition, wxDefaultSize,
843                                WXSIZEOF(vbitrates_array), vbitrates_array, wxCB_READONLY );
844     video_sizer1->Add( vb_combo, 0, wxALIGN_LEFT , 0 );
845
846     /* Line 3 : text */
847     video_text = new wxStaticText( this, -1,
848                      wxU( vlc_wraptext( TR_VIDEO_TEXT, TEXTWIDTH, false) ) );
849     /* Fill the main video sizer */
850     video_sizer->Add( video_sizer1 , 0, wxEXPAND , 5 );
851     video_sizer->Add( video_text, 0, wxLEFT|wxTOP , 5 );
852
853
854     /* Audio box */
855     wxStaticBox *audio_box = new wxStaticBox( this, -1, wxU(_("Audio")) );
856     wxStaticBoxSizer *audio_sizer = new wxStaticBoxSizer( audio_box,
857                                                           wxVERTICAL );
858     /* Line1: enabler */
859     wxFlexGridSizer *audio_sizer1 = new wxFlexGridSizer( 2,3,20);
860     audio_sizer1->Add( new wxCheckBox( this, AudioEnable_Event,
861                             wxU(_("Transcode audio") ) ), 0 , wxALIGN_CENTER_VERTICAL|wxALL, 5 );
862     audio_sizer1->Add( 0, 0, 1 );
863
864     /* Line 2 : codec */
865     audio_sizer1->Add( new wxStaticText(this, -1, wxU(_("Codec"))),0,wxLEFT,5);
866     audio_combo = new wxComboBox( this, AudioCodec_Event, wxT(""),
867                                   wxDefaultPosition, wxSize(200,25), 0, NULL, 
868                                   wxCB_DROPDOWN| wxCB_READONLY );
869     for( i= 0; acodecs_array[i].psz_display != NULL; i++ )
870     {
871         audio_combo->Append( wxU( acodecs_array[i].psz_display ) ,
872                             (void *)&acodecs_array[i] );
873     }
874     i_audio_codec = 0;
875     audio_combo->SetSelection(0);
876     audio_sizer1->Add( audio_combo, 0 , wxALIGN_LEFT, 0 );
877
878     audio_sizer1->Add( new wxStaticText(this, -1, wxU(_("Bitrate (kb/s)"))),0,
879                        wxLEFT ,5);
880     ab_combo = new wxComboBox( this, AudioBitrate_Event, wxT("192"),
881                                wxDefaultPosition, wxDefaultSize,
882                                WXSIZEOF(abitrates_array), abitrates_array, wxCB_READONLY );
883     audio_sizer1->Add( ab_combo, 0, wxALIGN_LEFT, 0 );
884
885     /* Line 3 : text */
886     audio_text = new wxStaticText( this, -1,
887                      wxU( vlc_wraptext( TR_AUDIO_TEXT, TEXTWIDTH, false) ) );
888
889     audio_sizer->Add(audio_sizer1, 0, wxEXPAND, 5);
890     audio_sizer->Add( audio_text, 0, wxLEFT | wxTOP, 5 );
891
892     main_sizer->Add( video_sizer, 1, wxGROW, 0 );
893     main_sizer->Add( audio_sizer, 1, wxGROW, 0 );
894     main_sizer->Layout();
895     SetSizerAndFit( main_sizer );
896
897     /* Default disabled */
898     video_combo->Disable(); video_text->Disable();vb_combo->Disable();
899     audio_combo->Disable(); audio_text->Disable();ab_combo->Disable();
900
901 }
902
903 wizTranscodeCodecPage::~wizTranscodeCodecPage()
904 {
905     if( acodec ) free( acodec );
906     if( vcodec ) free( vcodec );
907 }
908
909 void wizTranscodeCodecPage::OnEnableVideo(wxCommandEvent& event)
910 {
911    video_combo->Enable( event.IsChecked() );
912    vb_combo->Enable( event.IsChecked() );
913    video_text->Enable( event.IsChecked() );
914 }
915
916 void wizTranscodeCodecPage::OnEnableAudio(wxCommandEvent& event)
917 {
918    audio_combo->Enable( event.IsChecked() );
919    ab_combo->Enable( event.IsChecked() );
920    audio_text->Enable( event.IsChecked() );
921 }
922
923 void wizTranscodeCodecPage::OnVideoCodecChange(wxCommandEvent& event)
924 {
925     struct codec *c = (struct codec*)
926              (video_combo->GetClientData(video_combo->GetSelection()));
927     video_text->SetLabel( wxU( vlc_wraptext(c->psz_descr, TEXTWIDTH, false) ) );
928     i_video_codec = video_combo->GetSelection();
929     vcodec = strdup(c->psz_codec);
930 }
931
932 void wizTranscodeCodecPage::OnAudioCodecChange(wxCommandEvent& event)
933 {
934     struct codec *c = (struct codec*)
935              (audio_combo->GetClientData(audio_combo->GetSelection()));
936     audio_text->SetLabel( wxU( vlc_wraptext(c->psz_descr, TEXTWIDTH, false) ) );
937     i_audio_codec = audio_combo->GetSelection();
938     acodec = strdup(c->psz_codec);
939
940 }
941
942 void wizTranscodeCodecPage::OnWizardPageChanging(wxWizardEvent& event)
943 {
944     unsigned int i,j;
945
946     if( !event.GetDirection() )
947     {
948             GetPrev()->Enable();
949             return;
950     }
951
952     /* Set the dummy codec ( accept all muxers ) if needed */
953     if( !video_combo->IsEnabled() )
954     {
955         i_video_codec = VCODECS_NUMBER;
956     }
957     if( !audio_combo->IsEnabled() )
958     {
959         i_audio_codec = ACODECS_NUMBER;
960     }
961
962     ((wizEncapPage *)GetNext())->SetPrev(this);
963
964     for( i = 0 ; i< MUXERS_NUMBER ; i++ )
965     {
966         if( vcodecs_array[i_video_codec].muxers[i] != -1 )
967         {
968             for( j = 0 ; j<  MUXERS_NUMBER ; j++ )
969             {
970                 if( acodecs_array[i_audio_codec].muxers[j] ==
971                               vcodecs_array[i_video_codec].muxers[i] )
972                 {
973                     ((wizEncapPage*)GetNext())->EnableEncap(
974                                vcodecs_array[i_video_codec].muxers[i] );
975                 }
976             }
977         }
978     }
979     struct codec *c = (struct codec*)
980              (video_combo->GetClientData( video_combo->IsEnabled() ?
981                                           video_combo->GetSelection(): i_video_codec ));
982     vcodec = strdup(c->psz_codec);
983     c = (struct codec*)
984            (audio_combo->GetClientData( audio_combo->IsEnabled() ?
985                                        audio_combo->GetSelection() : i_audio_codec ));
986     acodec = strdup(c->psz_codec);
987
988     int vb = atoi(vb_combo->GetValue().mb_str() );
989     if( vb == 0 )
990     {
991          vb = 1024;
992     }
993     int ab = atoi(ab_combo->GetValue().mb_str() );
994     if( ab == 0)
995     {
996         ab = 192;
997     }
998
999     p_parent->SetTranscode( vcodec, vb , acodec, ab );
1000     ((wizEncapPage*)GetNext())->SetAction( p_parent->GetAction() );
1001     p_parent->SetAction( p_parent->GetAction() );
1002
1003     return;
1004 }
1005
1006 wxWizardPage *wizTranscodeCodecPage::GetPrev() const { return p_prev; }
1007 wxWizardPage *wizTranscodeCodecPage::GetNext() const { return p_next; }
1008 void wizTranscodeCodecPage::SetPrev( wxWizardPage *page) {p_prev = page; }
1009
1010
1011 /***************************************************
1012  * First streaming page: choose method             *
1013  ***************************************************/
1014 wizStreamingMethodPage::wizStreamingMethodPage( intf_thread_t *p_this, wxWizard *parent,
1015     wxWizardPage *next) : wxWizardPage(parent), p_intf( p_this )
1016 {
1017     int i;
1018     p_next = next;
1019     p_parent = (WizardDialog *)parent;
1020
1021     mainSizer = new wxBoxSizer(wxVERTICAL);
1022
1023     /* Create the texts */
1024     pageHeader( this, mainSizer,  STREAMING1_TITLE, STREAMING1_TEXT );
1025
1026     mainSizer->Add( 0,50,0 );
1027
1028     i_method = 0;
1029
1030     wxStaticBox *method_box = new wxStaticBox( this, -1,
1031                                                wxU(_("Streaming method")) );
1032     wxStaticBoxSizer *method_sizer = new wxStaticBoxSizer(method_box,
1033                                                           wxHORIZONTAL );
1034     for( i = 0 ; i< 3 ; i++ )
1035     {
1036         method_radios[i] = new wxRadioButton( this, MethodRadio0_Event + i,
1037                                wxU( methods_array[i].psz_method ) );
1038         method_radios[i]->SetToolTip( wxU(_( methods_array[i].psz_descr ) ) );
1039         method_sizer->Add( method_radios[i], 0, wxALL, 5 );
1040     }
1041
1042     method_sizer->Layout();
1043
1044     wxStaticBox *address_box = new wxStaticBox( this, -1,
1045                     wxU(_("Destination")) );
1046
1047     address_sizer = new wxStaticBoxSizer(address_box,
1048                                          wxVERTICAL );
1049
1050     /* Big kludge, we take the longest text to get the size */
1051     address_text = new wxStaticText(this, -1,
1052                wxU( vlc_wraptext(methods_array[2].psz_address,
1053                                  TEXTWIDTH, false ) ),
1054                wxDefaultPosition, wxDefaultSize );
1055
1056     address_txtctrl = new wxTextCtrl( this, -1, wxU(""), wxDefaultPosition,
1057                                       wxSize(200,25));
1058     address_sizer->Add( address_text, 0, wxALL, 5 );
1059     address_sizer->Add( address_txtctrl, 0, wxALL, 5 );
1060     address_sizer->Layout();
1061
1062     /* Set the minimum size */
1063     address_sizer->SetMinSize( address_sizer->GetSize() );
1064     address_text->SetLabel( wxU(
1065      vlc_wraptext( _(methods_array[0].psz_address), TEXTWIDTH, false)));
1066
1067     mainSizer->Add( method_sizer, 0, wxALL | wxEXPAND, 5 );
1068     mainSizer->Add( address_sizer, 0, wxALL | wxEXPAND, 5 );
1069
1070     mainSizer->Add( 0,0,1 );
1071
1072     mainSizer->Layout();
1073
1074     SetSizer(mainSizer);
1075     mainSizer->Fit(this);
1076
1077     return;
1078 }
1079
1080 void wizStreamingMethodPage::OnWizardPageChanging(wxWizardEvent& event)
1081 {
1082     unsigned int i;
1083     if( !event.GetDirection() ) return;
1084
1085     /* Check valid address */
1086     if( i_method == 1
1087      && !net_AddressIsMulticast( (vlc_object_t *)p_intf,
1088                                  address_txtctrl->GetValue().mb_str()) )
1089     {
1090         wxMessageBox( wxU( INVALID_MCAST_ADDRESS ) , wxU( ERROR_MSG ),
1091                       wxICON_WARNING | wxOK, this->p_parent );
1092         event.Veto();
1093
1094     }
1095     else if( i_method == 0 && address_txtctrl->GetValue().IsEmpty() )
1096     {
1097         wxMessageBox( wxU( NO_ADDRESS_TEXT ) , wxU( ERROR_MSG ),
1098                       wxICON_WARNING | wxOK, this->p_parent );
1099         event.Veto();
1100
1101     }
1102
1103     ((wizEncapPage *)GetNext())->SetPrev(this);
1104     for( i = 0 ; i< MUXERS_NUMBER ; i++ )
1105     {
1106         if( methods_array[i_method].muxers[i] != -1 )
1107         {
1108             ((wizEncapPage*)GetNext())->EnableEncap(
1109                                methods_array[i_method].muxers[i] );
1110         }
1111     }
1112     p_parent->SetStream( methods_array[i_method].psz_access ,
1113                          address_txtctrl->GetValue().mb_str() );
1114
1115     /* Set the action for the muxer page */
1116     ((wizEncapPage*)GetNext())->SetAction( p_parent->GetAction() );
1117     return;
1118 }
1119
1120 wxWizardPage *wizStreamingMethodPage::GetPrev() const { return p_prev; }
1121 wxWizardPage *wizStreamingMethodPage::GetNext() const { return p_next; }
1122
1123 void wizStreamingMethodPage::SetPrev( wxWizardPage *page) {p_prev = page; }
1124
1125
1126 void wizStreamingMethodPage::OnMethodChange( wxCommandEvent& event )
1127 {
1128     i_method = event.GetId() - MethodRadio0_Event;
1129     address_text->SetLabel( wxU(
1130      vlc_wraptext( _(methods_array[i_method].psz_address), TEXTWIDTH, false)));
1131     address_sizer->Layout();
1132     mainSizer->Layout();
1133 }
1134
1135 /***************************************************
1136  * Choose encapsulation format                     *
1137  ***************************************************/
1138 wizEncapPage::wizEncapPage( wxWizard *parent ) : wxWizardPage(parent)
1139 {
1140     int i;
1141     i_mux = 0;
1142     p_parent = (WizardDialog *)parent;
1143     p_streaming_page = NULL;
1144     p_transcode_page = NULL;
1145     p_prev = NULL;
1146     wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL);
1147
1148     /* Create the texts */
1149     pageHeader( this, mainSizer, ENCAP_TITLE, ENCAP_TEXT );
1150
1151     mainSizer->Add( 0,0,1 );
1152
1153     for( i = 0 ; i< MUXERS_NUMBER ; i++ )
1154     {
1155         encap_radios[i] = new wxRadioButton( this, EncapRadio0_Event + i,
1156                                wxU( encaps_array[i].psz_encap ) );
1157         encap_radios[i]->SetToolTip( wxU(_( encaps_array[i].psz_descr ) ) );
1158         mainSizer->Add( encap_radios[i], 0, wxLEFT, 5 );
1159         encap_radios[i]->Disable();
1160     }
1161
1162     mainSizer->Add( 0,0,1 );
1163
1164     SetSizer(mainSizer);
1165     mainSizer->Fit(this);
1166 }
1167
1168 wizEncapPage::~wizEncapPage()
1169 {
1170 }
1171
1172 void wizEncapPage::OnWizardPageChanging(wxWizardEvent& event)
1173 {
1174     int i;
1175     if( !event.GetDirection() )
1176     {
1177         for( i = 0 ; i< MUXERS_NUMBER ; i++ )
1178         {
1179             encap_radios[i]->Disable();
1180         }
1181     }
1182     p_parent->SetMux( encaps_array[i_mux].psz_mux );
1183
1184     if( p_parent->GetAction() == ACTION_STREAM )
1185     {
1186         if( strstr( p_parent->method, "rtp" ))
1187         {
1188             ((wizStreamingExtraPage *)GetNext())->sap_checkbox->Enable();
1189             ((wizStreamingExtraPage *)GetNext())->sap_text->Enable(false);
1190         }
1191         else
1192         {
1193            ((wizStreamingExtraPage *)GetNext())->sap_checkbox->Enable( false );
1194            ((wizStreamingExtraPage *)GetNext())->sap_text->Enable( false );
1195         }
1196     }
1197
1198     return;
1199 }
1200
1201
1202 void wizEncapPage::OnEncapChange( wxCommandEvent& event )
1203 {
1204     i_mux = event.GetId() - EncapRadio0_Event;
1205 }
1206
1207 void wizEncapPage::EnableEncap( int encap )
1208 {
1209     int i;
1210     for( i = 0 ; i< MUXERS_NUMBER ; i++)
1211     {
1212         if( encaps_array[i].id == encap )
1213         {
1214             encap_radios[i]->Enable();
1215             encap_radios[i]->SetValue(true);
1216             i_mux = i;
1217         }
1218     }
1219 }
1220
1221 void wizEncapPage::SetStreamingPage( wxWizardPage *page)
1222 {
1223     p_streaming_page = page;
1224 }
1225
1226 void wizEncapPage::SetTranscodePage( wxWizardPage *page)
1227 {
1228     p_transcode_page = page;
1229 }
1230
1231 wxWizardPage *wizEncapPage::GetPrev() const { return p_prev; }
1232
1233 wxWizardPage *wizEncapPage::GetNext() const
1234 {
1235     if( i_action== ACTION_STREAM )
1236         return p_streaming_page;
1237     else
1238        return p_transcode_page;
1239 }
1240
1241 void wizEncapPage::SetAction( int i_act  ) { i_action = i_act; }
1242
1243 void wizEncapPage::SetPrev( wxWizardPage *page) { p_prev = page; }
1244
1245 /***************************************************
1246  * Extra transcoding page : Select file            *
1247  ***************************************************/
1248 wizTranscodeExtraPage::wizTranscodeExtraPage( wxWizard *parent,
1249                        wxWizardPage *prev,
1250                        wxWizardPage *next) : wxWizardPage(parent)
1251 {
1252     p_next = next;
1253     p_prev = prev;
1254     p_parent = (WizardDialog *) parent;
1255     wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL);
1256
1257     /* Create the texts */
1258     pageHeader( this, mainSizer, EXTRATRANSCODE_TITLE, EXTRATRANSCODE_TEXT );
1259
1260     mainSizer->Add( 0, 0, 1 );
1261
1262     wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 2, 1 );
1263     sizer->Add( new wxStaticText( this, -1,
1264                     wxU(_("Select the file to save to") ) ),
1265                     0, wxALL, 5 );
1266     sizer->Add( 0, 0, 1 );
1267
1268     file_text = new wxTextCtrl( this, -1, wxU(""), wxDefaultPosition,
1269                                 wxSize( 150, -1 ) );
1270
1271     sizer->Add( file_text, 0,  wxALL, 5 );
1272     sizer->Add( new wxButton( this, Open_Event, wxU("Choose") ) );
1273
1274     mainSizer->Add( sizer, 0, 0, 0) ;
1275
1276     mainSizer->Add( 0, 0, 1 );
1277     SetSizer(mainSizer);
1278     mainSizer->Fit(this);
1279 }
1280
1281 void wizTranscodeExtraPage::OnSelectFile( wxCommandEvent &event)
1282 {
1283     wxFileDialog *file_dialog =  new wxFileDialog( this, wxU(_("Save to file")),
1284                    wxT(""), wxT(""), wxT("*"), wxSAVE );
1285
1286     if( file_dialog && file_dialog->ShowModal() == wxID_OK )
1287     {
1288         if( file_dialog->GetFilename().mb_str() )
1289         {
1290             file_text->SetValue( file_dialog->GetPath() );
1291         }
1292     }
1293 }
1294
1295 void wizTranscodeExtraPage::OnWizardPageChanging( wxWizardEvent& event )
1296 {
1297     if( event.GetDirection() && file_text->GetValue().IsEmpty() )
1298     {
1299         wxMessageBox( wxU( CHOOSE_OUTFILE ), wxU( ERROR_MSG ),
1300                       wxICON_WARNING | wxOK, this->p_parent );
1301         event.Veto();
1302     }
1303     if( event.GetDirection() )
1304     {
1305        p_parent->SetTranscodeOut( file_text->GetValue().mb_str());
1306     }
1307 }
1308
1309 wxWizardPage *wizTranscodeExtraPage::GetPrev() const { return p_prev; }
1310 wxWizardPage *wizTranscodeExtraPage::GetNext() const {return p_next; }
1311
1312 /***********************************************************
1313  *  Extra streaming page
1314  ***********************************************************/
1315 wizStreamingExtraPage::wizStreamingExtraPage( wxWizard *parent,
1316                        wxWizardPage *prev,
1317                        wxWizardPage *next) : wxWizardPage(parent)
1318 {
1319     p_next = next;
1320     p_prev = prev;
1321     p_parent = (WizardDialog *) parent;
1322     wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL);
1323
1324     /* Create the texts */
1325     pageHeader( this, mainSizer, EXTRASTREAMING_TITLE, EXTRASTREAMING_TEXT );
1326
1327     mainSizer->Add( 0, 0, 1 );
1328
1329     wxFlexGridSizer *sizer = new wxFlexGridSizer( 2,2,1) ;
1330
1331     /* TTL */
1332     sizer->Add( new wxStaticText( this, -1, wxU(_("Time-To-Live (TTL)"))),
1333                     0, wxALL,  5 );
1334     ttl_spin = new wxSpinCtrl( this, -1, wxEmptyString, wxDefaultPosition, wxDefaultSize,
1335                     0, 1, 255, 1 );
1336     ttl_spin->SetToolTip(wxU(_(TTL) ) ) ;
1337     sizer->Add( ttl_spin, 0, wxALL , 5 );
1338
1339     /* SAP announce */
1340     sap_checkbox =  new wxCheckBox( this, SAP_Event, wxU(_("SAP Announce")) );
1341     sap_checkbox->SetToolTip( wxU(_( SAP ) ) );
1342     sizer->Add( sap_checkbox, 0, 0 , 0 );
1343     sap_text = new wxTextCtrl( this, -1, wxU(""), wxDefaultPosition,
1344                     wxSize(100,25) );
1345     sap_text->SetToolTip( wxU(_( SAP ) ) );
1346     sizer->Add( sap_text, 0, wxALL , 5 );
1347
1348     mainSizer->Add(sizer, 0, wxALL, 5 );
1349
1350     mainSizer->Add( 0, 0, 1 );
1351
1352     SetSizer(mainSizer);
1353     mainSizer->Fit(this);
1354 }
1355
1356 void wizStreamingExtraPage::OnSAP( wxCommandEvent &event )
1357 {
1358     sap_text->Enable( event.IsChecked() );
1359 }
1360
1361 void wizStreamingExtraPage::OnWizardPageChanging(wxWizardEvent& event)
1362 {
1363     if( sap_checkbox->IsChecked() )
1364     {
1365         if( sap_text->GetValue().IsEmpty() )
1366         {
1367             p_parent->SetSAP( true, NULL );
1368         }
1369         else
1370         {
1371             p_parent->SetSAP( true,
1372                              (const char *)sap_text->GetValue().mb_str() );
1373         }
1374     }
1375     else
1376     {
1377         p_parent->SetSAP( false, NULL );
1378     }
1379
1380     p_parent->SetTTL( ttl_spin->GetValue() );
1381 }
1382
1383 wxWizardPage *wizStreamingExtraPage::GetPrev() const { return p_prev; }
1384 wxWizardPage *wizStreamingExtraPage::GetNext() const {return p_next; }
1385
1386
1387 /***************************************************************************
1388  * Implementation of the wizard itself
1389  ***************************************************************************/
1390 wizHelloPage *page1;
1391 wizInputPage *page2 ;
1392 wizTranscodeCodecPage *tr_page1 ;
1393 wizStreamingMethodPage *st_page1;
1394 wizTranscodeExtraPage *tr_page2 ;
1395 wizStreamingExtraPage *st_page2;
1396 wizEncapPage *encap_page;
1397
1398 WizardDialog::WizardDialog(intf_thread_t *_p_intf, wxWindow *_p_parent,
1399                            char *psz_uri, int _i_from, int _i_to  ) :
1400 wxWizard( _p_parent, -1, wxU(_("Streaming/Transcoding Wizard")), wxNullBitmap, wxDefaultPosition)
1401 {
1402     /* Initializations */
1403     p_intf = _p_intf;
1404     SetPageSize(wxSize(400,420));
1405
1406     /* Initialize structure */
1407     i_action = 0;
1408     i_from = _i_from;
1409     i_to = _i_to;
1410     i_ttl = 1;
1411     vb = 0;
1412     ab = 0;
1413     acodec=NULL;
1414     vcodec=NULL;
1415
1416     page1 = new wizHelloPage(this);
1417     page2 = new wizInputPage(this, page1, p_intf);
1418
1419     if( psz_uri )
1420     {
1421         page2->SetUri( psz_uri );
1422     }
1423     if( i_from != 0 || i_to != 0 )
1424     {
1425         page2->SetPartial( i_from, i_to );
1426     }
1427
1428     encap_page = new wizEncapPage(this );
1429     tr_page1 = new wizTranscodeCodecPage(this, encap_page );
1430     st_page1 = new wizStreamingMethodPage( p_intf, this, encap_page);
1431
1432     tr_page2 = new wizTranscodeExtraPage(this, encap_page, NULL );
1433     st_page2 = new wizStreamingExtraPage(this, encap_page, NULL );
1434
1435     /* Page 1 -> 2 */
1436     page1->SetNext( page2 );
1437     /* 2->1 in constructor of 2 */
1438
1439     /* Page 2 -> 3 */
1440     page2->SetTranscodePage(tr_page1);
1441     page2->SetStreamingPage(st_page1);
1442     page2->SetPintf( p_intf );
1443     tr_page1->SetPrev(page2);
1444     st_page1->SetPrev(page2);
1445
1446     /* Page 3 -> 4 */
1447     encap_page->SetTranscodePage( tr_page2 );
1448     encap_page->SetStreamingPage( st_page2 );
1449     /* 3->4 in constructor of 3 */
1450 //    encap_page->SetPrev(tr_page1);
1451 }
1452
1453 WizardDialog::~WizardDialog()
1454 {
1455     Destroy();
1456     delete page1;
1457     delete page2;
1458     delete tr_page1;
1459     delete st_page1 ;
1460     delete st_page2;
1461     delete tr_page2;
1462     delete encap_page;
1463 }
1464
1465 void WizardDialog::SetMrl( const char *mrl )
1466 {
1467     this->mrl = strdup( mrl );
1468 }
1469
1470 void WizardDialog::SetTTL( int i_ttl )
1471 {
1472     this->i_ttl = i_ttl;
1473 }
1474
1475 void WizardDialog::SetSAP( bool b_enabled, const char *psz_text )
1476 {
1477     this->b_sap = b_enabled;
1478     if( b_enabled )
1479     {
1480         if( psz_text != NULL )
1481         {
1482             this->psz_sap_name = strdup( psz_text );
1483         }
1484         else
1485         {
1486             this->psz_sap_name = NULL;
1487         }
1488     }
1489 }
1490
1491 void WizardDialog::SetPartial( int i_from, int i_to )
1492 {
1493     this->i_from = i_from;
1494     this->i_to = i_to;
1495 }
1496
1497 void WizardDialog::SetTranscode( char const *vcodec, int vb,
1498                                  char const *acodec, int ab)
1499 {
1500     if( strcmp( vcodec, "dummy") )
1501     {
1502         this->vcodec= strdup(vcodec);
1503     }
1504     if( strcmp( acodec, "dummy" ) )
1505     {
1506         this->acodec = strdup(acodec);
1507     }
1508     this->vb = vb;
1509     this->ab = ab;
1510 }
1511
1512 void WizardDialog::SetStream( char const *method, char const *address )
1513 {
1514     this->method = strdup( method );
1515     this->address = strdup( address );
1516 }
1517
1518 void WizardDialog::SetTranscodeOut( char const *address )
1519 {
1520     char *psz_utf8 = FromLocale( address );
1521     this->address = strdup( psz_utf8 );
1522     LocaleFree( psz_utf8 );
1523 }
1524
1525 void WizardDialog::SetMux( char const *mux )
1526 {
1527     this->mux = strdup( mux );
1528 }
1529
1530 void WizardDialog::SetAction( int i_action )
1531 {
1532     this->i_action = i_action;
1533 }
1534
1535 int WizardDialog::GetAction()
1536 {
1537     return i_action;
1538 }
1539
1540 void WizardDialog::Run()
1541 {
1542     if( RunWizard(page1) )
1543     {
1544         char *psz_opt;
1545
1546         if( i_action == ACTION_TRANSCODE )
1547         {
1548             msg_Dbg( p_intf,"Starting transcode of %s to file %s",
1549                                   mrl, address);
1550             msg_Dbg( p_intf,"Using %s (%i kbps) / %s (%i kbps),encap %s",
1551                                 vcodec,vb,acodec,ab,mux);
1552             char *psz_transcode;
1553
1554             if( vcodec != NULL || acodec != NULL )
1555             {
1556                 int i_tr_size = 14;
1557                 if( vcodec != NULL )
1558                     i_tr_size += strlen( vcodec ) + 17;
1559                 if( acodec != NULL )
1560                     i_tr_size += strlen( acodec ) + 17;
1561
1562                 if( vb > 999999 )
1563                     vb = 999999;
1564                 else if( vb < 0 )
1565                     vb = 0;
1566
1567                 if( ab > 999999 )
1568                     ab = 999999;
1569                 else if( ab < 0 )
1570                     ab = 0;
1571
1572                 psz_transcode = (char *)malloc( i_tr_size * sizeof(char) );
1573
1574                 strcpy( psz_transcode, "transcode{" );
1575                 if( vcodec != NULL )
1576                 {
1577                     sprintf( psz_transcode + strlen( psz_transcode ),
1578                              "vcodec=%s,vb=%i%s", vcodec, vb,
1579                              ( acodec != NULL ) ? "," : "}:" );
1580                 }
1581                 if( acodec != NULL )
1582                 {
1583                     sprintf( psz_transcode + strlen( psz_transcode ),
1584                              "acodec=%s,ab=%i}:", acodec, ab );
1585                 }
1586             }
1587             else
1588                 psz_transcode = "";
1589
1590             asprintf( &psz_opt, ":sout=#%sstandard{mux=%s,dst=%s,"
1591                       "access=file}", psz_transcode, mux, address );
1592
1593             if( *psz_transcode )
1594                 free( psz_transcode );
1595         }
1596         else
1597         {
1598             char *psz_sap_option = NULL;
1599             bool v6;
1600
1601             msg_Dbg( p_intf, "Starting stream of %s to %s using %s, encap %s",
1602                                mrl, address, method, mux );
1603             if( b_sap )
1604             {
1605                 if( psz_sap_name )
1606                 {
1607                     asprintf( &psz_sap_option,
1608                               ",sap,name=\"%s\"", psz_sap_name );
1609                 }
1610                 else
1611                     psz_sap_option = strdup( ",sap" );
1612
1613             }
1614
1615             /* Add brackets automatically for IPv6 if they are missing */
1616             v6 = ( address[0] != '[' ) && ( strchr( address, ':' ) != NULL );
1617             asprintf( &psz_opt,
1618                       ":sout=#standard{mux=%s,dst=%s%s%s,access=%s%s}",
1619                       mux, v6 ? "[" : "", address, v6 ? "]" : "", method,
1620                       psz_sap_option ?: "" );
1621             if( psz_sap_option ) free( psz_sap_option );
1622         }
1623
1624         playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_intf,
1625                             VLC_OBJECT_PLAYLIST, FIND_ANYWHERE);
1626         if( p_playlist )
1627         {
1628             playlist_item_t *p_item = playlist_ItemNew( p_playlist, mrl,
1629                                                         ITEM_NAME );
1630             playlist_ItemAddOption( p_item, psz_opt);
1631             if( i_from != 0)
1632             {
1633                 char psz_from[20];
1634                 snprintf( psz_from, 20, "start-time=%i", i_from);
1635                 playlist_ItemAddOption( p_item, psz_from);
1636             }
1637             if( i_to != 0)
1638             {
1639                 char psz_to[20];
1640                 snprintf( psz_to, 20, "stop-time=%i", i_to);
1641                 playlist_ItemAddOption( p_item, psz_to);
1642             }
1643
1644             char psz_ttl[20];
1645             snprintf( psz_ttl, 20, "ttl=%i",i_ttl );
1646             playlist_ItemAddOption( p_item, psz_ttl );
1647
1648             playlist_AddItem( p_playlist, p_item, PLAYLIST_GO, PLAYLIST_END );
1649             vlc_object_release(p_playlist);
1650         }
1651         else
1652         {
1653             wxMessageBox( wxU( NO_PLAYLIST ), wxU( ERROR_MSG ),
1654                           wxICON_WARNING | wxOK, this );
1655         }
1656     }
1657 }