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