]> git.sesse.net Git - vlc/blob - modules/gui/wxwindows/wizard.cpp
4c961d6c789dfc039d841647a90d85b4bb074d72
[vlc] / modules / gui / wxwindows / wizard.cpp
1 /*****************************************************************************
2  * wizard.cpp : wxWindows plugin for vlc
3  *****************************************************************************
4  * Copyright (C) 2000-2004 VideoLAN (Centrale Réseaux) and its contributors
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( wxCommandEvent& 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( wxCommandEvent& 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( wxCommandEvent& 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( wxCommandEvent& 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( wxCommandEvent& 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( wxCommandEvent& 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         p_parent->SetPartial( i_from, i_to );
725     }
726     return;
727 }
728
729 wxWizardPage *wizInputPage::GetPrev() const { return p_prev; }
730 wxWizardPage *wizInputPage::GetNext() const
731 {
732     if( i_action == ACTION_STREAM )
733         return p_streaming_page;
734     else
735        return p_transcode_page;
736 }
737
738 void wizInputPage::SetStreamingPage( wxWizardPage *page)
739 {
740     p_streaming_page = page;
741 }
742
743 void wizInputPage::SetTranscodePage( wxWizardPage *page)
744 {
745     p_transcode_page = page;
746 }
747
748 void wizInputPage::SetAction( int i_action )
749 {
750     this->i_action = i_action;
751 }
752
753 void wizInputPage::SetPintf( intf_thread_t *p_intf )
754 {
755     this->p_intf = p_intf;
756 }
757
758 void wizInputPage::SetUri( char *psz_uri )
759 {
760     mrl_text->SetValue( wxU( psz_uri ) );
761 }
762
763 void wizInputPage::SetPartial( int i_from, int i_to )
764 {
765    wxString msg;
766    msg.Printf( wxString( wxT( "%i") ), i_from );
767    from_text->Enable( TRUE );
768    from_text->SetValue( msg );
769    msg.Printf( wxString( wxT( "%i") ), i_to );
770    to_text->Enable( TRUE );
771    to_text->SetValue( msg );
772    enable_checkbox->SetValue( TRUE );
773 }
774
775 /***************************************************
776  * First transcode page: choose codecs             *
777  ***************************************************/
778 wizTranscodeCodecPage::wizTranscodeCodecPage( wxWizard *parent,
779                        wxWizardPage *next) : wxWizardPage(parent)
780 {
781     p_next = next;
782
783     acodec = NULL;
784     vcodec = NULL;
785     p_parent = (WizardDialog *) parent;
786
787     wxBoxSizer *main_sizer = new wxBoxSizer(wxVERTICAL);
788
789     /* Header */
790     pageHeader( this, main_sizer,  TRANSCODE1_TITLE, TRANSCODE1_TEXT );
791
792     /* Video Box */
793     wxStaticBox *video_box = new wxStaticBox( this, -1, wxU(_("Video")) );
794     wxStaticBoxSizer *video_sizer = new wxStaticBoxSizer( video_box,
795                                                           wxVERTICAL );
796     /* Line 1 : only the checkbox */
797     wxFlexGridSizer *video_sizer1 = new wxFlexGridSizer( 2,3,20 );
798     video_sizer1->Add( new wxCheckBox( this, VideoEnable_Event,
799                        wxU(_("Transcode video") ) ), 0 , wxALIGN_CENTER_VERTICAL|wxALL , 5 );
800     video_sizer1->Add( 0,0,1);
801     /* Line 2 : codec */
802     video_sizer1->Add( new wxStaticText(this, -1, wxU(_("Codec"))),0,wxLEFT ,5);
803     video_combo = new wxComboBox( this, VideoCodec_Event, wxT(""),
804                                   wxDefaultPosition, wxSize(200,25), 0, NULL, 
805                                   wxCB_DROPDOWN| wxCB_READONLY );
806     for( int i= 0; vcodecs_array[i].psz_display != NULL; i++ )
807     {
808         video_combo->Append( wxU( vcodecs_array[i].psz_display ) ,
809                             (void *)&vcodecs_array[i] );
810     }
811     i_video_codec = 0;
812     video_combo->SetSelection(0);
813
814     video_sizer1->Add( video_combo, 0 , wxALIGN_LEFT , 0 );
815
816     video_sizer1->Add( new wxStaticText(this, -1, wxU(_("Bitrate (kb/s)"))),0,
817                        wxLEFT ,5);
818     vb_combo = new wxComboBox( this, VideoBitrate_Event, wxT("1024"),
819                                wxDefaultPosition, wxDefaultSize,
820                                WXSIZEOF(vbitrates_array), vbitrates_array, wxCB_READONLY );
821     video_sizer1->Add( vb_combo, 0, wxALIGN_LEFT , 0 );
822
823     /* Line 3 : text */
824     video_text = new wxStaticText( this, -1,
825                      wxU( vlc_wraptext( TR_VIDEO_TEXT, TEXTWIDTH, false) ) );
826     /* Fill the main video sizer */
827     video_sizer->Add( video_sizer1 , 0, wxEXPAND , 5 );
828     video_sizer->Add( video_text, 0, wxLEFT|wxTOP , 5 );
829
830
831     /* Audio box */
832     wxStaticBox *audio_box = new wxStaticBox( this, -1, wxU(_("Audio")) );
833     wxStaticBoxSizer *audio_sizer = new wxStaticBoxSizer( audio_box,
834                                                           wxVERTICAL );
835     /* Line1: enabler */
836     wxFlexGridSizer *audio_sizer1 = new wxFlexGridSizer( 2,3,20);
837     audio_sizer1->Add( new wxCheckBox( this, AudioEnable_Event,
838                             wxU(_("Transcode audio") ) ), 0 , wxALIGN_CENTER_VERTICAL|wxALL, 5 );
839     audio_sizer1->Add( 0, 0, 1 );
840
841     /* Line 2 : codec */
842     audio_sizer1->Add( new wxStaticText(this, -1, wxU(_("Codec"))),0,wxLEFT,5);
843     audio_combo = new wxComboBox( this, AudioCodec_Event, wxT(""),
844                                   wxDefaultPosition, wxSize(200,25), 0, NULL, 
845                                   wxCB_DROPDOWN| wxCB_READONLY );
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     i_audio_codec = 0;
852     audio_combo->SetSelection(0);
853     audio_sizer1->Add( audio_combo, 0 , wxALIGN_LEFT, 0 );
854
855     audio_sizer1->Add( new wxStaticText(this, -1, wxU(_("Bitrate (kb/s)"))),0,
856                        wxLEFT ,5);
857     ab_combo = new wxComboBox( this, AudioBitrate_Event, wxT("192"),
858                                wxDefaultPosition, wxDefaultSize,
859                                WXSIZEOF(abitrates_array), abitrates_array, wxCB_READONLY );
860     audio_sizer1->Add( ab_combo, 0, wxALIGN_LEFT, 0 );
861
862     /* Line 3 : text */
863     audio_text = new wxStaticText( this, -1,
864                      wxU( vlc_wraptext( TR_AUDIO_TEXT, TEXTWIDTH, false) ) );
865
866     audio_sizer->Add(audio_sizer1, 0, wxEXPAND, 5);
867     audio_sizer->Add( audio_text, 0, wxLEFT | wxTOP, 5 );
868
869     main_sizer->Add( video_sizer, 1, wxGROW, 0 );
870     main_sizer->Add( audio_sizer, 1, wxGROW, 0 );
871     main_sizer->Layout();
872     SetSizerAndFit( main_sizer );
873
874     /* Default disabled */
875     video_combo->Disable(); video_text->Disable();vb_combo->Disable();
876     audio_combo->Disable(); audio_text->Disable();ab_combo->Disable();
877
878 }
879
880 wizTranscodeCodecPage::~wizTranscodeCodecPage()
881 {
882     if( acodec ) free( acodec );
883     if( vcodec ) free( vcodec );
884 }
885
886 void wizTranscodeCodecPage::OnEnableVideo(wxCommandEvent& event)
887 {
888    video_combo->Enable( event.IsChecked() );
889    vb_combo->Enable( event.IsChecked() );
890    video_text->Enable( event.IsChecked() );
891 }
892
893 void wizTranscodeCodecPage::OnEnableAudio(wxCommandEvent& event)
894 {
895    audio_combo->Enable( event.IsChecked() );
896    ab_combo->Enable( event.IsChecked() );
897    audio_text->Enable( event.IsChecked() );
898 }
899
900 void wizTranscodeCodecPage::OnVideoCodecChange(wxCommandEvent& event)
901 {
902     struct codec *c = (struct codec*)
903              (video_combo->GetClientData(video_combo->GetSelection()));
904     video_text->SetLabel( wxU( vlc_wraptext(c->psz_descr, TEXTWIDTH, false) ) );
905     i_video_codec = video_combo->GetSelection();
906     vcodec = strdup(c->psz_codec);
907 }
908
909 void wizTranscodeCodecPage::OnAudioCodecChange(wxCommandEvent& event)
910 {
911     struct codec *c = (struct codec*)
912              (audio_combo->GetClientData(audio_combo->GetSelection()));
913     audio_text->SetLabel( wxU( vlc_wraptext(c->psz_descr, TEXTWIDTH, false) ) );
914     i_audio_codec = audio_combo->GetSelection();
915     acodec = strdup(c->psz_codec);
916
917 }
918
919 void wizTranscodeCodecPage::OnWizardPageChanging(wxWizardEvent& event)
920 {
921     unsigned int i,j;
922
923     if( !event.GetDirection() )
924     {
925             GetPrev()->Enable();
926             return;
927     }
928
929     /* Set the dummy codec ( accept all muxers ) if needed */
930     if( !video_combo->IsEnabled() )
931     {
932         i_video_codec = VCODECS_NUMBER;
933     }
934     if( !audio_combo->IsEnabled() )
935     {
936         i_audio_codec = ACODECS_NUMBER;
937     }
938
939     ((wizEncapPage *)GetNext())->SetPrev(this);
940
941     for( i = 0 ; i< MUXERS_NUMBER ; i++ )
942     {
943         if( vcodecs_array[i_video_codec].muxers[i] != -1 )
944         {
945             for( j = 0 ; j<  MUXERS_NUMBER ; j++ )
946             {
947                 if( acodecs_array[i_audio_codec].muxers[j] ==
948                               vcodecs_array[i_video_codec].muxers[i] )
949                 {
950                     ((wizEncapPage*)GetNext())->EnableEncap(
951                                vcodecs_array[i_video_codec].muxers[i] );
952                 }
953             }
954         }
955     }
956     struct codec *c = (struct codec*)
957              (video_combo->GetClientData( video_combo->IsEnabled() ?
958                                           video_combo->GetSelection(): i_video_codec ));
959     vcodec = strdup(c->psz_codec);
960     c = (struct codec*)
961            (audio_combo->GetClientData( audio_combo->IsEnabled() ?
962                                        audio_combo->GetSelection() : i_audio_codec ));
963     acodec = strdup(c->psz_codec);
964
965     int vb = atoi(vb_combo->GetValue().mb_str() );
966     if( vb == 0 )
967     {
968          vb = 1024;
969     }
970     int ab = atoi(ab_combo->GetValue().mb_str() );
971     if( ab == 0)
972     {
973         ab = 192;
974     }
975
976     p_parent->SetTranscode( vcodec, vb , acodec, ab );
977     ((wizEncapPage*)GetNext())->SetAction( p_parent->GetAction() );
978     p_parent->SetAction( p_parent->GetAction() );
979
980     return;
981 }
982
983 wxWizardPage *wizTranscodeCodecPage::GetPrev() const { return p_prev; }
984 wxWizardPage *wizTranscodeCodecPage::GetNext() const { return p_next; }
985 void wizTranscodeCodecPage::SetPrev( wxWizardPage *page) {p_prev = page; }
986
987
988 /***************************************************
989  * First streaming page: choose method             *
990  ***************************************************/
991 wizStreamingMethodPage::wizStreamingMethodPage( wxWizard *parent,
992     wxWizardPage *next) : wxWizardPage(parent)
993 {
994     int i;
995     p_next = next;
996     p_parent = (WizardDialog *)parent;
997
998     mainSizer = new wxBoxSizer(wxVERTICAL);
999
1000     /* Create the texts */
1001     pageHeader( this, mainSizer,  STREAMING1_TITLE, STREAMING1_TEXT );
1002
1003     mainSizer->Add( 0,50,0 );
1004
1005     i_method = 0;
1006
1007     wxStaticBox *method_box = new wxStaticBox( this, -1,
1008                                                wxU(_("Streaming method")) );
1009     wxStaticBoxSizer *method_sizer = new wxStaticBoxSizer(method_box,
1010                                                           wxHORIZONTAL );
1011     for( i = 0 ; i< 3 ; i++ )
1012     {
1013         method_radios[i] = new wxRadioButton( this, MethodRadio0_Event + i,
1014                                wxU( methods_array[i].psz_method ) );
1015         method_radios[i]->SetToolTip( wxU(_( methods_array[i].psz_descr ) ) );
1016         method_sizer->Add( method_radios[i], 0, wxALL, 5 );
1017     }
1018
1019     method_sizer->Layout();
1020
1021     wxStaticBox *address_box = new wxStaticBox( this, -1,
1022                     wxU(_("Destination")) );
1023
1024     address_sizer = new wxStaticBoxSizer(address_box,
1025                                          wxVERTICAL );
1026
1027     /* Big kludge, we take the longest text to get the size */
1028     address_text = new wxStaticText(this, -1,
1029                wxU( vlc_wraptext(methods_array[2].psz_address,
1030                                  TEXTWIDTH, false ) ),
1031                wxDefaultPosition, wxDefaultSize );
1032
1033     address_txtctrl = new wxTextCtrl( this, -1, wxU(""), wxDefaultPosition,
1034                                       wxSize(200,25));
1035     address_sizer->Add( address_text, 0, wxALL, 5 );
1036     address_sizer->Add( address_txtctrl, 0, wxALL, 5 );
1037     address_sizer->Layout();
1038
1039     /* Set the minimum size */
1040     address_sizer->SetMinSize( address_sizer->GetSize() );
1041     address_text->SetLabel( wxU(
1042      vlc_wraptext( _(methods_array[0].psz_address), TEXTWIDTH, false)));
1043
1044     mainSizer->Add( method_sizer, 0, wxALL | wxEXPAND, 5 );
1045     mainSizer->Add( address_sizer, 0, wxALL | wxEXPAND, 5 );
1046
1047     mainSizer->Add( 0,0,1 );
1048
1049     mainSizer->Layout();
1050
1051     SetSizer(mainSizer);
1052     mainSizer->Fit(this);
1053
1054     return;
1055 }
1056
1057 void wizStreamingMethodPage::OnWizardPageChanging(wxWizardEvent& event)
1058 {
1059     unsigned int i;
1060     if( !event.GetDirection() ) return;
1061
1062     /* Check valid address */
1063     if( i_method == 1 && !ismult( address_txtctrl->GetValue().mb_str()) )
1064     {
1065         wxMessageBox( wxU( INVALID_MCAST_ADDRESS ) , wxU( ERROR_MSG ),
1066                       wxICON_WARNING | wxOK, this->p_parent );
1067         event.Veto();
1068
1069     }
1070     else if( i_method == 0 && address_txtctrl->GetValue().IsEmpty() )
1071     {
1072         wxMessageBox( wxU( NO_ADDRESS ) , wxU( ERROR_MSG ),
1073                       wxICON_WARNING | wxOK, this->p_parent );
1074         event.Veto();
1075
1076     }
1077
1078     ((wizEncapPage *)GetNext())->SetPrev(this);
1079     for( i = 0 ; i< MUXERS_NUMBER ; i++ )
1080     {
1081         if( methods_array[i_method].muxers[i] != -1 )
1082         {
1083             ((wizEncapPage*)GetNext())->EnableEncap(
1084                                methods_array[i_method].muxers[i] );
1085         }
1086     }
1087     p_parent->SetStream( methods_array[i_method].psz_access ,
1088                          address_txtctrl->GetValue().mb_str() );
1089
1090     /* Set the action for the muxer page */
1091     ((wizEncapPage*)GetNext())->SetAction( p_parent->GetAction() );
1092     return;
1093 }
1094
1095 wxWizardPage *wizStreamingMethodPage::GetPrev() const { return p_prev; }
1096 wxWizardPage *wizStreamingMethodPage::GetNext() const { return p_next; }
1097
1098 void wizStreamingMethodPage::SetPrev( wxWizardPage *page) {p_prev = page; }
1099
1100
1101 void wizStreamingMethodPage::OnMethodChange( wxCommandEvent& event )
1102 {
1103     i_method = event.GetId() - MethodRadio0_Event;
1104     address_text->SetLabel( wxU(
1105      vlc_wraptext( _(methods_array[i_method].psz_address), TEXTWIDTH, false)));
1106     address_sizer->Layout();
1107     mainSizer->Layout();
1108 }
1109
1110 /***************************************************
1111  * Choose encapsulation format                     *
1112  ***************************************************/
1113 wizEncapPage::wizEncapPage( wxWizard *parent ) : wxWizardPage(parent)
1114 {
1115     int i;
1116     i_mux = 0;
1117     p_parent = (WizardDialog *)parent;
1118     p_streaming_page = NULL;
1119     p_transcode_page = NULL;
1120     p_prev = NULL;
1121     wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL);
1122
1123     /* Create the texts */
1124     pageHeader( this, mainSizer, ENCAP_TITLE, ENCAP_TEXT );
1125
1126     mainSizer->Add( 0,0,1 );
1127
1128     for( i = 0 ; i< MUXERS_NUMBER ; i++ )
1129     {
1130         encap_radios[i] = new wxRadioButton( this, EncapRadio0_Event + i,
1131                                wxU( encaps_array[i].psz_encap ) );
1132         encap_radios[i]->SetToolTip( wxU(_( encaps_array[i].psz_descr ) ) );
1133         mainSizer->Add( encap_radios[i], 0, wxLEFT, 5 );
1134         encap_radios[i]->Disable();
1135     }
1136
1137     mainSizer->Add( 0,0,1 );
1138
1139     SetSizer(mainSizer);
1140     mainSizer->Fit(this);
1141 }
1142
1143 wizEncapPage::~wizEncapPage()
1144 {
1145 }
1146
1147 void wizEncapPage::OnWizardPageChanging(wxWizardEvent& event)
1148 {
1149     int i;
1150     if( !event.GetDirection() )
1151     {
1152         for( i = 0 ; i< MUXERS_NUMBER ; i++ )
1153         {
1154             encap_radios[i]->Disable();
1155         }
1156     }
1157     p_parent->SetMux( encaps_array[i_mux].psz_mux );
1158
1159     if( p_parent->GetAction() == ACTION_STREAM )
1160     {
1161         if( strstr( p_parent->method, "udp" ))
1162         {
1163             ((wizStreamingExtraPage *)GetNext())->sap_checkbox->Enable();
1164             ((wizStreamingExtraPage *)GetNext())->sap_text->Enable(false);
1165         }
1166         else
1167         {
1168            ((wizStreamingExtraPage *)GetNext())->sap_checkbox->Enable( false );
1169            ((wizStreamingExtraPage *)GetNext())->sap_text->Enable( false );
1170         }
1171     }
1172
1173     return;
1174 }
1175
1176
1177 void wizEncapPage::OnEncapChange( wxCommandEvent& event )
1178 {
1179     i_mux = event.GetId() - EncapRadio0_Event;
1180 }
1181
1182 void wizEncapPage::EnableEncap( int encap )
1183 {
1184     int i;
1185     for( i = 0 ; i< MUXERS_NUMBER ; i++)
1186     {
1187         if( encaps_array[i].id == encap )
1188         {
1189             encap_radios[i]->Enable();
1190             encap_radios[i]->SetValue(true);
1191             i_mux = i;
1192         }
1193     }
1194 }
1195
1196 void wizEncapPage::SetStreamingPage( wxWizardPage *page)
1197 {
1198     p_streaming_page = page;
1199 }
1200
1201 void wizEncapPage::SetTranscodePage( wxWizardPage *page)
1202 {
1203     p_transcode_page = page;
1204 }
1205
1206 wxWizardPage *wizEncapPage::GetPrev() const { return p_prev; }
1207
1208 wxWizardPage *wizEncapPage::GetNext() const
1209 {
1210     if( i_action== ACTION_STREAM )
1211         return p_streaming_page;
1212     else
1213        return p_transcode_page;
1214 }
1215
1216 void wizEncapPage::SetAction( int i_act  ) { i_action = i_act; }
1217
1218 void wizEncapPage::SetPrev( wxWizardPage *page) { p_prev = page; }
1219
1220 /***************************************************
1221  * Extra transcoding page : Select file            *
1222  ***************************************************/
1223 wizTranscodeExtraPage::wizTranscodeExtraPage( wxWizard *parent,
1224                        wxWizardPage *prev,
1225                        wxWizardPage *next) : wxWizardPage(parent)
1226 {
1227     p_next = next;
1228     p_prev = prev;
1229     p_parent = (WizardDialog *) parent;
1230     wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL);
1231
1232     /* Create the texts */
1233     pageHeader( this, mainSizer, EXTRATRANSCODE_TITLE, EXTRATRANSCODE_TEXT );
1234
1235     mainSizer->Add( 0, 0, 1 );
1236
1237     wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 2, 1 );
1238     sizer->Add( new wxStaticText( this, -1,
1239                     wxU(_("Select the file to save to") ) ),
1240                     0, wxALL, 5 );
1241     sizer->Add( 0, 0, 1 );
1242
1243     file_text = new wxTextCtrl( this, -1, wxU(""), wxDefaultPosition,
1244                                 wxSize( 150, -1 ) );
1245
1246     sizer->Add( file_text, 0,  wxALL, 5 );
1247     sizer->Add( new wxButton( this, Open_Event, wxU("Choose") ) );
1248
1249     mainSizer->Add( sizer, 0, 0, 0) ;
1250
1251     mainSizer->Add( 0, 0, 1 );
1252     SetSizer(mainSizer);
1253     mainSizer->Fit(this);
1254 }
1255
1256 void wizTranscodeExtraPage::OnSelectFile( wxCommandEvent &event)
1257 {
1258     wxFileDialog *file_dialog =  new wxFileDialog( this, wxU(_("Open File")),
1259                    wxT(""), wxT(""), wxT("*"), wxSAVE );
1260
1261     if( file_dialog && file_dialog->ShowModal() == wxID_OK )
1262     {
1263         if( file_dialog->GetFilename().mb_str() )
1264         {
1265             file_text->SetValue( file_dialog->GetFilename() );
1266         }
1267     }
1268 }
1269
1270 void wizTranscodeExtraPage::OnWizardPageChanging( wxWizardEvent& event )
1271 {
1272     if( event.GetDirection() && file_text->GetValue().IsEmpty() )
1273     {
1274         wxMessageBox( wxU( CHOOSE_OUTFILE ), wxU( ERROR_MSG ),
1275                       wxICON_WARNING | wxOK, this->p_parent );
1276         event.Veto();
1277     }
1278     if( event.GetDirection() )
1279     {
1280        p_parent->SetTranscodeOut( file_text->GetValue().mb_str());
1281     }
1282 }
1283
1284 wxWizardPage *wizTranscodeExtraPage::GetPrev() const { return p_prev; }
1285 wxWizardPage *wizTranscodeExtraPage::GetNext() const {return p_next; }
1286
1287 /***********************************************************
1288  *  Extra streaming page
1289  ***********************************************************/
1290 wizStreamingExtraPage::wizStreamingExtraPage( wxWizard *parent,
1291                        wxWizardPage *prev,
1292                        wxWizardPage *next) : wxWizardPage(parent)
1293 {
1294     p_next = next;
1295     p_prev = prev;
1296     p_parent = (WizardDialog *) parent;
1297     wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL);
1298
1299     /* Create the texts */
1300     pageHeader( this, mainSizer, EXTRASTREAMING_TITLE, EXTRASTREAMING_TEXT );
1301
1302     mainSizer->Add( 0, 0, 1 );
1303
1304     wxFlexGridSizer *sizer = new wxFlexGridSizer( 2,2,1) ;
1305
1306     /* TTL */
1307     sizer->Add( new wxStaticText( this, -1, wxU(_("Time-To-Live (TTL)"))),
1308                     0, wxALL,  5 );
1309     ttl_spin = new wxSpinCtrl( this, -1, wxEmptyString, wxDefaultPosition, wxDefaultSize,
1310                     0, 1, 255, 1 );
1311     ttl_spin->SetToolTip(wxU(_(TTL) ) ) ;
1312     sizer->Add( ttl_spin, 0, wxALL , 5 );
1313
1314     /* SAP announce */
1315     sap_checkbox =  new wxCheckBox( this, SAP_Event, wxU(_("SAP Announce")) );
1316     sap_checkbox->SetToolTip( wxU(_( SAP ) ) );
1317     sizer->Add( sap_checkbox, 0, 0 , 0 );
1318     sap_text = new wxTextCtrl( this, -1, wxU(""), wxDefaultPosition,
1319                     wxSize(100,25) );
1320     sap_text->SetToolTip( wxU(_( SAP ) ) );
1321     sizer->Add( sap_text, 0, wxALL , 5 );
1322
1323     mainSizer->Add(sizer, 0, wxALL, 5 );
1324
1325     mainSizer->Add( 0, 0, 1 );
1326
1327     SetSizer(mainSizer);
1328     mainSizer->Fit(this);
1329 }
1330
1331 void wizStreamingExtraPage::OnSAP( wxCommandEvent &event )
1332 {
1333     sap_text->Enable( event.IsChecked() );
1334 }
1335
1336 void wizStreamingExtraPage::OnWizardPageChanging(wxWizardEvent& event)
1337 {
1338     if( sap_checkbox->IsChecked() )
1339     {
1340         if( sap_text->GetValue().IsEmpty() )
1341         {
1342             p_parent->SetSAP( true, NULL );
1343         }
1344         else
1345         {
1346             p_parent->SetSAP( true,
1347                              (const char *)sap_text->GetValue().mb_str() );
1348         }
1349     }
1350     else
1351     {
1352         p_parent->SetSAP( false, NULL );
1353     }
1354
1355     p_parent->SetTTL( ttl_spin->GetValue() );
1356 }
1357
1358 wxWizardPage *wizStreamingExtraPage::GetPrev() const { return p_prev; }
1359 wxWizardPage *wizStreamingExtraPage::GetNext() const {return p_next; }
1360
1361
1362 /***************************************************************************
1363  * Implementation of the wizard itself
1364  ***************************************************************************/
1365 wizHelloPage *page1;
1366 wizInputPage *page2 ;
1367 wizTranscodeCodecPage *tr_page1 ;
1368 wizStreamingMethodPage *st_page1;
1369 wizTranscodeExtraPage *tr_page2 ;
1370 wizStreamingExtraPage *st_page2;
1371 wizEncapPage *encap_page;
1372
1373 WizardDialog::WizardDialog(intf_thread_t *_p_intf, wxWindow *_p_parent,
1374                            char *psz_uri, int _i_from, int _i_to  ) :
1375 wxWizard( _p_parent, -1, wxU(_("Streaming/Transcoding Wizard")), wxNullBitmap, wxDefaultPosition)
1376 {
1377     /* Initializations */
1378     p_intf = _p_intf;
1379     SetPageSize(wxSize(400,420));
1380
1381     /* Initialize structure */
1382     i_action = 0;
1383     i_from = _i_from;
1384     i_to = _i_to;
1385     i_ttl = 1;
1386     vb = 0;
1387     ab = 0;
1388     acodec=NULL;
1389     vcodec=NULL;
1390
1391     page1 = new wizHelloPage(this);
1392     page2 = new wizInputPage(this, page1, p_intf);
1393
1394     if( psz_uri )
1395     {
1396         page2->SetUri( psz_uri );
1397     }
1398     if( i_from != 0 || i_to != 0 )
1399     {
1400         page2->SetPartial( i_from, i_to );
1401     }
1402
1403     encap_page = new wizEncapPage(this );
1404     tr_page1 = new wizTranscodeCodecPage(this, encap_page );
1405     st_page1 = new wizStreamingMethodPage(this, encap_page);
1406
1407     tr_page2 = new wizTranscodeExtraPage(this, encap_page, NULL );
1408     st_page2 = new wizStreamingExtraPage(this, encap_page, NULL );
1409
1410     /* Page 1 -> 2 */
1411     page1->SetNext( page2 );
1412     /* 2->1 in constructor of 2 */
1413
1414     /* Page 2 -> 3 */
1415     page2->SetTranscodePage(tr_page1);
1416     page2->SetStreamingPage(st_page1);
1417     page2->SetPintf( p_intf );
1418     tr_page1->SetPrev(page2);
1419     st_page1->SetPrev(page2);
1420
1421     /* Page 3 -> 4 */
1422     encap_page->SetTranscodePage( tr_page2 );
1423     encap_page->SetStreamingPage( st_page2 );
1424     /* 3->4 in constructor of 3 */
1425 //    encap_page->SetPrev(tr_page1);
1426 }
1427
1428 WizardDialog::~WizardDialog()
1429 {
1430     Destroy();
1431     delete page1;
1432     delete page2;
1433     delete tr_page1;
1434     delete st_page1 ;
1435     delete st_page2;
1436     delete tr_page2;
1437     delete encap_page;
1438 }
1439
1440 void WizardDialog::SetMrl( const char *mrl )
1441 {
1442     this->mrl = strdup( mrl );
1443 }
1444
1445 void WizardDialog::SetTTL( int i_ttl )
1446 {
1447     this->i_ttl = i_ttl;
1448 }
1449
1450 void WizardDialog::SetSAP( bool b_enabled, const char *psz_text )
1451 {
1452     this->b_sap = b_enabled;
1453     if( b_enabled )
1454     {
1455         if( psz_text != NULL )
1456         {
1457             this->psz_sap_name = strdup( psz_text );
1458         }
1459         else
1460         {
1461             this->psz_sap_name = NULL;
1462         }
1463     }
1464 }
1465
1466 void WizardDialog::SetPartial( int i_from, int i_to )
1467 {
1468     this->i_from = i_from;
1469     this->i_to = i_to;
1470 }
1471
1472 void WizardDialog::SetTranscode( char *vcodec, int vb, char *acodec,int ab)
1473 {
1474     if( strcmp( vcodec, "dummy") )
1475     {
1476         this->vcodec= strdup(vcodec);
1477     }
1478     if( strcmp( acodec, "dummy" ) )
1479     {
1480         this->acodec = strdup(acodec);
1481     }
1482     this->vb = vb;
1483     this->ab = ab;
1484 }
1485
1486 void WizardDialog::SetStream( char *method, char *address )
1487 {
1488     this->method = strdup( method );
1489     this->address = strdup( address );
1490 }
1491
1492 void WizardDialog::SetTranscodeOut( const char *address )
1493 {
1494     this->address = strdup( address );
1495 }
1496
1497 void WizardDialog::SetMux( char *mux )
1498 {
1499     this->mux = strdup( mux );
1500 }
1501
1502 void WizardDialog::SetAction( int i_action )
1503 {
1504     this->i_action = i_action;
1505 }
1506
1507 int WizardDialog::GetAction()
1508 {
1509     return i_action;
1510 }
1511
1512 void WizardDialog::Run()
1513 {
1514     if( RunWizard(page1) )
1515     {
1516         int i_size;
1517         char *psz_opt;
1518
1519         if( i_action == ACTION_TRANSCODE )
1520         {
1521             msg_Dbg( p_intf,"Starting transcode of %s to file %s",
1522                                   mrl, address);
1523             msg_Dbg( p_intf,"Using %s (%i kbps) / %s (%i kbps),encap %s",
1524                                 vcodec,vb,acodec,ab,mux);
1525             char *psz_transcode;
1526
1527             if( vcodec != NULL || acodec != NULL )
1528             {
1529                 int i_tr_size = 14;
1530                 if( vcodec != NULL )
1531                     i_tr_size += strlen( vcodec ) + 17;
1532                 if( acodec != NULL )
1533                     i_tr_size += strlen( acodec ) + 17;
1534
1535                 if( vb > 999999 )
1536                     vb = 999999;
1537                 else if( vb < 0 )
1538                     vb = 0;
1539
1540                 if( ab > 999999 )
1541                     ab = 999999;
1542                 else if( ab < 0 )
1543                     ab = 0;
1544
1545                 psz_transcode = (char *)malloc( i_tr_size * sizeof(char) );
1546
1547                 strcpy( psz_transcode, "transcode{" );
1548                 if( vcodec != NULL )
1549                 {
1550                     sprintf( psz_transcode + strlen( psz_transcode ),
1551                              "vcodec=%s,vb=%i%s", vcodec, vb,
1552                              ( acodec != NULL ) ? "," : "}:" );
1553                 }
1554                 if( acodec != NULL )
1555                 {
1556                     sprintf( psz_transcode + strlen( psz_transcode ),
1557                              "acodec=%s,ab=%i}:", acodec, ab );
1558                 }
1559             }
1560             else
1561                 psz_transcode = "";
1562
1563             i_size = 73 + strlen(mux) + strlen(address) + strlen(psz_transcode);
1564             psz_opt = (char *)malloc( i_size * sizeof(char) );
1565             snprintf( psz_opt, i_size, ":sout=#%sstandard{mux=%s,url=%s,"
1566                       "access=file}", psz_transcode, mux, address );
1567
1568             if( *psz_transcode )
1569                 free( psz_transcode );
1570         }
1571         else
1572         {
1573             msg_Dbg( p_intf, "Starting stream of %s to %s using %s, encap %s",
1574                                mrl, address, method, mux);
1575             if( b_sap )
1576             {
1577                 char *psz_sap_option = NULL;
1578                 if( psz_sap_name )
1579                 {
1580                     psz_sap_option = (char *) malloc( strlen( psz_sap_name )
1581                                                + 15 );
1582                     snprintf( psz_sap_option,strlen( psz_sap_name ) + 15,
1583                              "sap,name=\"%s\"",psz_sap_name );
1584                 }
1585                 else
1586                     psz_sap_option = strdup( "sap" );
1587
1588                 i_size = 40 + strlen(mux) + strlen(address) +
1589                               strlen( psz_sap_option);
1590                 psz_opt = (char *)malloc( i_size * sizeof(char) );
1591                 snprintf( psz_opt, i_size,
1592                           ":sout=#standard{mux=%s,url=%s,access=%s,%s}",
1593                           mux, address,method, psz_sap_option);
1594                 if( psz_sap_option ) free( psz_sap_option );
1595             }
1596             else
1597             {
1598                 i_size = 40 + strlen(mux) + strlen(address);
1599                 psz_opt = (char *)malloc( i_size * sizeof(char) );
1600                 snprintf( psz_opt, i_size,
1601                           ":sout=#standard{mux=%s,url=%s,access=%s}",
1602                           mux, address,method);
1603             }
1604         }
1605
1606         playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_intf,
1607                             VLC_OBJECT_PLAYLIST, FIND_ANYWHERE);
1608         if( p_playlist )
1609         {
1610             playlist_item_t *p_item = playlist_ItemNew( p_playlist, mrl,
1611                                                         ITEM_NAME );
1612             playlist_ItemAddOption( p_item, psz_opt);
1613             if( i_from != 0)
1614             {
1615                 char psz_from[20];
1616                 snprintf( psz_from, 20, "start-time=%i", i_from);
1617                 playlist_ItemAddOption( p_item, psz_from);
1618             }
1619             if( i_to != 0)
1620             {
1621                 char psz_to[20];
1622                 snprintf( psz_to, 20, "stop-time=%i", i_to);
1623                 playlist_ItemAddOption( p_item, psz_to);
1624             }
1625
1626             char psz_ttl[20];
1627             snprintf( psz_ttl, 20, "ttl=%i",i_ttl );
1628             playlist_ItemAddOption( p_item, psz_ttl );
1629
1630             playlist_AddItem( p_playlist, p_item, PLAYLIST_GO, PLAYLIST_END );
1631             vlc_object_release(p_playlist);
1632         }
1633         else
1634         {
1635             wxMessageBox( wxU( NO_PLAYLIST ), wxU( ERROR_MSG ),
1636                           wxICON_WARNING | wxOK, this );
1637         }
1638     }
1639 }
1640 /****************************************************************
1641  * Local helper functions
1642  ****************************************************************/
1643 static int ismult( const char *psz_uri )
1644 {
1645     char *psz_end;
1646     unsigned long i_value;
1647
1648     /* IPv6 */
1649     if( psz_uri[0] == '[')
1650             return strncasecmp( &psz_uri[1], "FF" , 2) ? VLC_FALSE : VLC_TRUE;
1651
1652     /* IPv4 */
1653     i_value = strtoul( psz_uri, &psz_end, 10 );
1654     if( *psz_end != '.' ) { return( VLC_FALSE ); }
1655
1656     return( ( i_value >= 224 && i_value < 240 ) ? VLC_TRUE : VLC_FALSE );
1657
1658 }