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