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