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