]> git.sesse.net Git - vlc/blob - modules/gui/wxwindows/wizard.cpp
* modules/control/telnet.c: removed translation of "VLM"
[vlc] / modules / gui / wxwindows / wizard.cpp
1 /*****************************************************************************
2  * wizard.cpp : wxWindows plugin for vlc
3  *****************************************************************************
4  * Copyright (C) 2000-2004 VideoLAN
5  * $Id: streamwizard.cpp 6961 2004-03-05 17:34:23Z sam $
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 <wx/statline.h>
38
39 class wizHelloPage;
40 class wizInputPage;
41
42 /*****************************************************************************
43  * Define events
44  *****************************************************************************/
45 enum
46 {
47     ActionRadio0_Event, ActionRadio1_Event,
48
49     Open_Event,
50     ListView_Event,
51     InputRadio0_Event, InputRadio1_Event,
52
53     MethodRadio0_Event, MethodRadio1_Event,
54     MethodRadio2_Event, MethodRadio3_Event,
55
56     EncapRadio0_Event, EncapRadio1_Event,
57     EncapRadio2_Event, EncapRadio3_Event,
58     EncapRadio4_Event, EncapRadio5_Event,
59     EncapRadio6_Event, EncapRadio7_Event,
60     EncapRadio8_Event, EncapRadio9_Event,
61
62     VideoEnable_Event, VideoCodec_Event,
63     AudioEnable_Event, AudioCodec_Event,
64
65 };
66
67 #define TEXTWIDTH 50
68 #define ACTION_STREAM 0
69 #define ACTION_TRANSCODE 1
70
71 #define MUX_PS          0
72 #define MUX_TS          1
73 #define MUX_MPEG        2
74 #define MUX_OGG         3
75 #define MUX_RAW         4
76 #define MUX_ASF         5
77 #define MUX_AVI         6
78 #define MUX_MP4         7
79 #define MUX_MOV         8
80
81 BEGIN_EVENT_TABLE(WizardDialog, wxWizard)
82 END_EVENT_TABLE()
83
84 /*****************************************************************************
85  * Wizard strings
86  *****************************************************************************/
87
88 #define ERROR _("Error")
89 #define ITEM_NAME _("Streaming/Transcoding Wizard")
90
91 /* Hello page */
92 #define HELLO_TITLE _("Streaming/Transcoding Wizard")
93 #define HELLO_TEXT _("Welcome, streaming wizard")
94 #define HELLO_STREAMING _("Stream")
95 #define HELLO_STREAMING_DESC _("Use this to stream on a network")
96 #define HELLO_TRANSCODE _("Transcode")
97 #define HELLO_TRANSCODE_DESC _("Use this to re-encode a stream and save it to a file")
98 #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")
99
100 /* Input page */
101 #define INPUT_TITLE _("Choose input")
102 #define INPUT_TEXT _("Choose here your input stream")
103
104 #define INPUT_OPEN _("Select a stream" )
105 #define INPUT_PL _( "Existing playlist item" )
106
107 #define CHOOSE_STREAM _("You must choose a stream")
108 #define NO_PLAYLIST _("Uh Oh! Unable to find playlist !")
109
110 #define INPUT_BUTTON _("Choose")
111
112 /* Transcode 1 */
113 #define TRANSCODE1_TITLE _("Transcode")
114 #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)")
115
116 #define TR_VIDEO_TEXT0 _("If your stream has video and you want to " \
117                          "transcode it, enable this")
118 #define TR_VIDEO_TEXT _("Select your video codec. Click one to get more " \
119                         "information")
120
121 #define TR_AUDIO_TEXT0 _("If your stream has audio and you want to "\
122                          "transcode it, enable this")
123 #define TR_AUDIO_TEXT _("Select your audio codec. Click one to get more " \
124                         "information")
125
126 /* Streaming 1 */
127 #define STREAMING1_TITLE _("Streaming")
128 #define STREAMING1_TEXT _("In this page, you will select how your input stream will be sent.")
129
130
131 #define INVALID_MCAST_ADDRESS _("This does not appear to be a valid " \
132                                 "multicast address" )
133
134 /* Encap  */
135 #define ENCAP_TITLE _("Encapsulation format")
136 #define ENCAP_TEXT _("In this page, you will select how the stream will be "\
137                      "encapsulated." )
138
139
140 /* Transcode 2 */
141 #define EXTRATRANSCODE_TITLE _("Additional transcode options")
142 #define EXTRATRANSCODE_TEXT _("In this page, you will define a few " \
143                               "additionnal parameters for your transcoding" )
144
145 /* Streaming 2 */
146 #define EXTRASTREAMING_TITLE _("Additional streaming options")
147 #define EXTRASTREAMING_TEXT _("In this page, you will define a few " \
148                               "additionnal parameters for your stream" )
149
150
151 /*****************************************************************************
152  * Helper structures
153  *****************************************************************************/
154 struct codec {
155     char *psz_display;
156     char *psz_codec;
157     char *psz_descr;
158     int muxers[9];
159 };
160
161 struct codec vcodecs_array[] =
162 {
163     { "MPEG-1 Video" , "mp1v" , "MPEG-1 Video codec",
164        {MUX_PS, MUX_TS, MUX_MPEG, MUX_OGG, MUX_AVI, MUX_RAW, -1,-1,-1 } },
165     { "MPEG-2 Video" , "mp2v" , "MPEG-2 Video codec",
166        {MUX_PS, MUX_TS, MUX_MPEG, MUX_OGG, MUX_AVI, MUX_RAW, -1,-1,-1 } },
167     { "MPEG-4 Video" , "mp4v" , "MPEG-4 Video codec",
168        {MUX_PS,MUX_TS,MUX_MPEG,MUX_ASF,MUX_MP4,MUX_OGG,MUX_AVI,MUX_RAW, -1} },
169     { "DIVX 1" ,"DIV1","Divx first version" ,
170        {MUX_TS , MUX_MPEG , MUX_ASF , MUX_OGG , MUX_AVI , -1,-1,-1,-1 } },
171     { "DIVX 2" ,"DIV2","Divx second version" ,
172        {MUX_TS , MUX_MPEG , MUX_ASF , MUX_OGG , MUX_AVI , -1,-1,-1,-1 } },
173     { "DIVX 3" ,"DIV3","Divx third version" ,
174        {MUX_TS , MUX_MPEG , MUX_ASF , MUX_OGG , MUX_AVI , -1,-1,-1,-1 } },
175     { "H 263" , "H263" , "H263 is ..." ,
176        { MUX_TS, MUX_AVI, -1,-1,-1,-1,-1,-1,-1 } },
177     { "I 263", "I263", "I263 is ..." ,
178        { MUX_TS, MUX_AVI, -1,-1,-1,-1,-1,-1,-1 } },
179     { "WMV 1" , "WMV1", "First version of WMV" ,
180        {MUX_TS , MUX_MPEG , MUX_ASF , MUX_OGG , MUX_AVI , -1,-1,-1,-1 } },
181     { "WMV 2" , "WMV2", "2 version of WMV" ,
182        {MUX_TS , MUX_MPEG , MUX_ASF , MUX_OGG , MUX_AVI , -1,-1,-1,-1 } },
183     { "MJPEG" , "MJPG", "MJPEG consists of a series of JPEG pictures" ,
184        {MUX_TS , MUX_MPEG , MUX_ASF , MUX_OGG , MUX_AVI , -1,-1,-1,-1 } },
185     { "Theora" , "theo", "Experimental free codec",
186        {MUX_TS, -1,-1,-1,-1,-1,-1,-1,-1} },
187     { "Dummy", "dummy", "Dummy codec (do not transcode)" ,
188       {MUX_PS,MUX_TS,MUX_MPEG,MUX_ASF,MUX_MP4,MUX_OGG,MUX_AVI,MUX_RAW,MUX_MOV}},
189     { NULL,NULL,NULL , {-1,-1,-1,-1,-1,-1,-1,-1,-1}} /* Do not remove me */
190 };
191
192 struct codec acodecs_array[] =
193 {
194     { "MPEG Audio" , "mpga" , "The standard MPEG audio (1/2) format" ,
195        {MUX_PS,MUX_TS,MUX_MPEG,MUX_ASF,MUX_OGG,MUX_AVI,MUX_RAW, -1,-1} },
196     { "MP3" , "mp3" , "MPEG Audio Layer 3" ,
197        {MUX_PS,MUX_TS,MUX_MPEG,MUX_ASF,MUX_OGG,MUX_AVI,MUX_RAW, -1,-1} },
198     { "MPEG 4 Audio" , "mp4a" , "Audio format for MPEG4" ,
199        {MUX_TS, MUX_MP4, -1,-1,-1,-1,-1,-1,-1 } },
200     { "A/52" , "a52" , "DVD audio format" ,
201        {MUX_PS,MUX_TS,MUX_MPEG,MUX_ASF,MUX_OGG,MUX_AVI,MUX_RAW, -1,-1} },
202     { "Vorbis" , "vorb" , "This is a free audio codec" ,
203        {MUX_OGG, -1,-1,-1,-1,-1,-1,-1,-1} },
204     { "FLAC" , "flac" , "This is an audio codec" ,
205        {MUX_OGG , MUX_RAW, -1,-1,-1,-1,-1,-1,-1} },
206     { "Speex" , "spx" , "An audio codec dedicated to compression of voice" ,
207        {MUX_OGG, -1,-1,-1,-1,-1,-1,-1,-1} },
208     { "Dummy", "dummy", "Dummy codec (do not transcode)" ,
209      {MUX_PS,MUX_TS,MUX_MPEG,MUX_ASF,MUX_MP4,MUX_OGG,MUX_AVI,MUX_RAW,MUX_MOV}},
210     { NULL,NULL,NULL , {-1,-1,-1,-1,-1,-1,-1,-1,-1}} /* Do not remove me */
211 };
212
213 struct method {
214     char *psz_access;
215     char *psz_method;
216     char *psz_descr;
217     char *psz_address;
218     int   muxers[9];
219 };
220
221 struct method methods_array[] =
222 {
223     {"udp:","UDP Unicast", "Use this to stream to a single computer",
224      "Enter the address of the computer to stream to",
225      { MUX_TS, -1,-1,-1,-1,-1,-1,-1,-1 } },
226     {"udp:","UDP Multicast",
227      "Use this to stream to a dynamic group of computers on a "
228      "multicast-enabled network. This is the most efficient method "
229      "to stream to several computers, but it does not work over Internet.",
230      "Enter the multicast address to stream to in this field. "
231      "This must be an IP address between 224.0.0.0 an 239.255.255.255 "
232      "For a private use, enter an address beginning with 239.255.",
233      { MUX_TS, -1,-1,-1,-1,-1,-1,-1,-1 } },
234     {"http://","HTTP",
235             "Use this to stream to several computers. This method is "
236      "less efficient, as the server needs to send several times the "
237      "stream.",
238      "Enter the local addresses you want to listen to. Do not enter "
239      "anything to listen to all adresses. This is generally the best "
240      "thing to do.",
241      { MUX_TS, MUX_PS, MUX_MPEG, MUX_OGG, MUX_RAW, MUX_ASF, -1,-1,-1} },
242     { NULL, NULL,NULL,NULL , {-1,-1,-1,-1,-1,-1,-1,-1,-1}} /* Do not remove me */
243 };
244
245 struct encap {
246     int   id;
247     char *psz_mux;
248     char *psz_encap;
249     char *psz_descr;
250 };
251
252 struct encap encaps_array[] =
253 {
254     { MUX_PS, "ps","MPEG PS", "MPEG Program Stream" },
255     { MUX_TS, "ts","MPEG TS", "MPEG Transport Stream" },
256     { MUX_MPEG, "ps", "MPEG 1", "MPEG 1 Format" },
257     { MUX_OGG, "ogg," "OGG", "OGG" },
258     { MUX_RAW, "raw", "RAW", "RAW" },
259     { MUX_ASF, "asf","ASF", "ASF" },
260     { MUX_AVI, "avi","AVI", "AVI" },
261     { MUX_MP4, "mp4","MP4", "MPEG4" },
262     { MUX_MOV, "mov","MOV", "MOV" },
263     { -1 , NULL,NULL , NULL } /* Do not remove me */
264 };
265
266 /*****************************************************************************
267  * All the pages of the wizard, declaration
268  *****************************************************************************/
269
270 #if 0
271 /* The open dialog */
272 class WizardOpen : public wxNotebook
273 {
274     public:
275     protected:
276         wxPanel *p_parent;
277         wxPanel *FilePanel();
278         wxPanel *DiscPanel();
279         wxPanel *NetPanel();
280         wxPanel *V4LPanel();
281         ArrayOfAutoBuiltPanel input_tab_array;
282
283         /* Controls for the file panel */
284         wxComboBox *file_combo;
285         wxFileDialog *file_dialog;
286
287         /* Controls for the disc panel */
288         wxRadioBox *disc_type;
289         wxTextCtrl *disc_device;
290         wxSpinCtrl *disc_title;
291         wxSpinCtrl *disc_chapter;
292
293
294         /* The media equivalent name for a DVD names. For example,
295          *  "Title", is "Track" for a CD-DA */
296         wxStaticText *disc_title_label;
297         wxStaticText *disc_chapter_label;
298         /* Indicates if the disc device control was modified */
299         bool b_disc_device_changed;
300
301
302         /* Controls for the net panel */
303         wxRadioBox *net_type;
304         int i_net_type;
305         wxPanel *net_subpanels[4];
306         wxRadioButton *net_radios[4];
307         wxSpinCtrl *net_ports[4];
308         int        i_net_ports[4];
309         wxTextCtrl *net_addrs[4];
310         wxCheckBox *net_ipv6;
311
312         /* Controls for the v4l panel */
313         wxRadioBox *video_type;
314         wxTextCtrl *video_device;
315         wxSpinCtrl *video_channel;
316         wxButton *v4l_button;
317         V4LDialog *v4l_dialog;
318         wxArrayString v4l_mrl;
319 }
320 #endif
321
322 /* Declare classes */
323 class wizHelloPage : public wxWizardPageSimple
324 {
325     public:
326         wizHelloPage( wxWizard *parent);
327         void OnActionChange(wxEvent& event);
328         void OnWizardPageChanging(wxWizardEvent& event);
329     protected:
330         int i_action;
331         WizardDialog *p_parent;
332         wxRadioButton *action_radios[2];
333         DECLARE_EVENT_TABLE()
334 };
335
336 BEGIN_EVENT_TABLE(wizHelloPage, wxWizardPageSimple)
337     EVT_RADIOBUTTON( ActionRadio0_Event, wizHelloPage::OnActionChange)
338     EVT_RADIOBUTTON( ActionRadio1_Event, wizHelloPage::OnActionChange)
339     EVT_WIZARD_PAGE_CHANGING(-1, wizHelloPage::OnWizardPageChanging)
340 END_EVENT_TABLE()
341
342
343 class wizInputPage : public wxWizardPage
344 {
345     public:
346         wizInputPage( wxWizard *, wxWizardPage *, intf_thread_t *);
347         wizInputPage::~wizInputPage();
348         void OnWizardPageChanging(wxWizardEvent& event);
349         void OnInputChange(wxEvent& event);
350         virtual wxWizardPage *GetPrev() const;
351         virtual wxWizardPage *GetNext() const;
352         void SetStreamingPage( wxWizardPage *page);
353         void SetTranscodePage( wxWizardPage *page);
354         void SetAction( int i_action );
355         void SetPintf( intf_thread_t *p_intf );
356     protected:
357         bool b_chosen;
358         intf_thread_t *p_intf;
359         int i_action;
360         int i_input;
361
362         WizardDialog *p_parent;
363         wxRadioButton *input_radios[2];
364         wxBoxSizer *mainSizer;
365         wxArrayString mrl;
366         wxTextCtrl *mrl_text;
367         OpenDialog *p_open_dialog;
368         wxListView *listview;
369         wxPanel *open_panel;
370         wxPanel *pl_panel;
371         wxWizardPage *p_prev;
372         wxWizardPage *p_streaming_page;
373         wxWizardPage *p_transcode_page;
374         DECLARE_EVENT_TABLE()
375 };
376
377 BEGIN_EVENT_TABLE(wizInputPage, wxWizardPageSimple)
378     EVT_RADIOBUTTON( InputRadio0_Event, wizInputPage::OnInputChange)
379     EVT_RADIOBUTTON( InputRadio1_Event, wizInputPage::OnInputChange)
380     EVT_WIZARD_PAGE_CHANGING(-1, wizInputPage::OnWizardPageChanging)
381 END_EVENT_TABLE()
382
383
384 class wizTranscodeCodecPage : public wxWizardPage
385 {
386 public:
387     wizTranscodeCodecPage( wxWizard *parent, wxWizardPage *next);
388     ~wizTranscodeCodecPage();
389     void wizTranscodeCodecPage::OnWizardPageChanging(wxWizardEvent& event);
390     virtual wxWizardPage *GetPrev() const;
391     virtual wxWizardPage *GetNext() const;
392     void SetPrev( wxWizardPage *page);
393 protected:
394     wxCheckBox *video_checkbox;
395     wxComboBox *video_combo;
396     wxStaticText * video_text;
397     wxCheckBox *audio_checkbox;
398     wxComboBox *audio_combo;
399     wxStaticText * audio_text;
400
401     WizardDialog *p_parent;
402     int i_audio_codec;
403     int i_video_codec;
404
405     char *vcodec;
406     char *acodec;
407
408     wxWizardPage *p_prev;
409     wxWizardPage *p_next;
410
411     void OnVideoCodecChange(wxCommandEvent& event);
412     void OnAudioCodecChange(wxCommandEvent& event);
413     void OnEnableVideo(wxCommandEvent& event);
414     void OnEnableAudio(wxCommandEvent& event);
415
416     DECLARE_EVENT_TABLE()
417 };
418
419 BEGIN_EVENT_TABLE(wizTranscodeCodecPage, wxWizardPageSimple)
420    EVT_CHECKBOX( VideoEnable_Event, wizTranscodeCodecPage::OnEnableVideo)
421    EVT_CHECKBOX( AudioEnable_Event, wizTranscodeCodecPage::OnEnableAudio)
422    EVT_COMBOBOX( VideoCodec_Event, wizTranscodeCodecPage::OnVideoCodecChange)
423    EVT_COMBOBOX( AudioCodec_Event, wizTranscodeCodecPage::OnAudioCodecChange)
424    EVT_WIZARD_PAGE_CHANGING(-1, wizTranscodeCodecPage::OnWizardPageChanging)
425 END_EVENT_TABLE()
426
427 class wizStreamingMethodPage : public wxWizardPage
428 {
429 public:
430     wizStreamingMethodPage( wxWizard *parent, wxWizardPage *next);
431     void OnWizardPageChanging(wxWizardEvent& event);
432     virtual wxWizardPage *GetPrev() const;
433     virtual wxWizardPage *GetNext() const;
434     void SetPrev( wxWizardPage *page);
435 protected:
436     DECLARE_EVENT_TABLE()
437     int i_method;
438     wxStaticText *address_text;
439     wxTextCtrl *address_txtctrl;
440     WizardDialog * p_parent;
441     void OnMethodChange(wxEvent& event);
442     wxRadioButton *method_radios[4];
443     wxWizardPage *p_prev;
444     wxWizardPage *p_next;
445 };
446
447 BEGIN_EVENT_TABLE(wizStreamingMethodPage, wxWizardPageSimple)
448     EVT_RADIOBUTTON( MethodRadio0_Event, wizStreamingMethodPage::OnMethodChange)
449     EVT_RADIOBUTTON( MethodRadio1_Event, wizStreamingMethodPage::OnMethodChange)
450     EVT_RADIOBUTTON( MethodRadio2_Event, wizStreamingMethodPage::OnMethodChange)
451     EVT_RADIOBUTTON( MethodRadio3_Event, wizStreamingMethodPage::OnMethodChange)
452     EVT_WIZARD_PAGE_CHANGING(-1, wizStreamingMethodPage::OnWizardPageChanging)
453 END_EVENT_TABLE()
454
455
456 class wizEncapPage : public wxWizardPage
457 {
458 public:
459     wizEncapPage( wxWizard *parent);
460     wizEncapPage::~wizEncapPage();
461     void OnWizardPageChanging(wxWizardEvent& event);
462     virtual wxWizardPage *GetPrev() const;
463     virtual wxWizardPage *GetNext() const;
464     void SetStreamingPage( wxWizardPage *page);
465     void SetTranscodePage( wxWizardPage *page);
466     void SetPrev( wxWizardPage *page);
467     void SetAction( int );
468     void EnableEncap( int encap );
469 protected:
470     DECLARE_EVENT_TABLE()
471     int i_encap;
472     int i_mux;
473     int i_action;
474     void OnEncapChange(wxEvent& event);
475     wxRadioButton *encap_radios[9];
476     WizardDialog *p_parent;
477     wxWizardPage *p_prev;
478     wxWizardPage *p_streaming_page;
479     wxWizardPage *p_transcode_page;
480 };
481
482 BEGIN_EVENT_TABLE(wizEncapPage, wxWizardPageSimple)
483     EVT_WIZARD_PAGE_CHANGING(-1, wizEncapPage::OnWizardPageChanging)
484     EVT_RADIOBUTTON( EncapRadio0_Event, wizEncapPage::OnEncapChange)
485     EVT_RADIOBUTTON( EncapRadio1_Event, wizEncapPage::OnEncapChange)
486     EVT_RADIOBUTTON( EncapRadio2_Event, wizEncapPage::OnEncapChange)
487     EVT_RADIOBUTTON( EncapRadio3_Event, wizEncapPage::OnEncapChange)
488     EVT_RADIOBUTTON( EncapRadio4_Event, wizEncapPage::OnEncapChange)
489     EVT_RADIOBUTTON( EncapRadio5_Event, wizEncapPage::OnEncapChange)
490     EVT_RADIOBUTTON( EncapRadio6_Event, wizEncapPage::OnEncapChange)
491     EVT_RADIOBUTTON( EncapRadio7_Event, wizEncapPage::OnEncapChange)
492     EVT_RADIOBUTTON( EncapRadio8_Event, wizEncapPage::OnEncapChange)
493     EVT_RADIOBUTTON( EncapRadio9_Event, wizEncapPage::OnEncapChange)
494 END_EVENT_TABLE()
495
496 /* Additional settings for transcode */
497 class wizTranscodeExtraPage : public wxWizardPage
498 {
499 public:
500     wizTranscodeExtraPage( wxWizard *parent, wxWizardPage *prev,
501                             wxWizardPage *next);
502     virtual wxWizardPage *GetPrev() const;
503     virtual wxWizardPage *GetNext() const;
504 protected:
505     DECLARE_EVENT_TABLE()
506     void wizTranscodeExtraPage::OnSelectFile(wxCommandEvent&);
507     WizardDialog *p_parent;
508     wxWizardPage *p_prev;
509     wxWizardPage *p_next;
510 };
511
512 BEGIN_EVENT_TABLE(wizTranscodeExtraPage, wxWizardPage)
513     EVT_BUTTON( Open_Event, wizTranscodeExtraPage::OnSelectFile)
514 END_EVENT_TABLE()
515
516 /* Additional settings for streaming */
517 class wizStreamingExtraPage : public wxWizardPage
518 {
519 public:
520     wizStreamingExtraPage( wxWizard *parent, wxWizardPage *prev,
521                             wxWizardPage *next);
522     virtual wxWizardPage *GetPrev() const;
523     virtual wxWizardPage *GetNext() const;
524 protected:
525     DECLARE_EVENT_TABLE()
526     WizardDialog *p_parent;
527     wxWizardPage *p_prev;
528     wxWizardPage *p_next;
529 };
530
531 BEGIN_EVENT_TABLE(wizStreamingExtraPage, wxWizardPage)
532 END_EVENT_TABLE()
533
534
535 /* Local functions */
536 static int ismult( char *psz_uri );
537
538 /***************************************************************************
539  * Implementation of the pages
540  ***************************************************************************/
541
542
543 /***************************************************
544  * First page: choose between stream and transcode *
545  ***************************************************/
546 wizHelloPage::wizHelloPage( wxWizard *parent) : wxWizardPageSimple(parent)
547 {
548         i_action = 0;
549         p_parent = (WizardDialog *)parent;
550         wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL);
551
552         /* Create the texts */
553         mainSizer->Add( new wxStaticText(this, -1, wxU( HELLO_TITLE ) ),
554                         0, wxALL, 5 );
555         mainSizer->Add( new wxStaticText(this, -1,
556                         wxU( vlc_wraptext(HELLO_TEXT , TEXTWIDTH, false ) ) ),
557                         0, wxALL, 5 );
558
559         /* Create the radio buttons with their helps */
560         action_radios[0] = new wxRadioButton( this, ActionRadio0_Event,
561                                               wxU( HELLO_STREAMING ) );
562         action_radios[1] = new wxRadioButton( this, ActionRadio1_Event,
563                                               wxU( HELLO_TRANSCODE ) );
564         i_action = 0;
565
566         mainSizer->Add( action_radios[0], 0, wxALL, 5 );
567         mainSizer->Add( new wxStaticText(this, -1,
568                  wxU( vlc_wraptext( HELLO_STREAMING_DESC ,TEXTWIDTH, false))),
569                         0, wxBOTTOM, 5 );
570
571         mainSizer->Add( action_radios[1], 0, wxALL, 5 );
572         mainSizer->Add( new wxStaticText(this, -1,
573                  wxU( vlc_wraptext( HELLO_TRANSCODE_DESC ,TEXTWIDTH, false)))
574                         , 0, wxBOTTOM, 5 );
575
576         mainSizer->Add( new wxStaticLine(this, -1 ), 1, wxTOP|wxBOTTOM, 5 );
577
578         mainSizer->Add( new wxStaticText(this, -1,
579                         wxU( vlc_wraptext(HELLO_NOTICE , TEXTWIDTH , false ))),
580                         0, wxALL, 5 );
581
582         SetSizer(mainSizer);
583         mainSizer->Fit(this);
584     }
585
586 void wizHelloPage::OnActionChange(wxEvent& event)
587 {
588     i_action = event.GetId() - ActionRadio0_Event;
589     ((wizInputPage *)GetNext())->SetAction( i_action );
590     p_parent->SetAction( i_action );
591 }
592
593 void wizHelloPage::OnWizardPageChanging(wxWizardEvent& event)
594 {
595     ((wizInputPage *)GetNext())->SetAction( i_action );
596     p_parent->SetAction( i_action );
597 }
598
599 /************************************
600  * Second page: choose input stream *
601  ************************************/
602 wizInputPage::wizInputPage( wxWizard *parent, wxWizardPage *prev, intf_thread_t *_p_intf) :
603               wxWizardPage(parent)
604 {
605     p_prev = prev;
606     p_intf = _p_intf;
607     p_parent = (WizardDialog *)parent;
608     parent->SetModal(false);
609     b_chosen = false;
610     mainSizer = new wxBoxSizer(wxVERTICAL);
611
612     /* Create the texts */
613     mainSizer->Add( new wxStaticText(this, -1, wxU( INPUT_TITLE ) ),
614                     0, wxALL, 5 );
615     mainSizer->Add( new wxStaticText(this, -1,
616                     wxU( vlc_wraptext(INPUT_TEXT , TEXTWIDTH, false ) ) ),
617                     0, wxALL, 5 );
618
619     /* Create the radio buttons */
620     input_radios[0] = new wxRadioButton( this, InputRadio0_Event ,
621                                wxU( INPUT_OPEN ) );
622     mainSizer->Add( input_radios[0], 0, wxALL, 5 );
623     input_radios[1] = new wxRadioButton( this, InputRadio1_Event ,
624                                wxU( INPUT_PL ) );
625     i_input = 0;
626     mainSizer->Add( input_radios[1], 0, wxALL, 5 );
627
628     /* Open Panel */
629     open_panel = new wxPanel(this, -1);
630     open_panel->SetAutoLayout( TRUE );
631     wxBoxSizer *openSizer = new wxBoxSizer(wxVERTICAL);
632
633     mrl_text = new wxTextCtrl( open_panel, -1, wxU( "" ) );
634     openSizer->Add( mrl_text, 0 , wxALL, 5 );
635     open_panel->SetSizer( openSizer );
636     openSizer->Layout();
637     openSizer->Fit(open_panel);
638
639     mainSizer->Add( open_panel );
640
641     playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_intf,
642                                        VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
643
644     if( p_playlist )
645     {
646         if( p_playlist->i_size > 0)
647         {
648             pl_panel = new wxPanel(this, -1);
649             wxBoxSizer *plSizer = new wxBoxSizer( wxVERTICAL );
650             listview = new wxListView( pl_panel, ListView_Event,
651                                        wxDefaultPosition, wxDefaultSize,
652                                        wxLC_REPORT | wxSUNKEN_BORDER );
653             listview->InsertColumn( 0, wxU(_("Name")) );
654             listview->InsertColumn( 1, wxU(_("URI")) );
655             listview->SetColumnWidth( 0, 300 );
656             for( int i=0 ; i < p_playlist->i_size ; i++ )
657             {
658                 wxString filename = wxL2U( p_playlist->pp_items[i]->input.
659                                                                     psz_name );
660                 listview->InsertItem( i, filename );
661                 listview->SetItem( i, 1, wxL2U( p_playlist->pp_items[i]->
662                                                             input.psz_uri) );
663             }
664             listview->Select( p_playlist->i_index , TRUE);
665             plSizer->Add( listview, 0, wxALL, 5 );
666             pl_panel->SetSizer( plSizer );
667             plSizer->Layout();
668             mainSizer->Add( pl_panel );
669             pl_panel->Hide();
670         }
671         else
672         {
673             input_radios[1]->Disable();
674         }
675         vlc_object_release( p_playlist );
676     }
677     else
678     {
679         input_radios[1]->Disable();
680     }
681
682     SetSizer(mainSizer);
683     mainSizer->Fit(this);
684 }
685
686 wizInputPage::~wizInputPage()
687 {
688     if( p_open_dialog ) delete p_open_dialog;
689 }
690
691 void wizInputPage::OnInputChange(wxEvent& event)
692 {
693     i_input = event.GetId() - InputRadio0_Event;
694     if( i_input == 0 )
695     {
696         if( pl_panel )
697         {
698             pl_panel->Hide();
699             mainSizer->Hide( pl_panel );
700             open_panel->Show();
701             mainSizer->Show( open_panel );
702         }
703     }
704     else
705     {
706         open_panel->Hide();
707         mainSizer->Hide( open_panel );
708         pl_panel->Show();
709         mainSizer->Show( pl_panel );
710     }
711 }
712
713 void wizInputPage::OnWizardPageChanging(wxWizardEvent& event)
714 {
715     if( i_input == 0)
716     {
717         if( mrl_text->GetValue().IsSameAs( wxT(""), TRUE ) && event.GetDirection() )
718         {
719             wxMessageBox( wxU( CHOOSE_STREAM ), wxU( ERROR ),
720                           wxICON_WARNING | wxOK, this );
721             event.Veto();
722         }
723         else
724         {
725             p_parent->SetMrl( (const char *)mrl_text->GetValue().c_str() );
726         }
727     }
728     else
729     {
730         int i = -1;
731         wxListItem listitem;
732         i = listview->GetNextItem( i , wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
733         if( i != -1 )
734         {
735             listitem.SetId( i );
736             listitem.SetColumn( 1 );
737             listview->GetItem( listitem );
738             p_parent->SetMrl( (const char*) listitem.GetText().c_str() );
739         }
740     }
741     return;
742 }
743
744 wxWizardPage *wizInputPage::GetPrev() const { return p_prev; }
745 wxWizardPage *wizInputPage::GetNext() const
746 {
747     if( i_action == ACTION_STREAM )
748         return p_streaming_page;
749     else
750        return p_transcode_page;
751 }
752
753 void wizInputPage::SetStreamingPage( wxWizardPage *page)
754 {
755     p_streaming_page = page;
756 }
757
758 void wizInputPage::SetTranscodePage( wxWizardPage *page)
759 {
760     p_transcode_page = page;
761 }
762
763 void wizInputPage::SetAction( int i_action )
764 {
765     this->i_action = i_action;
766 }
767
768 void wizInputPage::SetPintf( intf_thread_t *p_intf )
769 {
770     this->p_intf = p_intf;
771 }
772
773 /***************************************************
774  * First transcode page: choose codecs             *
775  ***************************************************/
776 wizTranscodeCodecPage::wizTranscodeCodecPage( wxWizard *parent,
777                        wxWizardPage *next) : wxWizardPage(parent)
778 {
779     p_next = next;
780
781     acodec = NULL;
782     vcodec = NULL;
783     p_parent = (WizardDialog *) parent;
784
785     wxBoxSizer *main_sizer = new wxBoxSizer(wxVERTICAL);
786
787     /* Add the main texts */
788     main_sizer->Add( new wxStaticText(this, -1,
789                 wxU( vlc_wraptext( TRANSCODE1_TITLE ,TEXTWIDTH, false ) ) ),
790                     0, wxALL, 5 );
791     main_sizer->Add( new wxStaticText(this, -1,
792                 wxU( vlc_wraptext(TRANSCODE1_TEXT , TEXTWIDTH, false ) ) ),
793                     0, wxALL, 5 );
794
795     /* Video Box */
796     wxStaticBox *video_box = new wxStaticBox( this, -1, wxU(_("Video")) );
797     wxStaticBoxSizer *video_sizer = new wxStaticBoxSizer( video_box,
798                                                           wxVERTICAL );
799     /* Line 1 : only the checkbox */
800     wxFlexGridSizer *video_sizer1 = new wxFlexGridSizer( 1,1,20 );
801     video_sizer1->Add( new wxCheckBox( this, VideoEnable_Event,
802                             wxU(_("Transcode video") ) ), 0 , wxLEFT , 5 );
803     /* Line 2 : codec */
804     wxFlexGridSizer *video_sizer2 = new wxFlexGridSizer( 2,1,20 );
805     video_sizer2->Add( new wxStaticText(this, -1, wxU(_("Codec"))),0,wxLEFT ,5);
806     video_combo = new wxComboBox( this, VideoCodec_Event, wxT(""),
807                                   wxDefaultPosition, wxSize(200,25) );
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     video_sizer2->Add( video_combo, 0 , wxALIGN_RIGHT);
814     /* Line 3 : text */
815     video_text = new wxStaticText( this, -1,
816                      wxU( vlc_wraptext( TR_AUDIO_TEXT, TEXTWIDTH, false) ) );
817     wxFlexGridSizer *video_sizer3 = new wxFlexGridSizer( 2,1,20 );
818     video_sizer3->Add( video_text, 0, wxLEFT, 5 );
819     /* Fill the main video sizer */
820     video_sizer->Add( video_sizer1 , 0, wxEXPAND, 5 );
821     video_sizer->Add( video_sizer2, 0, wxALL, 5 );
822     video_sizer->Add( video_sizer3, 0, wxEXPAND );
823
824     /* Audio box */
825     wxStaticBox *audio_box = new wxStaticBox( this, -1, wxU(_("Audio")) );
826     wxStaticBoxSizer *audio_sizer = new wxStaticBoxSizer( audio_box,
827                                                           wxVERTICAL );
828     /* Line1: enabler */
829     wxFlexGridSizer *audio_sizer1 = new wxFlexGridSizer( 1,1,20);
830     audio_sizer1->Add( new wxCheckBox( this, AudioEnable_Event,
831                             wxU(_("Transcode audio") ) ), 0 , wxLEFT, 5 );
832     /* Line 2 : codec */
833     wxFlexGridSizer *audio_sizer2 = new wxFlexGridSizer( 2,1,20 );
834     audio_sizer2->Add( new wxStaticText(this, -1, wxU(_("Codec"))),0,wxLEFT,5);
835     audio_combo = new wxComboBox( this, AudioCodec_Event, wxT(""),
836                                   wxDefaultPosition, wxSize(200,25) );
837     for( int i= 0; acodecs_array[i].psz_display != NULL; i++ )
838     {
839         audio_combo->Append( wxU( acodecs_array[i].psz_display ) ,
840                             (void *)&acodecs_array[i] );
841     }
842     audio_sizer2->Add( audio_combo, 0 , wxALIGN_RIGHT );
843     /* Line 3 : text */
844     audio_text = new wxStaticText( this, -1,
845                      wxU( vlc_wraptext( TR_VIDEO_TEXT, TEXTWIDTH, false) ) );
846     wxFlexGridSizer *audio_sizer3 = new wxFlexGridSizer( 2,1,20 );
847     audio_sizer3->Add( audio_text, 0, wxLEFT,5 );
848
849     audio_sizer->Add(audio_sizer1, 0, wxEXPAND, 5);
850     audio_sizer->Add(audio_sizer2, 0, wxALL, 5 );
851     audio_sizer->Add(audio_sizer3, 0, wxEXPAND );
852
853     main_sizer->Add( video_sizer, 1, wxGROW, 0 );
854     main_sizer->Add( audio_sizer, 1, wxGROW, 0 );
855     main_sizer->Layout();
856     SetSizerAndFit( main_sizer );
857
858     /* Default disabled */
859     video_combo->Disable(); video_text->Disable();
860     audio_combo->Disable(); audio_text->Disable();
861
862 }
863
864 wizTranscodeCodecPage::~wizTranscodeCodecPage()
865 {
866     if( acodec ) free( acodec );
867     if( vcodec ) free( vcodec );
868 }
869
870 void wizTranscodeCodecPage::OnEnableVideo(wxCommandEvent& event)
871 {
872    video_combo->Enable( event.IsChecked() );
873    video_text->Enable( event.IsChecked() );
874 }
875
876 void wizTranscodeCodecPage::OnEnableAudio(wxCommandEvent& event)
877 {
878    audio_combo->Enable( event.IsChecked() );
879    audio_text->Enable( event.IsChecked() );
880 }
881
882 void wizTranscodeCodecPage::OnVideoCodecChange(wxCommandEvent& event)
883 {
884     struct codec *c = (struct codec*)
885              (video_combo->GetClientData(video_combo->GetSelection()));
886     video_text->SetLabel( wxU( vlc_wraptext(c->psz_descr, TEXTWIDTH, false) ) );
887     i_video_codec = video_combo->GetSelection();
888     vcodec = strdup(c->psz_codec);
889 }
890
891 void wizTranscodeCodecPage::OnAudioCodecChange(wxCommandEvent& event)
892 {
893     struct codec *c = (struct codec*)
894              (audio_combo->GetClientData(audio_combo->GetSelection()));
895     audio_text->SetLabel( wxU( vlc_wraptext(c->psz_descr, TEXTWIDTH, false) ) );
896     i_audio_codec = audio_combo->GetSelection();
897     acodec = strdup(c->psz_codec);
898
899 }
900
901 void wizTranscodeCodecPage::OnWizardPageChanging(wxWizardEvent& event)
902 {
903     unsigned int i,j;
904
905     if( !event.GetDirection() )
906     {
907             GetPrev()->Enable();
908             return;
909     }
910
911     /* Set the dummy codec ( accept all muxers ) if needed */
912     if( !video_combo->IsEnabled() )
913     {
914         i_video_codec = 12;
915     }
916     if( !audio_combo->IsEnabled() )
917     {
918         i_audio_codec = 7;
919     }
920
921     ((wizEncapPage *)GetNext())->SetPrev(this);
922
923     for( i = 0 ; i< 9 ; i++ )
924     {
925         //fprintf(stderr,"vcodecs[%i].muxers[%i] = %i\n",i_video_codec,i,vcodecs_array[i_video_codec].muxers[i]);
926         if( vcodecs_array[i_video_codec].muxers[i] != -1 )
927         {
928             for( j = 0 ; j< 9 ; j++ )
929             {
930 //        fprintf(stderr,"  acodecs[%i].muxers[%i] = %i\n",i_audio_codec,j,acodecs_array[i_audio_codec].muxers[j]);
931                 if( acodecs_array[i_audio_codec].muxers[j] ==
932                               vcodecs_array[i_video_codec].muxers[i] )
933                 {
934                     ((wizEncapPage*)GetNext())->EnableEncap(
935                                vcodecs_array[i_video_codec].muxers[i] );
936                 }
937             }
938         }
939     }
940     struct codec *c = (struct codec*)
941              (video_combo->GetClientData(video_combo->GetSelection()));
942     vcodec = strdup(c->psz_codec);
943     c = (struct codec*)
944             (audio_combo->GetClientData(audio_combo->GetSelection()));
945     acodec = strdup(c->psz_codec);
946
947
948     /* FIXME: Support bitrate */
949     p_parent->SetTranscode( vcodec, 1000, acodec, 200 );
950     ((wizEncapPage*)GetNext())->SetAction( p_parent->GetAction() );
951     p_parent->SetAction( p_parent->GetAction() );
952
953     return;
954 }
955
956 wxWizardPage *wizTranscodeCodecPage::GetPrev() const { return p_prev; }
957 wxWizardPage *wizTranscodeCodecPage::GetNext() const { return p_next; }
958 void wizTranscodeCodecPage::SetPrev( wxWizardPage *page) {p_prev = page; }
959
960
961 /***************************************************
962  * First streaming page: choose method             *
963  ***************************************************/
964 wizStreamingMethodPage::wizStreamingMethodPage( wxWizard *parent,
965     wxWizardPage *next) : wxWizardPage(parent)
966 {
967     int i;
968     p_next = next;
969     p_parent = (WizardDialog *)parent;
970
971     wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL);
972
973     /* Create the texts */
974     mainSizer->Add( new wxStaticText(this, -1, wxU(
975                         vlc_wraptext( STREAMING1_TITLE, TEXTWIDTH, false) ) ),
976                     0, wxALL, 5 );
977     mainSizer->Add( new wxStaticText(this, -1,
978                     wxU( vlc_wraptext(STREAMING1_TEXT , TEXTWIDTH, false ) ) ),
979                     0, wxALL, 5 );
980
981     i_method = 0;
982
983     for( i = 0 ; i< 3 ; i++ )
984     {
985         method_radios[i] = new wxRadioButton( this, MethodRadio0_Event + i,
986                                wxU( methods_array[i].psz_method ) );
987         method_radios[i]->SetToolTip( wxU(_( methods_array[i].psz_descr ) ) );
988         mainSizer->Add( method_radios[i], 0, wxALL, 5 );
989     }
990     address_text = new wxStaticText(this, -1,
991                  wxU( vlc_wraptext( methods_array[0].psz_address,
992                                     TEXTWIDTH, false ) ) );
993     address_txtctrl = new wxTextCtrl( this, -1, wxU("") );
994     mainSizer->Add( address_text, 0, wxALL, 5 );
995     mainSizer->Add( address_txtctrl, 0, wxALL, 5 );
996     mainSizer->Layout();
997     SetSizer(mainSizer);
998     mainSizer->Fit(this);
999
1000     return;
1001 }
1002
1003 void wizStreamingMethodPage::OnWizardPageChanging(wxWizardEvent& event)
1004 {
1005     unsigned int i;
1006     if( !event.GetDirection() ) return;
1007
1008     /* Check valid multicast address */
1009     if( i_method == 1 && !ismult((char *) address_txtctrl->GetValue().c_str()) )
1010     {
1011         wxMessageBox( wxU( INVALID_MCAST_ADDRESS ) , wxU( ERROR ),
1012                       wxICON_WARNING | wxOK, this );
1013         event.Veto();
1014
1015     }
1016     ((wizEncapPage *)GetNext())->SetPrev(this);
1017     for( i = 0 ; i< 9 ; i++ )
1018     {
1019         if( methods_array[i_method].muxers[i] != -1 )
1020         {
1021             ((wizEncapPage*)GetNext())->EnableEncap(
1022                                methods_array[i_method].muxers[i] );
1023         }
1024     }
1025     p_parent->SetStream( methods_array[i_method].psz_access ,
1026                          (char *)address_txtctrl->GetValue().c_str() );
1027     return;
1028 }
1029
1030 wxWizardPage *wizStreamingMethodPage::GetPrev() const { return p_prev; }
1031 wxWizardPage *wizStreamingMethodPage::GetNext() const { return p_next; }
1032
1033 void wizStreamingMethodPage::SetPrev( wxWizardPage *page) {p_prev = page; }
1034
1035
1036 void wizStreamingMethodPage::OnMethodChange(wxEvent& event)
1037 {
1038     i_method = event.GetId() - MethodRadio0_Event;
1039     address_text->SetLabel( wxU(
1040      vlc_wraptext( _(methods_array[i_method].psz_address), TEXTWIDTH, false)));
1041 }
1042
1043 /***************************************************
1044  * Choose encapsulation format                     *
1045  ***************************************************/
1046 wizEncapPage::wizEncapPage( wxWizard *parent ) : wxWizardPage(parent)
1047 {
1048     int i;
1049     i_mux = 0;
1050     p_parent = (WizardDialog *)parent;
1051     p_streaming_page = NULL;
1052     p_transcode_page = NULL;
1053     p_prev = NULL;
1054     wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL);
1055
1056     /* Create the texts */
1057     mainSizer->Add( new wxStaticText(this, -1, wxU(ENCAP_TITLE) ),
1058                     0, wxALL, 5 );
1059     mainSizer->Add( new wxStaticText(this, -1,
1060                     wxU( vlc_wraptext(ENCAP_TEXT , TEXTWIDTH, false ) ) ),
1061                     0, wxALL, 5 );
1062
1063     for( i = 0 ; i< 9 ; i++ )
1064     {
1065         encap_radios[i] = new wxRadioButton( this, EncapRadio0_Event + i,
1066                                wxU( encaps_array[i].psz_encap ) );
1067         encap_radios[i]->SetToolTip( wxU(_( encaps_array[i].psz_descr ) ) );
1068         mainSizer->Add( encap_radios[i], 0, wxALL, 5 );
1069         encap_radios[i]->Disable();
1070     }
1071
1072     SetSizer(mainSizer);
1073     mainSizer->Fit(this);
1074 }
1075
1076 wizEncapPage::~wizEncapPage()
1077 {
1078 }
1079
1080 void wizEncapPage::OnWizardPageChanging(wxWizardEvent& event)
1081 {
1082     int i;
1083     if( !event.GetDirection() )
1084     {
1085         for( i = 0 ; i< 9 ; i++ )
1086         {
1087             encap_radios[i]->Disable();
1088         }
1089     }
1090     p_parent->SetMux( encaps_array[i_mux].psz_mux );
1091     return;
1092 }
1093
1094 void wizEncapPage::OnEncapChange(wxEvent& event)
1095 {
1096     i_mux = event.GetId() - EncapRadio0_Event;
1097 }
1098
1099 void wizEncapPage::EnableEncap( int encap )
1100 {
1101     int i;
1102     for( i = 0 ; i< 9 ; i++)
1103     {
1104         if( encaps_array[i].id == encap )
1105         {
1106             encap_radios[i]->Enable();
1107             encap_radios[i]->SetValue(true);
1108             i_mux = i;
1109         }
1110     }
1111 }
1112
1113 void wizEncapPage::SetStreamingPage( wxWizardPage *page)
1114 {
1115     p_streaming_page = page;
1116 }
1117
1118 void wizEncapPage::SetTranscodePage( wxWizardPage *page)
1119 {
1120     p_transcode_page = page;
1121 }
1122
1123 wxWizardPage *wizEncapPage::GetPrev() const { return p_prev; }
1124
1125 wxWizardPage *wizEncapPage::GetNext() const
1126 {
1127     if( i_action== ACTION_STREAM )
1128         return p_streaming_page;
1129     else
1130        return p_transcode_page;
1131 }
1132
1133
1134 void wizEncapPage::SetAction( int i_act  ) { i_action = i_act; }
1135
1136 void wizEncapPage::SetPrev( wxWizardPage *page) { p_prev = page; }
1137
1138 /***************************************************
1139  * Extra transcoding page : Select file            *
1140  ***************************************************/
1141 wizTranscodeExtraPage::wizTranscodeExtraPage( wxWizard *parent,
1142                        wxWizardPage *prev,
1143                        wxWizardPage *next) : wxWizardPage(parent)
1144 {
1145     p_next = next;
1146     p_prev = prev;
1147     p_parent = (WizardDialog *) parent;
1148     wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL);
1149
1150     /* Create the texts */
1151     mainSizer->Add( new wxStaticText(this, -1, wxU( EXTRATRANSCODE_TITLE )),
1152                     0, wxALL, 5 );
1153     mainSizer->Add( new wxStaticText(this, -1,
1154                    wxU( vlc_wraptext( EXTRATRANSCODE_TEXT , TEXTWIDTH,
1155                                        false ) ) ),  0, wxALL, 5 );
1156     mainSizer->Add( new wxButton( this, Open_Event, wxU("Open") ) );
1157     SetSizer(mainSizer);
1158     mainSizer->Fit(this);
1159 }
1160
1161 void wizTranscodeExtraPage::OnSelectFile( wxCommandEvent &event)
1162 {
1163     wxFileDialog *file_dialog =  new wxFileDialog( this, wxU(_("Open File")),
1164                    wxT(""), wxT(""), wxT("*"), wxSAVE );
1165
1166     if( file_dialog && file_dialog->ShowModal() == wxID_OK )
1167     {
1168         if( file_dialog->GetFilename().mb_str() )
1169         {
1170             p_parent->SetTranscodeOut( (char*)file_dialog->GetFilename().
1171                                                   c_str() );
1172         }
1173     }
1174
1175 }
1176
1177 wxWizardPage *wizTranscodeExtraPage::GetPrev() const { return p_prev; }
1178 wxWizardPage *wizTranscodeExtraPage::GetNext() const {return p_next; }
1179
1180 /* Extra streaming page : Local display ? */
1181 wizStreamingExtraPage::wizStreamingExtraPage( wxWizard *parent,
1182                        wxWizardPage *prev,
1183                        wxWizardPage *next) : wxWizardPage(parent)
1184 {
1185     p_next = next;
1186     p_prev = prev;
1187     p_parent = (WizardDialog *) parent;
1188     wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL);
1189
1190     /* Create the texts */
1191     mainSizer->Add( new wxStaticText(this, -1, wxU( EXTRASTREAMING_TITLE )),
1192                     0, wxALL, 5 );
1193     mainSizer->Add( new wxStaticText(this, -1,
1194                     wxU( vlc_wraptext(EXTRASTREAMING_TEXT , TEXTWIDTH,
1195                                        false ) ) ),  0, wxALL, 5 );
1196     SetSizer(mainSizer);
1197     mainSizer->Fit(this);
1198 }
1199
1200 wxWizardPage *wizStreamingExtraPage::GetPrev() const { return p_prev; }
1201 wxWizardPage *wizStreamingExtraPage::GetNext() const {return p_next; }
1202
1203
1204 /***************************************************************************
1205  * Implementation of the wizard itself
1206  ***************************************************************************/
1207 wizHelloPage *page1;
1208 wizInputPage *page2 ;
1209 wizTranscodeCodecPage *tr_page1 ;
1210 wizStreamingMethodPage *st_page1;
1211 wizTranscodeExtraPage *tr_page2 ;
1212 wizStreamingExtraPage *st_page2;
1213 wizEncapPage *encap_page;
1214
1215 WizardDialog::WizardDialog(intf_thread_t *_p_intf, wxWindow *_p_parent ) :
1216 wxWizard( _p_parent, -1, wxU(_("Streaming/Transcoding Wizard")), wxNullBitmap, wxDefaultPosition)
1217 {
1218     /* Initializations */
1219     p_intf = _p_intf;
1220     SetPageSize(wxSize(400,350));
1221
1222     i_action = 0;
1223     page1 = new wizHelloPage(this);
1224     page2 = new wizInputPage(this, page1, p_intf);
1225     encap_page = new wizEncapPage(this );
1226     tr_page1 = new wizTranscodeCodecPage(this, encap_page );
1227     st_page1 = new wizStreamingMethodPage(this, encap_page);
1228
1229     tr_page2 = new wizTranscodeExtraPage(this, encap_page, NULL );
1230     st_page2 = new wizStreamingExtraPage(this, encap_page, NULL );
1231
1232     /* Page 1 -> 2 */
1233     page1->SetNext( page2 );
1234     /* 2->1 in constructor of 2 */
1235
1236     /* Page 2 -> 3 */
1237     page2->SetTranscodePage(tr_page1);
1238     page2->SetStreamingPage(st_page1);
1239     page2->SetPintf( p_intf );
1240     tr_page1->SetPrev(page2);
1241     st_page1->SetPrev(page2);
1242
1243     /* Page 3 -> 4 */
1244     encap_page->SetTranscodePage( tr_page2 );
1245     encap_page->SetStreamingPage( st_page2 );
1246     /* 3->4 in constructor of 3 */
1247 //    encap_page->SetPrev(tr_page1);
1248 }
1249
1250 WizardDialog::~WizardDialog()
1251 {
1252 //    Destroy();
1253     msg_Dbg(p_intf,"Killing wizard");
1254     delete page1;
1255     msg_Dbg(p_intf,"Killing wizard2");
1256     delete page2;
1257     msg_Dbg(p_intf,"Killing wizard3");
1258     delete tr_page1;
1259     msg_Dbg(p_intf,"Killing wizard4");
1260     delete st_page1 ;
1261     msg_Dbg(p_intf,"Killing wizard5");
1262     delete st_page2;
1263     msg_Dbg(p_intf,"Killing wizard6");
1264     delete tr_page2;
1265     msg_Dbg(p_intf,"Killing wizard7");
1266     encap_page->SetPrev(NULL);
1267     delete encap_page;
1268     msg_Dbg(p_intf,"Killing wizard done");
1269 }
1270
1271 void WizardDialog::SetMrl( const char *mrl )
1272 {
1273     msg_Dbg(p_intf, "Set MRL to : %s", mrl );
1274     this->mrl = strdup( mrl );
1275 }
1276
1277 void WizardDialog::SetTranscode( char *vcodec, int vb, char *acodec,int ab)
1278 {
1279     if( vcodec )
1280     {
1281         this->vcodec = strdup(vcodec);
1282     }
1283     if( acodec)
1284     {
1285         this->acodec = strdup(acodec);
1286     }
1287     this->vb = vb;
1288     this->ab = ab;
1289 }
1290
1291 void WizardDialog::SetStream( char *method, char *address )
1292 {
1293     this->method = strdup( method );
1294     this->address = strdup( address );
1295 }
1296
1297 void WizardDialog::SetTranscodeOut( char *address )
1298 {
1299     this->address = strdup( address );
1300 }
1301
1302 void WizardDialog::SetMux( char *mux )
1303 {
1304     this->mux = strdup( mux );
1305 }
1306
1307 void WizardDialog::SetAction( int i_action )
1308 {
1309     this->i_action = i_action;
1310 }
1311
1312 int WizardDialog::GetAction()
1313 {
1314     return i_action;
1315 }
1316
1317 void WizardDialog::Run()
1318 {
1319     msg_Dbg( p_intf,"Launching wizard");
1320     if( RunWizard(page1) )
1321     {
1322         int i_size;
1323         char *psz_opt;
1324         msg_Dbg( p_intf,"End wizard");
1325
1326         msg_Dbg( p_intf,"Action: %i", i_action);
1327         if( i_action == ACTION_TRANSCODE)
1328         {
1329             msg_Dbg( p_intf,"Starting transcode of %s to file %s", mrl, "caca");
1330             msg_Dbg( p_intf,"Using %s (%i kbps) / %s (%i kbps)",vcodec,vb,acodec,ab);
1331             msg_Dbg( p_intf,"Encap %s",mux);
1332             int i_tr_size = 10; /* 10 = ab + vb */
1333             i_tr_size += vcodec ? strlen(vcodec) : 0;
1334             i_tr_size += acodec ? strlen(acodec) : 0;
1335
1336             char *psz_transcode = (char *)malloc( i_tr_size * sizeof(char));
1337             if( vcodec )
1338             {
1339                 sprintf( psz_transcode, "vcodec=%s,vb=%i",
1340                                 vcodec, vb );
1341             }
1342             if( acodec )
1343             {
1344                 sprintf( psz_transcode, "%s%cacodec=%s,ab=%i",
1345                                 psz_transcode, vcodec ? ',' : ' ',
1346                                 acodec, ab );
1347             }
1348             i_size = 73 + strlen(mux) + strlen(address) + strlen(psz_transcode);
1349             psz_opt = (char *)malloc( i_size * sizeof(char) );
1350             sprintf( psz_opt, ":sout=#transcode{%s}:standard{mux=%s,url=%s,"
1351                                "access=file}",
1352                                psz_transcode, mux, address );
1353             msg_Dbg( p_intf,""); 
1354         }
1355         else
1356         {
1357             msg_Dbg( p_intf, "Starting stream of %s to %s using %s", mrl,
1358                                                           address, method);
1359             msg_Dbg( p_intf, "Encap %s", mux);
1360
1361             i_size = 40 + strlen(mux) + strlen(address);
1362             psz_opt = (char *)malloc( i_size * sizeof(char) );
1363             sprintf( psz_opt, ":sout=#standard{mux=%s,url=%s,access=%s}",
1364                             mux, address,method);
1365         }
1366
1367         playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_intf,
1368                             VLC_OBJECT_PLAYLIST, FIND_ANYWHERE);
1369         if( p_playlist )
1370         {
1371             playlist_AddExt( p_playlist, mrl, ITEM_NAME,PLAYLIST_APPEND |
1372                          PLAYLIST_GO, PLAYLIST_END , -1 ,
1373                          (const char **)&psz_opt , 1 );
1374             vlc_object_release(p_playlist);
1375         }
1376         else
1377         {
1378             wxMessageBox( wxU( NO_PLAYLIST ), wxU( ERROR ),
1379                           wxICON_WARNING | wxOK, this );
1380         }
1381     }
1382     else
1383     {
1384         msg_Dbg( p_intf, "Wizard cancelled");
1385     }
1386 }
1387 /****************************************************************
1388  * Local helper functions
1389  ****************************************************************/
1390 static int ismult( char *psz_uri )
1391 {
1392     char *psz_end;
1393     int  i_value;
1394
1395     i_value = strtol( psz_uri, &psz_end, 0 );
1396     /* IPv6 */
1397     if( psz_uri[0] == '[')
1398     {
1399             if( strncasecmp( &psz_uri[1], "FF0" , 3) ||
1400                             strncasecmp( &psz_uri[2], "FF0" , 3))
1401                     return( VLC_TRUE );
1402             else
1403                     return( VLC_FALSE );
1404     }
1405     if( *psz_end != '.' ) { return( VLC_FALSE ); }
1406
1407     return( i_value < 224 ? VLC_FALSE : VLC_TRUE );
1408
1409 }