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